Added gui for IMDB watchlists in Config General.

Used regex checks with javascript popup, for checking if valid imdb csv watchlist.
Added test/test_tvdb_api.py for testing the tvdb api for retrieving shows by IMDB id.

TODO: Help for assisting users in getting the correct IMDB url.
maybe, make interval configurable

First changes for imdb watchlist checker

Thrown the couch code overboard and created my own version of an imdb watchlist scraper

Added IMDB thread and test values with an IMDB csv url. These values should be replaced by front end UI settings.

- Removed some tracelogs when unable to download watchlist
- Added settings for enabling and setting of the watchlist csv url
TODO:
- create UI for setting from frontend
- Implement frontend and backend checks for validating the csv url

Default interval is 1 hour.
This commit is contained in:
KontiSR 2014-09-30 12:22:47 +02:00
parent 3e4d105b96
commit 7165df7405
11 changed files with 670 additions and 16 deletions

View File

@ -27,6 +27,7 @@
<script type="text/javascript" src="$sbRoot/js/config.js?$sbPID"></script>
<script type="text/javascript" src="$sbRoot/js/rootDirs.js?$sbPID"></script>
<script type="text/javascript" src="$sbRoot/js/imdbWatchlist.js?$sbPID"></script>
<div id="config">
<div id="config-content">
@ -176,7 +177,26 @@
</label>
</div>
<input type="submit" class="btn config_submitter" value="Save Changes" />
<fieldset class="component-group-list">
<div class="field-pair">
<input type="checkbox" name="use_imdbwl" class="enabler" id="use_imdbwl" #if $sickbeard.USE_IMDBWATCHLIST then "checked=\"checked\"" else ""#/>
<label class="clearfix" for="use_imdbwl">
<span class="component-title">Use IMDB Watchlists</span>
</label>
</div>
<div id="content_use_imdbwl">
<!-- Multiselect for managing IMDB watchlist csv url's -->
<div class="field-pair">
<label class="clearfix">
<span class="">Manage your IMDB watchlist url's. Each url should contain your list id and user id. They look like: ls014134 and us0918234.</span>
#include $os.path.join($sickbeard.PROG_DIR, "gui/slick/interfaces/default/inc_imdbWatchlists.tmpl")
</label>
</div>
</div>
<input type="submit" class="btn config_submitter" value="Save Changes" />
</fieldset>
</fieldset>
</div><!-- /component-group1 //-->

View File

@ -0,0 +1,33 @@
#import sickbeard
<span id="sampleImdbWl"></span>
#if $sickbeard.IMDB_WATCHLISTCSV:
#set $backend_pieces = $sickbeard.IMDB_WATCHLISTCSV.split('|')
#else:
#set $backend_pieces = []
#end if
<div style="padding: 10px 0 5px;">
<select name="imdbWatchlistCsv" id="imdbWl" size="6" style="min-width: 500px;">
#for $imdbwl in $backend_pieces:
#if $imdbwl != "":
<option value="$imdbwl">$imdbwl</option>
#end if
#end for
</select>
</div>
<div id="imdbWlControls" style="text-align: center; width: 500px;">
<input class="btn" type="button" id="addImdbWl" value="New" />
<input class="btn" type="button" id="editImdbWl" value="Edit" />
<input class="btn" type="button" id="deleteImdbWl" value="Delete" />
</div>
<input type="hidden" style="display: none" id="ImdbWlText" />
<input type="text" style="display: none" id="editImdbWlText" />
<div id="imdbWlUpdateControls" style="text-align: center; width: 500px;">
<input class="btn" style="display: none" type="button" id="updateImdbWl" value="Update" />
</div>
<br />

View File

@ -0,0 +1,170 @@
// Avoid `console` errors in browsers that lack a console.
(function() {
var method;
var noop = function noop() {};
var methods = [
'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error',
'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log',
'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd',
'timeStamp', 'trace', 'warn'
];
var length = methods.length;
var console = (window.console = window.console || {});
while (length--) {
method = methods[length];
// Only stub undefined methods.
if (!console[method]) {
console[method] = noop;
}
}
}());
$(document).ready(function() {
function addImdbWl(path) {
if (!path.length)
return;
$('#imdbWl').append('<option value="'+path+'">'+path+'</option>');
refreshImdbUrls();
$.get(sbRoot+'/config/general/saveImdbWatchlists', { imdbWatchlistString: $('#ImdbWlText').val() });
}
function editImdbWl(path) {
if (!path.length)
return;
// as long as something is selected
if ($("#imdbWl option:selected").length) {
$("#imdbWl option:selected").text(path);
$("#imdbWl option:selected").val(path);
}
refreshImdbUrls();
$.get(sbRoot+'/config/general/saveRootDirs', {rootDirString: $('#ImdbWlText').val()});
}
$('#addImdbWl').click(function(){editText()});
$('#editImdbWl').click(function(){editText({selectedWl: $("#imdbWl option:selected").val()})});
$('#deleteImdbWl').click(function() {
if ($("#imdbWl option:selected").length) {
var toDelete = $("#imdbWl option:selected");
toDelete.remove();
syncOptionIDs();
};
refreshImdbUrls();
$.get(sbRoot+'/config/general/saveImdbWatchlists', {imdbWatchlistString: $('#ImdbWlText').val()});
});
function syncOptionIDs() {
// re-sync option ids
var i = 0;
$('#imdbWl option').each(function() {
$(this).attr('id', 'wl-'+(i++));
});
}
function refreshImdbUrls() {
// Rebuild the string in #ImdbWlText as url|url|url
if (!$("#imdbWl").length)
return;
var do_disable = 'true';
// if something's selected then we have some behavior to figure out
if ($("#imdbWl option:selected").length) {
do_disable = '';
}
// update the elements
$('#deleteImdbWl').prop('disabled', do_disable);
$('#editImdbWl').prop('disabled', do_disable);
var log_str = '';
var dir_text = '';
$('#imdbWl option').each(function() {
log_str += $(this).val();
//Check if this is a valid IMDB link before adding it
if (checkIMDBUrl(log_str)) {
if (dir_text == '') {
dir_text = $(this).val()
}
else {
dir_text += '|' + $(this).val();
}
}
});
//console.log(log_str);
$('#ImdbWlText').val(dir_text);
$('#ImdbWlText').change();
//console.log('ImdbWlText: '+$('#ImdbWlText').val());
}
function checkIMDBUrl(url) {
if (url.match(/http.*:\/\/www\.imdb\.com\/.*/gi) &&
url.match(/ls[0-9]+/gi) &&
url.match(/ur[0-9]+/gi)) {
return true;
}
else {
alert(url + ' is not a valid IMDB csv export!');
return false;
};
};
$('#imdbWl').click(refreshImdbUrls);
// set up buttons on page load
refreshImdbUrls();
function editText(optionid) {
var updateVal = "";
if (optionid) {
updateVal = 'update-' + optionid.selectedWl;
$('#editImdbWlText').val(optionid.selectedWl);
}
else {
updateVal = 'add';
$('#editImdbWlText').val("");
}
$('#updateImdbWl').attr('action', updateVal);
$('#editImdbWlText').attr('style','display: block; width: 100%; margin-top: 4px; margin-bottom: 4px;');
$('#imdbWl').prop('disabled', 'true');
$('#updateImdbWl').attr('style','display: block;');
$('#editImdbWlText').select();
}
$('#updateImdbWl').click(function(){
// Update the Multiselect after clicking on the Update button
var updateText = $('#editImdbWlText').val();
if (checkIMDBUrl(updateText)) {
if ($('#updateImdbWl').attr('action') == 'add') {
addImdbWl(updateText);
}
else {
editImdbWl(updateText);
};
};
$('#editImdbWlText').attr('style','display: none; width: 100%');
$('#imdbWl').prop('disabled', '');
$('#updateImdbWl').attr('style','display: none;');
});
});

View File

@ -8,18 +8,27 @@
"""Unittests for tvdb_api
"""
import os
import os,os.path
import sys
print sys.path
import datetime
import unittest
# Force parent directory onto path
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
#sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import tvdb_api
sys.path.append(os.path.abspath('../../tests'))
import sickbeard
from tvdb_api import Tvdb
import tvdb_ui
from tvdb_api import (tvdb_shownotfound, tvdb_seasonnotfound,
tvdb_episodenotfound, tvdb_attributenotfound)
from lib import xmltodict
import lib
class test_tvdb_basic(unittest.TestCase):
# Used to store the cached instance of Tvdb()

View File

@ -522,10 +522,14 @@ class Tvdb:
if self.config['search_all_languages']:
self.config['url_getSeries'] = u"%(base_url)s/api/GetSeries.php" % self.config
self.config['url_getSeriesImdb'] = u"%(base_url)s/api/GetSeriesByRemoteID.php" % self.config
self.config['params_getSeries'] = {"seriesname": "", "language": "all"}
self.config['params_getSeriesByImdb'] = {"imdbid": "", "language": "all"}
else:
self.config['url_getSeries'] = u"%(base_url)s/api/GetSeries.php" % self.config
self.config['url_getSeriesImdb'] = u"%(base_url)s/api/GetSeriesByRemoteID.php" % self.config
self.config['params_getSeries'] = {"seriesname": "", "language": self.config['language']}
self.config['params_getSeriesByImdb'] = {"imdbid": "", "language": self.config['language']}
self.config['url_epInfo'] = u"%(base_url)s/api/%(apikey)s/series/%%s/all/%%s.xml" % self.config
self.config['url_epInfo_zip'] = u"%(base_url)s/api/%(apikey)s/series/%%s/all/%%s.zip" % self.config
@ -674,16 +678,20 @@ class Tvdb:
data = data.strip()
return data
def search(self, series):
def search(self, series, imdbid=None):
"""This searches TheTVDB.com for the series name
and returns the result list
"""
series = series.encode("utf-8")
log().debug("Searching for show %s" % series)
self.config['params_getSeries']['seriesname'] = series
self.config['params_getSeriesByImdb']['imdbid'] = imdbid
try:
seriesFound = self._getetsrc(self.config['url_getSeries'], self.config['params_getSeries']).values()[0]
if imdbid:
seriesFound = self._getetsrc(self.config['url_getSeriesImdb'], self.config['params_getSeriesByImdb']).values()[0]
else:
seriesFound = self._getetsrc(self.config['url_getSeries'], self.config['params_getSeries']).values()[0]
return seriesFound
except:
return []

View File

@ -39,6 +39,7 @@ from sickbeard.config import CheckSection, check_setting_int, check_setting_str,
naming_ep_type
from sickbeard import searchBacklog, showUpdater, versionChecker, properFinder, autoPostProcesser, \
subtitles, traktChecker
from sickbeard.automations import imdbChecker
from sickbeard import helpers, db, exceptions, show_queue, search_queue, scheduler, show_name_helpers
from sickbeard import logger
from sickbeard import naming
@ -465,6 +466,7 @@ def initialize(consoleLogging=True):
USE_XBMC, XBMC_ALWAYS_ON, XBMC_NOTIFY_ONSNATCH, XBMC_NOTIFY_ONDOWNLOAD, XBMC_NOTIFY_ONSUBTITLEDOWNLOAD, XBMC_UPDATE_FULL, XBMC_UPDATE_ONLYFIRST, \
XBMC_UPDATE_LIBRARY, XBMC_HOST, XBMC_USERNAME, XBMC_PASSWORD, BACKLOG_FREQUENCY, \
USE_TRAKT, TRAKT_USERNAME, TRAKT_PASSWORD, TRAKT_API, TRAKT_REMOVE_WATCHLIST, TRAKT_USE_WATCHLIST, TRAKT_METHOD_ADD, TRAKT_START_PAUSED, traktCheckerScheduler, TRAKT_USE_RECOMMENDED, TRAKT_SYNC, TRAKT_DEFAULT_INDEXER, TRAKT_REMOVE_SERIESLIST, \
USE_IMDBWATCHLIST, IMDB_WATCHLISTCSV, imdbWatchlistScheduler, \
USE_PLEX, PLEX_NOTIFY_ONSNATCH, PLEX_NOTIFY_ONDOWNLOAD, PLEX_NOTIFY_ONSUBTITLEDOWNLOAD, PLEX_UPDATE_LIBRARY, \
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, SORT_ARTICLE, showList, loadingShowList, \
@ -523,6 +525,7 @@ def initialize(consoleLogging=True):
CheckSection(CFG, 'Pushalot')
CheckSection(CFG, 'Pushbullet')
CheckSection(CFG, 'Subtitles')
CheckSection(CFG, 'IMDBWatchlist')
# wanted branch
BRANCH = check_setting_str(CFG, 'General', 'branch', '')
@ -572,7 +575,7 @@ def initialize(consoleLogging=True):
if WEB_PORT < 21 or WEB_PORT > 65535:
WEB_PORT = 8081
WEB_HOST = check_setting_str(CFG, 'General', 'web_host', '0.0.0.0')
WEB_IPV6 = bool(check_setting_int(CFG, 'General', 'web_ipv6', 0))
WEB_ROOT = check_setting_str(CFG, 'General', 'web_root', '').rstrip("/")
@ -834,7 +837,11 @@ def initialize(consoleLogging=True):
TRAKT_USE_RECOMMENDED = bool(check_setting_int(CFG, 'Trakt', 'trakt_use_recommended', 0))
TRAKT_SYNC = bool(check_setting_int(CFG, 'Trakt', 'trakt_sync', 0))
TRAKT_DEFAULT_INDEXER = check_setting_int(CFG, 'Trakt', 'trakt_default_indexer', 1)
### IMDB Watchlist set default values for config
USE_IMDBWATCHLIST = bool(check_setting_int(CFG, 'IMDBWatchlist', 'use_imdbwatchlist', 0))
IMDB_WATCHLISTCSV = check_setting_str(CFG, 'IMDBWatchlist', 'imdb_watchlistcsv', '')
CheckSection(CFG, 'pyTivo')
USE_PYTIVO = bool(check_setting_int(CFG, 'pyTivo', 'use_pytivo', 0))
PYTIVO_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'pyTivo', 'pytivo_notify_onsnatch', 0))
@ -1147,6 +1154,11 @@ def initialize(consoleLogging=True):
cycleTime=datetime.timedelta(hours=SUBTITLES_FINDER_FREQUENCY),
threadName="FINDSUBTITLES",
silent=not USE_SUBTITLES)
imdbWatchlistScheduler = scheduler.Scheduler(imdbChecker.IMDB(),
cycleTime=datetime.timedelta(hours=1),
threadName="IMDBWATCHLIST",
silent=not USE_IMDBWATCHLIST)
showList = []
loadingShowList = {}
@ -1159,7 +1171,7 @@ def start():
global __INITIALIZED__, backlogSearchScheduler, \
showUpdateScheduler, versionCheckScheduler, showQueueScheduler, \
properFinderScheduler, autoPostProcesserScheduler, searchQueueScheduler, \
subtitlesFinderScheduler, USE_SUBTITLES, traktCheckerScheduler, \
subtitlesFinderScheduler, USE_SUBTITLES, traktCheckerScheduler, imdbWatchlistScheduler, \
dailySearchScheduler, events, started
with INIT_LOCK:
@ -1200,7 +1212,10 @@ def start():
# start the trakt checker
if USE_TRAKT:
traktCheckerScheduler.start()
if USE_IMDBWATCHLIST:
imdbWatchlistScheduler.start()
started = True
@ -1208,7 +1223,7 @@ def halt():
global __INITIALIZED__, backlogSearchScheduler, \
showUpdateScheduler, versionCheckScheduler, showQueueScheduler, \
properFinderScheduler, autoPostProcesserScheduler, searchQueueScheduler, \
subtitlesFinderScheduler, traktCheckerScheduler, \
subtitlesFinderScheduler, traktCheckerScheduler, imdbWatchlistScheduler, \
dailySearchScheduler, events, started
with INIT_LOCK:
@ -1281,6 +1296,14 @@ def halt():
traktCheckerScheduler.join(10)
except:
pass
if USE_IMDBWATCHLIST:
imdbWatchlistScheduler.stop.set()
logger.log(u"Waiting for the IMDBWATCHLIST thread to exit")
try:
imdbWatchlistScheduler.join(10)
except:
pass
if DOWNLOAD_PROPERS:
properFinderScheduler.stop.set()
@ -1680,7 +1703,11 @@ def save_config():
new_config['Trakt']['trakt_use_recommended'] = int(TRAKT_USE_RECOMMENDED)
new_config['Trakt']['trakt_sync'] = int(TRAKT_SYNC)
new_config['Trakt']['trakt_default_indexer'] = int(TRAKT_DEFAULT_INDEXER)
new_config['IMDBWatchlist'] = {}
new_config['IMDBWatchlist']['use_imdbwatchlist'] = int(USE_IMDBWATCHLIST)
new_config['IMDBWatchlist']['imdb_watchlistcsv'] = IMDB_WATCHLISTCSV
new_config['pyTivo'] = {}
new_config['pyTivo']['use_pytivo'] = int(USE_PYTIVO)
new_config['pyTivo']['pytivo_notify_onsnatch'] = int(PYTIVO_NOTIFY_ONSNATCH)

View File

View File

@ -0,0 +1,230 @@
# Author: KontiSR
# URL: https://github.com/echel0n/SickRage
#
# This file is part of SickRage.
#
# SickRage is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# SickRage is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with SickRage. If not, see <http://www.gnu.org/licenses/>.
import urllib2, urllib
import shutil
import urlparse
import os, datetime
import requests
import cookielib
import re
from urllib2 import HTTPError, URLError
import sickbeard
from sickbeard import encodingKludge as ek
from sickbeard import logger
from sickbeard import helpers
from sickbeard import search_queue
from sickbeard.common import SKIPPED, WANTED
from lib.tvdb_api.tvdb_api import *
class ImdbBase():
def _download(self, baseurl, querystring=""):
fullurl = baseurl + urllib.urlencode(querystring)
req = urllib2.Request(fullurl)
try:
response = urllib2.urlopen(req)
except HTTPError as e:
logger.log('Could not download IMDB watchlist', logger.DEBUG)
#print 'Error code: ', e.code
return False
except URLError as e:
logger.log('Could not download IMDB watchlist', logger.DEBUG)
#print 'Reason: ', e.reason
return False
redirurl = response.geturl()
htmlResponse = response.read()
validHtml = True#BeautifulSoup(htmlResponse, 'html.parser')
if validHtml:
return htmlResponse
return False
class IMDB(ImdbBase):
listOfImdbIds = []
def __init__(self):
self.listOfImdbIds = []
def run(self, force=False):
try:
# add shows from trakt.tv watchlist
if sickbeard.USE_IMDBWATCHLIST:
self.listOfImdbIds = [] # its about to all get re-added
self.checkWatchlist() # Check the | separated watchlists (csv) urls
if len(self.listOfImdbIds):
self.updateShowsInDb() # Update the db with possible new shows
except Exception:
logger.log(traceback.format_exc(), logger.DEBUG)
def _getTTs(self, html):
nrAddedTTs = 0
### Get the tt's (shows) from the ajax html. E.a. [ tt1958961|imdb|8.1|8.1|list, tt1958961|imdb|8.1|8.1|list ]
if not html:
return False
parsedshows = re.findall("(tt[0-9]+)\\|imdb\\|([.0-9]+)", html)
if not parsedshows:
return False
for show in parsedshows:
if show[0] not in [x['imdbid'] for x in self.listOfImdbIds]:
self.listOfImdbIds.append({"imdbid" : show[0], "score" : show[1]})
nrAddedTTs += 1
if nrAddedTTs > 0:
return nrAddedTTs
return False
def checkWatchlist(self):
### Get imdbListId from the csv url's
AjaxUrls = self._getImdbAjaxUrls(sickbeard.IMDB_WATCHLISTCSV)
### Get imdbUserId from the csv url's
for url in AjaxUrls:
getImdbHtml = self._download(url)
nrAdded = self._getTTs(getImdbHtml)
if self.listOfImdbIds:
return self.listOfImdbIds
return False
'''
Tries to use the csvUrls as a comma separated list of imdb csv urls,
to retrieve a userid and listid for each of the csv url.
For each csv url an Ajax url is created. Thats used to get the list of Tvshows.
'''
def _getImdbAjaxUrls(self, csvUrls):
ajaxUrls = []
ajaxUrlBase = u"http://www.imdb.com/list/_ajax/list_filter?"
reUserId = re.compile(".*(ur[0-9]+)")
reListId = re.compile(".*(ls[0-9]+)")
#if "|" in csvUrls:
#print "Multiple Watchlists detected"
csvurl = csvUrls.split("|")
for url in csvurl:
userIdMatch = reUserId.match(url)
listIdMatch = reListId.match(url)
if userIdMatch and listIdMatch:
query = {"list_id" : listIdMatch.groups()[0],
"list_class" : "WATCHLIST",
"view" : "compact",
"list_type" : "Titles",
"filter" : '{"title_type":["tv_series"]}',
"sort_field" : "created",
"sort_direction" : "desc",
"user_id" : userIdMatch.groups()[0] }
ajaxUrls.append(ajaxUrlBase + urllib.urlencode(query))
if ajaxUrls:
return ajaxUrls
return False
def updateShowsInDb(self):
nrOfaddedShows = 0
# Get list with thetvdb and imdbIds from DB (tt1234324)
# Get thetvdb indexer_id, showname from tvdb using the IMDB id. ttxxxxx
# Use "[{listOfImdbIds}]" for updating the db, if the show isn't in it
tvdb_instance = Tvdb(cache = True, useZip = True)
for watchlistShow in self.listOfImdbIds:
if watchlistShow['imdbid'] not in [x.imdbid for x in sickbeard.showList ]:
TvdbShow = tvdb_instance.search('',imdbid=watchlistShow['imdbid'])
if TvdbShow:
self._addDefaultShow(1, TvdbShow['id'], TvdbShow['seriesname'], False)
nrOfaddedShows += 1
return nrOfaddedShows if nrOfaddedShows > 0 else False
return False
def _addDefaultShow(self, indexer, indexer_id, name, status):
"""
Adds a new show with the default settings
"""
if not helpers.findCertainShow(sickbeard.showList, int(indexer_id)):
logger.log(u"Adding show " + str(indexer_id))
root_dirs = sickbeard.ROOT_DIRS.split('|')
try:
location = root_dirs[int(root_dirs[0]) + 1]
except:
location = None
if location:
showPath = ek.ek(os.path.join, location, helpers.sanitizeFileName(name))
dir_exists = helpers.makeDir(showPath)
if not dir_exists:
logger.log(u"Unable to create the folder " + showPath + ", can't add the show", logger.ERROR)
return
else:
helpers.chmodAsParent(showPath)
sickbeard.showQueueScheduler.action.addShow(int(indexer), int(indexer_id), showPath, status,
int(sickbeard.QUALITY_DEFAULT),
int(sickbeard.FLATTEN_FOLDERS_DEFAULT),
paused=False, anime = False)
else:
logger.log(u"There was an error creating the show, no root directory setting found", logger.ERROR)
return
# imdbWatchlistTv = "http://www.imdb.com/user/%s/watchlist?ref_=wl_ref_typ&sort=list_order,asc&mode=simple&page=%s&title_type=tvSeries"
# imdbWatchlistTv2 = "http://www.imdb.com/list/export?list_id=ls009966268&author_id=ur35235230&ref_=wl_exp"
# imdbUserId = "ur5968686"
# imdbListId = "ls005547625"
# imdbWlPage = "1"
# ajaxUrlBase = u"http://www.imdb.com/list/_ajax/list_filter?"
# ajaxUrlQueryString = u"list_id=%s&list_class=WATCHLIST&view=compact&list_type=Titles&filter={\"title_type\":[\"tv_series\"]}&sort_field=created&sort_direction=desc&user_id=%s" % (imdbListId, imdbUserId)
#
# query = {"list_id" : imdbListId,
# "list_class" : "WATCHLIST",
# "view" : "compact",
# "list_type" : "Titles",
# "filter" : '{"title_type":["tv_series"]}',
# "sort_field" : "created",
# "sort_direction" : "desc",
# "user_id" : imdbUserId }
#
# imdbwatchlistcsv = "http://www.imdb.com/list/export?list_id=ls005547625&author_id=ur5968686&ref_=wl_exp"
# imdbWatchListTvFullURL = ajaxUrlBase + urllib.urlencode(query)
# # /download("%s%s" % (baseurl, searchurl), "test.csv")
#
# IMDBobj = IMDB()
#
# #Test one csv
# imdbIds = IMDBobj.checkWatchlist(imdbwatchlistcsv)
# print IMDBobj.listOfImdbIds
#
# # Test two csv's
# imdbIds = IMDBobj.checkWatchlist(imdbwatchlistcsv + "|" + imdbWatchlistTv2)
# print IMDBobj.listOfImdbIds
#
# print imdbIds

View File

@ -1425,7 +1425,9 @@ class ConfigGeneral(MainHandler):
def saveRootDirs(self, rootDirString=None):
sickbeard.ROOT_DIRS = rootDirString
def saveImdbWatchlists(self, imdbWatchlistString=None):
sickbeard.IMDB_WATCHLISTCSV = imdbWatchlistString
def saveAddShowDefaults(self, defaultStatus, anyQualities, bestQualities, defaultFlattenFolders, subtitles=False,
anime=False, scene=False):
@ -1485,7 +1487,7 @@ class ConfigGeneral(MainHandler):
handle_reverse_proxy=None, sort_article=None, auto_update=None, notify_on_update=None,
proxy_setting=None, anon_redirect=None, git_path=None, calendar_unprotected=None,
fuzzy_dating=None, trim_zero=None, date_preset=None, date_preset_na=None, time_preset=None,
indexer_timeout=None, play_videos=None, rootDir=None):
indexer_timeout=None, play_videos=None, rootDir=None, use_imdbwl=None, imdbWatchlistCsv=None):
results = []
@ -1495,6 +1497,7 @@ class ConfigGeneral(MainHandler):
config.change_VERSION_NOTIFY(config.checkbox_to_value(version_notify))
sickbeard.AUTO_UPDATE = config.checkbox_to_value(auto_update)
sickbeard.NOTIFY_ON_UPDATE = config.checkbox_to_value(notify_on_update)
sickbeard.USE_IMDBWATCHLIST = config.checkbox_to_value(use_imdbwl)
# sickbeard.LOG_DIR is set in config.change_LOG_DIR()
sickbeard.UPDATE_SHOWS_ON_START = config.checkbox_to_value(update_shows_on_start)

View File

@ -206,7 +206,8 @@ def setUp_test_episode_file():
def tearDown_test_episode_file():
shutil.rmtree(FILEDIR)
if os.path.exists(FILEDIR):
shutil.rmtree(FILEDIR)
def setUp_test_show_dir():
@ -215,7 +216,8 @@ def setUp_test_show_dir():
def tearDown_test_show_dir():
shutil.rmtree(SHOWDIR)
if os.path.exists(SHOWDIR):
shutil.rmtree(SHOWDIR)
tearDown_test_db()

152
tests/test_tvdb_api.py Normal file
View File

@ -0,0 +1,152 @@
"""Unittests for tvdb_api
"""
import unittest
import test_lib as test
import sys, os.path
sys.path.append(os.path.abspath('..'))
sys.path.append(os.path.abspath('../lib'))
print sys.path
from sickbeard import show_name_helpers, scene_exceptions, common, name_cache
import sickbeard
from sickbeard import db
from sickbeard.databases import cache_db
from sickbeard.tv import TVShow as Show
from lib.tvdb_api.tvdb_api import *
#import tvdb_api as tvdb_api
import tvdb_api
# class test_tvdb_basic(test.SickbeardTestDBCase):
# # Used to store the cached instance of Tvdb()
# t = None
#
# def setUp(self):
# if self.t is None:
# self.__class__.t = Tvdb(cache = True, banners = False)
#
# def test_different_case(self):
# """Checks the auto-correction of show names is working.
# It should correct the weirdly capitalised 'sCruBs' to 'Scrubs'
# """
# self.assertEquals(self.t['scrubs'][1][4]['episodename'], 'My Old Lady')
# self.assertEquals(self.t['sCruBs']['seriesname'], 'Scrubs')
#
# def test_spaces(self):
# """Checks shownames with spaces
# """
# self.assertEquals(self.t['My Name Is Earl']['seriesname'], 'My Name Is Earl')
# self.assertEquals(self.t['My Name Is Earl'][1][4]['episodename'], 'Faked His Own Death')
#
# def test_numeric(self):
# """Checks numeric show names
# """
# self.assertEquals(self.t['24'][2][20]['episodename'], 'Day 2: 3:00 A.M.-4:00 A.M.')
# self.assertEquals(self.t['24']['seriesname'], '24')
#
# def test_show_iter(self):
# """Iterating over a show returns each seasons
# """
# self.assertEquals(
# len(
# [season for season in self.t['Life on Mars']]
# ),
# 2
# )
#
# def test_season_iter(self):
# """Iterating over a show returns episodes
# """
# self.assertEquals(
# len(
# [episode for episode in self.t['Life on Mars'][1]]
# ),
# 8
# )
#
# def test_get_episode_overview(self):
# """Checks episode overview is retrieved correctly.
# """
# self.assertEquals(
# self.t['Battlestar Galactica (2003)'][1][6]['overview'].startswith(
# 'When a new copy of Doral, a Cylon who had been previously'),
# True
# )
#
# def test_get_parent(self):
# """Check accessing series from episode instance
# """
# show = self.t['Battlestar Galactica (2003)']
# season = show[1]
# episode = show[1][1]
#
# self.assertEquals(
# season.show,
# show
# )
#
# self.assertEquals(
# episode.season,
# season
# )
#
# self.assertEquals(
# episode.season.show,
# show
# )
#
# def test_no_season(self):
# show = self.t['Katekyo Hitman Reborn']
# print tvdb_api
# print show[1][1]
class searchTvdbImdbid(test.SickbeardTestDBCase):
# Used to store the cached instance of Tvdb()
t = None
def setUp(self):
if self.t is None:
self.__class__.t = Tvdb(cache = True, useZip = True)
def test_search(self):
"""Test Tvdb.search method
"""
results = self.t.search("",imdbid='tt0903747')
all_ids = results['seriesid']
self.assertTrue('81189' in all_ids)
class test_tvdb_show_search(test.SickbeardTestDBCase):
# Used to store the cached instance of Tvdb()
t = None
def setUp(self):
if self.t is None:
self.__class__.t = Tvdb(cache = True, useZip = True)
def test_search(self):
"""Test Tvdb.search method
"""
results = self.t.search("my name is earl")
all_ids = results['seriesid']
self.assertTrue('75397' in all_ids)
if __name__ == '__main__':
print "=================="
print "STARTING - PostProcessor TESTS"
print "=================="
print "######################################################################"
print "###Test Search Tvdb for show breaking bad, using the imdb id"
suite = unittest.TestLoader().loadTestsFromTestCase(searchTvdbImdbid)
unittest.TextTestRunner(verbosity=2).run(suite)
print "######################################################################"
print "###Test Search Tvdb for show my name is earl, using the show name"
suite = unittest.TestLoader().loadTestsFromTestCase(test_tvdb_show_search)
unittest.TextTestRunner(verbosity=2).run(suite)