
    	]j                       d Z ddlZddl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mZ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mZ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(m)Z) ddl*m+Z+m,Z,m-Z- ddl.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9 ddl:m;Z; ddl<m=Z= ddl>m?Z@ ddlAmBZB ddlCmDZD ddlEmFZF ddlGmHZH ddlImJZJ ddlKmLZLmMZMmNZNmOZOmPZPmQZQmRZRmSZS ddlTmUZU ddlVmWZW ddlXmYZY ddlZm[Z[m\Z\m]Z]m^Z^m_Z_m`Z`  ej                  eb      Zc G d de,j                        Ze G d deFee      Zf G d  d!e,j                        Zh G d" d#eh      Zi ee$j                        Zk ee$j                        Zm G d$ d%ekeB      Zn G d& d'e,j                        Zp G d( d)e,j                        Zq G d* d+e,j                        Zr G d, d-e,j                        Zs G d. d/e,j                        Zt G d0 d1e,j                        Zu G d2 d3e,j                        Zvy)4zThis file and its contents are licensed under the Apache License 2.0. Please see the included NOTICE for copyright information and LICENSE for a copy of the license.
    N)AnyMappingOptional)AutoOneToOneField)CurrentContext)flag_set) check_control_in_config_by_regexcheck_toname_in_config_by_regexconfig_line_stippedextract_data_typesget_all_control_tag_tuplesget_all_labelsget_all_object_tag_namesget_all_typesget_annotation_tupleget_original_fromname_by_regexget_sample_taskvalidate_label_config)create_hashget_attr_or_item	load_funcmerge_labels_counters)batch_update_with_retry
fast_firsthas_column_cachedsettings)SearchVectorField)MaxLengthValidatorMinLengthValidator)
connectionmodelstransaction)AvgBooleanFieldCaseCountGeneratedField	JSONFieldMaxQSumValueWhen)RawSQL)cached_property)gettext_lazy)FsmHistoryStateModel)&update_project_state_after_task_change)FSMStateQuerySetMixin)parse_config)Label)annotate_finished_task_numberannotate_ground_truth_number#annotate_num_tasks_with_annotations#annotate_skipped_annotations_numberannotate_task_number!annotate_total_annotations_number!annotate_total_predictions_number!annotate_useful_annotation_number)make_queryset_from_iterable)ProjectSignals)ValidationError)
AnnotationAnnotationDraft
PredictionQ_task_finished_annotationsTaskbulk_update_stats_project_tasksc                       e Zd Zy)ProjectQuerySetN__name__
__module____qualname__     F/root/env/lib/python3.12/site-packages/label_studio/projects/models.pyrI   rI   E       rO   rI   c                       e Zd Zy)ProjectQuerySetWithFSMNrJ   rN   rO   rP   rS   rS   I   rQ   rO   rS   c            	       Z    e Zd ZdZg dZeeeee	e
eedZd Zd Zd Zd	dZed
d       Zy)ProjectManagerz
    Manager for Project model.

    Provides:
    - User-scoped filtering
    - Counter annotations for project statistics
    - FSM state annotation support
    )task_numberfinished_task_numbertotal_predictions_numbertotal_annotations_numbernum_tasks_with_annotationsuseful_annotation_numberground_truth_numberskipped_annotations_numberc                 D    t        | j                  | j                        S )z8Return ProjectQuerySet with FSM state annotation support)using)rS   model_dbselfs    rP   get_querysetzProjectManager.get_querysetm   s    %djjAArO   c                 V    | j                         j                  |j                        S )N)organization)rd   filteractive_organizationrc   users     rP   for_userzProjectManager.for_userq   s%      "))t7O7O)PPrO   c                 >    | j                         j                         S )z
        Return queryset with FSM state annotated.

        Example:
            projects = Project.objects.with_state().filter(organization=org)
            for project in projects:
                print(project.state)  # No N+1 queries!
        )rd   
with_staterb   s    rP   rm   zProjectManager.with_statet   s       "--//rO   Nc                 D    | j                  | j                         |      S )Nfields)with_counts_annotaterd   )rc   rp   s     rP   with_countszProjectManager.with_counts   s!    (():):)<V(LLrO   c                 
   t         j                  }||}n|D ci c]  }||v s|||    }}|r(|j                         D ci c]  \  }}||vs|| }}}|j                         D ]  \  }} ||       }  | S c c}w c c}}w N)rU   ANNOTATED_FIELDSitems)	querysetrp   excludeavailable_fieldsto_annotatefieldfunc_annotate_funcs	            rP   rq   z#ProjectManager.with_counts_annotate   s    )::>*KGMkeQVZjQj5"25"99kKk:E:K:K:Mf;5$QV^eQe5$;fKf + 1 1 3 	/A}$X.H	/  l gs   	A:A:A?A?rt   )NN)rK   rL   rM   __doc__COUNTER_FIELDSr;   r7   r=   r<   r9   r>   r8   r:   ru   rd   rk   rm   rr   staticmethodrq   rN   rO   rP   rU   rU   M   s[    	N , =$E$E&I$E;&I	BQ	0M  rO   rU   c                   "     e Zd ZdZ fdZ xZS )ProjectVisibleManagerzFDefault manager that hides soft-deleted projects (deleted_at IS NULL).c                     t         |          }t        | j                  j                  j
                  d      r|j                  d      S |S )N
deleted_atT)deleted_at__isnull)superrd   r   r`   _metadb_tablerg   )rc   qs	__class__s     rP   rd   z"ProjectVisibleManager.get_queryset   s@    W!#TZZ--66E99955	rO   )rK   rL   rM   r   rd   __classcell__r   s   @rP   r   r      s    P rO   r   c                   ~    e Zd Z G d dej                        Z e       Z e       Z	dZ
 ej                   ed      dddej                  dej                   dej                   d	 eej                         eej                        g
      Z ej&                   ed      dddd      Z ej*                  dej,                  dd      Z ej&                   ed      dddd      Z ej2                   ed      dddd      Z ej6                  dd      Z ej&                   ed      dddd      Z ej<                   ed      dd      Z ej<                   ed      dd      Z  ej<                   ed      dd       Z! ej<                   ed!      dd"      Z" ej<                   ed#      dd$      Z# ej<                   ed%      dd&      Z$ ej<                   ed'      dd(      Z% ej                   ed)      d*e&dd+      Z' ejP                   ed,      d-d.      Z) ej                   ed/      d0d1dd+      Z* ej*                  ejV                  d2ejX                  d ed3      4      Z- ejP                   ed5      d6d7      Z. ejP                   ed8      d-d9      Z/ e ed:      de0d;<      Z1 ej&                   ed=      dddd>      Z2 e ed?      e0d@      Z3 ej<                   edA      ddB      Z4 ej<                   edC      ddD      Z5 ejl                   edE      dF      Z7 ejl                   edG      dH      Z8dIZ9dJZ:dKZ;e9dLfe:dMfe;dNffZ< ej                  dOe<de9P      Z= ej                  dOej|                  dej~                  P      Z@ ej<                   edQ      ddR      ZA ej<                   edS      dddTU      ZB ej<                   edV      dW      ZC ejP                   edX      dOW      ZD ej                   edY      d*dddZ[      ZE ej                   ed\      d*ddd][      ZF ejl                   ed^      ddd_<      ZG ejP                   ed`      ddda<      ZH ejl                   edb      ddc      ZI ej*                  ejV                  ddejX                  ddd ede      f      ZJ ejl                   edg      ddc      ZK fdhZLeMdi        ZNeMdj        ZOeMdk        ZPeMdl        ZQeMdm        ZReMdn        ZSeMdo        ZTeMdp        ZUeMdq        ZVeMdr        ZWeMds        ZXeMdt        ZYeMdu        ZZeMdv        Z[eMdw        Z\eMdx        Z]e^dy        Z_dz Z`d{ Zad| Zbd} Zcd~ ZdddZed Zfd Zgd Zhd Zid Zjd Zkd Zle^d        ZmddZnd ZoeMd        Zpd ZqddZrd Zsddd fd
Ztd Zud Zvd ZwddZxd Zyd ZzeMd        Z{ddZ|d Z}d Z~d Zed        Zed        Zd Zd ZddZd Zd ZeMd        Zd Zd Zed        Zed        Zed        Zdedeeeef      fdZddZ	 	 ddeeeef      fdZd Zd Zd Zej6                  dk(  r e edg  e              e       d      Zn ej&                  ddc      Z G d d      Z xZS )Projectc                       e Zd ZdZdZdZy)Project.SkipQueue)REQUEUE_FOR_MEzRequeue for me)REQUEUE_FOR_OTHERSzRequeue for others)IGNORE_SKIPPEDzIgnore skippedN)rK   rL   rM   r   r   r   rN   rO   rP   	SkipQueuer      s    ;G;rO   r   NtitleT zProject name. Must be between z and z characters long.)nullblankdefault
max_length	help_text
validatorsdescriptionzProject description)r   r   r   r   zorganizations.Organizationprojects)	on_deleterelated_namer   zlabel configz<View></View>z>Label config in XML format. See more about it in documentationzparsed label configzFParsed label config in JSON format. See more about it in documentation)r   r   zexpert instructionz$Labeling instructions in HTML formatzshow instructionFz4Show instructions to the annotator before they startr   r   zshow skip buttonzEShow a skip button in interface and allow annotators to skip the taskzenable empty annotationz,Allow annotators to submit empty annotations#reveal_preannotations_interactivelyz$Reveal pre-annotations interactivelyzshow annotation historyz$Show annotation history to annotatorzshow predictions to annotatorz0If set, the annotator can view model predictionsz"evaluate predictions automaticallyz4Retrieve and display predictions when loading a tasktoken   )r   r   r   r   zresult countr   z+Total results inside of annotations countercolor   z#FFFFFFcreated_projectsz
created by)r   r   r   verbose_namezmaximum annotation number   zMaximum number of annotations for one task. If the number of annotations per task is equal or greater to this value, the task is completed (is_labeled=True)!min_annotations_to_start_trainingzGMinimum number of completed tasks after which model training is startedzcontrol weightsa  Dict of weights for each control tag in metric calculation. Each control tag (e.g. label or choice) will have it's own key in control weight dict with weight for each label and overall weight.For example, if bounding box annotation with control tag named my_bbox should be included with 0.33 weight in agreement calculation, and the first label Car should be twice more important than Airplaine, then you have to need the specify: {'my_bbox': {'type': 'RectangleLabels', 'labels': {'Car': 1.0, 'Airplaine': 0.5}, 'overall': 0.33}r   r   r   zmodel versionzMachine learning model version
data_types)r   r   zis draftz<Whether or not the project is in the middle of being created	publishedz5Whether or not the project is published to annotators
created atauto_now_add
updated atauto_nowzSequential samplingzUniform samplingzUncertainty samplingz*Tasks are ordered by Data manager orderingzTasks are chosen randomlyzMTasks are chosen according to model uncertainty scores (active learning mode)d   )r   choicesr   r   zshow ground truth firstzLOnboarding mode (true): show ground truth tasks first in the labeling streamzannotator evaluation enabledz+Enable annotator evaluation for the project)r   
db_defaultr   zshow overlap firstr   overlap_cohort_percentagetask_data_loginzTask data credentials: login)r   r   r   r   task_data_passwordzTask data credentials: passwordz	pinned atzPinned date and timecustom_task_lock_ttlzFCustom task lock TTL in seconds. If not set, the default value is usedz
deleted atr   r   deleted_projectsz
deleted by)r   r   r   r   db_indexr   zpurge atc                    t        t        | 
  |i | | j                         }d|vr| j                  nd | _        d|vr| j                  nd | _        d|vr| j                  nd | _	        d|vr| j                  nd | _        d|vr?| j                  2d|vr-t        | j                        }| j                  |k7  r|| _        y y y y y )Nlabel_configmaximum_annotationsr   
skip_queuer   )r   r   __init__get_deferred_fieldsr   _Project__original_label_configr   _Project__maximum_annotationsr   #_Project__overlap_cohort_percentager   _Project__skip_queuer   r   )rc   argskwargsdeferred_fieldsr   r   s        rP   r   zProject.__init__n  s    gt%t6v6 224<JRa<at'8'8gk$AV^mAmT%=%=sw".IQ`.`D**fj 	( 0<?/RDOOX\
 /1!!-O3+D,=,=>J*,", - 4 . 2rO   c                 6    | j                   j                         S rt   taskscountrb   s    rP   	num_taskszProject.num_tasks      zz!!rO   c                 H    t        | j                  j                               S rt   )r   ml_backendsallrb   s    rP   
ml_backendzProject.ml_backend  s    $**..011rO   c                 j    | j                   r'| j                  }|r|j                  | j                  k(  S y)z,Returns true if the model was set to be usedF)show_collab_predictionsr   r   model_version)rc   mls     rP   should_retrieve_predictionsz#Project.should_retrieve_predictions  s1     ''Bxx4#5#555rO   c                 ^    t         j                  j                  |       j                         S Nproject)rB   objectsrg   r   rb   s    rP   num_annotationszProject.num_annotations  s%    !!(((6<<>>rO   c                 ^    t         j                  j                  |       j                         S )Ntask__project)rC   r   rg   r   rb   s    rP   
num_draftszProject.num_drafts  s%    &&--D-AGGIIrO   c                 >    | j                         j                         S rt   )get_current_predictionsexistsrb   s    rP   has_predictionszProject.has_predictions  s    ++-4466rO   c                     t         j                  j                  t        | j                              j                         S r   )rD   r   rg   r+   idr   rb   s    rP   has_any_predictionszProject.has_any_predictions  s+    !!((477);<CCEErO   c                 .    | j                   j                  S rt   )
created_bybusinessrb   s    rP   r   zProject.business  s    '''rO   c                      y rt   rN   rb   s    rP   
is_privatezProject.is_private  s    rO   c                      y)NFrN   rb   s    rP   secure_modezProject.secure_mode  s    rO   c                 2    t        | j                        dk  S )Nr   )lenr   rb   s    rP   one_object_in_label_configz"Project.one_object_in_label_config  s    4??#q((rO   c                 V    | j                   j                  d      j                         S NT
is_labeled)r   rg   r   rb   s    rP   get_labeled_countzProject.get_labeled_count  s#    zz  D 17799rO   c                 6    | j                   j                         S rt   r   rb   s    rP   get_collected_countzProject.get_collected_count  r   rO   c                     | j                   j                         dk(  ry| j                   j                  t        d            d   S )z
            Tasks has overlap - how many tc should be accepted
            possible count = sum [ t.overlap for t in tasks]

        :return: N int total amount of Annotations that should be submitted
        r   overlapoverlap__sum)r   r   	aggregater,   rb   s    rP   get_total_possible_countz Project.get_total_possible_count  s:     ::"zz##C	N3NCCrO   c                 4    | j                   | j                  z
  S rt   )r   r   rb   s    rP   get_available_for_labelingz"Project.get_available_for_labeling  s    ''$*@*@@@rO   c                 4    | j                   | j                  z
  S rt   )r   num_annotatorsrb   s    rP   need_annotatorszProject.need_annotators  s    ''$*=*===rO   c                     |j                  d      j                  d      d   }t        |      r t        j                  j                  |      S t        d|       )N/)r   z"Can't find Project by invite URL: )stripsplitr   r   r   getKeyError)clsurlr   s      rP   find_by_invite_urlzProject.find_by_invite_url  sQ    		#$$S)"-u:??&&U&33?uEFFrO   c                 H    t               | _        | j                  dg       y )Nr   update_fields)r   r   saverb   s    rP   reset_tokenzProject.reset_token  s     ]
				*rO   c                 R   d}t        j                         5  	 t        j                  j	                  ||        t
        j                  d|  d| d       d d d        |S # t        j                  $ r& t        j                  j                  ||        d}Y Bw xY w# 1 sw Y   |S xY w)NFrj   r   zProject membership z
 for user z already existsT)	r#   atomicProjectMemberr   r  loggerdebugDoesNotExistcreate)rc   rj   createds      rP   add_collaboratorzProject.add_collaborator  s    ! 	ZZ%%))tT)B
 24&
4&XY	Z  !-- %%,,$,E	Z s-   B!A B 6BBBBB&c                 `    t         j                  j                  ||       j                         S Nr  )r  r   rg   r   ri   s     rP   has_collaboratorzProject.has_collaborator  s'    $$++t+DKKMMrO   c                     t         j                  j                  ||       }|j                         xr |j	                         j
                  S r"  )r  r   rg   r   firstenabled)rc   rj   
memberships      rP   has_collaborator_enabledz Project.has_collaborator_enabled  s@    "**11tT1J
  "Az'7'7'9'A'AArO   c                    t         j                  dt        |        d| j                   d| j                          |r|s| j                  dkD  r| j
                  j                  d      n| j
                  j                         }|j                         r|j                  | j                         n`| j                  dk  r| j                          n@| j
                  j                  | j                         | j
                  j                         }t        ||        n|r| j                  dk(  rg|rB| j
                  j                  d       t        | j
                  j                         |        ndt         j                  d	t        |        d
       nA| j                          n0|r.| j                  dk  r| j                  dkD  r| j                          |rvt        j                         +| j                  rt        j                  | j                          t        j"                         r"t        j                         }t%        | |       yyy)a)  
        Update tasks states after settings change
        :param maximum_annotations_changed: If maximum_annotations param changed
        :param overlap_cohort_percentage_changed: If cohort_percentage param changed
        :param tasks_number_changed: If tasks number changed in project
        z3Starting _update_tasks_states with params: Project  maximum_annotations  and percentage r   )overlap__gtr   r   r   Project zZ: cohort percentage was changed but maximum annotations was not and is 1; taking no actionNrj   )r  infostrr   r   r   rg   r   r   update_rearrange_overlap_cohortrG   r   get_usercreated_by_idset_userr   is_fsm_enabledr3   )rc   maximum_annotations_changed!overlap_cohort_percentage_changedtasks_number_changedtasks_with_overlaprj   s         rP   _update_tasks_stateszProject._update_tasks_states  s    	A#d)La''((89W9W8XZ	

 '/P FJE]E]`aEa!2!2q!2!Agkgqgqgugugw!((*"))$2J2J)K//#5..0 

!!$*B*B!C%)ZZ^^%5"+,>M /''1,.JJ%%a%03DJJNN4DdSKK"3t9+  .H  I ..0 "d&D&Ds&JtOgOgjkOk**, &&(0T5G5G''8,,.%..06t$G /  rO   c                      t        |||fi | y rt   )r   )rc   rw   
batch_sizemax_retriesr  s        rP   _batch_update_with_retryz Project._batch_update_with_retry*  s    *kS]SrO   c           	      j   t         j                  j                  |       }| j                  }t	        | j
                  j                         | j                  z  dz  dz         }t        j                  dt        |        d| d| j                          |j                  t        dt        t        d	      z  
            j                  |      }|j                  |      }t!        ||j                         z
  d      }t        j                  d| d|        |dkD  rt#        |j%                  dd            }| j'                  |j                  |      |d       |j                  t        d            }t)        dd      r|j+                  dd      }n|j+                  d      j-                         }t#        |j%                  dd            }|d| }	||d }
| j'                  |j                  |	      |       | j'                  |j                  |
      d       n~t#        |j%                  dd            }| j'                  |j                  |      |       t#        |j%                  dd            }| j'                  |j                  |      d       t/        ||        y)zJ
        Rearrange overlap depending on annotation count in tasks
        r   r   g      ?z8Starting _rearrange_overlap_cohort with params: Project r*  r+  annotationsFannotations__ground_truthrg   )anno)	anno__gteid__inr   zRequired tasks z and left required tasks r   Tflat)r   r   annotation_count+fflag_feat_utc_563_randomize_overlap_cohortautor/  z-annotation_count?Nr-  r   )rF   r   rg   r   intr   r   r   r  r0  r1  annotater'   rE   r+   rx   maxlistvalues_listr@  r   order_bydistinctrG   )rc   all_project_tasksmax_annotations
must_taskstasks_with_max_annotationstasks_with_min_annotationsleft_must_tasksidsall_min_ids
cohort_idsremaining_idss              rP   r3  z!Project._rearrange_overlap_cohort-  s    !LL///=22))+d.L.LLsRUXXY
Fs4ykQf/0N0N/OQ	
 &7%?%?}-H1glKm-mn &@ &

&?&
+ 	# &7%>%>F`%>%a"j+E+K+K+MMqQoj\1J?J[\]Q1==d=NOC))!(((4oZ^ *  *D)L)L^cdq^r)L)s&EFS .H-P-PQdfi-j*-G-P-PQd-e-n-n-p* 9EEdQUEVWK$%5o6J'(89M ))*;*B*B**B*U_n)o))*;*B*B-*B*Xbc)d1==d=NOC))*;*B*B#*B*NXg)h1==d=NOC))*;*B*B#*B*NXY)Z'(94HrO   c                 X    | j                   j                  |      j                          y )N)file_upload_id__in)r   rg   delete)rc   file_upload_idss     rP   remove_tasks_by_file_uploadsz$Project.remove_tasks_by_file_uploadsa  s     

_=DDFrO   c                     | j                   j                  d      }|j                         }|r,|j                         }d|_        |j                          |dk7  S y)z$Move project to next onboarding stepstep__orderTr   N)
steps_leftrV  r   r%  finishedr  )rc   po_qsr   pos       rP   advance_onboardingzProject.advance_onboardingd  sN    ((7BBKGGIA: rO   c                 8    | j                   j                  d      S )Nz%d %b %Y %H:%M:%S)
created_atstrftimerb   s    rP   created_at_prettifyzProject.created_at_prettifyp  s    ''(;<<rO   c                     t         j                  j                  |      }t        j                  j                  | |      }d|_        |j                          |S )zMark specific step as finished)coder   stepT)ProjectOnboardingStepsr   r  ProjectOnboardingrj  r  )rc   ru  posrl  s       rP   onboarding_step_finishedz Project.onboarding_step_finisheds  sK    $,,00d0;&&**4c*B
		rO   c                 @    t        j                  | j                        S rt   )jsondumpsr   rb   s    rP   data_types_jsonzProject.data_types_json|  s    zz$//**rO   c                 Z    t        t        | j                  j                                     S rt   )sortedrT  r   keysrb   s    rP   available_data_keyszProject.available_data_keys  s    d4??//1233rO   c                     t        |       y rt   )r   )r  config_strings     rP   r   zProject.validate_label_config  s
    m,rO   c           
      
   | j                  |       t        | d      sy t        j                         5  t        j
                  j                         j                  |       }| j                  dk(  r3t        j                  d|  d       |j                          	 d d d        y t        |      }|st        j                  d       	 d d d        y 	 | j                  dk(  rD| j                  dk(  r5t        j                  d|  d       |j                  d	       	 d d d        y d d d        t        t!        |            }|st        j                  d
       y t        | j"                  j$                        }|r|j'                  |      st)        |j+                  |            }g }|D ]  }	|	j-                  d      \  }
}}|
|k(  r|j/                         dk(  r1|j/                         dk(  rEt1        ||
      rt3        ||      r|t5        |      vsk|j7                  | j"                  j$                  |	    d|
 d| d|         t9        |      dkD  rdj;                  |      }t=        d|       t?        |      \  }}tA        | j"                  jB                  | j"                  jD                        }dtF        dtH        dtJ        tH           fd}|jM                         D ]j  \  }}|r>||vr:||vr6t1        ||      s*t=        dtO        |jQ                         d       d| d      t        |tS        ||               }tU        |      }|jM                         D cg c]
  \  }}|d    }}}d|v r|D ]  }|t        ||         z  } d|v rXtV        j
                  jY                  |       j[                  dd      }t        |D cg c]  }|D ]  }|  c}}      }||z  }t        |      j'                  t        |            r,t)        t        |      j+                  |            }d }|D ]  }| j"                  jB                  j                  |i       j                  |d      }| j"                  jD                  j                  |i       j                  |d      }  ||d!      }! || d"      }"|!|"fD #cg c]  }#|#s|#	 }$}#|$s|| d#d$j;                  |$       d%z  } |du r;||vr7t1        |||j]                         &      st=        d'| d(tI        |       d)      t        j_                  d*| j`                   d+|        m y # 1 sw Y   1xY wc c}}w c c}}w c c}#w ),Nsummaryr   r   r.  zH has no tasks: nothing to validate here. Ensure project summary is emptyz(Data fields not found in labeling configzm has no annotations and drafts: nothing to validate here. Ensure annotations-related project summary is emptyFtasks_data_basedz(Annotation schema is not found in config|chatmessagetextareaz with from_name=z
, to_name=z, type=
zNCreated annotations are incompatible with provided labeling schema, we found:
r   typereturnc                 ,    | sy|  d| | dkD  rd S d S )zwHelper for displaying pluralized sources of validation errors,
            eg "1 draft" or "3 annotations"
            N r   sr   rN   )r   r  s     rP   display_countz.Project.validate_config.<locals>.display_count  s1     WAdV519C#=>>"#=>>rO   z
There are z! annotation(s) created with tag "z", you can't remove itVideoRectangleTaxonomy)links__projectvalueTrJ  r   
annotationdraftz (z, z)
rE  z3These labels still exist in annotations or drafts:
z$Please add labels to tag with name="z".zproject_id=z0 inconsistent labels in config and annotations: )1r   hasattrr#   r  ProjectSummaryr   select_for_updater  r   r  r  resetr   r   r   setr   r  created_annotationsissubsetrT  
differencer  lowerr	   r
   r   appendr   joinrA   r   r   created_labelscreated_labels_draftsrQ  r1  r   rv   sumvaluesr   r5   r6   rg   rU  r  r0  r   )%rc   r  strictr  fields_from_configannotations_from_configannotations_from_datadifferent_annotationsdiff_str	ann_tuple	from_nameto_nametlabels_from_configdynamic_label_from_configr  r  control_tag_from_datalabels_from_datalabels_from_config_by_tagparsed_configr}   tag_info	tag_typeskeycustom_tagssublistitemflat_custom_tagsdifferent_labelslabelannotation_label_countdraft_label_countannotation_display_countdraft_display_countdispdisplays%                                        rP   validate_configzProject.validate_config  s   ""=1tY'! 	$,,>>@DDTDRG~~"xv-uvw	 	 ":-!H%GH	 	  ##q(T__-Atf %J K u5?	 	 	D #&&@&O"P&LLCD #DLL$D$D E )>)G)GH_)`$()>)I)IJa)b$c!H2 	(1(<%	7A'AGGI,F779
*8	R:='Rm <<OO<<;;IFG H**3JwiwqcS  8}q 99X.%efneop 
 9G}8U55.t||/J/JDLLLnLno	? 	?C 	?HSM 	? 8F7K7K7M 7	s3!#3 !*2DD.6OO8H]^% %5%<%<%>!B C D-..EG  ),"#A-Qf#gh)% )7M=J=P=P=RSka&)SIS9,- NC-5G5L1MM-NY&#mm22$2GSST[bfSg#&K'\T['\D'\'\#] )-==)'(11#6O2PQ#',<(=(H(HIb(c#d - HE-1\\-H-H-L-LMbdf-g-k-klqst-u*(,(J(J(N(NOdfh(i(m(mnsuv(w%/<=SUa/b,*78I7*S'1IK^0_hcgthGh ugR		'0B/C3$GGH dN*2KK<)+@IbIgIgIi *Nxj>sCX?Y>ZZ\^ 
 KK+dggY6fgofp qro7	sY	 	| T (] is1   A(U$#UAU!U U&>U,U,Uc                 4    | j                   | j                  k7  S rt   )r   r   rb   s    rP   _label_config_has_changedz!Project._label_config_has_changed  s      D$@$@@@rO   c                 n    | j                   t        j                  j                  d      j                  k7  S )Nr   )r   r   r   	get_fieldr   rb   s    rP   label_config_is_not_defaultz#Project.label_config_is_not_default  s(      GMM$;$;N$K$S$SSSrO   c                 <    | j                   |k(  xs | j                  S )z
        Returns True if the model version provided matches the object's model version,
        or no model version is set for the object but model version exists in ML backend.
        )r   ml_backend_in_model_version)rc   r   s     rP   should_none_model_versionz!Project.should_none_model_version  s     
 !!]2Vd6V6VVrO   c                 l   d| i}|r|j                  d|i       t        j                  j                  di |}t	        j
                         5  | j                  |      rd| _        | j                  dg       |j                         \  }}ddd       j                  dd      }d|iS # 1 sw Y   xY w)	aw  
        Deletes the predictions based on the provided model version.
        If no model version is provided, it deletes all the predictions for this project.

        :param model_version: Identifier of the model version (default is None)
        :type model_version: str, optional
        :return: Dictionary with count of deleted predictions
        :rtype: dict
        r   r   Nr  ztasks.Predictionr   deleted_predictionsrN   )r2  rD   r   rg   r#   r  r  r   r  rd  r  )rc   r   paramspredictionsr}   deleted_mapr   s          rP   delete_predictionszProject.delete_predictions  s     T"MM?M:; ((//9&9! 	2 --m<%)"		(9	:(//1NA{	2  2A6%u--	2 	2s   ?B**B3c           
            j                         }i }d} fd} fd}|D ]F  |   d   }||v r |      ||   j                  dg       D ci c]  }| ||       c}d|<   H |S c c}w )N)Filterc                     j                   j                  i       j                  di       j                  |       }||S dS )Nlabels      ?control_weightsr  )r  label_valuecontrol_namerc   s     rP   	get_labelz.Project.get_updated_weights.<locals>.get_label@  sE    ..22<DHHSUVZZ[`aK"-"9;BsBrO   c                 r    j                   j                  | d       }|sy|j                  dd       }||S dS )Nr  overallr  )nameweightsweightrc   s      rP   get_overallz0Project.get_updated_weights.<locals>.get_overallD  sA    **..tT:G Y5!'!3v<<rO   r  r  )r  r  r  )get_parsed_configr  )	rc   outputsr  exclude_control_typesr  r  control_typer  r  s	   `       @rP   get_updated_weightszProject.get_updated_weights;  s    ((* +	C	= $ 		L"<08L44 '|4$@G@U@Y@YZbdf@ghu5)E"22h-OL)		  is   A/
)r  recalcc                   | j                   rdnd}| xr | j                  }| j                         }t        j	                  d| d| j
                   d| j                          |s|rlt        | j                        | _        t        | j                        | _	        t        t        | j                              | _        |h dj                  |      }| j                  rG| j                         s|r| j                  s)| j                         | _        |dhj                  |      }| j                   r(| j"                  rd| _        |dd	hj                  |      }t%        t&        | R  |d
|i| |r| j                  | _        | j*                  dkD  rHt        j	                  d| j,                          t.        j0                  j3                  t&        |        n#t        j	                  d| j,                   d       |sWt4        j6                  j9                         }|D 	cg c]  }	t;        | |	       }
}	t:        j6                  j=                  |
       |rd| j?                  | j@                  | jB                  k7  | jD                  | jF                  k7  d       | jB                  | _         | jF                  | _"        | jH                  | jJ                  k7  r;tM        | jN                  jQ                  tS        d      tS        d      z               tU        | d      rtW        jX                         5  tZ        j6                  j]                         j_                  |       }| j*                  dk(  r|ja                          n0| jb                  dk(  r!| jd                  dk(  r|ja                  d       d d d        tg        th        jj                        }| || | |       y y c c}	w # 1 sw Y   7xY w)NTFzLabel config has changed: z, original: z, new: >   r   label_config_hashparsed_label_configr  is_publishedis_draftr  r   z>Sending post_label_config_and_import_tasks signal for project )senderr   zNo tasks imported for project z4, skipping post_label_config_and_import_tasks signalrt  )r8  r9  r:  )annotations__isnullrC  r  r   r  )r   r  label_config_has_changed)6pkr   r  r  r  r   r   r   r5   r  hashr1  r  unionr  r  r  r  r   r   r  r   r   r@   "post_label_config_and_import_taskssendrv  r   r   rw  bulk_createupdate_tasks_statesr   r   r   r   r   r   rG   r   rg   r+   r  r#   r  r  r  r  r  r   r   r   r   #PROJECT_SAVE_DIMENSIONS_POSTPROCESS)rc   r  r  r   r   r    project_with_config_just_createdr  stepsru  objsr  dimensions_postprocessr   s                rP   r  zProject.saveX  s   e/5:+K$:K:K(#'#A#A#C ()A(B,tOkOkNllstx  uF  uF  tG  H	
 $'G01B1BCDO'3D4E4E'FD$%)#d.?.?*@%AD"( Z ` `an o$"@"@"B&X\XlXl#'#;#;#=D (!2 3 9 9- H !DM(!/ < B B= Qgt!4O}OO#+/+<+<D(~~!]^b^e^e]fghAAFFg_cFd4TWWI=qr *22668EKPQ4%d>QDQ%%11$7 $$,0,F,F$JbJb,b262R2RVZVtVt2t%* % 
 *.)A)AD&/3/M/MD,/+

!!!">]bAc"cd 4###% :(00BBDHHQUHV>>Q&MMO))Q.4??a3GMM5M9: "+8+W+W!X!-""
)A .= R&: :s   "O!1A?O&&O/c                     t        | d      r1| j                  j                  j                  j	                  dd      S ddlm} |j                  j                         S )N	team_linkrj   TrJ  r   User)	r  r   teammembersrU  users.modelsr  r   none)rc   r  s     rP   get_member_idszProject.get_member_ids  sL    4% >>&&..::6:MM) <<$$&&rO   c                 h    t        | d      xr% | j                  j                  j                  |      S )Nr   )r  r   r  has_userri   s     rP   has_team_userzProject.has_team_user  s)    t[)Pdnn.A.A.J.J4.PPrO   c           
         ddl m} | j                         }|j                  j	                  |      j                  d      }| j                  j                  dd      }|j                  j	                  |      }||z  }|j                  t        t        |t        d      	      t        d      t               
            }|S )z;Annotators connected to this project including team membersr   r  rH  emailuser__idTrJ  F)rI  then)r   output_field)team_member)r  r  r  r   rg   rV  r  rU  rR  r&   r.   r-   r%   )rc   r  
member_idsteam_membersproject_member_idsproject_members
annotatorss          rP   r  zProject.annotators  s    %((*
||****=FFwO "\\55jt5L,,--5G-H!O3
  ((.U5\Bd)^ ) 

 rO   c                     | j                         }t        |       t        z  t        d      z  }|j                  t	        d|d            }|j                  |      S )	zAnnotators with annotation number > min_number

        :param min_count: minimal annotation number to leave an annotators
        :return: filtered annotators
        )annotations__projectFrC  rB  T)rg   rW  rL  )annotation_count__gte)r  r+   rE   rR  r'   rg   )rc   	min_countr  qs       rP   annotators_with_annotationsz#Project.annotators_with_annotations  s]     __&
4(+FFejIkk((%VWbf:g(h
  y AArO   c                 :    | j                   j                  d      S r   )r   rg   rb   s    rP   labeled_taskszProject.labeled_tasks  s    zz  D 11rO   c                     ddl m} |j                  j                  t	        |       t	        d      z        j                         dkD  S )Nr   )rB   r   Fground_truth)tasks.modelsrB   r   rg   r+   r   )rc   rB   s     rP   has_annotationszProject.has_annotations  s9    +!!((41%;P)PQWWY\]]]rO   c                 0    | j                   }t        |      S rt   )r   r   )rc   cs     rP   label_config_linezProject.label_config_line  s    "1%%rO   c                 D    |xs | j                   }t        |      \  }}}|S rt   )r   r   )rc   r   configtaskr}   s        rP   r   zProject.get_sample_task  s'    2!2!2$V,
arO   c                 4   t         j                  j                  | j                  d      }t	        |D cg c]  }|j
                   c}      }t        j                  j                  | j                  ddd      j                         }| j                  }||z
  |z
  }t        j                  j                  t        | j                        t        d      z  d      j                  d      }|j                  t        d      	      d
   }|y||z  S c c}w )ao  
            Show eta for project to be finished
            eta = avg task annotations finish time * remain annotations

            task has overlap = amount of task annotations to consider as finished (is_labeled)
            remain annotations = sum ( task annotations to be done to fulfill each unfinished task overlap)

        :return: time in seconds
        T)r   r   F)r   task__is_labeledr   result__isnullr   r  )r+  	lead_timeavg_lead_timer.  N)rF   r   rg   r   r  r   rB   r   r  r+   r  r  r$   )	rc   finished_tasksftmin_n_finished_annotationsannotations_unfinished_taskstotal_annotations_neededannotations_remainfinished_annotationsr.  s	            rP   etazProject.eta  s    ,,TWW,N%(~)N"**)N%O"'1'9'9'@'@GGe%X] (A (

%' 	%
 $(#@#@ 58RRUqq  *1188dgg!66u  9  

&
 	 -66SEU6VWfg 111% *Os   Dc                 X    | j                   j                  d      j                          S )NFr   )r   rg   r   rb   s    rP   rj  zProject.finished  s&    ::$$$6==???rO   c                     t         j                  j                  t        | j                        t        d      z        }|j                  t        d            d   S )Nr   Fr  r,  r-  r.  )rB   r   rg   r+   r   r  r$   )rc   rB  s     rP   annotations_lead_timezProject.annotations_lead_time  sJ     ((//$''0BQTYEZ0Z[$$3{3C$D_UUrO   c                      t         S rt   r   rN   rO   rP   django_settingszProject.django_settings  s    rO   c                  "    t         j                  S rt   )r   TASKS_MAX_FILE_SIZErN   rO   rP   max_tasks_file_sizezProject.max_tasks_file_size  s    +++rO   c                 $   | j                   :	 t        | j                        | _         | j                  dg       | j                   S | j                   S # t        $ r3}t
        j                  d| j                   d| d       i cY d }~S d }~ww xY w)Nr  r  z'Error parsing label config for project z: T)exc_info)r  r5   r   r  	Exceptionr  errorr   )rc   es     rP   r  zProject.get_parsed_config!  s    ##++78I8I+J(		)>(?	@
 '''t'''	  FtwwirRSQTU`de	s   -A 	B(B
B
Bc                 ^    i }t         j                  D ]  }t        | |d      }||||<    |S )zCMethod to get extra counters data from Manager method with_counts()N)rU   r   getattr)rc   resultr{   r  s       rP   get_counterszProject.get_counters,  s@    #22 	&ED%.E  %u	& rO   c                    t         j                  j                  |       }|j                  d      j	                  t        d      t        d            j                  d      }|rt        |      S |r|d| }|D ci c]  }|d   |d    }}| j                  r?| j                  |vr1|rt        |      |k  rd|| j                  <   n|sd|| j                  <   |r|S t        |j                               S c c}w )	aW  
        Get model_versions from project predictions.
        :param with_counters: Boolean, if True, counts predictions for each version. Default is False.
        :param extended: Boolean, if True, returns additional information. Default is False.
        :return: Dict or list containing model versions and their count predictions.
        r   r   ro  )r   latestz-latestNr   r   )rD   r   rg   r  rR  r'   r*   rV  rT  r   r   r  )rc   with_countersextendedlimitr  model_versionsroutputs           rP   get_model_versionszProject.get_model_versions5  s     !((///= /XE/23|;LXMXi  	 ''!/!7>LMa(!G*4MFM !!d&8&8&FS[5012F4--.12F4--. +6CV[[]0CC Ns   <C6c                 J    ddl m}  |j                  j                  dd| i|S )Nr   )	MLBackendr   rN   )	ml.modelsrR  r   rg   )rc   r   r   rR  s       rP   get_ml_backendszProject.get_ml_backendsU  s&    ''y  ''????rO   c                 B     | j                   di |j                         S )NrN   )rT  r   )rc   r   r   s      rP   has_ml_backendzProject.has_ml_backendZ  s!    #t##-f-4466rO   c                 h    t        | j                  xr | j                  | j                              S )z
        Returns True if the ml_backend title matches this model version.
        If this model version is not set, Returns False
        )r   )boolr   rV  rb   s    rP   r  z#Project.ml_backend_in_model_version]  s.     D&&X4+>+>TEWEW+>+XYYrO   c                 T    | j                         }|D ]  }|j                           |S )z
        Updates the state of all ml_backends associated with this instance.

        :return: List of updated MLBackend instances.
        )rT  update_state)rc   r   mlbs      rP   update_ml_backends_statez Project.update_ml_backends_statee  s5     **, 	C	 rO   c                 F    ddl m} | j                  |j                        S )Nr   )MLBackendState)state)rS  r^  rT  	CONNECTED)rc   r^  s     rP   get_active_ml_backendszProject.get_active_ml_backendsq  s    ,##.*B*B#CCrO   c                     ddl m} g } |d      D ]*  }|t        |j                  j	                  |             z  }, |S )Nr   get_storage_classesimportr   io_storages.modelsrd  rT  r   rg   rc   rd  storage_objectsstorage_classs       rP   get_all_import_storage_objectsz&Project.get_all_import_storage_objectsv  K    :0: 	PMtM$9$9$@$@$@$NOOO	P rO   c                     ddl m} g } |d      D ]*  }|t        |j                  j	                  |             z  }, |S )Nr   rc  exportr   rf  rh  s       rP   get_all_export_storage_objectsz&Project.get_all_export_storage_objects  rl  rO   c                    | j                         }g }|j                         D ]`  }|j                  dg       D ]I  }|j                  d      dk(  s|j                  d      *|j                  |j                  d             K b |S )z
        Check if the project's label config contains an Image tag with a valueList attribute,
        which indicates multipage labeling.
        inputsr  Image	valueList)r  r  r  r  )rc   r'  r  tag
object_tags        rP   multipage_labeling_valuesz!Project.multipage_labeling_values  s     '')==? 	CC!ggh3 C
>>&)W4!~~k2>jnn[&ABC	C
 rO   r  r  c                 z    ddl m} | j                  } |||      }|r|j                  |      |j                  dS y )Nr   )get_storage_by_url)r  presign_ttl)io_storages.functionsrx  rk  generate_http_urlry  )rc   r  rx  ri  storages        rP   resolve_storage_urizProject.resolve_storage_uri  sE    <==$S/:005&22  rO   c                 n   ddl m} d}d}||t        j                  z  |dz   t        j                  z   x}rrt	        j
                         5  t        |      }| |||      z  }t        ||        ddd       |dz  }||t        j                  z  |dz   t        j                  z   x}rr|S # 1 sw Y   =xY w)z
        Update tasks counters and is_labeled in batches of size settings.BATCH_SIZE.
        :param task_ids: List of task ids to be updated
        :param from_scratch: Skip calculated tasks
        :return: Count of updated tasks
        r   update_tasks_countersr   N)tasks.functionsr  r   
BATCH_SIZEr#   r  r?   rG   )rc   task_idsfrom_scratchr  num_tasks_updatedpage_idxtask_ids_slicerw   s           rP   %_update_tasks_counters_and_is_labeledz-Project._update_tasks_counters_and_is_labeled  s     	: (H4G4G)G8VW<[c[n[nJn oono##% @ 7~F!%:8\%RR!/$?@ MH !)H4G4G)G8VW<[c[n[nJn oono ! @ @s   $B++B4recalculate_stats_countsc                     ddl m} t        |      } |||      }| j                  |||       t        r|rt	        | j
                  fi | |S )z
        Update tasks counters and update tasks states (rearrange and/or is_labeled)
        :param queryset: Tasks to update queryset
        :param from_scratch: Skip calculated tasks
        :return: Count of updated tasks
        r   r  )r  r  r?   r<  recalculate_all_statsr   )	rc   rw   r8  r9  r:  r  r  r  r  s	            rP   &_update_tasks_counters_and_task_statesz.Project._update_tasks_counters_and_task_states  sO     	:.x8$X|<!!"=?`bvw %=!$''F-EFrO   c                     t         j                  t         j                  k(  ryt        j                         5 }|j                  d| j                  g       |j                         }|r|d   s
	 ddd       y|d   cddd       S # 1 sw Y   yxY w)z7Get the maximum annotation result size for this projectr   a  
                SELECT id,
                       octet_length(result::text) AS bytes
                FROM   task_completion
                WHERE  project_id = %s
                ORDER  BY octet_length(result::text) DESC
                LIMIT  1
            r   N)r   	DJANGO_DBDJANGO_DB_SQLITEr!   cursorexecuter   fetchone)rc   r  rows      rP   get_max_annotation_result_sizez&Project.get_max_annotation_result_size  s     !:!::   	FNN 	
 //#Cc!f	 	" q6#	 	 	s   6B6BBc           
      d   t         j                  t         j                  k(  rt         j                  S d}t	        j
                         5 }|j                  d| j                  g       |j                         }|r
|d   r|d   }ddd       | j                         }t        ||      }|dk(  rt         j                  S t         j                  |z  }|t         j                  kD  rt         j                  }n|dk  rd}t        j                  d| j                   d| d| d|        |S # 1 sw Y   xY w)	zOCalculate optimal batch size based on task data size and annotation result sizer   z
                SELECT id,
                       octet_length(data::text) AS bytes
                FROM   task
                WHERE  project_id = %s
                ORDER  BY octet_length(data::text) DESC
                LIMIT  1
            r   Nr.  z: max task size z bytes, max annotation size z bytes, calculated batch size )r   r  r  MAX_TASK_BATCH_SIZEr!   r  r  r   r  r  rS  TASK_DATA_PER_BATCHr  r0  )rc   max_task_sizer  r  max_annotation_sizemax_data_sizer>  s          rP   get_task_batch_sizezProject.get_task_batch_size  s4    !:!::///   	'FNN 	
 //#Cs1v #A	'$ #AAC M+>?A///11]B
444!55J!^Jtwwi/ ?##6"7 8%%/L2	

 M	' 	's   :D&&D/c                 n    | j                    d| j                   dxs t        d      | j                  z  S )Nz (id=)zBusiness number %d)r   r   r}   r  rb   s    rP   __str__zProject.__str__   s1    **U477)1-R3G1H4771RRrO   
postgresqlzsetweight(to_tsvector('english', COALESCE(CAST(id AS TEXT), '')), 'A') || setweight(to_tsvector('english', COALESCE(title, '')), 'B') || setweight(to_tsvector('english', COALESCE(SUBSTRING(description, 1, 250000), '')), 'C'))r  r  )
expressionr  
db_persistc                   <    e Zd ZdZ ej
                  ddg      gZy)Project.Metar   	pinned_atro  ro   N)rK   rL   rM   r   r"   IndexindexesrN   rO   rP   Metar  2  s!    FLLl ;<
rO   r  )     )Frt   )r  )FFNT)TN)rK   rL   rM   r"   TextChoicesr   r   r   rU   all_objectsr   	CharFieldr}   r   PROJECT_TITLE_MAX_LENPROJECT_TITLE_MIN_LENr    r   r   	TextFieldr   
ForeignKeyCASCADErf   r   r)   r  BigIntegerFieldr  expert_instructionr%   show_instructionshow_skip_buttonenable_empty_annotationr   show_annotation_historyr   "evaluate_predictions_automaticallyr   r   IntegerFieldresult_countr   AUTH_USER_MODELSET_NULLr   r   r   dictr  r   r   r  r  DateTimeFieldro  
updated_atSEQUENCEUNIFORMUNCERTAINTYSAMPLING_CHOICESsamplingr   r   r   show_ground_truth_firstannotator_evaluation_enabledshow_overlap_firstr   r   r   r  r   r   
deleted_bypurge_atr   propertyr   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  classmethodr  r  r   r#  r(  r<  r@  r3  rf  rm  rq  ry  r}  r  r   r  r  r  r  r  r  r  r  r
  r  r  r  r"  r%  r   r6  rj  r9  r   r;  r>  r  rG  rP  rT  rV  r  r\  ra  r0   rk  ro  rv  r1  r   r   r   r}  r  rQ  r  r  r  r  r!   vendorr(   r/   r   search_vectorr  r   r   s   @rP   r   r      s	   <F&& < $%G "K"F	'
11283Q3Q2RRWX`XvXvWw  xI  Jx==>x==>
E #&""	-4G\K %6$$$Z^bL $6##	.RL +&**	
 Z /..D$G)))	
t$Nt +v**	
u8n +v**	
Y
 2f11	
#$d>l +>&*=*=	
/0%Kq+' 2f11	
#$e?e 2f11	
)*DDv *=)<)<	
./H*&
 FQwZCSW_cdE&6&&	.10]L FQwZB	PT\`aE"""  '//|_J .&--	
%&A )<(;(;	
-.[)%  	
m		O$ %F$$	/$T2IiM 1\?DtDJ"v""	*u0nH '6&&	+1hL &%%aoDIJ%%%aoEJ$H G(K 
?@	-.	ef  v38Ht]efH!!!	 1 1iFbFbJ
 2f11	
#$` $76#6#6	
()?	$  -,,Q/C-DeT 3 3 3A6Q4R\_ `&f&&	
DtOmO *))	
Ct$Rs %$$Q{^$XnoI.6..	
 !Z	 &%%aoDMJ"""  '//|_J $v##AjMDIH-. " " 2 2   ? ? J J 7 7 F F ( (     ) ) : : " " 	D 	D A A > > G G+
NB6HpT2IhG
=+4 - -HsTA T TW.:: )-T Nl	'Q.	B2^ & &
2B@V   , ,	(D@@
7 Z Z
D
      
s 
xS8I/J 
!8 @D #+738+<"=46.`S L(&j .0 +,

 )((d$?
 
rO   r   c                   r   e Zd ZdZdZdZdZdZedfedfedfed	ffZ e	j                  d
ed      Z e	j                   ed      dd      Z e	j                   ed      d      Z e	j                   d      Z e	j$                   ed      d      Z e	j$                   ed      d      Z G d d      Zy)rv  r  DUCFPBIEzImport your datazConfigure settingszPublish projectzInvite collaborators   T)r   r   r   r   i  F)r   r   r   )r   r   r   r   r   r   r   c                       e Zd ZdgZy)ProjectOnboardingSteps.MetaorderN)rK   rL   rM   orderingrN   rO   rP   r  r  S  s	    9rO   r  N)rK   rL   rM   r   DATA_UPLOADCONF_SETTINGSPUBLISHINVITE_EXPERTSSTEPS_CHOICESr"   r  rs  r}   r   r  r   r  r  r  ro  r  r  rN   rO   rP   rv  rv  ;  s    KMGN 
()	,-	#$	/0	M 6q-dKDFQwZDuEE"&""1]#3%@KF*E%%%aoDIJ%%%aoEJ rO   rv  c                   *    e Zd ZdZ ej
                  eej                  d      Z ej
                  e	ej                        Z
 ej                  d      Z ej                   ed      d	      Z ej                   ed
      d      Z fdZ xZS )rw  r  
po_through)r   r   )r   Fr   r   Tr   r   r   c                     t        t        | 
  |i | t        j                  j	                  | j
                  d      j                         dk(  r.d| j
                  _        | j
                  j                  d       y y )NT)r   rj     F)r  )r   rw  r  r   rg   r   r   skip_onboarding)rc   r   r   r   s      rP   r  zProjectOnboarding.saveb  sk    +T<V<$$++DLL4+PVVX\]]+/DLL(LLU+ ^rO   )rK   rL   rM   r   r"   r  rv  r  ru  r   r   r%   rj  r  r}   ro  r  r  r   r   s   @rP   rw  rw  W  s    63v~~\hiDf6>>BG"v""51H%%%aoDIJ%%%aoEJ, ,rO   rw  c                       e Zd Z ej                  ej                  ej                  dd      Z ej                  e	ej                  dd      Z
 ej                  e      Z G d d      Zy)	LabelStreamHistory	historiesUser IDr   r   r   
Project IDr   c                   :    e Zd Z ej                  ddgd      gZy)LabelStreamHistory.Metarj   r   unique_history)rp   r  N)rK   rL   rM   r"   UniqueConstraintconstraintsrN   rO   rP   r  r  q  s    .v..vy6IP`abrO   r  N)rK   rL   rM   r"   r  r   r  r  rj   r   r   r)   rT  datar  rN   rO   rP   r  r  i  sf    6  FNN`iD  f6>>P[gstG6D)Dc crO   r  c                   0   e Zd Z ej                  ej                  ej                  dd      Z ej                  e	ej                  dd      Z
 ej                  dd      Z ej                   ed	      d
      Z ej                   ed      d      Zy)r  project_membershipsr  r  r  r  TzProject member is enabledr   r   r   r   r   N)rK   rL   rM   r"   r  r   r  r  rj   r   r   r%   r&  r  r}   ro  r  rN   rO   rP   r  r  u  s    6  FNNI^jsD  f6>>PYeqrG!f!!$:UVG%%%aoDIJ%%%aoEJrO   r  c                   `   e Zd Z eedej                  d      Z ej                   e	d      dd      Z
 e e	d      ded	      Z e e	d
      ded	      Z e e	d      ded	      Z e e	d      ded	      Z e e	d      ded	      Zd ZddZd Zd Zd Zd Zd Zd Zd Zd Zy)r  Tr  )primary_keyr   r   r   Creation time)r   r   zall data columnsz(All data columns found in imported tasksr   zcommon data columnsz/Common data columns found across imported taskszcreated annotationszFUnique annotation types identified by tuple (from_name, to_name, type)zcreated labelszUnique labelszcreated labels in draftszUnique drafts labelsc                 Z    | j                   |_         | j                   j                  |      S rt   r   has_permissionri   s     rP   r  zProjectSummary.has_permission  s"    ||||**400rO   c                 n    |ri | _         g | _        i | _        i | _        i | _        | j                          y rt   )all_data_columnscommon_data_columnsr  r  r  r  )rc   r  s     rP   r  zProjectSummary.reset  s6    $&D!')D$#%  %'"		rO   c                    t               }t        | j                        }|D ]Z  }	 t        |d      }|j                         }|D ]  }|j                  |d      dz   ||<    |st        |      }M|t        |      z  }\ || _        | j                  st        t        |            | _        n/t        t        t        | j                        |z              | _        | j                  ddg       y # t        $ r |}Y w xY w)Nr  r   r   r  r  r  )r  r  r  r   r  r  r  r  rT  r  r  )rc   r   r  r  r(  	task_datatask_data_keyscolumns           rP   update_data_columnsz"ProjectSummary.update_data_columns  s	   !e 5 56 	;D!,T6:	 '^^-N( O+;+?+?+JQ+N (O&&).&9##s>'::#	; !1'''+F3F,G'HD$'+F3t7O7O3PSf3f,g'hD$		!35J K	L  ! 	!s   C00C>=C>c                    t        | j                        }g }|D ]`  }t        |d      }|j                         D ]?  }||v s||xx   dz  cc<   ||   dk(  s|j	                  |       |j                  |       A b || _        |r9t        | j                        }|D ]  }||v s|j                  |        || _        | j                  ddg       y )Nr  r   r   r  r  r  )
r  r  r   r  r  poprT  r  remover  )rc   r   r  keys_to_remover(  r  r  r  s           rP   remove_data_columnsz"ProjectSummary.remove_data_columns  s     5 56 	2D(v6I ~~' 2**$S)Q.)',1&--c2(,,S12	2 !1"&t'?'?"@% 4--'..s34 (;D$		"% 	 	
rO   c                     |j                  dd       }|dv ry d|vsd|vrt        j                  dddi       y |d   }t        ||d   |xs d	      }|S )
Nr  )relationpairwiseNr  r  zGUnexpected annotation.result format: "from_name" or "to_name" not foundsentry_skipT)extrar   )r  r  rB  r   )rc   rF  result_typeresult_from_namer  s        rP   _get_annotation_keyz"ProjectSummary._get_annotation_key  sx    jj.88f$	(?LLY$d+   !+."#3VI5FHYWYZ
rO   c                 B   |j                  d      }|dv rd}|d   j                  |      }|rt        |t              r|dk(  rg S g }|D ]S  }|dk(  r2t        |t              r"|D ]  }|j                  t	        |              :|j                  t	        |             U |S )Nr  )videorectangler  r  texttaxonomy)r  
isinstancerT  r  r1  )rc   rF  r	  result_valuer  r  label_s          rP   _get_labelszProjectSummary._get_labels  s    jj(,,"Kg**;7:lD#A[TZEZI! 	*Ej(Zt-D# /FMM#f+./ c%j)	* rO   c                 Z   t        | j                        }t        | j                        }|D ]  }t        |d      xs g }t	        |t
              s$|D ]  }| j                  |      }|s|j                  |d      dz   ||<   |d   }|| j                  vrt               ||<   | j                  |      D ]   }	||   j                  |	d      dz   ||   |	<   "   t        j                  d|        t        j                  d|        || _        || _        | j                  ddg	       y )
NrF  r   r   r  summary.created_annotations = summary.created_labels = r  r  r  )r  r  r  r   r  rT  r  r  r  r  r  r  )
rc   rB  r  r  r  resultsrF  r  r  r  s
             rP   %update_created_annotations_and_labelsz4ProjectSummary.update_created_annotations_and_labels  sP   "4#;#;<d))*% 	SJ&z8<BGgt,! S..v6+>+B+B3+JQ+N#C(";/	 D$7$77(,F9%!--f5 SE/5i/@/D/DUA/NQR/RF9%e,SS	S( 	56I5JKL09:#6 $		!68H I	JrO   c                 T   | j                   j                  j                         t        |      k(  }|ri i fn)t	        | j
                        t	        | j                        f\  }}|s|D ]  }t        |d      xs g }t        |t              s$|D ]  }| j                  |      }||v r&||xx   dz  cc<   ||   dk(  r|j                  |       |j                  dd       }	|	|vrU| j                  |      D ]E  }
t        |
      }
|
||	   v s||	   |
xx   dz  cc<   ||	   |
   dk(  s2||	   j                  |
       G ||	   r|j                  |	         t        j!                  d|        t        j!                  d|        || _        || _        | j#                  ddg	       y )
NrF  r   r   r  r  r  r  r  r  )r   rB  r   r   r  r  r  r   r  rT  r  r   r  r  r1  r  r  r  )rc   rB  remove_all_annotationsr  r  r  r  rF  r  r  r  s              rP   %remove_created_annotations_and_labelsz4ProjectSummary.remove_created_annotations_and_labels  s   !%!9!9!?!?!ASEU!U.RHT$:R:R5SUYZ^ZmZmUn4o 	,^ &) 6
*:x@FB!'40% 6F226:C11+C0A50.s3q8/33C8 !'

; =I 6 !%!1!1&!9 E #E
 N9$==*95e<A<-i8?1D .y 9 = =e DE *)4&**95'664 	56I5JKL00@AB#6 ,		!68H I	JrO   c                    t        | j                        }|D ]  }t        |d      xs g }t        |t              s$|D ][  }d|vr|d   }|| j                  vrt               ||<   | j                  |      D ]   }||   j                  |d      dz   ||   |<   " ]  t        j                  d|        || _        | j                  dg       y )NrF  r  r   r   z'update summary.created_labels_drafts = r  r  )
r  r  r   r  rT  r  r  r  r  r  )rc   draftsr  r  r  rF  r  r  s           rP   update_created_labels_draftsz+ProjectSummary.update_created_labels_drafts?  s    d001 	SE&uh7=2Ggt,! 
Sf,";/	 D$>$>>(,F9%!--f5 SE/5i/@/D/DUA/NQR/RF9%e,S
S	S" 	>vhGH%+"		!8 9	:rO   c                    t         j                  j                  | j                        j	                         t        |      k(  }|ri nt        | j                        }|s|D ]  }t        |d      xs g }t        |t              s$|D ]  }|j                  dd       }||vr| j                  |      D ]E  }t        |      }|||   v s||   |xx   dz  cc<   ||   |   dk(  s2||   j                  |       G ||   ry|j                  |         t        j!                  d|        || _        | j#                  dg       y )	Nr   rF  r  r   r   z summary.created_labels_drafts = r  r  )rC   r   rg   r   r   r   r  r  r   r  rT  r  r  r1  r   r  r  r  )	rc   r  remove_all_draftsr  r  r  rF  r  r  s	            rP    remove_created_drafts_and_labelsz/ProjectSummary.remove_created_drafts_and_labelsV  sS   +33:::V\\^beflbmm(d43M3M.N  .*5(;Ar!'40% .F &

; =I . !%!1!1&!9 = #E
 F9$55"9-e494%i071< &y 1 5 5e <= "),

9-..$ 	7x@A%+"		!8 9	:rO   Nr  )rK   rL   rM   r   r   r"   r  r   r  r}   ro  r)   r  r  rT  r  r  r  r  r  r  r  r  r  r  r  r  r  r!  rN   rO   rP   r  r    s    TV^^bklG%%%aoDTcdJ !	
D$Bl $	
 tTEv $	
 Z	 q!12tWfgN%	
$%D$J`1M.
6&K:&KP;.;rO   r  c                      e Zd Z G d dej                        Z ej                  dddej                        Z ej                  dd      Z
 ej                  d	      Z ej                  d	      Z ej                  d
ej                  ej                         Z ej                  ddd      Z ej&                  dd      Z ej&                  dd      Z ej,                   ed      ddd      Z ej,                   ed      ddd      Z ej,                   ed      ddd      Z ej6                  d	      Z ej6                  d	      Z ej6                  d	      Z ej6                  d	      Z ej                  e 	      Z! ej                  d	      Z" ej                  e 	      Z# ej                  e 	      Z$ ej                  dd      Z% ej                  e 	      Z&d Z'y)ProjectImportc                   \    e Zd Zd ed      fZd ed      fZd ed      fZd ed      fZy	)
ProjectImport.Statusr  Createdin_progressIn progressfailedFailed	completed	CompletedNrK   rL   rM   r}   CREATEDIN_PROGRESSFAILED	COMPLETEDrN   rO   rP   Statusr%  t  ;    Qy\)#Q}%551X;&;/	rO   r2  projects.ProjectTimportsr   r   r   r   Fr   @   r   r   r   i   )r   r   r   r   r  )r   r   r   r   zUpdated timezfinished atzComplete or fail timeN)r   r   r   r   )r   r   c                 8    | j                   j                  |      S rt   r  ri   s     rP   r  zProjectImport.has_permission      ||**400rO   )(rK   rL   rM   r"   r  r2  r  r  r   r)   preannotated_from_fieldsr%   commit_to_projectreturn_task_idsr  r   r.  statusr  r  	tracebackrB  r  r}   ro  r  finished_atr  
task_countrM  prediction_countdurationrT  re  could_be_tasks_listfound_formatsdata_columnsr   r  r  rN   rO   rP   r#  r#  s  s   0## 0  f 2IagaoaopG/v//TF+++E:)f))%8OVV^^V^^\F
&

dT
BC   d$7IF$d3E%%%aoDt_noJ%%%aoDt_mnJ&&&&q'7CZaeostK$$$Q/J*v**15*v**15"v""1-H&f&&t4O-&--e<$F$$T2M#6##D1LF4d3Ev-H1rO   r#  c                   N   e Zd Z G d dej                        Z ej                  dddej                        Z ej                  dej                  ej                        Z ej                  dd	      Z ej                  d
      Z ej                  d
      Z ej                  d
      Z ej                  d
      Z ej(                  e      Z ej.                  d      Z ej(                  e      Z ej(                  e      Z ej                  dd	      Zd Zy)ProjectReimportc                   \    e Zd Zd ed      fZd ed      fZd ed      fZd ed      fZy	)
ProjectReimport.Statusr  r&  r'  r(  r)  r*  r+  r,  Nr-  rN   rO   rP   r2  rJ    r3  rO   r2  r4  T	reimportsr6  r7  r8  r   r   r   Fc                 8    | j                   j                  |      S rt   r  ri   s     rP   r  zProjectReimport.has_permission  r:  rO   N)rK   rL   rM   r"   r  r2  r  r  r   r  r   r.  r>  r  rB  r  rA  rM  rB  rC  r)   rT  re  r%   files_as_tasks_listrE  rF  r?  r  rN   rO   rP   rH  rH    s   0## 0  f 2KcicqcqrGVV^^V^^\FF$d3E$$$Q/J*v**15*v**15"v""1-H&f&&t4O-&--e<$F$$T2M#6##D1L   d$7I1rO   rH  )wr   r{  loggingtypingr   r   r   annoying.fieldsr   core.current_requestr   core.feature_flagsr   core.label_configr	   r
   r   r   r   r   r   r   r   r   r   r   core.utils.commonr   r   r   r   core.utils.dbr   r   r   django.confr   django.contrib.postgres.searchr   django.core.validatorsr   r    	django.dbr!   r"   r#   django.db.modelsr$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   django.db.models.expressionsr/   django.utils.functionalr0   django.utils.translationr1   r}   
fsm.modelsr2   fsm.project_transitionsr3   fsm.queryset_mixinsr4   Alabel_studio_sdk._extensions.label_studio_tools.core.label_configr5   labels_manager.modelsr6   projects.functionsr7   r8   r9   r:   r;   r<   r=   r>   projects.functions.utilsr?   projects.signalsr@   rest_framework.exceptionsrA   r!  rB   rC   rD   rE   rF   rG   	getLoggerrK   r  QuerySetrI   rS   ManagerrU   r   PROJECT_MIXINProjectMixinRECALCULATE_ALL_STATSr  r   Modelrv  rw  r  r  r  r#  rH  rN   rO   rP   <module>rn     s     ) ) - / '     Q P   < I 5 5 p p p p / 3 6 + J 5 Z '	 	 	 A + 5  
		8	$	foo 		2O 	CV^^ CLN  //0 "("@"@A Q
l0 Q
l$V\\ 8, ,$	c 	cFFLL Fp;V\\ p;f1FLL 1B1fll 1rO   