diff --git a/SickBeard.py b/SickBeard.py index c3e46136978872eb1e1798d547b6e99c8f150dfa..6e06ba6514a5859c46b3ca97b83a3b95ea52b611 100755 --- a/SickBeard.py +++ b/SickBeard.py @@ -231,6 +231,11 @@ def main(): # stay alive while my threads do the work while (True): + if sickbeard.invoked_command: + logger.log(u"Executing invoked command: "+repr(sickbeard.invoked_command)) + sickbeard.invoked_command() + sickbeard.invoked_command = None + time.sleep(1) return diff --git a/data/css/browser.css b/data/css/browser.css index e6eab100af069a4bbdba62ab6f3201dfb4f4344b..482d9915edb11cc18784857a6704e5202c0ad0a6 100644 --- a/data/css/browser.css +++ b/data/css/browser.css @@ -1,5 +1,5 @@ #fileBrowserDialog { - max-height: 480; + max-height: 480px; overflow-y: auto; } #fileBrowserDialog ul { diff --git a/data/css/comingEpisodes.css b/data/css/comingEpisodes.css index cb932c5c8fc020031678e878ada9ec20afdcedf1..ad9b6fd37ca1ce2ecb2b80d9ec78752ef7f58fa2 100644 --- a/data/css/comingEpisodes.css +++ b/data/css/comingEpisodes.css @@ -1,23 +1,4 @@ -div#outsideWrapper { - margin: 0px auto; - text-align: center; -} - -div#insideWrapper { - margin: 0px auto; - border: 1px solid #E9E9E9; - background-color: #F8F8F8; - padding: 0px 35px 0px 35px; - width: 629px; -} - -div#insideContent { - text-align: center; - width: 629px; -} - .tvshowDiv { - width: 606px; display: block; clear: both; border-left: 1px solid #CCCCCC; @@ -26,6 +7,7 @@ div#insideContent { margin: auto; padding: 0px; text-align: left; + width: 606px; } .tvshowDiv a, .tvshowDiv a:link, .tvshowDiv a:visited, .tvshowDiv a:hover { @@ -54,7 +36,7 @@ div#insideContent { } .posterThumb { - /* display:table-cell; */ + -ms-interpolation-mode: bicubic; /* make scaling look nicer for ie */ vertical-align: top; height: 200px; width: 136px; @@ -62,7 +44,7 @@ div#insideContent { border-right: 1px solid #ccc; } .bannerThumb { - /* display:table-cell; */ + -ms-interpolation-mode: bicubic; /* make scaling look nicer for ie */ vertical-align: top; height: 112px; width: 606px; @@ -79,6 +61,7 @@ div#insideContent { .tvshowDiv th.nobg { background: #efefef; border-top: 1px solid #666; + text-align: center; } .tvshowDiv td { @@ -118,7 +101,7 @@ h1.network { border: 1px solid #CCCCCC; margin-bottom: 10px; /* margin: 10px; */ - overflow: hidden; + /* overflow: hidden; */ padding: 10px; } diff --git a/data/css/default.css b/data/css/default.css index 1947434f4bd0534d1c03ca335a425340a4d0ad1b..22034baff171604b6d6448a1cc7418ae88ebdd38 100644 --- a/data/css/default.css +++ b/data/css/default.css @@ -36,7 +36,7 @@ display:inline; /* these are for incl_top.tmpl */ #header { -padding-top:3px; +padding: 5px 0; z-index:2; } @@ -44,23 +44,12 @@ z-index:2; background:none; } -#tagline { -display:block; -position:relative; -padding-right:10px; -top:1px; -float:right; -text-align:right; -font-size:10px; -font-weight:400; -} - #logo { font-size:33px; font-family:Arial, Helvetica, sans-serif; font-weight:700; text-transform:uppercase; -padding-left:20px; +padding: 0px 5px 0px 15px; } #versiontext { @@ -76,24 +65,6 @@ table { margin:0; } -tr.active { -font-weight:700; -} - -tr.finished { -font-weight:400; -} - -tr.waiting { -font-style:italic; -} - -td.pre { -font-size:13px; -font-family:'courier new',courier,serif; -font-weight:700; -} - h1 { text-align:left; font-size:19px; @@ -138,47 +109,39 @@ border-bottom: 1px dotted #D7D7D7; } /* --------------- alignment ------------------- */ -.float-left { -float:left; -} - -.float-right { -float:right; -} - -.align-left { -text-align:left; -} - -.align-right { -text-align:right; -} +.float-left { float:left; } +.float-right { float:right; } +.align-left { text-align:left; } +.align-right { text-align:right; } +.nowrap { white-space: nowrap; } /* --------------------------------------------- */ .footer { +clear:both; +width: 100%; text-align:center; -padding-bottom:5px; -margin-top:20px; +padding-top: 5px; +padding-bottom: 5px; background-color:#F5F1E4; -border-top:1px solid #000; +border-top:1px solid #b3b3b3; color:#4e4e4e; line-height: 1.4em; } .sickbeardTable { -width:90%; +width:100%; margin-left:auto; margin-right:auto; } .sickbeardTable th{ -padding:2px; +padding:3px; font-weight:700; background-color:#333; color:#FFF; text-shadow: -1px -1px 0 rgba(0,0,0,0.3); } .sickbeardTable td{ -padding:5px; +padding:4px; } .sickbeardTable tfoot a { color:#FFF; @@ -191,25 +154,9 @@ clear:left; .plotInfo { cursor:help; -padding-left:5px; -float:right; -} - -.message { -margin-bottom:20px; -text-align:left; -font-size:larger; -padding:4px 0 4px 1em; -} - -.message p span { -float:left; -margin-right:.5em; -} - -.message a:hover { -color:blue; -background:none; +margin-left: 8px; +position: relative; +float: right; } #tooltip { @@ -222,6 +169,7 @@ margin-right:10px; } .progressbarText { +text-shadow: 0 0 0.1em #fff; position:absolute; top:0; width:100%; @@ -286,10 +234,6 @@ background-color:#000; color:#FFF; } -.message p,.message ul { -margin:0; -} - div#summary { background-color:#efefef; padding:10px; @@ -303,14 +247,14 @@ line-height: 17px; #MainMenu { background-color:#57442B; color:#F5F5F5; -/*margin-bottom:1em;*/ width:100%; -border-bottom: 1px solid #333; } #SubMenu { +clear:both; background-color:#F5F1E4; color:#333; -border-bottom: 1px solid #333; +border-top: 1px solid #333; +border-bottom: 1px solid #b3b3b3; padding-left:5px; } #SubMenu span { @@ -342,11 +286,17 @@ border:0; padding:4px 15px 0px; } #content { -padding: 10px 15px 15px; -_text-align: center; -min-width:500px; -z-index:1; -clear:both; + min-height: 100px; + background: #fff; + margin-left: auto; + margin-right: auto; + border-left: thin solid #B3B3B3; + border-right: thin solid #B3B3B3; + width: 88%; + min-width:650px; + z-index:1; + clear:both; + padding: 10px 15px 15px; } .showLegend{ font-weight:700; @@ -378,14 +328,21 @@ overflow: hidden; div#addShowPortal { margin-left: auto; margin-right: auto; -width: 600px; +width: 480px; } -div#addShowPortal button { padding: 10px; width: 450px; } -div#addShowPortal button div.button img{ float: left; margin: 25px 25px 25px 10px; vertical-align: middle;} -div#addShowPortal button .buttontext { float: right; text-align: left; width: 350px; } +div#addShowPortal button { padding: 10px; width: 100%; } +div#addShowPortal button div.button img{ position: absolute; display: block; overflow: hidden; top: 35%; padding-left: 0.4em; text-align: center;} +div#addShowPortal button .buttontext { position: relative; display: block; padding: 0.1em 0.4em 0.1em 4.4em; text-align: left; } #rootDirs, #rootDirsControls { width: 50%; min-width: 400px; } .hover { background-color: #cfcfcf !important; cursor: pointer; } +.navShow { display: inline; cursor: pointer; vertical-align: top; } + +/* for manage_massEdit */ +.optionWrapper { width: 450px; margin-left: auto; margin-right: auto; padding: 6px 12px; } +.optionWrapper span.selectTitle { float: left; font-weight: 700; font-size: 1.2em; text-align: left; width: 225px; } +.optionWrapper div.selectChoices { float: left; width: 175px; margin-left: 25px; } +.optionWrapper br { clear: both; } -.navShow { display: inline; cursor: pointer; vertical-align: top; } \ No newline at end of file +a.whitelink { color: white; } \ No newline at end of file diff --git a/data/css/tablesorter.css b/data/css/tablesorter.css index 791cbb3f60aa6cab98ea006ca7bb01181c791e11..6c262d5679276ff81adfe4ac35f740a244903d3d 100644 --- a/data/css/tablesorter.css +++ b/data/css/tablesorter.css @@ -8,7 +8,8 @@ table.tablesorter thead tr .header { } table.tablesorter thead tr th, table.tablesorter tfoot tr th { border: 1px solid #241109; - padding: 2px; + padding: 3px; + font-weight:700; } /* table.tablesorter thead tr .headerSortUp { diff --git a/data/images/bg.gif b/data/images/bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..53f4abc902ed0178d4b83f95b984eab7c8781609 Binary files /dev/null and b/data/images/bg.gif differ diff --git a/data/images/paypal/btn_donateCC_LG.gif b/data/images/paypal/btn_donateCC_LG.gif new file mode 100644 index 0000000000000000000000000000000000000000..2d1ec159beb1196e6ef23dccbc550daa5287288f Binary files /dev/null and b/data/images/paypal/btn_donateCC_LG.gif differ diff --git a/data/images/paypal/btn_donate_LG.gif b/data/images/paypal/btn_donate_LG.gif new file mode 100644 index 0000000000000000000000000000000000000000..43cef691e583af713ecbdb66e3a3884817eafb73 Binary files /dev/null and b/data/images/paypal/btn_donate_LG.gif differ diff --git a/data/interfaces/default/comingEpisodes.tmpl b/data/interfaces/default/comingEpisodes.tmpl index 394dbd44911185df228549e3cb4e94432f646705..2c7d46684bb6d07182361dd4294fabc02bbd745b 100644 --- a/data/interfaces/default/comingEpisodes.tmpl +++ b/data/interfaces/default/comingEpisodes.tmpl @@ -5,7 +5,7 @@ #set global $sbPath=".." -<!--#set global $topmenu="comingEpisodes"#--> +#set global $topmenu="comingEpisodes"# #import os.path #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_top.tmpl") #set $sort = $sickbeard.COMING_EPS_SORT @@ -16,13 +16,14 @@ <span class="listing_current">Current</span> <span class="listing_default">Future</span> <span class="listing_toofar">Distant</span> - <span class="listing_unknown">Unknown</span> -</div><br/> + <!-- <span class="listing_unknown">Unknown</span> //--> +</div> #if $layout == 'list': -<!-- start list view --> +<!-- start list view //--> <script type="text/javascript" src="$sbRoot/js/plotTooltip.js"></script> <script type="text/javascript" charset="utf-8"> +<!-- \$.tablesorter.addParser({ id: 'nextAirDate', is: function(s) { @@ -100,21 +101,22 @@ 3: { sorter: 'loadingNames' }, 4: { sorter: 'loadingNames' }, 5: { sorter: 'quality' }, - 6: { sorter: 'status' }, - 7: { sorter: false}, - 8: { sorter: false} + 6: { sorter: false}, + 7: { sorter: false} } }); }); +//--> </script> #set $show_div = "listing_default" <input type="hidden" id="sbRoot" value="$sbRoot" /> +<br/> <table id="showListTable" class="sickbeardTable tablesorter" cellspacing="1" border="0" cellpadding="0"> - <thead><tr><th>Next Ep</th><th>Next Ep Name</th><th>Airdate</th><th>Show</th><th>Network</th><th>Quality</th><th>Status</th><th>tvDB</th><th>Force</th></tr></thead> + <thead><tr><th class="nowrap">Next Ep</th><th>Next Ep Name</th><th>Airdate</th><th>Show</th><th>Network</th><th>Quality</th><th>tvDB</th><th>Force</th></tr></thead> <tbody> #for $cur_result in $sql_results: @@ -136,16 +138,16 @@ #end if #end if - <!-- start $cur_result["show_name"] --> - <tr class="$show_div"><div> - <td align="left"><span class="float-left"><%="%02ix%02i" % (int(cur_result["season"]), int(cur_result["episode"])) %></span> + <!-- start $cur_result["show_name"] //--> + <tr class="$show_div"> + <td class="nowrap"> #if $cur_result["description"] != "" and $cur_result["description"] != None: - <img alt="" src="$sbRoot/images/info32.png" height="16" width="16" class="plotInfo" id="plot_info_<%=str(cur_result["showid"])+"_"+str(cur_result["season"])+"_"+str(cur_result["episode"])%>" /> + <img alt="" src="$sbRoot/images/info32.png" height="16" width="16" class="plotInfo" id="plot_info_<%=str(cur_result["showid"])+"_"+str(cur_result["season"])+"_"+str(cur_result["episode"])%>" /> #end if - </div> + <span><%="%02ix%02i" % (int(cur_result["season"]), int(cur_result["episode"])) %></span> </td> <td>$cur_result["name"]</td> - <td align="center" nowrap="nowrap">$datetime.date.fromordinal(int($cur_result["airdate"]))</td> + <td align="center" class="nowrap">$datetime.date.fromordinal(int($cur_result["airdate"]))</td> <td><a href="$sbRoot/home/displayShow?show=${cur_result["showid"]}">$cur_result["show_name"]</a> #if int($cur_result["paused"]): <span class="pause">[paused]</span> @@ -159,18 +161,18 @@ $qualityPresetStrings[int($cur_result["quality"])] Custom #end if </td> - <td align="center">$cur_result["show_status"]</td> <td align="center"><a href="http://www.thetvdb.com/?tab=series&id=${cur_result["showid"]}" onclick="window.open(this.href, '_blank'); return false;" title="http://www.thetvdb.com/?tab=series&id=${cur_result["showid"]}"><img alt="[info]" height="16" width="16" src="$sbRoot/images/search32.png" /></a></td> - <td align="center"><a href="$sbRoot/home/searchEpisode?show=${cur_result["showid"]}&season=$cur_result["season"]&episode=$cur_result["episode"]" title="Force Update" id="forceUpdate|${cur_result["showid"]}|$cur_result["show_name"]" class="forceUpdate"><img alt="[update]" height="16" width="16" src="$sbRoot/images/forceUpdate32.png" id="forceUpdateImage|${cur_result["showid"]}" /></a></td> + <td align="center"><a href="$sbRoot/home/searchEpisode?show=${cur_result["showid"]}&season=$cur_result["season"]&episode=$cur_result["episode"]" title="Force Update" id="forceUpdate-${cur_result["showid"]}" class="forceUpdate"><img alt="[update]" height="16" width="16" src="$sbRoot/images/forceUpdate32.png" id="forceUpdateImage-${cur_result["showid"]}" /></a></td> </tr> - <!-- end $cur_result["show_name"] --> + <!-- end $cur_result["show_name"] //--> #end for </tbody> </table> -<!-- end list view --> +<!-- end list view //--> #else: -<!-- start non list view --> +<!-- start non list view //--> <script type="text/javascript" charset="utf-8"> +<!-- \$(document).ready(function(){ \$(".ep_summary").hide(); \$(".ep_summaryTrigger").click(function() { @@ -181,10 +183,8 @@ Custom }); }); }); +//--> </script> -<div id="outsideWrapper"> -<div id="insideWrapper"> - <div id="insideContent"> #set $cur_segment = None #set $too_late_header = False @@ -196,7 +196,7 @@ Custom #end if #for $cur_result in $sql_results: - <!-- start $cur_result["show_name"] --> + <!-- start $cur_result["show_name"] //--> #if int($cur_result["paused"]) and not $sickbeard.COMING_EPS_DISPLAY_PAUSED: #continue @@ -231,10 +231,11 @@ Custom #set $show_div = "ep_listing listing_toofar" #set $too_late_header = True #elif $cur_ep_airdate >= $today and $cur_ep_airdate < $next_week: - <br /><h1 class="day">$datetime.date.fromordinal($cur_ep_airdate).strftime("%A").decode($sickbeard.SYS_ENCODING)</h1> #if $cur_ep_airdate == $today: + <br /><h1 class="day">$datetime.date.fromordinal($cur_ep_airdate).strftime("%A").decode($sickbeard.SYS_ENCODING) <span style="font-size: 12px;">[today]</span></h1> #set $show_div = "ep_listing listing_current" #else: + <br /><h1 class="day">$datetime.date.fromordinal($cur_ep_airdate).strftime("%A").decode($sickbeard.SYS_ENCODING)</h1> #set $show_div = "ep_listing listing_default" #end if #end if @@ -252,12 +253,12 @@ Custom <span class="pause">[paused]</span> #end if </a></span> - <span class="tvshowTitleIcons"><a href="http://www.thetvdb.com/?tab=series&id=${cur_result["showid"]}" onclick="window.open(this.href, '_blank'); return false;" title="http://www.thetvdb.com/?tab=series&id=${cur_result["showid"]}"><img alt="[info]" height="20" width="20" src="$sbRoot/images/search32.png" /></a> <a href="$sbRoot/home/searchEpisode?show=${cur_result["showid"]}&season=$cur_result["season"]&episode=$cur_result["episode"]" title="Force Update" id="forceUpdate|${cur_result["showid"]}|$cur_result["show_name"]" class="forceUpdate"><img alt="[update]" height="20" width="20" src="$sbRoot/images/forceUpdate32.png" id="forceUpdateImage|${cur_result["showid"]}" /></a></span> + <span class="tvshowTitleIcons"><a href="http://www.thetvdb.com/?tab=series&id=${cur_result["showid"]}" onclick="window.open(this.href, '_blank'); return false;" title="http://www.thetvdb.com/?tab=series&id=${cur_result["showid"]}"><img alt="[info]" height="20" width="20" src="$sbRoot/images/search32.png" /></a> <a href="$sbRoot/home/searchEpisode?show=${cur_result["showid"]}&season=$cur_result["season"]&episode=$cur_result["episode"]" title="Force Update" id="forceUpdate-${cur_result["showid"]}" class="forceUpdate"><img alt="[update]" height="20" width="20" src="$sbRoot/images/forceUpdate32.png" id="forceUpdateImage-${cur_result["showid"]}" /></a></span> </th> </tr> <tr> <th #if $layout == 'banner' then "class=\"nobg\"" else "rowspan=\"2\""# style="background-color: #efefef;"> - <a href="$sbRoot/home/displayShow?show=${cur_result["showid"]}"><img alt="" class="#if $layout == 'banner' then "bannerThumb" else "posterThumb"#" src="$sbRoot/showPoster/?show=${cur_result["showid"]}&which=$layout" /></a> + <a href="$sbRoot/home/displayShow?show=${cur_result["showid"]}"><img alt="" class="#if $layout == 'banner' then "bannerThumb" else "posterThumb"#" src="$sbRoot/showPoster/?show=${cur_result["showid"]}&which=$layout" /></a> </th> #if $layout == 'banner': </tr> @@ -288,18 +289,19 @@ Custom </div> </div> - <!-- end $cur_result["show_name"] --> + <!-- end $cur_result["show_name"] //--> #end for <br/> - </div> -</div> -</div> -<!-- end non list view --> + +<!-- end non list view //--> #end if <script type="text/javascript" charset="utf-8"> +<!-- setInterval(window.location.reload, 180000); // Refresh every 3 minutes +//--> </script> +<script type="text/javascript" src="$sbRoot/js/tableClick.js"></script> #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_bottom.tmpl") diff --git a/data/interfaces/default/config.tmpl b/data/interfaces/default/config.tmpl index adfb70b9792c6e2fc6cba469da756daf396326c5..a070c2fe3964a13a6526477e5d040d014b31aed2 100644 --- a/data/interfaces/default/config.tmpl +++ b/data/interfaces/default/config.tmpl @@ -4,12 +4,12 @@ #set global $sbPath=".." -<!--#set global $topmenu="config"#--> +#set global $topmenu="config"# #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_top.tmpl") <div id="summary" class="align-left"> <table class="infoTable" cellspacing="1" border="0" cellpadding="0"> - <tr><td class="infoTableHeader">SB Version: </td><td class="infoTableCell">alpha ($sickbeard.version.SICKBEARD_VERSION) <!-- – build.date --></td></tr> + <tr><td class="infoTableHeader">SB Version: </td><td class="infoTableCell">alpha ($sickbeard.version.SICKBEARD_VERSION) <!-- – build.date //--></td></tr> <tr><td class="infoTableHeader">SB Config file: </td><td class="infoTableCell">$sickbeard.CONFIG_FILE</td></tr> <tr><td class="infoTableHeader">SB Cache Dir: </td><td class="infoTableCell">$sickbeard.CACHE_DIR</td></tr> <tr><td class="infoTableHeader">SB Arguments: </td><td class="infoTableCell">$sickbeard.MY_ARGS</td></tr> @@ -18,13 +18,13 @@ <tr style="border-top: 1px dotted #666666;"><td class="infoTableHeader">Homepage </td><td class="infoTableCell"><a href="http://www.sickbeard.com/">http://www.sickbeard.com/</a></td></tr> <tr><td class="infoTableHeader">Forums </td><td class="infoTableCell"><a href="http://sickbeard.com/forums/">http://sickbeard.com/forums/</a></td></tr> <tr><td class="infoTableHeader">Source </td><td class="infoTableCell"><a href="https://github.com/midgetspy/Sick-Beard/">https://github.com/midgetspy/Sick-Beard/</a></td></tr> - <tr><td class="infoTableHeader">Bug Tracker &<br/> Windows Builds </td><td class="infoTableCell"><a href="http://code.google.com/p/sickbeard/">http://code.google.com/p/sickbeard/</a></td></tr> - <tr><td class="infoTableHeader">Internet Relay Chat </td><td class="infoTableCell"><a href="irc://irc.freenode.net/#sickbeard"><i>#sickbeard</i> on <i>irc.freenode.net</i></a> + <tr><td class="infoTableHeader">Bug Tracker &<br/> Windows Builds </td><td class="infoTableCell"><a href="http://code.google.com/p/sickbeard/">http://code.google.com/p/sickbeard/</a></td></tr> + <tr><td class="infoTableHeader">Internet Relay Chat </td><td class="infoTableCell"><a href="irc://irc.freenode.net/#sickbeard"><i>#sickbeard</i> on <i>irc.freenode.net</i></a></td></tr> </table> </div> <table class="infoTable" cellspacing="1" border="0" cellpadding="0"><tr> - <td><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=JA8M7VDY89SQ4" onclick="window.open(this.href); return false;"><img src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif" alt="[donate]" /></td> + <td><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=JA8M7VDY89SQ4" onclick="window.open(this.href); return false;"><img src="$sbRoot/images/paypal/btn_donateCC_LG.gif" alt="[donate]" /></a></td> <td>Sickbeard is free, but you can contribute by giving a <b><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=JA8M7VDY89SQ4" onclick="window.open(this.href); return false;">donation</a></b>.</td> </tr></table> diff --git a/data/interfaces/default/config_episodedownloads.tmpl b/data/interfaces/default/config_episodedownloads.tmpl index b6070856c705aa6da9decd0aa63481d5d7257c25..eb54bcd2ec6a94867aa8dec70ed0164487482638 100644 --- a/data/interfaces/default/config_episodedownloads.tmpl +++ b/data/interfaces/default/config_episodedownloads.tmpl @@ -4,11 +4,12 @@ #set global $sbPath="../.." -<!--#set global $topmenu="config"#--> +#set global $topmenu="config"# #import os.path #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_top.tmpl") <script type="text/javascript" charset="utf-8"> +<!-- \$(document).ready(function(){ \$.fn.nzb_method_handler = function() { @@ -30,6 +31,7 @@ \$(this).nzb_method_handler(); }); +//--> </script> <div id="config"> @@ -81,7 +83,7 @@ <input type="submit" value="Save Changes" /><br/> </fieldset> - </div><!-- /component-group1 --> + </div><!-- /component-group1 //--> <div id="core-component-group2" class="component-group clearfix"> @@ -199,7 +201,7 @@ <input type="submit" value="Save Changes" /><br/> </fieldset> - </div><!-- /component-group2 --> + </div><!-- /component-group2 //--> <div id="core-component-group3" class="component-group clearfix"> @@ -273,20 +275,22 @@ <input type="submit" value="Save Changes" /><br/> </fieldset> - </div><!-- /component-group3 --> + </div><!-- /component-group3 //--> <br/><input type="submit" value="Save Changes" /><br/> - </div><!-- /config-components --> + </div><!-- /config-components //--> </form> </div></div> <div class="clearfix"></div> <script type="text/javascript" charset="utf-8"> +<!-- jQuery('#nzb_dir').fileBrowser({ title: 'Select NZB Black Hole/Watch Directory' }); jQuery('#torrent_dir').fileBrowser({ title: 'Select Torrent Black Hole/Watch Directory' }); jQuery('#tv_download_dir').fileBrowser({ title: 'Select TV Download Directory' }); +//--> </script> #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_bottom.tmpl") diff --git a/data/interfaces/default/config_general.tmpl b/data/interfaces/default/config_general.tmpl index 119b27b0411dd05e605d3944c0945669be30b2e3..b29734a4d6318dedd74e8be8af374ae2f05b8a0f 100644 --- a/data/interfaces/default/config_general.tmpl +++ b/data/interfaces/default/config_general.tmpl @@ -9,15 +9,18 @@ #set global $sbPath="../.." -<!--#set global $topmenu="config"#--> +#set global $topmenu="config"# #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_top.tmpl") <script type="text/javascript"> +<!-- nameTestURL = "$sbRoot/config/general/testNaming"; +//--> </script> <script type="text/javascript" src="$sbRoot/js/configGeneral.js"></script> #set $anyQualities, $bestQualities = $Quality.splitQuality($sickbeard.QUALITY_DEFAULT) <script type="text/javascript" charset="utf-8"> +<!-- \$(document).ready(function(){ if (#if $sickbeard.QUALITY_DEFAULT in $qualityPresets then "1" else "0"#) { @@ -51,6 +54,7 @@ nameTestURL = "$sbRoot/config/general/testNaming"; }); }); +//--> </script> <div id="config"> @@ -99,7 +103,7 @@ nameTestURL = "$sbRoot/config/general/testNaming"; <input type="submit" value="Save Changes" /> </fieldset> - </div><!-- /component-group1 --> + </div><!-- /component-group1 //--> <div id="core-component-group2" class="component-group clearfix"> @@ -157,17 +161,17 @@ nameTestURL = "$sbRoot/config/general/testNaming"; <div class="clearfix" style="clear:left;"></div> <div class="field-pair clearfix"> - <input type="checkbox" name="use_banner" id="use_banner" #if $sickbeard.USE_BANNER then "CHECKED" else ""#> + <input type="checkbox" name="use_banner" id="use_banner" #if $sickbeard.USE_BANNER then "checked=checked" else ""#/> <label class="clearfix" for="use_banner"> <span class="component-title">Use Banners</span> <span class="component-desc">Use banners instead of posters for your Show Folder Images</span> </label> </div> - <input type="submit" value="Save Changes"><br/> + <input type="submit" value="Save Changes" /><br/> </fieldset> - </div><!-- /component-group2 --> + </div><!-- /component-group2 //--> <div id="core-component-group3" class="component-group clearfix"> @@ -229,9 +233,9 @@ nameTestURL = "$sbRoot/config/general/testNaming"; <input type="submit" value="Save Changes" /> </fieldset> - </div><!-- /component-group3 --> + </div><!-- /component-group3 //--> - <div id="core-component-group5" class="component-group clearfix"> + <div id="core-component-group4" class="component-group clearfix"> <div class="component-group-desc"> <h3>Episode Naming</h3> @@ -292,7 +296,7 @@ nameTestURL = "$sbRoot/config/general/testNaming"; <span class="component-desc"> <select name="naming_sep_type" id="naming_sep_type"> #for ($i, $ex) in enumerate($config.naming_sep_type_text): - <option value="$i" #if $i == int($sickbeard.NAMING_SEP_TYPE) then "selected=\"selected\"" else ""#>$ex + <option value="$i" #if $i == int($sickbeard.NAMING_SEP_TYPE) then "selected=\"selected\"" else ""#>$ex</option> #end for </select> </span> @@ -305,7 +309,7 @@ nameTestURL = "$sbRoot/config/general/testNaming"; <span class="component-desc"> <select name="naming_ep_type" id="naming_ep_type"> #for ($i, $ex) in enumerate($config.naming_ep_type_text): - <option value="$i" #if $i == int($sickbeard.NAMING_EP_TYPE) then "selected=\"selected\"" else ""#>$ex + <option value="$i" #if $i == int($sickbeard.NAMING_EP_TYPE) then "selected=\"selected\"" else ""#>$ex</option> #end for </select> </span> @@ -315,9 +319,7 @@ nameTestURL = "$sbRoot/config/general/testNaming"; <div class="field-pair" style="padding:10px; background: #efefef;"> <label class="clearfix" for="naming_ep_type"> <span class="component-title jumbo">Single-Ep Example:</span> - <span class="component-desc jumbo"> - <div id="normalExampleText"></div> - </span> + <span class="component-desc jumbo" id="normalExampleText"></span> </label> </div> @@ -327,7 +329,7 @@ nameTestURL = "$sbRoot/config/general/testNaming"; <span class="component-desc"> <select name="naming_multi_ep_type" id="naming_multi_ep_type"> #for ($i, $ex) in enumerate($config.naming_multi_ep_type_text): - <option value="$i" #if $i == int($sickbeard.NAMING_MULTI_EP_TYPE) then "selected=\"selected\"" else ""#>$ex + <option value="$i" #if $i == int($sickbeard.NAMING_MULTI_EP_TYPE) then "selected=\"selected\"" else ""#>$ex</option> #end for </select> </span> @@ -337,9 +339,7 @@ nameTestURL = "$sbRoot/config/general/testNaming"; <div class="field-pair" style="padding:10px; background: #efefef;"> <label class="clearfix" for="naming_multi_ep_type"> <span class="component-title jumbo">Multi-Ep Example:</span> - <span class="component-desc jumbo"> - <div id="multiExampleText"></div> - </span> + <span class="component-desc jumbo" id="multiExampleText"></span> </label> </div> @@ -360,7 +360,7 @@ nameTestURL = "$sbRoot/config/general/testNaming"; <input type="submit" value="Save Changes" /> </fieldset> - </div><!-- /component-group5 --> + </div><!-- /component-group4 //--> <br/><input type="submit" value="Save Changes" /><br/> </div><!-- /config-components --> @@ -370,7 +370,9 @@ nameTestURL = "$sbRoot/config/general/testNaming"; <div class="clearfix"></div> <script type="text/javascript" charset="utf-8"> +<!-- jQuery('#log_dir').fileBrowser({ title: 'Select Log Directory' }); +//--> </script> #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_bottom.tmpl") diff --git a/data/interfaces/default/config_notifications.tmpl b/data/interfaces/default/config_notifications.tmpl index d007f587a21cb74c961fc4f8faab623d1405fb60..b2133838293abf7de2e8086f1c516891260d2d8b 100644 --- a/data/interfaces/default/config_notifications.tmpl +++ b/data/interfaces/default/config_notifications.tmpl @@ -4,7 +4,7 @@ #set global $sbPath="../.." -<!--#set global $topmenu="config"#--> +#set global $topmenu="config"# #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_top.tmpl") <script type="text/javascript" src="$sbRoot/js/configNotifications.js"></script> @@ -106,10 +106,10 @@ <input type="button" value="Test XBMC" id="testXBMC" /> <input type="submit" value="Save Changes" /> - </div><!-- /enabler_xbmc --> + </div><!-- /enabler_xbmc //--> </fieldset> - </div><!-- /component-group --> + </div><!-- /component-group //--> <div id="core-component-group2" class="component-group clearfix"> @@ -174,10 +174,10 @@ <input type="button" value="Test Growl" id="testGrowl" /> <input type="submit" value="Save Changes" /> - </div><!-- /content_use_growl --> + </div><!-- /content_use_growl //--> </fieldset> - </div><!-- /component-group --> + </div><!-- /component-group //--> <div id="core-component-group3" class="component-group clearfix"> @@ -249,10 +249,10 @@ <input type="button" value="Test Twitter" id="testTwitter" /> <input type="submit" value="Save Changes" /> - </div><!-- /content_use_twitter --> + </div><!-- /content_use_twitter //--> </fieldset> - </div><!-- /component-group --> + </div><!-- /component-group //--> <div id="core-component-group4" class="component-group clearfix"> @@ -302,11 +302,11 @@ <label class="nocheck clearfix"> <span class="component-title">Prowl priority:</span> <select id="prowl_priority" name="prowl_priority"> - <option value="-2" #if $sickbeard.PROWL_PRIORITY == "-2" then "selected" else ""#>Very Low - <option value="-1" #if $sickbeard.PROWL_PRIORITY == "-1" then "selected" else ""#>Moderate - <option value="0" #if $sickbeard.PROWL_PRIORITY == "0" then "selected" else ""#>Normal - <option value="1" #if $sickbeard.PROWL_PRIORITY == "1" then "selected" else ""#>High - <option value="2" #if $sickbeard.PROWL_PRIORITY == "2" then "selected" else ""#>Emergency + <option value="-2" #if $sickbeard.PROWL_PRIORITY == "-2" then 'selected="selected"' else ""#>Very Low</option> + <option value="-1" #if $sickbeard.PROWL_PRIORITY == "-1" then 'selected="selected"' else ""#>Moderate</option> + <option value="0" #if $sickbeard.PROWL_PRIORITY == "0" then 'selected="selected"' else ""#>Normal</option> + <option value="1" #if $sickbeard.PROWL_PRIORITY == "1" then 'selected="selected"' else ""#>High</option> + <option value="2" #if $sickbeard.PROWL_PRIORITY == "2" then 'selected="selected"' else ""#>Emergency</option> </select> </label> <label class="nocheck clearfix"> @@ -319,10 +319,10 @@ <input type="button" value="Test Prowl" id="testProwl" /> <input type="submit" value="Save Changes" /> - </div><!-- /content_use_prowl --> + </div><!-- /content_use_prowl //--> </fieldset> - </div><!-- /component-group --> + </div><!-- /component-group //--> <div id="core-component-group5" class="component-group clearfix"> @@ -383,7 +383,7 @@ <input type="button" value="Test Notifo" id="testNotifo" /> <input type="submit" value="Save Changes" /> - </div><!-- /content_use_notifo --> + </div><!-- /content_use_notifo //--> </fieldset> @@ -426,14 +426,14 @@ <input type="button" value="Test Libnotify" id="testLibnotify" /> <input type="submit" value="Save Changes" /> - </div><!-- /content_use_libnotify --> + </div><!-- /content_use_libnotify //--> </fieldset> - </div><!-- /component-group --> + </div><!-- /component-group //--> <br/><input type="submit" value="Save Changes" /><br/> - </div><!-- /config-components --> + </div><!-- /config-components //--> </form> diff --git a/data/interfaces/default/config_providers.tmpl b/data/interfaces/default/config_providers.tmpl index 5659ec8b212919b6b8ae84db77f40fc107700ef3..d5acb09404e7f493066c566b968ed6858348b74a 100644 --- a/data/interfaces/default/config_providers.tmpl +++ b/data/interfaces/default/config_providers.tmpl @@ -4,12 +4,13 @@ #set global $sbPath="../.." -<!--#set global $topmenu="config"#--> +#set global $topmenu="config"# #import os.path #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_top.tmpl") <script type="text/javascript" src="$sbRoot/js/configProviders.js"></script> <script type="text/javascript" charset="utf-8"> +<!-- sbRoot = '$sbRoot'; \$(document).ready(function(){ @@ -17,6 +18,7 @@ sbRoot = '$sbRoot'; \$(this).addProvider('$curNewznabProvider.getID()', '$curNewznabProvider.name', '$curNewznabProvider.url', '$curNewznabProvider.key', $int($curNewznabProvider.default)); #end for }); +//--> </script> <div id="config"> @@ -61,7 +63,7 @@ sbRoot = '$sbRoot'; <input type="hidden" name="provider_order" id="provider_order" value="<%=" ".join([x.getID()+':'+str(int(x.isEnabled())) for x in sickbeard.providers.sortedProviderList()])%>"/> <br/><input type="submit" value="Save Changes" /><br/> </fieldset> - </div><!-- /component-group1 --> + </div><!-- /component-group1 //--> <div id="core-component-group2" class="component-group clearfix"> @@ -87,7 +89,7 @@ sbRoot = '$sbRoot'; </div> -<!-- start div for editing providers --> +<!-- start div for editing providers //--> #if $sickbeard.SHOW_TVBINZ: <div class="providerDiv" id="tvbinzDiv"> <div class="field-pair"> @@ -170,12 +172,12 @@ sbRoot = '$sbRoot'; </label> </div> </div> -<!-- end div for editing providers --> +<!-- end div for editing providers //--> <input type="submit" value="Save Changes" /><br/> </fieldset> - </div><!-- /component-group2 --> + </div><!-- /component-group2 //--> <div id="core-component-group3" class="component-group clearfix"> @@ -230,12 +232,12 @@ sbRoot = '$sbRoot'; </div> </fieldset> - </div><!-- /component-group3 --> + </div><!-- /component-group3 //--> <br/><input type="submit" value="Save Changes" /><br/> - </div><!-- /config-components --> + </div><!-- /config-components //--> </form> </div></div> diff --git a/data/interfaces/default/displayShow.tmpl b/data/interfaces/default/displayShow.tmpl index 36d4fe8b759ce4002516cd831a69ec431e88e2e2..845923888e2e0e51831edfe4f0571d57bc0ed945 100644 --- a/data/interfaces/default/displayShow.tmpl +++ b/data/interfaces/default/displayShow.tmpl @@ -6,7 +6,7 @@ #set global $title=$show.name #set global $header = '<a href="http://thetvdb.com/?tab=series&id=%d" target="_new">%s</a>' % ($show.tvdbid, $show.name) -<!--#set global $topmenu="manageShows"#--> +#set global $topmenu="manageShows"# #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_top.tmpl") <script type="text/javascript" src="$sbRoot/js/jquery.bookmarkscroll.js"></script> @@ -21,7 +21,7 @@ #end for </div><br/> -<input type="hidden" id="sbRoot" value="$sbRoot"> +<input type="hidden" id="sbRoot" value="$sbRoot" /> <script type="text/javascript" src="$sbRoot/js/displayShow.js"></script> <script type="text/javascript" src="$sbRoot/js/plotTooltip.js"></script> @@ -30,7 +30,7 @@ <div class="navShow"><img id="prevShow" width="16" height="18" src="$sbRoot/images/prev.gif" alt="<<" title="Prev Show" /></div> <select id="pickShow"> #for $curShow in $sortedShowList: -<option value="$curShow.tvdbid" #if $curShow == $show then "SELECTED" else ""#>$curShow.name +<option value="$curShow.tvdbid" #if $curShow == $show then "selected=\"selected\"" else ""#>$curShow.name</option> #end for </select> <div class="navShow"><img id="nextShow" width="16" height="18" src="$sbRoot/images/next.gif" alt=">>" title="Next Show" /></div> @@ -77,11 +77,11 @@ Change selected episodes to #if $curStatus == $DOWNLOADED: #continue #end if -<option value="$curStatus">$statusStrings[$curStatus] +<option value="$curStatus">$statusStrings[$curStatus]</option> #end for </select> -<input type="hidden" id="showID" value="$show.tvdbid"> -<input type="button" id="changeStatus" value="Go"><br /> +<input type="hidden" id="showID" value="$show.tvdbid" /> +<input type="button" id="changeStatus" value="Go" /><br /> <br /> <br /> </div> @@ -90,13 +90,13 @@ Change selected episodes to #set $odd = 0 <div class="float-right" id="checkboxControls"> -<label for="wanted"><span class="wanted">Wanted: <b>$epCounts[$Overview.WANTED]</b> <input type="checkbox" id="wanted" checked=checked></span> -<label for="qual"><span class="qual">Low Quality: <b>$epCounts[$Overview.QUAL]</b> <input type="checkbox" id="qual" checked=checked></span> -<label for"good"><span class="good">Downloaded: <b>$epCounts[$Overview.GOOD]</b> <input type="checkbox" id="good" checked=checked></span> -<label for="skipped"><span class="skipped">Skipped: <b>$epCounts[$Overview.SKIPPED]</b> <input type="checkbox" id="skipped" checked=checked></label> +<label for="wanted"><span class="wanted">Wanted: <b>$epCounts[$Overview.WANTED]</b> <input type="checkbox" id="wanted" checked="checked" /></span></label> +<label for="qual"><span class="qual">Low Quality: <b>$epCounts[$Overview.QUAL]</b> <input type="checkbox" id="qual" checked="checked" /></span></label> +<label for="good"><span class="good">Downloaded: <b>$epCounts[$Overview.GOOD]</b> <input type="checkbox" id="good" checked="checked" /></span></label> +<label for="skipped"><span class="skipped">Skipped: <b>$epCounts[$Overview.SKIPPED]</b> <input type="checkbox" id="skipped" checked="checked" /></span></label> <br /> -<span class="selectAll"><a href="#" onClick="return false" class="seriesCheck">Select Filtered Episodes</a> </span> -<span class="clearAll"><a href="#" onClick="return false" class="clearAll">Clear All</a></span> +<span class="selectAll"><a href="#" onclick="return false;" class="seriesCheck">Select Filtered Episodes</a></span> +<span class="clearAll"><a href="#" onclick="return false;" class="clearAll">Clear All</a></span> </div> <div style="clear:both;" class="clearfix"></div> @@ -106,14 +106,13 @@ Change selected episodes to #for $epResult in $sqlResults: #if int($epResult["season"]) != $curSeason: - <tr><td colspan="9"></td></tr> + <tr><td colspan="9"><a name="season-$epResult["season"]"></a></td></tr> <tr class="seasonheader" id="season-$epResult["season"]"> - <a name="season-$epResult["season"]"></a> <td colspan="9"> <h2>#if int($epResult["season"]) == 0 then "Specials" else "Season "+str($epResult["season"])#</h2> </td> </tr> - <tr id="season-$epResult["season"]-cols"><th width="1%"><input type="checkbox" class="seasonCheck" id="$epResult["season"]"></th><th>NFO</th><th>TBN</th><th>Episode</th><th>Name</th><th>Airdate</th><th>Filename</th><th>Status</th><th>Action</th></tr> + <tr id="season-$epResult["season"]-cols"><th width="1%"><input type="checkbox" class="seasonCheck" id="$epResult["season"]" /></th><th>NFO</th><th>TBN</th><th>Episode</th><th>Name</th><th class="nowrap">Airdate</th><th>Filename</th><th>Status</th><th>Action</th></tr> #set $curSeason = int($epResult["season"]) #end if @@ -122,19 +121,19 @@ Change selected episodes to <tr class="$Overview.overviewStrings[$epCats[$epStr]] season-$curSeason"> <td width="1%"> #if int($epResult["status"]) != $UNAIRED - <input type="checkbox" class="epCheck" id="<%=str(epResult["season"])+'x'+str(epResult["episode"])%>" name="<%=str(epResult["season"]) +"x"+str(epResult["episode"]) %>"> + <input type="checkbox" class="epCheck" id="<%=str(epResult["season"])+'x'+str(epResult["episode"])%>" name="<%=str(epResult["season"]) +"x"+str(epResult["episode"]) %>" /> #end if </td> - <td align="center"><img src="$sbRoot/images/#if $epResult["hasnfo"] == 1 then "nfo.gif\" alt=\"Y" else "nfo-no.gif\" alt=\"N"#" width="23" height="11"></td> - <td align="center"><img src="$sbRoot/images/#if $epResult["hastbn"] == 1 then "tbn.gif\" alt=\"Y" else "tbn-no.gif\" alt=\"N"#" width="23" height="11"></td> + <td align="center"><img src="$sbRoot/images/#if $epResult["hasnfo"] == 1 then "nfo.gif\" alt=\"Y" else "nfo-no.gif\" alt=\"N"#" width="23" height="11" /></td> + <td align="center"><img src="$sbRoot/images/#if $epResult["hastbn"] == 1 then "tbn.gif\" alt=\"Y" else "tbn-no.gif\" alt=\"N"#" width="23" height="11" /></td> <td align="center">$epResult["episode"]</td> <td> $epResult["name"] #if $epResult["description"] != "" and $epResult["description"] != None: - <img src="$sbRoot/images/info32.png" height="16" class="plotInfo" id="plot_info_$show.tvdbid<%="_"+str(epResult["season"])+"_"+str(epResult["episode"])%>" /> + <img src="$sbRoot/images/info32.png" height="16" class="plotInfo" alt="" id="plot_info_$show.tvdbid<%="_"+str(epResult["season"])+"_"+str(epResult["episode"])%>" /> #end if </td> - <td align="center" nowrap="nowrap">#if int($epResult["airdate"]) == 1 then "never" else $datetime.date.fromordinal(int($epResult["airdate"]))#</td> + <td align="center">#if int($epResult["airdate"]) == 1 then "never" else $datetime.date.fromordinal(int($epResult["airdate"]))#</td> <td> #if $epLoc and $show._location and $epLoc.lower().startswith($show._location.lower()): $epLoc[len($show._location)+1:] @@ -146,7 +145,7 @@ $epLoc <td>$statusStrings[int($epResult["status"])]</td> <td align="center"> #if int($epResult["season"]) != 0: - <a href="searchEpisode?show=$show.tvdbid&season=$epResult["season"]&episode=$epResult["episode"]"><img src="$sbRoot/images/search32.png" height="16" alt="search" title="Manual Search" /></a> + <a href="searchEpisode?show=$show.tvdbid&season=$epResult["season"]&episode=$epResult["episode"]"><img src="$sbRoot/images/search32.png" height="16" alt="search" title="Manual Search" /></a> #end if </td> </tr> diff --git a/data/interfaces/default/editShow.tmpl b/data/interfaces/default/editShow.tmpl index 151ec59dcfdc5124f502add6a76167965cda19f5..afde1c78becbde904d60d0f7259f9b57b68fc52f 100644 --- a/data/interfaces/default/editShow.tmpl +++ b/data/interfaces/default/editShow.tmpl @@ -6,10 +6,11 @@ #set global $sbPath=".." -<!--#set global $topmenu="home"#--> +#set global $topmenu="home"# #import os.path #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_top.tmpl") -<script> +<script type="text/javascript" charset="utf-8"> +<!-- \$(document).ready(function(){ \$.getJSON('$sbRoot/home/addShows/getTVDBLanguages', {}, function(data){ @@ -38,12 +39,13 @@ }); }); +//--> </script> <form action="editShow" method="post"> -<input type="hidden" name="show" value="$show.tvdbid"> -Location: <input type="text" name="location" id="location" value="$show._location" size="50"><br /> +<input type="hidden" name="show" value="$show.tvdbid" /> +Location: <input type="text" name="location" id="location" value="$show._location" size="50" /><br /> <br /> Quality: #set $qualities = $common.Quality.splitQuality(int($show.quality)) @@ -55,22 +57,24 @@ Quality: Language: <select name="tvdbLang" id="tvdbLangSelect"></select> <br /> <br /> -Use Season Folders: <input type="checkbox" name="seasonfolders" #if $show.seasonfolders == 1 then "CHECKED" else ""#><br /><br /> -Paused: <input type="checkbox" name="paused" #if $show.paused == 1 then "CHECKED" else ""#><br /><br /> +Use Season Folders: <input type="checkbox" name="seasonfolders" #if $show.seasonfolders == 1 then "checked=\"checked\"" else ""# /><br /><br /> +Paused: <input type="checkbox" name="paused" #if $show.paused == 1 then "checked=\"checked\"" else ""# /><br /><br /> Air by date: #if ($show.genre and "Talk Show" not in $show.genre) or not $show.genre: -<input type="checkbox" name="air_by_date" #if $show.air_by_date == 1 then "CHECKED" else ""#><br /> +<input type="checkbox" name="air_by_date" #if $show.air_by_date == 1 then "checked=\"checked\"" else ""# /><br /> (check this if the show is released as Show.03.02.2010 rather than Show.S02E03) #else -<input type="checkbox" DISABLED CHECKED> +<input type="checkbox" disabled=\"disabled\" checked=\"checked\" /> #end if <br /><br /> -<input type="submit" value="Submit"> +<input type="submit" value="Submit" /> </form> <script type="text/javascript" charset="utf-8"> +<!-- jQuery('#location').fileBrowser({ title: 'Select Show Location' }); +//--> </script> #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_bottom.tmpl") diff --git a/data/interfaces/default/errorlogs.tmpl b/data/interfaces/default/errorlogs.tmpl index 2842d6d61afbe1e601c92b8cfa368127952f4a3b..08823124206cf09e0d6bc287cac4a35f9cbd2cc3 100644 --- a/data/interfaces/default/errorlogs.tmpl +++ b/data/interfaces/default/errorlogs.tmpl @@ -5,7 +5,7 @@ #set global $sbPath = ".." -<!--#set global $topmenu="errorlogs"#--> +#set global $topmenu="errorlogs"# #import os.path #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_top.tmpl") @@ -16,7 +16,9 @@ </div> <script type="text/javascript" charset="utf-8"> +<!-- setInterval(window.location.reload, 180000); // Refresh every 3 minutes +//--> </script> #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_bottom.tmpl") diff --git a/data/interfaces/default/genericMessage.tmpl b/data/interfaces/default/genericMessage.tmpl index 0e5622142ae1f1399605bb3bf77d86c9567ac781..47553c8853fa3d281da651200c9ca156b2e61230 100644 --- a/data/interfaces/default/genericMessage.tmpl +++ b/data/interfaces/default/genericMessage.tmpl @@ -4,7 +4,7 @@ #set global $sbPath="../.." -<!--#set global $topmenu="home"#--> +#set global $topmenu="home"# #import os.path #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_top.tmpl") diff --git a/data/interfaces/default/history.tmpl b/data/interfaces/default/history.tmpl index 4fc8caadd311c5ab385d664c8cfa6478c7ee877b..afaf97bee1ab64e6c357c094429611dfd10f46f8 100644 --- a/data/interfaces/default/history.tmpl +++ b/data/interfaces/default/history.tmpl @@ -10,10 +10,11 @@ #set global $sbPath=".." -<!--#set global $topmenu="history"#--> +#set global $topmenu="history"# #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_top.tmpl") <script type="text/javascript"> +<!-- \$(document).ready(function() { \$("#historyTable:has(tbody tr)").tablesorter({ @@ -21,16 +22,17 @@ sortList: [[0,1]] }); }); +//--> </script> <table id="historyTable" class="sickbeardTable tablesorter" cellspacing="1" border="0" cellpadding="0"> - <thead><tr><th>Time</th><th>Episode</th><th>Action</th><th>Provider</th><th>Quality</th></tr></thead> + <thead><tr><th class="nowrap">Time</th><th>Episode</th><th>Action</th><th>Provider</th><th>Quality</th></tr></thead> <tbody> #for $hItem in $historyResults: #set $curStatus, $curQuality = $Quality.splitCompositeStatus(int($hItem["action"])) <tr> - <td nowrap="nowrap">$datetime.datetime.strptime(str($hItem["date"]), $history.dateFormat)</td> + <td>$datetime.datetime.strptime(str($hItem["date"]), $history.dateFormat)</td> <td><a href="$sbRoot/home/displayShow?show=$hItem["showid"]#season-$hItem["season"]">$hItem["show_name"] - <%=str(hItem["season"]) +"x"+ "%02i" % int(hItem["episode"]) %></a></td> <td align="center">$statusStrings[$curStatus]</td> <td align="center"> diff --git a/data/interfaces/default/home.tmpl b/data/interfaces/default/home.tmpl index 4225f74919611d0bd8c2ec770b150e39d3ddc619..b71b642981d92300a12d9da62e922c8d587291d4 100644 --- a/data/interfaces/default/home.tmpl +++ b/data/interfaces/default/home.tmpl @@ -8,7 +8,7 @@ #set global $sbPath = ".." -<!--#set global $topmenu="home"#--> +#set global $topmenu="home"# #import os.path #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_top.tmpl") @@ -18,6 +18,7 @@ #set $allEps = $myDB.select("SELECT showid, COUNT(*) FROM tv_episodes WHERE season != 0 and episode != 0 AND (airdate != 1 OR status IN ("+",".join([str(x) for x in ($Quality.DOWNLOADED + $Quality.SNATCHED + $Quality.SNATCHED_PROPER) + [$ARCHIVED]])+")) AND airdate <= "+$today+" AND status != "+str($IGNORED)+" GROUP BY showid") <script type="text/javascript" charset="utf-8"> +<!-- \$.tablesorter.addParser({ id: 'nextAirDate', is: function(s) { @@ -135,14 +136,15 @@ }); }); +//--> </script> <table id="showListTable" class="sickbeardTable tablesorter" cellspacing="1" border="0" cellpadding="0"> - <thead><tr><th>Next Ep</th><th>Show</th><th>Network</th><th>Quality</th><th>Downloads</th><th>Active</th><th>Status</th></tr></thead> + <thead><tr><th class="nowrap">Next Ep</th><th>Show</th><th>Network</th><th>Quality</th><th>Downloads</th><th>Active</th><th>Status</th></tr></thead> <tfoot> <tr> - <th rowspan="1" colspan="1"><a href="$sbRoot/home/addShows/">Add Show</a></th> + <th rowspan="1" colspan="1" align="center"><a href="$sbRoot/home/addShows/">Add Show</a></th> <th rowspan="1" colspan="6"></th> </tr> </tfoot> @@ -195,7 +197,7 @@ $myShowList.sort(lambda x, y: cmp(x.name, y.name)) #end if <tr> - <td align="center" nowrap="nowrap">#if len($curEp) != 0 then $curEp[0].airdate else ""#</td> + <td align="center">#if len($curEp) != 0 then $curEp[0].airdate else ""#</td> <td><a href="$sbRoot/home/displayShow?show=$curShow.tvdbid">$curShow.name</a></td> <td>$curShow.network</td> #if $curShow.quality in $qualityPresets: @@ -203,22 +205,26 @@ $myShowList.sort(lambda x, y: cmp(x.name, y.name)) #else: <td align="center">Custom</td> #end if - <td align="center"><!--$dlStat--><div id="progressbar$curShow.tvdbid" style="position:relative;"></div></td> + <td align="center"><!--$dlStat--><div id="progressbar$curShow.tvdbid" style="position:relative;"></div> + <script type="text/javascript"> + <!-- + \$(function() { + \$("\#progressbar$curShow.tvdbid").progressbar({ + value: parseInt($nom) * 100 / parseInt($den) + }); + \$("\#progressbar$curShow.tvdbid").append( "<div class='progressbarText'>$dlStat</div>" ) + }); + //--> + </script> + </td> <td align="center"><img src="$sbRoot/images/#if int($curShow.paused) == 0 and $curShow.status != "Ended" then "yes16.png\" alt=\"Y\"" else "no16.png\" alt=\"N\""# width="16" height="16" /></td> <td align="center">$curShow.status</td> </tr> -<script type="text/javascript"> - \$(function() { - \$("\#progressbar$curShow.tvdbid").progressbar({ - value: parseInt($nom) * 100 / parseInt($den) - }); - \$("\#progressbar$curShow.tvdbid").append( "<!--$dlStat--><div class='progressbarText'>$dlStat</div>" ) - }); -</script> #end for </tbody> </table> +<script type="text/javascript" src="$sbRoot/js/tableClick.js"></script> #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_bottom.tmpl") diff --git a/data/interfaces/default/home_addExistingShow.tmpl b/data/interfaces/default/home_addExistingShow.tmpl index 2621fc272ef4aeeeabd39ab30f3632dfb0900e19..7ac6a079b45600c95da692eb03b79c44d1ac214d 100644 --- a/data/interfaces/default/home_addExistingShow.tmpl +++ b/data/interfaces/default/home_addExistingShow.tmpl @@ -6,8 +6,8 @@ #set global $sbPath="../.." -<!--#set global $statpath="../.."#--> -<!--#set global $topmenu="home"#--> +#set global $statpath="../.."# +#set global $topmenu="home"# #import os.path #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_top.tmpl") @@ -17,13 +17,15 @@ <script type="text/javascript" src="$sbRoot/js/rootDirs.js"></script> <script type="text/javascript" src="$sbRoot/js/addShowOptions.js"></script> -<script> +<script type="text/javascript" charset="utf-8"> +<!-- \$(document).ready(function(){ \$( "#tabs" ).tabs({ collapsible: true, selected: #if $sickbeard.ROOT_DIRS then '-1' else '0'# }); }); +//--> </script> <div id="tabs"> @@ -42,17 +44,17 @@ <p class="align-left">Sick Beard can add existing shows, using the current options, by using locally stored NFO/XML metadata to eliminate user interaction.<br /> If you would rather have Sick Beard prompt you to customize each show, then use the checkbox below.</p> -<p class="align-left"><input type="checkbox" name="promptForSettings" id="promptForSettings"> <label for="promptForSettings">Prompt me to set settings for each show</label></p> +<p class="align-left"><input type="checkbox" name="promptForSettings" id="promptForSettings" /> <label for="promptForSettings">Prompt me to set settings for each show</label></p> -<hr> +<hr /> <h3>Displaying folders within these directories which aren't already added to Sick Beard:</h3> -<ul id="rootDirStaticList"></ul> +<ul id="rootDirStaticList"><li></li></ul> <br /> <div id="tableDiv"></div> <br /> <br /> -<input type="button" value="Submit" id="submitShowDirs"> - +<input type="button" value="Submit" id="submitShowDirs" /> +</form> #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_bottom.tmpl") diff --git a/data/interfaces/default/home_addShows.tmpl b/data/interfaces/default/home_addShows.tmpl index a2a44fe65f9cb69e4546301b308d34422520d546..5eb7736ac5060018fa588ce400a7bd7056b0b531 100644 --- a/data/interfaces/default/home_addShows.tmpl +++ b/data/interfaces/default/home_addShows.tmpl @@ -5,13 +5,14 @@ #set global $sbPath="../.." -<!--#set global $statpath="../.."#--> -<!--#set global $topmenu="home"#--> +#set global $statpath="../.."# +#set global $topmenu="home"# #import os.path #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_top.tmpl") -<script> +<script type="text/javascript" charset="utf-8"> +<!-- \$(document).ready(function(){ \$('#btnNewShow').click(function() { @@ -22,29 +23,29 @@ }); }); +//--> </script> <div id="addShowPortal"> -<button id="btnNewShow"> -<div class="button"><img src="$sbRoot/images/add-new32.png" /></div> -<div class="buttontext"> - <h2>Add New Show</h2> - <p>For shows that you haven't downloaded yet, this option finds a show on TVDB.com, creates a directory for its episodes, and adds it to Sick Beard.</p> -</div> -</button> + <button id="btnNewShow" class="ui-button"> + <div class="button"><img src="$sbRoot/images/add-new32.png" alt="Add New Show"/></div> + <div class="buttontext"> + <h2>Add New Show</h2> + <p>For shows that you haven't downloaded yet, this option finds a show on TVDB.com, creates a directory for its episodes, and adds it to Sick Beard.</p> + </div> + </button> -<br/><br/> + <br/><br/> -<button id="btnExistingShow"> -<div class="button"><img src="$sbRoot/images/add-existing32.png" /></div> -<div class="buttontext"> - <h2>Add Existing Shows</h2> - <p>Use this option to add shows that already have a folder created on your hard drive. Sick Beard will scan your existing metadata/episodes and add the show accordingly.</p> -</div> -</button> + <button id="btnExistingShow" class="ui-button"> + <div class="button"><img src="$sbRoot/images/add-existing32.png" alt="Add Existing Shows"/></div> + <div class="buttontext"> + <h2>Add Existing Shows</h2> + <p>Use this option to add shows that already have a folder created on your hard drive. Sick Beard will scan your existing metadata/episodes and add the show accordingly.</p> + </div> + </button> </div> #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_bottom.tmpl") - diff --git a/data/interfaces/default/home_newShow.tmpl b/data/interfaces/default/home_newShow.tmpl index 11f32a50878e8c7e6fa480b08d37264f9ec0e7b7..dbb930271f8da1032d0dcbd8dd34fe2b6e88b984 100644 --- a/data/interfaces/default/home_newShow.tmpl +++ b/data/interfaces/default/home_newShow.tmpl @@ -5,8 +5,8 @@ #set global $sbPath="../.." -<!--#set global $statpath="../.."#--> -<!--#set global $topmenu="home"#--> +#set global $statpath="../.."# +#set global $topmenu="home"# #import os.path #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_top.tmpl") @@ -28,9 +28,9 @@ <div class="stepDiv"> #if $use_provided_info: Show retrieved from existing metadata: <a href="http://thetvdb.com/?tab=series&id=$provided_tvdb_id">$provided_tvdb_name</a> - <input type="hidden" name="tvdbLang" value="en"> - <input type="hidden" name="whichSeries" value="$provided_tvdb_id"> - <input type="hidden" id="providedName" value="$provided_tvdb_name"> + <input type="hidden" name="tvdbLang" value="en" /> + <input type="hidden" name="whichSeries" value="$provided_tvdb_id" /> + <input type="hidden" id="providedName" value="$provided_tvdb_name" /> #else: <input type="text" id="nameToSearch" value="$default_show_name" /> <select name="tvdbLang" id="tvdbLangSelect"> @@ -53,7 +53,7 @@ <div class="stepDiv"> #if $provided_show_dir: Pre-chosen Destination Folder: <b>$provided_show_dir</b> <br /> - <input type="hidden" id="fullShowPath" name="fullShowPath" value="$provided_show_dir"><br /> + <input type="hidden" id="fullShowPath" name="fullShowPath" value="$provided_show_dir" /><br /> #else #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_rootDirs.tmpl") #end if @@ -68,22 +68,20 @@ </fieldset> #for $curNextDir in $other_shows: -<input type="hidden" name="other_shows" value="$curNextDir"> +<input type="hidden" name="other_shows" value="$curNextDir" /> #end for -<input type="hidden" name="skipShow" id="skipShow" value=""> +<input type="hidden" name="skipShow" id="skipShow" value="" /> </form> <br /> <div style="width: 800px; text-align: center;"> -<input type="button" id="addShowButton" value="Add Show" disabled> +<input type="button" id="addShowButton" value="Add Show" disabled="disabled" /> #if $provided_show_dir: -<input type="button" id="skipShowButton" value="Skip Show"> +<input type="button" id="skipShowButton" value="Skip Show" /> #end if </div> <script type="text/javascript" src="$sbRoot/js/rootDirs.js"></script> -</div> - #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_bottom.tmpl") diff --git a/data/interfaces/default/home_postprocess.tmpl b/data/interfaces/default/home_postprocess.tmpl index 8a41dd9c780d1c01bda451d85418c8e446552138..33e31295e2b21cbfa6cc074fed320237c6a60256 100644 --- a/data/interfaces/default/home_postprocess.tmpl +++ b/data/interfaces/default/home_postprocess.tmpl @@ -3,8 +3,7 @@ #set global $sbPath="../.." - -<!--#set global $topmenu="home"#--> +#set global $topmenu="home"# #import os.path #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_top.tmpl") @@ -14,7 +13,9 @@ Enter the folder containing the episode: <input type="text" name="dir" id="episo <br /> <script type="text/javascript" charset="utf-8"> +<!-- jQuery('#episodeDir').fileBrowser({ title: 'Select Unprocessed Episode Folder', key: 'postprocessPath' }); +//--> </script> #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_bottom.tmpl") diff --git a/data/interfaces/default/inc_addShowOptions.tmpl b/data/interfaces/default/inc_addShowOptions.tmpl index ec896ad4ab02b0699aee3f39981bd8287aae3d70..bd0905bbcd1fb2802689be490259a2e504459d29 100644 --- a/data/interfaces/default/inc_addShowOptions.tmpl +++ b/data/interfaces/default/inc_addShowOptions.tmpl @@ -5,7 +5,7 @@ <span class="component-title"> <select name="defaultStatus" id="statusSelect"> #for $curStatus in [$SKIPPED, $WANTED, $ARCHIVED, $IGNORED]: - <option value="$curStatus" #if $sickbeard.STATUS_DEFAULT == $curStatus then 'selected="selected"' else ''#>$statusStrings[$curStatus] + <option value="$curStatus" #if $sickbeard.STATUS_DEFAULT == $curStatus then 'selected="selected"' else ''#>$statusStrings[$curStatus]</option> #end for </select> </span> @@ -14,7 +14,7 @@ </div> <div class="field-pair alt"> - <input type="checkbox" name="seasonFolders" id="seasonFolders" #if $sickbeard.SEASON_FOLDERS_DEFAULT then "checked=\"checked\"" else ""#> + <input type="checkbox" name="seasonFolders" id="seasonFolders" #if $sickbeard.SEASON_FOLDERS_DEFAULT then "checked=\"checked\"" else ""# /> <label for="seasonFolders" class="clearfix"> <span class="component-title">Season Folders</span> <span class="component-desc">Store episodes in season folders?</span> @@ -27,8 +27,8 @@ #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_qualityChooser.tmpl") <div class="field-pair alt"> - <label for="makeDefault" class="nocheck clearfix"> - <span class="component-title"><input type="button" id="saveDefaultsButton" value="Save Defaults" disabled></span> + <label for="saveDefaultsButton" class="nocheck clearfix"> + <span class="component-title"><input type="button" id="saveDefaultsButton" value="Save Defaults" disabled="disabled" /></span> <span class="component-desc">Persist current values as the defaults</span> </label> </div> diff --git a/data/interfaces/default/inc_bottom.tmpl b/data/interfaces/default/inc_bottom.tmpl index c19104e3c93501b9ae655c46015acd90056b06c6..cb741cece7e80264bcc99e4fd7c440186383312a 100644 --- a/data/interfaces/default/inc_bottom.tmpl +++ b/data/interfaces/default/inc_bottom.tmpl @@ -2,6 +2,7 @@ #import datetime #from sickbeard import db #from sickbeard.common import * + </div> </div> <div class="footer"> #set $myDB = $db.DBConnection() @@ -13,7 +14,7 @@ <b>$numShows shows</b> ($numGoodShows active) | <b>$numDLEpisodes/$numEpisodes</b> episodes downloaded <br /> <b>Search</b>: <%=str(sickbeard.currentSearchScheduler.timeLeft()).split('.')[0]%> | -<!--<b>Update</b>: <a%a=str(sickbeard.updateScheduler.timeLeft()).split('.')[0]%> | --> +<!--<b>Update</b>: <a%a=str(sickbeard.updateScheduler.timeLeft()).split('.')[0]%> | //--> <b>Backlog</b>: $sickbeard.backlogSearchScheduler.nextRun().strftime("%a %b %d").decode($sickbeard.SYS_ENCODING) <br /> </div> </body> diff --git a/data/interfaces/default/inc_qualityChooser.tmpl b/data/interfaces/default/inc_qualityChooser.tmpl index 2a1575792b9fb3404782b96743490650d4e6ee36..46c9b558b16c060fed63db765a8de72ec1169798 100644 --- a/data/interfaces/default/inc_qualityChooser.tmpl +++ b/data/interfaces/default/inc_qualityChooser.tmpl @@ -50,4 +50,4 @@ </div> <br style="clear:both;"/> -</div><br /> \ No newline at end of file +</div><br /> diff --git a/data/interfaces/default/inc_rootDirs.tmpl b/data/interfaces/default/inc_rootDirs.tmpl index f2efcf54021fa168d27d1780113bf48ed3473825..bd5a70d8b0c71e6fcfa58a616dcacc578e4feeec 100644 --- a/data/interfaces/default/inc_rootDirs.tmpl +++ b/data/interfaces/default/inc_rootDirs.tmpl @@ -10,7 +10,7 @@ #set $backend_dirs = [] #end if -<input type="hidden" id="whichDefaultRootDir" value="$backend_default"> +<input type="hidden" id="whichDefaultRootDir" value="$backend_default" /> <div style="padding-bottom: 5px; padding-top: 10px;"> <select name="rootDir" id="rootDirs" size="6" style="min-width: 400px;"> #for $cur_dir in $backend_dirs: @@ -24,5 +24,5 @@ <input type="button" id="deleteRootDir" value="Delete" /> <input type="button" id="defaultRootDir" value="Set as Default *" /> </div> -<input type="text" style="display: none" id="rootDirText"> +<input type="text" style="display: none" id="rootDirText" /> <br /> diff --git a/data/interfaces/default/inc_top.tmpl b/data/interfaces/default/inc_top.tmpl index e35eff7cfcdc9130db4c978dc841d9a9110b2447..57933ecd78b1ce07f2a49696650b81c6d30daa70 100644 --- a/data/interfaces/default/inc_top.tmpl +++ b/data/interfaces/default/inc_top.tmpl @@ -23,6 +23,8 @@ <style type="text/css"> <!-- +#contentWrapper { background: url("$sbRoot/images/bg.gif") repeat scroll 0 0 transparent; } + .ac_loading { background: white url("$sbRoot/images/loading16.gif") right center no-repeat; } .sf-sub-indicator { background: url("$sbRoot/images/arrows.png") no-repeat -10px -100px; } .sf-shadow ul { background: url("$sbRoot/images/shadow.png") no-repeat bottom right; } @@ -55,7 +57,7 @@ table.tablesorter thead tr .headerSortDown { background-image: url("$sbRoot/imag .ui-widget-overlay { background: #aaaaaa url("$sbRoot/css/smooth-grinder/images/ui-bg_flat_0_000000_40x100.png") 50% 50% repeat; opacity: .35;filter:Alpha(Opacity=35); } .ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #000000 url("$sbRoot/css/smooth-grinder/images/ui-bg_flat_0_000000_40x100.png") 50% 50% repeat-x; opacity: .35;filter:Alpha(Opacity=35); -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; } ---> +//--> </style> <script type="text/javascript" src="$sbRoot/js/jquery-1.5.1.min.js"></script> @@ -70,27 +72,13 @@ table.tablesorter thead tr .headerSortDown { background-image: url("$sbRoot/imag <script type="text/javascript" src="$sbRoot/js/jquery.tablesorter-2.0.3.min.js"></script> <script type="text/javascript" src="$sbRoot/js/tools.tooltip-1.2.5.min.js"></script> <script type="text/javascript" src="$sbRoot/js/jquery.pnotify-1.0.1.min.js"></script> - <script type="text/javascript" src="$sbRoot/js/jquery.divgrow-1.3.1.min.js"></script> - - <script type="text/javascript" charset="utf-8"> -\$(document).ready(function(){ + <script type="text/javascript" src="$sbRoot/js/jquery.expand-1.3.8.js"></script> - \$("table.sickbeardTable td").hover( - function() { \$(this).find("a").parent().addClass("hover"); }, - function() { \$(this).find("a").parent().removeClass("hover"); - } ); - - \$("table.sickbeardTable td").click( function() { - var href = \$(this).find("a").attr("href"); - if(href) { window.location = href; } - }); - -}); - </script> <script type="text/javascript" charset="utf-8"> + <!-- sbRoot = "$sbRoot"; //HTML for scrolltopcontrol, which is auto wrapped in DIV w/ ID="topcontrol" - top_image_html = '<img src="$sbRoot/images/top.gif" style="width:31px; height:11px" />'; + top_image_html = '<img src="$sbRoot/images/top.gif" style="width:31px; height:11px" alt="Jump to top" />'; $.Browser = { defaults: { @@ -99,11 +87,13 @@ table.tablesorter thead tr .headerSortDown { background-image: url("$sbRoot/imag autocompleteURL: '$sbRoot/browser/complete' } }; + //--> </script> <script type="text/javascript" src="$sbRoot/js/jquery.scrolltopcontrol-1.1.js"></script> <script type="text/javascript" src="$sbRoot/js/browser.js"></script> -<script type="text/javascript"> +<script type="text/javascript"> +<!-- \$(document).ready(function(){ \$("ul.sf-menu").supersubs({ minWidth: 12, // minimum width of sub-menus in em units @@ -145,7 +135,7 @@ table.tablesorter thead tr .headerSortDown { background-image: url("$sbRoot/imag return false; }); - \$.pnotify.defaults.pnotify_width = "325px"; + \$.pnotify.defaults.pnotify_width = "340px"; \$.pnotify.defaults.pnotify_history = false; \$.pnotify.defaults.pnotify_delay = 4000; @@ -166,6 +156,7 @@ table.tablesorter thead tr .headerSortDown { background-image: url("$sbRoot/imag #end for }); +//--> </script> </head> @@ -203,6 +194,7 @@ table.tablesorter thead tr .headerSortDown { background-image: url("$sbRoot/imag <ul> <li><a href="$sbRoot/manage/backlogOverview"><img src="$sbRoot/images/menu/backlog16.png" alt="" width="16" height="16" />Backlog Overview</a></li> <li><a href="$sbRoot/manage/manageSearches"><img src="$sbRoot/images/menu/managesearches16.png" alt="" width="16" height="16" />Manage Searches</a></li> + <li><a href="$sbRoot/manage/episodeStatuses"><img src="$sbRoot/images/menu/backlog16.png" alt="" width="16" height="16" />Episode Status Management</a></li> </ul> </li> <li id="NAVconfig"><a href="$sbRoot/config">Config</a> @@ -218,7 +210,7 @@ table.tablesorter thead tr .headerSortDown { background-image: url("$sbRoot/imag <li><a href="$sbRoot/errorlogs/viewlog"><img src="$sbRoot/images/menu/viewlog16.png" alt="" width="16" height="16" />View Log</a></li> </ul> </li> - <li id="donate"><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=JA8M7VDY89SQ4" onclick="window.open(this.href); return false;"><img src="https://www.paypal.com/en_US/i/btn/btn_donate_LG.gif" alt="[donate]" /></a></li> + <li id="donate"><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=JA8M7VDY89SQ4" onclick="window.open(this.href); return false;"><img src="$sbRoot/images/paypal/btn_donate_LG.gif" alt="[donate]" /></a></li> </ul> #if $varExists('submenu'): <div id="SubMenu"> @@ -244,22 +236,7 @@ table.tablesorter thead tr .headerSortDown { background-image: url("$sbRoot/imag </div> #end if -<div id="content"> - -#for $curMessage in $flash.messages(): -<br /> -<div class="message ui-state-highlight ui-corner-all"> - <p><span class="ui-icon ui-icon-info"></span>$curMessage[0]</p> - $curMessage[1] -</div> -#end for - -#for $curError in $flash.errors(): -<br /> -<div class="message ui-state-error ui-corner-all"> - <p><span class="ui-icon ui-icon-alert"></span>$curError[0]</p> - $curError[1] -</div> -#end for +<div id="contentWrapper"> + <div id="content"> <h1>#if $varExists('header') then $header else $title#</h1> diff --git a/data/interfaces/default/manage.tmpl b/data/interfaces/default/manage.tmpl index 6400c73ce94cee55ed9a9be190b5da31612718a9..1aafd88e9be5a5613742b45978de113f69aa9662 100644 --- a/data/interfaces/default/manage.tmpl +++ b/data/interfaces/default/manage.tmpl @@ -4,120 +4,136 @@ #set global $sbPath="../.." - -<!--#set global $topmenu="manage"#--> +#set global $topmenu="manage"# #import os.path #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_top.tmpl") <script type="text/javascript" charset="utf-8"> -\$.tablesorter.addParser({ - // set a unique id - id: 'showNames', - is: function(s) { - // return false so this parser is not auto detected - return false; +<!-- +\$.tablesorter.addParser({ + id: 'showNames', + is: function(s) { + return false; }, format: function(s) { - // format your data for normalization if (s.indexOf('The ') == 0) return s.replace('The ', '') else if (s.indexOf('A ') == 0) return s.replace('A ', '') else - return s; + return s; + }, + type: 'text' +}); + +\$.tablesorter.addParser({ + id: 'images', + is: function(s) { + return false; }, - // set type, either numeric or text - type: 'text' -}); - + format: function(s) { + if (s == '') + return '~~'; + else + return s; + }, + type: 'text' +}); + \$(document).ready(function() { \$("#massUpdateTable:has(tbody tr)").tablesorter({ - sortList: [[3,1],[1,0]], + sortList: [[1,0]], widgets: ['zebra'], headers: { 0: { sorter: false}, 1: { sorter: 'showNames'}, - 5: { sorter: false}, + 3: { sorter: 'images'}, + 4: { sorter: 'images'}, 6: { sorter: false}, - 7: { sorter: false} + 7: { sorter: false}, + 8: { sorter: false}, + 9: { sorter: false} } }); }); +//--> </script> <script type="text/javascript" src="$sbRoot/js/massUpdate.js"></script> <form name="massUpdateForm" method="post" action="massUpdate"> <table id="massUpdateTable" class="sickbeardTable tablesorter" cellspacing="1" border="0" cellpadding="0"> - <thead> <tr> <th width="1%">Edit <input type="checkbox" class="bulkCheck" id="editCheck" /></th> - <th>Show</th> + <th class="nowrap">Show Name</th> <th>Quality</th> - <th>Active</th> + <th>Season<br/>Folders</th> + <th>Paused</th> <th>Status</th> <th width="1%">Update <input type="checkbox" class="bulkCheck" id="updateCheck" /></th> <th width="1%">Rescan <input type="checkbox" class="bulkCheck" id="refreshCheck" /></th> <th width="1%">Rename <input type="checkbox" class="bulkCheck" id="renameCheck" /></th> -<!-- <th>Force Metadata Regen <input type="checkbox" class="bulkCheck" id="metadataCheck" /></th>--> +<!-- <th>Force Metadata Regen <input type="checkbox" class="bulkCheck" id="metadataCheck" /></th>//--> + <th width="1%">Delete <input type="checkbox" class="bulkCheck" id="deleteCheck" /></th> </tr> </thead> +<tfoot> + <tr> + <td rowspan="1" colspan="1" align="center"><input type="button" value="Edit Selected Shows" id="submitMassEdit" /></td> + <td rowspan="1" colspan="9" align="right"><input type="button" value="Submit" id="submitMassUpdate" /></td> + </tr> +</tfoot> <tbody> - #set $myShowList = $sickbeard.showList $myShowList.sort(lambda x, y: cmp(x.name, y.name)) #for $curShow in $myShowList: #set $curEp = $curShow.nextEpisode() - #set $curUpdate_disabled = "" #set $curRefresh_disabled = "" #set $curRename_disabled = "" +#set $curDelete_disabled = "" #if $sickbeard.showQueueScheduler.action.isBeingUpdated($curShow) or $sickbeard.showQueueScheduler.action.isInUpdateQueue($curShow): - #set $curUpdate_disabled = "disabled " + #set $curUpdate_disabled = "disabled=\"disabled\" " #end if #set $curUpdate = "<input type=\"checkbox\" class=\"updateCheck\" id=\"update-"+str($curShow.tvdbid)+"\" "+$curUpdate_disabled+"/>" - #if $sickbeard.showQueueScheduler.action.isBeingRefreshed($curShow) or $sickbeard.showQueueScheduler.action.isInRefreshQueue($curShow): - #set $curRefresh_disabled = "disabled " + #set $curRefresh_disabled = "disabled=\"disabled\" " #end if #set $curRefresh = "<input type=\"checkbox\" class=\"refreshCheck\" id=\"refresh-"+str($curShow.tvdbid)+"\" "+$curRefresh_disabled+"/>" - #if $sickbeard.showQueueScheduler.action.isBeingRenamed($curShow) or $sickbeard.showQueueScheduler.action.isInRenameQueue($curShow): - #set $curRename = "disabled " + #set $curRename = "disabled=\"disabled\" " #end if #set $curRename = "<input type=\"checkbox\" class=\"renameCheck\" id=\"rename-"+str($curShow.tvdbid)+"\" "+$curRename_disabled+"/>" +#if $sickbeard.showQueueScheduler.action.isBeingRenamed($curShow) or $sickbeard.showQueueScheduler.action.isInRenameQueue($curShow) or $sickbeard.showQueueScheduler.action.isInRefreshQueue($curShow): + #set $curDelete = "disabled=\"disabled\" " +#end if +#set $curDelete = "<input type=\"checkbox\" class=\"deleteCheck\" id=\"delete-"+str($curShow.tvdbid)+"\" "+$curDelete_disabled+"/>" <tr> <td align="center"><input type="checkbox" class="editCheck" id="edit-$curShow.tvdbid" /></td> - <td nowrap="nowrap"><a href="$sbRoot/home/displayShow?show=$curShow.tvdbid">$curShow.name</a></td> - <td align="center"> + <td><a href="$sbRoot/home/displayShow?show=$curShow.tvdbid">$curShow.name</a></td> #if $curShow.quality in $qualityPresets: -$qualityPresetStrings[$curShow.quality] + <td align="center">$qualityPresetStrings[$curShow.quality]</td> #else: -Custom + <td align="center">Custom</td> #end if - </td> - <td align="center"><img src="$sbRoot/images/#if int($curShow.paused) == 0 and $curShow.status != "Ended" then "yes16.png\" alt=\"Y\"" else "no16.png\" alt=\"N\""# width="16" height="16" /></td> + <td align="center"><img src="$sbRoot/images/#if int($curShow.seasonfolders) == 1 then "yes16.png\" alt=\"Y\"" else "no16.png\" alt=\"N\""# width="16" height="16" /></td> + <td align="center"><img src="$sbRoot/images/#if int($curShow.paused) == 1 then "yes16.png\" alt=\"Y\"" else "no16.png\" alt=\"N\""# width="16" height="16" /></td> <td align="center">$curShow.status</td> <td align="center">$curUpdate</td> <td align="center">$curRefresh</td> <td align="center">$curRename</td> -<!-- <td align="center"><input type="checkbox" class="metadataCheck" id="metadata-$curShow.tvdbid" /></td>--> +<!-- <td align="center"><input type="checkbox" class="metadataCheck" id="metadata-$curShow.tvdbid" /></td>//--> + <td align="center">$curDelete</td> </tr> - #end for </tbody> -<tfoot> - <tr> - <td align="center"><input type="button" value="Edit Selected Shows" id="submitMassEdit" /></td> - <td colspan="7" align="right"><input type="button" value="Submit" id="submitMassUpdate" /></td> - </tr> -</tfoot> </table> </form> +<script type="text/javascript" src="$sbRoot/js/tableClick.js"></script> #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_bottom.tmpl") diff --git a/data/interfaces/default/manage_backlogOverview.tmpl b/data/interfaces/default/manage_backlogOverview.tmpl index d10e94892362ee600ccbd12d091ff68e94506f8c..5a3bf9069e19febc8a419ca4f80f90c4c9bd71ca 100644 --- a/data/interfaces/default/manage_backlogOverview.tmpl +++ b/data/interfaces/default/manage_backlogOverview.tmpl @@ -5,7 +5,7 @@ #set global $sbPath=".." -<!--#set global $topmenu="manage"#--> +#set global $topmenu="manage"# #import os.path #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_top.tmpl") @@ -18,8 +18,8 @@ #end for <div class="h2footer align-right"> - <span class="wanted" style="white-space:nowrap;">Wanted: <b>$totalWanted</b></span> - <span class="qual" style="white-space:nowrap;">Low Quality: <b>$totalQual</b></span> + <span class="wanted nowrap">Wanted: <b>$totalWanted</b></span> + <span class="qual nowrap">Low Quality: <b>$totalQual</b></span> </div><br/> <table class="sickbeardTable" cellspacing="1" border="0" cellpadding="0"> @@ -34,13 +34,14 @@ <td colspan="3"> <br/><h2 style="display: inline; position:absolute;"><a href="$sbRoot/home/displayShow?show=$curShow.tvdbid">$curShow.name</a></h2> <div class="float-right"> - <span class="wanted" style="white-space:nowrap;">Wanted: <b>$showCounts[$curShow.tvdbid][$Overview.WANTED]</b></span> - <span class="qual" style="white-space:nowrap;">Low Quality: <b>$showCounts[$curShow.tvdbid][$Overview.QUAL]</b></span> + <span class="wanted nowrap">Wanted: <b>$showCounts[$curShow.tvdbid][$Overview.WANTED]</b></span> + <span class="qual nowrap">Low Quality: <b>$showCounts[$curShow.tvdbid][$Overview.QUAL]</b></span> <a href="$sbRoot/manage/backlogShow?tvdb_id=$curShow.tvdbid"><img alt="[force backlog]" height="20" src="$sbRoot/images/forceBacklog20.png" title="Force Backlog" /></a> </div> + </td> </tr> - <tr><th>Episode</th><th>Name</th><th>Airdate</th></tr> + <tr><th>Episode</th><th>Name</th><th class="nowrap">Airdate</th></tr> #for $curResult in $showSQLResults[$curShow.tvdbid]: #set $whichStr = $str($curResult["season"]) + "x" + $str($curResult["episode"]) @@ -51,7 +52,7 @@ <tr class="$Overview.overviewStrings[$showCats[$curShow.tvdbid][$whichStr]]"> <td align="center">$whichStr</td> <td>$curResult["name"]</td> - <td align="center" nowrap="nowrap">#if int($curResult["airdate"]) == 1 then "never" else $datetime.date.fromordinal(int($curResult["airdate"]))#</td> + <td align="center">#if int($curResult["airdate"]) == 1 then "never" else $datetime.date.fromordinal(int($curResult["airdate"]))#</td> </tr> #end for @@ -59,4 +60,6 @@ #end for -</table><br /><br /> +</table><br /> + +#include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_bottom.tmpl") diff --git a/data/interfaces/default/manage_episodeOverview.tmpl b/data/interfaces/default/manage_episodeOverview.tmpl deleted file mode 100644 index 81036edf67e292b04aea9101ab65010985ebe66b..0000000000000000000000000000000000000000 --- a/data/interfaces/default/manage_episodeOverview.tmpl +++ /dev/null @@ -1,138 +0,0 @@ -#import sickbeard -#import datetime -#from sickbeard.common import * -#set global $title="Episode Overview" - -#set global $sbPath=".." - -<!--#set global $topmenu="manage"#--> -#import os.path -#include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_top.tmpl") -<script> -\$(document).ready(function() -{ - // show/hide different types of rows when the checkboxes are changed - \$(".checkboxControls input").change(function(e){ - var whichClass = \$(this).attr('class') - \$('tr.'+whichClass).each(function(i){ - \$(this).toggle(); - }); - }); - - // select all visible checkboxes for the current show - \$('.checkAll').change(function(){ - - var showCheck = this - var tvdbid = \$(showCheck).attr('id'); - - \$('.epCheck-'+tvdbid+':visible').each(function(){ - var epParts = \$(this).attr('id').split('-') - - if (epParts[0] == tvdbid) { - this.checked = showCheck.checked - } - }); - }); -#if $showObj: - // handle the status change button - build the URL for the currently active show and send it via ajax (eventually) - \$('#changeStatus').click(function(){ - var epArr = new Array() - - \$('.epCheck').each(function(){ - if (this.checked == true) { - epArr.push(\$(this).attr('id')) - } - }); - - if (epArr.length == 0) - return false - - url = '$sbRoot/home/setStatus' - params = { show: $showObj.tvdbid, eps: epArr.join('|'), status: \$('#statusSelect').attr('value'), direct: 'True'} - - \$.getJSON(url, params, function(data){ - location.reload() - }); - - }); -#end if - // initially show/hide all the rows according to the checkboxes - \$(".checkboxControls input").each(function(e){ - var status = this.checked; - \$("tr."+\$(this).attr('class')).each(function(e){ - if (status) { - \$(this).show(); - } else { - \$(this).hide(); - } - }); - }); - - // handle the show selection dropbox - \$('#pickShow').change(function(){ - var val = \$(this).attr('value') - if (val == 0) - return - url = '$sbRoot/manageShows/episodeOverview/?showID='+val - window.location.href = url - }); - - -}); - -</script> - -<b>Show:</b> -<select id="pickShow"> -<option value="0">-- Pick Show -- -#for $curShow in $sickbeard.showList: -<option value="$curShow.tvdbid" #if $curShow == $showObj then "SELECTED" else ""#>$curShow.name -#end for -</select><br /> -<br /> -<br /> -Change selected episodes to -<select id="statusSelect"> -#for $curStatus in [$WANTED, $SKIPPED, $ARCHIVED, $IGNORED] + $Quality.DOWNLOADED: -#if $curStatus == $DOWNLOADED: -#continue -#end if -<option value="$curStatus">$statusStrings[$curStatus] -#end for -</select> -<input type="button" id="changeStatus" value="Go"><br /> -<br /> -<b>NOTE:</b> Episodes can only be changed to a "Downloaded ..." status if they are already either "Downloaded ..." or "Snatched ..."<br /> -All other statuses will automatically update to the appropriate "Downloaded ..." status on a show refresh.<br /> - -#if $showObj: - -<h2><a href="$sbRoot/home/displayShow?show=$showObj.tvdbid">$showObj.name</a></h2> -<div> -<div align="right" class="checkboxControls"> -<span class="wanted">Wanted: <b>$epCounts[$Overview.WANTED]</b> <input type="checkbox" class="wanted" CHECKED></span> -<span class="qual">Low Quality: <b>$epCounts[$Overview.QUAL]</b> <input type="checkbox" class="qual" CHECKED></span> -<span class="good">Downloaded: <b>$epCounts[$Overview.GOOD]</b> <input type="checkbox" class="good"></span> -<span class="skipped">Skipped: <b>$epCounts[$Overview.SKIPPED]</b> <input type="checkbox" class="skipped"></span> -<br /> -<br /> -</div> -<table id="showTable-$showObj.tvdbid" class="sickbeardTable" cellspacing="1" border="0" cellpadding="0"> - <thead><tr><th width="1%"><input type="checkbox" id="checkAll"></th><th>Episode</th><th>Name</th><th>Status</th></tr></thead> - <tbody> - #for $curEp in $allEps: - #set $epStr = str($curEp["season"]) + "x" + str($curEp["episode"]) - <tr class="$Overview.overviewStrings[$epCats[$epStr]]"> - <td><input type="checkbox" id="$epStr" class="epCheck"></td> - <td>$curEp["season"] x $curEp["episode"]</td> - <td>$curEp["name"]</td> - <td>$statusStrings[int($curEp["status"])]</td> - </tr> - #end for - </tbody> -</table> -</div> - -#end if - -#include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_bottom.tmpl") \ No newline at end of file diff --git a/data/interfaces/default/manage_episodeStatuses.tmpl b/data/interfaces/default/manage_episodeStatuses.tmpl new file mode 100644 index 0000000000000000000000000000000000000000..ecb928096f988e5bf85d56dc772da7c526a10d59 --- /dev/null +++ b/data/interfaces/default/manage_episodeStatuses.tmpl @@ -0,0 +1,72 @@ +#import sickbeard +#import datetime +#from sickbeard import common +#set global $title="Episode Overview" + +#set global $sbPath=".." + +#set global $topmenu="manage"# +#import os.path +#include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_top.tmpl") + +#if not $whichStatus or ($whichStatus and not $ep_counts): + +#if $whichStatus: +<h2>None of your episodes have status $common.statusStrings[$int($whichStatus)]</h2> +<br /> +#end if + +<form action="$sbRoot/manage/episodeStatuses" method="GET"> +Manage episodes with status <select name="whichStatus"> +#for $curStatus in [$common.SKIPPED, $common.SNATCHED, $common.WANTED, $common.ARCHIVED, $common.IGNORED]: +<option value="$curStatus">$common.statusStrings[$curStatus]</option> +#end for +</select> +<input type="submit" value="Manage"> +</form> + +#else + +<script type="text/javascript" src="$sbRoot/js/manageEpisodeStatuses.js"></script> + +<form action="$sbRoot/manage/changeEpisodeStatuses" method="POST"> +<input type="hidden" id="oldStatus" name="oldStatus" value="$whichStatus"> + +<h2>Shows containing $common.statusStrings[$int($whichStatus)] episodes</h2> + +<br/ > + +#if $whichStatus in ($common.ARCHIVED, $common.IGNORED, $common.SNATCHED): +#set $row_class = "good" +#else +#set $row_class = $common.Overview.overviewStrings[$whichStatus] +#end if +<input type="hidden" id="row_class" value="$row_class"> + +Set checked shows/episodes to <select name="newStatus"> +#set $statusList = [$common.SKIPPED, $common.WANTED, $common.ARCHIVED, $common.IGNORED] +#if $int($whichStatus) in $statusList +#$statusList.remove($int($whichStatus)) +#end if +#for $curStatus in $statusList: +<option value="$curStatus">$common.statusStrings[$curStatus]</option> +#end for +</select> +<input type="submit" value="Go"> +<br /> +<br /> +<br /> + +<table class="sickbeardTable" cellspacing="1" border="0" cellpadding="0"> +#for $cur_tvdb_id in $sorted_show_ids: + <tr id="$cur_tvdb_id"> + <th><input type="checkbox" class="allCheck" id="allCheck-$cur_tvdb_id" name="$cur_tvdb_id-all" checked></th> + <th colspan="2" style="width: 100%; text-align: left;"><a class="whitelink" href="$sbRoot/home/displayShow?show=$cur_tvdb_id">$show_names[$cur_tvdb_id]</a> ($ep_counts[$cur_tvdb_id]) <input type="button" class="get_more_eps" id="$cur_tvdb_id" value="Expand"></th> + </tr> +#end for +</table> +</form> + +#end if + +#include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_bottom.tmpl") \ No newline at end of file diff --git a/data/interfaces/default/manage_manageSearches.tmpl b/data/interfaces/default/manage_manageSearches.tmpl index afa5bfa94e71d0e04c6e3e52c5aeb82c0cd3b34a..9a3c157ebd1d87b31fa325ff99a8f11ddb5b4051 100644 --- a/data/interfaces/default/manage_manageSearches.tmpl +++ b/data/interfaces/default/manage_manageSearches.tmpl @@ -5,7 +5,7 @@ #set global $sbPath=".." -<!--#set global $topmenu="manage"#--> +#set global $topmenu="manage"# #import os.path #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_top.tmpl") diff --git a/data/interfaces/default/manage_massEdit.tmpl b/data/interfaces/default/manage_massEdit.tmpl index ba0dd6b2ab9c65b9635f6f292b7e6d2a31991fbb..492f4e89c60fe0089e928f15e597a5acb414be3c 100644 --- a/data/interfaces/default/manage_massEdit.tmpl +++ b/data/interfaces/default/manage_massEdit.tmpl @@ -6,22 +6,18 @@ #set global $sbPath=".." -<!--#set global $topmenu="manage"#--> +#set global $topmenu="manage"# #import os.path #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_top.tmpl") -#set $anyQualities, $bestQualities = $common.Quality.splitQuality(int($quality_value)) +#if $quality_value != None: +#set $initial_quality = int($quality_value) +#else: +#set $initial_quality = $common.SD +#end if +#set $anyQualities, $bestQualities = $common.Quality.splitQuality($initial_quality) <script type="text/javascript" src="$sbRoot/js/qualityChooser.js"></script> <script type="text/javascript" src="$sbRoot/js/massEdit.js"></script> -<style type="text/css"> -<!-- -.optionWrapper { width: 450px; margin-left: auto; margin-right: auto; padding: 6px 12px; } -.optionWrapper span.selectTitle { float: left; font-weight: 700; font-size: 1.2em; text-align: left; width: 225px; } -.optionWrapper div.selectChoices { float: left; width: 175px; margin-left: 25px; } -.optionWrapper br { clear: both; } ---> -</style> - <form action="massEditSubmit" method="post"> <input type="hidden" name="toEdit" value="$showList" /> @@ -30,11 +26,11 @@ #for $cur_dir in $root_dir_list: #set $cur_index = $root_dir_list.index($cur_dir) <div style="padding: 6px 0 3px 25px;"> - <input type="button" class="edit_root_dir" id="edit_root_dir_$cur_index" value="Edit"> + <input type="button" class="edit_root_dir" id="edit_root_dir_$cur_index" value="Edit" /> $cur_dir => <span id="display_new_root_dir_$cur_index">$cur_dir</span> </div> - <input type="hidden" name="orig_root_dir_$cur_index" value="$cur_dir"> - <input type="text" style="display: none" name="new_root_dir_$cur_index" id="new_root_dir_$cur_index" class="new_root_dir" value="$cur_dir"> + <input type="hidden" name="orig_root_dir_$cur_index" value="$cur_dir" /> + <input type="text" style="display: none" name="new_root_dir_$cur_index" id="new_root_dir_$cur_index" class="new_root_dir" value="$cur_dir" /> #end for </div> @@ -45,9 +41,9 @@ <select id="qualityPreset" name="quality_preset"> <option value="keep">< keep ></option> #set $selected = None - <option value="0">Custom + <option value="0" #if $quality_value != None and $quality_value not in $common.qualityPresets then "selected=\"selected\"" else ""#>Custom</option> #for $curPreset in sorted($common.qualityPresets): - <option value="$curPreset">$common.qualityPresetStrings[$curPreset] + <option value="$curPreset" #if $quality_value == $curPreset then "selected=\"selected\"" else ""#>$common.qualityPresetStrings[$curPreset]</option> #end for </select> </div><br /> @@ -58,7 +54,7 @@ #set $anyQualityList = filter(lambda x: x > $common.Quality.NONE, $common.Quality.qualityStrings) <select id="anyQualities" name="anyQualities" multiple="multiple" size="len($anyQualityList)"> #for $curQuality in sorted($anyQualityList): - <option value="$curQuality" #if $curQuality in $anyQualities then "SELECTED" else ""#>$common.Quality.qualityStrings[$curQuality] + <option value="$curQuality" #if $curQuality in $anyQualities then "selected=\"selected\"" else ""#>$common.Quality.qualityStrings[$curQuality]</option> #end for </select> </div> @@ -67,7 +63,7 @@ #set $bestQualityList = filter(lambda x: x > $common.Quality.SDTV, $common.Quality.qualityStrings) <select id="bestQualities" name="bestQualities" multiple="multiple" size="len($bestQualityList)"> #for $curQuality in sorted($bestQualityList): - <option value="$curQuality" #if $curQuality in $bestQualities then "SELECTED" else ""#>$common.Quality.qualityStrings[$curQuality] + <option value="$curQuality" #if $curQuality in $bestQualities then "selected=\"selected\"" else ""#>$common.Quality.qualityStrings[$curQuality]</option> #end for </select> </div> @@ -80,8 +76,8 @@ <div class="selectChoices"> <select id="edit_season_folders" name="season_folders"> <option value="keep">< keep ></option> - <option value="enable">enable</option> - <option value="disable">disable</option> + <option value="enable" #if $season_folders_value then "selected=\"selected\"" else ""#>enable</option> + <option value="disable" #if $season_folders_value == False then "selected=\"selected\"" else ""#>disable</option> </select> </div><br /> </div> @@ -91,8 +87,8 @@ <div class="selectChoices"> <select id="edit_paused" name="paused"> <option value="keep">< keep ></option> - <option value="enable">enable</option> - <option value="disable">disable</option> + <option value="enable" #if $paused_value then "selected=\"selected\"" else ""#>enable</option> + <option value="disable" #if $paused_value == False then "selected=\"selected\"" else ""#>disable</option> </select> </div><br /> </div> @@ -103,14 +99,16 @@ </div> <div class="optionWrapper" style="text-align: center;"> - <input type="submit" value="Submit"><br /> + <input type="submit" value="Submit" /><br /> </div> </form> <br /> <script type="text/javascript" charset="utf-8"> +<!-- jQuery('#location').fileBrowser({ title: 'Select Show Location' }); +//--> </script> #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_bottom.tmpl") diff --git a/data/interfaces/default/viewlogs.tmpl b/data/interfaces/default/viewlogs.tmpl index b5da92d8dd411f461cfd5e96b06704a762b9976c..6f596523a65e0662d4e6050b38e87561ba7798cc 100644 --- a/data/interfaces/default/viewlogs.tmpl +++ b/data/interfaces/default/viewlogs.tmpl @@ -6,17 +6,19 @@ #set global $sbPath = ".." -<!--#set global $topmenu="errorlogs"#--> +#set global $topmenu="errorlogs"# #import os.path #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_top.tmpl") -<script type="text/javascript"> +<script type="text/javascript" charset="utf-8"> +<!-- \$(document).ready(function(){ \$('#minLevel').change(function(){ url = 'viewlog?minLevel='+\$(this).val() window.location.href = url }); }); +//--> </script> <div class="h2footer align-right"><b>Minimum logging level to display:</b> <select name="minLevel" id="minLevel" style="margin-top: -5px;"> @@ -34,7 +36,9 @@ $logLines </div> <br /> <script type="text/javascript" charset="utf-8"> +<!-- setInterval(window.location.reload, 180000); // Refresh every 3 minutes +//--> </script> #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_bottom.tmpl") diff --git a/data/js/jquery.divgrow-1.3.1.min.js b/data/js/jquery.divgrow-1.3.1.min.js deleted file mode 100644 index fd08f7fa86e4eec61320e9301e1236783bfe4a0d..0000000000000000000000000000000000000000 --- a/data/js/jquery.divgrow-1.3.1.min.js +++ /dev/null @@ -1 +0,0 @@ -(function ($) { var divgrowid = 0; $.fn.divgrow = function (options) { var options = $.extend({}, { initialHeight: 100, moreText: "+ Show More", lessText: "- Show Less", speed: 1000, showBrackets: true }, options); return this.each(function () { divgrowid++; obj = $(this); var fullHeight = obj.height() + 10; obj.css('height', options.initialHeight).css('overflow', 'hidden'); if (options.showBrackets) { obj.after('<p class="divgrow-brackets">[…]</p><a href="#" class="divgrow-showmore' + " divgrow-obj-" + divgrowid + '"' + '></a>') } else { obj.after('<a href="#" class="divgrow-showmore' + " divgrow-obj-" + divgrowid + '"' + '></a>') } $("a.divgrow-showmore").html(options.moreText); $("." + "divgrow-obj-" + divgrowid).toggle(function () { $(this).prevAll("div:first").animate({ height: fullHeight + "px" }, options.speed, function () { if (options.showBrackets) { $(this).nextAll("p.divgrow-brackets:first").fadeOut() } $(this).nextAll("a.divgrow-showmore:first").html(options.lessText) }) }, function () { $(this).prevAll("div:first").stop(true, false).animate({ height: options.initialHeight }, options.speed, function () { if (options.showBrackets) { $(this).nextAll("p.divgrow-brackets:first").stop(true, false).fadeIn() } $(this).nextAll("a.divgrow-showmore:first").stop(true, false).html(options.moreText) }) }) }) } })(jQuery); \ No newline at end of file diff --git a/data/js/jquery.expand-1.3.8.js b/data/js/jquery.expand-1.3.8.js new file mode 100644 index 0000000000000000000000000000000000000000..f3165aa4119fc12e07939e1493a34552c8261570 --- /dev/null +++ b/data/js/jquery.expand-1.3.8.js @@ -0,0 +1,182 @@ +/* --------------------------------------------- +expandAll v.1.3.8 +http://www.adipalaz.com/experiments/jquery/expand.html +Requires: jQuery v1.3+ +Copyright (c) 2009 Adriana Palazova +Dual licensed under the MIT (http://www.adipalaz.com/docs/mit-license.txt) and GPL (http://www.adipalaz.com/docs/gpl-license.txt) licenses +------------------------------------------------ */ +(function($) { +$.fn.expandAll = function(options) { + var o = $.extend({}, $.fn.expandAll.defaults, options); + + return this.each(function(index) { + var $$ = $(this), $referent, $sw, $cllps, $tr, container, toggleTxt, toggleClass; + + // --- functions: + (o.switchPosition == 'before') ? ($.fn.findSibling = $.fn.prev, $.fn.insrt = $.fn.before) : ($.fn.findSibling = $.fn.next, $.fn.insrt = $.fn.after); + + // --- var container + if (this.id.length) { container = '#' + this.id; + } else if (this.className.length) { container = this.tagName.toLowerCase() + '.' + this.className.split(' ').join('.'); + } else { container = this.tagName.toLowerCase();} + + // --- var $referent + if (o.ref && $$.find(o.ref).length) { + (o.switchPosition == 'before') ? $referent = $$.find("'" + o.ref + ":first'") : $referent = $$.find("'" + o.ref + ":last'"); + } else { return; } + + // end the script if the length of the collapsible element isn't long enough. + if (o.cllpsLength && $$.closest(container).find(o.cllpsEl).text().length < o.cllpsLength) {$$.closest(container).find(o.cllpsEl).addClass('dont_touch'); return;} + + // --- if expandAll() claims initial state = hidden: + (o.initTxt == 'show') ? (toggleTxt = o.expTxt, toggleClass='') : (toggleTxt = o.cllpsTxt, toggleClass='open'); + if (o.state == 'hidden') { + $$.find(o.cllpsEl + ':not(.shown, .dont_touch)').hide().findSibling().find('> a.open').removeClass('open'); + } else { + $$.find(o.cllpsEl).show().findSibling().find('> a').addClass('open'); + } + + (o.oneSwitch) ? ($referent.insrt('<p class="switch"><a href="#" class="' + toggleClass + '">' + toggleTxt + '</a></p>')) : + ($referent.insrt('<p class="switch"><a href="#" class="">' + o.expTxt + '</a> | <a href="#" class="open">' + o.cllpsTxt + '</a></p>')); + + // --- var $sw, $cllps, $tr : + $sw = $referent.findSibling('p').find('a'); + $cllps = $$.closest(container).find(o.cllpsEl).not('.dont_touch'); + $tr = (o.trigger) ? $$.closest(container).find(o.trigger + ' > a') : $$.closest(container).find('.expand > a'); + + if (o.child) { + $$.find(o.cllpsEl + '.shown').show().findSibling().find('> a').addClass('open').text(o.cllpsTxt); + window.$vrbls = { kt1 : o.expTxt, kt2 : o.cllpsTxt }; + } + + var scrollElem; + (typeof scrollableElement == 'function') ? (scrollElem = scrollableElement('html', 'body')) : (scrollElem = 'html, body'); + + $sw.click(function() { + var $switch = $(this), + $c = $switch.closest(container).find(o.cllpsEl +':first'), + cOffset = $c.offset().top; + if (o.parent) { + var $swChildren = $switch.parent().nextAll().children('p.switch').find('a'); + kidTxt1 = $vrbls.kt1, kidTxt2 = $vrbls.kt2, + kidTxt = ($switch.text() == o.expTxt) ? kidTxt2 : kidTxt1; + $swChildren.text(kidTxt); + if ($switch.text() == o.expTxt) {$swChildren.addClass('open');} else {$swChildren.removeClass('open');} + } + if ($switch.text() == o.expTxt) { + if (o.oneSwitch) {$switch.text(o.cllpsTxt).attr('class', 'open');} + $tr.addClass('open'); + $cllps[o.showMethod](o.speed); + } else { + if (o.oneSwitch) {$switch.text(o.expTxt).attr('class', '');} + $tr.removeClass('open'); + if (o.speed == 0 || o.instantHide) {$cllps.hide();} else {$cllps[o.hideMethod](o.speed);} + if (o.scroll && cOffset < $(window).scrollTop()) {$(scrollElem).animate({scrollTop: cOffset},600);} + } + return false; + }); + /* ----------------------------------------------- + To save file size, feel free to remove the following code if you don't use the option: 'localLinks: true' + -------------------------------------------------- */ + if (o.localLinks) { + var localLink = $(container).find(o.localLinks); + if (localLink.length) { + // based on http://www.learningjquery.com/2007/10/improved-animated-scrolling-script-for-same-page-links: + $(localLink).click(function() { + var $target = $(this.hash); + $target = $target.length && $target || $('[name=' + this.hash.slice(1) + ']'); + if ($target.length) { + var tOffset = $target.offset().top; + $(scrollElem).animate({scrollTop: tOffset},600); + return false; + } + }); + } + } + /* ----------------------------------------------- + Feel free to remove the following function if you don't use the options: 'localLinks: true' or 'scroll: true' + -------------------------------------------------- */ + //http://www.learningjquery.com/2007/10/improved-animated-scrolling-script-for-same-page-links: + function scrollableElement(els) { + for (var i = 0, argLength = arguments.length; i < argLength; i++) { + var el = arguments[i], + $scrollElement = $(el); + if ($scrollElement.scrollTop() > 0) { + return el; + } else { + $scrollElement.scrollTop(1); + var isScrollable = $scrollElement.scrollTop() > 0; + $scrollElement.scrollTop(0); + if (isScrollable) { + return el; + } + } + }; + return []; + }; + /* --- end of the optional code --- */ +});}; +$.fn.expandAll.defaults = { + state : 'hidden', // If 'hidden', the collapsible elements are hidden by default, else they are expanded by default + initTxt : 'show', // 'show' - if the initial text of the switch is for expanding, 'hide' - if the initial text of the switch is for collapsing + expTxt : '[Expand All]', // the text of the switch for expanding + cllpsTxt : '[Collapse All]', // the text of the switch for collapsing + oneSwitch : true, // true or false - whether both [Expand All] and [Collapse All] are shown, or they swap + ref : '.expand', // the switch 'Expand All/Collapse All' is inserted in regards to the element specified by 'ref' + switchPosition: 'before', //'before' or 'after' - specifies the position of the switch 'Expand All/Collapse All' - before or after the collapsible element + scroll : false, // false or true. If true, the switch 'Expand All/Collapse All' will be dinamically repositioned to remain in view when the collapsible element closes + showMethod : 'slideDown', // 'show', 'slideDown', 'fadeIn', or custom + hideMethod : 'slideUp', // 'hide', 'slideUp', 'fadeOut', or custom + speed : 600, // the speed of the animation in m.s. or 'slow', 'normal', 'fast' + cllpsEl : '.collapse', // the collapsible element + trigger : '.expand', // if expandAll() is used in conjunction with toggle() - the elements that contain the trigger of the toggle effect on the individual collapsible sections + localLinks : null, // null or the selector of the same-page links to which we will apply a smooth-scroll function, e.g. 'a.to_top' + parent : false, // true, false + child : false, // true, false + cllpsLength : null, //null, {Number}. If {Number} (e.g. cllpsLength: 200) - if the number of characters inside the "collapsible element" is less than the given {Number}, the element will be visible all the time + instantHide : false // {true} fixes hiding content inside hidden elements +}; + +/* --------------------------------------------- +Toggler - http://www.adipalaz.com/experiments/jquery/expand.html +When using this script, please keep the above url intact. +*** Feel free to remove the Toggler script if you need only the plugin expandAll(). +------------------------------------------------ */ +$.fn.toggler = function(options) { + var o = $.extend({}, $.fn.toggler.defaults, options); + + var $this = $(this); + $this.wrapInner('<a style="display:block" href="#" title="Expand/Collapse" />'); + if (o.initShow) {$(o.initShow).addClass('shown');} + $this.next(o.cllpsEl + ':not(.shown)').hide(); + return this.each(function() { + var container; + (o.container) ? container = o.container : container = 'html'; + if ($this.next('div.shown').length) { $this.closest(container).find('.shown').show().prev().find('a').addClass('open'); } + $(this).click(function() { + $(this).find('a').toggleClass('open').end().next(o.cllpsEl)[o.method](o.speed); + return false; + }); +});}; +$.fn.toggler.defaults = { + cllpsEl : 'div.collapse', + method : 'slideToggle', + speed : 'slow', + container : '', //the common container of all groups with collapsible content (optional) + initShow : '.shown' //the initially expanded sections (optional) +}; +/* --------------------------------------------- +Feel free to remove any of the following functions if you don't need it. +------------------------------------------------ */ +$.fn.toggleHeight = function(speed, easing, callback) { + return this.animate({height: 'toggle'}, speed, easing, callback); +}; +//http://www.learningjquery.com/2008/02/simple-effects-plugins: +$.fn.fadeToggle = function(speed, easing, callback) { + return this.animate({opacity: 'toggle'}, speed, easing, callback); +}; +$.fn.slideFadeToggle = function(speed, easing, callback) { + return this.animate({opacity: 'toggle', height: 'toggle'}, speed, easing, callback); +}; +/* --- end of the optional code --- */ +})(jQuery); diff --git a/data/js/manageEpisodeStatuses.js b/data/js/manageEpisodeStatuses.js new file mode 100644 index 0000000000000000000000000000000000000000..48184bb388e32361427a3fb9219701da3df0a314 --- /dev/null +++ b/data/js/manageEpisodeStatuses.js @@ -0,0 +1,47 @@ +$(document).ready(function() { + + function make_row(tvdb_id, season, episode, name, checked) { + if (checked) + var checked = ' checked'; + else + var checked = ''; + + var row_class = $('#row_class').val(); + + var row = ''; + row += ' <tr class="'+row_class+'">'; + row += ' <td><input type="checkbox" class="'+tvdb_id+'-epcheck" name="'+tvdb_id+'-'+season+'x'+episode+'"'+checked+'></td>'; + row += ' <td>'+season+'x'+episode+'</td>'; + row += ' <td style="width: 100%">'+name+'</td>'; + row += ' </tr>' + + return row; + } + + $('.allCheck').click(function(){ + var tvdb_id = $(this).attr('id').split('-')[1]; + $('.'+tvdb_id+'-epcheck').attr('checked', $(this).attr('checked')); + }); + + $('.get_more_eps').click(function(){ + var cur_tvdb_id = $(this).attr('id'); + var checked = $('#allCheck-'+cur_tvdb_id).attr('checked'); + var last_row = $('tr#'+cur_tvdb_id); + + $.getJSON(sbRoot+'/manage/showEpisodeStatuses', + { + tvdb_id: cur_tvdb_id, + whichStatus: $('#oldStatus').val() + }, + function (data) { + $.each(data, function(season,eps){ + $.each(eps, function(episode, name) { + //alert(season+'x'+episode+': '+name); + last_row.after(make_row(cur_tvdb_id, season, episode, name, checked)); + }); + }); + }); + $(this).hide(); + }); + +}); \ No newline at end of file diff --git a/data/js/massUpdate.js b/data/js/massUpdate.js index e3364c92a90bbc6a7d282c553baa3c4a8f76d15d..4fa241d00587311fdbba9b8e7fc6a4612b515896 100644 --- a/data/js/massUpdate.js +++ b/data/js/massUpdate.js @@ -22,6 +22,7 @@ $(document).ready(function(){ var updateArr = new Array() var refreshArr = new Array() var renameArr = new Array() + var deleteArr = new Array() var metadataArr = new Array() $('.updateCheck').each(function() { @@ -41,6 +42,13 @@ $(document).ready(function(){ renameArr.push($(this).attr('id').split('-')[1]) } }); + + $('.deleteCheck').each(function() { + if (this.checked == true) { + deleteArr.push($(this).attr('id').split('-')[1]) + } + }); + /* $('.metadataCheck').each(function() { if (this.checked == true) { @@ -48,10 +56,10 @@ $(document).ready(function(){ } }); */ - if (updateArr.length+refreshArr.length+renameArr.length+metadataArr.length == 0) + if (updateArr.length+refreshArr.length+renameArr.length+deleteArr.length+metadataArr.length == 0) return false - url = 'massUpdate?toUpdate='+updateArr.join('|')+'&toRefresh='+refreshArr.join('|')+'&toRename='+renameArr.join('|')+'&toMetadata='+metadataArr.join('|') + url = 'massUpdate?toUpdate='+updateArr.join('|')+'&toRefresh='+refreshArr.join('|')+'&toRename='+renameArr.join('|')+'&toDelete='+deleteArr.join('|')+'&toMetadata='+metadataArr.join('|') window.location.href = url diff --git a/data/js/newShow.js b/data/js/newShow.js index b55d45a46825191aca0f9b37288497add2ecd5fd..7ba6cf7f59d5b79eb4fe8f81f55261f56eaae116 100644 --- a/data/js/newShow.js +++ b/data/js/newShow.js @@ -140,6 +140,8 @@ $(document).ready(function(){ sep_char = '/'; else if (root_dir_text.indexOf('\\') >= 0) sep_char = '\\'; + else + sep_char = ''; if (root_dir_text.substr(sample_text.length-1) != sep_char) root_dir_text += sep_char; diff --git a/data/js/tableClick.js b/data/js/tableClick.js new file mode 100644 index 0000000000000000000000000000000000000000..f60ba28aa99e984596a01ceee5e77d7079c6d2d0 --- /dev/null +++ b/data/js/tableClick.js @@ -0,0 +1,13 @@ +$(document).ready(function(){ + + $("table.sickbeardTable td").hover( + function() { $(this).find("a").parent().addClass("hover"); }, + function() { $(this).find("a").parent().removeClass("hover"); + } ); + + $("table.sickbeardTable td").click( function() { + var href = $(this).find("a").attr("href"); + if(href) { window.location = href; } + }); + +}); diff --git a/sickbeard/__init__.py b/sickbeard/__init__.py index 278f810c9bd038d4809a539ddd1c3f7f9f76d3a0..3266451cb4a5ecc14443f5ff331359c9761215e5 100644 --- a/sickbeard/__init__.py +++ b/sickbeard/__init__.py @@ -23,14 +23,14 @@ import webbrowser import sqlite3 import datetime import socket -import os, sys, subprocess +import os, sys, subprocess, re import urllib from threading import Lock # apparently py2exe won't build these unless they're imported somewhere from sickbeard import providers, metadata -from providers import ezrss, nzbs_org, nzbmatrix, tvbinz, nzbsrus, binreq, newznab, womble, newzbin +from providers import ezrss, nzbs_org, nzbmatrix, tvbinz, nzbsrus, newznab, womble, newzbin from sickbeard import searchCurrent, searchBacklog, showUpdater, versionChecker, properFinder, autoPostProcesser from sickbeard import helpers, db, exceptions, show_queue, search_queue, scheduler @@ -42,6 +42,8 @@ from sickbeard.databases import mainDB from lib.configobj import ConfigObj +invoked_command = None + SOCKET_TIMEOUT = 30 PID = None @@ -151,8 +153,6 @@ NZBS = False NZBS_UID = None NZBS_HASH = None -BINREQ = False - WOMBLE = False NZBSRUS = False @@ -327,7 +327,7 @@ def initialize(consoleLogging=True): NAMING_SHOW_NAME, NAMING_EP_TYPE, NAMING_MULTI_EP_TYPE, CACHE_DIR, TVDB_API_PARMS, \ RENAME_EPISODES, properFinderScheduler, PROVIDER_ORDER, autoPostProcesserScheduler, \ NAMING_EP_NAME, NAMING_SEP_TYPE, NAMING_USE_PERIODS, WOMBLE, \ - NZBSRUS, NZBSRUS_UID, NZBSRUS_HASH, BINREQ, NAMING_QUALITY, providerList, newznabProviderList, \ + NZBSRUS, NZBSRUS_UID, NZBSRUS_HASH, NAMING_QUALITY, providerList, newznabProviderList, \ NAMING_DATES, EXTRA_SCRIPTS, USE_TWITTER, TWITTER_USERNAME, TWITTER_PASSWORD, TWITTER_PREFIX, \ USE_NOTIFO, NOTIFO_USERNAME, NOTIFO_APISECRET, NOTIFO_NOTIFY_ONDOWNLOAD, NOTIFO_NOTIFY_ONSNATCH, \ USE_LIBNOTIFY, LIBNOTIFY_NOTIFY_ONSNATCH, LIBNOTIFY_NOTIFY_ONDOWNLOAD, \ @@ -379,6 +379,8 @@ def initialize(consoleLogging=True): CACHE_DIR = None ROOT_DIRS = check_setting_str(CFG, 'General', 'root_dirs', '') + if not re.match(r'\d+\|[^|]+(?:\|[^|]+)*', ROOT_DIRS): + ROOT_DIRS = '' proxies = urllib.getproxies() proxy_url = None @@ -462,8 +464,6 @@ def initialize(consoleLogging=True): NEWZBIN_USERNAME = check_setting_str(CFG, 'Newzbin', 'newzbin_username', '') NEWZBIN_PASSWORD = check_setting_str(CFG, 'Newzbin', 'newzbin_password', '') - BINREQ = bool(check_setting_int(CFG, 'Bin-Req', 'binreq', 1)) - WOMBLE = bool(check_setting_int(CFG, 'Womble', 'womble', 1)) SAB_USERNAME = check_setting_str(CFG, 'SABnzbd', 'sab_username', '') @@ -747,7 +747,6 @@ def halt (): def sig_handler(signum=None, frame=None): if type(signum) != type(None): logger.log(u"Signal %i caught, saving and exiting..." % int(signum)) - cherrypy.engine.exit() saveAndShutdown() @@ -797,6 +796,19 @@ def saveAndShutdown(restart=False): os._exit(0) +def invoke_command(to_call, *args, **kwargs): + def delegate(): + to_call(*args, **kwargs) + sickbeard.invoked_command = delegate + logger.log(u"Placed invoked command: "+repr(sickbeard.invoked_command)+" for "+repr(to_call)+" with "+repr(args)+" and "+repr(kwargs), logger.DEBUG) + +def invoke_restart(soft=True): + invoke_command(sickbeard.restart, soft=soft) + +def invoke_shutdown(): + invoke_command(sickbeard.saveAndShutdown) + + def restart(soft=True): if soft: @@ -897,9 +909,6 @@ def save_config(): new_config['Newzbin']['newzbin_username'] = NEWZBIN_USERNAME new_config['Newzbin']['newzbin_password'] = NEWZBIN_PASSWORD - new_config['Bin-Req'] = {} - new_config['Bin-Req']['binreq'] = int(BINREQ) - new_config['Womble'] = {} new_config['Womble']['womble'] = int(WOMBLE) diff --git a/sickbeard/common.py b/sickbeard/common.py index 2c1019361a69c715cebe18753874612bb8e5e7e2..57beeaaedd0492101a697c1ec816e9fd4e9b2a59 100644 --- a/sickbeard/common.py +++ b/sickbeard/common.py @@ -28,7 +28,7 @@ USER_AGENT = 'Sick Beard/alpha2-'+version.SICKBEARD_VERSION.replace(' ','-')+' ( mediaExtensions = ['avi', 'mkv', 'mpg', 'mpeg', 'wmv', 'ogm', 'mp4', 'iso', 'img', 'divx', 'm2ts', 'm4v', 'ts', 'flv', 'f4v', - 'mov', 'rmvb'] + 'mov', 'rmvb', 'vob'] ### Other constants MULTI_EP_RESULT = -1 @@ -132,9 +132,9 @@ class Quality: return Quality.HDTV elif checkName(["720p", "web.dl"], all) or checkName(["720p", "itunes", "h.?264"], all): return Quality.HDWEBDL - elif checkName(["720p", "bluray", "x264"], all): + elif checkName(["720p", "bluray", "x264"], all) or checkName(["720p", "hddvd", "x264"], all): return Quality.HDBLURAY - elif checkName(["1080p", "bluray", "x264"], all): + elif checkName(["1080p", "bluray", "x264"], all) or checkName(["1080p", "hddvd", "x264"], all): return Quality.FULLHDBLURAY else: return Quality.UNKNOWN @@ -142,9 +142,9 @@ class Quality: @staticmethod def assumeQuality(name): - if name.endswith(".avi"): + if name.lower().endswith(".avi"): return Quality.SDTV - elif name.endswith(".mkv"): + elif name.lower().endswith(".mkv"): return Quality.HDTV else: return Quality.UNKNOWN @@ -219,11 +219,11 @@ class StatusStrings: statusStrings = StatusStrings() class Overview: - SKIPPED = 1 - WANTED = 2 - QUAL = 3 + UNAIRED = UNAIRED # 1 + QUAL = 2 + WANTED = WANTED # 3 GOOD = 4 - UNAIRED = 5 + SKIPPED = SKIPPED # 5 overviewStrings = {SKIPPED: "skipped", WANTED: "wanted", @@ -287,6 +287,10 @@ sceneExceptions = {72546: ['CSI'], 189931: ['RBT (AU)'], 73255: ['House', 'House M D'], 73244: ['The Office (US)', 'The Office'], + 81386: ['Being Human', 'Being Human (UK)'], + 89991: ['Out of the Wild: The Alaskan Experiment', 'Out of the Wild: Venezuela'], + 222551: ['Only in America With Larry the Cable Guy', 'Only in America'], + 77733: ['Degrassi: The Next Generation', 'Degrassi TNG'], } countryList = {'Australia': 'AU', diff --git a/sickbeard/encodingKludge.py b/sickbeard/encodingKludge.py index 3bf14021ad1a0056e11a5622b10f6a879aed3a40..9debc5a09bad281fc3d5281c65277c064fdcc765 100644 --- a/sickbeard/encodingKludge.py +++ b/sickbeard/encodingKludge.py @@ -37,7 +37,7 @@ def ek(func, *args): if os.name == 'nt': result = func(*args) else: - result = func(*[x.encode(sickbeard.SYS_ENCODING) for x in args]) + result = func(*[x.encode(sickbeard.SYS_ENCODING) if type(x) in (str, unicode) else x for x in args]) if type(result) == list: return fixListEncodings(result) diff --git a/sickbeard/helpers.py b/sickbeard/helpers.py index b027936ff127784668733567b8176d905dafed42..bb4fcaadde6e69ff7d4275ffc31b732c461980ff 100644 --- a/sickbeard/helpers.py +++ b/sickbeard/helpers.py @@ -19,6 +19,7 @@ import StringIO, zlib, gzip import os.path, os +import stat import urllib, urllib2 import re import shutil @@ -406,6 +407,34 @@ def rename_file(old_path, new_name): return new_path +def chmodAsParent(childPath): + if os.name == 'nt' or os.name == 'ce': + return + + parentPath = ek.ek(os.path.dirname, childPath) + parentMode = stat.S_IMODE(os.stat(parentPath)[stat.ST_MODE]) + + if ek.ek(os.path.isfile, childPath): + childMode = readwriteBits(parentMode) + else: + childMode = parentMode + + try: + ek.ek(os.chmod, childPath, childMode) + logger.log(u"Setting permissions for %s to %o as parent directory has %o" % (childPath, childMode, parentMode), logger.DEBUG) + except OSError: + logger.log(u"Failed to set permission for %s to %o" % (childPath, childMode), logger.ERROR) + +def readwriteBits(currentMode): + newMode = 0 + + for bit in [stat.S_IRUSR, stat.S_IWUSR, stat.S_IRGRP, stat.S_IWGRP, stat.S_IROTH, stat.S_IWOTH]: + if currentMode & bit: + newMode += bit + + return newMode + + if __name__ == '__main__': import doctest doctest.testmod() diff --git a/sickbeard/metadata/generic.py b/sickbeard/metadata/generic.py index 23014668fe4163904218c781b4121655c23643ee..c31150a343d300f6227cc611ecabeec89fb222bb 100644 --- a/sickbeard/metadata/generic.py +++ b/sickbeard/metadata/generic.py @@ -291,6 +291,7 @@ class GenericMetadata(): if not ek.ek(os.path.isdir, nfo_file_dir): logger.log("Metadata dir didn't exist, creating it at "+nfo_file_dir, logger.DEBUG) ek.ek(os.makedirs, nfo_file_dir) + helpers.chmodAsParent(nfo_file_dir) logger.log(u"Writing show nfo file to "+nfo_file_path) @@ -298,6 +299,7 @@ class GenericMetadata(): data.write(nfo_file, encoding="utf-8") nfo_file.close() + helpers.chmodAsParent(nfo_file_path) except IOError, e: logger.log(u"Unable to write file to "+nfo_file_path+" - are you sure the folder is writable? "+str(e).decode('utf-8'), logger.ERROR) return False @@ -333,6 +335,7 @@ class GenericMetadata(): if not ek.ek(os.path.isdir, nfo_file_dir): logger.log("Metadata dir didn't exist, creating it at "+nfo_file_dir, logger.DEBUG) ek.ek(os.makedirs, nfo_file_dir) + helpers.chmodAsParent(nfo_file_dir) logger.log(u"Writing episode nfo file to "+nfo_file_path) @@ -340,6 +343,7 @@ class GenericMetadata(): data.write(nfo_file, encoding="utf-8") nfo_file.close() + helpers.chmodAsParent(nfo_file_path) except IOError, e: logger.log(u"Unable to write file to "+nfo_file_path+" - are you sure the folder is writable? "+str(e).decode('utf-8'), logger.ERROR) return False @@ -491,10 +495,12 @@ class GenericMetadata(): if not ek.ek(os.path.isdir, image_dir): logger.log("Metadata dir didn't exist, creating it at "+image_dir, logger.DEBUG) ek.ek(os.makedirs, image_dir) + helpers.chmodAsParent(image_dir) outFile = ek.ek(open, image_path, 'wb') outFile.write(image_data) outFile.close() + helpers.chmodAsParent(image_path) except IOError, e: logger.log(u"Unable to write image to "+image_path+" - are you sure the show folder is writable? "+str(e).decode('utf-8'), logger.ERROR) return False diff --git a/sickbeard/postProcessor.py b/sickbeard/postProcessor.py old mode 100644 new mode 100755 index 154d604eb2096c15e2eb5e5cb1ea414a7c5c1888..3ff63365af2b0fd3e75411119a4a7778f8619999 --- a/sickbeard/postProcessor.py +++ b/sickbeard/postProcessor.py @@ -110,6 +110,9 @@ class PostProcessor(object): file_path_list = [] base_name = file_path.rpartition('.')[0]+'.' + + # don't confuse glob with chars we didn't mean to use + base_name = re.sub(r'[\[\]\*\?]', r'\\\g<0>', base_name) for associated_file_path in ek.ek(glob.glob, base_name+'*'): # only list it if the only non-shared part is the extension @@ -120,15 +123,6 @@ class PostProcessor(object): return file_path_list - def _destination_file_name(self, new_name): - existing_extension = self.file_name.rpartition('.')[-1] - new_name = helpers.sanitizeFileName(new_name) - - if sickbeard.RENAME_EPISODES: - return new_name + '.' + existing_extension - else: - return self.file_name - def _delete(self, file_path, associated_files=False): if not file_path: @@ -147,82 +141,90 @@ class PostProcessor(object): self._log(u"Deleting file "+cur_file, logger.DEBUG) if ek.ek(os.path.isfile, cur_file): ek.ek(os.remove, cur_file) + + def _combined_file_operation (self, file_path, new_path, new_base_name, associated_files=False, action=None): + """ + file_path: The full path of the media file to copy + new_path: Destination path where we want to copy the file to + new_base_name: The base filename (no extension) to use during the copy. Use None to keep the same name. + associated_files: Boolean, whether we should copy similarly-named files too + action: function that takes an old path and new path and does an operation with them (move/copy) + """ + + if not action: + self._log(u"Must provide an action for the combined file operation", logger.ERROR) + return - def _rename(self, file_path, new_base_name, associated_files=False): - if associated_files: file_list = self._list_associated_files(file_path) else: file_list = [file_path] if not file_list: - self._log(u"There were no files associated with "+file_path+", not renaming anything", logger.DEBUG) + self._log(u"There were no files associated with "+file_path+", not moving anything", logger.DEBUG) return for cur_file_path in file_list: - # get the extension - cur_extension = cur_file_path.rpartition('.')[-1] - - # replace .nfo with .nfo-orig to avoid conflicts - if cur_extension == 'nfo': - cur_extension = 'nfo-orig' + cur_file_name = ek.ek(os.path.basename, cur_file_path) - new_path = ek.ek(os.path.join, ek.ek(os.path.dirname, cur_file_path), new_base_name+'.'+cur_extension) + # If new base name then convert name + if new_base_name: + # get the extension + cur_extension = cur_file_path.rpartition('.')[-1] - if ek.ek(os.path.abspath, cur_file_path) == ek.ek(os.path.abspath, new_path): - self._log(u"File "+cur_file_path+" is already named properly, no rename needed", logger.DEBUG) - continue + # replace .nfo with .nfo-orig to avoid conflicts + if cur_extension == 'nfo': + cur_extension = 'nfo-orig' + + new_file_name = new_base_name +'.' + cur_extension + else: + new_file_name = cur_file_name - self._log(u"Renaming file "+cur_file_path+" to "+new_path, logger.DEBUG) - ek.ek(os.rename, cur_file_path, new_path) - - def _move(self, file_path, new_path, associated_files=False): + new_file_path = ek.ek(os.path.join, new_path, new_file_name) - if associated_files: - file_list = self._list_associated_files(file_path) - else: - file_list = [file_path] - - if not file_list: - self._log(u"There were no files associated with "+file_path+", not moving anything", logger.DEBUG) - return - - for cur_file_path in file_list: + action(cur_file_path, new_file_path) + + def _move(self, file_path, new_path, new_base_name, associated_files=False): + """ + file_path: The full path of the media file to move + new_path: Destination path where we want to move the file to + new_base_name: The base filename (no extension) to use during the move. Use None to keep the same name. + associated_files: Boolean, whether we should move similarly-named files too + """ - cur_file_name = ek.ek(os.path.basename, cur_file_path) - new_file_path = ek.ek(os.path.join, new_path, cur_file_name) + def _int_move(cur_file_path, new_file_path): self._log(u"Moving file from "+cur_file_path+" to "+new_file_path, logger.DEBUG) try: helpers.moveFile(cur_file_path, new_file_path) + helpers.chmodAsParent(new_file_path) except (IOError, OSError), e: self._log("Unable to move file "+cur_file_path+" to "+new_file_path+": "+str(e).decode('utf-8'), logger.ERROR) raise e - def _copy(self, file_path, new_path, associated_files=False): - - if associated_files: - file_list = self._list_associated_files(file_path) - else: - file_list = [file_path] - - if not file_list: - self._log(u"There were no files associated with "+file_path+", not copying anything", logger.DEBUG) - return - - for cur_file_path in file_list: + self._combined_file_operation(file_path, new_path, new_base_name, associated_files, action=_int_move) + + def _copy(self, file_path, new_path, new_base_name, associated_files=False): + """ + file_path: The full path of the media file to copy + new_path: Destination path where we want to copy the file to + new_base_name: The base filename (no extension) to use during the copy. Use None to keep the same name. + associated_files: Boolean, whether we should copy similarly-named files too + """ - cur_file_name = ek.ek(os.path.basename, cur_file_path) - new_file_path = ek.ek(os.path.join, new_path, cur_file_name) + def _int_copy (cur_file_path, new_file_path): self._log(u"Copying file from "+cur_file_path+" to "+new_file_path, logger.DEBUG) try: helpers.copyFile(cur_file_path, new_file_path) + helpers.chmodAsParent(new_file_path) except (IOError, OSError), e: logger.log("Unable to copy file "+cur_file_path+" to "+new_file_path+": "+str(e).decode('utf-8'), logger.ERROR) raise e + self._combined_file_operation(file_path, new_path, new_base_name, associated_files, action=_int_copy) + def _find_ep_destination_folder(self, ep_obj): # if we're supposed to put it in a season folder then figure out what folder to use @@ -454,12 +456,16 @@ class PostProcessor(object): ltvdb_api_parms['language'] = tvdb_lang t = tvdb_api.Tvdb(**ltvdb_api_parms) - epObj = t[cur_tvdb_id].airedOn(episodes[0])[0] + epObj = t[tvdb_id].airedOn(episodes[0])[0] season = int(epObj["seasonnumber"]) episodes = [int(epObj["episodenumber"])] self._log(u"Got season "+str(season)+" episodes "+str(episodes), logger.DEBUG) except tvdb_exceptions.tvdb_episodenotfound, e: - self._log(u"Unable to find episode with date "+str(episodes[0])+u" for show "+str(cur_tvdb_id)+u", skipping", logger.DEBUG) + self._log(u"Unable to find episode with date "+str(episodes[0])+u" for show "+str(tvdb_id)+u", skipping", logger.DEBUG) + + # we don't want to leave dates in the episode list if we couldn't convert them to real episode numbers + episodes = [] + continue # if there's no season then we can hopefully just use 1 automatically @@ -629,20 +635,6 @@ class PostProcessor(object): else: self._log(u"This download is marked a priority download so I'm going to replace an existing file if I find one", logger.DEBUG) - # if renaming is turned on then rename the episode (and associated files, if necessary) - if sickbeard.RENAME_EPISODES: - new_file_name = helpers.sanitizeFileName(ep_obj.prettyName()) - try: - self._rename(self.file_path, new_file_name, sickbeard.MOVE_ASSOCIATED_FILES) - except OSError, IOError: - raise exceptions.PostProcessingFailed("Unable to rename the files") - - # remember the new name of the file - new_file_path = ek.ek(os.path.join, self.folder_path, new_file_name + '.' + self.file_name.rpartition('.')[-1]) - self._log(u"After renaming the new file path is "+new_file_path, logger.DEBUG) - else: - new_file_path = self.file_path - # delete the existing file (and company) for cur_ep in [ep_obj] + ep_obj.relatedEps: try: @@ -663,23 +655,40 @@ class PostProcessor(object): self._log(u"Season folder didn't exist, creating it", logger.DEBUG) try: ek.ek(os.mkdir, dest_path) + helpers.chmodAsParent(dest_path) except OSError, IOError: raise exceptions.PostProcessingFailed("Unable to create the episode's destination folder: "+dest_path) + # update the statuses before we rename so the quality goes into the name properly + for cur_ep in [ep_obj] + ep_obj.relatedEps: + with cur_ep.lock: + cur_ep.status = common.Quality.compositeStatus(common.DOWNLOADED, new_ep_quality) + cur_ep.saveToDB() + + # figure out the base name of the resulting episode file + if sickbeard.RENAME_EPISODES: + orig_extension = self.file_name.rpartition('.')[-1] + new_base_name = helpers.sanitizeFileName(ep_obj.prettyName()) + new_file_name = new_base_name + '.' + orig_extension + + else: + # if we're not renaming then there's no new base name, we'll just use the existing name + new_base_name = None + new_file_name = self.file_name + try: - # move the episode to the show dir + # move the episode and associated files to the show dir if sickbeard.KEEP_PROCESSED_DIR: - self._copy(new_file_path, dest_path, sickbeard.MOVE_ASSOCIATED_FILES) + self._copy(self.file_path, dest_path, new_base_name, sickbeard.MOVE_ASSOCIATED_FILES) else: - self._move(new_file_path, dest_path, sickbeard.MOVE_ASSOCIATED_FILES) + self._move(self.file_path, dest_path, new_base_name, sickbeard.MOVE_ASSOCIATED_FILES) except OSError, IOError: raise exceptions.PostProcessingFailed("Unable to move the files to their new home") - # update the statuses before we rename so the quality goes into the name properly + # put the new location in the database for cur_ep in [ep_obj] + ep_obj.relatedEps: with cur_ep.lock: - cur_ep.location = ek.ek(os.path.join, dest_path, self._destination_file_name(ep_obj.prettyName())) - cur_ep.status = common.Quality.compositeStatus(common.DOWNLOADED, new_ep_quality) + cur_ep.location = ek.ek(os.path.join, dest_path, new_file_name) cur_ep.saveToDB() # log it to history diff --git a/sickbeard/providers/__init__.py b/sickbeard/providers/__init__.py index c1afecd45758c95c77a69d0aae4a4b4e671c171c..8242fbe89e61a71e2744bb09ccf57dfae40b6ca7 100644 --- a/sickbeard/providers/__init__.py +++ b/sickbeard/providers/__init__.py @@ -3,7 +3,6 @@ __all__ = ['ezrss', 'nzbs_org', 'tvbinz', 'nzbsrus', - 'binreq', 'womble', 'newzbin', ] diff --git a/sickbeard/providers/binreq.py b/sickbeard/providers/binreq.py deleted file mode 100644 index 7e6ce4e36b75466d4c66df676525dce3eee1ace3..0000000000000000000000000000000000000000 --- a/sickbeard/providers/binreq.py +++ /dev/null @@ -1,73 +0,0 @@ -# Author: Nic Wolfe <nic@wolfeden.ca> -# URL: http://code.google.com/p/sickbeard/ -# -# This file is part of Sick Beard. -# -# Sick Beard is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Sick Beard is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Sick Beard. If not, see <http://www.gnu.org/licenses/>. - - - -import urllib - -import sickbeard -import generic - -from sickbeard import logger - -from sickbeard.common import * -from sickbeard import tvcache - -class BinReqProvider(generic.NZBProvider): - - def __init__(self): - - generic.NZBProvider.__init__(self, "Bin-Req") - - self.cache = BinReqCache(self) - - self.url = 'http://www.bin-req.net/' - - def isEnabled(self): - return sickbeard.BINREQ - - -class BinReqCache(tvcache.TVCache): - - def __init__(self, provider): - - tvcache.TVCache.__init__(self, provider) - - # only poll Bin-Req every 15 minutes max - self.minTime = 15 - - def _getRSSData(self): - url = self.provider.url + 'rss.php?' - urlArgs = {'id': 3} - - url += urllib.urlencode(urlArgs) - - logger.log(u"Bin-Req cache update URL: "+ url, logger.DEBUG) - - data = self.provider.getURL(url) - - return data - - def _checkAuth(self, data): - return data != 'Invalid Link' - - def _translateLinkURL(self, url): - return url.replace('&','&').replace('view.php', 'download.php') - - -provider = BinReqProvider() \ No newline at end of file diff --git a/sickbeard/providers/ezrss.py b/sickbeard/providers/ezrss.py index 83d584f013c5db92ab8504c6a5fab8408d64dc34..29cc174424ad538ed8b3be0374aa7d30c49916f3 100644 --- a/sickbeard/providers/ezrss.py +++ b/sickbeard/providers/ezrss.py @@ -54,7 +54,7 @@ class EZRSSProvider(generic.TorrentProvider): if not show: return params - params['show_name'] = sceneHelpers.sanitizeSceneName(show.name).replace('.',' ') + params['show_name'] = sceneHelpers.sanitizeSceneName(show.name).replace('.',' ').encode('utf-8') if season != None: params['season'] = season @@ -68,7 +68,7 @@ class EZRSSProvider(generic.TorrentProvider): if not ep_obj: return params - params['show_name'] = sceneHelpers.sanitizeSceneName(ep_obj.show.name).replace('.',' ') + params['show_name'] = sceneHelpers.sanitizeSceneName(ep_obj.show.name).replace('.',' ').encode('utf-8') if ep_obj.show.is_air_by_date: params['date'] = str(ep_obj.airdate) @@ -78,7 +78,7 @@ class EZRSSProvider(generic.TorrentProvider): return [params] - def _doSearch(self, search_params): + def _doSearch(self, search_params, show=None): params = {"mode": "rss"} diff --git a/sickbeard/providers/generic.py b/sickbeard/providers/generic.py index d18258790ae0dd36b625ab6ec18d2e3af787323c..cbce6ba235f9b393a60360ef6c843fc4e54e015c 100644 --- a/sickbeard/providers/generic.py +++ b/sickbeard/providers/generic.py @@ -167,7 +167,9 @@ class GenericProvider: def _get_title_and_url(self, item): title = item.findtext('title') - url = item.findtext('link').replace('&','&') + url = item.findtext('link') + if url: + url = url.replace('&','&') return (title, url) @@ -190,7 +192,7 @@ class GenericProvider: itemList = [] for cur_search_string in self._get_episode_search_strings(episode): - itemList += self._doSearch(cur_search_string) + itemList += self._doSearch(cur_search_string, show=episode.show) for item in itemList: diff --git a/sickbeard/providers/newzbin.py b/sickbeard/providers/newzbin.py index 5a0af4758769e3dbcb5dcba0b03f6542e87f2c82..5622859abfe9f6a98184b6ee2ca76ad4102fd352 100644 --- a/sickbeard/providers/newzbin.py +++ b/sickbeard/providers/newzbin.py @@ -263,7 +263,7 @@ class NewzbinProvider(generic.NZBProvider): searchStr = " OR ".join(['^"'+x+' - '+str(ep_obj.airdate)+'"' for x in nameList]) return [searchStr] - def _doSearch(self, searchStr): + def _doSearch(self, searchStr, show=None): data = self._getRSSData(searchStr.encode('utf-8')) diff --git a/sickbeard/providers/newznab.py b/sickbeard/providers/newznab.py index b79b4c17a3bca8c0036d8be0851b71359dfa95dc..b43df70f4bb3967c805fcc83512b15fc7f9b8d4a 100644 --- a/sickbeard/providers/newznab.py +++ b/sickbeard/providers/newznab.py @@ -116,7 +116,7 @@ class NewznabProvider(generic.NZBProvider): return self._doSearch({'q': search_string}) #def _doSearch(self, show, season=None, episode=None, search=None): - def _doSearch(self, search_params): + def _doSearch(self, search_params, show=None): params = {"t": "tvsearch", "maxage": sickbeard.USENET_RETENTION, diff --git a/sickbeard/providers/nzbmatrix.py b/sickbeard/providers/nzbmatrix.py index 05feca247f9b0ea20fa5be67962b097860720af7..d8a5563198e3314bbd4e4fbb3fa72b5908c7bc44 100644 --- a/sickbeard/providers/nzbmatrix.py +++ b/sickbeard/providers/nzbmatrix.py @@ -58,7 +58,7 @@ class NZBMatrixProvider(generic.NZBProvider): # search for all show names and episode numbers like ("a","b","c") in a single search return ['("' + '","'.join(sceneSearchStrings) + '")'] - def _doSearch(self, curString, quotes=False): + def _doSearch(self, curString, quotes=False, show=None): term = re.sub('[\.\-]', ' ', curString).encode('utf-8') if quotes: @@ -71,7 +71,12 @@ class NZBMatrixProvider(generic.NZBProvider): "apikey": sickbeard.NZBMATRIX_APIKEY, "subcat": "6,41", "english": 1, - "ssl": 1} + "ssl": 1, + "scenename": 1} + + # if the show is a documentary use those cats on nzbmatrix + if show and show.genre and 'documentary' in show.genre.lower(): + params['subcat'] = params['subcat'] + ',53,9' searchURL = "http://rss.nzbmatrix.com/rss.php?" + urllib.urlencode(params) diff --git a/sickbeard/providers/nzbs_org.py b/sickbeard/providers/nzbs_org.py index cfd1fcaeec114878984c8004415a30d9ea6066a1..1d9914c97039e844f43f83f6deb5c2592a2d3d13 100644 --- a/sickbeard/providers/nzbs_org.py +++ b/sickbeard/providers/nzbs_org.py @@ -58,7 +58,7 @@ class NZBsProvider(generic.NZBProvider): def _get_episode_search_strings(self, ep_obj): return ['^'+x for x in sceneHelpers.makeSceneSearchString(ep_obj)] - def _doSearch(self, curString): + def _doSearch(self, curString, show=None): curString = curString.replace('.', ' ').replace('-', '.') diff --git a/sickbeard/sceneHelpers.py b/sickbeard/sceneHelpers.py index e32bb3acb510b0f300c6430b3770ede4f60724fc..0ef745b3e489101a61125c7875e5a18ea71561ec 100644 --- a/sickbeard/sceneHelpers.py +++ b/sickbeard/sceneHelpers.py @@ -27,7 +27,7 @@ from name_parser.parser import NameParser, InvalidNameException resultFilters = ("sub(pack|s|bed)", "nlsub(bed|s)?", "swesub(bed)?", "(dir|sample|nfo)fix", "sample", "(dvd)?extras", - "dubbed", "german", "french", "core2hd") + "dub(bed)?", "german", "french", "core2hd") def filterBadReleases(name): diff --git a/sickbeard/show_queue.py b/sickbeard/show_queue.py index f074937c03ec047d56390f8f50e2254cbe188b0b..83785fd636af22f119d9571c76482af3b41852be 100644 --- a/sickbeard/show_queue.py +++ b/sickbeard/show_queue.py @@ -276,7 +276,7 @@ class QueueItemAdd(ShowQueueItem): if self.default_status != SKIPPED: logger.log(u"Setting all episodes to the specified default status: "+str(self.default_status)) myDB = db.DBConnection(); - myDB.action("UPDATE tv_episodes SET status = ? WHERE status = ? AND showid = ?", [self.default_status, SKIPPED, self.show.tvdbid]) + myDB.action("UPDATE tv_episodes SET status = ? WHERE status = ? AND showid = ? AND season != 0", [self.default_status, SKIPPED, self.show.tvdbid]) # if they started with WANTED eps then run the backlog if self.default_status == WANTED: diff --git a/sickbeard/tv.py b/sickbeard/tv.py index a14777662ada8a47de60f259c49c8ceb928c6370..a2f337ad49ceb4f0b1d0cc1c69c0d7f6d7839bf2 100644 --- a/sickbeard/tv.py +++ b/sickbeard/tv.py @@ -184,7 +184,7 @@ class TVShow(object): # find all media files in the show folder and create episodes for as many as possible def loadEpisodesFromDir (self): - if not os.path.isdir(self._location): + if not ek.ek(os.path.isdir, self._location): logger.log(str(self.tvdbid) + ": Show dir doesn't exist, not loading episodes from disk") return diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py index 7726882d5f65fd4d098b4d2e6f0d128a4d87c5f8..3501c5a997c4ef7f85266378ec61bba8bdbe2dba 100644 --- a/sickbeard/webserve.py +++ b/sickbeard/webserve.py @@ -129,7 +129,7 @@ def _getEpisode(show, season, episode): ManageMenu = [ { 'title': 'Backlog Overview', 'path': 'manage/backlogOverview' }, { 'title': 'Manage Searches', 'path': 'manage/manageSearches' }, - #{ 'title': 'Episode Overview', 'path': 'manage/episodeOverview' }, + { 'title': 'Episode Status Management', 'path': 'manage/episodeStatuses' }, ] class ManageSearches: @@ -188,6 +188,105 @@ class Manage: t.submenu = ManageMenu return _munge(t) + @cherrypy.expose + def showEpisodeStatuses(self, tvdb_id, whichStatus): + myDB = db.DBConnection() + + status_list = [int(whichStatus)] + if status_list[0] == SNATCHED: + status_list = Quality.SNATCHED + Quality.SNATCHED_PROPER + + cur_show_results = myDB.select("SELECT season, episode, name FROM tv_episodes WHERE showid = ? AND season != 0 AND status IN ("+','.join(['?']*len(status_list))+")", [int(tvdb_id)] + status_list) + + result = {} + for cur_result in cur_show_results: + cur_season = int(cur_result["season"]) + cur_episode = int(cur_result["episode"]) + + if cur_season not in result: + result[cur_season] = {} + + result[cur_season][cur_episode] = cur_result["name"] + + return json.dumps(result) + + @cherrypy.expose + def episodeStatuses(self, whichStatus=None): + + if whichStatus: + whichStatus = int(whichStatus) + status_list = [whichStatus] + if status_list[0] == SNATCHED: + status_list = Quality.SNATCHED + Quality.SNATCHED_PROPER + else: + status_list = [] + + t = PageTemplate(file="manage_episodeStatuses.tmpl") + t.submenu = ManageMenu + t.whichStatus = whichStatus + + # if we have no status then this is as far as we need to go + if not status_list: + return _munge(t) + + myDB = db.DBConnection() + status_results = myDB.select("SELECT show_name, tv_shows.tvdb_id as tvdb_id FROM tv_episodes, tv_shows WHERE tv_episodes.status IN ("+','.join(['?']*len(status_list))+") AND season != 0 AND tv_episodes.showid = tv_shows.tvdb_id ORDER BY show_name", status_list) + + ep_counts = {} + show_names = {} + sorted_show_ids = [] + for cur_status_result in status_results: + cur_tvdb_id = int(cur_status_result["tvdb_id"]) + if cur_tvdb_id not in ep_counts: + ep_counts[cur_tvdb_id] = 1 + else: + ep_counts[cur_tvdb_id] += 1 + + show_names[cur_tvdb_id] = cur_status_result["show_name"] + if cur_tvdb_id not in sorted_show_ids: + sorted_show_ids.append(cur_tvdb_id) + + t.show_names = show_names + t.ep_counts = ep_counts + t.sorted_show_ids = sorted_show_ids + return _munge(t) + + @cherrypy.expose + def changeEpisodeStatuses(self, oldStatus, newStatus, *args, **kwargs): + + status_list = [int(oldStatus)] + if status_list[0] == SNATCHED: + status_list = Quality.SNATCHED + Quality.SNATCHED_PROPER + + to_change = {} + + # make a list of all shows and their associated args + for arg in kwargs: + tvdb_id, what = arg.split('-') + + # we don't care about unchecked checkboxes + if kwargs[arg] != 'on': + continue + + if tvdb_id not in to_change: + to_change[tvdb_id] = [] + + to_change[tvdb_id].append(what) + + myDB = db.DBConnection() + + for cur_tvdb_id in to_change: + + # get a list of all the eps we want to change if they just said "all" + if 'all' in to_change[cur_tvdb_id]: + all_eps_results = myDB.select("SELECT season, episode FROM tv_episodes WHERE status IN ("+','.join(['?']*len(status_list))+") AND season != 0 AND showid = ?", status_list + [cur_tvdb_id]) + all_eps = [str(x["season"])+'x'+str(x["episode"]) for x in all_eps_results] + to_change[cur_tvdb_id] = all_eps + + result = Home().setStatus(cur_tvdb_id, '|'.join(to_change[cur_tvdb_id]), newStatus, direct=True) + + redirect('/manage/episodeStatuses') + @cherrypy.expose def backlogShow(self, tvdb_id): @@ -255,13 +354,13 @@ class Manage: if showObj: showList.append(showObj) - use_season_folders = True + season_folders_all_same = True last_season_folders = None - use_paused = True + paused_all_same = True last_paused = None - use_quality = True + quality_all_same = True last_quality = None root_dir_list = [] @@ -272,28 +371,30 @@ class Manage: if cur_root_dir not in root_dir_list: root_dir_list.append(cur_root_dir) - if use_paused: - if last_paused == None: + # if we know they're not all the same then no point even bothering + if paused_all_same: + # if we had a value already and this value is different then they're not all the same + if last_paused not in (curShow.paused, None): + paused_all_same = False + else: last_paused = curShow.paused - elif last_paused != curShow.paused: - use_paused = True - if use_season_folders: - if last_season_folders == None: + if season_folders_all_same: + if last_season_folders not in (None, curShow.seasonfolders): + season_folders_all_same = False + else: last_season_folders = curShow.seasonfolders - elif last_season_folders != curShow.seasonfolders: - use_season_folders = True - if use_quality: - if last_quality == None: + if quality_all_same: + if last_quality not in (None, curShow.quality): + quality_all_same = False + else: last_quality = curShow.quality - elif last_quality != curShow.quality: - use_quality = True t.showList = toEdit - t.paused_value = last_paused if use_paused else False - t.season_folders_value = last_season_folders if use_season_folders else False - t.quality_value = last_quality if use_quality else SD + t.paused_value = last_paused if paused_all_same else None + t.season_folders_value = last_season_folders if season_folders_all_same else None + t.quality_value = last_quality if quality_all_same else None t.root_dir_list = root_dir_list return _munge(t) @@ -329,13 +430,14 @@ class Manage: if paused == 'keep': new_paused = showObj.paused else: - new_paused = 'on' if paused == 'enable' else 'off' - logger.log(str(paused)+" so "+str(new_paused)) + new_paused = True if paused == 'enable' else False + new_paused = 'on' if new_paused else 'off' if season_folders == 'keep': new_season_folders = showObj.seasonfolders else: - new_season_folders = 'on' if season_folders == 'enable' else 'off' + new_season_folders = True if season_folders == 'enable' else False + new_season_folders = 'on' if new_season_folders else 'off' if quality_preset == 'keep': anyQualities, bestQualities = Quality.splitQuality(showObj.quality) @@ -343,7 +445,7 @@ class Manage: curErrors += Home().editShow(curShow, new_show_dir, anyQualities, bestQualities, new_season_folders, new_paused, directCall=True) if curErrors: - logger.log(u"Errors: "+str(curErrors)) + logger.log(u"Errors: "+str(curErrors), logger.ERROR) errors.append('<b>%s:</b><br />\n<ul>' % showObj.name + '\n'.join(['<li>%s</li>' % error for error in curErrors]) + "</ul>") if len(errors) > 0: @@ -353,7 +455,7 @@ class Manage: redirect("/manage") @cherrypy.expose - def massUpdate(self, toUpdate=None, toRefresh=None, toRename=None, toMetadata=None): + def massUpdate(self, toUpdate=None, toRefresh=None, toRename=None, toDelete=None, toMetadata=None): if toUpdate != None: toUpdate = toUpdate.split('|') @@ -370,6 +472,11 @@ class Manage: else: toRename = [] + if toDelete != None: + toDelete = toDelete.split('|') + else: + toDelete = [] + if toMetadata != None: toMetadata = toMetadata.split('|') else: @@ -380,7 +487,7 @@ class Manage: updates = [] renames = [] - for curShowID in set(toUpdate+toRefresh+toRename+toMetadata): + for curShowID in set(toUpdate+toRefresh+toRename+toDelete+toMetadata): if curShowID == '': continue @@ -390,6 +497,11 @@ class Manage: if showObj == None: continue + if curShowID in toDelete: + showObj.deleteShow() + # don't do anything else if it's being deleted + continue + if curShowID in toUpdate: try: sickbeard.showQueueScheduler.action.updateShow(showObj, True) @@ -397,6 +509,7 @@ class Manage: except exceptions.CantUpdateException, e: errors.append("Unable to update show "+showObj.name+": "+str(e).decode('utf-8')) + # don't bother refreshing shows that were updated anyway if curShowID in toRefresh and curShowID not in toUpdate: try: sickbeard.showQueueScheduler.action.refreshShow(showObj) @@ -408,7 +521,6 @@ class Manage: sickbeard.showQueueScheduler.action.renameShowEpisodes(showObj) renames.append(showObj.name) - if len(errors) > 0: ui.flash.error("Errors encountered", '<br >\n'.join(errors)) @@ -416,22 +528,22 @@ class Manage: messageDetail = "" if len(updates) > 0: - messageDetail += "<b>Updates</b><br />\n<ul>\n<li>" - messageDetail += "</li>\n<li>".join(updates) - messageDetail += "</li>\n</ul>\n<br />" + messageDetail += "<br /><b>Updates</b><br /><ul><li>" + messageDetail += "</li><li>".join(updates) + messageDetail += "</li></ul>" if len(refreshes) > 0: - messageDetail += "<b>Refreshes</b><br />\n<ul>\n<li>" - messageDetail += "</li>\n<li>".join(refreshes) - messageDetail += "</li>\n</ul>\n<br />" + messageDetail += "<br /><b>Refreshes</b><br /><ul><li>" + messageDetail += "</li><li>".join(refreshes) + messageDetail += "</li></ul>" if len(renames) > 0: - messageDetail += "<b>Renames</b><br />\n<ul>\n<li>" - messageDetail += "</li>\n<li>".join(renames) - messageDetail += "</li>\n</ul>\n<br />" + messageDetail += "<br /><b>Renames</b><br /><ul><li>" + messageDetail += "</li><li>".join(renames) + messageDetail += "</li></ul>" if len(updates+refreshes+renames) > 0: - ui.flash.message("The following actions were queued:<br /><br />", + ui.flash.message("The following actions were queued:", messageDetail) redirect("/manage") @@ -1400,6 +1512,8 @@ class NewHomeAddShows: logger.log(u"Unable to create the folder "+show_dir+", can't add the show", logger.ERROR) ui.flash.error("Unable to add show", "Unable to create the folder "+show_dir+", can't add the show") redirect("/home") + else: + helpers.chmodAsParent(show_dir) # prepare the inputs for passing along if seasonFolders == "on": @@ -1665,7 +1779,7 @@ class Home: @cherrypy.expose def shutdown(self): - threading.Timer(2, sickbeard.saveAndShutdown).start() + threading.Timer(2, sickbeard.invoke_shutdown).start() title = "Shutting down" message = "Sick Beard is shutting down..." @@ -1679,7 +1793,7 @@ class Home: redirect("/home") # do a soft restart - threading.Timer(2, sickbeard.restart, [False]).start() + threading.Timer(2, sickbeard.invoke_restart, [False]).start() title = "Restarting" message = "Sick Beard is restarting, refresh in 30 seconds." @@ -1696,7 +1810,7 @@ class Home: if updated: # do a hard restart - threading.Timer(2, sickbeard.restart, [False]).start() + threading.Timer(2, sickbeard.invoke_restart, [False]).start() return "Sick Beard is restarting, refresh in 30 seconds." else: return _genericMessage("Update Failed","Update wasn't successful, not restarting. Check your log for more information.") @@ -1752,7 +1866,7 @@ class Home: if not sickbeard.showQueueScheduler.action.isBeingUpdated(showObj): t.submenu.append({ 'title': 'Delete', 'path': 'home/deleteShow?show=%d'%showObj.tvdbid, 'confirm': True }) t.submenu.append({ 'title': 'Re-scan files', 'path': 'home/refreshShow?show=%d'%showObj.tvdbid }) - t.submenu.append({ 'title': 'Force Full Update', 'path': 'home/updateShow?show=%d&force=1'%showObj.tvdbid }) + t.submenu.append({ 'title': 'Force Full Update', 'path': 'home/updateShow?show=%d&force=1'%showObj.tvdbid }) t.submenu.append({ 'title': 'Update show in XBMC', 'path': 'home/updateXBMC?showName=%s'%urllib.quote_plus(showObj.name.encode('utf-8')), 'requires': haveXBMC }) t.submenu.append({ 'title': 'Rename Episodes', 'path': 'home/fixEpisodeNames?show=%d'%showObj.tvdbid, 'confirm': True }) @@ -2217,14 +2331,15 @@ class WebInterface: recently = (datetime.date.today() - datetime.timedelta(days=3)).toordinal() done_show_list = [] - sql_results = myDB.select("SELECT *, tv_shows.status as show_status FROM tv_episodes, tv_shows WHERE season != 0 AND airdate >= ? AND airdate < ? AND tv_shows.tvdb_id = tv_episodes.showid AND tv_episodes.status NOT IN ("+','.join(['?']*len(Quality.DOWNLOADED+Quality.SNATCHED))+")", [today, next_week] + Quality.DOWNLOADED + Quality.SNATCHED) + qualList = Quality.DOWNLOADED + Quality.SNATCHED + [ARCHIVED, IGNORED] + sql_results = myDB.select("SELECT *, tv_shows.status as show_status FROM tv_episodes, tv_shows WHERE season != 0 AND airdate >= ? AND airdate < ? AND tv_shows.tvdb_id = tv_episodes.showid AND tv_episodes.status NOT IN ("+','.join(['?']*len(qualList))+")", [today, next_week] + qualList) for cur_result in sql_results: done_show_list.append(int(cur_result["showid"])) more_sql_results = myDB.select("SELECT *, tv_shows.status as show_status FROM tv_episodes outer_eps, tv_shows WHERE season != 0 AND showid NOT IN ("+','.join(['?']*len(done_show_list))+") AND tv_shows.tvdb_id = outer_eps.showid AND airdate = (SELECT airdate FROM tv_episodes inner_eps WHERE inner_eps.showid = outer_eps.showid AND inner_eps.airdate >= ? ORDER BY inner_eps.airdate ASC LIMIT 1) AND outer_eps.status NOT IN ("+','.join(['?']*len(Quality.DOWNLOADED+Quality.SNATCHED))+")", done_show_list + [next_week] + Quality.DOWNLOADED + Quality.SNATCHED) sql_results += more_sql_results - more_sql_results = myDB.select("SELECT *, tv_shows.status as show_status FROM tv_episodes, tv_shows WHERE season != 0 AND tv_shows.tvdb_id = tv_episodes.showid AND airdate < ? AND airdate >= ? AND tv_episodes.status = ? AND tv_episodes.status NOT IN ("+','.join(['?']*len(Quality.DOWNLOADED+Quality.SNATCHED))+")", [today, recently, WANTED] + Quality.DOWNLOADED + Quality.SNATCHED) + more_sql_results = myDB.select("SELECT *, tv_shows.status as show_status FROM tv_episodes, tv_shows WHERE season != 0 AND tv_shows.tvdb_id = tv_episodes.showid AND airdate < ? AND airdate >= ? AND tv_episodes.status = ? AND tv_episodes.status NOT IN ("+','.join(['?']*len(qualList))+")", [today, recently, WANTED] + qualList) sql_results += more_sql_results #epList = sickbeard.comingList