commit 26ff2bb7237b5abbc0978cf0b269ddbd20467f9d
parent 601ea12d68287e7674e71da71370037c73ab4e55
Author: weetat <wtenison@protonmail.com>
Date: Mon, 24 Feb 2025 03:13:12 +0000
Split main into filesystem and network packages
Also move script.js and styles.css into web/global so other pages can
share them.
Diffstat:
6 files changed, 267 insertions(+), 198 deletions(-)
diff --git a/src/filesystem/filesystem.go b/src/filesystem/filesystem.go
@@ -0,0 +1,139 @@
+package filesystem
+
+import (
+ "bytes"
+ "fmt"
+ "log"
+ "os"
+ "path/filepath"
+ "regexp"
+
+ "github.com/goccy/go-yaml"
+)
+
+var FilePatternHTML = regexp.MustCompile("^([a-zA-Z0-9.]+).html$")
+
+var Paths struct {
+ RootDirectory string
+ WebDirectory string
+}
+
+var GlobalPkg DirectoryPackage
+
+type DirectorySignature struct {
+ Root string // The root directoy of the resource.
+ DependencyDepth int // The folder search depth of the resource. -1=inf, 0=single, >0=n-depth
+ DependencyPattern *regexp.Regexp // The pattern of valid resource dependency files.
+}
+
+type DirectoryPackage struct {
+ Root string // The root directory of the resource.
+ DependencyFiles []string // The set of valid resource files.
+ DependencyData IDirectoryData // Any relevant resource data.
+}
+
+type IDirectoryData interface {
+}
+
+func MakeDirectorySig(directory string, depth int, pattern *regexp.Regexp) (DirectorySignature, error) {
+
+ if directory == "" || depth < -1 || pattern == nil {
+ return DirectorySignature{}, fmt.Errorf("invalid directory signature (%s, %d, %s)", directory, depth, pattern)
+ }
+
+ if _, _err := os.Stat(directory); _err != nil {
+ return DirectorySignature{}, _err
+ }
+
+ return DirectorySignature{directory, depth, pattern}, nil
+}
+
+func MakeDirectoryPkg(resSig DirectorySignature) (DirectoryPackage, error) {
+
+ // Check and collect resource signature directory files.
+ _files, _err := os.ReadDir(resSig.Root)
+ if _err != nil {
+ return DirectoryPackage{}, _err
+ }
+
+ _resPkg := DirectoryPackage{
+ Root: resSig.Root,
+ DependencyFiles: []string{},
+ DependencyData: nil,
+ }
+
+ _resFileDirDeps := []string{}
+
+ // Collete all valid files and/or sub-directory files.
+ for _, _f := range _files {
+
+ if _f.IsDir() && (resSig.DependencyDepth > 0 || resSig.DependencyDepth == -1) {
+ // Recurse into valid sub-directory files.
+
+ _resDirSig, _err := MakeDirectorySig(_f.Name(), resSig.DependencyDepth, resSig.DependencyPattern)
+ if _err != nil {
+ return DirectoryPackage{}, _err
+ }
+
+ _resDirPkg, _err := MakeDirectoryPkg(_resDirSig)
+ if _err != nil {
+ return DirectoryPackage{}, _err
+ }
+
+ _resFileDirDeps = append(_resFileDirDeps, _resDirPkg.DependencyFiles...)
+
+ } else if resSig.DependencyPattern != nil && resSig.DependencyPattern.MatchString(_f.Name()) {
+ // Add files that match pattern to dependency list.
+
+ _resPkg.DependencyFiles = append(_resPkg.DependencyFiles, filepath.Join(_resPkg.Root, _f.Name()))
+ }
+ }
+
+ // Include any sub-directory file dependencies.
+ _resPkg.DependencyFiles = append(_resPkg.DependencyFiles, _resFileDirDeps...)
+
+ log.Printf("INFO\tMakeDirectoryPkg:%v\n", _resPkg)
+ return _resPkg, nil
+}
+
+func GetYamlContent(yamlObjectId string, dataContainerReference any) {
+
+ _byteBuffer := bytes.NewBufferString(yamlObjectId)
+
+ _decoder := yaml.NewDecoder(_byteBuffer, yaml.ReferenceDirs("sys"))
+ if _err := _decoder.Decode(dataContainerReference); _err != nil {
+ // NOTE: Not a sustainable solution for error handling long-term.
+ // TODO: Implement error handling to gracefully exit during runtime.
+ log.Panicln("__PANIC\tmain:GetYamlContent:" + _err.Error())
+ }
+
+ log.Printf("DONE\tmain:GetYamlContent:%v\n", dataContainerReference)
+}
+
+func Init() {
+
+ //// PULL SYSTEM INFO FROM YAML
+
+ var _mfilesys struct {
+ FileSystemInfo struct {
+ RootDir string
+ WebDir string
+ }
+ }
+ GetYamlContent("filesysteminfo: *fs\n", &_mfilesys)
+
+ Paths.RootDirectory = _mfilesys.FileSystemInfo.RootDir
+ Paths.WebDirectory = _mfilesys.FileSystemInfo.WebDir
+
+ //// GET GLOBAL DIRECTORY RESOURCES
+
+ _globalSig, _err := MakeDirectorySig(filepath.Join(Paths.WebDirectory, "/global"), 0, FilePatternHTML)
+ if _err != nil {
+ log.Panicf("__PANIC\tnetwork:Init:MakeDirectorySig:%s", _err)
+ }
+
+ GlobalPkg, _err = MakeDirectoryPkg(_globalSig)
+ if _err != nil {
+ log.Panicf("__PANIC\tnetwork:Init:MakeDirectoryPkg:%s", _err)
+ }
+}
diff --git a/src/miki/miki.go b/src/miki/miki.go
@@ -1,204 +1,13 @@
package main
import (
- "bytes"
- // "context"
- "fmt"
- "html/template"
- "log"
- "net/http"
- "os"
- "path/filepath"
- "regexp"
-
- "github.com/goccy/go-yaml"
- // "go.mongodb.org/mongo-driver/v2/mongo"
- // "go.mongodb.org/mongo-driver/v2/mongo/options"
+ mfs "miki/src/filesystem"
+ mnw "miki/src/network"
)
-type DirectorySignature struct {
- root string // The root directoy of the resource.
- dependencyDepth int // The folder search depth of the resource. -1=inf, 0=single, >0=n-depth
- dependencyPattern *regexp.Regexp // The pattern of valid resource dependency files.
-}
-
-func MakeDirectorySig(dir string, depth int, pattern *regexp.Regexp) (DirectorySignature, error) {
-
- if dir == "" || depth < -1 || pattern == nil {
- return DirectorySignature{}, fmt.Errorf("invalid directory signature (%s, %d, %s)", dir, depth, pattern)
- }
-
- if _, _err := os.Stat(dir); _err != nil {
- return DirectorySignature{}, _err
- }
-
- return DirectorySignature{dir, depth, pattern}, nil
-}
-
-type DirectoryPackage struct {
- root string // The root directory of the resource.
- dependencyFiles []string // The set of valid resource files.
- dependencyData IDirectoryData // Any relevant resource data.
-}
-
-type IDirectoryData interface {
-}
-
-func MakeDirectoryPkg(resSig DirectorySignature) (DirectoryPackage, error) {
-
- // Check and collect resource signature directory files.
- _files, _err := os.ReadDir(resSig.root)
- if _err != nil {
- return DirectoryPackage{}, _err
- }
-
- _resPkg := DirectoryPackage{
- root: resSig.root,
- dependencyFiles: []string{},
- dependencyData: nil,
- }
-
- _resFileDirDeps := []string{}
-
- // Collete all valid files and sub directory files.
- for _, _f := range _files {
-
- if _f.IsDir() && (resSig.dependencyDepth > 0 || resSig.dependencyDepth == -1) {
- // Recurse into valid directory files.
-
- _resDirSig, _err := MakeDirectorySig(_f.Name(), resSig.dependencyDepth, resSig.dependencyPattern)
- if _err != nil {
- return DirectoryPackage{}, _err
- }
-
- _resDirPkg, _err := MakeDirectoryPkg(_resDirSig)
- if _err != nil {
- return DirectoryPackage{}, _err
- }
-
- _resFileDirDeps = append(_resFileDirDeps, _resDirPkg.dependencyFiles...)
-
- } else if resSig.dependencyPattern != nil && resSig.dependencyPattern.MatchString(_f.Name()) {
- // Add files that match pattern to dependency list.
- _resPkg.dependencyFiles = append(_resPkg.dependencyFiles, filepath.Join(_resPkg.root, _f.Name()))
- }
- }
-
- // Add any sub directory file dependencies.
- _resPkg.dependencyFiles = append(_resPkg.dependencyFiles, _resFileDirDeps...)
-
- return _resPkg, nil
-}
-
-func GetYamlContent(yamlObjectId string, dataContainerReference any) {
-
- _byteBuffer := bytes.NewBufferString(yamlObjectId)
-
- _decoder := yaml.NewDecoder(_byteBuffer, yaml.ReferenceDirs("sys"))
- if _err := _decoder.Decode(dataContainerReference); _err != nil {
- // NOTE: Not a sustainable solution for error handling long-term.
- // TODO: Implement error handling to gracefully exit during runtime.
- log.Panicln("__PANIC\tmain:GetYamlContent:" + _err.Error())
- }
-
- log.Printf("DONE\tmain:GetYamlContent:%v\n", dataContainerReference)
-}
-
func main() {
+ mfs.Init()
- ////////// PULL SYSTEM INFO FROM YAML //////////
-
- var _mfilesys struct {
- FileSystemInfo struct {
- RootDir string
- WebDir string
- }
- }
- GetYamlContent("filesysteminfo: *fs\n", &_mfilesys)
-
- var _msrvinfo struct {
- ServerInfo struct {
- Port string
- SslPath string
- CertFile string
- KeyFile string
- }
- }
- GetYamlContent("serverinfo: *si\n", &_msrvinfo)
-
- ////////// CHECK FOR VALID CERT INFO //////////
-
- _tls_cert_path := filepath.Join(_msrvinfo.ServerInfo.SslPath, _msrvinfo.ServerInfo.CertFile)
- if _, err := os.Stat(_tls_cert_path); err != nil {
- log.Panicf("__PANIC\tmain:%s", err)
- }
-
- _tls_key_path := filepath.Join(_msrvinfo.ServerInfo.SslPath, _msrvinfo.ServerInfo.KeyFile)
- if _, err := os.Stat(_tls_key_path); err != nil {
- log.Panicf("__PANIC\tmain:%s", err)
- }
-
- ////////// SET UP SERVER MUX //////////
-
- _mux := http.NewServeMux()
-
- _mux.Handle("/web/", http.StripPrefix("/web/", http.FileServer(http.Dir(_mfilesys.FileSystemInfo.WebDir))))
-
- _mux.HandleFunc("/favicon.ico", func(w http.ResponseWriter, r *http.Request) {
- // log.Printf("CALL\tmain:mux.HandleFunc:%s\n", r.URL)
- http.ServeFile(w, r, _mfilesys.FileSystemInfo.WebDir+"/global/favicon.ico")
- // log.Printf("DONE\tmain:mux.HandleFunc:%s\n", r.URL)
- })
-
- _mux.HandleFunc("/home", func(w http.ResponseWriter, r *http.Request) {
- log.Printf("CALL\tmain:mux.HandleFunc:%s\n", r.URL)
-
- // Produce URL path to directory relation.
- _r, _err := MakeDirectorySig(_mfilesys.FileSystemInfo.WebDir+"/home", 0, regexp.MustCompile("^([a-zA-Z0-9.]+).html$"))
- if _err != nil {
- log.Printf("_ERROR\tmain:HandleFunc(\"/\"):MakeResourceSig():%s\n", _err)
- http.NotFound(w, r)
- return
- }
-
- // Collect HTML template files from directory.
- _rPkg, _err := MakeDirectoryPkg(_r)
- if _err != nil {
- log.Printf("_ERROR\tmain:HandleFunc(\"/\"):MakeResourcePkg():%s\n", _err)
- http.NotFound(w, r)
- return
- }
-
- _tmpl, _err := template.ParseFiles(_rPkg.dependencyFiles...)
- if _err != nil {
- log.Printf("_ERROR\tmain:HandleFunc(\"/\"):MakeResourcePkg():%s\n", _err)
- http.Error(w, "_ERROR:HandleFunc(\"/\"):template.ParseFiles()", 500)
- return
- }
-
- if _err = _tmpl.ExecuteTemplate(w, "index.html", _rPkg.dependencyData); _err != nil {
- log.Printf("_ERROR\tmain:HandleFunc(\"/\"):MakeResourcePkg():%s\n", _err)
- http.Error(w, "_ERROR:HandleFunc(\"/\"):template.ExecuteTemplate()", 500)
- return
- }
-
- log.Printf("DONE\tmain:mux.HandleFunc:%s\n", r.URL)
- })
-
- _mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
- // log.Printf("CALL\tmain:mux.HandleFunc:%s\n", r.URL)
- if r.URL.Path == "/" {
- http.Redirect(w, r, "/home", http.StatusMovedPermanently)
- return
- } else {
- http.NotFound(w, r)
- }
- // log.Printf("DONE\tmain:mux.HandleFunc:%s\n", r.URL)
- })
-
- ////////// RUN SERVERS //////////
-
- if _err := http.ListenAndServeTLS(":"+_msrvinfo.ServerInfo.Port, _tls_cert_path, _tls_key_path, _mux); _err != nil {
- fmt.Printf("_ERROR\tmain():ListenAndServeTLS:%s\n", _err)
- }
+ mnw.Init()
+ mnw.Exec()
}
diff --git a/src/network/network.go b/src/network/network.go
@@ -0,0 +1,121 @@
+package network
+
+import (
+ "fmt"
+ "log"
+ "net/http"
+ "os"
+ "path/filepath"
+ "text/template"
+
+ mfs "miki/src/filesystem"
+)
+
+var serverInfo struct {
+ port string
+ sslPath string
+ certFile string
+ keyFile string
+}
+
+var mux *http.ServeMux
+
+func Init() {
+
+ //// GET SERVER INFO
+
+ var _msrvinfo struct {
+ ServerInfo struct {
+ Port string
+ SslPath string
+ CertFile string
+ KeyFile string
+ }
+ }
+ mfs.GetYamlContent("serverinfo: *si\n", &_msrvinfo)
+ serverInfo.port = _msrvinfo.ServerInfo.Port
+ serverInfo.sslPath = _msrvinfo.ServerInfo.SslPath
+ serverInfo.certFile = filepath.Join(serverInfo.sslPath, _msrvinfo.ServerInfo.CertFile)
+ serverInfo.keyFile = filepath.Join(serverInfo.sslPath, _msrvinfo.ServerInfo.KeyFile)
+
+ //// CHECK FOR VALID CERT INFO
+
+ _tls_cert_path := filepath.Join(_msrvinfo.ServerInfo.SslPath, _msrvinfo.ServerInfo.CertFile)
+ if _, err := os.Stat(_tls_cert_path); err != nil {
+ log.Panicf("__PANIC\tmain:%s", err)
+ }
+
+ _tls_key_path := filepath.Join(_msrvinfo.ServerInfo.SslPath, _msrvinfo.ServerInfo.KeyFile)
+ if _, err := os.Stat(_tls_key_path); err != nil {
+ log.Panicf("__PANIC\tmain:%s", err)
+ }
+
+ //// SET UP SERVER MUX
+
+ mux = http.NewServeMux()
+
+ mux.Handle("/web/", http.StripPrefix("/web/", http.FileServer(http.Dir(mfs.Paths.WebDirectory))))
+
+ mux.HandleFunc("/favicon.ico", func(w http.ResponseWriter, r *http.Request) {
+ // log.Printf("CALL\tmain:mux.HandleFunc:%s\n", r.URL)
+ http.ServeFile(w, r, mfs.Paths.WebDirectory+"/global/favicon.ico")
+ // log.Printf("DONE\tmain:mux.HandleFunc:%s\n", r.URL)
+ })
+
+ mux.HandleFunc("/home", func(w http.ResponseWriter, r *http.Request) {
+ log.Printf("CALL\tmain:mux.HandleFunc:%s\n", r.URL)
+
+ // Produce URL path to directory relation.
+ _r, _err := mfs.MakeDirectorySig(mfs.Paths.WebDirectory+"/home", 0, mfs.FilePatternHTML)
+ if _err != nil {
+ log.Printf("_ERROR\tmain:HandleFunc(\"/\"):MakeResourceSig():%s\n", _err)
+ http.NotFound(w, r)
+ return
+ }
+
+ // Collect HTML template files from directory.
+ _rPkg, _err := mfs.MakeDirectoryPkg(_r)
+ if _err != nil {
+ log.Printf("_ERROR\tmain:HandleFunc(\"/\"):MakeResourcePkg():%s\n", _err)
+ http.NotFound(w, r)
+ return
+ }
+
+ _rPkg.DependencyFiles = append(_rPkg.DependencyFiles, mfs.GlobalPkg.DependencyFiles...)
+
+ _tmpl, _err := template.ParseFiles(_rPkg.DependencyFiles...)
+ if _err != nil {
+ log.Printf("_ERROR\tmain:HandleFunc(\"/\"):MakeResourcePkg():%s\n", _err)
+ http.Error(w, "_ERROR:HandleFunc(\"/\"):template.ParseFiles()", 500)
+ return
+ }
+
+ if _err = _tmpl.ExecuteTemplate(w, "index.html", _rPkg.DependencyData); _err != nil {
+ log.Printf("_ERROR\tmain:HandleFunc(\"/\"):MakeResourcePkg():%s\n", _err)
+ http.Error(w, "_ERROR:HandleFunc(\"/\"):template.ExecuteTemplate()", 500)
+ return
+ }
+
+ log.Printf("DONE\tmain:mux.HandleFunc:%s\n", r.URL)
+ })
+
+ mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
+ // log.Printf("CALL\tmain:mux.HandleFunc:%s\n", r.URL)
+ if r.URL.Path == "/" {
+ http.Redirect(w, r, "/home", http.StatusMovedPermanently)
+ return
+ } else {
+ http.NotFound(w, r)
+ }
+ // log.Printf("DONE\tmain:mux.HandleFunc:%s\n", r.URL)
+ })
+}
+
+func Exec() {
+
+ //// RUN SERVER
+
+ if _err := http.ListenAndServeTLS(":"+serverInfo.port, serverInfo.certFile, serverInfo.keyFile, mux); _err != nil {
+ fmt.Printf("_ERROR\tmain():ListenAndServeTLS:%s\n", _err)
+ }
+}
diff --git a/web/home/script.js b/web/global/script.js
diff --git a/web/home/styles.css b/web/global/styles.css
diff --git a/web/home/index.html b/web/home/index.html
@@ -4,8 +4,8 @@
<head>
<title>Miki</title>
<meta name="viewport" charset="utf-8" content="width=device-width, initial-scale=1.0" />
- <link rel="stylesheet" type="text/css" href="/web/home/styles.css" />
- <script src="/web/home/script.js" defer></script>
+ <link rel="stylesheet" type="text/css" href="/web/global/styles.css" />
+ <script src="/web/global/styles.css" defer></script>
</head>
<body>