Compare commits

..

6 Commits

Author SHA1 Message Date
Kieran Eglin b8da973a81 Bumped version 2024-06-25 08:19:06 -07:00
Kieran a46cfd1888 [Bugfix] Check for regex errors before saving a source (#296)
* Added error if provided regex is invalid

* improved test
2024-06-20 12:48:52 -07:00
Kieran Eglin f08768b887 Updated formatter 2024-06-20 11:33:49 -07:00
Kieran Eglin 199d0065e1 Updated screenshots 2024-06-14 09:23:40 -07:00
Kieran 781061b483 [Dev] Reduce config file clutter (#290)
* Added local tooling config files to the tooling/ directory

* Moved as many docker-related files as possible

* Updated dockerfile path

* Updated the correct dockerfile instead how about

* Off day - jeez louise

* Juggled around some more dockerfiles

* more dockerfile

* More docker tests

* it's docker time

* One more shot
2024-06-13 16:21:09 -07:00
Kieran 132f8e8da6 [Dev] Upgrade to Elixir 1.17.0 (#289)
* upgraded to Elixir 1.17.0

* Addressed deprecation warnings

* Updated Credo
2024-06-13 10:05:03 -07:00
24 changed files with 60 additions and 30 deletions
+2
View File
@@ -1,3 +1,5 @@
# TODO: figure out why my vscode extension doesn't respect the formatter.exs file
# if it's in a subdirectory
[ [
import_deps: [:ecto, :ecto_sql, :phoenix], import_deps: [:ecto, :ecto_sql, :phoenix],
subdirectories: ["priv/*/migrations"], subdirectories: ["priv/*/migrations"],
+1 -1
View File
@@ -75,7 +75,7 @@ jobs:
uses: docker/build-push-action@v5 uses: docker/build-push-action@v5
with: with:
context: . context: .
file: ./selfhosted.Dockerfile file: ./docker/selfhosted.Dockerfile
# If the event is a release, use the release_arch, otherwise use the # If the event is a release, use the release_arch, otherwise use the
# platforms input if present, falling back to dev_arch # platforms input if present, falling back to dev_arch
platforms: ${{ github.event_name == 'release' && env.release_arch || (github.event.inputs.platforms || env.dev_arch) }} platforms: ${{ github.event_name == 'release' && env.release_arch || (github.event.inputs.platforms || env.dev_arch) }}
-3
View File
@@ -1,3 +0,0 @@
assets/vendor/
deps/
_build/
+3 -3
View File
@@ -71,8 +71,8 @@ If it doesn't work for your use case, please make a feature request! You can als
## Screenshots ## Screenshots
<img src="priv/static/images/app-form-screenshot.png" alt="Pinchflat screenshot" width="700" /> <img src="priv/static/images/app-form-screenshot.jpg" alt="Pinchflat screenshot" width="700" />
<img src="priv/static/images/app-screenshot.png" alt="Pinchflat screenshot" width="700" /> <img src="priv/static/images/app-screenshot.jpg" alt="Pinchflat screenshot" width="700" />
## Installation ## Installation
@@ -108,7 +108,7 @@ services:
2. Prepare the docker image in one of the two ways below: 2. Prepare the docker image in one of the two ways below:
- **From GHCR:** `docker pull ghcr.io/kieraneglin/pinchflat:latest` - **From GHCR:** `docker pull ghcr.io/kieraneglin/pinchflat:latest`
- NOTE: also available on Docker Hub at `keglin/pinchflat:latest` - NOTE: also available on Docker Hub at `keglin/pinchflat:latest`
- **Building locally:** `docker build . --file selfhosted.Dockerfile -t ghcr.io/kieraneglin/pinchflat:latest` - **Building locally:** `docker build . --file docker/selfhosted.Dockerfile -t ghcr.io/kieraneglin/pinchflat:latest`
3. Run the container: 3. Run the container:
```bash ```bash
+1 -2
View File
@@ -1,9 +1,8 @@
version: '3'
services: services:
phx: phx:
build: build:
context: . context: .
dockerfile: dev.Dockerfile dockerfile: ./docker/dev.Dockerfile
environment: environment:
- MIX_ENV=test - MIX_ENV=test
volumes: volumes:
+2 -4
View File
@@ -1,15 +1,13 @@
version: '3'
services: services:
phx: phx:
build: build:
context: . context: .
dockerfile: dev.Dockerfile dockerfile: ./docker/dev.Dockerfile
volumes: volumes:
- '.:/app' - '.:/app'
ports: ports:
- '4008:4008' - '4008:4008'
command: command: bash -c "chmod +x docker/docker-run.dev.sh && docker/docker-run.dev.sh"
- ./docker-run.dev.sh
stdin_open: true stdin_open: true
tty: true tty: true
env_file: env_file:
+3 -6
View File
@@ -1,6 +1,6 @@
ARG ELIXIR_VERSION=1.16.2 ARG ELIXIR_VERSION=1.17.0
ARG OTP_VERSION=26.2.2 ARG OTP_VERSION=26.2.5
ARG DEBIAN_VERSION=bookworm-20240130 ARG DEBIAN_VERSION=bookworm-20240612-slim
ARG DEV_IMAGE="hexpm/elixir:${ELIXIR_VERSION}-erlang-${OTP_VERSION}-debian-${DEBIAN_VERSION}" ARG DEV_IMAGE="hexpm/elixir:${ELIXIR_VERSION}-erlang-${OTP_VERSION}-debian-${DEBIAN_VERSION}"
FROM ${DEV_IMAGE} FROM ${DEV_IMAGE}
@@ -53,9 +53,6 @@ ENV LC_ALL en_US.UTF-8
WORKDIR /app WORKDIR /app
COPY . ./ COPY . ./
# Needs permissions to be updated AFTER the copy step
RUN chmod +x ./docker-run.dev.sh
# Install Elixir deps # Install Elixir deps
# RUN mix archive.install github hexpm/hex branch latest # RUN mix archive.install github hexpm/hex branch latest
RUN mix deps.get RUN mix deps.get
@@ -1,8 +1,8 @@
# Find eligible builder and runner images on Docker Hub. We use Ubuntu/Debian # Find eligible builder and runner images on Docker Hub. We use Ubuntu/Debian
# instead of Alpine to avoid DNS resolution issues in production. # instead of Alpine to avoid DNS resolution issues in production.
ARG ELIXIR_VERSION=1.16.2 ARG ELIXIR_VERSION=1.17.0
ARG OTP_VERSION=26.2.2 ARG OTP_VERSION=26.2.5
ARG DEBIAN_VERSION=bookworm-20240130-slim ARG DEBIAN_VERSION=bookworm-20240612-slim
ARG BUILDER_IMAGE="hexpm/elixir:${ELIXIR_VERSION}-erlang-${OTP_VERSION}-debian-${DEBIAN_VERSION}" ARG BUILDER_IMAGE="hexpm/elixir:${ELIXIR_VERSION}-erlang-${OTP_VERSION}-debian-${DEBIAN_VERSION}"
ARG RUNNER_IMAGE="debian:${DEBIAN_VERSION}" ARG RUNNER_IMAGE="debian:${DEBIAN_VERSION}"
@@ -49,7 +49,7 @@ defmodule Pinchflat.Metadata.MetadataFileHelpers do
Returns {:ok, map()} | {:error, any} Returns {:ok, map()} | {:error, any}
""" """
def read_compressed_metadata(filepath) do def read_compressed_metadata(filepath) do
{:ok, json} = File.open(filepath, [:read, :compressed], &IO.read(&1, :all)) {:ok, json} = File.open(filepath, [:read, :compressed], &IO.read(&1, :eof))
Phoenix.json_library().decode(json) Phoenix.json_library().decode(json)
end end
+10
View File
@@ -112,6 +112,7 @@ defmodule Pinchflat.Sources.Source do
|> dynamic_default(:custom_name, fn cs -> get_field(cs, :collection_name) end) |> dynamic_default(:custom_name, fn cs -> get_field(cs, :collection_name) end)
|> dynamic_default(:uuid, fn _ -> Ecto.UUID.generate() end) |> dynamic_default(:uuid, fn _ -> Ecto.UUID.generate() end)
|> validate_required(required_fields) |> validate_required(required_fields)
|> validate_title_regex()
|> validate_number(:retention_period_days, greater_than_or_equal_to: 0) |> validate_number(:retention_period_days, greater_than_or_equal_to: 0)
# Ensures it ends with `.{{ ext }}` or `.%(ext)s` or similar (with a little wiggle room) # Ensures it ends with `.{{ ext }}` or `.%(ext)s` or similar (with a little wiggle room)
|> validate_format(:output_path_template_override, MediaProfile.ext_regex(), message: "must end with .{{ ext }}") |> validate_format(:output_path_template_override, MediaProfile.ext_regex(), message: "must end with .{{ ext }}")
@@ -149,6 +150,15 @@ defmodule Pinchflat.Sources.Source do
~r<^(?:(?!youtube\.com/(watch|shorts|embed)|youtu\.be).)*$> ~r<^(?:(?!youtube\.com/(watch|shorts|embed)|youtu\.be).)*$>
end end
defp validate_title_regex(%{changes: %{title_filter_regex: regex}} = changeset) when is_binary(regex) do
case Ecto.Adapters.SQL.query(Repo, "SELECT regexp_like('', ?)", [regex]) do
{:ok, _} -> changeset
_ -> add_error(changeset, :title_filter_regex, "is invalid")
end
end
defp validate_title_regex(changeset), do: changeset
defimpl Jason.Encoder, for: Source do defimpl Jason.Encoder, for: Source do
def encode(value, opts) do def encode(value, opts) do
value value
+5 -3
View File
@@ -4,8 +4,8 @@ defmodule Pinchflat.MixProject do
def project do def project do
[ [
app: :pinchflat, app: :pinchflat,
version: "2024.6.10", version: "2024.6.25",
elixir: "~> 1.16", elixir: "~> 1.17",
elixirc_paths: elixirc_paths(Mix.env()), elixirc_paths: elixirc_paths(Mix.env()),
start_permanent: Mix.env() == :prod, start_permanent: Mix.env() == :prod,
aliases: aliases(), aliases: aliases(),
@@ -71,7 +71,7 @@ defmodule Pinchflat.MixProject do
{:nimble_parsec, "~> 1.4"}, {:nimble_parsec, "~> 1.4"},
{:timex, "~> 3.0"}, {:timex, "~> 3.0"},
{:mox, "~> 1.0", only: :test}, {:mox, "~> 1.0", only: :test},
{:credo, "~> 1.7", only: [:dev, :test], runtime: false}, {:credo, "~> 1.7.7", only: [:dev, :test], runtime: false},
{:credo_naming, "~> 2.1", only: [:dev, :test], runtime: false}, {:credo_naming, "~> 2.1", only: [:dev, :test], runtime: false},
{:ex_check, "~> 0.14.0", only: [:dev, :test], runtime: false}, {:ex_check, "~> 0.14.0", only: [:dev, :test], runtime: false},
{:faker, "~> 0.17", only: :test}, {:faker, "~> 0.17", only: :test},
@@ -87,6 +87,8 @@ defmodule Pinchflat.MixProject do
# See the documentation for `Mix` for more info on aliases. # See the documentation for `Mix` for more info on aliases.
defp aliases do defp aliases do
[ [
check: "check --config=tooling/.check.exs",
credo: "credo --config-file=tooling/.credo.exs",
setup: ["deps.get", "ecto.setup", "assets.setup", "assets.build"], setup: ["deps.get", "ecto.setup", "assets.setup", "assets.build"],
"ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"], "ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
"ecto.reset": ["ecto.drop", "ecto.setup"], "ecto.reset": ["ecto.drop", "ecto.setup"],
+1 -1
View File
@@ -7,7 +7,7 @@
"cowboy": {:hex, :cowboy, "2.10.0", "ff9ffeff91dae4ae270dd975642997afe2a1179d94b1887863e43f681a203e26", [:make, :rebar3], [{:cowlib, "2.12.1", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "3afdccb7183cc6f143cb14d3cf51fa00e53db9ec80cdcd525482f5e99bc41d6b"}, "cowboy": {:hex, :cowboy, "2.10.0", "ff9ffeff91dae4ae270dd975642997afe2a1179d94b1887863e43f681a203e26", [:make, :rebar3], [{:cowlib, "2.12.1", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "3afdccb7183cc6f143cb14d3cf51fa00e53db9ec80cdcd525482f5e99bc41d6b"},
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"}, "cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"},
"cowlib": {:hex, :cowlib, "2.12.1", "a9fa9a625f1d2025fe6b462cb865881329b5caff8f1854d1cbc9f9533f00e1e1", [:make, :rebar3], [], "hexpm", "163b73f6367a7341b33c794c4e88e7dbfe6498ac42dcd69ef44c5bc5507c8db0"}, "cowlib": {:hex, :cowlib, "2.12.1", "a9fa9a625f1d2025fe6b462cb865881329b5caff8f1854d1cbc9f9533f00e1e1", [:make, :rebar3], [], "hexpm", "163b73f6367a7341b33c794c4e88e7dbfe6498ac42dcd69ef44c5bc5507c8db0"},
"credo": {:hex, :credo, "1.7.3", "05bb11eaf2f2b8db370ecaa6a6bda2ec49b2acd5e0418bc106b73b07128c0436", [: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", "35ea675a094c934c22fb1dca3696f3c31f2728ae6ef5a53b5d648c11180a4535"}, "credo": {:hex, :credo, "1.7.7", "771445037228f763f9b2afd612b6aa2fd8e28432a95dbbc60d8e03ce71ba4446", [: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", "8bc87496c9aaacdc3f90f01b7b0582467b69b4bd2441fe8aae3109d843cc2f2e"},
"credo_naming": {:hex, :credo_naming, "2.1.0", "d44ad58890d4db552e141ce64756a74ac1573665af766d1ac64931aa90d47744", [:make, :mix], [{:credo, "~> 1.6", [hex: :credo, repo: "hexpm", optional: false]}], "hexpm", "830e23b3fba972e2fccec49c0c089fe78c1e64bc16782a2682d78082351a2909"}, "credo_naming": {:hex, :credo_naming, "2.1.0", "d44ad58890d4db552e141ce64756a74ac1573665af766d1ac64931aa90d47744", [:make, :mix], [{:credo, "~> 1.6", [hex: :credo, repo: "hexpm", optional: false]}], "hexpm", "830e23b3fba972e2fccec49c0c089fe78c1e64bc16782a2682d78082351a2909"},
"db_connection": {:hex, :db_connection, "2.6.0", "77d835c472b5b67fc4f29556dee74bf511bbafecdcaf98c27d27fa5918152086", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c2f992d15725e721ec7fbc1189d4ecdb8afef76648c746a8e1cad35e3b8a35f3"}, "db_connection": {:hex, :db_connection, "2.6.0", "77d835c472b5b67fc4f29556dee74bf511bbafecdcaf98c27d27fa5918152086", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c2f992d15725e721ec7fbc1189d4ecdb8afef76648c746a8e1cad35e3b8a35f3"},
"decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"}, "decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"},
+3 -1
View File
@@ -5,7 +5,9 @@
"sqleton": "^2.2.0" "sqleton": "^2.2.0"
}, },
"scripts": { "scripts": {
"create-erd": "sqleton -o priv/repo/erd.png priv/repo/pinchflat_dev.db" "create-erd": "sqleton -o priv/repo/erd.png priv/repo/pinchflat_dev.db",
"lint:check": "prettier . --check --config=tooling/.prettierrc.js --ignore-path=tooling/.prettierignore --ignore-path=.gitignore",
"lint:fix": "prettier . --write --config=tooling/.prettierrc.js --ignore-path=tooling/.prettierignore --ignore-path=.gitignore"
}, },
"private": true "private": true
} }
Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

@@ -32,7 +32,7 @@ defmodule Pinchflat.Metadata.MetadataFileHelpersTest do
metadata_map = %{"foo" => "bar"} metadata_map = %{"foo" => "bar"}
filepath = Helpers.compress_and_store_metadata_for(media_item, metadata_map) filepath = Helpers.compress_and_store_metadata_for(media_item, metadata_map)
{:ok, json} = File.open(filepath, [:read, :compressed], &IO.read(&1, :all)) {:ok, json} = File.open(filepath, [:read, :compressed], &IO.read(&1, :eof))
assert json == Phoenix.json_library().encode!(metadata_map) assert json == Phoenix.json_library().encode!(metadata_map)
end end
+22
View File
@@ -659,6 +659,28 @@ defmodule Pinchflat.SourcesTest do
end end
end end
describe "change_source/3 when testing regex validation" do
test "succeeds when a valid regex is provided" do
source = source_fixture()
assert %{errors: []} = Sources.change_source(source, %{title_filter_regex: "(?i)^How to Bike$"})
end
test "succeeds when a regex is set back to nil" do
source = source_fixture(%{title_filter_regex: "(?i)^How to Bike$"})
assert %{errors: []} = Sources.change_source(source, %{title_filter_regex: nil})
end
test "fails when an invalid regex is provided" do
source = source_fixture()
changeset = Sources.change_source(source, %{title_filter_regex: "*FOO"})
assert "is invalid" in errors_on(changeset).title_filter_regex
end
end
describe "change_source/3 when testing original_url validation" do describe "change_source/3 when testing original_url validation" do
test "succeeds when an original URL is valid" do test "succeeds when an original URL is valid" do
source = source_fixture() source = source_fixture()
+1 -1
View File
@@ -16,7 +16,7 @@
{:compiler, env: %{"MIX_ENV" => "test"}}, {:compiler, env: %{"MIX_ENV" => "test"}},
{:formatter, env: %{"MIX_ENV" => "test"}}, {:formatter, env: %{"MIX_ENV" => "test"}},
{:sobelow, "mix sobelow --config"}, {:sobelow, "mix sobelow --config"},
{:prettier_formatting, "yarn run prettier . --check", fix: "yarn run prettier . --write"}, {:prettier_formatting, "yarn run lint:check", fix: "yarn run lint:fix"},
{:npm_test, false} {:npm_test, false}
## curated tools may be disabled (e.g. the check for compilation warnings) ## curated tools may be disabled (e.g. the check for compilation warnings)
View File
+1
View File
@@ -0,0 +1 @@
../assets/vendor/