
    sojAY                        d dl Z d dlmZ d dlmZmZ d dlmZ d dlmZ d dl	m
Z d dlmZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dl m!Z! d dl"m#Z# d dl$m%Z% d dl&m'Z'm(Z(m)Z) d dl*m+Z+ d dl,m-Z- d dl.m/Z/ d dl0m1Z1m2Z3 d dl4m5Z5 d dl6m7Z7 d dl8m9Z9 d dl:m;Z; d dl<m=Z= d dl>m?Z? d dl@mAZAmBZBmCZCmDZDmEZEmFZFmGZG d dlHmIZImJZJmKZK d d lLmMZM d d!lNmOZO d d"lPmQZQmRZRmSZSmTZTmUZUmVZV 	 	 dLd#ed$e!d%e7d&eWd'ed(dfd)ZXd#ed(eYe         fd*ZZ	 dMd#ed,e[d(eWfd-Z\dNd.e5d(eYe         fd/Z]d(e[fd0Z^d1ej_        d(dfd2Z`d3ed1ej_        d4e!d5ed(df
d6Zad#ed(dfd7ZbdOd#ed9e[d(dfd:Zcd1ej_        d(dfd;Zd	 dOd4e!d<e1d=eed>e[d(eef
d?Zfd4e!d<e1d@egd(egfdAZhd4e!d(e[fdBZi	 dNd1ej_        dCeYe!         d(dfdDZjdEegd(eYe         fdFZkd1ej_        d(dfdGZld(efdHZmdOd#edIe[d(eWfdJZnd#ed(e?fdKZodS )P    N)datetime)UpdateMessage)TelegramError)ContextTypes)phrases)Crew)
DevilFruit)DevilFruitAbility)DevilFruitTrade)	GroupChat)Leaderboard)LeaderboardUser)LegendaryPirate)Warlord)User)	AssetPath)Emoji)DevilFruitExpiredNotification#DevilFruitRevokeWarningNotificationDevilFruitRevokeNotification)ReservedKeyboardKeys)SavedMediaName)Screen)DevilFruitAbilityTypeSign)DevilFruitCategory)DevilFruitSource)DevilFruitStatus)DevilFruitTradeStatus)DevilFruitValidationException)Keyboard)get_datetime_in_future_daysget_random_time_between_by_cron get_random_time_between_by_hoursget_datetime_in_future_hoursget_remaining_time_in_minutesdatetime_is_beforedefault_datetime_format)	log_errorescape_valid_markdown_charsfull_media_send)send_notification)get_random_item_from_txt)add_percentage_to_valuesubtract_percentage_from_valueget_random_winget_cumulative_percentage_sumformat_percentage_valueget_random_intdevil_fruitreceiversourcereasondevil_fruit_tradereturnc                    | j         rM|t          j        t          j        fvr3| j         }t	          d|                                  d|j                   |t          j        u r|st	          d          || _         t          j	        | _
        |t          j        t          j        t          j        fv rHt          t          j                                                  | _        t%          j                    | _        |                                  |t-                      }| |_        ||_        ||_        ||_        t6          j        |_
        t%          j                    |_        |                                 t-          j        |            dS )z
    Give a devil fruit to a user
    :param devil_fruit: The devil fruit
    :param receiver: The receiver
    :param source: The source
    :param reason: The reason
    :param devil_fruit_trade: The devil fruit trade already created
    Devil fruit z is already owned by zGA reason must be provided when giving a devil fruit to a user via ADMINN)ownerr   USERSHOPr!   get_full_name
tg_user_idADMINr   	COLLECTEDstatusBOTDAILY_REWARD_PRIZEr#   EnvDEVIL_FRUIT_EXPIRATION_DAYSget_intexpiration_dater   nowcollection_datesaver   r5   r6   r7   r8   r    	COMPLETED	date_solddelete_pending_trades)r5   r6   r7   r8   r9   r=   s         '/app/src/service/devil_fruit_service.pygive_devil_fruit_to_userrR   >   s   "  
V,<,ACSCX+YYY!'+_;4466__UM]__
 
 	

 !''''+U
 
 	

 !K)3K +  
 'B+3355'
 '
# '/lnn#  -<->->$/!!)%%4>"*,.. )+66666    c                 j    t          j                                        t           j        | k              S )zj
    Get the devil fruit abilities
    :param devil_fruit: The devil fruit
    :return: The abilities
    )r   selectwherer5   r5   s    rQ   get_devil_fruit_abilitiesrX   |   s*     #%%++,=,I[,XYYYrS   T
add_headerc                    t          |           }|rt          j        nd}| j        r|t          j        z  }n|s| j        rr|D ]n}t          |j                  }|t          j        	                    t          j        |                                |                                |j                  z  }on|t          j        z  }|S )a  
    Get devil fruit abilities text
    :param devil_fruit: The devil fruit
    :param add_header: Whether to add the header
    :param always_show_abilities: Whether to always show the abilities, even if the Devil Fruit has
     never been eaten
    :return: The text
     )rX   r   DEVIL_FRUIT_ABILITY_TEXTis_defective#DEVIL_FRUIT_ABILITY_DEFECTIVE_SMILEshould_show_abilitiesr   ability_typeDEVIL_FRUIT_ABILITY_TEXT_LINEformatr   LOG_POSITIVEget_descriptionget_signvalueDEVIL_FRUIT_ABILITY_UNKNOWN)r5   rY   always_show_abilities	abilitiesabilities_textabilityr`   s          rQ   get_devil_fruit_abilities_textrl      s     *C;)O)OI>HP'::bN >'EE	 >+"C >  	 	G2GH\2]2]LgCJJ",,..%%''	  NN	 	'==rS   categoryc                    t          j                                        t           j                            t          j                                        }| r#|                    t           j        | k              }t          |          S )zx
    Get all devil fruits in circulation
    :param category: The category (optional)
    :return: The devil fruits
    )	r
   rU   rV   rD   in_r   get_released_statusesrm   list)rm   querys     rQ   get_devil_fruits_in_circulationrs      so     %%.DFFGG E  =J/8;<<;;rS   c                      dS )z
    Checks if a Devil Fruit should be released based on the number of Devil Fruits in circulation
    and the number of
    active users
    :return: Whether a Devil Fruit should be released
    T ru   rS   rQ   should_release_devil_fruitrv      s	     4rS   contextc                 P  K   t                      sdS t          j                                        t          j        t
          j        k    t          j        t          j	        k    z  t          j        t          j
        k    z                                t          j                                                                                  }|sKt          j                            d          }t%          | |           d{V  t'          j        |           dS t+          |d           dS )zF
    Schedule devil fruit release
    :param context: The context
    Nz"Any (non-Mythical Zoan, non-Smile)Tis_new_release)rv   r
   rU   rV   rD   r   ENABLEDrm   r   MYTHICAL_ZOANSMILEorder_byidascget_or_noner   NO_DEVIL_FRUIT_TO_SCHEDULErb   r*   loggingerrorset_devil_fruit_release_date)rw   r5   ot_texts      rQ   schedule_devil_fruit_releaser      s      &''  		"2":: $6$DDF $6$<<>

 


 
*-##%%	&	&	   4;;<`aa)))))))))g TBBBBBBrS   updateuser
group_chatc           
        K   ddl m} ddlm}  |            }t	          |j                  sdS |                                5 }t          j                    	                    t          j
        t          j        k                                                                  t          j                                                                                  }|s	 ddd           dS t%          |j                  }		 d|	z  dz  }
n# t&          $ r d}
Y nw xY wt)          |
          s>t+          t,          j                                                  |_        	 ddd           dS t2          j                            |                                t;          |                                          t?          |j                   !                                tE          |d                    }tG          |          gg}	 ||_$        tK          ||tL          j'                    |            |_        tQ          |tR          j*        ||| d	d
           d{V }|j+        |_,        |-                                 nQ# t\          t^          f$ r=}|0                                 tc          j2        d|j3         d|            Y d}~nd}~ww xY wddd           dS # 1 swxY w Y   dS )z
    Release a Devil Fruit to a user
    :param update: The update
    :param context: The context
    :param user: The user
    :param group_chat: The group chat
    :return: None
    r   )init)get_next_bounty_reset_timeN   d   Frh   T)saved_media_namecaptionkeyboardr   new_messagequote_if_groupz!Error giving devil fruit to user z: )4src.chat.manage_messager   src.service.bounty_servicer   r(   (devil_fruit_collection_cooldown_end_dateatomicr
   rU   rV   rD   r   	SCHEDULED
for_updater~   release_dater   r   r'   ZeroDivisionErrorr1   r&   rG   %DEVIL_FRUIT_COLLECT_COOLDOWN_DURATIONrI   r    DEVIL_FRUIT_RELEASE_MESSAGE_INFOrb   get_markdown_mentionr+   r@   r   rm   rd   rl   get_manage_deeplink_keyboardrelease_group_chatrR   r   rE   r,   r   DEVIL_FRUIT_NEW
message_idrelease_message_idrM   r   r!   rollbackr   r   rA   )r   rw   r   r   r   r   dbtransactionr5   minutes_to_releaseprobabilitytextinline_keyboardmessagees                  rQ   release_devil_fruit_to_userr      s      -,,,,,EEEEEE	BdKLL 	 ?V U:$(8(BBCCZ\\Xj-113344[]] 	  	?V ?V ?V ?V ?V ?V ?V ?V #@@X"Y"Y	"#&8"8C!?KK  	 	 	KKK	 k** 	<X9AACC= =D9 3?V ?V ?V ?V ?V ?V ?V ?V8 7>>%%'''(A(A(C(CDD{344DDFF*;eTTT	
 
 3O{2[2[1\0]	V
 .8K*$[$8H8LMMM<V<V<X<XD9 &5!/!?( $& & &            G .5-?K*<= 	V 	V 	V  """MTdoTTQRTTUUUUUUUU	V{?V ?V ?V ?V ?V ?V ?V ?V ?V ?V ?V ?V ?V ?V ?V ?V ?V ?Vsp   BK%K:DKDKDAK"BK:A7I21K2K 3J;6K;K  KKKc                 T   |                                  t          j        ur%t          d|                                  d          |                                 t          j        t          j        fv r%t          d|                                  d          t          | d           dS )zl
    Force schedule a devil fruit for release
    :param devil_fruit: The devil fruit
    :return: None
    r<   z, must be in ENABLED status to force schedulez cannot be force scheduledTry   N)

get_statusr   r{   r!   r@   get_categoryr   r|   r}   r   rW   s    rQ   force_schedule_devil_fruitr   7  s     '7'???+d;4466ddd
 
 	
 !!&8&FHZH`%aaa+R;4466RRR
 
 	
 !TBBBBBBrS   Frz   c                 x   d| _         t          j        |            |                                 t          j        u r't          j        | _        | 	                                 dS t                      s't          j        | _        | 	                                 dS |r,t          t          j                                                  }n+t!          t          j                                                  }d| _        d| _        d| _        || _        d| _        t          j        | _        | 	                                 dS )z
    Set the release date of a devil fruit
    :param devil_fruit: The devil fruit
    :param is_new_release: Whether this is a new release
    :return: None
    NrW   )r=   r   rP   r   r   r}   r   rN   rD   rM   rv   r{   r$   rG   &CRON_SCHEDULE_DEVIL_FRUIT_ZOAN_RELEASEgetr%   DEVIL_FRUIT_RESPAWN_HOURSrI   
eaten_daterJ   rL   r   r   r   )r5   rz   r   s      rQ   r   r   K  s(    K )kBBBB !!%7%===-7%'' -5  a66::<<
 
 88U8]8]8_8_``!K"&K"&K+K%)K")3KrS   c                   K   t          j                                        t           j        t          j        k    t           j        t          j        k    t           j        t          j	        k    z  z  t           j
        t          j                    k    z            }|D ]>}|j        }t          |           t          |          }t!          | ||           d{V  ?dS )zO
    Respawn Devil Fruit
    :param context: The context
    :return: None
    N)r
   rU   rV   rD   r   rC   EATENrm   r   r}   rJ   r   rK   r=   r   r   r-   )rw   devil_fruitsr5   r=   notifications        rQ   respawn_devil_fruitr   t  s       &0%6%8%8%>%>"2"<<"&6&<<&*<*BBD %7	9	& 	&L $ > >!'$[111 5[AA==========> >rS   r`   rf   add_to_valuec                    g }t          j        | |          }||                    |           |                                 r/| j        }|                    |                    |                     t          |          dk    r|S |                                }t          t          d |D                                 }|t          j        k    r|r||z   S t          ||          S |r||z
  S t          ||          S )a  
    Given a value, gets the updated value if user has eaten a Devil Fruit that modifies it
    :param user: The user
    :param ability_type: The ability type
    :param value: The value
    :param add_to_value: Whether to add to the value
    :return: The value
    Nr   c                     g | ]	}|j         
S ru   )rf   ).0rk   s     rQ   
<listcomp>z%get_ability_value.<locals>.<listcomp>  s    &N&N&Nw}&N&N&NrS   )r   get_user_abilityappendis_crew_membercrewextendget_active_abilitylenre   r3   r2   DevilFruitAbilityTypeSignPOSITIVEr/   r0   )	r   r`   rf   r   ri   devil_fruit_abilityr   ability_type_signability_values	            rQ   get_ability_valuer     s&    *,I .?-OPTVb-c-c&,---  @Y00>>???
9~~3?3H3H3J3J+%&N&NI&N&N&NOO M
 5>>> 	A=((*5-@@@  %}$$)%???rS   hoursc                 B    t          | ||          }t          |          S )z
    Given a value, get the updated datetime if user has eaten a Devil Fruit that modifies it
    :param user: The user
    :param ability_type: The ability type
    :param hours: The hours
    :return: The value
    )r   r&   )r   r`   r   	new_hourss       rQ   get_ability_adjusted_datetimer     s#     )|UCCI'	222rS   c                     t          j                                        t           j        | k    t           j        t
          j        k    z                                            S )z{
    Check if user has eaten a Devil Fruit
    :param user: The user
    :return: Whether user has eaten a Devil Fruit
    )r
   rU   rV   r=   rD   r   r   exists)r   s    rQ   user_has_eaten_devil_fruitr     sD     		
 D(Z->BRBX-XY	Z	Z	rS   usersc                    K   t          t          j                                        dz
            }|D ]9}||3|j        |v r*t          | |j        t          |                     d{V  :dS )z
    Warn inactive users with eaten Devil Fruits

    :param context: The context object
    :param users: The users to warn. If provided, it will only warn these users, else it will warn
    all inactive users
    :return: None
    r   NrW   )*get_inactive_users_with_eaten_devil_fruitsrG   6DEVIL_FRUIT_MAINTAIN_MIN_LATEST_LEADERBOARD_APPEARANCErI   r=   r-   r   )rw   r   inactive_users_devil_fruitsr5   s       rQ   *warn_inactive_users_with_eaten_devil_fruitr     s       #MBJJLLqP# # 3  =U.;3D3M3M#!3LLL         rS   latest_leaderboard_appearancec                 L   t          j        |           }t          j                                                                        t                                        t                                        t                                         t          j	        t          j        k    t           j                            |          z                                            }t          |          }t          j                                                                        t                                        t          j	        t          j        k    t          j        dk    z  t          j        dk    z  t          j                            t'          j                              z  t          j                            t+          j                              z  t          j                            d |D                       z                                            }t          |          S )z
    Find Devil Fruits eaten by users that have not appeared in the latest N leaderboards

    :param latest_leaderboard_appearance: The latest leaderboard appearance
    :return: The inactive captains
    )nFc                     g | ]	}|j         
S ru   )r   )r   dfs     rQ   r   z>get_inactive_users_with_eaten_devil_fruits.<locals>.<listcomp>!  s    $O$O$OrRU$O$O$OrS   )r   get_latest_nr
   rU   distinctjoinr   r   rV   rD   r   r   r   ro   executerq   is_admin.is_exempt_from_global_leaderboard_requirementsnot_inr   get_active_user_idsr   )r   latest_leaderboardsrr   eaten_active_devil_fruitsinactive_devil_fruitss        rQ   r   r     s    .9-E
'. . . 			d	o			k			"2"88~!!"5668

 

 
 
 37u++ 			d	"2"88}%'BeKM w~~oACCDDF w~~g9;;<<	>
 }##$O$O5N$O$O$OPPR

 

 
  %&&&rS   c                    K   t          t          j                                                  }|D ]=}|j        }t          |           t          | |t          |                     d{V  >dS )zk
    Revoke Devil Fruits from inactive users

    :param context: The context object
    :return: None
    rW   N)r   rG   r   rI   r=   r   r-   r   )rw   r   r5   r=   s       rQ   &revoke_devil_fruit_from_inactive_usersr   )  s       #MBJJLL# # 3 
 
!'$[111  U8[QQQ
 
 	
 	
 	
 	
 	
 	
 	
 	

 
rS   c                  b   t                      } t          j        | _        t	          t
          j                  | _        d| _        | 	                                 t                      }| |_        t          j                    |_        t          dd          |_        |	                                 | S )z1
    Generate a SMILE
    :return: The SMILE
    Tr   r   )r
   r   r}   rm   r.   r   ANIMALSnamer_   rM   r   r5   r   get_random_abilityr`   r4   rf   )r5   rk   s     rQ   create_smiler   @  s     )llK-3K/	0ABBK(,K% "3!4!4G%G0CEEG"1c**GMLLNNNrS   add_sell_commandc                 6   d}d}d}|                                  t          j        u s |                                 t          j        u r| j        et          j        	                    t          | j        d                    }|                                  t          j        u r|t          j        z  }d}nt          j        d| j                   |                                 t          j        u r|r|dz  }|t          j        z  }|r,|                                  t          j        urt          j        }t%          | d          }t          j        	                    |                                 t	          | j                                                  |||          S )	z
    Get the recap text
    :param devil_fruit: The devil fruit
    :param add_sell_command: Whether to add the sell command
    :return: The text
    r[   FNT)add_remaining_timez9Devil Fruit %s in collected status has no expiration date
r   )r   r   rC   r   r   r}   rJ   r   *DEVIL_FRUIT_ITEM_DETAIL_TEXT_EXPIRING_DATErb   r)   "DEVIL_FRUIT_EXPIRATION_EXPLANATIONr   r   r   (DEVIL_FRUIT_SMILE_EXPIRATION_EXPLANATIONr   )DEVIL_FRUIT_ITEM_DETAIL_TEXT_SELL_COMMANDrl   DEVIL_FRUIT_ITEM_DETAIL_TEXTr@   rm   rd   )r5   r   expiring_date_textsell_command_text&has_standard_expiring_date_explanationrj   s         rQ   get_recap_textr   V  s    -2* 	  $4$>>>##%%);)AAA&2!(!S!Z!Z'(CX\]]]" " %%''+;+EEE"g&PP"9=6 MK[^  
 !!%7%===1 	'$&gNN NK2244<L<RRR#M3KW\]]]N/66!!##;/00@@BB  rS   c                 r    t          t          j        t          j        t
          j        | j        id          S )zl
    Get the manage deeplink keyboard
    :param devil_fruit: The devil fruit
    :return: The keyboard
    T)screeninfois_deeplink)r"   r   KEY_MANAGE_DEVIL_FRUITr   PVT_DEVIL_FRUIT_DETAILr   DEFAULT_PRIMARY_KEYr   rW   s    rQ   r   r     s7     &,"6G	   rS   )NN)TT)N)F)pr   r   src.tg_compatr   r   src.tg_compat.errorr   src.tg_compat.extr   resources.EnvironmentEnvironmentrG   	resourcesr   src.model.Crewr	   src.model.DevilFruitr
   src.model.DevilFruitAbilityr   src.model.DevilFruitTrader   src.model.GroupChatr   src.model.Leaderboardr   src.model.LeaderboardUserr   src.model.LegendaryPirater   src.model.Warlordr   src.model.Userr   src.model.enums.AssetPathr   src.model.enums.Emojir   src.model.enums.Notificationr   r   r   $src.model.enums.ReservedKeyboardKeysr   src.model.enums.SavedMediaNamer   src.model.enums.Screenr   1src.model.enums.devil_fruit.DevilFruitAbilityTyper   r   r   .src.model.enums.devil_fruit.DevilFruitCategoryr   ,src.model.enums.devil_fruit.DevilFruitSourcer   ,src.model.enums.devil_fruit.DevilFruitStatusr   1src.model.enums.devil_fruit.DevilFruitTradeStatusr    src.model.error.CustomExceptionr!   src.model.pojo.Keyboardr"   src.service.date_servicer#   r$   r%   r&   r'   r(   r)   src.service.message_servicer*   r+   r,    src.service.notification_servicer-   src.utils.file_utilsr.   src.utils.math_utilsr/   r0   r1   r2   r3   r4   strrR   rq   rX   boolrl   rs   rv   DEFAULT_TYPEr   r   r   r   r   floatr   intr   r   r   r   r   r   r   r   ru   rS   rQ   <module>r/     s          ) ) ) ) ) ) ) ) - - - - - - * * * * * * # # # # # #             + + + + + + 9 9 9 9 9 9 5 5 5 5 5 5 ) ) ) ) ) ) - - - - - - 5 5 5 5 5 5 5 5 5 5 5 5 % % % % % %       / / / / / / ' ' ' ' ' '         
 F E E E E E 9 9 9 9 9 9 ) ) ) ) ) )        N M M M M M I I I I I I I I I I I I S S S S S S I I I I I I , , , , , ,                  ` _ _ _ _ _ _ _ _ _ > > > > > > 9 9 9 9 9 9                )-;7 ;7;7;7 ;7 	;7
 ';7 
;7 ;7 ;7 ;7|Z: Z$?P:Q Z Z Z Z MQ )-   D .@ DQ[L\     D    C0I Cd C C C C>SVSV)6SV>BSVPYSV	SV SV SV SVlCJ C4 C C C C(& &j &$ &[_ & & & &R>|'@ >T > > > >: Y^+@ +@
+@3+@<A+@QU+@
+@ +@ +@ +@\3
333<?33 3 3 3T d     =A &/3Dz	   22'#&2'	*2' 2' 2' 2'j
,:S 
X\ 
 
 
 
.j    ,. .
 .d .s . . . .bj X      rS   