Skip to content

Commit

Permalink
Create a single audio_image per feed_segment within a given range for…
Browse files Browse the repository at this point in the history
… a feed
  • Loading branch information
skanderm committed Sep 9, 2024
1 parent c6a7dd9 commit ca8499b
Show file tree
Hide file tree
Showing 8 changed files with 458 additions and 16 deletions.
1 change: 1 addition & 0 deletions server/config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ config :spark, :formatter,
:identities,
:attributes,
:calculations,
:aggregates,
:relationships,
:authentication,
:token,
Expand Down
16 changes: 8 additions & 8 deletions server/lib/orcasite/radio/audio_image.ex
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
defmodule Orcasite.Radio.AudioImage do
require Ash.Resource.Change.Builtins
require Ash.Resource.Change.Builtins
require Ash.Resource.Change.Builtins
require Ash.Resource.Change.Builtins

use Ash.Resource,
otp_app: :orcasite,
domain: Orcasite.Radio,
Expand All @@ -24,6 +19,10 @@ defmodule Orcasite.Radio.AudioImage do
end
end

identities do
identity :unique_audio_image, [:feed_id, :image_type, :start_time, :end_time]
end

attributes do
uuid_primary_key :id
attribute :image_type, Orcasite.Types.ImageType, public?: true
Expand Down Expand Up @@ -80,7 +79,7 @@ defmodule Orcasite.Radio.AudioImage do
defaults [:read, :destroy, create: :*, update: :*]

create :for_feed_segment do
argument :feed_segment_id, :uuid, allow_nil?: false
argument :feed_segment_id, :string, allow_nil?: false

argument :image_type, Orcasite.Types.ImageType do
default :spectrogram
Expand Down Expand Up @@ -152,6 +151,7 @@ defmodule Orcasite.Radio.AudioImage do
image_key: image.object_path
}
|> Orcasite.Radio.AwsClient.generate_spectrogram()
|> IO.inspect(label: "gen spect result")
|> case do
{:ok, %{"errorMessage" => _} = error} ->
image
Expand All @@ -161,7 +161,7 @@ defmodule Orcasite.Radio.AudioImage do
|> Ash.Changeset.force_change_attribute(:last_error, inspect(error))
|> Ash.update(authorize?: false)

{:error, :spectrogram_failed}
# {:error, :spectrogram_failed}

{:ok, %{image_size: image_size, sample_rate: _sample_rate}} ->
image
Expand All @@ -182,7 +182,7 @@ defmodule Orcasite.Radio.AudioImage do
|> Ash.Changeset.force_change_attribute(:last_error, inspect(error))
|> Ash.update(authorize?: false)

error
# error
end
end,
prepend?: true
Expand Down
2 changes: 1 addition & 1 deletion server/lib/orcasite/radio/aws_client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ defmodule Orcasite.Radio.AwsClient do
|> elem(1)
|> String.to_integer()

{:ok, %{size: size}}
{:ok, %{file_size: size}}

_ ->
# Doesn't exist, make spectrogram
Expand Down
53 changes: 46 additions & 7 deletions server/lib/orcasite/radio/feed.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
defmodule Orcasite.Radio.Feed do
require Ash.Resource.Change.Builtins

use Ash.Resource,
domain: Orcasite.Radio,
extensions: [AshAdmin.Resource, AshUUID, AshGraphql.Resource, AshJsonApi.Resource],
Expand Down Expand Up @@ -68,7 +70,7 @@ defmodule Orcasite.Radio.Feed do
{Orcasite.Radio.Calculations.FeedImageUrl, object: "map.png"},
public?: true

# calculate :uuid, :string, Orcasite.Radio.Calculations.DecodeUUID
calculate :uuid, :string, Orcasite.Radio.Calculations.DecodeUUID
end

aggregates do
Expand All @@ -78,14 +80,18 @@ defmodule Orcasite.Radio.Feed do
end
end


relationships do
has_many :feed_streams, Orcasite.Radio.FeedStream do
public? true
end

has_many :feed_segments, Orcasite.Radio.FeedSegment do
public? true
end

has_many :audio_images, Orcasite.Radio.AudioImage do
public? true
end
end

policies do
Expand Down Expand Up @@ -167,6 +173,44 @@ defmodule Orcasite.Radio.Feed do

change &change_lat_lng/2
end

update :generate_spectrogram do
require_atomic? false
argument :start_time, :utc_datetime_usec, allow_nil?: false
argument :end_time, :utc_datetime_usec, allow_nil?: false

validate {Orcasite.Validations.Compare, [lt: [:start_time, :end_time]]}

change before_action(fn change, _context ->
# Get feed_segments between the start time and end time, and, for now
# create a single spectrogram per segment. Once we can create an
# audio image for multiple segments (with concatenation in the lambda),
# we can change this to a single spectrogram with all those audio segments

feed_segments =
Orcasite.Radio.FeedSegment
|> Ash.Query.for_read(:for_feed_range, %{
feed_id: change.data.id,
start_time: change.arguments.start_time,
end_time: change.arguments.end_time
})
|> Ash.read!(authorize?: false)

audio_image_inputs = feed_segments |> Enum.map(&%{feed_segment_id: &1.id})

change
|> Ash.Changeset.manage_relationship(:audio_images, audio_image_inputs,
on_no_match: {:create, :for_feed_segment},
on_match: :ignore
)
|> IO.inspect(label: "new change")
end)
end
end

code_interface do
define :get_feed_by_slug, action: :get_by_slug, args: [:slug], get?: true
define :get_feed_by_node_name, action: :get_by_node_name, args: [:node_name], get?: true
end

admin do
Expand All @@ -179,11 +223,6 @@ defmodule Orcasite.Radio.Feed do
end
end

code_interface do
define :get_feed_by_slug, action: :get_by_slug, args: [:slug], get?: true
define :get_feed_by_node_name, action: :get_by_node_name, args: [:node_name], get?: true
end

json_api do
type "feed"

Expand Down
22 changes: 22 additions & 0 deletions server/lib/orcasite/radio/feed_segment.ex
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,28 @@ defmodule Orcasite.Radio.FeedSegment do
)
end

read :for_feed_range do
argument :start_time, :utc_datetime_usec, allow_nil?: false
argument :end_time, :utc_datetime_usec, allow_nil?: false
argument :feed_id, :string, allow_nil?: false

filter expr(
feed_id == ^arg(:feed_id) and
(fragment(
"(?) between (?) and (?)",
start_time,
^arg(:start_time),
^arg(:end_time)
) or
fragment(
"(?) between (?) and (?)",
end_time,
^arg(:start_time),
^arg(:end_time)
))
)
end

create :create do
primary? true
upsert? true
Expand Down
21 changes: 21 additions & 0 deletions server/lib/orcasite/validations/compare.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
defmodule Orcasite.Validations.Compare do
use Ash.Resource.Validation

def validate(changeset, [{op, [arg_key_1, arg_key_2]}], _context) do
arg_1 = changeset |> Ash.Changeset.get_argument(arg_key_1)
arg_2 = changeset |> Ash.Changeset.get_argument(arg_key_2)

case {compare(arg_1, arg_2), op} do
{:eq, :gte} -> :ok
{:gt, :gte} -> :ok
{:lt, :lte} -> :ok
{:lt, :lt} -> :ok
{:eq, :eq} -> :ok
_ -> {:error, "#{arg_key_1} (#{arg_1}) is not #{op} #{arg_key_2} (#{arg_2})"}
end
end

def compare(%DateTime{} = datetime_1, %DateTime{} = datetime_2) do
DateTime.compare(datetime_1, datetime_2)
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
defmodule Orcasite.Repo.Migrations.AddUniqueIndexToAudioImage do
@moduledoc """
Updates resources based on their most recent snapshots.
This file was autogenerated with `mix ash_postgres.generate_migrations`
"""

use Ecto.Migration

def up do
create unique_index(:audio_images, [:feed_id, :image_type, :start_time, :end_time],
name: "audio_images_unique_audio_image_index"
)
end

def down do
drop_if_exists unique_index(:audio_images, [:feed_id, :image_type, :start_time, :end_time],
name: "audio_images_unique_audio_image_index"
)
end
end
Loading

0 comments on commit ca8499b

Please sign in to comment.