def __init__(self, proto): self.proto = proto self.updater = None self.entry_cb = CallbackList() self.errbacks = CallbackList() self.raw_errbacks = CallbackList() self.continue_refreshing = False self.next_refresh = None self.loading = False self._last_id = None self._error_handler = ErrorThrottler(self.report_error)
def __init__(self, proto): self.proto = proto self.updater = None self.entry_cb = CallbackList() self.errbacks = CallbackList() self.raw_errbacks = CallbackList() self.continue_refreshing = False self.next_refresh = None self.loading = False self._last_id = None self._error_handler = ErrorThrottler(self.report_error)
class TwitterFeed: def __init__(self, proto): self.proto = proto self.updater = None self.entry_cb = CallbackList() self.errbacks = CallbackList() self.raw_errbacks = CallbackList() self.continue_refreshing = False self.next_refresh = None self.loading = False self._last_id = None self._error_handler = ErrorThrottler(self.report_error) def _last_id_var(self): return self.LAST_ID_VAR def update_last_id(self, last_id): self._last_id = last_id self.proto.set_user_var(self._last_id_var(), last_id) @property def last_id(self): if self._last_id is None: self._last_id = self.proto.user_var(self._last_id_var()) return self._last_id def addEntryCallback(self, *args, **kwargs): """Add a callback for new entries""" self.entry_cb.addCallback(*args, **kwargs) def addErrback(self, *args, **kwargs): """Add a callbck for loading errors""" self.errbacks.addCallback(*args, **kwargs) def addRawErrback(self, *args, **kwargs): """Add a "raw" error callback, without error throttling""" self.raw_errbacks.addCallback(*args, **kwargs) @property def api(self): return self.proto.api @property def scheduler(self): return self.proto.scheduler def refresh_resched(self): if self.updater is not None: self.updater.resched() def _refresh(self, last_id=None): if last_id is None: last_id = self.last_id entries = [] d = defer.Deferred() def doit(): args = {} if last_id: args['since_id'] = last_id args['count'] = str(QUERY_COUNT) return self._timeline(got_entry, args).addCallbacks(finished, error) dbg("_refresh returning") def error(e): dbg("_refresh error %r", e) return e # store the entries and then show them in chronological order: def got_entry(e): dbg("got an entry") entries.insert(0, e) def finished(*args): dbg("finished loading %r" % (args,)) # tell the error throttler that things are ok, now: self._error_handler.ok() for e in entries: self.entry_cb.callback(e) if self.last_id is None or int(e.id) > int(self.last_id): self.update_last_id(e.id) return len(entries) return doit() def report_error(self, e): """Send an error message back to interested parties""" self.errbacks.callback(e) def refresh(self): def doit(): if self.loading: dbg("Won't refresh now. Still loading...") return self.loading = True self._refresh().addCallbacks(done, error).addBoth(resched) def error(e): dbg("ERROR while refreshing") self.raw_errbacks.callback(e) self._error_handler.error(e.value) return e def done(num_entries): dbg("got %d entries." % (num_entries)) def resched(*args): self.loading = False dbg("rescheduling... [%r]", args) self.refresh_resched() return doit() def stop_refreshing(self): if self.updater is not None: self.updater.destroy() self.updater = None def start_refreshing(self): if self.updater is None: self.updater = self.scheduler.new_updater(self.refresh) # yes, this is cheating, but I don't want to make the user wait for # too long #FIXME: just add support for 'one-shot lower-latency' calls on # the scheduler, instead of cheating self.refresh()
class TwitterFeed: def __init__(self, proto): self.proto = proto self.updater = None self.entry_cb = CallbackList() self.errbacks = CallbackList() self.raw_errbacks = CallbackList() self.continue_refreshing = False self.next_refresh = None self.loading = False self._last_id = None self._error_handler = ErrorThrottler(self.report_error) def _last_id_var(self): return self.LAST_ID_VAR def update_last_id(self, last_id): self._last_id = last_id self.proto.set_user_var(self._last_id_var(), last_id) @property def last_id(self): if self._last_id is None: self._last_id = self.proto.user_var(self._last_id_var()) return self._last_id def addEntryCallback(self, *args, **kwargs): """Add a callback for new entries""" self.entry_cb.addCallback(*args, **kwargs) def addErrback(self, *args, **kwargs): """Add a callbck for loading errors""" self.errbacks.addCallback(*args, **kwargs) def addRawErrback(self, *args, **kwargs): """Add a "raw" error callback, without error throttling""" self.raw_errbacks.addCallback(*args, **kwargs) @property def api(self): return self.proto.api @property def scheduler(self): return self.proto.scheduler def refresh_resched(self): if self.updater is not None: self.updater.resched() def _refresh(self, last_id=None): if last_id is None: last_id = self.last_id entries = [] d = defer.Deferred() def doit(): args = {} if last_id: args['since_id'] = last_id args['count'] = str(QUERY_COUNT) return self._timeline(got_entry, args).addCallbacks(finished, error) dbg("_refresh returning") def error(e): dbg("_refresh error %r", e) return e # store the entries and then show them in chronological order: def got_entry(e): dbg("got an entry") entries.insert(0, e) def finished(*args): dbg("finished loading %r" % (args, )) # tell the error throttler that things are ok, now: self._error_handler.ok() for e in entries: self.entry_cb.callback(e) if self.last_id is None or int(e.id) > int(self.last_id): self.update_last_id(e.id) return len(entries) return doit() def report_error(self, e): """Send an error message back to interested parties""" self.errbacks.callback(e) def refresh(self): def doit(): if self.loading: dbg("Won't refresh now. Still loading...") return self.loading = True self._refresh().addCallbacks(done, error).addBoth(resched) def error(e): dbg("ERROR while refreshing") self.raw_errbacks.callback(e) self._error_handler.error(e.value) return e def done(num_entries): dbg("got %d entries." % (num_entries)) def resched(*args): self.loading = False dbg("rescheduling... [%r]", args) self.refresh_resched() return doit() def stop_refreshing(self): if self.updater is not None: self.updater.destroy() self.updater = None def start_refreshing(self): if self.updater is None: self.updater = self.scheduler.new_updater(self.refresh) # yes, this is cheating, but I don't want to make the user wait for # too long #FIXME: just add support for 'one-shot lower-latency' calls on # the scheduler, instead of cheating self.refresh()