Merge branch 'release/0.6.0'

This commit is contained in:
Adam 2015-01-18 13:06:48 +08:00
commit 663cb0691b
83 changed files with 2766 additions and 2249 deletions

View file

@ -1,3 +1,43 @@
### 0.6.0 (2015-01-18 05:05:00 UTC)
* Add network logos BBC Canada, Crackle, El Rey Network, SKY Atlantic, and Watch
* Change Yahoo! screen network logo
* Add and update Discovery Network's channel logos
* Add A&E Network International/Scripps Networks International channel logos
* Remove non required duplicate network logos
* Add lowercase PM to the General Config/Interface/Time style selection
* Change General Config/Interface/Trim zero padding to Trim date and time, now handles 2:00 pm > 2 pm
* Fix trim zero of military time hour to not use 12 hr time
* Change ThePirateBay to use oldpiratebay as a temporary fix
* Change Search Settings/Torrent/Deluge option texts for improved understanding
* Fix Womble's Index searching (ssl disabled for now, old categories are the new active ones again)
* Fix Add From Trending Show page to work with Trakt changes
* Add anime unit test cases (port from lad1337/sickbeard)
* Fix normal tv show regex (port from midgetspy/sickbeard)
* Fix anime regex (port from lad1337/sickbeard)
* Add pull request checkout option to General Config/Advanced Settings
* Add BTN api call parameter debug logging
* Fix anime searches on BTN provider
* Change replace "Daily-Search" with "Recent-Search"
* Add daily search to recent search renaming to config migration code
* Fix 'NoneType' object is not iterable in trakt module
* Add log message for when trakt does not return a watchlist
* Change Coming Episodes calendar view to a fluid layout, change episode layout design, and add day and month in column headers
* Add isotope plug-in to Coming Episodes calendar view to enable sort columns by Date, Network, and Show name
* Add imagesLoaded plug-in to prevent layout breakage by calling isotope to update content after a page auto-refresh
* Change Coming Episodes to "Episodes" page (API endpoint is not renamed)
* Add coming episodes to episode view renaming to config migration code
* Change Layout term "Calender" to "Day by Day" on Episodes page
* Fix saving of sort modes to config file on Episodes page
* Add qTip episode plots to "Day by Day" on Episodes page
* Add article sorting to networks on Episodes page
* Add toggle sort direction and multidimensional sort to isotope on Episodes page
* Add text "[paused]" where appropriate to shows on layout Day by Day on Episodes page
* Change Epsiodes page auto refresh from 10 to 30 mins
* Add UI tweaks
* Fix progress bars disappearing on home page
### 0.5.0 (2014-12-21 11:40:00 UTC) ### 0.5.0 (2014-12-21 11:40:00 UTC)
* Fix searches freezing due to unescaped ignored or required words * Fix searches freezing due to unescaped ignored or required words

View file

@ -149,10 +149,6 @@ inc_top.tmpl
margin-bottom: -15px; margin-bottom: -15px;
} }
#contentWrapper {
/* background: url("../images/bg.png") repeat 0 0 transparent; */
}
[class^="icon-"], [class^="icon-"],
[class*=" icon-"] { [class*=" icon-"] {
background-image: url("../images/glyphicons-halflings.png"); background-image: url("../images/glyphicons-halflings.png");
@ -301,18 +297,18 @@ inc_top.tmpl
} }
.ui-tabs { .ui-tabs {
padding: 0px; padding: 0;
background: none; background: none;
border-width: 0px; border-width: 0;
} }
.ui-tabs .ui-tabs-nav { .ui-tabs .ui-tabs-nav {
padding-left: 0px; padding-left: 0;
background: transparent; background: transparent;
border-width: 0px 0px 0px 0px; border-width: 0 0 0 0;
-moz-border-radius: 0px; -moz-border-radius: 0;
-webkit-border-radius: 0px; -webkit-border-radius: 0;
border-radius: 0px; border-radius: 0;
} }
.ui-tabs .ui-tabs-panel { .ui-tabs .ui-tabs-panel {
@ -331,15 +327,6 @@ inc_top.tmpl
border-top-right-radius: 5px; border-top-right-radius: 5px;
} }
#content {
width: 95%;
min-width: 875px;
padding: 15px;
margin-left: auto;
margin-right: auto;
clear: both;
}
#SubMenu { #SubMenu {
padding-right: 20px; padding-right: 20px;
clear: both; clear: both;
@ -353,7 +340,7 @@ inc_top.tmpl
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
margin-top: 50px; margin-top: 50px;
margin-bottom: 0px; margin-bottom: 0;
} }
[class^="menu-icon-"], [class*=" menu-icon-"] { [class^="menu-icon-"], [class*=" menu-icon-"] {
@ -379,83 +366,83 @@ inc_top.tmpl
} }
.menu-icon-addshow { .menu-icon-addshow {
background-position: 0px 0px; background-position: 0 0;
} }
.menu-icon-anime { .menu-icon-anime {
background-position: -21px 0px; background-position: -21px 0;
} }
.menu-icon-backlog-view { .menu-icon-backlog-view {
background-position: -42px 0px; background-position: -42px 0;
} }
.menu-icon-backlog { .menu-icon-backlog {
background-position: -63px 0px; background-position: -63px 0;
} }
.menu-icon-bittorrent { .menu-icon-bittorrent {
background-position: -84px 0px; background-position: -84px 0;
} }
.menu-icon-config-index { .menu-icon-config-index {
background-position: -105px 0px; background-position: -105px 0;
} }
.menu-icon-config { .menu-icon-config {
background-position: -126px 0px; background-position: -126px 0;
} }
.menu-icon-failed-download { .menu-icon-failed-download {
background-position: -147px 0px; background-position: -147px 0;
} }
.menu-icon-home { .menu-icon-home {
background-position: -168px 0px; background-position: -168px 0;
} }
.menu-icon-manage { .menu-icon-manage {
background-position: -189px 0px; background-position: -189px 0;
} }
.menu-icon-manage-searches { .menu-icon-manage-searches {
background-position: -210px 0px; background-position: -210px 0;
} }
.menu-icon-poster { .menu-icon-poster {
background-position: -231px 0px; background-position: -231px 0;
} }
.menu-icon-postprocess { .menu-icon-postprocess {
background-position: -252px 0px; background-position: -252px 0;
} }
.menu-icon-restart { .menu-icon-restart {
background-position: -273px 0px; background-position: -273px 0;
} }
.menu-icon-shutdown { .menu-icon-shutdown {
background-position: -294px 0px; background-position: -294px 0;
} }
.menu-icon-update { .menu-icon-update {
background-position: -315px 0px; background-position: -315px 0;
} }
.menu-icon-viewlog-errors { .menu-icon-viewlog-errors {
background-position: -336px 0px; background-position: -336px 0;
} }
.menu-icon-viewlog { .menu-icon-viewlog {
background-position: -357px 0px; background-position: -357px 0;
} }
.menu-icon-xbmc { .menu-icon-xbmc {
background-position: -378px 0px; background-position: -378px 0;
} }
.menu-icon-help { .menu-icon-help {
background-position: -399px 0px; background-position: -399px 0;
} }
[class^="submenu-icon-"], [class*=" submenu-icon-"] { [class^="submenu-icon-"], [class*=" submenu-icon-"] {
@ -465,27 +452,27 @@ inc_top.tmpl
} }
.submenu-icon-anime { .submenu-icon-anime {
background-position: -21px 0px; background-position: -21px 0;
} }
.submenu-icon-bittorrent { .submenu-icon-bittorrent {
background-position: -84px 0px; background-position: -84px 0;
} }
.submenu-icon-failed-download { .submenu-icon-failed-download {
background-position: -147px 0px; background-position: -147px 0;
} }
.submenu-icon-restart { .submenu-icon-restart {
background-position: -273px 0px; background-position: -273px 0;
} }
.submenu-icon-shutdown { .submenu-icon-shutdown {
background-position: -294px 0px; background-position: -294px 0;
} }
.submenu-icon-xbmc { .submenu-icon-xbmc {
background-position: -378px 0px; background-position: -378px 0;
} }
/* ======================================================================= /* =======================================================================
@ -622,42 +609,42 @@ home.tmpl
} }
.show .ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { .show .ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br {
border-bottom-right-radius: 0px; border-bottom-right-radius: 0;
} }
.show .ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { .show .ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl {
border-bottom-left-radius: 0px; border-bottom-left-radius: 0;
} }
.show .ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { .show .ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr {
border-top-right-radius: 0px; border-top-right-radius: 0;
} }
.show .ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { .show .ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl {
border-top-left-radius: 0px; border-top-left-radius: 0;
} }
.show .ui-widget-content { .show .ui-widget-content {
border-top: 1px solid #111; border-top: 1px solid #111;
border-bottom: 1px solid #111; border-bottom: 1px solid #111;
border-left: 0px; border-left: 0;
border-right: 0px; border-right: 0;
} }
.show .progress-80 { .show .progress-80 {
border-radius: 0px; border-radius: 0;
} }
.show .progress-60 { .show .progress-60 {
border-radius: 0px; border-radius: 0;
} }
.show .progress-40 { .show .progress-40 {
border-radius: 0px; border-radius: 0;
} }
.show .progress-20 { .show .progress-20 {
border-radius: 0px; border-radius: 0;
} }
.show-title { .show-title {
@ -665,7 +652,7 @@ home.tmpl
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
font-size: 11px; font-size: 11px;
margin: 4px 4px 0px 4px; margin: 4px 4px 0 4px;
} }
.show-title:after { .show-title:after {
@ -688,7 +675,7 @@ home.tmpl
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
font-size: 11px; font-size: 11px;
margin: 0px 4px 4px 4px; margin: 0 4px 4px 4px;
} }
.show-date:after { .show-date:after {
@ -828,7 +815,7 @@ home_trendingShows.tmpl
white-space: nowrap; white-space: nowrap;
font-size: 12px; font-size: 12px;
overflow: hidden; overflow: hidden;
/* text-shadow: 1px 1px 0px #000;*/ /* text-shadow: 1px 1px 0 #000;*/
padding-left: 4px; padding-left: 4px;
margin: 0; margin: 0;
} }
@ -928,7 +915,7 @@ ul.tags li {
border: 1px solid #111; border: 1px solid #111;
color: #FFF; color: #FFF;
font: 14px/18px "Open Sans", "Helvetica Neue", Helvetica, Arial, Geneva, sans-serif; font: 14px/18px "Open Sans", "Helvetica Neue", Helvetica, Arial, Geneva, sans-serif;
text-shadow: 0px 1px rgba(0, 0, 0, 0.8); text-shadow: 0 1px rgba(0, 0, 0, 0.8);
float: left; float: left;
} }
@ -1168,7 +1155,7 @@ td.col-search {
} }
/* ======================================================================= /* =======================================================================
comingEpisodes.tmpl episodeView.tmpl
========================================================================== */ ========================================================================== */
.sort_data { .sort_data {
@ -1227,7 +1214,7 @@ h2.day, h2.network {
letter-spacing: 1px; letter-spacing: 1px;
color: #FFF; color: #FFF;
text-align: center; text-align: center;
text-shadow: -1px -1px 0px rgba(0, 0, 0, 0.3); text-shadow: -1px -1px 0 rgba(0, 0, 0, 0.3);
background-color: #15528F; background-color: #15528F;
} }
@ -1236,7 +1223,7 @@ h2.day, h2.network {
clear: both; clear: both;
border: 1px solid #ccc; border: 1px solid #ccc;
margin: auto; margin: auto;
padding: 0px; padding: 0;
text-align: left; text-align: left;
width: 750px; width: 750px;
border-radius: 5px; border-radius: 5px;
@ -1325,17 +1312,42 @@ h2.day, h2.network {
color: #09A2FF; color: #09A2FF;
} }
table.cal-odd { .day-of-week .day-number {
background-color: #15528F;
color: #fff;
}
.today .day-number .number, .today .day-number .month, .today .day-number .day {
color: #8dbeee;
}
.odd .daybyday-show {
background-color: #333; background-color: #333;
} }
table.cal-even {
.even .daybyday-show {
background-color: #3d3d3d; background-color: #3d3d3d;
} }
.calendarShow .text .airtime { .daybyday-show .episode-blank {
color:#fff background-color: rgba(0,0,0,.1);
border-radius: 3px;
} }
.calendarShow .text .episode-title {
color:#aaa .day-of-week .poster img {
border-color: #111;
}
.day-of-week .text .airtime,
.day-of-week .text .episode,
.day-of-week .text .episode .name {
color: #fff;
}
.day-of-week .text .episode .season,
.day-of-week .text .episode .number {
color: rgb(9, 162, 255);
}
.day-of-week .text .episode {
color: rgb(141, 190, 238);
} }
/* ======================================================================= /* =======================================================================
@ -1372,12 +1384,7 @@ config*.tmpl
} }
#config div.field-pair { #config div.field-pair {
padding: 12px 0px; padding: 12px 0;
}
#config div.field-pair input {
float: left;
margin-right: 6px;
} }
#config .nocheck, #config div #customQuality, .metadataDiv { #config .nocheck, #config div #customQuality, .metadataDiv {
@ -1562,7 +1569,7 @@ td.tableright {
text-align: left; text-align: left;
vertical-align: middle; vertical-align: middle;
width: 225px; width: 225px;
padding: 6px 0px; padding: 6px 0;
} }
.optionWrapper div.selectChoices { .optionWrapper div.selectChoices {
@ -1596,7 +1603,6 @@ Global
========================================================================== */ ========================================================================== */
span.path { span.path {
padding: 3px 6px;
color: #09A2FF; color: #09A2FF;
background-color: #333; background-color: #333;
} }
@ -1614,7 +1620,7 @@ span.quality {
background-image:linear-gradient(to bottom, rgba(255, 255, 255, 0.08),rgba(255, 255, 255, 0) 50%,rgba(0, 0, 0, 0) 50%,rgba(0, 0, 0, 0.25)); background-image:linear-gradient(to bottom, rgba(255, 255, 255, 0.08),rgba(255, 255, 255, 0) 50%,rgba(0, 0, 0, 0) 50%,rgba(0, 0, 0, 0.25));
-webkit-box-shadow:inset 0 1px rgba(255, 255, 255, 0.1),inset 0 -1px 3px rgba(0, 0, 0, 0.3),inset 0 0 0 1px rgba(255, 255, 255, 0.08),0 1px 2px rgba(0, 0, 0, 0.15); -webkit-box-shadow:inset 0 1px rgba(255, 255, 255, 0.1),inset 0 -1px 3px rgba(0, 0, 0, 0.3),inset 0 0 0 1px rgba(255, 255, 255, 0.08),0 1px 2px rgba(0, 0, 0, 0.15);
box-shadow:inset 0 1px rgba(255, 255, 255, 0.1),inset 0 -1px 3px rgba(0, 0, 0, 0.3),inset 0 0 0 1px rgba(255, 255, 255, 0.08),0 1px 2px rgba(0, 0, 0, 0.15); box-shadow:inset 0 1px rgba(255, 255, 255, 0.1),inset 0 -1px 3px rgba(0, 0, 0, 0.3),inset 0 0 0 1px rgba(255, 255, 255, 0.08),0 1px 2px rgba(0, 0, 0, 0.15);
text-shadow: 0px 1px rgba(0, 0, 0, 0.8); text-shadow: 0 1px rgba(0, 0, 0, 0.8);
color: #FFFFFF; color: #FFFFFF;
display: inline-block; display: inline-block;
padding: 2px 4px; padding: 2px 4px;
@ -1734,7 +1740,7 @@ div.blackwhitelist span {
} }
div.blackwhitelist.anidb, div.blackwhitelist.manual { div.blackwhitelist.anidb, div.blackwhitelist.manual {
margin: 7px 0px; margin: 7px 0;
} }
@ -1751,7 +1757,7 @@ body {
} }
input[type="radio"] { input[type="radio"] {
margin: 2px 0px 0px; margin: 2px 0 0;
line-height: normal; line-height: normal;
} }
@ -1766,7 +1772,7 @@ input, textarea, select, .uneditable-input {
} }
.navbar-brand { .navbar-brand {
padding: 0px; padding: 0;
} }
/* navbar styling */ /* navbar styling */
@ -1906,7 +1912,7 @@ fieldset[disabled] .navbar-default .btn-link:focus {
.dropdown-menu { .dropdown-menu {
background-color: #333; background-color: #333;
border: 1px solid rgba(0, 0, 0, 0.15); border: 1px solid rgba(0, 0, 0, 0.15);
box-shadow: 0px 6px 12px rgba(0, 0, 0, 0.176); box-shadow: 0 6px 12px rgba(0, 0, 0, 0.176);
} }
.form-control { .form-control {
@ -2384,10 +2390,10 @@ pnotify.css
background-image: -o-linear-gradient(#333, #3d3d3d) !important; background-image: -o-linear-gradient(#333, #3d3d3d) !important;
filter: progid:dximagetransform.microsoft.gradient(startColorstr=#333, endColorstr=#3d3d3d) !important; filter: progid:dximagetransform.microsoft.gradient(startColorstr=#333, endColorstr=#3d3d3d) !important;
-ms-filter: progid:dximagetransform.microsoft.gradient(startColorstr=#333, endColorstr=#3d3d3d) !important; -ms-filter: progid:dximagetransform.microsoft.gradient(startColorstr=#333, endColorstr=#3d3d3d) !important;
-moz-box-shadow: 0px 0px 2px #000; -moz-box-shadow: 0 0 2px #000;
-webkit-box-shadow: 0px 0px 2px #000; -webkit-box-shadow: 0 0 2px #000;
-o-box-shadow: 0px 0px 2px #000; -o-box-shadow: 0 0 2px #000;
box-shadow: 0px 0px 2px #000; box-shadow: 0 0 2px #000;
} }
.ui-pnotify-title { .ui-pnotify-title {
@ -2648,10 +2654,19 @@ span.token-input-delete-token {
background-color: rgb(40, 40, 40); background-color: rgb(40, 40, 40);
} }
/*.episodeview-daybyday .time .time-min,*/
.episodeview-daybyday .time .time-hr-min,
.episodeview-daybyday .time .time-am-pm,
#addRootDirTable td label .filepath, #addRootDirTable td label .filepath,
.grey-text { .grey-text {
color:#999 color:#999
} }
/*.episodeview-daybyday .time .time-hr-min{
display:none
}
.episodeview-daybyday .time .time-min{
font-size: 11px;
}*/
#newShowPortal #displayText .show-name, #newShowPortal #displayText .show-name,
#newShowPortal #displayText .show-dest, #newShowPortal #displayText .show-dest,
@ -2687,7 +2702,7 @@ jquery.confirm.css
top: 50%; top: 50%;
margin: -130px 0 0 -230px; margin: -130px 0 0 -230px;
border: 1px solid #111; border: 1px solid #111;
box-shadow: 0px 0px 12px 0px rgba(0, 0, 0, 0.175); box-shadow: 0 0 12px 0 rgba(0, 0, 0, 0.175);
} }
#confirmBox h1, #confirmBox h1,
@ -2701,13 +2716,13 @@ jquery.confirm.css
color: #fff; color: #fff;
margin: 0; margin: 0;
font-size: 22px; font-size: 22px;
text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.75); text-shadow: 0 1px 1px rgba(0, 0, 0, 0.75);
} }
#confirmBox p { #confirmBox p {
padding-top: 20px; padding-top: 20px;
color: #fff; color: #fff;
text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.75); text-shadow: 0 1px 1px rgba(0, 0, 0, 0.75);
} }
#confirmButtons { #confirmButtons {
@ -2722,7 +2737,7 @@ jquery.confirm.css
display: inline-block; display: inline-block;
color: #fff; color: #fff;
text-align:center; text-align:center;
text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.75); text-shadow: 0 1px 1px rgba(0, 0, 0, 0.75);
background-clip: padding-box; background-clip: padding-box;
border: 1px solid #111; border: 1px solid #111;
border-radius: 3px; border-radius: 3px;

View file

@ -149,10 +149,6 @@ inc_top.tmpl
margin-bottom: -15px; margin-bottom: -15px;
} }
#contentWrapper {
/* background: url("../images/bg.png") repeat 0 0 transparent; */
}
[class^="icon-"], [class^="icon-"],
[class*=" icon-"] { [class*=" icon-"] {
background-image: url("../images/glyphicons-halflings.png"); background-image: url("../images/glyphicons-halflings.png");
@ -289,18 +285,18 @@ inc_top.tmpl
} }
.ui-tabs { .ui-tabs {
padding: 0px; padding: 0;
background: none; background: none;
border-width: 0px; border-width: 0;
} }
.ui-tabs .ui-tabs-nav { .ui-tabs .ui-tabs-nav {
padding-left: 0px; padding-left: 0;
background: transparent; background: transparent;
border-width: 0px 0px 0px 0px; border-width: 0 0 0 0;
-moz-border-radius: 0px; -moz-border-radius: 0;
-webkit-border-radius: 0px; -webkit-border-radius: 0;
border-radius: 0px; border-radius: 0;
} }
.ui-tabs .ui-tabs-panel { .ui-tabs .ui-tabs-panel {
@ -318,15 +314,6 @@ inc_top.tmpl
border-top-right-radius: 5px; border-top-right-radius: 5px;
} }
#content {
width: 95%;
min-width: 875px;
padding: 15px;
margin-left: auto;
margin-right: auto;
clear: both;
}
#SubMenu { #SubMenu {
padding-right: 20px; padding-right: 20px;
clear: both; clear: both;
@ -340,7 +327,7 @@ inc_top.tmpl
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
margin-top: 50px; margin-top: 50px;
margin-bottom: 0px; margin-bottom: 0;
} }
[class^="menu-icon-"], [class*=" menu-icon-"] { [class^="menu-icon-"], [class*=" menu-icon-"] {
@ -366,83 +353,83 @@ inc_top.tmpl
} }
.menu-icon-addshow { .menu-icon-addshow {
background-position: 0px 0px; background-position: 0 0;
} }
.menu-icon-anime { .menu-icon-anime {
background-position: -21px 0px; background-position: -21px 0;
} }
.menu-icon-backlog-view { .menu-icon-backlog-view {
background-position: -42px 0px; background-position: -42px 0;
} }
.menu-icon-backlog { .menu-icon-backlog {
background-position: -63px 0px; background-position: -63px 0;
} }
.menu-icon-bittorrent { .menu-icon-bittorrent {
background-position: -84px 0px; background-position: -84px 0;
} }
.menu-icon-config-index { .menu-icon-config-index {
background-position: -105px 0px; background-position: -105px 0;
} }
.menu-icon-config { .menu-icon-config {
background-position: -126px 0px; background-position: -126px 0;
} }
.menu-icon-failed-download { .menu-icon-failed-download {
background-position: -147px 0px; background-position: -147px 0;
} }
.menu-icon-home { .menu-icon-home {
background-position: -168px 0px; background-position: -168px 0;
} }
.menu-icon-manage { .menu-icon-manage {
background-position: -189px 0px; background-position: -189px 0;
} }
.menu-icon-manage-searches { .menu-icon-manage-searches {
background-position: -210px 0px; background-position: -210px 0;
} }
.menu-icon-poster { .menu-icon-poster {
background-position: -231px 0px; background-position: -231px 0;
} }
.menu-icon-postprocess { .menu-icon-postprocess {
background-position: -252px 0px; background-position: -252px 0;
} }
.menu-icon-restart { .menu-icon-restart {
background-position: -273px 0px; background-position: -273px 0;
} }
.menu-icon-shutdown { .menu-icon-shutdown {
background-position: -294px 0px; background-position: -294px 0;
} }
.menu-icon-update { .menu-icon-update {
background-position: -315px 0px; background-position: -315px 0;
} }
.menu-icon-viewlog-errors { .menu-icon-viewlog-errors {
background-position: -336px 0px; background-position: -336px 0;
} }
.menu-icon-viewlog { .menu-icon-viewlog {
background-position: -357px 0px; background-position: -357px 0;
} }
.menu-icon-xbmc { .menu-icon-xbmc {
background-position: -378px 0px; background-position: -378px 0;
} }
.menu-icon-help { .menu-icon-help {
background-position: -399px 0px; background-position: -399px 0;
} }
[class^="submenu-icon-"], [class*=" submenu-icon-"] { [class^="submenu-icon-"], [class*=" submenu-icon-"] {
@ -452,27 +439,27 @@ inc_top.tmpl
} }
.submenu-icon-anime { .submenu-icon-anime {
background-position: -21px 0px; background-position: -21px 0;
} }
.submenu-icon-bittorrent { .submenu-icon-bittorrent {
background-position: -84px 0px; background-position: -84px 0;
} }
.submenu-icon-failed-download { .submenu-icon-failed-download {
background-position: -147px 0px; background-position: -147px 0;
} }
.submenu-icon-restart { .submenu-icon-restart {
background-position: -273px 0px; background-position: -273px 0;
} }
.submenu-icon-shutdown { .submenu-icon-shutdown {
background-position: -294px 0px; background-position: -294px 0;
} }
.submenu-icon-xbmc { .submenu-icon-xbmc {
background-position: -378px 0px; background-position: -378px 0;
} }
/* ======================================================================= /* =======================================================================
@ -609,42 +596,42 @@ home.tmpl
} }
.show .ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { .show .ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br {
border-bottom-right-radius: 0px; border-bottom-right-radius: 0;
} }
.show .ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { .show .ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl {
border-bottom-left-radius: 0px; border-bottom-left-radius: 0;
} }
.show .ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { .show .ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr {
border-top-right-radius: 0px; border-top-right-radius: 0;
} }
.show .ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { .show .ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl {
border-top-left-radius: 0px; border-top-left-radius: 0;
} }
.show .ui-widget-content { .show .ui-widget-content {
border-top: 1px solid #111; border-top: 1px solid #111;
border-bottom: 1px solid #111; border-bottom: 1px solid #111;
border-left: 0px; border-left: 0;
border-right: 0px; border-right: 0;
} }
.show .progress-80 { .show .progress-80 {
border-radius: 0px; border-radius: 0;
} }
.show .progress-60 { .show .progress-60 {
border-radius: 0px; border-radius: 0;
} }
.show .progress-40 { .show .progress-40 {
border-radius: 0px; border-radius: 0;
} }
.show .progress-20 { .show .progress-20 {
border-radius: 0px; border-radius: 0;
} }
.show-title { .show-title {
@ -652,7 +639,7 @@ home.tmpl
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
font-size: 11px; font-size: 11px;
margin: 4px 4px 0px 4px; margin: 4px 4px 0 4px;
} }
.show-title:after { .show-title:after {
@ -675,7 +662,7 @@ home.tmpl
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
font-size: 11px; font-size: 11px;
margin: 0px 4px 4px 4px; margin: 0 4px 4px 4px;
} }
.show-date:after { .show-date:after {
@ -815,7 +802,7 @@ home_trendingShows.tmpl
white-space: nowrap; white-space: nowrap;
font-size: 12px; font-size: 12px;
overflow: hidden; overflow: hidden;
/* text-shadow: 1px 1px 0px #000;*/ /* text-shadow: 1px 1px 0 #000;*/
padding-left: 4px; padding-left: 4px;
margin: 0; margin: 0;
} }
@ -917,7 +904,7 @@ ul.tags li {
border: 1px solid #111; border: 1px solid #111;
color: #FFF; color: #FFF;
font: 14px/18px "Open Sans", "Helvetica Neue", Helvetica, Arial, Geneva, sans-serif; font: 14px/18px "Open Sans", "Helvetica Neue", Helvetica, Arial, Geneva, sans-serif;
text-shadow: 0px 1px rgba(0, 0, 0, 0.8); text-shadow: 0 1px rgba(0, 0, 0, 0.8);
float: left; float: left;
} }
@ -1074,7 +1061,7 @@ tr.seasonheader {
padding-top: 10px; padding-top: 10px;
text-align: left; text-align: left;
border: none; border: none;
color: #fff; color: #000;
} }
th.col-checkbox, th.col-checkbox,
@ -1157,7 +1144,7 @@ td.col-search {
} }
/* ======================================================================= /* =======================================================================
comingEpisodes.tmpl episodeView.tmpl
========================================================================== */ ========================================================================== */
.sort_data { .sort_data {
@ -1219,7 +1206,7 @@ h2.day, h2.network {
letter-spacing: 1px; letter-spacing: 1px;
color: #FFF; color: #FFF;
text-align: center; text-align: center;
text-shadow: -1px -1px 0px rgba(0, 0, 0, 0.3); text-shadow: -1px -1px 0 rgba(0, 0, 0, 0.3);
background-color: #333; background-color: #333;
} }
@ -1228,7 +1215,7 @@ h2.day, h2.network {
clear: both; clear: both;
border: 1px solid #ccc; border: 1px solid #ccc;
margin: auto; margin: auto;
padding: 0px; padding: 0;
text-align: left; text-align: left;
width: 750px; width: 750px;
border-radius: 5px; border-radius: 5px;
@ -1307,17 +1294,39 @@ h2.day, h2.network {
vertical-align: middle; vertical-align: middle;
} }
table.cal-odd { .day-of-week .day-number {
background-color: #ddd; background-color: #333;
color: #fff;
} }
table.cal-even {
background-color: #d2d2d2; .today .day-number .number, .today .day-number .month, .today .day-number .day {
color: #c7db40;
} }
.calendarShow .text .airtime {
color:#000 .odd .daybyday-show {
background-color: #F5F1E4;
} }
.calendarShow .text .episode-title {
color:#888 .even .daybyday-show {
background-color: #DFDACF;
}
.day-of-week .poster img {
border-color: #CCC;
}
.day-of-week .text .airtime,
.day-of-week .text .episode,
.day-of-week .text .episode .name {
color: #000;
}
.day-of-week .text .episode .season,
.day-of-week .text .episode .number {
color: rgb(9, 133, 225);
/*color: #3d3d3d;*/
}
.day-of-week .text .episode {
color: #888;
} }
/* ======================================================================= /* =======================================================================
@ -1355,12 +1364,7 @@ config*.tmpl
} }
#config div.field-pair { #config div.field-pair {
padding: 12px 0px; padding: 12px 0;
}
#config div.field-pair input {
float: left;
margin-right: 6px;
} }
#config .nocheck, #config div #customQuality, .metadataDiv { #config .nocheck, #config div #customQuality, .metadataDiv {
@ -1538,7 +1542,7 @@ td.tableright {
text-align: left; text-align: left;
vertical-align: middle; vertical-align: middle;
width: 225px; width: 225px;
padding: 6px 0px; padding: 6px 0;
} }
.optionWrapper div.selectChoices { .optionWrapper div.selectChoices {
@ -1572,7 +1576,6 @@ Global
========================================================================== */ ========================================================================== */
span.path { span.path {
padding: 3px 6px;
color: #8b0000; color: #8b0000;
background-color: #f5f1e4; background-color: #f5f1e4;
} }
@ -1594,7 +1597,7 @@ span.quality {
background-image:linear-gradient(to bottom, rgba(255, 255, 255, 0.08),rgba(255, 255, 255, 0) 50%,rgba(0, 0, 0, 0) 50%,rgba(0, 0, 0, 0.25)); background-image:linear-gradient(to bottom, rgba(255, 255, 255, 0.08),rgba(255, 255, 255, 0) 50%,rgba(0, 0, 0, 0) 50%,rgba(0, 0, 0, 0.25));
-webkit-box-shadow:inset 0 1px rgba(255, 255, 255, 0.1),inset 0 -1px 3px rgba(0, 0, 0, 0.3),inset 0 0 0 1px rgba(255, 255, 255, 0.08),0 1px 2px rgba(0, 0, 0, 0.15); -webkit-box-shadow:inset 0 1px rgba(255, 255, 255, 0.1),inset 0 -1px 3px rgba(0, 0, 0, 0.3),inset 0 0 0 1px rgba(255, 255, 255, 0.08),0 1px 2px rgba(0, 0, 0, 0.15);
box-shadow:inset 0 1px rgba(255, 255, 255, 0.1),inset 0 -1px 3px rgba(0, 0, 0, 0.3),inset 0 0 0 1px rgba(255, 255, 255, 0.08),0 1px 2px rgba(0, 0, 0, 0.15); box-shadow:inset 0 1px rgba(255, 255, 255, 0.1),inset 0 -1px 3px rgba(0, 0, 0, 0.3),inset 0 0 0 1px rgba(255, 255, 255, 0.08),0 1px 2px rgba(0, 0, 0, 0.15);
text-shadow: 0px 1px rgba(0, 0, 0, 0.8); text-shadow: 0 1px rgba(0, 0, 0, 0.8);
color: #FFFFFF; color: #FFFFFF;
display: inline-block; display: inline-block;
padding: 2px 4px; padding: 2px 4px;
@ -1714,7 +1717,7 @@ div.blackwhitelist span {
} }
div.blackwhitelist.anidb, div.blackwhitelist.manual { div.blackwhitelist.anidb, div.blackwhitelist.manual {
margin: 7px 0px; margin: 7px 0;
} }
@ -1730,7 +1733,7 @@ body {
} }
input[type="radio"] { input[type="radio"] {
margin: 2px 0px 0px; margin: 2px 0 0;
line-height: normal; line-height: normal;
} }
@ -1745,7 +1748,7 @@ input, textarea, select, .uneditable-input {
} }
.navbar-brand { .navbar-brand {
padding: 0px; padding: 0;
} }
/* navbar styling */ /* navbar styling */
@ -1884,7 +1887,7 @@ fieldset[disabled] .navbar-default .btn-link:focus {
.dropdown-menu { .dropdown-menu {
background-color: #F5F1E4; background-color: #F5F1E4;
border: 1px solid rgba(0, 0, 0, 0.15); border: 1px solid rgba(0, 0, 0, 0.15);
box-shadow: 0px 6px 12px rgba(0, 0, 0, 0.176); box-shadow: 0 6px 12px rgba(0, 0, 0, 0.176);
} }
.form-control { .form-control {
@ -2596,6 +2599,8 @@ span.token-input-delete-token {
background-color: rgb(245, 245, 245); background-color: rgb(245, 245, 245);
} }
.episodeview-daybyday .time .time-min,
.episodeview-daybyday .time .time-am-pm,
#addRootDirTable td label .filepath, #addRootDirTable td label .filepath,
.grey-text { .grey-text {
color:#666 color:#666
@ -2635,7 +2640,7 @@ jquery.confirm.css
top: 50%; top: 50%;
margin: -130px 0 0 -230px; margin: -130px 0 0 -230px;
border: 1px solid #111; border: 1px solid #111;
box-shadow: 0px 0px 12px 0px rgba(0, 0, 0, 0.175); box-shadow: 0 0 12px 0 rgba(0, 0, 0, 0.175);
} }
#confirmBox h1, #confirmBox h1,
@ -2649,13 +2654,13 @@ jquery.confirm.css
color: #fff; color: #fff;
margin: 0; margin: 0;
font-size: 22px; font-size: 22px;
text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.75); text-shadow: 0 1px 1px rgba(0, 0, 0, 0.75);
} }
#confirmBox p { #confirmBox p {
padding-top: 20px; padding-top: 20px;
color: #000; color: #000;
text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.75); text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
} }
#confirmButtons { #confirmButtons {
@ -2670,7 +2675,7 @@ jquery.confirm.css
display: inline-block; display: inline-block;
color: #fff; color: #fff;
text-align:center; text-align:center;
text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.75); text-shadow: 0 1px 1px rgba(0, 0, 0, 0.75);
background-clip: padding-box; background-clip: padding-box;
border: 1px solid #111; border: 1px solid #111;
border-radius: 3px; border-radius: 3px;

View file

@ -149,8 +149,11 @@ inc_top.tmpl
margin-bottom: -15px; margin-bottom: -15px;
} }
#contentWrapper { #contentWrapper .episodeview-banner,
/* background: url("../images/bg.png") repeat 0 0 transparent; */ #contentWrapper .episodeview-daybyday,
#contentWrapper .episodeview-list,
#contentWrapper .episodeview-poster{
padding-top:45px;
} }
[class^="icon-"], [class^="icon-"],
@ -285,18 +288,18 @@ inc_top.tmpl
} }
.ui-tabs { .ui-tabs {
padding: 0px; padding: 0;
background: none; background: none;
border-width: 0px; border-width: 0;
} }
.ui-tabs .ui-tabs-nav { .ui-tabs .ui-tabs-nav {
padding-left: 0px; padding-left: 0;
background: transparent; background: transparent;
border-width: 0px 0px 0px 0px; border-width: 0 0 0 0;
-moz-border-radius: 0px; -moz-border-radius: 0;
-webkit-border-radius: 0px; -webkit-border-radius: 0;
border-radius: 0px; border-radius: 0;
} }
.ui-tabs .ui-tabs-panel { .ui-tabs .ui-tabs-panel {
@ -336,7 +339,7 @@ inc_top.tmpl
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
margin-top: 50px; margin-top: 50px;
margin-bottom: 0px; margin-bottom: 0;
} }
[class^="menu-icon-"], [class*=" menu-icon-"] { [class^="menu-icon-"], [class*=" menu-icon-"] {
@ -362,83 +365,83 @@ inc_top.tmpl
} }
.menu-icon-addshow { .menu-icon-addshow {
background-position: 0px 0px; background-position: 0 0;
} }
.menu-icon-anime { .menu-icon-anime {
background-position: -21px 0px; background-position: -21px 0;
} }
.menu-icon-backlog-view { .menu-icon-backlog-view {
background-position: -42px 0px; background-position: -42px 0;
} }
.menu-icon-backlog { .menu-icon-backlog {
background-position: -63px 0px; background-position: -63px 0;
} }
.menu-icon-bittorrent { .menu-icon-bittorrent {
background-position: -84px 0px; background-position: -84px 0;
} }
.menu-icon-config-index { .menu-icon-config-index {
background-position: -105px 0px; background-position: -105px 0;
} }
.menu-icon-config { .menu-icon-config {
background-position: -126px 0px; background-position: -126px 0;
} }
.menu-icon-failed-download { .menu-icon-failed-download {
background-position: -147px 0px; background-position: -147px 0;
} }
.menu-icon-home { .menu-icon-home {
background-position: -168px 0px; background-position: -168px 0;
} }
.menu-icon-manage { .menu-icon-manage {
background-position: -189px 0px; background-position: -189px 0;
} }
.menu-icon-manage-searches { .menu-icon-manage-searches {
background-position: -210px 0px; background-position: -210px 0;
} }
.menu-icon-poster { .menu-icon-poster {
background-position: -231px 0px; background-position: -231px 0;
} }
.menu-icon-postprocess { .menu-icon-postprocess {
background-position: -252px 0px; background-position: -252px 0;
} }
.menu-icon-restart { .menu-icon-restart {
background-position: -273px 0px; background-position: -273px 0;
} }
.menu-icon-shutdown { .menu-icon-shutdown {
background-position: -294px 0px; background-position: -294px 0;
} }
.menu-icon-update { .menu-icon-update {
background-position: -315px 0px; background-position: -315px 0;
} }
.menu-icon-viewlog-errors { .menu-icon-viewlog-errors {
background-position: -336px 0px; background-position: -336px 0;
} }
.menu-icon-viewlog { .menu-icon-viewlog {
background-position: -357px 0px; background-position: -357px 0;
} }
.menu-icon-xbmc { .menu-icon-xbmc {
background-position: -378px 0px; background-position: -378px 0;
} }
.menu-icon-help { .menu-icon-help {
background-position: -399px 0px; background-position: -399px 0;
} }
[class^="submenu-icon-"], [class*=" submenu-icon-"] { [class^="submenu-icon-"], [class*=" submenu-icon-"] {
@ -448,27 +451,27 @@ inc_top.tmpl
} }
.submenu-icon-anime { .submenu-icon-anime {
background-position: -21px 0px; background-position: -21px 0;
} }
.submenu-icon-bittorrent { .submenu-icon-bittorrent {
background-position: -84px 0px; background-position: -84px 0;
} }
.submenu-icon-failed-download { .submenu-icon-failed-download {
background-position: -147px 0px; background-position: -147px 0;
} }
.submenu-icon-restart { .submenu-icon-restart {
background-position: -273px 0px; background-position: -273px 0;
} }
.submenu-icon-shutdown { .submenu-icon-shutdown {
background-position: -294px 0px; background-position: -294px 0;
} }
.submenu-icon-xbmc { .submenu-icon-xbmc {
background-position: -378px 0px; background-position: -378px 0;
} }
/* ======================================================================= /* =======================================================================
@ -626,26 +629,26 @@ home.tmpl
} }
.show .ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { .show .ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br {
border-bottom-right-radius: 0px; border-bottom-right-radius: 0;
} }
.show .ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { .show .ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl {
border-bottom-left-radius: 0px; border-bottom-left-radius: 0;
} }
.show .ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { .show .ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr {
border-top-right-radius: 0px; border-top-right-radius: 0;
} }
.show .ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { .show .ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl {
border-top-left-radius: 0px; border-top-left-radius: 0;
} }
.show .ui-widget-content { .show .ui-widget-content {
border-top: 1px solid #111; border-top: 1px solid #111;
border-bottom: 1px solid #111; border-bottom: 1px solid #111;
border-left: 0px; border-left: 0;
border-right: 0px; border-right: 0;
} }
.ui-progressbar .ui-progressbar-value { .ui-progressbar .ui-progressbar-value {
height:20px height:20px
@ -661,19 +664,19 @@ home.tmpl
} }
.show .progress-80 { .show .progress-80 {
border-radius: 0px; border-radius: 0;
} }
.show .progress-60 { .show .progress-60 {
border-radius: 0px; border-radius: 0;
} }
.show .progress-40 { .show .progress-40 {
border-radius: 0px; border-radius: 0;
} }
.show .progress-20 { .show .progress-20 {
border-radius: 0px; border-radius: 0;
} }
.show-title { .show-title {
@ -681,7 +684,7 @@ home.tmpl
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
font-size: 11px; font-size: 11px;
margin: 4px 4px 0px 4px; margin: 4px 4px 0 4px;
} }
.show-title:after { .show-title:after {
@ -704,7 +707,7 @@ home.tmpl
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
font-size: 11px; font-size: 11px;
margin: 0px 4px 4px 4px; margin: 0 4px 4px 4px;
} }
.show-date:after { .show-date:after {
@ -791,34 +794,27 @@ home_addShows.tmpl
========================================================================== */ ========================================================================== */
#addShowPortal { #addShowPortal {
width: 750px; width: 748px;
padding: 10px 0; padding: 10px 0;
margin-right: auto; margin-right: auto;
margin-left: auto; margin-left: auto;
} }
#addShowPortal a { #addShowPortal a {
/* padding: 10px;*/ padding: 0 20px;
padding: 0px 20px;
width: 360px; width: 360px;
float: left; float: left;
margin: 0 15px 15px 0; margin: 0 7px 14px;
} }
div.button { div.button {
display: table-cell; display: table-cell;
vertical-align: middle; vertical-align: middle;
/* padding-left: 10px;*/
} }
div.buttontext { div.buttontext {
display: table-cell; display: table-cell;
/* padding: 10px 0 10px 15px;
padding-left: 20px;
padding: 10px 15px;
*/
padding: 10px 0px 10px 15px;
text-align: left; text-align: left;
white-space: normal; white-space: normal;
} }
@ -826,7 +822,7 @@ div.buttontext p {
margin: 0 margin: 0
} }
div.buttontext h3 { div.buttontext h3 {
margin-top: 0px; margin-top: 0;
} }
div.buttontext p { div.buttontext p {
@ -970,7 +966,6 @@ home_trendingShows.tmpl
white-space: nowrap; white-space: nowrap;
font-size: 12px; font-size: 12px;
overflow: hidden; overflow: hidden;
/* text-shadow: 1px 1px 0px #000;*/
padding-left: 4px; padding-left: 4px;
margin: 0; margin: 0;
} }
@ -1104,7 +1099,7 @@ ul.tags li {
border: 1px solid #111; border: 1px solid #111;
color: #FFF; color: #FFF;
font: 14px/18px "Open Sans", "Helvetica Neue", Helvetica, Arial, Geneva, sans-serif; font: 14px/18px "Open Sans", "Helvetica Neue", Helvetica, Arial, Geneva, sans-serif;
text-shadow: 0px 1px rgba(0, 0, 0, 0.8); text-shadow: 0 1px rgba(0, 0, 0, 0.8);
float: left; float: left;
} }
@ -1347,7 +1342,7 @@ td.col-search {
} }
/* ======================================================================= /* =======================================================================
comingEpisodes.tmpl episodeView.tmpl
========================================================================== */ ========================================================================== */
.sort_data { .sort_data {
@ -1409,7 +1404,7 @@ h2.day, h2.network {
letter-spacing: 1px; letter-spacing: 1px;
color: #FFF; color: #FFF;
text-align: center; text-align: center;
text-shadow: -1px -1px 0px rgba(0, 0, 0, 0.3); text-shadow: -1px -1px 0 rgba(0, 0, 0, 0.3);
background-color: #333; background-color: #333;
} }
@ -1418,7 +1413,7 @@ h2.day, h2.network {
clear: both; clear: both;
border: 1px solid #ccc; border: 1px solid #ccc;
margin: auto; margin: auto;
padding: 0px; padding: 0;
text-align: left; text-align: left;
width: 750px; width: 750px;
border-radius: 5px; border-radius: 5px;
@ -1497,46 +1492,87 @@ h2.day, h2.network {
vertical-align: middle; vertical-align: middle;
} }
.calendarWrapper { .daybydayWrapper {
width:1000px; max-width: 1400px;
margin: 0 auto; margin: 0 auto;
padding:0 3px padding: 0 /*3px*/
} }
.calendarTable { .day-of-week {
float: left; float: left;
width:142px !important; width: 14.28%;
white-space:nowrap; padding: 0 2px;
table-layout:fixed !important;
} }
.calendarShow { .day-of-week .day-number {
padding:0 !important position: relative;
height: 40px;
} }
.calendarShow .poster { .day-of-week .day-number .number {
padding-bottom:2px position: absolute;
} right: 5px;
.calendarShow .poster img { font-weight: bold;
width:142px; font-size: 32px;
height:auto line-height: 38px;
} }
.calendarShow .text { .day-of-week .day-number .day {
padding:0 5px 10px 5px position: absolute;
left: 5px;
top: 3px;
text-transform: uppercase;
font-weight: bold;
} }
.calendarShow .text .airtime, .day-of-week .day-number .month {
.calendarShow .text .episode-title { position: absolute;
left: 5px;
bottom: 3px;
text-transform: uppercase;
}
.daybyday-show {
margin-top: 4px;
padding: 4px;
width: 100%
}
.day-of-week .poster img {
border: 1px solid;
border-radius: 5px;
margin-bottom: 2px;
display: block;
margin-left: auto;
margin-right: auto;
}
.day-of-week .text .airtime,
.day-of-week .text .episode {
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
display: block; display: block;
font-size:11px font-size: 12px;
} }
.calendarShow .show-status { .day-of-week .text .episode .season,
padding:5px 10px 10px; .day-of-week .text .episode .number {
text-align:center font-weight: 900;
}
.day-of-week .text .episode .season {
margin-right: 2px;
}
.day-of-week .text .episode .number {
margin-left: 2px;
}
.day-of-week .episode-blank {
width: 250px;
height: 32px;
text-align: center;
font-style: italic;
display: table-cell;
vertical-align: middle;
font-size: 12px;
} }
/* ======================================================================= /* =======================================================================
@ -1591,10 +1627,13 @@ config*.tmpl
padding: 12px 0 padding: 12px 0
} }
.stepDiv .component-desc select,
.stepDiv .component-desc input,
#config div.field-pair select, #config div.field-pair select,
#config div.field-pair input { #config div.field-pair input {
margin-right: 6px;
}
.stepDiv .component-desc select,
.stepDiv .component-desc input {
margin-right: 15px; margin-right: 15px;
} }
@ -1870,7 +1909,7 @@ div.metadata_example label {
line-height: 21px; line-height: 21px;
display: block; display: block;
padding: 3px; padding: 3px;
margin: 0px; margin: 0;
} }
div.metadata_options input { div.metadata_options input {
margin-right: 3px; margin-right: 3px;
@ -1883,7 +1922,7 @@ div.metadataDiv .disabled {
.notifier-icon { .notifier-icon {
float: left; float: left;
margin: 6px 4px 0px 0px; margin: 6px 4px 0 0;
} }
/* ======================================================================= /* =======================================================================
@ -1915,7 +1954,7 @@ td.tableright {
text-align: left; text-align: left;
vertical-align: middle; vertical-align: middle;
width: 225px; width: 225px;
padding: 6px 0px; padding: 6px 0;
} }
.optionWrapper div.selectChoices { .optionWrapper div.selectChoices {
@ -1949,9 +1988,8 @@ Global
========================================================================== */ ========================================================================== */
span.path { span.path {
padding: 3px 6px; padding: 3px;
color: #8b0000; margin-left: 3px;
background-color: #f5f1e4;
} }
.align-left { .align-left {
@ -1971,7 +2009,7 @@ span.quality {
background-image:linear-gradient(to bottom, rgba(255, 255, 255, 0.08),rgba(255, 255, 255, 0) 50%,rgba(0, 0, 0, 0) 50%,rgba(0, 0, 0, 0.25)); background-image:linear-gradient(to bottom, rgba(255, 255, 255, 0.08),rgba(255, 255, 255, 0) 50%,rgba(0, 0, 0, 0) 50%,rgba(0, 0, 0, 0.25));
-webkit-box-shadow:inset 0 1px rgba(255, 255, 255, 0.1),inset 0 -1px 3px rgba(0, 0, 0, 0.3),inset 0 0 0 1px rgba(255, 255, 255, 0.08),0 1px 2px rgba(0, 0, 0, 0.15); -webkit-box-shadow:inset 0 1px rgba(255, 255, 255, 0.1),inset 0 -1px 3px rgba(0, 0, 0, 0.3),inset 0 0 0 1px rgba(255, 255, 255, 0.08),0 1px 2px rgba(0, 0, 0, 0.15);
box-shadow:inset 0 1px rgba(255, 255, 255, 0.1),inset 0 -1px 3px rgba(0, 0, 0, 0.3),inset 0 0 0 1px rgba(255, 255, 255, 0.08),0 1px 2px rgba(0, 0, 0, 0.15); box-shadow:inset 0 1px rgba(255, 255, 255, 0.1),inset 0 -1px 3px rgba(0, 0, 0, 0.3),inset 0 0 0 1px rgba(255, 255, 255, 0.08),0 1px 2px rgba(0, 0, 0, 0.15);
text-shadow: 0px 1px rgba(0, 0, 0, 0.8); text-shadow: 0 1px rgba(0, 0, 0, 0.8);
color: #FFFFFF; color: #FFFFFF;
display: inline-block; display: inline-block;
padding: 2px 4px; padding: 2px 4px;
@ -2091,7 +2129,7 @@ div.blackwhitelist span {
} }
div.blackwhitelist.anidb, div.blackwhitelist.manual { div.blackwhitelist.anidb, div.blackwhitelist.manual {
margin: 7px 0px; margin: 7px 0;
} }
@ -2111,12 +2149,12 @@ html * {
} }
input[type="checkbox"] { input[type="checkbox"] {
margin: 2px 0px 0px; margin: 2px 0 0;
line-height: normal; line-height: normal;
} }
input[type="radio"] { input[type="radio"] {
margin: 2px 0px 0px; margin: 2px 0 0;
line-height: normal; line-height: normal;
} }
@ -2131,7 +2169,7 @@ input, textarea, select, .uneditable-input {
} }
.navbar-brand { .navbar-brand {
padding: 0px; padding: 0;
} }
/* navbar styling */ /* navbar styling */
@ -2258,7 +2296,7 @@ fieldset[disabled] .navbar-default .btn-link:focus {
.dropdown-menu { .dropdown-menu {
background-color: #F5F1E4; background-color: #F5F1E4;
border: 1px solid rgba(0, 0, 0, 0.15); border: 1px solid rgba(0, 0, 0, 0.15);
box-shadow: 0px 6px 12px rgba(0, 0, 0, 0.176); box-shadow: 0 6px 12px rgba(0, 0, 0, 0.176);
} }
.form-control { .form-control {
@ -2815,7 +2853,7 @@ div.formpaginate .prev, div.formpaginate .next {
.stepDiv.parent-folder { .stepDiv.parent-folder {
padding: 15px 0 0; padding: 15px 0 0;
width: 430px; width: 430px;
margin: 0px auto; margin: 0 auto;
} }
.stepDiv .nocheck { .stepDiv .nocheck {
@ -3153,6 +3191,15 @@ span.token-input-delete-token {
z-index: 0; z-index: 0;
background-image: url(../images/poster-dark.jpg) background-image: url(../images/poster-dark.jpg)
} }
.time-am-pm {
margin-left: 2px;
}
#content.episodeview-banner .time-am-pm,
#content.episodeview-poster .time-am-pm {
margin-left: 0;
}
/* ======================================================================= /* =======================================================================
jquery.confirm.css jquery.confirm.css
========================================================================== */ ========================================================================== */
@ -3177,7 +3224,7 @@ jquery.confirm.css
top: 50%; top: 50%;
margin: -130px 0 0 -230px; margin: -130px 0 0 -230px;
border: 1px solid #111; border: 1px solid #111;
box-shadow: 0px 0px 12px 0px rgba(0, 0, 0, 0.175); box-shadow: 0 0 12px 0 rgba(0, 0, 0, 0.175);
} }
#confirmBox h1, #confirmBox h1,
@ -3212,7 +3259,7 @@ jquery.confirm.css
display: inline-block; display: inline-block;
color: #fff; color: #fff;
text-align:center; text-align:center;
text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.75); text-shadow: 0 1px 1px rgba(0, 0, 0, 0.75);
background-clip: padding-box; background-clip: padding-box;
border: 1px solid #111; border: 1px solid #111;
border-radius: 3px; border-radius: 3px;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

View file

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

View file

@ -90,8 +90,8 @@ addOption("postprocess", "process_method", "&process_method=copy");
addOption("postprocess", "type", "&type=manual") addOption("postprocess", "type", "&type=manual")
addOption("sb.setdefaults", "Optional Param", "", 1); addOption("sb.setdefaults", "Optional Param", "", 1);
addList("sb.setdefaults", "Exclude Paused Shows on ComingEps", "&future_show_paused=0", "sb.setdefaults-status"); addList("sb.setdefaults", "Exclude Paused Shows on EpisodeView", "&future_show_paused=0", "sb.setdefaults-status");
addList("sb.setdefaults", "Include Paused Shows on ComingEps", "&future_show_paused=1", "sb.setdefaults-status"); addList("sb.setdefaults", "Include Paused Shows on EpisodeView", "&future_show_paused=1", "sb.setdefaults-status");
addOption("sb.setdefaults-status", "Optional Param", "", 1); addOption("sb.setdefaults-status", "Optional Param", "", 1);
addList("sb.setdefaults-status", "Wanted", "&status=wanted", "sb.setdefaults-opt"); addList("sb.setdefaults-status", "Wanted", "&status=wanted", "sb.setdefaults-opt");

View file

@ -1,549 +0,0 @@
#import sickbeard
#import datetime
#from sickbeard.common import *
#from sickbeard import sbdatetime
#from sickbeard.helpers import anon_url
#set global $title = 'Coming Episodes'
#set global $header = 'Coming Episodes'
#set global $sbPath = '..'
#set global $topmenu = 'comingEpisodes'
#import os.path
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_top.tmpl')
#set $sort = $sickbeard.COMING_EPS_SORT
<script type="text/javascript" src="$sbRoot/js/ajaxEpSearch.js?$sbPID"></script>
#if $varExists('header')
<h1 class="header">$header</h1>
#else
<h1 class="title">$title</h1>
#end if
<style type="text/css">
#SubMenu {display:none}
#contentWrapper {padding-top:30px}
</style>
<div class="h2footer pull-right">
<span>Layout:
<select name="layout" class="form-control form-control-inline input-sm" onchange="location = this.options[this.selectedIndex].value;">
<option value="$sbRoot/setComingEpsLayout/?layout=poster" #if 'poster' == $sickbeard.COMING_EPS_LAYOUT then 'selected="selected"' else ''#>Poster</option>
<option value="$sbRoot/setComingEpsLayout/?layout=calendar" #if 'calendar' == $sickbeard.COMING_EPS_LAYOUT then 'selected="selected"' else ''#>Calendar</option>
<option value="$sbRoot/setComingEpsLayout/?layout=banner" #if 'banner' == $sickbeard.COMING_EPS_LAYOUT then 'selected="selected"' else ''#>Banner</option>
<option value="$sbRoot/setComingEpsLayout/?layout=list" #if 'list' == $sickbeard.COMING_EPS_LAYOUT then 'selected="selected"' else ''#>List</option>
</select>
</span>
&nbsp;
<span>Sort By:
<select name="sort" class="form-control form-control-inline input-sm" onchange="location = this.options[this.selectedIndex].value;">
<option value="$sbRoot/setComingEpsSort/?sort=date" #if 'date' == $sickbeard.COMING_EPS_SORT then 'selected="selected"' else ''#>Date</option>
<option value="$sbRoot/setComingEpsSort/?sort=network" #if 'network' == $sickbeard.COMING_EPS_SORT then 'selected="selected"' else ''#>Network</option>
<option value="$sbRoot/setComingEpsSort/?sort=show" #if 'show' == $sickbeard.COMING_EPS_SORT then 'selected="selected"' else ''#>Show</option>
</select>
</span>
&nbsp;
<span>View Paused:
<select name="viewpaused" class="form-control form-control-inline input-sm" onchange="location = this.options[this.selectedIndex].value;">
<option value="$sbRoot/toggleComingEpsDisplayPaused"<%= (' selected="selected"', '')[True == sickbeard.COMING_EPS_DISPLAY_PAUSED] %>>Hidden</option>
<option value="$sbRoot/toggleComingEpsDisplayPaused"<%= ('', ' selected="selected"')[True == sickbeard.COMING_EPS_DISPLAY_PAUSED] %>>Shown</option>
</select>
</span>
</div>
<div class="key pull-right">
#if 'calendar' != $layout:
<b>Key:</b>
<span class="listing-key listing-overdue">Missed</span>
<span class="listing-key listing-current">Current</span>
<span class="listing-key listing-default">Future</span>
<span class="listing-key listing-toofar">Distant</span>
#end if
<a class="btn btn-inline forceBacklog" href="webcal://$sbHost:$sbHttpPort/calendar">
<i class="icon-calendar icon-white"></i>Subscribe</a>
</div>
<br>
#if 'list' == $layout:
<!-- start list view //-->
<script type="text/javascript" src="$sbRoot/js/plotTooltip.js?$sbPID"></script>
<script type="text/javascript" charset="utf-8">
<!--
\$.tablesorter.addParser({
id: 'loadingNames',
is: function(s) {
return false
},
format: function(s) {
if (0 == s.indexOf('Loading...'))
return s.replace('Loading...', '000')
#if not $sickbeard.SORT_ARTICLE:
return (s || '').replace(/^(?:(?:A(?!\s+to)n?)|The)\s(\w)/i, '$1')
#else:
return (s || '')
#end if
},
type: 'text'
});
\$.tablesorter.addParser({
id: 'quality',
is: function(s) {
return false
},
format: function(s) {
return s.replace('hd1080p', 5).replace('hd720p', 4).replace('hd', 3).replace('sd', 2).replace('any', 1).replace('best', 0).replace('custom', 7)
},
type: 'numeric'
});
\$.tablesorter.addParser({
id: 'cDate',
is: function(s) {
return false
},
format: function(s) {
return s
},
type: 'numeric'
});
\$(document).ready(function(){
#set $sort_codes = {'date': 0, 'show': 1, 'network': 4}
#if $sort not in $sort_codes:
$sort = 'date'
#end if
sortList = [[$sort_codes[$sort], 0]];
\$('#showListTable:has(tbody tr)').tablesorter({
widgets: ['stickyHeaders'],
sortList: sortList,
textExtraction: {
0: function(node) { return \$(node).find('span').text().toLowerCase() },
4: function(node) { return \$(node).find('img').attr('alt') },
5: function(node) { return \$(node).find('span').text().toLowerCase() }
},
headers: {
0: { sorter: 'cDate' },
1: { sorter: 'loadingNames' },
2: { sorter: false },
3: { sorter: false },
4: { sorter: 'loadingNames' },
5: { sorter: 'quality' },
6: { sorter: false },
7: { sorter: false },
8: { sorter: false }
}
});
\$('#sbRoot').ajaxEpSearch();
#set $fuzzydate = 'airdate'
#if $sickbeard.FUZZY_DATING:
fuzzyMoment({
containerClass : '.${fuzzydate}',
dateHasTime : true,
dateFormat : '${sickbeard.DATE_PRESET}',
timeFormat : '${sickbeard.TIME_PRESET}',
trimZero : #if $sickbeard.TRIM_ZERO then 'true' else 'false'#
});
#end if
});
//-->
</script>
#set $show_div = 'listing-default'
<input type="hidden" id="sbRoot" value="$sbRoot" />
<table id="showListTable" class="sickbeardTable tablesorter seasonstyle" cellspacing="1" border="0" cellpadding="0">
<thead>
<tr>
<th>Airdate</th>
<th>Show</th>
<th class="nowrap">Next Ep</th>
<th>Next Ep Name</th>
<th>Network</th>
<th>Quality</th>
<th>Indexers</th>
<th>Search</th>
</tr>
</thead>
<tbody style="text-shadow:none;">
#for $cur_result in $sql_results:
#set $cur_indexer = int($cur_result['indexer'])
#set $runtime = $cur_result['runtime']
#if int($cur_result['paused']) and not $sickbeard.COMING_EPS_DISPLAY_PAUSED:
#continue
#end if
#set $cur_ep_airdate = $cur_result['localtime'].date()
#if $runtime:
#set $cur_ep_enddate = $cur_result['localtime'] + datetime.timedelta(minutes = $runtime)
#if $cur_ep_enddate < $today:
#set $show_div = 'listing-overdue'
#elif $cur_ep_airdate >= $next_week.date():
#set $show_div = 'listing-toofar'
#elif $cur_ep_airdate >= $today.date() and $cur_ep_airdate < $next_week.date():
#if $cur_ep_airdate == $today.date():
#set $show_div = 'listing-current'
#else:
#set $show_div = 'listing-default'
#end if
#end if
#end if
<!-- start $cur_result['show_name'] //-->
<tr class="$show_div">
## forced to use a div to wrap airdate, the column sort went crazy with a span
<td align="center" class="nowrap">
<div class="${fuzzydate}">$sbdatetime.sbdatetime.sbfdatetime($cur_result['localtime']).decode($sickbeard.SYS_ENCODING)</div><span class="sort_data">$time.mktime($cur_result['localtime'].timetuple())</span>
</td>
<td class="tvShow"><a href="$sbRoot/home/displayShow?show=${cur_result['showid']}">$cur_result['show_name']</a>
#if int($cur_result['paused']):
<span class="pause">[paused]</span>
#end if
</td>
<td class="nowrap" align="center">
<%= 'S%02iE%02i' % (int(cur_result['season']), int(cur_result['episode'])) %>
</td>
<td>
#if $cur_result['description']:
<img alt='' src='$sbRoot/images/info32.png' height='16' width='16' class='plotInfo' id="plot_info_<%= '%s_%s_%s' % (str(cur_result['showid']), str(cur_result['season']), str(cur_result['episode'])) %>" />
#else:
<img alt="" src="$sbRoot/images/info32.png" width="16" height="16" class="plotInfoNone" />
#end if
$cur_result['name']
</td>
<td align="center">
$cur_result['network']
</td>
<td align="center">
#if int($cur_result['quality']) in $qualityPresets:
<span class="quality $qualityPresetStrings[int($cur_result['quality'])]">$qualityPresetStrings[int($cur_result['quality'])]</span>
#else:
<span class="quality Custom">Custom</span>
#end if
</td>
<td align="center" style="vertical-align: middle;">
#if $cur_result['imdb_id']:
<a href="<%= anon_url('http://www.imdb.com/title/', cur_result['imdb_id']) %>" rel="noreferrer" onclick="window.open(this.href, '_blank'); return false" title="http://www.imdb.com/title/${cur_result['imdb_id']}"><img alt="[imdb]" height="16" width="16" src="$sbRoot/images/imdb.png" />
#end if
<a href="<%= anon_url(sickbeard.indexerApi(cur_indexer).config['show_url'], cur_result['showid']) %>" rel="noreferrer" onclick="window.open(this.href, '_blank'); return false" title="$sickbeard.indexerApi($cur_indexer).config['show_url']${cur_result['showid']}"><img alt="$sickbeard.indexerApi($cur_indexer).name" height="16" width="16" src="$sbRoot/images/$sickbeard.indexerApi($cur_indexer).config['icon']" /></a>
</td>
<td align="center">
<a href="$sbRoot/home/searchEpisode?show=${cur_result['showid']}&amp;season=$cur_result['season']&amp;episode=$cur_result['episode']" title="Manual Search" id="forceUpdate-${cur_result['showid']}" class="forceUpdate epSearch"><img alt="[search]" height="16" width="16" src="$sbRoot/images/search16.png" id="forceUpdateImage-${cur_result['showid']}" /></a>
</td>
</tr>
<!-- end $cur_result['show_name'] //-->
#end for
</tbody>
<tfoot>
<tr>
<th rowspan="1" colspan="10" align="center">&nbsp</th>
</tr>
</tfoot>
</table>
<!-- end list view //-->
#else if $layout in ['banner', 'poster']:
<!-- start non list view //-->
<script type="text/javascript" charset="utf-8">
<!--
\$(document).ready(function(){
\$('#sbRoot').ajaxEpSearch({'size': 16, 'loadingImage': 'loading16' + themeSpinner + '.gif'});
\$('.ep_summary').hide();
\$('.ep_summaryTrigger').click(function() {
\$(this).next('.ep_summary').slideToggle('normal', function() {
\$(this).prev('.ep_summaryTrigger').attr('src', function(i, src) {
return \$(this).next('.ep_summary').is(':visible') ? src.replace('plus','minus') : src.replace('minus','plus')
});
});
});
#set $fuzzydate = 'airdate'
#if $sickbeard.FUZZY_DATING:
fuzzyMoment({
dtInline : true,
dtGlue : ' at ',
containerClass : '.${fuzzydate}',
dateHasTime : true,
dateFormat : '${sickbeard.DATE_PRESET}',
timeFormat : '${sickbeard.TIME_PRESET}',
trimZero : #if $sickbeard.TRIM_ZERO then 'true' else 'false'#
});
#end if
});
//-->
</script>
#set $cur_segment = None
#set $too_late_header = False
#set $missed_header = False
#set $today_header = False
#set $show_div = 'ep_listing listing-default'
#if 'show' == $sort:
<br /><br />
#end if
#for $cur_result in $sql_results:
#set $cur_indexer = int($cur_result['indexer'])
<!-- start $cur_result['show_name'] //-->
#if int($cur_result['paused']) and not $sickbeard.COMING_EPS_DISPLAY_PAUSED:
#continue
#end if
#set $runtime = $cur_result['runtime']
#if 'network' == $sort:
#set $show_network = $cur_result['network'] if $cur_result['network'] else 'no network'
#if $cur_segment != $show_network:
<div class="comingepheader">
<br><h2 class="network">$show_network</h2>
#set $cur_segment = $cur_result['network']
#end if
#set $cur_ep_airdate = $cur_result['localtime'].date()
#if $runtime:
#set $cur_ep_enddate = $cur_result['localtime'] + datetime.timedelta(minutes = $runtime)
#if $cur_ep_enddate < $today:
#set $show_div = 'ep_listing listing-overdue'
#elif $cur_ep_airdate >= $next_week.date():
#set $show_div = 'ep_listing listing-toofar'
#elif $cur_ep_enddate >= $today and $cur_ep_airdate < $next_week.date():
#if $cur_ep_airdate == $today.date():
#set $show_div = 'ep_listing listing-current'
#else:
#set $show_div = 'ep_listing listing-default'
#end if
#end if
#end if
#elif 'date' == $sort:
#set $cur_ep_airdate = $cur_result['localtime'].date()
#if $cur_segment != $cur_ep_airdate:
#if $runtime:
#set $cur_ep_enddate = $cur_result['localtime'] + datetime.timedelta(minutes = $runtime)
#if $cur_ep_enddate < $today and $cur_ep_airdate != $today.date() and not $missed_header:
<br /><h2 class="day">Missed</h2>
#set $missed_header = True
#elif $cur_ep_airdate >= $next_week.date() and not $too_late_header:
<br /><h2 class="day">Later</h2>
#set $too_late_header = True
#elif $cur_ep_enddate >= $today and $cur_ep_airdate < $next_week.date():
#if $cur_ep_airdate == $today.date():
<br /><h2 class="day">$sbdatetime.sbdatetime.sbfdate($cur_ep_airdate, '%A').decode($sickbeard.SYS_ENCODING).capitalize() <span style="font-size: 14px; vertical-align: top;">[Today]</span></h2>
#set $today_header = True
#else:
<br /><h2 class="day">$sbdatetime.sbdatetime.sbfdate($cur_ep_airdate, '%A').decode($sickbeard.SYS_ENCODING).capitalize()</h2>
#end if
#end if
#end if
#set $cur_segment = $cur_ep_airdate
#end if
#if $cur_ep_airdate == $today.date() and not $today_header:
<div class="comingepheader">
<br /><h2 class="day">$sbdatetime.sbdatetime.sbfdate($cur_ep_airdate, '%A').decode($sickbeard.SYS_ENCODING).capitalize() <span style="font-size: 14px; vertical-align: top;">[Today]</span></h2>
#set $today_header = True
#end if
#if $runtime:
#set $cur_ep_enddate = $cur_result['localtime'] + datetime.timedelta(minutes = $runtime)
#if $cur_ep_enddate < $today:
#set $show_div = 'ep_listing listing-overdue'
#elif $cur_ep_airdate >= $next_week.date():
#set $show_div = 'ep_listing listing-toofar'
#elif $cur_ep_enddate >= $today and $cur_ep_airdate < $next_week.date():
#if $cur_ep_airdate == $today.date():
#set $show_div = 'ep_listing listing-current'
#else:
#set $show_div = 'ep_listing listing-default'
#end if
#end if
#end if
#elif 'show' == $sort:
#set $cur_ep_airdate = $cur_result['localtime'].date()
#if $runtime:
#set $cur_ep_enddate = $cur_result['localtime'] + datetime.timedelta(minutes = $runtime)
#if $cur_ep_enddate < $today:
#set $show_div = 'ep_listing listing-overdue listingradius'
#elif $cur_ep_airdate >= $next_week.date():
#set $show_div = 'ep_listing listing-toofar listingradius'
#elif $cur_ep_enddate >= $today and $cur_ep_airdate < $next_week.date():
#if $cur_ep_airdate == $today.date():
#set $show_div = 'ep_listing listing-current listingradius'
#else:
#set $show_div = 'ep_listing listing-default listingradius'
#end if
#end if
#end if
#end if
<div class="$show_div" id="listing-${cur_result['showid']}">
<div class="tvshowDiv">
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<th #if 'banner' == $layout then 'class="nobg"' else 'rowspan="2"'# valign="top">
<a href="$sbRoot/home/displayShow?show=${cur_result['showid']}"><img alt="" class="#if 'banner' == $layout then 'bannerThumb' else 'posterThumb'#" src="$sbRoot/showPoster/?show=${cur_result['showid']}&amp;which=#if 'poster' == $layout then 'poster_thumb' else $layout#" /></a>
</th>
#if 'banner' == $layout:
</tr>
<tr>
#end if
<td class="next_episode">
<div class="clearfix">
<span class="tvshowTitle">
<a href="$sbRoot/home/displayShow?show=${cur_result['showid']}">$cur_result['show_name']
#if int($cur_result['paused']):
<span class="pause">[paused]</span>
#end if
</a></span>
<span class="tvshowTitleIcons">
#if $cur_result['imdb_id']:
<a href="<%= anon_url('http://www.imdb.com/title/', cur_result['imdb_id']) %>" rel="noreferrer" onclick="window.open(this.href, '_blank'); return false" title="http://www.imdb.com/title/${cur_result['imdb_id']}"><img alt="[imdb]" height="16" width="16" src="$sbRoot/images/imdb.png" />
#end if
<a href="<%= anon_url(sickbeard.indexerApi(cur_indexer).config['show_url'], cur_result['showid']) %>" rel="noreferrer" onclick="window.open(this.href, '_blank'); return false" title="$sickbeard.indexerApi($cur_indexer).config['show_url']${cur_result['showid']}"><img alt="$sickbeard.indexerApi($cur_indexer).name" height="16" width="16" src="$sbRoot/images/$sickbeard.indexerApi($cur_indexer).config['icon']" /></a>
<span><a href="$sbRoot/home/searchEpisode?show=${cur_result['showid']}&amp;season=$cur_result['season']&amp;episode=$cur_result['episode']" title="Manual Search" id="forceUpdate-${cur_result['showid']}" class="epSearch forceUpdate"><img alt="[search]" height="16" width="16" src="$sbRoot/images/search16.png" id="forceUpdateImage-${cur_result['showid']}" /></a></span>
</span>
</div>
<span class="title">Next Episode:</span> <span><%= 'S%02iE%02i' % (int(cur_result['season']), int(cur_result['episode'])) %> - $cur_result['name']</span>
<div class="clearfix">
<span class="title">Airs: </span><span class="${fuzzydate}">$sbdatetime.sbdatetime.sbfdatetime($cur_result['localtime']).decode($sickbeard.SYS_ENCODING)</span><%= ('', '<span> on %s</span>' % str(cur_result['network']))[None is not cur_result['network']] %>
</div>
<div class="clearfix">
<span class="title">Quality:</span>
#if int($cur_result['quality']) in $qualityPresets:
<span class="quality $qualityPresetStrings[int($cur_result['quality'])]">$qualityPresetStrings[int($cur_result['quality'])]</span>
#else:
<span class="quality Custom">Custom</span>
#end if
</div>
</td>
</tr>
<tr>
<td style="vertical-align: top;">
<div>
#if $cur_result['description']:
<span class="title" style="vertical-align:middle;">Plot:</span>
<img class="ep_summaryTrigger" src="$sbRoot/images/plus.png" height="16" width="16" alt="" title="Toggle Summary" /><div class="ep_summary">$cur_result['description']</div>
#else:
<span class="title ep_summaryTriggerNone" style="vertical-align:middle;">Plot:</span>
<img class="ep_summaryTriggerNone" src="$sbRoot/images/plus.png" height="16" width="16" alt="" />
#end if
</div>
</td>
</tr>
</table>
</div>
</div>
<!-- end $cur_result['show_name'] //-->
#end for
<!-- end non list view //-->
#end if
#if 'calendar' == $layout:
#set $today = datetime.date.today()
#set $dates = [$today + datetime.timedelta(days = $i) for $i in range(7)]
#set $tbl_day = 0
<br>
<br>
<div class="calendarWrapper">
<input type="hidden" id="sbRoot" value="$sbRoot" />
#for $day in $dates
#set $tbl_day += 1
<table class="sickbeardTable tablesorter calendarTable <%= 'cal-%s' % (('even', 'odd')[1 == tbl_day % 2]) %>" cellspacing="0" border="0" cellpadding="0">
<thead><tr><th>$sbdatetime.sbdatetime.sbfdate($day, '%A').decode($sickbeard.SYS_ENCODING).capitalize()</th></tr></thead>
<tbody>
#set $day_has_show = False
#for $cur_result in $sql_results:
#if int($cur_result['paused']) and not $sickbeard.COMING_EPS_DISPLAY_PAUSED:
#continue
#end if
#set $cur_indexer = int($cur_result['indexer'])
#set $runtime = $cur_result['runtime']
#set $airday = $cur_result['localtime'].date()
#if $airday == $day:
#set $day_has_show = True
#set $airtime = $sbdatetime.sbdatetime.sbftime($cur_result['localtime']).decode($sickbeard.SYS_ENCODING)
#if $sickbeard.TRIM_ZERO:
#set $airtime = re.sub(r'0(\d:\d\d)', r'\1', $airtime, 0, re.IGNORECASE | re.MULTILINE)
#end if
<tr>
<td class="calendarShow">
<div class="poster">
<a title="${cur_result['show_name']}" href="$sbRoot/home/displayShow?show=${cur_result['showid']}"><img alt="" src="$sbRoot/showPoster/?show=${cur_result['showid']}&amp;which=poster_thumb" /></a>
</div>
<div class="text">
<span class="airtime">
${airtime} on $cur_result["network"]
</span>
<span class="episode-title" title="$cur_result['name']">
<%= 'S%02iE%02i' % (int(cur_result['season']), int(cur_result['episode'])) %> - $cur_result['name']
</span>
</div>
</td> <!-- end $cur_result['show_name'] -->
</tr>
#end if
#end for
#if not $day_has_show:
<tr><td class="calendarShow"><span class="show-status">No shows for this day</span></td></tr>
#end if
</tbody>
</table>
#end for
<!-- end calender view //-->
</div>
#end if
<div class="clearfix"></div>
<script type="text/javascript" charset="utf-8">
<!--
window.setInterval('location.reload(true)', 600000); // Refresh every 10 minutes
//-->
</script>
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_bottom.tmpl')

View file

@ -246,10 +246,10 @@
</div> </div>
<div class="field-pair show_if_fuzzy_dating#if True == $sickbeard.FUZZY_DATING then '' else ' metadataDiv'#"> <div class="field-pair show_if_fuzzy_dating#if True == $sickbeard.FUZZY_DATING then '' else ' metadataDiv'#">
<label for="trim_zero"> <label for="trim_zero">
<span class="component-title">Trim zero padding</span> <span class="component-title">Trim date and time</span>
<span class="component-desc"> <span class="component-desc">
<input type="checkbox" name="trim_zero" id="trim_zero" #if True == $sickbeard.TRIM_ZERO then 'checked="checked"' else ''#/> <input type="checkbox" name="trim_zero" id="trim_zero" #if True == $sickbeard.TRIM_ZERO then 'checked="checked"' else ''#/>
<p>remove the leading number "0" shown on hour of day, and date of month</p> <p>display minimalist date and time i.e. <del>02:00</del> = 2:00, <del>02:00pm</del> = 2pm, <del>03 Jan</del> = 3 Jan</p>
</span> </span>
</label> </label>
</div> </div>
@ -280,10 +280,11 @@
<span class="component-desc"> <span class="component-desc">
<select id="time_presets" name="time_preset" class="form-control input-sm"> <select id="time_presets" name="time_preset" class="form-control input-sm">
#for $cur_preset in $time_presets: #for $cur_preset in $time_presets:
<option value="$cur_preset" #if $cur_preset == $sickbeard.TIME_PRESET_W_SECONDS then 'selected="selected"' else ''#>$sbdatetime.now().sbftime(show_seconds=True,t_preset=$cur_preset)</option> #set $show_seconds = not $sickbeard.FUZZY_DATING
<option value="$cur_preset" #if $cur_preset == $sickbeard.TIME_PRESET_W_SECONDS then 'selected="selected"' else ''#>$sbdatetime.now().sbftime(show_seconds=$show_seconds, t_preset=$cur_preset)</option>
#end for #end for
</select> </select>
<span><b>note:</b> seconds are only shown on the History page</span> <span id="trim_info_seconds"><b>note:</b> seconds are only shown on the History page</span>
</span> </span>
</label> </label>
</div> </div>
@ -460,6 +461,24 @@
</label> </label>
</div> </div>
#set pulls = sickbeard.versionCheckScheduler.action.list_remote_pulls()
#if len(pulls) > 0 and $sickbeard.BRANCH != 'master':
<div class="field-pair">
<label>
<span class="component-title">Pull request:</span>
<span class="component-desc">
<select id="pullRequestVersion" class="form-control form-control-inline input-sm pull-left">
#for $cur_branch in $pulls:
<option value="$cur_branch.fetch_name()" #if $cur_branch == $sickbeard.BRANCH then 'selected="selected"' else ''#>$cur_branch</option>
#end for
</select>
<input class="btn btn-inline" style="margin-left: 6px;" type="button" id="pullRequestCheckout" value="Checkout Pull Request">
<div class="clear-left"><p>select pull request to test (restart required)</p></div>
</span>
</label>
</div>
#end if
<div class="field-pair"> <div class="field-pair">
<label for="git_remote"> <label for="git_remote">
<span class="component-title">Git remote for branch</span> <span class="component-title">Git remote for branch</span>
@ -551,7 +570,7 @@
</div><!-- /component-group3 //--> </div><!-- /component-group3 //-->
<br/> <br/>
<h6 class="pull-right"><b>All non-absolute folder locations are relative to <span class="path">$sickbeard.DATA_DIR</span></b> </h6> <h6 class="pull-right"><b class="boldest">All non-absolute folder locations are relative to <span class="path">$sickbeard.DATA_DIR</span></b></h6>
<input type="submit" class="btn pull-left config_submitter button" value="Save Changes" /> <input type="submit" class="btn pull-left config_submitter button" value="Save Changes" />
</div><!-- /config-components --> </div><!-- /config-components -->

View file

@ -214,13 +214,13 @@
</div> </div>
#end if #end if
#if $hasattr($curNewznabProvider, 'enable_daily'): #if $hasattr($curNewznabProvider, 'enable_recentsearch'):
<div class="field-pair"> <div class="field-pair">
<label for="${curNewznabProvider.getID()}_enable_daily"> <label for="${curNewznabProvider.getID()}_enable_recentsearch">
<span class="component-title">Enable daily searches</span> <span class="component-title">Enable recent searches</span>
<span class="component-desc"> <span class="component-desc">
<input type="checkbox" name="${curNewznabProvider.getID()}_enable_daily" id="${curNewznabProvider.getID()}_enable_daily" <%= html_checked if curNewznabProvider.enable_daily else '' %>/> <input type="checkbox" name="${curNewznabProvider.getID()}_enable_recentsearch" id="${curNewznabProvider.getID()}_enable_recentsearch" <%= html_checked if curNewznabProvider.enable_recentsearch else '' %>/>
<p>perform daily searches at provider</p> <p>perform recent searches at provider</p>
</span> </span>
</label> </label>
</div> </div>
@ -292,13 +292,13 @@
#end if #end if
#if $hasattr($curNzbProvider, 'enable_daily'): #if $hasattr($curNzbProvider, 'enable_recentsearch'):
<div class="field-pair"> <div class="field-pair">
<label for="${curNzbProvider.getID()}_enable_daily"> <label for="${curNzbProvider.getID()}_enable_recentsearch">
<span class="component-title">Enable daily searches</span> <span class="component-title">Enable recent searches</span>
<span class="component-desc"> <span class="component-desc">
<input type="checkbox" name="${curNzbProvider.getID()}_enable_daily" id="${curNzbProvider.getID()}_enable_daily" <%= html_checked if curNzbProvider.enable_daily else '' %>/> <input type="checkbox" name="${curNzbProvider.getID()}_enable_recentsearch" id="${curNzbProvider.getID()}_enable_recentsearch" <%= html_checked if curNzbProvider.enable_recentsearch else '' %>/>
<p>enable provider to perform daily searches.</p> <p>enable provider to perform recent searches.</p>
</span> </span>
</label> </label>
</div> </div>
@ -512,13 +512,13 @@
</div> </div>
#end if #end if
#if $hasattr($curTorrentProvider, 'enable_daily'): #if $hasattr($curTorrentProvider, 'enable_recentsearch'):
<div class="field-pair"> <div class="field-pair">
<label for="${curTorrentProvider.getID()}_enable_daily"> <label for="${curTorrentProvider.getID()}_enable_recentsearch">
<span class="component-title">Enable daily searches</span> <span class="component-title">Enable recent searches</span>
<span class="component-desc"> <span class="component-desc">
<input type="checkbox" name="${curTorrentProvider.getID()}_enable_daily" id="${curTorrentProvider.getID()}_enable_daily" <%= html_checked if curTorrentProvider.enable_daily else '' %>/> <input type="checkbox" name="${curTorrentProvider.getID()}_enable_recentsearch" id="${curTorrentProvider.getID()}_enable_recentsearch" <%= html_checked if curTorrentProvider.enable_recentsearch else '' %>/>
<p>enable provider to perform daily searches.</p> <p>enable provider to perform recent searches.</p>
</span> </span>
</label> </label>
</div> </div>

View file

@ -90,10 +90,10 @@
<div class="field-pair"> <div class="field-pair">
<label> <label>
<span class="component-title">Daily search frequency</span> <span class="component-title">Recent search frequency</span>
<span class="component-desc"> <span class="component-desc">
<input type="text" name="dailysearch_frequency" value="$sickbeard.DAILYSEARCH_FREQUENCY" class="form-control input-sm input75" /> <input type="text" name="recentsearch_frequency" value="$sickbeard.RECENTSEARCH_FREQUENCY" class="form-control input-sm input75" />
<p>time in minutes between searches (min. $sickbeard.MIN_DAILYSEARCH_FREQUENCY)</p> <p>time in minutes between searches (min. $sickbeard.MIN_RECENTSEARCH_FREQUENCY)</p>
</span> </span>
</label> </label>
</div> </div>
@ -139,11 +139,11 @@
</div> </div>
<div class="field-pair"> <div class="field-pair">
<label for="dailysearch_startup"> <label for="recentsearch_startup">
<span class="component-title">Daily search on startup</span> <span class="component-title">Recent search on startup</span>
<span class="component-desc"> <span class="component-desc">
<input type="checkbox" name="dailysearch_startup" id="dailysearch_startup" <%= html_checked if sickbeard.DAILYSEARCH_STARTUP == True else '' %>/> <input type="checkbox" name="recentsearch_startup" id="recentsearch_startup" <%= html_checked if sickbeard.RECENTSEARCH_STARTUP == True else '' %>/>
<p>start daily search on startup of SickGear</p> <p>start recent search on startup of SickGear</p>
</span> </span>
</label> </label>
</div> </div>
@ -421,6 +421,7 @@
<div class="clear-left"> <div class="clear-left">
<p id="host_desc_torrent">URL to your torrent client (e.g. http://localhost:8000/)</p> <p id="host_desc_torrent">URL to your torrent client (e.g. http://localhost:8000/)</p>
<p id="host_desc_rtorrent" style="display:none"><b>Note:</b> <i>rTorrent</i> client URLs use e.g. scgi://localhost:5000/</p> <p id="host_desc_rtorrent" style="display:none"><b>Note:</b> <i>rTorrent</i> client URLs use e.g. scgi://localhost:5000/</p>
<p id="host_desc_deluge" style="display:none">URL to your Deluge WebUI (e.g. http://localhost:8112/)</p>
</div> </div>
</span> </span>
</label> </label>
@ -436,7 +437,7 @@
</label> </label>
</div> </div>
<div class="field-pair"> <div class="field-pair" id="torrent_username_option">
<label> <label>
<span class="component-title" id="username_title">Client username</span> <span class="component-title" id="username_title">Client username</span>
<span class="component-desc"> <span class="component-desc">

View file

@ -0,0 +1,695 @@
#import sickbeard
#import datetime
#from sickbeard.common import *
#from sickbeard import sbdatetime
#from sickbeard.helpers import anon_url
#set global $title = 'Episode View'
#set global $header = 'Episode View'
#set global $sbPath = '..'
#set global $topmenu = 'episodeView'
#import os.path
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_top.tmpl')
#set $sort = $sickbeard.EPISODE_VIEW_SORT
#set $table_sort_header_codes = {'time': 0, 'show': 1, 'network': 4}
#if $sort not in $table_sort_header_codes:
#set $sort = 'time'
#end if
#if 'daybyday' != $layout:
<script type="text/javascript" src="$sbRoot/js/ajaxEpSearch.js?$sbPID"></script>
#end if
#if $varExists('header')
<h1 class="header">$header</h1>
#else
<h1 class="title">$title</h1>
#end if
#if 'daybyday' == $layout:
<script type="text/javascript" src="$sbRoot/js/plotTooltip.js?$sbPID"></script>
<script type="text/javascript" charset="utf-8">
<!--
\$(document).ready(function(){
var \$container = [];
\$.each(\$('[id^=day]'), function(){\$container.push(\$('#' + \$(this).attr('id')))});
jQuery.each(\$container, function(j) {
this.isotope({
itemSelector: '.daybyday-show',
sortBy : '$sort',
layoutMode: 'vertical',
transitionDuration: 0,
getSortData: {
network: function(itemElem) {
return \$(itemElem).attr('data-network') || '';
},
showname: function(itemElem) {
return \$(itemElem).attr('data-name') || '';
},
season: function(itemElem) {
var season = \$(itemElem).attr('data-season') || '0';
return season.length && parseInt(season, 10);
},
episode: function(itemElem) {
var episode = \$(itemElem).attr('data-episode') || '0';
return episode.length && parseInt(episode, 10);
},
time: function(itemElem) {
var time = \$(itemElem).attr('data-time') || '0';
return time.length && parseInt(time, 10);
}
}
});
});
imagesLoaded('.daybyday-show', function() {
jQuery.each(\$container, function(j) {
this.isotope('layout');
});
});
var uiSortBy = (function(sortBy) {
var sortCriteria;
switch (sortBy) {
case 'network':
sortCriteria = ['network', 'time', 'showname', 'season', 'episode'];
break;
case 'show':
sortCriteria = ['showname', 'time', 'season', 'episode'];
break;
case 'time':
default:
sortCriteria = ['time', 'showname', 'season', 'episode'];
break;
}
jQuery.each(\$container, function(j) {
this.isotope({
sortBy: sortCriteria,
sortAscending: 'asc' == \$('#sort-dir').attr('data-sort-dir')
});
});
});
\$('#sort').on('change', function() {
uiSortBy(this.value);
\$.get(this.options[this.selectedIndex].getAttribute('data-sort'));
});
\$('#sort-dir').on('click', function() {
var sortdir = \$(this).attr('data-sort-dir'),
newdir = ('asc' == sortdir ? 'desc' : 'asc');
\$(this).attr('data-sort-dir', newdir);
\$(this).attr('title', 'Click to sort ' + sortdir + 'ending');
\$(this).removeClass(sortdir).addClass(newdir);
uiSortBy(\$('#sort').val());
});
});
//-->
</script>
#end if
<style type="text/css">
#SubMenu {display:none}
#if 'daybyday' == $layout:
.caret {
cursor: pointer;
vertical-align: middle;
margin-right: 2px;
}
.asc {
border-top: 0;
border-bottom: 8px solid;
}
.desc {
border-top: 8px solid;
border-bottom: 0;
}
#end if
</style>
<div class="h2footer pull-right">
<span>Layout:
<select name="layout" class="form-control form-control-inline input-sm" onchange="location = this.options[this.selectedIndex].value;">
<option value="$sbRoot/setEpisodeViewLayout/?layout=banner" #if 'banner' == $sickbeard.EPISODE_VIEW_LAYOUT then 'selected="selected"' else ''#>Banner</option>
<option value="$sbRoot/setEpisodeViewLayout/?layout=daybyday" #if 'daybyday' == $sickbeard.EPISODE_VIEW_LAYOUT then 'selected="selected"' else ''#>Day by Day</option>
<option value="$sbRoot/setEpisodeViewLayout/?layout=list" #if 'list' == $sickbeard.EPISODE_VIEW_LAYOUT then 'selected="selected"' else ''#>List</option>
<option value="$sbRoot/setEpisodeViewLayout/?layout=poster" #if 'poster' == $sickbeard.EPISODE_VIEW_LAYOUT then 'selected="selected"' else ''#>Poster</option>
</select>
</span>
&nbsp;
<span>Sort
#if 'daybyday' == $layout:
<span id="sort-dir" data-sort-dir="asc" class="caret asc" title="Click to sort descending">&nbsp;</span>
#end if
By
#if 'daybyday' == $layout:
<select name="sort" id="sort" class="form-control form-control-inline input-sm">
<option value="network" data-sort="$sbRoot/setEpisodeViewSort/?sort=network&redir=0" #if 'network' == $sort then 'selected="selected"' else ''#>Network</option>
<option value="show" data-sort="$sbRoot/setEpisodeViewSort/?sort=show&redir=0" #if 'show' == $sort then 'selected="selected"' else ''#>Show</option>
<option value="time" data-sort="$sbRoot/setEpisodeViewSort/?sort=time&redir=0" #if 'time' == $sort then 'selected="selected"' else ''#>Time</option>
#else
<select name="sort" class="form-control form-control-inline input-sm" onchange="location = this.options[this.selectedIndex].value;">
<option value="$sbRoot/setEpisodeViewSort/?sort=time" #if 'time' == $sort then 'selected="selected"' else ''#>Date/Time</option>
<option value="$sbRoot/setEpisodeViewSort/?sort=network" #if 'network' == $sort then 'selected="selected"' else ''#>Network</option>
<option value="$sbRoot/setEpisodeViewSort/?sort=show" #if 'show' == $sort then 'selected="selected"' else ''#>Show</option>
#end if
</select>
</span>
&nbsp;
<span>View Paused:
<select name="viewpaused" class="form-control form-control-inline input-sm" onchange="location = this.options[this.selectedIndex].value;">
<option value="$sbRoot/toggleEpisodeViewDisplayPaused"<%= (' selected="selected"', '')[True == sickbeard.EPISODE_VIEW_DISPLAY_PAUSED] %>>Hidden</option>
<option value="$sbRoot/toggleEpisodeViewDisplayPaused"<%= ('', ' selected="selected"')[True == sickbeard.EPISODE_VIEW_DISPLAY_PAUSED] %>>Shown</option>
</select>
</span>
</div>
<div class="key pull-right">
#if 'daybyday' != $layout:
<b>Key:</b>
<span class="listing-key listing-overdue">Missed</span>
<span class="listing-key listing-current">Current</span>
<span class="listing-key listing-default">Future</span>
<span class="listing-key listing-toofar">Distant</span>
#end if
<a class="btn btn-inline forceBacklog" href="webcal://$sbHost:$sbHttpPort/calendar">
<i class="icon-calendar icon-white"></i>Subscribe</a>
</div>
<br>
#if 'list' == $layout:
<!-- start list view //-->
<script type="text/javascript" src="$sbRoot/js/plotTooltip.js?$sbPID"></script>
<script type="text/javascript" charset="utf-8">
<!--
\$.tablesorter.addParser({
id: 'loadingNames',
is: function(s) {
return false
},
format: function(s) {
if(0 == s.indexOf('Loading...'))
return s.replace('Loading...', '000')
return (s || '')
},
type: 'text'
});
\$.tablesorter.addParser({
id: 'quality',
is: function(s) {
return false
},
format: function(s) {
return s.replace('hd1080p', 5).replace('hd720p', 4).replace('hd', 3).replace('sd', 2).replace('any', 1).replace('best', 0).replace('custom', 7)
},
type: 'numeric'
});
\$.tablesorter.addParser({
id: 'cDate',
is: function(s) {
return false
},
format: function(s) {
return s
},
type: 'numeric'
});
\$(document).ready(function(){
sortList = [[$table_sort_header_codes[$sort], 0]];
\$('#showListTable:has(tbody tr)').tablesorter({
widgets: ['stickyHeaders'],
sortList: sortList,
textExtraction: {
0: function(node) {return \$(node).find('span').text().toLowerCase() || ''},
1: function(node) {return \$(node).find('a').attr('data-name') || ''},
4: function(node) {return \$(node).find('span').attr('data-network') || ''},
5: function(node) {return \$(node).find('span').text().toLowerCase() || ''}
},
headers: {
0: {sorter: 'cDate'},
1: {sorter: 'loadingNames'},
2: {sorter: false},
3: {sorter: false},
4: {sorter: 'loadingNames'},
5: {sorter: 'quality'},
6: {sorter: false},
7: {sorter: false},
8: {sorter: false}
}
});
\$('#sbRoot').ajaxEpSearch();
#set $fuzzydate = 'airdate'
#if $sickbeard.FUZZY_DATING:
fuzzyMoment({
containerClass : '.${fuzzydate}',
dateHasTime : true,
dateFormat : '${sickbeard.DATE_PRESET}',
timeFormat : '${sickbeard.TIME_PRESET}',
trimZero : #if $sickbeard.TRIM_ZERO then 'true' else 'false'#
});
#end if
});
//-->
</script>
#set $show_div = 'listing-default'
<input type="hidden" id="sbRoot" value="$sbRoot" />
<table id="showListTable" class="sickbeardTable tablesorter seasonstyle" cellspacing="1" border="0" cellpadding="0">
<thead>
<tr>
<th>Airdate</th>
<th>Show</th>
<th class="nowrap">Next Ep</th>
<th>Next Ep Name</th>
<th>Network</th>
<th>Quality</th>
<th>Indexers</th>
<th>Search</th>
</tr>
</thead>
<tbody style="text-shadow:none;">
#for $cur_result in $sql_results:
#set $cur_indexer = int($cur_result['indexer'])
#set $runtime = $cur_result['runtime']
#if int($cur_result['paused']) and not $sickbeard.EPISODE_VIEW_DISPLAY_PAUSED:
#continue
#end if
#set $cur_ep_airdate = $cur_result['localtime'].date()
#if $runtime:
#set $cur_ep_enddate = $cur_result['localtime'] + datetime.timedelta(minutes = $runtime)
#if $cur_ep_enddate < $today:
#set $show_div = 'listing-overdue'
#elif $cur_ep_airdate >= $next_week.date():
#set $show_div = 'listing-toofar'
#elif $cur_ep_airdate >= $today.date() and $cur_ep_airdate < $next_week.date():
#if $cur_ep_airdate == $today.date():
#set $show_div = 'listing-current'
#else:
#set $show_div = 'listing-default'
#end if
#end if
#end if
<!-- start $cur_result['show_name'] //-->
<tr class="$show_div">
## forced to use a div to wrap airdate, the column sort went crazy with a span
<td align="center" class="nowrap">
<div class="${fuzzydate}">$sbdatetime.sbdatetime.sbfdatetime($cur_result['localtime']).decode($sickbeard.SYS_ENCODING)</div><span class="sort_data">$time.mktime($cur_result['localtime'].timetuple())</span>
</td>
<td class="tvShow"><a href="$sbRoot/home/displayShow?show=${cur_result['showid']}" data-name="$cur_result['data_show_name']">$cur_result['show_name']</a>
#if int($cur_result['paused']):
<span class="pause">[paused]</span>
#end if
</td>
<td class="nowrap" align="center">
<%= 'S%02iE%02i' % (int(cur_result['season']), int(cur_result['episode'])) %>
</td>
<td>
#if $cur_result['description']:
<img alt="" src="$sbRoot/images/info32.png" height="16" width="16" class="plotInfo" id="plot_info_<%= '%s_%s_%s' % (str(cur_result['showid']), str(cur_result['season']), str(cur_result['episode'])) %>" />
#else:
<img alt="" src="$sbRoot/images/info32.png" width="16" height="16" class="plotInfoNone" />
#end if
$cur_result['name']
</td>
<td align="center">
<span data-network="$cur_result['data_network']">$cur_result['network']</span>
</td>
<td align="center">
#if int($cur_result['quality']) in $qualityPresets:
<span class="quality $qualityPresetStrings[int($cur_result['quality'])]">$qualityPresetStrings[int($cur_result['quality'])]</span>
#else:
<span class="quality Custom">Custom</span>
#end if
</td>
<td align="center" style="vertical-align: middle;">
#if $cur_result['imdb_id']:
<a href="<%= anon_url('http://www.imdb.com/title/', cur_result['imdb_id']) %>" rel="noreferrer" onclick="window.open(this.href, '_blank'); return false" title="http://www.imdb.com/title/${cur_result['imdb_id']}"><img alt="[imdb]" height="16" width="16" src="$sbRoot/images/imdb.png" />
#end if
<a href="<%= anon_url(sickbeard.indexerApi(cur_indexer).config['show_url'], cur_result['showid']) %>" rel="noreferrer" onclick="window.open(this.href, '_blank'); return false" title="$sickbeard.indexerApi($cur_indexer).config['show_url']${cur_result['showid']}"><img alt="$sickbeard.indexerApi($cur_indexer).name" height="16" width="16" src="$sbRoot/images/$sickbeard.indexerApi($cur_indexer).config['icon']" /></a>
</td>
<td align="center">
<a href="$sbRoot/home/searchEpisode?show=${cur_result['showid']}&amp;season=$cur_result['season']&amp;episode=$cur_result['episode']" title="Manual Search" id="forceUpdate-${cur_result['showid']}" class="forceUpdate epSearch"><img alt="[search]" height="16" width="16" src="$sbRoot/images/search16.png" id="forceUpdateImage-${cur_result['showid']}" /></a>
</td>
</tr>
<!-- end $cur_result['show_name'] //-->
#end for
</tbody>
<tfoot>
<tr>
<th rowspan="1" colspan="10" align="center">&nbsp</th>
</tr>
</tfoot>
</table>
<!-- end list view //-->
#else if $layout in ['banner', 'poster']:
<!-- start non list view //-->
<script type="text/javascript" charset="utf-8">
<!--
\$(document).ready(function(){
\$('#sbRoot').ajaxEpSearch({'size': 16, 'loadingImage': 'loading16' + themeSpinner + '.gif'});
\$('.ep_summary').hide();
\$('.ep_summaryTrigger').click(function() {
\$(this).next('.ep_summary').slideToggle('normal', function() {
\$(this).prev('.ep_summaryTrigger').attr('src', function(i, src) {
return \$(this).next('.ep_summary').is(':visible') ? src.replace('plus','minus') : src.replace('minus','plus')
});
});
});
#set $fuzzydate = 'airdate'
#if $sickbeard.FUZZY_DATING:
fuzzyMoment({
dtInline : true,
dtGlue : ' at ',
containerClass : '.${fuzzydate}',
dateHasTime : true,
dateFormat : '${sickbeard.DATE_PRESET}',
timeFormat : '${sickbeard.TIME_PRESET}',
trimZero : #if $sickbeard.TRIM_ZERO then 'true' else 'false'#
});
#end if
});
//-->
</script>
#set $cur_segment = None
#set $too_late_header = False
#set $missed_header = False
#set $today_header = False
#set $show_div = 'ep_listing listing-default'
#if 'show' == $sort:
<br /><br />
#end if
#for $cur_result in $sql_results:
#set $cur_indexer = int($cur_result['indexer'])
#if int($cur_result['paused']) and not $sickbeard.EPISODE_VIEW_DISPLAY_PAUSED:
#continue
#end if
#set $runtime = $cur_result['runtime']
#if 'network' == $sort:
#set $show_network = $cur_result['network'] if $cur_result['network'] else 'no network'
#if $cur_segment != $show_network:
<div class="episode-view-header">
<br><h2 class="network">$show_network</h2>
#set $cur_segment = $cur_result['network']
#end if
#set $cur_ep_airdate = $cur_result['localtime'].date()
#if $runtime:
#set $cur_ep_enddate = $cur_result['localtime'] + datetime.timedelta(minutes = $runtime)
#if $cur_ep_enddate < $today:
#set $show_div = 'ep_listing listing-overdue'
#elif $cur_ep_airdate >= $next_week.date():
#set $show_div = 'ep_listing listing-toofar'
#elif $cur_ep_enddate >= $today and $cur_ep_airdate < $next_week.date():
#if $cur_ep_airdate == $today.date():
#set $show_div = 'ep_listing listing-current'
#else:
#set $show_div = 'ep_listing listing-default'
#end if
#end if
#end if
#elif 'time' == $sort:
#set $cur_ep_airdate = $cur_result['localtime'].date()
#if $cur_segment != $cur_ep_airdate:
#if $runtime:
#set $cur_ep_enddate = $cur_result['localtime'] + datetime.timedelta(minutes = $runtime)
#if $cur_ep_enddate < $today and $cur_ep_airdate != $today.date() and not $missed_header:
<br /><h2 class="day">Missed</h2>
#set $missed_header = True
#elif $cur_ep_airdate >= $next_week.date() and not $too_late_header:
<br /><h2 class="day">Later</h2>
#set $too_late_header = True
#elif $cur_ep_enddate >= $today and $cur_ep_airdate < $next_week.date():
#if $cur_ep_airdate == $today.date():
<br /><h2 class="day">$sbdatetime.sbdatetime.sbfdate($cur_ep_airdate, '%A').decode($sickbeard.SYS_ENCODING).capitalize() <span style="font-size: 14px; vertical-align: top;">[Today]</span></h2>
#set $today_header = True
#else:
<br /><h2 class="day">$sbdatetime.sbdatetime.sbfdate($cur_ep_airdate, '%A').decode($sickbeard.SYS_ENCODING).capitalize()</h2>
#end if
#end if
#end if
#set $cur_segment = $cur_ep_airdate
#end if
#if $cur_ep_airdate == $today.date() and not $today_header:
<div class="episode-view-header">
<br /><h2 class="day">$sbdatetime.sbdatetime.sbfdate($cur_ep_airdate, '%A').decode($sickbeard.SYS_ENCODING).capitalize() <span style="font-size: 14px; vertical-align: top;">[Today]</span></h2>
#set $today_header = True
#end if
#if $runtime:
#set $cur_ep_enddate = $cur_result['localtime'] + datetime.timedelta(minutes = $runtime)
#if $cur_ep_enddate < $today:
#set $show_div = 'ep_listing listing-overdue'
#elif $cur_ep_airdate >= $next_week.date():
#set $show_div = 'ep_listing listing-toofar'
#elif $cur_ep_enddate >= $today and $cur_ep_airdate < $next_week.date():
#if $cur_ep_airdate == $today.date():
#set $show_div = 'ep_listing listing-current'
#else:
#set $show_div = 'ep_listing listing-default'
#end if
#end if
#end if
#elif 'show' == $sort:
#set $cur_ep_airdate = $cur_result['localtime'].date()
#if $runtime:
#set $cur_ep_enddate = $cur_result['localtime'] + datetime.timedelta(minutes = $runtime)
#if $cur_ep_enddate < $today:
#set $show_div = 'ep_listing listing-overdue listingradius'
#elif $cur_ep_airdate >= $next_week.date():
#set $show_div = 'ep_listing listing-toofar listingradius'
#elif $cur_ep_enddate >= $today and $cur_ep_airdate < $next_week.date():
#if $cur_ep_airdate == $today.date():
#set $show_div = 'ep_listing listing-current listingradius'
#else:
#set $show_div = 'ep_listing listing-default listingradius'
#end if
#end if
#end if
#end if
<!-- start $cur_result['show_name'] //-->
<div class="$show_div" id="listing-${cur_result['showid']}">
<div class="tvshowDiv">
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<th #if 'banner' == $layout then 'class="nobg"' else 'rowspan="2"'# valign="top">
<a href="$sbRoot/home/displayShow?show=${cur_result['showid']}"><img alt="" class="#if 'banner' == $layout then 'bannerThumb' else 'posterThumb'#" src="$sbRoot/showPoster/?show=${cur_result['showid']}&amp;which=#if 'poster' == $layout then 'poster_thumb' else $layout#" /></a>
</th>
#if 'banner' == $layout:
</tr>
<tr>
#end if
<td class="next_episode">
<div class="clearfix">
<span class="tvshowTitle">
<a href="$sbRoot/home/displayShow?show=${cur_result['showid']}" data-name="$cur_result['data_show_name']">$cur_result['show_name']
#if int($cur_result['paused']):
<span class="pause">[paused]</span>
#end if
</a></span>
<span class="tvshowTitleIcons">
#if $cur_result['imdb_id']:
<a href="<%= anon_url('http://www.imdb.com/title/', cur_result['imdb_id']) %>" rel="noreferrer" onclick="window.open(this.href, '_blank'); return false" title="http://www.imdb.com/title/${cur_result['imdb_id']}"><img alt="[imdb]" height="16" width="16" src="$sbRoot/images/imdb.png" />
#end if
<a href="<%= anon_url(sickbeard.indexerApi(cur_indexer).config['show_url'], cur_result['showid']) %>" rel="noreferrer" onclick="window.open(this.href, '_blank'); return false" title="$sickbeard.indexerApi($cur_indexer).config['show_url']${cur_result['showid']}"><img alt="$sickbeard.indexerApi($cur_indexer).name" height="16" width="16" src="$sbRoot/images/$sickbeard.indexerApi($cur_indexer).config['icon']" /></a>
<span><a href="$sbRoot/home/searchEpisode?show=${cur_result['showid']}&amp;season=$cur_result['season']&amp;episode=$cur_result['episode']" title="Manual Search" id="forceUpdate-${cur_result['showid']}" class="epSearch forceUpdate"><img alt="[search]" height="16" width="16" src="$sbRoot/images/search16.png" id="forceUpdateImage-${cur_result['showid']}" /></a></span>
</span>
</div>
<span class="title">Next Episode:</span> <span><%= 'S%02iE%02i' % (int(cur_result['season']), int(cur_result['episode'])) %> - $cur_result['name']</span>
<div class="clearfix">
<span class="title">Airdate: </span><span class="${fuzzydate}">$sbdatetime.sbdatetime.sbfdatetime($cur_result['localtime']).decode($sickbeard.SYS_ENCODING)</span><%= ('', '<span> on %s</span>' % str(cur_result['network']))[None is not cur_result['network']] %>
</div>
<div class="clearfix">
<span class="title">Quality:</span>
#if int($cur_result['quality']) in $qualityPresets:
<span class="quality $qualityPresetStrings[int($cur_result['quality'])]">$qualityPresetStrings[int($cur_result['quality'])]</span>
#else:
<span class="quality Custom">Custom</span>
#end if
</div>
</td>
</tr>
<tr>
<td style="vertical-align: top;">
<div>
#if $cur_result['description']:
<span class="title" style="vertical-align:middle;">Plot:</span>
<img class="ep_summaryTrigger" src="$sbRoot/images/plus.png" height="16" width="16" alt="" title="Toggle Summary" /><div class="ep_summary">$cur_result['description']</div>
#else:
<span class="title ep_summaryTriggerNone" style="vertical-align:middle;">Plot:</span>
<img class="ep_summaryTriggerNone" src="$sbRoot/images/plus.png" height="16" width="16" alt="" />
#end if
</div>
</td>
</tr>
</table>
</div>
</div>
<!-- end $cur_result['show_name'] //-->
#end for
<!-- end non list view //-->
#end if
#if 'daybyday' == $layout:
#set $today = datetime.date.today()
#set $dates = [$today + datetime.timedelta(days = $i) for $i in range(7)]
#set $tbl_day = 0
<input type="hidden" id="sbRoot" value="$sbRoot" />
<br>
<br>
<div class="daybydayWrapper"> <!-- style="width:1600px" -->
#for $day in $dates
#set $tbl_day += 1
#set $col_class = ''
#if 1 == $tbl_day
#set $col_class = 'today'
#end if
#set $col_class = '%s %s' % ($col_class, ('even', 'odd')[1 == tbl_day % 2])
<div class="day-of-week $col_class">
<div class="day-number">
<div class="number">$sbdatetime.sbdatetime.sbfdate($day, ' %d').decode($sickbeard.SYS_ENCODING).replace(' 0', ' ')</div>
<div class="day">
<span class="visible-lg">$sbdatetime.sbdatetime.sbfdate($day, '%A').decode($sickbeard.SYS_ENCODING).capitalize()</span>
<span class="hidden-lg">$sbdatetime.sbdatetime.sbfdate($day, '%a').decode($sickbeard.SYS_ENCODING).capitalize()</span>
</div>
<div class="month">
<span class="visible-lg">$sbdatetime.sbdatetime.sbfdate($day, '%B').decode($sickbeard.SYS_ENCODING).capitalize()</span>
<span class="hidden-lg">$sbdatetime.sbdatetime.sbfdate($day, '%b').decode($sickbeard.SYS_ENCODING).capitalize()</span>
</div>
</div>
<div id="$sbdatetime.sbdatetime.sbfdate($day, 'day%w')">
#set $day_has_show = False
#for $cur_result in $sql_results:
#if int($cur_result['paused']) and not $sickbeard.EPISODE_VIEW_DISPLAY_PAUSED:
#continue
#end if
#set $cur_indexer = int($cur_result['indexer'])
#set $runtime = $cur_result['runtime']
#set $airday = $cur_result['localtime'].date()
#if $airday == $day:
#set $day_has_show = True
#set $airtime = $sbdatetime.sbdatetime.sbftime($cur_result['localtime'], markup=True).decode($sickbeard.SYS_ENCODING)
#set $img_tag = '<img'
#set $plot_class = 'class="img-responsive'
#set $title_text = ''
#if $cur_result['description']:
#set $img_tag += ' id="plot_info_%s_%s_%s"' % (str($cur_result['showid']), str($cur_result['season']), str($cur_result['episode']))
#set $plot_class += ' plot-daybyday'
#else
#set $title_text = $cur_result['show_name']
#end if
<div id="show-$cur_result['showid']" class="daybyday-show" data-name="$cur_result['data_show_name']" data-season="$cur_result['season']" data-episode="$cur_result['episode']" data-network="$cur_result['data_network']" data-time="$time.mktime($cur_result['localtime'].timetuple())">
<div class="poster">
<a title="${title_text}" href="$sbRoot/home/displayShow?show=${cur_result['showid']}">
${img_tag} ${plot_class}" alt="" src="$sbRoot/showPoster/?show=${cur_result['showid']}&amp;which=poster_thumb" /></a>
</div>
<div class="text">
<div class="airtime">
<span class="time">${airtime}</span> <span class="network pull-right grey-text">$cur_result['network']</span>
</div>
<div class="episode" title="$cur_result['name']">
<span class="season"><%= '%i' % int(cur_result['season']) %></span>x<span class="number"><%= '%02i' % int(cur_result['episode']) %></span>
<span class="name">$cur_result['name']</span>
#if int($cur_result['paused']):
<span class="pause">[paused]</span>
#end if
</div>
</div>
</div><!-- end show-$cur_result['showid'] //-->
#end if
#end for
#if not $day_has_show:
<div class="daybyday-show">
<span class="episode-blank">No shows for this day</span>
</div>
#end if
</div>
</div>
#end for
</div>
<!-- end calender view //-->
#end if
<div class="clearfix"></div>
<script type="text/javascript" charset="utf-8">
<!--
window.setInterval('location.reload(true)', 30*60000); // Refresh every xx minutes
//-->
</script>
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_bottom.tmpl')

View file

@ -366,13 +366,13 @@ $myShowList.sort(lambda x, y: cmp(x.name, y.name))
if (classvalue<20) { if (classvalue<20) {
classtoadd = "progress-20" classtoadd = "progress-20"
} }
if (classvalue>20 && classvalue<60) { if (classvalue>=20 && classvalue<60) {
classtoadd = "progress-40" classtoadd = "progress-40"
} }
if (classvalue>40 && classvalue<80) { if (classvalue>=40 && classvalue<80) {
classtoadd = "progress-60" classtoadd = "progress-60"
} }
if (classvalue>80) { if (classvalue>=80) {
classtoadd = "progress-80" classtoadd = "progress-80"
} }
\$("\#progressbar$curShow.indexerid > .ui-progressbar-value").addClass(classtoadd); \$("\#progressbar$curShow.indexerid > .ui-progressbar-value").addClass(classtoadd);
@ -596,13 +596,13 @@ $myShowList.sort(lambda x, y: cmp(x.name, y.name))
if (classvalue<20) { if (classvalue<20) {
classtoadd = "progress-20" classtoadd = "progress-20"
} }
if (classvalue>20 && classvalue<60) { if (classvalue>=20 && classvalue<60) {
classtoadd = "progress-40" classtoadd = "progress-40"
} }
if (classvalue>40 && classvalue<80) { if (classvalue>=40 && classvalue<80) {
classtoadd = "progress-60" classtoadd = "progress-60"
} }
if (classvalue>80) { if (classvalue>=80) {
classtoadd = "progress-80" classtoadd = "progress-80"
} }
\$("\#progressbar$curShow.indexerid > .ui-progressbar-value").addClass(classtoadd); \$("\#progressbar$curShow.indexerid > .ui-progressbar-value").addClass(classtoadd);

View file

@ -11,7 +11,7 @@
#set global $sbPath='..' #set global $sbPath='..'
#set global $topmenu='comingEpisodes' #set global $topmenu='episodeView'
#import os.path #import os.path
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_top.tmpl') #include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_top.tmpl')
@ -129,7 +129,7 @@
#else #else
#for $cur_show in $trending_shows: #for $cur_show in $trending_shows:
#set $image = re.sub(r'(.*)(\..*?)$', r'\1-300\2', $cur_show['images']['poster'], 0, re.IGNORECASE | re.MULTILINE) #set $image = re.sub(r'(.*)/original/(.+)$', r'\1/thumb/\2', $cur_show['images']['poster'], 0, re.IGNORECASE | re.MULTILINE)
<div class="trakt_show <%= ('notinlibrary', 'inlibrary')[':' in cur_show['show_id']] %>" data-name="$cur_show['title']" data-rating="$cur_show['ratings']['percentage']" data-votes="$cur_show['ratings']['votes']"> <div class="trakt_show <%= ('notinlibrary', 'inlibrary')[':' in cur_show['show_id']] %>" data-name="$cur_show['title']" data-rating="$cur_show['ratings']['percentage']" data-votes="$cur_show['ratings']['votes']">
<div class="traktContainer"> <div class="traktContainer">

View file

@ -62,7 +62,7 @@
)[0 < ep_snatched] )[0 < ep_snatched]
%> %>
&nbsp;/&nbsp;<span class="footerhighlight">$ep_total</span> episodes downloaded &nbsp;/&nbsp;<span class="footerhighlight">$ep_total</span> episodes downloaded
| daily search: <span class="footerhighlight"><%= str(sickbeard.dailySearchScheduler.timeLeft()).split('.')[0] %></span> | recent search: <span class="footerhighlight"><%= str(sickbeard.recentSearchScheduler.timeLeft()).split('.')[0] %></span>
| backlog search: <span class="footerhighlight">$sbdatetime.sbdatetime.sbfdate($sickbeard.backlogSearchScheduler.nextRun())</span> | backlog search: <span class="footerhighlight">$sbdatetime.sbdatetime.sbfdate($sickbeard.backlogSearchScheduler.nextRun())</span>
</div> </div>

View file

@ -57,6 +57,7 @@
<script type="text/javascript" src="$sbRoot/js/lib/jquery.form-3.35.js?$sbPID"></script> <script type="text/javascript" src="$sbRoot/js/lib/jquery.form-3.35.js?$sbPID"></script>
<script type="text/javascript" src="$sbRoot/js/lib/jquery.ui.touch-punch-0.2.2.min.js?$sbPID"></script> <script type="text/javascript" src="$sbRoot/js/lib/jquery.ui.touch-punch-0.2.2.min.js?$sbPID"></script>
<script type="text/javascript" src="$sbRoot/js/lib/isotope.pkgd.min.js?$sbPID"></script> <script type="text/javascript" src="$sbRoot/js/lib/isotope.pkgd.min.js?$sbPID"></script>
<script type="text/javascript" src="$sbRoot/js/lib/imagesloaded.pkgd.min.js?$sbPID"></script>
<script type="text/javascript" src="$sbRoot/js/lib/jquery.confirm.js?$sbPID"></script> <script type="text/javascript" src="$sbRoot/js/lib/jquery.confirm.js?$sbPID"></script>
<script type="text/javascript" src="$sbRoot/js/script.js?$sbPID"></script> <script type="text/javascript" src="$sbRoot/js/script.js?$sbPID"></script>
@ -149,8 +150,8 @@
</ul> </ul>
</li> </li>
<li id="NAVcomingEpisodes"> <li id="NAVepisodeView">
<a href="$sbRoot/comingEpisodes/" tabindex="$tab#set $tab += 1#">Coming Episodes</a> <a href="$sbRoot/episodeView/" tabindex="$tab#set $tab += 1#">Episodes</a>
</li> </li>
<li id="NAVhistory"> <li id="NAVhistory">
@ -261,6 +262,6 @@
#except (NameError, NotFound): #except (NameError, NotFound):
#pass #pass
#end try #end try
#set $page_class = ('', ' class="%s"' % '_'.join($items).lower().replace(' ', '-'))[0 < len($items)] #set $page_class = ('', ' class="%s"' % '_'.join($items).lower().replace(' ', '-').replace('_', '-'))[0 < len($items)]
<div id="contentWrapper"> <div id="contentWrapper">
<div id="content"$page_class> <div id="content"$page_class>

View file

@ -29,9 +29,9 @@ Currently running<br />
#end if #end if
<br /> <br />
<h3>Daily Search:</h3> <h3>Recent Search:</h3>
<a class="btn" href="$sbRoot/manage/manageSearches/forceSearch"><i class="icon-exclamation-sign"></i> Force</a> <a class="btn" href="$sbRoot/manage/manageSearches/forceSearch"><i class="icon-exclamation-sign"></i> Force</a>
#if not $dailySearchStatus: #if not $recentSearchStatus:
Not in progress<br /> Not in progress<br />
#else: #else:
In Progress<br /> In Progress<br />
@ -53,7 +53,7 @@ In Progress<br />
<h3>Search Queue:</h3> <h3>Search Queue:</h3>
Backlog: <i>$queueLength['backlog'] pending items</i></br> Backlog: <i>$queueLength['backlog'] pending items</i></br>
Daily: <i>$queueLength['daily'] pending items</i></br> Recent: <i>$queueLength['recent'] pending items</i></br>
Manual: <i>$queueLength['manual'] pending items</i></br> Manual: <i>$queueLength['manual'] pending items</i></br>
Failed: <i>$queueLength['failed'] pending items</i></br> Failed: <i>$queueLength['failed'] pending items</i></br>
</div> </div>

View file

@ -1,45 +1,87 @@
$(document).ready(function(){ $(document).ready(function(){
$('.enabler').each(function(){ var enabler = $('.enabler'),
viewIf = $('.viewIf');
enabler.each(function(){
if (!$(this).prop('checked')) if (!$(this).prop('checked'))
$('#content_' + $(this).attr('id')).hide(); $('#content_' + $(this).attr('id')).hide();
}); });
$('.enabler').click(function(){ enabler.click(function(){
var content_id = $('#content_' + $(this).attr('id'));
if ($(this).prop('checked')) if ($(this).prop('checked'))
$('#content_' + $(this).attr('id')).fadeIn('fast', 'linear'); content_id.fadeIn('fast', 'linear');
else else
$('#content_' + $(this).attr('id')).fadeOut('fast', 'linear'); content_id.fadeOut('fast', 'linear');
}); });
$('.viewIf').click(function(){ viewIf.each(function(){
$(($(this).prop('checked') ? '.hide_if_' : '.show_if_') + $(this).attr('id')).hide();
});
viewIf.click(function(){
var if_id = '_if_' + $(this).attr('id');
if ($(this).prop('checked')) { if ($(this).prop('checked')) {
$('.hide_if_' + $(this).attr('id')).css('display','none'); $('.hide' + if_id).fadeOut('fast', 'linear');
$('.show_if_' + $(this).attr('id')).fadeIn('fast', 'linear'); $('.show' + if_id).fadeIn('fast', 'linear');
} else { } else {
$('.show_if_' + $(this).attr('id')).css('display','none'); $('.show' + if_id).fadeOut('fast', 'linear');
$('.hide_if_' + $(this).attr('id')).fadeIn('fast', 'linear'); $('.hide' + if_id).fadeIn('fast', 'linear');
} }
}); });
var ui_update_trim_zero = (function() {
var secs = ('00' + new Date().getSeconds().toString()).slice(-2),
elSecs = $('#trim_info_seconds'),
elTrimZero = $('#trim_zero');
elTrimZero.each(function() {
var checked = $(this).prop('checked') && $('#fuzzy_dating').prop('checked');
$('#time_presets').find('option').each(function() {
var text = ($(this).text());
$(this).text(checked
? text.replace(/(\b\d+:\d\d):\d+/mg, '$1')
: text.replace(/(\b\d+:\d\d)(?:.\d+)?/mg, '$1:' + secs));
});
});
if ($('#fuzzy_dating').prop('checked'))
if (elTrimZero.prop('checked'))
elSecs.fadeOut('fast', 'linear');
else
elSecs.fadeIn('fast', 'linear');
else
elSecs.fadeIn('fast', 'linear');
});
$('#trim_zero, #fuzzy_dating').click(function() {
ui_update_trim_zero();
});
ui_update_trim_zero();
$('.datePresets').click(function(){ $('.datePresets').click(function(){
var def = $('#date_presets').val() var elDatePresets = $('#date_presets'),
if ($(this).prop('checked') && '%x' == def) { defaultPreset = elDatePresets.val();
def = '%a, %b %d, %Y' if ($(this).prop('checked') && '%x' == defaultPreset) {
defaultPreset = '%a, %b %d, %Y';
$('#date_use_system_default').html('1') $('#date_use_system_default').html('1')
} else if (!$(this).prop('checked') && '1' == $('#date_use_system_default').html()) } else if (!$(this).prop('checked') && '1' == $('#date_use_system_default').html())
def = '%x' defaultPreset = '%x';
$('#date_presets').attr('name', 'date_preset_old') elDatePresets.attr('name', 'date_preset_old');
$('#date_presets').attr('id', 'date_presets_old') elDatePresets.attr('id', 'date_presets_old');
$('#date_presets_na').attr('name', 'date_preset') var elDatePresets_na = $('#date_presets_na');
$('#date_presets_na').attr('id', 'date_presets') elDatePresets_na.attr('name', 'date_preset');
elDatePresets_na.attr('id', 'date_presets');
$('#date_presets_old').attr('name', 'date_preset_na') var elDatePresets_old = $('#date_presets_old');
$('#date_presets_old').attr('id', 'date_presets_na') elDatePresets_old.attr('name', 'date_preset_na');
elDatePresets_old.attr('id', 'date_presets_na');
if (def) if (defaultPreset)
$('#date_presets').val(def) elDatePresets.val(defaultPreset)
}); });
// bind 'myForm' and provide a simple callback function // bind 'myForm' and provide a simple callback function
@ -69,8 +111,11 @@ $(document).ready(function(){
}); });
$('#branchCheckout').click(function(){ $('#branchCheckout').click(function(){
url = sbRoot + '/home/branchCheckout?branch=' + $('#branchVersion').val(); window.location.href = sbRoot + '/home/branchCheckout?branch=' + $('#branchVersion').val();
window.location.href = url; });
$('#pullRequestCheckout').click(function(){
window.location.href = sbRoot + '/home/pullRequestCheckout?branch=' + $('#pullRequestVersion').val();
}); });
}); });

View file

@ -62,7 +62,9 @@ $(document).ready(function(){
$(label_warning_deluge).hide(); $(label_warning_deluge).hide();
$(host_desc_rtorrent).hide(); $(host_desc_rtorrent).hide();
$(host_desc_deluge).hide();
$(host_desc_torrent).show(); $(host_desc_torrent).show();
$(torrent_username_option).show();
$(torrent_verify_cert_option).hide(); $(torrent_verify_cert_option).hide();
$(torrent_path_option).show(); $(torrent_path_option).show();
$(torrent_path_option).find('.fileBrowser').show(); $(torrent_path_option).find('.fileBrowser').show();
@ -86,6 +88,9 @@ $(document).ready(function(){
client = 'Deluge'; client = 'Deluge';
$(torrent_verify_cert_option).show(); $(torrent_verify_cert_option).show();
$(label_warning_deluge).show(); $(label_warning_deluge).show();
$(host_desc_torrent).hide();
$(host_desc_deluge).show();
$(torrent_username_option).hide();
//$('#directory_title').text(client + directory); //$('#directory_title').text(client + directory);
} else if ('download_station' == selectedProvider){ } else if ('download_station' == selectedProvider){
client = 'Synology DS'; client = 'Synology DS';

View file

@ -21,11 +21,11 @@
jd = (function (str) { jd = (function (str) {
var token_map = ['a', 'ddd', 'A', 'dddd', 'b', 'MMM', 'B', 'MMMM', 'd', 'DD', 'm', 'MM', 'y', 'YY', 'Y', 'YYYY', 'x', 'L', var token_map = ['a', 'ddd', 'A', 'dddd', 'b', 'MMM', 'B', 'MMMM', 'd', 'DD', 'm', 'MM', 'y', 'YY', 'Y', 'YYYY', 'x', 'L',
'H', 'HH', 'I', 'hh', 'M', 'mm', 'S', 'ss', 'p', 'A'], 'H', 'HH', 'I', 'hh', 'M', 'mm', 'S', 'ss', 'p', 'A', 'P', 'a'],
result = ''; result = '';
for (var i = 0; i < str.length; i++) for (var i = 0; i < str.length; i++)
if (/[aAbBdmyYxHIMSp]/.test(str[i])) { if (/[aAbBdmyYxHIMSpP]/.test(str[i])) {
for (var t = 0; t < token_map.length; t = t + 2) for (var t = 0; t < token_map.length; t = t + 2)
if (str[i] == token_map[t]) { if (str[i] == token_map[t]) {
result += token_map[t + 1]; result += token_map[t + 1];
@ -36,8 +36,8 @@
return result; return result;
}), }),
dateToken = jd(dateFormat), dateTemplate = jd(dateFormat),
timeToken = jd(timeFormat), timeTemplate = jd(timeFormat),
addQTip = (function() { addQTip = (function() {
$(this).css('cursor', 'help'); $(this).css('cursor', 'help');
@ -60,32 +60,50 @@
}); });
if (trimZero) { if (trimZero) {
timeToken = timeToken.replace(/hh/ig, 'h'); timeTemplate = timeTemplate.replace(/hh/g, 'h');
dateToken = dateToken.replace(/\bDD\b/g, 'D'); timeTemplate = timeTemplate.replace(/HH/g, 'H');
dateTemplate = dateTemplate.replace(/\bDD\b/g, 'D');
} }
$(containerClass).each(function() { $(containerClass).each(function() {
var input = $(this).text(), var input = $(this).text(),
dateA = '[<span class="fd">', dateA = '[<span class="fd">',
dtSeparator = ' ', dtSeparator = ' ',
timeA = '</span>]', timeB = '[' + timeA; timeA = '</span>]', timeB = '[' + timeA,
timeToken = timeTemplate;
if (dateWithTime) { if (dateWithTime) {
var timeMeta = input.match(/^.{6,}?([,\s]+)(\d{1,2}).(?:\d{2,2})(?:.(\d{2,2}))?(?:\s([ap]m))?$/im); var timeMeta = input.match(/([,\s]+)(\d{1,2})(?:(.)(\d\d)(?:(.)(\d\d))?)?(?:\s?([ap]m))?$/im);
if (null != timeMeta) { if (null != timeMeta) {
dtSeparator = (! /undefined/i.test(typeof(timeMeta[1])) ? timeMeta[1] : dtSeparator); dtSeparator = (! /undefined/i.test(typeof(timeMeta[1])) ? timeMeta[1] : dtSeparator);
// adjust timeToken to num digits of input hours // adjust timeToken to num digits of input hours
timeToken = (! /undefined/i.test(typeof(timeMeta[2])) && 1 == timeMeta[2].length ? timeToken.replace(/hh/ig, 'h') : timeToken); timeToken = (! /undefined/i.test(typeof(timeMeta[2])) && 1 == timeMeta[2].length ? timeToken.replace(/hh/ig, 'h') : timeToken);
// adjust timeToken to remove min if input has one and there is a pm
timeToken = (trimZero && ! /undefined/i.test(typeof(timeMeta[7]))
&& (/undefined/i.test(typeof(timeMeta[4]))
|| '00' == timeMeta[4]) ? timeToken.replace(/.mm/ig, '') : timeToken);
// adjust timeToken to use seconds if input has them // adjust timeToken to use seconds if input has them
timeToken = (! /undefined/i.test(typeof(timeMeta[3])) && 2 == timeMeta[3].length ? timeToken : timeToken.replace(/.ss/, '')); timeToken = (! /undefined/i.test(typeof(timeMeta[5])) && 2 == timeMeta[5].length ? timeToken : timeToken.replace(/.ss/, ''));
// adjust timeToken to am/pm or AM/PM if input has it // adjust timeToken to am/pm or AM/PM if input has it
timeToken = (! /undefined/i.test(typeof(timeMeta[4])) && 2 == timeMeta[4].length ? timeToken.replace(/A$/, (/[ap]m/.test(timeMeta[4]) ? 'a' : 'A')) : timeToken); timeToken = (! /undefined/i.test(typeof(timeMeta[7])) && 2 == timeMeta[7].length ? timeToken.replace(/A$/, (/[ap]m/.test(timeMeta[7]) ? 'a' : 'A')) : timeToken);
} }
var token_build = (/h+/i.test(timeToken) ? timeToken.replace(/^(h+).*/i, '[<span class="time-hr">]$1[</span>]') : '');
if (/m+/i.test(timeToken)) {
token_build += (! /undefined/i.test(typeof(timeMeta[3])) ? '[<span class="time-hr-min">]' + timeMeta[3] + '[</span>]' : '')
+ (! /undefined/i.test(typeof(timeMeta[4])) ? timeToken.replace(/.*?(m+).*/i, '[<span class="time-min">]$1[</span>]') : '');
if (/s+/i.test(timeToken)) {
token_build += (! /undefined/i.test(typeof(timeMeta[5])) ? '[<span class="time-min-sec">]' + timeMeta[5] + '[</span>]' : '')
+ (! /undefined/i.test(typeof(timeMeta[6])) ? timeToken.replace(/.*?(s+).*/i, '[<span class="time-sec">]$1[</span>]') : '');
}
}
timeToken = token_build + (! /undefined/i.test(typeof(timeMeta[7])) ? timeToken.replace(/.*?[\s0-9](a).*/i, '[<span class="time-am-pm">]$1[</span>]') : '');
timeA = '</span>' + dtGlue + '<span class="ft">]' + timeToken + '[' + timeA; timeA = '</span>' + dtGlue + '<span class="ft">]' + timeToken + '[' + timeA;
timeB = '[</span>' + dtGlue + '<span class="ft">]' + timeToken + timeB; timeB = '[</span>' + dtGlue + '<span class="ft">]' + timeToken + timeB;
} }
var inputTokens = dateToken + dtSeparator + (dateWithTime ? timeToken : 'HH:mm:ss'); var inputTokens = dateTemplate + dtSeparator + (dateWithTime ? timeToken : 'HH:mm:ss');
if (! moment(input + (dateWithTime ? '' : dtSeparator + '00:00:00'), inputTokens).isValid()) if (! moment(input + (dateWithTime ? '' : dtSeparator + '00:00:00'), inputTokens).isValid())
return; return;
@ -152,11 +170,11 @@
if (dateWithTime && qTipTime) if (dateWithTime && qTipTime)
$(this).attr('title',(n?'4) ':'') + airdatetime.format(inputTokens)).each(addQTip); $(this).attr('title',(n?'4) ':'') + airdatetime.format(inputTokens)).each(addQTip);
else else
$(this).attr('title',(n?'5) ':'') + airdate.format(dateToken)).each(addQTip); $(this).attr('title',(n?'5) ':'') + airdate.format(dateTemplate)).each(addQTip);
else else
if (dateWithTime && qTipTime) if (dateWithTime && qTipTime)
$(this).find('.ft').attr('title',(n?'6) ':'') + airdatetime.format(inputTokens)).each(addQTip); $(this).find('.ft').attr('title',(n?'6) ':'') + airdatetime.format(inputTokens)).each(addQTip);
else else
$(this).find('.ft').attr('title',(n?'7) ':'') + airdate.format(dateToken)).each(addQTip); $(this).find('.ft').attr('title',(n?'7) ':'') + airdate.format(dateTemplate)).each(addQTip);
}); });
} }

File diff suppressed because one or more lines are too long

View file

@ -1,5 +1,5 @@
$(function () { $(function () {
$('.plotInfo').each(function () { $('.plotInfo, .plot-daybyday').each(function () {
var match = $(this).attr('id').match(/^plot_info_(\d+)_(\d+)_(\d+)$/); var match = $(this).attr('id').match(/^plot_info_(\d+)_(\d+)_(\d+)$/);
$(this).qtip({ $(this).qtip({
content: { content: {

View file

@ -42,7 +42,7 @@ from sickbeard import searchBacklog, showUpdater, versionChecker, properFinder,
from sickbeard import helpers, db, exceptions, show_queue, search_queue, scheduler, show_name_helpers from sickbeard import helpers, db, exceptions, show_queue, search_queue, scheduler, show_name_helpers
from sickbeard import logger from sickbeard import logger
from sickbeard import naming from sickbeard import naming
from sickbeard import dailysearcher from sickbeard import searchRecent
from sickbeard import scene_numbering, scene_exceptions, name_cache from sickbeard import scene_numbering, scene_exceptions, name_cache
from indexers.indexer_api import indexerApi from indexers.indexer_api import indexerApi
from indexers.indexer_exceptions import indexer_shownotfound, indexer_exception, indexer_error, indexer_episodenotfound, \ from indexers.indexer_exceptions import indexer_shownotfound, indexer_exception, indexer_error, indexer_episodenotfound, \
@ -58,7 +58,7 @@ CFG = None
CONFIG_FILE = None CONFIG_FILE = None
# This is the version of the config we EXPECT to find # This is the version of the config we EXPECT to find
CONFIG_VERSION = 5 CONFIG_VERSION = 7
# Default encryption version (0 for None) # Default encryption version (0 for None)
ENCRYPTION_VERSION = 0 ENCRYPTION_VERSION = 0
@ -78,7 +78,7 @@ NO_RESIZE = False
# system events # system events
events = None events = None
dailySearchScheduler = None recentSearchScheduler = None
backlogSearchScheduler = None backlogSearchScheduler = None
showUpdateScheduler = None showUpdateScheduler = None
versionCheckScheduler = None versionCheckScheduler = None
@ -196,19 +196,19 @@ CHECK_PROPERS_INTERVAL = None
ALLOW_HIGH_PRIORITY = False ALLOW_HIGH_PRIORITY = False
AUTOPOSTPROCESSER_FREQUENCY = None AUTOPOSTPROCESSER_FREQUENCY = None
DAILYSEARCH_FREQUENCY = None RECENTSEARCH_FREQUENCY = None
UPDATE_FREQUENCY = None UPDATE_FREQUENCY = None
DAILYSEARCH_STARTUP = False RECENTSEARCH_STARTUP = False
BACKLOG_FREQUENCY = None BACKLOG_FREQUENCY = None
BACKLOG_STARTUP = False BACKLOG_STARTUP = False
DEFAULT_AUTOPOSTPROCESSER_FREQUENCY = 10 DEFAULT_AUTOPOSTPROCESSER_FREQUENCY = 10
DEFAULT_DAILYSEARCH_FREQUENCY = 40 DEFAULT_RECENTSEARCH_FREQUENCY = 40
DEFAULT_BACKLOG_FREQUENCY = 21 DEFAULT_BACKLOG_FREQUENCY = 21
DEFAULT_UPDATE_FREQUENCY = 1 DEFAULT_UPDATE_FREQUENCY = 1
MIN_AUTOPOSTPROCESSER_FREQUENCY = 1 MIN_AUTOPOSTPROCESSER_FREQUENCY = 1
MIN_DAILYSEARCH_FREQUENCY = 10 MIN_RECENTSEARCH_FREQUENCY = 10
MIN_BACKLOG_FREQUENCY = 10 MIN_BACKLOG_FREQUENCY = 10
MIN_UPDATE_FREQUENCY = 1 MIN_UPDATE_FREQUENCY = 1
@ -419,10 +419,10 @@ GUI_NAME = None
HOME_LAYOUT = None HOME_LAYOUT = None
HISTORY_LAYOUT = None HISTORY_LAYOUT = None
DISPLAY_SHOW_SPECIALS = False DISPLAY_SHOW_SPECIALS = False
COMING_EPS_LAYOUT = None EPISODE_VIEW_LAYOUT = None
COMING_EPS_DISPLAY_PAUSED = False EPISODE_VIEW_SORT = None
COMING_EPS_SORT = None EPISODE_VIEW_DISPLAY_PAUSED = False
COMING_EPS_MISSED_RANGE = None EPISODE_VIEW_MISSED_RANGE = None
FUZZY_DATING = False FUZZY_DATING = False
TRIM_ZERO = False TRIM_ZERO = False
DATE_PRESET = None DATE_PRESET = None
@ -459,7 +459,7 @@ TRAKT_API_KEY = 'abd806c54516240c76e4ebc9c5ccf394'
__INITIALIZED__ = False __INITIALIZED__ = False
def get_backlog_cycle_time(): def get_backlog_cycle_time():
cycletime = DAILYSEARCH_FREQUENCY * 2 + 7 cycletime = RECENTSEARCH_FREQUENCY * 2 + 7
return max([cycletime, 720]) return max([cycletime, 720])
def initialize(consoleLogging=True): def initialize(consoleLogging=True):
@ -477,7 +477,7 @@ def initialize(consoleLogging=True):
PLEX_SERVER_HOST, PLEX_HOST, PLEX_USERNAME, PLEX_PASSWORD, DEFAULT_BACKLOG_FREQUENCY, MIN_BACKLOG_FREQUENCY, BACKLOG_STARTUP, SKIP_REMOVED_FILES, \ PLEX_SERVER_HOST, PLEX_HOST, PLEX_USERNAME, PLEX_PASSWORD, DEFAULT_BACKLOG_FREQUENCY, MIN_BACKLOG_FREQUENCY, BACKLOG_STARTUP, SKIP_REMOVED_FILES, \
showUpdateScheduler, __INITIALIZED__, LAUNCH_BROWSER, UPDATE_SHOWS_ON_START, TRASH_REMOVE_SHOW, TRASH_ROTATE_LOGS, HOME_SEARCH_FOCUS, SORT_ARTICLE, showList, loadingShowList, \ showUpdateScheduler, __INITIALIZED__, LAUNCH_BROWSER, UPDATE_SHOWS_ON_START, TRASH_REMOVE_SHOW, TRASH_ROTATE_LOGS, HOME_SEARCH_FOCUS, SORT_ARTICLE, showList, loadingShowList, \
NEWZNAB_DATA, NZBS, NZBS_UID, NZBS_HASH, INDEXER_DEFAULT, INDEXER_TIMEOUT, USENET_RETENTION, TORRENT_DIR, \ NEWZNAB_DATA, NZBS, NZBS_UID, NZBS_HASH, INDEXER_DEFAULT, INDEXER_TIMEOUT, USENET_RETENTION, TORRENT_DIR, \
QUALITY_DEFAULT, FLATTEN_FOLDERS_DEFAULT, SUBTITLES_DEFAULT, STATUS_DEFAULT, DAILYSEARCH_STARTUP, \ QUALITY_DEFAULT, FLATTEN_FOLDERS_DEFAULT, SUBTITLES_DEFAULT, STATUS_DEFAULT, RECENTSEARCH_STARTUP, \
GROWL_NOTIFY_ONSNATCH, GROWL_NOTIFY_ONDOWNLOAD, GROWL_NOTIFY_ONSUBTITLEDOWNLOAD, TWITTER_NOTIFY_ONSNATCH, TWITTER_NOTIFY_ONDOWNLOAD, TWITTER_NOTIFY_ONSUBTITLEDOWNLOAD, \ GROWL_NOTIFY_ONSNATCH, GROWL_NOTIFY_ONDOWNLOAD, GROWL_NOTIFY_ONSUBTITLEDOWNLOAD, TWITTER_NOTIFY_ONSNATCH, TWITTER_NOTIFY_ONDOWNLOAD, TWITTER_NOTIFY_ONSUBTITLEDOWNLOAD, \
USE_GROWL, GROWL_HOST, GROWL_PASSWORD, USE_PROWL, PROWL_NOTIFY_ONSNATCH, PROWL_NOTIFY_ONDOWNLOAD, PROWL_NOTIFY_ONSUBTITLEDOWNLOAD, PROWL_API, PROWL_PRIORITY, PROG_DIR, \ USE_GROWL, GROWL_HOST, GROWL_PASSWORD, USE_PROWL, PROWL_NOTIFY_ONSNATCH, PROWL_NOTIFY_ONDOWNLOAD, PROWL_NOTIFY_ONSUBTITLEDOWNLOAD, PROWL_API, PROWL_PRIORITY, PROG_DIR, \
USE_PYTIVO, PYTIVO_NOTIFY_ONSNATCH, PYTIVO_NOTIFY_ONDOWNLOAD, PYTIVO_NOTIFY_ONSUBTITLEDOWNLOAD, PYTIVO_UPDATE_LIBRARY, PYTIVO_HOST, PYTIVO_SHARE_NAME, PYTIVO_TIVO_NAME, \ USE_PYTIVO, PYTIVO_NOTIFY_ONSNATCH, PYTIVO_NOTIFY_ONDOWNLOAD, PYTIVO_NOTIFY_ONSUBTITLEDOWNLOAD, PYTIVO_UPDATE_LIBRARY, PYTIVO_HOST, PYTIVO_SHARE_NAME, PYTIVO_TIVO_NAME, \
@ -485,12 +485,12 @@ def initialize(consoleLogging=True):
USE_PUSHALOT, PUSHALOT_NOTIFY_ONSNATCH, PUSHALOT_NOTIFY_ONDOWNLOAD, PUSHALOT_NOTIFY_ONSUBTITLEDOWNLOAD, PUSHALOT_AUTHORIZATIONTOKEN, \ USE_PUSHALOT, PUSHALOT_NOTIFY_ONSNATCH, PUSHALOT_NOTIFY_ONDOWNLOAD, PUSHALOT_NOTIFY_ONSUBTITLEDOWNLOAD, PUSHALOT_AUTHORIZATIONTOKEN, \
USE_PUSHBULLET, PUSHBULLET_NOTIFY_ONSNATCH, PUSHBULLET_NOTIFY_ONDOWNLOAD, PUSHBULLET_NOTIFY_ONSUBTITLEDOWNLOAD, PUSHBULLET_API, PUSHBULLET_DEVICE, \ USE_PUSHBULLET, PUSHBULLET_NOTIFY_ONSNATCH, PUSHBULLET_NOTIFY_ONDOWNLOAD, PUSHBULLET_NOTIFY_ONSUBTITLEDOWNLOAD, PUSHBULLET_API, PUSHBULLET_DEVICE, \
versionCheckScheduler, VERSION_NOTIFY, AUTO_UPDATE, NOTIFY_ON_UPDATE, PROCESS_AUTOMATICALLY, UNPACK, CPU_PRESET, \ versionCheckScheduler, VERSION_NOTIFY, AUTO_UPDATE, NOTIFY_ON_UPDATE, PROCESS_AUTOMATICALLY, UNPACK, CPU_PRESET, \
KEEP_PROCESSED_DIR, PROCESS_METHOD, TV_DOWNLOAD_DIR, MIN_DAILYSEARCH_FREQUENCY, DEFAULT_UPDATE_FREQUENCY, MIN_UPDATE_FREQUENCY, UPDATE_FREQUENCY, \ KEEP_PROCESSED_DIR, PROCESS_METHOD, TV_DOWNLOAD_DIR, MIN_RECENTSEARCH_FREQUENCY, DEFAULT_UPDATE_FREQUENCY, MIN_UPDATE_FREQUENCY, UPDATE_FREQUENCY, \
showQueueScheduler, searchQueueScheduler, ROOT_DIRS, CACHE_DIR, ACTUAL_CACHE_DIR, TIMEZONE_DISPLAY, \ showQueueScheduler, searchQueueScheduler, ROOT_DIRS, CACHE_DIR, ACTUAL_CACHE_DIR, TIMEZONE_DISPLAY, \
NAMING_PATTERN, NAMING_MULTI_EP, NAMING_ANIME_MULTI_EP, NAMING_FORCE_FOLDERS, NAMING_ABD_PATTERN, NAMING_CUSTOM_ABD, NAMING_SPORTS_PATTERN, NAMING_CUSTOM_SPORTS, NAMING_ANIME_PATTERN, NAMING_CUSTOM_ANIME, NAMING_STRIP_YEAR, \ NAMING_PATTERN, NAMING_MULTI_EP, NAMING_ANIME_MULTI_EP, NAMING_FORCE_FOLDERS, NAMING_ABD_PATTERN, NAMING_CUSTOM_ABD, NAMING_SPORTS_PATTERN, NAMING_CUSTOM_SPORTS, NAMING_ANIME_PATTERN, NAMING_CUSTOM_ANIME, NAMING_STRIP_YEAR, \
RENAME_EPISODES, AIRDATE_EPISODES, properFinderScheduler, PROVIDER_ORDER, autoPostProcesserScheduler, \ RENAME_EPISODES, AIRDATE_EPISODES, properFinderScheduler, PROVIDER_ORDER, autoPostProcesserScheduler, \
WOMBLE, OMGWTFNZBS, OMGWTFNZBS_USERNAME, OMGWTFNZBS_APIKEY, providerList, newznabProviderList, torrentRssProviderList, \ WOMBLE, OMGWTFNZBS, OMGWTFNZBS_USERNAME, OMGWTFNZBS_APIKEY, providerList, newznabProviderList, torrentRssProviderList, \
EXTRA_SCRIPTS, USE_TWITTER, TWITTER_USERNAME, TWITTER_PASSWORD, TWITTER_PREFIX, DAILYSEARCH_FREQUENCY, \ EXTRA_SCRIPTS, USE_TWITTER, TWITTER_USERNAME, TWITTER_PASSWORD, TWITTER_PREFIX, RECENTSEARCH_FREQUENCY, \
USE_BOXCAR, BOXCAR_USERNAME, BOXCAR_PASSWORD, BOXCAR_NOTIFY_ONDOWNLOAD, BOXCAR_NOTIFY_ONSUBTITLEDOWNLOAD, BOXCAR_NOTIFY_ONSNATCH, \ USE_BOXCAR, BOXCAR_USERNAME, BOXCAR_PASSWORD, BOXCAR_NOTIFY_ONDOWNLOAD, BOXCAR_NOTIFY_ONSUBTITLEDOWNLOAD, BOXCAR_NOTIFY_ONSNATCH, \
USE_BOXCAR2, BOXCAR2_ACCESSTOKEN, BOXCAR2_NOTIFY_ONDOWNLOAD, BOXCAR2_NOTIFY_ONSUBTITLEDOWNLOAD, BOXCAR2_NOTIFY_ONSNATCH, \ USE_BOXCAR2, BOXCAR2_ACCESSTOKEN, BOXCAR2_NOTIFY_ONDOWNLOAD, BOXCAR2_NOTIFY_ONSUBTITLEDOWNLOAD, BOXCAR2_NOTIFY_ONSNATCH, \
USE_PUSHOVER, PUSHOVER_USERKEY, PUSHOVER_APIKEY, PUSHOVER_NOTIFY_ONDOWNLOAD, PUSHOVER_NOTIFY_ONSUBTITLEDOWNLOAD, PUSHOVER_NOTIFY_ONSNATCH, \ USE_PUSHOVER, PUSHOVER_USERKEY, PUSHOVER_APIKEY, PUSHOVER_NOTIFY_ONDOWNLOAD, PUSHOVER_NOTIFY_ONSUBTITLEDOWNLOAD, PUSHOVER_NOTIFY_ONSNATCH, \
@ -498,8 +498,8 @@ def initialize(consoleLogging=True):
USE_SYNOLOGYNOTIFIER, SYNOLOGYNOTIFIER_NOTIFY_ONSNATCH, SYNOLOGYNOTIFIER_NOTIFY_ONDOWNLOAD, SYNOLOGYNOTIFIER_NOTIFY_ONSUBTITLEDOWNLOAD, \ USE_SYNOLOGYNOTIFIER, SYNOLOGYNOTIFIER_NOTIFY_ONSNATCH, SYNOLOGYNOTIFIER_NOTIFY_ONDOWNLOAD, SYNOLOGYNOTIFIER_NOTIFY_ONSUBTITLEDOWNLOAD, \
USE_EMAIL, EMAIL_HOST, EMAIL_PORT, EMAIL_TLS, EMAIL_USER, EMAIL_PASSWORD, EMAIL_FROM, EMAIL_NOTIFY_ONSNATCH, EMAIL_NOTIFY_ONDOWNLOAD, EMAIL_NOTIFY_ONSUBTITLEDOWNLOAD, EMAIL_LIST, \ USE_EMAIL, EMAIL_HOST, EMAIL_PORT, EMAIL_TLS, EMAIL_USER, EMAIL_PASSWORD, EMAIL_FROM, EMAIL_NOTIFY_ONSNATCH, EMAIL_NOTIFY_ONDOWNLOAD, EMAIL_NOTIFY_ONSUBTITLEDOWNLOAD, EMAIL_LIST, \
USE_LISTVIEW, METADATA_XBMC, METADATA_XBMC_12PLUS, METADATA_MEDIABROWSER, METADATA_PS3, metadata_provider_dict, \ USE_LISTVIEW, METADATA_XBMC, METADATA_XBMC_12PLUS, METADATA_MEDIABROWSER, METADATA_PS3, metadata_provider_dict, \
NEWZBIN, NEWZBIN_USERNAME, NEWZBIN_PASSWORD, GIT_PATH, MOVE_ASSOCIATED_FILES, POSTPONE_IF_SYNC_FILES, dailySearchScheduler, NFO_RENAME, \ NEWZBIN, NEWZBIN_USERNAME, NEWZBIN_PASSWORD, GIT_PATH, MOVE_ASSOCIATED_FILES, POSTPONE_IF_SYNC_FILES, recentSearchScheduler, NFO_RENAME, \
GUI_NAME, HOME_LAYOUT, HISTORY_LAYOUT, DISPLAY_SHOW_SPECIALS, COMING_EPS_LAYOUT, COMING_EPS_SORT, COMING_EPS_DISPLAY_PAUSED, COMING_EPS_MISSED_RANGE, FUZZY_DATING, TRIM_ZERO, DATE_PRESET, TIME_PRESET, TIME_PRESET_W_SECONDS, THEME_NAME, \ GUI_NAME, HOME_LAYOUT, HISTORY_LAYOUT, DISPLAY_SHOW_SPECIALS, EPISODE_VIEW_LAYOUT, EPISODE_VIEW_SORT, EPISODE_VIEW_DISPLAY_PAUSED, EPISODE_VIEW_MISSED_RANGE, FUZZY_DATING, TRIM_ZERO, DATE_PRESET, TIME_PRESET, TIME_PRESET_W_SECONDS, THEME_NAME, \
POSTER_SORTBY, POSTER_SORTDIR, \ POSTER_SORTBY, POSTER_SORTDIR, \
METADATA_WDTV, METADATA_TIVO, METADATA_MEDE8ER, IGNORE_WORDS, REQUIRE_WORDS, CALENDAR_UNPROTECTED, CREATE_MISSING_SHOW_DIRS, \ METADATA_WDTV, METADATA_TIVO, METADATA_MEDE8ER, IGNORE_WORDS, REQUIRE_WORDS, CALENDAR_UNPROTECTED, CREATE_MISSING_SHOW_DIRS, \
ADD_SHOWS_WO_DIR, USE_SUBTITLES, SUBTITLES_LANGUAGES, SUBTITLES_DIR, SUBTITLES_SERVICES_LIST, SUBTITLES_SERVICES_ENABLED, SUBTITLES_HISTORY, SUBTITLES_FINDER_FREQUENCY, subtitlesFinderScheduler, \ ADD_SHOWS_WO_DIR, USE_SUBTITLES, SUBTITLES_LANGUAGES, SUBTITLES_DIR, SUBTITLES_SERVICES_LIST, SUBTITLES_SERVICES_ENABLED, SUBTITLES_HISTORY, SUBTITLES_FINDER_FREQUENCY, subtitlesFinderScheduler, \
@ -674,7 +674,7 @@ def initialize(consoleLogging=True):
ALLOW_HIGH_PRIORITY = bool(check_setting_int(CFG, 'General', 'allow_high_priority', 1)) ALLOW_HIGH_PRIORITY = bool(check_setting_int(CFG, 'General', 'allow_high_priority', 1))
DAILYSEARCH_STARTUP = bool(check_setting_int(CFG, 'General', 'dailysearch_startup', 1)) RECENTSEARCH_STARTUP = bool(check_setting_int(CFG, 'General', 'recentsearch_startup', 1))
BACKLOG_STARTUP = bool(check_setting_int(CFG, 'General', 'backlog_startup', 1)) BACKLOG_STARTUP = bool(check_setting_int(CFG, 'General', 'backlog_startup', 1))
SKIP_REMOVED_FILES = bool(check_setting_int(CFG, 'General', 'skip_removed_files', 0)) SKIP_REMOVED_FILES = bool(check_setting_int(CFG, 'General', 'skip_removed_files', 0))
@ -685,10 +685,10 @@ def initialize(consoleLogging=True):
if AUTOPOSTPROCESSER_FREQUENCY < MIN_AUTOPOSTPROCESSER_FREQUENCY: if AUTOPOSTPROCESSER_FREQUENCY < MIN_AUTOPOSTPROCESSER_FREQUENCY:
AUTOPOSTPROCESSER_FREQUENCY = MIN_AUTOPOSTPROCESSER_FREQUENCY AUTOPOSTPROCESSER_FREQUENCY = MIN_AUTOPOSTPROCESSER_FREQUENCY
DAILYSEARCH_FREQUENCY = check_setting_int(CFG, 'General', 'dailysearch_frequency', RECENTSEARCH_FREQUENCY = check_setting_int(CFG, 'General', 'recentsearch_frequency',
DEFAULT_DAILYSEARCH_FREQUENCY) DEFAULT_RECENTSEARCH_FREQUENCY)
if DAILYSEARCH_FREQUENCY < MIN_DAILYSEARCH_FREQUENCY: if RECENTSEARCH_FREQUENCY < MIN_RECENTSEARCH_FREQUENCY:
DAILYSEARCH_FREQUENCY = MIN_DAILYSEARCH_FREQUENCY RECENTSEARCH_FREQUENCY = MIN_RECENTSEARCH_FREQUENCY
MIN_BACKLOG_FREQUENCY = get_backlog_cycle_time() MIN_BACKLOG_FREQUENCY = get_backlog_cycle_time()
BACKLOG_FREQUENCY = check_setting_int(CFG, 'General', 'backlog_frequency', DEFAULT_BACKLOG_FREQUENCY) BACKLOG_FREQUENCY = check_setting_int(CFG, 'General', 'backlog_frequency', DEFAULT_BACKLOG_FREQUENCY)
@ -944,10 +944,10 @@ def initialize(consoleLogging=True):
HOME_LAYOUT = check_setting_str(CFG, 'GUI', 'home_layout', 'poster') HOME_LAYOUT = check_setting_str(CFG, 'GUI', 'home_layout', 'poster')
HISTORY_LAYOUT = check_setting_str(CFG, 'GUI', 'history_layout', 'detailed') HISTORY_LAYOUT = check_setting_str(CFG, 'GUI', 'history_layout', 'detailed')
DISPLAY_SHOW_SPECIALS = bool(check_setting_int(CFG, 'GUI', 'display_show_specials', 1)) DISPLAY_SHOW_SPECIALS = bool(check_setting_int(CFG, 'GUI', 'display_show_specials', 1))
COMING_EPS_LAYOUT = check_setting_str(CFG, 'GUI', 'coming_eps_layout', 'banner') EPISODE_VIEW_LAYOUT = check_setting_str(CFG, 'GUI', 'episode_view_layout', 'banner')
COMING_EPS_DISPLAY_PAUSED = bool(check_setting_int(CFG, 'GUI', 'coming_eps_display_paused', 0)) EPISODE_VIEW_SORT = check_setting_str(CFG, 'GUI', 'episode_view_sort', 'time')
COMING_EPS_SORT = check_setting_str(CFG, 'GUI', 'coming_eps_sort', 'date') EPISODE_VIEW_DISPLAY_PAUSED = bool(check_setting_int(CFG, 'GUI', 'episode_view_display_paused', 0))
COMING_EPS_MISSED_RANGE = check_setting_int(CFG, 'GUI', 'coming_eps_missed_range', 7) EPISODE_VIEW_MISSED_RANGE = check_setting_int(CFG, 'GUI', 'episode_view_missed_range', 7)
FUZZY_DATING = bool(check_setting_int(CFG, 'GUI', 'fuzzy_dating', 0)) FUZZY_DATING = bool(check_setting_int(CFG, 'GUI', 'fuzzy_dating', 0))
TRIM_ZERO = bool(check_setting_int(CFG, 'GUI', 'trim_zero', 0)) TRIM_ZERO = bool(check_setting_int(CFG, 'GUI', 'trim_zero', 0))
DATE_PRESET = check_setting_str(CFG, 'GUI', 'date_preset', '%x') DATE_PRESET = check_setting_str(CFG, 'GUI', 'date_preset', '%x')
@ -1022,11 +1022,10 @@ def initialize(consoleLogging=True):
curTorrentProvider.getID() + '_search_fallback', curTorrentProvider.getID() + '_search_fallback',
0)) 0))
if hasattr(curTorrentProvider, 'enable_daily'): if hasattr(curTorrentProvider, 'enable_recentsearch'):
curTorrentProvider.enable_daily = bool(check_setting_int(CFG, curTorrentProvider.getID().upper(), curTorrentProvider.enable_recentsearch = bool(check_setting_int(CFG, curTorrentProvider.getID().upper(),
curTorrentProvider.getID() + '_enable_daily', curTorrentProvider.getID() +
1)) '_enable_recentsearch', 1))
if hasattr(curTorrentProvider, 'enable_backlog'): if hasattr(curTorrentProvider, 'enable_backlog'):
curTorrentProvider.enable_backlog = bool(check_setting_int(CFG, curTorrentProvider.getID().upper(), curTorrentProvider.enable_backlog = bool(check_setting_int(CFG, curTorrentProvider.getID().upper(),
curTorrentProvider.getID() + '_enable_backlog', curTorrentProvider.getID() + '_enable_backlog',
@ -1050,11 +1049,10 @@ def initialize(consoleLogging=True):
curNzbProvider.search_fallback = bool(check_setting_int(CFG, curNzbProvider.getID().upper(), curNzbProvider.search_fallback = bool(check_setting_int(CFG, curNzbProvider.getID().upper(),
curNzbProvider.getID() + '_search_fallback', curNzbProvider.getID() + '_search_fallback',
0)) 0))
if hasattr(curNzbProvider, 'enable_daily'): if hasattr(curNzbProvider, 'enable_recentsearch'):
curNzbProvider.enable_daily = bool(check_setting_int(CFG, curNzbProvider.getID().upper(), curNzbProvider.enable_recentsearch = bool(check_setting_int(CFG, curNzbProvider.getID().upper(),
curNzbProvider.getID() + '_enable_daily', curNzbProvider.getID() + '_enable_recentsearch',
1)) 1))
if hasattr(curNzbProvider, 'enable_backlog'): if hasattr(curNzbProvider, 'enable_backlog'):
curNzbProvider.enable_backlog = bool(check_setting_int(CFG, curNzbProvider.getID().upper(), curNzbProvider.enable_backlog = bool(check_setting_int(CFG, curNzbProvider.getID().upper(),
curNzbProvider.getID() + '_enable_backlog', curNzbProvider.getID() + '_enable_backlog',
@ -1124,11 +1122,11 @@ def initialize(consoleLogging=True):
cycleTime=datetime.timedelta(seconds=3), cycleTime=datetime.timedelta(seconds=3),
threadName="SEARCHQUEUE") threadName="SEARCHQUEUE")
update_interval = datetime.timedelta(minutes=DAILYSEARCH_FREQUENCY) update_interval = datetime.timedelta(minutes=RECENTSEARCH_FREQUENCY)
dailySearchScheduler = scheduler.Scheduler(dailysearcher.DailySearcher(), recentSearchScheduler = scheduler.Scheduler(searchRecent.RecentSearcher(),
cycleTime=update_interval, cycleTime=update_interval,
threadName="DAILYSEARCHER", threadName="RECENTSEARCHER",
run_delay=update_now if DAILYSEARCH_STARTUP run_delay=update_now if RECENTSEARCH_STARTUP
else update_interval) else update_interval)
update_interval = datetime.timedelta(minutes=BACKLOG_FREQUENCY) update_interval = datetime.timedelta(minutes=BACKLOG_FREQUENCY)
@ -1181,15 +1179,15 @@ def start():
showUpdateScheduler, versionCheckScheduler, showQueueScheduler, \ showUpdateScheduler, versionCheckScheduler, showQueueScheduler, \
properFinderScheduler, autoPostProcesserScheduler, searchQueueScheduler, \ properFinderScheduler, autoPostProcesserScheduler, searchQueueScheduler, \
subtitlesFinderScheduler, USE_SUBTITLES, traktCheckerScheduler, \ subtitlesFinderScheduler, USE_SUBTITLES, traktCheckerScheduler, \
dailySearchScheduler, events, started recentSearchScheduler, events, started
with INIT_LOCK: with INIT_LOCK:
if __INITIALIZED__: if __INITIALIZED__:
# start sysetm events queue # start sysetm events queue
events.start() events.start()
# start the daily search scheduler # start the recent search scheduler
dailySearchScheduler.start() recentSearchScheduler.start()
# start the backlog scheduler # start the backlog scheduler
backlogSearchScheduler.start() backlogSearchScheduler.start()
@ -1230,7 +1228,7 @@ def halt():
showUpdateScheduler, versionCheckScheduler, showQueueScheduler, \ showUpdateScheduler, versionCheckScheduler, showQueueScheduler, \
properFinderScheduler, autoPostProcesserScheduler, searchQueueScheduler, \ properFinderScheduler, autoPostProcesserScheduler, searchQueueScheduler, \
subtitlesFinderScheduler, traktCheckerScheduler, \ subtitlesFinderScheduler, traktCheckerScheduler, \
dailySearchScheduler, events, started recentSearchScheduler, events, started
with INIT_LOCK: with INIT_LOCK:
@ -1245,10 +1243,10 @@ def halt():
except: except:
pass pass
dailySearchScheduler.stop.set() recentSearchScheduler.stop.set()
logger.log(u"Waiting for the DAILYSEARCH thread to exit") logger.log(u"Waiting for the RECENTSEARCH thread to exit")
try: try:
dailySearchScheduler.join(10) recentSearchScheduler.join(10)
except: except:
pass pass
@ -1397,13 +1395,13 @@ def save_config():
new_config['General']['torrent_method'] = TORRENT_METHOD new_config['General']['torrent_method'] = TORRENT_METHOD
new_config['General']['usenet_retention'] = int(USENET_RETENTION) new_config['General']['usenet_retention'] = int(USENET_RETENTION)
new_config['General']['autopostprocesser_frequency'] = int(AUTOPOSTPROCESSER_FREQUENCY) new_config['General']['autopostprocesser_frequency'] = int(AUTOPOSTPROCESSER_FREQUENCY)
new_config['General']['dailysearch_frequency'] = int(DAILYSEARCH_FREQUENCY) new_config['General']['recentsearch_frequency'] = int(RECENTSEARCH_FREQUENCY)
new_config['General']['backlog_frequency'] = int(BACKLOG_FREQUENCY) new_config['General']['backlog_frequency'] = int(BACKLOG_FREQUENCY)
new_config['General']['update_frequency'] = int(UPDATE_FREQUENCY) new_config['General']['update_frequency'] = int(UPDATE_FREQUENCY)
new_config['General']['download_propers'] = int(DOWNLOAD_PROPERS) new_config['General']['download_propers'] = int(DOWNLOAD_PROPERS)
new_config['General']['check_propers_interval'] = CHECK_PROPERS_INTERVAL new_config['General']['check_propers_interval'] = CHECK_PROPERS_INTERVAL
new_config['General']['allow_high_priority'] = int(ALLOW_HIGH_PRIORITY) new_config['General']['allow_high_priority'] = int(ALLOW_HIGH_PRIORITY)
new_config['General']['dailysearch_startup'] = int(DAILYSEARCH_STARTUP) new_config['General']['recentsearch_startup'] = int(RECENTSEARCH_STARTUP)
new_config['General']['backlog_startup'] = int(BACKLOG_STARTUP) new_config['General']['backlog_startup'] = int(BACKLOG_STARTUP)
new_config['General']['skip_removed_files'] = int(SKIP_REMOVED_FILES) new_config['General']['skip_removed_files'] = int(SKIP_REMOVED_FILES)
new_config['General']['quality_default'] = int(QUALITY_DEFAULT) new_config['General']['quality_default'] = int(QUALITY_DEFAULT)
@ -1526,9 +1524,9 @@ def save_config():
if hasattr(curTorrentProvider, 'search_fallback'): if hasattr(curTorrentProvider, 'search_fallback'):
new_config[curTorrentProvider.getID().upper()][curTorrentProvider.getID() + '_search_fallback'] = int( new_config[curTorrentProvider.getID().upper()][curTorrentProvider.getID() + '_search_fallback'] = int(
curTorrentProvider.search_fallback) curTorrentProvider.search_fallback)
if hasattr(curTorrentProvider, 'enable_daily'): if hasattr(curTorrentProvider, 'enable_recentsearch'):
new_config[curTorrentProvider.getID().upper()][curTorrentProvider.getID() + '_enable_daily'] = int( new_config[curTorrentProvider.getID().upper()][curTorrentProvider.getID() + '_enable_recentsearch'] = int(
curTorrentProvider.enable_daily) curTorrentProvider.enable_recentsearch)
if hasattr(curTorrentProvider, 'enable_backlog'): if hasattr(curTorrentProvider, 'enable_backlog'):
new_config[curTorrentProvider.getID().upper()][curTorrentProvider.getID() + '_enable_backlog'] = int( new_config[curTorrentProvider.getID().upper()][curTorrentProvider.getID() + '_enable_backlog'] = int(
curTorrentProvider.enable_backlog) curTorrentProvider.enable_backlog)
@ -1550,9 +1548,9 @@ def save_config():
if hasattr(curNzbProvider, 'search_fallback'): if hasattr(curNzbProvider, 'search_fallback'):
new_config[curNzbProvider.getID().upper()][curNzbProvider.getID() + '_search_fallback'] = int( new_config[curNzbProvider.getID().upper()][curNzbProvider.getID() + '_search_fallback'] = int(
curNzbProvider.search_fallback) curNzbProvider.search_fallback)
if hasattr(curNzbProvider, 'enable_daily'): if hasattr(curNzbProvider, 'enable_recentsearch'):
new_config[curNzbProvider.getID().upper()][curNzbProvider.getID() + '_enable_daily'] = int( new_config[curNzbProvider.getID().upper()][curNzbProvider.getID() + '_enable_recentsearch'] = int(
curNzbProvider.enable_daily) curNzbProvider.enable_recentsearch)
if hasattr(curNzbProvider, 'enable_backlog'): if hasattr(curNzbProvider, 'enable_backlog'):
new_config[curNzbProvider.getID().upper()][curNzbProvider.getID() + '_enable_backlog'] = int( new_config[curNzbProvider.getID().upper()][curNzbProvider.getID() + '_enable_backlog'] = int(
curNzbProvider.enable_backlog) curNzbProvider.enable_backlog)
@ -1765,10 +1763,10 @@ def save_config():
new_config['GUI']['home_layout'] = HOME_LAYOUT new_config['GUI']['home_layout'] = HOME_LAYOUT
new_config['GUI']['history_layout'] = HISTORY_LAYOUT new_config['GUI']['history_layout'] = HISTORY_LAYOUT
new_config['GUI']['display_show_specials'] = int(DISPLAY_SHOW_SPECIALS) new_config['GUI']['display_show_specials'] = int(DISPLAY_SHOW_SPECIALS)
new_config['GUI']['coming_eps_layout'] = COMING_EPS_LAYOUT new_config['GUI']['episode_view_layout'] = EPISODE_VIEW_LAYOUT
new_config['GUI']['coming_eps_display_paused'] = int(COMING_EPS_DISPLAY_PAUSED) new_config['GUI']['episode_view_display_paused'] = int(EPISODE_VIEW_DISPLAY_PAUSED)
new_config['GUI']['coming_eps_sort'] = COMING_EPS_SORT new_config['GUI']['episode_view_sort'] = EPISODE_VIEW_SORT
new_config['GUI']['coming_eps_missed_range'] = int(COMING_EPS_MISSED_RANGE) new_config['GUI']['episode_view_missed_range'] = int(EPISODE_VIEW_MISSED_RANGE)
new_config['GUI']['fuzzy_dating'] = int(FUZZY_DATING) new_config['GUI']['fuzzy_dating'] = int(FUZZY_DATING)
new_config['GUI']['trim_zero'] = int(TRIM_ZERO) new_config['GUI']['trim_zero'] = int(TRIM_ZERO)
new_config['GUI']['date_preset'] = DATE_PRESET new_config['GUI']['date_preset'] = DATE_PRESET

View file

@ -27,6 +27,8 @@ from sickbeard import helpers
from sickbeard import logger from sickbeard import logger
from sickbeard import naming from sickbeard import naming
from sickbeard import db from sickbeard import db
from sickbeard import providers
from sickbeard.providers.generic import GenericProvider
naming_ep_type = ("%(seasonnumber)dx%(episodenumber)02d", naming_ep_type = ("%(seasonnumber)dx%(episodenumber)02d",
"s%(seasonnumber)02de%(episodenumber)02d", "s%(seasonnumber)02de%(episodenumber)02d",
@ -155,13 +157,13 @@ def change_AUTOPOSTPROCESSER_FREQUENCY(freq):
sickbeard.autoPostProcesserScheduler.cycleTime = datetime.timedelta(minutes=sickbeard.AUTOPOSTPROCESSER_FREQUENCY) sickbeard.autoPostProcesserScheduler.cycleTime = datetime.timedelta(minutes=sickbeard.AUTOPOSTPROCESSER_FREQUENCY)
def change_DAILYSEARCH_FREQUENCY(freq): def change_RECENTSEARCH_FREQUENCY(freq):
sickbeard.DAILYSEARCH_FREQUENCY = to_int(freq, default=sickbeard.DEFAULT_DAILYSEARCH_FREQUENCY) sickbeard.RECENTSEARCH_FREQUENCY = to_int(freq, default=sickbeard.DEFAULT_RECENTSEARCH_FREQUENCY)
if sickbeard.DAILYSEARCH_FREQUENCY < sickbeard.MIN_DAILYSEARCH_FREQUENCY: if sickbeard.RECENTSEARCH_FREQUENCY < sickbeard.MIN_RECENTSEARCH_FREQUENCY:
sickbeard.DAILYSEARCH_FREQUENCY = sickbeard.MIN_DAILYSEARCH_FREQUENCY sickbeard.RECENTSEARCH_FREQUENCY = sickbeard.MIN_RECENTSEARCH_FREQUENCY
sickbeard.dailySearchScheduler.cycleTime = datetime.timedelta(minutes=sickbeard.DAILYSEARCH_FREQUENCY) sickbeard.recentSearchScheduler.cycleTime = datetime.timedelta(minutes=sickbeard.RECENTSEARCH_FREQUENCY)
def change_BACKLOG_FREQUENCY(freq): def change_BACKLOG_FREQUENCY(freq):
sickbeard.BACKLOG_FREQUENCY = to_int(freq, default=sickbeard.DEFAULT_BACKLOG_FREQUENCY) sickbeard.BACKLOG_FREQUENCY = to_int(freq, default=sickbeard.DEFAULT_BACKLOG_FREQUENCY)
@ -445,7 +447,9 @@ class ConfigMigrator():
2: 'Sync backup number with version number', 2: 'Sync backup number with version number',
3: 'Rename omgwtfnzb variables', 3: 'Rename omgwtfnzb variables',
4: 'Add newznab catIDs', 4: 'Add newznab catIDs',
5: 'Metadata update' 5: 'Metadata update',
6: 'Rename daily search to recent search',
7: 'Rename coming episodes to episode view'
} }
def migrate_config(self): def migrate_config(self):
@ -712,3 +716,27 @@ class ConfigMigrator():
sickbeard.METADATA_WDTV = _migrate_metadata(metadata_wdtv, 'WDTV', use_banner) sickbeard.METADATA_WDTV = _migrate_metadata(metadata_wdtv, 'WDTV', use_banner)
sickbeard.METADATA_TIVO = _migrate_metadata(metadata_tivo, 'TIVO', use_banner) sickbeard.METADATA_TIVO = _migrate_metadata(metadata_tivo, 'TIVO', use_banner)
sickbeard.METADATA_MEDE8ER = _migrate_metadata(metadata_mede8er, 'Mede8er', use_banner) sickbeard.METADATA_MEDE8ER = _migrate_metadata(metadata_mede8er, 'Mede8er', use_banner)
# Migration v6: Rename daily search to recent search
def _migrate_v6(self):
sickbeard.RECENTSEARCH_FREQUENCY = check_setting_int(self.config_obj, 'General', 'dailysearch_frequency',
sickbeard.DEFAULT_RECENTSEARCH_FREQUENCY)
sickbeard.RECENTSEARCH_STARTUP = bool(check_setting_int(self.config_obj, 'General', 'dailysearch_startup', 1))
if sickbeard.RECENTSEARCH_FREQUENCY < sickbeard.MIN_RECENTSEARCH_FREQUENCY:
sickbeard.RECENTSEARCH_FREQUENCY = sickbeard.MIN_RECENTSEARCH_FREQUENCY
for curProvider in providers.sortedProviderList():
if hasattr(curProvider, 'enable_recentsearch'):
curProvider.enable_recentsearch = bool(check_setting_int(self.config_obj, curProvider.getID().upper(),
curProvider.getID() + '_enable_dailysearch', 1))
def _migrate_v7(self):
sickbeard.EPISODE_VIEW_LAYOUT = check_setting_str(self.config_obj, 'GUI', 'coming_eps_layout', 'banner')
sickbeard.EPISODE_VIEW_SORT = check_setting_str(self.config_obj, 'GUI', 'coming_eps_sort', 'time')
if 'date' == sickbeard.EPISODE_VIEW_SORT:
sickbeard.EPISODE_VIEW_SORT = 'time'
sickbeard.EPISODE_VIEW_DISPLAY_PAUSED = bool(check_setting_int(self.config_obj, 'GUI', 'coming_eps_display_paused', 0))
sickbeard.EPISODE_VIEW_MISSED_RANGE = check_setting_int(self.config_obj, 'GUI', 'coming_eps_missed_range', 7)

View file

@ -93,3 +93,26 @@ class GitHub(object):
['repos', self.github_repo_user, self.github_repo, 'branches'], ['repos', self.github_repo_user, self.github_repo, 'branches'],
params={'per_page': 100}) params={'per_page': 100})
return access_API return access_API
def pull_requests(self):
access_API = self._access_API(
['repos', self.github_repo_user, self.github_repo, 'pulls'],
params={'per_page': 100})
pull = []
for x in access_API:
try:
pull.append(PullRequest(x['head']['ref'], x['number']))
except:
continue
return pull
class PullRequest(object):
def __init__(self, ref, number):
self.ref = ref
self.number = number
def __repr__(self):
return '%s: %s' % (self.number, self.ref)
def fetch_name(self):
return 'pull/%s/head:pull/%s/%s' % (self.number, self.number, self.ref)

View file

@ -26,8 +26,9 @@ import os.path
import regexes import regexes
import sickbeard import sickbeard
from sickbeard import logger, helpers, scene_numbering, common, exceptions, scene_exceptions, encodingKludge as ek, db from sickbeard import logger, helpers, scene_numbering, common, scene_exceptions, encodingKludge as ek, db
from dateutil import parser from dateutil import parser
from sickbeard.exceptions import ex
class NameParser(object): class NameParser(object):
@ -36,13 +37,14 @@ class NameParser(object):
ANIME_REGEX = 2 ANIME_REGEX = 2
def __init__(self, file_name=True, showObj=None, tryIndexers=False, convert=False, def __init__(self, file_name=True, showObj=None, tryIndexers=False, convert=False,
naming_pattern=False): naming_pattern=False, testing=False):
self.file_name = file_name self.file_name = file_name
self.showObj = showObj self.showObj = showObj
self.tryIndexers = tryIndexers self.tryIndexers = tryIndexers
self.convert = convert self.convert = convert
self.naming_pattern = naming_pattern self.naming_pattern = naming_pattern
self.testing = testing
if self.showObj and not self.showObj.is_anime: if self.showObj and not self.showObj.is_anime:
self._compile_regexes(self.NORMAL_REGEX) self._compile_regexes(self.NORMAL_REGEX)
@ -78,7 +80,7 @@ class NameParser(object):
def _compile_regexes(self, regexMode): def _compile_regexes(self, regexMode):
if regexMode == self.ANIME_REGEX: if regexMode == self.ANIME_REGEX:
logger.log(u"Using ANIME regexs", logger.DEBUG) logger.log(u"Using ANIME regexs", logger.DEBUG)
uncompiled_regex = [regexes.anime_regexes, regexes.normal_regexes] uncompiled_regex = [regexes.anime_regexes]
elif regexMode == self.NORMAL_REGEX: elif regexMode == self.NORMAL_REGEX:
logger.log(u"Using NORMAL regexs", logger.DEBUG) logger.log(u"Using NORMAL regexs", logger.DEBUG)
uncompiled_regex = [regexes.normal_regexes] uncompiled_regex = [regexes.normal_regexes]
@ -86,7 +88,8 @@ class NameParser(object):
logger.log(u"Using ALL regexes", logger.DEBUG) logger.log(u"Using ALL regexes", logger.DEBUG)
uncompiled_regex = [regexes.normal_regexes, regexes.anime_regexes] uncompiled_regex = [regexes.normal_regexes, regexes.anime_regexes]
self.compiled_regexes = [] self.compiled_regexes = {0: [], 1: []}
index = 0
for regexItem in uncompiled_regex: for regexItem in uncompiled_regex:
for cur_pattern_num, (cur_pattern_name, cur_pattern) in enumerate(regexItem): for cur_pattern_num, (cur_pattern_name, cur_pattern) in enumerate(regexItem):
try: try:
@ -94,7 +97,8 @@ class NameParser(object):
except re.error, errormsg: except re.error, errormsg:
logger.log(u"WARNING: Invalid episode_pattern, %s. %s" % (errormsg, cur_pattern)) logger.log(u"WARNING: Invalid episode_pattern, %s. %s" % (errormsg, cur_pattern))
else: else:
self.compiled_regexes.append((cur_pattern_num, cur_pattern_name, cur_regex)) self.compiled_regexes[index].append([cur_pattern_num, cur_pattern_name, cur_regex])
index += 1
def _parse_string(self, name): def _parse_string(self, name):
if not name: if not name:
@ -102,8 +106,8 @@ class NameParser(object):
matches = [] matches = []
bestResult = None bestResult = None
for regex in self.compiled_regexes:
for (cur_regex_num, cur_regex_name, cur_regex) in self.compiled_regexes: for (cur_regex_num, cur_regex_name, cur_regex) in self.compiled_regexes[regex]:
match = cur_regex.match(name) match = cur_regex.match(name)
if not match: if not match:
@ -150,13 +154,19 @@ class NameParser(object):
result.ab_episode_numbers = [ep_ab_num] result.ab_episode_numbers = [ep_ab_num]
result.score += 1 result.score += 1
if 'air_date' in named_groups: if 'air_year' in named_groups and 'air_month' in named_groups and 'air_day' in named_groups:
air_date = match.group('air_date') year = int(match.group('air_year'))
month = int(match.group('air_month'))
day = int(match.group('air_day'))
# make an attempt to detect YYYY-DD-MM formats
if month > 12:
tmp_month = month
month = day
day = tmp_month
try: try:
result.air_date = parser.parse(air_date, fuzzy=True).date() result.air_date = datetime.date(year, month, day)
result.score += 1 except ValueError, e:
except: raise InvalidNameException(ex(e))
continue
if 'extra_info' in named_groups: if 'extra_info' in named_groups:
tmp_extra_info = match.group('extra_info') tmp_extra_info = match.group('extra_info')
@ -194,13 +204,16 @@ class NameParser(object):
show = helpers.get_show(bestResult.series_name, self.tryIndexers) show = helpers.get_show(bestResult.series_name, self.tryIndexers)
# confirm passed in show object indexer id matches result show object indexer id # confirm passed in show object indexer id matches result show object indexer id
if show: if show and not self.testing:
if self.showObj and show.indexerid != self.showObj.indexerid: if self.showObj and show.indexerid != self.showObj.indexerid:
show = None show = None
bestResult.show = show bestResult.show = show
elif not show and self.showObj: elif not show and self.showObj:
bestResult.show = self.showObj bestResult.show = self.showObj
if bestResult.show and bestResult.show.is_anime and len(self.compiled_regexes[1]) > 1 and regex != 1:
continue
# if this is a naming pattern test or result doesn't have a show object then return best result # if this is a naming pattern test or result doesn't have a show object then return best result
if not bestResult.show or self.naming_pattern: if not bestResult.show or self.naming_pattern:
return bestResult return bestResult
@ -259,7 +272,7 @@ class NameParser(object):
new_episode_numbers.append(e) new_episode_numbers.append(e)
new_season_numbers.append(s) new_season_numbers.append(s)
elif bestResult.show.is_anime and len(bestResult.ab_episode_numbers): elif bestResult.show.is_anime and len(bestResult.ab_episode_numbers) and not self.testing:
scene_season = scene_exceptions.get_scene_exception_by_name(bestResult.series_name)[1] scene_season = scene_exceptions.get_scene_exception_by_name(bestResult.series_name)[1]
for epAbsNo in bestResult.ab_episode_numbers: for epAbsNo in bestResult.ab_episode_numbers:
a = epAbsNo a = epAbsNo
@ -275,7 +288,7 @@ class NameParser(object):
new_episode_numbers.extend(e) new_episode_numbers.extend(e)
new_season_numbers.append(s) new_season_numbers.append(s)
elif bestResult.season_number and len(bestResult.episode_numbers): elif bestResult.season_number and len(bestResult.episode_numbers) and not self.testing:
for epNo in bestResult.episode_numbers: for epNo in bestResult.episode_numbers:
s = bestResult.season_number s = bestResult.season_number
e = epNo e = epNo
@ -416,7 +429,7 @@ class NameParser(object):
file_name_result = self._parse_string(base_file_name) file_name_result = self._parse_string(base_file_name)
# use only the direct parent dir # use only the direct parent dir
dir_name = os.path.basename(dir_name) dir_name = ek.ek(os.path.basename, dir_name)
# parse the dirname for extra info if needed # parse the dirname for extra info if needed
dir_name_result = self._parse_string(dir_name) dir_name_result = self._parse_string(dir_name)
@ -452,6 +465,10 @@ class NameParser(object):
final_result.quality = self._combine_results(file_name_result, dir_name_result, 'quality') final_result.quality = self._combine_results(file_name_result, dir_name_result, 'quality')
if not final_result.show: if not final_result.show:
if self.testing:
pass
#final_result.which_regex = []
else:
raise InvalidShowException( raise InvalidShowException(
"Unable to parse " + name.encode(sickbeard.SYS_ENCODING, 'xmlcharrefreplace')) "Unable to parse " + name.encode(sickbeard.SYS_ENCODING, 'xmlcharrefreplace'))
@ -506,7 +523,7 @@ class ParseResult(object):
self.air_date = air_date self.air_date = air_date
self.which_regex = [] self.which_regex = None
self.show = show self.show = show
self.score = score self.score = score
@ -530,14 +547,14 @@ class ParseResult(object):
return False return False
if self.ab_episode_numbers != other.ab_episode_numbers: if self.ab_episode_numbers != other.ab_episode_numbers:
return False return False
if self.show != other.show: #if self.show != other.show:
return False # return False
if self.score != other.score: #if self.score != other.score:
return False # return False
if self.quality != other.quality: #if self.quality != other.quality:
return False # return False
if self.version != other.version: #if self.version != other.version:
return False # return False
return True return True
@ -556,6 +573,7 @@ class ParseResult(object):
to_return += str(self.air_date) to_return += str(self.air_date)
if self.ab_episode_numbers: if self.ab_episode_numbers:
to_return += ' [ABS: ' + str(self.ab_episode_numbers) + ']' to_return += ' [ABS: ' + str(self.ab_episode_numbers) + ']'
if self.is_anime:
if self.version: if self.version:
to_return += ' [ANIME VER: ' + str(self.version) + ']' to_return += ' [ANIME VER: ' + str(self.version) + ']'

View file

@ -30,8 +30,9 @@ normal_regexes = [
e(?P<extra_ep_num>\d+))+ # E03/etc and separator e(?P<extra_ep_num>\d+))+ # E03/etc and separator
[. _-]*((?P<extra_info>.+?) # Source_Quality_Etc- [. _-]*((?P<extra_info>.+?) # Source_Quality_Etc-
((?<![. _-])(?<!WEB) # Make sure this is really the release group ((?<![. _-])(?<!WEB) # Make sure this is really the release group
-(?P<release_group>[^- ]+([. _-]\[.*\])?))?)?$ # Group -(?P<release_group>[^- ]+))?)?$ # Group
'''), '''
),
('fov_repeat', ('fov_repeat',
# Show.Name.1x02.1x03.Source.Quality.Etc-Group # Show.Name.1x02.1x03.Source.Quality.Etc-Group
@ -44,8 +45,9 @@ normal_regexes = [
(?P<extra_ep_num>\d+))+ # 03/etc and separator (?P<extra_ep_num>\d+))+ # 03/etc and separator
[. _-]*((?P<extra_info>.+?) # Source_Quality_Etc- [. _-]*((?P<extra_info>.+?) # Source_Quality_Etc-
((?<![. _-])(?<!WEB) # Make sure this is really the release group ((?<![. _-])(?<!WEB) # Make sure this is really the release group
-(?P<release_group>[^- ]+([. _-]\[.*\])?))?)?$ # Group -(?P<release_group>[^- ]+))?)?$ # Group
'''), '''
),
('standard', ('standard',
# Show.Name.S01E02.Source.Quality.Etc-Group # Show.Name.S01E02.Source.Quality.Etc-Group
@ -62,8 +64,9 @@ normal_regexes = [
(?P<extra_ep_num>(?!(1080|720|480)[pi])\d+))* # additional E03/etc (?P<extra_ep_num>(?!(1080|720|480)[pi])\d+))* # additional E03/etc
[. _-]*((?P<extra_info>.+?) # Source_Quality_Etc- [. _-]*((?P<extra_info>.+?) # Source_Quality_Etc-
((?<![. _-])(?<!WEB) # Make sure this is really the release group ((?<![. _-])(?<!WEB) # Make sure this is really the release group
-(?P<release_group>[^- ]+([. _-]\[.*\])?))?)?$ # Group -(?P<release_group>[^- ]+))?)?$ # Group
'''), '''
),
('fov', ('fov',
# Show_Name.1x02.Source_Quality_Etc-Group # Show_Name.1x02.Source_Quality_Etc-Group
@ -80,31 +83,23 @@ normal_regexes = [
\d+))* # additional x03/etc \d+))* # additional x03/etc
[\]. _-]*((?P<extra_info>.+?) # Source_Quality_Etc- [\]. _-]*((?P<extra_info>.+?) # Source_Quality_Etc-
((?<![. _-])(?<!WEB) # Make sure this is really the release group ((?<![. _-])(?<!WEB) # Make sure this is really the release group
-(?P<release_group>[^- ]+([. _-]\[.*\])?))?)?$ # Group -(?P<release_group>[^- ]+))?)?$ # Group
'''), '''
),
('scene_date_format', ('scene_date_format',
# Show.Name.2010.11.23.Source.Quality.Etc-Group # Show.Name.2010.11.23.Source.Quality.Etc-Group
# Show Name - 2010-11-23 - Ep Name # Show Name - 2010-11-23 - Ep Name
''' '''
^((?P<series_name>.+?)[. _-]+)? # Show_Name and separator ^((?P<series_name>.+?)[. _-]+)? # Show_Name and separator
(?P<air_date>(\d+[. _-]\d+[. _-]\d+)|(\d+\w+[. _-]\w+[. _-]\d+)) (?P<air_year>\d{4})[. _-]+ # 2010 and separator
(?P<air_month>\d{2})[. _-]+ # 11 and separator
(?P<air_day>\d{2}) # 23 and separator
[. _-]*((?P<extra_info>.+?) # Source_Quality_Etc- [. _-]*((?P<extra_info>.+?) # Source_Quality_Etc-
((?<![. _-])(?<!WEB) # Make sure this is really the release group ((?<![. _-])(?<!WEB) # Make sure this is really the release group
-(?P<release_group>[^- ]+([. _-]\[.*\])?))?)?$ # Group -(?P<release_group>[^- ]+))?)?$ # Group
'''),
('scene_sports_format',
# Show.Name.100.Event.2010.11.23.Source.Quality.Etc-Group
# Show.Name.2010.11.23.Source.Quality.Etc-Group
# Show Name - 2010-11-23 - Ep Name
''' '''
^(?P<series_name>.*?(UEFA|MLB|ESPN|WWE|MMA|UFC|TNA|EPL|NASCAR|NBA|NFL|NHL|NRL|PGA|SUPER LEAGUE|FORMULA|FIFA|NETBALL|MOTOGP).*?)[. _-]+ ),
((?P<series_num>\d{1,3})[. _-]+)?
(?P<air_date>(\d+[. _-]\d+[. _-]\d+)|(\d+\w+[. _-]\w+[. _-]\d+))[. _-]+
((?P<extra_info>.+?)((?<![. _-])
(?<!WEB)-(?P<release_group>[^- ]+([. _-]\[.*\])?))?)?$
'''),
('stupid', ('stupid',
# tpz-abc102 # tpz-abc102
@ -113,7 +108,8 @@ normal_regexes = [
(?!264) # don't count x264 (?!264) # don't count x264
(?P<season_num>\d{1,2}) # 1 (?P<season_num>\d{1,2}) # 1
(?P<ep_num>\d{2})$ # 02 (?P<ep_num>\d{2})$ # 02
'''), '''
),
('verbose', ('verbose',
# Show Name Season 1 Episode 2 Ep Name # Show Name Season 1 Episode 2 Ep Name
@ -124,7 +120,8 @@ normal_regexes = [
episode[. _-]+ # episode and separator episode[. _-]+ # episode and separator
(?P<ep_num>\d+)[. _-]+ # 02 and separator (?P<ep_num>\d+)[. _-]+ # 02 and separator
(?P<extra_info>.+)$ # Source_Quality_Etc- (?P<extra_info>.+)$ # Source_Quality_Etc-
'''), '''
),
('season_only', ('season_only',
# Show.Name.S01.Source.Quality.Etc-Group # Show.Name.S01.Source.Quality.Etc-Group
@ -134,7 +131,7 @@ normal_regexes = [
(?P<season_num>\d+)[. _-]* # S01 and optional separator (?P<season_num>\d+)[. _-]* # S01 and optional separator
[. _-]*((?P<extra_info>.+?) # Source_Quality_Etc- [. _-]*((?P<extra_info>.+?) # Source_Quality_Etc-
((?<![. _-])(?<!WEB) # Make sure this is really the release group ((?<![. _-])(?<!WEB) # Make sure this is really the release group
-(?P<release_group>[^- ]+([. _-]\[.*\])?))?)?$ # Group -(?P<release_group>[^- ]+))?)?$ # Group
''' '''
), ),
@ -149,7 +146,7 @@ normal_regexes = [
(?P<extra_ep_num>(?!(1080|720|480)[pi])(\d+|[ivx]+))[. _-]) # second ep num (?P<extra_ep_num>(?!(1080|720|480)[pi])(\d+|[ivx]+))[. _-]) # second ep num
([. _-]*(?P<extra_info>.+?) # Source_Quality_Etc- ([. _-]*(?P<extra_info>.+?) # Source_Quality_Etc-
((?<![. _-])(?<!WEB) # Make sure this is really the release group ((?<![. _-])(?<!WEB) # Make sure this is really the release group
-(?P<release_group>[^- ]+([. _-]\[.*\])?))?)?$ # Group -(?P<release_group>[^- ]+))?)?$ # Group
''' '''
), ),
@ -167,22 +164,7 @@ normal_regexes = [
(\d+|([ivx]+(?=[. _-]))))[. _-])* # second ep num (\d+|([ivx]+(?=[. _-]))))[. _-])* # second ep num
([. _-]*(?P<extra_info>.+?) # Source_Quality_Etc- ([. _-]*(?P<extra_info>.+?) # Source_Quality_Etc-
((?<![. _-])(?<!WEB) # Make sure this is really the release group ((?<![. _-])(?<!WEB) # Make sure this is really the release group
-(?P<release_group>[^- ]+([. _-]\[.*\])?))?)?$ # Group -(?P<release_group>[^- ]+))?)?$ # Group
'''
),
('no_season',
# Show Name - 01 - Ep Name
# 01 - Ep Name
# 01 - Ep Name
'''
^((?P<series_name>.+?)(?:[. _-]{2,}|[. _]))? # Show_Name and separator
(?P<ep_num>\d{1,3}) # 02
(?:-(?P<extra_ep_num>\d{1,3}))* # -03-04-05 etc
\s?of?\s?\d{1,3}? # of joiner (with or without spaces) and series total ep
[. _-]+((?P<extra_info>.+?) # Source_Quality_Etc-
((?<![. _-])(?<!WEB) # Make sure this is really the release group
-(?P<release_group>[^- ]+([. _-]\[.*\])?))?)?$ # Group
''' '''
), ),
@ -193,23 +175,37 @@ normal_regexes = [
(?P<season_num>\d{1,2}) # 1 (?P<season_num>\d{1,2}) # 1
(?P<ep_num>\d{2}) # 02 and separator (?P<ep_num>\d{2}) # 02 and separator
([. _-]+(?P<extra_info>(?!\d{3}[. _-]+)[^-]+) # Source_Quality_Etc- ([. _-]+(?P<extra_info>(?!\d{3}[. _-]+)[^-]+) # Source_Quality_Etc-
(-(?P<release_group>[^- ]+([. _-]\[.*\])?))?)?$ # Group (-(?P<release_group>.+))?)?$ # Group
'''), '''
),
('no_season',
# Show Name - 01 - Ep Name
# 01 - Ep Name
'''
^((?P<series_name>.+?)(?:[. _-]{2,}|[. _]))? # Show_Name and separator
(?P<ep_num>\d{1,2}) # 01
(?:-(?P<extra_ep_num>\d{1,2}))* # 02
[. _-]+((?P<extra_info>.+?) # Source_Quality_Etc-
((?<![. _-])(?<!WEB) # Make sure this is really the release group
-(?P<release_group>[^- ]+))?)?$ # Group
'''
),
] ]
anime_regexes = [ anime_regexes = [
('anime_ultimate', ('anime_ultimate',
""" '''
^(?:\[(?P<release_group>.+?)\][ ._-]*) ^(?:\[(?P<release_group>.+?)\][ ._-]*)
(?P<series_name>.+?)[ ._-]+ (?P<series_name>.+?)[ ._-]+
(?P<ep_ab_num>((?!(1080|720|480)[pi])|(?![hx].?264))\d{1,3}) (?P<ep_ab_num>\d{1,3})
(-(?P<extra_ab_ep_num>((?!(1080|720|480)[pi])|(?![hx].?264))\d{1,3}))?[ ._-]+? (-(?P<extra_ab_ep_num>\d{1,3}))?[ ._-]+?
(?:v(?P<version>[0-9]))? (?:v(?P<version>[0-9]))?
(?:[\w\.]*) (?:[\w\.]*)
(?:(?:(?:[\[\(])(?P<extra_info>\d{3,4}[xp]?\d{0,4}[\.\w\s-]*)(?:[\]\)]))|(?:\d{3,4}[xp])) (?:(?:(?:[\[\(])(?P<extra_info>\d{3,4}[xp]?\d{0,4}[\.\w\s-]*)(?:[\]\)]))|(?:\d{3,4}[xp]))
(?:[ ._]?\[(?P<crc>\w+)\])? (?:[ ._]?\[(?P<crc>\w+)\])?
.*? .*?
""" '''
), ),
('anime_standard', ('anime_standard',
# [Group Name] Show Name.13-14 # [Group Name] Show Name.13-14
@ -221,42 +217,38 @@ anime_regexes = [
''' '''
^(\[(?P<release_group>.+?)\][ ._-]*)? # Release Group and separator ^(\[(?P<release_group>.+?)\][ ._-]*)? # Release Group and separator
(?P<series_name>.+?)[ ._-]+ # Show_Name and separator (?P<series_name>.+?)[ ._-]+ # Show_Name and separator
(?P<ep_ab_num>((?!(1080|720|480)[pi])|(?![hx].?264))\d{1,3}) # E01 (?P<ep_ab_num>\d{1,3}) # E01
(-(?P<extra_ab_ep_num>((?!(1080|720|480)[pi])|(?![hx].?264))\d{1,3}))? # E02 (-(?P<extra_ab_ep_num>\d{1,3}))? # E02
(v(?P<version>[0-9]))? # version (v(?P<version>[0-9]))? # version
[ ._-]+\[(?P<extra_info>\d{3,4}[xp]?\d{0,4}[\.\w\s-]*)\] # Source_Quality_Etc- [ ._-]+\[(?P<extra_info>\d{3,4}[xp]?\d{0,4}[\.\w\s-]*)\] # Source_Quality_Etc-
(\[(?P<crc>\w{8})\])? # CRC (\[(?P<crc>\w{8})\])? # CRC
.*? # Separator and EOL .*? # Separator and EOL
'''), '''),
('anime_standard_round', ('anime_standard_round',
# TODO examples
# [Stratos-Subs]_Infinite_Stratos_-_12_(1280x720_H.264_AAC)_[379759DB] # [Stratos-Subs]_Infinite_Stratos_-_12_(1280x720_H.264_AAC)_[379759DB]
# [ShinBunBu-Subs] Bleach - 02-03 (CX 1280x720 x264 AAC) # [ShinBunBu-Subs] Bleach - 02-03 (CX 1280x720 x264 AAC)
''' '''
^(\[(?P<release_group>.+?)\][ ._-]*)? # Release Group and separator ^(\[(?P<release_group>.+?)\][ ._-]*)? # Release Group and separator
(?P<series_name>.+?)[ ._-]+ # Show_Name and separator (?P<series_name>.+?)[ ._-]+ # Show_Name and separator
(?P<ep_ab_num>((?!(1080|720|480)[pi])|(?![hx].?264))\d{1,3}) # E01 (?P<ep_ab_num>\d{1,3}) # E01
(-(?P<extra_ab_ep_num>((?!(1080|720|480)[pi])|(?![hx].?264))\d{1,3}))? # E02 (-(?P<extra_ab_ep_num>\d{1,3}))? # E02
(v(?P<version>[0-9]))? # version (v(?P<version>[0-9]))? # version
[ ._-]+\((?P<extra_info>(CX[ ._-]?)?\d{3,4}[xp]?\d{0,4}[\.\w\s-]*)\) # Source_Quality_Etc- [ ._-]+\((?P<extra_info>(CX[ ._-]?)?\d{3,4}[xp]?\d{0,4}[\.\w\s-]*)\) # Source_Quality_Etc-
(\[(?P<crc>\w{8})\])? # CRC (\[(?P<crc>\w{8})\])? # CRC
.*? # Separator and EOL .*? # Separator and EOL
'''), '''),
('anime_slash', ('anime_slash',
# [SGKK] Bleach 312v1 [720p/MKV] # [SGKK] Bleach 312v1 [720p/MKV]
''' '''
^(\[(?P<release_group>.+?)\][ ._-]*)? # Release Group and separator ^(\[(?P<release_group>.+?)\][ ._-]*)? # Release Group and separator
(?P<series_name>.+?)[ ._-]+ # Show_Name and separator (?P<series_name>.+?)[ ._-]+ # Show_Name and separator
(?P<ep_ab_num>((?!(1080|720|480)[pi])|(?![hx].?264))\d{1,3}) # E01 (?P<ep_ab_num>\d{1,3}) # E01
(-(?P<extra_ab_ep_num>((?!(1080|720|480)[pi])|(?![hx].?264))\d{1,3}))? # E02 (-(?P<extra_ab_ep_num>\d{1,3}))? # E02
(v(?P<version>[0-9]))? # version (v(?P<version>[0-9]))? # version
[ ._-]+\[(?P<extra_info>\d{3,4}p) # Source_Quality_Etc- [ ._-]+\[(?P<extra_info>\d{3,4}p) # Source_Quality_Etc-
(\[(?P<crc>\w{8})\])? # CRC (\[(?P<crc>\w{8})\])? # CRC
.*? # Separator and EOL .*? # Separator and EOL
'''), '''),
('anime_standard_codec', ('anime_standard_codec',
# [Ayako]_Infinite_Stratos_-_IS_-_07_[H264][720p][EB7838FC] # [Ayako]_Infinite_Stratos_-_IS_-_07_[H264][720p][EB7838FC]
# [Ayako] Infinite Stratos - IS - 07v2 [H264][720p][44419534] # [Ayako] Infinite Stratos - IS - 07v2 [H264][720p][44419534]
@ -264,26 +256,15 @@ anime_regexes = [
''' '''
^(\[(?P<release_group>.+?)\][ ._-]*)? # Release Group and separator ^(\[(?P<release_group>.+?)\][ ._-]*)? # Release Group and separator
(?P<series_name>.+?)[ ._]* # Show_Name and separator (?P<series_name>.+?)[ ._]* # Show_Name and separator
([ ._-]+-[ ._-]+[A-Z]+[ ._-]+)?[ ._-]+ # funny stuff, this is sooo nuts ! this will kick me in the butt one day ([ ._-]+-[ ._-]+[A-Z]+[ ._-]+)?[ ._-]+ # this will kick me in the butt one day
(?P<ep_ab_num>((?!(1080|720|480)[pi])|(?![hx].?264))\d{1,3}) # E01 (?P<ep_ab_num>\d{1,3}) # E01
(-(?P<extra_ab_ep_num>((?!(1080|720|480)[pi])|(?![hx].?264))\d{1,3}))? # E02 (-(?P<extra_ab_ep_num>\d{1,3}))? # E02
(v(?P<version>[0-9]))? # version (v(?P<version>[0-9]))? # version
([ ._-](\[\w{1,2}\])?\[[a-z][.]?\w{2,4}\])? # codec ([ ._-](\[\w{1,2}\])?\[[a-z][.]?\w{2,4}\])? # codec
[ ._-]*\[(?P<extra_info>(\d{3,4}[xp]?\d{0,4})?[\.\w\s-]*)\] # Source_Quality_Etc- [ ._-]*\[(?P<extra_info>(\d{3,4}[xp]?\d{0,4})?[\.\w\s-]*)\] # Source_Quality_Etc-
(\[(?P<crc>\w{8})\])? (\[(?P<crc>\w{8})\])? # CRC
.*? # Separator and EOL .*? # Separator and EOL
'''), '''),
('anime_codec_crc',
'''
^(?:\[(?P<release_group>.*?)\][ ._-]*)?
(?:(?P<series_name>.*?)[ ._-]*)?
(?:(?P<ep_ab_num>(((?!(1080|720|480)[pi])|(?![hx].?264))\d{1,3}))[ ._-]*).+?
(?:\[(?P<codec>.*?)\][ ._-]*)
(?:\[(?P<crc>\w{8})\])?
.*?
'''),
('anime_and_normal', ('anime_and_normal',
# Bleach - s16e03-04 - 313-314 # Bleach - s16e03-04 - 313-314
# Bleach.s16e03-04.313-314 # Bleach.s16e03-04.313-314
@ -294,15 +275,14 @@ anime_regexes = [
[eE](?P<ep_num>\d+) # epipisode E02 [eE](?P<ep_num>\d+) # epipisode E02
(([. _-]*e|-) # linking e/- char (([. _-]*e|-) # linking e/- char
(?P<extra_ep_num>\d+))* # additional E03/etc (?P<extra_ep_num>\d+))* # additional E03/etc
([ ._-]{2,}|[ ._]+) # if "-" is used to separate at least something else has to be there(->{2,}) "s16e03-04-313-314" would make sens any way ([ ._-]{2,}|[ ._]+) # if "-" is used to separate at least something else has to be
((?P<ep_ab_num>((?!(1080|720|480)[pi])|(?![hx].?264))\d{1,3}))? # absolute number # there(->{2,}) "s16e03-04-313-314" would make sens any way
(-(?P<extra_ab_ep_num>((?!(1080|720|480)[pi])|(?![hx].?264))\d{1,3}))? # "-" as separator and anditional absolute number, all optinal (?P<ep_ab_num>\d{1,3}) # absolute number
(-(?P<extra_ab_ep_num>\d{1,3}))* # "-" as separator and anditional absolute number, all optinal
(v(?P<version>[0-9]))? # the version e.g. "v2" (v(?P<version>[0-9]))? # the version e.g. "v2"
.*? .*?
''' '''
), ),
('anime_and_normal_x', ('anime_and_normal_x',
# Bleach - s16e03-04 - 313-314 # Bleach - s16e03-04 - 313-314
# Bleach.s16e03-04.313-314 # Bleach.s16e03-04.313-314
@ -313,23 +293,23 @@ anime_regexes = [
[xX](?P<ep_num>\d+) # epipisode E02 [xX](?P<ep_num>\d+) # epipisode E02
(([. _-]*e|-) # linking e/- char (([. _-]*e|-) # linking e/- char
(?P<extra_ep_num>\d+))* # additional E03/etc (?P<extra_ep_num>\d+))* # additional E03/etc
([ ._-]{2,}|[ ._]+) # if "-" is used to separate at least something else has to be there(->{2,}) "s16e03-04-313-314" would make sens any way ([ ._-]{2,}|[ ._]+) # if "-" is used to separate at least something else has to be
((?P<ep_ab_num>((?!(1080|720|480)[pi])|(?![hx].?264))\d{1,3}))? # absolute number # there(->{2,}) "s16e03-04-313-314" would make sens any way
(-(?P<extra_ab_ep_num>((?!(1080|720|480)[pi])|(?![hx].?264))\d{1,3}))? # "-" as separator and anditional absolute number, all optinal (?P<ep_ab_num>\d{1,3}) # absolute number
(-(?P<extra_ab_ep_num>\d{1,3}))* # "-" as separator and anditional absolute number, all optinal
(v(?P<version>[0-9]))? # the version e.g. "v2" (v(?P<version>[0-9]))? # the version e.g. "v2"
.*? .*?
''' '''
), ),
('anime_and_normal_reverse', ('anime_and_normal_reverse',
# Bleach - 313-314 - s16e03-04 # Bleach - 313-314 - s16e03-04
''' '''
^(?P<series_name>.+?)[ ._-]+ # start of string and series name and non optinal separator ^(?P<series_name>.+?)[ ._-]+ # start of string and series name and non optinal separator
(?P<ep_ab_num>((?!(1080|720|480)[pi])|(?![hx].?264))\d{1,3}) # absolute number (?P<ep_ab_num>\d{1,3}) # absolute number
(-(?P<extra_ab_ep_num>((?!(1080|720|480)[pi])|(?![hx].?264))\d{1,3}))? # "-" as separator and anditional absolute number, all optinal (-(?P<extra_ab_ep_num>\d{1,3}))* # "-" as separator and anditional absolute number, all optinal
(v(?P<version>[0-9]))? # the version e.g. "v2" (v(?P<version>[0-9]))? # the version e.g. "v2"
([ ._-]{2,}|[ ._]+) # if "-" is used to separate at least something else has to be there(->{2,}) "s16e03-04-313-314" would make sens any way ([ ._-]{2,}|[ ._]+) # if "-" is used to separate at least something else has to be
# there(->{2,}) "s16e03-04-313-314" would make sens any way
[sS](?P<season_num>\d+)[. _-]* # S01 and optional separator [sS](?P<season_num>\d+)[. _-]* # S01 and optional separator
[eE](?P<ep_num>\d+) # epipisode E02 [eE](?P<ep_num>\d+) # epipisode E02
(([. _-]*e|-) # linking e/- char (([. _-]*e|-) # linking e/- char
@ -337,12 +317,11 @@ anime_regexes = [
.*? .*?
''' '''
), ),
('anime_and_normal_front', ('anime_and_normal_front',
# 165.Naruto Shippuuden.s08e014 # 165.Naruto Shippuuden.s08e014
''' '''
^(?P<ep_ab_num>((?!(1080|720|480)[pi])|(?![hx].?264))\d{1,3}) # start of string and absolute number ^(?P<ep_ab_num>\d{1,3}) # start of string and absolute number
(-(?P<extra_ab_ep_num>((?!(1080|720|480)[pi])|(?![hx].?264))\d{1,3}))? # "-" as separator and anditional absolute number, all optinal (-(?P<extra_ab_ep_num>\d{1,3}))* # "-" as separator and anditional absolute number, all optinal
(v(?P<version>[0-9]))?[ ._-]+ # the version e.g. "v2" (v(?P<version>[0-9]))?[ ._-]+ # the version e.g. "v2"
(?P<series_name>.+?)[ ._-]+ (?P<series_name>.+?)[ ._-]+
[sS](?P<season_num>\d+)[. _-]* # S01 and optional separator [sS](?P<season_num>\d+)[. _-]* # S01 and optional separator
@ -352,13 +331,12 @@ anime_regexes = [
.*? .*?
''' '''
), ),
('anime_ep_name', ('anime_ep_name',
''' '''
^(?:\[(?P<release_group>.+?)\][ ._-]*) ^(?:\[(?P<release_group>.+?)\][ ._-]*)
(?P<series_name>.+?)[ ._-]+ (?P<series_name>.+?)[ ._-]+
(?P<ep_ab_num>((?!(1080|720|480)[pi])|(?![hx].?264))\d{1,3}) (?P<ep_ab_num>\d{1,3})
(-(?P<extra_ab_ep_num>((?!(1080|720|480)[pi])|(?![hx].?264))\d{1,3}))?[ ._-]*? (-(?P<extra_ab_ep_num>\d{1,3}))*[ ._-]*?
(?:v(?P<version>[0-9])[ ._-]+?)? (?:v(?P<version>[0-9])[ ._-]+?)?
(?:.+?[ ._-]+?)? (?:.+?[ ._-]+?)?
\[(?P<extra_info>\w+)\][ ._-]? \[(?P<extra_info>\w+)\][ ._-]?
@ -366,16 +344,34 @@ anime_regexes = [
.*? .*?
''' '''
), ),
('anime_bare', ('anime_bare',
# One Piece - 102 # One Piece - 102
# [ACX]_Wolf's_Spirit_001.mkv # [ACX]_Wolf's_Spirit_001.mkv
''' '''
^(\[(?P<release_group>.+?)\][ ._-]*)? ^(\[(?P<release_group>.+?)\][ ._-]*)?
(?P<series_name>.+?)[ ._-]+ # Show_Name and separator (?P<series_name>.+?)[ ._-]+ # Show_Name and separator
(?P<ep_ab_num>((?!(1080|720|480)[pi])|(?![hx].?264))\d{1,3}) # E01 (?<!H.)(?P<ep_ab_num>\d{3})(?!0p) # E01, while avoiding H.264 and 1080p from being matched
(-(?P<extra_ab_ep_num>((?!(1080|720|480)[pi])|(?![hx].?264))\d{1,3}))? # E02 (-(?P<extra_ab_ep_num>\d{3}))* # E02
(v(?P<version>[0-9]))? # v2 (v(?P<version>[0-9]))? # v2
.*? # Separator and EOL .*? # Separator and EOL
''') '''),
('standard',
# Show.Name.S01E02.Source.Quality.Etc-Group
# Show Name - S01E02 - My Ep Name
# Show.Name.S01.E03.My.Ep.Name
# Show.Name.S01E02E03.Source.Quality.Etc-Group
# Show Name - S01E02-03 - My Ep Name
# Show.Name.S01.E02.E03
'''
^((?P<series_name>.+?)[. _-]+)? # Show_Name and separator
s(?P<season_num>\d+)[. _-]* # S01 and optional separator
e(?P<ep_num>\d+) # E02 and separator
(([. _-]*e|-) # linking e/- char
(?P<extra_ep_num>(?!(1080|720|480)[pi])\d+))* # additional E03/etc
[. _-]*((?P<extra_info>.+?) # Source_Quality_Etc-
((?<![. _-])(?<!WEB) # Make sure this is really the release group
-(?P<release_group>[^- ]+))?)?$ # Group
'''
),
] ]

View file

@ -83,6 +83,7 @@ class TraktNotifier:
# Start by getting all episodes in the watchlist # Start by getting all episodes in the watchlist
watchlist = TraktCall("user/watchlist/episodes.json/%API%/" + sickbeard.TRAKT_USERNAME, sickbeard.TRAKT_API, sickbeard.TRAKT_USERNAME, sickbeard.TRAKT_PASSWORD) watchlist = TraktCall("user/watchlist/episodes.json/%API%/" + sickbeard.TRAKT_USERNAME, sickbeard.TRAKT_API, sickbeard.TRAKT_USERNAME, sickbeard.TRAKT_PASSWORD)
if watchlist is not None:
# Convert watchlist to only contain current show # Convert watchlist to only contain current show
for show in watchlist: for show in watchlist:
# Check if tvdb_id exists # Check if tvdb_id exists
@ -100,6 +101,9 @@ class TraktNotifier:
data_show['episodes'].append(ep) data_show['episodes'].append(ep)
if data_show is not None: if data_show is not None:
TraktCall("show/episode/unwatchlist/%API%", sickbeard.TRAKT_API, sickbeard.TRAKT_USERNAME, sickbeard.TRAKT_PASSWORD, data_show) TraktCall("show/episode/unwatchlist/%API%", sickbeard.TRAKT_API, sickbeard.TRAKT_USERNAME, sickbeard.TRAKT_PASSWORD, data_show)
else:
logger.log('Failed to get watchlist from trakt. Unable to remove episode from watchlist',
logger.ERROR)
def test_notify(self, api, username, password): def test_notify(self, api, username, password):
""" """

View file

@ -97,7 +97,7 @@ def getNewznabProviderList(data):
providerDict[curDefault.name].needs_auth = curDefault.needs_auth providerDict[curDefault.name].needs_auth = curDefault.needs_auth
providerDict[curDefault.name].search_mode = curDefault.search_mode providerDict[curDefault.name].search_mode = curDefault.search_mode
providerDict[curDefault.name].search_fallback = curDefault.search_fallback providerDict[curDefault.name].search_fallback = curDefault.search_fallback
providerDict[curDefault.name].enable_daily = curDefault.enable_daily providerDict[curDefault.name].enable_recentsearch = curDefault.enable_recentsearch
providerDict[curDefault.name].enable_backlog = curDefault.enable_backlog providerDict[curDefault.name].enable_backlog = curDefault.enable_backlog
return filter(lambda x: x, providerList) return filter(lambda x: x, providerList)
@ -109,13 +109,13 @@ def makeNewznabProvider(configString):
search_mode = 'eponly' search_mode = 'eponly'
search_fallback = 0 search_fallback = 0
enable_daily = 0 enable_recentsearch = 0
enable_backlog = 0 enable_backlog = 0
try: try:
values = configString.split('|') values = configString.split('|')
if len(values) == 9: if len(values) == 9:
name, url, key, catIDs, enabled, search_mode, search_fallback, enable_daily, enable_backlog = values name, url, key, catIDs, enabled, search_mode, search_fallback, enable_recentsearch, enable_backlog = values
else: else:
name = values[0] name = values[0]
url = values[1] url = values[1]
@ -129,7 +129,7 @@ def makeNewznabProvider(configString):
newznab = sys.modules['sickbeard.providers.newznab'] newznab = sys.modules['sickbeard.providers.newznab']
newProvider = newznab.NewznabProvider(name, url, key=key, catIDs=catIDs, search_mode=search_mode, newProvider = newznab.NewznabProvider(name, url, key=key, catIDs=catIDs, search_mode=search_mode,
search_fallback=search_fallback, enable_daily=enable_daily, search_fallback=search_fallback, enable_recentsearch=enable_recentsearch,
enable_backlog=enable_backlog) enable_backlog=enable_backlog)
newProvider.enabled = enabled == '1' newProvider.enabled = enabled == '1'
@ -157,13 +157,13 @@ def makeTorrentRssProvider(configString):
cookies = None cookies = None
search_mode = 'eponly' search_mode = 'eponly'
search_fallback = 0 search_fallback = 0
enable_daily = 0 enable_recentsearch = 0
enable_backlog = 0 enable_backlog = 0
try: try:
values = configString.split('|') values = configString.split('|')
if len(values) == 8: if len(values) == 8:
name, url, cookies, enabled, search_mode, search_fallback, enable_daily, enable_backlog = values name, url, cookies, enabled, search_mode, search_fallback, enable_recentsearch, enable_backlog = values
else: else:
name = values[0] name = values[0]
url = values[1] url = values[1]
@ -178,7 +178,7 @@ def makeTorrentRssProvider(configString):
except: except:
return return
newProvider = torrentRss.TorrentRssProvider(name, url, cookies, search_mode, search_fallback, enable_daily, newProvider = torrentRss.TorrentRssProvider(name, url, cookies, search_mode, search_fallback, enable_recentsearch,
enable_backlog) enable_backlog)
newProvider.enabled = enabled == '1' newProvider.enabled = enabled == '1'

View file

@ -136,6 +136,8 @@ class BTNProvider(generic.TorrentProvider):
server = jsonrpclib.Server(self.url) server = jsonrpclib.Server(self.url)
parsedJSON = {} parsedJSON = {}
logger.log(u'Searching with parameters: %s' % params, logger.DEBUG)
try: try:
parsedJSON = server.getTorrents(apikey, params, int(results_per_page), int(offset)) parsedJSON = server.getTorrents(apikey, params, int(results_per_page), int(offset))
@ -201,8 +203,6 @@ class BTNProvider(generic.TorrentProvider):
if ep_obj.show.air_by_date or ep_obj.show.sports: if ep_obj.show.air_by_date or ep_obj.show.sports:
# Search for the year of the air by date show # Search for the year of the air by date show
current_params['name'] = str(ep_obj.airdate).split('-')[0] current_params['name'] = str(ep_obj.airdate).split('-')[0]
elif ep_obj.show.is_anime:
current_params['name'] = "%d" % ep_obj.scene_absolute_number
else: else:
current_params['name'] = 'Season ' + str(ep_obj.scene_season) current_params['name'] = 'Season ' + str(ep_obj.scene_season)
@ -238,8 +238,6 @@ class BTNProvider(generic.TorrentProvider):
# BTN uses dots in dates, we just search for the date since that # BTN uses dots in dates, we just search for the date since that
# combined with the series identifier should result in just one episode # combined with the series identifier should result in just one episode
search_params['name'] = date_str.replace('-', '.') search_params['name'] = date_str.replace('-', '.')
elif ep_obj.show.anime:
search_params['name'] = "%i" % int(ep_obj.scene_absolute_number)
else: else:
# Do a general name search for the episode, formatted like SXXEYY # Do a general name search for the episode, formatted like SXXEYY
search_params['name'] = "S%02dE%02d" % (ep_obj.scene_season, ep_obj.scene_episode) search_params['name'] = "S%02dE%02d" % (ep_obj.scene_season, ep_obj.scene_episode)

View file

@ -56,7 +56,7 @@ class GenericProvider:
self.search_mode = None self.search_mode = None
self.search_fallback = False self.search_fallback = False
self.enable_daily = False self.enable_recentsearch = False
self.enable_backlog = False self.enable_backlog = False
self.cache = tvcache.TVCache(self) self.cache = tvcache.TVCache(self)

View file

@ -43,7 +43,7 @@ from lib.bencode import bdecode
class NewznabProvider(generic.NZBProvider): class NewznabProvider(generic.NZBProvider):
def __init__(self, name, url, key='', catIDs='5030,5040', search_mode='eponly', search_fallback=False, def __init__(self, name, url, key='', catIDs='5030,5040', search_mode='eponly', search_fallback=False,
enable_daily=False, enable_backlog=False): enable_recentsearch=False, enable_backlog=False):
generic.NZBProvider.__init__(self, name) generic.NZBProvider.__init__(self, name)
@ -55,7 +55,7 @@ class NewznabProvider(generic.NZBProvider):
self.search_mode = search_mode self.search_mode = search_mode
self.search_fallback = search_fallback self.search_fallback = search_fallback
self.enable_daily = enable_daily self.enable_recentsearch = enable_recentsearch
self.enable_backlog = enable_backlog self.enable_backlog = enable_backlog
# a 0 in the key spot indicates that no key is needed # a 0 in the key spot indicates that no key is needed
@ -77,7 +77,7 @@ class NewznabProvider(generic.NZBProvider):
def configStr(self): def configStr(self):
return self.name + '|' + self.url + '|' + self.key + '|' + self.catIDs + '|' + str( return self.name + '|' + self.url + '|' + self.key + '|' + self.catIDs + '|' + str(
int(self.enabled)) + '|' + self.search_mode + '|' + str(int(self.search_fallback)) + '|' + str( int(self.enabled)) + '|' + self.search_mode + '|' + str(int(self.search_fallback)) + '|' + str(
int(self.enable_daily)) + '|' + str(int(self.enable_backlog)) int(self.enable_recentsearch)) + '|' + str(int(self.enable_backlog))
def imageName(self): def imageName(self):
if ek.ek(os.path.isfile, if ek.ek(os.path.isfile,

View file

@ -36,7 +36,7 @@ from lib.bencode import bdecode
class TorrentRssProvider(generic.TorrentProvider): class TorrentRssProvider(generic.TorrentProvider):
def __init__(self, name, url, cookies='', search_mode='eponly', search_fallback=False, enable_daily=False, def __init__(self, name, url, cookies='', search_mode='eponly', search_fallback=False, enable_recentsearch=False,
enable_backlog=False): enable_backlog=False):
generic.TorrentProvider.__init__(self, name) generic.TorrentProvider.__init__(self, name)
self.cache = TorrentRssCache(self) self.cache = TorrentRssCache(self)
@ -48,7 +48,7 @@ class TorrentRssProvider(generic.TorrentProvider):
self.search_mode = search_mode self.search_mode = search_mode
self.search_fallback = search_fallback self.search_fallback = search_fallback
self.enable_daily = enable_daily self.enable_recentsearch = enable_recentsearch
self.enable_backlog = enable_backlog self.enable_backlog = enable_backlog
self.cookies = cookies self.cookies = cookies
@ -59,7 +59,7 @@ class TorrentRssProvider(generic.TorrentProvider):
self.enabled, self.enabled,
self.search_mode or '', self.search_mode or '',
self.search_fallback, self.search_fallback,
self.enable_daily, self.enable_recentsearch,
self.enable_backlog) self.enable_backlog)
def imageName(self): def imageName(self):

View file

@ -61,11 +61,11 @@ class ThePirateBayProvider(generic.TorrentProvider):
self.proxy = ThePirateBayWebproxy() self.proxy = ThePirateBayWebproxy()
self.url = 'http://pirateproxy.net/' self.url = 'http://oldpiratebay.org/'
self.searchurl = self.url + 'search/%s/0/7/200' # order by seed self.searchurl = self.url + 'search.php?q=%s&Torrent_sort=seeders.desc' # order by seed
self.re_title_url = '/torrent/(?P<id>\d+)/(?P<title>.*?)//1".+?(?P<url>magnet.*?)//1".+?(?P<seeders>\d+)</td>.+?(?P<leechers>\d+)</td>' self.re_title_url = 'href=["\'](?P<url>magnet:.*?)&.*?/torrent/(?P<id>\d+)/(?P<title>.*?)".+?seeders-row sy">(?P<seeders>\d+)</td>.+?leechers-row ly">(?P<leechers>\d+)</td>'
def isEnabled(self): def isEnabled(self):
return self.enabled return self.enabled

View file

@ -30,7 +30,7 @@ class WombleProvider(generic.NZBProvider):
generic.NZBProvider.__init__(self, "Womble's Index") generic.NZBProvider.__init__(self, "Womble's Index")
self.enabled = False self.enabled = False
self.cache = WombleCache(self) self.cache = WombleCache(self)
self.url = 'https://newshost.co.za/' self.url = 'http://newshost.co.za/'
def isEnabled(self): def isEnabled(self):
return self.enabled return self.enabled
@ -53,7 +53,7 @@ class WombleCache(tvcache.TVCache):
return return
cl = [] cl = []
for url in [self.provider.url + 'rss/?sec=tv-sd&fr=false', self.provider.url + 'rss/?sec=tv-hd&fr=false']: for url in [self.provider.url + 'rss/?sec=tv-x264&fr=false', self.provider.url + 'rss/?sec=tv-sd&fr=false', self.provider.url + 'rss/?sec=tv-hd&fr=false']:
logger.log(u"Womble's Index cache update URL: " + url, logger.DEBUG) logger.log(u"Womble's Index cache update URL: " + url, logger.DEBUG)
data = self.getRSSFeed(url) data = self.getRSSFeed(url)
@ -63,12 +63,11 @@ class WombleCache(tvcache.TVCache):
# By now we know we've got data and no auth errors, all we need to do is put it in the database # By now we know we've got data and no auth errors, all we need to do is put it in the database
for item in data.entries: for item in data.entries:
ci = self._parseItem(item) title, url = self._get_title_and_url(item)
ci = self._parseItem(title, url)
if ci is not None: if ci is not None:
cl.append(ci) cl.append(ci)
if len(cl) > 0: if len(cl) > 0:
myDB = self._getDB() myDB = self._getDB()
myDB.mass_action(cl) myDB.mass_action(cl)
@ -81,4 +80,3 @@ class WombleCache(tvcache.TVCache):
return data != 'Invalid Link' return data != 'Invalid Link'
provider = WombleProvider() provider = WombleProvider()

View file

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

View file

@ -375,7 +375,7 @@ def searchForNeededEpisodes():
episodes.extend(wantedEpisodes(curShow, fromDate)) episodes.extend(wantedEpisodes(curShow, fromDate))
providers = [x for x in sickbeard.providers.sortedProviderList() if x.isActive() and x.enable_daily] providers = [x for x in sickbeard.providers.sortedProviderList() if x.isActive() and x.enable_recentsearch]
for curProvider in providers: for curProvider in providers:
# spawn separate threads for each provider so we don't need to wait for providers with slow network operation # spawn separate threads for each provider so we don't need to wait for providers with slow network operation
@ -435,7 +435,7 @@ def searchForNeededEpisodes():
if not didSearch: if not didSearch:
logger.log( logger.log(
u"No NZB/Torrent providers found or enabled in the SickGear config for daily searches. Please check your settings.", u"No NZB/Torrent providers found or enabled in the SickGear config for recent searches. Please check your settings.",
logger.ERROR) logger.ERROR)
return foundResults.values() return foundResults.values()

View file

@ -32,7 +32,7 @@ from sickbeard import network_timezones
from sickbeard.exceptions import ex from sickbeard.exceptions import ex
class DailySearcher(): class RecentSearcher():
def __init__(self): def __init__(self):
self.lock = threading.Lock() self.lock = threading.Lock()
self.amActive = False self.amActive = False
@ -97,8 +97,8 @@ class DailySearcher():
myDB = db.DBConnection() myDB = db.DBConnection()
myDB.mass_action(sql_l) myDB.mass_action(sql_l)
# queue episode for daily search # queue episode for recent search
dailysearch_queue_item = sickbeard.search_queue.DailySearchQueueItem() recentsearch_queue_item = sickbeard.search_queue.RecentSearchQueueItem()
sickbeard.searchQueueScheduler.action.add_item(dailysearch_queue_item) sickbeard.searchQueueScheduler.action.add_item(recentsearch_queue_item)
self.amActive = False self.amActive = False

View file

@ -33,7 +33,7 @@ from sickbeard.search import pickBestResult
search_queue_lock = threading.Lock() search_queue_lock = threading.Lock()
BACKLOG_SEARCH = 10 BACKLOG_SEARCH = 10
DAILY_SEARCH = 20 RECENT_SEARCH = 20
FAILED_SEARCH = 30 FAILED_SEARCH = 30
MANUAL_SEARCH = 40 MANUAL_SEARCH = 40
@ -95,17 +95,17 @@ class SearchQueue(generic_queue.GenericQueue):
return True return True
return False return False
def is_dailysearch_in_progress(self): def is_recentsearch_in_progress(self):
for cur_item in self.queue + [self.currentItem]: for cur_item in self.queue + [self.currentItem]:
if isinstance(cur_item, DailySearchQueueItem): if isinstance(cur_item, RecentSearchQueueItem):
return True return True
return False return False
def queue_length(self): def queue_length(self):
length = {'backlog': 0, 'daily': 0, 'manual': 0, 'failed': 0} length = {'backlog': 0, 'recent': 0, 'manual': 0, 'failed': 0}
for cur_item in self.queue: for cur_item in self.queue:
if isinstance(cur_item, DailySearchQueueItem): if isinstance(cur_item, RecentSearchQueueItem):
length['daily'] += 1 length['recent'] += 1
elif isinstance(cur_item, BacklogQueueItem): elif isinstance(cur_item, BacklogQueueItem):
length['backlog'] += 1 length['backlog'] += 1
elif isinstance(cur_item, ManualSearchQueueItem): elif isinstance(cur_item, ManualSearchQueueItem):
@ -116,8 +116,8 @@ class SearchQueue(generic_queue.GenericQueue):
def add_item(self, item): def add_item(self, item):
if isinstance(item, DailySearchQueueItem): if isinstance(item, RecentSearchQueueItem):
# daily searches # recent searches
generic_queue.GenericQueue.add_item(self, item) generic_queue.GenericQueue.add_item(self, item)
elif isinstance(item, BacklogQueueItem) and not self.is_in_queue(item.show, item.segment): elif isinstance(item, BacklogQueueItem) and not self.is_in_queue(item.show, item.segment):
# backlog searches # backlog searches
@ -128,16 +128,16 @@ class SearchQueue(generic_queue.GenericQueue):
else: else:
logger.log(u"Not adding item, it's already in the queue", logger.DEBUG) logger.log(u"Not adding item, it's already in the queue", logger.DEBUG)
class DailySearchQueueItem(generic_queue.QueueItem): class RecentSearchQueueItem(generic_queue.QueueItem):
def __init__(self): def __init__(self):
self.success = None self.success = None
generic_queue.QueueItem.__init__(self, 'Daily Search', DAILY_SEARCH) generic_queue.QueueItem.__init__(self, 'Recent Search', RECENT_SEARCH)
def run(self): def run(self):
generic_queue.QueueItem.run(self) generic_queue.QueueItem.run(self)
try: try:
logger.log("Beginning daily search for new episodes") logger.log("Beginning recent search for new episodes")
foundResults = search.searchForNeededEpisodes() foundResults = search.searchForNeededEpisodes()
if not len(foundResults): if not len(foundResults):

View file

@ -97,7 +97,7 @@ class TVCache():
myDB.action('DELETE FROM [' + self.providerID + '] WHERE 1') myDB.action('DELETE FROM [' + self.providerID + '] WHERE 1')
def _get_title_and_url(self, item): def _get_title_and_url(self, item):
# override this in the provider if daily search has a different data layout to backlog searches # override this in the provider if recent search has a different data layout to backlog searches
return self.provider._get_title_and_url(item) return self.provider._get_title_and_url(item)
def _getRSSData(self): def _getRSSData(self):
@ -222,7 +222,7 @@ class TVCache():
return True return True
def shouldClearCache(self): def shouldClearCache(self):
# if daily search hasn't used our previous results yet then don't clear the cache # if recent search hasn't used our previous results yet then don't clear the cache
if self.lastUpdate > self.lastSearch: if self.lastUpdate > self.lastSearch:
return False return False

View file

@ -115,9 +115,15 @@ class CheckVersion():
if self.updater.need_update(): if self.updater.need_update():
return self.updater.update() return self.updater.update()
def fetch(self, pull_request):
return self.updater.fetch(pull_request)
def list_remote_branches(self): def list_remote_branches(self):
return self.updater.list_remote_branches() return self.updater.list_remote_branches()
def list_remote_pulls(self):
return self.updater.list_remote_pulls()
def get_branch(self): def get_branch(self):
return self.updater.branch return self.updater.branch
@ -400,6 +406,17 @@ class GitUpdateManager(UpdateManager):
return re.findall('\S+\Wrefs/heads/(.*)', branches) return re.findall('\S+\Wrefs/heads/(.*)', branches)
return [] return []
def list_remote_pulls(self):
gh = github.GitHub(self.github_repo_user, self.github_repo, self.branch)
return gh.pull_requests()
def fetch(self, pull_request):
output, err, exit_status = self._run_git(self._git_path, 'fetch -f %s %s' % (sickbeard.GIT_REMOTE, pull_request)) # @UnusedVariable
if exit_status == 0:
return True
return False
class SourceUpdateManager(UpdateManager): class SourceUpdateManager(UpdateManager):
def __init__(self): def __init__(self):
@ -597,3 +614,7 @@ class SourceUpdateManager(UpdateManager):
def list_remote_branches(self): def list_remote_branches(self):
gh = github.GitHub(self.github_repo_user, self.github_repo, self.branch) gh = github.GitHub(self.github_repo_user, self.github_repo, self.branch)
return [x['name'] for x in gh.branches() if x and 'name' in x] return [x['name'] for x in gh.branches() if x and 'name' in x]
def list_remote_pulls(self):
# we don't care about testers that don't use git
return []

View file

@ -711,7 +711,7 @@ class CMD_ComingEpisodes(ApiCall):
self.sort, args = self.check_params(args, kwargs, "sort", "date", False, "string", ["date", "show", "network"]) self.sort, args = self.check_params(args, kwargs, "sort", "date", False, "string", ["date", "show", "network"])
self.type, args = self.check_params(args, kwargs, "type", "today|missed|soon|later", False, "list", self.type, args = self.check_params(args, kwargs, "type", "today|missed|soon|later", False, "list",
["missed", "later", "today", "soon"]) ["missed", "later", "today", "soon"])
self.paused, args = self.check_params(args, kwargs, "paused", sickbeard.COMING_EPS_DISPLAY_PAUSED, False, "int", self.paused, args = self.check_params(args, kwargs, "paused", sickbeard.EPISODE_VIEW_DISPLAY_PAUSED, False, "int",
[0, 1]) [0, 1])
# super, missing, help # super, missing, help
ApiCall.__init__(self, handler, args, kwargs) ApiCall.__init__(self, handler, args, kwargs)
@ -725,7 +725,7 @@ class CMD_ComingEpisodes(ApiCall):
tomorrow = (datetime.date.today() + datetime.timedelta(days=1)).toordinal() tomorrow = (datetime.date.today() + datetime.timedelta(days=1)).toordinal()
next_week_dt = (datetime.date.today() + datetime.timedelta(days=7)) next_week_dt = (datetime.date.today() + datetime.timedelta(days=7))
next_week = (next_week_dt + datetime.timedelta(days=1)).toordinal() next_week = (next_week_dt + datetime.timedelta(days=1)).toordinal()
recently = (yesterday_dt - datetime.timedelta(days=sickbeard.COMING_EPS_MISSED_RANGE)).toordinal() recently = (yesterday_dt - datetime.timedelta(days=sickbeard.EPISODE_VIEW_MISSED_RANGE)).toordinal()
done_show_list = [] done_show_list = []
qualList = Quality.DOWNLOADED + Quality.SNATCHED + [ARCHIVED, IGNORED] qualList = Quality.DOWNLOADED + Quality.SNATCHED + [ARCHIVED, IGNORED]
@ -758,31 +758,27 @@ class CMD_ComingEpisodes(ApiCall):
# multi dimension sort # multi dimension sort
sorts = { sorts = {
'date': (lambda a, b: cmp( 'date': (lambda a, b: cmp(
(a['parsed_datetime'], (a['parsed_datetime'], a['data_show_name'], a['season'], a['episode']),
(a['show_name'], remove_article(a['show_name']))[not sickbeard.SORT_ARTICLE], (b['parsed_datetime'], b['data_show_name'], b['season'], b['episode']))),
a['season'], a['episode']),
(b['parsed_datetime'],
(b['show_name'], remove_article(b['show_name']))[not sickbeard.SORT_ARTICLE],
b['season'], b['episode']))),
'show': (lambda a, b: cmp(
((a['show_name'], remove_article(a['show_name']))[not sickbeard.SORT_ARTICLE],
a['parsed_datetime'], a['season'], a['episode']),
((b['show_name'], remove_article(b['show_name']))[not sickbeard.SORT_ARTICLE],
b['parsed_datetime'], b['season'], b['episode']))),
'network': (lambda a, b: cmp( 'network': (lambda a, b: cmp(
(a['network'], a['parsed_datetime'], (a['data_network'], a['parsed_datetime'], a['data_show_name'], a['season'], a['episode']),
(a['show_name'], remove_article(a['show_name']))[not sickbeard.SORT_ARTICLE], (b['data_network'], b['parsed_datetime'], b['data_show_name'], b['season'], b['episode']))),
a['season'], a['episode']), 'show': (lambda a, b: cmp(
(b['network'], b['parsed_datetime'], (a['data_show_name'], a['parsed_datetime'], a['season'], a['episode']),
(b['show_name'], remove_article(b['show_name']))[not sickbeard.SORT_ARTICLE], (b['data_show_name'], b['parsed_datetime'], b['season'], b['episode'])))
b['season'], b['episode'])))
} }
def value_maybe_article(value=''):
return (remove_article(value.lower()), value.lower())[sickbeard.SORT_ARTICLE]
# add parsed_datetime to the dict # add parsed_datetime to the dict
for index, item in enumerate(sql_results): for index, item in enumerate(sql_results):
sql_results[index]['parsed_datetime'] = network_timezones.parse_date_time(item['airdate'], item['airs'], item['network']) sql_results[index]['parsed_datetime'] = network_timezones.parse_date_time(item['airdate'], item['airs'], item['network'])
sql_results[index]['data_show_name'] = value_maybe_article(item['show_name'])
sql_results[index]['data_network'] = value_maybe_article(item['network'])
sql_results.sort(sorts[self.sort]) sql_results.sort(sorts[self.sort])
finalEpResults = {} finalEpResults = {}
# add all requested types or all # add all requested types or all
@ -1507,7 +1503,7 @@ class CMD_SickBeardGetDefaults(ApiCall):
data = {"status": statusStrings[sickbeard.STATUS_DEFAULT].lower(), data = {"status": statusStrings[sickbeard.STATUS_DEFAULT].lower(),
"flatten_folders": int(sickbeard.FLATTEN_FOLDERS_DEFAULT), "initial": anyQualities, "flatten_folders": int(sickbeard.FLATTEN_FOLDERS_DEFAULT), "initial": anyQualities,
"archive": bestQualities, "future_show_paused": int(sickbeard.COMING_EPS_DISPLAY_PAUSED)} "archive": bestQualities, "future_show_paused": int(sickbeard.EPISODE_VIEW_DISPLAY_PAUSED)}
return _responds(RESULT_SUCCESS, data) return _responds(RESULT_SUCCESS, data)
@ -1756,7 +1752,7 @@ class CMD_SickBeardSetDefaults(ApiCall):
sickbeard.FLATTEN_FOLDERS_DEFAULT = int(self.flatten_folders) sickbeard.FLATTEN_FOLDERS_DEFAULT = int(self.flatten_folders)
if self.future_show_paused != None: if self.future_show_paused != None:
sickbeard.COMING_EPS_DISPLAY_PAUSED = int(self.future_show_paused) sickbeard.EPISODE_VIEW_DISPLAY_PAUSED = int(self.future_show_paused)
return _responds(RESULT_SUCCESS, msg="Saved defaults") return _responds(RESULT_SUCCESS, msg="Saved defaults")

View file

@ -67,7 +67,7 @@ from lib.dateutil import tz
from lib.unrar2 import RarFile from lib.unrar2 import RarFile
from lib import subliminal from lib import subliminal
from trakt import TraktCall from lib.trakt import TraktCall
try: try:
import json import json
@ -300,7 +300,7 @@ class MainHandler(RequestHandler):
def setPosterSortBy(self, sort): def setPosterSortBy(self, sort):
if sort not in ('name', 'date', 'network', 'progress'): if sort not in ('name', 'time', 'network', 'progress'):
sort = 'name' sort = 'name'
sickbeard.POSTER_SORTBY = sort sickbeard.POSTER_SORTBY = sort
@ -326,36 +326,40 @@ class MainHandler(RequestHandler):
redirect("/home/displayShow?show=" + show) redirect("/home/displayShow?show=" + show)
def setComingEpsLayout(self, layout): def setEpisodeViewLayout(self, layout):
if layout not in ('poster', 'banner', 'list', 'calendar'): if layout not in ('poster', 'banner', 'list', 'daybyday'):
layout = 'banner' layout = 'banner'
if layout == 'calendar': if 'daybyday' == layout:
sickbeard.COMING_EPS_SORT = 'date' sickbeard.EPISODE_VIEW_SORT = 'time'
sickbeard.COMING_EPS_LAYOUT = layout sickbeard.EPISODE_VIEW_LAYOUT = layout
redirect("/comingEpisodes/") sickbeard.save_config()
def toggleComingEpsDisplayPaused(self, *args, **kwargs): redirect("/episodeView/")
sickbeard.COMING_EPS_DISPLAY_PAUSED = not sickbeard.COMING_EPS_DISPLAY_PAUSED def toggleEpisodeViewDisplayPaused(self, *args, **kwargs):
redirect("/comingEpisodes/") sickbeard.EPISODE_VIEW_DISPLAY_PAUSED = not sickbeard.EPISODE_VIEW_DISPLAY_PAUSED
def setComingEpsSort(self, sort): sickbeard.save_config()
if sort not in ('date', 'network', 'show'):
sort = 'date'
if sickbeard.COMING_EPS_LAYOUT == 'calendar': redirect("/episodeView/")
sort = 'date'
sickbeard.COMING_EPS_SORT = sort def setEpisodeViewSort(self, sort, redir=1):
if sort not in ('time', 'network', 'show'):
sort = 'time'
redirect("/comingEpisodes/") sickbeard.EPISODE_VIEW_SORT = sort
def comingEpisodes(self, layout="None"): sickbeard.save_config()
""" display the coming episodes """
if int(redir):
redirect("/episodeView/")
def episodeView(self, layout="None"):
""" display the episodes """
today_dt = datetime.date.today() today_dt = datetime.date.today()
#today = today_dt.toordinal() #today = today_dt.toordinal()
yesterday_dt = today_dt - datetime.timedelta(days=1) yesterday_dt = today_dt - datetime.timedelta(days=1)
@ -363,8 +367,8 @@ class MainHandler(RequestHandler):
tomorrow = (datetime.date.today() + datetime.timedelta(days=1)).toordinal() tomorrow = (datetime.date.today() + datetime.timedelta(days=1)).toordinal()
next_week_dt = (datetime.date.today() + datetime.timedelta(days=7)) next_week_dt = (datetime.date.today() + datetime.timedelta(days=7))
next_week = (next_week_dt + datetime.timedelta(days=1)).toordinal() next_week = (next_week_dt + datetime.timedelta(days=1)).toordinal()
if not (layout and layout in ('calendar')) and not (sickbeard.COMING_EPS_LAYOUT and sickbeard.COMING_EPS_LAYOUT in ('calendar')): if not (layout and layout in 'daybyday') and not (sickbeard.EPISODE_VIEW_LAYOUT and sickbeard.EPISODE_VIEW_LAYOUT in 'daybyday'):
recently = (yesterday_dt - datetime.timedelta(days=sickbeard.COMING_EPS_MISSED_RANGE)).toordinal() recently = (yesterday_dt - datetime.timedelta(days=sickbeard.EPISODE_VIEW_MISSED_RANGE)).toordinal()
else: else:
recently = yesterday recently = yesterday
@ -379,7 +383,7 @@ class MainHandler(RequestHandler):
for cur_result in sql_results: for cur_result in sql_results:
done_show_list.append(int(cur_result["showid"])) done_show_list.append(int(cur_result["showid"]))
if not (layout and layout in ('calendar')) and not (sickbeard.COMING_EPS_LAYOUT and sickbeard.COMING_EPS_LAYOUT in ('calendar')): if not (layout and layout in 'daybyday') and not (sickbeard.EPISODE_VIEW_LAYOUT and sickbeard.EPISODE_VIEW_LAYOUT in 'daybyday'):
more_sql_results = myDB.select( 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( "SELECT *, tv_shows.status as show_status FROM tv_episodes outer_eps, tv_shows WHERE season != 0 AND showid NOT IN (" + ','.join(
['?'] * len( ['?'] * len(
@ -395,49 +399,44 @@ class MainHandler(RequestHandler):
sql_results = list(set(sql_results)) sql_results = list(set(sql_results))
# multi dimension sort
sorts = {
'date': (lambda a, b: cmp(
(a['localtime'],
(a['show_name'], remove_article(a['show_name']))[not sickbeard.SORT_ARTICLE],
a['season'], a['episode']),
(b['localtime'],
(b['show_name'], remove_article(b['show_name']))[not sickbeard.SORT_ARTICLE],
b['season'], b['episode']))),
'show': (lambda a, b: cmp(
((a['show_name'], remove_article(a['show_name']))[not sickbeard.SORT_ARTICLE],
a['localtime'], a['season'], a['episode']),
((b['show_name'], remove_article(b['show_name']))[not sickbeard.SORT_ARTICLE],
b['localtime'], b['season'], b['episode']))),
'network': (lambda a, b: cmp(
(a['network'], a['localtime'],
(a['show_name'], remove_article(a['show_name']))[not sickbeard.SORT_ARTICLE],
a['season'], a['episode']),
(b['network'], b['localtime'],
(b['show_name'], remove_article(b['show_name']))[not sickbeard.SORT_ARTICLE],
b['season'], b['episode'])))
}
# make a dict out of the sql results # make a dict out of the sql results
sql_results = [dict(row) for row in sql_results] sql_results = [dict(row) for row in sql_results]
# multi dimension sort
sorts = {
'network': (lambda a, b: cmp(
(a['data_network'], a['localtime'], a['data_show_name'], a['season'], a['episode']),
(b['data_network'], b['localtime'], b['data_show_name'], b['season'], b['episode']))),
'show': (lambda a, b: cmp(
(a['data_show_name'], a['localtime'], a['season'], a['episode']),
(b['data_show_name'], b['localtime'], b['season'], b['episode']))),
'time': (lambda a, b: cmp(
(a['localtime'], a['data_show_name'], a['season'], a['episode']),
(b['localtime'], b['data_show_name'], b['season'], b['episode'])))
}
def value_maybe_article(value=''):
return (remove_article(value.lower()), value.lower())[sickbeard.SORT_ARTICLE]
# add localtime to the dict # add localtime to the dict
for index, item in enumerate(sql_results): for index, item in enumerate(sql_results):
sql_results[index]['localtime'] = sbdatetime.sbdatetime.convert_to_setting(network_timezones.parse_date_time(item['airdate'], sql_results[index]['localtime'] = sbdatetime.sbdatetime.convert_to_setting(network_timezones.parse_date_time(item['airdate'],
item['airs'], item['network'])) item['airs'], item['network']))
sql_results[index]['data_show_name'] = value_maybe_article(item['show_name'])
sql_results[index]['data_network'] = value_maybe_article(item['network'])
sql_results.sort(sorts[sickbeard.COMING_EPS_SORT]) sql_results.sort(sorts[sickbeard.EPISODE_VIEW_SORT])
t = PageTemplate(headers=self.request.headers, file="comingEpisodes.tmpl") t = PageTemplate(headers=self.request.headers, file="episodeView.tmpl")
t.next_week = datetime.datetime.combine(next_week_dt, datetime.time(tzinfo=network_timezones.sb_timezone)) t.next_week = datetime.datetime.combine(next_week_dt, datetime.time(tzinfo=network_timezones.sb_timezone))
t.today = datetime.datetime.now(network_timezones.sb_timezone) t.today = datetime.datetime.now(network_timezones.sb_timezone)
t.sql_results = sql_results t.sql_results = sql_results
# Allow local overriding of layout parameter # Allow local overriding of layout parameter
if layout and layout in ('poster', 'banner', 'list','calendar'): if layout and layout in ('banner', 'daybyday', 'list', 'poster'):
t.layout = layout t.layout = layout
else: else:
t.layout = sickbeard.COMING_EPS_LAYOUT t.layout = sickbeard.EPISODE_VIEW_LAYOUT
return _munge(t) return _munge(t)
@ -549,7 +548,7 @@ class PageTemplate(Template):
self.sbPID = str(sickbeard.PID) self.sbPID = str(sickbeard.PID)
self.menu = [ self.menu = [
{'title': 'Home', 'key': 'home'}, {'title': 'Home', 'key': 'home'},
{'title': 'Coming Episodes', 'key': 'comingEpisodes'}, {'title': 'Episodes', 'key': 'episodeView'},
{'title': 'History', 'key': 'history'}, {'title': 'History', 'key': 'history'},
{'title': 'Manage', 'key': 'manage'}, {'title': 'Manage', 'key': 'manage'},
{'title': 'Config', 'key': 'config'}, {'title': 'Config', 'key': 'config'},
@ -630,7 +629,7 @@ class ManageSearches(MainHandler):
# t.backlogPI = sickbeard.backlogSearchScheduler.action.getProgressIndicator() # t.backlogPI = sickbeard.backlogSearchScheduler.action.getProgressIndicator()
t.backlogPaused = sickbeard.searchQueueScheduler.action.is_backlog_paused() # @UndefinedVariable t.backlogPaused = sickbeard.searchQueueScheduler.action.is_backlog_paused() # @UndefinedVariable
t.backlogRunning = sickbeard.searchQueueScheduler.action.is_backlog_in_progress() # @UndefinedVariable t.backlogRunning = sickbeard.searchQueueScheduler.action.is_backlog_in_progress() # @UndefinedVariable
t.dailySearchStatus = sickbeard.dailySearchScheduler.action.amActive # @UndefinedVariable t.recentSearchStatus = sickbeard.recentSearchScheduler.action.amActive # @UndefinedVariable
t.findPropersStatus = sickbeard.properFinderScheduler.action.amActive # @UndefinedVariable t.findPropersStatus = sickbeard.properFinderScheduler.action.amActive # @UndefinedVariable
t.queueLength = sickbeard.searchQueueScheduler.action.queue_length() t.queueLength = sickbeard.searchQueueScheduler.action.queue_length()
@ -658,10 +657,10 @@ class ManageSearches(MainHandler):
def forceSearch(self, *args, **kwargs): def forceSearch(self, *args, **kwargs):
# force it to run the next time it looks # force it to run the next time it looks
result = sickbeard.dailySearchScheduler.forceRun() result = sickbeard.recentSearchScheduler.forceRun()
if result: if result:
logger.log(u"Daily search forced") logger.log(u"Recent search forced")
ui.notifications.message('Daily search started') ui.notifications.message('Recent search started')
redirect("/manage/manageSearches/") redirect("/manage/manageSearches/")
@ -1628,10 +1627,10 @@ class ConfigSearch(MainHandler):
def saveSearch(self, use_nzbs=None, use_torrents=None, nzb_dir=None, sab_username=None, sab_password=None, def saveSearch(self, use_nzbs=None, use_torrents=None, nzb_dir=None, sab_username=None, sab_password=None,
sab_apikey=None, sab_category=None, sab_host=None, nzbget_username=None, nzbget_password=None, sab_apikey=None, sab_category=None, sab_host=None, nzbget_username=None, nzbget_password=None,
nzbget_category=None, nzbget_priority=None, nzbget_host=None, nzbget_use_https=None, nzbget_category=None, nzbget_priority=None, nzbget_host=None, nzbget_use_https=None,
backlog_days=None, backlog_frequency=None, dailysearch_frequency=None, backlog_days=None, backlog_frequency=None, recentsearch_frequency=None,
nzb_method=None, torrent_method=None, usenet_retention=None, nzb_method=None, torrent_method=None, usenet_retention=None,
download_propers=None, check_propers_interval=None, allow_high_priority=None, download_propers=None, check_propers_interval=None, allow_high_priority=None,
backlog_startup=None, dailysearch_startup=None, backlog_startup=None, recentsearch_startup=None,
torrent_dir=None, torrent_username=None, torrent_password=None, torrent_host=None, torrent_dir=None, torrent_username=None, torrent_password=None, torrent_host=None,
torrent_label=None, torrent_path=None, torrent_verify_cert=None, torrent_label=None, torrent_path=None, torrent_verify_cert=None,
torrent_seed_time=None, torrent_paused=None, torrent_high_bandwidth=None, ignore_words=None, require_words=None): torrent_seed_time=None, torrent_paused=None, torrent_high_bandwidth=None, ignore_words=None, require_words=None):
@ -1644,7 +1643,7 @@ class ConfigSearch(MainHandler):
if not config.change_TORRENT_DIR(torrent_dir): if not config.change_TORRENT_DIR(torrent_dir):
results += ["Unable to create directory " + os.path.normpath(torrent_dir) + ", dir not changed."] results += ["Unable to create directory " + os.path.normpath(torrent_dir) + ", dir not changed."]
config.change_DAILYSEARCH_FREQUENCY(dailysearch_frequency) config.change_RECENTSEARCH_FREQUENCY(recentsearch_frequency)
config.change_BACKLOG_FREQUENCY(backlog_frequency) config.change_BACKLOG_FREQUENCY(backlog_frequency)
sickbeard.BACKLOG_DAYS = config.to_int(backlog_days, default=7) sickbeard.BACKLOG_DAYS = config.to_int(backlog_days, default=7)
@ -1664,7 +1663,7 @@ class ConfigSearch(MainHandler):
sickbeard.ALLOW_HIGH_PRIORITY = config.checkbox_to_value(allow_high_priority) sickbeard.ALLOW_HIGH_PRIORITY = config.checkbox_to_value(allow_high_priority)
sickbeard.DAILYSEARCH_STARTUP = config.checkbox_to_value(dailysearch_startup) sickbeard.RECENTSEARCH_STARTUP = config.checkbox_to_value(recentsearch_startup)
sickbeard.BACKLOG_STARTUP = config.checkbox_to_value(backlog_startup) sickbeard.BACKLOG_STARTUP = config.checkbox_to_value(backlog_startup)
sickbeard.SAB_USERNAME = sab_username sickbeard.SAB_USERNAME = sab_username
@ -2092,10 +2091,10 @@ class ConfigProviders(MainHandler):
newznabProviderDict[cur_id].search_fallback = 0 newznabProviderDict[cur_id].search_fallback = 0
try: try:
newznabProviderDict[cur_id].enable_daily = config.checkbox_to_value( newznabProviderDict[cur_id].enable_recentsearch = config.checkbox_to_value(
kwargs[cur_id + '_enable_daily']) kwargs[cur_id + '_enable_recentsearch'])
except: except:
newznabProviderDict[cur_id].enable_daily = 0 newznabProviderDict[cur_id].enable_recentsearch = 0
try: try:
newznabProviderDict[cur_id].enable_backlog = config.checkbox_to_value( newznabProviderDict[cur_id].enable_backlog = config.checkbox_to_value(
@ -2258,12 +2257,12 @@ class ConfigProviders(MainHandler):
except: except:
curTorrentProvider.search_fallback = 0 # these exceptions are catching unselected checkboxes curTorrentProvider.search_fallback = 0 # these exceptions are catching unselected checkboxes
if hasattr(curTorrentProvider, 'enable_daily'): if hasattr(curTorrentProvider, 'enable_recentsearch'):
try: try:
curTorrentProvider.enable_daily = config.checkbox_to_value( curTorrentProvider.enable_recentsearch = config.checkbox_to_value(
kwargs[curTorrentProvider.getID() + '_enable_daily']) kwargs[curTorrentProvider.getID() + '_enable_recentsearch'])
except: except:
curTorrentProvider.enable_daily = 0 # these exceptions are actually catching unselected checkboxes curTorrentProvider.enable_recentsearch = 0 # these exceptions are actually catching unselected checkboxes
if hasattr(curTorrentProvider, 'enable_backlog'): if hasattr(curTorrentProvider, 'enable_backlog'):
try: try:
@ -2300,12 +2299,12 @@ class ConfigProviders(MainHandler):
except: except:
curNzbProvider.search_fallback = 0 # these exceptions are actually catching unselected checkboxes curNzbProvider.search_fallback = 0 # these exceptions are actually catching unselected checkboxes
if hasattr(curNzbProvider, 'enable_daily'): if hasattr(curNzbProvider, 'enable_recentsearch'):
try: try:
curNzbProvider.enable_daily = config.checkbox_to_value( curNzbProvider.enable_recentsearch = config.checkbox_to_value(
kwargs[curNzbProvider.getID() + '_enable_daily']) kwargs[curNzbProvider.getID() + '_enable_recentsearch'])
except: except:
curNzbProvider.enable_daily = 0 # these exceptions are actually catching unselected checkboxes curNzbProvider.enable_recentsearch = 0 # these exceptions are actually catching unselected checkboxes
if hasattr(curNzbProvider, 'enable_backlog'): if hasattr(curNzbProvider, 'enable_backlog'):
try: try:
@ -2980,7 +2979,7 @@ class NewHomeAddShows(MainHandler):
tvdbs = ['tvdb_id', 'tvrage_id'] tvdbs = ['tvdb_id', 'tvrage_id']
for index, tvdb in enumerate(tvdbs): for index, tvdb in enumerate(tvdbs):
try: try:
item[u'show_id'] = item[tvdb] item[u'show_id'] = str(item[tvdb])
tvshow = helpers.findCertainShow(sickbeard.showList, int(item[tvdb])) tvshow = helpers.findCertainShow(sickbeard.showList, int(item[tvdb]))
except: except:
continue continue
@ -3628,6 +3627,17 @@ class Home(MainHandler):
ui.notifications.message('Checking out branch: ', branch) ui.notifications.message('Checking out branch: ', branch)
return self.update(sickbeard.PID) return self.update(sickbeard.PID)
def pullRequestCheckout(self, branch):
pull_request = branch
branch = branch.split(':')[1]
fetched = sickbeard.versionCheckScheduler.action.fetch(pull_request)
if fetched:
sickbeard.BRANCH = branch
ui.notifications.message('Checking out branch: ', branch)
return self.update(sickbeard.PID)
else:
return redirect('/home/')
def displayShow(self, show=None): def displayShow(self, show=None):
if show is None: if show is None:

View file

@ -3,12 +3,14 @@ import unittest
import test_lib as test import test_lib as test
import sys, os.path import sys, os.path
sys.path.append(os.path.abspath('..')) sys.path.append(os.path.abspath('..'))
sys.path.append(os.path.abspath('../lib')) sys.path.append(os.path.abspath('../lib'))
from sickbeard.name_parser import parser from sickbeard.name_parser import parser
import sickbeard import sickbeard
sickbeard.SYS_ENCODING = 'UTF-8' sickbeard.SYS_ENCODING = 'UTF-8'
DEBUG = VERBOSE = False DEBUG = VERBOSE = False
@ -66,7 +68,7 @@ simple_test_cases = {
'show.name.2010.222.123.source.quality.etc-group': parser.ParseResult(None, 'show name 2010.222', 1, [23], 'source.quality.etc', 'group'), 'show.name.2010.222.123.source.quality.etc-group': parser.ParseResult(None, 'show name 2010.222', 1, [23], 'source.quality.etc', 'group'),
'Show.Name.102': parser.ParseResult(None, 'Show Name', 1, [2]), 'Show.Name.102': parser.ParseResult(None, 'Show Name', 1, [2]),
'the.event.401.hdtv-lol': parser.ParseResult(None, 'the event', 4, [1], 'hdtv', 'lol'), 'the.event.401.hdtv-lol': parser.ParseResult(None, 'the event', 4, [1], 'hdtv', 'lol'),
'show.name.2010.special.hdtv-blah': None, # 'show.name.2010.special.hdtv-blah': None,
}, },
'stupid': { 'stupid': {
@ -110,6 +112,86 @@ simple_test_cases = {
'2010-11-23 - Ep Name': parser.ParseResult(None, extra_info='Ep Name', air_date=datetime.date(2010, 11, 23)), '2010-11-23 - Ep Name': parser.ParseResult(None, extra_info='Ep Name', air_date=datetime.date(2010, 11, 23)),
'Show.Name.2010.11.23.WEB-DL': parser.ParseResult(None, 'Show Name', None, [], 'WEB-DL', None, datetime.date(2010, 11, 23)), 'Show.Name.2010.11.23.WEB-DL': parser.ParseResult(None, 'Show Name', None, [], 'WEB-DL', None, datetime.date(2010, 11, 23)),
}, },
'anime_ultimate': {
'[Tsuki] Bleach - 301 [1280x720][61D1D4EE]': parser.ParseResult(None, 'Bleach', None, [], '1280x720', 'Tsuki', None, [301]),
'[Tsuki] Fairy Tail - 70 [1280x720][C4807111]': parser.ParseResult(None, 'Fairy Tail', None, [], '1280x720', 'Tsuki', None, [70]),
'[SGKK] Bleach 312v2 [720p MKV]': parser.ParseResult(None, 'Bleach', None, [], '720p MKV', 'SGKK', None, [312]),
'[BSS-Anon] Tengen Toppa Gurren Lagann - 22-23 [1280x720][h264][6039D9AF]': parser.ParseResult(None, 'Tengen Toppa Gurren Lagann', None, [], '1280x720', 'BSS-Anon', None, [22, 23]),
'[SJSUBS]_Naruto_Shippuden_-_02_[480p AAC]': parser.ParseResult(None, 'Naruto Shippuden', None, [], '480p AAC', 'SJSUBS', None, [2]),
'[SFW-Chihiro] Dance in the Vampire Bund - 12 [1920x1080 Blu-ray FLAC][2F6DBC66].mkv': parser.ParseResult(None, 'Dance in the Vampire Bund', None, [], '1920x1080 Blu-ray FLAC', 'SFW-Chihiro', None, [12]),
'[SHiN-gx] Hanasaku Iroha - 01 [1280x720 h.264 AAC][BDC36683]': parser.ParseResult(None, 'Hanasaku Iroha', None, [], '1280x720 h.264 AAC', 'SHiN-gx', None, [1]),
'[SFW-Chihiro] Dance in the Vampire Bund - 02 [1920x1080 Blu-ray FLAC][C1FA0A09]': parser.ParseResult(None, 'Dance in the Vampire Bund', None, [], '1920x1080 Blu-ray FLAC', 'SFW-Chihiro', None, [2]),
'[HorribleSubs] No. 6 - 11 [720p]': parser.ParseResult(None, 'No. 6', None, [], '720p', 'HorribleSubs', None, [11]),
'[HorribleSubs] D Gray-Man - 312 (480p) [F501C9BE]': parser.ParseResult(None, 'D Gray-Man', None, [], '480p', 'HorribleSubs', None, [312]),
'[SGKK] Tengen Toppa Gurren Lagann - 45-46 (720p h264) [F501C9BE]': parser.ParseResult(None, 'Tengen Toppa Gurren Lagann', None, [], '720p h264', 'SGKK', None, [45, 46]),
'[Stratos-Subs]_Infinite_Stratos_-_12_(1280x720_H.264_AAC)_[379759DB]': parser.ParseResult(None, 'Infinite Stratos', None, [], '1280x720_H.264_AAC', 'Stratos-Subs', None, [12]),
'[ShinBunBu-Subs] Bleach - 02-03 (CX 1280x720 x264 AAC)': parser.ParseResult(None, 'Bleach', None, [], 'CX 1280x720 x264 AAC', 'ShinBunBu-Subs', None, [02, 03]),
'[Doki] Hanasaku Iroha - 03 (848x480 h264 AAC) [CB1AA73B]': parser.ParseResult(None, 'Hanasaku Iroha', None, [], '848x480 h264 AAC', 'Doki', None, [03]),
'[UTW]_Fractal_-_01_[h264-720p][96D3F1BF]': parser.ParseResult(None, 'Fractal', None, [], 'h264-720p', 'UTW', None, [1]),
'[a-s]_inuyasha_-_028_rs2_[BFDDF9F2]': parser.ParseResult(None, 'inuyasha', None, [], 'BFDDF9F2', 'a-s', None, [28]),
'[HorribleSubs] Fairy Tail S2 - 37 [1080p]': parser.ParseResult(None,'Fairy Tail S2', None, [], '1080p', 'HorribleSubs', None, [37]),
'[HorribleSubs] Sword Art Online II - 23 [720p]': parser.ParseResult(None, 'Sword Art Online II', None, [], '720p', 'HorribleSubs', None, [23])
},
'anime_ep_name': {
'[TzaTziki]_One_Piece_279_Chopper_Man_1_[720p][8AE5F25D]': parser.ParseResult(None, 'One Piece', None, [], '720p', 'TzaTziki', None, [279]),
"[ACX]Wolf's_Rain_-_04_-_Scars_in_the_Wasteland_[octavarium]_[82B7E357]": parser.ParseResult(None, "Wolf's Rain", None, [], 'octavarium', 'ACX', None, [4]),
'[ACX]Black Lagoon - 02v2 - Mangrove Heaven [SaintDeath] [7481F875]': parser.ParseResult(None, 'Black Lagoon', None, [], 'SaintDeath', 'ACX', None, [2]),
},
"anime_standard_round": {
'[SGKK] Bleach - 312v2 (1280x720 h264 AAC) [F501C9BE]': parser.ParseResult(None, 'Bleach', None, [], '1280x720 h264 AAC', 'SGKK', None, [312]),
},
'anime_slash': {
'[SGKK] Bleach 312v1 [720p/MKV]': parser.ParseResult(None, 'Bleach', None, [], '720p', 'SGKK', None, [312]),
'[SGKK] Bleach 312 [480p/MKV]': parser.ParseResult(None, 'Bleach', None, [], '480p', 'SGKK', None, [312])
},
'anime_standard_codec': {
'[Ayako]_Infinite_Stratos_-_IS_-_07_[H264][720p][EB7838FC]': parser.ParseResult(None, 'Infinite Stratos', None, [], '720p', 'Ayako', None, [7]),
'[Ayako] Infinite Stratos - IS - 07v2 [H264][720p][44419534]': parser.ParseResult(None, 'Infinite Stratos', None, [], '720p', 'Ayako', None, [7]),
'[Ayako-Shikkaku] Oniichan no Koto Nanka Zenzen Suki Janain Dakara ne - 10 [LQ][h264][720p] [8853B21C]': parser.ParseResult(None, 'Oniichan no Koto Nanka Zenzen Suki Janain Dakara ne', None, [], '720p', 'Ayako-Shikkaku', None, [10]),
'[Tsuki] Fairy Tail - 72 [XviD][C4807111]': parser.ParseResult(None, 'Fairy Tail', None, [], 'C4807111', 'Tsuki', None, [72]),
'Bubblegum Crisis Tokyo 2040 - 25 [aX] [F4E2E558]': parser.ParseResult(None, 'Bubblegum Crisis Tokyo 2040', None, [], "aX", None, None, [25]),
},
'anime_and_normal': {
'Bleach - s02e03 - 012 - Name & Name': parser.ParseResult(None, 'Bleach', 2, [3], None, None, None, [12]),
'Bleach - s02e03e04 - 012-013 - Name & Name': parser.ParseResult(None, 'Bleach', 2, [3, 4], None, None, None, [12, 13]),
'Bleach - s16e03-04 - 313-314': parser.ParseResult(None, 'Bleach', 16, [3, 4], None, None, None, [313, 314]),
'Blue Submarine No. 6 s16e03e04 313-314': parser.ParseResult(None, 'Blue Submarine No. 6', 16, [3, 4], None, None, None, [313, 314]),
'Bleach.s16e03-04.313-314': parser.ParseResult(None, 'Bleach', 16, [3, 4], None, None, None, [313, 314]),
'.hack roots s01e01 001.mkv': parser.ParseResult(None, 'hack roots', 1, [1], None, None, None, [1]),
'.hack sign s01e01 001.mkv': parser.ParseResult(None, 'hack sign', 1, [1], None, None, None, [1])
},
'anime_and_normal_reverse': {
'Bleach - 012 - s02e03 - Name & Name': parser.ParseResult(None, 'Bleach', 2, [3], None, None, None, [12]),
'Blue Submarine No. 6 - 012-013 - s02e03e04 - Name & Name': parser.ParseResult(None, 'Blue Submarine No. 6', 2, [3, 4], None, None, None, [12, 13]),
'07-GHOST - 012-013 - s02e03e04 - Name & Name': parser.ParseResult(None, '07-GHOST', 2, [3, 4], None, None, None, [12, 13]),
'3x3 Eyes - 012-013 - s02e03-04 - Name & Name': parser.ParseResult(None, '3x3 Eyes', 2, [3, 4], None, None, None, [12, 13]),
},
'anime_and_normal_front': {
'165.Naruto Shippuuden.s08e014': parser.ParseResult(None, 'Naruto Shippuuden', 8, [14], None, None, None, [165]),
'165-166.Naruto Shippuuden.s08e014e015': parser.ParseResult(None, 'Naruto Shippuuden', 8, [14, 15], None, None, None, [165, 166]),
'165-166.07-GHOST.s08e014-015': parser.ParseResult(None, '07-GHOST', 8, [14, 15], None, None, None, [165, 166]),
'165-166.3x3 Eyes.S08E014E015': parser.ParseResult(None, '3x3 Eyes', 8, [14, 15], None, None, None, [165, 166]),
},
'anime_bare': {
'One Piece 102': parser.ParseResult(None, 'One Piece', None, [], None, None, None, [102]),
'bleach - 010': parser.ParseResult(None, 'bleach', None, [], None, None, None, [10]),
'Naruto Shippuden - 314v2': parser.ParseResult(None, 'Naruto Shippuden', None, [], None, None, None, [314]),
'Blue Submarine No. 6 104-105': parser.ParseResult(None, 'Blue Submarine No. 6', None, [], None, None, None, [104, 105]),
'Samurai X: Trust & Betrayal (OVA) 001-002': parser.ParseResult(None, 'Samurai X: Trust & Betrayal (OVA)', None, [], None, None, None, [1, 2]),
"[ACX]_Wolf's_Spirit_001.mkv": parser.ParseResult(None, "Wolf's Spirit", None, [], None, 'ACX', None, [1])
}
} }
combination_test_cases = [ combination_test_cases = [
@ -159,7 +241,6 @@ failure_cases = ['7sins-jfcs01e09-720p-bluray-x264']
class UnicodeTests(test.SickbeardTestDBCase): class UnicodeTests(test.SickbeardTestDBCase):
def _test_unicode(self, name, result): def _test_unicode(self, name, result):
np = parser.NameParser(True) np = parser.NameParser(True)
@ -175,8 +256,8 @@ class UnicodeTests(test.SickbeardTestDBCase):
for (name, result) in unicode_test_cases: for (name, result) in unicode_test_cases:
self._test_unicode(name, result) self._test_unicode(name, result)
class FailureCaseTests(test.SickbeardTestDBCase):
class FailureCaseTests(test.SickbeardTestDBCase):
def _test_name(self, name): def _test_name(self, name):
np = parser.NameParser(True) np = parser.NameParser(True)
try: try:
@ -192,8 +273,8 @@ class FailureCaseTests(test.SickbeardTestDBCase):
for name in failure_cases: for name in failure_cases:
self.assertTrue(self._test_name(name)) self.assertTrue(self._test_name(name))
class ComboTests(test.SickbeardTestDBCase):
class ComboTests(test.SickbeardTestDBCase):
def _test_combo(self, name, result, which_regexes): def _test_combo(self, name, result, which_regexes):
if VERBOSE: if VERBOSE:
@ -211,7 +292,6 @@ class ComboTests(test.SickbeardTestDBCase):
print test_result, test_result.which_regex print test_result, test_result.which_regex
print result, which_regexes print result, which_regexes
self.assertEqual(test_result, result) self.assertEqual(test_result, result)
for cur_regex in which_regexes: for cur_regex in which_regexes:
self.assertTrue(cur_regex in test_result.which_regex) self.assertTrue(cur_regex in test_result.which_regex)
@ -224,8 +304,8 @@ class ComboTests(test.SickbeardTestDBCase):
# paths when test is run on Windows. # paths when test is run on Windows.
self._test_combo(os.path.normpath(name), result, which_regexes) self._test_combo(os.path.normpath(name), result, which_regexes)
class BasicTests(test.SickbeardTestDBCase):
class BasicTests(test.SickbeardTestDBCase):
def _test_names(self, np, section, transform=None, verbose=False): def _test_names(self, np, section, transform=None, verbose=False):
if VERBOSE or verbose: if VERBOSE or verbose:
@ -246,105 +326,146 @@ class BasicTests(test.SickbeardTestDBCase):
else: else:
test_result = np.parse(cur_test) test_result = np.parse(cur_test)
if DEBUG or verbose: try:
# self.assertEqual(test_result.which_regex, [section])
self.assertEqual(test_result, result)
except:
print 'air_by_date:', test_result.is_air_by_date, 'air_date:', test_result.air_date print 'air_by_date:', test_result.is_air_by_date, 'air_date:', test_result.air_date
print 'anime:', test_result.is_anime, 'ab_episode_numbers:', test_result.ab_episode_numbers print 'anime:', test_result.is_anime, 'ab_episode_numbers:', test_result.ab_episode_numbers
print test_result print test_result
print result print result
self.assertEqual(test_result.which_regex, [section]) raise
self.assertEqual(test_result, result)
#def test_standard_names(self):
# np = parser.NameParser(False) def test_standard_names(self):
# self._test_names(np, 'standard') np = parser.NameParser(False, testing=True)
# self._test_names(np, 'standard')
#def test_standard_repeat_names(self):
# np = parser.NameParser(False) def test_standard_repeat_names(self):
# self._test_names(np, 'standard_repeat') np = parser.NameParser(False, testing=True)
# self._test_names(np, 'standard_repeat')
#def test_fov_names(self):
# np = parser.NameParser(False) def test_fov_names(self):
# self._test_names(np, 'fov') np = parser.NameParser(False, testing=True)
# self._test_names(np, 'fov')
#def test_fov_repeat_names(self):
# np = parser.NameParser(False) def test_fov_repeat_names(self):
# self._test_names(np, 'fov_repeat') np = parser.NameParser(False, testing=True)
# self._test_names(np, 'fov_repeat')
#def test_bare_names(self):
# np = parser.NameParser(False) def test_bare_names(self):
# self._test_names(np, 'bare') np = parser.NameParser(False, testing=True)
# self._test_names(np, 'bare')
#def test_stupid_names(self):
# np = parser.NameParser(False) def test_stupid_names(self):
# self._test_names(np, 'stupid') np = parser.NameParser(False, testing=True)
# self._test_names(np, 'stupid')
#def test_no_season_names(self):
# np = parser.NameParser(False) def test_no_season_names(self):
# self._test_names(np, 'no_season') np = parser.NameParser(False, testing=True)
# self._test_names(np, 'no_season')
#def test_no_season_general_names(self):
# np = parser.NameParser(False) def test_no_season_general_names(self):
# self._test_names(np, 'no_season_general') np = parser.NameParser(False, testing=True)
# self._test_names(np, 'no_season_general')
#def test_no_season_multi_ep_names(self):
# np = parser.NameParser(False) def test_no_season_multi_ep_names(self):
# self._test_names(np, 'no_season_multi_ep') np = parser.NameParser(False, testing=True)
# self._test_names(np, 'no_season_multi_ep')
#def test_season_only_names(self):
# np = parser.NameParser(False) def test_season_only_names(self):
# self._test_names(np, 'season_only') np = parser.NameParser(False, testing=True)
# self._test_names(np, 'season_only')
#def test_scene_date_format_names(self):
# np = parser.NameParser(False) def test_scene_date_format_names(self):
# self._test_names(np, 'scene_date_format') np = parser.NameParser(False, testing=True)
# self._test_names(np, 'scene_date_format')
#def test_standard_file_names(self):
# np = parser.NameParser() def test_standard_file_names(self):
# self._test_names(np, 'standard', lambda x: x + '.avi') np = parser.NameParser(testing=True)
# self._test_names(np, 'standard', lambda x: x + '.avi')
#def test_standard_repeat_file_names(self):
# np = parser.NameParser() def test_standard_repeat_file_names(self):
# self._test_names(np, 'standard_repeat', lambda x: x + '.avi') np = parser.NameParser(testing=True)
# self._test_names(np, 'standard_repeat', lambda x: x + '.avi')
#def test_fov_file_names(self):
# np = parser.NameParser() def test_fov_file_names(self):
# self._test_names(np, 'fov', lambda x: x + '.avi') np = parser.NameParser(testing=True)
# self._test_names(np, 'fov', lambda x: x + '.avi')
#def test_fov_repeat_file_names(self):
# np = parser.NameParser() def test_fov_repeat_file_names(self):
# self._test_names(np, 'fov_repeat', lambda x: x + '.avi') np = parser.NameParser(testing=True)
# self._test_names(np, 'fov_repeat', lambda x: x + '.avi')
#def test_bare_file_names(self):
# np = parser.NameParser() def test_bare_file_names(self):
# self._test_names(np, 'bare', lambda x: x + '.avi') np = parser.NameParser(testing=True)
# self._test_names(np, 'bare', lambda x: x + '.avi')
#def test_stupid_file_names(self):
# np = parser.NameParser() def test_stupid_file_names(self):
# self._test_names(np, 'stupid', lambda x: x + '.avi') np = parser.NameParser(testing=True)
# self._test_names(np, 'stupid', lambda x: x + '.avi')
#def test_no_season_file_names(self):
# np = parser.NameParser() def test_no_season_file_names(self):
# self._test_names(np, 'no_season', lambda x: x + '.avi') np = parser.NameParser(testing=True)
# self._test_names(np, 'no_season', lambda x: x + '.avi')
#def test_no_season_general_file_names(self):
# np = parser.NameParser() def test_no_season_general_file_names(self):
# self._test_names(np, 'no_season_general', lambda x: x + '.avi') np = parser.NameParser(testing=True)
# self._test_names(np, 'no_season_general', lambda x: x + '.avi')
#def test_no_season_multi_ep_file_names(self):
# np = parser.NameParser() def test_no_season_multi_ep_file_names(self):
# self._test_names(np, 'no_season_multi_ep', lambda x: x + '.avi') np = parser.NameParser(testing=True)
# self._test_names(np, 'no_season_multi_ep', lambda x: x + '.avi')
#def test_season_only_file_names(self):
# np = parser.NameParser() def test_season_only_file_names(self):
# self._test_names(np, 'season_only', lambda x: x + '.avi') np = parser.NameParser(testing=True)
# self._test_names(np, 'season_only', lambda x: x + '.avi')
#def test_scene_date_format_file_names(self):
# np = parser.NameParser() def test_scene_date_format_file_names(self):
# self._test_names(np, 'scene_date_format', lambda x: x + '.avi') np = parser.NameParser(testing=True)
self._test_names(np, 'scene_date_format', lambda x: x + '.avi')
def test_combination_names(self): def test_combination_names(self):
pass pass
def test_anime_ultimate(self):
np = parser.NameParser(False, TVShow(is_anime=True), testing=True)
self._test_names(np, 'anime_ultimate')
def test_anime_ep_name(self):
np = parser.NameParser(False, TVShow(is_anime=True), testing=True)
self._test_names(np, 'anime_ep_name')
def test_anime_slash(self):
np = parser.NameParser(False, TVShow(is_anime=True), testing=True)
self._test_names(np, 'anime_slash')
def test_anime_codec(self):
np = parser.NameParser(False, TVShow(is_anime=True), testing=True)
self._test_names(np, 'anime_standard_codec')
def test_anime_and_normal(self):
np = parser.NameParser(False, TVShow(is_anime=True), testing=True)
self._test_names(np, 'anime_and_normal')
def test_anime_and_normal_reverse(self):
np = parser.NameParser(False, TVShow(is_anime=True), testing=True)
self._test_names(np, 'anime_and_normal_reverse')
def test_anime_and_normal_front(self):
np = parser.NameParser(False, TVShow(is_anime=True), testing=True)
self._test_names(np, 'anime_and_normal_front')
def test_anime_bare(self):
np = parser.NameParser(False, TVShow(is_anime=True), testing=True)
self._test_names(np, 'anime_bare')
class TVShow(object):
def __init__(self, is_anime=False):
self.is_anime = is_anime
if __name__ == '__main__': if __name__ == '__main__':
if len(sys.argv) > 1: if len(sys.argv) > 1:
suite = unittest.TestLoader().loadTestsFromName('name_parser_tests.BasicTests.test_' + sys.argv[1]) suite = unittest.TestLoader().loadTestsFromName('name_parser_tests.BasicTests.test_' + sys.argv[1])