2022-11-15 09:19:08 +00:00
from sqlalchemy import func
2022-09-02 23:58:55 +00:00
from files . classes . hats import *
from files . helpers . alerts import *
2022-12-11 23:44:34 +00:00
from files . helpers . config . const import *
2022-11-01 23:46:56 +00:00
from files . helpers . useractions import *
2022-11-15 09:19:08 +00:00
from files . routes . wrappers import *
from files . __main__ import app , limiter
2022-09-02 23:58:55 +00:00
2023-02-19 09:34:10 +00:00
@app.get ( " /shop/hats " )
2023-07-13 13:50:46 +00:00
@limiter.limit ( DEFAULT_RATELIMIT , deduct_when = lambda response : response . status_code < 400 )
@limiter.limit ( DEFAULT_RATELIMIT , deduct_when = lambda response : response . status_code < 400 , key_func = get_ID )
2022-11-14 15:11:05 +00:00
@auth_required
2023-07-30 00:42:06 +00:00
def hats ( v ) :
2022-09-03 19:11:02 +00:00
owned_hat_ids = [ x . hat_id for x in v . owned_hats ]
2022-09-02 23:58:55 +00:00
2023-05-05 03:13:17 +00:00
sort = request . values . get ( " sort " )
2023-05-05 05:23:59 +00:00
page = get_page ( )
2023-05-05 03:13:17 +00:00
if SITE == ' rdrama.net ' :
hats = g . db . query ( HatDef , User ) . join ( HatDef . author )
2022-09-03 19:11:02 +00:00
else :
2023-05-05 03:13:17 +00:00
hats = g . db . query ( HatDef )
2022-09-05 08:27:37 +00:00
2023-08-16 23:15:39 +00:00
hats = hats . filter ( HatDef . submitter_id == None )
2023-08-16 23:14:32 +00:00
2023-05-05 03:13:17 +00:00
if sort and sort != " owners " :
if sort == " name " :
key = HatDef . name
elif sort == " description " :
key = HatDef . description
elif sort == " author " :
key = User . username
elif sort == " price " :
key = HatDef . price
elif sort == " added_on " :
key = HatDef . created_utc . desc ( )
hats = hats . order_by ( key ) . offset ( PAGE_SIZE * ( page - 1 ) ) . limit ( PAGE_SIZE ) . all ( )
elif sort == " owners " :
2023-05-05 06:37:58 +00:00
hat_count = { x [ 0 ] : x [ 1 ] for x in g . db . query ( Hat . hat_id , func . count ( Hat . hat_id ) ) . group_by ( Hat . hat_id ) . all ( ) }
2023-05-05 21:45:25 +00:00
2023-05-05 03:13:17 +00:00
if SITE == ' rdrama.net ' :
2023-05-05 06:37:58 +00:00
hats = sorted ( hats . all ( ) , key = lambda x : hat_count [ x [ 0 ] . id ] if x [ 0 ] . id in hat_count else 0 , reverse = True )
2023-05-05 03:13:17 +00:00
else :
2023-05-05 06:37:58 +00:00
hats = sorted ( hats . all ( ) , key = lambda x : hat_count [ x . id ] if x . id in hat_count else 0 , reverse = True )
2023-05-05 21:45:25 +00:00
2023-05-05 03:13:17 +00:00
firstrange = PAGE_SIZE * ( page - 1 )
secondrange = firstrange + PAGE_SIZE
hats = hats [ firstrange : secondrange ]
else :
if v . equipped_hat_ids :
2023-08-16 23:14:32 +00:00
equipped = hats . filter ( HatDef . id . in_ ( owned_hat_ids ) , HatDef . id . in_ ( v . equipped_hat_ids ) ) . order_by ( HatDef . price , HatDef . name ) . all ( )
not_equipped = hats . filter ( HatDef . id . in_ ( owned_hat_ids ) , HatDef . id . notin_ ( v . equipped_hat_ids ) ) . order_by ( HatDef . price , HatDef . name ) . all ( )
2023-05-05 03:13:17 +00:00
owned = equipped + not_equipped
else :
2023-08-16 23:14:32 +00:00
owned = hats . filter ( HatDef . id . in_ ( owned_hat_ids ) ) . order_by ( HatDef . price , HatDef . name ) . all ( )
2023-05-05 03:13:17 +00:00
2023-08-16 23:14:32 +00:00
not_owned = hats . filter ( HatDef . id . notin_ ( owned_hat_ids ) ) . order_by ( HatDef . price == 0 , HatDef . price , HatDef . name ) . all ( )
2023-05-05 03:13:17 +00:00
hats = owned + not_owned
firstrange = PAGE_SIZE * ( page - 1 )
secondrange = firstrange + PAGE_SIZE
hats = hats [ firstrange : secondrange ]
2022-09-03 19:11:02 +00:00
2023-03-16 06:27:58 +00:00
sales = g . db . query ( func . sum ( User . coins_spent_on_hats ) ) . scalar ( )
num_of_hats = g . db . query ( HatDef ) . filter ( HatDef . submitter_id == None ) . count ( )
2023-05-05 03:13:17 +00:00
2023-05-05 21:44:24 +00:00
return render_template ( " hats.html " , owned_hat_ids = owned_hat_ids , hats = hats , v = v , sales = sales , num_of_hats = num_of_hats , total = num_of_hats , page = page , sort = sort )
2022-09-02 23:58:55 +00:00
2022-12-29 10:39:10 +00:00
@app.post ( " /buy_hat/<int:hat_id> " )
2023-02-27 05:33:45 +00:00
@limiter.limit ( ' 1/second ' , scope = rpath )
2023-04-02 06:52:26 +00:00
@limiter.limit ( ' 1/second ' , scope = rpath , key_func = get_ID )
2023-07-13 13:50:46 +00:00
@limiter.limit ( ' 100/minute;1000/3 days ' , deduct_when = lambda response : response . status_code < 400 )
@limiter.limit ( ' 100/minute;1000/3 days ' , deduct_when = lambda response : response . status_code < 400 , key_func = get_ID )
2022-09-02 23:58:55 +00:00
@auth_required
2023-07-30 00:42:06 +00:00
def buy_hat ( v , hat_id ) :
2023-03-16 06:27:58 +00:00
hat = g . db . query ( HatDef ) . filter_by ( submitter_id = None , id = hat_id ) . one_or_none ( )
2022-10-11 13:01:39 +00:00
if not hat : abort ( 404 , " Hat not found! " )
2022-09-02 23:58:55 +00:00
2023-03-16 06:27:58 +00:00
existing = g . db . query ( Hat ) . filter_by ( user_id = v . id , hat_id = hat . id ) . one_or_none ( )
2022-11-16 12:52:16 +00:00
if existing : abort ( 409 , " You already own this hat! " )
2022-09-03 03:58:43 +00:00
2022-11-01 03:37:52 +00:00
if not hat . is_purchasable :
2023-01-27 11:57:29 +00:00
abort ( 403 , " This hat is not for sale! " )
2022-11-01 03:37:52 +00:00
2023-04-25 04:47:36 +00:00
charged = v . charge_account ( ' combined ' , hat . price )
if not charged [ 0 ] :
abort ( 400 , " Not enough coins/marseybux! " )
2022-09-16 08:58:12 +00:00
2023-04-24 15:08:40 +00:00
v . coins_spent_on_hats + = charged [ 1 ]
hat . author . pay_account ( ' coins ' , hat . price * 0.1 )
2022-09-02 23:58:55 +00:00
new_hat = Hat ( user_id = v . id , hat_id = hat . id )
2023-03-16 06:27:58 +00:00
g . db . add ( new_hat )
2022-09-02 23:58:55 +00:00
2023-03-16 06:27:58 +00:00
g . db . add ( v )
g . db . add ( hat . author )
2022-09-02 23:58:55 +00:00
2022-09-05 07:59:24 +00:00
send_repeatable_notification (
hat . author . id ,
2023-04-24 15:08:40 +00:00
f " :marseycapitalistmanlet: @ { v . username } has just bought ` { hat . name } `, you have received your 10% cut ( { int ( hat . price * 0.1 ) } coins) :!marseycapitalistmanlet: "
2022-09-05 07:59:24 +00:00
)
2022-09-02 23:58:55 +00:00
2023-08-20 02:00:35 +00:00
if v . num_of_owned_hats > = 249 :
2022-09-03 00:54:17 +00:00
badge_grant ( user = v , badge_id = 154 )
2023-08-20 02:00:35 +00:00
elif v . num_of_owned_hats > = 99 :
2022-09-03 00:54:17 +00:00
badge_grant ( user = v , badge_id = 153 )
2023-08-20 02:00:35 +00:00
elif v . num_of_owned_hats > = 24 :
2022-09-03 00:54:17 +00:00
badge_grant ( user = v , badge_id = 152 )
2022-09-03 00:18:10 +00:00
2022-09-11 14:32:00 +00:00
return { " message " : f " ' { hat . name } ' bought! " }
2022-09-02 23:58:55 +00:00
2022-12-29 10:39:10 +00:00
@app.post ( " /equip_hat/<int:hat_id> " )
2023-02-27 05:33:45 +00:00
@limiter.limit ( ' 1/second ' , scope = rpath )
2023-04-02 06:52:26 +00:00
@limiter.limit ( ' 1/second ' , scope = rpath , key_func = get_ID )
2023-07-13 13:50:46 +00:00
@limiter.limit ( DEFAULT_RATELIMIT , deduct_when = lambda response : response . status_code < 400 )
@limiter.limit ( DEFAULT_RATELIMIT , deduct_when = lambda response : response . status_code < 400 , key_func = get_ID )
2022-11-14 15:11:05 +00:00
@auth_required
2023-07-30 00:42:06 +00:00
def equip_hat ( v , hat_id ) :
2023-03-16 06:27:58 +00:00
hat = g . db . query ( Hat ) . filter_by ( hat_id = hat_id , user_id = v . id ) . one_or_none ( )
2022-10-11 13:01:39 +00:00
if not hat : abort ( 403 , " You don ' t own this hat! " )
2022-09-02 23:58:55 +00:00
2022-09-05 03:44:24 +00:00
hat . equipped = True
2023-03-16 06:27:58 +00:00
g . db . add ( hat )
2022-09-02 23:58:55 +00:00
2022-09-11 14:32:00 +00:00
return { " message " : f " ' { hat . name } ' equipped! " }
2022-09-02 23:58:55 +00:00
2022-12-29 10:39:10 +00:00
@app.post ( " /unequip_hat/<int:hat_id> " )
2023-02-27 05:33:45 +00:00
@limiter.limit ( ' 1/second ' , scope = rpath )
2023-04-02 06:52:26 +00:00
@limiter.limit ( ' 1/second ' , scope = rpath , key_func = get_ID )
2023-07-13 13:50:46 +00:00
@limiter.limit ( DEFAULT_RATELIMIT , deduct_when = lambda response : response . status_code < 400 )
@limiter.limit ( DEFAULT_RATELIMIT , deduct_when = lambda response : response . status_code < 400 , key_func = get_ID )
2022-11-14 15:11:05 +00:00
@auth_required
2023-07-30 00:42:06 +00:00
def unequip_hat ( v , hat_id ) :
2023-03-16 06:27:58 +00:00
hat = g . db . query ( Hat ) . filter_by ( hat_id = hat_id , user_id = v . id ) . one_or_none ( )
2022-10-11 13:01:39 +00:00
if not hat : abort ( 403 , " You don ' t own this hat! " )
2022-09-05 03:44:24 +00:00
hat . equipped = False
2023-03-16 06:27:58 +00:00
g . db . add ( hat )
2022-09-02 23:58:55 +00:00
2022-09-11 14:32:00 +00:00
return { " message " : f " ' { hat . name } ' unequipped! " }
2022-09-03 19:36:50 +00:00
2022-12-29 10:39:10 +00:00
@app.get ( " /hat_owners/<int:hat_id> " )
2023-07-13 13:50:46 +00:00
@limiter.limit ( DEFAULT_RATELIMIT , deduct_when = lambda response : response . status_code < 400 )
@limiter.limit ( DEFAULT_RATELIMIT , deduct_when = lambda response : response . status_code < 400 , key_func = get_ID )
2022-09-03 19:36:50 +00:00
@auth_required
2023-07-30 00:42:06 +00:00
def hat_owners ( v , hat_id ) :
2023-05-05 05:23:59 +00:00
page = get_page ( )
2022-09-03 19:36:50 +00:00
2023-08-08 14:49:00 +00:00
users = g . db . query ( User , Hat . created_utc ) . join ( Hat . owners ) . filter ( Hat . hat_id == hat_id )
2022-09-03 19:36:50 +00:00
2023-05-05 21:44:24 +00:00
total = users . count ( )
2023-05-05 21:45:25 +00:00
2023-05-05 21:44:24 +00:00
users = users . order_by ( Hat . created_utc . desc ( ) ) . offset ( PAGE_SIZE * ( page - 1 ) ) . limit ( PAGE_SIZE ) . all ( )
2022-09-03 19:36:50 +00:00
2023-08-08 14:49:00 +00:00
return render_template ( " owners.html " , v = v , users = users , page = page , total = total , kind = " Hat " )