
    .i{9                        d dl Z d dlZd dlmZmZ d dlmZ d dlmZmZm	Z	m
Z
mZ d dlmZ d dlmZ  e j"                  e      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mZ de fdZ!de fdZ"de de fdZ#de de fdZ$ G d d      Z%y)    N)datetimetimezone)Path)AnyDictListOptionalTuple)Session)settings)AppError)t)ActivityLogger)ActivityLog)ProjectRegistryProjectMemberUserAccountreturnc                  d    t        j                  t        j                        j	                         S N)r   nowr   utc	isoformat     R/Users/manta/Documents/Projects/TheRoad-I1/backend/app/services/project_service.py_nowr      s    <<%//11r   c                  <    t        t        j                               S r   )struuiduuid4r   r   r   _new_idr"      s    tzz|r   korean_namec                 ^   	 ddl m}  |dd| dddiid      }|j                         j                  d	      j                  d
      }|rt        |      dk  r|S ddl}|j                  dd|       j                         xs dS # t        $ r!}t
        j                  d| |       Y d}~Nd}~ww xY w)ua   한국어 프로젝트명을 영어로 변환. gpt-nano 사용. 실패 시 romanization fallback.r   )	call_textproject_summarya$  You are a translator. The input is a Korean film/drama project name. Translate or transliterate it to English. For proper nouns (titles), use the official romanization or a natural English equivalent. Reply with ONLY the English name, nothing else. Use title case. Keep version numbers as-is.modelgptg        )stepsystem_promptuser_promptproject_configtemperature"'d   uF   English name generation failed for '%s': %s — 로컬 fallback 사용Nz[^a-zA-Z0-9 ] Project)	app.modules.llm.llm_clientr%   striplen	Exceptionloggerwarningresub)r#   r%   resultnameexcr9   s         r   generate_english_namer>      s    s8" A#-/?@
 ||~##C(..s3CIOK 66"B4::<I	I	  s_alnqrrss   AB 	B,B''B,
project_idc                    | j                  t              j                  t        j                  |k(        j	                         }|sy|j
                  r|j
                  S t        |j                        }||_        | j                          |S )u7   name_en이 없으면 생성해서 DB 저장 후 반환.r2   )	queryr   filteridfirstname_enr>   r<   commit)dbr?   projectrE   s       r   ensure_english_namerI   0   si    hh'../A/AZ/OPVVXG#GLL1GGOIIKNr   c                   &   e Zd ZdeddfdZdededee   fdZ	dededdfdZ
d	edefd
Z	 d&dedededeee   ef   fdZ	 d'dedededee   def
dZdedefdZd	ededeeef   fdZ	 d'd	edeeef   dedee   def
dZ	 d'd	ededee   defdZd	ededee   fdZ	 d'd	ededededee   defdZ	 d'd	ededededee   defdZ	 d'd	edededee   ddf
d Z	 	 	 	 	 	 	 d(deded	ee   d!ee   d"ee   d#ee   d$ee   deee   ef   fd%Zy))ProjectServicerG   r   Nc                 2    || _         t        |      | _        y r   )_dbr   _logger)selfrG   s     r   __init__zProjectService.__init__>   s    %b)r   rH   userc                 "   |j                   dk(  rs| j                  j                  t              j	                  t        j
                  |j                  k(  t        j                  |j                  k(        j                         S | j                  j                  t              j	                  t        j
                  |j                  k(  t        j                  |j                  k(        j                         }|st        dt        d      d      |S )z@Return the user's membership or None. Admins always have access.adminzproject.access_denied  codemessagestatus_coderolerM   rA   r   rB   r?   rC   user_idrD   r   r   rO   rH   rQ   members       r   _check_accesszProjectService._check_accessD   s    99}-00GJJ>@U@UY]Y`Y`@`a HHNN=)VM,,

:M<Q<QUYU\U\<\]UW 	
 ,12 
 r   c                 Z   |j                   dk(  ry | j                  j                  t              j	                  t        j
                  |j                  k(  t        j                  |j                  k(        j                         }|r|j                   dk7  rt        dt        d      d      y )NrS   ownerzproject.modify_deniedrT   rU   rY   r\   s       r   _check_modifyzProjectService._check_modifyY   s    99HHNN=)VM,,

:M<Q<QUYU\U\<\]UW 	
 /,12  0r   r?   c                     | j                   j                  t              j                  t        j                  |k(  t        j
                  dk7        j                         }|st        dt        d      d      |S )Ndeletedzproject.not_found  rU   )	rM   rA   r   rB   rC   statusrD   r   r   )rO   r?   rH   s      r   _get_projectzProjectService._get_projecth   si    HHNN?+VO&&*4o6L6LPY6YZUW 	
 (-. 
 r   pageper_pagec                    | j                   j                  t              j                  t        j                  dk7        }|j
                  dk7  r| j                   j                  t        j                        j                  t        j                  |j                  k(        j                         }|j                  t        j                  j                  |            }|j                         }|j                  t        j                  j                               j!                  |dz
  |z        j#                  |      j%                         }||fS )Nrc   rS      )rM   rA   r   rB   re   rZ   r   r?   r[   rC   scalar_subqueryin_countorder_by
created_atdescoffsetlimitall)rO   rQ   rg   rh   qmember_project_idstotalitemss           r   list_projectszProjectService.list_projectsx   s     HHNN?+22?3I3IY3VW99}778--89 " 
 ++//0BCDA	

?55::<=DDdQhRZEZ[aabjkooqe|r   r<   descriptioncreator_useripc           
      r   t               }t        t        j                        }||z  }dD ]  }||z  j	                  dd        t               }	t        |      }
t        |||
|xs dd|j                  |	|	      }| j                  j                  |       | j                  j                          t        t               ||j                  dd |	      }| j                  j                  |       | j                  j                          | j                  j                  |j                  d	d
||d|i|       |S )N)zassets/screenplayszassets/referenceszassets/generatedzassets/exportsT)parentsexist_okr1   active)rC   r<   rE   ry   re   
created_byro   
updated_atr`   rC   r?   r[   rZ   added_byro   zproject.createrH   r<   actor_idactionresource_typeresource_idr?   detail
ip_address)r"   r   r   projects_dirmkdirr   r>   r   rC   rM   addflushr   rF   rN   log)rO   r<   ry   rz   r{   r?   baseproject_dirr:   r   rE   rH   r]   s                r   create_projectzProjectService.create_project   s%    Y
 H))*Z'dC3%%dT%B e f'-!#)r#	
 	Wy! OO
 	V!__##"!D> 	 	
 r   r[   c                     | j                   j                  t              j                  t        j                  |k(        j                         }|r|j                  S |S r   )rM   rA   r   rB   rC   rD   display_name)rO   r[   us      r   _resolve_usernamez ProjectService._resolve_username   sB    HHNN;'..{~~/HIOOQ!"q~~//r   c                    | j                  |      }| j                  ||      }| j                  j                  t              j                  t        j                  |k(        j                         }ddlm	} |j                  |      j                         }||d<   |r|j                  n|j                  dk(  rdnd |d<   | j                  |j                        |d<   |S )Nr   )ProjectResponsemember_countrS   my_roler   )rf   r^   rM   rA   r   rB   r?   rm   app.schemas.projectr   model_validate
model_dumprZ   r   r   )rO   r?   rQ   rH   
membershipr   r   	proj_dicts           r   get_projectzProjectService.get_project   s    ##J/''6
HHNN=)VM,,
:;UW 	
 	8#227;FFH	$0	.!2<zdii[bNb7hl	)"&"8"89K9K"L	,r   updatesc           
      v   | j                  |      }| j                  ||       i }i }dD ]4  }||v s||   t        ||      ||<   t        ||||          ||   ||<   6 t	               |_        | j                  j                          | j                  j                  |j                  dd||||d|       |S )N)r<   ry   re   zproject.updaterH   )beforeafterr   )rf   ra   getattrsetattrr   r   rM   rF   rN   r   rC   )	rO   r?   r   rQ   r{   rH   r   r   fields	            r   update_projectzProjectService.update_project   s     ##J/7D)!# "6EGEN$> ' 7u7&u~e	 7 "VWW##"!$u5 	 	
 r   c                    | j                  |      }| j                  ||       d|_        t               |_        | j
                  j                          | j                  j                  |j                  dd|||       |S )Nrc   zproject.deleterH   )r   r   r   r   r?   r   )
rf   ra   re   r   r   rM   rF   rN   r   rC   )rO   r?   rQ   r{   rH   s        r   delete_projectzProjectService.delete_project   sw     ##J/7D)"!VWW##"! 	 	
 r   c                     | j                  |      }| j                  ||       | j                  j                  t              j                  t        j                  |k(        j                         S r   )rf   r^   rM   rA   r   rB   r?   rs   )rO   r?   rQ   rH   s       r   list_memberszProjectService.list_members	  sU     ##J/7D)HHNN=)VM,,
:;SU	
r   rZ   
actor_userc           
      n   | j                  |      }| j                  ||       | j                  j                  t              j                  t        j                  |k(  t        j                  |k(        j                         }|rt        dt        d      d      t	        t               ||||j                  t                     }| j                  j                  |       | j                  j                          | j                   j#                  |j                  dd|j                  |||d|       |S )	Nzmember.already_exists  rU   r   z
member.addr]   )r[   rZ   r   )rf   ra   rM   rA   r   rB   r?   r[   rD   r   r   r"   rC   r   r   rF   rN   r   )	rO   r?   r[   rZ   r   r{   rH   existingr]   s	            r   
add_memberzProjectService.add_member  s    ##J/7J/ HHNN=)VM,,
:M<Q<QU\<\]UW 	
 ,12  y!]]v
 	V]]"		!&5 	 	
 r   target_user_idnew_rolec                 (   | j                  |      }| j                  ||       | j                  j                  t              j                  t        j                  |k(  t        j                  |k(        j                         }|st        dt        d      d      |j                  dk(  r|dk7  r{| j                  j                  t              j                  t        j                  |k(  t        j                  dk(        j                         }|dk  rt        dt        d      d      |j                  }	||_        | j                  j                          | j                  j                  |j                   dd	|j                   |||	|d
|       |S )Nmember.not_foundrd   rU   r`   rj   zmember.must_have_ownerr   zmember.role_changer]   )r[   r   r   r   )rf   ra   rM   rA   r   rB   r?   r[   rD   r   r   rZ   rm   rF   rN   r   rC   )
rO   r?   r   r   r   r{   rH   r]   owner_countold_roles
             r   update_member_rolez!ProjectService.update_member_roleA  sb    ##J/7J/ HHNN=)VM,,
:M<Q<QUc<cdUW 	
 ',-  ;;'!h'&9}-00J>@R@RV]@]^ 
 a167 #  ;;]]'"		!-HU 	 	
 r   c           	      d   | j                  |      }| j                  ||       | j                  j                  t              j                  t        j                  |k(  t        j                  |k(        j                         }|st        dt        d      d      |j                  dk(  rt        dt        d      d      |j                  }| j                  j                  |       | j                  j                          | j                  j!                  |j                  dd||d	|i|
       y )Nr   rd   rU   r`   zmember.cannot_remove_ownerr   zmember.remover]   r[   r   )rf   ra   rM   rA   r   rB   r?   r[   rD   r   r   rZ   rC   deleterF   rN   r   )rO   r?   r   r   r{   rH   r]   	member_ids           r   remove_memberzProjectService.remove_memberu  s    ##J/7J/ HHNN=)VM,,
:M<Q<QUc<cdUW 	
 ',-  ;;'!167  II	]]""!!~. 	 	
r   r   r   	date_fromdate_toc                    | j                   j                  t              }|r"|j                  t        j                  |k(        }|r"|j                  t        j
                  |k(        }|r"|j                  t        j                  |k(        }|r"|j                  t        j                  |k\        }|r"|j                  t        j                  |k        }|j                         }	|j                  t        j                  j                               j                  |dz
  |z        j                  |      j                         }
|
|	fS )Nrj   )rM   rA   r   rB   r?   r   r   ro   rm   rn   rp   rq   rr   rs   )rO   rg   rh   r?   r   r   r   r   rt   rv   rw   s              r   list_activitieszProjectService.list_activities  s     HHNN;'//:=>A++v56A--9:A//9<=A//7:;A	

;116689@@$(hAVW]]^fgkkme|r   )rj      r   )rj   r   NNNNN)__name__
__module____qualname__
OrmSessionrP   r   r   r	   r   r^   ra   r   rf   intr
   r   rx   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rK   rK   =   s   *: *$ *_ K HUbLc *_ K D s  " AC'*:=	tO$c)	*( !44 4 "	4
 SM4 
4l0 0 0c  c3h ( ! c3h 	
 SM 
H !	  SM	
 
2	
	
%0	
	m		
" !++ + 	+
  + SM+ 
+f !22 2 	2
  2 SM2 
2r !)
)
 )
  	)

 SM)
 
)
^ $( $"&#'!%  SM	
  3- C= # 
tK #%	&r   rK   )&loggingr    r   r   pathlibr   typingr   r   r   r	   r
   sqlalchemy.ormr   r   app.core.configr   	getLoggerr   r7   app.core.errorsr   app.i18n.loaderr   app.logging.activity_loggerr   app.logging.modelsr   app.models.catalogr   r   r   r   r   r"   r>   rI   rK   r   r   r   <module>r      s      '  3 3 0 $			8	$ $  6 * J J2c 2 Js Js J*
 
 
| |r   