Search v1 (#19)

* Adds description to media items; hooks it up to indexing/media downloading

* Added a search method using postgres fulltext search

* Hooked up search functionality to the search form

* Added persistence to the search form when on search page
This commit is contained in:
Kieran
2024-02-13 14:46:14 -08:00
committed by GitHub
parent 219320ce11
commit 060e340558
25 changed files with 261 additions and 25 deletions
+34
View File
@@ -47,6 +47,40 @@ defmodule Pinchflat.Media do
|> Repo.all()
end
@doc """
Returns a list of media_items that match the search term. Adds a `matching_search_term`
virtual field to the result set.
Returns [%MediaItem{}, ...].
"""
def search(search_term, opts \\ []) do
limit = Keyword.get(opts, :limit, 50)
from(mi in MediaItem,
where: fragment("searchable @@ websearch_to_tsquery(?)", ^search_term),
select_merge: %{
matching_search_term:
fragment(
"""
ts_headline(
'english',
CONCAT(title, ' ', description),
websearch_to_tsquery(?),
'StartSel=[PF_HIGHLIGHT],StopSel=[/PF_HIGHLIGHT]'
)
""",
^search_term
)
},
order_by: {
:desc,
fragment("ts_rank_cd(searchable, websearch_to_tsquery(?), 0)", ^search_term)
},
limit: ^limit
)
|> Repo.all()
end
@doc """
Gets a single media_item.
+4
View File
@@ -13,6 +13,7 @@ defmodule Pinchflat.Media.MediaItem do
@allowed_fields ~w(
title
media_id
description
original_url
livestream
media_downloaded_at
@@ -27,6 +28,7 @@ defmodule Pinchflat.Media.MediaItem do
schema "media_items" do
field :title, :string
field :media_id, :string
field :description, :string
field :original_url, :string
field :livestream, :boolean, default: false
field :media_downloaded_at, :utc_datetime
@@ -39,6 +41,8 @@ defmodule Pinchflat.Media.MediaItem do
# Will very likely revisit because I can't leave well-enough alone.
field :subtitle_filepaths, {:array, {:array, :string}}, default: []
field :matching_search_term, :string, virtual: true
belongs_to :source, Source
has_one :metadata, MediaMetadata, on_replace: :update
@@ -32,6 +32,7 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.MetadataParser do
defp parse_media_metadata(metadata) do
%{
title: metadata["title"],
description: metadata["description"],
media_filepath: metadata["filepath"]
}
end
@@ -14,8 +14,9 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.VideoCollection do
def get_media_attributes(url, command_opts \\ []) do
runner = Application.get_env(:pinchflat, :yt_dlp_runner)
opts = command_opts ++ [:simulate, :skip_download]
output_template = "%(.{id,title,was_live,original_url,description})j"
case runner.run(url, opts, "%(.{id,title,was_live,original_url})j") do
case runner.run(url, opts, output_template) do
{:ok, output} ->
output
|> String.split("\n", trim: true)
+2 -1
View File
@@ -52,7 +52,8 @@ defmodule Pinchflat.Tasks.SourceTasks do
title: media_attrs["title"],
media_id: media_attrs["id"],
original_url: media_attrs["original_url"],
livestream: media_attrs["was_live"]
livestream: media_attrs["was_live"],
description: media_attrs["description"]
}
case Media.create_media_item(attrs) do
+17
View File
@@ -24,4 +24,21 @@ defmodule Pinchflat.Utils.StringUtils do
|> Base.encode16(case: :lower)
|> String.slice(0..(length - 1))
end
@doc """
Truncates a string to the given length and adds `...` if the string is longer than the given length.
Will break on a word boundary. Nothing happens if the string is shorter than the given length.
Returns binary()
"""
def truncate(string, length) do
if String.length(string) > length do
string
|> String.slice(0..(length - 1))
|> String.replace(~r/\s+\S*$/, "")
|> Kernel.<>("...")
else
string
end
end
end