
    bj>                        d dl mZ d dlZd dlZd dlZd dl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  G d d          ZdS )    )annotationsN)Path)Any   )	load_yaml)
HttpClient)NormalizedMovie)	NfoWriter)
StrmWriter)TmdbResolverc                      e Zd Zd4dZd5d6dZd7dZd8dZd9dZd:d Zd;d"Z	d<d(Z
d=d-Zed>d0            Zd?d2Zd@d3ZdS )ASlugRemapper
app_configdict[str, Any]httpr   c                   || _         |d         d         | _        || _        t          |                    di           |          | _        |                    di           }t          |d         d         |d         d         |                    dd	                    | _        t          |d         d         |                    dd	                    | _	        t          j        | j        j                  | _        d S )
Ndatabasepathtmdb	db_mountspaths	librariesplaylist_server
public_urlz/strm)r   db_pathr   r   getr   r   strm_writerr
   
nfo_writerlogging	getLogger	__class____name__log)selfr   r   r   s       moviebot/remap.py__init__zSlugRemapper.__init__   s    $!*-f5	 !;!;TBB	NN;33	%w,(),7MM+w//
 

 $Jw$7$DimmT_ahFiFijj$T^%<==    Nmovie_map_pathstrtvshow_map_path	only_slug
str | NonereturnNonec                   |                      |d          |                      |d          z   }t          j        | j                  5 }t          j        |_        |                    d           |                    d                                          }|D ]5}|r|d         |k    r|                     |d         |d         |          }|s8| 	                    |          }	| j
                            |	|           |                     ||	          }
|                     |t          |d                   |
t          |d                   |d         |d	         |           |                     ||
          }|                     ||
||d                    | j                            d
|d         |d         |d         |
|j                   7|                                 d d d            d S # 1 swxY w Y   d S )NmovietvzPRAGMA foreign_keys = ONa-  
                SELECT ms.id AS source_id, ms.source, ms.source_slug, ms.movie_id, ms.raw_json,
                       m.title, m.original_title, m.year, m.media_type, m.tmdb_id, m.imdb_id,
                       m.poster_url, m.backdrop_url, m.runtime, m.content, m.genres_json,
                       m.countries_json, m.actors_json, m.directors_json
                FROM movie_sources ms
                JOIN movies m ON m.id = ms.movie_id
                WHERE ms.movie_id IS NOT NULL
                ORDER BY ms.source, ms.source_slug
                source_slugsourcemovie_id	source_idraw_jsonzMRemapped slug source=%s slug=%s old_movie_id=%s target_movie_id=%s tmdb_id=%s)
_load_mapssqlite3connectr   Rowrow_factoryexecutefetchall_match_mapping_movie_from_rowr   apply_mapping_upsert_target_movie_move_source_to_targetint_movie_from_movie_id_rewrite_strm_filesr#   infotmdb_idcommit)r$   r(   r*   r+   mapsconnsourcesr3   mappingr0   	target_id	canonicals               r%   runzSlugRemapper.run!   sO   ~w77$///[_:`:``_T\** ,	d&{DLL3444ll	  hjj  "   !6)!C!C--fX.>}@UW[\\ ,,V44	''w777 55dEBB	++z*++{+,,8$:&   !55dIFF	((y)VHEUVVVc8$=):&%    KKMMMY,	 ,	 ,	 ,	 ,	 ,	 ,	 ,	 ,	 ,	 ,	 ,	 ,	 ,	 ,	 ,	 ,	 ,	s   FG//G36G3r   
media_typelist[dict[str, Any]]c                N   |r!t          |                                          sg S t          |          }|                    dt	          |t
                    r|ng           }g }|pg D ]<}t          |          }|                    d|           |                    |           =|S )NrI   rP   )	r   existsr   r   
isinstancelistdict
setdefaultappend)r$   r   rP   dataentriesresultentryitems           r%   r7   zSlugRemapper._load_mapsQ   s     	4::,,.. 	I((6:dD+A+A#I44rJJ] 	  	 E;;DOOL*555MM$r'   r3   slugrI   dict[str, Any] | Nonec                   |D ]U}t          |                    d          pd                                          }|r||                                k    rT|                    d          rAt          |d                                                   |                                k    r|c S |                    d          rt          j        t          |d                   |t          j                  }|r`t          |          }|                    d          }|r6|                    t          |                    }	|	rt          |	          |d<   |c S Wd S )Nr3    r^   slug_pattern)flagsseason_groupseason)	r)   r   lowerrematch
IGNORECASErV   grouprC   )
r$   r3   r^   rI   r\   entry_sourcerh   r]   rd   values
             r%   r>   zSlugRemapper._match_mapping]   sC    	  	 Euyy228b99??AAL  > >yy   Sv%7%7%=%=%?%?4::<<%O%Oyy(( 	 U>%:!;!;TWWW  ;;D#'88N#;#;L# 8 %C,=,= > >  8-0ZZDNKKKtr'   rowsqlite3.Rowr	   c           	     
   t          di d|d         d|d         d|d         p|d         d|d         pdd|d         pdd|d         pdd	|d	         pdd
|d
         pdd|d         pdd|d         pdd|d         pdd|d         pddt          j        |d         pd          dt          j        |d         pd          dt          j        |d         pd          dt          j        |d         pd          S )Nr3   r2   titleoriginal_titlera   yearrP   r0   rG   imdb_id
poster_urlbackdrop_urlruntimecontentgenresgenres_jsonz[]	countriescountries_jsonactorsactors_json	directorsdirectors_json )r	   jsonloads)r$   rm   s     r%   r?   zSlugRemapper._movie_from_rowp   s    
 
 
x==
M**
 g,4#m"4
 /06B	

 V"
 <(3G
 	N(b
 	N(b
 <(.B
 ^,2
 	N(b
 	N(b
 :c-08D999
 j%5!6!>$???
 :c-08D999
  j%5!6!>$???!
 	
r'   rJ   sqlite3.Connectionr4   rC   c                ~    |                     d|f                                          }|                     |          S )Nz
            SELECT ms.source, ms.source_slug, m.*
            FROM movies m
            LEFT JOIN movie_sources ms ON ms.movie_id = m.id
            WHERE m.id = ?
            ORDER BY ms.id
            LIMIT 1
            )r<   fetchoner?   )r$   rJ   r4   rm   s       r%   rD   z!SlugRemapper._movie_from_movie_id   sE    ll K

 

 (** 	 ##C(((r'   r0   c                   |                     d|j        |j        |j        |j        |j        |j        |j        |j        |j	        |j
        |j        t          j        |j        d          t          j        |j        d          t          j        |j        d          t          j        |j        d          f           |                     d|j        f                                          }t'          |d                   S )Na  
            INSERT INTO movies (
                merge_key, tmdb_id, media_type, title, original_title, year, imdb_id,
                poster_url, backdrop_url, runtime, content, genres_json, countries_json,
                actors_json, directors_json
            ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
            ON CONFLICT(merge_key) DO UPDATE SET
                tmdb_id=excluded.tmdb_id,
                media_type=excluded.media_type,
                title=excluded.title,
                original_title=excluded.original_title,
                year=excluded.year,
                imdb_id=COALESCE(NULLIF(excluded.imdb_id, ''), movies.imdb_id),
                poster_url=excluded.poster_url,
                backdrop_url=excluded.backdrop_url,
                runtime=excluded.runtime,
                content=excluded.content,
                genres_json=excluded.genres_json,
                countries_json=COALESCE(NULLIF(movies.countries_json, '[]'), excluded.countries_json),
                actors_json=COALESCE(NULLIF(movies.actors_json, '[]'), excluded.actors_json),
                directors_json=COALESCE(NULLIF(movies.directors_json, '[]'), excluded.directors_json),
                updated_at=CURRENT_TIMESTAMP
            F)ensure_asciiz)SELECT id FROM movies WHERE merge_key = ?id)r<   	merge_keyrG   rP   rp   rq   rr   rs   rt   ru   rv   rw   r   dumpsrx   rz   r|   r~   r   rC   )r$   rJ   r0   rm   s       r%   rA   z!SlugRemapper._upsert_target_movie   s    0  $
 "
5<e<<<
5????
5<e<<<
5????1)	
 )	
 )	
T llFHZ[[ddff3t9~~r'   old_movie_idtarget_movie_idr5   r6   rL   c           
        |                     d||f           |                     d||f                                          }i }	|D ]}
|                     d|||
d         f                                          }|rt          |d                   }ng|                     d|||
d         |
d         |
d         f           t          |                     d	                                          d
                   }||	t          |
d                   <   |                    d          }|                     |          }|r^d                    d |D                       }|                     d| d||gt          |          R                                           }ng }| j        	                    d||           |D ]V}|	                    t          |d         pd
                    }| 
                    |||||t          |          nd            W||k    re|                     d|f                                          d
         }|d
k    r2|                     d|f           |                     d|f           d S d S d S )NzRUPDATE movie_sources SET movie_id = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?z7SELECT * FROM servers WHERE movie_id = ? AND source = ?zESELECT id FROM servers WHERE movie_id = ? AND source = ? AND name = ?namer   z
                    INSERT INTO servers (movie_id, source, name, priority, raw_json)
                    VALUES (?, ?, ?, ?, ?)
                    priorityr6   zSELECT last_insert_rowid()r   re   ,c              3     K   | ]}d V  dS )?Nr   ).0_s     r%   	<genexpr>z6SlugRemapper._move_source_to_target.<locals>.<genexpr>   s"      #;#;AC#;#;#;#;#;#;r'   z
                SELECT *
                FROM episodes
                WHERE movie_id = ?
                  AND source = ?
                  AND origin_m3u8_url IN (z)
                z3No m3u8 URLs found for remap source=%s source_id=%s	server_idz5SELECT COUNT(*) FROM movie_sources WHERE movie_id = ?z&DELETE FROM servers WHERE movie_id = ?zDELETE FROM movies WHERE id = ?)r<   r=   r   rC   r   _source_m3u8_urlsjoinsortedr#   warning_move_episode_to_target)r$   rJ   r   r   r5   r3   r6   rL   server_rows
server_mapserverexistingtarget_server_idre   	m3u8_urlsplaceholdersepisode_rowsepisode	remainings                      r%   rB   z#SlugRemapper._move_source_to_target   s    	il{  ~G  lH  	I  	I  	Ill#\_kms^tuu~~  A  A%'
! 	= 	=F||W &&.9  hjj   
a#&x~#6#6   %ffVnfZ>PRXYcRde   $'t||4P'Q'Q'Z'Z'\'\]^'_#`#` ,<Js6$<(())X&&**844	 	g88#;#;#;#;#;;;L<<
 ,8   v:y(9(9::	 	 hjj L LHRTZ\efff# 	H 	HG)~~c'+2F2K!.L.LMM((wIYjpj|[^_e[f[f[f  CG  H  H  H  H?**%\_k^mnnwwyyz{|IA~~EWWW>PPPPP	 +*~r'   r   r   
int | Nonere   c                    ||nt          |d                   }|                    d|d         ||d         |d         |d         f                                          }|s"|                    d||||d         f           d S |                     |d         |d                   }|d	k    rd n|d
         p|d
         }	|d         r|d         dk    r|d         n|d         }
|                    d||d         p|d         |d         p|d         |t          |d         p|d                   |d         p|d         |d         p|d         |t          |d         pd          |	|
|d         f           |                    d|d         f           d S )Nre   z
            SELECT *
            FROM episodes
            WHERE id != ?
              AND movie_id = ?
              AND source = ?
              AND filename = ?
              AND origin_m3u8_url = ?
            LIMIT 1
            r   r3   filenameorigin_m3u8_urlz
                UPDATE episodes
                SET movie_id = ?, server_id = ?, season = ?, updated_at = CURRENT_TIMESTAMP
                WHERE id = ?
                crawl_statussuccess
last_errorr6   {}a  
            UPDATE episodes
            SET server_id = COALESCE(?, server_id),
                source_episode_id = ?,
                title = ?,
                season = ?,
                episode = ?,
                cleaned_m3u8_path = ?,
                strm_path = ?,
                crawl_status = ?,
                retry_count = MAX(retry_count, ?),
                last_error = ?,
                raw_json = ?,
                updated_at = CURRENT_TIMESTAMP
            WHERE id = ?
            source_episode_idrp   r   cleaned_m3u8_path	strm_pathretry_countr   z!DELETE FROM episodes WHERE id = ?)rC   r<   r   _merged_status)r$   rJ   r   r   r   re   final_seasonr   r   r   r6   s              r%   r   z$SlugRemapper._move_episode_to_target   s    "(!3vvWX=N9O9O<<	 !
#)*
 
$ (**% 	&  		LL
 !"2L'$-P   F**8N+CW^E\]])Y66TTXl=S=lW^_kWl
+3J+?yHZDX\`D`D`8J''fmnxfy" !,-M9L1M!5WW%5HY'=79+=>>,-M9L1M%=)=GM*/a00#	
 	
 	
@ 	874=:JKKKKKr'   leftrightc                B    | pd|pdh}d|v rdS d|v rdS d|v rdS | p|pdS )Nra   r   pendingfailedr   )r   r   statusess      r%   r   zSlugRemapper._merged_statusF  sT    JB,  9  9x8)u)	)r'   set[str]c                    	 t          j        |pd          }n## t           j        $ r t                      cY S w xY wt                      dfd |           S )Nr   rl   r   r-   r.   c                   t          | t                    r|                     d          }t          |t                    r<|                    d          r'                    |                                           |                                 D ]} |           d S t          | t                    r| D ]} |           d S d S )N	link_m3u8)zhttp://zhttps://)	rT   rV   r   r)   
startswithaddstripvaluesrU   )rl   linkchildurlswalks      r%   r   z,SlugRemapper._source_m3u8_urls.<locals>.walkY  s    %&&  yy--dC(( +T__=T-U-U +HHTZZ\\***"\\^^    EDKKKK   E4((  "    EDKKKK      r'   )rl   r   r-   r.   )r   r   JSONDecodeErrorset)r$   r6   rawr   r   s      @@r%   r   zSlugRemapper._source_m3u8_urlsQ  s    	*X-..CC# 	 	 	55LLL	 		  		  		  		  		  		  		  	S			s    ;;c                   |                     d||f                                          }d}|D ]}| j                            ||d         |d         |d         t	          |d                   t	          |d                             }|                     d|j        |d	         f           |j        d
k    r!| j                            ||j	                   d}|r| j                            |           d S d S )Na  
            SELECT id, filename, cleaned_m3u8_path, access_key, season, episode
            FROM episodes
            WHERE movie_id = ? AND source = ? AND crawl_status = 'success' AND cleaned_m3u8_path IS NOT NULL
            ORDER BY season, episode, filename
            Fr   r   
access_keyre   r   zNUPDATE episodes SET strm_path = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?r   r0   T)
r<   r=   r   writerC   r   rP   r   write_for_strm	file_path)	r$   rJ   r4   r0   r3   rowswrote_tv_nform   r[   s	            r%   rE   z SlugRemapper._rewrite_strm_filesg  s6   || v
 
 (** 	  	$ 	$C%++J'(L!CM""C	N## F LLilrlz|  AE  }F  lG  H  H  H7**..uf6FGGGG# 	)O!!%(((((	) 	)r'   )r   r   r   r   )N)r(   r)   r*   r)   r+   r,   r-   r.   )r   r)   rP   r)   r-   rQ   )r3   r)   r^   r)   rI   rQ   r-   r_   )rm   rn   r-   r	   )rJ   r   r4   rC   r-   r	   )rJ   r   r0   r	   r-   rC   )rJ   r   r   rC   r   rC   r5   rC   r3   r)   r6   r)   rL   r   r-   r.   )rJ   r   r   rn   r   rC   r   r   re   r   r-   r.   )r   r,   r   r,   r-   r)   )r6   r)   r-   r   )
rJ   r   r4   rC   r0   r	   r3   r)   r-   r.   )r"   
__module____qualname__r&   rO   r7   r>   r?   rD   rA   rB   r   staticmethodr   r   rE   r   r'   r%   r   r      s%       > > > >. . . . .`
 
 
 
   &
 
 
 
() ) ) ), , , ,\8Q 8Q 8Q 8QtJL JL JL JLX * * * \*   ,) ) ) ) ) )r'   r   )
__future__r   r   r   rg   r8   pathlibr   typingr   configr   r   r   modelsr	   r   r
   r   r   r   r   r   r   r'   r%   <module>r      s   " " " " " "   				                          # # # # # # ! ! ! ! ! ! # # # # # #      o) o) o) o) o) o) o) o) o) o)r'   