use strings.builder and unmarshal in jfapi

for some reason, json.Decoder sometimes fails when using an io.Reader. I
    noticed this happened all the time when adding ombi integration so I
    used strings.Builder to turn the io.Reader into a string before
    decoding with json.Unmarshal. The user in issue #4 had the
    same problem with Jellyfin, so this method is now also used in jfapi.
pull/20/head
Harvey Tindall 4 years ago
parent 1707c8c1f9
commit 410c35c844
No known key found for this signature in database
GPG Key ID: BBC65952848FB1A2

@ -9,6 +9,7 @@ import (
"io/ioutil" "io/ioutil"
"log" "log"
"net/http" "net/http"
"strings"
"time" "time"
) )
@ -136,7 +137,7 @@ func (jf *Jellyfin) authenticate(username, password string) (map[string]interfac
return user, resp.StatusCode, nil return user, resp.StatusCode, nil
} }
func (jf *Jellyfin) _getReader(url string, params map[string]string) (io.Reader, int, error) { func (jf *Jellyfin) _get(url string, params map[string]string) (string, int, error) {
var req *http.Request var req *http.Request
if params != nil { if params != nil {
jsonParams, _ := json.Marshal(params) jsonParams, _ := json.Marshal(params)
@ -154,26 +155,32 @@ func (jf *Jellyfin) _getReader(url string, params map[string]string) (io.Reader,
jf.authenticated = false jf.authenticated = false
_, _, authErr := jf.authenticate(jf.username, jf.password) _, _, authErr := jf.authenticate(jf.username, jf.password)
if authErr == nil { if authErr == nil {
v1, v2, v3 := jf._getReader(url, params) v1, v2, v3 := jf._get(url, params)
return v1, v2, v3 return v1, v2, v3
} }
} }
return nil, resp.StatusCode, err return "", resp.StatusCode, err
} }
defer resp.Body.Close() defer resp.Body.Close()
var data io.Reader var data io.Reader
switch resp.Header.Get("Content-Encoding") { encoding := resp.Header.Get("Content-Encoding")
if TEST {
fmt.Println("response encoding:", encoding)
}
switch encoding {
case "gzip": case "gzip":
data, _ = gzip.NewReader(resp.Body) data, _ = gzip.NewReader(resp.Body)
default: default:
data = resp.Body data = resp.Body
} }
buf := new(strings.Builder)
io.Copy(buf, data)
//var respData map[string]interface{} //var respData map[string]interface{}
//json.NewDecoder(data).Decode(&respData) //json.NewDecoder(data).Decode(&respData)
return data, resp.StatusCode, nil return buf.String(), resp.StatusCode, nil
} }
func (jf *Jellyfin) _post(url string, data map[string]interface{}, response bool) (io.Reader, int, error) { func (jf *Jellyfin) _post(url string, data map[string]interface{}, response bool) (string, int, error) {
params, _ := json.Marshal(data) params, _ := json.Marshal(data)
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(params)) req, _ := http.NewRequest("POST", url, bytes.NewBuffer(params))
for name, value := range jf.header { for name, value := range jf.header {
@ -190,7 +197,7 @@ func (jf *Jellyfin) _post(url string, data map[string]interface{}, response bool
return v1, v2, v3 return v1, v2, v3
} }
} }
return nil, resp.StatusCode, err return "", resp.StatusCode, err
} }
if response { if response {
defer resp.Body.Close() defer resp.Body.Close()
@ -201,34 +208,36 @@ func (jf *Jellyfin) _post(url string, data map[string]interface{}, response bool
default: default:
outData = resp.Body outData = resp.Body
} }
return outData, resp.StatusCode, nil buf := new(strings.Builder)
io.Copy(buf, outData)
return buf.String(), resp.StatusCode, nil
} }
return nil, resp.StatusCode, nil return "", resp.StatusCode, nil
} }
func (jf *Jellyfin) getUsers(public bool) ([]map[string]interface{}, int, error) { func (jf *Jellyfin) getUsers(public bool) ([]map[string]interface{}, int, error) {
var result []map[string]interface{} var result []map[string]interface{}
var data io.Reader var data string
var status int var status int
var err error var err error
if time.Now().After(jf.cacheExpiry) { if time.Now().After(jf.cacheExpiry) {
if public { if public {
url := fmt.Sprintf("%s/users/public", jf.server) url := fmt.Sprintf("%s/users/public", jf.server)
data, status, err = jf._getReader(url, nil) data, status, err = jf._get(url, nil)
} else { } else {
url := fmt.Sprintf("%s/users", jf.server) url := fmt.Sprintf("%s/users", jf.server)
data, status, err = jf._getReader(url, jf.loginParams) data, status, err = jf._get(url, jf.loginParams)
} }
if err != nil || status != 200 { if err != nil || status != 200 {
return nil, status, err return nil, status, err
} }
json.NewDecoder(data).Decode(&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))
return result, status, nil return result, status, nil
} }
return jf.userCache, 200, nil return jf.userCache, status, nil
} }
func (jf *Jellyfin) userByName(username string, public bool) (map[string]interface{}, int, error) { func (jf *Jellyfin) userByName(username string, public bool) (map[string]interface{}, int, error) {
@ -265,15 +274,15 @@ func (jf *Jellyfin) userById(userId string, public bool) (map[string]interface{}
return nil, status, err return nil, status, err
} else { } else {
var result map[string]interface{} var result map[string]interface{}
var data io.Reader var data string
var status int var status int
var err error var err error
url := fmt.Sprintf("%s/users/%s", jf.server, userId) url := fmt.Sprintf("%s/users/%s", jf.server, userId)
data, status, err = jf._getReader(url, jf.loginParams) data, status, err = jf._get(url, jf.loginParams)
if err != nil || status != 200 { if err != nil || status != 200 {
return nil, status, err return nil, status, err
} }
json.NewDecoder(data).Decode(&result) json.Unmarshal([]byte(data), &result)
return result, status, nil return result, status, nil
} }
} }
@ -288,9 +297,9 @@ func (jf *Jellyfin) newUser(username, password string) (map[string]interface{},
for key, value := range stringData { for key, value := range stringData {
data[key] = value data[key] = value
} }
reader, status, err := jf._post(url, data, true) response, status, err := jf._post(url, data, true)
var recv map[string]interface{} var recv map[string]interface{}
json.NewDecoder(reader).Decode(&recv) json.Unmarshal([]byte(response), &recv)
if err != nil || !(status == 200 || status == 204) { if err != nil || !(status == 200 || status == 204) {
return nil, status, err return nil, status, err
} }
@ -314,12 +323,12 @@ func (jf *Jellyfin) setConfiguration(userId string, configuration map[string]int
func (jf *Jellyfin) getDisplayPreferences(userId string) (map[string]interface{}, int, error) { func (jf *Jellyfin) getDisplayPreferences(userId string) (map[string]interface{}, int, error) {
url := fmt.Sprintf("%s/DisplayPreferences/usersettings?userId=%s&client=emby", jf.server, userId) url := fmt.Sprintf("%s/DisplayPreferences/usersettings?userId=%s&client=emby", jf.server, userId)
data, status, err := jf._getReader(url, nil) data, status, err := jf._get(url, nil)
if err != nil || !(status == 204 || status == 200) { if err != nil || !(status == 204 || status == 200) {
return nil, status, err return nil, status, err
} }
var displayprefs map[string]interface{} var displayprefs map[string]interface{}
err = json.NewDecoder(data).Decode(&displayprefs) err = json.Unmarshal([]byte(data), &displayprefs)
if err != nil { if err != nil {
return nil, status, err return nil, status, err
} }

Loading…
Cancel
Save