def channelSelectionCallback(self, *args): if args and len(args) == 2: serviceref, bouquetref = args[:2] if self.parent: self.parent.selectBouquet(bouquetref, self) self.setService(ServiceReference(serviceref))
def getMovieSearchList(rargs=None, locations=None): movieliste = [] tag = None directory = None fields = None short = None extended = None searchstr = None if rargs: searchstr = getUrlArg2(rargs, "find") short = getUrlArg2(rargs, "short") extended = getUrlArg2(rargs, "extended") s = {'title': str(searchstr)} if short is not None: s['shortDesc'] = str(searchstr) if extended is not None: s['extDesc'] = str(searchstr) movielist = MovieList(None) vdir_list = [] for x in moviedb.searchContent(s, 'ref', query_type="OR", exactmatch=False): vdir_list.append(eServiceReference(x[0])) root = eServiceReference("2:0:1:0:0:0:0:0:0:0:" + "/") movielist.load(root, None) movielist.reload(root=None, vdir=5, vdir_list=vdir_list) for (serviceref, info, begin, unknown) in movielist.list: if serviceref.flags & eServiceReference.mustDescent: continue length_minutes = 0 txtdesc = "" filename = '/'.join(serviceref.toString().split("/")[1:]) filename = '/' + filename name, ext = os.path.splitext(filename) sourceRef = ServiceReference( info.getInfoString(serviceref, iServiceInformation.sServiceref)) rtime = info.getInfo(serviceref, iServiceInformation.sTimeCreate) movie = { 'filename': filename, 'filename_stripped': filename.split("/")[-1], 'serviceref': serviceref.toString(), 'length': "?:??", 'lastseen': 0, 'filesize_readable': '', 'recordingtime': rtime, 'begintime': 'undefined', 'eventname': ServiceReference(serviceref).getServiceName().replace( '\xc2\x86', '').replace('\xc2\x87', ''), 'servicename': sourceRef.getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''), 'tags': info.getInfoString(serviceref, iServiceInformation.sTags), 'fullname': serviceref.toString(), } if rtime > 0: movie['begintime'] = FuzzyTime2(rtime) try: length_minutes = info.getLength(serviceref) except: # nosec # noqa: E722 pass if length_minutes: movie['length'] = "%d:%02d" % (length_minutes / 60, length_minutes % 60) # if fields is None or 'pos' in fields: # movie['lastseen'] = getPosition(filename + '.cuts', length_minutes) if fields is None or 'desc' in fields: txtfile = name + '.txt' if ext.lower() != '.ts' and os.path.isfile(txtfile): with open(txtfile, "rb") as handle: txtdesc = six.ensure_str(b''.join(handle.readlines())) event = info.getEvent(serviceref) extended_description = event and event.getExtendedDescription( ) or "" if extended_description == '' and txtdesc != '': extended_description = txtdesc movie['descriptionExtended'] = ConvertDesc(extended_description) desc = info.getInfoString(serviceref, iServiceInformation.sDescription) movie['description'] = ConvertDesc(desc) if fields is None or 'size' in fields: size = 0 sz = '' try: size = os.stat(filename).st_size if size > 1073741824: sz = "%.2f %s" % ((size / 1073741824.), _("GB")) elif size > 1048576: sz = "%.2f %s" % ((size / 1048576.), _("MB")) elif size > 1024: sz = "%.2f %s" % ((size / 1024.), _("kB")) except: # nosec # noqa: E722 pass movie['filesize'] = size movie['filesize_readable'] = sz movieliste.append(movie) return {"movies": movieliste, "locations": []}
def _moveMovie(session, sRef, destpath=None, newname=None): service = ServiceReference(sRef) result = True errText = 'unknown Error' if destpath is not None and not destpath[-1] == '/': destpath = destpath + '/' if service is not None: serviceHandler = eServiceCenter.getInstance() info = serviceHandler.info(service.ref) name = info and info.getName(service.ref) or "this recording" fullpath = service.ref.getPath() srcpath = '/'.join(fullpath.split('/')[:-1]) + '/' fullfilename = fullpath.split('/')[-1] fileName, fileExt = os.path.splitext(fullfilename) if newname is not None: newfullpath = srcpath + newname + fileExt # TODO: check splitted recording # TODO: use FileTransferJob def domove(): exists = os.path.exists move = os.rename errorlist = [] if fileExt == '.ts': suffixes = ".ts.meta", ".ts.cuts", ".ts.ap", ".ts.sc", ".eit", ".ts", ".jpg", ".ts_mp.jpg" else: suffixes = "%s.ts.meta" % fileExt, "%s.cuts" % fileExt, fileExt, '.jpg', '.eit' for suffix in suffixes: src = srcpath + fileName + suffix if exists(src): try: if newname is not None: # rename title in meta file if suffix == '.ts.meta': # todo error handling lines = [] with open(src, "r") as fin: for line in fin: lines.append(line) lines[1] = newname + '\n' lines[4] = '\n' with open(srcpath + newname + suffix, 'w') as fout: fout.write(''.join(lines)) os.remove(src) else: move(src, srcpath + newname + suffix) else: move(src, destpath + fileName + suffix) except IOError as e: errorlist.append("I/O error({0})".format(e)) break except OSError as ose: errorlist.append(str(ose)) return errorlist # MOVE if newname is None: if srcpath == destpath: result = False errText = 'Equal Source and Destination Path' elif not os.path.exists(fullpath): result = False errText = 'File not exist' elif not os.path.exists(destpath): result = False errText = 'Destination Path not exist' elif os.path.exists(destpath + fullfilename): errText = 'Destination File exist' result = False # rename else: if not os.path.exists(fullpath): result = False errText = 'File not exist' elif os.path.exists(newfullpath): result = False errText = 'New File exist' if result: errlist = domove() if not errlist: result = True else: errText = errlist[0] result = False etxt = "rename" if newname is None: etxt = "move" if result is False: return { "result": False, "message": "Could not %s recording '%s' Err: '%s'" % (etxt, name, errText) } else: # EMC reload try: config.EMC.needsreload.value = True except (AttributeError, KeyError): pass return { "result": True, "message": "The recording '%s' has been %sd successfully" % (name, etxt) }
def getInfo(session=None, need_fullinfo=False): # TODO: get webif versione somewhere! info = {} global STATICBOXINFO if not (STATICBOXINFO is None or need_fullinfo): return STATICBOXINFO info['brand'] = getMachineBrand() info['model'] = getMachineName() info['boxtype'] = getBoxType() info['machinebuild'] = getMachineBuild() try: info['lcd'] = getLcd() except: # temporary due OE-A info['lcd'] = 0 try: info['grabpip'] = getGrabPip() except: # temporary due OE-A info['grabpip'] = 0 chipset = "unknown" if fileExists("/etc/.box"): f = open("/etc/.box", 'r') model = f.readline().strip().lower() f.close() if model.startswith("ufs") or model.startswith("ufc"): if model in ("ufs910", "ufs922", "ufc960"): chipset = "SH4 @266MHz" else: chipset = "SH4 @450MHz" elif model in ("topf", "tf7700hdpvr"): chipset = "SH4 @266MHz" elif model.startswith("azbox"): f = open("/proc/stb/info/model", 'r') model = f.readline().strip().lower() f.close() if model == "me": chipset = "SIGMA 8655" elif model == "minime": chipset = "SIGMA 8653" else: chipset = "SIGMA 8634" elif model.startswith("spark"): if model == "spark7162": chipset = "SH4 @540MHz" else: chipset = "SH4 @450MHz" elif fileExists("/proc/stb/info/azmodel"): f = open("/proc/stb/info/model", 'r') model = f.readline().strip().lower() f.close() if model == "me": chipset = "SIGMA 8655" elif model == "minime": chipset = "SIGMA 8653" else: chipset = "SIGMA 8634" elif fileExists("/proc/stb/info/model"): f = open("/proc/stb/info/model", 'r') model = f.readline().strip().lower() f.close() if model == "tf7700hdpvr": chipset = "SH4 @266MHz" elif model == "nbox": chipset = "STi7100 @266MHz" elif model == "arivalink200": chipset = "STi7109 @266MHz" elif model in ("adb2850", "adb2849", "dsi87"): chipset = "STi7111 @450MHz" elif model in ("sagemcom88", "esi88"): chipset = "STi7105 @450MHz" elif model.startswith("spark"): if model == "spark7162": chipset = "STi7162 @540MHz" else: chipset = "STi7111 @450MHz" elif model == "dm800": chipset = "bcm7401" elif model == "dm800se": chipset = "bcm7405" elif model == "dm500hd": chipset = "bcm7405" elif model == "dm7020hd": chipset = "bcm7405" elif model == "dm8000": chipset = "bcm7400" elif model == "dm820": chipset = "bcm7435" elif model == "dm7080": chipset = "bcm7435" elif model == "dm520": chipset = "bcm73625" elif model == "dm525": chipset = "bcm73625" elif model == "dm900": chipset = "bcm7252S" elif model == "dm920": chipset = "bcm7252S" if fileExists("/proc/stb/info/chipset"): f = open("/proc/stb/info/chipset", 'r') chipset = f.readline().strip() f.close() info['chipset'] = chipset memFree = 0 for line in open("/proc/meminfo", 'r'): parts = line.split(':') key = parts[0].strip() if key == "MemTotal": info['mem1'] = parts[1].strip().replace("kB", _("kB")) elif key in ("MemFree", "Buffers", "Cached"): memFree += int(parts[1].strip().split(' ', 1)[0]) info['mem2'] = "%s %s" % (memFree, _("kB")) info['mem3'] = _("%s free / %s total") % (info['mem2'], info['mem1']) try: f = open("/proc/uptime", "rb") uptime = int(float(f.readline().split(' ', 2)[0].strip())) f.close() uptimetext = '' if uptime > 86400: d = uptime / 86400 uptime = uptime % 86400 uptimetext += '%dd ' % d uptimetext += "%d:%.2d" % (uptime / 3600, (uptime % 3600) / 60) except: # noqa: E722 uptimetext = "?" info['uptime'] = uptimetext info["webifver"] = OPENWEBIFVER info['imagedistro'] = getImageDistro() info['friendlyimagedistro'] = getFriendlyImageDistro() info['oever'] = getOEVersion() info['imagever'] = getImageVersion() ib = getImageBuild() if ib: info['imagever'] = info['imagever'] + "." + ib info['enigmaver'] = getEnigmaVersionString() info['driverdate'] = getDriverDate() info['kernelver'] = about.getKernelVersionString() try: from Tools.StbHardware import getFPVersion except ImportError: from Tools.DreamboxHardware import getFPVersion try: info['fp_version'] = getFPVersion() except: # noqa: E722 info['fp_version'] = None friendlychipsetdescription = _("Chipset") friendlychipsettext = info['chipset'].replace("bcm", "Broadcom ") if friendlychipsettext in ("7335", "7356", "7362", "73625", "7424", "7425", "7429"): friendlychipsettext = "Broadcom " + friendlychipsettext if not (info['fp_version'] is None or info['fp_version'] == 0): friendlychipsetdescription = friendlychipsetdescription + " (" + _( "Frontprocessor Version") + ")" friendlychipsettext = friendlychipsettext + " (" + str( info['fp_version']) + ")" info['friendlychipsetdescription'] = friendlychipsetdescription info['friendlychipsettext'] = friendlychipsettext info['tuners'] = [] for i in range(0, nimmanager.getSlotCount()): print "[OpenWebif] -D- tuner '%d' '%s' '%s'" % ( i, nimmanager.getNimName(i), nimmanager.getNim(i).getSlotName()) info['tuners'].append({ "name": nimmanager.getNim(i).getSlotName(), "type": nimmanager.getNimName(i) + " (" + nimmanager.getNim(i).getFriendlyType() + ")", "rec": "", "live": "" }) info['ifaces'] = [] ifaces = iNetwork.getConfiguredAdapters() for iface in ifaces: info['ifaces'].append({ "name": iNetwork.getAdapterName(iface), "friendlynic": getFriendlyNICChipSet(iface), "linkspeed": getLinkSpeed(iface), "mac": iNetwork.getAdapterAttribute(iface, "mac"), "dhcp": iNetwork.getAdapterAttribute(iface, "dhcp"), "ipv4method": getIPv4Method(iface), "ip": formatIp(iNetwork.getAdapterAttribute(iface, "ip")), "mask": formatIp(iNetwork.getAdapterAttribute(iface, "netmask")), "v4prefix": sum([ bin(int(x)).count('1') for x in formatIp( iNetwork.getAdapterAttribute(iface, "netmask")).split('.') ]), "gw": formatIp(iNetwork.getAdapterAttribute(iface, "gateway")), "ipv6": getAdapterIPv6(iface)['addr'], "ipmethod": getIPMethod(iface), "firstpublic": getAdapterIPv6(iface)['firstpublic'] }) info['hdd'] = [] for hdd in harddiskmanager.hdd: dev = hdd.findMount() if dev: stat = os.statvfs(dev) free = stat.f_bavail * stat.f_frsize / 1048576. else: free = -1 if free <= 1024: free = "%i %s" % (free, _("MB")) else: free = free / 1024. free = "%.1f %s" % (free, _("GB")) size = hdd.diskSize() * 1000000 / 1048576. if size > 1048576: size = "%.1f %s" % ((size / 1048576.), _("TB")) elif size > 1024: size = "%.1f %s" % ((size / 1024.), _("GB")) else: size = "%d %s" % (size, _("MB")) iecsize = hdd.diskSize() # Harddisks > 1000 decimal Gigabytes are labelled in TB if iecsize > 1000000: iecsize = (iecsize + 50000) // float(100000) / 10 # Omit decimal fraction if it is 0 if (iecsize % 1 > 0): iecsize = "%.1f %s" % (iecsize, _("TB")) else: iecsize = "%d %s" % (iecsize, _("TB")) # Round harddisk sizes beyond ~300GB to full tens: 320, 500, 640, 750GB elif iecsize > 300000: iecsize = "%d %s" % (((iecsize + 5000) // 10000 * 10), _("GB")) # ... be more precise for media < ~300GB (Sticks, SSDs, CF, MMC, ...): 1, 2, 4, 8, 16 ... 256GB elif iecsize > 1000: iecsize = "%d %s" % (((iecsize + 500) // 1000), _("GB")) else: iecsize = "%d %s" % (iecsize, _("MB")) info['hdd'].append({ "model": hdd.model(), "capacity": size, "labelled_capacity": iecsize, "free": free, "mount": dev, "friendlycapacity": _("%s free / %s total") % (free, size + ' ("' + iecsize + '")') }) info['shares'] = [] autofiles = ('/etc/auto.network', '/etc/auto.network_vti') for autofs in autofiles: if fileExists(autofs): method = "autofs" for line in file(autofs).readlines(): if not line.startswith('#'): # Replace escaped spaces that can appear inside credentials with underscores # Not elegant but we wouldn't want to expose credentials on the OWIF anyways tmpline = line.replace("\ ", "_") tmp = tmpline.split() if not len(tmp) == 3: continue name = tmp[0].strip() type = "unknown" if "cifs" in tmp[1]: # Linux still defaults to SMBv1 type = "SMBv1.0" settings = tmp[1].split(",") for setting in settings: if setting.startswith("vers="): type = setting.replace("vers=", "SMBv") elif "nfs" in tmp[1]: type = "NFS" # Default is r/w mode = _("r/w") settings = tmp[1].split(",") for setting in settings: if setting == "ro": mode = _("r/o") uri = tmp[2] parts = [] parts = tmp[2].split(':') if parts[0] is "": server = uri.split('/')[2] uri = uri.strip()[1:] else: server = parts[0] ipaddress = None if server: # Will fail on literal IPs try: # Try IPv6 first, as will Linux if has_ipv6: tmpaddress = None tmpaddress = getaddrinfo(server, 0, AF_INET6) if tmpaddress: ipaddress = "[" + list( tmpaddress)[0][4][0] + "]" # Use IPv4 if IPv6 fails or is not present if ipaddress is None: tmpaddress = None tmpaddress = getaddrinfo(server, 0, AF_INET) if tmpaddress: ipaddress = list(tmpaddress)[0][4][0] except: # noqa: E722 pass friendlyaddress = server if ipaddress is not None and not ipaddress == server: friendlyaddress = server + " (" + ipaddress + ")" info['shares'].append({ "name": name, "method": method, "type": type, "mode": mode, "path": uri, "host": server, "ipaddress": ipaddress, "friendlyaddress": friendlyaddress }) # TODO: fstab info['transcoding'] = TRANSCODING info['EX'] = '' if session: try: # gets all current stream clients for images using eStreamServer # TODO: merge eStreamServer and streamList # TODO: get tuner info for streams # TODO: get recoding/timer info if more than one info['streams'] = [] try: streams = [] from enigma import eStreamServer streamServer = eStreamServer.getInstance() if streamServer is not None: for x in streamServer.getConnectedClients(): servicename = ServiceReference( x[1]).getServiceName() or "(unknown service)" if int(x[2]) == 0: strtype = "S" else: strtype = "T" info['streams'].append({ "ref": x[1], "name": servicename, "ip": x[0], "type": strtype }) except Exception, error: print "[OpenWebif] -D- no eStreamServer %s" % error recs = NavigationInstance.instance.getRecordings() if recs: # only one stream and only TV from Plugins.Extensions.OpenWebif.controllers.stream import streamList s_name = '' # s_cip = '' print "[OpenWebif] -D- streamList count '%d'" % len(streamList) if len(streamList) == 1: from Screens.ChannelSelection import service_types_tv # from enigma import eEPGCache # epgcache = eEPGCache.getInstance() serviceHandler = eServiceCenter.getInstance() services = serviceHandler.list( eServiceReference('%s ORDER BY name' % (service_types_tv))) channels = services and services.getContent("SN", True) s = streamList[0] srefs = s.ref.toString() for channel in channels: if srefs == channel[0]: s_name = channel[1] + ' (' + s.clientIP + ')' break print "[OpenWebif] -D- s_name '%s'" % s_name # only for debug for stream in streamList: srefs = stream.ref.toString() print "[OpenWebif] -D- srefs '%s'" % srefs sname = '' timers = [] for timer in NavigationInstance.instance.RecordTimer.timer_list: if timer.isRunning() and not timer.justplay: timers.append( timer.service_ref.getServiceName().replace( '\xc2\x86', '').replace('\xc2\x87', '')) print "[OpenWebif] -D- timer '%s'" % timer.service_ref.getServiceName( ) # TODO: more than one recording if len(timers) == 1: sname = timers[0] if sname == '' and s_name != '': sname = s_name print "[OpenWebif] -D- recs count '%d'" % len(recs) for rec in recs: feinfo = rec.frontendInfo() frontendData = feinfo and feinfo.getAll(True) if frontendData is not None: cur_info = feinfo.getTransponderData(True) if cur_info: nr = frontendData['tuner_number'] info['tuners'][nr]['rec'] = getOrbitalText( cur_info) + ' / ' + sname service = session.nav.getCurrentService() if service is not None: sname = service.info().getName() feinfo = service.frontendInfo() frontendData = feinfo and feinfo.getAll(True) if frontendData is not None: cur_info = feinfo.getTransponderData(True) if cur_info: nr = frontendData['tuner_number'] info['tuners'][nr]['live'] = getOrbitalText( cur_info) + ' / ' + sname except Exception, error: info['EX'] = error
def rootBouquet(self): servicelist = Screens.InfoBar.InfoBar.instance.servicelist epg_bouquet = servicelist and servicelist.getRoot() if ServiceReference(epg_bouquet).getServiceName(): return False return True
def addTimer(session, serviceref, begin, end, name, description, disabled, justplay, afterevent, dirname, tags, repeated, vpsinfo=None, logentries=None, eit=0, always_zap=-1): rt = session.nav.RecordTimer if not dirname: dirname = preferredTimerPath() try: timer = RecordTimerEntry(ServiceReference(serviceref), begin, end, name, description, eit, disabled, justplay, afterevent, dirname=dirname, tags=tags) timer.repeated = repeated if logentries: timer.log_entries = logentries conflicts = rt.record(timer) if conflicts: errors = [] conflictinfo = [] for conflict in conflicts: errors.append(conflict.name) conflictinfo.append({ "serviceref": str(conflict.service_ref), "servicename": conflict.service_ref.getServiceName().replace( '\xc2\x86', '').replace('\xc2\x87', ''), "name": conflict.name, "begin": conflict.begin, "end": conflict.end, "realbegin": strftime("%d.%m.%Y %H:%M", (localtime(float(conflict.begin)))), "realend": strftime("%d.%m.%Y %H:%M", (localtime(float(conflict.end)))) }) return { "result": False, "message": _("Conflicting Timer(s) detected! %s") % " / ".join(errors), "conflicts": conflictinfo } # VPS if vpsinfo is not None: timer.vpsplugin_enabled = vpsinfo["vpsplugin_enabled"] timer.vpsplugin_overwrite = vpsinfo["vpsplugin_overwrite"] timer.vpsplugin_time = vpsinfo["vpsplugin_time"] if always_zap != -1: if hasattr(timer, "always_zap"): timer.always_zap = always_zap == 1 except Exception, e: print e return { "result": False, "message": _("Could not add timer '%s'!") % name }
def recordNow(session, infinite): rt = session.nav.RecordTimer serviceref = session.nav.getCurrentlyPlayingServiceReference().toString() try: event = session.nav.getCurrentService().info().getEvent(0) except Exception: event = None if not event and not infinite: return { "result": False, "message": _("No event found! Not recording!") } if event: (begin, end, name, description, eit) = parseEvent(event) begin = time() msg = _("Instant record for current Event started") else: name = "instant record" description = "" eit = 0 if infinite: begin = time() end = begin + 3600 * 10 msg = _("Infinite Instant recording started") timer = RecordTimerEntry(ServiceReference(serviceref), begin, end, name, description, eit, False, False, 0, dirname=preferredInstantRecordPath()) timer.dontSave = True if rt.record(timer): return { "result": False, "message": _("Timer conflict detected! Not recording!") } nt = { "serviceref": str(timer.service_ref), "servicename": timer.service_ref.getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''), "eit": timer.eit, "name": timer.name, "begin": timer.begin, "end": timer.end, "duration": timer.end - timer.begin } return {"result": True, "message": msg, "newtimer": nt}
def load(self, root, filter_tags): # this lists our root service, then building a # nice list self.serviceHandler = eServiceCenter.getInstance() parentLstEntry = self.realDirUp(root) self.rootlst = [] self.root = root list = self.serviceHandler.list(root) if list is None: print "[SF-Plugin] listing of movies failed" list = [] return tags = set() rootinfo = self.serviceHandler.info(root) pwd = rootinfo and rootinfo.getName(root) while 1: serviceref = list.getNext() if not serviceref.valid(): break pixmap = None type = 0 if serviceref.flags & eServiceReference.mustDescent: if not self.show_times & self.SHOW_DIRECTORIES: continue # hide Directories type = self.REAL_DIR # show Directories pixmap = self.rdirMap info = self.serviceHandler.info(serviceref) if info is None: continue txt = info.getName(serviceref) if serviceref.flags & eServiceReference.mustDescent: files = glob(os.path.join(txt, "*.ts")) # skip empty directories if not files: continue # use mtime of latest recording begin = sorted((os.path.getmtime(x) for x in files))[-1] if pwd and txt.startswith(pwd): txt = txt[len(pwd):] if txt.endswith(os.path.sep): txt = txt[:-len(os.path.sep)] else: begin = info.getInfo(serviceref, iServiceInformation.sTimeCreate) this_tags = info.getInfoString( serviceref, iServiceInformation.sTags).split(' ') # convert space-seperated list of tags into a set if this_tags == ['']: this_tags = [] this_tags = set(this_tags) tags |= this_tags # filter_tags is either None (which means no filter at all), or # a set. In this case, all elements of filter_tags must be present, # otherwise the entry will be dropped. if filter_tags is not None and not this_tags.issuperset( filter_tags): continue service = ServiceReference( info.getInfoString(serviceref, iServiceInformation.sServiceref) ).getServiceName() # Sender description = info.getInfoString(serviceref, iServiceInformation.sDescription) tinfo = [type, pixmap, txt, description, service, -1] self.rootlst.append((serviceref, info, begin, tinfo)) self.rootlst.sort( key=lambda x: -x[2]) # movies of same name stay sortet by time self.rootlst.sort(key=lambda x: (x[3][2] + x[3][3]).lower()) self.list = self.rootlst self.createSublists() if self.sort_type == self.SORT_RECORDED: self.sortLists() # finally, store a list of all tags which were found. these can be presented # to the user to filter the list self.tags = tags if parentLstEntry: # print "[SF-Plugin] SF:MovieList.load: parentLstEntry %s" % (self.debPrtEref(parentLstEntry[0])) self.list.insert(0, parentLstEntry)
def information(self): if self.type == TYPE_SERVICE_INFO: if self.session.nav.getCurrentlyPlayingServiceReference(): name = ServiceReference( self.session.nav.getCurrentlyPlayingServiceReference( )).getServiceName() refstr = self.session.nav.getCurrentlyPlayingServiceReference( ).toString() else: name = _("N/A") refstr = _("N/A") aspect = self.getServiceInfoValue(iServiceInformation.sAspect) if aspect in (1, 2, 5, 6, 9, 0xA, 0xD, 0xE): aspect = _("4:3") else: aspect = _("16:9") width = self.info and self.info.getInfo( iServiceInformation.sVideoWidth) or -1 height = self.info and self.info.getInfo( iServiceInformation.sVideoHeight) or -1 if width != -1 and height != -1: Labels = ((_("Name"), name, TYPE_TEXT), (_("Provider"), self.getServiceInfoValue( iServiceInformation.sProvider), TYPE_TEXT), (_("Aspect ratio"), aspect, TYPE_TEXT), (_("Resolution"), "%dx%d" % (width, height), TYPE_TEXT), (_("Namespace"), self.getServiceInfoValue( iServiceInformation.sNamespace), TYPE_VALUE_HEX, 8), (_("Service reference"), refstr, TYPE_TEXT)) else: Labels = ((_("Name"), name, TYPE_TEXT), (_("Provider"), self.getServiceInfoValue( iServiceInformation.sProvider), TYPE_TEXT), (_("Aspect ratio"), aspect, TYPE_TEXT), (_("Namespace"), self.getServiceInfoValue( iServiceInformation.sNamespace), TYPE_VALUE_HEX, 8), (_("Service reference"), refstr, TYPE_TEXT)) self.fillList(Labels) else: if self.transponder_info: tp_info = ConvertToHumanReadable(self.transponder_info) conv = { "tuner_type": _("Type"), "system": _("System"), "modulation": _("Modulation"), "orbital_position": _("Orbital position"), "frequency": _("Frequency"), "symbol_rate": _("Symbol rate"), "bandwidth": _("Bandwidth"), "polarization": _("Polarization"), "inversion": _("Inversion"), "pilot": _("Pilot"), "rolloff": _("Roll-off"), "fec_inner": _("FEC"), "code_rate_lp": _("Code rate LP"), "code_rate_hp": _("Code rate HP"), "constellation": _("Constellation"), "transmission_mode": _("Transmission mode"), "guard_interval": _("Guard interval"), "hierarchy_information": _("Hierarchy info") } Labels = [(conv[i], tp_info[i], TYPE_VALUE_DEC) for i in tp_info.keys()] self.fillList(Labels)
def preprocess_events_channel(self, services=None): if self.connection is None: cprint("NOT YET CONNECTED") self.size = os_path.getsize( self.epgdb_path) # to continue immediately self.start_process() if services is None: # reset event container self.events = [] return # cprint("EVENTS: %d" % len(self.events)) # one local cursor per table seems to perform slightly better ... cursor_service = self.connection.cursor() cursor_event = self.connection.cursor() cursor_title = self.connection.cursor() cursor_short_desc = self.connection.cursor() cursor_extended_desc = self.connection.cursor() cursor_data = self.connection.cursor() EPG_EVENT_DATA_id = 0 events = [] # now we go through all the channels we got for service in services: # prepare and write CHANNEL INFO record channel = ServiceReference(str(service)).getServiceName().encode( 'ascii', 'ignore') if len(channel) == 0: channel = str(service) ssid = service.split(":") # cprint("SSID %s" % ssid) number_of_events = len(self.events) # only add channels where we have events if number_of_events > 0 and len(ssid) > 6: # convert hex stuff to integer as epg.db likes it to have self.sid = int(ssid[3], 16) self.tsid = int(ssid[4], 16) self.onid = int(ssid[5], 16) self.dvbnamespace = int(ssid[6], 16) # cprint("%x %x %x %x" % (self.sid,self.tsid,self.onid,self.dvbnamespace)) # dvb-t fix: EEEExxxx => EEEE0000 if self.dvbnamespace > 4008574976 and self.dvbnamespace < 4008636143: # cprint("FIXING DVB-T") self.dvbnamespace = 4008574976 if self.dvbnamespace > 2147483647: self.dvbnamespace -= 4294967296 self.EPG_HEADER1_channel_count += 1 cmd = "SELECT id from T_Service WHERE sid=? and tsid=? and onid=? and dvbnamespace=?" cursor_service.execute( cmd, (self.sid, self.tsid, self.onid, self.dvbnamespace)) row = cursor_service.fetchone() if row is not None: self.service_id = int(row[0]) else: cmd = "INSERT INTO T_Service (sid,tsid,onid,dvbnamespace) VALUES(?,?,?,?)" cursor_service.execute( cmd, (self.sid, self.tsid, self.onid, self.dvbnamespace)) self.service_id = cursor_service.lastrowid # triggers will clean up the rest ... hopefully ... cmd = "DELETE FROM T_Event where service_id=%d" % self.service_id cursor_event.execute(cmd) # now we go through all the events for this channel/service_id and add them ... self.event_counter_journal = 0 events = self.events for event in events: # short description (title) self.short_d = event[2] # extended description if len(event[3]) > 0: self.long_d = event[3] else: self.long_d = event[2] self.extended_d = self.long_d if self.long_d.find("\n\n") is not -1: sp = self.long_d.split("\n\n") self.long_d = sp[0] self.extended_d = sp[1] # extract date and time self.begin_time = int(event[0]) self.duration = int(event[1]) if self.duration < 1: self.duration = 1 self.language = event[4] # we need hash values for descriptions, hash is provided by enigma self.short_hash = eEPGCache.getStringHash(self.short_d) self.long_hash = eEPGCache.getStringHash(self.long_d) self.extended_hash = eEPGCache.getStringHash( self.extended_d) # generate an unique dvb event id < 65536 self.dvb_event_id = ( self.begin_time - int(self.begin_time // 3932160) * 3932160) // 60 # cprint("dvb event id: %d" % self.dvb_event_id) if self.short_hash > 2147483647: self.short_hash -= 4294967296 if self.long_hash > 2147483647: self.long_hash -= 4294967296 # now insert into epg.db what we have self.end_time = self.begin_time + self.duration if self.end_time > self.epoch_time and self.begin_time < self.epg_cutoff_time and self.source_id is not None: cmd = "INSERT INTO T_Event (service_id, begin_time, duration, source_id, dvb_event_id) VALUES(?,?,?,?,?)" cursor_event.execute( cmd, (self.service_id, self.begin_time, self.duration, self.source_id, self.dvb_event_id)) self.event_id = cursor_event.lastrowid # check if hash already exists on Title cmd = "SELECT id from T_Title WHERE hash=%d" % self.short_hash cursor_title.execute(cmd) row = cursor_title.fetchone() if row is None: cmd = "INSERT INTO T_Title (hash, title) VALUES(?,?)" cursor_title.execute( cmd, (self.short_hash, self.short_d)) self.title_id = cursor_title.lastrowid else: self.title_id = int(row[0]) cmd = "SELECT id from T_Short_Description WHERE hash=%d" % self.long_hash cursor_short_desc.execute(cmd) row = cursor_short_desc.fetchone() if row is None: cmd = "INSERT INTO T_Short_Description (hash, short_description) VALUES(?,?)" cursor_short_desc.execute( cmd, (self.long_hash, self.long_d)) self.short_description_id = cursor_short_desc.lastrowid else: self.short_description_id = int(row[0]) # check if hash already exists for Extended Description cmd = "SELECT id from T_Extended_Description WHERE hash=%d" % self.extended_hash cursor_extended_desc.execute(cmd) row = cursor_extended_desc.fetchone() if row is None: cmd = "INSERT INTO T_Extended_Description (hash, extended_description) VALUES(?,?)" cursor_extended_desc.execute( cmd, (self.extended_hash, self.extended_d)) self.extended_description_id = cursor_extended_desc.lastrowid else: self.extended_description_id = int(row[0]) cmd = "INSERT INTO T_Data (event_id, title_id, short_description_id, extended_description_id, iso_639_language_code) VALUES(?,?,?,?,?)" cursor_data.execute( cmd, (self.event_id, self.title_id, self.short_description_id, self.extended_description_id, self.language)) # increase journaling counters self.events_in_import_range_journal += 1 self.event_counter_journal += 1 else: self.events_in_past_journal += 1 cprint("ADDED %d from %d events for channel %s" % (self.event_counter_journal, number_of_events, channel)) self.EPG_TOTAL_EVENTS += number_of_events # reset event container self.events = [] cursor_service.close() cursor_event.close() cursor_title.close() cursor_short_desc.close() cursor_extended_desc.close() cursor_data.close()
def addTimer(session, serviceref, begin, end, name, description, disabled, justplay, afterevent, dirname, tags, repeated, vpsinfo=None, logentries=None, eit=0): serviceref = unquote(serviceref) rt = session.nav.RecordTimer print "mao1", dirname if not dirname: dirname = preferredTimerPath() print "mao2", dirname try: timer = RecordTimerEntry(ServiceReference(serviceref), begin, end, name, description, eit, disabled, justplay, afterevent, dirname=dirname, tags=tags) timer.repeated = repeated if logentries: timer.log_entries = logentries conflicts = rt.record(timer) if conflicts: errors = [] for conflict in conflicts: errors.append(conflict.name) return { "result": False, "message": "Conflicting Timer(s) detected! %s" % " / ".join(errors) } #VPS if vpsinfo is not None: timer.vpsplugin_enabled = vpsinfo["vpsplugin_enabled"] timer.vpsplugin_overwrite = vpsinfo["vpsplugin_overwrite"] timer.vpsplugin_time = vpsinfo["vpsplugin_time"] except Exception, e: print e return {"result": False, "message": "Could not add timer '%s'!" % name}
def __init__(self, session, key, args=None): Screen.__init__(self, session) self.skinName = 'ButtonSetupSelect' self['description'] = Label( _('Select the desired function and click on "OK" to assign it. Use "CH+/-" to toggle between the lists. Select an assigned function and click on "OK" to de-assign it. Use "Next/Previous" to change the order of the assigned functions.' )) self.session = session self.key = key self.setTitle(_('Quick button setup for') + ': ' + key[0][0]) self['key_red'] = Button(_('Cancel')) self['key_green'] = Button(_('Save')) self.mode = 'list' self.ButtonSetupFunctions = getButtonSetupFunctions() self.config = eval('config.misc.ButtonSetup.' + key[0][1]) self.expanded = [] self.selected = [] for x in self.config.value.split(','): if x.startswith('ZapPanic'): self.selected.append( ChoiceEntryComponent( '', (_('Panic to') + ' ' + ServiceReference( eServiceReference(x.split( '/', 1)[1]).toString()).getServiceName(), x))) elif x.startswith('Zap'): self.selected.append( ChoiceEntryComponent( '', (_('Zap to') + ' ' + ServiceReference( eServiceReference(x.split( '/', 1)[1]).toString()).getServiceName(), x))) else: function = list((function for function in self.ButtonSetupFunctions if function[1] == x)) if function: self.selected.append( ChoiceEntryComponent('', (function[0][0], function[0][1]))) self.prevselected = self.selected[:] self['choosen'] = ChoiceList(list=self.selected, selection=0) self['list'] = ChoiceList(list=self.getFunctionList(), selection=0) self['actions'] = ActionMap( [ 'OkCancelActions', 'ColorActions', 'DirectionActions', 'KeyboardInputActions' ], { 'ok': self.keyOk, 'cancel': self.cancel, 'red': self.cancel, 'green': self.save, 'up': self.keyUp, 'down': self.keyDown, 'left': self.keyLeft, 'right': self.keyRight, 'upRepeated': self.keyUp, 'downRepeated': self.keyDown, 'leftRepeated': self.keyLeft, 'rightRepeated': self.keyRight, 'pageUp': self.toggleMode, 'pageDown': self.toggleMode, 'moveUp': self.moveUp, 'moveDown': self.moveDown }, -1) self.onLayoutFinish.append(self.__layoutFinished)
def isServicePlayable(self, ref, callback, session=None): self.session = session if self.isProtected(ref): if self.sessionPinCached: return True self.callback = callback service = ref.toCompareString() title = 'FROM BOUQUET "userbouquet.' in service and _("this bouquet is protected by a parental control pin") or _("this service is protected by a parental control pin") if session: Notifications.RemovePopup("Parental control") if self.PinDlg: self.PinDlg.close() self.PinDlg = session.openWithCallback(boundFunction(self.servicePinEntered, ref), PinInput, triesEntry=config.ParentalControl.retries.servicepin, pinList=self.getPinList(), service=ServiceReference(ref).getServiceName(), title=title, windowTitle=_("Parental control"), simple=False) else: Notifications.AddNotificationParentalControl(boundFunction(self.servicePinEntered, ref), PinInput, triesEntry=config.ParentalControl.retries.servicepin, pinList=self.getPinList(), service=ServiceReference(ref).getServiceName(), title=title, windowTitle=_("Parental control")) return False else: return True
def __init__(self, session, service, zapFunc=None, eventid=None, bouquetChangeCB=None, serviceChangeCB=None, parent=None): Screen.__init__(self, session) self.bouquetChangeCB = bouquetChangeCB self.serviceChangeCB = serviceChangeCB self.ask_time = -1 #now self["key_red"] = StaticText("") self.closeRecursive = False self.saved_title = None self["Service"] = ServiceEvent() self["Event"] = Event() self.session = session if isinstance(service, str) and eventid is not None: self.type = EPG_TYPE_SIMILAR self.setTitle(_("Similar EPG")) self["key_yellow"] = StaticText() self["key_blue"] = StaticText() self["key_red"] = StaticText() self.currentService = service self.eventid = eventid self.zapFunc = None elif isinstance(service, eServiceReference) or isinstance( service, str): self.setTitle(_("Single EPG")) self.type = EPG_TYPE_SINGLE self["key_yellow"] = StaticText() self["key_blue"] = StaticText(_("Select Channel")) self.currentService = ServiceReference(service) self.zapFunc = zapFunc self.sort_type = 0 self.setSortDescription() else: self.setTitle(_("Multi EPG")) self.skinName = "EPGSelectionMulti" self.type = EPG_TYPE_MULTI self["key_yellow"] = StaticText( pgettext("button label, 'previous screen'", "Prev")) self["key_blue"] = StaticText( pgettext("button label, 'next screen'", "Next")) self["now_button"] = Pixmap() self["next_button"] = Pixmap() self["more_button"] = Pixmap() self["now_button_sel"] = Pixmap() self["next_button_sel"] = Pixmap() self["more_button_sel"] = Pixmap() self["now_text"] = Label() self["next_text"] = Label() self["more_text"] = Label() self["date"] = Label() self.services = service self.zapFunc = zapFunc self.parent = parent self["key_green"] = StaticText(_("Add timer")) self.key_green_choice = self.ADD_TIMER self.key_red_choice = self.EMPTY self["list"] = EPGList(type=self.type, selChangedCB=self.onSelectionChanged, timer=session.nav.RecordTimer) self["actions"] = ActionMap( ["EPGSelectActions", "OkCancelActions"], { "cancel": self.closeScreen, "ok": self.eventSelected, "timerAdd": self.timerAdd, "yellow": self.yellowButtonPressed, "blue": self.blueButtonPressed, "info": self.infoKeyPressed, "red": self.zapTo, "menu": self.furtherOptions, "nextBouquet": self.nextBouquet, # just used in multi epg yet "prevBouquet": self.prevBouquet, # just used in multi epg yet "nextService": self.nextService, # just used in single epg yet "prevService": self.prevService, # just used in single epg yet "preview": self.eventPreview, }) self["actions"].csel = self self.onLayoutFinish.append(self.onCreate)
def keyGo(self, result=None): if not self.timerentry_service_ref.isRecordable(): self.session.openWithCallback( self.selectChannelSelector, MessageBox, _("You didn't select a channel to record from."), MessageBox.TYPE_ERROR) return self.timer.name = self.timerentry_name.value self.timer.description = self.timerentry_description.value self.timer.justplay = self.timerentry_justplay.value == "zap" self.timer.always_zap = self.timerentry_justplay.value == "zap+record" if self.timerentry_justplay.value == "zap": if not self.timerentry_showendtime.value: self.timerentry_endtime.value = self.timerentry_starttime.value self.timer.resetRepeated() self.timer.afterEvent = { "nothing": AFTEREVENT.NONE, "deepstandby": AFTEREVENT.DEEPSTANDBY, "standby": AFTEREVENT.STANDBY, "auto": AFTEREVENT.AUTO }[self.timerentry_afterevent.value] self.timer.descramble = { "normal": True, "descrambled+ecm": True, "scrambled+ecm": False, }[self.timerentry_recordingtype.value] self.timer.record_ecm = { "normal": False, "descrambled+ecm": True, "scrambled+ecm": True, }[self.timerentry_recordingtype.value] self.timer.service_ref = self.timerentry_service_ref self.timer.tags = self.timerentry_tags if self.timer.dirname or self.timerentry_dirname.value != defaultMoviePath( ): self.timer.dirname = self.timerentry_dirname.value config.movielist.last_timer_videodir.value = self.timer.dirname config.movielist.last_timer_videodir.save() if self.timerentry_type.value == "once": self.timer.begin, self.timer.end = self.getBeginEnd() if self.timerentry_type.value == "repeated": if self.timerentry_repeated.value == "daily": for x in (0, 1, 2, 3, 4, 5, 6): self.timer.setRepeated(x) if self.timerentry_repeated.value == "weekly": self.timer.setRepeated(self.timerentry_weekday.index) if self.timerentry_repeated.value == "weekdays": for x in (0, 1, 2, 3, 4): self.timer.setRepeated(x) if self.timerentry_repeated.value == "user": for x in (0, 1, 2, 3, 4, 5, 6): if self.timerentry_day[x].value: self.timer.setRepeated(x) self.timer.repeatedbegindate = self.getTimestamp( self.timerentry_repeatedbegindate.value, self.timerentry_starttime.value) if self.timer.repeated: self.timer.begin = self.getTimestamp( self.timerentry_repeatedbegindate.value, self.timerentry_starttime.value) self.timer.end = self.getTimestamp( self.timerentry_repeatedbegindate.value, self.timerentry_endtime.value) else: self.timer.begin = self.getTimestamp( time.time(), self.timerentry_starttime.value) self.timer.end = self.getTimestamp( time.time(), self.timerentry_endtime.value) # when a timer end is set before the start, add 1 day if self.timer.end < self.timer.begin: self.timer.end += 86400 if self.timer.eit is not None: event = eEPGCache.getInstance().lookupEventId( self.timer.service_ref.ref, self.timer.eit) if event: n = event.getNumOfLinkageServices() if n > 1: tlist = [] ref = self.session.nav.getCurrentlyPlayingServiceOrGroup() parent = self.timer.service_ref.ref selection = 0 for x in range(n): i = event.getLinkageService(parent, x) if i.toString() == ref.toString(): selection = x tlist.append((i.getName(), i)) self.session.openWithCallback( self.subserviceSelected, ChoiceBox, title=_("Please select a subservice to record..."), list=tlist, selection=selection) return elif n > 0: parent = self.timer.service_ref.ref self.timer.service_ref = ServiceReference( event.getLinkageService(parent, 0)) self.saveTimer() self.close((True, self.timer))
def getMovieList(directory=None, tag=None, rargs=None, locations=None): movieliste = [] if directory is None: directory = MovieSelection.defaultMoviePath() if not directory: directory = "/media/" elif directory[-1] != "/": directory += "/" root = eServiceReference("2:0:1:0:0:0:0:0:0:0:" + directory) bookmarklist=[x for x in listdir(directory) if (x[0] != '.' and (isdir(join(directory, x)) or (islink(join(directory, x)) and exists(join(directory, x)))))] bookmarklist.sort() folders = [] folders.append(root) if rargs and "recursive" in rargs.keys(): for f in bookmarklist: if f[-1] != "/": f += "/" ff = eServiceReference("2:0:1:0:0:0:0:0:0:0:" + directory + f) folders.append(ff) # get all locations if locations is not None: folders = [] for f in locations: if f[-1] != "/": f += "/" ff = eServiceReference("2:0:1:0:0:0:0:0:0:0:" + f) folders.append(ff) if config.OpenWebif.parentalenabled.value: dir_is_protected = checkParentalProtection(directory) else: dir_is_protected = False import os if not dir_is_protected: for root in folders: movielist = MovieList(None) movielist.load(root, None) if tag != None: movielist.reload(root=root, filter_tags=[tag]) #??? loadLength = True for (serviceref, info, begin, unknown) in movielist.list: if serviceref.flags & eServiceReference.mustDescent: continue rtime = info.getInfo(serviceref, iServiceInformation.sTimeCreate) if rtime > 0: t = FuzzyTime(rtime) begin_string = t[0] + ", " + t[1] else: begin_string = "undefined" try: Len = info.getLength(serviceref) except: Len = None filename = '/'.join(serviceref.toString().split("/")[1:]) filename = '/'+filename pos = getPosition(filename + '.cuts', Len) # get txt name, ext = os.path.splitext(filename) ext = ext.lower() txtdesc = "" if ext != 'ts': txtfile = name + '.txt' if fileExists(txtfile): txtlines = open(txtfile).readlines() txtdesc = "" for line in txtlines: txtdesc += line if Len > 0: Len = "%d:%02d" % (Len / 60, Len % 60) else: Len = "?:??" sourceERef = info.getInfoString(serviceref, iServiceInformation.sServiceref) sourceRef = ServiceReference(sourceERef) event = info.getEvent(serviceref) ext = event and event.getExtendedDescription() or "" if ext == '' and txtdesc != '': ext = txtdesc desc = info.getInfoString(serviceref, iServiceInformation.sDescription) servicename = ServiceReference(serviceref).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', '') movie = {} movie['filename'] = filename movie['filename_stripped'] = filename.split("/")[-1] movie['eventname'] = servicename movie['description'] = unicode(desc,'utf_8', errors='ignore').encode('utf_8', 'ignore') movie['begintime'] = begin_string movie['serviceref'] = serviceref.toString() movie['length'] = Len movie['tags'] = info.getInfoString(serviceref, iServiceInformation.sTags) filename = filename.replace("'","\'").replace("%","\%") try: movie['filesize'] = os_stat(filename).st_size except: movie['filesize'] = 0 movie['fullname'] = serviceref.toString() movie['descriptionExtended'] = unicode(ext,'utf_8', errors='ignore').encode('utf_8', 'ignore') movie['servicename'] = sourceRef.getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', '') movie['recordingtime'] = rtime movie['lastseen'] = pos movieliste.append(movie) if locations == None: ml = { "movies": movieliste, "bookmarks": bookmarklist, "directory": directory } else: ml = { "movies": movieliste, "locations": locations} return ml
def subserviceSelected(self, service): if not service is None: self.timer.service_ref = ServiceReference(service[1]) self.saveTimer() self.close((True, self.timer))
def removeMovie(session, sRef, Force=False): service = ServiceReference(sRef) result = False deleted = False message="service error" if service is not None: serviceHandler = eServiceCenter.getInstance() offline = serviceHandler.offlineOperations(service.ref) info = serviceHandler.info(service.ref) name = info and info.getName(service.ref) or "this recording" if offline is not None: if Force == True: message="force delete" elif hasattr(config.usage, 'movielist_trashcan'): fullpath = service.ref.getPath() srcpath = '/'.join(fullpath.split('/')[:-1]) + '/' # TODO: check trash # TODO: check enable trash default value if '.Trash' not in fullpath and config.usage.movielist_trashcan.value: result = False message = "trashcan" try: import Tools.Trashcan trash = Tools.Trashcan.createTrashFolder(srcpath) if trash: res = _moveMovie(session, sRef, destpath=trash) result = res['result'] message = res['message'] except ImportError: message = "trashcan exception" pass deleted = True elif hasattr(config.usage, 'movielist_use_trash_dir'): fullpath = service.ref.getPath() srcpath = '/'.join(fullpath.split('/')[:-1]) + '/' if TRASHDIRNAME not in fullpath and config.usage.movielist_use_trash_dir.value: message = "trashdir" try: trash = _getTrashDir(fullpath) if trash: res = _moveMovie(session, sRef, destpath=trash) result = res['result'] message = res['message'] except ImportError: message = "trashdir exception" pass deleted = True if not deleted: if not offline.deleteFromDisk(0): result = True else: message="no offline object" if result == False: return { "result": False, "message": "Could not delete Movie '%s' / %s" % (name,message) } else: return { "result": True, "message": "The movie '%s' has been deleted successfully" % name }
def editTimer(session, serviceref, begin, end, name, description, disabled, justplay, afterEvent, dirname, tags, repeated, channelOld, beginOld, endOld, vpsinfo, always_zap): channelOld_str = ':'.join(str(channelOld).split(':')[:11]) rt = session.nav.RecordTimer for timer in rt.timer_list + rt.processed_timers: needed_ref = ':'.join( timer.service_ref.ref.toString().split(':')[:11]) == channelOld_str if needed_ref and int(timer.begin) == beginOld and int( timer.end) == endOld: timer.service_ref = ServiceReference(serviceref) # TODO: start end time check timer.begin = int(float(begin)) timer.end = int(float(end)) timer.name = name timer.description = description # TODO : EIT # timer.eit = eit timer.disabled = disabled timer.justplay = justplay timer.afterEvent = afterEvent timer.dirname = dirname timer.tags = tags timer.repeated = repeated timer.processRepeated() if vpsinfo is not None: timer.vpsplugin_enabled = vpsinfo["vpsplugin_enabled"] timer.vpsplugin_overwrite = vpsinfo["vpsplugin_overwrite"] timer.vpsplugin_time = vpsinfo["vpsplugin_time"] if always_zap != -1: if hasattr(timer, "always_zap"): timer.always_zap = always_zap == 1 # TODO: multi tuner test sanity = TimerSanityCheck(rt.timer_list, timer) conflicts = None if not sanity.check(): conflicts = sanity.getSimulTimerList() if conflicts is not None: for conflict in conflicts: if conflict.setAutoincreaseEnd(timer): rt.timeChanged(conflict) if not sanity.check(): conflicts = sanity.getSimulTimerList() if conflicts is None: rt.timeChanged(timer) return { "result": True, "message": _("Timer '%s' changed") % name } else: errors = [] conflictinfo = [] for conflict in conflicts: errors.append(conflict.name) conflictinfo.append({ "serviceref": str(conflict.service_ref), "servicename": conflict.service_ref.getServiceName().replace( '\xc2\x86', '').replace('\xc2\x87', ''), "name": conflict.name, "begin": conflict.begin, "end": conflict.end, "realbegin": strftime("%d.%m.%Y %H:%M", (localtime(float(conflict.begin)))), "realend": strftime("%d.%m.%Y %H:%M", (localtime(float(conflict.end)))) }) return { "result": False, "message": _("Timer '%s' not saved while Conflict") % name, "conflicts": conflictinfo } return { "result": False, "message": _("Could not find timer '%s' with given start and end time!") % name }
def getMovieTags(sRef = None, addtag = None, deltag = None): if sRef is not None: result = False service = ServiceReference(sRef) if service is not None: fullpath = service.ref.getPath() filename = '/'.join(fullpath.split("/")[1:]) metafilename = '/'+filename + '.meta' if fileExists(metafilename): lines = [] with open(metafilename, 'r') as f: lines = f.readlines() if lines: meta = ["","","","","","",""] lines = [l.strip() for l in lines] le = len(lines) meta[0:le] = lines[0:le] oldtags = meta[4].split(' ') if addtag is not None: addtag = addtag.replace(' ','_') try: oldtags.index(addtag) except ValueError: oldtags.append(addtag) if deltag is not None: deltag = deltag.replace(' ','_') else: deltag = 'dummy' newtags = [] for tag in oldtags: if tag != deltag: newtags.append(tag) lines[4] = ' '.join(newtags) with open(metafilename, 'w') as f: f.write('\n'.join(lines)) result = True return { "result": result, "tags" : newtags } return { "result": result, "resulttext" : "Recording not found" } tags = [] wr = False if fileExists(MOVIETAGFILE): for tag in open(MOVIETAGFILE).read().split("\n"): if len(tag.strip()) > 0: if deltag != tag: tags.append(tag.strip()) if addtag == tag: addtag = None if deltag is not None: wr = True if addtag is not None: tags.append(addtag) wr = True if wr: with open(MOVIETAGFILE, 'w') as f: f.write("\n".join(tags)) return { "result": True, "tags": tags }
def __init__(self, session, key, args=None): Screen.__init__(self, session) self.session = session self.key = key getHotkeyFunctions() self.setTitle(_("Hotkey Setup") + " " + key[0][0]) self["key_red"] = StaticText(_("Cancel")) self["key_green"] = StaticText(_("Save")) self["key_yellow"] = StaticText("") self["h_prev"] = Pixmap() self["h_next"] = Pixmap() self["description"] = Label() self.mode = "list" self.config = eval("config.misc.hotkey." + key[0][1]) self.expanded = [] self.selected = [] for x in self.config.value.split(','): if x.startswith("ZapPanic"): self.selected.append( ChoiceEntryComponent( '', ((_("Panic to") + " " + ServiceReference( eServiceReference(x.split( "/", 1)[1]).toString()).getServiceName()), x))) elif x.startswith("Zap"): self.selected.append( ChoiceEntryComponent( '', ((_("Zap to") + " " + ServiceReference( eServiceReference(x.split( "/", 1)[1]).toString()).getServiceName()), x))) else: function = list(function for function in hotkey.functions if function[1] == x) if function: self.selected.append( ChoiceEntryComponent( '', ((function[0][0]), function[0][1]))) text = _( "Press 'OK' for attach next function or 'CH+/-' for edit attached." ) if len(self.selected) else _("Press 'OK' for attach function.") self.prevselected = self.selected[:] if self.prevselected: self["key_yellow"].setText(_("Edit selection")) self["choosen"] = ChoiceList(list=self.selected, selection=0) self["list"] = ChoiceList(list=self.getFunctionList(), selection=0) self["actions"] = ActionMap( [ "OkCancelActions", "ColorActions", "DirectionActions", "KeyboardInputActions", "MenuActions" ], { "ok": self.keyOk, "cancel": self.cancel, "red": self.cancel, "green": self.save, "yellow": self.toggleMode, "up": self.keyUp, "down": self.keyDown, "left": self.keyLeft, "right": self.keyRight, "upRepeated": self.keyUp, "downRepeated": self.keyDown, "leftRepeated": self.keyLeft, "rightRepeated": self.keyRight, "pageUp": self.toggleMode, "pageDown": self.toggleMode, "moveUp": self.moveUp, "moveDown": self.moveDown, "menu": boundFunction(self.close, True), }, -1) self.description(text) self.showPrevNext() self.onLayoutFinish.append(self.__layoutFinished)
def addTimer(session, serviceref, begin, end, name, description, disabled, justplay, afterevent, dirname, tags, repeated, vpsinfo=None, logentries=None, eit=0, always_zap=-1, pipzap=-1, allow_duplicate=1, autoadjust=-1): rt = session.nav.RecordTimer if not dirname: dirname = preferredTimerPath() # IPTV Fix serviceref = serviceref.replace('%253a', '%3a') try: timer = RecordTimerEntry( ServiceReference(serviceref), begin, end, name, description, eit, disabled, justplay, afterevent, dirname=dirname, tags=tags) timer.repeated = repeated if logentries: timer.log_entries = logentries conflicts = rt.record(timer) if conflicts: errors = [] conflictinfo = [] for conflict in conflicts: errors.append(conflict.name) conflictinfo.append({ "serviceref": str(conflict.service_ref), "servicename": conflict.service_ref.getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''), "name": conflict.name, "begin": conflict.begin, "end": conflict.end, "realbegin": strftime(_("%d.%m.%Y %H:%M"), (localtime(float(conflict.begin)))), "realend": strftime(_("%d.%m.%Y %H:%M"), (localtime(float(conflict.end)))) }) return { "result": False, "message": _("Conflicting Timer(s) detected! %s") % " / ".join(errors), "conflicts": conflictinfo } # VPS if vpsinfo is not None: timer.vpsplugin_enabled = vpsinfo["vpsplugin_enabled"] timer.vpsplugin_overwrite = vpsinfo["vpsplugin_overwrite"] timer.vpsplugin_time = vpsinfo["vpsplugin_time"] if always_zap != -1: if hasattr(timer, "always_zap"): timer.always_zap = always_zap == 1 if hasattr(timer, "zapbeforerecord"): timer.zapbeforerecord = always_zap == 1 if hasattr(timer, "autoadjust"): if autoadjust == -1: autoadjust = config.recording.adjust_time_to_event.value and 1 or 0 autoadjust = autoadjust if hasattr(timer, "allow_duplicate"): allow_duplicate = allow_duplicate if pipzap != -1: if hasattr(timer, "pipzap"): timer.pipzap = pipzap == 1 except Exception as e: print(str(e)) return { "result": False, "message": _("Could not add timer '%s'!") % name } return { "result": True, "message": _("Timer '%s' added") % name }
def parseTimer(self, timer, epgcache, serviceHandler, recordHandler, checkEvtLimit, evtLimit, timers, conflicting, similars, skipped, existing, timerdict, moviedict, taskname, simulateOnly=False): new = 0 modified = 0 # enable multiple timer if services or bouquets specified (eg. recording the same event on sd service and hd service) enable_multiple_timer = ((timer.services and 's' in config.plugins.autotimer.enable_multiple_timer.value or False) or (timer.bouquets and 'b' in config.plugins.autotimer.enable_multiple_timer.value or False)) # Precompute timer destination dir dest = timer.destination or config.usage.default_path.value # Workaround to allow search for umlauts if we know the encoding match = timer.match.replace('\xc2\x86', '').replace('\xc2\x87', '') if timer.encoding != 'UTF-8': try: match = match.decode('UTF-8').encode(timer.encoding) except UnicodeDecodeError: pass if timer.searchType == "description": epgmatches = [] casesensitive = timer.searchCase == "sensitive" if not casesensitive: match = match.lower() test = [] if timer.services: test = [(service, 0, -1, -1) for service in timer.services] elif timer.bouquets: for bouquet in timer.bouquets: services = serviceHandler.list(eServiceReference(bouquet)) if services: while True: service = services.getNext() if not service.valid(): break playable = not (service.flags & (eServiceReference.isMarker|eServiceReference.isDirectory)) or (service.flags & eServiceReference.isNumberedMarker) if playable: test.append((service.toString(), 0, -1, -1)) else: # Get all bouquets bouquetlist = [] refstr = '1:134:1:0:0:0:0:0:0:0:FROM BOUQUET \"bouquets.tv\" ORDER BY bouquet' bouquetroot = eServiceReference(refstr) mask = eServiceReference.isDirectory if config.usage.multibouquet.value: bouquets = serviceHandler.list(bouquetroot) if bouquets: while True: s = bouquets.getNext() if not s.valid(): break if s.flags & mask: info = serviceHandler.info(s) if info: bouquetlist.append(s) else: info = serviceHandler.info(bouquetroot) if info: bouquetlist.append(bouquetroot) if bouquetlist: for bouquet in bouquetlist: if not bouquet.valid(): break if bouquet.flags & eServiceReference.isDirectory: services = serviceHandler.list(bouquet) if services: while True: service = services.getNext() if not service.valid(): break playable = not (service.flags & (eServiceReference.isMarker|eServiceReference.isDirectory)) or (service.flags & eServiceReference.isNumberedMarker) if playable: test.append((service.toString(), 0, -1, -1)) if test: # Get all events # eEPGCache.lookupEvent( [ format of the returned tuples, ( service, 0 = event intersects given start_time, start_time -1 for now_time), ] ) test.insert(0, 'RITBDSE') allevents = epgcache.lookupEvent(test) or [] # Filter events for serviceref, eit, name, begin, duration, shortdesc, extdesc in allevents: if match in (shortdesc if casesensitive else shortdesc.lower()) or match in (extdesc if casesensitive else extdesc.lower()): epgmatches.append((serviceref, eit, name, begin, duration, shortdesc, extdesc)) else: # Search EPG, default to empty list epgmatches = epgcache.search( ('RITBDSE', 3000, typeMap[timer.searchType], match, caseMap[timer.searchCase]) ) or [] # Sort list of tuples by begin time 'B' epgmatches.sort(key=itemgetter(3)) # Contains the the marked similar eits and the conflicting strings similardict = defaultdict(list) # Loop over all EPG matches preveit = False for idx, ( serviceref, eit, name, begin, duration, shortdesc, extdesc ) in enumerate( epgmatches ): eserviceref = eServiceReference(serviceref) evt = epgcache.lookupEventId(eserviceref, eit) evtBegin = begin evtEnd = end = begin + duration if not evt: msg="[AutoTimer] Could not create Event!" print(msg) skipped.append((name, begin, end, str(serviceref), timer.name, msg)) continue # Try to determine real service (we always choose the last one) n = evt.getNumOfLinkageServices() if n > 0: i = evt.getLinkageService(eserviceref, n-1) serviceref = i.toString() # If event starts in less than 60 seconds skip it # if begin < time() + 60: # print ("[AutoTimer] Skipping " + name + " because it starts in less than 60 seconds") # skipped += 1 # continue # Set short description to equal extended description if it is empty. if not shortdesc: shortdesc = extdesc # Convert begin time timestamp = localtime(begin) # Update timer timer.update(begin, timestamp) # Check if eit is in similar matches list # NOTE: ignore evtLimit for similar timers as I feel this makes the feature unintuitive similarTimer = False if eit in similardict: similarTimer = True dayofweek = None # NOTE: ignore day on similar timer else: # If maximum days in future is set then check time if checkEvtLimit: if begin > evtLimit: msg="[AutoTimer] Skipping an event because of maximum days in future is reached" # print(msg) skipped.append((name, begin, end, serviceref, timer.name, msg)) continue dayofweek = str(timestamp.tm_wday) # Check timer conditions # NOTE: similar matches do not care about the day/time they are on, so ignore them if timer.checkServices(serviceref) \ or timer.checkDuration(duration) \ or (not similarTimer and (\ timer.checkTimespan(timestamp) \ or timer.checkTimeframe(begin) \ )) or timer.checkFilter(name, shortdesc, extdesc, dayofweek): msg="[AutoTimer] Skipping an event because of filter check" # print(msg) skipped.append((name, begin, end, serviceref, timer.name, msg)) continue if timer.hasOffset(): # Apply custom Offset begin, end = timer.applyOffset(begin, end) offsetBegin = timer.offset[0] offsetEnd = timer.offset[1] else: # Apply E2 Offset begin -= config.recording.margin_before.value * 60 end += config.recording.margin_after.value * 60 offsetBegin = config.recording.margin_before.value * 60 offsetEnd = config.recording.margin_after.value * 60 # Overwrite endtime if requested if timer.justplay and not timer.setEndtime: end = begin # Eventually change service to alternative if timer.overrideAlternatives: serviceref = timer.getAlternative(serviceref) # Append to timerlist and abort if simulating timers.append((name, begin, end, serviceref, timer.name)) if simulateOnly: continue # Check for existing recordings in directory if timer.avoidDuplicateDescription == 3: # Reset movie Exists movieExists = False if dest and dest not in moviedict: self.addDirectoryToMovieDict(moviedict, dest, serviceHandler) for movieinfo in moviedict.get(dest, ()): if self.checkSimilarity(timer, name, movieinfo.get("name"), shortdesc, movieinfo.get("shortdesc"), extdesc, movieinfo.get("extdesc")): print("[AutoTimer] We found a matching recorded movie, skipping event:", name) movieExists = True break if movieExists: msg="[AutoTimer] Skipping an event because movie already exists" # print(msg) skipped.append((name, begin, end, serviceref, timer.name, msg)) continue # Initialize newEntry = None oldExists = False # Check for double Timers # We first check eit and if user wants us to guess event based on time # we try this as backup. The allowed diff should be configurable though. for rtimer in timerdict.get(serviceref, ()): if rtimer.eit == eit or (config.plugins.autotimer.try_guessing.getValue() and timeSimilarityPercent(rtimer, evtBegin, evtEnd, timer) > 80): oldExists = True # Abort if we don't want to modify timers or timer is repeated if config.plugins.autotimer.refresh.value == "none" or rtimer.repeated: # print("[AutoTimer] Won't modify existing timer because either no modification allowed or repeated timer") break if eit == preveit: break if (evtBegin - offsetBegin != rtimer.begin) or (evtEnd + offsetEnd != rtimer.end) or (shortdesc != rtimer.description): if rtimer.isAutoTimer and eit == rtimer.eit: print ("[AutoTimer] AutoTimer %s modified this automatically generated timer." % (timer.name)) # rtimer.log(501, "[AutoTimer] AutoTimer %s modified this automatically generated timer." % (timer.name)) preveit = eit else: if config.plugins.autotimer.refresh.getValue() != "all": print("[AutoTimer] Won't modify existing timer because it's no timer set by us") break rtimer.log(501, "[AutoTimer] Warning, AutoTimer %s messed with a timer which might not belong to it: %s ." % (timer.name, rtimer.name)) newEntry = rtimer modified += 1 self.modifyTimer(rtimer, name, shortdesc, begin, end, serviceref, eit) # rtimer.log(501, "[AutoTimer] AutoTimer modified timer: %s ." % (rtimer.name)) break else: # print("[AutoTimer] Skipping timer because it has not changed.") existing.append((name, begin, end, serviceref, timer.name)) break elif timer.avoidDuplicateDescription >= 1 and not rtimer.disabled: if self.checkSimilarity(timer, name, rtimer.name, shortdesc, rtimer.description, extdesc, rtimer.extdesc ): print("[AutoTimer] We found a timer with similar description, skipping event") oldExists = True break # We found no timer we want to edit if newEntry is None: # But there is a match if oldExists: continue # We want to search for possible doubles for rtimer in chain.from_iterable( itervalues(timerdict) ): if not rtimer.disabled: if self.checkDoubleTimers(timer, name, rtimer.name, begin, rtimer.begin, end, rtimer.end, serviceref, str(rtimer.service_ref), enable_multiple_timer ): oldExists = True print("[AutoTimer] We found a timer with same StartTime, skipping event") break if timer.avoidDuplicateDescription >= 2: if self.checkSimilarity(timer, name, rtimer.name, shortdesc, rtimer.description, extdesc, rtimer.extdesc ): oldExists = True # print("[AutoTimer] We found a timer (any service) with same description, skipping event") break if oldExists: continue if timer.checkCounter(timestamp): print("[AutoTimer] Not adding new timer because counter is depleted.") continue newEntry = RecordTimerEntry(ServiceReference(serviceref), begin, end, name, shortdesc, eit) newEntry.log(500, "[AutoTimer] Try to add new timer based on AutoTimer %s." % (timer.name)) newEntry.log(509, "[AutoTimer] Timer start on: %s" % ctime(begin)) # Mark this entry as AutoTimer (only AutoTimers will have this Attribute set) # It is only temporarily, after a restart it will be lost, # because it won't be stored in the timer xml file newEntry.isAutoTimer = True # Apply afterEvent if timer.hasAfterEvent(): afterEvent = timer.getAfterEventTimespan(localtime(end)) if afterEvent is None: afterEvent = timer.getAfterEvent() if afterEvent is not None: newEntry.afterEvent = afterEvent newEntry.dirname = timer.destination newEntry.justplay = timer.justplay newEntry.vpsplugin_enabled = timer.vps_enabled newEntry.vpsplugin_overwrite = timer.vps_overwrite if hasattr(timer, 'always_zap') and hasattr(newEntry, 'always_zap'): newEntry.always_zap = timer.always_zap tags = timer.tags[:] if config.plugins.autotimer.add_autotimer_to_tags.value: if TAG not in tags: tags.append(TAG) if config.plugins.autotimer.add_name_to_tags.value: tagname = timer.name.strip() if tagname: tagname = tagname[0].upper() + tagname[1:].replace(" ", "_") if tagname not in tags: tags.append(tagname) newEntry.tags = tags if oldExists: # XXX: this won't perform a sanity check, but do we actually want to do so? recordHandler.timeChanged(newEntry) if renameTimer is not None and timer.series_labeling: renameTimer(newEntry, name, evtBegin, evtEnd) else: conflictString = "" if similarTimer: conflictString = similardict[eit].conflictString msg = "[AutoTimer] Try to add similar Timer because of conflicts with %s." % (conflictString) print(msg) newEntry.log(504, msg) # Try to add timer conflicts = recordHandler.record(newEntry) if conflicts and not timer.hasOffset() and not config.recording.margin_before.value and not config.recording.margin_after.value and len(conflicts) > 1: change_end = change_begin = False conflict_begin = conflicts[1].begin conflict_end = conflicts[1].end if conflict_begin == newEntry.end: newEntry.end -= 30 change_end = True elif newEntry.begin == conflict_end: newEntry.begin += 30 change_begin = True if change_end or change_begin: conflicts = recordHandler.record(newEntry) if conflicts: if change_end: newEntry.end += 30 elif change_begin: newEntry.begin -= 30 else: print ("[AutoTimer] The conflict is resolved by offset time begin/end (30 sec) for %s." % newEntry.name) if conflicts: # Maybe use newEntry.log conflictString += ' / '.join(["%s (%s)" % (x.name, strftime("%Y%m%d %H%M", localtime(x.begin))) for x in conflicts]) print("[AutoTimer] conflict with %s detected" % (conflictString)) if config.plugins.autotimer.addsimilar_on_conflict.value: # We start our search right after our actual index # Attention we have to use a copy of the list, because we have to append the previous older matches lepgm = len(epgmatches) for i in xrange(lepgm): servicerefS, eitS, nameS, beginS, durationS, shortdescS, extdescS = epgmatches[ (i+idx+1)%lepgm ] if self.checkSimilarity(timer, name, nameS, shortdesc, shortdescS, extdesc, extdescS, force=True ): # Check if the similar is already known if eitS not in similardict: print("[AutoTimer] Found similar Timer: " + name) # Store the actual and similar eit and conflictString, so it can be handled later newEntry.conflictString = conflictString similardict[eit] = newEntry similardict[eitS] = newEntry similarTimer = True if beginS <= evtBegin: # Event is before our actual epgmatch so we have to append it to the epgmatches list epgmatches.append((servicerefS, eitS, nameS, beginS, durationS, shortdescS, extdescS)) # If we need a second similar it will be found the next time else: similarTimer = False newEntry = similardict[eitS] break if conflicts is None: timer.decrementCounter() new += 1 newEntry.extdesc = extdesc timerdict[serviceref].append(newEntry) if renameTimer is not None and timer.series_labeling: renameTimer(newEntry, name, evtBegin, evtEnd) # Similar timers are in new timers list and additionally in similar timers list if similarTimer: similars.append((name, begin, end, serviceref, timer.name)) similardict.clear() # Don't care about similar timers elif not similarTimer: conflicting.append((name, begin, end, serviceref, timer.name)) if config.plugins.autotimer.disabled_on_conflict.value: msg = "[AutoTimer] Timer disabled because of conflicts with %s." % (conflictString) print(msg) newEntry.log(503, msg) newEntry.disabled = True # We might want to do the sanity check locally so we don't run it twice - but I consider this workaround a hack anyway conflicts = recordHandler.record(newEntry) self.result=(new, modified) self.completed.append(taskname) sleep(0.5)
def buildMovieListEntry(self, _directory, file_type, path, _file_name, _ext, name, event_start_time, _recording_start_time, _recording_stop_time, length, description, _extended_description, service_reference, _size, cuts, tags): def isCutting(path): logger.debug("isCutting: path: %s", path) file_name = os.path.splitext(path)[0] return file_name.endswith("_") and not os.path.exists(file_name + ".eit") def getPicon(service_reference): pos = service_reference.rfind(':') if pos != -1: service_reference = service_reference[:pos].rstrip( ':').replace(':', '_') picon_path = os.path.join( config.usage.configselection_piconspath.value, service_reference + '.png') logger.debug("picon_path: %s", picon_path) return loadPNG(picon_path) def getDateText(path, file_type, date): logger.debug("path: %s, file_type: %s, date: %s", path, file_type, date) count = 0 date_text = "" if path in self.lock_list: file_op = self.lock_list[path] if file_op == FILE_OP_COPY: date_text = _("COPYING") elif file_op == FILE_OP_MOVE: date_text = _("MOVING") elif file_op == FILE_OP_DELETE: date_text = _("DELETING") else: if file_type == FILE_TYPE_FILE: if config.plugins.moviecockpit.list_show_mount_points.value: words = path.split("/") if len(words) > 3 and words[1] == "media": date_text = words[2] else: date_text = datetime.fromtimestamp(date).strftime( config.plugins.moviecockpit.movie_date_format.value ) else: if os.path.basename(path) == "trashcan": info_value = config.plugins.moviecockpit.trashcan_info.value else: info_value = config.plugins.moviecockpit.directories_info.value if os.path.basename(path) == "..": date_text = _("up") else: if info_value == "D": if os.path.basename(path) == "trashcan": date_text = _("trashcan") else: date_text = _("directory") else: count, size = FileManager.getInstance( ).getCountSize(path) counttext = "%d" % count size /= (1024 * 1024 * 1024) # GB sizetext = "%.0f GB" % size if size >= 1024: sizetext = "%.1f TB" % (size / 1024) if info_value == "C": date_text = "(%s)" % counttext elif info_value == "S": date_text = "(%s)" % sizetext elif info_value == "CS": date_text = "(%s/%s)" % (counttext, sizetext) logger.debug("count: %s, date_text: %s", count, date_text) return date_text def getProgress(recording, path, event_start_time, length, cuts): logger.debug("path: %s", path) if recording: last = time() - event_start_time else: # get last position from cut file cut_list = unpackCutList(cuts) logger.debug("cut_list: %s", cut_list) last = ptsToSeconds(getCutListLast(cut_list)) logger.debug("last: %s", last) progress = 0 if length > 0 and last > 0: last = min(last, length) progress = int(round(float(last) / float(length), 2) * 100) logger.debug("progress: %s, path: %s, length: %s, recording: %s", progress, path, length, recording) return progress def getFileIcon(path, file_type, progress, recording, cutting): pixmap = None if file_type == FILE_TYPE_FILE: pixmap = self.pic_movie_default if recording: pixmap = self.pic_movie_rec elif cutting: pixmap = self.pic_movie_cut else: if progress >= int(config.plugins.moviecockpit. movie_finished_percent.value): pixmap = self.pic_movie_finished elif progress >= int(config.plugins.moviecockpit. movie_watching_percent.value): pixmap = self.pic_movie_watching elif file_type == FILE_TYPE_LINK: pixmap = self.pic_link elif file_type == FILE_TYPE_DIR: pixmap = self.pic_directory if os.path.basename(path) == "trashcan": pixmap = self.pic_trashcan elif os.path.basename(path) == "..": pixmap = self.pic_back return pixmap def getColor(path, file_type, recording, cutting): if path in self.selection_list or path in self.lock_list: color = self.selection_color color_sel = self.selection_color_sel else: if file_type == FILE_TYPE_FILE: if recording or cutting: color = self.recording_color color_sel = self.recording_color_sel else: color = self.color color_sel = self.color_sel else: color = self.color_sel color_sel = self.color_sel return color, color_sel logger.debug("list_style: %s", self.list_styles[self.list_style][0]) service = ServiceReference(service_reference) service_name = service.getServiceName() if service is not None else "" recording = isRecording(path) cutting = isCutting(path) color, color_sel = getColor(path, file_type, recording, cutting) progress = getProgress(recording, path, event_start_time, length, cuts) if file_type == FILE_TYPE_FILE else -1 progress_string = str(progress) + "%" if progress >= 0 else "" progress_bar = self.pic_rec_progress_bar if recording else self.pic_progress_bar length_string = str(length / 60) + " " + _( "min") if file_type == FILE_TYPE_FILE else "" picon = getPicon( service_reference) if file_type == FILE_TYPE_FILE else None name = _(name) if name == "trashcan" else name date_text = getDateText(path, file_type, event_start_time) file_icon = getFileIcon(path, file_type, progress, recording, cutting) res = [ None, name, # 1: name tags, # 2: tags service_name, # 3: service name description, # 4: short description date_text, # 5: event start time length_string, # 6: length color, # 7: color color_sel, # 8: color_sel progress, # 9: progress percent (-1 = don't show) progress_string, # 10: progress (xx%) progress_bar, # 11: progress bar png file_icon, # 12: status icon png picon, # 13: picon png ] #logger.debug("self.res: %s", res) return res
def getMovieList(rargs=None, locations=None): movieliste = [] tag = None directory = None fields = None internal = None bookmarklist = [] if rargs: tag = getUrlArg2(rargs, "tag") directory = getUrlArg2(rargs, "dirname") fields = getUrlArg2(rargs, "fields") internal = getUrlArg2(rargs, "internal") if directory is None: directory = defaultMoviePath() else: if not PY3: try: directory.decode('utf-8') except UnicodeDecodeError: try: directory = directory.decode("cp1252").encode("utf-8") except UnicodeDecodeError: directory = directory.decode("iso-8859-1").encode("utf-8") if not directory: directory = MOVIE_LIST_ROOT_FALLBACK if directory[-1] != "/": directory += "/" if not os.path.isdir(directory): return { "movies": [], "locations": [], "bookmarks": [], "directory": [], } root = eServiceReference(MOVIE_LIST_SREF_ROOT + directory) for item in sorted(os.listdir(directory)): abs_p = os.path.join(directory, item) if os.path.isdir(abs_p): bookmarklist.append(item) folders = [root] brecursive = False if rargs and b"recursive" in list(rargs.keys()): brecursive = True dirs = [] locations = [] if PY3: from glob import glob for subdirpath in glob(directory + "**/", recursive=True): locations.append(subdirpath) subdirpath = subdirpath[len(directory):] dirs.append(subdirpath) else: # FIXME SLOW!!! for subdirpath in [x[0] for x in os.walk(directory)]: locations.append(subdirpath) subdirpath = subdirpath[len(directory):] dirs.append(subdirpath) for f in sorted(dirs): if f != '': if f[-1] != "/": f += "/" ff = eServiceReference(MOVIE_LIST_SREF_ROOT + directory + f) folders.append(ff) else: # get all locations if locations is not None: folders = [] for f in locations: if f[-1] != "/": f += "/" ff = eServiceReference(MOVIE_LIST_SREF_ROOT + f) folders.append(ff) if config.OpenWebif.parentalenabled.value: dir_is_protected = checkParentalProtection(directory) else: dir_is_protected = False if not dir_is_protected: if internal: try: from .OWFMovieList import MovieList as OWFMovieList movielist = OWFMovieList(None) except ImportError: movielist = MovieList(None) pass else: movielist = MovieList(None) for root in folders: if tag is not None: movielist.load(root=root, filter_tags=[tag]) else: movielist.load(root=root, filter_tags=None) for (serviceref, info, begin, unknown) in movielist.list: if serviceref.flags & eServiceReference.mustDescent: continue # BAD fix _serviceref = serviceref.toString().replace('%25', '%') length_minutes = 0 txtdesc = "" filename = '/'.join(_serviceref.split("/")[1:]) filename = '/' + filename name, ext = os.path.splitext(filename) sourceRef = ServiceReference( info.getInfoString(serviceref, iServiceInformation.sServiceref)) rtime = info.getInfo(serviceref, iServiceInformation.sTimeCreate) movie = { 'filename': filename, 'filename_stripped': filename.split("/")[-1], 'serviceref': _serviceref, 'length': "?:??", 'lastseen': 0, 'filesize_readable': '', 'recordingtime': rtime, 'begintime': 'undefined', 'eventname': ServiceReference(serviceref).getServiceName().replace( '\xc2\x86', '').replace('\xc2\x87', ''), 'servicename': sourceRef.getServiceName().replace('\xc2\x86', '').replace( '\xc2\x87', ''), 'tags': info.getInfoString(serviceref, iServiceInformation.sTags), 'fullname': _serviceref, } if rtime > 0: movie['begintime'] = FuzzyTime2(rtime) try: length_minutes = info.getLength(serviceref) except: # nosec # noqa: E722 pass if length_minutes: movie['length'] = "%d:%02d" % (length_minutes / 60, length_minutes % 60) if fields is None or 'pos' in fields: movie['lastseen'] = _moviePlayState( filename + '.cuts', serviceref, length_minutes) or 0 if fields is None or 'desc' in fields: txtfile = name + '.txt' if ext.lower() != '.ts' and os.path.isfile(txtfile): with open(txtfile, "rb") as handle: txtdesc = six.ensure_str(b''.join( handle.readlines())) event = info.getEvent(serviceref) extended_description = event and event.getExtendedDescription( ) or "" if extended_description == '' and txtdesc != '': extended_description = txtdesc movie['descriptionExtended'] = ConvertDesc( extended_description) desc = info.getInfoString(serviceref, iServiceInformation.sDescription) movie['description'] = ConvertDesc(desc) if fields is None or 'size' in fields: size = 0 sz = '' try: size = os.stat(filename).st_size if size > 1073741824: sz = "%.2f %s" % ((size / 1073741824.), _("GB")) elif size > 1048576: sz = "%.2f %s" % ((size / 1048576.), _("MB")) elif size > 1024: sz = "%.2f %s" % ((size / 1024.), _("kB")) except: # nosec # noqa: E722 pass movie['filesize'] = size movie['filesize_readable'] = sz movieliste.append(movie) # del movielist if locations is None: return { "movies": movieliste, "bookmarks": bookmarklist, "directory": directory, "recursive": brecursive } if brecursive: return { "movies": movieliste, "locations": locations, "directory": directory, "bookmarks": bookmarklist, "recursive": brecursive } else: return { "movies": movieliste, "locations": locations, "recursive": brecursive }
def buildMovieListEntry(self, serviceref, info, begin, data): switch = config.usage.show_icons_in_movielist.value ext = config.movielist.useextlist.value width = self.l.getItemSize().width() pathName = serviceref.getPath() res = [None] if ext != '0': ih = self.itemHeight // 2 else: ih = self.itemHeight if self.screenwidth and self.screenwidth == 1920: listBeginX = 3 listEndX = 3 listMarginX = 12 pathIconSize = 29 dataIconSize = 25 progressIconSize = 25 progressBarSize = 72 textPosY = 2 else: listBeginX = 2 listEndX = 2 listMarginX = 8 pathIconSize = 25 dataIconSize = 21 progressIconSize = 21 progressBarSize = 48 textPosY = 1 textPosX = listBeginX + dataIconSize + listMarginX if serviceref.flags & eServiceReference.mustDescent: # Directory iconSize = pathIconSize iconPosX = listBeginX - 1 iconPosY = ih / 2 - iconSize / 2 if iconPosY < iconPosX: iconPosY = iconPosX # Name is full path name if info is None: # Special case: "parent" txt = ".." else: p = os.path.split(pathName) if not p[1]: # if path ends in '/', p is blank. p = os.path.split(p[0]) txt = p[1] if txt == ".Trash": dateSize = getTextBoundarySize(self.instance, self.dateFont, self.l.getItemSize(), _("Trashcan")).width() res.append( MultiContentEntryPixmapAlphaBlend(pos=(iconPosX, iconPosY), size=(iconSize, iconSize), png=self.iconTrash)) res.append( MultiContentEntryText( pos=(textPosX, 0), size=(width - textPosX - dateSize - listMarginX - listEndX, ih), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=_("Deleted items"))) res.append( MultiContentEntryText( pos=(width - dateSize - listEndX, textPosY), size=(dateSize, self.itemHeight), font=1, flags=RT_HALIGN_RIGHT | RT_VALIGN_CENTER, text=_("Trashcan"))) return res dateSize = getTextBoundarySize(self.instance, self.dateFont, self.l.getItemSize(), _("Directory")).width() res.append( MultiContentEntryPixmapAlphaBlend(pos=(iconPosX, iconPosY), size=(iconSize, iconSize), png=self.iconFolder)) res.append( MultiContentEntryText(pos=(textPosX, 0), size=(width - textPosX - dateSize - listMarginX - listEndX, ih), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=txt)) res.append( MultiContentEntryText(pos=(width - dateSize - listEndX, textPosY), size=(dateSize, self.itemHeight), font=1, flags=RT_HALIGN_RIGHT | RT_VALIGN_CENTER, text=_("Directory"))) return res if (data == -1) or (data is None): data = MovieListData() cur_idx = self.l.getCurrentSelectionIndex() x = self.list[cur_idx] # x = ref,info,begin,... data.len = 0 #dont recalc movielist to speedup loading the list self.list[cur_idx] = ( x[0], x[1], x[2], data ) #update entry in list... so next time we don't need to recalc data.txt = info.getName(serviceref) if config.movielist.hide_extensions.value: fileName, fileExtension = os.path.splitext(data.txt) if fileExtension in KNOWN_EXTENSIONS: data.txt = fileName data.icon = None data.part = None if os.path.split(pathName)[1] in self.runningTimers: if switch == 'i': if (self.playInBackground or self.playInForeground ) and serviceref == (self.playInBackground or self.playInForeground): data.icon = self.iconMoviePlayRec else: data.icon = self.iconMovieRec elif switch == 'p' or switch == 's': data.part = 100 if (self.playInBackground or self.playInForeground ) and serviceref == (self.playInBackground or self.playInForeground): data.partcol = 0xffc71d else: data.partcol = 0xff001d elif (self.playInBackground or self.playInForeground) and serviceref == ( self.playInBackground or self.playInForeground): data.icon = self.iconMoviePlay else: data.part = moviePlayState(pathName + '.cuts', serviceref, data.len) if switch == 'i': if data.part is not None and data.part > 0: data.icon = self.iconPart[data.part // 25] else: if config.usage.movielist_unseen.value: data.icon = self.iconUnwatched elif switch == 'p' or switch == 's': if data.part is not None and data.part > 0: data.partcol = 0xffc71d else: if config.usage.movielist_unseen.value: data.part = 100 data.partcol = 0x206333 len = data.len if len > 0: len = "%d:%02d" % (len // 60, len % 60) else: len = "" iconSize = 0 if switch == 'i': iconSize = dataIconSize iconPosX = listBeginX iconPosY = ih // 2 - iconSize // 2 if iconPosY < iconPosX: iconPosY = iconPosX res.append( MultiContentEntryPixmapAlphaBlend(pos=(iconPosX, iconPosY), size=(iconSize, iconSize), png=data.icon)) elif switch == 'p': if data.part is not None and data.part > 0: iconSize = progressBarSize iconPosX = listBeginX iconPosY = ih // 2 - iconSize // 8 if iconPosY < iconPosX: iconPosY = iconPosX res.append( MultiContentEntryProgress(pos=(iconPosX, iconPosY), size=(iconSize, iconSize // 4), percent=data.part, borderWidth=2, foreColor=data.partcol, foreColorSelected=None, backColor=None, backColorSelected=None)) else: iconSize = dataIconSize iconPosX = listBeginX iconPosY = ih // 2 - iconSize // 2 if iconPosY < iconPosX: iconPosY = iconPosX res.append( MultiContentEntryPixmapAlphaBlend(pos=(iconPosX, iconPosY), size=(iconSize, iconSize), png=data.icon)) elif switch == 's': iconSize = progressIconSize iconPosX = listBeginX iconPosY = ih // 2 - iconSize // 2 if iconPosY < iconPosX: iconPosY = iconPosX if data.part is not None and data.part > 0: res.append( MultiContentEntryProgress(pos=(iconPosX, iconPosY), size=(iconSize, iconSize), percent=data.part, borderWidth=2, foreColor=data.partcol, foreColorSelected=None, backColor=None, backColorSelected=None)) else: res.append( MultiContentEntryPixmapAlphaBlend(pos=(iconPosX, iconPosY), size=(iconSize, iconSize), png=data.icon)) begin_string = "" if begin > 0: begin_string = ', '.join(FuzzyTime(begin, inPast=True)) dateSize = serviceSize = getTextBoundarySize(self.instance, self.dateFont, self.l.getItemSize(), begin_string).width() if iconSize: textPosX = listBeginX + iconSize + listMarginX else: textPosX = listBeginX if ext != '0': getrec = info.getName(serviceref) fileName, fileExtension = os.path.splitext(getrec) desc = None picon = None service = None try: serviceHandler = eServiceCenter.getInstance() info = serviceHandler.info(serviceref) desc = info.getInfoString( serviceref, iServiceInformation.sDescription) # get description ref = info.getInfoString( serviceref, iServiceInformation.sServiceref) # get reference service = ServiceReference( ref).getServiceName() # get service name serviceSize = getTextBoundarySize(self.instance, self.dateFont, self.l.getItemSize(), service).width() except Exception as e: print(('[MovieList] load extended infos get failed: ', e)) if ext == '2': try: picon = getPiconName(ref) picon = loadPNG(picon) except Exception as e: print(('[MovieList] load picon get failed: ', e)) if fileExtension in RECORD_EXTENSIONS: if ext == '1': res.append( MultiContentEntryText( pos=(textPosX, 0), size=(width - textPosX - serviceSize - listMarginX - listEndX, ih), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=data.txt)) res.append( MultiContentEntryText( pos=(width - serviceSize - listEndX, textPosY), size=(serviceSize, ih), font=1, flags=RT_HALIGN_RIGHT | RT_VALIGN_CENTER, text=service)) if ext == '2': piconSize = ih * 1.667 res.append( MultiContentEntryText( pos=(textPosX, 0), size=(width - textPosX - dateSize - listMarginX - listEndX, ih), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=data.txt)) res.append( MultiContentEntryPixmapAlphaTest( pos=(width - piconSize - listEndX, listEndX), size=(piconSize, ih), png=picon, flags=BT_SCALE | BT_KEEP_ASPECT_RATIO)) res.append( MultiContentEntryText(pos=(listBeginX, ih + textPosY), size=(width - listBeginX - dateSize - listMarginX - listEndX, ih), font=1, flags=RT_HALIGN_LEFT, text=desc)) res.append( MultiContentEntryText(pos=(width - dateSize - listEndX, ih + textPosY), size=(dateSize, ih), font=1, flags=RT_HALIGN_RIGHT, text=begin_string)) return res else: res.append( MultiContentEntryText(pos=(textPosX, 0), size=(width - textPosX - dateSize - listMarginX - listEndX, ih), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=data.txt)) res.append( MultiContentEntryText(pos=(width - dateSize - listEndX, ih), size=(dateSize, ih), font=1, flags=RT_HALIGN_RIGHT, text=begin_string)) return res else: res.append( MultiContentEntryText(pos=(textPosX, 0), size=(width - textPosX - dateSize - listMarginX - listEndX, ih), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=data.txt)) res.append( MultiContentEntryText(pos=(width - dateSize - listEndX, textPosY), size=(dateSize, ih), font=1, flags=RT_HALIGN_RIGHT | RT_VALIGN_CENTER, text=begin_string)) return res
def removeMovie(session, sRef, Force=False): service = ServiceReference(sRef) result = False deleted = False message = "service error" if service is not None: serviceHandler = eServiceCenter.getInstance() offline = serviceHandler.offlineOperations(service.ref) info = serviceHandler.info(service.ref) name = info and info.getName(service.ref) or "this recording" if offline is not None: if Force is True: message = "force delete" elif hasattr(config.usage, 'movielist_trashcan'): fullpath = service.ref.getPath() srcpath = '/'.join(fullpath.split('/')[:-1]) + '/' # TODO: check trash # TODO: check enable trash default value if '.Trash' not in fullpath and config.usage.movielist_trashcan.value: result = False message = "trashcan" try: import Tools.Trashcan from Screens.MovieSelection import moveServiceFiles trash = Tools.Trashcan.createTrashFolder(srcpath) moveServiceFiles(service.ref, trash) result = True message = "The recording '%s' has been successfully moved to trashcan" % name except ImportError: message = "trashcan exception" pass except Exception as e: message = "Failed to move to .Trash folder: %s" + str(e) print(message) deleted = True elif hasattr(config.usage, 'movielist_use_trash_dir'): fullpath = service.ref.getPath() if TRASHDIRNAME not in fullpath and config.usage.movielist_use_trash_dir.value: message = "trashdir" try: from Screens.MovieSelection import getTrashDir from Components.FileTransfer import FileTransferJob from Components.Task import job_manager trash_dir = getTrashDir(fullpath) if trash_dir: src_file = str(fullpath) dst_file = trash_dir if dst_file.endswith("/"): dst_file = trash_dir[:-1] text = _("remove") job_manager.AddJob( FileTransferJob(src_file, dst_file, False, False, "%s : %s" % (text, src_file))) # No Result because of async job message = "The recording '%s' has been successfully moved to trashcan" % name result = True else: message = _( "Delete failed, because there is no movie trash !\nDisable movie trash in configuration to delete this item" ) except ImportError: message = "trashdir exception" pass except Exception as e: message = "Failed to move to trashdir: %s" + str(e) print(message) deleted = True if not deleted: if not offline.deleteFromDisk(0): result = True else: message = "no offline object" if result is False: return { "result": False, "message": "Could not delete Movie '%s' / %s" % (name, message) } else: # EMC reload try: config.EMC.needsreload.value = True except (AttributeError, KeyError): pass return { "result": True, "message": "The movie '%s' has been deleted successfully" % name }
def finishedChannelSelection(self, *args): if args: self.timerentry_service_ref = ServiceReference(args[0]) self.timerentry_service.setCurrentText( self.timerentry_service_ref.getServiceName()) self["config"].invalidate(self.channelEntry)
def getMovieInfo(sRef=None, addtag=None, deltag=None, title=None, cuts=None, NewFormat=False): if sRef is not None: result = False service = ServiceReference(sRef) newtags = [] newtitle = '' newcuts = [] if service is not None: fullpath = service.ref.getPath() filename = '/'.join(fullpath.split("/")[1:]) metafilename = '/' + filename + '.meta' if fileExists(metafilename): lines = [] with open(metafilename, 'r') as f: lines = f.readlines() if lines: meta = ["", "", "", "", "", "", ""] lines = [l.strip() for l in lines] le = len(lines) meta[0:le] = lines[0:le] oldtags = meta[4].split(' ') newtitle = meta[1] deltags = [] if addtag is not None: for _add in addtag.split(','): __add = _add.replace(' ', '_') if __add not in oldtags: oldtags.append(__add) if deltag is not None: for _del in deltag.split(','): __del = _del.replace(' ', '_') deltags.append(__del) for _add in oldtags: if _add not in deltags: newtags.append(_add) lines[4] = ' '.join(newtags) if title is not None and len(title) > 0: lines[1] = title newtitle = title with open(metafilename, 'w') as f: f.write('\n'.join(lines)) if not NewFormat: return {"result": result, "tags": newtags} cutsFileName = '/' + filename + '.cuts' if fileExists(cutsFileName): try: f = open(cutsFileName, 'rb') while True: data = f.read(cutsParser.size) if len(data) < cutsParser.size: break _pos, _type = cutsParser.unpack(data) newcuts.append({"type": _type, "pos": _pos}) f.close() except: # nosec # noqa: E722 print('Error') pass if cuts is not None: newcuts = [] cutsFileName = '/' + filename + '.cuts' f = open(cutsFileName, 'wb') for cut in cuts.split(','): item = cut.split(':') f.write(cutsParser.pack(int(item[1]), int(item[0]))) newcuts.append({"type": item[0], "pos": item[1]}) f.close() result = True return { "result": result, "tags": newtags, "title": newtitle, "cuts": newcuts } return {"result": result, "resulttext": "Recording not found"} tags = [] wr = False if fileExists(MOVIETAGFILE): for tag in open(MOVIETAGFILE).read().split("\n"): if len(tag.strip()) > 0: if deltag != tag: tags.append(tag.strip()) if addtag == tag: addtag = None if deltag is not None: wr = True if addtag is not None: tags.append(addtag) wr = True if wr: with open(MOVIETAGFILE, 'w') as f: f.write("\n".join(tags)) return {"result": True, "tags": tags}
def editTimer(self, param): print "[WebComponents.Timer] editTimer" #OK first we need to parse all of your Parameters #For some of them (like afterEvent or justplay) we can use default values #for others (the serviceReference or the Begin/End time of the timer #we have to quit if they are not set/have illegal values if 'sRef' not in param: return (False, "Missing Parameter: sRef") service_ref = ServiceReference(param['sRef']) repeated = int(param.get('repeated') or 0) if 'begin' not in param: return (False, "Missing Parameter: begin") begin = int(float(param['begin'])) if 'end' not in param: return (False, "Missing Parameter: end") end = int(float(param['end'])) tm = time() if tm <= begin: pass elif tm > begin and tm < end and repeated == 0: begin = time() elif repeated == 0: return (False, "Illegal Parameter value for Parameter begin : '%s'" % begin) if 'name' not in param: return (False, "Missing Parameter: name") name = param['name'] if 'description' not in param: return (False, "Missing Parameter: description") description = param['description'].replace("\n", " ") disabled = False #Default to: Enabled if 'disabled' in param: if param['disabled'] == "1": disabled = True else: #TODO - maybe we can give the user some useful hint here pass justplay = False #Default to: Record if 'justplay' in param: if param['justplay'] == "1": justplay = True afterEvent = 3 #Default to Afterevent: Auto if 'afterevent' in param: if (param['afterevent'] == "0") or (param['afterevent'] == "1") or (param['afterevent'] == "2"): afterEvent = int(param['afterevent']) dirname = config.movielist.last_timer_videodir.value if 'dirname' in param and param['dirname']: dirname = param['dirname'] tags = [] if 'tags' in param and param['tags']: tags = unescape(param['tags']).split(' ') delold = 0 if 'deleteOldOnSave' in param: delold = int(param['deleteOldOnSave']) #Try to edit an existing Timer if delold: if 'channelOld' in param and param['channelOld']: channelOld = ServiceReference(param['channelOld']) else: return (False, "Missing Parameter: channelOld") # We do need all of the following Parameters, too, for being able of finding the Timer. # Therefore so we can neither use default values in this part nor can we # continue if a parameter is missing if 'beginOld' not in param: return (False, "Missing Parameter: beginOld") beginOld = int(param['beginOld']) if 'endOld' not in param: return (False, "Missing Parameter: endOld") endOld = int(param['endOld']) #let's try to find the timer try: for timer in self.recordtimer.timer_list + self.recordtimer.processed_timers: if str(timer.service_ref) == str(channelOld): if int(timer.begin) == beginOld: if int(timer.end) == endOld: #we've found the timer we've been searching for #Delete the old entry self.recordtimer.removeEntry(timer) old = timer timer = RecordTimerEntry(service_ref, begin, end, name, description, 0, disabled, justplay, afterEvent, dirname=dirname, tags=tags) timer.repeated = repeated timer.log_entries = old.log_entries timer.processRepeated() #send the changed timer back to enigma2 and hope it's good conflicts = self.recordtimer.record(timer) if conflicts is None: print "[WebComponents.Timer] editTimer: Timer changed!" return (True, "Timer '%s' changed" % (timer.name)) else: print "[WebComponents.Timer] editTimer conflicting Timers: %s" % ( conflicts) msg = "" for timer in conflicts: msg = "%s / %s" % (msg, timer.name) return ( False, "Conflicting Timer(s) detected! %s" % (msg)) except Exception: #obviously some value was not good, return an error return (False, "Changing the timer for '%s' failed!" % name) return ( False, "Could not find timer '%s' with given start and end time!" % name) #Try adding a new Timer try: #Create a new instance of recordtimerentry timer = RecordTimerEntry(service_ref, begin, end, name, description, 0, disabled, justplay, afterEvent, dirname=dirname, tags=tags) timer.repeated = repeated #add the new timer conflicts = self.recordtimer.record(timer) if conflicts is None: return (True, "Timer '%s' added" % (timer.name)) else: print "[WebComponents.Timer] editTimer conflicting Timers: %s" % ( conflicts) msg = "" for timer in conflicts: msg = "%s / %s" % (msg, timer.name) return (False, "Conflicting Timer(s) detected! %s" % (msg)) except Exception, e: #something went wrong, most possibly one of the given paramater-values was wrong print "[WebComponents.Timer] editTimer exception: %s" % (e) return (False, "Could not add timer '%s'!" % name)