Commit a65bc0f1 authored by echel0n's avatar echel0n
Browse files

Release v9.3.29

parent d21e3aa2
# Changelog
- * 7e767e4 - 2018-06-02: Fixed NoneType error in displayShow mako code related to imdb ratings
- * 2a9ed57 - 2018-06-04: Release v9.3.29
- * d21e3aa - 2018-06-02: Fixed NoneType error in displayShow mako code related to imdb ratings
- * 1277227 - 2018-06-01: Release v9.3.28
- * 924a877 - 2018-06-01: Release v9.3.27
- * 22b37e3 - 2018-05-31: Pre-Release v9.3.27.dev1
......
......@@ -1470,85 +1470,6 @@ jQuery(document).ready(function ($) {
}
},
google: {
init: function () {
},
login: function () {
$.ajax({
dataType: "json",
url: SICKRAGE.srWebRoot + '/google/get_user_code',
type: 'POST',
success: function (data) {
var loginDialog = gt('<center><h1>' + data.user_code + '</h1><br/>From any computer, please visit <a href="' + data.verification_url + '" target="_blank">' + data.verification_url + '</a> and enter the code</center>');
$('#login-dialog').dialog({
modal: true,
draggable: false,
width: '25%',
title: gt('Link SiCKRAGE')
}).html(loginDialog);
SICKRAGE.google.poll_auth(data, new Date().getTime() + new Date(data.user_code_expiry).getTime() * 1000, data.interval);
}
});
},
logout: function () {
$.ajax({
url: SICKRAGE.srWebRoot + '/google/logout',
success: function () {
localStorage.clear();
location.reload();
}
});
},
poll_auth: function (flow_info, lastPollTime, nextPollDelay) {
if (new Date().getTime() < lastPollTime) {
$.ajax({
dataType: 'json',
url: SICKRAGE.srWebRoot + '/google/get_credentials',
data: {flow_info: JSON.stringify(flow_info)},
type: 'POST',
success: function (response) {
if (response.error) {
if (response.error === 'slow_down') {
nextPollDelay += 5;
}
setTimeout(function () {
SICKRAGE.google.poll_auth(flow_info, lastPollTime, nextPollDelay);
}, nextPollDelay * 1000);
} else {
$('#login-dialog').dialog('close');
localStorage.setItem('google_refresh_token', response.refresh_token);
localStorage.setItem('google_access_token', response.access_token);
localStorage.setItem('google_token_type', response.token_type);
location.reload();
}
}
});
}
},
refresh_auth: function () {
$.ajax({
dataType: 'json',
url: SICKRAGE.srWebRoot + '/google/refresh_credentials',
data: {token: localStorage.getItem('google_refresh_token')},
type: 'POST',
success: function (response) {
localStorage.setItem('google_access_token', response.access_token);
localStorage.setItem('google_token_type', response.token_type);
},
error: function () {
SICKRAGE.google.logout();
}
});
}
},
home: {
init: function () {
SICKRAGE.home.add_show_options();
......
......@@ -46,7 +46,6 @@ from sickrage.core.common import SD, SKIPPED, WANTED
from sickrage.core.config import Config
from sickrage.core.databases.cache import CacheDB
from sickrage.core.databases.main import MainDB
from sickrage.core.google import GoogleAuth
from sickrage.core.helpers import findCertainShow, generateCookieSecret, makeDir, get_lan_ip, restoreSR, \
getDiskSpaceUsage, getFreeSpace, launch_browser, torrent_webui_url
from sickrage.core.helpers.encoding import get_sys_encoding, ek, patch_modules
......@@ -161,7 +160,6 @@ class Core(object):
self.cache_db = CacheDB()
self.scheduler = TornadoScheduler()
self.wserver = WebServer()
self.google_auth = GoogleAuth()
self.name_cache = NameCache()
self.show_queue = ShowQueue()
self.search_queue = SearchQueue()
......
from __future__ import unicode_literals
import datetime
import json
import os
import sys
import time
from time import sleep
from urlparse import urljoin
from oauthlib.oauth2 import LegacyApplicationClient, MissingTokenError, InvalidClientIdError
......@@ -44,11 +48,10 @@ class API(object):
@property
def token(self):
if self._token is None:
if self._username != sickrage.app.config.api_username or self._password != sickrage.app.config.api_password:
if os.path.isfile(self.token_file):
os.remove(self.token_file)
if any([self._username, self._password]) and os.path.isfile(self.token_file):
os.remove(self.token_file)
if not os.path.isfile(self.token_file):
if not os.path.exists(self.token_file):
oauth = OAuth2Session(client=LegacyApplicationClient(client_id=self.credentials['client_id']))
self._token = oauth.fetch_token(token_url=self.token_url,
timeout=30,
......@@ -70,16 +73,25 @@ class API(object):
return
try:
resp = self.session.request(method, urljoin(self.api_url, url), timeout=30, **kwargs)
resp = self.session.request(method, urljoin(self.api_url, url), timeout=30,
hooks={'response': self.throttle_hook}, **kwargs)
if resp.status_code == 401:
raise unauthorized(resp.json()['message'])
elif resp.status_code >= 400:
raise error(resp.json()['message'])
return resp.json()
except (InvalidClientIdError, MissingTokenError):
except (InvalidClientIdError, MissingTokenError) as e:
sickrage.app.log.warning("Token is required for interacting with SiCKRAGE API, check username/password "
"under General settings.")
def user_profile(self):
return self._request('GET', 'user')
@staticmethod
def throttle_hook(response, **kwargs):
ratelimited = "X-RateLimit-Remaining" in response.headers
if ratelimited:
remaining = int(response.headers["X-RateLimit-Remaining"])
if remaining == 1:
sickrage.app.log.debug("Throttling SiCKRAGE API Calls... Sleeping for 60 secs...\n")
time.sleep(60)
......@@ -6,14 +6,18 @@ class GoogleDriveAPI(API):
query = 'api/v1/google-drive/is-connected'
return self._request('GET', query)
def clear_appdata(self):
query = 'api/v1/google-drive/appdata/clear'
def upload(self, file, folder):
query = 'api/v1/google-drive/upload'
return self._request('POST', query, files={'file': open(file, 'rb')}, params={'folder': folder})
def download(self, id):
query = 'api/v1/google-drive/download/{id}'.format(id=id)
return self._request('GET', query)
def upload_appdata(self, name, file):
query = 'api/v1/google-drive/appdata/upload'
return self._request('POST', query)
def list_appdata(self):
query = 'api/v1/google-drive/appdata'
return self._request('GET', query)
def download_appdata(self):
query = 'api/v1/google-drive/appdata/download'
return self._request('GET', query)
\ No newline at end of file
def clear_appdata(self):
query = 'api/v1/google-drive/appdata/clear'
return self._request('GET', query)
# Author: echel0n <[email protected]>
# URL: https://sickrage.ca
#
# 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/>.
from __future__ import unicode_literals
from oauth2client.client import OAuth2WebServerFlow, OAuth2Credentials
from sickrage.core.websession import WebSession
class GoogleAuth(object):
def __init__(self):
self.client_id = '48901323822-ebum0n1ago1bo2dku4mqm9l6kl2j60uv.apps.googleusercontent.com'
self.client_secret = 'vFQy_bojwJ1f2X0hYD3wPu7U'
self.scopes = ['https://www.googleapis.com/auth/drive.file',
'email',
'profile']
self.credentials = None
self.flow = OAuth2WebServerFlow(self.client_id, self.client_secret, ' '.join(self.scopes))
def get_user_code(self):
return self.flow.step1_get_device_and_user_codes()
def get_credentials(self, flow_info):
self.credentials = self.flow.step2_exchange(device_flow_info=flow_info)
return self.credentials
def refresh_credentials(self):
if isinstance(self.credentials, OAuth2Credentials):
self.credentials.refresh(WebSession())
def logout(self):
self.credentials = None
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -48,6 +48,7 @@ from adba import aniDBAbstracter
from sickrage.clients import getClientIstance
from sickrage.clients.sabnzbd import SabNZBd
from sickrage.core import API
from sickrage.core.api.google import GoogleDriveAPI
from sickrage.core.blackandwhitelist import BlackAndWhiteList, \
short_group_names
from sickrage.core.classes import ErrorViewer, AllShowsUI, AttrDict
......@@ -523,29 +524,6 @@ class WebRoot(WebHandler):
return indexerImage(id=indexerid, which="poster_thumb")
@Route('/google(/?.*)')
class GoogleAuth(WebHandler):
def __init__(self, *args, **kwargs):
super(GoogleAuth, self).__init__(*args, **kwargs)
def get_user_code(self):
data = sickrage.app.google_auth.get_user_code()
return json_encode({field: str(getattr(data, field)) for field in data._fields})
def get_credentials(self, flow_info):
try:
data = sickrage.app.google_auth.get_credentials(AttrDict(json_decode(flow_info)))
return json_encode(data.token_response)
except Exception as e:
return json_encode({'error': str(e)})
def refresh_credentials(self):
sickrage.app.google_auth.refresh_credentials()
def logout(self):
sickrage.app.google_auth.logout()
@Route('/ui(/?.*)')
class UI(WebHandler):
def __init__(self, *args, **kwargs):
......@@ -2245,6 +2223,9 @@ class Home(WebHandler):
return json_encode({'result': 'failure'})
@Route('/IRC(/?.*)')
class irc(WebHandler):
def __init__(self, *args, **kwargs):
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment