diff --git a/xmrbackers/config.py b/xmrbackers/config.py
index e091f06..ae79796 100644
--- a/xmrbackers/config.py
+++ b/xmrbackers/config.py
@@ -15,10 +15,9 @@ SERVER_NAME = getenv('SERVER_NAME', 'localhost:5000')
PLATFORM_WALLET = getenv('PLATFORM_WALLET')
# Constants - here for easy template references
-CREATOR_SUBSCRIPTION_TERM = 60 # term of how long creator subscriptions are valid for
-CREATOR_SUBSCRIPTION_GRACE = 10 # grace period after expiration of creator subscriptions until content is hidden
-CREATOR_SUBSCRIPTION_DELETE = 20 # time after grace period until content is deleted
-CREATOR_SUBSCRIPTION_FEE_XMR = .15 # default flat rate fee in XMR for creator subscriptions
+CREATOR_SUBSCRIPTION_TERM = 60 # days term of how long creator subscriptions are valid for until content is hidden
+CREATOR_SUBSCRIPTION_GRACE = 21 # days grace period after expiration of creator subscriptions until content is archived
+CREATOR_SUBSCRIPTION_FEE_XMR = .3 # XMR flat rate fee for creator subscriptions
# Crypto RPC
XMR_WALLET_PASS = getenv('XMR_WALLET_PASS')
diff --git a/xmrbackers/filters.py b/xmrbackers/filters.py
index 0c30283..8f8744b 100644
--- a/xmrbackers/filters.py
+++ b/xmrbackers/filters.py
@@ -1,7 +1,7 @@
from datetime import datetime
import arrow
-import monero
+from monero import numbers
from quart import Blueprint, current_app
@@ -22,4 +22,4 @@ def xmr_block_explorer(v):
@bp.app_template_filter('from_atomic')
def from_atomic(amt):
- return monero.numbers.from_atomic(amt)
+ return numbers.as_monero(numbers.from_atomic(amt))
diff --git a/xmrbackers/forms.py b/xmrbackers/forms.py
index 7c193f2..f1600ea 100644
--- a/xmrbackers/forms.py
+++ b/xmrbackers/forms.py
@@ -1,5 +1,5 @@
from flask_wtf import FlaskForm
-from wtforms import StringField
+from wtforms import StringField, FloatField
from wtforms.validators import DataRequired, ValidationError
from monero.address import address
@@ -35,3 +35,8 @@ class UserChallenge(FlaskForm):
class ConfirmSubscription(FlaskForm):
tx_id = StringField('TX ID:', validators=[DataRequired()], render_kw={"placeholder": "TX ID", "class": "form-control", "type": "text"})
tx_key = StringField('TX Key:', validators=[DataRequired()], render_kw={"placeholder": "TX Key", "class": "form-control", "type": "text"})
+
+
+class CreateSubscription(FlaskForm):
+ price_xmr = FloatField('Price (XMR):', validators=[DataRequired()], render_kw={'placeholder': '.5', 'class': 'form-control', 'type': 'text'})
+ number_days = FloatField('Length (Days)', validators=[DataRequired()], render_kw={'placeholder': '30', 'class': 'form-control', 'type': 'text'})
diff --git a/xmrbackers/models.py b/xmrbackers/models.py
index bdeb197..4d065db 100644
--- a/xmrbackers/models.py
+++ b/xmrbackers/models.py
@@ -1,4 +1,4 @@
-from datetime import datetime
+from datetime import datetime, timedelta
from enum import IntEnum, unique
from typing import List
from secrets import token_urlsafe
@@ -116,7 +116,29 @@ class CreatorSubscription(pw.Model):
atomic_xmr = pw.BigIntegerField()
term_hours = pw.IntegerField(default=config.CREATOR_SUBSCRIPTION_TERM * 24)
grace_hours = pw.IntegerField(default=config.CREATOR_SUBSCRIPTION_GRACE * 24)
- delete_hours = pw.IntegerField(default=config.CREATOR_SUBSCRIPTION_DELETE * 24)
+ delete_hours = pw.IntegerField(default=0) # delete me
+
+ @property
+ def grace_start_date(self):
+ # Hide content after this date if no new valid platform subscription
+ return self.create_date + timedelta(hours=self.term_hours)
+
+ @property
+ def delete_start_date(self):
+ # Archive content after this date if no new valid platform subscription
+ return self.grace_start_date + timedelta(hours=self.grace_hours)
+
+ @property
+ def hours_until_content_hidden(self):
+ return self.grace_start_date - datetime.utcnow()
+
+ @property
+ def hours_until_content_archived(self):
+ return self.delete_start_date - datetime.utcnow()
+
+ @property
+ def is_active(self):
+ return self.grace_start_date > datetime.utcnow()
class Meta:
database = db
@@ -136,9 +158,10 @@ class SubscriptionMeta(pw.Model):
number_hours = pw.IntegerField()
wallet_address = pw.CharField()
- def get_end_date(self) -> datetime:
- # some timedelta shiz
- pass
+ def get_active_subscriptions(self):
+ return Subscription.select().where(
+ Subscription.meta == self
+ )
class Meta:
database = db
diff --git a/xmrbackers/routes/creator.py b/xmrbackers/routes/creator.py
index e695605..0d7c14a 100644
--- a/xmrbackers/routes/creator.py
+++ b/xmrbackers/routes/creator.py
@@ -122,6 +122,43 @@ async def show(handle):
)
+@bp.route('/creator/subscriptions/manage', methods=['GET', 'POST'])
+@login_required
+async def manage_subscriptions():
+ form = forms.CreateSubscription()
+ if UserRole.creator not in current_user.roles:
+ await flash('You are not a creator!', 'warning')
+ return redirect(url_for('main.index'))
+
+ platform_subs = CreatorSubscription.select().where(
+ CreatorSubscription.user == current_user
+ ).order_by(CreatorSubscription.create_date.desc())
+ content_subs = SubscriptionMeta.select().where(
+ SubscriptionMeta.user == current_user
+ ).order_by(SubscriptionMeta.create_date.desc())
+ subscribers = Subscription.select().where(
+ Subscription.meta.in_(content_subs)
+ ).order_by(Subscription.subscribe_date.desc())
+
+ if form.validate_on_submit():
+ s = SubscriptionMeta(
+ user=current_user,
+ atomic_xmr=to_atomic(form.price_xmr.data),
+ number_hours=form.number_days.data * 24.0,
+ wallet_address=current_user.wallet_address
+ )
+ s.save()
+ await flash('posting form data', 'success')
+
+ return await render_template(
+ 'creator/manage_subscriptions.html',
+ platform_subs=platform_subs,
+ content_subs=content_subs,
+ subscribers=subscribers,
+ form=form
+ )
+
+
# @bp.route('/creator/
Platform Wallet: {{ config.PLATFORM_WALLET }}
- +{% include 'includes/form.html' %} {% endblock %} diff --git a/xmrbackers/templates/creator/manage_subscriptions.html b/xmrbackers/templates/creator/manage_subscriptions.html new file mode 100644 index 0000000..b5ad478 --- /dev/null +++ b/xmrbackers/templates/creator/manage_subscriptions.html @@ -0,0 +1,49 @@ +{% extends 'includes/base.html' %} + +{% block content %} + +No subscriptions to your content yet.
+ {% include 'includes/form.html' %} +{% else %} +No subscribers yet.
+{% else %} + {% for subscriber in subscribers %} + {{ subscriber }} + {% endfor %} +{% endif %} + +{% endblock %} diff --git a/xmrbackers/templates/includes/base.html b/xmrbackers/templates/includes/base.html index 4959b1d..9a642d8 100644 --- a/xmrbackers/templates/includes/base.html +++ b/xmrbackers/templates/includes/base.html @@ -2,9 +2,9 @@ {% include 'includes/head.html' %} - {% include 'includes/header.html' %} - {% block content %}{% endblock %} - {% include 'includes/footer.html' %} + {% include 'includes/header.html' %} + {% block content %}{% endblock %} + {% include 'includes/debug.html' %} {% include 'includes/scripts.html' %} diff --git a/xmrbackers/templates/includes/debug.html b/xmrbackers/templates/includes/debug.html new file mode 100644 index 0000000..98bc6b7 --- /dev/null +++ b/xmrbackers/templates/includes/debug.html @@ -0,0 +1,11 @@ +
+ Authenticated: {{ current_user.is_authenticated }}
+ Username: {{ current_user.handle }}
+ Email: {{ current_user.email }}
+ Wallet Address: {{ current_user.wallet_address }}
+
Authenticated: {{ current_user.is_authenticated }}
-Username: {{ current_user.handle }}
-Email: {{ current_user.email }}
-Wallet Address: {{ current_user.wallet_address }}
- {% endif %} -{{ p.id }}
- {% endfor %} - {% endif %} - {% if feed['active_subscriptions'] %} -{{ s.id }}
- {% endfor %} - {% endif %} - {% endif %} - - {% include 'includes/footer.html' %} - -{{ p.id }}
+ {% endfor %} + {% endif %} + {% if feed['active_subscriptions'] %} +{{ s.id }}
+ {% endfor %} + {% endif %} +{% endif %} + +{% endblock %}