From fa6f4c6948980f6872447449484093c9b5b241aa Mon Sep 17 00:00:00 2001 From: ngosang Date: Sat, 7 Feb 2015 15:14:22 +0100 Subject: [PATCH] New feature: Torrentz search engine --- src/searchengine/nova/engines/torrentz.png | Bin 0 -> 226 bytes src/searchengine/nova/engines/torrentz.py | 113 ++++++++++++++++++++ src/searchengine/nova/engines/versions.txt | 1 + src/searchengine/nova3/engines/torrentz.png | Bin 0 -> 226 bytes src/searchengine/nova3/engines/torrentz.py | 113 ++++++++++++++++++++ src/searchengine/nova3/engines/versions.txt | 1 + src/searchengine/search.qrc | 4 + 7 files changed, 232 insertions(+) create mode 100644 src/searchengine/nova/engines/torrentz.png create mode 100644 src/searchengine/nova/engines/torrentz.py create mode 100644 src/searchengine/nova3/engines/torrentz.png create mode 100644 src/searchengine/nova3/engines/torrentz.py diff --git a/src/searchengine/nova/engines/torrentz.png b/src/searchengine/nova/engines/torrentz.png new file mode 100644 index 0000000000000000000000000000000000000000..88c8130cd535f414a5e29b440f60e0a9f1a0132b GIT binary patch literal 226 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9oCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#J`)?0u1fx{q-{VU+02lL66gHf+|;}hAeVu`xhOTUBsE2$JhLQ2!QIn0AVn{g z9VpHj;1l8sq>a;N{{R2~I_ESYAcwIe$S;_|;n|He5GTpo-GwQQyCwz5(e!k24B?1Q z7U1ROP2^x@;&^yK>cEKuK*C`H2M_DU2!|Gijsk{mMuv?`IsI<0xAFvPV(@hJb6Mw< G&;$Swg*f8? literal 0 HcmV?d00001 diff --git a/src/searchengine/nova/engines/torrentz.py b/src/searchengine/nova/engines/torrentz.py new file mode 100644 index 000000000..42e67e9c5 --- /dev/null +++ b/src/searchengine/nova/engines/torrentz.py @@ -0,0 +1,113 @@ +#VERSION: 2.11 +#AUTHORS: Diego de las Heras (diegodelasheras@gmail.com) + +# 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 novaprinter import prettyPrinter +from helpers import retrieve_url, download_file +from HTMLParser import HTMLParser +from urllib import urlencode + +class torrentz(object): + # mandatory properties + url = 'https://torrentz.eu' + name = 'Torrentz' + supported_categories = {'all': ''} + + trackers_list = ['udp://open.demonii.com:1337/announce', + 'udp://tracker.openbittorrent.com:80/announce', + 'udp://tracker.publicbt.com:80/announce', + 'udp://tracker.istole.it:80/announce'] + + class MyHtmlParser(HTMLParser): + def __init__(self, results, url, trackers): + HTMLParser.__init__(self) + self.results = results + self.url = url + self.trackers = trackers + self.td_counter = None + self.current_item = None + + def handle_starttag(self, tag, attrs): + if tag == 'a': + params = dict(attrs) + if 'href' in params: + self.current_item = {} + self.td_counter = 0 + self.current_item['link'] = 'magnet:?xt=urn:btih:' + \ + params['href'].strip(' /') + self.trackers + self.current_item['desc_link'] = self.url + params['href'].strip() + elif tag == 'span': + if isinstance(self.td_counter,int): + self.td_counter += 1 + if self.td_counter > 6: # safety + self.td_counter = None + + def handle_data(self, data): + if self.td_counter == 0: + if 'name' not in self.current_item: + self.current_item['name'] = '' + self.current_item['name'] += data + elif self.td_counter == 4: + if 'size' not in self.current_item: + self.current_item['size'] = data.strip() + elif self.td_counter == 5: + if 'seeds' not in self.current_item: + self.current_item['seeds'] = data.strip().replace(',', '') + elif self.td_counter == 6: + if 'leech' not in self.current_item: + self.current_item['leech'] = data.strip().replace(',', '') + + # display item + self.td_counter = None + self.current_item['engine_url'] = self.url + if self.current_item['name'].find(' \xc2'): + self.current_item['name'] = self.current_item['name'].split(' \xc2')[0] + self.current_item['link'] += '&' + urlencode({'dn' : self.current_item['name']}) + if not self.current_item['seeds'].isdigit(): + self.current_item['seeds'] = 0 + if not self.current_item['leech'].isdigit(): + self.current_item['leech'] = 0 + prettyPrinter(self.current_item) + self.results.append('a') + + def download_torrent(self, info): + print(download_file(info)) + + def search(self, what, cat='all'): + # initialize trackers for magnet links + trackers = '&' + '&'.join(urlencode({'tr' : tracker}) for tracker in self.trackers_list) + + i = 0 + while i < 6: + results_list = [] + # "what" is already urlencoded + html = retrieve_url(self.url + '/search?f=%s&p=%d' % (what, i)) + parser = self.MyHtmlParser(results_list, self.url, trackers) + parser.feed(html) + parser.close() + if len(results_list) < 1: + break + i += 1 diff --git a/src/searchengine/nova/engines/versions.txt b/src/searchengine/nova/engines/versions.txt index cc9d332b9..89e98411b 100644 --- a/src/searchengine/nova/engines/versions.txt +++ b/src/searchengine/nova/engines/versions.txt @@ -5,3 +5,4 @@ extratorrent: 1.2 kickasstorrents: 1.26 btdigg: 1.23 legittorrents: 1.02 +torrentz: 2.11 diff --git a/src/searchengine/nova3/engines/torrentz.png b/src/searchengine/nova3/engines/torrentz.png new file mode 100644 index 0000000000000000000000000000000000000000..88c8130cd535f414a5e29b440f60e0a9f1a0132b GIT binary patch literal 226 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9oCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#J`)?0u1fx{q-{VU+02lL66gHf+|;}hAeVu`xhOTUBsE2$JhLQ2!QIn0AVn{g z9VpHj;1l8sq>a;N{{R2~I_ESYAcwIe$S;_|;n|He5GTpo-GwQQyCwz5(e!k24B?1Q z7U1ROP2^x@;&^yK>cEKuK*C`H2M_DU2!|Gijsk{mMuv?`IsI<0xAFvPV(@hJb6Mw< G&;$Swg*f8? literal 0 HcmV?d00001 diff --git a/src/searchengine/nova3/engines/torrentz.py b/src/searchengine/nova3/engines/torrentz.py new file mode 100644 index 000000000..67f146574 --- /dev/null +++ b/src/searchengine/nova3/engines/torrentz.py @@ -0,0 +1,113 @@ +#VERSION: 2.11 +#AUTHORS: Diego de las Heras (diegodelasheras@gmail.com) + +# 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 novaprinter import prettyPrinter +from helpers import retrieve_url, download_file +from html.parser import HTMLParser +from urllib.parse import urlencode + +class torrentz(object): + # mandatory properties + url = 'https://torrentz.eu' + name = 'Torrentz' + supported_categories = {'all': ''} + + trackers_list = ['udp://open.demonii.com:1337/announce', + 'udp://tracker.openbittorrent.com:80/announce', + 'udp://tracker.publicbt.com:80/announce', + 'udp://tracker.istole.it:80/announce'] + + class MyHtmlParser(HTMLParser): + def __init__(self, results, url, trackers): + HTMLParser.__init__(self) + self.results = results + self.url = url + self.trackers = trackers + self.td_counter = None + self.current_item = None + + def handle_starttag(self, tag, attrs): + if tag == 'a': + params = dict(attrs) + if 'href' in params: + self.current_item = {} + self.td_counter = 0 + self.current_item['link'] = 'magnet:?xt=urn:btih:' + \ + params['href'].strip(' /') + self.trackers + self.current_item['desc_link'] = self.url + params['href'].strip() + elif tag == 'span': + if isinstance(self.td_counter,int): + self.td_counter += 1 + if self.td_counter > 6: # safety + self.td_counter = None + + def handle_data(self, data): + if self.td_counter == 0: + if 'name' not in self.current_item: + self.current_item['name'] = '' + self.current_item['name'] += data + elif self.td_counter == 4: + if 'size' not in self.current_item: + self.current_item['size'] = data.strip() + elif self.td_counter == 5: + if 'seeds' not in self.current_item: + self.current_item['seeds'] = data.strip().replace(',', '') + elif self.td_counter == 6: + if 'leech' not in self.current_item: + self.current_item['leech'] = data.strip().replace(',', '') + + # display item + self.td_counter = None + self.current_item['engine_url'] = self.url + if self.current_item['name'].find(' »'): + self.current_item['name'] = self.current_item['name'].split(' »')[0] + self.current_item['link'] += '&' + urlencode({'dn' : self.current_item['name']}) + if not self.current_item['seeds'].isdigit(): + self.current_item['seeds'] = 0 + if not self.current_item['leech'].isdigit(): + self.current_item['leech'] = 0 + prettyPrinter(self.current_item) + self.results.append('a') + + def download_torrent(self, info): + print(download_file(info)) + + def search(self, what, cat='all'): + # initialize trackers for magnet links + trackers = '&' + '&'.join(urlencode({'tr' : tracker}) for tracker in self.trackers_list) + + i = 0 + while i < 6: + results_list = [] + # "what" is already urlencoded + html = retrieve_url(self.url + '/search?f=%s&p=%d' % (what, i)) + parser = self.MyHtmlParser(results_list, self.url, trackers) + parser.feed(html) + parser.close() + if len(results_list) < 1: + break + i += 1 diff --git a/src/searchengine/nova3/engines/versions.txt b/src/searchengine/nova3/engines/versions.txt index 7366d0cef..aee6231ca 100644 --- a/src/searchengine/nova3/engines/versions.txt +++ b/src/searchengine/nova3/engines/versions.txt @@ -5,3 +5,4 @@ extratorrent: 1.2 kickasstorrents: 1.26 btdigg: 1.23 legittorrents: 1.03 +torrentz: 2.11 diff --git a/src/searchengine/search.qrc b/src/searchengine/search.qrc index 6229d64a4..aece84bcc 100644 --- a/src/searchengine/search.qrc +++ b/src/searchengine/search.qrc @@ -20,6 +20,8 @@ nova/engines/piratebay.py nova/engines/torrentreactor.png nova/engines/torrentreactor.py + nova/engines/torrentz.png + nova/engines/torrentz.py nova3/helpers.py nova3/nova2.py nova3/nova2dl.py @@ -40,5 +42,7 @@ nova3/engines/piratebay.py nova3/engines/torrentreactor.png nova3/engines/torrentreactor.py + nova3/engines/torrentz.png + nova3/engines/torrentz.py