dynamic subscription fees

revamp
lza_menace 2 years ago
parent 680dc5aff5
commit ad6bad9b5e

@ -18,6 +18,8 @@ PLATFORM_WALLET = getenv('PLATFORM_WALLET')
CREATOR_SUBSCRIPTION_TERM = 30 # 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 = .15 # XMR flat rate fee for creator subscriptions
CREATOR_CONTENT_FEE_PERCENT = 5 # percentage of base fee to charge for content/posts
CREATOR_ACTIVE_SUBSCRIBER_FEE_PERCENT = 10 # percentage of received subscriber fees to charge creator for platform reup
# Crypto RPC
XMR_WALLET_PASS = getenv('XMR_WALLET_PASS')

@ -4,6 +4,7 @@ from typing import List
from secrets import token_urlsafe
import peewee as pw
from monero.numbers import to_atomic, from_atomic
from xmrbackers import config
from xmrbackers.helpers import EnumArrayField, EnumIntField
@ -28,12 +29,20 @@ class UserRole(IntEnum):
@unique
class ContentType(IntEnum):
class PostType(IntEnum):
text = 0
gallery = 1
stream = 2
@unique
class ContentType(IntEnum):
text = 0
image = 1
video = 2
stream = 3
class User(pw.Model):
"""
User model is for base user management and reporting.
@ -78,6 +87,29 @@ class User(pw.Model):
return True
return False
def derive_subscription_fees(self):
base_fee_atomic = to_atomic(config.CREATOR_SUBSCRIPTION_FEE_XMR)
posts = Post.select().where(Post.creator == self)
content = Content.select().join(Post).where(Post.creator == self)
content_base_fee_atomic = base_fee_atomic * config.CREATOR_CONTENT_FEE_PERCENT
content_fee_atomic = (posts.count() + content.count()) * content_base_fee_atomic
active_subs = Subscription.select().where(
Subscription.creator == self,
Subscription.is_active == True
)
received_sub_xmr_atomic = 0
for sub in active_subs:
received_sub_xmr_atomic += sub.meta.atomic_xmr
print('User can expect to pay the following fees on their next reup:\nBase Fee: {} XMR\nContent Fees: {} ({} posts, {} uploads)\nSubscriber Fees: {}'.format(
config.CREATOR_SUBSCRIPTION_FEE_XMR,
from_atomic(content_fee_atomic),
posts.count(),
content.count(),
from_atomic(received_sub_xmr_atomic)
))
class Meta:
database = db
@ -127,7 +159,6 @@ 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=0) # delete me
@property
def grace_start_date(self):
@ -188,19 +219,23 @@ class Subscription(pw.Model):
id = pw.AutoField()
subscribe_date = pw.DateTimeField(default=datetime.utcnow)
tx = pw.ForeignKeyField(Transaction)
active = pw.BooleanField(default=True)
creator = pw.ForeignKeyField(User)
backer = pw.ForeignKeyField(User)
meta = pw.ForeignKeyField(SubscriptionMeta)
@property
def is_active(self):
end_date = self.subscribe_date + timedelta(hours=self.meta.number_hours)
return end_date > datetime.utcnow()
class Meta:
database = db
class Content(pw.Model):
class Post(pw.Model):
"""
Content model represents any uploaded content from a creator which is only
viewable by backers with an active subscription.
Post model represents a post from a creator consisting of Content objects
which is only viewable by backers with an active subscription.
"""
id = pw.AutoField()
post_date = pw.DateTimeField(default=datetime.utcnow)
@ -210,6 +245,21 @@ class Content(pw.Model):
last_edit_date = pw.DateTimeField(default=datetime.utcnow)
creator = pw.ForeignKeyField(User)
type: List[PostType] = EnumIntField(enum_class=PostType, default=PostType.text)
class Meta:
database = db
class Content(pw.Model):
"""
Content model is any uploaded content from a creator.
"""
id = pw.AutoField()
location = pw.CharField()
upload_date = pw.DateTimeField(default=datetime.utcnow)
post = pw.ForeignKeyField(Post)
type: List[ContentType] = EnumIntField(enum_class=ContentType, default=ContentType.text)
class Meta:

@ -114,10 +114,12 @@ async def show(handle):
await flash('That creator does not exist.', 'warning')
return redirect(url_for('main.index'))
posts = Content.select().where(
Content.creator == creator,
Content.hidden == False
).order_by(Content.post_date.desc())
creator.derive_subscription_fees()
posts = Post.select().where(
Post.creator == creator,
Post.hidden == False
).order_by(Post.post_date.desc())
subscriptions = SubscriptionMeta.select().where(
SubscriptionMeta.user == creator
).order_by(SubscriptionMeta.create_date.desc())

@ -1,7 +1,7 @@
from quart import Blueprint, render_template
from flask_login import current_user
from xmrbackers.models import User, Profile, Subscription, Content, UserRole
from xmrbackers.models import *
bp = Blueprint('main', 'main')
@ -15,14 +15,14 @@ async def index():
feed['new_creators'] = new_creators
if current_user.is_authenticated:
active_subscriptions = Subscription.select().where(
Subscription.active == True,
Subscription.is_active == True,
Subscription.backer == current_user
).order_by(Subscription.subscribe_date.desc()).execute()
feed['active_subscriptions'] = active_subscriptions
new_posts = Content.select().where(
Content.hidden == False,
Content.creator in [c.creator for c in active_subscriptions]
).order_by(Content.post_date.desc()).execute()
new_posts = Post.select().where(
Post.hidden == False,
Post.creator in [c.creator for c in active_subscriptions]
).order_by(Post.post_date.desc()).execute()
feed['new_posts'] = new_posts
return await render_template(
'index.html',

Loading…
Cancel
Save