TooManySugar 3 năm trước cách đây
mục cha
commit
4b7f726320

+ 0 - 0
ethermineapi/api_structs.go → api/ethermineapi/api_structs.go


+ 10 - 10
ethermineapi/unmasrshal_url.go → api/ethermineapi/unmasrshal_url.go

@@ -26,7 +26,7 @@ func downloadBytesUrl(url string) (jsonData []byte, err error) {
 	}
 
 	return jsonData, nil
-}  
+}
 
 func removeNulls(data []byte) []byte{
 	// Convert []byte to string
@@ -34,10 +34,10 @@ func removeNulls(data []byte) []byte{
 	dataStr = strings.ReplaceAll(dataStr, "null", "0")
 
 	// Covenrt string ot []byte
-	return []byte(dataStr)	
-}  
+	return []byte(dataStr)
+}
 
-// Unmarahals JSON from specified url to v 
+// Unmarahals JSON from specified url to v
 // Usage example:
 // <url> - string with web url to raw json data
 // <JsonStruct> - struct type that describes json data at <url>
@@ -119,12 +119,12 @@ func Payouts(pool, wallet string) (JsonPayouts, error) {
 	// if err != nil {
 	// 	return payouts, err
 	// }
-	// 
+	//
 	// if !dataExists {
 	// 	return workers, fmt.Errorf("no data for workers of %s", wallet)
 	// }
-	
-	err = json.Unmarshal(jsonData, &payouts) 
+
+	err = json.Unmarshal(jsonData, &payouts)
 	if err != nil {
 		return payouts, fmt.Errorf("couldn't parse payouts from %s\n%v", url, err)
 	}
@@ -133,15 +133,15 @@ func Payouts(pool, wallet string) (JsonPayouts, error) {
 }
 
 // IsDataExists checks if Data part of json is not string
-// TODO Redo this using dynamic Json unmarshaling 
+// TODO Redo this using dynamic Json unmarshaling
 func IsDataExists(data [] byte) (bool, error) {
 
 	var base baseResponce
 	err := json.Unmarshal(data, &base)
 	if err != nil {
-		return false, fmt.Errorf("couldn't get base response from %s")
+		return false, fmt.Errorf("couldn't get base response from %s", err.Error())
 	}
-	
+
 	if string(base.Data) == "\"NO DATA\"" {
 		return false, nil
 	}

+ 0 - 3
botsettings/go.mod

@@ -1,3 +0,0 @@
-module botsettings
-
-go 1.17

+ 14 - 0
cmd/handler/action_handler.go

@@ -0,0 +1,14 @@
+package handler
+
+import (
+	"gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/internal/database"
+)
+
+type ActionHandler struct {
+	dbconn *database.Connection
+}
+
+func New(dbconn *database.Connection) *ActionHandler {
+	ah := &ActionHandler{dbconn: dbconn}
+	return ah
+}

+ 152 - 0
cmd/handler/actual.go

@@ -0,0 +1,152 @@
+package handler
+
+import (
+	"fmt"
+	"math"
+	"time"
+	tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
+	ethmineapi "gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/api/ethermineapi"
+	"gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/internal/database"
+	log "gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/internal/logger"
+	"gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/cmd/settings"
+)
+
+func (ah ActionHandler) getActualDataFromDatabaseHandler(chatId int64) (msgs []tgbotapi.MessageConfig) {
+
+	mT := tgbotapi.NewMessage(chatId, "")
+
+	errMsgToUser := "An exception occurred on sending messages while executing /actual command"
+	var wallet string
+	result := ah.dbconn.GormDb.Model(&database.User{}).
+		Where("chat_id = ?", chatId).
+		Select("wallet").
+		Scan(&wallet)
+
+	if result.Error != nil {
+		log.LogError.Println(result.Error)
+		mT.Text = errMsgToUser
+		return []tgbotapi.MessageConfig{ mT }
+	}
+
+	if wallet == "" {
+		mT.Text = "Set wallet at first! Use /setwallet"
+		return []tgbotapi.MessageConfig{ mT }
+	}
+
+	var lastMinerRecord database.Miner
+	result = ah.dbconn.GormDb.
+		Where(&database.Miner{Wallet: wallet}).
+		Order("time desc").
+		Limit(1).
+		Find(&lastMinerRecord)
+
+	if result.Error != nil {
+		log.LogError.Println(result.Error)
+
+		mT.Text = "No miner data for now!"
+		return []tgbotapi.MessageConfig{ mT }
+	}
+
+	var lastTime int64
+	result = ah.dbconn.GormDb.
+		Model(&database.Worker{}).
+		Where("wallet = ?", wallet).
+		Select("MAX(time)").
+		Scan(&lastTime)
+
+	if result.Error != nil {
+		log.LogError.Println(result.Error)
+
+		mT.Text = errMsgToUser
+		return []tgbotapi.MessageConfig{ mT }
+	}
+
+	var lastWorkerRecord []database.Worker
+	result = ah.dbconn.GormDb.
+		Where(&database.Worker{Wallet: wallet, Time: lastTime}).
+		Find(&lastWorkerRecord)
+
+	if result.Error != nil {
+		log.LogError.Println(result.Error)
+
+		mT.Text = errMsgToUser
+		return []tgbotapi.MessageConfig{ mT }
+	}
+
+	if len(lastWorkerRecord) == 0 {
+		mT.Text =  "No workers data for now!"
+		return []tgbotapi.MessageConfig{ mT }
+	}
+
+	mT.Text  = fmt.Sprintf("Miner %s stats:\n", lastMinerRecord.Wallet)
+	mT.Text += fmt.Sprintf("Updated: %s\n", time.Unix(lastMinerRecord.Time, 0).Format("Monday, January 2, 2006 3:04 PM"))
+	mT.Text += fmt.Sprintf("Reported Hashrate: %.3f MH/s\n", math.Round(float64(lastMinerRecord.ReportedHashrate)/1000)/1000)
+	mT.Text += fmt.Sprintf("Current Hashrate: %.3f MH/s\n", math.Round(float64(lastMinerRecord.CurrentHashrate)/1000)/1000)
+	mT.Text += fmt.Sprintf("Valid Shares: %d\n", lastMinerRecord.ValidShares)
+	mT.Text += fmt.Sprintf("Stale Shares: %d\n", lastMinerRecord.StaleShares)
+	mT.Text += fmt.Sprintf("Workers: %d\n", lastMinerRecord.Workers)
+	mT.Text += fmt.Sprintf("Unpaid Balance: %.5f ETH\n", float64(lastMinerRecord.Unpaid)/math.Pow10(18)) //TODO ETH = AppSettings.currency
+
+	msgs = append(msgs, mT)
+
+	for i := range lastWorkerRecord {
+		// Per worker message
+		// Anti spam filter
+		if i != 0 && i%20 == 0 { //TODO SOMETIHNG BETTER THAN USUAL TIMER
+			time.Sleep(30 * time.Second)
+		}
+
+		msgText := fmt.Sprintf("Worker %s stats:\n", lastWorkerRecord[i].Worker)
+		msgText += fmt.Sprintf("Updated: %s\n", time.Unix(lastWorkerRecord[i].Time, 0).Format("Monday, January 2, 2006 3:04 PM"))
+		msgText += fmt.Sprintf("Reported Hashrate: %.3f MH/s\n", math.Round(float64(lastWorkerRecord[i].ReportedHashrate)/1000)/1000)
+		msgText += fmt.Sprintf("Current Hashrate: %.3f MH/s\n", math.Round(float64(lastWorkerRecord[i].CurrentHashrate)/1000)/1000)
+		msgText += fmt.Sprintf("Valid Shares: %d\n", lastWorkerRecord[i].ValidShares)
+		msgText += fmt.Sprintf("Stale Shares: %d\n", lastWorkerRecord[i].StaleShares)
+		msgText += fmt.Sprintf("Unpaid Balance: %.5f ETH\n", float64(lastWorkerRecord[i].WorkerUnpaid)/math.Pow10(18)) //TODO ETH = AppSettings.currency
+		mW := tgbotapi.NewMessage(chatId, msgText)
+		msgs = append(msgs, mW)
+	}
+
+	return msgs
+}
+
+func (ah ActionHandler) getActualDataHandler(chatId int64, miner string) []tgbotapi.MessageConfig {
+
+	getActualData := func(miner string) string {
+		url := fmt.Sprintf("%s/miner/%s/currentStats", settings.ApiUrl(), miner)
+		var currentStats ethmineapi.JsonCurrentStats
+		err := ethmineapi.UnmasrshalFromUrl(url, &currentStats)
+		if err != nil {
+			// As in original...
+			return "An exception occurred while executing this command."
+			// return fmt.Sprintf("No data for specified wallet\n")
+		}
+
+		data := currentStats.Data
+
+		actualData := fmt.Sprintf("Stats of miner\n%s\n", miner)
+		actualData += fmt.Sprintf("Updated: %s\n", time.Unix(data.Time, 0).Format("Monday, January 2, 2006 3:04 PM"))
+		actualData += fmt.Sprintf("Reported Hashrate: %.3f MH/s\n", math.Round(float64(data.ReportedHashrate)/1000)/1000)
+		actualData += fmt.Sprintf("Current Hashrate: %.3f MH/s\n", math.Round(data.CurrentHashrate/1000)/1000)
+		actualData += fmt.Sprintf("Valid Shares: %d\n", data.ValidShares)
+		actualData += fmt.Sprintf("Stale Shares: %d\n", data.StaleShares)
+		actualData += fmt.Sprintf("Workers: %d\n", data.ActiveWorkers)
+		actualData += fmt.Sprintf("Unpaid Balance: %.5f ETH\n", float64(data.Unpaid)/math.Pow10(18))
+
+		return actualData
+	}
+
+	return []tgbotapi.MessageConfig{
+		tgbotapi.NewMessage(chatId, getActualData(miner))}
+}
+
+func (ah ActionHandler) ActualHandler(chatId int64, params []string) []tgbotapi.MessageConfig {
+	if len(params) == 0 {
+		return ah.getActualDataFromDatabaseHandler(chatId)
+	}
+	if len(params) == 1 {
+		return ah.getActualDataHandler(chatId, params[0])
+	}
+
+	return []tgbotapi.MessageConfig{tgbotapi.NewMessage(chatId, "usage: /actual [wallet]")}
+}

+ 16 - 0
cmd/handler/forceupdate.go

@@ -0,0 +1,16 @@
+package handler
+
+import (
+	tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
+)
+
+func (ah ActionHandler) ForceUpdateHandler(chatId int64, params []string) []tgbotapi.MessageConfig {
+	if len(params) != 0 {
+		return []tgbotapi.MessageConfig{tgbotapi.NewMessage(chatId, "usage: /forceupdate")}
+	}
+
+	ah.dbconn.UpdateData()
+
+	return []tgbotapi.MessageConfig{
+		tgbotapi.NewMessage(chatId, "Done!")}
+}

+ 29 - 0
cmd/handler/help.go

@@ -0,0 +1,29 @@
+package handler
+
+import (
+	tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
+)
+
+func getHelp() (help string) {
+	// TODO separate help variable
+	help = "This is bot tracks your miner stats and calculates unpaid per worker.\n"
+	help += "How to start:\n"
+	help += "1) \"/start\" - it will add you to database\n"
+	help += "2) \"/setwallet <wallet>\" - it will set wallet for tracking, bot will start to add info about your miner and workers to database\n"
+	help += "3) \"/actual\" - it will send you up to date data about your worker\n"
+	help += "4) \"/lastpayout\" - it will send you last payout data with calculated worker unpaid for that period if avaliable\n"
+	help += "5) \"/stop\" - it will clear all data about you from database\n"
+	help += "Additional commands:\n"
+	help += "\"/rate\" - get actual ETH and BTC rate from ethermine\n"
+	help += "\"/actual <wallet>\" - get up to date data about any wallet without unpaid per worker\n"
+	return help
+}
+
+func (ah ActionHandler) GetHelpHandler(chatId int64, params []string) []tgbotapi.MessageConfig {
+	if len(params) != 0 {
+		return []tgbotapi.MessageConfig{tgbotapi.NewMessage(chatId, "usage: /help")}
+	}
+
+	return []tgbotapi.MessageConfig{
+		tgbotapi.NewMessage(chatId, getHelp())}
+}

+ 14 - 0
cmd/handler/lastpayout.go

@@ -0,0 +1,14 @@
+package handler
+
+import (
+	tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
+)
+
+func (ah ActionHandler) LastPayoutHandler(chatId int64, params []string) []tgbotapi.MessageConfig {
+	if len(params) != 0 {
+		return []tgbotapi.MessageConfig{tgbotapi.NewMessage(chatId, "usage: /lastpayout")}
+	}
+
+	return []tgbotapi.MessageConfig{
+		tgbotapi.NewMessage(chatId, ah.dbconn.GetLastPayout(chatId))}
+}

+ 78 - 0
cmd/handler/message_handler.go

@@ -0,0 +1,78 @@
+package handler
+
+import (
+	"strings"
+	"time"
+
+	tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
+	log "gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/internal/logger"
+)
+
+func (ah ActionHandler )HandleMessage(reqMsg *tgbotapi.Message, botClient *tgbotapi.BotAPI) {
+	log.LogInfo.Printf("Received a text message in chat %d [%s]:%s", reqMsg.Chat.ID, reqMsg.From.UserName, reqMsg.Text)
+
+	args := strings.Split(reqMsg.Text, " ")
+
+	prefix := "/"
+	command := args[0]
+	if (!strings.HasPrefix(command, prefix)) {
+		return
+	}
+	command = strings.TrimPrefix(command, prefix)
+
+	params := args[1:]
+
+	var msgs []tgbotapi.MessageConfig
+
+	var commandHandler func(chatId int64, params []string) []tgbotapi.MessageConfig
+
+	switch command {
+
+	case "start":
+		commandHandler = ah.StartHandler
+		break
+
+	case "stop":
+		commandHandler = ah.StopHandler
+		break
+
+	case "forceupdate":
+		commandHandler = ah.ForceUpdateHandler
+		break
+
+	case "actual":
+		commandHandler = ah.ActualHandler
+		break
+
+	case "setwallet":
+		commandHandler = ah.SetWalletHandler
+		break
+
+	case "rate":
+		commandHandler = ah.GetActualRateHandler
+		break
+
+	case "help":
+		commandHandler = ah.GetHelpHandler
+		break
+
+	case "lastpayout":
+		commandHandler = ah.LastPayoutHandler
+		break
+
+	default:
+		return
+	}
+
+	msgs = commandHandler(reqMsg.Chat.ID, params)
+
+	for n, m := range msgs {
+		if n != 0 {
+			time.Sleep(1 * time.Second)
+		}
+
+		botClient.Send(m)
+
+		log.LogInfo.Printf("Replied with: %s", strings.ReplaceAll(m.Text, "\n", "\\n"))
+	}
+}

+ 31 - 0
cmd/handler/rate.go

@@ -0,0 +1,31 @@
+package handler
+
+import (
+	tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
+	ethmineapi "gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/api/ethermineapi"
+	"gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/cmd/settings"
+	"fmt"
+)
+
+func (ah ActionHandler) GetActualRateHandler(chatId int64, params []string) []tgbotapi.MessageConfig {
+	if len(params) != 0 {
+		return []tgbotapi.MessageConfig{tgbotapi.NewMessage(chatId, "usage: /rate")}
+	}
+
+
+	getActualRate := func() string {
+		url := fmt.Sprintf("%s/networkStats", settings.ApiUrl())
+		var networkStats ethmineapi.JsonNetworkStats
+		err := ethmineapi.UnmasrshalFromUrl(url, &networkStats)
+		if err != nil {
+			return fmt.Sprintf("Error with getting data from %s", settings.ApiUrl())
+		}
+		data := networkStats.Data
+		actualRate := fmt.Sprintf("ETH: %.2f\nBTC: %.2f", data.Usd, float64(data.Usd)/float64(data.Btc))
+		return actualRate
+	}
+
+
+	return []tgbotapi.MessageConfig{
+		tgbotapi.NewMessage(chatId, getActualRate())}
+}

+ 66 - 0
cmd/handler/setwallet.go

@@ -0,0 +1,66 @@
+package handler
+
+import (
+	tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
+	"fmt"
+	"gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/internal/database"
+	log "gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/internal/logger"
+)
+
+// whata
+var wrongFormatErr error = fmt.Errorf("Wrong format!")
+
+// returns wallet in format 0x%.40s or error if format is wrong
+func parseWallet(walletStr string) (wallet string, err error) {
+	if len(walletStr) == 40 {
+		return "0x" + walletStr, nil
+	}
+	if len(walletStr) == 42 && walletStr[0] == '0' && walletStr[1] == 'x' {
+		return walletStr, nil
+	}
+
+	return "", wrongFormatErr
+}
+
+func (ah ActionHandler) SetWalletHandler(chatId int64, params []string) []tgbotapi.MessageConfig {
+
+	if len(params) != 1 {
+		return []tgbotapi.MessageConfig{tgbotapi.NewMessage(chatId, "usage: /setwallet <wallet>")}
+	}
+
+	walletStr := params[0]
+
+	// Check if user registered
+	var user database.User
+	ah.dbconn.GormDb.
+		Model(&database.User{}).
+		Where(&database.User{ChatId: chatId}).FirstOrInit(&user)
+
+	if user == (database.User{}) {
+		return []tgbotapi.MessageConfig{
+			tgbotapi.NewMessage(chatId, "You are not registered! Type /start first!")}
+	}
+
+	wallet, err := parseWallet(walletStr)
+	if err != nil {
+		if err == wrongFormatErr {
+			return []tgbotapi.MessageConfig{
+				tgbotapi.NewMessage(chatId, "wallet must be in format:\n" +
+											"[0x]****************************************!")}
+		}
+	}
+
+	user.Wallet = wallet
+
+	err = ah.dbconn.GormDb.Save(&user).Error
+	if err != nil {
+		log.LogError.Printf("failed querying user: %s", err.Error())
+		return []tgbotapi.MessageConfig{
+			tgbotapi.NewMessage(chatId, "An exception occurred while executing this command.")}
+	}
+
+	log.LogInfo.Printf("Updated wallet of user %d to %s\n", chatId, wallet)
+
+	return []tgbotapi.MessageConfig{
+		tgbotapi.NewMessage(chatId, fmt.Sprintf("%s set!", wallet))}
+}

+ 21 - 0
cmd/handler/start.go

@@ -0,0 +1,21 @@
+package handler
+
+import (
+	tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
+	log "gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/internal/logger"
+)
+
+func (ah ActionHandler) StartHandler(chatId int64, params []string) []tgbotapi.MessageConfig {
+	if len(params) != 0 {
+		return []tgbotapi.MessageConfig{tgbotapi.NewMessage(chatId, "usage: /start")}
+	}
+
+	text, err := ah.dbconn.AddUser(chatId)
+	if err != nil {
+		log.LogError.Println(err)
+		text = "Internal error, please contact bot developer"
+	}
+
+	return []tgbotapi.MessageConfig{
+		tgbotapi.NewMessage(chatId, text)}
+}

+ 21 - 0
cmd/handler/stop.go

@@ -0,0 +1,21 @@
+package handler
+
+import (
+	tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
+	log "gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/internal/logger"
+)
+
+func (ah ActionHandler) StopHandler(chatId int64, params []string) []tgbotapi.MessageConfig {
+	if len(params) != 0 {
+		return []tgbotapi.MessageConfig{tgbotapi.NewMessage(chatId, "usage: /stop")}
+	}
+
+	text, err := ah.dbconn.DeleteUser(chatId)
+	if err != nil {
+		log.LogError.Println(err)
+		text = "Internal error, please contact bot developer"
+	}
+
+	return []tgbotapi.MessageConfig{
+		tgbotapi.NewMessage(chatId, text)}
+}

+ 34 - 37
main.go → cmd/main.go

@@ -2,7 +2,7 @@ package main
 
 import (
 	"fmt"
-	"log"
+	log "gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/internal/logger"
 	"bufio"
 	"os"
 	"time"
@@ -10,63 +10,60 @@ import (
 
 	tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
 
-	"GoEthemineTelegramBot/botsettings"
-)
-
+	"gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/cmd/settings"
+	"gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/internal/database"
 
-var (
-	dBConnector Connection
-	myBotClient tgbotapi.BotAPI
-
-	LogInfo  *log.Logger
-	LogWarn  *log.Logger
-	LogError *log.Logger
-	LogDebug *log.Logger
+	"gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/cmd/handler"
 )
 
+
 func main() {
+	var dBConnector database.Connection
+	var globalHandler *handler.ActionHandler
+
 	settingsPath := "config.json"
 	LoadSettings(settingsPath)
 
-	LoggersInit()
-	LogInfo.Println("App started")
+	log.LoggersInit()
+    log.LogInfo.Println("App started")
 
-	botClient, err := tgbotapi.NewBotAPI(botsettings.Token())
+	botClient, err := tgbotapi.NewBotAPI(settings.Token())
 	if err != nil {
-		LogError.Panic(err)
+		log.LogError.Panic(err)
 	}
-	myBotClient = *botClient
+
 	var me = botClient.Self
-	LogInfo.Printf("Hello, World! I am user %d and my name is %s.\n", me.ID, me.FirstName)
 
 	if len(os.Args[1:]) >= 2 {
-		botsettings.SetDbUser(os.Args[1])
-		botsettings.SetDbPassword(os.Args[2])
+		settings.SetDbUser(os.Args[1])
+		settings.SetDbPassword(os.Args[2])
 	} else {
 		var username string
 		fmt.Print("DataBase Username:")
 		_, err := fmt.Scanln(&username)
 		if err != nil {
-			LogError.Println(os.Stderr, err)
+			log.LogError.Println(err)
 			return
 		}
-		botsettings.SetDbUser(username)
+		settings.SetDbUser(username)
 
-		var password string 
+		var password string
 		fmt.Print("DataBase Password:")
 		_, err = fmt.Scanln(&password)
 		if err != nil {
-			LogError.Println(os.Stderr, err)
+			log.LogError.Println(err)
 			return
 		}
-		botsettings.SetDbPassword(password)
+		settings.SetDbPassword(password)
 	}
-	
+
 	dBConnector.Init()
 
-	go Updater()
-	go Listener(botClient)
+	globalHandler = handler.New(&dBConnector)
 
+	go Updater(&dBConnector)
+	go Listener(botClient, globalHandler)
+	log.LogInfo.Printf("Started at @%s\n", me.UserName)
 	fmt.Println("Press Enter to exit")
 	reader := bufio.NewReader(os.Stdin)
 	reader.ReadString('\n')
@@ -75,7 +72,7 @@ func main() {
 
 
 // Listens for comming messages.
-func Listener(botClient *tgbotapi.BotAPI) {
+func Listener(botClient *tgbotapi.BotAPI, handler *handler.ActionHandler) {
 	u := tgbotapi.NewUpdate(0)
 	u.Timeout = 60
 
@@ -87,23 +84,23 @@ func Listener(botClient *tgbotapi.BotAPI) {
 			continue
 		}
 
-		go HandleMessage(update.Message, botClient)
+		go handler.HandleMessage(update.Message, botClient)
 	}
 }
 
 // Starts DataUpdater goroutine every 4 minutes
-func Updater() {
-	LogInfo.Println("Scheduler started!")
+func Updater(c *database.Connection) {
+	log.LogInfo.Println("Scheduler started!")
 	for {
-		go UpdateData()
+		go c.UpdateData()
 		time.Sleep(4 * time.Minute)
 	}
 }
 
-// LoadSettings load settings from settingsPath 
+// LoadSettings load settings from settingsPath
 // and then saves them again for keep up-to-date struct
 func LoadSettings(settingsPath string) {
-	err := botsettings.LoadFromFile(settingsPath)
+	err := settings.LoadFromFile(settingsPath)
 	if err != nil {
 		if !strings.Contains(err.Error(), "The system cannot find the file specified") {
 			fmt.Println(err)
@@ -118,9 +115,9 @@ func LoadSettings(settingsPath string) {
 
 		path += "\\"+ settingsPath
      	fmt.Printf("The system cannot find the config file.\nCreating new config file at:\n%s\n", path)
-      	botsettings.SaveToFile(path)
+      	settings.SaveToFile(path)
       	fmt.Println("Please fill the config file")
       	os.Exit(0)
 	}
-	botsettings.SaveToFile(settingsPath)
+	settings.SaveToFile(settingsPath)
 }

+ 2 - 2
botsettings/file.go → cmd/settings/file.go

@@ -1,4 +1,4 @@
-package botsettings
+package settings
 
 import (
 	"os"
@@ -7,7 +7,7 @@ import (
 
 func LoadFromFile(filepath string) error {
 	b, err := os.ReadFile(filepath)
-    if err != nil { 
+    if err != nil {
     	return err
     }
 

+ 16 - 16
botsettings/settings.go → cmd/settings/settings.go

@@ -1,4 +1,4 @@
-package botsettings
+package settings
 
 import (
 	// "os"
@@ -7,7 +7,7 @@ import (
 	// "encoding/json"
 )
 
-var botSettings = Init() 
+var botSettings = Init()
 
 type settings struct{
 	Token 			string
@@ -25,23 +25,23 @@ type settings struct{
 }
 
 // type Base interface {
-// 	
+//
 // }
 
 func Init() settings {
 	var s settings
 	return s
-} 
+}
 /*
  *	'SETs'
  */
 // SetDbPassword sets botSettings.DbPassword to password
 func SetDbPassword(password string) {
-	botSettings.DbPassword = password	
+	botSettings.DbPassword = password
 }
 // SetDbUser sets botSettings.DbUser to user
 func SetDbUser(user string) {
-	botSettings.DbUser = user	
+	botSettings.DbUser = user
 }
 
 // func SetParam(param string) {
@@ -50,9 +50,9 @@ func SetDbUser(user string) {
 
 /*
  *	'GETs'
- */ 
+ */
 func Token() string {
-	return botSettings.Token 
+	return botSettings.Token
 }
 
 func ApiUrl() string {
@@ -93,36 +93,36 @@ func ErrorLogPath() string {
 func FullLogPath() string {
 	return botSettings.FullLogPath
 }
- 
+
 
 // func (s *settings) setParam(newParam string) {
 // 	s.param = newParam
 // }
-// 
+//
 // func (s *settings) getParam() string {
 // 	return s.param
 // }
 
 // func LoadFromFile(filepath string) error {
 // 	b, err := os.ReadFile(filepath)
-//     if err != nil { 
+//     if err != nil {
 //     	return err
 //     }
-// 
+//
 // 	return json.Unmarshal(b, &botSettings)
 // }
-// 
-// 
+//
+//
 // func SaveToFile(filepath string) err error {
 // 	res, err := json.MarshalIndent(s, "", "    ")
 // 	if err != nil {
 //         log.Panic(err)
 //     }
-// 
+//
 //     err = os.WriteFile(filepath, res, 0666)
 //     if err != nil {
 // 		return
 // 	}
 // 	return nil
 // }
-// 
+//

+ 0 - 3
ethermineapi/go.mod

@@ -1,3 +0,0 @@
-module ethermineapi
-
-go 1.17

+ 14 - 9
go.mod

@@ -1,21 +1,26 @@
-module gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/code
+module gogs.veloe.link/toomanysugar/GoEthemineTelegramBot
 
 go 1.17
 
+//gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/api/ethermineapi v0.0.0-unpublished
+//gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/cmd/handler v0.0.0-unpublished
+//gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/cmd/settings v0.0.0-unpublished
+require github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible
+
 require (
-	github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible
-	gorm.io/driver/mysql v1.1.3
-	gorm.io/gorm v1.22.2
+	gorm.io/driver/mysql v1.3.2
+	gorm.io/gorm v1.23.4
 )
 
 require (
-	GoEthemineTelegramBot/ethermineapi v0.0.0-unpublished // indirect
-	GoEthemineTelegramBot/botsettings v0.0.0-unpublished // indirect
 	github.com/go-sql-driver/mysql v1.6.0 // indirect
 	github.com/jinzhu/inflection v1.0.0 // indirect
-	github.com/jinzhu/now v1.1.2 // indirect
+	github.com/jinzhu/now v1.1.4 // indirect
 	github.com/technoweenie/multipartstreamer v1.0.1 // indirect
 )
 
-replace GoEthemineTelegramBot/ethermineapi v0.0.0-unpublished => ./ethermineapi
-replace GoEthemineTelegramBot/botsettings v0.0.0-unpublished => ./botsettings
+// replace gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/api/ethermineapi v0.0.0-unpublished => ./api/ethermineapi
+
+// replace gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/cmd/handler v0.0.0-unpublished => ./cmd/handler
+
+// replace gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/cmd/settings v0.0.0-unpublished => ./cmd/settings

+ 7 - 7
go.sum

@@ -4,12 +4,12 @@ github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible h1:2cauKuaEL
 github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible/go.mod h1:qf9acutJ8cwBUhm1bqgz6Bei9/C/c93FPDljKWwsOgM=
 github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
 github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
-github.com/jinzhu/now v1.1.2 h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI=
-github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
+github.com/jinzhu/now v1.1.4 h1:tHnRBy1i5F2Dh8BAFxqFzxKqqvezXrL2OW1TnX+Mlas=
+github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
 github.com/technoweenie/multipartstreamer v1.0.1 h1:XRztA5MXiR1TIRHxH2uNxXxaIkKQDeX7m2XsSOlQEnM=
 github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6MDx5eUJoiEBsSvzDU9uzog=
-gorm.io/driver/mysql v1.1.3 h1:+5g1UElqN0sr2gZqmg9djlu1zT3cErHiscc6+IbLHgw=
-gorm.io/driver/mysql v1.1.3/go.mod h1:4P/X9vSc3WTrhTLZ259cpFd6xKNYiSSdSZngkSBGIMM=
-gorm.io/gorm v1.21.12/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
-gorm.io/gorm v1.22.2 h1:1iKcvyJnR5bHydBhDqTwasOkoo6+o4Ms5cknSt6qP7I=
-gorm.io/gorm v1.22.2/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
+gorm.io/driver/mysql v1.3.2 h1:QJryWiqQ91EvZ0jZL48NOpdlPdMjdip1hQ8bTgo4H7I=
+gorm.io/driver/mysql v1.3.2/go.mod h1:ChK6AHbHgDCFZyJp0F+BmVGb06PSIoh9uVYKAlRbb2U=
+gorm.io/gorm v1.23.1/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
+gorm.io/gorm v1.23.4 h1:1BKWM67O6CflSLcwGQR7ccfmC4ebOxQrTfOQGRE9wjg=
+gorm.io/gorm v1.23.4/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=

+ 0 - 356
handlers.go

@@ -1,356 +0,0 @@
-// Response creators 
-package main
-
-import (
-	"fmt"
-	"strings"
-	"time"
-	"math"
-
-	tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
-
-	ethmineapi "GoEthemineTelegramBot/ethermineapi"
-	"GoEthemineTelegramBot/botsettings"
-)
-
-func (c *Connection) AddUser(reqChat *tgbotapi.Chat) (string, error) {
-	// Check if user already registered
-	var userCount int64
-	result := c.GormDb.Model(&User{}).
-		Where("chat_id = ?", reqChat.ID).
-		Count(&userCount)
-	if result.Error != nil {
-		return "", fmt.Errorf("failed creating user: %w", result.Error)
-	}
-	if userCount != 0 {
-		return "Already registered", nil
-	}
-
-	// Adding new user to database
-	newUser := User{ChatId: reqChat.ID}
-	result = c.GormDb.Create(newUser)
-	if result.Error != nil {
-		return "", fmt.Errorf("failed creating user: %w", result.Error)
-	}
-	LogInfo.Println("User was created:", newUser)
-	return "Added new user to database. Now you can connect your miner wallet using command /setwallet <address>", nil
-}
-
-
-func (c *Connection) SetWallet(reqMsg *tgbotapi.Message) (string, error) {
-	// Check if user already registered
-	var userCount int64
-	result := c.GormDb.Model(&User{}).
-		Where("chat_id = ?", reqMsg.Chat.ID).
-		Count(&userCount)
-	if result.Error != nil {
-		return "", fmt.Errorf("failed wallet set: %w", result.Error)
-	}
-	if userCount == 0 {
-		return "You are not registered! Type /start first!", nil
-	}
-
-	// *Strange* check for length of predifined eth wallet hash
-	if len(strings.Split(reqMsg.Text, " ")[1]) > 2 {
-		// Check if wallet hash typed with 0x
-		// TODO Should be: starts with '0x' or in format 0x....
-		if strings.Contains(strings.Split(reqMsg.Text, " ")[1], "0x") {
-			// TODO replace inefficient branching
-			result = c.GormDb.Model(&User{}).
-				Where("chat_id = ?", reqMsg.Chat.ID).
-				Update("wallet", strings.Split(reqMsg.Text, " ")[1])
-			if result.Error != nil {
-				return "", fmt.Errorf("failed querying user: %w", result.Error)
-			}
-		} else {
-			result = c.GormDb.Model(&User{}).
-				Where("chat_id = ?", reqMsg.Chat.ID).
-				Update("wallet", "0x"+strings.Split(reqMsg.Text, " ")[1])
-			if result.Error != nil {
-				return "", fmt.Errorf("failed querying user: %w", result.Error)
-			}
-		}
-		LogInfo.Printf("Updated wallet of user %d to %s\n", reqMsg.Chat.ID, strings.Split(reqMsg.Text, " ")[1])
-		// TODO     this is ▼▼  lame bro
-		return fmt.Sprintf("0x%s set!", strings.Split(reqMsg.Text, " ")[1]), nil
-	} else {
-		return "Too short!", nil
-	}
-}
-
-func (c *Connection) DeleteUser(reqChat *tgbotapi.Chat) (string, error) {
-	// Check for user existance
-	var userCount int64
-	result := c.GormDb.Model(&User{}).
-		Where("chat_id = ?", reqChat.ID).
-		Count(&userCount)
-	if result.Error != nil {
-		return "", fmt.Errorf("failed creating user: %w", result.Error)
-	}
-	if userCount == 0 {
-		return "Already deleted", nil
-	}
-
-	// Taking target for deletion
-	var user User
-	result = c.GormDb.Take(&user, "chat_id = ?", reqChat.ID)
-	if result.Error != nil {
-		return "", fmt.Errorf("failed querying user: %w", result.Error)
-	}
-
-	var walletHoldersCount int64
-	result = c.GormDb.Model(&User{}).
-		Where("wallet = ?", user.Wallet).
-		Count(&walletHoldersCount)
-	if result.Error != nil {
-		return "", fmt.Errorf("failed querying user: %w", result.Error)
-	}
-
-	// TODO Remove code repition
-	if walletHoldersCount > 1 {
-		// Wallet in multiple chats
-		result = c.GormDb.Where("chat_id = ?", reqChat.ID).Delete(User{})
-		if result.Error != nil {
-			return "", fmt.Errorf("failed deleting user: %w", result.Error)
-		}
-	} else {
-		// Wallet in single chat
-		result = c.GormDb.Where("chat_id = ?", reqChat.ID).Delete(User{})
-		if result.Error != nil {
-			return "", fmt.Errorf("failed deleting user: %w", result.Error)
-		}
-		
-		result = c.GormDb.Where("wallet = ?", user.Wallet).Delete(Miner{})
-		if result.Error != nil {
-			return "", fmt.Errorf("failed deleting miner: %w", result.Error)
-		}
-		LogInfo.Println("Miners deleted with wallet:", user.Wallet)
-
-		result = c.GormDb.Where("wallet = ?", user.Wallet).Delete(Worker{})
-		if result.Error != nil {
-			return "", fmt.Errorf("failed deleting workers: %w", result.Error)
-		}
-		LogInfo.Println("Workers deleted with wallet:", user.Wallet)
-
-		result = c.GormDb.Where("wallet = ?", user.Wallet).Delete(Payout{})
-		if result.Error != nil {
-			return "", fmt.Errorf("failed deleting payouts: %w", result.Error)
-		}
-		LogInfo.Println("Payouts deleted for wallet:", user.Wallet)
-	}
-
-	LogInfo.Println("User was deleted:", user)
-	return "Done!", nil
-}
-
-func (c *Connection) GetActualDataFromDatabase(chatId int64) string {
-	errMsgToUser := "An exception occurred on sending messages while executing /actual command"
-	var wallet string
-	result := c.GormDb.Model(&User{}).
-		Where("chat_id = ?", chatId).
-		Select("wallet").
-		Scan(&wallet)
-	if result.Error != nil {
-		LogError.Println(result.Error)
-		return errMsgToUser
-	}
-	if wallet == "" {
-		return "Set wallet at first! Use /setwallet"
-	}
-
-	var lastMinerRecord Miner
-	result = c.GormDb.
-		Where(&Miner{Wallet: wallet}).
-		Order("time desc").
-		Limit(1).
-		Find(&lastMinerRecord)
-	if result.Error != nil {
-		LogError.Println(result.Error)
-		return "No miner data for now!"
-	}
-
-	var lastTime int64
-	result = c.GormDb.Model(&Worker{}).
-		Where("wallet = ?", wallet).
-		Select("MAX(time)").
-		Scan(&lastTime)
-	if result.Error != nil {
-		LogError.Println(result.Error)
-		return errMsgToUser
-	}
-
-	var lastWorkerRecord []Worker
-	result = c.GormDb.
-		Where(&Worker{Wallet: wallet, Time: lastTime}).
-		Find(&lastWorkerRecord)
-	if result.Error != nil {
-		LogError.Println(result.Error)
-		return errMsgToUser
-	}
-
-	if len(lastWorkerRecord) == 0 {
-		return "No workers data for now!"
-	}
-
-	msgText := fmt.Sprintf("Miner %s stats:\n", lastMinerRecord.Wallet)
-	msgText += fmt.Sprintf("Updated: %s\n", time.Unix(lastMinerRecord.Time, 0).Format("Monday, January 2, 2006 3:04 PM"))
-	msgText += fmt.Sprintf("Reported Hashrate: %.3f MH/s\n", math.Round(float64(lastMinerRecord.ReportedHashrate)/1000)/1000)
-	msgText += fmt.Sprintf("Current Hashrate: %.3f MH/s\n", math.Round(float64(lastMinerRecord.CurrentHashrate)/1000)/1000)
-	msgText += fmt.Sprintf("Valid Shares: %d\n", lastMinerRecord.ValidShares)
-	msgText += fmt.Sprintf("Stale Shares: %d\n", lastMinerRecord.StaleShares)
-	msgText += fmt.Sprintf("Workers: %d\n", lastMinerRecord.Workers)
-	msgText += fmt.Sprintf("Unpaid Balance: %.5f ETH\n", float64(lastMinerRecord.Unpaid)/math.Pow10(18)) //TODO ETH = AppSettings.currency
-
-	msg := tgbotapi.NewMessage(chatId, msgText)
-	myBotClient.Send(msg)
-	LogInfo.Printf("Replied with: %s", strings.ReplaceAll(msg.Text, "\n", "\\n"))
-
-	for i := range lastWorkerRecord {
-		// Per worker message
-		time.Sleep(1 * time.Second)
-
-		// Anti spam filter
-		if i != 0 && i%20 == 0 { //TODO SOMETIHNG BETTER THAN USUAL TIMER
-			time.Sleep(30 * time.Second)
-		}
-
-		msgText := fmt.Sprintf("Worker %s stats:\n", lastWorkerRecord[i].Worker)
-		msgText += fmt.Sprintf("Updated: %s\n", time.Unix(lastWorkerRecord[i].Time, 0).Format("Monday, January 2, 2006 3:04 PM"))
-		msgText += fmt.Sprintf("Reported Hashrate: %.3f MH/s\n", math.Round(float64(lastWorkerRecord[i].ReportedHashrate)/1000)/1000)
-		msgText += fmt.Sprintf("Current Hashrate: %.3f MH/s\n", math.Round(float64(lastWorkerRecord[i].CurrentHashrate)/1000)/1000)
-		msgText += fmt.Sprintf("Valid Shares: %d\n", lastWorkerRecord[i].ValidShares)
-		msgText += fmt.Sprintf("Stale Shares: %d\n", lastWorkerRecord[i].StaleShares)
-		msgText += fmt.Sprintf("Unpaid Balance: %.5f ETH\n", float64(lastWorkerRecord[i].WorkerUnpaid)/math.Pow10(18)) //TODO ETH = AppSettings.currency
-		msg := tgbotapi.NewMessage(chatId, msgText)
-		myBotClient.Send(msg)
-		LogInfo.Printf("Replied with: %s", strings.ReplaceAll(msg.Text, "\n", "\\n"))
-	}
-
-	return "nice"
-}
-
-func (c *Connection) GetLastPayout(chatId int64) string {
-	errMsgToUser := "An exception occurred on sending messages while executing /actual command"
-
-	var wallet string
-	result := c.GormDb.Model(&User{}).
-		Where(User{ChatId: chatId}).
-		Select("wallet").
-		Scan(&wallet)
-	if result.Error != nil {
-		LogError.Println(result.Error)
-		return errMsgToUser
-	}
-	if wallet == "" {
-		return "Set wallet at first! Use /setwallet"
-	}
-
-	var payoutTime int64
-	result = c.GormDb.Model(&Payout{}).
-		Where(&Payout{Wallet: wallet}).
-		Order("time desc").
-		Limit(1).
-		Select("time").
-		Scan(&payoutTime)
-	if result.Error != nil {
-		LogInfo.Printf("No payouts data for %s! Time is set to 0!", wallet)
-		LogError.Println(result.Error)
-		payoutTime = 0
-	}
-
-	// NOTE Pointless if previous 'if' statement occurs
-	// Must go from the start to line 235
-	var dbPayoutRecords []Payout
-	result = c.GormDb.
-		Where(&Payout{Wallet: wallet, Time: payoutTime}).
-		Find(&dbPayoutRecords)
-	//Line 560 of Program.cs
-	if len(dbPayoutRecords) == 0 {
-		url := fmt.Sprintf("%s/miner/%s/payouts", botsettings.ApiUrl(), wallet)
-		var payouts ethmineapi.JsonPayouts
-		err := ethmineapi.UnmasrshalFromUrl(url, &payouts)
-		if err != nil {
-			LogError.Println(err)
-			return fmt.Sprintf("No payout data for %s", wallet)
-		}
-		lastPayout := payouts.Data[0]
-
-		message := fmt.Sprintf("Payout date: %s\n", time.Unix(lastPayout.PaidOn, 0).Format("Monday, January 2, 2006 3:04 PM"))
-		message += fmt.Sprintf("Amount: %.5f %s\n", float64(lastPayout.Amount)/math.Pow10(18), botsettings.Currency())
-		message += "Data source: Ethermine API \n"
-
-		return message
-	}
-	if result.Error != nil {
-		LogError.Println(result.Error)
-		return errMsgToUser
-	}
-
-	//Line 545 of Program.cs
-	message := fmt.Sprintf("Payout date: %s\n", time.Unix(dbPayoutRecords[0].Time, 0).Format("Monday, January 2, 2006 3:04 PM"))
-	message += fmt.Sprintf("Amount: %.5f ETH\n", float64(dbPayoutRecords[0].Amount)/math.Pow10(18))
-
-	for _, payoutRecord := range dbPayoutRecords {
-		message += fmt.Sprintf("Worker %s paid: %.5f %s\n",
-			payoutRecord.Worker,
-			float64(payoutRecord.Amount)/math.Pow10(18),
-			botsettings.Currency())
-	}
-
-	message += "Data source: Bot database \n"
-
-	return message
-}
-
-
-
-func GetActualRate() string {
-	url := fmt.Sprintf("%s/networkStats", botsettings.ApiUrl())
-	var networkStats ethmineapi.JsonNetworkStats
-	err := ethmineapi.UnmasrshalFromUrl(url, &networkStats)
-	if err != nil {
-		return fmt.Sprintf("Error with getting data from %s", botsettings.ApiUrl())
-	}
-	data := networkStats.Data
-	actualRate := fmt.Sprintf("ETH: %.2f\nBTC: %.2f", data.Usd, float64(data.Usd)/float64(data.Btc))
-	return actualRate
-}
-
-func GetActualData(miner string) string {
-	url := fmt.Sprintf("%s/miner/%s/currentStats", botsettings.ApiUrl(), miner)
-	var currentStats ethmineapi.JsonCurrentStats
-	err := ethmineapi.UnmasrshalFromUrl(url, &currentStats)
-	if err != nil {
-		// As in original...
-		return "An exception occurred while executing this command."
-		// return fmt.Sprintf("No data for specified wallet\n")
-	}
-
-	data := currentStats.Data
-
-	actualData := fmt.Sprintf("Stats of miner\n%s\n", miner)
-	actualData += fmt.Sprintf("Updated: %s\n", time.Unix(data.Time, 0).Format("Monday, January 2, 2006 3:04 PM"))
-	actualData += fmt.Sprintf("Reported Hashrate: %.3f MH/s\n", math.Round(float64(data.ReportedHashrate)/1000)/1000)
-	actualData += fmt.Sprintf("Current Hashrate: %.3f MH/s\n", math.Round(data.CurrentHashrate/1000)/1000)
-	actualData += fmt.Sprintf("Valid Shares: %d\n", data.ValidShares)
-	actualData += fmt.Sprintf("Stale Shares: %d\n", data.StaleShares)
-	actualData += fmt.Sprintf("Workers: %d\n", data.ActiveWorkers)
-	actualData += fmt.Sprintf("Unpaid Balance: %.5f ETH\n", float64(data.Unpaid)/math.Pow10(18))
-
-	return actualData
-}
-
-func GetHelp() (help string) {
-	// TODO separate help variable
-	help = "This is bot tracks your miner stats and calculates unpaid per worker.\n"
-	help += "How to start:\n"
-	help += "1) \"/start\" - it will add you to database\n"
-	help += "2) \"/setwallet <wallet>\" - it will set wallet for tracking, bot will start to add info about your miner and workers to database\n"
-	help += "3) \"/actual\" - it will send you up to date data about your worker\n"
-	help += "4) \"/lastpayout\" - it will send you last payout data with calculated worker unpaid for that period if avaliable\n"
-	help += "5) \"/stop\" - it will clear all data about you from database\n"
-	help += "Additional commands:\n"
-	help += "\"/rate\" - get actual ETH and BTC rate from ethermine\n"
-	help += "\"/actual <wallet>\" - get up to date data about any wallet without unpaid per worker\n"
-	return help
-}

+ 16 - 15
connection.go → internal/database/connection.go

@@ -1,4 +1,4 @@
-package main
+package database
 
 import (
 	"fmt"
@@ -6,7 +6,8 @@ import (
 	"gorm.io/gorm"
 	"gorm.io/driver/mysql"
 
-	"GoEthemineTelegramBot/botsettings"
+	log "gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/internal/logger"
+	"gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/cmd/settings"
 )
 
 type ConnectionProperties struct {
@@ -23,23 +24,23 @@ type Connection struct {
 }
 
 func (c *Connection) Init() {
-	c.ConnProperties.User = botsettings.DbUser()
-	c.ConnProperties.Pass = botsettings.DbPassword()
-	c.ConnProperties.Host = botsettings.DbHost()
-	c.ConnProperties.Db   = botsettings.DbName()
+	c.ConnProperties.User = settings.DbUser()
+	c.ConnProperties.Pass = settings.DbPassword()
+	c.ConnProperties.Host = settings.DbHost()
+	c.ConnProperties.Db   = settings.DbName()
 
 
-	c.DbOpenStr = fmt.Sprintf("%s:%s@tcp(%s)/%s", 
+	c.DbOpenStr = fmt.Sprintf("%s:%s@tcp(%s)/%s",
 		c.ConnProperties.User, c.ConnProperties.Pass, c.ConnProperties.Host, c.ConnProperties.Db)
-	LogInfo.Println("Connecting with:")
-	LogInfo.Println(c.DbOpenStr)
+	log.LogInfo.Println("Connecting with:")
+	log.LogInfo.Println(c.DbOpenStr)
 
 	gormDb, err := gorm.Open(mysql.Open(c.DbOpenStr), &gorm.Config{})
 	if err != nil {
-		LogError.Println("failed to connect database")
-		LogError.Println(err)
+		log.LogError.Println("failed to connect database")
+		log.LogError.Println(err)
 	} else {
-		LogInfo.Println("Connected to database using gorm")
+		log.LogInfo.Println("Connected to database using gorm")
 	}
 
 	c.GormDb = gormDb
@@ -52,9 +53,9 @@ func (c *Connection) LatestWorkerRecord(worker string) (lastWorkerRecord Worker,
 		Order("time desc").
 		Limit(1).
 		Find(&lastWorkerRecord)
-	
+
 	return lastWorkerRecord, result.Error
-} 
+}
 
 func (c *Connection) LatestMinerRecord(wallet string) (lastMinerRecord Miner, err error) {
 	result := c.GormDb.
@@ -62,7 +63,7 @@ func (c *Connection) LatestMinerRecord(wallet string) (lastMinerRecord Miner, er
 		Order("time desc").
 		Limit(1).
 		Find(&lastMinerRecord)
-	
+
 	return lastMinerRecord, result.Error
 }
 

+ 172 - 0
internal/database/handlers.go

@@ -0,0 +1,172 @@
+package database
+
+import (
+	"fmt"
+	"time"
+	"math"
+
+	ethmineapi "gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/api/ethermineapi"
+	"gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/cmd/settings"
+	log "gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/internal/logger"
+)
+
+func (c *Connection) AddUser(chatId int64) (string, error) {
+	// Check if user already registered
+	var userCount int64
+	result := c.GormDb.Model(&User{}).
+		Where("chat_id = ?", chatId).
+		Count(&userCount)
+	if result.Error != nil {
+		return "", fmt.Errorf("failed creating user: %w", result.Error)
+	}
+	if userCount != 0 {
+		return "Already registered", nil
+	}
+
+	// Adding new user to database
+	newUser := User{ChatId: chatId}
+	result = c.GormDb.Create(newUser)
+	if result.Error != nil {
+		return "", fmt.Errorf("failed creating user: %w", result.Error)
+	}
+	log.LogInfo.Println("User was created:", newUser)
+	return "Added new user to database. Now you can connect your miner wallet using command /setwallet <address>", nil
+}
+
+func (c *Connection) DeleteUser(chatId int64) (string, error) {
+	// Check for user existance
+	var userCount int64
+	result := c.GormDb.Model(&User{}).
+		Where("chat_id = ?", chatId).
+		Count(&userCount)
+	if result.Error != nil {
+		return "", fmt.Errorf("failed creating user: %w", result.Error)
+	}
+	if userCount == 0 {
+		return "Already deleted", nil
+	}
+
+	// Taking target for deletion
+	var user User
+	result = c.GormDb.Take(&user, "chat_id = ?", chatId)
+	if result.Error != nil {
+		return "", fmt.Errorf("failed querying user: %w", result.Error)
+	}
+
+	var walletHoldersCount int64
+	result = c.GormDb.Model(&User{}).
+		Where("wallet = ?", user.Wallet).
+		Count(&walletHoldersCount)
+	if result.Error != nil {
+		return "", fmt.Errorf("failed querying user: %w", result.Error)
+	}
+
+	// TODO Remove code repition
+	if walletHoldersCount > 1 {
+		// Wallet in multiple chats
+		result = c.GormDb.Where("chat_id = ?", chatId).Delete(User{})
+		if result.Error != nil {
+			return "", fmt.Errorf("failed deleting user: %w", result.Error)
+		}
+	} else {
+		// Wallet in single chat
+		result = c.GormDb.Where("chat_id = ?", chatId).Delete(User{})
+		if result.Error != nil {
+			return "", fmt.Errorf("failed deleting user: %w", result.Error)
+		}
+
+		result = c.GormDb.Where("wallet = ?", user.Wallet).Delete(Miner{})
+		if result.Error != nil {
+			return "", fmt.Errorf("failed deleting miner: %w", result.Error)
+		}
+		log.LogInfo.Println("Miners deleted with wallet:", user.Wallet)
+
+		result = c.GormDb.Where("wallet = ?", user.Wallet).Delete(Worker{})
+		if result.Error != nil {
+			return "", fmt.Errorf("failed deleting workers: %w", result.Error)
+		}
+		log.LogInfo.Println("Workers deleted with wallet:", user.Wallet)
+
+		result = c.GormDb.Where("wallet = ?", user.Wallet).Delete(Payout{})
+		if result.Error != nil {
+			return "", fmt.Errorf("failed deleting payouts: %w", result.Error)
+		}
+		log.LogInfo.Println("Payouts deleted for wallet:", user.Wallet)
+	}
+
+	log.LogInfo.Println("User was deleted:", user)
+	return "Done!", nil
+}
+
+func (c *Connection) GetLastPayout(chatId int64) string {
+	errMsgToUser := "An exception occurred on sending messages while executing /actual command"
+
+	var wallet string
+	result := c.GormDb.Model(&User{}).
+		Where(User{ChatId: chatId}).
+		Select("wallet").
+		Scan(&wallet)
+	if result.Error != nil {
+		log.LogError.Println(result.Error)
+		return errMsgToUser
+	}
+	if wallet == "" {
+		return "Set wallet at first! Use /setwallet"
+	}
+
+	var payoutTime int64
+	result = c.GormDb.Model(&Payout{}).
+		Where(&Payout{Wallet: wallet}).
+		Order("time desc").
+		Limit(1).
+		Select("time").
+		Scan(&payoutTime)
+	if result.Error != nil {
+		log.LogInfo.Printf("No payouts data for %s! Time is set to 0!", wallet)
+		log.LogError.Println(result.Error)
+		payoutTime = 0
+	}
+
+	// NOTE Pointless if previous 'if' statement occurs
+	// Must go from the start to line 235
+	var dbPayoutRecords []Payout
+	result = c.GormDb.
+		Where(&Payout{Wallet: wallet, Time: payoutTime}).
+		Find(&dbPayoutRecords)
+	//Line 560 of Program.cs
+	if len(dbPayoutRecords) == 0 {
+		url := fmt.Sprintf("%s/miner/%s/payouts", settings.ApiUrl(), wallet)
+		var payouts ethmineapi.JsonPayouts
+		err := ethmineapi.UnmasrshalFromUrl(url, &payouts)
+		if err != nil {
+			log.LogError.Println(err)
+			return fmt.Sprintf("No payout data for %s", wallet)
+		}
+		lastPayout := payouts.Data[0]
+
+		message := fmt.Sprintf("Payout date: %s\n", time.Unix(lastPayout.PaidOn, 0).Format("Monday, January 2, 2006 3:04 PM"))
+		message += fmt.Sprintf("Amount: %.5f %s\n", float64(lastPayout.Amount)/math.Pow10(18), settings.Currency())
+		message += "Data source: Ethermine API \n"
+
+		return message
+	}
+	if result.Error != nil {
+		log.LogError.Println(result.Error)
+		return errMsgToUser
+	}
+
+	//Line 545 of Program.cs
+	message := fmt.Sprintf("Payout date: %s\n", time.Unix(dbPayoutRecords[0].Time, 0).Format("Monday, January 2, 2006 3:04 PM"))
+	message += fmt.Sprintf("Amount: %.5f ETH\n", float64(dbPayoutRecords[0].Amount)/math.Pow10(18))
+
+	for _, payoutRecord := range dbPayoutRecords {
+		message += fmt.Sprintf("Worker %s paid: %.5f %s\n",
+			payoutRecord.Worker,
+			float64(payoutRecord.Amount)/math.Pow10(18),
+			settings.Currency())
+	}
+
+	message += "Data source: Bot database \n"
+
+	return message
+}

+ 1 - 1
models.go → internal/database/models.go

@@ -1,5 +1,5 @@
 // Models to represent db fields using gorm
-package main
+package database
 
 type User struct {
 	ChatId      int64

+ 88 - 80
update_data.go → internal/database/update_data.go

@@ -1,4 +1,4 @@
-package main
+package database
 
 import (
 	"fmt"
@@ -7,58 +7,62 @@ import (
 
 	tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
 
-	ethmineapi "GoEthemineTelegramBot/ethermineapi"
-	"GoEthemineTelegramBot/botsettings"
+
+	ethmineapi "gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/api/ethermineapi"
+	"gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/cmd/settings"
+	log "gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/internal/logger"
 )
 
-func UpdateData() {
-	LogInfo.Println("Updating data!")
 
-	walletList, err := dBConnector.UniqueWallets()
+func (c Connection) UpdateData() {
+	_ = tgbotapi.MessageConfig{}
+	log.LogInfo.Println("Updating data!")
+
+	walletList, err := c.UniqueWallets()
 	if err != nil {
-		LogError.Println(err); return
+		log.LogError.Println(err); return
 	}
 
 	for _, wallet := range walletList {
-		UpdateWallet(wallet)
+		c.UpdateWallet(wallet)
 	}
 }
 
-func UpdateWallet(wallet string) {
-	LogInfo.Printf(">> Getting data for wallet %s\n", wallet)
-	LogInfo.Printf("From: %s/miner/%s/currentStats\n", botsettings.ApiUrl(), wallet)
-	
+func (c Connection) UpdateWallet(wallet string) {
+	log.LogInfo.Printf(">> Getting data for wallet %s\n", wallet)
+	log.LogInfo.Printf("From: %s/miner/%s/currentStats\n", settings.ApiUrl(), wallet)
+
 	// Get current stats for miner
-	currentStats, err := ethmineapi.MinerStats(botsettings.ApiUrl(), wallet)
+	currentStats, err := ethmineapi.MinerStats(settings.ApiUrl(), wallet)
 	if err != nil {
 		if strings.Contains(err.Error(), "no data for miner") {
-			LogWarn.Println(err)
+			log.LogWarn.Println(err)
 		} else {
-			LogError.Println(err)
+			log.LogError.Println(err)
 		}
 		return
 	}
 
 	if currentStats.Status != "OK" {
-		LogError.Printf("Error getting response from pool for %s!\n", wallet); 
+		log.LogError.Printf("Error getting response from pool for %s!\n", wallet);
 		return
 	}
 
 	// Line 42 of UpdateData.cs
 	// Search for the latest record for miner
-	lastMinerRecord, err := dBConnector.LatestMinerRecord(wallet)
+	lastMinerRecord, err := c.LatestMinerRecord(wallet)
 	if err != nil {
-		LogError.Println(err)
+		log.LogError.Println(err)
 		return
 	}
 
 	// Exist previous record with the same time
 	if lastMinerRecord.Time == currentStats.Data.Time {
-		LogInfo.Printf("Row with wallet: %s and time: %d already exists!", wallet, currentStats.Data.Time)
+		log.LogInfo.Printf("Row with wallet: %s and time: %d already exists!", wallet, currentStats.Data.Time)
 		return
 	}
 
-	LogInfo.Printf("Creating new record for miner %s, time %d\n", wallet, currentStats.Data.Time)
+	log.LogInfo.Printf("Creating new record for miner %s, time %d\n", wallet, currentStats.Data.Time)
 	// Line 28 of UpdateData.cs
 	newMinerRecord := Miner {
 	    Wallet:           wallet,
@@ -72,45 +76,46 @@ func UpdateWallet(wallet string) {
 	    Unpaid:           currentStats.Data.Unpaid,
 	}
 
-	result := dBConnector.GormDb.Create(&newMinerRecord)
+	result := c.GormDb.Create(&newMinerRecord)
 	if result.Error != nil {
-		LogError.Println(result.Error)
+		log.LogError.Println(result.Error)
 		return
 	}
-	LogInfo.Printf("Added new row for miner %s\n", newMinerRecord.Wallet)
+	log.LogInfo.Printf("Added new row for miner %s\n", newMinerRecord.Wallet)
 
 	if (newMinerRecord.Unpaid < lastMinerRecord.Unpaid) {
-		err = NotifyChats(wallet)
-		if err != nil {
-			LogError.Println(err)
-		}
+		// TODO
+		// err := ChatsToNotify(wallet)
+		// if err != nil {
+		// 	log.LogError.Println(err)
+		// }
 	}
-	
-	dBConnector.UpdateWorkers(newMinerRecord, lastMinerRecord)
+
+	c.UpdateWorkers(newMinerRecord, lastMinerRecord)
 }
 
 // at main... or somewhere else
-func NotifyChats(wallet string) (err error) {
-	walletChats, err := dBConnector.ChatsWithWallet(wallet)
+func (c Connection) ChatsToNotify(wallet string) []int64 {
+	walletChats, err := c.ChatsWithWallet(wallet)
 	if err != nil {
-		return err
-	} 
-	for _, chat := range walletChats {
-		LogInfo.Println("Sended 'Payout detected!' message to chat ", chat)
-		go myBotClient.Send(tgbotapi.NewMessage(chat, "Payout detected!"))
+		panic(err)
 	}
-	return nil
+	// for _, chat := range walletChats {
+	// 	log.LogInfo.Println("Sended 'Payout detected!' message to chat ", chat)
+	// 	go myBotClient.Send(tgbotapi.NewMessage(chat, "Payout detected!"))
+	// }
+	return walletChats
 }
 
 // UpdateWorkers updates data on workers of newMinerRecord
 func (c *Connection) UpdateWorkers(newMinerRecord Miner, lastMinerRecord Miner) {
 	// Line 64 of UpdateData.cs
-	LogInfo.Printf("Getting workers data for wallet %s\n", newMinerRecord.Wallet)
-	LogInfo.Printf("From: %s/miner/%s", botsettings.ApiUrl(), newMinerRecord.Wallet)
+	log.LogInfo.Printf("Getting workers data for wallet %s\n", newMinerRecord.Wallet)
+	log.LogInfo.Printf("From: %s/miner/%s", settings.ApiUrl(), newMinerRecord.Wallet)
 
-	currentWorker, err := ethmineapi.Workers(botsettings.ApiUrl(), newMinerRecord.Wallet)
+	currentWorker, err := ethmineapi.Workers(settings.ApiUrl(), newMinerRecord.Wallet)
 	if err != nil {
-		LogWarn.Println(err); return
+		log.LogWarn.Println(err); return
 	}
 
 	if currentWorker.Status != "OK" {
@@ -118,9 +123,9 @@ func (c *Connection) UpdateWorkers(newMinerRecord Miner, lastMinerRecord Miner)
 	}
 
 	// Unsure is it occurs
-	if len(currentWorker.Data) == 0 { 
-		LogInfo.Printf("data in response from %s for workers of wallet %s not contains workers!\n",
-			botsettings.ApiUrl(), newMinerRecord.Wallet)
+	if len(currentWorker.Data) == 0 {
+		log.LogInfo.Printf("data in response from %s for workers of wallet %s not contains workers!\n",
+			settings.ApiUrl(), newMinerRecord.Wallet)
 		return
 	}
 
@@ -132,18 +137,18 @@ func (c *Connection) UpdateWorkers(newMinerRecord Miner, lastMinerRecord Miner)
 		// if worker.Payout {
 		//	c.getPayout()
 		//	...
-		// } 
+		// }
 		//
 		// In reality
 		c.updateWorker(workerData, newMinerRecord, lastMinerRecord)
 	}
 }
 
-// updateWorker updates data on workerData 
-func (c *Connection) updateWorker(workerData ethmineapi.WorkerData, 
+// updateWorker updates data on workerData
+func (c *Connection) updateWorker(workerData ethmineapi.WorkerData,
 	newMinerRecord Miner, lastMinerRecord Miner) {
 
-	LogInfo.Printf("Creating new worker record for %s, time %d\n", workerData.Worker, workerData.Time)
+	log.LogInfo.Printf("Creating new worker record for %s, time %d\n", workerData.Worker, workerData.Time)
 
 	newWorkerRecord := Worker{
 	    Wallet:            newMinerRecord.Wallet,
@@ -156,42 +161,42 @@ func (c *Connection) updateWorker(workerData ethmineapi.WorkerData,
 	    InvalidShares:     workerData.InvalidShares,
 	}
 
-	LogInfo.Printf("New worker record creating complete %s", newWorkerRecord.Worker)
+	log.LogInfo.Printf("New worker record creating complete %s", newWorkerRecord.Worker)
 
 	//Search for latest record for worker
 	lastWorkerRecord, err := c.LatestWorkerRecord(workerData.Worker)
 	if err != nil {
-		LogError.Println(err);
+		log.LogError.Println(err);
 		return
 	}
 
 	// Line 196 of UpdateData.cs
 	if lastWorkerRecord == (Worker{}) {
-		// TODO check default value of WorkerUnpaid 
-		LogDebug.Println("Setting WorkerUnpaid to 0")
+		// TODO check default value of WorkerUnpaid
+		log.LogDebug.Println("Setting WorkerUnpaid to 0")
 		newWorkerRecord.WorkerUnpaid = 0
 	}
-	
+
 	// Line 85 of UpdateData.cs
 	// check for payout
 	// maybe newWorkerRecord.WorkerUnpaid, err := c.{}payout{}(newMinerRecord, lastMinerRecord)
 
-	//Repeating of line 75 due to update of individual worker 
+	//Repeating of line 75 due to update of individual worker
 	if lastWorkerRecord != (Worker{}) && newMinerRecord.Unpaid < lastMinerRecord.Unpaid {
 		// Adding new payout field to db
-		payouts, err := ethmineapi.Payouts(botsettings.ApiUrl(), newWorkerRecord.Wallet)
+		payouts, err := ethmineapi.Payouts(settings.ApiUrl(), newWorkerRecord.Wallet)
 		if err != nil {
-			LogError.Println(err); return
+			log.LogError.Println(err); return
 		}
 
 		if (len(payouts.Data) == 0) {
-			LogWarn.Println("No actual payouts for wallet", newWorkerRecord.Wallet)
+			log.LogWarn.Println("No actual payouts for wallet", newWorkerRecord.Wallet)
 			return
 		}
 
 		lastPayout := payouts.Data[0]
 
-		LogInfo.Println("Last payout time =", lastPayout.PaidOn)
+		log.LogInfo.Println("Last payout time =", lastPayout.PaidOn)
 
 		newPayoutRecord := Payout{
 		    Wallet:  newWorkerRecord.Wallet,
@@ -210,43 +215,43 @@ func (c *Connection) updateWorker(workerData ethmineapi.WorkerData,
 
 		workerUnpaid := float64(newMinerRecord.Unpaid) *
 			(float64(workerData.ReportedHashrate) / float64(newMinerRecord.ReportedHashrate))
-		LogDebug.Println("newMinerRecord.Unpaid:", newMinerRecord.Unpaid)
-		LogDebug.Println("lastMinerRecord.Unpaid:", lastMinerRecord.Unpaid)
-		LogDebug.Println("workerData.ReportedHashrate:", workerData.ReportedHashrate)
-		LogDebug.Println("newMinerRecord.ReportedHashrate:", newMinerRecord.ReportedHashrate)
-		LogDebug.Println("workerUnpaid:", workerUnpaid)
+		log.LogDebug.Println("newMinerRecord.Unpaid:", newMinerRecord.Unpaid)
+		log.LogDebug.Println("lastMinerRecord.Unpaid:", lastMinerRecord.Unpaid)
+		log.LogDebug.Println("workerData.ReportedHashrate:", workerData.ReportedHashrate)
+		log.LogDebug.Println("newMinerRecord.ReportedHashrate:", newMinerRecord.ReportedHashrate)
+		log.LogDebug.Println("workerUnpaid:", workerUnpaid)
 		if math.IsNaN(workerUnpaid) || math.IsInf(workerUnpaid, 0) {
-			LogDebug.Println("workerUnpaid is NaN or Inf")
+			log.LogDebug.Println("workerUnpaid is NaN or Inf")
 			workerUnpaid = 0
 		}
 		newWorkerRecord.WorkerUnpaid = workerUnpaid
 
 		if result := c.GormDb.Create(&newPayoutRecord); result.Error != nil {
-			LogError.Println(result.Error)
+			log.LogError.Println(result.Error)
 			return
 		}
-		LogInfo.Println("Added newPayoutRecord, time =", newPayoutRecord.Time)
+		log.LogInfo.Println("Added newPayoutRecord, time =", newPayoutRecord.Time)
 
 		//removing old records
 		result := c.GormDb.
 			Where("wallet = ? AND time < ?", newPayoutRecord.Wallet, newMinerRecord.Time).
 			Delete(Worker{})
 		if result.Error != nil {
-			LogError.Println(result.Error)
+			log.LogError.Println(result.Error)
 		}
 
 		result = c.GormDb.
 			Where("wallet = ? AND time < ?", newPayoutRecord.Wallet, newMinerRecord.Time).
 			Delete(Miner{})
 		if result.Error != nil {
-			LogError.Println(result.Error)
+			log.LogError.Println(result.Error)
 		}
 
 		result = c.GormDb.
 			Where("wallet = ? AND time < ?", newPayoutRecord.Wallet, newMinerRecord.Time).
 			Delete(Payout{})
 		if result.Error != nil {
-			LogError.Println(result.Error)
+			log.LogError.Println(result.Error)
 		}
 
 	//Line 135 of UpdateData.cs
@@ -264,8 +269,8 @@ func (c *Connection) updateWorker(workerData ethmineapi.WorkerData,
 			Select("time").
 			Scan(&max)
 		if result.Error != nil {
-			LogWarn.Printf("No payouts data for %s! Time is set to 0!\n", lastWorkerRecord.Wallet)
-			LogError.Println(result.Error)
+			log.LogWarn.Printf("No payouts data for %s! Time is set to 0!\n", lastWorkerRecord.Wallet)
+			log.LogError.Println(result.Error)
 			max = 0
 		}
 
@@ -288,16 +293,19 @@ func (c *Connection) updateWorker(workerData ethmineapi.WorkerData,
 
 			targetedChats, err := c.ChatsWithWallet(newMinerRecord.Wallet)
 			if err != nil {
-				LogError.Println(err)
+				log.LogError.Println(err)
 			}
 
 			if err == nil {
-				msg := fmt.Sprintf("Debug info: Your worker %s hasn't been zeroed on payout!", 
+				msg := fmt.Sprintf("Debug info: Your worker %s hasn't been zeroed on payout!",
 					workerData.Worker)
 				for _, chatId := range targetedChats {
-					go myBotClient.Send(tgbotapi.NewMessage(int64(chatId), msg))
+					// TODO
+					_ = chatId
+					_ = msg
+					//go myBotClient.Send(tgbotapi.NewMessage(int64(chatId), msg))
 				}
-				LogDebug.Printf("Worker %s on address %s hasn't been zeroed on payout!\n", 
+				log.LogDebug.Printf("Worker %s on address %s hasn't been zeroed on payout!\n",
 					workerData.Worker, newMinerRecord.Wallet)
 			}
 		}
@@ -305,19 +313,19 @@ func (c *Connection) updateWorker(workerData ethmineapi.WorkerData,
 
 	rowExists, err := c.IsWorkerRowExists(newWorkerRecord.Worker, newWorkerRecord.Time)
 	if err != nil {
-		LogError.Println(err); return
+		log.LogError.Println(err); return
 	}
 
 	if rowExists {
-		LogInfo.Printf("Error adding new row: row with worker: %s, time: %d already exists!\n", 
+		log.LogInfo.Printf("Error adding new row: row with worker: %s, time: %d already exists!\n",
 		newWorkerRecord.Worker, newWorkerRecord.Time)
 		return
 	}
 
 	if result := c.GormDb.Create(&newWorkerRecord); result.Error != nil {
-		LogError.Println(result.Error)
+		log.LogError.Println(result.Error)
 		return
 	}
-	
-	LogInfo.Printf("Added new row for worker %s\n", newWorkerRecord.Worker)
+
+	log.LogInfo.Printf("Added new row for worker %s\n", newWorkerRecord.Worker)
 }

+ 11 - 4
logger.go → internal/logger/logger.go

@@ -1,21 +1,28 @@
-package main
+package logger
 
 import (
 	"io"
 	"log"
 	"os"
 	"time"
-	"GoEthemineTelegramBot/botsettings"
+	"gogs.veloe.link/toomanysugar/GoEthemineTelegramBot/cmd/settings"
 )
 
 type customLogWriter struct {
 	Writer io.Writer
 }
 
+var (
+	LogInfo  *log.Logger
+	LogWarn  *log.Logger
+	LogError *log.Logger
+	LogDebug *log.Logger
+)
+
 // Initializes Loggers
 func LoggersInit() {
-	fullLogPath := botsettings.FullLogPath()
-	errorLogPath := botsettings.ErrorLogPath()
+	fullLogPath := settings.FullLogPath()
+	errorLogPath := settings.ErrorLogPath()
 
 	fullLog, err := os.OpenFile(fullLogPath, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0766)
 	if err != nil {

+ 0 - 83
message_handler.go

@@ -1,83 +0,0 @@
-package main
-
-import (
-	"strings"
-
-	tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
-)
-
-func HandleMessage(reqMsg *tgbotapi.Message, botClient *tgbotapi.BotAPI) {
-	LogInfo.Printf("Received a text message in chat %d [%s]:%s", reqMsg.Chat.ID, reqMsg.From.UserName, reqMsg.Text)
-
-	msg := tgbotapi.NewMessage(reqMsg.Chat.ID, "")
-
-	switch strings.Split(reqMsg.Text, " ")[0] {
-
-	case "/start":
-		text, err := dBConnector.AddUser(reqMsg.Chat)
-		if err != nil {
-			LogError.Println(err)
-			text = "Internal error, please contact bot developer"
-		}
-		msg.Text = text
-		break
-
-	case "/stop":
-		text, err := dBConnector.DeleteUser(reqMsg.Chat)
-		if err != nil {
-			LogError.Println(err)
-			text = "Internal error, please contact bot developer"
-		}
-		msg.Text = text
-		break
-
-	case "/forceupdate":
-		UpdateData()
-		msg.Text = "Done!"
-		break
-
-	case "/actual":
-		if len(strings.Split(reqMsg.Text, " ")) > 1 {
-			msg.Text = GetActualData(strings.Split(reqMsg.Text, " ")[1])
-		} else {
-			result := dBConnector.GetActualDataFromDatabase(reqMsg.Chat.ID)
-			if (result == "nice"){
-				return //TODO better somehow different
-			}
-		}
-		break
-
-	case "/setwallet":
-		if len(strings.Split(reqMsg.Text, " ")) > 1 {
-			text, err := dBConnector.SetWallet(reqMsg)
-			if err != nil {
-				LogError.Println(err)
-				text = "An exception occurred while executing this command."
-			}
-			msg.Text = text
-		} else {
-			// LOL
-			msg.Text = "An exception occurred while executing this command."
-		}
-		break
-
-	case "/rate":
-		msg.Text = GetActualRate()
-		break
-
-	case "/help":
-		msg.Text = GetHelp()
-		break
-
-	case "/lastpayout":
-		msg.Text = dBConnector.GetLastPayout(reqMsg.Chat.ID)
-		break
-
-	default:
-		msg.Text = "Incorrect message"
-		break
-	}
-
-	LogInfo.Printf("Replied with: %s", strings.ReplaceAll(msg.Text, "\n", "\\n"))
-	botClient.Send(msg)
-}