Ticket #6440: MythVideo_SG_compliant.patch

File MythVideo_SG_compliant.patch, 8.3 KB (added by r.d.vaughan@…, 15 years ago)

MythVideo?.py binding - Storage Group compliance

  • mythtv/bindings/python/MythTV/MythVideo.py

     
    55
    66from MythDB import *
    77from MythLog import *
     8from socket import gethostname
    89
    910log = MythLog(CRITICAL, '#%(levelname)s - %(message)s', 'MythVideo')
    1011
     
    1819                """
    1920                self.db = MythDB()
    2021
     22        def rtnVideoStorageGroup(self, host=None):
     23                '''Get the storage group 'Videos' directory for the suppied host name or default to the localhost.
     24                return None if no Videos Storage Group found
     25                return dirname field
     26                '''
     27                if not host: # If a hostname was not supplied then use the local host name
     28                        host = gethostname()
     29
     30                # Get storagegroup table field names
     31                table_names = self.getTableFieldNames(u'storagegroup')
     32
     33                cur = self.db.cursor()
     34                # Check is there are storage groups for the supplied host or default to the local host
     35                try:
     36                        cur.execute(u"select * from storagegroup")
     37                except MySQLdb.Error, e:
     38                        log.Msg(INFO, u"! Error: Reading storagegroup MythTV table: %d: %s\n" % (e.args[0], e.args[1]))
     39                        return None
     40
     41                videos_dir = []
     42                while True:
     43                        data_id = cur.fetchone()
     44                        if not data_id:
     45                                break
     46                        record = {}
     47                        i = 0
     48                        for elem in data_id:
     49                                if table_names[i] == 'groupname' or table_names[i] == 'hostname' or table_names[i] == 'dirname':
     50                                        record[table_names[i]] = elem
     51                                i+=1
     52                        if record['hostname'].lower() == host.lower() and record['groupname'] == u'Videos':
     53                                # Add a slash if mussing to any storage group dirname
     54                                if record['dirname'][-1:] == '/':
     55                                        videos_dir.append(record['dirname'])
     56                                else:
     57                                        videos_dir.append(record['dirname']+u'/')
     58                        continue
     59                cur.close()
     60
     61                if not len(videos_dir):
     62                        return None
     63
     64                return videos_dir
     65        # end getStorageGroups
     66
    2167        def pruneMetadata(self):
    2268                """
    23                 Removes metadata from the database for files that no longer exist.
     69                Removes metadata from the database for files that no longer exist.
     70                Respects 'Videos' storage groups and relative paths.
    2471                """
     72                host = gethostname() # Pruning can only be done for local files therefore the local host forced
     73                host = host.lower() # Required as videometadata stores lowercase hostname unlike other db tables
     74                vid_sg = self.rtnVideoStorageGroup(host) # Get the 'Videos' storage groups directory for a host
     75
    2576                c = self.db.cursor()
    26                 c.execute("""
    27                                 SELECT intid, filename
     77                c.execute(u"""
     78                                SELECT intid, filename, host
    2879                                FROM videometadata""")
    2980
    30                 row = c.fetchone()
    31                 while row is not None:
     81                while True:
     82                        row = c.fetchone()
     83                        if not row:
     84                                break
    3285                        intid = row[0]
    3386                        filename = row[1]
    34                         if not os.path.exists(filename):
    35                                 log.Msg(INFO, '%s not exist, removing metadata...', filename)
     87                        hostname = row[2]
     88                        filename_array = []
     89                        if vid_sg == None: # If no 'Videos' storagegroups process only filenames with an absolute path
     90                                if filename[0] != u'/':  # Skip any video filenames with relative path
     91                                        continue
     92                                filename_array.append(filename)
     93                        else:   # If this localhost has a 'Videos' storagegroup process only filenames
     94                                        # with a relative path and belongs to this localhost
     95                                if filename[0] == u'/':
     96                                        continue
     97                                if hostname != host:
     98                                        continue
     99                                for sg in vid_sg: # Handle multiple Videos SGs for one backend
     100                                        filename_array.append(sg+filename) # Make an absolute path from a SG and relative path
     101                        for filename in filename_array:
     102                                if os.path.exists(filename): # Handle multiple Videos SGs for one backend
     103                                        break
     104                        else:
     105                                log.Msg(INFO, u'%s not exist, removing metadata...', filename)
    36106                                c2 = self.db.cursor()
    37                                 c2.execute("""DELETE FROM videometadata WHERE intid = %s""", (intid,))
     107                                c2.execute(u"""DELETE FROM videometadata WHERE intid = %s""", (intid,))
    38108                                c2.close()
    39109                                #Some additional cleanup
    40110                                #Remove cross-references in cast, country, genres
    41111                                self.cleanGenres(intid)
    42112                                self.cleanCountry(intid)
    43113                                self.cleanCast(intid)
    44                                
    45                         row = c.fetchone()
    46114                c.close()
    47115
     116
    48117        def getGenreId(self, genre_name):
    49118                """
    50119                Find the id of the given genre from MythDB.
     
    74143
    75144                If the cast does not exist, insert it and return its id.
    76145                """
    77                 return self.setFieldId('cast', cast_name)
     146                return self.getFieldId('cast', cast_name)
    78147
    79148        def setCast(self, cast_name, idvideo):
    80149                """
     
    85154
    86155                return self.setField('cast', cast_name, idvideo)
    87156
    88         def getMetadataId(self, videopath):
     157        def getMetadataId(self, videopath, host=None):
    89158                """
    90                 Insert the idvideo file in given cast list if it does already exist.
    91                 Cast will be created if it doesn't exist return its id.
     159                Finds the MythVideo metadata id for the given video path from the MythDB, if any.
     160                Returns None if no metadata was found.
    92161                """
     162                mysqlcommand = u'SELECT intid FROM videometadata WHERE filename=%s'
     163                if host != None and videopath[0] != '/':
     164                        mysqlcommand+=u' AND host=%s'
     165                else:
     166                        host = None
    93167                c = self.db.cursor()
    94                 c.execute("""
    95                                 SELECT intid
    96                                 FROM videometadata
    97                                 WHERE filename = %s""", (videopath,))
     168                if host:
     169                        c.execute(mysqlcommand, (videopath, host))
     170                else:
     171                        c.execute(mysqlcommand, (videopath,))
    98172                row = c.fetchone()
    99173                c.close()
    100174
     
    103177                else:
    104178                        return None
    105179
    106         def getTitleId(self, title, subtitle=None, season=None, episode=None, array=False):
     180        def getTitleId(self, title, subtitle=None, season=None, episode=None, array=False, host=None):
    107181                """
    108182                Finds the MythVideo metadata id for the given Title from the MythDB, if any.
    109                 Searches can be more specific if additional fields are supplied.
     183                Searches consider storage groups if a host is supplied
     184                Searches can be more specific if additional fields supplied.
    110185                If array is True return an array of intid's for the record(s) matching the search criteria.
    111186                Without the array option a search with multiple matches will return a random result if more
    112187                than one match was found. Non-array     return results are only supported for backward compatibilty
     
    114189               
    115190                Returns None if no metadata was found.
    116191                """
     192                if host: # Get the 'Videos' storage groups directory for a host
     193                        if self.rtnVideoStorageGroup(host):
     194                                # Required as videometadata stores lowercase hostname unlike other db tables
     195                                host2 = host.lower()
     196                        else:
     197                                host2 = None # If there is no storage group for a specific host then host is irrelevant
     198                else:
     199                        host2 = None
     200
    117201                tablenames = self.getTableFieldNames('videometadata')
    118202
    119203                mysqlcommand = u"SELECT intid FROM videometadata WHERE title = %s"
     
    122206                # Make sure all the additional query fields are actually in the videometadata schema
    123207                if subtitle and 'subtitle' in tablenames:
    124208                        mysqlcommand+=u" AND subtitle=%s" % subtitle
    125                 if not season == None and 'season' in tablenames:
     209                if season != None and 'season' in tablenames:
    126210                        mysqlcommand+=u" AND season=%d" % int(season)
    127                 if not episode == None and 'episode' in tablenames:
     211                if episode != None and 'episode' in tablenames:
    128212                        mysqlcommand+=u" AND episode=%d" % int(episode)
     213                if host2 != None and 'host' in tablenames:
     214                        mysqlcommand+=u" AND host=%s"
    129215
    130216                c = self.db.cursor()
    131                 c.execute(mysqlcommand, (title,))
     217                if host2 != None:
     218                        c.execute(mysqlcommand, (title, host2))
     219                else:
     220                        c.execute(mysqlcommand, (title,))
    132221                intids=[]
    133222                while True:
    134223                        row = c.fetchone()
     
    147236                else:
    148237                        return None
    149238
    150         def hasMetadata(self, videopath):
     239        def hasMetadata(self, videopath, host=None):
    151240                """
    152241                Determines if the given videopath has any metadata in the DB
    153242
    154243                Returns False if no metadata was found.
    155244                """
    156                 c = self.db.cursor()
    157                 c.execute("""
    158                                 SELECT category, year
    159                                 FROM videometadata
    160                                 WHERE filename = %s""", (videopath,))
    161                 row = c.fetchone()
    162                 c.close()
     245                intid = self.getMetadataId(videopath, host)
     246                if not intid:
     247                        return False
     248                metadata = self.getMetadataDictionary(intid)
     249                if not metadata:
     250                        return False
    163251
    164                 if row is not None:
    165                         # If category is 0 and year is 1895, we can safely assume no metadata
    166                         if (row[0] == 0) and (row[1] == 1895):
    167                                 return False
    168                         else:
    169                                 return True
     252                if (metadata['category'] == 0) and (metadata['year'] == 1895):
     253                        return False
    170254                else:
    171                         return False
     255                        return True
    172256
     257
    173258        def getMetadata(self, id):
    174259                """
    175260                Finds the MythVideo metadata for the given id from the MythDB, if any.