All checks were successful
continuous-integration/drone/push Build is passing
332 lines
6.6 KiB
Go
332 lines
6.6 KiB
Go
package src
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"net/url"
|
|
"strings"
|
|
"time"
|
|
|
|
m3u "xteve/src/internal/m3u-parser"
|
|
)
|
|
|
|
// fileType: Welcher Dateityp soll aktualisiert werden (m3u, hdhr, xml) | fileID: Update einer bestimmten Datei (Provider ID)
|
|
func getProviderData(fileType, fileID string) (err error) {
|
|
|
|
var fileExtension, serverFileName string
|
|
var body = make([]byte, 0)
|
|
var newProvider = false
|
|
var dataMap = make(map[string]any)
|
|
|
|
var saveDateFromProvider = func(fileSource, serverFileName, id string, body []byte) (err error) {
|
|
|
|
var data = make(map[string]any)
|
|
|
|
if value, ok := dataMap[id].(map[string]any); ok {
|
|
data = value
|
|
} else {
|
|
data["id.provider"] = id
|
|
dataMap[id] = data
|
|
}
|
|
|
|
// Default keys für die Providerdaten
|
|
var keys = []string{"name", "description", "type", "file." + System.AppName, "file.source", "tuner", "last.update", "compatibility", "counter.error", "counter.download", "provider.availability"}
|
|
|
|
for _, key := range keys {
|
|
|
|
if _, ok := data[key]; !ok {
|
|
|
|
switch key {
|
|
|
|
case "name":
|
|
data[key] = serverFileName
|
|
|
|
case "description":
|
|
data[key] = ""
|
|
|
|
case "type":
|
|
data[key] = fileType
|
|
|
|
case "file." + System.AppName:
|
|
data[key] = id + fileExtension
|
|
|
|
case "file.source":
|
|
data[key] = fileSource
|
|
|
|
case "last.update":
|
|
data[key] = time.Now().Format("2006-01-02 15:04:05")
|
|
|
|
case "tuner":
|
|
if fileType == "m3u" || fileType == "hdhr" {
|
|
if _, ok := data[key].(float64); !ok {
|
|
data[key] = 1
|
|
}
|
|
}
|
|
|
|
case "compatibility":
|
|
data[key] = make(map[string]any)
|
|
|
|
case "counter.download":
|
|
data[key] = 0.0
|
|
|
|
case "counter.error":
|
|
data[key] = 0.0
|
|
|
|
case "provider.availability":
|
|
data[key] = 100
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if _, ok := data["id.provider"]; !ok {
|
|
data["id.provider"] = id
|
|
}
|
|
|
|
// Datei extrahieren
|
|
body, err = extractGZIP(body, fileSource)
|
|
if err != nil {
|
|
ShowError(err, 000)
|
|
return
|
|
}
|
|
|
|
// Daten überprüfen
|
|
showInfo("Check File:" + fileSource)
|
|
switch fileType {
|
|
|
|
case "m3u":
|
|
_, err = m3u.MakeInterfaceFromM3U(body)
|
|
|
|
case "hdhr":
|
|
_, err = jsonToInterface(string(body))
|
|
|
|
case "xmltv":
|
|
err = checkXMLCompatibility(id, body)
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
var filePath = System.Folder.Data + data["file."+System.AppName].(string)
|
|
|
|
err = writeByteToFile(filePath, body)
|
|
|
|
if err == nil {
|
|
data["last.update"] = time.Now().Format("2006-01-02 15:04:05")
|
|
data["counter.download"] = data["counter.download"].(float64) + 1
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
switch fileType {
|
|
|
|
case "m3u":
|
|
dataMap = Settings.Files.M3U
|
|
fileExtension = ".m3u"
|
|
|
|
case "hdhr":
|
|
dataMap = Settings.Files.HDHR
|
|
fileExtension = ".json"
|
|
|
|
case "xmltv":
|
|
dataMap = Settings.Files.XMLTV
|
|
fileExtension = ".xml"
|
|
|
|
}
|
|
|
|
for dataID, d := range dataMap {
|
|
|
|
var data = d.(map[string]any)
|
|
var fileSource = data["file.source"].(string)
|
|
newProvider = false
|
|
|
|
if _, ok := data["new"]; ok {
|
|
newProvider = true
|
|
delete(data, "new")
|
|
}
|
|
|
|
// Wenn eine ID vorhanden ist und nicht mit der aus der Datanbank übereinstimmt, wird die Aktualisierung übersprungen (goto)
|
|
if len(fileID) > 0 && newProvider == false {
|
|
if dataID != fileID {
|
|
goto Done
|
|
}
|
|
}
|
|
|
|
switch fileType {
|
|
|
|
case "hdhr":
|
|
|
|
// Laden vom HDHomeRun Tuner
|
|
showInfo("Tuner:" + fileSource)
|
|
var tunerURL = "http://" + fileSource + "/lineup.json"
|
|
serverFileName, body, err = downloadFileFromServer(tunerURL)
|
|
|
|
default:
|
|
|
|
if strings.Contains(fileSource, "http://") || strings.Contains(fileSource, "https://") {
|
|
|
|
// Laden vom Remote Server
|
|
showInfo("Download:" + fileSource)
|
|
serverFileName, body, err = downloadFileFromServer(fileSource)
|
|
|
|
} else {
|
|
|
|
// Laden einer lokalen Datei
|
|
showInfo("Open:" + fileSource)
|
|
|
|
err = checkFile(fileSource)
|
|
if err == nil {
|
|
body, err = readByteFromFile(fileSource)
|
|
serverFileName = getFilenameFromPath(fileSource)
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if err == nil {
|
|
|
|
err = saveDateFromProvider(fileSource, serverFileName, dataID, body)
|
|
if err == nil {
|
|
showInfo("Save File:" + fileSource + " [ID: " + dataID + "]")
|
|
}
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
ShowError(err, 000)
|
|
var downloadErr = err
|
|
|
|
if newProvider == false {
|
|
|
|
// Prüfen ob ältere Datei vorhanden ist
|
|
var file = System.Folder.Data + dataID + fileExtension
|
|
|
|
err = checkFile(file)
|
|
if err == nil {
|
|
|
|
if len(fileID) == 0 {
|
|
showWarning(1011)
|
|
}
|
|
|
|
err = downloadErr
|
|
}
|
|
|
|
// Fehler Counter um 1 erhöhen
|
|
var data = make(map[string]any)
|
|
if value, ok := dataMap[dataID].(map[string]any); ok {
|
|
|
|
data = value
|
|
data["counter.error"] = data["counter.error"].(float64) + 1
|
|
data["counter.download"] = data["counter.download"].(float64) + 1
|
|
|
|
}
|
|
|
|
} else {
|
|
return downloadErr
|
|
}
|
|
|
|
}
|
|
|
|
// Berechnen der Fehlerquote
|
|
if newProvider == false {
|
|
|
|
if value, ok := dataMap[dataID].(map[string]any); ok {
|
|
|
|
var data = make(map[string]any)
|
|
data = value
|
|
|
|
if data["counter.error"].(float64) == 0 {
|
|
data["provider.availability"] = 100
|
|
} else {
|
|
data["provider.availability"] = int(data["counter.error"].(float64)*100/data["counter.download"].(float64)*-1 + 100)
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
switch fileType {
|
|
|
|
case "m3u":
|
|
Settings.Files.M3U = dataMap
|
|
|
|
case "hdhr":
|
|
Settings.Files.HDHR = dataMap
|
|
|
|
case "xmltv":
|
|
Settings.Files.XMLTV = dataMap
|
|
delete(Data.Cache.XMLTV, System.Folder.Data+dataID+fileExtension)
|
|
|
|
}
|
|
|
|
saveSettings(Settings)
|
|
|
|
Done:
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func downloadFileFromServer(providerURL string) (filename string, body []byte, err error) {
|
|
|
|
_, err = url.ParseRequestURI(providerURL)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
req, err := http.NewRequest(http.MethodGet, providerURL, nil)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
req.Header.Set("User-Agent", getUserAgent())
|
|
|
|
client := &http.Client{}
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
err = fmt.Errorf("%d: %s %s", resp.StatusCode, providerURL, http.StatusText(resp.StatusCode))
|
|
return
|
|
}
|
|
|
|
// Dateiname aus dem Header holen
|
|
var index = strings.Index(resp.Header.Get("Content-Disposition"), "filename")
|
|
|
|
if index > -1 {
|
|
|
|
var headerFilename = resp.Header.Get("Content-Disposition")[index:len(resp.Header.Get("Content-Disposition"))]
|
|
var value = strings.Split(headerFilename, `=`)
|
|
var f = strings.Replace(value[1], `"`, "", -1)
|
|
|
|
f = strings.Replace(f, `;`, "", -1)
|
|
filename = f
|
|
showInfo("Header filename:" + filename)
|
|
|
|
} else {
|
|
|
|
var cleanFilename = strings.SplitN(getFilenameFromPath(providerURL), "?", 2)
|
|
filename = cleanFilename[0]
|
|
|
|
}
|
|
|
|
body, err = ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
return
|
|
}
|