mylar/mylar/cmtagmylar.py

290 lines
13 KiB
Python

# This script was taken almost entirely from Manders2600 Script with the use of the awesome ComicTagger.
# modified very slightly so Mylar just passes it the IssueID for it to do it's magic.
import os, errno
import sys
import re
import glob
import shlex
import platform
import shutil
import time
import zipfile
import subprocess
from subprocess import CalledProcessError, check_output
import mylar
from mylar import logger
def run(dirName, nzbName=None, issueid=None, comversion=None, manual=None, filename=None, module=None, manualmeta=False):
if module is None:
module = ''
module += '[META-TAGGER]'
logger.fdebug(module + ' dirName:' + dirName)
# 2015-11-23: Recent CV API changes restrict the rate-limit to 1 api request / second.
# ComicTagger has to be included now with the install as a timer had to be added to allow for the 1/second rule.
comictagger_cmd = os.path.join(mylar.CMTAGGER_PATH, 'comictagger.py')
logger.fdebug('ComicTagger Path location for internal comictagger.py set to : ' + comictagger_cmd)
# Force mylar to use cmtagger_path = mylar.PROG_DIR to force the use of the included lib.
logger.fdebug(module + ' Filename is : ' + filename)
filepath = filename
og_filepath = filepath
try:
filename = os.path.split(filename)[1] # just the filename itself
except:
logger.warn('Unable to detect filename within directory - I am aborting the tagging. You best check things out.')
return "fail"
#make use of temporary file location in order to post-process this to ensure that things don't get hammered when converting
new_filepath = None
new_folder = None
try:
import tempfile
logger.fdebug('Filepath: %s' %filepath)
logger.fdebug('Filename: %s' %filename)
new_folder = tempfile.mkdtemp(prefix='mylar_', dir=mylar.CONFIG.CACHE_DIR) #prefix, suffix, dir
logger.fdebug('New_Folder: %s' % new_folder)
new_filepath = os.path.join(new_folder, filename)
logger.fdebug('New_Filepath: %s' % new_filepath)
if mylar.CONFIG.FILE_OPTS == 'copy' and manualmeta == False:
shutil.copy(filepath, new_filepath)
else:
shutil.copy(filepath, new_filepath)
filepath = new_filepath
except Exception as e:
logger.warn('%s Unexpected Error: %s [%s]' % (module, sys.exc_info()[0], e))
logger.warn(module + ' Unable to create temporary directory to perform meta-tagging. Processing without metatagging.')
tidyup(og_filepath, new_filepath, new_folder, manualmeta)
return "fail"
## Sets up other directories ##
scriptname = os.path.basename(sys.argv[0])
downloadpath = os.path.abspath(dirName)
sabnzbdscriptpath = os.path.dirname(sys.argv[0])
comicpath = new_folder
logger.fdebug(module + ' Paths / Locations:')
logger.fdebug(module + ' scriptname : ' + scriptname)
logger.fdebug(module + ' downloadpath : ' + downloadpath)
logger.fdebug(module + ' sabnzbdscriptpath : ' + sabnzbdscriptpath)
logger.fdebug(module + ' comicpath : ' + comicpath)
logger.fdebug(module + ' Running the ComicTagger Add-on for Mylar')
##set up default comictagger options here.
#used for cbr - to - cbz conversion
#depending on copy/move - eitehr we retain the rar or we don't.
if mylar.CONFIG.FILE_OPTS == 'move':
cbr2cbzoptions = ["-e", "--delete-rar"]
else:
cbr2cbzoptions = ["-e"]
tagoptions = ["-s"]
if mylar.CONFIG.CMTAG_VOLUME:
if mylar.CONFIG.CMTAG_START_YEAR_AS_VOLUME:
comversion = str(comversion)
else:
if any([comversion is None, comversion == '', comversion == 'None']):
comversion = '1'
comversion = re.sub('[^0-9]', '', comversion).strip()
cvers = 'volume=' + str(comversion)
else:
cvers = "volume="
tagoptions.extend(["-m", cvers])
try:
ctversion = subprocess.check_output([sys.executable, comictagger_cmd, "--version"], stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
#logger.warn(module + "[WARNING] "command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output))
logger.warn(module + '[WARNING] Make sure that you are using the comictagger included with Mylar.')
tidyup(filepath, new_filepath, new_folder, manualmeta)
return "fail"
ctend = ctversion.find('\n')
ctcheck = re.sub("[^0-9]", "", ctversion[:ctend])
ctcheck = re.sub('\.', '', ctcheck).strip()
if int(ctcheck) >= int('1115'): # (v1.1.15)
if any([mylar.CONFIG.COMICVINE_API == 'None', mylar.CONFIG.COMICVINE_API is None]):
logger.fdebug(module + ' ' + ctversion[:ctend] + ' being used - no personal ComicVine API Key supplied. Take your chances.')
use_cvapi = "False"
else:
logger.fdebug(module + ' ' + ctversion[:ctend] + ' being used - using personal ComicVine API key supplied via mylar.')
use_cvapi = "True"
tagoptions.extend(["--cv-api-key", mylar.CONFIG.COMICVINE_API])
else:
logger.fdebug(module + ' ' + ctversion[:ctend+1] + ' being used - personal ComicVine API key not supported in this version. Good luck.')
use_cvapi = "False"
i = 1
tagcnt = 0
if mylar.CONFIG.CT_TAG_CR:
tagcnt = 1
logger.fdebug(module + ' CR Tagging enabled.')
if mylar.CONFIG.CT_TAG_CBL:
if not mylar.CONFIG.CT_TAG_CR: i = 2 #set the tag to start at cbl and end without doing another tagging.
tagcnt = 2
logger.fdebug(module + ' CBL Tagging enabled.')
if tagcnt == 0:
logger.warn(module + ' You have metatagging enabled, but you have not selected the type(s) of metadata to write. Please fix and re-run manually')
tidyup(filepath, new_filepath, new_folder, manualmeta)
return "fail"
#if it's a cbz file - check if no-overwrite existing tags is enabled / disabled in config.
if filename.endswith('.cbz'):
if mylar.CONFIG.CT_CBZ_OVERWRITE:
logger.fdebug(module + ' Will modify existing tag blocks even if it exists.')
else:
logger.fdebug(module + ' Will NOT modify existing tag blocks even if they exist already.')
tagoptions.extend(["--nooverwrite"])
if issueid is None:
tagoptions.extend(["-f", "-o"])
else:
tagoptions.extend(["-o", "--id", issueid])
original_tagoptions = tagoptions
og_tagtype = None
initial_ctrun = True
error_remove = False
while (i <= tagcnt):
if initial_ctrun:
f_tagoptions = cbr2cbzoptions
f_tagoptions.extend([filepath])
else:
if i == 1:
tagtype = 'cr' # CR meta-tagging cycle.
tagdisp = 'ComicRack tagging'
elif i == 2:
tagtype = 'cbl' # Cbl meta-tagging cycle
tagdisp = 'Comicbooklover tagging'
f_tagoptions = original_tagoptions
if og_tagtype is not None:
for index, item in enumerate(f_tagoptions):
if item == og_tagtype:
f_tagoptions[index] = tagtype
else:
f_tagoptions.extend(["--type", tagtype, filepath])
og_tagtype = tagtype
logger.info(module + ' ' + tagdisp + ' meta-tagging processing started.')
currentScriptName = [sys.executable, comictagger_cmd]
script_cmd = currentScriptName + f_tagoptions
if initial_ctrun:
logger.fdebug(module + ' Enabling ComicTagger script: ' + str(currentScriptName) + ' with options: ' + str(f_tagoptions))
script_cmdlog = script_cmd
else:
logger.fdebug(module + ' Enabling ComicTagger script: ' + str(currentScriptName) + ' with options: ' + re.sub(f_tagoptions[f_tagoptions.index(mylar.CONFIG.COMICVINE_API)], 'REDACTED', str(f_tagoptions)))
# generate a safe command line string to execute the script and provide all the parameters
script_cmdlog = re.sub(f_tagoptions[f_tagoptions.index(mylar.CONFIG.COMICVINE_API)], 'REDACTED', str(script_cmd))
logger.fdebug(module + ' Executing command: ' +str(script_cmdlog))
logger.fdebug(module + ' Absolute path to script: ' +script_cmd[0])
try:
# use subprocess to run the command and capture output
p = subprocess.Popen(script_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
out, err = p.communicate()
#logger.info(out)
#logger.info(err)
if initial_ctrun and 'exported successfully' in out:
logger.fdebug(module + '[COMIC-TAGGER] : ' +str(out))
#Archive exported successfully to: X-Men v4 008 (2014) (Digital) (Nahga-Empire).cbz (Original deleted)
if 'Error deleting' in filepath:
tf1 = out.find('exported successfully to: ')
tmpfilename = out[tf1 + len('exported successfully to: '):].strip()
error_remove = True
else:
tmpfilename = re.sub('Archive exported successfully to: ', '', out.rstrip())
if mylar.CONFIG.FILE_OPTS == 'move':
tmpfilename = re.sub('\(Original deleted\)', '', tmpfilename).strip()
tmpf = tmpfilename.decode('utf-8')
filepath = os.path.join(comicpath, tmpf)
if filename.lower() != tmpf.lower() and tmpf.endswith('(1).cbz'):
logger.fdebug('New filename [%s] is named incorrectly due to duplication during metatagging - Making sure it\'s named correctly [%s].' % (tmpf, filename))
tmpfilename = filename
filepath_new = os.path.join(comicpath, tmpfilename)
try:
os.rename(filepath, filepath_new)
filepath = filepath_new
except:
logger.warn('%s unable to rename file to accomodate metatagging cbz to the same filename' % module)
if not os.path.isfile(filepath):
logger.fdebug(module + 'Trying utf-8 conversion.')
tmpf = tmpfilename.encode('utf-8')
filepath = os.path.join(comicpath, tmpf)
if not os.path.isfile(filepath):
logger.fdebug(module + 'Trying latin-1 conversion.')
tmpf = tmpfilename.encode('Latin-1')
filepath = os.path.join(comicpath, tmpf)
logger.fdebug(module + '[COMIC-TAGGER][CBR-TO-CBZ] New filename: ' + filepath)
initial_ctrun = False
elif initial_ctrun and 'Archive is not a RAR' in out:
logger.fdebug('%s Output: %s' % (module,out))
logger.warn(module + '[COMIC-TAGGER] file is not in a RAR format: ' + filename)
initial_ctrun = False
elif initial_ctrun:
initial_ctrun = False
if 'file is not expected size' in out:
logger.fdebug('%s Output: %s' % (module,out))
tidyup(og_filepath, new_filepath, new_folder, manualmeta)
return 'corrupt'
else:
logger.warn(module + '[COMIC-TAGGER][CBR-TO-CBZ] Failed to convert cbr to cbz - check permissions on folder : ' + mylar.CONFIG.CACHE_DIR + ' and/or the location where Mylar is trying to tag the files from.')
tidyup(og_filepath, new_filepath, new_folder, manualmeta)
return 'fail'
elif 'Cannot find' in out:
logger.fdebug('%s Output: %s' % (module,out))
logger.warn(module + '[COMIC-TAGGER] Unable to locate file: ' + filename)
file_error = 'file not found||' + filename
return file_error
elif 'not a comic archive!' in out:
logger.fdebug('%s Output: %s' % (module,out))
logger.warn(module + '[COMIC-TAGGER] Unable to locate file: ' + filename)
file_error = 'file not found||' + filename
return file_error
else:
logger.info(module + '[COMIC-TAGGER] Successfully wrote ' + tagdisp + ' [' + filepath + ']')
i+=1
except OSError, e:
logger.warn(module + '[COMIC-TAGGER] Unable to run comictagger with the options provided: ' + re.sub(f_tagoptions[f_tagoptions.index(mylar.CONFIG.COMICVINE_API)], 'REDACTED', str(script_cmd)))
tidyup(filepath, new_filepath, new_folder, manualmeta)
return "fail"
if mylar.CONFIG.CBR2CBZ_ONLY and initial_ctrun == False:
break
return filepath
def tidyup(filepath, new_filepath, new_folder, manualmeta):
if all([new_filepath is not None, new_folder is not None]):
if mylar.CONFIG.FILE_OPTS == 'copy' and manualmeta == False:
if all([os.path.exists(new_folder), os.path.isfile(filepath)]):
shutil.rmtree(new_folder)
elif os.path.exists(new_filepath) and not os.path.exists(filepath):
shutil.move(new_filepath, filepath + '.BAD')
else:
if os.path.exists(new_filepath) and not os.path.exists(filepath):
shutil.move(new_filepath, filepath + '.BAD')
if all([os.path.exists(new_folder), os.path.isfile(filepath)]):
shutil.rmtree(new_folder)