Ticket #6885: pyth.updates3.patch

File pyth.updates3.patch, 20.0 KB (added by Raymond Wagner <raymond@…>, 15 years ago)
  • MythTV/MythVideo.py

     
    2727                if not host: # If a hostname was not supplied then use the local host name
    2828                        host = gethostname()
    2929
    30                 # Get storagegroup table field names
    31                 table_names = self.getTableFieldNames(u'storagegroup')
     30                ret = []
     31                for i in self.db.getStorageGroup('Videos',host):
     32                        ret.append(i['dirname'])
    3233
    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]))
     34                if ret:
     35                        return ret
     36                else:
    3937                        return None
    4038
    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 
    6739        def pruneMetadata(self):
    6840                """
    6941                Removes metadata from the database for files that no longer exist.
     
    11587                This function should have been called getCategoryId
    11688                """
    11789                c = self.db.cursor()
    118                 c.execute("SELECT intid FROM videocategory WHERE lower(category) = %s", (genre_name,))
     90                c.execute("""SELECT intid FROM videocategory
     91                                WHERE lower(category) = %s""", (genre_name,))
    11992                row = c.fetchone()
    12093                c.close()
    12194
     
    12497
    12598                # Insert a new genre.
    12699                c = self.db.cursor()
    127                 c.execute("INSERT INTO videocategory(category) VALUES (%s)", (genre_name.capitalize(),))
     100                c.execute("""INSERT INTO videocategory(category)
     101                                VALUES (%s)""", (genre_name.capitalize(),))
    128102                newid = c.lastrowid
    129103                c.close()
    130104
  • MythTV/MythTV.py

     
    207207                """
    208208                Returns a Program object for the current recorders recording.
    209209                """
    210                 res = self.backendCommand('QUERY_RECORDER %s[]:[]GET_CURRENT_RECORDING' % recorder)
     210                res = self.backendCommand('QUERY_RECORDER '+BACKEND_SEP.join([recorder,'GET_CURRENT_RECORDING']))
    211211                return Program(res.split(BACKEND_SEP))
    212212
    213213        def isRecording(self, recorder):
    214214                """
    215215                Returns a boolean as to whether the given recorder is recording.
    216216                """
    217                 res = self.backendCommand('QUERY_RECORDER %s[]:[]IS_RECORDING' % recorder)
     217                res = self.backendCommand('QUERY_RECORDER '+BACKEND_SEP.join([recorder,'IS_RECORDING']))
    218218                if res == '1':
    219219                        return True
    220220                else:
     
    224224                """
    225225                Returns a boolean as to whether the given host is an active backend
    226226                """
    227                 res = self.backendCommand('QUERY_IS_ACTIVE_BACKEND[]:[]%s' % hostname)
     227                res = self.backendCommand(BACKEND_SEP.join(['QUERY_IS_ACTIVE_BACKEND',hostname]))
    228228                if res == 'TRUE':
    229229                        return True
    230230                else:
     
    245245                Returns a list of all Program objects which have already recorded
    246246                """
    247247                programs = []
    248                 res = self.backendCommand('QUERY_RECORDINGS Play').split('[]:[]')
     248                res = self.backendCommand('QUERY_RECORDINGS Play').split(BACKEND_SEP)
    249249                num_progs = int(res.pop(0))
    250250                log.Msg(DEBUG, '%s total recordings', num_progs)
    251251                for i in range(num_progs):
     
    253253                                + PROGRAM_FIELDS]))
    254254                return tuple(programs)
    255255
     256        def getExpiring(self):
     257                """
     258                Returns a tuple of all Program objects nearing expiration
     259                """
     260                programs = []
     261                res = self.backendCommand('QUERY_GETEXPIRING').split(BACKEND_SEP)
     262                num_progs = int(res.pop(0))
     263                for i in range(num_progs):
     264                        programs.append(Program(res[i * PROGRAM_FIELDS:(i * PROGRAM_FIELDS)
     265                                + PROGRAM_FIELDS]))
     266                return tuple(programs)
     267
    256268        def getCheckfile(self,program):
    257269                """
    258270                Returns location of recording in file system
    259271                """
    260                 res = self.backendCommand('QUERY_CHECKFILE[]:[]1[]:[]%s' % program.toString()).split(BACKEND_SEP)
     272                res = self.backendCommand(BACKEND_SEP.join(['QUERY_CHECKFILE',1,program.toString()])).split(BACKEND_SEP)
    261273                if res[0] == 0:
    262274                        return None
    263275                else:
     
    271283                command = 'DELETE_RECORDING'
    272284                if force:
    273285                        command = 'FORCE_DELETE_RECORDING'
    274                 return self.backendCommand('%s%s%s' % (command,BACKEND_SEP,program.toString()))
     286                return self.backendCommand(BACKEND_SEP.join([command,program.toString()]))
    275287
    276288        def forgetRecording(self,program):
    277289                """
    278290                Forgets old recording and allows it to be re-recorded
    279291                """
    280                 self.backendCommand('FORGET_RECORDING%s%s' % (BACKEND_SEP,program.toString()))
     292                self.backendCommand(BACKEND_SEP.join(['FORGET_RECORDING',program.toString()]))
    281293
    282294        def deleteFile(self,file,sgroup):
    283295                """
    284296                Deletes a file from specified storage group on the connected backend
    285297                Takes a relative file path from the root of the storage group, and returns 1 on success
    286298                """
    287                 return self.backendCommand('DELETE_FILE%s%s%s%s' % (BACKEND_SEP,file,BACKEND_SEP,sgroup))
     299                return self.backendCommand(BACKEND_SEP.join(['DELETE_FILE',file,sgroup]))
    288300
    289301        def getFreeSpace(self,all=False):
    290302                """
     
    329341                res = self.backendCommand('QUERY_LOAD').split(BACKEND_SEP)
    330342                return (float(res[0]),float(res[1]),float(res[2]))
    331343
     344        def getUptime(self):
     345                """
     346                Returns machine uptime in seconds
     347                """
     348                return self.backendCommand('QUERY_UPTIME')
     349
    332350        def getSGList(self,host,sg,path):
    333351                """
    334352                Returns a tuple of directories and files
    335353                """
    336                 res = self.backendCommand('QUERY_SG_GETFILELIST%s%s%s%s%s%s' % (BACKEND_SEP,host,BACKEND_SEP,sg,BACKEND_SEP,path)).split(BACKEND_SEP)
     354                res = self.backendCommand(BACKEND_SEP.join(['QUERY_SG_GETFILELIST',host,sg,path])).split(BACKEND_SEP)
    337355                if res[0] == 'EMPTY LIST':
    338356                        return -1
    339357                if res[0] == 'SLAVE UNREACHABLE: ':
     
    352370                """
    353371                Returns a tuple of last modification time and file size
    354372                """
    355                 res = self.backendCommand('QUERY_SG_FILEQUERY%s%s%s%s%s%s' % (BACKEND_SEP,host,BACKEND_SEP,sg,BACKEND_SEP,path)).split(BACKEND_SEP)
     373                res = self.backendCommand(BACKEND_SEP.join(['QUERY_SG_FILEQUERY',host,sg,path])).split(BACKEND_SEP)
    356374                if res[0] == 'EMPTY LIST':
    357375                        return -1
    358376                if res[0] == 'SLAVE UNREACHABLE: ':
     
    382400                port = self.db.getSetting("NetworkControlPort",host)
    383401                return Frontend(host,port)
    384402
     403        def getLastGuideData(self):
     404                """
     405                Returns the last dat for which guide data is available
     406                On error, 0000-00-00 00:00 is returned
     407                """
     408                return self.backendCommand('QUERY_GUIDEDATATHROUGH')
     409
    385410        def joinInt(self,high,low):
    386411                """
    387412                Returns a single long from a pair of signed integers
     
    458483                        if res[0] == 'REJECT':
    459484                                log.Msg(CRITICAL, 'Backend has version %s and we speak version %s', res[1], PROTO_VERSION)
    460485                                sys.exit(1)
    461                         res = self.send('ANN FileTransfer %s %d %d %d%s%s%s%s' % (socket.gethostname(), write, False, -1, BACKEND_SEP, self.filename, BACKEND_SEP, self.sgroup))
     486                        res = self.send('ANN FileTransfer %s %d %d %s' % (socket.gethostbyname(),write, False, BACKEND_SEP.join([-1,self.filename,self.sgroup])))
    462487                        if res.split(BACKEND_SEP)[0] != 'OK':
    463488                                log.Msg(CRITICAL, 'Unexpected answer to ANN command: %s', res)
    464489                        else:
     
    474499
    475500        def __del__(self):
    476501                if self.sockno:
    477                         self.comsock.backendCommand('QUERY_FILETRANSFER %d%sDONE' % (self.sockno, BACKEND_SEP))
     502                        self.comsock.backendCommand('QUERY_FILETRANSFER '+BACKEND_SEP.join([self.sockno, 'JOIN']))
    478503                if self.datsock:
    479504                        self.datsock.shutdown(1)
    480505                        self.datsock.close()
     
    533558                        csize = self.tsize
    534559                        rsize = size - csize
    535560                       
    536                 res = self.comsock.backendCommand('QUERY_FILETRANSFER %d%sREQUEST_BLOCK%s%d' % (self.sockno,BACKEND_SEP,BACKEND_SEP,csize))
     561                res = self.comsock.backendCommand('QUERY_FILETRANSFER '+BACKEND_SEP.join([self.sockno,'REQUEST_BLOCK',csize]))
    537562                self.pos += int(res)
    538563#               if int(res) == csize:
    539564#                       if csize < size:
     
    561586                        buff = data[size:]
    562587                        data = data[:size]
    563588                self.pos += int(self.datsock.send(data))
    564                 self.comsock.backendCommand('QUERY_FILETRANSFER %d%sWRITE_BLOCK%s%d' % (self.sockno,BACKEND_SEP,BACKEND_SEP,size))
     589                self.comsock.backendCommand('QUERY_FILETRANSFER '+BACKEND_SEP.join([self.sockno,'WRITE_BLOCK',size]))
    565590                self.write(buff)
    566591                return
    567592                       
     
    593618                curhigh,curlow = self.comsock.splitInt(self.pos)
    594619                offhigh,offlow = self.comsock.splitInt(offset)
    595620
    596                 res = self.comsock.backendCommand('QUERY_FILETRANSFER %d%sSEEK%s%d%s%d%s%d%s%d%s%d' % (self.sockno, BACKEND_SEP,BACKEND_SEP,offhigh,BACKEND_SEP,offlow,BACKEND_SEP,whence,BACKEND_SEP,curhigh,BACKEND_SEP,curlow)).split(BACKEND_SEP)
     621                res = self.comsock.backendCommand('QUERY_FILETRANSFER '+BACKEND_SEP.join([self.sockno,'SEEK',offhigh,offlow,whence,curhigh,curlow])).split(BACKEND_SEP)
    597622                self.pos = (int(res[0]) + (int(res[1])<0))*2**32 + int(res[1])
    598623
    599624
     
    885910
    886911                return string
    887912
     913        def setField(self,field,value):
     914                db = MythDB()
     915                c = db.cursor()
     916                c.execute("""UPDATE recorded SET %s = %%s
     917                                WHERE chanid=%%s and starttime=%%s""" % field,
     918                                (value,self.chanid,self.starttime))
     919                c.close()
     920
     921        def setBasename(self,name):
     922                """
     923                Change the file basename pointed to by the recording
     924                """
     925                self.setField('basename',name)
     926
     927        def setHostname(self,name):
     928                """
     929                Change the hostname of the machine which holds the recording
     930                """
     931                self.setField('hostname',name)
     932
     933        def setSG(self,name):
     934                """
     935                Change the storagegroup which holds the recording
     936                """
     937                self.setField('storagegroup',name)
     938
    888939if __name__ == '__main__':
    889940        banner = '\'m\' is a MythTV instance.'
    890941        try:
  • MythTV/MythDB.py

     
    9696                        raise MythError('Unable to find MythTV configuration file')
    9797
    9898                try:
    99                         self.db = MySQLdb.connect(user=dbconn['user'], host=dbconn['host'], passwd=dbconn['pass'], db=dbconn['name'], use_unicode=True, charset='utf8')
    100                         log.Msg(INFO, 'DB Connection info (host:%s, name:%s, user:%s, pass:%s)', dbconn['host'], dbconn['name'], dbconn['user'], dbconn['pass'])
     99                        self.db = MySQLdb.connect(user=dbconn['user'], host=dbconn['host'],
     100                                        passwd=dbconn['pass'], db=dbconn['name'], use_unicode=True,
     101                                        charset='utf8')
     102                        log.Msg(INFO, 'DB Connection info (host:%s, name:%s, user:%s, pass:%s)',
     103                                        dbconn['host'], dbconn['name'], dbconn['user'], dbconn['pass'])
    101104                except:
    102                         raise MythError('Connection failed for \'%s\'@\'%s\' to database %s using password %s' % (dbconn['user'], dbconn['host'], dbconn['name'], dbconn['pass']))
     105                        raise MythError('Connection failed for \'%s\'@\'%s\' to database %s using password %s' %
     106                                (dbconn['user'], dbconn['host'], dbconn['name'], dbconn['pass']))
    103107
    104108        def getAllSettings(self, hostname=None):
    105109                """
     
    119123                        c.execute("""
    120124                                        SELECT value, data
    121125                                        FROM settings
    122                                         WHERE hostname LIKE('%s%%')""" %
     126                                        WHERE hostname LIKE(%s)""",
    123127                                        (hostname))
    124128                rows = c.fetchall()
    125129                c.close()
     
    142146                        c.execute("""
    143147                                        SELECT data
    144148                                        FROM settings
    145                                         WHERE value LIKE('%s') AND hostname IS NULL LIMIT 1""" %
     149                                        WHERE value LIKE(%s) AND hostname IS NULL LIMIT 1""",
    146150                                        (value))
    147151                else:
     152                        hostname += '%'
    148153                        c.execute("""
    149154                                        SELECT data
    150155                                        FROM settings
    151                                         WHERE value LIKE('%s') AND hostname LIKE('%s%%') LIMIT 1""" %
     156                                        WHERE value LIKE(%s) AND hostname LIKE(%s) LIMIT 1""",
    152157                                        (value, hostname))
    153158                row = c.fetchone()
    154159                c.close()
     
    166171                c = self.db.cursor()
    167172                ws = None
    168173                ss = None
     174                t = None
    169175
    170176                if hostname is None:
    171                         ws = "WHERE value LIKE ('%s') AND hostname IS NULL" % (value)
    172                         ss = "(value,data) VALUES ('%s','%s')" % (value, data)
     177                        ws = "WHERE value LIKE (%s) AND hostname IS NULL"
     178                        ss = "(data,value) VALUES (%s,%s)"
     179                        t = (data,value)
    173180                else:
    174                         ws = "WHERE value LIKE ('%s') AND hostname LIKE ('%s%%')" % (value, hostname)
    175                         ss = "(value,data,hostname) VALUES ('%s','%s','%s')" % (value, data, hostname)
     181                        hostname += '%'
     182                        ws = "WHERE value LIKE (%s) AND hostname LIKE (%s)"
     183                        ss = "(data,value,hostname) VALUES (%s,%s,%s)"
     184                        t = (data,value,hostname)
    176185
    177                 if c.execute("""UPDATE settings SET data %s LIMIT 1""" % ws) == 0:
    178                         c.execute("""INSERT INTO settings %s""" % ss)
     186                if c.execute("""UPDATE settings SET data=%%s %s LIMIT 1""" % ws, t) == 0:
     187                        c.execute("""INSERT INTO settings %s""" % ss, t)
    179188                c.close()
    180189
    181190        def getCast(self, chanid, starttime, roles=None):
     
    187196                """
    188197                if roles is None:
    189198                        c = self.db.cursor()
    190                         length = c.execute("SELECT name,role FROM people,credits WHERE people.person=credits.person AND chanid=%d AND starttime=%d ORDER BY role" % (chanid, starttime))
     199                        length = c.execute("""SELECT name,role
     200                                        FROM people,credits
     201                                        WHERE people.person=credits.person
     202                                        AND chanid=%s AND starttime=%s
     203                                        ORDER BY role""", (chanid, starttime))
    191204                        if length == 0:
    192205                                return ()
    193206                        crole = None
     
    208221                        return dict
    209222                elif isinstance(roles,str):
    210223                        c = self.db.cursor()
    211                         length = c.execute("SELECT name FROM people,credits WHERE people.person=credits.person AND chanid=%d AND starttime=%d AND role='%s'" % (chanid, starttime, roles))
     224                        length = c.execute("""SELECT name
     225                                        FROM people,credits
     226                                        WHERE people.person=credits.person
     227                                        AND chanid=%s AND starttime=%s
     228                                        AND role=%s""", (chanid, starttime, roles))
    212229                        if length == 0:
    213230                                return ()
    214231                        names = []
     
    217234                        return tuple(names)
    218235                elif isinstance(roles,tuple):
    219236                        c = self.db.cursor()
    220                         length = c.execute("SELECT name FROM people,credits WHERE people.person=credits.person AND chanid=%d AND starttime=%d AND role IN %s" % (chanid, starttime, roles))
     237                        length = c.execute("""SELECT name
     238                                        FROM people,credits
     239                                        WHERE people.person=credits.person
     240                                        AND chanid=%d AND starttime=%d
     241                                        AND role IN %s""" % (chanid, starttime, roles))
    221242                        if length == 0:
    222243                                return ()
    223244                        names = []
     
    225246                                names.append(name[0])
    226247                        return tuple(names)
    227248
     249        def getStorageGroup(self, group=None, host=None):
     250                """
     251                Returns tuple of dictionaries containing storage group directories
     252                        with the fields 'id', 'group', 'host', and 'dirname'
     253                Takes an optional group and host for filtering
     254                """
     255                c = self.db.cursor()
     256                q1 = 'SELECT * FROM storagegroup'
     257                q2 = 'ORDER BY id'
     258                if host:
     259                        host += '%'
     260                if group and host:
     261                        c.execute("""%s
     262                                WHERE groupname=%%s
     263                                AND hostname like %%s
     264                                %s""" % (q1,q2), (group, host))
     265                elif group:
     266                        c.execute("""%s
     267                                WHERE groupname=%%s
     268                                %s""" % (q1,q2), (group,))
     269                elif host:
     270                        c.execute("""%s
     271                                WHERE hostname like %%s
     272                                %s""" % (q1,q2), (host,))
     273                else:
     274                        c.execute("""%s %s""" % (q1,q2))
     275                ret = []
     276                for i in c.fetchall():
     277                        if not i[3][-1] == '/':
     278                                i[3] += '/'
     279                        ret.append({'id':i[0], 'group':i[1], 'host':i[2], 'dirname':i[3]})
     280                return tuple(ret)
     281
     282        def getChannels(self):
     283                """
     284                Returns a tuple of channel object defined in the database
     285                """
     286                channels = []
     287                c = self.db.cursor()
     288                c.execute("""SELECT * FROM channel""")
     289                for row in c.fetchall():
     290                        channels.append(Channel(row))
     291                c.close()
     292                return tuple(channels)
     293
     294        def getChannel(self,chanid):
     295                """
     296                Returns a single channel object for the given chanid
     297                """
     298                c = self.db.cursor()
     299                if c.execute("""SELECT * FROM channel
     300                                WHERE chanid=%s""", (chanid,)):
     301                        return Channel(c.fetchone())
     302                else:
     303                        return None
     304
     305        def getGuideData(self, chanid, date):
     306                """
     307                Returns tuple of guide data for one channel on one date
     308                """
     309                guide = []
     310                c = self.db.cursor()
     311                c.execute("""SELECT * FROM program
     312                                WHERE chanid=%s AND DATE(starttime)=%s""",
     313                                (chanid,date))
     314                for show in c.fetchall():
     315                        guide.append(Guide(show))
     316                c.close()
     317                return tuple(guide)
     318
    228319        def cursor(self):
    229320                return self.db.cursor()
    230321
     
    251342                if self.mythdb is None:
    252343                        self.mythdb = MythDB()
    253344                c = self.mythdb.cursor()
    254                 c.execute("SELECT chanid,starttime FROM jobqueue WHERE id=%d" % self.jobid)
     345                c.execute("""SELECT chanid,starttime FROM jobqueue
     346                                WHERE id=%s""", (self.jobid))
    255347                self.chanid, self.starttime = c.fetchone()
    256348                c.close()
    257349
     
    260352                        self.mythdb = MythDB()
    261353                if self.jobid is None:
    262354                        c = self.mythdb.cursor()
    263                         c.execute("SELECT id FROM jobqueue WHERE chanid=%d AND starttime=%d" % (self.chanid, self.starttime))
     355                        c.execute("""SELECT id FROM jobqueue
     356                                        WHERE chanid=%s AND starttime=%s""",
     357                                        (self.chanid, self.starttime))
    264358                        self.jobid = c.fetchone()[0]
    265359                        c.close()
    266360                return self.jobid
     
    270364                        self.mythdb = MythDB()
    271365                if self.host is None:
    272366                        c = self.mythdb.cursor()
    273                         c.execute("SELECT hostname FROM jobqueue WHERE id=%d" % self.jobid)
     367                        c.execute("""SELECT hostname FROM jobqueue
     368                                        WHERE id=%s""", (self.jobid))
    274369                        self.host = c.fetchone()[0]
    275370                        c.close()
    276371                return self.host
     
    279374                if self.mythdb is None:
    280375                        self.mythdb = MythDB()
    281376                c = self.mythdb.cursor()
    282                 c.execute("UPDATE jobqueue SET comment='%s' WHERE id=%d" % (comment,self.jobid))
     377                c.execute("""UPDATE jobqueue SET comment=%s
     378                                WHERE id=%s""", (comment,self.jobid))
    283379                c.close()
    284380
    285381        def setStatus(self,status):
    286382                if self.mythdb is None:
    287383                        self.mythdb = MythDB()
    288384                c = self.mythdb.cursor()
    289                 c.execute("UPDATE jobqueue SET status=%d WHERE id=%d" % (status,self.jobid))
     385                c.execute("""UPDATE jobqueue SET status=%s
     386                                WHERE id=%s""", (status,self.jobid))
    290387                c.close()
    291388
     389class Channel:
     390        """
     391        Represents a single channel from the channel table
     392        """
     393        def __str__(self):
     394                return "%s (%s)" % (self.chanid, self.name)
     395
     396        def __repr__(self):
     397                return "%s (%s)" % (self.chanid, self.name)
     398
     399        def __init__(self,data):
     400                """
     401                Load data into object
     402                """
     403                self.chanid = data[0]
     404                self.channum = data[1]
     405                self.freqid = data[2]
     406                self.sourceid = data[3]
     407                self.callsign = data[4]
     408                self.name = data[5]
     409                self.icon = data[6]
     410                self.finetune = data[7]
     411                self.videofilters = data[8]
     412                self.xmltvid = data[9]
     413                self.recpriority = data[10]
     414                self.contrast = data[11]
     415                self.brightness = data[12]
     416                self.colour = data[13]
     417                self.hue = data[14]
     418                self.tvformat = data[15]
     419                self.visible = data[16]
     420                self.outputfiters = data[17]
     421                self.useonairguide = data[18]
     422                self.mplexid = data[19]
     423                self.serviceid = data[20]
     424                self.tmoffset = data[21]
     425                self.atsc_major_chan = data[22]
     426                self.atsc_minor_chan = data[23]
     427                self.last_record = data[24]
     428                self.default_authority = data[25]
     429                self.commmethod = data[26]
     430
     431class Guide:
     432        """
     433        Represents a single program from the program guide
     434        """
     435        def __str__(self):
     436                return "%s (%s)" % (self.title, self.starttime.strftime('%Y-%m-%d %H:%M:%S'))
     437
     438        def __repr__(self):
     439                return "%s (%s)" % (self.title, self.starttime.strftime('%Y-%m-%d %H:%M:%S'))
     440
     441        def __init__(self,data):
     442                """
     443                Load data into the object
     444                """
     445                self.chanid = data[0]
     446                self.starttime = data[1]
     447                self.endtime = data[2]
     448                self.title = data[3]
     449                self.subtitle = data[4]
     450                self.description = data[5]
     451                self.category = data[6]
     452                self.category_type = data[7]
     453                self.airdate = data[8]
     454                self.stars = data[9]
     455                self.previouslyshown = data[10]
     456                self.title_pronounce = data[11]
     457                self.stereo = data[12]
     458                self.subtitled = data[13]
     459                self.hdtv = data[14]
     460                self.closecaptioned = data[15]
     461                self.partnumber = data[16]
     462                self.parttotal = data[17]
     463                self.seriesid = data[18]
     464                self.originalairdate = data[19]
     465                self.showtype = data[20]
     466                self.colorcode = data[21]
     467                self.syndicatedepisodenumber = data[22]
     468                self.programid = data[23]
     469                self.manualid = data[24]
     470                self.generic = data[25]
     471                self.listingsource = data[26]
     472                self.first = data[27]
     473                self.last = data[28]
     474                self.audioprop = data[29]
     475                self.subtitletypes = data[30]
     476                self.videoprop = data[31]
     477
    292478if __name__ == '__main__':
    293479        banner = "'mdb' is a MythDB instance."
    294480        try: