defmodule SukaatoWeb.Theme do @moduledoc """ Manage website themes. """ @rel_proj_root "../.." @central_sass "export.sass" @site_config Toml.decode_file(Path.expand(@rel_proj_root <> "/site.toml", __DIR__)) @theme_filepath Path.expand(@rel_proj_root <> "/assets/sass/themes/" <> elem(@site_config, 1)["site"]["theme"] <> "/" <> @central_sass, __DIR__) @theme_glob Path.expand(@rel_proj_root <> "/assets/sass/themes/*/" <> @central_sass, __DIR__) @theme_linkpath Path.expand(@rel_proj_root <> "/assets/sass/app.sass", __DIR__) defp get_installed() do path_list = Path.wildcard(@theme_glob) extract_theme = fn theme_path -> Enum.at(Path.split(theme_path), length(Path.split(theme_path)) - 2) end installed = Enum.map(path_list, fn p -> extract_theme.(p) end) installed end @doc """ List installed website themes. """ def list() do get_installed() end defp get_current() do if File.exists?(@theme_linkpath) do link_path = File.read_link(@theme_linkpath) if elem(link_path, 0) == :ok do split_path = Path.split(elem(link_path, 1)) current_theme = Enum.at(split_path, length(split_path) - 2) {:ok, current_theme} else {:error, "link not traceable--sure its a link?"} end else {:error, "symbolic link does not exist"} end end @doc """ List website themes under project root's 'assets/sass/themes' path. """ def list(status) do case status do :installed -> get_installed() :current -> elem(get_current(), 1) end end defp change_theme_path(theme_name) do Path.expand(@rel_proj_root <> "/assets/sass/themes/" <> theme_name <> "/" <> @central_sass, __DIR__) end @doc """ Update website theme based on stored website settings, refreshes current theme otherwise. """ def update() do if File.exists?(@theme_filepath) do result = File.ln_s(@theme_filepath, @theme_linkpath) if result == :ok do {:ok, @theme_linkpath} else {:error, {@theme_filepath, @theme_linkpath}} end else link_path = File.read_link(@theme_linkpath) if Enum.at(link_path, 0) == :ok do split_path = Path.split(Enum.at(link_path, 1)) current_theme = Enum.at(split_path, length(split_path) - 2) # @TODO find some way to notify theme could not be found current_path = change_theme_path(current_theme) result = File.ln_s(current_path, @theme_linkpath) if result == :ok do {:ok, "current theme '" <> current_theme <> "' reinstated as no declared theme"} else result = File.ln_s(change_theme_path("default"), @theme_linkpath) if result == :ok do {:ok, "current theme '" <> current_theme <> "' unavailable, successful fallback to default theme"} else {:error, "current theme '" <> current_theme <> "' unavailable, failed fallback to default theme"} end end else {:error, @theme_linkpath} end end end @doc """ Update website theme in-memory, independent of stored website settings. """ def update(theme_name) do theme_path = change_theme_path(theme_name) if File.exists?(theme_path) do # @TODO find some way to notify theme could not be found result = File.ln_s(theme_path, @theme_linkpath) if result == :ok do {:ok, @theme_linkpath} else update() end else update() end end def grab(), do: nil def unpack(), do: nil def install(), do: nil def remove(theme_name) do theme_path = change_theme_path(theme_name) if theme_name != "default" do result = File.rm_rf(theme_path) result else {:error, theme_name <> " cannot be uninstalled"} end end end