diff --git a/alfred.go b/alfred.go index 476ca53..c55159d 100644 --- a/alfred.go +++ b/alfred.go @@ -2,7 +2,7 @@ * @Author: Bartuccio Antoine * @Date: 2018-07-23 15:24:22 * @Last Modified by: Bartuccio Antoine -* @Last Modified time: 2019-01-04 10:52:37 +* @Last Modified time: 2019-01-05 17:47:10 */ package main @@ -19,6 +19,7 @@ import ( ) func main() { + registeredCommands := map[string]func(*tb.Message){ tb.OnText: commands.OnText, "/registerprivate": commands.RegisterPrivate, diff --git a/shared/chat.go b/shared/chat.go index c5b29a1..5578e6b 100644 --- a/shared/chat.go +++ b/shared/chat.go @@ -2,13 +2,14 @@ * @Author: Bartuccio Antoine * @Date: 2018-07-27 15:37:59 * @Last Modified by: Bartuccio Antoine -* @Last Modified time: 2019-01-04 10:49:45 +* @Last Modified time: 2019-01-05 17:46:26 */ package shared import ( "encoding/json" + "fmt" "io/ioutil" "sync" ) @@ -25,23 +26,28 @@ type chatDataFile struct { } // ChatData manage access to stored data about a chat -var ChatData chatData +var ChatData *chatData var cdf chatDataFile // InitChatData is meant to store infos about a chat. -func InitChatData(path string) { - cdf = chatDataFile{path: path} - ChatData = chatData{data: make(map[int64]map[string]interface{})} +func InitChatData(chatDataFilePath string) { + + cdf = chatDataFile{path: chatDataFilePath} + ChatData = &chatData{data: make(map[int64]map[string]interface{})} + ChatData.mutex.Lock() defer ChatData.mutex.Unlock() + cdf.read() } // Set stores data about a chat -func (c chatData) Set(chat int64, key string, data interface{}) { +func (c *chatData) Set(chat int64, key string, data interface{}) { + c.mutex.Lock() defer c.mutex.Unlock() + if _, exists := c.data[chat]; !exists { c.data[chat] = make(map[string]interface{}) } @@ -50,9 +56,11 @@ func (c chatData) Set(chat int64, key string, data interface{}) { } // Get retrieves data about a chat -func (c chatData) Get(chat int64, key string) (interface{}, bool) { +func (c *chatData) Get(chat int64, key string) (interface{}, bool) { + c.mutex.Lock() defer c.mutex.Unlock() + m, exists := c.data[chat] if !exists { return nil, false @@ -64,22 +72,35 @@ func (c chatData) Get(chat int64, key string) (interface{}, bool) { return data, true } -func (c chatDataFile) read() { +func (c *chatDataFile) read() { + c.mutex.Lock() defer c.mutex.Unlock() + data, err := ioutil.ReadFile(c.path) if err != nil { // File doesn't exist, skip import return } - json.Unmarshal(data, &ChatData.data) + if err := json.Unmarshal(data, &ChatData.data); err != nil { + fmt.Printf("Error while unmarshaling chat data with path %s, error : %v\n", c.path, err) + } } -func (c chatDataFile) write() { +func (c *chatDataFile) write() { + c.mutex.Lock() defer c.mutex.Unlock() + ChatData.mutex.Lock() defer ChatData.mutex.Unlock() - data, _ := json.Marshal(ChatData.data) - ioutil.WriteFile(c.path, data, 0770) + + data, err := json.Marshal(ChatData.data) + if err != nil { + fmt.Printf("Error while marshaling chat data file with path %s, error : %v\n", c.path, err) + return + } + if err := ioutil.WriteFile(c.path, data, 0770); err != nil { + fmt.Printf("Error writing chat data file with path %s, error %v\n", c.path, err) + } } diff --git a/shared/history.go b/shared/history.go index 3be9c46..daa55b4 100644 --- a/shared/history.go +++ b/shared/history.go @@ -2,13 +2,14 @@ * @Author: Bartuccio Antoine * @Date: 2018-07-24 01:27:11 * @Last Modified by: Bartuccio Antoine -* @Last Modified time: 2019-01-04 10:51:32 +* @Last Modified time: 2019-01-05 17:45:18 */ package shared import ( "encoding/json" + "fmt" "io/ioutil" "sync" ) @@ -25,32 +26,39 @@ type historyFile struct { } // History manages acces to chat history -var History history +var History *history var hf historyFile // InitHistory init a chit history of a given size -func InitHistory(size int, history_file_path string) { +func InitHistory(size int, historyFilePath string) { + hf = historyFile{} - hf.path = history_file_path - History = history{} + hf.path = historyFilePath + History = &history{} + History.mutex.Lock() defer History.mutex.Unlock() + History.size = size History.data = make(map[int64][]string) hf.read() } // Size get the number of messages saved in the history -func (h history) Size() int { +func (h *history) Size() int { + h.mutex.Lock() defer h.mutex.Unlock() + return h.size } // Message get a selected message in a chat history -func (h history) Message(chatID int64, n int) string { +func (h *history) Message(chatID int64, n int) string { + h.mutex.Lock() defer h.mutex.Unlock() + array, exists := h.data[chatID] if exists && n >= 0 && n < len(array) { return array[n] @@ -59,9 +67,11 @@ func (h history) Message(chatID int64, n int) string { } // AddMessage append a message to a given chat -func (h history) AddMessage(chatID int64, m string) { +func (h *history) AddMessage(chatID int64, m string) { + h.mutex.Lock() defer h.mutex.Unlock() + if _, exists := h.data[chatID]; !exists { h.data[chatID] = make([]string, h.size, h.size) } @@ -69,9 +79,11 @@ func (h history) AddMessage(chatID int64, m string) { } // LastMessage get the last message of a given chat -func (h history) LastMessage(chatID int64) string { +func (h *history) LastMessage(chatID int64) string { + h.mutex.Lock() defer h.mutex.Unlock() + if _, exists := h.data[chatID]; exists { return h.data[chatID][h.size-1] } @@ -79,9 +91,11 @@ func (h history) LastMessage(chatID int64) string { } // ChatHistory get a copy of a given chat history -func (h history) ChatHistory(chatID int64) []string { +func (h *history) ChatHistory(chatID int64) []string { + h.mutex.Lock() defer h.mutex.Unlock() + array, exists := h.data[chatID] if exists { c := make([]string, h.size, h.size) @@ -93,7 +107,8 @@ func (h history) ChatHistory(chatID int64) []string { // Add a message at the end of a chat and move everithyng up // Assert that the slice exists and mutex already locked -func (h history) append(chatID int64, m string) { +func (h *history) append(chatID int64, m string) { + c := make([]string, h.size-1, h.size-1) array, _ := h.data[chatID] copy(c, array[1:]) @@ -104,22 +119,35 @@ func (h history) append(chatID int64, m string) { go hf.write() } -func (h historyFile) read() { +func (h *historyFile) read() { + h.mutex.Lock() defer h.mutex.Unlock() + data, err := ioutil.ReadFile(h.path) if err != nil { // File doesn't exist, skip import return } - json.Unmarshal(data, &History.data) + if err := json.Unmarshal(data, &History.data); err != nil { + fmt.Printf("Error while unmarshaling user history with path %s, error : %v\n", h.path, err) + } } -func (h historyFile) write() { +func (h *historyFile) write() { + h.mutex.Lock() defer h.mutex.Unlock() + History.mutex.Lock() defer History.mutex.Unlock() - data, _ := json.Marshal(History.data) - ioutil.WriteFile(h.path, data, 0770) + + data, err := json.Marshal(History.data) + if err != nil { + fmt.Printf("Error while marshaling history file with path %s, error : %v\n", h.path, err) + return + } + if err := ioutil.WriteFile(h.path, data, 0770); err != nil { + fmt.Printf("Error writing history file with path %s, error %v\n", h.path, err) + } } diff --git a/shared/users.go b/shared/users.go index 118cd31..1b5449f 100644 --- a/shared/users.go +++ b/shared/users.go @@ -2,7 +2,7 @@ * @Author: Bartuccio Antoine * @Date: 2018-07-24 14:41:03 * @Last Modified by: Bartuccio Antoine -* @Last Modified time: 2019-01-04 10:52:13 +* @Last Modified time: 2019-01-05 17:45:59 */ package shared @@ -27,24 +27,29 @@ type usersFile struct { } // Users shared user for commands -var Users users +var Users *users var uf usersFile // InitUsers inits the User info storage -func InitUsers(users_file_path string) { +func InitUsers(usersFilePath string) { + uf = usersFile{} - uf.path = users_file_path - Users = users{} + uf.path = usersFilePath + Users = &users{} + Users.mutex.Lock() defer Users.mutex.Unlock() + Users.data = make(map[string]map[string]string) uf.read() } // Get an info about a given user -func (u users) Get(username string, key string) (string, bool) { +func (u *users) Get(username string, key string) (string, bool) { + u.mutex.Lock() defer u.mutex.Unlock() + user, exists := u.data[username] if !exists { return "", false @@ -56,9 +61,11 @@ func (u users) Get(username string, key string) (string, bool) { } // Set add an info about a given user -func (u users) Set(username string, key, data string) { +func (u *users) Set(username string, key, data string) { + u.mutex.Lock() defer u.mutex.Unlock() + if _, exists := u.data[username]; !exists { u.data[username] = make(map[string]string) } @@ -67,9 +74,11 @@ func (u users) Set(username string, key, data string) { } // GetUsernames get all usernames stored in settings -func (u users) GetUsernames() []string { +func (u *users) GetUsernames() []string { + u.mutex.Lock() defer u.mutex.Unlock() + var usernames []string for username := range u.data { usernames = append(usernames, username) @@ -78,7 +87,8 @@ func (u users) GetUsernames() []string { } // GetUserChat retrieve the chat of the user if registered -func (u users) GetUserChat(username string) (*tb.Chat, error) { +func (u *users) GetUserChat(username string) (*tb.Chat, error) { + serializedChat, exists := u.Get(username, "private_chat") if !exists { return nil, fmt.Errorf("No private chat registered for %s", username) @@ -93,7 +103,8 @@ func (u users) GetUserChat(username string) (*tb.Chat, error) { } // SetUserChat register a private chat for an user -func (u users) SetUserChat(username string, chat *tb.Chat) { +func (u *users) SetUserChat(username string, chat *tb.Chat) { + serializedChat, err := json.Marshal(chat) if err != nil { return @@ -102,22 +113,35 @@ func (u users) SetUserChat(username string, chat *tb.Chat) { u.Set(username, "private_chat", string(serializedChat)) } -func (u usersFile) read() { +func (u *usersFile) read() { + u.mutex.Lock() defer u.mutex.Unlock() + data, err := ioutil.ReadFile(u.path) if err != nil { // File doesn't exist, skip import return } - json.Unmarshal(data, &Users.data) + if err := json.Unmarshal(data, &Users.data); err != nil { + fmt.Printf("Error while unmarshaling user file with path %s, error : %v\n", u.path, err) + } } -func (u usersFile) write() { +func (u *usersFile) write() { + u.mutex.Lock() defer u.mutex.Unlock() + Users.mutex.Lock() defer Users.mutex.Unlock() - data, _ := json.Marshal(Users.data) - ioutil.WriteFile(u.path, data, 0770) + + data, err := json.Marshal(Users.data) + if err != nil { + fmt.Printf("Error while marshaling user file with path %s, error : %v\n", u.path, err) + return + } + if err := ioutil.WriteFile(u.path, data, 0770); err != nil { + fmt.Printf("Error writing user file with path %s, error : %v\n", u.path, err) + } }