def test_rfc3339_decode(rfc3339_string, dt): parsed = Rfc3339().decode(rfc3339_string) assert parsed == dt assert parsed.tzinfo.utcoffset(parsed) == dt.tzinfo.utcoffset(parsed) utc_parsed = Rfc3339(prefer_utc=True).decode(rfc3339_string) assert utc_parsed == dt assert utc_parsed.tzinfo.utcoffset(parsed) == datetime.timedelta(0)
def read_all_entries(category_id='', feed_id=None): if feed_id: feed_ids = [feed_id] else: cursor = Cursor(category_id) feed_ids = [sub.feed_id for sub in cursor.recursive_subscriptions] try: codec = Rfc3339() last_updated = codec.decode(request.args.get('last_updated')) except: last_updated = None for feed_id in feed_ids: try: with get_stage() as stage: feed = stage.feeds[feed_id] for entry in feed.entries: if last_updated is None or entry.updated_at <= last_updated: entry.read = True stage.feeds[feed_id] = feed except KeyError: if feed_id: r = jsonify(error='feed-not-found', message='Given feed does not exist') r.status_code = 404 return r else: continue return jsonify()
def category_entries(category_id): cursor = Cursor(category_id) generator = None url_token, entry_after, read, starred = get_optional_args() if url_token: try: generator = get_entry_generator(url_token) except IteratorNotFound: pass else: url_token = text_type(now()) if not generator: subscriptions = cursor.recursive_subscriptions generator = CategoryEntryGenerator() if entry_after: id_after, time_after = decode_entry_after(entry_after) else: time_after = None id_after = None for subscription in subscriptions: try: with get_stage() as stage: feed = stage.feeds[subscription.feed_id] except KeyError: continue feed_title = text_type(feed.title) it = iter(feed.entries) feed_permalink = get_permalink(feed) child = FeedEntryGenerator(category_id, subscription.feed_id, feed_title, feed_permalink, it, now(), read, starred) generator.add(child) generator.set_generators(id_after, time_after) save_entry_generators(url_token, generator) tidy_generators_up() entries = generator.get_entries() if not entries or len(entries) < app.config['PAGE_SIZE']: next_url = None if not entries: remove_entry_generator(url_token) else: next_url = make_next_url( category_id, url_token, encode_entry_after(entries[-1]['entry_id'], entries[-1]['updated']), read, starred) # FIXME: use Entry.updated_at instead of from json data. codec = Rfc3339() last_updated_at = '' if len(entries) and not entry_after: last_updated_at = max(codec.decode(x['updated']) for x in entries).isoformat() return jsonify(title=category_id.split('/')[-1][1:] or app.config['ALLFEED'], entries=entries, read_url=url_for('read_all_entries', category_id=category_id, last_updated=last_updated_at, _external=True), next_url=next_url)
def test_rfc3339_with_white_spaces(): codec = Rfc3339() rfc_string = ''' 2003-12-13T18:30:02+01:00 ''' rfc_datetime = datetime.datetime(2003, 12, 13, 18, 30, 2, tzinfo=FixedOffset(60)) assert codec.decode(rfc_string) == rfc_datetime
def set_generators(self, entry_after, time_after): empty_generators = [] for generator in self.generators: while (not generator.entry or (time_after and generator.entry.updated_at > Rfc3339().decode(time_after)) or generator.skip_if_id(entry_after)): try: generator.find_next_entry() except StopIteration: empty_generators.append(generator) for generator in empty_generators: self.generators.remove(generator) self.sort_generators()
def get_entry_data(self): if not self.entry: raise StopIteration entry_permalink = get_permalink(self.entry) entry_data = { 'title': text_type(self.entry.title), 'entry_id': get_hash(self.entry.id), 'permalink': entry_permalink or None, 'updated': Rfc3339().encode(self.entry.updated_at.astimezone(utc)), 'read': bool(self.entry.read), 'starred': bool(self.entry.starred) } feed_data = { 'title': self.feed_title, 'permalink': self.feed_permalink or None } add_urls(entry_data, ['entry_url'], self.category_id, self.feed_id, get_hash(self.entry.id)) add_urls(feed_data, ['entries_url'], self.category_id, self.feed_id) entry_data['feed'] = feed_data return entry_data
def test_rfc3339_encode(rfc3339_string, dt): codec = Rfc3339() assert codec.encode(dt) == rfc3339_string assert (Rfc3339(prefer_utc=True).encode(dt) == codec.encode(dt.astimezone(utc)))
def entry_newer_than_timestamp(self, generator, time_after): return (time_after and generator.entry.updated_at > Rfc3339().decode(time_after))