~Zj6dZddlZddlZddlmZmZddlmZddlm Z ddl Z ddl m Z ee jjZejjdz Zedz Zed z Zd Zhd Zhd Zd efdZdeded e fdZd efdZdS)u6 Frank-relay: read-only file relay for Nave ↔ Ufficio cross-machine requests. Nave scrive richieste in tasks/to-frank/richiesta-.json via Dropbox. Frank le legge, esegue azioni allowlisted (sola lettura), scrive la risposta in tasks/from-frank/risposta-.json. Dropbox sincronizza automaticamente. Allowlist azioni (sola lettura, nessuna scrittura): list_dir — elenca directory read_file — legge file testo (max 200KB) glob — ricerca pattern ricorsiva duckdb_query — esegue SQL read-only via DuckDB (solo SELECT/WITH, blocca keyword di scrittura/comando, nessuna query multipla); params: sql, params (lista opzionale di bind), limit (default 1000 righe) Nessuna restrizione sui path — tutto ciò che è visibile dal PC ufficio è accessibile. N)datetimetimezone)Path)Any)loggertaskszto-frankz from-franki >globlist_dir read_file duckdb_query>CALLCOPYDROPALTERMERGEATTACHCREATEDELETEDETACHEXPORTINSERTPRAGMAUPDATEREPLACETRUNCATEreturnctjtjS)N)rnowrutc astimezone isoformatLC:\Users\Mauro Gagliardi\Dropbox\adrian\PYTHON\Frank\daemon\relay_handler.py_now_isor%-s, < % % 0 0 2 2 < < > >>r#actionparamsc |dkrt|d}g}t|D]}|}||j||s|jndtj |j  d|S|dkrt|d}|j}|tkr#td|jd|dtd|d d }||d S|d kr{|d}|d} | r9dtt| |DStt#j|dS|dkr|d} t)|dd} |dg} | r,| dnd} | dvrtd| d| d}d|vrtdddl}|}t2D]1}|d|zdz|rtd |d!2t7j|| }d"|jD}|| }|d#|Dt?|| kd$Std%|)&Nr path)nameis_dirsizemtimer zFile : z bytes > limite z bytesencodingutf-8replace)r/errorsr patternbasec,g|]}t|Sr")str).0ps r$ z_execute..KsFFFqCFFFFFr#T) recursiver sqllimitir'r)SELECTWITHz6Solo SELECT/WITH ammessi come inizio query (trovato: 'z');z7Query multiple non ammesse (';' interno non consentito)z\bzKeyword non ammessa: ''cg|] }|d S)rr")r7ds r$r9z_execute..es...!...r#c,g|]}t|Sr")list)r7rs r$r9z_execute..is+++T!WW+++r#)columnsrows truncatedzAzione non riconosciuta: ) rsortediterdirstatappendr*r+st_sizer fromtimestampst_mtimer!READ_FILE_MAX_BYTES ValueErrorget read_textrglob _glob_moduler stripintuppersplitrstripre_DUCKDB_WRITE_KEYWORDSsearchduckdbexecute description fetchmanylen)r&r'r)entriesentryrLr,r/r3r4r;r< query_params first_word sql_stripped_re sql_upperkwrelcolsrHs r$_executern1s F6N##DLLNN++  E::<>HHJJ       F6N##yy{{" % % %cTYcc$ccH[cccdd d::j'22~~x ~BBB #zz&!!  GFFF4::+;+;G+D+D$E$EFFF Fl'4@@@AAA Um!!##FJJw--..zz(B// 03:SYY[[&&((++ / / /dV`dddee ezz||**3// ,  VWW W  &&(( ( A ABzz%"*u,i88 A !?"!?!?!?@@@ An\<88..co...}}U##++d+++Te+   999 : ::r#c tsdStddd}t tdD]}|jd}td|dz }|r@ tj | d }n6#t$r)}tj d |jd |Yd }~d }~wwxYw|d d}|di}|d|}|t vrG|t#dd|dt t d} tjd|d|dn t'||} |t#d| d} tjd|d|dnT#t$rG}|t#dt+|d} tjd|d|d|Yd }~nd }~wwxYw|tj| dd !d |d"z }|S)#z Processa tutte le richieste pendenti in to-frank/ senza risposta in from-frank/. Ritorna il numero di richieste processate in questo ciclo. rT)parentsexist_okzrichiesta-*.jsonz richiesta-z risposta-z.jsonr0)r/z!Frank-relay: impossibile leggere r.Nr&r=r'iddeniedzAzione 'z' non in allowlist )rr timestampstatuserrorzFrank-relay: azione negata 'z' (id=)ok)rrrtruresultzFrank-relay: OK z (id=rvzFrank-relay: errore z): F) ensure_asciiindent) _TO_FRANKexists _FROM_FRANKmkdirrJr stem removeprefixjsonloadsrT Exceptionrrvr*rSALLOWED_ACTIONSr%warningrninfor6 write_textdumps) processedreq_filereq_id resp_filereqer&r' req_id_bodyresprys r$process_pending_requestsrps     qdT222I9>>*<==>>--++L99";f";";";;        *X///AABBCC    LQX]QQaQQ R R R HHHH 2&&2&&ggdF++  ( (!%ZZ"XFXXvo?V?VXX D NV&VV VVV W W W W X!&&11%!)"$   JvJJKJJJKKKK X X X%!)% VV  VfVV;VVSTVVWWWWWWWW X TZ5KKKV]^^^Q s0"(C  C>C99C>>G H$=HH$)__doc__rr rVrrpathlibrtypingrr_logurur__file__parent _FRANK_ROOT _TASKS_ROOTr~rrQrr]r6r%dictrnrXrr"r#r$rsC$ '''''''' d8nn#*  ''1 * $ L(  CCC ?#????<;S<;$<;3<;<;<;<;~:#::::::r#