mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-07 13:41:15 -07:00
Separate export poster and art
This commit is contained in:
parent
0203a1d4dc
commit
6bc7de7a6d
6 changed files with 63 additions and 34 deletions
3
API.md
3
API.md
|
@ -419,7 +419,8 @@ Optional parameters:
|
||||||
file_format (str): 'json' (default) or 'csv'
|
file_format (str): 'json' (default) or 'csv'
|
||||||
metadata_level (int): The level of metadata to export (default 1)
|
metadata_level (int): The level of metadata to export (default 1)
|
||||||
media_info_level (int): The level of media info to export (default 1)
|
media_info_level (int): The level of media info to export (default 1)
|
||||||
include_images (bool): True or False to export artwork and posters images
|
include_thumb (bool): True to export poster/cover images
|
||||||
|
include_art (bool): True to export background artwork images
|
||||||
custom_fields (str): Comma separated list of custom fields to export
|
custom_fields (str): Comma separated list of custom fields to export
|
||||||
in addition to the export level selected
|
in addition to the export level selected
|
||||||
|
|
||||||
|
|
|
@ -70,12 +70,19 @@ DOCUMENTATION :: END
|
||||||
</div>
|
</div>
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" id="export_include_images" name="export_include_images" value="1"> Export artwork and posters
|
<input type="checkbox" id="export_include_thumb" name="export_include_thumb" value="1"> Export poster / cover images
|
||||||
</label>
|
</label>
|
||||||
<p class="help-block">
|
</div>
|
||||||
Enable to export artwork and poster image files. Warning: This will take a long time!<br>
|
<div class="checkbox">
|
||||||
Note: Only applies to movies, shows, seasons, artists, albums, collections, and playlists.
|
<label>
|
||||||
</p>
|
<input type="checkbox" id="export_include_art" name="export_include_art" value="1"> Export background artwork images
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<p class="help-block">
|
||||||
|
Enable to export posters and covers or background artwork image files.<br>
|
||||||
|
Warning: Exporting images may take a long time!<br>
|
||||||
|
Note: Only applies to movies, shows, seasons, artists, albums, collections, and playlists.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -93,7 +100,8 @@ DOCUMENTATION :: END
|
||||||
var metadata_export_level = $('#metadata_export_level_select option:selected').val();
|
var metadata_export_level = $('#metadata_export_level_select option:selected').val();
|
||||||
var media_info_export_level = $('#media_info_export_level_select option:selected').val();
|
var media_info_export_level = $('#media_info_export_level_select option:selected').val();
|
||||||
var file_format = $('#file_format_select option:selected').val();
|
var file_format = $('#file_format_select option:selected').val();
|
||||||
var include_images = $("#export_include_images").is(':checked') ? 1 : 0;
|
var include_thumb = $("#export_include_thumb").is(':checked') ? 1 : 0;
|
||||||
|
var include_art = $("#export_include_art").is(':checked') ? 1 : 0;
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: 'export_metadata',
|
url: 'export_metadata',
|
||||||
|
@ -103,7 +111,8 @@ DOCUMENTATION :: END
|
||||||
metadata_level: metadata_export_level,
|
metadata_level: metadata_export_level,
|
||||||
media_info_level: media_info_export_level,
|
media_info_level: media_info_export_level,
|
||||||
file_format: file_format,
|
file_format: file_format,
|
||||||
include_images: include_images
|
include_thumb: include_thumb,
|
||||||
|
include_art: include_art
|
||||||
},
|
},
|
||||||
async: true,
|
async: true,
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
|
|
|
@ -85,7 +85,7 @@ export_table_options = {
|
||||||
"createdCell": function (td, cellData, rowData, row, col) {
|
"createdCell": function (td, cellData, rowData, row, col) {
|
||||||
if (cellData !== '') {
|
if (cellData !== '') {
|
||||||
var images = '';
|
var images = '';
|
||||||
if (rowData['include_images']) {
|
if (rowData['include_thumb'] || rowData['include_art']) {
|
||||||
images = ' + images';
|
images = ' + images';
|
||||||
}
|
}
|
||||||
$(td).html(cellData + images);
|
$(td).html(cellData + images);
|
||||||
|
|
|
@ -798,7 +798,8 @@ def dbcheck():
|
||||||
'CREATE TABLE IF NOT EXISTS exports (id INTEGER PRIMARY KEY AUTOINCREMENT, '
|
'CREATE TABLE IF NOT EXISTS exports (id INTEGER PRIMARY KEY AUTOINCREMENT, '
|
||||||
'timestamp INTEGER, section_id INTEGER, rating_key INTEGER, media_type TEXT, '
|
'timestamp INTEGER, section_id INTEGER, rating_key INTEGER, media_type TEXT, '
|
||||||
'filename TEXT, file_format TEXT, '
|
'filename TEXT, file_format TEXT, '
|
||||||
'metadata_level INTEGER, media_info_level INTEGER, include_images INTEGER DEFAULT 0, '
|
'metadata_level INTEGER, media_info_level INTEGER, '
|
||||||
|
'include_thumb INTEGER DEFAULT 0, include_art INTEGER DEFAULT 0, '
|
||||||
'custom_fields TEXT, '
|
'custom_fields TEXT, '
|
||||||
'file_size INTEGER DEFAULT 0, complete INTEGER DEFAULT 0)'
|
'file_size INTEGER DEFAULT 0, complete INTEGER DEFAULT 0)'
|
||||||
)
|
)
|
||||||
|
|
|
@ -78,14 +78,16 @@ class Export(object):
|
||||||
MEDIA_INFO_LEVELS = (0, 1, 2, 3, 9)
|
MEDIA_INFO_LEVELS = (0, 1, 2, 3, 9)
|
||||||
|
|
||||||
def __init__(self, section_id=None, rating_key=None, file_format='json',
|
def __init__(self, section_id=None, rating_key=None, file_format='json',
|
||||||
metadata_level=1, media_info_level=1, include_images=False,
|
metadata_level=1, media_info_level=1,
|
||||||
|
include_thumb=False, include_art=False,
|
||||||
custom_fields=''):
|
custom_fields=''):
|
||||||
self.section_id = helpers.cast_to_int(section_id) or None
|
self.section_id = helpers.cast_to_int(section_id) or None
|
||||||
self.rating_key = helpers.cast_to_int(rating_key) or None
|
self.rating_key = helpers.cast_to_int(rating_key) or None
|
||||||
self.file_format = file_format
|
self.file_format = file_format
|
||||||
self.metadata_level = helpers.cast_to_int(metadata_level)
|
self.metadata_level = helpers.cast_to_int(metadata_level)
|
||||||
self.media_info_level = helpers.cast_to_int(media_info_level)
|
self.media_info_level = helpers.cast_to_int(media_info_level)
|
||||||
self.include_images = include_images
|
self.include_thumb = include_thumb
|
||||||
|
self.include_art = include_art
|
||||||
self.custom_fields = custom_fields.replace(' ', '')
|
self.custom_fields = custom_fields.replace(' ', '')
|
||||||
self._custom_fields = {}
|
self._custom_fields = {}
|
||||||
|
|
||||||
|
@ -1420,8 +1422,9 @@ class Export(object):
|
||||||
if self.rating_key:
|
if self.rating_key:
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"Tautulli Exporter :: Export called with rating_key %s, "
|
"Tautulli Exporter :: Export called with rating_key %s, "
|
||||||
"metadata_level %d, media_info_level %d, include_images %s",
|
"metadata_level %d, media_info_level %d, include_thumb %s, include_art %s",
|
||||||
self.rating_key, self.metadata_level, self.media_info_level, self.include_images)
|
self.rating_key, self.metadata_level, self.media_info_level,
|
||||||
|
self.include_thumb, self.include_art)
|
||||||
|
|
||||||
item = plex.get_item(self.rating_key)
|
item = plex.get_item(self.rating_key)
|
||||||
self.media_type = item.type
|
self.media_type = item.type
|
||||||
|
@ -1446,8 +1449,9 @@ class Export(object):
|
||||||
elif self.section_id:
|
elif self.section_id:
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"Tautulli Exporter :: Export called with section_id %s, "
|
"Tautulli Exporter :: Export called with section_id %s, "
|
||||||
"metadata_level %d, media_info_level %d, include_images %s",
|
"metadata_level %d, media_info_level %d, include_thumb %s, include_art %s",
|
||||||
self.section_id, self.metadata_level, self.media_info_level, self.include_images)
|
self.section_id, self.metadata_level, self.media_info_level,
|
||||||
|
self.include_thumb, self.include_art)
|
||||||
|
|
||||||
library = plex.get_library(str(self.section_id))
|
library = plex.get_library(str(self.section_id))
|
||||||
self.media_type = library.type
|
self.media_type = library.type
|
||||||
|
@ -1469,7 +1473,8 @@ class Export(object):
|
||||||
logger.error("Tautulli Exporter :: %s", msg)
|
logger.error("Tautulli Exporter :: %s", msg)
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
self.include_images = self.include_images and self.MEDIA_TYPES[self.media_type]
|
self.include_thumb = self.include_thumb and self.MEDIA_TYPES[self.media_type]
|
||||||
|
self.include_art = self.include_art and self.MEDIA_TYPES[self.media_type]
|
||||||
self._process_custom_fields()
|
self._process_custom_fields()
|
||||||
|
|
||||||
self.filename = '{}.{}'.format(helpers.clean_filename(filename), self.file_format)
|
self.filename = '{}.{}'.format(helpers.clean_filename(filename), self.file_format)
|
||||||
|
@ -1512,7 +1517,8 @@ class Export(object):
|
||||||
'filename': self.filename,
|
'filename': self.filename,
|
||||||
'metadata_level': self.metadata_level,
|
'metadata_level': self.metadata_level,
|
||||||
'media_info_level': self.media_info_level,
|
'media_info_level': self.media_info_level,
|
||||||
'include_images': self.include_images,
|
'include_thumb': self.include_thumb,
|
||||||
|
'include_art': self.include_art,
|
||||||
'custom_fields': self.custom_fields}
|
'custom_fields': self.custom_fields}
|
||||||
|
|
||||||
db = database.MonitorDatabase()
|
db = database.MonitorDatabase()
|
||||||
|
@ -1532,7 +1538,8 @@ class Export(object):
|
||||||
keys = {'id': self.export_id}
|
keys = {'id': self.export_id}
|
||||||
values = {'complete': complete,
|
values = {'complete': complete,
|
||||||
'file_size': self.file_size,
|
'file_size': self.file_size,
|
||||||
'include_images': self.include_images}
|
'include_thumb': self.include_thumb,
|
||||||
|
'include_art': self.include_art}
|
||||||
|
|
||||||
db = database.MonitorDatabase()
|
db = database.MonitorDatabase()
|
||||||
db.upsert(table_name='exports', key_dict=keys, value_dict=values)
|
db.upsert(table_name='exports', key_dict=keys, value_dict=values)
|
||||||
|
@ -1564,8 +1571,12 @@ class Export(object):
|
||||||
self.file_size = os.path.getsize(filepath)
|
self.file_size = os.path.getsize(filepath)
|
||||||
|
|
||||||
if os.path.exists(images_folder):
|
if os.path.exists(images_folder):
|
||||||
self.include_images = True
|
|
||||||
for f in os.listdir(images_folder):
|
for f in os.listdir(images_folder):
|
||||||
|
if self.include_thumb is False and f.endswith('.thumb.jpg'):
|
||||||
|
self.include_thumb = True
|
||||||
|
if self.include_art is False and f.endswith('.art.jpg'):
|
||||||
|
self.include_art = True
|
||||||
|
|
||||||
image_path = os.path.join(images_folder, f)
|
image_path = os.path.join(images_folder, f)
|
||||||
if os.path.isfile(image_path):
|
if os.path.isfile(image_path):
|
||||||
self.file_size += os.path.getsize(image_path)
|
self.file_size += os.path.getsize(image_path)
|
||||||
|
@ -1609,10 +1620,12 @@ class Export(object):
|
||||||
if level <= self.media_info_level:
|
if level <= self.media_info_level:
|
||||||
export_attrs_set.update(attrs)
|
export_attrs_set.update(attrs)
|
||||||
|
|
||||||
if self.include_images:
|
if self.include_thumb:
|
||||||
for image_attr in ('artFile', 'thumbFile'):
|
if 'thumbFile' in media_attrs:
|
||||||
if image_attr in media_attrs:
|
export_attrs_set.add('thumbFile')
|
||||||
export_attrs_set.add(image_attr)
|
if self.include_art:
|
||||||
|
if 'artFile' in media_attrs:
|
||||||
|
export_attrs_set.add('artFile')
|
||||||
|
|
||||||
plural_media_type = self.PLURAL_MEDIA_TYPES.get(media_type)
|
plural_media_type = self.PLURAL_MEDIA_TYPES.get(media_type)
|
||||||
if plural_media_type in self._custom_fields:
|
if plural_media_type in self._custom_fields:
|
||||||
|
@ -1675,7 +1688,7 @@ class Export(object):
|
||||||
|
|
||||||
def get_export(export_id):
|
def get_export(export_id):
|
||||||
db = database.MonitorDatabase()
|
db = database.MonitorDatabase()
|
||||||
result = db.select_single('SELECT filename, file_format, include_images, complete '
|
result = db.select_single('SELECT filename, file_format, include_thumb, include_art, complete '
|
||||||
'FROM exports WHERE id = ?',
|
'FROM exports WHERE id = ?',
|
||||||
[export_id])
|
[export_id])
|
||||||
|
|
||||||
|
@ -1698,7 +1711,7 @@ def delete_export(export_id):
|
||||||
logger.info("Tautulli Exporter :: Deleting exported file from '%s'.", filepath)
|
logger.info("Tautulli Exporter :: Deleting exported file from '%s'.", filepath)
|
||||||
try:
|
try:
|
||||||
os.remove(filepath)
|
os.remove(filepath)
|
||||||
if export_data['include_images']:
|
if export_data['include_thumb'] or export_data['include_art']:
|
||||||
images_folder = get_export_filepath(export_data['filename'], images=True)
|
images_folder = get_export_filepath(export_data['filename'], images=True)
|
||||||
if os.path.exists(images_folder):
|
if os.path.exists(images_folder):
|
||||||
shutil.rmtree(images_folder)
|
shutil.rmtree(images_folder)
|
||||||
|
@ -1711,7 +1724,7 @@ def delete_export(export_id):
|
||||||
|
|
||||||
def delete_all_exports():
|
def delete_all_exports():
|
||||||
db = database.MonitorDatabase()
|
db = database.MonitorDatabase()
|
||||||
result = db.select('SELECT filename, include_images FROM exports')
|
result = db.select('SELECT filename, include_thumb, include_art FROM exports')
|
||||||
|
|
||||||
logger.info("Tautulli Exporter :: Deleting all exports from the database.")
|
logger.info("Tautulli Exporter :: Deleting all exports from the database.")
|
||||||
|
|
||||||
|
@ -1721,7 +1734,7 @@ def delete_all_exports():
|
||||||
filepath = get_export_filepath(row['filename'])
|
filepath = get_export_filepath(row['filename'])
|
||||||
try:
|
try:
|
||||||
os.remove(filepath)
|
os.remove(filepath)
|
||||||
if row['include_images']:
|
if row['include_thumb'] or row['include_art']:
|
||||||
images_folder = get_export_filepath(row['filename'], images=True)
|
images_folder = get_export_filepath(row['filename'], images=True)
|
||||||
if os.path.exists(images_folder):
|
if os.path.exists(images_folder):
|
||||||
shutil.rmtree(images_folder)
|
shutil.rmtree(images_folder)
|
||||||
|
@ -1764,7 +1777,8 @@ def get_export_datatable(section_id=None, rating_key=None, kwargs=None):
|
||||||
'exports.file_format',
|
'exports.file_format',
|
||||||
'exports.metadata_level',
|
'exports.metadata_level',
|
||||||
'exports.media_info_level',
|
'exports.media_info_level',
|
||||||
'exports.include_images',
|
'exports.include_thumb',
|
||||||
|
'exports.include_art',
|
||||||
'exports.custom_fields',
|
'exports.custom_fields',
|
||||||
'exports.file_size',
|
'exports.file_size',
|
||||||
'exports.complete'
|
'exports.complete'
|
||||||
|
@ -1799,7 +1813,8 @@ def get_export_datatable(section_id=None, rating_key=None, kwargs=None):
|
||||||
'file_format': item['file_format'],
|
'file_format': item['file_format'],
|
||||||
'metadata_level': item['metadata_level'],
|
'metadata_level': item['metadata_level'],
|
||||||
'media_info_level': item['media_info_level'],
|
'media_info_level': item['media_info_level'],
|
||||||
'include_images': item['include_images'],
|
'include_thumb': item['include_thumb'],
|
||||||
|
'include_art': item['include_art'],
|
||||||
'custom_fields': item['custom_fields'],
|
'custom_fields': item['custom_fields'],
|
||||||
'file_size': item['file_size'],
|
'file_size': item['file_size'],
|
||||||
'complete': item['complete'],
|
'complete': item['complete'],
|
||||||
|
|
|
@ -6492,7 +6492,8 @@ class WebInterface(object):
|
||||||
@requireAuth(member_of("admin"))
|
@requireAuth(member_of("admin"))
|
||||||
@addtoapi()
|
@addtoapi()
|
||||||
def export_metadata(self, section_id=None, rating_key=None, file_format='json',
|
def export_metadata(self, section_id=None, rating_key=None, file_format='json',
|
||||||
metadata_level=1, media_info_level=1, include_images=False,
|
metadata_level=1, media_info_level=1,
|
||||||
|
include_thumb=False, include_art=False,
|
||||||
custom_fields='', **kwargs):
|
custom_fields='', **kwargs):
|
||||||
""" Export library or media metadata to a file
|
""" Export library or media metadata to a file
|
||||||
|
|
||||||
|
@ -6505,7 +6506,8 @@ class WebInterface(object):
|
||||||
file_format (str): 'json' (default) or 'csv'
|
file_format (str): 'json' (default) or 'csv'
|
||||||
metadata_level (int): The level of metadata to export (default 1)
|
metadata_level (int): The level of metadata to export (default 1)
|
||||||
media_info_level (int): The level of media info to export (default 1)
|
media_info_level (int): The level of media info to export (default 1)
|
||||||
include_images (bool): True or False to export artwork and posters images
|
include_thumb (bool): True to export poster/cover images
|
||||||
|
include_art (bool): True to export background artwork images
|
||||||
custom_fields (str): Comma separated list of custom fields to export
|
custom_fields (str): Comma separated list of custom fields to export
|
||||||
in addition to the export level selected
|
in addition to the export level selected
|
||||||
|
|
||||||
|
@ -6521,7 +6523,8 @@ class WebInterface(object):
|
||||||
file_format=file_format,
|
file_format=file_format,
|
||||||
metadata_level=metadata_level,
|
metadata_level=metadata_level,
|
||||||
media_info_level=media_info_level,
|
media_info_level=media_info_level,
|
||||||
include_images=helpers.bool_true(include_images),
|
include_thumb=helpers.bool_true(include_thumb),
|
||||||
|
include_art=helpers.bool_true(include_art),
|
||||||
custom_fields=custom_fields).export()
|
custom_fields=custom_fields).export()
|
||||||
|
|
||||||
if result is True:
|
if result is True:
|
||||||
|
@ -6602,7 +6605,7 @@ class WebInterface(object):
|
||||||
if result and result['complete'] == 1 and result['exists']:
|
if result and result['complete'] == 1 and result['exists']:
|
||||||
export_filepath = exporter.get_export_filepath(result['filename'])
|
export_filepath = exporter.get_export_filepath(result['filename'])
|
||||||
|
|
||||||
if result['include_images']:
|
if result['include_thumb'] or result['include_art']:
|
||||||
zip_filename = '{}.zip'.format(os.path.splitext(result['filename'])[0])
|
zip_filename = '{}.zip'.format(os.path.splitext(result['filename'])[0])
|
||||||
images_folder = exporter.get_export_filepath(result['filename'], images=True)
|
images_folder = exporter.get_export_filepath(result['filename'], images=True)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue