Skip to content

[FIX] MyAnimeList - Use JSON instead of XML#2183

Merged
liiight merged 6 commits intoFlexget:developfrom
BrutuZ:patch-1
Aug 2, 2018
Merged

[FIX] MyAnimeList - Use JSON instead of XML#2183
liiight merged 6 commits intoFlexget:developfrom
BrutuZ:patch-1

Conversation

@BrutuZ
Copy link
Copy Markdown
Contributor

@BrutuZ BrutuZ commented Jul 31, 2018

Fixed MyAnimeList input plugin by switching from PHP\XML to JSON parsing.
ANIME_TYPE item 'series' updated to 'tv' in order to better reflect how the site refers to these.

Motivation for changes: Plugin stopped working after site maintenance and backend changes

Detailed changes:

  • Rewrote most of the segment responsible for fetching the data to use the JSON address and handle its data for Flexget entries.

Addressed issues:

Implemented feature requests:

  • None

Config usage if relevant (new plugin or updated schema):

  • type: series should be updated to type: tv

To Do:

  • Review
  • Pull

Fixed MyAnimeList input plugin by switching from PHP\XML to JSON parsing.
ANIME_TYPE item 'series' updated to 'tv' in order to better reflect how the site refers to these.
if not isinstance(selected_types, list):
selected_types = [selected_types]

for i in range(len(selected_status)):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like you can use enumerate here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed that and the other comments below. Should open a new PR or can a commit be added to this one?


try:
list_response = task.requests.get('https://myanimelist.net/malappinfo.php', params=parameters)
list.response = task.requests.get('https://myanimelist.net/animelist/' + config['username'] + '/load.json')
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dot is probably a typo, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, my bad.

if entry.isvalid():
entries.append(entry)

js = json.loads(list.response.text.encode('utf-8'))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for this, just call .json() on the response

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would also save the import json line at the top

raise plugin.PluginError('Error reading JSON')

for anime in js:
if (anime["status"] in selected_status
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Funky indentation

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Broke it down to comply with styling recommendation (up to 120 characters line) and make the conditions easier to read

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case, something like this is probably better:

            has_selected_status = anime["status"] in selected_status or config['status'] == 'all'
            has_selected_type = anime["anime_media_type_string"].lower() in selected_types or config['type'] == 'all'
            if has_selected_status and has_selected_type:

Lines are still <120 characters, and it's significantly easier to understand.

BrutuZ added 3 commits July 31, 2018 20:12
Fixed MyAnimeList input plugin by switching from PHP\XML to JSON parsing.
ANIME_TYPE item 'series' updated to 'tv' in order to better reflect how the site refers to these.
entries.append(entry)

js = list_response.json()
except:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is too broad. I imagine you want to catch requests.HTTPError here

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The HTTP request is done earlier, this just decodes the response.

What exception is raised on decode errors seems to depend on the underlying JSON library used by requests, and possibles exceptions include at least simplejson.errors.JSONDecodeError and json.decoder.JSONDecodeError.

At the very least, the statement should be updated to except Exception.

if not isinstance(selected_types, list):
selected_types = [selected_types]

for i,j in enumerate(selected_status):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing whitespace after comma. Also, if possible, please provide meaningful variable names.

'on_hold' : 3,
'dropped' : 4,
'plan_to_watch' : 6,
'all' : 7
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dictionary keys and : should not be separated by whitespace.

selected_status = config.get('status', list(STATUS.values()))
selected_types = config.get('type', list(ANIME_TYPE.values()))
selected_status = config.get('status', list(STATUS.keys()))
selected_types = config.get('type', list(ANIME_TYPE))
Copy link
Copy Markdown
Contributor

@tobbez tobbez Aug 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming the defaults set in the schema ensure these have values, the second parameter to .get will never be used, and these could be replaced by config['status']/config['type'].

selected_types = [selected_types]

for i,j in enumerate(selected_status):
selected_status[i] = STATUS[j]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replacing these two lines with selected_status = [STATUS[s] for s in selected_status] would be more idiomatic.

raise plugin.PluginError('Error reading JSON')

for anime in js:
if (anime["status"] in selected_status
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case, something like this is probably better:

            has_selected_status = anime["status"] in selected_status or config['status'] == 'all'
            has_selected_type = anime["anime_media_type_string"].lower() in selected_types or config['type'] == 'all'
            if has_selected_status and has_selected_type:

Lines are still <120 characters, and it's significantly easier to understand.

url = "https://myanimelist.net" + anime["anime_url"],
mal_name = anime["anime_title"],
mal_poster = anime["anime_image_path"],
mal_type = anime["anime_media_type_string"]
Copy link
Copy Markdown
Contributor

@tobbez tobbez Aug 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Equals sign (=) between parameter names and values should not be surrounded by white space.


try:
list_response = task.requests.get('https://myanimelist.net/malappinfo.php', params=parameters)
list_response = task.requests.get('https://myanimelist.net/animelist/' + config['username'] + '/load.json')
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

config['username'] may require URL encoding (depending on what characters are allowed in usernames).

mal_poster = anime["anime_image_path"],
mal_type = anime["anime_media_type_string"]
)
entries.append(entry)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Entry could be constructed directly when appended. No need to assign it to an intermediate variable first, i.e:

entries.append(Entry(
    title=anime["anime_title"],
    ...
))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing wrong with a little brevity there, assigning it first is fine

selected_types = [selected_types]

for index, value in enumerate(selected_status):
selected_status[index] = STATUS[value]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

selected_status = [STATUS[s] for s in selected_status] would still be more idiomatic than these two lines.

Other than that: LGTM.

@liiight liiight merged commit 9051386 into Flexget:develop Aug 2, 2018
@BrutuZ BrutuZ deleted the patch-1 branch May 21, 2019 17:55
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

Successfully merging this pull request may close these issues.

3 participants