v2.0.0.0000
This commit is contained in:
953
src/data.go
Normal file
953
src/data.go
Normal file
@@ -0,0 +1,953 @@
|
||||
package src
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"../src/internal/authentication"
|
||||
)
|
||||
|
||||
// Einstellungen ändern (WebUI)
|
||||
func updateServerSettings(request RequestStruct) (settings SettingsStrcut, err error) {
|
||||
|
||||
var oldSettings = jsonToMap(mapToJSON(Settings))
|
||||
var newSettings = jsonToMap(mapToJSON(request.Settings))
|
||||
var reloadData = false
|
||||
var cacheImages = false
|
||||
var createXEPGFiles = false
|
||||
var debug string
|
||||
|
||||
for key, value := range newSettings {
|
||||
|
||||
if _, ok := oldSettings[key]; ok {
|
||||
|
||||
switch key {
|
||||
|
||||
case "tuner":
|
||||
showWarning(2105)
|
||||
|
||||
case "epgSource":
|
||||
reloadData = true
|
||||
|
||||
case "update":
|
||||
// Die Formatierung der Uhrzeit überprüfen (0000 - 2359)
|
||||
for _, i := range newSettings[key].([]interface{}) {
|
||||
|
||||
_, err := time.Parse("1504", i.(string))
|
||||
if err != nil {
|
||||
ShowError(err, 1012)
|
||||
return Settings, err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
case "cache.images":
|
||||
cacheImages = true
|
||||
|
||||
case "xepg.replace.missing.images":
|
||||
createXEPGFiles = true
|
||||
|
||||
case "backup.path":
|
||||
value = strings.TrimRight(value.(string), string(os.PathSeparator)) + string(os.PathSeparator)
|
||||
err = checkFolder(value.(string))
|
||||
if err == nil {
|
||||
|
||||
err = checkFilePermission(value.(string))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
case "temp.path":
|
||||
value = strings.TrimRight(value.(string), string(os.PathSeparator)) + string(os.PathSeparator)
|
||||
err = checkFolder(value.(string))
|
||||
if err == nil {
|
||||
|
||||
err = checkFilePermission(value.(string))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
oldSettings[key] = value
|
||||
|
||||
switch fmt.Sprintf("%T", value) {
|
||||
|
||||
case "bool":
|
||||
debug = fmt.Sprintf("Save Setting:Key: %s | Value: %t (%T)", key, value, value)
|
||||
|
||||
case "string":
|
||||
debug = fmt.Sprintf("Save Setting:Key: %s | Value: %s (%T)", key, value, value)
|
||||
|
||||
case "[]interface {}":
|
||||
debug = fmt.Sprintf("Save Setting:Key: %s | Value: %v (%T)", key, value, value)
|
||||
|
||||
case "float64":
|
||||
debug = fmt.Sprintf("Save Setting:Key: %s | Value: %d (%T)", key, int(value.(float64)), value)
|
||||
|
||||
default:
|
||||
debug = fmt.Sprintf("%T", value)
|
||||
}
|
||||
|
||||
showDebug(debug, 1)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Einstellungen aktualisieren
|
||||
err = json.Unmarshal([]byte(mapToJSON(oldSettings)), &Settings)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if Settings.AuthenticationWEB == false {
|
||||
|
||||
Settings.AuthenticationAPI = false
|
||||
Settings.AuthenticationM3U = false
|
||||
Settings.AuthenticationPMS = false
|
||||
Settings.AuthenticationWEB = false
|
||||
Settings.AuthenticationXML = false
|
||||
|
||||
}
|
||||
|
||||
err = saveSettings(Settings)
|
||||
if err == nil {
|
||||
|
||||
settings = Settings
|
||||
|
||||
if reloadData == true {
|
||||
|
||||
err = buildDatabaseDVR()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
buildXEPG(false)
|
||||
|
||||
}
|
||||
|
||||
if cacheImages == true {
|
||||
|
||||
if Settings.EpgSource == "XEPG" {
|
||||
|
||||
go func() {
|
||||
|
||||
if Settings.CacheImages == true {
|
||||
|
||||
createXMLTVFile()
|
||||
cachingImages()
|
||||
createXMLTVFile()
|
||||
createM3UFile()
|
||||
|
||||
} else {
|
||||
|
||||
createXMLTVFile()
|
||||
createM3UFile()
|
||||
|
||||
}
|
||||
|
||||
}()
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if createXEPGFiles == true {
|
||||
|
||||
go func() {
|
||||
createXMLTVFile()
|
||||
createM3UFile()
|
||||
}()
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Providerdaten speichern (WebUI)
|
||||
func saveFiles(request RequestStruct, fileType string) (err error) {
|
||||
|
||||
var filesMap = make(map[string]interface{})
|
||||
var newData = make(map[string]interface{})
|
||||
var indicator string
|
||||
var reloadData = false
|
||||
|
||||
switch fileType {
|
||||
case "m3u":
|
||||
filesMap = Settings.Files.M3U
|
||||
newData = request.Files.M3U
|
||||
indicator = "M"
|
||||
|
||||
case "hdhr":
|
||||
filesMap = Settings.Files.HDHR
|
||||
newData = request.Files.HDHR
|
||||
indicator = "H"
|
||||
|
||||
case "xmltv":
|
||||
filesMap = Settings.Files.XMLTV
|
||||
newData = request.Files.XMLTV
|
||||
indicator = "X"
|
||||
}
|
||||
|
||||
if len(filesMap) == 0 {
|
||||
filesMap = make(map[string]interface{})
|
||||
}
|
||||
|
||||
for dataID, data := range newData {
|
||||
|
||||
if dataID == "-" {
|
||||
|
||||
// Neue Providerdatei
|
||||
dataID = indicator + randomString(19)
|
||||
data.(map[string]interface{})["new"] = true
|
||||
filesMap[dataID] = data
|
||||
|
||||
} else {
|
||||
|
||||
// Bereits vorhandene Providerdatei
|
||||
for key, value := range data.(map[string]interface{}) {
|
||||
|
||||
var oldData = filesMap[dataID].(map[string]interface{})
|
||||
oldData[key] = value
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
switch fileType {
|
||||
|
||||
case "m3u":
|
||||
Settings.Files.M3U = filesMap
|
||||
|
||||
case "hdhr":
|
||||
Settings.Files.HDHR = filesMap
|
||||
|
||||
case "xmltv":
|
||||
Settings.Files.XMLTV = filesMap
|
||||
|
||||
}
|
||||
|
||||
// Neue Providerdatei
|
||||
if _, ok := data.(map[string]interface{})["new"]; ok {
|
||||
|
||||
reloadData = true
|
||||
err = getProviderData(fileType, dataID)
|
||||
delete(data.(map[string]interface{}), "new")
|
||||
|
||||
if err != nil {
|
||||
delete(filesMap, dataID)
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if _, ok := data.(map[string]interface{})["delete"]; ok {
|
||||
|
||||
deleteLocalProviderFiles(dataID, fileType)
|
||||
reloadData = true
|
||||
|
||||
}
|
||||
|
||||
err = saveSettings(Settings)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if reloadData == true {
|
||||
|
||||
err = buildDatabaseDVR()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
buildXEPG(false)
|
||||
|
||||
}
|
||||
|
||||
Settings, _ = loadSettings()
|
||||
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Providerdaten manuell aktualisieren (WebUI)
|
||||
func updateFile(request RequestStruct, fileType string) (err error) {
|
||||
|
||||
var updateData = make(map[string]interface{})
|
||||
|
||||
switch fileType {
|
||||
|
||||
case "m3u":
|
||||
updateData = request.Files.M3U
|
||||
|
||||
case "hdhr":
|
||||
updateData = request.Files.HDHR
|
||||
|
||||
case "xmltv":
|
||||
updateData = request.Files.XMLTV
|
||||
}
|
||||
|
||||
for dataID := range updateData {
|
||||
|
||||
err = getProviderData(fileType, dataID)
|
||||
if err == nil {
|
||||
err = buildDatabaseDVR()
|
||||
buildXEPG(false)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Providerdaten löschen (WebUI)
|
||||
func deleteLocalProviderFiles(dataID, fileType string) {
|
||||
|
||||
var removeData = make(map[string]interface{})
|
||||
var fileExtension string
|
||||
|
||||
switch fileType {
|
||||
|
||||
case "m3u":
|
||||
removeData = Settings.Files.M3U
|
||||
fileExtension = ".m3u"
|
||||
|
||||
case "hdhr":
|
||||
removeData = Settings.Files.HDHR
|
||||
fileExtension = ".json"
|
||||
|
||||
case "xmltv":
|
||||
removeData = Settings.Files.XMLTV
|
||||
fileExtension = ".xml"
|
||||
}
|
||||
|
||||
if _, ok := removeData[dataID]; ok {
|
||||
delete(removeData, dataID)
|
||||
os.RemoveAll(System.Folder.Data + dataID + fileExtension)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Filtereinstellungen speichern (WebUI)
|
||||
func saveFilter(request RequestStruct) (settings SettingsStrcut, err error) {
|
||||
|
||||
var filterMap = make(map[int64]interface{})
|
||||
var newData = make(map[int64]interface{})
|
||||
var defaultFilter FilterStruct
|
||||
|
||||
defaultFilter.Active = true
|
||||
defaultFilter.CaseSensitive = false
|
||||
|
||||
filterMap = Settings.Filter
|
||||
newData = request.Filter
|
||||
|
||||
var createNewID = func() (id int64) {
|
||||
|
||||
newID:
|
||||
if _, ok := filterMap[id]; ok {
|
||||
id++
|
||||
goto newID
|
||||
}
|
||||
|
||||
return id
|
||||
}
|
||||
|
||||
for dataID, data := range newData {
|
||||
|
||||
if dataID == -1 {
|
||||
|
||||
// Neuer Filter
|
||||
dataID = createNewID()
|
||||
filterMap[dataID] = jsonToMap(mapToJSON(defaultFilter))
|
||||
|
||||
}
|
||||
|
||||
// Filter aktualisieren / löschen
|
||||
for key, value := range data.(map[string]interface{}) {
|
||||
|
||||
var oldData = filterMap[dataID].(map[string]interface{})
|
||||
oldData[key] = value
|
||||
|
||||
// Filter löschen
|
||||
if _, ok := data.(map[string]interface{})["delete"]; ok {
|
||||
|
||||
delete(filterMap, dataID)
|
||||
break
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
err = saveSettings(Settings)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
settings = Settings
|
||||
|
||||
err = buildDatabaseDVR()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
buildXEPG(false)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// XEPG Mapping speichern
|
||||
func saveXEpgMapping(request RequestStruct) (err error) {
|
||||
|
||||
var tmp = Data.XEPG
|
||||
|
||||
err = json.Unmarshal([]byte(mapToJSON(request.EpgMapping)), &tmp)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = saveMapToJSONFile(System.File.XEPG, request.EpgMapping)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Data.XEPG.Channels = request.EpgMapping
|
||||
|
||||
cleanupXEPG()
|
||||
buildXEPG(true)
|
||||
return
|
||||
}
|
||||
|
||||
// Benutzerdaten speichern (WebUI)
|
||||
func saveUserData(request RequestStruct) (err error) {
|
||||
|
||||
var userData = request.UserData
|
||||
|
||||
var newCredentials = func(userID string, newUserData map[string]interface{}) (err error) {
|
||||
|
||||
var newUsername, newPassword string
|
||||
if username, ok := newUserData["username"].(string); ok {
|
||||
newUsername = username
|
||||
}
|
||||
|
||||
if password, ok := newUserData["password"].(string); ok {
|
||||
newPassword = password
|
||||
}
|
||||
|
||||
if len(newUsername) > 0 {
|
||||
err = authentication.ChangeCredentials(userID, newUsername, newPassword)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
for userID, newUserData := range userData {
|
||||
|
||||
err = newCredentials(userID, newUserData.(map[string]interface{}))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if request.DeleteUser == true {
|
||||
err = authentication.RemoveUser(userID)
|
||||
return
|
||||
}
|
||||
|
||||
delete(newUserData.(map[string]interface{}), "password")
|
||||
delete(newUserData.(map[string]interface{}), "confirm")
|
||||
|
||||
if _, ok := newUserData.(map[string]interface{})["delete"]; ok {
|
||||
|
||||
authentication.RemoveUser(userID)
|
||||
|
||||
} else {
|
||||
|
||||
err = authentication.WriteUserData(userID, newUserData.(map[string]interface{}))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Neuen Benutzer anlegen (WebUI)
|
||||
func saveNewUser(request RequestStruct) (err error) {
|
||||
|
||||
var data = request.UserData
|
||||
var username = data["username"].(string)
|
||||
var password = data["password"].(string)
|
||||
|
||||
delete(data, "password")
|
||||
delete(data, "confirm")
|
||||
|
||||
userID, err := authentication.CreateNewUser(username, password)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = authentication.WriteUserData(userID, data)
|
||||
return
|
||||
}
|
||||
|
||||
// Wizard (WebUI)
|
||||
func saveWizard(request RequestStruct) (nextStep int, err error) {
|
||||
|
||||
var wizard = jsonToMap(mapToJSON(request.Wizard))
|
||||
|
||||
for key, value := range wizard {
|
||||
|
||||
switch key {
|
||||
|
||||
case "tuner":
|
||||
Settings.Tuner = int(value.(float64))
|
||||
nextStep = 1
|
||||
|
||||
case "epgSource":
|
||||
Settings.EpgSource = value.(string)
|
||||
nextStep = 2
|
||||
|
||||
case "m3u", "xmltv":
|
||||
|
||||
var filesMap = make(map[string]interface{})
|
||||
var data = make(map[string]interface{})
|
||||
var indicator, dataID string
|
||||
|
||||
filesMap = make(map[string]interface{})
|
||||
|
||||
data["type"] = key
|
||||
data["new"] = true
|
||||
|
||||
switch key {
|
||||
|
||||
case "m3u":
|
||||
filesMap = Settings.Files.M3U
|
||||
data["name"] = "M3U"
|
||||
indicator = "M"
|
||||
|
||||
case "xmltv":
|
||||
filesMap = Settings.Files.XMLTV
|
||||
data["name"] = "XMLTV"
|
||||
indicator = "X"
|
||||
|
||||
}
|
||||
|
||||
dataID = indicator + randomString(19)
|
||||
data["file.source"] = value.(string)
|
||||
|
||||
filesMap[dataID] = data
|
||||
|
||||
switch key {
|
||||
case "m3u":
|
||||
Settings.Files.M3U = filesMap
|
||||
nextStep = 3
|
||||
|
||||
err = getProviderData(key, dataID)
|
||||
|
||||
if err != nil {
|
||||
ShowError(err, 000)
|
||||
delete(filesMap, dataID)
|
||||
return
|
||||
}
|
||||
|
||||
err = buildDatabaseDVR()
|
||||
if err != nil {
|
||||
ShowError(err, 000)
|
||||
delete(filesMap, dataID)
|
||||
return
|
||||
}
|
||||
|
||||
if Settings.EpgSource == "PMS" {
|
||||
nextStep = 10
|
||||
}
|
||||
|
||||
case "xmltv":
|
||||
Settings.Files.XMLTV = filesMap
|
||||
nextStep = 10
|
||||
|
||||
err = getProviderData(key, dataID)
|
||||
|
||||
if err != nil {
|
||||
|
||||
ShowError(err, 000)
|
||||
delete(filesMap, dataID)
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
buildXEPG(false)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
err = saveSettings(Settings)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Filterregeln erstellen
|
||||
func createFilterRules() (err error) {
|
||||
|
||||
Data.Filter = nil
|
||||
var dataFilter Filter
|
||||
|
||||
for _, f := range Settings.Filter {
|
||||
|
||||
var filter FilterStruct
|
||||
|
||||
var exclude, include string
|
||||
|
||||
err = json.Unmarshal([]byte(mapToJSON(f)), &filter)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
switch filter.Type {
|
||||
|
||||
case "custom-filter":
|
||||
dataFilter.CaseSensitive = filter.CaseSensitive
|
||||
dataFilter.Rule = filter.Filter
|
||||
dataFilter.Type = filter.Type
|
||||
|
||||
Data.Filter = append(Data.Filter, dataFilter)
|
||||
|
||||
case "group-title":
|
||||
if len(filter.Include) > 0 {
|
||||
include = fmt.Sprintf(" {%s}", filter.Include)
|
||||
}
|
||||
|
||||
if len(filter.Exclude) > 0 {
|
||||
exclude = fmt.Sprintf(" !{%s}", filter.Exclude)
|
||||
}
|
||||
|
||||
dataFilter.CaseSensitive = filter.CaseSensitive
|
||||
dataFilter.Rule = fmt.Sprintf("%s%s%s", filter.Filter, include, exclude)
|
||||
dataFilter.Type = filter.Type
|
||||
|
||||
Data.Filter = append(Data.Filter, dataFilter)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Datenbank für das DVR System erstellen
|
||||
func buildDatabaseDVR() (err error) {
|
||||
|
||||
System.ScanInProgress = 1
|
||||
|
||||
Data.Streams.All = make([]interface{}, 0)
|
||||
Data.Streams.Active = make([]interface{}, 0)
|
||||
Data.Streams.Inactive = make([]interface{}, 0)
|
||||
Data.Playlist.M3U.Groups.Text = []string{}
|
||||
Data.Playlist.M3U.Groups.Value = []string{}
|
||||
Data.StreamPreviewUI.Active = []string{}
|
||||
Data.StreamPreviewUI.Inactive = []string{}
|
||||
|
||||
var availableFileTypes = []string{"m3u", "hdhr"}
|
||||
|
||||
var tmpGroupsM3U = make(map[string]int64)
|
||||
|
||||
err = createFilterRules()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, fileType := range availableFileTypes {
|
||||
|
||||
var playlistFile = getLocalProviderFiles(fileType)
|
||||
|
||||
for n, i := range playlistFile {
|
||||
|
||||
var channels []interface{}
|
||||
var groupTitle, tvgID, uuid int = 0, 0, 0
|
||||
var keys = []string{"group-title", "tvg-id", "uuid"}
|
||||
var compatibility = make(map[string]int)
|
||||
|
||||
var id = strings.TrimSuffix(getFilenameFromPath(i), path.Ext(getFilenameFromPath(i)))
|
||||
var playlistName = getProviderParameter(id, fileType, "name")
|
||||
|
||||
switch fileType {
|
||||
|
||||
case "m3u":
|
||||
channels, err = parsePlaylist(i, fileType)
|
||||
case "hdhr":
|
||||
channels, err = parsePlaylist(i, fileType)
|
||||
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
ShowError(err, 1005)
|
||||
err = errors.New(playlistName + ": Local copy of the file no longer exists")
|
||||
ShowError(err, 0)
|
||||
playlistFile = append(playlistFile[:n], playlistFile[n+1:]...)
|
||||
}
|
||||
|
||||
// Streams analysieren
|
||||
for _, stream := range channels {
|
||||
|
||||
var s = stream.(map[string]string)
|
||||
s["_file.m3u.path"] = i
|
||||
s["_file.m3u.name"] = playlistName
|
||||
s["_file.m3u.id"] = id
|
||||
|
||||
// Kompatibilität berechnen
|
||||
for _, key := range keys {
|
||||
|
||||
switch key {
|
||||
case "uuid":
|
||||
if value, ok := s["_uuid.key"]; ok {
|
||||
if len(value) > 0 {
|
||||
uuid++
|
||||
}
|
||||
}
|
||||
|
||||
case "group-title":
|
||||
if value, ok := s[key]; ok {
|
||||
if len(value) > 0 {
|
||||
|
||||
if _, ok := tmpGroupsM3U[value]; ok {
|
||||
tmpGroupsM3U[value]++
|
||||
} else {
|
||||
tmpGroupsM3U[value] = 1
|
||||
}
|
||||
|
||||
groupTitle++
|
||||
}
|
||||
}
|
||||
|
||||
case "tvg-id":
|
||||
if value, ok := s[key]; ok {
|
||||
if len(value) > 0 {
|
||||
tvgID++
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Data.Streams.All = append(Data.Streams.All, stream)
|
||||
|
||||
// Neuer Filter ab Version 1.3.0
|
||||
var preview string
|
||||
var status = filterThisStream(stream)
|
||||
|
||||
if name, ok := s["name"]; ok {
|
||||
var group string
|
||||
|
||||
if v, ok := s["group-title"]; ok {
|
||||
group = v
|
||||
}
|
||||
|
||||
preview = fmt.Sprintf("%s [%s]", name, group)
|
||||
|
||||
}
|
||||
|
||||
switch status {
|
||||
|
||||
case true:
|
||||
Data.StreamPreviewUI.Active = append(Data.StreamPreviewUI.Active, preview)
|
||||
Data.Streams.Active = append(Data.Streams.Active, stream)
|
||||
|
||||
case false:
|
||||
Data.StreamPreviewUI.Inactive = append(Data.StreamPreviewUI.Inactive, preview)
|
||||
Data.Streams.Inactive = append(Data.Streams.Inactive, stream)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if tvgID == 0 {
|
||||
compatibility["tvg.id"] = 0
|
||||
} else {
|
||||
compatibility["tvg.id"] = int(tvgID * 100 / len(channels))
|
||||
}
|
||||
|
||||
if groupTitle == 0 {
|
||||
compatibility["group.title"] = 0
|
||||
} else {
|
||||
compatibility["group.title"] = int(groupTitle * 100 / len(channels))
|
||||
}
|
||||
|
||||
if uuid == 0 {
|
||||
compatibility["stream.id"] = 0
|
||||
} else {
|
||||
compatibility["stream.id"] = int(uuid * 100 / len(channels))
|
||||
}
|
||||
|
||||
compatibility["streams"] = len(channels)
|
||||
|
||||
setProviderCompatibility(id, fileType, compatibility)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for group, count := range tmpGroupsM3U {
|
||||
var text = fmt.Sprintf("%s (%d)", group, count)
|
||||
var value = fmt.Sprintf("%s", group)
|
||||
Data.Playlist.M3U.Groups.Text = append(Data.Playlist.M3U.Groups.Text, text)
|
||||
Data.Playlist.M3U.Groups.Value = append(Data.Playlist.M3U.Groups.Value, value)
|
||||
}
|
||||
|
||||
sort.Strings(Data.Playlist.M3U.Groups.Text)
|
||||
sort.Strings(Data.Playlist.M3U.Groups.Value)
|
||||
|
||||
if len(Data.Streams.Active) == 0 && len(Data.Streams.All) <= System.DVRLimit && len(Settings.Filter) == 0 {
|
||||
Data.Streams.Active = Data.Streams.All
|
||||
Data.Streams.Inactive = make([]interface{}, 0)
|
||||
|
||||
Data.StreamPreviewUI.Active = Data.StreamPreviewUI.Inactive
|
||||
Data.StreamPreviewUI.Inactive = []string{}
|
||||
|
||||
}
|
||||
|
||||
if len(Data.Streams.Active) > System.DVRLimit {
|
||||
showWarning(2000)
|
||||
}
|
||||
|
||||
if len(Settings.Filter) == 0 && len(Data.Streams.All) > System.DVRLimit {
|
||||
showWarning(2001)
|
||||
}
|
||||
|
||||
System.ScanInProgress = 0
|
||||
showInfo(fmt.Sprintf("All streams:%d", len(Data.Streams.All)))
|
||||
showInfo(fmt.Sprintf("Active streams:%d", len(Data.Streams.Active)))
|
||||
showInfo(fmt.Sprintf("Filter:%d", len(Data.Filter)))
|
||||
|
||||
sort.Strings(Data.StreamPreviewUI.Active)
|
||||
sort.Strings(Data.StreamPreviewUI.Inactive)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Speicherort aller lokalen Providerdateien laden, immer für eine Dateityp (M3U, XMLTV usw.)
|
||||
func getLocalProviderFiles(fileType string) (localFiles []string) {
|
||||
|
||||
var fileExtension string
|
||||
var dataMap = make(map[string]interface{})
|
||||
|
||||
switch fileType {
|
||||
|
||||
case "m3u":
|
||||
fileExtension = ".m3u"
|
||||
dataMap = Settings.Files.M3U
|
||||
|
||||
case "hdhr":
|
||||
fileExtension = ".json"
|
||||
dataMap = Settings.Files.HDHR
|
||||
|
||||
case "xmltv":
|
||||
fileExtension = ".xml"
|
||||
dataMap = Settings.Files.XMLTV
|
||||
|
||||
}
|
||||
|
||||
for dataID := range dataMap {
|
||||
localFiles = append(localFiles, System.Folder.Data+dataID+fileExtension)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Providerparameter anhand von dem Key ausgeben
|
||||
func getProviderParameter(id, fileType, key string) (s string) {
|
||||
|
||||
var dataMap = make(map[string]interface{})
|
||||
|
||||
switch fileType {
|
||||
case "m3u":
|
||||
dataMap = Settings.Files.M3U
|
||||
|
||||
case "hdhr":
|
||||
dataMap = Settings.Files.HDHR
|
||||
|
||||
case "xmltv":
|
||||
dataMap = Settings.Files.XMLTV
|
||||
}
|
||||
|
||||
if data, ok := dataMap[id].(map[string]interface{}); ok {
|
||||
|
||||
if v, ok := data[key].(string); ok {
|
||||
s = v
|
||||
}
|
||||
|
||||
if v, ok := data[key].(float64); ok {
|
||||
s = strconv.Itoa(int(v))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Provider Statistiken Kompatibilität aktualisieren
|
||||
func setProviderCompatibility(id, fileType string, compatibility map[string]int) {
|
||||
|
||||
var dataMap = make(map[string]interface{})
|
||||
|
||||
switch fileType {
|
||||
case "m3u":
|
||||
dataMap = Settings.Files.M3U
|
||||
|
||||
case "hdhr":
|
||||
dataMap = Settings.Files.HDHR
|
||||
|
||||
case "xmltv":
|
||||
dataMap = Settings.Files.XMLTV
|
||||
}
|
||||
|
||||
if data, ok := dataMap[id].(map[string]interface{}); ok {
|
||||
|
||||
data["compatibility"] = compatibility
|
||||
|
||||
switch fileType {
|
||||
case "m3u":
|
||||
Settings.Files.M3U = dataMap
|
||||
case "hdhr":
|
||||
Settings.Files.HDHR = dataMap
|
||||
case "xmltv":
|
||||
Settings.Files.XMLTV = dataMap
|
||||
}
|
||||
|
||||
saveSettings(Settings)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user