├── .gitignore ├── KickFlix.py ├── LICENSE ├── README.md └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | venv/ 2 | __pycache__/ 3 | API/__pycache__/ 4 | -------------------------------------------------------------------------------- /KickFlix.py: -------------------------------------------------------------------------------- 1 | import os 2 | import time 3 | import json 4 | import requests 5 | from argparse import ArgumentParser 6 | 7 | class KickFlix(): 8 | 9 | def __init__(self): 10 | 11 | print(""" 12 | 13 | 14 | ██╗░░██╗██╗░█████╗░██╗░░██╗███████╗██╗░░░░░██╗██╗░░██╗ 15 | ██║░██╔╝██║██╔══██╗██║░██╔╝██╔════╝██║░░░░░██║╚██╗██╔╝ 16 | █████═╝░██║██║░░╚═╝█████═╝░█████╗░░██║░░░░░██║░╚███╔╝░ 17 | ██╔═██╗░██║██║░░██╗██╔═██╗░██╔══╝░░██║░░░░░██║░██╔██╗░ 18 | ██║░╚██╗██║╚█████╔╝██║░╚██╗██║░░░░░███████╗██║██╔╝╚██╗ 19 | ╚═╝░░╚═╝╚═╝░╚════╝░╚═╝░░╚═╝╚═╝░░░░░╚══════╝╚═╝╚═╝░░╚═╝ 20 | Minimal command line based torrent streaming client 21 | """) 22 | parser = ArgumentParser(description='KickFlix - Minimal torrent player') 23 | parser.add_argument('-s', '--stream', type=str, help='Stream a torrent') 24 | parser.add_argument('-d', '--download', help='Download a torrent') 25 | parser.add_argument('-m', '--magnet', help='Get the magnet link of a torrent') 26 | self.args = parser.parse_args() 27 | 28 | self.API_SEARCH = "https://kickass-api-unofficial.herokuapp.com/search?torrent=" 29 | self.API_MAGNET = "https://kickass-api-unofficial.herokuapp.com/magnet?page_url=" 30 | 31 | def run(self): 32 | """ Run the program """ 33 | 34 | if self.args.stream: 35 | search_results = self.search_kickass(self.args.stream) 36 | magnet = self.get_magnet(search_results["1"]['page_url']) 37 | print("\nNow streaming:\n",search_results["1"]['title']) 38 | time.sleep(0.7) 39 | self.stream(magnet) 40 | exit() 41 | 42 | elif self.args.download: 43 | search_results = self.search_kickass(self.args.download) 44 | magnet = self.get_magnet(search_results["1"]['page_url']) 45 | print("\nDownloading: \n",search_results["1"]['title']) 46 | time.sleep(0.7) 47 | self.download(magnet) 48 | exit() 49 | 50 | elif self.args.magnet: 51 | search_results = self.search_kickass(self.args.magnet) 52 | magnet = self.get_magnet(search_results["1"]['page_url']) 53 | print("\nMagnet for : ",str(search_results["1"]['title'])+ "\n") 54 | print(magnet) 55 | exit() 56 | 57 | else: 58 | query = input('What do you want to search for (q) to quit: ').strip() 59 | if query.lower() == "q": 60 | exit() 61 | else: 62 | results = self.search_kickass(query) 63 | 64 | for count in results.keys(): 65 | print(f"{count}. {results[count]['title']}\n") 66 | 67 | 68 | while True: 69 | try: 70 | user_input = input('\nSelect a torrent(s/d/m) (q) to quit (r) to re-search: ').strip() 71 | if user_input.lower() == "q": 72 | exit() 73 | elif user_input.lower() == "r": 74 | print("\n-----------------#####-----------------\n") 75 | self.run() 76 | elif " " not in user_input and len(user_input)<=3: 77 | if len(user_input) == 2: 78 | index = user_input[0] 79 | mode = user_input[1] 80 | else: 81 | index = user_input[0:2] 82 | mode = user_input[-1] 83 | magnet = self.get_magnet(results[index]['page_url']) 84 | 85 | if mode == "s": 86 | print("\nNow streaming: ",results[index]['title']) 87 | time.sleep(0.7) 88 | self.stream(magnet) 89 | elif mode == "d": 90 | print("\nDownloading: ",results[index]['title']) 91 | time.sleep(0.7) 92 | self.download(magnet) 93 | 94 | elif mode == "m": 95 | print("\nMagnet for : ",str(results[index]['title'])+ "\n") 96 | print(magnet) 97 | 98 | print("\n-----------------#####-----------------\n") 99 | self.run() 100 | elif len(user_input) > 2: 101 | raise ValueError 102 | 103 | except (IndexError,ValueError): 104 | print(""" 105 | ***************************************************** 106 | Please retry entering mode with torrent selection 107 | example: \"1s\" to stream first torrent 108 | or \"1d\" to download first torrent 109 | *****************************************************""") 110 | 111 | 112 | 113 | def get_magnet(self,page_url) -> str: 114 | """ Get magnet link of selected torrent """ 115 | resp = requests.get(self.API_MAGNET + page_url) 116 | resp.close() 117 | magnet = json.loads(resp.text) 118 | 119 | return (magnet['magnet']) 120 | 121 | 122 | def download(self,magnet): 123 | """ Download a torrent """ 124 | 125 | os.system('webtorrent ' + magnet) 126 | 127 | def stream(self,magnet): 128 | """ Stream a torrent """ 129 | 130 | os.system('webtorrent ' + f"\"{magnet}\"" + ' --vlc') 131 | 132 | def search_kickass(self,query) -> dict: 133 | """ Search for torrents """ 134 | 135 | print(f"Searching for \"{query}\"") 136 | 137 | resp = requests.get(self.API_SEARCH + query) 138 | resp.close() 139 | search_result = json.loads(resp.text) 140 | 141 | if search_result == {}: 142 | print("0 search results\n") 143 | print("\n-----------------#####-----------------\n") 144 | if self.args.stream == None and self.args.download == None: 145 | self.run() 146 | exit() 147 | print(str(len(search_result)) + " search results found\n") 148 | time.sleep(0.7) 149 | 150 | return search_result 151 | 152 | def main(): 153 | """ API check """ 154 | 155 | print("Checking API status...") 156 | 157 | if requests.get("https://kickass-api-unofficial.herokuapp.com/").status_code == 200: 158 | print("API is up and running :D") 159 | kickflix = KickFlix() 160 | kickflix.run() 161 | else: 162 | print("API is currently down :(") 163 | print("report issues at github.com/janardonh/KickFlix") 164 | 165 | main() 166 | 167 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Jonardon Hazarika 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ABOUT 2 | 3 | A command-line based, minimal torrent streaming client made using Python and Webtorrent-cli. 4 | 5 | ## This module doesn't work as of now because KickAss Torrents changed the structure of their webpages. Need help porting it over to 1337x.to 6 | 7 | 8 | ## Installation 9 | 10 | ```bash 11 | pip install -r requirements.txt 12 | ``` 13 | 14 | It uses webtorrent-cli to stream/download torrents (necessary) 15 | 16 | Download Nodejs from [here](https://nodejs.org/en/download/), install the package and then run this command in terminal 17 | ```bash 18 | npm install webtorrent-cli -g 19 | ``` 20 | 21 | ALso, if you want to stream torrents you'll need VLC Media Player (maybe the reason why you're using this script) (optional, downloaing will work without VLC) 22 | 23 | Download VLC from [here](https://www.videolan.org/) 24 | 25 | ## Usage 26 | 27 | To stream a torrent directly from command line (streams the torrent at top in search results) 28 | ```python 29 | python3 KickFlix.py -s "torrent" 30 | ``` 31 | Downloading a torrent from command line (downloads the torrent at top in search results) 32 | ```python 33 | python3 KickFlix.py -d "torrent" 34 | ``` 35 | To get the magnet of a torrent from command line (prints out the magnet of the torrent at top in search results) 36 | ```python 37 | python3 KickFlix.py -m "torrent" 38 | ``` 39 | Using the script to search torrents and then to stream/download selected torrent 40 | ```python 41 | python3 KickFlix.py 42 | ``` 43 | A video on how to use the script is [here](https://www.youtube.com/watch?v=Gh0XqfvKtcE) 44 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | beautifulsoup4==4.9.3 2 | bs4==0.0.1 3 | certifi==2021.5.30 4 | charset-normalizer==2.0.4 5 | idna==3.2 6 | requests==2.26.0 7 | soupsieve==2.2.1 8 | urllib3==1.26.6 9 | --------------------------------------------------------------------------------