messages: custom content described in customcontent.go, message tests
customcontent.go constains a structure with all the custom content, methods for getting display names, subjects, etc., and a list of variables, conditionals, and placeholder values. Tests for constructX methods included in email_test.go, and all jfa-go tests can be run with make INTERNAL=off test.
This commit is contained in:
@@ -24,7 +24,6 @@ import (
|
||||
"github.com/fatih/color"
|
||||
"github.com/hrfee/jfa-go/common"
|
||||
_ "github.com/hrfee/jfa-go/docs"
|
||||
"github.com/hrfee/jfa-go/easyproxy"
|
||||
"github.com/hrfee/jfa-go/jellyseerr"
|
||||
"github.com/hrfee/jfa-go/logger"
|
||||
lm "github.com/hrfee/jfa-go/logmessages"
|
||||
@@ -81,6 +80,11 @@ var serverTypes = map[string]string{
|
||||
var serverType = mediabrowser.JellyfinServer
|
||||
var substituteStrings = ""
|
||||
|
||||
var externalURI, externalDomain string // The latter lower-case as should be accessed through app.ExternalDomain()
|
||||
var UseProxyHost bool
|
||||
|
||||
var datePattern, timePattern string
|
||||
|
||||
// User is used for auth purposes.
|
||||
type User struct {
|
||||
UserID string `json:"id"`
|
||||
@@ -88,10 +92,15 @@ type User struct {
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
// Set of the usual log channels, for ease of passing between things.
|
||||
type LoggerSet struct {
|
||||
info, debug, err *logger.Logger
|
||||
}
|
||||
|
||||
// contains (almost) everything the application needs, essentially. This was a dumb design decision imo.
|
||||
type appContext struct {
|
||||
// defaults *Config
|
||||
config *ini.File
|
||||
config *Config
|
||||
configPath string
|
||||
configBasePath string
|
||||
configBase common.Config
|
||||
@@ -103,39 +112,32 @@ type appContext struct {
|
||||
adminUsers []User
|
||||
invalidTokens []string
|
||||
// Keeping jf name because I can't think of a better one
|
||||
jf *mediabrowser.MediaBrowser
|
||||
authJf *mediabrowser.MediaBrowser
|
||||
ombi *OmbiWrapper
|
||||
js *JellyseerrWrapper
|
||||
thirdPartyServices []ThirdPartyService
|
||||
datePattern string
|
||||
timePattern string
|
||||
storage Storage
|
||||
validator Validator
|
||||
email *Emailer
|
||||
telegram *TelegramDaemon
|
||||
discord *DiscordDaemon
|
||||
matrix *MatrixDaemon
|
||||
contactMethods []ContactMethodLinker
|
||||
info, debug, err *logger.Logger
|
||||
host string
|
||||
port int
|
||||
version string
|
||||
externalURI, externalDomain string // The latter lower-case as should be accessed through app.ExternalDomain()
|
||||
UseProxyHost bool
|
||||
updater *Updater
|
||||
webhooks *WebhookSender
|
||||
newUpdate bool // Whether whatever's in update is new.
|
||||
tag Tag
|
||||
update Update
|
||||
proxyEnabled bool
|
||||
proxyTransport *http.Transport
|
||||
proxyConfig easyproxy.ProxyConfig
|
||||
internalPWRs map[string]InternalPWR
|
||||
pwrCaptchas map[string]Captcha
|
||||
ConfirmationKeys map[string]map[string]ConfirmationKey // Map of invite code to jwt to request
|
||||
confirmationKeysLock sync.Mutex
|
||||
userCache *UserCache
|
||||
jf *mediabrowser.MediaBrowser
|
||||
authJf *mediabrowser.MediaBrowser
|
||||
ombi *OmbiWrapper
|
||||
js *JellyseerrWrapper
|
||||
thirdPartyServices []ThirdPartyService
|
||||
storage *Storage
|
||||
validator Validator
|
||||
email *Emailer
|
||||
telegram *TelegramDaemon
|
||||
discord *DiscordDaemon
|
||||
matrix *MatrixDaemon
|
||||
contactMethods []ContactMethodLinker
|
||||
LoggerSet
|
||||
host string
|
||||
port int
|
||||
version string
|
||||
updater *Updater
|
||||
webhooks *WebhookSender
|
||||
newUpdate bool // Whether whatever's in update is new.
|
||||
tag Tag
|
||||
update Update
|
||||
internalPWRs map[string]InternalPWR
|
||||
pwrCaptchas map[string]Captcha
|
||||
ConfirmationKeys map[string]map[string]ConfirmationKey // Map of invite code to jwt to request
|
||||
confirmationKeysLock sync.Mutex
|
||||
userCache *UserCache
|
||||
}
|
||||
|
||||
func generateSecret(length int) (string, error) {
|
||||
@@ -244,7 +246,9 @@ func start(asDaemon, firstCall bool) {
|
||||
|
||||
var debugMode bool
|
||||
var address string
|
||||
if err := app.loadConfig(); err != nil {
|
||||
var err error = nil
|
||||
app.config, err = NewConfig(app.configPath, app.dataPath, app.LoggerSet)
|
||||
if err != nil {
|
||||
app.err.Fatalf(lm.FailedLoadConfig, app.configPath, err)
|
||||
}
|
||||
app.info.Printf(lm.LoadConfig, app.configPath)
|
||||
@@ -262,12 +266,8 @@ func start(asDaemon, firstCall bool) {
|
||||
}
|
||||
if debugMode {
|
||||
app.debug = logger.NewLogger(os.Stdout, "[DEBUG] ", log.Ltime|log.Lshortfile, color.FgYellow)
|
||||
// Bind debug log
|
||||
app.storage.debug = app.debug
|
||||
app.storage.logActions = generateLogActions(app.config)
|
||||
} else {
|
||||
app.debug = logger.NewEmptyLogger()
|
||||
app.storage.debug = nil
|
||||
}
|
||||
if *PPROF {
|
||||
app.info.Print(warning("\n\nWARNING: Don't use pprof in production.\n\n"))
|
||||
@@ -312,14 +312,17 @@ func start(asDaemon, firstCall bool) {
|
||||
}()
|
||||
}
|
||||
|
||||
app.storage.lang.CommonPath = "common"
|
||||
app.storage.lang.UserPath = "form"
|
||||
app.storage.lang.AdminPath = "admin"
|
||||
app.storage.lang.EmailPath = "email"
|
||||
app.storage.lang.TelegramPath = "telegram"
|
||||
app.storage.lang.PasswordResetPath = "pwreset"
|
||||
dbPath := filepath.Join(app.dataPath, "db")
|
||||
if debugMode {
|
||||
app.storage = NewStorage(dbPath, app.debug, generateLogActions(app.config))
|
||||
} else {
|
||||
app.storage = NewStorage(dbPath, app.debug, nil)
|
||||
}
|
||||
|
||||
// Placed here, since storage.chosenXLang is set by this function.
|
||||
app.config.ReloadDependents(app)
|
||||
|
||||
externalLang := app.config.Section("files").Key("lang_files").MustString("")
|
||||
var err error
|
||||
if externalLang == "" {
|
||||
err = app.storage.loadLang(langFS)
|
||||
} else {
|
||||
@@ -362,7 +365,7 @@ func start(asDaemon, firstCall bool) {
|
||||
}
|
||||
address = fmt.Sprintf("%s:%d", app.host, app.port)
|
||||
|
||||
// NOTE: As of writing this, the order in app.thirdPartServices doesn't matter,
|
||||
// NOTE: As of writing this, the order in app.thirdPartyServices doesn't matter,
|
||||
// but in future it might (like app.contactMethods does), so append to the end!
|
||||
if app.config.Section("ombi").Key("enabled").MustBool(false) {
|
||||
app.ombi = &OmbiWrapper{}
|
||||
@@ -391,10 +394,12 @@ func start(asDaemon, firstCall bool) {
|
||||
|
||||
}
|
||||
|
||||
app.storage.db_path = filepath.Join(app.dataPath, "db")
|
||||
app.loadPendingBackup()
|
||||
app.ConnectDB()
|
||||
defer app.storage.db.Close()
|
||||
if err := app.storage.Connect(app.config); err != nil {
|
||||
app.err.Fatalf(lm.FailedConnectDB, dbPath, err)
|
||||
}
|
||||
app.info.Printf(lm.ConnectDB, dbPath)
|
||||
defer app.storage.Close()
|
||||
|
||||
// copy it to app.patchedConfig, and patch in settings from app.config, and language stuff.
|
||||
app.PatchConfigBase()
|
||||
@@ -475,10 +480,9 @@ func start(asDaemon, firstCall bool) {
|
||||
time.Minute*time.Duration(app.config.Section("jellyfin").Key("web_cache_sync_timeout").MustInt()),
|
||||
)
|
||||
|
||||
// Since email depends on language, the email reload in loadConfig won't work first time.
|
||||
// Since email depends on language, the email reload in NewConfig won't work first time.
|
||||
// Email also handles its own proxying, as (SMTP atleast) doesn't use a HTTP transport.
|
||||
app.email = NewEmailer(app)
|
||||
app.loadStrftime()
|
||||
app.email = NewEmailer(app.config, app.storage, app.LoggerSet)
|
||||
|
||||
var validatorConf ValidatorConf
|
||||
|
||||
@@ -579,13 +583,13 @@ func start(asDaemon, firstCall bool) {
|
||||
)
|
||||
|
||||
// Updater proxy set in config.go, don't worry!
|
||||
if app.proxyEnabled {
|
||||
app.jf.SetTransport(app.proxyTransport)
|
||||
if app.config.proxyConfig != nil {
|
||||
app.jf.SetTransport(app.config.proxyTransport)
|
||||
for _, c := range app.thirdPartyServices {
|
||||
c.SetTransport(app.proxyTransport)
|
||||
c.SetTransport(app.config.proxyTransport)
|
||||
}
|
||||
for _, c := range app.contactMethods {
|
||||
c.SetTransport(app.proxyTransport)
|
||||
c.SetTransport(app.config.proxyTransport)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -601,7 +605,6 @@ func start(asDaemon, firstCall bool) {
|
||||
app.host = "0.0.0.0"
|
||||
}
|
||||
address = fmt.Sprintf("%s:%d", app.host, app.port)
|
||||
app.storage.lang.SetupPath = "setup"
|
||||
err := app.storage.loadLangSetup(langFS)
|
||||
if err != nil {
|
||||
app.info.Fatalf(lm.FailedLangLoad, err)
|
||||
|
||||
Reference in New Issue
Block a user