1
0
mirror of https://github.com/hrfee/jfa-go.git synced 2024-10-18 09:00:11 +00:00

Compare commits

..

No commits in common. "8fcb76cf97c16e0635fc7e3fef2489813a110779" and "84a556dc19be70d43eb0ba4419929a2c082b3216" have entirely different histories.

8 changed files with 68 additions and 41 deletions

1
.gitignore vendored
View File

@ -6,6 +6,5 @@ data/
version.go version.go
notes notes
docs/* docs/*
lang/langtostruct.py
config-payload.json config-payload.json
!docs/go.mod !docs/go.mod

View File

@ -1,6 +1,6 @@
# ![jfa-go](images/banner.svg) # ![jfa-go](images/banner.svg)
jfa-go is a user management app for [Jellyfin](https://github.com/jellyfin/jellyfin) (and now [Emby](https://emby.media/)) that provides invite-based account creation as well as other features that make one's instance much easier to manage. jfa-go is a user management app for [Jellyfin](https://github.com/jellyfin/jellyfin) that provides invite-based account creation as well as other features that make one's instance much easier to manage.
I chose to rewrite the python [jellyfin-accounts](https://github.com/hrfee/jellyfin-accounts) in Go mainly as a learning experience, but also to slightly improve speeds and efficiency. I chose to rewrite the python [jellyfin-accounts](https://github.com/hrfee/jellyfin-accounts) in Go mainly as a learning experience, but also to slightly improve speeds and efficiency.

1
api.go
View File

@ -1050,7 +1050,6 @@ func (app *appContext) ApplySettings(gc *gin.Context) {
"homescreen": map[string]string{}, "homescreen": map[string]string{},
} }
for _, id := range req.ApplyTo { for _, id := range req.ApplyTo {
fmt.Printf("%+v\n", policy)
status, err := app.jf.SetPolicy(id, policy) status, err := app.jf.SetPolicy(id, policy)
if !(status == 200 || status == 204) || err != nil { if !(status == 200 || status == 204) || err != nil {
errors["policy"][id] = fmt.Sprintf("%d: %s", status, err) errors["policy"][id] = fmt.Sprintf("%d: %s", status, err)

View File

@ -82,7 +82,5 @@ func (app *appContext) loadConfig() error {
app.email = NewEmailer(app) app.email = NewEmailer(app)
substituteStrings = app.config.Section("jellyfin").Key("substitute_jellyfin_strings").MustString("")
return nil return nil
} }

View File

@ -65,15 +65,7 @@
"emby" "emby"
], ],
"value": "jellyfin", "value": "jellyfin",
"description": "Note: Emby integration works is missing some features, such as Password Resets." "description": "Media server type."
},
"substitute_jellyfin_strings": {
"name": "Substitute occurrences of \"Jellyfin\"",
"required": false,
"requires_restart": true,
"type": "text",
"value": "",
"description": "Optionally substitute occurrences of \"Jellyfin\" in the account creation form with this. May result in bad grammar."
} }
} }
}, },

57
config/jsontostruct.py Normal file
View File

@ -0,0 +1,57 @@
import json
with open("config-formatted.json", "r") as f:
config = json.load(f)
indent = 0
def writeln(ln):
global indent
if "}" in ln and "{" not in ln:
indent -= 1
s.write(("\t" * indent) + ln + "\n")
if "{" in ln and "}" not in ln:
indent += 1
with open("configStruct.go", "w") as s:
writeln("package main")
writeln("")
writeln("type Metadata struct{")
writeln('Name string `json:"name"`')
writeln('Description string `json:"description"`')
writeln("}")
writeln("")
writeln("type Config struct{")
if "order" in config:
writeln('Order []string `json:"order"`')
for section in [x for x in config.keys() if x != "order"]:
title = "".join([x.title() for x in section.split("_")])
writeln(title + " struct{")
if "order" in config[section]:
writeln('Order []string `json:"order"`')
if "meta" in config[section]:
writeln('Meta Metadata `json:"meta"`')
for setting in [
x for x in config[section].keys() if x != "order" and x != "meta"
]:
name = "".join([x.title() for x in setting.split("_")])
writeln(name + " struct{")
writeln('Name string `json:"name"`')
writeln('Required bool `json:"required"`')
writeln('Restart bool `json:"requires_restart"`')
writeln('Description string `json:"description"`')
writeln('Type string `json:"type"`')
dt = config[section][setting]["type"]
if dt == "select":
dt = "string"
writeln('Options []string `json:"options"`')
elif dt == "number":
dt = "int"
elif dt != "bool":
dt = "string"
writeln(f'Value {dt} `json:"value" cfg:"{setting}"`')
writeln("} " + f'`json:"{setting}" cfg:"{setting}"`')
writeln("} " + f'`json:"{section}"`')
writeln("}")

21
main.go
View File

@ -39,8 +39,6 @@ var serverTypes = map[string]string{
"jellyfin": "Jellyfin", "jellyfin": "Jellyfin",
"emby": "Emby (experimental)", "emby": "Emby (experimental)",
} }
var serverType = mediabrowser.JellyfinServer
var substituteStrings = ""
// User is used for auth purposes. // User is used for auth purposes.
type User struct { type User struct {
@ -284,6 +282,12 @@ func start(asDaemon, firstCall bool) {
if app.loadConfig() != nil { if app.loadConfig() != nil {
app.err.Fatalf("Failed to load config file \"%s\"", app.configPath) app.err.Fatalf("Failed to load config file \"%s\"", app.configPath)
} }
lang := app.config.Section("ui").Key("language").MustString("en-us")
app.storage.lang.FormPath = filepath.Join(app.localPath, "lang", "form", lang+".json")
if _, err := os.Stat(app.storage.lang.FormPath); os.IsNotExist(err) {
app.storage.lang.FormPath = filepath.Join(app.localPath, "lang", "form", "en-us.json")
}
app.storage.loadLang()
app.version = app.config.Section("jellyfin").Key("version").String() app.version = app.config.Section("jellyfin").Key("version").String()
// read from config... // read from config...
debugMode = app.config.Section("ui").Key("debug").MustBool(false) debugMode = app.config.Section("ui").Key("debug").MustBool(false)
@ -442,12 +446,13 @@ func start(asDaemon, firstCall bool) {
server := app.config.Section("jellyfin").Key("server").String() server := app.config.Section("jellyfin").Key("server").String()
cacheTimeout := int(app.config.Section("jellyfin").Key("cache_timeout").MustUint(30)) cacheTimeout := int(app.config.Section("jellyfin").Key("cache_timeout").MustUint(30))
stringServerType := app.config.Section("jellyfin").Key("type").String() stringServerType := app.config.Section("jellyfin").Key("type").String()
serverType := mediabrowser.JellyfinServer
timeoutHandler := common.NewTimeoutHandler("Jellyfin", server, true) timeoutHandler := common.NewTimeoutHandler("Jellyfin", server, true)
if stringServerType == "emby" { if stringServerType == "emby" {
serverType = mediabrowser.EmbyServer serverType = mediabrowser.EmbyServer
timeoutHandler = common.NewTimeoutHandler("Emby", server, true) timeoutHandler = common.NewTimeoutHandler("Emby", server, true)
app.info.Println("Using Emby server type") app.info.Println("Using Emby server type")
fmt.Println(aurora.Yellow("WARNING: Emby compatibility is experimental, and support is limited.\nPassword resets are not available.")) fmt.Println(aurora.Yellow("WARNING: Emby compatibility is experimental, things may not work."))
} else { } else {
app.info.Println("Using Jellyfin server type") app.info.Println("Using Jellyfin server type")
} }
@ -521,14 +526,6 @@ func start(asDaemon, firstCall bool) {
} }
} }
} }
lang := app.config.Section("ui").Key("language").MustString("en-us")
app.storage.lang.FormPath = filepath.Join(app.localPath, "lang", "form", lang+".json")
if _, err := os.Stat(app.storage.lang.FormPath); os.IsNotExist(err) {
app.storage.lang.FormPath = filepath.Join(app.localPath, "lang", "form", "en-us.json")
}
app.storage.loadLang()
app.authJf, _ = mediabrowser.NewServer(serverType, server, "jfa-go", app.version, "auth", "auth", timeoutHandler, cacheTimeout) app.authJf, _ = mediabrowser.NewServer(serverType, server, "jfa-go", app.version, "auth", "auth", timeoutHandler, cacheTimeout)
app.loadStrftime() app.loadStrftime()
@ -555,7 +552,7 @@ func start(asDaemon, firstCall bool) {
inviteDaemon := newRepeater(time.Duration(60*time.Second), app) inviteDaemon := newRepeater(time.Duration(60*time.Second), app)
go inviteDaemon.run() go inviteDaemon.run()
if app.config.Section("password_resets").Key("enabled").MustBool(false) && serverType == mediabrowser.JellyfinServer { if app.config.Section("password_resets").Key("enabled").MustBool(false) {
go app.StartPWR() go app.StartPWR()
} }
} else { } else {

View File

@ -58,21 +58,6 @@ func (st *Storage) storeInvites() error {
} }
func (st *Storage) loadLang() error { func (st *Storage) loadLang() error {
if substituteStrings != "" {
var file []byte
var err error
file, err = ioutil.ReadFile(st.lang.FormPath)
if err != nil {
file = []byte("{}")
}
// Replace Jellyfin with emby on form
file = []byte(strings.ReplaceAll(string(file), "Jellyfin", substituteStrings))
err = json.Unmarshal(file, &st.lang.Form)
if err != nil {
log.Printf("ERROR: Failed to read \"%s\": %s", st.lang.FormPath, err)
}
return err
}
err := loadJSON(st.lang.FormPath, &st.lang.Form) err := loadJSON(st.lang.FormPath, &st.lang.Form)
if err != nil { if err != nil {
return err return err