You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
166 lines
4.1 KiB
166 lines
4.1 KiB
// MediNET - session repository and community portal for Meditation Assistant |
|
// https://gitlab.com/tslocum/medinet |
|
// |
|
// 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 ( |
|
"fmt" |
|
"io/ioutil" |
|
"log" |
|
"math/rand" |
|
"os" |
|
"regexp" |
|
"time" |
|
|
|
"github.com/jessevdk/go-flags" |
|
"gopkg.in/yaml.v2" |
|
) |
|
|
|
type configuration struct { |
|
TimeZone string |
|
DBDriver string |
|
DBSource string |
|
Om string |
|
Web string |
|
} |
|
|
|
type statistics struct { |
|
AccountsCreated int |
|
ActiveAccounts []int |
|
|
|
SessionsPosted int |
|
TopStreak int |
|
} |
|
|
|
var ( |
|
db *database |
|
config *configuration |
|
printDebug bool |
|
stats *statistics |
|
serverLocation *time.Location |
|
|
|
regexpNumbers = regexp.MustCompile("[0-9]+") |
|
regexpMarket = regexp.MustCompile(".*?([a-zA-Z]+)$") |
|
) |
|
|
|
func logDebug(message string) { |
|
if printDebug { |
|
log.Println(message) |
|
} |
|
} |
|
|
|
func logDebugf(format string, a ...interface{}) { |
|
logDebug(fmt.Sprintf(format, a...)) |
|
} |
|
|
|
func atWindowStart(t time.Time, streakBuffer int) time.Time { |
|
year, month, day := t.Date() |
|
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)) |
|
} |
|
|
|
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) |
|
} |
|
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) |
|
} |
|
} |
|
|
|
func main() { |
|
var opts struct { |
|
ConfigFile string `short:"c" long:"config" description:"Configuration file"` |
|
Debug bool `short:"d" long:"debug" description:"Print debug information"` |
|
} |
|
_, err := flags.Parse(&opts) |
|
failOnError(err) |
|
|
|
rand.Seed(time.Now().UTC().UnixNano()) |
|
|
|
if opts.ConfigFile == "" { |
|
log.Fatal("Please specify configuration file with: medinet -c <config file>") |
|
} |
|
if _, err = os.Stat(opts.ConfigFile); err != nil { |
|
log.Fatalf("Configuration file %s does not exist: %s", opts.ConfigFile, err) |
|
} |
|
|
|
configData, err := ioutil.ReadFile(opts.ConfigFile) |
|
if err != nil { |
|
log.Fatalf("Failed to read %s: %v", opts.ConfigFile, err) |
|
} |
|
|
|
config = new(configuration) |
|
err = yaml.Unmarshal(configData, config) |
|
if err != nil { |
|
log.Fatalf("Failed to read %s: %v", opts.ConfigFile, err) |
|
} 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") |
|
} else if config.Web == "" { |
|
log.Fatal("Specify Web directory in configuration file") |
|
} |
|
|
|
tz := "Local" |
|
if config.TimeZone != "" { |
|
tz = config.TimeZone |
|
} |
|
loc, err := time.LoadLocation(tz) |
|
failOnError(err) |
|
serverLocation = loc |
|
|
|
printDebug = opts.Debug |
|
|
|
stats = new(statistics) |
|
go printStatistics() |
|
|
|
db, err = connect(config.DBDriver, config.DBSource) |
|
failOnError(err) |
|
|
|
initWeb() |
|
listenWeb() |
|
}
|
|
|