1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Pleroma.Clippy do
7 # No software is complete until they have a Clippy implementation.
8 # A ballmer peak _may_ be required to change this module.
17 host = Pleroma.Config.get([Pleroma.Web.Endpoint, :url, :host])
20 "“πλήρωμα” is “pleroma” in greek",
21 "For an extended Pleroma Clippy Experience, use the “Redmond” themes in Pleroma FE settings",
22 "Staff accounts and MRF policies of Pleroma instances are disclosed on the NodeInfo endpoints for easy transparency!\n
23 - https://catgirl.science/misc/nodeinfo.lua?#{host}
24 - https://fediverse.network/#{host}/federation",
25 "Pleroma can federate to the Dark Web!\n
26 - Tor: https://git.pleroma.social/pleroma/pleroma/wikis/Easy%20Onion%20Federation%20(Tor)
27 - i2p: https://git.pleroma.social/pleroma/pleroma/wikis/I2p%20federation",
28 "Lists of Pleroma instances:\n\n- http://distsn.org/pleroma-instances.html\n- https://fediverse.network/pleroma\n- https://the-federation.info/pleroma",
29 "Pleroma uses the LitePub protocol - https://litepub.social",
30 "To receive more federated posts, subscribe to relays!\n
31 - How-to: https://git.pleroma.social/pleroma/pleroma/wikis/Admin%20tasks#relay-managment
32 - Relays: https://fediverse.network/activityrelay"
36 @spec puts(String.t() | [[IO.ANSI.ansicode() | String.t(), ...], ...]) :: nil
37 def puts(text_or_lines) do
41 if is_binary(text_or_lines) do
42 String.split(text_or_lines, ~r/\n/)
49 |> Enum.map(&charlist_count_text/1)
53 pad_text = longest_line_size
56 for(_ <- 1..pad_text, do: "_")
60 for(_ <- 1..pad_text, do: " ")
66 " / \\#{spaces} _#{pad}___",
67 " | |#{spaces} / #{pad_spaces} \\"
75 " #{bright()}@ @#{reset()}#{spaces} ",
87 pad_spaces: pad_spaces,
90 noclippy_line: noclippy_line
93 # surrond one/five line clippy with blank lines around to not fuck up the layout
95 # yes this fix sucks but it's good enough, have you ever seen a release of windows
96 # without some butched features anyway?
98 if length(lines) == 1 or length(lines) == 5 do
104 clippy_line(lines, clippy_lines, env)
107 IO.puts("(Clippy crashed, sorry: #{inspect(e)})")
108 IO.puts(text_or_lines)
111 defp clippy_line([line | lines], [prefix | clippy_lines], env) do
112 IO.puts([prefix <> "| ", rpad_line(line, env.max_size)])
113 clippy_line(lines, clippy_lines, env)
116 # more text lines but clippy's complete
117 defp clippy_line([line | lines], [], env) do
118 IO.puts([env.noclippy_line, "| ", rpad_line(line, env.max_size)])
121 IO.puts(env.noclippy_line <> "\\_#{env.pad}___/")
124 clippy_line(lines, [], env)
127 # no more text lines but clippy's not complete
128 defp clippy_line([], [clippy | clippy_lines], env) do
130 IO.puts(clippy <> "\\_#{env.pad}___/")
131 clippy_line([], clippy_lines, %{env | pad: nil})
134 clippy_line([], clippy_lines, env)
138 defp clippy_line(_, _, _) do
141 defp rpad_line(line, max) do
142 pad = max - (charlist_count_text(line) - 2)
143 pads = Enum.join(for(_ <- 1..pad, do: " "))
144 [IO.ANSI.format(line), pads <> " |"]
147 defp charlist_count_text(line) do
149 text = Enum.join(Enum.filter(line, &is_binary/1))