Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ COPY lib lib
RUN mix compile

# copy runtime configuration file
COPY config/releases.exs config/
COPY config/runtime.exs config/
COPY rel rel

# assemble release
Expand Down
4 changes: 3 additions & 1 deletion config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ config :pr, PRWeb.Endpoint,
pubsub_server: PR.PubSub,
live_view: [
signing_salt: "SECRET_SALT"
]
],
# This is overriden in prod config
force_ssl: false

# Configures Elixir's Logger
config :logger, :console,
Expand Down
51 changes: 7 additions & 44 deletions config/dev.exs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import Config

config :pr,
playlist_name: "PlayRequest"
playlist_name: "PlayRequest",
session_same_site: "Lax",
session_secure: false

# Configure your database
config :pr, PR.Repo,
Expand All @@ -28,7 +30,7 @@ config :oauth2, debug: true
# watchers to your application. For example, we use it
# with webpack to recompile .js and .css sources.
config :pr, PRWeb.Endpoint,
http: [port: System.get_env("PORT")],
http: [port: System.get_env("PORT") || 4000, ip: {0, 0, 0, 0}],
debug_errors: true,
code_reloader: true,
check_origin: false,
Expand Down Expand Up @@ -78,8 +80,8 @@ config :pr, PRWeb.Endpoint,
]

# Do not include metadata nor timestamps in development logs
# config :logger, :console, format: "[$level] $message\n"
config :logger, level: :info
config :logger, :console, format: "[$level] $message\n", level: :debug
# config :logger, level: :info

# Initialize plugs at runtime for faster development compilation
config :phoenix, :plug_init_mode, :runtime
Expand All @@ -90,43 +92,4 @@ config :phoenix, :stacktrace_depth, 20

config :phoenix_live_view, :debug_heex_annotations, true

config :pr, :sonos,
scopes: "playback-control-all",
redirect_uri: "#{System.get_env("REDIRECT_URL_BASE")}/sonos/authorized",
key: System.get_env("SONOS_KEY"),
secret: System.get_env("SONOS_SECRET")

config :pr, :spotify,
scopes:
~w(user-modify-playback-state user-read-currently-playing user-read-playback-state playlist-modify-private playlist-read-private),
redirect_uri: "#{System.get_env("REDIRECT_URL_BASE")}/spotify/authorized",
user_id: System.get_env("SPOTIFY_USER_ID"),
key: System.get_env("SPOTIFY_CLIENT_ID"),
secret: System.get_env("SPOTIFY_SECRET")

config :ueberauth, Ueberauth.Strategy.Google.OAuth,
client_id: System.get_env("GOOGLE_CLIENT_ID"),
client_secret: System.get_env("GOOGLE_CLIENT_SECRET")

config :pr,
allowed_user_domains: System.get_env("ALLOWED_USER_DOMAINS"),
installation_name: System.get_env("INSTALLATION_NAME", "PlayRequest"),
super_likes_allowed: System.get_env("SUPER_LIKES_ALLOWED", "2"),
burns_allowed: System.get_env("BURNS_ALLOWED", "2")

config :pr, :feature_flags,
show_volume: System.get_env("FF_VOLUME", ""),
show_toggle_playback: System.get_env("FF_TOGGLE_PLAYBACK", ""),
show_skip: System.get_env("FF_SKIP", ""),
scale_play_button: System.get_env("FF_SCALE_PLAY_BUTTON", ""),
show_super_like: System.get_env("FF_SUPER_LIKE", ""),
show_burn: System.get_env("FF_BURN", "")

config :sentry,
dsn: System.get_env("SENTRY_DSN"),
environment_name: :dev,
enable_source_code_context: true,
root_source_code_path: File.cwd!(),
tags: %{
env: "dev"
}
# Runtime configuration for development environment has been moved to config/runtime.exs
32 changes: 19 additions & 13 deletions config/prod.exs
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
import Config

config :logger,
backends: [LoggerJSON],
level: :info
config :pr,
session_same_site: "None",
session_secure: true

# For production, don't forget to configure the url host
# to something meaningful, Phoenix uses this information
# when generating URLs.

config :pr, PR.Repo, ssl: false, socket_options: [:inet6]
# Runtime configuration (such as database credentials) should be
# placed in config/runtime.exs which is loaded at runtime.

# Note we also include the path to a cache manifest
# containing the digested version of static files. This
# manifest is generated by the `mix assets.deploy` task,
# which you should run after static files are built and
# before starting your production server.
config :pr, PRWeb.Endpoint,
force_ssl: [rewrite_on: [:x_forwarded_proto]],
server: true,
root: ".",
version: Application.spec(:pr, :vsn)
cache_static_manifest: "priv/static/cache_manifest.json",
force_ssl: [rewrite_on: [:x_forwarded_proto]]

config :pr,
sleep: 60_000
# Do not print debug messages in production
config :logger, level: :info

config :sentry,
enable_source_code_context: true,
root_source_code_path: File.cwd!()
# Runtime configuration moved to config/runtime.exs
71 changes: 0 additions & 71 deletions config/releases.exs

This file was deleted.

120 changes: 120 additions & 0 deletions config/runtime.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import Config

# config/runtime.exs is executed for all environments, including
# during releases. It is executed after compilation and before the
# system starts, so it is typically used to load production configuration
# and secrets from environment variables or elsewhere. Do not define
# any compile-time configuration in here, as it won't be applied.

# ## Using releases
#
# If you use `mix release`, you need to explicitly enable the server
# by passing the PHX_SERVER=true when you start it:
#
# PHX_SERVER=true bin/pr start
#
# Alternatively, you can use `mix phx.gen.release` to generate a `bin/server`
# script that automatically sets the env var above.
if System.get_env("PHX_SERVER") do
config :pr, PRWeb.Endpoint, server: true
end

# Common runtime configuration for all environments
config :pr, :sonos,
scopes: "playback-control-all",
redirect_uri: "#{System.get_env("REDIRECT_URL_BASE")}/sonos/authorized",
key: System.get_env("SONOS_KEY"),
secret: System.get_env("SONOS_SECRET")

config :pr, :spotify,
scopes:
~w(user-modify-playback-state user-read-currently-playing user-read-playback-state playlist-modify-private playlist-read-private),
redirect_uri: "#{System.get_env("REDIRECT_URL_BASE")}/spotify/authorized",
key: System.get_env("SPOTIFY_CLIENT_ID"),
secret: System.get_env("SPOTIFY_SECRET")

config :ueberauth, Ueberauth.Strategy.Google.OAuth,
client_id: System.get_env("GOOGLE_CLIENT_ID"),
client_secret: System.get_env("GOOGLE_CLIENT_SECRET")

config :pr,
allowed_user_domains: System.get_env("ALLOWED_USER_DOMAINS", ""),
installation_name: System.get_env("INSTALLATION_NAME", "PlayRequest"),
super_likes_allowed: System.get_env("SUPER_LIKES_ALLOWED", "2"),
burns_allowed: System.get_env("BURNS_ALLOWED", "2")

config :pr, :feature_flags,
show_volume: System.get_env("FF_VOLUME", ""),
show_toggle_playback: System.get_env("FF_TOGGLE_PLAYBACK", ""),
show_skip: System.get_env("FF_SKIP", ""),
scale_play_button: System.get_env("FF_SCALE_PLAY_BUTTON", ""),
show_super_like: System.get_env("FF_SUPER_LIKE", ""),
show_burn: System.get_env("FF_BURN", "")

config :sentry,
dsn: System.get_env("SENTRY_DSN"),
enable_source_code_context: true,
root_source_code_path: File.cwd!()

# Production-specific configuration
if config_env() == :prod do
config :logger,
backends: [LoggerJSON],
level: :info

config :pr, PR.Repo,
url: System.get_env("DATABASE_URL") || raise("DATABASE_URL not available"),
pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"),
ssl: false,
socket_options: [:inet6]

config :pr, PRWeb.Endpoint,
http: [port: String.to_integer(System.get_env("PORT") || "4000")],
url: [host: System.get_env("HOSTNAME"), port: 443, scheme: "https"],
cache_static_manifest: "priv/static/cache_manifest.json",
server: true

# Production requires these environment variables
unless System.get_env("SONOS_KEY"), do: raise("SONOS_KEY not available")
unless System.get_env("SONOS_SECRET"), do: raise("SONOS_SECRET not available")
unless System.get_env("SPOTIFY_CLIENT_ID"), do: raise("SPOTIFY_CLIENT_ID not available")
unless System.get_env("SPOTIFY_SECRET"), do: raise("SPOTIFY_SECRET not available")
unless System.get_env("GOOGLE_CLIENT_ID"), do: raise("GOOGLE_CLIENT_ID not available")
unless System.get_env("GOOGLE_CLIENT_SECRET"), do: raise("GOOGLE_CLIENT_SECRET not available")

config :pr,
sleep: 60_000

app_name =
System.get_env("FLY_APP_NAME") ||
raise "FLY_APP_NAME not available"

config :libcluster,
debug: true,
topologies: [
fly6pn: [
strategy: Cluster.Strategy.DNSPoll,
config: [
polling_interval: 5_000,
query: "#{app_name}.internal",
node_basename: app_name
]
]
]

config :sentry,
tags: %{
env: System.get_env("RELEASE_STAGE") || "dev"
},
environment_name: System.get_env("RELEASE_STAGE") || :prod,
release: System.get_env("APP_REVISION", "dev")
end

# Development-specific configuration
if config_env() == :dev do
config :sentry,
environment_name: :dev,
tags: %{
env: "dev"
}
end
2 changes: 1 addition & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,4 @@ remote_production:
fly ssh console -C "/home/elixir/app/bin/{{binname}} remote" --app {{appname}}

tunnel:
ssh -p 443 -R0:localhost:4000 ${PINGY_TOKEN}@a.pinggy.online
cloudflared tunnel run --token ${CLOUDFLARE_TOKEN}
15 changes: 11 additions & 4 deletions lib/pr/apis/sonos_api.ex
Original file line number Diff line number Diff line change
Expand Up @@ -186,10 +186,17 @@ defmodule PR.SonosAPI do
%Household{household_id: household_id, id: id} ->
%{playerIds: player_ids}
|> post("/households/#{household_id}/groups/createGroup")
|> Map.get(:group)
|> fields_for_group(id)
|> Map.put(:is_active, true)
|> SonosHouseholds.insert_or_update_group()
|> case do
%{group: group} ->
group
|> fields_for_group(id)
|> Map.put(:is_active, true)
|> SonosHouseholds.insert_or_update_group()

{:error, error} ->
Logger.error(error)
{:error, :cant_create_group}
end

_ ->
{:error, :no_household_activated}
Expand Down
5 changes: 4 additions & 1 deletion lib/pr/music/music.ex
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,13 @@ defmodule PR.Music do
def check_current_playstate(%PlaybackState{state: state}, _mode),
do: {:error, :playstate, state}

def check_current_playstate(%{}, _mode),
do: {:error, :playstate, nil}

def check_unplayed() do
# Check if there's something in the queue
# If might still be marked as playing if its a skip
# but that's probably ok as this check is only really
# but that's probably ok as this check is only really
# of interest for knowing what to do when skip is pressed
cond do
Queue.num_unplayed() == 0 ->
Expand Down
2 changes: 1 addition & 1 deletion lib/pr_web.ex
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ defmodule PRWeb do
def plug do
quote do
import Plug.Conn
use Phoenix.Controller, namespace: PRWeb
import Phoenix.Controller, only: [redirect: 2]
unquote(verified_routes())
end
end
Expand Down
10 changes: 10 additions & 0 deletions lib/pr_web/components/layouts/auth.html.heex
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<div class="content">
<header class="container--header">
<h1><%= installation_name() %></h1>
</header>
<div class="alert-container">
<.flash class="alert alert-info" kind={:info} title="Success!" flash={@flash} />
<.flash class="alert alert-danger" kind={:error} title="Error!" flash={@flash} />
</div>
<%= @inner_content %>
</div>
1 change: 1 addition & 0 deletions lib/pr_web/controllers/auth_controller.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
defmodule PRWeb.AuthController do
use PRWeb, :controller
plug(Ueberauth)
plug(:put_layout, html: {PRWeb.Layouts, :auth})

alias PR.Auth

Expand Down
Loading