From 307e4005774ad420f3c688a89262bd5ea9d4e776 Mon Sep 17 00:00:00 2001 From: djib Date: Sat, 7 Sep 2019 18:25:51 +0200 Subject: [PATCH] First fully functional commit --- PDMameUpdate.py | 209 +++++++++++++++++++++++++++++++++---------- config.template.json | 2 + 2 files changed, 166 insertions(+), 45 deletions(-) diff --git a/PDMameUpdate.py b/PDMameUpdate.py index 28448af..cedbc65 100644 --- a/PDMameUpdate.py +++ b/PDMameUpdate.py @@ -4,78 +4,197 @@ Checks available MAME Torrents on PleasureDome and updates the local versions if more recent versions are detected +Basically what it does is: + * Real all torrents in a directory and filters MAME torrents + * Get all torrents from PleasureDome RSS + * Get all torrents currently active in Transmission + * Mix the three lists to get updatable torrents + * And for each updatable torrent: + - remove the old torrent from Transmission, + - rename the local directory, + - add the new torrent + Work in progress… - + * TODO: implement some error handling + Requirements: - * Python3 with the libraries below * Transmission for Bitorrent * A PleasureDome account + * A proper config.json file (see config.template.json) + * Python3 with the libraries below + * Linux (untested on other OS, but it might work) -/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\ -/!\ Provided with no warranty whatsoever. /!\ -/!\ Use with caution. /!\ -/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\ +Notes + * This script logs in PleasureDome to get the proper cookies. + It seems you can also set your cookies in Transmission using + a cookies.txt file in the .config/transmission directory + https://forum.transmissionbt.com/viewtopic.php?t=7468 + +/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\ +/!\ Provided with no warranty whatsoever. /!\ +/!\ Make sure you understand what the script /!\ +/!\ does and adapt it to your context /!\ +/!\ Use with caution. /!\ +/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\ ''' import feedparser import json import logging import os import re +import requests from clutch.core import Client +from collections import defaultdict +from pprint import pformat -if __name__ == '__main__': - logging.basicConfig(level=logging.DEBUG, format=' %(asctime)s - %(levelname)s - %(message)s') - re_mame_version = re.compile('MAME 0.(\d+) (.*)') +def open_config_file(): + """Reads configuration from config.json file""" logging.info('Opening config file: config.json') with open('config.json') as config_file: config = json.load(config_file) + return config + + +def fetch_local_torrents(): + """Fetches local torrents versions""" logging.info('Fetching current MAME versions') - files = os.listdir(config['mame_directory']) - local_torrents = {} - for file in files: - match = re_mame_version.match(file) + directories = os.listdir(config['mame_directory']) + for directory in directories: + match = re_mame_version.match(directory) if match: - local_torrents[match[2]] = int(match[1]) - logging.info('Found the following Torrent version on disk: %s', local_torrents) + torrents[match[2]]['local-version'] = int(match[1]) + torrents[match[2]]['local-name'] = directory + logging.debug('Found the local torrent versions: %s', pformat(torrents)) + + +def fetch_remote_terrents(): + """Fetches PleasureDome torrents versions""" logging.info('Opening PleasureDome RSS feed') d = feedparser.parse('http://www.pleasuredome.org.uk/rss.xml') - remote_torrents = {} for post in d.entries: match = re_mame_version.match(post.title) if match: - remote_torrents[match[2]] = int(match[1]) - logging.info('Found the following Torrent version on PleasureDome: %s', remote_torrents) - - for torrent, version in local_torrents.items(): - if torrent in remote_torrents: - if version < remote_torrents[torrent]: - print('Torrent {}: {} -> {}'.format(torrent, version, remote_torrents[torrent])) - - print('Should I update the torrents listed above? (y/N)') - answer = input() - if answer.lower() == 'y': - logging.info('Updating…') + torrents[match[2]]['remote-version'] = int(match[1]) + torrents[match[2]]['remote-link'] = post.link + torrents[match[2]]['remote-name'] = post.title + logging.debug('Found the remote torrent versions: %s', pformat(torrents)) - logging.info('Connecting to Transmission Remote Control') - client = Client( - username=config['transmission-user'], - password=config['transmission-password'], - port=config['transmission-port'] - ) + +def filter_updatable_torrents(): + """Checks if newer versions are available and prompt for update""" + + for torrent, data in list(torrents.items()): + keys_to_check = {'local-version','remote-version','transmission-id'} + if not ( keys_to_check.issubset(data.keys()) + and data['local-version'] < data['remote-version']): + del torrents[torrent] + logging.info('The following torrents can be updated: %s', pformat(torrents)) + + +def prompt_for_update(): + """Ask for user confirmation before updating""" - logging.info('Listing Transmission torrents') - for torrent in client.list().values(): - print(torrent['name']); - + if len(torrents) > 0: + for torrent, data in torrents: + print('Torrent {}: {} -> {}'.format( + torrent, + data['local-version'], + data['remote-version'] + )) + print('Should I update the torrents listed above? (y/N)') + answer = input() + if answer.lower() != 'y': + logging.info('Quitting: user cancelled update') + print('Quitting…') + exit(0) else: - logging.info('Quitting: user cancelled update.') + logging.info('Quitting: no update candidate') + print('No update found…') + exit(0) + logging.info('User chose to update torrents') - - # TODO: connect to PleasureDome - # TODO: remove local torrent from Transmission - # TODO: rename local folder - # TODO: add new torrent to Transmission - # TODO: implement some error handling \ No newline at end of file + +def get_cookies_from_pleasuredome(): + """Connects to PleasureDome to retrieve Cookies""" + + logging.info('Logging in PleasureDome') + data = { + 'uid':config['pleasuredome-user'], + 'pwd':config['pleasuredome-password'] + } + r = requests.post('http://www.pleasuredome.org.uk/login2.php', data=data) + if r.status_code == 200: + logging.info('Connected to PleasureDome') + else: + logging.error( + 'Connection to PleasureDome failed with status %s', + r.status_code + ) + exit(1) + return {k: r.cookies[k] for k in ('uid','pass')} + + +def connect_to_transmission(): + """Connects to Transmission and return a Client object""" + + logging.info('Connecting to Transmission Remote Control') + return Client( + username=config['transmission-user'], + password=config['transmission-password'], + port=config['transmission-port'] + ) + + +def fetch_transmission_torrents(): + """Gets the torrents id from Transmission""" + + logging.info('Listing Transmission torrents') + for torrent in client.list().values(): + match = re_mame_version.match(torrent['name']) + if match: + torrents[match[2]]['transmission-id'] = torrent['id'] + logging.debug('Found the Transmission torrent ids: %s', pformat(torrents)) + + +def update_torrents(): + """ + Updates torrents: + * remove it from Transmission, + * rename the local directory, + * and add the new torrent + """ + logging.info('Updating torrents') + for torrent in torrents.values(): + old_name = os.path.join(config['mame_directory'], torrent['local-name']) + new_name = os.path.join(config['mame_directory'], torrent['remote-name']) + + client.torrent.remove(torrent['transmission-id']); + os.rename(old_name, new_name) + client.torrent.add( + filename=torrent['remote-link'], + cookies=cookies, + paused=True + ) + +if __name__ == '__main__': + logging.basicConfig( + level=logging.INFO, + format=' %(asctime)s - %(levelname)s - %(message)s' + ) + + re_mame_version = re.compile('MAME 0.(\d+) (.*)') + config = open_config_file() + torrents = defaultdict(dict) + + client = connect_to_transmission() + cookies = get_cookies_from_pleasuredome() + + fetch_local_torrents() + fetch_remote_terrents() + fetch_transmission_torrents() + filter_updatable_torrents() + prompt_for_update() + update_torrents() \ No newline at end of file diff --git a/config.template.json b/config.template.json index 1d8c22f..274a697 100644 --- a/config.template.json +++ b/config.template.json @@ -2,5 +2,7 @@ "mame_directory":"/path/to/your/locol/mame/torrent/target/folders", "transmission-user":"user", "transmission-password":"pass", + "pleasuredome-user":"user", + "pleasuredome-password":"pass", "transmission-port":8080 } \ No newline at end of file