示例#1
0
	def KeyOk(self):
		sel = self["list"].getCurrent()[0]
		if (sel == "searchEPGe2"):
			if self.epgserchplugin:
				self.epgserchplugin(session=self.session, servicelist=self)
		elif (sel == "searchEPG"):
			if config.dbp.usevkeyboard.value:
				self.session.openWithCallback(self.beginSearch, VirtualKeyBoard, title = _("Enter event to search:"), text = "")
			else:
				self.session.openWithCallback(self.beginSearch,InputBox, title = _("Enter event to search:"), windowTitle = _("Search in EPG cache"), text="")
		elif (sel == "searchEPGLast"):
			self.session.open(NEpgSearchLast)
		elif (sel == "downloadEPG"):
			if self.checkDevice():
				self.ref = self.session.nav.getCurrentlyPlayingServiceReference()
				if config.nemepg.downskyit.value:
					self.downloadItEPG()
				elif config.nemepg.downskyuk.value:
					self.downloadUkEPG()
		elif (sel == "e2LoaderEpg") or (sel == "e2LoaderEpgI"):
			self.downIMode = { 'e2LoaderEpg':False, 'e2LoaderEpgI':True }[sel]
			msg = _('Do you want download EPG\nusing e2_loadepg?')
			self.epgDBox = self.session.openWithCallback(self.downEPG,MessageBox, msg, MessageBox.TYPE_YESNO)
			self.epgDBox.setTitle(_("Download EPG"))
		elif (sel == "reloadEPG"):
			if self.e2Loader:
				searchPaths = ['/tmp/%s','/media/usb/%s','/media/cf/%s','/media/hdd/%s']
				for path in searchPaths:
					epgFile = (path % 'ext.epg.dat')
					if fileExists(epgFile):
						system("mv " +  epgFile + " " + config.nemepg.path.value + "/epg.dat")
			msg = _('Load EPG data in Enigma cache from:\n%s/epg.dat.\nPlease Wait...') % config.nemepg.path.value
			self.epgRBox = self.session.open(MessageBox, msg, MessageBox.TYPE_INFO)
			self.epgRBox.setTitle(_("Loading EPG"))
			self.reloadEPGTimer.start(500, False)
		elif (sel == "eraseEPG"):
			msg = _('Erasing EPG Chache.\nPlease Wait...')
			self.epgCBox = self.session.open(MessageBox, msg, MessageBox.TYPE_INFO)
			self.epgCBox.setTitle(_("Erasing EPG cache"))
			self.clearEPGTimer.start(500, False)
		elif (sel == "backupEPG"):
			msg = _('Backup Enigma EPG data on:\n%s.\nPlease Wait...') % config.nemepg.path.value
			self.epgBBox = self.session.open(MessageBox, msg, MessageBox.TYPE_INFO)
			self.epgBBox.setTitle(_("Backing-up EPG"))
			self.saveEPGTimer.start(500, False)
		elif (sel == "createTIMER"):
			serviceref = ServiceReference(getSid(config.nemepg.skyitch.value))
			begin = 1239332400
			end = 1239333600
			name = "Download EPG Daily"
			description = "Please do not remove this entry!"
			timer = RecordTimerEntry(serviceref, begin, end, name, description, 66, False, 2, 1)
			timer.repeated = 127
			self.session.openWithCallback(self.finishedAdd, TimerEntry, timer)
		elif (sel == "openTIMER"):
			self.session.open(TimerEditList)
		elif (sel == "epglog"):
			self.session.open(dbpShowPanel, '/usr/log/crossepg.log' ,_('EPG Timer log')) 
		elif (sel == "configEPG"):
			self.session.openWithCallback(self.saveConfig, NSetup, "epg")
 def __init__(
     self,
     session,
     serviceref,
     begin,
     end,
     name,
     description,
     eit,
     disabled=False,
     justplay=False,
     afterEvent=AFTEREVENT.AUTO,
     checkOldTimers=False,
     dirname=None,
     tags=None,
 ):
     self.session = session
     RecordTimerEntry.__init__(
         self,
         serviceref,
         begin,
         end,
         name,
         description,
         eit,
         disabled=False,
         justplay=False,
         afterEvent=AFTEREVENT.AUTO,
         checkOldTimers=False,
         dirname=None,
         tags=None,
     )
def addTimer(
    session,
    serviceref,
    begin,
    end,
    name,
    description,
    disabled,
    justplay,
    afterevent,
    dirname,
    tags,
    repeated,
    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)}
    except Exception, e:
        print e
        return {"result": False, "message": "Could not add timer '%s'!" % name}
示例#4
0
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!"
		}
		
	return {
		"result": True,
		"message": msg
	}
	
示例#5
0
	def recordNow(self, param):
		if not config.misc.recording_allowed.value:
			return (False, _("Recording is currently disabled!"))

		limitEvent = True
		if param == "undefinitely" or param == "infinite":
			ret = (True, "Infinite Instant recording started")
			limitEvent = False
		else:
			ret = ( True, "Instant record for current Event started" )

		serviceref = ServiceReference(self.session.nav.getCurrentlyPlayingServiceReference().toString())

		event = None

		try:
			service = self.session.nav.getCurrentService()
			event = service.info().getEvent(0)
		except Exception:
			print "[Webcomponents.Timer] recordNow Exception!"

		begin = time()
		end = begin + 3600 * 10
		name = "instant record"
		description = ""
		eventid = 0

		if event is not None:
			curEvent = parseEvent(event)
			name = curEvent[2]
			description = curEvent[3]
			eventid = curEvent[4]
			if limitEvent:
				end = curEvent[1]
		else:
			if limitEvent:
				ret = ( False, "No event found! Not recording!" )

		if ret[0]:
			location = preferredInstantRecordPath()
			timer = RecordTimerEntry(serviceref, begin, end, name, description, eventid, False, False, 0, dirname=location)
			timer.dontSave = True
			recRet = self.recordtimer.record(timer)
			if recRet is not None:
				# a conflict is rather unlikely, but this can also indicate a non-recordable service
				ret = (False, "Timer conflict detected! Not recording!" )

		return ret
示例#6
0
	def program_seek_vps_multiple_closed(self, retval):
		self.program_seek_vps_multiple_started = -1
		
		self.found_vps_multiple = sorted(self.found_vps_multiple)
		
		for evt_begin, evt_id, evt in self.found_vps_multiple:
			# eigenen Timer überprüfen, wenn Zeiten nicht überschrieben werden dürfen
			if not self.timer.vpsplugin_overwrite and evt_begin <= self.timer.end:
				self.next_events.append(evt_id)
				self.timer.log(0, "[VPS] add event_id "+ str(evt_id))
			
			else:
				canbeadded = True
				evt_begin += 60
				evt_end = evt.getBeginTime() + evt.getDuration() - 60
				now = time()
				
				for checktimer in self.session.nav.RecordTimer.timer_list:
					if checktimer == self.timer:
						continue
					if (checktimer.begin - now) > 3600*24:
						break
					if checktimer.service_ref.ref.toCompareString() == self.timer.service_ref.ref.toCompareString() or checktimer.service_ref.ref.toCompareString() == self.rec_ref.toCompareString():	
						if checktimer.begin <= evt_begin and checktimer.end >= evt_end:
							if not checktimer.vpsplugin_enabled or not checktimer.vpsplugin_overwrite:
								canbeadded = False
							
							# manuell angelegter Timer mit VPS
							if checktimer.vpsplugin_enabled and checktimer.name == "" and checktimer.vpsplugin_time is not None:
								checktimer.eit = evt_id
								checktimer.name = evt.getEventName()
								checktimer.description = evt.getShortDescription()
								checktimer.vpsplugin_time = None
								checktimer.log(0, "[VPS] changed timer (found same PDC-Time as in other VPS-recording)")
								canbeadded = False
								break

				
				if canbeadded:
					newevent_data = parseEvent(evt)
					newEntry = RecordTimerEntry(ServiceReference(self.rec_ref), *newevent_data)
					newEntry.vpsplugin_enabled = True
					newEntry.vpsplugin_overwrite = True
					newEntry.log(0, "[VPS] added this timer (found same PDC-Time as in other VPS-recording)")
					
					# Wenn kein Timer-Konflikt auftritt, wird der Timer angelegt.
					NavigationInstance.instance.RecordTimer.record(newEntry)
示例#7
0
	def copyTimer(self, start, duration):
		starttime = start - config.recording.margin_before.value * 60
		endtime = start + duration + config.recording.margin_after.value * 60
		self.new_timer_copy = RecordTimerEntry(ServiceReference(self.rec_ref), starttime, endtime, self.timer.name, self.timer.description, self.timer.eit, False, False, AFTEREVENT.AUTO, False, self.timer.dirname, self.timer.tags)
		self.new_timer_copy.vpsplugin_enabled = True
		self.new_timer_copy.vpsplugin_overwrite = self.timer.vpsplugin_overwrite
		self.new_timer_copy.log(0, "[VPS] added this timer")
		NavigationInstance.instance.RecordTimer.record(self.new_timer_copy)
示例#8
0
    def recordNow(self, param):
        limitEvent = True
        if param == "undefinitely" or param == "infinite":
            ret = (True, "Infinite Instant recording started")
            limitEvent = False
        else:
            ret = (True, "Instant record for current Event started")

        serviceref = ServiceReference(self.session.nav.getCurrentlyPlayingServiceReference().toString())

        event = None

        try:
            service = self.session.nav.getCurrentService()
            event = service.info().getEvent(0)
        except Exception:
            print "[Webcomponents.Timer] recordNow Exception!"

        begin = time()
        end = begin + 3600 * 10
        name = "instant record"
        description = ""
        eventid = 0

        if event is not None:
            curEvent = parseEvent(event)
            name = curEvent[2]
            description = curEvent[3]
            eventid = curEvent[4]
            if limitEvent:
                end = curEvent[1]
        else:
            if limitEvent:
                ret = (False, "No event found! Not recording!")

        if ret[0]:
            location = config.movielist.last_videodir.value
            timer = RecordTimerEntry(
                serviceref, begin, end, name, description, eventid, False, False, 0, dirname=location
            )
            timer.dontSave = True
            self.recordtimer.record(timer)

        return ret
示例#9
0
def addTimer(session, serviceref, begin, end, name, description, disabled, justplay, afterevent, dirname, tags, repeated, vpsinfo=None, logentries=None, eit=0, always_zap=-1):
	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"]

		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 getTimers(self):
		self._timer_list = []
		self._processed_timers = []

		baseurl = self.getBaseUrl()

		print "[GBIpboxRemoteTimer] get remote timer list"

		try:
			httprequest = urllib2.urlopen(baseurl + '/web/timerlist')
			xmldoc = minidom.parseString(httprequest.read())
			timers = xmldoc.getElementsByTagName('e2timer') 
			for timer in timers:
				serviceref = ServiceReference(getValueFromNode(timer, 'e2servicereference'))
				begin = int(getValueFromNode(timer, 'e2timebegin'))
				end = int(getValueFromNode(timer, 'e2timeend'))
				name = getValueFromNode(timer, 'e2name')
				description = getValueFromNode(timer, 'e2description')
				eit = int(getValueFromNode(timer, 'e2eit'))
				disabled = int(getValueFromNode(timer, 'e2disabled'))
				justplay = int(getValueFromNode(timer, 'e2justplay'))
				afterevent = int(getValueFromNode(timer, 'e2afterevent'))
				repeated = int(getValueFromNode(timer, 'e2repeated'))
				location = getValueFromNode(timer, 'e2location')
				tags = getValueFromNode(timer, 'e2tags').split(" ")

				entry = RecordTimerEntry(serviceref, begin, end, name, description, eit, disabled, justplay, afterevent, dirname = location, tags = tags, descramble = 1, record_ecm = 0, isAutoTimer = 0, always_zap = 0)
				entry.repeated = repeated

				entry.orig = RecordTimerEntry(serviceref, begin, end, name, description, eit, disabled, justplay, afterevent, dirname = location, tags = tags, descramble = 1, record_ecm = 0, isAutoTimer = 0, always_zap = 0)
				entry.orig.repeated = repeated

				if entry.shouldSkip() or entry.state == TimerEntry.StateEnded or (entry.state == TimerEntry.StateWaiting and entry.disabled):
					insort(self._processed_timers, entry)
				else:
					insort(self._timer_list, entry)
		except Exception, e:
			print "[GBIpboxRemoteTimer]", e
示例#11
0
	def UPDT(self, args):
		# <id> <settings>
		args = args.split(None, 1)
		if len(args) != 2:
			payload = "%d argument error" % (CODE_SYNTAX,)
			return self.sendLine(payload)

		try:
			timerId = int(args[0])
		except ValueError:
			payload = "%d argument error" % (CODE_SYNTAX,)
			return self.sendLine(payload)

		list = self.getTimerList()

		if timerId < 1:
			payload = "%d argument error" % (CODE_SYNTAX,)
			return self.sendLine(payload)

		if len(list) >= timerId: oldTimer = list[timerId - 1]
		else: oldTimer = None

		try:
			flags, channelid, datestring, beginstring, endstring, priority, lifetime, name, description = args[1].split(':')
			flags = int(flags)
			service_ref = ServiceReference(self.channelList[int(channelid)-1])
			datestruct = strptime(datestring, '%Y-%m-%d')
			timestruct = strptime(beginstring, '%H%M')
			begin = mktime((datestruct.tm_year, datestruct.tm_mon, datestruct.tm_mday, timestruct.tm_hour, timestruct.tm_min, 0, datestruct.tm_wday, datestruct.tm_yday, -1))
			timestruct = strptime(endstring, '%H%M')
			end = mktime((datestruct.tm_year, datestruct.tm_mon, datestruct.tm_mday, timestruct.tm_hour, timestruct.tm_min, 0, datestruct.tm_wday, datestruct.tm_yday, -1))
			del datestruct, timestruct
		except ValueError as e:
			payload = "%d argument error" % (CODE_SYNTAX,)
			return self.sendLine(payload)
		except KeyError as e:
			payload = "%d argument error" % (CODE_SYNTAX,)
			return self.sendLine(payload)

		if end < begin: end += 86400 # Add 1 day, beware - this is evil and might not work correctly due to dst
		timer = RecordTimerEntry(service_ref, begin, end, name, description, 0, disabled=flags & 1 == 0)
		if oldTimer:
			recordTimer.removeEntry(oldTimer)
			timer.justplay = oldTimer.justplay
			timer.afterEvent = oldTimer.afterEvent
			timer.dirname = oldTimer.dirname
			timer.tags = oldTimer.tags
			timer.log_entries = oldTimer.log_entries

		conflict = recordTimer.record(timer)
		if conflict is None:
			return self.sendTimerLine(timer, timerId, last=True)
		else:
			payload = "%d timer conflict detected, original timer lost." % (CODE_ERR_LOCAL,)
			return self.sendLine(payload)
示例#12
0
 def standbyTimeout(self):
     print "goto deep3"
     from RecordTimer import RecordTimerEntry
     RecordTimerEntry.TryQuitMainloop()
示例#13
0
    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

        self.isIPTV = bool(
            [service for service in timer.services if ":http" in service])

        # As well as description, also allow timers on individual IPTV streams
        if timer.searchType == "description" or self.isIPTV:
            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))
                            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():
                            continue
                        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))
                                    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 timer.searchType == "description":
                        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:  # IPTV streams (if not "description" search)
                        if timer.searchType == 'exact' and match == (name if casesensitive else name.lower()) or \
                         timer.searchType == 'partial' and match in (name if casesensitive else name.lower()) or \
                         timer.searchType == 'start' and (name if casesensitive else name.lower()).startswith(match):
                            epgmatches.append((serviceref, eit, name, begin,
                                               duration, shortdesc, extdesc))

        else:
            # Search EPG, default to empty list
            if timer.searchType in typeMap:
                EPG_searchType = typeMap[timer.searchType]
            else:
                EPG_searchType = typeMap["partial"]
            epgmatches = epgcache.search(
                ('RITBDSE', 3000, EPG_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

# If the timer actually has a timespan set it will be:
#   start[[hr], [min]], end[[hr], [min]], daySpan
# (if it has none the timespan will be (None,))
# (see calculateDayspan() in AutoTimerComponent.py) where daySpan is
# True if the timespan "ends before it starts" (so passes over
# midnight).
# If we have a timer for which daySpan is true and the day-offset of the
# begin time for the programme/broadcast we are checking is before that
# of the autotimer timespan start then we need to bring the dayofweek
# check forward by 1 day when checking it. (i.e. we pretend the
# recording starts a day before it does, but *just* for the dayofweek
# filter check).
#   e.g.
#       Monday AT for 23:00 to 02:00 should match a programme on
#       Tuesday at 01:00.
# The rest of the checks stay the same (which is why we don't need to
# check for the autotimer timespan end being after the begin time for
# the programme).
#
                tdow = timestamp.tm_wday
                if (timer.timespan[0] != None) and timer.timespan[2]:
                    begin_offset = 60 * timestamp.tm_hour + timestamp.tm_min
                    timer_offset = 60 * timer.timespan[0][0] + timer.timespan[
                        0][1]
                    if begin_offset < timer_offset:
                        tdow = (tdow - 1) % 7
                dayofweek = str(tdow)

            # 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
                    try:  # protect against vps plugin not being present
                        vps_changed = rtimer.vpsplugin_enabled != timer.vps_enabled or rtimer.vpsplugin_overwrite != timer.vps_overwrite
                    except AttributeError:
                        vps_changed = False
                    if (evtBegin - offsetBegin != rtimer.begin
                        ) or (evtEnd + offsetEnd != rtimer.end) or (
                            shortdesc != rtimer.description) or vps_changed:
                        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)
                newEntry.isAutoTimer = True
                newEntry.autoTimerId = timer.id

            # 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)
示例#14
0
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}
示例#15
0
    def parseTimer(self,
                   timer,
                   epgcache,
                   serviceHandler,
                   recordHandler,
                   checkEvtLimit,
                   evtLimit,
                   timers,
                   conflicting,
                   similars,
                   skipped,
                   timerdict,
                   moviedict,
                   simulateOnly=False):
        new = 0
        modified = 0

        # Search EPG, default to empty list
        epgmatches = epgcache.search(
            ('RITBDSE', 1000, typeMap[timer.searchType], timer.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
        for idx, (serviceref, eit, name, begin, duration, shortdesc,
                  extdesc) in enumerate(epgmatches):

            startLog()

            # timer destination dir
            dest = timer.destination or config.usage.default_path.value

            evtBegin = begin
            evtEnd = end = begin + duration

            doLog("possible epgmatch %s" % (name))
            doLog("Serviceref %s" % (str(serviceref)))
            eserviceref = eServiceReference(serviceref)
            evt = epgcache.lookupEventId(eserviceref, eit)
            if not evt:
                doLog("Could not create Event!")
                skipped.append(
                    (name, begin, end, str(serviceref), timer.name, getLog()))
                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()
                doLog("Serviceref2 %s" % (str(serviceref)))

            # If event starts in less than 60 seconds skip it
            if begin < time() + 60:
                doLog(
                    "Skipping an event because it starts in less than 60 seconds"
                )
                skipped.append(
                    (name, begin, end, serviceref, timer.name, getLog()))
                continue

            # 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:
                        doLog(
                            "Skipping an event because of maximum days in future is reached"
                        )
                        skipped.append((name, begin, end, serviceref,
                                        timer.name, getLog()))
                        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):
                doLog("Skipping an event because of check services")
                skipped.append(
                    (name, begin, end, serviceref, timer.name, getLog()))
                continue
            if timer.checkDuration(duration):
                doLog("Skipping an event because of duration check")
                skipped.append(
                    (name, begin, end, serviceref, timer.name, getLog()))
                continue
            if not similarTimer:
                if timer.checkTimespan(timestamp):
                    doLog("Skipping an event because of timestamp check")
                    skipped.append(
                        (name, begin, end, serviceref, timer.name, getLog()))
                    continue
                if timer.checkTimeframe(begin):
                    doLog("Skipping an event because of timeframe check")
                    skipped.append(
                        (name, begin, end, serviceref, timer.name, getLog()))
                    continue

            # Initialize
            newEntry = None
            oldExists = False
            allow_modify = True

            # Eventually change service to alternative
            if timer.overrideAlternatives:
                serviceref = timer.getAlternative(serviceref)

            if timer.series_labeling and sp_getSeasonEpisode is not None:
                allow_modify = False
                #doLog("Request name, desc, path %s %s %s" % (name,shortdesc,dest))
                sp = sp_getSeasonEpisode(serviceref, name, evtBegin, evtEnd,
                                         shortdesc, dest)
                if sp and type(sp) in (tuple, list) and len(sp) == 4:
                    name = sp[0] or name
                    shortdesc = sp[1] or shortdesc
                    dest = sp[2] or dest
                    doLog(str(sp[3]))
                    #doLog("Returned name, desc, path %s %s %s" % (name,shortdesc,dest))
                    allow_modify = True
                else:
                    # Nothing found
                    doLog(str(sp))

                    # If AutoTimer name not equal match, do a second lookup with the name
                    if timer.name.lower() != timer.match.lower():
                        #doLog("Request name, desc, path %s %s %s" % (timer.name,shortdesc,dest))
                        sp = sp_getSeasonEpisode(serviceref, timer.name,
                                                 evtBegin, evtEnd, shortdesc,
                                                 dest)
                        if sp and type(sp) in (tuple, list) and len(sp) == 4:
                            name = sp[0] or name
                            shortdesc = sp[1] or shortdesc
                            dest = sp[2] or dest
                            doLog(str(sp[3]))
                            #doLog("Returned name, desc, path %s %s %s" % (name,shortdesc,dest))
                            allow_modify = True
                        else:
                            doLog(str(sp))

            if timer.checkFilter(name, shortdesc, extdesc, dayofweek):
                doLog("Skipping an event because of filter check")
                skipped.append(
                    (name, begin, end, serviceref, timer.name, getLog()))
                continue

            if timer.hasOffset():
                # Apply custom Offset
                begin, end = timer.applyOffset(begin, end)
            else:
                # Apply E2 Offset
                if ServiceRecordingSettings:
                    begin -= ServiceRecordingSettings.instance.getMarginBefore(
                        eserviceref)
                    end += ServiceRecordingSettings.instance.getMarginAfter(
                        eserviceref)
                else:
                    begin -= config.recording.margin_before.value * 60
                    end += config.recording.margin_after.value * 60

            # Overwrite endtime if requested
            if timer.justplay and not timer.setEndtime:
                end = begin

            # 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.checkDuplicates(timer, name, movieinfo.get("name"),
                                            shortdesc,
                                            movieinfo.get("shortdesc"),
                                            extdesc, movieinfo.get("extdesc")):
                        doLog(
                            "We found a matching recorded movie, skipping event:",
                            name)
                        movieExists = True
                        break
                if movieExists:
                    doLog("Skipping an event because movie already exists")
                    skipped.append(
                        (name, begin, end, serviceref, timer.name, getLog()))
                    continue

            # 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:
                    oldExists = True
                    doLog("We found a timer based on eit")
                    newEntry = rtimer
                    break
                elif config.plugins.autotimer.try_guessing.value:
                    if timer.hasOffset():
                        # Remove custom Offset
                        rbegin = rtimer.begin + timer.offset[0]
                        rend = rtimer.end - timer.offset[1]
                    else:
                        # Remove E2 Offset
                        rbegin = rtimer.begin + config.recording.margin_before.value * 60
                        rend = rtimer.end - config.recording.margin_after.value * 60
                    # As alternative we could also do a epg lookup
                    #revent = epgcache.lookupEventId(rtimer.service_ref.ref, rtimer.eit)
                    #rbegin = revent.getBeginTime() or 0
                    #rduration = revent.getDuration() or 0
                    #rend = rbegin + rduration or 0
                    if getTimeDiff(rbegin, rend, evtBegin,
                                   evtEnd) > ((duration / 10) * 8):
                        oldExists = True
                        doLog("We found a timer based on time guessing")
                        newEntry = rtimer
                        break
                if timer.avoidDuplicateDescription >= 1 \
                 and not rtimer.disabled:
                    if self.checkDuplicates(timer, name, rtimer.name,
                                            shortdesc, rtimer.description,
                                            extdesc, rtimer.extdesc):
                        # if searchForDuplicateDescription > 1 then check short description
                        oldExists = True
                        doLog(
                            "We found a timer (similar service) with same description, skipping event"
                        )
                        break

            # We found no timer we want to edit
            if newEntry is None:
                # But there is a match
                if oldExists:
                    doLog(
                        "Skipping an event because a timer on same service exists"
                    )
                    skipped.append(
                        (name, begin, end, serviceref, timer.name, getLog()))
                    continue

                # We want to search for possible doubles
                if timer.avoidDuplicateDescription >= 2:
                    for rtimer in chain.from_iterable(itervalues(timerdict)):
                        if not rtimer.disabled:
                            if self.checkDuplicates(timer, name, rtimer.name,
                                                    shortdesc,
                                                    rtimer.description,
                                                    extdesc, rtimer.extdesc):
                                oldExists = True
                                doLog(
                                    "We found a timer (any service) with same description, skipping event"
                                )
                                break
                    if oldExists:
                        doLog(
                            "Skipping an event because a timer on any service exists"
                        )
                        skipped.append((name, begin, end, serviceref,
                                        timer.name, getLog()))
                        continue

                if timer.checkCounter(timestamp):
                    doLog("Not adding new timer because counter is depleted.")
                    skipped.append(
                        (name, begin, end, serviceref, timer.name, getLog()))
                    continue

            # if set option for check/save timer in filterlist and only if not found an existing timer
            isnewFilterEntry = False
            if (config.plugins.autotimer.series_save_filter.value
                    or timer.series_save_filter) and oldExists == False:
                # only if use series_labeling and if sp_getSeasonEpisode was succesful
                if timer.series_labeling and sp_getSeasonEpisode is not None:
                    if sp and type(sp) in (tuple, list) and len(sp) == 4:
                        ret = self.addToFilterfile(str(sp[0]), begin,
                                                   simulateOnly)
                        if ret:
                            if simulateOnly:
                                doLog(
                                    "only simulate - new Timer would be saved in autotimer_filter"
                                )
                            else:
                                doLog("new Timer saved in autotimer_filter")
                                isnewFilterEntry = True
                        else:
                            skipped.append(
                                (name, begin, end, serviceref, timer.name,
                                 getLog()))
                            continue

            # Append to timerlist and abort if simulating
            timers.append((name, begin, end, serviceref, timer.name, getLog()))
            if simulateOnly:
                continue

            if newEntry is not None:
                # Abort if we don't want to modify timers or timer is repeated
                if config.plugins.autotimer.refresh.value == "none" or newEntry.repeated:
                    doLog(
                        "Won't modify existing timer because either no modification allowed or repeated timer"
                    )
                    continue

                if hasattr(newEntry, "isAutoTimer"):
                    msg = "[AutoTimer] AutoTimer %s modified this automatically generated timer." % (
                        timer.name)
                    doLog(msg)
                    newEntry.log(501, msg)
                elif config.plugins.autotimer.add_autotimer_to_tags.value and TAG in newEntry.tags:
                    msg = "[AutoTimer] AutoTimer %s modified this automatically generated timer." % (
                        timer.name)
                    doLog(msg)
                    newEntry.log(501, msg)
                else:
                    if config.plugins.autotimer.refresh.value != "all":
                        doLog(
                            "Won't modify existing timer because it's no timer set by us"
                        )
                        continue

                    msg = "[AutoTimer] Warning, AutoTimer %s messed with a timer which might not belong to it: %s ." % (
                        timer.name, newEntry.name)
                    doLog(msg)
                    newEntry.log(501, msg)

                if newEntry.begin != begin or newEntry.end != end or newEntry.name != name:
                    modified += 1
                    #self.addToSearchLogfile(newEntry,"#", simulateOnly)

                if allow_modify:
                    modified_for_searchlog = True if newEntry.begin != begin or newEntry.end != end or newEntry.name != name else False
                    self.modifyTimer(newEntry, name, shortdesc, begin, end,
                                     serviceref, eit)
                    if modified_for_searchlog:
                        self.addToSearchLogfile(newEntry, "#", simulateOnly)
                    msg = "[AutoTimer] AutoTimer modified timer: %s ." % (
                        newEntry.name)
                    doLog(msg)
                    newEntry.log(501, msg)
                else:
                    msg = "[AutoTimer] AutoTimer modification not allowed for timer: %s ." % (
                        newEntry.name)
                    doLog(msg)
            else:
                newEntry = RecordTimerEntry(ServiceReference(serviceref),
                                            begin, end, name, shortdesc, eit)
                msg = "[AutoTimer] Try to add new timer based on AutoTimer %s." % (
                    timer.name)
                doLog(msg)
                newEntry.log(500, msg)

                # 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 = dest
            newEntry.calculateFilename()

            newEntry.justplay = timer.justplay
            newEntry.vpsplugin_enabled = timer.vps_enabled
            newEntry.vpsplugin_overwrite = timer.vps_overwrite
            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)

            else:
                conflictString = ""
                if similarTimer:
                    conflictString = similardict[eit].conflictString
                    msg = "[AutoTimer] Try to add similar Timer because of conflicts with %s." % (
                        conflictString)
                    doLog(msg)
                    newEntry.log(504, msg)

                # Try to add timer
                conflicts = recordHandler.record(newEntry)

                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
                    ])
                    doLog("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.checkDuplicates(timer,
                                                    name,
                                                    nameS,
                                                    shortdesc,
                                                    shortdescS,
                                                    extdesc,
                                                    extdescS,
                                                    force=True):
                                # Check if the similar is already known
                                if eitS not in similardict:
                                    doLog("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
                    if isnewFilterEntry:
                        self.addToSearchLogfile(newEntry, "++", simulateOnly)
                    else:
                        self.addToSearchLogfile(newEntry, "+", simulateOnly)
                    newEntry.extdesc = extdesc
                    timerdict[serviceref].append(newEntry)

                    # 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))
                    self.addToSearchLogfile(newEntry, "x", simulateOnly)

                    if config.plugins.autotimer.disabled_on_conflict.value:
                        msg = "[AutoTimer] Timer disabled because of conflicts with %s." % (
                            conflictString)
                        doLog(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)

        return (new, modified)
示例#16
0
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
        }
示例#17
0
    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", " ")

        eit = param.get("eit", None)
        if eit is None or eit.strip() == "":
            eit = 0
        else:
            try:
                eit = int(eit)
            except ValueError:
                return (False,
                        "Illegal Parameter value for Parameter edit : '%s'" %
                        eit)

        print "[WebComponents.Sources.Timer]: eit=%d" % eit
        if eit != 0:
            #check if the given event exists, if it doesn't return an error
            epgcache = eEPGCache.getInstance()
            event = epgcache.lookupEventId(eServiceReference(param['sRef']),
                                           eit)
            if event is None:
                return (False, "Event with id %d not found" % eit)
            eit = event.getEventId()

        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 = preferredTimerPath()
        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
                                #set the new data
                                timer.service_ref = service_ref
                                timer.begin = begin
                                timer.end = end
                                timer.name = name
                                timer.description = description
                                timer.eit = eit
                                timer.disabled = disabled
                                timer.justplay = justplay
                                timer.afterEvent = afterEvent
                                timer.dirname = dirname
                                timer.tags = tags
                                timer.repeated = repeated
                                timer.processRepeated()

                                #sanity check
                                timersanitycheck = TimerSanityCheck(
                                    self.session.nav.RecordTimer.timer_list,
                                    timer)
                                conflicts = None
                                if not timersanitycheck.check():
                                    conflicts = timersanitycheck.getSimulTimerList(
                                    )
                                    if conflicts is not None:
                                        for x in conflicts:
                                            if x.setAutoincreaseEnd(entry):
                                                self.session.nav.RecordTimer.timeChanged(
                                                    x)
                                        if not timersanitycheck.check():
                                            conflicts = timersanitycheck.getSimulTimerList(
                                            )

                                if conflicts is None:
                                    self.recordtimer.timeChanged(
                                        timer)  #go and save it
                                    print "[WebComponents.Timer] editTimer: Timer changed!"
                                    return (True, "Timer '%s' changed" %
                                            (timer.name))
                                else:
                                    print "[WebComponents.Timer] editTimer conflicting Timers: %s" % (
                                        conflicts)
                                    msg = ""
                                    for t in conflicts:
                                        msg = "%s / %s" % (msg, t.name)

                                    return (
                                        False,
                                        "Conflicting Timer(s) detected! %s" %
                                        (msg))

            except Exception as e:
                #obviously some value was not good, return an error
                print e
                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,
                                     eit,
                                     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)
示例#18
0
    def timerAdd(self):
        cur = self["list"].getCurrent()
        event = cur[0]
        if event is None:
            return
        serviceref = cur[1]
        isRecordEvent = isRepeat = firstNextRepeatEvent = isRunning = False
        eventid = event.getEventId()
        begin = event.getBeginTime()
        end = begin + event.getDuration()
        refstr = ':'.join(serviceref.ref.toString().split(':')[:11])
        for timer in self.session.nav.RecordTimer.getAllTimersList():
            needed_ref = ':'.join(
                timer.service_ref.ref.toString().split(':')[:11]) == refstr
            if needed_ref and timer.eit == eventid and (
                    begin < timer.begin <= end
                    or timer.begin <= begin <= timer.end):
                isRecordEvent = True
                break
            elif needed_ref and timer.repeated and self.session.nav.RecordTimer.isInRepeatTimer(
                    timer, event):
                isRecordEvent = True
                break
        if isRecordEvent:
            isRepeat = timer.repeated
            prev_state = timer.state
            isRunning = prev_state in (1, 2)
            title_text = isRepeat and _(
                "Attention, this is repeated timer!\n") or ""
            firstNextRepeatEvent = isRepeat and (
                begin < timer.begin <= end
                or timer.begin <= begin <= timer.end) and not timer.justplay
            menu = [(_("Delete timer"), "delete"), (_("Edit timer"), "edit")]
            buttons = ["red", "green"]
            if not isRunning:
                if firstNextRepeatEvent and timer.isFindRunningEvent(
                ) and not timer.isFindNextEvent():
                    menu.append((_("Options disable timer"), "disablerepeat"))
                else:
                    menu.append((_("Disable timer"), "disable"))
                buttons.append("yellow")
            elif prev_state == 2 and firstNextRepeatEvent:
                menu.append(
                    (_("Options disable timer"), "disablerepeatrunning"))
                buttons.append("yellow")
            menu.append((_("Timer Overview"), "timereditlist"))

            def timerAction(choice):
                if choice is not None:
                    if choice[1] == "delete":
                        self.removeTimer(timer)
                    elif choice[1] == "edit":
                        self.session.openWithCallback(self.finishedEdit,
                                                      TimerEntry, timer)
                    elif choice[1] == "disable":
                        self.disableTimer(timer, prev_state)
                    elif choice[1] == "timereditlist":
                        self.session.open(TimerEditList)
                    elif choice[1] == "disablerepeatrunning":
                        self.disableTimer(timer,
                                          prev_state,
                                          repeat=True,
                                          record=True)
                    elif choice[1] == "disablerepeat":
                        self.disableTimer(timer, prev_state, repeat=True)

            self.session.openWithCallback(
                timerAction,
                ChoiceBox,
                title=title_text +
                _("Select action for timer '%s'.") % timer.name,
                list=menu,
                keys=buttons)
        else:
            newEntry = RecordTimerEntry(serviceref,
                                        checkOldTimers=True,
                                        dirname=preferredTimerPath(),
                                        *parseEvent(event))
            newEntry.justplay = config.recording.timer_default_type.value == "zap"
            newEntry.always_zap = config.recording.timer_default_type.value == "zap+record"
            self.session.openWithCallback(self.finishedAdd, TimerEntry,
                                          newEntry)
示例#19
0
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
	}
示例#20
0
	def parseEPG(self, simulateOnly = False):
		if NavigationInstance.instance is None:
			print("[AutoTimer] Navigation is not available, can't parse EPG")
			return (0, 0, 0, [], [], [])

		total = 0
		new = 0
		modified = 0
		timers = []
		conflicting = []
		similar = defaultdict(list)			# Contains the the marked similar eits and the conflicting strings
		similars = []										# Contains the added similar timers

		# NOTE: the config option specifies "the next X days" which means today (== 1) + X
		delta = timedelta(days = config.plugins.autotimer.maxdaysinfuture.value + 1)
		evtLimit = mktime((date.today() + delta).timetuple())
		checkEvtLimit = delta.days > 1
		del delta

		# Read AutoTimer configuration
		self.readXml()

		# Get E2 instances
		epgcache = eEPGCache.getInstance()
		serviceHandler = eServiceCenter.getInstance()
		recordHandler = NavigationInstance.instance.RecordTimer

		# Save Recordings in a dict to speed things up a little
		# We include processed timers as we might search for duplicate descriptions
		# The recordict is always filled
		#Question: It might be better to name it timerdict
		#Question: Move to a separate function getTimerDict()
		#Note: It is also possible to use RecordTimer isInTimer(), but we won't get the timer itself on a match
		recorddict = defaultdict(list)
		for timer in chain(recordHandler.timer_list, recordHandler.processed_timers):
			if timer and timer.service_ref:
				if timer.eit is not None:
					event = epgcache.lookupEventId(timer.service_ref.ref, timer.eit)
					extdesc = event and event.getExtendedDescription() or ''
					timer.extdesc = extdesc
				elif not hasattr(timer, 'extdesc'):
					timer.extdesc = ''
				recorddict[str(timer.service_ref)].append(timer)

		# Create dict of all movies in all folders used by an autotimer to compare with recordings
		# The moviedict will be filled only if one AutoTimer is configured to avoid duplicate description for any recordings
		#Question: It might be better to name it recorddict
		moviedict = defaultdict(list)

		# Iterate Timer
		for timer in self.getEnabledTimerList():
			# 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
			if timer.encoding != 'UTF-8':
				try:
					match = match.decode('UTF-8').encode(timer.encoding)
				except UnicodeDecodeError:
					pass

			if timer.searchType == "description":
				test = []
				epgmatches = []

				casesensitive = timer.searchCase == "sensitive"
				if not casesensitive:
					match = match.lower()

				#if timer.services or timer.bouquets:
				# Service filter defined
				# Search only using the specified services
				for service in timer.services:
					test.append( (service, 0, -1, -1 ) )
				mask = (eServiceReference.isMarker | eServiceReference.isDirectory)
				for bouquet in timer.bouquets:
					services = serviceHandler.list(eServiceReference(bouquet))
					if not services is None:
						while True:
							service = services.getNext()
							if not service.valid(): #check end of list
								break
							if not (service.flags & mask):
								test.append( (service.toString(), 0, -1, -1 ) )

				if not test:
				#else:
					# No service filter defined
					# Search within all services - could be very slow

					# 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((info.getName(s), s))
					else:
						info = serviceHandler.info(bouquetroot)
						if info:
							bouquetlist.append((info.getName(bouquetroot), bouquetroot))

					# Get all services
					mask = (eServiceReference.isMarker | eServiceReference.isDirectory)
					for name, bouquet in bouquetlist:
						if not bouquet.valid(): #check end of list
							break
						if bouquet.flags & eServiceReference.isDirectory:
							services = serviceHandler.list(bouquet)
							if not services is None:
								while True:
									service = services.getNext()
									if not service.valid(): #check end of list
										break
									if not (service.flags & mask):
										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', 1000, typeMap[timer.searchType], match, caseMap[timer.searchCase])) or []
			# Sort list of tuples by begin time 'B'
			epgmatches.sort(key=itemgetter(3))

			# Reset the the marked similar servicerefs
			similar.clear()

			# Loop over all EPG matches
			for idx, ( serviceref, eit, name, begin, duration, shortdesc, extdesc ) in enumerate( epgmatches ):

			# Loop over all EPG matches
			for idx, ( serviceref, eit, name, begin, duration, shortdesc, extdesc ) in enumerate( epgmatches ):

				#Question: Do we need this?
				#Question: Move to separate function getRealService()
				eserviceref = eServiceReference(serviceref)
				evt = epgcache.lookupEventId(eserviceref, eit)
				if not evt:
					print("[AutoTimer] Could not create Event!")
					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()

				evtBegin = begin
				evtEnd = end = begin + duration

				# If event starts in less than 60 seconds skip it
				if begin < time() + 60:
					print("[AutoTimer] Skipping an event because it starts in less than 60 seconds")
					continue

				# 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 similar:
					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:
							continue

					dayofweek = str(timestamp.tm_wday)

				# Check timer conditions
				# NOTE: similar matches to 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):
					continue

				if timer.hasOffset():
					# Apply custom Offset
					begin, end = timer.applyOffset(begin, end)
				else:
					# Apply E2 Offset
					begin -= config.recording.margin_before.value * 60
					end += 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)

				total += 1

				# 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:
						#Question: Move to a separate function getRecordDict()
							print("[AutoTimer] listing of movies in " + dest + " failed")
								event = info.getEvent(movieref)
								if event is None:
									continue
									"shortdesc": info.getInfoString(movieref, iServiceInformation.sDescription),
									"extdesc": event.getExtendedDescription() or '' # XXX: does event.getExtendedDescription() actually return None on no description or an empty string?
					for movieinfo in moviedict.get(dest, ()):
						if movieinfo.get("name") == name \
							and movieinfo.get("shortdesc") == shortdesc:
							# Some channels indicate replays in the extended descriptions
							# If the similarity percent is higher then 0.8 it is a very close match
							extdescM = movieinfo.get("extdesc")
							if ( len(extdesc) == len(extdescM) and extdesc == extdescM ) \
								or ( 0.8 < SequenceMatcher(lambda x: x == " ",extdesc, extdescM).ratio() ):
								print("[AutoTimer] We found a matching recorded movie, skipping event:", name)
								movieExists = True
								break
					if movieExists:
						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 recorddict.get(serviceref, ()):
					if rtimer.eit == eit or config.plugins.autotimer.try_guessing.value and getTimeDiff(rtimer, evtBegin, evtEnd) > ((duration/10)*8):
						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 hasattr(rtimer, "isAutoTimer"):
							rtimer.log(501, "[AutoTimer] AutoTimer %s modified this automatically generated timer." % (timer.name))
						else:
							if config.plugins.autotimer.refresh.value != "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." % (timer.name))

						newEntry = rtimer
						modified += 1

						# Modify values saved in timer
						newEntry.name = name
						newEntry.description = shortdesc
						newEntry.begin = int(begin)
						newEntry.end = int(end)
						newEntry.service_ref = ServiceReference(serviceref)

						break
					elif timer.avoidDuplicateDescription >= 1 \
						and not rtimer.disabled \
						and rtimer.name == name \
						and rtimer.description == shortdesc:
							# Some channels indicate replays in the extended descriptions
							# If the similarity percent is higher then 0.8 it is a very close match
							if ( len(extdesc) == len(rtimer.extdesc) and extdesc == rtimer.extdesc ) \
								or ( 0.8 < SequenceMatcher(lambda x: x == " ",extdesc, rtimer.extdesc).ratio() ):
								oldExists = True
								print("[AutoTimer] We found a timer (similar service) with same description, skipping event")
								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
					if timer.avoidDuplicateDescription >= 2:
						for rtimer in chain.from_iterable( itervalues(recorddict) ):
							if not rtimer.disabled \
								and rtimer.name == name \
								and rtimer.description == shortdesc:
									# Some channels indicate replays in the extended descriptions
									# If the similarity percent is higher then 0.8 it is a very close match
									if ( len(extdesc) == len(rtimer.extdesc) and extdesc == rtimer.extdesc ) \
										or ( 0.8 < SequenceMatcher(lambda x: x == " ",extdesc, rtimer.extdesc).ratio() ):
										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))

					# 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.tags = timer.tags
				newEntry.vpsplugin_enabled = timer.vps_enabled
				newEntry.vpsplugin_overwrite = timer.vps_overwrite

				if oldExists:
					# XXX: this won't perform a sanity check, but do we actually want to do so?
					recordHandler.timeChanged(newEntry)
				else:
					conflictString = ""
					if similarTimer:
						conflictString = similar[eit].conflictString
						newEntry.log(504, "[AutoTimer] Try to add similar Timer because of conflicts with %s." % (conflictString))

					# Try to add timer
					conflicts = recordHandler.record(newEntry)

					if conflicts:
						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 conflicts and 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 shortdesc == shortdescS:
								# Some channels indicate replays in the extended descriptions
								# If the similarity percent is higher then 0.8 it is a very close match
								if ( len(extdesc) == len(extdescS) and extdesc == extdescS ) \
									or ( 0.8 < SequenceMatcher(lambda x: x == " ",extdesc, extdescS).ratio() ):
									# Check if the similar is already known
									if eitS not in similar:
										print("[AutoTimer] Found similar Timer: " + name)

										# Store the actual and similar eit and conflictString, so it can be handled later
										newEntry.conflictString = conflictString
										similar[eit] = newEntry
										similar[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
										break
									else:
										similarTimer = False
										newEntry = similar[eitS]
										break

					if conflicts is None:
						timer.decrementCounter()
						new += 1
						newEntry.extdesc = extdesc
						recorddict[serviceref].append(newEntry)

						# Similar timers are in new timers list and additionally in similar timers list
						if similarTimer:
							similars.append((name, begin, end, serviceref, timer.name))
							similar.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:
							newEntry.log(503, "[AutoTimer] Timer disabled because of conflicts with %s." % (conflictString))
							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)

		return (total, new, modified, timers, conflicting, similars)

# Supporting functions

	def addDirectoryToMovieDict(self, moviedict, dest, serviceHandler):
		movielist = serviceHandler.list(eServiceReference("2:0:1:0:0:0:0:0:0:0:" + dest))
		if movielist is None:
			print("[AutoTimer] listing of movies in " + dest + " failed")
		else:
			append = moviedict[dest].append
			while 1:
				movieref = movielist.getNext()
				if not movieref.valid():
					break
				if movieref.flags & eServiceReference.mustDescent:
					continue
				info = serviceHandler.info(movieref)
				if info is None:
					continue
				event = info.getEvent(movieref)
				if event is None:
					continue
				append({
					"name": info.getName(movieref),
					"shortdesc": info.getInfoString(movieref, iServiceInformation.sDescription),
					"extdesc": event.getExtendedDescription() or '' # XXX: does event.getExtendedDescription() actually return None on no description or an empty string?
				})

	def checkSimilarity(self, timer, name1, name2, shortdesc1, shortdesc2, extdesc1, extdesc2):
		foundTitle = (name1 == name2)
		foundShort = (shortdesc1 == shortdesc2) if timer.searchForDuplicateDescription > 0 else True
		foundExt = True
		# NOTE: only check extended if short description already is a match because otherwise
		# it won't evaluate to True anyway
		if timer.searchForDuplicateDescription == 2 and foundShort:
			# Some channels indicate replays in the extended descriptions
			# If the similarity percent is higher then 0.8 it is a very close match
			foundExt = ( len(extdesc1) == len(extdesc2) and extdesc1 == extdesc2 ) \
			 or ( 0.8 < SequenceMatcher(lambda x: x == " ",extdesc1, extdesc2).ratio() )

		return (total, new, modified, timers, conflicting, similars)
示例#21
0
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
		}
示例#22
0
	def parseTimer(self, timer, epgcache, serviceHandler, recordHandler, checkEvtLimit, evtLimit, timers, conflicting, similars, skipped, timerdict, moviedict, 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))

		# 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 == "favoritedesc":
			epgmatches = []

			casesensitive = timer.searchCase == "sensitive"
			if not casesensitive:
				match = match.lower()

			test = []
			if timer.services or timer.bouquets:
				if timer.services:
					test = [(service, 0, -1, -1) for service in timer.services]
				if 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 = []
				if config.usage.multibouquet.value:
					refstr = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.tv" ORDER BY bouquet'
					bouquetroot = eServiceReference(refstr)
					bouquets = serviceHandler.list(bouquetroot)
					if bouquets:
						while True:
							s = bouquets.getNext()
							if not s.valid():
								break
							if s.flags & eServiceReference.isDirectory and not s.flags & eServiceReference.isInvisible:
								info = serviceHandler.info(s)
								if info:
									bouquetlist.append(s)
				else:
					service_types_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 22) || (type == 25) || (type == 31) || (type == 134) || (type == 195)'
					refstr = '%s FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet' % (service_types_tv)
					bouquetroot = eServiceReference(refstr)
					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()) or match in (name if casesensitive else name.lower()):
						epgmatches.append((serviceref, eit, name, begin, duration, shortdesc, extdesc))

		else:
			# Search EPG, default to empty list
			epgmatches = epgcache.search(('RITBDSE', int(config.plugins.autotimer.max_search_events_match.value), 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
		for idx, (serviceref, eit, name, begin, duration, shortdesc, extdesc) in enumerate(epgmatches):
			startLog()

			# timer destination dir
			dest = timer.destination or config.usage.default_path.value

			evtBegin = begin
			evtEnd = end = begin + duration

			doLog("[AutoTimer] possible epgmatch %s" % (name))
			doLog("[AutoTimer] Serviceref %s" % serviceref)
			eserviceref = eServiceReference(serviceref)
			evt = epgcache.lookupEventId(eserviceref, eit)
			if not evt:
				doLog("[AutoTimer] Could not create Event!")
				skipped.append((name, begin, end, serviceref, timer.name, getLog()))
				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()
			#	doLog("[AutoTimer] Serviceref2 %s" % serviceref)

			# If event starts in less than 60 seconds skip it
			if begin < time() + 60:
				doLog("[AutoTimer] Skipping an event because it starts in less than 60 seconds")
				skipped.append((name, begin, end, serviceref, timer.name, getLog()))
				continue

			# Set short description to equal extended description if it is empty.
			if not shortdesc and timer.descShortEqualExt and extdesc:
				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:
						doLog("[AutoTimer] Skipping an event because of maximum days in future is reached")
						skipped.append((name, begin, end, serviceref, timer.name, getLog()))
						continue

				dayofweek = str(timestamp.tm_wday)
				# Update dayofweek when programmes that cross midnight and have a dayofweek filter
				end_timestamp = localtime(end)
				end_dayofweek = str(end_timestamp.tm_wday)
				if end_dayofweek != dayofweek:
					dayofweek = end_dayofweek

			# Check timer conditions
			# NOTE: similar matches do not care about the day/time they are on, so ignore them
			if timer.checkServices(serviceref):
				doLog("[AutoTimer] Skipping an event because of check services")
				skipped.append((name, begin, end, serviceref, timer.name, getLog()))
				continue
			if timer.checkDuration(duration):
				doLog("[AutoTimer] Skipping an event because of duration check")
				skipped.append((name, begin, end, serviceref, timer.name, getLog()))
				continue
			if not similarTimer:
				if timer.checkTimespan(timestamp):
					doLog("[AutoTimer] Skipping an event because of timestamp check")
					skipped.append((name, begin, end, serviceref, timer.name, getLog()))
					continue
				if timer.checkTimeframe(begin):
					doLog("[AutoTimer] Skipping an event because of timeframe check")
					skipped.append((name, begin, end, serviceref, timer.name, getLog()))
					continue

			# Initialize
			newEntry = None
			oldEntry = None
			oldExists = False
			allow_modify = True
			newAT = None

			# Eventually change service to alternative
			if timer.overrideAlternatives:
				serviceref = timer.getAlternative(serviceref)

			if timer.series_labeling and sp_getSeasonEpisode is not None:
				allow_modify = False
				doLog("[AutoTimer SeriesPlugin] Request name, desc, path %s %s %s" % (name, shortdesc, dest))
				sp = sp_getSeasonEpisode(serviceref, name, evtBegin, evtEnd, shortdesc, dest, True)
				if sp and type(sp) in (tuple, list) and len(sp) > 3:
					name = sp[0] or name
					shortdesc = sp[1] or shortdesc
					dest = sp[2] or dest
					doLog(str(sp[3]))
					allow_modify = True
					doLog("[AutoTimer SeriesPlugin] Returned name, desc, path %s %s %s" % (name, shortdesc, dest))
				else:
					# Nothing found
					doLog(str(sp))
					# If AutoTimer name not equal match, do a second lookup with the name
					if timer.name.lower() != timer.match.lower():
						doLog("[AutoTimer SeriesPlugin] Request name, desc, path %s %s %s" % (timer.name, shortdesc, dest))
						sp = sp_getSeasonEpisode(serviceref, timer.name, evtBegin, evtEnd, shortdesc, dest, True)
						if sp and type(sp) in (tuple, list) and len(sp) > 3:
							name = sp[0] or name
							shortdesc = sp[1] or shortdesc
							dest = sp[2] or dest
							doLog(str(sp[3]))
							allow_modify = True
							doLog("[AutoTimer SeriesPlugin] Returned name, desc, path %s %s %s" % (name, shortdesc, dest))
						else:
							doLog(str(sp))

			if timer.checkFilter(name, shortdesc, extdesc, dayofweek):
				doLog("[AutoTimer] Skipping an event because of filter check")
				skipped.append((name, begin, end, serviceref, timer.name, getLog()))
				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
				evtEnd = evtBegin

			# 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"), isMovie=True):
						doLog("[AutoTimer] We found a matching recorded movie, skipping event:", name)
						movieExists = True
						break
				if movieExists:
					doLog("[AutoTimer] Skipping an event because movie already exists")
					skipped.append((name, begin, end, serviceref, timer.name, getLog()))
					continue

			# 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, ()):
				try: # protect against vps plugin not being present
					vps_changed = hasVps and (rtimer.vpsplugin_enabled != timer.vps_enabled or rtimer.vpsplugin_overwrite != timer.vps_overwrite)
				except:
					vps_changed = False
				time_changed = (evtBegin - offsetBegin != rtimer.begin) or (evtEnd + offsetEnd != rtimer.end)
				desc_changed = (timer.avoidDuplicateDescription >= 1 and shortdesc and rtimer.description and shortdesc != rtimer.description) or (timer.avoidDuplicateDescription >= 2 and extdesc and rtimer.extdesc and extdesc != rtimer.extdesc)
				if rtimer.eit == eit:
					oldExists = True
					doLog("[AutoTimer] We found a timer based on eit")
					if time_changed or desc_changed or vps_changed:
						newEntry = rtimer
						oldEntry = [rtimer.name, rtimer.description, rtimer.extdesc, rtimer.begin, rtimer.end, rtimer.service_ref, rtimer.eit, rtimer.disabled]
					break
				elif config.plugins.autotimer.try_guessing.value:
					if timeSimilarityPercent(rtimer, evtBegin, evtEnd, timer) > 80:
						oldExists = True
						doLog("[AutoTimer] We found a timer based on time guessing")
						if time_changed or desc_changed or vps_changed:
							newEntry = rtimer
							oldEntry = [rtimer.name, rtimer.description, rtimer.extdesc, rtimer.begin, rtimer.end, rtimer.service_ref, rtimer.eit, rtimer.disabled]
						break
				if oldExists is None and timer.avoidDuplicateDescription >= 1 and not rtimer.disabled:
					# searchForDuplicateDescription is 1 - check short description / searchForDuplicateDescription is 2 - check extended description
					if self.checkSimilarity(timer, name, rtimer.name, shortdesc, rtimer.description, extdesc, rtimer.extdesc):
						oldExists = True
						doLog("[AutoTimer] We found a timer (similar service) with same description, skipping event")
						break

			# We found no timer we want to edit
			if newEntry is None:
				# But there is a match
				if oldExists:
					doLog("[AutoTimer] Skipping an event because a timer on same service exists")
					skipped.append((name, begin, end, serviceref, timer.name, getLog()))
					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, rtimer.service_ref.ref.toString(), enable_multiple_timer):
							oldExists = True
							print("[AutoTimer] We found a timer with same start time, skipping event")
							break
						if timer.avoidDuplicateDescription >= 2:
							if self.checkSimilarity(timer, name, rtimer.name, shortdesc, rtimer.description, extdesc, rtimer.extdesc):
								oldExists = True
								doLog("[AutoTimer] We found a timer (any service) with same description, skipping event")
								break
				if oldExists:
					doLog("[AutoTimer] Skipping an event because a timer on any service exists")
					skipped.append((name, begin, end, serviceref, timer.name, getLog()))
					continue

				if timer.checkCounter(timestamp):
					doLog("[AutoTimer] Not adding new timer because counter is depleted.")
					skipped.append((name, begin, end, serviceref, timer.name, getLog()))
					continue

			# if set option for check/save timer in filterlist and only if not found an existing timer
			isnewFilterEntry = False
			if (config.plugins.autotimer.series_save_filter.value or timer.series_save_filter) and not oldExists:
				if timer.series_labeling and sp_getSeasonEpisode is not None:
					if sp and type(sp) in (tuple, list) and len(sp) == 4:
						ret = self.addToFilterfile(str(sp[0]), begin, simulateOnly)
					if sp and type(sp) in (tuple, list) and len(sp) > 3:
						filter_title = str(sp[0])
						if len(sp) > 4:
							filter_title = "{series:s} - S{season:02d}E{rawepisode:s} - {title:s}".format(**sp[4])
						ret = self.addToFilterfile(filter_title, begin, simulateOnly, str(sp[0]))
						if ret:
							if simulateOnly:
								doLog("[AutoTimer SeriesPlugin] only simulate - new Timer would be saved in autotimer_filter")
							else:
								doLog("[AutoTimer SeriesPlugin] new Timer saved in autotimer_filter")
								isnewFilterEntry = True
						else:
							skipped.append((name, begin, end, serviceref, timer.name, getLog()))
							continue

			# Append to timerlist and abort if simulating
			timers.append((name, begin, end, serviceref, timer.name, getLog()))
			if simulateOnly:
				continue

			if newEntry is not None:
				# Abort if we don't want to modify timers or timer is repeated
				if config.plugins.autotimer.refresh.value == "none" or newEntry.repeated:
					doLog("[AutoTimer] Won't modify existing timer because either no modification allowed or repeated timer")
					continue
				if "autotimer" in newEntry.flags:
					msg = "[AutoTimer] AutoTimer %s modified this automatically generated timer." % (timer.name)
					doLog(msg)
					newEntry.log(501, msg)
				else:
					if config.plugins.autotimer.refresh.value != "all":
						doLog("[AutoTimer] Won't modify existing timer because it's no timer set by us")
						continue

					msg = "[AutoTimer] Warning, AutoTimer %s messed with a timer which might not belong to it: %s ." % (timer.name, newEntry.name)
					doLog(msg)
					newEntry.log(501, msg)

				changed = newEntry.begin != begin or newEntry.end != end or newEntry.name != name
				if allow_modify:
					if oldExists and newEntry.service_ref.ref.toString() == serviceref and newEntry.eit == eit and newEntry.name == name and newEntry.begin < begin and newEntry.end < end and (0 < begin - newEntry.end <= 600):
						begin = newEntry.begin
						doLog("[AutoTimer] This same eit and different times end - update only end")
					if self.modifyTimer(newEntry, name, shortdesc, begin, end, serviceref, eit, base_timer=timer):
						msg = "[AutoTimer] AutoTimer modified timer: %s ." % (newEntry.name)
						doLog(msg)
						newEntry.log(501, msg)
						if changed:
							self.addToSearchLogfile(newEntry, "#", simulateOnly)
							modified += 1
					else:
						msg = "[AutoTimer] AutoTimer modification not allowed for timer %s because conflicts or double timer." % (newEntry.name)
						doLog(msg)
						if oldEntry:
							self.setOldTimer(newEntry, oldEntry)
							doLog("[AutoTimer] conflict for modification timer %s detected return to old timer" % (newEntry.name))
						continue
				else:
					msg = "[AutoTimer] AutoTimer modification not allowed for timer: %s ." % (newEntry.name)
					doLog(msg)
					continue
			else:
				newEntry = RecordTimerEntry(ServiceReference(serviceref), begin, end, name, shortdesc, eit)
				newAT = True

				msg = "[AutoTimer] Try to add new timer based on AutoTimer %s." % (timer.name)
				doLog(msg)
				newEntry.log(500, msg)
				msg = "[AutoTimer] Timer start on: %s" % ctime(begin)
				doLog(msg)
				newEntry.log(509, msg)

				# Mark this entry as AutoTimer
				newEntry.flags.add("autotimer")
				# Mark this entry as timer name
				newEntry.flags.add(stringToXML(timer.name))

			# 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 = dest
			newEntry.calculateFilename()
			newEntry.justplay = timer.justplay
			newEntry.vpsplugin_enabled = timer.vps_enabled
			newEntry.vpsplugin_overwrite = timer.vps_overwrite
			newEntry.conflict_detection = timer.conflict_detection
			newEntry.always_zap = timer.always_zap
			newEntry.zap_wakeup = timer.zap_wakeup

			tags = timer.tags[:]
			if config.plugins.autotimer.add_autotimer_to_tags.value:
				if 'AutoTimer' not in tags:
					tags.append('AutoTimer')
			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 and newAT is None:
				if self.isResolvedConflict(newEntry):
					recordHandler.timeChanged(newEntry)
				else:
					if oldEntry:
						self.setOldTimer(newEntry, oldEntry)
						doLog("[AutoTimer] rechecking - conflict for timer %s detected return to old timer" % (newEntry.name))
					continue
			elif newAT:
				newAT = newEntry
				conflictString = ""
				if similarTimer:
					conflictString = similardict[eit].conflictString
					msg = "[AutoTimer] Try to add similar Timer because of conflicts with %s." % (conflictString)
					doLog(msg)
					newEntry.log(504, msg)

				# add new timer in AT timer list
				atDoubleTimer = False
				refstr = ':'.join(newEntry.service_ref.ref.toString().split(':')[:11])
				for at in addNewTimers:
					needed_ref = ':'.join(at.service_ref.ref.toString().split(':')[:11]) == refstr
					if needed_ref and at.eit == newEntry.eit and (newEntry.begin < at.begin <= newEntry.end or at.begin <= newEntry.begin <= at.end):
						atDoubleTimer = True
						break
				if atDoubleTimer:
					doLog("[AutoTimer] ignore double new auto timer %s." % newEntry.name)
					continue
				else:
					addNewTimers.append(newEntry)

				# 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:
							doLog("[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])
					doLog("[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:
									doLog("[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()
					if newEntry in (recordHandler.timer_list[:] + recordHandler.processed_timers[:]):
						new += 1
						if isnewFilterEntry:
							self.addToSearchLogfile(newEntry, "++", simulateOnly)
						else:
							self.addToSearchLogfile(newEntry, "+", simulateOnly)
						newEntry.extdesc = extdesc
						timerdict[serviceref].append(newEntry)

						# 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()
					else:
						doLog("[AutoTimer] ignore double timer %s." % newEntry.name)

				# 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)
						doLog(msg)
						newEntry.log(503, msg)
						newEntry.disabled = True
						if newEntry in (recordHandler.timer_list[:] + recordHandler.processed_timers[:]):
							recordHandler.timeChanged(newEntry)
						else:
							# 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)
					elif newAT != newEntry and newEntry in (recordHandler.timer_list[:] + recordHandler.processed_timers[:]):
						if not self.isResolvedConflict(newEntry):
							newEntry.disabled = True
							recordHandler.timeChanged(newEntry)
							doLog("[AutoTimer] Unknown conflict, disable this timer %s." % newEntry.name)

		return (new, modified)
示例#23
0
    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
                                #Let's apply the new values
                                timer.service_ref = service_ref
                                timer.begin = int(begin)
                                timer.end = int(end)
                                timer.name = name
                                timer.description = description
                                timer.disabled = disabled
                                timer.justplay = justplay
                                timer.afterEvent = afterEvent
                                timer.repeated = repeated
                                timer.dirname = dirname
                                timer.tags = tags

                                #send the changed timer back to enigma2 and hope it's good
                                self.session.nav.RecordTimer.timeChanged(timer)
                                print "[WebComponents.Timer] editTimer: Timer changed!"
                                return (True, "Timer %s has been changed!" %
                                        (timer.name))
            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
            self.recordtimer.record(timer)
            return (True, "Timer added successfully!")
        except Exception:
            #something went wrong, most possibly one of the given paramater-values was wrong
            return (False, "Could not add timer '%s'!" % name)

        return (False, "Unexpected Error")
示例#24
0
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'] = getBoxBrand()
    info['model'] = getBoxType()
    info['platform'] = boxbranding.getMachineBuild()

    try:
        info['procmodel'] = getBoxProc()
    except:  # noqa: E722
        info['procmodel'] = boxbranding.getMachineProcModel()

    try:
        info['procmodeltype'] = getBoxProcType()
    except:  # noqa: E722
        info['procmodeltype'] = None

    try:
        info['lcd'] = getLcd()
    except:  # noqa: E722
        info['lcd'] = 0

    try:
        info['grabpip'] = getGrabPip()
    except:  # noqa: E722
        info['grabpip'] = 0

    cpu = about.getCPUInfoString()
    info['chipset'] = cpu
    info['cpubrand'] = about.getCPUBrand()
    info['socfamily'] = boxbranding.getSoCFamily()
    info['cpuarch'] = about.getCPUArch()
    if config.OpenWebif.about_benchmark.value is True:
        info['cpubenchmark'] = about.getCPUBenchmark()
    else:
        info['cpubenchmark'] = _("Disabled in configuration")
    info['flashtype'] = about.getFlashType()

    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'])

    info['uptime'] = about.getBoxUptime()

    info["webifver"] = OPENWEBIFVER
    info['imagedistro'] = boxbranding.getImageDistro()
    info['oever'] = boxbranding.getImageBuild()
    info['visionversion'] = boxbranding.getVisionVersion()
    info['visionrevision'] = boxbranding.getVisionRevision()
    info['visionmodule'] = about.getVisionModule()

    if fileExists("/etc/openvision/multiboot"):
        multibootflag = open("/etc/openvision/multiboot", "r").read().strip()
        if multibootflag == "1":
            info['multiboot'] = _("Yes")
        else:
            info['multiboot'] = _("No")
    else:
        info['multiboot'] = _("Yes")

    info['enigmaver'] = getEnigmaVersionString()
    info['driverdate'] = about.getDriverInstalledDate()
    info['kernelver'] = boxbranding.getKernelVersion()
    info['dvbapitype'] = about.getDVBAPI()
    info['gstreamerversion'] = about.getGStreamerVersionString(cpu)
    info['ffmpegversion'] = about.getFFmpegVersionString()
    info['pythonversion'] = about.getPythonVersionString()

    try:
        info['hwserial'] = getHWSerial()
    except:  # noqa: E722
        info['hwserial'] = None

    if (info['hwserial'] is None or info['hwserial'] == "unknown"):
        info['hwserial'] = about.getCPUSerial()

    try:
        info['boxrctype'] = getBoxRCType()
    except:  # noqa: E722
        info['boxrctype'] = None

    if (info['boxrctype'] is None or info['boxrctype'] == "unknown"):
        if fileExists("/usr/bin/remotecfg"):
            info['boxrctype'] = _("Amlogic remote")
        elif fileExists("/usr/sbin/lircd"):
            info['boxrctype'] = _("LIRC remote")

    info['ovrctype'] = boxbranding.getRCType()
    info['ovrcname'] = boxbranding.getRCName()
    info['ovrcidnum'] = boxbranding.getRCIDNum()

    info['transcoding'] = boxbranding.getHaveTranscoding()
    info['multitranscoding'] = boxbranding.getHaveMultiTranscoding()

    info['displaytype'] = boxbranding.getDisplayType()

    info['updatedatestring'] = about.getUpdateDateString()
    info['enigmadebuglvl'] = eGetEnigmaDebugLvl()

    info['imagearch'] = boxbranding.getImageArch()
    info['imagefolder'] = boxbranding.getImageFolder()
    info['imagefilesystem'] = boxbranding.getImageFileSystem()
    info['feedsurl'] = boxbranding.getFeedsUrl()
    info['developername'] = boxbranding.getDeveloperName()
    info['builddatestring'] = about.getBuildDateString()
    info['imagefpu'] = boxbranding.getImageFPU()
    info['havemultilib'] = boxbranding.getHaveMultiLib()

    try:
        info['fp_version'] = getFPVersion()
    except:  # noqa: E722
        info['fp_version'] = None

    info['tuners'] = []
    for i in list(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 open(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] == "":
                        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['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:
                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 as 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(
                            removeBad(timer.service_ref.getServiceName()))
                        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 as error:
            info['EX'] = error

    info['timerpipzap'] = False
    info['timerautoadjust'] = False

    try:
        timer = RecordTimerEntry('', 0, 0, '', '', 0)
        if hasattr(timer, "pipzap"):
            info['timerpipzap'] = True
        if hasattr(timer, "autoadjust"):
            info['timerautoadjust'] = True
    except Exception as error:
        print("[OpenWebif] -D- RecordTimerEntry check %s" % error)

    STATICBOXINFO = info
    return info
示例#25
0
 def processTimers(self, timers):
     update_queue = []
     for iceTimer in timers:
         # print "[IceTV] iceTimer:", iceTimer
         try:
             action = iceTimer.get("action", "").encode("utf8")
             state = iceTimer.get("state", "").encode("utf8")
             name = iceTimer.get("name", "").encode("utf8")
             start = int(
                 timegm(
                     strptime(iceTimer["start_time"].split("+")[0],
                              "%Y-%m-%dT%H:%M:%S")))
             duration = 60 * int(iceTimer["duration_minutes"])
             channel_id = long(iceTimer["channel_id"])
             ice_timer_id = iceTimer["id"].encode("utf8")
             if action == "forget":
                 for timer in _session.nav.RecordTimer.timer_list:
                     if timer.ice_timer_id == ice_timer_id:
                         # print "[IceTV] removing timer:", timer
                         _session.nav.RecordTimer.removeEntry(timer)
                         break
                 else:
                     self.deleteTimer(ice_timer_id)
             elif state == "completed":
                 continue  # Completely ignore completed timers - the server should not be sending those back to us anyway.
             elif channel_id in self.channel_service_map:
                 completed = False
                 for timer in _session.nav.RecordTimer.processed_timers:
                     if timer.ice_timer_id == ice_timer_id:
                         # print "[IceTV] completed timer:", timer
                         iceTimer["state"] = "completed"
                         iceTimer["message"] = "Done"
                         update_queue.append(iceTimer)
                         completed = True
                 updated = False
                 if not completed:
                     for timer in _session.nav.RecordTimer.timer_list:
                         if timer.ice_timer_id == ice_timer_id:
                             # print "[IceTV] updating timer:", timer
                             if self.updateTimer(
                                     timer, name, start -
                                     config.recording.margin_before.value *
                                     60, start + duration +
                                     config.recording.margin_after.value *
                                     60,
                                     self.channel_service_map[channel_id]):
                                 if not self.modifyTimer(timer):
                                     iceTimer["state"] = "failed"
                                     iceTimer[
                                         "message"] = "Failed to update the timer"
                                     update_queue.append(iceTimer)
                             else:
                                 self.onTimerChanged(timer)
                             updated = True
                 created = False
                 if not completed and not updated:
                     channels = self.channel_service_map[channel_id]
                     # print "[IceTV] channel_id %s maps to" % channel_id, channels
                     db = eDVBDB.getInstance()
                     for channel in channels:
                         serviceref = ServiceReference(
                             "1:0:1:%x:%x:%x:EEEE0000:0:0:0:" %
                             (channel[2], channel[1], channel[0]))
                         if db.isValidService(channel[1], channel[0],
                                              channel[2]):
                             # print "[IceTV] %s is valid" % str(serviceref), serviceref.getServiceName()
                             recording = RecordTimerEntry(
                                 serviceref,
                                 start -
                                 config.recording.margin_before.value * 60,
                                 start + duration +
                                 config.recording.margin_after.value * 60,
                                 name,
                                 "",
                                 None,
                                 ice_timer_id=ice_timer_id)
                             conflicts = _session.nav.RecordTimer.record(
                                 recording)
                             if conflicts is None:
                                 iceTimer["state"] = "pending"
                                 iceTimer["message"] = "Added"
                                 created = True
                                 break
                             else:
                                 names = [r.name for r in conflicts]
                                 iceTimer["state"] = "failed"
                                 iceTimer[
                                     "message"] = "Timer conflict: " + ", ".join(
                                         names)
                                 update_queue.append(iceTimer)
                                 # print "[IceTV] Timer conflict:", conflicts
                                 self.addLog("Timer %s conflicts with %s" %
                                             (name, ", ".join(names)))
                         else:
                             iceTimer["state"] = "failed"
                             iceTimer["message"] = "No matching service"
                             update_queue.append(iceTimer)
                 if not completed and not updated and not created:
                     iceTimer["state"] = "failed"
                     update_queue.append(iceTimer)
             else:
                 iceTimer["state"] = "failed"
                 iceTimer[
                     "message"] = "No valid service mapping for channel_id %d" % channel_id
                 update_queue.append(iceTimer)
         except (IOError, RuntimeError, KeyError) as ex:
             print "[IceTV] Can not process iceTimer:", ex
     # Send back updated timer states
     res = True
     try:
         self.putTimers(update_queue)
         self.addLog("Timers updated OK")
     except KeyError as ex:
         print "[IceTV] ", str(ex)
         res = False
     except (IOError, RuntimeError) as ex:
         msg = "Can not update timers: " + str(ex)
         if hasattr(ex, "response") and hasattr(ex.response, "text"):
             msg += "\n%s" % str(ex.response.text).strip()
         self.addLog(msg)
         res = False
     return res
示例#26
0
	def parseEPG(self, simulateOnly = False):
		if NavigationInstance.instance is None:
			print "[AutoTimer] Navigation is not available, can't parse EPG"
			return (0, 0, 0, [], [])

		total = 0
		new = 0
		modified = 0
		timers = []
		conflicting = []

		self.readXml()

		# Save Recordings in a dict to speed things up a little
		# We include processed timers as we might search for duplicate descriptions
		recorddict = {}
		for timer in NavigationInstance.instance.RecordTimer.timer_list + NavigationInstance.instance.RecordTimer.processed_timers:
			recorddict.setdefault(str(timer.service_ref), []).append(timer)

		# Iterate Timer
		for timer in self.getEnabledTimerList():
			# Workaround to allow search for umlauts if we know the encoding
			match = timer.match
			if timer.encoding != 'UTF-8':
				try:
					match = match.decode('UTF-8').encode(timer.encoding)
				except UnicodeDecodeError:
					pass

			# Search EPG, default to empty list
			epgcache = eEPGCache.getInstance()
			ret = epgcache.search(('RI', 500, typeMap[timer.searchType], match, caseMap[timer.searchCase])) or ()

			for serviceref, eit in ret:
				eserviceref = eServiceReference(serviceref)

				evt = epgcache.lookupEventId(eserviceref, eit)
				if not evt:
					print "[AutoTimer] Could not create Event!"
					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()

				# Gather Information
				name = evt.getEventName()
				description = evt.getShortDescription()
				begin = evt.getBeginTime()
				duration = evt.getDuration()
				end = begin + duration

				# If event starts in less than 60 seconds skip it
				if begin < time() + 60:
					continue

				# Convert begin time
				timestamp = localtime(begin)

				# Update timer
				timer.update(begin, timestamp)

				# Check Duration, Timespan and Excludes
				if timer.checkServices(serviceref) \
					or timer.checkDuration(duration) \
					or timer.checkTimespan(timestamp) \
					or timer.checkFilter(name, description,
						evt.getExtendedDescription(), str(timestamp.tm_wday)):
					continue

				if timer.hasOffset():
					# Apply custom Offset
					begin, end = timer.applyOffset(begin, end)
				else:
					# Apply E2 Offset
					begin -= config.recording.margin_before.value * 60
					end += config.recording.margin_after.value * 60

				# Eventually change service to alternative
				if timer.overrideAlternatives:
					serviceref = timer.getAlternative(serviceref)

				total += 1

				# Append to timerlist and abort if simulating
				timers.append((name, begin, end, serviceref, timer.name))
				if simulateOnly:
					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 recorddict.get(serviceref, ()):
					if rtimer.eit == eit or config.plugins.autotimer.try_guessing.value and getTimeDiff(rtimer, begin, end) > ((duration/10)*8):
						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 hasattr(rtimer, "isAutoTimer"):
								print "[AutoTimer] Modifying existing AutoTimer!"
						else:
							if config.plugins.autotimer.refresh.value != "all":
								print "[AutoTimer] Won't modify existing timer because it's no timer set by us"
								break

							print "[AutoTimer] Warning, we're messing with a timer which might not have been set by us"

						newEntry = rtimer
						modified += 1

						# Modify values saved in timer
						newEntry.name = name
						newEntry.description = description
						newEntry.begin = int(begin)
						newEntry.end = int(end)
						newEntry.service_ref = ServiceReference(serviceref)

						break
					elif timer.avoidDuplicateDescription == 1 and not rtimer.disabled and rtimer.name == name and rtimer.description == description:
						oldExists = True
						print "[AutoTimer] We found a timer with same description, skipping event"
						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
					if timer.avoidDuplicateDescription == 2:
						# I thinks thats the fastest way to do this, though it's a little ugly
						try:
							for list in recorddict.values():
								for rtimer in list:
									if not rtimer.disabled and rtimer.name == name and rtimer.description == description:
										raise AutoTimerIgnoreTimerException("We found a timer with same description, skipping event")
						except AutoTimerIgnoreTimerException, etite:
							print etite
							continue

					if timer.checkCounter(timestamp):
						continue

					print "[AutoTimer] Adding an event."
					newEntry = RecordTimerEntry(ServiceReference(serviceref), begin, end, name, description, eit)

					# Mark this entry as AutoTimer (only AutoTimers will have this Attribute set)
					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.tags = timer.tags

				if oldExists:
					# XXX: this won't perform a sanity check, but do we actually want to do so?
					NavigationInstance.instance.RecordTimer.timeChanged(newEntry)
				else:
					conflicts = NavigationInstance.instance.RecordTimer.record(newEntry)
					if conflicts and config.plugins.autotimer.disabled_on_conflict.value:
						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 = NavigationInstance.instance.RecordTimer.record(newEntry)
						conflicting.append((name, begin, end, serviceref, timer.name))
					if conflicts is None:
						timer.decrementCounter()
						new += 1
						recorddict.setdefault(serviceref, []).append(newEntry)
					else:
						conflicting.append((name, begin, end, serviceref, timer.name))
示例#27
0
                 timestruct.tm_hour, timestruct.tm_min, 0, datestruct.tm_wday,
                 datestruct.tm_yday, -1))
            del datestruct, timestruct
        except ValueError, e:
            payload = "%d argument error" % (CODE_SYNTAX, )
            return self.sendLine(payload)
        except KeyError, e:
            payload = "%d argument error" % (CODE_SYNTAX, )
            return self.sendLine(payload)

        if end < begin:
            end += 86400  # Add 1 day, beware - this is evil and might not work correctly due to dst
        timer = RecordTimerEntry(service_ref,
                                 begin,
                                 end,
                                 name,
                                 description,
                                 0,
                                 disabled=flags & 1 == 0)
        if oldTimer:
            recordTimer.removeEntry(oldTimer)
            timer.justplay = oldTimer.justplay
            timer.afterEvent = oldTimer.afterEvent
            timer.dirname = oldTimer.dirname
            timer.tags = oldTimer.tags
            timer.log_entries = oldTimer.log_entries

        conflict = recordTimer.record(timer)
        if conflict is None:
            return self.sendTimerLine(timer, timerId, last=True)
        else:
示例#28
0
    def check_and_add_event(self, neweventid):
        if not config.plugins.vps.allow_seeking_multiple_pdc.value:
            return

        epgcache = eEPGCache.getInstance()
        evt = epgcache.lookupEventId(self.rec_ref, neweventid)

        if evt:
            evt_begin = evt.getBeginTime() + 60
            evt_end = evt.getBeginTime() + evt.getDuration() - 60

            if evt_begin < self.timer.begin:
                return

            for checktimer in self.session.nav.RecordTimer.timer_list:
                if checktimer == self.timer:
                    continue
                if (checktimer.begin - evt_begin) > 3600 * 2:
                    break

                compareString = checktimer.service_ref.ref.toCompareString()
                if compareString == self.timer.service_ref.ref.toCompareString(
                ) or compareString == self.rec_ref.toCompareString():
                    if checktimer.eit == neweventid:
                        return

                    if checktimer.begin <= evt_begin and checktimer.end >= evt_end:
                        if checktimer.vpsplugin_enabled is None or not checktimer.vpsplugin_enabled:
                            return

                        # manuell angelegter Timer mit VPS
                        if checktimer.name == "" and checktimer.vpsplugin_time is not None:
                            checktimer.eit = neweventid
                            checktimer.name = evt.getEventName()
                            checktimer.description = evt.getShortDescription()
                            checktimer.vpsplugin_time = None
                            checktimer.log(
                                0,
                                "[VPS] changed timer (found same PDC-Time as in other VPS-recording)"
                            )
                            return

            # eigenen Timer überprüfen, wenn Zeiten nicht überschrieben werden dürfen
            if not self.timer.vpsplugin_overwrite and evt_begin <= self.timer.end:
                check_already_existing = [
                    x for (x, y) in self.next_events if y == neweventid
                ]
                if len(check_already_existing) > 0:
                    start = check_already_existing.pop()
                    if start == evt_begin:
                        return
                    else:
                        self.next_events.remove((start, neweventid))
                        self.timer.log(
                            0, "[VPS] delete event_id " + str(neweventid) +
                            " because of delay " + str(evt_begin - start))

                self.next_events.append((evt_begin, neweventid))
                self.next_events = sorted(self.next_events)
                self.timer.log(0, "[VPS] add event_id " + str(neweventid))

            else:
                newevent_data = parseEvent(evt)
                newEntry = RecordTimerEntry(ServiceReference(self.rec_ref),
                                            *newevent_data)
                newEntry.vpsplugin_enabled = True
                newEntry.vpsplugin_overwrite = True
                newEntry.dirname = self.timer.dirname
                newEntry.log(
                    0,
                    "[VPS] added this timer (found same PDC-Time as in other VPS-recording)"
                )

                # Wenn kein Timer-Konflikt auftritt, wird der Timer angelegt.
                res = NavigationInstance.instance.RecordTimer.record(newEntry)
                self.timer.log(0, "[VPS] added another timer, res " + str(res))
示例#29
0
	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 = int( time() )
		if tm <= begin:
			pass
		elif tm > begin and tm < end and repeated == 0:
			pass
		elif repeated == 0:
			return ( False, _("Illegal Parameter value for Parameter begin : '%s'") % begin )

		if 'applyMargin' in param:
			if param['applyMargin'] == "1":
				begin -= config.recording.margin_before.value * 60
				end += config.recording.margin_after.value * 60

		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", " ")

		eit = param.get("eit", None)
		if eit is None or eit.strip() == "":
			eit = 0
		else:
			try: eit = int(eit)
			except ValueError: return ( False, _("Illegal Parameter value for Parameter eit : '%s'") % eit )

		print "[WebComponents.Sources.Timer]: eit=%d" %eit
		if eit != 0:
			#check if the given event exists, if it doesn't the timer may be already running
			epgcache = eEPGCache.getInstance()
			event = epgcache.lookupEventId(eServiceReference(param['sRef']), eit)
			if event:
				eit = event.getEventId()
				#TODO add some subservice handling
			else:
				print "[WebComponents.Sources.Timer] event not found, will be ignored"

		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

		if not justplay and not config.misc.recording_allowed.value:
			return (False, _("Recording is currently disabled!"))

		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 = preferredTimerPath()
		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
								#set the new data
								timer.service_ref = service_ref
								timer.begin = begin
								timer.end = end
								timer.name = name
								timer.description = description
								timer.eit = eit
								timer.disabled = disabled
								timer.justplay = justplay
								timer.afterEvent = afterEvent
								timer.dirname = dirname
								timer.tags = tags
								timer.repeated = repeated
								timer.processRepeated()

								#sanity check
								timersanitycheck = TimerSanityCheck(self.session.nav.RecordTimer.timer_list, timer)
								conflicts = None
								if not timersanitycheck.check():
									conflicts = timersanitycheck.getSimulTimerList()
									if conflicts is not None:
										for x in conflicts:
											if x.setAutoincreaseEnd(entry):
												self.session.nav.RecordTimer.timeChanged(x)
										if not timersanitycheck.check():
											conflicts = timersanitycheck.getSimulTimerList()

								if conflicts is None:
									self.recordtimer.timeChanged(timer) #go and save it
									print "[WebComponents.Timer] editTimer: Timer changed!"
									return ( True, "Timer '%s' changed" %(timer.name) )
								else:
									print "[WebComponents.Timer] editTimer conflicting Timers: %s" %(conflicts)
									msg = ""
									for t in conflicts:
										msg = "%s / %s" %(msg, t.name)

									return (False, _("Conflicting Timer(s) detected! %s") %(msg))

			except Exception as e:
				#obviously some value was not good, return an error
				import traceback
				print traceback.format_exc()
				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, eit, 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 )
示例#30
0
    def activate(self):
        next_state = self.state + 1
        self.log(5, "activating state %d" % next_state)

        if next_state == self.StatePrepared:
            if self.tryPrepare():
                self.log(6, "prepare ok, waiting for begin")
                # create file to "reserve" the filename
                # because another recording at the same time on another service can try to record the same event
                # i.e. cable / sat.. then the second recording needs an own extension... when we create the file
                # here than calculateFilename is happy
                if not self.justplay:
                    open(self.Filename + ".ts", "w").close()
                # fine. it worked, resources are allocated.
                self.next_activation = self.begin
                self.backoff = 0
                return True

            self.log(7, "prepare failed")
            if self.first_try_prepare:
                self.first_try_prepare = False
                cur_ref = NavigationInstance.instance.getCurrentlyPlayingServiceReference(
                )
                if cur_ref and not cur_ref.getPath():
                    if not config.recording.asktozap.value:
                        self.log(8, "asking user to zap away")
                        if config.plugins.merlinEpgCenter.showTimerMessages.value:
                            self.session.openWithCallback(
                                self.failureCB,
                                MessageBox,
                                _("A timer failed to record!\nDisable TV and try again?\n"
                                  ),
                                timeout=20)
                    else:  # zap without asking
                        self.log(9, "zap without asking")
                        if config.plugins.merlinEpgCenter.showTimerMessages.value:
                            self.session.open(
                                MessageBox,
                                _("In order to record a timer, the TV was switched to the recording service!\n"
                                  ),
                                type=MessageBox.TYPE_INFO,
                                timeout=config.merlin2.
                                timeout_message_channel_switch.value)
                        self.failureCB(True)
                elif cur_ref:
                    self.log(
                        8,
                        "currently running service is not a live service.. so stop it makes no sense"
                    )
                else:
                    self.log(
                        8,
                        "currently no service running... so we dont need to stop it"
                    )
            return False
        elif next_state == self.StateRunning:
            # if this timer has been cancelled, just go to "end" state.
            if self.cancelled:
                return True

            if self.justplay:
                if Screens.Standby.inStandby:
                    self.log(11, "wakeup and zap")
                    #set service to zap after standby
                    Screens.Standby.inStandby.prev_running_service = self.service_ref.ref
                    #wakeup standby
                    Screens.Standby.inStandby.Power()
                else:
                    self.log(11, "zapping")
                    NavigationInstance.instance.playService(
                        self.service_ref.ref)
                return True
            else:
                self.log(11, "start recording")
                record_res = self.record_service.start()

                if record_res:
                    self.log(13, "start record returned %d" % record_res)
                    self.do_backoff()
                    # retry
                    self.begin = time() + self.backoff
                    return False

                return True
        elif next_state == self.StateEnded:
            old_end = self.end
            if self.setAutoincreaseEnd():
                self.log(
                    12, "autoincrase recording %d minute(s)" % int(
                        (self.end - old_end) / 60))
                self.state -= 1
                return True
            self.log(12, "stop recording")
            if not self.justplay:
                NavigationInstance.instance.stopRecordService(
                    self.record_service)
                self.record_service = None
            if self.afterEvent == AFTEREVENT.STANDBY:
                if not Screens.Standby.inStandby and config.plugins.merlinEpgCenter.showTimerMessages.value:  # not already in standby
                    self.session.openWithCallback(
                        self.sendStandbyNotification,
                        MessageBox,
                        _("A finished record timer wants to set your\nDreambox to standby. Do that now?"
                          ),
                        timeout=20)
            elif self.afterEvent == AFTEREVENT.DEEPSTANDBY:
                if not Screens.Standby.inTryQuitMainloop:  # not a shutdown messagebox is open
                    if Screens.Standby.inStandby:  # in standby
                        RecordTimerEntry.TryQuitMainloop(
                        )  # start shutdown handling without screen
                    elif config.plugins.merlinEpgCenter.showTimerMessages.value:
                        self.session.openWithCallback(
                            self.sendTryQuitMainloopNotification,
                            MessageBox,
                            _("A finished record timer wants to shut down\nyour Dreambox. Shutdown now?"
                              ),
                            timeout=20)
            return True
示例#31
0
    def finish(self, *args, **kwargs):
        if self.showPendingServicesMessageShown:
            self.msg.close()
        print("[EPGRefresh] Debug: Refresh finished!")
        if config.plugins.epgrefresh.enablemessage.value:
            Notifications.AddPopup(_("EPG refresh finished."),
                                   MessageBox.TYPE_INFO,
                                   4,
                                   ENDNOTIFICATIONID,
                                   domain=NOTIFICATIONDOMAIN)
        epgrefreshtimer.cleanup()
        self.maybeStopAdapter()
        if config.plugins.epgrefresh.epgsave.value:
            Notifications.AddPopup(_("EPG refresh save."),
                                   MessageBox.TYPE_INFO,
                                   4,
                                   ENDNOTIFICATIONID,
                                   domain=NOTIFICATIONDOMAIN)
            from enigma import eEPGCache
            myEpg = None
            myEpg = eEPGCache.getInstance()
            myEpg.save()

        force_auto_shutdown = self.session.nav.wasTimerWakeup() and \
          config.plugins.epgrefresh.afterevent.value == "auto" and \
          Screens.Standby.inStandby and config.misc.standbyCounter.value == 1 and \
          config.misc.prev_wakeup_time.value == config.plugins.epgrefresh.wakeup_time.value

        if not self.forcedScan:
            # shutdown
            if config.plugins.epgrefresh.afterevent.value == "standby" or force_auto_shutdown:
                if not Screens.Standby.inTryQuitMainloop:
                    if (not config.plugins.epgrefresh.dontshutdownonabort.value
                            and self.doStopRunningRefresh
                        ) or not self.doStopRunningRefresh:
                        self.forcedScan = False
                        if Screens.Standby.inStandby:
                            RecordTimerEntry.TryQuitMainloop()
                        else:
                            Notifications.AddNotificationWithCallback(
                                self.sendTryQuitMainloopNotification,
                                MessageBox,
                                _("EPGRefresh wants to shut down\nyour Dreambox. Shutdown now?"
                                  ),
                                timeout=10,
                                domain=NOTIFICATIONDOMAIN)
            # idle
            elif config.plugins.epgrefresh.afterevent.value == "idle":
                if not Screens.Standby.inStandby:
                    Notifications.AddNotificationWithCallback(
                        self.sendStandbyNotification,
                        MessageBox,
                        _("EPGRefresh wants to set your\nDreambox to idle. Do that now?"
                          ),
                        timeout=10,
                        domain=NOTIFICATIONDOMAIN)

        self.doStopRunningRefresh = False
        self.forcedScan = False
        self.isrunning = False
        self._nextTodo()
示例#32
0
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

    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"]

        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
        }
示例#33
0
    def parseEPG(self, simulateOnly=False):
        if NavigationInstance.instance is None:
            print "[AutoTimer] Navigation is not available, can't parse EPG"
            return (0, 0, 0, [], [])

        total = 0
        new = 0
        modified = 0
        timers = []
        conflicting = []

        self.readXml()

        # Save Recordings in a dict to speed things up a little
        # We include processed timers as we might search for duplicate descriptions
        recorddict = {}
        for timer in NavigationInstance.instance.RecordTimer.timer_list + NavigationInstance.instance.RecordTimer.processed_timers:
            recorddict.setdefault(str(timer.service_ref), []).append(timer)

        # Iterate Timer
        for timer in self.getEnabledTimerList():
            # Workaround to allow search for umlauts if we know the encoding
            match = timer.match
            if timer.encoding != 'UTF-8':
                try:
                    match = match.decode('UTF-8').encode(timer.encoding)
                except UnicodeDecodeError:
                    pass

            # Search EPG, default to empty list
            epgcache = eEPGCache.getInstance()
            ret = epgcache.search(('RI', 500, typeMap[timer.searchType], match,
                                   caseMap[timer.searchCase])) or ()

            for serviceref, eit in ret:
                eserviceref = eServiceReference(serviceref)

                evt = epgcache.lookupEventId(eserviceref, eit)
                if not evt:
                    print "[AutoTimer] Could not create Event!"
                    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()

                # Gather Information
                name = evt.getEventName()
                description = evt.getShortDescription()
                begin = evt.getBeginTime()
                duration = evt.getDuration()
                end = begin + duration

                # If event starts in less than 60 seconds skip it
                if begin < time() + 60:
                    continue

                # Convert begin time
                timestamp = localtime(begin)

                # Update timer
                timer.update(begin, timestamp)

                # Check Duration, Timespan and Excludes
                if timer.checkServices(serviceref) \
                 or timer.checkDuration(duration) \
                 or timer.checkTimespan(timestamp) \
                 or timer.checkFilter(name, description,
                  evt.getExtendedDescription(), str(timestamp.tm_wday)):
                    continue

                if timer.hasOffset():
                    # Apply custom Offset
                    begin, end = timer.applyOffset(begin, end)
                else:
                    # Apply E2 Offset
                    begin -= config.recording.margin_before.value * 60
                    end += config.recording.margin_after.value * 60

                # Eventually change service to alternative
                if timer.overrideAlternatives:
                    serviceref = timer.getAlternative(serviceref)

                total += 1

                # Append to timerlist and abort if simulating
                timers.append((name, begin, end, serviceref, timer.name))
                if simulateOnly:
                    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 recorddict.get(serviceref, ()):
                    if rtimer.eit == eit or config.plugins.autotimer.try_guessing.value and getTimeDiff(
                            rtimer, begin, end) > ((duration / 10) * 8):
                        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 hasattr(rtimer, "isAutoTimer"):
                            print "[AutoTimer] Modifying existing AutoTimer!"
                        else:
                            if config.plugins.autotimer.refresh.value != "all":
                                print "[AutoTimer] Won't modify existing timer because it's no timer set by us"
                                break

                            print "[AutoTimer] Warning, we're messing with a timer which might not have been set by us"

                        newEntry = rtimer
                        modified += 1

                        # Modify values saved in timer
                        newEntry.name = name
                        newEntry.description = description
                        newEntry.begin = int(begin)
                        newEntry.end = int(end)
                        newEntry.service_ref = ServiceReference(serviceref)

                        break
                    elif timer.avoidDuplicateDescription == 1 and not rtimer.disabled and rtimer.name == name and rtimer.description == description:
                        oldExists = True
                        print "[AutoTimer] We found a timer with same description, skipping event"
                        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
                    if timer.avoidDuplicateDescription == 2:
                        # I thinks thats the fastest way to do this, though it's a little ugly
                        try:
                            for list in recorddict.values():
                                for rtimer in list:
                                    if not rtimer.disabled and rtimer.name == name and rtimer.description == description:
                                        raise AutoTimerIgnoreTimerException(
                                            "We found a timer with same description, skipping event"
                                        )
                        except AutoTimerIgnoreTimerException, etite:
                            print etite
                            continue

                    if timer.checkCounter(timestamp):
                        continue

                    print "[AutoTimer] Adding an event."
                    newEntry = RecordTimerEntry(ServiceReference(serviceref),
                                                begin, end, name, description,
                                                eit)

                    # Mark this entry as AutoTimer (only AutoTimers will have this Attribute set)
                    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.tags = timer.tags

                if oldExists:
                    # XXX: this won't perform a sanity check, but do we actually want to do so?
                    NavigationInstance.instance.RecordTimer.timeChanged(
                        newEntry)
                else:
                    conflicts = NavigationInstance.instance.RecordTimer.record(
                        newEntry)
                    if conflicts and config.plugins.autotimer.disabled_on_conflict.value:
                        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 = NavigationInstance.instance.RecordTimer.record(
                            newEntry)
                        conflicting.append(
                            (name, begin, end, serviceref, timer.name))
                    if conflicts is None:
                        timer.decrementCounter()
                        new += 1
                        recorddict.setdefault(serviceref, []).append(newEntry)
                    else:
                        conflicting.append(
                            (name, begin, end, serviceref, timer.name))
示例#34
0
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:  # temporary due OE-A
        info['lcd'] = getLcd()
    except:  # noqa: E722
        info['lcd'] = 0
    try:  # temporary due OE-A
        info['grabpip'] = getGrabPip()
    except:  # noqa: E722
        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", "r")
        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 list(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 open(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] == "":
                        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:
                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 as 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(
                            removeBad(timer.service_ref.getServiceName()))
                        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 as error:
            info['EX'] = error

    info['timerpipzap'] = False
    info['timerautoadjust'] = False

    try:
        timer = RecordTimerEntry('', 0, 0, '', '', 0)
        if hasattr(timer, "pipzap"):
            info['timerpipzap'] = True
        if hasattr(timer, "autoadjust"):
            info['timerautoadjust'] = True
    except Exception as error:
        print("[OpenWebif] -D- RecordTimerEntry check %s" % error)

    STATICBOXINFO = info
    return info
示例#35
0
    def addTimer(
        session,
        serviceref,
        begin,
        end,
        name,
        description,
        disabled,
        justplay,
        afterevent,
        dirname,
        tags,
        repeated,
        logentries=None,
        eit=0,
    ):

        recordHandler = NavigationInstance.instance.RecordTimer

        msgTimeout = config.plugins.skyrecorder.msgtimeout.value

        if not dirname:
            try:
                dirname = config.plugins.skyrecorder.anytimefolder.value
            except Exception:
                dirname = preferredTimerPath()

        print "mao1", 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
                print "rrgggg"

            conflicts = recordHandler.record(timer)
            if conflicts:
                errors = []
                for conflict in conflicts:
                    errors.append(conflict.name)

                print "duuuupppppppeeeeee"
                return {"result": False, "message": "Conflicting Timer(s) detected! %s" % " / ".join(errors)}
        except Exception, e:
            print "adupppeee"
            print e
            return {"result": False, "message": "Could not add timer '%s'!" % name}
示例#36
0
	def standbyTimeout(self):
		from RecordTimer import RecordTimerEntry
		RecordTimerEntry.TryQuitMainloop()
示例#37
0
    def check(self):
        # Simulation ggf. stoppen
        if self.timer.state > TimerEntry.StateWaiting and self.simulate_recordService:
            self.stop_simulation()

        # VPS wurde wieder deaktiviert oder Timer wurde beendet
        if self.timer is None or self.timer.state == TimerEntry.StateEnded or self.timer.cancelled:
            self.program_abort()
            self.stop_simulation()
            return -1

        if self.timer.vpsplugin_enabled == False or config.plugins.vps.enabled.value == False:
            if self.activated_auto_increase:
                self.timer.autoincrease = False
            self.program_abort()
            self.stop_simulation()
            return -1

        self.nextExecution = 180

        if config.plugins.vps.initial_time.value < 2 and self.timer.vpsplugin_overwrite:
            initial_time = 120
        else:
            initial_time = config.plugins.vps.initial_time.value * 60

        if self.timer.vpsplugin_overwrite == True:
            if self.timer.state == TimerEntry.StateWaiting or self.timer.state == TimerEntry.StatePrepared:
                # Startzeit verschieben
                if (self.timer.begin - 60) < time():
                    if self.org_timer_begin == 0:
                        self.org_timer_begin = self.timer.begin
                    elif (self.org_timer_begin +
                          self.max_extending_timer) < time():
                        # Sendung begann immer noch nicht -> abbrechen
                        self.timer.abort()
                        self.session.nav.RecordTimer.doActivate(self.timer)
                        self.program_abort()
                        self.stop_simulation()
                        self.timer.log(
                            0,
                            "[VPS] abort timer, waited enough to find Event-ID"
                        )
                        return -1

                    self.timer.begin += 60
                    if (self.timer.end - self.timer.begin) < 300:
                        self.timer.end += 180
                        # auf Timer-Konflikt prüfen
                        timersanitycheck = TimerSanityCheck(
                            self.session.nav.RecordTimer.timer_list,
                            self.timer)
                        if not timersanitycheck.check():
                            self.timer.abort()
                            self.session.nav.RecordTimer.doActivate(self.timer)
                            self.program_abort()
                            self.stop_simulation()
                            self.timer.log(
                                0, "[VPS] abort timer due to TimerSanityCheck")
                            return -1

                    self.session.nav.RecordTimer.timeChanged(self.timer)

                if 30 < self.nextExecution:
                    self.nextExecution = 30

        # Programm starten
        if not self.program_running:
            if self.timer.state == TimerEntry.StateRunning:
                self.program_start()

            elif initial_time > 0:
                if (self.timer.begin - initial_time) <= time():
                    self.program_start()
                else:
                    n = self.timer.begin - initial_time - time()
                    if n < self.nextExecution:
                        self.nextExecution = n

        if self.timer.state == TimerEntry.StateRunning:
            if self.activated_auto_increase and self.org_timer_end != 0 and (
                    self.org_timer_end + (4 * 3600)) < time():
                # Aufnahme läuft seit 4 Stunden im Autoincrease -> abbrechen
                self.timer.autoincrease = False
                self.activated_auto_increase = False
                self.dont_restart_program = True
                self.program_abort()
                self.stop_simulation()
                self.timer.log(0,
                               "[VPS] stop recording, too much autoincrease")

            try:
                if self.timer.vpsplugin_wasTimerWakeup:
                    self.timer.vpsplugin_wasTimerWakeup = False
                    if not Screens.Standby.inTryQuitMainloop:
                        RecordTimerEntry.TryQuitMainloop(False)
            except:
                pass

        return self.nextExecution
示例#38
0
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
	}
示例#39
0
    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
                                # Let's apply the new values
                                timer.service_ref = service_ref
                                timer.begin = int(begin)
                                timer.end = int(end)
                                timer.name = name
                                timer.description = description
                                timer.disabled = disabled
                                timer.justplay = justplay
                                timer.afterEvent = afterEvent
                                timer.repeated = repeated
                                timer.dirname = dirname
                                timer.tags = tags

                                # send the changed timer back to enigma2 and hope it's good
                                self.session.nav.RecordTimer.timeChanged(timer)
                                print "[WebComponents.Timer] editTimer: Timer changed!"
                                return (True, "Timer %s has been changed!" % (timer.name))
            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
            self.recordtimer.record(timer)
            return (True, "Timer added successfully!")
        except Exception:
            # something went wrong, most possibly one of the given paramater-values was wrong
            return (False, "Could not add timer '%s'!" % name)

        return (False, "Unexpected Error")
示例#40
0
    def parseTimer(self,
                   timer,
                   epgcache,
                   serviceHandler,
                   recordHandler,
                   checkEvtLimit,
                   evtLimit,
                   timers,
                   conflicting,
                   similars,
                   timerdict,
                   moviedict,
                   simulateOnly=False):
        new = 0
        modified = 0
        skipped = 0

        # Precompute timer destination dir
        dest = timer.destination or config.usage.default_path.getValue()

        # 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 = []
            mask = (eServiceReference.isMarker | eServiceReference.isDirectory)

            casesensitive = timer.searchCase == "sensitive"
            if not casesensitive:
                match = match.lower()

            # Service filter defined
            # Search only using the specified services
            test = [(service, 0, -1, -1) for service in timer.services]

            for bouquet in timer.bouquets:
                services = serviceHandler.list(eServiceReference(bouquet))
                if not services is None:
                    while True:
                        service = services.getNext()
                        if not service.valid():  #check end of list
                            break
                        if not (service.flags & mask):
                            test.append((service.toString(), 0, -1, -1))

            if not test:
                # No service filter defined
                # Search within all services - could be very slow

                # 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.getValue():
                    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((info.getName(s), s))
                else:
                    info = serviceHandler.info(bouquetroot)
                    if info:
                        bouquetlist.append(
                            (info.getName(bouquetroot), bouquetroot))

                # Get all services
                mask = (eServiceReference.isMarker
                        | eServiceReference.isDirectory)
                for name, bouquet in bouquetlist:
                    if not bouquet.valid():  #check end of list
                        break
                    if bouquet.flags & eServiceReference.isDirectory:
                        services = serviceHandler.list(bouquet)
                        if not services is None:
                            while True:
                                service = services.getNext()
                                if not service.valid():  #check end of list
                                    break
                                if not (service.flags & mask):
                                    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)
            if not evt:
                print("[AutoTimer] Could not create Event!")
                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()

            evtBegin = begin
            evtEnd = end = begin + duration

            # 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:
                        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):
                continue

            if timer.hasOffset():
                # Apply custom Offset
                begin, end = timer.applyOffset(begin, end)
            else:
                # Apply E2 Offset
                begin -= config.recording.margin_before.getValue() * 60
                end += config.recording.margin_after.getValue() * 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:
                    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 getTimeDiff(rtimer, evtBegin, evtEnd) > (
                        (duration / 10) * 8):
                    oldExists = True

                    # Abort if we don't want to modify timers or timer is repeated
                    if config.plugins.autotimer.refresh.getValue(
                    ) == "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 -
                        (config.recording.margin_before.getValue() * 60) !=
                            rtimer.begin) or (
                                evtEnd +
                                (config.recording.margin_after.getValue() * 60)
                                != rtimer.end):
                        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."
                                % (timer.name))
                        newEntry = rtimer
                        modified += 1
                        self.modifyTimer(rtimer, name, shortdesc, begin, end,
                                         serviceref)
                        break
                    else:
                        print(
                            "[AutoTimer] Skipping timer because it has not changed."
                        )
                        skipped += 1
                        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):
                            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))

                # Mark this entry as AutoTimer (only AutoTimers will have this Attribute set)
                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
            tags = timer.tags[:]
            if config.plugins.autotimer.add_autotimer_to_tags.getValue():
                tags.append('AutoTimer')
            if config.plugins.autotimer.add_name_to_tags.getValue():
                tagname = timer.name.strip()
                if tagname:
                    tagname = tagname[0].upper() + tagname[1:].replace(
                        " ", "_")
                    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
                    newEntry.log(
                        504,
                        "[AutoTimer] Try to add similar Timer because of conflicts with %s."
                        % (conflictString))

                # Try to add timer
                conflicts = recordHandler.record(newEntry)

                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.getValue(
                    ):
                        # 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.getValue(
                    ):
                        newEntry.log(
                            503,
                            "[AutoTimer] Timer disabled because of conflicts with %s."
                            % (conflictString))
                        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, skipped)
        self.completed.append(timer.name)
        sleep(0.5)
示例#41
0
	def parseEPG(self, simulateOnly = False):
		if NavigationInstance.instance is None:
			print "[AutoTimer] Navigation is not available, can't parse EPG"
			return (0, 0, 0, [], [])

		total = 0
		new = 0
		modified = 0
		timers = []
		conflicting = []

		# NOTE: the config option specifies "the next X days" which means today (== 1) + X
		delta = timedelta(days = config.plugins.autotimer.maxdaysinfuture.value + 1)
		evtLimit = mktime((date.today() + delta).timetuple())
		checkEvtLimit = delta.days > 1
		del delta

		self.readXml()

		# Save Recordings in a dict to speed things up a little
		# We include processed timers as we might search for duplicate descriptions
		recorddict = {}
		for rtimer in NavigationInstance.instance.RecordTimer.timer_list + NavigationInstance.instance.RecordTimer.processed_timers:
			if not rtimer.disabled:
				recorddict.setdefault(str(rtimer.service_ref), []).append(rtimer)

		# Iterate Timer
		for timer in self.getEnabledTimerList():
			# 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
			if timer.encoding != 'UTF-8':
				try:
					match = match.decode('UTF-8').encode(timer.encoding)
				except UnicodeDecodeError:
					pass

			# Search EPG, default to empty list
			ret = self.epgcache.search(('RI', 500, typeMap[timer.searchType], match, caseMap[timer.searchCase])) or ()

			for serviceref, eit in ret:
				eserviceref = eServiceReference(serviceref)

				evt = self.epgcache.lookupEventId(eserviceref, eit)
				if not evt:
					print "[AutoTimer] Could not create Event!"
					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()

				# Gather Information
				evtInfo = self.normalizeEvent(evt)
				evtBegin = begin = evt.getBeginTime()
				duration = evt.getDuration()
				evtEnd = end = begin + duration

				# If event starts in less than 60 seconds skip it
				if begin < time() + 60:
					print "[AutoTimer] Skipping an event because it starts in less than 60 seconds"
					continue

				# If maximum days in future is set then check time
				if checkEvtLimit:
					if begin > evtLimit:
						continue

				# Convert begin time
				timestamp = localtime(begin)

				# Update timer
				timer.update(begin, timestamp)

				# Check Duration, Timespan, Timeframe and Excludes
				if timer.checkServices(serviceref) \
					or timer.checkDuration(duration) \
					or timer.checkTimespan(timestamp) \
					or timer.checkTimeframe(begin) \
					or timer.checkFilter(
							evtInfo.name,
							evtInfo.shortDescription,
							evtInfo.extendedDescription,
							str(timestamp.tm_wday)
						):
					continue

				if timer.hasOffset():
					# Apply custom Offset
					begin, end = timer.applyOffset(begin, end)
				else:
					# Apply E2 Offset
					begin -= config.recording.margin_before.value * 60
					end += config.recording.margin_after.value * 60

				# Eventually change service to alternative
				if timer.overrideAlternatives:
					serviceref = timer.getAlternative(serviceref)

				total += 1

				# Append to timerlist and abort if simulating
				timers.append((evtInfo.name, begin, end, serviceref, timer.name))
				if simulateOnly:
					continue


                # Check for existing recordings in directory
				if timer.avoidDuplicateDescription == 3 and self.checkMovies(evtInfo, dest):
					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 recorddict.get(serviceref, ()):
					if rtimer.eit == eit or config.plugins.autotimer.try_guessing.value and getTimeDiff(rtimer, begin, end) > ((duration/10)*8):
						oldExists = True

						# Abort if we don't want to modify timers or timer is repeated
						if config.plugins.autotimer.refresh.value == "none":
							print "[AutoTimer] Won't modify existing timer because no modification allowed"
							break
						if rtimer.repeated:
							print "[AutoTimer] Won't modify existing timer because repeated timer"
							break

						if hasattr(rtimer, "isAutoTimer"):
								rtimer.log(501, "[AutoTimer] AutoTimer %s modified this automatically generated timer." % (timer.name,))
						else:
							if config.plugins.autotimer.refresh.value != "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." % (timer.name,))

						newEntry = rtimer
						modified += 1

						# Modify values saved in timer
						newEntry.name = evtInfo.name
						newEntry.description = evtInfo.shortDescription
						newEntry.begin = int(begin)
						newEntry.end = int(end)
						newEntry.service_ref = ServiceReference(serviceref)

						break
					elif timer.avoidDuplicateDescription >= 1 and self.normalizeRecordTimer(rtimer) == evtInfo:
						oldExists = True
						print "[AutoTimer] We found a timer with same service and description, skipping event"
						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
					if timer.avoidDuplicateDescription >= 2 and self.isEventInList(evtInfo, recorddict, self.normalizeRecordTimer):
						print "[AutoTimer] We found a timer with same description, skipping event"
						continue

					if timer.checkCounter(timestamp):
						print "[AutoTimer] Not adding new timer because counter is depleted."
						continue

					newEntry = RecordTimerEntry(ServiceReference(serviceref), begin, end, evtInfo.name, evtInfo.shortDescription, eit)
					newEntry.log(500, "[AutoTimer] Adding new timer based on AutoTimer %s." % (timer.name,))

					# Mark this entry as AutoTimer (only AutoTimers will have this Attribute set)
					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.tags = timer.tags
				newEntry.vpsplugin_enabled = timer.vps_enabled
				newEntry.vpsplugin_overwrite = timer.vps_overwrite

				if oldExists:
					# XXX: this won't perform a sanity check, but do we actually want to do so?
					NavigationInstance.instance.RecordTimer.timeChanged(newEntry)
				else:
					conflicts = NavigationInstance.instance.RecordTimer.record(newEntry)
					if conflicts and config.plugins.autotimer.disabled_on_conflict.value:
						conflictString = ' / '.join(["%s (%s)" % (x.name, strftime("%Y%m%d %H%M", localtime(x.begin))) for x in conflicts])
						newEntry.log(503, "[AutoTimer] Timer disabled because of conflicts with %s." % (conflictString,))
						del conflictString
						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 = NavigationInstance.instance.RecordTimer.record(newEntry)
						conflicting.append((evtInfo.name, begin, end, serviceref, timer.name))
					if conflicts is None:
						timer.decrementCounter()
						new += 1
						recorddict.setdefault(serviceref, []).append(newEntry)
					else:
						conflicting.append((evtInfo.name, begin, end, serviceref, timer.name))

		return (total, new, modified, timers, conflicting)
示例#42
0
    def UPDT(self, args):
        # <id> <settings>
        args = args.split(None, 1)
        if len(args) != 2:
            payload = "%d argument error" % (CODE_SYNTAX, )
            return self.sendLine(payload)

        try:
            timerId = int(args[0])
        except ValueError:
            payload = "%d argument error" % (CODE_SYNTAX, )
            return self.sendLine(payload)

        list = self.getTimerList()

        if timerId < 1:
            payload = "%d argument error" % (CODE_SYNTAX, )
            return self.sendLine(payload)

        if len(list) >= timerId: oldTimer = list[timerId - 1]
        else: oldTimer = None

        try:
            flags, channelid, datestring, beginstring, endstring, priority, lifetime, name, description = args[
                1].split(':')
            flags = int(flags)
            service_ref = ServiceReference(self.channelList[int(channelid) -
                                                            1])
            datestruct = strptime(datestring, '%Y-%m-%d')
            timestruct = strptime(beginstring, '%H%M')
            begin = mktime(
                (datestruct.tm_year, datestruct.tm_mon, datestruct.tm_mday,
                 timestruct.tm_hour, timestruct.tm_min, 0, datestruct.tm_wday,
                 datestruct.tm_yday, -1))
            timestruct = strptime(endstring, '%H%M')
            end = mktime(
                (datestruct.tm_year, datestruct.tm_mon, datestruct.tm_mday,
                 timestruct.tm_hour, timestruct.tm_min, 0, datestruct.tm_wday,
                 datestruct.tm_yday, -1))
            del datestruct, timestruct
        except ValueError as e:
            payload = "%d argument error" % (CODE_SYNTAX, )
            return self.sendLine(payload)
        except KeyError as e:
            payload = "%d argument error" % (CODE_SYNTAX, )
            return self.sendLine(payload)

        if end < begin:
            end += 86400  # Add 1 day, beware - this is evil and might not work correctly due to dst
        timer = RecordTimerEntry(service_ref,
                                 begin,
                                 end,
                                 name,
                                 description,
                                 0,
                                 disabled=flags & 1 == 0)
        if oldTimer:
            recordTimer.removeEntry(oldTimer)
            timer.justplay = oldTimer.justplay
            timer.afterEvent = oldTimer.afterEvent
            timer.dirname = oldTimer.dirname
            timer.tags = oldTimer.tags
            timer.log_entries = oldTimer.log_entries

        conflict = recordTimer.record(timer)
        if conflict is None:
            return self.sendTimerLine(timer, timerId, last=True)
        else:
            payload = "%d timer conflict detected, original timer lost." % (
                CODE_ERR_LOCAL, )
            return self.sendLine(payload)
示例#43
0
	def check_and_add_event(self, neweventid):
		if not config.plugins.vps.allow_seeking_multiple_pdc.value:
			return
		
		epgcache = eEPGCache.getInstance()
		evt = epgcache.lookupEventId(self.rec_ref, neweventid)
		
		if evt:
			evt_begin = evt.getBeginTime() + 60
			evt_end = evt.getBeginTime() + evt.getDuration() - 60
			
			if evt_begin < self.timer.begin:
				return
			
			for checktimer in self.session.nav.RecordTimer.timer_list:
				if checktimer == self.timer:
					continue
				if (checktimer.begin - evt_begin) > 3600*2:
					break
				
				compareString = checktimer.service_ref.ref.toCompareString()
				if compareString == self.timer.service_ref.ref.toCompareString() or compareString == self.rec_ref.toCompareString():	
					if checktimer.eit == neweventid:
						return
					
					if checktimer.begin <= evt_begin and checktimer.end >= evt_end:
						if checktimer.vpsplugin_enabled is None or not checktimer.vpsplugin_enabled:
							return
						
						# manuell angelegter Timer mit VPS
						if checktimer.name == "" and checktimer.vpsplugin_time is not None:
							checktimer.eit = neweventid
							checktimer.name = evt.getEventName()
							checktimer.description = evt.getShortDescription()
							checktimer.vpsplugin_time = None
							checktimer.log(0, "[VPS] changed timer (found same PDC-Time as in other VPS-recording)")
							return
			
			# eigenen Timer überprüfen, wenn Zeiten nicht überschrieben werden dürfen
			if not self.timer.vpsplugin_overwrite and evt_begin <= self.timer.end:
				check_already_existing = [x for (x,y) in self.next_events if y == neweventid]
				if len(check_already_existing) > 0:
					start = check_already_existing.pop()
					if start == evt_begin:
						return
					else:
						self.next_events.remove( (start, neweventid) )
						self.timer.log(0, "[VPS] delete event_id "+ str(neweventid) +" because of delay "+ str(evt_begin - start))
					
				self.next_events.append( (evt_begin, neweventid) )
				self.next_events = sorted(self.next_events)
				self.timer.log(0, "[VPS] add event_id "+ str(neweventid))
				
			else:
				newevent_data = parseEvent(evt)
				newEntry = RecordTimerEntry(ServiceReference(self.rec_ref), *newevent_data)
				newEntry.vpsplugin_enabled = True
				newEntry.vpsplugin_overwrite = True
				newEntry.dirname = self.timer.dirname
				newEntry.log(0, "[VPS] added this timer (found same PDC-Time as in other VPS-recording)")
				
				# Wenn kein Timer-Konflikt auftritt, wird der Timer angelegt.
				res = NavigationInstance.instance.RecordTimer.record(newEntry)
				self.timer.log(0, "[VPS] added another timer, res "+ str(res))
  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 'serviceref' in param:
      param['sRef'] = str(param['serviceref'])

    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 = preferredTimerPath()
    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 )
示例#45
0
			service_ref = ServiceReference(self.channelList[int(channelid)-1])
			datestruct = strptime(datestring, '%Y-%m-%d')
			timestruct = strptime(beginstring, '%H%M')
			begin = mktime((datestruct.tm_year, datestruct.tm_mon, datestruct.tm_mday, timestruct.tm_hour, timestruct.tm_min, 0, datestruct.tm_wday, datestruct.tm_yday, -1))
			timestruct = strptime(endstring, '%H%M')
			end = mktime((datestruct.tm_year, datestruct.tm_mon, datestruct.tm_mday, timestruct.tm_hour, timestruct.tm_min, 0, datestruct.tm_wday, datestruct.tm_yday, -1))
			del datestruct, timestruct
		except ValueError, e:
			payload = "%d argument error" % (CODE_SYNTAX,)
			return self.sendLine(payload)
		except KeyError, e:
			payload = "%d argument error" % (CODE_SYNTAX,)
			return self.sendLine(payload)

		if end < begin: end += 86400 # Add 1 day, beware - this is evil and might not work correctly due to dst
		timer = RecordTimerEntry(service_ref, begin, end, name, description, 0, disabled=flags & 1 == 0)
		if oldTimer:
			recordTimer.removeEntry(oldTimer)
			timer.justplay = oldTimer.justplay
			timer.afterEvent = oldTimer.afterEvent
			timer.dirname = oldTimer.dirname
			timer.tags = oldTimer.tags
			timer.log_entries = oldTimer.log_entries

		conflict = recordTimer.record(timer)
		if conflict is None:
			return self.sendTimerLine(timer, timerId, last=True)
		else:
			payload = "%d timer conflict detected, original timer lost." % (CODE_ERR_LOCAL,)
			return self.sendLine(payload)
示例#46
0
	def parseTimer(self, timer, epgcache, serviceHandler, recordHandler, checkEvtLimit, evtLimit, timers, conflicting, similars, timerdict, moviedict, simulateOnly=False):
		new = 0
		modified = 0
		skipped = 0

		# Precompute timer destination dir
		dest = timer.destination or config.usage.default_path.value

		match = timer.match
		if timer.searchType == "description":
			epgmatches = []
			mask = (eServiceReference.isMarker | eServiceReference.isDirectory)

			casesensitive = timer.searchCase == "sensitive"
			if not casesensitive:
				match = match.lower()

			# Service filter defined
			# Search only using the specified services
			test = [(service, 0, -1, -1) for service in timer.services]

			for bouquet in timer.bouquets:
				services = serviceHandler.list(eServiceReference(bouquet))
				if not services is None:
					while True:
						service = services.getNext()
						if not service.valid(): #check end of list
							break
						if not (service.flags & mask):
							test.append( (service.toString(), 0, -1, -1 ) )

			if not test:
				# No service filter defined
				# Search within all services - could be very slow

				# 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((info.getName(s), s))
				else:
					info = serviceHandler.info(bouquetroot)
					if info:
						bouquetlist.append((info.getName(bouquetroot), bouquetroot))

				# Get all services
				mask = (eServiceReference.isMarker | eServiceReference.isDirectory)
				for name, bouquet in bouquetlist:
					if not bouquet.valid(): #check end of list
						break
					if bouquet.flags & eServiceReference.isDirectory:
						services = serviceHandler.list(bouquet)
						if not services is None:
							while True:
								service = services.getNext()
								if not service.valid(): #check end of list
									break
								if not (service.flags & mask):
									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)
			if not evt:
				print("[AutoTimer] Could not create Event!")
				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()

			evtBegin = begin
			evtEnd = end = begin + duration

			# 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:
						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):
				continue

			if timer.hasOffset():
				# Apply custom Offset
				begin, end = timer.applyOffset(begin, end)
			else:
				# Apply E2 Offset
				begin -= config.recording.margin_before.value * 60
				end += 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:
					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 getTimeDiff(rtimer, evtBegin, evtEnd) > ((duration/10)*8):
					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 - (config.recording.margin_before.getValue() * 60) != rtimer.begin) or (evtEnd + (config.recording.margin_after.getValue() * 60) != 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.")
						skipped += 1
						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 ):
							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))

				# 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
			tags = timer.tags[:]
			if config.plugins.autotimer.add_autotimer_to_tags.value:
				tags.append('AutoTimer')
			if config.plugins.autotimer.add_name_to_tags.value:
				tagname = timer.name.strip()
				if tagname:
					tagname = tagname[0].upper() + tagname[1:].replace(" ", "_")
					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
					newEntry.log(504, "[AutoTimer] Try to add similar Timer because of conflicts with %s." % (conflictString))

				# Try to add timer
				conflicts = recordHandler.record(newEntry)

				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:
						newEntry.log(503, "[AutoTimer] Timer disabled because of conflicts with %s." % (conflictString))
						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, skipped)
		self.completed.append(timer.name)
		sleep(0.5)
示例#47
0
    def timerAdd(self):
        cur = self['list'].getCurrent()
        event = cur[0]
        if event is None:
            return
        serviceref = cur[1]
        isRecordEvent = isRepeat = firstNextRepeatEvent = isRunning = False
        eventid = event.getEventId()
        begin = event.getBeginTime()
        duration = event.getDuration()
        end = begin + duration
        refstr = ':'.join(serviceref.ref.toString().split(':')[:11])
        isRepeat = False
        prev_state = 0
        for timer in self.session.nav.RecordTimer.timer_list:
            needed_ref = ':'.join(
                timer.service_ref.ref.toString().split(':')[:11]) == refstr
            if needed_ref and timer.eit == eventid and (
                    begin < timer.begin <= end
                    or timer.begin <= begin <= timer.end):
                isRecordEvent = True
                break

        if not isRecordEvent:
            x = self.session.nav.RecordTimer.isInTimer(eventid, begin,
                                                       duration, refstr, True)
            if x and x[1][0] in (2, 7, 12):
                isRecordEvent = True
                timer = x[3]
        if isRecordEvent:
            isRepeat = timer.repeated
            prev_state = timer.state
            isRunning = prev_state in (1, 2)
            title_text = isRepeat and _(
                'Attention, this is repeated timer!\n') or ''
            firstNextRepeatEvent = isRepeat and (
                begin < timer.begin <= end
                or timer.begin <= begin <= timer.end) and not timer.justplay
            menu = [(_('Delete timer'), 'delete'), (_('Edit timer'), 'edit')]
            buttons = ['red', 'green']
            if not isRunning:
                if firstNextRepeatEvent and timer.isFindRunningEvent(
                ) and not timer.isFindNextEvent():
                    menu.append((_('Options disable timer'), 'disablerepeat'))
                else:
                    menu.append((_('Disable timer'), 'disable'))
                buttons.append('yellow')
            elif prev_state == 2 and firstNextRepeatEvent:
                menu.append(
                    (_('Options disable timer'), 'disablerepeatrunning'))
                buttons.append('yellow')
            menu.append((_('Timer Overview'), 'timereditlist'))

            def timerAction(choice):
                if choice is not None:
                    if choice[1] == 'delete':
                        self.removeTimer(timer)
                    elif choice[1] == 'edit':
                        self.session.openWithCallback(self.finishedEdit,
                                                      TimerEntry, timer)
                    elif choice[1] == 'disable':
                        self.disableTimer(timer, prev_state)
                    elif choice[1] == 'timereditlist':
                        self.session.open(TimerEditList)
                    elif choice[1] == 'disablerepeatrunning':
                        self.disableTimer(timer,
                                          prev_state,
                                          repeat=True,
                                          record=True)
                    elif choice[1] == 'disablerepeat':
                        self.disableTimer(timer, prev_state, repeat=True)

            self.session.openWithCallback(
                timerAction,
                ChoiceBox,
                title=title_text +
                _("Select action for timer '%s'.") % timer.name,
                list=menu,
                keys=buttons)
        else:
            newEntry = RecordTimerEntry(serviceref,
                                        checkOldTimers=True,
                                        dirname=preferredTimerPath(),
                                        *parseEvent(event))
            self.session.openWithCallback(self.finishedAdd, TimerEntry,
                                          newEntry)
示例#48
0
	def parseTimer(self, timer, epgcache, serviceHandler, recordHandler, checkEvtLimit, evtLimit, timers, conflicting, similars, skipped, timerdict, moviedict, simulateOnly=False):
		new = 0
		modified = 0

		# Workaround to allow search for umlauts if we know the encoding
		#match = timer.match
		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 = []
			mask = (eServiceReference.isMarker | eServiceReference.isDirectory)

			casesensitive = timer.searchCase == "sensitive"
			if not casesensitive:
				match = match.lower()

			# Service filter defined
			# Search only using the specified services
			test = [(service, 0, -1, -1) for service in timer.services]

			for bouquet in timer.bouquets:
				services = serviceHandler.list(eServiceReference(bouquet))
				if not services is None:
					while True:
						service = services.getNext()
						if not service.valid(): #check end of list
							break
						if not (service.flags & mask):
							test.append( (service.toString(), 0, -1, -1 ) )

			if not test:
				# No service filter defined
				# Search within all services - could be very slow

				# Get all bouquets
				bouquetlist = []
				if config.usage.multibouquet.value:
					refstr = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.tv" ORDER BY bouquet'
					bouquetroot = eServiceReference(refstr)
					bouquets = serviceHandler.list(bouquetroot)
					if bouquets:
						while True:
							s = bouquets.getNext()
							if not s.valid():
								break
							if s.flags & eServiceReference.isDirectory and not s.flags & eServiceReference.isInvisible:
								info = serviceHandler.info(s)
								if info:
									bouquetlist.append((info.getName(s), s))
					mask = (eServiceReference.isMarker | eServiceReference.isDirectory)
					for name, bouquet in bouquetlist:
						if not bouquet.valid(): #check end of list
							break
						if bouquet.flags & eServiceReference.isDirectory:
							services = serviceHandler.list(bouquet)
							if not services is None:
								while True:
									service = services.getNext()
									if not service.valid(): #check end of list
										break
									if not (service.flags & mask):
										test.append( (service.toString(), 0, -1, -1 ) )
				else:
					service_types_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 22) || (type == 25) || (type == 31) || (type == 134) || (type == 195)'
					refstr = '%s FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet'%(service_types_tv)
					bouquetroot = eServiceReference(refstr)
					info = serviceHandler.info(bouquetroot)
					if info:
						bouquetlist.append((info.getName(bouquetroot), bouquetroot))
					mask = (eServiceReference.isMarker | eServiceReference.isDirectory)
					for name, bouquet in bouquetlist:
						if bouquet.flags & eServiceReference.isDirectory:
							services = serviceHandler.list(bouquet)
							if not services is None:
								while True:
									service = services.getNext()
									if not service.valid(): #check end of list
										break
									if not (service.flags & mask):
										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', 2500, 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
		for idx, ( serviceref, eit, name, begin, duration, shortdesc, extdesc ) in enumerate( epgmatches ):

			startLog()

			# timer destination dir
			dest = timer.destination

			evtBegin = begin
			evtEnd = end = begin + duration

			doLog("[AutoTimer] possible epgmatch %s" % (name))
			doLog("[AutoTimer] Serviceref %s" % (str(serviceref)))
			eserviceref = eServiceReference(serviceref)
			evt = epgcache.lookupEventId(eserviceref, eit)
			if not evt:
				doLog("[AutoTimer] Could not create Event!")
				skipped.append((name, begin, end, str(serviceref), timer.name, getLog()))
				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()
				doLog("[AutoTimer] Serviceref2 %s" % (str(serviceref)))


			# If event starts in less than 60 seconds skip it
			if begin < time() + 60:
				doLog("[AutoTimer] Skipping an event because it starts in less than 60 seconds")
				skipped.append((name, begin, end, serviceref, timer.name, getLog()))
				continue

			# Set short description to equal extended description if it is empty.
			if not shortdesc and timer.descShortEqualExt:
				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:
						doLog("[AutoTimer] Skipping an event because of maximum days in future is reached")
						skipped.append((name, begin, end, serviceref, timer.name, getLog()))
						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):
				doLog("[AutoTimer] Skipping an event because of check services")
				skipped.append((name, begin, end, serviceref, timer.name, getLog()))
				continue
			if timer.checkDuration(duration):
				doLog("[AutoTimer] Skipping an event because of duration check")
				skipped.append((name, begin, end, serviceref, timer.name, getLog()))
				continue
			if not similarTimer:
				if timer.checkTimespan(timestamp):
					doLog("[AutoTimer] Skipping an event because of timestamp check")
					skipped.append((name, begin, end, serviceref, timer.name, getLog()))
					continue
				if timer.checkTimeframe(begin):
					doLog("[AutoTimer] Skipping an event because of timeframe check")
					skipped.append((name, begin, end, serviceref, timer.name, getLog()))
					continue

			# Initialize
			newEntry = None
			oldEntry = None
			oldExists = False
			allow_modify = True
			newAT = None

			# Eventually change service to alternative
			if timer.overrideAlternatives:
				serviceref = timer.getAlternative(serviceref)

			if timer.series_labeling and sp_getSeasonEpisode is not None:
				allow_modify = False
				doLog("[AutoTimer SeriesPlugin] Request name, desc, path %s %s %s" % (name, shortdesc, dest))
				sp = sp_getSeasonEpisode(serviceref, name, evtBegin, evtEnd, shortdesc, dest)
				if sp and type(sp) in (tuple, list) and len(sp) == 4:
					name = sp[0] or name
					shortdesc = sp[1] or shortdesc
					dest = sp[2] or dest
					doLog(str(sp[3]))
					allow_modify = True
					doLog("[AutoTimer SeriesPlugin] Returned name, desc, path %s %s %s" % (name, shortdesc, dest))
				else:
					# Nothing found
					doLog(str(sp))
					# If AutoTimer name not equal match, do a second lookup with the name
					if timer.name.lower() != timer.match.lower():
						doLog("[AutoTimer SeriesPlugin] Request name, desc, path %s %s %s" % (timer.name, shortdesc, dest))
						sp = sp_getSeasonEpisode(serviceref, timer.name, evtBegin, evtEnd, shortdesc, dest)
						if sp and type(sp) in (tuple, list) and len(sp) == 4:
							name = sp[0] or name
							shortdesc = sp[1] or shortdesc
							dest = sp[2] or dest
							doLog(str(sp[3]))
							allow_modify = True
							doLog("[AutoTimer SeriesPlugin] Returned name, desc, path %s %s %s" % (name, shortdesc, dest))
						else:
							doLog(str(sp))

			if timer.checkFilter(name, shortdesc, extdesc, dayofweek):
				doLog("[AutoTimer] Skipping an event because of filter check")
				skipped.append((name, begin, end, serviceref, timer.name, getLog()))
				continue

			if timer.hasOffset():
				# Apply custom Offset
				begin, end = timer.applyOffset(begin, end)
			else:
				# Apply E2 Offset
				begin -= config.recording.margin_before.value * 60
				end += config.recording.margin_after.value * 60

			# Overwrite endtime if requested
			if timer.justplay and not timer.setEndtime:
				end = begin

			# 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.checkDuplicates(timer, name, movieinfo.get("name"), shortdesc, movieinfo.get("shortdesc"), extdesc, movieinfo.get("extdesc") ):
						doLog("[AutoTimer] We found a matching recorded movie, skipping event:", name)
						movieExists = True
						break
				if movieExists:
					doLog("[AutoTimer] Skipping an event because movie already exists")
					skipped.append((name, begin, end, serviceref, timer.name, getLog()))
					continue

			# 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:
					oldExists = True
					doLog("[AutoTimer] We found a timer based on eit")
					newEntry = rtimer
					oldEntry = rtimer
					break
				elif config.plugins.autotimer.try_guessing.value:
					if timer.hasOffset():
						# Remove custom Offset
						rbegin = rtimer.begin + timer.offset[0] * 60
						rend = rtimer.end - timer.offset[1] * 60
					else:
						# Remove E2 Offset
						rbegin = rtimer.begin + config.recording.margin_before.value * 60
						rend = rtimer.end - config.recording.margin_after.value * 60
					# As alternative we could also do a epg lookup
					#revent = epgcache.lookupEventId(rtimer.service_ref.ref, rtimer.eit)
					#rbegin = revent.getBeginTime() or 0
					#rduration = revent.getDuration() or 0
					#rend = rbegin + rduration or 0
					if getTimeDiff(rbegin, rend, evtBegin, evtEnd) > ((duration/10)*8) or timeSimilarityPercent(rtimer, evtBegin, evtEnd, timer) > 80:
						oldExists = True
						doLog("[AutoTimer] We found a timer based on time guessing")
						newEntry = rtimer
						oldEntry = rtimer
						break
				if timer.avoidDuplicateDescription >= 1 \
					and not rtimer.disabled:
						if self.checkDuplicates(timer, name, rtimer.name, shortdesc, rtimer.description, extdesc, rtimer.extdesc ):
						# if searchForDuplicateDescription > 1 then check short description
							oldExists = True
							doLog("[AutoTimer] We found a timer (similar service) with same description, skipping event")
							break

			# We found no timer we want to edit
			if newEntry is None:
				# But there is a match
				if oldExists:
					doLog("[AutoTimer] Skipping an event because a timer on same service exists")
					skipped.append((name, begin, end, serviceref, timer.name, getLog()))
					continue

				# We want to search for possible doubles
				if timer.avoidDuplicateDescription >= 2:
					for rtimer in chain.from_iterable( itervalues(timerdict) ):
						if not rtimer.disabled:
							if self.checkDuplicates(timer, name, rtimer.name, shortdesc, rtimer.description, extdesc, rtimer.extdesc ):
								oldExists = True
								doLog("[AutoTimer] We found a timer (any service) with same description, skipping event")
								break
					if oldExists:
						doLog("[AutoTimer] Skipping an event because a timer on any service exists")
						skipped.append((name, begin, end, serviceref, timer.name, getLog()))
						continue

				if timer.checkCounter(timestamp):
					doLog("[AutoTimer] Not adding new timer because counter is depleted.")
					skipped.append((name, begin, end, serviceref, timer.name, getLog()))
					continue
			# Append to timerlist and abort if simulating
			timers.append((name, begin, end, serviceref, timer.name, getLog()))
			if simulateOnly:
				continue

			if newEntry is not None:
				# Abort if we don't want to modify timers or timer is repeated
				if config.plugins.autotimer.refresh.value == "none" or newEntry.repeated:
					doLog("[AutoTimer] Won't modify existing timer because either no modification allowed or repeated timer")
					continue

				if "autotimer" in newEntry.flags:
					msg = "[AutoTimer] AutoTimer %s modified this automatically generated timer." % (timer.name)
					doLog(msg)
					newEntry.log(501, msg)
				else:
					if config.plugins.autotimer.refresh.value != "all":
						doLog("[AutoTimer] Won't modify existing timer because it's no timer set by us")
						continue

					msg = "[AutoTimer] Warning, AutoTimer %s messed with a timer which might not belong to it: %s ." % (timer.name, newEntry.name)
					doLog(msg)
					newEntry.log(501, msg)

				if allow_modify:
					if self.modifyTimer(newEntry, name, shortdesc, begin, end, serviceref, eit, base_timer=timer):
						msg = "[AutoTimer] AutoTimer modified timer: %s ." % (newEntry.name)
						doLog(msg)
						newEntry.log(501, msg)
						modified += 1
					else:
						msg = "[AutoTimer] AutoTimer modification not allowed for timer %s because conflicts or double timer." % (newEntry.name)
						doLog(msg)
						if oldEntry:
							self.setOldTimer(newEntry, oldEntry)
							doLog("[AutoTimer] conflict for modification timer %s detected return to old timer" % (newEntry.name))
						continue
				else:
					msg = "[AutoTimer] AutoTimer modification not allowed for timer: %s ." % (newEntry.name)
					doLog(msg)
					continue
			else:
				newEntry = RecordTimerEntry(ServiceReference(serviceref), begin, end, name, shortdesc, eit)
				newAT = True

				msg = "[AutoTimer] Try to add new timer based on AutoTimer %s." % (timer.name)
				doLog(msg)
				newEntry.log(500, msg)

				# Mark this entry as AutoTimer
				newEntry.flags.add("autotimer")

			# 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 = dest
			newEntry.calculateFilename()
			newEntry.justplay = timer.justplay
			newEntry.vpsplugin_enabled = timer.vps_enabled
			newEntry.vpsplugin_overwrite = timer.vps_overwrite
			newEntry.conflict_detection = timer.conflict_detection
			newEntry.always_zap = timer.always_zap
			newEntry.zap_wakeup = timer.zap_wakeup

			tags = timer.tags[:]
			if config.plugins.autotimer.add_autotimer_to_tags.value:
				if 'AutoTimer' not in tags:
					tags.append('AutoTimer')
			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 and newAT is None:
				if self.isResolvedConflict(newEntry):
					recordHandler.timeChanged(newEntry)
				else:
					if oldEntry:
						self.setOldTimer(newEntry, oldEntry)
						doLog("[AutoTimer] rechecking - conflict for timer %s detected return to old timer" % (newEntry.name))
					continue
			elif newAT:
				newAT = newEntry
				conflictString = ""
				if similarTimer:
					conflictString = similardict[eit].conflictString
					msg = "[AutoTimer] Try to add similar Timer because of conflicts with %s." % (conflictString)
					doLog(msg)
					newEntry.log(504, msg)

				# add new timer in AT timer list
				atDoubleTimer = False
				refstr = ':'.join(newEntry.service_ref.ref.toString().split(':')[:11])
				for at in addNewTimers:
					needed_ref = ':'.join(at.service_ref.ref.toString().split(':')[:11]) == refstr
					if needed_ref and at.eit == newEntry.eit and (newEntry.begin < at.begin <= newEntry.end or at.begin <= newEntry.begin <= at.end):
						atDoubleTimer = True
						break
				if atDoubleTimer:
					doLog("[AutoTimer] ignore double new auto timer %s." % newEntry.name)
					continue
				else:
					addNewTimers.append(newEntry)

				# Try to add timer
				conflicts = recordHandler.record(newEntry)

				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])
					doLog("[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.checkDuplicates(timer, name, nameS, shortdesc, shortdescS, extdesc, extdescS, force=True ):
								# Check if the similar is already known
								if eitS not in similardict:
									doLog("[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()
					if newEntry in (recordHandler.timer_list[:] + recordHandler.processed_timers[:]):
						new += 1
						newEntry.extdesc = extdesc
						timerdict[serviceref].append(newEntry)

						# 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()
					else:
						doLog("[AutoTimer] ignore double timer %s." % newEntry.name)

				# 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)
						doLog(msg)
						newEntry.log(503, msg)
						newEntry.disabled = True
						if newEntry in (recordHandler.timer_list[:] + recordHandler.processed_timers[:]):
							recordHandler.timeChanged(newEntry)
						else:
							# 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)
					elif newAT != newEntry and newEntry in (recordHandler.timer_list[:] + recordHandler.processed_timers[:]):
						if not self.isResolvedConflict(newEntry):
							newEntry.disabled = True
							recordHandler.timeChanged(newEntry)
							doLog("[AutoTimer] Unknown conflict, disable this timer %s." % newEntry.name)

		return (new, modified)
	def addTimer(serviceref, begin, end, name, description, eit, disabled, dirname, vpsSettings, tags, logentries=None):

		recordHandler = NavigationInstance.instance.RecordTimer
		# config.plugins.serienRec.seriensubdir
		# if not dirname:
		#	try:
		#		dirname = config.plugins.serienRec.savetopath.value
		#	except Exception:
		#		dirname = preferredTimerPath()
		try:
			try:
				timer = RecordTimerEntry(
					ServiceReference(serviceref),
					begin,
					end,
					name,
					description,
					eit,
					disabled=disabled,
					justplay=config.plugins.serienRec.justplay.value,
					zapbeforerecord=config.plugins.serienRec.zapbeforerecord.value,
					justremind=config.plugins.serienRec.justremind.value,
					afterEvent=int(config.plugins.serienRec.afterEvent.value),
					dirname=dirname)
			except Exception:
				sys.exc_clear()

				timer = RecordTimerEntry(
					ServiceReference(serviceref),
					begin,
					end,
					name,
					description,
					eit,
					disabled,
					config.plugins.serienRec.justplay.value | config.plugins.serienRec.justremind.value,
					afterEvent=int(config.plugins.serienRec.afterEvent.value),
					dirname=dirname,
					tags=None)

			timer.repeated = 0

			# Add tags
			timerTags = timer.tags[:]
			timerTags.append('SerienRecorder')
			if len(tags) != 0:
				timerTags.extend(tags)
			timer.tags = timerTags

			# If eit = 0 the VPS plugin won't work properly for this timer, so we have to disable VPS in this case.
			if SerienRecorder.VPSPluginAvailable and eit is not 0:
				timer.vpsplugin_enabled = vpsSettings[0]
				timer.vpsplugin_overwrite = timer.vpsplugin_enabled and (not vpsSettings[1])

			if logentries:
				timer.log_entries = logentries

			timer.log(0, "[SerienRecorder] Timer angelegt")

			conflicts = recordHandler.record(timer)
			if conflicts:
				errors = []
				for conflict in conflicts:
					errors.append(conflict.name)

				return {
					"result": False,
					"message": "In Konflikt stehende Timer vorhanden! %s" % " / ".join(errors)
				}
		except Exception, e:
			print "[%s] <%s>" % (__name__, e)
			return {
				"result": False,
				"message": "Timer konnte nicht angelegt werden '%s'!" % e
			}
示例#50
0
	def parseTimer(self, timer, epgcache, serviceHandler, recordHandler, checkEvtLimit, evtLimit, timers, conflicting, similars, skipped, timerdict, moviedict, simulateOnly=False):
		new = 0
		modified = 0

		# Search EPG, default to empty list
		epgmatches = epgcache.search( ('RITBDSE', 1000, typeMap[timer.searchType], timer.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
		for idx, ( serviceref, eit, name, begin, duration, shortdesc, extdesc ) in enumerate( epgmatches ):
			
			startLog()
			
			# timer destination dir
			dest = timer.destination or config.usage.default_path.value
			
			evtBegin = begin
			evtEnd = end = begin + duration

			doLog("possible epgmatch %s" % (name))
			doLog("Serviceref %s" % (str(serviceref)))
			eserviceref = eServiceReference(serviceref)
			evt = epgcache.lookupEventId(eserviceref, eit)
			if not evt:
				doLog("Could not create Event!")
				skipped.append((name, begin, end, str(serviceref), timer.name, getLog()))
				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()
				doLog("Serviceref2 %s" % (str(serviceref)))

			# If event starts in less than 60 seconds skip it
			if begin < time() + 60:
				doLog("Skipping an event because it starts in less than 60 seconds")
				skipped.append((name, begin, end, serviceref, timer.name, getLog()))
				continue

			# 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:
						doLog("Skipping an event because of maximum days in future is reached")
						skipped.append((name, begin, end, serviceref, timer.name, getLog()))
						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):
				doLog("Skipping an event because of check services")
				skipped.append((name, begin, end, serviceref, timer.name, getLog()))
				continue
			if timer.checkDuration(duration):
				doLog("Skipping an event because of duration check")
				skipped.append((name, begin, end, serviceref, timer.name, getLog()))
				continue
			if not similarTimer:
				if timer.checkTimespan(timestamp):
					doLog("Skipping an event because of timestamp check")
					skipped.append((name, begin, end, serviceref, timer.name, getLog()))
					continue
				if timer.checkTimeframe(begin):
					doLog("Skipping an event because of timeframe check")
					skipped.append((name, begin, end, serviceref, timer.name, getLog()))
					continue

			# Initialize
			newEntry = None
			oldExists = False
			allow_modify = True
			
			# Eventually change service to alternative
			if timer.overrideAlternatives:
				serviceref = timer.getAlternative(serviceref)

			if timer.series_labeling and sp_getSeasonEpisode is not None:
				allow_modify = False
				#doLog("Request name, desc, path %s %s %s" % (name,shortdesc,dest))
				sp = sp_getSeasonEpisode(serviceref, name, evtBegin, evtEnd, shortdesc, dest)
				if sp and type(sp) in (tuple, list) and len(sp) == 4:
					name = sp[0] or name
					shortdesc = sp[1] or shortdesc
					dest = sp[2] or dest
					doLog(str(sp[3]))
					#doLog("Returned name, desc, path %s %s %s" % (name,shortdesc,dest))
					allow_modify = True
				else:
					# Nothing found
					doLog(str(sp))
					
					# If AutoTimer name not equal match, do a second lookup with the name
					if timer.name.lower() != timer.match.lower():
						#doLog("Request name, desc, path %s %s %s" % (timer.name,shortdesc,dest))
						sp = sp_getSeasonEpisode(serviceref, timer.name, evtBegin, evtEnd, shortdesc, dest)
						if sp and type(sp) in (tuple, list) and len(sp) == 4:
							name = sp[0] or name
							shortdesc = sp[1] or shortdesc
							dest = sp[2] or dest
							doLog(str(sp[3]))
							#doLog("Returned name, desc, path %s %s %s" % (name,shortdesc,dest))
							allow_modify = True
						else:
							doLog(str(sp))

			if timer.checkFilter(name, shortdesc, extdesc, dayofweek):
				doLog("Skipping an event because of filter check")
				skipped.append((name, begin, end, serviceref, timer.name, getLog()))
				continue
			
			if timer.hasOffset():
				# Apply custom Offset
				begin, end = timer.applyOffset(begin, end)
			else:
				# Apply E2 Offset
				if ServiceRecordingSettings:
					begin -= ServiceRecordingSettings.instance.getMarginBefore(eserviceref)
					end += ServiceRecordingSettings.instance.getMarginAfter(eserviceref)
				else:
					begin -= config.recording.margin_before.value * 60
					end += config.recording.margin_after.value * 60

			# Overwrite endtime if requested
			if timer.justplay and not timer.setEndtime:
				end = begin

			# 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.checkDuplicates(timer, name, movieinfo.get("name"), shortdesc, movieinfo.get("shortdesc"), extdesc, movieinfo.get("extdesc") ):
						doLog("We found a matching recorded movie, skipping event:", name)
						movieExists = True
						break
				if movieExists:
					doLog("Skipping an event because movie already exists")
					skipped.append((name, begin, end, serviceref, timer.name, getLog()))
					continue

			# 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:
					oldExists = True
					doLog("We found a timer based on eit")
					newEntry = rtimer
					break
				elif config.plugins.autotimer.try_guessing.value:
					if timer.hasOffset():
						# Remove custom Offset
						rbegin = rtimer.begin + timer.offset[0] * 60
						rend = rtimer.end - timer.offset[1] * 60
					else:
						# Remove E2 Offset
						rbegin = rtimer.begin + config.recording.margin_before.value * 60
						rend = rtimer.end - config.recording.margin_after.value * 60
					# As alternative we could also do a epg lookup
					#revent = epgcache.lookupEventId(rtimer.service_ref.ref, rtimer.eit)
					#rbegin = revent.getBeginTime() or 0
					#rduration = revent.getDuration() or 0
					#rend = rbegin + rduration or 0
					if getTimeDiff(rbegin, rend, evtBegin, evtEnd) > ((duration/10)*8):
						oldExists = True
						doLog("We found a timer based on time guessing")
						newEntry = rtimer
						break
				if timer.avoidDuplicateDescription >= 1 \
					and not rtimer.disabled:
						if self.checkDuplicates(timer, name, rtimer.name, shortdesc, rtimer.description, extdesc, rtimer.extdesc ):
						# if searchForDuplicateDescription > 1 then check short description
							oldExists = True
							doLog("We found a timer (similar service) with same description, skipping event")
							break

			# We found no timer we want to edit
			if newEntry is None:
				# But there is a match
				if oldExists:
					doLog("Skipping an event because a timer on same service exists")
					skipped.append((name, begin, end, serviceref, timer.name, getLog()))
					continue

				# We want to search for possible doubles
				if timer.avoidDuplicateDescription >= 2:
					for rtimer in chain.from_iterable( itervalues(timerdict) ):
						if not rtimer.disabled:
							if self.checkDuplicates(timer, name, rtimer.name, shortdesc, rtimer.description, extdesc, rtimer.extdesc ):
								oldExists = True
								doLog("We found a timer (any service) with same description, skipping event")
								break
					if oldExists:
						doLog("Skipping an event because a timer on any service exists")
						skipped.append((name, begin, end, serviceref, timer.name, getLog()))
						continue

				if timer.checkCounter(timestamp):
					doLog("Not adding new timer because counter is depleted.")
					skipped.append((name, begin, end, serviceref, timer.name, getLog()))
					continue

			# Append to timerlist and abort if simulating
			timers.append((name, begin, end, serviceref, timer.name, getLog()))
			if simulateOnly:
				continue

			if newEntry is not None:
				# Abort if we don't want to modify timers or timer is repeated
				if config.plugins.autotimer.refresh.value == "none" or newEntry.repeated:
					doLog("Won't modify existing timer because either no modification allowed or repeated timer")
					continue

				if hasattr(newEntry, "isAutoTimer"):
					msg = "[AutoTimer] AutoTimer %s modified this automatically generated timer." % (timer.name)
					doLog(msg)
					newEntry.log(501, msg)
				elif config.plugins.autotimer.add_autotimer_to_tags.value and TAG in newEntry.tags:
					msg = "[AutoTimer] AutoTimer %s modified this automatically generated timer." % (timer.name)
					doLog(msg)
					newEntry.log(501, msg)
				else:
					if config.plugins.autotimer.refresh.value != "all":
						doLog("Won't modify existing timer because it's no timer set by us")
						continue

					msg = "[AutoTimer] Warning, AutoTimer %s messed with a timer which might not belong to it: %s ." % (timer.name, newEntry.name)
					doLog(msg)
					newEntry.log(501, msg)

				modified += 1

				if allow_modify:
					self.modifyTimer(newEntry, name, shortdesc, begin, end, serviceref, eit)
					msg = "[AutoTimer] AutoTimer modified timer: %s ." % (newEntry.name)
					doLog(msg)
					newEntry.log(501, msg)
				else:
					msg = "[AutoTimer] AutoTimer modification not allowed for timer: %s ." % (newEntry.name)
					doLog(msg)
			else:
				newEntry = RecordTimerEntry(ServiceReference(serviceref), begin, end, name, shortdesc, eit)
				msg = "[AutoTimer] Try to add new timer based on AutoTimer %s." % (timer.name)
				doLog(msg)
				newEntry.log(500, msg)
				
				# 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 = dest
			newEntry.calculateFilename()

			newEntry.justplay = timer.justplay
			newEntry.vpsplugin_enabled = timer.vps_enabled
			newEntry.vpsplugin_overwrite = timer.vps_overwrite
			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)

			else:
				conflictString = ""
				if similarTimer:
					conflictString = similardict[eit].conflictString
					msg = "[AutoTimer] Try to add similar Timer because of conflicts with %s." % (conflictString)
					doLog(msg)
					newEntry.log(504, msg)

				# Try to add timer
				conflicts = recordHandler.record(newEntry)

				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])
					doLog("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.checkDuplicates(timer, name, nameS, shortdesc, shortdescS, extdesc, extdescS, force=True ):
								# Check if the similar is already known
								if eitS not in similardict:
									doLog("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)

					# 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)
						doLog(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)
		
		return (new, modified)
    def getTimers(self):
        self._timer_list = []
        self._processed_timers = []

        baseurl = self.getBaseUrl()

        print("[ClientModeBoxRemoteTimer] get remote timer list")

        try:
            httprequest = urllib2.urlopen(baseurl + '/web/timerlist')
            xmldoc = minidom.parseString(httprequest.read())
            timers = xmldoc.getElementsByTagName('e2timer')
            for timer in timers:
                serviceref = ServiceReference(
                    getValueFromNode(timer, 'e2servicereference'))
                begin = int(getValueFromNode(timer, 'e2timebegin'))
                end = int(getValueFromNode(timer, 'e2timeend'))
                name = getValueFromNode(timer, 'e2name')
                description = getValueFromNode(timer, 'e2description')
                eit = int(getValueFromNode(timer, 'e2eit'))
                disabled = int(getValueFromNode(timer, 'e2disabled'))
                justplay = int(getValueFromNode(timer, 'e2justplay'))
                afterevent = int(getValueFromNode(timer, 'e2afterevent'))
                repeated = int(getValueFromNode(timer, 'e2repeated'))
                location = getValueFromNode(timer, 'e2location')
                tags = getValueFromNode(timer, 'e2tags').split(" ")

                entry = RecordTimerEntry(serviceref,
                                         begin,
                                         end,
                                         name,
                                         description,
                                         eit,
                                         disabled,
                                         justplay,
                                         afterevent,
                                         dirname=location,
                                         tags=tags,
                                         descramble=1,
                                         record_ecm=0,
                                         isAutoTimer=0,
                                         always_zap=0)
                entry.repeated = repeated

                entry.orig = RecordTimerEntry(serviceref,
                                              begin,
                                              end,
                                              name,
                                              description,
                                              eit,
                                              disabled,
                                              justplay,
                                              afterevent,
                                              dirname=location,
                                              tags=tags,
                                              descramble=1,
                                              record_ecm=0,
                                              isAutoTimer=0,
                                              always_zap=0)
                entry.orig.repeated = repeated

                if entry.shouldSkip(
                ) or entry.state == TimerEntry.StateEnded or (
                        entry.state == TimerEntry.StateWaiting
                        and entry.disabled):
                    insort(self._processed_timers, entry)
                else:
                    insort(self._timer_list, entry)
        except Exception as e:
            print("[ClientModeBoxRemoteTimer]", e)

        self.last_update_ts = time()
示例#52
0
class vps_timer:
	def __init__(self, timer, session):
		self.timer = timer
		self.session = session
		self.program = eConsoleAppContainer()
		self.dataAvail_conn = self.program.dataAvail.connect(self.program_dataAvail)
		self.appClosed_conn = self.program.appClosed.connect(self.program_closed)
		self.program_running = False
		self.program_try_search_running = False
		self.activated_auto_increase = False
		self.simulate_recordService = None
		self.demux = -1
		self.rec_ref = None
		self.found_pdc = False
		self.dont_restart_program = False
		self.org_timer_end = 0
		self.org_timer_begin = 0
		self.max_extending_timer = 4*3600
		self.next_events = [ ]
		self.new_timer_copy = None
		self.pausing = False
	
	
	def program_closed(self, retval):
		self.timer.log(0, "[VPS] stop monitoring (process terminated)")
		if self.program_running or self.program_try_search_running:
			self.program_running = False
			self.program_try_search_running = False
			self.stop_simulation()
	
	def program_dataAvail(self, str):
		if self.timer is None or self.timer.state == TimerEntry.StateEnded or self.timer.cancelled:
			self.program_abort()
			self.stop_simulation()
			return
		if self.timer.vpsplugin_enabled == False or config.plugins.vps.enabled.value == False:
			if self.activated_auto_increase:
				self.timer.autoincrease = False
			self.program_abort()
			self.stop_simulation()
			return
		
		lines = str.split("\n")
		for line in lines:
			data = line.split()
			if len(data) == 0:
				continue
			
			self.timer.log(0, "[VPS] " + line)
			
			if data[0] == "RUNNING_STATUS":
				if data[1] == "0": # undefined
					if data[2] == "FOLLOWING":
						data[1] = "1"
					else:
						data[1] = "4"
				
				if data[1] == "1": # not running
					# Wenn der Eintrag im Following (Section_Number = 1) ist,
					# dann nicht beenden (Sendung begann noch gar nicht)
					if data[2] == "FOLLOWING":
						self.activate_autoincrease()
					elif self.timer.state == TimerEntry.StateRunning and not self.pausing and not self.set_next_event():
						self.stop_recording()
						self.dont_restart_program = True
						self.program_abort()
				
				elif data[1] == "2": # starts in a few seconds
					self.activate_autoincrease()
					if self.timer.state == TimerEntry.StateWaiting:
						self.session.nav.RecordTimer.doActivate(self.timer)
				
				elif data[1] == "3": # pausing
					self.pausing = True
					if self.timer.state == TimerEntry.StateRunning:
						self.activate_autoincrease()
				
				elif data[1] == "4": # running
					self.pausing = False
					if self.timer.state == TimerEntry.StateRunning:
						self.activate_autoincrease()
					elif self.timer.state == TimerEntry.StateWaiting or self.timer.state == TimerEntry.StatePrepared:
						# setze Startzeit auf jetzt
						self.timer.begin = int(time())
						self.session.nav.RecordTimer.timeChanged(self.timer)
						
						self.activate_autoincrease()
						self.program_abort()
						self.stop_simulation()
						vps_timers.checksoon(2000) # Programm neu starten
				
				elif data[1] == "5": # service off-air
					self.timer.vpsplugin_overwrite = False
					if self.activated_auto_increase:
						self.timer.autoincrease = False
						self.activated_auto_increase = False
			
			
			elif data[0] == "EVENT_ENDED":
				if not self.set_next_event():
					if self.timer.state == TimerEntry.StateRunning:
						self.stop_recording()
					
					self.program_abort()
					self.stop_simulation()
			
			
			elif data[0] == "OTHER_TS_RUNNING_STATUS":
				if self.timer.state == TimerEntry.StateWaiting:
					self.timer.start_prepare = int(time())
					self.session.nav.RecordTimer.doActivate(self.timer)
				
				self.program_abort()
				self.stop_simulation()
				vps_timers.checksoon(2000)
			
			
			# PDC
			elif data[0] == "PDC_FOUND_EVENT_ID":
				self.found_pdc = True
				self.timer.eit = int(data[1])
				epgcache = eEPGCache.getInstance()
				evt = epgcache.lookupEventId(self.rec_ref, self.timer.eit)
				if evt:
					self.timer.name = evt.getEventName()
					self.timer.description = evt.getShortDescription()
				self.program_abort()
				vps_timers.checksoon(500)
			
			
			elif data[0] == "FOUND_EVENT_ON_SCHEDULE":
				starttime = int(data[1])
				duration = int(data[2])
				# Soll die Sendung laut EPG erst nach dem Ende dieses Timers beginnen?
				if (not self.timer.vpsplugin_overwrite and (self.timer.end + 300) < starttime) or (self.timer.vpsplugin_overwrite and (self.timer.end + self.max_extending_timer - 1800) < starttime):
					if self.new_timer_copy is None:
						if self.activated_auto_increase:
							self.timer.autoincrease = False
							self.activated_auto_increase = False
						self.copyTimer(starttime, duration)
						self.timer.log(0, "[VPS] copied this timer, since the event may start later than this timer ends")
				
				elif not self.activated_auto_increase:
					self.activate_autoincrease()
			
			
			elif data[0] == "EVENT_OVER" or data[0] == "CANNOT_FIND_EVENT":
				self.max_extending_timer = 2*3600
				if self.activated_auto_increase:
					self.timer.autoincrease = False
					self.activated_auto_increase = False
			
			
			elif data[0] == "PDC_MULTIPLE_FOUND_EVENT":
				self.check_and_add_event(int(data[1]))
			
			
			# Programm meldet, dass die EIT (present/following) des Senders offenbar
			# momentan fehlerhaft ist
			elif data[0] == "EIT_APPARENTLY_UNRELIABLE":
				if self.timer.vpsplugin_overwrite:
					self.timer.vpsplugin_overwrite = False
					self.timer.log(0, "[VPS] can't trust EPG currently, go to safe mode")


	def stop_recording(self):
		self.activated_auto_increase = False
		self.timer.autoincrease = False
		
		if self.timer.vpsplugin_overwrite:
			# Stopp nach margin_after seconds
			if config.plugins.vps.margin_after.value == 0:
				self.timer.abort()
				self.session.nav.RecordTimer.doActivate(self.timer)
			else:
				self.timer.end = int(time()) + config.plugins.vps.margin_after.value
				self.session.nav.RecordTimer.timeChanged(self.timer)
			self.stop_simulation()
		else:
			new_end_time = int(time()) + config.plugins.vps.margin_after.value
			if new_end_time > self.timer.end:
				self.timer.end = new_end_time
				self.session.nav.RecordTimer.timeChanged(self.timer)
	
	def activate_autoincrease(self):
		if not self.activated_auto_increase:
			self.activated_auto_increase = True
			self.timer.autoincrease = True
			self.timer.autoincreasetime = 60
			
			if self.org_timer_end == 0:
				self.org_timer_end = self.timer.end
			self.timer.log(0, "[VPS] enable autoincrease")
			
			if self.new_timer_copy is not None and (self.new_timer_copy in self.session.nav.RecordTimer.timer_list):
				self.new_timer_copy.afterEvent = AFTEREVENT.NONE
				self.new_timer_copy.dontSave = True
				NavigationInstance.instance.RecordTimer.removeEntry(self.new_timer_copy)
				self.new_timer_copy = None
				self.timer.log(0, "[VPS] delete timer copy")
	
	# Noch ein Event aufnehmen?
	def set_next_event(self):
		if not self.timer.vpsplugin_overwrite and len(self.next_events) > 0:
			if not self.activated_auto_increase:
				self.activate_autoincrease()
			
			(starttime, neweventid) = self.next_events.pop(0)
			self.timer.eit = neweventid
			self.dont_restart_program = False
			self.program_abort()
			self.timer.log(0, "[VPS] record now event_id "+ str(neweventid))
			vps_timers.checksoon(3000)
			return True
		else:
			return False
	
	def program_abort(self):
		if self.program_running or self.program_try_search_running:
			#self.program.sendCtrlC()
			self.program.kill()
			self.program_running = False
			self.program_try_search_running = False
			self.timer.log(0, "[VPS] stop monitoring")
	
	def stop_simulation(self):
		if self.simulate_recordService:
			NavigationInstance.instance.stopRecordService(self.simulate_recordService)
			self.simulate_recordService = None
			self.timer.log(0, "[VPS] stop RecordService (simulation)")
	
	
	def check_and_add_event(self, neweventid):
		if not config.plugins.vps.allow_seeking_multiple_pdc.value:
			return
		
		epgcache = eEPGCache.getInstance()
		evt = epgcache.lookupEventId(self.rec_ref, neweventid)
		
		if evt:
			evt_begin = evt.getBeginTime() + 60
			evt_end = evt.getBeginTime() + evt.getDuration() - 60
			
			if evt_begin < self.timer.begin:
				return
			
			for checktimer in self.session.nav.RecordTimer.timer_list:
				if checktimer == self.timer:
					continue
				if (checktimer.begin - evt_begin) > 3600*2:
					break
				
				compareString = checktimer.service_ref.ref.toCompareString()
				if compareString == self.timer.service_ref.ref.toCompareString() or compareString == self.rec_ref.toCompareString():	
					if checktimer.eit == neweventid:
						return
					
					if checktimer.begin <= evt_begin and checktimer.end >= evt_end:
						if checktimer.vpsplugin_enabled is None or not checktimer.vpsplugin_enabled:
							return
						
						# manuell angelegter Timer mit VPS
						if checktimer.name == "" and checktimer.vpsplugin_time is not None:
							checktimer.eit = neweventid
							checktimer.name = evt.getEventName()
							checktimer.description = evt.getShortDescription()
							checktimer.vpsplugin_time = None
							checktimer.log(0, "[VPS] changed timer (found same PDC-Time as in other VPS-recording)")
							return
			
			# eigenen Timer überprüfen, wenn Zeiten nicht überschrieben werden dürfen
			if not self.timer.vpsplugin_overwrite and evt_begin <= self.timer.end:
				check_already_existing = [x for (x,y) in self.next_events if y == neweventid]
				if len(check_already_existing) > 0:
					start = check_already_existing.pop()
					if start == evt_begin:
						return
					else:
						self.next_events.remove( (start, neweventid) )
						self.timer.log(0, "[VPS] delete event_id "+ str(neweventid) +" because of delay "+ str(evt_begin - start))
					
				self.next_events.append( (evt_begin, neweventid) )
				self.next_events = sorted(self.next_events)
				self.timer.log(0, "[VPS] add event_id "+ str(neweventid))
				
			else:
				newevent_data = parseEvent(evt)
				newEntry = RecordTimerEntry(ServiceReference(self.rec_ref), *newevent_data)
				newEntry.vpsplugin_enabled = True
				newEntry.vpsplugin_overwrite = True
				newEntry.dirname = self.timer.dirname
				newEntry.log(0, "[VPS] added this timer (found same PDC-Time as in other VPS-recording)")
				
				# Wenn kein Timer-Konflikt auftritt, wird der Timer angelegt.
				res = NavigationInstance.instance.RecordTimer.record(newEntry)
				self.timer.log(0, "[VPS] added another timer, res "+ str(res))
	
	
	def copyTimer(self, start, duration):
		starttime = start - config.recording.margin_before.value * 60
		endtime = start + duration + config.recording.margin_after.value * 60
		self.new_timer_copy = RecordTimerEntry(ServiceReference(self.rec_ref), starttime, endtime, self.timer.name, self.timer.description, self.timer.eit, False, False, AFTEREVENT.AUTO, False, self.timer.dirname, self.timer.tags)
		self.new_timer_copy.vpsplugin_enabled = True
		self.new_timer_copy.vpsplugin_overwrite = self.timer.vpsplugin_overwrite
		self.new_timer_copy.log(0, "[VPS] added this timer")
		NavigationInstance.instance.RecordTimer.record(self.new_timer_copy)
		
	
	# startet den Hintergrundprozess
	def program_do_start(self, mode):
		if self.program_running or self.program_try_search_running:
			self.program_abort()
		
		if mode == 1:
			self.demux = -1
			current_service = NavigationInstance.instance.getCurrentService()
			if current_service:
				stream = current_service.stream()
				if stream:
					streamdata = stream.getStreamingData()
					if (streamdata and ('demux' in streamdata)):
						self.demux = streamdata['demux']
			if self.demux == -1:
				return;
			
			self.program_try_search_running = True
			self.program_running = False
			mode_program = 1
		else:
			self.program_try_search_running = False
			self.program_running = True
			mode_program = 0
		
		sid = self.rec_ref.getData(1)
		tsid = self.rec_ref.getData(2)
		onid = self.rec_ref.getData(3)
		demux = "/dev/dvb/adapter0/demux" + str(self.demux)
		
		# PDC-Zeit?
		if (self.timer.name == "" or self.timer.eit is None) and self.timer.vpsplugin_time is not None and not self.found_pdc:
			mode_program += 2
			day = strftime("%d", localtime(self.timer.vpsplugin_time))
			month = strftime("%m", localtime(self.timer.vpsplugin_time))
			hour = strftime("%H", localtime(self.timer.vpsplugin_time))
			minute = strftime("%M", localtime(self.timer.vpsplugin_time))
			cmd = vps_exe + " "+ demux +" "+ str(mode_program) +" "+ str(onid) +" "+ str(tsid) +" "+ str(sid) +" 0 "+ day +" "+ month +" "+ hour +" "+ minute
			self.timer.log(0, "[VPS] seek PDC-Time")
			self.program.execute(cmd)
			return
		
		cmd = vps_exe + " "+ demux +" "+ str(mode_program) +" "+ str(onid) +" "+ str(tsid) +" "+ str(sid) +" "+ str(self.timer.eit)
		self.timer.log(0, "[VPS] start monitoring running-status")
		self.program.execute(cmd)
	
	
	def program_start(self):
		self.demux = -1
		
		if self.dont_restart_program:
			return
		
		self.rec_ref = self.timer.service_ref and self.timer.service_ref.ref
		if self.rec_ref and self.rec_ref.flags & eServiceReference.isGroup:
			self.rec_ref = getBestPlayableServiceReference(self.rec_ref, eServiceReference())
		
		# recordService (Simulation) ggf. starten
		if self.timer.state == TimerEntry.StateWaiting:
			if self.simulate_recordService is None:
				if self.rec_ref:
					self.simulate_recordService = NavigationInstance.instance.recordService(self.rec_ref, True)
					if self.simulate_recordService:
						res = self.simulate_recordService.start()
						self.timer.log(0, "[VPS] start recordService (simulation) " + str(res))
						if res != 0 and res != -1:
							# Fehler aufgetreten (kein Tuner frei?)
							NavigationInstance.instance.stopRecordService(self.simulate_recordService)
							self.simulate_recordService = None
							
							# in einer Minute ggf. nochmal versuchen
							if 60 < self.nextExecution:
								self.nextExecution = 60
							
							# Bei Overwrite versuchen ohne Fragen auf Sender zu schalten
							if self.timer.vpsplugin_overwrite == True:
								cur_ref = NavigationInstance.instance.getCurrentlyPlayingServiceReference()
								if cur_ref and not cur_ref.getPath() and self.rec_ref.toCompareString() != cur_ref.toCompareString():
									self.timer.log(9, "[VPS-Plugin] zap without asking (simulation)")
									Notifications.AddNotification(MessageBox, _("In order to record a timer, the TV was switched to the recording service!\n"), type=MessageBox.TYPE_INFO, timeout=20)
									NavigationInstance.instance.playService(self.rec_ref)
									if 3 < self.nextExecution:
										self.nextExecution = 3
							else:
								# ansonsten versuchen auf dem aktuellen Transponder/Kanal nach Infos zu suchen
								if not self.program_try_search_running:
									self.program_do_start(1)
						else: # Simulation hat geklappt
							if 1 < self.nextExecution:
								self.nextExecution = 1
			else: # Simulation läuft schon
				# hole Demux
				stream = self.simulate_recordService.stream()
				if stream:
					streamdata = stream.getStreamingData()
					if (streamdata and ('demux' in streamdata)):
						self.demux = streamdata['demux']
				
				if self.demux == -1:
					# ist noch nicht soweit(?), in einer Sekunde erneut versuchen
					if 1 < self.nextExecution:
						self.nextExecution = 1
				else:
					self.program_do_start(0)
					
		
		elif self.timer.state == TimerEntry.StatePrepared or self.timer.state == TimerEntry.StateRunning:
			stream = self.timer.record_service.stream()
			if stream:
				streamdata = stream.getStreamingData()
				if (streamdata and ('demux' in streamdata)):
					self.demux = streamdata['demux']
			if self.demux != -1:
				self.program_do_start(0)
	
	
	# überprüft, ob etwas zu tun ist und gibt die Sekunden zurück, bis die Funktion
	# spätestens wieder aufgerufen werden sollte
	# oder -1, um vps_timer löschen zu lassen
	def check(self):
		# Simulation ggf. stoppen
		if self.timer.state > TimerEntry.StateWaiting and self.simulate_recordService:
			self.stop_simulation()
		
		# VPS wurde wieder deaktiviert oder Timer wurde beendet
		if self.timer is None or self.timer.state == TimerEntry.StateEnded or self.timer.cancelled:
			self.program_abort()
			self.stop_simulation()
			return -1
		
		if self.timer.vpsplugin_enabled == False or config.plugins.vps.enabled.value == False:
			if self.activated_auto_increase:
				self.timer.autoincrease = False
			self.program_abort()
			self.stop_simulation()
			return -1
		
		self.nextExecution = 180
		
		if config.plugins.vps.initial_time.value < 2 and self.timer.vpsplugin_overwrite:
			initial_time = 120
		else:
			initial_time = config.plugins.vps.initial_time.value * 60
		
		if self.timer.vpsplugin_overwrite == True:
			if self.timer.state == TimerEntry.StateWaiting or self.timer.state == TimerEntry.StatePrepared:
				# Startzeit verschieben
				if (self.timer.begin - 60) < time():
					if self.org_timer_begin == 0:
						self.org_timer_begin = self.timer.begin
					elif (self.org_timer_begin + self.max_extending_timer) < time():
						# Sendung begann immer noch nicht -> abbrechen
						self.timer.abort()
						self.session.nav.RecordTimer.doActivate(self.timer)
						self.program_abort()
						self.stop_simulation()
						self.timer.log(0, "[VPS] abort timer, waited enough to find Event-ID")
						return -1
					
					self.timer.begin += 60
					if (self.timer.end - self.timer.begin) < 300:
						self.timer.end += 180
						# auf Timer-Konflikt prüfen
						timersanitycheck = TimerSanityCheck(self.session.nav.RecordTimer.timer_list, self.timer)
						if not timersanitycheck.check():
							self.timer.abort()
							self.session.nav.RecordTimer.doActivate(self.timer)
							self.program_abort()
							self.stop_simulation()
							self.timer.log(0, "[VPS] abort timer due to TimerSanityCheck")
							return -1
						
					self.session.nav.RecordTimer.timeChanged(self.timer)
				
				if 30 < self.nextExecution:
					self.nextExecution = 30
		
		
		# Programm starten
		if not self.program_running:
			if self.timer.state == TimerEntry.StateRunning:
				self.program_start()
			
			elif initial_time > 0:
				if (self.timer.begin - initial_time) <= time():
					self.program_start()
				else:
					n = self.timer.begin - initial_time - time()
					if n < self.nextExecution:
						self.nextExecution = n
		
		
		if self.timer.state == TimerEntry.StateRunning:
			if self.activated_auto_increase and self.org_timer_end != 0 and (self.org_timer_end + (4*3600)) < time():
				# Aufnahme läuft seit 4 Stunden im Autoincrease -> abbrechen
				self.timer.autoincrease = False
				self.activated_auto_increase = False
				self.dont_restart_program = True
				self.program_abort()
				self.stop_simulation()
				self.timer.log(0, "[VPS] stop recording, too much autoincrease")
		
		return self.nextExecution
示例#53
0
	def __init__(self, session, serviceref, begin, end, name, description, eit, disabled = False, justplay = False, afterEvent = AFTEREVENT.AUTO, checkOldTimers = False, dirname = None, tags = None):
		self.session = session
		RecordTimerEntry.__init__(self, serviceref, begin, end, name, description, eit, disabled = False, justplay = False, afterEvent = AFTEREVENT.AUTO, checkOldTimers = False, dirname = None, tags = None)
示例#54
0
class vps_timer:
    def __init__(self, timer, session):
        self.timer = timer
        self.session = session
        self.program = eConsoleAppContainer()
        self.program.dataAvail.append(self.program_dataAvail)
        self.program.appClosed.append(self.program_closed)
        self.program_running = False
        self.program_try_search_running = False
        self.activated_auto_increase = False
        self.simulate_recordService = None
        self.demux = -1
        self.rec_ref = None
        self.found_pdc = False
        self.dont_restart_program = False
        self.org_timer_end = 0
        self.org_timer_begin = 0
        self.max_extending_timer = 4 * 3600
        self.next_events = []
        self.new_timer_copy = None
        self.pausing = False

    def program_closed(self, retval):
        self.timer.log(0, "[VPS] stop monitoring (process terminated)")
        if self.program_running or self.program_try_search_running:
            self.program_running = False
            self.program_try_search_running = False
            self.stop_simulation()

    def program_dataAvail(self, str):
        if self.timer is None or self.timer.state == TimerEntry.StateEnded or self.timer.cancelled:
            self.program_abort()
            self.stop_simulation()
            return
        if self.timer.vpsplugin_enabled == False or config.plugins.vps.enabled.value == False:
            if self.activated_auto_increase:
                self.timer.autoincrease = False
            self.program_abort()
            self.stop_simulation()
            return

        lines = str.split("\n")
        for line in lines:
            data = line.split()
            if len(data) == 0:
                continue

            self.timer.log(0, "[VPS] " + line)

            if data[0] == "RUNNING_STATUS":
                if data[1] == "0":  # undefined
                    if data[2] == "FOLLOWING":
                        data[1] = "1"
                    else:
                        data[1] = "4"

                if data[1] == "1":  # not running
                    # Wenn der Eintrag im Following (Section_Number = 1) ist,
                    # dann nicht beenden (Sendung begann noch gar nicht)
                    if data[2] == "FOLLOWING":
                        self.activate_autoincrease()
                    elif self.timer.state == TimerEntry.StateRunning and not self.pausing and not self.set_next_event(
                    ):
                        self.stop_recording()
                        self.dont_restart_program = True
                        self.program_abort()

                elif data[1] == "2":  # starts in a few seconds
                    self.activate_autoincrease()
                    if self.timer.state == TimerEntry.StateWaiting:
                        self.session.nav.RecordTimer.doActivate(self.timer)

                elif data[1] == "3":  # pausing
                    self.pausing = True
                    if self.timer.state == TimerEntry.StateRunning:
                        self.activate_autoincrease()

                elif data[1] == "4":  # running
                    self.pausing = False
                    if self.timer.state == TimerEntry.StateRunning:
                        self.activate_autoincrease()
                    elif self.timer.state == TimerEntry.StateWaiting or self.timer.state == TimerEntry.StatePrepared:
                        # setze Startzeit auf jetzt
                        self.timer.begin = int(time())
                        self.session.nav.RecordTimer.timeChanged(self.timer)

                        self.activate_autoincrease()
                        self.program_abort()
                        self.stop_simulation()
                        vps_timers.checksoon(2000)  # Programm neu starten

                elif data[1] == "5":  # service off-air
                    self.timer.vpsplugin_overwrite = False
                    if self.activated_auto_increase:
                        self.timer.autoincrease = False
                        self.activated_auto_increase = False

            elif data[0] == "EVENT_ENDED":
                if not self.set_next_event():
                    if self.timer.state == TimerEntry.StateRunning:
                        self.stop_recording()

                    # program terminates by itself
                    #self.program_abort()
                    self.stop_simulation()

            elif data[0] == "OTHER_TS_RUNNING_STATUS":
                if self.timer.state == TimerEntry.StateWaiting:
                    self.timer.start_prepare = int(time())
                    self.session.nav.RecordTimer.doActivate(self.timer)

                # program terminates by itself
                #self.program_abort()
                self.stop_simulation()
                vps_timers.checksoon(2000)

            # PDC
            elif data[0] == "PDC_FOUND_EVENT_ID":
                self.found_pdc = True
                self.timer.eit = int(data[1])
                epgcache = eEPGCache.getInstance()
                evt = epgcache.lookupEventId(self.rec_ref, self.timer.eit)
                if evt:
                    self.timer.name = evt.getEventName()
                    self.timer.description = evt.getShortDescription()
                # program terminates by itself
                #self.program_abort()
                vps_timers.checksoon(500)

            elif data[0] == "FOUND_EVENT_ON_SCHEDULE":
                starttime = int(data[1])
                duration = int(data[2])
                # Soll die Sendung laut EPG erst nach dem Ende dieses Timers beginnen?
                if (not self.timer.vpsplugin_overwrite and
                    (self.timer.end + 300) < starttime) or (
                        self.timer.vpsplugin_overwrite and
                        (self.timer.end + self.max_extending_timer - 1800) <
                        starttime):
                    if self.new_timer_copy is None:
                        if self.activated_auto_increase:
                            self.timer.autoincrease = False
                            self.activated_auto_increase = False
                        self.copyTimer(starttime, duration)
                        self.timer.log(
                            0,
                            "[VPS] copied this timer, since the event may start later than this timer ends"
                        )

                elif not self.activated_auto_increase:
                    self.activate_autoincrease()

            elif data[0] == "EVENT_OVER" or data[0] == "CANNOT_FIND_EVENT":
                self.max_extending_timer = 2 * 3600
                if self.activated_auto_increase:
                    self.timer.autoincrease = False
                    self.activated_auto_increase = False

            elif data[0] == "PDC_MULTIPLE_FOUND_EVENT":
                self.check_and_add_event(int(data[1]))

            # Programm meldet, dass die EIT (present/following) des Senders offenbar
            # momentan fehlerhaft ist
            elif data[0] == "EIT_APPARENTLY_UNRELIABLE":
                if self.timer.vpsplugin_overwrite:
                    self.timer.vpsplugin_overwrite = False
                    self.timer.log(
                        0, "[VPS] can't trust EPG currently, go to safe mode")

    def stop_recording(self):
        self.activated_auto_increase = False
        self.timer.autoincrease = False

        if self.timer.vpsplugin_overwrite:
            # Stopp nach margin_after seconds
            if config.plugins.vps.margin_after.value == 0:
                self.timer.abort()
                self.session.nav.RecordTimer.doActivate(self.timer)
            else:
                self.timer.end = int(
                    time()) + config.plugins.vps.margin_after.value
                self.session.nav.RecordTimer.timeChanged(self.timer)
            self.stop_simulation()
        else:
            new_end_time = int(time()) + config.plugins.vps.margin_after.value
            if new_end_time > self.timer.end:
                self.timer.end = new_end_time
                self.session.nav.RecordTimer.timeChanged(self.timer)

    def activate_autoincrease(self):
        if not self.activated_auto_increase:
            self.activated_auto_increase = True
            self.timer.autoincrease = True
            self.timer.autoincreasetime = 60

            if self.org_timer_end == 0:
                self.org_timer_end = self.timer.end
            self.timer.log(0, "[VPS] enable autoincrease")

            if self.new_timer_copy is not None and (
                    self.new_timer_copy
                    in self.session.nav.RecordTimer.timer_list):
                self.new_timer_copy.afterEvent = AFTEREVENT.NONE
                self.new_timer_copy.dontSave = True
                NavigationInstance.instance.RecordTimer.removeEntry(
                    self.new_timer_copy)
                self.new_timer_copy = None
                self.timer.log(0, "[VPS] delete timer copy")

    # Noch ein Event aufnehmen?
    def set_next_event(self):
        if not self.timer.vpsplugin_overwrite and len(self.next_events) > 0:
            if not self.activated_auto_increase:
                self.activate_autoincrease()

            (starttime, neweventid) = self.next_events.pop(0)
            self.timer.eit = neweventid
            self.dont_restart_program = False
            self.program_abort()
            self.timer.log(0, "[VPS] record now event_id " + str(neweventid))
            vps_timers.checksoon(3000)
            return True
        else:
            return False

    def program_abort(self):
        if self.program_running or self.program_try_search_running:
            #self.program.sendCtrlC()
            self.program.kill()
            self.program_running = False
            self.program_try_search_running = False
            self.timer.log(0, "[VPS] stop monitoring")

    def stop_simulation(self):
        if self.simulate_recordService:
            NavigationInstance.instance.stopRecordService(
                self.simulate_recordService)
            self.simulate_recordService = None
            self.timer.log(0, "[VPS] stop RecordService (simulation)")

    def check_and_add_event(self, neweventid):
        if not config.plugins.vps.allow_seeking_multiple_pdc.value:
            return

        epgcache = eEPGCache.getInstance()
        evt = epgcache.lookupEventId(self.rec_ref, neweventid)

        if evt:
            evt_begin = evt.getBeginTime() + 60
            evt_end = evt.getBeginTime() + evt.getDuration() - 60

            if evt_begin < self.timer.begin:
                return

            for checktimer in self.session.nav.RecordTimer.timer_list:
                if checktimer == self.timer:
                    continue
                if (checktimer.begin - evt_begin) > 3600 * 2:
                    break

                compareString = checktimer.service_ref.ref.toCompareString()
                if compareString == self.timer.service_ref.ref.toCompareString(
                ) or compareString == self.rec_ref.toCompareString():
                    if checktimer.eit == neweventid:
                        return

                    if checktimer.begin <= evt_begin and checktimer.end >= evt_end:
                        if checktimer.vpsplugin_enabled is None or not checktimer.vpsplugin_enabled:
                            return

                        # manuell angelegter Timer mit VPS
                        if checktimer.name == "" and checktimer.vpsplugin_time is not None:
                            checktimer.eit = neweventid
                            checktimer.name = evt.getEventName()
                            checktimer.description = evt.getShortDescription()
                            checktimer.vpsplugin_time = None
                            checktimer.log(
                                0,
                                "[VPS] changed timer (found same PDC-Time as in other VPS-recording)"
                            )
                            return

            # eigenen Timer überprüfen, wenn Zeiten nicht überschrieben werden dürfen
            if not self.timer.vpsplugin_overwrite and evt_begin <= self.timer.end:
                check_already_existing = [
                    x for (x, y) in self.next_events if y == neweventid
                ]
                if len(check_already_existing) > 0:
                    start = check_already_existing.pop()
                    if start == evt_begin:
                        return
                    else:
                        self.next_events.remove((start, neweventid))
                        self.timer.log(
                            0, "[VPS] delete event_id " + str(neweventid) +
                            " because of delay " + str(evt_begin - start))

                self.next_events.append((evt_begin, neweventid))
                self.next_events = sorted(self.next_events)
                self.timer.log(0, "[VPS] add event_id " + str(neweventid))

            else:
                newevent_data = parseEvent(evt)
                newEntry = RecordTimerEntry(ServiceReference(self.rec_ref),
                                            *newevent_data)
                newEntry.vpsplugin_enabled = True
                newEntry.vpsplugin_overwrite = True
                newEntry.dirname = self.timer.dirname
                newEntry.log(
                    0,
                    "[VPS] added this timer (found same PDC-Time as in other VPS-recording)"
                )

                # Wenn kein Timer-Konflikt auftritt, wird der Timer angelegt.
                res = NavigationInstance.instance.RecordTimer.record(newEntry)
                self.timer.log(0, "[VPS] added another timer, res " + str(res))

    def copyTimer(self, start, duration):
        starttime = start - config.recording.margin_before.value * 60
        endtime = start + duration + config.recording.margin_after.value * 60
        self.new_timer_copy = RecordTimerEntry(
            ServiceReference(self.rec_ref), starttime, endtime,
            self.timer.name, self.timer.description, self.timer.eit, False,
            False, AFTEREVENT.AUTO, False, self.timer.dirname, self.timer.tags)
        self.new_timer_copy.vpsplugin_enabled = True
        self.new_timer_copy.vpsplugin_overwrite = self.timer.vpsplugin_overwrite
        self.new_timer_copy.log(0, "[VPS] added this timer")
        NavigationInstance.instance.RecordTimer.record(self.new_timer_copy)

    # startet den Hintergrundprozess
    def program_do_start(self, mode):
        if self.program_running or self.program_try_search_running:
            self.program_abort()

        if mode == 1:
            self.demux = -1
            current_service = NavigationInstance.instance.getCurrentService()
            if current_service:
                stream = current_service.stream()
                if stream:
                    streamdata = stream.getStreamingData()
                    if (streamdata and ('demux' in streamdata)):
                        self.demux = streamdata['demux']
            if self.demux == -1:
                return

            self.program_try_search_running = True
            self.program_running = False
            mode_program = 1
        else:
            self.program_try_search_running = False
            self.program_running = True
            mode_program = 0

        sid = self.rec_ref.getData(1)
        tsid = self.rec_ref.getData(2)
        onid = self.rec_ref.getData(3)
        demux = "/dev/dvb/adapter0/demux" + str(self.demux)

        # PDC-Zeit?
        if (self.timer.name == "" or self.timer.eit is None
            ) and self.timer.vpsplugin_time is not None and not self.found_pdc:
            mode_program += 2
            day = strftime("%d", localtime(self.timer.vpsplugin_time))
            month = strftime("%m", localtime(self.timer.vpsplugin_time))
            hour = strftime("%H", localtime(self.timer.vpsplugin_time))
            minute = strftime("%M", localtime(self.timer.vpsplugin_time))
            cmd = vps_exe + " " + demux + " " + str(mode_program) + " " + str(
                onid) + " " + str(tsid) + " " + str(
                    sid
                ) + " 0 " + day + " " + month + " " + hour + " " + minute
            self.timer.log(0, "[VPS] seek PDC-Time")
            self.program.execute(cmd)
            return

        cmd = vps_exe + " " + demux + " " + str(mode_program) + " " + str(
            onid) + " " + str(tsid) + " " + str(sid) + " " + str(
                self.timer.eit)
        self.timer.log(0, "[VPS] start monitoring running-status")
        self.program.execute(cmd)

    def program_start(self):
        self.demux = -1

        if self.dont_restart_program:
            return

        self.rec_ref = self.timer.service_ref and self.timer.service_ref.ref
        if self.rec_ref and self.rec_ref.flags & eServiceReference.isGroup:
            self.rec_ref = getBestPlayableServiceReference(
                self.rec_ref, eServiceReference())

        # recordService (Simulation) ggf. starten
        if self.timer.state == TimerEntry.StateWaiting:
            if self.simulate_recordService is None:
                if self.rec_ref:
                    self.simulate_recordService = NavigationInstance.instance.recordService(
                        self.rec_ref, True)
                    if self.simulate_recordService:
                        res = self.simulate_recordService.start()
                        self.timer.log(
                            0, "[VPS] start recordService (simulation) " +
                            str(res))
                        if res != 0 and res != -1:
                            # Fehler aufgetreten (kein Tuner frei?)
                            NavigationInstance.instance.stopRecordService(
                                self.simulate_recordService)
                            self.simulate_recordService = None

                            # in einer Minute ggf. nochmal versuchen
                            if 60 < self.nextExecution:
                                self.nextExecution = 60

                            # Bei Overwrite versuchen ohne Fragen auf Sender zu schalten
                            if self.timer.vpsplugin_overwrite == True:
                                cur_ref = NavigationInstance.instance.getCurrentlyPlayingServiceReference(
                                )
                                if cur_ref and not cur_ref.getPath(
                                ) and self.rec_ref.toCompareString(
                                ) != cur_ref.toCompareString():
                                    self.timer.log(
                                        9,
                                        "[VPS-Plugin] zap without asking (simulation)"
                                    )
                                    Notifications.AddNotification(
                                        MessageBox,
                                        _("In order to record a timer, the TV was switched to the recording service!\n"
                                          ),
                                        type=MessageBox.TYPE_INFO,
                                        timeout=20)
                                    NavigationInstance.instance.playService(
                                        self.rec_ref)
                                    if 3 < self.nextExecution:
                                        self.nextExecution = 3
                            else:
                                # ansonsten versuchen auf dem aktuellen Transponder/Kanal nach Infos zu suchen
                                if not self.program_try_search_running:
                                    self.program_do_start(1)
                        else:  # Simulation hat geklappt
                            if 1 < self.nextExecution:
                                self.nextExecution = 1
            else:  # Simulation läuft schon
                # hole Demux
                stream = self.simulate_recordService.stream()
                if stream:
                    streamdata = stream.getStreamingData()
                    if (streamdata and ('demux' in streamdata)):
                        self.demux = streamdata['demux']

                if self.demux == -1:
                    # ist noch nicht soweit(?), in einer Sekunde erneut versuchen
                    if 1 < self.nextExecution:
                        self.nextExecution = 1
                else:
                    self.program_do_start(0)

        elif self.timer.state == TimerEntry.StatePrepared or self.timer.state == TimerEntry.StateRunning:
            stream = self.timer.record_service.stream()
            if stream:
                streamdata = stream.getStreamingData()
                if (streamdata and ('demux' in streamdata)):
                    self.demux = streamdata['demux']
            if self.demux != -1:
                self.program_do_start(0)

    # überprüft, ob etwas zu tun ist und gibt die Sekunden zurück, bis die Funktion
    # spätestens wieder aufgerufen werden sollte
    # oder -1, um vps_timer löschen zu lassen
    def check(self):
        # Simulation ggf. stoppen
        if self.timer.state > TimerEntry.StateWaiting and self.simulate_recordService:
            self.stop_simulation()

        # VPS wurde wieder deaktiviert oder Timer wurde beendet
        if self.timer is None or self.timer.state == TimerEntry.StateEnded or self.timer.cancelled:
            self.program_abort()
            self.stop_simulation()
            return -1

        if self.timer.vpsplugin_enabled == False or config.plugins.vps.enabled.value == False:
            if self.activated_auto_increase:
                self.timer.autoincrease = False
            self.program_abort()
            self.stop_simulation()
            return -1

        self.nextExecution = 180

        if config.plugins.vps.initial_time.value < 2 and self.timer.vpsplugin_overwrite:
            initial_time = 120
        else:
            initial_time = config.plugins.vps.initial_time.value * 60

        if self.timer.vpsplugin_overwrite == True:
            if self.timer.state == TimerEntry.StateWaiting or self.timer.state == TimerEntry.StatePrepared:
                # Startzeit verschieben
                if (self.timer.begin - 60) < time():
                    if self.org_timer_begin == 0:
                        self.org_timer_begin = self.timer.begin
                    elif (self.org_timer_begin +
                          self.max_extending_timer) < time():
                        # Sendung begann immer noch nicht -> abbrechen
                        self.timer.abort()
                        self.session.nav.RecordTimer.doActivate(self.timer)
                        self.program_abort()
                        self.stop_simulation()
                        self.timer.log(
                            0,
                            "[VPS] abort timer, waited enough to find Event-ID"
                        )
                        return -1

                    self.timer.begin += 60
                    if (self.timer.end - self.timer.begin) < 300:
                        self.timer.end += 180
                        # auf Timer-Konflikt prüfen
                        timersanitycheck = TimerSanityCheck(
                            self.session.nav.RecordTimer.timer_list,
                            self.timer)
                        if not timersanitycheck.check():
                            self.timer.abort()
                            self.session.nav.RecordTimer.doActivate(self.timer)
                            self.program_abort()
                            self.stop_simulation()
                            self.timer.log(
                                0, "[VPS] abort timer due to TimerSanityCheck")
                            return -1

                    self.session.nav.RecordTimer.timeChanged(self.timer)

                if 30 < self.nextExecution:
                    self.nextExecution = 30

        # Programm starten
        if not self.program_running:
            if self.timer.state == TimerEntry.StateRunning:
                self.program_start()

            elif initial_time > 0:
                if (self.timer.begin - initial_time) <= time():
                    self.program_start()
                else:
                    n = self.timer.begin - initial_time - time()
                    if n < self.nextExecution:
                        self.nextExecution = n

        if self.timer.state == TimerEntry.StateRunning:
            if self.activated_auto_increase and self.org_timer_end != 0 and (
                    self.org_timer_end + (4 * 3600)) < time():
                # Aufnahme läuft seit 4 Stunden im Autoincrease -> abbrechen
                self.timer.autoincrease = False
                self.activated_auto_increase = False
                self.dont_restart_program = True
                self.program_abort()
                self.stop_simulation()
                self.timer.log(0,
                               "[VPS] stop recording, too much autoincrease")

        return self.nextExecution
示例#55
0
	def parseEPG(self, simulateOnly = False):
		if NavigationInstance.instance is None:
			print("[AutoTimer] Navigation is not available, can't parse EPG")
			return (0, 0, 0, [], [], [])

		total = 0
		new = 0
		modified = 0
		timers = []
		conflicting = []
		similar = defaultdict(list)			# Contains the the marked similar eits and the conflicting strings
		similars = []										# Contains the added similar timers

		# NOTE: the config option specifies "the next X days" which means today (== 1) + X
		delta = timedelta(days = config.plugins.autotimer.maxdaysinfuture.value + 1)
		evtLimit = mktime((date.today() + delta).timetuple())
		checkEvtLimit = delta.days > 1
		del delta

		# Read AutoTimer configuration
		self.readXml()

		# Get E2 instances
		epgcache = eEPGCache.getInstance()
		serviceHandler = eServiceCenter.getInstance()
		recordHandler = NavigationInstance.instance.RecordTimer

		# Save Recordings in a dict to speed things up a little
		# We include processed timers as we might search for duplicate descriptions
		# The recordict is always filled
		#Question: It might be better to name it timerdict
		#Question: Move to a separate function getTimerDict()
		#Note: It is also possible to use RecordTimer isInTimer(), but we won't get the timer itself on a match
		recorddict = defaultdict(list)
		for timer in chain(recordHandler.timer_list, recordHandler.processed_timers):
			if timer and timer.service_ref:
				if timer.eit is not None:
					event = epgcache.lookupEventId(timer.service_ref.ref, timer.eit)
					extdesc = event and event.getExtendedDescription() or ''
					timer.extdesc = extdesc
				elif not hasattr(timer, 'extdesc'):
					timer.extdesc = ''
				recorddict[str(timer.service_ref)].append(timer)

		# Create dict of all movies in all folders used by an autotimer to compare with recordings
		# The moviedict will be filled only if one AutoTimer is configured to avoid duplicate description for any recordings
		#Question: It might be better to name it recorddict
		moviedict = defaultdict(list)

		# Iterate Timer
		for timer in self.getEnabledTimerList():
			# 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
			if timer.encoding != 'UTF-8':
				try:
					match = match.decode('UTF-8').encode(timer.encoding)
				except UnicodeDecodeError:
					pass

			# Search EPG, default to empty list
			epgmatches = epgcache.search(('RITBDSE', 1000, typeMap[timer.searchType], match, caseMap[timer.searchCase])) or []
			# Sort list of tuples by begin time 'B'
			epgmatches.sort(key=itemgetter(3))

			# Reset the the marked similar servicerefs
			similar.clear()

			# Loop over all EPG matches
			for idx, ( serviceref, eit, name, begin, duration, shortdesc, extdesc ) in enumerate( epgmatches ):

				#Question: Do we need this?
				#Question: Move to separate function getRealService()
				eserviceref = eServiceReference(serviceref)
				evt = epgcache.lookupEventId(eserviceref, eit)
				if not evt:
					print("[AutoTimer] Could not create Event!")
					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()

				evtBegin = begin
				evtEnd = end = begin + duration

				# If event starts in less than 60 seconds skip it
				if begin < time() + 60:
					print("[AutoTimer] Skipping an event because it starts in less than 60 seconds")
					continue

				# 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 similar:
					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:
							continue

					dayofweek = str(timestamp.tm_wday)

				# Check timer conditions
				# NOTE: similar matches to 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):
					continue

				if timer.hasOffset():
					# Apply custom Offset
					begin, end = timer.applyOffset(begin, end)
				else:
					# Apply E2 Offset
					begin -= config.recording.margin_before.value * 60
					end += config.recording.margin_after.value * 60

				# Eventually change service to alternative
				if timer.overrideAlternatives:
					serviceref = timer.getAlternative(serviceref)

				total += 1

				# 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

					# Eventually create cache
					if dest and dest not in moviedict:
						#Question: Move to a separate function getRecordDict()
						movielist = serviceHandler.list(eServiceReference("2:0:1:0:0:0:0:0:0:0:" + dest))
						if movielist is None:
							print("[AutoTimer] listing of movies in " + dest + " failed")
						else:
							append = moviedict[dest].append
							while 1:
								movieref = movielist.getNext()
								if not movieref.valid():
									break
								if movieref.flags & eServiceReference.mustDescent:
									continue
								info = serviceHandler.info(movieref)
								if info is None:
									continue
								event = info.getEvent(movieref)
								if event is None:
									continue
								append({
									"name": info.getName(movieref),
									"shortdesc": info.getInfoString(movieref, iServiceInformation.sDescription),
									"extdesc": event.getExtendedDescription() or '' # XXX: does event.getExtendedDescription() actually return None on no description or an empty string?
								})
							del append

					for movieinfo in moviedict.get(dest, ()):
						if movieinfo.get("name") == name \
							and movieinfo.get("shortdesc") == shortdesc:
							# Some channels indicate replays in the extended descriptions
							# If the similarity percent is higher then 0.8 it is a very close match
							extdescM = movieinfo.get("extdesc")
							if ( len(extdesc) == len(extdescM) and extdesc == extdescM ) \
								or ( 0.8 < SequenceMatcher(lambda x: x == " ",extdesc, extdescM).ratio() ):
								print("[AutoTimer] We found a matching recorded movie, skipping event:", name)
								movieExists = True
								break

					if movieExists:
						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 recorddict.get(serviceref, ()):
					if rtimer.eit == eit or config.plugins.autotimer.try_guessing.value and getTimeDiff(rtimer, evtBegin, evtEnd) > ((duration/10)*8):
						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 hasattr(rtimer, "isAutoTimer"):
							rtimer.log(501, "[AutoTimer] AutoTimer %s modified this automatically generated timer." % (timer.name))
						else:
							if config.plugins.autotimer.refresh.value != "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." % (timer.name))

						newEntry = rtimer
						modified += 1

						# Modify values saved in timer
						newEntry.name = name
						newEntry.description = shortdesc
						newEntry.begin = int(begin)
						newEntry.end = int(end)
						newEntry.service_ref = ServiceReference(serviceref)

						break
					elif timer.avoidDuplicateDescription >= 1 \
						and not rtimer.disabled \
						and rtimer.name == name \
						and rtimer.description == shortdesc:
							# Some channels indicate replays in the extended descriptions
							# If the similarity percent is higher then 0.8 it is a very close match
							if ( len(extdesc) == len(rtimer.extdesc) and extdesc == rtimer.extdesc ) \
								or ( 0.8 < SequenceMatcher(lambda x: x == " ",extdesc, rtimer.extdesc).ratio() ):
								oldExists = True
								print("[AutoTimer] We found a timer (similar service) with same description, skipping event")
								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
					if timer.avoidDuplicateDescription >= 2:
						for rtimer in chain.from_iterable( itervalues(recorddict) ):
							if not rtimer.disabled \
								and rtimer.name == name \
								and rtimer.description == shortdesc:
									# Some channels indicate replays in the extended descriptions
									# If the similarity percent is higher then 0.8 it is a very close match
									if ( len(extdesc) == len(rtimer.extdesc) and extdesc == rtimer.extdesc ) \
										or ( 0.8 < SequenceMatcher(lambda x: x == " ",extdesc, rtimer.extdesc).ratio() ):
										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))

					# 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.tags = timer.tags
				newEntry.vpsplugin_enabled = timer.vps_enabled
				newEntry.vpsplugin_overwrite = timer.vps_overwrite

				if oldExists:
					# XXX: this won't perform a sanity check, but do we actually want to do so?
					recordHandler.timeChanged(newEntry)
				else:
					conflictString = ""
					if similarTimer:
						conflictString = similar[eit].conflictString
						newEntry.log(504, "[AutoTimer] Try to add similar Timer because of conflicts with %s." % (conflictString))

					# Try to add timer
					conflicts = recordHandler.record(newEntry)

					if conflicts:
						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 conflicts and 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 shortdesc == shortdescS:
								# Some channels indicate replays in the extended descriptions
								# If the similarity percent is higher then 0.8 it is a very close match
								if ( len(extdesc) == len(extdescS) and extdesc == extdescS ) \
									or ( 0.8 < SequenceMatcher(lambda x: x == " ",extdesc, extdescS).ratio() ):
									# Check if the similar is already known
									if eitS not in similar:
										print("[AutoTimer] Found similar Timer: " + name)

										# Store the actual and similar eit and conflictString, so it can be handled later
										newEntry.conflictString = conflictString
										similar[eit] = newEntry
										similar[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
										break
									else:
										similarTimer = False
										newEntry = similar[eitS]
										break

					if conflicts is None:
						timer.decrementCounter()
						new += 1
						newEntry.extdesc = extdesc
						recorddict[serviceref].append(newEntry)

						# Similar timers are in new timers list and additionally in similar timers list
						if similarTimer:
							similars.append((name, begin, end, serviceref, timer.name))
							similar.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:
							newEntry.log(503, "[AutoTimer] Timer disabled because of conflicts with %s." % (conflictString))
							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)

		return (total, new, modified, timers, conflicting, similars)