2010-04-07 03:05:51 +00:00
|
|
|
#!/usr/bin/python
|
|
|
|
#
|
|
|
|
# Custom twitter client... mostly for learning Python
|
|
|
|
|
2010-04-07 19:54:54 +00:00
|
|
|
import sys, twitter, Tkinter, Pmw, ConfigParser, os, tkMessageBox
|
2010-04-07 03:05:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
class TwitWindow:
|
|
|
|
|
|
|
|
""" Display Tweets, post to twitter """
|
|
|
|
|
|
|
|
def __init__(self):
|
2010-04-07 17:17:21 +00:00
|
|
|
config = ConfigParser.ConfigParser()
|
|
|
|
config.read(os.path.expanduser("~/.mytwitter"))
|
|
|
|
self.username = config.get('global', 'username')
|
|
|
|
self.password = config.get('global', 'password')
|
2010-04-07 18:47:16 +00:00
|
|
|
self.num_entries = int(config.get('global', 'entries'))
|
|
|
|
self.refresh_time = int(config.get('global', 'refreshtime'))
|
2010-04-07 03:05:51 +00:00
|
|
|
|
|
|
|
self.labels = []
|
|
|
|
self.texts = []
|
|
|
|
|
|
|
|
|
|
|
|
def create_window(self):
|
|
|
|
self.tkroot = Tkinter.Tk()
|
|
|
|
self.tkroot.title("MyTwitter")
|
|
|
|
Pmw.initialise(self.tkroot)
|
2010-04-07 18:41:19 +00:00
|
|
|
self.tkroot.grid_columnconfigure(0, weight=1)
|
2010-04-07 03:05:51 +00:00
|
|
|
|
|
|
|
# Create the scrolled frame that will hold the tweets
|
|
|
|
self.tweet_view = Pmw.ScrolledFrame(self.tkroot, hscrollmode='none', horizflex='elastic')
|
2010-04-07 18:41:19 +00:00
|
|
|
self.tweet_view.grid(row=0)
|
2010-04-07 17:21:55 +00:00
|
|
|
|
2010-04-07 03:05:51 +00:00
|
|
|
# Create labels and text widgets
|
|
|
|
for i in range(0, self.num_entries):
|
|
|
|
self.labels.append(Tkinter.Label(self.tweet_view.interior()))
|
|
|
|
self.labels[i].pack(expand=False, fill=Tkinter.X)
|
2010-04-07 18:07:26 +00:00
|
|
|
self.texts.append(Tkinter.Label(self.tweet_view.interior()))
|
2010-04-07 03:05:51 +00:00
|
|
|
self.texts[i].pack(expand=False, fill=Tkinter.X)
|
2010-04-07 18:07:26 +00:00
|
|
|
self.labels[i].config(bg="#07c", fg="white", anchor=Tkinter.W)
|
|
|
|
self.texts[i].config(bg="#eff", fg="black", height=3, anchor=Tkinter.NW, justify=Tkinter.LEFT, wraplength=375)
|
2010-04-07 03:05:51 +00:00
|
|
|
|
2010-04-07 18:41:19 +00:00
|
|
|
# A button to refresh manually
|
|
|
|
self.button_box = Tkinter.Frame(self.tkroot)
|
|
|
|
self.button_box.grid(row=1, sticky=Tkinter.W)
|
|
|
|
self.refresh_button = Tkinter.Button(self.button_box, text="Refresh", command=self.update_window)
|
|
|
|
self.refresh_button.grid(row=0, sticky=Tkinter.W)
|
|
|
|
|
2010-04-07 03:05:51 +00:00
|
|
|
# Create an update box at the bottom of the window
|
|
|
|
self.update_box = Tkinter.Frame(self.tkroot)
|
2010-04-07 18:41:19 +00:00
|
|
|
self.update_box.grid(row=2, sticky=Tkinter.W)
|
2010-04-07 03:05:51 +00:00
|
|
|
self.update_entry = Tkinter.Entry(self.update_box)
|
2010-04-07 18:41:19 +00:00
|
|
|
self.update_entry.grid(row=0, sticky=Tkinter.W)
|
|
|
|
self.update_box.grid_columnconfigure(0, weight=1)
|
2010-04-07 03:05:51 +00:00
|
|
|
self.update_button = Tkinter.Button(self.update_box, text="Update", command=self.update_status)
|
2010-04-07 18:41:19 +00:00
|
|
|
self.update_button.grid(row=0, column=1, sticky=Tkinter.W)
|
2010-04-07 19:54:54 +00:00
|
|
|
self.update_count = Tkinter.Label(self.update_box, text="0/140")
|
|
|
|
self.update_count.grid(row=0, column=2, sticky=Tkinter.E)
|
2010-04-07 03:05:51 +00:00
|
|
|
|
2010-04-07 18:17:57 +00:00
|
|
|
### Set up bindings
|
|
|
|
|
2010-04-07 19:54:54 +00:00
|
|
|
# Bind scrollwheel to move the tweets, as well as page up/down
|
|
|
|
self.tkroot.bind_all("<Button-4>", self.scroll_wheel);
|
|
|
|
self.tkroot.bind_all("<Button-5>", self.scroll_wheel);
|
|
|
|
self.tkroot.bind_all("<Prior>", self.page_up);
|
|
|
|
self.tkroot.bind_all("<Next>", self.page_down);
|
2010-04-07 18:17:57 +00:00
|
|
|
|
2010-04-07 19:54:54 +00:00
|
|
|
# Bind any key in the update_entry to adjust the counter, except return
|
|
|
|
self.update_entry.bind('<KeyRelease>', self.char_counter)
|
2010-04-07 18:17:57 +00:00
|
|
|
self.update_entry.bind('<Return>', self.update_status_callback)
|
|
|
|
|
|
|
|
|
2010-04-07 03:05:51 +00:00
|
|
|
# Init the twitter API and start up the main loop
|
|
|
|
self.api = twitter.Api(username=self.username, password=self.password)
|
|
|
|
self.update_window()
|
|
|
|
self.tkroot.mainloop()
|
|
|
|
|
|
|
|
|
|
|
|
def update_window(self) :
|
2010-04-07 18:47:16 +00:00
|
|
|
statuses = self.api.GetFriendsTimeline(self.username, count=self.num_entries)
|
2010-04-07 03:05:51 +00:00
|
|
|
for i in range(0, self.num_entries):
|
|
|
|
if i < len(statuses):
|
|
|
|
# Update the label with the user's name and screen name
|
|
|
|
user = statuses[i].user
|
2010-04-07 19:01:05 +00:00
|
|
|
labeltext = user.name + " (" + user.screen_name + ") " + statuses[i].created_at
|
2010-04-07 03:05:51 +00:00
|
|
|
self.labels[i].config(text=labeltext)
|
|
|
|
|
|
|
|
# Display the text of the tweet
|
2010-04-07 18:07:26 +00:00
|
|
|
self.texts[i].config(text=statuses[i].text)
|
2010-04-07 03:05:51 +00:00
|
|
|
|
2010-04-07 18:47:16 +00:00
|
|
|
self.timer = self.tkroot.after(self.refresh_time * 1000, self.update_window)
|
2010-04-07 03:05:51 +00:00
|
|
|
|
|
|
|
|
2010-04-07 18:17:57 +00:00
|
|
|
|
|
|
|
def update_status(self):
|
2010-04-07 18:07:26 +00:00
|
|
|
text = self.update_entry.get()
|
2010-04-07 19:54:54 +00:00
|
|
|
if len(text) > 140:
|
|
|
|
tkMessageBox.showerror('Tweet too long', 'Tweets can only be 140 characters. Write a shorter tweet and try again.')
|
|
|
|
return
|
2010-04-07 03:05:51 +00:00
|
|
|
self.update_entry.delete(0, Tkinter.END)
|
|
|
|
self.api.PostUpdate(text)
|
2010-04-07 18:07:26 +00:00
|
|
|
self.update_window()
|
2010-04-07 18:17:57 +00:00
|
|
|
|
|
|
|
|
|
|
|
# Just calls update_status, here so that things
|
|
|
|
# that pass an event can be used
|
|
|
|
def update_status_callback(self, event):
|
|
|
|
self.update_status()
|
2010-04-07 18:07:26 +00:00
|
|
|
|
2010-04-07 03:05:51 +00:00
|
|
|
|
|
|
|
def scroll_wheel(self, event):
|
2010-04-07 17:07:26 +00:00
|
|
|
if event.num == 4:
|
2010-04-07 17:21:55 +00:00
|
|
|
self.tweet_view.yview('scroll', -5, 'units');
|
2010-04-07 17:07:26 +00:00
|
|
|
if event.num == 5:
|
2010-04-07 17:21:55 +00:00
|
|
|
self.tweet_view.yview('scroll', 5, 'units');
|
2010-04-07 17:07:26 +00:00
|
|
|
|
2010-04-07 03:05:51 +00:00
|
|
|
|
2010-04-07 18:17:57 +00:00
|
|
|
def page_up(self, event):
|
|
|
|
self.tweet_view.yview('scroll', -15, 'units');
|
|
|
|
|
2010-04-07 19:54:54 +00:00
|
|
|
|
2010-04-07 18:17:57 +00:00
|
|
|
def page_down(self, event):
|
|
|
|
self.tweet_view.yview('scroll', 15, 'units');
|
|
|
|
|
2010-04-07 19:54:54 +00:00
|
|
|
|
|
|
|
def char_counter(self, event):
|
|
|
|
new_count = str(len(self.update_entry.get())) + "/140"
|
|
|
|
self.update_count.config(text=new_count)
|
|
|
|
|
2010-04-07 03:05:51 +00:00
|
|
|
### end class TwitWindow
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def print_lists():
|
|
|
|
data = api.GetUserLists()
|
|
|
|
for l in data['lists']:
|
|
|
|
print l.name
|
|
|
|
|
|
|
|
def print_statuses_list():
|
|
|
|
statuses = api.GetListStatuses(sys.argv[2])
|
|
|
|
print_formatted(statuses)
|
|
|
|
|
|
|
|
def print_statuses():
|
|
|
|
statuses = api.GetFriendsTimeline(username)
|
|
|
|
print_formatted(statuses)
|
|
|
|
|
|
|
|
def print_formatted(statuses):
|
|
|
|
for s in statuses:
|
|
|
|
print s.user.name.encode("utf-8"), "(", s.user.screen_name, ") :"
|
|
|
|
print s.text.encode("utf-8")
|
|
|
|
print
|
|
|
|
|
|
|
|
|
|
|
|
# main
|
|
|
|
win = TwitWindow()
|
|
|
|
win.create_window()
|