class Pdod(Persist): """ pickled dicts of dicts """ def __init__(self, filename): Persist.__init__(self, filename) if not self.data: self.data = LazyDict() def __getitem__(self, name): """ return item with name """ if self.data.has_key(name): return self.data[name] def save(self): Persist.save(self) def __delitem__(self, name): """ delete name item """ if self.data.has_key(name): return self.data.__delitem__(name) def __setitem__(self, name, item): """ set name item """ self.data[name] = item def __contains__(self, name): return self.data.__contains__(name) def setdefault(self, name, default): """ set default of name """ return self.data.setdefault(name, default) def has_key(self, name): """ has name key """ return self.data.has_key(name) def has_key2(self, name1, najsb): """ has [name1][najsb] key """ if self.data.has_key(name1): return self.data[name1].has_key(najsb) def get(self, name1, najsb): """ get data[name1][najsb] """ try: result = self.data[name1][najsb] return result except KeyError: pass def set(self, name1, najsb, item): """ set name, najsb item """ if not self.data.has_key(name1): self.data[name1] = {} self.data[name1][najsb] = item
def savecallbacktable(modname=None): """ save command -> plugin list to db backend. """ if modname: logging.warn("boot - module name is %s" % modname) global callbacktable assert callbacktable if not callbacktable.data: callbacktable.data = {} if modname: target = LazyDict(callbacktable.data) else: target = LazyDict() from jsb.lib.callbacks import first_callbacks, callbacks, last_callbacks, remote_callbacks for cb in [first_callbacks, callbacks, last_callbacks, remote_callbacks]: for type, cbs in cb.cbs.iteritems(): for c in cbs: if modname and c.modname != modname: continue if not target.has_key(type): target[type] = [] if not c.modname in target[type]: target[type].append(c.modname) logging.warn("saving callback table") assert callbacktable assert target callbacktable.data = target callbacktable.save()
def savecmndtable(modname=None, saveperms=True): """ save command -> plugin list to db backend. """ global cmndtable if not cmndtable.data: cmndtable.data = {} if modname: target = LazyDict(cmndtable.data) else: target = LazyDict() global shorttable if not shorttable.data: shorttable.data = {} if modname: short = LazyDict(shorttable.data) else: short = LazyDict() global cmndperms from jsb.lib.commands import cmnds assert cmnds for cmndname, c in cmnds.iteritems(): if modname and c.modname != modname or cmndname == "subs": continue if cmndname and c: target[cmndname] = c.modname cmndperms[cmndname] = c.perms try: s = cmndname.split("-")[1] if not target.has_key(s): if not short.has_key(s): short[s] = [ cmndname, ] if cmndname not in short[s]: short[s].append(cmndname) except (ValueError, IndexError): pass logging.warn("saving command table") assert cmndtable assert target cmndtable.data = target cmndtable.save() logging.warn("saving short table") assert shorttable assert short shorttable.data = short shorttable.save() logging.warn("saving RE table") for command in cmnds.regex: retable.data[command.regex] = command.modname assert retable retable.save() if saveperms: logging.warn("saving command perms") cmndperms.save()
def savecmndtable(modname=None, saveperms=True): """ save command -> plugin list to db backend. """ global cmndtable if not cmndtable.data: cmndtable.data = {} if modname: target = LazyDict(cmndtable.data) else: target = LazyDict() global shorttable if not shorttable.data: shorttable.data = {} if modname: short = LazyDict(shorttable.data) else: short = LazyDict() global cmndperms from jsb.lib.commands import cmnds assert cmnds for cmndname, c in cmnds.iteritems(): if modname and c.modname != modname or cmndname == "subs": continue if cmndname and c: target[cmndname] = c.modname cmndperms[cmndname] = c.perms try: s = cmndname.split("-")[1] if not target.has_key(s): if not short.has_key(s): short[s] = [cmndname, ] if cmndname not in short[s]: short[s].append(cmndname) except (ValueError, IndexError): pass logging.warn("saving command table") assert cmndtable assert target cmndtable.data = target cmndtable.save() logging.warn("saving short table") assert shorttable assert short shorttable.data = short shorttable.save() logging.warn("saving RE table") for command in cmnds.regex: retable.data[command.regex] = command.modname assert retable retable.save() if saveperms: logging.warn("saving command perms") cmndperms.save()
class FloodControl(object): def __init__(self): self.stats = StatDict() self.times = LazyDict() self.wait = LazyDict() self.warned = LazyDict() def reset(self, userhost): try: del self.times[userhost] except KeyError: pass try: del self.stats[userhost] except KeyError: pass try: del self.wait[userhost] except KeyError: pass try: del self.warned[userhost] except KeyError: pass def check(self, userhost, timetomonitor=60, threshold=10, wait=120, floodrate=1): u = userhost t = time.time() w = wait if self.times.has_key(u): if t - self.times[u] > w: self.reset(u) ; return False if (t - self.times[u] < timetomonitor): self.stats.upitem(u) if (self.stats.get(u) > threshold) or (t - self.times[u] < floodrate): self.wait[userhost] = wait ; return True else: self.times[u] = t ; return False if self.stats.get(u) <= threshold: return False return True def checkevent(self, event, dobind=True): if not event.iscommand: return False if getmainconfig().floodallow: return False if dobind: event.bind() if not event.user: got = False else: got = True t = got and event.user.data.floodtime or 60 if t < 60: t = 60 threshold = got and event.user.data.floodthreshold or 20 if threshold < 20: threshold = 20 wait = got and event.user.data.floodwait or 120 if wait < 120: wait = 120 floodrate = got and event.user.data.floodrate or 0.1 if floodrate < 0.1: floodrate = 0.1 if not self.check(event.userhost, t, threshold, wait, floodrate): return False if event.user and "OPER" in event.user.data.perms: return False logging.warn("floodcontrol block on %s" % event.userhost) if event.userhost not in self.warned: logging.warn("floodcontrol block on %s" % event.userhost) event.reply("floodcontrol enabled (%s seconds)" % wait) self.warned[event.userhost] = time.time() return True
def makeoptions(ievent, options={}): options = LazyDict(options) try: optargs = "" optlist = [] if not options.has_key('--filter'): options['--filter'] = "" if not options.has_key('--to'): options['--to'] = None if not options.has_key('--chan'): options['--chan'] = ievent.channel if not options.has_key('--how'): options['--how'] = "msg" if not options.has_key('--speed'): options['--speed'] = str(ievent.speed) else: options['--speed'] = str(options['--speed']) for i, j in options.iteritems(): if '--' in i: optlist.append("%s=" % i[2:]) if j: optlist.append(j) continue if '-' in i: if j: optargs += ":%s" % i[1:] else: optargs += i[1:] args = ievent.txt.split() try: (opts, rest) = getopt.getopt(args[1:], optargs, optlist) except AttributeError, ex: print "option not allowed: %s" % str(ex), ievent.txt, options return 0 except getopt.GetoptError, ex: return 0
class FloodControl(object): def __init__(self): self.stats = StatDict() self.times = LazyDict() self.wait = LazyDict() self.warned = LazyDict() def reset(self, userhost): try: del self.times[userhost] except KeyError: pass try: del self.stats[userhost] except KeyError: pass try: del self.wait[userhost] except KeyError: pass try: del self.warned[userhost] except KeyError: pass def check(self, userhost, timetomonitor=60, threshold=10, wait=120, floodrate=1): u = userhost t = time.time() w = wait if self.times.has_key(u): if t - self.times[u] > w: self.reset(u) return False if (t - self.times[u] < timetomonitor): self.stats.upitem(u) if (self.stats.get(u) > threshold) or (t - self.times[u] < floodrate): self.wait[userhost] = wait return True else: self.times[u] = t return False if self.stats.get(u) <= threshold: return False return True def checkevent(self, event, dobind=True): if not event.iscommand: return False if getmainconfig().floodallow: return False if dobind: event.bind() if not event.user: got = False else: got = True t = got and event.user.data.floodtime or 60 if t < 60: t = 60 threshold = got and event.user.data.floodthreshold or 20 if threshold < 20: threshold = 20 wait = got and event.user.data.floodwait or 120 if wait < 120: wait = 120 floodrate = got and event.user.data.floodrate or 0.1 if floodrate < 0.1: floodrate = 0.1 if not self.check(event.userhost, t, threshold, wait, floodrate): return False if event.user and "OPER" in event.user.data.perms: return False logging.warn("floodcontrol block on %s" % event.userhost) if event.userhost not in self.warned: logging.warn("floodcontrol block on %s" % event.userhost) event.reply("floodcontrol enabled (%s seconds)" % wait) self.warned[event.userhost] = time.time() return True
class Commands(LazyDict): """ the commands object holds all commands of the bot. """ def add(self, cmnd, func, perms, threaded=False, wait=False, orig=None, how=None, *args, **kwargs): """ add a command. """ modname = calledfrom(sys._getframe()) target = Command(modname, cmnd, func, perms, threaded, wait, orig, how) self[cmnd] = target try: c = cmnd.split('-')[1] if not self.subs: self.subs = LazyDict() if self.subs.has_key(c): if not self.subs[c]: self.subs[c] = [] if target not in self.subs[c]: self.subs[c].append(target) else: self.subs[c] = [target, ] except IndexError: pass try: p = cmnd.split('-')[0] if not self.pre: self.pre = LazyDict() if self.pre.has_key(p): if not self.pre[p]: self.pre[p] = [] if target not in self.pre[p]: self.pre[p].append(target) else: self.pre[p] = [target, ] except IndexError: pass return self def woulddispatch(self, bot, event, cmnd=""): """ dispatch an event if cmnd exists and user is allowed to exec this command. """ event.bind(bot) cmnd = cmnd or event.usercmnd.lower() if not cmnd: return try: cmnd = event.chan.data.aliases[cmnd] except (KeyError, TypeError): try: cmnd = bot.aliases.data[cmnd] except (KeyError, TypeError): pass try: if cmnd: event.txt = cmnd + ' ' + ' '.join(event.txt.split()[1:]) event.usercmnd = cmnd.split()[0] event.prepare() except (TypeError, KeyError, AttributeError): pass logging.debug("commands - %s" % cmnd) bot.plugs.reloadcheck(bot, event) result = None cmnd = event.usercmnd try: result = self[cmnd] except KeyError: if self.subs and self.subs.has_key(cmnd): cmndlist = self.subs[cmnd] if len(cmndlist) == 1: result = cmndlist[0] else: event.reply("try one of: %s" % ", ".join([x.cmnd for x in cmndlist])) ; return else: if self.pre and self.pre.has_key(cmnd): cmndlist = self.pre[cmnd] if len(cmndlist) == 1: result = cmndlist[0] else: event.reply("try one of: %s" % ", ".join([x.cmnd for x in cmndlist])) ; return logging.debug("commands - woulddispatch result: %s" % result) return result def dispatch(self, bot, event, wait=0): """ dispatch an event if cmnd exists and user is allowed to exec this command. """ event.bind(bot) if event.groupchat: id = event.auth = event.userhost else: id = event.auth if not event.user: raise NoSuchUser(event.auth) c = self.woulddispatch(bot, event) if not c: raise NoSuchCommand() if bot.cmndperms and bot.cmndperms[c.cmnd]: perms = bot.cmndperms[c.cmnd] else: perms = c.perms if bot.allowall: return self.doit(bot, event, c, wait=wait) elif event.chan and event.chan.data.allowcommands and event.usercmnd in event.chan.data.allowcommands: if not 'OPER' in perms: return self.doit(bot, event, c, wait=wait) else: logging.warn("commands - %s is not in allowlist" % c) elif not bot.users or bot.users.allowed(id, perms, bot=bot): return self.doit(bot, event, c, wait=wait) elif bot.users.allowed(id, perms, bot=bot): return self.doit(bot, event, c, wait=wait) return event def doit(self, bot, event, target, wait=0): """ do the dispatching. """ if not target.enable: return if target.modname in event.chan.data.denyplug: logging.warn("commands - %s is denied in channel %s - %s" % (target.plugname, event.channel, event.userhost)) return id = event.auth or event.userhost event.iscommand = True event.how = target.how logging.warning('commands - dispatching %s for %s' % (event.usercmnd, id)) try: if bot.isgae: if not event.notask and (target.threaded or event.threaded) and not event.nothreads: logging.warn("commands - LAUNCHING AS TASK") from jsb.lib.gae.tasks import start_botevent event.txt = event.origtxt start_botevent(bot, event, event.speed) event.reply("task started for %s" % event.auth) else: target.func(bot, event) ; event.ready() ; return event else: if target.threaded and not event.nothreads: logging.warning("commands - launching thread for %s" % event.usercmnd) t = start_bot_command(target.func, (bot, event)) event.threads.append(t) else: event.dontclose = False; cmndrunner.put(target.modname, target.func, bot, event) except Exception, ex: logging.error('commands - %s - error executing %s' % (whichmodule(), str(target.func))) raise return event
class Commands(LazyDict): """ the commands object holds all commands of the bot. """ regex = [] def add(self, cmnd, func, perms, threaded=False, wait=False, orig=None, how=None, speed=None, regex=False, needcc=False, *args, **kwargs): """ add a command. """ modname = calledfrom(sys._getframe()) try: prev = self[cmnd] except KeyError: prev = None target = Command(modname, cmnd, func, perms, threaded, wait, orig, how, speed=speed, needcc=needcc) if regex: logging.info("regex command detected - %s" % cmnd) self.regex.append(target) target.regex = cmnd return self self[cmnd] = target try: p = cmnd.split('-')[0] if not self.pre: self.pre = LazyDict() if self.pre.has_key(p): if not self.pre[p]: self.pre[p] = [] if prev in self.pre[p]: self.pre[p].remove(prev) if target not in self.pre[p]: self.pre[p].append(target) else: self.pre[p] = [target, ] except IndexError: pass return self def checkre(self, bot, event): gotcc = event.gotcc() for r in self.regex: if not r.enable: continue if r.needcc and not event.gotcc(): logging.debug("RE needs cc but not found") ; continue s = re.search(r.cmnd, event.txt) if s: logging.info("regex matches %s" % r.cmnd) event.groups = list(s.groups()) return r def wouldmatchre(self, bot, event, cmnd=""): groups = self.checkre(bot, event) if groups: return groups def woulddispatch(self, bot, event): """ dispatch an event if cmnd exists and user is allowed to exec this command. """ event.bind(bot) aliased = False try: cmnd = event.stripcc().split()[0] if not cmnd: cmnd = event.execstr.split()[0] if not cmnd: cmnd = event.txt.split()[0] except Exception, ex: logging.warn("can't determine command from %s" % event.txt) ; return None try: a = event.chan.data.aliases[cmnd] if a: cmnd = a.split()[0] ; aliased = True except (KeyError, TypeError): try: a = getaliases()[cmnd] if a: cmnd = a.split()[0] ; aliased = True except (KeyError, TypeError): if not self.has_key(cmnd): try: short = getshorttable() if short.has_key(cmnd): cmndlist = short[cmnd] if len(cmndlist) == 1: cmnd = cmndlist[0] else: event.reply("choose one of: ", cmndlist) ; return except Exception, ex: handle_exception() logging.info("trying for %s" % cmnd) result = None try: result = self[cmnd] except KeyError: pass logging.debug("woulddispatch result: %s" % result) if result: event.bloh() ; event.makeargs() if aliased: event.usercmnd = cmnd return result def dispatch(self, bot, event, direct=False): """ dispatch an event if cmnd exists and user is allowed to exec this command. """ if event.nodispatch: logging.info("nodispatch is set on event") ; return if event.groupchat and bot.cfg.fulljids: id = event.auth elif event.groupchat: id = event.auth = event.userhost else: id = event.auth if not event.user: event.bind(bot) if not event.user: raise NoSuchUser(event.userhost) self.reloadcheck(bot, event) c = self.woulddispatch(bot, event) if not c: c = self.checkre(bot, event) if not c: raise NoSuchCommand(event.usercmnd) event.plugorigin = c.modname if c.modname in bot.plugs.loading and bot.plugs.loading[c.modname]: event.reply("%s is loading" % c.modname) ; return if bot.cmndperms and bot.cmndperms[c.cmnd]: perms = bot.cmndperms[c.cmnd] else: perms = c.perms if bot.allowall: return self.doit(bot, event, c, direct) elif not bot.users or bot.users.allowed(id, perms, bot=bot): return self.doit(bot, event, c, direct) elif bot.users.allowed(id, perms, bot=bot): return self.doit(bot, event, c, direct) return event def doit(self, bot, event, target, direct=False): """ do the dispatching. """ if not target.enable: return if target.modname in event.chan.data.denyplug: logging.warn("%s is denied in channel %s - %s" % (target.plugname, event.channel, event.userhost)) return id = event.auth or event.userhost event.iscommand = True event.how = event.how or target.how or "overwrite" aliascheck(event) display = "%s/%s/%s" % (target.plugname, bot.cfg.name, event.nick or event.channel) logging.warning('dispatching %s (%s)' % (event.usercmnd, display)) try: if direct or event.direct: target.func(bot, event) elif (target.threaded or event.threaded) and not event.nothreads: logging.warning("DIRECT COMMAND THREAD %s (%s)" % (event.usercmnd, display)) t = start_bot_command(target.func, (bot, event)) event.threaded = True event.thread = t else: event.dontclose = False cmndrunner.put(target.speed or event.speed, display, target.func, bot, event) except Exception, ex: logging.error('%s - error executing %s' % (whichmodule(), str(target.func))) raise return event
class Commands(LazyDict): """ the commands object holds all commands of the bot. """ regex = [] def add(self, cmnd, func, perms, threaded=False, wait=False, orig=None, how=None, speed=None, regex=False, needcc=False, *args, **kwargs): """ add a command. """ modname = calledfrom(sys._getframe()) try: prev = self[cmnd] except KeyError: prev = None target = Command(modname, cmnd, func, perms, threaded, wait, orig, how, speed=speed, needcc=needcc) if regex: logging.info("regex command detected - %s" % cmnd) self.regex.append(target) target.regex = cmnd return self self[cmnd] = target try: p = cmnd.split('-')[0] if not self.pre: self.pre = LazyDict() if self.pre.has_key(p): if not self.pre[p]: self.pre[p] = [] if prev in self.pre[p]: self.pre[p].remove(prev) if target not in self.pre[p]: self.pre[p].append(target) else: self.pre[p] = [ target, ] except IndexError: pass return self def checkre(self, bot, event): gotcc = event.gotcc() for r in self.regex: if not r.enable: continue if r.needcc and not event.gotcc(): logging.debug("RE needs cc but not found") continue s = re.search(r.cmnd, event.txt) if s: logging.info("regex matches %s" % r.cmnd) event.groups = list(s.groups()) return r def wouldmatchre(self, bot, event, cmnd=""): groups = self.checkre(bot, event) if groups: return groups def woulddispatch(self, bot, event): """ dispatch an event if cmnd exists and user is allowed to exec this command. """ event.bind(bot) aliased = False try: cmnd = event.stripcc().split()[0] if not cmnd: cmnd = event.execstr.split()[0] if not cmnd: cmnd = event.txt.split()[0] except Exception, ex: logging.warn("can't determine command from %s" % event.txt) return None try: a = event.chan.data.aliases[cmnd] if a: cmnd = a.split()[0] aliased = True except (KeyError, TypeError): try: a = getaliases()[cmnd] if a: cmnd = a.split()[0] aliased = True except (KeyError, TypeError): if not self.has_key(cmnd): try: short = getshorttable() if short.has_key(cmnd): cmndlist = short[cmnd] if len(cmndlist) == 1: cmnd = cmndlist[0] else: event.reply("choose one of: ", cmndlist) return except Exception, ex: handle_exception()
class HubbubWatcher(PlugPersist): """ this watcher helps with the handling of incoming POST. also maitains index of feed names. """ def __init__(self, filename, host): PlugPersist.__init__(self, filename) if not self.data: self.data = LazyDict() if not self.data.has_key('names'): self.data['names'] = [] if not self.data.has_key('urls'): self.data['urls'] = {} if not self.data.has_key('feeds'): self.data['feeds'] = {} if not self.data.has_key('host'): self.data['host'] = host self.feeds = {} def add(self, name, url, owner): """ add a feed to the database. """ if not name in self.data['names']: self.data['names'].append(name) self.data['urls'][url] = name self.save() item = HubbubItem(name, url, owner) if item.data.url != url: return False item.save() self.feeds[name] = item return True def byname(self, name): """ retrieve a feed by it's name. """ if name in self.feeds: return self.feeds[name] item = HubbubItem(name) if item.data.url: self.feeds[name] = item ; return item def byurl(self, url): """ retrieve a feed by it's url. """ try: name = self.data['urls'][url] return self.byname(name) except KeyError: pass def cloneurl(self, url, auth): """ add feeds from remote url. """ data = geturl2(url) got = [] for line in data.split('\n'): try: (name, url) = line.split() except ValueError: logging.debug("hubbub - cloneurl - can't split %s line" % line) continue if url.endswith('<br>'): url = url[:-4] self.add(name, url, auth) got.append(name) return got def watch(self, name): """ make feed ready for watching and mark it running. """ logging.debug('trying %s hubbub feed' % name) item = self.byname(name) if item == None: raise NoSuchFeed(name) if not item.data.running: item.data.running = 1 item.data.stoprunning = 0 item.save() subscribe(item.data['url'], self.data.host) logging.info('hubbub - started %s watch' % name) def work(self, botname, type, channel, entries, url, *args, **kwargs): logging.debug("in work .. %s" % str(entries)) try: item = self.byurl(url) name = item.data.name try: fleet = getfleet() bot = fleet.byname(botname) if not bot: logging.warn("can't find %s bot in fleet" % botname) ; return except NoSuchBotType, ex: logging.warn("hubbub - %s" % str(ex)) ; return if not bot: logging.error("hubbub - can't find %s bot in fleet" % type) ; return res2 = entries if not res2: logging.info("no updates for %s (%s) feed available" % (item.data.name, channel)) ; return if item.markup.get(jsonstring([name, channel]), 'reverse-order'): res2 = res2[::-1] if item.markup.get(jsonstring([name, channel]), 'all-lines'): for i in res2: response = self.makeresponse(name, [i, ], channel) try: bot.say(channel, response) except Exception, ex: handle_exception() else: sep = item.markup.get(jsonstring([name, channel]), 'separator') if sep: response = self.makeresponse(name, res2, channel, sep=sep) else: response = self.makeresponse(name, res2, channel) bot.say(channel, response) except Exception, ex: handle_exception() def incoming(self, data): """ process incoming hubbub data. """ result = feedparser.parse(data) url = find_self_url(result.feed.links) logging.debug("hubbub - in - %s - %s" % (url, data)) try: item = self.byurl(url) if not item: logging.warn("hubbub - can't find feed for %s" % url) ; return if not item.data.running: logging.warn("hubbub - %s is not in running mode" % item.data.url) ; return if not item.data.url or item.data.url == 'urlnotset': item.data.url = url item.save() if item: loopover = item.data.watchchannels name = item.data.name else: logging.warn("hubbub - can't find %s item" % url) ; return logging.warn("loopover in %s peek is: %s" % (name, loopover)) counter = 1 for i in loopover: if len(i) == 3: try: (botname, type, channel) = i except: try: (botname, type, channel) = loads(i) except: logging.warn('hubbub - %s is not in the format (botname, bottype, channel)' % str(item)) continue else: logging.warn('hubbub - %s is not in the format (botname, bottype, channel)' % item.data.url) continue counter += 1 start_new_thread(self.work, (botname, type, channel, result.entries, url), {"_countdown": counter}) except Exception, ex: handle_exception(txt=url) return True def getall(self): """ reconstruct all feeditems into self.feeds. """ for name in self.data['names']: self.feeds[name] = HubbubItem(name) return self.feeds def ownercheck(self, name, userhost): """ check if userhost is the owner of feed. """ try: return self.byname(name).ownercheck(userhost) except (KeyError, AttributeError): pass return False def makeresult(self, name, target, data): """ make a result (txt) of a feed depending on its itemlist (tokens) and markup. """ item = self.byname(name) res = [] for j in data: tmp = {} if not item.itemslists.data[jsonstring([name, target])]: return [] for i in item.itemslists.data[jsonstring([name, target])]: try: tmp[i] = unicode(j[i]) except KeyError: continue res.append(tmp) return res def makeresponse(self, name, res, channel, sep=" .. "): """ loop over result to make a response. """ item = self.byname(name) result = u"[%s] - " % name try: itemslist = item.itemslists.data[jsonstring([name, channel])] except KeyError: item = self.byname(name) if item == None: return "no %s rss item" % name else: item.itemslists.data[jsonstring([name, channel])] = ['title', 'link'] item.itemslists.save() for j in res: if item.markup.get(jsonstring([name, channel]), 'skipmerge') and 'Merge branch' in j['title']: continue resultstr = u"" for i in item.itemslists.data[jsonstring([name, channel])]: try: ii = getattr(j, i) if not ii: continue ii = unicode(ii) if ii.startswith('http://'): if item.markup.get(jsonstring([name, channel]), 'tinyurl'): try: tinyurl = get_tinyurl(ii) logging.debug('rss - tinyurl is: %s' % str(tinyurl)) if not tinyurl: resultstr += u"%s - " % ii else: resultstr += u"%s - " % tinyurl[0] except Exception, ex: handle_exception() resultstr += u"%s - " % item else: resultstr += u"%s - " % ii else: resultstr += u"%s - " % ii.strip() except (KeyError, AttributeError), ex: logging.info('hubbub - %s - %s' % (name, str(ex))) continue