1
0
mirror of https://github.com/hrfee/jfa-go.git synced 2024-12-29 12:30:11 +00:00

Compare commits

..

3 Commits

Author SHA1 Message Date
8fcb76cf97
Mention emby in README, add notices about password resets 2021-01-10 16:00:26 +00:00
c54e4811df
option to substitute "Jellyfin" in form.html
setting is jellyfin/substitute_jellyfin_strings.
2021-01-10 15:51:04 +00:00
4c6a9e9ad8
change settings description and console warning 2021-01-09 21:19:33 +00:00
8 changed files with 41 additions and 68 deletions

1
.gitignore vendored
View File

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

View File

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

View File

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

View File

@ -65,7 +65,15 @@
"emby"
],
"value": "jellyfin",
"description": "Media server type."
"description": "Note: Emby integration works is missing some features, such as Password Resets."
},
"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."
}
}
},

View File

@ -1,57 +0,0 @@
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,6 +39,8 @@ var serverTypes = map[string]string{
"jellyfin": "Jellyfin",
"emby": "Emby (experimental)",
}
var serverType = mediabrowser.JellyfinServer
var substituteStrings = ""
// User is used for auth purposes.
type User struct {
@ -282,12 +284,6 @@ func start(asDaemon, firstCall bool) {
if app.loadConfig() != nil {
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()
// read from config...
debugMode = app.config.Section("ui").Key("debug").MustBool(false)
@ -446,13 +442,12 @@ func start(asDaemon, firstCall bool) {
server := app.config.Section("jellyfin").Key("server").String()
cacheTimeout := int(app.config.Section("jellyfin").Key("cache_timeout").MustUint(30))
stringServerType := app.config.Section("jellyfin").Key("type").String()
serverType := mediabrowser.JellyfinServer
timeoutHandler := common.NewTimeoutHandler("Jellyfin", server, true)
if stringServerType == "emby" {
serverType = mediabrowser.EmbyServer
timeoutHandler = common.NewTimeoutHandler("Emby", server, true)
app.info.Println("Using Emby server type")
fmt.Println(aurora.Yellow("WARNING: Emby compatibility is experimental, things may not work."))
fmt.Println(aurora.Yellow("WARNING: Emby compatibility is experimental, and support is limited.\nPassword resets are not available."))
} else {
app.info.Println("Using Jellyfin server type")
}
@ -526,6 +521,14 @@ 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.loadStrftime()
@ -552,7 +555,7 @@ func start(asDaemon, firstCall bool) {
inviteDaemon := newRepeater(time.Duration(60*time.Second), app)
go inviteDaemon.run()
if app.config.Section("password_resets").Key("enabled").MustBool(false) {
if app.config.Section("password_resets").Key("enabled").MustBool(false) && serverType == mediabrowser.JellyfinServer {
go app.StartPWR()
}
} else {

View File

@ -58,6 +58,21 @@ func (st *Storage) storeInvites() 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)
if err != nil {
return err