medinet/main.go

171 lines
4.1 KiB
Go
Raw Permalink Normal View History

2024-10-02 23:53:21 +00:00
// MediNET - Session repository and community portal for Meditation Assistant
// https://code.rocket9labs.com/tslocum/medinet
2017-09-29 04:14:47 +00:00
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package main
import (
2024-10-02 23:53:21 +00:00
"flag"
2017-09-29 04:14:47 +00:00
"fmt"
2019-04-26 12:03:08 +00:00
"io/ioutil"
2017-09-29 04:14:47 +00:00
"log"
"math/rand"
"os"
"regexp"
2018-08-10 01:12:03 +00:00
"time"
2020-01-28 23:30:52 +00:00
"gopkg.in/yaml.v2"
2017-09-29 04:14:47 +00:00
)
2020-10-20 20:08:00 +00:00
type configuration struct {
2019-04-26 11:44:43 +00:00
TimeZone string
DBDriver string
DBSource string
Om string
2020-10-20 20:03:53 +00:00
Web string
2017-09-29 04:14:47 +00:00
}
2020-10-20 20:08:00 +00:00
type statistics struct {
AccountsCreated int
ActiveAccounts []int
SessionsPosted int
TopStreak int
}
var (
2020-10-20 20:08:00 +00:00
db *database
config *configuration
printDebug bool
stats *statistics
serverLocation *time.Location
regexpNumbers = regexp.MustCompile("[0-9]+")
regexpMarket = regexp.MustCompile(".*?([a-zA-Z]+)$")
)
2017-09-29 04:14:47 +00:00
2018-06-08 01:13:23 +00:00
func logDebug(message string) {
2020-10-20 20:08:00 +00:00
if printDebug {
2018-06-08 01:13:23 +00:00
log.Println(message)
}
}
func logDebugf(format string, a ...interface{}) {
2019-01-21 14:02:20 +00:00
logDebug(fmt.Sprintf(format, a...))
2018-06-08 01:13:23 +00:00
}
2019-01-21 14:02:20 +00:00
func atWindowStart(t time.Time, streakBuffer int) time.Time {
2017-09-29 04:14:47 +00:00
year, month, day := t.Date()
2019-01-21 14:02:20 +00:00
return time.Date(year, month, day, streakBuffer/3600, (streakBuffer%3600)/60, streakBuffer%60, 0, t.Location())
}
func beforeWindowStart(t time.Time, streakBuffer int) bool {
return t.Before(atWindowStart(t, streakBuffer))
2017-09-29 04:14:47 +00:00
}
func failOnError(err error) {
if err != nil {
log.Fatal(err)
}
}
func trackActiveAccount(accountID int) {
active := false
for _, aID := range stats.ActiveAccounts {
if aID == accountID {
active = true
}
}
if !active {
stats.ActiveAccounts = append(stats.ActiveAccounts, accountID)
}
2019-04-26 11:44:43 +00:00
err := db.updateLastActive(accountID)
failOnError(err)
}
func printStatistics() {
for {
stats.ActiveAccounts = nil
stats.AccountsCreated, stats.SessionsPosted, stats.TopStreak = 0, 0, 0
now := time.Now().In(serverLocation)
fourAM := time.Date(now.Year(), now.Month(), now.Day(), 4, 0, 0, 0, serverLocation)
if !fourAM.After(now) {
fourAM = fourAM.AddDate(0, 0, 1)
}
time.Sleep(time.Until(fourAM))
log.Printf("%d accounts (%d new) posted %d sessions (top streak %d)", len(stats.ActiveAccounts), stats.AccountsCreated, stats.SessionsPosted, stats.TopStreak)
}
}
2017-09-29 04:14:47 +00:00
func main() {
var opts struct {
2024-10-02 23:53:21 +00:00
ConfigFile string
Debug bool
2017-09-29 04:14:47 +00:00
}
2024-10-02 23:53:21 +00:00
flag.StringVar(&opts.ConfigFile, "config", "", "Configuration file")
flag.BoolVar(&opts.Debug, "debug", false, "Print debug information")
flag.Parse()
2017-09-29 04:14:47 +00:00
rand.Seed(time.Now().UTC().UnixNano())
if opts.ConfigFile == "" {
log.Fatal("Please specify configuration file with: medinet -c <config file>")
}
2024-10-02 23:53:21 +00:00
_, err := os.Stat(opts.ConfigFile)
if err != nil {
2017-09-29 04:14:47 +00:00
log.Fatalf("Configuration file %s does not exist: %s", opts.ConfigFile, err)
}
2019-04-26 12:03:08 +00:00
configData, err := ioutil.ReadFile(opts.ConfigFile)
if err != nil {
log.Fatalf("Failed to read %s: %v", opts.ConfigFile, err)
}
2020-10-20 20:08:00 +00:00
config = new(configuration)
2019-04-26 12:03:08 +00:00
err = yaml.Unmarshal(configData, config)
if err != nil {
2017-09-29 04:14:47 +00:00
log.Fatalf("Failed to read %s: %v", opts.ConfigFile, err)
2019-04-26 12:03:08 +00:00
} else if config.DBDriver == "" {
log.Fatal("Specify database driver in configuration file")
} else if config.Om == "" {
log.Fatal("Specify Om host:port in configuration file")
2020-10-20 20:03:53 +00:00
} else if config.Web == "" {
log.Fatal("Specify Web directory in configuration file")
2017-09-29 04:14:47 +00:00
}
2024-10-02 23:53:21 +00:00
tz := "UTC"
if config.TimeZone != "" {
tz = config.TimeZone
}
loc, err := time.LoadLocation(tz)
failOnError(err)
serverLocation = loc
2020-10-20 20:08:00 +00:00
printDebug = opts.Debug
2018-06-08 01:13:23 +00:00
2020-10-20 20:08:00 +00:00
stats = new(statistics)
go printStatistics()
2020-10-20 20:08:00 +00:00
db, err = connect(config.DBDriver, config.DBSource)
2017-09-29 04:14:47 +00:00
failOnError(err)
2020-10-20 20:03:53 +00:00
initWeb()
listenWeb()
2024-10-02 23:53:21 +00:00
log.Printf("Listening on %+v", config.Om)
2017-09-29 04:14:47 +00:00
}