def __init__(self, server, port, nick, user, password, ssl, chans=None, debug=False, default_quit_reason='*poof*', default_reset_reason='reset', max_message_size=420, callback_pubmsg=None, throttle_seconds=1.6, logger=None): BaseClass.__init__(self, logger=logger) self.trace(overrides={'password': '******'}) # data self.address = server self.port = port self.nick = nick self.user = user self.password = password self.ssl = ssl self.chans = chans self.callback_pubmsg = callback_pubmsg # configuration irclib.DEBUG = debug self.default_quit_reason = default_quit_reason self.default_reset_reason = default_reset_reason self.max_message_size = max_message_size self.throttle = throttle_seconds # throttled message queuing self.queue = [] # list of messages to send self.next_send = time.time( ) # minimum epoch time when next message can be sent self.last_size = 0 # size of last message sent (used to increase wait time for long messages) # IRC backend self.irc = irclib.IRC() self.irc.add_global_handler('pubmsg', self.onPublicMessage) self.server = self.irc.server() self.server.add_global_handler('welcome', self.onConnect) self.server.add_global_handler('disconnect', self.onDisonnect)
def __init__( self, server, port, nick, user, password, ssl, chans = None, debug = False, default_quit_reason = '*poof*', default_reset_reason = 'reset', max_message_size = 420, callback_pubmsg = None, throttle_seconds = 1.6, logger = None ): BaseClass.__init__( self, logger = logger ) self.trace(overrides = {'password':'******'}) # data self.address = server self.port = port self.nick = nick self.user = user self.password= password self.ssl = ssl self.chans = chans self.callback_pubmsg = callback_pubmsg # configuration irclib.DEBUG = debug self.default_quit_reason = default_quit_reason self.default_reset_reason = default_reset_reason self.max_message_size = max_message_size self.throttle = throttle_seconds # throttled message queuing self.queue = [] # list of messages to send self.next_send = time.time() # minimum epoch time when next message can be sent self.last_size = 0 # size of last message sent (used to increase wait time for long messages) # IRC backend self.irc = irclib.IRC() self.irc.add_global_handler( 'pubmsg', self.onPublicMessage ) self.server = self.irc.server() self.server.add_global_handler( 'welcome', self.onConnect ) self.server.add_global_handler( 'disconnect', self.onDisonnect )
def __init__(self, username, password, user_agent, obey_robot_rules=False, max_api_items=200, logger=None): BaseClass.__init__(self, logger=logger) self.trace(overrides={'password': '******'}) # configuration self.username = username self.password = password self.max_api_items = max_api_items # browser self.browser = mechanize.Browser(factory=mechanize.RobustFactory()) self.browser.addheaders = [('User-agent', user_agent)] self.browser.set_handle_robots(obey_robot_rules) # variables self.path_article = None self.path_index = None self.path_api = None self.url_base = None self.url_article = None self.url_index = None self.url_api = None self.def_path_article = None self.def_path_index = None self.def_path_api = None self.def_url_base = None self.def_url_article = None self.def_url_index = None self.def_url_api = None # tracking self.sessions = { } # data for each session: { base_url:{logged_in:NAME, tokens:{edit:..., protect:..., ...}} } self.response = None # response, created by load() self.last_url = None # last URL loaded, dumped on exception self.text = None # text of last page fetched self.parsed = None # result of parsing text (if asked to), either data structure or parser
def __init__( self, username, password, user_agent, obey_robot_rules = False, max_api_items = 200, logger = None ): BaseClass.__init__( self, logger = logger ) self.trace(overrides = {'password':'******'}) # configuration self.username = username self.password = password self.max_api_items = max_api_items # browser self.browser = mechanize.Browser(factory=mechanize.RobustFactory()) self.browser.addheaders = [('User-agent', user_agent)] self.browser.set_handle_robots( obey_robot_rules ) # variables self.path_article = None self.path_index = None self.path_api = None self.url_base = None self.url_article = None self.url_index = None self.url_api = None self.def_path_article = None self.def_path_index = None self.def_path_api = None self.def_url_base = None self.def_url_article = None self.def_url_index = None self.def_url_api = None # tracking self.sessions = {} # data for each session: { base_url:{logged_in:NAME, tokens:{edit:..., protect:..., ...}} } self.response = None # response, created by load() self.last_url = None # last URL loaded, dumped on exception self.text = None # text of last page fetched self.parsed = None # result of parsing text (if asked to), either data structure or parser
def __init__(self, tree, logger, default=None): BaseClass.__init__(self, logger=logger) self.trace() self.tree = copy(tree) self.default = default
def __init__(self, logger): BaseClass.__init__(self, logger=logger) self.trace() random.seed() self.new = [ # direct quotes '<Pathoschild> You can do tabs in Python, but you can\'t mix tab and space indenting. * Mike_lifeguard weeps <Mike_lifeguard> why did nobody tell me?', '<Prodego> Razorflame: btw, there are no quotes of me because I am a non-funny person', ' <DerHexer> where have all the stewbots gone | long time passing | where have all the stewbots gone | long time ago | where have all the stewbots gone | *poof* picked them everyone | when will he ever come back | when will he ever come back', # <http://meta.wikimedia.org/wiki/Bash> '<Werdna> When all is said and done on Wikipedia, a hell of a lot more is said than done.', '<chowbok> What\'s an "almost monopoly"? Is that like "slightly pregnant"?', '<Nilfanion> {{PD-Magic}}: This image is ineligible for copyright and therefore is in the public domain, because it consists entirely of information created by magic.', '<ElNino^> Why the f**k is Bambi a male in the cartoon but a female in porno?', '<Warm_fuzzies> I for one welcome our new sexually transmitted overlords', '<Gwern> when I was working on Helpdesk-l, we literally got emails telling us that we accidentally left our articles publicly editable.', '<kaiti> lmao, if you search for "p**n" in Windows XP\'s Help and Support program, it recommends the article on how to use Internet Explorer.', '<DavidGerard> personally, I agree with everything DavidGerard says and think you should all stfu. <DavidGerard> we can vote on it. <DavidGerard> I agree too.', '<Lunaway> You know you\'ve got too many tabs open when you manage to edit-conflict yourself.', '<Zero1328> I\'ve had one dream about editing Wikipedia, and it was pretty scary. Every time I made an edit I got an edit conflict. I couldn\'t make any changes at all.', '<Shadow42> bastique: They\'re raping my sprinklers!', '<TehKewl1> omgwtfbbqlolaslsendpixd00dipwntj00andj00arenolonger1337lolroflmaopwntpwnt. <TehKewl1> I mean.... hi.', '<01:46> TehKewl1 has left #wikipedia ("/me has been on irc too long"). <01:46> TehKewl1 has joined #wikipedia.', '<wmarsh> Heh, I apparently violated the established protocol for editting a page, established by editors of that page. The thing is, the page is in my own userspace.', '<ice_cream> ok ok i\'ll chill.', '<Luna-San> I heard a rumor that Wikipedia\'s server farm is powered by setting a bunch of kids up with giant hampster wheels and telling them their garage band\'s article is up for AfD.', '<Luna-San> I\'ve just run into a gang logo that is now officially available under the terms of the GFDL. <Luna-San> ...they don\'t seem very thuggish anymore', '<kaiti> i went to read about chatzilla bugs <kaiti> and firefox crashed.', '<NiklasNordblad> editing is life. :D <GerardM> well then I have a life.', '<SushiGeek> Dmcsleep needs to have a lanyard that he can wear around his neck that beeps loudly when somebody needs a checkuser. <SushiGeek> so when he\'s sleeping somebody can go "BEEP BEEP CHECKUSER".', '* helix84 still wonders if someone is still messing with his patch. <RealGrouchy> nicotine not flowing?', '* brion needs a dual-core oven', '<brion> it\'s xmas, so i\'m going to be nice and not WONTFIX this feature request just yet', '<brion> http://bugzilla.wikimedia.org/show_bug.cgi?id=42 ... appropriate somehow', '<gmaxwell> Sorry. The wikimedia orbital space laser is controlled by toolserver, as a result it seldom works.', '<barklund> you say there are more than 1 db request at a time? :) <intgr> Nah, Wikipedia can\'t be that popular.', '<Simetrical> Now, why do we have wikis for extinct languages again? <larne> Simetrical: because the foundation\'s mission is to distribute knowledge to dead people.', '<VoiceOfAll> yes, all straight socks <VoiceOfAll> (as opposed to gay socks)', '<flyingparchment> when official people are saying the same things as me trolling on irc, i think we might have operational issues', '<gwern> what viagra spam would cats get? \'is ur d1ck not spiny enuff? does she only mewl and not yowl when you pull backwards? get premium V I A G R A now, meow!\'', '<Aviator> i wonder why the stable server is such an unstable server', '<[21655]> it\'s called Sense of Humour. Your copy must have expired... <[21655]> ...may I recommend version 2.0 w/ added sarcasm?', '* drini has some theory about the vandalbots on enwiki a few years ago, you know those "OMG SHANEL HAS HUGE BOOBS" thing. <drini> I think the bot master was pathoschild hitting on shanel', '<Species8472> Jimbo? Isn\'t that the guy banned for editting articles about himself?', '* kylu hms... kylu\'s bedroom is oddly enough nearly all browns and tans. * kylu supposes that\'s why kylu\'s so boring. ;.; <harej> kylu has an ubunturoom', '<_mary_kate_> something is wrong with the fi.wikipedia. instead of being written in a human language, it\'s just full of weird letters.', '<mattbuck> The following is an announcement on behalf of Wikimedia Commons: People of wikipedia, if you don\'t want to see a penis, DON\'T SEARCH FOR PENIS. Thankyou, that is all.', '<Until_It_Sleeps> .count I really suck, because my penis <SoxBot> I really suck, because my penis has 7 contributions. For more info, see http://toolserver.org/~soxred93/ec/I_really_suck%2C_because_my_penis', '<NuclearWarfare> !delete [[zh-yue:??????]] r=Vandalism. <Dellieplagiat> NuclearWarfare: [[zh-yue:??????]] has been scheduled for termination. <kylu> y\'know, there\'s something kinda ominous about "NuclearWarfare: [[zh-yue:(something in chinese)]] has been scheduled for termination".', '<Ironholds> right, what general subject should I write an article on <Neurolysis> my enormous member <Ironholds> isn\'t that a stub?', '<slakr> "You\'re such an idiot for thinking I violated WP:CIVIL and WP:NPA. You\'re clearly an asshole for even making that assumption"', '<Thrawn> if you\'re hated by WR, that means you\'re probably doing an excellent job', '<La_Pianista> Did you know that Debussy once wrote a piece called, "Jimbo\'s Lullaby"? <Freudian|Sleep> was it then renamed to "Sagner\'s Co-Lullaby"?', # <https://bugzilla.wikimedia.org/quips.cgi?action=show> '[quip] I spent a minute looking at my own code by accident. I was thinking "What the hell is this guy doing?"', '<jwales> What good is having a war mongering President if we can\'t invade Estonia to kill spammers? I AM JOKING DO NOT QUOTE ME ON THAT. :-)', '<Raul654> come on, isn\'t anyone here an admin on meta? <BillyH> I think Raul654 is.', '<AlexS> Dear diary: No wikipedia today. Had to go outside and see real people again.', '<ilya> I don\'t know what to do and where to go. Outer world seems uneditable.', '<snoyes> looking for NPOV female; 5k - 10k edits, to edit together, nothing long-term just a couple of one-night contributions.', '<TimShell> Is there an IRC client that has a command that will allow me to physically hurt another user, because I would find that useful', '<TimStarling> It was a bad idea. The users made me do it.', '<TimStarling> I know how the MediaWiki namespace works, I invented it.', '<TimStarling> globals are magical structures, like little winged monkeys that fly your data from wherever it is generated to wherever it is needed.', '<TimStarling> temporary solutions have a terrible habit of becoming permanent, around here.', '<brion> well breaking wikipedia gets real f*****g old :)', '<kylu> I suspect wikipedia has resulted in more than one broken human husk staring vacantly at flickering screens in darkened basement rooms somewhere, the eyeless sockets of the long-departed locked onto some imperceptible virtual distance, where a lost soul travels the lonely off-roads away from the information superhighway. the smell of ozone and Dorito crumbs the only comfort to that former person\'s parents, the Diet Coke long ago having gone flat.', ] self.old = [] self.chloe_new = [ 'Moosh!', 'Jesse tinky!', 'Where Jessenel? :(', 'So sad, so lost. :(', 'Noooo, Chlo� perfect! :D', '*pout*', 'Dat gwandad, a pain!', 'Chlo� hungwy!', 'Where Michael be?', 'Chlo� 5 years old. Chlo� go school!', 'Germs-a-gone', 'Germs est parti!', 'No naughty chair! >:(', 'Chloe play game! >:(', 'Mommy come get me? :(', 'Look nel! Look nel!', 'Opsicle, opsicle! :o', 'Play fish game! >:(', 'Hmph. Not fair!' ] self.chloe_old = [] self.exit_new = [ 'Laaaaze. :D', 'Wai so srs? ._.', ':(', 'I\'ll remember this.', 'Acknowledged. Safely putting away knives... done.', 'So flee youthful passions and pursue righteousness, faith, love, and peace, along with those who call on the Operator from a pure heart.' ]
def __init__(self, logger): BaseClass.__init__(self, logger=logger) self.trace() random.seed() # Directly collects bash quotations from [[:m:IRC/Quotes]] f = urllib.urlopen("http://meta.wikimedia.org/w/api.php?action=query&titles=IRC/Quotes&export") text = f.read() text = unescape(unescape(text)) text = unescape(text, {""": '"'}) text = text.replace("Please leave the </nowiki></pre> above as-is", "") text = text[text.rindex("<pre><nowiki>") + len("<pre><nowiki>") : text.rindex("</nowiki></pre>")] text = re.sub(u'<a href=".+">', "", text) text = text.replace("</a>", "") text = re.sub("\n%( |\t)*\n", "{[$MARKER$]}", text) text = text.replace("\n", " ") self.new = text.split("{[$MARKER$]}")[1:-1] # self.new = [ # # direct quotes # '<Pathoschild> You can do tabs in Python, but you can\'t mix tab and space indenting. * Mike_lifeguard weeps <Mike_lifeguard> why did nobody tell me?', # '<Prodego> Razorflame: btw, there are no quotes of me because I am a non-funny person', # ' <DerHexer> where have all the stewbots gone | long time passing | where have all the stewbots gone | long time ago | where have all the stewbots gone | *poof* picked them everyone | when will he ever come back | when will he ever come back', # <http://meta.wikimedia.org/wiki/Bash> # '<Werdna> When all is said and done on Wikipedia, a hell of a lot more is said than done.', # '<chowbok> What\'s an "almost monopoly"? Is that like "slightly pregnant"?', # '<Nilfanion> {{PD-Magic}}: This image is ineligible for copyright and therefore is in the public domain, because it consists entirely of information created by magic.', # '<ElNino^> Why the f**k is Bambi a male in the cartoon but a female in porno?', # '<Warm_fuzzies> I for one welcome our new sexually transmitted overlords', # '<Gwern> when I was working on Helpdesk-l, we literally got emails telling us that we accidentally left our articles publicly editable.', # '<kaiti> lmao, if you search for "p**n" in Windows XP\'s Help and Support program, it recommends the article on how to use Internet Explorer.', # '<DavidGerard> personally, I agree with everything DavidGerard says and think you should all stfu. <DavidGerard> we can vote on it. <DavidGerard> I agree too.', # '<Lunaway> You know you\'ve got too many tabs open when you manage to edit-conflict yourself.', # '<Zero1328> I\'ve had one dream about editing Wikipedia, and it was pretty scary. Every time I made an edit I got an edit conflict. I couldn\'t make any changes at all.', # '<Shadow42> bastique: They\'re raping my sprinklers!', # '<TehKewl1> omgwtfbbqlolaslsendpixd00dipwntj00andj00arenolonger1337lolroflmaopwntpwnt. <TehKewl1> I mean.... hi.', # '<01:46> TehKewl1 has left #wikipedia ("/me has been on irc too long"). <01:46> TehKewl1 has joined #wikipedia.', # '<wmarsh> Heh, I apparently violated the established protocol for editting a page, established by editors of that page. The thing is, the page is in my own userspace.', # '<ice_cream> ok ok i\'ll chill.', # '<Luna-San> I heard a rumor that Wikipedia\'s server farm is powered by setting a bunch of kids up with giant hampster wheels and telling them their garage band\'s article is up for AfD.', # '<Luna-San> I\'ve just run into a gang logo that is now officially available under the terms of the GFDL. <Luna-San> ...they don\'t seem very thuggish anymore', # '<kaiti> i went to read about chatzilla bugs <kaiti> and firefox crashed.', # '<NiklasNordblad> editing is life. :D <GerardM> well then I have a life.', # '<SushiGeek> Dmcsleep needs to have a lanyard that he can wear around his neck that beeps loudly when somebody needs a checkuser. <SushiGeek> so when he\'s sleeping somebody can go "BEEP BEEP CHECKUSER".', # '* helix84 still wonders if someone is still messing with his patch. <RealGrouchy> nicotine not flowing?', # '* brion needs a dual-core oven', # '<brion> it\'s xmas, so i\'m going to be nice and not WONTFIX this feature request just yet', # '<brion> http://bugzilla.wikimedia.org/show_bug.cgi?id=42 ... appropriate somehow', # '<gmaxwell> Sorry. The wikimedia orbital space laser is controlled by toolserver, as a result it seldom works.', # '<barklund> you say there are more than 1 db request at a time? :) <intgr> Nah, Wikipedia can\'t be that popular.', # '<Simetrical> Now, why do we have wikis for extinct languages again? <larne> Simetrical: because the foundation\'s mission is to distribute knowledge to dead people.', # '<VoiceOfAll> yes, all straight socks <VoiceOfAll> (as opposed to gay socks)', # '<flyingparchment> when official people are saying the same things as me trolling on irc, i think we might have operational issues', # '<gwern> what viagra spam would cats get? \'is ur d1ck not spiny enuff? does she only mewl and not yowl when you pull backwards? get premium V I A G R A now, meow!\'', # '<Aviator> i wonder why the stable server is such an unstable server', # '<[21655]> it\'s called Sense of Humour. Your copy must have expired... <[21655]> ...may I recommend version 2.0 w/ added sarcasm?', # '* drini has some theory about the vandalbots on enwiki a few years ago, you know those "OMG SHANEL HAS HUGE BOOBS" thing. <drini> I think the bot master was pathoschild hitting on shanel', # '<Species8472> Jimbo? Isn\'t that the guy banned for editting articles about himself?', # '* kylu hms... kylu\'s bedroom is oddly enough nearly all browns and tans. * kylu supposes that\'s why kylu\'s so boring. ;.; <harej> kylu has an ubunturoom', # '<_mary_kate_> something is wrong with the fi.wikipedia. instead of being written in a human language, it\'s just full of weird letters.', # '<mattbuck> The following is an announcement on behalf of Wikimedia Commons: People of wikipedia, if you don\'t want to see a penis, DON\'T SEARCH FOR PENIS. Thankyou, that is all.', # '<Until_It_Sleeps> .count I really suck, because my penis <SoxBot> I really suck, because my penis has 7 contributions. For more info, see http://toolserver.org/~soxred93/ec/I_really_suck%2C_because_my_penis', # '<NuclearWarfare> !delete [[zh-yue:??????]] r=Vandalism. <Dellieplagiat> NuclearWarfare: [[zh-yue:??????]] has been scheduled for termination. <kylu> y\'know, there\'s something kinda ominous about "NuclearWarfare: [[zh-yue:(something in chinese)]] has been scheduled for termination".', # '<Ironholds> right, what general subject should I write an article on <Neurolysis> my enormous member <Ironholds> isn\'t that a stub?', # '<slakr> "You\'re such an idiot for thinking I violated WP:CIVIL and WP:NPA. You\'re clearly an asshole for even making that assumption"', # '<Thrawn> if you\'re hated by WR, that means you\'re probably doing an excellent job', # '<La_Pianista> Did you know that Debussy once wrote a piece called, "Jimbo\'s Lullaby"? <Freudian|Sleep> was it then renamed to "Sagner\'s Co-Lullaby"?', # <https://bugzilla.wikimedia.org/quips.cgi?action=show> # '[quip] I spent a minute looking at my own code by accident. I was thinking "What the hell is this guy doing?"', # '<jwales> What good is having a war mongering President if we can\'t invade Estonia to kill spammers? I AM JOKING DO NOT QUOTE ME ON THAT. :-)', # '<Raul654> come on, isn\'t anyone here an admin on meta? <BillyH> I think Raul654 is.', # '<AlexS> Dear diary: No wikipedia today. Had to go outside and see real people again.', # '<ilya> I don\'t know what to do and where to go. Outer world seems uneditable.', # '<snoyes> looking for NPOV female; 5k - 10k edits, to edit together, nothing long-term just a couple of one-night contributions.', # '<TimShell> Is there an IRC client that has a command that will allow me to physically hurt another user, because I would find that useful', # '<TimStarling> It was a bad idea. The users made me do it.', # '<TimStarling> I know how the MediaWiki namespace works, I invented it.', # '<TimStarling> globals are magical structures, like little winged monkeys that fly your data from wherever it is generated to wherever it is needed.', # '<TimStarling> temporary solutions have a terrible habit of becoming permanent, around here.', # '<brion> well breaking wikipedia gets real f*****g old :)', # '<kylu> I suspect wikipedia has resulted in more than one broken human husk staring vacantly at flickering screens in darkened basement rooms somewhere, the eyeless sockets of the long-departed locked onto some imperceptible virtual distance, where a lost soul travels the lonely off-roads away from the information superhighway. the smell of ozone and Dorito crumbs the only comfort to that former person\'s parents, the Diet Coke long ago having gone flat.', # ] self.old = [] self.chloe_new = [ "Moosh!", "Jesse tinky!", "Where Jessenel? :(", "So sad, so lost. :(", "Noooo, Chlo� perfect! :D", "*pout*", "Dat gwandad, a pain!", "Chlo� hungwy!", "Where Michael be?", "Chlo� 5 years old. Chlo� go school!", "Germs-a-gone", "Germs est parti!", "No naughty chair! >:(", "Chloe play game! >:(", "Mommy come get me? :(", "Look nel! Look nel!", "Opsicle, opsicle! :o", "Play fish game! >:(", "Hmph. Not fair!", ] self.chloe_old = [] self.exit_new = [ "Laaaaze. :D", "Wai so srs? ._.", ":(", "I'll remember this.", "Acknowledged. Safely putting away knives... done.", "So flee youthful passions and pursue righteousness, faith, love, and peace, along with those who call on the Operator from a pure heart.", ]
def __init__( self, tree, logger, default = None ): BaseClass.__init__( self, logger = logger ) self.trace() self.tree = copy( tree ) self.default = default
def __init__( self, commands, # hash of levels and commands: {0:['foo',...], 1:[...]} users, # hash of levels and users: {1:['person',...], 2:[...]} logger, # an ILogger implementation to send log messages to callback = None, # an instance; if not None, it will call: # - handle_<command> for valid commands; # - handle_None for valid command if handle_<command> not defined; # - handle_Error for errors; # - handle_Commit for commit command, with queued command as data.queued (else calls queued command's handler) # - handle_Queued if command queued for commit. banned = None, # array of regexes to match against the hostmask, for ignored users command_prefix = '!~', # characters to recognize as the start of a command at beginning of line command_delimiter = '<>', # characters to recognize as delimiters between arguments handle_commit = True, # handle !commit and !cancel? no_commit_commands = None, # array of commands that cannot be !commit'd commit_req_user_level = 1, # access level required to queue a command for !commit commit_imp_user_level = 2, # access level required to !commit a queued command ): BaseClass.__init__( self, logger = logger ) self.trace() # constants self.ERROR = 0 self.IGNORED = 1 self.OKAY = 2 self.COMMIT = 3 self.USER_BANNED = -9 self.NOT_COMMAND = -8 self.BLANK_ARGS = -7 self.NO_COMMIT_ID_GIVEN = -6 self.NO_SUCH_COMMIT_ID = -5 self.CANNOT_COMMIT = -4 self.NOT_ALLOWED = -3 self.HANDLED = -2 self.MUST_COMMIT = -1 # flag associations and descriptions self.flags = { # summary flags self.ERROR:[None, 'ERROR', 'An error has occurred (see data.flag property)'], self.IGNORED:[None, 'IGNORED', 'The input was ignored (see data.flag property)'], # detail flags self.USER_BANNED:[self.IGNORED, 'USER_BANNED', 'You are banned from giving me commands'], self.NOT_COMMAND:[self.IGNORED, 'NOT_COMMAND', 'That is not recognized as a command'], self.BLANK_ARGS:[self.ERROR, 'BLANK_ARGS', 'Arguments cannot be blank'], self.NOT_ALLOWED:[self.ERROR, 'NOT_ALLOWED', 'No'],#'You have insufficient access to issue that command'], self.CANNOT_COMMIT:[self.ERROR, 'CANNOT_COMMIT', 'You have insufficient access to issue that command, and it cannot be committed'], self.NO_SUCH_COMMIT_ID:[self.ERROR, 'NO_SUCH_COMMIT_ID', 'No commit id'], self.NO_COMMIT_ID_GIVEN:[self.ERROR, 'NO_COMMIT_ID_GIVEN', 'No commit id specified'], self.MUST_COMMIT:[self.MUST_COMMIT, 'MUST_COMMIT', 'The command has been queued for !commit'], self.OKAY:[self.OKAY, 'OKAY', 'The command was parsed and validated, and awaits implementation'] } # input self.command_groups = commands self.callback = callback self.user_groups = users self.banned_users = banned self.handle_commit = handle_commit self.no_commit = (no_commit_commands if no_commit_commands is not None else []) self.cmd_prefix = command_prefix self.cmd_delim = command_delimiter self.commit_req_level = commit_req_user_level self.commit_imp_level = commit_imp_user_level # tracking variables self.commit_id = -1 self.commit_queue = {} # handle commit & cancel if self.handle_commit: # add level to command if self.commit_imp_level not in self.command_groups: self.command_groups[self.commit_imp_level] = [] # add to lists for cmd in ('commit', 'cancel'): self.command_groups[self.commit_imp_level].append( cmd ) self.no_commit.append( cmd ) # lookup hashes self.command_hash = {} self.user_hash = {} for group in commands: for command in self.command_groups[group]: self.command_hash[command] = group or 0 for group in self.user_groups: for user in self.user_groups[group]: if user in self.user_hash: raise ValueError( "Cannot parse user access list, user '%s' is assigned multiple access levels (%s, %s)" % (user, self.user_hash[user], group) ) self.user_hash[user] = group # build regexes self.re_possible_cmd = re.compile( '^[%s]\S' % self.cmd_prefix ) self.re_has_args = re.compile( '^.[^%s\s]+(\s*[%s]|\s+[^%s])' % (self.cmd_delim, self.cmd_delim, self.cmd_delim) ) self.re_parse_cmd = re.compile( '^.([^%s\s]+)(?:\s*[%s]\s*|\s+|$)(.*)$' % (self.cmd_delim, self.cmd_delim) ) self.re_split_args = re.compile( '\s*[%s]\s*' % self.cmd_delim ) if banned and len(banned): self.re_banned_mask = re.compile( '|'.join(self.banned_users) ) else: self.re_banned_mask = None
def __init__( self, server, port, nick, user, password, channels, ssl, logger, config, documentation, exceptionLogger = None ): BaseClass.__init__( self, logger ) self.__name__ = 'Stewardbot' self.trace(overrides = {'password':'******'}) ############# ## Commands ############# self.irc_commands = config.irc.commands ############# ## Configuration ############# # exception logger self.config = config self.exceptionLogger = (exceptionLogger if exceptionLogger is not None else logger) # default runtime config self.options = { 'confirm_all':config.irc.confirm_all } self.irc_commands_help = documentation # irc users self.users = config.irc.wiki_names_by_level self.wiki_names = config.irc.wiki_names self.INDEX_USERS = ACCESS_WHITELISTED self.INDEX_OPERATORS = ACCESS_OPERATOR ############# ## Classes ############# self.help = Documentation( documentation, logger = logger ) self.bash = Bash(logger = logger) self.parser = CommandParser( commands = config.irc.commands_by_level, callback = self, users = config.irc.users_by_level, banned = config.irc.ignore_masks, command_prefix = config.irc.command_prefix, command_delimiter = config.irc.command_delimiter, no_commit_commands = config.irc.commands_nocommit, logger = logger, handle_commit = config.irc.handle_commit ) self.browser = Browser( username = config.web.user, password = config.web.password, user_agent = config.web.user_agent, max_api_items = config.web.max_api_items, default_base_url = config.web.default_base_url, logger = logger ) self.browser.login() self.irc = IRC( server = server, port = port, nick = nick, user = user, password = password, chans = channels, ssl = ssl, default_quit_reason = config.irc.quit_reason, callback_pubmsg = self.onPublicMessage, logger = logger ) self.connect()