Add lowercase PM to the General Config/Interface/Time style selection.

Change re-factor sbdatetime classes.
Add param "markup" to sbdatetime.sbftime() and sbdatetime.sbfdatetime() that when set True will return time dimensions HTML class wrapped.
Add HTML class wrapping to the dimension parser of fuzzy time.
Change General Config/Interface/Trim zero padding to Trim date and time, now handles 2:00 pm > 2 pm.
Fix trim zero of military time hour to not use 12 hr time.
This commit is contained in:
JackDandy 2014-12-17 18:25:23 +00:00
parent 2523d4a07e
commit c729e6d3a8
8 changed files with 370 additions and 352 deletions

View file

@ -1,10 +1,13 @@
### 0.x.x (2014-12-xx xx:xx:xx UTC) ### 0.x.x (2014-12-xx xx:xx:xx UTC)
* Add network logo's for BBC Canada, Crackle, El Rey Network, SKY Atlantic, and Watch * Add network logos BBC Canada, Crackle, El Rey Network, SKY Atlantic, and Watch
* Change Yahoo! screen network logo * Change Yahoo! screen network logo
* Change added and updated Discovery Network's channel logo's * Add and update Discovery Network's channel logos
* Remove unrequired duplicate network logo's * Add A&E Network International/Scripps Networks International channel logos
* Add Discovery Network International/A&E Network International/Scripps Networks International missing channel logos * Remove non required duplicate network logos
* Add lowercase PM to the General Config/Interface/Time style selection
* Change General Config/Interface/Trim zero padding to Trim date and time, now handles 2:00 pm > 2 pm
* Fix trim zero of military time hour to not use 12 hr time
[develop changelog] [develop changelog]

View file

@ -1375,11 +1375,6 @@ config*.tmpl
padding: 12px 0px; padding: 12px 0px;
} }
#config div.field-pair input {
float: left;
margin-right: 6px;
}
#config .nocheck, #config div #customQuality, .metadataDiv { #config .nocheck, #config div #customQuality, .metadataDiv {
padding-left: 20px; padding-left: 20px;
} }

View file

@ -1358,11 +1358,6 @@ config*.tmpl
padding: 12px 0px; padding: 12px 0px;
} }
#config div.field-pair input {
float: left;
margin-right: 6px;
}
#config .nocheck, #config div #customQuality, .metadataDiv { #config .nocheck, #config div #customQuality, .metadataDiv {
padding-left: 20px; padding-left: 20px;
} }

View file

@ -153,7 +153,7 @@ inc_top.tmpl
/* background: url("../images/bg.png") repeat 0 0 transparent; */ /* background: url("../images/bg.png") repeat 0 0 transparent; */
} }
[class^="icon-"], [class^="icon-"],
[class*=" icon-"] { [class*=" icon-"] {
background-image: url("../images/glyphicons-halflings.png"); background-image: url("../images/glyphicons-halflings.png");
} }
@ -1591,10 +1591,13 @@ config*.tmpl
padding: 12px 0 padding: 12px 0
} }
.stepDiv .component-desc select,
.stepDiv .component-desc input,
#config div.field-pair select, #config div.field-pair select,
#config div.field-pair input { #config div.field-pair input {
margin-right: 6px;
}
.stepDiv .component-desc select,
.stepDiv .component-desc input {
margin-right: 15px; margin-right: 15px;
} }
@ -3153,6 +3156,11 @@ span.token-input-delete-token {
z-index: 0; z-index: 0;
background-image: url(../images/poster-dark.jpg) background-image: url(../images/poster-dark.jpg)
} }
.time-am-pm {
margin-left: 2px;
}
/* ======================================================================= /* =======================================================================
jquery.confirm.css jquery.confirm.css
========================================================================== */ ========================================================================== */

View file

@ -103,9 +103,9 @@
<span class="component-desc"> <span class="component-desc">
<select id="indexer_default" name="indexer_default" class="form-control input-sm"> <select id="indexer_default" name="indexer_default" class="form-control input-sm">
<option value="0" #if $indexer == 0 then 'selected="selected"' else ''#>All Indexers</option> <option value="0" #if $indexer == 0 then 'selected="selected"' else ''#>All Indexers</option>
#for $indexer in $sickbeard.indexerApi().indexers #for $indexer in $sickbeard.indexerApi().indexers
<option value="$indexer" #if $indexer == $sickbeard.INDEXER_DEFAULT then 'selected="selected"' else ''#>$sickbeard.indexerApi().indexers[$indexer]</option> <option value="$indexer" #if $indexer == $sickbeard.INDEXER_DEFAULT then 'selected="selected"' else ''#>$sickbeard.indexerApi().indexers[$indexer]</option>
#end for #end for
</select> </select>
<span>as the default selection when adding new shows</span> <span>as the default selection when adding new shows</span>
</span> </span>
@ -127,7 +127,7 @@
<span class="component-title">Show root directories</span> <span class="component-title">Show root directories</span>
<span class="component-desc"> <span class="component-desc">
<p>where the files of shows are located</p> <p>where the files of shows are located</p>
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_rootDirs.tmpl') #include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_rootDirs.tmpl')
</span> </span>
</label> </label>
</div> </div>
@ -246,10 +246,10 @@
</div> </div>
<div class="field-pair show_if_fuzzy_dating#if True == $sickbeard.FUZZY_DATING then '' else ' metadataDiv'#"> <div class="field-pair show_if_fuzzy_dating#if True == $sickbeard.FUZZY_DATING then '' else ' metadataDiv'#">
<label for="trim_zero"> <label for="trim_zero">
<span class="component-title">Trim zero padding</span> <span class="component-title">Trim date and time</span>
<span class="component-desc"> <span class="component-desc">
<input type="checkbox" name="trim_zero" id="trim_zero" #if True == $sickbeard.TRIM_ZERO then 'checked="checked"' else ''#/> <input type="checkbox" name="trim_zero" id="trim_zero" #if True == $sickbeard.TRIM_ZERO then 'checked="checked"' else ''#/>
<p>remove the leading number "0" shown on hour of day, and date of month</p> <p>display minimalist date and time i.e. <del>02:00</del> = 2:00, <del>02:00pm</del> = 2pm, <del>03 Jan</del> = 3 Jan</p>
</span> </span>
</label> </label>
</div> </div>
@ -259,16 +259,16 @@
<span class="component-title">Date style:</span> <span class="component-title">Date style:</span>
<span class="component-desc"> <span class="component-desc">
<select class="form-control input-sm #if True == $sickbeard.FUZZY_DATING then '' else ' metadataDiv'#" id="date_presets#if True == $sickbeard.FUZZY_DATING then '' else '_na'#" name="date_preset#if True == $sickbeard.FUZZY_DATING then '' else '_na'#"> <select class="form-control input-sm #if True == $sickbeard.FUZZY_DATING then '' else ' metadataDiv'#" id="date_presets#if True == $sickbeard.FUZZY_DATING then '' else '_na'#" name="date_preset#if True == $sickbeard.FUZZY_DATING then '' else '_na'#">
#for $cur_preset in $date_presets: #for $cur_preset in $date_presets:
<option value="$cur_preset" #if $cur_preset == $sickbeard.DATE_PRESET or ("%x" == $sickbeard.DATE_PRESET and "$cur_preset" == '%a, %b %d, %Y') then 'selected="selected"' else ''#>$datetime.datetime($datetime.datetime.now().year, 12, 31, 14, 30, 47).strftime($cur_preset)</option> <option value="$cur_preset" #if $cur_preset == $sickbeard.DATE_PRESET or ("%x" == $sickbeard.DATE_PRESET and "$cur_preset" == '%a, %b %d, %Y') then 'selected="selected"' else ''#>$datetime.datetime($datetime.datetime.now().year, 12, 31, 14, 30, 47).strftime($cur_preset)</option>
#end for #end for
</select> </select>
<select class="form-control input-sm #if True != $sickbeard.FUZZY_DATING then '' else ' metadataDiv'#" id="date_presets#if True != $sickbeard.FUZZY_DATING then '' else '_na'#" name="date_preset#if True != $sickbeard.FUZZY_DATING then '' else '_na'#"> <select class="form-control input-sm #if True != $sickbeard.FUZZY_DATING then '' else ' metadataDiv'#" id="date_presets#if True != $sickbeard.FUZZY_DATING then '' else '_na'#" name="date_preset#if True != $sickbeard.FUZZY_DATING then '' else '_na'#">
<option value="%x" #if "%x" == $sickbeard.DATE_PRESET then 'selected="selected"' else ''#>Use System Default</option> <option value="%x" #if "%x" == $sickbeard.DATE_PRESET then 'selected="selected"' else ''#>Use System Default</option>
#for $cur_preset in $date_presets: #for $cur_preset in $date_presets:
<option value="$cur_preset" #if $cur_preset == $sickbeard.DATE_PRESET then 'selected="selected"' else ''#>$datetime.datetime($datetime.datetime.now().year, 12, 31, 14, 30, 47).strftime($cur_preset)</option> <option value="$cur_preset" #if $cur_preset == $sickbeard.DATE_PRESET then 'selected="selected"' else ''#>$datetime.datetime($datetime.datetime.now().year, 12, 31, 14, 30, 47).strftime($cur_preset)</option>
#end for #end for
</select> </select>
</span> </span>
</label> </label>
@ -279,11 +279,12 @@
<span class="component-title">Time style:</span> <span class="component-title">Time style:</span>
<span class="component-desc"> <span class="component-desc">
<select id="time_presets" name="time_preset" class="form-control input-sm"> <select id="time_presets" name="time_preset" class="form-control input-sm">
#for $cur_preset in $time_presets: #for $cur_preset in $time_presets:
<option value="$cur_preset" #if $cur_preset == $sickbeard.TIME_PRESET_W_SECONDS then 'selected="selected"' else ''#>$sbdatetime.now().sbftime(show_seconds=True,t_preset=$cur_preset)</option> #set $show_seconds = not $sickbeard.FUZZY_DATING
#end for <option value="$cur_preset" #if $cur_preset == $sickbeard.TIME_PRESET_W_SECONDS then 'selected="selected"' else ''#>$sbdatetime.now().sbftime(show_seconds=$show_seconds, t_preset=$cur_preset)</option>
#end for
</select> </select>
<span><b>note:</b> seconds are only shown on the History page</span> <span id="trim_info_seconds"><b>note:</b> seconds are only shown on the History page</span>
</span> </span>
</label> </label>
</div> </div>
@ -450,9 +451,9 @@
<span class="component-title">Branch version:</span> <span class="component-title">Branch version:</span>
<span class="component-desc"> <span class="component-desc">
<select id="branchVersion" class="form-control form-control-inline input-sm pull-left"> <select id="branchVersion" class="form-control form-control-inline input-sm pull-left">
#for $cur_branch in $sickbeard.versionCheckScheduler.action.list_remote_branches(): #for $cur_branch in $sickbeard.versionCheckScheduler.action.list_remote_branches():
<option value="$cur_branch" #if $cur_branch == $sickbeard.BRANCH then 'selected="selected"' else ''#>$cur_branch</option> <option value="$cur_branch" #if $cur_branch == $sickbeard.BRANCH then 'selected="selected"' else ''#>$cur_branch</option>
#end for #end for
</select> </select>
<input class="btn btn-inline" style="margin-left: 6px;" type="button" id="branchCheckout" value="Checkout Branch"> <input class="btn btn-inline" style="margin-left: 6px;" type="button" id="branchCheckout" value="Checkout Branch">
<div class="clear-left"><p>select branch to use (restart required)</p></div> <div class="clear-left"><p>select branch to use (restart required)</p></div>
@ -485,9 +486,9 @@
<span class="component-title">CPU throttling:</span> <span class="component-title">CPU throttling:</span>
<span class="component-desc"> <span class="component-desc">
<select id="cpu_presets" name="cpu_preset" class="form-control input-sm"> <select id="cpu_presets" name="cpu_preset" class="form-control input-sm">
#for $cur_preset in $cpu_presets: #for $cur_preset in $cpu_presets:
<option value="$cur_preset" #if $cur_preset == $sickbeard.CPU_PRESET then 'selected="selected"' else ''#>$cur_preset.capitalize()</option> <option value="$cur_preset" #if $cur_preset == $sickbeard.CPU_PRESET then 'selected="selected"' else ''#>$cur_preset.capitalize()</option>
#end for #end for
</select> </select>
<span>Normal (default). High is lower and Low is higher CPU use</span> <span>Normal (default). High is lower and Low is higher CPU use</span>
</span> </span>

View file

@ -1,85 +1,126 @@
$(document).ready(function(){ $(document).ready(function(){
$('.enabler').each(function(){ var enabler = $('.enabler'),
if (!$(this).prop('checked')) viewIf = $('.viewIf');
$('#content_' + $(this).attr('id')).hide();
});
$('.enabler').click(function(){ enabler.each(function(){
if ($(this).prop('checked')) if (!$(this).prop('checked'))
$('#content_' + $(this).attr('id')).fadeIn('fast', 'linear'); $('#content_' + $(this).attr('id')).hide();
else });
$('#content_' + $(this).attr('id')).fadeOut('fast', 'linear');
});
$('.viewIf').click(function(){ enabler.click(function(){
if ($(this).prop('checked')) { var content_id = $('#content_' + $(this).attr('id'));
$('.hide_if_' + $(this).attr('id')).css('display','none'); if ($(this).prop('checked'))
$('.show_if_' + $(this).attr('id')).fadeIn('fast', 'linear'); content_id.fadeIn('fast', 'linear');
} else { else
$('.show_if_' + $(this).attr('id')).css('display','none'); content_id.fadeOut('fast', 'linear');
$('.hide_if_' + $(this).attr('id')).fadeIn('fast', 'linear'); });
}
});
$('.datePresets').click(function(){ viewIf.each(function(){
var def = $('#date_presets').val() $(($(this).prop('checked') ? '.hide_if_' : '.show_if_') + $(this).attr('id')).hide();
if ($(this).prop('checked') && '%x' == def) { });
def = '%a, %b %d, %Y'
$('#date_use_system_default').html('1')
} else if (!$(this).prop('checked') && '1' == $('#date_use_system_default').html())
def = '%x'
$('#date_presets').attr('name', 'date_preset_old') viewIf.click(function(){
$('#date_presets').attr('id', 'date_presets_old') var if_id = '_if_' + $(this).attr('id');
if ($(this).prop('checked')) {
$('.hide' + if_id).fadeOut('fast', 'linear');
$('.show' + if_id).fadeIn('fast', 'linear');
} else {
$('.show' + if_id).fadeOut('fast', 'linear');
$('.hide' + if_id).fadeIn('fast', 'linear');
}
});
$('#date_presets_na').attr('name', 'date_preset') var ui_update_trim_zero = (function() {
$('#date_presets_na').attr('id', 'date_presets') var secs = ('00' + new Date().getSeconds().toString()).slice(-2),
elSecs = $('#trim_info_seconds'),
elTrimZero = $('#trim_zero');
elTrimZero.each(function() {
var checked = $(this).prop('checked') && $('#fuzzy_dating').prop('checked');
$('#date_presets_old').attr('name', 'date_preset_na') $('#time_presets').find('option').each(function() {
$('#date_presets_old').attr('id', 'date_presets_na') var text = ($(this).text());
$(this).text(checked
? text.replace(/(\b\d+:\d\d):\d+/mg, '$1')
: text.replace(/(\b\d+:\d\d)(?:.\d+)?/mg, '$1:' + secs));
});
});
if (def) if ($('#fuzzy_dating').prop('checked'))
$('#date_presets').val(def) if (elTrimZero.prop('checked'))
}); elSecs.fadeOut('fast', 'linear');
else
elSecs.fadeIn('fast', 'linear');
else
elSecs.fadeIn('fast', 'linear');
});
// bind 'myForm' and provide a simple callback function $('#trim_zero, #fuzzy_dating').click(function() {
$('#configForm').ajaxForm({ ui_update_trim_zero();
beforeSubmit: function(){ });
$('.config_submitter').each(function(){
$(this).attr('disabled', 'disabled');
$(this).after('<span><img src="' + sbRoot + '/images/loading16' + themeSpinner + '.gif"> Saving...</span>');
$(this).hide();
});
},
success: function(){
setTimeout('config_success()', 2000)
}
});
$('#api_key').click(function(){ $('#api_key').select() }); ui_update_trim_zero();
$("#generate_new_apikey").click(function(){
$.get(sbRoot + '/config/general/generateKey',
function(data){
if (data.error != undefined) {
alert(data.error);
return;
}
$('#api_key').val(data);
});
});
$('#branchCheckout').click(function(){ $('.datePresets').click(function(){
url = sbRoot + '/home/branchCheckout?branch=' + $('#branchVersion').val(); var elDatePresets = $('#date_presets'),
window.location.href = url; defaultPreset = elDatePresets.val();
}); if ($(this).prop('checked') && '%x' == defaultPreset) {
defaultPreset = '%a, %b %d, %Y';
$('#date_use_system_default').html('1')
} else if (!$(this).prop('checked') && '1' == $('#date_use_system_default').html())
defaultPreset = '%x';
elDatePresets.attr('name', 'date_preset_old');
elDatePresets.attr('id', 'date_presets_old');
var elDatePresets_na = $('#date_presets_na');
elDatePresets_na.attr('name', 'date_preset');
elDatePresets_na.attr('id', 'date_presets');
var elDatePresets_old = $('#date_presets_old');
elDatePresets_old.attr('name', 'date_preset_na');
elDatePresets_old.attr('id', 'date_presets_na');
if (defaultPreset)
elDatePresets.val(defaultPreset)
});
// bind 'myForm' and provide a simple callback function
$('#configForm').ajaxForm({
beforeSubmit: function(){
$('.config_submitter').each(function(){
$(this).attr('disabled', 'disabled');
$(this).after('<span><img src="' + sbRoot + '/images/loading16' + themeSpinner + '.gif"> Saving...</span>');
$(this).hide();
});
},
success: function(){
setTimeout('config_success()', 2000)
}
});
$('#api_key').click(function(){ $('#api_key').select() });
$("#generate_new_apikey").click(function(){
$.get(sbRoot + '/config/general/generateKey',
function(data){
if (data.error != undefined) {
alert(data.error);
return;
}
$('#api_key').val(data);
});
});
$('#branchCheckout').click(function(){
window.location.href = sbRoot + '/home/branchCheckout?branch=' + $('#branchVersion').val();
});
}); });
function config_success(){ function config_success(){
$('.config_submitter').each(function(){ $('.config_submitter').each(function(){
$(this).removeAttr('disabled'); $(this).removeAttr('disabled');
$(this).next().remove(); $(this).next().remove();
$(this).show(); $(this).show();
}); });
$('#email_show').trigger('notify'); $('#email_show').trigger('notify');
} }

View file

@ -11,152 +11,170 @@
*/ */
function fuzzyMoment(fmConfig) { function fuzzyMoment(fmConfig) {
var containerClass = (/undefined/i.test(typeof(fmConfig)) || /undefined/i.test(typeof(fmConfig.containerClass)) ? '.fuzzydate' : fmConfig.containerClass), var containerClass = (/undefined/i.test(typeof(fmConfig)) || /undefined/i.test(typeof(fmConfig.containerClass)) ? '.fuzzydate' : fmConfig.containerClass),
dateWithTime = (/undefined/i.test(typeof(fmConfig)) || /undefined/i.test(typeof(fmConfig.dateHasTime)) ? false : !!fmConfig.dateHasTime), dateWithTime = (/undefined/i.test(typeof(fmConfig)) || /undefined/i.test(typeof(fmConfig.dateHasTime)) ? false : !!fmConfig.dateHasTime),
dateFormat = (/undefined/i.test(typeof(fmConfig)) || /undefined/i.test(typeof(fmConfig.dateFormat)) ? '' : fmConfig.dateFormat), dateFormat = (/undefined/i.test(typeof(fmConfig)) || /undefined/i.test(typeof(fmConfig.dateFormat)) ? '' : fmConfig.dateFormat),
timeFormat = (/undefined/i.test(typeof(fmConfig)) || /undefined/i.test(typeof(fmConfig.timeFormat)) ? '' : fmConfig.timeFormat), timeFormat = (/undefined/i.test(typeof(fmConfig)) || /undefined/i.test(typeof(fmConfig.timeFormat)) ? '' : fmConfig.timeFormat),
trimZero = (/undefined/i.test(typeof(fmConfig)) || /undefined/i.test(typeof(fmConfig.trimZero)) ? false : !!fmConfig.trimZero), trimZero = (/undefined/i.test(typeof(fmConfig)) || /undefined/i.test(typeof(fmConfig.trimZero)) ? false : !!fmConfig.trimZero),
dtGlue = (/undefined/i.test(typeof(fmConfig)) || /undefined/i.test(typeof(fmConfig.dtGlue)) ? '<br />' : fmConfig.dtGlue), dtGlue = (/undefined/i.test(typeof(fmConfig)) || /undefined/i.test(typeof(fmConfig.dtGlue)) ? '<br />' : fmConfig.dtGlue),
dtInline = (/undefined/i.test(typeof(fmConfig)) || /undefined/i.test(typeof(fmConfig.dtInline)) ? false : fmConfig.dtInline), dtInline = (/undefined/i.test(typeof(fmConfig)) || /undefined/i.test(typeof(fmConfig.dtInline)) ? false : fmConfig.dtInline),
jd = (function (str) { jd = (function (str) {
var token_map = ['a', 'ddd', 'A', 'dddd', 'b', 'MMM', 'B', 'MMMM', 'd', 'DD', 'm', 'MM', 'y', 'YY', 'Y', 'YYYY', 'x', 'L', var token_map = ['a', 'ddd', 'A', 'dddd', 'b', 'MMM', 'B', 'MMMM', 'd', 'DD', 'm', 'MM', 'y', 'YY', 'Y', 'YYYY', 'x', 'L',
'H', 'HH', 'I', 'hh', 'M', 'mm', 'S', 'ss', 'p', 'A'], 'H', 'HH', 'I', 'hh', 'M', 'mm', 'S', 'ss', 'p', 'A', 'P', 'a'],
result = ''; result = '';
for (var i = 0; i < str.length; i++) for (var i = 0; i < str.length; i++)
if (/[aAbBdmyYxHIMSp]/.test(str[i])) { if (/[aAbBdmyYxHIMSpP]/.test(str[i])) {
for (var t = 0; t < token_map.length; t = t + 2) for (var t = 0; t < token_map.length; t = t + 2)
if (str[i] == token_map[t]) { if (str[i] == token_map[t]) {
result += token_map[t + 1]; result += token_map[t + 1];
break; break;
} }
} else if ('%' != str[i]) } else if ('%' != str[i])
result += str[i]; result += str[i];
return result; return result;
}), }),
dateToken = jd(dateFormat), dateTemplate = jd(dateFormat),
timeToken = jd(timeFormat), timeTemplate = jd(timeFormat),
addQTip = (function() { addQTip = (function() {
$(this).css('cursor', 'help'); $(this).css('cursor', 'help');
$(this).qtip({ $(this).qtip({
show: { show: {
solo: true solo: true
}, },
position: { position: {
viewport: $(window), viewport: $(window),
my: 'left center', my: 'left center',
adjust: { adjust: {
y: -10, y: -10,
x: 2 x: 2
} }
}, },
style: { style: {
classes: 'qtip-dark qtip-rounded qtip-shadow' classes: 'qtip-dark qtip-rounded qtip-shadow'
} }
}); });
}); });
if (trimZero) { if (trimZero) {
timeToken = timeToken.replace(/hh/ig, 'h'); timeTemplate = timeTemplate.replace(/hh/g, 'h');
dateToken = dateToken.replace(/\bDD\b/g, 'D'); timeTemplate = timeTemplate.replace(/HH/g, 'H');
} dateTemplate = dateTemplate.replace(/\bDD\b/g, 'D');
}
$(containerClass).each(function() { $(containerClass).each(function() {
var input = $(this).text(), var input = $(this).text(),
dateA = '[<span class="fd">', dateA = '[<span class="fd">',
dtSeparator = ' ', dtSeparator = ' ',
timeA = '</span>]', timeB = '[' + timeA; timeA = '</span>]', timeB = '[' + timeA,
timeToken = timeTemplate;
if (dateWithTime) { if (dateWithTime) {
var timeMeta = input.match(/^.{6,}?([,\s]+)(\d{1,2}).(?:\d{2,2})(?:.(\d{2,2}))?(?:\s([ap]m))?$/im); var timeMeta = input.match(/([,\s]+)(\d{1,2})(?:(.)(\d\d)(?:(.)(\d\d))?)?(?:\s?([ap]m))?$/im);
if (null != timeMeta) { if (null != timeMeta) {
dtSeparator = (! /undefined/i.test(typeof(timeMeta[1])) ? timeMeta[1] : dtSeparator); dtSeparator = (! /undefined/i.test(typeof(timeMeta[1])) ? timeMeta[1] : dtSeparator);
// adjust timeToken to num digits of input hours // adjust timeToken to num digits of input hours
timeToken = (! /undefined/i.test(typeof(timeMeta[2])) && 1 == timeMeta[2].length ? timeToken.replace(/hh/ig, 'h') : timeToken); timeToken = (! /undefined/i.test(typeof(timeMeta[2])) && 1 == timeMeta[2].length ? timeToken.replace(/hh/ig, 'h') : timeToken);
// adjust timeToken to use seconds if input has them // adjust timeToken to remove min if input has one and there is a pm
timeToken = (! /undefined/i.test(typeof(timeMeta[3])) && 2 == timeMeta[3].length ? timeToken : timeToken.replace(/.ss/, '')); timeToken = (trimZero && ! /undefined/i.test(typeof(timeMeta[7]))
// adjust timeToken to am/pm or AM/PM if input has it && (/undefined/i.test(typeof(timeMeta[4]))
timeToken = (! /undefined/i.test(typeof(timeMeta[4])) && 2 == timeMeta[4].length ? timeToken.replace(/A$/, (/[ap]m/.test(timeMeta[4]) ? 'a' : 'A')) : timeToken); || '00' == timeMeta[4]) ? timeToken.replace(/.mm/ig, '') : timeToken);
} // adjust timeToken to use seconds if input has them
timeA = '</span>' + dtGlue + '<span class="ft">]' + timeToken + '[' + timeA; timeToken = (! /undefined/i.test(typeof(timeMeta[5])) && 2 == timeMeta[5].length ? timeToken : timeToken.replace(/.ss/, ''));
timeB = '[</span>' + dtGlue + '<span class="ft">]' + timeToken + timeB; // adjust timeToken to am/pm or AM/PM if input has it
} timeToken = (! /undefined/i.test(typeof(timeMeta[7])) && 2 == timeMeta[7].length ? timeToken.replace(/A$/, (/[ap]m/.test(timeMeta[7]) ? 'a' : 'A')) : timeToken);
}
var inputTokens = dateToken + dtSeparator + (dateWithTime ? timeToken : 'HH:mm:ss'); var token_build = (/h+/i.test(timeToken) ? timeToken.replace(/^(h+).*/i, '[<span class="time-hr">]$1[</span>]') : '');
if (/m+/i.test(timeToken)) {
token_build += (! /undefined/i.test(typeof(timeMeta[3])) ? '[<span class="time-hr-min">]' + timeMeta[3] + '[</span>]' : '')
+ (! /undefined/i.test(typeof(timeMeta[4])) ? timeToken.replace(/.*?(m+).*/i, '[<span class="time-min">]$1[</span>]') : '');
if (/s+/i.test(timeToken)) {
token_build += (! /undefined/i.test(typeof(timeMeta[5])) ? '[<span class="time-min-sec">]' + timeMeta[5] + '[</span>]' : '')
+ (! /undefined/i.test(typeof(timeMeta[6])) ? timeToken.replace(/.*?(s+).*/i, '[<span class="time-sec">]$1[</span>]') : '');
}
}
timeToken = token_build + (! /undefined/i.test(typeof(timeMeta[7])) ? timeToken.replace(/.*?[\s0-9](a).*/i, '[<span class="time-am-pm">]$1[</span>]') : '');
if (! moment(input + (dateWithTime ? '' : dtSeparator + '00:00:00'), inputTokens).isValid()) timeA = '</span>' + dtGlue + '<span class="ft">]' + timeToken + '[' + timeA;
return; timeB = '[</span>' + dtGlue + '<span class="ft">]' + timeToken + timeB;
}
moment.lang('en', { var inputTokens = dateTemplate + dtSeparator + (dateWithTime ? timeToken : 'HH:mm:ss');
calendar: {
lastDay:dateA + 'Yesterday' + timeA, sameDay:dateA + 'Today' + timeA, nextDay:dateA + 'Tomorrow' + timeA,
lastWeek:dateA + 'last] ddd' + timeB, nextWeek:dateA + 'on] ddd' + timeB,
sameElse:dateA + ']ddd, MMM D YYYY[' + timeA
},
relativeTime: {
future:'in %s', past:'%s ago', s:'seconds', m:'a minute', mm:'%d minutes', h:'an hour', hh:'%d hours',
d:'a day', dd:'%d days', M:'a month', MM:'%d months', y:'a year', yy:'%d years'
}
});
var airdatetime = moment(input + (dateWithTime ? '' : dtSeparator + '00:00:00'), inputTokens), if (! moment(input + (dateWithTime ? '' : dtSeparator + '00:00:00'), inputTokens).isValid())
airdate = airdatetime.clone().hour(0).minute(0).second(0).millisecond(0), return;
today = moment({}),
day = Math.abs(airdate.diff(today, 'days')),
week = Math.abs(weekdiff = airdate.diff(today, 'week')), isPast = weekdiff < 0,
titleThis = false, qTipTime = false,
result = (0 == week ? airdatetime.calendar() : '');
if (/\bOn\b/i.test(result)) { moment.lang('en', {
var fuzzer = false, weekday = today.day(); calendar: {
if (3 == weekday) lastDay:dateA + 'Yesterday' + timeA, sameDay:dateA + 'Today' + timeA, nextDay:dateA + 'Tomorrow' + timeA,
fuzzer = (5 <= day); lastWeek:dateA + 'last] ddd' + timeB, nextWeek:dateA + 'on] ddd' + timeB,
else if (4 == weekday || 5 == weekday) sameElse:dateA + ']ddd, MMM D YYYY[' + timeA
fuzzer = (4 <= day); },
else relativeTime: {
fuzzer = (6 == day); future:'in %s', past:'%s ago', s:'seconds', m:'a minute', mm:'%d minutes', h:'an hour', hh:'%d hours',
if (fuzzer) d:'a day', dd:'%d days', M:'a month', MM:'%d months', y:'a year', yy:'%d years'
result = result.replace(/\bOn\b/i, 'Next'); }
});
} else if (! /\b((yester|to)day\b|tomo|last\b)/i.test(result)) { var airdatetime = moment(input + (dateWithTime ? '' : dtSeparator + '00:00:00'), inputTokens),
if (14 > day) airdate = airdatetime.clone().hour(0).minute(0).second(0).millisecond(0),
result = airdate.from(today) + (dateWithTime ? dtGlue + airdatetime.format(timeToken) : ''); today = moment({}),
else if (4 > week) { day = Math.abs(airdate.diff(today, 'days')),
result = (isPast ? '' : 'in ') + (1 == week ? 'a' : week) + ' week' + (1 == week ? '' : 's') + (isPast ? ' ago' : ''); week = Math.abs(weekdiff = airdate.diff(today, 'week')), isPast = weekdiff < 0,
qTipTime = true; titleThis = false, qTipTime = false,
} else { result = (0 == week ? airdatetime.calendar() : '');
result = airdate.from(today);
qTipTime = true;
var month = airdate.diff(today, 'month');
if (1 == parseInt(airdate.year() - today.year()))
result += (dtInline ? ' ' : '<br />') + '(Next Year)';
}
titleThis = true;
}
var n = false; // disable for prod if (/\bOn\b/i.test(result)) {
$(this).html(result); var fuzzer = false, weekday = today.day();
if (dateWithTime && /(yester|to)day/i.test(result)) if (3 == weekday)
$(this).find('.fd').attr('title',(n?'1) ':'') + moment.duration(airdatetime.diff(moment(),'seconds'),'seconds').humanize(true)).each(addQTip); fuzzer = (5 <= day);
else if (dateWithTime) else if (4 == weekday || 5 == weekday)
$(this).find('.fd').attr('title',(n?'2) ':'') + airdate.from(today)).each(addQTip); fuzzer = (4 <= day);
else if (! /today/i.test(result)) else
$(this).find('.fd').attr('title',(n?'3) ':'') + airdate.from(today)).each(addQTip); fuzzer = (6 == day);
else if (fuzzer)
titleThis = false; result = result.replace(/\bOn\b/i, 'Next');
if (titleThis) } else if (! /\b((yester|to)day\b|tomo|last\b)/i.test(result)) {
if (dateWithTime && qTipTime) if (14 > day)
$(this).attr('title',(n?'4) ':'') + airdatetime.format(inputTokens)).each(addQTip); result = airdate.from(today) + (dateWithTime ? dtGlue + airdatetime.format(timeToken) : '');
else else if (4 > week) {
$(this).attr('title',(n?'5) ':'') + airdate.format(dateToken)).each(addQTip); result = (isPast ? '' : 'in ') + (1 == week ? 'a' : week) + ' week' + (1 == week ? '' : 's') + (isPast ? ' ago' : '');
else qTipTime = true;
if (dateWithTime && qTipTime) } else {
$(this).find('.ft').attr('title',(n?'6) ':'') + airdatetime.format(inputTokens)).each(addQTip); result = airdate.from(today);
else qTipTime = true;
$(this).find('.ft').attr('title',(n?'7) ':'') + airdate.format(dateToken)).each(addQTip); var month = airdate.diff(today, 'month');
}); if (1 == parseInt(airdate.year() - today.year()))
result += (dtInline ? ' ' : '<br />') + '(Next Year)';
}
titleThis = true;
}
var n = false; // disable for prod
$(this).html(result);
if (dateWithTime && /(yester|to)day/i.test(result))
$(this).find('.fd').attr('title',(n?'1) ':'') + moment.duration(airdatetime.diff(moment(),'seconds'),'seconds').humanize(true)).each(addQTip);
else if (dateWithTime)
$(this).find('.fd').attr('title',(n?'2) ':'') + airdate.from(today)).each(addQTip);
else if (! /today/i.test(result))
$(this).find('.fd').attr('title',(n?'3) ':'') + airdate.from(today)).each(addQTip);
else
titleThis = false;
if (titleThis)
if (dateWithTime && qTipTime)
$(this).attr('title',(n?'4) ':'') + airdatetime.format(inputTokens)).each(addQTip);
else
$(this).attr('title',(n?'5) ':'') + airdate.format(dateTemplate)).each(addQTip);
else
if (dateWithTime && qTipTime)
$(this).find('.ft').attr('title',(n?'6) ':'') + airdatetime.format(inputTokens)).each(addQTip);
else
$(this).find('.ft').attr('title',(n?'7) ':'') + airdate.format(dateTemplate)).each(addQTip);
});
} }

View file

@ -19,6 +19,7 @@
import datetime import datetime
import locale import locale
import functools import functools
import re
import sickbeard import sickbeard
from sickbeard.network_timezones import sb_timezone from sickbeard.network_timezones import sb_timezone
@ -82,12 +83,12 @@ date_presets = ('%Y-%m-%d',
'%A, %b %d, %Y', '%A, %b %d, %Y',
'%B %d, %Y', '%B %d, %Y',
'%a, %B %d, %Y', '%a, %B %d, %Y',
'%A, %B %d, %Y' '%A, %B %d, %Y')
)
time_presets = ('%I:%M:%S %p', time_presets = ('%I:%M:%S %p',
'%H:%M:%S' '%I:%M:%S %P',
) '%H:%M:%S')
# helper class # helper class
class static_or_instance(object): class static_or_instance(object):
@ -104,142 +105,98 @@ class sbdatetime(datetime.datetime):
@static_or_instance @static_or_instance
def convert_to_setting(self, dt=None): def convert_to_setting(self, dt=None):
obj = (dt, self)[self is not None]
try: try:
if sickbeard.TIMEZONE_DISPLAY == 'local': if 'local' == sickbeard.TIMEZONE_DISPLAY:
if self is None: return obj.astimezone(sb_timezone)
return dt.astimezone(sb_timezone)
else:
return self.astimezone(sb_timezone)
else:
if self is None:
return dt
else:
return self
except: except:
if self is None: pass
return dt
else: return obj
return self
@static_or_instance
def setlocale(self, setlocale=True, use_has_locale=None, locale_str=''):
if setlocale:
try:
if None is use_has_locale or use_has_locale:
locale.setlocale(locale.LC_TIME, locale_str)
except:
if None is not use_has_locale:
sbdatetime.has_locale = False
pass
# display Time in SickGear Format # display Time in SickGear Format
@static_or_instance @static_or_instance
def sbftime(self, dt=None, show_seconds=False, t_preset=None): def sbftime(self, dt=None, show_seconds=False, t_preset=None, setlocale=True, markup=False):
try:locale.setlocale(locale.LC_TIME, '') sbdatetime.setlocale(setlocale=setlocale, use_has_locale=sbdatetime.has_locale, locale_str='us_US')
except:pass
try:
if sbdatetime.has_locale:
locale.setlocale(locale.LC_TIME, 'us_US')
except:
sbdatetime.has_locale = False
strt = '' strt = ''
try: try:
if self is None: obj = (dt, self)[self is not None]
if dt is not None: if None is not obj:
if t_preset is not None: tmpl = (((sickbeard.TIME_PRESET, sickbeard.TIME_PRESET_W_SECONDS)[show_seconds]),
strt = dt.strftime(t_preset) t_preset)[None is not t_preset]
elif show_seconds: tmpl = (tmpl.replace(':%S', ''), tmpl)[show_seconds]
strt = dt.strftime(sickbeard.TIME_PRESET_W_SECONDS)
else:
strt = dt.strftime(sickbeard.TIME_PRESET)
else:
if t_preset is not None:
strt = self.strftime(t_preset)
elif show_seconds:
strt = self.strftime(sickbeard.TIME_PRESET_W_SECONDS)
else:
strt = self.strftime(sickbeard.TIME_PRESET)
finally:
try:
if sbdatetime.has_locale:
locale.setlocale(locale.LC_TIME, '')
except:
sbdatetime.has_locale = False
strt = obj.strftime(tmpl.replace('%P', '%p'))
if sickbeard.TRIM_ZERO:
strt = re.sub(r'^0(\d:\d\d)', r'\1', strt)
if re.search(r'(?im)%p$', tmpl):
if '%p' in tmpl:
strt = strt.upper()
elif '%P' in tmpl:
strt = strt.lower()
if sickbeard.TRIM_ZERO:
strt = re.sub(r'(?im)^(\d+)(?::00)?(\s?[ap]m)', r'\1\2', strt)
if markup:
match = re.search(r'(?im)(\d{1,2})(?:(.)(\d\d)(?:(.)(\d\d))?)?(?:\s?([ap]m))?$', strt)
if match:
strt = ('%s%s%s%s%s%s' % (
('<span class="time-hr">%s</span>' % match.group(1), '')[None is match.group(1)],
('<span class="time-hr-min">%s</span>' % match.group(2), '')[None is match.group(2)],
('<span class="time-min">%s</span>' % match.group(3), '')[None is match.group(3)],
('<span class="time-min-sec">%s</span>' % match.group(4), '')[None is match.group(4)],
('<span class="time-sec">%s</span>' % match.group(5), '')[None is match.group(5)],
('<span class="time-am-pm">%s</span>' % match.group(6), '')[None is match.group(6)]))
finally:
sbdatetime.setlocale(setlocale=setlocale, use_has_locale=sbdatetime.has_locale)
return strt return strt
# display Date in SickGear Format # display Date in SickGear Format
@static_or_instance @static_or_instance
def sbfdate(self, dt=None, d_preset=None): def sbfdate(self, dt=None, d_preset=None, setlocale=True):
try: sbdatetime.setlocale(setlocale=setlocale)
locale.setlocale(locale.LC_TIME, '')
except:
pass
strd = '' strd = ''
try: try:
if self is None: obj = (dt, self)[self is not None]
if dt is not None: if None is not obj:
if d_preset is not None: strd = obj.strftime((sickbeard.DATE_PRESET, d_preset)[None is not d_preset])
strd = dt.strftime(d_preset)
else:
strd = dt.strftime(sickbeard.DATE_PRESET)
else:
if d_preset is not None:
strd = self.strftime(d_preset)
else:
strd = self.strftime(sickbeard.DATE_PRESET)
finally: finally:
sbdatetime.setlocale(setlocale=setlocale)
try:
locale.setlocale(locale.LC_TIME, '')
except:
pass
return strd return strd
# display Datetime in SickGear Format # display Datetime in SickGear Format
@static_or_instance @static_or_instance
def sbfdatetime(self, dt=None, show_seconds=False, d_preset=None, t_preset=None): def sbfdatetime(self, dt=None, show_seconds=False, d_preset=None, t_preset=None, markup=False):
try: sbdatetime.setlocale()
locale.setlocale(locale.LC_TIME, '')
except:
pass
strd = '' strd = ''
obj = (dt, self)[self is not None]
try: try:
if self is None: if None is not obj:
if dt is not None: strd = u'%s, %s' % (obj.strftime((sickbeard.DATE_PRESET, d_preset)[None is not d_preset]),
if d_preset is not None: sbdatetime.sbftime(dt, show_seconds, t_preset, False, markup))
strd = dt.strftime(d_preset)
else:
strd = dt.strftime(sickbeard.DATE_PRESET)
try:
if sbdatetime.has_locale:
locale.setlocale(locale.LC_TIME, 'us_US')
except:
sbdatetime.has_locale = False
if t_preset is not None:
strd += u', ' + dt.strftime(t_preset)
elif show_seconds:
strd += u', ' + dt.strftime(sickbeard.TIME_PRESET_W_SECONDS)
else:
strd += u', ' + dt.strftime(sickbeard.TIME_PRESET)
else:
if d_preset is not None:
strd = self.strftime(d_preset)
else:
strd = self.strftime(sickbeard.DATE_PRESET)
try:
if sbdatetime.has_locale:
locale.setlocale(locale.LC_TIME, 'us_US')
except:
sbdatetime.has_locale = False
if t_preset is not None:
strd += u', ' + self.strftime(t_preset)
elif show_seconds:
strd += u', ' + self.strftime(sickbeard.TIME_PRESET_W_SECONDS)
else:
strd += u', ' + self.strftime(sickbeard.TIME_PRESET)
finally:
try:
if sbdatetime.has_locale:
locale.setlocale(locale.LC_TIME, '')
except:
sbdatetime.has_locale = False
finally:
sbdatetime.setlocale(use_has_locale=sbdatetime.has_locale)
return strd return strd