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

Discusion: Breaking changes in qBittorrent search-engine #121

Open
ngosang opened this issue Dec 11, 2019 · 61 comments
Open

Discusion: Breaking changes in qBittorrent search-engine #121

ngosang opened this issue Dec 11, 2019 · 61 comments
Labels

Comments

@ngosang
Copy link
Member

ngosang commented Dec 11, 2019

Update: Proposal => qBittorrent.pdf


Hello everybody,

TLDR: I don't have time to maintain the plugins, the search-engine code needs a huge refactor. I'm proposing to remove all search plugins and Python code and make a native integration with https://github.com/Jackett/Jackett

First of all, I think this feature is used by thousands (take a look at Reddit) and qBittorrent is the only bittorrent client with this functionality. So, I don't want to remove it. Furthermore, in the latest releases is supported in the WebUI making it convenient for seedboxes.

The current implementation (code) is a mess, both, the C++ and Python parts. In this issue #84 I list all required changes to make it clean and more maintainable. That are a lot of changes, breaks compatibility, I don't have the skills to make the changes in the C++ code, and more important, there aren't maintainers for the plugins.

Instead of doing the changes, I propose to remove all Python code, including official and unofficial plugins and make native integration with Jackett for the following reasons.

  • https://github.com/Jackett/Jackett is a free and open source app that support more than 400 torrent sites. All official and unofficial plugins are supported. They are able to bypass captchas, cloudflare... We can't compete
  • It's well maintained. I'm contributor and it provides releases every day. We don't have maintainers to update the plugins frequently and most unofficial plugins are not working. https://github.com/Jackett/Jackett/releases
  • They provide a standard REST API based in Torznab. In simple words, it's a XML format well defined (never changes) and It's used by Radarr, Sonarr and many more software. https://github.com/Sonarr/Sonarr/wiki/Implementing-a-Torznab-indexer In case Jackett is discontinued, there are other projects that support Torznab and will be compatible also (see https://github.com/cardigann/cardigann). I'm talking about Jackett but we can make it generic to support all Torznab clients. Will be easy to request and parse the XML in C++ and keep the current UI/WebUI
  • We already support Jackett and I know many people using it. They won't have to make big changes. https://github.com/qbittorrent/search-plugins/wiki/How-to-configure-Jackett-plugin
  • Runs in the same platforms as qBittorrent does (win, linux, mac)
  • We won't have external dependencies, Python.
  • We won't have to worry about updating plugins nor resolving issues.
  • We won't have legal problems.
  • We can focus in doing the best bittorrent client, and let other projects to take care about the search-engines.

I want to know what do you think about and I would like you to try Jackett https://github.com/qbittorrent/search-plugins/wiki/How-to-configure-Jackett-plugin

ping @qbittorrent/demigods @qbittorrent/webdev @qbittorrent/frequent-contributors @qbittorrent/bug-handlers

UPDATE: Implementation draft

NOTE: In the first version I will try to make as few changes as possible.

1. Enable search engine

  • Python is not required as external dependency. We can remove all code related to check Python version, download python, copy python code...

2. Install plugins / search configuration

  • In a clean install, the list will be empty because we don't provide search engines anymore.
  • Remove strikethrough parts in the screenshot
    Sin título
  • When you click "add new indexer" or you "edit one" you will see a modal like this. We should add placeholders, tooltips or something to explain each field.
    image
  • All fields are mandatory and can be obtained from Jackett UI
    Sin título2

3. Search UI

  • By now we can let the UI as it is. Jackett provides additional information that we can add in the future.
    image

4. Perform searches with Torznab

5. Future steps

  • Add more columns in search results
    image
  • Move search engine to preferences ??
  • Allow to select several categories in the same search (eg, tv and movies)
  • Add all torznab categories. There are a lot.
  • Group search results by infohash. Torznab provides a field with this information
@ngosang ngosang added the chat label Dec 11, 2019
@glassez
Copy link
Member

glassez commented Dec 12, 2019

We can focus in doing the best bittorrent client, and let other projects to take care about the search-engines.

👍

@Piccirello
Copy link
Member

I like it, but I'm already a Jackett user.

@ngosang
Copy link
Member Author

ngosang commented Jan 4, 2020

Updated the first message with the changes required.

@Chocobo1 Would you like to work in the development? I can test everything carefully. :)

@Chocobo1
Copy link
Member

Chocobo1 commented Jan 5, 2020

@Chocobo1 Would you like to work in the development? I can test everything carefully. :)

I probably won't have much time to do anything significant.

@ngosang
Copy link
Member Author

ngosang commented Jan 5, 2020

If you don't mind I can help.

Of course you can. You have all the details in the first message. Just mention me when you have a PR or something. If at any point you are not longer interested in implementing this, please, notice me.

@libellula
Copy link

Imho the python integration has been there for a long time and it would not be ideal to drop it completely after all the work it required, just drop python2. Also, not all sites are supported and you can't use the "go to the description page" option.

@hannsen
Copy link

hannsen commented Feb 29, 2020

These would be the sites that we have but jackett does not:

Academic Torrents
ali213.net
anidex.info
CineCalidad
HorribleSubs
Linux Tracker
small-games.info
UnionDHT

But yeah, it sounds like a sensible idea, and there is no reason why these sites above could not be implemented in jackett.

and you can't use the "go to the description page" option.

Jackett does support that

@ngosang
Copy link
Member Author

ngosang commented Feb 29, 2020

I opened some requests in Jackett to add them. anidex.info, HorribleSubs are in Jackett already.
@hannsen Maybe you can help porting some of them to Jackett, or just helping Jackett somehow. :)

@jarmo
Copy link

jarmo commented Apr 14, 2020

Has anything already been done regarding this? I did upgrade my qBittorrent to 4.2.3 after which I still see all the plugins I had before, but "categories" only list "All categories". Also, sometimes plugins do not find anything anymore.

I agree that Jackett is a powerful plugin, but currently setting it up, running a separate process/server, configuring API keys and it being much slower than "normal" plugins, is not that good. I also see many errors in Jackett log, which implies that not everything works as reliably (of course, I have most of the indexers enabled for testing purposes, which might cause problems too - I will try to limit indexers).

Search functionality has been a killer feature for me so far when choosing a torrent client and if this changes then it needs to be easy/transparent to use (and Jackett is definitely not).

@ngosang
Copy link
Member Author

ngosang commented Apr 14, 2020

As far as I know no one is working in this. Most of the plugins included in qBittorrent are working (just make sure you have them updated). The categories are not tested well, just use "all categories".

I agree that Jackett is a powerful plugin, but currently setting it up, running a separate process/server, configuring API keys and it being much slower than "normal" plugins, is not that good. I also see many errors in Jackett log, which implies that not everything works as reliably (of course, I have most of the indexers enabled for testing purposes, which might cause problems too - I will try to limit indexers).

I'm Jackett developer too. These issues are real and are caused because Jackett has an API called "agregator" that sends the requests to all trackers at the same time.That API is not designed for use in production and its use is discouraged. It doesn't work well because it will wait until all trackers respond and if one tracker fails it causes problems in the others. In the current implementation of qBittorrent we are using that, but with the proposed changes the idea will be to list all indexers in qBittorrent and make separate requests. That is working really well in Jackett.

Search functionality has been a killer feature for me so far when choosing a torrent client and if this changes then it needs to be easy/transparent to use (and Jackett is definitely not).

I agree but qBittorent developers are not interested in maintaining this (an most of them use jackett anyway). In addition, it is increasingly difficult to maintain trackers because they have security measures such as re-captcha and cloudflare. Jackett has mechanisms to circumvent those protections.
PRs are welcome but I don't see any.

@jarmo
Copy link

jarmo commented Apr 15, 2020

@ngosang thank you for your thoughts.

The categories are not tested well, just use "all categories".

My point was that they were working before and stopped working after upgrading. That's why I asked. It doesn't really matter to me because I always have been using "all categories" anyway. Just an observation.

I'm Jackett developer too. These issues are real and are caused because Jackett has an API called "agregator" that sends the requests to all trackers at the same time.That API is not designed for use in production and its use is discouraged. It doesn't work well because it will wait until all trackers respond and if one tracker fails it causes problems in the others. In the current implementation of qBittorrent we are using that, but with the proposed changes the idea will be to list all indexers in qBittorrent and make separate requests. That is working really well in Jackett.

Looking at the Jackett logs that was my initial suspicion too, that it works exactly like you just described in here. Good that you confirmed it, since that explains a lot. When I did enable all (public) indexers in the beginning then I had to start looking at the log and disable some, which were failing thus causing entire search to not return any results. Using your proposed API does make sense and sounds like a good idea.

I agree but qBittorent developers are not interested in maintaining this (an most of them use jackett anyway). In addition, it is increasingly difficult to maintain trackers because they have security measures such as re-captcha and cloudflare. Jackett has mechanisms to circumvent those protections.

I totally understand this. One way of solving this problem would be to create better integration between Jackett and qBittorrent where Jackett is bundled with qBittorrent or can be installed somehow throught qBittorrent and it would start/stop Jackett server and configure API key automatically or whatever so that end-user would not need to know anything about Jackett or how to configure it etc. I'm quite sure that this is also not a small task and I totally understand that PRs are welcome since I'm developing some OSS stuff too.

Just my thoughts how things could be improved.

@ngosang ngosang mentioned this issue Apr 26, 2020
16 tasks
@cyberfunk

This comment has been minimized.

@ngosang

This comment has been minimized.

@cyberfunk

This comment has been minimized.

@ngosang

This comment has been minimized.

@cyberfunk

This comment has been minimized.

@glassez
Copy link
Member

glassez commented May 18, 2021

The idea is to make a basic Torznab implementation, that could be extended in the future, and remove existing search-egine code

@ngosang
Something like what an existing Jackett plugin does would be enough?

@glassez
Copy link
Member

glassez commented May 18, 2021

Torznab Spec => https://torznab.github.io/spec-1.3-draft/external/newznab/api.html

It says that I can optionally get data in the form of JSON. Does it really work in Jackett?

@FranciscoPombal
Copy link
Member

@glassez

You seem to be out of topic... Qt provides both XML and JSON parsers (e.g., the first is used in RSS subsystem whilst the second one is widely used across several components of qBittorrent). So it isn't a problem here.

😅 You're right of course :) Good thing this won't be an issue then.

Is some built-in HTTP server needed to implement Jackett support?

Again, a little bit of confusion from my part. Seems we just need to make a few requests using Jackett's API, i.e., we only ever act as a client, which is even simpler.

I'm afraid that by getting rid of the need to maintain one third-party app (Python), we'll get another "pain in the ass", in the form of a lot of requests from (lazy) users to have qBittorrent maintain yet another third-party app (Jackett).

My understanding (and hope) is that the maintenance burden will be minimal for us.

We "just" have to implement the required API calls, and process the received data and display it nicely in the UI.
After that we can basically forget about it, support for new plugins is entirely the responsibity of Jackett.
Of course, the maintenance burden being minimal for us hinges entirely on the premise that Jackett's API is mature and stable, but @ngosang is saying this is the case.

In fact, since apparently Torznab/Jackett's API is actually a "de facto" specification/protocol at this point, not just some internal one-off thing from some very particular 3rd party program, we could even think about ditching the search plugin concept entirely and just say qBittorrent implements support for the specification as a self-contained subsystem that is part of the core (I think this is exactly what @ngosang is suggesting, just worded a little differently) - i.e., we accept data from any program that sends it in the expected format, conformant to the spec.

This would be much like the relationship that qbittorrent has with RSS - qbittorrent implements the necessary bits of the protocol/spec so that the user can add any valid feed; there is no community-maintained repository of "RSS plugins" for each individual site. Of course, unlike the Torznab/Jacket API, I beleive RSS is standardized with an actual RFC (or multiple?), which is a stronger guarantee, but I believe the point still stands in spite of that.

@glassez
Copy link
Member

glassez commented May 18, 2021

we accept data from any program that sends it in the expected format

This is one of the key aspects of my concept as well.

I'm afraid that by getting rid of the need to maintain one third-party app (Python), we'll get another "pain in the ass", in the form of a lot of requests from (lazy) users to have qBittorrent maintain yet another third-party app (Jackett).

My understanding (and hope) is that the maintenance burden will be minimal for us.

I insist that we are no longer responsible for installing any third-party applications. If we do support Jackett, the responsibility for installing and configuring it should be entirely on the user himself. All qBittorrent should care about is maintaining the parameters it needs to interact with Jackett.

Offtopic:

I beleive RSS is standardized with an actual RFC (or multiple?), which is a stronger guarantee

I hope that Torznab/Jackett's API is something more strict/reliable than the RSS. Personally, I can't bring myself to call RSS a standard. It looks like a bunch of "may", "recommended" , etc. In addition, even what is defined there more or less strictly, is not respected by most of the so-called "web developers" who implement it on their sites. Because of this, our "generic" RSS support has a bunch of issues with supporting certain feeds.

Really, I'm not so strictly against implementing Jackett support instead of the existing subsystem. This looks like a worthwhile compromise. I am waiting for answers to my comments/questions above from interested parties (especially from @ngosang). Perhaps I will do this job if we agree on the key aspects of the problem.

@ngosang
Copy link
Member Author

ngosang commented May 18, 2021

Is some built-in HTTP server needed to implement Jackett support?

No. You only need to make HTTP requests to a remote service and parse the response. Jackett is stateless so you don't have to keep sessions or other things between requests neither. It's really simple.

It says that I can optionally get data in the form of JSON. Does it really work in Jackett?

The response is standard XML and can be parsed with Qt. The specification mentions JSON too but it's not implemented in Jackett. I never saw other Torznab programs using JSON, always XML.

I'm afraid that by getting rid of the need to maintain one third-party app (Python), we'll get another "pain in the ass", in the form of a lot of requests from (lazy) users to have qBittorrent maintain yet another third-party app (Jackett).

Don't worry about that. As I said, I'm maintainer and we have more than 20k daily downloads. There are other projects like Cardinann that follow the same Torznab specs. Jackett is not going anywhere, too many projects depend on it.

After briefly reviewing the code of the qBittorrent official Jackett plugin, I see that it doesn't even provide some of the possible values (size, seeds, leeches). Are these the limitations of the Jacket itself or just the plug-in? If the Jacket does not support receiving this information, will it not be another reason for reproaches in our direction if we switch to it?

It provides that information and more => https://github.com/qbittorrent/search-plugins/blob/master/nova3/engines/jackett.py#L136
The thing is Jackett supports 500 different torrents sites and not all the fields are available in all the sites. Some fields like the torrent name and download link are always present but other fields like the size, seeds, leechs can be null/unknown. We have to deal with that but we are already doing that in the current search engine.

Something like what an existing Jackett plugin does would be enough?

Yes and no. The basic functionality is covered by the plugin. Search request + XML response parsing.
The thing is the plugin is cheating a bit because it only makes 1 request. You can configure several indexers/sites in Jackett. The right thing to do is to make 1 Torznab request to each indexer. Instead of that, there is a hidden "indexer" in Jackett called "all" that internally calls all configured indexers and return 1 huge response after a lot of time. That endpoint cases problems if some of the indexers fails. It takes a long time until the endpoint responses. There is a limit in the number of results in the response...
I would like to allow configuring indexers 1 by 1 in qBittorrent and make requests in parallel. I know this is more work but the solution will be much better and forever.

@glassez I elaborated a document with the details. Take your time.
qBittorrent.pdf

@glassez
Copy link
Member

glassez commented May 19, 2021

It seems that the concept of using Torznab differs from mine only in the protocol, doesn't it?

@ngosang
In your Indexer configuration example you have both API path and Indexer URL fields. Seems API path is redundant since URL contains it. Or am I missing something?

@ngosang
Copy link
Member Author

ngosang commented May 19, 2021

In your Indexer configuration example you have both API path and Indexer URL fields. Seems API path is redundant since URL contains it. Or am I missing something?

The Torznab URL that you can copy & paste from Jackett UI doesn't have the /api part.
imagen

In other software like Radarr or Sonarr the /api part is set by default but it can be changed by the user. I don't know if there are other implementations out there with different terminations.

The Torznab specs one uses /api in the examples and the other doesn't mention.

For now, I think we can assume the URL has to end with /api (we have to concat that part if it's not in the URL). That way we can save one field. It can be added in the future is someone complains.

@FranciscoPombal
Copy link
Member

@ngosang

Cheers for the document, really nice.

I have 2 alternative proposals concerning "indexer management":

Is it possible to obtain a list of all possible indexers by querying the API? If so, qBittorrent could automatically make such a request and show all available indexers to the user. This also allows auto-filling all of the 4 mandatory text fields except the API key (page 4, 2nd figure), assuming the API returns a usable Name. Then, to get an indexer to work, it would have to be both configured and enabled (there can be a column for each property). If an indexer is not configured, it shows up as greyed-out in the list, and when selected, the only available button for clicking is a "configure indexer" button. Once an indexer is configured, it can either be enabled or disabled as normal.

Maybe indexer management could be a tab instead of a dialog? Not a very important decision, but worth thinking about.


Also, you mention that querying all indexers is error-prone and incurs a performance penalty. We should probably warn the user (with a red-lettered label or something) that executing searches with many indexers enabled may take a long time.

Another note: It should be possible to search with only a subset of enabled indexers, not just one or "all enabled" (but that capability can probably be left out of a first implementation).

@glassez
Copy link
Member

glassez commented May 20, 2021

Well, I'm going to do this job in the meantime.

Maybe indexer management could be a tab instead of a dialog? Not a very important decision, but worth thinking about.

  1. Why?
  2. Do you mean the tab in the same line with regular "search result" tabs?

In any case, it will initially be a dialog, since the other option is controversial.

Is it possible to obtain a list of all possible indexers by querying the API? If so, qBittorrent could automatically make such a request and show all available indexers to the user. [...]

I still insist on implementing it to be configurable at "independent indexers" basis I still insist that it can be configured based on "independent indexers", so we don't have a hard dependency on the Jackett or anything else. Just a set of individual endpoints that support Torznab protocol.
Of course, we can later add this feature as an additional action "Get a list of indexers from a URL".

@FranciscoPombal
Copy link
Member

@glassez

  1. Why?

  2. Do you mean the tab in the same line with regular "search result" tabs?

  1. I would prefer it to be a non-modal UI element, so that interaction with it is more seamless.

  2. I mean as "subtabs" within the search tab itself. A picture is worth a thousand words (imagine both buttons with red text switch between "subtabs"; here, the results "subtab" would be active):

    screenshot

Of course, I don't mind too much if you do end up implementing it as a dialog, this is simply a suggestion.

I agree with the rest of your post.

@glassez
Copy link
Member

glassez commented May 20, 2021

I mean as "subtabs" within the search tab itself. A picture is worth a thousand words (imagine both buttons with red text switch between "subtabs"; here, the results "subtab" would be active):

Well, it looks acceptable, except that it loses a bit of vertical space, which might worry someone.

@FranciscoPombal
Copy link
Member

@glassez

Well, it looks acceptable, except that it loses a bit of vertical space, which might worry someone.

Good point, agree that horizontal space is cheaper. But the button to bring out the dialog would take up approximately the same amount of space. So I guess the ideal solution would be to position the tabs vertically on the right, the same we do it for the banned IPs tab.

@ngosang
Copy link
Member Author

ngosang commented May 21, 2021

Well, I'm going to do this job in the meantime.

Nice to hear that. Please, quote me when there is something to test. I can help with that.

@glassez
Copy link
Member

glassez commented Jun 4, 2021

Torznab Spec => https://torznab.github.io/spec-1.3-draft/external/newznab/api.html

In the docs above is said:

The returned XML data stream is RSS 2.0 compliant and also contains additional information in the extra namespace.

But actually I see Jackett provide rss version="1.0" (although the content seems to look like RSS 2.0).
@ngosang, can you explain, what happens?

@ngosang
Copy link
Member Author

ngosang commented Jun 5, 2021

Yes, you are right. I will fix it in Jackett today. How it affects you?

@glassez
Copy link
Member

glassez commented Jun 5, 2021

Yes, you are right. I will fix it in Jackett today.

👍

How it affects you?

I needed to know what format the data is provided in Torznab in order to parse it. When I saw rss version="1.0", I thought, "What the hell is this? What document type is it?". Then I found in Torznab specification that it should be RSS 2.0 (only). I looked closer in XML produced by Jackett, and realized that it was very similar to RSS 2.0, but this declaration still confused me.
If it was just a mistake, then it's okay. Just fix it.

I have a sad experience of working with RSS, when even very soft requirements of the standard are often not met by server side. So in this situation, I would prefer that the Jackett bugs, if found, be fixed in Jackett without any workarounds in qBittorrent.

@ngosang
Copy link
Member Author

ngosang commented Jun 5, 2021

@glassez it's already fixed. New Jackett version will be released tomorrow. If you find more things just tell me.
Jackett/Jackett#11871

Released https://github.com/Jackett/Jackett/releases/tag/v0.18.255

@libellula

This comment has been minimized.

@glassez
Copy link
Member

glassez commented Jun 26, 2021

Well, I've finally completed the bulk of the work on this (qbittorrent/qBittorrent#15126). It's still a draft, since some little things are missing, such as validating the input data, etc. But you can already try it in practice. At the same time, I would have heard preliminary feedback. Just please don't ask for anything more advanced than what is there. I would like to limit myself to the basic functionality at the first stage. Advanced features can be added later.

@glassez
Copy link
Member

glassez commented Oct 6, 2021

I repeat qbittorrent/qBittorrent#15126 (comment) here. Maybe I'll get an answer after all...

Recently, I began to worry about one question. What is the real benefit of integrating the search engine system (of course, I don't mean the old subsystem, but the new one). What is there that can't be done just by having qBittorrent (w/o any Search Engine Integration) and Jackett?
Maybe this question sounds stupid for those who actively use this feature. But I am not an active user of it, so I would like to get an explanation.

@FranciscoPombal
Copy link
Member

@ghost
Copy link

ghost commented Jan 22, 2023

Hello all,

What is the state of the proposed changes on macOS version of QBT 4.5.0 / LT2.0?

According to the WIKI page for Search Plugins this has already been implemented yet I am seeing a nova3 directory wasn't removed upon install of v4.5.0 and I still see Python plugins. No mention of adding a torznab indexer. Do we need to remove the nova3 directory for the new torznab feature to be implemented properly?

@ngosang
Copy link
Member Author

ngosang commented May 21, 2023

It's not implemented yet and nobody is working on it. The development is here => qbittorrent/qBittorrent#15126
For now we are still using Official / Unofficial plugins written in Python. I recommend you to use the Jackett plugin for those indexers not supported => https://github.com/qbittorrent/search-plugins/wiki/How-to-configure-Jackett-plugin

@matterhub
Copy link

@ngosang I had some issues with Jackett (since resolved) and that led me to discover Prowlarr. I saw that Torznab implementation has stalled, but since Jackett already works I thought that means qBt can talk Torznab well enough already and I could just feed it Prowlarr's info in jackett.json since it's just another Torznab implementation.
It failed.
I would like to know if it's because qBittorrent has been modified to work specifically with Jackett and nothing else. Or if it's a stupid error on my end.

@ngosang
Copy link
Member Author

ngosang commented Jan 20, 2024

@amamelia Jacket is working fine. The qBittorrent plugin only works with Jackett but it could be modified to work with Prowlarr.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests