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
+
+
+
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)