+
    Zej                        R t ^ RIt^ RIt^ RIt^ RIHtHt ^ RIHt ]P                  ! ]
4      t^t]P                  ! R4      tRtR R ltRt]P                  ! R	],           R
,           ]P$                  4      ]P                  ! R],           R,           ]P$                  4      ]P                  ! R],           R
,           ]P$                  4      .t]P                  ! R]P$                  4      t]P                  ! R]P$                  4      t]P                  ! R],           ]P$                  4      t]P                  ! R]P$                  4      tRtRtRt]P                  ! ]R,           ],           ],           R,           ],           ]P$                  4      ]P                  ! ]R,           ],           ],           R,           ]P$                  4      .t]P                  ! R4      tR R ltR R ltR R ltR R  lt R! R" lt!R# )#u  Extracção do prazo de reclamação de créditos a partir do PDF do anúncio CIRE.

O bloco HTML da listagem não traz o prazo — só o PDF do anúncio o diz, e diz-o
textualmente: "O prazo para a reclamação de créditos foi fixado em 30 dias."
Guardamos também a frase que originou o número, porque a data calculada é o que
faz alguém decidir se ainda vai a tempo de reclamar um crédito: quem consulta
tem de poder confirmar a origem em vez de confiar num número sem rasto.

Os PDFs vêm com quebras de linha a meio das frases (layout de duas colunas com
cabeçalho), por isso normalizamos os espaços antes de aplicar os padrões.
N)date	timedelta)Anyz\s+z(\d[\d ]{7,15}\d)c                L    V ^8  d   QhR\         R,          R\         R,          /# )   rawNreturnstr)formats   "P/Volumes/www/segunor-intel-grid/backend/app/services/cire_announcement_parser.py__annotate__r   !   s"     0 03: 0#* 0    c                 n    V '       g   R # \         P                  ! RRV 4      p\        V4      ^	8X  d   V# R # )Nz\D )resublen)r   digitss   & r   	_norm_nifr   !   s0    VVE2s#F[A%6/4/r   z[_*\s]*(\d{1,3})[_*\s]*uh   prazo\s+para\s+a\s+reclama[çc][ãa]o\s+de\s+cr[ée]ditos\s+(?:foi\s+fixado\s+em|fixado\s+em|[ée]\s+de)diasz[Ff]ix[oa](?:-se)?\s+emuI   dias\s+o\s+prazo\s+(?:para\s+a\s+)?reclama[çc][ãa]o\s+de\s+cr[ée]ditosu=   reclama[çc][ãa]o\s+de\s+cr[ée]ditos.{0,60}?no\s+prazo\s+deu+   correm\s+[ée]ditos\s+de\s+(\d{1,3})\s+diasz,no\s+dia\s+(\d{1,2})[-/](\d{1,2})[-/](\d{4})u[   devedora?\s*/\s*insolvente\s*:\s*([^;]{3,300}?)\s*;\s*identifica[çc][ãa]o\s+fiscal\s*:\s*u^   devedora?\s*/\s*insolvente\s*:.{0,200}?com\s+domic[íi]lio\s+na\s+(.+?)(?:,\s*com\s+sede|\.\s)u-   Administrador[a]?\s+d[ae]\s+Insolv[êe]ncia\bu=   (?:domic[íi]lio\s*[:.]|nomead[oa]\s*:|nomeio\s+(?:o|a)\b)\s*z-(?:(?:Sr\.?a?\.?|Dr\.?a?\.?|Eng\.?a?\.?)\s*)*z	.{0,200}?uN   ([^;(]{3,120}?)\s*(?:\(([^)]+)\))?\s*;\s*identifica[çc][ãa]o\s+fiscal\s*:\s*z!([^;(\n]{3,120}?)\s*(?:\(|;|\.\s)z[\w.+-]+@[\w-]+\.[\w.-]+c                L    V ^8  d   QhR\         R,          R\        R,          /# )r   dataNr   )bytesr
   )r   s   "r   r   r   o   s"     * *edl *sTz *r   c                2   V '       g   R#  ^ RI Hp V! \        P                  ! V 4      4      pRP	                  R VP
                   4       4      pTP                  4       '       d   T# R#   \         d"   p\        P                  RT4        Rp?R# Rp?ii ; i)u   Texto do PDF, ou None se não houver camada de texto (alguns anúncios são
digitalizações). Não fazemos OCR — nesses casos o prazo fica estimado.N)	PdfReader
c              3   T   "   T F  qP                  4       ;'       g    R x  K   	  R# 5i)r   N)extract_text).0pages   & r   	<genexpr>pdf_to_text.<locals>.<genexpr>x   s"     N++-333s   ((z*cire_announcement_parser: pypdf falhou: %s)
pypdfr   ioBytesIOjoinpages	Exceptionloggerinfostrip)r   r   readertextes   &    r   pdf_to_textr/   o   sx     #2::d+,yyNNN ::<<4)T)  @!Ds   AA* *B5BBc                0    V ^8  d   QhR\         R\         /# )r   r-   r   r	   )r   s   "r   r   r      s     ! ! ! !r   c                 .    \         P                  R V 4      # ) )_WS_REr   )r-   s   &r   _flatr4      s    ::c4  r   c                >    V ^8  d   QhR\         R\         R,          /# )r   r   r   Nr	   )r   s   "r   r   r      s      S S4Z r   c                v    \         P                  ! RRV 4      P                  R4      pVR,          ;'       g    R# )uP   Cola de volta os códigos postais que o pypdf parte ("4820 -250" -> "4820-250").z(\d{4})\s*-\s*(\d{3})z\1-\2z ,;Ni  NN)r   r   r+   )r   addrs   & r   _clean_addrr9      s2    66*Hc:@@GD:r   c                `    V ^8  d   QhR\         R,          R\        \         \        3,          /# )r   r-   Nr   )r
   dictr   )r   s   "r   r   r      s&     ? ?#* ?c3h ?r   c                p   RRRRRRRRRRRRRRR	RR
RRR/
pV '       g   V# \        V 4      p\         Fd  pVP                  V4      pV'       g   K  \        VP	                  ^4      4      VR&   VP	                  ^ 4      P                  4       R,          VR&    M	  \        P                  V4      pV'       d   \        VP	                  ^4      4      VR&   \        P                  V4      pV'       d+   R VP                  4        4       w  rVp \        WvV4      VR&   \        P                  V4      pV'       dG   VP	                  ^4      P                  4       R,          VR&   \        VP	                  ^4      4      VR&   \        P                  V4      pV'       d   \        VP	                  ^4      4      VR&   \         F  pVP                  V4      pV'       g   K  VP                  4       pV^ ,          ;'       g    RP                  R4      p	V	'       g   KZ  V	R,          VR	&   \!        V4      ^8  d
   V^,          MRp
V
'       d4   \"        P                  V
4      pV'       d   VP	                  ^ 4      MRVR
&   \!        V4      ^8  d   \        V^,          4      VR&    V# 	  V#   \         d     ELi ; i)uy   Campos estruturados a partir do texto do PDF. Todos opcionais — os
anúncios variam bastante de tribunal para tribunal.
claim_daysNclaim_days_sourceeditos_daysinsolvency_date
debtor_nifdebtor_namedebtor_address
admin_nameadmin_email	admin_nif:Ni,  Nc              3   8   "   T F  p\        V4      x  K  	  R # 5i)N)int)r   xs   & r   r!   *parse_announcement_text.<locals>.<genexpr>   s     /JqCFFJs   r7   r   z ,;.)r4   CLAIM_DAYS_RESsearchrH   groupr+   	EDITOS_REINSOLVENCY_DATE_REgroupsr   
ValueError	DEBTOR_REr   DEBTOR_ADDR_REr9   	ADMIN_RESr   EMAIL_RE)r-   outflatrxmdmmyrP   nameparenfounds   &           r   parse_announcement_textr`      sX    	dTt4dt$dtTC 
;DIIdO1 #AGGAJC'(wwqz'7'7'9$'?C#$  	A _M!!$'A/AHHJ/q	%)!^C!" 	AWWQZ--/5M%aggaj1Ld#A +AGGAJ 7IIdOq	R&&v. JL [1_q	$OOE*E38QdCv;?(3CJ# " J9  		s   J& &J54J5c                    V ^8  d   QhR\         R,          R\        R,          R\        R,          R\        R\        \         R,          \        3,          /# )r   pub_dateNr=   r?   opens_claim_windowr   )r   rH   booltuple)r   s   "r   r   r      s[     K KTkKd
K tK 	K
 4$;Kr   c                    V '       d	   V'       g   R# VRJ pVe   TM\         pT \        YR;'       g    ^ ,           R7      ,           V3# )u  (prazo, estimado). O prazo conta a partir da publicação, depois de
correrem os éditos. Quando o PDF não deu o número usamos o supletivo de 30
dias do art. 128º CIRE e marcamos como estimado, para a UI o poder dizer.

Devolve (None, False) para actos que não abrem prazo nenhum.N)days)NF)DEFAULT_CLAIM_DAYSr   )rb   r=   r?   rc   	estimatedrg   s   &&&&  r   compute_deadlinerj      sG     -d"I#/:5GDiT-=-=A%>??JJr   )"__doc__r$   loggingr   datetimer   r   typingr   	getLogger__name__r)   rh   compiler3   _NIF_CAPr   _N
IGNORECASErK   rN   rO   rR   rS   _ADMIN_ANCHOR_ADMIN_INTRO_TITLESrT   rU   r/   r4   r9   r`   rj    r   r   <module>ry      s  
 
  	 $ 			8	$  	F	  0   JJ	8:<	=?F	G

 JJ"R' +B 	B

 JJH2MPWW
" JJEr}}U	ZZ3R]]  JJ-/78MM	
 eMM AO
: JJ$|3g=	1	13;	< 		 JJ$|3g=,	-
	 ::12* !?DKr   