diff --git a/app.py b/app.py
index 9e4b1aa..096395c 100644
--- a/app.py
+++ b/app.py
@@ -56,7 +56,7 @@
def media_list_clear_cache():
if GStorage["scaning_state"] == "inprogress":
return jsonify({"status": True})
-
+
media_remove_cache(config["cache_dir"], GStorage)
scan_medialib(config, GStorage, socketio)
return jsonify({"status": True})
@@ -68,7 +68,7 @@
if filtered_files == None:
filtered_files = scan_medialib(config, GStorage, socketio)
- if GStorage["scaning_state"] == "inprogress" and not len(filtered_files):
+ if GStorage["scaning_state"] == "inprogress" and filtered_files != None and not len(filtered_files):
response = {"status": "scaning", "data": []};
else:
response = {"status": True, "data": filtered_files}
diff --git a/mediascan.py b/mediascan.py
index b9188f7..af2fe09 100644
--- a/mediascan.py
+++ b/mediascan.py
@@ -138,13 +138,18 @@
# Function to list media files
-def list_media_files(directories):
+def list_media_files(socketio, directories):
media_files = []
for directory in directories:
if os.path.exists(directory):
for root, _, files in os.walk(directory):
- for file in files:
+ for inx, file in enumerate(files):
file_path = os.path.join(root, file)
+
+ if not inx or not inx % 50:
+ socketio.emit("medialib-scaning-process", {
+ "message": f"Scaning: { directory }"
+ })
try:
file_info = {
"name": file,
@@ -202,14 +207,24 @@
def bg_scan_medialib(socketio, config, GStorage):
GStorage["scaning_state"] = "inprogress";
- media_files = list_media_files(config.get("directories", []))
+ media_files = list_media_files(socketio, config.get("directories", []))
allowed_formats = config.get("allowed_formats", [])
+ socketio.emit("medialib-scaning-process", {
+ "message": f"Filtering by file extension..."
+ })
filtered_files = filter_media_files(media_files, allowed_formats)
+ socketio.emit("medialib-scaning-process", {
+ "message": f"Adding media file detail..."
+ })
+
# Add detailed media info
for file in filtered_files:
file["size"], file["size_unit"], file["size_bytes"] = human_readable_size(file["size"])
+ socketio.emit("medialib-scaning-process", {
+ "message": f"Adding detail: { file["path"] }"
+ })
file_info = get_media_info_with_ffprobe(file["path"])
if file_info:
file["info"] = file_info
@@ -218,6 +233,9 @@
GStorage["scaning_state"] = "inaction"
+ socketio.emit("medialib-scaning-process", {
+ "message": f"Creating cache..."
+ })
media_create_cache(config["cache_dir"], filtered_files)
socketio.emit("medialib-scaning-complete", {
diff --git a/scss/components/media-list.scss b/scss/components/media-list.scss
new file mode 100644
index 0000000..74e3e24
--- /dev/null
+++ b/scss/components/media-list.scss
@@ -0,0 +1,13 @@
+.component.media-list {
+ .do-rescan-media-lib {
+ .spinner-border {
+ display: none;
+ }
+
+ &.inprogress {
+ .spinner-border {
+ display: block;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/scss/index.scss b/scss/index.scss
index 360b4cc..8595abf 100644
--- a/scss/index.scss
+++ b/scss/index.scss
@@ -1 +1,2 @@
-@import "main.scss";
\ No newline at end of file
+@import "main.scss";
+@import "components/media-list.scss";
\ No newline at end of file
diff --git a/scss/main.scss b/scss/main.scss
index 2d58f16..f44096a 100644
--- a/scss/main.scss
+++ b/scss/main.scss
@@ -92,3 +92,22 @@
align-items: center;
}
+.sm-spinner {
+ width: 18px;
+ height: 18px;
+ border-width: 3px;
+}
+
+.btn {
+ .border-spinner {
+ margin-right: 2px;
+ position: relative;
+ top: 1px;
+ }
+
+ &.inprogress {
+ display: inline-flex;
+ gap: 6px;
+ align-items: center;
+ }
+}
\ No newline at end of file
diff --git a/static/css/main.css b/static/css/main.css
index 928b5d3..78c5b6b 100644
--- a/static/css/main.css
+++ b/static/css/main.css
@@ -1,2 +1,2 @@
-a{text-decoration:none}.loading-spinner-container{width:100%;margin:50px auto;text-align:center}.loader{width:48px;height:48px;border:5px solid #777;border-bottom-color:transparent;border-radius:50%;display:inline-block;box-sizing:border-box;animation:rotation 1s linear infinite}@keyframes rotation{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.transcodate-form-container{margin-top:20px;display:flex;flex-wrap:wrap;flex-direction:row;gap:10px}.transcodate-form-container>.form-control{display:flex;flex-wrap:nowrap;flex-direction:row;justify-content:flex-start;gap:10px;align-items:center}.transcodate-form-container>.form-control>strong{white-space:nowrap;display:inline-block;width:100px}.crf-range{margin-left:5px}#progress{margin-top:20px;margin-bottom:0}.circle-bg{stroke-dasharray:100,100}.circle-progress{transition:stroke-dasharray .3s ease}.list-group-item.task{display:flex;flex-direction:row;justify-content:space-between;align-items:center;gap:12px}.list-group-item.task .file{display:flex;flex-direction:row;gap:8px;align-items:center}
+a{text-decoration:none}.loading-spinner-container{width:100%;margin:50px auto;text-align:center}.loader{width:48px;height:48px;border:5px solid #777;border-bottom-color:transparent;border-radius:50%;display:inline-block;box-sizing:border-box;animation:rotation 1s linear infinite}@keyframes rotation{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.transcodate-form-container{margin-top:20px;display:flex;flex-wrap:wrap;flex-direction:row;gap:10px}.transcodate-form-container>.form-control{display:flex;flex-wrap:nowrap;flex-direction:row;justify-content:flex-start;gap:10px;align-items:center}.transcodate-form-container>.form-control>strong{white-space:nowrap;display:inline-block;width:100px}.crf-range{margin-left:5px}#progress{margin-top:20px;margin-bottom:0}.circle-bg{stroke-dasharray:100,100}.circle-progress{transition:stroke-dasharray .3s ease}.list-group-item.task{display:flex;flex-direction:row;justify-content:space-between;align-items:center;gap:12px}.list-group-item.task .file{display:flex;flex-direction:row;gap:8px;align-items:center}.sm-spinner{width:18px;height:18px;border-width:3px}.btn .border-spinner{margin-right:2px;position:relative;top:1px}.btn.inprogress{display:inline-flex;gap:6px;align-items:center}.component.media-list .do-rescan-media-lib .spinner-border{display:none}.component.media-list .do-rescan-media-lib.inprogress .spinner-border{display:block}
/*# sourceMappingURL=main.css.map */
diff --git a/static/css/main.css.map b/static/css/main.css.map
index 01c5d37..0e36f16 100644
--- a/static/css/main.css.map
+++ b/static/css/main.css.map
@@ -1 +1 @@
-{"version":3,"sources":["main.scss"],"names":[],"mappings":"AAAA,EACE,gBAAA,KAKF,2BACC,MAAA,KACA,OAAA,KAAA,KACA,WAAA,OAGD,QACE,MAAA,KACA,OAAA,KACA,OAAA,IAAA,MAAA,KACA,oBAAA,YACA,cAAA,IACA,QAAA,aACA,WAAA,WACA,UAAA,SAAA,GAAA,OAAA,SAGF,oBACE,GACE,UAAA,UAGF,KACE,UAAA,gBAMJ,4BACC,WAAA,KACA,QAAA,KACA,UAAA,KACC,eAAA,IACA,IAAA,KAGF,0CACC,QAAA,KACA,UAAA,OACC,eAAA,IACA,gBAAA,WACA,IAAA,KACA,YAAA,OAGF,iDACC,YAAA,OACA,QAAA,aACC,MAAA,MAGF,WACE,YAAA,IAGF,UACE,WAAA,KACA,cAAA,EAOF,WACE,iBAAA,GAAA,CAAA,IAGF,iBACE,WAAA,iBAAA,IAAA,KAGF,sBACE,QAAA,KACA,eAAA,IACA,gBAAA,cACA,YAAA,OACA,IAAA,KAGF,4BACE,QAAA,KACA,eAAA,IACA,IAAA,IACA,YAAA","file":"main.css","sourcesContent":["a {\n text-decoration: none;\n}\n\n/* LOADING SPINNER */\n\n.loading-spinner-container {\n\twidth: 100%;\n\tmargin: 50px auto;\n\ttext-align: center;\n}\n\n.loader {\n width: 48px;\n height: 48px;\n border: 5px solid #777;\n border-bottom-color: transparent;\n border-radius: 50%;\n display: inline-block;\n box-sizing: border-box;\n animation: rotation 1s linear infinite;\n}\n\n@keyframes rotation {\n 0% {\n transform: rotate(0deg);\n }\n\n 100% {\n transform: rotate(360deg);\n }\n} \n\n/* END LOADING SPINNER */\n\n.transcodate-form-container {\n\tmargin-top: 20px;\n\tdisplay: flex;\n\tflex-wrap: wrap;\n flex-direction: row;\n gap: 10px;\n}\n\n.transcodate-form-container > .form-control {\n\tdisplay: flex;\n\tflex-wrap: nowrap;\n flex-direction: row;\n justify-content: flex-start;\n gap: 10px;\n align-items: center;\n}\n\n.transcodate-form-container > .form-control > strong {\n\twhite-space: nowrap;\n\tdisplay: inline-block;\n width: 100px;\n}\n\n.crf-range {\n margin-left: 5px;\n}\n\n#progress {\n margin-top: 20px;\n margin-bottom: 0;\n}\n\n.progress-circle {\n/* transform: rotate(-90deg);*/\n}\n\n.circle-bg {\n stroke-dasharray: 100, 100;\n}\n\n.circle-progress {\n transition: stroke-dasharray 0.3s ease;\n}\n\n.list-group-item.task {\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n gap: 12px;\n}\n\n.list-group-item.task .file {\n display: flex;\n flex-direction: row;\n gap: 8px;\n align-items: center;\n}\n\n"]}
\ No newline at end of file
+{"version":3,"sources":["main.scss","components/media-list.scss"],"names":[],"mappings":"AAAA,EACE,gBAAA,KAKF,2BACC,MAAA,KACA,OAAA,KAAA,KACA,WAAA,OAGD,QACE,MAAA,KACA,OAAA,KACA,OAAA,IAAA,MAAA,KACA,oBAAA,YACA,cAAA,IACA,QAAA,aACA,WAAA,WACA,UAAA,SAAA,GAAA,OAAA,SAGF,oBACE,GACE,UAAA,UAGF,KACE,UAAA,gBAMJ,4BACC,WAAA,KACA,QAAA,KACA,UAAA,KACC,eAAA,IACA,IAAA,KAGF,0CACC,QAAA,KACA,UAAA,OACC,eAAA,IACA,gBAAA,WACA,IAAA,KACA,YAAA,OAGF,iDACC,YAAA,OACA,QAAA,aACC,MAAA,MAGF,WACE,YAAA,IAGF,UACE,WAAA,KACA,cAAA,EAOF,WACE,iBAAA,GAAA,CAAA,IAGF,iBACE,WAAA,iBAAA,IAAA,KAGF,sBACE,QAAA,KACA,eAAA,IACA,gBAAA,cACA,YAAA,OACA,IAAA,KAGF,4BACE,QAAA,KACA,eAAA,IACA,IAAA,IACA,YAAA,OAGF,YACE,MAAA,KACA,OAAA,KACA,aAAA,IAIA,qBACE,aAAA,IACA,SAAA,SACA,IAAA,IAGF,gBACE,QAAA,YACA,IAAA,IACA,YAAA,OC5GF,2DACC,QAAA,KAIA,sEACC,QAAA","file":"main.css","sourcesContent":["a {\n text-decoration: none;\n}\n\n/* LOADING SPINNER */\n\n.loading-spinner-container {\n\twidth: 100%;\n\tmargin: 50px auto;\n\ttext-align: center;\n}\n\n.loader {\n width: 48px;\n height: 48px;\n border: 5px solid #777;\n border-bottom-color: transparent;\n border-radius: 50%;\n display: inline-block;\n box-sizing: border-box;\n animation: rotation 1s linear infinite;\n}\n\n@keyframes rotation {\n 0% {\n transform: rotate(0deg);\n }\n\n 100% {\n transform: rotate(360deg);\n }\n} \n\n/* END LOADING SPINNER */\n\n.transcodate-form-container {\n\tmargin-top: 20px;\n\tdisplay: flex;\n\tflex-wrap: wrap;\n flex-direction: row;\n gap: 10px;\n}\n\n.transcodate-form-container > .form-control {\n\tdisplay: flex;\n\tflex-wrap: nowrap;\n flex-direction: row;\n justify-content: flex-start;\n gap: 10px;\n align-items: center;\n}\n\n.transcodate-form-container > .form-control > strong {\n\twhite-space: nowrap;\n\tdisplay: inline-block;\n width: 100px;\n}\n\n.crf-range {\n margin-left: 5px;\n}\n\n#progress {\n margin-top: 20px;\n margin-bottom: 0;\n}\n\n.progress-circle {\n/* transform: rotate(-90deg);*/\n}\n\n.circle-bg {\n stroke-dasharray: 100, 100;\n}\n\n.circle-progress {\n transition: stroke-dasharray 0.3s ease;\n}\n\n.list-group-item.task {\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n gap: 12px;\n}\n\n.list-group-item.task .file {\n display: flex;\n flex-direction: row;\n gap: 8px;\n align-items: center;\n}\n\n.sm-spinner {\n width: 18px;\n height: 18px;\n border-width: 3px;\n} \n\n.btn {\n .border-spinner {\n margin-right: 2px;\n position: relative;\n top: 1px;\n }\n\n &.inprogress {\n display: inline-flex;\n gap: 6px;\n align-items: center;\n }\n}",".component.media-list {\n\t.do-rescan-media-lib {\n\t\t.spinner-border {\n\t\t\tdisplay: none;\n\t\t}\n\n\t\t&.inprogress {\n\t\t\t.spinner-border {\n\t\t\t\tdisplay: block;\n\t\t\t}\n\t\t}\n\t}\n}"]}
\ No newline at end of file
diff --git a/static/js/components/media-list.js b/static/js/components/media-list.js
index ba880df..778f1f7 100644
--- a/static/js/components/media-list.js
+++ b/static/js/components/media-list.js
@@ -36,8 +36,14 @@
function rescanMediaLibHandler() {
$("#do-rescan-media-lib").on("click", function(){
+ if($(this).hasClass("disabled")) {
+ return;
+ }
+
+ console.log('test');
$.getJSON("/media-list/clear-cache").done(function(resp){
if(resp.status) {
+ document.getElementById("do-rescan-media-lib").setStateInprogress();
return;
// $('#media-table').DataTable().destroy();
// return loadMediaList();
@@ -53,6 +59,10 @@
function renderMediaList(data) {
const tableBody = $("#media-table tbody");
+ if(typeof data != "object") {
+ return;
+ }
+
if (data.length > 0) {
data.forEach((file, index) => {
const videoInfo = file.info.video
@@ -115,9 +125,41 @@
});
}
+let lastMediaLibScaningProcessMsg = "";
+
+function initScaningProcessingView() {
+ const activateBtn = document.getElementById("do-rescan-media-lib");
+ activateBtn.setStateInprogress = () => {
+ changeBtnStateToInProgress(activateBtn);
+ }
+
+ activateBtn.setStateDefault = () => {
+ changeBtnStateToDefault(activateBtn);
+ }
+
+
+ const scaningProcessingContainer = $(".scaning-process-container");
+
+ socket.on("medialib-scaning-process", data => {
+ if(!scaningProcessingContainer.is(":visible")) {
+ scaningProcessingContainer.html("");
+ scaningProcessingContainer.slideDown();
+ activateBtn.setStateInprogress();
+ }
+
+ if(lastMediaLibScaningProcessMsg == data.message) {
+ return;
+ }
+
+ lastMediaLibScaningProcessMsg = data.message;
+ scaningProcessingContainer.html(data.message);
+ });
+}
+
$(document).ready(function() {
loadMediaList();
rescanMediaLibHandler();
+ initScaningProcessingView();
socket.on("medialib-scaning-complete", resp => {
if($('#media-table_wrapper').length) {
@@ -126,5 +168,8 @@
}
renderMediaList(resp.data);
+
+ $(".scaning-process-container").slideUp();
+ document.getElementById("do-rescan-media-lib").setStateDefault();
});
});
\ No newline at end of file
diff --git a/static/js/lib.js b/static/js/lib.js
index 30f2df2..9d91ddb 100644
--- a/static/js/lib.js
+++ b/static/js/lib.js
@@ -15,4 +15,24 @@
function calcTranscodingProgress(time, duration) {
return Math.floor(timeToSeconds(time) / parseInt(duration) * 100);
+}
+
+function changeBtnStateToInProgress(btn) {
+ if(btn.stateIsInprogress) {
+ return;
+ }
+
+ btn.stateIsInprogress = true;
+ $(btn).addClass("inprogress");
+ $(btn).addClass("disabled");
+}
+
+function changeBtnStateToDefault(btn) {
+ if(!btn.stateIsInprogress) {
+ return;
+ }
+
+ btn.stateIsInprogress = false;
+ $(btn).removeClass("inprogress");
+ $(btn).removeClass("disabled");
}
\ No newline at end of file
diff --git a/templates/components/media-list.html b/templates/components/media-list.html
index 7b09573..22b3c7b 100644
--- a/templates/components/media-list.html
+++ b/templates/components/media-list.html
@@ -1,23 +1,30 @@
-
+
\ No newline at end of file