5
"""the rss mantra is of the following:
9
. add a url with rss-add
10
. start the watcher with rss-watch
12
now the user can start the bot sending messages of the feed to him with
13
rss-start. if an OPER gives a rss-start command in a channel data will be
17
__copyright__ = 'this file is in the public domain'
18
__gendocfirst__ = ['rss-add', 'rss-watch', 'rss-start']
19
__gendocskip__ = ['rss-dump', ]
21
from gozerbot.compat.persist import Persist
22
from gozerbot.utils.url import geturl2
23
from gozerbot.utils.exception import handle_exception
24
from gozerbot.utils.log import rlog
25
from gozerbot.utils.locking import lockdec
26
from gozerbot.utils.generic import strippedtxt, fromenc
27
from gozerbot.utils.url import striphtml, useragent
28
from gozerbot.utils.rsslist import rsslist
29
from gozerbot.utils.statdict import Statdict
30
from gozerbot.fleet import fleet
31
from gozerbot.commands import cmnds
32
from gozerbot.examples import examples
33
from gozerbot.datadir import datadir
34
from gozerbot.utils.dol import Dol
35
from gozerbot.compat.pdod import Pdod
36
from gozerbot.compat.pdol import Pdol
37
from gozerbot.plughelp import plughelp
38
from gozerbot.periodical import periodical
39
from gozerbot.aliases import aliasset
40
from gozerbot.users import users
42
import gozerbot.threads.thr as thr
43
import time, os, types, thread, socket, xml
45
plughelp.add('rss', 'manage rss feeds')
49
def txtindicts(result, d):
50
""" return lowlevel values in (nested) dicts """
52
if type(j) == types.DictType:
57
def checkfordate(data, date):
67
rsslock = thread.allocate_lock()
68
locked = lockdec(rsslock)
70
class RssException(Exception):
73
class Rss301(RssException):
76
class RssStatus(RssException):
79
class RssBozoException(RssException):
82
class RssNoSuchItem(RssException):
85
class Rssitem(object):
87
""" item that contains rss data """
89
def __init__(self, name, url, itemslist, watchchannels=[], \
93
self.itemslist = list(itemslist)
94
self.watchchannels = list(watchchannels)
95
self.sleeptime = int(sleeptime)
101
return "name=%s url=%s itemslist=%s watchchannels=%s sleeptime=%s \
102
running=%s" % (self.name, self.url, str(self.itemslist), \
103
str(self.watchchannels), str(self.sleeptime), self.running)
105
class Rssdict(Persist):
107
""" dict of rss entries """
109
def __init__(self, filename):
110
Persist.__init__(self, filename)
113
if self.data.has_key('itemslists'):
114
del self.data['itemslists']
115
self.itemslists = Pdol(filename + '.itemslists')
123
self.markup = Pdod(filename + '.markup')
126
""" return number of rss entries """
127
return len(self.data)
130
def add(self, name, url):
132
rlog(10, 'rss', 'adding %s %s' % (name, url))
133
self.data[name] = Rssitem(name, url, ['title', ])
137
def delete(self, name):
138
""" delete rss item by name """
140
for j, i in self.data.iteritems():
151
def byname(self, name):
152
""" return rss item by name """
154
return self.data[name]
158
def getdata(self, name):
159
""" get data of rss feed """
160
rssitem = self.byname(name)
162
raise RssNoSuchItem("no %s rss item found" % name)
164
modified = self.modified[name]
168
etag = self.etag[name]
171
result = feedparser.parse(rssitem.url, modified=modified, etag=etag, \
173
if result and result.has_key('bozo_exception'):
174
rlog(1, 'rss', '%s bozo_exception: %s' % (name, \
175
result['bozo_exception']))
176
#raise RssStatus(result['bozo_exception'])
178
status = result.status
179
except AttributeError:
181
if status != 200 and status != 301 and status != 302 and status != 304:
182
raise RssStatus(status)
184
self.modified[name] = result.modified
185
except AttributeError:
188
self.etag[name] = result.etag
189
except AttributeError:
192
return self.rawresults[name]
194
self.rawresults[name] = result.entries
195
return result.entries
197
class Rsswatcher(Rssdict):
201
def __init__(self, filename):
202
Rssdict.__init__(self, filename)
204
def sync(self, name):
205
result = self.getdata(name)
207
self.results[name] = result
209
def changeinterval(self, name, interval):
210
periodical.changeinterval(self.jobids[name], interval)
213
def startwatchers(self):
214
""" start watcher threads """
215
for j, i in self.data.iteritems():
217
thr.start_new_thread(self.watch, (i.name, ))
220
def stopwatchers(self):
221
""" stop all watcher threads """
222
for j, i in self.data.iteritems():
225
periodical.killgroup('rss')
227
def dowatch(self, name, sleeptime=1800):
228
rssitem = self.byname(name)
230
rlog(10, 'rss', "no %s rss item available" % name)
235
except Exception, ex:
236
rlog(100, 'rss', '%s feed error: %s' % (name, str(ex)))
237
rlog(100, 'rss', '%s sleeping %s seconds for retry' % \
239
time.sleep(sleeptime)
240
if not rssitem.running:
245
def makeresult(self, name, target, data):
249
if not self.itemslists[(name, target)]:
251
for i in self.itemslists[(name, target)]:
253
tmp[i] = unicode(j[i])
259
def watch(self, name):
260
""" start a watcher thread """
262
rlog(10, 'rss', 'trying %s rss feed watcher' % name)
264
result = self.getdata(name)
265
except RssException, ex:
266
rlog(10, 'rss', "%s error: %s" % (name, str(ex)))
268
rssitem = self.byname(name)
271
# poll every sleeptime seconds
272
self.results[name] = result
273
pid = periodical.addjob(rssitem.sleeptime, 0, self.peek, name, name)
274
self.jobids[name] = pid
275
rlog(10, 'rss', 'started %s rss watch' % name)
277
def makeresponse(self, name, res, channel, sep="\002||\002"):
278
# loop over result to make a response
280
itemslist = self.itemslists[(name, channel)]
282
rssitem = self.byname(name)
284
return "no %s rss item" % name
286
self.itemslists.extend((name, channel), rssitem.itemslist)
287
self.itemslists.save()
290
for i in self.itemslists[(name, channel)]:
295
if item.startswith('http://'):
296
resultstr += "<%s> - " % item
298
resultstr += "%s - " % striphtml(item)
301
resultstr = resultstr[:-3]
303
result += "%s %s " % (resultstr, sep)
306
def peek(self, name, *args):
307
rssitem = self.byname(name)
308
if not rssitem or not rssitem.running or rssitem.stoprunning:
312
res = self.getdata(name)
313
except socket.timeout:
314
rlog(10, 'rss', 'socket timeout of %s' % name)
316
except RssException, ex:
317
rlog(10, 'rss', '%s error: %s' % (name, str(ex)))
326
if j not in self.results[name]:
327
self.results[name].append(j)
330
if not checkfordate(self.results[name], d):
331
self.results[name].append(j)
335
for item in rssitem.watchchannels:
337
(botname, channel) = item
339
rlog(10, 'rss', '%s is not in the format \
340
(botname,channel)' % str(item))
341
bot = fleet.byname(botname)
344
if self.markup.get((name, channel), 'all-lines'):
346
response = self.makeresponse(name, [i, ], channel)
347
bot.say(channel, "\002%s\002: %s" % \
348
(rssitem.name, response), fromm=rssitem.name)
350
sep = self.markup.get((name, channel), 'seperator')
352
response = self.makeresponse(name, res2, channel, \
355
response = self.makeresponse(name, res2, channel)
356
bot.say(channel, "\002%s\002: %s" % (rssitem.name, \
357
response), fromm=rssitem.name)
358
except Exception, ex:
359
handle_exception(txt=name)
362
def stopwatch(self, name):
363
""" stop watcher thread """
364
for i, j in self.data.iteritems():
368
del self.results[name]
373
periodical.killjob(self.jobids[i])
380
""" return of rss names """
381
feeds = self.data.keys()
386
""" show names/channels of running watchers """
388
for j, i in self.data.iteritems():
389
if i.running == 1 and not i.stoprunning:
390
result.append((i.name, i.watchchannels))
394
def feeds(self, botname, channel):
395
""" show names/channels of running watcher """
397
for j, i in self.data.iteritems():
398
if (botname, channel) in i.watchchannels:
399
result.append(i.name)
404
""" return url of rssitem """
405
for j, i in self.data.iteritems():
409
def scan(self, name):
410
""" scan a rss url for used xml items """
412
result = self.getdata(name)
413
except RssException, ex:
414
rlog(10, 'rss', '%s error: %s' % (name, str(ex)))
419
for item in self.rawresults[name]:
420
for key in item.keys():
422
statdict = Statdict()
425
return statdict.top()
427
def search(self, name, item, search):
429
for result in self.rawresults[name]:
431
title = result['title']
435
if search in title.lower():
440
def searchall(self, item, search):
442
for name, results in self.rawresults.iteritems():
443
for result in results:
445
title = result['title']
449
if search in title.lower():
451
res.append("%s: %s" % (name, txt))
454
def all(self, name, item):
456
for result in self.rawresults[name]:
465
watcher = Rsswatcher(datadir + os.sep + 'old' + os.sep + 'rss')
468
""" called after plugin import """
469
thr.start_new_thread(watcher.startwatchers, ())
473
""" return number of watched rss entries """
474
return watcher.size()
477
""" called before plugin import """
478
watcher.stopwatchers()
481
def handle_rssadd(bot, ievent):
482
""" rss-add <name> <url> .. add a rss item """
484
(name, url) = ievent.args
486
ievent.missing('<name> <url>')
488
watcher.add(name, url)
489
ievent.reply('rss item added')
491
cmnds.add('rss-add', handle_rssadd, 'OPER')
492
examples.add('rss-add', 'rss-add <name> <url> to the rsswatcher', 'rss-add \
493
gozerbot http://gozerbot.org/hg/gozerbot/?cmd=changelog;style=rss')
495
def handle_rssdel(bot, ievent):
496
""" rss-del <name> .. delete a rss item """
498
name = ievent.args[0]
500
ievent.missing('<name>')
502
if watcher.byname(name):
503
watcher.stopwatch(name)
505
ievent.reply('rss item deleted')
507
ievent.reply('there is no %s rss item' % name)
509
cmnds.add('rss-del', handle_rssdel, 'OPER')
510
examples.add('rss-del', 'rss-del <name> .. remove <name> from the \
511
rsswatcher', 'rss-del mekker')
513
def handle_rsswatch(bot, ievent):
514
""" rss-watch <name> .. start watcher thread """
515
if not ievent.channel:
516
ievent.reply('no channel provided')
518
name, sleepsec = ievent.args
521
name = ievent.args[0]
524
ievent.missing('<name> [secondstosleep]')
527
sleepsec = int(sleepsec)
529
ievent.reply("time to sleep needs to be in seconds")
531
rssitem = watcher.byname(name)
533
ievent.reply("we don't have a %s rss object" % name)
536
if not rssitem.running:
537
rssitem.sleeptime = sleepsec
539
rssitem.stoprunning = 0
544
except Exception, ex:
545
ievent.reply(str(ex))
549
ievent.reply('watcher started')
551
ievent.reply('already watching %s' % name)
553
cmnds.add('rss-watch', handle_rsswatch, 'OPER')
554
examples.add('rss-watch', 'rss-watch <name> [seconds to sleep] .. go \
555
watching <name>', '1) rss-watch gozerbot 2) rss-watch gozerbot 600')
557
def handle_rssstart(bot, ievent):
558
""" rss-start <name> .. start a rss feed to a user """
560
ievent.missing('<feed name>')
563
rssitem = watcher.byname(name)
565
target = ievent.userhost
567
if users.allowed(ievent.userhost, ['OPER', ]) and not ievent.msg:
568
target = ievent.channel
572
ievent.reply("we don't have a %s rss object" % name)
574
if not rssitem.running:
575
ievent.reply('%s watcher is not running' % name)
577
if (bot.name, target) in rssitem.watchchannels:
578
ievent.reply('we are already monitoring %s on (%s,%s)' % \
579
(name, bot.name, target))
581
rssitem.watchchannels.append((bot.name, target))
582
for item in rssitem.itemslist:
583
watcher.itemslists.adduniq((name, target), item)
585
ievent.reply('%s started' % name)
587
cmnds.add('rss-start', handle_rssstart, ['RSS', 'USER'])
588
examples.add('rss-start', 'rss-start <name> .. start a rss feed \
589
(per user/channel) ', 'rss-start gozerbot')
591
def handle_rssstop(bot, ievent):
592
""" rss-start <name> .. start a rss feed to a user """
594
ievent.missing('<feed name>')
597
rssitem = watcher.byname(name)
599
target = ievent.userhost
601
if users.allowed(ievent.userhost, ['OPER', ]) and not ievent.msg:
602
target = ievent.channel
606
ievent.reply("we don't have a %s rss feed" % name)
608
if not rssitem.running:
609
ievent.reply('%s watcher is not running' % name)
611
if not (bot.name, target) in rssitem.watchchannels:
612
ievent.reply('we are not monitoring %s on (%s,%s)' % \
613
(name, bot.name, target))
615
rssitem.watchchannels.remove((bot.name, target))
617
ievent.reply('%s stopped' % name)
619
cmnds.add('rss-stop', handle_rssstop, ['RSS', 'USER'])
620
examples.add('rss-stop', 'rss-stop <name> .. stop a rss feed \
621
(per user/channel) ', 'rss-stop gozerbot')
623
def handle_rsschannels(bot, ievent):
624
""" rss-channels <name> .. show channels of rss feed """
626
name = ievent.args[0]
628
ievent.missing("<name>")
630
rssitem = watcher.byname(name)
632
ievent.reply("we don't have a %s rss object" % name)
634
if not rssitem.watchchannels:
635
ievent.reply('%s is not in watch mode' % name)
638
for i in rssitem.watchchannels:
639
result.append(str(i))
640
ievent.reply("channels of %s: " % name, result, dot=True)
642
cmnds.add('rss-channels', handle_rsschannels, 'OPER')
643
examples.add('rss-channels', 'rss-channels <name> .. show channels', \
644
'rss-channels gozerbot')
646
def handle_rssaddchannel(bot, ievent):
647
""" rss-addchannel <name> [<botname>] <channel> .. add a channel to \
650
(name, botname, channel) = ievent.args
653
(name, channel) = ievent.args
657
name = ievent.args[0]
659
channel = ievent.channel
661
ievent.missing('<name> [<botname>] <channel>')
663
rssitem = watcher.byname(name)
665
ievent.reply("we don't have a %s rss object" % name)
667
if not rssitem.running:
668
ievent.reply('%s watcher is not running' % name)
670
if (botname, channel) in rssitem.watchchannels:
671
ievent.reply('we are already monitoring %s on (%s,%s)' % \
672
(name, botname, channel))
674
rssitem.watchchannels.append((botname, channel))
676
ievent.reply('%s added to %s rss item' % (channel, name))
678
cmnds.add('rss-addchannel', handle_rssaddchannel, 'OPER')
679
examples.add('rss-addchannel', 'rss-addchannel <name> [<botname>] <channel> \
680
..add <channel> or <botname> <channel> to watchchannels of <name>', \
681
'1) rss-addchannel gozerbot #dunkbots 2) rss-addchannel gozerbot main \
684
def handle_rssadditem(bot, ievent):
686
(name, item) = ievent.args
688
ievent.missing('<name> <item>')
690
if bot.jabber or users.allowed(ievent.userhost, ['OPER', ]):
691
target = ievent.channel.lower()
693
target = ievent.nick.lower()
694
if not watcher.byname(name):
695
ievent.reply("we don't have a %s feed" % name)
697
watcher.itemslists.adduniq((name, target), item)
698
watcher.itemslists.save()
700
ievent.reply('%s added to (%s,%s) itemslist' % (item, name, target))
702
cmnds.add('rss-additem', handle_rssadditem, ['RSS', 'USER'])
703
examples.add('rss-additem', 'add a token to the itemslist (per user/channel)',\
704
'rss-additem gozerbot link')
706
def handle_rssdelitem(bot, ievent):
708
(name, item) = ievent.args
710
ievent.missing('<name> <item>')
712
if users.allowed(ievent.userhost, ['OPER', 'RSS']):
713
target = ievent.channel.lower()
715
target = ievent.nick.lower()
716
if not watcher.byname(name):
717
ievent.reply("we don't have a %s feed" % name)
720
watcher.itemslists.remove((name, target), item)
721
watcher.itemslists.save()
722
except RssNoSuchItem:
723
ievent.reply("we don't have a %s rss feed" % name)
725
ievent.reply('%s removed from (%s,%s) itemslist' % (item, name, target))
727
cmnds.add('rss-delitem', handle_rssdelitem, ['RSS', 'USER'])
728
examples.add('rss-delitem', 'remove a token from the itemslist \
729
(per user/channel)', 'rss-delitem gozerbot link')
731
def handle_rssmarkup(bot, ievent):
733
name = ievent.args[0]
735
ievent.missing('<name>')
737
if users.allowed(ievent.userhost, ['OPER', ]):
738
target = ievent.channel.lower()
740
target = ievent.nick.lower()
742
ievent.reply(str(watcher.markup[(name, target)]))
746
cmnds.add('rss-markup', handle_rssmarkup, ['RSS', 'USER'])
747
examples.add('rss-markup', 'show markup list for a feed (per user/channel)', \
748
'rss-markup gozerbot')
750
def handle_rssaddmarkup(bot, ievent):
752
(name, item, value) = ievent.args
754
ievent.missing('<name> <item> <value>')
756
if users.allowed(ievent.userhost, ['OPER', ]):
757
target = ievent.channel.lower()
759
target = ievent.nick.lower()
761
watcher.markup.set((name, target), item, value)
762
watcher.markup.save()
763
ievent.reply('%s added to (%s,%s) markuplist' % (item, name, target))
765
ievent.reply("no (%s,%s) feed available" % (name, target))
767
cmnds.add('rss-addmarkup', handle_rssaddmarkup, ['RSS', 'USER'])
768
examples.add('rss-addmarkup', 'add a markup option to the markuplist \
769
(per user/channel)', 'rss-addmarkup gozerbot noseperator 1')
771
def handle_rssdelmarkup(bot, ievent):
773
(name, item) = ievent.args
775
ievent.missing('<name> <item>')
777
if users.allowed(ievent.userhost, ['OPER', 'RSS']):
778
target = ievent.channel.lower()
780
target = ievent.nick.lower()
782
del watcher.markup[(name, target)][item]
783
except (KeyError, TypeError):
784
ievent.reply("can't remove %s from %s feed's markup" % (item, name))
786
watcher.markup.save()
787
ievent.reply('%s removed from (%s,%s) markuplist' % (item, name, target))
789
cmnds.add('rss-delmarkup', handle_rssdelmarkup, ['RSS', 'USER'])
790
examples.add('rss-delmarkup', 'remove a markup option from the markuplist \
791
(per user/channel)', 'rss-delmarkup gozerbot noseperator')
793
def handle_rssdelchannel(bot, ievent):
794
""" rss-delchannel <name> [<botname>] <channel> .. delete channel \
798
(name, botname, channel) = ievent.args
801
(name, channel) = ievent.args
805
name = ievent.args[0]
807
channel = ievent.channel
809
ievent.missing('<name> [<botname>] [<channel>]')
811
rssitem = watcher.byname(name)
813
ievent.reply("we don't have a %s rss object" % name)
815
if (botname, channel) not in rssitem.watchchannels:
816
ievent.reply('we are not monitoring %s on (%s,%s)' % \
817
(name, botname, channel))
819
rssitem.watchchannels.remove((botname, channel))
820
ievent.reply('%s removed from %s rss item' % (channel, name))
823
cmnds.add('rss-delchannel', handle_rssdelchannel, 'OPER')
824
examples.add('rss-delchannel', 'rss-delchannel <name> [<botname>] \
825
[<channel>] .. delete <channel> or <botname> <channel> from watchchannels of \
826
<name>', '1) rss-delchannel gozerbot #dunkbots 2) rss-delchannel gozerbot \
829
def handle_rssstopwatch(bot, ievent):
830
""" rss-stopwatch <name> .. stop a watcher thread """
832
name = ievent.args[0]
834
ievent.missing('<name>')
836
rssitem = watcher.byname(name)
838
ievent.reply("there is no %s rssitem" % name)
840
if not watcher.stopwatch(name):
841
ievent.reply("can't stop %s watcher" % name)
843
ievent.reply('stopped %s rss watch' % name)
845
cmnds.add('rss-stopwatch', handle_rssstopwatch, 'OPER')
846
examples.add('rss-stopwatch', 'rss-stopwatch <name> .. stop polling <name>', \
847
'rss-stopwatch gozerbot')
849
def handle_rsssleeptime(bot, ievent):
850
""" rss-sleeptime <name> .. get sleeptime of rss item """
852
name = ievent.args[0]
854
ievent.missing('<name>')
856
rssitem = watcher.byname(name)
858
ievent.reply("we don't have a %s rss item" % name)
861
ievent.reply('sleeptime for %s is %s seconds' % (name, \
862
str(rssitem.sleeptime)))
863
except AttributeError:
864
ievent.reply("can't get sleeptime for %s" % name)
866
cmnds.add('rss-sleeptime', handle_rsssleeptime, 'OPER')
867
examples.add('rss-sleeptime', 'rss-sleeptime <name> .. get sleeping time \
868
for <name>', 'rss-sleeptime gozerbot')
870
def handle_rsssetsleeptime(bot, ievent):
871
""" rss-setsleeptime <name> <seconds> .. set sleeptime of rss item """
873
(name, sec) = ievent.args
876
ievent.missing('<name> <seconds>')
879
ievent.reply('min is 60 seconds')
881
rssitem = watcher.byname(name)
883
ievent.reply("we don't have a %s rss item" % name)
885
rssitem.sleeptime = sec
887
watcher.changeinterval(name, sec)
889
ievent.reply('sleeptime set')
891
cmnds.add('rss-setsleeptime', handle_rsssetsleeptime, 'OPER')
892
examples.add('rss-setsleeptime', 'rss-setsleeptime <name> <seconds> .. set \
893
sleeping time for <name> .. min 60 sec', 'rss-setsleeptime gozerbot 600')
895
def handle_rssget(bot, ievent):
896
""" rss-get <name> .. fetch rss data """
898
name = ievent.args[0]
900
ievent.missing('<name>')
902
rssitem = watcher.byname(name)
904
ievent.reply("we don't have a %s rss item" % name)
907
result = watcher.getdata(name)
908
except Exception, ex:
909
ievent.reply('%s error: %s' % (name, str(ex)))
911
response = watcher.makeresponse(name, result, ievent.channel)
913
ievent.reply("results of %s: %s" % (name, response))
915
ievent.reply("can't match watcher data")
917
cmnds.add('rss-get', handle_rssget, ['RSS', 'USER', 'ANON'])
918
examples.add('rss-get', 'rss-get <name> .. get data from <name>', \
921
def handle_rssrunning(bot, ievent):
922
""" rss-running .. show which watchers are running """
923
result = watcher.runners()
927
resultlist.append("%s %s" % (i[0], i[1]))
929
ievent.reply("running rss watchers: ", resultlist, nr=1)
931
ievent.reply('nothing running yet')
933
cmnds.add('rss-running', handle_rssrunning, ['RSS', 'USER'])
934
examples.add('rss-running', 'rss-running .. get running rsswatchers', \
937
def handle_rsslist(bot, ievent):
938
""" rss-list .. return list of rss items """
939
result = watcher.list()
942
ievent.reply("rss items: ", result, dot=True)
944
ievent.reply('no rss items yet')
946
cmnds.add('rss-list', handle_rsslist, ['RSS', 'USER', 'ANON'])
947
examples.add('rss-list', 'get list of rss items', 'rss-list')
949
def handle_rssurl(bot, ievent):
950
""" rss-url <name> .. return url of rss item """
952
name = ievent.args[0]
954
ievent.missing('<name>')
956
result = watcher.url(name)
957
ievent.reply('url of %s: %s' % (name, result))
959
cmnds.add('rss-url', handle_rssurl, ['RSS', 'USER', 'ANON'])
960
examples.add('rss-url', 'rss-url <name> .. get url from rssitem with \
961
<name>', 'rss-url gozerbot')
963
def handle_rssitemslist(bot, ievent):
964
""" rss-itemslist <name> .. show itemslist of rss item """
966
name = ievent.args[0]
968
ievent.missing('<name>')
971
itemslist = watcher.itemslists[(name, ievent.channel.lower())]
973
ievent.reply("no itemslist set for (%s, %s)" % (name, \
974
ievent.channel.lower()))
976
ievent.reply("itemslist of (%s, %s): " % (name, ievent.channel.lower()), \
979
cmnds.add('rss-itemslist', handle_rssitemslist, ['RSS', 'USER'])
980
examples.add('rss-itemslist', 'rss-itemslist <name> .. get itemslist of \
981
<name> ', 'rss-itemslist gozerbot')
983
def handle_rssscan(bot, ievent):
984
""" rss-scan <name> .. scan rss item for used xml items """
986
name = ievent.args[0]
988
ievent.missing('<name>')
990
if not watcher.byname(name):
991
ievent.reply('no %s feeds available' % name)
994
result = watcher.scan(name)
995
except Exception, ex:
996
ievent.reply(str(ex))
999
ievent.reply("can't get data for %s" % name)
1003
res.append("%s=%s" % i)
1004
ievent.reply("tokens of %s: " % name, res)
1006
cmnds.add('rss-scan', handle_rssscan, 'OPER')
1007
examples.add('rss-scan', 'rss-scan <name> .. get possible items of <name> ', \
1008
'rss-scan gozerbot')
1010
def handle_rsssync(bot, ievent):
1011
""" rss-sync <name> .. sync rss item data """
1013
name = ievent.args[0]
1015
ievent.missing('<name>')
1018
result = watcher.sync(name)
1019
ievent.reply('%s synced' % name)
1020
except Exception, ex:
1021
ievent.reply("%s error: %s" % (name, str(ex)))
1023
cmnds.add('rss-sync', handle_rsssync, 'OPER')
1024
examples.add('rss-sync', 'rss-sync <name> .. sync data of <name>', \
1025
'rss-sync gozerbot')
1027
def handle_rssfeeds(bot, ievent):
1028
""" rss-feeds <channel> .. show what feeds are running in a channel """
1030
channel = ievent.args[0]
1032
channel = ievent.printto
1034
result = watcher.feeds(bot.name, channel)
1036
ievent.reply("feeds running in %s: " % channel, result, dot=True)
1038
ievent.reply('%s has no feeds running' % channel)
1039
except Exception, ex:
1040
ievent.reply("ERROR: %s" % str(ex))
1042
cmnds.add('rss-feeds', handle_rssfeeds, ['USER', 'RSS'])
1043
examples.add('rss-feeds', 'rss-feeds <name> .. show what feeds are running \
1044
in a channel', '1) rss-feeds 2) rss-feeds #dunkbots')
1046
def handle_rsslink(bot, ievent):
1048
feed, rest = ievent.rest.split(' ', 1)
1050
ievent.missing('<feed> <words to search>')
1052
rest = rest.strip().lower()
1054
res = watcher.search(feed, 'link', rest)
1056
res = watcher.search(feed, 'feedburner:origLink', rest)
1058
ievent.reply(res, dot=" \002||\002 ")
1060
ievent.reply('no %s feed data available' % feed)
1063
cmnds.add('rss-link', handle_rsslink, ['RSS', 'USER'])
1064
examples.add('rss-link', 'give link of item which title matches search key', \
1065
'rss-link gozerbot gozer')
1067
def handle_rssdescription(bot, ievent):
1069
feed, rest = ievent.rest.split(' ', 1)
1071
ievent.missing('<feed> <words to search>')
1073
rest = rest.strip().lower()
1076
ievent.reply(watcher.search(feed, 'description', rest), \
1079
ievent.reply('no %s feed data available' % feed)
1082
cmnds.add('rss-description', handle_rssdescription, ['RSS', 'USER'])
1083
examples.add('rss-description', 'give description of item which title \
1084
matches search key', 'rss-description gozerbot gozer')
1086
def handle_rssall(bot, ievent):
1088
feed = ievent.args[0]
1090
ievent.missing('<feed>')
1093
ievent.reply(watcher.all(feed, 'title'), dot=" \002||\002 ")
1095
ievent.reply('no %s feed data available' % feed)
1098
cmnds.add('rss-all', handle_rssall, ['RSS', 'USER'])
1099
examples.add('rss-all', "give titles of a feed", 'rss-all gozerbot')
1101
def handle_rsssearch(bot, ievent):
1103
txt = ievent.args[0]
1105
ievent.missing('<txt>')
1108
ievent.reply(watcher.searchall('title', txt), dot=" \002||\002 ")
1110
ievent.reply('no %s feed data available' % feed)
1113
cmnds.add('rss-search', handle_rsssearch, ['RSS', 'USER'])
1114
examples.add('rss-search', "search titles of all current feeds", \
1117
def handle_rssdump(bot, ievent):
1119
ievent.reply(str(watcher.rawresults[ievent.rest]))
1120
except Exception, ex:
1121
ievent.reply(str(ex))
1123
cmnds.add('rss-dump', handle_rssdump, 'OPER')
1124
examples.add('rss-dump', 'dump cached rss data', 'rss-dump')