
    g                         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
 d d
lmZ d dlmZ d ZddZd ZddZddZddZddZ G d de      Zy)    N)common)database)
datatables)helpers)logger)plextv)
pmsconnect)session)users)Plexc                     t        j                  d       t        j                  j                  } | st        j
                  d       y t        j                         j                         }|rt        j                         }g }g }t        j                  g}|D ]  }|j                  t        j                  |d                | |d   d}| |d   |d   |d   |d   |d   |d	   |d
   |j!                  dd       |j!                  dd       |d   d}|j#                  d||      }	|j                  |d          |	dk(  s|j                  |d           t%        d       dj'                  dj)                  dgt+        |      z              }
|j-                  |
t        j                  j                  g|z          t        j                  j.                  |z   }t        j                  j1                  d|       t        j                  j3                          t        j                  d       yt        j4                  d       y)Nz:Tautulli Libraries :: Requesting libraries list refresh...z]Tautulli Libraries :: No PMS identifier, cannot refresh libraries. Verify server in settings.
section_id	server_idr   section_namesection_typeagentthumbartcountparent_countchild_count	is_active)r   r   r   r   r   r   r   r   r   r   r   library_sectionskey_dict
value_dictinsertT)refreshzXUPDATE library_sections SET is_active = 0 WHERE server_id != ? OR section_id NOT IN ({})z, ?queryargsHOME_LIBRARY_CARDSz/Tautulli Libraries :: Libraries list refreshed.z7Tautulli Libraries :: Unable to refresh libraries list.F)r   infoplexpyCONFIGPMS_IDENTIFIERerrorr	   
PmsConnectget_library_detailsr   MonitorDatabaser   LIVE_TV_SECTION_IDappendr   cast_to_intgetupsertadd_live_tv_libraryformatjoinlenactionr$   __setattr__writewarn)r   r   
monitor_dblibrary_keysnew_keyssection_idssectionsection_keyssection_valuesresultr"   s              !/opt/Tautulli/plexpy/libraries.pyrefresh_librariesrC   "   s   
KKLM,,Itu!,,.BBD--/
 001' 	7Gw227<3HIJ)2*1,*?AL+4,3L,A.5n.E.5n.E'.w'7'.w'7%,U^'.w'7.5kk.$.O-4[[-M+2;+? N  &&'9L]k&lF 56! 56/	72 	D)))/		3%#kBR:R0S)T 	V]]-I-I,J[,XY==33h>!!"6AEFMN    c                    t        j                         }|j                  dt        j                  t
        j                  j                  g      }|r| r|s| ry | st        j                  d       t
        j                  j                  t        j                  d}t
        j                  j                  t        j                  t        j                  dt        j                  t        j                  dd}|j                  d||      }y )	NzESELECT * FROM library_sections WHERE section_id = ? and server_id = ?z=Tautulli Libraries :: Adding Live TV library to the database.r   live   )r   r   r   r   r   r   r   r   r   )r   r,   select_singler   r-   r&   r'   r(   r   r%   LIVE_TV_SECTION_NAMEDEFAULT_LIVE_TV_THUMBDEFAULT_LIVE_TV_ART_FULLr1   )r   r:   rA   r?   r@   s        rB   r2   r2   _   s    ))+J%% 'O'-'@'@&--B^B^&_aF gVST!'!=!="(";";=L#)==#?#?$*$=$=&,&A&A&,%;;#<<#$N 1LUcdFrD   c                 p    t        j                         }d}| g}|j                  ||      }t        |      S )NzMSELECT * FROM library_sections WHERE section_type = ? AND deleted_section = 0r!   )r   r,   rH   bool)r   r:   r"   r#   rA   s        rB   has_library_typerN   y   s;    ))+J[E>D%%E%=F<rD   c                    t        t        j                               }|j                  |       }|j                  dvrg S |j                         }g }|D ]i  }d|_        |j                  }|d}|j                  }|d}i dt        j                  |j                        d|j                  d|j                  d	|d
|j                  d|d|j                  d|j                   d|j"                  d|j$                  d|j&                  d|j(                  d|j*                  d|j,                  d|j.                  d|j0                  d|j2                  |j4                  |j6                  xs |j4                  |j                  t        j                  |j8                        d}|j;                  |       l |S )Ntoken)movieshowartistFr   addedAtr   
childCountcollectionModecollectionPublishedcollectionSortcontentRatingguidlibrarySectionIDlibrarySectionTitlemaxYearminYear	ratingKeysmartsubtypesummaryr   )title	titleSorttype	updatedAt)r   r
   get_session_user_tokenget_libraryrg   collections_autoReloadrX   rZ   r   datetime_to_isorV   r   rW   rY   r[   r\   r]   r^   r_   r`   ra   rb   rc   rd   r   re   rf   rh   r.   )	r   plexlibraryrk   collections_list
collectioncollection_modecollection_sortcollection_dicts	            rB   get_collectionsru      s   g4467Dz*G||66	%%'K! "1
!&
$33" O$33"O
w..z/A/AB
:>>
 *//
 o	

 ":#A#A
 o
 Z55
 JOO
 
 ; ;
 ":#A#A
 z))
 z))
 --
 Z%%
 z))
  z))!
" Z%%#
$  %%#--A1A1AOO 001E1EF+
. 	0E"1H rD   c                     | s	dddg d}|S t        |       }t        j                  |d         }dg}ddd	d
dddddd}t        j                  ||d||      }|d   |d   |d   t	        |d         d}|S )Nr   recordsFilteredrecordsTotaldrawdatar   	json_datajson_kwargsre   zLibrary DefaultzHide collectionzHide items in this collectionz"Show this collection and its items)rU   r   rG      zRelease dateAlphabeticalCustom)r   rG   r   )rX   rZ   rf   )default_sortsearch_cols	sort_keysfiltered_counttotal_countresultsrz   rx   ry   r{   rz   )ru   r   process_json_kwargsprocess_datatable_rowsint)	r   kwargsdefault_returnrk   r}   r   r   r   r{   s	            rB   get_collections_listr      s    -.*+"#"$& !Z8K ++{8KLI)K " .3	
 
I ,,Y[96G
 ##34.	"If%&	D KrD   c                    |r>t        j                         s*t        j                         j	                  |      }|d   }nt        j
                         }|sg S t        |      }|r|j                  j                         }n!|j                  |       }|j                         }g }|D ]  }d|_
        t        j                  |j                        |j                  |j                  |j                   |j"                  | |j$                  |j&                  |j(                  |j*                  |j,                  |j.                  t        j                  |j0                        |d}	|j3                  |	        |S )N)user_idserver_tokenrP   F)rV   	compositedurationr\   	leafCountr]   playlistTypera   rb   rd   re   rg   rh   userID)r
   get_session_user_idr   Users
get_tokensri   r   
PlexServer	playlistsrj   rl   r   rm   rV   r   r   r\   r   r   ra   rb   rd   re   rg   rh   r.   )
r   r   user_tokens
plex_tokenrn   r   ro   playlists_listplaylistplaylist_dicts
             rB   get_playlistsr      sC   w224kkm..w.? 0
335
	j!DOO--/	"":.%%'	N -$ ..x/?/?@!++ ))MM!++ *$11!++^^''^^MM 001C1CD
  	m,'-* rD   c                     | s|s	dddg d}|S t        | |      }t        j                  |d         }t        j                  ||d      }|d   |d	   |d
   t	        |d         d}|S )Nr   rw   )r   r   r}   r~   re   )r   r   r   r   rz   r   )r   r   r   r   r   )r   r   r   r   r   r}   r   r{   s           rB   get_playlists_listr     s    g-.*+"#"$& WEI ++{8KLI,,974G ##34.	"If%&	D KrD   c                       e Zd Zd ZddZddZddZddZddZ	 	 ddZ	dd	Z
dd
ZddZddZddZd ZddZddZddZd Zy)	Librariesc                      y N )selfs    rB   __init__zLibraries.__init__$  s    rD   Nc                    dddg d}t        j                         }ddgg}|t        j                  j                  }t        j                         r%|j                  dt        j                         g       |rdnd}g dddd	d
dddddddd|z  dddddddddddddd d!d"d#d$d%d&d'd(d)}	 |j                  d*||ddgg d+g d,d-dgdd.gdd/gg|0      }|d2   }
g }|
D ]6  }|d3   d4k(  r|d5   r|d5   }n|d3   d4k(  r|d6   }n|d7   }|d8   r|d8   |d9   k7  r|d8   }n|d9   r|d9   }nt        j                  }|d:   r|d:   |d;   k7  r|d:   }n|d;   }i d<|d<   d=|d=   d>|d>   d?|d?   d@|d@   dA|dA   dB|dB   dC|dC   d9|d;|dD|dD   dE|dE   dF|dF   dG|dG   dH|dH   dI|dI   d3|d3   ||dJ   |dK   |dL   |dM   |dN   |dO   r|dO   j                  dP      ndQ|dR   |dS   |dT   |dU   |dV   |dW   |dX   dY}|j                  |       9 |dZ   |d[   t        j                  |      |d\   d]}|S # t        $ r$}	t        j                  d1|	z         |cY d }	~	S d }	~	ww xY w)^Nr   rw   z library_sections.deleted_sectionzlibrary_sections.section_idsession_history.reference_idsession_history.idzlibrary_sections.id AS row_idzlibrary_sections.server_idzlibrary_sections.section_namezlibrary_sections.section_typezlibrary_sections.countzlibrary_sections.parent_countzlibrary_sections.child_countz'library_sections.thumb AS library_thumbz1library_sections.custom_thumb_url AS custom_thumbz#library_sections.art AS library_artz-library_sections.custom_art_url AS custom_artzCOUNT(DISTINCT %s) AS playsa	  SUM(CASE WHEN session_history.stopped > 0 THEN (session_history.stopped - session_history.started)                     ELSE 0 END) - SUM(CASE WHEN session_history.paused_counter IS NULL THEN 0 ELSE                     session_history.paused_counter END) AS durationz-MAX(session_history.started) AS last_accessedz)MAX(session_history.id) AS history_row_idz2session_history_metadata.full_title AS last_playedzsession_history.rating_keyz#session_history_metadata.media_typezsession_history_metadata.thumbz%session_history_metadata.parent_thumbz*session_history_metadata.grandparent_thumbz%session_history_metadata.parent_titlezsession_history_metadata.yearz$session_history_metadata.media_indexz+session_history_metadata.parent_media_indexz'session_history_metadata.content_ratingzsession_history_metadata.labelszsession_history_metadata.livez!session_history_metadata.added_atz0session_history_metadata.originally_available_atzsession_history_metadata.guidzlibrary_sections.do_notifyz"library_sections.do_notify_createdzlibrary_sections.keep_historyzlibrary_sections.is_activer   )LEFT OUTER JOINr   r   )session_historysession_history_metadatasession_history_media_infozsession_history.section_idzsession_history_metadata.idzsession_history_media_info.id)
table_namecolumnscustom_wheregroup_by
join_typesjoin_tables
join_evalsr   zHTautulli Libraries :: Unable to execute database query for get_list: %s.rA   
media_typeepisodeparent_thumbgrandparent_thumbr   custom_thumblibrary_thumb
custom_artlibrary_artrow_idr   r   r   r   r   r   r   playsr   last_accessedhistory_row_idlast_played
rating_keyparent_titleyearmedia_indexparent_media_indexcontent_ratinglabels;r   rF   originally_available_atr\   	do_notifydo_notify_createdkeep_historyr   )r   r   r   r   r   r   r   rF   r   r\   r   r   r   r   filteredCount
totalCountrz   r   )r   
DataTablesr&   r'   GROUP_HISTORY_TABLESr
   get_session_shared_librariesr.   	ssp_query	Exceptionr   r9   r   DEFAULT_COVER_THUMBsplitmask_session_info)r   r   groupingr   data_tablesr   r   r   r"   erA   rowsitemr   r   r   rowdicts                     rB   get_datatables_listzLibraries.get_datatables_list'  s6   -.*+"#"$&
 !++-;Q?@}}99H//1!>@d@d@f gh5=1CW&2 &/&0& 3& 3	&
 ,& 3& 2& =& G& 9& C& 18;&E&  C!&" ?#&$ H%&& 0'&( 9)&* 4+&, ;-&. @/&0 ;1&2 33&4 :5&6 A7&8 =9&: 5;&< 3=&> 7?&@ FA&B 3C&D 0E&F 8G&H 3I&J 0K&N	"))5G297C4PRo3p6I7U 8TUr6s7KMj6k7KMl6m6o 28 * 9E$ x 5	DL!Y.43G^,l#y001WN#^(<_@U(U $^ 4o& $_ 5 & : :L!d<&8D<O&O"<0"=18T(^ [ 1l!3 "4#7 "4#7	
 DM "4#7 !$}"5 #M !+ DM tJ/ #D$9 $T*:%; !$}"5  l!3   l!3!" "#'#7<"&}"5)-.B)C%)*:%;:>x.T(^11#6b<.23L.M< $[ 1(,-@(A#'#7 $[ 1=CB KKk5	n $)#9 %l 311$7f I  	"KKbeffg!!	"s   
(I 	J#J<JJc           	      f  * dddg ddd d}t        j                  |      s|S |r0t        |      j                         st	        j
                  d       |S |r0t        |      j                         st	        j
                  d       |S |s|st	        j
                  d       |S | j                  |      }|d   d k(  rt	        j                  d|z         |S |s|d	   }t        j                         }t        j                  j                  rd
}	nd}	|dk(  s|dk(  rd}
n|dk(  s|dk(  rd}
nd}
d|	d|
d}|j                  ||g      }i }|D ]  }|d   |d   d|t        ||
         <    | j                  ||      \  }}}|s|D ci c]  }|d   |d    c}ni }|s|st!        j"                         }|r|j%                  |||d      }n|r|j%                  ||d      }r|d    }|d!   }nt	        j
                  d"       |S g }|D ]  }|j'                  |d   d       }|r|n|j'                  dd#      }i d|d   d	|d	   d$|d$   d%|d%   d|d   d|d   d|d   d&|d&   d'|d'   xs |d&   d(|d(   d)|d)   d*|d*   d+|d+   d,|j'                  d,d#      d-|j'                  d-d#      d.|j'                  d.d#      d/|j'                  d/d#      |j'                  d0d#      |j'                  d1d#      |j'                  d2d#      |d3}|j)                  |        |}|s|S | j+                  |||4       |D ]4  }|j'                  |d   d       }|r|d   |d<   |d   |d<   +d |d<   d |d<   6 g }|j'                  d5      r%t-        j.                  |j'                  d5      6      }d7   d8   j1                         }|rj|d9   D cg c]  }|d:   s	|d;    c}d&gz   } |D ]D  }|j3                         D ]/  \  }!}"|!| v s||"j1                         v s|j)                  |        D F n|}t5        |      }#t7        |d< =      }|d>   }$t9        |$      D ]z  }%|d9   t;        |%d?            d;   *|%d@   dAk(  rdndB}&|r*d'k(  rt7        |dC |&D      }=*dEv rt7        |*fdF|&D      }S*d/k(  rt7        |*fdG|&D      }jt7        |*fdH|&D      }| t=        |D cg c]  }t-        j>                  |d          c}      }'||dI   |dI   |dJ   z    }t=        |D cg c]  }t-        j>                  |d          c}      }(|#t;        |      |t;        |dK         |(|'|dL})|)S # t        $ r$}t	        j
                  d|z         |cY d }~S d }~ww xY wc c}w c c}w c c}w c c}w )MNr   )rx   ry   rz   r{   filtered_file_sizetotal_file_sizelast_refreshedzRTautulli Libraries :: Datatable media info called but invalid section_id provided.zRTautulli Libraries :: Datatable media info called but invalid rating_key provided.zHTautulli Libraries :: Datatable media info called but no input provided.r|   r   6Tautulli Libraries :: Library section_id %s not found.r   reference_ididrS   rT   grandparent_rating_keyseasonalbumparent_rating_keyr   z3SELECT MAX(started) AS last_played, COUNT(DISTINCT zz) AS play_count, rating_key, parent_rating_key, grandparent_rating_key FROM session_history WHERE section_id = ? GROUP BY  r#   zZTautulli Libraries :: Unable to execute database query for get_datatables_media_info2: %s.r   
play_count)r   r   r   r   	file_sizeT)r   r   r   get_media_info)r   r   r   library_countchildren_listz<Tautulli Libraries :: Unable to get a list of library items. added_atr   re   
sort_titler   r   r   r   	containerbitratevideo_codecvideo_resolutionvideo_framerateaudio_codecaudio_channels)r   r   r  r   r   r   r   r}   r~   searchvaluer   
searchabler{   c                 (    | d   j                         S )Nr   lowerks    rB   <lambda>z5Libraries.get_datatables_media_info.<locals>.<lambda>R  s    ,0E0E0G rD   )keyordercolumndirdescFc                 2    t        j                  | d         S )Nr   r   r/   r	  s    rB   r  z5Libraries.get_datatables_media_info.<locals>.<lambda>X  s    8K8KAmL\8] rD   )r  reverse)r   r   r   r   r   c                 4    t        j                  |          S r   r  r
  sort_keys    rB   r  z5Libraries.get_datatables_media_info.<locals>.<lambda>Z  s    8K8KAhK8X rD   c                 r    t        j                  |    j                  dd      j                  d            S )N4k2160pp)r   r/   replacerstripr  s    rB   r  z5Libraries.get_datatables_media_info.<locals>.<lambda>\  s1    8K8KAhKL_L_`dfmLnLuLuvyLz8{ rD   c                 *    |    j                         S r   r  r  s    rB   r  z5Libraries.get_datatables_media_info.<locals>.<lambda>^  s    (8I8I8K rD   startlengthrz   )rx   ry   r{   rz   r   r   r   ) r
   allow_session_librarystrisdigitr   r9   get_detailsdebugr   r,   r&   r'   r   selectr   _load_media_info_cacher	   r*   get_library_children_detailsr0   r.   _save_media_info_cacher   r   r  itemsr5   sortedreversedr   sumr/   )+r   r   r   r   r   r   r   library_detailsr:   count_byr   r"   rA   r   watched_listr   
cache_timer   r   dcached_itemspms_connectlibrary_childrenr   new_rowscached_file_sizer   r   watched_itemr   r}   search_valuesearchable_columnsr
  vr   
sort_orderr  r  r   r   outputr  s+                                             @rB   get_datatables_media_infoz#Libraries.get_datatables_media_info  s6   -.*+"#"$01-.,02 ,,Z8!!c*o557KKlm!!J 7 7 9KKlm!!JKKbc!! **j*A<(D0LLQT^^_!!*>:L --/
==--%HH6!\X%=/HX%)@*H#H		"
 '/	:E
  &&uJ<&@F
  	SD@D]@S?CL?Q1SLT(^,-	S
 +/*E*EQ[hr*E*s'
D- OVFA,;7F[]$$//1K#.#K#KWaWaYe[_ $L $a  #.#K#KWaYe[_ $L $a    0 A 0 AZ[%%H% % $0#3#3D4F#M 0@,dhh{\^F_	|_\%B %~'F!4
#3 $T,%7 $T,%7	
 +D1D,E 06N1O W $T,%7%H4= tF| %d=&9 ,T2F-G W #DHH["$= !$((9b"9 %dhh}b&A  *4884F+K!" +/((3Db*I&*hh}b&A)-2BB)G$-), $9%< D%% '':*[_'`  	*D'++D,>EL&2=&A]#%1,%?\"&*]#%)\"	*  ::k"33

;@WXI !*7399;5>y5I!]Q|_!F)!]ah`i!i 99; CAa..<17793Ls+ GW &GHw'
j) 
	^E +Ch,@A&IH#Elf4d%Gh,6 .]gno^^ .Xbij// .{  FM  N .KU\]
	^ GTqw221[>BTU )G,i.@9XCV.VX w!W!'"5"5an"E!WX  ..	&)*"4.(
 O  	"KKtwxxy!!	" G^ "^4 U
 "Xs<   ,U/ 	V
V$V$(V)(V./	V8VVVc           	      *   t        j                  |      sy|r/t        |      j                         st	        j
                  d       y|r/t        |      j                         st	        j
                  d       y| j                  |      }|d   d k(  rt	        j                  d|z         y|d   dk(  ry| j                  ||	      \  }}}|rt	        j                  d
|z         n|rt	        j                  d|z         t        j                         }|D ]  }|d   s	|d   rd}|j                  |d   d|d   |      }	|	D ]|  }
i x}}d|
v rJt        |
d         dkD  r9|
d   d   }d|v r-t        |d         dkD  rt        d |d   D        |d   d         }|t        j                  |j!                  dd            z  }~ ||d<    | j#                  |||       |rt	        j                  d|z         y|rt	        j                  d|z         y)NFz\Tautulli Libraries :: Datatable media info file size called but invalid section_id provided.z\Tautulli Libraries :: Datatable media info file size called but invalid rating_key provided.r|   r   r   r   photor   z;Tautulli Libraries :: Getting file sizes for rating_key %s.z;Tautulli Libraries :: Fetting file sizes for section_id %s.r   r   r   Tr   )r   get_childrenr   r   
media_infopartsc              3   ,   K   | ]  }|d    s	|  yw)selectedNr   ).0r  s     rB   	<genexpr>z6Libraries.get_media_info_file_sizes.<locals>.<genexpr>  s     3d!VWXbVcA3ds   
r  z;Tautulli Libraries :: File sizes updated for rating_key %s.z;Tautulli Libraries :: File sizes updated for section_id %s.)r
   r   r!  r"  r   r9   r#  r$  r&  r	   r*   get_metadata_children_detailsr5   nextr   r/   r0   r(  )r   r   r   r-  _r   r3  r   r   metadatachild_metadatarA  media_part_infos                rB   get_media_info_file_sizesz#Libraries.get_media_info_file_sizess  sO   ,,Z8c*o557KKvwJ 7 7 9KKvw **j*A<(D0LLQT^^_>*g5 00JS]0^
4 LLVYccdLLVYccd ++- 	.DL!${*;	&DDPTUaPbRVPTUaPbPZ E \
 '/ 	ZN355J#~5#n\>Z:[^_:_%3L%A!%D
"j0S*W:M5NQR5R.23dz'?R3d3=g3Fq3I/KO !4!4_5H5HVW5X!YYI	Z %.[!)	.. 	##zjW[#\LLVYccd  LLVYccdrD   c                    d }g }d}|r	 t         j                  j                  t        j                  j
                  d|d|d      }t        |d      5 }t        j                  |      }t        |t              r|d   }|d   }n|}t        |      }d d d        t        j                  d|d	|d
       n|r	 t         j                  j                  t        j                  j
                  d|z        }t        |d      5 }t        j                  |      }t        |t              r|d   }|d   }n|}t        |      }d d d        t        j                  d|d	|d
       |||fS # 1 sw Y   xY w# t        $ r"}	t        j                  d|z         Y d }	~	7d }	~	ww xY w# 1 sw Y   dxY w# t        $ r"}	t        j                  d|z         Y d }	~	qd }	~	ww xY w)Nr   media_info_-.jsonrr   r   zBTautulli Libraries :: Loaded media info from cache for rating_key z (z items).z<Tautulli Libraries :: No media info cache for rating_key %s.media_info_%s.jsonzBTautulli Libraries :: Loaded media info from cache for section_id z<Tautulli Libraries :: No media info cache for section_id %s.)ospathr4   r&   r'   	CACHE_DIRopenjsonload
isinstancer   r5   r   r$  IOError)
r   r   r   r0  r   r   
inFilePathinFiler{   r   s
             rB   r&  z Libraries._load_media_info_cache  s   
 jWW\\&--*A*A]gisBtu
*c* .f99V,D!$-%)*:%;
#F|#$'IM. s}  @M  N  O jWW\\&--*A*ABVYcBcd
*c* .f99V,D!$-%)*:%;
#F|#$'IM. s}  @M  N  O 4..7. .  j[^hhiij. .  j[^hhiijsa   AE5 >E)$E5 ;AF/ >F# $F/ )E2.E5 5	F >FF #F,(F/ /	G8GGc                 8   t        j                         }|g }|r	 t        j                  j	                  t
        j                  j                  d|d|d      }t        |d      5 }t        j                  ||d|       d d d        t        j                  d|z         y |r	 t        j                  j	                  t
        j                  j                  d|z        }t        |d      5 }t        j                  ||d|       d d d        t        j                  d	|z         y y # 1 sw Y   xY w# t        $ r"}t        j                  d|z         Y d }~y d }~ww xY w# 1 sw Y   ]xY w# t        $ r"}t        j                  d
|z         Y d }~y d }~ww xY w)NrO  rP  rQ  w)r   r   z?Tautulli Libraries :: Saved media info cache for rating_key %s.zDTautulli Libraries :: Unable to create cache file for rating_key %s.rS  z?Tautulli Libraries :: Saved media info cache for section_id %s.zDTautulli Libraries :: Unable to create cache file for section_id %s.)r   	timestamprT  rU  r4   r&   r'   rV  rW  rX  dumpr   r$  r[  )r   r   r   r   r0  outFilePathoutFiler   s           rB   r(  z Libraries._save_media_info_cache  se   &&(
<Dr ggll6==+B+B^hjtCuv+s+ UwIITJGTU^akkl r ggll6==+B+BCWZdCde+s+ UwIITJGTU^akkl U U  rcfppqqrU U  rcfppqqrsa   AD4 'D( D4 %AE. ,E" E. (D1-D4 4	E=EE"E+'E. .	F7FFc                     |r5t        j                         }d|i}|||||d}		 |j                  d|	|       y y # t        $ r"}
t	        j
                  d|
z         Y d }
~
y d }
~
ww xY w)Nr   )custom_thumb_urlcustom_art_urlr   r   r   r   zJTautulli Libraries :: Unable to execute database query for set_config: %s.)r   r,   r1   r   r   r9   )r   r   r   r   r   r   r   r:   r   r   r   s              rB   
set_configzLibraries.set_config  s{    !113J$j1H.:,6'0/@*6	8J
n!!"4j(K   nhkllmmns   9 	A$AA$c                    i ddddddddddd	t         j                  d
ddddddddddddddddddd }|s|S |t        j                  j                  }| j                  |||      }|r|S t        j                  d|z         t                | j                  |||      }|r|S t        j                  d|z         |S )Nr   r   r   r   r   r   Localr   r   r   r   r   r   r   rG   r   r   r   deleted_sectionr   )r   r   include_last_accessedzcTautulli Libraries :: Unable to retrieve library %s from database. Requesting library list refresh.zYTautulli Users :: Unable to retrieve library %s from database. Returning 'Local' library.)	r   r   r&   r'   r(   r+   r   r9   rC   )r   r   r   rk  r   r-  s         rB   r#  zLibraries.get_details  s|   (A %r& )' )"	
 *6+E+E ( "1 )! ( &q &q .q )! ,Q *4$ !!44I22jT]I^ 3 ` "" KK}$% & "66*XaMb 7 dO && w() * &%rD   c                    |t         j                  j                  }d}d}|rd}d}t        j                         }	 t        |      j                         rd}|g}nt        d      d|d|d	|d
}	|j                  |	||gz         }
i }|
r|
D ]  }|d   r|d   |d   k7  r|d   }n|d   r|d   }nt        j                  }|d   r|d   |d   k7  r|d   }n|d   }i d|d   d|d   d|d   d|d   d|d   d|d|d|d   d|d   d|d   d|d   d|d   d|d   d|d   d|d   d|d   } |S # t        $ r$}t        j                  d|z         g }
Y d }~d }~ww xY w)NNULLr   zMAX(session_history.started)z\LEFT OUTER JOIN session_history ON library_sections.section_id = session_history.section_id zlibrary_sections.section_id = ?zMissing section_idab  SELECT library_sections.id AS row_id, server_id, library_sections.section_id, section_name, section_type, count, parent_count, child_count, library_sections.thumb AS library_thumb, custom_thumb_url AS custom_thumb, library_sections.art AS library_art, custom_art_url AS custom_art, is_active, do_notify, do_notify_created, keep_history, deleted_section, z( AS last_accessed FROM library_sections z WHERE z AND server_id = ? r   zSTautulli Libraries :: Unable to execute database query for get_library_details: %s.r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rj  r   )r&   r'   r(   r   r,   r!  r"  r   r%  r   r9   r   r   )r   r   r   rk  r   r4   r:   wherer#   r"   rA   r   r-  r   r   r   s                   rB   r+   zLibraries.get_library_details0  s]   44I :MqD--/
	:&&(9"| 455  6CD%QE  &&u49+3E&FF
  %'D,@DDY,Y$($8M/*$($9M$*$>$>M%$|*<]@S*S"&|"4K"&}"5K#%8T(^ #%#.[0A#%#/l1C#% $243G#% $243G	#%
 $3M#% $1+#% $+DM#% $243G#% $1$}2E#% $/[0A#% $/[0A#% $7=P8Q#% $243G#% $5d;L6M#% $3D4I#%%< I  	KKmpqqrF	s   AD> >	E+E&&E+c                    t        j                  |      sg S |t        j                  j                  }|r5|3t        t        j                  t        |      j                  d            }ng d}t        j                         }t        j                         }g }|rdnd}|D ]  }||dz  dz  dz  z
  }		 |dkD  r:t        |      j                         rd|d	|	d
}
|j                  |
|g      }n8g }n5t        |      j                         rd|z  }
|j                  |
|g      }ng }|D ]-  }|d   r|d   }|d   }nd}d}|||d}|j%                  |       /  |S # t        $ r$}t!        j"                  d|z         g }Y d }~^d }~ww xY w)N,)rG         r   r   r      <   r   zSELECT (SUM(stopped - started) - SUM(CASE WHEN paused_counter IS NULL THEN 0 ELSE paused_counter END)) AS total_time, COUNT(DISTINCT z) AS total_plays FROM session_history JOIN session_history_metadata ON session_history_metadata.id = session_history.id WHERE stopped >= z AND section_id = ?r   a  SELECT (SUM(stopped - started) - SUM(CASE WHEN paused_counter IS NULL THEN 0 ELSE paused_counter END)) AS total_time, COUNT(DISTINCT %s) AS total_plays FROM session_history JOIN session_history_metadata ON session_history_metadata.id = session_history.id WHERE section_id = ?zTTautulli Libraries :: Unable to execute database query for get_watch_time_stats: %s.
total_timetotal_plays)
query_daysru  rv  )r
   r   r&   r'   r   mapr   r/   r!  r   r`  r   r,   r"  r%  r   r   r9   r.   )r   r   r   rw  r`  r:   library_watch_time_statsr   daystimestamp_queryr"   rA   r   r   ru  rv  r   s                    rB   get_watch_time_statszLibraries.get_watch_time_statss  s   ,,Z8I}}99H*0W00#j/2G2G2LMJ&J%%'	--/
#% 5=1CW ,	5D'$)b.2*==O!8:..0 9A/!S ",!2!25
|!2!L!#:..0!7
 :B!B ",!2!25
|!2!L!#
  5%!%l!3J"&}"5K!"J"#K%)%/&1
 )//45?,	5\ (''  ruvvws   3A4E	F
&FF
c                 \   t        j                  |      sg S |t        j                  j                  }t        j                         }g }|rdnd}	 t        |      j                         rd|z  }|j                  ||g      }ng }|D ]\  }	|	d   r|	d   |	d   k7  r|	d   }
n|	d   r|	d   }
nt        j                  }
|	d   |	d	   |
|	d
   |	d   |	d   d}|j                  |       ^ t        j                   |d      S # t        $ r$}t        j                  d|z         g }Y d }~d }~ww xY w)Nr   r   am  SELECT (CASE WHEN users.friendly_name IS NULL OR TRIM(users.friendly_name) = '' THEN users.username ELSE users.friendly_name END) AS friendly_name, users.user_id, users.username, users.thumb, users.custom_avatar_url AS custom_thumb, COUNT(DISTINCT %s) AS total_plays, (SUM(stopped - started) - SUM(CASE WHEN paused_counter IS NULL THEN 0 ELSE paused_counter END)) AS total_time FROM session_history JOIN session_history_metadata ON session_history_metadata.id = session_history.id JOIN users ON users.user_id = session_history.user_id WHERE section_id = ? GROUP BY users.user_id ORDER BY total_plays DESC, total_time DESCr   zNTautulli Libraries :: Unable to execute database query for get_user_stats: %s.r   r   friendly_namer   usernamerv  ru  )r~  r   
user_thumbr  rv  ru  F)mask_metadata)r
   r   r&   r'   r   r   r,   r!  r"  r%  r   r   r9   r   DEFAULT_USER_THUMBr.   r   )r   r   r   r:   
user_statsr   r"   rA   r   r   r  r   s               rB   get_user_statszLibraries.get_user_stats  s^   ,,Z8I}}99H--/

5=1CW	:&&(
E HP
P $**5
|*D
  	#DN#^(<W(M!.1
g!']
#66
$($9"9o!+#J/"&}"5!%l!3C c"	#" ((5II+  	KKhkllmF	s   5C> >	D+D&&D+c                    t        j                  |      sg S t        j                         }g }|j	                         sd}	 t        |      j	                         rd}|j                  |||g      }ng }|D ]  }|d   dk(  r|d   r|d   }	n|d   dk(  r|d   }	n|d	   }	i d
|d   d|d   d|d   d|d   d|d   d|d   d|d   d|d   d|d   d	|	d|d   d|d   d|d   d|d   d|d   d|d   d|d   |d   |d   |d   |d   r|d   j                  d      nd d!}
|j                  |
        t        j                  |      S # t        $ r%}t        j                  d|z         g }Y d }~
d }~ww xY w)"N10aH  SELECT session_history.id, session_history.media_type, guid, session_history.rating_key, session_history.parent_rating_key, session_history.grandparent_rating_key, title, parent_title, grandparent_title, original_title, thumb, parent_thumb, grandparent_thumb, media_index, parent_media_index, year, originally_available_at, added_at, live, started, user, content_rating, labels, section_id FROM session_history_metadata JOIN session_history ON session_history_metadata.id = session_history.id WHERE section_id = ? GROUP BY session_history.rating_key ORDER BY MAX(started) DESC LIMIT ?r   zTTautulli Libraries :: Unable to execute database query for get_recently_watched: %s.r   r   r   r   r   r   r   r   r   r   re   r   grandparent_titleoriginal_titler   r   r   r   rF   r\   timestarteduserr   r   r   r   r   )r  r   r   r   )r
   r   r   r,   r"  r!  r%  r   r   r9   r   r.   r   )r   r   limitr:   recently_watchedr"   rA   r   r   r   recent_outputs              rB   get_recently_watchedzLibraries.get_recently_watched  sj   ,,Z8I--/
}}E	:&&(	= $**5
E7J*K
  	7C|$	1c.6I/E&)3 34ELE!#3t9 !#!-s</@!#!-s</@!# "5c:M6N!# ":3?W;X	!#
 ")#g,!# "0^1D!# "5c:M6N!# "237G3H!# ")%!# "/M0B!# "6s;O7P!# "(V!# ";C@Y<Z!# "(V!# "(V!#  "(Y!!#" *-V/2</@367G3HGJ8}3x=+>+>s+CZ\)!#, !''6=	7@ (()9::I  	KKnqrrsF	s   3E 	FE>>Fc                    t        j                         }	 d}|j                  |      }g }|D ]&  }|d   |d   |d   |d   d}|j                  |       ( |S # t        $ r"}t	        j
                  d|z         Y d }~y d }~ww xY w)	NzdSELECT section_id, section_name, section_type, agent FROM library_sections WHERE deleted_section = 0)r"   zLTautulli Libraries :: Unable to execute database query for get_sections: %s.r   r   r   r   )r   r   r   r   )r   r,   r%  r   r   r9   r.   )r   r:   r"   rA   r   	librariesr   ro   s           rB   get_sectionszLibraries.get_sections*  s    --/
	FE&&U&3F
 	 	&D%),%7'+N';'+N'; $WG
 W%	&   	KKfijjk	s   A 	B"A??Bc           
         t        j                         }|r|t        t        t        j
                  |j                  d                  }|j                  dj                  dj                  dgt        |      z              |      }g }|D ]+  }|j                  | j                  |d   |d   |             - t        |      S t        |      j                         r|xs t         j"                  j$                  }|t         j"                  j$                  k(  rt        j&                  |      }	n9t)        j*                  d|d	|d
t         j"                  j$                  d       d}	|r|	S t)        j,                  d|d|d       	 |j/                  d||g       |	S y# t0        $ r"}
t)        j*                  d|
z         Y d }
~
y d }
~
ww xY w)Nrp  zCSELECT server_id, section_id FROM library_sections WHERE id IN ({})r    r   r   )r   r   
purge_onlyr|   zITautulli Libraries :: Library history not deleted for library section_id z because library server_id z' does not match Plex server identifier .Tz6Tautulli Libraries :: Deleting library with server_id z and section_id z from database.zUPDATE library_sections SET deleted_section = 1, keep_history = 0, do_notify = 0, do_notify_created = 0 WHERE server_id = ? AND section_id = ?zFTautulli Libraries :: Unable to execute database query for delete: %s.F)r   r,   listrx  r   r/   r   r%  r3   r4   r5   r.   deleteallr!  r"  r&   r'   r(   delete_library_historyr   r9   r%   r6   r   )r   r   r   row_idsr  r:   rA   successro   delete_successr   s              rB   r  zLibraries.delete@  s   --/
w*3w22GMM#4FGHG  && (::@&3%RUV]R^J^A_:`bikF G! Ct{{W[5IV]^jVk6@  +  B CC w<_$$&!AV]]%A%AIFMM888!)!@!@J!W)9fmm6R6RT U "&%%(*6 7n%% 'OQZ\fPgi *)
 	 ! nKK hkl lmmns   
F! !	G*GGc                    t        j                         }	 |rU|j                         rEd}|j                  ||g      }|r,t	        j
                  d|z         |j                  d|g       yy|rEd}|j                  ||g      }|r,t	        j
                  d|z         |j                  d	|g       yyy # t        $ r"}t	        j                  d
|z         Y d }~y d }~ww xY w)Nz3SELECT * FROM library_sections WHERE section_id = ?r!   z?Tautulli Libraries :: Re-adding library with id %s to database.z|UPDATE library_sections SET deleted_section = 0, keep_history = 1, do_notify = 1, do_notify_created = 1 WHERE section_id = ?TFz5SELECT * FROM library_sections WHERE section_name = ?zATautulli Libraries :: Re-adding library with name %s to database.z~UPDATE library_sections SET deleted_section = 0, keep_history = 1, do_notify = 1, do_notify_created = 1 WHERE section_name = ?zHTautulli Libraries :: Unable to execute database query for undelete: %s.)	r   r,   r"  r%  r   r%   r6   r   r9   )r   r   r   r:   r"   rA   r   s          rB   undeletezLibraries.undeletej  s    --/
	hj002M#**j\*JKK adn no%% '= (2l4   O#**l^*LKK cfr rs%% '? (4n6      	hKKbeffgg	hs   AB5 -AB5 5	C >CC c           	         dd l }	 |j                         r |j                  t        j                  j
                        D cg c]k  }|j                  d|z        rU|j                  d      rD |j                  |j                  j                  t        j                  j
                  |            m c} t        j                  d|z         d|z  S yc c}w # t        $ r"}t        j                  d|z         Y d }~y d }~ww xY w)Nr   zmedia_info_%srQ  zGTautulli Libraries :: Deleted media info table cache for section_id %s.z6Deleted media info table cache for library with id %s.z>Unable to delete media info table cache, section_id not valid.zBTautulli Libraries :: Unable to delete media info table cache: %s.)rT  r"  listdirr&   r'   rV  
startswithendswithremoverU  r4   r   r$  r   r9   )r   r   rT  fr   s        rB   delete_media_info_cachez!Libraries.delete_media_info_cache  s    
	b!!#NXbjjY_YfYfYpYpNq XLL:!=>1::gCV 277<<(?(?CD X fisstOR\\\WX  	bKK\_``aa	bs*   <C A0C2C C 	D!C>>Dc                 <   t        j                         }t        j                          t        j
                  j                  }	 t        j                  d|z         |j                  d|g       y# t        $ r"}t        j                  d|z         Y d }~y d }~ww xY w)NzKTautulli Libraries :: Deleting libraries where server_id does not match %s.z1DELETE FROM library_sections WHERE server_id != ?z.Deleted duplicate libraries from the database.z?Tautulli Libraries :: Unable to delete duplicate libraries: %s.)r   r,   r   get_server_resourcesr&   r'   r(   r   r$  r6   r   r9   )r   r:   r   r   s       rB   delete_duplicate_librariesz$Libraries.delete_duplicate_libraries  s    --/
 	##%MM00		_LLfirrsQT]S^_C 	_KKY\]]^^	_s   +A0 0	B9BBNN)NNNFN)NNN)Nr   r   rG   rG   rG   )NNF)Nr  )NNNFr   )__name__
__module____qualname__r   r   r=  rM  r&  r(  rg  r#  r+   r|  r  r  r  r  r  r  r  r   rD   rB   r   r   "  sv    L\||<|$/Lr0 GIBCn /&bAFB(H2Jh=;~,(ThBb_rD   r   )Fr   r  )rX  rT  r&   r   r   r   r   r   r   r	   r
   r   plexpy.plexr   rC   r2   rN   ru   r   r   r   objectr   r   rD   rB   <module>r     sf   $  	           :ze4.b(V(V4F_ F_rD   