(17itFdZddlZddlZddlmZmZddlmZddlmZm Z m Z m Z eje ZeGddZeGdd Zy) zTData Models for ChefSystem. Defines Recipe and Output models with CRUD operations. N) dataclassasdict)datetime)OptionalListDictAnyceZdZUdZdZeeed<dZe ed<dZ e ed<dZ e ed<dZ e ed<dZ e ed <dZeeed <dZeeed <d ee effd Zedee efd dfdZedej.d dfdZe dde de de de d e d edf dZeded edfdZed edfdZeded efdZeded efdZedde deee d edfdZ y)RecipeaRecipe model representing a prompt template. Attributes: id: Unique identifier (auto-generated). name: Recipe name (must be unique). prompt_text: The actual prompt template text. tags: Comma-separated tags for categorization. description: Short description of the recipe. notes: Additional notes or instructions. created_at: Timestamp of creation. updated_at: Timestamp of last update. Nidname prompt_texttags descriptionnotes created_at updated_atreturnct|}|jr|jj|d<|jr|jj|d<|S)zConvert recipe to dictionary for serialization. Returns: dict: Recipe data as dictionary with datetime as ISO strings. rr)rr isoformatrselfdatas :/mnt/ssd/data/python-lab/ChefSystem/src/database/models.pyto_dictzRecipe.to_dict'sN d| ??!%!:!:!r?r'rAs rr7zRecipe.get_by_id3 $$&D\\# |4F//#C||C((}}  LLr?rowsr'rAs rget_allzRecipe.get_alls? $$&D\\#&F??$D156#CLL%6 66}}  LLB1#FQUL VI .5AAAAB,B B Bc hd}|jDcic] \}}||vs ||}}}|stjdydj|j Dcgc]}|d c}} | dz } d| d} t |j |gz} |j} | j| | } | j| jd kDrtjd |y tjd |ycc}}wcc}w#tj$r"}tjd |Yd}~yd}~wtj$r'}tjd|d|d Yd}~yd}~wwxYw)a*Update an existing recipe. Args: db: DatabaseManager instance. recipe_id: ID of recipe to update. **kwargs: Fields to update (name, prompt_text, tags, description, notes). Returns: bool: True if successful, False otherwise. >rrrrr#No valid fields provided for updateF,  = ?z , updated_at = CURRENT_TIMESTAMPzUPDATE recipes SET WHERE id = ?rzUpdated recipe TNo recipe found with ID z+Failed to update recipe (duplicate name?): NzDatabase error updating recipe r-r.)itemsr5warningjoinkeyslistvaluesr1r2r3rowcountr6r8r9r:r;)r%r<r@kwargsallowed_fieldskv update_fieldsfield set_clauser=rZr>r?rAs rupdatez Recipe.updatesqQ*0,,.P$!QAr?rAs rdeletez Recipe.deletes1 $$&D\\# |4F KKM" oi[8VWX!9)EF}}  LL:9+RsKVZL [ sAA9 A99B3 B..B3querycg}g}|rI|jr9d|jd}|jd|j|||g|rYdj|Dcgc]}dc}}|r8|jd|d|j|D cgc]} d| d c} |rdj|nd} d | d } |j } | j | |} | j }|Dcgc]}|j|c}Scc}wcc} wcc}w#tj$r&}tjd |d gcYd}~Sd}~wwxYw)aSearch recipes by name and/or tags. Args: db: DatabaseManager instance. query: Search query for recipe name (case-insensitive). tags: List of tags to filter by (any match). Returns: List of matching recipes. %z3(name LIKE ? OR description LIKE ? OR notes LIKE ?)z OR z tags LIKE ?()z AND z1=1zSELECT * FROM recipes WHERE z ORDER BY created_at DESCz"Database error searching recipes: Tr.N) stripappendextendrWr1r2rJr+r8r;r5r:)r%r<rgr conditionsparams query_pattern_tag_conditionstag where_clauser=r>r?rLr'rAs rsearchz Recipe.searchsV  U[[] a0M   S T MM=-G H #[[)FA-)FGN!!An%5Q"78 T:c3%qz:;4>w||J/5 ,\N:ST $$&D\\#v.F??$D156#CLL%6 6*G;7}}  LL=aSADL QI s<! D D6D'=D"D'"D''E :EE E )r r r )r N)!__name__ __module__ __qualname____doc__r rint__annotations__rr"rrrrrrrrr r classmethodr&r8Rowr+rBr7rrMboolrcrfrvrrrr r s B D#NKD#NKE3O%)J")%)J") c3h T#s(^  7;; 8  (CE#c###,/#=@#JRS[J\##Jchx.@0DN*+3+T++Z346*s*xS /B*dS[n**rr ceZdZUdZdZeeed<dZeed<dZ e ed<dZ e ed<dZ e ed <dZ eed <dZe ed <dZeeed <d ee effdZedee efd dfdZedej.d dfdZe ddede de d e d ed e d edfdZeded edfdZeded edfdZed edfdZeded efdZeded efdZ y)OutputaOutput model representing a generated output file. Attributes: id: Unique identifier (auto-generated). recipe_id: Foreign key to the recipe. filename: Name of the output file. filepath: Relative path from outputs/ directory. file_type: File extension (.pdf, .docx, etc.). file_size: Size in bytes. execution_notes: Notes about this execution. generated_at: Timestamp of generation. Nr rr@r filenamefilepath file_type file_sizeexecution_notes generated_atrcnt|}|jr|jj|d<|S)zConvert output to dictionary for serialization. Returns: dict: Output data as dictionary with datetime as ISO string. r)rrrrs rrzOutput.to_dict@s4 d|   #'#4#4#>#>#@D  rrcvd|vr.t|dtrtj|d|d<|di|S)zCreate Output from dictionary. Args: data: Dictionary with output data. Returns: Output: New output instance. rrr r$s rr&zOutput.from_dictKs@ T !jn1Es&K#+#9#9$~:N#OD {T{rr'c ||d|d|d|d|dxsd|dxsd|d xsd|d rtj|d  Sd S) zCreate Output from database row. Args: row: SQLite row object. Returns: Output: New output instance. r r@rrrr rrrrN)r r@rrrrrrr)r*s rr+zOutput.from_rowYs4y+&__+&,"+&+! 128bHKNH[//N0CD  bf  rc d} |j} | j|||||||f} | j| j} tj d| d|d||j || S#tj$r"} tjd| Yd} ~ yd} ~ wtj$r$} tjd| d Yd} ~ yd} ~ wwxYw) aCreate a new output record in the database. Args: db: DatabaseManager instance. recipe_id: ID of the associated recipe. filename: Output filename. filepath: Relative filepath from outputs/. file_type: File extension. file_size: File size in bytes. execution_notes: Notes about this execution. Returns: Output: Created output with id and timestamp, or None on error. z INSERT INTO outputs (recipe_id, filename, filepath, file_type, file_size, execution_notes) VALUES (?, ?, ?, ?, ?, ?) zCreated output with ID z for recipe r-z2Failed to create output (foreign key violation?): Nz Database error creating output: Tr.r0) r%r<r@rrrrrr=r>r? output_idrAs rrBz Output.createns$  $$&D\\# 8XyR[]l'mnF KKM((I KK1)L SUV^U_` a==Y/ /%%  LLMaSQ R}}  LL;A3?$L O s$A3A88C" B((C">CC"rcd} |j}|j||f}|j}|r|j|Sy#tj $r'}t jd|d|dYd}~yd}~wwxYw)zRetrieve an output by ID. Args: db: DatabaseManager instance. output_id: Output ID to retrieve. Returns: Output or None if not found. z"SELECT * FROM outputs WHERE id = ?Nz!Database error retrieving output r-Tr.rD)r%r<rr=r>r?r'rAs rr7zOutput.get_by_idrFrGc4d} |j}|j||f}|j}|Dcgc]}|j|c}Scc}w#tj $r)}t jd|d|dgcYd}~Sd}~wwxYw)aRetrieve all outputs for a specific recipe. Args: db: DatabaseManager instance. recipe_id: Recipe ID to filter by. Returns: List of outputs for the recipe, ordered by generation date (newest first). zDSELECT * FROM outputs WHERE recipe_id = ? ORDER BY generated_at DESCz-Database error retrieving outputs for recipe r-Tr.NrI) r%r<r@r=r>r?rLr'rAs r get_by_recipezOutput.get_by_recipesU $$&D\\# |4F??$D156#CLL%6 66}}  LLH SUVWUXYdhL iI s.7AAAAB.B BBc*d} |j}|j|}|j}|Dcgc]}|j|c}Scc}w#tj $r&}t jd|dgcYd}~Sd}~wwxYw)zRetrieve all outputs. Args: db: DatabaseManager instance. Returns: List of all outputs, ordered by generation date (newest first). z0SELECT * FROM outputs ORDER BY generated_at DESCz'Database error retrieving all outputs: Tr.NrIrKs rrMzOutput.get_allsA $$&D\\#&F??$D156#CLL%6 66}}  LLB1#FQUL VI rNc hd}|jDcic] \}}||vs ||}}}|stjdydj|j Dcgc]}|d c}} d| d} t |j |gz} |j} | j| | } | j| jdkDrtjd |y tjd |ycc}}wcc}w#tj$r'}tjd |d |d Yd}~yd}~wwxYw)zUpdate an existing output. Args: db: DatabaseManager instance. output_id: ID of output to update. **kwargs: Fields to update. Returns: bool: True if successful, False otherwise. >rrrrrrPFrQrRzUPDATE outputs SET rSrzUpdated output TNo output found with ID zDatabase error updating output r-r.N)rUr5rVrWrXrYrZr1r2r3r[r6r8r;r:)r%r<rr\r]r^r_r`rarbr=rZr>r?rAs rrcz Output.updates>_*0,,.P$!QAr?rAs rrfz Output.deletes1 $$&D\\# |4F KKM" oi[9:!9)EF}}  LL:9+RsKVZL [ sAA8A88B2 B--B2)r rr )!rwrxryrzr rr{r|r@rr"rrrrrrrr rr}r&r8r~r+rBr7rrrMrrcrfrrrrr(s B IsHcHcIsIsOS'+L(8$+ c3h  T#s(^    7;; 8  (56&($3$#$$$/2$ #$-5h-?$$Lchx.@0#$x.,DN*$3$T$$L34rr)rzr8logging dataclassesrrrtypingrrrr getLoggerrwr5r rrrrrsi ),,   8 $ UU Up ss sr