initial
This commit is contained in:
52
src/scripts/derailleur-add
Executable file
52
src/scripts/derailleur-add
Executable file
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2016-2017 Mads Michelsen (mail@brokkr.net)
|
||||
# This file is part of Derailleur.
|
||||
# Derailleur is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License,
|
||||
# or (at your option) any later version.
|
||||
|
||||
"""Torrent starter"""
|
||||
|
||||
import sys
|
||||
import derailleur
|
||||
|
||||
|
||||
def get_parsed_args():
|
||||
'''Parses arguments and return them'''
|
||||
parser = derailleur.args.start_parser()
|
||||
parser.add_argument("torrent", nargs='*',
|
||||
help="Magnet URL(s) or .torrent(s)")
|
||||
parsed_args = derailleur.args.end_parser(parser)
|
||||
return parsed_args
|
||||
|
||||
def start_torrent(config, client, logger, torrent):
|
||||
'''For each torrent in nargs, hand it over'''
|
||||
outcome = client.download(torrent, config['Add']['pause_when_added'])
|
||||
if outcome:
|
||||
logger.info(outcome)
|
||||
else:
|
||||
logger.error('ERROR : ' + 'Failed to add torrent')
|
||||
|
||||
def main():
|
||||
'''Putting it all together'''
|
||||
args = get_parsed_args()
|
||||
config, validation = derailleur.config.get_config()
|
||||
if validation['Connection'] is not True or validation['Add'] is not True:
|
||||
sys.exit('ERROR : Missing configuration')
|
||||
logger = derailleur.loggers.Logger('Add', config, validation)
|
||||
client = derailleur.client.get_client(config)
|
||||
if not client:
|
||||
logger.error('ERROR : Connect to Transmission failed')
|
||||
sys.exit(1)
|
||||
for torrent in args.torrent:
|
||||
start_torrent(config, client, logger, torrent)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
pass
|
81
src/scripts/derailleur-feed
Executable file
81
src/scripts/derailleur-feed
Executable file
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2016-2017 Mads Michelsen (mail@brokkr.net)
|
||||
# This file is part of Derailleur.
|
||||
# Derailleur is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License,
|
||||
# or (at your option) any later version.
|
||||
|
||||
import sys
|
||||
import feedparser
|
||||
import derailleur
|
||||
|
||||
|
||||
def get_parsed_args():
|
||||
'''Parses arguments and return them'''
|
||||
parser = derailleur.args.start_parser()
|
||||
parsed_args = derailleur.args.end_parser(parser)
|
||||
return parsed_args
|
||||
|
||||
def get_feed(config):
|
||||
'''Parses feed and returns dictionary of entries'''
|
||||
doc = feedparser.parse(config['Feed']['url'])
|
||||
get_edic = lambda x: {'title': x.title, 'url': x.link, 'done': False}
|
||||
feed_dic = {exml.id: get_edic(exml) for exml in doc.entries}
|
||||
return feed_dic
|
||||
|
||||
def get_fresh(feed_dic, jar_dic):
|
||||
'''Go through feed entries'''
|
||||
done_entries = [eid for eid in jar_dic if jar_dic[eid]['done'] is True]
|
||||
fresh_entries = [eid for eid in feed_dic if eid not in done_entries]
|
||||
return fresh_entries
|
||||
|
||||
def start_torrent(config, client, logger, feed_dic, eid):
|
||||
'''Start an entry from the feed'''
|
||||
edic = feed_dic[eid]
|
||||
outcome = client.download(edic['url'], config['Feed']['pause_when_added'])
|
||||
if outcome:
|
||||
edic['done'] = True
|
||||
logger.info(outcome)
|
||||
else:
|
||||
logger.error('ERROR : Failed to add %s', edic['title'])
|
||||
return edic
|
||||
|
||||
def main():
|
||||
'''Putting it all together'''
|
||||
_args = get_parsed_args()
|
||||
config, validation = derailleur.config.get_config()
|
||||
# note that defaults should ensure always-valid configs but bad user
|
||||
# input (e.g. a string for a port number) may invalidate it.
|
||||
if validation['Connection'] is not True or validation['Feed'] is not True:
|
||||
sys.exit('ERROR : Missing configuration')
|
||||
logger = derailleur.loggers.Logger('Feed', config, validation)
|
||||
client = derailleur.client.get_client(config)
|
||||
if not client:
|
||||
logger.error('ERROR : Connect to Transmission failed')
|
||||
sys.exit(1)
|
||||
feed_dic = get_feed(config)
|
||||
if not feed_dic:
|
||||
logger.error('ERROR : Cannot find feed or feed empty')
|
||||
sys.exit(1)
|
||||
jar = derailleur.history.Jar(config, 'derailleur-feed.db')
|
||||
jar_dic = jar.load()
|
||||
if jar_dic is False:
|
||||
logger.error('ERROR : Failure loading %s', jar.db_filepath)
|
||||
sys.exit(1)
|
||||
fresh_entries = get_fresh(feed_dic, jar_dic)
|
||||
for eid in fresh_entries:
|
||||
edic = start_torrent(config, client, logger, feed_dic, eid)
|
||||
jar_dic[eid] = edic
|
||||
success = jar.save(jar_dic)
|
||||
if success is False:
|
||||
logger.error('ERROR : Failure saving %s', jar.db_filepath)
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
pass
|
47
src/scripts/derailleur-manager
Executable file
47
src/scripts/derailleur-manager
Executable file
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2016-2017 Mads Michelsen (mail@brokkr.net)
|
||||
# This file is part of Derailleur.
|
||||
# Derailleur is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License,
|
||||
# or (at your option) any later version.
|
||||
|
||||
"""Torrent manager script"""
|
||||
|
||||
import sys
|
||||
import derailleur
|
||||
|
||||
|
||||
def get_parsed_args():
|
||||
'''Parses arguments and return them'''
|
||||
parser = derailleur.args.start_parser()
|
||||
parser.add_argument("-v", "--verbose", help="Get info on current torrents",
|
||||
action="store_true")
|
||||
parsed_args = derailleur.args.end_parser(parser)
|
||||
return parsed_args
|
||||
|
||||
def main():
|
||||
'''Putting it all together'''
|
||||
args = get_parsed_args()
|
||||
config, validation = derailleur.config.get_config()
|
||||
if validation['Connection'] is not True or \
|
||||
validation['Manager'] is not True:
|
||||
sys.exit('ERROR : Missing configuration')
|
||||
logger = derailleur.loggers.Logger('Manager', config, validation,
|
||||
verbose=args.verbose)
|
||||
client = derailleur.client.get_client(config)
|
||||
if not client:
|
||||
logger.error('ERROR : Connect to Transmission failed')
|
||||
sys.exit(1)
|
||||
jar = derailleur.history.Jar(config, 'derailleur-manager.db')
|
||||
manager = derailleur.manager.Manager(config, client, logger, jar)
|
||||
manager.check_torrents()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
pass
|
124
src/scripts/derailleur-postproc
Executable file
124
src/scripts/derailleur-postproc
Executable file
@@ -0,0 +1,124 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2016-2017 Mads Michelsen (mail@brokkr.net)
|
||||
# This file is part of Derailleur.
|
||||
# Derailleur is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License,
|
||||
# or (at your option) any later version.
|
||||
|
||||
import os
|
||||
import sys
|
||||
from collections import namedtuple
|
||||
import derailleur
|
||||
|
||||
try:
|
||||
from xbmcjson import XBMC
|
||||
import requests.packages.urllib3.exceptions
|
||||
except ImportError:
|
||||
XBMC = None
|
||||
|
||||
TorrentInfo = namedtuple('torrent_info', 'ppath name hash')
|
||||
|
||||
def get_parsed_args():
|
||||
'''Parses arguments and return them'''
|
||||
parser = derailleur.args.start_parser()
|
||||
parser.add_argument("-t", "--target", help='''Set a target manually '''
|
||||
'''rather than relying on environmental variables''')
|
||||
parsed_args = derailleur.args.end_parser(parser)
|
||||
return parsed_args
|
||||
|
||||
def get_torrent_info(args):
|
||||
'''Get Transmission info on target'''
|
||||
if args.target:
|
||||
target = os.path.abspath(args.target)
|
||||
if not os.path.isdir(target) and not os.path.isfile(target):
|
||||
sys.exit('ERROR : Not a valid target')
|
||||
get_pp = lambda x: os.path.abspath(os.path.join(x, os.path.pardir))
|
||||
torrent_info = TorrentInfo(ppath=get_pp(target),
|
||||
name=os.path.basename(target),
|
||||
hash='abcdef123456')
|
||||
else:
|
||||
try:
|
||||
torrent_info = TorrentInfo(ppath=os.environ['TR_TORRENT_DIR'],
|
||||
name=os.environ['TR_TORRENT_NAME'],
|
||||
hash=os.environ['TR_TORRENT_HASH'])
|
||||
except KeyError:
|
||||
torrent_info = None
|
||||
return torrent_info
|
||||
|
||||
def get_type(config, keywords, stats):
|
||||
'''Get torrent type'''
|
||||
module_dic = {
|
||||
'tv': derailleur.postproc.tv,
|
||||
'film': derailleur.postproc.film,
|
||||
'music': derailleur.postproc.audio,
|
||||
'audiobook': derailleur.postproc.audio
|
||||
}
|
||||
if stats.identity in keywords:
|
||||
type_module = derailleur.postproc.keywords
|
||||
type_path = os.path.join(config['Postproc']['base_path'],
|
||||
stats.identity)
|
||||
elif stats.identity == 'generic':
|
||||
type_module = derailleur.postproc.generic
|
||||
type_path = os.path.join(config['Postproc']['base_path'], 'default')
|
||||
else:
|
||||
type_module = module_dic[stats.identity]
|
||||
type_path = config['Postproc']['base_path_' + stats.identity]
|
||||
return (type_module, type_path)
|
||||
|
||||
def get_log_str(torrent, stats, move_errors):
|
||||
'''Logging'''
|
||||
log_str = "ERRORS ENCOUNTERED IN FILE OPERATION. " if move_errors else ""
|
||||
log_str += "NAME: " + stats.torrent_name + ". TYPE: " + stats.identity
|
||||
log_str += ". FILES: "
|
||||
type_count = [x + " " + str(torrent.move_type_lst.count(x))
|
||||
for x in set(torrent.move_type_lst)]
|
||||
log_str += ", ".join(type_count)
|
||||
common_path = os.path.commonprefix([x[1] for x in torrent.move_lst])
|
||||
log_str += ". PARENT: " + os.path.dirname(common_path)
|
||||
return log_str
|
||||
|
||||
def update_kodi(config, stats):
|
||||
'''Update kodi library'''
|
||||
url = 'http://' + config['Kodi']['host'] + ':' \
|
||||
+ str(config['Kodi']['port']) + '/jsonrpc'
|
||||
try:
|
||||
kodi = XBMC(url, config['Kodi']['user'], config['Kodi']['password'])
|
||||
except requests.packages.urllib3.exceptions.NewConnectionError:
|
||||
sys.exit(11)
|
||||
if stats.identity in ['tv', 'film']:
|
||||
kodi.VideoLibrary.Scan()
|
||||
if stats.identity in ['music']:
|
||||
kodi.AudioLibrary.Scan()
|
||||
|
||||
def main():
|
||||
'''Putting the whole thing together'''
|
||||
args = get_parsed_args()
|
||||
config, validation = derailleur.config.get_config()
|
||||
if validation['Postproc'] != True:
|
||||
sys.exit('ERROR : Config not valid')
|
||||
logger = derailleur.loggers.Logger('Postproc', config, validation)
|
||||
torrent_info = get_torrent_info(args)
|
||||
if not torrent_info:
|
||||
logger.error('ERROR : Could not access Transmission variables')
|
||||
sys.exit(1)
|
||||
keywords = config['Postproc']['keywords']
|
||||
stats = derailleur.postproc.stats.Stats(keywords, torrent_info)
|
||||
type_module, type_path = get_type(config, keywords, stats)
|
||||
torrent = type_module.Torrent(config, stats, type_path)
|
||||
torrent.manipulate()
|
||||
move_errors = torrent.move_files()
|
||||
log_str = get_log_str(torrent, stats, move_errors)
|
||||
logger.info(log_str)
|
||||
if XBMC and config['Kodi']['connect_to_kodi']:
|
||||
update_kodi(config, stats)
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
pass
|
Reference in New Issue
Block a user