Add export, improve config saving
This commit is contained in:
parent
f50f4f1919
commit
8a571dbee8
5 changed files with 94 additions and 15 deletions
8
TODO.md
8
TODO.md
|
@ -1,13 +1,11 @@
|
|||
# TODO
|
||||
List of things to add to this project
|
||||
|
||||
## Crucial
|
||||
* Add export feature
|
||||
* Use reflection in config loading
|
||||
* Check export function for improvements
|
||||
* Add missing frontend pages
|
||||
* More slog.Debug?
|
||||
|
||||
## Long-medium term considerations
|
||||
* Make the CLI better
|
||||
* Make the CLI multi-functional - export to path, edit file etc.
|
||||
* Think about timezones
|
||||
* Consider more secure auth methods
|
||||
* *Go* dependency-less? <-- this is a terrible idea
|
24
config.go
24
config.go
|
@ -6,6 +6,7 @@ import (
|
|||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
@ -13,18 +14,25 @@ import (
|
|||
var ConfigFile = "config/config.txt"
|
||||
|
||||
type Config struct {
|
||||
Username string
|
||||
Password string
|
||||
Port int
|
||||
Username string `config:"username"`
|
||||
Password string `config:"password"`
|
||||
Port int `config:"port"`
|
||||
|
||||
TelegramToken string
|
||||
TelegramChat string
|
||||
TelegramToken string `config:"tg_token"`
|
||||
TelegramChat string `config:"tg_chat"`
|
||||
}
|
||||
|
||||
func (c *Config) Save() error {
|
||||
output := fmt.Sprintf("port=%d\nusername=%s\npassword=%s", c.Port, c.Username, c.Password)
|
||||
if c.TelegramToken != "" && c.TelegramChat != "" {
|
||||
output += fmt.Sprintf("\ntg_token=%s\ntg_chat=%s", c.TelegramToken, c.TelegramChat)
|
||||
output := ""
|
||||
|
||||
v := reflect.ValueOf(*c)
|
||||
typeOfS := v.Type()
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
key := typeOfS.Field(i).Tag.Get("config")
|
||||
value := v.Field(i).Interface()
|
||||
if value != "" {
|
||||
output += fmt.Sprintf("%s=%v\n", key, value)
|
||||
}
|
||||
}
|
||||
|
||||
f, err := os.OpenFile(ConfigFile, os.O_CREATE|os.O_WRONLY, 0644)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
port=7101
|
||||
username=admin
|
||||
password=admin
|
||||
password=admin
|
||||
port=7101
|
||||
|
|
71
export.go
Normal file
71
export.go
Normal file
|
@ -0,0 +1,71 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"io"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
var ExportPath = "data/export.zip"
|
||||
|
||||
func Export(filename string) error {
|
||||
file, err := os.Create(filename)
|
||||
if err != nil {
|
||||
slog.Error("error creating export archive", "error", err)
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
w := zip.NewWriter(file)
|
||||
defer w.Close()
|
||||
|
||||
walker := func(path string, info os.FileInfo, err error) error {
|
||||
if path == filename { // Do not add export .zip itself
|
||||
return nil
|
||||
}
|
||||
slog.Debug("export crawling", "path", path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
f, err := w.Create(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = io.Copy(f, file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
err = filepath.Walk("data/", walker)
|
||||
if err != nil {
|
||||
slog.Error("error walking files", "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetExport returns a .zip archive with contents of the data folder
|
||||
func GetExport(w http.ResponseWriter, r *http.Request) {
|
||||
err := Export(ExportPath)
|
||||
if err != nil {
|
||||
http.Error(w, "could not export", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
http.ServeFile(w, r, "data/export.zip")
|
||||
}
|
2
serve.go
2
serve.go
|
@ -41,6 +41,8 @@ func Serve() {
|
|||
apiRouter.Get("/today", GetToday)
|
||||
apiRouter.Post("/today", PostToday)
|
||||
|
||||
apiRouter.Get("/export", GetExport)
|
||||
|
||||
r.Mount("/api", apiRouter)
|
||||
|
||||
// Static files
|
||||
|
|
Loading…
Reference in a new issue