
    GtjW                        d Z ddlZddlmZ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 dd	lmZ dd
lmZ ddlmZmZ ddlmZmZmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$ de%fdZ&de%fdZ'de(fdZ) G d d      Z* G d d      Z+y)u8   프로젝트 JSON 내보내기 / 가져오기 서비스.    N)datetimetimezone)Path)Any)Session)settings)AppError)to_relative_image_path)t)ProjectRegistryProjectMember)EpisodeEntityCanonEntityAliasRelationFactRelationParticipant
SceneStillEntityEpisodeLink
ImageAsset
WorldGuideWebbookPackageGenerationTraceOperationLogProjectSettingsCharacterOutlookreturnc                  d    t        j                  t        j                        j	                         S N)r   nowr   utc	isoformat     Y/Users/manta/Documents/Projects/TheRoad-I1/backend/app/services/project_export_service.py_nowr%   !   s    <<%//11r#   c                  <    t        t        j                               S r   )struuiduuid4r"   r#   r$   _new_idr*   %   s    tzz|r#   c                     | j                   j                  D ci c]#  }|j                  t        | |j                        % }}t	        | t
              r"|j                  d      rt        |d         |d<   |S c c}w )u8  Convert a SQLAlchemy ORM row to a plain dict (column values only).

    ImageAsset 행은 ``file_path`` 가 ImagePathType에 의해 절대로 환원된 상태로
    들어온다. export ZIP/JSON에 절대 호스트 경로가 누출되지 않도록 직렬화 시점에
    상대로 변환한다 (Codex B2).
    	file_path)	__table__columnsnamegetattr
isinstancer   getr
   )rowcds      r$   _row_to_dictr6   )   sj     03}}/D/DE/D!aff%	%/DAE#z"quu['9/+?+H 	Fs   (A7c                   D    e Zd ZdededdfdZd ZdefdZde	e   fdZ
y)	ProjectExportServicedb
project_idr   Nc                      || _         || _        y r   )_db_project_id)selfr9   r:   s      r$   __init__zProjectExportService.__init__;   s    %r#   c                     | j                   j                  |      j                  | j                        }|j	                         D ]#  \  }}|j                  t        ||      |k(        }% |j                         S )N)r:   )r<   query	filter_byr=   itemsfilterr0   all)r>   modelfiltersqkvs         r$   _qzProjectExportService._q?   sa    HHNN5!++t7G7G+HMMODAq*a/0A $uuwr#   c                 D	   | j                   }| j                  j                  t              j	                  t        j
                  |k(        j                         }|st        dt        d      d      | j                  j                  t              j	                  t        j                  |k(        j                         }| j                  t              }| j                  t              }|D cg c]  }|j
                   }}|rZ| j                  j                  t              j	                  t        j                   j#                  |            j                         }ng }| j                  t$              }	|	D 
cg c]  }
|
j
                   }}
|rZ| j                  j                  t&              j	                  t&        j(                  j#                  |            j                         }ng }| j                  t*              }| j                  t,              }| j                  t.              }| j                  t0              }| j                  t2              }| j                  t4              }| j                  t6              }| j                  t8              }| j                  t:              }i dddt=               dt?        |      d|D cg c]  }t?        |       c}d	|D cg c]  }t?        |       c}d
|D cg c]  }t?        |       c}d|D cg c]  }t?        |       c}d|	D 
cg c]  }
t?        |
       c}
d|D cg c]  }t?        |       c}d|D cg c]  }t?        |       c}d|D cg c]  }t?        |       c}d|D cg c]  }t?        |       c}d|D cg c]  }t?        |       c}d|D cg c]  }t?        |       c}d|D cg c]  }t?        |       c}d|D cg c]  }t?        |       c}d|D  cg c]  } t?        |        c} d|D !cg c]  }!t?        |!       c}!iS c c}w c c}
w c c}w c c}w c c}w c c}w c c}
w c c}w c c}w c c}w c c}w c c}w c c}w c c}w c c}w c c} w c c}!w )z4Export all project data as a JSON-serialisable dict.zproject.not_foundi  codemessagestatus_codeexport_versionz1.0exported_atprojectmembersepisodesentitiesentity_aliases	relationsrelation_participantsscene_stillsentity_episode_linksimagesworld_guideswebbook_packagesgeneration_tracesoperation_logsproject_settingscharacter_outlooks) r=   r<   rA   r   rD   idfirstr	   r   r   r:   rE   rK   r   r   r   canon_idin_r   r   relation_idr   r   r   r   r   r   r   r   r   r%   r6   )"r>   pidrS   rT   rU   rV   e
entity_idsrW   rX   rrelation_idsrY   rZ   r[   r\   r]   r^   r_   r`   ra   rb   mapslnkimgwgwpgtolpscos"                                     r$   export_jsonz ProjectExportService.export_jsonE   sQ    HHNN?+VO&&#-.UW 	
 (-.  HHNN=)VM,,34SU 	 777#77;' %--HqaddH
-{+,,00<=   NGGL)	&/0ii023+77;;LIJ " %'!wwz*#ww'89$wwz*77>2 GGO4.77?3!WW%56
e
46
 |G,
 9AQ9	

 (;(Qa(;
 (;(Qa(;
 G1|AG
 9=9a,q/9=
 $?T%U?T!l1o?T%U
 lCl\!_lC
 #BV$WBV3\#%6BV$W
 F;FS|C(F;
 E"\"-E
 <L M<Lbb!1<L M
  =N!O=Nr,r"2=N!O
  .I.B|B/.I!
" <L M<Lbb!1<L M#
$ !>P"Q>P<#3>P"Q%
 	
? . 10 :;;G=%UC$W;E M!OI M"Qsf   .Q:Q
Q$Q>Q!Q&2Q+Q0&Q5 Q:Q?4RR	(RRR6Rc                 ,   t        t        j                        | j                  z  }|j	                         sg S g }t        |j                  d            D ]<  }|j                         s|j                  t        |j                  |                   > |S )z@Return relative paths of every file under the project directory.*)r   r   projects_dirr=   existssortedrglobis_fileappendr'   relative_to)r>   project_dirresultpaths       r$   export_assets_listz'ProjectExportService.export_assets_list   sy    8001D4D4DD!!#I;,,S12D||~c$"2"2;"?@A 3 r#   )__name__
__module____qualname__
OrmSessionr'   r?   rK   dictry   listr   r"   r#   r$   r8   r8   :   s@    &: &3 &4 &L
T L
\	DI 	r#   r8   c                   <    e Zd ZdededdfdZd	dededz  defdZy)
ProjectImportServicer9   actor_idr   Nc                      || _         || _        y r   )r<   	_actor_id)r>   r9   r   s      r$   r?   zProjectImportService.__init__   s    !r#   datanew_namec                    d|vsd|vrt        dt        d      d      |d   d   }t               }t               }||idt        dz  d	t        dz  ffd
dt        d	t        ffd}|j                  dg       D ]  } ||d           |j                  dg       D ]  } ||d           |j                  dg       D ]  } ||d           |j                  dg       D ]  } ||d           |j                  dg       D ]  } ||d           |j                  dg       D ]  } ||d           |j                  dg       D ]  } ||d           |j                  dg       D ]  } ||d           |j                  dg       D ]  } ||d           |j                  dg       D ]  } ||d           |j                  dg       D ]  } ||d           |j                  dg       D ]  } ||d           |j                  dg       D ]  } ||d           |j                  dg       D ]  } ||d           |j                  dg       D ]  } ||d           t        t        j                        }||z  }	dD ]  }
|	|
z  j                  dd        |d   j                         }|xs |j                  dd      }t        |||j                  d d!      d"| j                  ||#      }| j                  j                  |       | j                  j                          t!        t               || j                  d$d|%      }| j                  j                  |       | j                  j                          d&t"        d't        d	t"        ffd(}|j                  dg       D ]  } ||dd)      }|j                  d*d!      }|r*t        |      j$                  }t	        |	d+z  d,z  |z        }nd!}| j                  j                  t'        |d   ||j                  d-d.      |j                  d/d!      |j                  d0d!      ||j                  d1      |j                  d2d3      |j                  d4      |j                  d5d6      |j                  d7      |j                  d8|      |j                  d9|      :             ! |j                  dg       D ]  } ||dd)      }| j                  j                  t)        |d   ||j                  d;      |j                  d<d=      |j                  dd!      |j                  d       |j                  d>d?      |j                  d@d?      |j                  dA      |j                  d5d"      |j                  d8|      |j                  d9|      B              | j                  j                          |j                  dg       D ]I  } ||ddC      }| j                  j                  t+        |d   |dC   |j                  dDd!      E             K |j                  dg       D ]  } ||dd)      }| j                  j                  t-        |d   ||j                  dFd!      |j                  dGd!      |j                  dHd!      |j                  dId!      |j                  dJd!      |j                  dK      |j                  d8|      L	              |j                  dg       D ]_  } ||ddMdC      }| j                  j                  t/        |d   |dM   |dC   |j                  dNd!      |j                  dOdP      Q             a t0        j2                  j4                  D ch c]  }|j$                   }}|j                  dg       D ]q  } ||dd)dRdS      }|j7                         D ci c]  \  }}||v s|| }}}||d)<   |j9                  d8|       | j                  j                  t1        di |       s |j                  dg       D ]P  } ||dd)dCdR      }| j                  j                  t;        |d   ||dC   |dR   |j                  dTdU      V             R |j                  dg       D ]l  } ||dd)dWdXdR      }|j                  dYd!      }|r*t        |      j$                  }t=        |	d+z  dZz  |z        }nd!}| j                  j                  t?        di d|d   d)|d[|j                  d[d\      dW|j                  dW      dX|j                  dX      dR|j                  dR      dY|d]|j                  d]      d^|j                  d^      d_|j                  d_      d`|j                  d`      d5|j                  d5dZ      da|j                  dad!      db|j                  db      dc|j                  dc      d8|j                  d8|             o |j                  dg       D ]h  } ||dd)dR      }| j                  j                  tA        |d   ||j                  dR      |j                  ddd?      |j                  d8|      e             j |j                  dg       D ]x  } ||dd)dR      }| j                  j                  tC        |d   ||j                  dR      |j                  dfd?      |j                  dg      |j                  d8|      h             z |j                  dg       D ]  } ||dd)didXdW      }| j                  j                  tE        |d   ||j                  di      |j                  dX      |j                  dW      |j                  djdP      |j                  d]d!      |j                  dgdk      |j                  dl      |j                  d5dm      |j                  dn      |j                  dodp      |j                  dq      |j                  dr      |j                  d8|      s              |j                  dg       D ]N  } ||dd)dR      }| j                  j                  tG        di d|d   d)|dt|j                  dtd!      dR|j                  dR      du|j                  dud!      dv|j                  dvd!      dw|j                  dw      dg|j                  dg      dx|j                  dx      dy|j                  dy      dz|j                  dz      d5|j                  d5dm      d{|j                  d{      d||j                  d|      d}|j                  d}d?      d@|j                  d@d?      d8|j                  d8|             Q |j                  dg       D ]  } ||dd)      }| j                  j                  tI        |d   ||j                  d~      |j                  d      |j                  d      |j                  d      |j                  dd      |j                  d9|                    |j                  dg       D ]P  } ||dddd)      }| j                  j                  tK        |d   |d   |d   ||j                  d8|                   R | j                  jM                          |S c c}w c c}}w )zImport a project from an exported JSON blob.

        Generates fresh UUIDs for every record, remaps all internal
        foreign-key references, and wires the importing user as owner.

        Returns the new project_id.
        rQ   rS   zimport.invalid_formati  rM   rc   old_idNr   c                 .    | y j                  | |       S r   )r2   )r   id_maps    r$   _remapz0ProjectImportService.import_json.<locals>._remap   s    ~::ff--r#   c                 &    t               }|| <   |S r   )r*   )r   new_idr   s     r$   	_registerz3ProjectImportService.import_json.<locals>._register   s    YF#F6NMr#   rU   rV   rW   rX   rY   rZ   r[   r\   r]   r^   r_   r`   ra   rb   rT   )zassets/screenplayszassets/referenceszassets/generatedzassets/exportsT)parentsexist_okr/   zImported Projectdescription active)rc   r/   r   status
created_by
created_at
updated_atowner)rc   r:   user_idroleadded_byr   r3   	fk_fieldsc                 h    | j                         }|D ]  }||v s||    ||         ||<    |S r   )copy)r3   r   rk   fieldr   s       r$   
_remap_rowz4ProjectImportService.import_json.<locals>._remap_row  sA    
A"A:!E("6%ah/AeH # Hr#   r:   source_pathassetsscreenplaysepisode_numberr   titlesource_filenamefulltextlanguageko
page_countr   uploadedanalysis_errorr   r   )rc   r:   r   r   r   r   r   r   r   r   r   r   r   short_identity_type	characterstable_traitsz{}metadata_json
t2i_prompt)rc   r:   r   r   r/   r   r   r   r   r   r   r   re   alias)rc   re   r   relation_familyrelation_typedirectionalitytemporal_scopecontinuity_prioritycontinuity_reason)	rc   r:   r   r   r   r   r   r   r   rg   participant_roleparticipant_order   )rc   rg   re   r   r   
episode_iddependent_scene_idsource	extracted)rc   r:   re   r   r   	entity_idstill_idr,   	generated
asset_typesceneprompt_usedgeneration_modelwidthheightreview_notesvalidation_scorevalidation_result
guide_json)rc   r:   r   r   r   package_jsonprompt_version)rc   r:   r   r   r   r   image_asset_idattempt_numberoriginal
model_namesuccessblock_reasonblock_categoriesz[]response_time_mssanitizer_feedback)rc   r:   r   r   r   r   r   r   r   r   r   r   r   r   r   operation_typemodule_namemodule_versionprompt_nameprompt_hashinput_summaryoutput_summaryerror_messageduration_mstoken_usagecomposer_system_promptcomposer_user_promptstyle_rules_jsonworld_summaryscene_split_thresholdiX  )rc   r:   r   r   r   r   r   r   character_id
outlook_id)rc   r   r   r:   r   r"   )'r	   r   r*   r%   r'   r2   r   r   r|   mkdirr   r   r   r<   addflushr   r   r/   r   r   r   r   r   r   r-   r.   rC   
setdefaultr   r
   r   r   r   r   r   r   r   commit)r>   r   r   old_project_idnew_project_idr   r   r3   baser   sub	proj_dataproject_namerS   owner_memberr   rk   original_sourcesafe_source_namesafe_source_pathr4   _still_colsrI   rJ   valsoriginal_file_path	safe_namesafe_file_pathr   r   s                               @@r$   import_jsonz ProjectImportService.import_json   sS    4'9D+@,12  #9od3%if #1.!A	.3: 	.#* 	.
	c 	c 	 88J+Cc$i  ,88J+Cc$i  ,88,b1Cc$i  288K,Cc$i  -883R8Cc$i  988NB/Cc$i  0882B7Cc$i  888Hb)Cc$i  *88NB/Cc$i  088.3Cc$i  488/4Cc$i  588,b1Cc$i  288.3Cc$i  4880"5Cc$i  6 88Ir*Cc$i  + H))*^+dC3%%dT%B e %)O$8$8$:	L9==9K#L!!mR8~~
 	W %y%NN
 	\"	D 	c 	d 	 88J+C3l3AeeM26O#'#8#=#= #&{X'='MP`'`#a #% HHLLT7) uu%5q9eeGR( !&7 <,z*z4055.uuXz2 uu%5655s355s3  ,4 88J+C3l3AHHLLT7)z*EE-=UU62&EE-0eeOT:  eeOT:55.uuXx055s355s3  ,6 	 88,b1C3j1AHHLLT7:eeGR(  2 88K,C3l3AHHLLT7) !&7 <eeOR8 uu%5r: uu%5r:$%EE*?$D"#%%(;"<55s3
 
 - 883R8C3mZ@AHHLL,T7m,:!"'92!>"#%%(;Q"?  9( (2';';'C'CD'C!qvv'CD88NB/C3lL/1A%&WWYCYTQ!{2BAqDYDC!/DOOL#.HHLL+d+, 0 882B7C3lJMAHHLL*T7):\?uuX{3  8 88Hb)C3lK\ZA "#{B!7! !3499	!7(*[89D" "$HHLL T7) 55w7 %%,	
 z* 55. ) EE-0 "#'9!: eeGn uuX uuX{3 UU>26 "#'9!: #$%%(;"<  55s3!  *@ 88NB/C3lLAAHHLLT7)55.55t455s3  0 88.3C3lLAAHHLLT7)55.UU>48 uu%5655s3  4 88/4C3l4DjR]^AHHLLT7) uu%56z*%%, uu%5q9EE-4 uu%5zB55.uuXy1UU>2!"'94!@!"'9!:#$55)=#>55s3  5* 88,b1C3lLAAHHLL T7)  !uu%5r: 55.	
 EE-4  !uu%5r: EE-0  !uu%56 EE-0  eeO4  !uu%56 uuXy1  eeO4 EE-0 EE-6   eeOT:!" 55s3#  2. 88.3C3l3AHHLLT7)'(uu-E'F%&UU+A%B!"'9!:eeO4&'ee,CS&I55s3	 	 4 880"5C3nlLQAHHLL)T7~.\?)55s3  6 	c E Ds   {{"{r   )r   r   r   r   r'   r?   r   r  r"   r#   r$   r   r      s>    ": " " "e ed
 ec er#   r   ),__doc__r(   r   r   pathlibr   typingr   sqlalchemy.ormr   r   app.core.configr   app.core.errorsr	   app.core.file_pathsr
   app.i18n.loaderr   app.models.catalogr   r   app.models.projectr   r   r   r   r   r   r   r   r   r   r   r   r   r   r'   r%   r*   r   r6   r8   r   r"   r#   r$   <module>r     sw    >  '   0 $ $ 6  =   $2c 2 
 
"b bRj jr#   