Beispiel #1
0
def _handle_brightness_request(device: str,
                               request: WSGIRequest) -> HttpResponse:
    value, response = extract_value(request.POST)
    assert device in ["ring", "strip", "wled", "screen"]
    storage.put(cast(DeviceBrightness, f"{device}_brightness"), float(value))
    _notify_settings_changed(device)
    return response
Beispiel #2
0
    def __init__(self, manager) -> None:
        super().__init__(manager, "wled")

        self.led_count = storage.get("wled_led_count")

        self.ip = storage.get("wled_ip")
        if not self.ip:
            try:
                device = util.get_devices()[0]
                broadcast = util.broadcast_of_device(device)
                self.ip = broadcast
            except Exception:  # pylint: disable=broad-except
                # we don't want the startup to fail
                # just because the broadcast address could not be determined
                self.ip = "127.0.0.1"
            storage.put("wled_ip", self.ip)
        self.port = storage.get("wled_port")

        self.header = bytes([
            2,  # DRGB protocol, we update every led every frame
            1,  # wait 1 second after the last packet until resuming normally
        ])

        self.initialized = True
        redis.put("wled_initialized", True)
Beispiel #3
0
def set_volume(request: WSGIRequest) -> HttpResponse:
    """Sets the playback volume.
    value has to be a float between 0 and 1."""
    volume, response = extract_value(request.POST)
    _set_volume(float(volume))
    storage.put("volume", float(volume))
    return response
Beispiel #4
0
def set_autoplay(request: WSGIRequest) -> None:
    """Enables or disables autoplay depending on the given value.
    If enabled and the current song is the last one,
    a new song is enqueued, based on the current one."""
    enabled = request.POST.get("value") == "true"
    storage.put("autoplay", enabled)
    playback.handle_autoplay()
Beispiel #5
0
    def setUp(self) -> None:
        super().setUp()
        self._setup_test_library()
        self._add_local_playlist()

        storage.put("interactivity", storage.Interactivity.full_voting)
        self.client.logout()
Beispiel #6
0
def set_wled_port(request: WSGIRequest) -> HttpResponse:
    """Updates the wled port."""
    value, response = extract_value(request.POST)
    if not 1024 <= int(value) <= 65535:
        return HttpResponseBadRequest("invalid port")
    storage.put("wled_port", int(value))
    _notify_settings_changed("wled")
    return response
Beispiel #7
0
def set_wled_led_count(request: WSGIRequest) -> HttpResponse:
    """Updates the wled led_count."""
    value, response = extract_value(request.POST)
    if not 2 <= int(value) <= 490:
        return HttpResponseBadRequest("must be between 2 and 490")
    storage.put("wled_led_count", int(value))
    _notify_settings_changed("wled")
    return response
Beispiel #8
0
def _handle_monochrome_request(device: str,
                               request: WSGIRequest) -> HttpResponse:
    value, response = extract_value(request.POST)
    assert device in ["ring", "strip", "wled", "screen"]
    storage.put(cast(DeviceMonochrome, f"{device}_monochrome"),
                strtobool(value))
    _notify_settings_changed(device)
    return response
Beispiel #9
0
def set_initial_resolution(request: WSGIRequest) -> HttpResponse:
    """Sets the resolution used on the screen."""
    value, response = extract_value(request.POST)
    resolution = tuple(map(int, value.split("x")))
    resolution = cast(Tuple[int, int], resolution)
    storage.put("initial_resolution", resolution)
    # adjusting sets the resolution and restarts the screen program
    _notify_settings_changed("adjust_screen")
    return response
Beispiel #10
0
def set_wled_ip(request: WSGIRequest) -> HttpResponse:
    """Updates the wled ip."""
    value, response = extract_value(request.POST)
    try:
        socket.inet_aton(value)
    except socket.error:
        return HttpResponseBadRequest("invalid ip")
    storage.put("wled_ip", value)
    _notify_settings_changed("wled")
    return response
Beispiel #11
0
 def adjust(self) -> None:
     """Updates resolutions and resets the current one.
     Needed after changing screens or hotplugging after booting without a connected screen."""
     self.resolution = storage.get("initial_resolution")
     resolutions = list(reversed(sorted(self.list_resolutions())))
     redis.put("resolutions", resolutions)
     # if unset, initialize with the highest resolution
     if self.resolution == (0, 0):
         storage.put("initial_resolution", resolutions[0])
         self.resolution = resolutions[0]
     self.set_resolution(self.resolution)
Beispiel #12
0
def set_jamendo_credentials(request: WSGIRequest) -> HttpResponse:
    """Update jamendo credentials."""
    client_id = request.POST.get("client_id")

    if not client_id:
        return HttpResponseBadRequest("All fields are required")

    storage.put("jamendo_client_id", client_id)

    system.update_mopidy_config("pulse")
    return HttpResponse("Updated credentials")
Beispiel #13
0
def set_soundcloud_credentials(request: WSGIRequest) -> HttpResponse:
    """Update soundcloud credentials."""
    auth_token = request.POST.get("auth_token")

    if not auth_token:
        return HttpResponseBadRequest("All fields are required")

    storage.put("soundcloud_auth_token", auth_token)

    system.update_mopidy_config("pulse")
    return HttpResponse("Updated credentials")
Beispiel #14
0
def set_interactivity(request: WSGIRequest) -> HttpResponse:
    """Enables or disables voting based on the given value."""
    value, response = extract_value(request.POST)
    if value not in [
        getattr(storage.Interactivity, attr)
        for attr in dir(storage.Interactivity)
        if not attr.startswith("__")
    ]:
        return HttpResponseBadRequest("Invalid value")
    storage.put("interactivity", value)
    return response
Beispiel #15
0
def set_output(request: WSGIRequest) -> HttpResponse:
    """Sets the given device as default output device."""
    output = request.POST.get("value")
    if not output:
        return HttpResponseBadRequest("No output selected")

    if output == request.POST.get("output"):
        return HttpResponseBadRequest("Output unchanged")

    storage.put("output", output)

    return _set_output(output)
Beispiel #16
0
def set_fixed_color(request: WSGIRequest) -> HttpResponse:
    """Updates the static color used for some programs."""
    hex_col, response = extract_value(request.POST)
    hex_col = hex_col.lstrip("#")
    try:
        color = tuple(int(hex_col[i:i + 2], 16) / 255 for i in (0, 2, 4))
    except IndexError:
        return HttpResponseBadRequest("color needs to be in #rrggbb format")
    # https://github.com/python/mypy/issues/5068
    color = cast(Tuple[float, float, float], color)
    storage.put("fixed_color", color)
    _notify_settings_changed("base")
    return response
Beispiel #17
0
def pause(_request: WSGIRequest) -> None:
    """Pauses the current song if it is playing.
    No-op if already paused."""
    with playback.mopidy_command() as allowed:
        if allowed:
            PLAYER.playback.pause()
    try:
        current_song = models.CurrentSong.objects.get()
        current_song.last_paused = timezone.now()
        current_song.save()
    except models.CurrentSong.DoesNotExist:
        pass
    storage.put("paused", True)
Beispiel #18
0
def start() -> None:
    """Initializes this module by checking which platforms are available to use."""

    # local songs are enabled if a library is set
    local_enabled = os.path.islink(library.get_library_path())
    storage.put("local_enabled", local_enabled)

    # in the docker container all dependencies are installed
    youtube_available = conf.DOCKER or importlib.util.find_spec(
        "yt_dlp") is not None
    redis.put("youtube_available", youtube_available)
    if not youtube_available:
        # if youtube is not available, overwrite the database to disable it
        storage.put("youtube_enabled", False)

    # Spotify has no python dependencies we could easily check.
    try:
        spotify_available = (
            conf.DOCKER or "[spotify]" in subprocess.check_output(
                ["mopidy", "config"],
                stderr=subprocess.DEVNULL).decode().splitlines())
    except FileNotFoundError:
        # mopidy is not installed (eg in docker). Since we can't check, enable
        spotify_available = True
    redis.put("spotify_available", spotify_available)
    if not spotify_available:
        storage.put("spotify_enabled", False)

    soundcloud_available = (conf.DOCKER or
                            importlib.util.find_spec("soundcloud") is not None)
    redis.put("soundcloud_available", soundcloud_available)
    if not soundcloud_available:
        storage.put("soundcloud_enabled", False)

    # Jamendo has no python dependencies we could easily check.
    try:
        jamendo_available = (
            conf.DOCKER or "[jamendo]" in subprocess.check_output(
                ["mopidy", "config"],
                stderr=subprocess.DEVNULL).decode().splitlines())
    except FileNotFoundError:
        jamendo_available = True
    redis.put("jamendo_available", jamendo_available)
    if not jamendo_available:
        storage.put("jamendo_enabled", False)
Beispiel #19
0
def play(_request: WSGIRequest) -> None:
    """Resumes the current song if it is paused.
    No-op if already playing."""
    with playback.mopidy_command() as allowed:
        if allowed:
            PLAYER.playback.play()
    try:
        # move the creation timestamp into the future for the duration of the pause
        # this ensures that the progress calculation (starting from created) is correct
        current_song = models.CurrentSong.objects.get()
        now = timezone.now()
        pause_duration = (now - current_song.last_paused).total_seconds()
        current_song.created += datetime.timedelta(seconds=pause_duration)
        current_song.created = min(current_song.created, now)
        current_song.save()
    except models.CurrentSong.DoesNotExist:
        pass
    storage.put("paused", False)
Beispiel #20
0
def _set_extension_enabled(extension, enabled) -> HttpResponse:
    if enabled:
        if conf.DOCKER:
            response = HttpResponse(
                "Make sure you provided mopidy with correct credentials.")
        else:
            extensions = system.check_mopidy_extensions()
            functional, message = extensions[extension]
            if not functional:
                return HttpResponseBadRequest(message)
            response = HttpResponse(message)
    else:
        response = HttpResponse("Disabled extension")
    assert extension in [
        "local", "youtube", "spotify", "soundcloud", "jamendo"
    ]
    storage.put(cast(PlatformEnabled, f"{extension}_enabled"), enabled)
    return response
Beispiel #21
0
def set_spotify_credentials(request: WSGIRequest) -> HttpResponse:
    """Update spotify credentials."""
    username = request.POST.get("username")
    password = request.POST.get("password")
    client_id = request.POST.get("client_id")
    client_secret = request.POST.get("client_secret")

    if not username or not password or not client_id or not client_secret:
        return HttpResponseBadRequest("All fields are required")

    storage.put("spotify_username", username)
    storage.put("spotify_password", password)
    storage.put("spotify_client_id", client_id)
    storage.put("spotify_client_secret", client_secret)

    system.update_mopidy_config("pulse")
    return HttpResponse("Updated credentials")
Beispiel #22
0
def set_online_suggestions(request: WSGIRequest) -> HttpResponse:
    """Enables or disables online suggestions based on the given value."""
    value, response = extract_value(request.POST)
    storage.put("online_suggestions", strtobool(value))
    return response
Beispiel #23
0
def set_dynamic_embedded_stream(request: WSGIRequest) -> HttpResponse:
    """Enables or disables dynamic streaming based on the given value."""
    value, response = extract_value(request.POST)
    storage.put("dynamic_embedded_stream", strtobool(value))
    return response
Beispiel #24
0
def set_embed_stream(request: WSGIRequest) -> HttpResponse:
    """Enables or disables logging of requests and play logs based on the given value."""
    value, response = extract_value(request.POST)
    storage.put("embed_stream", strtobool(value))
    return response
Beispiel #25
0
def set_downvotes_to_kick(request: WSGIRequest) -> HttpResponse:
    """Sets the number of downvotes that are needed to remove a song from the queue."""
    value, response = extract_value(request.POST)
    storage.put("downvotes_to_kick", int(value))
    return response
Beispiel #26
0
def set_ip_checking(request: WSGIRequest) -> HttpResponse:
    """Enables or disables ip checking based on the given value."""
    value, response = extract_value(request.POST)
    storage.put("ip_checking", strtobool(value))
    return response
Beispiel #27
0
def set_buzzer_success_probability(request: WSGIRequest) -> HttpResponse:
    """Sets the probability for the buzzer to play a success sound."""
    value, response = extract_value(request.POST)
    storage.put("buzzer_success_probability", float(value))
    return response
Beispiel #28
0
def set_buzzer_cooldown(request: WSGIRequest) -> HttpResponse:
    """Sets the minimum time that needs to pass between buzzer presses."""
    value, response = extract_value(request.POST)
    storage.put("buzzer_cooldown", float(value))
    return response
Beispiel #29
0
def set_alarm_probability(request: WSGIRequest) -> HttpResponse:
    """Sets the probability with which an alarm is triggered after each song."""
    value, response = extract_value(request.POST)
    storage.put("alarm_probability", float(value))
    return response
Beispiel #30
0
def set_people_to_party(request: WSGIRequest) -> HttpResponse:
    """Sets the amount of active clients needed to enable partymode."""
    value, response = extract_value(request.POST)
    storage.put("people_to_party", int(value))
    return response