This repository has been archived on 2022-09-04. You can view files and clone it, but cannot push or open issues or pull requests.
dataupdater/internal/cron/tasks/task_load_servers_and_update_data.go

123 lines
3.6 KiB
Go

package tasks
import (
"context"
"fmt"
phpserialize "github.com/Kichiyaki/go-php-serialize"
"github.com/go-pg/pg/v10"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/tribalwarshelp/shared/models"
"io/ioutil"
"net/http"
"github.com/tribalwarshelp/cron/internal/cron/queue"
"github.com/tribalwarshelp/cron/internal/db"
)
const (
endpointGetServers = "/backend/get_servers.php"
)
type taskLoadServersAndUpdateData struct {
*task
}
func (t *taskLoadServersAndUpdateData) execute(version *models.Version) error {
if err := t.validatePayload(version); err != nil {
log.Debug(err)
return nil
}
entry := log.WithField("host", version.Host)
entry.Infof("taskLoadServersAndUpdateData.execute: %s: Loading servers", version.Host)
data, err := t.getServers(version)
if err != nil {
log.Errorln(err)
return err
}
var serverKeys []string
var servers []*models.Server
for serverKey := range data {
if version.SpecialServers.Contains(serverKey) {
continue
}
server := &models.Server{
Key: serverKey,
Status: models.ServerStatusOpen,
VersionCode: version.Code,
Version: version,
}
if err := db.CreateSchema(t.db, server); err != nil {
logrus.Warn(errors.Wrapf(err, "taskLoadServersAndUpdateData.execute: %s: couldn't create the schema", server.Key))
continue
}
servers = append(servers, server)
serverKeys = append(serverKeys, serverKey)
}
if len(servers) > 0 {
if _, err := t.db.Model(&servers).
OnConflict("(key) DO UPDATE").
Set("status = ?", models.ServerStatusOpen).
Set("version_code = EXCLUDED.version_code").
Returning("*").
Insert(); err != nil {
err = errors.Wrap(err, "taskLoadServersAndUpdateData.execute: couldn't insert/update servers")
logrus.Error(err)
return err
}
}
if _, err := t.db.Model(&models.Server{}).
Set("status = ?", models.ServerStatusClosed).
Where("key NOT IN (?) AND version_code = ?", pg.In(serverKeys), version.Code).
Update(); err != nil {
err = errors.Wrap(err, "taskLoadServersAndUpdateData.execute: couldn't update server statuses")
logrus.Error(err)
return err
}
for _, server := range servers {
s := server
t.queue.Add(queue.MainQueue, Get(TaskNameUpdateServerData).WithArgs(context.Background(), data[s.Key], s))
}
entry.Infof("%s: Servers have been loaded", version.Host)
return nil
}
func (t *taskLoadServersAndUpdateData) validatePayload(version *models.Version) error {
if version == nil {
return errors.New("taskLoadServersAndUpdateData.validatePayload: Expected *models.Version, got nil")
}
return nil
}
func (t *taskLoadServersAndUpdateData) getServers(version *models.Version) (map[string]string, error) {
resp, err := http.Get(fmt.Sprintf("https://%s%s", version.Host, endpointGetServers))
if err != nil {
return nil, errors.Wrapf(err, "%s: taskLoadServersAndUpdateData.loadServers couldn't load servers", version.Host)
}
defer resp.Body.Close()
bodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, errors.Wrapf(err, "%s: taskLoadServersAndUpdateData.loadServers couldn't read the response body", version.Host)
}
body, err := phpserialize.Decode(string(bodyBytes))
if err != nil {
return nil, errors.Wrapf(err, "%s: taskLoadServersAndUpdateData.loadServers couldn't decode the response body into the go value", version.Host)
}
result := make(map[string]string)
for serverKey, url := range body.(map[interface{}]interface{}) {
serverKeyStr := serverKey.(string)
urlStr := url.(string)
if serverKeyStr != "" && urlStr != "" {
result[serverKeyStr] = urlStr
}
}
return result, nil
}