diff --git a/data/interfaces/default/css/tautulli.css b/data/interfaces/default/css/tautulli.css
index ca76687d..5c9c8076 100644
--- a/data/interfaces/default/css/tautulli.css
+++ b/data/interfaces/default/css/tautulli.css
@@ -70,6 +70,7 @@ div.form-control .selectize-input {
background-color: #555;
border-radius: 3px;
transition: background-color .3s;
+ height: 32px !important;
}
.react-selectize.root-node .react-selectize-control,
.selectize-control.form-control .selectize-input {
diff --git a/data/interfaces/default/settings.html b/data/interfaces/default/settings.html
index 3bd177b6..0f45535e 100644
--- a/data/interfaces/default/settings.html
+++ b/data/interfaces/default/settings.html
@@ -1007,12 +1007,19 @@
-
+
+
+ % if config['notify_upload_posters'] in (1, 3):
+
+
+
+ % endif
+
Select where to host Plex images for notifications and newsletters.
@@ -2615,11 +2622,37 @@ $(document).ready(function() {
} else {
$('#cloudinary_upload_options').slideUp();
}
+ var parent;
+ if (upload_val === '1' || upload_val === '3') {
+ parent = $('#notify_upload_posters').parent();
+ if ($('#delete_all_uploads_container').length === 0){
+ parent.addClass('input-group');
+ parent.append(
+ '' +
+ '' +
+ '');
+ }
+ } else {
+ parent = $('#notify_upload_posters').parent();
+ parent.removeClass('input-group');
+ $('#delete_all_uploads_container').remove();
+ }
}
$('#notify_upload_posters').change(function () {
imageUpload();
});
+ $('body').on('click', '#delete_all_uploads', function () {
+ var image_hosting_option = $('#notify_upload_posters').find(':selected');
+ var name = image_hosting_option.text();
+
+ var msg = 'Are you sure you want to delete all uploaded images on ' + name + '?' +
+ '
All previous links to the images will no longer work. This cannot be undone!';
+ var url = 'delete_hosted_images';
+ var data = { service: name, delete_all: true };
+ confirmAjaxCall(url, msg, data, false);
+ });
+
function baseURLSet() {
if ($('#http_base_url').val()) {
$('.base-url-warning').hide();
diff --git a/plexpy/datafactory.py b/plexpy/datafactory.py
index 9dbc24f7..9e971bb6 100644
--- a/plexpy/datafactory.py
+++ b/plexpy/datafactory.py
@@ -1215,52 +1215,64 @@ class DataFactory(object):
monitor_db.upsert(table, key_dict=keys, value_dict=values)
- def delete_img_info(self, rating_key=None, service=None):
+ def delete_img_info(self, rating_key=None, service='', delete_all=False):
monitor_db = database.MonitorDatabase()
- if rating_key:
- service = service or helpers.get_img_service()
+ if not delete_all:
+ service = helpers.get_img_service()
- if service == 'imgur':
- # Delete from Imgur
- query = 'SELECT imgur_title, delete_hash, fallback FROM imgur_lookup ' \
- 'JOIN image_hash_lookup ON imgur_lookup.img_hash = image_hash_lookup.img_hash ' \
- 'WHERE rating_key = ? '
- args = [rating_key]
- results = monitor_db.select(query, args=args)
-
- for imgur_info in results:
- if imgur_info['delete_hash']:
- helpers.delete_from_imgur(delete_hash=imgur_info['delete_hash'],
- img_title=imgur_info['imgur_title'],
- fallback=imgur_info['fallback'])
-
- logger.info(u"Tautulli DataFactory :: Deleting Imgur info for rating_key %s from the database."
- % rating_key)
- result = monitor_db.action('DELETE FROM imgur_lookup WHERE img_hash '
- 'IN (SELECT img_hash FROM image_hash_lookup WHERE rating_key = ?)',
- [rating_key])
-
- elif service == 'cloudinary':
- # Delete from Cloudinary
- helpers.delete_from_cloudinary(rating_key=rating_key)
-
- logger.info(u"Tautulli DataFactory :: Deleting Cloudinary info for rating_key %s from the database."
- % rating_key)
- result = monitor_db.action('DELETE FROM cloudinary_lookup WHERE img_hash '
- 'IN (SELECT img_hash FROM image_hash_lookup WHERE rating_key = ?)',
- [rating_key])
-
- else:
- logger.error(u"Tautulli DataFactory :: Unable to delete hosted images: invalid service '%s' provided."
- % service)
-
- return service
-
- else:
+ if not rating_key and not delete_all:
logger.error(u"Tautulli DataFactory :: Unable to delete hosted images: rating_key not provided.")
return False
+ where = ''
+ args = []
+ log_msg = ''
+ if rating_key:
+ where = 'WHERE rating_key = ?'
+ args = [rating_key]
+ log_msg = ' for rating_key %s' % rating_key
+
+ if service.lower() == 'imgur':
+ # Delete from Imgur
+ query = 'SELECT imgur_title, delete_hash, fallback FROM imgur_lookup ' \
+ 'JOIN image_hash_lookup ON imgur_lookup.img_hash = image_hash_lookup.img_hash %s' % where
+ results = monitor_db.select(query, args=args)
+
+ for imgur_info in results:
+ if imgur_info['delete_hash']:
+ helpers.delete_from_imgur(delete_hash=imgur_info['delete_hash'],
+ img_title=imgur_info['imgur_title'],
+ fallback=imgur_info['fallback'])
+
+ logger.info(u"Tautulli DataFactory :: Deleting Imgur info%s from the database."
+ % log_msg)
+ result = monitor_db.action('DELETE FROM imgur_lookup WHERE img_hash '
+ 'IN (SELECT img_hash FROM image_hash_lookup %s)' % where,
+ args)
+
+ elif service.lower() == 'cloudinary':
+ # Delete from Cloudinary
+ query = 'SELECT cloudinary_title, rating_key, fallback FROM cloudinary_lookup ' \
+ 'JOIN image_hash_lookup ON cloudinary_lookup.img_hash = image_hash_lookup.img_hash %s ' \
+ 'GROUP BY rating_key' % where
+ results = monitor_db.select(query, args=args)
+
+ for cloudinary_info in results:
+ helpers.delete_from_cloudinary(rating_key=cloudinary_info['rating_key'])
+
+ logger.info(u"Tautulli DataFactory :: Deleting Cloudinary info%s from the database."
+ % log_msg)
+ result = monitor_db.action('DELETE FROM cloudinary_lookup WHERE img_hash '
+ 'IN (SELECT img_hash FROM image_hash_lookup %s)' % where,
+ args)
+
+ else:
+ logger.error(u"Tautulli DataFactory :: Unable to delete hosted images: invalid service '%s' provided."
+ % service)
+
+ return service
+
def get_poster_info(self, rating_key='', metadata=None, service=None):
poster_key = ''
if str(rating_key).isdigit():
diff --git a/plexpy/webserve.py b/plexpy/webserve.py
index 5fd77f78..ae902955 100644
--- a/plexpy/webserve.py
+++ b/plexpy/webserve.py
@@ -4250,16 +4250,18 @@ class WebInterface(object):
@cherrypy.tools.json_out()
@requireAuth(member_of("admin"))
@addtoapi()
- def delete_hosted_images(self, rating_key='', service='', **kwargs):
+ def delete_hosted_images(self, rating_key='', service='', delete_all=False, **kwargs):
""" Delete the images uploaded to image hosting services.
```
Required parameters:
+ None
+
+ Optional parameters:
rating_key (int): 1234
(Note: Must be the movie, show, season, artist, or album rating key)
- Optional parameters:
- service (str): imgur or cloudinary
- (Note: Defaults to service in Image Hosting setting)
+ service (str): 'imgur' or 'cloudinary'
+ delete_all (bool): 'true' to delete all images form the service
Returns:
json:
@@ -4268,8 +4270,10 @@ class WebInterface(object):
```
"""
+ delete_all = (delete_all == 'true')
+
data_factory = datafactory.DataFactory()
- result = data_factory.delete_img_info(rating_key=rating_key, service=service)
+ result = data_factory.delete_img_info(rating_key=rating_key, service=service, delete_all=delete_all)
if result:
return {'result': 'success', 'message': 'Deleted hosted images from %s.' % result.capitalize()}