diff --git a/Changelog b/Changelog index ae2f1effc..6c319ebe7 100644 --- a/Changelog +++ b/Changelog @@ -8,6 +8,7 @@ - FEATURE: Give feedback regarding the IP filter parsing - FEATURE: Added a button to reload the IP filter - FEATURE: Search engine results can now be opened in a Web browser + - FEATURE: Added a search engine plugin to extratorrent.com - COSMETIC: Same deletion confirmation dialog in the GUI and Web UI - COSMETIC: Simplified the top toolbar - COSMETIC: Display execution log as a tab instead of a modal window diff --git a/src/searchengine/nova2/engines/extratorrent.png b/src/searchengine/nova2/engines/extratorrent.png new file mode 100644 index 000000000..e5e845718 Binary files /dev/null and b/src/searchengine/nova2/engines/extratorrent.png differ diff --git a/src/searchengine/nova2/engines/extratorrent.py b/src/searchengine/nova2/engines/extratorrent.py new file mode 100755 index 000000000..b57558915 --- /dev/null +++ b/src/searchengine/nova2/engines/extratorrent.py @@ -0,0 +1,116 @@ +#VERSION: 1.1 +#AUTHORS: Christophe Dumez (chris@qbittorrent.org) + +# 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 +import sgmllib +import re + +class extratorrent(object): + url = 'http://extratorrent.com' + name = 'extratorrent' + supported_categories = {'all': '', 'movies': '4', 'tv': '8', 'music': '5', 'games': '3', 'anime': '1', 'software': '7', 'books': '2', 'pictures': '6'} + + def __init__(self): + self.results = [] + self.parser = self.SimpleSGMLParser(self.results, self.url) + + def download_torrent(self, info): + print download_file(info) + + class SimpleSGMLParser(sgmllib.SGMLParser): + def __init__(self, results, url, *args): + sgmllib.SGMLParser.__init__(self) + self.url = url + self.td_counter = None + self.current_item = None + self.start_name = False + self.results = results + + def start_a(self, attr): + params = dict(attr) + #print params + if params.has_key('href') and params['href'].startswith("/torrent_download/"): + self.current_item = {} + self.td_counter = 0 + self.start_name = False + torrent_id = '/'.join(params['href'].split('/')[2:]) + self.current_item['link']=self.url+'/download/'+torrent_id + elif params.has_key('href') and params['href'].startswith("/torrent/") and params['href'].endswith(".html"): + self.current_item['desc_link'] = self.url + params['href'].strip() + self.start_name = True + + def handle_data(self, data): + if self.td_counter == 2: + if not self.current_item.has_key('name') and self.start_name: + self.current_item['name'] = data.strip() + elif self.td_counter == 3: + if not self.current_item.has_key('size'): + self.current_item['size'] = '' + self.current_item['size']+= data.replace(" ", " ").strip() + elif self.td_counter == 4: + if not self.current_item.has_key('seeds'): + self.current_item['seeds'] = '' + self.current_item['seeds']+= data.strip() + elif self.td_counter == 5: + if not self.current_item.has_key('leech'): + self.current_item['leech'] = '' + self.current_item['leech']+= data.strip() + + def start_td(self,attr): + if isinstance(self.td_counter,int): + self.td_counter += 1 + if self.td_counter > 5: + self.td_counter = None + # Display item + if self.current_item: + self.current_item['engine_url'] = self.url + 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 search(self, what, cat='all'): + ret = [] + i = 1 + while True and i<11: + results = [] + parser = self.SimpleSGMLParser(results, self.url) + dat = retrieve_url(self.url+'/advanced_search/?with=%s&s_cat=%s&page=%d'%(what, self.supported_categories[cat], i)) + results_re = re.compile('(?s).*') + for match in results_re.finditer(dat): + res_tab = match.group(0) + parser.feed(res_tab) + parser.close() + break + if len(results) <= 0: + break + i += 1 + diff --git a/src/searchengine/nova2/engines/versions.txt b/src/searchengine/nova2/engines/versions.txt index 4b7091029..565e8cc33 100644 --- a/src/searchengine/nova2/engines/versions.txt +++ b/src/searchengine/nova2/engines/versions.txt @@ -5,3 +5,4 @@ mininova: 1.50 piratebay: 1.40 vertor: 1.2 torrentdownloads: 1.1 +extratorrent: 1.1 diff --git a/src/searchengine/search.qrc b/src/searchengine/search.qrc index 21dfa0c96..eeb85bb14 100644 --- a/src/searchengine/search.qrc +++ b/src/searchengine/search.qrc @@ -19,5 +19,7 @@ nova2/engines/btjunkie.pynova2/engines/piratebay.pngnova2/engines/vertor.py + nova2/engines/extratorrent.py + nova2/engines/extratorrent.png