defmodule Archeometer.Reports.Generator do
@moduledoc """
Generates a report given a configuration and parameters.
"""
require Logger
use Archeometer.Repo
import Archeometer.Reports.Utils
alias Archeometer.Reports.Page
def generate(cfg) do
Logger.info("Preparing report paths...")
prepare_paths(:html)
Logger.info("Creating pages...")
create_pages(cfg)
Logger.info("Copying assets...")
copy_assets()
Logger.info("Copying images...")
copy_images()
Logger.info("Report generated!")
end
@index_page_name :index
defp create_pages(cfg) do
case length(cfg.modules) do
1 ->
create_module_page(hd(cfg.modules), cfg)
_ ->
page_names = page_names_fn(cfg)
create_main_page(cfg, page_names)
Enum.each(cfg.modules, &create_module_page(&1, cfg, page_names))
end
end
defp page_names_fn(cfg) do
sections =
Enum.map(
cfg.modules,
&module_section_names(&1, cfg.module_page_def)
)
mods = Enum.zip(cfg.modules, sections)
index_name = to_string(@index_page_name)
index = {
index_name,
module_section_names(index_name, cfg.root_page_def)
}
[index | mods]
end
defp module_section_names(mod, page_def) do
page_def.(mod)
|> Map.get(:sections)
|> Enum.map(&Map.get(&1, :desc))
end
defp create_main_page(cfg, page_names) do
file_name = to_string(@index_page_name)
file_name
|> cfg.root_page_def.()
|> create_page(file_name, page_names, cfg)
end
defp create_module_page(module, cfg, page_names \\ []) do
module
|> cfg.module_page_def.()
|> create_page(to_string(module), page_names, cfg)
end
defp create_page(%Page.Definition{} = page_def, out_file, page_names, cfg) do
Logger.info("Creating page: #{page_def.id} ...")
bindings = [app: page_def.id, limit: cfg.limit, db_name: cfg.db_name]
page_def
|> render_page(page_names, cfg.renderer, cfg.db_name, bindings)
|> write_to_file(:html, out_file <> ".html")
Logger.info("Page #{page_def.id} ready!")
end
defp render_page(%Page.Definition{} = page_def, page_names, renderer, db_name, bindings) do
old_db = setup_default_db(db_name)
rendered =
page_def
|> Page.process(bindings, db_name)
|> renderer.render(page_names, renderer)
restore_default_db(old_db)
rendered
end
defp setup_default_db(db_name) do
old_db = Application.fetch_env(:archeometer, :default_db)
Application.put_env(:archeometer, :default_db, db_name)
old_db
end
defp restore_default_db({:ok, db}) do
Application.put_env(:archeometer, :default_db, db)
end
defp restore_default_db(:error), do: :ok
end