155 lines
4.4 KiB
Python
155 lines
4.4 KiB
Python
#!/usr/bin/env python
|
|
|
|
|
|
# Standard library imports
|
|
import logging
|
|
import os
|
|
import threading
|
|
import urllib
|
|
|
|
|
|
# PyGTK imports
|
|
import pygtk
|
|
pygtk.require('2.0')
|
|
import gtk
|
|
import gtk.gdk
|
|
import gobject
|
|
import pango
|
|
|
|
# TweepyDeck imports
|
|
from TweepyDeck import bases
|
|
from TweepyDeck import notify
|
|
from TweepyDeck import signals
|
|
from TweepyDeck import views
|
|
from TweepyDeck import util
|
|
|
|
INTERVAL = 120
|
|
|
|
class Timeline(bases.BaseChildWidget):
|
|
api = None
|
|
since_id = None
|
|
timeline = 'statuses/home_timeline.json'
|
|
name = 'Home timeline'
|
|
users = None
|
|
rows = None
|
|
rendered = False
|
|
parent = None
|
|
timeline_widget = None
|
|
run = True
|
|
can_close = False
|
|
|
|
def __init__(self, api, **kwargs):
|
|
super(Timeline, self).__init__(**kwargs)
|
|
self.api = api
|
|
self.users = set()
|
|
self.rows = []
|
|
|
|
def start(self):
|
|
self.reset_timer()
|
|
|
|
def stop(self):
|
|
self.run = False
|
|
|
|
def reset_timer(self):
|
|
gobject.timeout_add_seconds(1, self._timerCallback)
|
|
|
|
def _timerCallback(self, **kwargs):
|
|
if not self.run:
|
|
return False
|
|
self.api.timeline(timeline=self.timeline, since_id=self.since_id,
|
|
callback=self._timerUpdatedCallback)
|
|
return False
|
|
|
|
def _grabNecessities(self, status):
|
|
return status['user']['screen_name'], status['created_at'], status['user']['profile_image_url']
|
|
|
|
def destroy(self, **kwargs):
|
|
self.stop()
|
|
if not self.scrolled_window:
|
|
return
|
|
self.scrolled_window.destroy()
|
|
|
|
def renderTo(self, parent, start=False):
|
|
self.scrolled_window = gtk.ScrolledWindow()
|
|
self.scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
|
self.scrolled_window.show()
|
|
parent.pack_start(self.scrolled_window)
|
|
|
|
self.viewport = gtk.Viewport()
|
|
self.viewport.show()
|
|
self.scrolled_window.add(self.viewport)
|
|
|
|
self.timeline_widget = gtk.VBox()
|
|
self.timeline_widget.show()
|
|
self.timeline_widget.set_homogeneous(False)
|
|
self.viewport.add(self.timeline_widget)
|
|
|
|
def _timerUpdatedCallback(self, data, **kwargs):
|
|
signals.emit(signals.PROGRESS_STOP)
|
|
if not self.rendered:
|
|
self.renderTo(self.parent)
|
|
self.rendered = True
|
|
|
|
odd = True
|
|
try:
|
|
if data:
|
|
logging.debug('_timerUpdatedCallback [%s], # items: %s' % (self.timeline, len(data)))
|
|
|
|
notify.notify('%s updated' % self.name,
|
|
'%d new tweets :)' % len(data), None)
|
|
self.since_id = data[0]['id']
|
|
data.reverse()
|
|
|
|
for i, status in enumerate(data):
|
|
what = status['text']
|
|
|
|
# *Very* crude dupe checking
|
|
if i > 0:
|
|
prev = data[i-1]
|
|
if prev['text'] == what:
|
|
continue
|
|
|
|
renderer = None
|
|
for view in util.get_global('views'):
|
|
if not view.matchForText(status):
|
|
continue
|
|
renderer = view
|
|
break
|
|
|
|
logging.debug('rendering %s with %s' % (status['id'], renderer))
|
|
|
|
if not renderer:
|
|
continue
|
|
|
|
row = renderer.rowForText(status)
|
|
self.users.add(row.who)
|
|
self.rows.insert(0, row)
|
|
row.renderTo(self.timeline_widget)
|
|
finally:
|
|
gobject.timeout_add_seconds(INTERVAL, self._timerCallback)
|
|
|
|
|
|
class RepliesTimeline(Timeline):
|
|
timeline = 'statuses/mentions.json'
|
|
name = 'Replies timeline'
|
|
|
|
class SearchesTimeline(Timeline):
|
|
timeline = 'search.json'
|
|
term = None
|
|
count = 30
|
|
can_close = True
|
|
name = property(fget=lambda s: '%s timeline' % s.term)
|
|
|
|
def _grabNecessities(self, status):
|
|
return status['from_user'], status['created_at'], status['profile_image_url']
|
|
|
|
def _timerCallback(self, **kwargs):
|
|
if not self.term:
|
|
return False
|
|
args = {'q' : self.term}
|
|
timeline = '%s?%s' % (self.timeline, urllib.urlencode(args))
|
|
self.api.timeline(timeline=timeline, since_id=self.since_id,
|
|
callback=self._timerUpdatedCallback, count=self.count)
|
|
return False
|
|
|