From 8b8afacaea04cb9776af8fb9ec2ff961af99c516 Mon Sep 17 00:00:00 2001
From: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com>
Date: Mon, 3 Aug 2020 15:32:24 -0700
Subject: [PATCH] Add function to delete exported files
---
.../default/js/tables/export_table.js | 37 +++++++++++++---
data/interfaces/default/library.html | 1 +
data/interfaces/default/settings.html | 6 +++
plexpy/database.py | 5 +++
plexpy/exporter.py | 42 ++++++++++++++++++-
plexpy/webserve.py | 34 ++++++++++++++-
6 files changed, 116 insertions(+), 9 deletions(-)
diff --git a/data/interfaces/default/js/tables/export_table.js b/data/interfaces/default/js/tables/export_table.js
index 0054048e..9121f149 100644
--- a/data/interfaces/default/js/tables/export_table.js
+++ b/data/interfaces/default/js/tables/export_table.js
@@ -50,7 +50,7 @@ export_table_options = {
$(td).html(cellData);
}
},
- "width": "7%",
+ "width": "8%",
"className": "no-wrap"
},
{
@@ -61,7 +61,7 @@ export_table_options = {
$(td).html(cellData);
}
},
- "width": "7%",
+ "width": "8%",
"className": "no-wrap"
},
{
@@ -72,7 +72,7 @@ export_table_options = {
$(td).html(cellData);
}
},
- "width": "7%",
+ "width": "8%",
"className": "no-wrap"
},
{
@@ -83,7 +83,7 @@ export_table_options = {
$(td).html(cellData);
}
},
- "width": "55%",
+ "width": "50%",
"className": "no-wrap"
},
{
@@ -98,7 +98,17 @@ export_table_options = {
$(td).html('');
}
},
- "width": "7%"
+ "width": "8%",
+ "className": "export_download"
+ },
+ {
+ "targets": [6],
+ "data": null,
+ "createdCell": function (td, cellData, rowData, row, col) {
+ $(td).html('');
+ },
+ "width": "8%",
+ "className": "export_delete"
}
],
"drawCallback": function (settings) {
@@ -117,7 +127,7 @@ export_table_options = {
}
};
-$('.export_table').on('click', '> tbody > tr > td > button.btn-download', function (e) {
+$('.export_table').on('click', '> tbody > tr > td.export_download > button', function (e) {
var tr = $(this).closest('tr');
var row = export_table.row(tr);
var rowData = row.data();
@@ -125,3 +135,18 @@ $('.export_table').on('click', '> tbody > tr > td > button.btn-download', functi
e.preventDefault();
window.location.href = 'download_export?row_id=' + rowData['row_id'];
});
+
+$('.export_table').on('click', '> tbody > tr > td.export_delete > button', function (e) {
+ var tr = $(this).closest('tr');
+ var row = export_table.row(tr);
+ var rowData = row.data();
+
+ var msg = 'Are you sure you want to delete the following export?
' + rowData['filename'] + '';
+ var url = 'delete_export?row_id=' + rowData['row_id'];
+ confirmAjaxCall(url, msg, null, null, redrawExportTable);
+
+});
+
+function redrawExportTable() {
+ export_table.draw();
+}
\ No newline at end of file
diff --git a/data/interfaces/default/library.html b/data/interfaces/default/library.html
index b0a915c6..b0d3847b 100644
--- a/data/interfaces/default/library.html
+++ b/data/interfaces/default/library.html
@@ -339,6 +339,7 @@ DOCUMENTATION :: END
Format |
Filename |
Download |
+ Delete |
diff --git a/data/interfaces/default/settings.html b/data/interfaces/default/settings.html
index 5dfa5169..004294bf 100644
--- a/data/interfaces/default/settings.html
+++ b/data/interfaces/default/settings.html
@@ -2308,6 +2308,12 @@ $(document).ready(function() {
confirmAjaxCall(url, msg);
});
+ $("#clear_exports").click(function () {
+ var msg = 'Are you sure you want to clear the Tautulli metadata exports?';
+ var url = 'delete_export?delete_all=true';
+ confirmAjaxCall(url, msg);
+ });
+
$("#clear_logs").click(function () {
var msg = 'Are you sure you want to clear the Tautulli logs?';
var url = 'delete_logs';
diff --git a/plexpy/database.py b/plexpy/database.py
index 8b0681e2..073c2c68 100644
--- a/plexpy/database.py
+++ b/plexpy/database.py
@@ -216,6 +216,11 @@ def delete_recently_added():
return clear_table('recently_added')
+def delete_exports():
+ logger.info("Tautulli Database :: Clearing exported items from database.")
+ return clear_table('exports')
+
+
def delete_rows_from_table(table, row_ids):
if row_ids and isinstance(row_ids, str):
row_ids = list(map(helpers.cast_to_int, row_ids.split(',')))
diff --git a/plexpy/exporter.py b/plexpy/exporter.py
index 31125274..78d5e6dd 100644
--- a/plexpy/exporter.py
+++ b/plexpy/exporter.py
@@ -970,6 +970,46 @@ def set_export_complete(export_id):
db.upsert(table_name='exports', key_dict=keys, value_dict=values)
+def delete_export(export_id):
+ db = database.MonitorDatabase()
+ if str(export_id).isdigit():
+ export_data = get_export(export_id=export_id)
+
+ logger.debug("Tautulli Exporter :: Deleting export_id %s from the database.", export_id)
+ result = db.action('DELETE FROM exports WHERE id = ?', args=[export_id])
+
+ if export_data and export_data['exists']:
+ filepath = get_export_filepath(export_data['filename'])
+ logger.debug("Tautulli Exporter :: Deleting exported file from '%s'.", filepath)
+ try:
+ os.remove(filepath)
+ except OSError as e:
+ logger.error("Tautulli Exporter :: Failed to delete exported file '%s': %s", filepath, e)
+ return True
+ else:
+ return False
+
+
+def delete_all_exports():
+ db = database.MonitorDatabase()
+ result = db.select('SELECT filename FROM exports')
+
+ deleted_files = True
+ for row in result:
+ if check_export_exists(row['filename']):
+ filepath = get_export_filepath(row['filename'])
+ try:
+ os.remove(filepath)
+ except OSError as e:
+ logger.error("Tautulli Exporter :: Failed to delete exported file '%s': %s", filepath, e)
+ deleted_files = False
+ break
+
+ if deleted_files:
+ database.delete_exports()
+ return True
+
+
def get_export_datatable(section_id=None, rating_key=None, kwargs=None):
default_return = {'recordsFiltered': 0,
'recordsTotal': 0,
@@ -1004,7 +1044,7 @@ def get_export_datatable(section_id=None, rating_key=None, kwargs=None):
join_evals=[],
kwargs=kwargs)
except Exception as e:
- logger.warn("Tautulli Exporter :: Unable to execute database query for get_export_datatable: %s." % e)
+ logger.warn("Tautulli Exporter :: Unable to execute database query for get_export_datatable: %s.", e)
return default_return
result = query['result']
diff --git a/plexpy/webserve.py b/plexpy/webserve.py
index a2283be8..aecc6282 100644
--- a/plexpy/webserve.py
+++ b/plexpy/webserve.py
@@ -6488,7 +6488,6 @@ class WebInterface(object):
Required parameters:
row_id (int): The row id of the exported file to download
-
Optional parameters:
None
@@ -6517,7 +6516,6 @@ class WebInterface(object):
Required parameters:
row_id (int): The row id of the exported file to download
-
Optional parameters:
None
@@ -6528,3 +6526,35 @@ class WebInterface(object):
result = exporter.get_export(export_id=row_id)
if result and result['complete'] and result['exists']:
serve_download(path=exporter.get_export_filepath(result['filename']), name=result['filename'])
+
+ @cherrypy.expose
+ @cherrypy.tools.json_out()
+ @requireAuth(member_of("admin"))
+ @addtoapi()
+ def delete_export(self, row_id=None, delete_all=False, **kwargs):
+ """ Delete exports from Tautulli.
+
+ ```
+ Required parameters:
+ row_id (int): The row id of the exported file to delete
+
+ Optional parameters:
+ delete_all (bool): 'true' to delete all exported files
+
+ Returns:
+ None
+ ```
+ """
+ if helpers.bool_true(delete_all):
+ result = exporter.delete_all_exports()
+ if result:
+ return {'result': 'success', 'message': 'All exports deleted successfully.'}
+ else:
+ return {'result': 'error', 'message': 'Failed to delete all exports.'}
+
+ else:
+ result = exporter.delete_export(export_id=row_id)
+ if result:
+ return {'result': 'success', 'message': 'Export deleted successfully.'}
+ else:
+ return {'result': 'error', 'message': 'Failed to delete export.'}