Example #1
0
 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)
Example #2
0
 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)
Example #3
0
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()
Example #4
0
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()