Putting all the code from the current master branch of TWBlue

This commit is contained in:
2014-10-27 16:29:04 -06:00
parent 58c82e5486
commit 1af4a8b291
284 changed files with 58760 additions and 0 deletions

2
src/twitter/__init__.py Normal file
View File

@@ -0,0 +1,2 @@
import buffers, utils, compose, starting, twitter
from compose import prettydate

View File

@@ -0,0 +1 @@
import stream, indibidual

View File

@@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
from twitter import compose
from twython import TwythonStreamer
import sound
from mysc import event
import wx
import config
import output
import logging as original_logger
log = original_logger.getLogger("MainStream")
class streamer(TwythonStreamer):
def __init__(self, app_key, app_secret, oauth_token, oauth_token_secret, timeout=300, retry_count=None, retry_in=10, client_args=None, handlers=None, chunk_size=1, parent=None):
self.db = parent.db
self.parent = parent
TwythonStreamer.__init__(self, app_key, app_secret, oauth_token, oauth_token_secret, timeout=60, retry_count=None, retry_in=180, client_args=None, handlers=None, chunk_size=1)
def on_error(self, status_code, data):
log.debug("%s: %s" % (status_code, data))
def check_tls(self, data):
for i in config.main["other_buffers"]["timelines"]:
if data["user"]["screen_name"] == i:
tweet_event = event.event(event.EVT_OBJECT, 1)
tweet_event.SetItem(data)
announce = _(u"One tweet from %s") % (data["user"]["name"])
tweet_event.SetAnnounce(announce)
wx.PostEvent(self.parent.nb.GetPage(self.db.settings["buffers"].index(i)), tweet_event)
for i in range(0, self.parent.nb.GetPageCount()):
if self.parent.nb.GetPage(i).type == "list":
try:
self.parent.nb.GetPage(i).users.index(data["user"]["id"])
tweet_event = event.event(event.EVT_OBJECT, 1)
tweet_event.SetItem(data)
announce = _(u"One tweet from %s in the list %s") % (data["user"]["name"], self.parent.nb.GetPage(i).name_buffer[:-5])
tweet_event.SetAnnounce(announce)
wx.PostEvent(self.parent.nb.GetPage(self.db.settings["buffers"].index(self.parent.nb.GetPage(i).name_buffer)), tweet_event)
except ValueError:
pass
def on_success(self, data):
try:
if "text" in data:
self.check_tls(data)
except:
pass

View File

@@ -0,0 +1,169 @@
# -*- coding: utf-8 -*-
from twitter import compose, utils
from twython import TwythonStreamer
import sound
from mysc import event
import wx
import config
import logging as original_logger
log = original_logger.getLogger("MainStream")
import output
class streamer(TwythonStreamer):
def __init__(self, app_key, app_secret, oauth_token, oauth_token_secret, timeout=300, retry_count=None, retry_in=10, client_args=None, handlers=None, chunk_size=1, parent=None):
self.db = parent.db
self.parent = parent
TwythonStreamer.__init__(self, app_key, app_secret, oauth_token, oauth_token_secret, timeout=480, retry_count=0, retry_in=60, client_args=None, handlers=None, chunk_size=1)
self.muted_users = self.db.settings["muted_users"]
# self.blocked_users = []
def on_error(self, status_code, data):
log.debug("Error %s: %s" % (status_code, data))
def block_user(self, data):
id = data["target"]["id"]
if id in self.friends:
self.friends.remove(id)
if config.main["other_buffers"]["show_blocks"] == True:
tweet_event = event.event(event.EVT_OBJECT, 1)
tweet_event.SetItem(data["target"])
wx.PostEvent(self.parent.nb.GetPage(self.db.settings["buffers"].index("blocks")), tweet_event)
def unblock(self, data):
if config.main["other_buffers"]["show_blocks"] == True:
item = utils.find_item(data["target"]["id"], self.db.settings["blocks"])
self.db.settings["blocks"].pop(item)
deleted_event = event.event(event.EVT_DELETED, 1)
deleted_event.SetItem(item)
wx.PostEvent(self.parent.nb.GetPage(self.db.settings["buffers"].index("blocks")), deleted_event)
wx.PostEvent(self.parent, event.ResultEvent())
def check_send(self, data):
if self.db.settings["user_name"] == data["user"]["screen_name"]:
tweet_event = event.event(event.EVT_OBJECT, 1)
tweet_event.SetItem(data)
wx.PostEvent(self.parent.nb.GetPage(self.db.settings["buffers"].index("sent")), tweet_event)
def check_favs(self, data):
if data["source"]["screen_name"] == self.db.settings["user_name"]:
tweet_event = event.event(event.EVT_OBJECT, 1)
tweet_event.SetItem(data["target_object"])
wx.PostEvent(self.parent.nb.GetPage(self.db.settings["buffers"].index("favs")), tweet_event)
def check_mentions(self, data):
if "@%s" % (self.db.settings["user_name"]) in data["text"]:
tweet_event = event.event(event.EVT_OBJECT, 1)
tweet_event.SetItem(data)
text = _(u"One mention from %s ") % (data["user"]["name"])
tweet_event.SetAnnounce(text)
wx.PostEvent(self.parent.nb.GetPage(self.db.settings["buffers"].index("mentions")), tweet_event)
def process_dm(self, data):
if self.db.settings["user_name"] == data["direct_message"]["sender"]["screen_name"]:
tweet_event = event.event(event.EVT_OBJECT, 1)
tweet_event.SetItem(data["direct_message"])
wx.PostEvent(self.parent.nb.GetPage(self.db.settings["buffers"].index("sent")), tweet_event)
if self.db.settings["user_name"] != data["direct_message"]["sender"]["screen_name"]:
tweet_event = event.event(event.EVT_OBJECT, 1)
tweet_event.SetItem(data["direct_message"])
text = _(u"One direct message")
tweet_event.SetAnnounce(text)
wx.PostEvent(self.parent.nb.GetPage(self.db.settings["buffers"].index("direct_messages")), tweet_event)
def check_follower(self, data):
if data["target"]["screen_name"] == self.db.settings["user_name"]:
if config.main["other_buffers"]["show_followers"] == True:
tweet_event = event.event(event.EVT_OBJECT, 1)
tweet_event.SetItem(data["source"])
wx.PostEvent(self.parent.nb.GetPage(self.db.settings["buffers"].index("followers")), tweet_event)
elif data["source"]["screen_name"] == self.db.settings["user_name"] and config.main["other_buffers"]["show_friends"] == True:
tweet_event = event.event(event.EVT_OBJECT, 1)
tweet_event.SetItem(data["target"])
wx.PostEvent(self.parent.nb.GetPage(self.db.settings["buffers"].index("friends")), tweet_event)
def remove_fav(self, data):
if self.db.settings["user_name"] == data["source"]["screen_name"]:
self.db.settings.update()
item = utils.find_item(data["target_object"]["id"], self.db.settings["favs"])
self.db.settings["favs"].pop(item)
deleted_event = event.event(event.EVT_DELETED, 1)
deleted_event.SetItem(item)
wx.PostEvent(self.parent.nb.GetPage(self.db.settings["buffers"].index("favs")), deleted_event)
def remove_friend(self, data):
if config.main["other_buffers"]["show_friends"] == True:
item = utils.find_item(data["target"]["id"], self.db.settings["friends"])
if item > 0:
deleted_event = event.event(event.EVT_DELETED, 1)
deleted_event.SetItem(item)
self.friends.pop(item)
self.db.settings["friends"].pop(item)
wx.PostEvent(self.parent.nb.GetPage(self.db.settings["buffers"].index("friends")), deleted_event)
def on_success(self, data):
try:
if "direct_message" in data:
self.process_dm(data)
elif "friends" in data:
self.friends = data["friends"]
elif "text" in data and utils.is_allowed(data) == True:
if data["user"]["id"] in self.muted_users: return
self.check_mentions(data)
self.check_send(data)
if data["user"]["id"] in self.friends or data["user"]["screen_name"] == self.db.settings["user_name"]:
tweet_event = event.event(event.EVT_OBJECT, 1)
tweet_event.SetItem(data)
wx.PostEvent(self.parent.nb.GetPage(self.db.settings["buffers"].index("home_timeline")), tweet_event)
elif data.has_key("event"):
if "favorite" == data["event"] and config.main["other_buffers"]["show_favourites"] == True:
self.check_favs(data)
elif "unfavorite" == data["event"] and config.main["other_buffers"]["show_favourites"] == True:
self.remove_fav(data)
elif "follow" == data["event"] and config.main["other_buffers"]["show_followers"] == True:
self.check_follower(data)
elif "unfollow" == data["event"] and config.main["other_buffers"]["show_followers"] == True:
self.remove_friend(data)
elif "block" == data["event"]:
self.block_user(data)
elif "unblock" in data["event"]:
self.unblock(data)
elif "list_created" == data["event"]:
item = utils.find_item(data["target_object"]["id"], self.db.settings["lists"])
if item != None: self.db.settings["lists"].append(data["target_object"])
elif "list_destroyed" == data["event"]:
item = utils.find_item(data["target_object"]["id"], self.db.settings["lists"])
if item != None: self.db.settings["lists"].pop(item)
self.parent.remove_list(data["target_object"]["id"])
elif "list_member_added" == data["event"] and data["source"]["screen_name"] == self.db.settings["user_name"]:
if len(config.main["other_buffers"]["lists"]) > 0:
for i in range(0, self.parent.nb.GetPageCount()):
if self.parent.nb.GetPage(i).type == "list":
if str(data["target_object"]["id"]) == str(self.parent.nb.GetPage(i).argumento):
self.parent.nb.GetPage(i).users.append(data["target"]["id"])
wx.PostEvent(self.parent, event.ResultEvent())
elif "list_member_added" == data["event"] and data["target"]["screen_name"] == self.db.settings["user_name"]:
self.db.settings["lists"].append(data["target_object"])
elif "list_member_removed" == data["event"] and data["source"]["screen_name"] == self.db.settings["user_name"]:
if len(config.main["other_buffers"]["lists"]) > 0:
for i in range(0, self.parent.nb.GetPageCount()):
if self.parent.nb.GetPage(i).type == "list":
if str(data["target_object"]["id"]) == str(self.parent.nb.GetPage(i).argumento):
self.parent.nb.GetPage(i).users.remove(data["target"]["id"])
wx.PostEvent(self.parent, event.ResultEvent())
elif "list_member_removed" == data["event"] and data["target"] == self.db.settings["user_name"]:
id = data["target_object"]["id"]
list = utils.find_item(id, self.db.settings["lists"])
if list != None: self.db.settings["lists"].pop(list)
self.parent.remove_list(data["target_object"]["id"])
if config.main["other_buffers"]["show_events"] == True:
evento = compose.compose_event(data, self.db.settings["user_name"])
tweet_event = event.event(event.EVT_OBJECT, 1)
tweet_event.SetItem(evento)
text = evento[1]
tweet_event.SetAnnounce(text)
# deleted_event = event.event(event.EVT_DELETED, 1)
# deleted_event.SetItem(evento)
wx.PostEvent(self.parent.nb.GetPage(self.db.settings["buffers"].index("events")), tweet_event)
# self.sound.play("new_event.ogg")
except:
pass

239
src/twitter/compose.py Normal file
View File

@@ -0,0 +1,239 @@
# -*- coding: utf-8 -*-
import utils
import re
import htmlentitydefs
import datetime
import time
import output
import gettext, paths, locale, gettext_windows
import config, languageHandler
if config.main != None:
languageHandler.setLanguage(config.main["general"]["language"])
else:
languageHandler.setLanguage("system")
import platform
system = platform.system()
def prettydate(d):
""" Converts a string to the relative time."""
diff = datetime.datetime.utcnow() - d
s = diff.seconds
if diff.days > 7 and diff.days < 14:
return _(u"About a week ago")
elif diff.days > 14 and diff.days < 31:
return _(u"About {} weeks ago").format(diff.days/7)
elif diff.days > 31 and diff.days <= 62:
return _(u"A month ago")
elif diff.days >62 and diff.days <= 365:
return _(u"About {} months ago").format(diff.days/30)
elif diff.days > 365 and diff.days <= 730:
return _(u"About a year ago")
elif diff.days > 730:
return _(u"About {} years ago").format(diff.days/365)
elif diff.days == 1:
return _(u"About 1 day ago")
elif diff.days > 1:
return _(u"About {} days ago").format(diff.days)
elif s <= 1:
return _(u"just now")
elif s < 60:
return _(u"{} seconds ago").format(s)
elif s < 120:
return _(u"1 minute ago")
elif s < 3600:
return _(u"{} minutes ago").format(s/60)
elif s < 7200:
return _(u"About 1 hour ago")
else:
return _(u"About {} hours ago").format(s/3600)
# Months, days, short_months and short_days are used to translate the string that Twitter gives to us with the date and time.
months = {
"January": _(u"January"),
"February": _(u"February"),
"March": _(u"March"),
"April": _(u"April"),
"May": _(u"May"),
"June": _(u"June"),
"July": _(u"July"),
"August": _(u"August"),
"September": _(u"September"),
"October": _(u"October"),
"November": _(u"November"),
"December": _(u"December"),
}
days = {"Sunday": _(u"Sunday"),
"Monday": _(u"Monday"),
"Tuesday": _(u"Tuesday"),
"Wednesday": _(u"Wednesday"),
"Thursday": _(u"Thursday"),
"Friday": _(u"Friday"),
"Saturday": _(u"Saturday")}
short_days = {
"Sun": _(u"sun"),
"Mon": _(u"mon"),
"Tue": _(u"tue"),
"Wed": _(u"wed"),
"Thu": _(u"thu"),
"Fri": _(u"fri"),
"Sat": _(u"sat")
}
short_months = {
"Jan": _(u"jan"),
"Feb": _(u"feb"),
"Mar": _(u"mar"),
"Apr": _(u"apr"),
"May": _(u"may"),
"Jun": _(u"jun"),
"Jul": _(u"jul"),
"Aug": _(u"aug"),
"Sep": _(u"sep"),
"Oct": _(u"oct"),
"Nov": _(u"nov"),
"Dec": _(u"dec")}
def StripChars(s):
"""Converts any html entities in s to their unicode-decoded equivalents and returns a string."""
entity_re = re.compile(r"&(#\d+|\w+);")
def matchFunc(match):
"""Nested function to handle a match object.
If we match &blah; and it's not found, &blah; will be returned.
if we match #\d+, unichr(digits) will be returned.
Else, a unicode string will be returned."""
if match.group(1).startswith('#'): return unichr(int(match.group(1)[1:]))
replacement = htmlentitydefs.entitydefs.get(match.group(1), "&%s;" % match.group(1))
return replacement.decode('iso-8859-1')
return unicode(entity_re.sub(matchFunc, s))
def translate(string):
""" Changes the days in English for the current language. Needed for Windows."""
if system != "Windows": return string
else:
global months, days
for d in months:
string = string.replace(d, months[d])
for d in days:
string = string.replace(d, days[d])
return string
def translate_short(string):
""" Changes the English date from Twitter to a local date and time. Needed for datetime on Linux."""
if system != "Linux": return string
else:
# if 1 == 1:
global short_months, short_days
for d in short_months:
string = string.replace(d, short_months[d])
for d in short_days:
string = string.replace(d, short_days[d])
return string
chars = "abcdefghijklmnopqrstuvwxyz"
def compose_tweet(tweet, db):
""" It receives a tweet and returns a list with the user, text for the tweet or message, date and the client where user is."""
# original_date = datetime.datetime.strptime(translate_short(tweet["created_at"]).encode("utf-8"), "%a %b %d %H:%M:%S +0000 %Y")
original_date = datetime.datetime.strptime(tweet["created_at"], "%a %b %d %H:%M:%S +0000 %Y")
# else:
# original_date = datetime.datetime.strptime(tweet["created_at"], '%a %b %d %H:%M:%S +0000 %Y')
date = original_date-datetime.timedelta(seconds=-db.settings["utc_offset"])
if config.main["general"]["relative_times"] == True:
ts = prettydate(original_date)
else:
# ts = translate(datetime.datetime.strftime(date, _("%A, %B %d, %Y at %I:%M:%S %p".encode("utf-8"))).decode("utf-8"))
ts = translate(datetime.datetime.strftime(date, _("%A, %B %d, %Y at %I:%M:%S %p")))
# ts = tweet["created_at"]
text = StripChars(tweet["text"])
if tweet.has_key("sender"):
source = "DM"
if db.settings["user_name"] == tweet["sender"]["screen_name"]: user = _(u"Dm to %s ") % (tweet["recipient"]["name"],)
else: user = tweet["sender"]["name"]
elif tweet.has_key("user"):
user = tweet["user"]["name"]
source = re.sub(r"(?s)<.*?>", " ", tweet["source"])
try: text = "rt @%s: %s" % (tweet["retweeted_status"]["user"]["screen_name"], StripChars(tweet["retweeted_status"]["text"]))
except KeyError: text = "%s" % (StripChars(tweet["text"]))
if text[-1] in chars: text=text+"."
urls = utils.find_urls_in_text(text)
for url in range(0, len(urls)):
try: text = text.replace(urls[url], tweet["entities"]["urls"][url]["expanded_url"])
except IndexError: pass
tweet["text"] = text
return [user+", ", tweet["text"], ts+", ", source]
def compose_followers_list(tweet, db):
# original_date = datetime.datetime.strptime(translate_short(tweet["created_at"]).encode("utf-8"), '%a %b %d %H:%M:%S +0000 %Y')
original_date = datetime.datetime.strptime(tweet["created_at"], '%a %b %d %H:%M:%S +0000 %Y')
date = original_date-datetime.timedelta(seconds=-db.settings["utc_offset"])
if config.main["general"]["relative_times"] == True:
ts = prettydate(original_date)
else:
ts = translate(datetime.datetime.strftime(date, _(u"%A, %B %d, %Y at %I:%M:%S %p")))
# ts = tweet["created_at"]
if tweet.has_key("status"):
if len(tweet["status"]) > 4:
# original_date2 = datetime.datetime.strptime(translate_short(tweet["status"]["created_at"]).encode("utf-8"), '%a %b %d %H:%M:%S +0000 %Y')
original_date2 = datetime.datetime.strptime(tweet["status"]["created_at"], '%a %b %d %H:%M:%S +0000 %Y')
date2 = original_date2-datetime.timedelta(seconds=-db.settings["utc_offset"])
if config.main["general"]["relative_times"]:
ts2 = prettydate(original_date2)
else:
ts2 = translate(datetime.datetime.strftime(date2, _(u"%A, %B %d, %Y at %I:%M:%S %p")))
else:
ts2 = _("Unavailable")
return [_(u"%s (@%s). %s followers, %s friends, %s tweets. Last tweet on %s. Joined Twitter on %s") % (tweet["name"], tweet["screen_name"], tweet["followers_count"], tweet["friends_count"], tweet["statuses_count"], ts2, ts)]
def compose_event(data, username):
if data["event"] == "block":
event = _("You've blocked %s") % (data["target"]["name"])
elif data["event"] == "unblock":
event = _(u"You've unblocked %s") % (data["target"]["name"])
elif data["event"] == "follow":
if data["target"]["screen_name"] == username:
event = _(u"%s(@%s) has followed you") % (data["source"]["name"], data["source"]["screen_name"])
elif data["source"]["screen_name"] == username:
event = _(u"You've followed %s(@%s)") % (data["target"]["name"], data["target"]["screen_name"])
elif data["event"] == "unfollow":
event = _(u"You've unfollowed %s (@%s)") % (data["target"]["name"], data["target"]["screen_name"])
elif data["event"] == "favorite":
if data["source"]["screen_name"] == username:
event = _(u"You've added to favourites: %s, %s") % (data["target"]["name"], data["target_object"]["text"])
else:
event = _(u"%s(@%s) has marked as favorite: %s") % (data["source"]["name"], data["source"]["screen_name"], data["target_object"]["text"])
elif data["event"] == "unfavorite":
if data["source"]["screen_name"] == username: event = _(u"You've removed from favourites: %s, %s") % (data["target"]["name"], data["target_object"]["text"])
else: event = _(u"%s(@%s) has removed from favourites: %s") % (data["source"]["name"], data["source"]["screen_name"], data["target_object"]["text"])
elif data["event"] == "list_created":
event = _(u"You've created the list %s") % (data["target_object"]["name"])
elif data["event"] == "list_destroyed":
event = _("You've deleted the list %s") % (data["target_object"]["name"])
elif data["event"] == "list_updated":
event = _("You've updated the list %s") % (data["target_object"]["name"])
elif data["event"] == "list_member_added":
if data["source"]["screen_name"] == username: event = _(u"You've added %s(@%s) to the list %s") % (data["target"]["name"], data["target"]["screen_name"], data["target_object"]["name"])
else: event = _(u"%s(@%s) has added you to the list %s") % (data["source"]["name"], data["source"]["screen_name"], data["target_object"]["name"])
elif data["event"] == "list_member_removed":
if data["source"]["screen_name"] == username: event = _(u"You'be removed %s(@%s) from the list %s") % (data["target"]["name"], data["target"]["screen_name"], data["target_object"]["name"])
else: event = _(u"%s(@%s) has removed you from the list %s") % (data["source"]["name"], data["source"]["screen_name"], data["target_object"]["name"])
elif data["event"] == "list_user_subscribed":
if data["source"]["screen_name"] == username: event = _(u"You've subscribed to the list %s, which is owned by %s(@%s)") % (data["target_object"]["name"], data["target"]["name"], data["target"]["screen_name"])
else: event = _(u"%s(@%s) has suscribed you to the list %s") % (data["source"]["name"], data["source"]["screen_name"], data["target_object"]["name"])
elif data["event"] == "list_user_unsubscribed":
if data["source"]["screen_name"] == username: event = _(u"You've unsubscribed from the list %s, which is owned by %s(@%s)") % (data["target_object"]["name"], data["target"]["name"], data["target"]["screen_name"])
else: event = _("You've been unsubscribed from the list %s, which is owned by %s(@%s)") % (data["target_object"]["name"], data["source"]["name"], data["source"]["screen_name"])
else: event = _("Unknown")
# output.speak(event)
return [time.strftime("%I:%M %p"), event]
def compose_list(list):
name = list["name"]
if list["description"] == None: description = _(u"No description available")
else: description = list["description"]
user = list["user"]["name"]
members = str(list["member_count"])
if list["mode"] == "private": status = _(u"private")
else: status = _(u"public")
return [name, description, user, members, status]

260
src/twitter/starting.py Normal file
View File

@@ -0,0 +1,260 @@
# -*- config: utf-8 -*-
from twython import Twython, TwythonError
import config
#import sound
import time
import utils
friends_cursor = followers_cursor = None
def get_more_items(update_function, twitter_object, users=False, name=None, *args, **kwargs):
results = []
data = update_function(*args, **kwargs)
if users == True:
global friends_cursor, followers_cursor
if name == "friends":
friends_cursor = data["next_cursor"]
elif name == "followers":
followers_cursor = data["next_cursor"]
for i in data["users"]: results.append(i)
else:
results.extend(data[1:])
if config.main["general"]["reverse_timelines"] == True: results.reverse()
return results
def call_paged(update_function, twitter_object, *args, **kwargs):
max = int(config.main["general"]["max_api_calls"])-1
results = []
data = update_function(*args, **kwargs)
results.extend(data)
for i in range(0, max):
if i == 0: max_id = results[-1]["id"]
else: max_id = results[0]["id"]
data = update_function(max_id=max_id, *args, **kwargs)
results.extend(data)
results.reverse()
return results
def start_user_info(config, twitter):
f = twitter.twitter.get_account_settings()
sn = f["screen_name"]
config.settings["user_name"] = sn
config.settings["user_id"] = twitter.twitter.show_user(screen_name=sn)["id_str"]
try:
config.settings["utc_offset"] = f["time_zone"]["utc_offset"]
except KeyError:
config.settings["utc_offset"] = -time.timezone
get_lists(config, twitter)
get_muted_users(config, twitter)
def get_lists(config, twitter):
config.settings["lists"] = twitter.twitter.show_lists(reverse=True)
def get_muted_users(config, twitter):
config.settings["muted_users"] = twitter.twitter.get_muted_users_ids()["ids"]
def start_stream(db, twitter, name, function, param=None):
num = 0
if db.settings.has_key(name):
try:
if db.settings[name][0]["id"] > db.settings[name][-1]["id"]:
last_id = db.settings[name][0]["id"]
else:
last_id = db.settings[name][-1]["id"]
except IndexError:
pass
if param != None:
tl = call_paged(function, twitter, sinze_id=last_id, screen_name=param, count=config.main["general"]["max_tweets_per_call"])
else:
tl = call_paged(function, twitter, sinze_id=last_id, count=config.main["general"]["max_tweets_per_call"])
else:
if param != None:
tl = call_paged(function, twitter, screen_name=param, count=config.main["general"]["max_tweets_per_call"])
else:
tl = call_paged(function, twitter, count=config.main["general"]["max_tweets_per_call"])
db.settings[name] = []
last_id = 0
if len(db.settings[name]) > 0:
for i in tl:
if int(i["id"]) > int(last_id):
if config.main["general"]["reverse_timelines"] == False: db.settings[name].append(i)
else: db.settings[name].insert(0, i)
num = num+1
elif len(db.settings[name]) == 0:
for i in tl:
if config.main["general"]["reverse_timelines"] == False: db.settings[name].append(i)
else: db.settings[name].insert(0, i)
num = num+1
# db.settings.update()
return num
def start_followers(db, twitter, name, function, param=None):
global friends_cursor, followers_cursor
num = 0
db.settings[name] = []
# next_cursor = -1
# while(next_cursor):
tl = function(screen_name=param, count=config.main["general"]["max_tweets_per_call"])
for i in tl['users']:
if config.main["general"]["reverse_timelines"] == False: db.settings[name].append(i)
else: db.settings[name].insert(0, i)
num = num+1
# next_cursor = tl["next_cursor"]
db.settings[name].reverse()
# if config.main["streams"]["reverse_timelines"] == True: db.settings[name].reverse()
if name == "followers": followers_cursor = tl["next_cursor"]
elif name == "friends": friends_cursor = tl["next_cursor"]
return num
def get_users_list(twitter, list_id):
answers = []
next_cursor = -1
while(next_cursor):
users = twitter.twitter.get_list_members(list_id=list_id, cursor=next_cursor, include_entities=False, skip_status=True)
for i in users['users']:
answers.append(i["id"])
next_cursor = users["next_cursor"]
return answers
def update_stream(config, twitter, name, function, param=None, sndFile=""):
num = 0
sounded = False
tl = function(sinze_id=config.settings[name][-1]["id"], screen_name=param, count=config.main["general"]["max_tweets_per_call"])
tl.reverse()
for i in tl:
if i["id"] > config.settings[name][-1]["id"]:
config.settings[name].append(i)
sounded = True
num = num+1
if sounded == True:
sound.play(sndFile)
return num
def start_sent(db, twitter, name, function, param=None):
num = 0
if db.settings.has_key(name):
try:
if db.settings[name][0]["id"] > db.settings[name][-1]["id"]:
last_id = db.settings[name][0]["id"]
else:
last_id = db.settings[name][-1]["id"]
except IndexError:
return 0
if param != None:
tl = function(sinze_id=last_id, screen_name=param, count=config.main["general"]["max_tweets_per_call"])
tl2 = twitter.twitter.get_sent_messages(sinze_id=last_id, count=config.main["general"]["max_tweets_per_call"])
else:
tl = function(sinze_id=last_id, count=config.main["general"]["max_tweets_per_call"])
tl2 = twitter.twitter.get_sent_messages(sinze_id=last_id, count=config.main["general"]["max_tweets_per_call"])
else:
if param != None:
tl = function(screen_name=param, count=config.main["general"]["max_tweets_per_call"])
tl2 = twitter.twitter.get_sent_messages(count=config.main["general"]["max_tweets_per_call"])
else:
tl = function(count=config.main["general"]["max_tweets_per_call"])
tl2 = twitter.twitter.get_sent_messages(sinze_id=last_id, count=config.main["general"]["max_tweets_per_call"])
db.settings[name] = []
last_id = 0
tl.extend(tl2)
# tl.reverse()
tl.sort(key=lambda tup: tup["id"])
if len(db.settings[name]) > 0:
for i in tl:
# print last_id, i["id"]
if int(i["id"]) > int(last_id):
if config.main["general"]["reverse_timelines"] == False: db.settings[name].append(i)
else: db.settings[name].insert(0, i)
num = num+1
elif len(db.settings[name]) == 0:
for i in tl:
if config.main["general"]["reverse_timelines"] == False: db.settings[name].append(i)
else: db.settings[name].insert(0, i)
num = num+1
return num
def start_list(db, twitter, name, list_id):
num = 0
if db.settings.has_key(name):
try:
if db.settings[name][0]["id"] > db.settings[name][-1]["id"]:
last_id = db.settings[name][0]["id"]
else:
last_id = db.settings[name][-1]["id"]
except IndexError:
pass
tl = twitter.twitter.get_list_statuses(list_id=list_id, count=200)
else:
tl = twitter.twitter.get_list_statuses(list_id=list_id, count=200)
tl.reverse()
db.settings[name] = []
last_id = 0
if len(db.settings[name]) > 0:
for i in tl:
if int(i["id"]) > int(last_id):
if config.main["general"]["reverse_timelines"] == False: db.settings[name].append(i)
else: db.settings[name].insert(0, i)
num = num+1
elif len(db.settings[name]) == 0:
for i in tl:
if config.main["general"]["reverse_timelines"] == False: db.settings[name].append(i)
else: db.settings[name].insert(0, i)
num = num+1
db.settings.update()
return num
def search(db, twitter, name, *args, **kwargs):
num = 0
if db.settings.has_key(name) == False:
db.settings[name] = []
tl = twitter.twitter.search(*args, **kwargs)
tl["statuses"].reverse()
if len(db.settings[name]) > 0:
for i in tl["statuses"]:
if utils.find_item(i["id"], db.settings[name]) == None:
if config.main["general"]["reverse_timelines"] == False: db.settings[name].append(i)
else: db.settings[name].insert(0, i)
num = num+1
elif len(db.settings[name]) == 0:
for i in tl["statuses"]:
if config.main["general"]["reverse_timelines"] == False: db.settings[name].append(i)
else: db.settings[name].insert(0, i)
num = num+1
return num
def search_users(db, twitter, name, *args, **kwargs):
num = 0
if db.settings.has_key(name) == False:
db.settings[name] = []
tl = twitter.twitter.search_users(*args, **kwargs)
tl.reverse()
if len(db.settings[name]) > 0:
for i in tl:
if utils.find_item(i["id"], db.settings[name]) == None:
if config.main["general"]["reverse_timelines"] == False: db.settings[name].append(i)
else: db.settings[name].insert(0, i)
num = num+1
elif len(db.settings[name]) == 0:
for i in tl:
if config.main["general"]["reverse_timelines"] == False: db.settings[name].append(i)
else: db.settings[name].insert(0, i)
num = num+1
return num
def get_favourites_timeline(db, twitter, name, param, *args, **kwargs):
num = 0
if db.settings.has_key(name) == False:
db.settings[name] = []
tl = twitter.twitter.get_favorites(screen_name=param, *args, **kwargs)
tl.reverse()
if len(db.settings[name]) > 0:
for i in tl:
if utils.find_item(i["id"], db.settings[name]) == None:
if config.main["general"]["reverse_timelines"] == False: db.settings[name].append(i)
else: db.settings[name].insert(0, i)
num = num+1
elif len(db.settings[name]) == 0:
for i in tl:
if config.main["general"]["reverse_timelines"] == False: db.settings[name].append(i)
else: db.settings[name].insert(0, i)
num = num+1
return num

83
src/twitter/twitter.py Normal file
View File

@@ -0,0 +1,83 @@
# -*- coding: utf-8 -*-
import BaseHTTPServer
import webbrowser
from urlparse import urlparse, parse_qs
from twython import Twython, TwythonError
import config
import application
import output
import sound
import time
logged = False
verifier = None
class handler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_GET(self):
global logged
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
logged = True
params = parse_qs(urlparse(self.path).query)
global verifier
verifier = params.get('oauth_verifier', [None])[0]
self.wfile.write("You have successfully logged in to Twitter with TW Blue. "
"You can close this window now.")
class twitter(object):
def login(self, user_key=None, user_secret=None):
if user_key != None and user_secret != None:
self.twitter = Twython(application.app_key, application.app_secret, user_key, user_secret)
elif config.main != None:
self.twitter = Twython(application.app_key, application.app_secret, config.main["twitter"]["user_key"], config.main["twitter"]["user_secret"])
else:
self.twitter = Twython(application.app_key, application.app_secret, self.final_step['oauth_token'], self.final_step['oauth_token_secret'])
self.credentials = self.twitter.verify_credentials()
def authorise(self):
httpd = BaseHTTPServer.HTTPServer(('127.0.0.1', 8080), handler)
twitter = Twython(application.app_key, application.app_secret)
auth = twitter.get_authentication_tokens("http://127.0.0.1:8080")
webbrowser.open_new_tab(auth['auth_url'])
global logged, verifier
while logged == False:
httpd.handle_request()
self.twitter = Twython(application.app_key, application.app_secret, auth['oauth_token'], auth['oauth_token_secret'])
final = self.twitter.get_authorized_tokens(verifier)
self.save_configuration(final["oauth_token"], final["oauth_token_secret"])
def save_configuration(self, user_key=None, user_secret=None):
if user_key != None and user_secret != None:
config.main["twitter"]["user_key"] = user_key
config.main["twitter"]["user_secret"] = user_secret
else:
config.main['twitter']['user_key'] = self.final_step['oauth_token']
config.main['twitter']['user_secret'] = self.final_step['oauth_token_secret']
config.main.write()
def api_call(self, call_name, action="", _sound=None, report_success=False, report_failure=True, preexec_message="", *args, **kwargs):
finished = False
tries = 0
if preexec_message:
output.speak(preexec_message, True)
while finished==False and tries < 25:
try:
val = getattr(self.twitter, call_name)(*args, **kwargs)
finished = True
except TwythonError as e:
# if hasattr(e, 'reason') and e.reason.startswith("Failed to send request"):
output.speak(e.message)
if report_failure and hasattr(e, 'message'):
output.speak(_("%s failed. Reason: %s") % (action, e.message))
finished = True
except:
tries = tries + 1
time.sleep(5)
# raise e
if report_success:
output.speak(_("%s succeeded.") % action)
if _sound != None: sound.player.play(_sound)
# return val

114
src/twitter/utils.py Normal file
View File

@@ -0,0 +1,114 @@
# -*- coding: utf-8 -*-
import url_shortener, re
""" Some utilities for the twitter interface."""
import output
from twython import TwythonError
import config
__version__ = 0.1
__doc__ = "Find urls in tweets and #audio hashtag."
url_re = re.compile(r"(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'\".,<>?«»“”‘’]))")
#"(?:\w+://|www\.)[^ ,.?!#%=+][^ ]*")
#bad_chars = '\'\\.,[](){}:;"'
url_re2 = re.compile("(?:\w+://|www\.)[^ ,.?!#%=+][^ ]*")
bad_chars = '\'\\.,[](){}:;"'
def find_urls_in_text(text):
return [s.strip(bad_chars) for s in url_re2.findall(text)]
def find_urls (tweet):
urls = []
# for i in tweet["entities"]["urls"]:
# unshortened = url_shortener.unshorten(i["expanded_url"])
# if unshortened == None:
# urls.append(i["expanded_url"])
# else:
# urls.append(unshortened)
# return urls
return [s[0] for s in url_re.findall(tweet["text"])]
def find_item(id, listItem):
for i in range(0, len(listItem)):
if listItem[i]["id"] == id: return i
return None
def find_list(name, lists):
for i in range(0, len(lists)):
if lists[i]["slug"] == name: return lists[i]["id"]
def find_previous_reply(id, listItem):
for i in range(0, len(listItem)):
if listItem[i]["id_str"] == str(id): return i
return None
def find_next_reply(id, listItem):
# r = range(0, len(listItem))
# r.reverse()
# for i in r:
for i in range(0, len(listItem)):
if listItem[i]["in_reply_to_status_id_str"] == str(id): return i
return None
def is_audio(tweet):
if len(tweet["entities"]["hashtags"]) > 0:
for i in tweet["entities"]["hashtags"]:
if i["text"] == "audio":
return True
return False
def get_all_mentioned(tweet, config):
""" Gets all users that has been mentioned."""
if tweet.has_key("retweeted_status"): tweet = tweet["retweeted_status"]
string = []
for i in tweet["entities"]["user_mentions"]:
if i["screen_name"] != config.settings["user_name"] and i["screen_name"] != tweet["user"]["screen_name"]:
if "@"+i["screen_name"] not in string:
string.append("@"+i["screen_name"])
return " ".join(string)+" "
def get_all_users(tweet, config):
string = []
if tweet.has_key("retweeted_status"):
string.append(tweet["user"]["screen_name"])
tweet = tweet["retweeted_status"]
if tweet.has_key("sender"):
string.append(tweet["sender"]["screen_name"])
else:
if tweet["user"]["screen_name"] != config.settings["user_name"]:
string.append(tweet["user"]["screen_name"])
for i in tweet["entities"]["user_mentions"]:
if i["screen_name"] != config.settings["user_name"] and i["screen_name"] != tweet["user"]["screen_name"]:
if i["screen_name"] not in string:
string.append(i["screen_name"])
if len(string) == 0:
string.append(tweet["user"]["screen_name"])
return string
def if_user_exists(twitter, user):
try:
data = twitter.show_user(screen_name=user)
return data["screen_name"]
except:
return None
def api_call(parent=None, call_name=None, preexec_message="", success="", success_snd="", *args, **kwargs):
if preexec_message:
output.speak(preexec_message, True)
try:
val = getattr(parent.twitter.twitter, call_name)(*args, **kwargs)
output.speak(success)
parent.parent.sound.play(success_snd)
except TwythonError as e:
output.speak("Error %s: %s" % (e.error_code, e.msg), True)
parent.parent.sound.play("error.wav")
return val
def is_allowed(tweet):
allowed = True
if tweet.has_key("retweeted_status"): tweet = tweet["retweeted_status"]
source = re.sub(r"(?s)<.*?>", "", tweet["source"])
for i in config.main["twitter"]["ignored_clients"]:
if i.lower() == source.lower(): allowed = False
return allowed