Browse Source

add svg support

Help-14 3 năm trước cách đây
mục cha
commit
9d350399ca

+ 2 - 2
src/common/data.yaml

@@ -7,7 +7,7 @@ data:
             icon: fa-solid fa-wifi
             icon: fa-solid fa-wifi
             url: https://openwrt.org
             url: https://openwrt.org
           - name: Proxmox
           - name: Proxmox
-            icon: fa-solid fa-rectangle-xmark
+            icon: https://iconape.com/wp-content/files/pk/18549/svg/cib-proxmox.svg
             url: https://www.proxmox.com/en/
             url: https://www.proxmox.com/en/
           - name: Home Assistant
           - name: Home Assistant
             icon: fa-solid fa-house
             icon: fa-solid fa-house
@@ -29,7 +29,7 @@ data:
       - title: Monitoring
       - title: Monitoring
         bookmarks:
         bookmarks:
           - name: Grafana
           - name: Grafana
-            icon: fa-solid fa-server
+            icon: https://iconape.com/wp-content/files/sn/17615/svg/cib-grafana.svg
             url: https://grafana.com
             url: https://grafana.com
           - name: InfluxDb
           - name: InfluxDb
             icon: fa-solid fa-database
             icon: fa-solid fa-database

+ 9 - 7
src/main.go

@@ -1,7 +1,6 @@
 package main
 package main
 
 
 import (
 import (
-	"fmt"
 	"html/template"
 	"html/template"
 	"io/ioutil"
 	"io/ioutil"
 	"log"
 	"log"
@@ -20,14 +19,16 @@ var websiteData = struct {
 	Language modules.Language
 	Language modules.Language
 	Contents []modules.GroupData
 	Contents []modules.GroupData
 }{}
 }{}
+var webTemplate *template.Template
 
 
 func main() {
 func main() {
 	pwd, _ = os.Getwd()
 	pwd, _ = os.Getwd()
 
 
 	dataPath := filepath.Join(pwd, "data")
 	dataPath := filepath.Join(pwd, "data")
 	if _, err := os.Stat(filepath.Join(dataPath, "data.yaml")); os.IsNotExist(err) {
 	if _, err := os.Stat(filepath.Join(dataPath, "data.yaml")); os.IsNotExist(err) {
-		fmt.Println("Copy files to data folder")
-		modules.CopyDirectory(filepath.Join(pwd, "common"), dataPath)
+		log.Println("Copy files to data folder")
+		os.MkdirAll(dataPath, os.ModePerm)
+		modules.CopyDir(filepath.Join(pwd, "common"), dataPath)
 	}
 	}
 
 
 	appConfig = modules.LoadConfig()
 	appConfig = modules.LoadConfig()
@@ -35,7 +36,10 @@ func main() {
 	websiteData.Language = modules.LoadLanguage(appConfig.Website.Language)
 	websiteData.Language = modules.LoadLanguage(appConfig.Website.Language)
 	websiteData.Contents = modules.LoadContent().Data
 	websiteData.Contents = modules.LoadContent().Data
 
 
-	commonfs := http.FileServer(http.Dir(filepath.Join(dataPath, "common")))
+	tmpl, _ := template.ParseFiles(filepath.Join(pwd, "themes", appConfig.Website.Theme, "index.html"))
+	webTemplate = tmpl
+
+	commonfs := http.FileServer(http.Dir(dataPath))
 	http.Handle("/common/", http.StripPrefix("/common/", commonfs))
 	http.Handle("/common/", http.StripPrefix("/common/", commonfs))
 
 
 	languagefs := http.FileServer(http.Dir(filepath.Join(pwd, "languages")))
 	languagefs := http.FileServer(http.Dir(filepath.Join(pwd, "languages")))
@@ -77,7 +81,5 @@ func serveWeather(w http.ResponseWriter, r *http.Request) {
 }
 }
 
 
 func serveTemplate(w http.ResponseWriter, r *http.Request) {
 func serveTemplate(w http.ResponseWriter, r *http.Request) {
-	lp := filepath.Join(pwd, "themes", appConfig.Website.Theme, "index.html")
-	tmpl, _ := template.ParseFiles(lp)
-	tmpl.Execute(w, websiteData)
+	webTemplate.Execute(w, websiteData)
 }
 }

+ 2 - 1
src/modules/config.go

@@ -3,6 +3,7 @@ package modules
 import (
 import (
 	"fmt"
 	"fmt"
 	"io/ioutil"
 	"io/ioutil"
+	"path/filepath"
 
 
 	"gopkg.in/yaml.v2"
 	"gopkg.in/yaml.v2"
 )
 )
@@ -41,7 +42,7 @@ func LoadConfig() Config {
 		Addons: []string{},
 		Addons: []string{},
 	}
 	}
 
 
-	yamlFile, err := ioutil.ReadFile("./common/config.yaml")
+	yamlFile, err := ioutil.ReadFile(filepath.Join("data", "config.yaml"))
 	if err != nil {
 	if err != nil {
 		fmt.Printf("Error reading YAML file: %s\n", err)
 		fmt.Printf("Error reading YAML file: %s\n", err)
 		return defaultConfig
 		return defaultConfig

+ 8 - 2
src/modules/content.go

@@ -4,6 +4,7 @@ import (
 	"fmt"
 	"fmt"
 	"io/ioutil"
 	"io/ioutil"
 	"path/filepath"
 	"path/filepath"
+	"strings"
 
 
 	"gopkg.in/yaml.v2"
 	"gopkg.in/yaml.v2"
 )
 )
@@ -24,14 +25,19 @@ type ColumnData struct {
 
 
 type BookmarkData struct {
 type BookmarkData struct {
 	Name string `yaml:"name"`
 	Name string `yaml:"name"`
-	Icon string `yaml:"icon"`
 	Url  string `yaml:"url"`
 	Url  string `yaml:"url"`
+
+	Icon string `yaml:"icon"`
+}
+
+func (b *BookmarkData) IsSVG() bool {
+	return strings.Contains(b.Icon, ".svg")
 }
 }
 
 
 func LoadContent() ContentData {
 func LoadContent() ContentData {
 	emptyData := ContentData{}
 	emptyData := ContentData{}
 
 
-	yamlFile, err := ioutil.ReadFile(filepath.Join("common", "data.yaml"))
+	yamlFile, err := ioutil.ReadFile(filepath.Join("data", "data.yaml"))
 	if err != nil {
 	if err != nil {
 		fmt.Printf("Error reading YAML file: %s\n", err)
 		fmt.Printf("Error reading YAML file: %s\n", err)
 		return emptyData
 		return emptyData

+ 75 - 15
src/modules/file.go

@@ -1,33 +1,93 @@
 package modules
 package modules
 
 
 import (
 import (
+	"fmt"
 	"io"
 	"io"
-	"log"
 	"os"
 	"os"
-	"os/exec"
 )
 )
 
 
-func CopyFile(src, dst string) {
-	fin, err := os.Open(src)
+// func CopyFile(src, dst string) {
+// 	fin, err := os.Open(src)
+// 	if err != nil {
+// 		log.Fatal(err)
+// 	}
+// 	defer fin.Close()
+
+// 	fout, err := os.Create(dst)
+// 	if err != nil {
+// 		log.Fatal(err)
+// 	}
+// 	defer fout.Close()
+
+// 	_, err = io.Copy(fout, fin)
+
+// 	if err != nil {
+// 		log.Fatal(err)
+// 	}
+// }
+
+// func CopyDirectory(oldDir, newDir string) {
+// 	cmd := exec.Command("cp", "--recursive", oldDir, newDir)
+// 	cmd.Run()
+// }
+
+func CopyFile(source string, dest string) (err error) {
+	sourcefile, err := os.Open(source)
 	if err != nil {
 	if err != nil {
-		log.Fatal(err)
+		return err
 	}
 	}
-	defer fin.Close()
 
 
-	fout, err := os.Create(dst)
+	defer sourcefile.Close()
+
+	destfile, err := os.Create(dest)
 	if err != nil {
 	if err != nil {
-		log.Fatal(err)
+		return err
 	}
 	}
-	defer fout.Close()
 
 
-	_, err = io.Copy(fout, fin)
+	defer destfile.Close()
+
+	_, err = io.Copy(destfile, sourcefile)
+	if err == nil {
+		sourceinfo, err := os.Stat(source)
+		if err != nil {
+			err = os.Chmod(dest, sourceinfo.Mode())
+		}
 
 
-	if err != nil {
-		log.Fatal(err)
 	}
 	}
+	return
 }
 }
 
 
-func CopyDirectory(oldDir, newDir string) {
-	cmd := exec.Command("cp", "--recursive", oldDir, newDir)
-	cmd.Run()
+func CopyDir(source string, dest string) (err error) {
+	// get properties of source dir
+	sourceinfo, err := os.Stat(source)
+	if err != nil {
+		return err
+	}
+
+	// create dest dir
+	err = os.MkdirAll(dest, sourceinfo.Mode())
+	if err != nil {
+		return err
+	}
+
+	directory, _ := os.Open(source)
+	objects, err := directory.Readdir(-1)
+	for _, obj := range objects {
+		sourcefilepointer := source + "/" + obj.Name()
+		destinationfilepointer := dest + "/" + obj.Name()
+		if obj.IsDir() {
+			// create sub-directories - recursively
+			err = CopyDir(sourcefilepointer, destinationfilepointer)
+			if err != nil {
+				fmt.Println(err)
+			}
+		} else {
+			// perform copy
+			err = CopyFile(sourcefilepointer, destinationfilepointer)
+			if err != nil {
+				fmt.Println(err)
+			}
+		}
+	}
+	return
 }
 }

+ 7 - 0
src/themes/flame/css/magma.css

@@ -82,6 +82,13 @@ body {
   vertical-align: middle;
   vertical-align: middle;
 }
 }
 
 
+.group-items .svg-icon {
+  vertical-align: middle;
+  fill: var(--foreground) !important;
+  width: 32px !important;
+  height: 32px !important;
+}
+
 .group-items a:hover {
 .group-items a:hover {
   background-color: rgba(0, 0, 0, 0.3) !important;
   background-color: rgba(0, 0, 0, 0.3) !important;
   cursor: pointer;
   cursor: pointer;

+ 18 - 0
src/themes/flame/index.html

@@ -17,6 +17,19 @@
     <link rel="stylesheet" href="/common/css/core.css">
     <link rel="stylesheet" href="/common/css/core.css">
     <link rel="stylesheet" href="/theme/css/magma.css">
     <link rel="stylesheet" href="/theme/css/magma.css">
     <link rel="stylesheet" href="/common/css/custom.css">
     <link rel="stylesheet" href="/common/css/custom.css">
+
+    <script>
+        customElements.define("svg-file", class extends HTMLElement {
+            async connectedCallback(
+                src = this.getAttribute("src"),
+                shadowRoot = this.shadowRoot || this.attachShadow({mode:"open"})
+            ) {
+                shadowRoot.innerHTML = await (await fetch(src)).text()
+                shadowRoot.append(...this.querySelectorAll("[shadowRoot]"))
+                this.hasAttribute("replaceWith") && this.replaceWith(...shadowRoot.childNodes)
+            }
+        })
+    </script>
 </head>
 </head>
 
 
 <body>
 <body>
@@ -53,7 +66,11 @@
                         {{range .Bookmarks}}
                         {{range .Bookmarks}}
                             <a href="{{.Url}}">
                             <a href="{{.Url}}">
                                 <div class="icon-container">
                                 <div class="icon-container">
+                                {{if .IsSVG}}
+                                    <svg-file src="{{.Icon}}" class="svg-icon"></svg-file>
+                                {{else}}
                                     <i class="{{.Icon}} fa-xl icon"></i>
                                     <i class="{{.Icon}} fa-xl icon"></i>
+                                {{end}}
                                 </div>
                                 </div>
                                 <h6>{{.Name}}</h6>
                                 <h6>{{.Name}}</h6>
                             </a>
                             </a>
@@ -145,6 +162,7 @@
             document.querySelector("#humidity").innerText = Math.floor(weather.main.humidity) + "%";
             document.querySelector("#humidity").innerText = Math.floor(weather.main.humidity) + "%";
             document.querySelector("#weather-info").style.visibility = "visible";
             document.querySelector("#weather-info").style.visibility = "visible";
         })();
         })();
+    });
     </script>
     </script>
     <script src="/common/js/custom.js"></script>
     <script src="/common/js/custom.js"></script>
 </body>
 </body>