fix: issue #7 rebuild media links to get gallery working again
This commit is contained in:
@@ -196,6 +196,14 @@ defmodule BDS.Desktop.ShellCommands do
|
||||
end)
|
||||
end
|
||||
|
||||
defp dispatch("rebuild_media_links", project, _params) do
|
||||
queue_task(project, "rebuild_media_links", "Rebuild Media Links", "Maintenance", fn report ->
|
||||
{:ok, result} = BDS.Media.rebuild_media_links(project.id, on_progress: report)
|
||||
report.(1.0, "Media links rebuilt")
|
||||
%{project_id: project.id, counts: %{media_links: result.links}}
|
||||
end)
|
||||
end
|
||||
|
||||
defp dispatch("regenerate_missing_thumbnails", project, _params) do
|
||||
queue_task(
|
||||
project,
|
||||
|
||||
@@ -375,7 +375,8 @@
|
||||
<button class="secondary ui-button ui-button-secondary" type="button" phx-click="settings_shell_command" phx-value-action="rebuild_media_from_files"><%= dgettext("ui", "Rebuild Media From Files") %></button>
|
||||
<button class="secondary ui-button ui-button-secondary" type="button" phx-click="settings_shell_command" phx-value-action="rebuild_scripts_from_files"><%= dgettext("ui", "Rebuild Scripts From Files") %></button>
|
||||
<button class="secondary ui-button ui-button-secondary" type="button" phx-click="settings_shell_command" phx-value-action="rebuild_templates_from_files"><%= dgettext("ui", "Rebuild Templates From Files") %></button>
|
||||
<button class="secondary ui-button ui-button-secondary" type="button" phx-click="settings_shell_command" phx-value-action="rebuild_post_links"><%= dgettext("ui", "Rebuild Links") %></button>
|
||||
<button class="secondary ui-button ui-button-secondary" type="button" phx-click="settings_shell_command" phx-value-action="rebuild_post_links"><%= dgettext("ui", "Rebuild Post Links") %></button>
|
||||
<button class="secondary ui-button ui-button-secondary" type="button" phx-click="settings_shell_command" phx-value-action="rebuild_media_links"><%= dgettext("ui", "Rebuild Media Links") %></button>
|
||||
<button class="secondary ui-button ui-button-secondary" type="button" phx-click="settings_shell_command" phx-value-action="regenerate_missing_thumbnails"><%= dgettext("ui", "Regenerate Missing Thumbnails") %></button>
|
||||
<button class="secondary ui-button ui-button-secondary" type="button" phx-click="settings_shell_command" phx-value-action="rebuild_embedding_index"><%= dgettext("ui", "Rebuild Embedding Index") %></button>
|
||||
<button class="secondary ui-button ui-button-secondary" type="button" phx-click="settings_shell_command" phx-value-action="open_data_folder"><%= dgettext("ui", "Open Data Folder") %></button>
|
||||
|
||||
@@ -66,6 +66,12 @@ defmodule BDS.Media do
|
||||
defdelegate link_media_to_post(media_id, post_id), to: BDS.Media.Linking
|
||||
defdelegate unlink_media_from_post(media_id, post_id), to: BDS.Media.Linking
|
||||
|
||||
defdelegate rebuild_media_links(project_id), to: BDS.Media.Linking,
|
||||
as: :rebuild_links_from_sidecars
|
||||
|
||||
defdelegate rebuild_media_links(project_id, opts), to: BDS.Media.Linking,
|
||||
as: :rebuild_links_from_sidecars
|
||||
|
||||
defdelegate rebuild_media_from_files(project_id), to: BDS.Media.Rebuilder
|
||||
defdelegate rebuild_media_from_files(project_id, opts), to: BDS.Media.Rebuilder
|
||||
|
||||
|
||||
@@ -5,6 +5,13 @@ defmodule BDS.Media.Linking do
|
||||
|
||||
import Ecto.Query
|
||||
|
||||
import BDS.Media.FileOps,
|
||||
only: [
|
||||
progress_callback: 1,
|
||||
report_rebuild_progress: 4,
|
||||
report_rebuild_started: 3
|
||||
]
|
||||
|
||||
alias BDS.Media.Media
|
||||
alias BDS.Media.Sidecars
|
||||
alias BDS.Persistence
|
||||
@@ -134,6 +141,45 @@ defmodule BDS.Media.Linking do
|
||||
|
||||
def restore_post_links(_project_id, _media_id, _post_ids), do: :ok
|
||||
|
||||
@doc """
|
||||
Rebuild the `post_media` junction for a project from every media sidecar's
|
||||
`linkedPostIds`.
|
||||
|
||||
Media sidecars are the source of truth for gallery associations (matching the
|
||||
old bDS `rebuildFromSidecars`). Existing project links are cleared and then
|
||||
re-created from the on-disk sidecars, so galleries reflect the project's
|
||||
metadata even if the junction table drifted or was never populated. Links to
|
||||
posts that are not present in the database are skipped.
|
||||
"""
|
||||
@spec rebuild_links_from_sidecars(String.t(), keyword()) ::
|
||||
{:ok, %{media: non_neg_integer(), links: non_neg_integer()}}
|
||||
def rebuild_links_from_sidecars(project_id, opts \\ []) when is_binary(project_id) do
|
||||
project = Projects.get_project!(project_id)
|
||||
on_progress = progress_callback(opts)
|
||||
|
||||
media_list =
|
||||
Repo.all(from m in Media, where: m.project_id == ^project_id, order_by: [asc: m.id])
|
||||
|
||||
total = length(media_list)
|
||||
:ok = report_rebuild_started(on_progress, total, "media links")
|
||||
|
||||
{_cleared, _} =
|
||||
Repo.delete_all(from pm in PostMedia, where: pm.project_id == ^project_id)
|
||||
|
||||
media_list
|
||||
|> Enum.with_index(1)
|
||||
|> Enum.each(fn {media, index} ->
|
||||
post_ids = Sidecars.read_linked_post_ids(project, media)
|
||||
restore_post_links(project_id, media.id, post_ids)
|
||||
:ok = report_rebuild_progress(on_progress, index, total, "media links")
|
||||
end)
|
||||
|
||||
links =
|
||||
Repo.aggregate(from(pm in PostMedia, where: pm.project_id == ^project_id), :count)
|
||||
|
||||
{:ok, %{media: total, links: links}}
|
||||
end
|
||||
|
||||
defp ensure_link(project_id, media_id, post_id) do
|
||||
already_linked? =
|
||||
Repo.exists?(
|
||||
|
||||
@@ -349,6 +349,29 @@ defmodule BDS.Media.Sidecars do
|
||||
|> File.exists?()
|
||||
end
|
||||
|
||||
@doc """
|
||||
Read the `linkedPostIds` list persisted in a media item's canonical sidecar.
|
||||
|
||||
The media sidecar is the source of truth for gallery associations (matching
|
||||
the old bDS `linkedPostIds` field). Returns `[]` when the sidecar is missing
|
||||
or has no linked posts.
|
||||
"""
|
||||
@spec read_linked_post_ids(BDS.Projects.Project.t(), Media.t()) :: [String.t()]
|
||||
def read_linked_post_ids(project, %Media{} = media) do
|
||||
sidecar_path = Path.join(Projects.project_data_dir(project), media.sidecar_path)
|
||||
|
||||
case parse_existing_canonical_sidecar(project, sidecar_path) do
|
||||
{:ok, sidecar} ->
|
||||
sidecar.fields
|
||||
|> DocumentFields.get("linkedPostIds", [])
|
||||
|> List.wrap()
|
||||
|> Enum.filter(&is_binary/1)
|
||||
|
||||
{:error, _reason} ->
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
defp parse_existing_canonical_sidecar(project, sidecar_path) do
|
||||
if File.exists?(sidecar_path) do
|
||||
parse_canonical_sidecar(project, sidecar_path)
|
||||
|
||||
@@ -1757,7 +1757,7 @@ msgid "Open"
|
||||
msgstr "Öffnen"
|
||||
|
||||
#: lib/bds/desktop/menu_bar.ex:154
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:381
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:382
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Open Data Folder"
|
||||
msgstr "Datenordner öffnen"
|
||||
@@ -2049,16 +2049,11 @@ msgid "Rebuild Database"
|
||||
msgstr "Datenbank neu aufbauen"
|
||||
|
||||
#: lib/bds/desktop/menu_bar.ex:184
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:380
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:381
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Rebuild Embedding Index"
|
||||
msgstr "Embedding-Index neu aufbauen"
|
||||
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:378
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Rebuild Links"
|
||||
msgstr "Links neu aufbauen"
|
||||
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:375
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Rebuild Media From Files"
|
||||
@@ -2116,7 +2111,7 @@ msgstr "Übersetzung aktualisieren"
|
||||
msgid "Regenerate Calendar"
|
||||
msgstr "Kalender neu erzeugen"
|
||||
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:379
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:380
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Regenerate Missing Thumbnails"
|
||||
msgstr "Fehlende Vorschaubilder neu erzeugen"
|
||||
@@ -3533,3 +3528,13 @@ msgstr "Vorgeschlagene Tags"
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Force Render Site"
|
||||
msgstr "Website vollständig neu generieren"
|
||||
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:379
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Rebuild Media Links"
|
||||
msgstr "Medien-Links neu aufbauen"
|
||||
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:378
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Rebuild Post Links"
|
||||
msgstr "Beitrags-Links neu aufbauen"
|
||||
|
||||
@@ -1757,7 +1757,7 @@ msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: lib/bds/desktop/menu_bar.ex:154
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:381
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:382
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Open Data Folder"
|
||||
msgstr ""
|
||||
@@ -2049,16 +2049,11 @@ msgid "Rebuild Database"
|
||||
msgstr ""
|
||||
|
||||
#: lib/bds/desktop/menu_bar.ex:184
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:380
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:381
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Rebuild Embedding Index"
|
||||
msgstr ""
|
||||
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:378
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Rebuild Links"
|
||||
msgstr ""
|
||||
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:375
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Rebuild Media From Files"
|
||||
@@ -2116,7 +2111,7 @@ msgstr ""
|
||||
msgid "Regenerate Calendar"
|
||||
msgstr ""
|
||||
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:379
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:380
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Regenerate Missing Thumbnails"
|
||||
msgstr ""
|
||||
@@ -3533,3 +3528,13 @@ msgstr ""
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Force Render Site"
|
||||
msgstr ""
|
||||
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:379
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Rebuild Media Links"
|
||||
msgstr ""
|
||||
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:378
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Rebuild Post Links"
|
||||
msgstr ""
|
||||
|
||||
@@ -1757,7 +1757,7 @@ msgid "Open"
|
||||
msgstr "Abrir"
|
||||
|
||||
#: lib/bds/desktop/menu_bar.ex:154
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:381
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:382
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Open Data Folder"
|
||||
msgstr "Abrir carpeta de datos"
|
||||
@@ -2049,16 +2049,11 @@ msgid "Rebuild Database"
|
||||
msgstr "Reconstruir base de datos"
|
||||
|
||||
#: lib/bds/desktop/menu_bar.ex:184
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:380
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:381
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Rebuild Embedding Index"
|
||||
msgstr "Reconstruir índice de embeddings"
|
||||
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:378
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Rebuild Links"
|
||||
msgstr "Reconstruir enlaces"
|
||||
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:375
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Rebuild Media From Files"
|
||||
@@ -2116,7 +2111,7 @@ msgstr "Actualizar traducción"
|
||||
msgid "Regenerate Calendar"
|
||||
msgstr "Regenerar calendario"
|
||||
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:379
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:380
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Regenerate Missing Thumbnails"
|
||||
msgstr "Regenerar miniaturas faltantes"
|
||||
@@ -3533,3 +3528,13 @@ msgstr "Etiquetas sugeridas"
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Force Render Site"
|
||||
msgstr "Forzar la regeneración del sitio"
|
||||
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:379
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Rebuild Media Links"
|
||||
msgstr "Reconstruir enlaces de medios"
|
||||
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:378
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Rebuild Post Links"
|
||||
msgstr "Reconstruir enlaces de entradas"
|
||||
|
||||
@@ -1757,7 +1757,7 @@ msgid "Open"
|
||||
msgstr "Ouvrir"
|
||||
|
||||
#: lib/bds/desktop/menu_bar.ex:154
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:381
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:382
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Open Data Folder"
|
||||
msgstr "Ouvrir le dossier de données"
|
||||
@@ -2049,16 +2049,11 @@ msgid "Rebuild Database"
|
||||
msgstr "Reconstruire la base de données"
|
||||
|
||||
#: lib/bds/desktop/menu_bar.ex:184
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:380
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:381
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Rebuild Embedding Index"
|
||||
msgstr "Reconstruire l’index d’embeddings"
|
||||
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:378
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Rebuild Links"
|
||||
msgstr "Reconstruire les liens"
|
||||
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:375
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Rebuild Media From Files"
|
||||
@@ -2116,7 +2111,7 @@ msgstr "Actualiser la traduction"
|
||||
msgid "Regenerate Calendar"
|
||||
msgstr "Régénérer le calendrier"
|
||||
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:379
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:380
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Regenerate Missing Thumbnails"
|
||||
msgstr "Régénérer les vignettes manquantes"
|
||||
@@ -3533,3 +3528,13 @@ msgstr "Tags suggérés"
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Force Render Site"
|
||||
msgstr "Forcer la régénération du site"
|
||||
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:379
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Rebuild Media Links"
|
||||
msgstr "Reconstruire les liens des médias"
|
||||
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:378
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Rebuild Post Links"
|
||||
msgstr "Reconstruire les liens des articles"
|
||||
|
||||
@@ -1757,7 +1757,7 @@ msgid "Open"
|
||||
msgstr "Apri"
|
||||
|
||||
#: lib/bds/desktop/menu_bar.ex:154
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:381
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:382
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Open Data Folder"
|
||||
msgstr "Apri cartella dati"
|
||||
@@ -2049,16 +2049,11 @@ msgid "Rebuild Database"
|
||||
msgstr "Ricostruisci database"
|
||||
|
||||
#: lib/bds/desktop/menu_bar.ex:184
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:380
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:381
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Rebuild Embedding Index"
|
||||
msgstr "Ricostruisci indice embeddings"
|
||||
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:378
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Rebuild Links"
|
||||
msgstr "Ricostruisci i link"
|
||||
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:375
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Rebuild Media From Files"
|
||||
@@ -2116,7 +2111,7 @@ msgstr "Aggiorna traduzione"
|
||||
msgid "Regenerate Calendar"
|
||||
msgstr "Rigenera calendario"
|
||||
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:379
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:380
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Regenerate Missing Thumbnails"
|
||||
msgstr "Rigenera miniature mancanti"
|
||||
@@ -3533,3 +3528,13 @@ msgstr "Tag suggeriti"
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Force Render Site"
|
||||
msgstr "Forza la rigenerazione del sito"
|
||||
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:379
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Rebuild Media Links"
|
||||
msgstr "Ricostruisci i link dei media"
|
||||
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:378
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Rebuild Post Links"
|
||||
msgstr "Ricostruisci i link degli articoli"
|
||||
|
||||
@@ -1770,7 +1770,7 @@ msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: lib/bds/desktop/menu_bar.ex:154
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:381
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:382
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Open Data Folder"
|
||||
msgstr ""
|
||||
@@ -2062,16 +2062,11 @@ msgid "Rebuild Database"
|
||||
msgstr ""
|
||||
|
||||
#: lib/bds/desktop/menu_bar.ex:184
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:380
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:381
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Rebuild Embedding Index"
|
||||
msgstr ""
|
||||
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:378
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Rebuild Links"
|
||||
msgstr ""
|
||||
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:375
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Rebuild Media From Files"
|
||||
@@ -2129,7 +2124,7 @@ msgstr ""
|
||||
msgid "Regenerate Calendar"
|
||||
msgstr ""
|
||||
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:379
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:380
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Regenerate Missing Thumbnails"
|
||||
msgstr ""
|
||||
@@ -3546,3 +3541,13 @@ msgstr ""
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Force Render Site"
|
||||
msgstr ""
|
||||
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:379
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Rebuild Media Links"
|
||||
msgstr ""
|
||||
|
||||
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:378
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Rebuild Post Links"
|
||||
msgstr ""
|
||||
|
||||
62
test/bds/media/link_restore_fresh_test.exs
Normal file
62
test/bds/media/link_restore_fresh_test.exs
Normal file
@@ -0,0 +1,62 @@
|
||||
defmodule BDS.Media.LinkRestoreFreshTest do
|
||||
use ExUnit.Case, async: false
|
||||
|
||||
import Ecto.Query
|
||||
|
||||
alias BDS.Media
|
||||
alias BDS.Media.Media, as: MediaRecord
|
||||
alias BDS.Posts.PostMedia
|
||||
alias BDS.Repo
|
||||
|
||||
setup do
|
||||
:ok = Ecto.Adapters.SQL.Sandbox.checkout(Repo)
|
||||
Ecto.Adapters.SQL.Sandbox.mode(Repo, {:shared, self()})
|
||||
temp_dir = Path.join(System.tmp_dir!(), "bds-freshlink-#{System.unique_integer([:positive])}")
|
||||
File.mkdir_p!(temp_dir)
|
||||
on_exit(fn -> File.rm_rf(temp_dir) end)
|
||||
|
||||
{:ok, project} = BDS.Projects.create_project(%{name: "Fresh", data_path: temp_dir})
|
||||
{:ok, _} = BDS.Metadata.update_project_metadata(project.id, %{main_language: "en"})
|
||||
|
||||
{:ok, post} =
|
||||
BDS.Posts.create_post(%{
|
||||
project_id: project.id,
|
||||
title: "Gallery Post",
|
||||
content: "[[gallery]]",
|
||||
language: "en"
|
||||
})
|
||||
|
||||
source = Path.join(temp_dir, "fresh.jpg")
|
||||
File.write!(source, "fake jpeg")
|
||||
{:ok, media} = Media.import_media(%{project_id: project.id, source_path: source})
|
||||
{:ok, _} = Media.link_media_to_post(media.id, post.id)
|
||||
|
||||
%{project: project, post: post, media: media}
|
||||
end
|
||||
|
||||
test "fresh media rebuild (media record gone, only files on disk) restores links", %{
|
||||
project: project,
|
||||
post: post,
|
||||
media: media
|
||||
} do
|
||||
# Sidecar on disk should carry the link.
|
||||
sidecar_path = Path.join(project.data_path, media.sidecar_path)
|
||||
assert File.exists?(sidecar_path)
|
||||
contents = File.read!(sidecar_path)
|
||||
assert contents =~ "linkedPostIds"
|
||||
assert contents =~ post.id
|
||||
|
||||
# Simulate a fresh DB: drop the media record AND its links entirely.
|
||||
Repo.delete_all(from pm in PostMedia, where: pm.media_id == ^media.id)
|
||||
Repo.delete_all(from m in MediaRecord, where: m.id == ^media.id)
|
||||
assert Repo.aggregate(from(m in MediaRecord, where: m.id == ^media.id), :count) == 0
|
||||
|
||||
assert {:ok, _} = BDS.Media.rebuild_media_from_files(project.id)
|
||||
|
||||
# Media re-inserted from sidecar.
|
||||
assert Repo.aggregate(from(m in MediaRecord, where: m.project_id == ^project.id), :count) == 1
|
||||
|
||||
# Link restored so the post's media list is populated again.
|
||||
assert Repo.aggregate(from(pm in PostMedia, where: pm.post_id == ^post.id), :count) == 1
|
||||
end
|
||||
end
|
||||
@@ -69,4 +69,51 @@ defmodule BDS.Media.LinkRestoreTest do
|
||||
assert {:ok, _} = BDS.Media.rebuild_media_from_files(project.id)
|
||||
assert link_count(post.id, media.id) == 1
|
||||
end
|
||||
|
||||
test "rebuild_media_links rebuilds gallery links from sidecars", %{
|
||||
project: project,
|
||||
post: post,
|
||||
media: media
|
||||
} do
|
||||
# Simulate a project whose junction table was never populated even though
|
||||
# the media sidecar references the post (the reported gallery regression).
|
||||
Repo.delete_all(from pm in PostMedia, where: pm.media_id == ^media.id)
|
||||
assert link_count(post.id, media.id) == 0
|
||||
|
||||
assert {:ok, %{media: 1, links: 1}} = BDS.Media.rebuild_media_links(project.id)
|
||||
|
||||
assert link_count(post.id, media.id) == 1
|
||||
end
|
||||
|
||||
test "rebuild_media_links drops stale junction links not present in sidecars", %{
|
||||
project: project,
|
||||
post: post,
|
||||
media: media
|
||||
} do
|
||||
{:ok, other_post} =
|
||||
BDS.Posts.create_post(%{
|
||||
project_id: project.id,
|
||||
title: "Unrelated Post",
|
||||
content: "no gallery here",
|
||||
language: "en"
|
||||
})
|
||||
|
||||
# A junction row that drifted from the sidecar: the media is linked to a
|
||||
# post its sidecar does not reference. The sidecar is the source of truth,
|
||||
# so rebuild must drop this link.
|
||||
Repo.insert!(%PostMedia{
|
||||
id: Ecto.UUID.generate(),
|
||||
project_id: project.id,
|
||||
post_id: other_post.id,
|
||||
media_id: media.id,
|
||||
sort_order: 5,
|
||||
created_at: 0
|
||||
})
|
||||
|
||||
assert {:ok, %{links: 1}} = BDS.Media.rebuild_media_links(project.id)
|
||||
|
||||
# The real (sidecar-backed) link survives, the drifted link is gone.
|
||||
assert link_count(post.id, media.id) == 1
|
||||
assert link_count(other_post.id, media.id) == 0
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user