Exemplo n.º 1
0
    def on_response(self, session, msg, data):
        status = msg.status_code
        if not 200 <= status < 400:
            logger.error(
                'Subscriptions synchronization failed {0}'.format(status))
            return

        # Clear database, it's easier than updating everything ;)
        q = '; DELETE FROM '.join(('subscriptions', 'labels', 'labels_fk'))
        sqlite.executescript('DELETE FROM ' + q)
        res = json.loads(msg.response_body.data)['subscriptions']
        # Some items do not have htmlUrl
        for d in res:
            d.setdefault('htmlUrl')

        # Reinsert items
        q = '''INSERT INTO subscriptions(id, url, title)
               VALUES(:id, :htmlUrl, :title)'''
        sqlite.executemany(q, res)

        lid = lambda x: x['id'].split('/', 2)[-1]
        # Reinsert labels
        q = 'INSERT OR IGNORE INTO labels(id, name) VALUES (?, ?)'
        values = {(lid(l), l['label']) for s in res for l in s['categories']}
        sqlite.executemany(q, values)

        # Estabilish foreign keys via labels_fk
        q = 'INSERT INTO labels_fk(item_id, label_id) VALUES(?, ?)'
        values = ((s['id'], lid(l)) for s in res for l in s['categories'])
        sqlite.executemany(q, values)
        logger.debug('Subscriptions synchronization completed')
        GLib.idle_add(self.emit, 'sync-done')
Exemplo n.º 2
0
    def on_sync_ids(self, job, success):
        if not success:
            logger.error('Could not get data from SQLite')
            return

        if len(job.result) == 0:
            logger.debug('Items doesn\'t need synchronization')
            GLib.idle_add(self.emit, 'sync-done')
            return

        # Somewhy when streaming items and asking more than 512 returns 400.
        # Asking anything in between 250 and 512 returns exactly 250 items.
        chunks = split_chunks((('i', i) for i, in job.result), 250, ('', ''))
        # Asynchronous job queue for items parsing
        # We will, unless we have a bug, have only one synchronization at time
        # thus it is safe to initialize it like that.
        executor = JobExecutor()
        executor.start()

        uri = api_method('stream/items/contents')
        req_type = 'application/x-www-form-urlencoded'
        for chunk in chunks:
            self.sync_status += 1
            data = urlencode(chunk)
            message = self.auth.message('POST', uri)
            message.set_request(req_type, Soup.MemoryUse.COPY, data, len(data))
            session.queue_message(message, self.on_response, executor)
        self.connect('notify::sync-status', self.on_sync_status, executor)
Exemplo n.º 3
0
    def on_data(self, job, success, data):
        flag, st = data
        self.sync_status -= 1
        if not success:
            logger.error('Could not get data from SQLite correctly')
            return

        if not len(job.result) == 0:
            uri = api_method('edit-tag')
            req_type = 'application/x-www-form-urlencoded'

            post = (
                (
                    'r' if st else 'a',
                    flag,
                ),
                ('T', self.auth.edit_token),
            )
            chunks = split_chunks(job.result, 250, None)
            for chunk in chunks:
                iids, ids = zip(*filter(lambda x: x is not None, chunk))
                iids = tuple(zip(itertools.repeat('i'), iids))
                payload = urlencode(iids + post)
                msg = self.auth.message('POST', uri)
                msg.set_request(req_type, Soup.MemoryUse.COPY, payload,
                                len(payload))
                session.queue_message(msg, self.on_response, ids)
                self.sync_status += 1

        if self.sync_status == 0:
            # In case we didn't have any flags to synchronize
            logger.debug('There were no flags to synchronize')
            GLib.idle_add(self.emit, 'sync-done')
Exemplo n.º 4
0
 def __setitem__(self, key, value):
     logger.debug('{0} = {1}'.format(key, value))
     if key not in self.types:
         logger.error('Cannot set value, because we don\'t know type (it\'s'
                      ' not in self.types')
         return
     value = getattr(GLib.Variant, 'new_{0}'.format(self.types[key]))(value)
     self.set_value(key, value)
Exemplo n.º 5
0
 def on_token(self, session, message, data=None):
     status = message.status_code
     if not 200 <= status < 400:
         logger.error('Token request failed (HTTP {0})'.format(status))
     else:
         self.edit_token = message.response_body.data
         self.edit_token_expire = int(GLib.get_real_time() + 1.5E9) #µs
     self.status.update({'PROGRESS': False, 'OK': 200 <= status < 400})
     self.notify('status')
Exemplo n.º 6
0
    def on_response(self, session, message, executor):
        status = message.status_code
        if not 200 <= status < 400:
            logger.error('Items synchronization failed {0}'.format(status))
            return

        job = executor.submit(itemparse.process_items,
                              message.response_body.data)
        job.connect('finished', self.on_chunk_parsed, executor)
Exemplo n.º 7
0
 def on_navigate(self, frame, request, action, policy):
     policy.ignore()
     uri = action.get_original_uri()
     if frame is not self.get_main_frame():
         return True
     elif uri.startswith('file://'):
         return False
     elif not Gio.AppInfo.launch_default_for_uri(uri, None):
         logger.error('System could not open {0}'.format(uri))
     return True
Exemplo n.º 8
0
    def sync(self):
        if self.sync_status > 0:
            logger.error('Flags are already being synchronized')
            return False
        self.sync_status = 0
        query = 'SELECT item_id, id FROM flags WHERE flag=? AND remove=?'

        for flag, st in itertools.product(StateIds, [True, False]):
            self.sync_status += 1
            sqlite.execute(query, (flag, st)).connect('finished', self.on_data,
                                                      (flag, st))
Exemplo n.º 9
0
 def _on_item_status(self, column, value):
     item_view = self._builder.get_object('item-view')
     items = self._builder.get_object('items-view')
     item_id = item_view.item_id
     for row in items.main_model:
         if row[ItemsColumn.ID] == item_id:
             row[ItemsColumn.FORCE_VISIBLE] = True
             row[column] = value
             return
     logger.error(
         "Couldn't set status for item {0}, it doesn't exist".format(
             item_id))
Exemplo n.º 10
0
 def on_login(self, session, message, data):
     status = message.status_code
     if not 200 <= status < 400:
         logger.error('Authentication failed (HTTP {0})'.format(status))
         self.status.update({'OK': False, 'PROGRESS': False,
                             'BAD_CREDENTIALS': status == 403})
         self.notify('status')
     else: # Login was likely successful
         for line in message.response_body.data.splitlines():
             if line.startswith('Auth'):
                 self.login_token = line[5:]
                 message = self.message('GET', api_method('token'))
                 session.queue_message(message, self.on_token, None)
                 break
Exemplo n.º 11
0
    def on_response(self, session, message, data):
        self.sync_status -= 1
        if self.sync_status == 0:
            logger.debug('Flags synchronizaton completed')
            GLib.idle_add(self.emit, 'sync-done')

        status = message.status_code
        if not 200 <= status < 400:
            logger.error('Flags synchronizaton failed {0}'.format(status))
            return False

        data = ((i, ) for i in data)
        sqlite.executemany('DELETE FROM flags WHERE id=?', data)
        if self.sync_status == 0:
            sqlite.commit()
Exemplo n.º 12
0
    def sync(self):
        if self.sync_status.get('synchronizing', False):
            logger.error('IDs are already being synchronized')
            return False
        self.sync_status['synchronizing'] = True

        item_limit = settings.settings['cache-items']
        for name, state in self.states.items():
            getargs = state + [('n', item_limit)]
            url = api_method('stream/items/ids', getargs)
            msg = self.auth.message('GET', url)
            session.queue_message(msg, self.on_response, name)
        # Initially mark everything as deletable and unflag all items.
        # Laten in process items that are still important will be unmarked
        # and reflagged again.
        query = 'UPDATE items SET to_delete=1, unread=0, starred=0, to_sync=0'
        sqlite.execute(query)
Exemplo n.º 13
0
    def on_response(self, session, msg, data):
        status = msg.status_code
        if not 200 <= status < 400:
            logger.error('IDs synchronization failed: {0}'.format(status))
            return False

        res = json.loads(msg.response_body.data)['itemRefs']
        id_list = [(int(i['id']), ) for i in res]
        self.ensure_ids(id_list)
        self.set_sync_flag({
            'update_time': int(i['timestampUsec']),
            'id': int(i['id'])
        } for i in res)
        if data in ['unread', 'starred']:
            self.set_flag(data, id_list)

        self.sync_status[data] = True
        GLib.idle_add(self.notify, 'sync-status')
Exemplo n.º 14
0
    def set_item_label(self, vals, label_id, value):
        if vals[0] != SubscriptionType.SUBSCRIPTION:
            logger.error('Adding label to non-subscription!')
            return False

        uri = api_method('subscription/edit')
        req_type = 'application/x-www-form-urlencoded'
        label_id = 'user/-/{0}'.format(label_id)
        action = 'a' if value else 'r'
        item_id = split_id(vals[1])[1]
        data = urlencode({
            'T': self.auth.edit_token,
            's': item_id,
            'ac': 'edit',
            action: label_id
        })
        msg = self.auth.message('POST', uri)
        msg.set_request(req_type, Soup.MemoryUse.COPY, data, len(data))
        session.queue_message(msg, self.on_sub_edit, None)
Exemplo n.º 15
0
 def stored(source, result, data):
     if not Secret.password_store_finish(result):
         logger.error('Could not store password into keyring')
Exemplo n.º 16
0
 def on_quickadd(self, session, msg, data=None):
     if not 200 <= msg.status_code < 400:
         logger.error('Add request returned {0}'.format(msg.status_code))
         GLib.idle_add(self.emit, 'subscribed', False)
     res = json.loads(msg.response_body.data)
     GLib.idle_add(self.emit, 'subscribed', 'streamId' in res)
Exemplo n.º 17
0
 def on_sub_edit(self, session, msg, data=None):
     if not 200 <= msg.status_code < 400:
         logger.error('Edit request returned {0}'.format(msg.status_code))
         return False
     GLib.idle_add(self.emit, 'label-set', 200 <= msg.status_code < 400)