#! /usr/bin/env python3 """Provide SoundFile which is used to link between database and file system. File name ========= It tries to parse the file name to get the date of the diffusion of an episode and associate the file with it; We use the following format: yyyymmdd[_n][_][name] Where: 'yyyy' the year of the episode's diffusion; 'mm' the month of the episode's diffusion; 'dd' the day of the episode's diffusion; 'n' the number of the episode (if multiple episodes); 'name' the title of the sound; Sound Quality ============= To check quality of files, call the command sound_quality_check using the parameters given by the setting SOUND_QUALITY. This script requires Sox (and soxi). """ import logging from django.conf import settings as conf from aircox.models import Program, Sound, EpisodeSound logger = logging.getLogger("aircox.commands") __all__ = ("SoundFile",) class SoundFile: """Handle synchronisation between sounds on files and database.""" path = None info = None path_info = None sound = None def __init__(self, path): self.path = path @property def sound_path(self): """Relative path name.""" return self.path.replace(conf.MEDIA_ROOT + "/", "") @property def episode(self): return self.sound and self.sound.episode def sync(self, sound=None, program=None, deleted=False, keep_deleted=False, **kwargs): """Update related sound model and save it.""" if deleted: self.sound = self._on_delete(self.path, keep_deleted) return self.sound program = sound and sound.program or Program.get_from_path(self.path) if program: kwargs["program_id"] = program.pk created = False if not sound: sound, created = Sound.objects.get_or_create(file=self.sound_path, defaults=kwargs) self.sound = sound sound.sync_fs(on_update=True, find_playlist=True) sound.save() if not sound.episodesound_set.all().exists(): self.create_episode_sound(sound) return sound def create_episode_sound(self, sound): episode = sound.find_episode() if episode: # FIXME: position from name item = EpisodeSound( episode=episode, sound=sound, position=episode.episodesound_set.all().count(), broadcast=sound.broadcast ) item.save() def _on_delete(self, path, keep_deleted): sound = None if keep_deleted: if sound := Sound.objects.path(self.path).first(): sound.is_removed = True sound.save(sync=False) elif sound := Sound.objects.path(self.path): sound.delete() return sound