kickass.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. ## Kickass Torrent (Videos, Music, Files)
  2. #
  3. # @website https://kickass.so
  4. # @provide-api no (nothing found)
  5. #
  6. # @using-api no
  7. # @results HTML (using search portal)
  8. # @stable yes (HTML can change)
  9. # @parse url, title, content, seed, leech, magnetlink
  10. from urlparse import urljoin
  11. from cgi import escape
  12. from urllib import quote
  13. from lxml import html
  14. from operator import itemgetter
  15. # engine dependent config
  16. categories = ['videos', 'music', 'files']
  17. paging = True
  18. # search-url
  19. url = 'https://kickass.so/'
  20. search_url = url + 'search/{search_term}/{pageno}/'
  21. # specific xpath variables
  22. magnet_xpath = './/a[@title="Torrent magnet link"]'
  23. torrent_xpath = './/a[@title="Download torrent file"]'
  24. content_xpath = './/span[@class="font11px lightgrey block"]'
  25. # do search-request
  26. def request(query, params):
  27. params['url'] = search_url.format(search_term=quote(query),
  28. pageno=params['pageno'])
  29. # FIX: SSLError: hostname 'kickass.so'
  30. # doesn't match either of '*.kickass.to', 'kickass.to'
  31. params['verify'] = False
  32. return params
  33. # get response from search-request
  34. def response(resp):
  35. results = []
  36. dom = html.fromstring(resp.text)
  37. search_res = dom.xpath('//table[@class="data"]//tr')
  38. # return empty array if nothing is found
  39. if not search_res:
  40. return []
  41. # parse results
  42. for result in search_res[1:]:
  43. link = result.xpath('.//a[@class="cellMainLink"]')[0]
  44. href = urljoin(url, link.attrib['href'])
  45. title = ' '.join(link.xpath('.//text()'))
  46. content = escape(html.tostring(result.xpath(content_xpath)[0],
  47. method="text"))
  48. seed = result.xpath('.//td[contains(@class, "green")]/text()')[0]
  49. leech = result.xpath('.//td[contains(@class, "red")]/text()')[0]
  50. filesize = result.xpath('.//td[contains(@class, "nobr")]/text()')[0]
  51. filesize_multiplier = result.xpath('.//td[contains(@class, "nobr")]//span/text()')[0]
  52. files = result.xpath('.//td[contains(@class, "center")][2]/text()')[0]
  53. # convert seed to int if possible
  54. if seed.isdigit():
  55. seed = int(seed)
  56. else:
  57. seed = 0
  58. # convert leech to int if possible
  59. if leech.isdigit():
  60. leech = int(leech)
  61. else:
  62. leech = 0
  63. # convert filesize to byte if possible
  64. try:
  65. filesize = float(filesize)
  66. # convert filesize to byte
  67. if filesize_multiplier == 'TB':
  68. filesize = int(filesize * 1024 * 1024 * 1024 * 1024)
  69. elif filesize_multiplier == 'GB':
  70. filesize = int(filesize * 1024 * 1024 * 1024)
  71. elif filesize_multiplier == 'MB':
  72. filesize = int(filesize * 1024 * 1024)
  73. elif filesize_multiplier == 'kb':
  74. filesize = int(filesize * 1024)
  75. except:
  76. filesize = None
  77. # convert files to int if possible
  78. if files.isdigit():
  79. files = int(files)
  80. else:
  81. files = None
  82. magnetlink = result.xpath(magnet_xpath)[0].attrib['href']
  83. torrentfile = result.xpath(torrent_xpath)[0].attrib['href']
  84. # append result
  85. results.append({'url': href,
  86. 'title': title,
  87. 'content': content,
  88. 'seed': seed,
  89. 'leech': leech,
  90. 'filesize': filesize,
  91. 'files': files,
  92. 'magnetlink': magnetlink,
  93. 'torrentfile': torrentfile,
  94. 'template': 'torrent.html'})
  95. # return results sorted by seeder
  96. return sorted(results, key=itemgetter('seed'), reverse=True)