Skip to content

Feature/Torrentleech v5 API#2121

Merged
cvium merged 9 commits intoFlexget:developfrom
carlba:feature/torrentleech_v5_api
Apr 12, 2018
Merged

Feature/Torrentleech v5 API#2121
cvium merged 9 commits intoFlexget:developfrom
carlba:feature/torrentleech_v5_api

Conversation

@carlba
Copy link
Copy Markdown
Contributor

@carlba carlba commented Apr 11, 2018

Motivation for changes:

The last PR I made used the Torrentleech V4 API as a temporary fix to get the plugin working. This could stop working any time. Implementing support for the new API will futureproof the plugin

Detailed changes:

Addressed issues:

Notes:

This is the first real PR I make to this project so if I have made any mistakes feel free to point them out and I will gladly fix them :)

@carlba
Copy link
Copy Markdown
Contributor Author

carlba commented Apr 11, 2018

What would be a good User-Agent to use? The default FlexGet one didn't work so I tried with a couple of others and the default User-Agent of cURL seems to work.

"""
Search for name from torrentleech.
"""
task.requests.headers.update({'User-Agent': 'curl/7.54.0'})
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.

This changes the user agent for all plugins in the same task run. Not ideal.

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.

Agreed when I tested in the beginning I thought setting it globally was needed. But when I retested now it wasn't. I also didn't realise it messed with the requests of the other plugins used in the task.

Will fix.

Copy link
Copy Markdown
Contributor Author

@carlba carlba Apr 11, 2018

Choose a reason for hiding this comment

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

Unfortunately my initial tests where correct. The User-Agent has to be set globally otherwise the task will fail when using the download output plugin flexget.plugins.output.download.download_entry. When it tries to get the file it fails if the User-Agent is not set to curl/7.54.0 or something else supported.

Setting it globally affects other plugins so that is not good. I suppose the headers could be passed through the entry entry['download_headers']= {'User-Agent': 'curl/7.54.0'} much like auth is handled in the flexget.plugins.output.download.download_entry method.

Copy link
Copy Markdown
Contributor Author

@carlba carlba Apr 11, 2018

Choose a reason for hiding this comment

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

Another approach would be to create a custom download_auth like so:

class TorrentleechHeader(AuthBase):

    def __call__(self, request):
        request.headers['User-Agent'] = 'curl/7.54.0'
        return request

@cvium @liiight What do you think is best?

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.

No opinion

url = ('https://www.torrentleech.org/torrents/browse/list/query/' +
quote(query.encode('utf-8')) + filter_url)
log.debug('Using %s as torrentleech search url' % url)
log.debug('Using {} as torrentleech search url'.format(url))
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.

Change to log.debug('Using %s as torrentleech search url', url)

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.

Will fix

entry['content_size'] = parse_filesize(size.group(0))
# construct download URL
torrent_url = 'https://www.torrentleech.org/rss/download/{}/{}/{}'.format(
torrent['fid'], rss_key, torrent['filename'])
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.

Is the linebreak necessary? We allow up to 120 chars on one line.

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.

I will adjust my IDE accordingly :)

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.

This particular line is still above 120 chars though.

entry['torrent_leeches'] = torrent['leechers']
entry['search_sort'] = torrent_availability(entry['torrent_seeds'],
entry['torrent_leeches'])
entry['content_size'] = torrent['size']
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.

Which unit is the size in?

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.

It is in bytes I realized now that is should be in MiB.

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.

That is why we have a utility function to do the heavy lifting.

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.

Yes I did of course look at the util but it didn't seem like it was a perfect fit since it is meant to handle strings not integers.

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.

I will use the util according to your other comment.

url = ('https://www.torrentleech.org/torrents/browse/list/query/' +
quote(query.encode('utf-8')) + filter_url)
log.debug('Using %s as torrentleech search url' % url)
log.debug('Using {} as torrentleech search url'.format(url))
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.

leave the logger to do its own interpolation:

log.debug('Using %s as torrentleech search url', url)

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.

Good point having gone through have the python logger actually works your suggestion makes more sense :)

# urllib.quote will crash if the unicode string has non ascii characters,
# so encode in utf-8 beforehand

url = ('https://www.torrentleech.org/torrents/browse/list/query/' +
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.

i don't think you meant to make the url a tuple

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.

It's not a tuple.

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.

This will not make it into a tuple it is just a method to construct a multiline string.

entry['torrent_leeches'] = torrent['leechers']
entry['search_sort'] = torrent_availability(entry['torrent_seeds'],
entry['torrent_leeches'])
entry['content_size'] = torrent['size']
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.

we have a util that converts size to our requested format:

def parse_filesize(text_size, si=True):

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.

The util is according to it's docstring meant to parse a string containing a size to a MiB float. The value returned from the torrentleach API is a int of bytes.

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.

Yes, so just append 'b' to the int. Not the nicest way and I've been wanting to change the function signature, but it's also very low priority.

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.

Alright that works for me! Will fix


try:
response = task.requests.get(url, auth=auth, raise_status=False)
response = task.requests.get(url, auth=auth, raise_status=False, headers=headers)
Copy link
Copy Markdown
Contributor

@cvium cvium Apr 11, 2018

Choose a reason for hiding this comment

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

This overwrites any header set using the header plugin. None should not be the default.

Copy link
Copy Markdown
Contributor Author

@carlba carlba Apr 11, 2018

Choose a reason for hiding this comment

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

No it doesn't override the custom headers specified by the headers plugin. The default value of the headers parameter in the requests library is actually None so it has no affect. But I changed the method to retrieve the custom headers configured in the headers plugin from the config anyway.

Copy link
Copy Markdown
Contributor

@cvium cvium Apr 11, 2018

Choose a reason for hiding this comment

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

task.requests is a requests Session instance, so it may or may not contain headers set by other plugins. The default should be task.requests.headers.

Copy link
Copy Markdown
Contributor Author

@carlba carlba Apr 11, 2018

Choose a reason for hiding this comment

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

Yes but if you pass in headers=None to the get request it will not override the existing headers. Any existing headers are merged with headers passed in to the function.

I did change to task.requests.headers because it is a lot easier to understand and generally nicer.

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.

Thanks for all the patience with the PR btw :)

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.

I see.


# construct download URL
torrent_url = 'https://www.torrentleech.org/rss/download/{}/{}/{}'.format(torrent['fid'], rss_key,
torrent['filename'])
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.

I don't think this line break is necessary though

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.

The limit was 120 chars? Because the line is over that limit.

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.

I think my mono-space font is missing.

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.

I just use my IDE ruler :)

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.

screenshot 2018-04-11 20 10 57

@carlba
Copy link
Copy Markdown
Contributor Author

carlba commented Apr 12, 2018

@cvium @liiight Is there anything further I need to fix with the PR?

@cvium cvium merged commit a3f01e4 into Flexget:develop Apr 12, 2018
@carlba carlba deleted the feature/torrentleech_v5_api branch November 20, 2018 17:18
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.

The torrentleech plugin is not working with their V5 api

3 participants