mirror of
https://github.com/moparisthebest/SickRage
synced 2024-12-12 19:12:26 -05:00
Added feature that gets all recommended shows from your trakt.tv account and lets you add the show like you would if adding a new show and searching.
This commit is contained in:
parent
301f124cbb
commit
df7aa364aa
@ -29,6 +29,16 @@
|
|||||||
|
|
||||||
<br/><br/>
|
<br/><br/>
|
||||||
|
|
||||||
|
<a href="$sbRoot/home/addShows/recommendedShows/" id="btnNewShow" class="btn btn-large">
|
||||||
|
<div class="button"><img src="$sbRoot/images/add-new32.png" height="32" width="32" alt="Add Recommended Shows"/></div>
|
||||||
|
<div class="buttontext">
|
||||||
|
<h2>Add Recommended Shows</h2>
|
||||||
|
<p>For shows that you haven't downloaded yet, this option recommends shows to add based on your Trakt.tv watch list, creates a directory for its episodes, and adds it to SickRage. *** Trakt.tv must be enabled ***</p>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<br/><br/>
|
||||||
|
|
||||||
<a href="$sbRoot/home/addShows/existingShows/" id="btnExistingShow" class="btn btn-large">
|
<a href="$sbRoot/home/addShows/existingShows/" id="btnExistingShow" class="btn btn-large">
|
||||||
<div class="button"><img src="$sbRoot/images/add-existing32.png" height="32" width="32" alt="Add Existing Shows"/></div>
|
<div class="button"><img src="$sbRoot/images/add-existing32.png" height="32" width="32" alt="Add Existing Shows"/></div>
|
||||||
<div class="buttontext">
|
<div class="buttontext">
|
||||||
|
64
gui/slick/interfaces/default/home_recommendedShows.tmpl
Normal file
64
gui/slick/interfaces/default/home_recommendedShows.tmpl
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#import os.path
|
||||||
|
#import json
|
||||||
|
#import sickbeard
|
||||||
|
#set global $header="Recommended Shows"
|
||||||
|
#set global $title="Recommended Shows"
|
||||||
|
|
||||||
|
#set global $sbPath="../.."
|
||||||
|
|
||||||
|
#set global $statpath="../.."#
|
||||||
|
#set global $topmenu="home"#
|
||||||
|
#import os.path
|
||||||
|
|
||||||
|
#include $os.path.join($sickbeard.PROG_DIR, "gui/slick/interfaces/default/inc_top.tmpl")
|
||||||
|
|
||||||
|
<link rel="stylesheet" type="text/css" href="$sbRoot/css/formwizard.css?$sbPID" />
|
||||||
|
<script type="text/javascript" src="$sbRoot/js/formwizard.js?$sbPID"></script>
|
||||||
|
<script type="text/javascript" src="$sbRoot/js/qualityChooser.js?$sbPID"></script>
|
||||||
|
<script type="text/javascript" src="$sbRoot/js/recommendedShows.js?$sbPID"></script>
|
||||||
|
<script type="text/javascript" src="$sbRoot/js/addShowOptions.js?$sbPID"></script>
|
||||||
|
|
||||||
|
#if $varExists('header')
|
||||||
|
<h1 class="header">$header</h1>
|
||||||
|
#else
|
||||||
|
<h1 class="title">$title</h1>
|
||||||
|
#end if
|
||||||
|
|
||||||
|
<div id="displayText"></div>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<form id="recommendedShowsForm" method="post" action="$sbRoot/home/addShows/addRecommendedShow" accept-charset="utf-8">
|
||||||
|
<fieldset class="sectionwrap">
|
||||||
|
<legend class="legendStep">Select a recommended show</legend>
|
||||||
|
|
||||||
|
<div class="stepDiv">
|
||||||
|
<div id="searchResults" style="height: 225px; overflow: auto;"><br/></div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset class="sectionwrap">
|
||||||
|
<legend class="legendStep">Pick the parent folder</legend>
|
||||||
|
|
||||||
|
<div class="stepDiv">
|
||||||
|
#include $os.path.join($sickbeard.PROG_DIR, "gui/slick/interfaces/default/inc_rootDirs.tmpl")
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset class="sectionwrap">
|
||||||
|
<legend class="legendStep">Customize options</legend>
|
||||||
|
|
||||||
|
<div class="stepDiv">
|
||||||
|
#include $os.path.join($sickbeard.PROG_DIR, "gui/slick/interfaces/default/inc_addShowOptions.tmpl")
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<div style="width: 800px; text-align:">
|
||||||
|
<input class="btn" type="button" id="addShowButton" value="Add Show" disabled="disabled" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="$sbRoot/js/rootDirs.js?$sbPID"></script>
|
||||||
|
|
||||||
|
#include $os.path.join($sickbeard.PROG_DIR,"gui/slick/interfaces/default/inc_bottom.tmpl")
|
@ -37,7 +37,7 @@ $(document).ready(function() {
|
|||||||
$('.dir_check').each(function(i,w){
|
$('.dir_check').each(function(i,w){
|
||||||
if ($(w).is(':checked')) {
|
if ($(w).is(':checked')) {
|
||||||
if (url.length)
|
if (url.length)
|
||||||
url += '&'
|
url += '&';
|
||||||
url += 'rootDir=' + encodeURIComponent($(w).attr('id'));
|
url += 'rootDir=' + encodeURIComponent($(w).attr('id'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
144
gui/slick/js/recommendedShows.js
Normal file
144
gui/slick/js/recommendedShows.js
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
$(document).ready(function () {
|
||||||
|
function getRecommendedShows() {
|
||||||
|
$.getJSON(sbRoot + '/home/addShows/getRecommendedShows', {}, function (data) {
|
||||||
|
var firstResult = true;
|
||||||
|
var resultStr = '<fieldset>\n<legend>Recommended Shows:</legend>\n';
|
||||||
|
var checked = '';
|
||||||
|
|
||||||
|
if (data.results.length === 0) {
|
||||||
|
resultStr += '<b>No recommended shows found, update your watched shows list on trakt.tv.</b>';
|
||||||
|
} else {
|
||||||
|
$.each(data.results, function (index, obj) {
|
||||||
|
if (firstResult) {
|
||||||
|
checked = ' checked';
|
||||||
|
firstResult = false;
|
||||||
|
} else {
|
||||||
|
checked = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
var whichSeries = obj.join('|');
|
||||||
|
|
||||||
|
resultStr += '<input type="radio" id="whichSeries" name="whichSeries" value="' + whichSeries + '"' + checked + ' /> ';
|
||||||
|
resultStr += '<a href="' + obj[1] + '" onclick=\"window.open(this.href, \'_blank\'); return false;\" ><b>' + obj[2] + '</b></a>';
|
||||||
|
|
||||||
|
if (obj[4] !== null) {
|
||||||
|
var startDate = new Date(obj[4]);
|
||||||
|
var today = new Date();
|
||||||
|
if (startDate > today) {
|
||||||
|
resultStr += ' (will debut on ' + obj[4] + ')';
|
||||||
|
} else {
|
||||||
|
resultStr += ' (started on ' + obj[4] + ')';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj[0] !== null) {
|
||||||
|
resultStr += ' [' + obj[0] + ']';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj[3] !== null) {
|
||||||
|
resultStr += '<br />' + obj[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
resultStr += '<p /><br />';
|
||||||
|
});
|
||||||
|
resultStr += '</ul>';
|
||||||
|
}
|
||||||
|
resultStr += '</fieldset>';
|
||||||
|
$('#searchResults').html(resultStr);
|
||||||
|
updateSampleText();
|
||||||
|
myform.loadsection(0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#addShowButton').click(function () {
|
||||||
|
// if they haven't picked a show don't let them submit
|
||||||
|
if (!$("input:radio[name='whichSeries']:checked").val() && !$("input:hidden[name='whichSeries']").val().length) {
|
||||||
|
alert('You must choose a show to continue');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#recommendedShowsForm').submit();
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#qualityPreset').change(function () {
|
||||||
|
myform.loadsection(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
var myform = new formtowizard({
|
||||||
|
formid: 'recommendedShowsForm',
|
||||||
|
revealfx: ['slide', 500],
|
||||||
|
oninit: function () {
|
||||||
|
getRecommendedShows();
|
||||||
|
updateSampleText();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function goToStep(num) {
|
||||||
|
$('.step').each(function () {
|
||||||
|
if ($.data(this, 'section') + 1 == num) {
|
||||||
|
$(this).click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateSampleText() {
|
||||||
|
// if something's selected then we have some behavior to figure out
|
||||||
|
|
||||||
|
var show_name, sep_char;
|
||||||
|
// if they've picked a radio button then use that
|
||||||
|
if ($('input:radio[name=whichSeries]:checked').length) {
|
||||||
|
show_name = $('input:radio[name=whichSeries]:checked').val().split('|')[2];
|
||||||
|
} else {
|
||||||
|
show_name = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
var sample_text = 'Adding show <b>' + show_name + '</b> into <b>';
|
||||||
|
|
||||||
|
// if we have a root dir selected, figure out the path
|
||||||
|
if ($("#rootDirs option:selected").length) {
|
||||||
|
var root_dir_text = $('#rootDirs option:selected').val();
|
||||||
|
if (root_dir_text.indexOf('/') >= 0) {
|
||||||
|
sep_char = '/';
|
||||||
|
} else if (root_dir_text.indexOf('\\') >= 0) {
|
||||||
|
sep_char = '\\';
|
||||||
|
} else {
|
||||||
|
sep_char = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (root_dir_text.substr(sample_text.length - 1) != sep_char) {
|
||||||
|
root_dir_text += sep_char;
|
||||||
|
}
|
||||||
|
root_dir_text += '<i>||</i>' + sep_char;
|
||||||
|
|
||||||
|
sample_text += root_dir_text;
|
||||||
|
} else if ($('#fullShowPath').length && $('#fullShowPath').val().length) {
|
||||||
|
sample_text += $('#fullShowPath').val();
|
||||||
|
} else {
|
||||||
|
sample_text += 'unknown dir.';
|
||||||
|
}
|
||||||
|
|
||||||
|
sample_text += '</b>';
|
||||||
|
|
||||||
|
// if we have a show name then sanitize and use it for the dir name
|
||||||
|
if (show_name.length) {
|
||||||
|
$.get(sbRoot + '/home/addShows/sanitizeFileName', {name: show_name}, function (data) {
|
||||||
|
$('#displayText').html(sample_text.replace('||', data));
|
||||||
|
});
|
||||||
|
// if not then it's unknown
|
||||||
|
} else {
|
||||||
|
$('#displayText').html(sample_text.replace('||', '??'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// also toggle the add show button
|
||||||
|
if (($("#rootDirs option:selected").length || ($('#fullShowPath').length && $('#fullShowPath').val().length)) &&
|
||||||
|
($('input:radio[name=whichSeries]:checked').length)) {
|
||||||
|
$('#addShowButton').attr('disabled', false);
|
||||||
|
} else {
|
||||||
|
$('#addShowButton').attr('disabled', true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#rootDirText').change(updateSampleText);
|
||||||
|
$('#whichSeries').live('change', updateSampleText);
|
||||||
|
|
||||||
|
});
|
@ -46,7 +46,7 @@ class TraktNotifier:
|
|||||||
|
|
||||||
# URL parameters
|
# URL parameters
|
||||||
data = {
|
data = {
|
||||||
'indexer_id': ep_obj.show.indexerid,
|
'tvdb_id': ep_obj.show.indexerid,
|
||||||
'title': ep_obj.show.name,
|
'title': ep_obj.show.name,
|
||||||
'year': ep_obj.show.startyear,
|
'year': ep_obj.show.startyear,
|
||||||
'episodes': [{
|
'episodes': [{
|
||||||
@ -60,6 +60,26 @@ class TraktNotifier:
|
|||||||
if sickbeard.TRAKT_REMOVE_WATCHLIST:
|
if sickbeard.TRAKT_REMOVE_WATCHLIST:
|
||||||
TraktCall("show/episode/unwatchlist/%API%", self._api(), self._username(), self._password(), data)
|
TraktCall("show/episode/unwatchlist/%API%", self._api(), self._username(), self._password(), data)
|
||||||
|
|
||||||
|
|
||||||
|
def update_show_library(self, show_obj):
|
||||||
|
"""
|
||||||
|
Sends a request to trakt indicating that the given show and all its episodes is part of our library.
|
||||||
|
|
||||||
|
show_obj: The TVShow object to add to trakt
|
||||||
|
"""
|
||||||
|
|
||||||
|
if sickbeard.USE_TRAKT:
|
||||||
|
|
||||||
|
# URL parameters
|
||||||
|
data = {
|
||||||
|
'tvdb_id': show_obj.indexerid,
|
||||||
|
'title': show_obj.name,
|
||||||
|
'year': show_obj.startyear,
|
||||||
|
}
|
||||||
|
|
||||||
|
if data is not None:
|
||||||
|
TraktCall("show/library/%API%", self._api(), self._username(), self._password(), data)
|
||||||
|
|
||||||
def test_notify(self, api, username, password):
|
def test_notify(self, api, username, password):
|
||||||
"""
|
"""
|
||||||
Sends a test notification to trakt with the given authentication info and returns a boolean
|
Sends a test notification to trakt with the given authentication info and returns a boolean
|
||||||
|
@ -65,6 +65,7 @@ from lib.unrar2 import RarFile
|
|||||||
|
|
||||||
from lib import subliminal
|
from lib import subliminal
|
||||||
import tornado
|
import tornado
|
||||||
|
from trakt import TraktCall
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import json
|
import json
|
||||||
@ -1046,8 +1047,10 @@ class Manage(MainHandler):
|
|||||||
|
|
||||||
exceptions_list = []
|
exceptions_list = []
|
||||||
|
|
||||||
curErrors += Home(self.application, self.request).editShow(curShow, new_show_dir, anyQualities, bestQualities, exceptions_list,
|
curErrors += Home(self.application, self.request).editShow(curShow, new_show_dir, anyQualities,
|
||||||
new_flatten_folders, new_paused, subtitles=new_subtitles, anime=new_anime,
|
bestQualities, exceptions_list,
|
||||||
|
new_flatten_folders, new_paused,
|
||||||
|
subtitles=new_subtitles, anime=new_anime,
|
||||||
scene=new_scene, directCall=True)
|
scene=new_scene, directCall=True)
|
||||||
|
|
||||||
if curErrors:
|
if curErrors:
|
||||||
@ -1612,7 +1615,8 @@ class ConfigPostProcessing(MainHandler):
|
|||||||
wdtv_data=None, tivo_data=None, mede8er_data=None,
|
wdtv_data=None, tivo_data=None, mede8er_data=None,
|
||||||
keep_processed_dir=None, process_method=None, process_automatically=None,
|
keep_processed_dir=None, process_method=None, process_automatically=None,
|
||||||
rename_episodes=None, airdate_episodes=None, unpack=None,
|
rename_episodes=None, airdate_episodes=None, unpack=None,
|
||||||
move_associated_files=None, nfo_rename=None, tv_download_dir=None, naming_custom_abd=None, naming_anime=None,
|
move_associated_files=None, nfo_rename=None, tv_download_dir=None, naming_custom_abd=None,
|
||||||
|
naming_anime=None,
|
||||||
naming_abd_pattern=None, naming_strip_year=None, use_failed_downloads=None,
|
naming_abd_pattern=None, naming_strip_year=None, use_failed_downloads=None,
|
||||||
delete_failed=None, extra_scripts=None, skip_removed_files=None,
|
delete_failed=None, extra_scripts=None, skip_removed_files=None,
|
||||||
naming_custom_sports=None, naming_sports_pattern=None, autopostprocesser_frequency=None):
|
naming_custom_sports=None, naming_sports_pattern=None, autopostprocesser_frequency=None):
|
||||||
@ -2719,6 +2723,57 @@ class NewHomeAddShows(MainHandler):
|
|||||||
|
|
||||||
return _munge(t)
|
return _munge(t)
|
||||||
|
|
||||||
|
def recommendedShows(self, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Display the new show page which collects a tvdb id, folder, and extra options and
|
||||||
|
posts them to addNewShow
|
||||||
|
"""
|
||||||
|
t = PageTemplate(file="home_recommendedShows.tmpl")
|
||||||
|
t.submenu = HomeMenu()
|
||||||
|
|
||||||
|
return _munge(t)
|
||||||
|
|
||||||
|
def getRecommendedShows(self, *args, **kwargs):
|
||||||
|
final_results = []
|
||||||
|
|
||||||
|
if sickbeard.USE_TRAKT:
|
||||||
|
for myShow in sickbeard.showList:
|
||||||
|
notifiers.trakt_notifier.update_show_library(myShow)
|
||||||
|
|
||||||
|
logger.log(u"Getting recommended shows from Trakt.tv", logger.DEBUG)
|
||||||
|
recommendedlist = TraktCall("recommendations/shows.json/%API%/" + sickbeard.TRAKT_USERNAME,
|
||||||
|
sickbeard.TRAKT_API,
|
||||||
|
sickbeard.TRAKT_USERNAME, sickbeard.TRAKT_PASSWORD)
|
||||||
|
if recommendedlist is None:
|
||||||
|
logger.log(u"Could not connect to trakt service, aborting recommended list update", logger.ERROR)
|
||||||
|
return
|
||||||
|
|
||||||
|
map(final_results.append, ([int(show['tvdb_id']), show['url'], show['title'], show['overview'],
|
||||||
|
datetime.date.fromtimestamp(show['first_aired']).strftime('%Y%m%d')] for show in
|
||||||
|
recommendedlist if
|
||||||
|
not helpers.findCertainShow(sickbeard.showList, indexerid=int(show['tvdb_id']))))
|
||||||
|
|
||||||
|
return json.dumps({'results': final_results})
|
||||||
|
|
||||||
|
def addRecommendedShow(self, whichSeries=None, indexerLang="en", rootDir=None, defaultStatus=None,
|
||||||
|
anyQualities=None, bestQualities=None, flatten_folders=None, subtitles=None,
|
||||||
|
fullShowPath=None, other_shows=None, skipShow=None, providedIndexer=None, anime=None,
|
||||||
|
scene=None):
|
||||||
|
|
||||||
|
indexer = 1
|
||||||
|
indexer_name = sickbeard.indexerApi(int(indexer)).name
|
||||||
|
show_url = whichSeries.split('|')[1]
|
||||||
|
indexer_id = whichSeries.split('|')[0]
|
||||||
|
show_name = whichSeries.split('|')[2]
|
||||||
|
first_aired = whichSeries.split('|')[4]
|
||||||
|
|
||||||
|
self.addNewShow('|'.join([indexer_name, str(indexer), show_url, indexer_id, show_name, first_aired]),
|
||||||
|
indexerLang, rootDir,
|
||||||
|
defaultStatus,
|
||||||
|
anyQualities, bestQualities, flatten_folders, subtitles, fullShowPath, other_shows,
|
||||||
|
skipShow, providedIndexer, anime, scene)
|
||||||
|
|
||||||
|
return self.redirect('/home/')
|
||||||
|
|
||||||
def existingShows(self, *args, **kwargs):
|
def existingShows(self, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
@ -3004,7 +3059,8 @@ class Home(MainHandler):
|
|||||||
self.set_header('Access-Control-Allow-Headers', 'x-requested-with')
|
self.set_header('Access-Control-Allow-Headers', 'x-requested-with')
|
||||||
|
|
||||||
if sickbeard.started:
|
if sickbeard.started:
|
||||||
return callback + '(' + json.dumps({"msg": str(sickbeard.PID), "restarted": str(sickbeard.restarted)}) + ');'
|
return callback + '(' + json.dumps(
|
||||||
|
{"msg": str(sickbeard.PID), "restarted": str(sickbeard.restarted)}) + ');'
|
||||||
else:
|
else:
|
||||||
return callback + '(' + json.dumps({"msg": "nope", "restarted": str(sickbeard.restarted)}) + ');'
|
return callback + '(' + json.dumps({"msg": "nope", "restarted": str(sickbeard.restarted)}) + ');'
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user