From d062eb1dd8ede38208f97b95e5f73503415f61f4 Mon Sep 17 00:00:00 2001 From: MrTyton Date: Tue, 22 Dec 2020 04:06:55 -0500 Subject: [PATCH] Update to Python3 and some other fixes --- README.md | 6 ++++++ config_template.ini | 10 +++++++++ fanficdownload.py | 52 +++++++++++++++++++++------------------------ runner_notify.py | 15 +++++++------ 4 files changed, 48 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 39c5de7..73848b8 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,14 @@ Python script to automate the use of FanFicFare CLI (https://github.com/JimmXinu Primary script is fanficdownload.py. Use -h or --help to see the options. +All of the options can be loaded into the config file, of which the template is provided in `config_template.ini`, and utilized with `python3 fanficdownload.py -c path_to_config.ini`. + There is additional support for notifications, including pushbullet integration, through runner_notify. Use -h to see options. Works with Fanficfare 2.3.6+. Rewrite underway to take advantage of new features in Fanficfare 2.4.0 +Requires Python 3.6.9. Unsure if it will work on higher versions of Python. + For basic cron usage, this is not needed, `fanficfare -dowload-imap -u` should work if you're not integrating into calibre. This script is best used if you want to update the calibre library, for the usage of calibre-server for instance. + +If anything does not work, please open a ticket. \ No newline at end of file diff --git a/config_template.ini b/config_template.ini index 897ee49..3d7ad91 100644 --- a/config_template.ini +++ b/config_template.ini @@ -1,17 +1,27 @@ +# Email Login Information, so that the script can download from email subscription notifications. [login] +# Username for email user= +# Password for email password= +# IMAP address for email server= +# The mailbox to look in the emails for, such as INBOX mailbox= [locations] +# Web Address for the calibre library to update library= +# Path to file to read links from, or to output links that didn't work. input= +# If you want to user runner_notify.py to send alerts to your phone, fill out the fields here. [runner] notification= pushbullet= pbdevice= +tag= +# How to display output. True will display as the program runs, false will wait until the end. [output] live= diff --git a/fanficdownload.py b/fanficdownload.py index 6c9a0b5..aaf1248 100644 --- a/fanficdownload.py +++ b/fanficdownload.py @@ -5,7 +5,7 @@ from subprocess import check_output, STDOUT, call, PIPE import logging from optparse import OptionParser import re -from ConfigParser import ConfigParser +from configparser import ConfigParser from tempfile import mkdtemp from shutil import rmtree import socket @@ -61,7 +61,7 @@ def log(msg, color=None, output=True): bcolors.ENDC, msg) if output: - print line + print(line) return "" else: return line + "\n" @@ -72,10 +72,11 @@ def touch(fname, times=None): utime(fname, times) -ffnet = re.compile('(fanfiction.net/s/\d*)/?.*') -aooo = re.compile('(archiveofourown.org/works/\d*)/?.*') -ficpress = re.compile('(fictionpress.com/s/\d*)/?.*') -neutral = re.compile('https?://(.*)') +url_parsers = [(re.compile('(fanfiction.net/s/\d*)/?.*'), "www."), #ffnet + (re.compile('(archiveofourown.org/works/\d*)/?.*'), ""), #ao3 + (re.compile('(fictionpress.com/s/\d*)/?.*'), ""), #fictionpress + (re.compile('(royalroad.com/fiction/\d*)/?.*'), ""), #royalroad + (re.compile('https?://(.*)'), "")] #other sites story_name = re.compile('(.*)-.*') equal_chapters = re.compile('.* already contains \d* chapters.') @@ -89,14 +90,10 @@ more_chapters = re.compile( def parse_url(url): - if ffnet.search(url): - url = "www." + ffnet.search(url).group(1) - elif aooo.search(url): - url = aooo.search(url).group(1) - elif ficpress.search(url): - url = ficpress.search(url).group(1) - elif neutral.search(url): - url = neutral.search(url).group(1) + for cur_parser, cur_prefix in url_parsers: + if cur_parser.search(url): + url = cur_prefix + cur_parser.search(url).group(1) + return url return url @@ -135,12 +132,12 @@ def downloader(args): try: storyId = check_output( 'calibredb search "Identifiers:{}" {}'.format( - url, path), shell=True, stderr=STDOUT, stdin=PIPE, ) + url, path), shell=True, stderr=STDOUT, stdin=PIPE, ).decode('utf-8') output += log("\tStory is in calibre with id {}".format(storyId), 'BLUE', live) output += log("\tExporting file", 'BLUE', live) res = check_output( 'calibredb export {} --dont-save-cover --dont-write-opf --single-dir --to-dir "{}" {}'.format( - storyId, loc, path), shell=True, stdin=PIPE, stderr=STDOUT) + storyId, loc, path), shell=True, stdin=PIPE, stderr=STDOUT).decode('utf-8') cur = get_files(loc, ".epub", True)[0] output += log( '\tDownloading with fanficfare, updating file "{}"'.format(cur), @@ -156,11 +153,11 @@ def downloader(args): shell=True, stderr=STDOUT, stdin=PIPE, - ) + ).decode('utf-8') output += log('\tRunning: {}fanficfare -u "{}" --update-cover'.format( moving, cur), 'BLUE', live) res = check_output('{}fanficfare -u "{}" --update-cover'.format( - moving, cur), shell=True, stderr=STDOUT, stdin=PIPE) + moving, cur), shell=True, stderr=STDOUT, stdin=PIPE).decode('utf-8') check_regexes(res) if chapter_difference.search(res) or more_chapters.search(res): output += log("\tForcing download update due to:", @@ -170,7 +167,7 @@ def downloader(args): output += log("\t\t{}".format(line), 'WARNING', live) res = check_output( '{}fanficfare -u "{}" --force --update-cover'.format( - moving, cur), shell=True, stderr=STDOUT, stdin=PIPE) + moving, cur), shell=True, stderr=STDOUT, stdin=PIPE).decode('utf-8') check_regexes(res) cur = get_files(loc, '.epub', True)[0] @@ -185,25 +182,25 @@ def downloader(args): shell=True, stderr=STDOUT, stdin=PIPE, - ) + ).decode('utf-8') except BaseException: if not live: - print output.strip() + print(output.strip()) raise output += log("\tAdding {} to library".format(cur), 'BLUE', live) try: res = check_output( - 'calibredb add -d {} "{}"'.format(path, cur), shell=True, stderr=STDOUT, stdin=PIPE, ) + 'calibredb add -d {} "{}"'.format(path, cur), shell=True, stderr=STDOUT, stdin=PIPE, ).decode('utf-8') except Exception as e: output += log(e) if not live: - print output.strip() + print(output.strip()) raise try: res = check_output( 'calibredb search "Identifiers:{}" {}'.format( - url, path), shell=True, stderr=STDOUT, stdin=PIPE) + url, path), shell=True, stderr=STDOUT, stdin=PIPE).decode('utf-8') output += log("\tAdded {} to library with id {}".format(cur, res), 'GREEN', live) except BaseException: @@ -216,7 +213,7 @@ def downloader(args): else: res = check_output( 'cd "{}" && fanficfare -u "{}" --update-cover'.format( - loc, url), shell=True, stderr=STDOUT, stdin=PIPE) + loc, url), shell=True, stderr=STDOUT, stdin=PIPE).decode('utf-8') check_regexes(res) cur = get_files(loc, '.epub', True)[0] name = get_files(loc, '.epub', False)[0] @@ -228,12 +225,12 @@ def downloader(args): 'GREEN', live) if not live: - print output.strip() + print(output.strip()) rmtree(loc) except Exception as e: output += log("Exception: {}".format(e), 'FAIL', live) if not live: - print output.strip() + print(output.strip()) try: rmtree(loc) except BaseException: @@ -409,7 +406,6 @@ if __name__ == "__main__": if not (options.user or options.password): raise ValueError("User or Password not given") - main( options.user, options.password, diff --git a/runner_notify.py b/runner_notify.py index 29d2846..b1724cd 100644 --- a/runner_notify.py +++ b/runner_notify.py @@ -1,4 +1,4 @@ -from StringIO import StringIO +from io import StringIO import re from subprocess import check_output, STDOUT @@ -9,7 +9,7 @@ from notifications import Notification from pushbullet import Pushbullet from optparse import OptionParser -from ConfigParser import ConfigParser +from configparser import ConfigParser def enable_notifications(options): @@ -18,13 +18,13 @@ def enable_notifications(options): try: pb = Pushbullet(options.pushbullet) except BaseException: - print "Problem wtih connecting to pushbullet. API Key likely invalid" + print("Problem wtih connecting to pushbullet. API Key likely invalid") fail = True if options.pbdevice and not fail: try: pb = pb.get_device(options.pbdevice) except BaseException: - print "Cannot get this device." + print("Cannot get this device.") fail = True pass if not fail: @@ -45,16 +45,17 @@ def touch(fname, times=None): def main(options): try: res = check_output( - "python fanficdownload.py -c config.ini", + "python3 fanficdownload.py -c config.ini", shell=True, stderr=STDOUT) except Exception as e: - print e + print(e) res = None if not res: return else: - print res + res = res.decode('utf-8') + print(res) buf = StringIO(res) regex = re.compile("Added (?:.*/)?(.*)-.* to library with id \d*") searcher = regex.search