@ -0,0 +1,17 @@ |
|||
engines: |
|||
eslint: |
|||
enabled: true |
|||
csslint: |
|||
enabled: true |
|||
pep8: |
|||
enabled: true |
|||
ratings: |
|||
paths: |
|||
- "**.py" |
|||
- "**.js" |
|||
- "**.css" |
|||
exclude_paths: |
|||
- lib/**/* |
|||
- tornado/**/* |
|||
- gui/slick/css/lib/**/* |
|||
- gui/slick/js/lib/**/* |
@ -1,7 +1,10 @@ |
|||
Libs with customisations... |
|||
|
|||
/tornado |
|||
/lib/cachecontrol/caches/file_cache.py |
|||
/lib/hachoir_core/config.py |
|||
/lib/pynma/pynma.py |
|||
/lib/requests/packages/urllib3/connectionpool.py |
|||
/lib/requests/packages/urllib3/util/ssl_.py |
|||
/lib/cachecontrol/caches/file_cache.py |
|||
/lib/pynma/pynma.py |
|||
/tornado |
|||
/lib/unrar2/unix.py |
|||
/lib/tvdb/tvdb_api.py |
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 726 B |
After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 752 B |
After Width: | Height: | Size: 860 B |
After Width: | Height: | Size: 583 B |
After Width: | Height: | Size: 557 B |
After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 588 B |
After Width: | Height: | Size: 1002 B |
@ -0,0 +1,265 @@ |
|||
#import sickbeard |
|||
#import datetime |
|||
#import re |
|||
#import urllib |
|||
#from sickbeard.common import * |
|||
#from sickbeard import sbdatetime |
|||
#from sickbeard.helpers import anon_url |
|||
## |
|||
#set global $title='Browse Shows' |
|||
#set global $header='Browse Shows' |
|||
#set global $sbPath='..' |
|||
#set global $topmenu='home' |
|||
## |
|||
#import os.path |
|||
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_top.tmpl') |
|||
|
|||
<script type="text/javascript" src="$sbRoot/js/plotTooltip.js?v=$sbPID"></script> |
|||
|
|||
<script type="text/javascript" charset="utf-8"> |
|||
<!-- |
|||
#raw |
|||
var addQTip = (function(){ |
|||
$(this).css('cursor', 'help'); |
|||
$(this).qtip({ |
|||
show: {solo:true}, |
|||
position: {viewport:$(window), my:'left center', adjust:{y: -10,x: 2 }}, |
|||
style: {tip: {corner:true, method:'polygon'}, classes:'qtip-rounded qtip-bootstrap qtip-shadow ui-tooltip-sb'} |
|||
}); |
|||
}); |
|||
#end raw |
|||
|
|||
\$(document).ready(function(){ |
|||
// initialise combos for dirty page refreshes |
|||
\$('#showsort').val('original'); |
|||
\$('#showsortdirection').val('asc'); |
|||
\$('#showfilter').val('*'); |
|||
|
|||
var \$container = [\$('#container')]; |
|||
jQuery.each(\$container, function (j) { |
|||
this.isotope({ |
|||
itemSelector: '.browse-show', |
|||
sortBy: 'original-order', |
|||
layoutMode: 'masonry', |
|||
masonry: { |
|||
columnWidth: 12, |
|||
isFitWidth: true |
|||
}, |
|||
getSortData: { |
|||
premiered: '[data-premiered] parseInt', |
|||
name: function( itemElem ) { |
|||
var name = \$( itemElem ).attr('data-name') || ''; |
|||
#if not $sickbeard.SORT_ARTICLE: |
|||
name = name.replace(/^(?:(?:A(?!\s+to)n?)|The)\s(\w)/i, '$1'); |
|||
#end if |
|||
return name.toLowerCase(); |
|||
}, |
|||
rating: '[data-rating] parseInt', |
|||
votes: '[data-votes] parseInt', |
|||
} |
|||
}); |
|||
}); |
|||
|
|||
\$('#showsort').on( 'change', function() { |
|||
var sortCriteria; |
|||
switch (this.value) { |
|||
case 'original': |
|||
sortCriteria = 'original-order' |
|||
break; |
|||
case 'rating': |
|||
/* randomise, else the rating_votes can already |
|||
* have sorted leaving this with nothing to do. |
|||
*/ |
|||
\$('#container').isotope({sortBy: 'random'}); |
|||
sortCriteria = 'rating'; |
|||
break; |
|||
case 'rating_votes': |
|||
sortCriteria = ['rating', 'votes']; |
|||
break; |
|||
case 'votes': |
|||
sortCriteria = 'votes'; |
|||
break; |
|||
case 'premiered': |
|||
sortCriteria = 'premiered'; |
|||
break; |
|||
default: |
|||
sortCriteria = 'name' |
|||
break; |
|||
} |
|||
\$('#container').isotope({sortBy: sortCriteria}); |
|||
}); |
|||
|
|||
\$('#showsortdirection').on( 'change', function() { |
|||
\$('#container').isotope({sortAscending: ('asc' == this.value)}); |
|||
}); |
|||
|
|||
\$('#showfilter').on( 'change', function() { |
|||
var filterValue = this.value; |
|||
if (-1 == filterValue.indexOf('trakt')) { |
|||
\$('#container').isotope({ filter: filterValue }); |
|||
} else { |
|||
location = '$sbRoot/home/addShows/' + filterValue; |
|||
} |
|||
}); |
|||
|
|||
#raw |
|||
$('.service, .browse-image').each(addQTip); |
|||
#end raw |
|||
}); |
|||
|
|||
//--> |
|||
</script> |
|||
#if $varExists('header') |
|||
#set $heading = ('header', $header) |
|||
#else |
|||
#set $heading = ('title', $title) |
|||
#end if |
|||
<h1 style="margin-bottom:0" class="grey-text #echo '%s">%s' % $heading#</h1> |
|||
|
|||
#if $all_shows or ($kwargs and $kwargs.get('show_header', None)) |
|||
<div class="pull-right" style="margin-top:-35px"> |
|||
<span>Show:</span> |
|||
<select id="showfilter" class="form-control form-control-inline input-sm"> |
|||
#set $count_all_shows = len($all_shows) |
|||
#set $count_inlibrary = $all_shows_inlibrary |
|||
<option value="*" selected="selected">All<%= ' (%d)' % count_all_shows %></option> |
|||
<option value=".notinlibrary">Not In Library<%= ' (%d)' % (count_all_shows - count_inlibrary) %></option> |
|||
<option value=".inlibrary">In Library<%= ' (%d)' % count_inlibrary %></option> |
|||
#if 'Trakt' == $browse_type |
|||
#set $mode = $kwargs and $kwargs.get('mode', None) |
|||
#set $selected = ' class="selected"' |
|||
<optgroup label="Trakt"> |
|||
<option value="trakt_anticipated"#echo ('', selected)['anticipated' == $mode]#>Anticipating</option> |
|||
<option value="trakt_newseasons"#echo ('', selected)['newseasons' == $mode]#>New Seasons</option> |
|||
<option value="trakt_newshows"#echo ('', selected)['newshows' == $mode]#>New Shows</option> |
|||
<option value="trakt_popular"#echo ('', selected)['popular' == $mode]#>Popular</option> |
|||
<option value="trakt_trending"#echo ('', selected)['trending' == $mode]#>Trending</option> |
|||
</optgroup> |
|||
<optgroup label="Trakt last month"> |
|||
<option value="trakt_watched"#echo ('', selected)['watched' == $mode]#>Most Watched</option> |
|||
<option value="trakt_played"#echo ('', selected)['played' == $mode]#>Most Played</option> |
|||
<option value="trakt_collected"#echo ('', selected)['collected' == $mode]#>Most Collected</option> |
|||
</optgroup> |
|||
<optgroup label="Trakt last 12 months"> |
|||
<option value="trakt_watched?period=year"#echo ('', selected)['watched-year' == $mode]#>Most Watched</option> |
|||
<option value="trakt_played?period=year"#echo ('', selected)['played-year' == $mode]#>Most Played</option> |
|||
<option value="trakt_collected?period=year"#echo ('', selected)['collected-year' == $mode]#>Most Collected</option> |
|||
</optgroup> |
|||
#if any($sickbeard.TRAKT_ACCOUNTS) |
|||
<optgroup label="Trakt recommended"> |
|||
#for $account in $sickbeard.TRAKT_ACCOUNTS |
|||
#if $sickbeard.TRAKT_ACCOUNTS[$account].active and $sickbeard.TRAKT_ACCOUNTS[$account].name |
|||
<option value="trakt_recommended?account=$account"#echo ('', selected)['recommended-%s' % $account == $mode]#>for $sickbeard.TRAKT_ACCOUNTS[$account].name</option> |
|||
#end if |
|||
#end for |
|||
#else |
|||
<optgroup label="To get recommended"> |
|||
<option value="trakt_recommended?action=add">Enable Trakt here</option> |
|||
#end if |
|||
</optgroup> |
|||
#end if |
|||
</select> |
|||
|
|||
<span style="margin-left:12px">Sort By:</span> |
|||
<select id="showsort" class="form-control form-control-inline input-sm"> |
|||
<option value="name">Name</option> |
|||
<option value="original" selected="selected">Original</option> |
|||
<option value="premiered">First aired</option> |
|||
<option value="votes">Votes</option> |
|||
<option value="rating">% Rating</option> |
|||
<option value="rating_votes">% Rating > Votes</option> |
|||
</select> |
|||
|
|||
<span style="margin-left:12px">Sort Order:</span> |
|||
<select id="showsortdirection" class="form-control form-control-inline input-sm"> |
|||
<option value="asc" selected="selected">Asc</option> |
|||
<option value="desc">Desc</option> |
|||
</select> |
|||
</div> |
|||
<h4 style="float:left;margin:0 0 0 2px">$browse_title</h4> |
|||
#if $kwargs and $kwargs.get('oldest', None): |
|||
<div class="grey-text" style="clear:both;margin-left:2px;font-size:0.85em"> |
|||
First aired from $kwargs['oldest'] until $kwargs['newest'] |
|||
</div> |
|||
#end if |
|||
#end if |
|||
|
|||
<div id="container"> |
|||
#if $all_shows |
|||
#for $this_show in $all_shows: |
|||
#set $title_html = $this_show['title'].replace('"', '"').replace("'", ''') |
|||
#if 'newseasons' == $kwargs.get('mode', '') |
|||
#set $overview = '%s: %s' % ( |
|||
('Season %s' % $this_show['episode_season'], 'Brand-new')[1 == $this_show['episode_season']], |
|||
($this_show['overview'], $this_show['episode_overview'])[any($this_show['episode_overview']) and 1 != $this_show['episode_season']]) |
|||
#else |
|||
#set $overview = $this_show['overview'] |
|||
#end if |
|||
|
|||
<div class="browse-show <%= ('notinlibrary', 'inlibrary')[':' in this_show['show_id']] %>" data-name="#echo re.sub(r'([\'\"])', r'', $this_show['title'])#" data-rating="$this_show['rating']" data-votes="$this_show['votes']" data-premiered="$this_show['premiered']"> |
|||
<div class="browse-container"> |
|||
<div class="browse-image"> |
|||
<a class="browse-image" href="<%= anon_url(this_show['url_src_db']) %>" target="_blank" |
|||
title="<span style='color: rgb(66, 139, 202)'>$re.sub(r'(?m)\s+\((?:19|20)\d\d\)\s*$', '', $title_html)</span>#if $this_show['genres']#<br /><div style='font-weight:bold'>(<em>$this_show['genres']</em>)</div>#end if# |
|||
<p style='margin:0 0 2px'>#echo re.sub(r'([,\.!][^,\.!]*?)$', '...', re.sub(r'([!\?\.])(?=\w)', r'\1 ', $overview))#</p> |
|||
<p><span style='font-weight:bold;font-size:0.9em;color:#888'><em>#if $kwargs and 'newseasons' == $kwargs.get('mode', None)#Air#else#First air#end if##echo ('s', 'ed')[$this_show['when_past']]#: $this_show['premiered_str']</em></span></p> |
|||
<span style='float:right'>Click for more at <span class='boldest'>$browse_type</span></span>"> |
|||
#if 'poster' in $this_show['images']: |
|||
#set $image = $this_show['images']['poster']['thumb'] |
|||
<img alt="" class="browse-image" src="#if $image and 'http' != $image[:4]#$sbRoot/#end if#$image" /> |
|||
#else: |
|||
<span> </span> |
|||
#end if |
|||
</a> |
|||
</div> |
|||
|
|||
<div class="show-title"> |
|||
<%= (this_show['title'], '<span> </span>')['' == this_show['title']] %> |
|||
</div> |
|||
|
|||
<div class="clearfix"> |
|||
<p>$this_show['rating']% <img src="$sbRoot/images/heart.png"><i>$this_show['votes'] votes</i></p> |
|||
#if 'url_tvdb' in $this_show and $this_show['url_tvdb']: |
|||
<a class="service" href="<%= anon_url(this_show['url_tvdb']) %>" onclick="window.open(this.href, '_blank'); return false;" |
|||
title="View <span class='boldest'>tvdb</span> detail for <span style='color: rgb(66, 139, 202)'>$title_html</span>"> |
|||
<i><img style="margin-top:5px" alt="tvdb" height="16" width="16" src="$sbRoot/images/$sickbeard.indexerApi($sickbeard.indexers.indexer_config.INDEXER_TVDB).config['icon']" /></i></a> |
|||
#end if |
|||
|
|||
<div class="browse-add-show-holder"> |
|||
#if ':' in $this_show['show_id']: |
|||
<p style="line-height: 1.5; padding: 2px 5px 3px" title="<%= '%s added' % ('TVRage', 'theTVDB')['1' == this_show['show_id'][:1]] %>">In library</p> |
|||
#else |
|||
<a href="$sbRoot/home/addShows/add${browse_type}Show?indexer_id=${this_show['show_id']}&showName=${urllib.quote($this_show['title'].encode("utf-8"))}" class="btn btn-xs">Add Show</a> |
|||
#end if |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
#end for |
|||
</div> |
|||
#if $kwargs and $kwargs.get('footnote', None): |
|||
<div> |
|||
$kwargs['footnote'] |
|||
</div> |
|||
#end if |
|||
#else |
|||
<div class="browse-show" style="width:100%; margin-top:20px"> |
|||
<p class="red-text"> |
|||
#if $kwargs and $kwargs.get('error_msg', None): |
|||
$kwargs['error_msg'] |
|||
#else |
|||
$browse_type API did not return results, this can happen from time to time. |
|||
<br /><br />This view should auto refresh every 10 mins. |
|||
#end if |
|||
</p> |
|||
</div> |
|||
</div> |
|||
#end if |
|||
|
|||
<script type="text/javascript" charset="utf-8"> |
|||
<!-- |
|||
window.setInterval('location.reload(true)', 600000); // Refresh every 10 minutes |
|||
//--> |
|||
</script> |
|||
|
|||
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_bottom.tmpl') |
@ -1,169 +0,0 @@ |
|||
#import sickbeard |
|||
#import datetime |
|||
#import re |
|||
#import urllib |
|||
#from sickbeard.common import * |
|||
#from sickbeard import sbdatetime |
|||
#from sickbeard.helpers import anon_url |
|||
## |
|||
#set global $title='Trending Shows' |
|||
#set global $header='Trending Shows' |
|||
#set global $sbPath='..' |
|||
#set global $topmenu='episodeView' |
|||
## |
|||
#import os.path |
|||
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_top.tmpl') |
|||
|
|||
<script type="text/javascript" src="$sbRoot/js/plotTooltip.js?$sbPID"></script> |
|||
|
|||
<script type="text/javascript" charset="utf-8"> |
|||
<!-- |
|||
|
|||
\$(document).ready(function(){ |
|||
// initialise combos for dirty page refreshes |
|||
\$('#showsort').val('original'); |
|||
\$('#showsortdirection').val('asc'); |
|||
\$('#showfilter').val('*'); |
|||
|
|||
var \$container = [\$('#container')]; |
|||
jQuery.each(\$container, function (j) { |
|||
this.isotope({ |
|||
itemSelector: '.trakt_show', |
|||
sortBy: 'original-order', |
|||
layoutMode: 'fitRows', |
|||
getSortData: { |
|||
name: function( itemElem ) { |
|||
var name = \$( itemElem ).attr('data-name') || ''; |
|||
#if not $sickbeard.SORT_ARTICLE: |
|||
name = name.replace(/^(?:(?:A(?!\s+to)n?)|The)\s(\w)/i, '$1'); |
|||
#end if |
|||
return name.toLowerCase(); |
|||
}, |
|||
rating: '[data-rating] parseInt', |
|||
votes: '[data-votes] parseInt', |
|||
} |
|||
}); |
|||
}); |
|||
|
|||
\$('#showsort').on( 'change', function() { |
|||
var sortCriteria; |
|||
switch (this.value) { |
|||
case 'original': |
|||
sortCriteria = 'original-order' |
|||
break; |
|||
case 'rating': |
|||
/* randomise, else the rating_votes can already |
|||
* have sorted leaving this with nothing to do. |
|||
*/ |
|||
\$('#container').isotope({sortBy: 'random'}); |
|||
sortCriteria = 'rating'; |
|||
break; |
|||
case 'rating_votes': |
|||
sortCriteria = ['rating', 'votes']; |
|||
break; |
|||
case 'votes': |
|||
sortCriteria = 'votes'; |
|||
break; |
|||
default: |
|||
sortCriteria = 'name' |
|||
break; |
|||
} |
|||
\$('#container').isotope({sortBy: sortCriteria}); |
|||
}); |
|||
|
|||
\$('#showsortdirection').on( 'change', function() { |
|||
\$('#container').isotope({sortAscending: ('asc' == this.value)}); |
|||
}); |
|||
|
|||
\$('#showfilter').on( 'change', function() { |
|||
var filterValue = this.value; |
|||
\$('#container').isotope({ filter: filterValue }); |
|||
}); |
|||
}); |
|||
|
|||
//--> |
|||
</script> |
|||
|
|||
#if $varExists('header') |
|||
<h1 class="header">$header</h1> |
|||
#else |
|||
<h1 class="title">$title</h1> |
|||
#end if |
|||
|
|||
#if $trending_shows |
|||
<div class="pull-right" style="margin-top: -40px;"> |
|||
<span>Show:</span> |
|||
<select id="showfilter" class="form-control form-control-inline input-sm"> |
|||
#set $count_trending = len($trending_shows) |
|||
#set $count_inlibrary = $trending_inlibrary |
|||
<option value="*" selected="selected">All<%= ' (%d)' % count_trending %></option> |
|||
<option value=".notinlibrary">Not In Library<%= ' (%d)' % (count_trending - count_inlibrary) %></option> |
|||
<option value=".inlibrary">In Library<%= ' (%d)' % count_inlibrary %></option> |
|||
</select> |
|||
|
|||
<span style="margin-left:12px">Sort By:</span> |
|||
<select id="showsort" class="form-control form-control-inline input-sm"> |
|||
<option value="name">Name</option> |
|||
<option value="original" selected="selected">Original</option> |
|||
<option value="votes">Votes</option> |
|||
<option value="rating">% Rating</option> |
|||
<option value="rating_votes">% Rating > Votes</option> |
|||
</select> |
|||
|
|||
<span style="margin-left:12px">Sort Order:</span> |
|||
<select id="showsortdirection" class="form-control form-control-inline input-sm"> |
|||
<option value="asc" selected="selected">Asc</option> |
|||
<option value="desc">Desc</option> |
|||
</select> |
|||
</div> |
|||
#end if |
|||
|
|||
<div id="container"> |
|||
|
|||
#if None is $trending_shows |
|||
<div class="trakt_show" style="width:100%; margin-top:20px"> |
|||
<p class="red-text">Trakt API did not return results, this can happen from time to time. |
|||
<br /><br />This view should auto refresh every 10 mins.</p> |
|||
</div> |
|||
#else |
|||
#for $cur_show in $trending_shows: |
|||
|
|||
#set $image = re.sub(r'(.*)/original/(.+)$', r'\1/thumb/\2', $cur_show['images']['poster'], 0, re.IGNORECASE | re.MULTILINE) |
|||
|
|||
<div class="trakt_show <%= ('notinlibrary', 'inlibrary')[':' in cur_show['show_id']] %>" data-name="$cur_show['title']" data-rating="$cur_show['ratings']['percentage']" data-votes="$cur_show['ratings']['votes']"> |
|||
<div class="traktContainer"> |
|||
<div class="trakt-image"> |
|||
<a class="trakt-image" href="<%= anon_url('https://trakt.tv', cur_show['url']) %>" target="_blank"><img alt="" class="trakt-image" src="${image}" /></a> |
|||
</div> |
|||
|
|||
<div class="show-title"> |
|||
<%= (cur_show['title'], '<span> </span>')[ '' == cur_show['title']] %> |
|||
</div> |
|||
|
|||
<div class="clearfix"> |
|||
<p>$cur_show['ratings']['percentage']% <img src="$sbRoot/images/heart.png"></p> |
|||
<i>$cur_show['ratings']['votes'] votes</i> |
|||
|
|||
<div class="traktShowTitleIcons"> |
|||
#if ':' in $cur_show['show_id']: |
|||
<p style="line-height: 1.5; padding: 2px 5px 3px" title="<%= '%s added' % ('TVRage', 'theTVDB')['1' == cur_show['show_id'][:1]] %>">In library</p> |
|||
#else |
|||
#set $encoded_show_title = urllib.quote($cur_show['title'].encode("utf-8")) |
|||
<a href="$sbRoot/home/addShows/addTraktShow?indexer_id=${cur_show['show_id']}&showName=${encoded_show_title}" class="btn btn-xs">Add Show</a> |
|||
#end if |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
#end for |
|||
#end if |
|||
</div> |
|||
|
|||
<script type="text/javascript" charset="utf-8"> |
|||
<!-- |
|||
window.setInterval('location.reload(true)', 600000); // Refresh every 10 minutes |
|||
//--> |
|||
</script> |
|||
|
|||
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_bottom.tmpl') |
@ -1,23 +0,0 @@ |
|||
#import sickbeard |
|||
#import datetime |
|||
#from sickbeard.common import * |
|||
## |
|||
#set global $title = 'Manage Torrents' |
|||
#set global $header = 'Manage Torrents' |
|||
#set global $sbPath = '..' |
|||
#set global $topmenu = 'manage' |
|||
## |
|||
#import os.path |
|||
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_top.tmpl') |
|||
|
|||
<script type="text/javascript" src="$sbRoot/js/plotTooltip.js?$sbPID"></script> |
|||
#if $varExists('header') |
|||
<h1 class="header">$header</h1> |
|||
#else |
|||
<h1 class="title">$title</h1> |
|||
#end if |
|||
|
|||
$info_download_station |
|||
<iframe id="extFrame" src="$webui_url" width="100%" height="500" frameBorder="0" style="border: 1px black solid;"></iframe> |
|||
|
|||
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_bottom.tmpl') |
@ -0,0 +1,20 @@ |
|||
#import sickbeard |
|||
## |
|||
#set global $header = 'Changes' |
|||
#set global $title = 'Changes' |
|||
#set global $topmenu = '' |
|||
## |
|||
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_top.tmpl') |
|||
|
|||
<h1 class="header">$header</h1> |
|||
|
|||
<div class="align-left" style="margin:30px 0"> |
|||
<div id="changes"> |
|||
#for $i, $change in $enumerate($changelist)##if 'rel' == $change['type']# |
|||
<div class="release#echo ('', ' old')[bool($i)]#"><span class="ver">$change['ver']</span> <span class="change-date grey-text">$change['date']</span></div> |
|||
#else# <div><span class="btn-text change-$change['type'].lower()">$change['type']</span> <span class="change-text">$change['text']</span></div> |
|||
#end if##end for# |
|||
</div> |
|||
</div> |
|||
|
|||
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_bottom.tmpl') |
@ -1,181 +1,208 @@ |
|||
;(function($) { |
|||
"use strict"; |
|||
|
|||
$.Browser = { |
|||
defaults: { |
|||
title: 'Choose Directory', |
|||
url: sbRoot + '/browser/', |
|||
autocompleteURL: sbRoot + '/browser/complete', |
|||
includeFiles: 0 |
|||
} |
|||
}; |
|||
|
|||
var fileBrowserDialog, currentBrowserPath, currentRequest = null; |
|||
|
|||
function browse(path, endpoint, includeFiles) { |
|||
|
|||
if (currentBrowserPath == path) { |
|||
return; |
|||
} |
|||
|
|||
currentBrowserPath = path; |
|||
|
|||
if (currentRequest) { |
|||
currentRequest.abort(); |
|||
} |
|||
|
|||
fileBrowserDialog.dialog('option', 'dialogClass', 'browserDialog busy'); |
|||
|
|||
currentRequest = $.getJSON(endpoint, { path: path, includeFiles: includeFiles }, function (data) { |
|||
fileBrowserDialog.empty(); |
|||
var first_val = data[0]; |
|||
var i = 0; |
|||
var list, link = null; |
|||
data = $.grep(data, function (value) { |
|||
return i++ != 0; |
|||
}); |
|||
$('<h2>').text(first_val.current_path).appendTo(fileBrowserDialog); |
|||
list = $('<ul>').appendTo(fileBrowserDialog); |
|||
$.each(data, function (i, entry) { |
|||
link = $("<a href='javascript:void(0)' />").click(function () { browse(entry.path, endpoint, includeFiles); }).text(entry.name); |
|||
$('<span class="ui-icon ui-icon-folder-collapsed"></span>').prependTo(link); |
|||
link.hover( |
|||
function () {$("span", this).addClass("ui-icon-folder-open"); }, |
|||
function () {$("span", this).removeClass("ui-icon-folder-open"); } |
|||
); |
|||
link.appendTo(list); |
|||
}); |
|||
$("a", list).wrap('<li class="ui-state-default ui-corner-all">'); |
|||
fileBrowserDialog.dialog('option', 'dialogClass', 'browserDialog'); |
|||
}); |
|||
} |
|||
|
|||
$.fn.nFileBrowser = function (callback, options) { |
|||
options = $.extend({}, $.Browser.defaults, options); |
|||
|
|||
// make a fileBrowserDialog object if one doesn't exist already
|
|||
if (!fileBrowserDialog) { |
|||
|
|||
// set up the jquery dialog
|
|||
fileBrowserDialog = $('<div id="fileBrowserDialog" style="display:hidden"></div>').appendTo('body').dialog({ |
|||
dialogClass: 'browserDialog', |
|||
title: options.title, |
|||
position: ['center', 40], |
|||
minWidth: Math.min($(document).width() - 80, 650), |
|||
height: Math.min($(document).height() - 80, $(window).height() - 80), |
|||
maxHeight: Math.min($(document).height() - 80, $(window).height() - 80), |
|||
maxWidth: $(document).width() - 80, |
|||
modal: true, |
|||
autoOpen: false |
|||
}); |
|||
} |
|||
|
|||
fileBrowserDialog.dialog('option', 'buttons', [ |
|||
{ |
|||
text: "Ok", |
|||
"class": "btn", |
|||
click: function() { |
|||
// store the browsed path to the associated text field
|
|||
callback(currentBrowserPath, options); |
|||
$(this).dialog("close"); |
|||
} |
|||
}, |
|||
{ |
|||
text: "Cancel", |
|||
"class": "btn", |
|||
click: function() { |
|||
$(this).dialog("close"); |
|||
} |
|||
} |
|||
]); |
|||
|
|||
// set up the browser and launch the dialog
|
|||
var initialDir = ''; |
|||
if (options.initialDir) { |
|||
initialDir = options.initialDir; |
|||
} |
|||
|
|||
browse(initialDir, options.url, options.includeFiles); |
|||
fileBrowserDialog.dialog('open'); |
|||
|
|||
return false; |
|||
}; |
|||
|
|||
$.fn.fileBrowser = function (options) { |
|||
options = $.extend({}, $.Browser.defaults, options); |
|||
// text field used for the result
|
|||
options.field = $(this); |
|||
|
|||
if (options.field.autocomplete && options.autocompleteURL) { |
|||
var query = ''; |
|||
options.field.autocomplete({ |
|||
position: { my : "top", at: "bottom", collision: "flipfit" }, |
|||
source: function (request, response) { |
|||
//keep track of user submitted search term
|
|||
query = $.ui.autocomplete.escapeRegex(request.term, options.includeFiles); |
|||
$.ajax({ |
|||
url: options.autocompleteURL, |
|||
data: request, |
|||
dataType: "json", |
|||
success: function (data, item) { |
|||
//implement a startsWith filter for the results
|
|||
var matcher = new RegExp("^" + query, "i"); |
|||
var a = $.grep(data, function (item, index) { |
|||
return matcher.test(item); |
|||
}); |
|||
response(a); |
|||
} |
|||
}); |
|||
}, |
|||
open: function (event, ui) { |
|||
$(".ui-autocomplete li.ui-menu-item a").removeClass("ui-corner-all"); |
|||
$(".ui-autocomplete li.ui-menu-item:odd a").addClass("ui-menu-item-alternate"); |
|||
} |
|||
}) |
|||
.data("ui-autocomplete")._renderItem = function (ul, item) { |
|||
//highlight the matched search term from the item -- note that this is global and will match anywhere
|
|||
var result_item = item.label; |
|||
var x = new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + query + ")(?![^<>]*>)(?![^&;]+;)", "gi"); |
|||
result_item = result_item.replace(x, function (FullMatch, n) { |
|||
return '<b>' + FullMatch + '</b>'; |
|||
}); |
|||
return $("<li></li>") |
|||
.data("ui-autocomplete-item", item) |
|||
.append("<a class='nowrap'>" + result_item + "</a>") |
|||
.appendTo(ul); |
|||
}; |
|||
} |
|||
|
|||
var initialDir, path, callback, ls = false; |
|||
// if the text field is empty and we're given a key then populate it with the last browsed value from localStorage
|
|||
try { ls = !!(localStorage.getItem); } catch (e) {} |
|||
if (ls && options.key) { |
|||
path = localStorage['fileBrowser-' + options.key]; |
|||
} |
|||
if (options.key && options.field.val().length == 0 && (path)) { |
|||
options.field.val(path); |
|||
} |
|||
|
|||
callback = function (path, options) { |
|||
// store the browsed path to the associated text field
|
|||
options.field.val(path); |
|||
|
|||
// use a localStorage to remember for next time -- no ie6/7
|
|||
if (ls && options.key) { |
|||
localStorage['fileBrowser-' + options.key] = path; |
|||
} |
|||
|
|||
}; |
|||
|
|||
initialDir = options.field.val() || (options.key && path) || ''; |
|||
|
|||
options = $.extend(options, {initialDir: initialDir}); |
|||
|
|||
// append the browse button and give it a click behaviour
|
|||
return options.field.addClass('fileBrowserField').after($('<input type="button" value="Browse…" class="btn btn-inline fileBrowser" />').click(function () { |
|||
$(this).nFileBrowser(callback, options); |
|||
return false; |
|||
})); |
|||
}; |
|||
'use strict'; |
|||
|
|||
$.Browser = { |
|||
defaults: { |
|||
title: 'Choose Directory (or enter manually)', |
|||
url: sbRoot + '/browser/', |
|||
autocompleteURL: sbRoot + '/browser/complete', |
|||
includeFiles: 0, |
|||
showBrowseButton: !0 |
|||
} |
|||
}; |
|||
|
|||
var fileBrowserDialog, currentBrowserPath, currentRequest = null; |
|||
|
|||
function browse(path, endpoint, includeFiles) { |
|||
|
|||
if (path === currentBrowserPath) { |
|||
return; |
|||
} |
|||
|
|||
currentBrowserPath = path; |
|||
|
|||
if (currentRequest) { |
|||
currentRequest.abort(); |
|||
} |
|||
|
|||
fileBrowserDialog.dialog('option', 'dialogClass', 'browserDialog busy'); |
|||
|
|||
currentRequest = $.getJSON(endpoint, {path: path, includeFiles: includeFiles}, function(data){ |
|||
fileBrowserDialog.empty(); |
|||
var firstVal = data[0], i = 0, list, link = null; |
|||
data = $.grep(data, function(){ |
|||
return i++ != 0; |
|||
}); |
|||
$('<input type="text" class="form-control input-sm">') |
|||
.val(firstVal.currentPath) |
|||
.on('keypress', function(e){ |
|||
if (13 === e.which) { |
|||
browse(e.target.value, endpoint, includeFiles); |
|||
} |
|||
}) |
|||
.appendTo(fileBrowserDialog) |
|||
.fileBrowser({showBrowseButton: !1}) |
|||
.on('autocompleteselect', |
|||
function(e, ui){browse(ui.item.value, endpoint, includeFiles); |
|||
}); |
|||
|
|||
list = $('<ul>').appendTo(fileBrowserDialog); |
|||
$.each(data, function(i, entry){ |
|||
link = $('<a href="javascript:void(0)">').on('click', |
|||
function(){ |
|||
if (entry.isFile) { |
|||
currentBrowserPath = entry.path; |
|||
$('.browserDialog .ui-button:contains("Ok")').click(); |
|||
} else { |
|||
browse(entry.path, endpoint, includeFiles); |
|||
} |
|||
}).text(entry.name); |
|||
|
|||
if (entry.isFile) { |
|||
link.prepend('<span class="ui-icon ui-icon-blank"></span>'); |
|||
} else { |
|||
link.prepend('<span class="ui-icon ui-icon-folder-collapsed"></span>') |
|||
.on('mouseenter', function(){$('span', this).addClass('ui-icon-folder-open');}) |
|||
.on('mouseleave', function(){$('span', this).removeClass('ui-icon-folder-open');}); |
|||
} |
|||
link.appendTo(list); |
|||
}); |
|||
$('a', list).wrap('<li class="ui-state-default ui-corner-all">'); |
|||
fileBrowserDialog.dialog('option', 'dialogClass', 'browserDialog'); |
|||
}); |
|||
} |
|||
|
|||
$.fn.nFileBrowser = function(callback, options){ |
|||
options = $.extend({}, $.Browser.defaults, options); |
|||
|
|||
// make a fileBrowserDialog object if one doesn't exist already
|
|||
if (fileBrowserDialog) { |
|||
fileBrowserDialog.dialog('option', 'title', options.title); |
|||
} else { |
|||
// set up the jquery dialog
|
|||
var docWidth = $(document).width(), dlgWidth = Math.min(docWidth - 80, 650), |
|||
docHeight = $(document).height() - 80, winHeight = $(window).height() - 80; |
|||
fileBrowserDialog = $('<div id="fileBrowserDialog" style="display:none"></div>').appendTo('body').dialog({ |
|||
dialogClass: 'browserDialog', |
|||
title: options.title, |
|||
position: [(docWidth - dlgWidth)/2, 60], |
|||
minWidth: dlgWidth, |
|||
height: Math.min(docHeight, winHeight), |
|||
maxHeight: Math.min(docHeight, winHeight), |
|||
maxWidth: docWidth - 80, |
|||
modal: true, |
|||
autoOpen: false |
|||
}); |
|||
} |
|||
|
|||
fileBrowserDialog.dialog('option', 'buttons', |
|||
[{ |
|||
text: 'Ok', |
|||
'class': 'btn', |
|||
click: function(){ |
|||
// store the browsed path to the associated text field
|
|||
callback(currentBrowserPath, options); |
|||
$(this).dialog('close'); |
|||
} |
|||
}, |
|||
{ |
|||
text: 'Cancel', |
|||
'class': 'btn', |
|||
click: function(){ |
|||
$(this).dialog('close'); |
|||
} |
|||
}]); |
|||
|
|||
// set up the browser and launch the dialog
|
|||
var initialDir = ''; |
|||
if (options.initialDir) { |
|||
initialDir = options.initialDir; |
|||
} |
|||
|
|||
browse(initialDir, options.url, options.includeFiles); |
|||
fileBrowserDialog.dialog('open'); |
|||
|
|||
return false; |
|||
}; |
|||
|
|||
$.fn.fileBrowser = function(options){ |
|||
options = $.extend({}, $.Browser.defaults, options); |
|||
// text field used for the result
|
|||
options.field = $(this); |
|||
|
|||
if (options.field.autocomplete && options.autocompleteURL) { |
|||
var query = ''; |
|||
options.field.autocomplete({ |
|||
position: {my: 'top', at: 'bottom', collision: 'flipfit'}, |
|||
source: function(request, response){ |
|||
//keep track of user submitted search term
|
|||
query = $.ui.autocomplete.escapeRegex(request.term, options.includeFiles); |
|||
$.ajax({ |
|||
url: options.autocompleteURL, |
|||
data: request, |
|||
dataType: 'json', |
|||
success: function(data){ |
|||
//implement a startsWith filter for the results
|
|||
var matcher = new RegExp('^' + query, 'i'); |
|||
var a = $.grep(data, function(item){ |
|||
return matcher.test(item); |
|||
}); |
|||
response(a); |
|||
} |
|||
}); |
|||
}, |
|||
open: function(){ |
|||
$('.ui-autocomplete li.ui-menu-item a').removeClass('ui-corner-all'); |
|||
$('.ui-autocomplete li.ui-menu-item:odd a').addClass('ui-menu-item-alternate'); |
|||
} |
|||
}).data('ui-autocomplete')._renderItem = function(ul, item){ |
|||
//highlight the matched search term from the item -- note that this is global and will match anywhere
|
|||
var resultItem = item.label; |
|||
var x = new RegExp('(?![^&;]+;)(?!<[^<>]*)(' + query + ')(?![^<>]*>)(?![^&;]+;)', 'gi'); |
|||
resultItem = resultItem.replace(x, function(fullMatch){ |
|||
return '<b>' + fullMatch + '</b>'; |
|||
}); |
|||
return $('<li></li>') |
|||
.data('ui-autocomplete-item', item) |
|||
.append('<a class="nowrap">' + resultItem + '</a>') |
|||
.appendTo(ul); |
|||
}; |
|||
} |
|||
|
|||
var path, callback, ls = false; |
|||
// if empty text field and given a key then populate it with the last browsed value from localStorage
|
|||
try { ls = !!(localStorage.getItem); } catch (e) {} |
|||
if (ls && options.key) { |
|||
path = localStorage['fileBrowser-' + options.key]; |
|||
} |
|||
if (options.key && options.field.val().length == 0 && (path)) { |
|||
options.field.val(path); |
|||
} |
|||
|
|||
callback = function(path, options){ |
|||
// store the browsed path to the associated text field
|
|||
options.field.val(path); |
|||
|
|||
// use a localStorage to remember for next time -- no ie6/7
|
|||
if (ls && options.key) { |
|||
localStorage['fileBrowser-' + options.key] = path; |
|||
} |
|||
}; |
|||
|
|||
|
|||
options.field.addClass('fileBrowserField'); |
|||
if (options.showBrowseButton) { |
|||
// append the browse button and give it a click behaviour
|
|||
options.field.after( |
|||
$('<input type="button" value="Browse…" class="btn btn-inline fileBrowser">').on('click', |
|||
function(){ |
|||
$(this).nFileBrowser(callback, $.extend( |
|||
{}, options, {initialDir: options.field.val() || (options.key && path) || ''} |
|||
)); |
|||
return false; |
|||
})); |
|||
} |
|||
return options.field; |
|||
}; |
|||
|
|||
})(jQuery); |
|||
|
@ -0,0 +1,106 @@ |
|||
/*globals $, config, sbRoot, generate_bwlist*/ |
|||
|
|||
$(document).ready(function () { |
|||
|
|||
$.getJSON(sbRoot + '/home/addShows/getIndexerLanguages', {}, function (data) { |
|||
var resultStr, flag, selected, current_lang_added = ''; |
|||
|
|||
if (data.results.length === 0) { |
|||
flag = ' class="flag" style="background-image:url(' + sbRoot + '/images/flags/' + config.show_lang + '.png)"'; |
|||
resultStr = '<option value="' + config.show_lang + '" selected="selected"' + flag + '>' + config.show_lang + '</option>'; |
|||
} else { |
|||
current_lang_added = false; |
|||
$.each(data.results, function (index, obj) { |
|||
|
|||
if (obj === config.show_lang) { |
|||
selected = ' selected="selected"'; |
|||
current_lang_added = true; |
|||
} |
|||
else { |
|||
selected = ''; |
|||
} |
|||
|
|||
flag = ' class="flag" style="background-image:url(' + sbRoot + '/images/flags/' + obj + '.png);"'; |
|||
resultStr += '<option value="' + obj + '"' + selected + flag + '>' + obj + '</option>'; |
|||
}); |
|||
|
|||
if (!current_lang_added) { |
|||
resultStr += '<option value=" ' + config.show_lang + '" selected="selected"> ' + config.show_lang + '</option>'; |
|||
} |
|||
|
|||
} |
|||
$('#indexerLangSelectEdit').html(resultStr); |
|||
|
|||
}); |
|||
|
|||
|
|||
var all_exceptions = []; |
|||
|
|||
$('#location').fileBrowser({title: 'Select Show Location'}); |
|||
|
|||
$('#submit').click(function () { |
|||
all_exceptions = []; |
|||
|
|||
$('#exceptions_list').find('option').each (function () { |
|||
all_exceptions.push($(this).val()); |
|||
}); |
|||
|
|||
$('#exceptions_list').val(all_exceptions); |
|||
if (config.show_isanime) { |
|||
generate_bwlist(); |
|||
} |
|||
}); |
|||
|
|||
$('#addSceneName').click(function () { |
|||
var scene_ex = $('#SceneName').val(); |
|||
var scene_ex_season = $('#SceneNameSeason').val(); |
|||
var option = $('<option>'); |
|||
all_exceptions = []; |
|||
|
|||
$('#exceptions_list').find('option').each (function () { |
|||
all_exceptions.push($(this).val()); |
|||
}); |
|||
|
|||
$('#SceneName').val(''); |
|||
$('#SceneNameSeason').val(''); |
|||
|
|||
if ($.inArray(scene_ex_season + '|' + scene_ex, all_exceptions) > -1 || (scene_ex === '')) { |
|||
return; |
|||
} |
|||
$('#SceneException').show(); |
|||
|
|||
option.attr('value', scene_ex_season + '|' + scene_ex); |
|||
if (scene_ex_season === "-1") { |
|||
option.html('S*: ' + scene_ex); |
|||
} |
|||
else { |
|||
option.html('S' + scene_ex_season + ': ' + scene_ex); |
|||
} |
|||
return option.appendTo('#exceptions_list'); |
|||
}); |
|||
|
|||
$('#removeSceneName').click(function () { |
|||
$('#exceptions_list').find('option:selected').remove(); |
|||
|
|||
$(this).toggle_SceneException(); |
|||
}); |
|||
|
|||
$.fn.toggle_SceneException = function () { |
|||
all_exceptions = []; |
|||
|
|||
$('#exceptions_list').find('option').each (function () { |
|||
all_exceptions.push($(this).val()); |
|||
}); |
|||
|
|||
if ('' === all_exceptions) { |
|||
$('#SceneException').hide(); |
|||
} |
|||
else { |
|||
$('#SceneException').show(); |
|||
} |
|||
}; |
|||
|
|||
$(this).toggle_SceneException(); |
|||
|
|||
|
|||
}); |
@ -0,0 +1,141 @@ |
|||
$.tablesorter.addParser({ |
|||
id: 'loadingNames', |
|||
is: function (s) { |
|||
return false; |
|||
}, |
|||
format: function (s) { |
|||
if (s.indexOf('Loading...') === 0) { |
|||
return s.replace('Loading...', '000'); |
|||
} else if (config.sortArticle) { |
|||
return (s || ''); |
|||
} else { |
|||
return (s || '').replace(/^(?:(?:A(?!\s+to)n?)|The)\s(\w)/i, '$1'); |
|||
} |
|||
}, |
|||
type: 'text' |
|||
}); |
|||
|
|||
$.tablesorter.addParser({ |
|||
id: 'quality', |
|||
is: function (s) { |
|||
return false; |
|||
}, |
|||
format: function (s) { |
|||
return s.replace('hd1080p', 5).replace('hd720p', 4).replace('hd', 3).replace('sd', 2).replace('any', 1).replace('custom', 7); |
|||
}, |
|||
type: 'numeric' |
|||
}); |
|||
|
|||
$(document).ready(function () { |
|||
if (config.homeSearchFocus) { |
|||
$('#search_show_name').focus(); |
|||
} |
|||
|
|||
if (config.fuzzyDating) { |
|||
fuzzyMoment({ |
|||
dtInline: config.isPoster, |
|||
containerClass: config.fuzzydate, |
|||
dateHasTime: !1, |
|||
dateFormat: config.datePreset, |
|||
timeFormat: config.timePreset, |
|||
trimZero: config.trimZero |
|||
}); |
|||
} |
|||
|
|||
$('div[id^="progressbar"]').each(function (k, v) { |
|||
var progress = parseInt($(this).siblings('span[class="sort-data"]').attr('data-progress'), 10), elId = '#' + $(this).attr('id'), v = 80; |
|||
$(elId).progressbar({value: progress}); |
|||
if (progress < 80) { |
|||
v = progress >= 40 ? 60 : (progress >= 20 ? 40 : 20); |
|||
} |
|||
$(elId + ' > .ui-progressbar-value').addClass('progress-' + v); |
|||
}); |
|||
|
|||
$('img#network').on('error', function () { |
|||
$(this).parent().text($(this).attr('alt')); |
|||
$(this).remove(); |
|||
}); |
|||
|
|||
if (config.isPoster) { |
|||
$('.container').each(function (i, obj) { |
|||
$(obj).isotope({ |
|||
itemSelector: '.show', |
|||
sortBy: config.posterSortby, |
|||
sortAscending: config.posterSortdir, |
|||
layoutMode: 'masonry', |
|||
masonry: { |
|||
columnWidth: 12, |
|||
isFitWidth: true |
|||
}, |
|||
getSortData: { |
|||
name: function (itemElem) { |
|||
var name = $(itemElem).attr('data-name'); |
|||
if (config.sortArticle) { |
|||
return (name || ''); |
|||
} else { |
|||
return (name || '').replace(/^(?:(?:A(?!\s+to)n?)|The)\s(\w)/i, '$1'); |
|||
} |
|||
}, |
|||
date: function (itemElem) { |
|||
var date = $(itemElem).attr('data-date'); |
|||
return date.length && parseInt(date, 10) || Number.POSITIVE_INFINITY; |
|||
}, |
|||
network: '[data-network]', |
|||
progress: function (itemElem) { |
|||
var progress = $(itemElem).children('.sort-data').attr('data-progress'); |
|||
return progress.length && parseInt(progress, 10) || Number.NEGATIVE_INFINITY; |
|||
} |
|||
} |
|||
}); |
|||
|
|||
$('#postersort').on('change', function () { |
|||
var sortValue = this.value; |
|||
$(obj).isotope({sortBy: sortValue}); |
|||
$.get(this.options[this.selectedIndex].getAttribute('data-sort')); |
|||
}); |
|||
|
|||
$('#postersortdirection').on('change', function () { |
|||
var sortDirection = this.value; |
|||
sortDirection = sortDirection == 'true'; |
|||
$(obj).isotope({sortAscending: sortDirection}); |
|||
$.get(this.options[this.selectedIndex].getAttribute('data-sort')); |
|||
}); |
|||
}); |
|||
} else { |
|||
$('.tablesorter').each(function (i, obj) { |
|||
$(obj).has('tbody tr').tablesorter({ |
|||
sortList: [[5, 1], [1, 0]], |
|||
textExtraction: { |
|||
0: function (node) { |
|||
return $(node).find('span').text().toLowerCase(); |
|||
}, |
|||
2: function (node) { |
|||
return $(node).find('span').text().toLowerCase(); |
|||
}, |
|||
3: function (node) { |
|||
return $(node).find('span').text().toLowerCase(); |
|||
}, |
|||
4: function (node) { |
|||
return $(node).find('span').attr('data-progress'); |
|||
}, |
|||
5: function (node) { |
|||
return $(node).find('i').attr('alt'); |
|||
} |
|||
}, |
|||
widgets: ['saveSort', 'zebra', 'stickyHeaders', 'filter'], |
|||
headers: { |
|||
0: {sorter: 'isoDate'}, |
|||
1: {sorter: 'loadingNames'}, |
|||
3: {sorter: 'quality'}, |
|||
4: {sorter: 'eps'} |
|||
}, |
|||
widgetOptions: { |
|||
filter_columnFilters: false, |
|||
filter_reset: '.resetshows' |
|||
}, |
|||
sortStable: true |
|||
}); |
|||
$.tablesorter.filter.bindSearch($(obj), $('.search')); |
|||
}); |
|||
} |
|||
}); |
@ -0,0 +1,40 @@ |
|||
function initActions() { |
|||
$('#SubMenu a[href*="/home/restart/"]').addClass('btn restart').html('<i class="sgicon-restart"></i>Restart'); |
|||
$('#SubMenu a[href*="/home/shutdown/"]').addClass('btn shutdown').html('<i class="sgicon-shutdown"></i>Shutdown'); |
|||
$('#SubMenu a[href*="/home/logout/"]').addClass('btn').html('<i class="sgicon-logout"></i>Logout'); |
|||
$('#SubMenu a:contains("Edit")').addClass('btn').html('<i class="sgicon-edit"></i>Edit'); |
|||
$('#SubMenu a:contains("Remove")').addClass('btn remove').html('<i class="sgicon-delete"></i>Remove'); |
|||
$('#SubMenu a:contains("Clear History")').addClass('btn clearhistory').html('<i class="sgicon-delete"></i>Clear History'); |
|||
$('#SubMenu a:contains("Trim History")').addClass('btn trimhistory').html('<i class="sgicon-trim"></i>Trim History'); |
|||
$('#SubMenu a[href$="/errorlogs/clearerrors/"]').addClass('btn').html('<i class="sgicon-delete"></i>Clear Errors'); |
|||
$('#SubMenu a:contains("Re-scan")').addClass('btn').html('<i class="sgicon-refresh"></i>Re-scan'); |
|||
$('#SubMenu a:contains("Backlog Overview")').addClass('btn').html('<i class="sgicon-backlog"></i>Backlog Overview'); |
|||
$('#SubMenu a[href$="/home/updatePLEX/"]').addClass('btn').html('<i class="sgicon-plex"></i>Update PLEX'); |
|||
$('#SubMenu a:contains("Force")').addClass('btn').html('<i class="sgicon-fullupdate"></i>Force Full Update'); |
|||
$('#SubMenu a:contains("Rename")').addClass('btn').html('<i class="sgicon-rename"></i>Media Renamer'); |
|||
$('#SubMenu a[href$="/config/subtitles/"]').addClass('btn').html('<i class="sgicon-subtitles"></i>Search Subtitles'); |
|||
$('#SubMenu a[href*="/home/subtitleShow"]').addClass('btn').html('<i class="sgicon-subtitles"></i>Download Subtitles'); |
|||
$('#SubMenu a:contains("Anime")').addClass('btn').html('<i class="sgicon-anime"></i>Anime'); |
|||
$('#SubMenu a:contains("Settings")').addClass('btn').html('<i class="sgicon-search"></i>Search Settings'); |
|||
$('#SubMenu a:contains("Provider")').addClass('btn').html('<i class="sgicon-search"></i>Search Providers'); |
|||
$('#SubMenu a:contains("General")').addClass('btn').html('<i class="sgicon-config"></i>General'); |
|||
$('#SubMenu a:contains("Episode Status")').addClass('btn').html('<i class="sgicon-episodestatus"></i>Episode Status Management'); |
|||
$('#SubMenu a:contains("Missed Subtitle")').addClass('btn').html('<i class="sgicon-subtitles"></i>Missed Subtitles'); |
|||
$('#SubMenu a[href$="/home/addShows/"]').addClass('btn').html('<i class="sgicon-addshow"></i>Add Show'); |
|||
$('#SubMenu a:contains("Processing")').addClass('btn').html('<i class="sgicon-postprocess"></i>Post-Processing'); |
|||
$('#SubMenu a:contains("Manage Searches")').addClass('btn').html('<i class="sgicon-search"></i>Manage Searches'); |
|||
$('#SubMenu a:contains("Manage Torrents")').addClass('btn').html('<i class="sgicon-bittorrent"></i>Manage Torrents'); |
|||
$('#SubMenu a:contains("Show Queue Overview")').addClass('btn').html('<i class="sgicon-showqueue"></i>Show Queue Overview'); |
|||
$('#SubMenu a[href$="/manage/failedDownloads/"]').addClass('btn').html('<i class="sgicon-failed"></i>Failed Downloads'); |
|||
$('#SubMenu a:contains("Notification")').addClass('btn').html('<i class="sgicon-notification"></i>Notifications'); |
|||
$('#SubMenu a:contains("Update show in XBMC")').addClass('btn').html('<i class="sgicon-xbmc"></i>Update show in XBMC'); |
|||
$('#SubMenu a[href$="/home/updateXBMC/"]').addClass('btn').html('<i class="sgicon-xbmc"></i>Update XBMC'); |
|||
$('#SubMenu a:contains("Update show in Kodi")').addClass('btn').html('<i class="sgicon-kodi"></i>Update show in Kodi'); |
|||
$('#SubMenu a[href$="/home/updateKODI/"]').addClass('btn').html('<i class="sgicon-kodi"></i>Update Kodi'); |
|||
} |
|||
|
|||
$(document).ready(function(){ |
|||
initActions(); |
|||
$('#NAV' + topmenu).addClass('active'); |
|||
$('.dropdown-toggle').dropdownHover(); |
|||
}); |
@ -1,211 +0,0 @@ |
|||
$(document).ready(function (){ |
|||
|
|||
function getRecommendedShows(){ |
|||
|
|||
$('#searchResults').empty().html('<img id="searchingAnim"' |
|||
+ ' src="' + sbRoot + '/images/loading32' + themeSpinner + '.gif"' |
|||
+ ' height="32" width="32" />' |
|||
+ ' fetching recommendations...'); |
|||
|
|||
$.getJSON(sbRoot + '/home/addShows/getRecommendedShows', |
|||
{}, |
|||
function (data){ |
|||
var resultStr = '', checked = '', rowType, row = 0; |
|||
|
|||
if (null === data || 0 === data.results.length){ |
|||
resultStr += '<p>Sorry, no recommended shows found, this can happen from time to time.</p>' |
|||
+ '<p>However, if the issue persists, then try updating your watched shows list on trakt.tv</p>'; |
|||
} else { |
|||
|
|||
$.each(data.results, function (index, obj){ |
|||
checked = (0 == row ? ' checked' : ''); |
|||
rowType = (0 == row % 2 ? '' : ' class="alt"'); |
|||
row++; |
|||
|
|||
var whichSeries = obj[6] + '|' + obj[0] + '|' + obj[1] + '|' + obj[2] + '|' + obj[3], |
|||
showstartdate = ''; |
|||
|
|||
if (null !== obj[3]){ |
|||
var startDate = new Date(obj[3]); |
|||
var today = new Date(); |
|||
showstartdate = ' <span class="stepone-result-date">(' |
|||
+ (startDate > today ? 'will debut' : 'started') |
|||
+ ' on ' + obj[3] + ')</span>'; |
|||
} |
|||
|
|||
resultStr += '<div' + rowType + '>' |
|||
+ '<input id="whichSeries" type="radio"' |
|||
+ ' class="stepone-result-radio"' |
|||
+ ' style="float:left;margin-top:4px"' |
|||
+ ' title="Add show <span style=\'color: rgb(66, 139, 202)\'>' + obj[1] + '</span>"' |
|||
+ ' name="whichSeries"' |
|||
+ ' value="' + whichSeries + '"' |
|||
+ checked |
|||
+ ' />' |
|||
+ '<div style="margin-left:20px">' |
|||
+ '<a' |
|||
+ ' class="stepone-result-title"' |
|||
+ ' style="margin-left:5px"' |
|||
+ ' title="View <span class=\'boldest\'>Trakt</span> detail for <span style=\'color: rgb(66, 139, 202)\'>' + obj[1] + '</span>"' |
|||
+ ' href="' + anonURL + obj[0] + '"' |
|||
+ ' onclick="window.open(this.href, \'_blank\'); return false;"' |
|||
+ '>' + obj[1] + '</a>' |
|||
+ showstartdate |
|||
+ (null == obj[6] ? '' |
|||
: ' ' |
|||
+ '<span class="stepone-result-db grey-text">' |
|||
+ '<a class="service" href="' + anonURL + obj[7] + '"' |
|||
+ ' onclick="window.open(this.href, \'_blank\'); return false;"' |
|||
+ ' title="View <span class=\'boldest\'>' + obj[4] + '</span> detail for <span style=\'color: rgb(66, 139, 202)\'>' + obj[1] + '</span>"' |
|||
+ '>' |
|||
+ '<img alt="' + obj[4] + '" height="16" width="16" src="' + sbRoot + '/images/' + obj[5] + '" />' |
|||
+ '' |
|||
+ '</a>' |
|||
+ '</span>' |
|||
) |
|||
+ (null == obj[10] ? '' |
|||
: ' ' |
|||
+ '<span class="stepone-result-db grey-text">' |
|||
+ '<a class="service" href="' + anonURL + obj[11] + '"' |
|||
+ ' onclick="window.open(this.href, \'_blank\'); return false;"' |
|||
+ ' title="View <span class=\'boldest\'>' + obj[8] + '</span> detail for <span style=\'color: rgb(66, 139, 202)\'>' + obj[1] + '</span>"' |
|||
+ '>' |
|||
+ '<img alt="' + obj[8] + '" height="16" width="16" src="' + sbRoot + '/images/' + obj[9] + '" />' |
|||
+ '' |
|||
+ '</a>' |
|||
+ '</span>' |
|||
) |
|||
+ (null == obj[2] ? '' |
|||
: ' <div class="stepone-result-overview grey-text">' + obj[2] + '</div>') |
|||
+ '</div></div>'; |
|||
}); |
|||
} |
|||
|
|||
$('#searchResults').html( |
|||
'<fieldset>' + "\n" + '<legend class="legendStep" style="margin-bottom: 15px">' |
|||
+ (0 < row ? row : 'No') |
|||
+ ' recommended result' + (1 == row ? '' : 's') + '...</legend>' + "\n" |
|||
+ resultStr |
|||
+ '</fieldset>' |
|||
); |
|||
updateSampleText(); |
|||
myform.loadsection(0); |
|||
$('.stepone-result-radio, .stepone-result-title, .service').each(addQTip); |
|||
} |
|||
); |
|||
} |
|||
|
|||
$('#addShowButton').click(function () { |
|||
// if they haven't picked a show don't let them submit
|
|||
if (!$('input:radio[name="whichSeries"]:checked').val() |
|||
&& !$('input:hidden[name="whichSeries"]').val().length) { |
|||
alert('You must choose a show to continue'); |
|||
return false; |
|||
} |
|||
$('#addShowForm').submit(); |
|||
}); |
|||
|
|||
$('#qualityPreset').change(function (){ |
|||
myform.loadsection(2); |
|||
}); |
|||
|
|||
var myform = new FormToWizard({ |
|||
fieldsetborderwidth: 0, |
|||
formid: 'addShowForm', |
|||
revealfx: ['slide', 500], |
|||
oninit: function (){ |
|||
getRecommendedShows(); |
|||
updateSampleText(); |
|||
} |
|||
}); |
|||
|
|||
function goToStep(num){ |
|||
$('.step').each(function (){ |
|||
if ($.data(this, 'section') + 1 == num){ |
|||
$(this).click(); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
function updateSampleText(){ |
|||
// if something's selected then we have some behavior to figure out
|
|||
|
|||
var elRadio = $('input:radio[name="whichSeries"]:checked'), |
|||
elFullShowPath = $('#fullShowPath'), |
|||
sep_char = '', |
|||
root_dirs = $('#rootDirs'), |
|||
// if they've picked a radio button then use that
|
|||
show_name = (elRadio.length ? elRadio.val().split('|')[2] : ''), |
|||
sample_text = '<p>Adding show <span class="show-name">' + show_name + '</span>' |
|||
+ ('' == show_name ? 'into<br />' : '<br />into') |
|||
+ ' <span class="show-dest">'; |
|||
|
|||
// if we have a root dir selected, figure out the path
|
|||
if (root_dirs.find('option:selected').length){ |
|||
var root_dir_text = root_dirs.find('option:selected').val(); |
|||
if (0 <= root_dir_text.indexOf('/')){ |
|||
sep_char = '/'; |
|||
} else if (0 <= root_dir_text.indexOf('\\')){ |
|||
sep_char = '\\'; |
|||
} |
|||
|
|||
root_dir_text += (sep_char != root_dir_text.substr(sample_text.length - 1) |
|||
? sep_char : '') |
|||
+ '<i>||</i>' + sep_char; |
|||
|
|||
sample_text += root_dir_text; |
|||
} else if (elFullShowPath.length && elFullShowPath.val().length){ |
|||
sample_text += elFullShowPath.val(); |
|||
} else { |
|||
sample_text += 'unknown dir.'; |
|||
} |
|||
|
|||
sample_text += '</span></p>'; |
|||
|
|||
// if we have a show name then sanitize and use it for the dir name
|
|||
if (show_name.length){ |
|||
$.get(sbRoot + '/home/addShows/sanitizeFileName', {name: show_name}, function (data){ |
|||
$('#displayText').html(sample_text.replace('||', data)); |
|||
}); |
|||
// if not then it's unknown
|
|||
} else { |
|||
$('#displayText').html(sample_text.replace('||', '??')); |
|||
} |
|||
|
|||
// also toggle the add show button
|
|||
$('#addShowButton').attr('disabled', |
|||
((root_dirs.find('option:selected').length |
|||
|| (elFullShowPath.length && elFullShowPath.val().length)) |
|||
&& elRadio.length |
|||
? false : true)); |
|||
} |
|||
|
|||
var addQTip = (function(){ |
|||
$(this).css('cursor', 'help'); |
|||
$(this).qtip({ |
|||
show: { |
|||
solo: true |
|||
}, |
|||
position: { |
|||
viewport: $(window), |
|||
my: 'left center', |
|||
adjust: { |
|||
y: -10, |
|||
x: 2 |
|||
} |
|||
}, |
|||
style: { |
|||
tip: { |
|||
corner: true, |
|||
method: 'polygon' |
|||
}, |
|||
classes: 'qtip-rounded qtip-bootstrap qtip-shadow ui-tooltip-sb' |
|||
} |
|||
}); |
|||
}); |
|||
|
|||
$('#rootDirText').change(updateSampleText); |
|||
|
|||
$('#searchResults').on('click', '.stepone-result-radio', updateSampleText); |
|||
|
|||
}); |
@ -0,0 +1,98 @@ |
|||
#!/bin/sh |
|||
# |
|||
# PROVIDE: sickgear |
|||
# REQUIRE: LOGIN |
|||
# KEYWORD: shutdown |
|||
# |
|||
# Add the following lines to /etc/rc.conf.local or /etc/rc.conf |
|||
# to enable this service: |
|||
# |
|||
# sickgear_enable (bool): Set to NO by default. |
|||
# Set it to YES to enable it. |
|||
# sickgear_user: The user account SickGear daemon runs as what |
|||
# you want it to be. It uses '_sabnzbd' user by |
|||
# default. Do not sets it as empty or it will run |
|||
# as root. |
|||
# sickgear_dir: Directory where SickGear lives. |
|||
# Default: /usr/local/sickgear |
|||
# sickgear_chdir: Change to this directory before running SickGear. |
|||
# Default is same as sickgear_dir. |
|||
# sickgear_datadir: Data directory for Sick Beard (DB, Logs, config) |
|||
# Default is same as sickgear_chdir |
|||
# sickgear_pid: The name of the pidfile to create. |
|||
# Default is sickgear.pid in sickgear_dir. |
|||
# sickgear_host: The hostname or IP SickGear is listening on |
|||
# Default is 127.0.0.1 |
|||
# sickgear_port: The port SickGear is listening on |
|||
# Default is 8081 |
|||
# sickgear_web_user: Username to authenticate to the SickGear web interface |
|||
# Default is an empty string (no username) |
|||
# sickgear_web_password: Password to authenticate to the SickGear web interface |
|||
# Default is an empty string (no password) |
|||
# sickgear_webroot: Set to value of web_root in config (for proxies etc) |
|||
# Default is an empty string (if set must start with a "/") |
|||
PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin" |
|||
|
|||
. /etc/rc.subr |
|||
|
|||
name="sickgear" |
|||
rcvar=${name}_enable |
|||
|
|||
load_rc_config ${name} |
|||
|
|||
: ${sickgear_enable:="NO"} |
|||
: ${sickgear_user:="_sabnzbd"} |
|||
: ${sickgear_dir:="/usr/local/sickgear"} |
|||
: ${sickgear_chdir:="${sickgear_dir}"} |
|||
: ${sickgear_datadir:="${sickgear_chdir}"} |
|||
: ${sickgear_pid:="${sickgear_dir}/sickgear.pid"} |
|||
: ${sickgear_host:="127.0.0.1"} |
|||
: ${sickgear_port:="8081"} |
|||
: ${sickgear_web_user:=""} |
|||
: ${sickgear_web_password:=""} |
|||
: ${sickgear_webroot:=""} |
|||
|
|||
status_cmd="${name}_status" |
|||
stop_cmd="${name}_stop" |
|||
|
|||
command="/usr/sbin/daemon" |
|||
command_args="-f -p ${sickgear_pid} python ${sickgear_dir}/SickBeard.py --quiet --nolaunch" |
|||
|
|||
# Add datadir to the command if set |
|||
[ ! -z "${sickgear_datadir}" ] && \ |
|||
command_args="${command_args} --datadir ${sickgear_datadir}" |
|||
|
|||
# Ensure user is root when running this script. |
|||
if [ `id -u` != "0" ]; then |
|||
echo "Oops, you should be root before running this!" |
|||
exit 1 |
|||
fi |
|||
|
|||
verify_sickgear_pid() { |
|||
# Make sure the pid corresponds to the SickGear process. |
|||
pid=`cat ${sickgear_pid} 2>/dev/null` |
|||
ps -p ${pid} 2>/dev/null | grep -q "python ${sickgear_dir}/SickBeard.py" |
|||
return $? |
|||
} |
|||
|
|||
# Try to stop SickGear cleanly by calling shutdown over http. |
|||
sickgear_stop() { |
|||
echo "Stopping $name" |
|||
verify_sickgear_pid |
|||
sickgear_url="${sickgear_host}:${sickgear_port}" |
|||
[ ! -z "${sickgear_web_user}" ] && \ |
|||
sickgear_url="${sickgear_web_user}:${sickgear_web_password}@${sickgear_url}" |
|||
[ ! -z "${sickgear_webroot}" ] && \ |
|||
sickgear_url="${sickgear_url}${sickgear_webroot}" |
|||
fetch -o - -q "http://${sickgear_url}/home/shutdown/?pid=${pid}" >/dev/null |
|||
if [ -n "${pid}" ]; then |
|||
wait_for_pids ${pid} |
|||
echo "Stopped" |
|||
fi |
|||
} |
|||
|
|||
sickgear_status() { |
|||
verify_sickgear_pid && echo "$name is running as ${pid}" || echo "$name is not running" |
|||
} |
|||
|
|||
run_rc_command "$1" |
@ -1,98 +0,0 @@ |
|||
#!/bin/sh |
|||
# |
|||
# PROVIDE: sickbeard |
|||
# REQUIRE: LOGIN |
|||
# KEYWORD: shutdown |
|||
# |
|||
# Add the following lines to /etc/rc.conf.local or /etc/rc.conf |
|||
# to enable this service: |
|||
# |
|||
# sickbeard_enable (bool): Set to NO by default. |
|||
# Set it to YES to enable it. |
|||
# sickbeard_user: The user account SickGear daemon runs as what |
|||
# you want it to be. It uses '_sabnzbd' user by |
|||
# default. Do not sets it as empty or it will run |
|||
# as root. |
|||
# sickbeard_dir: Directory where SickGear lives. |
|||
# Default: /usr/local/sickbeard |
|||
# sickbeard_chdir: Change to this directory before running SickGear. |
|||
# Default is same as sickbeard_dir. |
|||
# sickbeard_datadir: Data directory for Sick Beard (DB, Logs, config) |
|||
# Default is same as sickbeard_chdir |
|||
# sickbeard_pid: The name of the pidfile to create. |
|||
# Default is sickbeard.pid in sickbeard_dir. |
|||
# sickbeard_host: The hostname or IP SickGear is listening on |
|||
# Default is 127.0.0.1 |
|||
# sickbeard_port: The port SickGear is listening on |
|||
# Default is 8081 |
|||
# sickbeard_web_user: Username to authenticate to the SickGear web interface |
|||
# Default is an empty string (no username) |
|||
# sickbeard_web_password: Password to authenticate to the SickGear web interface |
|||
# Default is an empty string (no password) |
|||
# sickbeard_webroot: Set to value of web_root in config (for proxies etc) |
|||
# Default is an empty string (if set must start with a "/") |
|||
PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin" |
|||
|
|||
. /etc/rc.subr |
|||
|
|||
name="sickbeard" |
|||
rcvar=${name}_enable |
|||
|
|||
load_rc_config ${name} |
|||
|
|||
: ${sickbeard_enable:="NO"} |
|||
: ${sickbeard_user:="_sabnzbd"} |
|||
: ${sickbeard_dir:="/usr/local/sickbeard"} |
|||
: ${sickbeard_chdir:="${sickbeard_dir}"} |
|||
: ${sickbeard_datadir:="${sickbeard_chdir}"} |
|||
: ${sickbeard_pid:="${sickbeard_dir}/sickbeard.pid"} |
|||
: ${sickbeard_host:="127.0.0.1"} |
|||
: ${sickbeard_port:="8081"} |
|||
: ${sickbeard_web_user:=""} |
|||
: ${sickbeard_web_password:=""} |
|||
: ${sickbeard_webroot:=""} |
|||
|
|||
status_cmd="${name}_status" |
|||
stop_cmd="${name}_stop" |
|||
|
|||
command="/usr/sbin/daemon" |
|||
command_args="-f -p ${sickbeard_pid} python ${sickbeard_dir}/SickBeard.py --quiet --nolaunch" |
|||
|
|||
# Add datadir to the command if set |
|||
[ ! -z "${sickbeard_datadir}" ] && \ |
|||
command_args="${command_args} --datadir ${sickbeard_datadir}" |
|||
|
|||
# Ensure user is root when running this script. |
|||
if [ `id -u` != "0" ]; then |
|||
echo "Oops, you should be root before running this!" |
|||
exit 1 |
|||
fi |
|||
|
|||
verify_sickbeard_pid() { |
|||
# Make sure the pid corresponds to the SickGear process. |
|||
pid=`cat ${sickbeard_pid} 2>/dev/null` |
|||
ps -p ${pid} 2>/dev/null | grep -q "python ${sickbeard_dir}/SickBeard.py" |
|||
return $? |
|||
} |
|||
|
|||
# Try to stop SickGear cleanly by calling shutdown over http. |
|||
sickbeard_stop() { |
|||
echo "Stopping $name" |
|||
verify_sickbeard_pid |
|||
sickbeard_url="${sickbeard_host}:${sickbeard_port}" |
|||
[ ! -z "${sickbeard_web_user}" ] && \ |
|||
sickbeard_url="${sickbeard_web_user}:${sickbeard_web_password}@${sickbeard_url}" |
|||
[ ! -z "${sickbeard_webroot}" ] && \ |
|||
sickbeard_url="${sickbeard_url}${sickbeard_webroot}" |
|||
fetch -o - -q "http://${sickbeard_url}/home/shutdown/?pid=${pid}" >/dev/null |
|||
if [ -n "${pid}" ]; then |
|||
wait_for_pids ${pid} |
|||
echo "Stopped" |
|||
fi |
|||
} |
|||
|
|||
sickbeard_status() { |
|||
verify_sickbeard_pid && echo "$name is running as ${pid}" || echo "$name is not running" |
|||
} |
|||
|
|||
run_rc_command "$1" |
@ -0,0 +1,43 @@ |
|||
import logging |
|||
import os |
|||
import tempfile |
|||
import shutil |
|||
import json |
|||
from subprocess import check_call |
|||
|
|||
from dateutil.zoneinfo import tar_open, METADATA_FN, ZONEFILENAME |
|||
|
|||
|
|||
def rebuild(filename, tag=None, format="gz", zonegroups=[], metadata=None): |
|||
"""Rebuild the internal timezone info in dateutil/zoneinfo/zoneinfo*tar* |
|||
|
|||
filename is the timezone tarball from ftp.iana.org/tz. |
|||
|
|||
""" |
|||
tmpdir = tempfile.mkdtemp() |
|||
zonedir = os.path.join(tmpdir, "zoneinfo") |
|||
moduledir = os.path.dirname(__file__) |
|||
try: |
|||
with tar_open(filename) as tf: |
|||
for name in zonegroups: |
|||
tf.extract(name, tmpdir) |
|||
filepaths = [os.path.join(tmpdir, n) for n in zonegroups] |
|||
try: |
|||
check_call(["zic", "-d", zonedir] + filepaths) |
|||
except OSError as e: |
|||
if e.errno == 2: |
|||
logging.error( |
|||
"Could not find zic. Perhaps you need to install " |
|||
"libc-bin or some other package that provides it, " |
|||
"or it's not in your PATH?") |
|||
raise |
|||
# write metadata file |
|||
with open(os.path.join(zonedir, METADATA_FN), 'w') as f: |
|||
json.dump(metadata, f, indent=4, sort_keys=True) |
|||
target = os.path.join(moduledir, ZONEFILENAME) |
|||
with tar_open(target, "w:%s" % format) as tf: |
|||
for entry in os.listdir(zonedir): |
|||
entrypath = os.path.join(zonedir, entry) |
|||
tf.add(entrypath, entry) |
|||
finally: |
|||
shutil.rmtree(tmpdir) |
@ -1,2 +1,2 @@ |
|||
from lib.hachoir_core.version import VERSION as __version__, PACKAGE, WEBSITE, LICENSE |
|||
from hachoir_core.version import VERSION as __version__, PACKAGE, WEBSITE, LICENSE |
|||
|
|||
|