Files
PDMameUpdate/PDMameUpdate.py
2019-10-23 21:11:44 +02:00

247 lines
7.6 KiB
Python
Executable File

#!/usr/bin/python3
'''
Checks available MAME Torrents on PleasureDome
and updates the local versions if more recent
versions are detected
Basically what it does is:
* Get all torrents in a directory and filter MAME torrents
* Get all torrents from PleasureDome RSS
* Get all torrents currently active in Transmission
* Intersect 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:
* Transmission for Bitorrent
* A PleasureDome account
* A proper config.json file (see config.template.json)
* Python3 with the libraries below
- feedparser
- transmission-clutch
* Linux (untested on other OS, but it might work)
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
See: 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 argparse
import feedparser
import json
import logging
import os
import re
import requests
import time
from clutch.core import Client
from collections import defaultdict
from pprint import pformat
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')
directories = os.listdir(config['mame-directory'])
for directory in directories:
match = re_mame_version.match(directory)
if match:
torrents[match.group(2)]['local-version'] = int(match.group(1))
torrents[match.group(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')
for post in d.entries:
match = re_mame_version.match(post.title)
if match:
torrents[match.group(2)]['remote-version'] = int(match.group(1))
torrents[match.group(2)]['remote-link'] = post.link
torrents[match.group(2)]['remote-name'] = post.title
logging.debug('Found the remote torrent versions: %s', pformat(torrents))
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']
and
data['remote-link'].startswith(
'http://www.pleasuredome.org.uk/download.php'
)
):
del torrents[torrent]
logging.info(
'The following torrents can be updated: %s', pformat(torrents)
)
def prompt_for_update():
"""Ask for user confirmation before updating"""
if len(torrents) > 0:
for torrent, data in torrents.items():
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: no update candidate')
print('No update found…')
exit(0)
logging.info('User chose to update torrents')
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')
logging.info('Logging out')
requests.get('http://www.pleasuredome.org.uk/logout.php')
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.group(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'],
download_dir=config['mame-directory'],
cookies=cookies,
paused=False
)
if __name__ == '__main__':
logging.basicConfig(
level=logging.WARNING,
format=' %(asctime)s - %(levelname)s - %(message)s'
)
parser = argparse.ArgumentParser(
description='Update PleasureDome MAME Torrents'
)
parser.add_argument(
'-l', '--log',
action='store_true',
help='Display more log messages'
)
parser.add_argument(
'-c', '--countdown',
action='store_true',
help='Start with a 5 second countdown'
)
args = parser.parse_args()
if args.log:
logging.getLogger().setLevel(logging.INFO)
if args.countdown:
print('PDMameUpdate is about to start')
# Useful if you run this script when your machine boots
for i in range(5, 0, -1):
print('{}\r'.format(i), end=''),
time.sleep(1)
re_mame_version = re.compile(r'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()