Browse Source

Removed FFMpeg Factory and Message (WIP)

Toby Chui 2 years ago
parent
commit
75ea2c7bfb
46 changed files with 68 additions and 927 deletions
  1. 0 4
      README.md
  2. 0 67
      installer/install_for_pi.sh
  3. 1 1
      src/main.flags.go
  4. 14 5
      src/mod/agi/agi.go
  5. 3 2
      src/mod/agi/external.agi.go
  6. 1 1
      src/mod/time/scheduler/scheduler.go
  7. 1 1
      src/mod/www/www.go
  8. 0 5
      src/web/FFmpeg Factory/README.txt
  9. 0 64
      src/web/FFmpeg Factory/backend/convert.js
  10. 0 8
      src/web/FFmpeg Factory/backend/readConfig.js
  11. 0 14
      src/web/FFmpeg Factory/backend/writeConfig.js
  12. 0 11
      src/web/FFmpeg Factory/config/i2i.json
  13. 0 6
      src/web/FFmpeg Factory/config/other.json
  14. 0 12
      src/web/FFmpeg Factory/config/v2a.json
  15. 0 16
      src/web/FFmpeg Factory/config/v2v.json
  16. BIN
      src/web/FFmpeg Factory/img/desktop_icon.png
  17. BIN
      src/web/FFmpeg Factory/img/desktop_icon.psd
  18. BIN
      src/web/FFmpeg Factory/img/module_icon.png
  19. BIN
      src/web/FFmpeg Factory/img/module_icon.psd
  20. BIN
      src/web/FFmpeg Factory/img/small_icon.png
  21. BIN
      src/web/FFmpeg Factory/img/small_icon.psd
  22. 0 267
      src/web/FFmpeg Factory/index.html
  23. 0 30
      src/web/FFmpeg Factory/init.agi
  24. 0 1
      src/web/FFmpeg Factory/jquery.min.js
  25. 0 0
      src/web/FFmpeg Factory/tocas.css
  26. 0 62
      src/web/Message/backend/rpc.js
  27. 0 156
      src/web/Message/chat.html
  28. BIN
      src/web/Message/img/desktop_icon.png
  29. BIN
      src/web/Message/img/desktop_icon.psd
  30. BIN
      src/web/Message/img/logo.png
  31. BIN
      src/web/Message/img/module_icon.png
  32. BIN
      src/web/Message/img/module_icon.psd
  33. BIN
      src/web/Message/img/noicon.png
  34. BIN
      src/web/Message/img/noicon.psd
  35. BIN
      src/web/Message/img/small_icon.png
  36. BIN
      src/web/Message/img/small_icon.psd
  37. 0 104
      src/web/Message/index.html
  38. 0 20
      src/web/Message/init.agi
  39. 0 34
      src/web/Message/message.js
  40. 1 1
      src/web/Serverless/index.html
  41. 1 1
      src/web/SystemAO/file_system/file_operation.html
  42. 0 21
      src/web/SystemAO/info/license/Tocas UI.txt
  43. 15 1
      src/web/SystemAO/internalServerError.html
  44. 15 1
      src/web/SystemAO/notfound.html
  45. 1 1
      src/web/desktop.system
  46. 15 10
      src/web/script/ao_module.js

+ 0 - 4
README.md

@@ -2,10 +2,6 @@
 
 <img src="https://img.shields.io/badge/License-GPLv3-blue"> <img src="https://img.shields.io/badge/Device-Raspberry%20Pi%203B%2B%20%2F%204B-red"> <img src="https://img.shields.io/badge/Made%20In%20Hong%20Kong-香港開發-blueviolet">
 
-## README is update pending
-
-This is a copy of the ArozOS v1.0 readme file. We didn't have time to update this yet so please do not following the instruction below to compile ArozOS 2.0. (We recommend using make if you want to try the latest version on any devices)  
-
 ## Features
 
 ### User Interface

+ 0 - 67
installer/install_for_pi.sh

@@ -1,67 +0,0 @@
-#!/bin/bash
-
-# Automatic install script for ArozOS - by tobychui
-# For internal use only, All Right Reserved
-echo "[ArozOS Installer]"
-echo "Updating apt"
-sudo apt upgrade -y
-sudo apt-get update -y
-sudo apt-get install ffmpeg samba git net-tools -y
-
-echo "Cloning ArozOS from source"
-git clone https://github.com/tobychui/arozos
-
-echo "Installing Golang"
-arch=$(uname -m)
-gover="1.17.6"
-if [[ $arch == x86_64* ]]; then
-    echo "Selecting x64 Architecture"
-    wget https://golang.org/dl/go$gover.linux-amd64.tar.gz
-elif  [[ $arch == arm* ]]; then
-    echo "Selecting ARM Architecture"
-    wget https://golang.org/dl/go$gover.linux-armv6l.tar.gz
-elif  [[ $arch == "aarch64" ]]; then
-    echo "Selecting ARM64 Architecture"
-    wget https://golang.org/dl/go$gover.linux-arm64.tar.gz
-elif [[ $arch == "unknown" ]]; then
-    echo "Unknown CPU arch. Please enter CPU architecture manually (arm/arm64/amd64)"
-    read -p "Architecture: " arch
-    if [ "$arch" = "arm" ]; then
-        echo "Installing arm version of go"
-        wget https://golang.org/dl/go$gover.linux-armv6l.tar.gz
-    fi
-    if [ "$arch" = "arm64" ]; then
-	echo "Installing arm64 version of go"
-	wget https://golang.org/dl/go$gover.linux-arm64.tar.gz
-    fi
-
-    if [ "$arch" = "amd64" ]; then
-	echo "Installing amd64 version of go"
-	wget https://golang.org/dl/go$gover.linux-amd64.tar.gz
-    fi
-fi
-sudo tar -C /usr/local -xzf go*
-echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
-PATH=$PATH:/usr/local/go/bin
-
-echo "Building ArozOS"
-cd arozos
-sudo chmod 777 -R ./
-cd src
-go mod tidy
-go build
-
-echo "Setting up system services"
-sudo systemctl enable systemd-networkd.service systemd-networkd-wait-online.service
-cd /etc/systemd/system/
-
-printf "[Unit]\nDescription=ArozOS Cloud Service\nAfter=systemd-networkd-wait-online.service\nWants=systemd-networkd-wait-online.service\n\n[Service]\nType=simple\nExecStartPre=/bin/sleep 10\nWorkingDirectory=/home/$USER/arozos/src/\nExecStart=/bin/bash /home/$USER/arozos/src/start.sh\n\nRestart=always\nRestartSec=10\n\n[Install]\nWantedBy=multi-user.target" | sudo tee -a ./arozos.service
-
-echo "Registering systemctl service"
-sudo systemctl start arozos.service
-
-echo "Starting arozos"
-sudo systemctl enable arozos.service
-
-thisip=$(hostname -I | cut -d' ' -f1)
-echo "Installation completed. Visit ArozOS web UI with http://$thisip:8080"

+ 1 - 1
src/main.flags.go

@@ -29,7 +29,7 @@ var subserviceBasePort = 12810            //Next subservice port
 
 // =========== SYSTEM BUILD INFORMATION ==============
 var build_version = "development"                      //System build flag, this can be either {development / production / stable}
-var internal_version = "0.2.015"                       //Internal build version, [fork_id].[major_release_no].[minor_release_no]
+var internal_version = "0.2.016"                       //Internal build version, [fork_id].[major_release_no].[minor_release_no]
 var deviceUUID string                                  //The device uuid of this host
 var deviceVendor = "IMUSLAB.INC"                       //Vendor of the system
 var deviceVendorURL = "http://imuslab.com"             //Vendor contact information

+ 14 - 5
src/mod/agi/agi.go

@@ -291,7 +291,7 @@ func (g *Gateway) ExecuteAGIScript(scriptContent string, fsh *filesystem.FileSys
 	//Detect cotent type
 	contentType := r.Header.Get("Content-type")
 	if strings.Contains(contentType, "application/json") {
-		//For shitty people who use Angular
+		//For people who use Angular
 		body, _ := io.ReadAll(r.Body)
 		fields := map[string]interface{}{}
 		json.Unmarshal(body, &fields)
@@ -338,11 +338,11 @@ func (g *Gateway) ExecuteAGIScript(scriptContent string, fsh *filesystem.FileSys
 }
 
 /*
-Execute AGI script with given user information
-scriptFile must be realpath resolved by fsa VirtualPathToRealPath function
-Pass in http.Request pointer to enable serverless GET / POST request
+	Execute AGI script with given user information
+	scriptFile must be realpath resolved by fsa VirtualPathToRealPath function
+	Pass in http.Request pointer to enable serverless GET / POST request
 */
-func (g *Gateway) ExecuteAGIScriptAsUser(fsh *filesystem.FileSystemHandler, scriptFile string, targetUser *user.User, r *http.Request) (string, error) {
+func (g *Gateway) ExecuteAGIScriptAsUser(fsh *filesystem.FileSystemHandler, scriptFile string, targetUser *user.User, w http.ResponseWriter, r *http.Request) (string, error) {
 	//Create a new vm for this request
 	vm := otto.New()
 	//Inject standard libs into the vm
@@ -397,6 +397,15 @@ func (g *Gateway) ExecuteAGIScriptAsUser(fsh *filesystem.FileSystemHandler, scri
 		return "", err
 	}
 
+	if w != nil {
+		//Serverless: Get respond header type from the vm
+		header, _ := vm.Get("HTTP_HEADER")
+		headerString, _ := header.ToString()
+		if headerString != "" {
+			w.Header().Set("Content-Type", headerString)
+		}
+	}
+
 	valueString, err := value.ToString()
 	if err != nil {
 		return "", err

+ 3 - 2
src/mod/agi/external.agi.go

@@ -63,14 +63,15 @@ func (g *Gateway) ExtAPIHandler(w http.ResponseWriter, r *http.Request) {
 	// execute!
 	start := time.Now()
 	//g.ExecuteAGIScript(scriptContent, "", "", w, r, userInfo)
-	result, err := g.ExecuteAGIScriptAsUser(fsh, realPath, userInfo, r)
+	result, err := g.ExecuteAGIScriptAsUser(fsh, realPath, userInfo, w, r)
 	duration := time.Since(start)
 
 	if err != nil {
 		utils.SendErrorResponse(w, err.Error())
 		return
 	}
-	utils.SendTextResponse(w, result)
+
+	w.Write([]byte(result))
 
 	log.Println("[Remote AGI] IP:", r.RemoteAddr, " executed the script ", pathFromDb, "(", realPath, ")", " on behalf of", userInfo.Username, "with total duration: ", duration)
 

+ 1 - 1
src/mod/time/scheduler/scheduler.go

@@ -138,7 +138,7 @@ func (a *Scheduler) createTicker(duration time.Duration) chan bool {
 								//Resolve the sript path to realpath
 								//Run the script with this user scope
 								thisJob.lastExecutionTime = time.Now().Unix()
-								resp, err := a.options.Gateway.ExecuteAGIScriptAsUser(fsh, rpath, targetUser, nil)
+								resp, err := a.options.Gateway.ExecuteAGIScriptAsUser(fsh, rpath, targetUser, nil, nil)
 								if err != nil {
 									a.cronlogError(thisJob.Name+" execution error: "+err.Error(), err)
 									thisJob.lastExecutionOutput = err.Error()

+ 1 - 1
src/mod/www/www.go

@@ -146,7 +146,7 @@ func (h *Handler) RouteRequest(w http.ResponseWriter, r *http.Request) {
 
 	//Execute it if it is agi file
 	if fsh.FileSystemAbstraction.FileExists(targetFilePath) && filepath.Ext(targetFilePath) == ".agi" {
-		result, err := h.Options.AgiGateway.ExecuteAGIScriptAsUser(fsh, targetFilePath, userinfo, r)
+		result, err := h.Options.AgiGateway.ExecuteAGIScriptAsUser(fsh, targetFilePath, userinfo, w, r)
 		if err != nil {
 			w.Write([]byte("500 - Internal Server Error \n" + err.Error()))
 			return

+ 0 - 5
src/web/FFmpeg Factory/README.txt

@@ -1,5 +0,0 @@
-This is a wrapper for FFmpeg. Licensed under MIT (Not under FFmpeg)
-Also, the FFmpeg main binary (or program if you wanna call it like that) is licensed under GNU and it is under its own folder (ffmpeg-{version_number}-win32-static). Please read the license.txt for more information on the license.
-
-Wrapper written by Toby Chui feat. IMUS Laboratory under ArOZ Online Project Beta
-Learn more at http://imuslab.com/. 

+ 0 - 64
src/web/FFmpeg Factory/backend/convert.js

@@ -1,64 +0,0 @@
-/*
-    FFmpeg Factory ArOZ JavaScript Gateway Interface Converter
-
-    This script will launch ffmpeg and convert a given file into the desired format
-*/
-//Require library
-requirelib("filelib");
-
-//Globaal variables
-var targetFilepath = filepath;
-var conversionCommand = command;
-
-//Helper function to get the filepath.Dir of the realpath
-function dir(filepath){
-	filepath = filepath.split("/");
-	filepath.pop();
-	return filepath.join("/");
-}
-
-//Return the filename of the path without extension
-function base(filepath){
-    filepath = filepath.split("\\").join("/");
-    filepath = filepath.split("/");
-    filename = filepath.pop();
-    filename = filename.split(".")
-    filename.pop();
-    return filename.join(".");
-}
-
-//Package required. Get the real path of the file
-if (filelib.fileExists(targetFilepath)){
-    var srcReal = decodeVirtualPath(targetFilepath);
-    srcReal = srcReal.split("\\").join("/");
-
-    //Parse the command for the conversion
-    var actualCommand = decodeURIComponent(command);
-    actualCommand = actualCommand.replace('{filepath}',srcReal);
-    actualCommand = actualCommand.replace('{filename}',dir(srcReal) + "/" + base(srcReal))
-
-    //Register this task in on-going task list
-    newDBTableIfNotExists("FFmpeg Factory")
-    var ts = Math.round((new Date()).getTime() / 1000);
-    var taskKey = USERNAME + "/" + ts;
-    writeDBItem("FFmpeg Factory",taskKey,targetFilepath)
-
-    //Pass the command into ffmpeg pkg
-    var results = execpkg("ffmpeg",actualCommand);
-
-    //Deregister this task from on-going task list
-    deleteDBItem("FFmpeg Factory",taskKey,targetFilepath);
-
-    sendJSONResp(JSON.stringify({
-        status: "ok",
-        execresults: results
-    }));
-
-   
-
-}else{
-    //File not exists. Return an error json
-    sendJSONResp(JSON.stringify({
-        error: "File not exists: " + targetFilepath
-    }));
-}

+ 0 - 8
src/web/FFmpeg Factory/backend/readConfig.js

@@ -1,8 +0,0 @@
-if (newDBTableIfNotExists("FFmpeg Factory")){
-	var value = readDBItem("FFmpeg Factory",USERNAME + "_" + key);
-	sendResp(value);
-}else{
-	sendJSONResp(JSON.stringify({
-		error: "Database Creation Failed"
-	}));
-}

+ 0 - 14
src/web/FFmpeg Factory/backend/writeConfig.js

@@ -1,14 +0,0 @@
-if (newDBTableIfNotExists("FFmpeg Factory")){
-	if (writeDBItem("FFmpeg Factory",USERNAME + "_" + key,value)){
-		sendJSONResp(JSON.stringify("OK"));
-	}else{
-		sendJSONResp(JSON.stringify({
-			error: "Database write failed"
-		}));
-	}
-	
-}else{
-	sendJSONResp(JSON.stringify({
-		error: "Database Creation Failed"
-	}));
-}

+ 0 - 11
src/web/FFmpeg Factory/config/i2i.json

@@ -1,11 +0,0 @@
-{
-    "PNG(Default)": "-y -i \"{filepath}\" \"{filename}.png\"",
-    "PNG(High Quality)": "-y -i \"{filepath}\" -compression_level 0 \"{filename}.png\"",
-    "PNG(Low Quality)": "-y -i \"{filepath}\" -compression_level 200 \"{filename}.png\"",
-    "JPG(Default)": "-y -i \"{filepath}\" \"{filename}.jpg\"",
-    "JPG(High Quality)": "-y -i \"{filepath}\" -compression_level 0 \"{filename}.jpg\"",
-    "JPG(Low Quality)": "-y -i \"{filepath}\" -compression_level 200 \"{filename}.jpg\"",
-    "GIF": "-y -i \"{filepath}\" \"{filename}.gif\"",
-    "BMP": "-y -i \"{filepath}\" \"{filename}.bmp\"",
-    "TIF(TIFF)": "-y -i \"{filepath}\" \"{filename}.tif\""
-}

+ 0 - 6
src/web/FFmpeg Factory/config/other.json

@@ -1,6 +0,0 @@
-{
-	"MP4 to GIF": "-y -i \"{filepath}\" -f gif \"{filename}.gif\"",
-	"GIF to MP4": "-y -i \"{filepath}\" -f mp4 -pix_fmt yuv420p \"{filename}.mp4\"",
-	"SRT to ASS": "-y -i \"{filepath}\" \"{filename}.ass\"",
-	"ASS to SRT": "-y -i \"{filepath}\" -c:s srt \"{filename}.srt\""
-}

+ 0 - 12
src/web/FFmpeg Factory/config/v2a.json

@@ -1,12 +0,0 @@
-{
-    "MP3(Default)": "-y -i \"{filepath}\" \"{filename}.mp3\"",
-    "MP3(320 Kbps)": "-y -i \"{filepath}\" -b:a 320k \"{filename}.mp3\"",
-    "MP3(256 Kbps)": "-y -i \"{filepath}\" -b:a 256k \"{filename}.mp3\"",
-    "MP3(192 Kbps)": "-y -i \"{filepath}\" -b:a 192k \"{filename}.mp3\"",
-    "MP3(128 Kbps)": "-y -i \"{filepath}\" -b:a 128k \"{filename}.mp3\"",
-    "AAC(Default)": "-y -i \"{filepath}\" -strict experimental \"{filename}.aac\"",
-    "AAC(codec copy)": "-i \"{filepath}\" -vn -acodec copy \"{filename}.aac\"",
-    "FLAC": "-y -i \"{filepath}\" \"{filename}.flac\"",
-    "OGG": "-y -i \"{filepath}\" \"{filename}.ogg\"",
-    "WAV": "-y -i \"{filepath}\" \"{filename}.wav\""
-}

+ 0 - 16
src/web/FFmpeg Factory/config/v2v.json

@@ -1,16 +0,0 @@
-{
-    "MP4(Default)": "-y -i \"{filepath}\" \"{filename}.mp4\"",
-    "MP4(1080p)": "-y -i \"{filepath}\" -s hd1080 -c:v libx264 -crf 23 -c:a aac -strict -2 \"{filename}.mp4\"",
-    "MP4(720p)": "-y -i \"{filepath}\" -s hd720 -c:v libx264 -crf 23 -c:a aac -strict -2 \"{filename}.mp4\"",
-    "MP4(480p)": "-y -i \"{filepath}\" -s hd480 -c:v libx264 -crf 23 -c:a aac -strict -2 \"{filename}.mp4\"",
-    "AVI(Default)": "-y -i \"{filepath}\" -q:v 2 \"{filename}.avi\"",
-    "AVI(Low Quality)": "-y -i \"{filepath}\" -q:v 6 \"{filename}.avi\"",
-    "AVI(High Quality)": "-y -i \"{filepath}\" -q:v 0 \"{filename}.avi\"",
-    "AVI(codec copy)": "-y -i \"{filepath}\" -vcodec copy -acodec copy \"{filename}.avi\"",
-    "WebM": "-y -i \"{filepath}\" -c:v libvpx -crf 10 -b:v 1M -c:a libvorbis \"{filename}.webm\"",
-    "WMV": "-y -i \"{filepath}\" \"{filename}.wmv\"",
-    "FLV": "-y -i \"{filepath}\" \"{filename}.flv\"",
-    "MKV(Default)": "-y -i \"{filepath}\" \"{filename}.mkv\"",
-    "MKV(codec copy)": "-y -i \"{filepath}\" -vcodec copy -acodec copy \"{filename}.mkv\"",
-    "MOV": "-y -i \"{filepath}\" \"{filename}.mov\""
-}

BIN
src/web/FFmpeg Factory/img/desktop_icon.png


BIN
src/web/FFmpeg Factory/img/desktop_icon.psd


BIN
src/web/FFmpeg Factory/img/module_icon.png


BIN
src/web/FFmpeg Factory/img/module_icon.psd


BIN
src/web/FFmpeg Factory/img/small_icon.png


BIN
src/web/FFmpeg Factory/img/small_icon.psd


File diff suppressed because it is too large
+ 0 - 267
src/web/FFmpeg Factory/index.html


+ 0 - 30
src/web/FFmpeg Factory/init.agi

@@ -1,30 +0,0 @@
-/*
-	FFmpeg Factory
-	CopyRight tobychui 2020 - 2021
-
-	This is a port of the ArOZ Online Beta FFmpeg Factory to the ArOZ Online 1.0
-	If you are running on Windows, ffmpeg must be installed in your %PATH% environment 
-	variable before you can actually use this module.
-*/
-
-//Define the launchInfo for the module
-var moduleLaunchInfo = {
-    Name: "FFmpeg Factory",
-	Group: "Media",
-	IconPath: "FFmpeg Factory/img/small_icon.png",
-	Version: "2.0",
-	StartDir: "FFmpeg Factory/index.html",
-	SupportFW: true,
-	LaunchFWDir: "FFmpeg Factory/index.html",
-	InitFWSize: [1150, 640],
-	SupportedExt: [".avi",".mp4",".mp3",".aac",".flac"]
-}
-
-//Request ffmpeg for this module
-if (requirepkg("ffmpeg",true)){
-	//Register the module
-	registerModule(JSON.stringify(moduleLaunchInfo));
-}else{
-	console.log("FFMPEG not found! Not enabling FFmpeg Factory");
-}
-

File diff suppressed because it is too large
+ 0 - 1
src/web/FFmpeg Factory/jquery.min.js


File diff suppressed because it is too large
+ 0 - 0
src/web/FFmpeg Factory/tocas.css


+ 0 - 62
src/web/Message/backend/rpc.js

@@ -1,62 +0,0 @@
-/*
-    rpc.js
-
-    This script do the following stuffs
-    - set a user online status 
-    - get the latest message id (if channel id is given)
-    - set a user state (if channel id is given)
-
-    Required paramters:
-    channel (optional): Channel ID
-    userstate (optional): {typing / standby / uploading}
-*/
-
-var username = USERNAME;
-newDBTableIfNotExists("message")
-
-//Set this user last online time
-writeDBItem("message", "online_status/" + username, Math.floor(Date.now() / 1000));
-
-//Check if channel id is defined
-if (typeof(channel) != "undefined" && channel != ""){
-    //In channel. Get the ID out of this user pair
-    var channelID = channel + "_" + username;
-    if (username < channel){
-        channelID = username + "_" + channel
-    }
-
-    //Get opposite online time if exists
-    var oppositeOnlineTime = readDBItem("message", "online_status/" + channel)
-    if (oppositeOnlineTime != ""){
-        oppositeOnlineTime = parseInt(oppositeOnlineTime);
-    }else{
-        oppositeOnlineTime = -1;
-    }
-
-    //Prepare the data structure to be returned
-    var resultingStruct = {
-        latestMessageId: "",
-        oppositeLastOnlineTime: oppositeOnlineTime,
-        oppositeStatus: ""
-    };
-
-    
-    //Check the latest message id
-    var latestMessage = readDBItem("message", "latest_id/" + channelID);
-    var message = [];
-    if (latestMessage == ""){
-        //No message 
-
-    }else{
-        resultingStruct.latestMessageId = latestMessage;
-    }
-
-    sendJSONResp(resultingStruct);
-
-}else if (typeof(group) != "undefined" && group != ""){
-    //Group function, to be developed
-
-}else{
-    //Homepage. Show all chat updates
-
-}

+ 0 - 156
src/web/Message/chat.html

@@ -1,156 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta charset="UTF-8">
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"/>
-		<meta name="theme-color" content="#4b75ff">
-		<link rel="stylesheet" href="../script/semantic/semantic.min.css">
-		<script src="../script/jquery.min.js"></script>
-		<script src="../script/ao_module.js"></script>
-		<script src="../script/semantic/semantic.min.js"></script>
-        <script src="message.js"></script>
-		<link rel="icon" type="image/png" href="img/module_icon.png">
-		<link rel="manifest" crossorigin="use-credentials" href="manifest.json">
-		<title>Message</title>
-		<style>
-			body{
-                background-color: rgb(250, 250, 250);
-			}  
-
-            .chatdialog{
-                width: 100%;
-                display: flex;
-                padding-top: 0.4em;
-            }   
-
-            .self.chatdialog{
-                justify-content: end;
-            }
-
-            .other.chatdialog{
-                justify-content: start;
-            }
-
-            .chatbubble{
-                max-width: 70%;
-            }
-
-            .self.chatdialog .chatbubble{
-                background: rgb(98,135,254);
-                background: linear-gradient(120deg, rgba(98,135,254,1) 37%, rgba(67,202,231,1) 100%); 
-                
-                color: white;
-            }
-
-            .other.chatdialog .chatbubble{
-                
-            }
-
-            .chatbubble{
-                display: inline-block !important;
-                padding: 7px !important;
-                padding-left: 12px !important;
-                padding-right: 12px !important;
-            }
-
-            .chatbubble p{
-                margin-right: 2em;
-            }
-
-            .chatbubble .timestamp{
-                float: right;
-            }
-            .chatbubble .timestampWrapper{
-                height: 1em;
-            }
-            .sendbar{
-                position: fixed;
-                bottom: 0;
-                left: 0;
-                width: 100%;
-                padding: 0.4em;
-            }
-		</style>
-	</head>
-	<body>
-        <div class="ui segment" stlye="padding-top: 1em;">
-            <div style="width: 100%; height: 0.3em;"></div>
-            <img id="usericon" class="ui avatar mini image" style="margin-top: -0.7em; " src="img/noicon.png">
-            <div style="display: inline-block; font-size: 1.5rem; margin-left: 0.2em;"><i id="onlineStatus"></i><span id="username">Username</span></div>
-        </div>
-		<div id="chatroom" class="ui text container">
-            <!-- 
-			<div class="self chatdialog">
-                <div class="ui segment chatbubble">
-                    <p>Hello World! How are you today?</p>
-                    <div class="timestampWrapper">
-                        <small class="timestamp">4 Jan 14:25</small>
-                    </div>
-                </div>
-            </div>
-            <div class="other chatdialog">
-                <div class="ui segment chatbubble">
-                    <p>Good, thanks!</p>
-                    <div class="timestampWrapper">
-                        <small class="timestamp">4 Jan 14:25</small>
-                    </div>
-                </div>
-            </div>
-            -->
-		</div>
-        <div class="sendbar">
-            <div class="ui fluid action input">
-                <input id="msgInput" type="text" placeholder="Aa">
-                <button class="ui icon button" style="background-color: #608cfc; color: white;"><i class="chevron right icon"></i></button>
-            </div>
-        </div>
-		
-		<br><br>
-		<script>
-            var username = "";
-			if (window.location.hash.length > 1){
-                username = window.location.hash.substr(1);
-                $("#username").text(username);
-
-                //Get the user icon
-                $.get("../system/users/list", function(data){
-					console.log(data);
-					data.forEach(function(user){
-						let thisUsername = user[0];
-						let usericon = user[2];
-                        if (thisUsername == username){
-                            $("#usericon").attr('src', usericon);
-                        }
-                    });
-                });
-
-                //Update the channel id, see message.js
-                channelID = username;
-                
-            }
-
-
-            function updateUserOnlineStatus(lastOnlineTimestamp){
-                var currentTime = Math.floor(Date.now() / 1000);
-                if (currentTime - lastOnlineTimestamp > 300){
-                    //Offline
-                    $("#onlineStatus").attr("class", "grey small circle icon");
-                }else{
-                    //Online
-                    $("#onlineStatus").attr("class", "green small circle icon");
-                }
-            }
-
-            //RPC callback events
-            rpcCallback = function(data){
-                console.log(data);
-                updateUserOnlineStatus(data.oppositeLastOnlineTime);
-            }
-
-            //Manually start the first request on page load
-            updateStatus();
-            
-		</script>
-	</body>
-</html>

BIN
src/web/Message/img/desktop_icon.png


BIN
src/web/Message/img/desktop_icon.psd


BIN
src/web/Message/img/logo.png


BIN
src/web/Message/img/module_icon.png


BIN
src/web/Message/img/module_icon.psd


BIN
src/web/Message/img/noicon.png


BIN
src/web/Message/img/noicon.psd


BIN
src/web/Message/img/small_icon.png


BIN
src/web/Message/img/small_icon.psd


+ 0 - 104
src/web/Message/index.html

@@ -1,104 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta charset="UTF-8">
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"/>
-		<meta name="theme-color" content="#4b75ff">
-		<link rel="stylesheet" href="../script/semantic/semantic.min.css">
-		<script src="../script/jquery.min.js"></script>
-		<script src="../script/ao_module.js"></script>
-		<script src="../script/semantic/semantic.min.js"></script>
-		<link rel="icon" type="image/png" href="img/module_icon.png">
-		<link rel="manifest" crossorigin="use-credentials" href="manifest.json">
-		<title>Message</title>
-		<style>
-			body{
-                background-color: rgb(250, 250, 250);
-			}
-
-			#banner{
-				background: rgb(74,179,255);
-				background: linear-gradient(153deg, rgba(74,179,255,1) 0%, rgba(182,183,247,1) 52%, rgba(133,87,255,1) 100%); 
-				padding: 1.2em;
-				-webkit-border-bottom-right-radius: 20px;
-				-webkit-border-bottom-left-radius: 20px;
-				-moz-border-radius-bottomright: 20px;
-				-moz-border-radius-bottomleft: 20px;
-				border-bottom-right-radius: 20px;
-				border-bottom-left-radius: 20px;
-				margin-bottom: 0.4em;
-			}
-
-			#banner h2{
-				color: white;
-			}
-
-			.latestMessage{
-				color: rgb(43, 40, 40);
-			}
-
-			.chatroom{
-				cursor: pointer;
-				transition: opacity 0.1s ease-in-out;
-			}
-
-			.chatroom:hover{
-				opacity: 0.7;
-			}
-		</style>
-	</head>
-	<body>
-        <div id="banner">
-			<div class="ui container">
-				<h2>Message</h2>
-
-				<div class="ui fluid small icon input">
-					<input type="text" placeholder="Search">
-					<i class="circular search link icon"></i>
-				</div>
-			</div>
-		</div>
-		<div id="chatHistoryList" class="ui container">
-			
-		</div>
-		<div class="ui divider"></div>
-		<br><br>
-		<script>
-			function initUserList(){
-				$.get("../system/users/list", function(data){
-					console.log(data);
-					data.forEach(function(user){
-						let username = user[0];
-						let usericon = user[2];
-						if (usericon == ""){
-							usericon = "img/noicon.png";
-						}
-						let chatroomID = username;
-						$("#chatHistoryList").append(`<div class="ui message chatroom">
-						<a class="ui feed" href="chat.html#${chatroomID}">
-							<div class="event">
-								<div class="label" style="padding-top: 0.3em;">
-									<img src="${usericon}">
-								</div>
-							<div class="content" style="margin-top: 0; position: relative;">
-								<div class="summary">
-									<h3 style="margin-bottom: 0; font-size: 1.2em;">${username}</h3>
-									<small class="latestMessage">
-										(No Message)
-									</small>
-								</div>
-								<div class="date" style="position: absolute; right: 0;top:0;">
-									Offline
-								</div>
-							</div>
-							</div>
-						</a>
-					</div>`);
-					})
-				});
-			}
-			initUserList();
-		</script>
-	</body>
-</html>

+ 0 - 20
src/web/Message/init.agi

@@ -1,20 +0,0 @@
-/*
-	Message - Quick chatroom tool for ArozOS
-*/
-
-//Setup the module information
-var moduleLaunchInfo = {
-    Name: "Message",
-	Desc: "Maybe the best messenging app on ArozOS",
-	Group: "Office",
-	IconPath: "Message/img/module_icon.png",
-	Version: "1.0",
-	StartDir: "Message/index.html",
-	SupportFW: true,
-	InitFWSize: [340, 630],
-	SupportedExt: []
-}
-
-
-//Register the module
-registerModule(JSON.stringify(moduleLaunchInfo));

+ 0 - 34
src/web/Message/message.js

@@ -1,34 +0,0 @@
-/*
-    Common Message app Tools
-*/
-
-//Current watching channel, leave empty for all
-var channelID = "";
-var userstate = "standby"; //standby / typing / uploading
-//Current status return data from last rpc
-var statusData = {};
-var rpcCallback = undefined;
-
-//Setup timer to update the above two paramters
-setInterval(function(){
-    updateStatus();
-}, 5000);
-
-//Call this function on start
-function updateStatus(){
-    var messageInputValue = $("#msgInput").val();
-    if (messageInputValue.trim() != ""){
-        userstate = "typing";
-    }else{
-        userstate = "standby";
-    }
-    ao_module_agirun("Message/backend/rpc.js", {
-        channel: channelID,
-        userstate: userstate
-    }, function(data){
-        statusData = data;
-        if (rpcCallback != undefined){
-            rpcCallback(data);
-        }
-    });
-}

+ 1 - 1
src/web/Serverless/index.html

@@ -121,7 +121,7 @@
             });
 
             function openfileselector(){
-                ao_module_openFileSelector(fileLoader, "user:/", "file",false, {filter:["agi"]});
+                ao_module_openFileSelector(fileLoader, "user:/", "file",false, {filter:["agi", "js"]});
             }
 
 

+ 1 - 1
src/web/SystemAO/file_system/file_operation.html

@@ -831,7 +831,7 @@
             }
 
             function showPauseCancelButton(){
-                ao_module_setWindowSize(400,244);
+                ao_module_setWindowSize(400,254);
                 $("#progressbar").parent().css({
                     "margin-bottom":"1em"
                 });

+ 0 - 21
src/web/SystemAO/info/license/Tocas UI.txt

@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2018 Yami Odymel
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.

+ 15 - 1
src/web/SystemAO/internalServerError.html

@@ -37,7 +37,7 @@
             <div>
                 <h3 class="">Internal Server Error</h3>
                 <div class="ui divider"></div>
-                <p>Unable to serve the requested page due to some unknown backend error. <br><a href="{{root_escape}}">Back</a></p>
+                <p>Unable to serve the requested page due to some unknown backend error. <br><a style="cursor: pointer;" onclick="back();">Back</a></p>
                 <div class="ui divider"></div>
                 <div style="text-align: left;">
                     <small>Request time: <span id="reqtime"></span></small><br>
@@ -46,6 +46,20 @@
             </div>
         </div>
         <script>
+             var ao_module_virtualDesktop = false;
+            try{
+                ao_module_virtualDesktop = !(!parent.isDesktopMode);
+            }catch(ex){
+                
+            }
+
+            function back(){
+                if (ao_module_virtualDesktop){
+                    history.back();
+                }else{
+                    window.location.href = "{{root_escape}}";
+                }
+            }
             $("#reqtime").text(new Date().toLocaleString(undefined, {year: 'numeric', month: '2-digit', day: '2-digit', weekday:"long", hour: '2-digit', hour12: false, minute:'2-digit', second:'2-digit'}));
         </script>
     </body>

+ 15 - 1
src/web/SystemAO/notfound.html

@@ -37,7 +37,7 @@
             <div>
                 <h3 class="">Page Not Found</h3>
                 <div class="ui divider"></div>
-                <p>The page or resource you are trying to access does not exist. <br><a href="{{root_escape}}">Back</a></p>
+                <p>The page or resource you are trying to access does not exist. <br><a style="cursor: pointer;" onclick="back();">Back</a></p>
                 <div class="ui divider"></div>
                 <div style="text-align: left;">
                     <small>Request time: <span id="reqtime"></span></small><br>
@@ -46,6 +46,20 @@
             </div>
         </div>
         <script>
+            var ao_module_virtualDesktop = false;
+            try{
+                ao_module_virtualDesktop = !(!parent.isDesktopMode);
+            }catch(ex){
+                
+            }
+
+            function back(){
+                if (ao_module_virtualDesktop){
+                    history.back();
+                }else{
+                    window.location.href = "{{root_escape}}";
+                }
+            }
             $("#reqtime").text(new Date().toLocaleString(undefined, {year: 'numeric', month: '2-digit', day: '2-digit', weekday:"long", hour: '2-digit', hour12: false, minute:'2-digit', second:'2-digit'}));
         </script>
     </body>

+ 1 - 1
src/web/desktop.system

@@ -1480,7 +1480,7 @@
                     return a.ID > b.ID;
                 });
 
-                console.log(tasks);
+                //console.log(tasks);
                 $("#backgroundTaskPanel").html("");
                 tasks.forEach(function(task){
                     console.log(task);

+ 15 - 10
src/web/script/ao_module.js

@@ -771,16 +771,21 @@ class ao_module_codec{
 
 
 /**
-ArOZ Online Module Utils for quick deploy of ArOZ Online WebApps
-
-ao_module_utils.objectToAttr(object); //object to DOM attr
-ao_module_utils.attrToObject(attr); //DOM attr to Object
-ao_module_utils.getRandomUID(); //Get random UUID from timestamp
-ao_module_utils.getIconFromExt(ext); //Get icon tag from file extension
-
-ao_module_utils.getDropFileInfo(dropEvent); //Get the filepath and filename list from file explorer drag drop
-ao_module_utils.formatBytes(byte, decimals); //Format file byte size to human readable size
-ao_module_utils.timeConverter(unix_timestamp); //Get human readable timestamp 
+    ArOZ Online Module Utils for quick deploy of ArOZ Online WebApps
+
+    ao_module_utils.objectToAttr(object); //object to DOM attr
+    ao_module_utils.attrToObject(attr); //DOM attr to Object
+    ao_module_utils.getRandomUID(); //Get random UUID from timestamp
+    ao_module_utils.getIconFromExt(ext); //Get icon tag from file extension
+    ao_module_utils.stringToBlob(text, mimetype="text/plain") //Convert string to blob
+    ao_module_utils.blobToFile(blob, filename, mimetype="text/plain") //Convert blob to file
+    ao_module_utils.getDropFileInfo(dropEvent); //Get the filepath and filename list from file explorer drag drop
+    ao_module_utils.readFileFromFileObject(fileObject, successCallback, failedCallback=undefined) //Read file object as text
+    ao_module_utils.durationConverter(seconds) //Convert duration in seconds to Days / Hours / Minutes / Seconds
+    ao_module_utils.formatBytes(byte, decimals); //Format file byte size to human readable size
+    ao_module_utils.timeConverter(unix_timestamp); //Get human readable timestamp 
+    ao_module_utils.getWebSocketEndpoint() //Build server websocket endpoint root, e.g. wss://192.168.1.100:8080/
+    ao_module_utils.formatBytes(bytes, decimalPlace=2) //Convert and rounds bytes into KB, MB, GB or TB
 **/
 class ao_module_utils{
     

Some files were not shown because too many files changed in this diff