
    [i.                    6   S SK Jr  S SKrS SKrS SKJr  S SKJrJrJr  S SK	J
r
JrJrJrJrJrJr  S SKJrJr  S SKJr  S SKJr  S S	KJr  S S
KJr  S SKJrJrJr  S SK J!r"  S SK#J$r%  S SK&J'r'J(r(  S SK#J)r*  \
" S/S9r+ " S S\5      r, " S S\5      r- " S S\5      r. " S S\5      r/ " S S\5      r0 " S S\5      r1S;S<S jjr2S=S jr3S>S  jr4\\\" \5      4   r5\+Rm                  S!\" \25      /S"9S?S# j5       r7\+Rm                  S$\" \25      /S"9S@S% j5       r8SAS& jr9\+Rm                  S'5      SBS( j5       r:\+Rm                  S)\" \25      /S"9SCS* j5       r;\+Rm                  S+\" \25      /S"9SDS, j5       r<\+Rm                  S-\" \25      /S"9SES. j5       r=\+Rm                  S/5      SFS0 j5       r>\+R                  S15      SCS2 j5       r@\+R                  S35      SCS4 j5       rA\+R                  S55      \" S6S7S894SGS9 jj5       rB\+R                  S$5      SHS: j5       rCg)I    )annotationsN)datetime)	AnnotatedAnyOptional)	APIRouterDependsHeaderHTTPExceptionQueryRequeststatus)	BaseModelField)select)AsyncSession)settings)get_session)Poll
PollStatusRoom)ws)participants)as_utc_naiveutc_now)votingpolls)tagsc                  2    \ rS rSr% SrS\S'   SrS\S'   Srg)	
RoomCreate    strnameNOptional[str]id )__name__
__module____qualname____firstlineno__r$   __annotations__r&   __static_attributes__r'       GC:\Users\jasmi\Projects\line-hihaho-voting\backend\app\routers\polls.pyr    r       s    D#NBr.   r    c                      \ rS rSr% S\S'   \" SS9rS\S'   \" \S9rS\S	'   \" \S9r	S\S
'   \" \
S9rS\S'   \" \
S9rS\S'   SrS\S'   Srg)
PollCreate   r#   title   )
min_lengthz	list[str]options)default_factorytrigger_namestrigger_keyszdict[str, Any]pause_actionzdict[str, dict[str, Any]]winner_actionsr   intduration_secondsr'   N)r(   r)   r*   r+   r,   r   r6   listr8   r9   dictr:   r;   r=   r-   r'   r.   r/   r1   r1      s^    J!,GY,$T:M9:#D9L)9#(#>L.>05d0KN-Kcr.   r1   c                  N    \ rS rSr% SrS\S'   SrS\S'   SrS\S'   SrS	\S
'   Sr	g)PollOpenBody'   NzOptional[datetime]deadline_atr"   r#   open_sourceopen_reasonOptional[dict[str, Any]]trigger_eventr'   )
r(   r)   r*   r+   rC   r,   rD   rE   rG   r-   r'   r.   r/   rA   rA   '   s,    &*K#*KK.2M+2r.   rA   c                  <    \ rS rSr% S\S'   SrS\S'   SrS\S	'   S
rg)PollOverrideBody.   r#   winner_optionNrF   actionTbool
close_pollr'   )r(   r)   r*   r+   r,   rL   rN   r-   r'   r.   r/   rI   rI   .   s    '+F$+Jr.   rI   c                  $    \ rS rSr% SrS\S'   Srg)PollResendBody4   NrF   rL   r'   )r(   r)   r*   r+   rL   r,   r-   r'   r.   r/   rP   rP   4   s    '+F$+r.   rP   c                  .    \ rS rSr% SrS\S'   S\S'   Srg)VoteBody8   Nr%   voter_idr#   choicer'   )r(   r)   r*   r+   rU   r,   r-   r'   r.   r/   rS   rS   8   s    "Hm"Kr.   rS   c                   #    [         R                  (       d  g U [         R                  :w  a  [        [        R                  SS9eg 7f)Ninvalid host keystatus_codedetail)r   host_api_keyr   r   HTTP_403_FORBIDDEN)
x_host_keys    r/   require_host_keyr_   =   s8       X***(A(AJ\]] +s   AAc                   U R                   =(       d    SR                  5       R                  5       nU R                  =(       d    SR                  5       R                  5       n[	        U R
                  [        5      (       a  U R
                  OS n[        U=(       d    0 R                  S5      =(       d    S5      R                  5       nUS:H  =(       a#    UR                  S5      =(       a    [        U5      $ )Nr"   
event_typeplayerzhihaho_event:)rD   striplowerrE   
isinstancerG   r?   r#   get
startswithrM   )bodysourcereasontriggerra   s        r/   allow_player_trigger_openrl   D   s    $"++-335F$"++-335F$.t/A/A4$H$Hd  dGgm((6<"=CCEJXY&"3"3O"DYjIYYr.   c                    U R                   R                  S5      n[        R                  (       d  gU[        R                  :X  a  g[	        U5      (       a  g[        [        R                  SS9e)Nz
X-Host-Keyno_host_key_configuredhost_keyplayer_triggerrX   rY   )headersrf   r   r\   rl   r   r   r]   )requestrh   r^   s      r/   ensure_can_open_pollrs   L   sU    $$\2J  'X*** &&
F$=$=FX
YYr.   z/rooms)dependenciesc                ^  #    U R                   =(       d    [        [        R                  " 5       5      n[        R
                  " XU R                  5      I S h  vN nUR                  5       I S h  vN   UR                  U5      I S h  vN   UR                   UR                  S.$  NN N8 N!7f)N)r&   r$   )	r&   r#   uuiduuid4
voting_svcensure_roomr$   commitrefresh)rh   sessionridrooms       r/   create_roomr   Z   sx     
''
&S&C''dii@@D
..

//$
''499-- As6   AB-B'B-0B)1B-	B+
B-)B-+B-z/rooms/{room_id}/pollsc           	       #    [         R                  " X 5      I S h  vN   [        [        R                  " 5       5      n[        UU UR                  [        R                  " UR                  5      [        R                  S9n[         R                  " UUR                  UR                  UR                  UR                   UR"                  S.5        UR%                  U5        UR'                  5       I S h  vN   UR)                  U5      I S h  vN   [*        R,                  " U 5      I S h  vN   [/        U5      $  GN  NI N2 N7f)N)r&   room_idr3   options_jsonr   )r8   r9   r:   r;   r=   )rx   ry   r#   rv   rw   r   r3   jsondumpsr6   r   draftset_poll_configr8   r9   r:   r;   r=   addrz   r{   	ws_routerbroadcast_room_snapshotpoll_out)r   rh   r|   pidpolls        r/   create_pollr   c   s     

 
 
222
djjl
CjjZZ-D !// -- --"11 $ 5 5	
	 KK
..

//$


+
+G
444D>/ 3( 4sF   ED<CE5D?6EEE,E-E?EEEc                v   U R                   U R                  U R                  [        R                  " U 5      U R
                  R                  U R                  U R                  U R                  (       a  U R                  R                  5       OS [        R                  " U 5      [        R                  " U 5      S.
$ )N)
r&   r   r3   r6   r   rK   winner_sourcerC   configruntime)r&   r   r3   rx   parse_optionsr   valuerK   r   rC   	isoformatparse_poll_configparse_poll_runtime)r   s    r/   r   r      s    gg<<++D1++##++++7;7G7Gt''113T..t4006 r.   z/polls/{poll_id}/openc                j  #    [        X!5      nUR                  [        U 5      I S h  vN nU(       d  [        SS5      eUR                  [
        R                  :X  a  [        U5      $ US:X  a*  UR                  [
        R                  :w  a  [        SS5      e[        UR                  5      nU(       a  U[        5       ::  a  [        SS5      e[        R                  " U5      n[        5       R                  5       S-   US	'   UR                  =(       d    S
US'   UR                   =(       d    SUS'   XGS'   UR"                  b  UR"                  US'   [        R$                  " XWS   5      nU(       a  XS'   [        R&                  " XW5        [
        R                  Ul        Xel
        S Ul        SUl        UR-                  U5        UR/                  5       I S h  vN   UR1                  U5      I S h  vN   [2        R4                  " UR6                  5      I S h  vN   [        U5      $  GN NS N< N7f)N  poll not foundrp     z)player trigger can only open a draft poll  z!deadline_at must be in the futureZ	opened_athostrD   manual_openrE   open_auth_modelast_open_eventcontroller_commandr"   )rs   rf   r   r   r   r   openr   r   r   rC   r   rx   r   r   rD   rE   rG   build_open_pause_commandset_poll_runtimerK   r   r   rz   r{   r   r   r   )	poll_idrh   rr   r|   	auth_moder   rC   r   pause_commands	            r/   	open_pollr      s    $W3IT7++DC!122{{joo%~$$
8H8H)HC!LMMt//0K{gi/C!DEE++D1G"9..036GK!--7GM!-->GM )%%)%7%7!"77m>TUM(5$%.//DK"DDKK
..

//$


+
+DLL
999D>; ,4 9sF   %H3H*F1H3H-H32H/3'H3H1H3-H3/H31H3z/polls/{poll_id}/closec                  #    UR                  [        U 5      I S h  vN nU(       d  [        SS5      e[        R                  " X5      I S h  vN   UR                  5       I S h  vN   UR                  U5      I S h  vN   [        R                  " UR                  5      I S h  vN   [        U5      $  N Nj NT N= N7fNr   r   )rf   r   r   rx   close_poll_and_set_winnerrz   r{   r   r   r   r   r   r|   r   s      r/   rN   rN      s     T7++DC!122

.
.w
===
..

//$


+
+DLL
999D> , >9sW   C B60C B8C %B:&C >B<?'C &B>'C 8C :C <C >C z/polls/{poll_id}/overridec                \  #    UR                  [        U 5      I S h  vN nU(       d  [        SS5      eUR                  R	                  5       nU(       a&  U[
        R                  " U5      ;  a  [        SS5      eUR                  (       a  [        R                  Ul
        U=(       d    S Ul        SUl        [
        R                  " U5      n[        5       R                  5       S-   US'   SUS	'   SUS
'   UR                  =(       d!    [
        R                   " X3R                  S5      n[#        U[$        5      (       aY  SU;  aO  [
        R&                  " U5      UR                  SUR                  SU5      [        5       R                  5       S-   S.nXeS'   [
        R(                  " X55        UR+                  U5        UR-                  5       I S h  vN   UR/                  U5      I S h  vN   [0        R2                  " UR4                  5      I S h  vN   [7        U5      $  GN NS N< N7f)Nr   r   r   z)winner_option must be one of poll optionshost_overrider   override_atr   override_sourceclose_reasonseqrL   r   rK   ri   rL   	issued_atr   )rf   r   r   rK   rc   rx   r   rN   r   closedr   r   r   r   r   rL   build_winner_commandre   r?   next_command_seqr   r   rz   r{   r   r   r   r   )r   rh   r|   r   winnerr   commands          r/   override_poll_winnerr      s    T7++DC!122%%'F&
 8 8 >>C!LMM ''4D(D++D1G$Y002S8GM!'G-GNkkgZ<<TCUCUWfgG'4  !2248!%!3!3)!++h8$Y002S8G )0$%.KK
..

//$


+
+DLL
999D>? ,8 9sF   H,H#F5H,H&H,+H(,'H,H*H,&H,(H,*H,z/polls/{poll_id}/control/resendc                R  #    UR                  [        U 5      I S h  vN nU(       d  [        SS5      e[        R                  " U5      nUR                  S5      =(       d    0 nUR
                  =(       d    UR                  S5      n[        U[        5      (       a  U(       d  [        SS5      e[        R                  " U5      UR                  SU[        5       R                  5       S-   S	.US'   [        5       R                  5       S-   US
'   [        R                  " X45        UR                  U5        UR                  5       I S h  vN   UR                  U5      I S h  vN   [         R"                  " UR$                  5      I S h  vN   S['        U5      S.$  GN NV N? N7f)Nr   r   r   rL   r   zno action available to resendhost_resendr   r   last_resend_atT)okr   )rf   r   r   rx   r   rL   re   r?   r   rK   r   r   r   r   rz   r{   r   r   r   r   )r   rh   r|   r   r   current_commandrL   s          r/   resend_control_commandr      sP    T7++DC!122++D1Gkk"67=2O[[9O//9Ffd##6C!@AA**40++Y((*S0%G ! !(	 3 3 5 ;G.KK
..

//$


+
+DLL
999//+ ,$ 9sF   F'FD-F'
F!F'#F#$'F'F%F'!F'#F'%F'z/polls/{poll_id}/votesc                f  #    UR                  [        U 5      I S h  vN nU(       d  [        SS5      eUR                  =(       d    SR	                  5       nUR
                  R                  S5      n[        R                  " X65      I S h  vN nU(       aH  UR                  UR                  :X  a.  U(       a  XWR                  :w  a  [        SS5      eUR                  nU(       d  [        SS5      e [        R                  " X4XQR                  5      I S h  vN nUR                  5       I S h  vN   [         R"                  " UR                  5      I S h  vN   SXR                  S.$  GNO N NX! [         a.  n	[        U	5      n
U
S	:X  a  [        SS
5      e[        SS5      eS n	A	ff = f N} NW7f)Nr   r   r"   
session_idi  zvoter_id mismatch with sessionr   zvoter_id is requiredinvalid_choicezinvalid choicer   z poll not open or deadline passedT)r   r   rV   )rf   r   r   rU   rc   cookiesparticipants_svcget_session_recordr   participant_idrx   	cast_voterV   
ValueErrorr#   rz   r   r   )r   rh   rr   r|   r   rU   sidsid_recvecodes              r/   	post_voter      sb    T7++DC!122#**,H
//

l
+C$77EEG7??dll2$:$::%EFF))C!788E&&whLL ..


+
+DLL
9997hh??+ ,
 F M E1v##%566C!CDD	E
 9sw   F1E+A.F1E.A&F13$E2 E0E2 F1/F-0'F1F/F1.F10E2 2
F*<)F%%F**F1/F1z/polls/{poll_id}c                   #    UR                  [        U 5      I S h  vN nU(       d  [        SS5      e[        U5      $  N"7fr   )rf   r   r   r   r   s      r/   get_pollr     s8     T7++DC!122D> ,s   A?#Az/polls/{poll_id}/statsc                  #    UR                  [        U 5      I S h  vN nU(       d  [        SS5      e[        R                  " X5      I S h  vN n[        R
                  " U5      nU H  nUR                  US5        M     [        UR                  5       5      n[        R                  " X45      u  pxU UR                  R                  UUUUUR                  [        R                  :X  a  UR                  S.$ S S.$  N N7f)Nr   r   r   )r   r   countstotalleadertierK   )rf   r   r   rx   compute_tallyr   
setdefaultsumvaluespick_winnerr   r   r   r   rK   )	r   r|   r   tallyoptsor   r   r   s	            r/   
poll_statsr     s     T7++DC!122**7<<E##D)DA E((5KF++##/3{{j>O>O/O++  VZ  , =s"   DC>0DD B1D Dz/polls/current.zroom id)descriptionc                6  #    U R                  [        [        5      R                  [        R                  U:H  [        R
                  [        R                  :H  5      5      I S h  vN nUR                  5       nU(       d  [        SS5      e[        U5      $  N27f)Nr   zno open poll for room)execr   r   wherer   r   r   r   firstr   r   )r|   r   resultr   s       r/   current_pollr   3  so     <<t4<<72DKK:??4RS F <<>DC!899D>s   A"B$B%3Bc                   #    UR                  [        [        5      R                  [        R                  U :H  5      5      I S h  vN nUR                  5       nU Vs/ sH  n[        U5      PM     sn$  N/s  snf 7fN)r   r   r   r   r   allr   )r   r|   r   r   ps        r/   
list_pollsr   >  s[     <<t 2 24<<73J KLLFJJLE!&'AHQK'' M's$   AA;A4A;A61A;6A;r   )r^   z4Annotated[Optional[str], Header(alias='X-Host-Key')])rh   rA   returnrM   )rr   r   rh   rA   r   r#   )rh   r    r|   
SessionDep)r   r#   rh   r1   r|   r   )r   r   r   r?   )r   r#   rh   rA   rr   r   r|   r   )r   r#   r|   r   )r   r#   rh   rI   r|   r   )r   r#   rh   rP   r|   r   )r   r#   rh   rS   rr   r   r|   r   )r|   r   r   r#   )r   r#   r|   r   )D
__future__r   r   rv   r   typingr   r   r   fastapir   r	   r
   r   r   r   r   pydanticr   r   sqlmodelr   sqlmodel.ext.asyncio.sessionr   
app.configr   app.dbr   app.models.entitiesr   r   r   app.routersr   r   app.servicesr   r   app.services.time_utilsr   r   r   rx   routerr    r1   rA   rI   rP   rS   r_   rl   rs   r   postr   r   r   r   rN   r   r   r   rf   r   r   r   r   r'   r.   r/   <module>r      s`   "    + + U U U %  5   6 6 ' 9 9 -			" 
 39 3y ,Y ,y 
^ZZ |W[%99:
 XW-=%>$?@. A. %W=M5N4OP Q6 $% &D %W=M5N4OP Q (@P8Q7RS  T F .gFV>W=XY0 Z02 %&@ '@2    $% &* ;@R[;\   $%( &(r.   