diff --git a/gui/slick/css/trakt.css b/gui/slick/css/trakt.css
new file mode 100644
index 00000000..f2de517f
--- /dev/null
+++ b/gui/slick/css/trakt.css
@@ -0,0 +1,92 @@
+.traktShowDiv {
+
+ clear: both;
+ border-left: 1px solid #CCCCCC;
+ border-right: 1px solid #CCCCCC;
+ border-bottom: 1px solid #CCCCCC;
+ margin: auto;
+ padding: 0px;
+ text-align: left;
+ width: 750px;
+}
+
+.traktShowDiv a, .traktShowDiv a:link, .traktShowDiv a:visited, .traktShowDiv a:hover {
+ text-decoration: none;
+ background: none;
+}
+
+.traktShowTitle a {
+ color: #000000;
+ float: left;
+ padding-top: 3px;
+ line-height: 1.2em;
+ font-size: 1.1em;
+ text-shadow: -1px -1px 0 #FFF);
+}
+
+.traktShowTitleIcons {
+ float: right;
+ padding: 3px 5px;
+}
+
+.traktShowDiv .title {
+ font-weight: 900;
+ color: #333;
+}
+.imgWrapper {
+ background: url("../images/loading.gif") no-repeat scroll center center #FFFFFF;
+ border: 3px solid #FFFFFF;
+ box-shadow: 1px 1px 2px 0 #555555;
+ float: left;
+ height: 50px;
+ overflow: hidden;
+ text-indent: -3000px;
+ width: 50px;
+}
+.imgWrapper .traktPosterThumb {
+ float: left;
+ min-height: 100%;
+ min-width: 100%;
+ width: 50px;
+ height: auto;
+ position: relative;
+ border: none;
+ vertical-align: middle;
+}
+.traktPosterThumb {
+ -ms-interpolation-mode: bicubic; /* make scaling look nicer for ie */
+ vertical-align: top;
+ height: auto;
+ width: 160px;
+ border-top: 1px solid #ccc;
+ border-right: 1px solid #ccc;
+}
+
+.traktShowDiv th {
+ color: #000;
+ letter-spacing: 1px;
+ text-align: left;
+ background-color: #333333;
+}
+
+.traktShowDiv th.nobg {
+ background: #efefef;
+ border-top: 1px solid #666;
+ text-align: center;
+}
+
+.traktShowDiv td {
+ border-top: 1px solid #d2ebe8;
+ background: #fff;
+ padding: 5px 10px 5px 10px;
+ color: #000;
+}
+
+.traktShowDiv td.trakts_show {
+ width: 100%;
+ height: 90%;
+ border-top: 1px solid #ccc;
+ vertical-align: top;
+ background: #F5FAFA;
+ color: #000;
+}
diff --git a/gui/slick/interfaces/default/home_addShows.tmpl b/gui/slick/interfaces/default/home_addShows.tmpl
index 4d28ec81..953ccf96 100644
--- a/gui/slick/interfaces/default/home_addShows.tmpl
+++ b/gui/slick/interfaces/default/home_addShows.tmpl
@@ -26,15 +26,23 @@
For shows that you haven't downloaded yet, this option finds a show on theTVDB.com and TVRage.com, creates a directory for its episodes, and adds it to SickRage.
-
+
+
+
+
+
+
Add Trending Show
+
For shows that you haven't downloaded yet, this option lets you choose from a list of current trending shows with ratings to add, creates a directory for its episodes, and adds it to SickRage.
+
+
#if $sickbeard.TRAKT_USE_RECOMMENDED:
-
Add Recommended Shows
-
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 ***
+
Add Recommended Show
+
For shows that you haven't downloaded yet, this option recommends shows to add based on your Trakt.tv show library, creates a directory for its episodes, and adds it to SickRage. *** Trakt.tv must be enabled ***
diff --git a/gui/slick/interfaces/default/home_trendingShows.tmpl b/gui/slick/interfaces/default/home_trendingShows.tmpl
new file mode 100644
index 00000000..7bbdeb19
--- /dev/null
+++ b/gui/slick/interfaces/default/home_trendingShows.tmpl
@@ -0,0 +1,58 @@
+#import sickbeard
+#import datetime
+#import re
+#from sickbeard.common import *
+#from sickbeard import sbdatetime
+
+#set global $title="Trending Shows"
+#set global $header="Trending Shows"
+
+#set global $sbPath=".."
+
+#set global $topmenu="comingEpisodes"
+#import os.path
+#include $os.path.join($sickbeard.PROG_DIR, "gui/slick/interfaces/default/inc_top.tmpl")
+
+
+
+
+#if $varExists('header')
+
+#else
+ $title
+#end if
+
+
+
+#for $i, $cur_show in $enumerate($trending_shows):
+
+
+#if not $i%4
+
+#end if
+
+
+
+
+
+
$cur_show["ratings"]["percentage"]%
+
$cur_show["ratings"]["votes"] votes
+
+
+
+
+
+
+
+
+#end for
+
+
+
+
+
+#include $os.path.join($sickbeard.PROG_DIR, "gui/slick/interfaces/default/inc_bottom.tmpl")
\ No newline at end of file
diff --git a/lib/trakt/__init__.py b/lib/trakt/__init__.py
index f4cc7f48..c9565a3b 100644
--- a/lib/trakt/__init__.py
+++ b/lib/trakt/__init__.py
@@ -7,7 +7,7 @@ try:
except ImportError:
from lib import simplejson as json
-def TraktCall(method, api, username, password, data = {}):
+def TraktCall(method, api, username=None, password=None, data={}):
"""
A generic method for communicating with trakt. Uses the method and data provided along
with the auth info to send the command.
@@ -26,19 +26,16 @@ def TraktCall(method, api, username, password, data = {}):
return None
# if the username isn't given then it failed
- if not username:
- return None
-
- password = sha1(password).hexdigest()
+ if username and password:
+ password = sha1(password).hexdigest()
+ data["username"] = username
+ data["password"] = password
# replace the API string with what we found
method = method.replace("%API%", api)
- data["username"] = username
- data["password"] = password
-
# take the URL params and make a json object out of them
- encoded_data = json.dumps(data);
+ encoded_data = json.dumps(data)
# request the URL from trakt and parse the result as json
try:
diff --git a/sickbeard/__init__.py b/sickbeard/__init__.py
index 8da92f76..0b774322 100644
--- a/sickbeard/__init__.py
+++ b/sickbeard/__init__.py
@@ -432,7 +432,7 @@ IGNORE_WORDS = "german,french,core2hd,dutch,swedish,reenc,MrLss"
CALENDAR_UNPROTECTED = False
TMDB_API_KEY = 'edc5f123313769de83a71e157758030b'
-
+TRAKT_API_KEY = 'abd806c54516240c76e4ebc9c5ccf394'
__INITIALIZED__ = False
def initialize(consoleLogging=True):
diff --git a/sickbeard/traktChecker.py b/sickbeard/traktChecker.py
index 51d2b7ef..eec11e15 100644
--- a/sickbeard/traktChecker.py
+++ b/sickbeard/traktChecker.py
@@ -147,9 +147,9 @@ class TraktChecker():
"""
Adds a new show with the default settings
"""
- showObj = helpers.findCertainShow(sickbeard.showList, int(indexerid))
- if showObj != None:
+ if helpers.findCertainShow(sickbeard.showList, int(indexerid)):
return
+
logger.log(u"Adding show " + str(indexerid))
root_dirs = sickbeard.ROOT_DIRS.split('|')
location = root_dirs[int(root_dirs[0]) + 1]
@@ -161,6 +161,7 @@ class TraktChecker():
return
else:
helpers.chmodAsParent(showPath)
+
sickbeard.showQueueScheduler.action.addShow(1, int(indexerid), showPath, status,
int(sickbeard.QUALITY_DEFAULT),
int(sickbeard.FLATTEN_FOLDERS_DEFAULT))
diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py
index c55dbdc5..8f8d0ee2 100644
--- a/sickbeard/webserve.py
+++ b/sickbeard/webserve.py
@@ -48,7 +48,7 @@ from sickbeard import subtitles
from sickbeard import network_timezones
from sickbeard.providers import newznab, rsstorrent
-from sickbeard.common import Quality, Overview, statusStrings, qualityPresetStrings, cpu_presets
+from sickbeard.common import Quality, Overview, statusStrings, qualityPresetStrings, cpu_presets, SKIPPED
from sickbeard.common import SNATCHED, UNAIRED, IGNORED, ARCHIVED, WANTED, FAILED
from sickbeard.common import SD, HD720p, HD1080p
from sickbeard.exceptions import ex
@@ -82,6 +82,7 @@ from lib import adba
from Cheetah.Template import Template
from tornado.web import RequestHandler, HTTPError
+
def authenticated(handler_class):
def wrap_execute(handler_execute):
def basicauth(handler, transforms, *args, **kwargs):
@@ -125,6 +126,7 @@ def authenticated(handler_class):
handler_class._execute = wrap_execute(handler_class._execute)
return handler_class
+
class HTTPRedirect(Exception):
"""Exception raised when the request should be redirected."""
@@ -138,9 +140,11 @@ class HTTPRedirect(Exception):
"""Use this exception as a request.handler (raise self)."""
raise self
+
def redirect(url, permanent=False, status=None):
raise HTTPRedirect(url, permanent, status)
+
@authenticated
class MainHandler(RequestHandler):
def http_error_401_handler(self):
@@ -216,7 +220,7 @@ class MainHandler(RequestHandler):
def get(self, *args, **kwargs):
try:
self.finish(self._dispatch())
- except HTTPRedirect,inst:
+ except HTTPRedirect, inst:
self.redirect(inst.url, inst.permanent, inst.status)
def post(self, *args, **kwargs):
@@ -462,6 +466,7 @@ class MainHandler(RequestHandler):
browser = WebFileBrowser
+
class PageTemplate(Template):
def __init__(self, headers, *args, **KWs):
KWs['file'] = os.path.join(sickbeard.PROG_DIR, "gui/" + sickbeard.GUI_NAME + "/interfaces/default/",
@@ -499,7 +504,7 @@ class PageTemplate(Template):
{'title': 'Manage', 'key': 'manage'},
{'title': 'Config', 'key': 'config'},
{'title': logPageTitle, 'key': 'errorlogs'},
- ]
+ ]
class IndexerWebUI(MainHandler):
@@ -518,6 +523,7 @@ class IndexerWebUI(MainHandler):
def _munge(string):
return unicode(string).encode('utf-8', 'xmlcharrefreplace')
+
def _getEpisode(show, season=None, episode=None, absolute=None):
if show is None:
return "Invalid show parameters"
@@ -2643,7 +2649,7 @@ class NewHomeAddShows(MainHandler):
'display_dir': '' + ek.ek(os.path.dirname, cur_path) + os.sep + ' ' + ek.ek(
os.path.basename,
cur_path),
- }
+ }
# see if the folder is in XBMC already
dirResults = myDB.select("SELECT * FROM tv_shows WHERE location = ?", [cur_path])
@@ -2745,10 +2751,10 @@ class NewHomeAddShows(MainHandler):
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']))))
+ map(final_results.append,
+ ([int(show['tvdb_id']), show['url'], show['title'], show['overview'],
+ datetime.date.fromtimestamp(int(show['first_aired']) / 1000.0).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})
@@ -2764,10 +2770,22 @@ class NewHomeAddShows(MainHandler):
show_name = whichSeries.split('|')[2]
return self.addNewShow('|'.join([indexer_name, str(indexer), show_url, indexer_id, show_name, ""]),
- indexerLang, rootDir,
- defaultStatus,
- anyQualities, bestQualities, flatten_folders, subtitles, fullShowPath, other_shows,
- skipShow, providedIndexer, anime, scene)
+ indexerLang, rootDir,
+ defaultStatus,
+ anyQualities, bestQualities, flatten_folders, subtitles, fullShowPath, other_shows,
+ skipShow, providedIndexer, anime, scene)
+
+ def trendingShows(self, *args, **kwargs):
+ """
+ Display the new show page which collects a tvdb id, folder, and extra options and
+ posts them to addNewShow
+ """
+ t = PageTemplate(headers=self.request.headers, file="home_trendingShows.tmpl")
+ t.submenu = HomeMenu()
+
+ t.trending_shows = TraktCall("shows/trending.json/%API%/", sickbeard.TRAKT_API_KEY)
+
+ return _munge(t)
def existingShows(self, *args, **kwargs):
"""
@@ -2778,6 +2796,33 @@ class NewHomeAddShows(MainHandler):
return _munge(t)
+ def addTraktShow(self, indexer_id, showName):
+ if helpers.findCertainShow(sickbeard.showList, int(indexer_id)):
+ return
+
+ root_dirs = sickbeard.ROOT_DIRS.split('|')
+ location = root_dirs[int(root_dirs[0]) + 1]
+
+ show_dir = ek.ek(os.path.join, location, helpers.sanitizeFileName(showName))
+ dir_exists = helpers.makeDir(show_dir)
+ if not dir_exists:
+ logger.log(u"Unable to create the folder " + show_dir + ", can't add the show", logger.ERROR)
+ return
+ else:
+ helpers.chmodAsParent(show_dir)
+
+ sickbeard.showQueueScheduler.action.addShow(1, int(indexer_id), show_dir,
+ default_status=sickbeard.STATUS_DEFAULT,
+ quality=sickbeard.QUALITY_DEFAULT,
+ flatten_folders=sickbeard.FLATTEN_FOLDERS_DEFAULT,
+ subtitles=sickbeard.SUBTITLES_DEFAULT,
+ anime=sickbeard.ANIME_DEFAULT,
+ scene=sickbeard.SCENE_DEFAULT)
+
+ ui.notifications.message('Show added', 'Adding the specified show into ' + show_dir)
+
+ # done adding show
+ redirect('/home/')
def addNewShow(self, whichSeries=None, indexerLang="en", rootDir=None, defaultStatus=None,
anyQualities=None, bestQualities=None, flatten_folders=None, subtitles=None,
@@ -3394,7 +3439,7 @@ class Home(MainHandler):
return _munge(t)
else:
return self._genericMessage("Update Failed",
- "Update wasn't successful, not restarting. Check your log for more information.")
+ "Update wasn't successful, not restarting. Check your log for more information.")
def displayShow(self, show=None):
@@ -3999,7 +4044,6 @@ class Home(MainHandler):
myDB = db.DBConnection()
myDB.mass_action(sql_l)
-
if int(status) == WANTED:
msg = "Backlog was automatically started for the following seasons of " + showObj.name + " : "
for season in segment:
@@ -4294,9 +4338,9 @@ class Home(MainHandler):
return json.dumps({'result': 'failure'})
+
class UI(MainHandler):
def add_message(self):
-
ui.notifications.message('Test 1', 'This is test number 1')
ui.notifications.error('Test 2', 'This is test number 2')
@@ -4307,8 +4351,8 @@ class UI(MainHandler):
cur_notification_num = 1
for cur_notification in ui.notifications.get_notifications(self.request.remote_ip):
messages['notification-' + str(cur_notification_num)] = {'title': cur_notification.title,
- 'message': cur_notification.message,
- 'type': cur_notification.type}
+ 'message': cur_notification.message,
+ 'type': cur_notification.type}
cur_notification_num += 1
return json.dumps(messages)
\ No newline at end of file