mirror of
https://github.com/moparisthebest/SickRage
synced 2024-12-12 11:02:21 -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
@ -28,7 +28,17 @@
|
||||
</a>
|
||||
|
||||
<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">
|
||||
<div class="button"><img src="$sbRoot/images/add-existing32.png" height="32" width="32" alt="Add Existing Shows"/></div>
|
||||
<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){
|
||||
if ($(w).is(':checked')) {
|
||||
if (url.length)
|
||||
url += '&'
|
||||
url += '&';
|
||||
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
|
||||
data = {
|
||||
'indexer_id': ep_obj.show.indexerid,
|
||||
'tvdb_id': ep_obj.show.indexerid,
|
||||
'title': ep_obj.show.name,
|
||||
'year': ep_obj.show.startyear,
|
||||
'episodes': [{
|
||||
@ -60,6 +60,26 @@ class TraktNotifier:
|
||||
if sickbeard.TRAKT_REMOVE_WATCHLIST:
|
||||
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):
|
||||
"""
|
||||
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
|
||||
import tornado
|
||||
from trakt import TraktCall
|
||||
|
||||
try:
|
||||
import json
|
||||
@ -1046,9 +1047,11 @@ class Manage(MainHandler):
|
||||
|
||||
exceptions_list = []
|
||||
|
||||
curErrors += Home(self.application, self.request).editShow(curShow, new_show_dir, anyQualities, bestQualities, exceptions_list,
|
||||
new_flatten_folders, new_paused, subtitles=new_subtitles, anime=new_anime,
|
||||
scene=new_scene, directCall=True)
|
||||
curErrors += Home(self.application, self.request).editShow(curShow, new_show_dir, anyQualities,
|
||||
bestQualities, exceptions_list,
|
||||
new_flatten_folders, new_paused,
|
||||
subtitles=new_subtitles, anime=new_anime,
|
||||
scene=new_scene, directCall=True)
|
||||
|
||||
if curErrors:
|
||||
logger.log(u"Errors: " + str(curErrors), logger.ERROR)
|
||||
@ -1612,7 +1615,8 @@ class ConfigPostProcessing(MainHandler):
|
||||
wdtv_data=None, tivo_data=None, mede8er_data=None,
|
||||
keep_processed_dir=None, process_method=None, process_automatically=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,
|
||||
delete_failed=None, extra_scripts=None, skip_removed_files=None,
|
||||
naming_custom_sports=None, naming_sports_pattern=None, autopostprocesser_frequency=None):
|
||||
@ -2719,6 +2723,57 @@ class NewHomeAddShows(MainHandler):
|
||||
|
||||
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):
|
||||
"""
|
||||
@ -3004,7 +3059,8 @@ class Home(MainHandler):
|
||||
self.set_header('Access-Control-Allow-Headers', 'x-requested-with')
|
||||
|
||||
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:
|
||||
return callback + '(' + json.dumps({"msg": "nope", "restarted": str(sickbeard.restarted)}) + ');'
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user