penguin/golifehk

@golifehk bot in Telegram

commit 446847a7a8c8a8bd04c3b33064076ec236ccd326

author斟酌 鵬兄 <tgckpg@gmail.com>
date2023-01-05T18:22:12Z
subjectAdded option to disable chat
commit 446847a7a8c8a8bd04c3b33064076ec236ccd326
Author: 斟酌 鵬兄 <tgckpg@gmail.com>
Date:   2023-01-05T18:22:12Z

    Added option to disable chat
---
 .gitignore      |  1 +
 main.go         | 12 +++++++-
 utils/cache.go  | 61 ++++++++++++++++++++++++++++++++++---
 utils/system.go | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 162 insertions(+), 5 deletions(-)

diff --git a/.gitignore b/.gitignore
index dcc712c..d07f2ff 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+.DS_Store
 ./golifehk
 *.csv
 *.json
diff --git a/main.go b/main.go
index 8559168..525c91d 100644
--- a/main.go
+++ b/main.go
@@ -4,6 +4,7 @@ import (
     "fmt"
     "log"
     "os"
+    utils "github.com/tgckpg/golifehk/utils"
     mtrbus "github.com/tgckpg/golifehk/datasources/mtr/bus"
     kmb "github.com/tgckpg/golifehk/datasources/kmb"
     query "github.com/tgckpg/golifehk/query"
@@ -42,6 +43,14 @@ func main() {
         log.Printf( "[%s] %s", update.Message.From.UserName, update.Message.Text )
         isGroup := ( update.Message.Chat.ID < 0 )
 
+        mesg, processed := utils.SystemControl( update.Message )
+        if processed {
+            if mesg != "" {
+                botsend( bot, &update, &mesg )
+            }
+            continue
+        }
+
         f_queries := []func( string, string ) query.IQueryResult{
             mtrbus.Query,
             kmb.Query,
@@ -50,7 +59,8 @@ func main() {
         var f_sent bool = false
         var f_err error = nil
         for _, Query := range f_queries {
-            mesg, err := Query( "zh-Hant", update.Message.Text ).Message()
+            var err error
+            mesg, err = Query( "zh-Hant", update.Message.Text ).Message()
 
             if err == nil {
                 f_sent = true
diff --git a/utils/cache.go b/utils/cache.go
index 1fea008..c61c404 100644
--- a/utils/cache.go
+++ b/utils/cache.go
@@ -10,13 +10,13 @@ import (
 )
 
 
-func CacheStream( path string, readStream func() ( io.ReadCloser, error ), expires int ) ( *bytes.Buffer, error ) {
+func CacheStream( path string, readStream func() ( io.ReadCloser, error ), expires time.Duration ) ( *bytes.Buffer, error ) {
 
     cache, err := os.Stat( path )
 
     // Check if cache exists and not expired
     if err == nil {
-        expired := cache.ModTime().Add( 60 * 1e9 )
+        expired := cache.ModTime().Add( expires * 1e9 )
         if time.Now().Before( expired ) {
             f, err := os.Open( path )
             if err == nil {
@@ -33,8 +33,7 @@ func CacheStream( path string, readStream func() ( io.ReadCloser, error ), expir
 
     err = os.MkdirAll( filepath.Dir( path ), 0750 )
     if err != nil {
-        return nil, err
-    }
+        return nil, err }
 
     writeBuff := bytes.NewBuffer( []byte{} )
 
@@ -66,3 +65,57 @@ func CacheStream( path string, readStream func() ( io.ReadCloser, error ), expir
 
     return writeBuff, nil
 }
+
+func ChangedStream( path string, readStream func() ( io.Reader, error ), dataModTime time.Time ) ( *bytes.Buffer, error ) {
+
+    cache, err := os.Stat( path )
+
+    // Check if cache exists and not expired
+    if err == nil {
+        if dataModTime.Before( cache.ModTime() ) {
+            f, err := os.Open( path )
+            if err == nil {
+                defer f.Close()
+                log.Printf( "Reading from file: %s", path )
+                writeBuff := bytes.NewBuffer( []byte{} )
+                _, err = io.Copy( writeBuff, f )
+                if err == nil {
+                    return writeBuff, nil
+                }
+            }
+        }
+    }
+
+    err = os.MkdirAll( filepath.Dir( path ), 0750 )
+    if err != nil {
+        return nil, err
+    }
+
+    writeBuff := bytes.NewBuffer( []byte{} )
+
+    // Get the reader that return new data
+    s, err := readStream()
+    if err != nil {
+        return nil, err
+    }
+
+    _, err = io.Copy( writeBuff, s )
+    if err != nil {
+        return nil, err
+    }
+
+    f, err := os.OpenFile( path, os.O_CREATE | os.O_WRONLY | os.O_TRUNC, 0644 )
+    if err != nil {
+        return nil, err
+    }
+
+    defer f.Close()
+
+    data := writeBuff.Bytes()
+    _, err = io.Copy( f, bytes.NewReader( data ) )
+    if err != nil {
+        return nil, err
+    }
+
+    return writeBuff, nil
+}
diff --git a/utils/system.go b/utils/system.go
new file mode 100644
index 0000000..ec52be4
--- /dev/null
+++ b/utils/system.go
@@ -0,0 +1,93 @@
+package utils
+
+import (
+    "bytes"
+    "encoding/json"
+    "fmt"
+    "io"
+    "log"
+    "path/filepath"
+    "strings"
+    "time"
+    tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
+)
+
+var JSON_SETTINGS string = filepath.Join( WORKDIR, "settings.json" )
+
+var settingsTime = time.Unix( 0, 0 )
+
+type SysSettings struct {
+    IgnoredChats map[int64] bool `json:"IgnoredChats"`
+}
+
+var Settings = SysSettings{ IgnoredChats: map[int64] bool{} }
+
+func rwSettings() {
+
+    buff, err := ChangedStream( JSON_SETTINGS, writeSettings, settingsTime )
+    if err != nil {
+        log.Panic( err )
+        return
+    }
+
+    conf := SysSettings{}
+    err = json.Unmarshal( buff.Bytes(), &conf )
+    if err != nil {
+        log.Panic( err )
+        return
+    }
+
+    Settings = conf
+}
+
+func writeSettings() ( io.Reader, error ) {
+    b, err := json.Marshal( Settings )
+    if err != nil {
+        return nil, err
+    }
+    return bytes.NewBuffer( b ), nil
+}
+
+func SystemControl( tgMesg *tgbotapi.Message ) ( string, bool ) {
+
+    rwSettings()
+
+    processed := false
+    mesg := ""
+
+    if tgMesg.Text[0] == '/' {
+        processed = true
+    }
+
+    chatId := tgMesg.Chat.ID
+
+    if Settings.IgnoredChats == nil {
+        Settings.IgnoredChats = map[int64] bool{}
+    }
+
+    if strings.Contains( tgMesg.Text, "/golifehk disable" ) {
+        mesg = fmt.Sprintf( "OK" )
+        Settings.IgnoredChats[ chatId ] = true
+        processed = true
+    }
+
+    if strings.Contains( tgMesg.Text, "/golifehk enable" ) {
+        mesg = fmt.Sprintf( "OK" )
+        Settings.IgnoredChats[ chatId ] = false
+        processed = true
+    }
+
+    if processed {
+        settingsTime = time.Now()
+        rwSettings()
+    }
+
+    //// Begin processing settings
+
+    // ignore chats if enabled
+    if Settings.IgnoredChats[ chatId ] {
+        processed = true
+    }
+
+    return mesg, processed
+}