o
    Ej                     @  s  d dl mZ d dlZd dlZd dlZd dl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lmZmZ d d	lmZ d d
lmZmZmZmZmZmZmZmZmZ d dl m!Z!m"Z" ede#e$ef f Z%dZ&dZ'dZ(G dd dZ)d{ddZ*d|ddZ+d}ddZ,d~d"d#Z-dd%d&Z.dd.d/Z/dd4d5Z0dd6dd8d9Z1dd=d>Z2dd?d@Z3ddBdCZ4ddDdEZ5ddIdJZ6ddKdLZ7ddNdOZ8ddQdRZ9dddSddUdVZ:ddXdYZ;dd]d^Z<dd`daZ=ddedfZ>ddidjZ?ddkdlZ@ddpdqZAddrdsZBddudvZCddydzZDdS )    )annotationsN)Callable)datetime	timedeltatimezone)Path)Any)ALLOWED_ACTIONS)sanitize_provider_call_metricssummarize_provider_call_metrics)LocalJsonStore)	StateTransitionErrorassert_can_approve_buildassert_can_create_buildassert_can_download_packageassert_can_mark_package_readyassert_can_reserve_model_costassert_can_run_packageassert_can_start_full_buildassert_can_start_revision)enqueue_buildfind_next_queued_item.i   sixxie_monthly_launchcustom_pet_buildrevision_creditpackage_downloadpackage_runtime_accessc                   @  s  e Zd ZddddddZdddZdedddddddZdedddd%d&Zdd'd(Zdd*d+Z	dddddd,dd3d4Z
dd5dd:d;Zdd@dAZddDdEZddFddGddNdOZddTdUZddXdYZddZd[Zdd]d^Zdd_d`ZddcddZddedfZdddgddidjZddkdlZddmdnZddpdqZddrddtduZddvddydzZdd|d}Zdd~dZdddZdddZdddZ dS )LocalPetApiN)output_rootmedia_storagestorer   build_runnerBuildRunnerr   str | Path | Noner    
Any | NonereturnNonec                C  s@   || _ || _|rt|n|jjd | _|| _| jjddd d S )N
pet_buildsT)parentsexist_ok)r!   r"   r   pathparentr   r    mkdir)selfr!   r"   r   r     r/   6/opt/sixxie/releases/current/services/api/local_api.py__init__)   s
   zLocalPetApi.__init__dict[str, Any]c                 C  sz   | j d ur
| j  nddi}| jj o| j ot|d| jj r'dnd|dr/dnd| j r9ddS ddS )NokFmissing)r3   r!   storageoutput)r    healthr!   r+   existsr   boolget)r.   storage_healthr/   r/   r0   r7   7   s   "zLocalPetApi.healthcheckout)pet_id	plan_codesourceperiod_start
period_enduser_idstrr=   
str | Noner>   r?   r@   rA   c                C  s  | j  }t }t||| |d urt|||d t|||d |p#|}	|p)t|}
t|dd}|dkr6dnd}||||||d|	|
|
d||d	|d
i |< d }|dkr`t	||||d|d|d}t
||||||	|
|d}t|||d|d | j | ||tt|d|
dS )NrB   r=   )nowr>   subscriptionsubinvitestripeactiveF)subscription_idrB   r=   r>   providerr?   statuscurrent_period_startcurrent_period_endaccess_ends_atcancel_at_period_end
created_at
updated_atsubscriptions  )rB   r=   rL   rM   product_codeamount_total_centsrF   )rB   r=   rL   order_id	starts_at
expires_atrF   entitlement_grantedrB   r=   
event_namerF   subscription_active)rL   entitlement_idsentitlement_typesr?   user_visible_statusrP   )r!   transaction_now_ensure_user_require_owned_pet_ensure_default_price_plan_one_month_later_next_id
setdefault_create_paid_order_grant_monthly_entitlements_append_eventwritelistMONTHLY_ENTITLEMENT_TYPES)r.   rB   r=   r>   r?   r@   rA   staterF   rZ   r[   rL   rM   rY   r`   r/   r/   r0   grant_test_subscription@   sn   



z#LocalPetApi.grant_test_subscription   )max_usesgrant_plan_coder[   codert   intru   r[   c             
   C  s   |  std|dk rtd| j }t }t|dd}|t|d|d|d||p-t|d	|d	i |< | j	| |d
|dS )Nzinvite code is requiredrs   zmax_uses must be at least 1rI   invrK   r   )		invite_id	code_hashrN   rt   
used_countru   grant_monthsrS   r[   beta_invitesinvite_created)ry   rb   rt   )
strip
ValueErrorr!   rc   rd   ri   _hash_invite_coderh   rj   rn   )r.   rv   rt   ru   r[   rq   rF   ry   r/   r/   r0   create_test_invite   s,   

zLocalPetApi.create_test_invitec                C  s  | j  }t }t||| |d urt|||d t|||d}|d  d| }||di v r5tdt|d t|d krId	|d
< tdt|d d |d< t|d t|d krcd	|d
< |d ||d|d |< | j 	| | j
||t|dptd|t|dS )NrE   )rv   rF   ry   :invite_redemptionsz-invite has already been redeemed by this userr{   rt   used_uprN   zinvite has no remaining usesrs   )ry   rB   redeemed_atru   rI   )rB   r=   r>   r?   r@   rA   )r!   rc   rd   re   rf   _find_invite_by_coderj   r   rw   rn   rr   rC   r:   DEFAULT_PLAN_CODErh   )r.   rB   r=   rv   rq   rF   rI   redemption_keyr/   r/   r0   redeem_test_invite   s8   
zLocalPetApi.redeem_test_inviteestimated_cost_centsc          	      C  s   | j  }t|||d t }t||||d}t|ddt|dd }t||t|ddd t|dd| |d< ||d	< t|d
d}|	dg 
||d ||d|t|d t|dd d|d	 | j | |d |d |d ddS )NrE   )rB   r=   rF   
used_valuer   reserved_valuelimit_value  )current_cost_centsr   	cap_centsrT   usageuseusage_ledgerquota_idreservemodel_call_estimate)	usage_idr   rB   r=   
usage_typeamountbalance_afterreasonrS   model_cost_reserved)r   reserved_cost_centsr   rb   )r!   rc   rf   rd   _get_or_create_model_cost_quotarw   r:   r   ri   rj   appendrn   )	r.   rB   r=   r   rq   rF   quotacurrent_costr   r/   r/   r0   reserve_model_cost   s>   
 zLocalPetApi.reserve_model_cost)speciesbreedpersonality_notestypical_gesturesmemory_notespet_namer   r   r   r   r   c                C  s   |  std| j }t }	t|||	 t|dd}
|
||  |||||ddd|	|	d|d |
< t|||
d|	d	 | j| |
|  d|	d
S )Nzpet_name is requiredpetnot_requestedFready_for_media)r=   rB   r   r   r   r   r   r   consent_statusboundary_acknowledgedrN   rS   rT   pet_profilespet_profile_createdr]   )r=   display_namerb   rS   )	r   r   r!   rc   rd   re   ri   rm   rn   )r.   rB   r   r   r   r   r   r   rq   rF   r=   r/   r/   r0   
create_pet   s6   
zLocalPetApi.create_pet)original_filename
media_type	mime_typestorage_refr   c                C  s   | j  }t|||d}|dkrtdt }	t|dd}
|
|d |||||dd|	|	d	|d
 |
< t|||d|	d | j | |
dd|	dS )NrE   photoz%P0 local API only accepts photo mediamediamedr=   	uncheckedrK   media_idr=   rB   r   r   r   r   source_qualitydeletion_statusrS   rT   	pet_mediapet_media_uploadedr]   uploadedr   rb   quality_statusrS   )r!   rc   rf   r   rd   ri   rm   rn   )r.   rB   r=   r   r   r   r   rq   r   rF   r   r/   r/   r0   create_media_record  s2   

zLocalPetApi.create_media_recordfilenamecontent_typecontentbytesc                C  s   | j d u r	tdt|||d | j }t|||d}t }t|dd}	| j j||d |	|||d}
|	|d |d|||
d	d
||d|d |	< t	|||d|d t	|||d|d | j
| |	dd	|dS )Nzmedia storage is not configured)r   r   r   rE   r   r   r=   )rB   r=   r   r   r   r   r   passedrK   r   r   r   r]   pet_media_quality_passedr   r   )r    r   _assert_supported_image_uploadr!   rc   rf   rd   ri   	put_mediarm   rn   )r.   rB   r=   r   r   r   rq   r   rF   r   r   r/   r/   r0   upload_media_bytes6  sF   
	
	zLocalPetApi.upload_media_bytesr   r   c                C  s~   |dvrt d| j }t|d |d}t }||d< ||d< t||d |d |d	kr.d
nd|d | j| |||dS )N>   failedr   z'source_quality must be passed or failedr   r   r   rT   rB   r=   r   r   pet_media_quality_failedr]   )r   r   rT   )r   r!   rc   _requirerd   rm   rn   )r.   r   r   rq   r   rF   r/   r/   r0   mark_media_qualitye  s&   
zLocalPetApi.mark_media_qualityF)external_processor_nameexternal_processor_consent"external_processor_consent_versionr   r9   consent_versionr   r   r   c                C  s   |durt d| j }t|||d}	t }
|	d||
d|t|||r&|
nd d|
d
 t|||d|
d | j| |dd	|
d
S )NTz$boundary acknowledgement is requiredrE   grantedgeneration_allowed)
r   r   
consent_atr   r   r   r   external_processor_consent_atrN   rT   r   r]   ready_to_generate)r=   r   rb   rT   )	r   r!   rc   rf   rd   updater9   rm   rn   )r.   rB   r=   r   r   r   r   r   rq   r   rF   r/   r/   r0   grant_consent{  s2   

zLocalPetApi.grant_consent	media_ids	list[str]image_providerimage_modelc                  sD  | j  t d} fdd|D }tdd |D r$tdt|d t|dd	d |D d
 t }t	 d|d}	t
t|	dpKdt|	ddt|	dd|	d|d t|	| d tdd}
|
 dt|||di ||dd |
< t|
|d t |
d|d | j  |
d|dS )NrE   c                   s   g | ]
}t  |d qS ))rB   r=   r   )_require_owned_media.0r   r=   rq   rB   r/   r0   
<listcomp>      z,LocalPetApi.create_build.<locals>.<listcomp>c                 s  s    | ]
}| d dkV  qdS )r   rK   Nr:   r   itemr/   r/   r0   	<genexpr>  s    z+LocalPetApi.create_build.<locals>.<genexpr>z*active media is required before generationr   r   c                 S  s   g | ]}|d  qS )r   r/   r   r/   r/   r0   r         )r   r   media_quality_statusesr   rB   r=   entitlement_typerF   rN   inactivequantity_totalr   quantity_usedr[   entitlement_statusr   r   r[   rF   rF   event_user_idevent_pet_idbuildbldqueuedF)build_idr=   rB   rN   input_media_idsr   r   user_approvedapproval_answersrS   rT   r(   r   rF   pet_build_createdrB   r=   r   r^   rF   )r   rb   rS   )r!   rc   rf   anyr   r   r9   r:   rd   _find_active_entitlementr   rC   rw   _consume_entitlementri   ro   r   rm   rn   )r.   rB   r=   r   r   r   r   r   rF   build_entitlementr   r/   r   r0   create_build  s\   
	zLocalPetApi.create_buildr   revision_reasonc          	      C  sD  | j  }t|||d}|d dvs|ddurtdt }t|||d d|d	}tt|dp3d
t	|ddt	|dd|d|d t
|||||d d t|dd}|||d |dt|dpig |d|d|d d di ||d|d |< t|||d t|||d |d|d | j | ||d|dS ) NrB   r   rN   >   approvedpackage_readyr   Tz=approved build with user approval is required before revisionr=   r   r   r   r   r   r   r[   r   r   r   r   r   r   r   r      F)r   parent_build_idr=   rB   rN   r   r   r   r  r   r   rS   rT   r(   r   r   r   revision_queued)r   r  rb   rS   )r!   rc   _require_owned_buildr:   r   rd   r  r   rC   rw   r  ri   ro   r   rm   rn   )	r.   r   rB   r  rq   r   rF   entitlementrevision_build_idr/   r/   r0   request_revision  sd   

zLocalPetApi.request_revisionc                   s  | j   t d |d}t d |d d} fdd|d D }t }d	|d
< ||d< | j   | j| | dd |D | jd}| j   t d |d}t }t||| j|d t	 |||d t
 |d |d |d|d | j   |dd|dS )Nr(   r   r   r=   r   c                      g | ]
}t  d  |dqS r   r   r   r   rq   r/   r0   r     r   z-LocalPetApi.process_build.<locals>.<listcomp>r   
processingrN   rT   c                 S     g | ]}|  qS r/   copyr   r/   r/   r0   r     r   r   r   r   r   resultr   rF   r   r  rF   rB   pet_build_completedr   preview_readyTr   rb   preview_availablerT   )r!   rc   r   rd   rn   r"   r  r   _apply_build_success_append_provider_call_metricsrm   )r.   r   r   r   r   rF   r  r/   r  r0   process_build  s*   
&
zLocalPetApi.process_build	worker_idc                C  s   | j  }t|}|d u rtdt|d |d d}|d dkr1d|d< | j | | j|dS t }|d	|||d
 |d	||d | j | |d d	|dS )Nzqueued build not foundr(   r   r   rN   r   skipped)r$  r  )rN   
claimed_by
claimed_atrT   )rN   r&  rT   )r   rb   r'  )	r!   rc   r   KeyErrorr   rn   claim_next_buildrd   r   )r.   r$  rq   r   r   rF   r/   r/   r0   r)  ,  s8   
zLocalPetApi.claim_next_buildc          	        sB  | j   t d |d}|d dks|d|krtdt d |d d	} fd
d|d D }| j   | j| | dd |D | jd}| j   t d |d}t	 }t
||| j|d t |||d  dg D ]}|d|kr|d||d qst |d |d |d|d | j   |dd|dS )Nr(   r   rN   r  r&  z6build must be claimed by this worker before completionr   r=   r   c                   r  r  r  r   r  r/   r0   r   S  r   z6LocalPetApi.complete_claimed_build.<locals>.<listcomp>r   c                 S  r  r/   r  r   r/   r/   r0   r   V  r   r  r  r  build_queuer   	completed)rN   rT   completed_atrB   r  r   r  Tr  )r!   rc   r   r:   r   rn   r"   r  r   rd   r!  r"  rj   r   rm   )	r.   r   r$  r   r   r   r  rF   r   r/   r  r0   complete_claimed_buildM  s0   
&
z"LocalPetApi.complete_claimed_buildfailure_codefailure_reasonc          	      C  s   | j  }t|d |d}|d dks|d|krtdt }|d|t|||d |d	g D ]}|d
|krF|d||d q4t	||d |d |d|d | j 
| |d||dS )Nr(   r   rN   r  r&  z3build must be claimed by this worker before failurer   )rN   r.  r/  rT   r,  r*  r   )rN   rT   r.  rB   r=   pet_build_failedr   )r   rb   r.  rT   )r!   rc   r   r:   r   rd   r   _safe_failure_reasonrj   rm   rn   )	r.   r   r$  r.  r/  rq   r   rF   r   r/   r/   r0   fail_claimed_buildi  s0   
	zLocalPetApi.fail_claimed_buildc                 C  s|   | j  }t|d |d}|t|d |d dk|d d}|d dkr<t|dp+d	|d< tt|d
p7d|d
< |S )Nr(   r   rN   r  rT   r  r   r.  worker_errorr/  $Generation failed. Please try again.)r!   readr   _visible_build_statusrC   r:   r1  )r.   r   rq   r   payloadr/   r/   r0   	get_build  s   


zLocalPetApi.get_buildrM   r   rM   c                  s6   | j  } fdd|dg D }t| dS )Nc                   sL   g | ]"}t |tr$|d kr$r|dkr$ r"|d kr|qS )rB   rM   r   )
isinstancedictr:   r   r   rM   rB   r/   r0   r     s    z4LocalPetApi.get_provider_metrics.<locals>.<listcomp>provider_call_metricsr9  )r!   r5  r:   r   )r.   rB   rM   r   rq   metricsr/   r<  r0   get_provider_metrics  s
   

z LocalPetApi.get_provider_metricsc                 C  sR   | j  }t|d |d}|d dkrtd|d| dt|dp$td	d
S )Nr(   r   rN   r  2preview is only available for preview_ready buildsz/api/builds/z/preview/contact-sheetactionsT)r   preview_asset_urlrA  approval_required)r!   r5  r   r   ro   r:   r	   )r.   r   rq   r   r/   r/   r0   get_build_preview  s   

zLocalPetApi.get_build_previewc          	      C  s   | j  }t|||d}|d dkrtdt|dpd}t|dp&d}|r7t| s7dt|jv r;t	d	|rJt| sJdt|jv rNt	d
| j
| | }| s]tdt|| j
| d}|d|jt|jt| t|ddS )Nr  rN   r  r@  build_dir_ref preview_ref..z(preview build directory is not availablezpreview asset path is not safezpreview asset not found)preview_path
build_rootpreview_asset_readyascii)r   rb   r   r   sha256base64)r!   r5  r  r   rC   r:   r   is_absolutepartsr   r   r8   FileNotFoundError_preview_asset_bytesname_mime_type_for_assethashlibrM  	hexdigestrN  	b64encodedecode)	r.   r   rB   rq   r   rE  rG  rI  preview_bytesr/   r/   r0   get_build_preview_asset  s*   
z#LocalPetApi.get_build_preview_assetr   c                C  sx   | j  }t|||d}t|d |d t }|ddt|||d t|||d |d|d	 | j | |d|d
S )Nr  rN   )build_statusr   r  T)rN   r   r   approved_atrT   r=   pet_build_approvedr   )r   rb   r\  )	r!   rc   r  r   rd   r   r;  rm   rn   )r.   r   rB   r   rq   r   rF   r/   r/   r0   approve_build  s$   
	zLocalPetApi.approve_build)r   r   c                C  s4  | j  }t|||d}t }t|||d d|d}t|dp!d}t|d t|d |d t	|d	d
}	t
|dp=t}
tdd|t|ddt|dd|
d t|||||d d d|d< ||d< |	||d |d|d |
d||d
|d |	< t|||d |d|d | j | |	|dd|	 ddS )Nr  r=   r   r   rN   r   r   )r[  r   r   packagepkgrA  approved_for_downloadTchecksum_validruntime_compatible)package_statuspackage_user_approvedr   rb  rc  allowed_actionsr   r	  rT   output_package_ref)

package_idr   r=   rB   rN   package_storage_refrf  r   rS   rT   pet_packagespet_package_downloadedr   download_ready/api/packages/	/downloadrh  r   rb   download_url)r!   rc   r  rd   r  rC   r:   r   r9   ri   ro   r	   r   r  rm   rn   )r.   r   rB   r   rq   r   rF   download_entitlementeffective_entitlement_statusrh  rA  r/   r/   r0   create_package_download  s^   


z#LocalPetApi.create_package_download)rF   rh  rF   c                C  s   | j  }t|d |d}|d |krtd|pt }t|||d d|d}t|d t|d	t	|dp8d
|d|t|ddt|ddt
|dpStd |d|ddS )Nrj  r_  rB   package does not belong to userr=   r   r   rN   r   r   r[   rb  Trc  rf  )rd  re  runtime_entitlement_statusruntime_entitlement_expires_atrF   rb  rc  rf  runtime_access_granted)rh  rb   r[   )r!   r5  r   PermissionErrorrd   r  r   r9   r:   rC   ro   r	   )r.   rh  rB   rF   rq   r_  effective_nowruntime_entitlementr/   r/   r0   check_package_runtime_access  s4   

z(LocalPetApi.check_package_runtime_accessrW   c          	      C  s   | j  }t|||d}|d dks|ddurtdt }t|dd}t|d	d
}|||d |dd|dd|||d|di |< ||||d |dddd||d|di |< t|||d |d|d t|||d |d|d | j 	| |||d|dS )Nr  rN   r  r   Tz=approved build with user approval is required before checkoutorderordr  entr=   manualpaidUSDr   )rY   rB   r=   r   rM   rN   rW   currencyrX   rS   rT   paid_atordersr   rK   rs   )entitlement_idrB   rY   r=   r   typerN   r   r   rS   rT   entitlements
order_paidr   r\   )rY   r  r   rb   rS   )
r!   rc   r  r:   r   rd   ri   rj   rm   rn   )	r.   rB   r   rW   rq   r   rF   rY   r  r/   r/   r0   create_test_checkout=  sR   
z LocalPetApi.create_test_checkoutc                C  s   | j  }t|d |d}|d |krtdt }d|d< ||d< ||d< | jd ur3| j|d	  t|||d
 d|d | j | |d|dS )Nr   r   rB   zmedia does not belong to userdeletedr   
deleted_atrT   r   r=   pet_media_deletedr]   )r   r   rT   )	r!   rc   r   rx  rd   r    deleterm   rn   )r.   r   rB   rq   r   rF   r/   r/   r0   delete_mediak  s    

zLocalPetApi.delete_mediac                C  s\   | j  }t|d |d}|d |krtd|d dkr!td||d d	d
| ddS )Nrj  r_  rB   rt  rN   ra  z%package is not available for downloadr   rl  rm  rn  ro  )r!   r5  r   rx  r   )r.   rh  rB   rq   r_  r/   r/   r0   get_package_download~  s   

z LocalPetApi.get_package_downloadc             
   C  s4  | j  }t|d |d}|d |krtd|d dkr!tdt|d |d	 d
}t|dp2d}|rCt| sCdt|j	v rGtd| j
| d }|d }| sZtdt|jdd}	d|	d< t|	|d}
|
|	d< |
|	d< ||
 }| }||d	 d|	|
t|
t| t|ddgdS )Nrj  r_  rB   rt  rN   ra  z*package is not available for bundle exportr(   r   r   rE  rF  rH  z(package build directory is not availablezpet.jsonzpet package manifest not foundutf-8encodingTuserApproved)manifestpackage_dirspritesheetPathspritesheet_pathbundle_readyrL  )r   r   rM  rN  )rh  r   rb   r  assets)r!   r5  r   rx  r   rC   r:   r   rO  rP  r   r8   rQ  jsonloads	read_text_bundle_spritesheet_name
read_bytesrT  rU  rM  rV  rN  rW  rX  )r.   rh  rB   rq   r_  r   rE  r  pet_json_pathr  spritesheet_namer  asset_bytesr/   r/   r0   get_package_bundle  s@   
zLocalPetApi.get_package_bundlec                C  s   | j  }t|d |d}|d |krtdt }d|d< ||d< ||d< t|||d	 |d
 d|d | j | |d|dS )Nrj  r_  rB   rt  r  rN   r  rT   r=   r   pet_package_deletedr   )rh  rb   rT   )r!   rc   r   rx  rd   rm   rn   )r.   rh  rB   rq   r_  rF   r/   r/   r0   delete_package  s   
zLocalPetApi.delete_package)
r!   r   r"   r#   r   r$   r    r%   r&   r'   )r&   r2   )rB   rC   r=   rD   r>   rC   r?   rC   r@   rD   rA   rD   r&   r2   )
rv   rC   rt   rw   ru   rC   r[   rD   r&   r2   )rB   rC   r=   rD   rv   rC   r&   r2   )rB   rC   r=   rC   r   rw   r&   r2   )rB   rC   r   rC   r   rD   r   rD   r   rD   r   rD   r   rD   r&   r2   )rB   rC   r=   rC   r   rC   r   rC   r   rC   r   rD   r&   r2   )rB   rC   r=   rC   r   rC   r   rC   r   r   r&   r2   )r   rC   r   rC   r&   r2   )rB   rC   r=   rC   r   r9   r   rC   r   rD   r   r9   r   rD   r&   r2   )rB   rC   r=   rC   r   r   r   rC   r   rC   r&   r2   )r   rC   rB   rC   r  rC   r&   r2   )r   rC   r&   r2   )r$  rC   r&   r2   )r   rC   r$  rC   r&   r2   )
r   rC   r$  rC   r.  rC   r/  rC   r&   r2   )rB   rC   rM   rD   r   rD   r&   r2   )r   rC   rB   rC   r&   r2   )r   rC   rB   rC   r   r2   r&   r2   )r   rC   rB   rC   r   rD   r&   r2   )rh  rC   rB   rC   rF   rD   r&   r2   )rB   rC   r   rC   rW   rC   r&   r2   )r   rC   rB   rC   r&   r2   )rh  rC   rB   rC   r&   r2   )!__name__
__module____qualname__r1   r7   r   rr   r   r   r   r   r   r   r   r   r  r  r#  r)  r-  r2  r8  r?  rD  rZ  r^  rs  r{  r  r  r  r  r  r/   r/   r/   r0   r   (   sh    
H
!
(1
&
/
'
:
6

!

"


8
#
.

'r   r&   rC   c                   C  s   t tj ddS )N+00:00Z)r   rF   r   utc	isoformatreplacer/   r/   r/   r0   rd        rd   valuec                 C  s,   t | dd}|tdd  ddS )Nr  r     )days)r   fromisoformatr  r   r  )r  baser/   r/   r0   rh     s   rh   rq   r2   counterprefixc                 C  s8   t | d |dd | d |< | d| d | dS )Ncountersr   rs   _06d)rw   r:   )rq   r  r  r/   r/   r0   ri     s    ri   rB   rF   r'   c                 C  s   | d  ||d||d d S )NusersrK   )rB   rN   rS   rT   rj   )rq   rB   rF   r/   r/   r0   re     s   re   r>   c                C  s6   |  di  ||ddddddddd	d
d||d d S )Nprice_plansrJ   usdi  rV   monthrs      Tr   rK   )r>   rM   r  list_price_centsactive_price_centsbilling_intervalincluded_build_countincluded_revision_countincluded_package_download_countincluded_runtime_accessmodel_cost_cap_centsrN   rS   rT   r  )rq   rF   r>   r/   r/   r0   rg     s$   rg   r=   rD   rL   rM   rW   rX   rw   c          	      C  s:   t | dd}|||||d|d||||d| di |< |S )Nr|  r}  r  r  )rY   rB   r=   rL   rM   rN   rW   r  rX   rS   rT   r  r  )ri   rj   )	rq   rB   r=   rL   rM   rW   rX   rF   rY   r/   r/   r0   rk     s   rk   rY   rZ   r[   r   c                C  sf   ddddd}g }	t D ]%}
t| dd}|	| ||||||
d||
 d||||d| d	i |< q|	S )
Nrs   r  r   r  r~  rK   r   )r  rB   rY   rL   r=   r  rN   r   r   rZ   r[   rS   rT   r  )rp   ri   r   rj   )rq   rB   r=   rL   rY   rZ   r[   rF   
quantitiesr`   r   r  r/   r/   r0   rl     s0   
rl   )r=   r   c                C  s   d }|  di  D ]P}|d|ks|d|krq
|d ur)|dd |hvr)q
|dr?t|d |kr?t|}d|d< q
|ddkrZt|d	d
t|dd
k rZ|  S q
|d ura|S dd
d
d dS )Nr  rB   r  r=   r[   expiredrN   rK   r   r   r   r   )rN   r   r   r[   )rj   valuesr:   rC   r;  rw   )rq   rB   r   rF   r=   expired_candidater  r/   r/   r0   r  9  s,   
r  r  r   r   c                C  sx   | d}|stdt| ddd |d< t|d t| ddkr-d|d< ||d	< ||d
< t| ||d|d d S )Nr  zactive entitlement is requiredr   r   rs   r   consumedrN   consumed_atrT   entitlement_consumedr]   )r:   r   rw   rm   )rq   r  rF   r   r   r  r/   r/   r0   r  Y  s   

r  c                C  s   |  di  D ]}|d|kr#|d|kr#|ddkr#|  S qt| dd}|||ddd	d	d
||d
| d |< | d | S )Nquota_bucketsrB   r=   
quota_typemodel_cost_centsr   quor   r   rK   )
r   rB   r=   r  r   r   r   rN   rS   rT   )rj   r  r:   ri   )rq   rB   r=   rF   r   r   r/   r/   r0   r   r  s"   *r   rv   c                 C  s   t |  d S )Nr  )rU  rM  r   encoderV  )rv   r/   r/   r0   r     r  r   c                C  s|   t |}| di  D ]-}|d|krq|dr+t|d |kr+d|d< td|ddkr6td|  S td)	Nr}   rz   r[   r  rN   zinvite has expiredrK   zinvite is not active)r   rj   r  r:   rC   r   )rq   rv   rF   rz   rI   r/   r/   r0   r     s   r   
collectionkeylabelc                 C  s&   |  |}t|tst| d|S )Nz
 not found)r:   r:  r;  r(  )r  r  r  r   r/   r/   r0   r     s   

r   c                C  (   t | d |d}|d |krtd|S )Nr   r   rB   zpet does not belong to userr   rx  )rq   rB   r=   r   r/   r/   r0   rf        rf   r   c                C  s4   t | d |d}|d |ks|d |krtd|S )Nr   r   rB   r=   zmedia does not belong to petr  )rq   rB   r=   r   r   r/   r/   r0   r     s   r   r   c                C  r  )Nr(   r   rB   zbuild does not belong to userr  )rq   rB   r   r   r/   r/   r0   r    r  r  )r=   r   r^   c             
   C  s.   t | dd}| d |||||i |d d S )Neventevtevents)event_idrB   r=   r   r^   event_propertiesoccurred_at)ri   r   )rq   rB   r^   rF   r=   r   r  r/   r/   r0   rm     s   	rm   rN   c                 C  s   ddddddd | dS )	Nr   r  r  r  rl  r   )r   r  r  r  r	  r   draftr   )rN   r/   r/   r0   r6    s   r6  r  r  r   c                 C  sj   |d }|  r
dS t| dp| dpd}t| s%dt|jv r)td||   s3td|S )Nzspritesheet.pngr  r  rH  zpackage asset path is not safez!pet package spritesheet not found)r8   rC   r:   r   rO  rP  r   rQ  )r  r  preferred_pngr  r/   r/   r0   r    s   r  r   c                 C  sB   t | j }|dkrdS |dkrdS |dv rdS |dkrdS d	S )
N.png	image/png.webp
image/webp>   .jpg.jpeg
image/jpeg.htmlz	text/htmlzapplication/octet-stream)r   suffixlower)r   r  r/   r/   r0   rT    s   rT  rI  rJ  r   c                   sF   j  dkr S jdd}d fdd	}td
||dS )Nr  r  r  matchre.Match[str]r&   rC   c                   s   |  d}|  d}|dr|  dS t|}| r!|  dS j|  }z	|   W n ty?   |  d Y S w | sI|  dS t	|j
}t| d}d| d| d| | S )	Nquotesrc)data:zhttp://zhttps:///r   rL  zsrc=r  z;base64,)group
startswithr   rO  r,   resolverelative_tor   r8   rT  rS  rN  rW  r  rX  )r  r  r  	asset_ref
asset_pathr   encodedrJ  rI  r/   r0   replace_src  s$   






z)_preview_asset_bytes.<locals>.replace_srcz.src=(?P<quote>[\"'])(?P<src>[^\"']+)(?P=quote))r  r  r&   rC   )r  r  r  r  rerH   r  )rI  rJ  htmlr  r/   r  r0   rR    s
   rR  r   rootc              	   C  sJ   | d u rdS t | }zt| | W S  ttfy$   |j Y S w )NrF  )r   rC   r  r  OSErrorr   rS  )r  r  r+   r/   r/   r0   _safe_relative_ref
  s   
r  c                C  sJ   |  di  D ]}|d|kr"|d|kr"|ddkr" dS qdS )Nr  rB   r   rN   rK   r   )rj   r  r:   )rq   rB   r   r  r/   r/   r0   _entitlement_status_for_build  s   r  r   r  r   c                C  sz   | ddu rtd| dt|d t|d t| dptt| dd	t| d
d	t| d|||d	 d S )Nvalidation_okFz#generated package validation failedr  package_refrG  rA  rb  Trc  	build_dir)	rN   rg  rG  rA  rb  rc  rE  rT   r,  )r:   r   r   rC   ro   r	   r9   r  )r   r  r   rF   r/   r/   r0   r!    s   

r!  c                C  s`   t |dt|dpdt|dpdt|dpd|d}|r.| dg | d S d S )Nr=  rB   rF  r=   r   )rB   r=   r   rS   )r
   r:   rC   rj   extend)rq   r   r  rF   r>  r/   r/   r0   r"  1  s   r"  r   c                 C  s8   d| v sd| v sd|   v sd|   v rdS | d d S )Nr  \	tracebackstackr4  r
  )r  )r   r/   r/   r0   r1  C  s   (r1  r   r   c                 C  s   |st dt|tkrt d|dvrt dt| j }|r)|dvr)t d|dkr6|ds6t d	|d
krC|dsCt d|dkrX|drT|dd dksXt d|dkrj|dsl|dsnt dd S d S d S )Nzuploaded file is emptyzuploaded file is too large>   	image/gifr  r  r  z'uploaded file must be a supported image>   .gifr  r  r  r  z-uploaded filename must use an image extensionr  s   PNG

zuploaded PNG is not readabler  s   zuploaded JPEG is not readabler  s   RIFF      s   WEBPzuploaded WebP is not readabler  s   GIF87as   GIF89azuploaded GIF is not readable)r   lenMAX_UPLOAD_BYTESr   r  r  r  )r   r   r   r  r/   r/   r0   r   I  s$   "r   )r&   rC   )r  rC   r&   rC   )rq   r2   r  rC   r  rC   r&   rC   )rq   r2   rB   rC   rF   rC   r&   r'   )rq   r2   rF   rC   r>   rC   r&   r'   )rq   r2   rB   rC   r=   rD   rL   rC   rM   rC   rW   rC   rX   rw   rF   rC   r&   rC   )rq   r2   rB   rC   r=   rD   rL   rC   rY   rD   rZ   rC   r[   rC   rF   rC   r&   r   )rq   r2   rB   rC   r   rC   rF   rC   r=   rD   r&   r2   )rq   r2   r  r2   rF   rC   r   rC   r   rD   r&   r'   )
rq   r2   rB   rC   r=   rC   rF   rC   r&   r2   )rv   rC   r&   rC   )rq   r2   rv   rC   rF   rC   r&   r2   )r  r2   r  rC   r  rC   r&   r2   )rq   r2   rB   rC   r=   rC   r&   r2   )
rq   r2   rB   rC   r=   rC   r   rC   r&   r2   )rq   r2   rB   rC   r   rC   r&   r2   )rq   r2   rB   rC   r^   rC   rF   rC   r=   rD   r   rD   r&   r'   )rN   rC   r&   rC   )r  r2   r  r   r&   rC   )r   rC   r&   rC   )rI  r   rJ  r   r&   r   )r  r   r  r   r&   rC   )rq   r2   rB   rC   r   rC   r&   rC   )
r   r2   r  r2   r   r   rF   rC   r&   r'   )
rq   r2   r   r2   r  r2   rF   rC   r&   r'   )r   rC   r&   rC   )r   rC   r   rC   r   r   r&   r'   )E
__future__r   rN  rU  r  r  collections.abcr   r   r   r   pathlibr   typingr   packages.pet_package_schemar	   services.ai.provider_metricsr
   r   services.api.local_storer   services.api.state_guardsr   r   r   r   r   r   r   r   r    services.queue.local_build_queuer   r   r;  rC   r#   r  r   rp   r   rd   rh   ri   re   rg   rk   rl   r  r  r   r   r   r   rf   r   r  rm   r6  r  rT  rR  r  r  r!  r"  r1  r   r/   r/   r/   r0   <module>   sp    ,       
$





-
 
















