2019-11-25 22:48:42 +01:00
|
|
|
import xbmcgui
|
|
|
|
import xbmcvfs
|
2023-06-02 16:13:33 +02:00
|
|
|
import json
|
2021-04-08 22:43:26 +02:00
|
|
|
import pyqrcode
|
2017-01-31 15:08:00 +01:00
|
|
|
import resources.lib.tinyurl as tinyurl
|
|
|
|
import resources.lib.utils as utils
|
2023-06-02 16:13:33 +02:00
|
|
|
from datetime import datetime
|
2019-08-26 22:40:15 +02:00
|
|
|
|
2019-11-25 22:19:57 +01:00
|
|
|
# don't die on import error yet, these might not even get used
|
2019-08-26 22:40:15 +02:00
|
|
|
try:
|
2019-11-26 19:58:35 +01:00
|
|
|
from dropbox import dropbox
|
2020-12-18 16:31:52 +01:00
|
|
|
from dropbox import oauth
|
2019-08-26 22:40:15 +02:00
|
|
|
except ImportError:
|
|
|
|
pass
|
|
|
|
|
2019-11-26 17:43:38 +01:00
|
|
|
|
2021-04-08 22:43:26 +02:00
|
|
|
class QRCode(xbmcgui.WindowXMLDialog):
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
self.image = kwargs["image"]
|
|
|
|
self.text = kwargs["text"]
|
|
|
|
self.url = kwargs['url']
|
|
|
|
|
|
|
|
def onInit(self):
|
|
|
|
self.imagecontrol = 501
|
|
|
|
self.textbox1 = 502
|
|
|
|
self.textbox2 = 504
|
|
|
|
self.okbutton = 503
|
|
|
|
self.showdialog()
|
|
|
|
|
|
|
|
def showdialog(self):
|
|
|
|
self.getControl(self.imagecontrol).setImage(self.image)
|
|
|
|
self.getControl(self.textbox1).setText(self.text)
|
|
|
|
self.getControl(self.textbox2).setText(self.url)
|
|
|
|
self.setFocus(self.getControl(self.okbutton))
|
|
|
|
|
|
|
|
def onClick(self, controlId):
|
|
|
|
if (controlId == self.okbutton):
|
|
|
|
self.close()
|
|
|
|
|
|
|
|
|
2017-01-31 15:08:00 +01:00
|
|
|
class DropboxAuthorizer:
|
2023-06-02 16:13:33 +02:00
|
|
|
TOKEN_FILE = "tokens.json"
|
2017-01-31 15:08:00 +01:00
|
|
|
APP_KEY = ""
|
|
|
|
APP_SECRET = ""
|
2019-11-26 17:43:38 +01:00
|
|
|
|
2017-01-31 15:08:00 +01:00
|
|
|
def __init__(self):
|
2024-04-28 17:09:59 +02:00
|
|
|
self.APP_KEY = utils.getSettingStringStripped('dropbox_key')
|
|
|
|
self.APP_SECRET = utils.getSettingStringStripped('dropbox_secret')
|
2017-01-31 15:08:00 +01:00
|
|
|
|
|
|
|
def setup(self):
|
2017-11-07 21:19:27 +01:00
|
|
|
result = True
|
2019-11-25 22:33:34 +01:00
|
|
|
|
2017-01-31 15:08:00 +01:00
|
|
|
if(self.APP_KEY == '' and self.APP_SECRET == ''):
|
2019-11-25 22:19:57 +01:00
|
|
|
# we can't go any farther, need these for sure
|
2020-12-18 16:28:17 +01:00
|
|
|
xbmcgui.Dialog().ok(utils.getString(30010), '%s %s\n%s' % (utils.getString(30027), utils.getString(30058), utils.getString(30059)))
|
2017-11-07 21:19:27 +01:00
|
|
|
|
|
|
|
result = False
|
2019-11-25 22:33:34 +01:00
|
|
|
|
|
|
|
return result
|
2017-01-31 15:08:00 +01:00
|
|
|
|
|
|
|
def isAuthorized(self):
|
2017-12-04 00:32:21 +01:00
|
|
|
user_token = self._getToken()
|
2017-01-31 15:08:00 +01:00
|
|
|
|
2023-06-02 16:13:33 +02:00
|
|
|
return 'access_token' in user_token
|
2017-01-31 15:08:00 +01:00
|
|
|
|
|
|
|
def authorize(self):
|
|
|
|
result = True
|
2017-11-07 21:19:27 +01:00
|
|
|
|
|
|
|
if(not self.setup()):
|
|
|
|
return False
|
2019-11-25 22:33:34 +01:00
|
|
|
|
2017-01-31 15:08:00 +01:00
|
|
|
if(self.isAuthorized()):
|
2019-11-25 22:19:57 +01:00
|
|
|
# delete the token to start over
|
2017-01-31 15:08:00 +01:00
|
|
|
self._deleteToken()
|
|
|
|
|
2019-11-25 22:19:57 +01:00
|
|
|
# copied flow from http://dropbox-sdk-python.readthedocs.io/en/latest/moduledoc.html#dropbox.oauth.DropboxOAuth2FlowNoRedirect
|
2023-06-02 16:13:33 +02:00
|
|
|
flow = oauth.DropboxOAuth2FlowNoRedirect(consumer_key=self.APP_KEY, consumer_secret=self.APP_SECRET, token_access_type="offline")
|
2017-01-31 15:08:00 +01:00
|
|
|
|
2017-12-04 00:32:21 +01:00
|
|
|
url = flow.start()
|
2017-01-31 15:08:00 +01:00
|
|
|
|
2019-11-25 22:19:57 +01:00
|
|
|
# print url in log
|
2017-01-31 15:08:00 +01:00
|
|
|
utils.log("Authorize URL: " + url)
|
2021-04-08 22:43:26 +02:00
|
|
|
|
|
|
|
# create a QR Code
|
|
|
|
shortUrl = str(tinyurl.shorten(url), 'utf-8')
|
|
|
|
imageFile = xbmcvfs.translatePath(utils.data_dir() + '/qrcode.png')
|
|
|
|
qrIMG = pyqrcode.create(shortUrl)
|
|
|
|
qrIMG.png(imageFile, scale=10)
|
|
|
|
|
|
|
|
# show the dialog prompt to authorize
|
|
|
|
qr = QRCode("script-backup-qrcode.xml", utils.addon_dir(), "default", image=imageFile, text=utils.getString(30056), url=shortUrl)
|
|
|
|
qr.doModal()
|
|
|
|
|
|
|
|
# cleanup
|
|
|
|
del qr
|
|
|
|
xbmcvfs.delete(imageFile)
|
2017-12-04 00:32:21 +01:00
|
|
|
|
2019-11-25 22:19:57 +01:00
|
|
|
# get the auth code
|
2017-12-04 00:32:21 +01:00
|
|
|
code = xbmcgui.Dialog().input(utils.getString(30027) + ' ' + utils.getString(30103))
|
2019-11-25 22:33:34 +01:00
|
|
|
|
2019-11-26 17:43:38 +01:00
|
|
|
# if user authorized this will work
|
2017-01-31 15:08:00 +01:00
|
|
|
|
2017-12-04 00:32:21 +01:00
|
|
|
try:
|
|
|
|
user_token = flow.finish(code)
|
2023-06-02 16:13:33 +02:00
|
|
|
self._setToken(user_token)
|
2019-08-19 22:23:48 +02:00
|
|
|
except Exception as e:
|
2017-12-04 00:32:21 +01:00
|
|
|
utils.log("Error: %s" % (e,))
|
|
|
|
result = False
|
2019-11-25 22:33:34 +01:00
|
|
|
|
2019-11-26 17:49:17 +01:00
|
|
|
return result
|
2017-01-31 15:08:00 +01:00
|
|
|
|
2019-11-25 22:19:57 +01:00
|
|
|
# return the DropboxClient, or None if can't be created
|
2017-01-31 15:08:00 +01:00
|
|
|
def getClient(self):
|
|
|
|
result = None
|
|
|
|
|
2017-12-04 00:32:21 +01:00
|
|
|
user_token = self._getToken()
|
|
|
|
|
|
|
|
if(user_token != ''):
|
2019-11-26 17:43:38 +01:00
|
|
|
# create the client
|
2023-06-02 16:13:33 +02:00
|
|
|
result = dropbox.Dropbox(oauth2_access_token=user_token['access_token'], oauth2_refresh_token=user_token['refresh_token'],
|
|
|
|
oauth2_access_token_expiration=user_token['expiration'], app_key=self.APP_KEY, app_secret=self.APP_SECRET)
|
2017-01-31 15:08:00 +01:00
|
|
|
try:
|
2017-12-04 00:32:21 +01:00
|
|
|
result.users_get_current_account()
|
2017-01-31 15:08:00 +01:00
|
|
|
except:
|
2019-11-26 17:43:38 +01:00
|
|
|
# this didn't work, delete the token file
|
2017-01-31 15:08:00 +01:00
|
|
|
self._deleteToken()
|
2017-12-04 00:32:21 +01:00
|
|
|
result = None
|
2019-11-25 22:33:34 +01:00
|
|
|
|
2017-01-31 15:08:00 +01:00
|
|
|
return result
|
|
|
|
|
2019-11-25 22:45:41 +01:00
|
|
|
def _setToken(self, token):
|
2019-11-25 22:19:57 +01:00
|
|
|
# write the token files
|
2023-06-02 16:13:33 +02:00
|
|
|
token_file = open(xbmcvfs.translatePath(utils.data_dir() + self.TOKEN_FILE), 'w')
|
|
|
|
|
|
|
|
token_file.write(json.dumps({"access_token": token.access_token, "refresh_token": token.refresh_token, "expiration": str(token.expires_at)}))
|
2017-01-31 15:08:00 +01:00
|
|
|
token_file.close()
|
|
|
|
|
|
|
|
def _getToken(self):
|
2023-06-02 16:13:33 +02:00
|
|
|
result = {}
|
2019-11-25 22:19:57 +01:00
|
|
|
# get token, if it exists
|
2023-06-02 16:13:33 +02:00
|
|
|
if(xbmcvfs.exists(xbmcvfs.translatePath(utils.data_dir() + self.TOKEN_FILE))):
|
|
|
|
token_file = open(xbmcvfs.translatePath(utils.data_dir() + self.TOKEN_FILE))
|
2017-12-04 00:32:21 +01:00
|
|
|
token = token_file.read()
|
2023-06-02 16:13:33 +02:00
|
|
|
|
|
|
|
if(token.strip() != ""):
|
|
|
|
result = json.loads(token)
|
|
|
|
# convert expiration back to a datetime object
|
|
|
|
result['expiration'] = datetime.strptime(result['expiration'], "%Y-%m-%d %H:%M:%S.%f")
|
|
|
|
|
2017-01-31 15:08:00 +01:00
|
|
|
token_file.close()
|
|
|
|
|
2023-06-02 16:13:33 +02:00
|
|
|
return result
|
2019-11-25 22:33:34 +01:00
|
|
|
|
2017-01-31 15:08:00 +01:00
|
|
|
def _deleteToken(self):
|
2023-06-02 16:13:33 +02:00
|
|
|
if(xbmcvfs.exists(xbmcvfs.translatePath(utils.data_dir() + self.TOKEN_FILE))):
|
|
|
|
xbmcvfs.delete(xbmcvfs.translatePath(utils.data_dir() + self.TOKEN_FILE))
|