Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

json: cannot unmarshal number into Go struct field Metadata.MediaContainer.Metadata.ratingCount of type string #41

Open
anatosun opened this issue Nov 14, 2021 · 10 comments

Comments

@anatosun
Copy link
Contributor

I encountered this issue when using the function GetPlaylist(int). What seems to fix it is to change the field RatingCount of type Metadata from string to int. It appears that #35 does not bring a fix for that though.

@jrudio
Copy link
Owner

jrudio commented Nov 22, 2021

The whole Metadata struct is is getting this error when I run GetPlaylist(int)

Changing RatingCount to int now gives me:

"json: cannot unmarshal number into Go struct field Metadata.MediaContainer.Metadata.librarySectionID of type string"

I change librarySectionID to int

now I get "json: cannot unmarshal number into Go struct field Media.MediaContainer.Metadata.Media.id of type string"

I change that to int and now I get:

"json: cannot unmarshal number into Go struct field Part.MediaContainer.Metadata.Media.Part.id of type string"

I change that now I get "json: cannot unmarshal number into Go struct field Media.MediaContainer.Metadata.Media.optimizedForStreaming of type bool"

I change that to int and it works, but breaks GetSessions() 😅

In #35 I changed the following to satisfy the returned types in GetSessions():

librarySectionID -> int
.Metadata.Media.id -> int
.Metadata.Media.Part.id -> int
Media.optimizedForStreaming -> int

Are you able to test this on your server? Maybe it's just me?

Edit: RatingCount still works under GetSessions(), so yes, you are right, that needs to be changed.

@jrudio
Copy link
Owner

jrudio commented Nov 22, 2021

For clarity, the following two functions (and more) share the same Metadata struct when decoding the response body as json from PMS api:

GetSessions() needs:

Part.ID -> string
Metadata.LibrarySectionID -> string
Media.OptimizedForStreaming -> bool
Media.ID -> string

GetPlaylist(int) needs:

Part.ID -> int
Metadata.LibrarySectionID -> int
Media.OptimizedForStreaming -> int
Media.ID -> int

@anatosun
Copy link
Contributor Author

anatosun commented Nov 22, 2021

We should try this solution first: https://stackoverflow.com/questions/49097385/how-to-decode-json-with-type-convert-from-string-to-integer-in-golang-for-non-lo.

Or maybe we should come up with a custom Unmarshaler by implementing the interface json.Unmarshaler and doing some type conversion when necessary.

I haven't had the chance to test it on my side. My PMS server version is 1.24.5.5173 by the way.

@jrudio
Copy link
Owner

jrudio commented Dec 31, 2021

After changing the appropriate properties to use json.Number, sessions and playlist work fine

The only one that I can't handle is OptimizedForStreaming, which is either:

  • a boolean when fetching a playlist (GetPlaylist())
  • or an int (0 or 1) when fetching episode metadata (GetEpisode)

Custom Unmarshaler may be the best route for this

jrudio added a commit that referenced this issue Dec 31, 2021
@anatosun
Copy link
Contributor Author

anatosun commented Jan 18, 2022

I found this solution that could resolve our issue here. I may test it in the future. What should I do to reproduce the issue?

@jrudio
Copy link
Owner

jrudio commented Jan 18, 2022

Good find! This commit did something similar take care of it, but there are possibly some edge cases that are not well thought out with my commit.

To reproduce the issue I was using the commands: ./plex-client playlist <playlist-id> which uses GetPlaylist() and ./plex-client episode <episode-id> which uses GetEpisode() from the cli.

Edit: ./plex-client metadata <id> and ./plex-client playlist <id> should return 0 or 1

./plex-client sessions should return boolean

// plex can return int (GetMetadata(), GetPlaylist()) or boolean (GetSessions())

Not sure if having different media would affect the output of boolean or int on OptimizedForStreaming .

Looking forward to your thoughts or suggestions.

@anatosun
Copy link
Contributor Author

I've just tested the fix. While the fix itself works for the field OptimizedForStreaming, other issues are unfortunately raised with strings being number, int being float and vice versa. Here is a non exhaustive list of some errors I managed to fix by replacing the type in question with json.Number:

  • json: cannot unmarshal number into Go struct field Metadata.MediaContainer.Metadata.librarySectionID of type string
  • json: cannot unmarshal number into Go struct field Media.MediaContainer.Metadata.Media.id of type string
  • json: cannot unmarshal number into Go struct field Part.MediaContainer.Metadata.Media.Part.id of type string
  • json: cannot unmarshal number into Go struct field Stream.MediaContainer.Metadata.Media.Part.Stream.id of type string.

I will work on a separate branch to fix those different issues. I propose to replace very float/int (and some string) fields with json.Number to avoid further issues.

@anatosun
Copy link
Contributor Author

I came up with a working solution. I still have to make some test to make a PR but it fixes the aforementioned issues. Take a look at my branch type-fix on my profile.

@jrudio
Copy link
Owner

jrudio commented Jan 19, 2022

Really great work! Looked it over and I love the naming conventions the dynamic types. I think your PR will nullify #35, so I am looking forward to that.

I am curious about some of the Size fields that have xml tags but json.Number types as I don't know how it works. Do those still unmarshal as XML, but with json.Number?

Some Size fields still have type string, is that intended?

Good stuff!

@anatosun
Copy link
Contributor Author

anatosun commented Jan 22, 2022

I am curious about some of the Size fields that have xml tags but json.Number types as I don't know how it works. Do those still unmarshal as XML, but with json.Number?

No, it is a mistake on my side. json.Number will only work when unmarshalling json as far as I know.

Some Size fields still have type string, is that intended?

I'm still working on it and making some tests to see what's the best solution. Of course, it's way more sensible to use an integer type for Size.

jrudio added a commit that referenced this issue Apr 28, 2022
* fixed the types for metadata json responses

* added GetPlaylist() to cli

* added GetPlaylist() to cli

* fixed GetPlaylist() - catch non-200 status http errors

* changed types on properties that are int or string

* changed RatingCount per #41

* handle OptimizedForStreaming bool or int
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants