diff --git a/.github/workflows/elixir.yml b/.github/workflows/elixir.yml index ea429a09..dc34bb9e 100644 --- a/.github/workflows/elixir.yml +++ b/.github/workflows/elixir.yml @@ -13,122 +13,88 @@ jobs: build: name: Build and test runs-on: ubuntu-latest - container: - image: alpine:3.21 env: MIX_ENV: test steps: + - uses: actions/checkout@v4 + + - name: Set up Elixir + uses: erlef/setup-beam@v1 + with: + elixir-version: '1.19.2' + otp-version: '28.0' + version-type: 'strict' + id: beam + + - name: Restore PLT cache + uses: actions/cache@v4 + id: plt-cache + with: + path: priv/plts + key: ${{ runner.os }}-${{ steps.beam.outputs.otp-version }}-${{ steps.beam.outputs.elixir-version }}-plt-${{ hashFiles('**/mix.lock') }} + restore-keys: | + ${{ runner.os }}-${{ steps.beam.outputs.otp-version }}-${{ steps.beam.outputs.elixir-version }}-plt- + - name: Install system dependencies and FFmpeg run: | - # Add community repository for 3.21 packages - echo "https://dl-cdn.alpinelinux.org/alpine/v3.21/community" >> /etc/apk/repositories - apk update - - # Install basic system dependencies including GNU tar for GitHub Actions caching - apk add --no-cache \ - git \ - bash \ - curl \ - build-base \ - openssl-dev \ - ncurses-dev \ - zlib-dev \ + sudo apt-get update + sudo apt-get install -y \ mediainfo \ - cmake \ - make \ - gzip \ - tar - - # Verify tar installation for GitHub Actions caching compatibility - # GitHub Actions cache requires POSIX-compliant tar - which tar && tar --version | head -1 - - # Install FFmpeg with essential codec libraries (minimal set to avoid conflicts) - apk add --no-cache \ ffmpeg \ - x264-libs \ - x265-libs \ - svt-av1 - - - name: Install Erlang and Elixir - run: | - # Install Erlang 27 and Elixir 1.19 from Alpine 3.21 (should be available in community repo) - apk add --no-cache \ - erlang \ - elixir - - - uses: actions/checkout@v4 + build-essential - - name: Cache rustup and cargo installation + - name: Cache Rust toolchain uses: actions/cache@v4 + id: rust-toolchain-cache with: path: | ~/.rustup ~/.cargo/registry/index ~/.cargo/registry/cache - ~/.cargo/git - key: ${{ runner.os }}-alpine-rust-${{ hashFiles('**/Cargo.lock') }}-v1 + ~/.cargo/git/db + key: ${{ runner.os }}-rust-toolchain-v3 restore-keys: | - ${{ runner.os }}-alpine-rust- + ${{ runner.os }}-rust-toolchain- - name: Cache ab-av1 binary uses: actions/cache@v4 id: ab-av1-cache with: path: ~/.cargo/bin/ab-av1 - key: ${{ runner.os }}-alpine-ab-av1-${{ hashFiles('~/.cargo/bin/ab-av1') }}-v1 + key: ${{ runner.os }}-ab-av1-binary-v3 restore-keys: | - ${{ runner.os }}-alpine-ab-av1- + ${{ runner.os }}-ab-av1-binary- + + - name: Install Rust toolchain + if: steps.rust-toolchain-cache.outputs.cache-hit != 'true' + run: | + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable - name: Install ab-av1 if: steps.ab-av1-cache.outputs.cache-hit != 'true' run: | - # Install rustup to get latest stable Rust (Alpine's is too old) - if [ ! -f ~/.cargo/env ]; then - apk add --no-cache curl - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y - fi source ~/.cargo/env - # Add cargo to PATH for this and future steps - echo "$HOME/.cargo/bin" >> $GITHUB_PATH - # Install latest stable ab-av1 with newer Rust toolchain - cargo install ab-av1 + cargo install ab-av1 --locked - name: Setup cargo PATH run: | # Ensure cargo is available in PATH for subsequent steps echo "$HOME/.cargo/bin" >> $GITHUB_PATH + source ~/.cargo/env || true - - name: Cache Mix dependencies + - name: Cache Mix dependencies and build uses: actions/cache@v4 + id: mix-cache with: path: | deps - _build/test/lib - key: ${{ runner.os }}-alpine-mix-${{ hashFiles('mix.lock') }} - restore-keys: | - ${{ runner.os }}-alpine-mix- - - - name: Cache compiled dependencies - uses: actions/cache@v4 - with: - path: _build - key: ${{ runner.os }}-alpine-build-${{ hashFiles('mix.lock') }}-${{ hashFiles('lib/**/*.ex', 'test/**/*.exs', 'config/**/*.exs') }} - restore-keys: | - ${{ runner.os }}-alpine-build-${{ hashFiles('mix.lock') }}- - ${{ runner.os }}-alpine-build- - - - name: Cache native dependencies - uses: actions/cache@v4 - with: - path: | - deps/*/priv - deps/*/_build - key: ${{ runner.os }}-alpine-native-${{ hashFiles('mix.lock') }} + _build + key: ${{ runner.os }}-${{ steps.beam.outputs.otp-version }}-${{ steps.beam.outputs.elixir-version }}-mix-${{ hashFiles('**/mix.lock') }}-${{ hashFiles('lib/**/*.ex', 'config/**/*.exs') }} restore-keys: | - ${{ runner.os }}-alpine-native- + ${{ runner.os }}-${{ steps.beam.outputs.otp-version }}-${{ steps.beam.outputs.elixir-version }}-mix-${{ hashFiles('**/mix.lock') }}- + ${{ runner.os }}-${{ steps.beam.outputs.otp-version }}-${{ steps.beam.outputs.elixir-version }}-mix- - name: Verify environment run: | @@ -139,9 +105,11 @@ jobs: echo 'ffmpeg version:' && ffmpeg -version | head -1 - name: Install dependencies + if: steps.mix-cache.outputs.cache-hit != 'true' run: mix deps.get - name: Compile dependencies + if: steps.mix-cache.outputs.cache-hit != 'true' run: mix deps.compile - name: Compile project diff --git a/flake.lock b/flake.lock index 28293a93..ee27006b 100644 --- a/flake.lock +++ b/flake.lock @@ -20,11 +20,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1758127371, - "narHash": "sha256-0VkGTLwl6E/MS+Yx0Eku2iwdTzgEsYxvjtjlMLq9Ekg=", + "lastModified": 1762451070, + "narHash": "sha256-sxqROO5LA9kYtu1hOEz6kAigHB8kvVJVRKGHBaZscJw=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "d48aa7a2404f69bc748a86da230baa6eb308eeb6", + "rev": "c64bcccaf5608a016d993a43fcecdc2dd2e108be", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index c067767c..f52d8d45 100644 --- a/flake.nix +++ b/flake.nix @@ -14,17 +14,10 @@ system: let pkgs = import nixpkgs {inherit system;}; lib = pkgs.lib; - # Use latest OTP 28.1 with Elixir 1.19.0-rc.0 for cutting-edge features + # Use latest stable OTP 28 with Elixir 1.19 erlang = pkgs.erlang_28; beamPackages = pkgs.beam.packagesWith erlang; - elixir = beamPackages.elixir.override { - erlang = erlang; - version = "1.19.0-rc.0"; - src = pkgs.fetchurl { - url = "https://github.com/elixir-lang/elixir/archive/refs/tags/v${elixir.version}.tar.gz"; - sha256 = "sha256-YvkDCI578h4SmtEA5XP2XQNjixDGIHdwIEuOa50Uh5E="; - }; - }; + elixir = beamPackages.elixir_1_19; in { # Docker image for the application packages.dockerImage = pkgs.dockerTools.buildLayeredImage { @@ -77,7 +70,6 @@ pkgs.curl pkgs.docker-compose pkgs.gnupg - pkgs.pinentry pkgs.pinentry-curses # Video processing tools for CI/dev pkgs.ab-av1 diff --git a/lib/reencodarr/analyzer/broadway/producer.ex b/lib/reencodarr/analyzer/broadway/producer.ex index b75ed985..fa877d43 100644 --- a/lib/reencodarr/analyzer/broadway/producer.ex +++ b/lib/reencodarr/analyzer/broadway/producer.ex @@ -23,15 +23,14 @@ defmodule Reencodarr.Analyzer.Broadway.Producer do def init(_opts) do # Poll every 2 seconds to check for new work schedule_poll() - {:producer, %{}} + {:producer, %{pending_demand: 0}} end @impl GenStage def handle_demand(demand, state) when demand > 0 do - # Fetch up to 5 videos for batch processing - videos = Media.get_videos_needing_analysis(min(demand, 5)) - Logger.debug("Analyzer: handle_demand(#{demand}) -> #{length(videos)} videos") - {:noreply, videos, state} + # Accumulate demand and fetch videos + new_demand = state.pending_demand + demand + dispatch(new_demand, state) end @impl GenStage @@ -40,22 +39,28 @@ defmodule Reencodarr.Analyzer.Broadway.Producer do @impl GenStage def handle_info(:poll, state) do schedule_poll() - # Check if there's work and manually ask Broadway to pull - case Media.count_videos_needing_analysis() do - 0 -> - {:noreply, [], state} - - _count -> - # There's work available - return one video to wake up Broadway - videos = Media.get_videos_needing_analysis(1) - Logger.debug("Analyzer: poll wakeup -> #{length(videos)} videos") - {:noreply, videos, state} - end + # If there's pending demand, try to fulfill it + # This wakes up Broadway when new work appears + dispatch(state.pending_demand, state) end @impl GenStage def handle_info(_msg, state), do: {:noreply, [], state} + defp dispatch(demand, state) when demand > 0 do + # Fetch up to 5 videos for batch processing + videos = Media.get_videos_needing_analysis(min(demand, 5)) + remaining_demand = demand - length(videos) + + Logger.debug( + "Analyzer: dispatch(#{demand}) -> #{length(videos)} videos, #{remaining_demand} remaining" + ) + + {:noreply, videos, %{state | pending_demand: remaining_demand}} + end + + defp dispatch(_demand, state), do: {:noreply, [], state} + defp schedule_poll do Process.send_after(self(), :poll, 2000) end diff --git a/lib/reencodarr/crf_searcher/broadway/producer.ex b/lib/reencodarr/crf_searcher/broadway/producer.ex index 844e381f..5cdac7da 100644 --- a/lib/reencodarr/crf_searcher/broadway/producer.ex +++ b/lib/reencodarr/crf_searcher/broadway/producer.ex @@ -18,40 +18,39 @@ defmodule Reencodarr.CrfSearcher.Broadway.Producer do def init(_opts) do # Poll every 2 seconds to check for new work schedule_poll() - {:producer, %{}} + {:producer, %{pending_demand: 0}} end @impl GenStage - def handle_demand(_demand, state) do - dispatch(state) + def handle_demand(demand, state) do + new_demand = state.pending_demand + demand + dispatch(new_demand, state) end @impl GenStage def handle_info(:poll, state) do schedule_poll() - # Check if there's work and CrfSearch is available, wake up Broadway if so - if CrfSearch.available?() do - case Media.get_videos_for_crf_search(1) do - [] -> {:noreply, [], state} - videos -> {:noreply, videos, state} - end - else - {:noreply, [], state} - end + # If there's pending demand, try to fulfill it + dispatch(state.pending_demand, state) end @impl GenStage def handle_info(_msg, state), do: {:noreply, [], state} - defp dispatch(state) do - if CrfSearch.available?() do - videos = Media.get_videos_for_crf_search(1) - {:noreply, videos, state} - else - {:noreply, [], state} - end + defp dispatch(demand, state) when demand > 0 do + videos = + if CrfSearch.available?() do + Media.get_videos_for_crf_search(1) + else + [] + end + + remaining_demand = demand - length(videos) + {:noreply, videos, %{state | pending_demand: remaining_demand}} end + defp dispatch(_demand, state), do: {:noreply, [], state} + defp schedule_poll do Process.send_after(self(), :poll, 2000) end diff --git a/lib/reencodarr/encoder/broadway.ex b/lib/reencodarr/encoder/broadway.ex index cf59dd39..c418c3ab 100644 --- a/lib/reencodarr/encoder/broadway.ex +++ b/lib/reencodarr/encoder/broadway.ex @@ -20,7 +20,9 @@ defmodule Reencodarr.Encoder.Broadway do alias Reencodarr.AbAv1.ProgressParser alias Reencodarr.Dashboard.Events alias Reencodarr.Encoder.Broadway.Producer + alias Reencodarr.Media.VideoStateMachine alias Reencodarr.PostProcessor + alias Reencodarr.Repo @typedoc "VMAF struct for encoding processing" @type vmaf :: %{id: integer(), video: map()} @@ -169,6 +171,25 @@ defmodule Reencodarr.Encoder.Broadway do defp process_vmaf_encoding(vmaf, context) do Logger.info("Broadway: Starting encoding for VMAF #{vmaf.id}: #{vmaf.video.path}") + # Mark video as encoding NOW that we're actually starting + case VideoStateMachine.transition_to_encoding(vmaf.video) do + {:ok, changeset} -> + case Repo.update(changeset) do + {:ok, _updated_video} -> + :ok + + {:error, reason} -> + Logger.warning( + "Failed to mark video #{vmaf.video.id} as encoding: #{inspect(reason)}" + ) + end + + {:error, reason} -> + Logger.warning( + "Failed to transition video #{vmaf.video.id} to encoding: #{inspect(reason)}" + ) + end + # Broadcast initial encoding progress at 0% Events.broadcast_event(:encoding_started, %{ video_id: vmaf.video.id, diff --git a/lib/reencodarr/encoder/broadway/producer.ex b/lib/reencodarr/encoder/broadway/producer.ex index 40e4ddad..0c476117 100644 --- a/lib/reencodarr/encoder/broadway/producer.ex +++ b/lib/reencodarr/encoder/broadway/producer.ex @@ -24,45 +24,44 @@ defmodule Reencodarr.Encoder.Broadway.Producer do def init(_opts) do # Poll every 2 seconds to check for new work schedule_poll() - {:producer, %{}} + {:producer, %{pending_demand: 0}} end @impl GenStage - def handle_demand(_demand, state) do - dispatch(state) + def handle_demand(demand, state) do + new_demand = state.pending_demand + demand + dispatch(new_demand, state) end @impl GenStage def handle_info(:poll, state) do schedule_poll() - # Check if there's work and Encode is available, wake up Broadway if so - if Encode.available?() do - case Media.get_next_for_encoding(1) do - %Reencodarr.Media.Vmaf{} = vmaf -> {:noreply, [vmaf], state} - [%Reencodarr.Media.Vmaf{} = vmaf] -> {:noreply, [vmaf], state} - _ -> {:noreply, [], state} - end - else - {:noreply, [], state} - end + # If there's pending demand, try to fulfill it + dispatch(state.pending_demand, state) end @impl GenStage def handle_info(_msg, state), do: {:noreply, [], state} - defp dispatch(state) do - if Encode.available?() do - case Media.get_next_for_encoding(1) do - %Reencodarr.Media.Vmaf{} = vmaf -> {:noreply, [vmaf], state} - [%Reencodarr.Media.Vmaf{} = vmaf] -> {:noreply, [vmaf], state} - [] -> {:noreply, [], state} - nil -> {:noreply, [], state} + defp dispatch(demand, state) when demand > 0 do + vmaf_list = + if Encode.available?() do + case Media.get_next_for_encoding(1) do + %Reencodarr.Media.Vmaf{} = vmaf -> [vmaf] + [%Reencodarr.Media.Vmaf{} = vmaf] -> [vmaf] + [] -> [] + nil -> [] + end + else + [] end - else - {:noreply, [], state} - end + + remaining_demand = demand - length(vmaf_list) + {:noreply, vmaf_list, %{state | pending_demand: remaining_demand}} end + defp dispatch(_demand, state), do: {:noreply, [], state} + defp schedule_poll do Process.send_after(self(), :poll, 2000) end diff --git a/lib/reencodarr/media/video_queries.ex b/lib/reencodarr/media/video_queries.ex index e708a164..411234e5 100644 --- a/lib/reencodarr/media/video_queries.ex +++ b/lib/reencodarr/media/video_queries.ex @@ -11,6 +11,7 @@ defmodule Reencodarr.Media.VideoQueries do @doc """ Gets videos ready for CRF search (state: analyzed). + Excludes videos already in crf_searching state to avoid showing currently processing videos. """ @spec videos_for_crf_search(integer()) :: [Video.t()] def videos_for_crf_search(limit \\ 10) do @@ -37,6 +38,7 @@ defmodule Reencodarr.Media.VideoQueries do @doc """ Counts the total number of videos ready for CRF search. + Excludes videos already in crf_searching state. """ @spec count_videos_for_crf_search() :: integer() def count_videos_for_crf_search do diff --git a/lib/reencodarr/services/radarr.ex b/lib/reencodarr/services/radarr.ex index 922ff877..cb69e1f1 100644 --- a/lib/reencodarr/services/radarr.ex +++ b/lib/reencodarr/services/radarr.ex @@ -122,6 +122,7 @@ defmodule Reencodarr.Services.Radarr do json_payload = %{ name: "RenameFiles", + movieId: movie_id, files: renameable_file_ids } diff --git a/lib/reencodarr/sync.ex b/lib/reencodarr/sync.ex index 2677d69e..24a3e4ce 100644 --- a/lib/reencodarr/sync.ex +++ b/lib/reencodarr/sync.ex @@ -6,9 +6,10 @@ defmodule Reencodarr.Sync do alias Reencodarr.Analyzer.Broadway, as: AnalyzerBroadway alias Reencodarr.Core.Parsers alias Reencodarr.Dashboard.Events + alias Reencodarr.{Media, Repo, Services} + alias Reencodarr.Media.{MediaInfoExtractor, VideoFileInfo, VideoUpsert} alias Reencodarr.Media.Video.MediaInfoConverter - alias Reencodarr.{Media, Repo, Services} # Public API def start_link(_), do: GenServer.start_link(__MODULE__, %{}, name: __MODULE__) diff --git a/mix.exs b/mix.exs index 5033e2a7..83848a0d 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule Reencodarr.MixProject do [ app: :reencodarr, version: "0.1.0", - elixir: "~> 1.14", + elixir: "~> 1.19", elixirc_paths: elixirc_paths(Mix.env()), start_permanent: Mix.env() == :prod, aliases: aliases(), diff --git a/mix.lock b/mix.lock index 91206baf..56917653 100644 --- a/mix.lock +++ b/mix.lock @@ -9,35 +9,35 @@ "certifi": {:hex, :certifi, "2.15.0", "0e6e882fcdaaa0a5a9f2b3db55b1394dba07e8d6d9bcad08318fb604c6839712", [:rebar3], [], "hexpm", "b147ed22ce71d72eafdad94f055165c1c182f61a2ff49df28bcc71d1d5b94a60"}, "combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"}, "contex": {:hex, :contex, "0.5.0", "5d8a6defbeb41f54adfcb0f85c4756d4f2b84aa5b0d809d45a5d2e90d91d0392", [:mix], [{:nimble_strftime, "~> 0.1.0", [hex: :nimble_strftime, repo: "hexpm", optional: false]}], "hexpm", "b7497a1790324d84247859df44ba4bcf2489d9bba1812a5375b2f2046b9e6fd7"}, - "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, + "credo": {:hex, :credo, "1.7.13", "126a0697df6b7b71cd18c81bc92335297839a806b6f62b61d417500d1070ff4e", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "47641e6d2bbff1e241e87695b29f617f1a8f912adea34296fb10ecc3d7e9e84f"}, "db_connection": {:hex, :db_connection, "2.8.1", "9abdc1e68c34c6163f6fb96a96532272d13ad7ca45262156ae8b7ec6d9dc4bec", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a61a3d489b239d76f326e03b98794fb8e45168396c925ef25feb405ed09da8fd"}, "decimal": {:hex, :decimal, "2.3.0", "3ad6255aa77b4a3c4f818171b12d237500e63525c2fd056699967a3e7ea20f62", [:mix], [], "hexpm", "a4d66355cb29cb47c3cf30e71329e58361cfcb37c34235ef3bf1d7bf3773aeac"}, - "dialyxir": {:hex, :dialyxir, "1.4.6", "7cca478334bf8307e968664343cbdb432ee95b4b68a9cba95bdabb0ad5bdfd9a", [:mix], [{:erlex, ">= 0.2.7", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "8cf5615c5cd4c2da6c501faae642839c8405b49f8aa057ad4ae401cb808ef64d"}, + "dialyxir": {:hex, :dialyxir, "1.4.7", "dda948fcee52962e4b6c5b4b16b2d8fa7d50d8645bbae8b8685c3f9ecb7f5f4d", [:mix], [{:erlex, ">= 0.2.8", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "b34527202e6eb8cee198efec110996c25c5898f43a4094df157f8d28f27d9efe"}, "dns_cluster": {:hex, :dns_cluster, "0.2.0", "aa8eb46e3bd0326bd67b84790c561733b25c5ba2fe3c7e36f28e88f384ebcb33", [:mix], [], "hexpm", "ba6f1893411c69c01b9e8e8f772062535a4cf70f3f35bcc964a324078d8c8240"}, - "ecto": {:hex, :ecto, "3.13.2", "7d0c0863f3fc8d71d17fc3ad3b9424beae13f02712ad84191a826c7169484f01", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "669d9291370513ff56e7b7e7081b7af3283d02e046cf3d403053c557894a0b3e"}, + "ecto": {:hex, :ecto, "3.13.4", "27834b45d58075d4a414833d9581e8b7bb18a8d9f264a21e42f653d500dbeeb5", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5ad7d1505685dfa7aaf86b133d54f5ad6c42df0b4553741a1ff48796736e88b2"}, "ecto_sql": {:hex, :ecto_sql, "3.13.2", "a07d2461d84107b3d037097c822ffdd36ed69d1cf7c0f70e12a3d1decf04e2e1", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.13.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.7", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.19 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "539274ab0ecf1a0078a6a72ef3465629e4d6018a3028095dc90f60a19c371717"}, - "ecto_sqlite3": {:hex, :ecto_sqlite3, "0.21.0", "8531f5044fb08289b3aacd21e383a9fb187e5a78981b9ed6d0929a78a25c2341", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.13.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.13.0", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:exqlite, "~> 0.22", [hex: :exqlite, repo: "hexpm", optional: false]}], "hexpm", "9c3e90ea33099ca0ddd160c8d9eaf80d7d4a9b110d325fa6ed0409858a714606"}, + "ecto_sqlite3": {:hex, :ecto_sqlite3, "0.22.0", "edab2d0f701b7dd05dcf7e2d97769c106aff62b5cfddc000d1dd6f46b9cbd8c3", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.13.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.13.0", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:exqlite, "~> 0.22", [hex: :exqlite, repo: "hexpm", optional: false]}], "hexpm", "5af9e031bffcc5da0b7bca90c271a7b1e7c04a93fecf7f6cd35bc1b1921a64bd"}, "elixir_make": {:hex, :elixir_make, "0.9.0", "6484b3cd8c0cee58f09f05ecaf1a140a8c97670671a6a0e7ab4dc326c3109726", [:mix], [], "hexpm", "db23d4fd8b757462ad02f8aa73431a426fe6671c80b200d9710caf3d1dd0ffdb"}, - "erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"}, + "erlex": {:hex, :erlex, "0.2.8", "cd8116f20f3c0afe376d1e8d1f0ae2452337729f68be016ea544a72f767d9c12", [:mix], [], "hexpm", "9d66ff9fedf69e49dc3fd12831e12a8a37b76f8651dd21cd45fcf5561a8a7590"}, "esbuild": {:hex, :esbuild, "0.10.0", "b0aa3388a1c23e727c5a3e7427c932d89ee791746b0081bbe56103e9ef3d291f", [:mix], [{:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "468489cda427b974a7cc9f03ace55368a83e1a7be12fba7e30969af78e5f8c70"}, - "expo": {:hex, :expo, "1.1.0", "f7b9ed7fb5745ebe1eeedf3d6f29226c5dd52897ac67c0f8af62a07e661e5c75", [:mix], [], "hexpm", "fbadf93f4700fb44c331362177bdca9eeb8097e8b0ef525c9cc501cb9917c960"}, - "exqlite": {:hex, :exqlite, "0.33.0", "2cc96c4227fbb2d0864716def736dff18afb9949b1eaa74630822a0865b4b342", [:make, :mix], [{:cc_precompiler, "~> 0.1", [hex: :cc_precompiler, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.8", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "8a7c2792e567bbebb4dafe96f6397f1c527edd7039d74f508a603817fbad2844"}, + "expo": {:hex, :expo, "1.1.1", "4202e1d2ca6e2b3b63e02f69cfe0a404f77702b041d02b58597c00992b601db5", [:mix], [], "hexpm", "5fb308b9cb359ae200b7e23d37c76978673aa1b06e2b3075d814ce12c5811640"}, + "exqlite": {:hex, :exqlite, "0.33.1", "0465fdb997be174edeba6a27496fa27dfe8bc79ef1324a723daa8f0e8579da24", [:make, :mix], [{:cc_precompiler, "~> 0.1", [hex: :cc_precompiler, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.8", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "b3db0c9ae6e5ee7cf84dd0a1b6dc7566b80912eb7746d45370f5666ed66700f9"}, "file_system": {:hex, :file_system, "1.1.1", "31864f4685b0148f25bd3fbef2b1228457c0c89024ad67f7a81a3ffbc0bbad3a", [:mix], [], "hexpm", "7a15ff97dfe526aeefb090a7a9d3d03aa907e100e262a0f8f7746b78f8f87a5d"}, "finch": {:hex, :finch, "0.20.0", "5330aefb6b010f424dcbbc4615d914e9e3deae40095e73ab0c1bb0968933cadf", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2658131a74d051aabfcba936093c903b8e89da9a1b63e430bee62045fa9b2ee2"}, "fine": {:hex, :fine, "0.1.4", "b19a89c1476c7c57afb5f9314aed5960b5bc95d5277de4cb5ee8e1d1616ce379", [:mix], [], "hexpm", "be3324cc454a42d80951cf6023b9954e9ff27c6daa255483b3e8d608670303f5"}, "floki": {:hex, :floki, "0.38.0", "62b642386fa3f2f90713f6e231da0fa3256e41ef1089f83b6ceac7a3fd3abf33", [:mix], [], "hexpm", "a5943ee91e93fb2d635b612caf5508e36d37548e84928463ef9dd986f0d1abd9"}, "fuse": {:hex, :fuse, "2.5.0", "71afa90be21da4e64f94abba9d36472faa2d799c67fedc3bd1752a88ea4c4753", [:rebar3], [], "hexpm", "7f52a1c84571731ad3c91d569e03131cc220ebaa7e2a11034405f0bac46a4fef"}, "gen_stage": {:hex, :gen_stage, "1.3.2", "7c77e5d1e97de2c6c2f78f306f463bca64bf2f4c3cdd606affc0100b89743b7b", [:mix], [], "hexpm", "0ffae547fa777b3ed889a6b9e1e64566217413d018cabd825f786e843ffe63e7"}, - "gettext": {:hex, :gettext, "1.0.0", "f8853ecb33e96361288f6239fafcfd50214b0a88ec38b5e452138d815d4877d8", [:mix], [{:expo, "~> 0.5.1 or ~> 1.0", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "cc8196640756894a4fd75606067bed41a9863c0db09d6d6cc576e6170cffaa74"}, + "gettext": {:hex, :gettext, "1.0.1", "f5e374f4232c70fd6217d9ef11617cd8450a95b9fdabd3e4802e37a8b63f676b", [:mix], [{:expo, "~> 0.5.1 or ~> 1.0", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "606cb4d7ca52c90223ec8505abaa0398e3f796313fbd7cbcfbdb5d556faaffb5"}, "hackney": {:hex, :hackney, "1.25.0", "390e9b83f31e5b325b9f43b76e1a785cbdb69b5b6cd4e079aa67835ded046867", [:rebar3], [{:certifi, "~> 2.15.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~> 6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~> 1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.4", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.4.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~> 0.7.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "7209bfd75fd1f42467211ff8f59ea74d6f2a9e81cbcee95a56711ee79fd6b1d4"}, "heroicons": {:git, "https://github.com/tailwindlabs/heroicons.git", "88ab3a0d790e6a47404cba02800a6b25d2afae50", [tag: "v2.1.1", sparse: "optimized", depth: 1]}, "hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"}, "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, - "lazy_html": {:hex, :lazy_html, "0.1.7", "53aa9ebdbde8aec7c8ee03a8bdaec38dd56302995b0baeebf8dbe7cbdd550400", [:make, :mix], [{:cc_precompiler, "~> 0.1", [hex: :cc_precompiler, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.9.0", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:fine, "~> 0.1.0", [hex: :fine, repo: "hexpm", optional: false]}], "hexpm", "e115944e6ddb887c45cadfd660348934c318abec0341f7b7156e912b98d3eb95"}, + "lazy_html": {:hex, :lazy_html, "0.1.8", "677a8642e644eef8de98f3040e2520d42d0f0f8bd6c5cd49db36504e34dffe91", [:make, :mix], [{:cc_precompiler, "~> 0.1", [hex: :cc_precompiler, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.9.0", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:fine, "~> 0.1.0", [hex: :fine, repo: "hexpm", optional: false]}], "hexpm", "0d8167d930b704feb94b41414ca7f5779dff9bca7fcf619fcef18de138f08736"}, "logger_backends": {:hex, :logger_backends, "1.0.0", "09c4fad6202e08cb0fbd37f328282f16539aca380f512523ce9472b28edc6bdf", [:mix], [], "hexpm", "1faceb3e7ec3ef66a8f5746c5afd020e63996df6fd4eb8cdb789e5665ae6c9ce"}, "logger_file_backend": {:hex, :logger_file_backend, "0.0.14", "774bb661f1c3fed51b624d2859180c01e386eb1273dc22de4f4a155ef749a602", [:mix], [], "hexpm", "071354a18196468f3904ef09413af20971d55164267427f6257b52cfba03f9e6"}, - "meck": {:hex, :meck, "1.0.0", "24676cb6ee6951530093a93edcd410cfe4cb59fe89444b875d35c9d3909a15d0", [:rebar3], [], "hexpm", "680a9bcfe52764350beb9fb0335fb75fee8e7329821416cee0a19fec35433882"}, + "meck": {:hex, :meck, "1.1.0", "e65a3d84d7b418afcb2c8efde2b5106a98eefb7fe8e5f7e324fe9765122aefa2", [:rebar3], [], "hexpm", "0fdfbd4d4f9eb9251ba621f4740a6e450e2a7d0e5e07a37830c5cf632f2ca8bb"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mime": {:hex, :mime, "2.0.7", "b8d739037be7cd402aee1ba0306edfdef982687ee7e9859bee6198c1e7e2f128", [:mix], [], "hexpm", "6171188e399ee16023ffc5b76ce445eb6d9672e2e241d2df6050f3c771e80ccd"}, "mimerl": {:hex, :mimerl, "1.4.0", "3882a5ca67fbbe7117ba8947f27643557adec38fa2307490c4c4207624cb213b", [:rebar3], [], "hexpm", "13af15f9f68c65884ecca3a3891d50a7b57d82152792f3e19d88650aa126b144"}, @@ -49,11 +49,11 @@ "parse_trans": {:hex, :parse_trans, "3.4.1", "6e6aa8167cb44cc8f39441d05193be6e6f4e7c2946cb2759f015f8c56b76e5ff", [:rebar3], [], "hexpm", "620a406ce75dada827b82e453c19cf06776be266f5a67cff34e1ef2cbb60e49a"}, "phoenix": {:hex, :phoenix, "1.8.1", "865473a60a979551a4879db79fbfb4503e41cd809e77c85af79716578b6a456d", [:mix], [{:bandit, "~> 1.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.7", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "84d77d2b2e77c3c7e7527099bd01ef5c8560cd149c036d6b3a40745f11cd2fb2"}, "phoenix_ecto": {:hex, :phoenix_ecto, "4.6.5", "c4ef322acd15a574a8b1a08eff0ee0a85e73096b53ce1403b6563709f15e1cea", [:mix], [{:ecto, "~> 3.5", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.1", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "26ec3208eef407f31b748cadd044045c6fd485fbff168e35963d2f9dfff28d4b"}, - "phoenix_html": {:hex, :phoenix_html, "4.2.1", "35279e2a39140068fc03f8874408d58eef734e488fc142153f055c5454fd1c08", [:mix], [], "hexpm", "cff108100ae2715dd959ae8f2a8cef8e20b593f8dfd031c9cba92702cf23e053"}, + "phoenix_html": {:hex, :phoenix_html, "4.3.0", "d3577a5df4b6954cd7890c84d955c470b5310bb49647f0a114a6eeecc850f7ad", [:mix], [], "hexpm", "3eaa290a78bab0f075f791a46a981bbe769d94bc776869f4f3063a14f30497ad"}, "phoenix_live_dashboard": {:hex, :phoenix_live_dashboard, "0.8.7", "405880012cb4b706f26dd1c6349125bfc903fb9e44d1ea668adaf4e04d4884b7", [:mix], [{:ecto, "~> 3.6.2 or ~> 3.7", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_mysql_extras, "~> 0.5", [hex: :ecto_mysql_extras, repo: "hexpm", optional: true]}, {:ecto_psql_extras, "~> 0.7", [hex: :ecto_psql_extras, repo: "hexpm", optional: true]}, {:ecto_sqlite3_extras, "~> 1.1.7 or ~> 1.2.0", [hex: :ecto_sqlite3_extras, repo: "hexpm", optional: true]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.19 or ~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6 or ~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "3a8625cab39ec261d48a13b7468dc619c0ede099601b084e343968309bd4d7d7"}, "phoenix_live_reload": {:hex, :phoenix_live_reload, "1.6.1", "05df733a09887a005ed0d69a7fc619d376aea2730bf64ce52ac51ce716cc1ef0", [:mix], [{:file_system, "~> 0.2.10 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "74273843d5a6e4fef0bbc17599f33e3ec63f08e69215623a0cd91eea4288e5a0"}, - "phoenix_live_view": {:hex, :phoenix_live_view, "1.1.11", "1b4d8fa56898d93b6f528c89227198a3fce7c5b242819b22ed9e92b73c1bb077", [:mix], [{:igniter, ">= 0.6.16 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:lazy_html, "~> 0.1.0", [hex: :lazy_html, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0 or ~> 1.8.0-rc", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.15", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "266823602e11a54e562ac03a25b3d232d79de12514262db7cfcbb83fdfd8fd57"}, - "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.3", "3168d78ba41835aecad272d5e8cd51aa87a7ac9eb836eabc42f6e57538e3731d", [:mix], [], "hexpm", "bba06bc1dcfd8cb086759f0edc94a8ba2bc8896d5331a1e2c2902bf8e36ee502"}, + "phoenix_live_view": {:hex, :phoenix_live_view, "1.1.17", "1d782b5901cf13b137c6d8c56542ff6cb618359b2adca7e185b21df728fa0c6c", [:mix], [{:igniter, ">= 0.6.16 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:lazy_html, "~> 0.1.0", [hex: :lazy_html, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0 or ~> 1.8.0-rc", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.15", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "fa82307dd9305657a8236d6b48e60ef2e8d9f742ee7ed832de4b8bcb7e0e5ed2"}, + "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.2.0", "ff3a5616e1bed6804de7773b92cbccfc0b0f473faf1f63d7daf1206c7aeaaa6f", [:mix], [], "hexpm", "adc313a5bf7136039f63cfd9668fde73bba0765e0614cba80c06ac9460ff3e96"}, "phoenix_template": {:hex, :phoenix_template, "1.0.4", "e2092c132f3b5e5b2d49c96695342eb36d0ed514c5b252a77048d5969330d639", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "2c0c81f0e5c6753faf5cca2f229c9709919aba34fab866d3bc05060c9c444206"}, "plug": {:hex, :plug, "1.18.1", "5067f26f7745b7e31bc3368bc1a2b818b9779faa959b49c934c17730efc911cf", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "57a57db70df2b422b564437d2d33cf8d33cd16339c1edb190cd11b1a3a546cc2"}, "plug_crypto": {:hex, :plug_crypto, "2.1.1", "19bda8184399cb24afa10be734f84a16ea0a2bc65054e23a62bb10f06bc89491", [:mix], [], "hexpm", "6470bce6ffe41c8bd497612ffde1a7e4af67f36a15eea5f921af71cf3e11247c"}, @@ -62,15 +62,15 @@ "req_fuse": {:hex, :req_fuse, "0.3.2", "8f96b26527deefe3d128496c058a23014754a569d12d281905d4c9e56bc3bae2", [:mix], [{:fuse, ">= 2.4.0", [hex: :fuse, repo: "hexpm", optional: false]}, {:req, ">= 0.4.14", [hex: :req, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "55cf642c03f10aed0dc4f97adc10f0985b355b377d2bc32bb0c569d82f3aa07e"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"}, "stream_data": {:hex, :stream_data, "1.2.0", "58dd3f9e88afe27dc38bef26fce0c84a9e7a96772b2925c7b32cd2435697a52b", [:mix], [], "hexpm", "eb5c546ee3466920314643edf68943a5b14b32d1da9fe01698dc92b73f89a9ed"}, - "swoosh": {:hex, :swoosh, "1.19.5", "5abd71be78302ba21be56a2b68d05c9946ff1f1bd254f949efef09d253b771ac", [:mix], [{:bandit, ">= 1.0.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mua, "~> 0.2.3", [hex: :mua, repo: "hexpm", optional: true]}, {:multipart, "~> 0.4", [hex: :multipart, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:req, "~> 0.5.10 or ~> 0.6 or ~> 1.0", [hex: :req, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c953f51ee0a8b237e0f4307c9cefd3eb1eb751c35fcdda2a8bccb991766473be"}, - "tailwind": {:hex, :tailwind, "0.4.0", "4b2606713080437e3d94a0fa26527e7425737abc001f172b484b42f43e3274c0", [:mix], [], "hexpm", "530bd35699333f8ea0e9038d7146c2f0932dfec2e3636bd4a8016380c4bc382e"}, + "swoosh": {:hex, :swoosh, "1.19.8", "0576f2ea96d1bb3a6e02cc9f79cbd7d497babc49a353eef8dce1a1f9f82d7915", [:mix], [{:bandit, ">= 1.0.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:idna, "~> 6.0", [hex: :idna, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mua, "~> 0.2.3", [hex: :mua, repo: "hexpm", optional: true]}, {:multipart, "~> 0.4", [hex: :multipart, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:req, "~> 0.5.10 or ~> 0.6 or ~> 1.0", [hex: :req, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d7503c2daf0f9899afd8eba9923eeddef4b62e70816e1d3b6766e4d6c60e94ad"}, + "tailwind": {:hex, :tailwind, "0.4.1", "e7bcc222fe96a1e55f948e76d13dd84a1a7653fb051d2a167135db3b4b08d3e9", [:mix], [], "hexpm", "6249d4f9819052911120dbdbe9e532e6bd64ea23476056adb7f730aa25c220d1"}, "telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"}, "telemetry_metrics": {:hex, :telemetry_metrics, "1.1.0", "5bd5f3b5637e0abea0426b947e3ce5dd304f8b3bc6617039e2b5a008adc02f8f", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "e7b79e8ddfde70adb6db8a6623d1778ec66401f366e9a8f5dd0955c56bc8ce67"}, "telemetry_poller": {:hex, :telemetry_poller, "1.3.0", "d5c46420126b5ac2d72bc6580fb4f537d35e851cc0f8dbd571acf6d6e10f5ec7", [:rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "51f18bed7128544a50f75897db9974436ea9bfba560420b646af27a9a9b35211"}, - "thousand_island": {:hex, :thousand_island, "1.4.1", "8df065e627407e281f7935da5ad0f3842d10eb721afa92e760b720d71e2e37aa", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "204a8640e5d2818589b87286ae66160978628d7edf6095181cbe0440765fb6c1"}, + "thousand_island": {:hex, :thousand_island, "1.4.2", "735fa783005d1703359bbd2d3a5a3a398075ba4456e5afe3c5b7cf4666303d36", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "1c7637f16558fc1c35746d5ee0e83b18b8e59e18d28affd1f2fa1645f8bc7473"}, "timex": {:hex, :timex, "3.7.11", "bb95cb4eb1d06e27346325de506bcc6c30f9c6dea40d1ebe390b262fad1862d1", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.20", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.1", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "8b9024f7efbabaf9bd7aa04f65cf8dcd7c9818ca5737677c7b76acbc6a94d1aa"}, "tzdata": {:hex, :tzdata, "1.1.3", "b1cef7bb6de1de90d4ddc25d33892b32830f907e7fc2fccd1e7e22778ab7dfbc", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "d4ca85575a064d29d4e94253ee95912edfb165938743dbf002acdf0dcecb0c28"}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.1", "a48703a25c170eedadca83b11e88985af08d35f37c6f664d6dcfb106a97782fc", [:rebar3], [], "hexpm", "b3a917854ce3ae233619744ad1e0102e05673136776fb2fa76234f3e03b23642"}, "websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"}, - "websock_adapter": {:hex, :websock_adapter, "0.5.8", "3b97dc94e407e2d1fc666b2fb9acf6be81a1798a2602294aac000260a7c4a47d", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "315b9a1865552212b5f35140ad194e67ce31af45bcee443d4ecb96b5fd3f3782"}, + "websock_adapter": {:hex, :websock_adapter, "0.5.9", "43dc3ba6d89ef5dec5b1d0a39698436a1e856d000d84bf31a3149862b01a287f", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "5534d5c9adad3c18a0f58a9371220d75a803bf0b9a3d87e6fe072faaeed76a08"}, } diff --git a/test/reencodarr/media/video_upsert_test.exs b/test/reencodarr/media/video_upsert_test.exs index 7ec0045d..53a52469 100644 --- a/test/reencodarr/media/video_upsert_test.exs +++ b/test/reencodarr/media/video_upsert_test.exs @@ -2,8 +2,7 @@ defmodule Reencodarr.Media.VideoUpsertTest do use Reencodarr.DataCase import ExUnit.CaptureLog - alias Reencodarr.Media.VideoUpsert - alias Reencodarr.Media.{Library, Video} + alias Reencodarr.Media.{Library, Video, VideoUpsert} alias Reencodarr.Repo setup do