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

Crash after adding search plugin #19061

Closed
orvn opened this issue Jun 2, 2023 · 2 comments
Closed

Crash after adding search plugin #19061

orvn opened this issue Jun 2, 2023 · 2 comments
Labels
Crash Duplicate OS: macOS Issues specific to macOS Search engine Issues related to the search engine/search plugins functionality

Comments

@orvn
Copy link

orvn commented Jun 2, 2023

qBittorrent & operating system versions

qBittorrent version: v4.5.3 (64-bit)
Libtorrent version: 2.0.9.0
Qt version: 6.5.1
Boost version: 1.82.0
OpenSSL version: 1.1.1t
zlib version: 1.2.11
OS version: macOS Ventura (13.2) 22.3.0 arm64

What is the problem?

After I added a search plugin, the app crashed. Now, whenever I try to access the search plugins, it crashes right away.

Steps to reproduce

App crashes immediately upon attempting to access search plugins, see video.

search-plugins-crash_2023-06-01.mp4

Additional context

No response

Log(s) & preferences file(s)

Additional logs

Caught signal: SIGABRT
 0# getStacktrace() in /Applications/qbittorrent.app/Contents/MacOS/qbittorrent
 1# (anonymous namespace)::abnormalExitHandler(int) in /Applications/qbittorrent.app/Contents/MacOS/qbittorrent
 2# _sigtramp in /usr/lib/system/libsystem_platform.dylib
 3# pthread_kill in /usr/lib/system/libsystem_pthread.dylib
 4# abort in /usr/lib/system/libsystem_c.dylib
 5# __cxxabiv1::__aligned_malloc_with_fallback(unsigned long) in /usr/lib/libc++abi.dylib
 6# demangling_unexpected_handler() in /usr/lib/libc++abi.dylib
 7# _objc_terminate() in /usr/lib/libobjc.A.dylib
 8# std::__terminate(void (*)()) in /usr/lib/libc++abi.dylib
 9# __cxa_get_exception_ptr in /usr/lib/libc++abi.dylib
10# __cxxabiv1::exception_cleanup_func(_Unwind_Reason_Code, _Unwind_Exception*) in /usr/lib/libc++abi.dylib
11# objc_exception_throw in /usr/lib/libobjc.A.dylib
12# -[__NSCFString characterAtIndex:].cold.1 in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
13# -[__NSArrayM objectAtIndexedSubscript:] in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
14# -[QMacAccessibilityElement initWithId:role:] in /Applications/qbittorrent.app/Contents/MacOS/qbittorrent
15# +[QMacAccessibilityElement elementWithId:] in /Applications/qbittorrent.app/Contents/MacOS/qbittorrent
16# QCocoaAccessibility::notifyAccessibilityUpdate(QAccessibleEvent*) in /Applications/qbittorrent.app/Contents/MacOS/qbittorrent

@orvn
Copy link
Author

orvn commented Jun 2, 2023

The following are the search plugins I tried to load:

one337x.py

# VERSION: 2.1
# AUTHORS: sa3dany, Alyetama, BurningMop

# LICENSING INFORMATION
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

import re
from html.parser import HTMLParser

from helpers import retrieve_url
from novaprinter import prettyPrinter


class one337x(object):
    url = 'https://1337x.to'
    name = '1337x'
    supported_categories = {
        'all': None,
        'anime': 'Anime',
        'software': 'Applications',
        'games': 'Games',
        'movies': 'Movies',
        'music': 'Music',
        'tv': 'TV',
    }

    class MyHtmlParser(HTMLParser):

        def error(self, message):
            pass

        A, TD, TR, HREF, TABLE = ('a', 'td', 'tr', 'href', 'tbody')

        def __init__(self, url):
            HTMLParser.__init__(self)
            self.url = url
            self.row = {}
            self.column = None
            self.insideRow = False
            self.foundTable = False
            self.foundResults = False
            self.parser_class = {
                # key: className
                'name': 'name',
                'seeds': 'seeds',
                'leech': 'leeches',
                'size': 'size'
            }

        def handle_starttag(self, tag, attrs):
            params = dict(attrs)

            if 'search-page' in params.get('class', ''):
                self.foundResults = True
                return

            if self.foundResults and tag == self.TABLE:
                self.foundTable = True
                return

            if self.foundTable and tag == self.TR:
                self.insideRow = True
                return

            if self.insideRow and tag == self.TD:
                classList = params.get('class', None)
                for columnName, classValue in self.parser_class.items():
                    if classValue in classList:
                        self.column = columnName
                        self.row[self.column] = -1
                return

            if self.insideRow and tag == self.A:
                if self.column != 'name' or self.HREF not in params:
                    return
                link = params[self.HREF]
                if link.startswith('/torrent/'):
                    link = f'{self.url}{link}'

                    torrent_page = retrieve_url(link)
                    magnet_regex = r'href="magnet:.*"'
                    matches = re.finditer(magnet_regex, torrent_page,
                                          re.MULTILINE)
                    magnet_urls = [x.group() for x in matches]

                    self.row['link'] = magnet_urls[0].split('"')[1]
                    self.row['engine_url'] = self.url
                    self.row['desc_link'] = link

        def handle_data(self, data):
            if self.insideRow and self.column:
                self.row[self.column] = data
                self.column = None

        def handle_endtag(self, tag):
            if tag == 'table':
                self.foundTable = False

            if self.insideRow and tag == self.TR:
                self.insideRow = False
                self.column = None
                array_length = len(self.row)
                if array_length < 1:
                    return
                prettyPrinter(self.row)
                self.row = {}

    def download_torrent(self, info):
        print(download_file(info))

    def search(self, what, cat='all'):
        lastli = '<li class="last">'
        category = self.supported_categories[cat]

        if category:
            page_url = f'{self.url}/category-search/{what}/{category}/'
        else:
            page_url = f'{self.url}/search/{what}/'

        # try to get 15 pages (20 * 15 = 300 results) and stop when we don't found results
        results_list = []
        parser = self.MyHtmlParser(self.url)
        page = 1
        while page < 16:
            # download the page
            html = retrieve_url(page_url + str(page) + '/')
            parser.feed(html)
            if html.find(lastli) == -1:
                break
            page += 1
        parser.close()

thepiratebay.py

# VERSION: 4.1
# AUTHORS: Scare! (https://Scare.ca/dl/qBittorrent/)

# added categories to v1.0 by LightDestory https://github.com/LightDestory

import urllib.parse
import json
from helpers import retrieve_url,download_file
from novaprinter import prettyPrinter


class thepiratebay(object):
	url='https://thepiratebay.org'
	api='https://apibay.org'
	name='The Pirate Bay w. categories'

	# uncomment appropriate lines to include TPB category in qBittorrent search category
	# currently set to include only HD video for "movies" & "tv"
	supported_categories={
		'all':		[0],
		'anime':
		[
			207,	# Video > HD - Movies
			208,	# Video > HD - TV shows
			201,	# Video > Movies
			202,	# Video > Movies DVDR
			205,	# Video > TV shows
			206,	# Video > Handheld
			209,	# Video > 3D
			299,	# Video > Other
			501,	# Porn > Movies
			502,	# Porn > Movies DVDR
			505,	# Porn > HD - Movies
			599,	# Porn > Other			!!! comma after each number...
			699		# Other > Other			!!! ...except the last!
		],
		'books':
		[
#			102,	# Audio > Audio books
			601,	# Other > E-books
			602		# Other > Comics
		],
		'games':
		[
			400,	# Games
			504		# Porn > Games
		],
		'movies':
		[
#			201,	# Video > Movies
#			202,	# Video > Movies DVDR
#			209,	# Video > 3D
			207		# Video > HD - Movies
		],
		'music':
		[
#			203,	# Video > Music videos
			101,	# Audio > Music
			104		# Audio > FLAC
		],
		'pictures':
		[
			603,	# Other > Pictures
			604,	# Other > Covers
			503		# Porn > Pictures
		],
		'software':	# but not games
		[
			300		# Applications
		],
		'tv':
		[
#			205,	# Video > TV shows
			208		# Video > HD - TV shows
		]
	}

	torrent='{self.url}/description.php?id={id}'
	download='{self.api}/t.php?id={id}'
	magnet='magnet:?xt=urn:btih:{hash}&dn={name}&{trackers} {info}'
	query='{self.api}/q.php?q={what}&cat={category}'

	trackers=[
		'udp://tracker.coppersurfer.tk:6969/announce',
		'udp://tracker.openbittorrent.com:6969/announce',
		'udp://9.rarbg.to:2710/announce',
		'udp://9.rarbg.me:2780/announce',
		'udp://9.rarbg.to:2730/announce',
		'udp://tracker.opentrackr.org:1337',
		'http://p4p.arenabg.com:1337/announce',
		'udp://tracker.torrent.eu.org:451/announce',
		'udp://tracker.tiny-vps.com:6969/announce',
		'udp://open.stealth.si:80/announce']

	def download_torrent(self,info):
		torrent_id=urllib.parse.unquote(info).split('=')[-1]
		url=self.download.format(self=self,id=torrent_id)
		data=json.loads(retrieve_url(url))
		if data:
			name=urllib.parse.quote(data['name'],safe='')
			trs=urllib.parse.urlencode({'tr':self.trackers},True)
			print(self.magnet.format(hash		=data['info_hash'],
									 name		=name,
									 trackers	=trs,
									 info		=info))
		else:
			raise Exception('Error in "'+self.name+'" search plugin, download_torrent()')

	def search(self,what,cat='all'):
		x=[]
		for category in self.supported_categories[cat]:
			url=self.query.format(self=self,what=what,category=category)
			x+=json.loads(retrieve_url(url))
		self.parseJSON(x)

	def parseJSON(self,collection):
		for torrent in collection:
			torrent_id=self.torrent.format(self=self,id=torrent['id'])
			data={
				'link':			urllib.parse.quote(torrent_id),
				'name':			torrent['name'],
				'size':			torrent['size'],
				'seeds':		torrent['seeders'],
				'leech':		torrent['leechers'],
				'engine_url':	self.url,
				'desc_link':	torrent_id
			}
			prettyPrinter(data)

yts_am.py

# VERSION: 1.0.1
# AUTHORS: mauricci

from helpers import download_file, retrieve_url
from novaprinter import prettyPrinter
import json, math

try:
    # python3
    from html.parser import HTMLParser
except ImportError:
    # python2
    from HTMLParser import HTMLParser


class yts_am(object):
    url = 'https://yts.am/'
    name = 'Yts.am'
    # category not used, just declared for qbt
    supported_categories = {'all': '', 'movies': ''}

    def search(self, what, cat='all'):
        page = 1#current page number
        limit = 20  # results per page
        moviesPages = 10  # actual total number of pages

        while page <= 10 and page <= moviesPages:  # max 10 pages
            url = self.url + 'api/v2/list_movies.json?query_term={0}&page={1}&limit={2}'.format(what, page, limit)
            page += 1
            html = retrieve_url(url)
            jsonData = json.loads(html)
            self.processJson(jsonData)
            moviesPages = math.ceil(float(jsonData['data']['movie_count']) / limit)

    def getSingleData(self):
        return {'name': '-1', 'seeds': '-1', 'leech': '-1', 'size': '-1', 'link': '-1', 'desc_link': '-1',
                'engine_url': self.url}

    def processJson(self, json):
        movieData = self.getSingleData()
        for movie in json['data']['movies']:
            movieData['name'] = '{} - {}'.format(movie['title'], movie['year'])
            movieData['desc_link'] = movie['url']
            for torrent in movie['torrents']:
                movieData['seeds'] = torrent['seeds']
                movieData['leech'] = torrent['peers']
                movieData['size'] = torrent['size']
                movieData['link'] = torrent['url']
                prettyPrinter(movieData)

    def download_torrent(self, info):
        """ Downloader """
        print(download_file(info))


# script test
if __name__ == "__main__":
    y = yts_am()
    y.search('tomb%20raider')

@xavier2k6 xavier2k6 added OS: macOS Issues specific to macOS Search engine Issues related to the search engine/search plugins functionality Crash labels Jun 2, 2023
@thalieht
Copy link
Contributor

thalieht commented Jun 6, 2023

Duplicate of #19090

@thalieht thalieht marked this as a duplicate of #19090 Jun 6, 2023
@thalieht thalieht closed this as not planned Won't fix, can't repro, duplicate, stale Jun 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Crash Duplicate OS: macOS Issues specific to macOS Search engine Issues related to the search engine/search plugins functionality
Projects
None yet
Development

No branches or pull requests

3 participants