def program_start(program_id): from programs.models import Program from streams.models import Channel logger.info( "Launching program with id {0}" .format(program_id) ) try: program = Program.objects.get(pk=program_id) channel = Channel.objects.get(program=program) sck = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) sck.connect(LS_SOCKET_BASE_CHANNEL_PATH.format(channel.pk)) sck.send( LSTN_CMD_PROGRAM_ADD.format(program_id).encode(encoding='utf_8')) sck.send( LSTN_CMD_EXIT.encode(encoding="utf_8")) sck.close() except Program.DoesNotExist: logger.error( "Program with id {0} does not exist" .format(program_id) ) logger.info( "Launched program with id {0}" .format(program_id) ) return
def recording_capture(recording_source_id): from .models import RecordingSource logger.info( "Starting recording for external source with id {0}" .format(recording_source_id) ) try: recording = RecordingSource.objects.get(pk=recording_source_id) recording.location = create_recording_path(recording) recording.save() subprocess.Popen([ LIQUIDSOAP_BIN_PATH, LS_RECORD_SCRIPT, "--", str(recording_source_id), str(SWR_API_ROOT), ]) logger.info( "Started recording for external source with id {0}" .format(recording_source_id) ) except RecordingSource.DoesNotExist: logger.error( "Recording with id {0} does not exist" .format(recording_source_id) ) return
def podcast_check(podcast_id): from sources.models import PodcastSource logger.info("Checking PodcastSource with id {0}".format(podcast_id)) try: podcast = PodcastSource.objects.get(pk=podcast_id) feed = feedparser.parse(podcast.url) last_entry = feed.entries[0] publish_date = parser.parse(last_entry.published) urls = [] for enclosure in last_entry.enclosures: urls.append(enclosure.href) if ((podcast.last_date is None) or (publish_date > podcast.last_date) or (podcast.last_url not in urls)): download_podcast.delay(podcast_id, last_entry.published, urls[0]) except PodcastSource.DoesNotExist: logger.error( "PodcastSource with id {0} does not exist".format(podcast_id) ) except IndexError: logger.warning( "Feed for PodcastSource with id {0} has no content".format( podcast_id) ) return
def folder_check(folder_id): from .models import FolderSource logger.info("Checking FolderSource with id {0}".format(folder_id)) try: folder_source = FolderSource.objects.get(pk=folder_id) if not location_exists(folder_source.location): logger.error( "FolderSource with id {0} no longer exists".format(folder_id)) folder_source.delete() except FolderSource.DoesNotExist: logger.error( "FolderSource with id {0} does not exist".format(folder_id) ) return
def recording_check(recording_id): from .models import RecordingSource logger.info("Checking RecordingSource with id {0}".format(recording_id)) try: recording_source = RecordingSource.objects.get(pk=recording_id) if (recording_source.location is not None) and \ (not location_exists(recording_source.location)): logger.error( "RecordingSource with id {0} no longer exists".format( recording_id)) recording_source.delete() except RecordingSource.DoesNotExist: logger.error( "RecordingSource with id {0} does not exist".format(recording_id) ) return
def channel_start(channel_id): from .models import Channel, ChannelProc logger.info("Starting channel with id {0}".format(channel_id)) try: channel = Channel.objects.get(pk=channel_id) init_proc = subprocess.Popen([ LIQUIDSOAP_BIN_PATH, LS_CHANNEL_SCRIPT, "--", str(channel_id), str(SWR_API_ROOT), ]) logger.info("Started channel with id {0}".format(channel_id)) logger.info( "Storing init_proc info " "for channel with id {0}".format(channel_id) ) proc = psutil.Process(init_proc.pid) channel_proc = ChannelProc() channel_proc.channel = channel channel_proc.pid = init_proc.pid channel_proc.hash = (hash(proc)) channel_proc.save() logger.info( "Stored init_proc info " "for channel with id {0}".format(channel_id) ) except Channel.DoesNotExist: logger.error( "Channel with id {0} does not exist" .format(channel_id) ) return
def manage_mount_proc(mount_id, is_post_save): from .models import Mount, MountProc logger.info("Managing status of mount with id {0}".format(mount_id)) try: # Recover mount info mount = Mount.objects.get(pk=mount_id) mount_proc = None try: mount_proc = MountProc.objects.get(mount=mount) except MountProc.DoesNotExist: mount_proc = None # Manage stream status if (mount.channel.enabled): if (mount_proc is None): # Launch mount logger.info( "Launching mount with id {0}".format(mount_id) ) mount_start.delay(mount.pk) else: # Check if mount is running try: proc = psutil.Process(mount_proc.pid) if proc.status() == psutil.STATUS_ZOMBIE: logger.warning( "Mount is not running (zombie process pid {0})" .format(mount_proc.pid) ) mount_proc.delete() mount_start.delay(mount_id) elif hash(proc) != mount_proc.hash: logger.warning( "Mount is not running (diff hash for pid {0})" .format(mount_proc.pid) ) mount_proc.delete() mount_start.delay(mount_id) else: logger.info( "Mount is running with pid {0}" .format(mount_proc.pid) ) if is_post_save: mount_notify_save.delay(mount_id) except psutil.NoSuchProcess: # If it's not running, restart logger.warning( "Mount proc with pid {0} does not exist" .format(mount_proc.pid) ) logger.info( "Restarting mount with id {0}".format(mount_id) ) mount_proc.delete() mount_start.delay(mount_id) elif (not mount.channel.enabled) and (mount_proc is not None): # Close mount logger.info( "Closing mount with id {0}".format(mount_id) ) mount_end.delay(mount.pk) logger.info("Managed status of mount with id {0}".format(mount_id)) except Mount.DoesNotExist: logger.error("Mount with id {0} does not exist".format(mount_id)) return
def manage_channel_proc(channel_id, is_post_save): from .models import Channel, ChannelProc logger.info("Managing status of channel with id {0}".format(channel_id)) try: # Recover channel info channel = Channel.objects.get(pk=channel_id) channel_proc = None try: channel_proc = ChannelProc.objects.get(channel=channel) except ChannelProc.DoesNotExist: channel_proc = None if (channel.enabled): if (channel_proc is None): # Launch channel logger.info( "Launching channel with id {0}".format(channel_id) ) channel_start.delay(channel_id) else: # Check if channel is running try: proc = psutil.Process(channel_proc.pid) if proc.status() == psutil.STATUS_ZOMBIE: logger.warning( "Channel is not running (zombie process pid {0})" .format(channel_proc.pid) ) channel_proc.delete() channel_start.delay(channel_id) elif hash(proc) != channel_proc.hash: logger.warning( "Channel is not running (diff hash for pid {0})" .format(channel_proc.pid) ) channel_proc.delete() channel_start.delay(channel_id) else: logger.info( "Channel is running with pid {0}" .format(channel_proc.pid) ) if is_post_save: channel_notify_save.delay(channel_id) except psutil.NoSuchProcess: # If it's not running, restart logger.warning( "Channel proc with pid {0} does not exist" .format(channel_proc.pid) ) logger.info( "Restarting channel with id {0}".format(channel_id) ) channel_proc.delete() channel_start.delay(channel_id) elif (not channel.enabled) and (channel_proc is not None): # Close channel logger.info( "Closing channel with id {0}".format(channel_id) ) channel_end.delay(channel.pk) for mount in channel.mount_set.all(): manage_mount_proc.delay(mount.pk, is_post_save) logger.info( "Managed status of channel with id {0}".format(channel_id)) except Channel.DoesNotExist: logger.error("Channel with id {0} does not exist".format(channel_id)) return