Initial commit;
This commit is contained in:
commit
e07a749e4a
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
venv
|
||||||
|
__pycache__
|
||||||
|
db.sqlite
|
121
main.py
Normal file
121
main.py
Normal 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
3
requirements.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Flask
|
||||||
|
feedgen
|
||||||
|
pony
|
Loading…
Reference in New Issue
Block a user