From 284f78de49e18de6f46f7d0fda03315f31088fc4 Mon Sep 17 00:00:00 2001 From: lukas Date: Tue, 21 Sep 2021 17:45:24 +0200 Subject: [PATCH 1/7] uploadable file --- .eslintrc.js | 1 + apiGo/api/API.go | 1 + apiGo/api/FileUpload.go | 60 ++++++++++++++++++++++++ src/pages/SettingsPage/MovieSettings.tsx | 47 ++++++++++++++++++- 4 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 apiGo/api/FileUpload.go diff --git a/.eslintrc.js b/.eslintrc.js index 49f4aa6..81e444c 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -45,6 +45,7 @@ module.exports = { // Map from global var to bool specifying if it can be redefined globals: { + File: true, jest: true, __DEV__: true, __dirname: false, diff --git a/apiGo/api/API.go b/apiGo/api/API.go index 020a7f1..94cf059 100644 --- a/apiGo/api/API.go +++ b/apiGo/api/API.go @@ -6,4 +6,5 @@ func AddHandlers() { addTagHandlers() addActorsHandlers() addTvshowHandlers() + addUploadHandler() } diff --git a/apiGo/api/FileUpload.go b/apiGo/api/FileUpload.go new file mode 100644 index 0000000..c71b043 --- /dev/null +++ b/apiGo/api/FileUpload.go @@ -0,0 +1,60 @@ +package api + +import ( + "fmt" + "io" + "openmediacenter/apiGo/api/api" + "os" +) + +func addUploadHandler() { + api.AddHandler("fileupload", api.VideoNode, api.PermUser, func(ctx api.Context) { + fmt.Println("we are in file upload handler") + + req := ctx.GetRequest() + + mr, err := req.MultipartReader() + if err != nil { + return + } + length := req.ContentLength + fmt.Println(length) + for { + part, err := mr.NextPart() + if err == io.EOF { + fmt.Println("part is eof") + break + } + + fmt.Println(part.FormName()) + + var read int64 + var p float32 + dst, err := os.OpenFile(part.FileName(), os.O_WRONLY|os.O_CREATE, 0644) + if err != nil { + return + } + + // so now loop through every appended file and upload + buffer := make([]byte, 100000) + for { + cBytes, err := part.Read(buffer) + if cBytes > 0 { + read = read + int64(cBytes) + //fmt.Printf("read: %v \n",read ) + p = float32(read) / float32(length) * 100 + fmt.Printf("progress: %v \n", p) + dst.Write(buffer[0:cBytes]) + } + + if err == io.EOF { + fmt.Println(cBytes) + fmt.Println("eof this file") + break + } + } + } + + ctx.Text("finished") + }) +} diff --git a/src/pages/SettingsPage/MovieSettings.tsx b/src/pages/SettingsPage/MovieSettings.tsx index 451a2d1..47a218f 100644 --- a/src/pages/SettingsPage/MovieSettings.tsx +++ b/src/pages/SettingsPage/MovieSettings.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, {BaseSyntheticEvent, useState} from 'react'; import style from './MovieSettings.module.css'; import {APINode, callAPI} from '../../utils/Api'; import {GeneralSuccess} from '../../types/GeneralTypes'; @@ -123,6 +123,7 @@ class MovieSettings extends React.Component { ))} + ); } @@ -162,3 +163,47 @@ class MovieSettings extends React.Component { } export default MovieSettings; + +const FileHandler = (): JSX.Element => { + const [file, setfile] = useState(null); + + const uploadFile = (): void => { + let xhr = new XMLHttpRequest(); // create XMLHttpRequest + let data = new FormData(); // create formData object + if (!file) { + return; + } + data.append('file', file); + + xhr.onload = function (): void { + console.log(this.responseText); // whatever the server returns + }; + + xhr.upload.onprogress = function (e): void { + console.log(e.loaded / e.total); + }; + + xhr.open('post', '/api/video/fileupload'); // open connection + xhr.setRequestHeader('Accept', 'multipart/form-data'); + + xhr.send(data); // send data + }; + + return ( +
+ { + console.log(e); + if (e.target) { + console.log(e.target.files[0]); + setfile(e.target.files[0]); + // setfile(e.target.files[0]); + } + }} + type='file' + name='Select file to upload' + /> + +
+ ); +}; From d3bd810a1a174c860ee4a7656f33c7095b0cd252 Mon Sep 17 00:00:00 2001 From: lukas Date: Tue, 21 Sep 2021 23:39:21 +0200 Subject: [PATCH 2/7] nice progressbar and correct authentication header --- apiGo/api/FileUpload.go | 5 ++++- apiGo/api/api/ApiBase.go | 2 +- apiGo/api/api/Auth.go | 16 +++++++++++----- apiGo/api/api/Context.go | 7 ++++++- src/pages/SettingsPage/MovieSettings.tsx | 11 +++++++++++ 5 files changed, 33 insertions(+), 8 deletions(-) diff --git a/apiGo/api/FileUpload.go b/apiGo/api/FileUpload.go index c71b043..c140642 100644 --- a/apiGo/api/FileUpload.go +++ b/apiGo/api/FileUpload.go @@ -10,6 +10,7 @@ import ( func addUploadHandler() { api.AddHandler("fileupload", api.VideoNode, api.PermUser, func(ctx api.Context) { fmt.Println("we are in file upload handler") + fmt.Printf("permission: %s\n", ctx.PermID().String()) req := ctx.GetRequest() @@ -30,6 +31,7 @@ func addUploadHandler() { var read int64 var p float32 + // todo check where we want to place this file dst, err := os.OpenFile(part.FileName(), os.O_WRONLY|os.O_CREATE, 0644) if err != nil { return @@ -41,7 +43,6 @@ func addUploadHandler() { cBytes, err := part.Read(buffer) if cBytes > 0 { read = read + int64(cBytes) - //fmt.Printf("read: %v \n",read ) p = float32(read) / float32(length) * 100 fmt.Printf("progress: %v \n", p) dst.Write(buffer[0:cBytes]) @@ -53,6 +54,8 @@ func addUploadHandler() { break } } + + _ = dst.Close() } ctx.Text("finished") diff --git a/apiGo/api/api/ApiBase.go b/apiGo/api/api/ApiBase.go index 375a4f0..a5ee382 100644 --- a/apiGo/api/api/ApiBase.go +++ b/apiGo/api/api/ApiBase.go @@ -15,7 +15,7 @@ const ( LoginNode = "login" ) -func AddHandler(action string, apiNode string, perm uint8, handler func(ctx Context)) { +func AddHandler(action string, apiNode string, perm Perm, handler func(ctx Context)) { http.Handle(fmt.Sprintf("/api/%s/%s", apiNode, action), http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { srvPwd := settings.GetPassword() if srvPwd == nil { diff --git a/apiGo/api/api/Auth.go b/apiGo/api/api/Auth.go index 9e50ddd..982fde0 100644 --- a/apiGo/api/api/Auth.go +++ b/apiGo/api/api/Auth.go @@ -13,12 +13,18 @@ import ( var srv *server.Server +type Perm uint8 + const ( - PermAdmin uint8 = iota - PermUser uint8 = iota - PermUnauthorized uint8 = iota + PermAdmin Perm = iota + PermUser + PermUnauthorized ) +func (p Perm) String() string { + return [...]string{"PermAdmin", "PermUser", "PermUnauthorized"}[p] +} + const SignKey = "89013f1753a6890c6090b09e3c23ff43" const TokenExpireHours = 24 @@ -27,7 +33,7 @@ type Token struct { ExpiresAt int64 } -func TokenValid(token string) (int, uint8) { +func TokenValid(token string) (int, Perm) { t, err := jwt.ParseWithClaims(token, &jwt.StandardClaims{}, func(token *jwt.Token) (interface{}, error) { return []byte(SignKey), nil }) @@ -42,7 +48,7 @@ func TokenValid(token string) (int, uint8) { if err != nil { return -1, PermUnauthorized } - return id, uint8(permid) + return id, Perm(permid) } func InitOAuth() { diff --git a/apiGo/api/api/Context.go b/apiGo/api/api/Context.go index edde0ef..3904fe5 100644 --- a/apiGo/api/api/Context.go +++ b/apiGo/api/api/Context.go @@ -13,6 +13,7 @@ type Context interface { GetRequest() *http.Request GetWriter() http.ResponseWriter UserID() int + PermID() Perm } type apicontext struct { @@ -20,7 +21,7 @@ type apicontext struct { request *http.Request responseWritten bool userid int - permid uint8 + permid Perm } func (r *apicontext) GetRequest() *http.Request { @@ -58,3 +59,7 @@ func (r *apicontext) Error(msg string) { func (r *apicontext) Errorf(msg string, args ...interface{}) { r.Error(fmt.Sprintf(msg, &args)) } + +func (r *apicontext) PermID() Perm { + return r.permid +} diff --git a/src/pages/SettingsPage/MovieSettings.tsx b/src/pages/SettingsPage/MovieSettings.tsx index 47a218f..a4aa820 100644 --- a/src/pages/SettingsPage/MovieSettings.tsx +++ b/src/pages/SettingsPage/MovieSettings.tsx @@ -2,6 +2,7 @@ import React, {BaseSyntheticEvent, useState} from 'react'; import style from './MovieSettings.module.css'; import {APINode, callAPI} from '../../utils/Api'; import {GeneralSuccess} from '../../types/GeneralTypes'; +import {cookie} from '../../utils/context/Cookie'; interface state { text: string[]; @@ -166,6 +167,7 @@ export default MovieSettings; const FileHandler = (): JSX.Element => { const [file, setfile] = useState(null); + const [percent, setpercent] = useState(0.0); const uploadFile = (): void => { let xhr = new XMLHttpRequest(); // create XMLHttpRequest @@ -181,11 +183,17 @@ const FileHandler = (): JSX.Element => { xhr.upload.onprogress = function (e): void { console.log(e.loaded / e.total); + setpercent((e.loaded * 100.0) / e.total); }; xhr.open('post', '/api/video/fileupload'); // open connection xhr.setRequestHeader('Accept', 'multipart/form-data'); + const tkn = cookie.Load(); + if (tkn) { + xhr.setRequestHeader('Token', tkn.Token); + } + xhr.send(data); // send data }; @@ -204,6 +212,9 @@ const FileHandler = (): JSX.Element => { name='Select file to upload' /> +
+
+
); }; From a92ce73806420b64a8aa4364a2ec113bf305102b Mon Sep 17 00:00:00 2001 From: lukas Date: Thu, 23 Sep 2021 17:38:20 +0200 Subject: [PATCH 3/7] seperate component for file drop and upload correct save position of uploaded files then parse video file --- apiGo/api/FileUpload.go | 34 +++++---- apiGo/videoparser/ReIndexVideos.go | 12 ++-- apiGo/videoparser/VideoParser.go | 3 +- src/elements/DropZone/DropZone.module.css | 57 +++++++++++++++ src/elements/DropZone/DropZone.tsx | 84 +++++++++++++++++++++++ src/pages/SettingsPage/MovieSettings.tsx | 60 +--------------- 6 files changed, 173 insertions(+), 77 deletions(-) create mode 100644 src/elements/DropZone/DropZone.module.css create mode 100644 src/elements/DropZone/DropZone.tsx diff --git a/apiGo/api/FileUpload.go b/apiGo/api/FileUpload.go index c140642..33fe6bb 100644 --- a/apiGo/api/FileUpload.go +++ b/apiGo/api/FileUpload.go @@ -4,6 +4,8 @@ import ( "fmt" "io" "openmediacenter/apiGo/api/api" + "openmediacenter/apiGo/database" + "openmediacenter/apiGo/videoparser" "os" ) @@ -12,45 +14,49 @@ func addUploadHandler() { fmt.Println("we are in file upload handler") fmt.Printf("permission: %s\n", ctx.PermID().String()) + // get path where to store videos to + mSettings, PathPrefix, _ := database.GetSettings() + req := ctx.GetRequest() mr, err := req.MultipartReader() if err != nil { return } - length := req.ContentLength - fmt.Println(length) + //length := req.ContentLength for { part, err := mr.NextPart() if err == io.EOF { - fmt.Println("part is eof") break } - fmt.Println(part.FormName()) - - var read int64 - var p float32 + //var read int64 + //var p float32 // todo check where we want to place this file - dst, err := os.OpenFile(part.FileName(), os.O_WRONLY|os.O_CREATE, 0644) + vidpath := PathPrefix + mSettings.VideoPath + part.FileName() + dst, err := os.OpenFile(vidpath, os.O_WRONLY|os.O_CREATE, 0644) if err != nil { return } + fmt.Printf("Uploading file %s\n", part.FileName()) + // so now loop through every appended file and upload buffer := make([]byte, 100000) for { cBytes, err := part.Read(buffer) if cBytes > 0 { - read = read + int64(cBytes) - p = float32(read) / float32(length) * 100 - fmt.Printf("progress: %v \n", p) + //read = read + int64(cBytes) + //p = float32(read) / float32(length) * 100 + //fmt.Printf("progress: %v \n", p) dst.Write(buffer[0:cBytes]) } if err == io.EOF { - fmt.Println(cBytes) - fmt.Println("eof this file") + fmt.Printf("Finished uploading file %s\n", part.FileName()) + + videoparser.InitDeps(&mSettings) + videoparser.ProcessVideo(part.FileName()) break } } @@ -58,6 +64,6 @@ func addUploadHandler() { _ = dst.Close() } - ctx.Text("finished") + ctx.Text("finished all files") }) } diff --git a/apiGo/videoparser/ReIndexVideos.go b/apiGo/videoparser/ReIndexVideos.go index 50f5626..1fca565 100644 --- a/apiGo/videoparser/ReIndexVideos.go +++ b/apiGo/videoparser/ReIndexVideos.go @@ -11,7 +11,7 @@ import ( "strings" ) -var mSettings types.SettingsType +var mSettings *types.SettingsType var mExtDepsAvailable *ExtDependencySupport // default Tag ids @@ -32,20 +32,22 @@ type VideoAttributes struct { Width uint } -func ReIndexVideos(path []string, sett types.SettingsType) { +func InitDeps(sett *types.SettingsType) { mSettings = sett // check if the extern dependencies are available mExtDepsAvailable = checkExtDependencySupport() fmt.Printf("FFMPEG support: %t\n", mExtDepsAvailable.FFMpeg) fmt.Printf("MediaInfo support: %t\n", mExtDepsAvailable.MediaInfo) +} +func ReIndexVideos(path []string) { // filter out those urls which are already existing in db nonExisting := filterExisting(path) fmt.Printf("There are %d videos not existing in db.\n", len(*nonExisting)) for _, s := range *nonExisting { - processVideo(s) + ProcessVideo(s) } AppendMessage("reindex finished successfully!") @@ -92,8 +94,8 @@ func filterExisting(paths []string) *[]string { return &resultarr } -func processVideo(fileNameOrig string) { - fmt.Printf("Processing %s video-", fileNameOrig) +func ProcessVideo(fileNameOrig string) { + fmt.Printf("Processing %s video\n", fileNameOrig) // match the file extension r := regexp.MustCompile(`\.[a-zA-Z0-9]+$`) diff --git a/apiGo/videoparser/VideoParser.go b/apiGo/videoparser/VideoParser.go index 9175962..1f1cbd8 100644 --- a/apiGo/videoparser/VideoParser.go +++ b/apiGo/videoparser/VideoParser.go @@ -49,7 +49,8 @@ func StartReindex() bool { } // start reindex process AppendMessage("Starting Reindexing!") - go ReIndexVideos(files, mSettings) + InitDeps(&mSettings) + go ReIndexVideos(files) return true } diff --git a/src/elements/DropZone/DropZone.module.css b/src/elements/DropZone/DropZone.module.css new file mode 100644 index 0000000..c994a9c --- /dev/null +++ b/src/elements/DropZone/DropZone.module.css @@ -0,0 +1,57 @@ +.container { + +} + +.dropArea { + border: 2px dashed #ccc; + border-radius: 20px; + width: 480px; + font-family: sans-serif; + margin: 100px auto; + padding: 20px; + background-color: grey; +} + +.dropArea:hover{ + cursor: pointer; +} + +.dropArea.highlight { + border-color: purple; +} + +p { + margin-top: 0; +} + +.myForm { + margin-bottom: 10px; +} + +.gallery { + margin-top: 10px; +} + +.gallery img { + width: 150px; + margin-bottom: 10px; + margin-right: 10px; + vertical-align: middle; +} + +.button { + display: inline-block; + padding: 10px; + background: #ccc; + cursor: pointer; + border-radius: 5px; + border: 1px solid #ccc; +} + +.button:hover { + background: #ddd; +} + +.fileElem { + display: none; +} diff --git a/src/elements/DropZone/DropZone.tsx b/src/elements/DropZone/DropZone.tsx new file mode 100644 index 0000000..3e9967e --- /dev/null +++ b/src/elements/DropZone/DropZone.tsx @@ -0,0 +1,84 @@ +import style from './DropZone.module.css'; +import React, {useState} from 'react'; +import {cookie} from '../../utils/context/Cookie'; + +export const DropZone = (): JSX.Element => { + const [ondrag, setDrag] = useState(0); + const [percent, setpercent] = useState(0.0); + + const uploadFile = (f: FileList): void => { + let xhr = new XMLHttpRequest(); // create XMLHttpRequest + let data = new FormData(); // create formData object + + for (let i = 0; i < f.length; i++) { + const file = f.item(i); + if (file) { + data.append('file' + i, file); + } + } + + xhr.onload = function (): void { + console.log(this.responseText); // whatever the server returns + }; + + xhr.upload.onprogress = function (e): void { + console.log(e.loaded / e.total); + setpercent((e.loaded * 100.0) / e.total); + }; + + xhr.open('post', '/api/video/fileupload'); // open connection + xhr.setRequestHeader('Accept', 'multipart/form-data'); + + const tkn = cookie.Load(); + if (tkn) { + xhr.setRequestHeader('Token', tkn.Token); + } + + xhr.send(data); // send data + }; + + return ( +
0 ? ' ' + style.highlight : '')} + onDragEnter={(e): void => { + e.preventDefault(); + e.stopPropagation(); + setDrag(ondrag + 1); + }} + onDragLeave={(e): void => { + e.preventDefault(); + e.stopPropagation(); + setDrag(ondrag - 1); + }} + onDragOver={(e): void => { + e.stopPropagation(); + e.preventDefault(); + }} + onDrop={(e): void => { + setDrag(0); + e.preventDefault(); + e.stopPropagation(); + + uploadFile(e.dataTransfer.files); + }} + onClick={(): void => { + let input = document.createElement('input'); + input.type = 'file'; + input.multiple = true; + input.onchange = function (): void { + if (input.files) { + console.log(input.files); + uploadFile(input.files); + } + }; + input.click(); + }}> +
+

To upload new Videos darg and drop them here or click to select some...

+
+
+
+
+
+ ); +}; diff --git a/src/pages/SettingsPage/MovieSettings.tsx b/src/pages/SettingsPage/MovieSettings.tsx index a4aa820..3e4d518 100644 --- a/src/pages/SettingsPage/MovieSettings.tsx +++ b/src/pages/SettingsPage/MovieSettings.tsx @@ -1,8 +1,8 @@ -import React, {BaseSyntheticEvent, useState} from 'react'; +import React from 'react'; import style from './MovieSettings.module.css'; import {APINode, callAPI} from '../../utils/Api'; import {GeneralSuccess} from '../../types/GeneralTypes'; -import {cookie} from '../../utils/context/Cookie'; +import {DropZone} from '../../elements/DropZone/DropZone'; interface state { text: string[]; @@ -124,7 +124,7 @@ class MovieSettings extends React.Component {
))} - + ); } @@ -164,57 +164,3 @@ class MovieSettings extends React.Component { } export default MovieSettings; - -const FileHandler = (): JSX.Element => { - const [file, setfile] = useState(null); - const [percent, setpercent] = useState(0.0); - - const uploadFile = (): void => { - let xhr = new XMLHttpRequest(); // create XMLHttpRequest - let data = new FormData(); // create formData object - if (!file) { - return; - } - data.append('file', file); - - xhr.onload = function (): void { - console.log(this.responseText); // whatever the server returns - }; - - xhr.upload.onprogress = function (e): void { - console.log(e.loaded / e.total); - setpercent((e.loaded * 100.0) / e.total); - }; - - xhr.open('post', '/api/video/fileupload'); // open connection - xhr.setRequestHeader('Accept', 'multipart/form-data'); - - const tkn = cookie.Load(); - if (tkn) { - xhr.setRequestHeader('Token', tkn.Token); - } - - xhr.send(data); // send data - }; - - return ( -
- { - console.log(e); - if (e.target) { - console.log(e.target.files[0]); - setfile(e.target.files[0]); - // setfile(e.target.files[0]); - } - }} - type='file' - name='Select file to upload' - /> - -
-
-
-
- ); -}; From afaad8184960276d4f0ea914dc15c542a0c97e5f Mon Sep 17 00:00:00 2001 From: lukas Date: Thu, 23 Sep 2021 19:45:58 +0200 Subject: [PATCH 4/7] fix linter errror use correct videopath on reindex after upload --- .eslintrc.js | 1 + apiGo/api/FileUpload.go | 1 - apiGo/videoparser/ReIndexVideos.go | 7 +++++-- apiGo/videoparser/VideoParser.go | 12 +++++++----- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 81e444c..52b1cbf 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -46,6 +46,7 @@ module.exports = { // Map from global var to bool specifying if it can be redefined globals: { File: true, + FileList: true, jest: true, __DEV__: true, __dirname: false, diff --git a/apiGo/api/FileUpload.go b/apiGo/api/FileUpload.go index 33fe6bb..d4a8a57 100644 --- a/apiGo/api/FileUpload.go +++ b/apiGo/api/FileUpload.go @@ -54,7 +54,6 @@ func addUploadHandler() { if err == io.EOF { fmt.Printf("Finished uploading file %s\n", part.FileName()) - videoparser.InitDeps(&mSettings) videoparser.ProcessVideo(part.FileName()) break diff --git a/apiGo/videoparser/ReIndexVideos.go b/apiGo/videoparser/ReIndexVideos.go index 1fca565..1a59fa2 100644 --- a/apiGo/videoparser/ReIndexVideos.go +++ b/apiGo/videoparser/ReIndexVideos.go @@ -4,6 +4,7 @@ import ( "database/sql" "fmt" "openmediacenter/apiGo/api/types" + "openmediacenter/apiGo/config" "openmediacenter/apiGo/database" "openmediacenter/apiGo/videoparser/tmdb" "regexp" @@ -122,8 +123,10 @@ func addVideo(videoName string, fileName string, year int) { Width: 0, } + vidFolder := config.GetConfig().General.ReindexPrefix + mSettings.VideoPath + if mExtDepsAvailable.FFMpeg { - ppic, err = parseFFmpegPic(mSettings.VideoPath + fileName) + ppic, err = parseFFmpegPic(vidFolder + fileName) if err != nil { fmt.Printf("FFmpeg error occured: %s\n", err.Error()) } else { @@ -132,7 +135,7 @@ func addVideo(videoName string, fileName string, year int) { } if mExtDepsAvailable.MediaInfo { - atr := getVideoAttributes(mSettings.VideoPath + fileName) + atr := getVideoAttributes(vidFolder + fileName) if atr != nil { vidAtr = atr } diff --git a/apiGo/videoparser/VideoParser.go b/apiGo/videoparser/VideoParser.go index 1f1cbd8..d64a01e 100644 --- a/apiGo/videoparser/VideoParser.go +++ b/apiGo/videoparser/VideoParser.go @@ -3,6 +3,7 @@ package videoparser import ( "fmt" "io/ioutil" + "openmediacenter/apiGo/config" "openmediacenter/apiGo/database" "os" "path/filepath" @@ -19,20 +20,21 @@ func StartReindex() bool { SendEvent("start") AppendMessage("starting reindex..") - mSettings, PathPrefix, _ := database.GetSettings() + mSettings, _, _ := database.GetSettings() + // add the path prefix to videopath - mSettings.VideoPath = PathPrefix + mSettings.VideoPath + vidFolder := config.GetConfig().General.ReindexPrefix + mSettings.VideoPath // check if path even exists - if _, err := os.Stat(mSettings.VideoPath); os.IsNotExist(err) { + if _, err := os.Stat(vidFolder); os.IsNotExist(err) { fmt.Println("Reindex path doesn't exist!") - AppendMessage(fmt.Sprintf("Reindex path doesn't exist! :%s", mSettings.VideoPath)) + AppendMessage(fmt.Sprintf("Reindex path doesn't exist! :%s", vidFolder)) SendEvent("stop") return false } var files []string - err := filepath.Walk(mSettings.VideoPath, func(path string, info os.FileInfo, err error) error { + err := filepath.Walk(vidFolder, func(path string, info os.FileInfo, err error) error { if err != nil { fmt.Println(err.Error()) return err From 156aaa7a7150d809d9476f42ef7124b6ffea7cc7 Mon Sep 17 00:00:00 2001 From: lukas Date: Thu, 23 Sep 2021 20:16:09 +0200 Subject: [PATCH 5/7] nice heading above uploadfield 10G upload limit for nginx config --- .../etc/nginx/sites-available/OpenMediaCenter.conf | 1 + src/elements/DropZone/DropZone.module.css | 6 ------ src/elements/DropZone/DropZone.tsx | 5 ++++- src/pages/SettingsPage/MovieSettings.module.css | 6 ++++++ src/pages/SettingsPage/MovieSettings.tsx | 8 +++++++- 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/deb/OpenMediaCenter/etc/nginx/sites-available/OpenMediaCenter.conf b/deb/OpenMediaCenter/etc/nginx/sites-available/OpenMediaCenter.conf index cbdb815..b3bd949 100755 --- a/deb/OpenMediaCenter/etc/nginx/sites-available/OpenMediaCenter.conf +++ b/deb/OpenMediaCenter/etc/nginx/sites-available/OpenMediaCenter.conf @@ -14,6 +14,7 @@ server { } location ~* ^/(api/|token) { + client_max_body_size 10G; proxy_pass http://127.0.0.1:8081; } location /subscribe { diff --git a/src/elements/DropZone/DropZone.module.css b/src/elements/DropZone/DropZone.module.css index c994a9c..32f6e61 100644 --- a/src/elements/DropZone/DropZone.module.css +++ b/src/elements/DropZone/DropZone.module.css @@ -1,15 +1,9 @@ -.container { - -} - .dropArea { border: 2px dashed #ccc; border-radius: 20px; width: 480px; font-family: sans-serif; - margin: 100px auto; padding: 20px; - background-color: grey; } .dropArea:hover{ diff --git a/src/elements/DropZone/DropZone.tsx b/src/elements/DropZone/DropZone.tsx index 3e9967e..2139017 100644 --- a/src/elements/DropZone/DropZone.tsx +++ b/src/elements/DropZone/DropZone.tsx @@ -1,11 +1,14 @@ import style from './DropZone.module.css'; import React, {useState} from 'react'; import {cookie} from '../../utils/context/Cookie'; +import GlobalInfos from '../../utils/GlobalInfos'; export const DropZone = (): JSX.Element => { const [ondrag, setDrag] = useState(0); const [percent, setpercent] = useState(0.0); + const theme = GlobalInfos.getThemeStyle(); + const uploadFile = (f: FileList): void => { let xhr = new XMLHttpRequest(); // create XMLHttpRequest let data = new FormData(); // create formData object @@ -39,7 +42,7 @@ export const DropZone = (): JSX.Element => { return (
0 ? ' ' + style.highlight : '')} + className={style.dropArea + (ondrag > 0 ? ' ' + style.highlight : '') + ' ' + theme.secbackground} onDragEnter={(e): void => { e.preventDefault(); e.stopPropagation(); diff --git a/src/pages/SettingsPage/MovieSettings.module.css b/src/pages/SettingsPage/MovieSettings.module.css index 37c5ef8..e67147d 100644 --- a/src/pages/SettingsPage/MovieSettings.module.css +++ b/src/pages/SettingsPage/MovieSettings.module.css @@ -11,3 +11,9 @@ padding: 10px; width: 40%; } + +.uploadtext { + font-size: x-large; + margin-top: 30px; + margin-bottom: 10px; +} diff --git a/src/pages/SettingsPage/MovieSettings.tsx b/src/pages/SettingsPage/MovieSettings.tsx index 3e4d518..f87a92b 100644 --- a/src/pages/SettingsPage/MovieSettings.tsx +++ b/src/pages/SettingsPage/MovieSettings.tsx @@ -3,6 +3,7 @@ import style from './MovieSettings.module.css'; import {APINode, callAPI} from '../../utils/Api'; import {GeneralSuccess} from '../../types/GeneralTypes'; import {DropZone} from '../../elements/DropZone/DropZone'; +import GlobalInfos from '../../utils/GlobalInfos'; interface state { text: string[]; @@ -100,6 +101,8 @@ class MovieSettings extends React.Component { } render(): JSX.Element { + const theme = GlobalInfos.getThemeStyle(); + return ( <>
))}
- +
+
Video Upload:
+ +
); } From fd5542c5287f4462fa665798d92edbb85664bfdc Mon Sep 17 00:00:00 2001 From: lukas Date: Fri, 24 Sep 2021 22:12:42 +0200 Subject: [PATCH 6/7] parse new video in new go function validate extension on server to allow only videos --- apiGo/api/FileUpload.go | 16 +++++++++++----- .../nginx/sites-available/OpenMediaCenter.conf | 2 +- src/elements/DropZone/DropZone.tsx | 7 ++++--- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/apiGo/api/FileUpload.go b/apiGo/api/FileUpload.go index d4a8a57..175be85 100644 --- a/apiGo/api/FileUpload.go +++ b/apiGo/api/FileUpload.go @@ -7,6 +7,7 @@ import ( "openmediacenter/apiGo/database" "openmediacenter/apiGo/videoparser" "os" + "path/filepath" ) func addUploadHandler() { @@ -21,8 +22,12 @@ func addUploadHandler() { mr, err := req.MultipartReader() if err != nil { + ctx.Errorf("incorrect request!") return } + + videoparser.InitDeps(&mSettings) + //length := req.ContentLength for { part, err := mr.NextPart() @@ -30,9 +35,11 @@ func addUploadHandler() { break } - //var read int64 - //var p float32 - // todo check where we want to place this file + // todo allow more video formats than mp4 + // only allow valid extensions + if filepath.Ext(part.FileName()) != ".mp4" { + continue + } vidpath := PathPrefix + mSettings.VideoPath + part.FileName() dst, err := os.OpenFile(vidpath, os.O_WRONLY|os.O_CREATE, 0644) if err != nil { @@ -54,8 +61,7 @@ func addUploadHandler() { if err == io.EOF { fmt.Printf("Finished uploading file %s\n", part.FileName()) - videoparser.InitDeps(&mSettings) - videoparser.ProcessVideo(part.FileName()) + go videoparser.ProcessVideo(part.FileName()) break } } diff --git a/deb/OpenMediaCenter/etc/nginx/sites-available/OpenMediaCenter.conf b/deb/OpenMediaCenter/etc/nginx/sites-available/OpenMediaCenter.conf index b3bd949..ce85ae1 100755 --- a/deb/OpenMediaCenter/etc/nginx/sites-available/OpenMediaCenter.conf +++ b/deb/OpenMediaCenter/etc/nginx/sites-available/OpenMediaCenter.conf @@ -13,7 +13,7 @@ server { try_files $uri /index.html; } - location ~* ^/(api/|token) { + location ~* ^/(api) { client_max_body_size 10G; proxy_pass http://127.0.0.1:8081; } diff --git a/src/elements/DropZone/DropZone.tsx b/src/elements/DropZone/DropZone.tsx index 2139017..4277576 100644 --- a/src/elements/DropZone/DropZone.tsx +++ b/src/elements/DropZone/DropZone.tsx @@ -10,8 +10,8 @@ export const DropZone = (): JSX.Element => { const theme = GlobalInfos.getThemeStyle(); const uploadFile = (f: FileList): void => { - let xhr = new XMLHttpRequest(); // create XMLHttpRequest - let data = new FormData(); // create formData object + const xhr = new XMLHttpRequest(); // create XMLHttpRequest + const data = new FormData(); // create formData object for (let i = 0; i < f.length; i++) { const file = f.item(i); @@ -22,6 +22,8 @@ export const DropZone = (): JSX.Element => { xhr.onload = function (): void { console.log(this.responseText); // whatever the server returns + + setpercent(0); }; xhr.upload.onprogress = function (e): void { @@ -70,7 +72,6 @@ export const DropZone = (): JSX.Element => { input.multiple = true; input.onchange = function (): void { if (input.files) { - console.log(input.files); uploadFile(input.files); } }; From 6c553e6f48ffab30d98b93431db27008ce74c52d Mon Sep 17 00:00:00 2001 From: lukas Date: Sun, 26 Sep 2021 22:30:32 +0200 Subject: [PATCH 7/7] message if upload was successfull or not --- apiGo/api/FileUpload.go | 12 +++---- src/elements/DropZone/DropZone.module.css | 39 ++++++----------------- src/elements/DropZone/DropZone.tsx | 24 ++++++++++++-- 3 files changed, 35 insertions(+), 40 deletions(-) diff --git a/apiGo/api/FileUpload.go b/apiGo/api/FileUpload.go index 175be85..3f5c148 100644 --- a/apiGo/api/FileUpload.go +++ b/apiGo/api/FileUpload.go @@ -12,9 +12,6 @@ import ( func addUploadHandler() { api.AddHandler("fileupload", api.VideoNode, api.PermUser, func(ctx api.Context) { - fmt.Println("we are in file upload handler") - fmt.Printf("permission: %s\n", ctx.PermID().String()) - // get path where to store videos to mSettings, PathPrefix, _ := database.GetSettings() @@ -28,7 +25,6 @@ func addUploadHandler() { videoparser.InitDeps(&mSettings) - //length := req.ContentLength for { part, err := mr.NextPart() if err == io.EOF { @@ -43,6 +39,7 @@ func addUploadHandler() { vidpath := PathPrefix + mSettings.VideoPath + part.FileName() dst, err := os.OpenFile(vidpath, os.O_WRONLY|os.O_CREATE, 0644) if err != nil { + ctx.Error("error opening file") return } @@ -53,9 +50,6 @@ func addUploadHandler() { for { cBytes, err := part.Read(buffer) if cBytes > 0 { - //read = read + int64(cBytes) - //p = float32(read) / float32(length) * 100 - //fmt.Printf("progress: %v \n", p) dst.Write(buffer[0:cBytes]) } @@ -69,6 +63,8 @@ func addUploadHandler() { _ = dst.Close() } - ctx.Text("finished all files") + ctx.Json(struct { + Message string + }{Message: "finished all files"}) }) } diff --git a/src/elements/DropZone/DropZone.module.css b/src/elements/DropZone/DropZone.module.css index 32f6e61..f578e61 100644 --- a/src/elements/DropZone/DropZone.module.css +++ b/src/elements/DropZone/DropZone.module.css @@ -6,7 +6,7 @@ padding: 20px; } -.dropArea:hover{ +.dropArea:hover { cursor: pointer; } @@ -14,38 +14,17 @@ border-color: purple; } -p { - margin-top: 0; -} - .myForm { margin-bottom: 10px; } -.gallery { +.progresswrapper { + width: 100%; + height: 5px; + margin-top: 3px; +} + +.finished { margin-top: 10px; -} - -.gallery img { - width: 150px; - margin-bottom: 10px; - margin-right: 10px; - vertical-align: middle; -} - -.button { - display: inline-block; - padding: 10px; - background: #ccc; - cursor: pointer; - border-radius: 5px; - border: 1px solid #ccc; -} - -.button:hover { - background: #ddd; -} - -.fileElem { - display: none; + text-align: center; } diff --git a/src/elements/DropZone/DropZone.tsx b/src/elements/DropZone/DropZone.tsx index 4277576..ba1b53c 100644 --- a/src/elements/DropZone/DropZone.tsx +++ b/src/elements/DropZone/DropZone.tsx @@ -6,6 +6,7 @@ import GlobalInfos from '../../utils/GlobalInfos'; export const DropZone = (): JSX.Element => { const [ondrag, setDrag] = useState(0); const [percent, setpercent] = useState(0.0); + const [finished, setfinished] = useState(null); const theme = GlobalInfos.getThemeStyle(); @@ -23,7 +24,17 @@ export const DropZone = (): JSX.Element => { xhr.onload = function (): void { console.log(this.responseText); // whatever the server returns - setpercent(0); + const resp = JSON.parse(this.responseText); + if (resp.Message === 'finished all files') { + setfinished(''); + } else { + setfinished(resp.Message); + } + + setTimeout(() => { + setpercent(0); + setfinished(null); + }, 2000); }; xhr.upload.onprogress = function (e): void { @@ -79,9 +90,18 @@ export const DropZone = (): JSX.Element => { }}>

To upload new Videos darg and drop them here or click to select some...

-
+
+ {finished !== null ? ( + finished === '' ? ( +
Finished uploading
+ ) : ( +
Upload failed: {finished}
+ ) + ) : ( + <> + )}
);