Compare commits
34 Commits
2.1.0.0100
...
2.1.2.0120
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c1970a8393 | ||
|
|
493d612d52 | ||
|
|
4fc4330a94 | ||
|
|
a683533824 | ||
|
|
4b9f5826cf | ||
|
|
ca49d70910 | ||
|
|
1b425018d4 | ||
|
|
87b36c283b | ||
|
|
6da26ff4fb | ||
|
|
cd08985e79 | ||
|
|
dc04519229 | ||
|
|
c4ad96b715 | ||
|
|
45b5e602bb | ||
|
|
1cefbf022d | ||
|
|
d5328f6b1a | ||
|
|
91b80bc8bb | ||
|
|
aa763726a3 | ||
|
|
66c01dd1fb | ||
|
|
03e1abbe90 | ||
|
|
469581e280 | ||
|
|
019c98996a | ||
|
|
36db927794 | ||
|
|
f0a49788cc | ||
|
|
72767d7dbd | ||
|
|
8eecbf2b78 | ||
|
|
1a1e37fe15 | ||
|
|
08f6fb60e3 | ||
|
|
eded490ac7 | ||
|
|
ed770b9dbc | ||
|
|
6129b4911a | ||
|
|
477c5f30c1 | ||
|
|
65ddc6f301 | ||
|
|
3ef95c1950 | ||
|
|
3a3798cd2d |
@@ -31,7 +31,7 @@ Documentation for setup and configuration is [here](https://github.com/xteve-pro
|
|||||||
* Merge external M3U files
|
* Merge external M3U files
|
||||||
* Merge external XMLTV files
|
* Merge external XMLTV files
|
||||||
* Automatic M3U and XMLTV update
|
* Automatic M3U and XMLTV update
|
||||||
* M3U und XMLTV export
|
* M3U and XMLTV export
|
||||||
|
|
||||||
#### Channel management
|
#### Channel management
|
||||||
* Filtering streams
|
* Filtering streams
|
||||||
@@ -84,7 +84,7 @@ Including:
|
|||||||
---
|
---
|
||||||
|
|
||||||
### xTeVe Beta branch
|
### xTeVe Beta branch
|
||||||
New features and bug fixes are only available in beta brunch. Only after successful testing, they are merged into the master branch.
|
New features and bug fixes are only available in beta branch. Only after successful testing are they are merged into the master branch.
|
||||||
|
|
||||||
**It is not recommended to use the beta version in a production system.**
|
**It is not recommended to use the beta version in a production system.**
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,29 @@
|
|||||||
|
#### 2.1.1.0116-beta
|
||||||
|
If no user agent is specified, the default FFmpeg or VLC user agent is used.
|
||||||
|
|
||||||
|
#### 2.1.1.0115-beta
|
||||||
|
```diff
|
||||||
|
+ GZIP compression for xteve.xml file. (http://xteve.ip:34400/xmltv/xteve.xml.gz)
|
||||||
|
- Removed protocol setting for reverse proxy. HTTPS can also be configured in the proxy, where it makes more sense.
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2.1.0.0106-beta
|
||||||
|
```diff
|
||||||
|
+ User-Agent is now also used by VLC and FFmpeg.
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2.1.0.0105-beta
|
||||||
|
```diff
|
||||||
|
+ Fixed wrong buffer value in log
|
||||||
|
+ New setting: URL protocol for M3U and XML file
|
||||||
|
+ Add xml tag premiere to xteve.xml
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2.1.0.0101-beta
|
||||||
|
```diff
|
||||||
|
+ Reverse proxy fix
|
||||||
|
```
|
||||||
|
|
||||||
#### 2.0.3.0042-beta
|
#### 2.0.3.0042-beta
|
||||||
**Version 2.0.3.0042 changes the settings.json.**
|
**Version 2.0.3.0042 changes the settings.json.**
|
||||||
Settings from the current beta can not be used for the current master version 2.0.3
|
Settings from the current beta can not be used for the current master version 2.0.3
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
<div id="content">
|
<div id="content">
|
||||||
|
|
||||||
<form id="authentication" action="/web/" method="post">
|
<form id="authentication" action="" method="post">
|
||||||
|
|
||||||
<h5>{{.account.username.title}}:</h5>
|
<h5>{{.account.username.title}}:</h5>
|
||||||
<input id="username" type="text" name="username" placeholder="Username" value="">
|
<input id="username" type="text" name="username" placeholder="Username" value="">
|
||||||
|
|||||||
@@ -1253,6 +1253,12 @@ function openPopUp(dataType, element) {
|
|||||||
}
|
}
|
||||||
content.appendRow("{{.mapping.channelName.title}}", input);
|
content.appendRow("{{.mapping.channelName.title}}", input);
|
||||||
content.description(data["name"]);
|
content.description(data["name"]);
|
||||||
|
// Beschreibung
|
||||||
|
var dbKey = "x-description";
|
||||||
|
var input = content.createInput("text", dbKey, data[dbKey]);
|
||||||
|
input.setAttribute("placeholder", "{{.mapping.description.placeholder}}");
|
||||||
|
input.setAttribute("onchange", "javascript: this.className = 'changed'");
|
||||||
|
content.appendRow("{{.mapping.description.title}}", input);
|
||||||
// Aktualisierung des Kanalnamens
|
// Aktualisierung des Kanalnamens
|
||||||
if (data.hasOwnProperty("_uuid.key")) {
|
if (data.hasOwnProperty("_uuid.key")) {
|
||||||
if (data["_uuid.key"] != "") {
|
if (data["_uuid.key"] != "") {
|
||||||
|
|||||||
@@ -190,6 +190,11 @@
|
|||||||
"placeholder": "",
|
"placeholder": "",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
"description": {
|
||||||
|
"title": "Channel Description",
|
||||||
|
"placeholder": "Used by the Dummy as an XML description",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
"updateChannelName": {
|
"updateChannelName": {
|
||||||
"title": "Update Channel Name",
|
"title": "Update Channel Name",
|
||||||
"placeholder": "",
|
"placeholder": "",
|
||||||
@@ -358,7 +363,7 @@
|
|||||||
},
|
},
|
||||||
"userAgent": {
|
"userAgent": {
|
||||||
"title": "User Agent",
|
"title": "User Agent",
|
||||||
"description": "User Agent for HTTP requests. Only used if xTeVe is selected as the buffer.",
|
"description": "User Agent for HTTP requests. For every HTTP connection, this value is used for the user agent. Should only be changed if xTeVe is blocked.",
|
||||||
"placeholder": "xTeVe"
|
"placeholder": "xTeVe"
|
||||||
},
|
},
|
||||||
"backupPath": {
|
"backupPath": {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
<div id="content">
|
<div id="content">
|
||||||
|
|
||||||
<form id="authentication" action="/web/" method="post">
|
<form id="authentication" action="" method="post">
|
||||||
|
|
||||||
<h5>{{.login.username.title}}:</h5>
|
<h5>{{.login.username.title}}:</h5>
|
||||||
<input id="username" type="text" name="username" placeholder="Username" value="">
|
<input id="username" type="text" name="username" placeholder="Username" value="">
|
||||||
|
|||||||
@@ -261,7 +261,9 @@ func bufferingStream(playlistID, streamingURL, channelName string, w http.Respon
|
|||||||
var oldSegments []string
|
var oldSegments []string
|
||||||
|
|
||||||
for { // Loop 2: Temporäre Datein sind vorhanden, Daten können zum Client gesendet werden
|
for { // Loop 2: Temporäre Datein sind vorhanden, Daten können zum Client gesendet werden
|
||||||
|
|
||||||
// HTTP Clientverbindung überwachen
|
// HTTP Clientverbindung überwachen
|
||||||
|
|
||||||
cn, ok := w.(http.CloseNotifier)
|
cn, ok := w.(http.CloseNotifier)
|
||||||
if ok {
|
if ok {
|
||||||
|
|
||||||
@@ -449,6 +451,9 @@ func getTmpFiles(stream *ThisStream) (tmpFiles []string) {
|
|||||||
|
|
||||||
func killClientConnection(streamID int, playlistID string, force bool) {
|
func killClientConnection(streamID int, playlistID string, force bool) {
|
||||||
|
|
||||||
|
Lock.Lock()
|
||||||
|
defer Lock.Unlock()
|
||||||
|
|
||||||
if p, ok := BufferInformation.Load(playlistID); ok {
|
if p, ok := BufferInformation.Load(playlistID); ok {
|
||||||
|
|
||||||
var playlist = p.(Playlist)
|
var playlist = p.(Playlist)
|
||||||
@@ -493,6 +498,8 @@ func killClientConnection(streamID int, playlistID string, force bool) {
|
|||||||
func clientConnection(stream ThisStream) (status bool) {
|
func clientConnection(stream ThisStream) (status bool) {
|
||||||
|
|
||||||
status = true
|
status = true
|
||||||
|
Lock.Lock()
|
||||||
|
defer Lock.Unlock()
|
||||||
|
|
||||||
if _, ok := BufferClients.Load(stream.PlaylistID + stream.MD5); !ok {
|
if _, ok := BufferClients.Load(stream.PlaylistID + stream.MD5); !ok {
|
||||||
|
|
||||||
@@ -901,6 +908,8 @@ func connectToStreamingServer(streamID int, playlistID string) {
|
|||||||
// Buffer auf die Festplatte speichern
|
// Buffer auf die Festplatte speichern
|
||||||
if fileSize >= tmpFileSize/2 || n == 0 {
|
if fileSize >= tmpFileSize/2 || n == 0 {
|
||||||
|
|
||||||
|
Lock.Lock()
|
||||||
|
|
||||||
bandwidth.Stop = time.Now()
|
bandwidth.Stop = time.Now()
|
||||||
bandwidth.Size += fileSize
|
bandwidth.Size += fileSize
|
||||||
|
|
||||||
@@ -919,6 +928,7 @@ func connectToStreamingServer(streamID int, playlistID string) {
|
|||||||
stream.Status = true
|
stream.Status = true
|
||||||
playlist.Streams[streamID] = stream
|
playlist.Streams[streamID] = stream
|
||||||
BufferInformation.Store(playlistID, playlist)
|
BufferInformation.Store(playlistID, playlist)
|
||||||
|
Lock.Unlock()
|
||||||
|
|
||||||
tmpSegment++
|
tmpSegment++
|
||||||
|
|
||||||
@@ -1408,8 +1418,42 @@ func thirdPartyBuffer(streamID int, playlistID string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var args = strings.Replace(options, "[URL]", url, -1)
|
//args = strings.Replace(args, "[USER-AGENT]", Settings.UserAgent, -1)
|
||||||
var cmd = exec.Command(path, strings.Split(args, " ")...)
|
|
||||||
|
// User-Agent setzen
|
||||||
|
var args []string
|
||||||
|
|
||||||
|
for i, a := range strings.Split(options, " ") {
|
||||||
|
|
||||||
|
switch bufferType {
|
||||||
|
case "FFMPEG":
|
||||||
|
a = strings.Replace(a, "[URL]", url, -1)
|
||||||
|
if i == 0 {
|
||||||
|
if len(Settings.UserAgent) != 0 {
|
||||||
|
args = []string{"-user_agent", Settings.UserAgent}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
args = append(args, a)
|
||||||
|
|
||||||
|
case "VLC":
|
||||||
|
if a == "[URL]" {
|
||||||
|
a = strings.Replace(a, "[URL]", url, -1)
|
||||||
|
args = append(args, a)
|
||||||
|
|
||||||
|
if len(Settings.UserAgent) != 0 {
|
||||||
|
args = append(args, fmt.Sprintf(":http-user-agent=%s", Settings.UserAgent))
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
args = append(args, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var cmd = exec.Command(path, args...)
|
||||||
|
|
||||||
debug = fmt.Sprintf("%s:%s %s", bufferType, path, args)
|
debug = fmt.Sprintf("%s:%s %s", bufferType, path, args)
|
||||||
showDebug(debug, 1)
|
showDebug(debug, 1)
|
||||||
@@ -1551,9 +1595,11 @@ func thirdPartyBuffer(streamID int, playlistID string) {
|
|||||||
tmpSegment++
|
tmpSegment++
|
||||||
|
|
||||||
if stream.Status == false {
|
if stream.Status == false {
|
||||||
|
Lock.Lock()
|
||||||
stream.Status = true
|
stream.Status = true
|
||||||
playlist.Streams[streamID] = stream
|
playlist.Streams[streamID] = stream
|
||||||
BufferInformation.Store(playlistID, playlist)
|
BufferInformation.Store(playlistID, playlist)
|
||||||
|
Lock.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpFile = fmt.Sprintf("%s%d.ts", tmpFolder, tmpSegment)
|
tmpFile = fmt.Sprintf("%s%d.ts", tmpFolder, tmpSegment)
|
||||||
|
|||||||
@@ -146,3 +146,20 @@ func extractGZIP(gzipBody []byte, fileSource string) (body []byte, err error) {
|
|||||||
body = resB.Bytes()
|
body = resB.Bytes()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func compressGZIP(data *[]byte, file string) (err error) {
|
||||||
|
|
||||||
|
if len(file) != 0 {
|
||||||
|
|
||||||
|
f, err := os.Create(file)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
w := gzip.NewWriter(f)
|
||||||
|
w.Write(*data)
|
||||||
|
w.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|||||||
@@ -29,6 +29,9 @@ var BufferInformation sync.Map
|
|||||||
// BufferClients : Anzahl der Clients die einen Stream über den Buffer abspielen
|
// BufferClients : Anzahl der Clients die einen Stream über den Buffer abspielen
|
||||||
var BufferClients sync.Map
|
var BufferClients sync.Map
|
||||||
|
|
||||||
|
// Lock : Lock Map
|
||||||
|
var Lock = sync.RWMutex{}
|
||||||
|
|
||||||
// Init : Systeminitialisierung
|
// Init : Systeminitialisierung
|
||||||
func Init() (err error) {
|
func Init() (err error) {
|
||||||
|
|
||||||
@@ -95,6 +98,8 @@ func Init() (err error) {
|
|||||||
System.File.XML = getPlatformFile(fmt.Sprintf("%s%s.xml", System.Folder.Data, System.AppName))
|
System.File.XML = getPlatformFile(fmt.Sprintf("%s%s.xml", System.Folder.Data, System.AppName))
|
||||||
System.File.M3U = getPlatformFile(fmt.Sprintf("%s%s.m3u", System.Folder.Data, System.AppName))
|
System.File.M3U = getPlatformFile(fmt.Sprintf("%s%s.m3u", System.Folder.Data, System.AppName))
|
||||||
|
|
||||||
|
System.Compressed.GZxml = getPlatformFile(fmt.Sprintf("%s%s.xml.gz", System.Folder.Data, System.AppName))
|
||||||
|
|
||||||
err = activatedSystemAuthentication()
|
err = activatedSystemAuthentication()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
|||||||
12
src/data.go
12
src/data.go
@@ -56,6 +56,10 @@ func updateServerSettings(request RequestStruct) (settings SettingsStrcut, err e
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(newUpdateTimes) == 0 {
|
||||||
|
newUpdateTimes = append(newUpdateTimes, "0000")
|
||||||
|
}
|
||||||
|
|
||||||
value = newUpdateTimes
|
value = newUpdateTimes
|
||||||
|
|
||||||
case "cache.images":
|
case "cache.images":
|
||||||
@@ -107,6 +111,9 @@ func updateServerSettings(request RequestStruct) (settings SettingsStrcut, err e
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case "scheme.m3u", "scheme.xml":
|
||||||
|
createXEPGFiles = true
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
oldSettings[key] = value
|
oldSettings[key] = value
|
||||||
@@ -505,7 +512,7 @@ func saveXEpgMapping(request RequestStruct) (err error) {
|
|||||||
|
|
||||||
System.ScanInProgress = 1
|
System.ScanInProgress = 1
|
||||||
cleanupXEPG()
|
cleanupXEPG()
|
||||||
//buildXEPG(true)
|
buildXEPG(true)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
|
||||||
@@ -540,8 +547,7 @@ func saveXEpgMapping(request RequestStruct) (err error) {
|
|||||||
System.ScanInProgress = 1
|
System.ScanInProgress = 1
|
||||||
|
|
||||||
cleanupXEPG()
|
cleanupXEPG()
|
||||||
//buildXEPG(false)
|
buildXEPG(false)
|
||||||
|
|
||||||
createXMLTVFile()
|
createXMLTVFile()
|
||||||
createM3UFile()
|
createM3UFile()
|
||||||
showInfo("XEPG:" + fmt.Sprintf("Ready to use"))
|
showInfo("XEPG:" + fmt.Sprintf("Ready to use"))
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ func getCacheImageURL(imageURL string) (cacheImageURL string) {
|
|||||||
|
|
||||||
if indexOfString(urlMD5+fileExtension, Data.Cache.ImagesCache) != -1 {
|
if indexOfString(urlMD5+fileExtension, Data.Cache.ImagesCache) != -1 {
|
||||||
|
|
||||||
cacheImageURL = fmt.Sprintf("%s://%s/images/%s%s", System.ServerProtocol.WEB, System.Domain, urlMD5, fileExtension)
|
cacheImageURL = fmt.Sprintf("%s://%s/images/%s%s", System.ServerProtocol.XML, System.Domain, urlMD5, fileExtension)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@@ -163,7 +163,7 @@ func uploadLogo(input, filename string) (logoURL string, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
logoURL = fmt.Sprintf("%s://%s/data_images/%s", System.ServerProtocol.WEB, System.Domain, filename)
|
logoURL = fmt.Sprintf("%s://%s/data_images/%s", System.ServerProtocol.XML, System.Domain, filename)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,10 @@ type SystemStruct struct {
|
|||||||
XML string
|
XML string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Compressed struct {
|
||||||
|
GZxml string
|
||||||
|
}
|
||||||
|
|
||||||
Flag struct {
|
Flag struct {
|
||||||
Branch string
|
Branch string
|
||||||
Debug int
|
Debug int
|
||||||
@@ -187,6 +191,7 @@ type XEPGChannelStruct struct {
|
|||||||
XName string `json:"x-name,required"`
|
XName string `json:"x-name,required"`
|
||||||
XUpdateChannelIcon bool `json:"x-update-channel-icon,required"`
|
XUpdateChannelIcon bool `json:"x-update-channel-icon,required"`
|
||||||
XUpdateChannelName bool `json:"x-update-channel-name,required"`
|
XUpdateChannelName bool `json:"x-update-channel-name,required"`
|
||||||
|
XDescription string `json:"x-description,required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// M3UChannelStructXEPG : M3U Struktur für XEPG
|
// M3UChannelStructXEPG : M3U Struktur für XEPG
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ type RequestStruct struct {
|
|||||||
UserAgent *string `json:"user.agent,omitempty"`
|
UserAgent *string `json:"user.agent,omitempty"`
|
||||||
XepgReplaceMissingImages *bool `json:"xepg.replace.missing.images,omitempty"`
|
XepgReplaceMissingImages *bool `json:"xepg.replace.missing.images,omitempty"`
|
||||||
XteveAutoUpdate *bool `json:"xteveAutoUpdate,omitempty"`
|
XteveAutoUpdate *bool `json:"xteveAutoUpdate,omitempty"`
|
||||||
|
SchemeM3U *string `json:"scheme.m3u,omitempty"`
|
||||||
|
SchemeXML *string `json:"scheme.xml,omitempty"`
|
||||||
} `json:"settings,omitempty"`
|
} `json:"settings,omitempty"`
|
||||||
|
|
||||||
// Upload Logo
|
// Upload Logo
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ type Program struct {
|
|||||||
PreviouslyShown *PreviouslyShown `xml:"previously-shown"`
|
PreviouslyShown *PreviouslyShown `xml:"previously-shown"`
|
||||||
New *New `xml:"new"`
|
New *New `xml:"new"`
|
||||||
Live *Live `xml:"live"`
|
Live *Live `xml:"live"`
|
||||||
|
Premiere *Live `xml:"premiere"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Title : Programmtitel
|
// Title : Programmtitel
|
||||||
|
|||||||
63
src/webUI.go
63
src/webUI.go
File diff suppressed because one or more lines are too long
@@ -132,7 +132,7 @@ func Stream(w http.ResponseWriter, r *http.Request) {
|
|||||||
switch Settings.Buffer {
|
switch Settings.Buffer {
|
||||||
|
|
||||||
case "-":
|
case "-":
|
||||||
showInfo(fmt.Sprintf("Buffer:false", Settings.Buffer))
|
showInfo(fmt.Sprintf("Buffer:false [%s]", Settings.Buffer))
|
||||||
|
|
||||||
case "xteve":
|
case "xteve":
|
||||||
if strings.Index(streamInfo.URL, "rtsp://") != -1 || strings.Index(streamInfo.URL, "rtp://") != -1 {
|
if strings.Index(streamInfo.URL, "rtsp://") != -1 || strings.Index(streamInfo.URL, "rtp://") != -1 {
|
||||||
@@ -206,7 +206,7 @@ func Auto(w http.ResponseWriter, r *http.Request) {
|
|||||||
// xTeVe : Web Server /xmltv/ und /m3u/
|
// xTeVe : Web Server /xmltv/ und /m3u/
|
||||||
func xTeVe(w http.ResponseWriter, r *http.Request) {
|
func xTeVe(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
var requestType, groupTitle, file, content string
|
var requestType, groupTitle, file, content, contentType string
|
||||||
var err error
|
var err error
|
||||||
var path = strings.TrimPrefix(r.URL.Path, "/")
|
var path = strings.TrimPrefix(r.URL.Path, "/")
|
||||||
var groups = []string{}
|
var groups = []string{}
|
||||||
@@ -216,7 +216,6 @@ func xTeVe(w http.ResponseWriter, r *http.Request) {
|
|||||||
// XMLTV Datei
|
// XMLTV Datei
|
||||||
if strings.Contains(path, "xmltv/") {
|
if strings.Contains(path, "xmltv/") {
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/xml")
|
|
||||||
requestType = "xml"
|
requestType = "xml"
|
||||||
|
|
||||||
file = System.Folder.Data + getFilenameFromPath(path)
|
file = System.Folder.Data + getFilenameFromPath(path)
|
||||||
@@ -260,6 +259,13 @@ func xTeVe(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
contentType = http.DetectContentType([]byte(content))
|
||||||
|
if strings.Contains(strings.ToLower(contentType), "xml") {
|
||||||
|
contentType = "application/xml; charset=utf-8"
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", contentType)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
w.Write([]byte(content))
|
w.Write([]byte(content))
|
||||||
}
|
}
|
||||||
@@ -316,10 +322,12 @@ func WS(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
var newToken string
|
var newToken string
|
||||||
|
|
||||||
|
/*
|
||||||
if r.Header.Get("Origin") != "http://"+r.Host {
|
if r.Header.Get("Origin") != "http://"+r.Host {
|
||||||
httpStatusError(w, r, 403)
|
httpStatusError(w, r, 403)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
conn, err := websocket.Upgrade(w, r, w.Header(), 1024, 1024)
|
conn, err := websocket.Upgrade(w, r, w.Header(), 1024, 1024)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -583,6 +591,8 @@ func Web(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
var language LanguageUI
|
var language LanguageUI
|
||||||
|
|
||||||
|
setGlobalDomain(r.Host)
|
||||||
|
|
||||||
if System.Dev == true {
|
if System.Dev == true {
|
||||||
|
|
||||||
lang, err = loadJSONFileToMap(fmt.Sprintf("html/lang/%s.json", Settings.Language))
|
lang, err = loadJSONFileToMap(fmt.Sprintf("html/lang/%s.json", Settings.Language))
|
||||||
|
|||||||
13
src/xepg.go
13
src/xepg.go
@@ -641,9 +641,10 @@ func createXMLTVFile() (err error) {
|
|||||||
var xmlOutput = []byte(xml.Header + string(content))
|
var xmlOutput = []byte(xml.Header + string(content))
|
||||||
writeByteToFile(System.File.XML, xmlOutput)
|
writeByteToFile(System.File.XML, xmlOutput)
|
||||||
|
|
||||||
xepgXML = XMLTV{}
|
showInfo("XEPG:" + fmt.Sprintf("Compress XMLTV file (%s)", System.Compressed.GZxml))
|
||||||
|
err = compressGZIP(&xmlOutput, System.Compressed.GZxml)
|
||||||
|
|
||||||
//saveMapToJSONFile(System.File.Images, Data.Cache.ImageCache)
|
xepgXML = XMLTV{}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -717,6 +718,9 @@ func getProgramData(xepgChannel XEPGChannelStruct) (xepgXML XMLTV, err error) {
|
|||||||
// Live
|
// Live
|
||||||
program.Live = xmltvProgram.Live
|
program.Live = xmltvProgram.Live
|
||||||
|
|
||||||
|
// Premiere
|
||||||
|
program.Premiere = xmltvProgram.Premiere
|
||||||
|
|
||||||
xepgXML.Program = append(xepgXML.Program, program)
|
xepgXML.Program = append(xepgXML.Program, program)
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -759,7 +763,12 @@ func createDummyProgram(xepgChannel XEPGChannelStruct) (dummyXMLTV XMLTV) {
|
|||||||
epg.Start = epgStartTime.Format("20060102150405") + offset
|
epg.Start = epgStartTime.Format("20060102150405") + offset
|
||||||
epg.Stop = epgStopTime.Format("20060102150405") + offset
|
epg.Stop = epgStopTime.Format("20060102150405") + offset
|
||||||
epg.Title = append(epg.Title, &Title{Value: xepgChannel.XName + " (" + epgStartTime.Weekday().String()[0:2] + ". " + epgStartTime.Format("15:04") + " - " + epgStopTime.Format("15:04") + ")", Lang: "en"})
|
epg.Title = append(epg.Title, &Title{Value: xepgChannel.XName + " (" + epgStartTime.Weekday().String()[0:2] + ". " + epgStartTime.Format("15:04") + " - " + epgStopTime.Format("15:04") + ")", Lang: "en"})
|
||||||
|
|
||||||
|
if len(xepgChannel.XDescription) == 0 {
|
||||||
epg.Desc = append(epg.Desc, &Desc{Value: "xTeVe: (" + strconv.Itoa(dummyLength) + " Minutes) " + epgStartTime.Weekday().String() + " " + epgStartTime.Format("15:04") + " - " + epgStopTime.Format("15:04"), Lang: "en"})
|
epg.Desc = append(epg.Desc, &Desc{Value: "xTeVe: (" + strconv.Itoa(dummyLength) + " Minutes) " + epgStartTime.Weekday().String() + " " + epgStartTime.Format("15:04") + " - " + epgStopTime.Format("15:04"), Lang: "en"})
|
||||||
|
} else {
|
||||||
|
epg.Desc = append(epg.Desc, &Desc{Value: xepgChannel.XDescription, Lang: "en"})
|
||||||
|
}
|
||||||
|
|
||||||
if Settings.XepgReplaceMissingImages == true {
|
if Settings.XepgReplaceMissingImages == true {
|
||||||
poster.Src = getCacheImageURL(xepgChannel.TvgLogo)
|
poster.Src = getCacheImageURL(xepgChannel.TvgLogo)
|
||||||
|
|||||||
@@ -21,8 +21,7 @@ menuItems.push(new MainMenuItem("logout", "{{.mainMenu.item.logout}}", "logout.p
|
|||||||
|
|
||||||
// Kategorien für die Einstellungen
|
// Kategorien für die Einstellungen
|
||||||
var settingsCategory = new Array()
|
var settingsCategory = new Array()
|
||||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.general}}", "xteveAutoUpdate,tuner,epgSource,api"))
|
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.general}}", "xteveAutoUpdate,tuner,epgSource,api"));settingsCategory.push(new SettingsCategoryItem("{{.settings.category.files}}", "update,files.update,temp.path,cache.images,xepg.replace.missing.images"))
|
||||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.files}}", "update,files.update,temp.path,cache.images,xepg.replace.missing.images"))
|
|
||||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.streaming}}", "buffer,buffer.size.kb,buffer.timeout,user.agent,ffmpeg.path,ffmpeg.options,vlc.path,vlc.options"))
|
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.streaming}}", "buffer,buffer.size.kb,buffer.timeout,user.agent,ffmpeg.path,ffmpeg.options,vlc.path,vlc.options"))
|
||||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.backup}}", "backup.path,backup.keep"))
|
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.backup}}", "backup.path,backup.keep"))
|
||||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.authentication}}", "authentication.web,authentication.pms,authentication.m3u,authentication.xml,authentication.api"))
|
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.authentication}}", "authentication.web,authentication.pms,authentication.m3u,authentication.xml,authentication.api"))
|
||||||
|
|||||||
@@ -1532,6 +1532,13 @@ function openPopUp(dataType, element) {
|
|||||||
|
|
||||||
content.description(data["name"])
|
content.description(data["name"])
|
||||||
|
|
||||||
|
// Beschreibung
|
||||||
|
var dbKey:string = "x-description"
|
||||||
|
var input = content.createInput("text", dbKey, data[dbKey])
|
||||||
|
input.setAttribute("placeholder", "{{.mapping.description.placeholder}}")
|
||||||
|
input.setAttribute("onchange", "javascript: this.className = 'changed'")
|
||||||
|
content.appendRow("{{.mapping.description.title}}", input)
|
||||||
|
|
||||||
// Aktualisierung des Kanalnamens
|
// Aktualisierung des Kanalnamens
|
||||||
if (data.hasOwnProperty("_uuid.key")) {
|
if (data.hasOwnProperty("_uuid.key")) {
|
||||||
if (data["_uuid.key"] != "") {
|
if (data["_uuid.key"] != "") {
|
||||||
|
|||||||
2
xteve.go
2
xteve.go
@@ -39,7 +39,7 @@ var GitHub = GitHubStruct{Branch: "master", User: "xteve-project", Repo: "xTeVe-
|
|||||||
const Name = "xTeVe"
|
const Name = "xTeVe"
|
||||||
|
|
||||||
// Version : Version, die Build Nummer wird in der main func geparst.
|
// Version : Version, die Build Nummer wird in der main func geparst.
|
||||||
const Version = "2.1.0.0100"
|
const Version = "2.1.2.0120"
|
||||||
|
|
||||||
// DBVersion : Datanbank Version
|
// DBVersion : Datanbank Version
|
||||||
const DBVersion = "2.1.0"
|
const DBVersion = "2.1.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user