go fix for 1.26
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2026-02-11 12:53:35 +11:00
parent 339d2d0aa5
commit c5545cbf08
20 changed files with 656 additions and 660 deletions

View File

@@ -1,21 +1,21 @@
package authentication
import (
"encoding/json"
"errors"
"io/ioutil"
"net/http"
"os"
"path/filepath"
"encoding/json"
"errors"
"io/ioutil"
"net/http"
"os"
"path/filepath"
"crypto/hmac"
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"crypto/hmac"
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"time"
//"fmt"
//"log"
"time"
//"fmt"
//"log"
)
const tokenLength = 40
@@ -27,19 +27,19 @@ var database string
var databaseFile = "authentication.json"
var data = make(map[string]interface{})
var tokens = make(map[string]interface{})
var data = make(map[string]any)
var tokens = make(map[string]any)
var initAuthentication = false
// Cookie : cookie
type Cookie struct {
Name string
Value string
Path string
Domain string
Expires time.Time
RawExpires string
Name string
Value string
Path string
Domain string
Expires time.Time
RawExpires string
}
// Framework examples
@@ -128,465 +128,465 @@ func main() {
// Init : databasePath = Path to authentication.json
func Init(databasePath string, validity int) (err error) {
database = filepath.Dir(databasePath) + string(os.PathSeparator) + databaseFile
database = filepath.Dir(databasePath) + string(os.PathSeparator) + databaseFile
// Check if the database already exists
if _, err = os.Stat(database); os.IsNotExist(err) {
// Create an empty database
var defaults = make(map[string]interface{})
defaults["dbVersion"] = "1.0"
defaults["hash"] = "sha256"
defaults["users"] = make(map[string]interface{})
// Check if the database already exists
if _, err = os.Stat(database); os.IsNotExist(err) {
// Create an empty database
var defaults = make(map[string]any)
defaults["dbVersion"] = "1.0"
defaults["hash"] = "sha256"
defaults["users"] = make(map[string]any)
if saveDatabase(defaults) != nil {
return
}
}
if saveDatabase(defaults) != nil {
return
}
}
// Loading the database
err = loadDatabase()
// Loading the database
err = loadDatabase()
// Set Token Validity
tokenValidity = validity
initAuthentication = true
return
// Set Token Validity
tokenValidity = validity
initAuthentication = true
return
}
// CreateDefaultUser = created efault user
func CreateDefaultUser(username, password string) (err error) {
err = checkInit()
if err != nil {
return
}
err = checkInit()
if err != nil {
return
}
var users = data["users"].(map[string]interface{})
// Check if the default user exists
if len(users) > 0 {
err = createError(001)
return
}
var users = data["users"].(map[string]any)
// Check if the default user exists
if len(users) > 0 {
err = createError(001)
return
}
var defaults = defaultsForNewUser(username, password)
users[defaults["_id"].(string)] = defaults
saveDatabase(data)
var defaults = defaultsForNewUser(username, password)
users[defaults["_id"].(string)] = defaults
saveDatabase(data)
return
return
}
// CreateNewUser : create new user
func CreateNewUser(username, password string) (userID string, err error) {
err = checkInit()
if err != nil {
return
}
err = checkInit()
if err != nil {
return
}
var checkIfTheUserAlreadyExists = func(username string, userData map[string]interface{}) (err error) {
var salt = userData["_salt"].(string)
var loginUsername = userData["_username"].(string)
var checkIfTheUserAlreadyExists = func(username string, userData map[string]any) (err error) {
var salt = userData["_salt"].(string)
var loginUsername = userData["_username"].(string)
if SHA256(username, salt) == loginUsername {
err = createError(020)
}
if SHA256(username, salt) == loginUsername {
err = createError(020)
}
return
}
return
}
var users = data["users"].(map[string]interface{})
for _, userData := range users {
err = checkIfTheUserAlreadyExists(username, userData.(map[string]interface{}))
if err != nil {
return
}
}
var users = data["users"].(map[string]any)
for _, userData := range users {
err = checkIfTheUserAlreadyExists(username, userData.(map[string]any))
if err != nil {
return
}
}
var defaults = defaultsForNewUser(username, password)
userID = defaults["_id"].(string)
users[userID] = defaults
var defaults = defaultsForNewUser(username, password)
userID = defaults["_id"].(string)
users[userID] = defaults
saveDatabase(data)
saveDatabase(data)
return
return
}
// UserAuthentication : user authentication
func UserAuthentication(username, password string) (token string, err error) {
err = checkInit()
if err != nil {
return
}
err = checkInit()
if err != nil {
return
}
var login = func(username, password string, loginData map[string]interface{}) (err error) {
err = createError(010)
var login = func(username, password string, loginData map[string]any) (err error) {
err = createError(010)
var salt = loginData["_salt"].(string)
var loginUsername = loginData["_username"].(string)
var loginPassword = loginData["_password"].(string)
var salt = loginData["_salt"].(string)
var loginUsername = loginData["_username"].(string)
var loginPassword = loginData["_password"].(string)
if SHA256(username, salt) == loginUsername {
if SHA256(password, salt) == loginPassword {
err = nil
}
}
if SHA256(username, salt) == loginUsername {
if SHA256(password, salt) == loginPassword {
err = nil
}
}
return
}
return
}
var users = data["users"].(map[string]interface{})
for id, loginData := range users {
err = login(username, password, loginData.(map[string]interface{}))
if err == nil {
token = setToken(id, "-")
return
}
}
var users = data["users"].(map[string]any)
for id, loginData := range users {
err = login(username, password, loginData.(map[string]any))
if err == nil {
token = setToken(id, "-")
return
}
}
return
return
}
// CheckTheValidityOfTheToken : check token
func CheckTheValidityOfTheToken(token string) (newToken string, err error) {
err = checkInit()
if err != nil {
return
}
err = checkInit()
if err != nil {
return
}
err = createError(011)
err = createError(011)
if v, ok := tokens[token]; ok {
var expires = v.(map[string]interface{})["expires"].(time.Time)
var userID = v.(map[string]interface{})["id"].(string)
if v, ok := tokens[token]; ok {
var expires = v.(map[string]any)["expires"].(time.Time)
var userID = v.(map[string]any)["id"].(string)
if expires.Sub(time.Now().Local()) < 0 {
return
}
if expires.Sub(time.Now().Local()) < 0 {
return
}
newToken = setToken(userID, token)
newToken = setToken(userID, token)
err = nil
err = nil
} else {
return
}
} else {
return
}
return
return
}
// GetUserID : get user ID
func GetUserID(token string) (userID string, err error) {
err = checkInit()
if err != nil {
return
}
err = checkInit()
if err != nil {
return
}
err = createError(002)
err = createError(002)
if v, ok := tokens[token]; ok {
var expires = v.(map[string]interface{})["expires"].(time.Time)
userID = v.(map[string]interface{})["id"].(string)
if v, ok := tokens[token]; ok {
var expires = v.(map[string]any)["expires"].(time.Time)
userID = v.(map[string]any)["id"].(string)
if expires.Sub(time.Now().Local()) < 0 {
return
}
if expires.Sub(time.Now().Local()) < 0 {
return
}
err = nil
}
err = nil
}
return
return
}
// WriteUserData : save user date
func WriteUserData(userID string, userData map[string]interface{}) (err error) {
func WriteUserData(userID string, userData map[string]any) (err error) {
err = checkInit()
if err != nil {
return
}
err = checkInit()
if err != nil {
return
}
err = createError(030)
err = createError(030)
if v, ok := data["users"].(map[string]interface{})[userID].(map[string]interface{}); ok {
if v, ok := data["users"].(map[string]any)[userID].(map[string]any); ok {
v["data"] = userData
err = saveDatabase(data)
v["data"] = userData
err = saveDatabase(data)
} else {
return
}
} else {
return
}
return
return
}
// ReadUserData : load user date
func ReadUserData(userID string) (userData map[string]interface{}, err error) {
func ReadUserData(userID string) (userData map[string]any, err error) {
err = checkInit()
if err != nil {
return
}
err = checkInit()
if err != nil {
return
}
err = createError(031)
err = createError(031)
if v, ok := data["users"].(map[string]interface{})[userID].(map[string]interface{}); ok {
userData = v["data"].(map[string]interface{})
err = nil
if v, ok := data["users"].(map[string]any)[userID].(map[string]any); ok {
userData = v["data"].(map[string]any)
err = nil
return
}
return
}
return
return
}
// RemoveUser : remove user
func RemoveUser(userID string) (err error) {
err = checkInit()
if err != nil {
return
}
err = checkInit()
if err != nil {
return
}
err = createError(032)
err = createError(032)
if _, ok := data["users"].(map[string]interface{})[userID]; ok {
if _, ok := data["users"].(map[string]any)[userID]; ok {
delete(data["users"].(map[string]interface{}), userID)
err = saveDatabase(data)
delete(data["users"].(map[string]any), userID)
err = saveDatabase(data)
return
}
return
}
return
return
}
// SetDefaultUserData : set default user data
func SetDefaultUserData(defaults map[string]interface{}) (err error) {
func SetDefaultUserData(defaults map[string]any) (err error) {
allUserData, err := GetAllUserData()
allUserData, err := GetAllUserData()
for _, d := range allUserData {
var data = d.(map[string]interface{})["data"].(map[string]interface{})
var userID = d.(map[string]interface{})["_id"].(string)
for _, d := range allUserData {
var data = d.(map[string]any)["data"].(map[string]any)
var userID = d.(map[string]any)["_id"].(string)
for k, v := range defaults {
if _, ok := data[k]; ok {
// Key exist
} else {
data[k] = v
}
}
err = WriteUserData(userID, data)
}
return
for k, v := range defaults {
if _, ok := data[k]; ok {
// Key exist
} else {
data[k] = v
}
}
err = WriteUserData(userID, data)
}
return
}
// ChangeCredentials : change credentials
func ChangeCredentials(userID, username, password string) (err error) {
err = checkInit()
if err != nil {
return
}
err = checkInit()
if err != nil {
return
}
err = createError(032)
err = createError(032)
if userData, ok := data["users"].(map[string]interface{})[userID]; ok {
//var userData = tmp.(map[string]interface{})
var salt = userData.(map[string]interface{})["_salt"].(string)
if userData, ok := data["users"].(map[string]any)[userID]; ok {
//var userData = tmp.(map[string]interface{})
var salt = userData.(map[string]any)["_salt"].(string)
if len(username) > 0 {
userData.(map[string]interface{})["_username"] = SHA256(username, salt)
}
if len(username) > 0 {
userData.(map[string]any)["_username"] = SHA256(username, salt)
}
if len(password) > 0 {
userData.(map[string]interface{})["_password"] = SHA256(password, salt)
}
if len(password) > 0 {
userData.(map[string]any)["_password"] = SHA256(password, salt)
}
err = saveDatabase(data)
}
err = saveDatabase(data)
}
return
return
}
// GetAllUserData : get all user data
func GetAllUserData() (allUserData map[string]interface{}, err error) {
func GetAllUserData() (allUserData map[string]any, err error) {
err = checkInit()
if err != nil {
return
}
err = checkInit()
if err != nil {
return
}
if len(data) == 0 {
var defaults = make(map[string]interface{})
defaults["dbVersion"] = "1.0"
defaults["hash"] = "sha256"
defaults["users"] = make(map[string]interface{})
saveDatabase(defaults)
data = defaults
}
if len(data) == 0 {
var defaults = make(map[string]any)
defaults["dbVersion"] = "1.0"
defaults["hash"] = "sha256"
defaults["users"] = make(map[string]any)
saveDatabase(defaults)
data = defaults
}
allUserData = data["users"].(map[string]interface{})
return
allUserData = data["users"].(map[string]any)
return
}
// CheckTheValidityOfTheTokenFromHTTPHeader : get token from HTTP header
func CheckTheValidityOfTheTokenFromHTTPHeader(w http.ResponseWriter, r *http.Request) (writer http.ResponseWriter, newToken string, err error) {
err = createError(011)
for _, cookie := range r.Cookies() {
if cookie.Name == "Token" {
var token string
token, err = CheckTheValidityOfTheToken(cookie.Value)
//fmt.Println("T", token, err)
writer = SetCookieToken(w, token)
newToken = token
}
}
//fmt.Println(err)
return
err = createError(011)
for _, cookie := range r.Cookies() {
if cookie.Name == "Token" {
var token string
token, err = CheckTheValidityOfTheToken(cookie.Value)
//fmt.Println("T", token, err)
writer = SetCookieToken(w, token)
newToken = token
}
}
//fmt.Println(err)
return
}
// Framework tools
func checkInit() (err error) {
if initAuthentication == false {
err = createError(000)
}
if initAuthentication == false {
err = createError(000)
}
return
return
}
func saveDatabase(tmpMap interface{}) (err error) {
func saveDatabase(tmpMap any) (err error) {
jsonString, err := json.MarshalIndent(tmpMap, "", " ")
jsonString, err := json.MarshalIndent(tmpMap, "", " ")
if err != nil {
return
}
if err != nil {
return
}
err = ioutil.WriteFile(database, []byte(jsonString), 0600)
if err != nil {
return
}
err = ioutil.WriteFile(database, []byte(jsonString), 0600)
if err != nil {
return
}
return
return
}
func loadDatabase() (err error) {
jsonString, err := ioutil.ReadFile(database)
if err != nil {
return
}
jsonString, err := ioutil.ReadFile(database)
if err != nil {
return
}
err = json.Unmarshal([]byte(jsonString), &data)
if err != nil {
return
}
err = json.Unmarshal([]byte(jsonString), &data)
if err != nil {
return
}
return
return
}
// SHA256 : password + salt = sha256 string
func SHA256(secret, salt string) string {
key := []byte(secret)
h := hmac.New(sha256.New, key)
h.Write([]byte("_remote_db"))
return base64.StdEncoding.EncodeToString(h.Sum(nil))
key := []byte(secret)
h := hmac.New(sha256.New, key)
h.Write([]byte("_remote_db"))
return base64.StdEncoding.EncodeToString(h.Sum(nil))
}
func randomString(n int) string {
const alphanum = "-AbCdEfGhIjKlMnOpQrStUvWxYz0123456789aBcDeFgHiJkLmNoPqRsTuVwXyZ_"
const alphanum = "-AbCdEfGhIjKlMnOpQrStUvWxYz0123456789aBcDeFgHiJkLmNoPqRsTuVwXyZ_"
var bytes = make([]byte, n)
rand.Read(bytes)
for i, b := range bytes {
bytes[i] = alphanum[b%byte(len(alphanum))]
}
return string(bytes)
var bytes = make([]byte, n)
rand.Read(bytes)
for i, b := range bytes {
bytes[i] = alphanum[b%byte(len(alphanum))]
}
return string(bytes)
}
func randomID(n int) string {
const alphanum = "ABCDEFGHJKLMNOPQRSTUVWXYZ0123456789"
const alphanum = "ABCDEFGHJKLMNOPQRSTUVWXYZ0123456789"
var bytes = make([]byte, n)
rand.Read(bytes)
for i, b := range bytes {
bytes[i] = alphanum[b%byte(len(alphanum))]
}
return string(bytes)
var bytes = make([]byte, n)
rand.Read(bytes)
for i, b := range bytes {
bytes[i] = alphanum[b%byte(len(alphanum))]
}
return string(bytes)
}
func createError(errCode int) (err error) {
var errMsg string
switch errCode {
case 000:
errMsg = "Authentication has not yet been initialized"
case 001:
errMsg = "Default user already exists"
case 002:
errMsg = "No user id found for this token"
case 010:
errMsg = "User authentication failed"
case 011:
errMsg = "Session has expired"
case 020:
errMsg = "User already exists"
case 030:
errMsg = "User data could not be saved"
case 031:
errMsg = "User data could not be read"
case 032:
errMsg = "User ID was not found"
}
var errMsg string
switch errCode {
case 000:
errMsg = "Authentication has not yet been initialized"
case 001:
errMsg = "Default user already exists"
case 002:
errMsg = "No user id found for this token"
case 010:
errMsg = "User authentication failed"
case 011:
errMsg = "Session has expired"
case 020:
errMsg = "User already exists"
case 030:
errMsg = "User data could not be saved"
case 031:
errMsg = "User data could not be read"
case 032:
errMsg = "User ID was not found"
}
err = errors.New(errMsg)
return
err = errors.New(errMsg)
return
}
func defaultsForNewUser(username, password string) map[string]interface{} {
var defaults = make(map[string]interface{})
var salt = randomString(saltLength)
defaults["_username"] = SHA256(username, salt)
defaults["_password"] = SHA256(password, salt)
defaults["_salt"] = salt
defaults["_id"] = "id-" + randomID(idLength)
//defaults["_one.time.token"] = randomString(tokenLength)
defaults["data"] = make(map[string]interface{})
func defaultsForNewUser(username, password string) map[string]any {
var defaults = make(map[string]any)
var salt = randomString(saltLength)
defaults["_username"] = SHA256(username, salt)
defaults["_password"] = SHA256(password, salt)
defaults["_salt"] = salt
defaults["_id"] = "id-" + randomID(idLength)
//defaults["_one.time.token"] = randomString(tokenLength)
defaults["data"] = make(map[string]any)
return defaults
return defaults
}
func setToken(id, oldToken string) (newToken string) {
delete(tokens, oldToken)
delete(tokens, oldToken)
loopToken:
newToken = randomString(tokenLength)
if _, ok := tokens[newToken]; ok {
goto loopToken
}
newToken = randomString(tokenLength)
if _, ok := tokens[newToken]; ok {
goto loopToken
}
var tmp = make(map[string]interface{})
tmp["id"] = id
tmp["expires"] = time.Now().Local().Add(time.Minute * time.Duration(tokenValidity))
var tmp = make(map[string]any)
tmp["id"] = id
tmp["expires"] = time.Now().Local().Add(time.Minute * time.Duration(tokenValidity))
tokens[newToken] = tmp
tokens[newToken] = tmp
return
return
}
func mapToJSON(tmpMap interface{}) string {
jsonString, err := json.MarshalIndent(tmpMap, "", " ")
if err != nil {
return "{}"
}
return string(jsonString)
func mapToJSON(tmpMap any) string {
jsonString, err := json.MarshalIndent(tmpMap, "", " ")
if err != nil {
return "{}"
}
return string(jsonString)
}
// SetCookieToken : set cookie
func SetCookieToken(w http.ResponseWriter, token string) http.ResponseWriter {
expiration := time.Now().Add(time.Minute * time.Duration(tokenValidity))
cookie := http.Cookie{Name: "Token", Value: token, Expires: expiration}
http.SetCookie(w, &cookie)
return w
expiration := time.Now().Add(time.Minute * time.Duration(tokenValidity))
cookie := http.Cookie{Name: "Token", Value: token, Expires: expiration}
http.SetCookie(w, &cookie)
return w
}

View File

@@ -1,84 +1,84 @@
package m3u
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"testing"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"testing"
)
type M3UStream struct {
GroupTitle string `json:"group-title,required"`
Name string `json:"name,required"`
TvgID string `json:"tvg-id,required"`
TvgLogo string `json:"tvg-logo,required"`
TvgName string `json:"tvg-name,required"`
URL string `json:"url,required"`
UUIDKey string `json:"_uuid.key,omitempty"`
UUIDValue string `json:"_uuid.value,omitempty"`
GroupTitle string `json:"group-title,required"`
Name string `json:"name,required"`
TvgID string `json:"tvg-id,required"`
TvgLogo string `json:"tvg-logo,required"`
TvgName string `json:"tvg-name,required"`
URL string `json:"url,required"`
UUIDKey string `json:"_uuid.key,omitempty"`
UUIDValue string `json:"_uuid.value,omitempty"`
}
func TestStream1(t *testing.T) {
var file = "test_list_1.m3u"
var content, err = ioutil.ReadFile(file)
if err != nil {
t.Error(err)
return
}
var file = "test_list_1.m3u"
var content, err = ioutil.ReadFile(file)
if err != nil {
t.Error(err)
return
}
streams, err := MakeInterfaceFromM3U(content)
streams, err := MakeInterfaceFromM3U(content)
if err != nil {
t.Error(err)
}
if err != nil {
t.Error(err)
}
err = checkStream(streams)
if err != nil {
t.Error(err)
}
err = checkStream(streams)
if err != nil {
t.Error(err)
}
fmt.Println("Streams:", len(streams))
t.Log(streams)
fmt.Println("Streams:", len(streams))
t.Log(streams)
}
func checkStream(streamInterface []interface{}) (err error) {
func checkStream(streamInterface []any) (err error) {
for i, s := range streamInterface {
for i, s := range streamInterface {
var stream = s.(map[string]string)
var m3uStream M3UStream
var stream = s.(map[string]string)
var m3uStream M3UStream
jsonString, err := json.MarshalIndent(stream, "", " ")
jsonString, err := json.MarshalIndent(stream, "", " ")
if err == nil {
if err == nil {
err = json.Unmarshal(jsonString, &m3uStream)
if err == nil {
err = json.Unmarshal(jsonString, &m3uStream)
if err == nil {
log.Print(fmt.Sprintf("Stream: %d", i))
log.Print(fmt.Sprintf("Name*: %s", m3uStream.Name))
log.Print(fmt.Sprintf("URL*: %s", m3uStream.URL))
log.Print(fmt.Sprintf("tvg-name: %s", m3uStream.TvgName))
log.Print(fmt.Sprintf("tvg-id**: %s", m3uStream.TvgID))
log.Print(fmt.Sprintf("tvg-logo: %s", m3uStream.TvgLogo))
log.Print(fmt.Sprintf("group-title**: %s", m3uStream.GroupTitle))
log.Print(fmt.Sprintf("Stream: %d", i))
log.Print(fmt.Sprintf("Name*: %s", m3uStream.Name))
log.Print(fmt.Sprintf("URL*: %s", m3uStream.URL))
log.Print(fmt.Sprintf("tvg-name: %s", m3uStream.TvgName))
log.Print(fmt.Sprintf("tvg-id**: %s", m3uStream.TvgID))
log.Print(fmt.Sprintf("tvg-logo: %s", m3uStream.TvgLogo))
log.Print(fmt.Sprintf("group-title**: %s", m3uStream.GroupTitle))
if len(m3uStream.UUIDKey) > 0 {
log.Print(fmt.Sprintf("UUID key***: %s", m3uStream.UUIDKey))
log.Print(fmt.Sprintf("UUID value: %s", m3uStream.UUIDValue))
} else {
log.Print(fmt.Sprintf("UUID key: false"))
}
if len(m3uStream.UUIDKey) > 0 {
log.Print(fmt.Sprintf("UUID key***: %s", m3uStream.UUIDKey))
log.Print(fmt.Sprintf("UUID value: %s", m3uStream.UUIDValue))
} else {
log.Print(fmt.Sprintf("UUID key: false"))
}
}
}
}
}
log.Println(fmt.Sprintf("- - - - - (*: Required) | (**: Nice to have) | (***: Love it) - - - - -"))
}
log.Println(fmt.Sprintf("- - - - - (*: Required) | (**: Nice to have) | (***: Love it) - - - - -"))
}
return
return
}

View File

@@ -1,186 +1,186 @@
package m3u
import (
"errors"
"fmt"
"log"
"net/url"
"regexp"
"strings"
"errors"
"fmt"
"log"
"net/url"
"regexp"
"strings"
)
// MakeInterfaceFromM3U :
func MakeInterfaceFromM3U(byteStream []byte) (allChannels []interface{}, err error) {
func MakeInterfaceFromM3U(byteStream []byte) (allChannels []any, err error) {
var content = string(byteStream)
var channelName string
var uuids []string
var content = string(byteStream)
var channelName string
var uuids []string
var parseMetaData = func(channel string) (stream map[string]string) {
var parseMetaData = func(channel string) (stream map[string]string) {
stream = make(map[string]string)
var exceptForParameter = `[a-z-A-Z=]*(".*?")`
var exceptForChannelName = `,([^\n]*|,[^\r]*)`
stream = make(map[string]string)
var exceptForParameter = `[a-z-A-Z=]*(".*?")`
var exceptForChannelName = `,([^\n]*|,[^\r]*)`
var lines = strings.Split(strings.Replace(channel, "\r\n", "\n", -1), "\n")
var lines = strings.Split(strings.Replace(channel, "\r\n", "\n", -1), "\n")
// Zeilen mit # und leerer Zeilen entfernen
for i := len(lines) - 1; i >= 0; i-- {
// Zeilen mit # und leerer Zeilen entfernen
for i := len(lines) - 1; i >= 0; i-- {
if len(lines[i]) == 0 || lines[i][0:1] == "#" {
lines = append(lines[:i], lines[i+1:]...)
}
if len(lines[i]) == 0 || lines[i][0:1] == "#" {
lines = append(lines[:i], lines[i+1:]...)
}
}
}
if len(lines) >= 2 {
if len(lines) >= 2 {
for _, line := range lines {
for _, line := range lines {
_, err := url.ParseRequestURI(line)
_, err := url.ParseRequestURI(line)
switch err {
switch err {
case nil:
stream["url"] = strings.Trim(line, "\r\n")
case nil:
stream["url"] = strings.Trim(line, "\r\n")
default:
default:
var value string
// Alle Parameter parsen
var p = regexp.MustCompile(exceptForParameter)
var streamParameter = p.FindAllString(line, -1)
var value string
// Alle Parameter parsen
var p = regexp.MustCompile(exceptForParameter)
var streamParameter = p.FindAllString(line, -1)
for _, p := range streamParameter {
for _, p := range streamParameter {
line = strings.Replace(line, p, "", 1)
line = strings.Replace(line, p, "", 1)
p = strings.Replace(p, `"`, "", -1)
var parameter = strings.SplitN(p, "=", 2)
p = strings.Replace(p, `"`, "", -1)
var parameter = strings.SplitN(p, "=", 2)
if len(parameter) == 2 {
if len(parameter) == 2 {
// TVG Key als Kleinbuchstaben speichern
switch strings.Contains(parameter[0], "tvg") {
// TVG Key als Kleinbuchstaben speichern
switch strings.Contains(parameter[0], "tvg") {
case true:
stream[strings.ToLower(parameter[0])] = parameter[1]
case false:
stream[parameter[0]] = parameter[1]
case true:
stream[strings.ToLower(parameter[0])] = parameter[1]
case false:
stream[parameter[0]] = parameter[1]
}
}
// URL's nicht an die Filterfunktion übergeben
if !strings.Contains(parameter[1], "://") && len(parameter[1]) > 0 {
value = value + parameter[1] + " "
}
// URL's nicht an die Filterfunktion übergeben
if !strings.Contains(parameter[1], "://") && len(parameter[1]) > 0 {
value = value + parameter[1] + " "
}
}
}
}
}
// Kanalnamen parsen
n := regexp.MustCompile(exceptForChannelName)
var name = n.FindAllString(line, 1)
// Kanalnamen parsen
n := regexp.MustCompile(exceptForChannelName)
var name = n.FindAllString(line, 1)
if len(name) > 0 {
channelName = name[0]
channelName = strings.Replace(channelName, `,`, "", 1)
channelName = strings.TrimRight(channelName, "\r\n")
channelName = strings.TrimRight(channelName, " ")
}
if len(name) > 0 {
channelName = name[0]
channelName = strings.Replace(channelName, `,`, "", 1)
channelName = strings.TrimRight(channelName, "\r\n")
channelName = strings.TrimRight(channelName, " ")
}
if len(channelName) == 0 {
if len(channelName) == 0 {
if v, ok := stream["tvg-name"]; ok {
channelName = v
}
if v, ok := stream["tvg-name"]; ok {
channelName = v
}
}
}
channelName = strings.TrimRight(channelName, " ")
channelName = strings.TrimRight(channelName, " ")
// Kanäle ohne Namen werden augelassen
if len(channelName) == 0 {
return
}
// Kanäle ohne Namen werden augelassen
if len(channelName) == 0 {
return
}
stream["name"] = channelName
value = value + channelName
stream["name"] = channelName
value = value + channelName
stream["_values"] = value
stream["_values"] = value
}
}
}
}
}
}
// Nach eindeutiger ID im Stream suchen
for key, value := range stream {
// Nach eindeutiger ID im Stream suchen
for key, value := range stream {
if !strings.Contains(strings.ToLower(key), "tvg-id") {
if !strings.Contains(strings.ToLower(key), "tvg-id") {
if strings.Contains(strings.ToLower(key), "id") {
if strings.Contains(strings.ToLower(key), "id") {
if indexOfString(value, uuids) != -1 {
log.Println(fmt.Sprintf("Channel: %s - %s = %s ", stream["name"], key, value))
break
}
if indexOfString(value, uuids) != -1 {
log.Println(fmt.Sprintf("Channel: %s - %s = %s ", stream["name"], key, value))
break
}
uuids = append(uuids, value)
uuids = append(uuids, value)
stream["_uuid.key"] = key
stream["_uuid.value"] = value
break
stream["_uuid.key"] = key
stream["_uuid.value"] = value
break
}
}
}
}
}
}
return
}
return
}
//fmt.Println(content)
if strings.Contains(content, "#EXT-X-TARGETDURATION") || strings.Contains(content, "#EXT-X-MEDIA-SEQUENCE") {
err = errors.New("Invalid M3U file, an extended M3U file is required.")
return
}
//fmt.Println(content)
if strings.Contains(content, "#EXT-X-TARGETDURATION") || strings.Contains(content, "#EXT-X-MEDIA-SEQUENCE") {
err = errors.New("Invalid M3U file, an extended M3U file is required.")
return
}
if strings.Contains(content, "#EXTM3U") {
if strings.Contains(content, "#EXTM3U") {
var channels = strings.Split(content, "#EXTINF")
var channels = strings.Split(content, "#EXTINF")
channels = append(channels[:0], channels[1:]...)
channels = append(channels[:0], channels[1:]...)
for _, channel := range channels {
for _, channel := range channels {
var stream = parseMetaData(channel)
var stream = parseMetaData(channel)
if len(stream) > 0 && stream != nil {
allChannels = append(allChannels, stream)
}
if len(stream) > 0 && stream != nil {
allChannels = append(allChannels, stream)
}
}
}
} else {
} else {
err = errors.New("Invalid M3U file, an extended M3U file is required.")
err = errors.New("Invalid M3U file, an extended M3U file is required.")
}
}
return
return
}
func indexOfString(element string, data []string) int {
for k, v := range data {
if element == v {
return k
}
}
for k, v := range data {
if element == v {
return k
}
}
return -1
return -1
}

View File

@@ -22,7 +22,7 @@ type ClientInfo struct {
OS string `json:"os,required"`
URL string `json:"url,required"`
Response ServerResponse `json:"response,omitempty"`
Response ServerResponse `json:"response"`
}
// ServerResponse : Response from server after client request