コード例 #1
0
def transcode(jobid=None, chanid=None, starttime=None):
        ' connect to mythtv database '
        db = MythDB()
        be = MythBE(db=db)

	logging.info("start transcode")

	if jobid:
		job = Job(jobid, db=db)
		chanid = job.chanid
		starttime = job.starttime
		logging.info("%s" % jobid)
		logging.info("%s" % chanid)
		logging.info("%s" % starttime)
	rec = Recorded((chanid, starttime), db=db)
	' TODO: get the starttime into the correct format (from 20150827014200 to 2015-08-27 00:42:00-06:00)'

	' loop all files in lib_dir that are symlinks and find the one that matches this recording '
        for ld in LIBDIR:
                for dp, dn, files in os.walk(ld):
                        for file in files:
                                filepath = os.path.join(dp,file)
                                if (os.path.islink(filepath)):
                                        logging.debug("%s -> %s" % (filepath, os.readlink(filepath)))

	' do the transode '

	' update the database for the new file name '

	' update the symlink for the new file name '
コード例 #2
0
 def __init__(self):
     self.db = MythDB()
     self.be = MythBE(db=db)
     self.vids = {}
     self._addCallback = doNothing
     self._events = [self.handleUpdate]
     self.be.registerevent(self.handleUpdate)
コード例 #3
0
    def __init__(self, host=None):
        self.db = MythDB()
        self.db.searchRecorded.handler = Recorded
        self.be = MythBE(db=self.db)
        self.log = MythLog(db=self.db)

        self.set_host(host)
        self.load_backends()
        self.load_storagegroups()
コード例 #4
0
    def test_repr_004_01(self):
        """
        Test '__repr__' and '__str__' methods of 'MythBE' class.
        Note: MythBE inherits from 'FileOps', which is inherited from 'BeCache'.
        """

        db = MythDB()
        be = MythBE(db=db)
        print()
        print(repr(be))
        print(str(be))
コード例 #5
0
 def checkRecordingStatus(self):
     """Checks whether the backend is currently recording."""
     try:
         recbe = MythBE()
         for recorder in recbe.getRecorderList():
             if recbe.isRecording(recorder):
                 self.isrecording = True
                 break
     except:
         # If we can't connect to it then it can't be recording.
         self.isrecording = False
コード例 #6
0
 def load_backends(self):
     with self.db as c:
         c.execute("""SELECT hostname FROM settings
                      WHERE value='BackendServerIP'""")
         hosts = [r[0] for r in c.fetchall()]
     self.hosts = []
     for host in hosts:
         # try to access all defined hosts, and
         # store the ones currently accessible
         try:
             MythBE(backend=host)
             self.hosts.append(host)
         except:
             pass
コード例 #7
0
 def getRecordings(self):
     """Attempts to connect to MythTV backend and retrieve recordings."""
     try:
         # If we can connect then get recordings and save a local cache.
         self.be = MythBE()
         uprecs = self.be.getUpcomingRecordings()
         self.recs = self.recs_to_dict(uprecs)
         self.cacheRecs(self.recs)
         self.backendonline = True
     except:
         # Can't connect so we need to set variables accordinly and try
         # to load data from the cache.
         self.be = None
         self.recs = self.loadCache()
         self.backendonline = False
コード例 #8
0
def main():
    """Startup function."""
    parser = OptionParser(usage="usage: %prog [options]")
    parser.add_option("--verbose",
                      action="store_true",
                      default=False,
                      help="enable verbose output of MythTV API")
    parser.add_option(
        '-f',
        "--force",
        action="store_true",
        default=False,
        help="non-interactive mode, answer 'yes' to all questions")
    parser.add_option('-t',
                      "--title",
                      action="store",
                      type="string",
                      help="limit recordings that match title")

    opts, _ = parser.parse_args()
    MythLog._setlevel('unknown' if opts.verbose else 'err')  # pylint:disable=protected-access

    try:
        backend = MythBE()
        recs = [
            r for r in list(backend.getRecordings()) if r.recgroup == 'Deleted'
        ]
        if opts.title:
            recs = [
                r for r in recs
                if re.findall(opts.title, r.title, re.IGNORECASE)
            ]
        if len(recs) == 0:
            print('no matching recordings found')
            sys.exit(0)
        if opts.force:
            undelete_all(backend, recs)
        else:
            interactive_undelete(backend, recs)
    except MythDBError as e:
        if e.name == 'DB_CREDENTIALS':
            print("ERROR: Could not find MythDB host:port OR correct login "
                  "credentials!")
            sys.exit(-1)
        else:
            raise
    sys.exit(0)
コード例 #9
0
def main(opts):
    MythBE.getPendingRecordings.handler = MyProgram
    be = MythBE()
    now = datetime.now()

    if not opts.plaintext:
        print '<h3>Upcoming Recordings:</h3>'
        print '<div class="schedule">'

    count = 0
    for rec in be.getPendingRecordings():
        if not ((opts.filter & 2**0 and rec.is_scheduled) or
                (opts.filter & 2**1 and rec.is_duplicate) or
                (opts.filter & 2**2 and rec.is_deactivated) or
                (opts.filter & 2**3 and rec.is_conflict)):
            continue
        if opts.time and (opts.time < rec.recstartts):
            continue
        if now > rec.recendts:
            continue
        if opts.count and (opts.count <= count):
            break
        count += 1

        if opts.plaintext:
            print '{0} - {1}'.format(rec.starttime.strftime('%m/%d, %I:%M %p'),
                                     rec.callsign)
            if rec.subtitle:
                print '{0.title} - {0.subtitle}'.format(rec)
            else:
                print '{0.title}'.format(rec)
            print rec.description
            print ''
        else:
            print '<a href="#">{0} - {1} - {2}'.format(
                rec.starttime.strftime('%m/%d, %I:%M %p'), rec.callsign,
                rec.title),
            if rec.subtitle:
                print rec.subtitle,
            print '<br /><span><strong>{0.title}</strong>'.format(rec),
            print rec.starttime.strftime('%m/%d, %I:%M %p'),
            print '<br /><em>{0.description}<br/></span></a><hr />'

    if not opts.plaintext:
        print '</div>'
コード例 #10
0
    def __init__(self, opts, jobid=None):

        # Setup for the job to run
        if jobid:
            self.thisJob = Job(jobid)
            self.chanID = self.thisJob.chanid
            self.startTime = self.thisJob.starttime
            self.thisJob.update(status=Job.STARTING)

        # If no job ID given, must be a command line run
        else:
            self.thisJob = jobid
            self.chanID = opts.chanid
            self.startTime = opts.startdate + " " + opts.starttime + opts.offset
        self.opts = opts
        self.type = "none"
        self.db = MythDB()
        self.log = MythLog(module='Myth-Rec-to-Vid.py', db=self.db)

        # Capture the backend host name
        self.host = self.db.gethostname()

        # prep objects
        self.rec = Recorded((self.chanID, self.startTime), db=self.db)
        self.log(
            MythLog.GENERAL, MythLog.INFO, 'Using recording',
            '%s - %s' % (self.rec.title.encode('utf-8'),
                         self.rec.subtitle.encode('utf-8')))

        self.vid = Video(db=self.db).create({
            'title': '',
            'filename': '',
            'host': self.host
        })

        self.bend = MythBE(db=self.db)
コード例 #11
0
    def copy(self):
        stime = time.time()
        srcsize = self.rec.filesize
        htime = [stime, stime, stime, stime]

        self.log(MythLog.GENERAL|MythLog.FILE, MythLog.INFO, "Copying myth://%s@%s/%s"\
               % (self.rec.storagegroup, self.rec.hostname, self.rec.basename)\
                                                    +" to myth://Videos@%s/%s"\
                                          % (self.vid.host, self.vid.filename))
        srcfp = self.rec.open('r')
        dstfp = self.vid.open('w', nooverwrite=True)

        if self.job:
            self.job.setStatus(Job.RUNNING)
        tsize = 2**24
        while tsize == 2**24:
            tsize = min(tsize, srcsize - dstfp.tell())
            dstfp.write(srcfp.read(tsize))
            htime.append(time.time())
            rate = float(tsize * 4) / (time.time() - htime.pop(0))
            remt = (srcsize - dstfp.tell()) / rate
            if self.job:
                self.job.setComment("%02d%% complete - %d seconds remaining" %\
                            (dstfp.tell()*100/srcsize, remt))
        srcfp.close()
        dstfp.close()

        self.vid.hash = self.vid.getHash()

        self.log(MythLog.GENERAL | MythLog.FILE, MythLog.INFO,
                 "Transfer Complete",
                 "%d seconds elapsed" % int(time.time() - stime))

        if self.opts.reallysafe:
            if self.job:
                self.job.setComment("Checking file hashes")
            self.log(MythLog.GENERAL | MythLog.FILE, MythLog.INFO,
                     "Checking file hashes.")
            srchash = hashfile(self.rec.open('r'))
            dsthash = hashfile(self.vid.open('r'))
            if srchash != dsthash:
                raise MythError('Source hash (%s) does not match destination hash (%s)' \
                            % (srchash, dsthash))
        elif self.opts.safe:
            self.log(MythLog.GENERAL | MythLog.FILE, MythLog.INFO,
                     "Checking file sizes.")
            be = MythBE(db=self.vid._db)
            try:
                srcsize = be.getSGFile(self.rec.hostname, self.rec.storagegroup, \
                                       self.rec.basename)[1]
                dstsize = be.getSGFile(self.vid.host, 'Videos',
                                       self.vid.filename)[1]
            except:
                raise MythError('Could not query file size from backend')
            if srcsize != dstsize:
                raise MythError('Source size (%d) does not match destination size (%d)' \
                            % (srcsize, dstsize))

        if self.job:
            self.job.setComment("Complete - %d seconds elapsed" % \
                            (int(time.time()-stime)))
            self.job.setStatus(Job.FINISHED)
コード例 #12
0
 def setUp(self):
     with add_log_flags():
         self.mydb = MythDB()
         self.mybe = MythBE(db=self.mydb)
コード例 #13
0
 def delete(self):
     be = MythBE(self.host, db=DB)
     be.deleteFile(self, self.group)
コード例 #14
0
 def __init__(self):
     self.be = MythBE()
     self.recs = {}
     self._events = [self.handleAdd, self.handleDelete, self.handleUpdate]
     for e in self._events:
         self.be.registerevent(e)
コード例 #15
0
ファイル: test.py プロジェクト: dougt/myth-hacks

def filepathToScreenshotFromRecording(recording):
    filepath = filepathFromRecording(recording)
    return filepath + ".png"


db = None
db = MythDB()

if db == None:
    print "Database could not be open or found"
    exit()

be = None
be = MythBE()

if be == None:
    print "Backend could not be found."
    #exit()

recordings = be.getRecordings()

for r in recordings:
    filepath = filepathFromRecording(r)
    size = -1
    try:
        size = os.path.getsize(filepath) / 1024 / 1024
    except:
        size = "NaN"
コード例 #16
0
                    res = int(res)
                except:
                    res = input('input number. ctrl-c to exit > ')
                    continue
                if (res <= 0) or (res > len(opts)):
                    res = input('input number within range > ')
                    continue
                break
            opt = opts[res - 1]
            if opt[1] is None:
                continue
            else:
                opt[1](opt[2])

        except KeyboardInterrupt:
            break
        except EOFError:
            sys.exit(0)


DB = MythDB()
BE = MythBE(db=DB)
DB.searchRecorded.handler = MyRecorded
DB.searchRecorded.dbclass = MyRecorded

if __name__ == '__main__':
    if len(sys.argv) == 2:
        main(sys.argv[1])
    else:
        main()
コード例 #17
0
 def delete(self):
     be = MythBE(self.hosts[0], db=self.db)
     be.deleteFile(self, self.group)
コード例 #18
0
def main():
    parser = OptionParser(usage="usage: option [option] [option]")

    maintenancegroup = OptionGroup(
        parser, "Maintenance",
        "These options can be used to perform DB cleanup.")
    maintenancegroup.add_option(
        "--dedup",
        action="store_true",
        default=False,
        dest="dedup",
        help="checks for duplicate entries in the Video database")
    maintenancegroup.add_option("--check_orphans",
                                action="store_true",
                                default=False,
                                dest="check_orphans",
                                help="checks for orphaned DB entries in Video")
    parser.add_option_group(maintenancegroup)

    actiongroup = OptionGroup(parser, "Meta Updates",
                              "This option updates Video Meta Data")
    actiongroup.add_option('--update',
                           action='store_true',
                           default=False,
                           dest='update',
                           help='Updates the video meta data on each entry')
    parser.add_option_group(actiongroup)

    othergroup = OptionGroup(parser, 'Other Options',
                             "These options allow for additional controls")
    othergroup.add_option(
        '--folder',
        action='store',
        type='string',
        dest='folder',
        help='Limits actions to Videos in a specified folder,\
                                  example "Movies" would limit to any filename \
                                  starting with Movies/some_video_file.mpg')
    othergroup.add_option(
        '--step',
        action="store_true",
        default=False,
        dest='step',
        help='Steps through each action to allow evaluation of \
                                  process')
    parser.add_option_group(othergroup)

    opts, args = parser.parse_args()

    # if a manual channel and time entry then setup the export with opts

    # sys.exit(1)

    # setup the connection to the DB
    db = MythDB()
    be = MythBE()

    #Setup a scanner for all videos in the DB
    videos = db.searchVideos()

    # setup a Video object to work with

    def get_Meta(item):

        metadata = item.exportMetadata()

        if not item.filename.startswith('Television'):
            grab = VideoGrabber('Movie')
            if item.get('inetref') != '00000000':
                try:
                    match = grab.grabInetref(item.inetref)
                    item.importMetadata(match)
                    item.plot = match.get('description')
                    item.title = match.get('title')
                    copy_Art(match, item)
                    item.update()
                    return

                except Exception:
                    print 'grabber failed for: ' + str(item.get('inetref'))
                    print 'trying by name instead'

            try:
                results = grab.sortedSearch(item.title)
            except Exception, e:
                print 'grabber failed for: ' + str(item.get('inetref'))
                print e
                return

            if len(results) > 0:
                if len(results) > 1:
                    menu = {}
                    list = 1
                    for each in results:
                        menu[list]= each.title + ', year: ' + str(each.get('year')) \
                                                + ', inetref: ' + str(each.get('inetref'))
                        list = list + 1
                    menu[list] = 'Skip to next video\n\n'
                    print '\n'
                    while True:
                        options = menu.keys()
                        options.sort()
                        for entry in options:
                            print entry, menu[entry]
                        try:
                            selection = input("Please Select: ")
                            if selection in range(1, len(results) + 1):
                                listing = results[selection - 1]
                                break
                            elif selection == len(results) + 1:
                                return
                            else:
                                print "Invalid Selection, try again!\n\n"
                        except Exception:
                            print "Invalid Selection, try again!\n\n"
                else:
                    listing = results[0]

                try:
                    match = grab.grabInetref(listing.get('inetref'))
                    item.importMetadata(match)
                    item.plot = match.get('description')
                    item.title = match.get('title')
                    copy_Art(match, item)
                    item.update()
                    print 'Full MetaData Import complete for: ' + item.title + '\n'

                except Exception, e:
                    print 'grabber failed for: ' + str(item.get('inetref'))
                    print e

            elif len(results) == 0:
                print 'No MetaData to import for: ' + item.title + '\n'
コード例 #19
0
    def showScreen(self):
        self.surface.fill([0, 0, 0])

        if self.be == None:
            try:
                recs = []
                self.be = MythBE()
                self.upcomingrecs = self.be.getUpcomingRecordings()
                for r in self.upcomingrecs:
                    rec = {}
                    rec["title"] = r.title
                    rec["subtitle"] = r.subtitle
                    rec["time"] = r.starttime.strftime("%a %d %b %H:%M")
                    rec["desc"] = r.description
                    recs.append(rec)
                recorders = MythBE().getRecorderList()
                for recorder in recorders:
                    if MythBE().isRecording(recorder):
                        self.isrecording = True
                        break
                self.backendfail = False
                self.cachedmode = False
            except:
                self.backendfail = True

        if self.backendfail:
            recs = self.loadCache()
            if recs:
                self.backendfail = False
                self.cachedmode = True

        if not self.backendfail:

            self.cacheRecs(recs)

            screentitle = self.mytitlefont.render("MythTV upcoming recordings",
                                                  1, (255, 255, 255))
            screenrect = screentitle.get_rect()
            screenrect.centerx = self.surface.get_rect().centerx
            screenrect.centery = 20
            self.surface.blit(screentitle, screenrect)

            n = min(len(recs), 5)
            if n > 0:
                for i in range(n):
                    mytitlerect = pygame.Rect((0, 0, self.rectwidth, 60))
                    mytimerect = pygame.Rect((0, 0, self.rectwidth, 30))
                    mydescrect = pygame.Rect((0, 0, self.rectwidth, 330))
                    fontcolour = (255, 255, 255)
                    rectcolour = (0, 50, 75)
                    titletext = self.render_textrect(recs[i]["title"],
                                                     self.myboldfont,
                                                     mytitlerect, fontcolour,
                                                     rectcolour, 1)
                    timetext = self.render_textrect(recs[i]["time"],
                                                    self.myitalicfont,
                                                    mytimerect, fontcolour,
                                                    rectcolour, 1)
                    desctext = self.render_textrect(recs[i]["desc"],
                                                    self.myregularfont,
                                                    mydescrect,
                                                    fontcolour,
                                                    rectcolour,
                                                    0,
                                                    margin=5)
                    self.surface.blit(titletext,
                                      ((self.rectwidth * i) +
                                       (self.rectgap *
                                        (i + 1) + self.rectadjust), 40))
                    self.surface.blit(timetext,
                                      ((self.rectwidth * i) +
                                       (self.rectgap *
                                        (i + 1) + self.rectadjust), 80))
                    self.surface.blit(desctext,
                                      ((self.rectwidth * i) +
                                       (self.rectgap *
                                        (i + 1) + self.rectadjust), 105))

                if self.cachedmode:
                    mystatus = self.myitalicfont.render(
                        "Backend is offline. Displaying cached recording list",
                        1, (255, 255, 255))
                else:
                    if self.isrecording:
                        recording = "currently"
                    else:
                        recording = "not"
                    mystatus = self.myitalicfont.render(
                        "Backend is online and is " + recording +
                        " recording.", 1, (255, 255, 255))

                self.surface.blit(mystatus, (5, 445))
            else:
                failtext = self.myboldfont.render(
                    "No upcoming recordings found.", 1, (255, 255, 255))
                failrect = failtext.get_rect()
                failrect.centerx = self.surface.get_rect().centerx
                failrect.centery = self.surface.get_rect().centery
                self.surface.blit(failtext, failrect)

        else:
            failtext = self.myboldfont.render("MythTV backend unavailable.", 1,
                                              (255, 255, 255))
            failrect = failtext.get_rect()
            failrect.centerx = self.surface.get_rect().centerx
            failrect.centery = self.surface.get_rect().centery
            self.surface.blit(failtext, failrect)

        self.be = None

        # Scale our surface to the required screensize before sending back
        scaled = pygame.transform.scale(self.surface, self.screensize)
        self.screen.blit(scaled, (0, 0))

        return self.screen
コード例 #20
0
def getBeObject(databaseObj=getDbObject()):
    return MythBE(db=databaseObj)
コード例 #21
0
 def __init__(self):
     self.db = MythDB()
     self.be = MythBE(db=self.db)