query individual feeds by their url rather than id

prevent nefarious people like @dissolve from crawling all the
subscribed feeds :P
This commit is contained in:
Kyle Mahan 2015-02-09 22:46:02 -08:00
parent 19180b1829
commit 32cdeaa781
8 changed files with 42 additions and 23 deletions

3
fabfile.py vendored
View file

@ -24,8 +24,7 @@ def restart():
with cd(REMOTE_PATH): with cd(REMOTE_PATH):
with prefix("source venv/bin/activate"): with prefix("source venv/bin/activate"):
run("pip install -r requirements.txt") run("pip install -r requirements.txt")
# run("uwsgi --reload /tmp/redwind.pid") run("supervisorctl restart ww:*")
run("supervisorctl restart woodwind woodwind-celery")
def deploy(): def deploy():

View file

@ -1,5 +1,6 @@
import bleach import bleach
import json import json
import binascii
from .extensions import db from .extensions import db
@ -85,6 +86,9 @@ class Feed(db.Model):
last_checked = db.Column(db.DateTime) last_checked = db.Column(db.DateTime)
etag = db.Column(db.String(512)) etag = db.Column(db.String(512))
def get_feed_code(self):
return binascii.hexlify(self.feed.encode())
def __repr__(self): def __repr__(self):
return '<Feed:{},{}>'.format(self.name, self.feed) return '<Feed:{},{}>'.format(self.name, self.feed)

View file

@ -403,6 +403,8 @@ article {
article header img { article header img {
max-width: 64px; max-width: 64px;
max-height: 64px; max-height: 64px;
min-width: 48px;
min-height: 48px;
margin-left: -85px; margin-left: -85px;
float: left; float: left;
border-radius: 4px; } border-radius: 4px; }
@ -454,6 +456,8 @@ form {
margin: inherit; margin: inherit;
display: inline; display: inline;
max-width: 1.2em; max-width: 1.2em;
max-height: 1.2em; } } max-height: 1.2em;
min-width: inherit;
min-height: inherit; } }
/*# sourceMappingURL=style.css.map */ /*# sourceMappingURL=style.css.map */

View file

@ -1,6 +1,6 @@
{ {
"version": 3, "version": 3,
"mappings": "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", "mappings": "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",
"sources": ["normalize.scss","style.scss"], "sources": ["normalize.scss","style.scss"],
"names": [], "names": [],
"file": "style.css" "file": "style.css"

View file

@ -70,6 +70,8 @@ article {
img { img {
max-width: 64px; max-width: 64px;
max-height: 64px; max-height: 64px;
min-width: 48px;
min-height: 48px;
margin-left: -85px; margin-left: -85px;
float: left; float: left;
border-radius: 4px; border-radius: 4px;
@ -144,6 +146,8 @@ form {
display: inline; display: inline;
max-width: 1.2em; max-width: 1.2em;
max-height: 1.2em; max-height: 1.2em;
min-width: inherit;
min-height: inherit;
} }
} }
} }

View file

@ -56,7 +56,7 @@ def update_feed(feed_id):
logger.info('Updating {}'.format(feed)) logger.info('Updating {}'.format(feed))
process_feed_for_new_entries(session, feed) process_feed_for_new_entries(session, feed)
def process_feed_for_new_entries(session, feed): def process_feed_for_new_entries(session, feed):
now = datetime.datetime.utcnow() now = datetime.datetime.utcnow()
found_new = False found_new = False
@ -76,17 +76,17 @@ def process_feed_for_new_entries(session, feed):
if not old or not is_content_equal(old, entry): if not old or not is_content_equal(old, entry):
# set a default value for published if none is provided # set a default value for published if none is provided
if not entry.published: if not entry.published:
entry.published = (old.published or now) if old else now entry.published = (old and old.published) or now
if old: if old:
feed.entries.remove(old) feed.entries.remove(old)
session.delete(old) session.delete(old)
feed.entries.append(entry) feed.entries.append(entry)
session.commit() session.commit()
found_new = True found_new = True
else: else:
logger.info('skipping previously seen post {}'.format(old.permalink)) logger.info('skipping previously seen post %s', old.permalink)
finally: finally:
feed.last_checked = now feed.last_checked = now
@ -104,7 +104,7 @@ def is_content_equal(e1, e2):
and e1.author_name == e2.author_name and e1.author_name == e2.author_name
and e1.author_url == e2.author_url and e1.author_url == e2.author_url
and e1.author_photo == e2.author_photo) and e1.author_photo == e2.author_photo)
def process_xml_feed_for_new_entries(session, feed): def process_xml_feed_for_new_entries(session, feed):
logger.debug('fetching xml feed: %s', feed) logger.debug('fetching xml feed: %s', feed)
@ -128,7 +128,7 @@ def process_xml_feed_for_new_entries(session, feed):
if 'updated_parsed' in p_entry: if 'updated_parsed' in p_entry:
updated = datetime.datetime.fromtimestamp( updated = datetime.datetime.fromtimestamp(
time.mktime(p_entry.updated_parsed)) time.mktime(p_entry.updated_parsed))
else: else:
updated = None updated = None
@ -203,7 +203,8 @@ def process_html_feed_for_new_entries(session, feed):
title=title, title=title,
content=content, content=content,
author_name=hentry.get('author', {}).get('name'), author_name=hentry.get('author', {}).get('name'),
author_photo=hentry.get('author', {}).get('photo') or fallback_photo(feed.origin), author_photo=hentry.get('author', {}).get('photo')
or fallback_photo(feed.origin),
author_url=hentry.get('author', {}).get('url')) author_url=hentry.get('author', {}).get('url'))
logger.debug('built entry: %s', entry.permalink) logger.debug('built entry: %s', entry.permalink)

View file

@ -13,10 +13,10 @@
action="{{ url_for('.update_all') }}" method="POST"> action="{{ url_for('.update_all') }}" method="POST">
<button type="submit">Update All</button> <button type="submit">Update All</button>
</form> </form>
{% for feed in feeds %} {% for feed in feeds %}
<article> <article>
<form style="display:inline" <form style="display:inline"
action="{{ url_for('.edit_feed') }}" method="POST"> action="{{ url_for('.edit_feed') }}" method="POST">
<input type="hidden" name="id" value="{{ feed.id }}"/> <input type="hidden" name="id" value="{{ feed.id }}"/>
@ -37,7 +37,7 @@
<button type="submit">Delete</button> <button type="submit">Delete</button>
</form> </form>
<br/> <br/>
<a href="{{ url_for('.index', feed=feed.id) }}">View posts from this feed</a> <a href="{{ url_for('.index', feed=feed.get_feed_code()) }}">View posts from this feed</a>
</article> </article>
{% endfor %} {% endfor %}

View file

@ -2,6 +2,7 @@ from . import tasks
from .extensions import db, login_mgr, micropub from .extensions import db, login_mgr, micropub
from .models import Feed, Entry, User from .models import Feed, Entry, User
import flask.ext.login as flask_login import flask.ext.login as flask_login
import binascii
import bs4 import bs4
import feedparser import feedparser
import flask import flask
@ -21,15 +22,19 @@ def index():
if flask_login.current_user.is_authenticated(): if flask_login.current_user.is_authenticated():
per_page = flask.current_app.config.get('PER_PAGE', 30) per_page = flask.current_app.config.get('PER_PAGE', 30)
offset = (page - 1) * per_page offset = (page - 1) * per_page
if 'feed' in flask.request.args: entry_query = Entry.query\
feed_ids = [int(flask.request.args.get('feed'))] .join(Entry.feed)\
else: .join(Feed.users)\
feed_ids = set(f.id for f in flask_login.current_user.feeds) .filter(User.id == flask_login.current_user.id)
if 'feed' in flask.request.args:
feed_hex = flask.request.args.get('feed').encode()
feed_url = binascii.unhexlify(feed_hex).decode('utf-8')
entry_query = entry_query.filter(Feed.feed == feed_url)
entries = entry_query.order_by(Entry.published.desc())\
.offset(offset).limit(per_page).all()
if feed_ids:
entries = Entry.query.filter(Entry.feed_id.in_(feed_ids))\
.order_by(Entry.published.desc())\
.offset(offset).limit(per_page).all()
return flask.render_template('feed.jinja2', entries=entries, page=page) return flask.render_template('feed.jinja2', entries=entries, page=page)
@ -312,5 +317,7 @@ def url_for_other_page(page):
"""http://flask.pocoo.org/snippets/44/#URL+Generation+Helper """http://flask.pocoo.org/snippets/44/#URL+Generation+Helper
""" """
args = flask.request.view_args.copy() args = flask.request.view_args.copy()
args.update(flask.request.args)
args['page'] = page args['page'] = page
return flask.url_for(flask.request.endpoint, **args) return flask.url_for(flask.request.endpoint, **args)