Add export, improve config saving

This commit is contained in:
Andrew-71 2024-03-23 15:36:01 +03:00
parent f50f4f1919
commit 8a571dbee8
5 changed files with 94 additions and 15 deletions

View file

@ -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

View file

@ -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)

View file

@ -1,3 +1,3 @@
port=7101
username=admin
password=admin
password=admin
port=7101

71
export.go Normal file
View 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")
}

View file

@ -41,6 +41,8 @@ func Serve() {
apiRouter.Get("/today", GetToday)
apiRouter.Post("/today", PostToday)
apiRouter.Get("/export", GetExport)
r.Mount("/api", apiRouter)
// Static files