mirror of https://github.com/evilhero/mylar
FIX: undefined on filter box on startup, IMP: Added Meta-Tagging options on a series / issue basis on comic details screen, IMP: Issue Information is now available per issue and is extracted currently from the cbz file to display (if no cbz is present, the option isn't available), IMP: Failed Download handling is implemented and available in GUI - required to replace existing autoProcessComics.py and ComicRN.py scripts, IMP: Added ability to specify post-processing script instead of ComicRN.py, IMP: Added abilty to edit the issue date for a given issue by simply clicking on it - this will help to avoid dates that have incorrect or 0000-00-00, IMP: Story Arc searching is working (not adding yet), IMP: Added Archived/Ignored options to Upcoming/Wanted tab, IMP: Fixed some alignment and display issues on the Upcoming section, IMP: Added better directory handling for Updating Comic Location when it needs to get changed for all existing series (locmove in config.ini), IMP: Added better handling for unicode characters in series titles when searching / filechecking, IMP: When adding a new series with no data, Mylar would error out (now will add and just retain 0 issues), FIX: When year was fuzzied, search would still attempt to do a date-check comparison and say everything failed, IMP: Better handling of nzb names when retaining for post-processing comparisons, IMP: Future Upcoming now will use actual shipping date of issue if available in order to see if issue is available, FIX: If annuals were enabled, refreshing a series would put some issues into an Archived status because the actual counts would be off, IMP: When file checking, Alternate Naming would be searched last which resulted in matching incorrectly to the series title or other alternate naming for the given series, now will check the Alternate Naming first for a match, then drop back down to the series name itself otherwise, IMP: Improved Annual detection when integrated with a given series, IMP: Improved the checking of the future Upcoming list for issues marked as Wanted but not available yet and then auto-adding, IMP: Improved upon story arc checking for missing issues / searching for wanted, IMP: Enabling Annuals support now within Configuration GUI, bunch of other things....
This commit is contained in:
parent
5696ab905c
commit
78261e8fd8
|
@ -148,17 +148,25 @@ div#main { margin: 0; padding: 80px 0 0 0; }
|
|||
.comictable td#maindetails { width: 200px; padding: 10px; }
|
||||
.comictable td#middle { vertical-align: middle; }
|
||||
|
||||
table#artist_table { background-color: white; width: 100%; padding: 20px; }
|
||||
table#series_table { background-color: white; width: 100%; padding: 20px; }
|
||||
|
||||
table#artist_table th#select { text-align: left; }
|
||||
table#artist_table th#name { text-align: left; min-width: 200px; }
|
||||
table#artist_table th#status { text-align: left; min-width: 50px; }
|
||||
table#artist_table th#album { text-align: left; min-width: 300px; }
|
||||
table#artist_table th#have { text-align: center; }
|
||||
table#artist_table td#name { vertical-align: middle; text-align: left; min-width:200px; }
|
||||
table#artist_table td#status { vertical-align: middle; text-align: left; min-width: 50px; }
|
||||
table#artist_table td#album { vertical-align: middle; text-align: left; min-width: 300px; }
|
||||
table#artist_table td#have { vertical-align: middle; }
|
||||
table#series_table th#publisher { text-align: left; min-width: 50px; }
|
||||
table#series_table th#name { text-align: left; min-width: 250px; }
|
||||
table#series_table th#year { text-align: left; min-width: 25px; }
|
||||
table#series_table th#issue { text-align: left; min-width: 100px; }
|
||||
table#series_table th#published { vertical-align: middle; text-align: left; min-width:40px; }
|
||||
table#series_table th#have { text-align: center; }
|
||||
table#series_table th#status { vertical-align: middle; text-align: left; min-width: 25px; }
|
||||
table#series_table th#active { vertical-align: middle; text-align: left; min-width: 20px; }
|
||||
|
||||
table#series_table td#publisher { text-align: left; max-width: 100px; }
|
||||
table#series_table td#name { text-align: left; max-width: 250px; }
|
||||
table#series_table td#year { vertical-align: middle; text-align: left; max-width: 30px; }
|
||||
table#series_table td#issue { vertical-align: middle; text-align: left; max-width: 100px; }
|
||||
table#series_table td#published { vertical-align: middle; text-align: left; max-width: 40px; }
|
||||
table#series_table td#have { text-align: center; }
|
||||
table#series_table td#status { vertical-align: middle; text-align: left; max-width: 25px; }
|
||||
table#series_table td#active { vertical-align: middle; text-align: left; max-width: 20px; }
|
||||
|
||||
div#paddingheader { padding-top: 48px; font-size: 24px; font-weight: bold; text-align: center; }
|
||||
div#paddingheadertitle { padding-top: 24px; font-size: 24px; font-weight: bold; text-align: center; }
|
||||
|
|
|
@ -112,7 +112,6 @@
|
|||
|
||||
<script src="js/plugins.js"></script>
|
||||
<script src="interfaces/default/js/script.js"></script>
|
||||
<script src="interfaces/default/js/browser.js"></script>
|
||||
<!--[if lt IE 7 ]>
|
||||
<script src="js/libs/dd_belatedpng.js"></script>
|
||||
<script> DD_belatedPNG.fix('img, .png_bg');</script>
|
||||
|
|
|
@ -13,7 +13,10 @@
|
|||
%if mylar.RENAME_FILES:
|
||||
<a id="menu_link_refresh" onclick="doAjaxCall('manualRename?comicid=${comic['ComicID']}', $(this),'table')" data-success="Renaming files.">Rename Files</a>
|
||||
%endif
|
||||
<a id="menu_link_refresh" onclick="doAjaxCall('forceRescan?ComicID=${comic['ComicID']}', $(this)),'table'" href="#" data-success="'${comic['ComicName']}' is being rescanned">Recheck Files</a>
|
||||
<a id="menu_link_refresh" onclick="doAjaxCall('forceRescan?ComicID=${comic['ComicID']}', $(this),'table')" data-success="${comic['ComicName']} is being rescanned">Recheck Files</a>
|
||||
%if mylar.ENABLE_META:
|
||||
<a id="menu_link_refresh" onclick="doAjaxCall('group_metatag?dirName=${comic['ComicLocation']}&ComicID=${comic['ComicID']}', $(this),'table')" data-success="(re)tagging every issue present for '${comic['ComicName']}'">Manual MetaTagging</a>
|
||||
%endif
|
||||
%if comic['Status'] == 'Paused':
|
||||
<a id="menu_link_resume" href="#" onclick="doAjaxCall('resumeArtist?ComicID=${comic['ComicID']}',$(this),true)" data-success="${comic['ComicName']} resumed">Resume Comic</a>
|
||||
%else:
|
||||
|
@ -295,6 +298,7 @@
|
|||
<label for="Downloaded" class="checkbox inline Downloaded"><input type="checkbox" id="Downloaded" checked="checked" /> Downloaded: <b>${isCounts['Downloaded']}</b></label>
|
||||
<label for="Skipped" class="checkbox inline Skipped"><input type="checkbox" id="Skipped" checked="checked" /> Skipped: <b>${isCounts['Skipped']}</b></label>
|
||||
<label for="Ignored" class="checkbox inline Ignored"><input type="checkbox" id="Ignored" checked="checked" /> Ignored: <b>${isCounts['Ignored']}</b></label>
|
||||
<label for="Failed" class="checkbox inline Failed"><input type="checkbox" id="Failed" checked="checked" /> Failed: <b>${isCounts['Failed']}</b></label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -310,6 +314,7 @@
|
|||
<option value="Downloaded">Downloaded</option>
|
||||
<option value="Archived">Archived</option>
|
||||
<option value="Ignored">Ignored</option>
|
||||
<option value="Failed">Failed</option>
|
||||
</select>
|
||||
selected issues
|
||||
<input type="hidden" value="Go">
|
||||
|
@ -345,6 +350,8 @@
|
|||
grade = 'A'
|
||||
elif issue['Status'] == 'Ignored':
|
||||
grade = 'A'
|
||||
elif issue['Status'] == 'Failed':
|
||||
grade = 'C'
|
||||
else:
|
||||
grade = 'A'
|
||||
%>
|
||||
|
@ -353,8 +360,15 @@
|
|||
<td id="select"><input type="checkbox" name="${issue['IssueID']}" class="checkbox" value="${issue['IssueID']}"/></td>
|
||||
<td id="int_issuenumber">${issue['Int_IssueNumber']}</td>
|
||||
<td id="issuenumber">${issue['Issue_Number']}</td>
|
||||
<td id="issuename">${issue['IssueName']}</td>
|
||||
<td id="reldate">${issue['IssueDate']}</td>
|
||||
<%
|
||||
if len(issue['IssueName']) > 80:
|
||||
issuename = issue['IssueName'][:80] + '...'
|
||||
else:
|
||||
issuename = issue['IssueName']
|
||||
endif
|
||||
%>
|
||||
<td id="issuename">${issuename}</td>
|
||||
<td class="edit" title="Publication Date (click to edit)" id="${issue['ComicID']}.${issue['IssueID']}">${issue['IssueDate']}</td>
|
||||
<td id="status">${issue['Status']}
|
||||
%if issue['Status'] == 'Downloaded' or issue['Status'] == 'Archived':
|
||||
<%Csize = mylar.helpers.human_size(issue['ComicSize'])%>
|
||||
|
@ -369,8 +383,9 @@
|
|||
<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'):
|
||||
<a href="#" onclick="doAjaxCall('queueit?ComicID=${issue['ComicID']}&IssueID=${issue['IssueID']}&ComicIssue=${issue['Issue_Number']}&mode=want', $(this),'table')" data-success="Retrying the same version of '${issue['ComicName']}' '${issue['Issue_Number']}'" title="Retry the same download again"><img src="interfaces/default/images/retry_icon.png" height="25" width="25" /></a>
|
||||
<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'] == 'Downloaded'):
|
||||
<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>
|
||||
<a href="#" title="Mark issue as Failed" onclick="doAjaxCall('unqueueissue?IssueID=${issue['IssueID']}&ComicID=${issue['ComicID']}&mode="failed"',$(this),'table')" data-success="'${issue['Issue_Number']}' has been marked as Failed"><img src="interfaces/default/images/skipped_icon.png" height="25" width="25" /></a>
|
||||
%elif (issue['Status'] == 'Downloaded'):
|
||||
<%
|
||||
if issue['Location'] is not None:
|
||||
linky = os.path.join(comic['ComicLocation'],issue['Location'])
|
||||
|
@ -379,15 +394,34 @@
|
|||
else:
|
||||
linky = None
|
||||
%>
|
||||
%if linky:
|
||||
%if linky:
|
||||
<a href="downloadthis?pathfile=${linky |u}"><img src="interfaces/default/images/download_icon.png" height="25" width="25" title="Download the Issue" /></a>
|
||||
%if linky.endswith('.cbz'):
|
||||
<a href="#login-box" onclick="return runMetaIssue('${linky}');" class="login-window"><img src="interfaces/default/images/issueinfo.png" height="25" width="25" title="View Issue Details" /></a>
|
||||
<div id="login-box" class="login-popup">
|
||||
<a href="#" class="close"><img src="interfaces/default/images/close_pop.png" class="btn_close" title="Close Window" alt="Close" /></a>
|
||||
<fieldset>
|
||||
<div id="responsethis">
|
||||
<label><strong>[ NODATA ]</strong></label></br>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
%endif
|
||||
|
||||
%if mylar.ENABLE_META:
|
||||
<a href="#" title="Manually meta-tag issue" onclick="doAjaxCall('manual_metatag?dirName=${comic['ComicLocation']}&issueid=${issue['IssueID']}&filename=${linky |u}&comicid=${issue['ComicID']}',$(this),'table')" data-success="${issue['Issue_Number']} successfully tagged."><img src="interfaces/default/images/comictagger.png" height="25" width="25" /></a>
|
||||
%endif
|
||||
%endif
|
||||
<!--
|
||||
<a href="#" title="Add to Reading List" onclick="doAjaxCall('addtoreadlist?IssueID=${issue['IssueID']}',$(this),'table')" data-success="${issue['Issue_Number']} added to Reading List"><img src="interfaces/default/images/glasses-icon.png" height="25" width="25" /></a>
|
||||
-->
|
||||
%else:
|
||||
<a href="#" onclick="doAjaxCall('queueit?ComicID=${issue['ComicID']}&IssueID=${issue['IssueID']}&ComicIssue=${issue['Issue_Number']}&mode=want', $(this),'table')" data-success="Retrying the same version of '${issue['ComicName']}' '${issue['Issue_Number']}'" title="Retry the same download again"><img src="interfaces/default/images/retry_icon.png" height="25" width="25" /></a>
|
||||
<a href="#" title="Retry the same download again" onclick="doAjaxCall('queueit?ComicID=${issue['ComicID']}&IssueID=${issue['IssueID']}&ComicIssue=${issue['Issue_Number']}&mode=want', $(this),'table')" data-success="Retrying the same version of '${issue['ComicName']}' '${issue['Issue_Number']}'"><img src="interfaces/default/images/retry_icon.png" height="25" width="25" /></a>
|
||||
<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>
|
||||
%endif
|
||||
<a href="#" onclick="doAjaxCall('archiveissue?IssueID=${issue['IssueID']}',$(this),'table')"><img src="interfaces/default/images/archive_icon.png" height="25" width="25" title="Mark issue as Archived"></a>
|
||||
<!--
|
||||
<a href="#" onclick="doAjaxCall('archiveissue?IssueID=${issue['IssueID']}&comicid=${comic['ComicID']}',$(this),'table')"><img src="interfaces/default/images/archive_icon.png" height="25" width="25" title="Mark issue as Archived"></a>
|
||||
-->
|
||||
</td>
|
||||
</tr>
|
||||
%endfor
|
||||
|
@ -481,7 +515,7 @@
|
|||
<% amode = 'want_ann' %>
|
||||
<a href="#" title="Manual Search" onclick="doAjaxCall('queueit?ComicID=${annual['ComicID']}&IssueID=${annual['IssueID']}&ComicIssue=${annual['Issue_Number']}&ComicYear=${annual['IssueDate']}&mode=${amode}&manualsearch=True',$(this),'table')" data-success="Manually searching for ${annual['ComicName']} #${annual['Issue_Number']}"><img src="interfaces/default/images/search.png" height="25" width="25" /></a>
|
||||
<a href="#" title="Mark issue as Wanted" onclick="doAjaxCall('queueissue?ComicID=${annual['ComicID']}&IssueID=${annual['IssueID']}&ComicIssue=${annual['Issue_Number']}&ComicYear=${annual['IssueDate']}&mode=${amode}',$(this),'table')"><img src="interfaces/default/images/wanted_icon.png" height="25" width="25" /></a>
|
||||
<a href="#" title="Mark issue as Skipped" onclick="doAjaxCall('unqueueissue?IssueID=${annual['IssueID']}&ComicID=${annual['ComicID']}',$(this),'table')" data-success="'${annual['Issue_Number']}' has been marked as skipped"><img src="interfaces/default/images/skipped_icon.png" height="25" width="25" /></a>
|
||||
<a href="#" title="Mark issue as Skipped" onclick="doAjaxCall('unqueueissue?IssueID=${annual['IssueID']}&ComicID=${annual['ComicID']}&ReleaseComicID=${annual['ReleaseComicID']}',$(this),'table')" data-success="'${annual['Issue_Number']}' has been marked as skipped"><img src="interfaces/default/images/skipped_icon.png" height="25" width="25" /></a>
|
||||
<a href="#" title="Add to Reading List"><img src="interfaces/default/images/glasses-icon.png" height="25" width="25" /></a>
|
||||
<a href="#" title="Retry" onclick="doAjaxCall('queueissue?ComicID=${annual['ComicID']}&IssueID=${annual['IssueID']}&ComicIssue=${annual['Issue_Number']}&mode=${amode}', $(this),'table')" data-success="Retrying the same version of '${annual['ComicName']}'"><img src="interfaces/default/images/retry_icon.png" height="25" width="25" /></a>
|
||||
<a href="#" title="Archive" onclick="doAjaxCall('archiveissue?IssueID=${annual['IssueID']}',$(this),'table')"><img src="interfaces/default/images/archive_icon.png" height="25" width="25" title="Mark issue as Archived" /></a>
|
||||
|
@ -521,12 +555,79 @@
|
|||
|
||||
<%def name="javascriptIncludes()">
|
||||
<script src="js/libs/jquery.dataTables.min.js"></script>
|
||||
<script src="js/libs/jquery.jeditable.js"></script>
|
||||
<style>
|
||||
.ui-autocomplete-loading {
|
||||
background: white url('interfaces/default/images/loader_black.gif') right center no-repeat;
|
||||
}
|
||||
#annseries{ width: 25em; }
|
||||
</style>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('.edit').editable('issue_edit', {
|
||||
callback : function(value, settings) {
|
||||
console.log(this);
|
||||
console.log(value);
|
||||
console.log(settings);
|
||||
return(value);
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('a.login-window').click(function() {
|
||||
|
||||
//Getting the variable's value from a link
|
||||
var loginBox = $(this).attr('href');
|
||||
|
||||
//Fade in the Popup
|
||||
$(loginBox).fadeIn(300);
|
||||
|
||||
//Set the center alignment padding + border see css style
|
||||
var popMargTop = ($(loginBox).height() + 24) / 2;
|
||||
var popMargLeft = ($(loginBox).width() + 24) / 2;
|
||||
|
||||
$(loginBox).css({
|
||||
'margin-top' : -popMargTop,
|
||||
'margin-left' : -popMargLeft
|
||||
});
|
||||
|
||||
// Add the mask to body
|
||||
$('body').append('<div id="mask"></div>');
|
||||
$('#mask').fadeIn(300);
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
// When clicking on the button close or the mask layer the popup closed
|
||||
$('a.close, #mask').on('click', function() {
|
||||
$('#mask , .login-popup').fadeOut(300 , function() {
|
||||
$('#mask').remove();
|
||||
});
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<script>
|
||||
function runMetaIssue(filelink) {
|
||||
alert(filelink);
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: "IssueInfo",
|
||||
data: { filelocation: filelink },
|
||||
success: function(response) {
|
||||
var names = response
|
||||
$('#responsethis').html(response);
|
||||
},
|
||||
error: function(data)
|
||||
{
|
||||
alert('ERROR'+data.responseText);
|
||||
},
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
$(function() {
|
||||
|
|
|
@ -133,10 +133,20 @@
|
|||
<input type="checkbox" name="cvapifix" value="1" ${config['cvapifix']} /> <label>Comicvine URL Fix</label>
|
||||
<br/><small>*Use this if CV's URL has changed*</small>
|
||||
</div>
|
||||
|
||||
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Annual Handling</legend>
|
||||
<div>
|
||||
<small class="heading"><span style="float: left; margin-right: .3em; margin-top: 4px;" class="ui-icon ui-icon-info"></span>Series need to be Refreshed for annuals to appear</small>
|
||||
</div>
|
||||
<div class="row checkbox">
|
||||
<input type="checkbox" name="annuals_on" value="1" ${config['annuals_on']} /><label>Enable Series-Annual Integration</label>
|
||||
</div>
|
||||
</br><small>Enabled: Annuals are tracked as part of the series it belongs to</small></br>
|
||||
<small>Disabled: Annuals are tracked independently and will appear on your watchlist as a series</small>
|
||||
</fieldset>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<fieldset>
|
||||
<legend>API</legend>
|
||||
|
@ -150,7 +160,7 @@
|
|||
<input id="api_enabled" type="checkbox" onclick="initConfigCheckbox($(this));" name="api_enabled" value="1" ${config['api_enabled']} /><label>Enable API</label>
|
||||
</div>
|
||||
<div class="apioptions">
|
||||
<div Class="row">
|
||||
<div class="row">
|
||||
<label>Mylar API key</label>
|
||||
<input type="text" name="api_key" id="api_key" value="${config['api_key']}" size="20">
|
||||
<input type="button" value="Generate" id="generate_api">
|
||||
|
@ -167,21 +177,13 @@
|
|||
<input type="checkbox" name="nzb_startup_search" value="1" ${config['nzb_startup_search']} /><label>NZB Search on startup</label>
|
||||
</div>
|
||||
<div class="row">
|
||||
<label>Search delay</label>
|
||||
<input type="text" name="search_delay" value="${config['search_delay']}" size="4" />mins
|
||||
<label>Search delay</label>
|
||||
<input type="text" name="search_delay" value="${config['search_delay']}" size="4" />mins
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row">
|
||||
<label>Download Scan Interval</label>
|
||||
<input type="text" name="download_scan_interval" value="${config['download_scan_interval']}" size="4">mins
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<label>Library Scan Interval</label>
|
||||
<label>Library Scan Interval</label>
|
||||
<input type="text" name="libraryscan_interval" value="${config['libraryscan_interval']}" size="4">mins
|
||||
</div>
|
||||
<legend>Comic Location</legend>
|
||||
|
@ -584,28 +586,62 @@
|
|||
</div>
|
||||
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Failed Download Handling</legend>
|
||||
<div class="row checkbox left clearfix">
|
||||
<input type="checkbox" id="enable_failed" onclick="initConfigCheckbox($this));" name="failed_download_handling" value="1" ${config['failed_download_handling']} /><label>Enable Failed Download Handling</label>
|
||||
</div>
|
||||
<div class="config">
|
||||
<div class="row checkbox left clearfix">
|
||||
<input type="checkbox" name="failed_auto" value="1" ${config['failed_auto']} /><label>Enable Automatic-Retry for Failed Downloads</label>
|
||||
</div>
|
||||
|
||||
</fieldset>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
<fieldset>
|
||||
<legend>Post-Processing</legend>
|
||||
<div class="row checkbox left clearfix">
|
||||
<input type="checkbox" name="post_processing" value="1" ${config['post_processing']} /><label>Enable Post-Processing<small> (not checked = NO post-processing/post-management)</small></label>
|
||||
<input type="checkbox" id="post_processing" onclick="initConfigCheckbox($this));" name="post_processing" value="1" ${config['post_processing']} /><label>Enable Post-Processing<small> (not checked = NO post-processing/post-management)</small></label>
|
||||
</div>
|
||||
<div class="config">
|
||||
<div class="row checkbox left clearfix">
|
||||
<input type="checkbox" id="enable_check_folder" onclick="initConfigCheckbox($this));" name="enable_check_folder" value="1" ${config['enable_check_folder']} /><label>Enable Folder Monitoring<small></label>
|
||||
</div>
|
||||
<div class="config">
|
||||
<div class="row">
|
||||
<label>Folder location to monitor</label>
|
||||
<input type="text" name="check_folder" value="${config['check_folder']}" size="30">
|
||||
<small>enter in the absolute path to monitor for new issues</small>
|
||||
</div>
|
||||
<div class="row">
|
||||
<label>Folder Monitor Scan Interval</label>
|
||||
<input type="text" name="download_scan_interval" value="${config['download_scan_interval']}" size="4">mins
|
||||
<small>enter in the time delay scanning the folder</small>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="row checkbox left clearfix">
|
||||
<input type="checkbox" name="enable_pre_scripts" value="1" ${config['enable_pre_scripts']} /><label>Use Extra Script BEFORE Post-Processing</label>
|
||||
<input type="checkbox" id="enable_pre_scripts" onclick="initConfigCheckbox($this));" name="enable_pre_scripts" value="1" ${config['enable_pre_scripts']} /><label>Use Extra Script BEFORE Post-Processing</label>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="config">
|
||||
<div class="row">
|
||||
<label>Pre - Script Location</label>
|
||||
<input type="text" name="pre_scripts" value="${config['pre_scripts']}" size="30">
|
||||
<small>enter in the absolute path to the script</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row checkbox left clearfix">
|
||||
<input type="checkbox" name="enable_extra_scripts" value="1" ${config['enable_extra_scripts']} /><label>Use Extra Script AFTER Post-Processing</label>
|
||||
<input type="checkbox" id="enable_extra_scripts" onclick="initConfigCheckbox($this));" name="enable_extra_scripts" value="1" ${config['enable_extra_scripts']} /><label>Use Extra Script AFTER Post-Processing</label>
|
||||
</div>
|
||||
<div class="row">
|
||||
<label>Extra Script Location</label>
|
||||
<input type="text" name="extra_scripts" value="${config['extra_scripts']}" size="30">
|
||||
<small>enter in the absolute path to the script</small>
|
||||
<div class="config">
|
||||
<div class="row">
|
||||
<label>Extra Script Location</label>
|
||||
<input type="text" name="extra_scripts" value="${config['extra_scripts']}" size="30">
|
||||
<small>enter in the absolute path to the script</small>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
|
@ -1132,8 +1168,13 @@
|
|||
initConfigCheckbox("#replace_spaces");
|
||||
initConfigCheckbox("#use_minsize");
|
||||
initConfigCheckbox("#use_maxsize");
|
||||
initConfigCheckbox("#enable_failed");
|
||||
initConfigCheckbox("#enable_meta");
|
||||
initConfigCheckbox("#zero_level");
|
||||
initConfigCheckbox("#post_processing");
|
||||
initConfigCheckbox("#enable_check_folder");
|
||||
initConfigCheckbox("#enable_pre_scripts");
|
||||
initConfigCheckbox("#enable_extra_scripts");
|
||||
}
|
||||
$(document).ready(function() {
|
||||
initThisPage();
|
||||
|
|
|
@ -283,7 +283,7 @@ input,
|
|||
select,
|
||||
form .checkbox input,
|
||||
.configtable td#middle,
|
||||
#artist_table td#have,
|
||||
#series_table td#have,
|
||||
#album_table td#have {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
@ -1065,58 +1065,54 @@ div#artistheader h2 a {
|
|||
vertical-align: middle;
|
||||
}
|
||||
|
||||
#artist_table {
|
||||
#series_table {
|
||||
background-color: #FFF;
|
||||
padding: 20px;
|
||||
width: 100%;
|
||||
}
|
||||
#artist_table th#select {
|
||||
#series_table th#publisher {
|
||||
min-width: 150px;
|
||||
text-align: left;
|
||||
}
|
||||
#artist_table th#select input {
|
||||
vertical-align: middle;
|
||||
}
|
||||
#artist_table #artistImg {
|
||||
background: url("../images/loader_black.gif") no-repeat scroll center center #ffffff;
|
||||
border: 3px solid #FFFFFF;
|
||||
box-shadow: 1px 1px 2px 0 #555555;
|
||||
float: left;
|
||||
height: 50px;
|
||||
overflow: hidden;
|
||||
text-indent: -3000px;
|
||||
width: 50px;
|
||||
}
|
||||
#artist_table th#name {
|
||||
min-width: 200px;
|
||||
#series_table th#name {
|
||||
min-width: 275px;
|
||||
text-align: left;
|
||||
}
|
||||
#artist_table th#album {
|
||||
min-width: 300px;
|
||||
#series_table th#year,
|
||||
#series_table th#issue {
|
||||
min-width: 25px;
|
||||
text-align: left;
|
||||
}
|
||||
#artist_table th#status,
|
||||
#artist_table th#albumart,
|
||||
#artist_table th#lastupdated {
|
||||
#series_table th#status,
|
||||
#series_table th#active,
|
||||
#series_table th#published {
|
||||
min-width: 50px;
|
||||
text-align: left;
|
||||
}
|
||||
#artist_table th#have {
|
||||
#series_table th#have {
|
||||
text-align: center;
|
||||
}
|
||||
#artist_table td#name {
|
||||
min-width: 200px;
|
||||
#series_table td#publisher {
|
||||
min-width: 150px;
|
||||
text-align: left;
|
||||
vertical-align: middle;
|
||||
font-size: 12px;
|
||||
}
|
||||
#artist_table td#status,
|
||||
#artist_table td#lastupdated {
|
||||
min-width: 50px;
|
||||
#series_table td#name {
|
||||
min-width: 275px;
|
||||
text-align: left;
|
||||
vertical-align: middle;
|
||||
}
|
||||
#artist_table td#album {
|
||||
min-width: 300px;
|
||||
#series_table th#year,
|
||||
#series_table th#issue {
|
||||
max-width: 25px;
|
||||
text-align: left;
|
||||
vertical-align: middle;
|
||||
}
|
||||
#series_table td#status,
|
||||
#series_table td#active,
|
||||
#series_table td#published {
|
||||
max-width: 50px;
|
||||
text-align: left;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
@ -1771,3 +1767,121 @@ table tr td#status a {
|
|||
.ie7 legend {
|
||||
margin-left: -7px;
|
||||
}
|
||||
/* Mask for background, by default is not display */
|
||||
#mask {
|
||||
display: none;
|
||||
background: #000;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0.8;
|
||||
z-index: 999;
|
||||
}
|
||||
/* You can customize to your needs */
|
||||
.login-popup {
|
||||
width: 600px;
|
||||
display: none;
|
||||
background: #333;
|
||||
padding: 5px;
|
||||
border: 2px solid #ddd;
|
||||
color: white;
|
||||
font-size: 1.2em;
|
||||
position: absolute;
|
||||
top: 20%;
|
||||
left: 50%;
|
||||
z-index: 99999;
|
||||
box-shadow: 0px 0px 20px #999;
|
||||
/* CSS3 */
|
||||
-moz-box-shadow: 0px 0px 20px #999;
|
||||
/* Firefox */
|
||||
-webkit-box-shadow: 0px 0px 20px #999;
|
||||
/* Safari, Chrome */
|
||||
border-radius: 3px 3px 3px 3px;
|
||||
-moz-border-radius: 3px;
|
||||
/* Firefox */
|
||||
-webkit-border-radius: 3px;
|
||||
/* Safari, Chrome */;
|
||||
}
|
||||
|
||||
.alignleft {
|
||||
float: left;
|
||||
}
|
||||
.alignright {
|
||||
float: right;
|
||||
}
|
||||
|
||||
img.btn_close {
|
||||
Position the close button
|
||||
float: right;
|
||||
margin: -28px -28px 0 0;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
border: none;
|
||||
}
|
||||
|
||||
form.signin .textbox label {
|
||||
display: block;
|
||||
padding-bottom: 7px;
|
||||
}
|
||||
|
||||
form.signin .textbox span {
|
||||
display: block;
|
||||
}
|
||||
|
||||
form.signin p, form.signin span {
|
||||
color: #999;
|
||||
font-size: 11px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
form.signin .textbox input {
|
||||
background: #666666;
|
||||
border-bottom: 1px solid #333;
|
||||
border-left: 1px solid #000;
|
||||
border-right: 1px solid #333;
|
||||
border-top: 1px solid #000;
|
||||
color: #fff;
|
||||
border-radius: 3px 3px 3px 3px;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
font: 13px Arial, Helvetica, sans-serif;
|
||||
padding: 6px 6px 4px;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
form.signin input:-moz-placeholder {
|
||||
color: #bbb;
|
||||
text-shadow: 0 0 2px #000;
|
||||
}
|
||||
|
||||
form.signin input::-webkit-input-placeholder {
|
||||
color: #bbb;
|
||||
text-shadow: 0 0 2px #000;
|
||||
}
|
||||
|
||||
.button {
|
||||
background: -moz-linear-gradient(center top, #f3f3f3, #dddddd);
|
||||
background: -webkit-gradient(linear, left top, left bottom, from(#f3f3f3), to(#dddddd));
|
||||
background: -o-linear-gradient(top, #f3f3f3, #dddddd);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#f3f3f3', EndColorStr='#dddddd');
|
||||
border-color: #000;
|
||||
border-width: 1px;
|
||||
border-radius: 4px 4px 4px 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
color: #333;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
padding: 6px 6px 4px;
|
||||
margin-top: 10px;
|
||||
font: 12px;
|
||||
width: 214px;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
background: #ddd;
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
%elif future['STATUS'] == 'Skipped':
|
||||
<a href="searchit?name=${future['COMIC'] | u}&issue=${future['ISSUE']}&mode=pullseries"><span class="ui-icon ui-icon-plus"></span>add series</a>
|
||||
<a href="queueissue?ComicName=${future['COMIC'] | u}&ComicIssue=${future['ISSUE']}&mode=pullwant"><span class="ui-icon ui-icon-plus"></span>one off</a>
|
||||
<a href="add2futurewatchlist?ComicName=${future['COMIC'] | u}&Issue=${future['ISSUE']}&Publisher=${future['PUBLISHER']}&ShipDate=${future['SHIPDATE']}&FutureID=${future['FUTUREID']}"><span class="ui-icon ui-icon-plus"></span>Watch For</a>
|
||||
<a href="#" onclick="doAjaxCall('add2futurewatchlist?ComicName=${future['COMIC'] |u}&Issue=${future['ISSUE']}&Publisher=${future['PUBLISHER']}}&ShipDate=${future['SHIPDATE']}&FutureID=${future['FUTUREID']}', $(this), 'table')" data-success="Adding ${future['COMIC']} Issue: ${future['ISSUE']} to Upcoming Watchlist"><span class="ui-icon ui-icon-plus"></span>Watch For</a>
|
||||
%endif
|
||||
</td>
|
||||
%endif
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
Binary file not shown.
After Width: | Height: | Size: 73 KiB |
Binary file not shown.
After Width: | Height: | Size: 625 KiB |
|
@ -7,7 +7,7 @@
|
|||
<%def name="body()">
|
||||
<div class="table_wrapper">
|
||||
|
||||
<table class="display" id="artist_table">
|
||||
<table class="display" id="series_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th id="publisher">Publisher</th>
|
||||
|
@ -17,7 +17,7 @@
|
|||
<th id="published">Published</th>
|
||||
<th id="have">Have</th>
|
||||
<th id="status">Status</th>
|
||||
<th id="status">Active</th>
|
||||
<th id="active">Active</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -63,7 +63,7 @@
|
|||
<script>
|
||||
|
||||
function initThisPage() {
|
||||
$('#artist_table').dataTable(
|
||||
$('#series_table').dataTable(
|
||||
{
|
||||
"bDestroy": true,
|
||||
"aoColumnDefs": [
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
|
||||
(function($){$.fn.editable=function(target,options){if('disable'==target){$(this).data('disabled.editable',true);return;}
|
||||
if('enable'==target){$(this).data('disabled.editable',false);return;}
|
||||
if('destroy'==target){$(this).unbind($(this).data('event.editable')).removeData('disabled.editable').removeData('event.editable');return;}
|
||||
var settings=$.extend({},$.fn.editable.defaults,{target:target},options);var plugin=$.editable.types[settings.type].plugin||function(){};var submit=$.editable.types[settings.type].submit||function(){};var buttons=$.editable.types[settings.type].buttons||$.editable.types['defaults'].buttons;var content=$.editable.types[settings.type].content||$.editable.types['defaults'].content;var element=$.editable.types[settings.type].element||$.editable.types['defaults'].element;var reset=$.editable.types[settings.type].reset||$.editable.types['defaults'].reset;var callback=settings.callback||function(){};var onedit=settings.onedit||function(){};var onsubmit=settings.onsubmit||function(){};var onreset=settings.onreset||function(){};var onerror=settings.onerror||reset;if(settings.tooltip){$(this).attr('title',settings.tooltip);}
|
||||
settings.autowidth='auto'==settings.width;settings.autoheight='auto'==settings.height;return this.each(function(){var self=this;var savedwidth=$(self).width();var savedheight=$(self).height();$(this).data('event.editable',settings.event);if(!$.trim($(this).html())){$(this).html(settings.placeholder);}
|
||||
$(this).bind(settings.event,function(e){if(true===$(this).data('disabled.editable')){return;}
|
||||
if(self.editing){return;}
|
||||
if(false===onedit.apply(this,[settings,self])){return;}
|
||||
e.preventDefault();e.stopPropagation();if(settings.tooltip){$(self).removeAttr('title');}
|
||||
if(0==$(self).width()){settings.width=savedwidth;settings.height=savedheight;}else{if(settings.width!='none'){settings.width=settings.autowidth?$(self).width():settings.width;}
|
||||
if(settings.height!='none'){settings.height=settings.autoheight?$(self).height():settings.height;}}
|
||||
if($(this).html().toLowerCase().replace(/(;|")/g,'')==settings.placeholder.toLowerCase().replace(/(;|")/g,'')){$(this).html('');}
|
||||
self.editing=true;self.revert=$(self).html();$(self).html('');var form=$('<form />');if(settings.cssclass){if('inherit'==settings.cssclass){form.attr('class',$(self).attr('class'));}else{form.attr('class',settings.cssclass);}}
|
||||
if(settings.style){if('inherit'==settings.style){form.attr('style',$(self).attr('style'));form.css('display',$(self).css('display'));}else{form.attr('style',settings.style);}}
|
||||
var input=element.apply(form,[settings,self]);var input_content;if(settings.loadurl){var t=setTimeout(function(){input.disabled=true;content.apply(form,[settings.loadtext,settings,self]);},100);var loaddata={};loaddata[settings.id]=self.id;if($.isFunction(settings.loaddata)){$.extend(loaddata,settings.loaddata.apply(self,[self.revert,settings]));}else{$.extend(loaddata,settings.loaddata);}
|
||||
$.ajax({type:settings.loadtype,url:settings.loadurl,data:loaddata,async:false,success:function(result){window.clearTimeout(t);input_content=result;input.disabled=false;}});}else if(settings.data){input_content=settings.data;if($.isFunction(settings.data)){input_content=settings.data.apply(self,[self.revert,settings]);}}else{input_content=self.revert;}
|
||||
content.apply(form,[input_content,settings,self]);input.attr('name',settings.name);buttons.apply(form,[settings,self]);$(self).append(form);plugin.apply(form,[settings,self]);$(':input:visible:enabled:first',form).focus();if(settings.select){input.select();}
|
||||
input.keydown(function(e){if(e.keyCode==27){e.preventDefault();reset.apply(form,[settings,self]);}});var t;if('cancel'==settings.onblur){input.blur(function(e){t=setTimeout(function(){reset.apply(form,[settings,self]);},500);});}else if('submit'==settings.onblur){input.blur(function(e){t=setTimeout(function(){form.submit();},200);});}else if($.isFunction(settings.onblur)){input.blur(function(e){settings.onblur.apply(self,[input.val(),settings]);});}else{input.blur(function(e){});}
|
||||
form.submit(function(e){if(t){clearTimeout(t);}
|
||||
e.preventDefault();if(false!==onsubmit.apply(form,[settings,self])){if(false!==submit.apply(form,[settings,self])){if($.isFunction(settings.target)){var str=settings.target.apply(self,[input.val(),settings]);$(self).html(str);self.editing=false;callback.apply(self,[self.innerHTML,settings]);if(!$.trim($(self).html())){$(self).html(settings.placeholder);}}else{var submitdata={};submitdata[settings.name]=input.val();submitdata[settings.id]=self.id;if($.isFunction(settings.submitdata)){$.extend(submitdata,settings.submitdata.apply(self,[self.revert,settings]));}else{$.extend(submitdata,settings.submitdata);}
|
||||
if('PUT'==settings.method){submitdata['_method']='put';}
|
||||
$(self).html(settings.indicator);var ajaxoptions={type:'POST',data:submitdata,dataType:'html',url:settings.target,success:function(result,status){if(ajaxoptions.dataType=='html'){$(self).html(result);}
|
||||
self.editing=false;callback.apply(self,[result,settings]);if(!$.trim($(self).html())){$(self).html(settings.placeholder);}},error:function(xhr,status,error){onerror.apply(form,[settings,self,xhr]);}};$.extend(ajaxoptions,settings.ajaxoptions);$.ajax(ajaxoptions);}}}
|
||||
$(self).attr('title',settings.tooltip);return false;});});this.reset=function(form){if(this.editing){if(false!==onreset.apply(form,[settings,self])){$(self).html(self.revert);self.editing=false;if(!$.trim($(self).html())){$(self).html(settings.placeholder);}
|
||||
if(settings.tooltip){$(self).attr('title',settings.tooltip);}}}};});};$.editable={types:{defaults:{element:function(settings,original){var input=$('<input type="hidden"></input>');$(this).append(input);return(input);},content:function(string,settings,original){$(':input:first',this).val(string);},reset:function(settings,original){original.reset(this);},buttons:function(settings,original){var form=this;if(settings.submit){if(settings.submit.match(/>$/)){var submit=$(settings.submit).click(function(){if(submit.attr("type")!="submit"){form.submit();}});}else{var submit=$('<button type="submit" />');submit.html(settings.submit);}
|
||||
$(this).append(submit);}
|
||||
if(settings.cancel){if(settings.cancel.match(/>$/)){var cancel=$(settings.cancel);}else{var cancel=$('<button type="cancel" />');cancel.html(settings.cancel);}
|
||||
$(this).append(cancel);$(cancel).click(function(event){if($.isFunction($.editable.types[settings.type].reset)){var reset=$.editable.types[settings.type].reset;}else{var reset=$.editable.types['defaults'].reset;}
|
||||
reset.apply(form,[settings,original]);return false;});}}},text:{element:function(settings,original){var input=$('<input />');if(settings.width!='none'){input.width(settings.width);}
|
||||
if(settings.height!='none'){input.height(settings.height);}
|
||||
input.attr('autocomplete','off');$(this).append(input);return(input);}},textarea:{element:function(settings,original){var textarea=$('<textarea />');if(settings.rows){textarea.attr('rows',settings.rows);}else if(settings.height!="none"){textarea.height(settings.height);}
|
||||
if(settings.cols){textarea.attr('cols',settings.cols);}else if(settings.width!="none"){textarea.width(settings.width);}
|
||||
$(this).append(textarea);return(textarea);}},select:{element:function(settings,original){var select=$('<select />');$(this).append(select);return(select);},content:function(data,settings,original){if(String==data.constructor){eval('var json = '+data);}else{var json=data;}
|
||||
for(var key in json){if(!json.hasOwnProperty(key)){continue;}
|
||||
if('selected'==key){continue;}
|
||||
var option=$('<option />').val(key).append(json[key]);$('select',this).append(option);}
|
||||
$('select',this).children().each(function(){if($(this).val()==json['selected']||$(this).text()==$.trim(original.revert)){$(this).attr('selected','selected');}});}}},addInputType:function(name,input){$.editable.types[name]=input;}};$.fn.editable.defaults={name:'value',id:'id',type:'text',width:'auto',height:'auto',event:'click.editable',onblur:'cancel',loadtype:'GET',loadtext:'Loading...',placeholder:'Click to edit',loaddata:{},submitdata:{},ajaxoptions:{}};})(jQuery);
|
|
@ -60,11 +60,11 @@
|
|||
<small>Leaving this unchecked will not move anything, but will mark the issues as Archived</small>
|
||||
</div>
|
||||
<div class="config">
|
||||
<input type="checkbox" name="imp_rename" id="imp_rename" value="1" ${checked(mylar.IMP_RENAME)}><label>Rename Files </label>
|
||||
<input type="checkbox" style="vertical-align: middle; margin: 3px; margin-top: -1px;" name="imp_rename" id="imp_rename" value="1" ${checked(mylar.IMP_RENAME)}><label>Rename Files </label>
|
||||
<small>Rename files to configuration settings</small>
|
||||
</div>
|
||||
<br/>
|
||||
<input type="button" value="Save Changes and Scan" onclick="addScanAction();doAjaxCall('comicScan',$(this),'tabs',true);return false;" data-success="Changes saved. Library will be scanned">
|
||||
<input type="button" value="Save Changes and Scan" onclick="addScanAction();doAjaxCall('comicScan',$(this),'tabs',true);return false;" data-success="Changes saved. Library will be scanned" data-always="Sucessfully completed scanning library.">
|
||||
<input type="button" value="Save Changes without Scanning Library" onclick="doAjaxCall('comicScan',$(this),'tabs',true);return false;" data-success="Changes Saved Successfully">
|
||||
</fieldset>
|
||||
</form>
|
||||
|
|
|
@ -69,18 +69,7 @@
|
|||
<%def name="javascriptIncludes()">
|
||||
<script src="js/libs/jquery.dataTables.min.js"></script>
|
||||
<script>
|
||||
function getArtistArt() {
|
||||
$("table#artist_table tr td#albumart #artistImg").each(function(){
|
||||
var id = $(this).children('img').attr('id');
|
||||
var image = $(this).children('img');
|
||||
if ( !image.hasClass('done') ) {
|
||||
image.addClass('done');
|
||||
getThumb(image,id,'artist');
|
||||
}
|
||||
});
|
||||
}
|
||||
function initThisPage() {
|
||||
getArtistArt();
|
||||
$('#manage_comic').dataTable(
|
||||
{
|
||||
"bDestroy": true,
|
||||
|
|
|
@ -78,7 +78,7 @@
|
|||
<table class="configtable">
|
||||
<tr>
|
||||
<form action="searchit" method="get">
|
||||
<input type="hidden" name="type" value="storyarc">
|
||||
<input type="hidden" name="type" value="story_arc">
|
||||
<input type="text" value="" placeholder="Search" onfocus="if(this.value==this.defaultValue) this.value='';" name="name" />
|
||||
<span class="mini-icon"></span>
|
||||
<input type="submit" value="Search"/>
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
<%inherit file="base.html" />
|
||||
<%!
|
||||
import mylar
|
||||
from mylar.helpers import checked
|
||||
|
||||
%>
|
||||
|
||||
<%def name="headerIncludes()">
|
||||
<div id="subhead_container">
|
||||
|
@ -28,6 +33,16 @@
|
|||
%>
|
||||
|
||||
<h1 class="clearfix"><img src="interfaces/default/images/icon_search.png" alt="Search results"/>${searchtext}</h1>
|
||||
<div>
|
||||
<form action="CreateFolders" method="GET" id="CreatetheFolders">
|
||||
<fieldset>
|
||||
<div class="row">
|
||||
<input type="checkbox" name="createfolders" id="createfolders" value=1 ${checked(mylar.CREATE_FOLDERS)} /><label>Automatic Folder Creation</label>
|
||||
</div>
|
||||
<input type="submit" style="display:none" />
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table_wrapper">
|
||||
<table class="display" id="searchresults_table">
|
||||
|
@ -57,7 +72,7 @@
|
|||
<td class="comicyear">${result['comicyear']}</a></td>
|
||||
<td class="issues">${result['issues']}</td>
|
||||
|
||||
<td class="add" nowrap="nowrap"><a href="addComic?comicid=${result['comicid']}&comicname=${result['name'] |u}&comicyear=${result['comicyear']}&comicpublisher=${result['publisher'] |u}&comicimage=${result['comicimage']}&comicissues=${result['issues']}&imported=${imported}&ogcname=${ogcname}"><span class="ui-icon ui-icon-plus"></span> Add this Comic</a></td>
|
||||
<td class="add" nowrap="nowrap"><a href="addComic?comicid=${result['comicid']}&comicname=${result['name'] |u}&comicyear=${result['comicyear']}&comicpublisher=${result['publisher'] |u}&comicimage=${result['comicimage']}&comicissues=${result['issues']}&imported=${imported}&ogcname=${ogcname}&serinfo=${serinfo}"><span class="ui-icon ui-icon-plus"></span> Add this Comic</a></td>
|
||||
</tr>
|
||||
%endfor
|
||||
%endif
|
||||
|
@ -71,6 +86,12 @@
|
|||
</%def>
|
||||
|
||||
<%def name="javascriptIncludes()">
|
||||
<script type="text/javascript">
|
||||
$("#createfolders").click(function() {
|
||||
$('#CreatetheFolders').submit();
|
||||
return true;
|
||||
});
|
||||
</script>
|
||||
|
||||
<script src="js/libs/jquery.dataTables.min.js"></script>
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
<option disabled="disabled" selected="selected">Choose...</option>
|
||||
<option value="Skipped">Skipped</option>
|
||||
<option value="Downloaded">Downloaded</option>
|
||||
<option value="Archived">Archived</option>
|
||||
<option value="Ignored">Ignored</option>
|
||||
</select>
|
||||
<input type="hidden" value="Go">
|
||||
</div>
|
||||
|
@ -90,10 +92,10 @@
|
|||
<td id="status">${upcome['Status']}</td>
|
||||
</tr>
|
||||
%endfor
|
||||
</tbody>
|
||||
%else:
|
||||
<tr><td align="center" width="100%"> no upcoming data to display</td></tr>
|
||||
%endif
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -102,7 +104,7 @@
|
|||
<div class="table_wrapper">
|
||||
<table class="display_no_select" id="upcoming_table">
|
||||
%if future_nodata_upcoming:
|
||||
<thead>
|
||||
<thead>
|
||||
<tr>
|
||||
<th id="comicname">Comic</th>
|
||||
<th id="issuenumber">Issue</th>
|
||||
|
@ -116,13 +118,13 @@
|
|||
<td id="comicname"><a href="comicDetails?ComicID=${f_nodata['ComicID']}">${f_nodata['ComicName']}</a></td>
|
||||
<td id="issuenumber">${f_nodata['IssueNumber']}</td>
|
||||
<td id="reldate">${f_nodata['IssueDate']}</td>
|
||||
<td id="status">${f_nodata['Status']}</td>
|
||||
<td id="status">${f_nodata['Status']}</td>
|
||||
</tr>
|
||||
%endfor
|
||||
</tbody>
|
||||
%else:
|
||||
<tr><td align='center" width="100%">no upcoming future data to display</td></tr>
|
||||
<tr><td align="center" width="100%">no upcoming future data to display</td></tr>
|
||||
%endif
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -131,14 +133,14 @@
|
|||
<div class="table_wrapper">
|
||||
<table class="display_no_select" id="upcoming_table">
|
||||
%if futureupcoming:
|
||||
<thead>
|
||||
<thead>
|
||||
<tr>
|
||||
<th id="comicname">Comic</th>
|
||||
<th id="issuenumber">Issue</th>
|
||||
<th id="reldate">Release Date</th>
|
||||
<th id="status">Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</thead>
|
||||
<tbody>
|
||||
%for f_upcome in futureupcoming:
|
||||
<tr class="gradeZ">
|
||||
|
@ -148,10 +150,10 @@
|
|||
<td id="status">${f_upcome['Status']}</td>
|
||||
</tr>
|
||||
%endfor
|
||||
</tbody>
|
||||
%else:
|
||||
<tr><td align="center" width="100%">no upcoming future data to display</td></tr>
|
||||
%endif
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<div id="subhead_menu">
|
||||
<a id="menu_link_refresh" href="manualpull">Refresh Pull-list</a>
|
||||
<a id="menu_link_delete" href="pullrecreate">Recreate Pull-list</a>
|
||||
<a id="menu_link_scan" class="button">Download</a>
|
||||
<a id="menu_link_refresh" class="button">Download</a>
|
||||
<!-- <a id="menu_link_refresh" onclick="doAjaxCall('MassWeeklyDownload?pulldate=${pulldate}, $(this)),'table'" href="#" data-success="Now Downloading Comics to : ${mylar.GRABBAG_DIR}">Download.</a> -->
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,543 @@
|
|||
/*
|
||||
* Jeditable - jQuery in place edit plugin
|
||||
*
|
||||
* Copyright (c) 2006-2009 Mika Tuupola, Dylan Verheul
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*
|
||||
* Project home:
|
||||
* http://www.appelsiini.net/projects/jeditable
|
||||
*
|
||||
* Based on editable by Dylan Verheul <dylan_at_dyve.net>:
|
||||
* http://www.dyve.net/jquery/?editable
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Version 1.7.1
|
||||
*
|
||||
* ** means there is basic unit tests for this parameter.
|
||||
*
|
||||
* @name Jeditable
|
||||
* @type jQuery
|
||||
* @param String target (POST) URL or function to send edited content to **
|
||||
* @param Hash options additional options
|
||||
* @param String options[method] method to use to send edited content (POST or PUT) **
|
||||
* @param Function options[callback] Function to run after submitting edited content **
|
||||
* @param String options[name] POST parameter name of edited content
|
||||
* @param String options[id] POST parameter name of edited div id
|
||||
* @param Hash options[submitdata] Extra parameters to send when submitting edited content.
|
||||
* @param String options[type] text, textarea or select (or any 3rd party input type) **
|
||||
* @param Integer options[rows] number of rows if using textarea **
|
||||
* @param Integer options[cols] number of columns if using textarea **
|
||||
* @param Mixed options[height] 'auto', 'none' or height in pixels **
|
||||
* @param Mixed options[width] 'auto', 'none' or width in pixels **
|
||||
* @param String options[loadurl] URL to fetch input content before editing **
|
||||
* @param String options[loadtype] Request type for load url. Should be GET or POST.
|
||||
* @param String options[loadtext] Text to display while loading external content.
|
||||
* @param Mixed options[loaddata] Extra parameters to pass when fetching content before editing.
|
||||
* @param Mixed options[data] Or content given as paramameter. String or function.**
|
||||
* @param String options[indicator] indicator html to show when saving
|
||||
* @param String options[tooltip] optional tooltip text via title attribute **
|
||||
* @param String options[event] jQuery event such as 'click' of 'dblclick' **
|
||||
* @param String options[submit] submit button value, empty means no button **
|
||||
* @param String options[cancel] cancel button value, empty means no button **
|
||||
* @param String options[cssclass] CSS class to apply to input form. 'inherit' to copy from parent. **
|
||||
* @param String options[style] Style to apply to input form 'inherit' to copy from parent. **
|
||||
* @param String options[select] true or false, when true text is highlighted ??
|
||||
* @param String options[placeholder] Placeholder text or html to insert when element is empty. **
|
||||
* @param String options[onblur] 'cancel', 'submit', 'ignore' or function ??
|
||||
*
|
||||
* @param Function options[onsubmit] function(settings, original) { ... } called before submit
|
||||
* @param Function options[onreset] function(settings, original) { ... } called before reset
|
||||
* @param Function options[onerror] function(settings, original, xhr) { ... } called on error
|
||||
*
|
||||
* @param Hash options[ajaxoptions] jQuery Ajax options. See docs.jquery.com.
|
||||
*
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
|
||||
$.fn.editable = function(target, options) {
|
||||
|
||||
if ('disable' == target) {
|
||||
$(this).data('disabled.editable', true);
|
||||
return;
|
||||
}
|
||||
if ('enable' == target) {
|
||||
$(this).data('disabled.editable', false);
|
||||
return;
|
||||
}
|
||||
if ('destroy' == target) {
|
||||
$(this)
|
||||
.unbind($(this).data('event.editable'))
|
||||
.removeData('disabled.editable')
|
||||
.removeData('event.editable');
|
||||
return;
|
||||
}
|
||||
|
||||
var settings = $.extend({}, $.fn.editable.defaults, {target:target}, options);
|
||||
|
||||
/* setup some functions */
|
||||
var plugin = $.editable.types[settings.type].plugin || function() { };
|
||||
var submit = $.editable.types[settings.type].submit || function() { };
|
||||
var buttons = $.editable.types[settings.type].buttons
|
||||
|| $.editable.types['defaults'].buttons;
|
||||
var content = $.editable.types[settings.type].content
|
||||
|| $.editable.types['defaults'].content;
|
||||
var element = $.editable.types[settings.type].element
|
||||
|| $.editable.types['defaults'].element;
|
||||
var reset = $.editable.types[settings.type].reset
|
||||
|| $.editable.types['defaults'].reset;
|
||||
var callback = settings.callback || function() { };
|
||||
var onedit = settings.onedit || function() { };
|
||||
var onsubmit = settings.onsubmit || function() { };
|
||||
var onreset = settings.onreset || function() { };
|
||||
var onerror = settings.onerror || reset;
|
||||
|
||||
/* show tooltip */
|
||||
if (settings.tooltip) {
|
||||
$(this).attr('title', settings.tooltip);
|
||||
}
|
||||
|
||||
settings.autowidth = 'auto' == settings.width;
|
||||
settings.autoheight = 'auto' == settings.height;
|
||||
|
||||
return this.each(function() {
|
||||
|
||||
/* save this to self because this changes when scope changes */
|
||||
var self = this;
|
||||
|
||||
/* inlined block elements lose their width and height after first edit */
|
||||
/* save them for later use as workaround */
|
||||
var savedwidth = $(self).width();
|
||||
var savedheight = $(self).height();
|
||||
|
||||
/* save so it can be later used by $.editable('destroy') */
|
||||
$(this).data('event.editable', settings.event);
|
||||
|
||||
/* if element is empty add something clickable (if requested) */
|
||||
if (!$.trim($(this).html())) {
|
||||
$(this).html(settings.placeholder);
|
||||
}
|
||||
|
||||
$(this).bind(settings.event, function(e) {
|
||||
|
||||
/* abort if disabled for this element */
|
||||
if (true === $(this).data('disabled.editable')) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* prevent throwing an exeption if edit field is clicked again */
|
||||
if (self.editing) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* abort if onedit hook returns false */
|
||||
if (false === onedit.apply(this, [settings, self])) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* prevent default action and bubbling */
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
/* remove tooltip */
|
||||
if (settings.tooltip) {
|
||||
$(self).removeAttr('title');
|
||||
}
|
||||
|
||||
/* figure out how wide and tall we are, saved width and height */
|
||||
/* are workaround for http://dev.jquery.com/ticket/2190 */
|
||||
if (0 == $(self).width()) {
|
||||
//$(self).css('visibility', 'hidden');
|
||||
settings.width = savedwidth;
|
||||
settings.height = savedheight;
|
||||
} else {
|
||||
if (settings.width != 'none') {
|
||||
settings.width =
|
||||
settings.autowidth ? $(self).width() : settings.width;
|
||||
}
|
||||
if (settings.height != 'none') {
|
||||
settings.height =
|
||||
settings.autoheight ? $(self).height() : settings.height;
|
||||
}
|
||||
}
|
||||
//$(this).css('visibility', '');
|
||||
|
||||
/* remove placeholder text, replace is here because of IE */
|
||||
if ($(this).html().toLowerCase().replace(/(;|")/g, '') ==
|
||||
settings.placeholder.toLowerCase().replace(/(;|")/g, '')) {
|
||||
$(this).html('');
|
||||
}
|
||||
|
||||
self.editing = true;
|
||||
self.revert = $(self).html();
|
||||
$(self).html('');
|
||||
|
||||
/* create the form object */
|
||||
var form = $('<form />');
|
||||
|
||||
/* apply css or style or both */
|
||||
if (settings.cssclass) {
|
||||
if ('inherit' == settings.cssclass) {
|
||||
form.attr('class', $(self).attr('class'));
|
||||
} else {
|
||||
form.attr('class', settings.cssclass);
|
||||
}
|
||||
}
|
||||
|
||||
if (settings.style) {
|
||||
if ('inherit' == settings.style) {
|
||||
form.attr('style', $(self).attr('style'));
|
||||
/* IE needs the second line or display wont be inherited */
|
||||
form.css('display', $(self).css('display'));
|
||||
} else {
|
||||
form.attr('style', settings.style);
|
||||
}
|
||||
}
|
||||
|
||||
/* add main input element to form and store it in input */
|
||||
var input = element.apply(form, [settings, self]);
|
||||
|
||||
/* set input content via POST, GET, given data or existing value */
|
||||
var input_content;
|
||||
|
||||
if (settings.loadurl) {
|
||||
var t = setTimeout(function() {
|
||||
input.disabled = true;
|
||||
content.apply(form, [settings.loadtext, settings, self]);
|
||||
}, 100);
|
||||
|
||||
var loaddata = {};
|
||||
loaddata[settings.id] = self.id;
|
||||
if ($.isFunction(settings.loaddata)) {
|
||||
$.extend(loaddata, settings.loaddata.apply(self, [self.revert, settings]));
|
||||
} else {
|
||||
$.extend(loaddata, settings.loaddata);
|
||||
}
|
||||
$.ajax({
|
||||
type : settings.loadtype,
|
||||
url : settings.loadurl,
|
||||
data : loaddata,
|
||||
async : false,
|
||||
success: function(result) {
|
||||
window.clearTimeout(t);
|
||||
input_content = result;
|
||||
input.disabled = false;
|
||||
}
|
||||
});
|
||||
} else if (settings.data) {
|
||||
input_content = settings.data;
|
||||
if ($.isFunction(settings.data)) {
|
||||
input_content = settings.data.apply(self, [self.revert, settings]);
|
||||
}
|
||||
} else {
|
||||
input_content = self.revert;
|
||||
}
|
||||
content.apply(form, [input_content, settings, self]);
|
||||
|
||||
input.attr('name', settings.name);
|
||||
|
||||
/* add buttons to the form */
|
||||
buttons.apply(form, [settings, self]);
|
||||
|
||||
/* add created form to self */
|
||||
$(self).append(form);
|
||||
|
||||
/* attach 3rd party plugin if requested */
|
||||
plugin.apply(form, [settings, self]);
|
||||
|
||||
/* focus to first visible form element */
|
||||
$(':input:visible:enabled:first', form).focus();
|
||||
|
||||
/* highlight input contents when requested */
|
||||
if (settings.select) {
|
||||
input.select();
|
||||
}
|
||||
|
||||
/* discard changes if pressing esc */
|
||||
input.keydown(function(e) {
|
||||
if (e.keyCode == 27) {
|
||||
e.preventDefault();
|
||||
//self.reset();
|
||||
reset.apply(form, [settings, self]);
|
||||
}
|
||||
});
|
||||
|
||||
/* discard, submit or nothing with changes when clicking outside */
|
||||
/* do nothing is usable when navigating with tab */
|
||||
var t;
|
||||
if ('cancel' == settings.onblur) {
|
||||
input.blur(function(e) {
|
||||
/* prevent canceling if submit was clicked */
|
||||
t = setTimeout(function() {
|
||||
reset.apply(form, [settings, self]);
|
||||
}, 500);
|
||||
});
|
||||
} else if ('submit' == settings.onblur) {
|
||||
input.blur(function(e) {
|
||||
/* prevent double submit if submit was clicked */
|
||||
t = setTimeout(function() {
|
||||
form.submit();
|
||||
}, 200);
|
||||
});
|
||||
} else if ($.isFunction(settings.onblur)) {
|
||||
input.blur(function(e) {
|
||||
settings.onblur.apply(self, [input.val(), settings]);
|
||||
});
|
||||
} else {
|
||||
input.blur(function(e) {
|
||||
/* TODO: maybe something here */
|
||||
});
|
||||
}
|
||||
|
||||
form.submit(function(e) {
|
||||
|
||||
if (t) {
|
||||
clearTimeout(t);
|
||||
}
|
||||
|
||||
/* do no submit */
|
||||
e.preventDefault();
|
||||
|
||||
/* call before submit hook. */
|
||||
/* if it returns false abort submitting */
|
||||
if (false !== onsubmit.apply(form, [settings, self])) {
|
||||
/* custom inputs call before submit hook. */
|
||||
/* if it returns false abort submitting */
|
||||
if (false !== submit.apply(form, [settings, self])) {
|
||||
|
||||
/* check if given target is function */
|
||||
if ($.isFunction(settings.target)) {
|
||||
var str = settings.target.apply(self, [input.val(), settings]);
|
||||
$(self).html(str);
|
||||
self.editing = false;
|
||||
callback.apply(self, [self.innerHTML, settings]);
|
||||
/* TODO: this is not dry */
|
||||
if (!$.trim($(self).html())) {
|
||||
$(self).html(settings.placeholder);
|
||||
}
|
||||
} else {
|
||||
/* add edited content and id of edited element to POST */
|
||||
var submitdata = {};
|
||||
submitdata[settings.name] = input.val();
|
||||
submitdata[settings.id] = self.id;
|
||||
/* add extra data to be POST:ed */
|
||||
if ($.isFunction(settings.submitdata)) {
|
||||
$.extend(submitdata, settings.submitdata.apply(self, [self.revert, settings]));
|
||||
} else {
|
||||
$.extend(submitdata, settings.submitdata);
|
||||
}
|
||||
|
||||
/* quick and dirty PUT support */
|
||||
if ('PUT' == settings.method) {
|
||||
submitdata['_method'] = 'put';
|
||||
}
|
||||
|
||||
/* show the saving indicator */
|
||||
$(self).html(settings.indicator);
|
||||
|
||||
/* defaults for ajaxoptions */
|
||||
var ajaxoptions = {
|
||||
type : 'POST',
|
||||
data : submitdata,
|
||||
dataType: 'html',
|
||||
url : settings.target,
|
||||
success : function(result, status) {
|
||||
if (ajaxoptions.dataType == 'html') {
|
||||
$(self).html(result);
|
||||
}
|
||||
self.editing = false;
|
||||
callback.apply(self, [result, settings]);
|
||||
if (!$.trim($(self).html())) {
|
||||
$(self).html(settings.placeholder);
|
||||
}
|
||||
},
|
||||
error : function(xhr, status, error) {
|
||||
onerror.apply(form, [settings, self, xhr]);
|
||||
}
|
||||
};
|
||||
|
||||
/* override with what is given in settings.ajaxoptions */
|
||||
$.extend(ajaxoptions, settings.ajaxoptions);
|
||||
$.ajax(ajaxoptions);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* show tooltip again */
|
||||
$(self).attr('title', settings.tooltip);
|
||||
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
/* privileged methods */
|
||||
this.reset = function(form) {
|
||||
/* prevent calling reset twice when blurring */
|
||||
if (this.editing) {
|
||||
/* before reset hook, if it returns false abort reseting */
|
||||
if (false !== onreset.apply(form, [settings, self])) {
|
||||
$(self).html(self.revert);
|
||||
self.editing = false;
|
||||
if (!$.trim($(self).html())) {
|
||||
$(self).html(settings.placeholder);
|
||||
}
|
||||
/* show tooltip again */
|
||||
if (settings.tooltip) {
|
||||
$(self).attr('title', settings.tooltip);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
|
||||
$.editable = {
|
||||
types: {
|
||||
defaults: {
|
||||
element : function(settings, original) {
|
||||
var input = $('<input type="hidden"></input>');
|
||||
$(this).append(input);
|
||||
return(input);
|
||||
},
|
||||
content : function(string, settings, original) {
|
||||
$(':input:first', this).val(string);
|
||||
},
|
||||
reset : function(settings, original) {
|
||||
original.reset(this);
|
||||
},
|
||||
buttons : function(settings, original) {
|
||||
var form = this;
|
||||
if (settings.submit) {
|
||||
/* if given html string use that */
|
||||
if (settings.submit.match(/>$/)) {
|
||||
var submit = $(settings.submit).click(function() {
|
||||
if (submit.attr("type") != "submit") {
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
/* otherwise use button with given string as text */
|
||||
} else {
|
||||
var submit = $('<button type="submit" />');
|
||||
submit.html(settings.submit);
|
||||
}
|
||||
$(this).append(submit);
|
||||
}
|
||||
if (settings.cancel) {
|
||||
/* if given html string use that */
|
||||
if (settings.cancel.match(/>$/)) {
|
||||
var cancel = $(settings.cancel);
|
||||
/* otherwise use button with given string as text */
|
||||
} else {
|
||||
var cancel = $('<button type="cancel" />');
|
||||
cancel.html(settings.cancel);
|
||||
}
|
||||
$(this).append(cancel);
|
||||
|
||||
$(cancel).click(function(event) {
|
||||
//original.reset();
|
||||
if ($.isFunction($.editable.types[settings.type].reset)) {
|
||||
var reset = $.editable.types[settings.type].reset;
|
||||
} else {
|
||||
var reset = $.editable.types['defaults'].reset;
|
||||
}
|
||||
reset.apply(form, [settings, original]);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
text: {
|
||||
element : function(settings, original) {
|
||||
var input = $('<input />');
|
||||
if (settings.width != 'none') { input.width(settings.width); }
|
||||
if (settings.height != 'none') { input.height(settings.height); }
|
||||
/* https://bugzilla.mozilla.org/show_bug.cgi?id=236791 */
|
||||
//input[0].setAttribute('autocomplete','off');
|
||||
input.attr('autocomplete','off');
|
||||
$(this).append(input);
|
||||
return(input);
|
||||
}
|
||||
},
|
||||
textarea: {
|
||||
element : function(settings, original) {
|
||||
var textarea = $('<textarea />');
|
||||
if (settings.rows) {
|
||||
textarea.attr('rows', settings.rows);
|
||||
} else if (settings.height != "none") {
|
||||
textarea.height(settings.height);
|
||||
}
|
||||
if (settings.cols) {
|
||||
textarea.attr('cols', settings.cols);
|
||||
} else if (settings.width != "none") {
|
||||
textarea.width(settings.width);
|
||||
}
|
||||
$(this).append(textarea);
|
||||
return(textarea);
|
||||
}
|
||||
},
|
||||
select: {
|
||||
element : function(settings, original) {
|
||||
var select = $('<select />');
|
||||
$(this).append(select);
|
||||
return(select);
|
||||
},
|
||||
content : function(data, settings, original) {
|
||||
/* If it is string assume it is json. */
|
||||
if (String == data.constructor) {
|
||||
eval ('var json = ' + data);
|
||||
} else {
|
||||
/* Otherwise assume it is a hash already. */
|
||||
var json = data;
|
||||
}
|
||||
for (var key in json) {
|
||||
if (!json.hasOwnProperty(key)) {
|
||||
continue;
|
||||
}
|
||||
if ('selected' == key) {
|
||||
continue;
|
||||
}
|
||||
var option = $('<option />').val(key).append(json[key]);
|
||||
$('select', this).append(option);
|
||||
}
|
||||
/* Loop option again to set selected. IE needed this... */
|
||||
$('select', this).children().each(function() {
|
||||
if ($(this).val() == json['selected'] ||
|
||||
$(this).text() == $.trim(original.revert)) {
|
||||
$(this).attr('selected', 'selected');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/* Add new input type */
|
||||
addInputType: function(name, input) {
|
||||
$.editable.types[name] = input;
|
||||
}
|
||||
};
|
||||
|
||||
// publicly accessible defaults
|
||||
$.fn.editable.defaults = {
|
||||
name : 'value',
|
||||
id : 'id',
|
||||
type : 'text',
|
||||
width : 'auto',
|
||||
height : 'auto',
|
||||
event : 'click.editable',
|
||||
onblur : 'cancel',
|
||||
loadtype : 'GET',
|
||||
loadtext : 'Loading...',
|
||||
placeholder: 'Click to edit',
|
||||
loaddata : {},
|
||||
submitdata : {},
|
||||
ajaxoptions: {}
|
||||
};
|
||||
|
||||
})(jQuery);
|
|
@ -46,7 +46,7 @@ class PostProcessor(object):
|
|||
FOLDER_NAME = 2
|
||||
FILE_NAME = 3
|
||||
|
||||
def __init__(self, nzb_name, nzb_folder, module=None):
|
||||
def __init__(self, nzb_name, nzb_folder, module=None, queue=None):
|
||||
"""
|
||||
Creates a new post processor with the given file path and optionally an NZB name.
|
||||
|
||||
|
@ -72,10 +72,11 @@ class PostProcessor(object):
|
|||
self.module = module + '[POST-PROCESSING]'
|
||||
else:
|
||||
self.module = '[POST-PROCESSING]'
|
||||
if queue: self.queue = queue
|
||||
#self.in_history = False
|
||||
#self.release_group = None
|
||||
#self.is_proper = False
|
||||
|
||||
self.valreturn = []
|
||||
self.log = ''
|
||||
|
||||
def _log(self, message, level=logger.message): #level=logger.MESSAGE):
|
||||
|
@ -109,7 +110,7 @@ class PostProcessor(object):
|
|||
try:
|
||||
p = subprocess.Popen(script_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=mylar.PROG_DIR)
|
||||
out, err = p.communicate() #@UnusedVariable
|
||||
self._log(u"Script result: "+str(out))
|
||||
self._log(u"Script result: " + out)
|
||||
except OSError, e:
|
||||
self._log(u"Unable to run pre_script: " + str(script_cmd))
|
||||
|
||||
|
@ -134,7 +135,7 @@ class PostProcessor(object):
|
|||
try:
|
||||
p = subprocess.Popen(script_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=mylar.PROG_DIR)
|
||||
out, err = p.communicate() #@UnusedVariable
|
||||
self._log(u"Script result: "+str(out))
|
||||
self._log(u"Script result: " + out)
|
||||
except OSError, e:
|
||||
self._log(u"Unable to run extra_script: " + str(script_cmd))
|
||||
|
||||
|
@ -327,7 +328,10 @@ class PostProcessor(object):
|
|||
nzbiss = myDB.selectone("SELECT * from nzblog WHERE nzbname=?", [nzbname]).fetchone()
|
||||
if nzbiss is None:
|
||||
logger.error(module + ' Unable to locate downloaded file to rename. PostProcessing aborted.')
|
||||
return
|
||||
self._log('Unable to locate downloaded file to rename. PostProcessing aborted.')
|
||||
self.valreturn.append({"self.log" : self.log,
|
||||
"mode" : 'stop'})
|
||||
return self.queue.put(self.valreturn)
|
||||
else:
|
||||
self._log("I corrected and found the nzb as : " + str(nzbname))
|
||||
logger.fdebug(module + ' Auto-corrected and found the nzb as : ' + str(nzbname))
|
||||
|
@ -683,7 +687,14 @@ class PostProcessor(object):
|
|||
elif pcheck == "unrar error":
|
||||
self._log("This is a corrupt archive - whether CRC errors or it's incomplete. Marking as BAD, and retrying a different copy.")
|
||||
logger.error(module + ' This is a corrupt archive - whether CRC errors or it is incomplete. Marking as BAD, and retrying a different copy.')
|
||||
return self.log
|
||||
self.valreturn.append({"self.log": self.log,
|
||||
"mode": 'fail',
|
||||
"issueid": issueid,
|
||||
"comicid": comicid,
|
||||
"comicname": comicnzb['ComicName'],
|
||||
"issuenumber": issuenzb['Issue_Number'],
|
||||
"annchk": annchk})
|
||||
return self.queue.put(self.valreturn)
|
||||
else:
|
||||
otofilename = pcheck
|
||||
self._log("Sucessfully wrote metadata to .cbz - Continuing..")
|
||||
|
@ -728,7 +739,7 @@ class PostProcessor(object):
|
|||
|
||||
#if it's a Manual Run, use the ml['ComicLocation'] for the exact filename.
|
||||
if ml is None:
|
||||
for root, dirnames, filenames in os.walk(self.nzb_folder):
|
||||
for root, dirnames, filenames in os.walk(self.nzb_folder, followlinks=True):
|
||||
for filename in filenames:
|
||||
if filename.lower().endswith(extensions):
|
||||
odir = root
|
||||
|
@ -817,7 +828,10 @@ class PostProcessor(object):
|
|||
self._log("Post-Processing ABORTED.")
|
||||
logger.warn(module + ' Failed to move directory : ' + src + ' to ' + dst + ' - check directory and manually re-run')
|
||||
logger.warn(module + ' Post-Processing ABORTED')
|
||||
return
|
||||
self.valreturn.append({"self.log" : self.log,
|
||||
"mode" : 'stop'})
|
||||
return self.queue.put(self.valreturn)
|
||||
|
||||
#tidyup old path
|
||||
try:
|
||||
shutil.rmtree(self.nzb_folder)
|
||||
|
@ -826,8 +840,9 @@ class PostProcessor(object):
|
|||
self._log("Post-Processing ABORTED.")
|
||||
logger.warn(module + ' Failed to remove temporary directory : ' + self.nzb_folder)
|
||||
logger.warn(module + ' Post-Processing ABORTED')
|
||||
return
|
||||
|
||||
self.valreturn.append({"self.log" : self.log,
|
||||
"mode" : 'stop'})
|
||||
return self.queue.put(self.valreturn)
|
||||
self._log("Removed temporary directory : " + str(self.nzb_folder))
|
||||
logger.fdebug(module + ' Removed temporary directory : ' + self.nzb_folder)
|
||||
else:
|
||||
|
@ -848,7 +863,10 @@ class PostProcessor(object):
|
|||
except (OSError, IOError):
|
||||
logger.fdebug(module + ' Failed to move directory - check directories and manually re-run.')
|
||||
logger.fdebug(module + ' Post-Processing ABORTED.')
|
||||
return
|
||||
|
||||
self.valreturn.append({"self.log" : self.log,
|
||||
"mode" : 'stop'})
|
||||
return self.queue.put(self.valreturn)
|
||||
logger.fdebug(module + ' Successfully moved to : ' + dst)
|
||||
|
||||
#tidyup old path
|
||||
|
@ -921,7 +939,12 @@ class PostProcessor(object):
|
|||
#manual run + not snatched torrent (or normal manual-run)
|
||||
logger.info(module + ' Post-Processing completed for: ' + series + ' ' + dispiss )
|
||||
self._log(u"Post Processing SUCCESSFUL! ")
|
||||
return self.log
|
||||
self.valreturn.append({"self.log" : self.log,
|
||||
"mode" : 'stop',
|
||||
"issueid" : issueid,
|
||||
"comicid" : comicid})
|
||||
|
||||
return self.queue.put(self.valreturn)
|
||||
|
||||
if annchk == "no":
|
||||
prline = series + '(' + issueyear + ') - issue #' + issuenumOG
|
||||
|
@ -952,7 +975,15 @@ class PostProcessor(object):
|
|||
|
||||
logger.info(module + ' Post-Processing completed for: ' + series + ' ' + dispiss )
|
||||
self._log(u"Post Processing SUCCESSFUL! ")
|
||||
return self.log
|
||||
|
||||
self.valreturn.append({"self.log" : self.log,
|
||||
"mode" : 'stop',
|
||||
"issueid" : issueid,
|
||||
"comicid" : comicid})
|
||||
|
||||
return self.queue.put(self.valreturn)
|
||||
|
||||
|
||||
|
||||
class FolderCheck():
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ import sqlite3
|
|||
import itertools
|
||||
import csv
|
||||
import shutil
|
||||
import Queue
|
||||
import platform
|
||||
import locale
|
||||
from threading import Lock, Thread
|
||||
|
@ -66,6 +67,7 @@ WRITELOCK = False
|
|||
#WeeklyScheduler = None
|
||||
#VersionScheduler = None
|
||||
#FolderMonitorScheduler = None
|
||||
QUEUE = Queue.Queue()
|
||||
|
||||
DATA_DIR = None
|
||||
DBLOCK = False
|
||||
|
@ -119,6 +121,7 @@ DESTINATION_DIR = None
|
|||
CHMOD_DIR = None
|
||||
CHMOD_FILE = None
|
||||
USENET_RETENTION = None
|
||||
CREATE_FOLDERS = True
|
||||
|
||||
ADD_COMICS = False
|
||||
COMIC_DIR = None
|
||||
|
@ -132,6 +135,7 @@ NZB_STARTUP_SEARCH = False
|
|||
LIBRARYSCAN_INTERVAL = 300
|
||||
DOWNLOAD_SCAN_INTERVAL = 5
|
||||
CHECK_FOLDER = None
|
||||
ENABLE_CHECK_FOLDER = False
|
||||
INTERFACE = None
|
||||
|
||||
PREFERRED_QUALITY = 0
|
||||
|
@ -179,6 +183,7 @@ SKIPPED2WANTED = False
|
|||
CVINFO = False
|
||||
LOG_LEVEL = None
|
||||
POST_PROCESSING = 1
|
||||
POST_PROCESSING_SCRIPT = None
|
||||
|
||||
NZB_DOWNLOADER = None #0 = sabnzbd, #1 = nzbget, #2 = blackhole
|
||||
|
||||
|
@ -276,6 +281,9 @@ ENABLE_RSS = 0
|
|||
RSS_CHECKINTERVAL = 20
|
||||
RSS_LASTRUN = None
|
||||
|
||||
FAILED_DOWNLOAD_HANDLING = 0
|
||||
FAILED_AUTO = 0
|
||||
|
||||
ENABLE_TORRENTS = 0
|
||||
MINSEEDS = 0
|
||||
TORRENT_LOCAL = 0
|
||||
|
@ -346,8 +354,8 @@ def initialize():
|
|||
with INIT_LOCK:
|
||||
|
||||
global __INITIALIZED__, COMICVINE_API, DEFAULT_CVAPI, CVAPI_COUNT, CVAPI_TIME, CVAPI_MAX, FULL_PATH, PROG_DIR, VERBOSE, DAEMON, COMICSORT, DATA_DIR, CONFIG_FILE, CFG, CONFIG_VERSION, LOG_DIR, CACHE_DIR, MAX_LOGSIZE, LOGVERBOSE, OLDCONFIG_VERSION, OS_DETECT, OS_LANG, OS_ENCODING, \
|
||||
HTTP_PORT, HTTP_HOST, HTTP_USERNAME, HTTP_PASSWORD, HTTP_ROOT, HTTPS_FORCE_ON, API_ENABLED, API_KEY, LAUNCH_BROWSER, GIT_PATH, SAFESTART, \
|
||||
CURRENT_VERSION, LATEST_VERSION, CHECK_GITHUB, CHECK_GITHUB_ON_STARTUP, CHECK_GITHUB_INTERVAL, USER_AGENT, DESTINATION_DIR, \
|
||||
queue, HTTP_PORT, HTTP_HOST, HTTP_USERNAME, HTTP_PASSWORD, HTTP_ROOT, HTTPS_FORCE_ON, API_ENABLED, API_KEY, LAUNCH_BROWSER, GIT_PATH, SAFESTART, \
|
||||
CURRENT_VERSION, LATEST_VERSION, CHECK_GITHUB, CHECK_GITHUB_ON_STARTUP, CHECK_GITHUB_INTERVAL, USER_AGENT, DESTINATION_DIR, CREATE_FOLDERS, \
|
||||
DOWNLOAD_DIR, USENET_RETENTION, SEARCH_INTERVAL, NZB_STARTUP_SEARCH, INTERFACE, AUTOWANT_ALL, AUTOWANT_UPCOMING, ZERO_LEVEL, ZERO_LEVEL_N, COMIC_COVER_LOCAL, HIGHCOUNT, \
|
||||
LIBRARYSCAN, LIBRARYSCAN_INTERVAL, DOWNLOAD_SCAN_INTERVAL, NZB_DOWNLOADER, USE_SABNZBD, SAB_HOST, SAB_USERNAME, SAB_PASSWORD, SAB_APIKEY, SAB_CATEGORY, SAB_PRIORITY, SAB_DIRECTORY, USE_BLACKHOLE, BLACKHOLE_DIR, ADD_COMICS, COMIC_DIR, IMP_MOVE, IMP_RENAME, IMP_METADATA, \
|
||||
USE_NZBGET, NZBGET_HOST, NZBGET_PORT, NZBGET_USERNAME, NZBGET_PASSWORD, NZBGET_CATEGORY, NZBGET_PRIORITY, NZBGET_DIRECTORY, NZBSU, NZBSU_UID, NZBSU_APIKEY, DOGNZB, DOGNZB_UID, DOGNZB_APIKEY, \
|
||||
|
@ -356,10 +364,10 @@ def initialize():
|
|||
ENABLE_META, CMTAGGER_PATH, CT_TAG_CR, CT_TAG_CBL, CT_CBZ_OVERWRITE, 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, SNATCHEDTORRENT_NOTIFY, \
|
||||
ENABLE_RSS, RSS_CHECKINTERVAL, RSS_LASTRUN, FAILED_DOWNLOAD_HANDLING, FAILED_AUTO, 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, \
|
||||
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, POST_PROCESSING_SCRIPT, SEARCH_DELAY, GRABBAG_DIR, READ2FILENAME, STORYARCDIR, CVURL, CVAPIFIX, CHECK_FOLDER, ENABLE_CHECK_FOLDER, \
|
||||
COMIC_LOCATION, QUAL_ALTVERS, QUAL_SCANNER, QUAL_TYPE, QUAL_QUALITY, ENABLE_EXTRA_SCRIPTS, EXTRA_SCRIPTS, ENABLE_PRE_SCRIPTS, PRE_SCRIPTS, PULLNEW, COUNT_ISSUES, COUNT_HAVES, COUNT_COMICS, SYNO_FIX, CHMOD_FILE, CHMOD_DIR, ANNUALS_ON, CV_ONLY, CV_ONETIMER, WEEKFOLDER, UMASK
|
||||
|
||||
if __INITIALIZED__:
|
||||
|
@ -417,6 +425,7 @@ def initialize():
|
|||
CHECK_GITHUB_INTERVAL = check_setting_int(CFG, 'General', 'check_github_interval', 360)
|
||||
|
||||
DESTINATION_DIR = check_setting_str(CFG, 'General', 'destination_dir', '')
|
||||
CREATE_FOLDERS = bool(check_setting_int(CFG, 'General', 'create_folders', 1))
|
||||
CHMOD_DIR = check_setting_str(CFG, 'General', 'chmod_dir', '0777')
|
||||
CHMOD_FILE = check_setting_str(CFG, 'General', 'chmod_file', '0660')
|
||||
USENET_RETENTION = check_setting_int(CFG, 'General', 'usenet_retention', '1500')
|
||||
|
@ -432,6 +441,7 @@ def initialize():
|
|||
IMP_METADATA = bool(check_setting_int(CFG, 'General', 'imp_metadata', 0))
|
||||
DOWNLOAD_SCAN_INTERVAL = check_setting_int(CFG, 'General', 'download_scan_interval', 5)
|
||||
CHECK_FOLDER = check_setting_str(CFG, 'General', 'check_folder', '')
|
||||
ENABLE_CHECK_FOLDER = bool(check_setting_int(CFG, 'General', 'enable_check_folder', 0))
|
||||
INTERFACE = check_setting_str(CFG, 'General', 'interface', 'default')
|
||||
AUTOWANT_ALL = bool(check_setting_int(CFG, 'General', 'autowant_all', 0))
|
||||
AUTOWANT_UPCOMING = bool(check_setting_int(CFG, 'General', 'autowant_upcoming', 1))
|
||||
|
@ -520,6 +530,7 @@ def initialize():
|
|||
ENABLE_PRE_SCRIPTS = bool(check_setting_int(CFG, 'General', 'enable_pre_scripts', 0))
|
||||
PRE_SCRIPTS = check_setting_str(CFG, 'General', 'pre_scripts', '')
|
||||
POST_PROCESSING = bool(check_setting_int(CFG, 'General', 'post_processing', 1))
|
||||
POST_PROCESSING_SCRIPT = check_setting_str(CFG, 'General', 'post_processing_script', '')
|
||||
|
||||
ENABLE_META = bool(check_setting_int(CFG, 'General', 'enable_meta', 0))
|
||||
CMTAGGER_PATH = check_setting_str(CFG, 'General', 'cmtagger_path', '')
|
||||
|
@ -534,6 +545,8 @@ def initialize():
|
|||
RSS_CHECKINTERVAL = check_setting_str(CFG, 'General', 'rss_checkinterval', '20')
|
||||
RSS_LASTRUN = check_setting_str(CFG, 'General', 'rss_lastrun', '')
|
||||
|
||||
FAILED_DOWNLOAD_HANDLING = bool(check_setting_int(CFG, 'General', 'failed_download_handling', 0))
|
||||
FAILED_AUTO = bool(check_setting_int(CFG, 'General', 'failed_auto', 0))
|
||||
ENABLE_TORRENTS = bool(check_setting_int(CFG, 'Torrents', 'enable_torrents', 0))
|
||||
MINSEEDS = check_setting_str(CFG, 'Torrents', 'minseeds', '0')
|
||||
TORRENT_LOCAL = bool(check_setting_int(CFG, 'Torrents', 'torrent_local', 0))
|
||||
|
@ -594,12 +607,13 @@ def initialize():
|
|||
PR = []
|
||||
|
||||
#add torrents to provider counter.
|
||||
if ENABLE_CBT:
|
||||
PR.append('cbt')
|
||||
PR_NUM +=1
|
||||
if ENABLE_KAT:
|
||||
PR.append('kat')
|
||||
PR_NUM +=1
|
||||
if ENABLE_TORRENT_SEARCH:
|
||||
if ENABLE_CBT:
|
||||
PR.append('cbt')
|
||||
PR_NUM +=1
|
||||
if ENABLE_KAT:
|
||||
PR.append('kat')
|
||||
PR_NUM +=1
|
||||
|
||||
|
||||
NZBSU = bool(check_setting_int(CFG, 'NZBsu', 'nzbsu', 0))
|
||||
|
@ -720,19 +734,20 @@ def initialize():
|
|||
TMPPR_NUM +=1
|
||||
|
||||
if PR_NUM != TMPPR_NUM:
|
||||
#print 'existing Order count does not match New Order count'
|
||||
if PR_NUM > TMPPR_NUM:
|
||||
#print 'New entries exist, appending to end as default ordering'
|
||||
TMPPR_NUM = 0
|
||||
while (TMPPR_NUM < PR_NUM):
|
||||
#print 'checking entry #' + str(TMPPR_NUM) + ': ' + str(PR[TMPPR_NUM])
|
||||
if not any(d.get("provider",None) == str(PR[TMPPR_NUM]) for d in PROV_ORDER):
|
||||
#print 'new provider should be : ' + str(TMPPR_NUM) + ' -- ' + str(PR[TMPPR_NUM])
|
||||
PROV_ORDER.append({"order_seq": TMPPR_NUM,
|
||||
"provider": str(PR[TMPPR_NUM])})
|
||||
# print 'existing Order count does not match New Order count'
|
||||
# if PR_NUM > TMPPR_NUM:
|
||||
# print 'New entries exist, appending to end as default ordering'
|
||||
TMPPR_NUM = 0
|
||||
while (TMPPR_NUM < PR_NUM):
|
||||
#print 'checking entry #' + str(TMPPR_NUM) + ': ' + str(PR[TMPPR_NUM])
|
||||
if not any(d.get("provider",None) == str(PR[TMPPR_NUM]) for d in PROV_ORDER):
|
||||
new_order_seqnum = len(PROV_ORDER)
|
||||
#print 'new provider should be : ' + str(new_order_seqnum) + ' -- ' + str(PR[TMPPR_NUM])
|
||||
PROV_ORDER.append({"order_seq": new_order_seqnum,
|
||||
"provider": str(PR[TMPPR_NUM])})
|
||||
#else:
|
||||
#print 'provider already exists at : ' + str(TMPPR_NUM) + ' -- ' + str(PR[TMPPR_NUM])
|
||||
TMPPR_NUM +=1
|
||||
#print 'provider already exists at : ' + str(new_order_seqnum) + ' -- ' + str(PR[TMPPR_NUM])
|
||||
TMPPR_NUM +=1
|
||||
|
||||
|
||||
#this isn't ready for primetime just yet...
|
||||
|
@ -1052,6 +1067,7 @@ def config_write():
|
|||
new_config['General']['check_github_interval'] = CHECK_GITHUB_INTERVAL
|
||||
|
||||
new_config['General']['destination_dir'] = DESTINATION_DIR
|
||||
new_config['General']['create_folders'] = int(CREATE_FOLDERS)
|
||||
new_config['General']['chmod_dir'] = CHMOD_DIR
|
||||
new_config['General']['chmod_file'] = CHMOD_FILE
|
||||
new_config['General']['usenet_retention'] = USENET_RETENTION
|
||||
|
@ -1065,6 +1081,7 @@ def config_write():
|
|||
new_config['General']['imp_move'] = int(IMP_MOVE)
|
||||
new_config['General']['imp_rename'] = int(IMP_RENAME)
|
||||
new_config['General']['imp_metadata'] = int(IMP_METADATA)
|
||||
new_config['General']['enable_check_folder'] = int(ENABLE_CHECK_FOLDER)
|
||||
new_config['General']['download_scan_interval'] = DOWNLOAD_SCAN_INTERVAL
|
||||
new_config['General']['check_folder'] = CHECK_FOLDER
|
||||
new_config['General']['interface'] = INTERFACE
|
||||
|
@ -1103,6 +1120,7 @@ def config_write():
|
|||
new_config['General']['enable_pre_scripts'] = int(ENABLE_PRE_SCRIPTS)
|
||||
new_config['General']['pre_scripts'] = PRE_SCRIPTS
|
||||
new_config['General']['post_processing'] = int(POST_PROCESSING)
|
||||
new_config['General']['post_processing_script'] = POST_PROCESSING_SCRIPT
|
||||
new_config['General']['weekfolder'] = int(WEEKFOLDER)
|
||||
new_config['General']['locmove'] = int(LOCMOVE)
|
||||
new_config['General']['newcom_dir'] = NEWCOM_DIR
|
||||
|
@ -1118,6 +1136,8 @@ def config_write():
|
|||
new_config['General']['enable_rss'] = int(ENABLE_RSS)
|
||||
new_config['General']['rss_checkinterval'] = RSS_CHECKINTERVAL
|
||||
new_config['General']['rss_lastrun'] = RSS_LASTRUN
|
||||
new_config['General']['failed_download_handling'] = int(FAILED_DOWNLOAD_HANDLING)
|
||||
new_config['General']['failed_auto'] = int(FAILED_AUTO)
|
||||
|
||||
# Need to unpack the providers for saving in config.ini
|
||||
if PROVIDER_ORDER is None:
|
||||
|
@ -1290,8 +1310,7 @@ def start():
|
|||
SCHED.add_interval_job(versioncheck.checkGithub, minutes=CHECK_GITHUB_INTERVAL)
|
||||
|
||||
#run checkFolder every X minutes (basically Manual Run Post-Processing)
|
||||
logger.info('Monitor folder set to : ' + str(CHECK_FOLDER))
|
||||
if CHECK_FOLDER:
|
||||
if ENABLE_CHECK_FOLDER:
|
||||
if DOWNLOAD_SCAN_INTERVAL >0:
|
||||
logger.info('Enabling folder monitor for : ' + str(CHECK_FOLDER) + ' every ' + str(DOWNLOAD_SCAN_INTERVAL) + ' minutes.')
|
||||
#FolderMonitorScheduler.thread.start()
|
||||
|
@ -1307,19 +1326,20 @@ def dbcheck():
|
|||
conn=sqlite3.connect(DB_FILE)
|
||||
c=conn.cursor()
|
||||
|
||||
c.execute('CREATE TABLE IF NOT EXISTS comics (ComicID TEXT UNIQUE, ComicName TEXT, ComicSortName TEXT, ComicYear TEXT, DateAdded TEXT, Status TEXT, IncludeExtras INTEGER, Have INTEGER, Total INTEGER, ComicImage TEXT, ComicPublisher TEXT, ComicLocation TEXT, ComicPublished TEXT, LatestIssue TEXT, LatestDate TEXT, Description TEXT, QUALalt_vers TEXT, QUALtype TEXT, QUALscanner TEXT, QUALquality TEXT, LastUpdated TEXT, AlternateSearch TEXT, UseFuzzy TEXT, ComicVersion TEXT, SortOrder INTEGER, ForceContinuing INTEGER)')
|
||||
c.execute('CREATE TABLE IF NOT EXISTS issues (IssueID TEXT, ComicName TEXT, IssueName TEXT, Issue_Number TEXT, DateAdded TEXT, Status TEXT, Type TEXT, ComicID, ArtworkURL Text, ReleaseDate TEXT, Location TEXT, IssueDate TEXT, Int_IssueNumber INT, ComicSize TEXT, AltIssueNumber TEXT)')
|
||||
c.execute('CREATE TABLE IF NOT EXISTS comics (ComicID TEXT UNIQUE, ComicName TEXT, ComicSortName TEXT, ComicYear TEXT, DateAdded TEXT, Status TEXT, IncludeExtras INTEGER, Have INTEGER, Total INTEGER, ComicImage TEXT, ComicPublisher TEXT, ComicLocation TEXT, ComicPublished TEXT, LatestIssue TEXT, LatestDate TEXT, Description TEXT, QUALalt_vers TEXT, QUALtype TEXT, QUALscanner TEXT, QUALquality TEXT, LastUpdated TEXT, AlternateSearch TEXT, UseFuzzy TEXT, ComicVersion TEXT, SortOrder INTEGER, ForceContinuing INTEGER, ComicName_Filesafe TEXT)')
|
||||
c.execute('CREATE TABLE IF NOT EXISTS issues (IssueID TEXT, ComicName TEXT, IssueName TEXT, Issue_Number TEXT, DateAdded TEXT, Status TEXT, Type TEXT, ComicID, ArtworkURL Text, ReleaseDate TEXT, Location TEXT, IssueDate TEXT, Int_IssueNumber INT, ComicSize TEXT, AltIssueNumber TEXT, IssueDate_Edit TEXT)')
|
||||
c.execute('CREATE TABLE IF NOT EXISTS snatched (IssueID TEXT, ComicName TEXT, Issue_Number TEXT, Size INTEGER, DateAdded TEXT, Status TEXT, FolderName TEXT, ComicID TEXT, Provider TEXT)')
|
||||
c.execute('CREATE TABLE IF NOT EXISTS upcoming (ComicName TEXT, IssueNumber TEXT, ComicID TEXT, IssueID TEXT, IssueDate TEXT, Status TEXT, DisplayComicName TEXT)')
|
||||
c.execute('CREATE TABLE IF NOT EXISTS nzblog (IssueID TEXT, NZBName TEXT, SARC TEXT)')
|
||||
c.execute('CREATE TABLE IF NOT EXISTS nzblog (IssueID TEXT, NZBName TEXT, SARC TEXT, PROVIDER TEXT, ID TEXT)')
|
||||
c.execute('CREATE TABLE IF NOT EXISTS weekly (SHIPDATE text, PUBLISHER text, ISSUE text, COMIC VARCHAR(150), EXTRA text, STATUS text)')
|
||||
# c.execute('CREATE TABLE IF NOT EXISTS sablog (nzo_id TEXT, ComicName TEXT, ComicYEAR TEXT, ComicIssue TEXT, name TEXT, nzo_complete TEXT)')
|
||||
c.execute('CREATE TABLE IF NOT EXISTS importresults (impID TEXT, ComicName TEXT, ComicYear TEXT, Status TEXT, ImportDate TEXT, ComicFilename TEXT, ComicLocation TEXT, WatchMatch TEXT, DisplayName TEXT)')
|
||||
c.execute('CREATE TABLE IF NOT EXISTS readlist (IssueID TEXT, ComicName TEXT, Issue_Number TEXT, Status TEXT, DateAdded TEXT, Location TEXT, inCacheDir TEXT, SeriesYear TEXT, ComicID TEXT)')
|
||||
c.execute('CREATE TABLE IF NOT EXISTS readinglist(StoryArcID TEXT, ComicName TEXT, IssueNumber TEXT, SeriesYear TEXT, IssueYEAR TEXT, StoryArc TEXT, TotalIssues TEXT, Status TEXT, inCacheDir TEXT, Location TEXT, IssueArcID TEXT, ReadingOrder INT, IssueID TEXT)')
|
||||
c.execute('CREATE TABLE IF NOT EXISTS annuals (IssueID TEXT, Issue_Number TEXT, IssueName TEXT, IssueDate TEXT, Status TEXT, ComicID TEXT, GCDComicID TEXT, Location TEXT, ComicSize TEXT, Int_IssueNumber INT, ComicName TEXT, ReleaseDate TEXT, ReleaseComicID TEXT, ReleaseComicName TEXT)')
|
||||
c.execute('CREATE TABLE IF NOT EXISTS annuals (IssueID TEXT, Issue_Number TEXT, IssueName TEXT, IssueDate TEXT, Status TEXT, ComicID TEXT, GCDComicID TEXT, Location TEXT, ComicSize TEXT, Int_IssueNumber INT, ComicName TEXT, ReleaseDate TEXT, ReleaseComicID TEXT, ReleaseComicName TEXT, IssueDate_Edit TEXT)')
|
||||
c.execute('CREATE TABLE IF NOT EXISTS rssdb (Title TEXT UNIQUE, Link TEXT, Pubdate TEXT, Site TEXT, Size TEXT)')
|
||||
c.execute('CREATE TABLE IF NOT EXISTS futureupcoming (ComicName TEXT, IssueNumber TEXT, ComicID TEXT, IssueID TEXT, IssueDate TEXT, Publisher TEXT, Status TEXT, DisplayComicName TEXT)')
|
||||
c.execute('CREATE TABLE IF NOT EXISTS failed (ID TEXT, Status TEXT, ComicID TEXT, IssueID TEXT, Provider TEXT, ComicName TEXT, Issue_Number TEXT, NZBName TEXT)')
|
||||
conn.commit
|
||||
c.close
|
||||
#new
|
||||
|
@ -1450,6 +1470,16 @@ def dbcheck():
|
|||
except:
|
||||
c.execute('ALTER TABLE nzblog ADD COLUMN SARC TEXT')
|
||||
|
||||
try:
|
||||
c.execute('SELECT PROVIDER from nzblog')
|
||||
except:
|
||||
c.execute('ALTER TABLE nzblog ADD COLUMN PROVIDER TEXT')
|
||||
|
||||
try:
|
||||
c.execute('SELECT ID from nzblog')
|
||||
except:
|
||||
c.execute('ALTER TABLE nzblog ADD COLUMN ID TEXT')
|
||||
|
||||
try:
|
||||
c.execute('SELECT Location from annuals')
|
||||
except:
|
||||
|
@ -1516,6 +1546,20 @@ def dbcheck():
|
|||
except:
|
||||
c.execute('ALTER TABLE importresults ADD COLUMN DisplayName TEXT')
|
||||
|
||||
try:
|
||||
c.execute('SELECT ComicName_Filesafe from comics')
|
||||
except:
|
||||
c.execute('ALTER TABLE comics ADD COLUMN ComicName_Filesafe TEXT')
|
||||
|
||||
try:
|
||||
c.execute('SELECT IssueDate_Edit from issues')
|
||||
except:
|
||||
c.execute('ALTER TABLE issues ADD COLUMN IssueDate_Edit TEXT')
|
||||
|
||||
try:
|
||||
c.execute('SELECT IssueDate_Edit from annuals')
|
||||
except:
|
||||
c.execute('ALTER TABLE annuals ADD COLUMN IssueDate_Edit TEXT')
|
||||
|
||||
#if it's prior to Wednesday, the issue counts will be inflated by one as the online db's everywhere
|
||||
#prepare for the next 'new' release of a series. It's caught in updater.py, so let's just store the
|
||||
|
|
12
mylar/cv.py
12
mylar/cv.py
|
@ -52,7 +52,7 @@ def pulldetails(comicid,type,issueid=None,offset=1):
|
|||
#this is used ONLY for CV_ONLY
|
||||
PULLURL = mylar.CVURL + 'issues/?api_key=' + str(comicapi) + '&format=xml&filter=id:' + str(issueid) + '&field_list=cover_date'
|
||||
elif type == 'storyarc':
|
||||
PULLURL = mylar.CVURL + 'story_arc/?api_key=' + str(comicapi) + '&format=xml&filter=id:' + str(issueid) + '&field_list=cover_date'
|
||||
PULLURL = mylar.CVURL + 'story_arcs/?api_key=' + str(comicapi) + '&format=xml&filter=name:' + str(issueid) + '&field_list=cover_date'
|
||||
|
||||
#CV API Check here.
|
||||
if mylar.CVAPI_COUNT == 0 or mylar.CVAPI_COUNT >= mylar.CVAPI_MAX:
|
||||
|
@ -71,7 +71,7 @@ def pulldetails(comicid,type,issueid=None,offset=1):
|
|||
return dom
|
||||
|
||||
|
||||
def getComic(comicid,type,issueid=None):
|
||||
def getComic(comicid,type,issueid=None,arc=None):
|
||||
if type == 'issue':
|
||||
offset = 1
|
||||
issue = {}
|
||||
|
@ -111,6 +111,9 @@ def getComic(comicid,type,issueid=None):
|
|||
elif type == 'firstissue':
|
||||
dom = pulldetails(comicid,'firstissue',issueid,1)
|
||||
return GetFirstIssue(issueid,dom)
|
||||
elif type == 'storyarc':
|
||||
dom = pulldetails(arc,'storyarc',None,1)
|
||||
return GetComicInfo(issueid,dom)
|
||||
|
||||
def GetComicInfo(comicid,dom):
|
||||
|
||||
|
@ -333,7 +336,10 @@ def GetIssuesInfo(comicid,dom):
|
|||
tempissue['StoreDate'] = subtrack.getElementsByTagName('store_date')[0].firstChild.wholeText
|
||||
except:
|
||||
tempissue['StoreDate'] = '0000-00-00'
|
||||
tempissue['Issue_Number'] = subtrack.getElementsByTagName('issue_number')[0].firstChild.wholeText
|
||||
try:
|
||||
tempissue['Issue_Number'] = subtrack.getElementsByTagName('issue_number')[0].firstChild.wholeText
|
||||
except:
|
||||
logger.fdebug('No Issue Number available - Trade Paperbacks, Graphic Novels and Compendiums are not supported as of yet.')
|
||||
issuech.append({
|
||||
'Comic_ID': comicid,
|
||||
'Issue_ID': tempissue['Issue_ID'],
|
||||
|
|
|
@ -129,8 +129,10 @@ def listFiles(dir,watchcomic,Publisher,AlternateSearch=None,manual=None,sarc=Non
|
|||
|
||||
#check if a year is present in series title (ie. spider-man 2099)
|
||||
#also check if decimal present in series title (ie. batman beyond 2.0)
|
||||
#- check if brackets present in series title
|
||||
numberinseries = 'False'
|
||||
decimalinseries = 'False'
|
||||
bracketsinseries = 'False'
|
||||
|
||||
for i in watchcomic.split():
|
||||
if ('20' in i or '19' in i):
|
||||
|
@ -154,11 +156,29 @@ def listFiles(dir,watchcomic,Publisher,AlternateSearch=None,manual=None,sarc=Non
|
|||
logger.fdebug('[FILECHECKER] std is : ' + str(std))
|
||||
except:
|
||||
pass
|
||||
#logger.fdebug('[FILECHECKER] i : ' + str(i))
|
||||
if ('(' in i):
|
||||
bracketsinseries = 'True'
|
||||
bracket_length_st = watchcomic.find('(')
|
||||
bracket_length_en = watchcomic.find(')', bracket_length_st)
|
||||
bracket_length = bracket_length_en - bracket_length_st
|
||||
bracket_word = watchcomic[bracket_length_st:bracket_length_en]
|
||||
logger.fdebug('[FILECHECKER] bracketinseries: ' + str(bracket_word))
|
||||
|
||||
logger.fdebug('[FILECHECKER] numberinseries: ' + str(numberinseries))
|
||||
logger.fdebug('[FILECHECKER] decimalinseries: ' + str(decimalinseries))
|
||||
logger.fdebug('[FILECHECKER] bracketinseries: ' + str(bracketsinseries))
|
||||
|
||||
#remove the brackets..
|
||||
if bracketsinseries == 'True':
|
||||
logger.fdebug('[FILECHECKER] modifying subname to accomodate brackets within series title.')
|
||||
subnm_mod2 = re.findall('[^()]+', subname[bracket_length_en:])
|
||||
logger.fdebug('[FILECHECKER] subnm_mod : ' + str(subnm_mod2))
|
||||
|
||||
subnm_mod = re.sub('[\(\)]',' ', subname[:bracket_length_en]) + str(subname[bracket_length_en+1:])
|
||||
logger.fdebug('[FILECHECKER] modified subname is now : ' + str(subnm_mod))
|
||||
subname = subnm_mod
|
||||
|
||||
subnm = re.findall('[^()]+', subname)
|
||||
logger.fdebug('[FILECHECKER] subnm len : ' + str(len(subnm)))
|
||||
if len(subnm) == 1:
|
||||
|
@ -196,6 +216,26 @@ def listFiles(dir,watchcomic,Publisher,AlternateSearch=None,manual=None,sarc=Non
|
|||
subname = re.sub('[\.]', '', subname)
|
||||
|
||||
subnm = re.findall('[^()]+', subname)
|
||||
else:
|
||||
if numberinseries == 'True' or decimalinseries == 'True':
|
||||
#we need to remove the series from the subname and then search the remainder.
|
||||
watchname = re.sub('[\:\;\!\'\/\?\+\=\_\%\.]', '', watchcomic) #remove spec chars for watchcomic match.
|
||||
logger.fdebug('[FILECHECKER] watch-cleaned: ' + watchname)
|
||||
subthis = re.sub('.cbr', '', subname)
|
||||
subthis = re.sub('.cbz', '', subthis)
|
||||
subthis = re.sub('[\:\;\!\'\/\?\+\=\_\%\.]', '', subthis)
|
||||
logger.fdebug('[FILECHECKER] sub-cleaned: ' + subthis)
|
||||
#we need to make sure the file is part of the correct series or else will match falsely
|
||||
if watchname not in subthis:
|
||||
logger.fdebug('[FILECHECKER] this is a false match. Ignoring this result.')
|
||||
continue
|
||||
subthis = subthis[len(watchname):] #remove watchcomic
|
||||
#we need to now check the remainder of the string for digits assuming it's a possible year
|
||||
logger.fdebug('[FILECHECKER] new subname: ' + str(subthis))
|
||||
subname = re.sub('(.*)[\s+|_+](19\d{2}|20\d{2})(.*)', '\\1 (\\2) \\3', subthis)
|
||||
subname = watchname + subname
|
||||
subnm = re.findall('[^()]+', subname)
|
||||
|
||||
|
||||
subsplit = subname.replace('_', ' ').split()
|
||||
|
||||
|
@ -320,10 +360,12 @@ def listFiles(dir,watchcomic,Publisher,AlternateSearch=None,manual=None,sarc=Non
|
|||
nonocount = nonocount + subcnt + blspc
|
||||
#subname = re.sub('[\_\#\,\/\:\;\.\-\!\$\%\+\'\?\@]',' ', subname)
|
||||
if decimalinseries == 'True':
|
||||
modwatchcomic = re.sub('[\_\#\,\/\:\;\!\$\%\'\?\@]', ' ', u_watchcomic)
|
||||
modwatchcomic = re.sub('[\_\#\,\/\:\;\!\$\%\?\@]', ' ', u_watchcomic)
|
||||
else:
|
||||
modwatchcomic = re.sub('[\_\#\,\/\:\;\.\!\$\%\'\?\@]', ' ', u_watchcomic)
|
||||
modwatchcomic = re.sub('[\-]', '', modwatchcomic) #trying this too - 2014-03-01
|
||||
modwatchcomic = re.sub('[\_\#\,\/\:\;\.\!\$\%\?\@]', ' ', u_watchcomic)
|
||||
if bracketsinseries == 'True':
|
||||
modwatchcomic = re.sub('[\(\)]', ' ', modwatchcomic)
|
||||
modwatchcomic = re.sub('[\-\']', '', modwatchcomic) #trying this too - 2014-03-01
|
||||
#if leavehyphen == False:
|
||||
# logger.fdebug('[FILECHECKER] ('removing hyphen for comparisons')
|
||||
# modwatchcomic = re.sub('-', ' ', modwatchcomic)
|
||||
|
@ -346,18 +388,38 @@ def listFiles(dir,watchcomic,Publisher,AlternateSearch=None,manual=None,sarc=Non
|
|||
subname = re.sub('\s+', ' ', str(subname)).strip()
|
||||
|
||||
AS_Alt = []
|
||||
AS_Tuple = []
|
||||
if AlternateSearch is not None:
|
||||
chkthealt = AlternateSearch.split('##')
|
||||
if chkthealt == 0:
|
||||
AS_Alternate = AlternateSearch
|
||||
for calt in chkthealt:
|
||||
AS_tupled = False
|
||||
AS_Alternate = re.sub('##','',calt)
|
||||
if '!!' in AS_Alternate:
|
||||
# if it's !! present, it's the comicid associated with the series as an added annual.
|
||||
# extract the !!, store it and then remove it so things will continue.
|
||||
as_start = AS_Alternate.find('!!')
|
||||
logger.fdebug('as_start: ' + str(as_start) + ' --- ' + str(AS_Alternate[as_start:]))
|
||||
as_end = AS_Alternate.find('##', as_start)
|
||||
if as_end == -1: as_end = len(AS_Alternate)
|
||||
logger.fdebug('as_start: ' + str(as_end) + ' --- ' + str(AS_Alternate[as_start:as_end]))
|
||||
AS_ComicID = AS_Alternate[as_start+2:as_end]
|
||||
logger.fdebug('[FILECHECKER] Extracted comicid for given annual : ' + str(AS_ComicID))
|
||||
AS_Alternate = re.sub('!!' + str(AS_ComicID), '', AS_Alternate)
|
||||
AS_tupled = True
|
||||
#same = encode.
|
||||
u_altsearchcomic = AS_Alternate.encode('ascii', 'ignore').strip()
|
||||
altsearchcomic = re.sub('[\_\#\,\/\:\;\.\!\$\%\+\'\?\@]', ' ', u_altsearchcomic)
|
||||
altsearchcomic = re.sub('[\-]', ' ', altsearchcomic) #because this is a watchcomic registered, use same algorithim for watchcomic
|
||||
altsearchcomic = re.sub('[\_\#\,\/\:\;\.\!\$\%\+\?\@]', ' ', u_altsearchcomic)
|
||||
altsearchcomic = re.sub('[\-\']', '', altsearchcomic) #because this is a watchcomic registered, use same algorithim for watchcomic
|
||||
altsearchcomic = re.sub('\&', ' and ', altsearchcomic)
|
||||
altsearchcomic = re.sub('\s+', ' ', str(altsearchcomic)).strip()
|
||||
if detectthe_sub == True:
|
||||
altsearchcomic = re.sub("\\bthe\\b", "", altsearchcomic.lower())
|
||||
altsearchcomic = re.sub('\s+', ' ', str(altsearchcomic)).strip()
|
||||
|
||||
if AS_tupled:
|
||||
AS_Tuple.append({"ComicID": AS_ComicID,
|
||||
"AS_Alternate": altsearchcomic})
|
||||
AS_Alt.append(altsearchcomic)
|
||||
else:
|
||||
#create random characters so it will never match.
|
||||
|
@ -365,421 +427,428 @@ def listFiles(dir,watchcomic,Publisher,AlternateSearch=None,manual=None,sarc=Non
|
|||
AS_Alt.append(altsearchcomic)
|
||||
#if '_' in subname:
|
||||
# subname = subname.replace('_', ' ')
|
||||
logger.fdebug('[FILECHECKER] AS_Alt : ' + str(AS_Alt))
|
||||
logger.fdebug('[FILECHECKER] watchcomic:' + str(modwatchcomic) + ' ..comparing to found file: ' + str(subname))
|
||||
if modwatchcomic.lower() in subname.lower() or any(x.lower() in subname.lower() for x in AS_Alt):#altsearchcomic.lower() in subname.lower():
|
||||
comicpath = os.path.join(basedir, item)
|
||||
logger.fdebug('[FILECHECKER] ' + modwatchcomic + ' - watchlist match on : ' + comicpath)
|
||||
comicsize = os.path.getsize(comicpath)
|
||||
#print ("Comicsize:" + str(comicsize))
|
||||
comiccnt+=1
|
||||
if modwatchcomic.lower() in subname.lower() or any(x.lower() in subname.lower() for x in AS_Alt):
|
||||
#if the alternate search name is almost identical, it won't match up because it will hit the 'normal' first.
|
||||
#not important for series' matches, but for annuals, etc it is very important.
|
||||
#loop through the Alternates picking out the ones that match and then do an overall loop.
|
||||
enable_annual = False
|
||||
loopchk = [x for x in AS_Alt if x.lower() in subname.lower()]
|
||||
if len(loopchk) > 0 and loopchk[0] != '':
|
||||
logger.fdebug('[FILECHECKER] This should be an alternate: ' + str(loopchk))
|
||||
if 'annual' in subname.lower():
|
||||
logger.fdebug('[FILECHECKER] Annual detected - proceeding')
|
||||
enable_annual = True
|
||||
|
||||
stann = 0
|
||||
if 'annual' in subname.lower():
|
||||
logger.fdebug('[FILECHECKER] Annual detected - proceeding')
|
||||
jtd_len = subname.lower().find('annual')
|
||||
cchk = modwatchcomic
|
||||
else:
|
||||
if modwatchcomic.lower() in subname.lower():
|
||||
cchk = modwatchcomic
|
||||
else:
|
||||
cchk_ls = [x for x in AS_Alt if x.lower() in subname.lower()]
|
||||
cchk = cchk_ls[0]
|
||||
#print "something: " + str(cchk)
|
||||
loopchk = []
|
||||
|
||||
if modwatchcomic.lower() in subname.lower() and enable_annual == False:
|
||||
loopchk.append(modwatchcomic)
|
||||
if 'annual' in subname.lower():
|
||||
logger.fdebug('[FILECHECKER] Annual detected - proceeding cautiously.')
|
||||
enable_annual = False
|
||||
jtd_len = subname.lower().find('annual')
|
||||
|
||||
logger.fdebug('[FILECHECKER] Complete matching list of names to this file [' + str(len(loopchk)) + '] : ' + str(loopchk))
|
||||
|
||||
for loopit in loopchk:
|
||||
modwatchcomic = loopit
|
||||
logger.fdebug('[FILECHECKER] AS_Tuple : ' + str(AS_Tuple))
|
||||
annual_comicid = None
|
||||
for ATS in AS_Tuple:
|
||||
logger.fdebug('[FILECHECKER] ' + str(ATS['AS_Alternate']) + ' comparing to ' + str(modwatchcomic))
|
||||
if ATS['AS_Alternate'] == modwatchcomic:
|
||||
logger.fdebug('[FILECHECKER] Associating ComiciD : ' + str(ATS['ComicID']))
|
||||
annual_comicid = str(ATS['ComicID'])
|
||||
break
|
||||
comicpath = os.path.join(basedir, item)
|
||||
logger.fdebug('[FILECHECKER] ' + modwatchcomic + ' - watchlist match on : ' + comicpath)
|
||||
comicsize = os.path.getsize(comicpath)
|
||||
#print ("Comicsize:" + str(comicsize))
|
||||
comiccnt+=1
|
||||
|
||||
stann = 0
|
||||
|
||||
cchk = modwatchcomic
|
||||
#else:
|
||||
#if modwatchcomic.lower() in subname.lower():
|
||||
# cchk = modwatchcomic
|
||||
#else:
|
||||
# cchk_ls = [x for x in AS_Alt if x.lower() in subname.lower()]
|
||||
# cchk = cchk_ls[0]
|
||||
|
||||
logger.fdebug('[FILECHECKER] cchk is : ' + str(cchk))
|
||||
logger.fdebug('[FILECHECKER] we should remove ' + str(nonocount) + ' characters')
|
||||
|
||||
findtitlepos = subname.find('-')
|
||||
if charpos != 0:
|
||||
logger.fdebug('[FILECHECKER] detected ' + str(len(charpos)) + ' special characters')
|
||||
i=0
|
||||
while (i < len(charpos)):
|
||||
for i,j in enumerate(charpos):
|
||||
#logger.fdebug('i,j:' + str(i) + ',' + str(j))
|
||||
#logger.fdebug(str(len(subname)) + ' - subname: ' + subname)
|
||||
#logger.fdebug("digitchk: " + str(subname[j:]))
|
||||
if j >= len(subname):
|
||||
logger.fdebug('[FILECHECKER] end reached. ignoring remainder.')
|
||||
break
|
||||
elif subname[j:] == '-':
|
||||
if j <= len(subname) and subname[j+1].isdigit():
|
||||
logger.fdebug('[FILECHECKER] negative issue detected.')
|
||||
#detneg = "yes"
|
||||
elif j > findtitlepos:
|
||||
if subname[j:] == '#':
|
||||
if subname[j+1].isdigit():
|
||||
logger.fdebug('[FILECHECKER] # detected denoting issue#, ignoring.')
|
||||
else:
|
||||
nonocount-=1
|
||||
elif '-' in watchcomic and j < len(watchcomic):
|
||||
logger.fdebug('[FILECHECKER] - appears in series title, ignoring.')
|
||||
else:
|
||||
logger.fdebug('[FILECHECKER] special character appears outside of title - ignoring @ position: ' + str(charpos[i]))
|
||||
nonocount-=1
|
||||
i+=1
|
||||
for i,j in enumerate(charpos):
|
||||
logger.fdebug('i,j:' + str(i) + ',' + str(j))
|
||||
logger.fdebug(str(len(subname)) + ' - subname: ' + subname)
|
||||
logger.fdebug("digitchk: " + str(subname[j:]))
|
||||
if j >= len(subname):
|
||||
logger.fdebug('[FILECHECKER] ' + str(j) + ' is >= ' + str(len(subname)) + ' .End reached. ignoring remainder.')
|
||||
break
|
||||
elif subname[j:] == '-':
|
||||
if j <= len(subname) and subname[j+1].isdigit():
|
||||
logger.fdebug('[FILECHECKER] negative issue detected.')
|
||||
#detneg = "yes"
|
||||
elif j > findtitlepos:
|
||||
if subname[j:] == '#':
|
||||
if subname[j+1].isdigit():
|
||||
logger.fdebug('[FILECHECKER] # detected denoting issue#, ignoring.')
|
||||
else:
|
||||
nonocount-=1
|
||||
elif ('-' in watchcomic or '.' in watchcomic) and j < len(watchcomic):
|
||||
logger.fdebug('[FILECHECKER] - appears in series title, ignoring.')
|
||||
else:
|
||||
logger.fdebug('[FILECHECKER] special character appears outside of title - ignoring @ position: ' + str(charpos[i]))
|
||||
nonocount-=1
|
||||
|
||||
#remove versioning here
|
||||
if volrem != None:
|
||||
jtd_len = len(cchk)# + len(volrem)# + nonocount + 1 #1 is to account for space btwn comic and vol #
|
||||
else:
|
||||
jtd_len = len(cchk)# + nonocount
|
||||
#remove versioning here
|
||||
if volrem != None:
|
||||
jtd_len = len(cchk)# + len(volrem)# + nonocount + 1 #1 is to account for space btwn comic and vol #
|
||||
else:
|
||||
jtd_len = len(cchk)# + nonocount
|
||||
|
||||
if sarc and mylar.READ2FILENAME:
|
||||
removest = subname.find(' ') # the - gets removed above so we test for the first blank space...
|
||||
if subname[:removest].isdigit():
|
||||
jtd_len += removest + 1 # +1 to account for space in place of -
|
||||
logger.fdebug('[FILECHECKER] adjusted jtd_len to : ' + str(removest) + ' because of story-arc reading order tags')
|
||||
if sarc and mylar.READ2FILENAME:
|
||||
removest = subname.find(' ') # the - gets removed above so we test for the first blank space...
|
||||
if subname[:removest].isdigit():
|
||||
jtd_len += removest + 1 # +1 to account for space in place of -
|
||||
logger.fdebug('[FILECHECKER] adjusted jtd_len to : ' + str(removest) + ' because of story-arc reading order tags')
|
||||
|
||||
logger.fdebug('[FILECHECKER] nonocount [' + str(nonocount) + '] cchk [' + cchk + '] length [' + str(len(cchk)) + ']')
|
||||
logger.fdebug('[FILECHECKER] nonocount [' + str(nonocount) + '] cchk [' + cchk + '] length [' + str(len(cchk)) + ']')
|
||||
|
||||
#if detectand:
|
||||
# jtd_len = jtd_len - 2 # char substitution diff between & and 'and' = 2 chars
|
||||
#if detectthe_mod == True and detectthe_sub == False:
|
||||
#jtd_len = jtd_len - 3 # char subsitiution diff between 'the' and '' = 3 chars
|
||||
#if detectand:
|
||||
# jtd_len = jtd_len - 2 # char substitution diff between & and 'and' = 2 chars
|
||||
#if detectthe_mod == True and detectthe_sub == False:
|
||||
#jtd_len = jtd_len - 3 # char subsitiution diff between 'the' and '' = 3 chars
|
||||
|
||||
#justthedigits = item[jtd_len:]
|
||||
#justthedigits = item[jtd_len:]
|
||||
|
||||
logger.fdebug('[FILECHECKER] final jtd_len to prune [' + str(jtd_len) + ']')
|
||||
logger.fdebug('[FILECHECKER] before title removed from FILENAME [' + str(item) + ']')
|
||||
logger.fdebug('[FILECHECKER] after title removed from FILENAME [' + str(item[jtd_len:]) + ']')
|
||||
logger.fdebug('[FILECHECKER] creating just the digits using SUBNAME, pruning first [' + str(jtd_len) + '] chars from [' + subname + ']')
|
||||
logger.fdebug('[FILECHECKER] final jtd_len to prune [' + str(jtd_len) + ']')
|
||||
logger.fdebug('[FILECHECKER] before title removed from FILENAME [' + str(item) + ']')
|
||||
logger.fdebug('[FILECHECKER] after title removed from FILENAME [' + str(item[jtd_len:]) + ']')
|
||||
logger.fdebug('[FILECHECKER] creating just the digits using SUBNAME, pruning first [' + str(jtd_len) + '] chars from [' + subname + ']')
|
||||
|
||||
justthedigits_1 = subname[jtd_len:].strip()
|
||||
justthedigits_1 = subname[jtd_len:].strip()
|
||||
|
||||
logger.fdebug('[FILECHECKER] after title removed from SUBNAME [' + justthedigits_1 + ']')
|
||||
if enable_annual: justthedigits_1 = 'Annual ' + str(justthedigits_1)
|
||||
logger.fdebug('[FILECHECKER] after title removed from SUBNAME [' + justthedigits_1 + ']')
|
||||
|
||||
#remove the title if it appears
|
||||
#findtitle = justthedigits.find('-')
|
||||
#if findtitle > 0 and detneg == "no":
|
||||
# justthedigits = justthedigits[:findtitle]
|
||||
# logger.fdebug('[FILECHECKER] ("removed title from name - is now : " + str(justthedigits))
|
||||
#remove the title if it appears
|
||||
#findtitle = justthedigits.find('-')
|
||||
#if findtitle > 0 and detneg == "no":
|
||||
# justthedigits = justthedigits[:findtitle]
|
||||
# logger.fdebug('[FILECHECKER] ("removed title from name - is now : " + str(justthedigits))
|
||||
|
||||
justthedigits = justthedigits_1.split(' ', 1)[0]
|
||||
justthedigits = justthedigits_1.split(' ', 1)[0]
|
||||
|
||||
digitsvalid = "false"
|
||||
|
||||
for jdc in list(justthedigits):
|
||||
#logger.fdebug('[FILECHECKER] ('jdc:' + str(jdc))
|
||||
if not jdc.isdigit():
|
||||
#logger.fdebug('[FILECHECKER] ('alpha')
|
||||
jdc_start = justthedigits.find(jdc)
|
||||
alpha_isschk = justthedigits[jdc_start:]
|
||||
#logger.fdebug('[FILECHECKER] ('alpha_isschk:' + str(alpha_isschk))
|
||||
for issexcept in issue_exceptions:
|
||||
if issexcept.lower() in alpha_isschk.lower() and len(alpha_isschk) <= len(issexcept):
|
||||
logger.fdebug('[FILECHECKER] ALPHANUMERIC EXCEPTION : [' + justthedigits + ']')
|
||||
digitsvalid = "true"
|
||||
break
|
||||
if digitsvalid == "true": break
|
||||
|
||||
try:
|
||||
tmpthedigits = justthedigits_1.split(' ', 1)[1]
|
||||
logger.fdebug('[FILECHECKER] If the series has a decimal, this should be a number [' + tmpthedigits + ']')
|
||||
if 'cbr' in tmpthedigits.lower() or 'cbz' in tmpthedigits.lower():
|
||||
tmpthedigits = tmpthedigits[:-3].strip()
|
||||
logger.fdebug('[FILECHECKER] Removed extension - now we should just have a number [' + tmpthedigits + ']')
|
||||
poss_alpha = tmpthedigits
|
||||
if poss_alpha.isdigit():
|
||||
digitsvalid = "true"
|
||||
if justthedigits.lower() == 'annual':
|
||||
logger.fdebug('[FILECHECKER] ANNUAL DETECTED [' + poss_alpha + ']')
|
||||
justthedigits += ' ' + poss_alpha
|
||||
else:
|
||||
justthedigits += '.' + poss_alpha
|
||||
logger.fdebug('[FILECHECKER] DECIMAL ISSUE DETECTED [' + justthedigits + ']')
|
||||
else:
|
||||
for issexcept in issue_exceptions:
|
||||
decimalexcept = False
|
||||
if '.' in issexcept:
|
||||
decimalexcept = True
|
||||
issexcept = issexcept[1:] #remove the '.' from comparison...
|
||||
if issexcept.lower() in poss_alpha.lower() and len(poss_alpha) <= len(issexcept):
|
||||
if decimalexcept:
|
||||
issexcept = '.' + issexcept
|
||||
justthedigits += issexcept #poss_alpha
|
||||
logger.fdebug('[FILECHECKER] ALPHANUMERIC EXCEPTION. COMBINING : [' + justthedigits + ']')
|
||||
digitsvalid = "true"
|
||||
break
|
||||
except:
|
||||
tmpthedigits = None
|
||||
|
||||
# justthedigits = justthedigits.split(' ', 1)[0]
|
||||
|
||||
#if the issue has an alphanumeric (issue_exceptions, join it and push it through)
|
||||
logger.fdebug('[FILECHECKER] JUSTTHEDIGITS [' + justthedigits + ']' )
|
||||
if digitsvalid == "true":
|
||||
pass
|
||||
else:
|
||||
if justthedigits.isdigit():
|
||||
digitsvalid = "true"
|
||||
else:
|
||||
if '.' in justthedigits:
|
||||
tmpdec = justthedigits.find('.')
|
||||
b4dec = justthedigits[:tmpdec]
|
||||
a4dec = justthedigits[tmpdec+1:]
|
||||
if a4dec.isdigit() and b4dec.isdigit():
|
||||
logger.fdebug('[FILECHECKER] DECIMAL ISSUE DETECTED')
|
||||
digitsvalid = "true"
|
||||
else:
|
||||
try:
|
||||
x = float(justthedigits)
|
||||
#validity check
|
||||
if x < 0:
|
||||
logger.fdebug("I've encountered a negative issue #: " + str(justthedigits) + ". Trying to accomodate.")
|
||||
digitsvalid = "false"
|
||||
|
||||
for jdc in list(justthedigits):
|
||||
#logger.fdebug('[FILECHECKER] ('jdc:' + str(jdc))
|
||||
if not jdc.isdigit():
|
||||
#logger.fdebug('[FILECHECKER] ('alpha')
|
||||
jdc_start = justthedigits.find(jdc)
|
||||
alpha_isschk = justthedigits[jdc_start:]
|
||||
#logger.fdebug('[FILECHECKER] ('alpha_isschk:' + str(alpha_isschk))
|
||||
for issexcept in issue_exceptions:
|
||||
if issexcept.lower() in alpha_isschk.lower() and len(alpha_isschk) <= len(issexcept):
|
||||
logger.fdebug('[FILECHECKER] ALPHANUMERIC EXCEPTION : [' + justthedigits + ']')
|
||||
digitsvalid = "true"
|
||||
else: raise ValueError
|
||||
except ValueError, e:
|
||||
logger.fdebug('Probably due to an incorrect match - I cannot determine the issue number from given issue #: ' + str(justthedigits))
|
||||
break
|
||||
if digitsvalid == "true": break
|
||||
|
||||
try:
|
||||
tmpthedigits = justthedigits_1.split(' ', 1)[1]
|
||||
logger.fdebug('[FILECHECKER] If the series has a decimal, this should be a number [' + tmpthedigits + ']')
|
||||
if 'cbr' in tmpthedigits.lower() or 'cbz' in tmpthedigits.lower():
|
||||
tmpthedigits = tmpthedigits[:-3].strip()
|
||||
logger.fdebug('[FILECHECKER] Removed extension - now we should just have a number [' + tmpthedigits + ']')
|
||||
poss_alpha = tmpthedigits
|
||||
if poss_alpha.isdigit():
|
||||
digitsvalid = "true"
|
||||
if justthedigits.lower() == 'annual' and 'annual' not in watchcomic.lower():
|
||||
logger.fdebug('[FILECHECKER] ANNUAL DETECTED [' + poss_alpha + ']')
|
||||
justthedigits += ' ' + poss_alpha
|
||||
else:
|
||||
justthedigits += '.' + poss_alpha
|
||||
logger.fdebug('[FILECHECKER] DECIMAL ISSUE DETECTED [' + justthedigits + ']')
|
||||
else:
|
||||
for issexcept in issue_exceptions:
|
||||
decimalexcept = False
|
||||
if '.' in issexcept:
|
||||
decimalexcept = True
|
||||
issexcept = issexcept[1:] #remove the '.' from comparison...
|
||||
if issexcept.lower() in poss_alpha.lower() and len(poss_alpha) <= len(issexcept):
|
||||
if decimalexcept:
|
||||
issexcept = '.' + issexcept
|
||||
justthedigits += issexcept #poss_alpha
|
||||
logger.fdebug('[FILECHECKER] ALPHANUMERIC EXCEPTION. COMBINING : [' + justthedigits + ']')
|
||||
digitsvalid = "true"
|
||||
break
|
||||
except:
|
||||
tmpthedigits = None
|
||||
|
||||
# justthedigits = justthedigits.split(' ', 1)[0]
|
||||
|
||||
#if the issue has an alphanumeric (issue_exceptions, join it and push it through)
|
||||
logger.fdebug('[FILECHECKER] JUSTTHEDIGITS [' + justthedigits + ']' )
|
||||
if digitsvalid == "true":
|
||||
pass
|
||||
else:
|
||||
if justthedigits.isdigit():
|
||||
digitsvalid = "true"
|
||||
else:
|
||||
if '.' in justthedigits:
|
||||
tmpdec = justthedigits.find('.')
|
||||
b4dec = justthedigits[:tmpdec]
|
||||
a4dec = justthedigits[tmpdec+1:]
|
||||
if a4dec.isdigit() and b4dec.isdigit():
|
||||
logger.fdebug('[FILECHECKER] DECIMAL ISSUE DETECTED')
|
||||
digitsvalid = "true"
|
||||
else:
|
||||
try:
|
||||
x = float(justthedigits)
|
||||
#validity check
|
||||
if x < 0:
|
||||
logger.fdebug("I've encountered a negative issue #: " + str(justthedigits) + ". Trying to accomodate.")
|
||||
digitsvalid = "true"
|
||||
else: raise ValueError
|
||||
except ValueError, e:
|
||||
logger.fdebug('Probably due to an incorrect match - I cannot determine the issue number from given issue #: ' + str(justthedigits))
|
||||
|
||||
|
||||
# else:
|
||||
# logger.fdebug('[FILECHECKER] NO DECIMALS DETECTED')
|
||||
# digitsvalid = "false"
|
||||
|
||||
# if justthedigits.lower() == 'annual':
|
||||
# logger.fdebug('[FILECHECKER] ANNUAL [' + tmpthedigits.split(' ', 1)[1] + ']')
|
||||
# justthedigits += ' ' + tmpthedigits.split(' ', 1)[1]
|
||||
# digitsvalid = "true"
|
||||
# else:
|
||||
# try:
|
||||
# if tmpthedigits.isdigit(): #.split(' ', 1)[1] is not None:
|
||||
# poss_alpha = tmpthedigits#.split(' ', 1)[1]
|
||||
# if poss_alpha.isdigit():
|
||||
# digitsvalid = "true"
|
||||
# justthedigits += '.' + poss_alpha
|
||||
# logger.fdebug('[FILECHECKER] DECIMAL ISSUE DETECTED [' + justthedigits + ']')
|
||||
# for issexcept in issue_exceptions:
|
||||
# if issexcept.lower() in poss_alpha.lower() and len(poss_alpha) <= len(issexcept):
|
||||
# justthedigits += poss_alpha
|
||||
# logger.fdebug('[FILECHECKER] ALPHANUMERIC EXCEPTION. COMBINING : [' + justthedigits + ']')
|
||||
# digitsvalid = "true"
|
||||
# break
|
||||
# except:
|
||||
# pass
|
||||
|
||||
logger.fdebug('[FILECHECKER] final justthedigits [' + justthedigits + ']')
|
||||
if digitsvalid == "false":
|
||||
logger.fdebug('[FILECHECKER] Issue number not properly detected...ignoring.')
|
||||
comiccnt -=1 # remove the entry from the list count as it was incorrrectly tallied.
|
||||
continue
|
||||
logger.fdebug('[FILECHECKER] final justthedigits [' + justthedigits + ']')
|
||||
if digitsvalid == "false":
|
||||
logger.fdebug('[FILECHECKER] Issue number not properly detected...ignoring.')
|
||||
comiccnt -=1 # remove the entry from the list count as it was incorrrectly tallied.
|
||||
continue
|
||||
|
||||
|
||||
if manual is not None:
|
||||
#this is needed for Manual Run to determine matches
|
||||
#without this Batman will match on Batman Incorporated, and Batman and Robin, etc..
|
||||
if manual is not None:
|
||||
#this is needed for Manual Run to determine matches
|
||||
#without this Batman will match on Batman Incorporated, and Batman and Robin, etc..
|
||||
|
||||
# in case it matches on an Alternate Search pattern, set modwatchcomic to the cchk value
|
||||
modwatchcomic = cchk
|
||||
logger.fdebug('[FILECHECKER] cchk = ' + cchk.lower())
|
||||
logger.fdebug('[FILECHECKER] modwatchcomic = ' + modwatchcomic.lower())
|
||||
logger.fdebug('[FILECHECKER] subname = ' + subname.lower())
|
||||
comyear = manual['SeriesYear']
|
||||
issuetotal = manual['Total']
|
||||
comicvolume = manual['ComicVersion']
|
||||
logger.fdebug('[FILECHECKER] SeriesYear: ' + str(comyear))
|
||||
logger.fdebug('[FILECHECKER] IssueTotal: ' + str(issuetotal))
|
||||
logger.fdebug('[FILECHECKER] Comic Volume: ' + str(comicvolume))
|
||||
logger.fdebug('[FILECHECKER] volume detected: ' + str(volrem))
|
||||
# in case it matches on an Alternate Search pattern, set modwatchcomic to the cchk value
|
||||
modwatchcomic = cchk
|
||||
logger.fdebug('[FILECHECKER] cchk = ' + cchk.lower())
|
||||
logger.fdebug('[FILECHECKER] modwatchcomic = ' + modwatchcomic.lower())
|
||||
logger.fdebug('[FILECHECKER] subname = ' + subname.lower())
|
||||
comyear = manual['SeriesYear']
|
||||
issuetotal = manual['Total']
|
||||
comicvolume = manual['ComicVersion']
|
||||
logger.fdebug('[FILECHECKER] SeriesYear: ' + str(comyear))
|
||||
logger.fdebug('[FILECHECKER] IssueTotal: ' + str(issuetotal))
|
||||
logger.fdebug('[FILECHECKER] Comic Volume: ' + str(comicvolume))
|
||||
logger.fdebug('[FILECHECKER] volume detected: ' + str(volrem))
|
||||
|
||||
if comicvolume:
|
||||
ComVersChk = re.sub("[^0-9]", "", comicvolume)
|
||||
if ComVersChk == '' or ComVersChk == '1':
|
||||
ComVersChk = 0
|
||||
else:
|
||||
ComVersChk = 0
|
||||
if comicvolume:
|
||||
ComVersChk = re.sub("[^0-9]", "", comicvolume)
|
||||
if ComVersChk == '' or ComVersChk == '1':
|
||||
ComVersChk = 0
|
||||
else:
|
||||
ComVersChk = 0
|
||||
|
||||
# even if it's a V1, we need to pull the date for the given issue ID and get the publication year
|
||||
# for the issue. Because even if it's a V1, if there are additional Volumes then it's possible that
|
||||
# it will take the incorrect series. (ie. Detective Comics (1937) & Detective Comics (2011).
|
||||
# If issue #28 (2013) is found, it exists in both series, and because DC 1937 is a V1, it will bypass
|
||||
# the year check which will result in the incorrect series being picked (1937)
|
||||
# even if it's a V1, we need to pull the date for the given issue ID and get the publication year
|
||||
# for the issue. Because even if it's a V1, if there are additional Volumes then it's possible that
|
||||
# it will take the incorrect series. (ie. Detective Comics (1937) & Detective Comics (2011).
|
||||
# If issue #28 (2013) is found, it exists in both series, and because DC 1937 is a V1, it will bypass
|
||||
# the year check which will result in the incorrect series being picked (1937)
|
||||
|
||||
|
||||
#set the issue/year threshold here.
|
||||
# 2013 - (24issues/12) = 2011.
|
||||
#minyear = int(comyear) - (int(issuetotal) / 12)
|
||||
#set the issue/year threshold here.
|
||||
# 2013 - (24issues/12) = 2011.
|
||||
#minyear = int(comyear) - (int(issuetotal) / 12)
|
||||
|
||||
maxyear = manual['LatestDate'][:4] # yyyy-mm-dd
|
||||
maxyear = manual['LatestDate'][:4] # yyyy-mm-dd
|
||||
|
||||
#subnm defined at being of module.
|
||||
len_sm = len(subnm)
|
||||
#subnm defined at being of module.
|
||||
len_sm = len(subnm)
|
||||
|
||||
#print ("there are " + str(lenm) + " words.")
|
||||
cnt = 0
|
||||
yearmatch = "none"
|
||||
vers4year = "no"
|
||||
vers4vol = "no"
|
||||
#print ("there are " + str(lenm) + " words.")
|
||||
cnt = 0
|
||||
yearmatch = "none"
|
||||
vers4year = "no"
|
||||
vers4vol = "no"
|
||||
|
||||
for ct in subsplit:
|
||||
if ct.lower().startswith('v') and ct[1:].isdigit():
|
||||
logger.fdebug('[FILECHECKER] possible versioning..checking')
|
||||
#we hit a versioning # - account for it
|
||||
if ct[1:].isdigit():
|
||||
if len(ct[1:]) == 4: #v2013
|
||||
logger.fdebug('[FILECHECKER] Version detected as ' + str(ct))
|
||||
vers4year = "yes" #re.sub("[^0-9]", " ", str(ct)) #remove the v
|
||||
for ct in subsplit:
|
||||
if ct.lower().startswith('v') and ct[1:].isdigit():
|
||||
logger.fdebug('[FILECHECKER] possible versioning..checking')
|
||||
#we hit a versioning # - account for it
|
||||
if ct[1:].isdigit():
|
||||
if len(ct[1:]) == 4: #v2013
|
||||
logger.fdebug('[FILECHECKER] Version detected as ' + str(ct))
|
||||
vers4year = "yes" #re.sub("[^0-9]", " ", str(ct)) #remove the v
|
||||
break
|
||||
else:
|
||||
if len(ct) < 4:
|
||||
logger.fdebug('[FILECHECKER] Version detected as ' + str(ct))
|
||||
vers4vol = str(ct)
|
||||
break
|
||||
logger.fdebug('[FILECHECKER] false version detection..ignoring.')
|
||||
|
||||
versionmatch = "false"
|
||||
if vers4year is not "no" or vers4vol is not "no":
|
||||
|
||||
if comicvolume: #is not "None" and comicvolume is not None:
|
||||
D_ComicVersion = re.sub("[^0-9]", "", comicvolume)
|
||||
if D_ComicVersion == '':
|
||||
D_ComicVersion = 0
|
||||
else:
|
||||
D_ComicVersion = 0
|
||||
|
||||
F_ComicVersion = re.sub("[^0-9]", "", volrem)
|
||||
S_ComicVersion = str(comyear)
|
||||
logger.fdebug('[FILECHECKER] FCVersion: ' + str(F_ComicVersion))
|
||||
logger.fdebug('[FILECHECKER] DCVersion: ' + str(D_ComicVersion))
|
||||
logger.fdebug('[FILECHECKER] SCVersion: ' + str(S_ComicVersion))
|
||||
|
||||
#if annualize == "true" and int(ComicYear) == int(F_ComicVersion):
|
||||
# logger.fdebug('[FILECHECKER] ("We matched on versions for annuals " + str(volrem))
|
||||
|
||||
if int(F_ComicVersion) == int(D_ComicVersion) or int(F_ComicVersion) == int(S_ComicVersion):
|
||||
logger.fdebug('[FILECHECKER] We matched on versions...' + str(volrem))
|
||||
versionmatch = "true"
|
||||
else:
|
||||
logger.fdebug('[FILECHECKER] Versions wrong. Ignoring possible match.')
|
||||
|
||||
result_comyear = None
|
||||
while (cnt < len_sm):
|
||||
if subnm[cnt] is None: break
|
||||
if subnm[cnt] == ' ':
|
||||
pass
|
||||
else:
|
||||
logger.fdebug('[FILECHECKER] ' + str(cnt) + ' Bracket Word: ' + str(subnm[cnt]))
|
||||
|
||||
#if ComVersChk == 0:
|
||||
# logger.fdebug('[FILECHECKER] Series version detected as V1 (only series in existance with that title). Bypassing year check')
|
||||
# yearmatch = "true"
|
||||
# break
|
||||
if subnm[cnt][:-2] == '19' or subnm[cnt][:-2] == '20':
|
||||
logger.fdebug('[FILECHECKER] year detected: ' + str(subnm[cnt]))
|
||||
result_comyear = subnm[cnt]
|
||||
if int(result_comyear) <= int(maxyear) and int(result_comyear) >= int(comyear):
|
||||
logger.fdebug('[FILECHECKER] ' + str(result_comyear) + ' is within the series range of ' + str(comyear) + '-' + str(maxyear))
|
||||
#still possible for incorrect match if multiple reboots of series end/start in same year
|
||||
yearmatch = "true"
|
||||
break
|
||||
else:
|
||||
if len(ct) < 4:
|
||||
logger.fdebug('[FILECHECKER] Version detected as ' + str(ct))
|
||||
vers4vol = str(ct)
|
||||
break
|
||||
logger.fdebug('[FILECHECKER] false version detection..ignoring.')
|
||||
|
||||
versionmatch = "false"
|
||||
if vers4year is not "no" or vers4vol is not "no":
|
||||
|
||||
if comicvolume: #is not "None" and comicvolume is not None:
|
||||
D_ComicVersion = re.sub("[^0-9]", "", comicvolume)
|
||||
if D_ComicVersion == '':
|
||||
D_ComicVersion = 0
|
||||
else:
|
||||
D_ComicVersion = 0
|
||||
|
||||
F_ComicVersion = re.sub("[^0-9]", "", volrem)
|
||||
S_ComicVersion = str(comyear)
|
||||
logger.fdebug('[FILECHECKER] FCVersion: ' + str(F_ComicVersion))
|
||||
logger.fdebug('[FILECHECKER] DCVersion: ' + str(D_ComicVersion))
|
||||
logger.fdebug('[FILECHECKER] SCVersion: ' + str(S_ComicVersion))
|
||||
|
||||
#if annualize == "true" and int(ComicYear) == int(F_ComicVersion):
|
||||
# logger.fdebug('[FILECHECKER] ("We matched on versions for annuals " + str(volrem))
|
||||
|
||||
if int(F_ComicVersion) == int(D_ComicVersion) or int(F_ComicVersion) == int(S_ComicVersion):
|
||||
logger.fdebug('[FILECHECKER] We matched on versions...' + str(volrem))
|
||||
versionmatch = "true"
|
||||
else:
|
||||
logger.fdebug('[FILECHECKER] Versions wrong. Ignoring possible match.')
|
||||
|
||||
result_comyear = None
|
||||
while (cnt < len_sm):
|
||||
if subnm[cnt] is None: break
|
||||
if subnm[cnt] == ' ':
|
||||
pass
|
||||
else:
|
||||
logger.fdebug('[FILECHECKER] ' + str(cnt) + ' Bracket Word: ' + str(subnm[cnt]))
|
||||
|
||||
#if ComVersChk == 0:
|
||||
# logger.fdebug('[FILECHECKER] Series version detected as V1 (only series in existance with that title). Bypassing year check')
|
||||
# yearmatch = "true"
|
||||
# break
|
||||
if subnm[cnt][:-2] == '19' or subnm[cnt][:-2] == '20':
|
||||
logger.fdebug('[FILECHECKER] year detected: ' + str(subnm[cnt]))
|
||||
result_comyear = subnm[cnt]
|
||||
if int(result_comyear) <= int(maxyear):
|
||||
logger.fdebug('[FILECHECKER] ' + str(result_comyear) + ' is within the series range of ' + str(comyear) + '-' + str(maxyear))
|
||||
#still possible for incorrect match if multiple reboots of series end/start in same year
|
||||
yearmatch = "true"
|
||||
break
|
||||
logger.fdebug('[FILECHECKER] ' + str(result_comyear) + ' - not right - year not within series range of ' + str(comyear) + '-' + str(maxyear))
|
||||
yearmatch = "false"
|
||||
break
|
||||
cnt+=1
|
||||
if versionmatch == "false":
|
||||
if yearmatch == "false":
|
||||
logger.fdebug('[FILECHECKER] Failed to match on both version and issue year.')
|
||||
continue
|
||||
else:
|
||||
logger.fdebug('[FILECHECKER] ' + str(result_comyear) + ' - not right - year not within series range of ' + str(comyear) + '-' + str(maxyear))
|
||||
yearmatch = "false"
|
||||
logger.fdebug('[FILECHECKER] Matched on versions, not on year - continuing.')
|
||||
else:
|
||||
if yearmatch == "false":
|
||||
logger.fdebug('[FILECHECKER] Matched on version, but not on year - continuing.')
|
||||
else:
|
||||
logger.fdebug('[FILECHECKER] Matched on both version, and issue year - continuing.')
|
||||
|
||||
if yearmatch == "none":
|
||||
if ComVersChk == 0:
|
||||
logger.fdebug('[FILECHECKER] Series version detected as V1 (only series in existance with that title). Bypassing year check.')
|
||||
yearmatch = "true"
|
||||
else:
|
||||
continue
|
||||
|
||||
if 'annual' in subname.lower():
|
||||
subname = re.sub('annual', '', subname.lower())
|
||||
subname = re.sub('\s+', ' ', subname)
|
||||
#if the sub has an annual, let's remove it from the modwatch as well
|
||||
modwatchcomic = re.sub('annual', '', modwatchcomic.lower())
|
||||
|
||||
#tmpitem = item[:jtd_len]
|
||||
# if it's an alphanumeric with a space, rejoin, so we can remove it cleanly just below this.
|
||||
substring_removal = None
|
||||
poss_alpha = subname.split(' ')[-1:]
|
||||
logger.fdebug('[FILECHECKER] poss_alpha: ' + str(poss_alpha))
|
||||
logger.fdebug('[FILECHECKER] lenalpha: ' + str(len(''.join(poss_alpha))))
|
||||
for issexcept in issue_exceptions:
|
||||
if issexcept.lower()in str(poss_alpha).lower() and len(''.join(poss_alpha)) <= len(issexcept):
|
||||
#get the last 2 words so that we can remove them cleanly
|
||||
substring_removal = ' '.join(subname.split(' ')[-2:])
|
||||
substring_join = ''.join(subname.split(' ')[-2:])
|
||||
logger.fdebug('[FILECHECKER] substring_removal: ' + str(substring_removal))
|
||||
logger.fdebug('[FILECHECKER] substring_join: ' + str(substring_join))
|
||||
break
|
||||
cnt+=1
|
||||
if versionmatch == "false":
|
||||
if yearmatch == "false":
|
||||
logger.fdebug('[FILECHECKER] Failed to match on both version and issue year.')
|
||||
continue
|
||||
else:
|
||||
logger.fdebug('[FILECHECKER] Matched on versions, not on year - continuing.')
|
||||
else:
|
||||
if yearmatch == "false":
|
||||
logger.fdebug('[FILECHECKER] Matched on version, but not on year - continuing.')
|
||||
else:
|
||||
logger.fdebug('[FILECHECKER] Matched on both version, and issue year - continuing.')
|
||||
|
||||
if yearmatch == "none":
|
||||
if ComVersChk == 0:
|
||||
logger.fdebug('[FILECHECKER] Series version detected as V1 (only series in existance with that title). Bypassing year check.')
|
||||
yearmatch = "true"
|
||||
if substring_removal is not None:
|
||||
sub_removed = subname.replace('_', ' ').replace(substring_removal, substring_join)
|
||||
else:
|
||||
sub_removed = subname.replace('_', ' ')
|
||||
logger.fdebug('[FILECHECKER] sub_removed: ' + str(sub_removed))
|
||||
split_sub = sub_removed.rsplit(' ',1)[0].split(' ') #removes last word (assuming it's the issue#)
|
||||
split_mod = modwatchcomic.replace('_', ' ').split() #batman
|
||||
logger.fdebug('[FILECHECKER] split_sub: ' + str(split_sub))
|
||||
logger.fdebug('[FILECHECKER] split_mod: ' + str(split_mod))
|
||||
|
||||
x = len(split_sub)-1
|
||||
scnt = 0
|
||||
if x > len(split_mod)-1:
|
||||
logger.fdebug('[FILECHECKER] number of words do not match...aborting.')
|
||||
else:
|
||||
while ( x > -1 ):
|
||||
logger.fdebug(str(split_sub[x]) + ' comparing to ' + str(split_mod[x]))
|
||||
if str(split_sub[x]).lower() == str(split_mod[x]).lower():
|
||||
scnt+=1
|
||||
logger.fdebug('[FILECHECKER] word match exact. ' + str(scnt) + '/' + str(len(split_mod)))
|
||||
x-=1
|
||||
|
||||
wordcnt = int(scnt)
|
||||
logger.fdebug('[FILECHECKER] scnt:' + str(scnt))
|
||||
totalcnt = int(len(split_mod))
|
||||
logger.fdebug('[FILECHECKER] split_mod length:' + str(totalcnt))
|
||||
try:
|
||||
spercent = (wordcnt/totalcnt) * 100
|
||||
except ZeroDivisionError:
|
||||
spercent = 0
|
||||
logger.fdebug('[FILECHECKER] we got ' + str(spercent) + ' percent.')
|
||||
if int(spercent) >= 80:
|
||||
logger.fdebug('[FILECHECKER] this should be considered an exact match.Justthedigits:' + justthedigits)
|
||||
else:
|
||||
logger.fdebug('[FILECHECKER] failure - not an exact match.')
|
||||
continue
|
||||
|
||||
if 'annual' in subname.lower():
|
||||
subname = re.sub('annual', '', subname.lower())
|
||||
subname = re.sub('\s+', ' ', subname)
|
||||
#if the sub has an annual, let's remove it from the modwatch as well
|
||||
modwatchcomic = re.sub('annual', '', modwatchcomic.lower())
|
||||
|
||||
#tmpitem = item[:jtd_len]
|
||||
# if it's an alphanumeric with a space, rejoin, so we can remove it cleanly just below this.
|
||||
substring_removal = None
|
||||
poss_alpha = subname.split(' ')[-1:]
|
||||
logger.fdebug('[FILECHECKER] poss_alpha: ' + str(poss_alpha))
|
||||
logger.fdebug('[FILECHECKER] lenalpha: ' + str(len(''.join(poss_alpha))))
|
||||
for issexcept in issue_exceptions:
|
||||
if issexcept.lower()in str(poss_alpha).lower() and len(''.join(poss_alpha)) <= len(issexcept):
|
||||
#get the last 2 words so that we can remove them cleanly
|
||||
substring_removal = ' '.join(subname.split(' ')[-2:])
|
||||
substring_join = ''.join(subname.split(' ')[-2:])
|
||||
logger.fdebug('[FILECHECKER] substring_removal: ' + str(substring_removal))
|
||||
logger.fdebug('[FILECHECKER] substring_join: ' + str(substring_join))
|
||||
break
|
||||
|
||||
if substring_removal is not None:
|
||||
sub_removed = subname.replace('_', ' ').replace(substring_removal, substring_join)
|
||||
if manual:
|
||||
#print item
|
||||
#print comicpath
|
||||
#print comicsize
|
||||
#print result_comyear
|
||||
#print justthedigits
|
||||
comiclist.append({
|
||||
'ComicFilename': item,
|
||||
'ComicLocation': comicpath,
|
||||
'ComicSize': comicsize,
|
||||
'ComicYear': result_comyear,
|
||||
'JusttheDigits': justthedigits
|
||||
})
|
||||
#print('appended.')
|
||||
# watchmatch['comiclist'] = comiclist
|
||||
# break
|
||||
else:
|
||||
sub_removed = subname.replace('_', ' ')
|
||||
logger.fdebug('[FILECHECKER] sub_removed: ' + str(sub_removed))
|
||||
split_sub = sub_removed.rsplit(' ',1)[0].split(' ') #removes last word (assuming it's the issue#)
|
||||
split_mod = modwatchcomic.replace('_', ' ').split() #batman
|
||||
logger.fdebug('[FILECHECKER] split_sub: ' + str(split_sub))
|
||||
logger.fdebug('[FILECHECKER] split_mod: ' + str(split_mod))
|
||||
|
||||
x = len(split_sub)-1
|
||||
scnt = 0
|
||||
if x > len(split_mod)-1:
|
||||
logger.fdebug('[FILECHECKER] number of words do not match...aborting.')
|
||||
else:
|
||||
while ( x > -1 ):
|
||||
logger.fdebug(str(split_sub[x]) + ' comparing to ' + str(split_mod[x]))
|
||||
if str(split_sub[x]).lower() == str(split_mod[x]).lower():
|
||||
scnt+=1
|
||||
logger.fdebug('[FILECHECKER] word match exact. ' + str(scnt) + '/' + str(len(split_mod)))
|
||||
x-=1
|
||||
|
||||
wordcnt = int(scnt)
|
||||
logger.fdebug('[FILECHECKER] scnt:' + str(scnt))
|
||||
totalcnt = int(len(split_mod))
|
||||
logger.fdebug('[FILECHECKER] split_mod length:' + str(totalcnt))
|
||||
try:
|
||||
spercent = (wordcnt/totalcnt) * 100
|
||||
except ZeroDivisionError:
|
||||
spercent = 0
|
||||
logger.fdebug('[FILECHECKER] we got ' + str(spercent) + ' percent.')
|
||||
if int(spercent) >= 80:
|
||||
logger.fdebug('[FILECHECKER] this should be considered an exact match.Justthedigits:' + justthedigits)
|
||||
else:
|
||||
logger.fdebug('[FILECHECKER] failure - not an exact match.')
|
||||
continue
|
||||
|
||||
if manual:
|
||||
#print item
|
||||
#print comicpath
|
||||
#print comicsize
|
||||
#print result_comyear
|
||||
#print justthedigits
|
||||
comiclist.append({
|
||||
'ComicFilename': item,
|
||||
'ComicLocation': comicpath,
|
||||
'ComicSize': comicsize,
|
||||
'ComicYear': result_comyear,
|
||||
'JusttheDigits': justthedigits
|
||||
})
|
||||
#print('appended.')
|
||||
# watchmatch['comiclist'] = comiclist
|
||||
# break
|
||||
else:
|
||||
if moddir is not None:
|
||||
item = os.path.join(moddir, item)
|
||||
comiclist.append({
|
||||
'ComicFilename': item,
|
||||
'ComicLocation': comicpath,
|
||||
'ComicSize': comicsize,
|
||||
'JusttheDigits': justthedigits
|
||||
})
|
||||
#crcvalue = crc(comicpath)
|
||||
#logger.fdebug('[FILECHECKER] CRC is calculated as ' + str(crcvalue) + ' for : ' + item)
|
||||
watchmatch['comiclist'] = comiclist
|
||||
if moddir is not None:
|
||||
item = os.path.join(moddir, item)
|
||||
comiclist.append({
|
||||
'ComicFilename': item,
|
||||
'ComicLocation': comicpath,
|
||||
'ComicSize': comicsize,
|
||||
'JusttheDigits': justthedigits,
|
||||
'AnnualComicID': annual_comicid
|
||||
})
|
||||
#crcvalue = crc(comicpath)
|
||||
#logger.fdebug('[FILECHECKER] CRC is calculated as ' + str(crcvalue) + ' for : ' + item)
|
||||
watchmatch['comiclist'] = comiclist
|
||||
break
|
||||
else:
|
||||
#directory found - ignoring
|
||||
pass
|
||||
|
|
358
mylar/helpers.py
358
mylar/helpers.py
|
@ -616,6 +616,8 @@ def fullmonth(monthno):
|
|||
#simple numerical to worded month conversion....
|
||||
basmonths = {'1':'January','2':'February','3':'March','4':'April','5':'May','6':'June','7':'July','8':'August','9':'September','10':'October','11':'November','12':'December'}
|
||||
|
||||
monthconv = None
|
||||
|
||||
for numbs in basmonths:
|
||||
if numbs in str(int(monthno)):
|
||||
monthconv = basmonths[numbs]
|
||||
|
@ -628,23 +630,21 @@ def updateComicLocation():
|
|||
if mylar.NEWCOM_DIR is not None:
|
||||
logger.info('Performing a one-time mass update to Comic Location')
|
||||
#create the root dir if it doesn't exist
|
||||
if os.path.isdir(mylar.NEWCOM_DIR):
|
||||
logger.info('Directory (' + mylar.NEWCOM_DIR + ') already exists! Continuing...')
|
||||
else:
|
||||
logger.info('Directory does not exist!')
|
||||
try:
|
||||
os.makedirs(mylar.NEWCOM_DIR)
|
||||
logger.info('Directory successfully created at: ' + mylar.NEWCOM_DIR)
|
||||
except OSError:
|
||||
logger.error('Could not create comicdir : ' + mylar.NEWCOM_DIR)
|
||||
return
|
||||
mylar.filechecker.validateAndCreateDirectory(mylar.NEWCOM_DIR, create=True)
|
||||
|
||||
dirlist = myDB.select("SELECT * FROM comics")
|
||||
comloc = []
|
||||
|
||||
if dirlist is not None:
|
||||
for dl in dirlist:
|
||||
|
||||
comversion = dl['ComicVersion']
|
||||
u_comicnm = dl['ComicName']
|
||||
# let's remove the non-standard characters here that will break filenaming / searching.
|
||||
comicname_folder = filesafe(u_comicnm)
|
||||
|
||||
publisher = re.sub('!','',dl['ComicPublisher']) # thanks Boom!
|
||||
year = dl['ComicYear']
|
||||
comversion = dl['ComicVersion']
|
||||
if comversion is None:
|
||||
comversion = 'None'
|
||||
#if comversion is None, remove it so it doesn't populate with 'None'
|
||||
|
@ -655,54 +655,61 @@ def updateComicLocation():
|
|||
else:
|
||||
folderformat = mylar.FOLDER_FORMAT
|
||||
|
||||
#remove all 'bad' characters from the Series Name in order to create directories.
|
||||
u_comicnm = dl['ComicName']
|
||||
u_comicname = u_comicnm.encode('ascii', 'ignore').strip()
|
||||
if ':' in u_comicname or '/' in u_comicname or ',' in u_comicname or '?' in u_comicname:
|
||||
comicdir = u_comicname
|
||||
if ':' in comicdir:
|
||||
comicdir = comicdir.replace(':','')
|
||||
if '/' in comicdir:
|
||||
comicdir = comicdir.replace('/','-')
|
||||
if ',' in comicdir:
|
||||
comicdir = comicdir.replace(',','')
|
||||
if '?' in comicdir:
|
||||
comicdir = comicdir.replace('?','')
|
||||
else: comicdir = u_comicname
|
||||
#do work to generate folder path
|
||||
|
||||
|
||||
values = {'$Series': comicdir,
|
||||
'$Publisher': re.sub('!','',dl['ComicPublisher']),
|
||||
'$Year': dl['ComicYear'],
|
||||
'$series': dl['ComicName'].lower(),
|
||||
'$publisher': re.sub('!','',dl['ComicPublisher']).lower(),
|
||||
'$VolumeY': 'V' + str(dl['ComicYear']),
|
||||
'$VolumeN': comversion
|
||||
values = {'$Series': comicname_folder,
|
||||
'$Publisher': publisher,
|
||||
'$Year': year,
|
||||
'$series': comicname_folder.lower(),
|
||||
'$publisher': publisher.lower(),
|
||||
'$VolumeY': 'V' + str(year),
|
||||
'$VolumeN': comversion,
|
||||
'$Annual': 'Annual'
|
||||
}
|
||||
|
||||
|
||||
if mylar.FFTONEWCOM_DIR:
|
||||
#if this is enabled (1) it will apply the Folder_Format to all the new dirs
|
||||
if mylar.FOLDER_FORMAT == '':
|
||||
comlocation = re.sub(mylar.DESTINATION_DIR, mylar.NEWCOM_DIR, comicdir)
|
||||
comlocation = re.sub(mylar.DESTINATION_DIR, mylar.NEWCOM_DIR, dl['ComicLocation']).strip()
|
||||
else:
|
||||
first = replace_all(folderformat, values)
|
||||
if mylar.REPLACE_SPACES:
|
||||
#mylar.REPLACE_CHAR ...determines what to replace spaces with underscore or dot
|
||||
first = first.replace(' ', mylar.REPLACE_CHAR)
|
||||
comlocation = os.path.join(mylar.NEWCOM_DIR,first)
|
||||
comlocation = os.path.join(mylar.NEWCOM_DIR,first).strip()
|
||||
|
||||
else:
|
||||
comlocation = re.sub(mylar.DESTINATION_DIR, mylar.NEWCOM_DIR, comicdir)
|
||||
comlocation = re.sub(mylar.DESTINATION_DIR, mylar.NEWCOM_DIR, dl['ComicLocation']).strip()
|
||||
|
||||
ctrlVal = {"ComicID": dl['ComicID']}
|
||||
newVal = {"ComicLocation": comlocation}
|
||||
myDB.upsert("Comics", newVal, ctrlVal)
|
||||
logger.fdebug('updated ' + dl['ComicName'] + ' to : ' + comlocation)
|
||||
comloc.append({"comlocation": comlocation,
|
||||
"origlocation": dl['ComicLocation'],
|
||||
"comicid": dl['ComicID']})
|
||||
|
||||
if len(comloc) > 0:
|
||||
#give the information about what we're doing.
|
||||
if mylar.FFTONEWCOM_DIR:
|
||||
logger.info('FFTONEWCOM_DIR is enabled. Applying the existing folder format to ALL directories regardless of existing location paths')
|
||||
else:
|
||||
logger.info('FFTONEWCOM_DIR is not enabled. I will keep existing subdirectory paths, and will only change the actual Comic Location in the path.')
|
||||
logger.fdebug(' (ie. /mnt/Comics/Marvel/Hush-(2012) to /mnt/mynewLocation/Marvel/Hush-(2012) ')
|
||||
|
||||
#do the deed.
|
||||
for cl in comloc:
|
||||
ctrlVal = {"ComicID": cl['comicid']}
|
||||
newVal = {"ComicLocation": cl['comlocation']}
|
||||
# myDB.upsert("Comics", newVal, ctrlVal)
|
||||
logger.fdebug('Updated : ' + cl['origlocation'] + ' .: TO :. ' + cl['comlocation'])
|
||||
logger.info('Updated ' + str(len(comloc)) + ' series to a new Comic Location as specified in the config.ini')
|
||||
else:
|
||||
logger.fdebug('Failed in updating the Comic Locations. Check Folder Format string and/or log the issue.')
|
||||
else:
|
||||
logger.info('There are no series in your watchlist to Update the locations. Not updating anything at this time.')
|
||||
#set the value to 0 here so we don't keep on doing this...
|
||||
mylar.LOCMOVE = 0
|
||||
mylar.config_write()
|
||||
else:
|
||||
logger.info('No new ComicLocation path specified - not updating.')
|
||||
logger.info('No new ComicLocation path specified - not updating. Set NEWCOMD_DIR in config.ini')
|
||||
#raise cherrypy.HTTPRedirect("config")
|
||||
return
|
||||
|
||||
|
@ -918,12 +925,16 @@ def renamefile_readingorder(readorder):
|
|||
def latestdate_fix():
|
||||
import db, logger
|
||||
datefix = []
|
||||
cnupdate = []
|
||||
myDB = db.DBConnection()
|
||||
comiclist = myDB.select('SELECT * FROM comics')
|
||||
if comiclist is None:
|
||||
logger.fdebug('No Series in watchlist to correct latest date')
|
||||
return
|
||||
for cl in comiclist:
|
||||
if cl['ComicName_Filesafe'] is None:
|
||||
cnupdate.append({"comicid": cl['ComicID'],
|
||||
"comicname_filesafe": filesafe(cl['ComicName'])})
|
||||
latestdate = cl['LatestDate']
|
||||
#logger.fdebug("latestdate: " + str(latestdate))
|
||||
if latestdate[8:] == '':
|
||||
|
@ -945,10 +956,18 @@ def latestdate_fix():
|
|||
|
||||
#now we fix.
|
||||
if len(datefix) > 0:
|
||||
logger.info('Preparing to correct/fix ' + str(len(datefix)) + ' series that have incorrect values given for the Latest Date field.')
|
||||
for df in datefix:
|
||||
newCtrl = {"ComicID": df['comicid']}
|
||||
newVal = {"LatestDate": df['latestdate']}
|
||||
myDB.upsert("comics", newVal, newCtrl)
|
||||
if len(cnupdate) > 0:
|
||||
logger.info('Preparing to update ' + str(len(cnupdate)) + ' series on your watchlist for use with non-ascii characters')
|
||||
for cn in cnupdate:
|
||||
newCtrl = {"ComicID": cn['comicid']}
|
||||
newVal = {"ComicName_Filesafe": cn['comicname_filesafe']}
|
||||
myDB.upsert("comics", newVal, newCtrl)
|
||||
|
||||
return
|
||||
|
||||
def checkFolder():
|
||||
|
@ -1120,6 +1139,258 @@ def cvapi_check(web=None):
|
|||
line = str(mylar.CVAPI_COUNT) + ' hits / ' + str(mins) + ' minutes'
|
||||
return line
|
||||
|
||||
def filesafe(comic):
|
||||
import unicodedata
|
||||
u_comic = unicodedata.normalize('NFKD', comic).encode('ASCII', 'ignore').strip()
|
||||
|
||||
comicname_filesafe = re.sub('[\:\'\,\?\!\\\]', '', u_comic)
|
||||
comicname_filesafe = re.sub('[\/]','-', comicname_filesafe)
|
||||
|
||||
return comicname_filesafe
|
||||
|
||||
def IssueDetails(filelocation, IssueID=None):
|
||||
import zipfile, logger, shutil
|
||||
from xml.dom.minidom import parseString
|
||||
|
||||
dstlocation = os.path.join(mylar.CACHE_DIR, 'temp.zip')
|
||||
|
||||
issuedetails = []
|
||||
|
||||
if filelocation.endswith('.cbz'):
|
||||
logger.info('CBZ file detected. Checking for .xml within file')
|
||||
shutil.copy( filelocation, dstlocation )
|
||||
else:
|
||||
logger.info('filename is not a cbz : ' + filelocation)
|
||||
return
|
||||
|
||||
cover = "notfound"
|
||||
issuetag = None
|
||||
|
||||
modtime = os.path.getmtime(dstlocation)
|
||||
logger.info('file modtime set to : ' + str(modtime))
|
||||
|
||||
with zipfile.ZipFile(dstlocation, 'r') as inzipfile:
|
||||
for infile in inzipfile.namelist():
|
||||
if infile == 'ComicInfo.xml':
|
||||
logger.info('Extracting ComicInfo.xml to display.')
|
||||
dst = os.path.join(mylar.CACHE_DIR, 'ComicInfo.xml')
|
||||
data = inzipfile.read(infile)
|
||||
print str(data)
|
||||
issuetag = 'xml'
|
||||
elif '000.jpg' in infile or '000.png' in infile or '00.jpg' in infile:
|
||||
logger.info('Extracting primary image ' + infile + ' as coverfile for display.')
|
||||
local_file = open(os.path.join(mylar.CACHE_DIR,'temp.jpg'), "wb")
|
||||
local_file.write(inzipfile.read(infile))
|
||||
local_file.close
|
||||
cover = "found"
|
||||
elif ('001.jpg' in infile or '001.png' in infile) and cover == "notfound":
|
||||
logger.info('Extracting primary image ' + infile + ' as coverfile for display.')
|
||||
local_file = open(os.path.join(mylar.CACHE_DIR,'temp.jpg'), "wb")
|
||||
local_file.write(inzipfile.read(infile))
|
||||
local_file.close
|
||||
cover = "found"
|
||||
|
||||
ComicImage = os.path.join('cache', 'temp.jpg?'+str(modtime))
|
||||
IssueImage = replacetheslash(ComicImage)
|
||||
|
||||
if issuetag is None:
|
||||
import subprocess
|
||||
from subprocess import CalledProcessError, check_output
|
||||
unzip_cmd = "/usr/bin/unzip"
|
||||
try:
|
||||
#unzip -z will extract the zip comment field.
|
||||
data = subprocess.check_output( [ unzip_cmd, '-z', dstlocation ] )
|
||||
# return data is encoded in bytes, not unicode. Need to figure out how to run check_output returning utf-8
|
||||
issuetag = 'comment'
|
||||
except CalledProcessError as e:
|
||||
logger.warn('Unable to extract comment field from zipfile.')
|
||||
|
||||
print 'data:' + str(data)
|
||||
if issuetag == 'xml':
|
||||
#import easy to use xml parser called minidom:
|
||||
dom = parseString(data)
|
||||
|
||||
results = dom.getElementsByTagName('ComicInfo')
|
||||
for result in results:
|
||||
try:
|
||||
issue_title = result.getElementsByTagName('Title')[0].firstChild.wholeText
|
||||
except:
|
||||
issue_title = "None"
|
||||
try:
|
||||
series_title = result.getElementsByTagName('Series')[0].firstChild.wholeText
|
||||
except:
|
||||
series_title = "None"
|
||||
try:
|
||||
issue_number = result.getElementsByTagName('Number')[0].firstChild.wholeText
|
||||
except:
|
||||
issue_number = "None"
|
||||
try:
|
||||
summary = result.getElementsByTagName('Summary')[0].firstChild.wholeText
|
||||
except:
|
||||
summary = "None"
|
||||
|
||||
if '*List' in summary:
|
||||
summary_cut = summary.find('*List')
|
||||
summary = summary[:summary_cut]
|
||||
|
||||
try:
|
||||
notes = result.getElementsByTagName('Notes')[0].firstChild.wholeText #IssueID is in here
|
||||
except:
|
||||
notes = "None"
|
||||
try:
|
||||
year = result.getElementsByTagName('Year')[0].firstChild.wholeText
|
||||
except:
|
||||
year = "None"
|
||||
try:
|
||||
month = result.getElementsByTagName('Month')[0].firstChild.wholeText
|
||||
except:
|
||||
month = "None"
|
||||
try:
|
||||
day = result.getElementsByTagName('Day')[0].firstChild.wholeText
|
||||
except:
|
||||
day = "None"
|
||||
try:
|
||||
writer = result.getElementsByTagName('Writer')[0].firstChild.wholeText
|
||||
except:
|
||||
writer = "None"
|
||||
try:
|
||||
penciller = result.getElementsByTagName('Penciller')[0].firstChild.wholeText
|
||||
except:
|
||||
penciller = "None"
|
||||
try:
|
||||
inker = result.getElementsByTagName('Inker')[0].firstChild.wholeText
|
||||
except:
|
||||
inker = "None"
|
||||
try:
|
||||
colorist = result.getElementsByTagName('Colorist')[0].firstChild.wholeText
|
||||
except:
|
||||
colorist = "None"
|
||||
try:
|
||||
letterer = result.getElementsByTagName('Letterer')[0].firstChild.wholeText
|
||||
except:
|
||||
letterer = "None"
|
||||
try:
|
||||
cover_artist = result.getElementsByTagName('CoverArtist')[0].firstChild.wholeText
|
||||
except:
|
||||
cover_artist = "None"
|
||||
try:
|
||||
editor = result.getElementsByTagName('Editor')[0].firstChild.wholeText
|
||||
except:
|
||||
editor = "None"
|
||||
try:
|
||||
publisher = result.getElementsByTagName('Publisher')[0].firstChild.wholeText
|
||||
except:
|
||||
publisher = "None"
|
||||
try:
|
||||
webpage = result.getElementsByTagName('Web')[0].firstChild.wholeText
|
||||
except:
|
||||
webpage = "None"
|
||||
try:
|
||||
pagecount = result.getElementsByTagName('PageCount')[0].firstChild.wholeText
|
||||
except:
|
||||
pagecount = 0
|
||||
logger.info("number of pages I counted: " + str(pagecount))
|
||||
i = 0
|
||||
while (i < int(pagecount)):
|
||||
pageinfo = result.getElementsByTagName('Page')[i].attributes
|
||||
attrib = pageinfo.getNamedItem('Image')
|
||||
logger.info('Frontcover validated as being image #: ' + str(attrib.value))
|
||||
att = pageinfo.getNamedItem('Type')
|
||||
logger.info('pageinfo: ' + str(pageinfo))
|
||||
if att.value == 'FrontCover':
|
||||
logger.info('FrontCover detected. Extracting.')
|
||||
break
|
||||
i+=1
|
||||
else:
|
||||
stripline = 'Archive: ' + dstlocation
|
||||
data = re.sub(stripline, '', data.encode("utf-8"))
|
||||
import ast
|
||||
ast_data = ast.literal_eval(str(data))
|
||||
lastmodified = ast_data['lastModified']
|
||||
print lastmodified
|
||||
dt = ast_data['ComicBookInfo/1.0']
|
||||
publisher = dt['publisher']
|
||||
year = dt['publicationYear']
|
||||
month = dt['publicationMonth']
|
||||
try:
|
||||
day = dt['publicationDay']
|
||||
except:
|
||||
day = None
|
||||
issue_title = dt['title']
|
||||
series_title = dt['series']
|
||||
issue_number = dt['issue']
|
||||
summary = dt['comments']
|
||||
editor = "None"
|
||||
colorist = "None"
|
||||
artist = "None"
|
||||
writer = "None"
|
||||
letterer = "None"
|
||||
cover_artist = "None"
|
||||
penciller = "None"
|
||||
inker = "None"
|
||||
for cl in dt['credits']:
|
||||
if cl['role'] == 'Editor':
|
||||
if editor == "None": editor = cl['person']
|
||||
else: editor += ', ' + cl['person']
|
||||
elif cl['role'] == 'Colorist':
|
||||
if colorist == "None": colorist = cl['person']
|
||||
else: colorist += ', ' + cl['person']
|
||||
elif cl['role'] == 'Artist':
|
||||
if artist == "None": artist = cl['person']
|
||||
else: artist += ', ' + cl['person']
|
||||
elif cl['role'] == 'Writer':
|
||||
if writer == "None": writer = cl['person']
|
||||
else: writer += ', ' + cl['person']
|
||||
elif cl['role'] == 'Letterer':
|
||||
if letterer == "None": letterer = cl['person']
|
||||
else: letterer += ', ' + cl['person']
|
||||
elif cl['role'] == 'Cover':
|
||||
if cover_artist == "None": cover_artist = cl['person']
|
||||
else: cover_artist += ', ' + cl['person']
|
||||
elif cl['role'] == 'Penciller':
|
||||
if penciller == "None": penciller = cl['person']
|
||||
else: penciller += ', ' + cl['person']
|
||||
elif cl['role'] == 'Inker':
|
||||
if inker == "None": inker = cl['person']
|
||||
else: inker += ', ' + cl['person']
|
||||
|
||||
try:
|
||||
notes = dt['notes']
|
||||
except:
|
||||
notes = "None"
|
||||
try:
|
||||
webpage = dt['web']
|
||||
except:
|
||||
webpage = "None"
|
||||
try:
|
||||
pagecount = dt['pagecount']
|
||||
except:
|
||||
pagecount = "None"
|
||||
|
||||
issuedetails.append({"title": issue_title,
|
||||
"series": series_title,
|
||||
"issue_number": issue_number,
|
||||
"summary": summary,
|
||||
"notes": notes,
|
||||
"year": year,
|
||||
"month": month,
|
||||
"day": day,
|
||||
"writer": writer,
|
||||
"penciller": penciller,
|
||||
"inker": inker,
|
||||
"colorist": colorist,
|
||||
"letterer": letterer,
|
||||
"cover_artist": cover_artist,
|
||||
"editor": editor,
|
||||
"publisher": publisher,
|
||||
"webpage": webpage,
|
||||
"pagecount": pagecount,
|
||||
"IssueImage": IssueImage})
|
||||
|
||||
return issuedetails
|
||||
|
||||
|
||||
|
||||
from threading import Thread
|
||||
|
||||
class ThreadWithReturnValue(Thread):
|
||||
|
@ -1129,10 +1400,9 @@ class ThreadWithReturnValue(Thread):
|
|||
self._return = None
|
||||
def run(self):
|
||||
if self._Thread__target is not None:
|
||||
self._return = self._Thread__target(*self._Thread__args,
|
||||
**self._Thread__kwargs)
|
||||
self._return = self._Thread__target(*self._Thread__args, **self._Thread__kwargs)
|
||||
|
||||
def join(self):
|
||||
Thread.join(self)
|
||||
return self._return
|
||||
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ import re
|
|||
import urllib
|
||||
import urllib2
|
||||
import shutil
|
||||
import imghdr
|
||||
import sqlite3
|
||||
import cherrypy
|
||||
|
||||
|
@ -43,7 +44,7 @@ def is_exists(comicid):
|
|||
return False
|
||||
|
||||
|
||||
def addComictoDB(comicid,mismatch=None,pullupd=None,imported=None,ogcname=None,calledfrom=None,annload=None,chkwant=None,issuechk=None,issuetype=None):
|
||||
def addComictoDB(comicid,mismatch=None,pullupd=None,imported=None,ogcname=None,calledfrom=None,annload=None,chkwant=None,issuechk=None,issuetype=None,latestissueinfo=None):
|
||||
# Putting this here to get around the circular import. Will try to use this to update images at later date.
|
||||
# from mylar import cache
|
||||
|
||||
|
@ -66,6 +67,11 @@ def addComictoDB(comicid,mismatch=None,pullupd=None,imported=None,ogcname=None,c
|
|||
return 'Exists'
|
||||
newValueDict = {"Status": "Loading"}
|
||||
comlocation = dbcomic['ComicLocation']
|
||||
if not latestissueinfo:
|
||||
latestissueinfo = []
|
||||
latestissueinfo.append({"latestiss": dbcomic['LatestIssue'],
|
||||
"latestdate": dbcomic['LatestDate']})
|
||||
|
||||
filechecker.validateAndCreateDirectory(comlocation, True)
|
||||
oldcomversion = dbcomic['ComicVersion'] #store the comicversion and chk if it exists before hammering.
|
||||
myDB.upsert("comics", newValueDict, controlValueDict)
|
||||
|
@ -195,7 +201,7 @@ def addComictoDB(comicid,mismatch=None,pullupd=None,imported=None,ogcname=None,c
|
|||
#sresults = mb.findComic(annComicName, mode, issue=annissues, limityear=annualval['AnnualYear'])
|
||||
#print "annualyear: " + str(annualval['AnnualYear'])
|
||||
logger.fdebug('[IMPORTER-ANNUAL] - Annual Year:' + str(annualyear))
|
||||
sresults, explicit = mb.findComic(annComicName, mode, issue=None)#,explicit=True)
|
||||
sresults, explicit = mb.findComic(annComicName, mode, issue=None, explicit='all')#,explicit=True)
|
||||
|
||||
type='comic'
|
||||
|
||||
|
@ -290,28 +296,12 @@ def addComictoDB(comicid,mismatch=None,pullupd=None,imported=None,ogcname=None,c
|
|||
#comic book location on machine
|
||||
# setup default location here
|
||||
|
||||
if comlocation is None:
|
||||
# let's remove the non-standard characters here.
|
||||
u_comicnm = comic['ComicName']
|
||||
u_comicname = u_comicnm.encode('ascii', 'ignore').strip()
|
||||
dirbad = [':',',','/','?','!','\''] #in u_comicname or '/' in u_comicname or ',' in u_comicname or '?' in u_comicname:
|
||||
comicdir = u_comicname
|
||||
for dbd in dirbad:
|
||||
if dbd in u_comicname:
|
||||
if dbd == '/': repthechar = '-'
|
||||
else: repthechar = ''
|
||||
comicdir = comicdir.replace(dbd,repthechar)
|
||||
# if ':' in comicdir:
|
||||
# comicdir = comicdir.replace(dbd,'')
|
||||
# if '/' in comicdir:
|
||||
# comicdir = comicdir.replace('/','-')
|
||||
# if ',' in comicdir:
|
||||
# comicdir = comicdir.replace(',','')
|
||||
# if '?' in comicdir:
|
||||
# comicdir = comicdir.replace('?','')
|
||||
# if '!' in comicdir:
|
||||
# comicdir = comicdir.replace('!','')
|
||||
u_comicnm = comic['ComicName']
|
||||
# let's remove the non-standard characters here that will break filenaming / searching.
|
||||
comicname_filesafe = helpers.filesafe(u_comicnm)
|
||||
|
||||
if comlocation is None:
|
||||
comicdir = comicname_filesafe
|
||||
series = comicdir
|
||||
publisher = re.sub('!','',comic['ComicPublisher']) # thanks Boom!
|
||||
year = SeriesYear
|
||||
|
@ -408,6 +398,11 @@ def addComictoDB(comicid,mismatch=None,pullupd=None,imported=None,ogcname=None,c
|
|||
with open(coverfile, 'wb') as the_file:
|
||||
the_file.write(com_image)
|
||||
|
||||
try:
|
||||
logger.info('Image header check: ' + imghdr.what(coverfile))
|
||||
except:
|
||||
logger.info('image is corrupted.')
|
||||
raise Exception
|
||||
logger.info('Successfully retrieved cover for ' + comic['ComicName'])
|
||||
|
||||
except Exception, e:
|
||||
|
@ -459,6 +454,7 @@ def addComictoDB(comicid,mismatch=None,pullupd=None,imported=None,ogcname=None,c
|
|||
controlValueDict = {"ComicID": comicid}
|
||||
newValueDict = {"ComicName": comic['ComicName'],
|
||||
"ComicSortName": sortname,
|
||||
"ComicName_Filesafe": comicname_filesafe,
|
||||
"ComicYear": SeriesYear,
|
||||
"ComicImage": ComicImage,
|
||||
"Total": comicIssues,
|
||||
|
@ -489,7 +485,7 @@ def addComictoDB(comicid,mismatch=None,pullupd=None,imported=None,ogcname=None,c
|
|||
|
||||
#move to own function so can call independently to only refresh issue data
|
||||
#issued is from cv.getComic, comic['ComicName'] & comicid would both be already known to do independent call.
|
||||
issuedata = updateissuedata(comicid, comic['ComicName'], issued, comicIssues, calledfrom, SeriesYear=SeriesYear)
|
||||
issuedata = updateissuedata(comicid, comic['ComicName'], issued, comicIssues, calledfrom, SeriesYear=SeriesYear, latestissueinfo=latestissueinfo)
|
||||
if issuedata is None:
|
||||
logger.warn('Unable to complete Refreshing / Adding issue data - this WILL create future problems if not addressed.')
|
||||
return
|
||||
|
@ -520,8 +516,8 @@ def addComictoDB(comicid,mismatch=None,pullupd=None,imported=None,ogcname=None,c
|
|||
latestdate = issuedata['LatestDate']
|
||||
lastpubdate = issuedata['LastPubDate']
|
||||
|
||||
#move the files...if imported is not empty (meaning it's not from the mass importer.)
|
||||
if imported is None or imported == 'None':
|
||||
#move the files...if imported is not empty & not futurecheck (meaning it's not from the mass importer.)
|
||||
if imported is None or imported == 'None' or imported == 'futurecheck':
|
||||
pass
|
||||
else:
|
||||
if mylar.IMP_MOVE:
|
||||
|
@ -547,7 +543,11 @@ def addComictoDB(comicid,mismatch=None,pullupd=None,imported=None,ogcname=None,c
|
|||
logger.fdebug('latestissue status: ' + chkstats['Status'])
|
||||
if chkstats['Status'] == 'Skipped' or chkstats['Status'] == 'Wanted' or chkstats['Status'] == 'Snatched':
|
||||
logger.info('Checking this week pullist for new issues of ' + comic['ComicName'])
|
||||
updater.newpullcheck(comic['ComicName'], comicid, issue=latestiss)
|
||||
if comic['ComicName'] != comicname_filesafe:
|
||||
cn_pull = comicname_filesafe
|
||||
else:
|
||||
cn_pull = comic['ComicName']
|
||||
updater.newpullcheck(cn_pull, comicid, issue=latestiss)
|
||||
|
||||
#here we grab issues that have been marked as wanted above...
|
||||
|
||||
|
@ -583,7 +583,9 @@ def addComictoDB(comicid,mismatch=None,pullupd=None,imported=None,ogcname=None,c
|
|||
|
||||
logger.info('Finished grabbing what I could.')
|
||||
|
||||
|
||||
if imported == 'futurecheck':
|
||||
logger.info('Returning to Future-Check module to complete the add & remove entry.')
|
||||
return
|
||||
|
||||
if calledfrom == 'addbyid':
|
||||
logger.info('Sucessfully added ' + comic['ComicName'] + ' (' + str(SeriesYear) + ') by directly using the ComicVine ID')
|
||||
|
@ -994,7 +996,7 @@ def manualAnnual(manual_comicid, comicname, comicyear, comicid):
|
|||
logger.info('Attempting to integrate ' + sr['ComicName'] + ' (' + str(issueid) + ') to the existing series of ' + comicname + '(' + str(comicyear) + ')')
|
||||
if len(sr) is None or len(sr) == 0:
|
||||
logger.fdebug('Could not find any information on the series indicated : ' + str(manual_comicid))
|
||||
pass
|
||||
return
|
||||
else:
|
||||
n = 0
|
||||
noissues = sr['ComicIssues']
|
||||
|
@ -1034,10 +1036,11 @@ def manualAnnual(manual_comicid, comicname, comicyear, comicid):
|
|||
#"M_ComicID": manual_comicid}
|
||||
myDB.upsert("annuals", newVals, newCtrl)
|
||||
n+=1
|
||||
logger.info('Successfully integrated ' + str(n) + ' issues of ' + sr['ComicName'] + ' to the series: ' + comicname)
|
||||
return
|
||||
|
||||
|
||||
def updateissuedata(comicid, comicname=None, issued=None, comicIssues=None, calledfrom=None, issuechk=None, issuetype=None, SeriesYear=None):
|
||||
def updateissuedata(comicid, comicname=None, issued=None, comicIssues=None, calledfrom=None, issuechk=None, issuetype=None, SeriesYear=None, latestissueinfo=None):
|
||||
weeklyissue_check = []
|
||||
logger.fdebug('issuedata call references...')
|
||||
logger.fdebug('comicid:' + str(comicid))
|
||||
|
@ -1045,6 +1048,7 @@ def updateissuedata(comicid, comicname=None, issued=None, comicIssues=None, call
|
|||
logger.fdebug('comicissues:' + str(comicIssues))
|
||||
logger.fdebug('calledfrom: ' + str(calledfrom))
|
||||
logger.fdebug('issuechk: ' + str(issuechk))
|
||||
logger.fdebug('latestissueinfo: ' + str(latestissueinfo))
|
||||
logger.fdebug('issuetype: ' + str(issuetype))
|
||||
#to facilitate independent calls to updateissuedata ONLY, account for data not available and get it.
|
||||
#chkType comes from the weeklypulllist - either 'annual' or not to distinguish annuals vs. issues
|
||||
|
@ -1222,38 +1226,60 @@ def updateissuedata(comicid, comicname=None, issued=None, comicIssues=None, call
|
|||
|
||||
n+=1
|
||||
|
||||
if len(issuedata) > 1 and not calledfrom == 'dbupdate':
|
||||
logger.fdebug('initiating issue updating - info & status')
|
||||
issue_collection(issuedata,nostatus='False')
|
||||
else:
|
||||
logger.fdebug('initiating issue updating - just the info')
|
||||
issue_collection(issuedata,nostatus='True')
|
||||
|
||||
styear = str(SeriesYear)
|
||||
|
||||
if firstdate[5:7] == '00':
|
||||
stmonth = "?"
|
||||
else:
|
||||
stmonth = helpers.fullmonth(firstdate[5:7])
|
||||
|
||||
ltyear = re.sub('/s','', latestdate[:4])
|
||||
if latestdate[5:7] == '00':
|
||||
ltmonth = "?"
|
||||
else:
|
||||
ltmonth = helpers.fullmonth(latestdate[5:7])
|
||||
|
||||
#try to determine if it's an 'actively' published comic from above dates
|
||||
#threshold is if it's within a month (<55 days) let's assume it's recent.
|
||||
c_date = datetime.date(int(latestdate[:4]),int(latestdate[5:7]),1)
|
||||
n_date = datetime.date.today()
|
||||
recentchk = (n_date - c_date).days
|
||||
#print ("recentchk: " + str(recentchk))
|
||||
if recentchk <= 55:
|
||||
if calledfrom == 'futurecheck' and len(issuedata) == 0:
|
||||
logger.fdebug('This is a NEW series with no issue data - skipping issue updating for now, and assigning generic information so things don\'t break')
|
||||
latestdate = latestissueinfo[0]['latestdate'] # if it's from futurecheck, issuechk holds the latestdate for the given issue
|
||||
latestiss = latestissueinfo[0]['latestiss']
|
||||
lastpubdate = 'Present'
|
||||
publishfigure = str(SeriesYear) + ' - ' + str(lastpubdate)
|
||||
else:
|
||||
lastpubdate = str(ltmonth) + ' ' + str(ltyear)
|
||||
if len(issuedata) > 1 and not calledfrom == 'dbupdate':
|
||||
logger.fdebug('initiating issue updating - info & status')
|
||||
issue_collection(issuedata,nostatus='False')
|
||||
else:
|
||||
logger.fdebug('initiating issue updating - just the info')
|
||||
issue_collection(issuedata,nostatus='True')
|
||||
|
||||
styear = str(SeriesYear)
|
||||
|
||||
if firstdate[5:7] == '00':
|
||||
stmonth = "?"
|
||||
else:
|
||||
stmonth = helpers.fullmonth(firstdate[5:7])
|
||||
|
||||
ltyear = re.sub('/s','', latestdate[:4])
|
||||
if latestdate[5:7] == '00':
|
||||
ltmonth = "?"
|
||||
else:
|
||||
ltmonth = helpers.fullmonth(latestdate[5:7])
|
||||
|
||||
#try to determine if it's an 'actively' published comic from above dates
|
||||
#threshold is if it's within a month (<55 days) let's assume it's recent.
|
||||
try:
|
||||
c_date = datetime.date(int(latestdate[:4]),int(latestdate[5:7]),1)
|
||||
except:
|
||||
logger.error('Cannot determine Latest Date for given series. This is most likely due to an issue having a date of : 0000-00-00')
|
||||
latestdate = str(SeriesYear) + '-01-01'
|
||||
logger.error('Setting Latest Date to be ' + str(latestdate) + '. You should inform CV that the issue data is stale.')
|
||||
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:
|
||||
lastpubdate = 'Present'
|
||||
else:
|
||||
lastpubdate = str(ltmonth) + ' ' + str(ltyear)
|
||||
|
||||
publishfigure = str(stmonth) + ' ' + str(styear) + ' - ' + str(lastpubdate)
|
||||
if stmonth == '?' and styear == '?' and lastpubdate =='0000' and comicIssues == '0':
|
||||
logger.info('No available issue data - I believe this is a NEW series.')
|
||||
latestdate = latestissueinfo[0]['latestdate']
|
||||
latestiss = latestissueinfo[0]['latestiss']
|
||||
lastpubdate = 'Present'
|
||||
publishfigure = str(SeriesYear) + ' - ' + str(lastpubdate)
|
||||
|
||||
|
||||
publishfigure = str(stmonth) + ' ' + str(styear) + ' - ' + str(lastpubdate)
|
||||
|
||||
controlValueStat = {"ComicID": comicid}
|
||||
|
||||
|
|
|
@ -96,9 +96,10 @@ def libraryScan(dir=None, append=False, ComicID=None, ComicName=None, cron=None)
|
|||
import_comicids = {}
|
||||
|
||||
for watch in watchlist:
|
||||
#use the comicname_filesafe to start
|
||||
watchdisplaycomic = re.sub('[\_\#\,\/\:\;\!\$\%\&\+\'\?\@]', ' ', watch['ComicName']).encode('utf-8').strip()
|
||||
# let's clean up the name, just in case for comparison purposes...
|
||||
watchcomic = re.sub('[\_\#\,\/\:\;\.\-\!\$\%\&\+\'\?\@]', ' ', watch['ComicName']).encode('utf-8').strip()
|
||||
watchcomic = re.sub('[\_\#\,\/\:\;\.\-\!\$\%\&\+\'\?\@]', ' ', watch['ComicName_Filesafe']).encode('utf-8').strip()
|
||||
#watchcomic = re.sub('\s+', ' ', str(watchcomic)).strip()
|
||||
|
||||
if ' the ' in watchcomic.lower():
|
||||
|
@ -153,6 +154,10 @@ def libraryScan(dir=None, append=False, ComicID=None, ComicName=None, cron=None)
|
|||
d_filename = re.sub('[\_\#\,\/\;\!\$\%\&\?\@]', ' ', comfilename)
|
||||
d_filename = re.sub('[\:\-\+\']', '#', d_filename)
|
||||
|
||||
#strip extraspaces
|
||||
d_filename = re.sub('\s+', ' ', d_filename)
|
||||
cfilename = re.sub('\s+', ' ', cfilename)
|
||||
|
||||
#versioning - remove it
|
||||
subsplit = cfilename.replace('_', ' ').split()
|
||||
volno = None
|
||||
|
@ -315,14 +320,13 @@ def libraryScan(dir=None, append=False, ComicID=None, ComicName=None, cron=None)
|
|||
logger.fdebug("adjusted comic and issue: " + str(comic_iss))
|
||||
#remove 'the' from here for proper comparisons.
|
||||
if ' the ' in comic_iss.lower():
|
||||
comic_iss = comic_iss[-4:]
|
||||
comic_iss = re.sub('\\bthe\\b','', comic_iss).strip()
|
||||
splitit = comic_iss.split(None)
|
||||
logger.fdebug("adjusting from: " + str(comic_iss_b4) + " to: " + str(comic_iss))
|
||||
#here we cycle through the Watchlist looking for a match.
|
||||
while (cm_cn < watchcnt):
|
||||
#setup the watchlist
|
||||
comname = ComicName[cm_cn]
|
||||
print ("watch_comic:" + comname)
|
||||
comyear = ComicYear[cm_cn]
|
||||
compub = ComicPublisher[cm_cn]
|
||||
comtotal = ComicTotal[cm_cn]
|
||||
|
|
24
mylar/mb.py
24
mylar/mb.py
|
@ -15,6 +15,7 @@
|
|||
|
||||
from __future__ import with_statement
|
||||
|
||||
import re
|
||||
import time
|
||||
import threading
|
||||
import urllib, urllib2
|
||||
|
@ -27,16 +28,20 @@ from mylar.helpers import multikeysort, replace_all, cleanName, cvapi_check
|
|||
mb_lock = threading.Lock()
|
||||
|
||||
|
||||
def pullsearch(comicapi,comicquery,offset,explicit):
|
||||
def pullsearch(comicapi,comicquery,offset,explicit,type):
|
||||
u_comicquery = urllib.quote(comicquery.encode('utf-8').strip())
|
||||
u_comicquery = u_comicquery.replace(" ", "%20")
|
||||
|
||||
if explicit == 'all' or explicit == 'loose':
|
||||
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)
|
||||
PULLURL = mylar.CVURL + 'search?api_key=' + str(comicapi) + '&resources=' + str(type) + '&query=' + u_comicquery + '&field_list=id,name,start_year,site_detail_url,count_of_issues,image,publisher,description&format=xml&page=' + str(offset)
|
||||
|
||||
else:
|
||||
# 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
|
||||
# add the 's' to the end of type to pluralize the caption (it's needed)
|
||||
if type == 'story_arc':
|
||||
logger.info('redefining.')
|
||||
u_comicquery = re.sub("%20AND%20", "%20", u_comicquery)
|
||||
PULLURL = mylar.CVURL + str(type) + 's?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
|
||||
#CV API Check here.
|
||||
|
@ -59,7 +64,7 @@ def pullsearch(comicapi,comicquery,offset,explicit):
|
|||
dom = parseString(data)
|
||||
return dom
|
||||
|
||||
def findComic(name, mode, issue, limityear=None, explicit=None):
|
||||
def findComic(name, mode, issue, limityear=None, explicit=None, type=None):
|
||||
|
||||
#with mb_lock:
|
||||
comiclist = []
|
||||
|
@ -77,7 +82,7 @@ def findComic(name, mode, issue, limityear=None, explicit=None):
|
|||
|
||||
if explicit is None:
|
||||
#logger.fdebug('explicit is None. Setting to Default mode of ALL search words.')
|
||||
comicquery=name.replace(" ", " AND ")
|
||||
#comicquery=name.replace(" ", " AND ")
|
||||
explicit = 'all'
|
||||
|
||||
#OR
|
||||
|
@ -99,8 +104,11 @@ def findComic(name, mode, issue, limityear=None, explicit=None):
|
|||
else:
|
||||
comicapi = mylar.COMICVINE_API
|
||||
|
||||
if type is None:
|
||||
type = 'volume'
|
||||
|
||||
#let's find out how many results we get from the query...
|
||||
searched = pullsearch(comicapi,comicquery,0,explicit)
|
||||
searched = pullsearch(comicapi,comicquery,0,explicit,type)
|
||||
if searched is None: return False
|
||||
totalResults = searched.getElementsByTagName('number_of_total_results')[0].firstChild.wholeText
|
||||
logger.fdebug("there are " + str(totalResults) + " search results...")
|
||||
|
@ -118,8 +126,8 @@ def findComic(name, mode, issue, limityear=None, explicit=None):
|
|||
#explicit uses offset
|
||||
offsetcount = countResults
|
||||
|
||||
searched = pullsearch(comicapi,comicquery,offsetcount,explicit)
|
||||
comicResults = searched.getElementsByTagName('volume')
|
||||
searched = pullsearch(comicapi,comicquery,offsetcount,explicit,type)
|
||||
comicResults = searched.getElementsByTagName(type) #('volume')
|
||||
body = ''
|
||||
n = 0
|
||||
if not comicResults:
|
||||
|
|
224
mylar/search.py
224
mylar/search.py
|
@ -16,13 +16,12 @@
|
|||
from __future__ import division
|
||||
|
||||
import mylar
|
||||
from mylar import logger, db, updater, helpers, parseit, findcomicfeed, notifiers, rsscheck
|
||||
from mylar import logger, db, updater, helpers, parseit, findcomicfeed, notifiers, rsscheck, Failed
|
||||
|
||||
import lib.feedparser as feedparser
|
||||
import urllib
|
||||
import os, errno
|
||||
import string
|
||||
import sqlite3 as lite
|
||||
import sys
|
||||
import getopt
|
||||
import re
|
||||
|
@ -34,7 +33,11 @@ import email.utils
|
|||
import datetime
|
||||
from wsgiref.handlers import format_date_time
|
||||
|
||||
def search_init(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDate, StoreDate, IssueID, AlternateSearch=None, UseFuzzy=None, ComicVersion=None, SARC=None, IssueArcID=None, mode=None, rsscheck=None, ComicID=None, manualsearch=None):
|
||||
def search_init(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDate, StoreDate, IssueID, AlternateSearch=None, UseFuzzy=None, ComicVersion=None, SARC=None, IssueArcID=None, mode=None, rsscheck=None, ComicID=None, manualsearch=None, filesafe=None):
|
||||
if filesafe:
|
||||
if filesafe != ComicName:
|
||||
logger.info('[SEARCH] altering ComicName to search-safe Name : ' + filesafe)
|
||||
ComicName = filesafe
|
||||
if ComicYear == None: ComicYear = '2014'
|
||||
else: ComicYear = str(ComicYear)[:4]
|
||||
if Publisher == 'IDW Publishing': Publisher = 'IDW'
|
||||
|
@ -597,46 +600,51 @@ def NZB_SEARCH(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDa
|
|||
except:
|
||||
logger.fdebug('invalid date found. Unable to continue - skipping result.')
|
||||
continue
|
||||
#use store date instead of publication date for comparisons since publication date is usually +2 months
|
||||
if StoreDate is None or StoreDate == '0000-00-00':
|
||||
if IssueDate is None or IssueDate == '0000-00-00':
|
||||
logger.fdebug('Invalid store date & issue date detected - you probably should refresh the series or wait for CV to correct the data')
|
||||
|
||||
if UseFuzzy == "1":
|
||||
logger.fdebug('Year has been fuzzied for this series, ignoring store date comparison entirely.')
|
||||
else:
|
||||
|
||||
#use store date instead of publication date for comparisons since publication date is usually +2 months
|
||||
if StoreDate is None or StoreDate == '0000-00-00':
|
||||
if IssueDate is None or IssueDate == '0000-00-00':
|
||||
logger.fdebug('Invalid store date & issue date detected - you probably should refresh the series or wait for CV to correct the data')
|
||||
continue
|
||||
else:
|
||||
stdate = IssueDate
|
||||
else:
|
||||
stdate = StoreDate
|
||||
#logger.fdebug('Posting date of : ' + str(pubdate))
|
||||
# convert it to a tuple
|
||||
dateconv = email.utils.parsedate_tz(pubdate)
|
||||
#logger.fdebug('dateconv of : ' + str(dateconv))
|
||||
# convert it to a numeric time, then subtract the timezone difference (+/- GMT)
|
||||
if dateconv[-1] is not None:
|
||||
postdate_int = time.mktime(dateconv[:len(dateconv)-1]) - dateconv[-1]
|
||||
else:
|
||||
postdate_int = time.mktime(dateconv[:len(dateconv)-1])
|
||||
#logger.fdebug('postdate_int of : ' + str(postdate_int))
|
||||
#logger.fdebug('Issue date of : ' + str(stdate))
|
||||
#convert it to a Thu, 06 Feb 2014 00:00:00 format
|
||||
issue_convert = datetime.datetime.strptime(stdate.rstrip(), '%Y-%m-%d')
|
||||
#logger.fdebug('issue_convert:' + str(issue_convert))
|
||||
#issconv = issue_convert.strftime('%a, %d %b %Y %H:%M:%S')
|
||||
# to get past different locale's os-dependent dates, let's convert it to a generic datetime format
|
||||
stamp = time.mktime(issue_convert.timetuple())
|
||||
#logger.fdebug('stamp: ' + str(stamp))
|
||||
issconv = format_date_time(stamp)
|
||||
#logger.fdebug('issue date is :' + str(issconv))
|
||||
#convert it to a tuple
|
||||
econv = email.utils.parsedate_tz(issconv)
|
||||
#logger.fdebug('econv:' + str(econv))
|
||||
#convert it to a numeric and drop the GMT/Timezone
|
||||
issuedate_int = time.mktime(econv[:len(econv)-1])
|
||||
#logger.fdebug('issuedate_int:' + str(issuedate_int))
|
||||
if postdate_int < issuedate_int:
|
||||
logger.fdebug(str(pubdate) + ' is before store date of ' + str(stdate) + '. Ignoring search result as this is not the right issue.')
|
||||
continue
|
||||
else:
|
||||
stdate = IssueDate
|
||||
else:
|
||||
stdate = StoreDate
|
||||
#logger.fdebug('Posting date of : ' + str(pubdate))
|
||||
# convert it to a tuple
|
||||
dateconv = email.utils.parsedate_tz(pubdate)
|
||||
#logger.fdebug('dateconv of : ' + str(dateconv))
|
||||
# convert it to a numeric time, then subtract the timezone difference (+/- GMT)
|
||||
if dateconv[-1] is not None:
|
||||
postdate_int = time.mktime(dateconv[:len(dateconv)-1]) - dateconv[-1]
|
||||
else:
|
||||
postdate_int = time.mktime(dateconv[:len(dateconv)-1])
|
||||
#logger.fdebug('postdate_int of : ' + str(postdate_int))
|
||||
#logger.fdebug('Issue date of : ' + str(stdate))
|
||||
#convert it to a Thu, 06 Feb 2014 00:00:00 format
|
||||
issue_convert = datetime.datetime.strptime(stdate.rstrip(), '%Y-%m-%d')
|
||||
#logger.fdebug('issue_convert:' + str(issue_convert))
|
||||
#issconv = issue_convert.strftime('%a, %d %b %Y %H:%M:%S')
|
||||
# to get past different locale's os-dependent dates, let's convert it to a generic datetime format
|
||||
stamp = time.mktime(issue_convert.timetuple())
|
||||
#logger.fdebug('stamp: ' + str(stamp))
|
||||
issconv = format_date_time(stamp)
|
||||
#logger.fdebug('issue date is :' + str(issconv))
|
||||
#convert it to a tuple
|
||||
econv = email.utils.parsedate_tz(issconv)
|
||||
#logger.fdebug('econv:' + str(econv))
|
||||
#convert it to a numeric and drop the GMT/Timezone
|
||||
issuedate_int = time.mktime(econv[:len(econv)-1])
|
||||
#logger.fdebug('issuedate_int:' + str(issuedate_int))
|
||||
if postdate_int < issuedate_int:
|
||||
logger.fdebug(str(pubdate) + ' is before store date of ' + str(stdate) + '. Ignoring search result as this is not the right issue.')
|
||||
continue
|
||||
else:
|
||||
logger.fdebug(str(pubdate) + ' is after store date of ' + str(stdate))
|
||||
logger.fdebug(str(pubdate) + ' is after store date of ' + str(stdate))
|
||||
|
||||
# -- end size constaints.
|
||||
|
||||
|
@ -1094,6 +1102,10 @@ def NZB_SEARCH(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDa
|
|||
|
||||
#issue comparison now as well
|
||||
if int(intIss) == int(comintIss):
|
||||
comicinfo = []
|
||||
comicinfo.append({"ComicName": ComicName,
|
||||
"IssueNumber": IssueNumber,
|
||||
"comyear": comyear})
|
||||
#check if nzb is in do not download list ;)
|
||||
if nzbprov == 'experimental':
|
||||
#id is located after the /download/ portion
|
||||
|
@ -1113,13 +1125,29 @@ def NZB_SEARCH(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDa
|
|||
nzbtempid = path_parts[2]
|
||||
nzbid = re.sub('.torrent', '', nzbtempid).rstrip()
|
||||
elif nzbprov == 'nzb.su':
|
||||
pass
|
||||
url_parts = urlparse.urlparse(entry['link'])
|
||||
path_parts = url_parts[2].rpartition('/')
|
||||
nzbid = re.sub('.nzb&','', path_parts[2]).strip()
|
||||
elif nzbprov == 'dognzb':
|
||||
pass
|
||||
url_parts = urlparse.urlparse(entry['link'])
|
||||
path_parts = url_parts[2].rpartition('/')
|
||||
nzbid = path_parts[0].rsplit('/',1)[1]
|
||||
elif nzbprov == 'newznab':
|
||||
#if in format of http://newznab/getnzb/<id>.nzb&i=1&r=apikey
|
||||
nzbid = os.path.splitext(entry['link'])[0].rsplit('/', 1)[1]
|
||||
|
||||
nzbname = nzbname_create(nzbprov, info=comicinfo, title=entry['title'])
|
||||
|
||||
if mylar.FAILED_DOWNLOAD_HANDLING:
|
||||
if nzbid is not None:
|
||||
call_the_fail = Failed.FailedProcessor(nzb_name=nzbname, id=nzbid, issueid=IssueID, comicid=ComicID, prov=tmpprov)
|
||||
check_the_fail = call_the_fail.failed_check()
|
||||
if check_the_fail == 'Failed':
|
||||
logger.fdebug('[FAILED_DOWNLOAD_CHECKER] [' + str(tmpprov) + '] Marked as a bad download : ' + str(nzbid))
|
||||
continue
|
||||
elif check_the_fail == 'Good':
|
||||
logger.fdebug('[FAILED_DOWNLOAD_CHECKER] This is not in the failed downloads list. Will continue with the download.')
|
||||
|
||||
logger.fdebug('issues match!')
|
||||
logger.info(u"Found " + ComicName + " (" + str(comyear) + ") issue: " + str(IssueNumber) + " using " + str(tmpprov) )
|
||||
## -- inherit issue. Comic year is non-standard. nzb year is the year
|
||||
|
@ -1131,7 +1159,6 @@ def NZB_SEARCH(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDa
|
|||
linkit = os.path.splitext(entry['link'])[1]
|
||||
if mylar.USE_SABNZBD:
|
||||
linkit = linkit.replace("&", "%26")
|
||||
logger.fdebug('new linkit:' + linkit)
|
||||
linkapi = str(linkstart) + str(linkit)
|
||||
else:
|
||||
# this should work for every other provider
|
||||
|
@ -1147,27 +1174,16 @@ def NZB_SEARCH(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDa
|
|||
if mylar.USE_BLACKHOLE and nzbprov != 'CBT' and nzbprov != 'KAT':
|
||||
logger.fdebug("using blackhole directory at : " + str(mylar.BLACKHOLE_DIR))
|
||||
if os.path.exists(mylar.BLACKHOLE_DIR):
|
||||
#pretty this biatch up.
|
||||
BComicName = re.sub('[\:\,\/\?]', '', str(ComicName))
|
||||
Bl_ComicName = re.sub('[\&]', 'and', str(BComicName))
|
||||
filenamenzb = str(re.sub(" ", ".", str(Bl_ComicName))) + "." + str(IssueNumber) + ".(" + str(comyear) + ").nzb"
|
||||
# Add a user-agent
|
||||
request = urllib2.Request(linkapi) #(str(mylar.BLACKHOLE_DIR) + str(filenamenzb))
|
||||
request.add_header('User-Agent', str(mylar.USER_AGENT))
|
||||
try:
|
||||
opener = helpers.urlretrieve(urllib2.urlopen(request), str(mylar.BLACKHOLE_DIR) + str(filenamenzb))
|
||||
opener = helpers.urlretrieve(urllib2.urlopen(request), str(mylar.BLACKHOLE_DIR) + str(nzbname) + '.nzb')
|
||||
except Exception, e:
|
||||
logger.warn('Error fetching data from %s: %s' % (nzbprov, e))
|
||||
return
|
||||
logger.fdebug("filename saved to your blackhole as : " + str(filenamenzb))
|
||||
logger.info(u"Successfully sent .nzb to your Blackhole directory : " + str(mylar.BLACKHOLE_DIR) + str(filenamenzb) )
|
||||
extensions = ('.cbr', '.cbz')
|
||||
|
||||
if filenamenzb.lower().endswith(extensions):
|
||||
fd, ext = os.path.splitext(filenamenzb)
|
||||
logger.fdebug("Removed extension from nzb: " + ext)
|
||||
nzbname = re.sub(str(ext), '', str(filenamenzb))
|
||||
logger.fdebug("nzb name to be used for post-processing is : " + str(nzbname))
|
||||
logger.fdebug("filename saved to your blackhole as : " + str(nzbname) + '.nzb')
|
||||
logger.info(u"Successfully sent .nzb to your Blackhole directory : " + str(mylar.BLACKHOLE_DIR) + str(filenamenzb) + '.nzb')
|
||||
sent_to = "your Blackhole Directory"
|
||||
#end blackhole
|
||||
elif nzbprov == 'CBT' or nzbprov == 'KAT':
|
||||
|
@ -1177,13 +1193,6 @@ def NZB_SEARCH(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDa
|
|||
logger.fdebug("Torrent Provider:" + nzbprov)
|
||||
foundc = "yes"
|
||||
|
||||
#let's change all space to decimals for simplicity
|
||||
nzbname = re.sub(" ", ".", str(entry['title']))
|
||||
#gotta replace & or escape it
|
||||
nzbname = re.sub("\&", 'and', str(nzbname))
|
||||
nzbname = re.sub('[\,\:\?]', '', str(nzbname))
|
||||
if nzbname.lower().endswith('.torrent'):
|
||||
nzbname = re.sub('.torrent', '', nzbname)
|
||||
rcheck = rsscheck.torsend2client(ComicName, IssueNumber, comyear, entry['link'], nzbprov)
|
||||
if rcheck == "fail":
|
||||
logger.error("Unable to send torrent - check logs and settings.")
|
||||
|
@ -1208,27 +1217,8 @@ def NZB_SEARCH(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDa
|
|||
if e.errno != errno.EEXIST:
|
||||
raise
|
||||
logger.fdebug("link to retrieve via api:" + str(helpers.apiremove(linkapi,'$')))
|
||||
|
||||
#let's change all space to decimals for simplicity
|
||||
nzbname = re.sub('\s+',' ', entry['title']) #make sure we remove the extra spaces.
|
||||
logger.fdebug('[SEARCHER] entry[title]: ' + entry['title'])
|
||||
logger.fdebug('[SEARCHER] nzbname (\s): ' + nzbname)
|
||||
nzbname = re.sub(' ', '.', nzbname)
|
||||
logger.fdebug('[SEARCHER] nzbname (space to .): ' + nzbname)
|
||||
#gotta replace & or escape it
|
||||
nzbname = re.sub("\&", 'and', nzbname)
|
||||
nzbname = re.sub('[\,\:\?]', '', nzbname)
|
||||
extensions = ('.cbr', '.cbz')
|
||||
logger.fdebug('[SEARCHER] end nzbname: ' + nzbname)
|
||||
|
||||
if nzbname.lower().endswith(extensions):
|
||||
fd, ext = os.path.splitext(nzbname)
|
||||
logger.fdebug("Removed extension from nzb: " + ext)
|
||||
nzbname = re.sub(str(ext), '', str(nzbname))
|
||||
|
||||
logger.fdebug("nzbname used for post-processing:" + str(nzbname))
|
||||
|
||||
# #test nzb.get
|
||||
#test nzb.get
|
||||
if mylar.USE_NZBGET:
|
||||
from xmlrpclib import ServerProxy
|
||||
if mylar.NZBGET_HOST[:4] == 'http':
|
||||
|
@ -1271,8 +1261,12 @@ def NZB_SEARCH(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDa
|
|||
if mylar.SAB_CATEGORY:
|
||||
tmpapi = tmpapi + "&cat=" + str(mylar.SAB_CATEGORY)
|
||||
logger.fdebug("...attaching category: " + str(helpers.apiremove(tmpapi,'&')))
|
||||
if mylar.RENAME_FILES or mylar.POST_PROCESSING:
|
||||
tmpapi = tmpapi + "&script=ComicRN.py"
|
||||
if mylar.POST_PROCESSING: #or mylar.RENAME_FILES:
|
||||
if mylar.POST_PROCESSING_SCRIPT:
|
||||
#this is relative to the SABnzbd script directory (ie. no path)
|
||||
tmpapi = tmpapi + "&script=" + mylar.POST_PROCESSING_SCRIPT
|
||||
else:
|
||||
tmpapi = tmpapi + "&script=ComicRN.py"
|
||||
logger.fdebug("...attaching rename script: " + str(helpers.apiremove(tmpapi,'&')))
|
||||
#final build of send-to-SAB
|
||||
tmpapi = tmpapi + "&apikey=" + str(mylar.SAB_APIKEY)
|
||||
|
@ -1333,7 +1327,8 @@ def NZB_SEARCH(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDa
|
|||
if foundc == "yes":
|
||||
foundcomic.append("yes")
|
||||
logger.fdebug("Found matching comic...preparing to send to Updater with IssueID: " + str(IssueID) + " and nzbname: " + str(nzbname))
|
||||
updater.nzblog(IssueID, nzbname, ComicName, SARC, IssueArcID)
|
||||
if '[RSS]' in tmpprov : tmpprov = tmpprov[:-4].strip()
|
||||
updater.nzblog(IssueID, nzbname, ComicName, SARC, IssueArcID, nzbid, tmpprov)
|
||||
prov_count == 0
|
||||
#break
|
||||
return foundc
|
||||
|
@ -1409,7 +1404,7 @@ def searchforissue(issueid=None, new=False, rsscheck=None):
|
|||
ComicYear = str(result['IssueDate'])[:4]
|
||||
mode = result['mode']
|
||||
if (mylar.NZBSU or mylar.DOGNZB or mylar.EXPERIMENTAL or mylar.NEWZNAB or mylar.ENABLE_KAT or mylar.ENABLE_CBT) and (mylar.USE_SABNZBD or mylar.USE_NZBGET or mylar.ENABLE_TORRENTS or mylar.USE_BLACKHOLE):
|
||||
foundNZB, prov = search_init(comic['ComicName'], result['Issue_Number'], str(ComicYear), comic['ComicYear'], Publisher, IssueDate, StoreDate, result['IssueID'], AlternateSearch, UseFuzzy, ComicVersion, SARC=None, IssueArcID=None, mode=mode, rsscheck=rsscheck, ComicID=result['ComicID'])
|
||||
foundNZB, prov = search_init(comic['ComicName'], result['Issue_Number'], str(ComicYear), comic['ComicYear'], Publisher, IssueDate, StoreDate, result['IssueID'], AlternateSearch, UseFuzzy, ComicVersion, SARC=None, IssueArcID=None, mode=mode, rsscheck=rsscheck, ComicID=result['ComicID'], filesafe=comic['ComicName_Filesafe'])
|
||||
if foundNZB == "yes":
|
||||
#print ("found!")
|
||||
updater.foundsearch(result['ComicID'], result['IssueID'], mode=mode, provider=prov)
|
||||
|
@ -1448,7 +1443,7 @@ def searchforissue(issueid=None, new=False, rsscheck=None):
|
|||
|
||||
foundNZB = "none"
|
||||
if (mylar.NZBSU or mylar.DOGNZB or mylar.EXPERIMENTAL or mylar.NEWZNAB or mylar.ENABLE_KAT or mylar.ENABLE_CBT) and (mylar.USE_SABNZBD or mylar.USE_NZBGET or mylar.ENABLE_TORRENTS or mylar.USE_BLACKHOLE):
|
||||
foundNZB, prov = search_init(comic['ComicName'], result['Issue_Number'], str(IssueYear), comic['ComicYear'], Publisher, IssueDate, StoreDate, result['IssueID'], AlternateSearch, UseFuzzy, ComicVersion, SARC=None, IssueArcID=None, mode=mode, rsscheck=rsscheck, ComicID=result['ComicID'])
|
||||
foundNZB, prov = search_init(comic['ComicName'], result['Issue_Number'], str(IssueYear), comic['ComicYear'], Publisher, IssueDate, StoreDate, result['IssueID'], AlternateSearch, UseFuzzy, ComicVersion, SARC=None, IssueArcID=None, mode=mode, rsscheck=rsscheck, ComicID=result['ComicID'], filesafe=comic['ComicName_Filesafe'])
|
||||
if foundNZB == "yes":
|
||||
logger.fdebug("I found " + comic['ComicName'] + ' #:' + str(result['Issue_Number']))
|
||||
updater.foundsearch(ComicID=result['ComicID'], IssueID=result['IssueID'], mode=mode, provider=prov)
|
||||
|
@ -1481,7 +1476,7 @@ def searchIssueIDList(issuelist):
|
|||
else:
|
||||
IssueYear = str(issue['IssueDate'])[:4]
|
||||
if (mylar.NZBSU or mylar.DOGNZB or mylar.EXPERIMENTAL or mylar.NEWZNAB or mylar.ENABLE_CBT or mylar.ENABLE_KAT) and (mylar.USE_SABNZBD or mylar.USE_NZBGET or mylar.ENABLE_TORRENTS or mylar.USE_BLACKHOLE):
|
||||
foundNZB, prov = search_init(comic['ComicName'], issue['Issue_Number'], str(IssueYear), comic['ComicYear'], Publisher, issue['IssueDate'], issue['ReleaseDate'], issue['IssueID'], AlternateSearch, UseFuzzy, ComicVersion, SARC=None, IssueArcID=None, mode=mode, ComicID=issue['ComicID'])
|
||||
foundNZB, prov = search_init(comic['ComicName'], issue['Issue_Number'], str(IssueYear), comic['ComicYear'], Publisher, issue['IssueDate'], issue['ReleaseDate'], issue['IssueID'], AlternateSearch, UseFuzzy, ComicVersion, SARC=None, IssueArcID=None, mode=mode, ComicID=issue['ComicID'], filesafe=comic['ComicName_Filesafe'])
|
||||
if foundNZB == "yes":
|
||||
#print ("found!")
|
||||
updater.foundsearch(ComicID=issue['ComicID'], IssueID=issue['IssueID'], mode=mode, provider=prov)
|
||||
|
@ -1533,3 +1528,50 @@ def provider_sequence(nzbprovider, torprovider, newznab_hosts):
|
|||
logger.fdebug('sequence is now to start with ' + pr_order[1] + ' at spot #' + str(pr_order[0]))
|
||||
|
||||
return prov_order,newznab_info
|
||||
|
||||
def nzbname_create(provider, title=None, info=None):
|
||||
#the nzbname here is used when post-processing
|
||||
# it searches nzblog which contains the nzbname to pull out the IssueID and start the post-processing
|
||||
# it is also used to keep the hashinfo for the nzbname in case it fails downloading, it will get put into the failed db for future exclusions
|
||||
|
||||
if mylar.USE_BLACKHOLE and provider != 'CBT' and provider != 'KAT':
|
||||
if os.path.exists(mylar.BLACKHOLE_DIR):
|
||||
#load in the required info to generate the nzb names when required (blackhole only)
|
||||
ComicName = info[0]['ComicName']
|
||||
IssueNumber = info[0]['IssueNumber']
|
||||
comyear = info[0]['comyear']
|
||||
#pretty this biatch up.
|
||||
BComicName = re.sub('[\:\,\/\?]', '', str(ComicName))
|
||||
Bl_ComicName = re.sub('[\&]', 'and', str(BComicName))
|
||||
nzbname = str(re.sub(" ", ".", str(Bl_ComicName))) + "." + str(IssueNumber) + ".(" + str(comyear) + ")"
|
||||
|
||||
logger.fdebug("nzb name to be used for post-processing is : " + str(nzbname))
|
||||
|
||||
elif provider == 'CBT' or provider == 'KAT':
|
||||
#let's change all space to decimals for simplicity
|
||||
nzbname = re.sub(" ", ".", title)
|
||||
#gotta replace & or escape it
|
||||
nzbname = re.sub("\&", 'and', str(nzbname))
|
||||
nzbname = re.sub('[\,\:\?]', '', str(nzbname))
|
||||
if nzbname.lower().endswith('.torrent'):
|
||||
nzbname = re.sub('.torrent', '', nzbname)
|
||||
|
||||
else:
|
||||
# let's change all space to decimals for simplicity
|
||||
nzbname = re.sub('\s+',' ', title) #make sure we remove the extra spaces.
|
||||
logger.fdebug('[SEARCHER] entry[title]: ' + title)
|
||||
logger.fdebug('[SEARCHER] nzbname (\s): ' + nzbname)
|
||||
nzbname = re.sub(' ', '.', nzbname)
|
||||
logger.fdebug('[SEARCHER] nzbname (space to .): ' + nzbname)
|
||||
#gotta replace & or escape it
|
||||
nzbname = re.sub("\&", 'and', nzbname)
|
||||
nzbname = re.sub('[\,\:\?]', '', nzbname)
|
||||
extensions = ('.cbr', '.cbz')
|
||||
logger.fdebug('[SEARCHER] end nzbname: ' + nzbname)
|
||||
|
||||
|
||||
nzbname = re.sub('.cbr', '', nzbname).strip()
|
||||
nzbname = re.sub('.cbz', '', nzbname).strip()
|
||||
|
||||
logger.fdebug("nzbname used for post-processing:" + str(nzbname))
|
||||
return nzbname
|
||||
|
|
|
@ -281,13 +281,42 @@ def populate(link,publisher,shipdate):
|
|||
if exinfo == '&': exinfo = 'N/A'
|
||||
|
||||
comic = tempName[:stissue].strip()
|
||||
|
||||
if 'for \$1' in comic:
|
||||
exinfo = 'for $1'
|
||||
comic = comic.replace('for \$1\:', '').lstrip()
|
||||
|
||||
issuedate = shipdate
|
||||
if 'on sale' in str(titlet).lower():
|
||||
onsale_start = str(titlet).lower().find('on sale') + 8
|
||||
onsale_end = str(titlet).lower().find('<br>',onsale_start)
|
||||
thedate = str(titlet)[onsale_start:onsale_end]
|
||||
m = None
|
||||
|
||||
basemonths = {'january':'1','jan':'1','february':'2','feb':'2','march':'3','mar':'3','april':'4','apr':'4','may':'5','june':'6','july':'7','august':'8','aug':'8','september':'9','sept':'9','october':'10','oct':'10','november':'11','nov':'11','december':'12','dec':'12'}
|
||||
for month in basemonths:
|
||||
if month in thedate.lower():
|
||||
m = basemonths[month]
|
||||
monthname = month
|
||||
break
|
||||
|
||||
if m is not None:
|
||||
theday = len(month) + 1 # account for space between month & day
|
||||
thedaystart = thedate[theday:(theday+2)].strip() # day numeric won't exceed 2
|
||||
if len(str(thedaystart)) == 1:
|
||||
thedaystart = '0' + str(thedaystart)
|
||||
if len(str(m)) == 1:
|
||||
m = '0' + str(m)
|
||||
thedate = shipdate[-4:] + '-' + str(m) + '-' + str(thedaystart)
|
||||
|
||||
logger.info('[' + comic + '] On sale :' + str(thedate))
|
||||
exinfo += ' [' + str(thedate) + ']'
|
||||
issuedate = thedate
|
||||
|
||||
|
||||
if issue1:
|
||||
upcome.append({
|
||||
'Shipdate': shipdate,
|
||||
'Shipdate': issuedate,
|
||||
'Publisher': publisher.upper(),
|
||||
'Issue': re.sub('#', '',issue1).lstrip(),
|
||||
'Comic': comic.upper(),
|
||||
|
@ -298,7 +327,7 @@ def populate(link,publisher,shipdate):
|
|||
#print ('extra info: ' + exinfo)
|
||||
if issue2:
|
||||
upcome.append({
|
||||
'Shipdate': shipdate,
|
||||
'Shipdate': issuedate,
|
||||
'Publisher': publisher.upper(),
|
||||
'Issue': re.sub('#', '', issue2).lstrip(),
|
||||
'Comic': comic.upper(),
|
||||
|
@ -309,7 +338,7 @@ def populate(link,publisher,shipdate):
|
|||
#print ('extra info: ' + exinfo)
|
||||
else:
|
||||
upcome.append({
|
||||
'Shipdate': shipdate,
|
||||
'Shipdate': issuedate,
|
||||
'Publisher': publisher.upper(),
|
||||
'Issue': re.sub('#', '', issue).lstrip(),
|
||||
'Comic': comic.upper(),
|
||||
|
|
124
mylar/updater.py
124
mylar/updater.py
|
@ -113,44 +113,55 @@ def dbUpdate(ComicIDList=None):
|
|||
fndissue = []
|
||||
for issue in issues:
|
||||
for issuenew in issues_new:
|
||||
#logger.fdebug(str(issue['Issue_Number']) + ' - issuenew:' + str(issuenew['IssueID']) + ' : ' + str(issuenew['Status']))
|
||||
#logger.fdebug(str(issue['Issue_Number']) + ' - issue:' + str(issue['IssueID']) + ' : ' + str(issue['Status']))
|
||||
if issuenew['IssueID'] == issue['IssueID'] and issuenew['Status'] != issue['Status']:
|
||||
ctrlVAL = {"IssueID": issue['IssueID']}
|
||||
#if the status is None and the original status is either Downloaded / Archived, keep status & stats
|
||||
if issuenew['Status'] == None and (issue['Status'] == 'Downloaded' or issue['Status'] == 'Archived'):
|
||||
newVAL = {"Location": issue['Location'],
|
||||
"ComicSize": issue['ComicSize'],
|
||||
"Status": issue['Status']}
|
||||
#if the status is now Downloaded/Snatched, keep status & stats (downloaded only)
|
||||
elif issuenew['Status'] == 'Downloaded' or issue['Status'] == 'Snatched':
|
||||
newVAL = {"Location": issue['Location'],
|
||||
"ComicSize": issue['ComicSize']}
|
||||
if issuenew['Status'] == 'Downloaded':
|
||||
newVAL['Status'] = issuenew['Status']
|
||||
logger.fdebug(str(issue['Issue_Number']) + ' - issuenew:' + str(issuenew['IssueID']) + ' : ' + str(issuenew['Status']))
|
||||
logger.fdebug(str(issue['Issue_Number']) + ' - issue:' + str(issue['IssueID']) + ' : ' + str(issue['Status']))
|
||||
try:
|
||||
if issuenew['IssueID'] == issue['IssueID'] and (issuenew['Status'] != issue['Status'] or issue['IssueDate_Edit'] is not None):
|
||||
ctrlVAL = {"IssueID": issue['IssueID']}
|
||||
#if the status is None and the original status is either Downloaded / Archived, keep status & stats
|
||||
if issuenew['Status'] == None and (issue['Status'] == 'Downloaded' or issue['Status'] == 'Archived'):
|
||||
newVAL = {"Location": issue['Location'],
|
||||
"ComicSize": issue['ComicSize'],
|
||||
"Status": issue['Status']}
|
||||
#if the status is now Downloaded/Snatched, keep status & stats (downloaded only)
|
||||
elif issuenew['Status'] == 'Downloaded' or issue['Status'] == 'Snatched':
|
||||
newVAL = {"Location": issue['Location'],
|
||||
"ComicSize": issue['ComicSize']}
|
||||
if issuenew['Status'] == 'Downloaded':
|
||||
newVAL['Status'] = issuenew['Status']
|
||||
else:
|
||||
newVAL['Status'] = issue['Status']
|
||||
|
||||
elif issue['Status'] == 'Archived':
|
||||
newVAL = {"Status": issue['Status'],
|
||||
"Location": issue['Location'],
|
||||
"ComicSize": issue['ComicSize']}
|
||||
else:
|
||||
newVAL['Status'] = issue['Status']
|
||||
#change the status to the previous status
|
||||
newVAL = {"Status": issue['Status']}
|
||||
|
||||
elif issue['Status'] == 'Archived':
|
||||
newVAL = {"Status": issue['Status'],
|
||||
"Location": issue['Location'],
|
||||
"ComicSize": issue['ComicSize']}
|
||||
else:
|
||||
#change the status to the previous status
|
||||
newVAL = {"Status": issue['Status']}
|
||||
if newVAL['Status'] == None:
|
||||
newVAL = {"Status": "Skipped"}
|
||||
|
||||
if newVAL['Status'] == None:
|
||||
newVAL = {"Status": "Skipped"}
|
||||
if issue['IssueDate_Edit']:
|
||||
logger.info('[#' + str(issue['Issue_Number']) + '] detected manually edited Issue Date.')
|
||||
logger.info('new value : ' + str(issue['IssueDate']) + ' ... cv value : ' + str(issuenew['IssueDate']))
|
||||
newVAL['IssueDate'] = issue['IssueDate']
|
||||
newVAL['IssueDate_Edit'] = issue['IssueDate_Edit']
|
||||
|
||||
if any(d['IssueID'] == str(issue['IssueID']) for d in ann_list):
|
||||
#logger.fdebug("annual detected for " + str(issue['IssueID']) + " #: " + str(issue['Issue_Number']))
|
||||
myDB.upsert("Annuals", newVAL, ctrlVAL)
|
||||
else:
|
||||
#logger.fdebug('#' + str(issue['Issue_Number']) + ' writing issuedata: ' + str(newVAL))
|
||||
myDB.upsert("Issues", newVAL, ctrlVAL)
|
||||
fndissue.append({"IssueID": issue['IssueID']})
|
||||
icount+=1
|
||||
break
|
||||
except:
|
||||
logger.warn('Something is out of whack somewhere with the series.')
|
||||
#if it's an annual (ie. deadpool-2011 ) on a refresh will throw index errors for some reason.
|
||||
|
||||
if any(d['IssueID'] == str(issue['IssueID']) for d in ann_list):
|
||||
#logger.fdebug("annual detected for " + str(issue['IssueID']) + " #: " + str(issue['Issue_Number']))
|
||||
myDB.upsert("Annuals", newVAL, ctrlVAL)
|
||||
else:
|
||||
#logger.fdebug('#' + str(issue['Issue_Number']) + ' writing issuedata: ' + str(newVAL))
|
||||
myDB.upsert("Issues", newVAL, ctrlVAL)
|
||||
fndissue.append({"IssueID": issue['IssueID']})
|
||||
icount+=1
|
||||
break
|
||||
logger.info("In the process of converting the data to CV, I changed the status of " + str(icount) + " issues.")
|
||||
|
||||
issues_new = myDB.select('SELECT * FROM issues WHERE ComicID=? AND Status is NULL', [ComicID])
|
||||
|
@ -410,7 +421,7 @@ def no_searchresults(ComicID):
|
|||
"LatestIssue": "Error"}
|
||||
myDB.upsert("comics", newValue, controlValue)
|
||||
|
||||
def nzblog(IssueID, NZBName, ComicName, SARC=None, IssueArcID=None):
|
||||
def nzblog(IssueID, NZBName, ComicName, SARC=None, IssueArcID=None, id=None, prov=None):
|
||||
myDB = db.DBConnection()
|
||||
|
||||
newValue = {"NZBName": NZBName}
|
||||
|
@ -428,12 +439,17 @@ def nzblog(IssueID, NZBName, ComicName, SARC=None, IssueArcID=None):
|
|||
IssueID = 'S' + str(IssueArcID)
|
||||
newValue['SARC'] = SARC
|
||||
|
||||
controlValue = {"IssueID": IssueID}
|
||||
#print controlValue
|
||||
#newValue['NZBName'] = NZBName
|
||||
#print newValue
|
||||
controlValue = {"IssueID": IssueID,
|
||||
"Provider": prov}
|
||||
|
||||
|
||||
if id:
|
||||
logger.info('setting the nzbid for this download grabbed by ' + prov + ' in the nzblog to : ' + str(id))
|
||||
newValue["ID"] = id
|
||||
|
||||
myDB.upsert("nzblog", newValue, controlValue)
|
||||
|
||||
|
||||
def foundsearch(ComicID, IssueID, mode=None, down=None, provider=None, SARC=None, IssueArcID=None, module=None):
|
||||
# When doing a Force Search (Wanted tab), the resulting search calls this to update.
|
||||
|
||||
|
@ -563,9 +579,22 @@ def forceRescan(ComicID,archive=None,module=None):
|
|||
myDB = db.DBConnection()
|
||||
# file check to see if issue exists
|
||||
rescan = myDB.selectone('SELECT * FROM comics WHERE ComicID=?', [ComicID]).fetchone()
|
||||
if rescan['AlternateSearch'] is not None:
|
||||
altnames = rescan['AlternateSearch'] + '##'
|
||||
else:
|
||||
altnames = ''
|
||||
annscan = myDB.select('SELECT * FROM annuals WHERE ComicID=?', [ComicID])
|
||||
if annscan is None:
|
||||
pass
|
||||
else:
|
||||
for ascan in annscan:
|
||||
logger.info('ReleaseComicName: ' + ascan['ReleaseComicName'])
|
||||
if ascan['ReleaseComicName'] not in altnames:
|
||||
altnames += ascan['ReleaseComicName'] + '!!' + ascan['ReleaseComicID'] + '##'
|
||||
altnames = altnames[:-2]
|
||||
logger.info(module + ' Now checking files for ' + rescan['ComicName'] + ' (' + str(rescan['ComicYear']) + ') in ' + rescan['ComicLocation'] )
|
||||
if archive is None:
|
||||
fc = filechecker.listFiles(dir=rescan['ComicLocation'], watchcomic=rescan['ComicName'], Publisher=rescan['ComicPublisher'], AlternateSearch=rescan['AlternateSearch'])
|
||||
fc = filechecker.listFiles(dir=rescan['ComicLocation'], watchcomic=rescan['ComicName'], Publisher=rescan['ComicPublisher'], AlternateSearch=altnames) #rescan['AlternateSearch'])
|
||||
else:
|
||||
fc = filechecker.listFiles(dir=archive, watchcomic=rescan['ComicName'], Publisher=rescan['ComicPublisher'], AlternateSearch=rescan['AlternateSearch'])
|
||||
iscnt = rescan['Total']
|
||||
|
@ -747,9 +776,15 @@ def forceRescan(ComicID,archive=None,module=None):
|
|||
if haveissue == "yes" or issuedupe == "yes": break
|
||||
n+=1
|
||||
else:
|
||||
if tmpfc['AnnualComicID']:
|
||||
ANNComicID = tmpfc['AnnualComicID']
|
||||
logger.fdebug(module + ' Forcing ComicID to ' + str(ANNComicID) + ' in case of duplicate numbering across volumes.')
|
||||
reannuals = myDB.select('SELECT * FROM annuals WHERE ComicID=? AND ReleaseComicID=?', [ComicID, ANNComicID])
|
||||
else:
|
||||
reannuals = myDB.select('SELECT * FROM annuals WHERE ComicID=?', [ComicID])
|
||||
|
||||
# annual inclusion here.
|
||||
#logger.fdebug("checking " + str(temploc))
|
||||
reannuals = myDB.select('SELECT * FROM annuals WHERE ComicID=?', [ComicID])
|
||||
fcnew = shlex.split(str(temploc))
|
||||
fcn = len(fcnew)
|
||||
n = 0
|
||||
|
@ -786,8 +821,8 @@ def forceRescan(ComicID,archive=None,module=None):
|
|||
if int(fcdigit) == int_iss:
|
||||
logger.fdebug(module + ' Annual match - issue : ' + str(int_iss))
|
||||
for d in annualdupechk:
|
||||
if int(d['fcdigit']) == int(fcdigit):
|
||||
logger.fdebug(module + ' Duplicate annual issue detected - not counting this: ' + str(tmpfc['ComicFilename']))
|
||||
if int(d['fcdigit']) == int(fcdigit) and d['anncomicid'] == ANNComicID:
|
||||
logger.fdebug(module + ' Duplicate annual issue detected for Annual ComicID of ' + str(ANNComicID) + ' - not counting this: ' + str(tmpfc['ComicFilename']))
|
||||
issuedupe = "yes"
|
||||
break
|
||||
if issuedupe == "no":
|
||||
|
@ -800,7 +835,8 @@ def forceRescan(ComicID,archive=None,module=None):
|
|||
logger.fdebug(module + ' .......filesize: ' + str(tmpfc['ComicSize']))
|
||||
# to avoid duplicate issues which screws up the count...let's store the filename issues then
|
||||
# compare earlier...
|
||||
annualdupechk.append({'fcdigit': int(fcdigit)})
|
||||
annualdupechk.append({'fcdigit': int(fcdigit),
|
||||
'anncomicid': ANNComicID})
|
||||
break
|
||||
som+=1
|
||||
if haveissue == "yes": break
|
||||
|
|
|
@ -33,7 +33,7 @@ import shutil
|
|||
|
||||
import mylar
|
||||
|
||||
from mylar import logger, db, importer, mb, search, filechecker, helpers, updater, parseit, weeklypull, PostProcessor, version, librarysync, moveit #,rsscheck
|
||||
from mylar import logger, db, importer, mb, search, filechecker, helpers, updater, parseit, weeklypull, PostProcessor, version, librarysync, moveit, Failed #,rsscheck
|
||||
#from mylar.helpers import checked, radio, today
|
||||
|
||||
import lib.simplejson as simplejson
|
||||
|
@ -119,10 +119,11 @@ class WebInterface(object):
|
|||
isCounts[3] = 0 #3 archived
|
||||
isCounts[4] = 0 #4 downloaded
|
||||
isCounts[5] = 0 #5 ignored
|
||||
#isCounts[6] = 0 #6 read
|
||||
isCounts[6] = 0 #6 failed
|
||||
#isCounts[7] = 0 #7 read
|
||||
|
||||
for curResult in issues:
|
||||
baseissues = {'skipped':1,'wanted':2,'archived':3,'downloaded':4,'ignored':5}
|
||||
baseissues = {'skipped':1,'wanted':2,'archived':3,'downloaded':4,'ignored':5,'failed':6}
|
||||
for seas in baseissues:
|
||||
if curResult['Status'] is None:
|
||||
continue
|
||||
|
@ -136,7 +137,8 @@ class WebInterface(object):
|
|||
"Wanted" : str(isCounts[2]),
|
||||
"Archived" : str(isCounts[3]),
|
||||
"Downloaded" : str(isCounts[4]),
|
||||
"Ignored" : str(isCounts[5])
|
||||
"Ignored" : str(isCounts[5]),
|
||||
"Failed" : str(isCounts[6])
|
||||
}
|
||||
usethefuzzy = comic['UseFuzzy']
|
||||
skipped2wanted = "0"
|
||||
|
@ -173,7 +175,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, explicit=None):
|
||||
def searchit(self, name, issue=None, mode=None, type=None, explicit=None, serinfo=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:
|
||||
|
@ -195,15 +197,15 @@ class WebInterface(object):
|
|||
searchresults, explicit = mb.findComic(name, mode, issue=None, explicit=explicit)
|
||||
elif type == 'comic' and mode == 'want':
|
||||
searchresults, explicit = mb.findComic(name, mode, issue)
|
||||
elif type == 'storyarc':
|
||||
searchresults, explicit = mb.findComic(name, mode, issue=None, storyarc='yes')
|
||||
elif type == 'story_arc':
|
||||
searchresults, explicit = mb.findComic(name, mode=None, issue=None, explicit='explicit', type='story_arc')
|
||||
|
||||
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, name=name, explicit=explicit)
|
||||
return serve_template(templatename="searchresults.html", title='Search Results for: "' + name + '"', searchresults=searchresults, type=type, imported=None, ogcname=None, name=name, explicit=explicit, serinfo=serinfo)
|
||||
searchit.exposed = True
|
||||
|
||||
def addComic(self, comicid, comicname=None, comicyear=None, comicimage=None, comicissues=None, comicpublisher=None, imported=None, ogcname=None):
|
||||
def addComic(self, comicid, comicname=None, comicyear=None, comicimage=None, comicissues=None, comicpublisher=None, imported=None, ogcname=None, serinfo=None):
|
||||
myDB = db.DBConnection()
|
||||
if imported == "confirm":
|
||||
# if it's coming from the importer and it's just for confirmation, record the right selection and break.
|
||||
|
@ -224,6 +226,17 @@ class WebInterface(object):
|
|||
myDB.upsert("importresults", newValue, controlValue)
|
||||
self.importResults()
|
||||
return
|
||||
elif imported == 'futurecheck':
|
||||
print 'serinfo:' + str(serinfo)
|
||||
logger.info('selected comicid of : ' + str(comicid) + ' [ ' + comicname + ' (' + str(comicyear) + ') ]')
|
||||
ser = []
|
||||
ser.append({"comicname": comicname,
|
||||
"comicyear": comicyear,
|
||||
"comicissues": comicissues,
|
||||
"comicpublisher": comicpublisher,
|
||||
"IssueDate": serinfo[0]['IssueDate'],
|
||||
"IssueNumber": serinfo[0]['IssueNumber']})
|
||||
self.future_check_add(comicid, ser)
|
||||
sresults = []
|
||||
cresults = []
|
||||
mismatch = "no"
|
||||
|
@ -410,19 +423,64 @@ class WebInterface(object):
|
|||
raise cherrypy.HTTPRedirect("comicDetails?ComicID=%s" % gcomicid)
|
||||
GCDaddComic.exposed = True
|
||||
|
||||
def post_process(self, nzb_name, nzb_folder):
|
||||
logger.info(u"Starting postprocessing for : " + str(nzb_name) )
|
||||
PostProcess = PostProcessor.PostProcessor(nzb_name, nzb_folder)
|
||||
if nzb_name == 'Manual Run' or nzb_name == 'Manual+Run':
|
||||
threading.Thread(target=PostProcess.Process).start()
|
||||
raise cherrypy.HTTPRedirect("home")
|
||||
else:
|
||||
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")
|
||||
def post_process(self, nzb_name, nzb_folder, failed=False):
|
||||
import Queue
|
||||
logger.info('Starting postprocessing for : ' + nzb_name)
|
||||
if failed == '0':
|
||||
failed = False
|
||||
elif failed == '1':
|
||||
failed = True
|
||||
|
||||
queue = Queue.Queue()
|
||||
|
||||
if not failed:
|
||||
PostProcess = PostProcessor.PostProcessor(nzb_name, nzb_folder, queue=queue)
|
||||
if nzb_name == 'Manual Run' or nzb_name == 'Manual+Run':
|
||||
threading.Thread(target=PostProcess.Process).start()
|
||||
raise cherrypy.HTTPRedirect("home")
|
||||
else:
|
||||
thread_ = threading.Thread(target=PostProcess.Process, name="Post-Processing")
|
||||
thread_.start()
|
||||
thread_.join()
|
||||
chk = queue.get()
|
||||
while True:
|
||||
if chk[0]['mode'] == 'fail':
|
||||
yield chk[0]['self.log']
|
||||
logger.info('Initiating Failed Download handling')
|
||||
if chk[0]['annchk'] == 'no': mode = 'want'
|
||||
else: mode = 'want_ann'
|
||||
failed = True
|
||||
break
|
||||
elif chk[0]['mode'] == 'stop':
|
||||
yield chk[0]['self.log']
|
||||
break
|
||||
else:
|
||||
logger.error('mode is unsupported: ' + chk[0]['mode'])
|
||||
yield chk[0]['self.log']
|
||||
break
|
||||
|
||||
if failed:
|
||||
if mylar.FAILED_DOWNLOAD_HANDLING:
|
||||
#drop the if-else continuation so we can drop down to this from the above if statement.
|
||||
logger.info('Initiating Failed Download handling for this download.')
|
||||
FailProcess = Failed.FailedProcessor(nzb_name=nzb_name, nzb_folder=nzb_folder, queue=queue)
|
||||
thread_ = threading.Thread(target=FailProcess.Process, name="FAILED Post-Processing")
|
||||
thread_.start()
|
||||
thread_.join()
|
||||
failchk = queue.get()
|
||||
if failchk[0]['mode'] == 'retry':
|
||||
yield chk[0]['self.log']
|
||||
logger.info('Attempting to return to search module with ' + str(failchk[0]['issueid']))
|
||||
if failchk[0]['annchk'] == 'no': mode = 'want'
|
||||
else: mode = 'want_ann'
|
||||
self.queueit(mode=mode, ComicName=failchk[0]['comicname'], ComicIssue=failchk[0]['issuenumber'], ComicID=failchk[0]['comicid'], IssueID=failchk[0]['issueid'], manualsearch=True)
|
||||
elif failchk[0]['mode'] == 'stop':
|
||||
yield chk[0]['self.log']
|
||||
else:
|
||||
logger.error('mode is unsupported: ' + failchk[0]['mode'])
|
||||
yield chk[0]['self.log']
|
||||
else:
|
||||
logger.warn('Failed Download Handling is not enabled. Leaving Failed Download as-is.')
|
||||
post_process.exposed = True
|
||||
|
||||
def pauseArtist(self, ComicID):
|
||||
|
@ -462,7 +520,7 @@ class WebInterface(object):
|
|||
if ComicID is None:
|
||||
myDB.action('DROP table nzblog')
|
||||
logger.fdebug("Deleted nzblog table.")
|
||||
myDB.action('CREATE TABLE IF NOT EXISTS nzblog (IssueID TEXT, NZBName TEXT, SARC TEXT)')
|
||||
myDB.action('CREATE TABLE IF NOT EXISTS nzblog (IssueID TEXT, NZBName TEXT, SARC TEXT, PROVIDER TEXT, ID TEXT)')
|
||||
logger.fdebug("Re-created nzblog table.")
|
||||
raise cherrypy.HTTPRedirect("history")
|
||||
wipenzblog.exposed = True
|
||||
|
@ -619,13 +677,43 @@ class WebInterface(object):
|
|||
raise cherrypy.HTTPRedirect("comicDetails?ComicID=%s" % ComicID)
|
||||
refreshArtist.exposed=True
|
||||
|
||||
def editIssue(self, ComicID):
|
||||
def issue_edit(self, id, value):
|
||||
print 'here'
|
||||
print 'id: ' + str(id)
|
||||
print 'value: ' + str(value)
|
||||
comicid = id[:id.find('.')]
|
||||
print 'comicid:' + str(comicid)
|
||||
issueid = id[id.find('.')+1:]
|
||||
print 'issueid:' + str(issueid)
|
||||
myDB = db.DBConnection()
|
||||
comic = myDB.selectone('SELECT * from comics WHERE ComicID=?', [ComicID]).fetchone()
|
||||
title = 'Now Editing ' + comic['ComicName']
|
||||
return serve_template(templatename="editcomic.html", title=title, comic=comic)
|
||||
#raise cherrypy.HTTPRedirect("comicDetails?ComicID=%s" & ComicID)
|
||||
editIssue.exposed=True
|
||||
comicchk = myDB.selectone('SELECT ComicYear FROM comics WHERE ComicID=?', [comicid]).fetchone()
|
||||
issuechk = myDB.selectone('SELECT * FROM issues WHERE IssueID=?', [issueid]).fetchone()
|
||||
if issuechk is None:
|
||||
logger.error('Cannot edit this for some reason - something is wrong.')
|
||||
return
|
||||
oldissuedate = issuechk['IssueDate']
|
||||
seriesyear = comicchk['ComicYear']
|
||||
|
||||
#check if the new date is in the correct format of yyyy-mm-dd
|
||||
try:
|
||||
valid_date = time.strptime(value, '%Y-%m-%d')
|
||||
except ValueError:
|
||||
logger.error('invalid date provided. Rejecting edit.')
|
||||
return oldissuedate
|
||||
|
||||
#if the new issue year is less than the series year - reject it.
|
||||
if value[:4] < seriesyear:
|
||||
logger.error('Series year of ' + str(seriesyear) + ' is less than new issue date of ' + str(value[:4]))
|
||||
return oldissuedate
|
||||
|
||||
newVal = {"IssueDate" : value,
|
||||
"IssueDate_Edit" : oldissuedate}
|
||||
ctrlVal = {"IssueID": issueid}
|
||||
myDB.upsert("issues", newVal, ctrlVal)
|
||||
logger.info('updated issueinfo')
|
||||
return value
|
||||
|
||||
issue_edit.exposed=True
|
||||
|
||||
def force_rss(self):
|
||||
logger.info('attempting to run RSS Check Forcibly')
|
||||
|
@ -662,7 +750,7 @@ class WebInterface(object):
|
|||
else:
|
||||
newaction = action
|
||||
for IssueID in args:
|
||||
#print ("issueID: " + str(IssueID) + "... " + str(newaction))
|
||||
print ("issueID: " + str(IssueID) + "... " + str(newaction))
|
||||
if IssueID is None or 'issue_table' in IssueID or 'history_table' in IssueID:
|
||||
continue
|
||||
else:
|
||||
|
@ -686,12 +774,17 @@ class WebInterface(object):
|
|||
issuestoArchive.append(IssueID)
|
||||
elif action == 'Wanted' or action == 'Retry':
|
||||
if action == 'Retry': newaction = 'Wanted'
|
||||
logger.info(u"Marking %s %s as %s" % (mi['ComicName'], mi['Issue_Number'], newaction))
|
||||
logger.info(u"Marking %s %s as %s" % (comicname, mi['Issue_Number'], newaction))
|
||||
issuesToAdd.append(IssueID)
|
||||
elif action == 'Skipped':
|
||||
logger.info(u"Marking " + str(IssueID) + " as Skipped")
|
||||
elif action == 'Clear':
|
||||
myDB.action("DELETE FROM snatched WHERE IssueID=?", [IssueID])
|
||||
elif action == 'Failed' and mylar.FAILED_DOWNLOAD_HANDLING:
|
||||
logger.info('Marking [' + comicname + '] : ' + str(IssueID) + ' as Failed. Sending to failed download handler.')
|
||||
failedcomicid = mi['ComicID']
|
||||
failedissueid = IssueID
|
||||
break
|
||||
controlValueDict = {"IssueID": IssueID}
|
||||
newValueDict = {"Status": newaction}
|
||||
if annchk == 'yes':
|
||||
|
@ -699,6 +792,8 @@ class WebInterface(object):
|
|||
else:
|
||||
myDB.upsert("issues", newValueDict, controlValueDict)
|
||||
logger.fdebug("updated...to " + str(newaction))
|
||||
if action == 'Failed' and mylar.FAILED_DOWNLOAD_HANDLING:
|
||||
self.failed_handling(failedcomicid, failedissueid)
|
||||
if len(issuestoArchive) > 0:
|
||||
updater.forceRescan(mi['ComicID'])
|
||||
if len(issuesToAdd) > 0:
|
||||
|
@ -763,8 +858,8 @@ class WebInterface(object):
|
|||
raise cherrypy.HTTPRedirect("pullist")
|
||||
#return
|
||||
elif mode == 'want' or mode == 'want_ann' or manualsearch:
|
||||
cdname = myDB.selectone("SELECT ComicName from comics where ComicID=?", [ComicID]).fetchone()
|
||||
ComicName = cdname['ComicName']
|
||||
cdname = myDB.selectone("SELECT ComicName, ComicName_Filesafe from comics where ComicID=?", [ComicID]).fetchone()
|
||||
ComicName = cdname['ComicName_Filesafe']
|
||||
controlValueDict = {"IssueID": IssueID}
|
||||
newStatus = {"Status": "Wanted"}
|
||||
if mode == 'want':
|
||||
|
@ -804,7 +899,7 @@ class WebInterface(object):
|
|||
Publisher = miy['ComicPublisher']
|
||||
UseAFuzzy = miy['UseFuzzy']
|
||||
ComicVersion = miy['ComicVersion']
|
||||
foundcom, prov = search.search_init(ComicName, ComicIssue, ComicYear, SeriesYear, Publisher, issues['IssueDate'], storedate, IssueID, AlternateSearch, UseAFuzzy, ComicVersion, mode=mode, ComicID=ComicID, manualsearch=manualsearch)
|
||||
foundcom, prov = search.search_init(ComicName, ComicIssue, ComicYear, SeriesYear, Publisher, issues['IssueDate'], storedate, IssueID, AlternateSearch, UseAFuzzy, ComicVersion, mode=mode, ComicID=ComicID, manualsearch=manualsearch, filesafe=miy['ComicName_Filesafe'])
|
||||
if foundcom == "yes":
|
||||
# file check to see if issue exists and update 'have' count
|
||||
if IssueID is not None:
|
||||
|
@ -819,24 +914,40 @@ class WebInterface(object):
|
|||
raise cherrypy.HTTPRedirect(redirect)
|
||||
queueissue.exposed = True
|
||||
|
||||
def unqueueissue(self, IssueID, ComicID, ComicName=None, Issue=None, FutureID=None):
|
||||
def unqueueissue(self, IssueID, ComicID, ComicName=None, Issue=None, FutureID=None, mode=None, ReleaseComicID=None):
|
||||
myDB = db.DBConnection()
|
||||
if ComicName is None:
|
||||
issue = myDB.selectone('SELECT * FROM issues WHERE IssueID=?', [IssueID]).fetchone()
|
||||
if ReleaseComicID is None: #ReleaseComicID is used for annuals.
|
||||
issue = myDB.selectone('SELECT * FROM issues WHERE IssueID=?', [IssueID]).fetchone()
|
||||
else:
|
||||
issue = None
|
||||
annchk = 'no'
|
||||
if issue is None:
|
||||
if mylar.ANNUALS_ON:
|
||||
issann = myDB.selectone('SELECT * FROM annuals WHERE IssueID=?', [IssueID]).fetchone()
|
||||
comicname = issann['ReleaseComicName']
|
||||
issue = issann['Issue_Number']
|
||||
if ReleaseComicID is None:
|
||||
issann = myDB.selectone('SELECT * FROM annuals WHERE IssueID=?', [IssueID]).fetchone()
|
||||
else:
|
||||
issann = myDB.selectone('SELECT * FROM annuals WHERE IssueID=? AND ReleaseComicID=?', [IssueID, ReleaseComicID]).fetchone()
|
||||
ComicName = issann['ReleaseComicName']
|
||||
IssueNumber = issann['Issue_Number']
|
||||
annchk = 'yes'
|
||||
comicid = issann['ComicID']
|
||||
ComicID = issann['ComicID']
|
||||
ReleaseComicID = issann['ReleaseComicID']
|
||||
else:
|
||||
comicname = issue['ComicName']
|
||||
issue = issue['Issue_Number']
|
||||
logger.info(u"Marking " + comicname + " issue # " + str(issue) + " as Skipped...")
|
||||
ComicName = issue['ComicName']
|
||||
IssueNumber = issue['Issue_Number']
|
||||
|
||||
controlValueDict = {"IssueID": IssueID}
|
||||
newValueDict = {"Status": "Skipped"}
|
||||
if mode == 'failed' and mylar.FAILED_DOWNLOAD_HANDLING:
|
||||
logger.info(u"Marking " + ComicName + " issue # " + str(IssueNumber) + " as Failed...")
|
||||
newValueDict = {"Status": "Failed"}
|
||||
myDB.upsert("failed", newValueDict, controlValueDict)
|
||||
yield cherrypy.HTTPRedirect("comicDetails?ComicID=%s" % ComicID)
|
||||
self.failed_handling(ComicID=ComicID, IssueID=IssueID)
|
||||
else:
|
||||
logger.info(u"Marking " + ComicName + " issue # " + str(IssueNumber) + " as Skipped...")
|
||||
newValueDict = {"Status": "Skipped"}
|
||||
|
||||
if annchk == 'yes':
|
||||
myDB.upsert("annuals", newValueDict, controlValueDict)
|
||||
else:
|
||||
|
@ -868,11 +979,34 @@ class WebInterface(object):
|
|||
|
||||
unqueueissue.exposed = True
|
||||
|
||||
def archiveissue(self, IssueID):
|
||||
def failed_handling(self, ComicID, IssueID):
|
||||
import Queue
|
||||
queue = Queue.Queue()
|
||||
|
||||
FailProcess = Failed.FailedProcessor(issueid=IssueID, comicid=ComicID, queue=queue)
|
||||
thread_ = threading.Thread(target=FailProcess.Process, name="FAILED Post-Processing")
|
||||
thread_.start()
|
||||
thread_.join()
|
||||
failchk = queue.get()
|
||||
if failchk[0]['mode'] == 'retry':
|
||||
logger.info('Attempting to return to search module with ' + str(failchk[0]['issueid']))
|
||||
if failchk[0]['annchk'] == 'no': mode = 'want'
|
||||
else: mode = 'want_ann'
|
||||
self.queueit(mode=mode, ComicName=failchk[0]['comicname'], ComicIssue=failchk[0]['issuenumber'], ComicID=failchk[0]['comicid'], IssueID=failchk[0]['issueid'], manualsearch=True)
|
||||
elif failchk[0]['mode'] == 'stop':
|
||||
pass
|
||||
else:
|
||||
logger.error('mode is unsupported: ' + failchk[0]['mode'])
|
||||
|
||||
failed_handling.exposed = True
|
||||
|
||||
def archiveissue(self, IssueID, comicid):
|
||||
print 'marking issue : ' + str(IssueID)
|
||||
myDB = db.DBConnection()
|
||||
issue = myDB.selectone('SELECT * FROM issues WHERE IssueID=?', [IssueID]).fetchone()
|
||||
annchk = 'no'
|
||||
if issue is None:
|
||||
print 'issue is none'
|
||||
if mylar.ANNUALS_ON:
|
||||
issann = myDB.selectone('SELECT * FROM annuals WHERE IssueID=?', [IssueID]).fetchone()
|
||||
comicname = issann['ReleaseComicName']
|
||||
|
@ -880,9 +1014,11 @@ class WebInterface(object):
|
|||
annchk = 'yes'
|
||||
comicid = issann['ComicID']
|
||||
else:
|
||||
print 'issue not none'
|
||||
comicname = issue['ComicName']
|
||||
print comicname
|
||||
issue = issue['Issue_Number']
|
||||
comicid = issue['ComicID']
|
||||
print issue
|
||||
logger.info(u"Marking " + comicname + " issue # " + str(issue) + " as archived...")
|
||||
controlValueDict = {'IssueID': IssueID}
|
||||
newValueDict = {'Status': 'Archived'}
|
||||
|
@ -1014,12 +1150,14 @@ class WebInterface(object):
|
|||
if chkfuture is not None:
|
||||
logger.info('Already on Future Upcoming list - not adding at this time.')
|
||||
return
|
||||
logger.info('Adding ' + ComicName + ' # ' + str(Issue) + ' to future upcoming watchlist')
|
||||
newCtrl = {"ComicName": ComicName,
|
||||
"IssueNumber": Issue,
|
||||
logger.info('Adding ' + ComicName + ' # ' + str(Issue) + ' [' + Publisher + '] to future upcoming watchlist')
|
||||
newCtrl = {"ComicName": ComicName,
|
||||
"IssueNumber": Issue,
|
||||
"Publisher": Publisher}
|
||||
|
||||
newVal = {"Status": "Wanted",
|
||||
"IssueDate": ShipDate}
|
||||
|
||||
myDB.upsert("futureupcoming", newVal, newCtrl)
|
||||
|
||||
fCtrl = {"FutureID": FutureID}
|
||||
|
@ -1055,18 +1193,24 @@ class WebInterface(object):
|
|||
"IssueNumber": cf['IssueNumber'], #this should be all #1's as the sql above limits the hits.
|
||||
"Publisher": cf['Publisher'],
|
||||
"Status": cf['Status']})
|
||||
|
||||
print 'cflist: ' + str(cflist)
|
||||
#now we load in
|
||||
logger.info('I will be looking to see if any information has been released for ' + str(len(cflist)) + ' series that are NEW series')
|
||||
#limit the search to just the 'current year' since if it's anything but a #1, it should have associated data already.
|
||||
#limittheyear = []
|
||||
#limittheyear.append(cf['IssueDate'][-4:])
|
||||
for ser in cflist:
|
||||
logger.info('looking for new data for ' + ser['ComicName'] + '[#' + str(ser['IssueNumber']) + '] (' + str(ser['IssueDate'][-4:]) + ')')
|
||||
searchresults, explicit = mb.findComic(ser['ComicName'], mode='pullseries', issue=ser['IssueNumber'], limityear=ser['IssueDate'][-4:], explicit='explicit')
|
||||
theissdate = ser['IssueDate'][-4:]
|
||||
if not theissdate.startswith('20'):
|
||||
theissdate = ser['IssueDate'][:4]
|
||||
logger.info('looking for new data for ' + ser['ComicName'] + '[#' + str(ser['IssueNumber']) + '] (' + str(theissdate) + ')')
|
||||
searchresults, explicit = mb.findComic(ser['ComicName'], mode='pullseries', issue=ser['IssueNumber'], limityear=theissdate, explicit='all')
|
||||
print searchresults
|
||||
if len(searchresults) > 1:
|
||||
logger.info('publisher: ' + str(ser['Publisher']))
|
||||
logger.info('More than one result returned - this may have to be a manual add')
|
||||
return serve_template(templatename="searchresults.html", title='New Series Results for: "' + ser['ComicName'] + '"',searchresults=searchresults, type='series', imported='futurecheck', ogcname=ser['ComicName'], name=ser['ComicName'], explicit='all', serinfo=ser) #imported=comicstoIMP, ogcname=ogcname)
|
||||
#call secondary module here to complete the selected add.
|
||||
else:
|
||||
for sr in searchresults:
|
||||
#we should probably load all additional issues for the series on the futureupcoming list that are marked as Wanted and then
|
||||
|
@ -1086,15 +1230,36 @@ class WebInterface(object):
|
|||
|
||||
logger.info('Marking ' + str(len(chkthewanted)) + ' additional issues as Wanted from ' + ser['ComicName'] + ' series as requested')
|
||||
|
||||
chktheadd = importer.addComictoDB(sr['comicid'], "no", chkwant=chkthewanted)
|
||||
if chktheadd != 'Exists':
|
||||
logger.info('Sucessfully imported ' + ser['ComicName'] + ' (' + str(ser['IssueDate'][-4:]) + ')')
|
||||
|
||||
myDB.action('DELETE from futureupcoming WHERE ComicName=?', [ser['ComicName']])
|
||||
logger.info('Removed ' + ser['ComicName'] + ' (' + str(ser['IssueDate'][-4:]) + ') from the future upcoming list as it is now added.')
|
||||
self.future_check_add(sr['comicid'], ser, chkthewanted, theissdate)
|
||||
|
||||
future_check.exposed = True
|
||||
|
||||
def future_check_add(self, comicid, serinfo, chkthewanted=None, theissdate=None):
|
||||
#In order to not error out when adding series with absolutely NO issue data, we need to 'fakeup' some values
|
||||
#latestdate = the 'On sale' date from the futurepull-list OR the Shipping date if not available.
|
||||
#latestiss = the IssueNumber for the first issue (this should always be #1, but might change at some point)
|
||||
ser = serinfo
|
||||
if theissdate is None:
|
||||
theissdate = ser['IssueDate'][-4:]
|
||||
if not theissdate.startswith('20'):
|
||||
theissdate = ser['IssueDate'][:4]
|
||||
|
||||
latestissueinfo = []
|
||||
latestissueinfo.append({"latestdate": ser['IssueDate'],
|
||||
"latestiss": ser['IssueNumber']})
|
||||
logger.fdebug('sending latestissueinfo from future as : ' + str(latestissueinfo))
|
||||
chktheadd = importer.addComictoDB(comicid, "no", chkwant=chkthewanted, latestissueinfo=latestissueinfo, calledfrom="futurecheck")
|
||||
|
||||
if chktheadd != 'Exists':
|
||||
logger.info('Sucessfully imported ' + ser['ComicName'] + ' (' + str(theissdate) + ')')
|
||||
|
||||
myDB = db.DBConnection()
|
||||
myDB.action('DELETE from futureupcoming WHERE ComicName=?', [ser['ComicName']])
|
||||
logger.info('Removed ' + ser['ComicName'] + ' (' + str(theissdate) + ') from the future upcoming list as it is now added.')
|
||||
|
||||
raise cherrypy.HTTPRedirect("home")
|
||||
future_check.exposed = True
|
||||
|
||||
future_check_add.exposed = True
|
||||
|
||||
def filterpull(self):
|
||||
myDB = db.DBConnection()
|
||||
|
@ -1133,46 +1298,65 @@ class WebInterface(object):
|
|||
upcoming = []
|
||||
upcoming_count = 0
|
||||
futureupcoming_count = 0
|
||||
try:
|
||||
pull_date = myDB.selectone("SELECT SHIPDATE from weekly").fetchone()
|
||||
logger.fdebug(u"Weekly pull list present - retrieving pull-list date.")
|
||||
if (pull_date is None):
|
||||
pulldate = '00000000'
|
||||
else:
|
||||
pulldate = pull_date['SHIPDATE']
|
||||
except (sqlite3.OperationalError, TypeError),msg:
|
||||
logger.info(u"Error Retrieving weekly pull list - attempting to adjust")
|
||||
pulldate = '00000000'
|
||||
|
||||
for upc in upcomingdata:
|
||||
|
||||
if len(upc['IssueDate']) <= 7 :
|
||||
#if it's less than or equal 7, then it's a future-pull so let's check the date and display
|
||||
#tmpdate = datetime.datetime.com
|
||||
tmpdatethis = upc['IssueDate']
|
||||
if tmpdatethis[:2] == '20':
|
||||
tmpdate = tmpdatethis #in correct format of yyyymm
|
||||
tmpdate = tmpdatethis + '01' #in correct format of yyyymm
|
||||
else:
|
||||
findst = tmpdatethis.find('-') #find the '-'
|
||||
tmpdate = tmpdatethis[findst+1:] + tmpdatethis[:findst] #rebuild in format of yyyymm
|
||||
timenow = datetime.datetime.now().strftime('%Y%m')
|
||||
#logger.fdebug('comparing pubdate of: ' + str(tmpdate) + ' to now date of: ' + str(timenow))
|
||||
if int(tmpdate) >= int(timenow):
|
||||
if upc['Status'] == 'Wanted':
|
||||
futureupcoming_count +=1
|
||||
futureupcoming.append({"ComicName": upc['ComicName'],
|
||||
"IssueNumber": upc['IssueNumber'],
|
||||
"IssueDate": upc['IssueDate'],
|
||||
"ComicID": upc['ComicID'],
|
||||
"IssueID": upc['IssueID'],
|
||||
"Status": upc['Status'],
|
||||
"DisplayComicName": upc['DisplayComicName']})
|
||||
tmpdate = tmpdatethis[findst+1:] + tmpdatethis[:findst] + '01' #rebuild in format of yyyymm
|
||||
#timenow = datetime.datetime.now().strftime('%Y%m')
|
||||
else:
|
||||
#if it's greater than 7 it's a full date, and shouldn't be displayed ;)
|
||||
timenow = datetime.datetime.now().strftime('%Y%m%d') #convert to yyyymmdd
|
||||
#if it's greater than 7 it's a full date.
|
||||
tmpdate = re.sub("[^0-9]", "", upc['IssueDate']) #convert date to numerics only (should be in yyyymmdd)
|
||||
|
||||
#logger.fdebug('comparing pubdate of: ' + str(tmpdate) + ' to now date of: ' + str(timenow))
|
||||
timenow = datetime.datetime.now().strftime('%Y%m%d') #convert to yyyymmdd
|
||||
#logger.fdebug('comparing pubdate of: ' + str(tmpdate) + ' to now date of: ' + str(timenow))
|
||||
|
||||
pulldate = re.sub("[^0-9]", "", pulldate) #convert pulldate to numerics only (should be in yyyymmdd)
|
||||
|
||||
if int(tmpdate) >= int(timenow) and int(tmpdate) == int(pulldate): #int(pulldate) <= int(timenow):
|
||||
if upc['Status'] == 'Wanted':
|
||||
upcoming_count +=1
|
||||
upcoming.append({"ComicName": upc['ComicName'],
|
||||
"IssueNumber": upc['IssueNumber'],
|
||||
"IssueDate": upc['IssueDate'],
|
||||
"ComicID": upc['ComicID'],
|
||||
"IssueID": upc['IssueID'],
|
||||
"Status": upc['Status'],
|
||||
"DisplayComicName": upc['DisplayComicName']})
|
||||
|
||||
elif int(tmpdate) >= int(timenow):
|
||||
if len(upc['IssueDate']) <= 7:
|
||||
issuedate = tmpdate[:4] + '-' + tmpdate[4:6] + '-00'
|
||||
else:
|
||||
issuedate = upc['IssueDate']
|
||||
if upc['Status'] == 'Wanted':
|
||||
futureupcoming_count +=1
|
||||
futureupcoming.append({"ComicName": upc['ComicName'],
|
||||
"IssueNumber": upc['IssueNumber'],
|
||||
"IssueDate": issuedate,
|
||||
"ComicID": upc['ComicID'],
|
||||
"IssueID": upc['IssueID'],
|
||||
"Status": upc['Status'],
|
||||
"DisplayComicName": upc['DisplayComicName']})
|
||||
|
||||
futureupcoming = sorted(futureupcoming, key=itemgetter('IssueDate','ComicName','IssueNumber'), reverse=True)
|
||||
|
||||
if int(tmpdate) >= int(timenow):
|
||||
if upc['Status'] == 'Wanted':
|
||||
upcoming_count +=1
|
||||
upcoming.append({"ComicName": upc['ComicName'],
|
||||
"IssueNumber": upc['IssueNumber'],
|
||||
"IssueDate": upc['IssueDate'],
|
||||
"ComicID": upc['ComicID'],
|
||||
"IssueID": upc['IssueID'],
|
||||
"Status": upc['Status'],
|
||||
"DisplayComicName": upc['DisplayComicName']})
|
||||
|
||||
issues = myDB.select("SELECT * from issues WHERE Status='Wanted'")
|
||||
isscnt = myDB.select("SELECT COUNT(*) FROM issues WHERE Status='Wanted'")
|
||||
|
@ -1594,9 +1778,11 @@ class WebInterface(object):
|
|||
GCDissue = int(GCDissue) / 1000
|
||||
if '.' not in str(GCDissue): GCDissue = str(GCDissue) + ".00"
|
||||
logger.fdebug("issue converted to " + str(GCDissue))
|
||||
isschk = myDB.selectone("SELECT * FROM issues WHERE ComicName=? AND Issue_Number=? AND ComicID=?", [comic['ComicName'], str(GCDissue), comic['ComicID']]).fetchone()
|
||||
isschk = myDB.selectone("SELECT * FROM issues WHERE Issue_Number=? AND ComicID=?", [str(GCDissue), comic['ComicID']]).fetchone()
|
||||
else:
|
||||
isschk = myDB.selectone("SELECT * FROM issues WHERE ComicName=? AND Issue_Number=? AND ComicID=?", [comic['ComicName'], arc['IssueNumber'], comic['ComicID']]).fetchone()
|
||||
issue_int = helpers.issuedigits(arc['IssueNumber'])
|
||||
logger.info('int_issue = ' + str(issue_int))
|
||||
isschk = myDB.selectone("SELECT * FROM issues WHERE Int_IssueNumber=? AND ComicID=?", [issue_int, comic['ComicID']]).fetchone()
|
||||
if isschk is None:
|
||||
logger.fdebug("we matched on name, but issue " + str(arc['IssueNumber']) + " doesn't exist for " + comic['ComicName'])
|
||||
else:
|
||||
|
@ -1823,7 +2009,7 @@ class WebInterface(object):
|
|||
logger.fdebug("You don't have any issues from " + StoryArcName + ". Aborting Mass Copy.")
|
||||
return
|
||||
else:
|
||||
dst = os.path.join(mylar.CACHE, StoryArcName)
|
||||
dst = os.path.join(mylar.CACHE_DIR, StoryArcName)
|
||||
for files in copylist:
|
||||
|
||||
copyloc = files['Location']
|
||||
|
@ -2218,9 +2404,9 @@ class WebInterface(object):
|
|||
|
||||
mode='series'
|
||||
if yearRANGE is None:
|
||||
sresults, explicit = mb.findComic(displaycomic, mode, issue=numissues, explicit='all') #ComicName, mode, issue=numissues)
|
||||
sresults, explicit = mb.findComic(ogcname, mode, issue=numissues, explicit='all') #ComicName, mode, issue=numissues)
|
||||
else:
|
||||
sresults, explicit = mb.findComic(displaycomic, mode, issue=numissues, limityear=yearRANGE, explicit='all') #ComicName, mode, issue=numissues, limityear=yearRANGE)
|
||||
sresults, explicit = mb.findComic(ogcname, mode, issue=numissues, limityear=yearRANGE, explicit='all') #ComicName, mode, issue=numissues, limityear=yearRANGE)
|
||||
type='comic'
|
||||
|
||||
if len(sresults) == 1:
|
||||
|
@ -2230,7 +2416,7 @@ class WebInterface(object):
|
|||
# #need to move the files here.
|
||||
elif len(sresults) == 0 or len(sresults) is None:
|
||||
implog = implog + "no results, removing the year from the agenda and re-querying.\n"
|
||||
sresults, explicit = mb.findComic(displaycomic, mode, issue=numissues, explicit='all') #ComicName, mode, issue=numissues)
|
||||
sresults, explicit = mb.findComic(ogcname, mode, issue=numissues, explicit='all') #ComicName, mode, issue=numissues)
|
||||
if len(sresults) == 1:
|
||||
sr = sresults[0]
|
||||
implog = implog + "only one result...automagik-mode enabled for " + displaycomic + " :: " + str(sr['comicid']) + "\n"
|
||||
|
@ -2252,7 +2438,7 @@ class WebInterface(object):
|
|||
cresults = self.addComic(comicid=sr['comicid'],comicname=sr['name'],comicyear=sr['comicyear'],comicpublisher=sr['publisher'],comicimage=sr['comicimage'],comicissues=sr['issues'],imported='yes',ogcname=ogcname) #imported=comicstoIMP,ogcname=ogcname)
|
||||
return serve_template(templatename="searchfix.html", title="Error Check", comicname=sr['name'], comicid=sr['comicid'], comicyear=sr['comicyear'], comicimage=sr['comicimage'], comicissues=sr['issues'], cresults=cresults, imported='yes', ogcname=str(ogcname))
|
||||
else:
|
||||
return serve_template(templatename="searchresults.html", title='Import Results for: "' + displaycomic + '"',searchresults=sresults, type=type, imported='yes', ogcname=ogcname, explicit=explicit) #imported=comicstoIMP, ogcname=ogcname)
|
||||
return serve_template(templatename="searchresults.html", title='Import Results for: "' + displaycomic + '"',searchresults=sresults, type=type, imported='yes', ogcname=ogcname, name=ogcname, explicit=explicit) #imported=comicstoIMP, ogcname=ogcname)
|
||||
preSearchit.exposed = True
|
||||
|
||||
def pretty_git(self, br_history):
|
||||
|
@ -2332,6 +2518,9 @@ class WebInterface(object):
|
|||
"launch_browser" : helpers.checked(mylar.LAUNCH_BROWSER),
|
||||
"logverbose" : helpers.checked(mylar.LOGVERBOSE),
|
||||
"max_logsize" : mylar.MAX_LOGSIZE,
|
||||
"annuals_on" : helpers.checked(mylar.ANNUALS_ON),
|
||||
"enable_check_folder" : helpers.checked(mylar.ENABLE_CHECK_FOLDER),
|
||||
"check_folder" : mylar.CHECK_FOLDER,
|
||||
"download_scan_interval" : mylar.DOWNLOAD_SCAN_INTERVAL,
|
||||
"nzb_search_interval" : mylar.SEARCH_INTERVAL,
|
||||
"nzb_startup_search" : helpers.checked(mylar.NZB_STARTUP_SEARCH),
|
||||
|
@ -2389,6 +2578,7 @@ class WebInterface(object):
|
|||
"cbt_passkey" : mylar.CBT_PASSKEY,
|
||||
"snatchedtorrent_notify" : mylar.SNATCHEDTORRENT_NOTIFY,
|
||||
"destination_dir" : mylar.DESTINATION_DIR,
|
||||
"create_folders" : helpers.checked(mylar.CREATE_FOLDERS),
|
||||
"chmod_dir" : mylar.CHMOD_DIR,
|
||||
"chmod_file" : mylar.CHMOD_FILE,
|
||||
"replace_spaces" : helpers.checked(mylar.REPLACE_SPACES),
|
||||
|
@ -2443,6 +2633,8 @@ class WebInterface(object):
|
|||
"ct_tag_cr" : helpers.checked(mylar.CT_TAG_CR),
|
||||
"ct_tag_cbl" : helpers.checked(mylar.CT_TAG_CBL),
|
||||
"ct_cbz_overwrite" : helpers.checked(mylar.CT_CBZ_OVERWRITE),
|
||||
"failed_download_handling" : helpers.checked(mylar.FAILED_DOWNLOAD_HANDLING),
|
||||
"failed_auto" : helpers.checked(mylar.FAILED_AUTO),
|
||||
"branch" : version.MYLAR_VERSION,
|
||||
"br_type" : mylar.INSTALL_TYPE,
|
||||
"br_version" : mylar.versioncheck.getVersion(),
|
||||
|
@ -2491,13 +2683,13 @@ class WebInterface(object):
|
|||
b = urllib.unquote_plus(comicname)
|
||||
cname = b.encode('utf-8')
|
||||
|
||||
print ('comicid to be attached : ' + str(manual_comicid))
|
||||
print ('comicname : ' + str(cname))
|
||||
print ('comicyear : ' + str(comicyear))
|
||||
print ('comicid : ' + str(comicid))
|
||||
logger.fdebug('comicid to be attached : ' + str(manual_comicid))
|
||||
logger.fdebug('comicname : ' + str(cname))
|
||||
logger.fdebug('comicyear : ' + str(comicyear))
|
||||
logger.fdebug('comicid : ' + str(comicid))
|
||||
issueid = manual_comicid
|
||||
logger.fdebug(str(issueid) + ' added to series list as an Annual')
|
||||
threading.Thread(target=importer.manualAnnual, args=[manual_comicid, comicname, comicyear, comicid]).start()
|
||||
logger.fdebug('I will be adding ' + str(issueid) + ' to the Annual list for this series.')
|
||||
threading.Thread(target=importer.manualAnnual, args=[manual_comicid, cname, comicyear, comicid]).start()
|
||||
|
||||
raise cherrypy.HTTPRedirect("comicDetails?ComicID=%s" % comicid)
|
||||
manual_annual_add.exposed = True
|
||||
|
@ -2619,17 +2811,17 @@ class WebInterface(object):
|
|||
readOptions.exposed = True
|
||||
|
||||
|
||||
def configUpdate(self, comicvine_api=None, http_host='0.0.0.0', http_username=None, http_port=8090, http_password=None, api_enabled=0, api_key=None, launch_browser=0, logverbose=0, max_logsize=None, download_scan_interval=None, nzb_search_interval=None, nzb_startup_search=0, libraryscan_interval=None,
|
||||
def configUpdate(self, comicvine_api=None, http_host='0.0.0.0', http_username=None, http_port=8090, http_password=None, api_enabled=0, api_key=None, launch_browser=0, logverbose=0, annuals_on=0, max_logsize=None, download_scan_interval=None, nzb_search_interval=None, nzb_startup_search=0, libraryscan_interval=None,
|
||||
nzb_downloader=0, sab_host=None, sab_username=None, sab_apikey=None, sab_password=None, sab_category=None, sab_priority=None, sab_directory=None, log_dir=None, log_level=0, blackhole_dir=None,
|
||||
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, ct_tag_cr=0, ct_tag_cbl=0, ct_cbz_overwrite=0, enable_rss=0, rss_checkinterval=None, enable_torrent_search=0, enable_kat=0, enable_cbt=0, cbt_passkey=None, snatchedtorrent_notify=0,
|
||||
raw=0, raw_provider=None, raw_username=None, raw_password=None, raw_groups=None, experimental=0, check_folder=None, enable_check_folder=0,
|
||||
enable_meta=0, cmtagger_path=None, ct_tag_cr=0, ct_tag_cbl=0, ct_cbz_overwrite=0, enable_rss=0, rss_checkinterval=None, failed_download_handling=0, failed_auto=0, 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,
|
||||
preferred_quality=0, move_files=0, rename_files=0, add_to_csv=1, cvinfo=0, lowercase_filenames=0, folder_format=None, file_format=None, enable_extra_scripts=0, extra_scripts=None, enable_pre_scripts=0, pre_scripts=None, post_processing=0, syno_fix=0, search_delay=None, chmod_dir=0777, chmod_file=0660, cvapifix=0,
|
||||
tsab=None, destination_dir=None, replace_spaces=0, replace_char=None, use_minsize=0, minsize=None, use_maxsize=0, maxsize=None, autowant_all=0, autowant_upcoming=0, comic_cover_local=0, zero_level=0, zero_level_n=None, interface=None, **kwargs):
|
||||
tsab=None, destination_dir=None, create_folders=1, replace_spaces=0, replace_char=None, use_minsize=0, minsize=None, use_maxsize=0, maxsize=None, autowant_all=0, autowant_upcoming=0, comic_cover_local=0, zero_level=0, zero_level_n=None, interface=None, **kwargs):
|
||||
mylar.COMICVINE_API = comicvine_api
|
||||
mylar.HTTP_HOST = http_host
|
||||
mylar.HTTP_PORT = http_port
|
||||
|
@ -2639,7 +2831,10 @@ class WebInterface(object):
|
|||
mylar.API_KEY = api_key
|
||||
mylar.LAUNCH_BROWSER = launch_browser
|
||||
mylar.LOGVERBOSE = logverbose
|
||||
mylar.ANNUALS_ON = int(annuals_on)
|
||||
mylar.MAX_LOGSIZE = max_logsize
|
||||
mylar.ENABLE_CHECK_FOLDER = enable_check_folder
|
||||
mylar.CHECK_FOLDER = check_folder
|
||||
mylar.DOWNLOAD_SCAN_INTERVAL = download_scan_interval
|
||||
mylar.SEARCH_INTERVAL = nzb_search_interval
|
||||
mylar.NZB_STARTUP_SEARCH = nzb_startup_search
|
||||
|
@ -2739,6 +2934,7 @@ class WebInterface(object):
|
|||
mylar.FOLDER_FORMAT = folder_format
|
||||
mylar.FILE_FORMAT = file_format
|
||||
mylar.DESTINATION_DIR = destination_dir
|
||||
mylar.CREATE_FOLDERS = create_folders
|
||||
mylar.AUTOWANT_ALL = autowant_all
|
||||
mylar.AUTOWANT_UPCOMING = autowant_upcoming
|
||||
mylar.COMIC_COVER_LOCAL = comic_cover_local
|
||||
|
@ -2753,6 +2949,8 @@ class WebInterface(object):
|
|||
mylar.CT_TAG_CR = ct_tag_cr
|
||||
mylar.CT_TAG_CBL = ct_tag_cbl
|
||||
mylar.CT_CBZ_OVERWRITE = ct_cbz_overwrite
|
||||
mylar.FAILED_DOWNLOAD_HANDLING = failed_download_handling
|
||||
mylar.FAILED_AUTO = failed_auto
|
||||
mylar.LOG_DIR = log_dir
|
||||
mylar.LOG_LEVEL = log_level
|
||||
mylar.CHMOD_DIR = chmod_dir
|
||||
|
@ -2983,3 +3181,78 @@ class WebInterface(object):
|
|||
return serve_download(pathfile)
|
||||
|
||||
downloadthis.exposed = True
|
||||
|
||||
def IssueInfo(self, filelocation):
|
||||
issuedetails = helpers.IssueDetails(filelocation)
|
||||
print str(issuedetails)
|
||||
issueinfo = '<table width="500"><tr><td>'
|
||||
issueinfo += '<img style="float: left; padding-right: 10px" src=' + issuedetails[0]['IssueImage'] + ' height="400" width="263">'
|
||||
issueinfo += '<h1><center><b>' + issuedetails[0]['series'] + '</br>[#' + issuedetails[0]['issue_number'] + ']</b></center></h1>'
|
||||
issueinfo += '<center>"' + issuedetails[0]['title'] + '"</center></br>'
|
||||
issueinfo += '</br><p class="alignleft">' + str(issuedetails[0]['pagecount']) + ' pages</p>'
|
||||
if issuedetails[0]['day'] is None:
|
||||
issueinfo += '<p class="alignright">(' + str(issuedetails[0]['year']) + '-' + str(issuedetails[0]['month']) + ')</p></br>'
|
||||
else:
|
||||
issueinfo += '<p class="alignright">(' + str(issuedetails[0]['year']) + '-' + str(issuedetails[0]['month']) + '-' + str(issuedetails[0]['day']) + ')</p></br>'
|
||||
if not issuedetails[0]['writer'] == 'None':
|
||||
issueinfo += 'Writer: ' + issuedetails[0]['writer'] + '</br>'
|
||||
if not issuedetails[0]['penciller'] == 'None':
|
||||
issueinfo += 'Penciller: ' + issuedetails[0]['penciller'] + '</br>'
|
||||
if not issuedetails[0]['inker'] == 'None':
|
||||
issueinfo += 'Inker: ' + issuedetails[0]['inker'] + '</br>'
|
||||
if not issuedetails[0]['colorist'] == 'None':
|
||||
issueinfo += 'Colorist: ' + issuedetails[0]['colorist'] + '</br>'
|
||||
if not issuedetails[0]['letterer'] == 'None':
|
||||
issueinfo += 'Letterer: ' + issuedetails[0]['letterer'] + '</br>'
|
||||
if not issuedetails[0]['editor'] == 'None':
|
||||
issueinfo += 'Editor: ' + issuedetails[0]['editor'] + '</br>'
|
||||
issueinfo += '</td></tr>'
|
||||
#issueinfo += '<img src="interfaces/default/images/rename.png" height="25" width="25"></td></tr>'
|
||||
issueinfo += '<tr><td>Summary: ' + issuedetails[0]['summary'] + '</br></td></tr>'
|
||||
issueinfo += '<tr><td><center>' + os.path.split(filelocation)[1] + '</center>'
|
||||
issueinfo += '</td></tr></table>'
|
||||
return issueinfo
|
||||
#import json
|
||||
#json_dump = json.dumps(issuedetails)
|
||||
#json_dump = json_dump.replace("\\","\\\\")
|
||||
#print 'json_dump:' + str(json_dump)
|
||||
#return json_dump
|
||||
IssueInfo.exposed = True
|
||||
|
||||
def manual_metatag(self, dirName, issueid, filename, comicid):
|
||||
module = '[MANUAL META-TAGGING]'
|
||||
try:
|
||||
import cmtagmylar
|
||||
metaresponse = cmtagmylar.run(dirName, issueid=issueid, filename=filename)
|
||||
except ImportError:
|
||||
logger.warn(module + ' comictaggerlib not found on system. Ensure the ENTIRE lib directory is located within mylar/lib/comictaggerlib/ directory.')
|
||||
metaresponse = "fail"
|
||||
|
||||
if metaresponse == "fail":
|
||||
logger.fdebug(module + ' Unable to write metadata successfully - check mylar.log file.')
|
||||
elif metaresponse == "unrar error":
|
||||
logger.error(module + ' This is a corrupt archive - whether CRC errors or it is incomplete. Marking as BAD, and retrying a different copy.')
|
||||
#launch failed download handling here.
|
||||
else:
|
||||
logger.info(module + ' Sucessfully wrote metadata to .cbz (' + os.path.split(metaresponse)[1] + ') - Continuing..')
|
||||
updater.forceRescan(comicid)
|
||||
manual_metatag.exposed = True
|
||||
|
||||
def group_metatag(self, dirName, ComicID):
|
||||
myDB = db.DBConnection()
|
||||
groupinfo = myDB.select('SELECT * FROM issues WHERE ComicID=? and Location is not NULL', [ComicID])
|
||||
if groupinfo is None:
|
||||
logger.warn('No issues physically exist within the series directory for me to (re)-tag.')
|
||||
return
|
||||
for ginfo in groupinfo:
|
||||
self.manual_metatag(dirName, ginfo['IssueID'], os.path.join(dirName, ginfo['Location']))
|
||||
logger.info('Finished doing a complete series (re)tagging of metadata.')
|
||||
group_metatag.exposed = True
|
||||
|
||||
def CreateFolders(self, createfolders=None):
|
||||
print 'createfolders is ' + str(createfolders)
|
||||
if createfolders:
|
||||
mylar.CREATE_FOLDERS = int(createfolders)
|
||||
mylar.config_write()
|
||||
|
||||
CreateFolders.exposed = True
|
||||
|
|
|
@ -97,10 +97,10 @@ def pullit(forcecheck=None):
|
|||
# this checks for the following lists
|
||||
# first need to only look for checkit variables
|
||||
checkit=['COMICS',
|
||||
'COMIC & GRAPHIC NOVELS',
|
||||
'IDW PUBLISHING',
|
||||
'MAGAZINES',
|
||||
'MERCHANDISE']
|
||||
#'COMIC & GRAPHIC NOVELS',
|
||||
|
||||
#if COMICS is found, determine which publisher
|
||||
checkit2=['DC',
|
||||
|
@ -174,32 +174,41 @@ def pullit(forcecheck=None):
|
|||
mylar.PULLNEW = 'yes'
|
||||
for yesyes in checkit:
|
||||
if yesyes in i:
|
||||
logger.info('yesyes found: ' + yesyes)
|
||||
if format(str(yesyes)) == 'COMICS':
|
||||
logger.info('yesyes = comics: ' + format(str(yesyes)))
|
||||
for chkchk in checkit2:
|
||||
flagged = "no"
|
||||
logger.info('chkchk is : ' + chkchk)
|
||||
if chkchk in i:
|
||||
logger.info('chkchk found in i: ' + chkchk)
|
||||
bl = i.split()
|
||||
blchk = str(bl[0]) + " " + str(bl[1])
|
||||
if chkchk in blchk:
|
||||
pub = format(str(chkchk)) + " COMICS"
|
||||
#print (pub)
|
||||
logger.info("chkchk: " + str(pub))
|
||||
break
|
||||
else:
|
||||
if i.find("COMICS") < 1 and "GRAPHIC NOVELS" in i:
|
||||
logger.info('chkchk not in i - i.findcomics: ' + str(i.find("COMICS")) + ' length: ' + str(len(i.strip())))
|
||||
if all( [i.find("COMICS") < 1, len(i.strip()) == 6 ] ) or ("GRAPHIC NOVELS" in i):
|
||||
# if i.find("COMICS") < 1 and (len(i.strip()) == 6 or "& GRAPHIC NOVELS" in i):
|
||||
pub = "COMICS"
|
||||
#print (pub)
|
||||
logger.info("i.find comics & len =6 : " + pub)
|
||||
break
|
||||
elif i.find("COMICS") > 12:
|
||||
#print ("comics word found in comic title")
|
||||
logger.info("comics word found in comic title")
|
||||
flagged = "yes"
|
||||
break
|
||||
else:
|
||||
if i.find("COMIC") < 1 and "GRAPHIC NOVELS" in i:
|
||||
logger.info('yesyes not found: ' + yesyes + ' i.findcomics: ' + str(i.find("COMICS")) + ' length: ' + str(len(i.strip())))
|
||||
if all( [i.find("COMICS") < 1, len(i.strip()) == 6 ] ) or ("GRAPHIC NOVELS" in i):
|
||||
# if i.find("COMIC") < 1 and (len(i.strip()) == 6 or "& GRAPHIC NOVELS" in i):
|
||||
logger.info("format string not comics & i.find < 1: " + pub)
|
||||
pub = "COMICS"
|
||||
break
|
||||
else:
|
||||
pub = format(str(yesyes))
|
||||
#print (pub)
|
||||
logger.info("format string not comics & i.find > 1: " + pub)
|
||||
break
|
||||
if flagged == "no":
|
||||
break
|
||||
|
@ -231,7 +240,8 @@ def pullit(forcecheck=None):
|
|||
while (n < comicend + 1):
|
||||
comicnm = comicnm + " " + issname[n]
|
||||
n+=1
|
||||
#print ("Comicname: " + str(comicnm) )
|
||||
comcnm = re.sub('1 FOR \$1','', comicnm).strip()
|
||||
logger.info("Comicname: " + str(comicnm) )
|
||||
#get remainder
|
||||
comicrm = issname[comicend +2]
|
||||
if '$' in comicrm:
|
||||
|
@ -242,10 +252,10 @@ def pullit(forcecheck=None):
|
|||
break
|
||||
comicrm = str(comicrm) + " " + str(issname[n])
|
||||
n+=1
|
||||
#print ("Comic Extra info: " + str(comicrm) )
|
||||
#print ("ship: " + str(shipdate))
|
||||
#print ("pub: " + str(pub))
|
||||
#print ("issue: " + str(issue))
|
||||
logger.info("Comic Extra info: " + str(comicrm) )
|
||||
logger.info("ship: " + str(shipdate))
|
||||
logger.info("pub: " + str(pub))
|
||||
logger.info("issue: " + str(issue))
|
||||
#--let's make sure we don't wipe out decimal issues ;)
|
||||
# if '.' in issue:
|
||||
# issue_decimal = re.compile(r'[^\d.]+')
|
||||
|
@ -446,7 +456,7 @@ def pullitcheck(comic1off_name=None,comic1off_id=None,forcecheck=None, futurepul
|
|||
w = 1
|
||||
else:
|
||||
#let's read in the comic.watchlist from the db here
|
||||
cur.execute("SELECT ComicID, ComicName, ComicYear, ComicPublisher, ComicPublished, LatestDate, ForceContinuing, AlternateSearch, LatestIssue from comics")
|
||||
cur.execute("SELECT ComicID, ComicName_Filesafe, ComicYear, ComicPublisher, ComicPublished, LatestDate, ForceContinuing, AlternateSearch, LatestIssue from comics")
|
||||
while True:
|
||||
watchd = cur.fetchone()
|
||||
#print ("watchd: " + str(watchd))
|
||||
|
|
|
@ -22,7 +22,7 @@ class AuthURLOpener(urllib.FancyURLopener):
|
|||
return urllib.FancyURLopener.open(self, url)
|
||||
|
||||
|
||||
def processIssue(dirName, nzbName=None):
|
||||
def processIssue(dirName, nzbName=None, failed=False):
|
||||
|
||||
config = ConfigParser.ConfigParser()
|
||||
configFilename = os.path.join(os.path.dirname(sys.argv[0]), "autoProcessComics.cfg")
|
||||
|
@ -59,6 +59,8 @@ def processIssue(dirName, nzbName=None):
|
|||
params['nzb_folder'] = dirName
|
||||
if nzbName != None:
|
||||
params['nzb_name'] = nzbName
|
||||
|
||||
params['failed'] = failed
|
||||
|
||||
myOpener = AuthURLOpener(username, password)
|
||||
|
||||
|
|
|
@ -26,7 +26,12 @@ if os.environ.has_key('NZBOP_SCRIPTDIR') and not os.environ['NZBOP_VERSION'][0:5
|
|||
POSTPROCESS_NONE=95
|
||||
|
||||
#Start script
|
||||
result = autoProcessComics.processIssue(os.environ['NZBPP_DIRECTORY'], os.environ['NZBPP_NZBNAME'])
|
||||
if os.environ['NZBPP_TOTALSTATUS'] == 'FAILURE' or os.environ['NZBPP_TOTALSTATUS'] == 'WARNING':
|
||||
failit = 1
|
||||
else:
|
||||
failit = 0
|
||||
|
||||
result = autoProcessComics.processIssue(os.environ['NZBPP_DIRECTORY'], os.environ['NZBPP_NZBNAME'], failed=failit)
|
||||
|
||||
|
||||
elif len(sys.argv) == NZBGET_NO_OF_ARGUMENTS:
|
||||
|
|
|
@ -17,6 +17,6 @@ if len(sys.argv) < 2:
|
|||
print "No folder supplied - is this being called from SABnzbd or NZBGet?"
|
||||
sys.exit()
|
||||
elif len(sys.argv) >= 3:
|
||||
sys.exit(autoProcessComics.processIssue(sys.argv[1], sys.argv[3]))
|
||||
sys.exit(autoProcessComics.processIssue(sys.argv[1], sys.argv[3], sys.argv[7])
|
||||
else:
|
||||
sys.exit(autoProcessComics.processIssue(sys.argv[1]))
|
||||
|
|
Loading…
Reference in New Issue