
    xh                        S SK Jr  S SKJr  S SKJr  S SKJr  S SKJ	r	  S SK
JrJrJr  S SKJr  S SKJr  S S	KJr  S S
KJrJr  S SKJr  S SKJrJrJr   " S S\\5      r " S S\	R<                  5      r " S S\5      r  " S S\5      r! " S S\!5      r" " S S\!5      r# " S S\	RH                  5      r% " S S\	R<                  5      r&g)    )urlparse)uuid4)settings)MaxValueValidator)models)CountQQuerySet)Cast)slugify)AutoSlugField)Issue
IssueEvent)clear_metrics_cache)AggregationModelCreatedModelSoftDeleteModelc                     ^  \ rS rSrSr\" SS/SS9r\R                  " SS9r	\R                  " S	\R                  S
S9r\R                  " SSSS9r\R                  " SS9r\R                   " SSS9r\R$                  " S\" S5      /SS9r " S S5      rS r\S\S\4S j5       rU 4S jrU 4S jrU 4S jrS rSrU =r $ ) Project   zf
Projects are permission based namespaces which generally
are the top level entry point for all data.
nameorganization_id2   )populate_from
max_length@   )r   zorganizations_ext.Organizationprojects)	on_deleterelated_nameT)r   blanknull)r!   z%Should project anonymize IP Addresses)default	help_textr   d   z_Probability (in percent) on how many events are throttled. Used for throttling at project level)r"   
validatorsr#   c                       \ rS rSrSrSrg)Project.Meta*   ))organizationslug N__name__
__module____qualname____firstlineno__unique_together__static_attributes__r+       /code/apps/projects/models.pyMetar'   *   s    5r3   r5   c                     U R                   $ N)r   selfs    r4   __str__Project.__str__-   s    yyr3   querysetuser_idc                     UR                  [        [        [        S[        US9SS9[        R
                  " 5       S9[        R                  " 5       S9S9$ )z2Add is_member boolean annotate to Project querysetteams__members)teams__members__user_idT)filterdistinct)output_field)	is_member)annotater   r   r	   r   IntegerFieldBooleanField)clsr<   r=   s      r4   annotate_is_memberProject.annotate_is_member0   s^       ( A!%
 "(!4!4!6 $002
 ! 
 	
r3   c                    > SnU R                   (       d  Sn[        TU ]  " U0 UD6  U(       a(  [        5         [        R
                  R                  U S9  g g )NFT)project)pksupersaver   
ProjectKeyobjectscreate)r9   argskwargsfirst	__class__s       r4   rO   Project.saveA   sJ    wwEd%f%!%%d%3 r3   c                 h   > SSK Jn  [        TU ]  " U0 UD6  UR	                  U R
                  5        g)z1Mark the record as deleted instead of deleting itr   )delete_projectN)apps.projects.tasksrY   rN   deletedelayrM   )r9   rS   rT   rY   rV   s       r4   r[   Project.deleteJ   s+     	7''TWW%r3   c                   > [         R                  R                  U S9nUR                  UR                  5        U R
                  R                  S5      n  UR                  SSS9SS R                  5       nUR                  US9R                  5         MA  ! [        R                   a     Of = fUR                  5         [        TU ]4  " U0 UD6  [        5         g)	z/Really delete the project and all related data.)issue__projectidT)flati  i  )id__lteN)r   rQ   rA   _raw_deletedbissuesorder_byvalues_listgetr[   r   DoesNotExistrN   force_deleter   )r9   rS   rT   	events_qs	issues_qsissue_delimiterrV   s         r4   rj   Project.force_deleteR   s     &&--T-B	ill+ KK((.	"+"7"74"7"H##%      9@@B  %%  	 	d-f-s   >B B.-B.c                 x    S/nSn[        U[        5      (       a  [        U R                  5      nX2;   a  US-  nU$ )z
Make the slug the project name. Validate uniqueness with both name and org id.
This works because when it runs on organization_id it returns an empty string.
new z-1)
isinstancestrr   r   )r9   contentreserved_wordsr*   s       r4   slugify_functionProject.slugify_functioni   s?    
  gs##499%D%r3   r+   )!r-   r.   r/   r0   __doc__r   r*   r   	CharFieldr   
ForeignKeyCASCADEr)   platformDateTimeFieldfirst_eventrG   scrub_ip_addressesPositiveSmallIntegerFieldr   event_throttle_rater5   r:   classmethodr
   intrI   rO   r[   rj   rv   r2   __classcell__)rV   s   @r4   r   r      s    
 0A'BrRDr*D$$(..L
 2TEH&&D1K,,9 !::%c*+s6 6 
( 
S 
 
 4&. r3   r   c                   p    \ rS rSrSr\R                  " \\R                  S9r	\R                  " 5       rSrg)ProjectCounterx   zv
Counter for issue short IDs
- Unique per project
- Autoincrements on each new issue
- Separate table for performance
r   r+   N)r-   r.   r/   r0   rx   r   OneToOneFieldr   r{   rL   PositiveIntegerFieldvaluer2   r+   r3   r4   r   r   x   s-     ""7fnnEG'')Er3   r   c                   Z   \ rS rSrSr\R                  " \\R                  S9r	\R                  " SS9r\R                  " SSS9r\R                  " \SSS	9r\R"                  " SSS
9r\R"                  " SSS
9r\R(                  " SSS
9rS r\S\4S j5       r\S 5       rS rS rS rSrg)rP      z Authentication key for a Projectr   T)r"   r   )r   r    F)r"   uniqueeditable)r    r!   c                 ,    [        U R                  5      $ r7   )rs   
public_keyr8   s    r4   r:   ProjectKey.__str__   s    4??##r3   dsnc                     [        U5      nUR                  nUR                  R                  SS5      S   n [        R
                  R                  X4S9$ ! [         a  n[        R                  S5      UeS nAff = f)N/   )r   rL   z)ProjectKey matching query does not exist.)	r   usernamepathrsplitrP   rQ   rh   
ValueErrorri   )rH   r   urlpartsr   
project_iderrs         r4   from_dsnProjectKey.from_dsn   s{    C=&&
]]))#q1"5
	%%))Z)TT 	 ));		s   A 
A:A55A:c                 .    U R                   R                  $ )zThe public key without dashes)r   hexr8   s    r4   public_key_hexProjectKey.public_key_hex   s     """r3   c                 "    U R                  5       $ r7   )get_dsnr8   s    r4   r   ProjectKey.dsn   s    ||~r3   c                     [         R                  nUR                  (       a  UR                  (       d  gUR                  < SU R                  < SUR                  UR
                  -   < SU R                  < 3$ )Nrq   ://@r   )r   GLITCHTIP_URLnetlocschemer   r   r   r9   r   s     r4   r   ProjectKey.get_dsn   sR    )) hoo OOOOhmm+OO	
 	
r3   c                     [         R                  nUR                  (       a  UR                  (       d  gUR                  < SUR                  UR                  -   < SU R
                  < SU R                  < 3$ )Nrq   r   z/api/z/security/?glitchtip_key=)r   r   r   r   r   r   r   r   s     r4   get_dsn_securityProjectKey.get_dsn_security   sP    ))hoo OOOOhmm+OO	
 	
r3   r+   N) r-   r.   r/   r0   rx   r   rz   r   r{   rL   rG   	is_activery   r   	UUIDFieldr   r   r   rate_limit_countrate_limit_window	JSONFielddatar:   r   rs   r   propertyr   r   r   r   r2   r+   r3   r4   rP   rP      s    *6>>BG##D1Ir6D!!%uMJ77dN88t$O$T2D$ 3    # #

r3   rP   c                   ^    \ rS rSr\R
                  " S\R                  S9r " S S5      rSr	g)ProjectStatisticBase   projects.Projectr   c                       \ rS rSrSrSrSrg)ProjectStatisticBase.Meta   ))rL   dateTr+   N)r-   r.   r/   r0   r1   abstractr2   r+   r3   r4   r5   r      s    0r3   r5   r+   N)
r-   r.   r/   r0   r   rz   r{   rL   r5   r2   r+   r3   r4   r   r      s#     2fnnMG r3   r   c                   >    \ rS rSr " S S\R
                  5      rSrg)&TransactionEventProjectHourlyStatistic   c                       \ rS rSrSrg)7TransactionEventProjectHourlyStatistic.PartitioningMeta   r+   Nr-   r.   r/   r0   r2   r+   r3   r4   PartitioningMetar          r3   r   r+   Nr-   r.   r/   r0   r   r   r2   r+   r3   r4   r   r          +<< r3   r   c                   >    \ rS rSr " S S\R
                  5      rSrg) IssueEventProjectHourlyStatistic   c                       \ rS rSrSrg)1IssueEventProjectHourlyStatistic.PartitioningMeta   r+   Nr   r+   r3   r4   r   r      r   r3   r   r+   Nr   r+   r3   r4   r   r      r   r3   r   c                       \ rS rSrSrSrSrg)ProjectAlertStatus   )r   off)r   onr+   N)r-   r.   r/   r0   OFFONr2   r+   r3   r4   r   r      s    
C	Br3   r   c                       \ rS rSrSr\R                  " S\R                  S9r\R                  " S\R                  S9r	\R                  " \R                  S9r " S S5      rS	rg
)UserProjectAlert   z
Determine if user alert notifications should always happen, never, or defer to default
Default is stored as the lack of record.
z
users.Userr   r   )choicesc                       \ rS rSrSrSrg)UserProjectAlert.Meta   )userrL   r+   Nr,   r+   r3   r4   r5   r      s    -r3   r5   r+   N)r-   r.   r/   r0   rx   r   rz   r{   r   rL   r   r   r   statusr5   r2   r+   r3   r4   r   r      sW    
 \V^^DD 2fnnMG--6H6P6PQF. .r3   r   N)'urllib.parser   uuidr   django.confr   django.core.validatorsr   	django.dbr   django.db.modelsr   r	   r
   django.db.models.functionsr   django.utils.textr   django_extensions.db.fieldsr   apps.issue_events.modelsr   r   apps.observability.utilsr   glitchtip.base_modelsr   r   r   r   Modelr   rP   r   r   r   IntegerChoicesr   r   r+   r3   r4   <module>r      s    !    4  / / + % 5 6 8 Q QdlO dN	*V\\ 	*@
 @
F+ -A 
'; 
.. 
.v|| .r3   