1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Mix.Tasks.Pleroma.Emoji do
8 @shortdoc "Manages Pleroma instance"
12 @default_manifest "https://git.pleroma.social/vaartis/emoji-index/raw/master/index.json"
14 def run(["ls-packs" | args]) do
15 Application.ensure_all_started(:hackney)
17 {options, [], []} = parse_global_opts(args)
20 fetch_manifest(if options[:manifest], do: options[:manifest], else: @default_manifest)
22 Enum.each(manifest, fn {name, info} ->
25 {"Homepage", info["homepage"]},
26 {"Description", info["description"]},
27 {"License", info["license"]},
28 {"Source", info["src"]}
31 for {param, value} <- to_print do
32 IO.puts(IO.ANSI.format([:bright, param, :normal, ": ", value]))
37 def run(["get-packs" | args]) do
38 Application.ensure_all_started(:hackney)
40 {options, pack_names, []} = parse_global_opts(args)
42 manifest_url = if options[:manifest], do: options[:manifest], else: @default_manifest
44 manifest = fetch_manifest(manifest_url)
46 for pack_name <- pack_names do
47 if Map.has_key?(manifest, pack_name) do
48 pack = manifest[pack_name]
63 binary_archive = Tesla.get!(src_url).body
64 archive_md5 = :crypto.hash(:md5, binary_archive) |> Base.encode16()
66 md5_status_text = ["MD5 of ", :bright, pack_name, :normal, " source file is ", :bright]
67 if archive_md5 == String.upcase(pack["src_md5"]) do
68 IO.puts(IO.ANSI.format(md5_status_text ++ [:green, "OK"]))
70 IO.puts(IO.ANSI.format(md5_status_text ++ [:red, "BAD"]))
72 raise "Bad MD5 for #{pack_name}"
75 # The url specified in files should be in the same directory
76 files_url = Path.join(Path.dirname(manifest_url), pack["files"])
80 "Fetching the file list for ",
90 files = Tesla.get!(files_url).body |> Poison.decode!()
92 IO.puts(IO.ANSI.format(["Unpacking ", :bright, pack_name]))
94 static_path = Path.join(:code.priv_dir(:pleroma), "static")
99 Pleroma.Config.get!([:instance, :static_dir]),
107 fn {_, f} -> to_charlist(f) end
111 :zip.unzip(binary_archive,
113 file_list: files_to_unzip
116 IO.puts(IO.ANSI.format(["Writing emoji.txt for ", :bright, pack_name]))
118 common_pack_path = Path.join([
119 "/", Pleroma.Config.get!([:instance, :static_dir]), "emoji", pack_name
124 fn {shortcode, path} ->
125 "#{shortcode}, #{Path.join(common_pack_path, path)}"
130 File.write!(Path.join(pack_path, "emoji.txt"), emoji_txt_str)
132 IO.puts(IO.ANSI.format([:bright, :red, "No pack named \"#{pack_name}\" found"]))
137 def run(["gen-pack", src]) do
138 Application.ensure_all_started(:hackney)
140 proposed_name = Path.basename(src) |> Path.rootname()
141 name = String.trim(IO.gets("Pack name [#{proposed_name}]: "))
142 # If there's no name, use the default one
143 name = if String.length(name) > 0, do: name, else: proposed_name
145 license = String.trim(IO.gets("License: "))
146 homepage = String.trim(IO.gets("Homepage: "))
147 description = String.trim(IO.gets("Description: "))
149 proposed_files_name = "#{name}.json"
150 files_name = String.trim(IO.gets("Save file list to [#{proposed_files_name}]: "))
151 files_name = if String.length(files_name) > 0, do: files_name, else: proposed_files_name
153 default_exts = [".png", ".gif"]
154 default_exts_str = Enum.join(default_exts, " ")
156 String.trim(IO.gets("Emoji file extensions (separated with spaces) [#{default_exts_str}]: "))
157 exts = if String.length(exts) > 0 do
158 String.split(exts, " ") |> Enum.filter(fn e -> (e |> String.trim() |> String.length()) > 0 end)
163 IO.puts "Downloading the pack and generating MD5"
165 binary_archive = Tesla.get!(src).body
166 archive_md5 = :crypto.hash(:md5, binary_archive) |> Base.encode16()
168 IO.puts "MD5 is #{archive_md5}"
174 description: description,
176 src_md5: archive_md5,
181 tmp_pack_dir = Path.join(System.tmp_dir!(), "emoji-pack-#{name}")
188 emoji_map = Pleroma.Emoji.make_shortcode_to_file_map(tmp_pack_dir, exts)
191 File.write!(files_name, Poison.encode!(emoji_map, pretty: true))
195 #{files_name} has been created and contains the list of all found emojis in the pack.
196 Please review the files in the remove those not needed.
199 if File.exists?("index.json") do
200 existing_data = File.read!("index.json") |> Poison.decode!()
213 IO.puts "index.json file has been update with the #{name} pack"
215 File.write!("index.json", Poison.encode!(pack_json, pretty: true))
217 IO.puts "index.json has been created with the #{name} pack"
222 defp fetch_manifest(from) do
223 Tesla.get!(from).body |> Poison.decode!()
226 defp parse_global_opts(args) do