def _readApiKey(fil='key.api'): log.info('Loading API key') dir_path = Path(os.path.dirname(os.path.realpath(__file__))) log.info(str(dir_path)) with open(dir_path / fil) as api_file: key = api_file.readline() return key
def reboot(self, irc, msg, args, vmname): """<vm> Reboots the vm Returns the status of migration """ username = self.user password = self.password vcenter = self.vcenter try: si = SmartConnect(host=vcenter, user=username, pwd=password, port=443) except: err_text = 'Error connecting to {0}'.format(vcenter) log.info(err_text) irc.reply(err_text) return # Finding source VM try: vm = vmutils.get_vm_by_name(si, vmname) except: irc.reply('{0} not found.'.format(vmname)) return try: vm.RebootGuest() except: vm.ResetVM_Task() irc.reply('Rebooting {0}'.format(vmname)) Disconnect(si)
def clone(self, irc, msg, args, optlist, vmname): """<vm> [--{mem, cpu, tmpl, pool, dnsdomain, vcenter}] option details: mem = 1024 (MB) - RAM cpu = 1 (int) - CPUs tmpl = centos6 (str) - template to use pool = DEV (str) - resource pool dnsdomain = domain.local (str) - dns domain search vcenter = vcenter1.domain.local - vcenter server Creates a vm from a template Returns the status of clone """ opts = dict(optlist) conf = {} conf['mem'] = opts.get('mem', 1024) conf['cpu'] = opts.get('cpu', 1) conf['tmpl'] = opts.get('tmpl', self.template) conf['pool'] = opts.get('pool', self.pool) conf['dnsdomain'] = opts.get('dnsdomain', self.vm_dnsdomain) conf['vcenter'] = opts.get('vcenter', self.vcenter) conf['name'] = vmname.lower() username = self.user password = self.password vm_username = self.vm_username vm_password = self.vm_password try: si = SmartConnect(host=conf['vcenter'], user=username, pwd=password, port=443) except IOError, e: log.info('Error connecting to {0}'.format(conf['vcenter'])) return
def flevel(self, irc, msg, args, level): """ Change your level """ dungeon = self.SpiffyWorld.get_dungeon_by_channel(GAME_CHANNEL) if dungeon is not None: user_id = self._get_user_id(irc, msg.prefix) unit = dungeon.get_unit_by_user_id(user_id) if unit is not None: int_level = int(level) xp_for_level = self.unit_level.get_xp_for_level(int_level) + 1 log.info("SpiffyRPG: setting xp for %s to %s (level %s)" % (unit.get_name(), xp_for_level, int_level)) unit.experience = xp_for_level unit.level = self.unit_level.get_level_by_xp(unit.experience) unit.on_unit_level() dungeon.announcer.unit_info(unit=unit, dungeon=dungeon, irc=irc) else: log.error("SpiffyRPG: could not find dungeon %s" % msg.args[0])
def sendEmail(self, irc, suser, duser, message): config = ConfigParser.ConfigParser() config.read(os.path.join(conf.supybot.directories.conf(), 'xmpp.conf')) # log.info(str(user)) if not config.has_section('Users'): config.add_section('Users') alias = self.aliasExists(duser, config) # log.info('Alias %s exists. Owner: %s' % (duser,alias)) if alias: email = config.get('Users', alias) else: email = None if email is not None: email = email.split(' ')[0] #subprocess.Popen(['python', '/.private/xmppScript/xmpp.py', '-t', email, '-m', message]) # REPLACE - xmpp email id jid = xmpp.protocol.JID(self.registryValue('auth.username')) cl = xmpp.Client(jid.getDomain(), debug=[]) connection = cl.connect(("talk.google.com", 5222)) if connection: # REPLACE - xmpp password auth = cl.auth(jid.getNode(), self.registryValue('auth.password'), resource=jid.getResource()) if auth: id = cl.send(xmpp.protocol.Message(email, message)) cl.disconnect() log.info('%s successfully sent a message to %s: %s' % (suser, duser, message)) return 0 else: log.error('XMPP: failed auth') return 3 else: log.error('XMPP: could not connect') return 2 else: return 1
def addAlias(self, irc, msg, origuser, user, alias, config): if not config.has_section('Users'): config.add_section('Users') atest = self.aliasExists(alias, config) if atest and atest != user.name.lower(): if atest == alias: irc.reply("You can not have an alias that is the name of a user.") return False irc.reply("%s already owns %s" % (atest,alias)) return False elif atest: if atest == alias: irc.reply("Why are you trying to have an alias that is your name?") return False # irc.reply("Error: You already own that alias") irc.reply("Your aliases: %s" % ", ".join(aliases)) return False aliases = config.get('Users', user.name).split(" ") if alias in aliases: # We should never reach here return False config.set('Users', user.name, " ".join(aliases) + " " + alias) aliases = aliases[1:] aliases.append(alias) log.info(str(aliases)) if origuser.name == user.name: irc.reply("Your aliases: %s" % ", ".join(aliases)) else: irc.reply("%s's aliases: %s" % (user.name, ", ".join(aliases))) return config
def _init_world(self): """ We need the nicks in the channel in order to initialize the world. """ db_path = conf.supybot.directories.data.dirize(SQLITE_DB_FILENAME) if self.db is None: database = Database(path=db_path, log=log) self.db = database.get_connection() assert self.db is not None if self.SpiffyWorld is None: log.info("Initializing world.") worldbuilder = Worldbuilder(db=self.db, irc=self.irc, ircmsgs=ircmsgs, ircutils=ircutils, log=log) spiffy_world = worldbuilder.build_world() self.SpiffyWorld = spiffy_world self._add_players_from_channel(new_player_nick=None) assert self.SpiffyWorld is not None
def doNick(self, irc, msg): """ Update player's nick if they change it """ old_nick = msg.prefix.split('!')[0] new_nick = msg.args[0] user_id = None try: hostmask = irc.state.nickToHostmask(new_nick) user_id = ircdb.users.getUserId(hostmask) except KeyError: log.info("SpiffyRPG: error getting hostmask for %s" % new_nick) if user_id is not None: dungeon = self.SpiffyWorld.get_dungeon_by_channel(GAME_CHANNEL) if dungeon is not None: unit = dungeon.get_player_by_user_id(user_id) if unit is not None: unit.nick = new_nick log.info("SpiffyRPG: nick change: %s is now known as %s, updating unit %s" % (old_nick, new_nick, unit.get_name()))
def racers(self, irc, msg, args): """takes no arguments Lists all users currently in sessions (not just races) """ logger.info("Command sent by " + str(msg.nick)) self.iRacingData.grabData() onlineDrivers = self.iRacingData.onlineDrivers() onlineDriverNames = [] for driver in onlineDrivers: name = driver.nameForPrinting() if driver.currentSession is not None: name += ' (%s)' % (driver.currentSession.sessionDescription) onlineDriverNames.append(name) if len(onlineDriverNames) == 0: response = self.NO_ONE_ONLINE_RESPONSE else: response = 'Online racers: %s' % utils.str.commaAndify( onlineDriverNames) irc.reply(response)
def startServer(): """Starts the HTTP server. Shouldn't be called from other modules. The callback should be an instance of a child of SupyHTTPServerCallback.""" global http_servers addresses4 = [(4, (x, configGroup.port())) for x in configGroup.hosts4() if x != ''] addresses6 = [(6, (x, configGroup.port())) for x in configGroup.hosts6() if x != ''] http_servers = [] for protocol, address in (addresses4 + addresses6): try: server = SupyHTTPServer(address, protocol, SupyHTTPRequestHandler) except OSError as e: log.error( 'Failed to start HTTP server with protocol %s at address: %s', protocol, address, e) if e.args[0] == 98: log.error( 'This means the port (and address) is already in use by an ' 'other process. Either find the process using the port ' 'and stop it, or change the port configured in ' 'supybot.servers.http.port.') continue except: log.exception( "Failed to start HTTP server with protocol %s at address", protocol, address) continue Thread(target=server.serve_forever, name='HTTP Server').start() http_servers.append(server) log.info('Starting HTTP server: %s' % str(server))
def onPayload(self, headers, payload): if "full_name" in payload["repository"]: repo = payload["repository"]["full_name"] elif "name" in payload["repository"]["owner"]: repo = "%s/%s" % (payload["repository"]["owner"]["name"], payload["repository"]["name"]) else: repo = "%s/%s" % (payload["repository"]["owner"]["login"], payload["repository"]["name"]) event = headers["X-GitHub-Event"] announces = self._load() if repo not in announces: log.info("Commit for repo %s not announced anywhere" % repo) return for channel in announces[repo]: for irc in world.ircs: if channel in irc.state.channels: break if event == "push": commits = payload["commits"] if channel not in irc.state.channels: log.info("Cannot announce commit for repo %s on %s" % (repo, channel)) elif len(commits) == 0: log.warning("GitHub push hook called without any commit.") else: hidden = None last_commit = commits[-1] if last_commit["message"].startswith("Merge ") and len(commits) > 5: hidden = len(commits) + 1 commits = [last_commit] payload2 = dict(payload) for commit in commits: payload2["__commit"] = commit self._createPrivmsg(irc, channel, payload2, "push", hidden) else: self._createPrivmsg(irc, channel, payload, event)
def onPayload(self, payload): repo = '%s/%s' % (payload['repository']['owner']['name'], payload['repository']['name']) announces = self._load() if repo not in announces: log.info('Commit for repo %s not announced anywhere' % repo) return for channel in announces[repo]: for irc in world.ircs: if channel in irc.state.channels: break commits = payload['commits'] if channel not in irc.state.channels: log.info('Cannot announce commit for repo %s on %s' % (repo, channel)) elif len(commits) == 0: log.warning('GitHub callback called without any commit.') else: hidden = None last_commit = commits[-1] if last_commit['message'].startswith('Merge ') and \ len(commits) > 5: hidden = len(commits) + 1 payload['commits'] = [last_commit] for commit in payload['commits']: msg = self._createPrivmsg(channel, payload, commit, hidden) irc.queueMsg(msg)
def toGBP(raw): urlPattern = 'http://finance.yahoo.com/d/quotes.csv?e=.csv&f=sl1d1t1&s=%sGBP=X' currency, value = raw.split(' ') log.info("Getting currency for %s" % currency) if not exchangeRateCache.has_key(currency): exchangeRateCache[currency] = float(urllib2.urlopen(urlPattern % currency).read().split(',')[1].replace(',', '')) return float(value.replace(',', '')) * exchangeRateCache[currency]
def etym(self, irc, msg, args, etym): """queries etymonline.com for word etymology""" try: req = requests.get( "https://www.etymonline.com/word/{}".format(etym)) soup = bs4.BeautifulSoup(req.text, 'html.parser') word_soup = soup.find('div', {'class': 'word--C9UPa'}) if not word_soup: irc.reply("'{}' not found".format(etym)) return irc_reply = "" for word in word_soup: irc_reply += "{}: {} ".format(word.div.h1.text, word.div.section.text) log.info(irc_reply) irc.reply(irc_reply) except Exception as e: log.exception() irc.reply("Error! Send the log to Druid@Freenode")
def doPost(self, handler, path, form): if not handler.address_string().endswith('.rs.github.com') and \ not handler.address_string().endswith('.cloud-ips.com') and \ not handler.address_string() == 'localhost' and \ not handler.address_string().startswith('127.0.0.') and \ not handler.address_string().startswith('192.30.252.') and \ not handler.address_string().startswith('204.232.175.'): log.warning("""'%s' tried to act as a web hook for Github, but is not GitHub.""" % handler.address_string()) self.send_response(403) self.send_header('Content-type', 'text/plain') self.end_headers() self.wfile.write(b('Error: you are not a GitHub server.')) else: headers = dict(self.headers) try: self.send_response(200) self.send_header('Content-type', 'text/plain') self.end_headers() self.wfile.write(b('Thanks.')) except socket.error: pass if 'X-GitHub-Event' in headers: event = headers['X-GitHub-Event'] else: # WTF? event = headers['x-github-event'] if event == 'ping': log.info('Got ping event from GitHub.') self.send_response(200) self.send_header('Content-type', 'text/plain') self.end_headers() self.wfile.write(b('Thanks.')) return self.plugin.announce.onPayload(headers, json.loads(form['payload'].value))
def _topic_callback(self): self.topic_lock.acquire() sections = { lambda: len(TestingRCBugs().get_bugs()): 'RC bug count:', NewQueue().get_size: 'NEW queue:', RmQueue().get_size: 'RM queue:', } try: values = {} for callback, prefix in sections.iteritems(): values[callback] = callback() for channel in self.irc.state.channels: new_topic = topic = self.irc.state.getTopic(channel) for callback, prefix in sections.iteritems(): if values[callback]: new_topic = rewrite_topic(new_topic, prefix, values[callback]) if topic != new_topic: log.info("Queueing change of topic in #%s to '%s'" % (channel, new_topic)) self.queued_topics[channel] = new_topic event_name = '%s_topic' % channel try: schedule.removeEvent(event_name) except KeyError: pass schedule.addEvent(lambda channel=channel: self._update_topic(channel), time.time() + 60, event_name) finally: self.topic_lock.release()
def start(self): log.info("Starting mail processing thread.") self.quit = False self.thread = threading.Thread(target=self.process_mails, name='mail processing') self.thread.start()
def _poll(self): try: tochannel = self.registryValue('postChannel') if tochannel: irc = self.irc server = self.xmlrpc lastseen = self.lastseen if tochannel in irc.state.channels: for rcgthread in self.registryValue('watchedThreads').split(): response = server.get_thread(rcgthread, 0, 0) lastpost = response.get('total_post_num') if rcgthread in lastseen: if lastpost > lastseen[rcgthread]: log.info("New posts in %s" % (rcgthread)) response = server.get_thread(rcgthread, lastseen[rcgthread], lastpost) for post in response.get('posts'): log.info("Posting about %s:%s on %s" % (rcgthread, post.get('post_id'), tochannel)) message = "New post in '%s' by %s: %sp=%s" % (response.get('topic_title').data, post.get('post_author_name').data, POSTURL, post.get('post_id')) irc.queueMsg(ircmsgs.privmsg(tochannel, message)) lastseen[rcgthread] = lastpost else: lastseen[rcgthread] = lastpost except: pass self._schedule_next_event()
def _topic_callback(self): sections = { self.testing_rc_bugs.get_number_bugs: 'RC bug count', self.stable_rc_bugs.get_number_bugs: 'Stable RC bug count', self.new_queue.get_size: 'NEW queue', RmQueue().get_size: 'RM queue', } with self.topic_lock: values = {} for callback, prefix in sections.iteritems(): values[callback] = callback() for channel in self.irc.state.channels: new_topic = topic = self.irc.state.getTopic(channel) for callback, prefix in sections.iteritems(): if values[callback]: new_topic = rewrite_topic(new_topic, prefix, values[callback]) if topic != new_topic: log.info("Queueing change of topic in #%s to '%s'" % (channel, new_topic)) self.queued_topics[channel] = new_topic event_name = '%s_topic' % channel try: schedule.removeEvent(event_name) except KeyError: pass schedule.addEvent(lambda channel=channel: self._update_topic(channel), time.time() + 60, event_name)
def racers(self, irc, msg, args): """takes no arguments Lists all users currently in sessions (not just races) """ logger.info("Command sent by " + str(msg.nick)) self.iRacingData.grabData() onlineDrivers = self.iRacingData.onlineDrivers() onlineDriverNames = [] for driver in onlineDrivers: name = driver.nameForPrinting() if driver.currentSession is not None: name += ' (%s)' % (driver.currentSession.sessionDescription) onlineDriverNames.append(name) if len(onlineDriverNames) == 0: response = self.NO_ONE_ONLINE_RESPONSE else: response = 'Online racers: %s' % utils.str.commaAndify(onlineDriverNames) irc.reply(response)
def grabData(self, onlineOnly=True): """Refreshes data from iRacing JSON API.""" # Have we loaded the car/track/season data recently? timeSinceSeasonDataFetch = sys.maxint if self.lastSeasonDataFetchTime is None else time.time() - self.lastSeasonDataFetchTime shouldFetchSeasonData = timeSinceSeasonDataFetch >= self.SECONDS_BETWEEN_CACHING_SEASON_DATA # TODO: Check if a new season has started more recently than the past 12 hours. if shouldFetchSeasonData: logTime = 'forever' if self.lastSeasonDataFetchTime is None else '%s seconds' % timeSinceSeasonDataFetch logger.info('Fetching iRacing main page season data since it has been %s since we\'ve done so.', logTime) self.grabSeasonData() json = self.iRacingConnection.fetchDriverStatusJSON(onlineOnly=onlineOnly) if json is None: # This is already logged in fetchDriverStatusJSON return # Populate drivers and sessions dictionaries for racerJSON in json['fsRacers']: driverID = Driver.driverIDWithJson(racerJSON) # Check if we already have data for this driver to update if driverID in self.driversByID: driver = self.driversByID[driverID] """@type driver: Driver""" driver.updateWithJSON(racerJSON) else: # This is the first time we've seen this driver driver = Driver(racerJSON, self.db, self) self.driversByID[driver.id] = driver
def grabSeasonData(self): """Refreshes season/car/track data from the iRacing main page Javascript""" rawMainPageHTML = self.iRacingConnection.fetchMainPageRawHTML() if rawMainPageHTML is None: logger.warning('Unable to fetch iRacing homepage data.') return self.lastSeasonDataFetchTime = time.time() try: trackJSON = re.search("var TrackListing\\s*=\\s*extractJSON\\('(.*)'\\);", rawMainPageHTML).group(1) carJSON = re.search("var CarListing\\s*=\\s*extractJSON\\('(.*)'\\);", rawMainPageHTML).group(1) carClassJSON = re.search("var CarClassListing\\s*=\\s*extractJSON\\('(.*)'\\);", rawMainPageHTML).group(1) seasonJSON = re.search("var SeasonListing\\s*=\\s*extractJSON\\('(.*)'\\);", rawMainPageHTML).group(1) tracks = json.loads(trackJSON) cars = json.loads(carJSON) carClasses = json.loads(carClassJSON) seasons = json.loads(seasonJSON) for track in tracks: self.tracksByID[track['id']] = track for car in cars: self.carsByID[car['id']] = car for carClass in carClasses: self.carClassesByID[carClass['id']] = carClass for season in seasons: self.seasonsByID[season['seriesid']] = season logger.info('Loaded data for %i tracks, %i cars, %i car classes, and %i seasons.', len(self.tracksByID), len(self.carsByID), len(self.carClassesByID), len(self.seasonsByID)) except AttributeError: logger.info('Unable to match track/car/season (one or more) listing regex in iRacing main page data. It is possible that iRacing changed the JavaScript structure of their main page! Oh no!')
def create_tables(cls) -> str: if isfile(db_path) and cls.table_exists(): return "Users table already created." with db: cls.create_table() log.info("Created the users table") return "Created users table."
def log_message(self, format, *args): log.info( "HTTP: %s - - [%s] %s" % ( self.client_address[0], self.log_date_time_string(), format % args ) )
def _update_topic(self, channel): with self.topic_lock: try: new_topic = self.queued_topics[channel] log.info("Changing topic in #%s to '%s'" % (channel, new_topic)) self.irc.queueMsg(supybot.ircmsgs.topic(channel, new_topic)) except KeyError: pass
def doJoin(self, irc, msg): channel = msg.args[0] log.info(channel + " has servers " + ', '.join(self.registryValue('servers', channel))) for server in self.registryValue('servers', channel): if not self.servers.has_key(server): self.servers[server] = Server(self, irc, server) srv = self.servers[server] srv.addChannel(channel)
def stopServer(): """Stops the HTTP server. Should be run only from this module or from when the bot is dying (ie. from supybot.world)""" global http_servers for server in http_servers: log.info('Stopping HTTP server: %s' % str(server)) server.shutdown() server = None
def makeIrcsDie(): """Kills Ircs.""" log.info("Killing Irc objects.") for irc in ircs[:]: if not irc.zombie: irc.die() else: log.debug("Not killing %s, it's already a zombie.", irc)
def startServer(): """Starts the HTTP server. Shouldn't be called from other modules. The callback should be an instance of a child of SupyHTTPServerCallback.""" global httpServer log.info('Starting HTTP server.') address = (configGroup.host(), configGroup.port()) httpServer = SupyHTTPServer(address, SupyHTTPRequestHandler) Thread(target=httpServer.serve_forever, name='HTTP Server').start()
def loadKeyring(): global keyring path = os.path.abspath(conf.supybot.directories.data.dirize('GPGkeyring')) if not os.path.isdir(path): log.info('Creating directory %s' % path) os.mkdir(path, 0700) assert os.path.isdir(path) keyring = gnupg.GPG(gnupghome=path)
def makeIrcsDie(): """Kills Ircs.""" log.info('Killing Irc objects.') for irc in ircs[:]: if not irc.zombie: irc.die() else: log.debug('Not killing %s, it\'s already a zombie.', irc)
def stopServer(): """Stops the HTTP server. Should be run only from this module or from when the bot is dying (ie. from supybot.world)""" global httpServer if httpServer is not None: log.info('Stopping HTTP server.') httpServer.shutdown() httpServer = None
def onPayload(self, headers, payload): if 'reply_env' not in ircmsgs.IrcMsg.__slots__: log.error("Got event payload from GitHub, but your version " "of Supybot is not compatible with reply " "environments, so, the GitHub plugin can't " "announce it.") if 'full_name' in payload['repository']: repo = payload['repository']['full_name'] elif 'name' in payload['repository']['owner']: repo = '%s/%s' % (payload['repository']['owner']['name'], payload['repository']['name']) else: repo = '%s/%s' % (payload['repository']['owner']['login'], payload['repository']['name']) event = headers['X-GitHub-Event'] announces = self._load() repoAnnounces = [] for (dbRepo, network, channel) in announces: if dbRepo == repo: repoAnnounces.append((network, channel)) if len(repoAnnounces) == 0: log.info('Commit for repo %s not announced anywhere' % repo) return for (network, channel) in repoAnnounces: # Compatability with DBs without a network if network == '': for irc in world.ircs: if channel in irc.state.channels: break else: irc = world.getIrc(network) if not irc: log.warning('Received GitHub payload with announcing ' 'enabled in %s on unloaded network %s.', channel, network) return if channel not in irc.state.channels: log.info(('Cannot announce event for repo ' '%s in %s on %s because I\'m not in %s.') % (repo, channel, irc.network, channel)) if event == 'push': commits = payload['commits'] if len(commits) == 0: log.warning('GitHub push hook called without any commit.') else: hidden = None last_commit = commits[-1] if last_commit['message'].startswith('Merge ') and \ len(commits) > 5: hidden = len(commits) + 1 commits = [last_commit] payload2 = dict(payload) for commit in commits: payload2['__commit'] = commit self._createPrivmsg(irc, channel, payload2, 'push', hidden) else: self._createPrivmsg(irc, channel, payload, event)
def doPrivmsg(self, irc, msg): channel = msg.args[0] content = msg.args[1] if not self.registryValue('enable', channel): return encoding = chardet.detect(content)['encoding'] if encoding not in ('utf-8', 'ascii'): log.info('Warning %s (using %s)' % (msg.prefix, encoding)) self._warn(irc, channel, msg.prefix.split('!')[0])
def do376(self, irc, msg): """Watch for the MOTD and login if we can""" if irc.state.supported.get('NETWORK', '') == 'UnderNet': if self.registryValue('auth.username') and self.registryValue('auth.password'): log.info("Attempting login to XService") else: log.warning("username and password not set, this plugin will not work") return self._login(irc)
def fakehostmask(self, irc, msg, args, hostmask, command): """<hostmask> <command> Runs <command> as if you were wearing the <hostmask>. Of course, usage of the command is restricted to the owner.""" log.info('fakehostmask used to run "%s" as %s' % (command, hostmask)) msg.prefix = hostmask tokens = callbacks.tokenize(command) self.Proxy(irc.irc, msg, tokens)
def upkeep(): """Does upkeep (like flushing, garbage collection, etc.)""" sys.exc_clear() # Just in case, let's clear the exception info. if os.name == 'nt': try: import msvcrt msvcrt.heapmin() except ImportError: pass except IOError: # Win98 sux0rs! pass if conf.daemonized: # If we're daemonized, sys.stdout has been replaced with a StringIO # object, so let's see if anything's been printed, and if so, let's # log.warning it (things shouldn't be printed, and we're more likely # to get bug reports if we make it a warning). assert not type(sys.stdout) == file, 'Not a StringIO object!' if not hasattr(sys.stdout, 'getvalue'): # Stupid twisted sometimes replaces our stdout with theirs, because # "The Twisted Way Is The Right Way" (ha!). So we're stuck simply # returning. log.warning('Expected cStringIO as stdout, got %r.', sys.stdout) return s = sys.stdout.getvalue() if s: log.warning('Printed to stdout after daemonization: %s', s) sys.stdout.reset() # Seeks to 0. sys.stdout.truncate() # Truncates to current offset. assert not type(sys.stderr) == file, 'Not a StringIO object!' s = sys.stderr.getvalue() if s: log.error('Printed to stderr after daemonization: %s', s) sys.stderr.reset() # Seeks to 0. sys.stderr.truncate() # Truncates to current offset. doFlush = conf.supybot.flush() and not starting if doFlush: flush() # This is so registry._cache gets filled. # This seems dumb, so we'll try not doing it anymore. #if registryFilename is not None: # registry.open(registryFilename) if not dying: log.debug('Regexp cache size: %s', len(sre._cache)) log.debug('Pattern cache size: %s', len(ircutils._patternCache)) log.debug('HostmaskPatternEqual cache size: %s', len(ircutils._hostmaskPatternEqualCache)) #timestamp = log.timestamp() if doFlush: log.info('Flushers flushed and garbage collected.') else: log.info('Garbage collected.') collected = gc.collect() if gc.garbage: log.warning( 'Noncollectable garbage (file this as a bug on SF.net): %s', gc.garbage) return collected
def upkeep(): """Does upkeep (like flushing, garbage collection, etc.)""" sys.exc_clear() # Just in case, let's clear the exception info. if os.name == 'nt': try: import msvcrt msvcrt.heapmin() except ImportError: pass except IOError: # Win98 sux0rs! pass if conf.daemonized: # If we're daemonized, sys.stdout has been replaced with a StringIO # object, so let's see if anything's been printed, and if so, let's # log.warning it (things shouldn't be printed, and we're more likely # to get bug reports if we make it a warning). assert not type(sys.stdout) == file, 'Not a StringIO object!' if not hasattr(sys.stdout, 'getvalue'): # Stupid twisted sometimes replaces our stdout with theirs, because # "The Twisted Way Is The Right Way" (ha!). So we're stuck simply # returning. log.warning('Expected cStringIO as stdout, got %r.', sys.stdout) return s = sys.stdout.getvalue() if s: log.warning('Printed to stdout after daemonization: %s', s) sys.stdout.reset() # Seeks to 0. sys.stdout.truncate() # Truncates to current offset. assert not type(sys.stderr) == file, 'Not a StringIO object!' s = sys.stderr.getvalue() if s: log.error('Printed to stderr after daemonization: %s', s) sys.stderr.reset() # Seeks to 0. sys.stderr.truncate() # Truncates to current offset. doFlush = conf.supybot.flush() and not starting if doFlush: flush() # This is so registry._cache gets filled. # This seems dumb, so we'll try not doing it anymore. #if registryFilename is not None: # registry.open(registryFilename) if not dying: log.debug('Regexp cache size: %s', len(sre._cache)) log.debug('Pattern cache size: %s', len(ircutils._patternCache)) log.debug('HostmaskPatternEqual cache size: %s', len(ircutils._hostmaskPatternEqualCache)) #timestamp = log.timestamp() if doFlush: log.info('Flushers flushed and garbage collected.') else: log.info('Garbage collected.') collected = gc.collect() if gc.garbage: log.warning('Noncollectable garbage (file this as a bug on SF.net): %s', gc.garbage) return collected
def _add_players_from_channel(self, **kwargs): nicks_in_channel = [] ignore_nicks = self.registryValue("ignoreNicks") new_player_nick = None if "new_player_nick" in kwargs: new_player_nick = kwargs["new_player_nick"] if GAME_CHANNEL in self.irc.state.channels: nicks_in_channel = self.irc.state.channels[GAME_CHANNEL].users for nick in nicks_in_channel: if not nick: continue if nick in ignore_nicks: continue # Skip bot nick if nick == self.irc.nick: continue unit_collection = self.SpiffyWorld.unit_collection try: hostmask = self.irc.state.nickToHostmask(nick) except KeyError: hostmask = None user_id = None if hostmask is None: continue try: user_id = ircdb.users.getUserId(hostmask) except KeyError: log.info("SpiffyRPG: %s is not registered." % nick) """ Registered users only """ if user_id is None: continue if user_id is not None: player = unit_collection.get_player_by_user_id(user_id) if player is not None: player.nick = nick dungeon = self.SpiffyWorld.get_dungeon_by_channel(GAME_CHANNEL) dungeon.add_unit(player) if new_player_nick is not None: if player.nick == new_player_nick: return player else: log.error("No player with user_id %s" % user_id)
def responseRequiresAuthentication(self, response): if response.status_code != requests.codes.ok: return True if "<HTML>" in response.content.upper(): logger.info("Request looks like HTML. Needs login?") return True return False
def _start_polling(self): log.info('Start polling.') schedule.addPeriodicEvent(self._minutely_diff_poll, 60, now=True, name='minutely_poll') schedule.addPeriodicEvent(self._notes_rss_poll, 60, now=True, name='notes_rss_poll')
def do376(self, irc, msg): """Watch for the MOTD and login if we can""" if irc.state.supported.get("NETWORK", "") == "UnderNet": if self.registryValue("auth.username") and self.registryValue( "auth.password"): log.info("Attempting login to XService") else: log.warning( "username and password not set, this plugin will not work") return self._login(irc)
def Query(self, queryId): if not self.valid: log.error("Querying on an invalid server instance!") else: self.conn = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.conn.sendto(struct.pack("<IB",0x80, queryId), (self.addr, self.port)) recv, addr = self.conn.recvfrom(500000) if recv[0:5] == struct.pack("<IB",0x80, queryId): return recv[5:] else: log.info("Invalid response header") return ""
def migrate(self, irc, msg, args, vmname, hostname): """<vm> [<host>] Migrates the vm to another esx host Returns the status of migration """ username = self.user password = self.password vcenter = self.vcenter try: si = SmartConnect(host=vcenter, user=username, pwd=password, port=443) except: err_text = 'Error connecting to {0}'.format(vcenter) log.info(err_text) irc.reply(err_text) return if hostname: try: host = vmutils.get_host_by_name(si, hostname) hostname = host.name except: irc.reply('{0} not found'.format(hostname)) return else: # hostname was not passed all_hosts = vmutils.get_hosts(si) host = vmutils.get_host_by_name(si, random.choice(all_hosts.values())) hostname = host.name # Finding source VM try: vm = vmutils.get_vm_by_name(si, vmname) except: irc.reply('{0} not found.'.format(vmname)) return # relocate spec, to migrate to another host # this can do other things, like storage and resource pool # migrations relocate_spec = vim.vm.RelocateSpec(host=host) # does the actual migration to host vm.Relocate(relocate_spec) irc.reply('Migrating {0} to {1}'.format(vmname, hostname)) Disconnect(si)
def sudo(self, irc, msg, args, command): """<commande> [<arg1> [<arg2> ...]] Runs the command fellowing the Sudo rules.""" name, rule = self.db.getRuleMatching(command) if name is None: log.warning('Sudo not granted to "%s"' % msg.prefix) irc.error(_('Sudo not granted.')) else: assert rule is not None log.info('Sudo granted to "%s" with rule %s' % (msg.prefix, name)) msg.prefix = rule.hostmask tokens = callbacks.tokenize(command) self.Proxy(irc.irc, msg, tokens)
def poll(self): try: log.info("Polling for " + str(self) + " on channels " + str(self.channels)) response, players, scores, joined, parted = self.Poll() log.info(str(response)) for channel in self.channels: log.info("Checking for " + channel) if len(self.players) == 0 and len(players) > 0 and len(str(self.parent.registryValue('onFirstJoinSay', channel)).strip()) > 0: if self.utdelay == 0: self.irc.queueMsg(ircmsgs.privmsg(channel, self.parent.registryValue('onFirstJoinSay'))) msgJoins = self.printJoins(joined, channel) msgParts = self.printParts(parted, channel) msg = msgJoins if len(msgParts) > 0: if len(msg) > 0: msg += ' and ' msg += msgParts log.info("Send to " + channel + " with msg: " + msg) if len(msg) > 0: self.irc.queueMsg(ircmsgs.privmsg(channel, msg)) self.players = players if len(players) > 0: self.utdelay = 6*30 elif self.utdelay > 0: self.utdelay = self.utdelay - 1 except: out = StringIO.StringIO() traceback.print_exc(file=out) log.error(out.getvalue())
def startServer(): """Starts the HTTP server. Shouldn't be called from other modules. The callback should be an instance of a child of SupyHTTPServerCallback.""" global http_servers addresses4 = [(4, (x, configGroup.port())) for x in configGroup.hosts4().split(' ') if x != ''] addresses6 = [(6, (x, configGroup.port())) for x in configGroup.hosts6().split(' ') if x != ''] http_servers = [] for protocol, address in (addresses4 + addresses6): server = SupyHTTPServer(address, protocol, SupyHTTPRequestHandler) Thread(target=server.serve_forever, name='HTTP Server').start() http_servers.append(server) log.info('Starting HTTP server: %s' % str(server))
def doPost(self, handler, path, form): headers = dict(self.headers) if sys.version_info[0] >= 3 and isinstance(form, bytes): # JSON mode valid_signatures = [ 'sha1=' + hmac.new(s.encode(), form, hashlib.sha1).hexdigest() for s in self.plugin.registryValue('announces.secret') ] elif sys.version_info[0] == 2 and isinstance(form, str): # JSON mode valid_signatures = [ 'sha1=' + hmac.new(s.encode(), form, hashlib.sha1).hexdigest() for s in self.plugin.registryValue('announces.secret') ] else: valid_signatures = [] if valid_signatures and \ headers.get('X-Hub-Signature', None) not in valid_signatures: log.warning('%s', valid_signatures) log.warning('%s', headers.get('X-Hub-Signature', None)) log.warning("""'%s' tried to act as a web hook for Github, but is not GitHub (no secret or invalid secret).""" % handler.address_string()) self.send_response(403) self.send_header('Content-type', 'text/plain') self.end_headers() self.wfile.write(b('Error: you are not a GitHub server.')) else: try: self.send_response(200) self.send_header('Content-type', 'text/plain') self.end_headers() self.wfile.write(b('Thanks.')) except socket.error: pass if 'X-GitHub-Event' in headers: event = headers['X-GitHub-Event'] else: # WTF? event = headers['x-github-event'] if event == 'ping': log.info('Got ping event from GitHub.') self.send_response(200) self.send_header('Content-type', 'text/plain') self.end_headers() self.wfile.write(b('Thanks.')) return payload = json.loads(form.decode('utf8')) self.plugin.announce.onPayload(headers, payload)
def login(self, irc, msg, args): """takes no arguments Logins to Undernet's X Service""" if irc.state.supported.get("NETWORK", "") == "UnderNet": if self.registryValue("auth.username") and self.registryValue( "auth.password"): log.info("Attempting login to XService") else: log.warning( "username and password not set, this plugin will not work") return self._login(irc) else: log.error("We're not on UnderNet, we can't use this.") irc.error("We're not on UnderNet, this is useless.")
def _loadFromConfig(self, name=None): broker = self.registryValue('mqttbroker') network = self.registryValue('network') channel = self.registryValue('channel') for thread in self.listenerThreads: thread.mqtthandler.active = False time.sleep(2) self.listenerThreads = [] try: log.info('Starting mqtt listener thread: %s' % broker) thread = self.ListeningThread(network, channel, broker) thread.start() self.listenerThreads.append(thread) except TypeError: irc.error('Cannot load mqtt: %s' % broker)
def namecheap(self, method, args={}): """Make a request to the namecheap API.""" args['Command'] = method args['ApiUser'] = self.registryValue('ApiUser') args['ApiKey'] = self.registryValue('ApiKey') args['UserName'] = self.registryValue('ApiUser') args['ClientIP'] = "127.0.0.1" # When in production, use https://api.namecheap.com/xml.response sandbox = ".sandbox" if self.registryValue('sandbox') else "" api_base = "https://api%s.namecheap.com/xml.response" % sandbox response = requests.get(api_base, params=args) log.info(response.url) tree = ElementTree.fromstring(response.content) return tree