-
Notifications
You must be signed in to change notification settings - Fork 7
/
twitter-bot.py
executable file
·132 lines (113 loc) · 4.45 KB
/
twitter-bot.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
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright (C) 2010 Saúl ibarra Corretgé <saghul@gmail.com>
#
import feedparser
import os
import re
import sys
import twitter
import urllib
import urllib2
from application.configuration import ConfigSection
from application import log
from optparse import OptionParser
from pysqlite2 import dbapi2 as sqlite
TWITTERBOT_CFG = "%s/config.ini" % (os.path.dirname(sys.argv[0]) or '.')
TWITTERBOT_DB = "%s/twitterbot.db" % (os.path.dirname(sys.argv[0]) or '.')
class Config(ConfigSection):
__cfgfile__ = TWITTERBOT_CFG
__section__ = 'twitterbot'
consumer_key = ''
consumer_secret = ''
access_token_key = ''
access_token_secret = ''
class TwitterBot(object):
_rt_regex = re.compile(r"^(RT @\w+: )+(?P<tweet>.*)$")
_via_regex = re.compile(r"^(?P<tweet>.*)\(via @\w+\)$")
def __init__(self):
self._api = twitter.Api(username=Config.consumer_key,
password=Config.consumer_secret,
access_token_key=Config.access_token_key,
access_token_secret=Config.access_token_secret)
try:
user = self._api.VerifyCredentials()
except twitter.TwitterError, e:
raise RuntimeError(str(e))
else:
self.user = user.GetName()
def start(self, searchtag):
try:
con = sqlite.connect(TWITTERBOT_DB)
con.isolation_level = None
twitts = self.search_tag(searchtag)
for twitt in reversed(twitts['entries']):
try:
twitt_id = twitt.id.split(':')[2]
except IndexError:
twitt_id = twitt.id.split(':')
twitt_author = twitt.author.split(' ')[0]
twitt_content = twitt.title
if self.user == twitt_author:
# I don't want to RT my own twitts!
continue
db_id = con.execute("SELECT id FROM twitts WHERE id MATCH ?", [twitt_id])
if db_id.fetchall():
# We already twitted this!
continue
# Avoid duplicated twitts because of retwitting
tmp = twitt_content
if tmp.find('RT @') != -1:
tmp = tmp[tmp.find('RT @'):]
m = self._rt_regex.match(tmp) or self._via_regex.match(tmp)
if m:
data = m.groupdict()
tmp = data['tweet']
if not tmp:
continue
db_content = con.execute("SELECT id FROM twitts WHERE content MATCH ?", [tmp[:100]])
if db_content.fetchall():
continue
try:
message = "RT @%s: %s" % (twitt_author, twitt_content)
if len(message) > 140:
message = "%s..." % message[:137]
self._api.PostUpdate(message)
except twitter.TwitterError, e:
log.error("Twitter Error: %s" % e.message)
else:
con.execute("INSERT INTO twitts(id, content) VALUES(?, ?)", [twitt_id, message])
con.close()
except sqlite.Error, e:
log.fatal("SQLite error: %s" % str(e))
sys.exit(1)
def search_tag(self, tag, lang='en'):
url = 'http://search.twitter.com/search.atom'
data = urllib.urlencode({'tag' : tag, 'lang' : lang})
try:
opener = urllib2.build_opener()
opener.addheaders = [ ( 'User-agent', 'Mozilla/5.0' ) ]
req = urllib2.Request(url, data)
except urllib2.HTTPError, err:
print str(err)
return {}
else:
d = feedparser.parse(opener.open(req).read())
if d.bozo == 1:
return {}
return d
if __name__ == "__main__":
if not Config.consumer_key or not Config.consumer_secret or not Config.access_token_key or not Config.access_token_secret:
log.fatal("Please, fill the confion file")
sys.exit(1)
usage = "usage: %prog [options]"
parser = OptionParser(usage=usage)
parser.add_option('-t', dest='tag', help='Hashtag to search for')
options, args = parser.parse_args()
if options.tag:
log.start_syslog("twitterbot")
bot = TwitterBot()
bot.start(options.tag)
else:
parser.print_help()
sys.exit(1)