
    @j6                        U d Z ddlmZ ddlZddlZddlZddlZddlZddlZ	ddl
m
Z
mZ ddlmZ dZdZdZd	Zd
ZdZdZdZdZ ej.                         Zdaded<   daddZddZdddZddZddZ ddZ!dd dZ"y)!zLocal utility outage providers for the NWAL Scanner platform.

Normalizes Florence Electricity and Sheffield Utilities into the county-shaped
JSON payload expected by the existing broadcast display.
    )annotationsN)datetimetimezone)Anyz5http://68.208.116.30:7576/data/outageSummary.json?v=2zAhttps://ebill.sheffieldutils.org/maps/Outage_Web_Map/maps/GWT.rpcz https://ebill.sheffieldutils.orgz5https://ebill.sheffieldutils.org/maps/Outage_Web_Map/z:https://ebill.sheffieldutils.org/maps/Outage_Web_Map/maps/ 1D9BF682AF8D25FA7709856C83E9910Fz7|0|4|https://ebill.sheffieldutils.org/maps/Outage_Web_Map/maps/|612278413EC26C34D54A3907AA0CDFD8|coop.nisc.oms.webmap.services.RpcCombinedOutageDetailsService|getCombinedOutageDetails|1|2|3|4|0|<   i  zdict[str, Any] | None_cacheg        c                     t        j                  t        j                        j	                         j                  dd      S )N+00:00Z)r   nowr   utc	isoformatreplace     0/opt/nwal-platform/app/current/outage_sources.py_utc_now_isor   (   s+    <<%//199(CHHr   c           	        | sy 	 t        j                  t        |       j                  dd            }|j                   |j                  t
        j                        }t        dt        t        j                  t
        j                        |j                  t
        j                        z
  j                                     S # t        $ r Y y w xY w)Nr   r   )tzinfor   )r   fromisoformatstrr   r   r   r   maxintr   
astimezonetotal_seconds	Exception)valuedts     r   _parse_iso_age_secondsr    ,   s    ##CJ$6$6sH$EF998<<0B1c8<<5hll8SSbbdeff s   B=C 	CCc                    t        j                         }t        j                  j	                  | ||      5 }|j                         cd d d        S # 1 sw Y   y xY w)N)timeoutcontext)sslcreate_default_contexturllibrequesturlopenread)r'   r"   r#   responses       r   _fetch_bytesr+   8   sI    ((*G			'		J h}}  s   AAc                    t         j                  j                  t        dddddd      } t	        |       }t        j                  |j                  d            }t        |j                  d      xs d	      }t        |j                  d
      xs d	      }|j                  d      xs |j                  d      xs
 t               }t        |      }ddd||t        |j                  d      xs	 |d	kD  rdnd	      |ddt        |d uxr	 |t        kD  ||j                  d      |j                  d      |j                  d      ddS )Nz!application/json, text/plain, */*no-cachezhttp://68.208.116.30:7576/z/NWALScannerPlatform/018 (+local outage adapter))AcceptCache-ControlPragmaReferer
User-Agent)headers	utf-8-sigcustomersOutNowr   customersServed
updateTimelastUpdated01077
LauderdaleALoutageCount   Florence Electricityz!Florence Electricity service areacustomersAffectedcustomersRestoredstreetsAffected)r?   r@   rA   )US_Full_FIPS
CountyName	StateAbbrCustomersTrackedCustomersOutOutageEventsLastUpdatedDateTimeProviderNameProviderArea	SourceURLStale
AgeSeconds
RawSummary)r&   r'   RequestFLORENCE_URLr+   jsonloadsdecoder   getr   r    STALE_AFTER_SECONDS)r'   rawpayloadcustomers_outcustomers_servedupdatedages          r   fetch_florencer\   >   s>   nn$$9' 3K
 % 	G w
CjjK01G$56;!<M7;;'89>Q?kk,'W7;;}+EWG
 
)C  ",%GKK6YPQ@Q1WXZ&.;!D>S+>%>!(-@!A!(-@!A&{{+<=
 r   c           	        | j                  d      st        d      t        j                  | dd        }t	        |t
              r!t        |      dk  st	        |d   t
              st        d      |d d }|d   }|D cg c]*  }t	        |t              rt        j                  d|      r|, }}g }g }t        dt        dt        |      dz
              D ]  }	 ||d	z      ||d
z      ||dz      ||dz      f\  }	}
}}t	        |	t        t        f      rt        t        |	            dkD  r|
dk(  rt	        |t        t        f      ryt        t        |            dkD  rb|dk(  r]||dz      }t	        |t              rEd|cxk  rdk  r:n n7|j                  |       |j                  t        |	      t        |      d        g }g }t%               }t'        ||      D ]G  \  }}|d   |d   f}||v r|j)                  |       |j                  |       |j                  |       I t+        d t-        |      D        d       }t+        d t-        |      D        d       }t+        d t-        |      D        d       }t-        |      D ci c]1  \  }}t	        |t              rt        j                  d|      r|d	z   |3 }}}i }i }||rt-        |      D ]  \  }}||vr|d
z   t        |      k\  r|||d	z      |k7  r+|||d
z      |k7  r9||   }d }d }|dk\  rU||d	z
     |k(  rJ||d
z
     }t	        |t              r|dk\  r|}||dz
     |k(  r]||dz
     }t	        |t              rE|dk\  r@|}n=|dk\  r8||d	z
     | k(  r,d}||d
z
     |k(  r||dz
     }t	        |t              r|dk\  r|}||||<   ||||<    |rt/        |j1                               nd }||} d}!n|r|st        |      } d}!nt/        |      } d}!| t        t        |      t        |            ||||||!dS c c}w # t         t"        t        f$ r Y lw xY wc c}}w )Nz//OKz(Sheffield returned a non-OK GWT response   z'Unexpected Sheffield GWT response shapez\d{6,}r   
   r=         i 7   	   i@B )xyre   rf   c              3  n   K   | ]-  \  }}t        |t              r|j                  d       r|dz    / yw)zjava.lang.Integer/r=   N
isinstancer   
startswith.0iitems      r   	<genexpr>z-_decode_sheffield_response.<locals>.<genexpr>   s7      \'!T%dC0T__EY5Z A \   35c              3  n   K   | ]-  \  }}t        |t              r|j                  d       r|dz    / yw)z+cc.nisc.oms.clientandserver.v2.pojo.Region/r=   Nrh   rk   s      r   ro   z-_decode_sheffield_response.<locals>.<genexpr>   s7      zwq$ *4 5$//Jw:x U zrp   c              3  6   K   | ]  \  }}|d k(  r|dz     yw)zZip Code Regionsr=   Nr   rk   s      r   ro   z-_decode_sheffield_response.<locals>.<genexpr>   s(      ;ga#'99 E ;s   z\d{5}zcustomers-summary-by-zipzevent-count-fallbackzdecoded-marker-counts-fallback)rX   outage_events
outage_idscustomer_countszip_outageszip_customers_servedcoordinatesparse_quality)rj   
ValueErrorrQ   rR   ri   listlenr   re	fullmatchranger   r   floatabsappend
IndexError	TypeErrorsetzipaddnext	enumeratesumvalues)"textstreamr   stringsrn   rt   ru   rx   rm   re   x_typerf   y_typecountdedup_countsdedup_coordsseen_coordscoordkeyinteger_refregion_class_refregion_name_refzip_refsrv   rw   r   zip_codeoutage_countserved_countpossible_outpossible_servedsummary_totalrX   ry   s"                                     r   _decode_sheffield_responser   f   s   ??6"CDDZZQR!Ffd#s6{QjPRUY>ZBCCCR[FRjG
 !dC R\\)T%B 	J  "$O*,K1c!S[2-./ 	#)!a%=&Q-APVWX[\W\P]#] Avq&1sEl+E!H0FbLq3,/CaMF4JbLq1ueS)a5.EI.E#**51&&U1XE!H'EF" !L+-L,/EKO[9 #uSz5:&+E"E"#(  \Yw-? \]acK z)G2D z{A ;71C ;<@BO+4W+= K4dC(R\\(D-I At KH K #%K+-8!&) #	>HAuH$1uF#*va!e}/O+q1uAQ0QHLL Av&Q-;6%a!e}lC0\Q5F#/L!a%=K/&,QUmO!/37Oq<P'6 aF1q5Mk\9 !a%=K/&,QUmO!/37Oq<P'6'(4H%'1=$X.G#	>J 2=C**,-$M
  %2	LJ.L)8 'S_c,.?@ '" 4#&	 	i2 Iz2 		BKs   ?/P&C$P+6Q+QQc                 
   t         j                  j                  t        t        j                  d      dddddt        t        dt        t        dd
	      } t        | d
      }|j                  dd      }t        |      }t               }i dddddddddt        |d         dt        |d         d|ddddd t        d!d"d#dd$|d%   d&|d'   d(|d)   d*|j                  d+i       d,|j                  d-i       S ).Nzutf-8POSTz*/*r-   ztext/x-gwt-rpc; charset=UTF-8z#Mozilla/5.0 NWALScannerPlatform/018mv)
r.   r/   r0   zContent-TypeOriginr1   r2   zX-GWT-Module-BasezX-GWT-Permutationz!coop.nisc.outagewebmap.configName)datamethodr3      )r"   r4   r   )errorsrB   01033rC   ColbertrD   r;   rE   r   rF   rX   rG   rs   rH   rI   Sheffield UtilitiesrJ   z)Sheffield Utilities electric service arearK   rL   FrM   ParseQualityry   	OutageIDsrt   CustomerCountsru   
ZipOutagesrv   ZipCustomersServedrw   )r&   r'   rO   SHEFFIELD_URLSHEFFIELD_BODYencodeSHEFFIELD_ORIGINSHEFFIELD_REFERERSHEFFIELD_MODULE_BASESHEFFIELD_PERMUTATIONr+   rS   r   r   r   rT   )r'   rV   r   decodedrZ   s        r   fetch_sheffieldr      s   nn$$""7+' ;&(?!6!615
	 % G" w
+C::k):4D(.GnGi 	T 	A	
 	GO45 	GO45 	w 	- 	C 	] 	 	a 	0 	W\* 	'"34  	gkk-4!" 	gkk*@"E# r   c                   t        j                          }t        5  | s.t        (|t        z
  t        k  rt        t              cd d d        S t        }d d d        g }g }dt        fdt        ffD ]}  \  }}	  |       }|j                  |       |j                  |d|j                  dd      |j                  dd      |j                  d      t        |j                  d            d	        rt        |j                  d      t              rb|D 	ch c]  }	|	j                  d       }
}	|d   D ]<  }|j                  d      |
vst        |      }d|d<   d|d<   |j                  |       > ddd|j!                  fd       t        |      dt#               ||t%        d |D              t%        d |D              d}t        5  |at        j                          ad d d        t        |      S # 1 sw Y   xY w# t        $ r<}|j                  |d
t        |      d       t        d| d| d       Y d }~d }~ww xY wc c}	w # 1 sw Y   t        |      S xY w)Nr>   r   TrF   r   rG   rH   rL   )providerokcustomersOutoutageEventsrZ   staleF)r   r   errorz
[OUTAGES] z fetch failed: )flushcountiesrI   Fallbackr=   )r9   r   c                Z    j                  t        | j                  dd            d      S )NrB    c   )rT   r   )corders    r   <lambda>z#get_local_outages.<locals>.<lambda>O  s"    		#aeeNB.G*H" M r   )r   zlocal-utility-aggregatorc              3  X   K   | ]"  }t        |j                  d       xs d       $ yw)rF   r   Nr   rT   rl   r   s     r   ro   z$get_local_outages.<locals>.<genexpr>W  #      SQQUU>%:%?a!@ S   (*c              3  X   K   | ]"  }t        |j                  d       xs d       $ yw)rG   r   Nr   r   s     r   ro   z$get_local_outages.<locals>.<genexpr>X  r   r   )successsourcegeneratedAtr   	providerstotalCustomersOuttotalOutageEvents)time_cache_lockr	   _cache_timeCACHE_SECONDSdictr\   r   r   rT   boolr   r   printri   r{   sortr   r   )forcer   previousr   provider_statusprovider_namefetchercountyexcr   current_namesoldfallbackresultr   s                 @r   get_local_outagesr     s^    ))+C	 +k0AM0Q<  
 &(H,.O 
 0	0# Pw	PYFOOF#"") &

>1 = &

>1 =!::&;<fjj12$ P4 Jx||J7>8@A1~.AAJ' 	*Cww~&m;9$(!'+$)	* !$EMMMMN >,#~$  S( SS  S( SSF 
 "iik" <w .  	P"")S$ 
 J}o_SEB$OO	P B*" <s<   'G7G76A7HII7H	I	1II	I$)returnr   )r   r   r   z
int | None)r`   )r'   zurllib.request.Requestr"   r   r   bytes)r   dict[str, Any])r   r   r   r   )F)r   r   r   r   )#__doc__
__future__r   rQ   r}   r$   	threadingr   urllib.requestr&   r   r   typingr   rP   r   r   r   r   r   r   r   rU   Lockr   r	   __annotations__r   r   r    r+   r\   r   r   r   r   r   r   <module>r      s    #  	 
    ' FS5 K T : *   inn $ $I	%PJZ)X?r   