forked from blha303/Twitter-IRC-Bridge
-
Notifications
You must be signed in to change notification settings - Fork 0
/
run.py
159 lines (138 loc) · 6.02 KB
/
run.py
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
import sys
import json
from time import sleep
import yaml
from twitter import *
from twisted.internet import reactor, task, protocol
from twisted.python import log
from twisted.words.protocols import irc
from twisted.application import internet, service
with open('config.yml') as configf:
config = yaml.load(configf.read())
HOST, PORT = config['host'], config['port']
def munge(inp):
return inp[0] + u"\u200b" + inp[1:]
def parsemsg(msg):
for i in msg["entities"]["urls"]:
msg["text"] = msg["text"].replace(i["url"], i["expanded_url"])
return msg["text"].replace("\n", " ")
class TwitterProtocol(irc.IRCClient):
nickname = config["nickname"]
password = config["password"]
username = 'Twitter'
versionName = 'Twitter'
versionNum = 'v1.6'
realname = 'https://github.com/blha303/Twitter-IRCBridge'
loopcall = None
def __init__(self):
self.lastid = {}
try:
with open('lastid') as f:
self.lastid = json.loads(f.read())
except (IOError, ValueError):
with open('lastid', 'w') as f:
f.write(json.dumps(self.lastid))
print "Created lastid file"
def updatelastid(self, sn, lid):
self.lastid[sn] = lid
with open('lastid', 'w') as f:
f.write(json.dumps(self.lastid))
def signedOn(self):
for channel in self.factory.channels:
self.join(channel)
if config["nickserv"]:
self._send_message("identify " + config["nickserv"], "NickServ")
def restartloop(reason):
reason.printTraceback()
print "Loop crashed: " + reason.getErrorMessage()
sleep(3)
self.loopcall.start(60.0).addErrback(restartloop)
self.loopcall = task.LoopingCall(self.getnewtweets)
self.loopcall.start(60.0).addErrback(restartloop)
def getnewtweets(self):
print "Getting tweets."
t = Twitter(auth=OAuth(config["oauth-token"],
config["oauth-secret"],
config["consumer-key"],
config["consumer-secret"]))
for sn in config["twusers"]:
print "Starting " + sn
try:
if sn in self.lastid:
print "[%s] lastid: %s" % (sn, self.lastid[sn])
timeline = t.statuses.user_timeline(screen_name=sn,
since_id=self.lastid[sn],
count=5,
exclude_replies=True)
else:
timeline = t.statuses.user_timeline(screen_name=sn, count=5,
exclude_replies=True)
print "Rate limit remaining: %s" % timeline.headers.getheader('x-rate-limit-remaining')
timeline.reverse()
for i in timeline:
fmt = u"\x02@{screen_name}\x0f: {text}"
out = fmt.format(text=parsemsg(i),
screen_name=i["user"]["screen_name"],
id=i["id_str"])
print "Sending " + out
try:
self._send_message(out.encode('utf-8'), config["twusers"][sn])
except UnicodeError:
print "Couldn't send %s due to error"
self.updatelastid(sn, i["id_str"])
finally:
print "Done " + sn
print "----------"
def privmsg(self, user, channel, message):
nick, _, host = user.partition('!')
try:
key = (key for key, value in config["twusers"].items() if value.lower() == channel.lower()).next()
except StopIteration:
key = None
split = message.split(" ")
if message == "!twitter" and nick == config["owner"]:
if key:
self._send_message("https://twitter.com/" + key, channel)
else:
self._send_message("I'm not set up for this channel.", channel)
elif split[0] == "!add" and nick == config["owner"]:
if len(split) != 3:
self._send_message("Usage: !add screenname #channel", channel)
else:
config["twusers"][split[1]] = split[2]
with open('config.yml', 'w') as f:
f.write(yaml.dump(config))
self.join(split[2])
self._send_message("Hi! I'm here to relay messages from https://twitter.com/%s to this "
"channel. Please ask %s if you have any questions or would like"
"this bot removed." % (split[1], config["owner"]), split[2])
self._send_message("Done.", channel)
elif split[0] == "!del" and nick == config["owner"]:
if len(split) != 2:
self._send_message("Usage: !del #channel", channel)
else:
try:
del config["twusers"][key]
self.leave(split[1])
with open('config.yml', 'w') as f:
f.write(yaml.dump(config))
except StopIteration:
self._send_message("I'm not set up for that channel.", channel)
def _send_message(self, msg, target, nick=None):
if nick:
msg = '%s, %s' % (nick, msg)
self.msg(target, msg)
@staticmethod
def _show_error(failure):
return failure.getErrorMessage()
class TwitterFactory(protocol.ReconnectingClientFactory):
protocol = TwitterProtocol
channels = config["twusers"].values()
if __name__ == '__main__':
reactor.connectTCP(HOST, PORT, TwitterFactory())
log.startLogging(sys.stdout)
reactor.run()
elif __name__ == '__builtin__':
application = service.Application('Twitter')
ircService = internet.TCPClient(HOST, PORT, TwitterFactory())
ircService.setServiceParent(application)