7 changed files with 0 additions and 1501 deletions
			
			
		| @ -1,3 +0,0 @@ | |||
| type=4 | |||
| name=LocalTV | |||
| desc=LocalTV | |||
| @ -1,681 +0,0 @@ | |||
| --[[ | |||
| 	LocalTV Plugin | |||
| 	Copyright (C) 2015,  Jacek Jendrzej 'satbaby', Janus, flk | |||
| 	Slovak translate: EnoSat | |||
| 	Czech translate: marecek29 | |||
| 
 | |||
| 	License: GPL | |||
| 
 | |||
| 	This program is free software; you can redistribute it and/or | |||
| 	modify it under the terms of the GNU General Public | |||
| 	License as published by the Free Software Foundation; either | |||
| 	version 2 of the License, or (at your option) any later version. | |||
| 
 | |||
| 	This program is distributed in the hope that it will be useful, | |||
| 	but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | |||
| 	General Public License for more details. | |||
| 
 | |||
| 	You should have received a copy of the GNU General Public | |||
| 	License along with this program; if not, write to the | |||
| 	Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, | |||
| 	Boston, MA  02110-1301, USA. | |||
| ]] | |||
| 
 | |||
| local conf = {} | |||
| local g = {} | |||
| local ListeTab = {} | |||
| local n = neutrino() | |||
| 
 | |||
| local u="ubouquets" | |||
| local b="bouquets" | |||
| local localtv_version="LocalTV 0.22" | |||
| function __LINE__() return debug.getinfo(2, 'l').currentline end | |||
| 
 | |||
| locale = {} | |||
| locale["deutsch"] = { | |||
| 	create_error = "Liste konnte nicht erstellt werden.", | |||
| 	patient = "Bitte warten ...", | |||
| 	Error = "Fehler", | |||
| 	fover = "Favoriten durch erstellte Bouquets ersetzen", | |||
| 	fno = "Favoriten nicht ändern", | |||
| 	fadd = "Erstellte Bouquets zu deiner Favoritenliste hinzufügen ", | |||
| 	on = "ein", | |||
| 	off = "aus", | |||
| 	favoption = "Erstellte Bouquets zu den Favoriten hinzufügen, überschreiben oder unverändert lassen", | |||
| 	dirnotwrit = "Verzeichnis nicht beschreibbar", | |||
| 	saved = " wurde gespeichert", | |||
| 	notdef = "Nicht definiert", | |||
| 	askoverwrit = "Die existierende Datei überschreiben ?", | |||
| 	isavailable = " ist vorhanden", | |||
| 	list = "Liste ", | |||
| 	info = "Information", | |||
| 	savelist = "Speichere Liste", | |||
| 	savelisthint = "Speichert die Liste unter ", | |||
| 	keyboardhint = "Unter welchem Namen soll die Liste gespeichert werden", | |||
| 	listsaveto = "In welchem Verzeichnis soll die Liste gespeichert werden ?", | |||
| 	directory = "Verzeichnis", | |||
| 	directory_hint = "Verzeichnis wählen, in dem das Favoriten bin-Paket erstellt werden soll", | |||
| 	createlist = "Erstelle Liste", | |||
| 	createlisthint = "Die Liste erstellen", | |||
| 	onoffhint = "Erstelle Auswahlliste mit 'ein' oder 'aus'", | |||
| 	provhint = "Liste aus Favoriten- oder Anbieterbouquets", | |||
| 	select = "Auswahl vorbelegen mit", | |||
| 	saveonoff = " speichern ? Ein/Aus", | |||
| 	deflinkpath = "Symlinks im Var-Bereich", | |||
| 	deflinkpathhint="Sollen alle Logo links zu /var/tuxbox/icons/logo führen ?" | |||
| } | |||
| locale["english"] = { | |||
| 	create_error = "List could not be created.", | |||
| 	patient = "Please be patient.", | |||
| 	Error = "Error", | |||
| 	fover = "Replace favorites by created bouquets", | |||
| 	fno = "Favorites do not change", | |||
| 	fadd = "Created bouquets Add to My Favorites List ", | |||
| 	on = "on", | |||
| 	off = "off", | |||
| 	favoption = "Created Bouquets bookmark, overwrite or leave unchanged", | |||
| 	dirnotwrit = "Directory not writable", | |||
| 	saved = " has been saved", | |||
| 	notdef = "Not defined", | |||
| 	askoverwrit = "Overwrite existing file ?", | |||
| 	isavailable = " is available", | |||
| 	list = "List ", | |||
| 	info = "Information", | |||
| 	savelist = "Save list", | |||
| 	savelisthint = "Saves the list under ", | |||
| 	keyboardhint = "Under what name the list is to be saved", | |||
| 	listsaveto = "In which directory list to be saved ?", | |||
| 	directory = "Directory", | |||
| 	createlist = "Create List", | |||
| 	directory_hint = "Choose directory where the Favorites bin-package should be created", | |||
| 	createlisthint = "Create List", | |||
| 	onoffhint = "Creating selection list with 'on' or 'off'", | |||
| 	provhint = "List of Favorites or Provider Bouquets", | |||
| 	select = "Selection Preassign with", | |||
| 	saveonoff = " save ? on/off", | |||
| 	deflinkpath = "Symlinks in the VAR-area", | |||
| 	deflinkpathhint="If all logo links lead to /var/tuxbox/icons/logo logo ?" | |||
| } | |||
| locale["slovak"] = { | |||
| 	create_error = "Zoznam nemohol byť vytvorený.", | |||
| 	patient = "Prosím čakajte...", | |||
| 	Error = "Chyba", | |||
| 	on = "áno", | |||
| 	off = "nie", | |||
| 	dirnotwrit = "Do adresára nemožno zapisovať", | |||
| 	saved = " bolo uložené", | |||
| 	notdef = "Nedefinované", | |||
| 	askoverwrit = "Prepísať existujúcí súbor ?", | |||
| 	isavailable = " je dostupné", | |||
| 	list = "Zoznam ", | |||
| 	info = "Informácie", | |||
| 	savelist = "Uložit zoznam", | |||
| 	savelisthint = "Uloženie zoznamu pod ", | |||
| 	name = "Názov", | |||
| 	keyboardhint = "Pod akým názvom uložiť zoznam", | |||
| 	ip = "IP názov boxu", | |||
| 	boxhint = "IP adresa boxu alebo Url", | |||
| 	ub="Zoznam z:", | |||
| 	provhint = "Zoznam obľúbených alebo Buket poskytovateľov", | |||
| 	directory = "adresár", | |||
| 	listsaveto = "V ktorom adresári uložiť zoznam ?", | |||
| 	select = "Výber s priradením", | |||
| 	onoffhint = "Vytvorenie vybraného zoznamu s 'áno' alebo 'nie'", | |||
| 	fno = "Nemeniť obľúbené", | |||
| 	fadd = "Vytvorené bukety pridať do zoznamu obľúbených ", | |||
| 	fover = "Nahradenie obľúbených vytvorenými buketami", | |||
| 	favoption = "Vytvorenie záložky obľúbených, prepísanie alebo ponechanie bez zmeny", | |||
| 	directory_hint = "Vyberte adresár v ktorom balíky Obľúbených budú vytvorené", | |||
| 	deflinkpath = "Symlinky vo VAR-oblasti", | |||
| 	deflinkpathhint="Ak všetky odkazy na logá smerujú do /var/tuxbox/icons/logo ?", | |||
| 	createlist = "Vytvoriť zoznam", | |||
| 	createlisthint = "Vytvorenie zoznamu", | |||
| 	saveonoff = " uložiť ? áno/nie" | |||
| } | |||
| locale["czech"] = { | |||
| 	create_error = "Seznam nemohl byt nahrán.", | |||
| 	patient = "Prosím čekejte ...", | |||
| 	Error = "Chyba", | |||
| 	fover = "Nahradit oblíbené vytvořeným buketem ", | |||
| 	fno = "Oblíbené neměnit", | |||
| 	fadd = "Vytvořit buket a přidat do oblíbených ", | |||
| 	on = "ano", | |||
| 	off = "ne", | |||
| 	favoption = "Vytvořit Buket,přepsat nebo opustit beze změn", | |||
| 	dirnotwrit = "Adresář není zapisovatelný", | |||
| 	saved = " uloženo", | |||
| 	notdef = "Nedefinováno", | |||
| 	askoverwrit = "Prepsat existující soubor ?", | |||
| 	isavailable = " je přístupný", | |||
| 	list = "seznam ", | |||
| 	info = "Informace", | |||
| 	savelist = "Uložit seznam", | |||
| 	savelisthint = "Ukládání seznamu pod ", | |||
| 	keyboardhint = "Pod jakým jménem uložit", | |||
| 	listsaveto = "V jakém adresáři uložit ?", | |||
| 	directory = "Adresář", | |||
| 	directory_hint = "Vyberte adresář ve kterém Oblíbené budou vytvořeny", | |||
| 	createlist = "Vytvořit seznam", | |||
| 	createlisthint = "Vytvořit seznam", | |||
| 	onoffhint = "Vtvoření seznamu s ano nebo ne'", | |||
| 	provhint = "Seznam Oblíbených nebo Bukety Poskytovatelů", | |||
| 	select = "Výběr s přiřazenímt", | |||
| 	saveonoff = " uloži ? Ano/Ne", | |||
| 	deflinkpath = "Symlinks ve Var-oblasti", | |||
| 	deflinkpathhint="Jestliže linky vedou do /var/tuxbox/icons/logo logo ?" | |||
| } | |||
| ---------------------------------------------------------------------------------------------- | |||
| function gethttpdata(host,link) | |||
| 
 | |||
| 	local p = require "posix" | |||
| 	local b = bit32 or require "bit" | |||
| 	p.signal(p.SIGPIPE, function() print("pipe") end) | |||
| 
 | |||
| 	local httpreq  = "GET /" .. link .. " HTTP/1.0\r\nHost: " ..host .. "\r\n\r\n" | |||
| 	local res, err = p.getaddrinfo(host, "http", { family = p.AF_INET, socktype = p.SOCK_STREAM }) | |||
| 	if not res then  | |||
| 		info(locale[conf.lang].Error .. ":", err) | |||
| 		return | |||
| 	end | |||
| 
 | |||
| 	local fd = p.socket(p.AF_INET, p.SOCK_STREAM, 0) | |||
| 	local ok, err, e = p.connect(fd, res[1]) | |||
| 	if err then  | |||
| 		info(locale[conf.lang].Error .. ":", err) | |||
| 		return | |||
| 	end | |||
| 	p.send(fd, httpreq) | |||
| 
 | |||
| 	local data = {} | |||
| 	while true do | |||
| 		local b = p.recv(fd, 1024) | |||
| 		if not b or #b == 0 then | |||
| 			break | |||
| 		end | |||
| 		table.insert(data, b) | |||
| 	end | |||
| 	p.close(fd) | |||
| 	data = table.concat(data) | |||
| 	return data | |||
| end | |||
| 
 | |||
| function getDomainandLink(url) | |||
| 	local f = string.find(url, '//') | |||
| 	local patern = '([^/]+)/(.*)' | |||
| 	if f  then  | |||
| 		patern = "^%w+://"..patern | |||
| 	end | |||
| 	local host,link = url:match(patern) | |||
| 	return host,link | |||
| end | |||
| 
 | |||
| function getdatafromurl(url) | |||
| 	local data = nil | |||
| 	local nBeginn, nEnde   | |||
| 
 | |||
| 		local host,link = getDomainandLink(url) | |||
| 		data = gethttpdata(host,link) | |||
| 		if data == nil then | |||
| 			print("DEBUG ".. __LINE__()) | |||
| 		else | |||
| 			nBeginn, nEnde, data = string.find(data, "^.-\r\n\r\n(.*)") -- skip header | |||
| 		end | |||
| 
 | |||
| 	if data == nil then | |||
| 		print("DEBUG ".. __LINE__()) | |||
| 	end | |||
| 	return data | |||
| end | |||
| 
 | |||
| function to_chid(satpos, frq, t, on, i) | |||
| 	local transport_stream_id=tonumber (t, 16); | |||
| 	local original_network_id=tonumber (on, 16); | |||
| 	local service_id=tonumber(i, 16); | |||
| 	return (string.format('%04x', satpos+frq*4) ..  | |||
| 		string.format('%04x', transport_stream_id) ..  | |||
| 		string.format('%04x', original_network_id) ..  | |||
| 		string.format('%04x', service_id)) | |||
| end | |||
| 
 | |||
| function add_channels(t,b_name,logolist) | |||
| 	local BListeTab = {} | |||
| 	local ok = false | |||
| 	if t and b_name then | |||
| 		for k, v in ipairs(t) do | |||
| 			if v.tag == "S" then | |||
| --				print(v.tag) | |||
| 				if v.attr.u then | |||
| --					print(v.attr.u) | |||
| 				elseif v.attr.i then | |||
| --					print(v.attr.i , v.attr.t , v.attr.on , v.attr.s , v.attr.frq, v.attr.n ) | |||
| 					local chid = to_chid(v.attr.s, v.attr.frq, v.attr.t, v.attr.on, v.attr.i) | |||
| 					if v.attr.n == nil then | |||
| 						if logolist ~= nil then | |||
| 							v.attr.n = logolist:match(chid .. ";(.-);") | |||
| 						end | |||
| 						if v.attr.n == nil then | |||
| 							v.attr.n = locale[conf.lang].notdef .. " " .. k | |||
| 						end | |||
| 					end | |||
| 					local url='http://' .. conf.ip .. ':31339/id='.. chid | |||
| 					local _epgid = chid:sub(#chid-11,#chid) | |||
| 					_epgid = _epgid:gsub("^0+(.-)", "%1") | |||
| 					table.insert(BListeTab, { tv=url, n=v.attr.n, l=v.attr.l, un=v.attr.un, epgid= _epgid }) | |||
| 					ok=true | |||
| 				end | |||
| 			end | |||
| 		end | |||
| 	end | |||
| 	if ok then  | |||
| 		return BListeTab | |||
| 	else | |||
| 		return nil | |||
| 	end | |||
| end | |||
| 
 | |||
| function make_list(value) | |||
| 	local boxurl ="http://" .. conf.ip .. "/control/get" .. conf.bouquet .."xml" | |||
| 	local h = hintbox.new{caption=locale[conf.lang].info, text=locale[conf.lang].patient} | |||
| 	h:paint() | |||
| 
 | |||
| 	local data = getdatafromurl(boxurl) | |||
| 
 | |||
| 	if data == nil then return end -- error | |||
| 	local logolist = getdatafromurl("http://" .. conf.ip .. "/control/logolist") | |||
| 	local lom = require("lxp.lom") | |||
| 	local tab = lom.parse(data) | |||
| 	if tab == nil then | |||
| 		h:hide() | |||
| 		info(locale[conf.lang].Error, locale[conf.lang].create_error) | |||
| 		return | |||
| 	end | |||
| 	ListeTab = {} | |||
| 	for i, v in ipairs(tab) do | |||
| 		if v.tag == "Bouquet" then | |||
| 			local blt = add_channels(v,v.attr.name,logolist) | |||
| 			if blt then | |||
| 				table.insert(ListeTab, { name=v.attr.name, epg=v.attr.epg, hidden=v.attr.hidden, locked=v.attr.locked ,bqID=v.attr.bqID , bt=blt, enabled=conf.enabled}) | |||
| 			end | |||
| 		end | |||
| 	end | |||
| 	h:hide() | |||
| 	if ListeTab then | |||
| 		gen_menu(ListeTab) | |||
| 	end | |||
| end | |||
| 
 | |||
| function file_exists(file) | |||
| 	local f = io.open(file, "rb") | |||
| 	if f then f:close() end | |||
| 	return f ~= nil | |||
| end | |||
| 
 | |||
| function is_dir(path) | |||
| 	local f = io.open(path, "r") | |||
| 	local ok, err, code = false, false, false | |||
| 	if f then | |||
| 		ok, err, code = f:read(1) | |||
| 		f:close() | |||
| 	end | |||
| 	return code == 21 | |||
| end | |||
| 
 | |||
| function make_fav_back() | |||
| 	os.execute("mkdir /tmp/tmpfav") | |||
| 	os.execute("mkdir /tmp/tmpfav/temp_inst") | |||
| 	os.execute("mkdir /tmp/tmpfav/temp_inst/inst") | |||
| 	os.execute("mkdir /tmp/tmpfav/temp_inst/inst/var") | |||
| 	os.execute("mkdir /tmp/tmpfav/temp_inst/inst/var/tuxbox") | |||
| 	os.execute("mkdir /tmp/tmpfav/temp_inst/inst/var/tuxbox/config") | |||
| 	os.execute("mkdir /tmp/tmpfav/temp_inst/inst/var/tuxbox/config/zapit") | |||
| 	os.execute("mkdir /tmp/tmpfav/temp_inst/ctrl") | |||
| 	local postins = "/tmp/tmpfav/temp_inst/ctrl/postinstall.sh" | |||
| 	local fileout = io.open(postins, 'w') | |||
| 	fileout:write("pzapit -c \n") | |||
| 	fileout:write('wget -q -O /dev/null "http://localhost/control/message?popup=Favoriten-Bouquet%20wurde%20installiert."') | |||
| 	fileout:close() | |||
| 	os.execute("chmod 755 " .. postins) | |||
| 	os.execute("cp " .. conf.ubouquets_xml .. " /tmp/tmpfav/temp_inst/inst/var/tuxbox/config/zapit/" ) | |||
| 	os.execute("cd /tmp/tmpfav && tar -czvf  " .. conf.backuppath .."/last_ubouquets_xml.bin temp_inst" ) | |||
| 	os.execute("rm -rf /tmp/tmpfav/") | |||
| end | |||
| 
 | |||
| function toUcode(str) | |||
| 	local ustr=str:gsub("&","&") | |||
| 	ustr=ustr:gsub("'","'") | |||
| 	return ustr | |||
| end | |||
| 
 | |||
| function changeFav() | |||
| 	if is_dir(conf.backuppath) then | |||
| 		make_fav_back() | |||
| 	end | |||
| 	local force = true | |||
| 	local fileout = nil | |||
| 	if conf.fav == "add" then | |||
| 			local lines = read_ubouquets_xml(conf.ubouquets_xml) | |||
| 			if lines then | |||
| 				fileout = io.open(conf.ubouquets_xml, 'w+') | |||
| 				if fileout then | |||
| 					for k,v in pairs(lines) do | |||
| 						local f = string.find(v, "</zapit>") | |||
| 						if not f then | |||
| 							fileout:write(v .. "\n") | |||
| 							force = false | |||
| 						end | |||
| 					end | |||
| 				end | |||
| 			end | |||
| 	end | |||
| 	if force then | |||
| 		fileout = io.open(conf.ubouquets_xml, 'w+') | |||
| 		if fileout == nil then return end | |||
| 		fileout:write('<?xml version="1.0" encoding="UTF-8"?>\n<zapit>\n') | |||
| 	end | |||
| 	for _, v in ipairs(ListeTab) do | |||
| 		if v.enabled then | |||
| 			if v.bt then | |||
| 				local locked = "" | |||
| 				local hidden = "" | |||
| 				local epg = "" | |||
| 				local bqID = "" | |||
| 				if v.bqID then | |||
| 					bqID=' bqID="' .. v.bqID .. '"'  | |||
| 				end | |||
| 				if v.locked then | |||
| 					locked=' locked="' .. v.locked .. '"'  | |||
| 				end | |||
| 				if v.hidden then | |||
| 					hidden=' hidden="' .. v.hidden .. '"'  | |||
| 				end | |||
| 				if v.epg then | |||
| 					epg=' epg="' .. "0"  .. '"' -- v.epg disable epg scan  | |||
| 				end | |||
| 				local bname =toUcode(v.name) | |||
| 				fileout:write('\t<Bouquet name="' .. bname .. " (".. conf.name .. ')"' .. bqID .. hidden .. locked .. epg ..' >\n') | |||
| 				for __, b in ipairs(v.bt) do | |||
| 					local un = "" | |||
| 					local l = "" | |||
| 					if b.l then | |||
| 						l=' l="' .. b.l .. '"'  | |||
| 					end | |||
| 					if b.un then | |||
| 						un=' un="' .. b.un  .. '"' | |||
| 						un=toUcode(un) | |||
| 					end | |||
| 					local name =toUcode(b.n) | |||
| 					fileout:write('\t\t<S u="' .. b.tv..'" n="' ..name.. '"' .. un .. l ..' />\n') | |||
| 				end | |||
| 				fileout:write('\t</Bouquet>\n') | |||
| 			end | |||
| 		end | |||
| 	end | |||
| 	fileout:write('</zapit>\n') | |||
| 	fileout:close() | |||
| end | |||
| 
 | |||
| function read_ubouquets_xml(file) | |||
|  	if not file_exists(file) then return {} end | |||
| 	lines = {} | |||
| 	for line in io.lines(file) do  | |||
| 		lines[#lines + 1] = line | |||
| 	end | |||
| 	return lines | |||
| end | |||
| 
 | |||
| function saveliste() | |||
| 	if ListeTab then | |||
| 		local filename = conf.path .. "/" .. conf.name .. ".xml" | |||
| 		if is_dir(conf.path) then | |||
| 			if file_exists(filename) then | |||
| 				local res = messagebox.exec{title=conf.name .. locale[conf.lang].isavailable, text=locale[conf.lang].askoverwrit, buttons={ "yes", "no" } } | |||
| 				if (res == "no") then return  end | |||
| 			end | |||
| 			local localtv = io.open(filename,'w+') | |||
| 			if localtv then | |||
| 				localtv:write('<?xml version="1.0" encoding="UTF-8"?>\n<webtvs>\n') | |||
| 			else | |||
| 				return | |||
| 			end | |||
| 			local deflogopth = "/var/tuxbox/icons/logo" | |||
| 			for _, v in ipairs(ListeTab) do | |||
| 				if v.enabled then | |||
| 					if v.bt then | |||
| 						for __, b in ipairs(v.bt) do | |||
| 							localtv:write('\t<webtv title="' .. toUcode(b.n) .. '" url="' .. b.tv  .. '" epgid="' .. b.epgid.. '" description="' .. toUcode(v.name) .. '" genre="' .. toUcode(conf.name)  ..'" />\n') | |||
| 							if conf.logo_dir  ~= "#" then | |||
| 								local logo={} | |||
| 								logo[1] =  deflogopth .."/" | |||
| 								logo[2] = "/share/tuxbox/neutrino/icons/logo" | |||
| 								logo[3] = conf.logo_dir | |||
| 								for j,l  in pairs(logo) do | |||
| 									if l and is_dir(l) then | |||
| 										local logopath = l .."/" ..b.epgid | |||
| 										local jpg = false | |||
| 										local png = file_exists(logopath..".png") | |||
| 										local picformat = ".png" | |||
| 										if png == false then | |||
| 											jpg = file_exists(logopath..".jpg") | |||
| 											picformat = ".jpg" | |||
| 										end | |||
| 										if  png or jpg then | |||
| 											local webtvid = n:createChannelIDfromUrl(b.tv) | |||
| 											webtvid = webtvid:sub(#webtvid-11,#webtvid) | |||
| 											local defvar ="" | |||
| 											if conf.varonoff == true and is_dir(deflogopth) then | |||
| 												defvar = deflogopth .. "/" | |||
| 											end | |||
| 											local logo_symlink = defvar .. webtvid .. picformat | |||
| 											if conf.varonoff == true then | |||
| 												os.execute("ln  -fs " .. l .."/".. b.epgid.. picformat .. " " .. logo_symlink) | |||
| 											else | |||
| 												os.execute("cd " .. l .. "/ && ln  -fs " .. b.epgid.. picformat .. " " .. logo_symlink) | |||
| 											end | |||
| 										end | |||
| 									end | |||
| 								end | |||
| 							end | |||
| 						end | |||
| 					end | |||
| 				end | |||
| 			end | |||
| 			localtv:write("</webtvs>\n") | |||
| 			localtv:close() | |||
| 			if conf.fav ~= "no" then | |||
| 				changeFav() | |||
| 			end | |||
| 			os.execute( 'pzapit -c') | |||
| 			info(locale[conf.lang].info, locale[conf.lang].list.. conf.name .. ".xml" .. locale[conf.lang].saved) | |||
| 		end | |||
| 	else | |||
| 		info(locale[conf.lang].Error, locale[conf.lang].dirnotwrit) | |||
| 		return | |||
| 	end | |||
| end | |||
| 
 | |||
| function get_confFile() | |||
| 	local confFile = "/var/tuxbox/config/localtv.conf" | |||
| 	return confFile | |||
| end | |||
| 
 | |||
| function saveConfig() | |||
| 	if conf.changed then | |||
| 		local config	= configfile.new() | |||
| 		config:setString("path", conf.path) | |||
| 		config:setString("backuppath", conf.backuppath) | |||
| 		config:setString("name",conf.name) | |||
| 		config:setString("bouquet",conf.bouquet) | |||
| 		config:setString("ip",conf.ip) | |||
| 		config:setBool  ("enabled",conf.enabled) | |||
| 		config:setBool  ("varonoff",conf.varonoff) | |||
| 		config:setString("fav",conf.fav) | |||
| 		config:saveConfig(get_confFile()) | |||
| 		conf.changed = false | |||
| 	end | |||
| end | |||
| 
 | |||
| function loadConfig() | |||
| 	local config	= configfile.new() | |||
| 	config:loadConfig(get_confFile()) | |||
| 	conf.path = config:getString("path", "/var/tuxbox/config") | |||
| 	conf.backuppath = config:getString("backuppath", "/media/sda1") | |||
| 	conf.name = config:getString("name", "BoxName") | |||
| 	conf.ip   = config:getString("ip", "192.168.178.2") | |||
| 	conf.bouquet = config:getString("bouquet", "ubouquets") | |||
| 
 | |||
| 	conf.enabled = config:getBool("enabled", true) | |||
| 	conf.varonoff = config:getBool("varonoff", false) | |||
| 	conf.fav = config:getString("fav", "no") | |||
| 	conf.changed = false | |||
| 	local Nconfig	= configfile.new() | |||
| 	Nconfig:loadConfig("/var/tuxbox/config/neutrino.conf") | |||
| 	if APIVERSION.MAJOR > 1 or ( APIVERSION.MAJOR == 1 and APIVERSION.MINOR > 5 ) then | |||
| 		conf.logo_dir = Nconfig:getString("logo_hdd_dir", "#") | |||
| 	else | |||
| 		conf.logo_dir = "#" | |||
| 	end | |||
| 	conf.lang = Nconfig:getString("language", "english") | |||
| 	if locale[conf.lang] == nil then | |||
| 		conf.lang = "english" | |||
| 	end | |||
| 	conf.ubouquets_xml = "/var/tuxbox/config/zapit/ubouquets.xml" | |||
| 
 | |||
| end | |||
| 
 | |||
| function setvar(k, v)  | |||
| 	conf[k]=v | |||
| 	conf.changed = true | |||
| end | |||
| 
 | |||
| function bool2onoff(a) | |||
| 	if a then return locale[conf.lang].on end | |||
| 	return locale[conf.lang].off | |||
| end | |||
| 
 | |||
| function favoption(a) | |||
| 	if a == "on" then return locale[conf.lang].fon | |||
| 	end | |||
| 	if a == "overwrite" then return locale[conf.lang].fover | |||
| 	end | |||
| 	if a == "add" then return locale[conf.lang].fadd | |||
| 	end | |||
| end | |||
| 
 | |||
| function setub(a,b) | |||
| 	conf.bouquet = b | |||
| 	conf.changed = true | |||
| 	return b | |||
| end | |||
| 
 | |||
| function setabc(a,b) | |||
| 	local aktiv = true | |||
| 	if b == locale[conf.lang].fno then | |||
| 		conf.fav = "no" | |||
| 		aktiv = false | |||
| 	elseif b == locale[conf.lang].fover then | |||
| 		conf.fav = "overwrite" | |||
| 	elseif b == locale[conf.lang].fadd then | |||
| 		conf.fav = "add" | |||
| 	end | |||
| 	conf.changed = true | |||
| 	g.main:setActive{item=g.item1, activ=aktiv} | |||
| 	return b | |||
| end | |||
| 
 | |||
| function set_path(value) | |||
| 	conf.path=value | |||
| 	conf.changed = true | |||
| end | |||
| 
 | |||
| function set_backup_path(value) | |||
| 	conf.backuppath=value | |||
| 	conf.changed = true | |||
| end | |||
| 
 | |||
| function info(captxt,infotxt) | |||
| 	if captxt == localtv_version and infotxt==nil then | |||
| 		infotxt=captxt | |||
| 		captxt=locale[conf.lang].info | |||
| 	end | |||
| 	local h = hintbox.new{caption=captxt, text=infotxt} | |||
| 	h:paint() | |||
| 	repeat | |||
| 		msg, data = n:GetInput(500) | |||
| 	until msg == RC.ok or msg == RC.home | |||
| 	h:hide() | |||
| end | |||
| 
 | |||
| function set_bool_in_liste(k, v)  | |||
| 	local i = tonumber(k) | |||
| 	if v == locale[conf.lang].on then | |||
| 		ListeTab[i].enabled=true | |||
| 	else  | |||
| 		ListeTab[i].enabled=false | |||
| 	end | |||
| end | |||
| 
 | |||
| function set_option(k, v) | |||
| 	if v == locale[conf.lang].on then | |||
| 		conf[k]=true | |||
| 	else  | |||
| 		conf[k]=false | |||
| 	end | |||
| 	conf.changed = true | |||
| end | |||
| 
 | |||
| function gen_menu(table) | |||
| 	if table == nil then | |||
| 		return | |||
| 	end | |||
| 	g.main:hide() | |||
| 	local m  = menu.new{name=locale[conf.lang].list .. conf.name .. ": ".. conf.ip, icon="icon_blue"} | |||
| 	m:addItem{type="separator"} | |||
| 	m:addItem{type="back"} | |||
| 	m:addItem{type="separatorline"} | |||
| 	m:addItem{type="forwarder", name=locale[conf.lang].savelist, action="saveliste",enabled=true,id="" ,directkey=RC["red"],hint_icon="hint_service",hint=locale[conf.lang].savelisthint .. conf.path .. "/" .. conf.name .. ".xml" } | |||
| 	m:addItem{type="separatorline"} | |||
| 	for i, v in ipairs(table) do | |||
| 		local name=v.name:gsub("&","%&") | |||
| 		name=name:gsub("'","'") | |||
| 		m:addItem{type="chooser", action="set_bool_in_liste", options={ locale[conf.lang].on, locale[conf.lang].off }, id=i, value=bool2onoff(v.enabled), name=name,hint_icon="hint_service",hint="Bouquet ".. name .. locale[conf.lang].saveonoff} | |||
| 	end | |||
| 	m:exec() | |||
| 	m:hide() | |||
| 	return MENU_RETURN.EXIT | |||
| end | |||
| 
 | |||
| function main_menu() | |||
|   	g.main = menu.new{name="LocalTV", icon="icon_red"} | |||
| 	m=g.main | |||
| 	m:addKey{directkey=RC["info"], id=localtv_version, action="info"} | |||
| 
 | |||
| 	m:addItem{type="back"} | |||
| 	m:addItem{type="separatorline"} | |||
| 	m:addItem{type="keyboardinput", action="setvar", id="name", name=locale[conf.lang].name, value=conf.name,directkey=RC["1"],hint_icon="hint_service",hint=locale[conf.lang].keyboardhint} | |||
| 	m:addItem{type="keyboardinput", action="setvar", id="ip",   value=conf.ip, name=locale[conf.lang].ip,directkey=RC["2"],hint_icon="hint_service",hint=locale[conf.lang].boxhint} | |||
| 	m:addItem{type="chooser", action="setub", options={ u, b }, id="ub", value=conf.bouquet, name=locale[conf.lang].ub,directkey=RC["3"],hint_icon="hint_service",hint=locale[conf.lang].provhint} | |||
| 	m:addItem{ type="filebrowser", dir_mode="1", id="path", name="WebTV ".. locale[conf.lang].directory .. ": ", action="set_path", | |||
| 		   enabled=true,value=conf.path,directkey=RC["4"], | |||
| 		   hint_icon="hint_service",hint=locale[conf.lang].listsaveto | |||
| 		 } | |||
| 	m:addItem{type="chooser", action="set_option", options={ locale[conf.lang].on, locale[conf.lang].off }, id="enabled", value=bool2onoff(conf.enabled), directkey=RC["5"], name=locale[conf.lang].select,hint_icon="hint_service",hint=locale[conf.lang].onoffhint} | |||
| 	m:addItem{type="chooser", action="setabc", options={ locale[conf.lang].fno, locale[conf.lang].fadd, locale[conf.lang].fover }, id="boxub", value=favoption(conf.fav), name="",directkey=RC["6"],hint_icon="hint_service",hint=locale[conf.lang].favoption} | |||
| 	g.item1 = m:addItem{type="filebrowser",dir_mode="1",name="Fav " .. locale[conf.lang].directory .. ":",action="set_backup_path",enabled=file_exists(conf.ubouquets_xml), | |||
| 		value=conf.backuppath,directkey=RC["7"] ,hint_icon="hint_service",hint=locale[conf.lang].directory_hint} | |||
| 	m:addItem{type="chooser", action="set_option", options={ locale[conf.lang].on, locale[conf.lang].off }, id="varonoff", value=bool2onoff(conf.varonoff), directkey=RC["8"], enabled=is_dir("/var/tuxbox/icons/logo"), name=locale[conf.lang].deflinkpath,hint_icon="hint_service",hint=locale[conf.lang].deflinkpathhint} | |||
| 	m:addItem{type="separatorline"} | |||
| 	m:addItem{type="forwarder", name=locale[conf.lang].createlist, action="make_list",enabled=true,id="",directkey=RC["red"],hint_icon="hint_service",hint=locale[conf.lang].createlisthint } | |||
| 
 | |||
| 	m:setActive{item=g.item1, activ=conf.fav ~= "no"} | |||
| 	m:exec() | |||
| 	m:hide() | |||
| end | |||
| 
 | |||
| function main() | |||
| 	loadConfig() | |||
| 	main_menu() | |||
| 	saveConfig() | |||
| end | |||
| 
 | |||
| main() | |||
| Before Width: | Height: | Size: 192 B | 
| @ -1,5 +0,0 @@ | |||
| name=Add locale to NI-Image | |||
| desc=Add or update languages to NI-Image | |||
| type=4 | |||
| integration=0 | |||
| hinticon=hint_language | |||
| @ -1,297 +0,0 @@ | |||
| 
 | |||
| caption="Add locale to NI-Image" | |||
| 
 | |||
| -- --------------------------------------------------------------------------- | |||
| 
 | |||
| n	= neutrino() | |||
| locales	= {} | |||
| 
 | |||
| chooser	= nil | |||
| infobox	= nil | |||
| 
 | |||
| tmp_dir		= "/tmp/add-locale.data" | |||
| user_agent	= "\"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Firefox/31.0\"" | |||
| wget_cmd	= "wget -q -U " .. user_agent .. " -O " | |||
| remote_dir	= "http://neutrino-images.de/neutrino-images/locale" | |||
| locale_dir	= "/var/tuxbox/locale" | |||
| icons_dir	= "/var/tuxbox/icons" | |||
| 
 | |||
| -- --------------------------------------------------------------------------- | |||
| 
 | |||
| function trim(s) | |||
| 	return (s:gsub("^%s*(.-)%s*$", "%1")) | |||
| end | |||
| 
 | |||
| function capitalize(s) | |||
| 	return (s:gsub("^%l", string.upper)) | |||
| end | |||
| 
 | |||
| function file_exists(name) | |||
| 	local f = io.open(name, "r") | |||
| 	if f ~= nil then | |||
| 		io.close(f) | |||
| 		return true | |||
| 	else | |||
| 		return false | |||
| 	end | |||
| end | |||
| 
 | |||
| function delay(timeout) | |||
| 	local timeout = timeout or 2 | |||
| 	local i = 0 | |||
| 	repeat | |||
| 		i = i + 1 | |||
| 		msg, data = n:GetInput(500) | |||
| 	until msg == RC.ok or msg == RC.home or i == (timeout * 2) | |||
| end | |||
| 
 | |||
| function cleanup() | |||
| 	os.execute("rm -rf " .. tmp_dir) | |||
| end | |||
| 
 | |||
| function init() | |||
| 	cleanup() | |||
| 	os.execute("mkdir -p " .. tmp_dir) | |||
| 	local tmp_data = tmp_dir .. "/index.html" | |||
| 	os.execute(wget_cmd .. tmp_data .. " '" .. remote_dir .. "'"); | |||
| 
 | |||
| 	local fp = io.open(tmp_data, "r") | |||
| 	if fp == nil then | |||
| 		error("Error opening file '" .. tmp_data .. "'.") | |||
| 	end | |||
| 	for line in fp:lines() do | |||
| 		local match = string.find(line, "<a href=\".*.locale\">") | |||
| 		if match ~= nil then | |||
| 			match = line:gsub("^.*\"(.-).locale\".*$", "%1") | |||
| 			table.insert(locales, match) | |||
| 		end | |||
| 	end | |||
| 	fp:close() | |||
| 
 | |||
| 	os.execute("mkdir -p " .. locale_dir) | |||
| 	os.execute("mkdir -p " .. icons_dir) | |||
| end | |||
| 
 | |||
| function is_used(locale) | |||
| 	local ret = false | |||
| 
 | |||
| 	local conf = io.open("/var/tuxbox/config/neutrino.conf", "r") | |||
| 	if conf then | |||
| 		for line in conf:lines() do | |||
| 			local key, val = line:match("^([^=#]+)=([^\n]*)") | |||
| 			if (key) then | |||
| 				if key == "language" then | |||
| 					if (val == locale) then | |||
| 						ret = true | |||
| 					end | |||
| 				end | |||
| 			end | |||
| 		end | |||
| 		conf:close() | |||
| 	end | |||
| 
 | |||
| 	return ret | |||
| end | |||
| 
 | |||
| function get_icon(locale) | |||
| 	local icon = "dummy" | |||
| 	if file_exists(icons_dir .. "/" .. locale .. ".png") then | |||
| 		icon = locale | |||
| 	end | |||
| 	return icon | |||
| end | |||
| 
 | |||
| function paint_infobox(locale, text) | |||
| 	hide_menu() | |||
| 
 | |||
| 	local dx = n:scale2Res(450) | |||
| 	local dy = n:scale2Res(150) | |||
| 	local x = SCREEN.OFF_X + (((SCREEN.END_X - SCREEN.OFF_X) - dx) / 2) | |||
| 	local y = SCREEN.OFF_Y + (((SCREEN.END_Y - SCREEN.OFF_Y) - dy) / 2) | |||
| 
 | |||
| 	infobox = cwindow.new{x=x, y=y, dx=dx, dy=dy, title=capitalize(locale), icon=get_icon(locale), has_shadow=true, show_footer=true} | |||
| 	local t = ctext.new { | |||
| 		parent=infobox, | |||
| 		x=n:scale2Res(10), | |||
| 		y=n:scale2Res(10), | |||
| 		dx=dx-n:scale2Res(2*10), | |||
| 		dy=dy-infobox:headerHeight()-n:scale2Res(2*10), | |||
| 		text=text, | |||
| 		font_text=FONT.MENU, | |||
| 		mode="ALIGN_CENTER" | |||
| 	} | |||
| 	infobox:paint() | |||
| end | |||
| 
 | |||
| function hide_infobox() | |||
| 	if infobox ~= nil then | |||
| 		infobox:hide() | |||
| 		infobox = nil | |||
| 	end | |||
| end | |||
| 
 | |||
| function update(locale) | |||
| 	paint_infobox(locale, "Updating" .. " \"" .. locale .. "\"") | |||
| 	download(locale) | |||
| 	delay(2) | |||
| 	hide_infobox() | |||
| 	return MENU_RETURN.EXIT | |||
| end | |||
| 
 | |||
| function install(locale) | |||
| 	paint_infobox(locale, "Installing" .. " \"" .. locale .. "\"") | |||
| 	download(locale) | |||
| 	delay(2) | |||
| 	hide_infobox() | |||
| 	return MENU_RETURN.EXIT | |||
| end | |||
| 
 | |||
| function remove(locale) | |||
| 	paint_infobox(locale, "Removing" .. " \"" .. locale .. "\"") | |||
| 	delete(locale) | |||
| 	delay(2) | |||
| 	hide_infobox() | |||
| 	return MENU_RETURN.EXIT | |||
| end | |||
| 
 | |||
| function download(locale) | |||
| 	local ll = locale_dir .. "/" .. locale .. ".locale" | |||
| 	local lr = remote_dir .. "/" .. locale .. ".locale" | |||
| 	os.execute(wget_cmd .. ll .. " '" .. lr .. "'"); | |||
| 	if not file_exists(ll) then | |||
| 		showhint("Error", "Download failed: " .. locale .. ".locale", "error") | |||
| 		return MENU_RETURN.EXIT | |||
| 	end | |||
| 
 | |||
| 	local il = icons_dir  .. "/" .. locale .. ".png" | |||
| 	local ir = remote_dir .. "/" .. locale .. ".png" | |||
| 	os.execute(wget_cmd .. il .. " '" .. ir .. "'"); | |||
| 	if not file_exists(il) then | |||
| 		showhint("Error", "Download failed: " .. locale .. ".png", "error") | |||
| 		return MENU_RETURN.EXIT | |||
| 	end | |||
| end | |||
| 
 | |||
| function delete(locale) | |||
| 	local ll = locale_dir .. "/" .. locale .. ".locale" | |||
| 	if file_exists(ll) then | |||
| 		assert(os.remove(ll), "Error removing file '" .. ll .. "'.") | |||
| 	end | |||
| 	local il = icons_dir  .. "/" .. locale .. ".png" | |||
| 	if file_exists(il) then | |||
| 		assert(os.remove(il), "Error removing file '" .. il .. "'.") | |||
| 	end | |||
| end | |||
| 
 | |||
| function w_chooser(locale) | |||
| 	hide_menu() | |||
| 
 | |||
| 	local dx = n:scale2Res(450) | |||
| 	local dy = n:scale2Res(150) | |||
| 	local x = SCREEN.OFF_X + (((SCREEN.END_X - SCREEN.OFF_X) - dx) / 2) | |||
| 	local y = SCREEN.OFF_Y + (((SCREEN.END_Y - SCREEN.OFF_Y) - dy) / 2) | |||
| 
 | |||
| 	local chooser = cwindow.new{x=x, y=y, dx=dx, dy=dy, title=capitalize(locale), icon=get_icon(locale), has_shadow=true, show_footer=true, btnRed="Remove", btnGreen="Update"} | |||
| 	ctext.new { | |||
| 		parent=chooser, | |||
| 		x=n:scale2Res(10), | |||
| 		y=n:scale2Res(10), | |||
| 		dx=dx-n:scale2Res(2*10), | |||
| 		dy=dy-chooser:headerHeight()-n:scale2Res(2*10), | |||
| 		text="Remove or update ?", | |||
| 		font_text=FONT.MENU, | |||
| 		mode="ALIGN_CENTER" | |||
| 	} | |||
| 	chooser:paint() | |||
| 
 | |||
| 	repeat | |||
| 		msg, data = n:GetInput(500) | |||
| 		if (msg == RC.red) then | |||
| 			remove(locale) | |||
| 			msg = RC.home; | |||
| 		elseif (msg == RC.ok) or (msg == RC.green) then | |||
| 			update(locale) | |||
| 			msg = RC.home; | |||
| 		end | |||
| 	until msg == RC.home or msg == RC.setup; | |||
| 
 | |||
| 	chooser:hide() | |||
| 	chooser = nil | |||
| 
 | |||
| 	if msg == RC.setup then | |||
| 		repaint_menu = false | |||
| 		return MENU_RETURN.EXIT_ALL | |||
| 	end | |||
| 	return MENU_RETURN.EXIT | |||
| end | |||
| 
 | |||
| function showhint(caption, text, icon, timeout) | |||
| 	local caption = caption or "Info" | |||
| 	local text = text or "" | |||
| 	local icon = icon or "information" | |||
| 
 | |||
| 	local h = hintbox.new{caption=caption, text=text, icon=icon} | |||
| 	h:paint() | |||
| 	delay(5) | |||
| 	h:hide() | |||
| end | |||
| 
 | |||
| function paint_menu() | |||
| 	m = menu.new{name=caption, icon="language"} | |||
| 	m:addKey{directkey=RC.setup, id="setup", action="exit_menu"} | |||
| 	m:addItem{type="separator"} | |||
| 	m:addItem{type="forwarder", id="home", action="exit_menu", name="Back", icon="home", directkey=RC.home, hint="Return to previous menu", hint_icon="hint_back"}; | |||
| 	m:addItem{type="separatorline"} | |||
| 
 | |||
| 	for index, locale in pairs(locales) do | |||
| 		if file_exists(locale_dir .. "/" .. locale .. ".locale") then | |||
| 			install_or_update = "update" | |||
| 			action_function = "update" | |||
| 			if not is_used(locale) then | |||
| 				action_function = "w_chooser" | |||
| 			end | |||
| 		else | |||
| 			install_or_update = "install" | |||
| 			action_function = "install" | |||
| 		end | |||
| 
 | |||
| 		m:addItem{ | |||
| 			type="forwarder", | |||
| 			action=action_function, | |||
| 			id=locale, | |||
| 			icon=get_icon(locale), | |||
| 			name=capitalize(locale), | |||
| 			value=capitalize(install_or_update),  | |||
| 			hint=capitalize(install_or_update) .." the language \"" .. capitalize(locale) .. "\"", | |||
| 			hint_icon="hint_language" | |||
| 		} | |||
| 
 | |||
| 	end | |||
| 
 | |||
| 	m:exec() | |||
| end | |||
| 
 | |||
| function hide_menu() | |||
| 	if m ~= nil then | |||
| 		m:hide() | |||
| 	end | |||
| end | |||
| 
 | |||
| function exit_menu(id) | |||
| 	repaint_menu = false | |||
| 	if id == "setup" then | |||
| 		return MENU_RETURN.EXIT_ALL | |||
| 	end | |||
| 	return MENU_RETURN.EXIT | |||
| end | |||
| 
 | |||
| -- --------------------------------------------------------------------------- | |||
| 
 | |||
| init() | |||
| 
 | |||
| repaint_menu = true | |||
| while repaint_menu do | |||
| 	paint_menu() | |||
| end | |||
| 
 | |||
| cleanup() | |||
| @ -1,6 +0,0 @@ | |||
| type=4 | |||
| integration=4 | |||
| name=Userbouquets | |||
| desc=Manage user defined bouquets | |||
| name.deutsch=Benutzer-Bouquets | |||
| desc.deutsch=Verwaltet benutzerdefinierte Kanallisten | |||
| @ -1,509 +0,0 @@ | |||
| --[[ | |||
| 	userbouquets - Manage user defined bouquets | |||
| 
 | |||
| 	Copyright (C) 2016 Sven Hoefer <svenhoefer@svenhoefer.com> | |||
| 	License: WTFPLv2 | |||
| ]] | |||
| 
 | |||
| -- ---------------------------------------------------------------------------- | |||
| 
 | |||
| version = 0.12 | |||
| 
 | |||
| function script_path() | |||
| 	local str = debug.getinfo(2, "S").source:sub(2) | |||
| 	return str:match("(.*/)") | |||
| end | |||
| 
 | |||
| function capitalize(s) | |||
| 	return s:gsub("^%l", string.upper) | |||
| end | |||
| 
 | |||
| function add_slash(dir) | |||
| 	-- add trailing slash if needed | |||
| 	if string.sub(dir, -1) ~= "/" then | |||
| 		dir = dir .. "/" | |||
| 	end | |||
| 	return dir | |||
| end | |||
| 
 | |||
| function remove_slash(dir) | |||
| 	-- remove trailing slash if needed | |||
| 	if string.sub(dir, -1) == "/" then | |||
| 		dir = dir:sub(1, -2) | |||
| 	end | |||
| 	return dir | |||
| end | |||
| 
 | |||
| function showhint(caption, text, icon, timeout) | |||
| 	local caption = caption or "Info" | |||
| 	local text = text or "" | |||
| 	local icon = icon or "information" | |||
| 
 | |||
| 	local h = hintbox.new{caption=caption, text=text, icon=icon} | |||
| 	h:paint() | |||
| 	delay(5) | |||
| 	h:hide() | |||
| end | |||
| 
 | |||
| function delay(timeout) | |||
| 	local timeout = timeout or 2 | |||
| 	local i = 0 | |||
| 	repeat | |||
| 		i = i + 1 | |||
| 		msg, data = n:GetInput(500) | |||
| 	until msg == RC.ok or msg == RC.home or i == (timeout * 2) | |||
| end | |||
| 
 | |||
| function check_content(dir) | |||
| 	dir = add_slash(dir) | |||
| 	if not fh:exist(dir .. bouquets_xml, "f") or not fh:exist(dir .. ubouquets_xml, "f") | |||
| 	then | |||
| 		return false | |||
| 	end | |||
| 	return true | |||
| end | |||
| 
 | |||
| function check_owner(dir) | |||
| 	dir = add_slash(dir) | |||
| 	if dir == owner_dir | |||
| 	then | |||
| 		return true | |||
| 	end | |||
| 	return false | |||
| end | |||
| 
 | |||
| function check_active(dir) | |||
| 	dir = add_slash(dir) | |||
| 	local bouquets_target = fh:readlink(zapit_dir .. bouquets_xml) | |||
| 	if bouquets_target == dir .. bouquets_xml | |||
| 	then | |||
| 		return true | |||
| 	end | |||
| 	return false | |||
| end | |||
| 
 | |||
| function get_active_icon(dir) | |||
| 	if check_active(dir) then | |||
| 		return "checkmark" | |||
| 	end | |||
| 	return "" | |||
| end | |||
| 
 | |||
| function get_username(dir) | |||
| 	dir = remove_slash(dir) | |||
| 	local name = string.match(dir, "[^/]+$") | |||
| 	if name == "owner" then | |||
| 		name = locale[lang].owner | |||
| 	end | |||
| 	return capitalize(name:gsub("_", " ")) | |||
| end | |||
| 
 | |||
| function activate(dir) | |||
| 	dir = add_slash(dir) | |||
| 	if check_active(dir) then | |||
| 		showhint(get_username(dir), locale[lang].already_active) | |||
| 		return | |||
| 	end | |||
| 	if not check_content(dir) then | |||
| 		showhint(get_username(dir), locale[lang].content_failed) | |||
| 		return | |||
| 	end | |||
| 	if get_pin(dir) then | |||
| 		fh:ln(dir .. bouquets_xml, zapit_dir .. bouquets_xml, "sf") | |||
| 		fh:ln(dir .. ubouquets_xml, zapit_dir .. ubouquets_xml, "sf") | |||
| 		os.execute("pzapit -c") | |||
| 	end | |||
| 	return MENU_RETURN.EXIT -- force rebuild menu | |||
| end | |||
| 
 | |||
| function remove(dir) | |||
| 	dir = add_slash(dir) | |||
| 	if check_owner(dir) then | |||
| 		showhint(get_username(dir), locale[lang].cant_remove_owner) | |||
| 		return | |||
| 	end | |||
| 	if check_active(dir) then | |||
| 		showhint(get_username(dir), locale[lang].cant_remove_active) | |||
| 		return | |||
| 	end | |||
| 	if get_pin(owner_dir) then | |||
| 		fh:rmdir(dir) | |||
| 		showhint(get_username(dir), locale[lang].removed) | |||
| 	end | |||
| end | |||
| 
 | |||
| function get_pin(dir) | |||
| 	local pin = read_pin(dir) | |||
| 	if pin == "0000" or pin == "" or pin == nil then | |||
| 		return true | |||
| 	end | |||
| 	local input = input_pin(dir) | |||
| 	if input == pin then | |||
| 		return true | |||
| 	end | |||
| 	showhint(locale[lang].panic, locale[lang].pin_wrong) | |||
| 	return false | |||
| end | |||
| 
 | |||
| function set_pin(dir) | |||
| 	dir = add_slash(dir) | |||
| 	local input = input_pin(dir, "new") | |||
| --[[ | |||
| 	TODO: check input | |||
| ]] | |||
| 	local f = io.open(dir .. passwd, "w") | |||
| 	f:write(input .. "\n") | |||
| 	f:close() | |||
| end | |||
| 
 | |||
| function read_pin(dir) | |||
| 	dir = add_slash(dir) | |||
| 	local f = io.open(dir .. passwd, "rb") | |||
| 	local pin = f:read() | |||
| 	f:close() | |||
| --[[ | |||
| 	TODO: check pin | |||
| ]] | |||
| 	return pin | |||
| end | |||
| 
 | |||
| function input_pin(dir, new) | |||
| 	dir = remove_slash(dir) | |||
| 	local heading = get_username(dir) .. " - " | |||
| 	if new == "new" then | |||
| 		heading = heading .. locale[lang].pin_new | |||
| 	else | |||
| 		heading = heading .. locale[lang].pin | |||
| 	end | |||
| 	local input = stringinput.exec { | |||
| 		caption=heading, | |||
| 		value="", | |||
| 		valid_chars="0123456789", | |||
| 		pin=1, | |||
| 		size=4 | |||
| 	} | |||
| 	return input | |||
| end | |||
| 
 | |||
| function pin(dir) | |||
| --[[ | |||
| 	if check_active(dir) then | |||
| 		showhint(get_username(dir), locale[lang].cant_change_pin) | |||
| 		return | |||
| 	end | |||
| ]] | |||
| 	if get_pin(dir) then | |||
| 		set_pin(dir) | |||
| 		showhint(get_username(dir), locale[lang].pin_changed) | |||
| 	end | |||
| end | |||
| 
 | |||
| function create(id, value) | |||
| 	local user = value | |||
| 	user = add_slash(user) | |||
| 	fh:mkdir(users_dir .. user) | |||
| 	if check_content(owner_dir) then | |||
| 		fh:cp(owner_dir .. bouquets_xml, users_dir .. user, "a") | |||
| 		fh:cp(owner_dir .. ubouquets_xml, users_dir .. user, "a") | |||
| 	end | |||
| 	fh:touch(users_dir .. user .. passwd) | |||
| 	user_new = nil | |||
| 	return MENU_RETURN.EXIT -- force rebuild menu | |||
| end | |||
| 
 | |||
| function reset(id, value) | |||
| 	if not check_content(owner_dir) then | |||
| 		showhint(locale[lang].panic, locale[lang].cant_reset_plugin) | |||
| 		return | |||
| 	end | |||
| 	local res = messagebox.exec{title=locale[lang].reset, text=locale[lang].reset_confirm, buttons={ "yes", "no" } } | |||
| 	if res == "yes" then | |||
| 		if not get_pin(owner_dir) then | |||
| 			return | |||
| 		end | |||
| 		os.remove(zapit_dir .. bouquets_xml) | |||
| 		fh:cp(owner_dir .. bouquets_xml, zapit_dir .. bouquets_xml, "f") | |||
| 		os.remove(zapit_dir .. ubouquets_xml) | |||
| 		fh:cp(owner_dir .. ubouquets_xml, zapit_dir .. ubouquets_xml, "f") | |||
| 		fh:rmdir(data_dir) | |||
| 		repaint_menu = false | |||
| 		return MENU_RETURN.EXIT_ALL | |||
| 	end | |||
| end | |||
| 
 | |||
| function info() | |||
| 	showhint(locale[lang].caption, locale[lang].info) | |||
| end | |||
| 
 | |||
| -- ---------------------------------------------------------------------------- | |||
| 
 | |||
| n = neutrino() | |||
| m = nil -- the menu | |||
| fh = filehelpers.new() | |||
| 
 | |||
| data_dir = "/var/tuxbox/plugins/userbouquets/" | |||
| owner_dir = data_dir .. "owner/" | |||
| users_dir = data_dir .. "users/" | |||
| user_new = nil | |||
| 
 | |||
| zapit_dir = "/var/tuxbox/config/zapit/" | |||
| bouquets_xml = "bouquets.xml" | |||
| ubouquets_xml = "ubouquets.xml" | |||
| passwd = ".passwd" | |||
| 
 | |||
| locale = {} | |||
| locale["deutsch"] = { | |||
| 	activate = "Aktivieren", | |||
| 	active = "aktiv", | |||
| 	already_active = "Benutzer ist bereits aktiviert.", | |||
| 	apiversion_failed = "Ihre Lua-API ist zu alt. Bitte Neutrino aktualisieren.", | |||
| 	back = "Zurück", | |||
| 	back_hint = "Zurück zum vorherigen Menü.", | |||
| 	cant_change_pin = "PIN kann beim aktiven Benutzer nicht geändert werden", | |||
| 	cant_remove_active = "Der aktive Benutzer kann nicht entfernt werden.", | |||
| 	cant_remove_owner = "Der Eigentümer darf nicht entfernt werden.", | |||
| 	cant_reset_plugin = "Plugin kann nicht zurückgesetzt werden", | |||
| 	caption = "Benutzer-Bouquets" .. " v" .. version, | |||
| 	content_failed = "Fehler! Verzeichnisinhalt nicht korrekt.", | |||
| 	create = "Neuen Benutzer anlegen", | |||
| 	create_hint = "Erstellt einen neuen Benutzer basierend auf den Eigentümer-Daten", | |||
| 	info = "Ben Uwe lebt!", | |||
| 	no_users = "Keine Benutzer angelegt", | |||
| 	owner = "Eigentümer", | |||
| 	panic = "Panik!", | |||
| 	pin = "PIN", | |||
| 	pin_change = "PIN ändern", | |||
| 	pin_changed = "PIN geändert", | |||
| 	pin_new = "Neue PIN", | |||
| 	pin_wrong = "PIN falsch", | |||
| 	remove = "Entfernen", | |||
| 	removed = "Benutzer wurde entfernt.", | |||
| 	reset = "Plugin zurücksetzen", | |||
| 	reset_confirm = "Es werden alle Benutzer-Bouquets und Plugin-Daten gelöscht.\n \nFortfahren?", | |||
| 	reset_hint = "Entferne Benutzer-Bouquets und Plugin-Daten", | |||
| 	selection = "Aktivieren, entfernen oder PIN ändern?", | |||
| 	selection_hint = "Aktion für den Benutzer wählen", | |||
| 	start_confirm = "Dieses Plugin erlaubt es, die Senderlisten bouquets.xml und\nubouquets.xml je nach Benutzer einzustellen.\nSie können dann unabhängig voneinander verwaltet werden.\n \nLöschen Sie das Plugin nicht, bevor sie es nicht zurückgesetzt haben!\n \nFortfahren?", | |||
| 	users = "Benutzer", | |||
| } | |||
| locale["english"] = { | |||
| 	activate = "Activate", | |||
| 	active = "active", | |||
| 	already_active = "User is already activated.", | |||
| 	apiversion_failed = "Your Lua-API is too old. Please update Neutrino.", | |||
| 	back = "Back", | |||
| 	back_hint = "Return to previous menu", | |||
| 	cant_change_pin = "PIN can not be changed while user is active", | |||
| 	cant_remove_active = "The active user can not be removed.", | |||
| 	cant_remove_owner = "The owner may not be removed.", | |||
| 	cant_reset_plugin = "Can't reset plugin.", | |||
| 	caption = "Userbouquets" .. " v" .. version, | |||
| 	content_failed = "Error! Directory content not correct.", | |||
| 	create = "Create new user", | |||
| 	create_hint = "Create new user based apon owner data", | |||
| 	info = "Ben Uwe lives!", | |||
| 	no_users = "No users created", | |||
| 	owner = "Owner", | |||
| 	panic = "Panic!", | |||
| 	pin = "PIN", | |||
| 	pin_change = "Change PIN", | |||
| 	pin_changed = "PIN changed", | |||
| 	pin_new = "New PIN", | |||
| 	pin_wrong = "Wrong PIN", | |||
| 	remove = "Remove", | |||
| 	removed = "User was removed.", | |||
| 	reset = "Reset plugin", | |||
| 	reset_confirm = "All user bouquets and plugin data will be removed.\n \nContinue?", | |||
| 	reset_hint = "Remove user bouquets and plugin data", | |||
| 	selection = "Activate, remove or change PIN?", | |||
| 	selection_hint = "Select action for this user", | |||
| 	start_confirm = "This plugin allows to adjust the channellists bouquets.xml and\nubouquets.xml depending on users.\nThey can be managed independently.\n \nDon't remove this plugin before you don't have executed the built-in reset!\n \nContinue?", | |||
| 	users = "Users", | |||
| } | |||
| 
 | |||
| local neutrino_conf = configfile.new() | |||
| neutrino_conf:loadConfig("/var/tuxbox/config/neutrino.conf") | |||
| lang = neutrino_conf:getString("language", "english") | |||
| if locale[lang] == nil then | |||
| 	lang = "english" | |||
| end | |||
| timing_menu = neutrino_conf:getString("timing.menu", "0") | |||
| 
 | |||
| -- ---------------------------------------------------------------------------- | |||
| 
 | |||
| function init() | |||
| 	if not check_content(owner_dir) then | |||
| 		local res = messagebox.exec{title=locale[lang].caption, text=locale[lang].start_confirm, buttons={ "yes", "no" } } | |||
| 		if res == "no" then | |||
| 			return false | |||
| 		end | |||
| 		fh:mkdir(owner_dir) | |||
| 		fh:mkdir(users_dir) | |||
| 		fh:cp(zapit_dir .. bouquets_xml, owner_dir, "a") | |||
| 		fh:cp(zapit_dir .. bouquets_xml, zapit_dir .. bouquets_xml .. ".bak", "a") | |||
| 		fh:cp(zapit_dir .. ubouquets_xml, owner_dir, "a") | |||
| 		fh:cp(zapit_dir .. ubouquets_xml, zapit_dir .. ubouquets_xml .. ".bak", "a") | |||
| 		fh:touch(owner_dir .. passwd) | |||
| 		activate(owner_dir) | |||
| 	end | |||
| 	return true | |||
| end | |||
| 
 | |||
| function paint_menu() | |||
| 	m = menu.new{name=locale[lang].caption, icon="settings"} | |||
| 	m:addKey{directkey=RC.home, id="home", action="exit_menu"} | |||
| 	m:addKey{directkey=RC.setup, id="setup", action="exit_menu"} | |||
| 	m:addKey{directkey=RC.info, id="info", action="info"} | |||
| 	m:addItem{type="separator"} | |||
| 	m:addItem{type="forwarder", id="home", action="exit_menu", name=locale[lang].back, icon="home", directkey=RC.home, hint_icon="hint_back", hint=locale[lang].back_hint}; | |||
| 	m:addItem{type="separatorline"} | |||
| 
 | |||
| 	m:addItem { | |||
| 		type="forwarder", | |||
| 		action="selection", | |||
| 		enabled=check_content(owner_dir), | |||
| 		id=owner_dir, | |||
| 		name=get_username(owner_dir), | |||
| 		right_icon=get_active_icon(owner_dir), | |||
| 		directkey=RC.red, | |||
| 		hint_icon="hint_service", | |||
| 		hint=locale[lang].selection_hint | |||
| 	} | |||
| 
 | |||
| 	m:addItem{type="separator"} | |||
| 
 | |||
| 	user_new = "" | |||
| 	m:addItem { | |||
| 		type="keyboardinput", | |||
| 		action="create",  | |||
| 		id="dummy", | |||
| 		value=user_new, | |||
| 		name=locale[lang].create, | |||
| 		directkey=RC.green, | |||
| 		hint_icon="hint_bedit", | |||
| 		hint=locale[lang].create_hint | |||
| 	} | |||
| 
 | |||
| 	m:addItem{type="separatorline", name=locale[lang].users} | |||
| 
 | |||
| 	local i = 0 | |||
| 	local d = io.popen('find "' .. users_dir .. '" -type d -maxdepth 1 -mindepth 1') | |||
| 	for user_dir in d:lines() do | |||
| 		i = i + 1 | |||
| 		m:addItem { | |||
| 			type="forwarder", | |||
| 			action="selection", | |||
| 			enabled=check_content(user_dir), | |||
| 			id=user_dir, | |||
| 			name=get_username(user_dir), | |||
| 			right_icon=get_active_icon(user_dir), | |||
| 			directkey=RC[""..i..""]; | |||
| 			hint_icon="hint_service", | |||
| 			hint=locale[lang].selection_hint | |||
| 		} | |||
| 	end | |||
| 	if i == 0 then | |||
| 		m:addItem { | |||
| 			type="forwarder", | |||
| 			enabled=false, | |||
| 			name=locale[lang].no_users, | |||
| 		} | |||
| 	end | |||
| 
 | |||
| 	m:addItem{type="separatorline"} | |||
| 	m:addItem{type="separator"} | |||
| 
 | |||
| 	m:addItem { | |||
| 		type="forwarder", | |||
| 		action="reset", | |||
| 		name=locale[lang].reset, | |||
| 		directkey=RC.blue, | |||
| 		hint_icon="hint_delete", | |||
| 		hint=locale[lang].reset_hint | |||
| 	} | |||
| 
 | |||
| 	m:exec() | |||
| --[[ | |||
| 	msg, data = n:GetInput(50) | |||
| 	if msg == RC.timeout then | |||
| 		repaint_menu = false | |||
| 	end | |||
| ]] | |||
| end | |||
| 
 | |||
| function hide_menu() | |||
| 	if m ~= nil then | |||
| 		m:hide() | |||
| 	end | |||
| end | |||
| 
 | |||
| function exit_menu(id) | |||
| 	repaint_menu = false | |||
| 	if id == "setup" then | |||
| 		return MENU_RETURN.EXIT_ALL | |||
| 	end | |||
| 	return MENU_RETURN.EXIT | |||
| end | |||
| 
 | |||
| function selection(dir) | |||
| 	hide_menu() | |||
| 
 | |||
| 	local dx = n:scale2Res(500) | |||
| 	local dy = n:scale2Res(150) | |||
| 	local x = SCREEN.OFF_X + (((SCREEN.END_X - SCREEN.OFF_X) - dx) / 2) | |||
| 	local y = SCREEN.OFF_Y + (((SCREEN.END_Y - SCREEN.OFF_Y) - dy) / 2) | |||
| 	local t = get_username(dir) | |||
| 	if check_active(dir) then | |||
| 		t = t .. " (" .. locale[lang].active .. ")" | |||
| 	end | |||
| 
 | |||
| 	local chooser = cwindow.new{x=x, y=y, dx=dx, dy=dy, title=t, icon="settings", has_shadow=true, show_footer=true, btnGreen=locale[lang].activate, btnYellow=locale[lang].remove, btnBlue=locale[lang].pin_change} | |||
| 	ctext.new{parent=chooser, x=n:scale2Res(10), y=0, dx=dx-n:scale2Res(2*10), dy=dy-chooser:headerHeight(), text=locale[lang].selection, font_text=FONT.MENU, mode="ALIGN_CENTER"} | |||
| 	chooser:paint() | |||
| 
 | |||
| 	local i = 0 | |||
| 	local d = 500 -- ms | |||
| 	local t = (timing_menu * 1000) / d | |||
| 	if t == 0 then | |||
| 		t = -1 -- no timeout | |||
| 	end | |||
| 	repeat | |||
| 		i = i + 1 | |||
| 		msg, data = n:GetInput(d) | |||
| 		if (msg == RC.ok) or (msg == RC.green) then | |||
| 			activate(dir) | |||
| 			msg = RC.home | |||
| 		elseif (msg == RC.yellow) then | |||
| 			remove(dir) | |||
| 			msg = RC.home | |||
| 		elseif (msg == RC.blue) then | |||
| 			chooser:hide() | |||
| 			pin(dir) | |||
| 			chooser:paint() | |||
| 		end | |||
| 	until msg == RC.home or msg == RC.setup or i == t; | |||
| 
 | |||
| 	chooser:hide() | |||
| 	chooser = nil | |||
| 
 | |||
| 	if msg == RC.setup then | |||
| 		repaint_menu = false | |||
| 		return MENU_RETURN.EXIT_ALL | |||
| 	end | |||
| 	return MENU_RETURN.EXIT | |||
| end | |||
| 
 | |||
| -- --------------------------------------------------------------------------- | |||
| 
 | |||
| if APIVERSION.MAJOR .. APIVERSION.MINOR < "156" then | |||
| 	local apiversion = "Lua-Api v" .. APIVERSION.MAJOR .. "." .. APIVERSION.MINOR .. "\n \n" | |||
| 	showhint(locale[lang].panic, apiversion .. locale[lang].apiversion_failed) | |||
| 	return | |||
| end | |||
| 
 | |||
| if init() then | |||
| 	repaint_menu = true | |||
| 	while repaint_menu do | |||
| 		paint_menu() | |||
| 	end | |||
| end | |||
					Loading…
					
					
				
		Reference in new issue