Score.py :  » RSS » XPN » xpn-1.2.6 » xpn_src » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » RSS » XPN 
XPN » xpn 1.2.6 » xpn_src » Score.py
import time
import re
import gtk
import gobject
import pango
import cPickle
import os
from email.Utils import parsedate_tz,mktime_tz
from xpn_src.Article import Article
from xpn_src.Dialogs import Dialog_OK
from xpn_src.UserDir import get_wdir


try:
    set()
except:
    from sets import Set


def escape(data):
    """Escape &, <, and > in a string of data.
    """

    # must do ampersand first
    data = data.replace("&", "&amp;")
    data = data.replace(">", "&gt;")
    data = data.replace("<", "&lt;")
    return data


class Score_Rules:
    def valid_re(self,regex):
        try :
            re.compile(regex)
        except:
            return False
        else:
            return True

    def match_is_valid(self,match,header):
        interval_re=re.compile(r"\[\d+,\d+\]")
        header_is_string=lambda header: header.lower() in ("from","subject","date","message-id","references","xref")
        header_is_number=lambda header: header.lower() in ("age","lines","bytes","xpost","score")

        #match is a string case insensitive
        match_is_string_c_ins=lambda match: (match[0]=="\"" and match[-1]=="\"") or \
                                            (match[0]=="{" and match[-1]=="}" and self.valid_re(match[1:]))
        #match is a string case sensitive:
        match_is_string_c_sens=lambda match: match[0].lower()=="c" and ((match[1]=="\"" and match[-1]=="\"") or \
                                            (match[1]=="{" and match[-1]=="}" and self.valid_re(match[2:])))
        #match is a inverted string case insensitive:
        match_is_string_c_ins_neg=lambda match: match[0]=="~" and match_is_string_c_ins(match[1:])
        #match is a inverted string case sensitive:
        match_is_string_c_sens_neg=lambda match: match[0]=="~" and match_is_string_c_sens(match[1:])

        #match is a string:
        match_is_string = lambda match: match_is_string_c_ins_neg(match) or match_is_string_c_sens_neg(match) or\
                                        match_is_string_c_ins(match) or match_is_string_c_sens(match)
                                        
        match_is_numb=lambda match: (match[0]=="%" and ( ((match[1]==">" or match[1]=="<" or match[1]=="=") and \
                                       (match[2:].isdigit() or (match[2]=="-" and match[3:].isdigit()))) or \
                                       (match[1]=="[" and interval_re.search(match[1:])) ))
        match_is_numb_neg= lambda match: match[0]=="~" and match_is_numb(match[1:])

        #match is a number:
        match_is_number = lambda match: match_is_numb(match) or match_is_numb_neg(match)


        if len(match)>2:
            if (header_is_string(header) and (match_is_string(match))) or \
               (header_is_number(header) and (match_is_number(match))):
                return True
            else:
                return False
        else:
            return False

    def score_mod_is_valid(self,score_mod):
        if score_mod[0]=="=":
            if (score_mod[1]=="+" or score_mod[1]=="-"):
                return score_mod[2:].isdigit()
            else:
                return False
        if score_mod[0]=="+" or score_mod[0]=="-":
            return score_mod[1:].isdigit()
        else:
            if score_mod[1:].startswith("setcolor"):
                regex=re.compile("(^setcolor)\((([a-z]+)|(#\w+));(([a-z]+)|(#\w+))\)")
                match=regex.match(score_mod[1:])
                if match:
                    if (match.groups()[0] and match.groups()[1] and match.groups()[4]):
                        return True
                    else:
                        return False
                else:
                    return False
            else:
                return score_mod[1:] in self.actions
           
           
    def header_is_valid(self,header,score_mod):
        if score_mod[0]=="!":
            return header in self.action_headers
        else:
            return header in self.headers

    def scan_for_rule(self,line):
        scope_number=len(self.group_scope_list)-1
        ind1=line.find(" ")
        score_mod=""
        header=""
        match=""
        if ind1!=-1:
            score_mod=line[:ind1].strip().lower()
            line2=line[ind1+1:]
            ind2=line2.strip().find(" ")
            if ind2!=-1:
                header=line2.strip()[:ind2].strip().lower()
                match=line2.strip()[ind2+1:].strip()
        if not self.score_mod_is_valid(score_mod):
            if score_mod[0]=="!":
                self.errors.append("<b>"+_("Syntax Error: Unknown Action on line:: ")+"</b>\n%s\n" % (escape(line),))
            else:
                self.errors.append("<b>"+_("Syntax Error: Bad Score Modifier on line:: ")+"</b>\n%s\n" % (escape(line),))
        elif not self.header_is_valid(header,score_mod):
            self.errors.append("<b>"+_("Syntax Error: Unknown Header Name on line:: ")+"</b>\n%s\n" % (escape(line),))
        elif not self.match_is_valid(match,header):
            self.errors.append("<b>"+_("Syntax Error: Bad Match Rule on line:: ")+"</b>\n%s\n" % (escape(line),))

        else:
            self.group_rules_list[scope_number].append({"score_mod":score_mod,"header":header,"match":match})

    def scan_for_block(self,line):
        scope=line[1:-1].strip()
        groups=[]
        if scope!="":
            if scope=="*":
                groups="*"
            else:
                groups=scope.split(" ")
            self.raw_scopes.append(line)
        return groups

    def load_file(self):
        "Score file parser"
        try:
            f=open(os.path.join(self.wdir,"scores.txt"),"r")
        except IOError:
            lines=[]
        else:
            lines=f.readlines()
            lines=[line.strip("\n").decode("utf-8") for line in lines]
            f.close()
        return lines

    def load_rules(self,lines):
        self.raw_file="\n".join(lines)
        self.group_scope_list=[]
        self.group_rules_list=[]
        self.errors=[]
        self.raw_scopes=[]

        current_group_scope=[]
        for line in lines:
            line=line.strip()
            if line!="":
                if line[0]!="#":
                    #It's not empty nor a comment
                    if line[0]=="[" and line[-1]=="]":
                        #This is the group scope
                        current_group_scope=self.scan_for_block(line)
                        self.group_scope_list.append(current_group_scope)
                        self.group_rules_list.append([])

                    elif line[0]=="+" or line[0]=="-" or line[0]=="=" or line[0]=="!":
                        #This is a rule
                        if current_group_scope:
                            self.scan_for_rule(line)
                        else:
                            self.errors.append("<b>"+_("Syntax Error: Missing scope for line :: ")+"</b>\n%s\n" % (escape(line),))
                    else:
                        self.errors.append("<b>"+_("Syntax Error: Bad Line:: ")+"</b>\n%s\n" % (escape(line),))

    def build_match_rule(self,match):
        def build_plain_match_rule(match,index=1):
            """ Builds the match rule without the inverter information,
                index point to the start of the match (i.e. without the ~)"""
            if match[0].lower()=="c":
                #case sensitive
                if match[1]=="{":
                    #regular expression
                    match_rule=lambda field,regex: bool(re.compile(regex[index+1:-1],re.UNICODE).search(field))
                else:
                    #normal match
                    match_rule=lambda field,word: bool(field.find(word[index+1:-1])+1)
            elif match[0].lower()!="%":
                #case sensitive
                if match[0]=="{":
                    #regular expression
                    match_rule=lambda field,regex: bool(re.compile(regex[index:-1],re.UNICODE|re.IGNORECASE).search(field))
                else:
                    #normal match
                    match_rule=lambda field,word: bool(field.lower().find(word[index:-1].lower())+1)
            else:
                #numeric rule
                if match[1]==">":
                    match_rule=lambda field,num: field>int(num[index+1:])
                elif match[1]=="<":
                    match_rule=lambda field,num: field<int(num[index+1:])
                elif match[1]=="=":
                    match_rule=lambda field,num: field==int(num[index+1:])
                else:
                    match_rule=lambda field,interval: field in range(int(interval[index+1:-1].split(",")[0]),int(interval[index+1:-1].split(",")[1])+1)
            return match_rule

        if match[0]=="~":
            #inverted rule
                plain_match_rule=build_plain_match_rule(match[1:])
                return lambda field,match: not plain_match_rule(field,match[1:])

        else:
            #not inverted rule
                plain_match_rule=build_plain_match_rule(match)
                return lambda field,match: plain_match_rule(field,match)
            

    def apply_score_rules(self,xpn_article,group):
        score=xpn_article.get_score()
        i=0
        time_now=mktime_tz(parsedate_tz(time.ctime()))
        age=(time_now-xpn_article.secs)/(24.0*60*60)

        #compatibility check
        try: xpn_article.xref
        except AttributeError: xpn_article.xref=""
        try: xpn_article.bytes
        except AttributeError: xpn_article.bytes=0
        try: xpn_article.lines
        except AttributeError: xpn_article.lines=0

        xpost=xpn_article.xref.count(":")

        fields={"subject":xpn_article.subj,"from":xpn_article.from_name,"date":xpn_article.date,
                "message-id":xpn_article.msgid,"references":xpn_article.ref,"age":age,"xref":xpn_article.xref,
                "bytes":xpn_article.bytes,"lines":xpn_article.lines,"xpost":xpost}

        for group_scope in self.group_scope_list:
            if group_scope=="*" or (group in group_scope):
                #current group is in this scope
                for rule in self.group_rules_list[i]:
                    #let's apply rule
                    score_mod=rule["score_mod"]
                    if score_mod[0]=="!":
                        #this is an action
                        continue
                    match_rule=self.build_match_rule(rule["match"])
                    if match_rule(fields[rule["header"]],rule["match"]):
                        score_mod=rule["score_mod"]
                        if score_mod[0]=="=":
                            score=int(score_mod[1:])
                            if score>9999: score=9999
                            if score<-9999: score=-9999
                            return score
                        else:
                            score=score+int(score_mod)
            i=i+1
        if score>9999: score=9999
        if score<-9999: score=-9999
        return score

    def apply_action_rules(self,xpn_article,group):
        score=xpn_article.get_score()
        i=0
        time_now=mktime_tz(parsedate_tz(time.ctime()))
        age=(time_now-xpn_article.secs)/(24.0*60*60)

        #compatibility check
        #there is no need here, it's has been already performed in apply_score_rules
        
        xpost=xpn_article.xref.count(":")

        fields={"subject":xpn_article.subj,"from":xpn_article.from_name,"date":xpn_article.date,
                "message-id":xpn_article.msgid,"references":xpn_article.ref,"age":age,"xref":xpn_article.xref,
                "bytes":xpn_article.bytes,"lines":xpn_article.lines,"xpost":xpost,"score":score}
        
        actions=[]
        for group_scope in self.group_scope_list:
            if group_scope=="*" or (group in group_scope):
                #current group is in this scope
                for rule in self.group_rules_list[i]:
                    #let's apply rule
                    match_rule=self.build_match_rule(rule["match"])
                    if match_rule(fields[rule["header"]],rule["match"]):
                        action=rule["score_mod"]
                        if action[0]=="!":
                            #this is an action
                            if action[1:]=="kill":
                                #xpn_article=None
                                pass #need this to let reapply_rules work
                            elif action[1:]=="markread":
                                xpn_article.is_read=True
                            elif action[1:]=="markunread":
                                xpn_article.is_read=False
                            elif action[1:]=="mark":
                                xpn_article.marked_for_download=True
                            elif action[1:]=="unmark":
                                xpn_article.marked_for_download=False                                
                            elif action[1:]=="keep":
                                xpn_article.keep=True
                            elif action[1:]=="unkeep":
                                xpn_article.keep=False
                            elif action[1:]=="watch":
                                xpn_article.watch=True
                                xpn_article.ignore=False
                            elif action[1:]=="ignore":
                                xpn_article.watch=False
                                xpn_article.ignore=True
                                xpn_article.is_read=True
                            elif action[1:]=="unsetwatchignore":
                                xpn_article.watch=False
                                xpn_article.ignore=False
                            elif action[1:].startswith("setcolor"):
                                regex=re.compile("(^setcolor)\((([a-z]+)|(#\w+));(([a-z]+)|(#\w+))\)")
                                matches=regex.match(action[1:])
                                xpn_article.fg_color=str(matches.groups()[1])
                                xpn_article.bg_color=str(matches.groups()[4])
                            actions.append(action[1:])
            i=i+1
        return xpn_article,actions
       
    
    def __init__(self):
        self.wdir=get_wdir()
        self.headers=["from","subject","date","message-id","references","age","xref","xpost","bytes","lines"]
        self.action_headers=["from","subject","date","message-id","references","age","xref","xpost","bytes","lines","score"]
        self.actions=["kill","markread","markunread","mark","unmark","retrieve","keep","unkeep","watch","ignore","unsetwatchignore","setcolor"]
        self.group_scope_list=[]
        self.group_rules_list=[]
        self.errors=[]
        self.raw_file=""
        self.raw_scopes=[]
        self.lines=self.load_file()
        self.load_rules(self.lines)

class Rules_Tree:
    def get_widget(self):
        return self.scrolledwin

    def insert(self,iter_parent,iter_sibling,values):
        iter=self.model.insert_before(iter_parent,iter_sibling)
        for i in range(len(values)):
            if i<3:
                value=values[i].encode("utf-8")
            else:
                value=values[i]
            self.model.set_value(iter,i,value)
        return iter

    def __init__(self):
        self.scrolledwin=gtk.ScrolledWindow()
        self.scrolledwin.set_border_width(4)
        self.scrolledwin.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
        self.scrolledwin.set_shadow_type(gtk.SHADOW_ETCHED_IN)
        self.rules_tree=gtk.TreeView()
        self.rules_tree.set_border_width(4)
        self.model=gtk.TreeStore(gobject.TYPE_STRING,gobject.TYPE_STRING,gobject.TYPE_STRING,gobject.TYPE_INT)
        text_renderer_scope=gtk.CellRendererText()
        text_renderer_scope.set_property("weight",1000)
        text_renderer=gtk.CellRendererText()

        self.column1=gtk.TreeViewColumn(_("Scope/Score Mod"),text_renderer_scope,text=0,weight=3)
        self.column2=gtk.TreeViewColumn(_("Header"),text_renderer,text=1)
        self.column3=gtk.TreeViewColumn(_("Match Rule"),text_renderer,text=2)
        self.rules_tree.append_column(self.column1)
        self.rules_tree.append_column(self.column2)
        self.rules_tree.append_column(self.column3)
        self.scrolledwin.add(self.rules_tree)
        self.rules_tree.set_model(self.model)

class Score_Win:
    def delete_event(self,widget,event,data=None):
        return False

    def destroy(self,widget):
        lines=self.score_rules.load_file()
        self.score_rules.load_rules(lines)
        self.window.destroy()

    def show(self):
        self.window.show_all()
        self.match_value2_entry.hide()
        self.match_value2_label.hide()
        self.match_value_label.hide()
        self.action_match_value2_entry.hide()
        self.action_match_value2_label.hide()
        self.action_match_value_label.hide()
        self.color1_entry.hide()
        self.color1_button.hide()
        self.color1_label.hide()
        self.color2_entry.hide()
        self.color2_button.hide()
        self.color2_label.hide()

    def show_rules(self):
        self.rules_tree.model.clear()
        iter_scope=None
        group_scope_list=self.score_rules.group_scope_list
        group_rules_list=self.score_rules.group_rules_list
        for i in range(len(group_scope_list)):
            if group_scope_list[i]=="*":
                scope="[*]"
            else:
                scope="[ "+",\n".join(group_scope_list[i])+" ]"
            iter_scope=self.rules_tree.insert(None,None,[str(scope),"","",pango.WEIGHT_BOLD])
            for rule in group_rules_list[i]:
                self.rules_tree.insert(iter_scope,None,[rule["score_mod"],rule["header"],rule["match"],pango.WEIGHT_NORMAL])

    def show_errors(self,obj):
        errors="\n".join(self.score_rules.errors)
        if errors:
            self.dialog=Dialog_OK(errors.encode("utf-8"))
        else:
            self.dialog=Dialog_OK(_("No Errors"))

    def close_window(self,obj):
        start,stop=self.file_buffer.get_bounds()
        text=self.file_buffer.get_text(start,stop,True)
        f=open(os.path.join(self.wdir,"scores.txt"),"w")
        f.write(text)
        f.close()
        self.window.destroy()

    def rescan_rules(self,obj):
        start,stop=self.file_buffer.get_bounds()
        lines=self.file_buffer.get_text(start,stop,True).decode("utf-8").split("\n")
        self.score_rules.load_rules(lines)
        self.score_rules.lines=lines
        self.show_rules()
        subscribed=self.art_db.getSubscribed()
        subscribed=["["+subscribed[i][0]+"]" for i in range(len(subscribed))]
        popdown=self.score_rules.raw_scopes
        for item in subscribed:
            if item not in popdown:
                popdown.append(item)
        if "[*]" not in popdown:
            popdown.insert(0,"[*]")
        model=self.scope_combo.get_model()
        model.clear()
        self.scope_combo.set_model(model)
        model=self.action_scope_combo.get_model()
        model.clear()
        self.action_scope_combo.set_model(model)
        for item in popdown:
            self.scope_combo.append_text(item)
            self.action_scope_combo.append_text(item)
        iter_first=self.scope_combo.get_model().get_iter_first()
        self.scope_combo.set_active_iter(iter_first)
        iter_first=self.action_scope_combo.get_model().get_iter_first()
        self.action_scope_combo.set_active_iter(iter_first)

    def add_new_rule(self,obj):
        scope=self.scope_combo.child.get_text().decode("utf-8")
        header=self.score_rules.headers[self.header_opt_menu.get_active()]
        match_type=self.match_type_opt_menu.get_active()
        match_type, match_type_inverted =match_type/2,match_type%2
        match_value=self.match_value_entry.get_text().decode("utf-8")
        case=self.case_checkbutton.get_active()
        action_type=self.score_mod_opt_menu.get_active()
        number=self.score_mod_spinbutton.get_value_as_int()
        if scope!="" and match_value!="":
            rule=[]
            if action_type==0 and number<0:
                number=repr(abs(number))
            elif action_type==1:
                number=repr(abs(number))
            elif action_type==2 and number>=0:
                number="+"+repr(number)
            else:
                number=repr(number)
            rule.append(["+","-","="][action_type]+number)
            rule.append(header.capitalize())
            if match_type==0:
                match_value="\""+match_value+"\""
            elif match_type==1:
                match_value="{"+match_value+"}"
            elif match_type==2:
                match_value="%>"+match_value
            elif match_type==3:
                match_value="%<"+match_value
            elif match_type==4:
                match_value="%="+match_value
            else:
                match_value2=self.match_value2_entry.get_text().decode("utf-8")
                match_value="%["+match_value+","+match_value2+"]"
            if (match_type in [0,1]) and case:
                match_value="c"+match_value
            if match_type_inverted:
                match_value="~"+match_value
            rule.append(match_value)
            rule=" ".join(rule)

            found_scope=False
            for i in range(len(self.score_rules.lines)):
                if scope==self.score_rules.lines[i]:
                    found_scope=True
                    break
            if found_scope==True:
                found_block_end=False
                for j in range(i,len(self.score_rules.lines)):
                    if self.score_rules.lines[j]=="":
                        found_block_end=True
                        break
                if found_block_end:
                    self.score_rules.lines.insert(j,rule)
                else:
                    self.score_rules.lines.insert(i+1,rule)
            if found_scope==False:
                self.score_rules.lines.append("")
                self.score_rules.lines.append(scope)
                self.score_rules.lines.append(rule)
                self.score_rules.lines.append("")
            self.file_buffer.set_text(("\n".join(self.score_rules.lines)).encode("utf-8"))
            self.rescan_rules(None)

    def add_new_action_rule(self,obj):
        scope=self.action_scope_combo.child.get_text().decode("utf-8")
        header=self.score_rules.action_headers[self.action_header_opt_menu.get_active()]
        action_match_type=self.action_match_type_opt_menu.get_active()
        action_match_type, action_match_type_inverted =action_match_type/2,action_match_type%2

        action_value=self.action_match_value_entry.get_text().decode("utf-8")
        case=self.action_case_checkbutton.get_active()
        #values=["Kill","Mark Read","Mark Unread","Mark for Download","UnMark for Download","Retrieve","Keep","UnKeep","Watch","Ignore","UnSetWatchIgnore"]
        action_type=self.action_type_opt_menu.get_active()
        if scope!="" and action_value!="":
            rule=[]
            if action_type!=11:
                rule.append(["!kill","!markread","!markunread","!mark","!unmark","!retrieve","!keep","!unkeep","!watch","!ignore","!unsetwatchignore"][action_type])
            else:
                color_fg=self.color1_entry.get_text().decode("utf-8")
                color_bg=self.color2_entry.get_text().decode("utf-8")
                if color_fg=="": color_fg="Default"
                if color_bg=="": color_bg="Default"
                rule.append("!setcolor(%s;%s)" % (color_fg,color_bg))
            rule.append(header.capitalize())
            if action_match_type==0:
                action_value="\""+action_value+"\""
            elif action_match_type==1:
                action_value="{"+action_value+"}"
            elif action_match_type==2:
                action_value="%>"+action_value
            elif action_match_type==3:
                action_value="%<"+action_value
            elif action_match_type==4:
                action_value="%="+action_value
            else:
                action_value2=self.action_match_value2_entry.get_text().decode("utf-8")
                action_value="%["+action_value+","+action_value2+"]"

            if (action_match_type in [0,1]) and case:
                action_value="c"+action_value
            if action_match_type_inverted:
                action_value="~"+action_value
            rule.append(action_value)
            rule=" ".join(rule)

            found_scope=False
            for i in range(len(self.score_rules.lines)):
                if scope==self.score_rules.lines[i]:
                    found_scope=True
                    break
            if found_scope==True:
                found_block_end=False
                for j in range(i,len(self.score_rules.lines)):
                    if self.score_rules.lines[j]=="":
                        found_block_end=True
                        break
                if found_block_end:
                    self.score_rules.lines.insert(j,rule)
                else:
                    self.score_rules.lines.insert(i+1,rule)
            if found_scope==False:
                self.score_rules.lines.append("")
                self.score_rules.lines.append(scope)
                self.score_rules.lines.append(rule)
                self.score_rules.lines.append("")
            self.file_buffer.set_text(("\n".join(self.score_rules.lines)).encode("utf-8"))
            self.rescan_rules(None)


        
    def test_re(self,obj):
        RE=self.re_entry.get_text().decode("utf-8")
        bounds=self.text_buffer.get_bounds()
        if bounds and RE:
            start,stop=bounds
            test_text=self.text_buffer.get_text(start,stop,True).decode("utf-8")
            self.text_buffer.delete(start,stop)
            self.text_buffer.set_text(test_text.encode("utf-8"))
            if self.test_case_checkbutton.get_active()==True:
                matches=re.compile(RE,re.UNICODE).finditer(test_text)
            else:
                matches=re.compile(RE,re.UNICODE|re.IGNORECASE).finditer(test_text)
            for match in matches:
                match_start,match_stop,match_text= match.start(), match.end(), match.group()
                iter_start=self.text_buffer.get_iter_at_offset(match_start)
                iter_stop=self.text_buffer.get_iter_at_offset(match_stop)
                self.text_buffer.delete(iter_start,iter_stop)
                self.text_buffer.insert_with_tags_by_name(iter_start,match_text.encode("utf-8"),"match")

    def match_type_changed(self,obj):
        if self.match_type_opt_menu.get_active()/2==5:
            self.match_value2_entry.show()
            self.match_value2_label.show()
            self.match_value_label.show()
            self.match_value_entry.set_size_request(-1,-1)
            self.match_value2_entry.set_size_request(-1,-1)

        else:
            self.match_value2_entry.hide()
            self.match_value2_label.hide()
            self.match_value_label.hide()
            self.match_value_entry.set_size_request(200,-1)
    
    def action_match_type_changed(self,obj):
        if self.action_match_type_opt_menu.get_active()/2==5:
            self.action_match_value2_entry.show()
            self.action_match_value2_label.show()
            self.action_match_value_label.show()
            self.action_match_value_entry.set_size_request(-1,-1)
            self.action_match_value2_entry.set_size_request(-1,-1)

        else:
            self.action_match_value2_entry.hide()
            self.action_match_value2_label.hide()
            self.action_match_value_label.hide()
            self.action_match_value_entry.set_size_request(200,-1)
    
    def action_type_changed(self,obj):
        if self.action_type_opt_menu.get_active()==11:
            self.color1_label.show()
            self.color1_entry.show()
            self.color1_button.show()
            self.color2_entry.show()
            self.color2_button.show()
            self.color2_label.show()
        else:
            self.color1_label.hide()
            self.color1_entry.hide()
            self.color1_button.hide()
            self.color2_entry.hide()
            self.color2_button.hide()
            self.color2_label.hide()

    def get_color_from_button(self,color_button):
        def gdkcolor_to_hex(gdk_color):
            colors=[gdk_color.red,gdk_color.green,gdk_color.blue]
            colors= [("0"+str(hex(col*255/65535))[2:])[-2:].upper() for col in (colors)]
            color = "#"+colors[0]+colors[1]+colors[2]
            return color

        color=color_button.get_color()
        color=gdkcolor_to_hex(color)
        if color_button==self.color1_button:
            self.color1_entry.set_text(color)
        else:
            self.color2_entry.set_text(color)

    def __init__(self,score_rules,main_win):
        self.score_rules=score_rules
        self.wdir=get_wdir()
        self.art_db=main_win.art_db
        self.window=gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.connect("delete_event",self.delete_event)
        self.window.connect("destroy",self.destroy)
        self.window.set_title(_("Scoring Rules"))
        self.window.set_position(gtk.WIN_POS_CENTER)
        self.window.set_default_size(450,450)
        self.window.set_icon(gtk.gdk.pixbuf_new_from_file("pixmaps/score.xpm"))



        main_vbox=gtk.VBox()
        main_vbox.set_border_width(2)
        self.notebook=gtk.Notebook()


        #Rules Page
        vpaned=gtk.VPaned()
        vpaned.set_border_width(4)
        rules_vbox=gtk.VBox()
        rules_vbox_label=gtk.Label("<b>"+_("Correct Rules")+"</b>")
        rules_vbox_label.set_alignment(0,0.5)
        rules_vbox_label.set_use_markup(True)
        rules_vbox.pack_start(rules_vbox_label,False,False,4)
        self.rules_tree=Rules_Tree()
        rules_table=gtk.Table(1,1,False)
        rules_table.attach(self.rules_tree.get_widget(),0,1,0,1,gtk.EXPAND|gtk.FILL,gtk.EXPAND|gtk.FILL,16)
        rules_vbox.pack_start(rules_table,True,True)

        file_vbox=gtk.VBox()
        file_vbox_label=gtk.Label("<b>"+_("Score File Editor")+"</b>")
        file_vbox_label.set_alignment(0,0.5)
        file_vbox_label.set_use_markup(True)
        file_vbox.pack_start(file_vbox_label,False,False,4)
        file_table=gtk.Table(3,2,False)
        file_scrolledwin=gtk.ScrolledWindow()
        file_scrolledwin.set_border_width(4)
        file_scrolledwin.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
        file_scrolledwin.set_shadow_type(gtk.SHADOW_ETCHED_IN)
        self.file_buffer=gtk.TextBuffer()
        self.file_view=gtk.TextView(self.file_buffer)
        self.file_view.set_border_width(4)
        self.file_view.modify_font(pango.FontDescription("Monospace 8"))
        self.file_buffer.set_text(self.score_rules.raw_file.encode("utf-8"))
        file_scrolledwin.add(self.file_view)

        file_butt_hbox=gtk.HBox()
        file_butt_hbox.set_border_width(4)
        self.button_rescan=gtk.Button(_("ReScan Rules"))
        self.button_rescan.connect("clicked",self.rescan_rules)
        self.button_show_errors=gtk.Button(_("Show Errors"))
        self.button_show_errors.connect("clicked",self.show_errors)
        file_butt_hbox.pack_start(self.button_rescan,True,True,2)
        file_butt_hbox.pack_start(self.button_show_errors,True,True,2)
       
        file_table.attach(file_scrolledwin,0,1,0,1,gtk.EXPAND|gtk.FILL,gtk.EXPAND|gtk.FILL,16)
        file_table.attach(file_butt_hbox,0,1,1,2,gtk.EXPAND|gtk.FILL,gtk.FILL,16)

        
        file_vbox.pack_start(file_table,True,True)
        vpaned.add(file_vbox)
        vpaned.add(rules_vbox)
        rules_label=gtk.Label("<b>"+_("Rules")+"</b>")
        rules_label.set_use_markup(True)
        self.notebook.append_page(vpaned,rules_label)



        #New Score Rule Page
        new_rule_vbox=gtk.VBox()
        new_rule_vbox.set_border_width(4)

        scope_vbox=gtk.VBox()
        scope_vbox.set_border_width(4)
        scope_label=gtk.Label("<b>"+_("Groups Scope")+"</b>")
        scope_label.set_alignment(0,0.5)
        scope_label.set_use_markup(True)
        scope_vbox.pack_start(scope_label,False,False,4)

        self.scope_combo=gtk.combo_box_entry_new_text()
        popdown=self.score_rules.raw_scopes
        if "[*]" not in popdown:
            popdown.insert(0,"[*]")
        subscribed=self.art_db.getSubscribed()
        subscribed=["["+subscribed[i][0]+"]" for i in range(len(subscribed))]
        popdown=popdown+subscribed
        for item in popdown:
            self.scope_combo.append_text(item)
        self.scope_combo.set_active(0)
        self.scope_combo.set_size_request(250,-1)
        scope_hbox=gtk.HBox()
        scope_hbox.set_border_width(4)
        scope_hbox.pack_start(self.scope_combo,True,False,2)
        scope_vbox.add(scope_hbox)

        condition_main_vbox=gtk.VBox()
        condition_label=gtk.Label("<b>"+_("Condition")+"</b>")
        condition_label.set_alignment(0,0.5)
        condition_label.set_use_markup(True)
        condition_main_vbox.pack_start(condition_label,False,False,4)
        condition_table=gtk.Table(3,1,False)
        condition_hbox=gtk.HBox()
        self.header_opt_menu=gtk.combo_box_new_text()
        self.header_opt_menu.set_size_request(130,-1)
        for header in self.score_rules.headers:
            self.header_opt_menu.append_text(header.capitalize())
        self.header_opt_menu.set_active(0)
        condition_hbox.pack_start(self.header_opt_menu,True,False,2)
        values=[_("Contains String"),_("Doesn't Contain String"),_("Matches RegEx"),_("Doesn't Match RegEx"), _("Greater Than"), _("Not Greater Than"), _("Lower Than"),_("Not Lower Than"), _("Equal To (numbers only)"),_("Different From (numbers only)"), _("In Range"),_("Out Of Range")]
        self.match_type_opt_menu=gtk.combo_box_new_text()
        self.match_type_opt_menu.set_size_request(130,-1)
        for value in values:
            self.match_type_opt_menu.append_text(value)
        self.match_type_opt_menu.set_active(0)
        self.match_type_opt_menu.connect("changed",self.match_type_changed)
        condition_hbox.pack_start(self.match_type_opt_menu,True,False)
        self.case_checkbutton=gtk.CheckButton(_("Case Sensitive"))
        self.match_value_entry=gtk.Entry()
        self.match_value_entry.set_size_request(200,-1)
        self.match_value2_entry=gtk.Entry()
        self.match_value_label=gtk.Label(_("Lower Limit"))
        self.match_value2_label=gtk.Label(_("Upper Limit"))
        match_value_hbox=gtk.HBox()
        match_value_hbox.pack_start(self.match_value_label,True,False,2)
        match_value_hbox.pack_start(self.match_value_entry,True,True,2)
        match_value_hbox.pack_start(self.match_value2_label,True,False,2)
        match_value_hbox.pack_start(self.match_value2_entry,True,True,2)
        condition_table.attach(condition_hbox,0,1,0,1,gtk.EXPAND|gtk.FILL,gtk.FILL,16,6)
        condition_table.attach(match_value_hbox,0,1,1,2,gtk.EXPAND|gtk.FILL,gtk.FILL,16,6)
        condition_table.attach(self.case_checkbutton,0,1,2,3,gtk.EXPAND|gtk.FILL,gtk.FILL,16,6)
        condition_main_vbox.pack_start(condition_table,True,True)

        score_mod_vbox=gtk.VBox()
        score_mod_label=gtk.Label("<b>"+_("Score")+"</b>")
        score_mod_label.set_use_markup(True)
        score_mod_label.set_alignment(0,0.5)
        score_mod_vbox.pack_start(score_mod_label,False,False,4)
        score_mod_table=gtk.Table(1,1,False)
        score_mod_hbox=gtk.HBox()
        values=[_("Raise Score"),_("Lower Score"), _("Set Score")]
        self.score_mod_opt_menu=gtk.combo_box_new_text()
        for value in values:
            self.score_mod_opt_menu.append_text(value)
        self.score_mod_opt_menu.set_active(0)
        self.score_mod_opt_menu.set_size_request(130,-1)
        score_mod_hbox.pack_start(self.score_mod_opt_menu,True,False,2)
        score_mod_table.attach(score_mod_hbox,0,1,0,1,gtk.EXPAND|gtk.FILL,gtk.FILL,16,2)
        score_mod_vbox.add(score_mod_table)
        self.score_mod_spinbutton=gtk.SpinButton(gtk.Adjustment(value=100,lower=-9999,upper=9999,step_incr=100,page_incr=1000))
        self.score_mod_spinbutton.set_size_request(130,-1)
        score_mod_hbox.pack_start(self.score_mod_spinbutton,True,False,2)

        #add rule button
        self.add_rule_button=gtk.Button(_("Add Rule"))
        self.add_rule_button.connect("clicked",self.add_new_rule)

        new_rule_vbox.pack_start(scope_vbox,False,True,2)
        new_rule_vbox.pack_start(condition_main_vbox,True,True,2)
        new_rule_vbox.pack_start(score_mod_vbox,True,True,2)
        new_rule_vbox.pack_start(self.add_rule_button,True,False,2)
        new_rule_label=gtk.Label("<b>"+_("New Scoring Rule")+"</b>")
        new_rule_label.set_use_markup(True)
        self.notebook.append_page(new_rule_vbox,new_rule_label)



        #New Action Rule Page
        new_action_rule_vbox=gtk.VBox()
        new_action_rule_vbox.set_border_width(4)

        action_scope_vbox=gtk.VBox()
        action_scope_vbox.set_border_width(4)
        action_scope_label=gtk.Label("<b>"+_("Groups Scope")+"</b>")
        action_scope_label.set_use_markup(True)
        action_scope_label.set_alignment(0,0.5)
        action_scope_vbox.pack_start(action_scope_label,False,False,4)
        self.action_scope_combo=gtk.combo_box_entry_new_text()
        popdown=self.score_rules.raw_scopes
        if "[*]" not in popdown:
            popdown.insert(0,"[*]")
        subscribed=self.art_db.getSubscribed()
        subscribed=["["+subscribed[i][0]+"]" for i in range(len(subscribed))]
        popdown=popdown+subscribed
        for item in popdown:
            self.action_scope_combo.append_text(item)
        self.action_scope_combo.set_active(0)
        self.action_scope_combo.set_size_request(250,-1)
        action_scope_hbox=gtk.HBox()
        action_scope_hbox.set_border_width(4)
        action_scope_hbox.pack_start(self.action_scope_combo,True,False,2)
        action_scope_vbox.add(action_scope_hbox)

        action_condition_main_vbox=gtk.VBox()
        action_condition_label=gtk.Label("<b>"+_("Condition")+"</b>")
        action_condition_label.set_alignment(0,0.5)
        action_condition_label.set_use_markup(True)
        action_condition_main_vbox.pack_start(action_condition_label,False,False,4)
        action_condition_table=gtk.Table(3,1,False)
        action_condition_hbox=gtk.HBox()
        self.action_header_opt_menu=gtk.combo_box_new_text()
        self.action_header_opt_menu.set_size_request(130,-1)
        for header in self.score_rules.action_headers:
            self.action_header_opt_menu.append_text(header.capitalize())
        self.action_header_opt_menu.set_active(0)
        action_condition_hbox.pack_start(self.action_header_opt_menu,True,False,2)
        values=[_("Contains String"),_("Doesn't Contain String"),_("Matches RegEx"),_("Doesn't Match RegEx"), _("Greater Than"), _("Not Greater Than"), _("Lower Than"),_("Not Lower Than"), _("Equal To (numbers only)"),_("Different From (numbers only)"), _("In Range"),_("Out Of Range")]
        self.action_match_type_opt_menu=gtk.combo_box_new_text()
        self.action_match_type_opt_menu.set_size_request(130,-1)
        for value in values:
            self.action_match_type_opt_menu.append_text(value)
        self.action_match_type_opt_menu.set_active(0)
        self.action_match_type_opt_menu.connect("changed",self.action_match_type_changed)
        action_condition_hbox.pack_start(self.action_match_type_opt_menu,True,False)
        self.action_case_checkbutton=gtk.CheckButton(_("Case Sensitive"))
        self.action_match_value_entry=gtk.Entry()
        self.action_match_value_entry.set_size_request(200,-1)
        self.action_match_value2_entry=gtk.Entry()
        self.action_match_value_label=gtk.Label(_("Lower Limit"))
        self.action_match_value2_label=gtk.Label(_("Upper Limit"))
        action_match_value_hbox=gtk.HBox()
        action_match_value_hbox.pack_start(self.action_match_value_label,True,False,2)
        action_match_value_hbox.pack_start(self.action_match_value_entry,True,True,2)
        action_match_value_hbox.pack_start(self.action_match_value2_label,True,False,2)
        action_match_value_hbox.pack_start(self.action_match_value2_entry,True,True,2)
        action_condition_table.attach(action_condition_hbox,0,1,0,1,gtk.EXPAND|gtk.FILL,gtk.FILL,16,6)
        action_condition_table.attach(action_match_value_hbox,0,1,1,2,gtk.EXPAND|gtk.FILL,gtk.FILL,16,6)
        action_condition_table.attach(self.action_case_checkbutton,0,1,2,3,gtk.EXPAND|gtk.FILL,gtk.FILL,16,6)
        action_condition_main_vbox.add(action_condition_table)


        action_vbox=gtk.VBox()
        action_label=gtk.Label("<b>"+_("Action")+"</b>")
        action_label.set_use_markup(True)
        action_label.set_alignment(0,0.5)
        action_vbox.pack_start(action_label,False,False,4)
        action_table=gtk.Table(1,1,False)
        action_hbox=gtk.HBox()
        action_setcolor_hbox=gtk.HBox()
        action_setcolor_color_hbox=gtk.HBox()
        values=[_("Kill"),_("Mark Read"),_("Mark Unread"),_("Mark for Download"),_("UnMark for Download"),_("Retrieve"),_("Keep"),_("UnKeep"),_("Watch"),_("Ignore"),_("UnSetWatchIgnore"),_("SetColor")]
        self.action_type_opt_menu=gtk.combo_box_new_text()
        for value in values:
            self.action_type_opt_menu.append_text(value)
        self.action_type_opt_menu.set_active(0)
        self.action_type_opt_menu.set_size_request(130,-1)
        self.action_type_opt_menu.connect("changed",self.action_type_changed)
        action_hbox.pack_start(self.action_type_opt_menu,True,False,2)
        self.color1_label=gtk.Label(_("Foreground Color"))
        self.color2_label=gtk.Label(_("Background Color"))
        self.color1_entry=gtk.Entry()
        self.color2_entry=gtk.Entry()
        self.color1_button=gtk.ColorButton()
        self.color2_button=gtk.ColorButton()
        self.color1_button.connect("color_set",self.get_color_from_button)
        self.color2_button.connect("color_set",self.get_color_from_button)
        action_setcolor_color_hbox.pack_start(self.color1_label,True,False)
        action_setcolor_color_hbox.pack_start(self.color2_label,True,False)
        action_setcolor_hbox.pack_start(self.color1_entry,True,False,2)
        action_setcolor_hbox.pack_start(self.color1_button,True,False,2)
        action_setcolor_hbox.pack_start(self.color2_entry,True,False,2)
        action_setcolor_hbox.pack_start(self.color2_button,True,False,2)
        action_table.attach(action_hbox,0,1,0,1,gtk.EXPAND|gtk.FILL,16,6)
        action_table.attach(action_setcolor_color_hbox,0,1,1,2,gtk.EXPAND|gtk.FILL,gtk.FILL,16,6)
        action_table.attach(action_setcolor_hbox,0,1,2,3,gtk.EXPAND|gtk.FILL,gtk.FILL,16,6)
        action_vbox.pack_start(action_table,True,True)

        #add action rule button
        self.add_action_rule_button=gtk.Button(_("Add Rule"))
        self.add_action_rule_button.connect("clicked",self.add_new_action_rule)

        new_action_rule_vbox.pack_start(action_scope_vbox,False,True,2)
        new_action_rule_vbox.pack_start(action_condition_main_vbox,True,True,2)
        new_action_rule_vbox.pack_start(action_vbox,True,True,2)
        new_action_rule_vbox.pack_start(self.add_action_rule_button,True,False,2)
        new_action_rule_label=gtk.Label("<b>"+_("New Action Rule")+"</b>")
        new_action_rule_label.set_use_markup(True)
        self.notebook.append_page(new_action_rule_vbox,new_action_rule_label)



        #RegEx Tester Page
        re_tester_vbox=gtk.VBox()
        re_tester_vbox.set_border_width(4)

        re_vbox=gtk.VBox()
        re_label=gtk.Label("<b>"+_("Regular Expression")+"</b>")
        re_label.set_use_markup(True)
        re_label.set_alignment(0,0.5)
        re_vbox.pack_start(re_label,False,False,4)
        re_table=gtk.Table(1,1,False)
        re_table.set_border_width(2)
        self.re_entry=gtk.Entry()
        re_test_button=gtk.Button(_("Test Regular Expression"))
        re_test_button.connect("clicked",self.test_re)
        self.test_case_checkbutton=gtk.CheckButton(_("Case Sensitive"))
        re_table.attach(self.re_entry,0,1,0,1,gtk.EXPAND|gtk.FILL,gtk.FILL,16,6)
        re_table.attach(self.test_case_checkbutton,0,1,1,2,gtk.EXPAND|gtk.FILL,gtk.FILL,16,6)
        re_table.attach(re_test_button,0,1,2,3,gtk.EXPAND|gtk.FILL,gtk.FILL,16,6)
        re_vbox.add(re_table)
        re_tester_vbox.pack_start(re_vbox,False,True,2)

        text_vbox=gtk.VBox()
        text_label=gtk.Label("<b>"+_("Test Text")+"</b>")
        text_label.set_alignment(0,0.5)
        text_label.set_use_markup(True)
        text_vbox.pack_start(text_label,False,False,4)
        text_table=gtk.Table(1,1,False)
        text_scrolledwin=gtk.ScrolledWindow()
        text_scrolledwin.set_border_width(4)
        text_scrolledwin.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
        text_scrolledwin.set_shadow_type(gtk.SHADOW_ETCHED_IN)
        self.text_buffer=gtk.TextBuffer()
        self.text_view=gtk.TextView(self.text_buffer)
        self.text_view.set_border_width(4)
        text_scrolledwin.add(self.text_view)
        text_table.attach(text_scrolledwin,0,1,0,1,gtk.EXPAND|gtk.FILL,gtk.EXPAND|gtk.FILL,16)
        text_vbox.pack_start(text_table,True,True)
        re_tester_vbox.pack_start(text_vbox,True,True,2)

        re_tester_label=gtk.Label("<b>"+_("RE Tester")+"</b>")
        re_tester_label.set_use_markup(True)
        self.notebook.append_page(re_tester_vbox,re_tester_label)

        #OK CANCEL buttons
        main_buttons_hbox=gtk.HBox()
        main_buttons_hbox.set_border_width(4)

        cancel_button=gtk.Button(None,gtk.STOCK_CANCEL)
        cancel_button_tooltip=gtk.Tooltips()
        cancel_button_tooltip.set_tip(cancel_button,_("Close window. Discard changes"))
        cancel_button.connect("clicked",self.destroy)
        main_buttons_hbox.pack_start(cancel_button,True,True,0)
        ok_button=gtk.Button(None,gtk.STOCK_OK)
        ok_button_tooltip=gtk.Tooltips()
        ok_button_tooltip.set_tip(ok_button,_("Close window. Save Changes"))
        ok_button.connect("clicked",self.close_window)
        main_buttons_hbox.pack_start(ok_button,True,True,2)

        vpaned.set_position(200)
        main_vbox.pack_start(self.notebook,True,True,0)

        main_vbox.pack_start(main_buttons_hbox,False,False,0)
        self.window.add(main_vbox)


        #some init
        self.show_rules()

        tag_table=self.text_buffer.get_tag_table()
        tag_match=gtk.TextTag("match")
        tag_table.add(tag_match)
        color_bg=gtk.gdk.color_parse("#0000FF")
        color_fg=gtk.gdk.color_parse("#FFFFFF")
        tag_match.set_property("weight",1000)
        tag_match.set_property("background-gdk",color_bg)
        tag_match.set_property("foreground-gdk",color_fg)




if __name__=="__main__":
    Score_Rules()
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.