summaryrefslogtreecommitdiffstats
path: root/news/rssbot.py
blob: 87c58781d4f0db09e737252cc62f80a432d8528e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/usr/bin/python
import irc.bot
from irc.client import IRC
import feedparser
import threading
import math
import re
import subprocess
from datetime import datetime
from time import sleep

class RssBot(irc.bot.SingleServerIRCBot):
    def __init__(self, rss, name, chans=['#news'], url_shortener="http://localhost", server='ire', port=6667, timeout=60):
        irc.bot.SingleServerIRCBot.__init__(self, [(server, port)], name, name)
        self.url = rss
        self.name = name
        self.server = server
        self.port = port
        self.chans = chans
        self.to = timeout
        self.oldnews = []
        self.sendqueue = []
        self.loop = True
        self.lastnew = datetime.now()
        self.url_shortener = url_shortener

        def better_loop(timeout=0.2):
            while self.loop:
                self.ircobj.process_once(timeout)
        self.ircobj.process_forever = better_loop


    def start(self):
        self.upd_loop = threading.Thread(target=self.updateloop)
        self.bot = threading.Thread(target=irc.bot.SingleServerIRCBot.start, args=(self,))
        self.upd_loop.start()
        self.bot.start()

    def stop(self):
        self.ircobj.disconnect_all()
        self.loop = False
        del self

    def updateloop(self):
        failcount=0
        while True:
          try:
              self.feed = feedparser.parse(self.url)
              for entry in self.feed.entries:
                  self.oldnews.append(entry.link)
              break
          except:
              print(self.name + ': rss timeout occured')
              failcount+=1
              if failcount>20:
                  print(self.name + ' is broken, going to die')
                  self.stop()
                  return
        while self.loop:
            try:
                self.feed = feedparser.parse(self.url)
                for entry in self.feed.entries:
                    if not entry.link in self.oldnews:
                        #try:
                        #    self.send(entry.title + " " + entry.link + " com: " + entry.comments)
                        #except AttributeError:
                        shorturl = self.shortenurl(entry.link)
                        self.sendall(entry.title + ' ' + shorturl)
                        self.oldnews.append(entry.link)
                        self.lastnew = datetime.now()
            except:
                print(self.name + ': rss timeout occured')
            sleep(self.to)

    def shortenurl(self, url):
      while True:
          try:
              shorturl = subprocess.check_output(["curl", "-sS", "-F", "uri=" + url, self.url_shortener]).decode().strip('\n').strip('\r') + '#' + url.partition('://')[2].partition('/')[0]
              return shorturl
          except:
              print('url shortener error')
              sleep(1)

    def last(self, target, num):
        for feed in [x for x in self.feed.entries][:num]:
            self.send(target, feed.title + ' ' + self.shortenurl(feed.link))

    def sendall(self, string):
        for chan in self.channels:
            self.send(chan, string)

    def send(self, target, string):
        if self.connection.connected:
            for line in string.split('\n'):
                if len(line) < 450:
                    self.connection.privmsg(target, line)
                    sleep(1)
                else:
                    space = 0
                    for x in range(math.ceil(len(line)/400)):
                        oldspace = space
                        space = line.find(" ", (x+1)*400, (x+1)*400+50)
                        self.connection.privmsg(target, line[oldspace:space])
                        sleep(1)
        else:
            self.connection.reconnect()
            sleep(1)
            self.send(string)

    def on_invite(self, connection, event):
        for chan in event.arguments:
            connection.join(chan)

    def on_welcome(self, connection, event):
        for chan in self.chans:
            connection.join(chan)