def __init__(self, url=None): """Create a new client instance. The url argument can be a TransmissionURL object or dict with any combination of the following keys: host, port, path, username, password, ssl """ if url is None: url = TransmissionURL() Transmission.__init__(self, **url) self._cache = {} self._cache["session"] = TransmissionRPC("session", setter=self.session) self._cache["torrents"] = {}
def readEdge(self): msg = self.DownStream.recv() if msg is None: self.DownStream.close() self.DownStream = None else: t = Transmission.from_bytes(msg) self.Node.routeTransmission(t, False)
def send(self, payload, to=Transmission.BROADCAST, flags=None): if flags is None: flags = Link.flags() # defaults t = Transmission(self.Index, to, payload, flags) tid = t.TID self.Seen.set(tid, (False, True, False)) self.UpLink.send(t) if t.send_diagonal: self.Seen.set(tid, (False, True, True)) self.DiagonalLink.send(t)
def receiveEdgeTransmission(self): self.DownStream.readMore(1024*1024, 10.0) while self.DownStream.msgReady(): msg = self.DownStream.getMsg() t = Transmission.from_bytes(msg) self.Node.routeTransmission(t, False) if self.DownStream.EOF: self.DownStream.close() self.DownStream = None
def add_torrent_to_queue(torrent_name): torrent_file = f"{os.getcwd()}/downloads/torrent_files/{torrent_name}" connection = create_connection() cursor = connection.cursor() client = Transmission() transmission_hash = client( "torrent-add", filename=torrent_file)["torrent-added"]["hashString"] cursor.execute( f"UPDATE torrents SET transmission_hash = '{transmission_hash}' WHERE name = \"{torrent_name}\"" ) connection.commit() cursor.close() connection.close()
def main(wf): ''' main to check args and call ''' tr = Transmission(wf) if wf.args[0] == '--register' and len(wf.args) > 1: registerTransmission(wf, tr) elif wf.args[0] == '--reset': tr.resetConfig() elif wf.args[0] == '--copy' and len(wf.args) > 1: print(wf.args[1], end='') notify(title='Link copied in your clipboard') elif wf.args[0] == '--open' and len(wf.args) > 1: if tr.connection(): tr.addTorrent(wf.args[1]) else: nyaa(wf)
def _connect_if_necessary() -> None: global client if not client: log.info("Connecting to transmission daemon") client = Transmission(**config.get_torrent_client_config(), timeout=60)
def flags(**args): return Transmission.flags(**args)
def main(): parser = OptionParser() parser.add_option("-c", "--config", dest="configfile", help="config file", default="%s/.anime_fetcher.conf" % os.environ['HOME']) parser.add_option("-n", "--name", dest="name", help="Short name of anime to fetch") parser.add_option("-a", "--all", dest="all", help="Fetch all configured animes", action="store_true", default=False) parser.add_option("-t", "--test", dest="test", help="only fetch, don't write anything", action="store_true", default=False) (options, args) = parser.parse_args() get_all = False name = "" if not options.configfile: print('Give me config file!') sys.exit(1) if not os.path.exists(options.configfile): print('File %s does not exists' % options.configfile) if options.all: get_all = True elif options.name: name = options.name.strip().lower() else: print("Either --name or --all needed!") sys.exit(1) try: configfile = os.path.abspath(options.configfile) f = open(configfile,'r') configcont = f.read() f.close() except IOError as e: print('Can\'t open file %s, error %s' % (options.configfile, e)) sys.exit(1) config = ConfigParser.RawConfigParser() config.readfp(io.BytesIO(configcont)) tc = None if 'transmission' in config.sections(): port = None host = None try: port = config.get('transmission', 'port') except ConfigParser.NoOptionError: pass try: host = config.get('transmission', 'host') except ConfigParser.NoOptionError: pass tc = Transmission(host=host, port=port) if get_all: animes = config.sections() if 'transmission' in animes: animes.pop(animes.index('transmission')) else: animes = [name] if name not in config.sections(): print("Anime named %s not found from config" % name) sys.exit(1) for anime in animes: seed_ratio = None destination = None try: search_term = config.get(anime,'search') except ConfigParser.NoOptionError: print('Search for anime %s not given in config!' % anime) sys.exit(1) try: seed_ratio = config.get(anime, 'seed_ratio') except ConfigParser.NoOptionError: pass try: destination = config.get(anime, 'destination') except ConfigParser.NoOptionError: #print('No destination set for %s' % anime) pass numfile = ''.join(ch for ch in anime if ch.isalnum() or ch in '_-').lower() numfile = os.path.join(os.environ['HOME'], '.%s_episode' % numfile) try: f = open(numfile, 'r') except IOError as e: if e.errno == 2: print('Create file %s and add latest episode number to it' % numfile, file=sys.stderr) sys.exit(1) else: print('Error: %s' % e, file=sys.stderr) sys.exit(1) num = f.readline() f.close() try: num = int(num) except: print('File %s does not contain number' % numfile, file=sys.stderr) sys.exit(1) a = Parser(search_term % {'num' : num}) a.strict() a.deduplicate() a.print_url() if len(a.objects) > 0 and not options.test: f = open(numfile, 'w+') num = str(num + 1) f.write(num) f.close() if tc: try: tc.add_torrent(a.get_url(), seed_ratio=seed_ratio, destination=destination) except TransmissionError as e: print("Cannot add torrent, %s" % str(e))
transmission_rpc_port = int(Config.get("transmission", "rpc-port")) transmission_redirect_url = Config.get("transmission", "redirect-url") transmission_rpc_username = Config.get("transmission", "username") transmission_rpc_password = Config.get("transmission", "password") #Initiaze various search engines haruhichan_scraper = haruhichanScraper.haruhichanScraper() ixirc_scraper = ixircScraper.ixircScraper() daddicts_scraper = daddictsScraper.DAddictsScraper() shanaproject_scraper = shanaprojectScraper.ShanaProjectScraper() crunchyroll = MetaApi() gooddrama_scraper = gooddramaScraper.GoodDramaScraper() animeseason_scraper = animeseasonScraper.AnimeSeasonScraper() tpb = TPB('https://thepiratebay.org') transmission_client = Transmission(host=transmission_rpc_host, port=transmission_rpc_port, username=transmission_rpc_username, password=transmission_rpc_password) xdccPool = [] #---------------------------------------- # controllers #---------------------------------------- @app.route("/") def index(): return render_template('index.html') @app.route("/search", methods=['GET']) def search():
def callback(self, buffer): transmission = Transmission.parse(buffer) if transmission: self.transmission_subject.on_next(transmission)
class Car: engine = Engine() # подключаем двигатель transmission = Transmission() # подключаем КП wheels = Wheels() # подключаем колёса def __init__(self): self.path = 0 self.power = False self.gasoline = 0.0 self.oil = 0.0 self.speed = 0.0 self.__time_start = 0 def __repr__(self): self.transforms() return "Данные автомобиля и поездки:\n" \ "\tзапущен = %s\n" \ "\tуровень топлива = %s л.\n" \ "\tуровень масла = %s %%\n" \ "\tскорость = %s км/ч\n" \ "\tпройденый путь = %s км" % (self.power, self.gasoline, self.oil, self.speed, self.path) def transforms(self): # соединение классов, получение данных для вывода self.engine.time = self.power * (time.time() - self.__time_start) self.transmission.turns_engine = self.engine.turns_engine() self.wheels.turns_wheels = self.transmission.clutch_pedal() self.power = self.engine.power self.gasoline = self.engine.gasoline self.oil = self.transmission.oil * 100 self.get_speed() self.path = self.wheels.transform_path() def turn_on(self): # включить двигатель, начинаем отсчёт времени try: self.engine.start_engine() except Exception as e: print("Авто не поедет, пока есть проблемы:\n %s" % e) else: self.__time_start = time.time() print("Вжжжжжжжж-чух-чух-чух-чух") def turn_off(self): # выключить двигатель self.engine.stop_engine() print("Двигатель выключен") def add_gasoline(self, litres): # добавить топлива self.engine.add_gasoline(litres) print("Машина заправлена. Всего в баке %s литров бензина" % self.engine.gasoline) def add_oil(self): # восстановить масло self.transmission.add_oil() print("Ты зашёл на ближайшую СТО и поменял масло. Какой молодец ^_^ ") def change_speed(self, gas=engine.gas, gear=transmission.gear): # изменить скорость self.transmission.gear = gear self.engine.gas = gas print( "Теперь ты едешь на %s передаче и нажал газ на %s градусов. Какой молодец ^_^ " % (self.transmission.gear, self.engine.gas)) def get_speed(self): # расчитать скорость try: self.speed = self.engine.rpm * self.transmission.gear * self.wheels.wheel * 60 except Exception: self.speed = 0 return self.speed
def __init__(self, client_config: Dict[str, Any]) -> None: self.name = client_config["name"] del client_config["name"] self.address = f"{client_config['host']}:{client_config['port']}" self.client = Transmission(**client_config) self.connected = False
class TransmissionClient(object): def __init__(self, client_config: Dict[str, Any]) -> None: self.name = client_config["name"] del client_config["name"] self.address = f"{client_config['host']}:{client_config['port']}" self.client = Transmission(**client_config) self.connected = False def __repr__(self) -> str: return f"Transmission({self.name} [{self.address}])" def connect_if_necessary(self) -> None: if not self.connected: log.info( f"Connecting to transmission daemon {self.name} at {self.address}" ) version = self.client.call("session-get", fields=["version"]).get("version") log.debug( f"{self.name} connected. Transmission version: {version}") self.connected = True def _create_empty_tracker_point(self, time: str, tracker: str) -> Dict[str, Any]: return { "measurement": "trackers", "time": time, "tags": { "client_name": self.name, "tracker": tracker }, "fields": { "downloaded": 0, "uploaded": 0, "download_speed": 0, "upload_speed": 0, "connected_peers": 0, "seeding": 0, "downloading": 0, "stopped": 0, "errored": 0, }, } def _get_client_stats_point(self, time: str) -> Dict[str, Any]: session = self.client.call("session-get", fields=["download-dir", "version"]) version = session.get("version") free_space = self.client.call( "free-space", path=session.get("download-dir")).get("size-bytes") stats = self.client.call("session-stats") return { "measurement": "stats", "time": time, "tags": { "client_name": self.name, "version": version }, "fields": { "free_space": free_space, "downloaded": stats.get("cumulative-stats").get("downloadedBytes"), "uploaded": stats.get("cumulative-stats").get("uploadedBytes"), "torrents": stats.get("torrentCount"), "download_speed": stats.get("downloadSpeed"), "upload_speed": stats.get("uploadSpeed"), # These counts are iterated when going through torrents below "seeding": 0, "downloading": 0, "errored": 0, "stopped": 0, "connected_peers": 0, }, } def _get_historical_tracker_stats(self) -> Dict[str, Any]: tracker_stat_data = influxdb.get_kvp(TRACKER_STAT_STORAGE_KEY) if not tracker_stat_data: tracker_stat_data = "{}" historical_tracker_stats = json.loads(tracker_stat_data) if self.name not in historical_tracker_stats: historical_tracker_stats[self.name] = {} return historical_tracker_stats def get_data_points(self, time: Optional[str] = None) -> List[Dict[str, Any]]: # TODO: Break this function up so it's not an ugly monolith self.connect_if_necessary() if time is None: time = utils.now() stats_point = self._get_client_stats_point(time) torrents = self.client.call( "torrent-get", fields=[ "addedDate", "downloadedEver", "error", "hashString", "name", "peersConnected", "percentDone", "rateDownload", "rateUpload", "status", "trackers", "uploadedEver", ], ).get("torrents") historical_tracker_stats = self._get_historical_tracker_stats() tracker_points = {} points = [] for torrent in torrents: tracker = "" # Only keep track of first tracker in any given torrent to not complicate tags match = url_domain_regex.match( torrent.get("trackers")[0].get("announce")) if match: tracker = match.group(3) else: log.error( f"Torrent {torrent.get('name')} could not parse tracker. Not recording this data point" ) continue if tracker not in tracker_points: tracker_points[tracker] = self._create_empty_tracker_point( time, tracker) # Append stats for these torrents to their relevant tracker/client points if tracker not in historical_tracker_stats[self.name]: historical_tracker_stats[self.name][tracker] = {} historical_tracker_stats[self.name][tracker][get_unique_torrent_id( torrent.get("hashString"), torrent.get("addedDate"))] = { "downloaded": torrent.get("downloadedEver"), "uploaded": torrent.get("uploadedEver"), } status = get_status(torrent.get("status")) if status == "downloading": stats_point["fields"]["downloading"] += 1 tracker_points[tracker]["fields"]["downloading"] += 1 elif status == "seeding": stats_point["fields"]["seeding"] += 1 tracker_points[tracker]["fields"]["seeding"] += 1 elif status == "stopped": stats_point["fields"]["stopped"] += 1 tracker_points[tracker]["fields"]["stopped"] += 1 if torrent.get("error") != 0: stats_point["fields"]["errored"] += 1 tracker_points[tracker]["fields"]["errored"] += 1 tracker_points[tracker]["fields"]["download_speed"] += torrent.get( "rateDownload") tracker_points[tracker]["fields"]["upload_speed"] += torrent.get( "rateUpload") tracker_points[tracker]["fields"][ "connected_peers"] += torrent.get("peersConnected") stats_point["fields"]["connected_peers"] += torrent.get( "peersConnected") # Create point for this individual torrent points.append({ "measurement": "torrents", "time": time, "tags": { "client_name": self.name, "infohash": torrent.get("hashString"), "torrent_name": torrent.get("name"), "tracker": tracker, "error": str(torrent.get("error")), "status": status, }, "fields": { "downloaded": torrent.get("downloadedEver"), "uploaded": torrent.get("uploadedEver"), "download_speed": torrent.get("rateDownload"), "upload_speed": torrent.get("rateUpload"), "connected_peers": torrent.get("peersConnected"), "percent_done": float(torrent.get("percentDone")), }, }) influxdb.write_kvp(TRACKER_STAT_STORAGE_KEY, json.dumps(historical_tracker_stats)) for tracker, tracker_torrent_stats in historical_tracker_stats[ self.name].items(): for _, values in tracker_torrent_stats.items(): if tracker not in tracker_points: tracker_points[tracker] = self._create_empty_tracker_point( time, tracker) tracker_points[tracker]["fields"]["downloaded"] += values[ "downloaded"] tracker_points[tracker]["fields"]["uploaded"] += values[ "uploaded"] points.append(tracker_points[tracker]) points.append(stats_point) return points
#!/usr/bin/python import config from trakttv import TraktTV import torrentsearch from pushover import Pushover from transmission import Transmission from datetime import datetime try: trakt = TraktTV(config.CLIENT_ID, config.CLIENT_SECRET) trakt.login() calendar = trakt.calendar(1) transmission = Transmission(config.TRANSMISSION, config.TRANSMISSION_USER, config.TRANSMISSION_PWD) for item in calendar: id = item['show']['ids']['trakt'] season = ('0' + str(item['episode']['season']))[-2:] number = ('0' + str(item['episode']['number']))[-2:] lastCollectedEpisode = trakt.collectionProgress(id)['last_episode'] collected = (lastCollectedEpisode['season'] == int(season) and lastCollectedEpisode['number'] == int(number)) if (collected == False): searchStr = '{title} S{season}E{episode}'.format( title=item['show']['title'], season=season, episode=number) torrents = torrentsearch.search(searchStr + ' 720p') if (len(torrents) > 0 and transmission.addTorrent(torrents[0]['magnet'])): info = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# Get filed to seeds/apollo or seeds/waffles # Also copied to to_process (for headphones?) # # Ru torrents are seeded to 1:1 and then removed + delete files # # Public torrents are removed and left in downloads/complete/torrents # from transmission import Transmission import shutil import os # # Connect and retrieve torrents # client = Transmission(host='localhost',username='******',password='******') response = client('torrent-get',fields=['id','name','percentDone','seedRatioMode','uploadRatio','downloadDir','trackers']) doneTorrents = 0; moveTorrents = 0; removeTorrents = 0; ruDeleted = 0; ruSeeding = 0; totalTorrents = len(response['torrents']) loop = 0; print "Connecting to Transmission to check torrents..." while (loop < totalTorrents): currentTorrent = response['torrents'][loop];
def main(argv): optional_args = '[-y <year>] [-d] [--allow-chronologies] [--high-quality] [-s <season>] [-e <episode>] [--debug]' try: opts, args = getopt.getopt(argv, "hdn:y:s:e:", [ "name=", "year=", "download", "allow-chronologies", "high-quality", "season=", "episode=", "debug" ]) except getopt.GetoptError: print "find_torrents.py -n '<name of movie>' " + optional_args sys.exit(2) year = '' download = False chronologies = False high_quality = False season = None episode = None debug = False for opt, arg in opts: if opt == '-h': print "find_torrents.py -n '<name of movie>' " + optional_args sys.exit() elif opt in ("-n", "--name"): name = arg elif opt in ("-d", "--download"): download = True elif opt in ("-y", "--year"): year = arg elif opt == '--allow-chronologies': chronologies = True elif opt == '--high-quality': high_quality = True elif opt in ("-s", "--season"): season = '{:02d}'.format(int(arg)) season = int(arg) elif opt in ("-e", "--episode"): episode = '{:02d}'.format(int(arg)) episode = int(arg) elif opt == '--debug': debug = True if season or episode: video_type = 'television' else: video_type = 'movie' logger = logging.getLogger(__name__) handler = logging.FileHandler('find_torrent.log') handler.setLevel(logging.DEBUG) formatter = logging.Formatter( '%(asctime)s %(name)-12s %(levelname)-8s %(message)s') handler.setFormatter(formatter) logger.addHandler(handler) if debug: logger.setLevel(logging.DEBUG) else: logger.setLevel(logging.INFO) logger.debug("arguments: %s" % ' '.join(argv)) transmission = Transmission() transmission_creds = transmission.user + ':' + transmission.password tmdb = TMDB() tmdb_url = 'https://api.themoviedb.org/3/search/movie' title_variations = [] # logger.debug("name.split() = %s" % name.split()) for delimiter in [' ', '.', '-', '_']: variation = delimiter.join(name.split()) logger.debug(variation) title_variations.append(variation) query = re.sub(r'[\s-]', '+', name) if year: logger.debug("year: %s" % year) if video_type == 'movie': if year == '': logger.debug('searching for year on tmdb') r = requests.get(tmdb_url + '?api_key=' + tmdb.key + '&query=' + name) tmdb_results = r.json() logger.debug("len(tmdb_results): %s" % len(tmdb_results)) for result in tmdb_results['results']: logger.debug(result) if result['title'] == name: logger.debug("result['title']: %s" % result['title']) m = re.match(r'(\d{4})-\d{2}-\d{2}', result['release_date']) year = m.group(1) logger.info( "this film appears to have been released in %s" % year) break query = "%s+%s" % (query, year) if year: logger.debug("year: %s" % year) elif video_type == 'television': if season: if episode: catalog = "S%sE%s" % ('{:02d}'.format(season), '{:02d}'.format(episode)) else: catalog = "Season+%s" % str(season) logger.debug("catalog: %s" % catalog) query = "%s+%s" % (query, catalog) logger.debug("query: %s" % query) great_words = title_variations if year != '': great_words.append(year) good_words = [ 'BrRip', 'BDRip', 'BRRip', 'BluRay', 'Bluray', 'x264', 'H.264' ] bad_words = ['DVDR', 'PAL', 'DvDrip', 'DVDrip', 'DVDscr', '480p'] avoid_words = ['YIFY', 'H.265', 'h265', 'x265', 'HEVC'] if '3D' not in name: avoid_words.append('3D') chronology_words = [ 'chronology', 'collection', 'sequel', '1, 2', '1&2', '1 & 2', 'series', 'duology', 'trilogy', 'triology', 'quadrilogy', 'tetralogy', 'pentalogy', 'hexalogy', 'heptalogy' ] sequel_words = ['part', 'chapter'] if video_type == 'movie': sequel_words.append('episode') numbers = [str(x) for x in range(1, 11)] numbers = numbers + [ 'i', 'ii', 'iii', 'iv', 'v', 'vi', 'vii', 'viii', 'ix', 'x' ] sequel_phrases = [w + ' ' + x for w in sequel_words for x in numbers] if video_type == 'movie': too_small = 1.0 ideal_min = 4.0 ideal_max = 9.0 elif video_type == 'television': too_small = 0.12 ideal_min = 0.7 ideal_max = 1.5 too_big = 17.0 if high_quality: hiq_min = ideal_min + ((too_big - ideal_min) / 2) hiq_max = too_big else: hiq_min = ideal_min hiq_max = ideal_max torrents = [] # scrape torrent site search_results = [] r = requests.get("https://kickass.cd/search.php?q=%s" % query) # r = requests.get("https://kickass2.org/search.php?q=%s" % query) search_results.append(r.content) if len(search_results) == 0: logger.critical('no HTML response from kickass.cd') sys.exit(1) else: logger.info('got HTML response from kickass.cd') #html_doc = open('webpage2.html', 'r') # parse scraped HTML start_list = [] final_list = [] for doc in search_results: soup = BeautifulSoup(doc, 'lxml') div = soup.find(id='mainSearchTable') # div = soup.find(class_='mainpart') if not div: sys.exit("couldn't find mainpart div") logger.debug('found mainSearchTable div') rows = div.find_all('tr', class_='odd') if len(rows) == 0: logger.critical('query returned no results') sys.exit(1) else: logger.info("query returned %s results" % len(rows)) for tr in div.find_all('tr', class_='odd'): score = 0 rejected = False link = tr.find('a', {'title': 'Torrent magnet link'})['href'] title = tr.find('a', class_='cellMainLink').get_text() logger.debug("scraped title: %s" % title) size = tr.find_all('td')[1].get_text() size = re.sub('<[^<]+?>', '', size) if isinstance(size, unicode): size = size.encode('ascii', 'ignore') trs = tr.find_all('td')[3] # logger.debug(tr.find_all('td')[3]) try: seeders = tr.find_all('td')[3].get_text() seeders = re.sub('<[^<]+?>', '', seeders) seeders = int(seeders) except: logger.debug( "couldn't display HTML in seeders column. setting seeders to a default of 1" ) seeders = 1 size = size.replace(' ', ' ') if 'MiB' in size or 'MB' in size: size = re.sub(r'Mi*B', '', size) size = float(size.split()[0]) / 1024 elif 'GiB' in size or 'GB' in size: size = re.sub(r'Gi*B', '', size) size = float(size.split()[0]) else: rejected = True size = 0 logger.debug('rejected due to size') chronology_matches = [ w for w in chronology_words if w in title.lower() and w not in name.lower() ] #logger.debug(chronology_matches) sequel_matches = [ w for w in sequel_phrases if w in title.lower() and w not in name.lower() ] #logger.debug(sequel_matches) if ((any(chronology_matches) or any(sequel_matches) or re.search(r'\d{4}[-\s]\d{4}', title)) and not chronologies): rejected = True logger.debug( 'rejected because it looks like a sequel or collection') if title not in [t['title'] for t in torrents]: if seeders == 0: rejected = True logger.debug('rejected because there are no seeders') if size < too_small: rejected = True logger.debug("rejected because %.2f GB is too small" % size) if size > too_big: rejected = True logger.debug("rejected because %.2f GB is too big" % size) if any(w in title for w in avoid_words): rejected = True rejected_words = ' '.join( list(set(title.split()).intersection(avoid_words))) logger.debug( "rejected because torrent name contains the following keywords: %s" % rejected_words) if not rejected: torrent = { 'title': title, 'link': link, 'size': size, 'seeders': seeders, 'score': score, 'res': '' } start_list.append(torrent) logger.info("%s results look relevant" % len(start_list)) # categorize torrents based on resolution logger.debug("separating torrents by resolution") hd1080 = [] hd720 = [] other = [] for torrent in start_list: if any(w in torrent['title'] for w in ['1080p', '1080i']): hd1080.append(torrent) torrent['res'] = '1080p' elif '720p' in torrent['title']: hd720.append(torrent) torrent['res'] = '720p' else: other.append(torrent) torrent['res'] = '' logger.debug("\t1080i/p: %s torrents" % len(hd1080)) logger.debug("\t720p: %s torrents" % len(hd720)) logger.debug("\tother: %s torrents" % len(other)) # score torrents based on keywords, size, and number of seeders for tlist in [hd1080, hd720, other]: for torrent in tlist: logger.debug(torrent['title']) delta = math.log(torrent['seeders'], 16) logger.debug("\tnumber of seeders: %+.2f points" % delta) torrent['score'] = torrent['score'] + delta for w in great_words: if w in torrent['title']: if w == year: delta = 2 else: delta = 4 logger.debug("\tmatched great_words: %+.2f points" % delta) torrent['score'] = torrent['score'] + delta for w in good_words: if w in torrent['title']: delta = 1 logger.debug("\tmatched good_words: %+.2f points" % delta) torrent['score'] = torrent['score'] + delta for w in bad_words: if w in torrent['title']: delta = -1 logger.debug("\tmatched bad_words: %+.2f points" % delta) torrent['score'] = torrent['score'] + delta if season: delta = 2 if episode: if catalog in torrent['title']: logger.debug("\tmatched season/episode: %+.2f points" % delta) torrent['score'] = torrent['score'] + delta else: if re.search(r"season[\s\.\-_]*0*%d" % season, torrent['title'], re.I): logger.debug("\tmatched season: %+.2f points" % delta) torrent['score'] = torrent['score'] + delta if torrent['size'] < ideal_min: delta = 1.0 * ( (math.log(torrent['size'] / math.log(torrent['size'] + 1)) + 1) + (math.log(torrent['size'] / math.log(torrent['size'] + 1)) * 15) - 6) / 2 logger.debug("\tsmaller than ideal file size: %+.2f points" % delta) torrent['score'] = torrent['score'] + delta if torrent['size'] > ideal_max: delta = -1 logger.debug("\tlarger than ideal file size: %+.2f points" % delta) torrent['score'] = torrent['score'] + delta if torrent['size'] > hiq_min or torrent['size'] < hiq_max: if high_quality: delta = (torrent['size'] / 2) * math.log(torrent['size']) #else: # delta = 1 logger.debug("\tideal file size: %+.2f points" % delta) torrent['score'] = torrent['score'] + delta # sort torrents by score for torrent in sorted(tlist, key=lambda t: t['score'], reverse=True): final_list.append(torrent) logger.debug("final list contains %s torrents" % len(final_list)) if video_type == 'television': logger.debug( 'merging 1080 and 720p content scores because this is a television program' ) final_list = sorted(final_list, key=lambda t: t['score'], reverse=True) # return the results if download: if len(final_list) < 1: logger.info("final list was empty") sys.exit("no results") logger.info("downloading %s" % final_list[0]['link']) # print final_list[0]['link'] sp = subprocess.Popen(' '.join([ 'transmission-remote', '--auth', transmission_creds, '-a', final_list[0]['link'] ]), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) sp_data = [] sp_data = sp.communicate() # print(sp_data) if sp_data[1]: if re.search(r"transmission-remote.*Couldn\'t connect to server", sp_data[1]): sys.exit("transmission-daemon unreachable") elif re.search(r"invalid or corrupt torrent file", sp_data[0]): sys.exit("invalid or corrupt torrent file") else: print("found a %s copy of %s" % (final_list[0]['res'], final_list[0]['title'])) else: logger.info("not downloading") if len(final_list) > 0: logger.info('---------------- RESULTS ----------------') logger.info("score\tseeders\tsize\t title") print("score\tseeders\tsize\t title") for torrent in final_list[:10]: result = "%.2f\t%s\t%.1f GiB\t %s" % ( torrent['score'], torrent['seeders'], torrent['size'], torrent['title']) print(result) logger.info(result) logger.info('-----------------------------------------') else: logger.warning("no results!") print "Error: no results"
#!/usr/bin/env python from transmission import Transmission from upnp import UPnP t = Transmission('localhost', 9091) u = UPnP() proto = 'UDP' if u.isPortMapped(t.peer_port, proto): if not u.isPortMappedToLanIp(t.peer_port, proto): t.peer_port = u.getFreePort(t.peer_port, proto) u.addPortMappingToLanIp(t.peer_port, proto) else: u.addPortMappingToLanIp(t.peer_port, proto) print 'Transmission peer port is %s. The port is mapped in UPnP IGD.' % t.peer_port exit(0)
def test_nothing_works(self): self.assertEqual(1, 1) t = Transmission() print(t.request(requests.get).__dict__)