support tagging subscriptions

This commit is contained in:
Kyle Mahan 2015-04-19 13:58:31 -07:00
parent 9cfa2e4739
commit c9b2366637
11 changed files with 80 additions and 37 deletions

View file

@ -23,7 +23,7 @@ def upgrade():
sa.Column('user_id', sa.Integer(), sa.ForeignKey('user.id'), nullable=False),
sa.Column('feed_id', sa.Integer(), sa.ForeignKey('feed.id'), nullable=False),
sa.Column('name', sa.String(length=256), nullable=True),
sa.Column('tags', JsonType(), nullable=True),
sa.Column('tags', sa.String(length=256), nullable=True),
sa.PrimaryKeyConstraint('id')
)

View file

@ -1,7 +1,7 @@
from flask.ext.login import LoginManager
from flask.ext.micropub import MicropubClient
from flask.ext.sqlalchemy import SQLAlchemy
#from flask_debugtoolbar import DebugToolbarExtension
from flask_debugtoolbar import DebugToolbarExtension
from flask.ext.migrate import Migrate
@ -9,7 +9,7 @@ db = SQLAlchemy()
micropub = MicropubClient(client_id='http://reader.kylewm.com')
login_mgr = LoginManager()
login_mgr.login_view = 'views.index'
#toolbar = DebugToolbarExtension()
toolbar = DebugToolbarExtension()
migrate = Migrate()
@ -17,5 +17,5 @@ def init_app(app):
db.init_app(app)
micropub.init_app(app)
login_mgr.init_app(app)
#toolbar.init_app(app)
toolbar.init_app(app)
migrate.init_app(app, db)

View file

@ -112,7 +112,7 @@ class Subscription(db.Model):
# user-editable name of this subscribed feed
name = db.Column(db.String(256))
tags = db.Column(JsonType)
tags = db.Column(db.String(256))
user = db.relationship(User, backref='subscriptions')
feed = db.relationship(Feed, backref='subscriptions')

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 396 B

View file

@ -0,0 +1,25 @@
$(function() {
$(".feed-details").css({display: "none"});
$(".show-details").click(function(evt) {
evt.preventDefault();
var target = $(this).data("target");
$("#" + target).css({display: "inherit"});
$(this).css({display: "none"});
});
$("form.edit-subscription").submit(function(evt) {
var form = $(this);
evt.preventDefault();
$(".save-status", form).html("Saving…");
$.post(form.attr('action'), form.serialize(), function success(){
$(".save-status", form).html("Saved.");
}).fail(function failure() {
$(".save-status", form).html("Save Failed!");
});
});
});

View file

@ -51,7 +51,7 @@
<footer>
<a href="{{ entry.permalink }}">{{ entry.published | relative_time }}</a>
<a href="{{ url_for('.index', entry=entry.permalink) }}" target="_blank">
<img src="{{ url_for('static', filename='open_in_new_window2.png') }}" style="vertical-align:middle;" />
<i class="fa fa-external-link"></i>
</a>
{% if entry._syndicated_copies %}

View file

@ -11,6 +11,7 @@
<link rel="stylesheet" href="{{ url_for('static', filename='style.css', version='2015-03-20a') }}"/>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css"/>
<script src="//code.jquery.com/jquery-2.1.3.min.js"></script>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
{% block head %}{% endblock %}
</head>

View file

@ -20,6 +20,12 @@
<input type="url" id="origin" name="origin" placeholder="Subscribe to URL" />
</form>
{% endif %}
<i class="fa fa-tags"></i>
{% for tag in all_tags %}
<a href="{{ url_for('.index', tag=tag) }}">{{ tag }}</a>{% if not loop.last %}, {% endif %}
{% endfor %}
{% endblock header %}
{% block body %}
@ -28,7 +34,7 @@
{% include '_entry.jinja2' with context %}
{% endfor %}
{% if entries and has_older %}
{% if not solo %}
<div class="pager">
<a id="older-link" href="{{ url_for_other_page(page=page+1) }}">Older</a>
</div>

View file

@ -1,5 +1,9 @@
{% extends "base.jinja2" %}
{% block head %}
<script src="{{url_for('static', filename='subscriptions.js', version='2015-04-19')}}"></script>
{% endblock head %}
{% block header %}
{% if current_user.is_authenticated() %}
<form action="{{ url_for('.subscribe') }}" method="POST">
@ -24,12 +28,12 @@
<form class="edit-subscription" action="{{ url_for('.edit_subscription') }}" method="POST">
<input type="hidden" name="id" value="{{ s.id }}"/>
<label>Name</label>
<input type="text" name="name" value="{{ s.name }}"/>
<input type="text" name="name" value="{{ s.name }}"/>
<label>Tags</label>
<input type="text" name="tags" value="{{ (s.tags or []) | join(',') }}"/>
<input type="text" name="tags" value="{{ s.tags or ''}}"/>
<label>URL</label>
<input type="text" name="feed" value="{{ s.feed.feed }}" disabled />
<button type="submit">Save Edits</button>
<button type="submit">Save Edits</button> <span class="save-status"></span>
</form>
@ -69,19 +73,5 @@
{% endblock body %}
{% block foot %}
<script>
$(function() {
$(".feed-details").css({display: "none"});
$(".show-details").click(function(evt) {
evt.preventDefault();
var target = $(this).data("target");
$("#" + target).css({display: "inherit"});
$(this).css({display: "none"});
});
});
</script>
{% endblock foot %}

View file

@ -23,15 +23,22 @@ def index():
page = int(flask.request.args.get('page', 1))
entries = []
ws_topic = None
has_older = True
solo = False
if flask_login.current_user.is_authenticated():
all_tags = set()
for subsc in flask_login.current_user.subscriptions:
if subsc.tags:
all_tags.update(subsc.tags.split())
per_page = flask.current_app.config.get('PER_PAGE', 30)
offset = (page - 1) * per_page
entry_query = Entry.query\
.options(sqlalchemy.orm.subqueryload(Entry.feed),
sqlalchemy.orm.subqueryload(Entry.reply_context))\
.options(
sqlalchemy.orm.subqueryload(Entry.feed),
sqlalchemy.orm.subqueryload(Entry.reply_context)
)\
.join(Entry.feed)\
.join(Feed.subscriptions)\
.join(Subscription.user)\
@ -45,9 +52,13 @@ def index():
if not entry:
flask.abort(404)
entries = [entry]
has_older = False
solo = True
else:
if 'subscription' in flask.request.args:
if 'tag' in flask.request.args:
tag = flask.request.args.get('tag')
entry_query = entry_query.filter(
Subscription.tags.like('%{}%'.format(tag)))
elif 'subscription' in flask.request.args:
subsc_id = flask.request.args.get('subscription')
subsc = Subscription.query.get(subsc_id)
if not subsc:
@ -63,7 +74,8 @@ def index():
entries = dedupe_copies(entries)
return flask.render_template('feed.jinja2', entries=entries, page=page,
ws_topic=ws_topic, has_older=has_older)
ws_topic=ws_topic, solo=solo,
all_tags=all_tags)
@views.route('/install')
@ -75,10 +87,16 @@ def install():
@views.route('/subscriptions')
@flask_login.login_required
def subscriptions():
subscs = flask_login.current_user.subscriptions
sorted_subscs = sorted(subscs, key=lambda s: s.name and s.name.lower())
subscs = Subscription\
.query\
.filter_by(user_id=flask_login.current_user.id)\
.options(sqlalchemy.orm.subqueryload(Subscription.feed))\
.order_by(db.func.lower(Subscription.name))\
.all()
return flask.render_template('subscriptions.jinja2',
subscriptions=sorted_subscs)
subscriptions=subscs)
@views.route('/settings', methods=['GET', 'POST'])
@ -140,16 +158,19 @@ def unsubscribe():
def edit_subscription():
subsc_id = flask.request.form.get('id')
subsc_name = flask.request.form.get('name')
#feed_url = flask.request.form.get('feed')
subsc_tags = flask.request.form.get('tags')
subsc = Subscription.query.get(subsc_id)
if subsc_name:
subsc.name = subsc_name
#if feed_url:
# feed.feed = feed_url
if subsc_tags:
tag_list = re.split(r'(?:\s|,)+', subsc_tags)
subsc.tags = ' '.join(t.strip() for t in tag_list if t.strip())
else:
subsc_tags = None
db.session.commit()
flask.flash('Edited {} ({})'.format(subsc.name))
flask.flash('Edited {}'.format(subsc.name))
return flask.redirect(flask.url_for('.subscriptions'))