
    /j>                    @   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	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 ed      Zedz  Z ed	      Zd
ZdZdZdddddddZd Zd Zd Zd Z d Z!d Z"d Z#d Z$d Z%d Z&d#dZ'd Z(d  Z)d! Z*d" Z+y)$zControlled manual-ingest adapter for the existing knowledge pipeline.
The adapter stores immutable originals, reuses the canonical registry/version/KU
and Graphiti queue tables, and exposes only a loopback endpoint in the aggregator.
    )annotationsN)datetimetimezone)Pathz+/opt/struktur/youtube-research/knowledge.dbz/opt/struktur/manual-ingestrawz!/opt/obsidian-vault/Manual-Ingesti@ i  P i   zapplication/pdfzGapplication/vnd.openxmlformats-officedocument.wordprocessingml.document
text/plainztext/markdownzAapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheetztext/csv).pdf.docx.txt.mdz.xlsx.csvc                 d    t        j                  t        j                        j	                         S N)r   nowr   utc	isoformat     /home/hermes/manual_ingest.pyr   r      s    (,,x||,6688r   c                H    t        j                  |       j                         S r   )hashlibsha256	hexdigest)bs    r   shar      s    7>>!$..00r   c                 8    t        j                  t        d      S )N   timeout)sqlite3connectDBr   r   r   dbr#      s    B/
/r   c                 `    t         j                  dd       t        j                  dd       y )NT)parentsexist_ok)RAWmkdirDERIVEDr   r   r   	init_dirsr*      s!    46d\`8ar   c                   t         j                  j                  |       }|j                  dvs$|j                  r|j
                  s|j                  rt        d      |j                  j                  d      j                         }|dv s|j                  d      rt        d      |j                  xs |j                  dk(  rdnd	}|d
vrt        d      t        j                  ||t        j                        }|D ]{  }t!        j"                  |d   d         }|j$                  sH|j&                  s<|j(                  s0|j*                  s$|j,                  s|t!        j.                  d      v srt        d       ||j                  rdt1        |      z   ndz   }t         j                  j3                  |j                  ||j4                  xs d|j6                  |j8                  df      S # t        $ r}t        d      |d }~ww xY w)N)httphttpsu@   Nur öffentliche http/https-URLs ohne Zugangsdaten sind erlaubt..)	localhostzmetadata.google.internalz
.localhostz*Interne/Metadata-Ziele sind nicht erlaubt.r-     P   )r1   r0   u:   Nur öffentliche HTTP/HTTPS-Ports 80 und 443 sind erlaubt.)typeu"   URL-DNS-Auflösung fehlgeschlagen.   r   z169.254.0.0/16zBURL zeigt auf ein nicht erlaubtes internes oder reserviertes Netz.: /)urllibparseurlparseschemehostnameusernamepassword
ValueErrorrstripcasefoldendswithportsocketgetaddrinfoSOCK_STREAMOSError	ipaddress
ip_address
is_privateis_loopbackis_link_localis_reservedis_multicast
ip_networkstr
urlunparsepathparamsquery)	urlphostrB   infoseitemipnetlocs	            r   valid_public_urlr\      s   llC Axx''qzzQZZ1::]g  ik  ^l  Xl	
		3		(	(	*D774==;V^h  jV  _W  YW	
	5188W,C"D8:.j#kk!!$t1C1CD nQ
+MMR^^r/?/?2>>UWUdUdhjnw  oC  oC  DT  oU  iU  ^h  im  ^n  Xnn affCD	M"5F<<""AHHVAFFMc!((177SU#VWW Vz*NOUVVVs   &G, ,	H5HHc                  	 t        |       }t        j                  j                  t        j                  j	                               }t        d      D ]   }t        j                  j                  |dddd      }|j                  |d      5 }t        |j                               }|j                  j                  d	      xs d
j                         	t        |j                  j                  d      xs d      }|t        kD  rt        d      |j                  t        dz         }t!        |      t        kD  rt        d      t#        	fddD              st        d      ||	fcd d d        c S  t        d      # 1 sw Y   9xY w)N   z!Wissenspipeline-Manual-Ingest/1.0z;text/html,text/plain,application/xhtml+xml,application/json)z
User-AgentAcceptGET)headersmethod   r   Content-Typer5   zContent-Lengthr   u6   URL-Inhalt überschreitet das Downloadlimit von 5 MiB.   c              3  &   K   | ]  }|v  
 y wr   r   ).0xctypes     r   	<genexpr>zfetch_url.<locals>.<genexpr>*   s     `aqEz`s   )ztext/zapplication/xhtml+xmlzapplication/jsonu&   Nicht unterstützter URL-Content-Type.zZu viele Redirects.)r\   r7   requestbuild_openerHTTPRedirectHandlerrangeRequestopengeturlra   getlowerintMAX_URLr>   readlenany)
rT   currentopener_reqrfinallengthdatari   s
            @r   	fetch_urlr       s   S!G>>&&v~~'I'I'KLF1X $NN""7Ad  ol  4m  uz"  {[[R[( 	$A"188:.Eqyy}}^7T7ZXZ6a6a6clopqpypyp}p}  O  qP  qU  TU  mVekg~Z0h%ii	"D4y 
3k(l"l`+_``hr  t\  i]  c]e#	$ 	$$ *
++	$ 	$s   CFF	c                  	
 t        |       j                  j                         }|t        vrt	        d      t        |      t        kD  rt	        d      |dv r|j                  dd      S |dk(  rdd l}dd l	m
c m	 |j                  t        j                  |            5 
	j                  
j!                  d            }d d d        d	j#                  d
 j%                  d      D              S |dk(  rt'        j(                  d      5 }|j+                  |       |j-                          t/        j0                  d|j2                  dgddd      }d d d        j4                  dk7  rt	        d      |j6                  S dd l}dd l	m
c m	 |j                  t        j                  |            5 

j9                         D cg c](  }|j;                  d      s|j=                  d      s'|* }}d	j#                  	
fd|D              cd d d        S # 1 sw Y   YxY w# 1 sw Y   xY wc c}w # 1 sw Y   y xY w)NuH   Nicht unterstütztes Dateiformat (PDF, DOCX, TXT, MD; XLSX/CSV erlaubt).u0   Datei überschreitet das Uploadlimit von 10 MiB.)r   r   r   utf8replacer
   r   zword/document.xml
c              3  j   K   | ]+  }d j                  d |j                  d      D               - yw)r5   c              3  <   K   | ]  }|j                   xs d   ywr5   Ntext)rg   ts     r   rj   z)extract_file.<locals>.<genexpr>.<genexpr>5   s        !B!2  !B   z?{http://schemas.openxmlformats.org/wordprocessingml/2006/main}tN)joiniter)rg   rU   s     r   rj   zextract_file.<locals>.<genexpr>5   s@       Y  GH  !Bqvv>  8A  !B  B  Ys   13z?{http://schemas.openxmlformats.org/wordprocessingml/2006/main}pr	   )suffix	pdftotext-Tr   )capture_outputr   r   z(PDF-Text konnte nicht extrahiert werden.zxl/worksheets/z.xmlc           	   3     K   | ]H  }d j                  d j                  j                  |            j                         D               J yw) c              3  <   K   | ]  }|j                   xs d   ywr   r   )rg   rh   s     r   rj   z)extract_file.<locals>.<genexpr>.<genexpr>>   s     !X1!&&,B,!Xr   N)r   
fromstringrv   r   )rg   nETzs     r   rj   zextract_file.<locals>.<genexpr>>   s;     h]^!XaffQi8P8U8U8W!XXhs   AA)r   r   r@   ALLOWED_FILEr>   rw   MAX_FILEdecodezipfilexml.etree.ElementTreeetreeElementTreeZipFileioBytesIOr   rv   r   r   tempfileNamedTemporaryFilewriteflush
subprocessrunname
returncodestdoutnamelist
startswithrA   )r   r   extr   rootfrU   r   namesr   r   s            @@r   extract_filer   -   s   T
""$C
,j1{&| |
4y,^!__
##DKKy,I%I
G|22__RZZ-.d!"--ObHc:dTdyy  Y  LP  LU  LU  VW  LX  Y  Y  	Y
F{((7 	z1GGDM1779
AFF37O_cimvx(ya	z<<?*-W"XXxx..	D)	* ia**,`Q!,,7G*HQZZX^M_q``yyhbghhi i 	ed	z 	z ai isC   "!HAH'4H8H3H30H34H8H$'H03H88Ic                ~   d| j                  dd      t        t        |            d}t        j                  t        j                  |      |d      }|j                  xs g D ci c]L  }|j                  |j                  r'|j                  j                         |j                  dn|j                  N c}S c c}w )NPOSTrd   r5   )REQUEST_METHODCONTENT_TYPECONTENT_LENGTHT)fpenvironkeep_blank_values)r   filename)rr   rO   rw   cgiFieldStorager   r   listr   r   filerv   value)ra   bodyenvfsr   s        r   form_fieldsr   ?   s     N20N`cdghldm`noC
2::d+C$OBgigngngtrtvabAFFAJJAFFKKMQZZ@TUT[T[[vvvs   &AB:c                &    | j                  d       y )Na  CREATE TABLE IF NOT EXISTS manual_ingest_submissions (submission_id TEXT PRIMARY KEY, source_identity TEXT UNIQUE NOT NULL, source_type TEXT NOT NULL, original_title TEXT, original_url TEXT, original_filename TEXT, submitted_at TEXT NOT NULL, submitted_by TEXT NOT NULL, source_hash TEXT NOT NULL, content_hash TEXT NOT NULL, topic TEXT, project TEXT, company TEXT, relevance_note TEXT, processing_mode TEXT NOT NULL, provenance_state TEXT NOT NULL, duplicate_class TEXT NOT NULL, status TEXT NOT NULL, status_detail TEXT, raw_path TEXT, derived_path TEXT, source_version_id INTEGER, ku_count INTEGER DEFAULT 0, graphiti_queue_id INTEGER, index_updated INTEGER DEFAULT 0))execute)cs    r   init_schemar   C   s    II  t
  u
r   c                b    | j                  d|f      j                         }|rt        |      S d S )Nz=select * from manual_ingest_submissions where submission_id=?)r   fetchonedict)r   sidr}   s      r   get_submissionr   E   sA    iiOQTPVW``bAvwkopqkr  eB  ~B  eBr   c                   t               }t        j                  |_        t	        |       |j                  d| f      j                         D cg c]  }t        |       c}|j                          S c c}w # |j                          w xY w)NzJselect * from manual_ingest_submissions order by submitted_at desc limit ?)	r#   r    Rowrow_factoryr   r   fetchallr   close)limitr   r}   s      r   historyr   G   s{    dA'++AM	Q!))  =I  KP  JR  3S  3\  3\  3^  !_Qa  !_WWY !_WWYs   .A8 A3 A8 3A8 8B
c                h   t                t               }t        j                  |_        	 t        |       dt        j                         j                  z   }t               }t        |j                  d      xs d      j                         dv rdnd}t        |j                  d      xs d      j                         }t        |j                  d      xs d      j                         }t        |j                  d	      xs d      j                         }t        |j                  d
      xs d      j                         }	t        |j                  d      xs d      j                         }
d}d}d}| dk(  rt        t        |j                  d      xs d      j                               }t        |      \  }}}t!        t"        j$                  j'                  |      j(                        j*                  xs d}|j-                  dd      }n| dk(  r1t        |j                  d      xs d      }|j/                         }d}nP| dk(  r@t        |j                  d      xs d      }|j                  d      xs d}t1        ||      }nt3        d      |j                         st3        d      | dk(  rt5        |      t6        kD  rt3        d      t9        |j/                               }t9        |      }|xs d}|j;                  d||df      j=                         }|r
|d   |k(  rdn|rdnd}|rt9        |j/                               n|}d| z   dz   |d d  z   }|j;                  d!|f      j=                         r|d"|j?                  dd#      d#   d d$ z   z  }t        t@        |d%z   tC        jD                  d&d'|      d d( z   z        }t!        |      jG                  |       |j;                  d)||d*d+d,d-|    |xs ||||d.|||||	|
|d/|d0d |d d d d1d1f       |dk(  rG|j;                  d2dd3|d4   z   |f       |jI                          tK        ||      |jM                          S |j;                  d5|f      j=                         }|r|d1   nd }|C|j;                  d6d.||||d7||d8d9d:|||d/f       |j;                  d;      j=                         d1   }|j;                  d<|f      j=                         }|r|d=   d#z   nd#}|j;                  d>||||d?z   t        |      z   ||r|d@   nd |d7dAdA||dBf       |j;                  d;      j=                         d1   }|j;                  dC|dD||f       |j;                  dE|dDd/|f       |dk(  rL|j;                  dFdG|f       t        tN        |dHz   t        |      z   dIz   z        }djQ                  g dJd*d+d,d-|     dK| dL| dM| dN| dO| dP| dQ| dR|	 dS| dT| dU|
 dV|xs | dW|d t6          dX|xs | dY| dZ| d[| d\      }t!        |      jS                  |d]       |j;                  d^d_dG||f       |r|d`z   nd|d t6         z   }|d?z   t        |      z   daz   } |j;                  db| |tU        jV                  |||	dcdddef      dg|||tU        jV                  ||||dhdef      di|djdkdldmdnf       |j;                  d;      j=                         d1   }!|j;                  do|!|t        |      djdp|f       |j;                  dq|||dr||d t6         f       |j;                  dsdtdt|f       |j;                  dud.|||d8||||| dvd7dBtU        jV                  | g      f       |j;                  d;      j=                         d1   }"|j;                  dw|"dxdy|f       |jI                          tK        ||      |jM                          S # t        jX                  $ r Y w xY w# |jM                          w xY w)zNmanual:processing_modearchive)fullu   vollständigvollstaendigr   titler5   topicprojectcompanyrelevance_noter   rT   z
index.htmlr   r   r   zmanual-text.txtr   r   
upload.binr   zUnbekannter Eingangstyp.z"Kein verwertbarer Inhalt gefunden.u)   Text überschreitet das Limit von 200 kB.zselect * from manual_ingest_submissions where content_hash=? or (original_url=? and original_url<>?) order by submitted_at desc limit 1content_hash	DUPLICATENEW_VERSION
NEW_SOURCEr4       z?select 1 from manual_ingest_submissions where source_identity=?z:duplicate:re      r   z[^A-Za-z0-9._-]r{   d   z`INSERT INTO manual_ingest_submissions VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
MANUAL_URLMANUAL_TEXTMANUAL_FILE)rT   r   r   manualORIGINAL_GESICHERTEINGEGANGENr   zSupdate manual_ingest_submissions set status=?,status_detail=? where submission_id=?z,Identischer Content Hash bereits vorhanden: source_identityzAselect id from source_processing_registry where source_identity=?a  INSERT INTO source_processing_registry(source_system,source_id,source_external_id,source_title,source_hash,artifact_status,artifact_path,artifact_hash,quality_status,graphiti_status,notes,updated_at,source_identity,canonical_url,current_state) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)createdreview_required
not_queuedz9manual ingest; USER_SUPPLIED_METADATA; original immutablezselect last_insert_rowid()zVselect * from source_versions where registry_id=? order by version_number desc limit 1version_numbera  INSERT INTO source_versions(registry_id,content_hash,content_version_hash,import_identity,version_number,supersedes_version_id,artifact_path,artifact_state,reconciliation_state,graphiti_state,original_import_path,created_at,promotion_policy) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)z:v
version_idpendingREVIEW_REQUIREDzjupdate source_processing_registry set latest_observed_version_id=?,current_state=?,updated_at=? where id=?SOURCE_REGISTEREDzjupdate manual_ingest_submissions set source_version_id=?,provenance_state=?,status=? where submission_id=?zCupdate manual_ingest_submissions set status=? where submission_id=?
EXTRAHIERTz-vr   z---
type: DERIVED
source_type: z
source_identity: z
source_version: z
source_hash: z
content_hash: z
original_url: z
original_filename: z

project: z

company: z
topic: z5
metadata_class: USER_SUPPLIED_METADATA
ingest_date: z
relevance_note: z
---

# u   

## Zusammenfassung
Manuell eingebrachte Quelle. Diese Datei ist eine DERIVED-Projektion; das Original liegt unverändert im Manual-Ingest-Archiv.

## Kernaussagen / extrahierter Inhalt

z 

## Provenienz
Originalquelle: z
Source Identity: z
Source Version: z
Hash: r   )encodingzeupdate manual_ingest_submissions set status=?,provenance_state=?,derived_path=? where submission_id=?
ANALYSIERTz: z:ku1a2  INSERT INTO knowledge_units(knowledge_unit_identity,statement,entities,relations,source_identity,source_version_id,content_version_hash,provenance,promotion_reason,created_at,source_locator,evidence_class,confidence_reason,review_state,gold_state,legacy_placeholder) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,0)USER_SUPPLIED_METADATA)r   r   r   metadata_classF)ensure_asciiz[])r   source_version_idoriginal_pathsource_hashzmanual source pending reviewzmanual:contentUNSICHERzmanual source requires reviewPENDINGNONEzinsert into knowledge_unit_provenance(knowledge_unit_id,source_identity,source_version,source_locator,representation_type,created_at) values(?,?,?,?,?,?)MANUAL_SOURCE_DERIVEDzminsert into kdata_fts(doc_id,source_identity,project,document_type,original_path,content) values(?,?,?,?,?,?)MANUAL_SOURCEzqupdate manual_ingest_submissions set ku_count=1,status=?,provenance_state=?,index_updated=1 where submission_id=?	INDEXIERTa  INSERT INTO graphiti_import_queue(source_type,obsidian_path,content_hash,file_modified_at,graphiti_status,created_at,updated_at,source_version_id,import_identity,knowledge_unit_identity,action,file_state,promotion_policy,knowledge_unit_identities) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?)CREATEzjupdate manual_ingest_submissions set graphiti_queue_id=?,status=?,provenance_state=? where submission_id=?ABGESCHLOSSENDERIVED_OBSIDIAN_AKTUALISIERT)-r*   r#   r    r   r   r   uuiduuid4hexr   rO   rr   rs   stripr\   r   r   r7   r8   r9   rQ   r   r   encoder   r>   rw   MAX_TEXTr   r   r   splitr'   resubwrite_bytescommitr   r   r)   r   
write_textjsondumpsError)#kindfieldsr   r   	submittedmoder   r   r   r   noterT   r   ri   r   r   r   r   	canonicaldup	duplicateidentity_keyr   raw_pathregreg_idprevvnr   derived_pathfrontstmtkuidentkidqids#                                      r   ingestr-  K   s   K24w{{&AIdjjl&6&66#%	X[\b\f\fgx\y  ]G  ~G  YH  YN  YN  YP  Tz  Yzf  @I&**W%+,224C

7@S@YWY<Z<`<`<belopvpzpz  |E  qF  qL  JL  mM  mS  mS  mUdk  _b  ci  cm  cm  nw  cx  c~  |~  _  _E  _E  _G  W^  NQ  RX  R\  R\  ]m  Rn  Rt  rt  Nu  N{  N{  N}  IM  CE  B  PR  GO  Zf  TY;,SE1B1Hb-I-O-O-QRbklobpTaTWX[\a{  AG  AM  AM  AV  AV  WZ  A[  A`  A`  |a  |f  |f  |v  jvrz  }@  }G  }G  HN  OX  }Y  x|6\FJJv$6$<" =44;;=s[lRZ6\C

:(>(N,$O8U[U_U_`fUgUnknQT  vB  CK  LO  vPpt9::zz|:.R#SS<CHX-Z@k5l/l'SXPRyII  `  bn  ox  y{  a|  }  F  F  H!$^)<l)J+beQ^kw	09S))+,|!$s*<+<<99VXgWijssu  xG  KX  Y\  Yb  Yb  cf  gh  Yi  jk  Yl  mp  np  Yq  Kq  xq  xGS,s*2662DS+RSWTW+XXYZ\`ai\j\v\vwz\{			xz}  N  Vb  jw  L  OM  NR  OS  TY  Te  ]e  fi  jr  s|  }E  FQ  R^  _d  el  mt  uy  z~  S  T]  ^k  lp  qy  z~  C  DH  IJ  KL  zM  	Nk!199  .C  EP  Q  @C  DU  @V  QV  WZ  D[  $\  ^_  ^f  ^f  ^h  q  @A  BE  qF* WWY) IIY[jZlmvvx  LO  BE  FG  BH  UY  {A>II  v  x@  AD  EH  IN  OZ  [d  em  ny  zK  LX  YT  U^  _n  ox  yM  wN  O  XY  Xa  Xa  b~  X  XH	  XH	  XJ	  K	L	  XM	  QWYYoqwpyz  D  D  F  hl  LP  Qa  Lb  cd  Ld  rs  HJ			  l  nt  u@  AM  N]  ^b  Nb  cf  gi  cj  Nj  km  DH  nr  s  n@  NR  S[  \e  fo  py  zB  CL  M^  m_  	`  mn  mv  mv  wS  mT  m]  m]  m_  `a  mb  bl			~  AK  L_  `i  jp  @q  	r  tu  t}  t}  ~j  lv  wJ  K_  `c  kd  te<II[]ijm\no  B  CJ  LX  Y]  L]  ^a  bd  ^e  Le  fk  Lk  Cl  mq} E  E7  ETaiv9wx|9}7  E  @S  E  Tc  Sd  E  dv  E  wA  vB  E  BQ  E  R]  Q^  E  ^n  E  o{  n|  E  |L  E  MP  LQ  E  Qf  E  go  fp  E  p{  E  |C  {D  E  DO  E  PW  OX  E  Xa  E  bg  ah  E  h_  E  `i  _j  E  j|  E  }A  |B  E  BM  E  NS  N_  W_  M`  E  `c
  E  d
h
  i
r
  j
r
  d
s
  c
t
  E  t
W  E  X[  Xg  _g  Wh  E  h{  E  |K  {L  E  L^  E  _i  ^j  E  jr  E  s  r@  E  @B  EE  GK  LX  GY  Gd  Gd  ej  tz  Gd  G{II}  @L  MY  Zf  gj  k  l %%*2tIX>DX\H\]`ac]dHdekHkII  O  QX  Y]  ^b  ^h  ^h  rw  BI  T[  mE  iF  TY  ^Z  [_  `o  pz  {G  HL  HR  HR  fu  J	T	  e	m	  |	G
  SH
  V
[
  H\
  ]
{
  |
E  FV  Wa  bA  BK  LR  PS  T		67@@B1ECqyy  Rm  or  sB  CF  GQ  CR  Sc  d{  |E  nF  HG  K  MP  Q`  ah  ix  yA  BF  GP  HP  BQ  LR  SII  J  LW  Xc  dg  Kh  iII  x  zB  CO  P\  ]f  gx  yB  CL  MW  Xg  ho  px  yB  CT  UY  U_  U_  ah  `i  Uj  yk  l		67@@B1ECqyy  R~  @C  DS  Ts  tw  x  Hy	
>!C0WWY ==&$&
 WWYs8   P-` )K` :` B` `` `` `1c                
    | dv S )N)z	127.0.0.1z::1r/   r   )clients    r   
local_onlyr0  t   s    v)HHHr   c                D   t        |      sdddifS ddddj                  |       }|sy t        |      t        dz   kD  rd	dd
ifS 	 |dk(  rt	        ||      n"t        j                  |j                               }|dk(  rk|j                  d      xs i }dD ci c]  }||j                  |d       }}|j                  |j                  d      xs d|j                  dd             dt        ||      fS c c}w # t        $ r}ddt        |      ifcY d }~S d }~ww xY w)Ni  errormanual_ingest_local_onlyrT   r   r   )z/api/knowledge/ingest/urlz/api/knowledge/ingest/textz/api/knowledge/ingest/filei   i  payload_too_large)r   r   r   r   r   r   r5   r   r   r   r   )r   r      i  )r0  rr   rw   r   r   r  loadsr   updater-  	ExceptionrO   )	rQ   ra   r   r/  r  r  ukrX   s	            r   ingest_postr;  u   s   fc73M*N&NN&+ms	t	x	xy}	~Dt
4y)##38K/L+L$L6,0&L{74(djj>W<jj &BA  MU  0Vq&**Qr2B0B  0V  0V  X^  Xe  Xe  op  ot  ot  u  o@  oP  DP  VW  V[  V[  \b  cf  Vg  Xe  Xh6$v&&& 0V5gc!f%5!555s2   AC= C82AC= 8C= =	DDDDc                   | dk(  rdt               fS t        j                  d|       }|rOt               }t        j
                  |_        dt        |d|j                  d      z         f|j                          S y # |j                          w xY w)Nz/api/knowledge/ingest/historyr5  z^/api/knowledge/ingest/([^/]+)$r   re   )
r   r  matchr#   r    r   r   r   groupr   )rQ   mr   s      r   
ingest_getr@     sp    ,,S].Bhh1$7A
$gkk~a	!''!*(<==	 	s   	A: :B)rc   ),__doc__
__future__r   r   r   rG   r   r  r  rC   r    r   r   urllib.parser7   urllib.requestr
  r   r   pathlibr   r"   ROOTr'   r)   r  ru   r   r   r   r   r#   r*   r\   r   r   r   r   r   r   r-  r0  r;  r@  r   r   r   <module>rG     s    # w w w w w w w ' 0t<Y7Z$`dej`j\_tx  z]  u^ls	+'x&/x  AM  Tc  lo  wA  B 8 0 / aX,i$wu
B(R I
6r   