예제 #1
0
				def parse(root):
					channels = {}
					version = root.get("version", "1")
					if version.startswith("1"):
						log.warning( _("Skipping old channels file") )
					elif version.startswith("2") or version.startswith("3") or version.startswith("4"):
						log.debug("Channel XML Version 4")
						ChannelsBase.channels_changed = True
						if root:
							for element in root.findall("Channel"):
								name = element.get("name", "")
								reference = element.get("reference", "")
								if name and reference:
									alternatives = []
									for alternative in element.findall("Alternative"):
										alternatives.append( alternative.text )
									channels[reference] = (name, list(set(alternatives)))
									log.debug("Channel", reference, channels[reference] )
					else:
						# XMLTV compatible channels file
						log.debug("Channel XML Version 5")
						if root:
							for element in root.findall("channel"):
								alternatives = []
								id = readFromXML(element.get("id", ""))
								alternatives.append( id )
								name = readFromXML(element.get("name", ""))
								reference = readFromXML(element.text)
								#Test customization but XML conform
								for web in element.findall("web"):
									alternatives.append( readFromXML(web.text) )
								channels[reference] = (name, list(set(alternatives)))
								log.debug("Channel", reference, channels[reference] )
					return channels
예제 #2
0
	def timerCallback(self, timer, data=None):
		log.debug("timerCallback", data)
		
		if data and isinstance(data, dict) and timer:
			
			# Episode data available, refactor name and description
			timer.name = str(refactorTitle(timer.name, data))
			timer.description = str(refactorDescription(timer.description, data))
			
			timer.dirname = str(refactorDirectory(timer.dirname or config.usage.default_path.value, data))
			timer.calculateFilename()
			
			msg = _("Success: %s" % (timer.name))
			log.debug(msg)
			timer.log(610, "[SeriesPlugin]" + " " + msg)
			
			if config.plugins.seriesplugin.timer_add_tag.value:
				timer.tags.append(TAG)
		
		elif data:
			msg = _("Failed: %s." % ( str( data ) ))
			log.debug(msg)
			timer.log(611, "[SeriesPlugin]" + " " + msg)
			SeriesPluginTimer.data.append(
				str(timer.name) + ": " + msg
			)
		
		else:
			msg = _("No data available")
			log.debug(msg)
			timer.log(612, "[SeriesPlugin]" + " " + msg)
			SeriesPluginTimer.data.append(
				str(timer.name) + ": " + msg
			)
		
		timer.sp_in_queue = False
		
		SeriesPluginTimer.counter = SeriesPluginTimer.counter +1
		
		# Maybe there is a better way to avoid multiple Popups
		from SeriesPlugin import getInstance
		
		instance = getInstance()
		
		if instance.thread.empty() and instance.thread.finished():
		
			if SeriesPluginTimer.data:
				msg = "SeriesPlugin:\n" + _("Timer rename has been finished with %d errors:\n") % (len(SeriesPluginTimer.data)) +"\n" +"\n".join(SeriesPluginTimer.data)
				log.warning(msg)
				
			else:
				if SeriesPluginTimer.counter > 0:
					msg = "SeriesPlugin:\n" + _("%d timer renamed successfully") % (SeriesPluginTimer.counter)
					log.success(msg)
				
			SeriesPluginTimer.data = []
			SeriesPluginTimer.counter = 0
		
		return timer
예제 #3
0
	def timerCallback(self, timer, data=None):
		log.debug("timerCallback", data)
		
		if data and isinstance(data, dict) and timer:
			
			# Episode data available, refactor name and description
			timer.name = str(refactorTitle(timer.name, data))
			timer.description = str(refactorDescription(timer.description, data))
			
			timer.dirname = str(refactorDirectory(timer.dirname or config.usage.default_path.value, data))
			timer.calculateFilename()
			
			msg = _("Success: %s" % (timer.name))
			log.debug(msg)
			timer.log(610, "[SeriesPlugin]" + " " + msg)
			
			if config.plugins.seriesplugin.timer_add_tag.value:
				timer.tags.append(TAG)
		
		elif data:
			msg = _("Failed: %s." % ( str( data ) ))
			log.debug(msg)
			timer.log(611, "[SeriesPlugin]" + " " + msg)
			SeriesPluginTimer.data.append(
				str(timer.name) + ": " + msg
			)
		
		else:
			msg = _("No data available")
			log.debug(msg)
			timer.log(612, "[SeriesPlugin]" + " " + msg)
			SeriesPluginTimer.data.append(
				str(timer.name) + ": " + msg
			)
		
		timer.sp_in_queue = False
		
		SeriesPluginTimer.counter = SeriesPluginTimer.counter +1
		
		# Maybe there is a better way to avoid multiple Popups
		from SeriesPlugin import getInstance
		
		instance = getInstance()
		
		if instance.thread.empty() and instance.thread.finished():
		
			if SeriesPluginTimer.data:
				msg = "SeriesPlugin:\n" + _("Timer rename has been finished with %d errors:\n") % (len(SeriesPluginTimer.data)) +"\n" +"\n".join(SeriesPluginTimer.data)
				log.warning(msg)
				
			else:
				if SeriesPluginTimer.counter > 0:
					msg = "SeriesPlugin:\n" + _("%d timer renamed successfully") % (SeriesPluginTimer.counter)
					log.success(msg)
				
			SeriesPluginTimer.data = []
			SeriesPluginTimer.counter = 0
		
		return timer
예제 #4
0
def bareShowResult():
	global loop_data, loop_counter
	
	if loop_data:
		msg = "SeriesPlugin:\n" + _("Finished with errors:\n") +"\n" +"\n".join(loop_data)
		log.warning(msg)
	
	else:
		if loop_counter > 0:
			msg = "SeriesPlugin:\n" + _("Lookup of %d episodes was successful") % (loop_counter)
			log.success(msg)
	
	loop_data = []
	loop_counter = 0
예제 #5
0
def bareShowResult():
    global loop_data, loop_counter

    if loop_data:
        msg = "SeriesPlugin:\n" + _(
            "Finished with errors:\n") + "\n" + "\n".join(loop_data)
        log.warning(msg)

    else:
        if loop_counter > 0:
            msg = "SeriesPlugin:\n" + _(
                "Lookup of %d episodes was successful") % (loop_counter)
            log.success(msg)

    loop_data = []
    loop_counter = 0
def osrename(src, dst):
	#Py3 for f in glob( escape(src) + "*" ):
	glob_src = CompiledRegexpGlobEscape.sub("[\\1]", src)
	log.debug("glob_src      ", glob_src)
	for f in glob( glob_src + ".*" ):
		log.debug("servicepathRnm", f)
		to = f.replace(src, dst)
		log.debug("servicepathTo ", to)
		
		if not os.path.exists(to):
			try:
				os.rename(f, to)
			except:
				log.exception("rename error", f, to)
		elif config.plugins.seriesplugin.rename_existing_files.value:
			log.debug("Destination file already exists", to, " - Append '_'")
			return osrename( src, dst + "_")
			break
		else:
			log.warning( _("Skipping rename because file already exists") + "\n" + to + "\n\n" + _("Can be configured within the setup") )
	return True
예제 #7
0
    def renamerCallback(self, servicepath, name, short, data=None):
        log.debug("renamerCallback", name, data)

        result = None

        if data and isinstance(data, dict):
            result = rename(servicepath, name, short, data)

        elif data and isinstance(data, basestring):
            msg = _("Failed: %s." % (str(data)))
            log.debug(msg)
            self.data.append(name + ": " + msg)

        else:
            msg = _("No data available")
            log.debug(msg)
            self.data.append(name + ": " + msg)

        self.counter = self.counter + 1

        # Maybe there is a better way to avoid multiple Popups
        from SeriesPlugin import getInstance

        instance = getInstance()

        if instance.thread.empty() and instance.thread.finished():
            if self.data:
                msg = "SeriesPlugin:\n" + _(
                    "Record rename has been finished with %d errors:\n") % (
                        len(self.data)) + "\n" + "\n".join(self.data)
                log.warning(msg)

            else:
                if self.counter > 0:
                    msg = "SeriesPlugin:\n" + _(
                        "%d records renamed successfully") % (self.counter)
                    log.success(msg)

            self.data = []
            self.counter = 0
예제 #8
0
def osrename(src, dst):
    #Py3 for f in glob( escape(src) + "*" ):
    glob_src = CompiledRegexpGlobEscape.sub("[\\1]", src)
    log.debug("glob_src      ", glob_src)
    for f in glob(glob_src + ".*"):
        log.debug("servicepathRnm", f)
        to = f.replace(src, dst)
        log.debug("servicepathTo ", to)

        if not os.path.exists(to):
            try:
                os.rename(f, to)
            except:
                log.exception("rename error", f, to)
        elif config.plugins.seriesplugin.rename_existing_files.value:
            log.debug("Destination file already exists", to, " - Append '_'")
            return osrename(src, dst + "_")
            break
        else:
            log.warning(
                _("Skipping rename because file already exists") + "\n" + to +
                "\n\n" + _("Can be configured within the setup"))
    return True
	def renamerCallback(self, servicepath, name, short, data=None):
		log.debug("renamerCallback", name, data)
		
		result = None
		
		if data and isinstance(data, dict):
			result = rename(servicepath, name, short, data)
		
		elif data and isinstance(data, basestring):
			msg = _("Failed: %s." % ( str( data ) ))
			log.debug(msg)
			self.data.append( name + ": " + msg )
		
		else:
			msg = _("No data available")
			log.debug(msg)
			self.data.append( name + ": " + msg )
		
		self.counter = self.counter +1
		
		# Maybe there is a better way to avoid multiple Popups
		from SeriesPlugin import getInstance
		
		instance = getInstance()
		
		if instance.thread.empty() and instance.thread.finished():
			if self.data:
				msg = "SeriesPlugin:\n" + _("Record rename has been finished with %d errors:\n") % (len(self.data)) +"\n" +"\n".join(self.data)
				log.warning(msg)
				
			else:
				if self.counter > 0:
					msg = "SeriesPlugin:\n" + _("%d records renamed successfully") % (self.counter)
					log.success(msg)
				
			self.data = []
			self.counter = 0
예제 #10
0
def getInstance():
	global instance
	
	if instance is None:
		
		log.reinit()
		
		from plugin import VERSION
		
		log.debug(" SERIESPLUGIN NEW INSTANCE " + VERSION)
		log.debug( " ", strftime("%a, %d %b %Y %H:%M:%S", localtime()) )
		
		try:
			from Tools.HardwareInfo import HardwareInfo
			log.debug( " DeviceName " + HardwareInfo().get_device_name().strip() )
		except:
			sys.exc_clear()
		
		try:
			from Components.About import about
			log.debug( " EnigmaVersion " + about.getEnigmaVersionString().strip() )
			log.debug( " ImageVersion " + about.getVersionString().strip() )
		except:
			sys.exc_clear()
		
		try:
			#http://stackoverflow.com/questions/1904394/python-selecting-to-read-the-first-line-only
			log.debug( " dreamboxmodel " + open("/proc/stb/info/model").readline().strip() )
			log.debug( " imageversion " + open("/etc/image-version").readline().strip() )
			log.debug( " imageissue " + open("/etc/issue.net").readline().strip() )
		except:
			sys.exc_clear()
		
		try:
			for key, value in config.plugins.seriesplugin.dict().iteritems():
				log.debug( " config..%s = %s" % (key, str(value.value)) )
		except Exception as e:
			sys.exc_clear()
		
		global CompiledRegexpReplaceChars
		try:
			if config.plugins.seriesplugin.replace_chars.value:
				CompiledRegexpReplaceChars = re.compile('['+config.plugins.seriesplugin.replace_chars.value.replace("\\", "\\\\\\\\")+']')
		except:
			log.exception( " Config option 'Replace Chars' is no valid regular expression" )
			CompiledRegexpReplaceChars = re.compile("[:\!/\\,\(\)'\?]")
		
		# Check autotimer
		try:
			from Plugins.Extensions.AutoTimer.plugin import autotimer
			deprecated = False
			try:
				from Plugins.Extensions.AutoTimer.plugin import AUTOTIMER_VERSION
				if int(AUTOTIMER_VERSION[0]) < 4:
					deprecated = True
			except ImportError:
				AUTOTIMER_VERSION = "deprecated"
				deprecated = True
			log.debug( " AutoTimer: " + AUTOTIMER_VERSION )
			if deprecated:
				log.warning( _("Your autotimer is deprecated")  + "\n" +_("Please update it") )
		except ImportError:
			log.debug( " AutoTimer: Not found" )
		
		# Check dependencies
		start = True
		from imp import find_module
		dependencies = ["difflib", "json", "re", "xml", "xmlrpclib"]
		for dependency in dependencies:
			try:
				find_module(dependency)
			except ImportError:
				start = False
				log.error( _("Error missing dependency")  + "\n" + "python-"+dependency + "\n\n" +_("Please install missing python paket manually") )
		if start:
			instance = SeriesPlugin()
		
	return instance
예제 #11
0
	def getEpisode(self, callback, name, begin, end=None, service=None, future=False, today=False, elapsed=False, block=False, rename=False):
		
		if config.plugins.seriesplugin.skip_during_records.value:
			try:
				import NavigationInstance
				if NavigationInstance.instance.RecordTimer.isRecording():
					msg = _("Skip check during running records") + "\n\n" + _("Can be configured within the setup")
					log.warning( msg)
					if callable(callback):
						callback(msg)
					return msg
			except:
				pass
		
		# Check for episode information in title
		match = self.compiledRegexpSeries.match(name)
		if match:
			#log.debug(match.group(0))     # Entire match
			#log.debug(match.group(1))     # First parenthesized subgroup
			if not rename and config.plugins.seriesplugin.skip_pattern_match.value:
				msg = _("Skip check because of pattern match") + "\n" + name + "\n\n" + _("Can be configured within the setup")
				log.warning(msg)
				if callable(callback):
					callback(msg)
				return msg
			if match.group(1):
				name = match.group(1)
		
		if elapsed:
			identifier = self.identifier_elapsed
		elif today:
			identifier = self.identifier_today
		elif future:
			identifier = self.identifier_future
		else:
			identifier = self.modules and self.instantiateModule( self.modules.itervalues().next() )
		
		if not identifier:
			msg = _("No identifier available") + "\n\n" + _("Please check Your installation")
			log.error(msg)
			if callable(callback):
				callback(msg)
			return msg
		
		elif self.channelsEmpty():
			msg = _("Channels are not matched") + "\n\n" + _("Please open the channel editor (setup) and match them")
			log.error(msg)
			if callable(callback):
				callback(msg)
			return msg
			
		else:
			# Reset title search depth on every new request
			identifier.search_depth = 0;
			
			# Reset the knownids on every new request
			identifier.knownids = []
			
			try:
				serviceref = service.toString()
			except:
				sys.exc_clear()
				serviceref = str(service)
			serviceref = re.sub('::.*', ':', serviceref)

			if block == False:
				
				self.thread.add( ThreadItem(identifier, callback, name, begin, end, serviceref) )
				
			else:
				
				result = None
				
				try:
					result = identifier.getEpisode( name, begin, end, serviceref )
				except Exception, e:
					log.exception("Worker:", str(e))
					
					# Exception finish job with error
					result = str(e)
				
				config.plugins.seriesplugin.lookup_counter.value += 1
				
				data = normalizeResult(result)
				
				if callable(callback):
					callback(data)
				
				return data
예제 #12
0
	def getEpisode(self, timer, block=False):
		
		log.info("timername, service, begin, end:", timer.name, str(timer.service_ref.ref), timer.begin, timer.end)
		
		if hasattr(timer, 'sp_in_queue'):
			if timer.sp_in_queue:
				msg = _("Skipping timer because it is already in queue")
				log.warning(msg, timer.name)
				timer.log(601, "[SeriesPlugin]" + " " + msg )
				return
		
		# We have to compare the length,
		# because of the E2 special chars handling for creating the filenames
		#if timer.name == name:
		# Mad Men != Mad_Men
		
		if TAG in timer.tags:
			msg = _("Skipping timer because it is already handled") + "\n\n" + _("Can be configured within the setup")
			log.info(msg, timer.name)
			timer.log(607, "[SeriesPlugin]" + " " + msg )
			return
		
		if timer.begin < time() + 60:
			msg = _("Skipping timer because it starts in less than 60 seconds")
			log.debug(msg, timer.name)
			timer.log(604, "[SeriesPlugin]" + " " + msg )
			return
		
		if timer.isRunning():
			msg = _("Skipping timer because it is already running")
			log.debug(msg, timer.name)
			timer.log(605, "[SeriesPlugin]" + " " + msg )
			return
		
		if timer.justplay:
			msg = _("Skipping timer because it is a just play timer")
			log.debug(msg, timer.name)
			timer.log(606, "[SeriesPlugin]" + " " + msg )
			return
		
		
		event = None
		epgcache = eEPGCache.getInstance()
		
		if timer.eit:
			event = epgcache.lookupEventId(timer.service_ref.ref, timer.eit)
			log.debug("lookupEventId", timer.eit, event)
		if not(event):
			event = epgcache.lookupEventTime( timer.service_ref.ref, timer.begin + ((timer.end - timer.begin) /2) );
			log.debug("lookupEventTime", event )
		
		if event:
			if not ( len(timer.name) == len(event.getEventName()) ):
				msg = _("Skipping timer because it is already modified %s" % (timer.name) )
				log.info(msg)
				timer.log(602, "[SeriesPlugin]" + " " + msg )
				return
			begin = event.getBeginTime() or 0
			duration = event.getDuration() or 0
			end = begin + duration
			
		else:
			if config.plugins.seriesplugin.timer_eit_check.value:
				msg = _("Skipping timer because no event was found")
				log.info(msg, timer.name)
				timer.log(603, "[SeriesPlugin]" + " " + msg )
				return
			else:
				# We don't know the exact margins, we will assume the E2 default margins
				log.debug("We don't know the exact margins, we will assume the E2 default margins")
				begin = timer.begin + (config.recording.margin_before.value * 60)
				end = timer.end - (config.recording.margin_after.value * 60)
		
		
		timer.log(600, "[SeriesPlugin]" + " " + _("Try to find infos for %s" % (timer.name) ) )
		
		seriesPlugin = getInstance()
		
		if timer.service_ref:
			log.debug("getEpisode:", timer.name, timer.begin, timer.end, block)
			
			timer.sp_in_queue = True
			
			return seriesPlugin.getEpisode(
					boundFunction(self.timerCallback, timer),
					timer.name, begin, end, timer.service_ref, future=True, block=block
				)
		else:
			msg = _("Skipping lookup because no channel is specified")
			log.warning(msg)
			self.timerCallback(timer, msg)
			return None
예제 #13
0
	def getEpisode(self, timer, block=False):
		
		log.info("timername, service, begin, end:", timer.name, str(timer.service_ref.ref), timer.begin, timer.end)
		
		if hasattr(timer, 'sp_in_queue'):
			if timer.sp_in_queue:
				msg = _("Skipping timer because it is already in queue")
				log.warning(msg, timer.name)
				timer.log(601, "[SeriesPlugin]" + " " + msg )
				return
		
		# We have to compare the length,
		# because of the E2 special chars handling for creating the filenames
		#if timer.name == name:
		# Mad Men != Mad_Men
		
		if TAG in timer.tags:
			msg = _("Skipping timer because it is already handled") + "\n\n" + _("Can be configured within the setup")
			log.info(msg, timer.name)
			timer.log(607, "[SeriesPlugin]" + " " + msg )
			return
		
		if timer.begin < time() + 60:
			msg = _("Skipping timer because it starts in less than 60 seconds")
			log.debug(msg, timer.name)
			timer.log(604, "[SeriesPlugin]" + " " + msg )
			return
		
		if timer.isRunning():
			msg = _("Skipping timer because it is already running")
			log.debug(msg, timer.name)
			timer.log(605, "[SeriesPlugin]" + " " + msg )
			return
		
		if timer.justplay:
			msg = _("Skipping timer because it is a just play timer")
			log.debug(msg, timer.name)
			timer.log(606, "[SeriesPlugin]" + " " + msg )
			return
		
		
		event = None
		epgcache = eEPGCache.getInstance()
		
		if timer.eit:
			event = epgcache.lookupEventId(timer.service_ref.ref, timer.eit)
			log.debug("lookupEventId", timer.eit, event)
		if not(event):
			event = epgcache.lookupEventTime( timer.service_ref.ref, timer.begin + ((timer.end - timer.begin) /2) );
			log.debug("lookupEventTime", event )
		
		if event:
			if not ( len(timer.name) == len(event.getEventName()) ):
				msg = _("Skipping timer because it is already modified %s" % (timer.name) )
				log.info(msg)
				timer.log(602, "[SeriesPlugin]" + " " + msg )
				return
			begin = event.getBeginTime() or 0
			duration = event.getDuration() or 0
			end = begin + duration
			
		else:
			if config.plugins.seriesplugin.timer_eit_check.value:
				msg = _("Skipping timer because no event was found")
				log.info(msg, timer.name)
				timer.log(603, "[SeriesPlugin]" + " " + msg )
				return
			else:
				# We don't know the exact margins, we will assume the E2 default margins
				log.debug("We don't know the exact margins, we will assume the E2 default margins")
				begin = timer.begin + (config.recording.margin_before.value * 60)
				end = timer.end - (config.recording.margin_after.value * 60)
		
		
		timer.log(600, "[SeriesPlugin]" + " " + _("Try to find infos for %s" % (timer.name) ) )
		
		seriesPlugin = getInstance()
		
		if timer.service_ref:
			log.debug("getEpisode:", timer.name, timer.begin, timer.end, block)
			
			timer.sp_in_queue = True
			
			return seriesPlugin.getEpisode(
					boundFunction(self.timerCallback, timer),
					timer.name, begin, end, timer.service_ref, future=True, block=block
				)
		else:
			msg = _("Skipping lookup because no channel is specified")
			log.warning(msg)
			self.timerCallback(timer, msg)
			return None