bd65e9e36e2b1f534c9908e1dc62301768568460
[akkoma] / lib / mix / tasks / pleroma / frontend.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Mix.Tasks.Pleroma.Frontend do
6 use Mix.Task
7
8 import Mix.Pleroma
9
10 @shortdoc "Manages bundled Pleroma frontends"
11
12 # @moduledoc File.read!("docs/administration/CLI_tasks/frontend.md")
13
14 def run(["install", "none" | _args]) do
15 shell_info("Skipping frontend installation because none was requested")
16 "none"
17 end
18
19 def run(["install", frontend | args]) do
20 log_level = Logger.level()
21 Logger.configure(level: :warn)
22 start_pleroma()
23
24 {options, [], []} =
25 OptionParser.parse(
26 args,
27 strict: [
28 ref: :string,
29 static_dir: :string,
30 build_url: :string
31 ]
32 )
33
34 instance_static_dir =
35 with nil <- options[:static_dir] do
36 Pleroma.Config.get!([:instance, :static_dir])
37 end
38
39 cmd_frontend_info = %{
40 "name" => frontend,
41 "ref" => options[:ref],
42 "build_url" => options[:build_url]
43 }
44
45 config_frontend_info = Pleroma.Config.get([:frontends, :available, frontend], %{})
46
47 frontend_info =
48 Map.merge(config_frontend_info, cmd_frontend_info, fn _key, config, cmd ->
49 # This only overrides things that are actually set
50 cmd || config
51 end)
52
53 ref = frontend_info["ref"]
54
55 unless ref do
56 raise "No ref given or configured"
57 end
58
59 dest =
60 Path.join([
61 instance_static_dir,
62 "frontends",
63 frontend,
64 ref
65 ])
66
67 fe_label = "#{frontend} (#{ref})"
68
69 shell_info("Downloading pre-built bundle for #{fe_label}")
70 tmp_dir = Path.join(dest, "tmp")
71
72 with {_, :ok} <- {:download, download_build(frontend_info, tmp_dir)},
73 shell_info("Installing #{fe_label} to #{dest}"),
74 :ok <- install_frontend(frontend_info, tmp_dir, dest) do
75 File.rm_rf!(tmp_dir)
76 shell_info("Frontend #{fe_label} installed to #{dest}")
77
78 Logger.configure(level: log_level)
79 else
80 {:download, _} ->
81 shell_info("Could not download the frontend")
82
83 _e ->
84 shell_info("Could not install the frontend")
85 end
86 end
87
88 defp download_build(frontend_info, dest) do
89 url = String.replace(frontend_info["build_url"], "${ref}", frontend_info["ref"])
90
91 with {:ok, %{status: 200, body: zip_body}} <-
92 Pleroma.HTTP.get(url, [], timeout: 120_000, recv_timeout: 120_000),
93 {:ok, unzipped} <- :zip.unzip(zip_body, [:memory]) do
94 File.rm_rf!(dest)
95 File.mkdir_p!(dest)
96
97 Enum.each(unzipped, fn {filename, data} ->
98 path = filename
99
100 new_file_path = Path.join(dest, path)
101
102 new_file_path
103 |> Path.dirname()
104 |> File.mkdir_p!()
105
106 File.write!(new_file_path, data)
107 end)
108
109 :ok
110 else
111 e -> {:error, e}
112 end
113 end
114
115 defp install_frontend(frontend_info, source, dest) do
116 from = frontend_info["build_dir"] || "dist"
117 File.mkdir_p!(dest)
118 File.cp_r!(Path.join([source, from]), dest)
119 :ok
120 end
121 end