kick off an update when subscribing to a new feed

This commit is contained in:
Kyle Mahan 2015-01-27 16:49:43 -08:00
parent 65667e6010
commit 24226ea0d8
6 changed files with 39 additions and 28 deletions

2
.gitignore vendored
View file

@ -1,2 +1,4 @@
*.css *.css
*.css.map *.css.map
*~
.sass-cache

View file

@ -7,7 +7,9 @@ CELERY_RESULT_SERIALIZER = 'json'
CELERY_ACCEPT_CONTENT = ['json'] CELERY_ACCEPT_CONTENT = ['json']
CELERYBEAT_SCHEDULE = { CELERYBEAT_SCHEDULE = {
'tick-every-5-minutes': { 'tick-every-5-minutes': {
'task': 'tasks.tick', 'task': 'woodwind.tasks.tick',
'schedule': datetime.timedelta(minutes=5), 'schedule': datetime.timedelta(seconds=30),
} }
} }
# recommended to disable if not using -- introduces a lot of complexity
CELERY_DISABLE_RATE_LIMITS = True

6
config.py.template Normal file
View file

@ -0,0 +1,6 @@
import os
class Config:
SECRET_KEY = 'super secret key'
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.getcwd() + '/db.sqlite'

View file

@ -1,30 +1,31 @@
from woodwind.extensions import db
from woodwind.models import Feed, Entry from woodwind.models import Feed, Entry
from config import Config
import celery import celery
import requests
import celery.utils.log import celery.utils.log
import feedparser import feedparser
import mf2py import mf2py
import mf2util import mf2util
import requests
import time import time
import urllib.parse import urllib.parse
import datetime import datetime
import sqlalchemy
import sqlalchemy.orm
UPDATE_INTERVAL = datetime.timedelta(hours=1) UPDATE_INTERVAL = datetime.timedelta(hours=1)
queue = celery.Celery('woodwind') app = celery.Celery('woodwind')
queue.config_from_object('celeryconfig') app.config_from_object('celeryconfig')
logger = celery.utils.log.get_task_logger(__name__) logger = celery.utils.log.get_task_logger(__name__)
engine = sqlalchemy.create_engine(Config.SQLALCHEMY_DATABASE_URI)
session = sqlalchemy.orm.Session(bind=engine)
@queue.task @app.task
def tick(): def tick():
now = datetime.datetime.utcnow() now = datetime.datetime.utcnow()
logger.debug('Tick {}'.format(now)) logger.debug('Tick {}'.format(now))
for feed in Feed.query.all(): for feed in session.query(Feed).all():
logger.debug('Feed {} last checked {}'.format( logger.debug('Feed {} last checked {}'.format(
feed, feed.last_checked)) feed, feed.last_checked))
if (not feed.last_checked if (not feed.last_checked
@ -32,9 +33,9 @@ def tick():
update_feed.delay(feed.id) update_feed.delay(feed.id)
@queue.task @app.task
def update_feed(feed_id): def update_feed(feed_id):
feed = Feed.query.get(feed_id) feed = session.query(Feed).get(feed_id)
logger.info('Updating {}'.format(feed)) logger.info('Updating {}'.format(feed))
new_entries = process_feed_for_new_entries(feed) new_entries = process_feed_for_new_entries(feed)
for entry in new_entries: for entry in new_entries:
@ -55,7 +56,7 @@ def process_feed_for_new_entries(feed):
feed.last_checked = now feed.last_checked = now
if result: if result:
feed.last_updated = now feed.last_updated = now
db.session.commit() session.commit()
def process_xml_feed_for_new_entries(feed): def process_xml_feed_for_new_entries(feed):
@ -70,7 +71,7 @@ def process_xml_feed_for_new_entries(feed):
default_author_photo = feed_props.get('logo') default_author_photo = feed_props.get('logo')
all_uids = [e.id or e.link for e in parsed.entries] all_uids = [e.id or e.link for e in parsed.entries]
preexisting = set(row[0] for row in db.session.query(Entry.uid) preexisting = set(row[0] for row in session.query(Entry.uid)
.filter(Entry.uid.in_(all_uids)) .filter(Entry.uid.in_(all_uids))
.filter(Entry.feed == feed)) .filter(Entry.feed == feed))
@ -118,8 +119,8 @@ def process_xml_feed_for_new_entries(feed):
author_photo=default_author_photo author_photo=default_author_photo
or fallback_photo(feed.origin)) or fallback_photo(feed.origin))
db.session.add(entry) session.add(entry)
db.session.commit() session.commit()
yield entry yield entry
@ -132,7 +133,7 @@ def process_html_feed_for_new_entries(feed):
hfeed = parsed.get('entries', []) hfeed = parsed.get('entries', [])
all_uids = [e.get('uid') or e.get('url') for e in hfeed] all_uids = [e.get('uid') or e.get('url') for e in hfeed]
preexisting = set(row[0] for row in db.session.query(Entry.uid) preexisting = set(row[0] for row in session.query(Entry.uid)
.filter(Entry.uid.in_(all_uids)) .filter(Entry.uid.in_(all_uids))
.filter(Entry.feed == feed)) .filter(Entry.feed == feed))
@ -161,8 +162,8 @@ def process_html_feed_for_new_entries(feed):
author_photo=hentry.get('author', {}).get('photo') author_photo=hentry.get('author', {}).get('photo')
or fallback_photo(feed.origin), or fallback_photo(feed.origin),
author_url=hentry.get('author', {}).get('url')) author_url=hentry.get('author', {}).get('url'))
db.session.add(entry) session.add(entry)
db.session.commit() session.commit()
logger.debug('saved entry: %s', entry.permalink) logger.debug('saved entry: %s', entry.permalink)
yield entry yield entry

View file

@ -1,7 +1,7 @@
{% extends "base.jinja2" %} {% extends "base.jinja2" %}
{% block body %} {% block body %}
<main> <main>
<form action="{{ url_for('subscribe') }}" method="POST"> <form method="POST">
<input type="text" id="origin" name="origin" placeholder="Feed URL" /> <input type="text" id="origin" name="origin" placeholder="Feed URL" />
<button type="submit" id="subscribe">Subscribe</button> <button type="submit" id="subscribe">Subscribe</button>
</form> </form>

View file

@ -15,6 +15,9 @@ ui = flask.Blueprint('ui', __name__)
@ui.route('/') @ui.route('/')
def index(): def index():
import os
print('cwd', os.getcwd(), 'db', db)
if flask_login.current_user.is_authenticated(): if flask_login.current_user.is_authenticated():
feed_ids = [f.id for f in flask_login.current_user.feeds] feed_ids = [f.id for f in flask_login.current_user.feeds]
entries = Entry.query.filter( entries = Entry.query.filter(
@ -149,28 +152,25 @@ def subscribe():
def add_subscription(origin, feed, type): def add_subscription(origin, feed, type):
feed = None
if type == 'html': if type == 'html':
parsed = mf2util.interpret_feed(mf2py.parse(url=feed), feed) parsed = mf2util.interpret_feed(mf2py.parse(url=feed), feed)
name = parsed.get('name') name = parsed.get('name')
if not name or len(name) > 140: if not name or len(name) > 140:
p = urllib.parse.urlparse(origin) p = urllib.parse.urlparse(origin)
name = p.netloc + p.path name = p.netloc + p.path
feed = Feed(user=flask_login.current_user, name=name, feed = Feed(user=flask_login.current_user, name=name,
origin=origin, feed=feed, type=type) origin=origin, feed=feed, type=type)
db.session.add(feed)
db.session.commit()
return feed
elif type == 'xml': elif type == 'xml':
parsed = feedparser.parse(feed) parsed = feedparser.parse(feed)
feed = Feed(user=flask_login.current_user, feed = Feed(user=flask_login.current_user,
name=parsed.feed.title, origin=origin, feed=feed, name=parsed.feed.title, origin=origin, feed=feed,
type=type) type=type)
if feed:
db.session.add(feed) db.session.add(feed)
db.session.commit() db.session.commit()
# go ahead and update the fed
tasks.update_feed.delay(feed.id)
return feed return feed