PageRenderTime 50ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/vsroom/common/twitterbot.py

https://bitbucket.org/clarifiednetworks/vsroom/
Python | 201 lines | 141 code | 28 blank | 32 comment | 26 complexity | 2ddc3bb0443ed725e03e7286497b5958 MD5 | raw file
  1. # depends on bleeding edge http://code.google.com/p/python-twitter/
  2. # depends on http://github.com/simplegeo/python-oauth2
  3. # which depends on http://pypi.python.org/packages/source/s/setuptools/
  4. #
  5. # Due to the fact that twitter uses oauth, you need to do this dance to use this bot.
  6. #
  7. # 0. create twitter account, if you don't have one
  8. #
  9. # 1. register 'twitter application:
  10. # http://dev.twitter.com/apps/new
  11. #
  12. # 2. once you are done pick the consumer key and consumer secret from
  13. # the resulting web page
  14. #
  15. # 3. from python-twitter api directory, run
  16. # 'python get_access_token.py'
  17. #
  18. # 4. go to the url it prints, see the pin code in shown in your browser, and
  19. # give it to the get_access_token.py
  20. #
  21. # 5. copy & paste the produced twitter access token key and access
  22. # token secret for using it with this bot
  23. try:
  24. import json
  25. JSONDecodeError = ValueError
  26. except ImportError:
  27. import simplejson as json
  28. JSONDecodeError = getattr(json, "JSONDecodeError", ValueError)
  29. from abusehelper.core import bot,events
  30. from idiokit import threado,timer
  31. import twitter
  32. import re,time
  33. import socket
  34. from urllib2 import URLError
  35. from vsroom.common import id
  36. from vsroom.common import timeconversion
  37. class TwitterBot(bot.PollingBot):
  38. consumer_key = bot.Param()
  39. consumer_secret = bot.Param()
  40. access_token_key = bot.Param()
  41. access_token_secret = bot.Param()
  42. old_tweets = dict()
  43. def feed_keys(self, user, **keys):
  44. return [user]
  45. @threado.stream
  46. def poll(inner,self,user):
  47. yield timer.sleep(1)
  48. new_tweets = dict()
  49. api = twitter.Api(consumer_key=self.consumer_key,
  50. consumer_secret=self.consumer_secret,
  51. access_token_key=self.access_token_key,
  52. access_token_secret=self.access_token_secret)
  53. try:
  54. userobj = api.GetUser(user)
  55. friends = api.GetFriends()
  56. except (URLError,twitter.TwitterError,ValueError,JSONDecodeError,socket.error), e:
  57. self.log.error("Twitter error: %s." % (e))
  58. return
  59. self.log.info('Fetching status for %s' % userobj.name)
  60. for friend in [userobj] + friends:
  61. status = friend.GetStatus()
  62. name = friend.screen_name
  63. if status == None: continue
  64. start = status.GetCreatedAtInSeconds()
  65. new_tweets[name] = friend
  66. #dedup
  67. for name, friend in new_tweets.iteritems():
  68. # 1. is this the same event that was sent previously, and
  69. # 2. is this older event than the recent one (twitter api
  70. # sometimes returns non-latest tweet)
  71. old_friend = self.old_tweets.get(name)
  72. if old_friend == None:
  73. event = self.get_event(friend)
  74. inner.send(event)
  75. continue
  76. old_tweet = self.old_tweets.get(name).GetStatus()
  77. new_tweet = friend.GetStatus()
  78. prev_created = old_tweet.GetCreatedAtInSeconds()
  79. new_created = new_tweet.GetCreatedAtInSeconds()
  80. if prev_created < new_created:
  81. event = self.get_event(friend)
  82. inner.send(event)
  83. self.old_tweets = new_tweets
  84. def get_event(self,user):
  85. status = user.GetStatus()
  86. update = status.GetCreatedAtInSeconds()
  87. name = user.name.lower()
  88. followers_count = user.GetFriendsCount()
  89. statuses_count = user.GetStatusesCount()
  90. event = events.Event()
  91. event.add('user',user.name.lower())
  92. now = timeconversion.local_iso()
  93. event = blogparse(event, status.text)
  94. event.add('description', "%s - %s - %s" % (now, name, status.text.lower()))
  95. event.add('type', 'microblog')
  96. event.add('subtype','twitter')
  97. event.add('followers',unicode(followers_count))
  98. event.add('statuses_count', unicode(statuses_count))
  99. event.add('src',user.name.lower())
  100. event.add('dst','followers')
  101. event.add('id',id.create_id(event,'user'))
  102. event.add('start', timeconversion.seconds2iso(update))
  103. return event
  104. def blogparse(event,txt):
  105. for _,dst in re.findall('(^|\s){0,1}@([^\s|:]+)',txt):
  106. event.add('dst', dst)
  107. for k,v in fuzzy(txt):
  108. event.add(k.lower(),v.lower())
  109. for k,v in tags(txt):
  110. k = k.lower()
  111. v = v.lower()
  112. #tags override fuzzy
  113. event.clear(k)
  114. event.add(k,v)
  115. for k,v in keyvalues(txt):
  116. k = k.lower()
  117. v = v.lower()
  118. #keyvalues override tags
  119. event.clear(k)
  120. event.add(k,v)
  121. return event
  122. def fuzzy(txt):
  123. problem = re.search('problem|Problem|PROBLEM|warning|Warning|WARNING',txt)
  124. if problem:
  125. yield ('status', '20')
  126. yield ('problem', '20')
  127. alert = re.search('alert|Alert|ALERT',txt)
  128. if alert:
  129. yield ('status','75')
  130. yield ('problem', '75')
  131. ok = re.search('ok|Ok|OK',txt)
  132. if ok:
  133. yield('status','0')
  134. def tags(txt):
  135. tags = re.findall('#([^"][^=|^\s]+)',txt)
  136. for tag in tags:
  137. yield tag, '1'
  138. def keyvalues(txt):
  139. kvs = re.findall('#([^"][^\s]+)=([^"][^\s]+)',txt)
  140. for k,v in kvs:
  141. yield k,v
  142. #spaces in key and value
  143. kvs = re.findall('#"([^"]+)"="([^"]+)"',txt)
  144. for k,v in kvs:
  145. yield k,v
  146. #spaces in value
  147. kvs = re.findall('#([^"][^\s]+)="([^"]+)"',txt)
  148. for k,v in kvs:
  149. yield k,v
  150. #spaces in key
  151. kvs = re.findall('#"([^"]+)"=([^"][^\s]+)',txt)
  152. for k,v in kvs:
  153. yield k,v
  154. def test():
  155. msgs = list()
  156. msgs.append('Hello world')
  157. msgs.append('We have problems.')
  158. msgs.append('Alert foo bar')
  159. msgs.append('everythig OK')
  160. msgs.append('i want to #tag #tag2')
  161. msgs.append('key value #sector=comm')
  162. msgs.append(u'aaa #"key space"="value space"')
  163. msgs.append('key valuespace #sector="tele of comm" and problem')
  164. msgs.append('key valuespace #sector x=telecomm"')
  165. msgs.append('#"foo2"="bar2"')
  166. msgs.append('#starttag key valuespace #key="value space"')
  167. for msg in msgs:
  168. for fuz in fuzzy(msg): print ' fuz:', fuz
  169. for tag in tags(msg): print ' tag:', tag
  170. for kv in keyvalues(msg): print ' kv:', kv
  171. if __name__ == "__main__":
  172. TwitterBot.from_command_line().execute()
  173. # test()