diff --git a/woodwind/api.py b/woodwind/api.py
new file mode 100644
index 0000000..62f5ee4
--- /dev/null
+++ b/woodwind/api.py
@@ -0,0 +1,23 @@
+import flask
+import requests
+
+api = flask.Blueprint('api', __name__)
+
+
+@api.route('/_forward', methods=['GET', 'POST'])
+def forward_request():
+ if flask.request.method == 'GET':
+ args = flask.request.args.copy()
+ url = args.pop('_url')
+ result = requests.get(url, params=args)
+ else:
+ data = flask.request.form.copy()
+ url = data.pop('_url')
+ result = requests.post(url, data=data)
+
+ return flask.jsonify({
+ 'code': result.status_code,
+ 'content': result.text,
+ 'content-type': result.headers.get('content-type'),
+ 'location': result.url,
+ })
diff --git a/woodwind/app.py b/woodwind/app.py
index 5e74f20..382f4c5 100644
--- a/woodwind/app.py
+++ b/woodwind/app.py
@@ -1,5 +1,6 @@
from . import extensions
-from .views import ui
+from .views import views
+from .api import api
from config import Config
import flask
@@ -8,5 +9,6 @@ def create_app():
app = flask.Flask('woodwind')
app.config.from_object(Config)
extensions.init_app(app)
- app.register_blueprint(ui)
+ app.register_blueprint(views)
+ app.register_blueprint(api)
return app
diff --git a/woodwind/static/feed.js b/woodwind/static/feed.js
new file mode 100644
index 0000000..d1f50ed
--- /dev/null
+++ b/woodwind/static/feed.js
@@ -0,0 +1,53 @@
+$(function(){
+ function clickOlderLink(evt) {
+ evt.preventDefault();
+ $.get(this.href, function(result) {
+ $(".pager").replaceWith(
+ $("article,.pager", $(result)));
+ attachListeners();
+ });
+ }
+
+ function clickShowReplyForm(evt) {
+ var a = $(this);
+ evt.preventDefault();
+ $(".reply-form", a.parent()).css('display', 'inherit');
+ a.css('display', 'none');
+ }
+
+ function submitMicropubForm(evt) {
+ evt.preventDefault();
+
+ var form = $(this);
+ var endpoint = form.attr('action');
+ var responseArea = $('.submit-response', form);
+
+ $.post(
+ '/_forward',
+ '_url=' + encodeURIComponent(endpoint) + '&' + form.serialize(),
+ function(result) {
+ if (result.code == 200) {
+ responseArea.html('Success!');
+ } else {
+ responseArea.html('Failure');
+ }
+ },
+ 'json'
+ );
+ responseArea.html('Posting…');
+ }
+
+ function attachListeners() {
+ $(".reply-form").css('display', 'none');
+ $(".show-reply-form").css('display', 'inline');
+
+ $("#older-link").off('click').click(clickOlderLink);
+ $(".show-reply-form").off('click').click(clickShowReplyForm);
+
+ $(".like-form, .reply-form").off('submit').submit(submitMicropubForm);
+ }
+
+
+
+ attachListeners();
+});
diff --git a/woodwind/templates/feed.jinja2 b/woodwind/templates/feed.jinja2
index 005c99e..57dbbf6 100644
--- a/woodwind/templates/feed.jinja2
+++ b/woodwind/templates/feed.jinja2
@@ -1,32 +1,7 @@
{% extends "base.jinja2" %}
{% block head %}
-
-
-
+
{% endblock head %}
{% block header %}
@@ -62,21 +37,23 @@ $(attachListeners);
diff --git a/woodwind/views.py b/woodwind/views.py
index f35509b..25addbc 100644
--- a/woodwind/views.py
+++ b/woodwind/views.py
@@ -10,10 +10,10 @@ import mf2util
import requests
import urllib
-ui = flask.Blueprint('ui', __name__)
+views = flask.Blueprint('views', __name__)
-@ui.route('/')
+@views.route('/')
def index():
page = int(flask.request.args.get('page', 1))
if flask_login.current_user.is_authenticated():
@@ -28,26 +28,26 @@ def index():
return flask.render_template('feed.jinja2', entries=entries, page=page)
-@ui.route('/install')
+@views.route('/install')
def install():
db.create_all()
return 'Success!'
-@ui.route('/feeds')
+@views.route('/feeds')
def feeds():
feeds = flask_login.current_user.feeds
return flask.render_template('feeds.jinja2', feeds=feeds)
-@ui.route('/update_feed')
+@views.route('/update_feed')
def update_feed():
feed_id = flask.request.args.get('id')
tasks.update_feed.delay(feed_id)
return flask.redirect(flask.url_for('.feeds'))
-@ui.route('/delete_feed', methods=['POST'])
+@views.route('/delete_feed', methods=['POST'])
def delete_feed():
feed_id = flask.request.form.get('id')
feed = Feed.query.get(feed_id)
@@ -57,7 +57,7 @@ def delete_feed():
return flask.redirect(flask.url_for('.feeds'))
-@ui.route('/edit_feed', methods=['POST'])
+@views.route('/edit_feed', methods=['POST'])
def edit_feed():
feed_id = flask.request.form.get('id')
feed_name = flask.request.form.get('name')
@@ -74,7 +74,7 @@ def edit_feed():
return flask.redirect(flask.url_for('.feeds'))
-@ui.route('/login')
+@views.route('/login')
def login():
me = flask.request.args.get('me')
if me:
@@ -85,7 +85,7 @@ def login():
return flask.render_template('login.jinja2')
-@ui.route('/login-callback')
+@views.route('/login-callback')
@micropub.authorized_handler
def login_callback(resp):
if not resp.me:
@@ -112,7 +112,7 @@ def load_user(domain):
return User.query.filter_by(domain=domain).first()
-@ui.route('/subscribe', methods=['GET', 'POST'])
+@views.route('/subscribe', methods=['GET', 'POST'])
def subscribe():
if flask.request.method == 'POST':
origin = flask.request.form.get('origin')