chore: next big god module down
Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
204
lib/bds/scripting/capabilities/projects.ex
Normal file
204
lib/bds/scripting/capabilities/projects.ex
Normal file
@@ -0,0 +1,204 @@
|
||||
defmodule BDS.Scripting.Capabilities.Projects do
|
||||
@moduledoc false
|
||||
|
||||
import BDS.Scripting.Capabilities.Crud
|
||||
import BDS.Scripting.Capabilities.Util
|
||||
|
||||
alias BDS.Metadata
|
||||
alias BDS.Projects, as: ProjectsCtx
|
||||
alias BDS.Projects.Project
|
||||
alias BDS.Repo
|
||||
alias BDS.Tags
|
||||
|
||||
def create_project(attrs), do: attrs |> normalize_map() |> ProjectsCtx.create_project() |> unwrap_result()
|
||||
|
||||
def delete_project(project_id), do: boolean_result(ProjectsCtx.delete_project(string_or_nil(project_id)))
|
||||
|
||||
def delete_project_with_data(project_id) do
|
||||
case string_or_nil(project_id) && ProjectsCtx.get_project(string_or_nil(project_id)) do
|
||||
%Project{} = project ->
|
||||
data_dir = ProjectsCtx.project_data_dir(project)
|
||||
|
||||
case ProjectsCtx.delete_project(project.id) do
|
||||
{:ok, _deleted_project} ->
|
||||
_ = File.rm_rf(data_dir)
|
||||
true
|
||||
|
||||
{:error, _reason} ->
|
||||
false
|
||||
end
|
||||
|
||||
_other ->
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def load_project(project_id) do
|
||||
case string_or_nil(project_id) do
|
||||
nil -> nil
|
||||
id -> ProjectsCtx.get_project(id) |> sanitize_nilable()
|
||||
end
|
||||
end
|
||||
|
||||
def list_projects do
|
||||
ProjectsCtx.list_projects()
|
||||
|> Enum.map(&sanitize/1)
|
||||
end
|
||||
|
||||
def set_active_project(project_id) do
|
||||
project_id
|
||||
|> string_or_nil()
|
||||
|> then(fn
|
||||
nil -> {:error, :not_found}
|
||||
id -> ProjectsCtx.set_active_project(id)
|
||||
end)
|
||||
|> unwrap_result()
|
||||
end
|
||||
|
||||
def update_project(project_id, attrs) do
|
||||
case string_or_nil(project_id) && ProjectsCtx.get_project(string_or_nil(project_id)) do
|
||||
%Project{} = project ->
|
||||
attrs = normalize_map(attrs)
|
||||
|
||||
updates = %{
|
||||
name: Map.get(attrs, "name", project.name),
|
||||
description: Map.get(attrs, "description", project.description),
|
||||
data_path: Map.get(attrs, "data_path", project.data_path),
|
||||
updated_at: System.system_time(:millisecond),
|
||||
is_active: Map.get(attrs, "is_active", project.is_active)
|
||||
}
|
||||
|
||||
project
|
||||
|> Project.changeset(updates)
|
||||
|> Repo.update()
|
||||
|> unwrap_result()
|
||||
|
||||
_other ->
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def load_metadata(project_id) do
|
||||
{:ok, metadata} = Metadata.get_project_metadata(project_id)
|
||||
sanitize(metadata)
|
||||
end
|
||||
|
||||
def update_project_metadata(project_id, attrs) do
|
||||
Metadata.update_project_metadata(project_id, normalize_map(attrs))
|
||||
|> unwrap_result()
|
||||
end
|
||||
|
||||
def add_category(project_id, name) do
|
||||
Metadata.add_category(project_id, string_or_nil(name) || "")
|
||||
|> unwrap_result()
|
||||
end
|
||||
|
||||
def remove_category(project_id, name) do
|
||||
Metadata.remove_category(project_id, string_or_nil(name) || "")
|
||||
|> unwrap_result()
|
||||
end
|
||||
|
||||
def metadata_categories(project_id) do
|
||||
load_metadata(project_id)
|
||||
|> Map.get("categories", [])
|
||||
end
|
||||
|
||||
def metadata_tags(project_id) do
|
||||
project_id
|
||||
|> list_tags()
|
||||
|> Enum.map(&Map.get(&1, "name"))
|
||||
end
|
||||
|
||||
def add_meta_tag(project_id, name) do
|
||||
normalized_name = string_or_nil(name) |> to_string() |> String.trim()
|
||||
|
||||
cond do
|
||||
normalized_name == "" -> metadata_tags(project_id)
|
||||
load_tag_by_name(project_id, normalized_name) -> metadata_tags(project_id)
|
||||
true ->
|
||||
create_tag(project_id, %{"name" => normalized_name})
|
||||
metadata_tags(project_id)
|
||||
end
|
||||
end
|
||||
|
||||
def remove_meta_tag(project_id, name) do
|
||||
case load_tag_by_name(project_id, name) do
|
||||
%{"id" => tag_id} ->
|
||||
_ = delete_tag(project_id, tag_id)
|
||||
metadata_tags(project_id)
|
||||
|
||||
_other ->
|
||||
metadata_tags(project_id)
|
||||
end
|
||||
end
|
||||
|
||||
def publishing_preferences(project_id) do
|
||||
load_metadata(project_id)
|
||||
|> Map.get("publishing_preferences")
|
||||
end
|
||||
|
||||
def set_publishing_preferences(project_id, prefs) do
|
||||
project_id
|
||||
|> Metadata.set_publishing_preferences(normalize_map(prefs))
|
||||
|> unwrap_result()
|
||||
|> case do
|
||||
nil -> nil
|
||||
metadata -> Map.get(metadata, "publishing_preferences")
|
||||
end
|
||||
end
|
||||
|
||||
def clear_publishing_preferences(project_id) do
|
||||
set_publishing_preferences(project_id, %{})
|
||||
end
|
||||
|
||||
def sync_meta_on_startup(project_id) do
|
||||
_ = Tags.sync_tags_from_posts(project_id)
|
||||
|
||||
%{
|
||||
tags: metadata_tags(project_id),
|
||||
categories: metadata_categories(project_id),
|
||||
project_metadata: load_metadata(project_id)
|
||||
}
|
||||
end
|
||||
|
||||
def data_paths(project_id) do
|
||||
database_path = Repo.config()[:database]
|
||||
project_dir = project_path(project_id)
|
||||
|
||||
%{
|
||||
database: database_path,
|
||||
project: project_dir,
|
||||
posts: Path.join(project_dir, "posts"),
|
||||
media: Path.join(project_dir, "media")
|
||||
}
|
||||
end
|
||||
|
||||
def read_project_metadata(folder_path) do
|
||||
case project_for_folder(folder_path) do
|
||||
nil -> read_project_metadata_file(folder_path)
|
||||
project -> load_metadata(project.id)
|
||||
end
|
||||
end
|
||||
|
||||
def project_for_folder(folder_path) do
|
||||
normalized = string_or_nil(folder_path)
|
||||
|
||||
ProjectsCtx.list_projects()
|
||||
|> Enum.find(fn project -> ProjectsCtx.project_data_dir(project) == normalized end)
|
||||
end
|
||||
|
||||
def read_project_metadata_file(folder_path) do
|
||||
path = Path.join([string_or_nil(folder_path) || "", "meta", "project.json"])
|
||||
|
||||
case File.read(path) do
|
||||
{:ok, contents} ->
|
||||
case Jason.decode(contents) do
|
||||
{:ok, decoded} when is_map(decoded) -> sanitize(decoded)
|
||||
_other -> nil
|
||||
end
|
||||
|
||||
{:error, _reason} ->
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user