kick off an update when subscribing to a new feed
This commit is contained in:
parent
65667e6010
commit
24226ea0d8
6 changed files with 39 additions and 28 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,2 +1,4 @@
|
||||||
*.css
|
*.css
|
||||||
*.css.map
|
*.css.map
|
||||||
|
*~
|
||||||
|
.sass-cache
|
|
@ -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
6
config.py.template
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
SECRET_KEY = 'super secret key'
|
||||||
|
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.getcwd() + '/db.sqlite'
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue