diff --git a/data/interfaces/default/notifier_config.html b/data/interfaces/default/notifier_config.html index 2f2db2d6..1d87ca56 100644 --- a/data/interfaces/default/notifier_config.html +++ b/data/interfaces/default/notifier_config.html @@ -253,9 +253,10 @@ return false; }); + % if notifier['agent_name'] == 'facebook': function disableFacebookRequest() { - if ($('#facebook_app_id').val() != '' && $('#facebook_app_secret').val() != '') { $('#facebookStep1').prop('disabled', false); } - else { $('#facebookStep1').prop('disabled', true); } + if ($('#facebook_app_id').val() != '' && $('#facebook_app_secret').val() != '') { $('#facebook_facebookStep1').prop('disabled', false); } + else { $('#facebook_facebookStep1').prop('disabled', true); } } disableFacebookRequest(); $('#facebook_app_id, #facebook_app_secret').on('change', function () { @@ -267,19 +268,62 @@ if ($('#facebook_redirect_uri') && $('#facebook_redirect_uri').val().endsWith('/')) { $('#facebook_redirect_uri').val($('#facebook_redirect_uri').val().slice(0, -1)); } - doAjaxCall('set_notifier_config', $(this), 'tabs', true); - $.get('facebookStep1', function (data) { window.open(data); }) - .done(function () { showMsg(' Confirm Authorization. Check pop-up blocker if no response.', false, true, 3000); }); + + $.ajax({ + url: 'facebookStep1', + data: { + app_id: $('#facebook_app_id').val(), + app_secret: $('#facebook_app_secret').val(), + redirect_uri: $('#facebook_redirect_uri').val(), + }, + cache: false, + async: true, + complete: function (xhr, status) { + var result = $.parseJSON(xhr.responseText); + var msg = result.msg; + if (result.result == 'success') { + showMsg(' ' + msg, false, true, 5000); + window.open(result.url); + check_token = setInterval(retrieve_token, 500); + } else { + showMsg(' ' + msg, false, true, 5000, true); + } + } + }); }); + check_token = null; + function retrieve_token() { + $.ajax({ + url: 'facebook_retrieve_token', + cache: false, + async: true, + complete: function (xhr, status) { + var result = $.parseJSON(xhr.responseText); + var msg = result.msg; + if (result.result == 'success') { + showMsg(' ' + msg, false, true, 5000); + $('#facebook_access_token').val(result.access_token); + clearInterval(check_token) + } else if (result.result == 'error') { + showMsg(' ' + msg, false, true, 5000, true); + clearInterval(check_token) + } + } + }); + } + + % elif notifier['agent_name'] == 'browser': $('#browser_allow_browser').click(function () { PNotify.desktop.permission(); }) + % elif notifier['agent_name'] == 'osx': $('#osxnotifyregister').click(function () { var osx_notify_app = $('#osx_notify_app').val(); $.get('osxnotifyregister', { 'app': osx_notify_app }, function (data) { showMsg(' ' + data, false, true, 3000); }); }) + % endif $('#test_notifier').click(function () { doAjaxCall('set_notifier_config', $(this), 'tabs', true, false, sendTestNotification); diff --git a/data/interfaces/default/settings.html b/data/interfaces/default/settings.html index 93b45137..dc0c3baf 100644 --- a/data/interfaces/default/settings.html +++ b/data/interfaces/default/settings.html @@ -2540,8 +2540,8 @@ $(document).ready(function() { cache: false, async: true, complete: function (xhr, status) { - result = $.parseJSON(xhr.responseText); - msg = result.message; + var result = $.parseJSON(xhr.responseText); + var msg = result.message; $('#add-notifier-modal').modal('hide'); if (result.result == 'success') { showMsg(' ' + msg, false, true, 5000); diff --git a/plexpy/notifiers.py b/plexpy/notifiers.py index 9b6fb10d..bd90226e 100644 --- a/plexpy/notifiers.py +++ b/plexpy/notifiers.py @@ -1022,36 +1022,50 @@ class FACEBOOK(Notifier): 'incl_subject': 1 } - def _get_authorization(self): - return facebook.auth_url(app_id=self.config['app_id'], - canvas_url=self.config['redirect_uri'] + '/facebookStep2', + def _get_authorization(self, app_id='', app_secret='', redirect_uri=''): + # Temporarily store settings in the config so we can retrieve them in Facebook step 2. + # Assume the user won't be requesting authorization for multiple Facebook notifiers at the same time. + plexpy.CONFIG.FACEBOOK_APP_ID = app_id + plexpy.CONFIG.FACEBOOK_APP_SECRET = app_secret + plexpy.CONFIG.FACEBOOK_REDIRECT_URI = redirect_uri + plexpy.CONFIG.FACEBOOK_TOKEN = 'temp' + + return facebook.auth_url(app_id=app_id, + canvas_url=redirect_uri + '/facebookStep2', perms=['user_managed_groups','publish_actions']) - def _get_credentials(self, code): + def _get_credentials(self, code=''): logger.info(u"PlexPy Notifiers :: Requesting access token from Facebook") + app_id = plexpy.CONFIG.FACEBOOK_APP_ID + app_secret = plexpy.CONFIG.FACEBOOK_APP_SECRET + redirect_uri = plexpy.CONFIG.FACEBOOK_REDIRECT_URI + try: # Request user access token api = facebook.GraphAPI(version='2.5') response = api.get_access_token_from_code(code=code, - redirect_uri=self.config['redirect_uri'] + '/facebookStep2', - app_id=self.config['app_id'], - app_secret=self.config['app_secret']) + redirect_uri=redirect_uri + '/facebookStep2', + app_id=app_id, + app_secret=app_secret) access_token = response['access_token'] # Request extended user access token api = facebook.GraphAPI(access_token=access_token, version='2.5') - response = api.extend_access_token(app_id=self.config['app_id'], - app_secret=self.config['app_secret']) - access_token = response['access_token'] + response = api.extend_access_token(app_id=app_id, + app_secret=app_secret) - plexpy.CONFIG.FACEBOOK_TOKEN = access_token - plexpy.CONFIG.write() + plexpy.CONFIG.FACEBOOK_TOKEN = response['access_token'] except Exception as e: logger.error(u"PlexPy Notifiers :: Error requesting Facebook access token: %s" % e) - return False + plexpy.CONFIG.FACEBOOK_TOKEN = '' + + # Clear out temporary config values + plexpy.CONFIG.FACEBOOK_APP_ID = '' + plexpy.CONFIG.FACEBOOK_APP_SECRET = '' + plexpy.CONFIG.FACEBOOK_REDIRECT_URI = '' - return True + return plexpy.CONFIG.FACEBOOK_TOKEN def _post_facebook(self, message=None, attachment=None): if self.config['group_id']: @@ -1114,8 +1128,9 @@ class FACEBOOK(Notifier): Step 4: Click App Review on the left and toggle "make public" to Yes.
\ Step 5: Fill in the PlexPy URL below with the exact same URL from Step 3.
\ Step 6: Fill in the App ID and App Secret below.
\ - Step 7: Click the Request Authorization button below.
\ - Step 8: Fill in your Group ID below.', + Step 7: Click the Request Authorization button below to retrieve your access token.
\ + Step 8: Fill in your Access Token below if it is not filled in automatically.
\ + Step 9: Fill in your Group ID below.', 'input_type': 'help' }, {'label': 'PlexPy URL', @@ -1143,6 +1158,12 @@ class FACEBOOK(Notifier): 'description': 'Request Facebook authorization. (Ensure you allow the browser pop-up).', 'input_type': 'button' }, + {'label': 'Facebook Access Token', + 'value': self.config['access_token'], + 'name': 'facebook_access_token', + 'description': 'Your Facebook access token. Automatically filled in after requesting authorization.', + 'input_type': 'text' + }, {'label': 'Facebook Group ID', 'value': self.config['group_id'], 'name': 'facebook_group_id', diff --git a/plexpy/webserve.py b/plexpy/webserve.py index cdf6e041..c36750c7 100644 --- a/plexpy/webserve.py +++ b/plexpy/webserve.py @@ -3064,23 +3064,48 @@ class WebInterface(object): return None @cherrypy.expose + @cherrypy.tools.json_out() @requireAuth(member_of("admin")) - def facebookStep1(self, **kwargs): + def facebookStep1(self, app_id='', app_secret='', redirect_uri='', **kwargs): cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store" - facebook = notifiers.FACEBOOK() - return facebook._get_authorization() + + facebook_notifier = notifiers.FACEBOOK() + url = facebook_notifier._get_authorization(app_id=app_id, + app_secret=app_secret, + redirect_uri=redirect_uri) + + if url: + return {'result': 'success', 'msg': 'Confirm Authorization. Check pop-up blocker if no response.', 'url': url} + else: + return {'result': 'error', 'msg': 'Failed to retrieve authorization url.'} @cherrypy.expose @requireAuth(member_of("admin")) - def facebookStep2(self, code, **kwargs): + def facebookStep2(self, code='', **kwargs): cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store" + facebook = notifiers.FACEBOOK() - result = facebook._get_credentials(code) - # logger.info(u"result: " + str(result)) - if result: - return "Key verification successful, PlexPy can send notification to Facebook. You may close this page now." + access_token = facebook._get_credentials(code) + + if access_token: + return "Facebook authorization successful. PlexPy can send notification to Facebook. " \ + "Your Facebook access token is:" \ + "
{0}
You may close this page.".format(access_token) else: - return "Unable to verify key" + return "Failed to request authorization from Facebook. Check the PlexPy logs for details.
You may close this page." + + @cherrypy.expose + @cherrypy.tools.json_out() + @requireAuth(member_of("admin")) + def facebook_retrieve_token(self, **kwargs): + if plexpy.CONFIG.FACEBOOK_TOKEN == 'temp': + return {'result': 'waiting'} + elif plexpy.CONFIG.FACEBOOK_TOKEN: + token = plexpy.CONFIG.FACEBOOK_TOKEN + plexpy.CONFIG.FACEBOOK_TOKEN = '' + return {'result': 'success', 'msg': 'Authorization successful.', 'access_token': token} + else: + return {'result': 'error', 'msg': 'Failed to request authorization.'} @cherrypy.expose @requireAuth(member_of("admin"))