← back to Rentv Sheet Enrich Refine

__pycache__/live_server.cpython-314.pyc

132 lines

+
�~j�5����Rt^RIt^RIt^RIt^RIt^RIt^RIt^RIt^RI	H
t
Ht]PP^]PP]PP]444^RIt^RIt]PP]PP]44tRRutt]P,P/RR4t]P,P/RR4t]P4!4tR	t!R
R]4tR^/R
lt^RI t!Rs"]P4!4t#Rt$Rt%Rt&Rt'Rt(Rt)Rt*RRlt+Rt,!RR]
4t-^RI.tRt/]0R8Xd
]/!4R#R#)u=
live_server.py — LIVE two-way web console over the RENTV CRE contacts Google Sheet.

Reuses lib.py (OAuth token + read_tab + green-stamping batch_fill), so no new auth.
  GET  /                     -> the console UI (public_live/index.html)
  GET  /api/meta             -> [{gid,title}]  (all tabs)
  GET  /api/tab?gid=N        -> {gid,title,headers,rows}   (pull latest — Sheet->UI)
  POST /api/write            -> {gid,row0,col0,value} write one cell green (UI->Sheet)
  POST /api/enhance          -> {prompt} optional local-Ollama draft polish ($0, if up)

Two independent sync directions: writes are event-driven (on cell edit); the UI polls
/api/tab to pull external Sheet edits. Basic-auth admin/DW2024! per the viewer convention.
All contacts are Steve Bloom's (RENTV) — ADD only, never bulk-overwrite. $0 (local).
N)�BaseHTTPRequestHandler�ThreadingHTTPServer�adminzDW2024!�
OLLAMA_URLz#http://localhost:11434/api/generate�DRAFT_MODELz	qwen3:14bc��\;_uu_4\P!4uuRRR4# +'giR#;i�N)�	_tok_lock�lib�access_token���live_server.py�tokrs��	�����!�
����s	�/�A	c��]tRt^!tRtRtR#)�
QuotaErrorzCRaised when the Sheets read/write quota (429) is hit after retries.rN)�__name__�
__module__�__qualname__�__firstlineno__�__doc__�__static_attributes__rr
rrr!s��Mr
r�triesc�L�^RIp\V4F
pV!V!u#	R# \dyp\T4pRT9gRT9gRT9d3YA^,
8d&TP	RT^,,4Rp?KmRT9gRT9gRT9d\R4hhRp?ii;i)z�Call a Sheets-reading fn, retrying on a 429/RESOURCE_EXHAUSTED. lib._req raises
SystemExit (a BaseException) on any API error, so we catch BaseException, inspect the
message, back off on quota errors, and re-raise everything else.N�429�RESOURCE_EXHAUSTED�
RATE_LIMITg�?u3Sheets read quota (60/min) hit — retrying shortly)�time�range�
BaseException�str�sleepr)�fnr�a�_t�i�e�ms&$*    r�retryr($s����
�5�\��	��q�6�M����	��A��A���
�2�a�7�<�1�;L�RS�^_�V_�R_������A���'����z�1�Q�6�,�!�:K� �!V�W�W���
	�s� �B#�AB�=!B�B#c�*�\\PP\RR44;_uu_4p\
P!V4pRRR4XR,Uu/uFq"R,VbK	upVR&VsR# +'giL7;iuupi)uRLoad our OWN local copy (data/snapshot.json) into memory — no live Sheets reads.�data�
snapshot.jsonN�tabs�gid�_by_gid)�open�os�path�join�HERE�json�load�SNAP)�f�s�ts   r�	load_snapr:9sf��
�b�g�g�l�l�4���9�	:�	:�a��I�I�a�L��
;�)*�6��3��A�e�H�a�K��3�A�i�L��D�
;�	:��3s�A=�!B�=B
	c�@�\P!\44pVR,Uu/uFqR,VbK	upVR&\;_uu_4VsRRR4\
P!VP4UUu/uFwr#VR8wgKW#bK	upp\\PP\RR4R44RR	R
VR
,R\VR,4R\RVR,44/#uupi +'giL�;iuuppi)
zNRebuild the local copy from the live sheet (a few batch reads) and swap it in.r,r-r.Nr*r+�w�okT�	generated�rowsc3�F"�TFp\VR,4x�K	R#5i)r?N)�len)�.0r9s& r�	<genexpr>�refresh_snap.<locals>.<genexpr>Ks���:�	�1��A�f�I���	�s�!)�snap_mod�buildr�
_snap_lockr6r4�dump�itemsr/r0r1r2r3rA�sum)r8r9�k�vs    r�refresh_snaprMAs���	���s�u��A�)*�6��3��A�e�H�a�K��3�A�i�L�	����
��I�I����	�<�	���Q�)�^�t�q�t�	�<��2�7�7�<�<��f�o�>��D�F��$��Q�{�^�V�S��6��^��C�:��&�	�:�:�<�<��4�	���<s�D�D�>D
�D
�D	c�.�R\R,R\PR4R\PR/4R\PR.4R\R,Uu.uF)pRVR,RVR,R\VR,4/NK+	up/#uupi)r>�status_field�
status_colors�
status_valuesr,r-�titler?)r6�getrA)r9s r�metarTMs�����k�*��D�H�H�^�4��T�X�X�o�r�:��T�X�X�o�r�:��]a�bh�]i�j�]i�XY�e�Q�u�X�w��'�
�F�C��&�	�N�S�]i�j�	l�l��ks�/Bc��\R,\V4,p\P!RVR,RVR,RVR,RVR,RVR,RVP	R/4R\R,/4#)r.r-rR�headersr?�green�colorsr>)r6�int�warmth�augmentrS�r-r9s& r�tabr]Tsl���Y���C��!�A��>�>�5�!�E�(�G�Q�w�Z��A�i�L��A�f�I�w��'�
�H�a�e�e�H�b�>Q���k�*�,�-�-r
c�d�\R,\V4,pRVR,RVR,/#)uGEnriched (green) cells for a tab — precomputed in the local snapshot.r.r-rW)r6rYr\s& r�	green_mapr_Zs+���Y���C��!�A��1�U�8�W�a��j�1�1r
c�T�VUu.uF=p\V4\R,9gK \R,\V4,NK?	pp.p\4pVFGpVR,F7pV'gK
Wd9gKVPV4VP	V4K9	KI	RV9d$VPR4VP
^R4\V4UUu/uFwrvWgbK		ppp.p	.p
/pVEFgpVR,Uu.uFqhPV4NK	pp\VPR.44p
VPR/4p\V	4p\VR,4F�wppR.\V4,p\V4F,wppV\V48d
VV,MRpVfK'VVV&K.	V	P	V4\\VR,44FkpVV,pVfKVR	V2V
9dV
P	VV,R	V24VPVR	V24pV'gK[VW�V,R	V2&Km	K�	EKj	\P!R
RR\V4R
2RVRV	RV
RVR\R,/4#uupiuuppiuupi)z�Merge several tabs into ONE view: columns = union of their headers (by name),
rows concatenated, each already carrying its Sheet Name. Green coords remapped.r.rV�
Sheet NamerWrXr?�N�,r-�combinedrRz sheets combinedr>)
rYr6�set�add�append�remove�insert�	enumeraterSrArrZr[)�gids�gr,�order�seenr9�hr%�colidxr?rWrX�hmap�gset�cmap�base�ri�r�newrow�ci�val�ui�hxs&                      rrdrd_sm��.2�O�T��S��V�t�I��5N�#�D��O�C��F�#�#�T�D�O��E�s�u��
���9���A��q�Q�]������U�\�\�!�_����u��
���\�"�E�L�L��L�$A�(��/�
0�/�t�q�a�d�/�F�
0�
�D�r�u�B�6�
��'(��|�4�|�!�
�
�1�
�|��4��1�5�5��"�%�&���u�u�X�r�"���4�y���q��y�)�E�B���T�C��J�&�F�$�Q�<���C�!#�c�$�i��T�"�X�T���>�!$�F�2�J�(�
�K�K����C��)��-�.���"�X���:���T��2�$�<�4�'��L�L�D��G�9�A�b�T�!2�3��X�X���A�b�T�l�+���2�02�F�2�g�Y�a��t�,�-�/�*��*�>�>�5�*�g�#�d�)��DT�7U��u�f�d�G�U�H�f���k�*�,�-�-��?P��1��5s�J�!J�
J�J%c�$�VUu.uF^p\V4P4'gK$\V4\R,9gKA\R,\V4,NK`	pp.p\	4pVFGpVR,F7pV'gK
W�9gKVPV4VP
V4K9	KI	RV9d$VPR4VP^R4^Tu;8:d\V48dMMWR,MRp	^p
VF]p\VR,4pWV,8d4V	eVR,PV	4MRpVR,W,
V3u#W�,
p
K_	R#uupi \dRpL6i;i)aGReverse-map a combined-view (row, union-col) back to the SOURCE (gid, tab_row0, tab_col0).
Mirrors combined()'s row/col construction EXACTLY so a write lands on the right sheet cell.
Returns (gid, tab_row0, tab_col0); tab_col0 == -1 means that union column doesn't exist on
the row's source tab (not editable in combined view).r.rVraNr?r-�����)r �striprYr6rerfrgrhrirA�index�
ValueError)
rk�crow�ucolrlr,rmrnr9ro�headerrt�n�tcols
&&&          r�resolve_combinedr��sM��
.2�b�T��S��V�\�\�^�#��A��RV�W`�Ra�Ha�#�D��O�C��F�#�#�T�D�b��E�s�u��
���9���A��q�Q�]������U�\�\�!�_����u��
���\�"�E�L�L��L�$A���2��E�
�2�U�[��F��D�
����&�	�N����(�?�
�5;�5G�q��|�)�)�&�1�R���e�H�d�k�4�0�0��	�����'c���
���
�s"�!E:�E:�!E:�:E?�?
F�Fc�aa	�\R,P\S44pV'd'\V4\VR,48�dRRRR/#V'dVPR^4M^pR\V4V,^,R\V4R	V/o	V'dR
S	R&\	V	V3Rl4V'd�\V4\V4r�\VR
,4V8:dVR
,P.4K1\VR
,V,4V8:d"VR
,V,PR4K?W5R
,V,V&VRV2VR,9dVR,PVRV24RR
/#)r.rVr=F�erroru)derived column (🔥 Warmth) is read-only�hr�row0�col0�valueT�formulac�X<�\P!\4\S4S.4#r)r
�
batch_fillrrY)�cellr-s��r�<lambda>�write_cell.<locals>.<lambda>�s���#�.�.����C��4�&�9r
r?rbrcrW)r6rSrYrAr(rg)
r-r�r�r�r�r9r�rv�cr�s
f&&&&    @r�
write_cellr��s;���	
�Y����C��H�%�A�	�S��Y�#�a�	�l�+�
+��e�W�&Q�R�R�����t�Q��!�B��C��I��N�Q�&���D�	�7�E�J�D����Y��	�
9�:���4�y�#�d�)�1��!�F�)�n��!�
�f�I���R� ��!�F�)�A�,��1�$�
�f�I�a�L����#��&�	�!��Q���S��!��:�Q�w�Z�'�
�g�J�����1�Q�C�j�)��$�<�r
c�
�\P!R\RVRRRRR//4P4p\P
P
\P
P\VRR/R	7^<R
7p\P!V4PRR4P4pR
V9d(VPR
^4^,P4pRRRV/# \dpRRRRTR2/uRp?#Rp?ii;i)�model�prompt�streamF�options�temperatureg�?�Content-Type�application/json)r*rV)�timeout�responserbz</think>r=T�textr�zlocal model unavailable (�)N)r4�dumps�OLLAMA_MODEL�encode�urllib�request�urlopen�Request�OLLAMAr5rSr~�split�	Exception)r��bodyrv�outr&s&    r�enhancer��s���H��z�z�7�L�(�F�H�e�$�}�c�&:�<�=�=C�V�X�	
��N�N�"�"�6�>�>�#9�#9����8J�'K�$:�$M�VX�
#�
Z���i�i��l���z�2�.�4�4�6������)�)�J��*�1�-�3�3�5�C��d�F�C�(�(���H��e�W�(A�!��A�&F�G�G��H�s�C C#�#D�.	C=�7D�=Dc�Ha�]tRt^�toRtRtR	RltRtRtRt	Rt
VtR#)
�Hc��VPPRR4pVPR4'dW\P!VR,4P4P
R^4wr#V\8XdV\8XdR#VPR4VPRR4VP4R	# \dLBi;i)
�
AuthorizationrbzBasic :�NN�:Ti�zWWW-Authenticatez Basic realm="RENTV Live Console"F)
rVrS�
startswith�base64�	b64decode�decoder��USER�PWr��
send_response�send_header�end_headers)�selfro�u�ps&   r�_auth�H._auth�s����L�L���_�b�1���<�<��!�!�
��'�'��"��.�5�5�7�=�=�c�1�E�����9��b���	
���3�����+�-O�P��������
��
�s�AB?�?C
�C
c��\V\4'dVP4pVPV4VP	RV4VP	R\\V444VP	RR4VP	RR4VP	RR4VP
4VPPV4R#)	r��Content-Lengthz
Cache-Controlz.no-store, no-cache, must-revalidate, max-age=0�Pragmazno-cache�Expires�0N)	�
isinstancer r�r�r�rAr��wfile�write)r��code�ctyper*s&&&&r�_send�H._send�s����d�C� � ��;�;�=�D����4� ������/����)�3�s�4�y�>�:�����*Z�[�����:�.�����C�(������
�
����r
c�T�VPVR\P!V44R#)r�N)r�r4r�)r��objr�s&&&r�_json�H._json�s���
�
�4�+�T�Z�Z��_�=r
c��R#rr)r�r#s&*r�log_message�
H.log_message�s��r
c	��VP4'gR#VPPR^4^,p/pRVP9dxVPPR^4^,PR4FApRV9gKVPR^4wrE\PPV4W$&KC	VR8XgVR8Xdd\
\PP\RR4R4;_uu_4pVP^�R	VP44RRR4R#VR
8XdVP\44R#VR8Xd-VP\VPRR
444R#VR8Xd-VP\!VPRR
444R#VR8XdcTP\#VPRR4PR4Uu.uFqwP%4'gKVNK	up44R#RV9EdVP'R4'gVP)R 4'd�\PP\RVP+R44p\PP-V4'dcVP)R4'dRMRp	\
VR4;_uu_4pVP^�V	R,VP44RRR4R#VPRR/R4R#VPRR/R4R# +'giR#;iuupi +'giR#;i \.d+p
TPR\1T
4RR/R4Rp
?
R#Rp
?
i\2d)p
TPR\1T
4/R4Rp
?
R#Rp
?
ii;i)!N�?�&�=�/z/index.html�public_livez
index.html�rbztext/html; charset=utf-8z	/api/metaz/api/tabr-r�z/api/formatz
/api/combinedrkrbrcz/../z/nav-agent/�.cssztext/csszapplication/javascriptz; charset=utf-8r��	not found�r(T����)r�z.js)r�r1r�r��parse�unquoter/r0r2r3r��readr�rTr]rSr_rdr~r��endswith�lstrip�isfilerr r)r�r1�q�kvrKrLr7rl�fp�ctr&s&          r�do_GET�H.do_GET�s����z�z�|�|���y�y���s�A�&�q�)�����$�)�)���i�i�o�o�c�1�-�a�0�6�6�s�;���"�9��8�8�C��+�D�A�!�<�<�/�/��2�A�D�<�	/��s�{�d�m�3��"�'�'�,�,�t�]�L�I�4�P�P�TU��J�J�s�$>�����I�Q�P���$��
�
�4�6�"���#��
�
�3�q�u�u�U�C�0�1�2���&��
�
�9�Q�U�U�5�#�%6�7�8���(��
�
�8����f�b�0A�0G�0G��0L�$Z�0L�1�PW�PW�PY�Q�Q�0L�$Z�[�\��t�#�����)G�)G�4�=�=�Yh�Ki�Ki��W�W�\�\�$�
�t�{�{�3�7G�H���7�7�>�>�"�%�%�')�{�{�6�':�':��@X�B��b�$���1��
�
�3��->�(>�����I�(���J�J���5�s�;��
�
�G�[�1�3�7�'Q�P�P��%[�
(�����	>��J�J���Q���$�7��=�=���	/��J�J���Q��(�#�.�.��	/�s��AM3�"M�.M3�8 M3�1M3�
1M3�:M3�:M�M�M3�)M3�A/M3�8M3�M3�')M�M3�M3�0M3�M	�M3�M3�M0	�*M3�0M3�3O�>N#�#O�0O�1O�Oc�d�VP4'gR#\VPPR^44p\P
!VPPV4;'gR4pVPR8Xd�VR,VR,VR,rTpVR8Xdb\VPR.4\V4\V44pV'dV^,^8dVPR	R
RR/4R#Vwr4pVP\W4VVPR
R4VPRR
444R#VPR8Xd-VP\VPRR444R#VPR8XdVP\44R#VPRR/R4R# \d+pTPR\T4RR/R4Rp?R#Rp?i\ d)pTPR\T4/R4Rp?R#Rp?ii;i)Nr�s{}z
/api/writer-r�r�rdrkr=Fr�ugThat column isn't editable in the combined view for this row's sheet — open the single sheet to edit.r�rbr�z/api/enhancer�z/api/refreshr�r�r(Tr�r�)r�rYrVrSr4�loads�rfiler�r1r�r�r�r�rMrr r)r�r�r�r-r�r��resr&s&       r�do_POST�	H.do_POST
s����z�z�|�|��	/��D�L�L�$�$�%5�q�9�:�A��:�:�d�j�j�o�o�a�0�9�9�E�:�D��y�y�L�(�"&�u�+�t�F�|�T�&�\�4���*�$�*�4�8�8�F�B�+?��T��C�PT�I�V�C��#�a�&�1�*��
�
�D�%��;d�$e�f��&)�O�C�t��
�
�:�c��&*�h�h�w��&;�T�X�X�i�QV�=W�Y�Z����n�,��
�
�7�4�8�8�H�b�#9�:�;����n�,��
�
�<�>�*��
�
�G�[�1�3�7���	>��J�J���Q���$�7��=�=���	/��J�J���Q��(�#�.�.��	/�sJ�AG	�1BG	�AG	�
;G	�*G	�3G	�	H/�G9�9H/�H/�H*�*H/rN)��)rrrrr�r�r�r�r�r�r�__classdictcell__)�
__classdict__s@rr�r��s)������>�
�#/�J/�/r
r�c��\4\\P4^8�d!\	\P^,4M^p\RV3\4pVP^,p\\PP\R4R4P\V44\RVR2RR7VP!4R#)	�z	127.0.0.1z.liveviewer.portr<z)RENTV Live Console  ->  http://127.0.0.1:z   (admin / DW2024!)   $0 localT)�flushN)r:rA�sys�argvrYrr��server_addressr/r0r1r2r3r�r �print�
serve_forever)�port�srv�reals   r�mainr*s���
�K�"�3�8�8�}�q�0�3�s�x�x��{��a�D�
�{�D�1�1�
5�C����a� �D�������d�.�	/��5�;�;�C��I�F�	�5�d�V�;Z�
[�cg�h����r
�__main__)F)1rr�r4r0�socketr��	threading�urllib.requestr��http.serverrrr1ri�dirname�abspath�__file__r
rZr3r�r��environrSr�r��Lockr	rr�rr(�snapshotrEr6rGr:rMrTr]r_rdr�r�r�r��urllib.parserrrr
r�<module>rsB��
�@�?�?�?�C�������2�7�7�?�?�2�7�7�?�?�8�#<�=�>�
�
�	�w�w���r�w�w���x�0�1���I���b�	������&K�	L���z�z�~�~�m�[�9��
�N�N��	�"�N��N���� ���
�^�^�
�
�
�
<�l�-�2�
$-�L�4�2H�`/��`/�D���z���F�r