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:
@@ -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.
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user