Merge pull request #807 from tcely/patch-10

No more errors for `None` values set in metadata
This commit is contained in:
meeb 2025-03-07 00:31:26 +11:00 committed by GitHub
commit f80e0ce8a2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -810,6 +810,30 @@ class Media(models.Model):
fields = self.METADATA_FIELDS.get(field, {}) fields = self.METADATA_FIELDS.get(field, {})
return fields.get(self.source.source_type, field) return fields.get(self.source.source_type, field)
def get_metadata_first_value(self, iterable, default=None, /):
'''
fetch the first key with a value from metadata
'''
# str is an iterable of characters
# we do not want to look for each character!
if isinstance(iterable, str):
iterable = (iterable,)
for key in tuple(iterable):
# reminder: unmapped fields return the key itself
field = self.get_metadata_field(key)
value = self.loaded_metadata.get(field)
# value can be None because:
# - None was stored at the key
# - the key was not in the dictionary
# either way, we don't want those values
if value is None:
continue
if isinstance(value, str):
return value.strip()
return value
return default
def iter_formats(self): def iter_formats(self):
for fmt in self.formats: for fmt in self.formats:
yield parse_media_format(fmt) yield parse_media_format(fmt)
@ -1026,6 +1050,7 @@ class Media(models.Model):
'uploader': self.uploader, 'uploader': self.uploader,
} }
@property @property
def has_metadata(self): def has_metadata(self):
return self.metadata is not None return self.metadata is not None
@ -1087,6 +1112,7 @@ class Media(models.Model):
except Exception as e: except Exception as e:
return {} return {}
@property @property
def refresh_formats(self): def refresh_formats(self):
data = self.loaded_metadata data = self.loaded_metadata
@ -1121,6 +1147,7 @@ class Media(models.Model):
self.metadata = compact_json self.metadata = compact_json
return True return True
@property @property
def url(self): def url(self):
url = self.URLS.get(self.source.source_type, '') url = self.URLS.get(self.source.source_type, '')
@ -1128,32 +1155,24 @@ class Media(models.Model):
@property @property
def description(self): def description(self):
field = self.get_metadata_field('description') return self.get_metadata_first_value('description', '')
return self.loaded_metadata.get(field, '').strip()
@property @property
def metadata_title(self): def metadata_title(self):
result = '' return self.get_metadata_first_value(('fulltitle', 'title',), '')
for key in ('fulltitle', 'title'):
field = self.get_metadata_field(key)
value = self.loaded_metadata.get(field, '').strip()
if value:
result = value
break
return result
def metadata_published(self, timestamp=None): def metadata_published(self, timestamp=None):
published_dt = None
if timestamp is None: if timestamp is None:
field = self.get_metadata_field('timestamp') timestamp = self.get_metadata_first_value('timestamp')
timestamp = self.loaded_metadata.get(field, None)
if timestamp is not None: if timestamp is not None:
try: try:
timestamp_float = float(timestamp) timestamp_float = float(timestamp)
published_dt = self.posix_epoch + timedelta(seconds=timestamp_float)
except Exception as e: except Exception as e:
log.warn(f'Could not compute published from timestamp for: {self.source} / {self} with "{e}"') log.warn(f'Could not compute published from timestamp for: {self.source} / {self} with "{e}"')
return published_dt pass
else:
return self.posix_epoch + timedelta(seconds=timestamp_float)
return None
@property @property
def slugtitle(self): def slugtitle(self):
@ -1162,8 +1181,7 @@ class Media(models.Model):
@property @property
def thumbnail(self): def thumbnail(self):
field = self.get_metadata_field('thumbnail') return self.get_metadata_first_value('thumbnail', '')
return self.loaded_metadata.get(field, '').strip()
@property @property
def name(self): def name(self):
@ -1172,20 +1190,19 @@ class Media(models.Model):
@property @property
def upload_date(self): def upload_date(self):
field = self.get_metadata_field('upload_date') upload_date_str = self.get_metadata_first_value('upload_date')
try: if not upload_date_str:
upload_date_str = self.loaded_metadata.get(field, '').strip()
except (AttributeError, ValueError) as e:
return None return None
try: try:
return datetime.strptime(upload_date_str, '%Y%m%d') return datetime.strptime(upload_date_str, '%Y%m%d')
except (AttributeError, ValueError) as e: except (AttributeError, ValueError) as e:
return None log.debug(f'Media.upload_date: {self.source} / {self}: strptime: {e}')
pass
return None
@property @property
def metadata_duration(self): def metadata_duration(self):
field = self.get_metadata_field('duration') duration = self.get_metadata_first_value('duration', 0)
duration = self.loaded_metadata.get(field, 0)
try: try:
duration = int(duration) duration = int(duration)
except (TypeError, ValueError): except (TypeError, ValueError):
@ -1201,45 +1218,37 @@ class Media(models.Model):
@property @property
def categories(self): def categories(self):
field = self.get_metadata_field('categories') return self.get_metadata_first_value('categories', list())
return self.loaded_metadata.get(field, [])
@property @property
def rating(self): def rating(self):
field = self.get_metadata_field('rating') return self.get_metadata_first_value('rating', 0)
return self.loaded_metadata.get(field, 0)
@property @property
def votes(self): def votes(self):
field = self.get_metadata_field('upvotes') upvotes = self.get_metadata_first_value('upvotes', 0)
upvotes = self.loaded_metadata.get(field, 0)
if not isinstance(upvotes, int): if not isinstance(upvotes, int):
upvotes = 0 upvotes = 0
field = self.get_metadata_field('downvotes') downvotes = self.get_metadata_first_value('downvotes', 0)
downvotes = self.loaded_metadata.get(field, 0)
if not isinstance(downvotes, int): if not isinstance(downvotes, int):
downvotes = 0 downvotes = 0
return upvotes + downvotes return upvotes + downvotes
@property @property
def age_limit(self): def age_limit(self):
field = self.get_metadata_field('age_limit') return self.get_metadata_first_value('age_limit', 0)
return self.loaded_metadata.get(field, 0)
@property @property
def uploader(self): def uploader(self):
field = self.get_metadata_field('uploader') return self.get_metadata_first_value('uploader', '')
return self.loaded_metadata.get(field, '')
@property @property
def formats(self): def formats(self):
field = self.get_metadata_field('formats') return self.get_metadata_first_value('formats', list())
return self.loaded_metadata.get(field, [])
@property @property
def playlist_title(self): def playlist_title(self):
field = self.get_metadata_field('playlist_title') return self.get_metadata_first_value('playlist_title', '')
return self.loaded_metadata.get(field, '')
@property @property
def filename(self): def filename(self):