diff --git a/script.module.dropbox_auth/LICENSE.txt b/script.module.dropbox_auth/LICENSE.txt new file mode 100644 index 000000000..aeba2b6e9 --- /dev/null +++ b/script.module.dropbox_auth/LICENSE.txt @@ -0,0 +1,20 @@ +Copyright (c) 2016-2020 Moritz Schappler + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/script.module.dropbox_auth/addon.xml b/script.module.dropbox_auth/addon.xml new file mode 100644 index 000000000..11d5e6b88 --- /dev/null +++ b/script.module.dropbox_auth/addon.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + Dropbox Auth API + Provide Dropbox Authentification + all + MIT + https://github.com/SchapplM/xbmc-addon-dropboxauth + + diff --git a/script.module.dropbox_auth/authenticate.py b/script.module.dropbox_auth/authenticate.py new file mode 100644 index 000000000..f9e3c4f3a --- /dev/null +++ b/script.module.dropbox_auth/authenticate.py @@ -0,0 +1,121 @@ +# This script should be called in the settings dialog of other addons that use the dropbox API. +# example (from settings.xml): +# +# +# This script authorizes with dropbox by using the given App key (has to be requested at dropbox) and the app secret. +# The registration token will be written back to the settings of the calling addon (with given id and settings name) + +import xbmc, xbmcgui, xbmcaddon, xbmcvfs +import os, sys +from dropbox import DropboxOAuth2FlowNoRedirect + +# PIL needed for QR code generation (source code from qr-code.py from service.linuxwhatelse.notify) +''' +The QR-Code module used need the PIL (Python Image Library) to draw +the image. On some platforms (like android) PIL isn't available so +we check for the availability of this module and in case it is not +available we show a notification informing the user about it +''' +try: + import PIL + PIL_AVAILABLE = True +except ImportError: + PIL_AVAILABLE = False +import qrcode + +import resources.utils as utils + + +# parse input arguments +if len(sys.argv) == 5:# + ADDON_TARGET_ID = sys.argv[1] # id of the calling addon + SETTINGNAME_TARGET = sys.argv[2] # name of the settings field where the output is written to + DROPBOX_APP_KEY = sys.argv[3] + DROPBOX_APP_SECRET = sys.argv[4] +else: + utils.log('expecting 5 input arguments for Target Addon Id, Setting Name, Dropbox App key and secret. Received %d:' % len(sys.argv), xbmc.LOGERROR) + utils.log(str(sys.argv), xbmc.LOGINFO) + utils.showNotification(utils.getString(32102), utils.getString(32202)) + sys.exit(1) + + +# Define a class for the Dialog to show the URL +class MyClass(xbmcgui.WindowDialog): + # Opening a xbmcgui.Window does not work, since the open settings dialog prevents this (http://forum.kodi.tv/showthread.php?tid=262100&pid=2263074#pid2263074) + # Use xbmcgui.WindowDiaolog to be able to show the QR-code image + def __init__(self, authorize_url): + + # save window resolution to arrange the text fields an QR code + screenx = self.getWidth() + screeny = self.getHeight() + utils.log('Screen resolution: %dx%d' % (screenx, screeny), xbmc.LOGDEBUG) + # Show Dialog with Dropbox Authorization URL + + res_qr_code = [0,0] # resolution of the QR-code image. + # Show QR-Code Dropbox Authorization URL (source code from qr-code.py from service.linuxwhatelse.notify) + if PIL_AVAILABLE: + tmp_dir = os.path.join(utils.data_dir()) # tmp_dir has to exist + tmp_file = os.path.join(tmp_dir, 'dropbox-auth-qr-code.png') + # Create the QR-code image and save it to temp direcotry + qr = qrcode.main.QRCode(box_size=40, border=2) + qr.add_data(authorize_url) + qr.make(fit=True) + img = qr.make_image() + img.save(tmp_file) + # Show the QR-Code in Kodi + # http://www.programcreek.com/python/example/84322/xbmcgui.getCurrentWindowId + utils.log('Add control image with %dx%d at (%d,%d)' % (screeny/2, screeny/2, 100, 100), xbmc.LOGDEBUG) + res_qr_code = [int(screeny/4), int(screeny/4)] # TODO: the image is displayed bigger than the desired size. Find out why. + image = xbmcgui.ControlImage(100, 100, res_qr_code[0], res_qr_code[1], tmp_file) + self.addControl(image) + else: + # The PIL module isn't available so we inform the user about it + utils.showNotification(utils.getString(32102), utils.getString(32201)) + + # Print the Information text below the QR code + self.addControl(xbmcgui.ControlLabel(x=100, y=(100+res_qr_code[1]+ 50), width=screenx, height=25, label=utils.getString(32704), textColor='0xFFFFFFFF')) + self.addControl(xbmcgui.ControlLabel(x=100, y=(100+res_qr_code[1]+100), width=screenx, height=25, label=authorize_url, textColor='0xFFFFFFFF')) + self.addControl(xbmcgui.ControlLabel(x=100, y=(100+res_qr_code[1]+150), width=screenx, height=25, label=utils.getString(32705), textColor='0xFFFFFFFF')) + + # Also print the text to the log file for manual use + utils.log('Open the following URL: %s' % authorize_url) + + # this shows the window on the screen + self.show() + + def onAction(self, action): + # the window will be closed with any key + self.close() + + +utils.log('Starting Dropbox authentification with key %s and secret %s' % (DROPBOX_APP_KEY, DROPBOX_APP_SECRET), xbmc.LOGDEBUG) +# start dropbox authentification +flow = DropboxOAuth2FlowNoRedirect(DROPBOX_APP_KEY, DROPBOX_APP_SECRET) +authorize_url = flow.start() +# display URL +mydisplay = MyClass(authorize_url) +mydisplay.doModal() +del mydisplay + +# Open dialog to input the confirmation code. +dialog = xbmcgui.Dialog() +code = dialog.input(utils.getString(32703), type=xbmcgui.INPUT_ALPHANUM).strip() + +if code == '': + # empty code, aborted + utils.log('Entered an empty authorization code. Abort.', xbmc.LOGDEBUG) + sys.exit(0); + +# finish authentification by sending the code to dropbox +try: + token = flow.finish(code).access_token +except Exception as e: + dialog.ok(utils.getString(32103), utils.getString(32706)+": " + str(e)) + sys.exit(1); + +# positive notification +utils.showNotification(utils.getString(32103), utils.getString(32707)) + +# return the token to the calling script. That means writing the token in the pre-defined settings field +__Addon_Target = xbmcaddon.Addon(ADDON_TARGET_ID) +__Addon_Target.setSetting(SETTINGNAME_TARGET,token) diff --git a/script.module.dropbox_auth/resources/language/resource.language.de_de/strings.po b/script.module.dropbox_auth/resources/language/resource.language.de_de/strings.po new file mode 100644 index 000000000..444a43b09 --- /dev/null +++ b/script.module.dropbox_auth/resources/language/resource.language.de_de/strings.po @@ -0,0 +1,58 @@ +# XBMC Media Center language file +# Addon Name: Dropbox Auth +# Addon id: script.module.dropbox_auth +# Addon version: 1.0.0 +# Addon Provider: schapplm +msgid "" +msgstr "" +"Project-Id-Version: XBMC-Addons\n" +"Report-Msgid-Bugs-To: http://trac.xbmc.org/\n" +"POT-Creation-Date: 2017-11-20 22:00+0400\n" +"PO-Revision-Date: 2017-11-20 22:00+0400\n" +"Last-Translator: Moritz Schappler \n" +"Language-Team: LANGUAGE\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: de\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" + +msgctxt "32101" +msgid "Dropbox" +msgstr "Dropbox" + +msgctxt "32102" +msgid "Dropbox: Error" +msgstr "Dropbox: Fehler" + +msgctxt "32103" +msgid "Dropbox: Setup" +msgstr "Dropbox: Konfiguration" + +msgctxt "32201" +msgid "Python Image Library for QR code not available" +msgstr "Python Image Library für QR-Code-Erzeugung nicht verfügbar" + +msgctxt "32202" +msgid "Wrong input arguments" +msgstr "Falsche Anzahl an Eingabeargumenten" + +msgctxt "32703" +msgid "Dropbox authorization Code" +msgstr "Dropbox Bestätigungscode" + +msgctxt "32704" +msgid "Open the following URL by scanning the QR-Code or by typing it manually" +msgstr "Öffnen Sie die folgende URL durch Scannen des QR-Codes oder abtippen" + +msgctxt "32705" +msgid "Press any key to close the QR-Code and continue to enter your the authorization code" +msgstr "Drücken Sie eine beliebige Taste zum Schließen dieses Fensters und anschließender Eingabe des Bestätigungscodes" + +msgctxt "32706" +msgid "Unable to authorize with Dropbox" +msgstr "Autorisierung mit Dropbox nicht möglich" + +msgctxt "32707" +msgid "Dropbox successfully authorized" +msgstr "Autorisierung mit Dropbox erfolgreich abgeschlossen" diff --git a/script.module.dropbox_auth/resources/language/resource.language.en_gb/strings.po b/script.module.dropbox_auth/resources/language/resource.language.en_gb/strings.po new file mode 100644 index 000000000..f0c075dec --- /dev/null +++ b/script.module.dropbox_auth/resources/language/resource.language.en_gb/strings.po @@ -0,0 +1,58 @@ +# XBMC Media Center language file +# Addon Name: Dropbox Auth +# Addon id: script.module.dropbox_auth +# Addon version: 1.0.0 +# Addon Provider: schapplm +msgid "" +msgstr "" +"Project-Id-Version: XBMC-Addons\n" +"Report-Msgid-Bugs-To: http://trac.xbmc.org/\n" +"POT-Creation-Date: 2017-11-20 22:00+0400\n" +"PO-Revision-Date: 2017-11-20 22:00+0400\n" +"Last-Translator: FULL NAME \n" +"Language-Team: English\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: en\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" + +msgctxt "#32101" +msgid "Dropbox" +msgstr "" + +msgctxt "#32102" +msgid "Dropbox: Error" +msgstr "" + +msgctxt "#32103" +msgid "Dropbox: Setup" +msgstr "" + +msgctxt "#32201" +msgid "Python Image Library for QR code not available" +msgstr "" + +msgctxt "#32202" +msgid "Wrong input arguments" +msgstr "" + +msgctxt "#32703" +msgid "Dropbox authorization Code" +msgstr "" + +msgctxt "#32704" +msgid "Open the following URL by scanning the QR-Code or by typing it manually" +msgstr "" + +msgctxt "#32705" +msgid "Press any key to close the QR-Code and continue to enter your the authorization code" +msgstr "" + +msgctxt "#32706" +msgid "Unable to authorize with Dropbox" +msgstr "" + +msgctxt "#32707" +msgid "Dropbox successfully authorized" +msgstr "" diff --git a/script.module.dropbox_auth/resources/utils.py b/script.module.dropbox_auth/resources/utils.py new file mode 100644 index 000000000..03f82e057 --- /dev/null +++ b/script.module.dropbox_auth/resources/utils.py @@ -0,0 +1,53 @@ +""" +This file contains additional utility functions +""" +import xbmc, xbmcgui, xbmcvfs, xbmcaddon +import os +import sys + +__addon_id__= u'script.module.dropbox_auth' +__Addon = xbmcaddon.Addon(__addon_id__) + + +def data_dir(): + """"get user data directory of this addon. + according to http://wiki.xbmc.org/index.php?title=Add-on_Rules#Requirements_for_scripts_and_plugins + """ + __datapath__ = xbmcvfs.translatePath( __Addon.getAddonInfo('profile') ) + if not xbmcvfs.exists(__datapath__): + xbmcvfs.mkdir(__datapath__) + return __datapath__ + +def addon_dir(): + """"get source directory of this addon. + according to http://wiki.xbmc.org/index.php?title=Add-on_Rules#Requirements_for_scripts_and_plugins + """ + return __Addon.getAddonInfo('path') + +def log(message,loglevel=xbmc.LOGDEBUG): + """"save message to kodi.log. + + Args: + message: has to be unicode, http://wiki.xbmc.org/index.php?title=Add-on_unicode_paths#Logging + loglevel: xbmc.LOGDEBUG, xbmc.LOGINFO, xbmc.LOGWARNING, xbmc.LOGERROR, xbmc.LOGFATAL + """ + xbmc.log(__addon_id__ + u": " + message, level=loglevel) + + +def showNotification(title,message, showtime=4000): + """Show Notification + + Args: + title: has to be unicode + message: has to be unicode + time: Time that the message is beeing displayed + """ + __addoniconpath__ = os.path.join(addon_dir(), "icon.png") + log(u'Notification. %s: %s' % (title, message)) + xbmcgui.Dialog().notification(title, message, __addoniconpath__, showtime) + + +def getString(string_id): + # return a localized string from resources/language/*.po + # The returned string is unicode + return __Addon.getLocalizedString(string_id)