diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/mix/tasks/pleroma/frontend.ex | 140 | ||||
| -rw-r--r-- | lib/pleroma/plugs/frontend_static.ex | 1 | ||||
| -rw-r--r-- | lib/pleroma/web/endpoint.ex | 14 | 
3 files changed, 153 insertions, 2 deletions
| diff --git a/lib/mix/tasks/pleroma/frontend.ex b/lib/mix/tasks/pleroma/frontend.ex new file mode 100644 index 000000000..2adbf8d72 --- /dev/null +++ b/lib/mix/tasks/pleroma/frontend.ex @@ -0,0 +1,140 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Mix.Tasks.Pleroma.Frontend do +  use Mix.Task + +  import Mix.Pleroma + +  @shortdoc "Manages bundled Pleroma frontends" + +  @moduledoc File.read!("docs/administration/CLI_tasks/frontend.md") + +  def run(["install", "none" | _args]) do +    shell_info("Skipping frontend installation because none was requested") +    "none" +  end + +  def run(["install", frontend | args]) do +    log_level = Logger.level() +    Logger.configure(level: :warn) +    start_pleroma() + +    {options, [], []} = +      OptionParser.parse( +        args, +        strict: [ +          ref: :string, +          static_dir: :string, +          build_url: :string, +          build_dir: :string, +          file: :string +        ] +      ) + +    instance_static_dir = +      with nil <- options[:static_dir] do +        Pleroma.Config.get!([:instance, :static_dir]) +      end + +    cmd_frontend_info = %{ +      "name" => frontend, +      "ref" => options[:ref], +      "build_url" => options[:build_url], +      "build_dir" => options[:build_dir] +    } + +    config_frontend_info = Pleroma.Config.get([:frontends, :available, frontend], %{}) + +    frontend_info = +      Map.merge(config_frontend_info, cmd_frontend_info, fn _key, config, cmd -> +        # This only overrides things that are actually set +        cmd || config +      end) + +    ref = frontend_info["ref"] + +    unless ref do +      raise "No ref given or configured" +    end + +    dest = +      Path.join([ +        instance_static_dir, +        "frontends", +        frontend, +        ref +      ]) + +    fe_label = "#{frontend} (#{ref})" + +    tmp_dir = Path.join(dest, "tmp") + +    with {_, :ok} <- +           {:download_or_unzip, download_or_unzip(frontend_info, tmp_dir, options[:file])}, +         shell_info("Installing #{fe_label} to #{dest}"), +         :ok <- install_frontend(frontend_info, tmp_dir, dest) do +      File.rm_rf!(tmp_dir) +      shell_info("Frontend #{fe_label} installed to #{dest}") + +      Logger.configure(level: log_level) +    else +      {:download_or_unzip, _} -> +        shell_info("Could not download or unzip the frontend") + +      _e -> +        shell_info("Could not install the frontend") +    end +  end + +  defp download_or_unzip(frontend_info, temp_dir, file) do +    if file do +      with {:ok, zip} <- File.read(Path.expand(file)) do +        unzip(zip, temp_dir) +      end +    else +      download_build(frontend_info, temp_dir) +    end +  end + +  def unzip(zip, dest) do +    with {:ok, unzipped} <- :zip.unzip(zip, [:memory]) do +      File.rm_rf!(dest) +      File.mkdir_p!(dest) + +      Enum.each(unzipped, fn {filename, data} -> +        path = filename + +        new_file_path = Path.join(dest, path) + +        new_file_path +        |> Path.dirname() +        |> File.mkdir_p!() + +        File.write!(new_file_path, data) +      end) + +      :ok +    end +  end + +  defp download_build(frontend_info, dest) do +    shell_info("Downloading pre-built bundle for #{frontend_info["name"]}") +    url = String.replace(frontend_info["build_url"], "${ref}", frontend_info["ref"]) + +    with {:ok, %{status: 200, body: zip_body}} <- +           Pleroma.HTTP.get(url, [], timeout: 120_000, recv_timeout: 120_000) do +      unzip(zip_body, dest) +    else +      e -> {:error, e} +    end +  end + +  defp install_frontend(frontend_info, source, dest) do +    from = frontend_info["build_dir"] || "dist" +    File.mkdir_p!(dest) +    File.cp_r!(Path.join([source, from]), dest) +    :ok +  end +end diff --git a/lib/pleroma/plugs/frontend_static.ex b/lib/pleroma/plugs/frontend_static.ex index f549ca75f..11a0d5382 100644 --- a/lib/pleroma/plugs/frontend_static.ex +++ b/lib/pleroma/plugs/frontend_static.ex @@ -30,6 +30,7 @@ defmodule Pleroma.Plugs.FrontendStatic do      opts      |> Keyword.put(:from, "__unconfigured_frontend_static_plug")      |> Plug.Static.init() +    |> Map.put(:frontend_type, opts[:frontend_type])    end    def call(conn, opts) do diff --git a/lib/pleroma/web/endpoint.ex b/lib/pleroma/web/endpoint.ex index 527fb288d..8b153763d 100644 --- a/lib/pleroma/web/endpoint.ex +++ b/lib/pleroma/web/endpoint.ex @@ -39,6 +39,18 @@ defmodule Pleroma.Web.Endpoint do      }    ) +  plug(Plug.Static.IndexHtml, at: "/pleroma/admin/") + +  plug(Pleroma.Plugs.FrontendStatic, +    at: "/pleroma/admin", +    frontend_type: :admin, +    gzip: true, +    cache_control_for_etags: @static_cache_control, +    headers: %{ +      "cache-control" => @static_cache_control +    } +  ) +    # Serve at "/" the static files from "priv/static" directory.    #    # You should set gzip to true if you are running phoenix.digest @@ -56,8 +68,6 @@ defmodule Pleroma.Web.Endpoint do      }    ) -  plug(Plug.Static.IndexHtml, at: "/pleroma/admin/") -    plug(Plug.Static,      at: "/pleroma/admin/",      from: {:pleroma, "priv/static/adminfe/"} | 
