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:  # nosec # noqa: E722
		info['lcd'] = 0
	try:  # temporary due OE-A
		info['grabpip'] = getGrabPip()
	except:  # nosec # 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 in ("dm800se", "dm500hd", "dm7020hd", "dm800sev2", "dm500hdv2", "dm7020hdv2"):
			chipset = "bcm7405"
		elif model == "dm8000":
			chipset = "bcm7400"
		elif model in ("dm820", "dm7080"):
			chipset = "bcm7435"
		elif model in ("dm520", "dm525"):
			chipset = "bcm73625"
		elif model in ("dm900", "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:  # nosec # 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:  # nosec # 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 + " (" + _("Front processor 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:  # nosec # 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: get tuner info for streams
			info['streams'] = GetStreamInfo()

			recs = NavigationInstance.instance.getRecordings()
			if recs:
				#  only one stream
				s_name = ''
				if len(info['streams']) == 1:
					sinfo = info['streams'][0]
					s_name = sinfo["name"] + ' (' + sinfo["ip"] + ')'
					print("[OpenWebif] -D- s_name '%s'" % s_name)

				serviceNames = {}
				for timer in NavigationInstance.instance.RecordTimer.timer_list:
					if timer.isRunning() and not timer.justplay:
						timer_rs = timer.record_service
						feinfo = timer_rs and hasattr(timer_rs, "frontendInfo") and timer_rs.frontendInfo()
						fedata = feinfo and hasattr(feinfo, "getFrontendData") and feinfo.getFrontendData()
						tuner_num = fedata and "tuner_number" in fedata and fedata.get("tuner_number")
						if tuner_num is not None:
							if tuner_num in serviceNames: # this tuner is recording more than one timer
								serviceNames[tuner_num] += ", " + removeBad(timer.service_ref.getServiceName())
							else:
								serviceNames[tuner_num] = removeBad(timer.service_ref.getServiceName())
						print("[OpenWebif] -D- timer '%s'" % timer.service_ref.getServiceName())

				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']
							if nr in serviceNames:
								info['tuners'][nr]['rec'] = getOrbitalText(cur_info) + ' / ' + serviceNames[nr]
							else:
								info['tuners'][nr]['rec'] = getOrbitalText(cur_info) + ' / ' + s_name

			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(ServiceReference("1:0:1:0:0:0:0:0:0:0"), 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)

	info['textinputsupport'] = TEXTINPUTSUPPORT
	STATICBOXINFO = info
	return info def getCurrentTime():
	t = time.localtime()
	return {
		"status": True,
		"time": "%2d:%02d:%02d" % (t.tm_hour, t.tm_min, t.tm_sec)
	} def getStatusInfo(self):
	# Get Current Volume and Mute Status
	vcontrol = eDVBVolumecontrol.getInstance()
	statusinfo = {
		'volume': vcontrol.getVolume(),
		'muted': vcontrol.isMuted(),
		'transcoding': TRANSCODING,
		'currservice_filename': "",
		'currservice_id': -1,
	}

	# Get currently running Service
	event = None
	serviceref = NavigationInstance.instance.getCurrentlyPlayingServiceReference()
	serviceref_string = None
	currservice_station = None
	if serviceref is not None:
		serviceHandler = eServiceCenter.getInstance()
		serviceHandlerInfo = serviceHandler.info(serviceref)

		service = NavigationInstance.instance.getCurrentService()
		serviceinfo = service and service.info()
		event = serviceinfo and serviceinfo.getEvent(0)
		serviceref_string = serviceref.toString()
		currservice_station = removeBad(serviceHandlerInfo.getName(serviceref))
	else:
		event = None
		serviceHandlerInfo = None

	if event is not None:
		# (begin, end, name, description, eit)
		curEvent = parseEvent(event)
		begin_timestamp = int(curEvent[0]) + (config.recording.margin_before.value * 60)
		end_timestamp = int(curEvent[1]) - (config.recording.margin_after.value * 60)
		statusinfo['currservice_name'] = removeBad(curEvent[2])
		statusinfo['currservice_serviceref'] = serviceref_string
		statusinfo['currservice_begin'] = time.strftime("%H:%M", (time.localtime(begin_timestamp)))
		statusinfo['currservice_begin_timestamp'] = begin_timestamp
		statusinfo['currservice_end'] = time.strftime("%H:%M", (time.localtime(end_timestamp)))
		statusinfo['currservice_end_timestamp'] = end_timestamp
		desc = curEvent[3]
		if six.PY2:
			desc = desc.decode('utf-8')
		if len(desc) > 220:
			desc = desc + u"..."
		if six.PY2:
			desc = desc.encode('utf-8')
		statusinfo['currservice_description'] = desc
		statusinfo['currservice_station'] = currservice_station
		if statusinfo['currservice_serviceref'].startswith('1:0:0'):
			statusinfo['currservice_filename'] = '/' + '/'.join(serviceref_string.split("/")[1:])
		full_desc = statusinfo['currservice_name'] + '\n'
		full_desc += statusinfo['currservice_begin'] + " - " + statusinfo['currservice_end'] + '\n\n'
		full_desc += removeBad2(event.getExtendedDescription())
		statusinfo['currservice_fulldescription'] = full_desc
		statusinfo['currservice_id'] = curEvent[4]
	else:
		statusinfo['currservice_name'] = "N/A"
		statusinfo['currservice_begin'] = ""
		statusinfo['currservice_end'] = ""
		statusinfo['currservice_description'] = ""
		statusinfo['currservice_fulldescription'] = "N/A"
		if serviceref:
			statusinfo['currservice_serviceref'] = serviceref_string
			if statusinfo['currservice_serviceref'].startswith('1:0:0') or statusinfo['currservice_serviceref'].startswith('4097:0:0'):
				this_path = '/' + '/'.join(serviceref_string.split("/")[1:])
				if os.path.exists(this_path):
					statusinfo['currservice_filename'] = this_path
			if serviceHandlerInfo:
				statusinfo['currservice_station'] = currservice_station
			elif serviceref_string.find("http") != -1:
				statusinfo['currservice_station'] = serviceref_string.replace('%3a', ':')[serviceref_string.find("http"):]
			else:
				statusinfo['currservice_station'] = "N/A"

	# Get Standby State
	from Screens.Standby import inStandby
	if inStandby is None:
		statusinfo['inStandby'] = "false"
	else:
		statusinfo['inStandby'] = "true"

	# Get recording state
	recs = NavigationInstance.instance.getRecordings()
	if recs:
		statusinfo['isRecording'] = "true"
		statusinfo['Recording_list'] = "\n"
		for timer in NavigationInstance.instance.RecordTimer.timer_list:
			if timer.state == TimerEntry.StateRunning:
				if not timer.justplay:
					statusinfo['Recording_list'] += removeBad(timer.service_ref.getServiceName()) + ": " + timer.name + "\n"
		if statusinfo['Recording_list'] == "\n":
			statusinfo['isRecording'] = "false"
	else:
		statusinfo['isRecording'] = "false"

	# Get streaminfo
	streams = GetStreamInfo()
	Streaming_list = []
	try:

		# TODO move this code to javascript getStatusinfo
		for stream in streams:
			st = ''
			s = stream["name"]
			e = stream["eventname"]
			i = stream["ip"]
			del stream
			if i is not None:
				st += i + ": "
			st += s + ' - ' + e
			if st != '':
				Streaming_list.append(st)

	except Exception as error:  # nosec # noqa: E722
#		print("[OpenWebif] -D- build Streaming_list %s" % error)
		pass

	if len(streams) > 0:
		statusinfo['Streaming_list'] = '\n'.join(Streaming_list)
		statusinfo['isStreaming'] = 'true'
	else:
		statusinfo['Streaming_list'] = ''
		statusinfo['isStreaming'] = 'false'

	return statusinfo def getFrontendStatus(session):
	inf = {}
	inf['tunertype'] = ""
	inf['tunernumber'] = ""
	inf['snr'] = ""
	inf['snr_db'] = ""
	inf['agc'] = ""
	inf['ber'] = ""

	from Screens.Standby import inStandby
	if inStandby is None:
		inf['inStandby'] = "false"
	else:
		inf['inStandby'] = "true"

	service = session.nav.getCurrentService()
	if service is None:
		return inf
	feinfo = service.frontendInfo()
	frontendData = feinfo and feinfo.getAll(True)

	if frontendData is not None:
		inf['tunertype'] = frontendData.get("tuner_type", "UNKNOWN")
		inf['tunernumber'] = frontendData.get("tuner_number")

	frontendStatus = feinfo and feinfo.getFrontendStatus()
	if frontendStatus is not None:
		percent = frontendStatus.get("tuner_signal_quality")
		if percent is not None:
			inf['snr'] = int(percent * 100 / 65535)
			inf['snr_db'] = inf['snr']
		percent = frontendStatus.get("tuner_signal_quality_db")
		if percent is not None:
			inf['snr_db'] = "%3.02f" % (percent / 100.0)
		percent = frontendStatus.get("tuner_signal_power")
		if percent is not None:
			inf['agc'] = int(percent * 100 / 65535)
		percent = frontendStatus.get("tuner_bit_error_rate")
		if percent is not None:
			inf['ber'] = int(percent * 100 / 65535)

	return inf def testPipStatus(self):
	pipinfo = {
		'pip': getPipStatus(),
	}
	return pipinfo def getCurrentService(session):
	try:
		info = session.nav.getCurrentService().info()
		ref = str(getServiceInfoString(info, iServiceInformation.sServiceref))
		if len(ref) < 10:
			serviceref = session.nav.getCurrentlyPlayingServiceReference()
			if serviceref is not None:
				ref = serviceref.toString()

		ns = getServiceInfoString(info, iServiceInformation.sNamespace)
		try:
			ns = int(ns)
		except ValueError:
			ns = 0

		bqname = ""
		bqref = ""

		try:
			servicelist = InfoBar.instance.servicelist
			epg_bouquet = servicelist and servicelist.getRoot()
			if epg_bouquet:
				bqname = ServiceReference(epg_bouquet).getServiceName()
				bqref = ServiceReference(epg_bouquet).ref.toString()
		except:  # nosec # noqa: E722
			pass

		return {
			"result": True,
			"name": filterName(info.getName()),
			"namespace": 0xffffffff & ns,
			"aspect": getServiceInfoString(info, iServiceInformation.sAspect),
			"provider": getServiceInfoString(info, iServiceInformation.sProvider),
			"width": getServiceInfoString(info, iServiceInformation.sVideoWidth),
			"height": getServiceInfoString(info, iServiceInformation.sVideoHeight),
			"apid": getServiceInfoString(info, iServiceInformation.sAudioPID),
			"vpid": getServiceInfoString(info, iServiceInformation.sVideoPID),
			"pcrpid": getServiceInfoString(info, iServiceInformation.sPCRPID),
			"pmtpid": getServiceInfoString(info, iServiceInformation.sPMTPID),
			"txtpid": getServiceInfoString(info, iServiceInformation.sTXTPID),
			"tsid": getServiceInfoString(info, iServiceInformation.sTSID),
			"onid": getServiceInfoString(info, iServiceInformation.sONID),
			"sid": getServiceInfoString(info, iServiceInformation.sSID),
			"ref": quote(ref, safe=' ~@#$&()*!+=:;,.?/\''),
			"iswidescreen": info.getInfo(iServiceInformation.sAspect) in (3, 4, 7, 8, 0xB, 0xC, 0xF, 0x10),
			"bqref": quote(bqref, safe=' ~@#$&()*!+=:;,.?/\''),
			"bqname": bqname
		}
	except Exception as e:
		print(str(e))
		return {
			"result": False,
			"name": "",
			"namespace": "",
			"aspect": 0,
			"provider": "",
			"width": 0,
			"height": 0,
			"apid": 0,
			"vpid": 0,
			"pcrpid": 0,
			"pmtpid": 0,
			"txtpid": "N/A",
			"tsid": 0,
			"onid": 0,
			"sid": 0,
			"ref": "",
			"iswidescreen": False,
			"bqref": "",
			"bqname": ""
		} def getBouquets(stype):
	s_type = service_types_tv
	s_type2 = "bouquets.tv"
	if stype == "radio":
		s_type = service_types_radio
		s_type2 = "bouquets.radio"
	serviceHandler = eServiceCenter.getInstance()
	services = serviceHandler.list(eServiceReference('%s FROM BOUQUET "%s" ORDER BY bouquet' % (s_type, s_type2)))
	bouquets = services and services.getContent("SN", True)
	bouquets = removeHiddenBouquets(bouquets)
	return {"bouquets": bouquets} def getServices(sRef, showAll=True, showHidden=False, pos=0, provider=False, picon=False, noiptv=False):
	services = []
	allproviders = {}

	CalcPos = False

	if sRef == "":
		sRef = '%s FROM BOUQUET "bouquets.tv" ORDER BY bouquet' % (service_types_tv)
		CalcPos = True
	elif ' "bouquets.radio" ' in sRef:
		CalcPos = True
	elif ' "bouquets.tv" ' in sRef:
		CalcPos = True

	if provider:
		s_type = service_types_tv
		if "radio" in sRef:
			s_type = service_types_radio
		pserviceHandler = eServiceCenter.getInstance()
		pservices = pserviceHandler.list(eServiceReference('%s FROM PROVIDERS ORDER BY name' % (s_type)))
		providers = pservices and pservices.getContent("SN", True)

		if provider:
			for provider in providers:
				servicelist = ServiceList(eServiceReference(provider[0]))
				slist = servicelist.getServicesAsList()
				for sitem in slist:
					allproviders[sitem[0]] = provider[1]

	servicelist = ServiceList(eServiceReference(sRef))
	slist = servicelist.getServicesAsList()
	serviceHandler = eServiceCenter.getInstance()

	oPos = 0
	for sitem in slist:
		oldoPos = oPos
		sref = sitem[0]
		if CalcPos and 'userbouquet' in sref:
			serviceslist = serviceHandler.list(eServiceReference(sref))
			sfulllist = serviceslist and serviceslist.getContent("RN", True)
			for citem in sfulllist:
				sref = citem[0].toString()
				hs = (int(sref.split(":")[1]) & 512)
				sp = (sref[:7] == '1:832:D') or (sref[:7] == '1:832:1') or (sref[:6] == '1:320:')
				if not hs or sp:  # 512 is hidden service on sifteam image. Doesn't affect other images
					oPos = oPos + 1
					if not sp and citem[0].flags & eServiceReference.isMarker:
						oPos = oPos - 1
		showiptv = True
		if noiptv:
			if '4097:' in sref or '5002:' in sref or 'http%3a' in sref or 'https%3a' in sref:
				showiptv = False

		st = int(sitem[0].split(":")[1])
		sp = (sitem[0][:7] == '1:832:D') or (sitem[0][:7] == '1:832:1') or (sitem[0][:6] == '1:320:')
		if sp or (not (st & 512) and not (st & 64)):
			pos = pos + 1
		if showiptv and (not st & 512 or showHidden):
			if showAll or st == 0:
				service = {}
				service['pos'] = 0 if (st & 64) else pos
				sr = convertUnicode(sitem[0])
				if CalcPos:
					service['startpos'] = oldoPos
				if picon:
					service['picon'] = getPicon(sr)
				service['servicereference'] = sr
				service['program'] = int(service['servicereference'].split(':')[3], 16)
				service['servicename'] = convertUnicode(sitem[1])
				if provider:
					if sitem[0] in allproviders:
						service['provider'] = allproviders[sitem[0]]
					else:
						service['provider'] = ""
				services.append(service)

	return {"services": services, "pos": pos} def getSubServices(session):
	services = []
	service = session.nav.getCurrentService()
	if service is not None:
		services.append({
			"servicereference": service.info().getInfoString(iServiceInformation.sServiceref),
			"servicename": service.info().getName()
		})
		subservices = service.subServices()
		if subservices and subservices.getNumberOfSubservices() > 0:
			print(subservices.getNumberOfSubservices())
			for i in list(range(subservices.getNumberOfSubservices())):
				sub = subservices.getSubservice(i)
				services.append({
					"servicereference": sub.toString(),
					"servicename": sub.getName()
				})
	else:
		services.append({
			"servicereference": "N/A",
			"servicename": "N/A"
		})

	return {"services": services} def getSatellites(stype):
	ret = []
	s_type = service_types_tv
	if stype == "radio":
		s_type = service_types_radio
	refstr = '%s FROM SATELLITES ORDER BY satellitePosition' % (s_type)
	ref = eServiceReference(refstr)
	serviceHandler = eServiceCenter.getInstance()
	servicelist = serviceHandler.list(ref)
	if servicelist is not None:
		while True:
			service = servicelist.getNext()
			if not service.valid():
				break
			unsigned_orbpos = service.getUnsignedData(4) >> 16
			orbpos = service.getData(4) >> 16
			if orbpos < 0:
				orbpos += 3600
			if service.getPath().find("FROM PROVIDER") != -1:
				# service_type = _("Providers")
				continue
			elif service.getPath().find("flags == %d" % (FLAG_SERVICE_NEW_FOUND)) != -1:
				service_type = _("New")
			else:
				service_type = _("Services")
			try:
				service_name = str(nimmanager.getSatDescription(orbpos))
			except:  # nosec # noqa: E722
				if unsigned_orbpos == 0xFFFF:  # Cable
					service_name = _("Cable")
				elif unsigned_orbpos == 0xEEEE:  # Terrestrial
					service_name = _("Terrestrial")
				else:
					service_name = getOrb(orbpos)
			service.setName("%s - %s" % (service_name, service_type))
			ret.append({
				"service": service.toString(),
				"name": service.getName()
			})
	ret = sortSatellites(ret)
	return {"satellites": ret} def getBouquetEpg(ref, begintime=-1, endtime=None, encode=False):
	ref = unquote(ref)
	ret = []
	services = eServiceCenter.getInstance().list(eServiceReference(ref))
	if not services:
		return {"events": ret, "result": False}

	if endtime == None:
		endtime = -1

	# prevent crash
	if endtime > 100000:
		endtime = -1

	search = ['IBDCTSERNW']
	for service in services.getContent('S'):
		search.append((service, 0, begintime, endtime))

	epgcache = eEPGCache.getInstance()
	events = epgcache.lookupEvent(search)
	if events is not None:
		for event in events:
			ev = {}
			ev['id'] = event[0]
			ev['begin_timestamp'] = event[1]
			ev['duration_sec'] = event[2]
			ev['title'] = filterName(event[4], encode)
			ev['shortdesc'] = convertDesc(event[5], encode)
			ev['longdesc'] = convertDesc(event[6], encode)
			ev['sref'] = event[7]
			ev['sname'] = filterName(event[8], encode)
			ev['now_timestamp'] = event[3]
			ev['genre'], ev['genreid'] = convertGenre(event[9])
			ret.append(ev)

	return {"events": ret, "result": True} def getBouquetNowNextEpg(ref, servicetype, encode=False):
	ref = unquote(ref)
	ret = []
	services = eServiceCenter.getInstance().list(eServiceReference(ref))
	if not services:
		return {"events": ret, "result": False}

	search = ['IBDCTSERNWX']
	if servicetype == -1:
		for service in services.getContent('S'):
			search.append((service, 0, -1))
			search.append((service, 1, -1))
	else:
		for service in services.getContent('S'):
			search.append((service, servicetype, -1))

	epgcache = eEPGCache.getInstance()
	events = epgcache.lookupEvent(search)
	if events is not None:
		for event in events:
			ev = {}
			ev['id'] = event[0]
			ev['begin_timestamp'] = event[1]
			ev['duration_sec'] = event[2]
			ev['title'] = filterName(event[4], encode)
			ev['shortdesc'] = convertDesc(event[5], encode)
			ev['longdesc'] = convertDesc(event[6], encode)
			if event[7] is not None:
				achannels = GetWithAlternative(event[7], False)
				if achannels:
					ev['asrefs'] = achannels
			ev['sref'] = event[7]
			ev['sname'] = filterName(event[8], encode)
			ev['now_timestamp'] = event[3]
			ev['genre'], ev['genreid'] = convertGenre(event[9])
			ret.append(ev)

	return {"events": ret, "result": True} def getServicesNowNextEpg(sList, encode=False):
	ret = []
	if not sList:
		return {"events": ret, "result": False}

	sRefList = sList.split(",")
	search = ['IBDCTSERNX']
	for service in sRefList:
		search.append((service, 0, -1))
		search.append((service, 1, -1))

	epgcache = eEPGCache.getInstance()
	events = epgcache.lookupEvent(search)
	if events is not None:
		for event in events:
			ev = {}
			ev['id'] = event[0]
			ev['begin_timestamp'] = event[1]
			ev['duration_sec'] = event[2]
			ev['title'] = filterName(event[4], encode)
			ev['shortdesc'] = convertDesc(event[5], encode)
			ev['longdesc'] = convertDesc(event[6], encode)
			# if event[7] is not None:
			#  achannels = GetWithAlternative(event[7], False)
			#   if achannels:
			#    ev['asrefs'] = achannels
			ev['sref'] = event[7]
			ev['sname'] = filterName(event[8], encode)
			ev['now_timestamp'] = event[3]
			ret.append(ev)

	return {"events": ret, "result": True} def getSearchEpg(sstr, endtime=None, fulldesc=False, bouquetsonly=False, encode=False):
	ret = []
	ev = {}
	if config.OpenWebif.epg_encoding.value != 'utf-8':
		try:
			sstr = sstr.encode(config.OpenWebif.epg_encoding.value)
		except UnicodeEncodeError:
			pass
	epgcache = eEPGCache.getInstance()
	search_type = eEPGCache.PARTIAL_TITLE_SEARCH
	if fulldesc:
		if hasattr(eEPGCache, 'FULL_DESCRIPTION_SEARCH'):
			search_type = eEPGCache.FULL_DESCRIPTION_SEARCH
		elif hasattr(eEPGCache, 'PARTIAL_DESCRIPTION_SEARCH'):
			search_type = eEPGCache.PARTIAL_DESCRIPTION_SEARCH
	events = epgcache.search(('IBDTSENRW', 128, search_type, sstr, 1))
	if events is not None:
		# TODO : discuss #677
		# events.sort(key = lambda x: (x[1],x[6])) # sort by date,sname
		# events.sort(key = lambda x: x[1]) # sort by date
		if bouquetsonly:
			# collect service references from TV bouquets
			bsref = {}
			for service in getAllServices('tv')['services']:
				for service2 in service['subservices']:
					bsref[service2['servicereference']] = True
				else:
					bsref[service['servicereference']] = True

		for event in events:
			if bouquetsonly and not event[7] in bsref:
				continue
			ev = {}
			ev['id'] = event[0]
			ev['date'] = "%s %s" % (tstrings[("day_" + strftime("%w", (localtime(event[1]))))], strftime(_("%d.%m.%Y"), (localtime(event[1]))))
			ev['begin_timestamp'] = event[1]
			ev['begin'] = strftime("%H:%M", (localtime(event[1])))
			ev['duration_sec'] = event[2]
			ev['duration'] = int(event[2] / 60)
			ev['end'] = strftime("%H:%M", (localtime(event[1] + event[2])))
			ev['title'] = filterName(event[3], encode)
			ev['shortdesc'] = convertDesc(event[4], encode)
			ev['longdesc'] = convertDesc(event[5], encode)
			ev['sref'] = event[7]
			ev['sname'] = filterName(event[6], encode)
			ev['picon'] = getPicon(event[7])
			ev['now_timestamp'] = None
			ev['genre'], ev['genreid'] = convertGenre(event[8])
			if endtime:
				# don't show events if begin after endtime
				if event[1] <= endtime:
					ret.append(ev)
			else:
				ret.append(ev)

			psref = parse_servicereference(event[7])
			ev['service_type'] = SERVICE_TYPE_LOOKUP.get(psref.get('service_type'), "UNKNOWN")
			nsi = psref.get('ns')
			ns = NS_LOOKUP.get(nsi, "DVB-S")
			if ns == "DVB-S":
				ev['ns'] = getOrb(nsi >> 16 & 0xFFF)
			else:
				ev['ns'] = ns

	return {"events": ret, "result": True} def getChannelEpg(ref, begintime=-1, endtime=-1, encode=True):
	ret = []
	ev = {}
	use_empty_ev = False
	if ref:
		ref = unquote(ref)

		# When quering EPG we dont need URL, also getPicon doesn't like URL
		if "://" in ref:
			_ref = ":".join(ref.split(":")[:10]) + "::" + ref.split(":")[-1]
		else:
			_ref = ref

		picon = getPicon(_ref)
		epgcache = eEPGCache.getInstance()
		events = epgcache.lookupEvent(['IBDTSENCW', (_ref, 0, begintime, endtime)])
		if events is not None:
			for event in events:
				ev = {}
				ev['picon'] = picon
				ev['id'] = event[0]
				if event[1]:
					ev['date'] = "%s %s" % (tstrings[("day_" + strftime("%w", (localtime(event[1]))))], strftime(_("%d.%m.%Y"), (localtime(event[1]))))
					ev['begin'] = strftime("%H:%M", (localtime(event[1])))
					ev['begin_timestamp'] = event[1]
					ev['duration'] = int(event[2] / 60)
					ev['duration_sec'] = event[2]
					ev['end'] = strftime("%H:%M", (localtime(event[1] + event[2])))
					ev['title'] = filterName(event[3], encode)
					ev['shortdesc'] = convertDesc(event[4], encode)
					ev['longdesc'] = convertDesc(event[5], encode)
					ev['sref'] = ref
					ev['sname'] = filterName(event[6], encode)
					ev['tleft'] = int(((event[1] + event[2]) - event[7]) / 60)
					if ev['duration_sec'] == 0:
						ev['progress'] = 0
					else:
						ev['progress'] = int(((event[7] - event[1]) * 100 / event[2]) * 4)
					ev['now_timestamp'] = event[7]
					ev['genre'], ev['genreid'] = convertGenre(event[8])
					ret.append(ev)
				else:
					use_empty_ev = True
					ev['sref'] = ref
	else:
		use_empty_ev = True
		ev['sref'] = ""

	if use_empty_ev:
		ev['date'] = 0
		ev['begin'] = 0
		ev['begin_timestamp'] = 0
		ev['duration'] = 0
		ev['duration_sec'] = 0
		ev['end'] = 0
		ev['title'] = "N/A"
		ev['shortdesc'] = ""
		ev['sname'] = ""
		ev['longdesc'] = ""
		ev['tleft'] = 0
		ev['progress'] = 0
		ev['now_timestamp'] = 0
		ev['genre'] = ""
		ev['genreid'] = 0
		ret.append(ev)

	return {"events": ret, "result": True} def getNowNextEpg(ref, servicetype, encode=False):
	ref = unquote(ref)
	ret = []
	epgcache = eEPGCache.getInstance()
	events = epgcache.lookupEvent(['IBDCTSERNWX', (ref, servicetype, -1)])
	if events is not None:
		for event in events:
			ev = {}
			ev['id'] = event[0]
			if event[1]:
				ev['begin_timestamp'] = event[1]
				ev['duration_sec'] = event[2]
				ev['title'] = filterName(event[4], encode)
				ev['shortdesc'] = convertDesc(event[5], encode)
				ev['longdesc'] = convertDesc(event[6], encode)
				ev['sref'] = event[7]
				ev['sname'] = filterName(event[8], encode)
				ev['now_timestamp'] = event[3]
				ev['remaining'] = (event[1] + event[2]) - event[3]
				ev['genre'], ev['genreid'] = convertGenre(event[9])
			else:
				ev['begin_timestamp'] = 0
				ev['duration_sec'] = 0
				ev['title'] = "N/A"
				ev['shortdesc'] = ""
				ev['longdesc'] = ""
				ev['sref'] = event[7]
				ev['sname'] = filterName(event[8])
				ev['now_timestamp'] = 0
				ev['remaining'] = 0
				ev['genre'] = ""
				ev['genreid'] = 0

			ret.append(ev)

	return {"events": ret, "result": True} def getSearchSimilarEpg(ref, eventid, encode=False):
	ref = unquote(ref)
	ret = []
	ev = {}
	epgcache = eEPGCache.getInstance()
	events = epgcache.search(('IBDTSENRW', 128, eEPGCache.SIMILAR_BROADCASTINGS_SEARCH, ref, eventid))
	if events is not None:
		# TODO : discuss #677
		# events.sort(key = lambda x: (x[1],x[6])) # sort by date,sname
		# events.sort(key = lambda x: x[1]) # sort by date
		for event in events:
			ev = {}
			ev['id'] = event[0]
			ev['date'] = "%s %s" % (tstrings[("day_" + strftime("%w", (localtime(event[1]))))], strftime(_("%d.%m.%Y"), (localtime(event[1]))))
			ev['begin_timestamp'] = event[1]
			ev['begin'] = strftime("%H:%M", (localtime(event[1])))
			ev['duration_sec'] = event[2]
			ev['duration'] = int(event[2] / 60)
			ev['end'] = strftime("%H:%M", (localtime(event[1] + event[2])))
			ev['title'] = filterName(event[3], encode)
			ev['shortdesc'] = convertDesc(event[4], encode)
			ev['longdesc'] = convertDesc(event[5], encode)
			ev['sref'] = event[7]
			ev['sname'] = filterName(event[6], encode)
			ev['picon'] = getPicon(event[7])
			ev['now_timestamp'] = None
			ev['genre'], ev['genreid'] = convertGenre(event[8])
			ret.append(ev)

	return {"events": ret, "result": True} def getAllServices(type, noiptv=False, nolastscanned=False):
	services = []
	if type is None:
		type = "tv"
	bouquets = getBouquets(type)["bouquets"]
	pos = 0
	for bouquet in bouquets:
		if nolastscanned and 'LastScanned' in bouquet[0]:
			continue
		sv = getServices(sRef=bouquet[0], showAll=True, showHidden=False, pos=pos, noiptv=noiptv)
		services.append({
			"servicereference": bouquet[0],
			"servicename": bouquet[1],
			"subservices": sv["services"]
		})
		pos = sv["pos"]

	return {
		"result": True,
		"services": services
	} def getPlayableServices(sRef, sRefPlaying):
	if sRef == "":
		sRef = '%s FROM BOUQUET "bouquets.tv" ORDER BY bouquet' % (service_types_tv)

	services = []
	servicecenter = eServiceCenter.getInstance()
	servicelist = servicecenter.list(eServiceReference(sRef))
	servicelist2 = servicelist and servicelist.getContent('S') or []

	for service in servicelist2:
		if not int(service.split(":")[1]) & 512:  # 512 is hidden service on sifteam image. Doesn't affect other images
			service2 = {}
			service2['servicereference'] = service
			info = servicecenter.info(eServiceReference(service))
			service2['isplayable'] = info.isPlayable(eServiceReference(service), eServiceReference(sRefPlaying)) > 0
			services.append(service2)

	return {
		"result": True,
		"services": services
	} def getPlayableService(sRef, sRefPlaying):
	servicecenter = eServiceCenter.getInstance()
	info = servicecenter.info(eServiceReference(sRef))
	return {
		"result": True,
		"service": {
			"servicereference": sRef,
			"isplayable": info.isPlayable(eServiceReference(sRef), eServiceReference(sRefPlaying)) > 0
		}
	} def getParentalControlList():
	if config.ParentalControl.configured.value:
		return {
			"result": True,
			"services": []
		}
	parentalControl.open()
	if config.ParentalControl.type.value == "whitelist":
		tservices = parentalControl.whitelist
	else:
		tservices = parentalControl.blacklist
	services = []
	if tservices is not None:
		for service in tservices:
			tservice = ServiceReference(service)
			services.append({
				"servicereference": service,
				"servicename": tservice.getServiceName()
			})
	return {
		"result": True,
		"type": config.ParentalControl.type.value,
		"services": services
	} def getEvent(ref, idev, encode=True):
	epgcache = eEPGCache.getInstance()
	eventLookupTable = 'IBDTSENRWX'
	events = epgcache.lookupEvent([eventLookupTable, (ref, 2, int(idev))]) #IBTSRND
	info = {}
	for event in events:
		info['id'] = event[0]
		info['begin_str'] = strftime("%H:%M", (localtime(event[1])))
		info['begin'] = event[1]
		info['end'] = strftime("%H:%M", (localtime(event[1] + event[2])))
		info['duration'] = event[2]
		info['title'] = filterName(event[3], encode)
		info['shortdesc'] = convertDesc(event[4], encode)
		info['longdesc'] = convertDesc(event[5], encode)
		info['channel'] = filterName(event[6], encode)
		info['sref'] = event[7]
		info['genre'], info['genreid'] = convertGenre(event[8])
		info['picon'] = getPicon(event[7])
		info['timer'] = getTimerEventStatus(event, eventLookupTable, None)
		info['link'] = getIPTVLink(event[7])
		break
	return {'event': info} def loadEpg():
	epgcache = eEPGCache.getInstance()
	epgcache.load()
	return {
		"result": True,
		"message": ""
	} def saveEpg():
	epgcache = eEPGCache.getInstance()
	epgcache.save()
	return {
		"result": True,
		"message": ""
	} def getServiceRef(name, searchinBouquetsOnly=False, bRef=None):
	# TODO Radio
	# TODO bRef

	sfulllist = []
	serviceHandler = eServiceCenter.getInstance()
	if searchinBouquetsOnly:
		s_type = service_types_tv
		s_type2 = "bouquets.tv"
	#		if stype == "radio":
	#			s_type = service_types_radio
	#			s_type2 = "bouquets.radio"
		if bRef is None:
			services = serviceHandler.list(eServiceReference('%s FROM BOUQUET "%s" ORDER BY bouquet' % (s_type, s_type2)))
			bouquets = services and services.getContent("SN", True)
			bouquets = removeHiddenBouquets(bouquets)

		for bouquet in bouquets:
			serviceslist = serviceHandler.list(eServiceReference(bouquet[0]))
			sfulllist = serviceslist and serviceslist.getContent("SN", True)
			for sv in sfulllist:
				if sv[1] == name:
					return {
						"result": True,
						"sRef": sv[0]
					}

	else:
		refstr = '%s ORDER BY name' % (service_types_tv)
		serviceslist = serviceHandler.list(eServiceReference(refstr))
		sfulllist = serviceslist and serviceslist.getContent("SN", True)
		for sv in sfulllist:
			if sv[1] == name:
				return {
					"result": True,
					"sRef": sv[0]
				}

	return {
		"result": True,
		"sRef": ""
	} def getPicon(sname, pp=None, defaultpicon=True):

	if pp is None:
		pp = PICON_PATH
	if pp is not None:
		# remove URL part
		if ("://" in sname) or ("%3a//" in sname) or ("%3A//" in sname):
			cname = unquote(sname.split(":")[-1])
			sname = unquote(sname)
			# sname = ":".join(sname.split(":")[:10]) -> old way
			sname = ":".join(sname.split("://")[:1])
			sname = GetWithAlternative(sname)
			if PY3:
				cname = unicodedata.normalize('NFKD', cname)
			else:
				cname = unicodedata.normalize('NFKD', six.text_type(cname, 'utf_8', errors='ignore')).encode('ASCII', 'ignore')
			cname = re.sub('[^a-z0-9]', '', cname.replace('&', 'and').replace('+', 'plus').replace('*', 'star').replace(':', '').lower())
			# picon by channel name for URL
			if len(cname) > 0 and fileExists(pp + cname + ".png"):
				return "/picon/" + cname + ".png"
			if len(cname) > 2 and cname.endswith('hd') and fileExists(pp + cname[:-2] + ".png"):
				return "/picon/" + cname[:-2] + ".png"
			if len(cname) > 5:
				series = re.sub(r's[0-9]*e[0-9]*$', '', cname)
				if fileExists(pp + series + ".png"):
					return "/picon/" + series + ".png"

		sname = GetWithAlternative(sname)
		if sname is not None:
			pos = sname.rfind(':')
		else:
			return "/images/default_picon.png"
		cname = None
		if pos != -1:
			cname = ServiceReference(sname[:pos].rstrip(':')).getServiceName()
			sname = sname[:pos].rstrip(':').replace(':', '_') + ".png"
		filename = pp + sname
		if fileExists(filename):
			return "/picon/" + sname
		fields = sname.split('_', 8)
		if len(fields) > 7 and not fields[6].endswith("0000"):
			# remove "sub-network" from namespace
			fields[6] = fields[6][:-4] + "0000"
			sname = '_'.join(fields)
			filename = pp + sname
			if fileExists(filename):
				return "/picon/" + sname
		if len(fields) > 1 and fields[0] != '1':
			# fallback to 1 for other reftypes
			fields[0] = '1'
			sname = '_'.join(fields)
			filename = pp + sname
			if fileExists(filename):
				return "/picon/" + sname
		if len(fields) > 3 and fields[2] != '1':
			# fallback to 1 for tv services with nonstandard servicetypes
			fields[2] = '1'
			sname = '_'.join(fields)
			filename = pp + sname
			if fileExists(filename):
				return "/picon/" + sname
		if cname is not None:  # picon by channel name
			cname1 = filterName(cname).replace('/', '_')
			if not PY3:
				cname1 = cname1.encode('utf-8', 'ignore')

			if fileExists(pp + cname1 + ".png"):
				return "/picon/" + cname1 + ".png"
			if PY3:
				cname = unicodedata.normalize('NFKD', cname)
			else:
				cname = unicodedata.normalize('NFKD', six.text_type(cname, 'utf_8', errors='ignore')).encode('ASCII', 'ignore')
			cname = re.sub('[^a-z0-9]', '', cname.replace('&', 'and').replace('+', 'plus').replace('*', 'star').lower())
			if len(cname) > 0:
				filename = pp + cname + ".png"
			if fileExists(filename):
				return "/picon/" + cname + ".png"
			if len(cname) > 2 and cname.endswith('hd') and fileExists(pp + cname[:-2] + ".png"):
				return "/picon/" + cname[:-2] + ".png"
	if defaultpicon:
		return "/images/default_picon.png"
	else:
		return None def getVolumeStatus():
	owebif_vctrl = VolumeControl.instance
	return {
		"result": True,
		"message": "Status",
		"current": owebif_vctrl.volctrl.getVolume(),
		"ismute": owebif_vctrl.volctrl.isMuted()
	} def setVolumeUp():
	owebif_vctrl = VolumeControl.instance
	owebif_vctrl.volUp()
	ret = getVolumeStatus()
	ret["message"] = "Volume changed"
	return ret def setVolumeDown():
	owebif_vctrl = VolumeControl.instance
	owebif_vctrl.volDown()
	ret = getVolumeStatus()
	ret["message"] = "Volume changed"
	return ret def setVolumeMute():
	owebif_vctrl = VolumeControl.instance
	owebif_vctrl.volMute()
	ret = getVolumeStatus()
	ret["message"] = "Mute toggled"
	return ret def setVolume(value):
	owebif_vctrl = VolumeControl.instance
	owebif_vctrl.volumeDialog.show()
	if value < 0:
		value = 0
	if value > 100:
		value = 100
	owebif_vctrl.volctrl.setVolume(value, value)
	owebif_vctrl.volSave()
	owebif_vctrl.volumeDialog.setValue(value)
	owebif_vctrl.hideVolTimer.start(3000, True)
	ret = getVolumeStatus()
	ret["message"] = "Volume set to %i" % value
	return ret def zapService(session, id, title="", stream=False):
	if checkIsQPiP():
		return {
			"result": False,
			"message": "Can not zap service in quad PiP mode."
		}

	# Must NOT unquote id here, breaks zap to streams
	service = eServiceReference(id)

	if len(title) > 0:
		service.setName(title)
	else:
		title = id

	isRecording = service.getPath()
	isRecording = isRecording and isRecording.startswith("/")

	if not isRecording:
		if config.ParentalControl.servicepinactive.value and config.OpenWebif.parentalenabled.value:
			if getProtection(service.toString()) != "0":
				return {
					"result": False,
					"message": "Service '%s' is blocked by parental Control" % title
				}

	# use mediaplayer for recording
	if isRecording:
		if isinstance(session.current_dialog, InfoBar):
			session.open(MoviePlayer, service)
		else:
			session.nav.playService(service)
	else:
		if isinstance(session.current_dialog, MoviePlayer):
			session.current_dialog.lastservice = service
			session.current_dialog.close()
		from Screens.Standby import inStandby
		if inStandby is None:
			zapInServiceList(service)
		else:
			if stream:
				stop_text = ""
				if session.nav.getCurrentlyPlayingServiceReference() and isPlayableForCur(service):
					session.nav.stopService()
					stop_text = ": simple stop current service"
				return {
					"result": True,
					"message": "For stream don't need zap in standby %s" % stop_text
				}
			else:
				session.nav.playService(service)

	return {
		"result": True,
		"message": "Active service is now '%s'" % title
	} def remoteControl(key, type="", rcu=DEFAULT_RCU):
	remotetype = "dreambox remote control (native)"
	if rcu == "advanced":
		remotetype = "dreambox advanced remote control (native)"
	elif rcu == "keyboard":
		remotetype = "dreambox ir keyboard"

	amap = eActionMap.getInstance()

	if type == "text" and rcu != "":
		message = "RC command text not supported"
		result = False
		if setPrevAsciiCode:
			for k in unquote(rcu):
				setPrevAsciiCode(ord(k))
				amap.keyPressed(remotetype, 510, 0)
				amap.keyPressed(remotetype, 510, 1)
			message = "RC command text '%s' has been issued" % str(rcu)
			result = True
		return {
			"result": result,
			"message": message
		}
	elif type == "long":
		amap.keyPressed(remotetype, key, 0)
		amap.keyPressed(remotetype, key, 3)
	elif type == "ascii":
		amap.keyPressed(remotetype, key, 4)
	else:
		amap.keyPressed(remotetype, key, 0)

	amap.keyPressed(remotetype, key, 1)
	return {
		"result": True,
		"message": "RC command '%s' has been issued" % str(key)
	} def setPowerState(session, state):
	from Screens.Standby import Standby, TryQuitMainloop, inStandby
	state = int(state)

	if state == 0:  # Toggle StandBy
		if inStandby is None:
			session.open(Standby)
		else:
			inStandby.Power()
	elif state == 1:  # DeepStandBy
		session.open(TryQuitMainloop, state)
	elif state == 2:  # Reboot
		session.open(TryQuitMainloop, state)
	elif state == 3:  # Restart Enigma
		session.open(TryQuitMainloop, state)
	elif state == 4:  # Wakeup
		if inStandby is not None:
			inStandby.Power()
	elif state == 5:  # Standby
		if inStandby is None:
			session.open(Standby)

	elif state == 6:
		print("HAHA")

	return {
		"result": True,
		"instandby": inStandby is not None
	} def getStandbyState(session):
	from Screens.Standby import inStandby
	return {
		"result": True,
		"instandby": inStandby is not None
	} def sendMessage(session, message, ttype, timeout):
	global lastreply
	ttype = MessageMapping.get(ttype, MessageBox.TYPE_INFO)

	if ttype == MessageBox.TYPE_YESNO:
		lastreply = None
		session.openWithCallback(messageReply, MessageBox, message, type=ttype, timeout=timeout)
	else:
		session.open(MessageBox, message, type=ttype, timeout=timeout)

	return {
		"result": True,
		"message": _('Message sent successfully!')
	} def getMessageAnswer():
	global lastreply
	reply = lastreply

	if reply is None:
		return {
			"result": False,
			"message": _('No answer in time')
		}

	return {
		"result": True,
		"message": _('Answer is YES!') if reply else _('Answer is NO!')
	} def getSettings():
	configkeyval = []
	privSettingValues("config", config.saved_value, configkeyval)
	return {
		"result": True,
		"settings": configkeyval
	} def addCollapsedMenu(name):
	tags = config.OpenWebif.webcache.collapsedmenus.value.split("|")
	if name not in tags:
		tags.append(name)

	config.OpenWebif.webcache.collapsedmenus.value = "|".join(tags).strip("|")
	config.OpenWebif.webcache.collapsedmenus.save()

	return {
		"result": True
	} def removeCollapsedMenu(name):
	tags = config.OpenWebif.webcache.collapsedmenus.value.split("|")
	if name in tags:
		tags.remove(name)

	config.OpenWebif.webcache.collapsedmenus.value = "|".join(tags).strip("|")
	config.OpenWebif.webcache.collapsedmenus.save()

	return {
		"result": True
	} def saveConfig(path, value):
	try:
		cnf = get_config_attribute(path, root_obj=config)
	except Exception as exc:
		print("[OpenWebif] ", exc)
		return {
			"result": False,
			"message": "I'm sorry Dave, I'm afraid I can't do that"
		}

	try:
		if cnf.__class__.__name__ in ("ConfigBoolean", "ConfigEnableDisable", "ConfigYesNo"):
			cnf.value = value == "true"
		elif cnf.__class__.__name__ == "ConfigSet":
			values = cnf.value
			if int(value) in values:
				values.remove(int(value))
			else:
				values.append(int(value))
			cnf.value = values
		elif cnf.__class__.__name__ == "ConfigNumber":
			cnf.value = int(value)
		elif cnf.__class__.__name__ in ("ConfigInteger", "TconfigInteger"):
			cnf_min = int(cnf.limits[0][0])
			cnf_max = int(cnf.limits[0][1])
			cnf_value = int(value)
			if cnf_value < cnf_min:
				cnf_value = cnf_min
			elif cnf_value > cnf_max:
				cnf_value = cnf_max
			cnf.value = cnf_value
		elif cnf.__class__.__name__ in ("ConfigSlider"):
			cnf_min = int(cnf.min)
			cnf_max = int(cnf.max)
			cnf_value = int(value)
			if cnf_value < cnf_min:
				cnf_value = cnf_min
			elif cnf_value > cnf_max:
				cnf_value = cnf_max
			cnf.value = cnf_value
		else:
			cnf.value = value
		cnf.save()
		configfiles.reload()
	except Exception as e:
		print("[OpenWebif] ", e)
		return {
			"result": False
		}

	return {
		"result": True
	} def getConfigs(key):
	configs = []
	title = None
	if not len(configfiles.sections):
		configfiles.parseConfigFiles()
	if key in configfiles.section_config:
		config_entries = configfiles.section_config[key][1]
		title = configfiles.section_config[key][0]
	if config_entries:
		for entry in config_entries:
			try:
				data = getJsonFromConfig(eval(entry.text or ""))  # nosec
				if data is None:
					continue
				# print("[OpenWebif] -D- config entry: ", entry.text)
				text = _(entry.get("text", ""))
				if "limits" in data:
					text = "%s (%d - %d)" % (text, data["limits"][0], data["limits"][1])
				configs.append({
					"description": text,
					"path": entry.text or "",
					"data": data
				})
			except Exception:
				pass
	return {
		"result": True,
		"configs": configs,
		"title": title,
		"key": key
	} def getConfigsSections():
	if not len(configfiles.sections):
		configfiles.parseConfigFiles()
	return {
		"result": True,
		"sections": configfiles.sections
	} def getUtcOffset():
	now = time.time()
	offset = (datetime.fromtimestamp(now) - datetime.utcfromtimestamp(now)).total_seconds()
	hours = round(offset / 3600)
	minutes = (offset - (hours * 3600))
	return {
		"result": True,
		# round minutes to next quarter hour
		"utcoffset": "{:+05}".format(int(hours * 100 + (round(minutes / 900) * 900 / 60)))
	} def getStream(session, request, m3ufile):
	sRef = getUrlArg(request, "ref")
	if sRef != None:
		if PY3:
			sRef = unquote(unquote(sRef))
		else:
			sRef = unquote(unquote(request.args["ref"][0]).decode('utf-8', 'ignore')).encode('utf-8')
	else:
		sRef = ""

	currentServiceRef = None
	if m3ufile == "streamcurrent.m3u":
		currentServiceRef = session.nav.getCurrentlyPlayingServiceReference()
		sRef = currentServiceRef.toString()

	if sRef.startswith("1:134:"):
		if currentServiceRef is None:
			currentServiceRef = session.nav.getCurrentlyPlayingServiceReference()
		if currentServiceRef is None:
			currentServiceRef = eServiceReference()
		ref = getBestPlayableServiceReference(eServiceReference(sRef), currentServiceRef)
		if ref is None:
			sRef = ""
		else:
			sRef = ref.toString()

	# #EXTINF:-1,%s\n adding back to show service name in programs like VLC
	progopt = ''
	name = getUrlArg(request, "name")
	if name != None:
		if config.OpenWebif.service_name_for_stream.value:
			progopt = "#EXTINF:-1,%s\n" % name

	name = "stream"
	portNumber = config.OpenWebif.streamport.value
	info = getInfo()
	model = info["model"]
	machinebuild = info["machinebuild"]
	urlparam = '?'
	if info["imagedistro"] in ('openpli', 'satdreamgr', 'openvision'):
		urlparam = '&'
	transcoder_port = None
	args = ""

	device = getUrlArg(request, "device")

	if fileExists("/dev/bcm_enc0"):
		try:
			transcoder_port = int(config.plugins.transcodingsetup.port.value)
		except Exception:
			# Transcoding Plugin is not installed or your STB does not support transcoding
			transcoder_port = None
		if device == "phone":
			portNumber = transcoder_port
		_port = getUrlArg(request, "port")
		if _port != None:
			portNumber = _port
	elif fileExists("/dev/encoder0") or fileExists("/proc/stb/encoder/0/apply"):
		transcoder_port = portNumber

	if fileExists("/dev/bcm_enc0") or fileExists("/dev/encoder0") or fileExists("/proc/stb/encoder/0/apply"):
		if device == "phone":
			try:
				bitrate = config.plugins.transcodingsetup.bitrate.value
				resolution = config.plugins.transcodingsetup.resolution.value
				(width, height) = tuple(resolution.split('x'))
				# framerate = config.plugins.transcodingsetup.framerate.value
				aspectratio = config.plugins.transcodingsetup.aspectratio.value
				interlaced = config.plugins.transcodingsetup.interlaced.value
				if fileExists("/proc/stb/encoder/0/vcodec"):
					vcodec = config.plugins.transcodingsetup.vcodec.value
					args = "?bitrate=%s__width=%s__height=%s__vcodec=%s__aspectratio=%s__interlaced=%s" % (bitrate, width, height, vcodec, aspectratio, interlaced)
				else:
					args = "?bitrate=%s__width=%s__height=%s__aspectratio=%s__interlaced=%s" % (bitrate, width, height, aspectratio, interlaced)
				args = args.replace('__', urlparam)
			except Exception:
				pass

	# When you use EXTVLCOPT:program in a transcoded stream, VLC does not play stream
	if config.OpenWebif.service_name_for_stream.value and sRef != '' and portNumber != transcoder_port:
		progopt = "%s#EXTVLCOPT:program=%d\n" % (progopt, int(sRef.split(':')[3], 16))

	if config.OpenWebif.auth_for_streaming.value:
		asession = GetSession()
		if asession.GetAuth(request) is not None:
			auth = ':'.join(asession.GetAuth(request)) + "@"
		else:
			auth = '-sid:' + str(asession.GetSID(request)) + "@"
	else:
		auth = ''

	response = "#EXTM3U \n#EXTVLCOPT:http-reconnect=true \n%shttp://%s%s:%s/%s%s\n" % (progopt, auth, request.getRequestHostname(), portNumber, sRef, args)
	if config.OpenWebif.playiptvdirect.value:
		if "http://" in sRef or "https://" in sRef:
			l = sRef.split(":http")[1]
			response = "#EXTM3U \n#EXTVLCOPT:http-reconnect=true\n%shttp%s\n" % (progopt, l)
	request.setHeader('Content-Type', 'application/x-mpegurl')
	# Note: do not rename the m3u file all the time
	fname = getUrlArg(request, "fname")
	if fname != None:
		request.setHeader('Content-Disposition', 'inline; filename=%s.%s;' % (fname, 'm3u8'))
	return response def getTS(self, request):
	file = getUrlArg(request, "file")
	if file != None:
		if PY3:
			filename = unquote(file)
		else:
			filename = unquote(file).decode('utf-8', 'ignore').encode('utf-8')
		if not os.path.exists(filename):
			return "File '%s' not found" % (filename)

# ServiceReference is not part of filename so look in the '.ts.meta' file
		sRef = ""
		progopt = ''

		if os.path.exists(filename + '.meta'):
			metafile = open(filename + '.meta', "r")
			name = ''
			seconds = -1  # unknown duration default
			line = metafile.readline()  # service ref
			if line:
				sRef = eServiceReference(line.strip()).toString()
			line2 = metafile.readline()  # name
			if line2:
				name = line2.strip()
			line6 = metafile.readline()  # description
			line6 = metafile.readline()  # recording time
			line6 = metafile.readline()  # tags
			line6 = metafile.readline()  # length

			if line6:
				seconds = float(line6.strip()) / 90000  # In seconds

			if config.OpenWebif.service_name_for_stream.value:
				progopt = "%s#EXTINF:%d,%s\n" % (progopt, seconds, name)

			metafile.close()

		portNumber = None
		proto = 'http'
		info = getInfo()
		model = info["model"]
		machinebuild = info["machinebuild"]
		transcoder_port = None
		args = ""
		urlparam = '?'
		if info["imagedistro"] in ('openpli', 'satdreamgr', 'openvision'):
			urlparam = '&'

		device = getUrlArg(request, "device")

		if fileExists("/dev/bcm_enc0") or fileExists("/dev/encoder0") or fileExists("/proc/stb/encoder/0/apply"):
			try:
				transcoder_port = int(config.plugins.transcodingsetup.port.value)
			except Exception:
				# Transcoding Plugin is not installed or your STB does not support transcoding
				transcoder_port = None
			if device == "phone":
				portNumber = transcoder_port
			_port = getUrlArg(request, "port")
			if _port != None:
				portNumber = _port

		if fileExists("/dev/bcm_enc0") or fileExists("/dev/encoder0") or fileExists("/proc/stb/encoder/0/apply"):
			if device == "phone":
				try:
					bitrate = config.plugins.transcodingsetup.bitrate.value
					resolution = config.plugins.transcodingsetup.resolution.value
					(width, height) = tuple(resolution.split('x'))
					# framerate = config.plugins.transcodingsetup.framerate.value
					aspectratio = config.plugins.transcodingsetup.aspectratio.value
					interlaced = config.plugins.transcodingsetup.interlaced.value
					if fileExists("/proc/stb/encoder/0/vcodec"):
						vcodec = config.plugins.transcodingsetup.vcodec.value
						args = "?bitrate=%s__width=%s__height=%s__vcodec=%s__aspectratio=%s__interlaced=%s" % (bitrate, width, height, vcodec, aspectratio, interlaced)
					else:
						args = "?bitrate=%s__width=%s__height=%s__aspectratio=%s__interlaced=%s" % (bitrate, width, height, aspectratio, interlaced)
					args = args.replace('__', urlparam)
				except Exception:
					pass
			# Add position parameter to m3u link
			position = getUrlArg(request, "position")
			if position != None:
				args = args + "&position=" + position

		# When you use EXTVLCOPT:program in a transcoded stream, VLC does not play stream
		if config.OpenWebif.service_name_for_stream.value and sRef != '' and portNumber != transcoder_port:
			progopt = "%s#EXTVLCOPT:program=%d\n" % (progopt, int(sRef.split(':')[3], 16))

		if portNumber is None:
			portNumber = config.OpenWebif.port.value
			if request.isSecure():
				portNumber = config.OpenWebif.https_port.value
				proto = 'https'
			ourhost = request.getHeader('host')
			m = re.match('.+\:(\d+)$', ourhost)
			if m is not None:
				portNumber = m.group(1)

		if config.OpenWebif.auth_for_streaming.value:
			asession = GetSession()
			if asession.GetAuth(request) is not None:
				auth = ':'.join(asession.GetAuth(request)) + "@"
			else:
				auth = '-sid:' + str(asession.GetSID(request)) + "@"
		else:
			auth = ''

		response = "#EXTM3U \n#EXTVLCOPT:http-reconnect=true \n%s%s://%s%s:%s/file?file=%s%s\n" % ((progopt, proto, auth, request.getRequestHostname(), portNumber, quote(filename), args))
		request.setHeader('Content-Type', 'application/x-mpegurl')
		return response
	else:
		return "Missing file parameter" def getStreamSubservices(session, request):
	services = []
	currentServiceRef = session.nav.getCurrentlyPlayingServiceReference()

	# TODO : this will only work if sref = current channel
	# the DMM webif can also show subservices for other channels like the current
	# ideas are welcome

	sRef = getUrlArg(request, "sRef")
	if sRef != None:
		currentServiceRef = eServiceReference(sRef)

	if currentServiceRef is not None:
		currentService = session.nav.getCurrentService()
		subservices = currentService.subServices()

		services.append({
			"servicereference": currentServiceRef.toString(),
			"servicename": ServiceReference(currentServiceRef).getServiceName()
		})
		if subservices and subservices.getNumberOfSubservices() != 0:
			n = subservices and subservices.getNumberOfSubservices()
			z = 0
			while z < n:
				sub = subservices.getSubservice(z)
				services.append({
					"servicereference": sub.toString(),
					"servicename": sub.getName()
				})
				z += 1
	else:
		services.append = ({
			"servicereference": "N/A",
			"servicename": "N/A"
		})

	return {"services": services} class GetSession(Resource):
	def GetSID(self, request):
		sid = request.getSession().uid
		return sid

	def GetAuth(self, request):
		session = request.getSession().sessionNamespaces
		if "pwd" in list(session.keys()) and session["pwd"] is not None:
			return (session["user"], session["pwd"])
		else:
			return None def mediaPlayerAdd(session, filename):
	mp = getOrCreateMpInstance(session)
	if mp is None:
		return {
			"result": False,
			"message": "Mediaplayer not installed"
		}

	if fileExists(filename):
		service = eServiceReference(4097, 0, filename)
	else:
		service = eServiceReference(filename)

	if not service.valid():
		return {
			"result": False,
			"message": "'%s' is neither a valid reference nor a valid file" % filename
		}

	mp.playlist.addFile(service)
	mp.playlist.updateList()

	return {
		"result": True,
		"message": "'%s' has been added to playlist" % filename
	} def mediaPlayerRemove(session, filename):
	mp = getOrCreateMpInstance(session)
	if mp is None:
		return {
			"result": False,
			"message": "Mediaplayer not installed"
		}

	service = eServiceReference(filename)
	if not service.valid():
		service = eServiceReference(4097, 0, filename)

	if not service.valid():
		return {
			"result": False,
			"message": "'%s' is neither a valid reference nor a valid file" % filename
		}

	count = 0
	removed = False
	for item in mp.playlist.getServiceRefList():
		if item == service:
			mp.playlist.deleteFile(count)
			removed = True
			break
		count += 1

	if not removed:
		return {
			"result": False,
			"message": "'%s' not found in playlist" % filename
		}

	mp.playlist.updateList()
	return {
		"result": True,
		"message": "'%s' removed from playlist" % filename
	} def mediaPlayerPlay(session, filename, root):
	mp = getOrCreateMpInstance(session)
	if mp is None:
		return {
			"result": False,
			"message": "Mediaplayer not installed"
		}

	if fileExists(filename):
		service = eServiceReference(4097, 0, filename)
	else:
		service = eServiceReference(filename)

	if not service.valid():
		return {
			"result": False,
			"message": "'%s' is neither a valid reference nor a valid file" % filename
		}

	if root != "playlist":
		mp.playlist.addFile(service)
		mp.playlist.updateList()

	mp.playServiceRefEntry(service)

	return {
		"result": True,
		"message": "'%s' has been added to playlist" % filename
	} def mediaPlayerCommand(session, command):
	mp = getMpInstance(session)
	if mp is None:
		return {
			"result": False,
			"message": "Mediaplayer not active"
		}

	if command == "play":
		mp.playEntry()
	elif command == "pause":
		mp.pauseEntry()
	elif command == "stop":
		mp.stopEntry()
	elif command == "next":
		mp.nextEntry()
	elif command == "previous":
		mp.previousMarkOrEntry()
	elif command == "shuffle":
		mp.playlist.PlayListShuffle()
	elif command == "clear":
		mp.clear_playlist()
	elif command == "exit":
		mp.exit()
	else:
		return {
			"result": False,
			"message": "Unknown parameter %s" % command
		}
	return {
		"result": True,
		"message": "Command '%s' executed" % command
	} def mediaPlayerCurrent(session):
	mp = getMpInstance(session)
	if mp is None:
		return {
			"result": False,
			"message": "Mediaplayer not active"
		}
	return {
		"result": True,
		"artist": mp["artist"].getText(),
		"title": mp["title"].getText(),
		"album": mp["album"].getText(),
		"year": mp["year"].getText(),
		"genre": mp["genre"].getText(),
		"coverArt": mp["coverArt"].coverArtFileName
	} def mediaPlayerList(session, path, types):
	if types == "video":
		mpattern = "(?i)^.*\.(ts|mts|m2ts|e2pls|mpg|vob|avi|divx|m4v|mkv|mp4|dat|flv|mov|dts)"
		mserviceref = True
	elif types == "audio":
		mserviceref = True
		mpattern = "(?i)^.*\.(mp2|mp3|ogg|wav|wave|m3u|pls|e2pls|m4a|flac)"
	elif types == "any" or types == "":
		mserviceref = True
		# complete pattern from mediaplayer
		mpattern = "(?i)^.*\.(mp2|mp3|ogg|ts|mts|m2ts|wav|wave|m3u|pls|e2pls|mpg|vob|avi|divx|m4v|mkv|mp4|m4a|dat|flac|flv|mov|dts)"
	else:
		mserviceref = False
		mpattern = types

	rpath = path
	if rpath == "":
		rpath = None

	if rpath == "playlist":
		mp = getOrCreateMpInstance(session)
		if mp is None:
			return {
				"result": False,
				"files": []
			}
		files = []
		for service in mp.playlist.getServiceRefList():
			files.append({
				"servicereference": service.getPath(),
				"isdirectory": False,
				"root": "playlist"
			})
		return {
			"result": True,
			"files": files
		}
	elif rpath is None or os.path.isdir(rpath):
		files = []
		filelist = FileList(rpath, matchingPattern=mpattern, useServiceRef=mserviceref, additionalExtensions="4098:m3u 4098:e2pls 4098:pls")
		for item in filelist.getFileList():
			if item[0][1]:
				files.append({
					"servicereference": item[0][0],
					"isdirectory": item[0][1],
					"root": rpath
				})
			elif mserviceref:
				files.append({
					"servicereference": item[0][0].toString(),
					"isdirectory": item[0][1],
					"root": rpath
				})
			else:
				files.append({
					"servicereference": path + item[0][0],
					"isdirectory": item[0][1],
					"root": rpath
				})

		return {
			"result": True,
			"files": files
		}

	return {
		"result": False,
		"files": []
	} def mediaPlayerLoad(session, filename):
	mp = getOrCreateMpInstance(session)
	if mp is None:
		return {
			"result": False,
			"message": "Mediaplayer not installed"
		}

	path = resolveFilename(SCOPE_PLAYLIST, filename)
	if not fileExists(path):
		return {
			"result": False,
			"message": "Playlist '%s' does not exist" % path
		}

	mp.PlaylistSelected((filename, path))
	return {
		"result": True,
		"message": "Playlist loaded from '%s'" % path
	} def mediaPlayerSave(session, filename):
	mp = getOrCreateMpInstance(session)
	if mp is None:
		return {
			"result": False,
			"message": "Mediaplayer not installed"
		}

	path = resolveFilename(SCOPE_PLAYLIST, filename)
	mp.playlistIOInternal.save(path)
	return {
		"result": True,
		"message": "Playlist saved to '%s'" % path
	} def mediaPlayerFindFile(session, path, pattern):
	rfiles = []
	for root, dirs, files in os.walk(path):
		for filename in fnmatch.filter(files, pattern):
			rfiles.append({
				"name": filename,
				"path": root
			})

	return {
		"result": True,
		"files": rfiles
	} def reloadPlugins():
	plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
	return {
		"result": True,
		"message": "List of Plugins has been read"
	} class BaseController(resource.Resource):
	"""
	Web Base Controller
	"""
	isLeaf = False

	def __init__(self, path="", **kwargs):
		"""

		Args:
			* path: Base path
			* session: (?) Session instance
			* withMainTemplate: (?)
			* isJson: responses shall be JSON encoded
			* isCustom: (?)
			* isGZ: responses shall be GZIP compressed
			* isMobile: (?) responses shall be optimised for mobile devices
			* isImage: (?) responses shall image
		"""
		resource.Resource.__init__(self)

		self.path = six.ensure_str(path)
		self.session = kwargs.get("session")
		self.withMainTemplate = kwargs.get("withMainTemplate", False)
		self.isJson = kwargs.get("isJson", False)
		self.isCustom = kwargs.get("isCustom", False)
		self.isGZ = kwargs.get("isGZ", False)
		self.isMobile = kwargs.get("isMobile", False)
		self.isImage = kwargs.get("isImage", False)

	def error404(self, request):
		"""
		Perform HTTP Error 404

		Args:
			request (twisted.web.server.Request): HTTP request object

		"""
		request.setHeader("content-type", "text/html")
		request.setResponseCode(http.NOT_FOUND)
		request.write(b"<html><head><title>Open Webif</title></head><body><h1>Error 404: Page not found</h1><br />The requested URL was not found on this server.</body></html>")
		request.finish()

	def loadTemplate(self, path, module, args):
		if fileExists(getViewsPath(path + ".py")) or fileExists(getViewsPath(path + ".pyo")) or fileExists(getViewsPath(path + ".pyc")):
			if fileExists(getViewsPath(path + ".pyo")):
				template = imp.load_compiled(module, getViewsPath(path + ".pyo"))
			elif fileExists(getViewsPath(path + ".pyc")):
				template = imp.load_compiled(module, getViewsPath(path + ".pyc"))
			else:
				template = imp.load_source(module, getViewsPath(path + ".py"))
			mod = getattr(template, module, None)
			if callable(mod):
				return str(mod(searchList=args))
		elif fileExists(getViewsPath(path + ".tmpl")):
			vp = str(getViewsPath(path + ".tmpl"))
			return str(Template(file=vp, searchList=[args]))
		return None

	def putChild2(self, path, child):
		self.putChild(six.ensure_binary(path), child)

	def putGZChild(self, path, child):
		child.isGZ = True
		self.putChild(six.ensure_binary(path), EncodingResourceWrapper(child, [GzipEncoderFactory()]))

	def getChild(self, path, request):
		if self.isGZ:
			return EncodingResourceWrapper(self.__class__(self.session, path), [GzipEncoderFactory()])
		else:
			return self.__class__(self.session, path)

	def NoDataRender(self):
		return []

	def noData(self, request):
		return {}

	def render(self, request):

		@defer.inlineCallbacks
		def _showImage(data):

			@defer.inlineCallbacks
			def _setContentDispositionAndSend(file_path):
				filename = os.path.basename(file_path)
				request.setHeader('content-disposition', 'filename="%s"' % filename)
				request.setHeader('content-type', "image/png")
				f = open(file_path, "rb")
				yield FileSender().beginFileTransfer(f, request)
				f.close()
				defer.returnValue(0)

			if os.path.exists(data):
				yield _setContentDispositionAndSend(data)
			else:
				request.setResponseCode(http.NOT_FOUND)

			request.finish()
			defer.returnValue(0)

		# cache data
		withMainTemplate = self.withMainTemplate
		path = self.path
		isCustom = self.isCustom
		isMobile = self.isMobile
		isImage = self.isImage

		if self.path == "":
			self.path = "index"
		elif self.path == "signal":
			self.path = "tunersignal"
			request.uri = request.uri.replace(b'signal', b'tunersignal')
			request.path = request.path.replace(b'signal', b'tunersignal')

		self.suppresslog = False
		self.path = self.path.replace(".", "")
		if request.path.startswith(b'/api/config'):
			func = getattr(self, "P_config", None)
		elif self.path in self.NoDataRender():
			func = getattr(self, "noData", None)
		else:
			func = getattr(self, "P_" + self.path, None)

		if callable(func):
			request.setResponseCode(http.OK)

			# call prePageLoad function if exist
			plfunc = getattr(self, "prePageLoad", None)
			if callable(plfunc):
				plfunc(request)

			data = func(request)
			if data is None:
				# if not self.suppresslog:
					# print "[OpenWebif] page '%s' without content" % request.uri
				self.error404(request)
			elif self.isCustom:
				# if not self.suppresslog:
					# print "[OpenWebif] page '%s' ok (custom)" % request.uri
				request.write(six.ensure_binary(data))
				request.finish()
			elif self.isImage:
				_showImage(data)
			elif self.isJson:
				request.setHeader("content-type", "application/json; charset=utf-8")
				try:
					return six.ensure_binary(json.dumps(data, indent=1))
				except Exception as exc:
					request.setResponseCode(http.INTERNAL_SERVER_ERROR)
					return six.ensure_binary(json.dumps({"result": False, "request": request.path, "exception": repr(exc)}))
					pass
			elif isinstance(data, str):
				# if not self.suppresslog:
					# print "[OpenWebif] page '%s' ok (simple string)" % request.uri
				request.setHeader("content-type", "text/plain")
				request.write(six.ensure_binary(data))
				request.finish()
			else:
				# print "[OpenWebif] page '%s' ok (cheetah template)" % request.uri
				module = six.ensure_text(request.path)
				if module[-1:] == "/":
					module += "index"
				elif module[-5:] != "index" and self.path == "index":
					module += "/index"
				module = module.strip("/")
				module = module.replace(".", "")
				out = self.loadTemplate(module, self.path, data)
				if out is None:
					print("[OpenWebif] ERROR! Template not found for page '%s'" % request.uri)
					self.error404(request)
				else:
					if self.isMobile:
						head = self.loadTemplate('mobile/head', 'head', [])
						out = head + out
					elif self.withMainTemplate:
						args = self.prepareMainTemplate(request)
						args["content"] = out
						nout = self.loadTemplate("main", "main", args)
						if nout:
							out = nout
					elif self.isGZ:
						return out
					request.write(six.ensure_binary(out))
					request.finish()

		else:
			print("[OpenWebif] page '%s' not found" % request.uri)
			self.error404(request)

		# restore cached data
		self.withMainTemplate = withMainTemplate
		self.path = path
		self.isCustom = isCustom
		self.isMobile = isMobile
		self.isImage = isImage

		return server.NOT_DONE_YET

	def oscamconfPath(self):
		# Find and parse running oscam
		opath = None
		owebif = False
		oport = None
		variant = "oscam"
		for file in ["/tmp/.ncam/ncam.version", "/tmp/.oscam/oscam.version"]:
			if fileExists(file):  # nosec
				if "ncam" in file:
					variant = "ncam"
				else:
					variant = "oscam"

				conffile = file.split('/')[-1].replace("version", "conf")

				data = open(file, "r").readlines()  # nosec
				for i in data:
					if "configdir:" in i.lower():
						opath = i.split(":")[1].strip() + "/" + conffile
						if not fileExists(opath):
							opath = None
					elif "web interface support:" in i.lower():
						owebif = i.split(":")[1].strip()
						if owebif == "yes":
							owebif = True
					elif "webifport:" in i.lower():
						oport = i.split(":")[1].strip()
						if oport == "0":
							oport = None
					else:
						continue
		return owebif, oport, opath, variant

	def prepareMainTemplate(self, request):
		# here will be generated the dictionary for the main template
		ret = getCollapsedMenus()
		ret['configsections'] = getConfigsSections()['sections']
		ret['showname'] = getShowName()['showname']
		ret['customname'] = getCustomName()['customname']
		ret['boxname'] = getBoxName()['boxname']
		if not ret['boxname'] or not ret['customname']:
			ret['boxname'] = getInfo()['brand'] + " " + getInfo()['model']
		ret['box'] = getBoxType()
		ret["remote"] = REMOTE
		if hasattr(eEPGCache, 'FULL_DESCRIPTION_SEARCH'):
			ret['epgsearchcaps'] = True
		else:
			ret['epgsearchcaps'] = False
		extras = [{'key': 'ajax/settings', 'description': _("Settings")}]

		ip = getIP()
		if ip != None:
			if _isPluginInstalled("LCD4linux", "WebSite"):
				lcd4linux_key = "lcd4linux/config"
				if _isPluginInstalled("WebInterface"):
					try:
						lcd4linux_port = "http://" + ip + ":" + str(config.plugins.Webinterface.http.port.value) + "/"
						lcd4linux_key = lcd4linux_port + 'lcd4linux/config'
					except:  # nosec # noqa: E722
						lcd4linux_key = None
				if lcd4linux_key:
					extras.append({'key': lcd4linux_key, 'description': _("LCD4Linux Setup"), 'nw': '1'})

		oscamwebif, port, oscamconf, variant = self.oscamconfPath()

		# Assume http until we know better ...
		proto = "http"

		# config file exists
		if oscamwebif and oscamconf is not None:
			# oscam defaults to NOT to start the web interface unless a section for it exists, so reset port to None until we find one
			port = None
			data = open(oscamconf, "r").readlines()
			for i in data:
				if "httpport" in i.lower():
					port = i.split("=")[1].strip()
					if port[0] == '+':
						proto = "https"
						port = port[1:]

		if oscamwebif and port is not None:
			url = "%s://%s:%s" % (proto, request.getRequestHostname(), port)
			if variant == "oscam":
				extras.append({'key': url, 'description': _("OSCam Webinterface"), 'nw': '1'})
			elif variant == "ncam":
				extras.append({'key': url, 'description': _("NCam Webinterface"), 'nw': '1'})

		if HASAUTOTIMER:
			extras.append({'key': 'ajax/at', 'description': _('AutoTimers')})

		extras.append({'key': 'ajax/bqe', 'description': _('BouquetEditor')})

		try:
			from Plugins.Extensions.EPGRefresh.EPGRefresh import epgrefresh  # noqa: F401
			extras.append({'key': 'ajax/epgr', 'description': _('EPGRefresh')})
		except ImportError:
			pass

		try:
			# this will currenly only works if NO Webiterface plugin installed
			# TODO: test if webinterface AND openwebif installed

			# 'nw'='1' -> target _blank
			# 'nw'='2' -> target popup
			# 'nw'=None -> target _self

			# syntax
			# addExternalChild( (Link, Resource, Name, Version, HasGUI, WebTarget) )
			# example addExternalChild( ("webadmin", root, "WebAdmin", 1, True, "_self") )

			from Plugins.Extensions.WebInterface.WebChilds.Toplevel import loaded_plugins
			for plugins in loaded_plugins:
				if plugins[0] in ["fancontrol", "iptvplayer"]:
					try:
						extras.append({'key': plugins[0], 'description': plugins[2], 'nw': '2'})
					except KeyError:
						pass
				elif len(plugins) > 4:
					if plugins[4] == True:
						try:
							if len(plugins) > 5 and plugins[5] == "_self":
								extras.append({'key': plugins[0], 'description': plugins[2]})
							else:
								extras.append({'key': plugins[0], 'description': plugins[2], 'nw': '1'})
						except KeyError:
							pass

		except ImportError:
			pass

		if os.path.exists('/usr/bin/shellinaboxd'):
			extras.append({'key': 'ajax/terminal', 'description': _('Terminal')})

		ret['extras'] = extras
		theme = 'original'
		if config.OpenWebif.webcache.theme.value:
			theme = config.OpenWebif.webcache.theme.value
		if not os.path.exists(getPublicPath('themes')):
			if not (theme == 'original' or theme == 'clear'):
				theme = 'original'
				config.OpenWebif.webcache.theme.value = theme
				config.OpenWebif.webcache.theme.save()
		ret['theme'] = theme
		moviedb = config.OpenWebif.webcache.moviedb.value if config.OpenWebif.webcache.moviedb.value else EXT_EVENT_INFO_SOURCE
		config.OpenWebif.webcache.moviedb.value = moviedb
		config.OpenWebif.webcache.moviedb.save()
		ret['moviedb'] = moviedb
		imagedistro = getInfo()['imagedistro']
		ret['vti'] = "1" if imagedistro in ("VTi-Team Image") else "0"
		ret['webtv'] = os.path.exists(getPublicPath('webtv'))
		ret['stbLang'] = STB_LANG
		smallremote = config.OpenWebif.webcache.smallremote.value if config.OpenWebif.webcache.smallremote.value else 'new'
		ret['smallremote'] = smallremote
		ret['textinputsupport'] = TEXTINPUTSUPPORT
		return ret class StreamController(resource.Resource):
	def __init__(self, session, path=""):
		resource.Resource.__init__(self)
		self.session = session

	def render(self, request):
		StreamAdapter(self.session, request)
		return server.NOT_DONE_YET PICON_PATH = getPiconPath()
from Components.config import config as comp_config
from .models.info import getInfo, getCurrentTime, getStatusInfo, getFrontendStatus, testPipStatus
from .models.services import getCurrentService, getBouquets, getServices, getSubServices, getSatellites, getBouquetEpg, getBouquetNowNextEpg, getServicesNowNextEpg, getSearchEpg, getChannelEpg, getNowNextEpg, getSearchSimilarEpg, getAllServices, getPlayableServices, getPlayableService, getParentalControlList, getEvent, loadEpg, saveEpg, getServiceRef, getPicon
from .models.volume import getVolumeStatus, setVolumeUp, setVolumeDown, setVolumeMute, setVolume
from .models.audiotrack import getAudioTracks, setAudioTrack
from .models.control import zapService, remoteControl, setPowerState, getStandbyState
from .models.locations import getLocations, getCurrentLocation, addLocation, removeLocation
from .models.timers import getTimers, addTimer, addTimerByEventId, editTimer, removeTimer, toggleTimerStatus, cleanupTimer, writeTimerList, recordNow, tvbrowser, getSleepTimer, setSleepTimer, getPowerTimer, setPowerTimer, getVPSChannels
from .models.message import sendMessage, getMessageAnswer
from .models.movies import getMovieList, removeMovie, getMovieInfo, moveMovie, renameMovie, getAllMovies, getMovieDetails
from .models.config import getSettings, addCollapsedMenu, removeCollapsedMenu, saveConfig, getConfigs, getConfigsSections, getUtcOffset
from .models.stream import getStream, getTS, getStreamSubservices, GetSession
from .models.servicelist import reloadServicesLists
from .models.mediaplayer import mediaPlayerAdd, mediaPlayerRemove, mediaPlayerPlay, mediaPlayerCommand, mediaPlayerCurrent, mediaPlayerList, mediaPlayerLoad, mediaPlayerSave, mediaPlayerFindFile
from .models.plugins import reloadPlugins
from Screens.InfoBar import InfoBar
from .i18n import _
from .base import BaseController
from .stream import StreamController
from .utilities import getUrlArg
from .defaults import PICON_PATH
			from enigma import eEPGCache, eServiceReference
						from enigma import eServiceCenter
		from Plugins.Extensions.OpenWebif.httpserver import HttpdRestart
			from Plugins.Extensions.WebInterface.WebChilds.Toplevel import loaded_plugins
from Plugins.Extensions.OpenWebif.vtiaddon import expand_basecontroller  # noqa: F401
import re
import six
	def P_epgservice(self, request):
		res = self.testMandatoryArguments(request, ["sRef"])
		if res:
			return res

		begintime = -1
		if b"time" in list(request.args.keys()):
			try:
				begintime = int(request.args[b"time"][0])
			except ValueError:
				pass

		endtime = -1
		if b"endTime" in list(request.args.keys()):
			try:
				endtime = int(request.args[b"endTime"][0])
			except ValueError:
				pass
		return getChannelEpg(getUrlArg(request, "sRef"), begintime, endtime, self.isJson)

	def P_epgservicenow(self, request):
		res = self.testMandatoryArguments(request, ["sRef"])
		if res:
			return res
		return getNowNextEpg(getUrlArg(request, "sRef"), 0, self.isJson)

	def P_epgservicenext(self, request):
		res = self.testMandatoryArguments(request, ["sRef"])
		if res:
			return res
		return getNowNextEpg(getUrlArg(request, "sRef"), 1, self.isJson)

	def P_epgsimilar(self, request):
		res = self.testMandatoryArguments(request, ["sRef", "eventid"])
		if res:
			return res

		try:
			eventid = int(request.args[b"eventid"][0])
		except ValueError:
			return {
				"result": False,
				"message": "The parameter 'eventid' must be a number"
			}

		return getSearchSimilarEpg(getUrlArg(request, "sRef"), eventid, self.isJson)

	def P_event(self, request):
		sRef = getUrlArg(request, "sRef")
		if sRef == None:
			sRef = getUrlArg(request, "sref")
		event = getEvent(sRef, request.args[b"idev"][0], self.isJson)
		event['event']['recording_margin_before'] = comp_config.recording.margin_before.value
		event['event']['recording_margin_after'] = comp_config.recording.margin_after.value
		return event

	def P_getcurrent(self, request):
		"""
		Request handler for the `getcurrent` endpoint.

		.. seealso::

			https://dream.reichholf.net/e2web/#getcurrent

		Args:
			request (twisted.web.server.Request): HTTP request object
		Returns:
			HTTP response with headers


		.. http:get:: /web/getcurrent

		"""
		info = getCurrentService(self.session)
		now = getNowNextEpg(info["ref"], 0, self.isJson)
		if len(now["events"]) > 0:
			now = now["events"][0]
			now["provider"] = info["provider"]
		else:
			now = {
				"id": 0,
				"begin_timestamp": 0,
				"duration_sec": 0,
				"title": "",
				"shortdesc": "",
				"longdesc": "",
				"sref": "",
				"sname": "",
				"now_timestamp": 0,
				"remaining": 0,
				"provider": "",
				"genre": "",
				"genreid": 0
			}
		next = getNowNextEpg(info["ref"], 1, self.isJson)
		if len(next["events"]) > 0:
			next = next["events"][0]
			next["provider"] = info["provider"]
		else:
			next = {
				"id": 0,
				"begin_timestamp": 0,
				"duration_sec": 0,
				"title": "",
				"shortdesc": "",
				"longdesc": "",
				"sref": "",
				"sname": "",
				"now_timestamp": 0,
				"remaining": 0,
				"provider": "",
				"genre": "",
				"genreid": 0
			}
		# replace EPG NOW with Movie info
		mnow = now
		if mnow["sref"].startswith('1:0:0:0:0:0:0:0:0:0:/') or mnow["sref"].startswith('4097:0:0:0:0:0:0:0:0:0:/'):
			try:
				service = self.session.nav.getCurrentService()
				minfo = service and service.info()

				movie = minfo and minfo.getEvent(0)