diff --git a/circle.yml b/circle.yml index 5dd274a..034e261 100644 --- a/circle.yml +++ b/circle.yml @@ -10,6 +10,6 @@ test: - coverage run -m unittest discover post: - mkdir -p $CIRCLE_ARTIFACTS/coverage - - cd /home/ubuntu/pirate-get && coverage html --include=`pwd`* + - cd /home/ubuntu/pirate-get && coverage html --include=`pwd`* --omit="*/tests/*,*__init__*" - cp -R /home/ubuntu/pirate-get/htmlcov/* $CIRCLE_ARTIFACTS/coverage - coveralls diff --git a/pirate/pirate.py b/pirate/pirate.py index b740b00..5077acf 100755 --- a/pirate/pirate.py +++ b/pirate/pirate.py @@ -6,6 +6,8 @@ import configparser import socket import urllib.request as request import urllib.error +import sys + import webbrowser import pirate.data @@ -17,7 +19,7 @@ from os.path import expanduser, expandvars from pirate.print import print -def load_config(): +def parse_config_file(text): config = configparser.ConfigParser() # default options @@ -31,16 +33,12 @@ def load_config(): config.set('LocalDB', 'path', expanduser('~/downloads/pirate-get/db')) config.add_section('Misc') + # TODO: try to use https://docs.python.org/3/library/configparser.html#configparser.BasicInterpolation for interpolating in the command config.set('Misc', 'openCommand', '') config.set('Misc', 'transmission', 'false') config.set('Misc', 'colors', 'true') - # user-defined config files - main = expandvars('$XDG_CONFIG_HOME/pirate-get') - alt = expanduser('~/.config/pirate-get') - - # read config file - config.read([main] if os.path.isfile(main) else [alt]) + config.read_string(text) # expand env variables directory = expanduser(expandvars(config.get('Save', 'Directory'))) @@ -51,6 +49,22 @@ def load_config(): return config +def load_config(): + # user-defined config files + main = expandvars('$XDG_CONFIG_HOME/pirate-get') + alt = expanduser('~/.config/pirate-get') + + # read config file + if os.path.isfile(main): + with open(main) as f: + return parse_config_file(f.read()) + + if os.path.isfile(alt): + with open(alt) as f: + return parse_config_file(f.read()) + + return parse_config_file("") + def parse_cmd(cmd, url): cmd_args_regex = r'''(('[^']*'|"[^"]*"|(\\\s|[^\s])+)+ *)''' @@ -103,9 +117,7 @@ def parse_torrent_command(l): return code, choices -def main(): - config = load_config() - +def parse_args(args_in): parser = argparse.ArgumentParser( description='finds and downloads torrents from the Pirate Bay') parser.add_argument('-b', dest='browse', @@ -158,7 +170,7 @@ def main(): parser.add_argument('--disable-colors', dest='color', action='store_false', help='disable colored output') - args = parser.parse_args() + args = parser.parse_args(args_in) # figure out the mode - browse, search, top or recent if args.browse: @@ -170,6 +182,14 @@ def main(): else: args.mode = 'search' + return args + + +def main(): + config = load_config() + + args = parse_args(sys.argv[1:]) + if (config.getboolean('Misc', 'colors') and not args.color or not config.getboolean('Misc', 'colors')): pirate.data.colored_output = False diff --git a/pirate/torrent.py b/pirate/torrent.py index 3c0aa16..1acba15 100644 --- a/pirate/torrent.py +++ b/pirate/torrent.py @@ -28,7 +28,7 @@ def parse_category(category): return pirate.data.categories[category] else: print('Invalid category ignored', color='WARN') - return '0' + return 0 def parse_sort(sort): @@ -42,7 +42,7 @@ def parse_sort(sort): return pirate.data.sorts[sort] else: print('Invalid sort ignored', color='WARN') - return '99' + return 99 #TODO: warn users when using a sort in a mode that doesn't accept sorts @@ -161,6 +161,7 @@ def get_torrent(info_hash): return torrent.read() +# TODO: handle slashes in torrent names def save_torrents(chosen_links, results, folder): for link in chosen_links: magnet = results[link]['magnet'] @@ -178,7 +179,8 @@ def save_torrents(chosen_links, results, folder): print('Saved {:X} in {}'.format(info_hash, file)) -def save_magnets(chosen_links, mags, folder): +# TODO: handle slashes in torrent names +def save_magnets(chosen_links, results, folder): for link in chosen_links: magnet = results[link]['magnet'] name = re.search(r'dn=([^\&]*)', magnet) diff --git a/tests/test_pirate.py b/tests/test_pirate.py index a11f696..7ea2f53 100755 --- a/tests/test_pirate.py +++ b/tests/test_pirate.py @@ -32,9 +32,68 @@ class TestPirate(unittest.TestCase): [['1d'], ('d', [1])], [['1 ... d'], ('d', [1])], [['1-3 d'], ('d', [1,2,3])], + [['1-3'], (None, [1,2,3])], ] for test in tests: self.assertEqual(pirate.pirate.parse_torrent_command(*test[0]), test[1]) + def test_parse_config_file(self): + types = { + 'Save': { + 'magnets': bool, + 'Magnets': bool, + 'torrents': bool, + 'directory': str, + }, + 'LocalDB': { + 'enabled': bool, + 'path': str, + } + } + config1 = """ + [Save] + magnets=False + directory=dir + [LocalDB] + enabled=true + path=abc + """ + config2 = """ + [Save] + Magnets=True + """ + tests = [ + (config1, {'Save': {'magnets': False}}), + (config1, {'Save': {'torrents': False}}), + (config1, {'Save': {'directory': 'dir'}}), + (config1, {'LocalDB': {'enabled': True}}), + (config1, {'LocalDB': {'path': 'abc'}}), + (config2, {'Save': {'magnets': True}}), + ] + for test in tests: + config = pirate.pirate.parse_config_file(test[0]) + for section in test[1].keys(): + for name in test[1][section].keys(): + if types[section][name] == bool: + lhs = config.getboolean(section, name) + else: + lhs = config.get(section, name) + rhs = test[1][section][name] + self.assertEqual(lhs, rhs) + + def test_parse_args(self): + tests = [ + (['-b'], {'mode': 'browse'}), + ([], {'mode': 'top'}), + (['-R'], {'mode': 'recent'}), + (['internets'], {'mode': 'search', 'search': ['internets']}), + (['internets lol', 'lel'], {'mode': 'search', 'search': ['internets lol', 'lel']}), + ] + for test in tests: + config = pirate.pirate.parse_args(test[0]) + for option in test[1].keys(): + value = getattr(config, option) + self.assertEqual(test[1][option], value) + if __name__ == '__main__': unittest.main() diff --git a/tests/test_torrent.py b/tests/test_torrent.py index 6ca7c5c..137e2df 100755 --- a/tests/test_torrent.py +++ b/tests/test_torrent.py @@ -1,7 +1,12 @@ #!/usr/bin/env python3 import unittest +from unittest import mock +from unittest.mock import patch import pirate.torrent +import pirate.data import os +import io +import urllib from tests import util @@ -22,8 +27,97 @@ class TestTorrent(unittest.TestCase): def test_search_results(self): res = util.read_data('dan_bull_search.html') actual = pirate.torrent.parse_page(res) - expected = [{'uploaded': '04-04\xa02014', 'seeds': '16', 'leechers': '1', 'id': '9890864', 'magnet': 'magnet:?xt=urn:btih:30df4f8b42b8fd77f5e5aa34abbffe97f5e81fbf&dn=Dan+Croll+%26bull%3B+Sweet+Disarray+%5B2014%5D+320&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969', 'size': ['89.33', 'MiB']}, {'uploaded': '03-02\xa02014', 'seeds': '4', 'leechers': '0', 'id': '9684858', 'magnet': 'magnet:?xt=urn:btih:7abd3eda600996b8e6fc9a61b83288e0c6ac0d83&dn=Dan+Bull+-+Massive+Collection&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969', 'size': ['294', 'MiB']}, {'uploaded': '01-19\xa02013', 'seeds': '2', 'leechers': '0', 'id': '8037968', 'magnet': 'magnet:?xt=urn:btih:8f8d68fd0a51237c89692c428ed8a8f64a969c70&dn=Dan+Bull+-+Generation+Gaming+-+2013&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969', 'size': ['54.86', 'MiB']}, {'uploaded': '01-21\xa02010', 'seeds': '1', 'leechers': '0', 'id': '5295449', 'magnet': 'magnet:?xt=urn:btih:3da6a0fdc1d67a768cb32597e926abdf3e1a2fdd&dn=Dan+Bull+Collection&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969', 'size': ['236.78', 'MiB']}, {'uploaded': '09-02\xa02014', 'seeds': '1', 'leechers': '0', 'id': '10954408', 'magnet': 'magnet:?xt=urn:btih:5cd371a235317319db7da52c64422f9c2ac75d77&dn=Dan+Bull+-+The+Garden+%7B2014-Album%7D&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969', 'size': ['36.27', 'MiB']}, {'uploaded': '09-27\xa02009', 'seeds': '0', 'leechers': '1', 'id': '5101630', 'magnet': 'magnet:?xt=urn:btih:4e14dbd077c920875be4c15971b23b609ad6716a&dn=Dan+Bull+-+Dear+Lily+%5Ban+open+letter+to+Lily+Allen%5D+-+2009%5BMP3+%40&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969', 'size': ['5.51', 'MiB']}, {'uploaded': '11-29\xa02009', 'seeds': '0', 'leechers': '0', 'id': '5185893', 'magnet': 'magnet:?xt=urn:btih:5d9319cf852f7462422cb1bffc37b65174645047&dn=Dan+Bull+-+Dear+Mandy+%5Ban+open+letter+to+Lord+Mandelson%5D&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969', 'size': ['5.07', 'MiB']}, {'uploaded': '11-10\xa02011', 'seeds': '0', 'leechers': '0', 'id': '6806996', 'magnet': 'magnet:?xt=urn:btih:1c54af57426f53fdef4bbf1a9dbddf32f7b4988a&dn=Dan+Bull+-+Dear+Lily+%28Lily+Allen%29+%28Song+about+filesharing%29&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969', 'size': ['5.34', 'MiB']}, {'uploaded': '12-20\xa02011', 'seeds': '0', 'leechers': '0', 'id': '6901871', 'magnet': 'magnet:?xt=urn:btih:942c5bf3e1e9bc263939e13cea6ad7bd5f62aa36&dn=Dan+Bull+-+SOPA+Cabana.mp3&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969', 'size': ['4.8', 'MiB']}, {'uploaded': '12-21\xa02011', 'seeds': '0', 'leechers': '1', 'id': '6902247', 'magnet': 'magnet:?xt=urn:btih:d376f68a31b0db652234e790ed7256ac5e32db57&dn=Dan+Bull+-+SOPA+Cabana&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969', 'size': ['3.4', 'MiB']}, {'uploaded': '12-21\xa02011', 'seeds': '0', 'leechers': '1', 'id': '6903548', 'magnet': 'magnet:?xt=urn:btih:28163770a532eb24b9e0865878288a9bbdb7a5e6&dn=Dan+Bull+-+SOPA+Cabana+%5BWORKING%5D&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969', 'size': ['4.8', 'MiB']}, {'uploaded': '03-09\xa02012', 'seeds': '0', 'leechers': '1', 'id': '7088979', 'magnet': 'magnet:?xt=urn:btih:779ab0f13a3fbb12ba68b27721491e4d143f26eb&dn=Dan+Bull+-+Bye+Bye+BPI+2012++%5BMP3%40192%5D%28oan%29&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969', 'size': ['60.72', 'MiB']}, {'uploaded': '10-24\xa02012', 'seeds': '0', 'leechers': '0', 'id': '7756344', 'magnet': 'magnet:?xt=urn:btih:2667e4795bd5c868dedcabcb52943f4bb7212bab&dn=Dan+Bull+-+Dishonored+%5BExplicit+ver.%5D+%28Single+2012%29&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969', 'size': ['6.29', 'MiB']}, {'uploaded': '11-10\xa02012', 'seeds': '0', 'leechers': '0', 'id': '7812951', 'magnet': 'magnet:?xt=urn:btih:16364f83c556ad0fd3bb57a4a7c890e7e8087414&dn=Halo+4+EPIC+Rap+By+Dan+Bull&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969', 'size': ['6.41', 'MiB']}, {'uploaded': '01-19\xa02013', 'seeds': '0', 'leechers': '1', 'id': '8037899', 'magnet': 'magnet:?xt=urn:btih:843b466d9fd1f0bee3a476573b272dc2d6d0ebae&dn=Dan+Bull+-+Generation+Gaming+-+2013&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969', 'size': ['54.87', 'MiB']}] + expected = [ + {'uploaded': '04-04\xa02014', 'seeds': '16', 'leechers': '1', 'id': '9890864', 'magnet': 'magnet:?xt=urn:btih:30df4f8b42b8fd77f5e5aa34abbffe97f5e81fbf&dn=Dan+Croll+%26bull%3B+Sweet+Disarray+%5B2014%5D+320&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969', 'size': ['89.33', 'MiB']}, + {'uploaded': '03-02\xa02014', 'seeds': '4', 'leechers': '0', 'id': '9684858', 'magnet': 'magnet:?xt=urn:btih:7abd3eda600996b8e6fc9a61b83288e0c6ac0d83&dn=Dan+Bull+-+Massive+Collection&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969', 'size': ['294', 'MiB']}, + {'uploaded': '01-19\xa02013', 'seeds': '2', 'leechers': '0', 'id': '8037968', 'magnet': 'magnet:?xt=urn:btih:8f8d68fd0a51237c89692c428ed8a8f64a969c70&dn=Dan+Bull+-+Generation+Gaming+-+2013&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969', 'size': ['54.86', 'MiB']}, + {'uploaded': '01-21\xa02010', 'seeds': '1', 'leechers': '0', 'id': '5295449', 'magnet': 'magnet:?xt=urn:btih:3da6a0fdc1d67a768cb32597e926abdf3e1a2fdd&dn=Dan+Bull+Collection&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969', 'size': ['236.78', 'MiB']}, + {'uploaded': '09-02\xa02014', 'seeds': '1', 'leechers': '0', 'id': '10954408', 'magnet': 'magnet:?xt=urn:btih:5cd371a235317319db7da52c64422f9c2ac75d77&dn=Dan+Bull+-+The+Garden+%7B2014-Album%7D&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969', 'size': ['36.27', 'MiB']}, + {'uploaded': '09-27\xa02009', 'seeds': '0', 'leechers': '1', 'id': '5101630', 'magnet': 'magnet:?xt=urn:btih:4e14dbd077c920875be4c15971b23b609ad6716a&dn=Dan+Bull+-+Dear+Lily+%5Ban+open+letter+to+Lily+Allen%5D+-+2009%5BMP3+%40&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969', 'size': ['5.51', 'MiB']}, + {'uploaded': '11-29\xa02009', 'seeds': '0', 'leechers': '0', 'id': '5185893', 'magnet': 'magnet:?xt=urn:btih:5d9319cf852f7462422cb1bffc37b65174645047&dn=Dan+Bull+-+Dear+Mandy+%5Ban+open+letter+to+Lord+Mandelson%5D&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969', 'size': ['5.07', 'MiB']}, + {'uploaded': '11-10\xa02011', 'seeds': '0', 'leechers': '0', 'id': '6806996', 'magnet': 'magnet:?xt=urn:btih:1c54af57426f53fdef4bbf1a9dbddf32f7b4988a&dn=Dan+Bull+-+Dear+Lily+%28Lily+Allen%29+%28Song+about+filesharing%29&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969', 'size': ['5.34', 'MiB']}, + {'uploaded': '12-20\xa02011', 'seeds': '0', 'leechers': '0', 'id': '6901871', 'magnet': 'magnet:?xt=urn:btih:942c5bf3e1e9bc263939e13cea6ad7bd5f62aa36&dn=Dan+Bull+-+SOPA+Cabana.mp3&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969', 'size': ['4.8', 'MiB']}, + {'uploaded': '12-21\xa02011', 'seeds': '0', 'leechers': '1', 'id': '6902247', 'magnet': 'magnet:?xt=urn:btih:d376f68a31b0db652234e790ed7256ac5e32db57&dn=Dan+Bull+-+SOPA+Cabana&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969', 'size': ['3.4', 'MiB']}, + {'uploaded': '12-21\xa02011', 'seeds': '0', 'leechers': '1', 'id': '6903548', 'magnet': 'magnet:?xt=urn:btih:28163770a532eb24b9e0865878288a9bbdb7a5e6&dn=Dan+Bull+-+SOPA+Cabana+%5BWORKING%5D&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969', 'size': ['4.8', 'MiB']}, + {'uploaded': '03-09\xa02012', 'seeds': '0', 'leechers': '1', 'id': '7088979', 'magnet': 'magnet:?xt=urn:btih:779ab0f13a3fbb12ba68b27721491e4d143f26eb&dn=Dan+Bull+-+Bye+Bye+BPI+2012++%5BMP3%40192%5D%28oan%29&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969', 'size': ['60.72', 'MiB']}, + {'uploaded': '10-24\xa02012', 'seeds': '0', 'leechers': '0', 'id': '7756344', 'magnet': 'magnet:?xt=urn:btih:2667e4795bd5c868dedcabcb52943f4bb7212bab&dn=Dan+Bull+-+Dishonored+%5BExplicit+ver.%5D+%28Single+2012%29&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969', 'size': ['6.29', 'MiB']}, + {'uploaded': '11-10\xa02012', 'seeds': '0', 'leechers': '0', 'id': '7812951', 'magnet': 'magnet:?xt=urn:btih:16364f83c556ad0fd3bb57a4a7c890e7e8087414&dn=Halo+4+EPIC+Rap+By+Dan+Bull&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969', 'size': ['6.41', 'MiB']}, + {'uploaded': '01-19\xa02013', 'seeds': '0', 'leechers': '1', 'id': '8037899', 'magnet': 'magnet:?xt=urn:btih:843b466d9fd1f0bee3a476573b272dc2d6d0ebae&dn=Dan+Bull+-+Generation+Gaming+-+2013&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969', 'size': ['54.87', 'MiB']} + ] self.assertEqual(actual, expected) + def test_parse_category(self): + category = pirate.torrent.parse_category('Audio') + self.assertEqual(100, category) + category = pirate.torrent.parse_category('Video') + self.assertEqual(200, category) + category = pirate.torrent.parse_category('100') + self.assertEqual(100, category) + category = pirate.torrent.parse_category('asdf') + self.assertEqual(0, category) + category = pirate.torrent.parse_category('9001') + self.assertEqual(0, category) + + def test_parse_sort(self): + sort = pirate.torrent.parse_sort('SeedersDsc') + self.assertEqual(7, sort) + sort = pirate.torrent.parse_sort('7') + self.assertEqual(7, sort) + sort = pirate.torrent.parse_sort('asdf') + self.assertEqual(99, sort) + sort = pirate.torrent.parse_sort('7000') + self.assertEqual(99, sort) + + def test_request_path(self): + # the args are (page, category, sort, mode, terms) + tests = [ + ((0, 100, 10, 'browse', []), '/browse/100/0/10'), + ((0, 0, 10, 'browse', []), '/browse/100/0/10'), + ((0, 0, 10, 'recent', []), '/top/48hall'), + ((0, 100, 10, 'recent', []), '/top/48h100'), + ((0, 100, 10, 'top', []), '/top/100'), + ((0, 0, 10, 'top', []), '/top/all'), + ((0, 100, 10, 'search', ['abc']), '/search/abc/0/10/100'), + ((0, 100, 10, 'search', ['abc', 'def']), '/search/abc+def/0/10/100'), + ((0, 100, 10, 'search', [u'\u1234']), '/search/%E1%88%B4/0/10/100'), + ((0, 100, 10, 'asdf', []), Exception), + ] + for test in tests: + if test[1] != Exception: + path = pirate.torrent.build_request_path(*test[0]) + self.assertEqual(test[1], path) + else: + with self.assertRaises(test[1]): + pirate.torrent.build_request_path(test[0]) + + @patch('pirate.torrent.get_torrent') + def test_save_torrents(self, get_torrent): + with patch('pirate.torrent.open', mock.mock_open(), create=True) as open_: + magnet = 'magnet:?xt=urn:btih:335fcd3cfbecc85554616d73de888033c6c16d37&dn=Test+Drive+Unlimited+%5BPC+Version%5D&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969' + pirate.torrent.save_torrents([0], [{'magnet':magnet}], 'path') + get_torrent.assert_called_once_with(293294978876299923284263767676068334936407502135) + open_.assert_called_once_with('path/Test Drive Unlimited [PC Version].torrent', 'wb') + + @patch('pirate.torrent.get_torrent', side_effect=urllib.error.HTTPError('', '', '', '', io.StringIO())) + def test_save_torrents_fail(self, get_torrent): + magnet = 'magnet:?xt=urn:btih:335fcd3cfbecc85554616d73de888033c6c16d37&dn=Test+Drive+Unlimited+%5BPC+Version%5D&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969' + pirate.torrent.save_torrents([0], [{'magnet':magnet}], 'path') + + def test_save_magnets(self): + with patch('pirate.torrent.open', mock.mock_open(), create=True) as open_: + magnet = 'magnet:?xt=urn:btih:335fcd3cfbecc85554616d73de888033c6c16d37&dn=Test+Drive+Unlimited+%5BPC+Version%5D&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969' + pirate.torrent.save_magnets([0], [{'magnet':magnet}], 'path') + open_.assert_called_once_with('path/Test Drive Unlimited [PC Version].magnet', 'w') + + def test_get_torrent(self): + with patch('urllib.request.urlopen') as urlopen: + class MockResponse(): + add_header = mock.MagicMock() + response = MockResponse() + with patch('urllib.request.Request', return_value=response) as request: + pirate.torrent.get_torrent(100000000000000) + request.assert_called_once_with('http://torcache.net/torrent/5AF3107A4000.torrent', headers=pirate.data.default_headers) + urlopen.assert_called_once_with(response, timeout=pirate.data.default_timeout) + if __name__ == '__main__': unittest.main()