Initial commit;

This commit is contained in:
Benjamin Bouvier 2017-12-29 13:10:25 +01:00
commit e07a749e4a
3 changed files with 127 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
venv
__pycache__
db.sqlite

121
main.py Normal file
View File

@ -0,0 +1,121 @@
import json
import dateutil
from datetime import datetime, timezone
from flask import Flask, request, abort
from feedgen.feed import FeedGenerator
from pony import orm
from pony.orm import Required, Optional, Set
app = Flask(__name__)
SITE_URL = 'http://localhost:5000/feeds/'
db = orm.Database()
class Feed(db.Entity):
slug = Required(str, unique=True)
admin_token = Required(str)
title = Required(str)
atom_id = Required(str) # also link
description = Required(str)
login = Optional(str)
password = Optional(str)
items = Set('Item')
class Item(db.Entity):
feed = Required(Feed)
atom_id = Required(str)
title = Required(str)
content = Required(str)
date = Required(datetime)
db.bind(provider='sqlite', filename='db.sqlite', create_db=True)
db.generate_mapping(create_tables=True)
orm.set_sql_debug(True)
def does_slug_exist(slug):
with orm.db_session:
return len(orm.select(f for f in Feed if f.slug == slug)[:1])
@app.route('/feeds', methods=['POST'])
def add_feed():
data = request.get_json(silent=True)
if 'slug' not in data:
abort(400, 'missing slug')
slug = data['slug']
if does_slug_exist(slug):
abort(400, "feed with this slug already exists")
if 'title' not in data or 'description' not in data or 'admin_token' not in data:
abort(400, "missing title or description or admin_token")
url = SITE_URL + slug
with orm.db_session:
feed = Feed(slug=slug,
admin_token=data['admin_token'],
title=data['title'],
atom_id=url,
description=data['description'])
if 'login' in data and 'password' in data:
feed.login = data['login']
feed.password = data['password']
return "OK"
@app.route('/feeds/<slug>', methods=['GET', 'POST'])
@orm.db_session
def by_feed_name(slug):
if not does_slug_exist(slug):
abort(404, "unknown slug")
feed = orm.select(f for f in Feed if f.slug == slug)[:1][0]
if feed.password is not '':
auth = request.authorization
if not auth or auth.username != feed.login or auth.password != feed.password:
abort(401, "missing or incorrect password")
if request.method == 'POST':
data = request.get_json(silent=True)
if 'title' not in data or 'content' not in data or 'admin_token' not in data:
abort(400, "missing title or content")
if data['admin_token'] != feed.admin_token:
abort(401, "incorrect admin_token")
item_id = feed.atom_id + '/' + str(len(feed.items))
date = datetime.now(dateutil.tz.tzutc())
with orm.db_session:
item = Item(feed=feed,
atom_id=item_id,
title=data['title'],
content=data['content'],
date=date)
return "OK"
gen = FeedGenerator()
gen.title(feed.title)
gen.id(feed.atom_id)
gen.link(href=feed.atom_id)
gen.description(feed.description)
for item in feed.items:
fe = gen.add_entry()
fe.id(item.atom_id)
fe.title(item.title)
fe.content(item.content)
date = item.date.replace(tzinfo=timezone.utc)
fe.updated(date)
return gen.atom_str(pretty=True).decode('utf8')

3
requirements.txt Normal file
View File

@ -0,0 +1,3 @@
Flask
feedgen
pony