IMP:(#732) manageComics now sortable, Status column included, have counts tally correctly, FIX:(#729) if cover image did not exist on CV, would error - now will attempt alternate size, IMP: Option added to search results to allow explicit searching (meaning will search for ONLY terms, instead of default of ALL), FIX:(#730) typo, IMP:(#719) Configuration/Advanced/Notify on manual post-processing of torrents option added now - will notify on post-processing of snatched torrents, IMP: Added some more threading for performance (marking issues as wanted will now thread instead of run & wait)

This commit is contained in:
evilhero 2014-06-02 15:02:28 -04:00
parent 1fa44a7121
commit cdd409016e
11 changed files with 283 additions and 210 deletions

View File

@ -364,7 +364,7 @@
</td>
<td id="options">
%if issue['Status'] == 'Skipped' or issue['Status'] == 'Ignored':
<a href="#" title="Mark issue as Wanted" onclick="doAjaxCall('queueissue?ComicID=${issue['ComicID']}&IssueID=${issue['IssueID']}&ComicIssue=${issue['Issue_Number']}&ComicYear=${issue['IssueDate']}&mode=want',$(this),'table')"><img src="interfaces/default/images/wanted_icon.png" height="25" width="25" /></a>
<a href="#" title="Mark issue as Wanted" onclick="doAjaxCall('queueissue?ComicID=${issue['ComicID']}&IssueID=${issue['IssueID']}&ComicIssue=${issue['Issue_Number']}&ComicYear=${issue['IssueDate']}&mode=want',$(this),'table')" data-success="Issue Marked as Wanted"><img src="interfaces/default/images/wanted_icon.png" height="25" width="25" /></a>
%elif (issue['Status'] == 'Wanted'):
<a href="#" title="Mark issue as Skipped" onclick="doAjaxCall('unqueueissue?IssueID=${issue['IssueID']}&ComicID=${issue['ComicID']}',$(this),'table')" data-success="'${issue['Issue_Number']}' has been marked as skipped"><img src="interfaces/default/images/skipped_icon.png" height="25" width="25" /></a>
%elif (issue['Status'] == 'Snatched'):

View File

@ -251,14 +251,14 @@
<div class="row">
<label>SAB Priority</label>
<select name="sab_priority">
%for prio in ['Default', 'Low', 'Normal', 'High', 'Paused']:
%for prio in ['Default', 'Low', 'Normal', 'High', 'Paused']:
<%
if config['sab_priority'] == prio:
outputselect = 'selected'
else:
outputselect = ''
%>
<option value=${prio} ${outputselect}>${prio}</option>
<option value=${prio} ${outputselect}>${prio}</option>
%endfor
</select>
</div>
@ -706,6 +706,9 @@
<input type="checkbox" style="vertical-align: middle; margin: 3px; margin-top: -1px;" name="autowant_all" value="1" ${config['autowant_all']} /><label>Automatically Mark All Issues as Wanted</label>
<input type="checkbox" style="vertical-align: middle; margin: 3px; margin-top: -1px;" name="comic_cover_local" value="1" ${config['comic_cover_local']} /><label>Place cover.jpg into Comic Directory for each comic</label>
<input type="checkbox" style="vertical-align: middle; margin: 3px; margin-top: -1px;" name="cvinfo" value="1" ${config['cvinfo']} /><label>Write cvinfo into each comic directory</label>
%if mylar.ENABLE_TORRENTS:
<input type="checkbox" style="vertical-align: middle; margin: 3px; margin-top: -1px;" name="snatchedtorrent_notify" value="1" ${config['snatchedtorrent_notify']} /><label>Manual Post-Processing - Notify on Completed Torrents</label>
%endif
</div>
</fieldset>

View File

@ -44,34 +44,14 @@
</thead>
<tbody>
%for comic in comics:
<%
totaltracks = comic['Total']
havetracks = comic['Have']
if not havetracks:
havetracks = 0
try:
percent = (havetracks*100.0)/totaltracks
if percent > 100:
percent = 100
except (ZeroDivisionError, TypeError):
percent = 0
totaltracks = '?'
if comic['Status'] == 'Paused':
grade = 'X'
elif comic['Status'] == 'Loading':
grade = 'C'
else:
grade = 'Z'
%>
<tr class="grade${grade}">
<tr>
<td id="select"><input type="checkbox" name="${comic['ComicID']}" class="checkbox" /></td>
<td id="albumart"><div><img src="${comic['ComicImage']}" height="75" width="50"></div></td>
<td id="name"><span title="${comic['ComicSortName']}"></span><a href="comicDetails?ComicID=${comic['ComicID']}">${comic['ComicName']} (${comic['ComicYear']})</a></td>
<td id="status">${comic['Status']}</td>
<td id="status">${comic['recentstatus']}</td>
<td id="latest">${comic['LatestIssue']} (${comic['LatestDate']})</td>
<td id="publisher">${comic['ComicPublisher']}</td>
<td id="have" valign="center"><span title="${percent}"></span><div class="progress-container"><div style="width:${percent}%"><div style="width:${percent}%"><div class="havetracks">${havetracks}/${totaltracks}</div></div></div></td>
<td id="have" valign="center"><span title="${comic['percent']}"></span><div class="progress-container"><div style="width:${comic['percent']}%"><div style="width:${comic['percent']}%"><div class="havetracks">${comic['haveissues']}/${comic['totalissues']}</div></div></div></td>
<td id="lastupdated">${comic['DateAdded']}</td>
</tr>
%endfor
@ -98,31 +78,36 @@
}
});
}
function initThisPage() {
getArtistArt();
$('#manage_comic').dataTable(
{
"bDestroy": true,
"aoColumnDefs": [
{ 'bSortable': false, 'aTargets': [ 0, 1 ] }
],
"aLengthMenu": [[10, 25, 50, -1], [10, 25, 50, 'All' ]],
"oLanguage": {
"sLengthMenu":"Show _MENU_ results per page",
"sEmptyTable": "No results",
"sInfo":"Showing _START_ to _END_ of _TOTAL_ results",
"sInfoEmpty":"Showing 0 to 0 of 0 results",
"sInfoFiltered":"(filtered from _MAX_ total results)",
"sSearch" : ""},
"bStateSave": true,
"iDisplayLength": 25,
"sPaginationType": "full_numbers",
"aaSorting": [[2, 'desc'],[3, 'desc']]
});
resetFilters("comic");
}
$(document).ready(function(){
initThisPage();
});
$(window).load(function(){
initFancybox();
});
</script>
function initThisPage() {
getArtistArt();
$('#artist_table').dataTable({
"bDestroy":true,
"aoColumns": [
null,
null,
{ "sType": "title-string"},
null,
{ "sType": "title-string"},
null
],
"oLanguage": {
"sSearch" : ""},
"bStateSave": true,
"bPaginate": false
});
resetFilters("comics");
}
$(document).ready(function() {
initThisPage();
});
$(window).load(function(){
initFancybox();
});
</script>
</%def>

View File

@ -1,17 +1,35 @@
<%inherit file="base.html" />
<%def name="headerIncludes()">
<div id="subhead_container">
<div id="subhead_menu">
%if explicit:
<a id="menu_link_delete" title="This will search for any of the terms given : ${name}" href="searchit?name=${name |u}&explicit=True">Explicit Search</a>
%else:
<a id="menu_link_delete" title="This will search explicitly for only the terms given : ${name}" href="searchit?name=${name |u}&explicit=True">Explicit Search</a>
%endif
</div>
</div>
</%def>
<%def name="body()">
<div class="table_wrapper">
<div id="paddingheader">
<h1 class="clearfix"><img src="interfaces/default/images/icon_search.png" alt="Search results"/>Search Result</h1>
</div>
<%
if explicit:
searchtext = "Explicit Search results for: </br><center> " + name + "</center>"
else:
searchtext = "Search results for : </br><center>" + name + "</center>"
%>
<h1 class="clearfix"><img src="interfaces/default/images/icon_search.png" alt="Search results"/>${searchtext}</h1>
</div>
<div class="table_wrapper">
<table class="display" id="searchresults_table">
<thead>
<tr>
<th id="blank"></th>
<th id="name">Comic Name</th>
<th id="publisher">Publisher</th>
<th id="comicyear">Year</th>
<th id="publisher">Publisher</th>
<th id="comicyear">Year</th>
<th id="issues">Issues</th>
<th id="add"></th>
</tr>
@ -20,7 +38,7 @@
%if searchresults:
%for result in searchresults:
<%
if result['comicyear'] == '2013':
if result['comicyear'] == '2014':
grade = 'A'
else:
grade = 'Z'
@ -50,42 +68,36 @@
<script src="js/libs/jquery.dataTables.min.js"></script>
<script>
function getArt() {
$("table#searchresults_table tr td#comicimage img").each(function(){
var id = $(this).attr('title');
var image = $(this);
if ( !image.hasClass('done') ) {
image.addClass('done');
getImageLinks(image,id,"${type}");
}
});
}
function initThisPage() {
getArt();
function initThisPage(){
initActions();
$('#searchresults_table').dataTable(
{
"bDestroy": true,
"aoColumnDefs": [
{ 'bSortable': false, 'aTargets': [ 0,3 ] }
],
"oLanguage": {
"sLengthMenu":"Show _MENU_ results per page",
"sEmptyTable": "No results",
"sInfo":"Showing _START_ to _END_ of _TOTAL_ results",
"sInfoEmpty":"Showing 0 to 0 of 0 results",
"sInfoFiltered":"(filtered from _MAX_ total results)",
"sSearch" : ""},
"iDisplayLength": 25,
"sPaginationType": "full_numbers",
"aaSorting": []
});
resetFilters("result");
}
$(document).ready(function(){
initThisPage();
});
$(window).load(function(){
initFancybox();
});
"bDestroy": true,
"aoColumnDefs": [
{ 'bSortable': false, 'aTargets': [ 0,3 ] }
],
"oLanguage": {
"sLengthMenu":"Show _MENU_ results per page",
"sEmptyTable": "No results",
"sInfo":"Showing _START_ to _END_ of _TOTAL_ results",
"sInfoEmpty":"Showing 0 to 0 of 0 results",
"sInfoFiltered":"(filtered from _MAX_ total results)",
"sSearch" : ""},
"iDisplayLength": 25,
"sPaginationType": "full_numbers",
"aaSorting": []
});
resetFilters("result");
setTimeout(function(){
initFancybox();
},1500);
}
$(document).ready(function() {
initThisPage();
});
</script>
</%def>

View File

@ -470,9 +470,17 @@ class PostProcessor(object):
def Process_next(self,comicid,issueid,issuenumOG,ml=None):
annchk = "no"
extensions = ('.cbr', '.cbz')
snatchedtorrent = False
myDB = db.DBConnection()
comicnzb = myDB.selectone("SELECT * from comics WHERE comicid=?", [comicid]).fetchone()
issuenzb = myDB.selectone("SELECT * from issues WHERE issueid=? AND comicid=? AND ComicName NOT NULL", [issueid,comicid]).fetchone()
if ml is not None and mylar.SNATCHEDTORRENT_NOTIFY:
snatchnzb = myDB.selectone("SELECT * from snatched WHERE IssueID=? AND ComicID=? AND (provider=? OR provider=?) AND Status='Snatched'", [issueid,comicid,'KAT','CBT']).fetchone()
if snatchnzb is None:
logger.fdebug('Was not downloaded with Mylar and the usage of torrents. Disabling torrent manual post-processing completion notification.')
else:
logger.fdebug('Was downloaded from ' + snatchnzb['Provider'] + '. Enabling torrent manual post-processing completion notification.')
snatchedtorrent = True
logger.fdebug('issueid: ' + str(issueid))
logger.fdebug('issuenumOG: ' + str(issuenumOG))
if issuenzb is None:
@ -852,7 +860,7 @@ class PostProcessor(object):
#force rescan of files
updater.forceRescan(comicid)
logger.info(u"Post-Processing completed for: " + series + " " + dispiss )
self._log(u"Post Processing SUCCESSFULL! ")
self._log(u"Post Processing SUCCESSFUL! ")
# retrieve/create the corresponding comic objects
if mylar.ENABLE_EXTRA_SCRIPTS:
@ -875,37 +883,43 @@ class PostProcessor(object):
seriesmetadata['seriesmeta'] = seriesmeta
self._run_extra_scripts(nzbn, self.nzb_folder, filen, folderp, seriesmetadata )
if ml is not None:
return self.log
else:
if annchk == "no":
prline = series + '(' + issueyear + ') - issue #' + issuenumOG
if ml is not None:
#we only need to return self.log if it's a manual run and it's not a snatched torrent
if snatchedtorrent:
#manual run + snatched torrent
pass
else:
prline = series + ' Annual (' + issueyear + ') - issue #' + issuenumOG
prline2 = 'Mylar has downloaded and post-processed: ' + prline
#manual run + not snatched torrent (or normal manual-run)
return self.log
if mylar.PROWL_ENABLED:
pushmessage = prline
logger.info(u"Prowl request")
prowl = notifiers.PROWL()
prowl.notify(pushmessage,"Download and Postprocessing completed")
if annchk == "no":
prline = series + '(' + issueyear + ') - issue #' + issuenumOG
else:
prline = series + ' Annual (' + issueyear + ') - issue #' + issuenumOG
prline2 = 'Mylar has downloaded and post-processed: ' + prline
if mylar.PROWL_ENABLED:
pushmessage = prline
logger.info(u"Prowl request")
prowl = notifiers.PROWL()
prowl.notify(pushmessage,"Download and Postprocessing completed")
if mylar.NMA_ENABLED:
nma = notifiers.NMA()
nma.notify(prline=prline, prline2=prline2)
if mylar.NMA_ENABLED:
nma = notifiers.NMA()
nma.notify(prline=prline, prline2=prline2)
if mylar.PUSHOVER_ENABLED:
logger.info(u"Pushover request")
pushover = notifiers.PUSHOVER()
pushover.notify(prline, "Download and Post-Processing completed")
if mylar.PUSHOVER_ENABLED:
logger.info(u"Pushover request")
pushover = notifiers.PUSHOVER()
pushover.notify(prline, "Download and Post-Processing completed")
if mylar.BOXCAR_ENABLED:
boxcar = notifiers.BOXCAR()
boxcar.notify(prline=prline, prline2=prline2)
if mylar.BOXCAR_ENABLED:
boxcar = notifiers.BOXCAR()
boxcar.notify(prline=prline, prline2=prline2)
if mylar.PUSHBULLET_ENABLED:
pushbullet = notifiers.PUSHBULLET()
pushbullet.notify(prline=prline, prline2=prline2)
if mylar.PUSHBULLET_ENABLED:
pushbullet = notifiers.PUSHBULLET()
pushbullet.notify(prline=prline, prline2=prline2)
return self.log

View File

@ -278,7 +278,7 @@ KAT_PROXY = None
ENABLE_CBT = 0
CBT_PASSKEY = None
SNATCHEDTORRENT_NOTIFY = 0
def CheckSection(sec):
""" Check if INI section exists, if not create it """
@ -341,7 +341,7 @@ def initialize():
ENABLE_META, CMTAGGER_PATH, INDIE_PUB, BIGGIE_PUB, IGNORE_HAVETOTAL, PROVIDER_ORDER, \
dbUpdateScheduler, searchScheduler, RSSScheduler, WeeklyScheduler, VersionScheduler, FolderMonitorScheduler, \
ENABLE_TORRENTS, MINSEEDS, TORRENT_LOCAL, LOCAL_WATCHDIR, TORRENT_SEEDBOX, SEEDBOX_HOST, SEEDBOX_PORT, SEEDBOX_USER, SEEDBOX_PASS, SEEDBOX_WATCHDIR, \
ENABLE_RSS, RSS_CHECKINTERVAL, RSS_LASTRUN, ENABLE_TORRENT_SEARCH, ENABLE_KAT, KAT_PROXY, ENABLE_CBT, CBT_PASSKEY, \
ENABLE_RSS, RSS_CHECKINTERVAL, RSS_LASTRUN, ENABLE_TORRENT_SEARCH, ENABLE_KAT, KAT_PROXY, ENABLE_CBT, CBT_PASSKEY, SNATCHEDTORRENT_NOTIFY, \
PROWL_ENABLED, PROWL_PRIORITY, PROWL_KEYS, PROWL_ONSNATCH, NMA_ENABLED, NMA_APIKEY, NMA_PRIORITY, NMA_ONSNATCH, PUSHOVER_ENABLED, PUSHOVER_PRIORITY, PUSHOVER_APIKEY, PUSHOVER_USERKEY, PUSHOVER_ONSNATCH, BOXCAR_ENABLED, BOXCAR_ONSNATCH, BOXCAR_TOKEN, \
PUSHBULLET_ENABLED, PUSHBULLET_APIKEY, PUSHBULLET_DEVICEID, PUSHBULLET_ONSNATCH, LOCMOVE, NEWCOM_DIR, FFTONEWCOM_DIR, \
PREFERRED_QUALITY, MOVE_FILES, RENAME_FILES, LOWERCASE_FILENAMES, USE_MINSIZE, MINSIZE, USE_MAXSIZE, MAXSIZE, CORRECT_METADATA, FOLDER_FORMAT, FILE_FORMAT, REPLACE_CHAR, REPLACE_SPACES, ADD_TO_CSV, CVINFO, LOG_LEVEL, POST_PROCESSING, SEARCH_DELAY, GRABBAG_DIR, READ2FILENAME, STORYARCDIR, CVURL, CVAPIFIX, CHECK_FOLDER, \
@ -525,7 +525,8 @@ def initialize():
KAT_PROXY = check_setting_str(CFG, 'Torrents', 'kat_proxy', '')
ENABLE_CBT = bool(check_setting_int(CFG, 'Torrents', 'enable_cbt', 0))
CBT_PASSKEY = check_setting_str(CFG, 'Torrents', 'cbt_passkey', '')
SNATCHEDTORRENT_NOTIFY = bool(check_setting_int(CFG, 'Torrents', 'snatchedtorrent_notify', 0))
#this needs to have it's own category - for now General will do.
NZB_DOWNLOADER = check_setting_int(CFG, 'General', 'nzb_downloader', 0)
#legacy support of older config - reload into old values for consistency.
@ -1102,7 +1103,7 @@ def config_write():
new_config['Torrents']['kat_proxy'] = KAT_PROXY
new_config['Torrents']['enable_cbt'] = int(ENABLE_CBT)
new_config['Torrents']['cbt_passkey'] = CBT_PASSKEY
new_config['Torrents']['snatchedtorrent_notify'] = int(SNATCHEDTORRENT_NOTIFY)
new_config['SABnzbd'] = {}
#new_config['SABnzbd']['use_sabnzbd'] = int(USE_SABNZBD)
new_config['SABnzbd']['sab_host'] = SAB_HOST

View File

@ -150,6 +150,12 @@ def GetComicInfo(comicid,dom):
except:
comic_deck = 'None'
try:
comic['Aliases'] = dom.getElementsByTagName('aliases')[0].firstChild.wholeText
#logger.fdebug('Aliases: ' + str(aliases))
except:
comic['Aliases'] = 'None'
comic['ComicVersion'] = 'noversion'
#logger.info('comic_desc:' + comic_desc)
#logger.info('comic_deck:' + comic_deck)
@ -224,7 +230,9 @@ def GetComicInfo(comicid,dom):
comic['ComicIssues'] = str(cntit)
else:
comic['ComicIssues'] = dom.getElementsByTagName('count_of_issues')[0].firstChild.wholeText
comic['ComicImage'] = dom.getElementsByTagName('super_url')[0].firstChild.wholeText
comic['ComicImageALT'] = dom.getElementsByTagName('small_url')[0].firstChild.wholeText
try:
comic['ComicPublisher'] = dom.getElementsByTagName('name')[trackcnt+2].firstChild.wholeText

View File

@ -927,3 +927,93 @@ def LoadAlternateSearchNames(seriesname_alt, comicid):
#logger.info('AlternateNames returned:' + str(Alternate_Names))
return Alternate_Names
def havetotals():
import db, logger
comics = []
myDB = db.DBConnection()
comiclist = myDB.select('SELECT * from comics order by ComicSortName COLLATE NOCASE')
for comic in comiclist:
issue = myDB.select("SELECT * FROM issues WHERE ComicID=?", [comic['ComicID']])
if mylar.ANNUALS_ON:
annuals_on = True
annual = myDB.selectone("SELECT COUNT(*) as count FROM annuals WHERE ComicID=?", [comic['ComicID']]).fetchone()
annualcount = annual[0]
if not annualcount:
annualcount = 0
else:
annuals_on = False
annual = None
annualcount = 0
try:
totalissues = comic['Total'] + annualcount
haveissues = comic['Have']
except TypeError:
logger.warning('[Warning] ComicID: ' + str(comic['ComicID']) + ' is incomplete - Removing from DB. You should try to re-add the series.')
myDB.action("DELETE from COMICS WHERE ComicID=? AND ComicName LIKE 'Comic ID%'", [comic['ComicID']])
myDB.action("DELETE from ISSUES WHERE ComicID=? AND ComicName LIKE 'Comic ID%'", [comic['ComicID']])
continue
if not haveissues:
havetracks = 0
try:
percent = (haveissues*100.0)/totalissues
if percent > 100:
percent = 100
except (ZeroDivisionError, TypeError):
percent = 0
totalissuess = '?'
if comic['ComicPublished'] is None or comic['ComicPublished'] == '':
recentstatus = 'Unknown'
elif comic['ForceContinuing'] == 1:
recentstatus = 'Continuing'
elif 'present' in comic['ComicPublished'].lower() or ( today()[:4] in comic['LatestDate']):
latestdate = comic['LatestDate']
c_date = datetime.date(int(latestdate[:4]),int(latestdate[5:7]),1)
n_date = datetime.date.today()
recentchk = (n_date - c_date).days
if recentchk < 55:
recentstatus = 'Continuing'
else:
recentstatus = 'Ended'
else:
recentstatus = 'Ended'
comics.append({"ComicID": comic['ComicID'],
"ComicName": comic['ComicName'],
"ComicSortName": comic['ComicSortName'],
"ComicPublisher": comic['ComicPublisher'],
"ComicYear": comic['ComicYear'],
"ComicImage": comic['ComicImage'],
"LatestIssue": comic['LatestIssue'],
"LatestDate": comic['LatestDate'],
"ComicPublished": comic['ComicPublished'],
"Status": comic['Status'],
"recentstatus": recentstatus,
"percent": percent,
"totalissues": totalissues,
"haveissues": haveissues,
"DateAdded": comic['LastUpdated']})
return comics
from threading import Thread
class ThreadWithReturnValue(Thread):
def __init__(self, group=None, target=None, name=None,
args=(), kwargs={}, Verbose=None):
Thread.__init__(self, group, target, name, args, kwargs, Verbose)
self._return = None
def run(self):
if self._Thread__target is not None:
self._return = self._Thread__target(*self._Thread__args,
**self._Thread__kwargs)
def join(self):
Thread.join(self)
return self._return

View File

@ -411,7 +411,18 @@ def addComictoDB(comicid,mismatch=None,pullupd=None,imported=None,ogcname=None,c
except Exception, e:
logger.warn('[%s] Error fetching data using : %s' % (e, comic['ComicImage']))
logger.info('Attempting to use alternate image size to get cover.')
try:
cimage = re.sub('[\+]','%20', comic['ComicImageALT'])
request = urllib2.Request(cimage)
response = urllib2.urlopen(request)
com_image = response.read()
with open(coverfile, 'wb') as the_file:
the_file.write(com_image)
logger.info('Successfully retrieved cover for ' + comic['ComicName'])
except Exception, e:
logger.warn('[%s] Error fetching data using : %s' % (e, comic['ComicImageALT']))
PRComicImage = os.path.join('cache',str(comicid) + ".jpg")
ComicImage = helpers.replacetheslash(PRComicImage)

View File

@ -27,15 +27,19 @@ from mylar.helpers import multikeysort, replace_all, cleanName
mb_lock = threading.Lock()
def pullsearch(comicapi,comicquery,offset):
def pullsearch(comicapi,comicquery,offset,explicit):
u_comicquery = urllib.quote(comicquery.encode('utf-8').strip())
u_comicquery = u_comicquery.replace(" ", "%20")
# as of 02/15/2014 this is buggered up.
#PULLURL = mylar.CVURL + 'search?api_key=' + str(comicapi) + '&resources=volume&query=' + u_comicquery + '&field_list=id,name,start_year,site_detail_url,count_of_issues,image,publisher,description&format=xml&page=' + str(offset)
#FALSE
if explicit == False:
PULLURL = mylar.CVURL + 'search?api_key=' + str(comicapi) + '&resources=volume&query=' + u_comicquery + '&field_list=id,name,start_year,site_detail_url,count_of_issues,image,publisher,description&format=xml&offset=' + str(offset)
else:
#TRUE
# 02/22/2014 use the volume filter label to get the right results.
PULLURL = mylar.CVURL + 'volumes?api_key=' + str(comicapi) + '&filter=name:' + u_comicquery + '&field_list=id,name,start_year,site_detail_url,count_of_issues,image,publisher,description&format=xml&offset=' + str(offset) # 2012/22/02 - CVAPI flipped back to offset instead of page
PULLURL = mylar.CVURL + 'volumes?api_key=' + str(comicapi) + '&filter=name:' + u_comicquery + '&field_list=id,name,start_year,site_detail_url,count_of_issues,image,publisher,description&format=xml&offset=' + str(offset) # 2012/22/02 - CVAPI flipped back to offset instead of page
#all these imports are standard on most modern python implementations
#download the file:
@ -53,7 +57,7 @@ def pullsearch(comicapi,comicquery,offset):
dom = parseString(data)
return dom
def findComic(name, mode, issue, limityear=None):
def findComic(name, mode, issue, limityear=None, explicit=None):
#with mb_lock:
comiclist = []
@ -65,14 +69,23 @@ def findComic(name, mode, issue, limityear=None):
#print ("limityear: " + str(limityear))
if limityear is None: limityear = 'None'
comicquery = name
#comicquery=name.replace(" ", "%20")
#comicquery=name.replace(" ", " AND ")
if explicit is None:
logger.fdebug('explicit is None. Setting to False.')
explicit = False
if explicit:
logger.fdebug('changing to explicit mode.')
comicquery=name.replace(" ", " AND ")
else:
logger.fdebug('non-explicit mode.')
comicapi='583939a3df0a25fc4e8b7a29934a13078002dc27'
#let's find out how many results we get from the query...
searched = pullsearch(comicapi,comicquery,0)
searched = pullsearch(comicapi,comicquery,0,explicit)
if searched is None: return False
totalResults = searched.getElementsByTagName('number_of_total_results')[0].firstChild.wholeText
logger.fdebug("there are " + str(totalResults) + " search results...")
@ -85,7 +98,7 @@ def findComic(name, mode, issue, limityear=None):
#2012/22/02 - CV API flipped back to offset usage instead of page
offsetcount = countResults
searched = pullsearch(comicapi,comicquery,offsetcount)
searched = pullsearch(comicapi,comicquery,offsetcount,explicit)
comicResults = searched.getElementsByTagName('volume')
body = ''
n = 0

View File

@ -60,74 +60,7 @@ class WebInterface(object):
index.exposed=True
def home(self):
comics = []
myDB = db.DBConnection()
comiclist = myDB.select('SELECT * from comics order by ComicSortName COLLATE NOCASE')
for comic in comiclist:
issue = myDB.select("SELECT * FROM issues WHERE ComicID=?", [comic['ComicID']])
if mylar.ANNUALS_ON:
annuals_on = True
annual = myDB.selectone("SELECT COUNT(*) as count FROM annuals WHERE ComicID=?", [comic['ComicID']]).fetchone()
annualcount = annual[0]
if not annualcount:
annualcount = 0
else:
annuals_on = False
annual = None
annualcount = 0
try:
totalissues = comic['Total'] + annualcount
haveissues = comic['Have']
except TypeError:
logger.warning('[Warning] ComicID: ' + str(comic['ComicID']) + ' is incomplete - Removing from DB. You should try to re-add this again.')
myDB.action("DELETE from COMICS WHERE ComicID=? AND ComicName LIKE 'Comic ID%'", [comic['ComicID']])
myDB.action("DELETE from ISSUES WHERE ComicID=? AND ComicName LIKE 'Comic ID%'", [comic['ComicID']])
continue
if not haveissues:
havetracks = 0
try:
percent = (haveissues*100.0)/totalissues
if percent > 100:
percent = 100
except (ZeroDivisionError, TypeError):
percent = 0
totalissuess = '?'
if comic['ComicPublished'] is None or comic['ComicPublished'] == '':
recentstatus = 'Unknown'
elif comic['ForceContinuing'] == 1:
recentstatus = 'Continuing'
elif 'present' in comic['ComicPublished'].lower() or ( helpers.today()[:4] in comic['LatestDate']):
latestdate = comic['LatestDate']
c_date = datetime.date(int(latestdate[:4]),int(latestdate[5:7]),1)
n_date = datetime.date.today()
recentchk = (n_date - c_date).days
if recentchk < 55:
recentstatus = 'Continuing'
else:
recentstatus = 'Ended'
else:
recentstatus = 'Ended'
comics.append({"ComicID": comic['ComicID'],
"ComicName": comic['ComicName'],
"ComicSortName": comic['ComicSortName'],
"ComicPublisher": comic['ComicPublisher'],
"ComicYear": comic['ComicYear'],
"LatestIssue": comic['LatestIssue'],
"LatestDate": comic['LatestDate'],
"ComicPublished": comic['ComicPublished'],
"Status": comic['Status'],
"recentstatus": recentstatus,
"percent": percent,
"totalissues": totalissues,
"haveissues": haveissues})
comics = helpers.havetotals()
return serve_template(templatename="index.html", title="Home", comics=comics)
home.exposed = True
@ -230,7 +163,7 @@ class WebInterface(object):
return serve_template(templatename="comicdetails.html", title=comic['ComicName'], comic=comic, issues=issues, comicConfig=comicConfig, isCounts=isCounts, series=series, annuals=annuals, annualinfo=aName)
comicDetails.exposed = True
def searchit(self, name, issue=None, mode=None, type=None):
def searchit(self, name, issue=None, mode=None, type=None, explicit=None):
if type is None: type = 'comic' # let's default this to comic search only for the time being (will add story arc, characters, etc later)
else: logger.fdebug(str(type) + " mode enabled.")
#mode dictates type of search:
@ -249,7 +182,7 @@ class WebInterface(object):
logger.info('Attempting to add directly by ComicVineID: ' + str(comicid) + '. I sure hope you know what you are doing.')
threading.Thread(target=importer.addComictoDB, args=[comicid,mismatch,None]).start()
raise cherrypy.HTTPRedirect("comicDetails?ComicID=%s" % comicid)
searchresults = mb.findComic(name, mode, issue=None)
searchresults = mb.findComic(name, mode, issue=None, explicit=explicit)
elif type == 'comic' and mode == 'want':
searchresults = mb.findComic(name, mode, issue)
elif type == 'storyarc':
@ -257,7 +190,7 @@ class WebInterface(object):
searchresults = sorted(searchresults, key=itemgetter('comicyear','issues'), reverse=True)
#print ("Results: " + str(searchresults))
return serve_template(templatename="searchresults.html", title='Search Results for: "' + name + '"', searchresults=searchresults, type=type, imported=None, ogcname=None)
return serve_template(templatename="searchresults.html", title='Search Results for: "' + name + '"', searchresults=searchresults, type=type, imported=None, ogcname=None, name=name, explicit=explicit)
searchit.exposed = True
def addComic(self, comicid, comicname=None, comicyear=None, comicimage=None, comicissues=None, comicpublisher=None, imported=None, ogcname=None):
@ -474,8 +407,10 @@ class WebInterface(object):
threading.Thread(target=PostProcess.Process).start()
raise cherrypy.HTTPRedirect("home")
else:
result = PostProcess.Process()
return result
result = helpers.ThreadWithReturnValue(target=PostProcess.Process)
result.start()
#result = PostProcess.Process()
return result.join()
#log2screen = threading.Thread(target=PostProcessor.PostProcess, args=[nzb_name,nzb_folder]).start()
#return serve_template(templatename="postprocess.html", title="postprocess")
post_process.exposed = True
@ -961,7 +896,7 @@ class WebInterface(object):
logger.fdebug('month = ' + str(month))
logger.fdebug('year = ' + str(year))
threading.Thread(target=solicit.solicit, args=[month, year]).start()
raise cherrypy.HTTPRedirect("home")
raise cherrypy.HTTPRedirect("futurepulllist")
futurepull.exposed = True
def futurepulllist(self):
@ -1065,7 +1000,7 @@ class WebInterface(object):
# specify whether you want to 'add a series (Watch For)' or 'mark an issue as a one-off download'.
# currently the 'add series' option in the futurepulllist will attempt to add a series as per normal.
myDB = db.DBConnection()
chkfuture = myDB.select("SELECT * FROM futureupcoming WHERE IssueNumber is not NULL")
chkfuture = myDB.select("SELECT * FROM futureupcoming WHERE IssueNumber='1' OR IssueNumber='0'") #is not NULL")
if chkfuture is None:
logger.info("There are not any series on your future-list that I consider to be a NEW series")
raise cherrypy.HTTPRedirect("home")
@ -1217,7 +1152,7 @@ class WebInterface(object):
wantedcount = iss_cnt + ann_cnt
#let's straightload the series that have no issue data associated as of yet (ie. new series) from the futurepulllist
future_nodata_upcoming = myDB.select('SELECT * FROM futureupcoming')
future_nodata_upcoming = myDB.select("SELECT * FROM futureupcoming WHERE IssueNumber='1' OR IssueNumber='0'")
#let's move any items from the upcoming table into the wanted table if the date has already passed.
#gather the list...
@ -1341,8 +1276,7 @@ class WebInterface(object):
manage.exposed = True
def manageComics(self):
myDB = db.DBConnection()
comics = myDB.select('SELECT * from comics order by ComicSortName COLLATE NOCASE')
comics = helpers.havetotals()
return serve_template(templatename="managecomics.html", title="Manage Comics", comics=comics)
manageComics.exposed = True
@ -2409,6 +2343,7 @@ class WebInterface(object):
"enable_kat" : helpers.checked(mylar.ENABLE_KAT),
"enable_cbt" : helpers.checked(mylar.ENABLE_CBT),
"cbt_passkey" : mylar.CBT_PASSKEY,
"snatchedtorrent_notify" : mylar.SNATCHEDTORRENT_NOTIFY,
"destination_dir" : mylar.DESTINATION_DIR,
"chmod_dir" : mylar.CHMOD_DIR,
"chmod_file" : mylar.CHMOD_FILE,
@ -2642,7 +2577,7 @@ class WebInterface(object):
nzbget_host=None, nzbget_port=None, nzbget_username=None, nzbget_password=None, nzbget_category=None, nzbget_priority=None, nzbget_directory=None,
usenet_retention=None, nzbsu=0, nzbsu_uid=None, nzbsu_apikey=None, dognzb=0, dognzb_uid=None, dognzb_apikey=None, newznab=0, newznab_host=None, newznab_name=None, newznab_apikey=None, newznab_uid=None, newznab_enabled=0,
raw=0, raw_provider=None, raw_username=None, raw_password=None, raw_groups=None, experimental=0,
enable_meta=0, cmtagger_path=None, enable_rss=0, rss_checkinterval=None, enable_torrent_search=0, enable_kat=0, enable_cbt=0, cbt_passkey=None,
enable_meta=0, cmtagger_path=None, enable_rss=0, rss_checkinterval=None, enable_torrent_search=0, enable_kat=0, enable_cbt=0, cbt_passkey=None, snatchedtorrent_notify=0,
enable_torrents=0, minseeds=0, torrent_local=0, local_watchdir=None, torrent_seedbox=0, seedbox_watchdir=None, seedbox_user=None, seedbox_pass=None, seedbox_host=None, seedbox_port=None,
prowl_enabled=0, prowl_onsnatch=0, prowl_keys=None, prowl_priority=None, nma_enabled=0, nma_apikey=None, nma_priority=0, nma_onsnatch=0, pushover_enabled=0, pushover_onsnatch=0, pushover_apikey=None, pushover_userkey=None, pushover_priority=None, boxcar_enabled=0, boxcar_onsnatch=0, boxcar_token=None,
pushbullet_enabled=0, pushbullet_apikey=None, pushbullet_deviceid=None, pushbullet_onsnatch=0,
@ -2716,6 +2651,7 @@ class WebInterface(object):
mylar.ENABLE_KAT = int(enable_kat)
mylar.ENABLE_CBT = int(enable_cbt)
mylar.CBT_PASSKEY = cbt_passkey
mylar.SNATCHEDTORRENT_NOTIFY = int(snatchedtorrent_notify)
mylar.PREFERRED_QUALITY = int(preferred_quality)
mylar.MOVE_FILES = move_files
mylar.RENAME_FILES = rename_files