continuous-integration/drone/push Build encountered an error
Client (ts/network_ts.ts): one WebSocket per page. Commands queue and go out one at a time with a client-chosen id; the response is matched on the echoed id (or to the in-flight request for older servers). 12 s timeout per request, exponential-backoff reconnect (0.5 s to 10 s), the in-flight request is retried after a reconnect, and log polls are de-duplicated so they cannot pile up behind a stalled connection. The old global flag that silently dropped any request made while another was in flight is gone. Server (src/webserver.go): the /data/ handler now serves any number of commands on one connection (it used to break out of its loop after the first reply without closing the socket, leaving it open and deaf; the old client papered over that by opening a new socket per request). Connection closed on exit, request id echoed in the response. Test: TestWSServesMultipleCommandsPerConnection.
2478 lines
69 KiB
TypeScript
2478 lines
69 KiB
TypeScript
|
|
class MainMenu {
|
|
DocumentID:string = "main-menu"
|
|
HTMLTag:string = "LI"
|
|
ImagePath:string = "img/"
|
|
|
|
createIMG(src):any {
|
|
var element = document.createElement("IMG")
|
|
element.setAttribute("src", this.ImagePath + src)
|
|
return element
|
|
}
|
|
|
|
createValue(value):any {
|
|
var element = document.createElement("P")
|
|
element.textContent = value
|
|
return element
|
|
}
|
|
}
|
|
|
|
class MainMenuItem extends MainMenu {
|
|
menuKey:string
|
|
value:string
|
|
imgSrc:string
|
|
headline:string
|
|
id:string
|
|
tableHeader:string[]
|
|
|
|
constructor(menuKey:string, value:string, image:string, headline:string) {
|
|
super()
|
|
this.menuKey = menuKey
|
|
this.value = value
|
|
this.imgSrc = image
|
|
this.headline = headline
|
|
}
|
|
|
|
createItem():void {
|
|
var item = document.createElement("LI")
|
|
item.setAttribute("onclick", "javascript: openThisMenu(this)")
|
|
item.setAttribute("id", this.id)
|
|
item.setAttribute("data-menu", this.menuKey)
|
|
var img = this.createIMG(this.imgSrc)
|
|
var value = this.createValue(this.value)
|
|
|
|
item.appendChild(img)
|
|
item.appendChild(value)
|
|
|
|
var doc = document.getElementById(this.DocumentID)
|
|
doc.appendChild(item)
|
|
|
|
switch(this.menuKey) {
|
|
case "playlist":
|
|
this.tableHeader = ["Playlist", "Tuner", "Last Update", "Availability %", "Type", "Streams", "group-title %", "tvg-id %", "Unique ID %"]
|
|
break
|
|
|
|
case "xmltv":
|
|
this.tableHeader = ["Guide", "Last Update", "Availability %", "Channels", "Programs"]
|
|
break
|
|
|
|
case "filter":
|
|
this.tableHeader = ["Filter Name", "Filter Type", "Filter"]
|
|
break
|
|
|
|
case "users":
|
|
this.tableHeader = ["Username", "Password", "WEB", "PMS", "M3U", "XML", "API"]
|
|
break
|
|
|
|
case "mapping":
|
|
this.tableHeader = ["BULK", "Ch. No.", "Logo", "Channel Name", "Playlist", "Group Title", "XMLTV File", "XMLTV ID", "Edit"]
|
|
break
|
|
|
|
}
|
|
|
|
//console.log(this.menuKey, this.tableHeader);
|
|
|
|
}
|
|
}
|
|
|
|
class Content {
|
|
|
|
DocumentID:string = "content"
|
|
TableID:string = "content_table"
|
|
DivID:string
|
|
headerClass:string = "content_table_header"
|
|
interactionID:string = "content-interaction"
|
|
|
|
createHeadline(value):any {
|
|
var element = document.createElement("H3")
|
|
element.textContent = value
|
|
return element
|
|
}
|
|
|
|
createHR():any {
|
|
var element = document.createElement("HR")
|
|
return element
|
|
}
|
|
|
|
createInteraction():any {
|
|
var element = document.createElement("DIV")
|
|
element.setAttribute("id", this.interactionID)
|
|
return element
|
|
}
|
|
|
|
createDIV():any {
|
|
var element = document.createElement("DIV")
|
|
element.id = this.DivID
|
|
return element
|
|
}
|
|
|
|
createTABLE():any {
|
|
var element = document.createElement("TABLE")
|
|
element.id = this.TableID
|
|
return element
|
|
}
|
|
|
|
createTableRow():any {
|
|
var element = document.createElement("TR")
|
|
element.className = this.headerClass
|
|
return element
|
|
}
|
|
|
|
createTableContent(menuKey:string):string[] {
|
|
|
|
var data = new Object()
|
|
var rows = new Array()
|
|
|
|
switch(menuKey) {
|
|
case "playlist":
|
|
var fileTypes = new Array("m3u", "hdhr")
|
|
|
|
fileTypes.forEach(fileType => {
|
|
|
|
data = SERVER["settings"]["files"][fileType]
|
|
|
|
var keys = getObjKeys(data)
|
|
|
|
keys.forEach(key => {
|
|
var tr = document.createElement("TR")
|
|
tr.id = key
|
|
|
|
tr.setAttribute('onclick', 'javascript: openPopUp("' + fileType + '", this)')
|
|
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "P"
|
|
cell.value = data[key]["name"]
|
|
tr.appendChild(cell.createCell())
|
|
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "P"
|
|
if (SERVER["settings"]["buffer"] != "-") {
|
|
cell.value = data[key]["tuner"]
|
|
} else {
|
|
cell.value = "-"
|
|
}
|
|
|
|
tr.appendChild(cell.createCell())
|
|
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "P"
|
|
cell.value = data[key]["last.update"]
|
|
tr.appendChild(cell.createCell())
|
|
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "P"
|
|
cell.value = data[key]["provider.availability"]
|
|
tr.appendChild(cell.createCell())
|
|
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "P"
|
|
cell.value = data[key]["type"].toUpperCase();
|
|
tr.appendChild(cell.createCell())
|
|
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "P"
|
|
cell.value = data[key]["compatibility"]["streams"]
|
|
tr.appendChild(cell.createCell())
|
|
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "P"
|
|
cell.value = data[key]["compatibility"]["group.title"]
|
|
tr.appendChild(cell.createCell())
|
|
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "P"
|
|
cell.value = data[key]["compatibility"]["tvg.id"]
|
|
tr.appendChild(cell.createCell())
|
|
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "P"
|
|
cell.value = data[key]["compatibility"]["stream.id"]
|
|
tr.appendChild(cell.createCell())
|
|
|
|
rows.push(tr)
|
|
});
|
|
|
|
});
|
|
break
|
|
|
|
case "filter":
|
|
delete SERVER["settings"]["filter"][-1]
|
|
data = SERVER["settings"]["filter"]
|
|
var keys = getObjKeys(data)
|
|
keys.forEach(key => {
|
|
var tr = document.createElement("TR")
|
|
tr.id = key
|
|
|
|
tr.setAttribute('onclick', 'javascript: openPopUp("' + data[key]["type"] + '", this)')
|
|
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "P"
|
|
cell.value = data[key]["name"]
|
|
tr.appendChild(cell.createCell())
|
|
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "P"
|
|
switch (data[key]["type"]) {
|
|
case "custom-filter":
|
|
cell.value = "Custom"
|
|
break;
|
|
|
|
case "group-title":
|
|
cell.value = "Group"
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
tr.appendChild(cell.createCell())
|
|
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "P"
|
|
cell.value = data[key]["filter"]
|
|
tr.appendChild(cell.createCell())
|
|
|
|
rows.push(tr)
|
|
|
|
});
|
|
break
|
|
|
|
case "xmltv":
|
|
var fileTypes = new Array("xmltv")
|
|
|
|
fileTypes.forEach(fileType => {
|
|
|
|
data = SERVER["settings"]["files"][fileType]
|
|
|
|
var keys = getObjKeys(data)
|
|
|
|
keys.forEach(key => {
|
|
var tr = document.createElement("TR")
|
|
|
|
tr.id = key
|
|
tr.setAttribute('onclick', 'javascript: openPopUp("' + fileType + '", this)')
|
|
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "P"
|
|
cell.value = data[key]["name"]
|
|
tr.appendChild(cell.createCell())
|
|
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "P"
|
|
cell.value = data[key]["last.update"]
|
|
tr.appendChild(cell.createCell())
|
|
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "P"
|
|
cell.value = data[key]["provider.availability"]
|
|
tr.appendChild(cell.createCell())
|
|
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "P"
|
|
cell.value = data[key]["compatibility"]["xmltv.channels"]
|
|
tr.appendChild(cell.createCell())
|
|
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "P"
|
|
cell.value = data[key]["compatibility"]["xmltv.programs"]
|
|
tr.appendChild(cell.createCell())
|
|
|
|
rows.push(tr)
|
|
});
|
|
|
|
});
|
|
break
|
|
|
|
case "users":
|
|
var fileTypes = new Array("users")
|
|
|
|
fileTypes.forEach(fileType => {
|
|
data = SERVER[fileType]
|
|
|
|
var keys = getObjKeys(data)
|
|
|
|
keys.forEach(key => {
|
|
var tr = document.createElement("TR")
|
|
tr.id = key
|
|
tr.setAttribute('onclick', 'javascript: openPopUp("' + fileType + '", this)')
|
|
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "P"
|
|
cell.value = data[key]["data"]["username"]
|
|
tr.appendChild(cell.createCell())
|
|
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "P"
|
|
cell.value = "******"
|
|
tr.appendChild(cell.createCell())
|
|
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "P"
|
|
if (data[key]["data"]["authentication.web"] == true) {
|
|
cell.value = "✓"
|
|
} else {
|
|
cell.value = "-"
|
|
}
|
|
tr.appendChild(cell.createCell())
|
|
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "P"
|
|
if (data[key]["data"]["authentication.pms"] == true) {
|
|
cell.value = "✓"
|
|
} else {
|
|
cell.value = "-"
|
|
}
|
|
tr.appendChild(cell.createCell())
|
|
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "P"
|
|
if (data[key]["data"]["authentication.m3u"] == true) {
|
|
cell.value = "✓"
|
|
} else {
|
|
cell.value = "-"
|
|
}
|
|
tr.appendChild(cell.createCell())
|
|
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "P"
|
|
if (data[key]["data"]["authentication.xml"] == true) {
|
|
cell.value = "✓"
|
|
} else {
|
|
cell.value = "-"
|
|
}
|
|
tr.appendChild(cell.createCell())
|
|
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "P"
|
|
if (data[key]["data"]["authentication.api"] == true) {
|
|
cell.value = "✓"
|
|
} else {
|
|
cell.value = "-"
|
|
}
|
|
tr.appendChild(cell.createCell())
|
|
|
|
rows.push(tr)
|
|
});
|
|
|
|
});
|
|
break
|
|
|
|
case "mapping":
|
|
BULK_EDIT = false
|
|
createSearchObj()
|
|
checkUndo("epgMapping")
|
|
console.log("MAPPING")
|
|
data = SERVER["xepg"]["epgMapping"]
|
|
|
|
var keys = getObjKeys(data)
|
|
keys.forEach(key => {
|
|
var tr = document.createElement("TR")
|
|
tr.id = key
|
|
|
|
//tr.setAttribute('oncontextmenu', 'javascript: rightClick(this)')
|
|
|
|
switch (data[key]["x-active"]) {
|
|
case true:
|
|
tr.className = "activeEPG"
|
|
break;
|
|
|
|
case false:
|
|
tr.className = "notActiveEPG"
|
|
break;
|
|
}
|
|
|
|
// Bulk
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "BULK"
|
|
cell.value = false
|
|
tr.appendChild(cell.createCell())
|
|
|
|
// Kanalnummer
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "INPUTCHANNEL"
|
|
cell.value = data[key]["x-channelID"]
|
|
//td.setAttribute('onclick', 'javascript: changeChannelNumber("' + key + '", this)')
|
|
tr.appendChild(cell.createCell())
|
|
|
|
// Logo
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "IMG"
|
|
cell.imageURL = data[key]["tvg-logo"]
|
|
tr.appendChild(cell.createCell())
|
|
|
|
// Kanalname
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "P"
|
|
cell.className = data[key]["x-category"]
|
|
cell.value = data[key]["x-name"]
|
|
tr.appendChild(cell.createCell())
|
|
|
|
|
|
// Playlist
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "P"
|
|
//cell.value = data[key]["_file.m3u.name"]
|
|
cell.value = getValueFromProviderFile(data[key]["_file.m3u.id"], "m3u", "name")
|
|
tr.appendChild(cell.createCell())
|
|
|
|
|
|
// Gruppe (group-title)
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "P"
|
|
cell.value = data[key]["x-group-title"]
|
|
tr.appendChild(cell.createCell())
|
|
|
|
// XMLTV Datei
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "P"
|
|
|
|
if (data[key]["x-xmltv-file"] != "-") {
|
|
cell.value = getValueFromProviderFile(data[key]["x-xmltv-file"], "xmltv", "name")
|
|
} else {
|
|
cell.value = data[key]["x-xmltv-file"]
|
|
}
|
|
|
|
tr.appendChild(cell.createCell())
|
|
|
|
// XMLTV Kanal
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "P"
|
|
//var value = str.substring(1, 4);
|
|
var value = data[key]["x-mapping"]
|
|
if (value.length > 20) {
|
|
value = data[key]["x-mapping"].substring(0, 20) + "..."
|
|
}
|
|
cell.value = value
|
|
tr.appendChild(cell.createCell())
|
|
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "EDIT"
|
|
cell.value = "Edit"
|
|
var editTd = cell.createCell()
|
|
var editButton = (editTd.firstChild as HTMLInputElement)
|
|
editButton.setAttribute('onclick', 'javascript: openPopUp("mapping", this)')
|
|
editButton.setAttribute("id", key)
|
|
editButton.setAttribute("aria-label", "Edit " + data[key]["x-name"])
|
|
tr.appendChild(editTd)
|
|
|
|
rows.push(tr)
|
|
});
|
|
|
|
break
|
|
|
|
case "settings":
|
|
alert()
|
|
break
|
|
|
|
default:
|
|
console.log("Table content (menuKey):", menuKey);
|
|
|
|
break
|
|
|
|
}
|
|
|
|
return rows
|
|
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
class Cell {
|
|
child:Boolean
|
|
childType:string
|
|
value:any
|
|
className:string
|
|
tdClassName:string
|
|
imageURL:string
|
|
onclick:boolean
|
|
onclickFunktion:string
|
|
|
|
createCell():any {
|
|
var td = document.createElement("TD")
|
|
|
|
|
|
if (this.child == true) {
|
|
var element:any
|
|
|
|
switch(this.childType){
|
|
case "P":
|
|
element = document.createElement(this.childType);
|
|
element.textContent = this.value
|
|
element.className = this.className
|
|
break
|
|
|
|
case "INPUT":
|
|
element = document.createElement(this.childType);
|
|
(element as HTMLInputElement).value = this.value;
|
|
(element as HTMLInputElement).type = "text";
|
|
break
|
|
|
|
case "INPUTCHANNEL":
|
|
element = document.createElement("INPUT");
|
|
(element as HTMLInputElement).setAttribute("onchange", "javscript: changeChannelNumber(this)");
|
|
(element as HTMLInputElement).value = this.value;
|
|
(element as HTMLInputElement).type = "text";
|
|
break
|
|
|
|
case "BULK":
|
|
element = document.createElement("INPUT");
|
|
(element as HTMLInputElement).checked = this.value;
|
|
(element as HTMLInputElement).type = "checkbox";
|
|
(element as HTMLInputElement).className = "bulk hideBulk";
|
|
(element as HTMLInputElement).addEventListener("click", function(event) {
|
|
scheduleChannelRangeSelection((element as HTMLInputElement), (event as MouseEvent))
|
|
})
|
|
break
|
|
|
|
case "BULK_HEAD":
|
|
element = document.createElement("INPUT");
|
|
(element as HTMLInputElement).checked = this.value;
|
|
(element as HTMLInputElement).type = "checkbox";
|
|
(element as HTMLInputElement).className = "bulk hideBulk";
|
|
(element as HTMLInputElement).setAttribute("onclick", "javascript: selectAllChannels()")
|
|
break
|
|
|
|
case "IMG":
|
|
element = document.createElement(this.childType);
|
|
element.setAttribute("src", this.imageURL)
|
|
if (this.imageURL != "") {
|
|
element.setAttribute("onerror", "javascript: this.onerror=null;this.src=''" )
|
|
//onerror="this.onerror=null;this.src='missing.gif';"
|
|
}
|
|
break
|
|
|
|
case "EDIT":
|
|
element = document.createElement("INPUT");
|
|
(element as HTMLInputElement).type = "button";
|
|
(element as HTMLInputElement).value = this.value;
|
|
(element as HTMLInputElement).className = "mapping-edit-button";
|
|
break
|
|
}
|
|
|
|
td.appendChild(element)
|
|
|
|
} else {
|
|
td.textContent = this.value
|
|
}
|
|
|
|
if (this.onclick == true) {
|
|
td.setAttribute("onclick", this.onclickFunktion)
|
|
td.className = "pointer"
|
|
}
|
|
|
|
if (this.tdClassName != undefined) {
|
|
td.className = this.tdClassName
|
|
}
|
|
|
|
return td
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
class ShowContent extends Content {
|
|
menuID:number
|
|
|
|
constructor(menuID:number) {
|
|
super()
|
|
this.menuID = menuID
|
|
}
|
|
|
|
createInput(type:string, name:string, value:string,):any {
|
|
|
|
var input = document.createElement("INPUT")
|
|
input.setAttribute("type", type)
|
|
input.setAttribute("name", name)
|
|
input.setAttribute("value", value)
|
|
return input
|
|
}
|
|
|
|
show():void {
|
|
COLUMN_TO_SORT = -1
|
|
// Alten Inhalt löschen
|
|
var doc = document.getElementById(this.DocumentID)
|
|
doc.innerHTML = ""
|
|
showPreview(false)
|
|
|
|
// Überschrift
|
|
var headline:string[] = menuItems[this.menuID].headline
|
|
|
|
var menuKey = menuItems[this.menuID].menuKey
|
|
var h = this.createHeadline(headline)
|
|
doc.appendChild(h)
|
|
|
|
var hr = this.createHR()
|
|
doc.appendChild(hr)
|
|
|
|
// Interaktion
|
|
var div =this.createInteraction()
|
|
doc.appendChild(div)
|
|
var interaction = document.getElementById(this.interactionID)
|
|
switch (menuKey) {
|
|
case "playlist":
|
|
var input = this.createInput("button", menuKey, "New")
|
|
input.setAttribute("id", "-")
|
|
input.setAttribute("onclick", 'javascript: openPopUp("playlist")')
|
|
interaction.appendChild(input)
|
|
break;
|
|
|
|
case "filter":
|
|
var input = this.createInput("button", menuKey, "New")
|
|
input.setAttribute("id", -1)
|
|
input.setAttribute("onclick", 'javascript: openPopUp("filter", this)')
|
|
interaction.appendChild(input)
|
|
break;
|
|
|
|
|
|
case "xmltv":
|
|
var input = this.createInput("button", menuKey, "New")
|
|
input.setAttribute("id", "xmltv")
|
|
input.setAttribute("onclick", 'javascript: openPopUp("xmltv")')
|
|
interaction.appendChild(input)
|
|
break;
|
|
|
|
case "users":
|
|
var input = this.createInput("button", menuKey, "New")
|
|
input.setAttribute("id", "users")
|
|
input.setAttribute("onclick", 'javascript: openPopUp("users")')
|
|
interaction.appendChild(input)
|
|
break;
|
|
|
|
case "mapping":
|
|
showElement("loading", true)
|
|
var input = this.createInput("button", menuKey, "Save")
|
|
input.setAttribute("onclick", 'javascript: savePopupData("mapping", "", "")')
|
|
interaction.appendChild(input)
|
|
|
|
var input = this.createInput("button", menuKey, "Bulk Edit")
|
|
input.setAttribute("onclick", 'javascript: bulkEdit()')
|
|
interaction.appendChild(input)
|
|
|
|
var input = this.createInput("search", "search", "")
|
|
input.setAttribute("id", "searchMapping")
|
|
input.setAttribute("placeholder", "Search")
|
|
input.className = "search"
|
|
input.setAttribute("oninput", 'javascript: searchInMapping()')
|
|
interaction.appendChild(input)
|
|
break;
|
|
|
|
case "settings":
|
|
var input = this.createInput("button", menuKey, "Save")
|
|
input.setAttribute("onclick", 'javascript: saveSettings();')
|
|
interaction.appendChild(input)
|
|
|
|
var input = this.createInput("button", menuKey, "Backup")
|
|
input.setAttribute("onclick", 'javascript: backup();')
|
|
interaction.appendChild(input)
|
|
|
|
var input = this.createInput("button", menuKey, "Restore")
|
|
input.setAttribute("onclick", 'javascript: restore();')
|
|
interaction.appendChild(input)
|
|
|
|
var wrapper = document.createElement("DIV")
|
|
wrapper.setAttribute("id", "box-wrapper")
|
|
doc.appendChild(wrapper)
|
|
|
|
this.DivID = "content_settings"
|
|
var settings = this.createDIV()
|
|
wrapper.appendChild(settings)
|
|
|
|
showSettings()
|
|
|
|
return
|
|
break
|
|
|
|
case "log":
|
|
var input = this.createInput("button", menuKey, "Reset Logs")
|
|
input.setAttribute("onclick", 'javascript: resetLogs();')
|
|
interaction.appendChild(input)
|
|
|
|
var wrapper = document.createElement("DIV")
|
|
wrapper.setAttribute("id", "box-wrapper")
|
|
doc.appendChild(wrapper)
|
|
|
|
this.DivID = "content_log"
|
|
var logs = this.createDIV()
|
|
wrapper.appendChild(logs)
|
|
|
|
showLogs(true)
|
|
|
|
return
|
|
break
|
|
|
|
case "logout":
|
|
location.reload()
|
|
document.cookie = "Token= ; expires = Thu, 01 Jan 1970 00:00:00 GMT"
|
|
break
|
|
|
|
default:
|
|
console.log("Show content (menuKey):", menuKey);
|
|
break;
|
|
}
|
|
|
|
// Tabelle erstellen (falls benötigt)
|
|
var tableHeader:string[] = menuItems[this.menuID].tableHeader
|
|
if (tableHeader.length > 0) {
|
|
var wrapper = document.createElement("DIV")
|
|
doc.appendChild(wrapper)
|
|
wrapper.setAttribute("id", "box-wrapper")
|
|
|
|
var table = this.createTABLE()
|
|
wrapper.appendChild(table)
|
|
|
|
var header = this.createTableRow()
|
|
table.appendChild(header)
|
|
|
|
// Kopfzeile der Tablle
|
|
tableHeader.forEach(element => {
|
|
var cell:Cell = new Cell()
|
|
cell.child = true
|
|
cell.childType = "P"
|
|
cell.value = element
|
|
if (element == "BULK") {
|
|
cell.childType = "BULK_HEAD";
|
|
cell.value = false
|
|
}
|
|
|
|
if (menuKey == "mapping") {
|
|
|
|
if (element == "Ch. No.") {
|
|
cell.onclick = true
|
|
cell.onclickFunktion = "javascript: sortTable(1);"
|
|
cell.tdClassName = "sortThis"
|
|
}
|
|
|
|
if (element == "Channel Name") {
|
|
cell.onclick = true
|
|
cell.onclickFunktion = "javascript: sortTable(3);"
|
|
}
|
|
|
|
if (element == "Playlist") {
|
|
cell.onclick = true
|
|
cell.onclickFunktion = "javascript: sortTable(4);"
|
|
}
|
|
|
|
if (element == "Group Title") {
|
|
cell.onclick = true
|
|
cell.onclickFunktion = "javascript: sortTable(5);"
|
|
}
|
|
|
|
}
|
|
|
|
header.appendChild(cell.createCell())
|
|
});
|
|
|
|
table.appendChild(header)
|
|
|
|
// Inhalt der Tabelle
|
|
var rows:any = this.createTableContent(menuKey)
|
|
rows.forEach(tr => {
|
|
table.appendChild(tr)
|
|
});
|
|
|
|
}
|
|
|
|
switch (menuKey) {
|
|
case "mapping":
|
|
sortTable(1)
|
|
break;
|
|
|
|
case "filter":
|
|
showPreview(true)
|
|
sortTable(0)
|
|
break
|
|
|
|
default:
|
|
COLUMN_TO_SORT = -1
|
|
sortTable(0)
|
|
break;
|
|
}
|
|
|
|
showElement("loading", false)
|
|
}
|
|
|
|
}
|
|
|
|
var SHELL_LAYOUT_READY:boolean = false
|
|
|
|
function setLayoutMenuState(open:boolean) {
|
|
if (document.body == null) {
|
|
return
|
|
}
|
|
|
|
if (open == true) {
|
|
document.body.classList.add("menu-open")
|
|
} else {
|
|
document.body.classList.remove("menu-open")
|
|
}
|
|
}
|
|
|
|
function toggleLayoutMenu() {
|
|
if (document.body == null) {
|
|
return
|
|
}
|
|
|
|
var isOpen:boolean = document.body.classList.contains("menu-open")
|
|
setLayoutMenuState(!isOpen)
|
|
}
|
|
|
|
function closeLayoutMenuIfMobile() {
|
|
if (window.innerWidth <= 900) {
|
|
setLayoutMenuState(false)
|
|
}
|
|
}
|
|
|
|
function setActiveMenu(menuID:string) {
|
|
|
|
ACTIVE_MENU_ID = menuID.toString()
|
|
var menu = document.getElementById("main-menu")
|
|
if (menu == null) {
|
|
return
|
|
}
|
|
|
|
var items = menu.getElementsByTagName("LI")
|
|
for (var i = 0; i < items.length; i++) {
|
|
items[i].classList.remove("menu-active")
|
|
}
|
|
|
|
var activeItem = document.getElementById(ACTIVE_MENU_ID)
|
|
var activeMenuKey:string = ""
|
|
if (activeItem != null) {
|
|
activeItem.classList.add("menu-active")
|
|
var menuKeyValue = activeItem.getAttribute("data-menu")
|
|
if (menuKeyValue != null) {
|
|
activeMenuKey = menuKeyValue
|
|
}
|
|
}
|
|
|
|
if (document.body != null) {
|
|
if (activeMenuKey.length > 0) {
|
|
document.body.setAttribute("data-active-menu", activeMenuKey)
|
|
} else {
|
|
document.body.removeAttribute("data-active-menu")
|
|
}
|
|
|
|
if (activeMenuKey == "log") {
|
|
document.body.classList.add("menu-log-focus")
|
|
} else {
|
|
document.body.classList.remove("menu-log-focus")
|
|
}
|
|
}
|
|
}
|
|
|
|
function renderStatusCards() {
|
|
var wrapper = document.getElementById("status-cards")
|
|
if (wrapper == null || SERVER.hasOwnProperty("clientInfo") == false) {
|
|
return
|
|
}
|
|
|
|
var info = SERVER["clientInfo"]
|
|
var errors:number = parseInt(info["errors"], 10)
|
|
var warnings:number = parseInt(info["warnings"], 10)
|
|
var cards:any[] = [
|
|
{label: "Streams", value: info["streams"], tone: "ok"},
|
|
{label: "EPG Source", value: info["epgSource"], tone: "neutral"},
|
|
{label: "XEPG Channels", value: info["xepg"], tone: "ok"},
|
|
{label: "Errors", value: info["errors"], tone: errors > 0 ? "error" : "ok"},
|
|
{label: "Warnings", value: info["warnings"], tone: warnings > 0 ? "warn" : "ok"},
|
|
{label: "DVR", value: info["DVR"], tone: "neutral"},
|
|
]
|
|
|
|
wrapper.innerHTML = ""
|
|
cards.forEach(card => {
|
|
|
|
var box = document.createElement("DIV")
|
|
box.className = "status-card status-card-" + card.tone
|
|
|
|
var label = document.createElement("P")
|
|
label.className = "status-card-label"
|
|
label.innerText = card.label
|
|
|
|
var value = document.createElement("P")
|
|
value.className = "status-card-value"
|
|
if (card.value == undefined || card.value == "") {
|
|
value.innerText = "-"
|
|
} else {
|
|
value.innerText = card.value
|
|
}
|
|
|
|
box.appendChild(label)
|
|
box.appendChild(value)
|
|
wrapper.appendChild(box)
|
|
});
|
|
|
|
}
|
|
|
|
function initShellLayout() {
|
|
|
|
if (SHELL_LAYOUT_READY == true) {
|
|
return
|
|
}
|
|
|
|
var toggle = document.getElementById("menu-toggle")
|
|
if (toggle != null) {
|
|
toggle.onclick = function() {
|
|
toggleLayoutMenu()
|
|
}
|
|
}
|
|
|
|
var overlay = document.getElementById("layout-overlay")
|
|
if (overlay != null) {
|
|
overlay.onclick = function() {
|
|
setLayoutMenuState(false)
|
|
}
|
|
}
|
|
|
|
document.addEventListener("keydown", function(event) {
|
|
|
|
if (event.key == "Escape") {
|
|
setLayoutMenuState(false)
|
|
showElement("popup", false)
|
|
return
|
|
}
|
|
|
|
if (event.key == "/") {
|
|
var target = event.target as HTMLElement
|
|
var onInput = target.tagName == "INPUT" || target.tagName == "TEXTAREA" || target.tagName == "SELECT"
|
|
|
|
if (onInput == true) {
|
|
return
|
|
}
|
|
|
|
var search = document.getElementById("searchMapping")
|
|
if (search != null) {
|
|
event.preventDefault();
|
|
(search as HTMLInputElement).focus()
|
|
}
|
|
}
|
|
|
|
});
|
|
|
|
setConnectionState("idle")
|
|
SHELL_LAYOUT_READY = true
|
|
}
|
|
|
|
function shouldPollLogs():boolean {
|
|
if (document.hidden == true) {
|
|
return false
|
|
}
|
|
|
|
if (document.getElementById("content_log") == null) {
|
|
return false
|
|
}
|
|
|
|
if (ACTIVE_MENU_ID.length < 1) {
|
|
return false
|
|
}
|
|
|
|
var activeItem = document.getElementById(ACTIVE_MENU_ID)
|
|
if (activeItem == null) {
|
|
return false
|
|
}
|
|
|
|
return activeItem.getAttribute("data-menu") == "log"
|
|
}
|
|
|
|
function PageReady() {
|
|
|
|
initShellLayout()
|
|
|
|
var server:Server = new Server("getServerConfig")
|
|
server.request(new Object())
|
|
|
|
var bootstrapAttempts:number = 0
|
|
var maxBootstrapAttempts:number = 5
|
|
var bootstrapTimer:number = window.setInterval(function() {
|
|
|
|
if (SERVER.hasOwnProperty("clientInfo") == true) {
|
|
window.clearInterval(bootstrapTimer)
|
|
return
|
|
}
|
|
|
|
if (WS.hasQueued("getServerConfig")) {
|
|
return
|
|
}
|
|
|
|
bootstrapAttempts++
|
|
var retryServer:Server = new Server("getServerConfig")
|
|
retryServer.request(new Object())
|
|
|
|
if (bootstrapAttempts >= maxBootstrapAttempts) {
|
|
window.clearInterval(bootstrapTimer)
|
|
}
|
|
|
|
}, 3000)
|
|
|
|
window.addEventListener("resize", function(){
|
|
if (window.innerWidth > 900) {
|
|
setLayoutMenuState(false)
|
|
}
|
|
calculateWrapperHeight();
|
|
}, true);
|
|
|
|
setInterval(function(){
|
|
if (shouldPollLogs() == false) {
|
|
return
|
|
}
|
|
updateLog()
|
|
}, 10000);
|
|
|
|
|
|
return
|
|
}
|
|
|
|
function isClientInfoHttpURL(value:string):boolean {
|
|
return /^https?:\/\//i.test(value)
|
|
}
|
|
|
|
function setClientInfoValue(key:string, value:any) {
|
|
var element = document.getElementById(key)
|
|
if (element == null) {
|
|
return
|
|
}
|
|
|
|
var textValue = ""
|
|
if (value != undefined && value != null) {
|
|
textValue = String(value)
|
|
}
|
|
|
|
if ((key == "m3u-url" || key == "xepg-url") && isClientInfoHttpURL(textValue)) {
|
|
element.innerHTML = ""
|
|
var anchor = document.createElement("a")
|
|
anchor.href = textValue
|
|
anchor.target = "_blank"
|
|
anchor.rel = "noopener noreferrer"
|
|
anchor.textContent = textValue
|
|
element.appendChild(anchor)
|
|
return
|
|
}
|
|
|
|
element.textContent = textValue
|
|
}
|
|
|
|
function createLayout() {
|
|
|
|
// Client Info
|
|
var obj = SERVER["clientInfo"]
|
|
var keys = getObjKeys(obj);
|
|
for (var i = 0; i < keys.length; i++) {
|
|
|
|
setClientInfoValue(keys[i], obj[keys[i]])
|
|
|
|
}
|
|
renderStatusCards()
|
|
|
|
if (!document.getElementById("main-menu")) {
|
|
return
|
|
}
|
|
|
|
|
|
|
|
// Menü erstellen
|
|
document.getElementById("main-menu").innerHTML = ""
|
|
for (let i = 0; i < menuItems.length; i++) {
|
|
|
|
menuItems[i].id = i
|
|
|
|
switch (menuItems[i]["menuKey"]) {
|
|
|
|
case "users":
|
|
case "logout":
|
|
if (SERVER["settings"]["authentication.web"] == true) {
|
|
menuItems[i].createItem()
|
|
}
|
|
break
|
|
|
|
case "mapping":
|
|
case "xmltv":
|
|
if (SERVER["clientInfo"]["epgSource"] == "XEPG") {
|
|
menuItems[i].createItem()
|
|
}
|
|
break
|
|
|
|
default:
|
|
menuItems[i].createItem()
|
|
break
|
|
}
|
|
|
|
}
|
|
|
|
if (ACTIVE_MENU_ID.length > 0 && document.getElementById(ACTIVE_MENU_ID)) {
|
|
setActiveMenu(ACTIVE_MENU_ID)
|
|
}
|
|
|
|
var content = document.getElementById("content")
|
|
var menu = document.getElementById("main-menu")
|
|
if (ACTIVE_MENU_ID.length == 0 && content != null && menu != null) {
|
|
|
|
if (content.innerHTML.replace(/\\s/g, "").length == 0) {
|
|
var firstItem = menu.getElementsByTagName("LI")[0] as HTMLElement
|
|
if (firstItem != undefined) {
|
|
firstItem.click()
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
function openThisMenu(element) {
|
|
var id = element.id
|
|
var content:ShowContent = new ShowContent(id)
|
|
setActiveMenu(id)
|
|
content.show()
|
|
closeLayoutMenuIfMobile()
|
|
calculateWrapperHeight()
|
|
|
|
return
|
|
}
|
|
|
|
class PopupWindow {
|
|
DocumentID:string = "popup-custom"
|
|
InteractionID:string = "interaction"
|
|
doc = document.getElementById(this.DocumentID)
|
|
|
|
createTitle(title:string):any {
|
|
var td = document.createElement("TD")
|
|
td.className = "left"
|
|
td.innerHTML = title + ":"
|
|
return td
|
|
}
|
|
|
|
createContent(element):any {
|
|
var td = document.createElement("TD")
|
|
td.appendChild(element)
|
|
return td
|
|
}
|
|
|
|
createInteraction():any {
|
|
var div = document.createElement("div")
|
|
div.setAttribute("id", "popup-interaction")
|
|
div.className = "interaction"
|
|
this.doc.appendChild(div)
|
|
}
|
|
}
|
|
|
|
class PopupContent extends PopupWindow{
|
|
|
|
table = document.createElement("TABLE")
|
|
|
|
createHeadline(headline):void {
|
|
this.doc.innerHTML = ""
|
|
var element = document.createElement("H3")
|
|
element.innerHTML = headline.toUpperCase()
|
|
this.doc.appendChild(element)
|
|
|
|
// Tabelle erstellen
|
|
this.table = document.createElement("TABLE")
|
|
this.doc.appendChild(this.table)
|
|
}
|
|
|
|
appendRow(title:string, element:any):void {
|
|
var tr = document.createElement("TR")
|
|
|
|
// Bezeichnung
|
|
if (title.length != 0) {
|
|
tr.appendChild(this.createTitle(title))
|
|
}
|
|
|
|
|
|
// Content
|
|
tr.appendChild(this.createContent(element))
|
|
this.table.appendChild(tr)
|
|
}
|
|
|
|
|
|
createInput(type:string, name:string, value:string):any {
|
|
|
|
var input = document.createElement("INPUT")
|
|
if (value == undefined) {
|
|
value = ""
|
|
}
|
|
|
|
input.setAttribute("type", type)
|
|
input.setAttribute("name", name)
|
|
input.setAttribute("value", value)
|
|
return input
|
|
}
|
|
|
|
createCheckbox(name:string):any {
|
|
var input = document.createElement("INPUT")
|
|
|
|
input.setAttribute("type", "checkbox")
|
|
input.setAttribute("name", name)
|
|
return input
|
|
}
|
|
|
|
createSelect(text:string[], values:string[], set:string, dbKey:string):any {
|
|
var select = document.createElement("SELECT")
|
|
select.setAttribute("name", dbKey)
|
|
for (let i = 0; i < text.length; i++) {
|
|
var option = document.createElement("OPTION")
|
|
option.setAttribute("value", values[i])
|
|
option.innerText = text[i]
|
|
select.appendChild(option)
|
|
}
|
|
if(set != "") {
|
|
(select as HTMLSelectElement).value = set
|
|
}
|
|
|
|
if (set == undefined) {
|
|
(select as HTMLSelectElement).value = values[0]
|
|
}
|
|
|
|
return select
|
|
}
|
|
|
|
selectOption(select:any, value:string):any {
|
|
//select.selectedOptions = value
|
|
var s:HTMLSelectElement = (select as HTMLSelectElement)
|
|
s.options[s.selectedIndex].value = value
|
|
return select
|
|
}
|
|
|
|
// isHTML must only be true for static text written in the source; never for data.
|
|
description(value:string, isHTML:boolean = false):any {
|
|
var tr = document.createElement("TR")
|
|
var td = document.createElement("TD")
|
|
var span = document.createElement("PRE")
|
|
|
|
if (isHTML) {
|
|
span.innerHTML = value
|
|
} else {
|
|
span.textContent = value
|
|
}
|
|
|
|
tr.appendChild(td)
|
|
|
|
tr.appendChild(this.createContent(span))
|
|
|
|
this.table.appendChild(tr)
|
|
}
|
|
|
|
// Interaktion
|
|
addInteraction(element:any) {
|
|
var interaction = document.getElementById("popup-interaction")
|
|
interaction.appendChild(element)
|
|
}
|
|
}
|
|
|
|
function openPopUp(dataType, element) {
|
|
|
|
var data:object = new Object();
|
|
var id:any
|
|
switch (element) {
|
|
case undefined:
|
|
|
|
switch (dataType) {
|
|
case "group-title":
|
|
if (id == undefined) {
|
|
id = -1
|
|
}
|
|
data = getLocalData("filter", id)
|
|
data["type"] = "group-title"
|
|
break;
|
|
|
|
case "custom-filter":
|
|
if (id == undefined) {
|
|
id = -1
|
|
}
|
|
data = getLocalData("filter", id)
|
|
data["type"] = "custom-filter"
|
|
break;
|
|
|
|
default:
|
|
data["id.provider"] = "-"
|
|
data["type"] = dataType
|
|
id = "-"
|
|
break;
|
|
}
|
|
|
|
break
|
|
|
|
default:
|
|
id = element.id
|
|
data = getLocalData(dataType, id)
|
|
break;
|
|
}
|
|
|
|
var content:PopupContent = new PopupContent()
|
|
|
|
switch (dataType) {
|
|
case "playlist":
|
|
content.createHeadline("Playlist type")
|
|
// Type
|
|
var text:string[] = ["M3U", "HDHomeRun"]
|
|
var values:string[] = ["javascript: openPopUp('m3u')", "javascript: openPopUp('hdhr')"]
|
|
var select = content.createSelect(text, values, "", "type")
|
|
select.setAttribute("id", "type")
|
|
select.setAttribute("onchange", 'javascript: changeButtonAction(this, "next", "onclick")') // changeButtonAction
|
|
content.appendRow("Type", select)
|
|
|
|
// Interaktion
|
|
content.createInteraction()
|
|
// Abbrechen
|
|
var input = content.createInput("button", "cancel", "Cancel")
|
|
input.setAttribute("onclick", 'javascript: showElement("popup", false);')
|
|
content.addInteraction(input)
|
|
|
|
// Weiter
|
|
var input = content.createInput("button", "next", "Next")
|
|
input.setAttribute("onclick", 'javascript: openPopUp("m3u")')
|
|
input.setAttribute("id", 'next')
|
|
content.addInteraction(input)
|
|
break
|
|
|
|
case "m3u":
|
|
content.createHeadline(dataType)
|
|
// Name
|
|
var dbKey:string = "name"
|
|
var input = content.createInput("text", dbKey, data[dbKey])
|
|
input.setAttribute("placeholder", "Playlist name")
|
|
content.appendRow("Name", input)
|
|
|
|
// Beschreibung
|
|
var dbKey:string = "description"
|
|
var input = content.createInput("text", dbKey, data[dbKey])
|
|
input.setAttribute("placeholder", "Description")
|
|
content.appendRow("Description", input)
|
|
|
|
// URL
|
|
var dbKey:string = "file.source"
|
|
var input = content.createInput("text", dbKey, data[dbKey])
|
|
input.setAttribute("placeholder", "File path or URL of the M3U")
|
|
content.appendRow("M3U File", input)
|
|
|
|
// Tuner
|
|
if (SERVER["settings"]["buffer"] != "-") {
|
|
var text:string[] = new Array()
|
|
var values:string[] = new Array()
|
|
|
|
for (var i = 1; i <= 100; i++) {
|
|
text.push(i.toString())
|
|
values.push(i.toString())
|
|
}
|
|
|
|
var dbKey:string = "tuner"
|
|
var select = content.createSelect(text, values, data[dbKey], dbKey)
|
|
select.setAttribute("onfocus", "javascript: return;")
|
|
content.appendRow("Tuner / Streams", select)
|
|
} else {
|
|
var dbKey:string = "tuner"
|
|
if (data[dbKey] == undefined) {
|
|
data[dbKey] = 1
|
|
}
|
|
var input = content.createInput("text", dbKey, data[dbKey])
|
|
input.setAttribute("readonly", "true")
|
|
input.className = "notAvailable"
|
|
content.appendRow("Tuner / Streams", input)
|
|
}
|
|
|
|
content.description("Number of parallel connections that can be established to the provider. <br>Only available with activated buffer.<br>New settings will only be applied after quitting all streams.", true)
|
|
|
|
// Interaktion
|
|
content.createInteraction()
|
|
// Löschen
|
|
if (data["id.provider"]!= "-") {
|
|
var input = content.createInput("button", "delete", "Delete")
|
|
input.className = "delete"
|
|
input.setAttribute('onclick', 'javascript: savePopupData("m3u", "' + id + '", true, 0)')
|
|
content.addInteraction(input)
|
|
} else {
|
|
var input = content.createInput("button", "back", "Back")
|
|
input.setAttribute("onclick", 'javascript: openPopUp("playlist")')
|
|
content.addInteraction(input)
|
|
}
|
|
|
|
// Abbrechen
|
|
var input = content.createInput("button", "cancel", "Cancel")
|
|
input.setAttribute("onclick", 'javascript: showElement("popup", false);')
|
|
content.addInteraction(input)
|
|
|
|
// Aktualisieren
|
|
if (data["id.provider"]!= "-") {
|
|
var input = content.createInput("button", "update", "Update")
|
|
input.setAttribute('onclick', 'javascript: savePopupData("m3u", "' + id + '", false, 1)')
|
|
content.addInteraction(input)
|
|
}
|
|
|
|
// Speichern
|
|
var input = content.createInput("button", "save", "Save")
|
|
input.setAttribute('onclick', 'javascript: savePopupData("m3u", "' + id + '", false, 0)')
|
|
content.addInteraction(input)
|
|
break
|
|
|
|
case "hdhr":
|
|
content.createHeadline(dataType)
|
|
// Name
|
|
var dbKey:string = "name"
|
|
var input = content.createInput("text", dbKey, data[dbKey])
|
|
input.setAttribute("placeholder", "Playlist name")
|
|
content.appendRow("Name", input)
|
|
|
|
// Beschreibung
|
|
var dbKey:string = "description"
|
|
var input = content.createInput("text", dbKey, data[dbKey])
|
|
input.setAttribute("placeholder", "Description")
|
|
content.appendRow("Description", input)
|
|
|
|
// URL
|
|
var dbKey:string = "file.source"
|
|
var input = content.createInput("text", dbKey, data[dbKey])
|
|
input.setAttribute("placeholder", "IP address and port (192.168.1.10:5004)")
|
|
content.appendRow("HDHomeRun IP", input)
|
|
|
|
// Tuner
|
|
if (SERVER["settings"]["buffer"] != "-") {
|
|
var text:string[] = new Array()
|
|
var values:string[] = new Array()
|
|
|
|
for (var i = 1; i <= 100; i++) {
|
|
text.push(i.toString())
|
|
values.push(i.toString())
|
|
}
|
|
|
|
var dbKey:string = "tuner"
|
|
var select = content.createSelect(text, values, data[dbKey], dbKey)
|
|
select.setAttribute("onfocus", "javascript: return;")
|
|
content.appendRow("Tuner / Streams", select)
|
|
} else {
|
|
var dbKey:string = "tuner"
|
|
if (data[dbKey] == undefined) {
|
|
data[dbKey] = 1
|
|
}
|
|
var input = content.createInput("text", dbKey, data[dbKey])
|
|
input.setAttribute("readonly", "true")
|
|
input.className = "notAvailable"
|
|
content.appendRow("Tuner / Streams", input)
|
|
}
|
|
|
|
content.description("Number of parallel connections that can be established to the provider. <br>Only available with activated buffer.<br>New settings will only be applied after quitting all streams.", true)
|
|
|
|
// Interaktion
|
|
content.createInteraction()
|
|
// Löschen
|
|
if (data["id.provider"]!= "-") {
|
|
var input = content.createInput("button", "delete", "Delete")
|
|
input.setAttribute('onclick', 'javascript: savePopupData("hdhr", "' + id + '", true, 0)')
|
|
input.className = "delete"
|
|
content.addInteraction(input)
|
|
} else {
|
|
var input = content.createInput("button", "back", "Back")
|
|
input.setAttribute("onclick", 'javascript: openPopUp("playlist")')
|
|
content.addInteraction(input)
|
|
}
|
|
|
|
// Abbrechen
|
|
var input = content.createInput("button", "cancel", "Cancel")
|
|
input.setAttribute("onclick", 'javascript: showElement("popup", false);')
|
|
content.addInteraction(input)
|
|
|
|
// Aktualisieren
|
|
if (data["id.provider"]!= "-") {
|
|
var input = content.createInput("button", "update", "Update")
|
|
input.setAttribute('onclick', 'javascript: savePopupData("hdhr", "' + id + '", false, 1)')
|
|
content.addInteraction(input)
|
|
}
|
|
|
|
// Speichern
|
|
var input = content.createInput("button", "save", "Save")
|
|
input.setAttribute('onclick', 'javascript: savePopupData("hdhr", "' + id + '", false, 0)')
|
|
content.addInteraction(input)
|
|
break
|
|
|
|
case "filter":
|
|
content.createHeadline(dataType)
|
|
|
|
// Type
|
|
var dbKey:string = "type"
|
|
var text:string[] = ["M3U: " + "Group Title", "xTeVe: " + "Custom Filter"]
|
|
var values:string[] = ["javascript: openPopUp('group-title')", "javascript: openPopUp('custom-filter')"]
|
|
var select = content.createSelect(text, values, "javascript: openPopUp('group-title')", dbKey)
|
|
select.setAttribute("id", id)
|
|
select.setAttribute("onchange", 'javascript: changeButtonAction(this, "next", "onclick");') // changeButtonAction
|
|
content.appendRow("Type", select)
|
|
|
|
// Interaktion
|
|
content.createInteraction()
|
|
// Abbrechen
|
|
var input = content.createInput("button", "cancel", "Cancel")
|
|
input.setAttribute("onclick", 'javascript: showElement("popup", false);')
|
|
content.addInteraction(input)
|
|
|
|
// Weiter
|
|
var input = content.createInput("button", "next", "Next")
|
|
input.setAttribute("onclick", 'javascript: openPopUp("group-title")')
|
|
input.setAttribute("id", 'next')
|
|
content.addInteraction(input)
|
|
break
|
|
|
|
case "custom-filter":
|
|
case "group-title":
|
|
|
|
switch (dataType) {
|
|
case "custom-filter":
|
|
content.createHeadline("Custom")
|
|
break;
|
|
|
|
case "group-title":
|
|
content.createHeadline("Group")
|
|
break;
|
|
}
|
|
|
|
// Name
|
|
var dbKey:string = "name"
|
|
var input = content.createInput("text", dbKey, data[dbKey])
|
|
input.setAttribute("placeholder", "Filter name")
|
|
content.appendRow("Filter Name", input)
|
|
|
|
// Beschreibung
|
|
var dbKey:string = "description"
|
|
var input = content.createInput("text", dbKey, data[dbKey])
|
|
input.setAttribute("placeholder", "Description")
|
|
content.appendRow("Description", input)
|
|
|
|
// Typ
|
|
var dbKey:string = "type"
|
|
var input = content.createInput("hidden", dbKey, data[dbKey])
|
|
content.appendRow("", input)
|
|
|
|
var filterType = data[dbKey]
|
|
|
|
switch (filterType) {
|
|
|
|
case "custom-filter":
|
|
// Groß- Kleinschreibung beachten
|
|
var dbKey:string = "caseSensitive"
|
|
var input = content.createCheckbox(dbKey)
|
|
input.checked = data[dbKey]
|
|
content.appendRow("Case Sensitive", input)
|
|
|
|
// Filterregel (Benutzerdefiniert)
|
|
var dbKey:string = "filter"
|
|
var input = content.createInput("text", dbKey, data[dbKey])
|
|
input.setAttribute("placeholder", "Sport {HD} !{ES,IT}")
|
|
content.appendRow("Filter Rule", input)
|
|
|
|
break;
|
|
|
|
case "group-title":
|
|
//alert(dbKey + " " + filterType)
|
|
// Filter basierend auf den Gruppen in der M3U
|
|
var dbKey:string = "filter"
|
|
var groupsM3U = getLocalData("m3uGroups", "")
|
|
var text:string[] = groupsM3U["text"]
|
|
var values:string[] = groupsM3U["value"]
|
|
|
|
var select = content.createSelect(text, values, data[dbKey], dbKey)
|
|
select.setAttribute("onchange", "javascript: this.className = 'changed'")
|
|
content.appendRow("Group Title", select)
|
|
content.description("Select a M3U group. (Counter)<br>Changing the group title in the M3U invalidates the filter.", true)
|
|
|
|
// Groß- Kleinschreibung beachten
|
|
var dbKey:string = "caseSensitive"
|
|
var input = content.createCheckbox(dbKey)
|
|
input.checked = data[dbKey]
|
|
content.appendRow("Case Sensitive", input)
|
|
|
|
|
|
var dbKey:string = "include"
|
|
var input = content.createInput("text", dbKey, data[dbKey])
|
|
input.setAttribute("placeholder", "FHD,UHD")
|
|
|
|
content.appendRow("Include", input)
|
|
content.description("Channel name must include.<br>(Comma separated) Comma means or", true)
|
|
|
|
var dbKey:string = "exclude"
|
|
var input = content.createInput("text", dbKey, data[dbKey])
|
|
input.setAttribute("placeholder", "ES,IT")
|
|
content.appendRow("Exclude", input)
|
|
content.description("Channel name must not contain.<br>(Comma separated) Comma means or", true)
|
|
|
|
break
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// Interaktion
|
|
content.createInteraction()
|
|
|
|
// Löschen
|
|
var input = content.createInput("button", "delete", "Delete")
|
|
input.setAttribute('onclick', 'javascript: savePopupData("filter", "' + id + '", true, 0)')
|
|
input.className = "delete"
|
|
content.addInteraction(input)
|
|
|
|
// Abbrechen
|
|
var input = content.createInput("button", "cancel", "Cancel")
|
|
input.setAttribute("onclick", 'javascript: showElement("popup", false);')
|
|
content.addInteraction(input)
|
|
|
|
// Speichern
|
|
var input = content.createInput("button", "save", "Save")
|
|
input.setAttribute('onclick', 'javascript: savePopupData("filter", "' + id + '", false, 0)')
|
|
content.addInteraction(input)
|
|
|
|
break
|
|
|
|
case "xmltv":
|
|
content.createHeadline(dataType)
|
|
// Name
|
|
var dbKey:string = "name"
|
|
var input = content.createInput("text", dbKey, data[dbKey])
|
|
input.setAttribute("placeholder", "Guide name")
|
|
content.appendRow("Name", input)
|
|
|
|
// Beschreibung
|
|
var dbKey:string = "description"
|
|
var input = content.createInput("text", dbKey, data[dbKey])
|
|
input.setAttribute("placeholder", "Description")
|
|
content.appendRow("Description", input)
|
|
|
|
// URL
|
|
var dbKey:string = "file.source"
|
|
var input = content.createInput("text", dbKey, data[dbKey])
|
|
input.setAttribute("placeholder", "File path or URL of the XMLTV")
|
|
content.appendRow("XMLTV File", input)
|
|
|
|
// Interaktion
|
|
content.createInteraction()
|
|
// Löschen
|
|
if (data["id.provider"]!= "-") {
|
|
var input = content.createInput("button", "delete", "Delete")
|
|
input.setAttribute('onclick', 'javascript: savePopupData("xmltv", "' + id + '", true, 0)')
|
|
input.className = "delete"
|
|
content.addInteraction(input)
|
|
}
|
|
|
|
// Abbrechen
|
|
var input = content.createInput("button", "cancel", "Cancel")
|
|
input.setAttribute("onclick", 'javascript: showElement("popup", false);')
|
|
content.addInteraction(input)
|
|
|
|
// Aktualisieren
|
|
if (data["id.provider"]!= "-") {
|
|
var input = content.createInput("button", "update", "Update")
|
|
input.setAttribute('onclick', 'javascript: savePopupData("xmltv", "' + id + '", false, 1)')
|
|
content.addInteraction(input)
|
|
}
|
|
|
|
// Speichern
|
|
var input = content.createInput("button", "save", "Save")
|
|
input.setAttribute('onclick', 'javascript: savePopupData("xmltv", "' + id + '", false, 0)')
|
|
content.addInteraction(input)
|
|
break
|
|
|
|
case "users":
|
|
content.createHeadline("Users")
|
|
// Benutzername
|
|
var dbKey:string = "username"
|
|
var input = content.createInput("text", dbKey, data[dbKey])
|
|
input.setAttribute("placeholder", "Username")
|
|
content.appendRow("Username", input)
|
|
|
|
// Neues Passwort
|
|
var dbKey:string = "password"
|
|
var input = content.createInput("password", dbKey, "")
|
|
input.setAttribute("placeholder", "Password")
|
|
content.appendRow("Password", input)
|
|
|
|
// Bestätigung
|
|
var dbKey:string = "confirm"
|
|
var input = content.createInput("password", dbKey, "")
|
|
input.setAttribute("placeholder", "Password confirm")
|
|
content.appendRow("Confirm", input)
|
|
|
|
// Berechtigung WEB
|
|
var dbKey:string = "authentication.web"
|
|
var input = content.createCheckbox(dbKey)
|
|
input.checked = data[dbKey]
|
|
if (data["defaultUser"] == true) {
|
|
input.setAttribute("onclick", "javascript: return false")
|
|
}
|
|
content.appendRow("Web Access", input)
|
|
|
|
// Berechtigung PMS
|
|
var dbKey:string = "authentication.pms"
|
|
var input = content.createCheckbox(dbKey)
|
|
input.checked = data[dbKey]
|
|
content.appendRow("PMS Access", input)
|
|
|
|
// Berechtigung M3U
|
|
var dbKey:string = "authentication.m3u"
|
|
var input = content.createCheckbox(dbKey)
|
|
input.checked = data[dbKey]
|
|
content.appendRow("M3U Access", input)
|
|
|
|
// Berechtigung XML
|
|
var dbKey:string = "authentication.xml"
|
|
var input = content.createCheckbox(dbKey)
|
|
input.checked = data[dbKey]
|
|
content.appendRow("XML Access", input)
|
|
|
|
// Berechtigung API
|
|
var dbKey:string = "authentication.api"
|
|
var input = content.createCheckbox(dbKey)
|
|
input.checked = data[dbKey]
|
|
content.appendRow("API Access", input)
|
|
|
|
// Interaktion
|
|
content.createInteraction()
|
|
|
|
// Löschen
|
|
if (data["defaultUser"]!= true && id != "-") {
|
|
var input = content.createInput("button", "delete", "Delete")
|
|
input.className = "delete"
|
|
input.setAttribute('onclick', 'javascript: savePopupData("' + dataType + '", "' + id + '", true, 0)')
|
|
content.addInteraction(input)
|
|
}
|
|
|
|
// Abbrechen
|
|
var input = content.createInput("button", "cancel", "Cancel")
|
|
input.setAttribute("onclick", 'javascript: showElement("popup", false);')
|
|
content.addInteraction(input)
|
|
|
|
// Speichern
|
|
var input = content.createInput("button", "save", "Save")
|
|
input.setAttribute("onclick", 'javascript: savePopupData("' + dataType + '", "' + id + '", "false");')
|
|
content.addInteraction(input)
|
|
|
|
break
|
|
|
|
case "mapping":
|
|
content.createHeadline("Mapping")
|
|
// Aktiv
|
|
var dbKey:string = "x-active"
|
|
var input = content.createCheckbox(dbKey)
|
|
input.checked = data[dbKey]
|
|
input.id = "active"
|
|
//input.setAttribute("onchange", "javascript: this.className = 'changed'")
|
|
input.setAttribute("onchange", "javascript: toggleChannelStatus('" + id + "', this)")
|
|
content.appendRow("Active", input)
|
|
|
|
// Kanalname
|
|
var dbKey:string = "x-name"
|
|
var input = content.createInput("text", dbKey, data[dbKey])
|
|
input.setAttribute("onchange", "javascript: this.className = 'changed'")
|
|
if (BULK_EDIT == true) {
|
|
input.style.border = "solid 1px red"
|
|
input.setAttribute("readonly", "true")
|
|
}
|
|
content.appendRow("Channel Name", input)
|
|
|
|
content.description(data["name"])
|
|
|
|
// Beschreibung
|
|
var dbKey:string = "x-description"
|
|
var input = content.createInput("text", dbKey, data[dbKey])
|
|
input.setAttribute("placeholder", "Used by the Dummy as an XML description")
|
|
input.setAttribute("onchange", "javascript: this.className = 'changed'")
|
|
content.appendRow("Channel Description", input)
|
|
|
|
// Aktualisierung des Kanalnamens
|
|
if (data.hasOwnProperty("_uuid.key")) {
|
|
if (data["_uuid.key"] != "") {
|
|
var dbKey:string = "x-update-channel-name"
|
|
var input = content.createCheckbox(dbKey)
|
|
input.setAttribute("onchange", "javascript: this.className = 'changed'")
|
|
input.checked = data[dbKey]
|
|
content.appendRow("Update Channel Name", input)
|
|
}
|
|
}
|
|
|
|
// Logo URL (Kanal)
|
|
var dbKey:string = "tvg-logo"
|
|
var input = content.createInput("text", dbKey, data[dbKey])
|
|
input.setAttribute("onchange", "javascript: this.className = 'changed'")
|
|
input.setAttribute("id", "channel-icon")
|
|
content.appendRow("Logo URL", input)
|
|
|
|
// Aktualisierung des Kanallogos
|
|
var dbKey:string = "x-update-channel-icon"
|
|
var input = content.createCheckbox(dbKey)
|
|
input.checked = data[dbKey]
|
|
input.setAttribute("id", "update-icon")
|
|
input.setAttribute("onchange", "javascript: this.className = 'changed'; changeChannelLogo('" + id + "');")
|
|
content.appendRow("Update Channel Logo", input)
|
|
|
|
// Erweitern der EPG Kategorie
|
|
var dbKey:string = "x-category"
|
|
var text:string[] = ["-", "Kids (Emby only)", "News", "Movie", "Series", "Sports"]
|
|
var values:string[] = ["", "Kids", "News", "Movie", "Series", "Sports"]
|
|
var select = content.createSelect(text, values, data[dbKey], dbKey)
|
|
select.setAttribute("onchange", "javascript: this.className = 'changed'")
|
|
content.appendRow("EPG Category", select)
|
|
|
|
// M3U Gruppentitel
|
|
var dbKey:string = "x-group-title"
|
|
var input = content.createInput("text", dbKey, data[dbKey])
|
|
input.setAttribute("onchange", "javascript: this.className = 'changed'")
|
|
content.appendRow("Group Title (xteve.m3u)", input)
|
|
|
|
if (data["group-title"] != undefined) {
|
|
content.description(data["group-title"])
|
|
}
|
|
|
|
// XMLTV Datei
|
|
var dbKey:string = "x-xmltv-file"
|
|
var xmlFile = data[dbKey]
|
|
var xmltv:XMLTVFile = new XMLTVFile()
|
|
var select = xmltv.getFiles(data[dbKey])
|
|
select.setAttribute("name", dbKey)
|
|
select.setAttribute("id", "popup-xmltv")
|
|
select.setAttribute("onchange", "javascript: this.className = 'changed'; setXmltvChannel('" + id + "',this);")
|
|
content.appendRow("XMLTV File", select)
|
|
var file = data[dbKey]
|
|
|
|
// XMLTV Mapping
|
|
var dbKey:string = "x-mapping"
|
|
var xmltv:XMLTVFile = new XMLTVFile()
|
|
var select = xmltv.getPrograms(file, data[dbKey])
|
|
select.setAttribute("name", dbKey)
|
|
select.setAttribute("id", "popup-mapping")
|
|
select.setAttribute("onchange", "javascript: this.className = 'changed'; checkXmltvChannel('" + id + "',this,'" + xmlFile + "');")
|
|
|
|
sortSelect(select)
|
|
content.appendRow("XMLTV Channel", select)
|
|
|
|
// Interaktion
|
|
content.createInteraction()
|
|
|
|
// Logo hochladen
|
|
var input = content.createInput("button", "cancel", "Upload Logo")
|
|
input.setAttribute("onclick", 'javascript: uploadLogo();')
|
|
content.addInteraction(input)
|
|
|
|
// Abbrechen
|
|
var input = content.createInput("button", "cancel", "Cancel")
|
|
input.setAttribute("onclick", 'javascript: showElement("popup", false);')
|
|
content.addInteraction(input)
|
|
|
|
// Fertig
|
|
var ids:string[] = new Array()
|
|
ids = getAllSelectedChannels()
|
|
if (ids.length == 0) {
|
|
ids.push(id)
|
|
}
|
|
|
|
var input = content.createInput("button", "save", "Done")
|
|
input.setAttribute("onclick", 'javascript: donePopupData("' + dataType + '", "' + ids + '", "false");')
|
|
content.addInteraction(input)
|
|
break
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
showPopUpElement('popup-custom');
|
|
}
|
|
|
|
class XMLTVFile {
|
|
File:string
|
|
|
|
getFiles(set:string):any {
|
|
var fileIDs:string[] = getObjKeys(SERVER["xepg"]["xmltvMap"])
|
|
var values = new Array("-");
|
|
var text = new Array("-");
|
|
|
|
for (let i = 0; i < fileIDs.length; i++) {
|
|
if (fileIDs[i] != "xTeVe Dummy") {
|
|
values.push(getValueFromProviderFile(fileIDs[i], "xmltv", "file.xteve"))
|
|
text.push(getValueFromProviderFile(fileIDs[i], "xmltv", "name"))
|
|
} else {
|
|
values.push(fileIDs[i])
|
|
text.push(fileIDs[i])
|
|
}
|
|
|
|
}
|
|
|
|
var select = document.createElement("SELECT")
|
|
for (let i = 0; i < text.length; i++) {
|
|
var option = document.createElement("OPTION")
|
|
option.setAttribute("value", values[i])
|
|
option.innerText = text[i]
|
|
select.appendChild(option)
|
|
}
|
|
|
|
if(set != "") {
|
|
(select as HTMLSelectElement).value = set
|
|
}
|
|
|
|
return select
|
|
}
|
|
|
|
getPrograms(file:string, set:string):any {
|
|
//var fileIDs:string[] = getObjKeys(SERVER["xepg"]["xmltvMap"])
|
|
var values = getObjKeys(SERVER["xepg"]["xmltvMap"][file]);
|
|
var text = new Array()
|
|
var displayName:string
|
|
|
|
for (let i = 0; i < values.length; i++) {
|
|
if (SERVER["xepg"]["xmltvMap"][file][values[i]].hasOwnProperty('display-name') == true) {
|
|
displayName = SERVER["xepg"]["xmltvMap"][file][values[i]]["display-name"];
|
|
} else {
|
|
displayName = "-"
|
|
}
|
|
|
|
text[i] = displayName + " (" + values[i] + ")";
|
|
}
|
|
|
|
text.unshift("-");
|
|
values.unshift("-");
|
|
|
|
var select = document.createElement("SELECT")
|
|
for (let i = 0; i < text.length; i++) {
|
|
var option = document.createElement("OPTION")
|
|
option.setAttribute("value", values[i])
|
|
option.innerText = text[i]
|
|
select.appendChild(option)
|
|
}
|
|
|
|
if(set != "") {
|
|
(select as HTMLSelectElement).value = set
|
|
}
|
|
|
|
if ((select as HTMLSelectElement).value != set) {
|
|
(select as HTMLSelectElement).value = "-"
|
|
}
|
|
|
|
return select
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
function getValueFromProviderFile(file:string, fileType, key) {
|
|
|
|
if (file == "xTeVe Dummy") {
|
|
return file
|
|
}
|
|
|
|
var fileID:string
|
|
var indicator = file.charAt(0)
|
|
|
|
switch (indicator) {
|
|
case "M":
|
|
fileType = "m3u"
|
|
fileID = file
|
|
break;
|
|
|
|
case "H":
|
|
fileType = "hdhr"
|
|
fileID = file
|
|
break;
|
|
|
|
case "X":
|
|
fileType = "xmltv"
|
|
fileID = file.substring(0, file.lastIndexOf('.'))
|
|
break;
|
|
|
|
}
|
|
|
|
if (SERVER["settings"]["files"][fileType].hasOwnProperty(fileID) == true) {
|
|
var data = SERVER["settings"]["files"][fileType][fileID];
|
|
return data[key]
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
function setXmltvChannel(id, element) {
|
|
|
|
var xmltv:XMLTVFile = new XMLTVFile()
|
|
var xmlFile = element.value
|
|
|
|
var tvgId:string = SERVER["xepg"]["epgMapping"][id]["tvg-id"]
|
|
var td = document.getElementById("popup-mapping").parentElement
|
|
td.innerHTML = ""
|
|
|
|
var select = xmltv.getPrograms(element.value, tvgId)
|
|
select.setAttribute("name", "x-mapping")
|
|
select.setAttribute("id", "popup-mapping")
|
|
select.setAttribute("onchange", "javascript: this.className = 'changed'; checkXmltvChannel('" + id + "',this,'" + xmlFile + "');")
|
|
select.className = "changed"
|
|
sortSelect(select)
|
|
td.appendChild(select);
|
|
|
|
checkXmltvChannel(id, select, xmlFile)
|
|
}
|
|
|
|
function checkXmltvChannel(id:string, element:any, xmlFile) {
|
|
|
|
var value = (element as HTMLSelectElement).value
|
|
var bool:boolean
|
|
var checkbox = document.getElementById('active')
|
|
var channel:any = SERVER["xepg"]["epgMapping"][id]
|
|
var updateLogo:boolean
|
|
|
|
|
|
if (value == "-") {
|
|
bool = false
|
|
} else {
|
|
bool = true
|
|
}
|
|
|
|
(checkbox as HTMLInputElement).checked = bool
|
|
checkbox.className = "changed"
|
|
console.log(xmlFile);
|
|
|
|
// Kanallogo aktualisieren
|
|
/*
|
|
updateLogo = (document.getElementById("update-icon") as HTMLInputElement).checked
|
|
console.log(updateLogo);
|
|
*/
|
|
|
|
if(xmlFile != "xTeVe Dummy" && bool == true) {
|
|
|
|
//(document.getElementById("update-icon") as HTMLInputElement).checked = true;
|
|
//(document.getElementById("update-icon") as HTMLInputElement).className = "changed";
|
|
|
|
console.log("ID", id)
|
|
changeChannelLogo(id)
|
|
|
|
return
|
|
}
|
|
|
|
if (xmlFile == "xTeVe Dummy") {
|
|
(document.getElementById("update-icon") as HTMLInputElement).checked = false;
|
|
(document.getElementById("update-icon") as HTMLInputElement).className = "changed";
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
function changeChannelLogo(id:string) {
|
|
|
|
var updateLogo:boolean
|
|
var channel:any = SERVER["xepg"]["epgMapping"][id]
|
|
|
|
var f = (document.getElementById("popup-xmltv") as HTMLSelectElement);
|
|
var xmltvFile = f.options[f.selectedIndex].value;
|
|
|
|
var m = (document.getElementById("popup-mapping") as HTMLSelectElement);
|
|
var xMapping = m.options[m.selectedIndex].value;
|
|
|
|
var xmltvLogo = SERVER["xepg"]["xmltvMap"][xmltvFile][xMapping]["icon"]
|
|
updateLogo = (document.getElementById("update-icon") as HTMLInputElement).checked
|
|
|
|
if (updateLogo == true && xmltvFile != "xTeVe Dummy") {
|
|
|
|
if (SERVER["xepg"]["xmltvMap"][xmltvFile].hasOwnProperty(xMapping)) {
|
|
var logo = xmltvLogo
|
|
} else {
|
|
logo = channel["tvg-logo"]
|
|
}
|
|
|
|
var logoInput = (document.getElementById("channel-icon") as HTMLInputElement);
|
|
logoInput.value = logo
|
|
if (BULK_EDIT == false) {
|
|
logoInput.className = "changed"
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function savePopupData(dataType:string, id:string, remove:Boolean, option:number) {
|
|
|
|
if (dataType == "mapping") {
|
|
|
|
var data = new Object()
|
|
console.log("Save mapping data")
|
|
|
|
cmd = "saveEpgMapping"
|
|
data["epgMapping"] = SERVER["xepg"]["epgMapping"]
|
|
|
|
console.log("SEND TO SERVER");
|
|
|
|
var server:Server = new Server(cmd)
|
|
server.request(data)
|
|
|
|
delete UNDO["epgMapping"]
|
|
|
|
return
|
|
}
|
|
|
|
console.log("Save popup data")
|
|
var div = document.getElementById("popup-custom")
|
|
|
|
var inputs = div.getElementsByTagName("TABLE")[0].getElementsByTagName("INPUT");
|
|
var selects = div.getElementsByTagName("TABLE")[0].getElementsByTagName("SELECT");
|
|
|
|
var input = new Object();
|
|
var confirmMsg: string
|
|
|
|
for (let i = 0; i < selects.length; i++) {
|
|
|
|
var name:string
|
|
name = (selects[i] as HTMLSelectElement).name
|
|
var value = (selects[i] as HTMLSelectElement).value
|
|
|
|
switch (name) {
|
|
case "tuner":
|
|
input[name] = parseInt(value)
|
|
break;
|
|
|
|
default:
|
|
input[name] = value
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
for (let i = 0; i < inputs.length; i++) {
|
|
|
|
switch ((inputs[i] as HTMLInputElement).type) {
|
|
|
|
case "checkbox":
|
|
name = (inputs[i] as HTMLInputElement).name
|
|
input[name] = (inputs[i] as HTMLInputElement).checked
|
|
break
|
|
|
|
case "text":
|
|
case "hidden":
|
|
case "password":
|
|
|
|
name = (inputs[i] as HTMLInputElement).name
|
|
|
|
switch (name) {
|
|
case "tuner":
|
|
input[name] = parseInt((inputs[i] as HTMLInputElement).value)
|
|
break;
|
|
|
|
default:
|
|
input[name] = (inputs[i] as HTMLInputElement).value
|
|
break;
|
|
}
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var data = new Object()
|
|
|
|
var cmd:string
|
|
|
|
if (remove == true) {
|
|
input["delete"] = true
|
|
}
|
|
|
|
switch (dataType) {
|
|
case "users":
|
|
|
|
confirmMsg = "Delete this user?"
|
|
if (id == "-") {
|
|
cmd = "saveNewUser"
|
|
data["userData"] = input
|
|
} else {
|
|
cmd = "saveUserData"
|
|
var d = new Object()
|
|
d[id] = input
|
|
data["userData"] = d
|
|
}
|
|
|
|
break;
|
|
|
|
case "m3u":
|
|
|
|
confirmMsg = "Delete this playlist?"
|
|
switch (option) {
|
|
// Popup: Save
|
|
case 0:
|
|
cmd = "saveFilesM3U"
|
|
break
|
|
|
|
// Popup: Update
|
|
case 1:
|
|
cmd = "updateFileM3U"
|
|
break
|
|
|
|
}
|
|
|
|
data["files"] = new Object
|
|
data["files"][dataType] = new Object
|
|
data["files"][dataType][id] = input
|
|
|
|
break
|
|
|
|
case "hdhr":
|
|
|
|
confirmMsg = "Delete this HDHomeRun tuner?"
|
|
switch (option) {
|
|
// Popup: Save
|
|
case 0:
|
|
cmd = "saveFilesHDHR"
|
|
break
|
|
|
|
// Popup: Update
|
|
case 1:
|
|
cmd = "updateFileHDHR"
|
|
break
|
|
|
|
}
|
|
|
|
data["files"] = new Object
|
|
data["files"][dataType] = new Object
|
|
data["files"][dataType][id] = input
|
|
|
|
break
|
|
|
|
case "xmltv":
|
|
|
|
confirmMsg = "Delete this XMLTV file?"
|
|
switch (option) {
|
|
// Popup: Save
|
|
case 0:
|
|
cmd = "saveFilesXMLTV"
|
|
break
|
|
|
|
// Popup: Update
|
|
case 1:
|
|
cmd = "updateFileXMLTV"
|
|
break
|
|
|
|
}
|
|
|
|
data["files"] = new Object
|
|
data["files"][dataType] = new Object
|
|
data["files"][dataType][id] = input
|
|
|
|
break
|
|
|
|
case "filter":
|
|
|
|
confirmMsg = "Delete this filter?"
|
|
cmd = "saveFilter"
|
|
data["filter"] = new Object
|
|
data["filter"][id] = input
|
|
break
|
|
|
|
default:
|
|
console.log(dataType, id);
|
|
return
|
|
break;
|
|
|
|
}
|
|
|
|
if (remove == true) {
|
|
|
|
if (!confirm(confirmMsg)) {
|
|
showElement("popup", false)
|
|
return
|
|
}
|
|
|
|
}
|
|
|
|
console.log("SEND TO SERVER");
|
|
|
|
console.log(data);
|
|
|
|
var server:Server = new Server(cmd)
|
|
server.request(data)
|
|
|
|
}
|
|
|
|
function donePopupData(dataType:string, idsStr:string) {
|
|
|
|
var ids:string[] = idsStr.split(',');
|
|
var div = document.getElementById("popup-custom")
|
|
var inputs = div.getElementsByClassName("changed")
|
|
|
|
ids.forEach(id => {
|
|
var input = new Object();
|
|
input = SERVER["xepg"]["epgMapping"][id]
|
|
|
|
console.log(input);
|
|
|
|
for (let i = 0; i < inputs.length; i++) {
|
|
|
|
var name:string
|
|
var value:any
|
|
|
|
switch (inputs[i].tagName) {
|
|
|
|
case "INPUT":
|
|
switch ((inputs[i] as HTMLInputElement).type) {
|
|
case "checkbox":
|
|
name = (inputs[i] as HTMLInputElement).name
|
|
value = (inputs[i] as HTMLInputElement).checked
|
|
input[name] = value
|
|
break
|
|
|
|
case "text":
|
|
name = (inputs[i] as HTMLInputElement).name
|
|
value = (inputs[i] as HTMLInputElement).value
|
|
input[name] = value
|
|
break
|
|
|
|
}
|
|
|
|
break
|
|
|
|
case "SELECT":
|
|
name = (inputs[i] as HTMLSelectElement).name
|
|
value = (inputs[i] as HTMLSelectElement).value
|
|
input[name] = value
|
|
break
|
|
|
|
}
|
|
|
|
switch (name) {
|
|
|
|
|
|
case "tvg-logo":
|
|
//(document.getElementById(id).childNodes[2].firstChild as HTMLElement).setAttribute("src", value)
|
|
break
|
|
|
|
case "x-name":
|
|
(document.getElementById(id).childNodes[3].firstChild as HTMLElement).textContent = value
|
|
break
|
|
|
|
case "x-category":
|
|
(document.getElementById(id).childNodes[3].firstChild as HTMLElement).className = value
|
|
break
|
|
|
|
case "x-group-title":
|
|
(document.getElementById(id).childNodes[5].firstChild as HTMLElement).textContent = value
|
|
break
|
|
|
|
case "x-xmltv-file":
|
|
if (value != "xTeVe Dummy" && value != "-") {
|
|
value = getValueFromProviderFile(value, "xmltv", "name")
|
|
}
|
|
|
|
if (value == "-") {
|
|
input["x-active"] = false
|
|
}
|
|
|
|
(document.getElementById(id).childNodes[6].firstChild as HTMLElement).textContent = value
|
|
break
|
|
|
|
case "x-mapping":
|
|
if (value == "-") {
|
|
input["x-active"] = false
|
|
}
|
|
|
|
(document.getElementById(id).childNodes[7].firstChild as HTMLElement).textContent = value
|
|
|
|
break
|
|
|
|
default:
|
|
|
|
}
|
|
|
|
createSearchObj()
|
|
searchInMapping()
|
|
|
|
}
|
|
|
|
if (input["x-active"] == false) {
|
|
document.getElementById(id).className = "notActiveEPG"
|
|
} else {
|
|
document.getElementById(id).className = "activeEPG"
|
|
}
|
|
|
|
console.log(input["tvg-logo"]);
|
|
(document.getElementById(id).childNodes[2].firstChild as HTMLElement).setAttribute("src", input["tvg-logo"])
|
|
|
|
|
|
});
|
|
|
|
showElement("popup", false);
|
|
|
|
return
|
|
}
|
|
|
|
function showPreview(element:boolean) {
|
|
|
|
var div = document.getElementById("myStreamsBox")
|
|
switch (element) {
|
|
|
|
case false:
|
|
div.className = "notVisible"
|
|
return
|
|
break;
|
|
}
|
|
|
|
var streams:string[] = ["activeStreams", "inactiveStreams"]
|
|
|
|
streams.forEach(preview => {
|
|
|
|
var table = document.getElementById(preview)
|
|
table.innerHTML = ""
|
|
var obj:string[] = SERVER["data"]["StreamPreviewUI"][preview]
|
|
|
|
obj.forEach(channel => {
|
|
|
|
var tr = document.createElement("TR")
|
|
var tdKey = document.createElement("TD")
|
|
var tdVal = document.createElement("TD")
|
|
|
|
tdKey.className = "tdKey"
|
|
tdVal.className = "tdVal"
|
|
|
|
switch (preview) {
|
|
case "activeStreams":
|
|
tdKey.innerText = "Channel: (+)"
|
|
break;
|
|
|
|
case "inactiveStreams":
|
|
tdKey.innerText = "Channel: (-)"
|
|
break;
|
|
}
|
|
|
|
tdVal.innerText = channel
|
|
tr.appendChild(tdKey)
|
|
tr.appendChild(tdVal)
|
|
|
|
table.appendChild(tr)
|
|
|
|
});
|
|
|
|
});
|
|
|
|
showElement("loading", false)
|
|
div.className = "visible"
|
|
|
|
return
|
|
}
|