From 0caa2c77632ce039f7d2bda9a287667d3944d0eb Mon Sep 17 00:00:00 2001 From: sledgehammer999 Date: Sun, 25 Jun 2017 22:33:53 +0300 Subject: [PATCH] Initial commit. --- .gitattributes | 2 + README.md | 10 ++ nova3/engines/__init__.py | 0 nova3/engines/btdb.py | 147 +++++++++++++++++++++++++++ nova3/engines/demonoid.py | 144 +++++++++++++++++++++++++++ nova3/engines/legittorrents.py | 101 +++++++++++++++++++ nova3/engines/piratebay.py | 176 +++++++++++++++++++++++++++++++++ nova3/engines/torlock.py | 97 ++++++++++++++++++ nova3/engines/torrentz.py | 119 ++++++++++++++++++++++ nova3/engines/versions.txt | 6 ++ 10 files changed, 802 insertions(+) create mode 100644 .gitattributes create mode 100644 README.md create mode 100644 nova3/engines/__init__.py create mode 100644 nova3/engines/btdb.py create mode 100644 nova3/engines/demonoid.py create mode 100644 nova3/engines/legittorrents.py create mode 100644 nova3/engines/piratebay.py create mode 100644 nova3/engines/torlock.py create mode 100644 nova3/engines/torrentz.py create mode 100644 nova3/engines/versions.txt diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..d0c2d74 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +core.eol=lf +* text eol=lf diff --git a/README.md b/README.md new file mode 100644 index 0000000..b3ca4c9 --- /dev/null +++ b/README.md @@ -0,0 +1,10 @@ +search-plugins +=== + +This repository contains search plugins for the search feature in qBittorrent. + +This repository isn't managed by the core team directly. Its purpose is to allow a place where 3rd party contributors can gather and submit their plugins. + +Use the plugins and the websites they refer to at your own risk. You are personally responsible for following your country's copyright laws. + +Anyone is welcome to submit PRs that fix problems or add new plugins. diff --git a/nova3/engines/__init__.py b/nova3/engines/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/nova3/engines/btdb.py b/nova3/engines/btdb.py new file mode 100644 index 0000000..555850a --- /dev/null +++ b/nova3/engines/btdb.py @@ -0,0 +1,147 @@ +#VERSION: 1.01 +#AUTHORS: Charles Worthing +#CONTRIBUTORS: Diego de las Heras (ngosang@hotmail.es) + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the author nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +from html.parser import HTMLParser +#qBt +from novaprinter import prettyPrinter +from helpers import download_file, retrieve_url + +class btdb(object): + """ Search engine class """ + url = 'https://btdb.in' + name = 'BTDB' + + def download_torrent(self, info): + """ Downloader """ + print(download_file(info)) + + class MyHtmlParser(HTMLParser): + """ Parser class """ + def __init__(self, results, url): + HTMLParser.__init__(self) + self.results = results + self.url = url + self.current_item = {} # One torrent result + self.add_query = True + self.torrent_info_index = 0 # Count of the meta data encountered + self.torrent_info_array = [] + self.meta_data_grabbing = 0 + self.meta_data_array = [] + self.torrent_no_files = 0 + self.torrent_date_added = 0 + self.torrent_popularity = 0 + self.mangnet_link = "" + self.desc_link = "" + self.torrent_name = "" + + def handle_starttag(self, tag, attrs): + if tag == "span": + span_dict = dict(attrs) + if "class" in span_dict: + the_class = span_dict["class"] + if the_class == "item-meta-info-value": + self.meta_data_grabbing += 1 + else: + self.meta_data_grabbing = 0 + if tag == "script": + return + if tag == "li": + for attr in attrs: + if attr[1] == "search-ret-item": + self.torrent_info_index = 1 + if tag == "a": + if self.torrent_info_index > 0: + params = dict(attrs) + if "href" in params: + link = params["href"] + if link.startswith("/torrent"): + self.desc_link = "".join((self.url, link)) + self.torrent_name = params["title"] + if link.startswith("magnet:"): + self.mangnet_link = link + + def handle_endtag(self, tag): + if tag == "script": + return + if tag == "div": + if self.meta_data_grabbing > 0: + + self.torrent_no_files = self.meta_data_array[2] # Not used + self.torrent_date_added = self.meta_data_array[4] # Not used + self.torrent_popularity = self.meta_data_array[6] # Not used + + self.current_item["size"] = self.meta_data_array[0] + self.current_item["name"] = self.torrent_name + self.current_item["engine_url"] = self.url + self.current_item["link"] = self.mangnet_link + self.current_item["desc_link"] = self.desc_link + self.current_item["seeds"] = -1 + self.current_item["leech"] = -1 + + prettyPrinter(self.current_item) + self.results.append('a') + self.current_item = {} + + self.meta_data_grabbing = 0 + self.meta_data_array = [] + self.mangnet_link = "" + self.desc_link = "" + self.torrent_name = "" + + def handle_data(self, data): + if self.torrent_info_index > 0: + self.torrent_info_array.append(data) + self.torrent_info_index += 1 + if self.meta_data_grabbing > 0: + self.meta_data_array.append(data) + self.meta_data_grabbing += 1 + + def handle_entityref(self, name): + c = unichr(name2codepoint[name]) + + def handle_charref(self, name): + if name.startswith('x'): + c = unichr(int(name[1:], 16)) + else: + c = unichr(int(name)) + + + def search(self, what, cat='all'): + """ Performs search """ + results_list = [] + parser = self.MyHtmlParser(results_list, self.url) + i = 1 + while i < 31: + # "what" is already urlencoded + html = retrieve_url(self.url + '/q/%s/%d?sort=popular' % (what, i)) + parser.feed(html) + if len(results_list) < 1: + break + del results_list[:] + i += 1 + parser.close() diff --git a/nova3/engines/demonoid.py b/nova3/engines/demonoid.py new file mode 100644 index 0000000..1372ac9 --- /dev/null +++ b/nova3/engines/demonoid.py @@ -0,0 +1,144 @@ +#VERSION: 1.23 +#AUTHORS: Douman (custparasite@gmx.se) +#CONTRIBUTORS: Diego de las Heras (ngosang@hotmail.es) + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the author nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +from html.parser import HTMLParser +from re import compile as re_compile +from re import DOTALL +from itertools import islice +#qBt +from novaprinter import prettyPrinter +from helpers import download_file, retrieve_url + +class demonoid(object): + """ Search engine class """ + url = "https://www.demonoid.pw" + name = "Demonoid" + supported_categories = {'all': '0', + 'music': '2', + 'movies': '1', + 'games': '4', + 'software': '5', + 'books': '11', + 'anime': '9', + 'tv': '3'} + + def download_torrent(self, info): + """ Downloader """ + print(download_file(info)) + + class MyHtmlParseWithBlackJack(HTMLParser): + """ Parser class """ + def __init__(self, url): + HTMLParser.__init__(self) + self.url = url + self.current_item = None + self.save_data = None + self.seeds_leech = False + self.size_repl = re_compile(",") + + def handle_starttag(self, tag, attrs): + """ Parser's start tag handler """ + if tag == "a": + params = dict(attrs) + if "href" in params: + link = params["href"] + if link.startswith("/files/details"): + self.current_item = dict() + self.current_item["desc_link"] = "".join((self.url, link)) + self.current_item["engine_url"] = self.url + self.save_data = "name" + elif link.startswith("/files/download"): + self.current_item["link"] = "".join((self.url, link)) + + elif self.current_item: + if tag == "td": + params = dict(attrs) + if "class" in params and "align" in params: + if params["class"].startswith("tone"): + if params["align"] == "right": + self.save_data = "size" + elif params["align"] == "center": + self.seeds_leech = True + + elif self.seeds_leech and tag == "font": + for attr in attrs: + if "class" in attr: + if attr[1] == "green": + self.save_data = "seeds" + elif attr[1] == "red": + self.save_data = "leech" + + self.seeds_leech = False + + + def handle_data(self, data): + """ Parser's data handler """ + if self.save_data: + if self.save_data == "name": + # names with special characters like '&' are splitted in several pieces + if 'name' not in self.current_item: + self.current_item['name'] = '' + self.current_item['name'] += data + else: + self.current_item[self.save_data] = data + self.save_data = None + if self.current_item.__len__() == 7: + self.current_item["size"] = self.size_repl.sub("", self.current_item["size"]) + prettyPrinter(self.current_item) + self.current_item = None + + def handle_endtag(self, tag): + """ Parser's end tag handler """ + if self.save_data == "name": + self.save_data = None + + def search(self, what, cat='all'): + """ Performs search """ + #prepare query + cat = self.supported_categories[cat.lower()] + query = "".join((self.url, "/files/?category=", cat, "&subcategory=All&quality=All&seeded=2&external=2&query=", what, "&uid=0&sort=S")) + + data = retrieve_url(query) + + add_res_list = re_compile("/files.*page=[0-9]+") + torrent_list = re_compile("start torrent list -->(.*)