Пример #1
0
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
Пример #2
0
def channel_end(channel_id):
    from .models import Channel, ChannelProc
    logger.info("Closing channel with id {0}".format(channel_id))

    channel = Channel.objects.get(pk=channel_id)

    try:
        channel_proc = ChannelProc.objects.get(channel=channel)
        try:
            proc = psutil.Process(channel_proc.pid)
            proc.kill()
        except psutil.NoSuchProcess:
            logger.warning(
                "Channel proc with pid {0} does not exist"
                .format(channel_proc.pid)
            )
        channel_proc.delete()
    except ChannelProc.DoesNotExist:
        logger.warning(
            "There's no proc info for channel with id {0}"
            .format(channel_id)
        )

    logger.info("Closed channel with id {0}".format(channel_id))

    return
Пример #3
0
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
Пример #4
0
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
Пример #5
0
def check_channels():
    from .models import Channel
    logger.info("Checking status of all channels")
    channel_list = Channel.objects.all()
    logger.info("{0} channels to check".format(channel_list.count()))
    for channel in channel_list:
        manage_channel_proc.delay(channel.pk, False)
    return
Пример #6
0
def mount_start(mount_id):
    from .models import Mount, MountProc
    logger.info("Starting mount with id {0}".format(mount_id))

    mount = Mount.objects.get(pk=mount_id)

    init_proc = subprocess.Popen([
      LIQUIDSOAP_BIN_PATH,
      LS_MOUNT_SCRIPT,
      "--",
      str(mount_id),
      str(SWR_API_ROOT),
      ])
    logger.info("Started mount with id {0}".format(mount_id))
    logger.info(
        "Storing init_proc info for mount with id {0}".format(mount_id)
        )

    proc = psutil.Process(init_proc.pid)

    mount_proc = MountProc()
    mount_proc.mount = mount
    mount_proc.pid = init_proc.pid
    mount_proc.hash = (hash(proc))
    mount_proc.save()
    logger.info(
        "Stored init_proc info for mount with id {0}".format(mount_id)
        )

    return
Пример #7
0
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
Пример #8
0
def check_programmation():
    from .models import Program

    logger.info("Checking programs")

    now = timezone.localtime(timezone.now()) + TIME_AHEAD
    future = (now + PROGRAMMING_TIMEDELTA)
    need_programming = Program.objects.filter(
        channel__enabled=True,
        start__gte=now,
        start__lt=future
        )
    for program in need_programming:
        program_start.delay(program.pk)

    logger.info("Checked programmations")
    return
Пример #9
0
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
Пример #10
0
def channel_notify_save(channel_id):
    from .models import Channel

    logger.info(
        "Notifying save to channel with id {0}"
        .format(channel_id)
    )

    try:
        channel = Channel.objects.get(pk=channel_id)

        sck = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)

        sck.connect(LS_SOCKET_BASE_CHANNEL_PATH.format(channel.pk))

        sck.send(LSTN_CMD_NOTIFY_SAVE.encode(encoding='utf_8'))
        sck.send(LSTN_CMD_EXIT.encode(encoding="utf_8"))

        sck.close()

        logger.info(
            "Notified save to channel with id {0}"
            .format(channel_id)
        )
    except Channel.DoesNotExist:
        logger.info(
            "Channel with id {0} does not exist"
            .format(channel_id)
        )

    return
Пример #11
0
def media_check():
    from sources.models import FileSource, FolderSource, RecordingSource,\
        PodcastSource
    logger.info("Checking media files")

    # Recordings to recording_capture
    # This check goes first because the recordings need to be launched
    now = timezone.localtime(timezone.now()) + TIME_AHEAD
    future = (now + MEDIA_CHECK_TIMEDELTA)
    need_record_set = RecordingSource.objects.filter(
        start__gte=now,
        start__lt=future
        )
    for recording in need_record_set:
        recording_capture.delay(recording.pk)

    # Check files
    file_set = FileSource.objects.all()
    for file in file_set:
        file_check.delay(file.pk)

    # Check folders
    folder_set = FolderSource.objects.all()
    for folder in folder_set:
        folder_check.delay(folder.pk)

    # Check captured records
    already_recorded_set = RecordingSource.objects.filter(
        start__lt=now)
    for recording in already_recorded_set:
        recording_check.delay(recording.pk)

    # Check podcasts
    podcast_set = PodcastSource.objects.all()
    for podcast in podcast_set:
        podcast_check.delay(podcast.pk)

    return
Пример #12
0
def mount_notify_save(mount_id):
    from .models import Mount

    logger.info(
        "Notifying save to mount with id {0}"
        .format(mount_id)
    )

    mount = Mount.objects.get(pk=mount_id)

    sck = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)

    sck.connect(LS_SOCKET_BASE_MOUNT_PATH.format(mount.pk))

    sck.send(LSTN_CMD_NOTIFY_SAVE.encode(encoding='utf_8'))
    sck.send(LSTN_CMD_EXIT.encode(encoding="utf_8"))

    sck.close()

    logger.info(
        "Notified save to mount with id {0}"
        .format(mount_id)
    )
    return
Пример #13
0
def mount_end(mount_id):
    from .models import Mount, MountProc
    logger.info("Ending mount with id {0}".format(mount_id))
    mount = Mount.objects.get(pk=mount_id)

    try:
        mount_proc = MountProc.objects.get(mount=mount)
        try:
            proc = psutil.Process(mount_proc.pid)
            proc.kill()
        except psutil.NoSuchProcess:
            logger.warning(
                "Mount proc with pid {0} does not exist"
                .format(mount_proc.pid)
            )
        mount_proc.delete()
    except MountProc.DoesNotExist:
        logger.warning(
            "There's no proc info for mount with id {0}"
            .format(mount_id)
        )

    logger.info("Ended mount with id {0}".format(mount_id))
    return
Пример #14
0
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
Пример #15
0
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
Пример #16
0
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