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
5 changes: 2 additions & 3 deletions .claude/settings.local.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"env": { "ENABLE_LSP_TOOL": "1" },
"permissions": {
"allow": [
"Bash(mix compile:*)"
]
"allow": ["Bash(mix compile:*)"]
}
}
20 changes: 20 additions & 0 deletions .github/workflows/elixir.yml
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,16 @@ jobs:
with:
args: -o errkk -r playrequest -s success -u https://sonosnow.fly.dev -f

- name: Notify via Pushover
if: success()
run: |
curl -s -X POST https://api.pushover.net/1/messages.json \
-d "token=${{ secrets.PUSHOVER_KEY }}" \
-d "user=${{ secrets.PUSHOVER_USER }}" \
-d "title=SonosNow Production Deployed" \
-d "message=Version ${{ github.ref_name }} deployed to production" \
-d "url=https://sonosnow.fly.dev"

deploy_staging:
name: Deploy staging
runs-on: ubuntu-latest
Expand Down Expand Up @@ -167,3 +177,13 @@ jobs:
uses: niklasmerz/github-deployment-action@master
with:
args: -o errkk -r playrequest -s success -u https://sonosnow-staging.fly.dev -f

- name: Notify via Pushover
if: success()
run: |
curl -s -X POST https://api.pushover.net/1/messages.json \
-d "token=${{ secrets.PUSHOVER_KEY }}" \
-d "user=${{ secrets.PUSHOVER_USER }}" \
-d "title=SonoNow Staging Deployed" \
-d "message=Version ${{ github.ref_name }} deployed to production" \
-d "url=https://sonosnow-staging.fly.dev"
40 changes: 40 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
## Output

- Return code first. Explanation after, only if non-obvious.
- No inline prose. Use comments sparingly - only where logic is unclear.
- No boilerplate unless explicitly requested.

## Code Rules

- Simplest working solution. No over-engineering.
- No abstractions for single-use operations.
- No speculative features or "you might also want..."
- Read the file before modifying it. Never edit blind.
- No docstrings or type annotations on code not being changed.
- No error handling for scenarios that cannot happen.
- Three similar lines is better than a premature abstraction.

## Review Rules

- State the bug. Show the fix. Stop.
- No suggestions beyond the scope of the review.
- No compliments on the code before or after the review.

## Debugging Rules

- Never speculate about a bug without reading the relevant code first.
- State what you found, where, and the fix. One pass.
- If cause is unclear: say so. Do not guess.

## ASCII Only

- No em dashes, smart quotes, Unicode bullets.
- Plain hyphens and straight quotes only.
- Code output must be copy-paste safe.

## Deployment

- To deploy to staging look at the git log to see the latest version tag, and for a new feature tag with 0.0.0-rc.0 incrementing the RC number. The deployment is triggered by pushing the tag.
- New features should be committed to new feature branches
- Pull request to master when complete
- Don't deploy to production
2 changes: 1 addition & 1 deletion lib/pr/play_state.ex
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ defmodule PR.PlayState do
end

defp cast_metadata(data) do
Logger.info("Probably playing something else? #{Jason.encode!(data)}")
Logger.info("Probably playing something else? #{inspect(data)}")
{:error, :probably_playing_something_else}
end
end
2 changes: 1 addition & 1 deletion lib/pr/sonos_households/group_manager.ex
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ defmodule PR.SonosHouseholds.GroupManager do
end

@spec recreate_group() :: {:ok, String.t()} | {:error, String.t()}
defp recreate_group do
def recreate_group do
# Do this before making the new group
Logger.info("Unsubscribing")
SonosAPI.unsubscribe_webhooks()
Expand Down
20 changes: 19 additions & 1 deletion lib/pr_web/controllers/service/service_setup_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ defmodule PRWeb.Service.ServiceSetupController do
alias PR.SonosHouseholds
alias PR.ExternalAuth
alias PR.Music
alias PR.SonosHouseholds.GroupManager

def index(conn, _params) do
households = SonosHouseholds.list_houeholds()
Expand All @@ -31,6 +32,8 @@ defmodule PRWeb.Service.ServiceSetupController do
groups
|> Enum.any?(&(&1.is_active and not is_nil(&1.subscribed_at)))

active_group = SonosHouseholds.get_active_group()

render(
conn,
:index,
Expand All @@ -45,7 +48,8 @@ defmodule PRWeb.Service.ServiceSetupController do
has_active_households: has_active_households,
has_active_groups: has_active_groups,
active_group_subscribed: active_group_subscribed,
spotify_playlist_created: [] != spotify_playlists
spotify_playlist_created: [] != spotify_playlists,
active_group: active_group
)
end

Expand Down Expand Up @@ -189,4 +193,18 @@ defmodule PRWeb.Service.ServiceSetupController do
PR.PlayState.get_initial_state()
redirect(conn, to: ~p"/setup")
end

def recreate_group(conn, _) do
case GroupManager.recreate_group() do
{:ok, id} ->
conn
|> put_flash(:info, "Group recreated (#{id})")
|> redirect(to: ~p"/setup")

{:error, reason} ->
conn
|> put_flash(:error, "Couldn't recreate group: #{reason}")
|> redirect(to: ~p"/setup")
end
end
end
12 changes: 12 additions & 0 deletions lib/pr_web/controllers/service/service_setup_html/index.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,18 @@
Webhook should do this, but this will fetch the state
</p>
</li>
<li>
<h3>Recreate Group</h3>
<.link href={~p"/setup/recreate-group"} method="post" class="button">
Recreate group
</.link>
<p>
Recreate the Sonos group with all available players.
</p>
<%= if @active_group do %>
<p>Current group: <strong><%= @active_group.name %></strong></p>
<% end %>
</li>
</ol>
</div>
</div>
1 change: 1 addition & 0 deletions lib/pr_web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ defmodule PRWeb.Router do
post("/create-playlist", ServiceSetupController, :create_spotify_playlist)
post("/bump", ServiceSetupController, :bump)
post("/get-state", ServiceSetupController, :get_state)
post("/recreate-group", ServiceSetupController, :recreate_group)
end

scope "/", PRWeb.Service do
Expand Down
3 changes: 3 additions & 0 deletions scripts/recreate_group.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh
echo "Recreating group with all available players"
bin/pr rpc "PR.SonosHouseholds.GroupManager.recreate_group"
Loading