diff --git a/data/interfaces/default/settings.html b/data/interfaces/default/settings.html
index bf3b76fb..166999cc 100644
--- a/data/interfaces/default/settings.html
+++ b/data/interfaces/default/settings.html
@@ -2652,13 +2652,9 @@ $(document).ready(function() {
$('#api_key').click(function(){ $('#api_key').select() });
$("#generate_api").click(function() {
- $.get('generateAPI',
- function(data){
- if (data.error != undefined) {
- alert(data.error);
- return;
- }
- $('#api_key').val(data);
+ $.get('generate_api_key',
+ function (apikey) {
+ $('#api_key').val(apikey);
});
});
@@ -3046,41 +3042,52 @@ $(document).ready(function() {
});
$('#api_qr_https').toggle(!(url.startsWith('https')));
- var token = Math.random().toString(36).substr(2, 20);
- var encoded_string = url + '|' + $('#api_key').val() + '|' + token;
- $('#api_qr_string').html(encoded_string);
- $('#api_qr_code').empty().qrcode({
- text: encoded_string
- });
+ $.get('generate_api_key', { device: true }).then(function (token) {
+ var encoded_string = url + '|' + token;
+ $('#api_qr_string').html(encoded_string);
+ $('#api_qr_code').empty().qrcode({
+ text: encoded_string
+ });
- (function poll(){
- verifiedDevice = false;
- setTimeout(function() {
- $.ajax({
- url: 'verify_mobile_device',
- type: 'GET',
- data: { device_token: token },
- success: function(data) {
- if (data.result === 'success') {
- verifiedDevice = true;
- getMobileDevicesTable();
- $('#api-qr-modal').modal('hide');
- showMsg(' ' + data.message, false, true, 5000, false);
- }
- },
- complete: function() {
- if (!(verifiedDevice)) {
- poll();
- }
- },
- timeout: 1000
- });
- }, 1000);
- })();
+ (function poll(){
+ verifiedDevice = false;
+ setTimeout(function() {
+ $.ajax({
+ url: 'verify_mobile_device',
+ type: 'GET',
+ data: { device_token: token },
+ success: function(data) {
+ if (data.result === 'success') {
+ verifiedDevice = true;
+ getMobileDevicesTable();
+ $('#api-qr-modal').modal('hide');
+ showMsg(' ' + data.message, false, true, 5000, false);
+ }
+ },
+ complete: function() {
+ if (!(verifiedDevice)) {
+ poll();
+ }
+ },
+ timeout: 1000
+ });
+ }, 1000);
+ })();
+ });
});
});
$('#api-qr-modal').on('hidden.bs.modal', function () {
+ if (!(verifiedDevice)) {
+ $.ajax({
+ url: 'verify_mobile_device',
+ type: 'GET',
+ data: { cancel: true },
+ success: function(data) {
+ showMsg(' ' + data.message, false, true, 5000, false);
+ }
+ });
+ }
verifiedDevice = true;
})
diff --git a/plexpy/__init__.py b/plexpy/__init__.py
index 3ed46c55..78d0436c 100644
--- a/plexpy/__init__.py
+++ b/plexpy/__init__.py
@@ -36,6 +36,7 @@ import activity_pinger
import config
import database
import logger
+import mobile_app
import notification_handler
import notifiers
import plextv
@@ -165,6 +166,7 @@ def initialize(config_file):
# Add notifier configs to logger blacklist
notifiers.blacklist_logger()
+ mobile_app.blacklist_logger()
# Check if PlexPy has a uuid
if CONFIG.PMS_UUID == '' or not CONFIG.PMS_UUID:
diff --git a/plexpy/api2.py b/plexpy/api2.py
index 82d493c2..40d9a3e9 100644
--- a/plexpy/api2.py
+++ b/plexpy/api2.py
@@ -33,6 +33,7 @@ import plexpy
import config
import database
import logger
+import mobile_app
import plextv
import pmsconnect
@@ -88,7 +89,9 @@ class API2:
elif 'apikey' not in kwargs:
self._api_msg = 'Parameter apikey is required'
- elif kwargs.get('apikey', '') != plexpy.CONFIG.API_KEY:
+ elif (kwargs.get('apikey', '') != plexpy.CONFIG.API_KEY and
+ kwargs.get('apikey', '') != mobile_app.TEMP_DEVICE_TOKEN and
+ not mobile_app.get_mobile_device_by_token(kwargs.get('apikey', ''))):
self._api_msg = 'Invalid apikey'
elif 'cmd' not in kwargs:
@@ -105,7 +108,9 @@ class API2:
# Allow override for the api.
self._api_out_type = kwargs.pop('out_type', 'json')
- if self._api_apikey == plexpy.CONFIG.API_KEY and plexpy.CONFIG.API_ENABLED and self._api_cmd in self._api_valid_methods:
+ if ((self._api_apikey == plexpy.CONFIG.API_KEY or
+ mobile_app.get_mobile_device_by_token(self._api_apikey)) and
+ plexpy.CONFIG.API_ENABLED and self._api_cmd in self._api_valid_methods):
self._api_authenticated = True
self._api_msg = None
self._api_kwargs = kwargs
@@ -341,7 +346,7 @@ class API2:
return data
- def register_device(self, device_id='', device_name='', device_token='', **kwargs):
+ def register_device(self, device_id='', device_name='', **kwargs):
""" Registers the PlexPy Android App for notifications.
```
@@ -350,7 +355,7 @@ class API2:
device_id (str): The OneSignal device id of the PlexPy Android App
Optional parameters:
- device_token (str): The device token to verify QR code scan
+ None
Returns:
None
@@ -366,28 +371,18 @@ class API2:
self._api_result_type = 'error'
return
+ result = mobile_app.add_mobile_device(device_id=device_id,
+ device_name=device_name,
+ device_token=self._api_apikey)
- db = database.MonitorDatabase()
-
- keys = {'device_id': device_id}
- values = {'device_name': device_name,
- 'device_token': device_token}
-
- try:
- result = db.upsert(table_name='mobile_devices', key_dict=keys, value_dict=values)
- except Exception as e:
- logger.warn(u"PlexPy APIv2 :: Failed to register mobile device in the database: %s." % e)
+ if result:
+ self._api_msg = 'Device registration successful.'
+ self._api_result_type = 'success'
+ mobile_app.TEMP_DEVICE_TOKEN = None
+ else:
self._api_msg = 'Device registartion failed: database error.'
self._api_result_type = 'error'
- return
- if result == 'insert':
- logger.info(u"PlexPy APIv2 :: Registered mobile device in the database: %s." % device_name)
- else:
- logger.debug(u"PlexPy APIv2 :: Re-registered mobile device in the database: %s." % device_name)
-
- self._api_msg = 'Device registration successful.'
- self._api_result_type = 'success'
return
def _api_make_md(self):
diff --git a/plexpy/mobile_app.py b/plexpy/mobile_app.py
index 575e2c09..f5bcb885 100644
--- a/plexpy/mobile_app.py
+++ b/plexpy/mobile_app.py
@@ -19,6 +19,9 @@ import helpers
import logger
+TEMP_DEVICE_TOKEN = None
+
+
def get_mobile_devices(device_id=None, device_token=None):
where = where_id = where_token = ''
args = []
@@ -33,19 +36,57 @@ def get_mobile_devices(device_id=None, device_token=None):
args.append(device_token)
where += ' AND '.join([w for w in [where_id, where_token] if w])
- monitor_db = database.MonitorDatabase()
- result = monitor_db.select('SELECT * FROM mobile_devices %s' % where, args=args)
+ db = database.MonitorDatabase()
+ result = db.select('SELECT * FROM mobile_devices %s' % where, args=args)
return result
+def get_mobile_device_by_token(device_token=None):
+ if not device_token:
+ return None
+
+ return get_mobile_devices(device_token=device_token)
+
+
+def add_mobile_device(device_id=None, device_name=None, device_token=None):
+ db = database.MonitorDatabase()
+
+ keys = {'device_id': device_id}
+ values = {'device_name': device_name,
+ 'device_token': device_token}
+
+ try:
+ result = db.upsert(table_name='mobile_devices', key_dict=keys, value_dict=values)
+ except Exception as e:
+ logger.warn(u"PlexPy MobileApp :: Failed to register mobile device in the database: %s." % e)
+ return
+
+ if result == 'insert':
+ logger.info(u"PlexPy MobileApp :: Registered mobile device '%s' in the database." % device_name)
+ else:
+ logger.debug(u"PlexPy MobileApp :: Re-registered mobile device '%s' in the database." % device_name)
+
+ return True
+
+
def delete_mobile_device(device_id=None):
- monitor_db = database.MonitorDatabase()
+ db = database.MonitorDatabase()
if device_id:
- logger.debug(u"PlexPy Notifiers :: Deleting device_id %s from the database." % device_id)
- result = monitor_db.action('DELETE FROM mobile_devices WHERE device_id = ?', args=[device_id])
+ logger.debug(u"PlexPy MobileApp :: Deleting device_id %s from the database." % device_id)
+ result = db.action('DELETE FROM mobile_devices WHERE device_id = ?', args=[device_id])
return True
else:
return False
+
+def blacklist_logger():
+ devices = get_mobile_devices()
+
+ blacklist = []
+
+ for d in devices:
+ blacklist.append(d['device_token'])
+
+ logger._BLACKLIST_WORDS.extend(blacklist)
diff --git a/plexpy/notifiers.py b/plexpy/notifiers.py
index 47000732..7b03f68f 100644
--- a/plexpy/notifiers.py
+++ b/plexpy/notifiers.py
@@ -375,8 +375,8 @@ def get_notifiers(notifier_id=None, notify_action=None):
args.append(1)
where += ' AND '.join([w for w in [where_id, where_action] if w])
- monitor_db = database.MonitorDatabase()
- result = monitor_db.select('SELECT id, agent_id, agent_name, agent_label, friendly_name, %s FROM notifiers %s'
+ db = database.MonitorDatabase()
+ result = db.select('SELECT id, agent_id, agent_name, agent_label, friendly_name, %s FROM notifiers %s'
% (', '.join(notify_actions), where), args=args)
for item in result:
@@ -386,11 +386,11 @@ def get_notifiers(notifier_id=None, notify_action=None):
def delete_notifier(notifier_id=None):
- monitor_db = database.MonitorDatabase()
+ db = database.MonitorDatabase()
if str(notifier_id).isdigit():
logger.debug(u"PlexPy Notifiers :: Deleting notifier_id %s from the database." % notifier_id)
- result = monitor_db.action('DELETE FROM notifiers WHERE id = ?',
+ result = db.action('DELETE FROM notifiers WHERE id = ?',
args=[notifier_id])
return True
else:
@@ -404,8 +404,8 @@ def get_notifier_config(notifier_id=None):
logger.error(u"PlexPy Notifiers :: Unable to retrieve notifier config: invalid notifier_id %s." % notifier_id)
return None
- monitor_db = database.MonitorDatabase()
- result = monitor_db.select_single('SELECT * FROM notifiers WHERE id = ?',
+ db = database.MonitorDatabase()
+ result = db.select_single('SELECT * FROM notifiers WHERE id = ?',
args=[notifier_id])
if not result:
@@ -466,10 +466,10 @@ def add_notifier_config(agent_id=None, **kwargs):
values[a['name'] + '_subject'] = a['subject']
values[a['name'] + '_body'] = a['body']
- monitor_db = database.MonitorDatabase()
+ db = database.MonitorDatabase()
try:
- monitor_db.upsert(table_name='notifiers', key_dict=keys, value_dict=values)
- notifier_id = monitor_db.last_insert_id()
+ db.upsert(table_name='notifiers', key_dict=keys, value_dict=values)
+ notifier_id = db.last_insert_id()
logger.info(u"PlexPy Notifiers :: Added new notification agent: %s (notifier_id %s)." % (agent['label'], notifier_id))
return notifier_id
except Exception as e:
@@ -514,9 +514,9 @@ def set_notifier_config(notifier_id=None, agent_id=None, **kwargs):
values.update(subject_text)
values.update(body_text)
- monitor_db = database.MonitorDatabase()
+ db = database.MonitorDatabase()
try:
- monitor_db.upsert(table_name='notifiers', key_dict=keys, value_dict=values)
+ db.upsert(table_name='notifiers', key_dict=keys, value_dict=values)
logger.info(u"PlexPy Notifiers :: Updated notification agent: %s (notifier_id %s)." % (agent['label'], notifier_id))
return True
except Exception as e:
@@ -538,8 +538,8 @@ def send_notification(notifier_id=None, subject='', body='', notify_action='', *
def blacklist_logger():
- monitor_db = database.MonitorDatabase()
- notifiers = monitor_db.select('SELECT notifier_config FROM notifiers')
+ db = database.MonitorDatabase()
+ notifiers = db.select('SELECT notifier_config FROM notifiers')
blacklist = []
blacklist_keys = [w.lstrip('_') for w in _BLACKLIST_KEYS]
@@ -554,17 +554,6 @@ def blacklist_logger():
logger._BLACKLIST_WORDS.extend(blacklist)
-def delete_mobile_device(device_id=None):
- monitor_db = database.MonitorDatabase()
-
- if device_id:
- logger.debug(u"PlexPy Notifiers :: Deleting device_id %s from the database." % device_id)
- result = monitor_db.action('DELETE FROM mobile_devices WHERE device_id = ?', [device_id])
- return True
- else:
- return False
-
-
class PrettyMetadata(object):
def __init__(self, parameters):
self.parameters = parameters
@@ -692,7 +681,7 @@ class ANDROIDAPP(Notifier):
return
# Check mobile device is still registered
- if self.config['device_id'] and not mobile_app.get_mobile_devices(device_id=self.config['device_id']):
+ if not mobile_app.get_mobile_devices(device_id=self.config['device_id']):
logger.warn(u"PlexPy Notifiers :: Unable to send Android app notification: device not registered.")
return
@@ -867,8 +856,8 @@ class BROWSER(Notifier):
if not self.config['enabled']:
return
- monitor_db = database.MonitorDatabase()
- result = monitor_db.select('SELECT subject_text, body_text FROM notify_log '
+ db = database.MonitorDatabase()
+ result = db.select('SELECT subject_text, body_text FROM notify_log '
'WHERE agent_id = 17 AND timestamp >= ? ',
args=[time.time() - 3])
diff --git a/plexpy/webserve.py b/plexpy/webserve.py
index bb5e7227..5cd3379f 100644
--- a/plexpy/webserve.py
+++ b/plexpy/webserve.py
@@ -3204,9 +3204,14 @@ class WebInterface(object):
@cherrypy.expose
@cherrypy.tools.json_out()
@requireAuth(member_of("admin"))
- def verify_mobile_device(self, device_token='', **kwargs):
- result = mobile_app.get_mobile_devices(device_token=device_token)
+ def verify_mobile_device(self, device_token='', cancel=False, **kwargs):
+ if cancel == 'true':
+ mobile_app.TEMP_DEVICE_TOKEN = None
+ return {'result': 'error', 'message': 'Device registration cancelled.'}
+
+ result = mobile_app.get_mobile_device_by_token(device_token)
if result:
+ mobile_app.TEMP_DEVICE_TOKEN = None
return {'result': 'success', 'message': 'Device registered successfully.', 'data': result}
else:
return {'result': 'error', 'message': 'Device not registered.'}
@@ -3421,10 +3426,16 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_server_pref.")
@cherrypy.expose
+ @cherrypy.tools.json_out()
@requireAuth(member_of("admin"))
- def generateAPI(self, **kwargs):
+ def generate_api_key(self, device=None, **kwargs):
apikey = hashlib.sha224(str(random.getrandbits(256))).hexdigest()[0:32]
logger.info(u"New API key generated.")
+ logger._BLACKLIST_WORDS.append(apikey)
+
+ if device == 'true':
+ mobile_app.TEMP_DEVICE_TOKEN = apikey
+
return apikey
@cherrypy.expose