Переглянути джерело

Optimized AirMusic serach cache function

TC pushbot 5 4 роки тому
батько
коміт
b58d7fbe51

+ 2 - 2
mod/agi/agi.go

@@ -237,7 +237,7 @@ func (g *Gateway) ExecuteAGIScript(scriptContent string, scriptFile string, scri
 	vm := otto.New()
 	//Inject standard libs into the vm
 	g.injectStandardLibs(vm, scriptFile, scriptScope)
-	g.injectUserFunctions(vm, thisuser, w, r)
+	g.injectUserFunctions(vm, scriptFile, scriptScope, thisuser, w, r)
 
 	//Detect cotent type
 	contentType := r.Header.Get("Content-type")
@@ -292,7 +292,7 @@ func (g *Gateway) ExecuteAGIScriptAsUser(scriptFile string, targetUser *user.Use
 	vm := otto.New()
 	//Inject standard libs into the vm
 	g.injectStandardLibs(vm, scriptFile, "")
-	g.injectUserFunctions(vm, targetUser, nil, nil)
+	g.injectUserFunctions(vm, scriptFile, "", targetUser, nil, nil)
 
 	//Try to read the script content
 	scriptContent, err := ioutil.ReadFile(scriptFile)

+ 43 - 1
mod/agi/userFunc.go

@@ -3,6 +3,7 @@ package agi
 import (
 	"encoding/json"
 	"errors"
+	"io/ioutil"
 	"log"
 	"net/http"
 	"path/filepath"
@@ -21,7 +22,7 @@ func realpathToVirtualpath(path string, u *user.User) (string, error) {
 }
 
 //Inject user based functions into the virtual machine
-func (g *Gateway) injectUserFunctions(vm *otto.Otto, u *user.User, w http.ResponseWriter, r *http.Request) {
+func (g *Gateway) injectUserFunctions(vm *otto.Otto, scriptFile string, scriptScope string, u *user.User, w http.ResponseWriter, r *http.Request) {
 	username := u.Username
 	vm.Set("USERNAME", username)
 	vm.Set("USERICON", u.GetUserIcon())
@@ -273,4 +274,45 @@ func (g *Gateway) injectUserFunctions(vm *otto.Otto, u *user.User, w http.Respon
 		return otto.FalseValue()
 	})
 
+	//Execd (Execute & detach) run another script and detach the execution
+	vm.Set("execd", func(call otto.FunctionCall) otto.Value {
+		//Check if the pkg is already registered
+		scriptName, err := call.Argument(0).ToString()
+		if err != nil {
+			g.raiseError(err)
+			return otto.FalseValue()
+		}
+
+		//Carry the payload to the forked process if there are any
+		payload, _ := call.Argument(1).ToString()
+
+		//Check if the script file exists
+		targetScriptPath := filepath.ToSlash(filepath.Join(filepath.Dir(scriptFile), scriptName))
+		if !fileExists(targetScriptPath) {
+			g.raiseError(errors.New("*AGI* Target path not exists!"))
+			return otto.FalseValue()
+		}
+
+		//Run the script
+		scriptContent, _ := ioutil.ReadFile(targetScriptPath)
+		go func() {
+			//Create a new VM to execute the script (also for isolation)
+			vm := otto.New()
+			//Inject standard libs into the vm
+			g.injectStandardLibs(vm, scriptFile, scriptScope)
+			g.injectUserFunctions(vm, scriptFile, scriptScope, u, w, r)
+
+			vm.Set("PARENT_DETACHED", true)
+			vm.Set("PARENT_PAYLOAD", payload)
+			_, err = vm.Run(string(scriptContent))
+			if err != nil {
+				//Script execution failed
+				log.Println("Script Execution Failed: ", err.Error())
+				g.raiseError(err)
+			}
+		}()
+
+		return otto.TrueValue()
+	})
+
 }

+ 0 - 1
web/Music/functions/buildCache.js

@@ -32,7 +32,6 @@ for (var i = 0; i < rootDirs.length; i++){
 function buildCache(){
     //Create db if not exists
     newDBTableIfNotExists("AirMusic");
-
      //Do the scanning
      var songData = [];
      var musicFiles = [];

+ 1 - 1
web/Music/functions/common.js

@@ -29,4 +29,4 @@ function bytesToSize(bytes) {
     if (bytes == 0) return '0 Byte';
     var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
     return (bytes / Math.pow(1024, i)).toFixed(2) + ' ' + sizes[i];
- }
+ }

+ 24 - 6
web/Music/functions/listSong.js

@@ -42,11 +42,7 @@ function handleUserRequest(){
         var rootDirs = filelib.glob("/");
         for (var i = 0; i < rootDirs.length; i++){
             var thisRoot = rootDirs[i];
-            /*
-            if (filelib.fileExists(thisRoot + "Music/")){
-                musicDis.push(thisRoot + "Music/");
-            }
-            */
+           
             //Always use all roots
             musicDis.push(thisRoot);
             
@@ -127,11 +123,30 @@ function handleUserRequest(){
                 }));
             
             }else if (listSong.substr(0,7) == "search:"){
+                //Search mode
                 var keyword = listSong.substr(7)
                 var songData = [];
                 for (var i = 0; i < musicDis.length; i++){
                     var thisFileLib = musicDis[i];
-                    var allfilelist = filelib.walk(thisFileLib, "file");
+
+                    //Load the music list from cache to reduce scanning time
+                    var cachedList = readDBItem("AirMusic", "cache");
+                    var allfilelist = [];
+                    if (cachedList == ""){
+                        allfilelist  = filelib.walk(thisFileLib, "file");
+                    }else{
+                        //Try parse it. If parse failed fallback to realtime scanning
+                        try{    
+                            cachedList = JSON.parse(cachedList);
+                            for (var j = 0; j < cachedList.length; j++){
+                                var thisCachedSong = cachedList[j];
+                                allfilelist.push(thisCachedSong[0].replace("/media?file=", ""));
+                            }
+                        }catch(ex){
+                            allfilelist  = filelib.walk(thisFileLib, "file");
+                        }
+                    }
+                    
                     for (var k = 0; k < allfilelist.length; k++){
                         var thisFile = allfilelist[k];
                         var ext = allfilelist[k].split('.').pop();
@@ -161,6 +176,9 @@ function handleUserRequest(){
 
                 //Send resp
                 sendJSONResp(JSON.stringify(songData));
+
+                //Run build cache in background so to update any cache if exists
+                execd("buildCache.js")
             }else{
                 //WIP
                 console.log("listSong type " + listSong + " work in progress")

+ 3 - 2
web/SystemAO/utilities/gcodeViewer.html

@@ -31,7 +31,8 @@
 		<script src="../../script/ao_module.js"></script>
 		<div id="infotab">
 			<p id="filename"></p>
-			<p id="filepath"></p>
+			<p id="filepath" style="display:none;"></p>
+			<p id="displayfilepath"></p>
 			<p id="filesize"></p>
 		</div>
 		<script>
@@ -42,7 +43,7 @@
 				file = files[0];
 				$("#filename").text(file.filename);
 				$("#filepath").text("../../media?file=" + file.filepath);
-
+				$("#displayfilepath").text(file.filepath);
 				//Get filesize info
 				$.ajax({
 					url: "../../system/file_system/getProperties", 

+ 37 - 0
web/UnitTest/backend/execd.js

@@ -0,0 +1,37 @@
+/*
+
+    Execd - Execute after Detach
+
+    This script demonstrate the execd function call
+    USE WITH CAUTION
+
+    Here is a few tips for you to develop a script containing execd
+    1. Do not execute self script unless you are sure about what you are doing
+    2. Instant / short task should be put in the main script while long running 
+    task should be called with execd instead
+
+*/
+
+function parent(){
+    console.log("Parent starting Child Process...")
+    //Execute this script file in child mode with payload string
+    execd("execd.js", "Payload to child")
+    console.log("Parent Completed")
+}
+
+function child(){
+    //Print the payload string
+    console.log("Receiving payload from parent: " + PARENT_PAYLOAD)
+    //Delay (emulate processing something)
+    delay(5000);
+    console.log("Child finished")
+}
+
+if (typeof PARENT_DETACHED == 'undefined'){
+    //This is parent
+    parent();
+
+}else if (PARENT_DETACHED == true){
+    //This is child
+    child();
+}