137 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Elixir
		
	
	
	
	
	
			
		
		
	
	
			137 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Elixir
		
	
	
	
	
	
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
 |