Add ability to revert to non-hyphenated user IDs

The first 10.7.0 build i tried used hyphens, but a later one didn't.
emails.json can now be converted between the two forms depending on what
the server uses.
pull/24/head
Harvey Tindall 4 years ago
parent c79f86137e
commit ee6f81b9e9
No known key found for this signature in database
GPG Key ID: BBC65952848FB1A2

@ -44,6 +44,7 @@ type Jellyfin struct {
CacheExpiry time.Time CacheExpiry time.Time
cacheLength int cacheLength int
noFail bool noFail bool
Hyphens bool
timeoutHandler common.TimeoutHandler timeoutHandler common.TimeoutHandler
} }
@ -208,8 +209,8 @@ func (jf *Jellyfin) post(url string, data map[string]interface{}, response bool)
} }
// DeleteUser deletes the user corresponding to the provided ID. // DeleteUser deletes the user corresponding to the provided ID.
func (jf *Jellyfin) DeleteUser(id string) (int, error) { func (jf *Jellyfin) DeleteUser(userID string) (int, error) {
url := fmt.Sprintf("%s/Users/%s", jf.Server, id) url := fmt.Sprintf("%s/Users/%s", jf.Server, userID)
req, _ := http.NewRequest("DELETE", url, nil) req, _ := http.NewRequest("DELETE", url, nil)
for name, value := range jf.header { for name, value := range jf.header {
req.Header.Add(name, value) req.Header.Add(name, value)
@ -239,6 +240,11 @@ func (jf *Jellyfin) GetUsers(public bool) ([]map[string]interface{}, int, error)
json.Unmarshal([]byte(data), &result) json.Unmarshal([]byte(data), &result)
jf.userCache = result jf.userCache = result
jf.CacheExpiry = time.Now().Add(time.Minute * time.Duration(jf.cacheLength)) jf.CacheExpiry = time.Now().Add(time.Minute * time.Duration(jf.cacheLength))
if id, ok := result[0]["Id"]; ok {
if id.(string)[8] == '-' {
jf.Hyphens = true
}
}
return result, status, nil return result, status, nil
} }
return jf.userCache, 200, nil return jf.userCache, 200, nil

@ -42,6 +42,7 @@ type User struct {
Password string `json:"password"` Password string `json:"password"`
} }
// contains everything the application needs, essentially. Wouldn't do this in the future.
type appContext struct { type appContext struct {
// defaults *Config // defaults *Config
config *ini.File config *ini.File
@ -461,7 +462,7 @@ func start(asDaemon, firstCall bool) {
app.err.Fatalf("Failed to authenticate with Jellyfin @ %s: Code %d", server, status) app.err.Fatalf("Failed to authenticate with Jellyfin @ %s: Code %d", server, status)
} }
app.info.Printf("Authenticated with %s", server) app.info.Printf("Authenticated with %s", server)
// from 10.7.0, jellyfin hyphenates user IDs. This checks if the version is equal or higher. // from 10.7.0, jellyfin may hyphenate user IDs. This checks if the version is equal or higher.
checkVersion := func(version string) int { checkVersion := func(version string) int {
numberStrings := strings.Split(version, ".") numberStrings := strings.Split(version, ".")
n := 0 n := 0
@ -474,6 +475,9 @@ func start(asDaemon, firstCall bool) {
return n return n
} }
if checkVersion(app.jf.ServerInfo.Version) >= checkVersion("10.7.0") { if checkVersion(app.jf.ServerInfo.Version) >= checkVersion("10.7.0") {
// Get users to check if server uses hyphenated userIDs
app.jf.GetUsers(false)
noHyphens := true noHyphens := true
for id := range app.storage.emails { for id := range app.storage.emails {
if strings.Contains(id, "-") { if strings.Contains(id, "-") {
@ -481,10 +485,19 @@ func start(asDaemon, firstCall bool) {
break break
} }
} }
if noHyphens { if noHyphens == app.jf.Hyphens {
app.info.Println(aurora.Yellow("From Jellyfin 10.7.0 onwards, user IDs are hyphenated.\nYour emails.json file will be modified to match this new format.\nA backup will be placed next to the file.\n")) var newEmails map[string]interface{}
time.Sleep(time.Second * time.Duration(3)) var status int
newEmails, status, err := app.upgradeEmailStorage(app.storage.emails) var err error
if app.jf.Hyphens {
app.info.Println(aurora.Yellow("Your build of Jellyfin appears to hypenate user IDs. Your emails.json file will be modified to match."))
time.Sleep(time.Second * time.Duration(3))
newEmails, status, err = app.hyphenateEmailStorage(app.storage.emails)
} else {
app.info.Println(aurora.Yellow("Your emails.json file uses hyphens, but the Jellyfin server no longer does. It will be modified."))
time.Sleep(time.Second * time.Duration(3))
newEmails, status, err = app.deHyphenateEmailStorage(app.storage.emails)
}
if status != 200 || err != nil { if status != 200 || err != nil {
app.err.Printf("Failed to get users from Jellyfin: Code %d", status) app.err.Printf("Failed to get users from Jellyfin: Code %d", status)
app.debug.Printf("Error: %s", err) app.debug.Printf("Error: %s", err)

@ -192,10 +192,34 @@ func storeJSON(path string, obj interface{}) error {
return err return err
} }
// JF 10.7.0 added hyphens to user IDs like this and we need to upgrade email storage to match it: // One build of JF 10.7.0 hyphenated to user IDs like this and we need to upgrade email storage to match it:
// [8 chars]-[4]-[4]-[4]-[12] // One build of JF 10.7.0 hyphenated user IDs while another one later didn't. These functions will hyphenate/de-hyphenate email storage.
// This seems consistent, but we'll grab IDs from jellyfin just in case theres some variation.
func (app *appContext) upgradeEmailStorage(old map[string]interface{}) (map[string]interface{}, int, error) { func hyphenate(userID string) string {
if userID[8] == '-' {
return userID
}
return userID[:8] + "-" + userID[8:12] + "-" + userID[12:16] + "-" + userID[16:20] + "-" + userID[20:]
}
func (app *appContext) deHyphenateEmailStorage(old map[string]interface{}) (map[string]interface{}, int, error) {
jfUsers, status, err := app.jf.GetUsers(false)
if status != 200 || err != nil {
return nil, status, err
}
newEmails := map[string]interface{}{}
for _, user := range jfUsers {
unHyphenated := user["Id"].(string)
hyphenated := hyphenate(unHyphenated)
email, ok := old[hyphenated]
if ok {
newEmails[unHyphenated] = email
}
}
return newEmails, status, err
}
func (app *appContext) hyphenateEmailStorage(old map[string]interface{}) (map[string]interface{}, int, error) {
jfUsers, status, err := app.jf.GetUsers(false) jfUsers, status, err := app.jf.GetUsers(false)
if status != 200 || err != nil { if status != 200 || err != nil {
return nil, status, err return nil, status, err

Loading…
Cancel
Save