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.'}