diff --git a/requirements.txt b/requirements.txt index 5e78128..d462646 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,3 +14,4 @@ WTForms quart monero arrow +flake8 diff --git a/xmrbackers/decorators.py b/xmrbackers/decorators.py new file mode 100644 index 0000000..0158817 --- /dev/null +++ b/xmrbackers/decorators.py @@ -0,0 +1,25 @@ +from quart import session, redirect, url_for, flash +from flask_login import current_user +from functools import wraps +from xmrbackers.models import User, CreatorProfile, BackerProfile, Subscription + + +# def login_required(f): +# @wraps(f) +# def decorated_function(*args, **kwargs): +# if "auth" not in session or not session["auth"]: +# return redirect(url_for("auth.login")) +# return f(*args, **kwargs) +# return decorated_function + +def subscription_required(f): + @wraps(f) + def decorated_function(*args, **kwargs): + print(current_user) + # m = Moderator.filter(username=session["auth"]["preferred_username"]) + # if m: + # return f(*args, **kwargs) + # else: + # flash("You are not a moderator") + # return redirect(url_for("index")) + return decorated_function diff --git a/xmrbackers/factory.py b/xmrbackers/factory.py index b73ea54..ef9c35e 100644 --- a/xmrbackers/factory.py +++ b/xmrbackers/factory.py @@ -20,13 +20,14 @@ def create_app(): app.config.from_envvar('QUART_SECRETS') @app.before_serving async def startup(): - from xmrbackers.routes import meta, api, auth, creator + from xmrbackers.routes import meta, api, auth, creator, post from xmrbackers import filters await _setup_db(app) app.register_blueprint(meta.bp) app.register_blueprint(api.bp) app.register_blueprint(auth.bp) app.register_blueprint(creator.bp) + app.register_blueprint(post.bp) app.register_blueprint(filters.bp) login_manager = LoginManager(app) diff --git a/xmrbackers/filters.py b/xmrbackers/filters.py index 8434efd..0c30283 100644 --- a/xmrbackers/filters.py +++ b/xmrbackers/filters.py @@ -1,6 +1,7 @@ -import arrow from datetime import datetime +import arrow +import monero from quart import Blueprint, current_app @@ -18,3 +19,7 @@ def from_ts(v): @bp.app_template_filter('xmr_block_explorer') def xmr_block_explorer(v): return f'https://www.exploremonero.com/transaction/{v}' + +@bp.app_template_filter('from_atomic') +def from_atomic(amt): + return monero.numbers.from_atomic(amt) diff --git a/xmrbackers/routes/auth.py b/xmrbackers/routes/auth.py index 3e34cec..1729cdc 100644 --- a/xmrbackers/routes/auth.py +++ b/xmrbackers/routes/auth.py @@ -1,4 +1,3 @@ -import quart.flask_patch from quart import Blueprint, render_template from quart import flash, redirect, url_for from flask_login import login_user, logout_user, current_user diff --git a/xmrbackers/routes/creator.py b/xmrbackers/routes/creator.py index 6c7c43e..f77c938 100644 --- a/xmrbackers/routes/creator.py +++ b/xmrbackers/routes/creator.py @@ -1,6 +1,6 @@ -from quart import Blueprint, render_template, flash, redirect +from quart import Blueprint, render_template, flash, redirect, url_for -from xmrbackers.models import User, CreatorProfile +from xmrbackers.models import User, CreatorProfile, TextPost, SubscriptionMeta bp = Blueprint('creator', 'creator') @@ -19,7 +19,33 @@ async def show(username): CreatorProfile.user == user ).first() if creator: - return await render_template('creator/creator.html', creator=creator) + posts = TextPost.select().where( + TextPost.creator == creator, + TextPost.hidden == False + ).order_by(TextPost.post_date.desc()) + return await render_template( + 'creator/creator.html', + creator=creator, + posts=posts + ) else: - flash('That creator does not exist.') + await flash('That creator does not exist.') + return redirect(url_for('meta.index')) + +@bp.route('/creator//subscription') +async def subscription(username): + user = User.select().where(User.username == username) + creator = CreatorProfile.select().where( + CreatorProfile.user == user + ) + if creator: + subscription_meta = SubscriptionMeta.select().where( + SubscriptionMeta.creator == creator + ).order_by(SubscriptionMeta.create_date.desc()).first() + return await render_template( + 'creator/subscription.html', + subscription_meta=subscription_meta + ) + else: + await flash('That creator does not exist.') return redirect(url_for('meta.index')) diff --git a/xmrbackers/routes/post.py b/xmrbackers/routes/post.py new file mode 100644 index 0000000..f0cd656 --- /dev/null +++ b/xmrbackers/routes/post.py @@ -0,0 +1,27 @@ +from quart import Blueprint, render_template, flash, redirect, url_for +from flask_login import current_user + +from xmrbackers.models import TextPost, Subscription + + +bp = Blueprint('post', 'post') + +@bp.route('/post/') +async def show(post_id): + post = TextPost.get_or_none(post_id) + if post: + if current_user.is_anonymous: + await flash('You must login to view this post.') + return redirect(url_for('creator.show', username=post.creator.user.username)) + user_subscriptions = Subscription.select().where( + Subscription.active == True, + Subscription.backer == current_user.backer_profile.first() + ) + if user_subscriptions: + return await render_template('post/show.html', post=post) + else: + await flash('Viewing posts requires a subscription.') + return redirect(url_for('creator.subscription', username=post.creator.user.username)) + else: + flash('That post does not exist.') + return redirect(url_for('meta.index')) diff --git a/xmrbackers/templates/creator/creator.html b/xmrbackers/templates/creator/creator.html index a1005a2..f66ebd7 100644 --- a/xmrbackers/templates/creator/creator.html +++ b/xmrbackers/templates/creator/creator.html @@ -7,12 +7,19 @@
{% include 'includes/header.html' %} - + {% if creator %}

{{ creator.user.username }}

Bio: {{ creator.bio }}

{% endif %} + {% if posts %} +

Posts

+ {% for post in posts %} +

{{ post.id }} - {{ post.title }} - {{ post.post_date | humanize }}

+ {% endfor %} + {% endif %} + {% include 'includes/footer.html' %}
diff --git a/xmrbackers/templates/creator/subscription.html b/xmrbackers/templates/creator/subscription.html new file mode 100644 index 0000000..a846fe5 --- /dev/null +++ b/xmrbackers/templates/creator/subscription.html @@ -0,0 +1,27 @@ + + + + {% include 'includes/head.html' %} + + +
+ + {% include 'includes/header.html' %} + + {% if subscription_meta %} +

Subscribe

+

Creator: {{ subscription_meta.creator.user.username }}

+

ID: {{ subscription_meta.id }}

+

XMR: {{ subscription_meta.atomic_xmr | from_atomic }}

+

Address: {{ subscription_meta.wallet_address }}

+

Hours: {{ subscription_meta.number_hours }}

+ {% endif %} + + {% include 'includes/footer.html' %} + +
+ + {% include 'includes/scripts.html' %} + + + diff --git a/xmrbackers/templates/post/show.html b/xmrbackers/templates/post/show.html new file mode 100644 index 0000000..80d20b4 --- /dev/null +++ b/xmrbackers/templates/post/show.html @@ -0,0 +1,25 @@ + + + + {% include 'includes/head.html' %} + + +
+ + {% include 'includes/header.html' %} + + {% if post %} +

{{ post.title }}

+

Posted: {{ post.post_date }}

+

Edited: {{ post.last_edit_date }}

+

{{ post.content }}

+ {% endif %} + + {% include 'includes/footer.html' %} + +
+ + {% include 'includes/scripts.html' %} + + +