Ë
    éÃSj3�  ã                   óP  — d dl mZmZmZmZ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 d dlZd dlZd dlZd dlZd dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlm Z   eejB                  jE                  ejB                  jG                  e$«      d«      «        ejJ                  dd«      Z& ee'd¬«      Z( ejJ                  dd«      Z) ejJ                  dd«      Z* ejJ                  dd«      Z+ ejJ                  dd«      Z, ejJ                  dd«      Z- ejJ                  dd«      Z. ee)«      Z/ ee*«      Z0 ee+«      Z1de.› de/› de0› d e,› de-› d!e1› �e(jd                  d"<   d#e(jd                  d$<   d%e(jd                  d&<   d%e(jd                  d'<   d(e(jd                  d)<   d*e(jd                  d+<   e&e(jd                  d<    e e(«      Z3 G d,„ d-e3jh                  «      Z5 G d.„ d/e3jh                  «      Z6e(jo                  «       5  e3jq                  «        ddd«        ejJ                  d0«      e(_9         ee(jt                  d1d1¬2«      e(_:         ee(«      Z;e;jy                  d3 ejJ                  d4«       ejJ                  d5«      d6d7d8i¬9«      Z= ejJ                  d:d;«      Z>dd<d=d>d?d@dAdBdCdDdddEœZ?d1dFdGdHdIdJdKdLdMdNdOdPdQœZ@dRdSiZAdT„ ZBdU„ ZC ejJ                  dVdW«      ZD ejJ                  dX«      ZE ejJ                  dY«      ZFdZ„ ZG ejJ                  d[«      ZHeHr?eHj“                  d\«      D � ch c]#  } | j•                  «       sŒ| j•                  «       ’Œ% c} ZKnh d]£ZKd^„ ZLeKD �ch c]  } eL|«      sŒ eL|«      ’Œ c}ZMd_„ ZNd`„ ZOda„ ZPdb„ ZQdc„ ZRdd„ ZSde„ ZTe(jª                  df„ «       ZVdg„ ZWdh„ ZXdi„ ZYdj„ ZZdk„ Z[dl„ Z\dm„ Z]dn„ Z^do„ Z_e(jÁ                  d!dpdqg¬r«      e(jÁ                  ddpdqg¬r«      e(jÁ                  dsdpdqg¬r«      dt„ «       «       «       Zae(jÁ                  du«      e(jÁ                  dv«      dw„ «       «       Zbe(jÁ                  dx«      e(jÁ                  dy«      dz„ «       «       Zce(jÁ                  d{«      e(jÁ                  d|«      d}„ «       «       Zde(jÁ                  d~dpdqg¬r«      e(jÁ                  ddpdqg¬r«      d€„ «       «       Zee(jÁ                  d�«      e(jÁ                  d‚«      dƒ„ «       «       Zfe(jÁ                  d„dpdqg¬r«      e(jÁ                  d…dpdqg¬r«      d†„ «       «       Zgd‡„ Zhe(jÁ                  dˆdpdqg¬r«      e(jÁ                  d‰dpdqg¬r«      dŠ„ «       «       Zie(jÁ                  d‹«      e(jÁ                  dŒ«      d�„ «       «       Zje'dŽk(  re(j×                  d%¬�«       yy# 1 sw Y   �Œ‚xY wc c} w c c}w )�é    )ÚFlaskÚrender_templateÚrequestÚredirectÚurl_forÚsessionÚ	send_file)ÚBytesIO)ÚOAuth)Ú
OAuthErrorÚMismatchingStateError)Úload_dotenvN)Ú
monthrange)Údatetime)Ú
quote_plus)ÚProxyFix)Úsecure_filename)Ú
SQLAlchemyz.envÚAPPLICATION_ROOTú/pytimesheetú/static)Ústatic_url_pathÚDB_USERÚ	timesheetÚDB_PASSÚ ÚDB_NAMEÚDB_HOSTÚ	localhostÚDB_PORTÚ3306Ú	DB_DRIVERÚpymysqlzmysql+z://ú:ú@ú/ÚSQLALCHEMY_DATABASE_URIFÚSQLALCHEMY_TRACK_MODIFICATIONSTÚSESSION_COOKIE_SECUREÚSESSION_COOKIE_HTTPONLYÚLaxÚSESSION_COOKIE_SAMESITEÚhttpsÚPREFERRED_URL_SCHEMEc                   óš  — e Zd ZdZej                  ej                  d¬«      Zej                  ej                  d«      dd¬«      Z	ej                  ej                  d«      d¬«      Z
ej                  ej                  dd¬«      Zej                  ej                  d	«      dd¬«      Zej                  ej                  d¬«      Zej                  ej                  dd¬«      Zej                  ej"                  dd
¬«      Zej                  ej                  d«      d¬«      Zej                  ej(                  ej,                  ¬«      Zy)ÚTimesheetEntryÚtimesheet_entriesT©Úprimary_keyéÿ   F©ÚnullableÚindexé2   ©r6   éd   ç        ©r6   Údefault©r=   N)Ú__name__Ú
__module__Ú__qualname__Ú__tablename__ÚdbÚColumnÚIntegerÚidÚStringÚassigneeÚmonthÚyearÚ	issue_keyÚTextÚsummaryÚDateÚ	work_dateÚFloatÚhoursÚsource_fileÚDateTimer   ÚutcnowÚ
created_at© ó    ú /var/www/html/pytimesheet/app.pyr0   r0   6   s  „ Ø'€Mà	�‰�2—:‘:¨4ˆÓ	0€BØ�y‰y˜Ÿ™ 3›°%¸tˆyÓD€HØ�I‰I�b—i‘i “m¨eˆIÓ4€EØ�9‰9�R—Z‘Z¨%°tˆ9Ó<€DØ—	‘	˜"Ÿ)™) C›.°4¸t�	ÓD€IØ�i‰i˜Ÿ™¨$ˆiÓ/€GØ—	‘	˜"Ÿ'™'¨E¸�	Ó>€IØ�I‰I�b—h‘h¨¸ˆIÓ<€EØ—)‘)˜BŸI™I c›N°T�)Ó:€KØ—‘˜2Ÿ;™;°·±�Ó@�JrW   r0   c                   ó\  — e Zd ZdZej                  ej                  d¬«      Zej                  ej                  d«      dd¬«      Z	ej                  ej                  d«      d¬«      Z
ej                  ej                  d«      d¬«      Zej                  ej                  d¬«      Zej                  ej                  dd¬«      Zej                  ej                   dd	¬
«      Zej                  ej$                  ej(                  ¬«      Zej                  ej                  d«      d¬«      Zy)ÚManualTaskEntryÚmanual_task_entriesTr2   r4   Fr5   r9   éô  r;   r<   r>   N)r?   r@   rA   rB   rC   rD   rE   rF   rG   rH   ÚprojectrM   rL   ÚdescriptionrN   rO   rP   Útime_spent_hoursrS   r   rT   rU   Ú
created_byrV   rW   rX   rZ   rZ   E   sè   „ Ø)€Mà	�‰�2—:‘:¨4ˆÓ	0€BØ�y‰y˜Ÿ™ 3›°%¸tˆyÓD€HØ�i‰i˜Ÿ	™	 #›°ˆiÓ7€GØ�i‰i˜Ÿ	™	 #›°ˆiÓ7€GØ—)‘)˜BŸG™G¨d�)Ó3€KØ—	‘	˜"Ÿ'™'¨E¸�	Ó>€IØ—y‘y §¡°EÀ3�yÓGÐØ—‘˜2Ÿ;™;°·±�Ó@€JØ—‘˜2Ÿ9™9 S›>°D�Ó9�JrW   rZ   Ú
SECRET_KEYé   )Úx_protoÚx_hostÚgoogleÚGOOGLE_CLIENT_IDÚGOOGLE_CLIENT_SECRETz<https://accounts.google.com/.well-known/openid-configurationÚscopezemail profile)ÚnameÚ	client_idÚclient_secretÚserver_metadata_urlÚclient_kwargsÚCANONICAL_HOSTzpeoplehub.golsh2e.comÚ5daecffeb86cd40c2da5b814z+712020:dab8b27b-72b1-487b-8601-9891f845e1d7z+712020:b8137e7f-a9eb-4e2c-9334-c553234d7851z+712020:f5e4004d-0a88-455b-b6e7-a8673d0deb9bz+712020:6abe06b5-3b14-4c48-b7c1-0b6dbb0e8f9az+712020:2055ac99-ebe7-4220-b4a6-0f00c31c794cz+712020:12c64083-13c9-4143-8c89-f2abdb6884f0z+712020:b8f39c86-b3b3-4417-8802-65e422e7b1a1z+712020:adebb062-e0f1-4b12-be4a-23fa16640c67)úAkhil SÚAwadheshzMonish BzNikhil Bú
Priyanka SzRamkrishan DzSakshi Jz	Shambhu Kz
Shamsher Sz	Sufiyan AÚAnugrahÚVikasé   é   é   é   é   é   é   é	   é
   é   é   )ÚJanuaryÚFebruaryÚMarchÚAprilÚMayÚJuneÚJulyÚAugustÚ	SeptemberÚOctoberÚNovemberÚDecemberúpriyanka.sangam@golsh2e.comrr   c                  óÐ   — t        j                  dd«      } | j                  d«      D �ch c]1  }|j                  «       sŒ|j                  «       j	                  «       ’Œ3 c}S c c}w )NÚADMIN_EMAILSrŒ   ú,)ÚosÚgetenvÚsplitÚstripÚlower)ÚrawÚemails     rX   Ú_admin_emailsr—   ‰   sF   € Ü
�)‰)�NÐ$AÓ
B€CØ/2¯y©y¸«~ÖO eÀÇÁÅˆE�K‰K‹M×ÑÕ!ÒOÐOùÒOs   ªA#Á  A#c                 ó‚   — | sy| j                  d«      xs dj                  «       j                  «       }|t        «       v S )NFr–   r   )Úgetr”   r“   r—   )Úuserr–   s     rX   Úis_adminr›   Ž   s:   € ÙØØ�X‰X�gÓÒ$ "×+Ñ+Ó-×3Ñ3Ó5€EØ”M“OÐ#Ð#rW   ÚJIRA_SERVERzhttps://golsteam.atlassian.netÚ
JIRA_EMAILÚ
JIRA_TOKENc                  ó   — t         t        fS ©N)r�   ÚJIRA_API_TOKENrV   rW   rX   Ú
_jira_authr¢   ™   s   € ÜœÐ'Ð'rW   ÚMANUAL_TASK_ASSIGNEESr�   >   ÚAkhilrt   rs   rp   c                 óŽ   — | syt        | «      j                  «       } | sydddddœ}|j                  | j                  «       | «      S )Nr   rp   rs   rt   )Úakhilzakhil sÚanugrahÚvikas)Ústrr“   r™   r”   )ri   Úaliasess     rX   Ú_normalize_assignee_namer«   §   sJ   € ÙØÜˆt‹9�?‰?Ó€DÙØàØØØñ	€Gð �;‰;�t—z‘z“| TÓ*Ð*rW   c                 ó”  — | sy| j                  d«      xs dj                  «       j                  «       }|t        v r	t        |   S | j                  d«      xs dj                  «       }|r|j	                  d«      d   nd}t
        D ]?  }|j                  «       j	                  «       d   }||v s||j                  dd«      v sŒ=|c S  y)	z7Match logged-in Google profile to a team assignee name.Nr–   r   ri   r%   r   ú.ú )r™   r”   r“   Úemail_assignee_mapr’   Úassignee_mapÚreplace)rš   r–   ri   Úemail_localrH   Útokens         rX   Úresolve_assignee_from_userr´   ¼   sÂ   € áØà�X‰X�gÓÒ$ "×+Ñ+Ó-×3Ñ3Ó5€EØÔ"Ñ"Ü! %Ñ(Ð(à�H‰H�VÓÒ" ×)Ñ)Ó+€DÙ).�%—+‘+˜cÓ" 1Ò%°B€Kä ò ˆØ—‘Ó ×&Ñ&Ó(¨Ñ+ˆØ�D‰=˜E [×%8Ñ%8¸¸cÓ%BÒBØŠOðð
 rW   c                 óª   ‡‡— | €yt        | t        «      r| j                  «       S g Šˆˆfd„Š ‰| «       dj                  ‰«      j                  «       S )z?Convert Jira rich-text (ADF) or plain strings to readable text.r   c                 ó  •— t        | t        «      rX| j                  d«      dk(  r!‰j                  | j                  dd«      «       | j                  d«      xs g D ]
  } ‰|«       Œ y t        | t        «      r| D ]
  } ‰|«       Œ y y )NÚtypeÚtextr   Úcontent)Ú
isinstanceÚdictr™   ÚappendÚlist)ÚnodeÚchildÚitemÚtextsÚwalks      €€rX   rÂ   zextract_adf_text.<locals>.walkÙ   s~   ø€ Ü�dœDÔ!Ø�x‰x˜Ó 6Ò)Ø—‘˜TŸX™X f¨bÓ1Ô2ØŸ™ )Ó,Ò2°ò �Ù�U•ñä˜œdÔ#Øò �Ù�T•
ñð $rW   r®   )rº   r©   r“   Újoin)ÚvaluerÁ   rÂ   s    @@rX   Úextract_adf_textrÅ   Ð   sK   ù€ à€}ØÜ�%œÔØ�{‰{‹}Ðà€Eõñ 	ˆ„KØ�8‰8�E‹?× Ñ Ó"Ð"rW   c                 ó®   — t         › d�}| dddœ}t        j                  ||t        «       ddid¬«      }|j	                  «        |j                  «       d	   S )
Nz/rest/api/3/search/jqliè  z$summary,project,assignee,description)ÚjqlÚ
maxResultsÚfieldsÚAcceptúapplication/jsoné<   ©ÚparamsÚauthÚheadersÚtimeoutÚissues)rœ   Úrequestsr™   r¢   Úraise_for_statusÚjson)rÇ   ÚurlrÎ   Úresponses       rX   Úsearch_jira_issuesrØ   ç   se   € ÜˆMÐ/Ð
0€CàØØ8ñ€Fô
 �|‰|ØØÜ‹\ØÐ-Ð.Øô€Hð ×ÑÔØ�=‰=‹?˜8Ñ$Ð$rW   c                 óv  — t         › d| › d�}g }d}	 t        j                  ||ddœt        «       ddid¬	«      }|j	                  «        |j                  «       }|j                  |j                  d
g «      «       ||j                  dd«      z   |j                  dd«      k\  r	 |S ||j                  dd«      z  }Œ©)Nz/rest/api/3/issue/z/worklogr   r:   )ÚstartAtrÈ   rÊ   rË   rÌ   rÍ   ÚworklogsrÈ   Útotal)rœ   rÓ   r™   r¢   rÔ   rÕ   Úextend)rK   rÖ   rÛ   Ústart_atr×   Úpayloads         rX   Úget_issue_worklogsrà   ù   sÃ   € ÜˆMÐ+¨I¨;°hÐ
?€CØ€HØ€HØ
Ü—<‘<ØØ'°sÑ;Ü“ØÐ1Ð2Øô
ˆð 	×!Ñ!Ô#Ø—-‘-“/ˆØ�‰˜Ÿ™ J°Ó3Ô4Ø�g—k‘k ,°Ó2Ñ2°g·k±kÀ'È1Ó6MÒMØà€Oð 	�G—K‘K ¨cÓ2Ñ2ˆð rW   c           
      ó,  — t        | «      }|t        vry t        j                  |«      }|sy |› d|d›d�}t	        ||«      d   }|› d|d›d|› �}t        j                  ||¬«      j                  d«      j                  «       }t        j                  |d«      j                  «       }	t        j                  |d«      j                  «       }
t        j                  j                  t        j                  |k(  t        j                   |	k\  t        j                   |
k  «      j#                  t        j                   j%                  «       t        j&                  j%                  «       «      j)                  «       }|sy g }|D ]i  }|j+                  |j                  |j,                  |j.                  |j0                  xs d|j                   j                  d«      |j2                  d	œ«       Œk t        j4                  |«      }|j7                  g d
¢dddd¬«      }d |j8                  _        |j=                  «       j?                  d«      jA                  d«      }|D ]  }||j8                  vsŒd||<   Œ |g d
¢|z      }|jC                  dd«      }|D ].  }t        jD                  ||   d¬«      jA                  d«      ||<   Œ0 ||   jG                  «       j?                  d«      j                  «       }g d¢|z   }t        j4                  |g|j8                  ¬«      }t?        tG        |«      d«      }g d¢dgtI        |«      dz
  z  z   |gz   }t        j4                  |g|j8                  ¬«      }|jC                  dd«      }t        jJ                  |||gd¬«      S )Nú-Ú02dú-01rb   ©ÚstartÚendú%d-%bú%Y-%m-%dr   ©ÚAssigneeÚProjectÚSummaryÚDescriptionrN   úTime Spent (h)©rë   rì   rí   rî   rN   rï   Úsumr   ©r7   ÚcolumnsÚvaluesÚaggfuncÚ
fill_valueru   Úcoerce©Úerrors©zTotal (per day)r   r   r   ©ró   ©zTotal Monthly Hoursr   r   r   r;   T©Úignore_index)&r«   r£   Úmonth_name_mapr™   r   ÚpdÚ
date_rangeÚstrftimeÚtolistr   ÚstrptimeÚdaterZ   ÚqueryÚfilterrH   rO   Úorder_byÚascrF   Úallr¼   r]   rM   r^   r_   Ú	DataFrameÚpivot_tableró   ri   Úreset_indexÚroundÚfillnar±   Ú
to_numericrñ   ÚlenÚconcat)Úassignee_nameÚselected_monthrJ   Únormalized_namerI   Ú
start_dateÚend_dayÚend_dateÚ	all_datesÚstart_dtÚend_dtÚentriesÚrowsÚentryÚdfÚpivotr  Úpivot_for_sumÚcolÚtotal_row_valuesÚ	total_rowÚtotal_row_dfÚmonthly_total_valueÚmonthly_total_rowÚmonthly_total_dfÚpivot_displays                             rX   Úgenerate_manual_task_reportr*    sK  € Ü.¨}Ó=€OØÔ3Ñ3Øä×Ñ˜~Ó.€EÙØà�6˜˜5 ˜+ SÐ)€JÜ˜˜uÓ% aÑ(€GØ��q˜˜s˜ 1 W IÐ.€HÜ—‘ J°HÔ=×FÑFÀwÓO×VÑVÓX€Iä× Ñ  ¨ZÓ8×=Ñ=Ó?€HÜ×Ñ˜x¨Ó4×9Ñ9Ó;€Fä×Ñ×$Ñ$Ü×$Ñ$¨Ñ7Ü×%Ñ%¨Ñ1Ü×%Ñ%¨Ñ/ó	
÷
 
‰”/×+Ñ+×/Ñ/Ó1´?×3EÑ3E×3IÑ3IÓ3KÓ	Lß	‰‹ð ñ Øà€DØò ˆØ�‰ØŸ™Ø—}‘}Ø—}‘}Ø ×,Ñ,Ò2°Ø—O‘O×,Ñ,¨WÓ5Ø#×4Ñ4ñ
õ 	ðô 
�‰�dÓ	€BØ�N‰NÚ?ØØØØð ó €Eð €E‡M�MÔØ×ÑÓ×%Ñ% aÓ(×/Ñ/°Ó3€Eàò ˆØ�u—}‘}Ò$ØˆE�$ŠKðð ÒCÀiÑOÑP€Eà—M‘M " aÓ(€MØò ZˆÜŸ]™]¨=¸Ñ+=ÀhÔO×VÑVÐWXÓYˆ�cÒðZà$ YÑ/×3Ñ3Ó5×;Ñ;¸AÓ>×EÑEÓGÐâ/Ð2BÑB€IÜ—<‘<  °U·]±]ÔC€Lä¤Ð$4Ó 5°qÓ9ÐÚ;¸r¸dÄcÈ)ÃnÐWXÑFXÑ>YÑYÐ]pÐ\qÑqÐÜ—|‘|Ð%6Ð$7ÀÇÁÔOÐà—M‘M # rÓ*€MÜ�9‰9�m \Ð3CÐDÐSWÔXÐXrW   c                 óÜ  — t        | «      } | t        v rt        | ||«      S t        j	                  | «      }|sy t
        j	                  |«      }|sy |› d|d›d�}t        ||«      d   }|› d|d›d|› �}t        j                  ||¬«      j                  d«      j                  «       }d|› d|› d	|› d
�}	t        |	«      }
g }|
D �]m  }|j	                  di «      }|j	                  dd«      }|j	                  di «      j	                  dd«      }t        |j	                  d«      «      }|j	                  d«      xs i }|j	                  d«      xs | }|d   }t        |«      D ]Í  }|j	                  d«      xs i }|j	                  d«      |k7  rŒ-|j	                  d«      xs dd d }|r
||k  s||kD  rŒRt        j                  |d«      j                  d«      }t!        |j	                  dd«      dz  d«      }t        |j	                  d«      «      }|xs |}|j#                  ||||||dœ«       ŒÏ �Œp t        j$                  |«      }|j&                  ry |j)                  g d¢d d!d"d¬#«      }d |j*                  _        |j/                  «       j!                  d«      j1                  d«      }|D ]  }||j*                  vsŒd||<   Œ |g d¢|z      }|j3                  dd«      }|D ].  }t        j4                  ||   d$¬%«      j1                  d«      ||<   Œ0 ||   j7                  «       j!                  d«      j                  «       } g d&¢| z   }!t        j$                  |!g|j*                  ¬'«      }"t!        t7        | «      d«      }#g d(¢dgt9        |«      dz
  z  z   |#gz   }$t        j$                  |$g|j*                  ¬'«      }%|j3                  d)d«      }&t        j:                  |&|"|%gd*¬+«      S ),Nrâ   rã   rä   rb   rå   rè   zassignee = z AND worklogDate >= "z" AND worklogDate <= "z" ORDER BY created ASCrÉ   rM   r   r]   ri   r^   rH   ÚdisplayNameÚkeyÚauthorÚ	accountIdÚstartedr}   ré   ÚtimeSpentSecondsr   i  ru   Úcommentrê   rð   rN   rï   rñ   rò   r÷   rø   rú   rû   rü   r;   Trý   )r«   r£   r*  r°   r™   rÿ   r   r   r  r  r  rØ   rÅ   rà   r   r  r  r¼   r  Úemptyr  ró   ri   r  r  r±   r  rñ   r  r  )'r  r  rJ   Úassignee_idrI   r  r  r  r  rÇ   rÒ   ÚdataÚissuerÉ   rM   r]   Úissue_descriptionÚassignee_fieldÚassignee_displayr-  Úlogr.  r0  Údate_strÚtime_spent_hrsÚworklog_commentr^   r  r   r  r!  r"  r#  r$  r%  r&  r'  r(  r)  s'                                          rX   Úgenerate_jira_worklog_reportr>  V  s  € Ü,¨]Ó;€MØÔ-Ñ-Ü*¨=¸.È$ÓOÐOä×"Ñ" =Ó1€KÙØä×Ñ˜~Ó.€EÙØà�6˜˜5 ˜+ SÐ)€JÜ˜˜uÓ% aÑ(€GØ��q˜˜s˜ 1 W IÐ.€HÜ—‘ J°HÔ=×FÑFÀwÓO×VÑVÓX€Ið �k�]ð #Ø)˜lð +Ø'˜jð )ð	 ð ô   Ó$€FØ€Dàó ˆØ—‘˜8 RÓ(ˆØ—*‘*˜Y¨Ó+ˆØ—*‘*˜Y¨Ó+×/Ñ/°¸Ó;ˆÜ,¨V¯Z©Z¸Ó-FÓGÐØŸ™ JÓ/Ò5°2ˆØ)×-Ñ-¨mÓ<ÒMÀÐØ�E‰lˆä% cÓ*ò 	ˆCØ—W‘W˜XÓ&Ò,¨"ˆFØ�z‰z˜+Ó&¨+Ò5Øà—w‘w˜yÓ)Ò/¨R°°"Ð5ˆGÙ˜g¨
Ò2°gÀÒ6HØä×(Ñ(¨°*Ó=×FÑFÀwÓOˆHÜ" 3§7¡7Ð+=¸qÓ#AÀDÑ#HÈ!ÓLˆNÜ.¨s¯w©w°yÓ/AÓBˆOØ)Ò>Ð->ˆKà�K‰KØ,Ø"Ø"Ø*Ø Ø"0ñõ ò	ðô@ 
�‰�dÓ	€BØ	‡x‚xØà�N‰NÚ?ØØØØð ó €Eð €E‡M�MÔØ×ÑÓ×%Ñ% aÓ(×/Ñ/°Ó3€Eàò ˆØ�u—}‘}Ò$ØˆE�$ŠKðð ÒCÀiÑOÑP€Eà—M‘M " aÓ(€MØò ZˆÜŸ]™]¨=¸Ñ+=ÀhÔO×VÑVÐWXÓYˆ�cÒðZà$ YÑ/×3Ñ3Ó5×;Ñ;¸AÓ>×EÑEÓGÐâ/Ð2BÑB€IÜ—<‘<  °U·]±]ÔC€Lä¤Ð$4Ó 5°qÓ9Ðâ+Øˆ$”#�i“. 1Ñ$Ñ
%ñ	&àÐ
ñ	 ð ô
 —|‘|Ð%6Ð$7ÀÇÁÔOÐà—M‘M # rÓ*€MÜ�9‰9�m \Ð3CÐDÐSWÔXÐXrW   c                 ó   — t        «       }t        j                  |d¬«      5 }| j                  |dd¬«       d d d «       |j	                  d«       |› d|› d|› �j                  dd«      }d	|› d
�}||fS # 1 sw Y   Œ>xY w)NÚopenpyxl©ÚengineFÚ	Timesheet©r7   Ú
sheet_namer   Ú_r®   Ú
Timesheet_z.xlsx)r
   r   ÚExcelWriterÚto_excelÚseekr±   )r  r  rI   rJ   ÚbufferÚwriterÚ	safe_nameÚfilenames           rX   Úbuild_excel_downloadrO  º  s‹   € Ü‹Y€FÜ	�‰˜ zÔ	2ð A°fØ
�‰�F %°KˆÔ@÷Aà
‡K�K�„NØ �/  5 '¨¨4¨&Ð1×9Ñ9¸#¸sÓC€IØ˜I˜; eÐ,€HØ�8ÐÐ÷Að Aús   ¢A4Á4A=c                  óè   — t         j                  j                  d«      ryt         j                  j	                  dd«      d   } | t
        ddhv ryt        dt
        › t         j                  › �d	¬
«      S )z8Keep OAuth session/callback on one hostname when needed.r   Nr$   rb   r   r   z	127.0.0.1úhttps://i.  )Úcode)r   ÚpathÚ
startswithÚhostr’   rn   r   Ú	full_path)rU  s    rX   Úensure_canonical_hostrW  Ä  sl   € ô ‡|�|×Ñ˜yÔ)Øä�<‰<×Ñ˜c 1Ó% aÑ(€DØ” ¨[Ð9Ñ9ØäØ
”>Ð"¤7×#4Ñ#4Ð"5Ð6Øôð rW   c                 óª   — t         j                  j                  d«      xs dj                  d«      }|s| S | j	                  d«      r|› | › �S |› d| › �S )Nr   r   r&   )ÚappÚconfigr™   ÚrstriprT  )rS  Úprefixs     rX   Ú	_app_pathr]  Ô  sW   € Ü�j‰j�n‰nÐ/Ó0Ò6°B×>Ñ>¸sÓC€FÙØˆØ $§¡°Ô 4ˆfˆX�d�VÐÐL¸V¸HÀAÀdÀVÐ:LÐLrW   c                  óÄ   — t        j                  d«      } | r6| j                  d«      j                  d«      r| j                  d«      dz   S | S dt        › t        d«      › �S )NÚGOOGLE_REDIRECT_URIr&   r   ú/auth/callbackrQ  )r�   r‘   r[  Úendswithrn   r]  )Úenv_redirects    rX   Ú_oauth_callback_urlrc  Û  se   € ä—9‘9Ð2Ó3€LÙð ×Ñ˜sÓ#×,Ñ,¨^Ô<Ø×&Ñ& sÓ+Ð.>Ñ>Ð>ØÐà”nÐ%¤iÐ0@Ó&AÐ%BÐCÐCrW   c                  ó<  — t         j                  j                  d«      t         j                  j                  d«      dœ} t        j                  j                  t        | j                  d«      «      }t        j                  || «      } t        j                  di | ¤ŽS )zKExchange auth code for token without parsing id_token (avoids jwks errors).rR  Ústate)rR  re  rV   )	r   Úargsr™   re   Ú	frameworkÚget_state_datar   Ú_format_state_paramsÚfetch_access_token)rÎ   Ú
state_datas     rX   Ú_exchange_google_coderl  è  sx   € ô —‘× Ñ  Ó(Ü—‘×!Ñ! 'Ó*ñ€Fô ×!Ñ!×0Ñ0´¸&¿*¹*ÀWÓ:MÓN€JÜ×(Ñ(¨°VÓ<€FÜ×$Ñ$Ñ. vÑ.Ð.rW   c                 óš   — | j                  d«      }|r|S t        j                  d| ¬«      }|j                  «        |j                  «       S )NÚuserinfoz-https://www.googleapis.com/oauth2/v3/userinfo)r³   )r™   re   rÔ   rÕ   )r³   Ú	user_infoÚresps      rX   Ú_fetch_google_userrq  ó  sL   € Ø—	‘	˜*Ó%€IÙØÐÜ�:‰:Ø7Øð ó €Dð 	×ÑÔØ�9‰9‹;ÐrW   c                 óp  ‡— t        j                  d«      }|r||k7  ry| j                  «       j                  «       }|dv rdddœS t        D ]h  Š‰j                  «       j                  «       d   }||‰j                  «       fv sŒ9t        ˆfd„t        j                  «       D «       |› d	�«      }‰|dœc S  y)
z2Validate username/password login for team members.ÚLOCAL_LOGIN_PASSWORDN)ÚadminÚpriyankaz
priyanka srr   zpriyanka.sangam@gols.in)ri   r–   r   c              3   ó4   •K  — | ]  \  }}|‰k(  sŒ|–— Œ y ­wr    rV   )Ú.0ÚeÚarH   s      €rX   ú	<genexpr>z*authenticate_local_user.<locals>.<genexpr>  s   øè ø€ ÒK‘t�q˜!¸QÀ(»]”ÑKùs   ƒ‘z@gols.in)	r�   r‘   r”   r“   r°   r’   Únextr¯   Úitems)ÚusernameÚpasswordÚexpected_passwordr-  r³   r–   rH   s         @rX   Úauthenticate_local_userr€  ÿ  sÀ   ø€ äŸ	™	Ð"8Ó9ÐÙ Ð,=Ò =Øà
�.‰.Ó
×
 Ñ
 Ó
"€CØ
Ð1Ñ1Ø$Ð/HÑIÐIä ò 6ˆØ—‘Ó ×&Ñ&Ó(¨Ñ+ˆØ�5˜(Ÿ.™.Ó*Ð+Ò+ÜÛKÔ1×7Ñ7Ó9ÔKØ�'˜Ð"óˆEð %¨uÑ5Ò5ð6ð rW   c                 ó¤   — |D ]K  }|| j                   v sŒ| |   }t        j                  |«      rŒ-t        |«      j	                  «       }|sŒI|c S  y)Nr   )r7   r   Úisnar©   r“   )ÚrowÚ
candidatesri   rÄ   s       rX   Ú_first_non_emptyr…    sS   € Øò ˆØ�3—9‘9ÒØ˜‘IˆEÜ�w‰w�uŒ~ØÜ˜“J×$Ñ$Ó&ˆEÚØ’ðð rW   c                 ó´   — g }| j                   D ]F  }|€Œt        |«      j                  «       }t        j                  d|«      sŒ6|j                  |«       ŒH |S )Nz$^\d{1,2}[-/]([A-Za-z]{3,9}|\d{1,2})$)ró   r©   r“   ÚreÚmatchr¼   )r  ró   Úcolumnr¸   s       rX   Ú_date_columns_from_framerŠ  !  sV   € Ø€GØ—*‘*ò !ˆØˆ>ØÜ�6‹{× Ñ Ó"ˆÜ�8‰8Ð;¸TÕBØ�N‰N˜4Õ ð!ð €NrW   c                 óÎ   — t        | «      j                  «       }dD ]8  }	 t        j                  ||«      j	                  |¬«      j                  «       c S  y # t        $ r Y ŒGw xY w)N)rè   z%d-%Bz%d-%m)rJ   )r©   r“   r   r  r±   r  Ú
ValueError)Ú	day_labelrJ   r•   Úfmts       rX   Ú_parse_work_dater�  ,  sk   € Ü
ˆi‹.×
Ñ
Ó
 €CØ*ò ˆð	Ü×$Ñ$ S¨#Ó.×6Ñ6¸DÐ6ÓA×FÑFÓHÒHðð
 øô ò 	Ùð	ús    3AÁ	A$Á#A$c                 óx  — t         j                  j                  t        j                  t        |«      «      }t        j                  t        j                  d¬«       | j                  |«       t        j                  |«      }|j                  ryt        |«      }|st        d«      ‚t        |«      }|}	d}
|j                  «       D ]›  \  }}t        |g d¢«      }t        |g d¢«      }|D ]u  }||   }t        j                   |«      rŒ	 t#        |«      }|dk  rŒ0t'        ||«      }|sŒ?t)        ||	||||||¬«      }t*        j,                  j/                  |«       |
dz  }
Œw Œ� |
r t*        j,                  j1                  «        |
S t*        j,                  j3                  «        |
S # t$        t        f$ r Y ŒÍw xY w)	NT)Úexist_okr   z>No day columns like 01-Feb were found in the uploaded workbook)z	Issue Keyz	Issue keyÚIssueÚKey)rí   zTask SummaryÚTitle)rH   rI   rJ   rK   rM   rO   rQ   rR   rb   )r�   rS  rÃ   rY  Úinstance_pathr   ÚmakedirsÚsaver   Ú
read_excelr3  rŠ  rŒ  ÚintÚiterrowsr…  r‚  ÚfloatÚ	TypeErrorr�  r0   rC   r   ÚaddÚcommitÚrollback)Úfile_storagerH   rI   rJ   Úsource_nameÚupload_pathr  Údate_columnsÚyear_intÚ
month_nameÚcreated_countrF  rƒ  rK   rM   Ú
day_columnrÄ   rQ   rO   Úrecords                       rX   Úimport_excel_timesheetr©  6  s™  € Ü—'‘'—,‘,œs×0Ñ0´/À+Ó2NÓO€KÜ‡K�K”×!Ñ!¨DÕ1Ø×Ñ�kÔ"ä	�‰�{Ó	#€BØ	‡x‚xØä+¨BÓ/€LÙÜÐYÓZÐZä�4‹y€HØ€JØ€Mà—+‘+“-ò ‰ˆˆ3Ü$ SÒ*TÓUˆ	Ü" 3Ò(LÓMˆà&ò 	ˆJØ˜
‘OˆEÜ�w‰w�uŒ~ØðÜ˜e›�ð ˜ŠzØä(¨°XÓ>ˆIÙØä#Ø!Ø ØØ#ØØ#ØØ'ô	ˆFô �J‰J�N‰N˜6Ô"Ø˜QÑ‰Mñ5	ð	ñ@ Ü
�
‰
×ÑÔð Ðô 	�
‰
×ÑÔàÐøô7 œzÐ*ò Ùðús   Ä
F'Æ'F9Æ8F9ÚGETÚPOST)Úmethodsz/pytimesheet/c                  ó¢  — t        j                  d«      rt        t        d«      «      S t        j
                  dk(  r‡t        j                  j                  dd«      j                  «       } t        j                  j                  dd«      }t        | |«      }|r|t         d<   t        t        d«      «      S t        dd d¬	«      S t        dd ¬
«      S )Nrš   ÚgetSheetr«  r}  r   r~  ú
index.htmlzInvalid username or password.©rš   Úerror)rš   )
r   r™   r   r   r   ÚmethodÚformr“   r€  r   )r}  r~  rš   s      rX   r7   r7   r  s®   € ô ‡{�{�6ÔÜœ 
Ó+Ó,Ð,ä‡~�~˜ÒÜ—<‘<×#Ñ# J°Ó3×9Ñ9Ó;ˆÜ—<‘<×#Ñ# J°Ó3ˆÜ& x°Ó:ˆÙØ"ŒG�F‰OÜœG JÓ/Ó0Ð0ÜØØØ1ô
ð 	
ô ˜<¨dÔ3Ð3rW   z/google-loginz/pytimesheet/google-loginc                  ó@   — t        «       } t        j                  | «      S r    )rc  re   Úauthorize_redirect)Úcallback_urls    rX   Úloginr·  ‰  s   € ô 'Ó(€LÜ×$Ñ$ \Ó2Ð2rW   r`  z/pytimesheet/auth/callbackc                  óD  — t         j                  j                  d«      } | r3t         j                  j                  d| «      }t        dd d|› �¬«      dfS 	 t	        «       }t        |«      t        d<   t        t        d«      «      S # t        $ r t        dd d	t        › d
�¬«      dfcY S t        $ r5}t        dd d|j                  xs |j                  › �¬«      dfcY d }~S d }~wt        $ r2 t        j                   j#                  d«       t        dd d¬«      dfcY S w xY w)Nr±  Úerror_descriptionr¯  zGoogle sign-in failed: r°  i�  rš   r®  z2Sign-in session expired. Open the site at https://z and try again.zOAuth callback failedz!Sign-in failed. Please try again.r\   )r   rf  r™   r   rl  rq  r   r   r   r   rn   r   r^   r±  Ú	ExceptionrY  ÚloggerÚ	exception)Úoauth_errorr^   r³   rx  s       rX   Úcallbackr¾  �  s8  € ô —,‘,×"Ñ" 7Ó+€KÙÜ—l‘l×&Ñ&Ð':¸KÓHˆÜØ˜tÐ-DÀ[ÀMÐ+Rô
àðð 	ðÜ%Ó'ˆÜ,¨UÓ3Œ�‰Üœ 
Ó+Ó,Ð,øÜ ò ÜØØØFÄ~ÐFVÐVeÐfô
ð ð	ò 	ô
 ò ÜØØØ+¨A¯M©MÒ,D¸Q¿W¹WÐ+EÐFô
ð ð	õ 	ûô
 ò Ü�
‰
×ÑÐ4Ô5ÜØØØ5ô
ð ð	ò 	ðús*   Á/B Â!DÂ)DÂ1*C!ÃDÃ!;DÄDz/logoutz/pytimesheet/logoutc                  óV   — t        j                  dd «       t        t        d«      «      S )Nrš   r7   )r   Úpopr   r   rV   rW   rX   ÚlogoutrÁ  ³  s"   € ô ‡K�K�˜ÔÜ”G˜GÓ$Ó%Ð%rW   z	/add-taskz/pytimesheet/add-taskc                  ó:  — t        j                  d«      st        t        d«      «      S t        j                  d«      } t	        | «      }t        | «      xs d}t        |«      }|s|t        vrt        	 di t        | d¬«      ¤ŽS t        j                  dk(  �rZt        j                  j                  d«      xs dj                  «       }t        j                  j                  d«      xs dj                  «       }t        j                  j                  d	«      xs dj                  «       }t        j                  j                  d
«      xs dj                  «       }t        j                  j                  d«      xs dj                  «       }t        j                  j                  d«      xs dj                  «       }	|r|r|r|r|	sNt        d| |t        t        j!                  «       «      |dt#        j$                  «       j'                  d«      ¬«      S 	 t#        j(                  |d«      j+                  «       }
t-        |	«      }t1        |||||
|| j                  d«      ¬«      }t2        j                   j5                  |«       t2        j                   j7                  «        t        d| |t        t        j!                  «       «      |dt#        j$                  «       j'                  d«      ¬«      S t        d| |t        t        j!                  «       «      |t#        j$                  «       j'                  d«      ¬«      S # t.        $ rQ t        d| |t        t        j!                  «       «      |dt#        j$                  «       j'                  d«      ¬«      cY S w xY w)Nrš   r7   r   z+You are not authorized to add manual tasks.)r±  r«  rH   r]   rM   r^   rO   Ú
time_spentzadd_task.htmlz Please fill all required fields.ré   )rš   r›   Ú	assigneesÚdefault_assigneer±  Útodayz,Please enter a valid date and numeric hours.r–   )rH   r]   rM   r^   rO   r_   r`   zTask saved successfully.)rš   r›   rÄ  rÅ  ÚsuccessrÆ  )rš   r›   rÄ  rÅ  rÆ  ©z	form.html)r   r™   r   r   r›   r´   r«   r£   r   Ú_form_contextr   r²  r³  r“   r½   r°   Úkeysr   Únowr  r  r  r›  rŒ  rZ   rC   r�  rž  )rš   rt  rÅ  Únormalized_defaultrH   r]   rM   r^   rO   rÃ  Úparsed_dateÚparsed_hoursr  s                rX   Úadd_taskrÏ  º  sô  € ô �;‰;�vÔÜœ Ó(Ó)Ð)ä�;‰;�vÓ€DÜ�T‹N€EÜ1°$Ó7Ò=¸2Ðô 2Ð2BÓCÐÙÐ'Ô/DÑDÜØñ
äØØCôñ
ð 	
ô ‡~�~˜ÓÜ—L‘L×$Ñ$ ZÓ0Ò6°B×=Ñ=Ó?ˆÜ—<‘<×#Ñ# IÓ.Ò4°"×;Ñ;Ó=ˆÜ—<‘<×#Ñ# IÓ.Ò4°"×;Ñ;Ó=ˆÜ—|‘|×'Ñ'¨Ó6Ò<¸"×CÑCÓEˆÜ—\‘\×%Ñ% kÓ2Ò8°b×?Ñ?ÓAˆ	Ü—l‘l×&Ñ& |Ó4Ò:¸×AÑAÓCˆ
á™w©g¹YÉjÜ"ØØØÜœ|×0Ñ0Ó2Ó3Ø!1Ø8Ü—l‘l“n×-Ñ-¨jÓ9ôð ð	Ü"×+Ñ+¨I°zÓB×GÑGÓIˆKÜ  Ó,ˆLô  ØØØØ#Ø!Ø)Ø—x‘x Ó(ô
ˆô 	�
‰
�‰�uÔÜ
�
‰
×ÑÔäØØØÜœ<×,Ñ,Ó.Ó/Ø-Ø.Ü—,‘,“.×)Ñ)¨*Ó5ô
ð 	
ô ØØØÜ”|×(Ñ(Ó*Ó+Ø)Ü�l‰l‹n×%Ñ% jÓ1ôð øôC ò 		Ü"ØØØÜœ|×0Ñ0Ó2Ó3Ø!1ØDÜ—l‘l“n×-Ñ-¨jÓ9ôò ð		ús   È/M  Í ANÎNz/download-task-excelz /pytimesheet/download-task-excelc            
      ó  — t        j                  d«      st        t        d«      «      S t        j
                  j                  t        j                  j                  «       t        j                  j                  «       «      j                  «       } | st        t        d«      «      S | D �cg c]Z  }|j                  |j                  |j                  |j                  xs d|j                  j                  d«      |j                   dœ‘Œ\ }}t#        j$                  |«      }t'        «       }t#        j(                  |d¬«      5 }|j+                  |d	d
¬«       d d d «       |j-                  d«       t/        |ddd¬«      S c c}w # 1 sw Y   Œ.xY w)Nrš   r7   rÏ  r   rè   rê   r@  rA  FzManual TasksrD  r   TzManual_Tasks.xlsxúAapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheet©Úas_attachmentÚdownload_nameÚmimetype)r   r™   r   r   rZ   r  r  rO   r	  rF   r
  rH   r]   rM   r^   r  r_   r   r  r
   rH  rI  rJ  r	   )r  r  r  r  rK  rL  s         rX   Údownload_task_excelrÖ    sN  € ô �;‰;�vÔÜœ Ó(Ó)Ð)ä×#Ñ#×,Ñ,¬_×-FÑ-F×-JÑ-JÓ-LÌo×N`ÑN`×NdÑNdÓNfÓg×kÑkÓm€GÙÜœ 
Ó+Ó,Ð,ð ö
ð ð Ÿ™Ø—}‘}Ø—}‘}Ø ×,Ñ,Ò2°Ø—O‘O×,Ñ,¨WÓ5Ø#×4Ñ4ó	
ð
€Dð 
ô 
�‰�dÓ	€Bä‹Y€FÜ	�‰˜ zÔ	2ð D°fØ
�‰�F %°NˆÔC÷Dà
‡K�K�„NäØØØ)ØTô	ð ùò%
÷Dð Dús   Â*AE>ÅFÆFz/import-timesheetz/pytimesheet/import-timesheetc            
      óü  — t        j                  d«      st        t        d«      «      S t        j                  d«      } t        j
                  dk(  �r®t        j                  j                  d«      xs dj                  «       }t        j                  j                  d«      xs dj                  «       }t        j                  j                  d«      xs dj                  «       }t        j                  j                  d«      }|r|r|r|r|j                  dk(  rct        d	| t        t        j                  «       «      t        t        j                  «       «      t        j                   «       j"                  d
¬«      S 	 t%        |||||j                  ¬«      }t        d	| t        t        j                  «       «      t        t        j                  «       «      t        j                   «       j"                  d|› d�¬«      S t        d	| t        t        j                  «       «      t        t        j                  «       «      t        j                   «       j"                  ¬«      S # t&        $ r�}t(        j*                  j-                  d«       t        d	| t        t        j                  «       «      t        t        j                  «       «      t        j                   «       j"                  d|› �¬«      cY d }~S d }~ww xY w)Nrš   r7   r«  rH   r   rI   rJ   Ú
excel_filezimport_timesheet.htmlz0Please fill all fields and choose an Excel file.)rš   rÄ  ÚmonthsÚcurrent_yearr±  )rH   rI   rJ   r¡  z	Imported z% entries into the timesheet database.)rš   rÄ  rÙ  rÚ  rÇ  zExcel import failedzImport failed: )rš   rÄ  rÙ  rÚ  )r   r™   r   r   r   r²  r³  r“   ÚfilesrN  r   r½   r°   rÊ  rÿ   r   rË  rJ   r©  rº  rY  r»  r¼  )rš   rH   rI   rJ   r   r¦  Úexcs          rX   Úimport_timesheetrÝ  4  sB  € ô �;‰;�vÔÜœ Ó(Ó)Ð)ä�;‰;�vÓ€DÜ‡~�~˜ÓÜ—L‘L×$Ñ$ ZÓ0Ò6°B×=Ñ=Ó?ˆÜ—‘×!Ñ! 'Ó*Ò0¨b×7Ñ7Ó9ˆÜ—‘× Ñ  Ó(Ò.¨B×5Ñ5Ó7ˆÜ—}‘}×(Ñ(¨Ó6ˆá™u©D¹È×H]ÑH]ÐacÒHcÜ"Ø'ØÜœ|×0Ñ0Ó2Ó3ÜœN×/Ñ/Ó1Ó2Ü%Ÿ\™\›^×0Ñ0ØHôð ð	Ü2ØØ!ØØØ(×1Ñ1ôˆMô #Ø'ØÜœ|×0Ñ0Ó2Ó3ÜœN×/Ñ/Ó1Ó2Ü%Ÿ\™\›^×0Ñ0Ø# M ?Ð2WÐXôð ô& ØØÜ”|×(Ñ(Ó*Ó+Ü”N×'Ñ'Ó)Ó*Ü—\‘\“^×(Ñ(ôð øô ò 		Ü�J‰J× Ñ Ð!6Ô7Ü"Ø'ØÜœ|×0Ñ0Ó2Ó3ÜœN×/Ñ/Ó1Ó2Ü%Ÿ\™\›^×0Ñ0Ø'¨ uÐ-ôõ ûð		ús    Æ B I# É#	K;É,BK6Ë0K;Ë6K;c                 óÖ   — t        | «      }t        | «      }t        |«      }|t        v }t	        t
        j                  «       «      t	        t        j                  «       «      | |||dœ|¥S )N)rÄ  rÙ  rš   r›   rÅ  Úshow_manual_add)r›   r´   r«   r£   r½   r°   rÊ  rÿ   )rš   Úkwargsrt  rH   Ú
normalizedrß  s         rX   rÉ  rÉ  o  sl   € Ü�T‹N€EÜ)¨$Ó/€HÜ)¨(Ó3€JØ Ô$9Ð9€Oäœ,×+Ñ+Ó-Ó.Ü”~×*Ñ*Ó,Ó-ØØØ$Ø*ñð ðð rW   z/get-timesheetz/pytimesheet/get-timesheetc                  ó,  — t        j                  d«      st        t        d«      «      S t	        j
                  «       j                  } t        j                  d«      }t        |«      }t        |«      }|s|st        	 di t        |d| ¬«      ¤ŽS t        j                  dk(  �r	t        j                  j                  d«      }t        j                  j                  d«      }|r t        j                  j                  d«      }n|}	 |rt        |«      n| }t        |||«      }|�|j                   r#t        	 di t        |d	|› d
|› d|› d�||¬«      ¤ŽS |||dœt         d<   t        	 di t        ||j"                  j%                  «       |j&                  j%                  «       ||||¬«      ¤ŽS t        	 di t        || ¬«      ¤ŽS # t(        $ rG}	dd l}
|
j-                  «        t        	 di t        |dt/        |	«      › �| |xs |¬«      ¤ŽcY d }	~	S d }	~	ww xY w)Nrš   r7   zBYour Google account is not linked to a team member. Contact admin.)r±  rÚ  r«  rI   rJ   rH   zNo data found for z (r®   ú))r±  rÚ  rÅ  )rH   rI   rJ   Úreport_params)rÐ   Ú
table_datarÚ  rÅ  r  Úselected_yearr   zSystem Error: )rÚ  rÈ  )r   r™   r   r   r   rË  rJ   r›   r´   r   rÉ  r   r²  r³  r™  r>  r3  ró   r  rô   rº  Ú	tracebackÚ	print_excr©   )rÚ  rš   rt  Úuser_assigneer  ræ  Úselected_assigneer¤  r  rx  rç  s              rX   r®  r®    s,  € ô �;‰;�vÔÜœ Ó(Ó)Ð)ä—<‘<“>×&Ñ&€LÜ�;‰;�vÓ€DÜ�T‹N€EÜ.¨tÓ4€Má™ÜØñ
äØØZØ)ôñ
ð 	
ô ‡~�~˜ÓÜ Ÿ™×)Ñ)¨'Ó2ˆÜŸ™×(Ñ(¨Ó0ˆÙÜ '§¡× 0Ñ 0°Ó <Ñà -Ðð1	Ù-:”s˜=Ô)ÀˆHÜ-Ø! >°8óˆBð ˆz˜RŸXšXÜ&Øñä#Øà0Ð1BÐ0Cð D Ø .Ð/¨q°°
¸!ð=ð &.Ø):ôñð ð .Ø'Ø ñ(ŒG�OÑ$ô
 #ØñäØØŸJ™J×-Ñ-Ó/Ø!Ÿy™y×/Ñ/Ó1Ø!)Ø%6Ø#1Ø"*ôñð ô4 Øñä
˜¨<Ô
8ñð øô ò 	ÛØ×ÑÔ!Ü"ØñäØØ*¬3¨q«6¨(Ð3Ø!-Ø%6Ò%G¸-ô	ñõ ûð	ús&   ÄAG ÅAG Ç	HÇ<HÈHÈHz/download-timesheetz/pytimesheet/download-timesheetc                  ól  — t        j                  d«      st        t        d«      «      S t        j                  d«      } | st        t        d«      «      S t	        | d   | d   | d   «      }|�|j
                  rt        t        d«      «      S t        || d   | d   | d   «      \  }}t        |d|d	¬
«      S )Nrš   r7   rä  r®  rH   rI   rJ   TrÑ  rÒ  )r   r™   r   r   r>  r3  rO  r	   )rÎ   r  rK  rN  s       rX   Údownload_timesheetrì  Õ  s¾   € ô �;‰;�vÔÜœ Ó(Ó)Ð)ä�[‰[˜Ó)€FÙÜœ 
Ó+Ó,Ð,ä	%ØˆzÑ˜F 7™O¨V°F©^ó
€Bð 
€z�R—X’XÜœ 
Ó+Ó,Ð,ä+Ø
ˆF�:Ñ  w¡°¸±óÑ€FˆHô ØØØð#ôð rW   Ú__main__)Údebug)lÚflaskr   r   r   r   r   r   r	   Úior
   Ú!authlib.integrations.flask_clientr   Ú'authlib.integrations.base_client.errorsr   r   Údotenvr   r�   r‡  rÓ   Úpandasr   Úcalendarr   r   Úurllib.parser   Úwerkzeug.middleware.proxy_fixr   Úwerkzeug.utilsr   Úflask_sqlalchemyr   rS  rÃ   ÚdirnameÚ__file__r‘   r   r?   rY  Údb_userÚdb_passÚdb_nameÚdb_hostÚdb_portÚ	db_driverÚencoded_userÚencoded_passÚencoded_namerZ  rC   ÚModelr0   rZ   Úapp_contextÚ
create_allÚ
secret_keyÚwsgi_appÚoauthÚregisterre   rn   r°   rÿ   r¯   r—   r›   rœ   r�   r¡   r¢   Úraw_envr’   r“   ÚRAW_MANUAL_TASK_ASSIGNEESr«   r£   r´   rÅ   rØ   rà   r*  r>  rO  Úbefore_requestrW  r]  rc  rl  rq  r€  r…  rŠ  r�  r©  Úrouter7   r·  r¾  rÁ  rÏ  rÖ  rÝ  rÉ  r®  rì  Úrun)ÚsÚns   00rX   ú<module>r     sJ  ðß X× XÑ XÝ Ý 3ß UÝ Û 	Û 	Û Û Ý Ý Ý #Ý 2Ý *Ý 'ñ
 ˆB�G‰G�L‰L˜Ÿ™Ÿ™¨Ó2°FÓ;Ô <ð
 �2—9‘9Ð/°Ó@Ð ÙØØô€ð
 ˆ"�)‰)�I˜{Ó
+€Ø
ˆ"�)‰)�I˜rÓ
"€Ø
ˆ"�)‰)�I˜{Ó
+€Ø
ˆ"�)‰)�I˜{Ó
+€Ø
ˆ"�)‰)�I˜vÓ
&€ØˆB�I‰I�k 9Ó-€	á˜'Ó"€Ù˜'Ó"€Ù˜'Ó"€àˆYˆK�s˜<˜.¨¨,¨°q¸¸	ÀÀ7À)È1È\ÈNÐ[ð ‡
�
Ð$Ñ %ð 05€‡
�
Ð+Ñ ,Ø&*€‡
�
Ð"Ñ #Ø(,€‡
�
Ð$Ñ %Ø(-€‡
�
Ð$Ñ %Ø%,€‡
�
Ð!Ñ "Ø!1€‡
�
ÐÑ á�ƒ_€ôA�R—X‘Xô Aô:�b—h‘hô :ð 	‡_�_Óñ Ø‡M�M„O÷ð �—‘˜<Ó(€„ñ ˜Ÿ™¨a¸Ô:€„áˆc‹
€ð
 
�‰Ø	Øˆb�i‰iÐ*Ó+Ø�"—)‘)Ð2Ó3ØVà�ðð 
ó 
€ð �—‘Ð+Ð-DÓE€ð Ø*Ø=Ø=Ø?ØAØ=Ø>Ø?Ø>ØØñ€ð  ˜a¨!°aØ�a ¨aØ˜r¨r¸rñ€ð " <ðÐ òPò
$ð ˆb�i‰i˜Ð'GÓH€ØˆR�Y‰Y�|Ó$€
Ø�—‘˜<Ó(€ò(ð ˆ"�)‰)Ð+Ó
,€Ù
Ø4;·M±MÀ#Ó4FÖ T¨qÈ!Ï'É'Í) §¡¥Ò TÑâ HÐò+ð" *CöØ$%ÑF^Ð_`ÕFaÑ˜QÕòÐ ò
ò(#ò.%ò$ò*EYòPaYòHð ×Ññó ðòMò
Dò/ò	òò,	òòò6ðx ‡�ˆ3˜ ˜€Ó(Ø‡�ˆ> E¨6 ?€Ó3Ø‡�ˆ? U¨F O€Ó4ñ4ó 5ó 4ó )ð4ð( ‡�ˆ?ÓØ‡�Ð&Ó'ñ3ó (ó ð3ð
 ‡�ÐÓØ‡�Ð'Ó(ñó )ó ððB ‡�ˆ9ÓØ‡�Ð Ó!ñ&ó "ó ð&ð
 ‡�ˆ; ¨ €Ó0Ø‡�Ð"¨U°F¨O€Ó<ñQó =ó 1ðQðh ‡�Ð!Ó"Ø‡�Ð-Ó.ñó /ó #ððD ‡�Ð¨°¨€Ó8Ø‡�Ð*°U¸F°O€ÓDñ6ó Eó 9ð6òrð  ‡�Ð e¨V _€Ó5Ø‡�Ð'°%¸°€ÓAñQó Bó 6ðQðh ‡�Ð Ó!Ø‡�Ð,Ó-ñó .ó "ðð8 ˆzÒØ‡G�G�$€GÕð ÷Añ üò^ !Uùò*s$   È VÌ&VÌ<VÍV#Í+
V#ÖV