
    hh                        d Z ddlT ddlT ddlmZ ddlmZmZmZ ddl	m
Z
mZmZmZm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T dd	lmZ dd
lmZ ddlmZ ddl m!Z! ddl"Z" G d de          Z# G d de          Z$ G d de          Z% G d de          Z& G d de          Z' G d de          Z( G d de(          Z) G d de          Z* G d de+e          Z,dS ) z,
Provides base classes for accessing MythTV
    )*)MythLog)FEConnectionXMLConnectionBEEventConnection)databaseSearchdatetime
check_ipv6
_donothing
resolve_ip)DBCacheDBData)SystemEvent)BECacheFileOpsProgram	FreeSpace	EventLock)	timedelta)proxy)
namedtuple)urlopenNc                       e Zd ZdS )CaptureCardN)__name__
__module____qualname__     3/usr/lib/python3/dist-packages/MythTV/methodheap.pyr   r      s        Dr   r   c                       e Zd Zej        dz   Zi ZdZ ede          Zd Z	 ej
        ddd          d	             Z ej
        d
d          d             Z ej
        dddej                  d             Z ej
        dddej                  d             Zd Zd Zd Zd(dZd(dZd Zd Zd Z ej
        dd          d             Z ej
        dd          d             Zd Zd)dZd  Zd! Zd" Z d(d#Z!d)d$Z"d% Z#d& Z$d' Z%dS )*MythBEa  
        getPendingRecordings()    - returns a list of scheduled recordings
        getScheduledRecordings()  - returns a list of scheduled recordings
        getUpcomingRecordings()   - returns a list of scheduled recordings
        getConflictedRecordings() - returns a list of conflicting recordings
        getRecorderList()         - returns a list of all recorder ids
        getFreeRecorderList()     - returns a list of free recorder ids
        lockTuner()               - requests a lock of a recorder
        freeTuner()               - requests an unlock of a recorder
        getCheckfile()            - returns the location of a recording
        getExpiring()             - returns a list of expiring recordings
        getFreeSpace()            - returns a list of FreeSpace objects
        getFreeSpaceSummary()     - returns a tuple of total and used space
        getLastGuideData()        - returns the last date of guide data
        getLoad()                 - returns a tuple of load averages
        getRecordings()           - returns a list of all recordings
        getSGFile()               - returns information on a single file
        getSGList()               - returns lists of directories,
                                    files, and sizes
        getUptime()               - returns system uptime in seconds
        isActiveBackend()         - determines whether backend is
                                    currently active
        isRecording()             - determinds whether recorder is
                                    currently recording
        walkSG()                  - walks a storage group tree, similarly
                                    to os.walk(). returns a tuple of dirnames
                                    and dictionary of filenames with sizes
    )
namesourceidinputidmplexidchaniddisplayNamerecPriorityscheduleOrderlivetvorder	quickTune	InputInfoc                 .    |                                   d S N)	freeTunerselfs    r    __del__zMythBE.__del__@   s    r   QUERY_GETALLPENDING   T)header_lengthsortedc                     |S zW
        Returns a list of Program objects which are scheduled to be recorded.
        r   r2   pgs     r    getPendingRecordingszMythBE.getPendingRecordingsC   	    
 	r   QUERY_GETALLSCHEDULED)r7   c                     |S r9   r   r:   s     r    getScheduledRecordingszMythBE.getScheduledRecordingsJ   r=   r   )r6   r7   	recstatusc                     |S )z
        Returns a list of Program objects which are scheduled to be recorded.

        Sorts the list by recording start time and only returns those with
        record status of WillRecord.
        r   r:   s     r    getUpcomingRecordingszMythBE.getUpcomingRecordingsQ   s	     	r   c                     |S )zX
        Retuns a list of Program objects subject to conflicts in the schedule.
        r   r:   s     r    getConflictedRecordingszMythBE.getConflictedRecordings\   s	     	r   c                     g }| j                             | j                  5 }|                    d           |D ]*}|                    t          |d                              +	 ddd           n# 1 swxY w Y   |S )zH
        Returns a list of recorders, or an empty list if none.
        zSELECT cardid FROM capturecardr   N)dbcursorlogexecuteappendint)r2   	recordersrH   rows       r    getRecorderListzMythBE.getRecorderListd   s     	W^^DH%% 	.NN;<<< . .  SV----.	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. s   AA22A69A6c                                            d                              t                    } fdt          t	          |          gt           j                  z   D             }d |D             }|S )zp
        Returns a list of free recorders in preferred live TV order,
        or an empty list if none.
        GET_FREE_INPUT_INFO 0c                 $    g | ]} j         | S r   
_InputInfo.0elr2   s     r    
<listcomp>z.MythBE.getFreeRecorderList.<locals>.<listcomp>w   "    PPPb_T_b!PPPr   c                     g | ]	}|j         
S r   )r%   )rV   xs     r    rX   z.MythBE.getFreeRecorderList.<locals>.<listcomp>x   s    6661QY666r   backendCommandsplitBACKEND_SEPzipiterlen_i_info)r2   resres_inputinforM   s   `   r    getFreeRecorderListzMythBE.getFreeRecorderListo   s{    
 !!"9::@@MM QPPPC$s))S=N=N1N,OPPP 	66666	r   c                                            d                              t                    } fdt          t	          |          gt           j                  z   D             }|S )a  
        Return a list of 'InputInfo' tuples of free recorders in preferred
        live TV order.
        Returns an empty list if no recorders are available.
        Introduced in protocol 87, changed in protocols 89, 90, 91.

        InputInfo is a named tuple containing:
        ('InputInfo', ('name', 'sourceid', 'inputid', 'mplexid', 'chanid',
                       'displayName', 'recPriority', 'scheduleOrder',
                       'livetvorder', 'quickTune')).

        See definition of InputInfo in inputinfo.h.

        Usage examples:

        MythBE.getFreeInputInfo()[3].displayName   ---> 'Eingang 13:MPEG2TS'

        [x.inputid for x in getFreeInputInfo()]   --->  list of free recorders
        rQ   c                 $    g | ]} j         | S r   rS   rU   s     r    rX   z+MythBE.getFreeInputInfo.<locals>.<listcomp>   rY   r   r\   )r2   rd   re   s   `  r    getFreeInputInfozMythBE.getFreeInputInfo{   sh    ( !!"9::@@MM QPPPC$s))S=N=N1N,OPPP 	r   Nc                    d}| }|fd}	 t          |          }n # t          $ r t          d|z            w xY w|d|z  z  }|j        |j        k    rt          |j        | j                  }|                    |                              t                    }t          |d                   }|dk    r&|j        | j	        |<   t          |dd                   S |S )a	  
        Request a tuner be locked from use, optionally specifying which tuner
        Returns a tuple of ID, video dev node, audio dev node, vbi dev node
        Returns an ID of -2 if tuner is locked
                         -1 if no tuner could be found
        
LOCK_TUNERNCapture card %s not foundz %drG   r   r5   )r   	MythErrorhostnamer"   rG   r]   r^   r_   rL   locked_tunerstuple)r2   idcmdbecardrd   errs          r    	lockTunerzMythBE.lockTuner   s     >DB"2 B B B ;b @AAAB 52:C}++DMdg666$$**;77#a&kk77&(kDs#QRR>>! 
s    7c                    i }|rt          |          }|| j        v r| j                            |          ||<   nC	 t          |          }n # t          $ r t	          d|z            w xY w|j        ||<   n| j        }| j        | i}	 	 |                                \  }}d}||v r	||         }nt          || j                  }|||<   |	                    d|z             n# t          $ r Y dS w xY wm)zz
        Frees a requested tuner ID
        If no ID given, free all tuners listed as used by this class instance
        Nrl   Trm   zFREE_TUNER %d)rL   rp   popr   rn   ro   popitemr"   rG   r]   KeyError)r2   rr   	tunerlistru   hostshostrt   s          r    r0   zMythBE.freeTuner   sH   
 	>RBT''' $ 2 6 6r : :	"F&r??DD  F F F#$?"$DEEEF $	" *It$	$,,..D 5==tBB111B"$E$K !!/B"67777   	s   A A)	AC# #
C10C1c                     |                      dt                              t          |          dg          z             }t	          |                    t                    | j                  S )zO
        Returns a Program object for the current recorders recording.
        QUERY_RECORDER GET_CURRENT_RECORDINGrm   )r]   r_   joinstrr   r^   rG   r2   recorderrd   s      r    getCurrentRecordingzMythBE.getCurrentRecording   sb     !!"3  #h--0G!HII#J K Ksyy--$'::::r   c                     |                      dt                              t          |          dg          z             }|dk    rdS dS )zR
        Returns a boolean as to whether the given recorder is recording.
        r   IS_RECORDING1TF)r]   r_   r   r   r   s      r    isRecordingzMythBE.isRecording   sS     !!"3  #h--!?@@#A B B#::45r   c                 t    |                      t                              d|g                    }|dk    rdS dS )zU
        Returns a boolean as to whether the given host is an active backend
        QUERY_IS_ACTIVE_BACKENDTRUETF)r]   r_   r   )r2   ro   rd   s      r    isActiveBackendzMythBE.isActiveBackend   sF     !!+"2"2.x8#: #: ; ;&==45r   zQUERY_RECORDINGS Ascendingc                     |S )zS
        Returns a list of all Program objects which have already recorded
        r   r:   s     r    getRecordingszMythBE.getRecordings  r=   r   QUERY_GETEXPIRINGc                     |S )zK
        Returns a tuple of all Program objects nearing expiration
        r   r:   s     r    getExpiringzMythBE.getExpiring	  r=   r   c                     |                      t                              dd|                                g                                        t                    }|d         dk    rdS |d         S )z>
        Returns location of recording in file system
        QUERY_CHECKFILEr   r   Nr5   )r]   r_   r   toStringr^   )r2   programrd   s      r    getCheckfilezMythBE.getCheckfile  sn     !!+"2"2*3w/?/?/A/AB# #  u[)) 	 q6Q;;4q6Mr   Fc              #   *  K   d}|rd}|                      |                              t                    }t          t          j                  }t          t          |          |z            D ]$}t	          |||z  ||z  |z                      V  %dS )z6
        Returns a tuple of FreeSpace objects
        QUERY_FREE_SPACEQUERY_FREE_SPACE_LISTN)r]   r^   r_   rb   r   _field_orderrange)r2   allcommandrd   lis         r    getFreeSpacezMythBE.getFreeSpace  s       % 	.-G!!'**00==	&''s3xx{## 	, 	,AC!AaCE	N++++++	, 	,r   c                     d |                      d                              t                    D             }|d         |d         fS )zO
        Returns a tuple of total space (in KB) and used space (in KB)
        c                 ,    g | ]}t          |          S r   rL   rV   rs     r    rX   z.MythBE.getFreeSpaceSummary.<locals>.<listcomp>,  s*     8 8 8!s1vv 8 8 8r   QUERY_FREE_SPACE_SUMMARYr   r5   r]   r^   r_   )r2   rd   s     r    getFreeSpaceSummaryzMythBE.getFreeSpaceSummary(  sN    8 8t223MNN$)E+$6$68 8 8AAr   c                 p    d |                      d                              t                    D             S )zJ
        Returns a tuple of the 1, 5, and 15 minute load averages
        c                 ,    g | ]}t          |          S r   floatr   s     r    rX   z"MythBE.getLoad.<locals>.<listcomp>4  s*     ; ; ;Qa ; ; ;r   
QUERY_LOADr   r1   s    r    getLoadzMythBE.getLoad0  s=    ; ;$"5"5l"C"C',u['9'9; ; ; 	;r   c                 b    t          dt          |                     d                              S )z3
        Returns machine uptime in seconds
        r   QUERY_UPTIME)r   rL   r]   r1   s    r    	getUptimezMythBE.getUptime7  s*     C 3 3N C CDDEEEr   c                 $   fd|                      ||d          }|dk    s|d}i }|D ]u} | ||||          }|D ]a}||v rP||         dxx         ||         d         z  cc<   ||         d                             ||         d                    V||         ||<   bvg }t          |                                          D ]6\  }	}
|                    |	t          |
d                   |
d         f           7|                                 |S )a  
        Performs similar to os.walk(), returning a tuple of tuples containing
            (dirpath, dirnames, filenames).
        'dirnames' is a tuple of all directories at the current level.
        'filenames' is a dictionary, where the values are the file sizes.
        c                 h   |                      ||||z   dz             }t          |t                    r~t          |d                   }|t	          t          |d         |d                             g}|dk    rd|i}n||i}|D ]*}|                     | ||||dz   |z                        +|S i S )N/r   r5       )	getSGList
isinstancerq   listdictr`   update)	r2   r~   sgrootpathrd   dlistdwalks	           r    r   zMythBE.walkSG.<locals>.walkD  s    ..r49S=99C#u%% SVd3s1vs1v#6#67782::s)CC*C G GAJJttD$D$s(1*EEFFFF
	r   r   r   Nr   r5   )r   r   r   itemsrK   rq   sort)r2   r~   r   topbaseswalkedbaserd   r   keyvalr   s              @r    walkSGzMythBE.walkSG=  sJ   	 	 	 	 	 tR,,3JJCK# 	' 	'D$tT2tS11C ' ';;1IaLLLCF1I-LLL1IaL''Aq	2222 #AF1II' V\\^^,, 	5 	5HCJJU3q6]]CF34444



r   c                    |rd}|                      t                              d|||t          t	          |                    g                                        t                    }|d         dk    rdS |d         dk    rdS g }g }g }|D ]}	|r|                    |	           |dk    r.|	                    d          \  }
}|                    |           N|	                    d          }|d         d	k    r7|                    |d
                    |                    |d                    |d         dk    r|                    |d
                    |r|S |dk    r|S |||fS )z
        Returns a tuple of directories, files, and filesizes.
        Two special modes
            'filenamesonly' returns only filenames, no directories or size
            empty path base directories returns base storage group paths
        r   QUERY_SG_GETFILELISTr   
EMPTY LISTSLAVE UNREACHABLE: ::filer5   r   dir)r]   r_   r   r   rL   r^   rK   )r2   r~   r   r   filenamesonlyrd   dirsfilessizesentrytyper#   ses                r    r   zMythBE.getSGListe  s    #$!!+"2"2+DDM**++-# #   5%% 	 q6\!!2q6***2 	' 	'E 'U####!KK--	TD!!!![[&&a5F??LLA'''LLA''''Ue^^KK1&&& 	(LRZZK%''r   c                     |                      t                              d|||g                                        t                    }|d         dk    rdS |d         dk    rdS t	          |dd                   S )	zI
        Returns a tuple of last modification time and file size
        QUERY_SG_FILEQUERYr   r   r   r   r   r5      )r]   r_   r   r^   rq   )r2   r~   r   r   rd   s        r    	getSGFilezMythBE.getSGFile  s     !!+"2"2%d2d3#5 #5 6 66;eK6H6H 	q6\!!2q6***2S1Xr   c                 t    	 t          j        |                     d                    S # t          $ r Y dS w xY w)zH
        Returns the last dat for which guide data is available
        QUERY_GUIDEDATATHROUGHN)r	   duckr]   
ValueErrorr1   s    r    getLastGuideDatazMythBE.getLastGuideData  sH    	=!4!45M!N!NOOO 	 	 	44	s   &) 
77c                 |    |                      dt          z             | j        j                                         dS )zV
        Triggers an event to clear the settings cache on all active systems.
        zMESSAGE%sCLEAR_SETTINGS_CACHEN)r]   r_   rG   settingsclearr1   s    r    clearSettingszMythBE.clearSettings  s;     	;kIJJJ     r   r/   )F)&r   r   r   r   __doc__rp   rc   r   rT   r3   _ProgramQueryr<   r@   r   rsWillRecordrC   
rsConflictrE   rO   rf   ri   rw   r0   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r"   r"      s       o  G: MKGK11J   W0$OOO  PO W24@@@  A@ W0$%,%9; ; ; ; ; W0$%,%79 9 9 9 9	 	 	
 
 
  4       D+ + + +Z; ; ;	 	 		 	 	 W7EEE  FE W.t<<<  =<
 
 

, 
, 
, 
,     ; ; ;F F F& & & &P%( %( %( %(N
 
 
  ! ! ! ! !r   r"   c                   8     e Zd Z	 	 d fd	Zd Zd ZddZ xZS )	BEEventMonitorNFc                 l    || _         t          t          |                               ||d|           d S NT)systemeventssuperr   __init__)r2   backendblockshutdownr   rG   	__class__s        r    r   zBEEventMonitor.__init__  s5    (nd##,,WmT2NNNNNr   c                     | j         gS r/   )eventMonitorr1   s    r    _listhandlerszBEEventMonitor._listhandlers  s    !""r   c                     t          | j        | j        | j                                        d| j                           S )N)r   r5   level)r   r~   portrG   gethostnamer   r1   s    r    _neweventconnzBEEventMonitor._neweventconn  s<     DItw7J7J7L7L!$"346 6 6 	6r   c                     |t          j        d          S |                     t          j        t          j        |           d S )NBACKEND_MESSAGE)recompilerI   r   ALLINFOr2   events     r    r   zBEEventMonitor.eventMonitor  s8    =:/000glE22222r   )NFFNr/   )r   r   r   r   r   r   r   __classcell__r   s   @r    r   r     s{        38.2O O O O O O
# # #6 6 63 3 3 3 3 3 3 3r   r   c                   b     e Zd Z G d de          Zd Z	 	 d
 fd	Zd Zed	             Z xZ	S )MythSystemEventc                       e Zd Ze                    dd                              dd          Z ej        e                    g d                    Z	d Z
d Zd
d	ZdS )"MythSystemEvent.systemeventhandler[z\[]z\])r  zSYSTEM_EVENT (?P<event>[A-Z0-9_]*)( HOSTNAME (?P<hostname>[a-zA-Z0-9_\.]*))?( SENDER (?P<sender>[a-zA-Z0-9_\.]*))?( CARDID (?P<cardid>[0-9]*))?( CHANID (?P<chanid>[0-9]*))?( STARTTIME (?P<starttime>[0-9-]*T[0-9-]))?( SECS (?P<secs>[0-9]*))?emptyc                 r   || _         | j         j        | _        | j         j        | _        | j         j        | _        d | _        t          j        d| j        d| j                                                  | _	        | j        dk    | _
        | j
        r#t          j        d| j        z            | _	        d S d S )Nr  zSYSTEM_EVENT _generic_handlerzBACKEND_MESSAGE%sSYSTEM_EVENT)funcr   r   r   filterr  r  bsupper	re_searchgeneric)r2   r  s     r    r   z+MythSystemEvent.systemeventhandler.__init__  s    DI9,DL I.DM"i2DODKZZ!%$-*=*=*?*?*?)A B BDN !M-??DL| K!# ?$' I"K "KK Kr   c                     || _         | S r/   )inst)r2   r  owns      r    __get__z*MythSystemEvent.systemeventhandler.__get__  s    DIKr   Nc                 d   || j         S | j                            |          }i }dD ]/}|                    |          |                    |          ||<   0| j        r3| j        d | j        j        D             | _        |d         | j        v rd S |                    d          n|                    d          Yt          | j        j	                  }|
                    |                    d          |                    d          f          |d<   |                     | j        |           d S )N)r  ro   sendercardidsecsc                 @    g | ]}|j                                         S r   )r   r  )rV   fs     r    rX   z?MythSystemEvent.systemeventhandler.__call__.<locals>.<listcomp>  s<     #D #D #D,- $%:#3#3#5#5 #D #D #Dr   r  r'   	starttimer   )r  
re_processmatchgroupr  r  r  _eventsr"   ro   getRecordingr  )r2   r  r&  art   s        r    __call__z+MythSystemEvent.systemeventhandler.__call__  sB   }~% O))%00EEB . .;;q>>-${{1~~E!H | ;&#D #D151B#D #D #DDK>T[00F H%%1K((4	 233B') ;;x00[1I1IJ(L (LE)$ IIdi'''''r   r/   )r   r   r   r_   replacer  r  r  r   r%  r   r  r+  r   r   r    systemeventhandlerr    s          U++33C>>RZ 	) 	) 	) 	! 	! 	 	
	K 	K 	K	 	 		( 	( 	( 	( 	( 	(r   r-  c                     g S r/   r   r1   s    r    r   zMythSystemEvent._listhandlers  s    	r   NFTc                     t          t          |                               ||d|           |r;| j                            | j                   |                     | j                   d S d S r   )r   r  r   r(  rK   r  registerevent)r2   r   r   rG   enablehandlerr   s        r    r   zMythSystemEvent.__init__  so    ot$$--g}dBOOO 	6L 5666t455555	6 	6r   c                 j    t          | j        | j        | j                                        d          S )Nr   r   )r   r~   r   rG   r   r1   s    r    r   zMythSystemEvent._neweventconn  s,     DItw7J7J7L7LTUVVVVr   c                 b    t          |d         | j                                      |           d S )Nr  )r   rG   r   r  s     r    r  z MythSystemEvent._generic_handler  s,    E'NDG,,44U;;;;;r   )NFNT)
r   r   r   objectr-  r   r   r   r  r	  r
  s   @r    r  r    s        ;( ;( ;( ;( ;(f ;( ;( ;(z   >B%)6 6 6 6 6 6W W W < < < < < < <r   r  c                       e Zd ZdZ G d de          Z G d de          Zd Zd Zd Z	d	 Z
d
 Zd Zd Zd Zd Zd Zd ZdS )FrontendNc                   >    e Zd Zd Zd Zd Zd Zd Zd Zd Z	d Z
d	S )
Frontend._Jumpc                 D    t          |                                           S r/   r   r   r1   s    r    __str__zFrontend._Jump.__str__      3tyy{{#3#33r   c                      t          |           S r/   r   r1   s    r    __repr__zFrontend._Jump.__repr__      3t99,r   c                 <    t          |          | _        i | _        d S r/   )r   _parent_pointsr2   parents     r    r   zFrontend._Jump.__init__  s     ==DLDLLLr   c                 v    t           | _        t          | j                            d                    | _        d S )Njump)r   	_populater   rB  sendrC  r1   s    r    rH  zFrontend._Jump._populate  s,    'DN 1 1& 9 9::DLLLr   c                 v    |                                   || j        v r| j                            d|          S dS )NrG  F)rH  rC  rB  rI  r2   r   s     r    __getitem__zFrontend._Jump.__getitem__  s<    NNdl""|((555ur   c                     |                                   || j        v r| j        |         S |                     |          S r/   )rH  __dict__rL  rK  s     r    __getattr__zFrontend._Jump.__getattr__  s@    NNdm##}S))##C(((r   c                 8    |                                   | j        S r/   )rH  rC  r1   s    r    r   zFrontend._Jump.dict%  s    NN<r   c                 \    |                                   | j                                        S r/   )rH  rC  r   r1   s    r    r   zFrontend._Jump.list)  s&    NN<%%'''r   N)r   r   r   r;  r?  r   rH  rL  rO  r   r   r   r   r    _Jumpr8    s        333,,,	 	 		; 	; 	;	 	 		) 	) 	)	  	  	 	( 	( 	( 	( 	(r   rR  c                   \   e Zd Z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%d&d'd(d)d*d+d,	Zd-  e ed.d/                     e ed0d1                    z    e ed2d3                    z   D             Zd4 Zd5 Zd6 Z	d7 Z
d8 Zd9 Zd: Zd; Zd< Zd=S )>Frontend._Key	   tab
   enter   escape    space\   	backslash   	backspacei  downi  upi  lefti  righti	  f1i
  f2i  f3i  f4i  f5i  f6i  f7f8f9f10f11f12deleteinsertpagedownpageup)	i  i  i  i  i  iJ  iK  iR  iS  c                 ,    g | ]}t          |          S r   )chr)rV   r   s     r    rX   zFrontend._Key.<listcomp>7  s    \\\Q#a&&\\\r   0   :   A   [   a   {   c                 D    t          |                                           S r/   r:  r1   s    r    r;  zFrontend._Key.__str__9  r<  r   c                      t          |           S r/   r>  r1   s    r    r?  zFrontend._Key.__repr__:  r@  r   c                 <    t          |          | _        g | _        d S r/   )r   rB  _keysrD  s     r    r   zFrontend._Key.__init__<  s     ==DLDJJJr   c                 \    t           | _        | j                            d          | _        d S )Nr   )r   rH  rB  rI  r  r1   s    r    rH  zFrontend._Key._populate@  s$    'DN**511DJJJr   c                 `    || j         v s	|| j        v r| j                            d|          S dS )Nr   F)r  _alnumrB  rI  rK  s     r    _sendLiteralzFrontend._Key._sendLiteralD  s8    tz!!sdk'9'9|((4445r   c                     	 t          |          }|| j        v r| j        |         }nt          |          }|                     |          S # t          $ r Y dS w xY w)NF)rL   _keymaprv  r  r   rK  s     r    _sendOrdinalzFrontend._Key._sendOrdinalI  sn    #hh$,&&,s+CCc((C((---   uus   A	A 
AAc                     |                                   |                     |          rdS |                     |          rdS dS )NTF)rH  r  r  rK  s     r    rL  zFrontend._Key.__getitem__T  sM    NN  %% t""3'' tur   c                     |                                   || j        v r| j        |         S |                     |          S r/   )rH  rN  r  rK  s     r    rO  zFrontend._Key.__getattr__]  s@    NNdm##}S))$$S)))r   c                 8    |                                   | j        S r/   )rH  r  r1   s    r    r   zFrontend._Key.listc  s    NN:r   N)r   r   r   r  r   r   r  r;  r?  r   rH  r  r  rL  rO  r   r   r    _KeyrT  -  s       2Ae 2Bw 2Bx 2w2$&{24722$'2472 2 %(2 582 	2 %(	2 58	2
 2
 %(2
 9="2 2 2 ]\$$uuR||"4"4TT%%2,,5G5G"GUUSUVY]]H[H["[\\\333,,,	 	 		2 	2 	2	 	 	
		 		 			 	 		* 	* 	*	 	 	 	 	r   r  c                     t          j        | g|R i | |                     |           | _        |                     |           | _        d S r/   )r   r   rR  rG  r  r   )r2   argskwargss      r    r   zFrontend.__init__g  sK    d4T444V444JJt$$	99T??r   c                 .    |                      d|          S NqueryrI  )r2   r  s     r    	sendQueryzFrontend.sendQueryl  s    dii&?&??r   c                 ,    |                      d          S r  r  r1   s    r    getQueryzFrontend.getQuerym  s    tyy111r   c                 .    |                      d|          S Nplayr  )r2   r  s     r    sendPlayzFrontend.sendPlayn  s    DIIfd$;$;;r   c                 ,    |                      d          S r  r  r1   s    r    getPlayzFrontend.getPlayo  s    dii///r   c                 ,    |                     |           S )z!Plays selected media on frontend.)	_playOnFe)r2   medias     r    r  zFrontend.playq  s    t$$$r   c                 ~    t          d |                     d                                          D                       S )z&Returns tuple of 1/5/15 load averages.c                 ,    g | ]}t          |          S r   r   )rV   r   s     r    rX   z$Frontend.getLoad.<locals>.<listcomp>w  s    GGG1eAhhGGGr   load)rq   r  r^   r1   s    r    r   zFrontend.getLoadu  s7    GGv(>(>(D(D(F(FGGGHHHr   c                 b    t          dt          |                     d                              S )zReturns timedelta of uptime.r   uptime)r   rL   r  r1   s    r    r   zFrontend.getUptimey  s&    Cx 8 899:::r   c                 P    t          j        |                     d                    S )z!Returns current time on frontend.time)r	   fromIsor  r1   s    r    getTimezFrontend.getTime}  s    v 6 6777r   c           	          t          t          dd |                     d                                          D                                 S )z1Returns free and total, physical and swap memory.)totalmemfreemem	totalswapfreeswapc                 ,    g | ]}t          |          S r   r   )rV   ms     r    rX   z&Frontend.getMemory.<locals>.<listcomp>  s    HHHSVVHHHr   memstats)r   r`   r  r^   r1   s    r    	getMemoryzFrontend.getMemory  sQ    CEHHT^^J%?%?%E%E%G%GHHHJ J K K 	Kr   c                     t          d| j        z            }|                                }|                                 |S )z"Returns PNG image of the frontend.z#http://%s:6547/MythFE/GetScreenShot)r   r~   readclose)r2   fdimgs      r    getScreenShotzFrontend.getScreenShot  s6    :TYFGGggii




r   )r   r   r   _dbr4  rR  r  r   r  r  r  r  r  r   r   r  r  r  r   r   r    r6  r6  
  s       
C( ( ( ( ( ( ( (B8 8 8 8 8 8 8 8t# # #
 @??111;;;///% % %I I I; ; ;8 8 8K K K
    r   r6  c                   
   e Zd Zej        dz   Zedd            Zedd            Zedd            Zedd            Z	edd            Z
d	ej        fd
Zedd            Zedd            Zd Zd Zd Zedd            ZdS )MythDBa(  
        obj.searchRecorded()    - return a list of matching Recorded objects
        obj.searchOldRecorded() - return a list of matching
                                  OldRecorded objects
        obj.searchJobs()        - return a list of matching Job objects
        obj.searchGuide()       - return a list of matching Guide objects
        obj.searchRecord()      - return a list of matching Record rules
        obj.getFrontends()      - return a list of available Frontends
        obj.getFrontend()       - return a single Frontend object
    FNc                    |rjd|_         t          |_        d|_        |                    dddd          |                    dddd          |                    ddd	
          f|_        dS |dv rd|z  |dfS |dv rd|z  t          j        |          dfS |dk    rdt          j        |          dfS |dk    rdt          j        |          dfS |dv rd|z  |dfS |dk    rdS |dk    r||dk    rdS dS dS )aN  
        obj.searchRecorded(**kwargs) -> list of Recorded objects

        Supports the following keywords:
            title,      subtitle,   chanid,     starttime,  progstart,
            category,   hostname,   autoexpire, commflagged,
            stars,      recgroup,   playgroup,  duplicate,  transcoded,
            watched,    storagegroup,           category_type,
            airdate,    stereo,     subtitled,  hdtv,       closecaptioned,
            partnumber, parttotal,  seriesid,   showtype,   programid,
            manualid,   generic,    cast,       livetv,     basename,
            syndicatedepisodenumber,            olderthan,  newerthan,
            inetref,    season,     episode,    recordedid

        Multiple keywords can be chained as such:
            obj.searchRecorded(title='Title', commflagged=False)
        recorded)livetvrecordedprogramr'   r$  )r'   	progstarttabletableto
fieldsfromfieldstorecordedcreditspeoplepersonr  r  fieldsN)titlesubtitler'   categoryro   
autoexpirecommflaggedstarsrecgroup	playgroup	duplicate
transcodedwatchedstoragegroupbasenameinetrefseasonepisode
recordedidzrecorded.%s=%%sr   )r$  endtimer  progendrecorded.%s=?	olderthanzrecorded.starttime<?	newerthanzrecorded.starttime>?)category_typeairdatestereo	subtitledhdtvclosecaptioned
partnumber	parttotalseriesidshowtypesyndicatedepisodenumber	programidmanualidr  zrecordedprogram.%s=?r5   cast)people.namer     r5   r  F)zrecorded.recgroup!=?LiveTVr   r   )r  RecordedhandlerrequireJoinjoinsr	   r   r2   initr   values       r    searchRecordedzMythDB.searchRecorded  s   (  	#DJ#DL&DL))*;,6/E-C $ E E ))*;,6/E-C $ E E ))(,=+6 $ 8 8
9DJ 4  D D D
 &+UA66 ???#c)8=+?+?CC+*HM%,@,@!DD+*HM%,@,@!DD  * * * +S0%;;&==;;(??5E>><<2tr   c                     |rd|_         t          |_        dS |dv rd|z  |dfS |dv rd|z  t          j        |          dfS dS )aJ  
        obj.searchOldRecorded(**kwargs) -> list of OldRecorded objects

        Supports the following keywords:
            title,      subtitle,   chanid,     starttime,  endtime,
            category,   seriesid,   programid,  station,    duplicate,
            generic,    recstatus,  inetref,    season,     episode
        oldrecordedN)r  r  r'   r  r  r  stationr  r  rA   r  r  r  zoldrecorded.%s=?r   r$  r  )r  OldRecordedr  r	   r   r  s       r    searchOldRecordedzMythDB.searchOldRecorded  sr      	&DJ&DL4 , , , ',eQ77)))&,hmE.B.BAFFtr   c                     |r4d|_         t          |_        |                    dddd          f|_        dS |dv rd|z  |dfS |d	v rd
|z  |dfS |dk    rd
|z  t          j        |          dfS dS )z
        obj.searchArtwork(**kwargs) -> list of RecordedArtwork objects

        Supports the following keywords:
            inetref,    season,     host,   chanid,     starttime
            title,      subtitle
        recordedartworkr  )r  r  ro   )r  r  r~   r  Nzrecordedartwork.%s=?r   )r'   r  r  r  r5   r$  )r  RecordedArtworkr  r  r  r	   r   r  s       r    searchArtworkzMythDB.searchArtwork  s      	*DJ*DL))*,=/N-H $ J J LDJ 4///*S0%;;111#c)5!44+#c)8=+?+?CCtr   c                 d   |r3d|_         t          |_        |                    ddd          f|_        dS |dv rd|z  |dfS |d	v rd
|z  |dfS |dk    rd|dfS |dk    rdt          j        |          dfS |dk    rdt          j        |          dfS |dk    rdt          j        |          dfS dS )z
        obj.searchJobs(**kwars) -> list of Job objects

        Supports the following keywords:
            chanid,     starttime,  type,       status,     hostname,
            title,      subtitle,   flags,      olderthan,  newerthan
        jobqueuer  r  r  N)r'   r   statusro   zjobqueue.%s=?r   )r  r  r  r5   flagszjobqueue.flags&?r$  zjobqueue.starttime=?r  zjobqueue.inserttime>?r  zjobqueue.inserttime<?)r  Jobr  r  r  r	   r   r  s       r    
searchJobszMythDB.searchJobs  s     	#DJDL))*,6+A $ C C EDJ 4777#c)5!44&&&#c)5!44'>>&q11+*HM%,@,@!DD++X]5-A-A1EE++X]5-A-A1EEtr   c                 ,   |rd|_         t          |_        |                    ddd          |                    ddd          |                    ddd          |                    d	dd          |                    d
d	d          |                    ddd          |                    ddd          |                    ddd          f|_        dS |dv rd|z  |dfS |dv rd|z  t          j        |          dfS |dk    rd|dfS |dk    rdS |dv rd|z  ddfS |dk    rd|dfS |dk    rdS |d	k    rd |d!fS |dk    r!	 t          |          }d"|dfS #  d#|d$fcY S xY w|d%k    rd&|d'fS |d(k    rd)|d*fS |d+k    rd,S |                    d-          r;|d.d         d/v rd0|d.d         z  d1|z   d1z   dfS |d.d         dk    rd2d1|z   d1z   dfS |	                    d3          r8d4d5d6d7}|dd8         |v r&d9
                    ||dd8                            |dfS |d:k    rd;t          j        |          dfS |d<k    rd=t          j        |          dfS |d>k    rd?t          j        |          dfS |d@k    rdAt          j        |          dfS dS )BaF  
        obj.searchGuide(**args) -> list of Guide objects

        Supports the following keywords:
            chanid,     starttime,  endtime,    title,      subtitle,
            category,   airdate,    stars,      previouslyshown,
            stereo,     subtitled,  hdtv,       closecaptioned,
            partnumber, parttotal,  seriesid,   originalairdate,
            showtype,   programid,  generic,    syndicatedepisodenumber,
            ondate,     cast,       startbefore,startafter
            endbefore,  endafter,   dayofweek,  weekday
            first,      last,       callsign,   commfree
            channelgroup,           videosource,
            genre,      rating,     cast,       fuzzytitle
            fuzzysubtitle,          fuzzydescription,
            fuzzyprogramid,         beforedate, afterdate,
        r   creditsr  r  r  r  channel)r'   channelgroupchannelgroupnames)grpidvideosource)r$   programgenresprogramratingN)r'   r  r  r  r  r  previouslyshownr  r  r  r  r  r  r  originalairdater  r  r  r  r  zprogram.%s=?r   r  	dayofweekzDAYNAME(program.starttime)=?weekday)zWEEKDAY(program.starttime)<?   r   )firstlastr5   callsignzchannel.callsign=?r  commfree)zchannel.commmethod=?r   r  zchannelgroupnames.name=?   zchannel.sourceid=?zvideosource.name=?$   genrezprogramgenres.genre=?@   ratingzprogramrating.rating=?   r  )r  r  r   r   fuzzyr  )r  r  descriptionr  zprogram.%s LIKE ?%zchannel.callsign LIKE ?date=<>)onbeforeafterzDATE(program.starttime){0}?startbeforezprogram.starttime<?
startafterzprogram.starttime>?	endbeforezprogram.endtime<?endafterzprogram.endtime>?)r  Guider  r  r  r	   r   rL   
startswithendswithformat)r2   r  r   r  prefixs        r    searchGuidezMythDB.searchGuide;  s   &  	"DJ DL))),5+A $ C C ))(,5+6 $ 8 8 ))),5+6 $ 8 8 )).,5+6 $ 8 8 ))*=,:+5 $ 7 7 ))-,5+8 $ : : ))/,5+A $ C C ))/,5+A $ C C+DDJ0 4 ) ) ) #S(%33)))"S((-*>*>BB+2E1==)99###"S(!Q//*(%33*22.  .r::-9E

,eQ779,eR8888'>>+UB77(??,eS99&==33>>'"" 	E122wKKK+c!""g5s5y}aHH122w*$$13u9S=!DD<< 	"c::F3B3x6!!5<<VCH=MNNq" " -)8=+?+?CC,)8=+?+?CC+'u)=)=qAA*'u)=)=qAAts   E E"zunnamed (Power Searchc                     | j                             |          \  }}}d                    |          }| j                             |          }t                              ||||||           S )Nz AND )r  r   wherer  r   rG   )r7  parseInpr   	buildJoinRecordfromPowerRule)r2   	ruletitler   r  r9  r  r   s          r    makePowerRulezMythDB.makePowerRule  ss     ,55f==tTU##))$//##)$e)-DT $ C C 	Cr   c                 L    |rd|_         t          |_        dS |dv rd|z  |dfS dS )aS  
        obj.searchRecord(**kwargs) -> list of Record objects

        Supports the following keywords:
            type,       chanid,     starttime,  startdate,  endtime
            enddate,    title,      subtitle,   category,   profile
            recgroup,   station,    seriesid,   programid,  playgroup,
            inetref
        recordN)r   r'   r$  	startdater  enddater  r  r  profiler  r  r  r  r  r  %s=?r   )r  r<  r  r  s       r    searchRecordzMythDB.searchRecord  sL      	!DJ!DL4 P P P SL%++tr   c                     |rd|_         t          |_        dS |dv rd|z  |dfS |dk    rd|dfS |dk    rd	|dfS |d
k    rd|dfS |dk    rd|dfS |dk    rd|dfS |dk    rdd|z   dz   dfS dS )a  
        obj.searchInternetContent(**kwargs) -> list of content

        Supports the following keywords:
            feedtitle,  title,      subtitle,   season,     episode,
            url,        type,       author,     rating,     player,
            width,      height,     language,   podcast,    downloadable,
            ondate,     olderthan,  newerthan,  longerthan, shorterthan,
            country,    description
        internetcontentarticlesN)	feedtitler  r  r  r  urlr   authorr!  playerwidthheightlanguagepodcastdownloadabler$  rE  r   ondatezDATE(date)=?r  zdate>?r  zdate<?
longerthanztime<?shorterthanztime>?countryzcountries LIKE ?r%  )r  InternetContentArticlesr  r  s       r    searchInternetContentzMythDB.searchInternetContent  s      	2DJ2DL4 L L L SL%++(??"E1--+eQ''+eQ'',eQ''-eQ'')&E	#q99 r   c                                             j                  5 }|                    d            fd|D             }ddd           n# 1 swxY w Y   t                              |          S )zM
        Returns a list of Frontend objects for accessible frontends
        zSELECT DISTINCT hostname
                              FROM settings
                              WHERE hostname IS NOT NULL
                              AND value='NetworkControlEnabled'
                              AND data=1c                 P    g | ]"}|d          j         |d                   j        f#S )r   )r   NetworkControlPort)rV   fer2   s     r    rX   z'MythDB.getFrontends.<locals>.<listcomp>  s@     . . . " Q%r!u!5!HI . . .r   N)rH   rI   rJ   r6  testList)r2   rH   	frontendss   `  r    getFrontendszMythDB.getFrontends  s     [["" 	.fNN , - - -
. . . .&,. . .I	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	.   +++s   $AAAc                 F    | j         |         j        }t          ||          S )zB
        Returns a Frontend object for the specified host
        )r   rZ  r6  )r2   r~   r   s      r    getFrontendzMythDB.getFrontend  s#     }T"5T"""r   c                    t          d t                              |           D                       }t          |           }t	          j        t	          j        t                                        g d                    }t          ||           }|
                    d           |                                 g }g }g }|                    |j                  }|                    d          dk    r|                    d                              t                    D ]}	|	                    d          \  }
}t!          |          }|
d	k    r#|                    t          |                     R|
d
k    r2||         }|                                 |                    |           |
dk    r|                    ||                    |||fS )zL
        obj.scanVideo() --> list of new, moved, and deleted Videos
        c                      g | ]}|j         |fS r   intid)rV   vids     r    rX   z%MythDB.scanVideos.<locals>.<listcomp>  s    SSSs39c*SSSr   rm   )r  z(VIDEO_LIST(_NO)?_CHANGE)z(.*)SCAN_VIDEOSr5   VIDEO_LIST_CHANGEr   r   addedmoveddeleted)r   VideogetAllEntriesr"   r  r  rZ  r_   r   r   r]   waitr&  r  r'  r^   rL   rK   _pull)r2   	startvidsrt   r   locknewvidsmovvidsoldvidsr&  r   r   rd  vs                r    
scanVideoszMythDB.scanVideos  s    SSe6I6IT6I6R6RSSSTT	t___Jry--         t$$$
-(((		
##;;q>>000Q--k:: 
5 
5"[[..
UE

7??NN5<<0000W__!%(AGGIIINN1%%%%Y&&NN9U#3444ww&&r   c                    |rd|_         t          |_        |                    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          f|_        dS |dv rd|z  |dfS dddd}||v r'd|d|d|z  ||         d         ||         d         fS |dk    rd|z  |dfS |dk    rd |dfS |d!k    rd"d#|z   dfS |d$k    rd%|dfS |d&k    rd'|dfS dS )(a  
        obj.searchVideos(**kwargs) -> list of Video objects

        Supports the following keywords:
            title, subtitle, season, episode, host, director, year, cast,
            genre, country, category, insertedbefore, insertedafter, custom
        videometadatavideometadatacast)idvideorc  r  	videocast)idcastvideometadatagenre
videogenre)idgenrevideometadatacountryvideocountry)	idcountryvideocategory)r  N)r  r  r  r  r~   directoryearzvideometadata.%s=?r   )r   r   )   r   )r[  r  )r  r  rU  video.zvideometadata%sr5   r  zvideocategory.%s=?r   	exactfilezvideometadata.filename=?r   zvideometadata.filename LIKE ?r%  insertedbeforezvideometadata.insertdate<?insertedafterzvideometadata.insertdate>?)r  rk  r  r  r  )r2   r  r   r  vidrefs        r    searchVideoszMythDB.searchVideos  s     	(DJ DL))*=,;/;-7 $ 9 9 ))+,?/9-8 $ : : ))*>,;/;-7 $ 9 9 )),,@/9-9 $ ; ; ))*@,;/;-7 $ 9 9 )).,B/9-; $ = = ))/,;/9-: $ < <1=DJ8 4 + + +'#-ua88@@&===$'CC,%+3KN3KN$ $ *(3.r::+.q99&==3SYBB"""0%;;/!!0%;;tr   FNN)r   r   r   r   r   r   r  r   r  r
  r7  RECTYPE
kAllRecordr?  rF  rW  r^  r`  ru  r  r   r   r    r  r    s       o 	 	G E E E ^EN    ^2    ^<    ^> e e e ^eN '>!(!3C C C C    ^* : : : ^:B, , ,# # #"' "' "'H < < < ^< < <r   r  c                       e Zd ZdZddZdS )	MythVideolegacy - do not useTc                 .    t                      \  }}}||fS )r  )ru  )r2   rq  rh  ri  rj  s        r    scanStorageGroupszMythVideo.scanStorageGroups]  s     *ugwr   NT)r   r   r   r   r  r   r   r    r  r  [  s.                   r   r  c                   b    e Zd ZdZddZd Zd ZddZddZd Z	d	 Z
ddZd Zd Z	 	 ddZdS )MythXMLz
    Provides convenient methods to access the backend XML server.
    Parameter 'backend' is either a hostname from 'settings',
    an ip address or a hostname in ip-notation.
    Nc                    |r!|rt          j        | ||           || _        d S t          |          | _        t	          d          | _        || j                                        }| j                            |          }|r%t          | j        j	        |         j
                  }n@| j                            |          }|}t          | j        j	        |         j
                  }t          ||          \  }}|st          t          j        |dz             |st          t          j        |dz             || _        || _        d S )NzPython XML Connectionz: BackendServerAddrz: BackendStatusPort)r   r   rG   r   r   rI   getMasterBackend_getpreferredaddrrL   r   BackendStatusPort_gethostfromaddrr   MythDBErrorrn   
DB_SETTINGr~   r   )r2   r   r   rG   r~   ro   reshostresports           r    r   zMythXML.__init__h  sQ    	t 	"4$777DGF"++233?g..00G w((11 	Etw'0BCCDD w//88HDtw'1CDDD &d400 	?i2 '(= =? ? ? 	?i2 '(= =? ? ?				r   c                 \    |                      d                                          d         S )z?Returns a list of unique hostnames found in the settings table.zMyth/GetHosts
StringList_requestreadJSONr1   s    r    getHostszMythXML.getHosts  s(    }}_--)1LB 	Br   c                 \    |                      d                                          d         S )z:Returns a list of unique keys found in the settings table.zMyth/GetKeysr  r  r1   s    r    getKeyszMythXML.getKeys  s(    }}^,,)1LB 	Br   c                 p    d|i}|r||d<   |r||d<    | j         di |                                d         S )z%Retrieves a setting from the backend.KeyHostNameDefaultMyth/GetSettingString)r  r  )r2   r   ro   defaultr  s        r    
getSettingzMythXML.getSetting  sX    c{ 	('D 	&%DOt}77$77)1H> 	>r   c              #     K   t          j        |          }t          j        |          }|                                                    dd          d         |                                                    dd          d         |dd}|r||d<   nd|d<    | j        di |                                }|d         d	         D ]:}|d
         D ]/}|d         |d<   t                              || j                  V  0;dS )zY
        Returns a list of Guide objects corresponding to the given time period.
        r  r5   r   r   )	StartTimeEndTimeStartChanIdDetailsNumOfChannelsGuide/GetProgramGuideProgramGuideChannelsProgramsChanIdN)r  )	r	   r   utcisoformatrsplitr  r  r2  fromJSONrG   )	r2   r$  r  	startchannumchanr  datchanprogs	            r    getProgramGuidezMythXML.getProgramGuide  s+      M),,	-((%2244;;CBB1E!..0077A>>qA'38 8  	($+D!!$'D!dm<<t<<EEGG'
3 	4 	4DZ( 4 4!%hXnnT473333334	4 	4r   c                     t          j        |          }||                                d}t          j         | j        di |                                d         | j                  S )zA
        Returns a Program object for the matching show.
        r  r  Guide/GetProgramDetailsr   rm   )r  )r	   r   r  r   r  r  r  rG   )r2   r'   r$  r  s       r    getProgramDetailszMythXML.getProgramDetails  sp     M),,	 y/E/E/G/GHH@@4@@XZZ	+7   	r   c                 T    |                      d|                                          S )z%Returns channel icon as a data stringzGuide/GetChannelIcon)r  )r  r  )r2   r'   s     r    getChannelIconzMythXML.getChannelIcon  s%    }}3F}CCHHJJJr   Tc              #      K   |rdnd}|                      d|                                          d         d         D ]}t          j        || j                  V  dS )zV
        Returns a list of Program objects for recorded shows on the backend.
        truefalsezDvr/GetRecordedList)
DescendingProgramListr  Nr  r  r   r  rG   )r2   
descendingdescendingstrr  s       r    getRecordedzMythXML.getRecorded  sv       #-9'MM"7MMRRXZZ//9; 	2 	2D"4111111	2 	2r   c              #      K   |                      d                                          d         d         D ]}t          j        || j                  V  dS )zV
        Returns a list of Program objects for expiring shows on the backend.
        zDvr/GetExpiringListr  r  Nr  )r2   r  s     r    r   zMythXML.getExpiring  sd       MM"788XZZ//9; 	2 	2D"4111111	2 	2r   c                 2    d| j         d| j        d|d|S )Nzmythflash://:z,/InternetContent/GetInternetContent?Grabber=z&videocode=)r~   r   )r2   grabber	videocodes      r    getInternetContentUrlzMythXML.getInternetContentUrl  s)     yyy$)))WWWii9 	9r   c                     t          j        |          }||                                d}|r||d<   |r||d<   |r||d<    | j        di |                                S )Nr  WidthHeightSecsInContent/GetPreviewImage)r  )r	   r   r  r  r  )r2   r'   r$  rM  rN  secsinr  s          r    getPreviewImagezMythXML.getPreviewImage  sx    M),,	Y-C-C-E-EFF'%$w-*F4>*F4>t}??$??DDFFFr   )NNN)NNr/   r  )r   r   r   r   r   r  r  r  r  r  r  r  r   r  r  r   r   r    r  r  b  s         
   BB B B
B B B
> > > >4 4 4 4(	 	 	K K K2 2 2 22 2 29 9 9 8<EIG G G G G Gr   r  c                   *    e Zd ZdZedd            ZdS )	MythMusiczN
    Provides convenient methods to access the MythTV MythMusic database.
    FNc                 8   |r_d|_         t          |_        |                    ddd          |                    ddd          |                    ddd          f|_        |d	v rd
|z  |dfS |dk    rd|dfS |dk    rd|dfS |dk    rd|dfS |dk    rd|dfS dS )z
        obj.searchMusic(**kwargs) -> iterable of Song objects

        Supports the following keywords:
            name,  track,  disc_number, artist,      album,   year
            genre, rating, format,      sample_rate, bitrate
        music_songsmusic_artists)	artist_idr  music_albums)album_idmusic_genres)genre_id)r#   trackdisc_numberr!  r5  sample_ratebitratero   zmusic_songs.%s=%%sr   artistzmusic_artists.artist_name=%sr5   albumzmusic_albums.album_name=%sr   r  zmusic_albums.year=%sr  zmusic_genres.genre=%sr  N)r  Songr  r  r  r  s       r    searchMusiczMythMusic.searchMusic  s	     	;&DJDL))/,9+9 $ ; ; )).,9+8 $ : : )).,9+8 $ : :;DJ  F F F(3.q99(??2E1=='>>0%;;&==*E155'>>+UA66 >r   r  )r   r   r   r   r   r  r   r   r    r  r    s>          7 7 7 ^7 7 7r   r  )-r   MythTV.staticMythTV.exceptionsMythTV.loggingr   MythTV.connectionsr   r   r   MythTV.utilityr   r	   r
   r   r   MythTV.databaser   r   MythTV.systemr   MythTV.mythprotor   r   r   r   r   MythTV.dataheapr   weakrefr   collectionsr   urllib.requestr   r  r   r"   r   r  r6  r  r  r  MusicSchemar  r   r   r    <module>r      s            " " " " " " M M M M M M M M M M W W W W W W W W W W W W W W + + + + + + + + % % % % % % L L L L L L L L L L L L L L                 " " " " " " " " " " " " 					 	 	 	 	6 	 	 	K! K! K! K! K!g K! K! K!Z3 3 3 3 3g 3 3 3$N< N< N< N< N<w N< N< N<`A A A A A A A AFL L L L Lg L L L\               @G @G @G @G @G} @G @G @GD$7 $7 $7 $7 $7g $7 $7 $7 $7 $7r   