]> git.feebdaed.xyz Git - gomehub.git/commitdiff
Add log audit
authorseantywork <seantywork@gmail.com>
Fri, 26 Jul 2024 08:15:12 +0000 (17:15 +0900)
committerseantywork <seantywork@gmail.com>
Fri, 26 Jul 2024 08:15:12 +0000 (17:15 +0900)
15 files changed:
.gitattributes
Makefile
ctl/config.go
ctl/ctl.go
data/.gitignore
data/log/.gitignore [new file with mode: 0644]
data/log/README.md [new file with mode: 0644]
pkg/auth/session.go
pkg/dbquery/dbquery.go [deleted file]
pkg/dbquery/dbquery_fs.go [new file with mode: 0644]
pkg/log/log.go [new file with mode: 0644]
pkg/manage/manage.go [new file with mode: 0644]
public/js/mypage/index.js
view/index/index.html
view/mypage/index.html

index 633218059de6c230612df026ca584e4c6f5b940d..e0764170e27985a359ed7ab807ae1249cf06d6ee 100644 (file)
@@ -1,4 +1,3 @@
 * linguist-vendored
 *.go linguist-vendored=false
-*.js linguist-vendored
 *.sh linguist-vendored=false
index cc5d74025398a267967e4e90294a826416556cea..b4fefe2094152a8e1ed4448b775b088a4d064a7d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -23,6 +23,8 @@ clean-data:
        rm -rf data/media/video/*.json data/media/video/*.mp4
        rm -rf data/session/*.json 
        rm -rf data/user/*.json
+       rm -rf data/log/*.txt
+       rm -rf data/log/*.json
 
 
 clean:
index 9600f3a570bcc257c9dbd9b13e4f07a1bd5b7cad..3045c287382d43549be9b49379f52887d312f553 100644 (file)
@@ -42,6 +42,9 @@ type SOLIAGAIN_CONFIG struct {
                RtpReceivePort         int    `yaml:"rtpReceivePort"`
                RtpReceivePortExternal int    `yaml:"rtpReceivePortExternal"`
        } `yaml:"stream"`
+       Log struct {
+               FlushIntervalSec int `yaml:"flushIntervalSec"`
+       } `yaml:"log"`
        Utils struct {
                UseCompress bool `yaml:"useCompress"`
        } `yaml:"utils"`
index 9d11b94adb4914bcf66c679c6b2f9e82fb5f8733..a2f263b28af21762f46d33efa42bb3bfaac4a400 100644 (file)
@@ -9,6 +9,8 @@ import (
        pkgauth "github.com/seantywork/sorrylinus-again/pkg/auth"
        pkgcom "github.com/seantywork/sorrylinus-again/pkg/com"
        pkgedition "github.com/seantywork/sorrylinus-again/pkg/edition"
+       pkglog "github.com/seantywork/sorrylinus-again/pkg/log"
+       pkgman "github.com/seantywork/sorrylinus-again/pkg/manage"
        pkgsoli "github.com/seantywork/sorrylinus-again/pkg/sorrylinus"
        pkgstream "github.com/seantywork/sorrylinus-again/pkg/stream"
        pkgutils "github.com/seantywork/sorrylinus-again/pkg/utils"
@@ -94,6 +96,8 @@ func ConfigureRuntime(e *gin.Engine) {
        pkgstream.RTP_RECEIVE_PORT = fmt.Sprintf("%d", CONF.Stream.RtpReceivePort)
        pkgstream.RTP_RECEIVE_PORT_EXTERNAL = fmt.Sprintf("%d", CONF.Stream.RtpReceivePortExternal)
 
+       pkglog.FLUSH_INTERVAL_SEC = CONF.Log.FlushIntervalSec
+
        pkgutils.USE_COMPRESS = CONF.Utils.UseCompress
 
 }
@@ -204,4 +208,12 @@ func RegisterRoutes(e *gin.Engine) {
        }
 
        go pkgcom.StartAllChannelHandlers()
+
+       // manage
+
+       e.GET("/api/manage/log/flush", pkgman.GetManualLogFlush)
+
+       // log
+
+       pkglog.InitLog()
 }
index 9826870ea4704952d55cf05203545724160b44c8..62e15902fcf3314f09b3845f1c64c59938e69c04 100644 (file)
@@ -2,4 +2,5 @@
 *.jpg
 *.jpeg
 *.png
-*.mp4
\ No newline at end of file
+*.mp4
+*.txt
\ No newline at end of file
diff --git a/data/log/.gitignore b/data/log/.gitignore
new file mode 100644 (file)
index 0000000..9826870
--- /dev/null
@@ -0,0 +1,5 @@
+*.json
+*.jpg
+*.jpeg
+*.png
+*.mp4
\ No newline at end of file
diff --git a/data/log/README.md b/data/log/README.md
new file mode 100644 (file)
index 0000000..e69de29
index 48ded9e60c60cab94b6bd41b441e5ec19e0f1bfc..bfd71853567c4975a87e8a4f68aa7f3a266c276f 100644 (file)
@@ -1,11 +1,13 @@
 package auth
 
 import (
+       "encoding/json"
        "fmt"
 
        "github.com/gin-gonic/contrib/sessions"
        "github.com/gin-gonic/gin"
        "github.com/seantywork/sorrylinus-again/pkg/dbquery"
+       pkglog "github.com/seantywork/sorrylinus-again/pkg/log"
 )
 
 func WhoAmI(c *gin.Context) (string, string, string) {
@@ -20,6 +22,24 @@ func WhoAmI(c *gin.Context) (string, string, string) {
 
        var session_id string
 
+       route_key := c.Request.URL.Path
+
+       header, err := json.Marshal(c.Request.Header)
+
+       var header_string string
+
+       if err != nil {
+
+               header_string = err.Error()
+
+       } else {
+
+               header_string = string(header)
+
+       }
+
+       pkglog.PushLog(route_key, header_string)
+
        v := session.Get("SOLIAGAIN")
 
        if v == nil {
diff --git a/pkg/dbquery/dbquery.go b/pkg/dbquery/dbquery.go
deleted file mode 100644 (file)
index 86c29dd..0000000
+++ /dev/null
@@ -1,932 +0,0 @@
-package dbquery
-
-import (
-       "encoding/json"
-       "fmt"
-       "mime/multipart"
-       "os"
-       "strings"
-       "time"
-
-       "github.com/gin-gonic/gin"
-)
-
-type AdminStruct struct {
-}
-
-type UserStruct struct {
-       Passphrase      string `json:"passphrase"`
-       DurationSeconds int    `json:"duration_seconds"`
-}
-
-type SessionStruct struct {
-       Type            string `json:"type"`
-       Id              string `json:"id"`
-       StartTime       string `json:"start_time"`
-       DurationSeconds int    `json:"duration_seconds"`
-}
-
-type MediaStruct struct {
-       ISPublic  bool     `json:"is_public"`
-       CreatedAt string   `json:"created_at"`
-       Type      string   `json:"type"`
-       Extension string   `json:"extension"`
-       PlainName string   `json:"plain_name"`
-       Author    string   `json:"author"`
-       AllowedId []string `json:"allowed_id"`
-}
-
-var adminPath string = "./data/admin/"
-
-var userPath string = "./data/user/"
-
-var sessionPath string = "./data/session/"
-
-var mediaPath string = "./data/media/"
-
-var articlePath string = "./data/media/article/"
-
-var imagePath string = "./data/media/image/"
-
-var videoPath string = "./data/media/video/"
-
-func GetByIdFromAdmin(email string) (*AdminStruct, error) {
-
-       var as AdminStruct
-
-       this_file_path := adminPath + email + ".json"
-
-       file_b, err := os.ReadFile(this_file_path)
-
-       if err != nil {
-
-               return nil, fmt.Errorf("failed to get from admin: %s", err.Error())
-       }
-
-       err = json.Unmarshal(file_b, &as)
-
-       if err != nil {
-
-               return nil, fmt.Errorf("failed to get from admin: %s", err.Error())
-       }
-
-       return &as, nil
-
-}
-
-func GetByIdFromUser(id string) (*UserStruct, error) {
-
-       var us UserStruct
-
-       this_file_path := userPath + id + ".json"
-
-       file_b, err := os.ReadFile(this_file_path)
-
-       if err != nil {
-
-               return nil, fmt.Errorf("failed to get from user: %s", err.Error())
-
-       }
-
-       err = json.Unmarshal(file_b, &us)
-
-       if err != nil {
-
-               return nil, fmt.Errorf("failed to get from user: %s", err.Error())
-       }
-
-       return &us, nil
-
-}
-
-func GetBySessionKeyFromSession(session_key string) (*SessionStruct, error) {
-
-       var ss SessionStruct
-
-       this_file_path := sessionPath + session_key + ".json"
-
-       file_b, err := os.ReadFile(this_file_path)
-
-       if err != nil {
-
-               return nil, fmt.Errorf("session pool: failed to read file: %s", err.Error())
-
-       }
-
-       err = json.Unmarshal(file_b, &ss)
-
-       if err != nil {
-
-               return nil, fmt.Errorf("session pool: failed to marshal: %s", err.Error())
-
-       }
-
-       t_now := time.Now()
-
-       t, _ := time.Parse("2006-01-02-15-04-05", ss.StartTime)
-
-       diff := t_now.Sub(t)
-
-       if ss.DurationSeconds == 0 || (diff.Seconds() < float64(ss.DurationSeconds)) {
-
-               return &ss, nil
-
-       } else {
-
-               err = RemoveSessionKeyFromSession(session_key)
-
-               if err != nil {
-
-                       return nil, fmt.Errorf("session: failed to remove: %s", err.Error())
-
-               }
-
-               return nil, fmt.Errorf("id: %s: expired", ss.Id)
-
-       }
-
-}
-
-func GetByMediaKeyFromMedia(media_key string) (*MediaStruct, error) {
-
-       var ms MediaStruct
-
-       this_file_path := mediaPath + media_key + ".json"
-
-       file_b, err := os.ReadFile(this_file_path)
-
-       if err != nil {
-
-               return nil, fmt.Errorf("media: failed to read file: %s", err.Error())
-
-       }
-
-       err = json.Unmarshal(file_b, &ms)
-
-       if err != nil {
-
-               return nil, fmt.Errorf("media: failed to marshal: %s", err.Error())
-       }
-
-       return &ms, nil
-
-}
-
-func GetByIdFromSession(email string) (string, *SessionStruct, error) {
-
-       files, err := os.ReadDir(sessionPath)
-
-       if err != nil {
-
-               return "", nil, fmt.Errorf("session pool: failed to read dir: %s", err.Error())
-
-       }
-
-       for _, f := range files {
-
-               ss := SessionStruct{}
-
-               f_name := f.Name()
-
-               if !strings.Contains(f_name, ".json") {
-                       continue
-               }
-
-               key_name := strings.ReplaceAll(f_name, ".json", "")
-
-               this_file_path := sessionPath + f_name
-
-               file_b, err := os.ReadFile(this_file_path)
-
-               if err != nil {
-
-                       return "", nil, fmt.Errorf("session pool: failed to read file: %s", err.Error())
-
-               }
-
-               err = json.Unmarshal(file_b, &ss)
-
-               if err != nil {
-
-                       return "", nil, fmt.Errorf("session pool: failed to marshal: %s", err.Error())
-               }
-
-               t_now := time.Now()
-
-               t, _ := time.Parse("2006-01-02-15-04-05", ss.StartTime)
-
-               diff := t_now.Sub(t)
-
-               if ss.Id == email {
-
-                       if ss.DurationSeconds == 0 || (diff.Seconds() < float64(ss.DurationSeconds)) {
-
-                               return key_name, &ss, nil
-
-                       } else {
-
-                               err = RemoveSessionKeyFromSession(key_name)
-
-                               if err != nil {
-
-                                       return "", nil, fmt.Errorf("session pool: failed to remove: %s", err.Error())
-
-                               }
-
-                               return "", nil, fmt.Errorf("id: %s: expired", email)
-
-                       }
-
-               }
-
-       }
-
-       return "", nil, fmt.Errorf("id: %s: not found", email)
-}
-
-func GetEntryForMedia() (map[string]MediaStruct, error) {
-
-       em := make(map[string]MediaStruct)
-
-       files, err := os.ReadDir(mediaPath)
-
-       if err != nil {
-
-               return nil, fmt.Errorf("media entry: failed to read dir: %s", err.Error())
-
-       }
-
-       for _, f := range files {
-
-               ms := MediaStruct{}
-
-               f_name := f.Name()
-
-               if !strings.Contains(f_name, ".json") {
-                       continue
-               }
-
-               key_name := strings.ReplaceAll(f_name, ".json", "")
-
-               this_file_path := mediaPath + f_name
-
-               file_b, err := os.ReadFile(this_file_path)
-
-               if err != nil {
-
-                       return nil, fmt.Errorf("media entry: failed to read file: %s", err.Error())
-
-               }
-
-               err = json.Unmarshal(file_b, &ms)
-
-               if err != nil {
-
-                       return nil, fmt.Errorf("media entry: failed to marshal: %s", err.Error())
-               }
-
-               em[key_name] = ms
-
-       }
-
-       return em, nil
-}
-
-func RemoveSessionKeyFromSession(session_key string) error {
-
-       this_file_path := sessionPath + session_key + ".json"
-
-       err := os.Remove(this_file_path)
-
-       if err != nil {
-
-               return err
-
-       }
-
-       return nil
-}
-
-func MakeSessionForAdmin(session_key string, email string) error {
-
-       _, ss, _ := GetByIdFromSession(email)
-
-       if ss != nil {
-
-               return fmt.Errorf("valid session already exists for: %s", email)
-
-       }
-
-       new_ss := SessionStruct{}
-
-       t_now := time.Now()
-
-       t_str := t_now.Format("2006-01-02-15-04-05")
-
-       new_ss.Type = "admin"
-
-       new_ss.Id = email
-
-       new_ss.StartTime = t_str
-
-       new_ss.DurationSeconds = 0
-
-       jb, err := json.Marshal(new_ss)
-
-       if err != nil {
-
-               return fmt.Errorf("failed to marshal new session admin: %s", err.Error())
-       }
-
-       this_file_path := sessionPath + session_key + ".json"
-
-       err = os.WriteFile(this_file_path, jb, 0644)
-
-       if err != nil {
-
-               return fmt.Errorf("failed to write new session admin: %s", err.Error())
-       }
-
-       return nil
-}
-
-func GetAllUsers() (map[string]UserStruct, error) {
-
-       var ret_us = make(map[string]UserStruct)
-
-       files, err := os.ReadDir(userPath)
-
-       if err != nil {
-
-               return nil, fmt.Errorf("all users: failed to read dir: %s", err.Error())
-
-       }
-
-       for _, f := range files {
-
-               us := UserStruct{}
-
-               f_name := f.Name()
-
-               if !strings.Contains(f_name, ".json") {
-                       continue
-               }
-
-               key_name := strings.ReplaceAll(f_name, ".json", "")
-
-               this_file_path := userPath + f_name
-
-               file_b, err := os.ReadFile(this_file_path)
-
-               if err != nil {
-
-                       return nil, fmt.Errorf("all users: failed to read file: %s", err.Error())
-
-               }
-
-               err = json.Unmarshal(file_b, &us)
-
-               if err != nil {
-
-                       return nil, fmt.Errorf("all users: failed to marshal: %s", err.Error())
-               }
-
-               ret_us[key_name] = us
-
-       }
-
-       return ret_us, nil
-
-}
-
-func MakeUser(id string, passphrase string, duration_seconds int) error {
-
-       var us UserStruct
-
-       this_file_path := userPath + id + ".json"
-
-       if _, err := os.Stat(this_file_path); err == nil {
-
-               return fmt.Errorf("id: %s: exists", err.Error())
-
-       }
-
-       us.Passphrase = passphrase
-
-       us.DurationSeconds = duration_seconds
-
-       jb, err := json.Marshal(us)
-
-       if err != nil {
-
-               return fmt.Errorf("failed to make user: %s", err.Error())
-
-       }
-
-       err = os.WriteFile(this_file_path, jb, 0644)
-
-       if err != nil {
-
-               return fmt.Errorf("failed to make user: %s", err.Error())
-       }
-
-       return nil
-}
-
-func RemoveUser(id string) error {
-
-       this_file_path := userPath + id + ".json"
-
-       key, ss, _ := GetByIdFromSession(id)
-
-       if ss == nil {
-
-               fmt.Println("remove user: existing session removed")
-
-               _ = RemoveSessionKeyFromSession(key)
-
-       }
-
-       err := os.Remove(this_file_path)
-
-       if err != nil {
-
-               return err
-
-       }
-
-       return nil
-}
-
-func MakeSessionForUser(session_key string, id string, duration_seconds int) error {
-
-       var ss SessionStruct
-
-       this_file_path := sessionPath + session_key + ".json"
-
-       t_now := time.Now()
-
-       t_str := t_now.Format("2006-01-02-15-04-05")
-
-       ss.Type = "user"
-
-       ss.Id = id
-
-       ss.StartTime = t_str
-
-       ss.DurationSeconds = duration_seconds
-
-       jb, err := json.Marshal(ss)
-
-       if err != nil {
-
-               return fmt.Errorf("failed to make session for user: %s", err.Error())
-
-       }
-
-       err = os.WriteFile(this_file_path, jb, 0644)
-
-       if err != nil {
-
-               return fmt.Errorf("failed to make session: %s", err.Error())
-
-       }
-
-       return nil
-}
-
-func UploadArticle(author string, content string, plain_name string, new_name string) error {
-
-       ms := MediaStruct{}
-
-       c_time := time.Now()
-
-       c_time_fmt := c_time.Format("2006-01-02-15-04-05")
-
-       ms.ISPublic = true
-       ms.Type = "article"
-       ms.PlainName = plain_name
-       ms.Extension = "json"
-       ms.CreatedAt = c_time_fmt
-       ms.Author = author
-
-       this_file_path := mediaPath + new_name + ".json"
-
-       this_article_path := articlePath + new_name + ".json"
-
-       content_b := []byte(content)
-
-       jb, err := json.Marshal(ms)
-
-       if err != nil {
-
-               return fmt.Errorf("failed to upload: %s", err.Error())
-       }
-
-       err = os.WriteFile(this_file_path, jb, 0644)
-
-       if err != nil {
-
-               return fmt.Errorf("failed to upload: %s", err.Error())
-       }
-
-       err = os.WriteFile(this_article_path, content_b, 0644)
-
-       if err != nil {
-
-               return fmt.Errorf("failed to upload: %s", err.Error())
-       }
-
-       return nil
-}
-
-func DeleteArticle(media_key string) error {
-
-       var ms MediaStruct
-
-       this_file_path := mediaPath + media_key + ".json"
-
-       file_b, err := os.ReadFile(this_file_path)
-
-       if err != nil {
-
-               return fmt.Errorf("failed to delete article: %s", err.Error())
-
-       }
-
-       err = json.Unmarshal(file_b, &ms)
-
-       if err != nil {
-
-               return fmt.Errorf("failed to delete article: marshal: %s", err.Error())
-       }
-
-       this_article_path := articlePath + media_key + "." + ms.Extension
-
-       article_file_b, err := os.ReadFile(this_article_path)
-
-       if err != nil {
-
-               return fmt.Errorf("failed to delete article: article file: %s", err.Error())
-       }
-
-       associatedTargets, err := GetAssociateMediaKeysForEditorjsSrc(article_file_b)
-
-       if err != nil {
-
-               return fmt.Errorf("failed to delete article: %s", err.Error())
-
-       }
-
-       atLen := len(associatedTargets)
-
-       for i := 0; i < atLen; i++ {
-
-               err := DeleteMedia(associatedTargets[i])
-
-               if err != nil {
-
-                       return fmt.Errorf("failed to delete associated key: %s", err.Error())
-               }
-
-       }
-
-       err = os.Remove(this_article_path)
-
-       if err != nil {
-
-               return fmt.Errorf("failed to delete article: rmart: %s", err.Error())
-       }
-
-       err = os.Remove(this_file_path)
-
-       if err != nil {
-
-               return fmt.Errorf("failed to delete video: rmmd: %s", err.Error())
-       }
-
-       return nil
-}
-
-func GetArticle(media_key string) (string, error) {
-
-       var ms MediaStruct
-
-       var content string
-
-       this_file_path := mediaPath + media_key + ".json"
-
-       file_b, err := os.ReadFile(this_file_path)
-
-       if err != nil {
-
-               return "", fmt.Errorf("failed to get article: %s", err.Error())
-
-       }
-
-       err = json.Unmarshal(file_b, &ms)
-
-       if err != nil {
-
-               return "", fmt.Errorf("failed to get article: marshal: %s", err.Error())
-       }
-
-       if ms.Type != "article" {
-
-               return "", fmt.Errorf("failed to get article: %s: %s", "wrong type", ms.Type)
-
-       }
-
-       this_article_path := articlePath + media_key + "." + ms.Extension
-
-       article_b, err := os.ReadFile(this_article_path)
-
-       if err != nil {
-
-               return "", fmt.Errorf("failed to get article: read file: %s", err.Error())
-
-       }
-
-       content = string(article_b)
-
-       return content, nil
-
-}
-
-func UploadImage(c *gin.Context, author string, file *multipart.FileHeader, filename string, new_filename string, extension string) error {
-
-       ms := MediaStruct{}
-
-       this_file_path := mediaPath + new_filename + ".json"
-
-       this_image_path := imagePath + new_filename + "." + extension
-
-       c_time := time.Now()
-
-       c_time_fmt := c_time.Format("2006-01-02-15-04-05")
-
-       ms.ISPublic = true
-       ms.Type = "image"
-       ms.PlainName = filename
-       ms.Extension = extension
-       ms.CreatedAt = c_time_fmt
-       ms.Author = author
-
-       jb, err := json.Marshal(ms)
-
-       if err != nil {
-
-               return fmt.Errorf("failed to upload: %s", err.Error())
-       }
-
-       err = os.WriteFile(this_file_path, jb, 0644)
-
-       if err != nil {
-
-               return fmt.Errorf("failed to upload: %s", err.Error())
-       }
-
-       err = c.SaveUploadedFile(file, this_image_path)
-
-       if err != nil {
-
-               return fmt.Errorf("failed to upload: %s", err.Error())
-       }
-
-       return nil
-}
-
-func DownloadMedia(c *gin.Context, watchId string) error {
-
-       ms, err := GetByMediaKeyFromMedia(watchId)
-
-       if ms == nil {
-
-               return fmt.Errorf("failed to download media: %s", err.Error())
-
-       }
-
-       this_media_path := ""
-
-       if ms.Type == "image" {
-
-               this_media_path = imagePath + watchId + "." + ms.Extension
-
-       } else if ms.Type == "video" {
-
-               this_media_path = videoPath + watchId + "." + ms.Extension
-
-       }
-
-       if _, err := os.Stat(this_media_path); err != nil {
-
-               return err
-
-       }
-
-       if ms.Type == "image" {
-
-               c.Header("Content-Type", "image/"+ms.Extension)
-
-       } else if ms.Type == "video" {
-
-               c.Header("Content-Type", "video/"+ms.Extension)
-
-       }
-
-       c.File(this_media_path)
-
-       return nil
-}
-
-func DownloadImage(c *gin.Context, watchId string) error {
-
-       ms, err := GetByMediaKeyFromMedia(watchId)
-
-       if ms == nil {
-
-               return fmt.Errorf("failed to download image: %s", err.Error())
-
-       }
-
-       if ms.Type != "image" {
-
-               return fmt.Errorf("failed to download image: %s: %s", "wrong type", ms.Type)
-       }
-
-       this_image_path := imagePath + watchId + "." + ms.Extension
-
-       if _, err := os.Stat(this_image_path); err != nil {
-
-               return err
-
-       }
-
-       c.Header("Content-Type", "image/"+ms.Extension)
-
-       c.File(this_image_path)
-
-       return nil
-}
-
-func UploadVideo(c *gin.Context, author string, file *multipart.FileHeader, filename string, new_filename string, extension string) error {
-
-       ms := MediaStruct{}
-
-       this_file_path := mediaPath + new_filename + ".json"
-
-       this_video_path := videoPath + new_filename + "." + extension
-
-       c_time := time.Now()
-
-       c_time_fmt := c_time.Format("2006-01-02-15-04-05")
-
-       ms.ISPublic = true
-       ms.Type = "video"
-       ms.PlainName = filename
-       ms.Extension = extension
-       ms.CreatedAt = c_time_fmt
-       ms.Author = author
-
-       jb, err := json.Marshal(ms)
-
-       if err != nil {
-
-               return fmt.Errorf("failed to upload: %s", err.Error())
-       }
-
-       err = os.WriteFile(this_file_path, jb, 0644)
-
-       if err != nil {
-
-               return fmt.Errorf("failed to upload: %s", err.Error())
-       }
-
-       err = c.SaveUploadedFile(file, this_video_path)
-
-       if err != nil {
-
-               return fmt.Errorf("failed to upload: %s", err.Error())
-       }
-
-       return nil
-}
-
-func DeleteMedia(media_key string) error {
-
-       var ms MediaStruct
-
-       this_file_path := mediaPath + media_key + ".json"
-
-       file_b, err := os.ReadFile(this_file_path)
-
-       if err != nil {
-
-               return fmt.Errorf("failed to delete media: %s", err.Error())
-
-       }
-
-       err = json.Unmarshal(file_b, &ms)
-
-       if err != nil {
-
-               return fmt.Errorf("failed to delete media: marshal: %s", err.Error())
-       }
-
-       var this_media_path string
-
-       if ms.Type == "image" {
-
-               this_media_path = imagePath + media_key + "." + ms.Extension
-
-       } else if ms.Type == "video" {
-
-               this_media_path = videoPath + media_key + "." + ms.Extension
-       }
-
-       err = os.Remove(this_media_path)
-
-       if err != nil {
-
-               return fmt.Errorf("failed to delete media: rm: %s", err.Error())
-       }
-
-       err = os.Remove(this_file_path)
-
-       if err != nil {
-
-               return fmt.Errorf("failed to delete media: rmkey: %s", err.Error())
-       }
-
-       return nil
-}
-
-func DeleteVideo(media_key string) error {
-
-       var ms MediaStruct
-
-       this_file_path := mediaPath + media_key + ".json"
-
-       file_b, err := os.ReadFile(this_file_path)
-
-       if err != nil {
-
-               return fmt.Errorf("failed to delete video: %s", err.Error())
-
-       }
-
-       err = json.Unmarshal(file_b, &ms)
-
-       if err != nil {
-
-               return fmt.Errorf("failed to delete video: marshal: %s", err.Error())
-       }
-
-       this_video_path := videoPath + media_key + "." + ms.Extension
-
-       err = os.Remove(this_video_path)
-
-       if err != nil {
-
-               return fmt.Errorf("failed to delete video: rmvid: %s", err.Error())
-       }
-
-       err = os.Remove(this_file_path)
-
-       if err != nil {
-
-               return fmt.Errorf("failed to delete video: rmmd: %s", err.Error())
-       }
-
-       return nil
-}
-
-func DownloadVideo(c *gin.Context, watchId string) error {
-
-       ms, err := GetByMediaKeyFromMedia(watchId)
-
-       if ms == nil {
-
-               return fmt.Errorf("failed to download video: %s", err.Error())
-
-       }
-
-       if ms.Type != "video" {
-
-               return fmt.Errorf("failed to download video: %s: %s", "wrong type", ms.Type)
-       }
-
-       this_video_path := videoPath + watchId + "." + ms.Extension
-
-       if _, err := os.Stat(this_video_path); err != nil {
-
-               return err
-
-       }
-
-       c.Header("Content-Type", "video/"+ms.Extension)
-
-       c.File(this_video_path)
-
-       return nil
-}
diff --git a/pkg/dbquery/dbquery_fs.go b/pkg/dbquery/dbquery_fs.go
new file mode 100644 (file)
index 0000000..dd902d1
--- /dev/null
@@ -0,0 +1,979 @@
+package dbquery
+
+import (
+       "encoding/json"
+       "fmt"
+       "mime/multipart"
+       "os"
+       "strings"
+       "time"
+
+       "github.com/gin-gonic/gin"
+)
+
+type AdminStruct struct {
+}
+
+type UserStruct struct {
+       Passphrase      string `json:"passphrase"`
+       DurationSeconds int    `json:"duration_seconds"`
+}
+
+type SessionStruct struct {
+       Type            string `json:"type"`
+       Id              string `json:"id"`
+       StartTime       string `json:"start_time"`
+       DurationSeconds int    `json:"duration_seconds"`
+}
+
+type MediaStruct struct {
+       ISPublic  bool     `json:"is_public"`
+       CreatedAt string   `json:"created_at"`
+       Type      string   `json:"type"`
+       Extension string   `json:"extension"`
+       PlainName string   `json:"plain_name"`
+       Author    string   `json:"author"`
+       AllowedId []string `json:"allowed_id"`
+}
+
+var adminPath string = "./data/admin/"
+
+var userPath string = "./data/user/"
+
+var sessionPath string = "./data/session/"
+
+var mediaPath string = "./data/media/"
+
+var articlePath string = "./data/media/article/"
+
+var imagePath string = "./data/media/image/"
+
+var videoPath string = "./data/media/video/"
+
+var logPath string = "./data/log/"
+
+func GetByIdFromAdmin(email string) (*AdminStruct, error) {
+
+       var as AdminStruct
+
+       this_file_path := adminPath + email + ".json"
+
+       file_b, err := os.ReadFile(this_file_path)
+
+       if err != nil {
+
+               return nil, fmt.Errorf("failed to get from admin: %s", err.Error())
+       }
+
+       err = json.Unmarshal(file_b, &as)
+
+       if err != nil {
+
+               return nil, fmt.Errorf("failed to get from admin: %s", err.Error())
+       }
+
+       return &as, nil
+
+}
+
+func GetByIdFromUser(id string) (*UserStruct, error) {
+
+       var us UserStruct
+
+       this_file_path := userPath + id + ".json"
+
+       file_b, err := os.ReadFile(this_file_path)
+
+       if err != nil {
+
+               return nil, fmt.Errorf("failed to get from user: %s", err.Error())
+
+       }
+
+       err = json.Unmarshal(file_b, &us)
+
+       if err != nil {
+
+               return nil, fmt.Errorf("failed to get from user: %s", err.Error())
+       }
+
+       return &us, nil
+
+}
+
+func GetBySessionKeyFromSession(session_key string) (*SessionStruct, error) {
+
+       var ss SessionStruct
+
+       this_file_path := sessionPath + session_key + ".json"
+
+       file_b, err := os.ReadFile(this_file_path)
+
+       if err != nil {
+
+               return nil, fmt.Errorf("session pool: failed to read file: %s", err.Error())
+
+       }
+
+       err = json.Unmarshal(file_b, &ss)
+
+       if err != nil {
+
+               return nil, fmt.Errorf("session pool: failed to marshal: %s", err.Error())
+
+       }
+
+       t_now := time.Now()
+
+       t, _ := time.Parse("2006-01-02-15-04-05", ss.StartTime)
+
+       diff := t_now.Sub(t)
+
+       if ss.DurationSeconds == 0 || (diff.Seconds() < float64(ss.DurationSeconds)) {
+
+               return &ss, nil
+
+       } else {
+
+               err = RemoveSessionKeyFromSession(session_key)
+
+               if err != nil {
+
+                       return nil, fmt.Errorf("session: failed to remove: %s", err.Error())
+
+               }
+
+               return nil, fmt.Errorf("id: %s: expired", ss.Id)
+
+       }
+
+}
+
+func GetByMediaKeyFromMedia(media_key string) (*MediaStruct, error) {
+
+       var ms MediaStruct
+
+       this_file_path := mediaPath + media_key + ".json"
+
+       file_b, err := os.ReadFile(this_file_path)
+
+       if err != nil {
+
+               return nil, fmt.Errorf("media: failed to read file: %s", err.Error())
+
+       }
+
+       err = json.Unmarshal(file_b, &ms)
+
+       if err != nil {
+
+               return nil, fmt.Errorf("media: failed to marshal: %s", err.Error())
+       }
+
+       return &ms, nil
+
+}
+
+func GetByIdFromSession(email string) (string, *SessionStruct, error) {
+
+       files, err := os.ReadDir(sessionPath)
+
+       if err != nil {
+
+               return "", nil, fmt.Errorf("session pool: failed to read dir: %s", err.Error())
+
+       }
+
+       for _, f := range files {
+
+               ss := SessionStruct{}
+
+               f_name := f.Name()
+
+               if !strings.Contains(f_name, ".json") {
+                       continue
+               }
+
+               key_name := strings.ReplaceAll(f_name, ".json", "")
+
+               this_file_path := sessionPath + f_name
+
+               file_b, err := os.ReadFile(this_file_path)
+
+               if err != nil {
+
+                       return "", nil, fmt.Errorf("session pool: failed to read file: %s", err.Error())
+
+               }
+
+               err = json.Unmarshal(file_b, &ss)
+
+               if err != nil {
+
+                       return "", nil, fmt.Errorf("session pool: failed to marshal: %s", err.Error())
+               }
+
+               t_now := time.Now()
+
+               t, _ := time.Parse("2006-01-02-15-04-05", ss.StartTime)
+
+               diff := t_now.Sub(t)
+
+               if ss.Id == email {
+
+                       if ss.DurationSeconds == 0 || (diff.Seconds() < float64(ss.DurationSeconds)) {
+
+                               return key_name, &ss, nil
+
+                       } else {
+
+                               err = RemoveSessionKeyFromSession(key_name)
+
+                               if err != nil {
+
+                                       return "", nil, fmt.Errorf("session pool: failed to remove: %s", err.Error())
+
+                               }
+
+                               return "", nil, fmt.Errorf("id: %s: expired", email)
+
+                       }
+
+               }
+
+       }
+
+       return "", nil, fmt.Errorf("id: %s: not found", email)
+}
+
+func GetEntryForMedia() (map[string]MediaStruct, error) {
+
+       em := make(map[string]MediaStruct)
+
+       files, err := os.ReadDir(mediaPath)
+
+       if err != nil {
+
+               return nil, fmt.Errorf("media entry: failed to read dir: %s", err.Error())
+
+       }
+
+       for _, f := range files {
+
+               ms := MediaStruct{}
+
+               f_name := f.Name()
+
+               if !strings.Contains(f_name, ".json") {
+                       continue
+               }
+
+               key_name := strings.ReplaceAll(f_name, ".json", "")
+
+               this_file_path := mediaPath + f_name
+
+               file_b, err := os.ReadFile(this_file_path)
+
+               if err != nil {
+
+                       return nil, fmt.Errorf("media entry: failed to read file: %s", err.Error())
+
+               }
+
+               err = json.Unmarshal(file_b, &ms)
+
+               if err != nil {
+
+                       return nil, fmt.Errorf("media entry: failed to marshal: %s", err.Error())
+               }
+
+               em[key_name] = ms
+
+       }
+
+       return em, nil
+}
+
+func RemoveSessionKeyFromSession(session_key string) error {
+
+       this_file_path := sessionPath + session_key + ".json"
+
+       err := os.Remove(this_file_path)
+
+       if err != nil {
+
+               return err
+
+       }
+
+       return nil
+}
+
+func MakeSessionForAdmin(session_key string, email string) error {
+
+       _, ss, _ := GetByIdFromSession(email)
+
+       if ss != nil {
+
+               return fmt.Errorf("valid session already exists for: %s", email)
+
+       }
+
+       new_ss := SessionStruct{}
+
+       t_now := time.Now()
+
+       t_str := t_now.Format("2006-01-02-15-04-05")
+
+       new_ss.Type = "admin"
+
+       new_ss.Id = email
+
+       new_ss.StartTime = t_str
+
+       new_ss.DurationSeconds = 0
+
+       jb, err := json.Marshal(new_ss)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to marshal new session admin: %s", err.Error())
+       }
+
+       this_file_path := sessionPath + session_key + ".json"
+
+       err = os.WriteFile(this_file_path, jb, 0644)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to write new session admin: %s", err.Error())
+       }
+
+       return nil
+}
+
+func GetAllUsers() (map[string]UserStruct, error) {
+
+       var ret_us = make(map[string]UserStruct)
+
+       files, err := os.ReadDir(userPath)
+
+       if err != nil {
+
+               return nil, fmt.Errorf("all users: failed to read dir: %s", err.Error())
+
+       }
+
+       for _, f := range files {
+
+               us := UserStruct{}
+
+               f_name := f.Name()
+
+               if !strings.Contains(f_name, ".json") {
+                       continue
+               }
+
+               key_name := strings.ReplaceAll(f_name, ".json", "")
+
+               this_file_path := userPath + f_name
+
+               file_b, err := os.ReadFile(this_file_path)
+
+               if err != nil {
+
+                       return nil, fmt.Errorf("all users: failed to read file: %s", err.Error())
+
+               }
+
+               err = json.Unmarshal(file_b, &us)
+
+               if err != nil {
+
+                       return nil, fmt.Errorf("all users: failed to marshal: %s", err.Error())
+               }
+
+               ret_us[key_name] = us
+
+       }
+
+       return ret_us, nil
+
+}
+
+func MakeUser(id string, passphrase string, duration_seconds int) error {
+
+       var us UserStruct
+
+       this_file_path := userPath + id + ".json"
+
+       if _, err := os.Stat(this_file_path); err == nil {
+
+               return fmt.Errorf("id: %s: exists", err.Error())
+
+       }
+
+       us.Passphrase = passphrase
+
+       us.DurationSeconds = duration_seconds
+
+       jb, err := json.Marshal(us)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to make user: %s", err.Error())
+
+       }
+
+       err = os.WriteFile(this_file_path, jb, 0644)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to make user: %s", err.Error())
+       }
+
+       return nil
+}
+
+func RemoveUser(id string) error {
+
+       this_file_path := userPath + id + ".json"
+
+       key, ss, _ := GetByIdFromSession(id)
+
+       if ss == nil {
+
+               fmt.Println("remove user: existing session removed")
+
+               _ = RemoveSessionKeyFromSession(key)
+
+       }
+
+       err := os.Remove(this_file_path)
+
+       if err != nil {
+
+               return err
+
+       }
+
+       return nil
+}
+
+func MakeSessionForUser(session_key string, id string, duration_seconds int) error {
+
+       var ss SessionStruct
+
+       this_file_path := sessionPath + session_key + ".json"
+
+       t_now := time.Now()
+
+       t_str := t_now.Format("2006-01-02-15-04-05")
+
+       ss.Type = "user"
+
+       ss.Id = id
+
+       ss.StartTime = t_str
+
+       ss.DurationSeconds = duration_seconds
+
+       jb, err := json.Marshal(ss)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to make session for user: %s", err.Error())
+
+       }
+
+       err = os.WriteFile(this_file_path, jb, 0644)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to make session: %s", err.Error())
+
+       }
+
+       return nil
+}
+
+func UploadArticle(author string, content string, plain_name string, new_name string) error {
+
+       ms := MediaStruct{}
+
+       c_time := time.Now()
+
+       c_time_fmt := c_time.Format("2006-01-02-15-04-05")
+
+       ms.ISPublic = true
+       ms.Type = "article"
+       ms.PlainName = plain_name
+       ms.Extension = "json"
+       ms.CreatedAt = c_time_fmt
+       ms.Author = author
+
+       this_file_path := mediaPath + new_name + ".json"
+
+       this_article_path := articlePath + new_name + ".json"
+
+       content_b := []byte(content)
+
+       jb, err := json.Marshal(ms)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to upload: %s", err.Error())
+       }
+
+       err = os.WriteFile(this_file_path, jb, 0644)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to upload: %s", err.Error())
+       }
+
+       err = os.WriteFile(this_article_path, content_b, 0644)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to upload: %s", err.Error())
+       }
+
+       return nil
+}
+
+func DeleteArticle(media_key string) error {
+
+       var ms MediaStruct
+
+       this_file_path := mediaPath + media_key + ".json"
+
+       file_b, err := os.ReadFile(this_file_path)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to delete article: %s", err.Error())
+
+       }
+
+       err = json.Unmarshal(file_b, &ms)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to delete article: marshal: %s", err.Error())
+       }
+
+       this_article_path := articlePath + media_key + "." + ms.Extension
+
+       article_file_b, err := os.ReadFile(this_article_path)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to delete article: article file: %s", err.Error())
+       }
+
+       associatedTargets, err := GetAssociateMediaKeysForEditorjsSrc(article_file_b)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to delete article: %s", err.Error())
+
+       }
+
+       atLen := len(associatedTargets)
+
+       for i := 0; i < atLen; i++ {
+
+               err := DeleteMedia(associatedTargets[i])
+
+               if err != nil {
+
+                       return fmt.Errorf("failed to delete associated key: %s", err.Error())
+               }
+
+       }
+
+       err = os.Remove(this_article_path)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to delete article: rmart: %s", err.Error())
+       }
+
+       err = os.Remove(this_file_path)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to delete video: rmmd: %s", err.Error())
+       }
+
+       return nil
+}
+
+func GetArticle(media_key string) (string, error) {
+
+       var ms MediaStruct
+
+       var content string
+
+       this_file_path := mediaPath + media_key + ".json"
+
+       file_b, err := os.ReadFile(this_file_path)
+
+       if err != nil {
+
+               return "", fmt.Errorf("failed to get article: %s", err.Error())
+
+       }
+
+       err = json.Unmarshal(file_b, &ms)
+
+       if err != nil {
+
+               return "", fmt.Errorf("failed to get article: marshal: %s", err.Error())
+       }
+
+       if ms.Type != "article" {
+
+               return "", fmt.Errorf("failed to get article: %s: %s", "wrong type", ms.Type)
+
+       }
+
+       this_article_path := articlePath + media_key + "." + ms.Extension
+
+       article_b, err := os.ReadFile(this_article_path)
+
+       if err != nil {
+
+               return "", fmt.Errorf("failed to get article: read file: %s", err.Error())
+
+       }
+
+       content = string(article_b)
+
+       return content, nil
+
+}
+
+func UploadImage(c *gin.Context, author string, file *multipart.FileHeader, filename string, new_filename string, extension string) error {
+
+       ms := MediaStruct{}
+
+       this_file_path := mediaPath + new_filename + ".json"
+
+       this_image_path := imagePath + new_filename + "." + extension
+
+       c_time := time.Now()
+
+       c_time_fmt := c_time.Format("2006-01-02-15-04-05")
+
+       ms.ISPublic = true
+       ms.Type = "image"
+       ms.PlainName = filename
+       ms.Extension = extension
+       ms.CreatedAt = c_time_fmt
+       ms.Author = author
+
+       jb, err := json.Marshal(ms)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to upload: %s", err.Error())
+       }
+
+       err = os.WriteFile(this_file_path, jb, 0644)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to upload: %s", err.Error())
+       }
+
+       err = c.SaveUploadedFile(file, this_image_path)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to upload: %s", err.Error())
+       }
+
+       return nil
+}
+
+func DownloadMedia(c *gin.Context, watchId string) error {
+
+       ms, err := GetByMediaKeyFromMedia(watchId)
+
+       if ms == nil {
+
+               return fmt.Errorf("failed to download media: %s", err.Error())
+
+       }
+
+       this_media_path := ""
+
+       if ms.Type == "image" {
+
+               this_media_path = imagePath + watchId + "." + ms.Extension
+
+       } else if ms.Type == "video" {
+
+               this_media_path = videoPath + watchId + "." + ms.Extension
+
+       }
+
+       if _, err := os.Stat(this_media_path); err != nil {
+
+               return err
+
+       }
+
+       if ms.Type == "image" {
+
+               c.Header("Content-Type", "image/"+ms.Extension)
+
+       } else if ms.Type == "video" {
+
+               c.Header("Content-Type", "video/"+ms.Extension)
+
+       }
+
+       c.File(this_media_path)
+
+       return nil
+}
+
+func DownloadImage(c *gin.Context, watchId string) error {
+
+       ms, err := GetByMediaKeyFromMedia(watchId)
+
+       if ms == nil {
+
+               return fmt.Errorf("failed to download image: %s", err.Error())
+
+       }
+
+       if ms.Type != "image" {
+
+               return fmt.Errorf("failed to download image: %s: %s", "wrong type", ms.Type)
+       }
+
+       this_image_path := imagePath + watchId + "." + ms.Extension
+
+       if _, err := os.Stat(this_image_path); err != nil {
+
+               return err
+
+       }
+
+       c.Header("Content-Type", "image/"+ms.Extension)
+
+       c.File(this_image_path)
+
+       return nil
+}
+
+func UploadVideo(c *gin.Context, author string, file *multipart.FileHeader, filename string, new_filename string, extension string) error {
+
+       ms := MediaStruct{}
+
+       this_file_path := mediaPath + new_filename + ".json"
+
+       this_video_path := videoPath + new_filename + "." + extension
+
+       c_time := time.Now()
+
+       c_time_fmt := c_time.Format("2006-01-02-15-04-05")
+
+       ms.ISPublic = true
+       ms.Type = "video"
+       ms.PlainName = filename
+       ms.Extension = extension
+       ms.CreatedAt = c_time_fmt
+       ms.Author = author
+
+       jb, err := json.Marshal(ms)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to upload: %s", err.Error())
+       }
+
+       err = os.WriteFile(this_file_path, jb, 0644)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to upload: %s", err.Error())
+       }
+
+       err = c.SaveUploadedFile(file, this_video_path)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to upload: %s", err.Error())
+       }
+
+       return nil
+}
+
+func DeleteMedia(media_key string) error {
+
+       var ms MediaStruct
+
+       this_file_path := mediaPath + media_key + ".json"
+
+       file_b, err := os.ReadFile(this_file_path)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to delete media: %s", err.Error())
+
+       }
+
+       err = json.Unmarshal(file_b, &ms)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to delete media: marshal: %s", err.Error())
+       }
+
+       var this_media_path string
+
+       if ms.Type == "image" {
+
+               this_media_path = imagePath + media_key + "." + ms.Extension
+
+       } else if ms.Type == "video" {
+
+               this_media_path = videoPath + media_key + "." + ms.Extension
+       }
+
+       err = os.Remove(this_media_path)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to delete media: rm: %s", err.Error())
+       }
+
+       err = os.Remove(this_file_path)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to delete media: rmkey: %s", err.Error())
+       }
+
+       return nil
+}
+
+func DeleteVideo(media_key string) error {
+
+       var ms MediaStruct
+
+       this_file_path := mediaPath + media_key + ".json"
+
+       file_b, err := os.ReadFile(this_file_path)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to delete video: %s", err.Error())
+
+       }
+
+       err = json.Unmarshal(file_b, &ms)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to delete video: marshal: %s", err.Error())
+       }
+
+       this_video_path := videoPath + media_key + "." + ms.Extension
+
+       err = os.Remove(this_video_path)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to delete video: rmvid: %s", err.Error())
+       }
+
+       err = os.Remove(this_file_path)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to delete video: rmmd: %s", err.Error())
+       }
+
+       return nil
+}
+
+func DownloadVideo(c *gin.Context, watchId string) error {
+
+       ms, err := GetByMediaKeyFromMedia(watchId)
+
+       if ms == nil {
+
+               return fmt.Errorf("failed to download video: %s", err.Error())
+
+       }
+
+       if ms.Type != "video" {
+
+               return fmt.Errorf("failed to download video: %s: %s", "wrong type", ms.Type)
+       }
+
+       this_video_path := videoPath + watchId + "." + ms.Extension
+
+       if _, err := os.Stat(this_video_path); err != nil {
+
+               return err
+
+       }
+
+       c.Header("Content-Type", "video/"+ms.Extension)
+
+       c.File(this_video_path)
+
+       return nil
+}
+
+func LoadLogStat() ([]byte, error) {
+
+       this_log_path := logPath + "stat.json"
+
+       file_b, err := os.ReadFile(this_log_path)
+
+       if err != nil {
+
+               return nil, fmt.Errorf("failed to load log stat: %s", err.Error())
+       }
+
+       return file_b, nil
+
+}
+
+func UnloadLogStat(content []byte) error {
+
+       this_log_path := logPath + "stat.json"
+
+       err := os.WriteFile(this_log_path, content, 0644)
+
+       if err != nil {
+               return fmt.Errorf("failed to save log stat: %s", err.Error())
+       }
+
+       return nil
+
+}
+
+func UnloadLogDetail(timestamp string, logDetail []byte) error {
+
+       this_log_path := logPath + timestamp + ".txt"
+
+       err := os.WriteFile(this_log_path, logDetail, 0644)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to save log detail: %s", err.Error())
+
+       }
+
+       return nil
+
+}
diff --git a/pkg/log/log.go b/pkg/log/log.go
new file mode 100644 (file)
index 0000000..285f7db
--- /dev/null
@@ -0,0 +1,189 @@
+package log
+
+import (
+       "encoding/json"
+       "log"
+       "sync"
+       "time"
+
+       "github.com/seantywork/sorrylinus-again/pkg/dbquery"
+)
+
+var FLUSH_INTERVAL_SEC int
+
+type LogStruct struct {
+       LogRouteCount map[string]int `json:"log_route_count"`
+}
+
+type LogDetailStruct struct {
+       LogTime   time.Time `json:"log_time"`
+       LogRoute  string    `json:"log_route"`
+       LogDetail string    `json:"log_detail"`
+}
+
+var LOGD_QUEUE []LogDetailStruct
+
+var LOGS LogStruct
+
+var GMTX sync.Mutex
+
+func InitLog() {
+
+       ResetLOGS()
+
+       go AutomaticLogFlush()
+
+       log.Println("initiated log")
+}
+
+func ResetLOGS() {
+
+       LOGS.LogRouteCount = nil
+
+       LOGS.LogRouteCount = make(map[string]int)
+}
+
+func AutomaticLogFlush() {
+
+       ticker := time.NewTicker(time.Duration(FLUSH_INTERVAL_SEC) * time.Second)
+
+       for {
+
+               select {
+
+               case <-ticker.C:
+
+                       LogFlush()
+
+                       log.Printf("log flushed")
+               }
+
+       }
+
+}
+
+func LogFlush() {
+
+       GMTX.Lock()
+
+       log_len := len(LOGD_QUEUE)
+
+       var logStat_b = make([]byte, 0)
+
+       var logDetail_b = make([]byte, 0)
+
+       var oldLs LogStruct
+
+       oldLs.LogRouteCount = make(map[string]int)
+
+       new_line := []byte("\n")
+
+       ls, err := dbquery.LoadLogStat()
+
+       if err != nil {
+
+               log.Printf("error log flush: load: %s\n", err.Error())
+
+               return
+       }
+
+       err = json.Unmarshal(ls, &oldLs)
+
+       if err != nil {
+
+               log.Printf("error log flush: unmarshal: %s\n", err.Error())
+
+               return
+       }
+
+       for k, v := range LOGS.LogRouteCount {
+
+               count, okay := oldLs.LogRouteCount[k]
+
+               if !okay {
+
+                       oldLs.LogRouteCount[k] = v
+
+               } else {
+
+                       oldLs.LogRouteCount[k] += count + v
+
+               }
+
+       }
+
+       logStat_b, err = json.Marshal(oldLs)
+
+       if err != nil {
+
+               log.Printf("error log flush: unmarshal new stat: %s\n", err.Error())
+
+               return
+       }
+
+       for i := 0; i < log_len; i++ {
+
+               ld := LOGD_QUEUE[i]
+
+               jb, _ := json.Marshal(ld)
+
+               logDetail_b = append(logDetail_b, jb...)
+
+               logDetail_b = append(logDetail_b, new_line...)
+
+       }
+
+       c_time := time.Now()
+
+       c_time_fmt := c_time.Format("2006-01-02-15-04-05")
+
+       err = dbquery.UnloadLogStat(logStat_b)
+
+       if err != nil {
+
+               log.Printf("error log flush: unload log stat: %s\n", err.Error())
+
+               return
+
+       }
+
+       err = dbquery.UnloadLogDetail(c_time_fmt, logDetail_b)
+
+       if err != nil {
+
+               log.Printf("error log flush: unload log detail: %s\n", err.Error())
+
+               return
+
+       }
+
+       GMTX.Unlock()
+
+}
+
+func PushLog(logRoute string, logDetail string) {
+
+       GMTX.Lock()
+
+       log_detail := LogDetailStruct{
+               LogRoute:  logRoute,
+               LogTime:   time.Now().UTC(),
+               LogDetail: logDetail,
+       }
+
+       route_count, okay := LOGS.LogRouteCount[logRoute]
+
+       if !okay {
+
+               LOGS.LogRouteCount[logRoute] = 1
+
+       } else {
+
+               LOGS.LogRouteCount[logRoute] += route_count + 1
+       }
+
+       LOGD_QUEUE = append(LOGD_QUEUE, log_detail)
+
+       GMTX.Unlock()
+
+}
diff --git a/pkg/manage/manage.go b/pkg/manage/manage.go
new file mode 100644 (file)
index 0000000..91e5c30
--- /dev/null
@@ -0,0 +1,38 @@
+package manage
+
+import (
+       "fmt"
+       "log"
+       "net/http"
+
+       "github.com/gin-gonic/gin"
+       pkgauth "github.com/seantywork/sorrylinus-again/pkg/auth"
+       "github.com/seantywork/sorrylinus-again/pkg/com"
+       pkglog "github.com/seantywork/sorrylinus-again/pkg/log"
+)
+
+func GetManualLogFlush(c *gin.Context) {
+
+       log.Println("incoming flush log")
+
+       _, my_type, _ := pkgauth.WhoAmI(c)
+
+       if my_type != "admin" {
+
+               fmt.Printf("log flush: not admin\n")
+
+               c.JSON(http.StatusForbidden, com.SERVER_RE{Status: "error", Reply: "you're not admin"})
+
+               return
+
+       }
+       var resp com.SERVER_RE
+
+       pkglog.LogFlush()
+
+       resp.Status = "success"
+       resp.Reply = "flush executed"
+
+       c.JSON(200, resp)
+
+}
index 7e085fd68bae4c1ea4709f4cdaca416149d84088..b362a647b41f11c58f66256c19d64a6e648cabfc 100644 (file)
@@ -597,6 +597,26 @@ async function deleteUser(userId){
 }
 
 
+async function flushLog(){
+
+    let options = {
+        method: "GET"
+    }
+    let result = await fetch("/api/manage/log/flush", options)
+
+    let data = await result.json()
+
+    if(data.status != "success"){
+
+        alert("failed to flush log")
+
+        return
+    }
+
+    alert("successfully flushed log: "+ data.reply)
+
+}
+
 
 
 (async function (){
index 9dad2442ef51cc2415151f98ca231da819e86980..6418ae71a29364ae2ab28beb42720769a2f3a479 100644 (file)
@@ -11,6 +11,7 @@
 
     {{ if .logged_in }}
     <a href="/api/auth/signout"> Sign Out </a>
+    <br>
     <a href="/mypage"> My Page </a>
     {{ else }}
     <a href="/signin"> Sign in </a>
index 80eccecaf30ea13f39c28af7bcdd2668bd11a0c7..a603f342adce49daabf1ff2a1dae488f284f86a7 100644 (file)
     <input type="text" id="create-user-duration">
     <br>
     <input type="button" onclick="createUser()" value="create">
-
+    <br>
     <div id="user-reader"></div>
 
+    <br>
+    <h3> Log </h3>
+    <input type="button" onclick="flushLog()" value="flush">
+    <br>
 
   </body>