def __init__(self, app, opts, vf): self.container = vf.getShare() self.app = app self.opts = opts self.vf = vf self.isactive = True self.submenu = None self.ip, self.port, self.sep = self.selectPyTivo(app, self.container) if self.ip == None: raise ConfigError("Share Configuration Error - unable to find share {%s}" % self.container) self.menu = [] self.tsns = [] for t in app.tivos: self.menu.append(t['name']) self.tsns.append(t['tsn']) if len(self.menu) == 0: raise ConfigError("Tivo Configuration Error") if len(self.menu) == 1: self.app.send_key(KEY_TIVO, MYKEY_PUSHRESUME) return self.submenu = self.app.subMenu self.submenu.load("Select Destination Tivo", self.menu, MYKEY_PUSHRESUME) return
def startup(self): print "Vidmgr thread entering startup" self.vwInfo = None self.vcChanged = False config = Config.Config() self.opts = config.load() self.cp = config.getConfigParser() # get the tivo information out of the startup config file. For each tivo, we need to know: # tivox.name - the user friendly name and # tivox.tsn - the TSN # these fields all go into a section named [tivos] self.loadTivos(self.cp, self.opts['sorttivosbyname']) if len(self.tivos) == 0: raise ConfigError("No Tivos found - exiting") # get the pytivo information. For each pytivo instance, we need the following: # pytivox.config - the location of the config file # pytivox.ip - the ip address # # also, if the pytivo port number is not specified in the pytivo config file, you must have # pytivox.port - the port number self.shares = [] self.loadShares(self.cp) if len(self.shares) == 0: raise ConfigError("No shares found - exiting")
def loadPyTivoConfig(self, cf, ip, defport, sep, skip): pyconfig = ConfigParser.ConfigParser() if not pyconfig.read(cf): raise ConfigError("ERROR: pyTivo config file " + cf + " does not exist.") port = defport if pyconfig.has_option('Server', 'port'): port = pyconfig.get('Server', 'port') if port == None: raise ConfigError( "Neither main config file nor pytivo config file " + cf + " has port number specified") for section in pyconfig.sections(): if not section in skip: if (pyconfig.has_option(section, "type") and (pyconfig.get(section, "type") == "video" or pyconfig.get(section, "type") == "dvdvideo") and pyconfig.has_option(section, 'path')): path = pyconfig.get(section, 'path') self.shares.append({ 'name': section, 'ip': ip, 'port': port, 'path': path, 'sep': sep })
def start(self): if self.rootNode == None: raise ConfigError("No video cache - exiting") self.TitleView.set_text(TITLE, font=self.myfonts.fnt30, colornum=0xffffff, flags=RSRC_VALIGN_BOTTOM) self.SubTitleView.set_text(self.rootNode.getFullTitle(), font=self.app.myfonts.fnt20, colornum=0xffffff, flags=RSRC_VALIGN_BOTTOM) self.currentNode, self.currentItem = self.ldm.Descend(self.rootNode) self.lopts = self.rootNode.getOpts() self.ddm.show(self.currentItem) if self.currentNode == None: print "Current node = NULL - exiting" self.active = False
def harvest(self, vf): if not Harvester.harvest(self, vf): return mvf = vf.getMeta() # determine grouping groupTag = self.opts['group'] if groupTag == None: # no grouping - stuff into root node target = self.root else: # get the grouping value if groupTag not in mvf: grp = OTHER else: grp = mvf[groupTag] if type(grp) is list: raise ConfigError( "Configuration Error - grouping item must not be a list" ) if grp in self.nodeMap: # if we've seen this group, then just reuse the # same node target = self.nodeMap[grp] else: # Otherwise create a new node and link it in path = os.path.join(self.hpath, Legalize(grp)) target = Node(grp, self.opts, path=path, title="%s: %s" % (metaTranslate(groupTag), grp)) self.pathMap[os.path.join(self.name, grp)] = path self.nodeMap[grp] = target self.root.addDir(target) self.gcount += 1 target.addVideo(vf) self.count += 1
def loadPyTivoShares(self, cf, skip): shares = [] pyconfig = ConfigParser.ConfigParser() if not pyconfig.read(cf): raise ConfigError("ERROR: pyTivo config file " + cf + " does not exist.") for section in pyconfig.sections(): if not section in skip: if (pyconfig.has_option(section, "type") and pyconfig.get(section, "type") == "video" and pyconfig.has_option(section, 'path')): path = pyconfig.get(section, 'path') shares.append([section, path, SHARETYPE_VIDEO]) elif (pyconfig.has_option(section, "type") and pyconfig.get(section, "type") == "dvdvideo" and pyconfig.has_option(section, 'path')): path = pyconfig.get(section, 'path') shares.append([section, path, SHARETYPE_DVD]) return shares
def harvest(self, vf): if not Harvester.harvest(self, vf): return # get the metadata for the video we are trying to add mvf = vf.getMeta() k = self.metakey if not k in mvf: return if type(mvf[k]) is list: raise ConfigError( "Configuration Error - tag for alpha cannot be a list") if k in ['title', 'episodeTitle'] and self.opts['ignorearticle']: data = stripArticle(mvf[k]) else: data = mvf[k] keychar = data[0].upper() if keychar not in AlphaKeys: keychar = OTHER groupTag = self.opts['group'] if groupTag == None: # no grouping for this share OR video does not have # grouping metadata item if keychar not in self.nodeMap: # we've not seen this value yet - create a Node # and link it in path = os.path.join(self.hpath, Legalize(keychar)) target = Node(keychar + "... ", self.opts, path=path) self.pathMap[os.path.join(self.name, keychar)] = path self.nodeMap[keychar] = target self.root.addDir(target) else: # otherwise we've seen it so just use it target = self.nodeMap[keychar] target.addVideo(vf) else: # otherwise we are grouping if groupTag not in mvf: grplist = [OTHER] else: grp = mvf[groupTag] if type(grp) is list: grplist = grp else: grplist = [grp] for grp in grplist: grpTitle = "%s: %s" % (metaTranslate(groupTag), grp) if grp not in self.nodeMap: path = os.path.join(self.hpath, Legalize(grp)) grpNode = Node(grp, self.opts, title=grpTitle, path=path) self.pathMap[os.path.join(self.name, grp)] = path self.nodeMap[grp] = grpNode self.root.addDir(grpNode) self.gcount += 1 else: grpNode = self.nodeMap[grp] mvkey = grpTitle + "/" + keychar if mvkey not in self.nodeMap: path = os.path.join(self.hpath, Legalize(grp), Legalize(keychar)) target = Node(keychar + "... ", self.opts, title=mvkey + "...", path=path) self.pathMap[os.path.join(self.name, grp, keychar)] = path self.nodeMap[mvkey] = target grpNode.addDir(target) else: target = self.nodeMap[mvkey] target.addVideo(vf) self.count += 1
def build(self, verbose=False): def cmpHarvesters(a, b): ta = a.formatDisplayText(None) tb = b.formatDisplayText(None) return cmp(ta, tb) title = "Main Menu" sharepage = True sortroot = False vidlist = VideoList() harvesters = [] if self.cfg.has_option(OPTSECT, 'sharepage'): v = self.cfg.get(OPTSECT, 'sharepage') if v.lower() == 'false': sharepage = False if self.cfg.has_option(OPTSECT, 'topsubtitle'): title = self.cfg.get(OPTSECT, 'topsubtitle') if self.cfg.has_option(OPTSECT, 'sortroot'): f = self.cfg.get(OPTSECT, 'sortroot').lower() if f == 'true': sortroot = True elif f == 'false': sortroot = False else: raise ConfigError("Error - sortroot must be true or false") for section in self.cfg.sections(): if section not in [OPTSECT, 'tivos', 'pytivos']: lopts = self.opts.copy() if self.cfg.has_option(section, 'sort'): lopts['sortopt'] = self.cfg.get(section, 'sort').split() if self.cfg.has_option(section, 'sortdirection'): lval = self.cfg.get(section, 'sortdirection').lower() if lval == 'down': lopts['sortup'] = False elif lval == 'up': lopts['sortup'] = True else: raise ConfigError( "Error in ini file - sortdirection must be up or down" ) if self.cfg.has_option(section, 'tagorder'): lval = self.cfg.get(section, 'tagorder').lower() if lval == 'down': lopts['tagssortup'] = False elif lval == 'up': lopts['tagssortup'] = True else: raise ConfigError( "Error in ini file - tagorder must be up or down") else: lopts['tagssortup'] = True if self.cfg.has_option(section, 'display)'): lopts['dispopt'] = self.cfg.get(section, 'display').split() if self.cfg.has_option(section, 'displaysep'): lopts['dispsep'] = self.cfg.get(section, 'displaysep') if self.cfg.has_option(section, 'groupby'): lopts['group'] = self.cfg.get(section, 'groupby') lopts['shares'] = None if self.cfg.has_option(section, "shares"): inc = self.cfg.get(section, "shares").split(",") lopts['shares'] = [s.strip() for s in inc] hasTags = self.cfg.has_option(section, 'tags') hasValues = self.cfg.has_option(section, 'values') hasAlpha = self.cfg.has_option(section, 'alpha') if hasTags: if hasValues or hasAlpha: raise ConfigError( "Error - tags, values, and alpha are mutually exclusive in section %s" % section) h = KeySetHarvester(section, lopts, self.cfg.get(section, 'tags').split(), verbose) harvesters.append(h) elif hasAlpha: if hasValues: raise ConfigError( "Error - tags, values, and alpha are mutually exclusive in section %s" % section) mkey = self.cfg.get(section, 'alpha') h = AlphaHarvester(section, lopts, mkey, verbose) harvesters.append(h) elif hasValues: if self.cfg.get(section, 'values').lower() == 'all': h = AllHarvester(section, lopts, verbose) harvesters.append(h) else: terms = self.cfg.get(section, 'values').split('/') vdict = {} for t in terms: v = t.split(':') if len(v) != 2: raise ConfigError( "Error in ini file - syntax on values statement in section %s" % section) tag = v[0] vals = v[1].split(',') vdict[tag] = vals h = KeyValHarvester(section, lopts, vdict, verbose) harvesters.append(h) else: # section does not have the necessary virtual share tags raise ConfigError( "Error - Section %s needs tags, values, or alpha option" % section) sl = self.loadShares() if len(sl) == 0: raise ConfigError("Error - no shares are defined") root = Node(title, self.opts) if sharepage: shares = Node("Browse Shares", self.opts) for name, path, type in sl: if type == SHARETYPE_VIDEO: print "Processing video share " + name s = VideoShare(self.opts, name, path, vidlist, harvesters) print "%d Videos found" % s.VideoCount() else: # type == SHARETYPE_DVD print "Processing DVD share " + name s = DVDShare(self.opts, name, path, vidlist, harvesters) print "%d DVD Videos found" % s.VideoCount() shares.addDir(s) root.addDir(shares) else: for name, path, type in sl: if type == SHARETYPE_VIDEO: print "Processing video share " + name s = VideoShare(self.opts, name, path, vidlist, harvesters) print "%d Videos found" % s.VideoCount() else: # type == SHARETYPE_DVD print "Processing DVD share " + name s = DVDShare(self.opts, name, path, vidlist, harvesters) print "%d DVD Videos found" % s.VideoCount() root.addDir(s) root.sort() for h in sorted(harvesters, cmpHarvesters): title = h.formatDisplayText(None) nd = h.getNode() vc, gc = h.videoCount() if gc == None: print "%s count: %d videos" % (title, vc) else: print "%s count: %d videos in %d groups" % (title, vc, gc) root.addDir(nd) if verbose: pm = h.getPathMap() for k in sorted(pm.keys()): print "%s: %s%s%s.jpg" % (k, artworkDir, os.sep, pm[k]) if sortroot: root.sort() self.cache = root return root