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-02-26 08:41:04 +00:00
@limiter.limit ( DEFAULT_RATELIMIT )
2023-01-21 04:39:46 +00:00
@limiter.limit ( DEFAULT_RATELIMIT , key_func = get_ID )
2022-11-14 15:11:05 +00:00
@auth_required
2022-11-26 21:00:03 +00:00
def hats ( v : User ) :
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-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 " :
hat_count = [ x [ 0 ] for x in g . db . query ( Hat . hat_id ) . group_by ( Hat . hat_id ) . order_by ( func . count ( Hat . hat_id ) . desc ( ) ) . all ( ) ]
if SITE == ' rdrama.net ' :
2023-05-05 05:01:36 +00:00
hats = sorted ( hats . all ( ) , key = lambda x : hat_count . index ( x [ 0 ] . id ) if x [ 0 ] . id in hat_count else 0 )
2023-05-05 03:13:17 +00:00
else :
2023-05-05 06:06:31 +00:00
hats = sorted ( hats . all ( ) , key = lambda x : hat_count . index ( x . id ) if x . id in hat_count else 0 , reverse = True )
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 :
equipped = hats . filter ( HatDef . submitter_id == None , 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 . submitter_id == None , HatDef . id . in_ ( owned_hat_ids ) , HatDef . id . notin_ ( v . equipped_hat_ids ) ) . order_by ( HatDef . price , HatDef . name ) . all ( )
owned = equipped + not_equipped
else :
owned = hats . filter ( HatDef . submitter_id == None , HatDef . id . in_ ( owned_hat_ids ) ) . order_by ( HatDef . price , HatDef . name ) . all ( )
not_owned = hats . filter ( HatDef . submitter_id == None , HatDef . id . notin_ ( owned_hat_ids ) ) . order_by ( HatDef . price == 0 , HatDef . price , HatDef . name ) . all ( )
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
return render_template ( " hats.html " , owned_hat_ids = owned_hat_ids , hats = hats , v = v , sales = sales , num_of_hats = num_of_hats , next_exists = 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 )
2022-10-23 19:43:32 +00:00
@limiter.limit ( ' 100/minute;1000/3 days ' )
2023-01-21 04:39:46 +00:00
@limiter.limit ( ' 100/minute;1000/3 days ' , key_func = get_ID )
2022-09-02 23:58:55 +00:00
@auth_required
2022-11-26 21:00:03 +00:00
def buy_hat ( v : User , hat_id ) :
2022-09-02 23:58:55 +00:00
try : hat_id = int ( hat_id )
2022-10-11 13:01:39 +00:00
except : abort ( 404 , " Hat not found! " )
2022-09-02 23:58:55 +00:00
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
2022-09-16 21:57:56 +00:00
if v . num_of_owned_hats > = 250 :
2022-09-03 00:54:17 +00:00
badge_grant ( user = v , badge_id = 154 )
2022-09-16 21:57:56 +00:00
elif v . num_of_owned_hats > = 100 :
2022-09-03 00:54:17 +00:00
badge_grant ( user = v , badge_id = 153 )
2022-09-16 21:57:56 +00:00
elif v . num_of_owned_hats > = 25 :
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-02-26 08:41:04 +00:00
@limiter.limit ( DEFAULT_RATELIMIT )
2023-01-21 04:39:46 +00:00
@limiter.limit ( DEFAULT_RATELIMIT , key_func = get_ID )
2022-11-14 15:11:05 +00:00
@auth_required
2022-11-26 21:00:03 +00:00
def equip_hat ( v : User , hat_id ) :
2022-09-02 23:58:55 +00:00
try : hat_id = int ( hat_id )
2022-10-11 13:01:39 +00:00
except : abort ( 404 , " Hat not found! " )
2022-09-02 23:58:55 +00:00
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-02-26 08:41:04 +00:00
@limiter.limit ( DEFAULT_RATELIMIT )
2023-01-21 04:39:46 +00:00
@limiter.limit ( DEFAULT_RATELIMIT , key_func = get_ID )
2022-11-14 15:11:05 +00:00
@auth_required
2022-11-26 21:00:03 +00:00
def unequip_hat ( v : User , hat_id ) :
2022-09-05 03:44:24 +00:00
try : hat_id = int ( hat_id )
2022-10-11 13:01:39 +00:00
except : abort ( 404 , " Hat not found! " )
2022-09-05 03:44:24 +00:00
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-02-26 08:41:04 +00:00
@limiter.limit ( DEFAULT_RATELIMIT )
2023-01-21 04:39:46 +00:00
@limiter.limit ( DEFAULT_RATELIMIT , key_func = get_ID )
2022-09-03 19:36:50 +00:00
@auth_required
2022-11-26 21:00:03 +00:00
def hat_owners ( v : User , hat_id ) :
2022-09-03 19:36:50 +00:00
try : hat_id = int ( hat_id )
2022-11-16 12:52:16 +00:00
except : abort ( 404 , " Hat not found! " )
2022-09-03 19:36:50 +00:00
2023-05-05 05:23:59 +00:00
page = get_page ( )
2022-09-03 19:36:50 +00:00
2023-03-16 06:27:58 +00:00
users = [ x [ 1 ] for x in g . db . query ( Hat , User ) . join ( Hat . owners ) . filter ( Hat . hat_id == hat_id ) . offset ( PAGE_SIZE * ( page - 1 ) ) . limit ( PAGE_SIZE + 1 ) . all ( ) ]
2022-09-03 19:36:50 +00:00
2022-10-29 03:20:48 +00:00
next_exists = ( len ( users ) > PAGE_SIZE )
users = users [ : PAGE_SIZE ]
2022-09-03 19:36:50 +00:00
2022-09-05 20:23:35 +00:00
return render_template ( " user_cards.html " ,
2022-09-04 23:15:37 +00:00
v = v ,
users = users ,
next_exists = next_exists ,
page = page ,
2022-11-21 08:52:22 +00:00
user_cards_title = " Hat Owners " ,
2022-09-29 05:43:29 +00:00
)