Update to Python3 and some other fixes

This commit is contained in:
MrTyton 2020-12-22 04:06:55 -05:00
parent db8d9e953b
commit d062eb1dd8
4 changed files with 48 additions and 35 deletions

View File

@ -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. 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. 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 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. 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.

View File

@ -1,17 +1,27 @@
# Email Login Information, so that the script can download from email subscription notifications.
[login] [login]
# Username for email
user= user=
# Password for email
password= password=
# IMAP address for email
server= server=
# The mailbox to look in the emails for, such as INBOX
mailbox= mailbox=
[locations] [locations]
# Web Address for the calibre library to update
library= library=
# Path to file to read links from, or to output links that didn't work.
input= input=
# If you want to user runner_notify.py to send alerts to your phone, fill out the fields here.
[runner] [runner]
notification= notification=
pushbullet= pushbullet=
pbdevice= pbdevice=
tag=
# How to display output. True will display as the program runs, false will wait until the end.
[output] [output]
live= live=

View File

@ -5,7 +5,7 @@ from subprocess import check_output, STDOUT, call, PIPE
import logging import logging
from optparse import OptionParser from optparse import OptionParser
import re import re
from ConfigParser import ConfigParser from configparser import ConfigParser
from tempfile import mkdtemp from tempfile import mkdtemp
from shutil import rmtree from shutil import rmtree
import socket import socket
@ -61,7 +61,7 @@ def log(msg, color=None, output=True):
bcolors.ENDC, bcolors.ENDC,
msg) msg)
if output: if output:
print line print(line)
return "" return ""
else: else:
return line + "\n" return line + "\n"
@ -72,10 +72,11 @@ def touch(fname, times=None):
utime(fname, times) utime(fname, times)
ffnet = re.compile('(fanfiction.net/s/\d*)/?.*') url_parsers = [(re.compile('(fanfiction.net/s/\d*)/?.*'), "www."), #ffnet
aooo = re.compile('(archiveofourown.org/works/\d*)/?.*') (re.compile('(archiveofourown.org/works/\d*)/?.*'), ""), #ao3
ficpress = re.compile('(fictionpress.com/s/\d*)/?.*') (re.compile('(fictionpress.com/s/\d*)/?.*'), ""), #fictionpress
neutral = re.compile('https?://(.*)') (re.compile('(royalroad.com/fiction/\d*)/?.*'), ""), #royalroad
(re.compile('https?://(.*)'), "")] #other sites
story_name = re.compile('(.*)-.*') story_name = re.compile('(.*)-.*')
equal_chapters = re.compile('.* already contains \d* chapters.') equal_chapters = re.compile('.* already contains \d* chapters.')
@ -89,14 +90,10 @@ more_chapters = re.compile(
def parse_url(url): def parse_url(url):
if ffnet.search(url): for cur_parser, cur_prefix in url_parsers:
url = "www." + ffnet.search(url).group(1) if cur_parser.search(url):
elif aooo.search(url): url = cur_prefix + cur_parser.search(url).group(1)
url = aooo.search(url).group(1) return url
elif ficpress.search(url):
url = ficpress.search(url).group(1)
elif neutral.search(url):
url = neutral.search(url).group(1)
return url return url
@ -135,12 +132,12 @@ def downloader(args):
try: try:
storyId = check_output( storyId = check_output(
'calibredb search "Identifiers:{}" {}'.format( '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("\tStory is in calibre with id {}".format(storyId), 'BLUE', live)
output += log("\tExporting file", 'BLUE', live) output += log("\tExporting file", 'BLUE', live)
res = check_output( res = check_output(
'calibredb export {} --dont-save-cover --dont-write-opf --single-dir --to-dir "{}" {}'.format( '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] cur = get_files(loc, ".epub", True)[0]
output += log( output += log(
'\tDownloading with fanficfare, updating file "{}"'.format(cur), '\tDownloading with fanficfare, updating file "{}"'.format(cur),
@ -156,11 +153,11 @@ def downloader(args):
shell=True, shell=True,
stderr=STDOUT, stderr=STDOUT,
stdin=PIPE, stdin=PIPE,
) ).decode('utf-8')
output += log('\tRunning: {}fanficfare -u "{}" --update-cover'.format( output += log('\tRunning: {}fanficfare -u "{}" --update-cover'.format(
moving, cur), 'BLUE', live) moving, cur), 'BLUE', live)
res = check_output('{}fanficfare -u "{}" --update-cover'.format( 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) check_regexes(res)
if chapter_difference.search(res) or more_chapters.search(res): if chapter_difference.search(res) or more_chapters.search(res):
output += log("\tForcing download update due to:", output += log("\tForcing download update due to:",
@ -170,7 +167,7 @@ def downloader(args):
output += log("\t\t{}".format(line), 'WARNING', live) output += log("\t\t{}".format(line), 'WARNING', live)
res = check_output( res = check_output(
'{}fanficfare -u "{}" --force --update-cover'.format( '{}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) check_regexes(res)
cur = get_files(loc, '.epub', True)[0] cur = get_files(loc, '.epub', True)[0]
@ -185,25 +182,25 @@ def downloader(args):
shell=True, shell=True,
stderr=STDOUT, stderr=STDOUT,
stdin=PIPE, stdin=PIPE,
) ).decode('utf-8')
except BaseException: except BaseException:
if not live: if not live:
print output.strip() print(output.strip())
raise raise
output += log("\tAdding {} to library".format(cur), 'BLUE', live) output += log("\tAdding {} to library".format(cur), 'BLUE', live)
try: try:
res = check_output( 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: except Exception as e:
output += log(e) output += log(e)
if not live: if not live:
print output.strip() print(output.strip())
raise raise
try: try:
res = check_output( res = check_output(
'calibredb search "Identifiers:{}" {}'.format( '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, output += log("\tAdded {} to library with id {}".format(cur,
res), 'GREEN', live) res), 'GREEN', live)
except BaseException: except BaseException:
@ -216,7 +213,7 @@ def downloader(args):
else: else:
res = check_output( res = check_output(
'cd "{}" && fanficfare -u "{}" --update-cover'.format( '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) check_regexes(res)
cur = get_files(loc, '.epub', True)[0] cur = get_files(loc, '.epub', True)[0]
name = get_files(loc, '.epub', False)[0] name = get_files(loc, '.epub', False)[0]
@ -228,12 +225,12 @@ def downloader(args):
'GREEN', 'GREEN',
live) live)
if not live: if not live:
print output.strip() print(output.strip())
rmtree(loc) rmtree(loc)
except Exception as e: except Exception as e:
output += log("Exception: {}".format(e), 'FAIL', live) output += log("Exception: {}".format(e), 'FAIL', live)
if not live: if not live:
print output.strip() print(output.strip())
try: try:
rmtree(loc) rmtree(loc)
except BaseException: except BaseException:
@ -409,7 +406,6 @@ if __name__ == "__main__":
if not (options.user or options.password): if not (options.user or options.password):
raise ValueError("User or Password not given") raise ValueError("User or Password not given")
main( main(
options.user, options.user,
options.password, options.password,

View File

@ -1,4 +1,4 @@
from StringIO import StringIO from io import StringIO
import re import re
from subprocess import check_output, STDOUT from subprocess import check_output, STDOUT
@ -9,7 +9,7 @@ from notifications import Notification
from pushbullet import Pushbullet from pushbullet import Pushbullet
from optparse import OptionParser from optparse import OptionParser
from ConfigParser import ConfigParser from configparser import ConfigParser
def enable_notifications(options): def enable_notifications(options):
@ -18,13 +18,13 @@ def enable_notifications(options):
try: try:
pb = Pushbullet(options.pushbullet) pb = Pushbullet(options.pushbullet)
except BaseException: except BaseException:
print "Problem wtih connecting to pushbullet. API Key likely invalid" print("Problem wtih connecting to pushbullet. API Key likely invalid")
fail = True fail = True
if options.pbdevice and not fail: if options.pbdevice and not fail:
try: try:
pb = pb.get_device(options.pbdevice) pb = pb.get_device(options.pbdevice)
except BaseException: except BaseException:
print "Cannot get this device." print("Cannot get this device.")
fail = True fail = True
pass pass
if not fail: if not fail:
@ -45,16 +45,17 @@ def touch(fname, times=None):
def main(options): def main(options):
try: try:
res = check_output( res = check_output(
"python fanficdownload.py -c config.ini", "python3 fanficdownload.py -c config.ini",
shell=True, shell=True,
stderr=STDOUT) stderr=STDOUT)
except Exception as e: except Exception as e:
print e print(e)
res = None res = None
if not res: if not res:
return return
else: else:
print res res = res.decode('utf-8')
print(res)
buf = StringIO(res) buf = StringIO(res)
regex = re.compile("Added (?:.*/)?(.*)-.* to library with id \d*") regex = re.compile("Added (?:.*/)?(.*)-.* to library with id \d*")
searcher = regex.search searcher = regex.search