feat: headless server mode with ExRatatui SSH daemon (issue #26, phase 1)
This commit is contained in:
@@ -25,6 +25,8 @@ config :bds, :desktop,
|
|||||||
window_min_size: {800, 600},
|
window_min_size: {800, 600},
|
||||||
title: "Blogging Desktop Server"
|
title: "Blogging Desktop Server"
|
||||||
|
|
||||||
|
config :bds, :server, ssh_port: 2222
|
||||||
|
|
||||||
config :bds, BDS.Desktop.Endpoint,
|
config :bds, BDS.Desktop.Endpoint,
|
||||||
url: [host: "127.0.0.1"],
|
url: [host: "127.0.0.1"],
|
||||||
adapter: Bandit.PhoenixAdapter,
|
adapter: Bandit.PhoenixAdapter,
|
||||||
|
|||||||
@@ -5,6 +5,15 @@ defmodule BDS.Application do
|
|||||||
|
|
||||||
@compiled_env Application.compile_env(:bds, :current_env, Mix.env())
|
@compiled_env Application.compile_env(:bds, :current_env, Mix.env())
|
||||||
|
|
||||||
|
# Children that depend on the boot mode (issue #26): desktop mode runs the
|
||||||
|
# wx window shell, server mode runs headless behind the SSH daemon. Both
|
||||||
|
# start the loopback HTTP endpoint and the CLI sync watcher.
|
||||||
|
def mode_children(:server, _env) do
|
||||||
|
[{BDS.Desktop.Server, []}, BDS.CliSync.Watcher, BDS.Server]
|
||||||
|
end
|
||||||
|
|
||||||
|
def mode_children(:desktop, env), do: desktop_children(env)
|
||||||
|
|
||||||
def desktop_children(env \\ nil)
|
def desktop_children(env \\ nil)
|
||||||
|
|
||||||
def desktop_children(:test) do
|
def desktop_children(:test) do
|
||||||
@@ -41,7 +50,7 @@ defmodule BDS.Application do
|
|||||||
{Task.Supervisor, name: BDS.Scripting.TaskSupervisor},
|
{Task.Supervisor, name: BDS.Scripting.TaskSupervisor},
|
||||||
BDS.Scripting.JobSupervisor,
|
BDS.Scripting.JobSupervisor,
|
||||||
BDS.Embeddings.Index
|
BDS.Embeddings.Index
|
||||||
] ++ embedding_children() ++ desktop_children(current_env())
|
] ++ embedding_children() ++ mode_children(BDS.Server.mode(), current_env())
|
||||||
|
|
||||||
opts = [strategy: :one_for_one, name: BDS.Supervisor]
|
opts = [strategy: :one_for_one, name: BDS.Supervisor]
|
||||||
Supervisor.start_link(children, opts)
|
Supervisor.start_link(children, opts)
|
||||||
|
|||||||
95
lib/bds/server.ex
Normal file
95
lib/bds/server.ex
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
defmodule BDS.Server do
|
||||||
|
@moduledoc """
|
||||||
|
Headless server mode (issue #26).
|
||||||
|
|
||||||
|
Boots the app without any wx window and serves clients over a single SSH
|
||||||
|
daemon: TUI sessions run server-side via `ExRatatui.SSH` (only terminal
|
||||||
|
cells cross the wire), and GUI clients tunnel to the loopback HTTP
|
||||||
|
endpoint through the same daemon (`tcpip_tunnel_out`). Authentication is
|
||||||
|
public-key only; host key and `authorized_keys` live in the private app
|
||||||
|
data dir next to the database — never in the repo or a priv dir.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Resolves the boot mode from the `BDS_MODE` environment variable.
|
||||||
|
Anything other than `"server"` (case-insensitive) is desktop mode.
|
||||||
|
"""
|
||||||
|
@spec mode(String.t() | nil) :: :desktop | :server
|
||||||
|
def mode(value \\ System.get_env("BDS_MODE"))
|
||||||
|
|
||||||
|
def mode(value) when is_binary(value) do
|
||||||
|
if String.downcase(value) == "server", do: :server, else: :desktop
|
||||||
|
end
|
||||||
|
|
||||||
|
def mode(nil), do: :desktop
|
||||||
|
|
||||||
|
@doc "SSH key-material directory: `<data dir>/ssh` next to the database."
|
||||||
|
@spec ssh_dir() :: Path.t()
|
||||||
|
def ssh_dir do
|
||||||
|
Application.get_env(:bds, BDS.Repo)[:database]
|
||||||
|
|> Path.dirname()
|
||||||
|
|> Path.join("ssh")
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Ensures the SSH directory exists with an `authorized_keys` file (created
|
||||||
|
empty and chmod 600 on first boot; existing keys are never touched).
|
||||||
|
"""
|
||||||
|
@spec ensure_ssh_dir!(Path.t()) :: Path.t()
|
||||||
|
def ensure_ssh_dir!(dir) do
|
||||||
|
File.mkdir_p!(dir)
|
||||||
|
keys_path = Path.join(dir, "authorized_keys")
|
||||||
|
|
||||||
|
unless File.exists?(keys_path) do
|
||||||
|
File.write!(keys_path, "")
|
||||||
|
File.chmod!(keys_path, 0o600)
|
||||||
|
end
|
||||||
|
|
||||||
|
dir
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Options for `ExRatatui.SSH.Daemon`: serves `BDS.TUI`, public-key auth
|
||||||
|
only, and allows TCP/IP tunneling out so GUI clients can reach the
|
||||||
|
loopback HTTP endpoint through the SSH connection.
|
||||||
|
"""
|
||||||
|
@spec daemon_opts(Path.t()) :: keyword()
|
||||||
|
def daemon_opts(dir \\ ssh_dir()) do
|
||||||
|
dir = ensure_ssh_dir!(dir)
|
||||||
|
system_dir = ExRatatui.SSH.Daemon.ensure_host_key!(dir)
|
||||||
|
|
||||||
|
[
|
||||||
|
mod: BDS.TUI,
|
||||||
|
port: ssh_port(),
|
||||||
|
system_dir: system_dir,
|
||||||
|
user_dir: String.to_charlist(dir),
|
||||||
|
auth_methods: ~c"publickey",
|
||||||
|
tcpip_tunnel_out: true
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc "SSH listen port: `BDS_SSH_PORT` env or `:bds, :server` config."
|
||||||
|
@spec ssh_port() :: pos_integer()
|
||||||
|
def ssh_port do
|
||||||
|
case System.get_env("BDS_SSH_PORT") do
|
||||||
|
value when is_binary(value) and value != "" -> String.to_integer(value)
|
||||||
|
_other -> Application.get_env(:bds, :server)[:ssh_port] || 2222
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc false
|
||||||
|
# Child spec that defers all filesystem work (key generation) to process
|
||||||
|
# start, so building a children list never touches the data dir.
|
||||||
|
def child_spec(_opts) do
|
||||||
|
%{
|
||||||
|
id: __MODULE__,
|
||||||
|
start: {__MODULE__, :start_link, []},
|
||||||
|
type: :worker
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc false
|
||||||
|
def start_link do
|
||||||
|
ExRatatui.SSH.Daemon.start_link(daemon_opts())
|
||||||
|
end
|
||||||
|
end
|
||||||
38
lib/bds/tui.ex
Normal file
38
lib/bds/tui.ex
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
defmodule BDS.TUI do
|
||||||
|
@moduledoc """
|
||||||
|
Terminal UI entry point (issue #26), served per SSH connection by
|
||||||
|
`ExRatatui.SSH.Daemon` in server mode and runnable locally.
|
||||||
|
|
||||||
|
Placeholder shell for now: renders the app banner while the workbench
|
||||||
|
renderer lands in a later phase. The UI locale is the server-side UI
|
||||||
|
language setting, same as the GUI.
|
||||||
|
"""
|
||||||
|
|
||||||
|
use ExRatatui.App
|
||||||
|
use Gettext, backend: BDS.Gettext
|
||||||
|
|
||||||
|
alias BDS.Desktop.UILocale
|
||||||
|
alias ExRatatui.Layout.Rect
|
||||||
|
alias ExRatatui.Widgets.Paragraph
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def mount(_opts) do
|
||||||
|
UILocale.put(BDS.Desktop.ShellData.ui_language())
|
||||||
|
{:ok, %{}}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def render(_state, frame) do
|
||||||
|
text =
|
||||||
|
"bDS2 — " <>
|
||||||
|
dgettext("ui", "Blogging Desktop Server") <>
|
||||||
|
"\n\n" <>
|
||||||
|
dgettext("ui", "Press q to quit.")
|
||||||
|
|
||||||
|
[{%Paragraph{text: text}, %Rect{x: 0, y: 0, width: frame.width, height: frame.height}}]
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_event(%ExRatatui.Event.Key{code: "q"}, state), do: {:stop, state}
|
||||||
|
def handle_event(_event, state), do: {:noreply, state}
|
||||||
|
end
|
||||||
1
mix.exs
1
mix.exs
@@ -40,6 +40,7 @@ defmodule BDS.MixProject do
|
|||||||
{:live_toast, "~> 0.8.0"},
|
{:live_toast, "~> 0.8.0"},
|
||||||
{:saxy, "~> 1.4"},
|
{:saxy, "~> 1.4"},
|
||||||
{:desktop, "~> 1.5"},
|
{:desktop, "~> 1.5"},
|
||||||
|
{:ex_ratatui, "~> 0.11"},
|
||||||
{:image, "~> 0.67"},
|
{:image, "~> 0.67"},
|
||||||
{:nx, "~> 0.10"},
|
{:nx, "~> 0.10"},
|
||||||
{:exla, "~> 0.10"},
|
{:exla, "~> 0.10"},
|
||||||
|
|||||||
1
mix.lock
1
mix.lock
@@ -25,6 +25,7 @@
|
|||||||
"esbuild": {:hex, :esbuild, "0.10.0", "b0aa3388a1c23e727c5a3e7427c932d89ee791746b0081bbe56103e9ef3d291f", [:mix], [{:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "468489cda427b974a7cc9f03ace55368a83e1a7be12fba7e30969af78e5f8c70"},
|
"esbuild": {:hex, :esbuild, "0.10.0", "b0aa3388a1c23e727c5a3e7427c932d89ee791746b0081bbe56103e9ef3d291f", [:mix], [{:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "468489cda427b974a7cc9f03ace55368a83e1a7be12fba7e30969af78e5f8c70"},
|
||||||
"ex_dbus": {:hex, :ex_dbus, "0.1.4", "053df83d45b27ba0b9b6ef55a47253922069a3ace12a2a7dd30d3aff58301e17", [:mix], [{:dbus, "~> 0.8.0", [hex: :dbus, repo: "hexpm", optional: false]}, {:saxy, "~> 1.4.0", [hex: :saxy, repo: "hexpm", optional: false]}], "hexpm", "d8baeaf465eab57b70a47b70e29fdfef6eb09ba110fc37176eebe6ac7874d6d5"},
|
"ex_dbus": {:hex, :ex_dbus, "0.1.4", "053df83d45b27ba0b9b6ef55a47253922069a3ace12a2a7dd30d3aff58301e17", [:mix], [{:dbus, "~> 0.8.0", [hex: :dbus, repo: "hexpm", optional: false]}, {:saxy, "~> 1.4.0", [hex: :saxy, repo: "hexpm", optional: false]}], "hexpm", "d8baeaf465eab57b70a47b70e29fdfef6eb09ba110fc37176eebe6ac7874d6d5"},
|
||||||
"ex_doc": {:hex, :ex_doc, "0.40.3", "4a972ffe64bc07dc605af487e98fc19b72a4185f55ca031b94c0552d6071c1d9", [:mix], [{:earmark_parser, "~> 1.4.44", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "2756e357742fecd9749b489b85d67c9ce99c465f2e75728d9e6dc8d704b973de"},
|
"ex_doc": {:hex, :ex_doc, "0.40.3", "4a972ffe64bc07dc605af487e98fc19b72a4185f55ca031b94c0552d6071c1d9", [:mix], [{:earmark_parser, "~> 1.4.44", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "2756e357742fecd9749b489b85d67c9ce99c465f2e75728d9e6dc8d704b973de"},
|
||||||
|
"ex_ratatui": {:hex, :ex_ratatui, "0.11.1", "f3cc5c9827d957bc326d3b3b48338a927716fedc2575311d65a3af0dd03ed951", [:mix], [{:rustler, ">= 0.0.0", [hex: :rustler, repo: "hexpm", optional: true]}, {:rustler_precompiled, "~> 0.8", [hex: :rustler_precompiled, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b37b02b33e1e8f49874497d7b7f8872417b3807ec77d4bc1526c07c05c7e4cc9"},
|
||||||
"ex_sni": {:hex, :ex_sni, "0.2.9", "81f9421035dd3edb6d69f1a4dd5f53c7071b41628130d32ba5ab7bb4bfdc2da0", [:mix], [{:debouncer, "~> 0.1", [hex: :debouncer, repo: "hexpm", optional: false]}, {:ex_dbus, "~> 0.1", [hex: :ex_dbus, repo: "hexpm", optional: false]}, {:saxy, "~> 1.4.0", [hex: :saxy, repo: "hexpm", optional: false]}], "hexpm", "921d67d913765ed20ea8354fd1798dabc957bf66990a6842d6aaa7cd5ee5bc06"},
|
"ex_sni": {:hex, :ex_sni, "0.2.9", "81f9421035dd3edb6d69f1a4dd5f53c7071b41628130d32ba5ab7bb4bfdc2da0", [:mix], [{:debouncer, "~> 0.1", [hex: :debouncer, repo: "hexpm", optional: false]}, {:ex_dbus, "~> 0.1", [hex: :ex_dbus, repo: "hexpm", optional: false]}, {:saxy, "~> 1.4.0", [hex: :saxy, repo: "hexpm", optional: false]}], "hexpm", "921d67d913765ed20ea8354fd1798dabc957bf66990a6842d6aaa7cd5ee5bc06"},
|
||||||
"ex_stemmers": {:hex, :ex_stemmers, "0.1.0", "63a84ae3a6f0c28a1d75768411f0ae15cfe8462fb70589b60977aa1b04c9372d", [:mix], [{:rustler, "~> 0.32.1", [hex: :rustler, repo: "hexpm", optional: false]}], "hexpm", "498826e2188e502f41d1a15f3d90e7738f0d94747e197367f03a2a44c09167c0"},
|
"ex_stemmers": {:hex, :ex_stemmers, "0.1.0", "63a84ae3a6f0c28a1d75768411f0ae15cfe8462fb70589b60977aa1b04c9372d", [:mix], [{:rustler, "~> 0.32.1", [hex: :rustler, repo: "hexpm", optional: false]}], "hexpm", "498826e2188e502f41d1a15f3d90e7738f0d94747e197367f03a2a44c09167c0"},
|
||||||
"exla": {:hex, :exla, "0.10.0", "93e7d75a774fbc06ce05b96de20c4b01bda413b315238cb3c727c09a05d2bc3a", [:make, :mix], [{:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:fine, "~> 0.1.0", [hex: :fine, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:nx, "~> 0.10.0", [hex: :nx, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:xla, "~> 0.9.0", [hex: :xla, repo: "hexpm", optional: false]}], "hexpm", "16fffdb64667d7f0a3bc683fdcd2792b143a9b345e4b1f1d5cd50330c63d8119"},
|
"exla": {:hex, :exla, "0.10.0", "93e7d75a774fbc06ce05b96de20c4b01bda413b315238cb3c727c09a05d2bc3a", [:make, :mix], [{:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:fine, "~> 0.1.0", [hex: :fine, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:nx, "~> 0.10.0", [hex: :nx, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:xla, "~> 0.9.0", [hex: :xla, repo: "hexpm", optional: false]}], "hexpm", "16fffdb64667d7f0a3bc683fdcd2792b143a9b345e4b1f1d5cd50330c63d8119"},
|
||||||
|
|||||||
@@ -71,8 +71,8 @@ msgid "AI Assistant"
|
|||||||
msgstr "KI-Assistent"
|
msgstr "KI-Assistent"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:93
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:93
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:190
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:193
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:208
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:211
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "AI Settings"
|
msgid "AI Settings"
|
||||||
msgstr "KI-Einstellungen"
|
msgstr "KI-Einstellungen"
|
||||||
@@ -336,7 +336,7 @@ msgstr "Autor"
|
|||||||
msgid "Auto"
|
msgid "Auto"
|
||||||
msgstr "Automatisch"
|
msgstr "Automatisch"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:448
|
#: lib/bds/desktop/shell_live.ex:442
|
||||||
#: lib/bds/desktop/shell_live/chat_editor.ex:234
|
#: lib/bds/desktop/shell_live/chat_editor.ex:234
|
||||||
#: lib/bds/desktop/shell_live/media_editor.ex:171
|
#: lib/bds/desktop/shell_live/media_editor.ex:171
|
||||||
#: lib/bds/desktop/shell_live/media_editor.ex:364
|
#: lib/bds/desktop/shell_live/media_editor.ex:364
|
||||||
@@ -486,7 +486,7 @@ msgstr "Kategorie-Standards, Render-Flags und Template-Zuordnung"
|
|||||||
msgid "Category name is required"
|
msgid "Category name is required"
|
||||||
msgstr "Kategoriename ist erforderlich"
|
msgstr "Kategoriename ist erforderlich"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:771
|
#: lib/bds/desktop/shell_live.ex:780
|
||||||
#: lib/bds/desktop/shell_live/chat_editor.ex:87
|
#: lib/bds/desktop/shell_live/chat_editor.ex:87
|
||||||
#: lib/bds/desktop/shell_live/chat_editor.ex:233
|
#: lib/bds/desktop/shell_live/chat_editor.ex:233
|
||||||
#: lib/bds/desktop/shell_live/chat_editor.ex:323
|
#: lib/bds/desktop/shell_live/chat_editor.ex:323
|
||||||
@@ -1063,7 +1063,7 @@ msgstr "Galerie"
|
|||||||
msgid "Generate Site"
|
msgid "Generate Site"
|
||||||
msgstr "Website generieren"
|
msgstr "Website generieren"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:772
|
#: lib/bds/desktop/shell_live.ex:781
|
||||||
#: lib/bds/desktop/shell_live/socket_state.ex:109
|
#: lib/bds/desktop/shell_live/socket_state.ex:109
|
||||||
#: lib/bds/ui/sidebar.ex:789
|
#: lib/bds/ui/sidebar.ex:789
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
@@ -1077,7 +1077,7 @@ msgid "Git Diff"
|
|||||||
msgstr "Git-Diff"
|
msgstr "Git-Diff"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_data.ex:226
|
#: lib/bds/desktop/shell_data.ex:226
|
||||||
#: lib/bds/desktop/shell_live.ex:768
|
#: lib/bds/desktop/shell_live.ex:777
|
||||||
#: lib/bds/desktop/shell_live/panel_renderer.ex:171
|
#: lib/bds/desktop/shell_live/panel_renderer.ex:171
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Git Log"
|
msgid "Git Log"
|
||||||
@@ -1200,9 +1200,9 @@ msgstr "Importdefinitionen"
|
|||||||
msgid "Import failed: %{error}"
|
msgid "Import failed: %{error}"
|
||||||
msgstr "Import fehlgeschlagen: %{error}"
|
msgstr "Import fehlgeschlagen: %{error}"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:598
|
#: lib/bds/desktop/shell_live.ex:605
|
||||||
#: lib/bds/desktop/shell_live.ex:884
|
#: lib/bds/desktop/shell_live.ex:893
|
||||||
#: lib/bds/desktop/shell_live.ex:890
|
#: lib/bds/desktop/shell_live.ex:899
|
||||||
#: lib/bds/desktop/shell_live/sidebar_create.ex:47
|
#: lib/bds/desktop/shell_live/sidebar_create.ex:47
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Import media"
|
msgid "Import media"
|
||||||
@@ -1784,7 +1784,7 @@ msgstr "Sonstige"
|
|||||||
msgid "Other (%{count})"
|
msgid "Other (%{count})"
|
||||||
msgstr "Andere (%{count})"
|
msgstr "Andere (%{count})"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:767
|
#: lib/bds/desktop/shell_live.ex:776
|
||||||
#: lib/bds/desktop/shell_live/panel_renderer.ex:83
|
#: lib/bds/desktop/shell_live/panel_renderer.ex:83
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Output"
|
msgid "Output"
|
||||||
@@ -2538,7 +2538,7 @@ msgstr "Schlagwortname"
|
|||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Tags"
|
msgstr "Tags"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:766
|
#: lib/bds/desktop/shell_live.ex:775
|
||||||
#: lib/bds/desktop/shell_live/panel_renderer.ex:54
|
#: lib/bds/desktop/shell_live/panel_renderer.ex:54
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Tasks"
|
msgid "Tasks"
|
||||||
@@ -3218,12 +3218,12 @@ msgstr "Willkommen beim KI-Assistenten"
|
|||||||
msgid "Comparing database and filesystem metadata"
|
msgid "Comparing database and filesystem metadata"
|
||||||
msgstr "Vergleicht Datenbank- und Dateisystem-Metadaten"
|
msgstr "Vergleicht Datenbank- und Dateisystem-Metadaten"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:674
|
#: lib/bds/desktop/shell_live.ex:681
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Added %{count} images to post"
|
msgid "Added %{count} images to post"
|
||||||
msgstr "%{count} Bilder zum Beitrag hinzugefügt"
|
msgstr "%{count} Bilder zum Beitrag hinzugefügt"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:642
|
#: lib/bds/desktop/shell_live.ex:649
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Added %{title}"
|
msgid "Added %{title}"
|
||||||
msgstr "%{title} hinzugefügt"
|
msgstr "%{title} hinzugefügt"
|
||||||
@@ -3243,18 +3243,18 @@ msgstr "Endbenutzer-Anleitung für redaktionelle Arbeitsabläufe, Medien, Vorlag
|
|||||||
msgid "Image Import Concurrency"
|
msgid "Image Import Concurrency"
|
||||||
msgstr "Gleichzeitige Bildimporte"
|
msgstr "Gleichzeitige Bildimporte"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:447
|
#: lib/bds/desktop/shell_live.ex:441
|
||||||
#: lib/bds/desktop/shell_live.ex:460
|
#: lib/bds/desktop/shell_live.ex:454
|
||||||
#: lib/bds/desktop/shell_live.ex:641
|
#: lib/bds/desktop/shell_live.ex:648
|
||||||
#: lib/bds/desktop/shell_live.ex:673
|
#: lib/bds/desktop/shell_live.ex:680
|
||||||
#: lib/bds/desktop/shell_live.ex:684
|
#: lib/bds/desktop/shell_live.ex:691
|
||||||
#: lib/bds/desktop/shell_live.ex:695
|
#: lib/bds/desktop/shell_live.ex:702
|
||||||
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:420
|
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:420
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Add Gallery Images"
|
msgid "Add Gallery Images"
|
||||||
msgstr "Galerie-Bilder hinzufügen"
|
msgstr "Galerie-Bilder hinzufügen"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:696
|
#: lib/bds/desktop/shell_live.ex:703
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Failed to process %{path}: %{reason}"
|
msgid "Failed to process %{path}: %{reason}"
|
||||||
msgstr "%{path} konnte nicht verarbeitet werden: %{reason}"
|
msgstr "%{path} konnte nicht verarbeitet werden: %{reason}"
|
||||||
@@ -3445,12 +3445,12 @@ msgstr "umbenannt"
|
|||||||
msgid "untracked"
|
msgid "untracked"
|
||||||
msgstr "nicht verfolgt"
|
msgstr "nicht verfolgt"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:792
|
#: lib/bds/desktop/shell_live.ex:801
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Blogmark"
|
msgid "Blogmark"
|
||||||
msgstr "Blogmark"
|
msgstr "Blogmark"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:835
|
#: lib/bds/desktop/shell_live.ex:844
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Open a project before importing a blogmark."
|
msgid "Open a project before importing a blogmark."
|
||||||
msgstr "Öffnen Sie ein Projekt, bevor Sie ein Blogmark importieren."
|
msgstr "Öffnen Sie ein Projekt, bevor Sie ein Blogmark importieren."
|
||||||
@@ -3491,7 +3491,7 @@ msgstr "Loeschen"
|
|||||||
msgid "Failed to copy bookmarklet to clipboard"
|
msgid "Failed to copy bookmarklet to clipboard"
|
||||||
msgstr "Bookmarklet konnte nicht in die Zwischenablage kopiert werden"
|
msgstr "Bookmarklet konnte nicht in die Zwischenablage kopiert werden"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:804
|
#: lib/bds/desktop/shell_live.ex:813
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "The project this blogmark targets does not exist here."
|
msgid "The project this blogmark targets does not exist here."
|
||||||
msgstr "Das Projekt, auf das dieses Blogmark verweist, existiert hier nicht."
|
msgstr "Das Projekt, auf das dieses Blogmark verweist, existiert hier nicht."
|
||||||
@@ -3578,12 +3578,12 @@ msgstr "KI-Einstellungen gespeichert."
|
|||||||
msgid "Could not load models"
|
msgid "Could not load models"
|
||||||
msgstr "Modelle konnten nicht geladen werden"
|
msgstr "Modelle konnten nicht geladen werden"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:187
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:190
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Could not save AI settings"
|
msgid "Could not save AI settings"
|
||||||
msgstr "KI-Einstellungen konnten nicht gespeichert werden"
|
msgstr "KI-Einstellungen konnten nicht gespeichert werden"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:182
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:184
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Loaded %{count} models."
|
msgid "Loaded %{count} models."
|
||||||
msgstr "%{count} Modelle geladen."
|
msgstr "%{count} Modelle geladen."
|
||||||
@@ -3593,7 +3593,17 @@ msgstr "%{count} Modelle geladen."
|
|||||||
msgid "OK"
|
msgid "OK"
|
||||||
msgstr "OK"
|
msgstr "OK"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:173
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:174
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "The endpoint returned no models. You can still type a model name manually."
|
msgid "The endpoint returned no models. You can still type a model name manually."
|
||||||
msgstr "Der Endpunkt hat keine Modelle zurückgegeben. Sie können einen Modellnamen weiterhin manuell eingeben."
|
msgstr "Der Endpunkt hat keine Modelle zurückgegeben. Sie können einen Modellnamen weiterhin manuell eingeben."
|
||||||
|
|
||||||
|
#: lib/bds/tui.ex:28
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Blogging Desktop Server"
|
||||||
|
msgstr "Blogging Desktop Server"
|
||||||
|
|
||||||
|
#: lib/bds/tui.ex:30
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Press q to quit."
|
||||||
|
msgstr "Drücken Sie q zum Beenden."
|
||||||
|
|||||||
@@ -71,8 +71,8 @@ msgid "AI Assistant"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:93
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:93
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:190
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:193
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:208
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:211
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "AI Settings"
|
msgid "AI Settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -336,7 +336,7 @@ msgstr ""
|
|||||||
msgid "Auto"
|
msgid "Auto"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:448
|
#: lib/bds/desktop/shell_live.ex:442
|
||||||
#: lib/bds/desktop/shell_live/chat_editor.ex:234
|
#: lib/bds/desktop/shell_live/chat_editor.ex:234
|
||||||
#: lib/bds/desktop/shell_live/media_editor.ex:171
|
#: lib/bds/desktop/shell_live/media_editor.ex:171
|
||||||
#: lib/bds/desktop/shell_live/media_editor.ex:364
|
#: lib/bds/desktop/shell_live/media_editor.ex:364
|
||||||
@@ -486,7 +486,7 @@ msgstr ""
|
|||||||
msgid "Category name is required"
|
msgid "Category name is required"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:771
|
#: lib/bds/desktop/shell_live.ex:780
|
||||||
#: lib/bds/desktop/shell_live/chat_editor.ex:87
|
#: lib/bds/desktop/shell_live/chat_editor.ex:87
|
||||||
#: lib/bds/desktop/shell_live/chat_editor.ex:233
|
#: lib/bds/desktop/shell_live/chat_editor.ex:233
|
||||||
#: lib/bds/desktop/shell_live/chat_editor.ex:323
|
#: lib/bds/desktop/shell_live/chat_editor.ex:323
|
||||||
@@ -1063,7 +1063,7 @@ msgstr ""
|
|||||||
msgid "Generate Site"
|
msgid "Generate Site"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:772
|
#: lib/bds/desktop/shell_live.ex:781
|
||||||
#: lib/bds/desktop/shell_live/socket_state.ex:109
|
#: lib/bds/desktop/shell_live/socket_state.ex:109
|
||||||
#: lib/bds/ui/sidebar.ex:789
|
#: lib/bds/ui/sidebar.ex:789
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
@@ -1077,7 +1077,7 @@ msgid "Git Diff"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_data.ex:226
|
#: lib/bds/desktop/shell_data.ex:226
|
||||||
#: lib/bds/desktop/shell_live.ex:768
|
#: lib/bds/desktop/shell_live.ex:777
|
||||||
#: lib/bds/desktop/shell_live/panel_renderer.ex:171
|
#: lib/bds/desktop/shell_live/panel_renderer.ex:171
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Git Log"
|
msgid "Git Log"
|
||||||
@@ -1200,9 +1200,9 @@ msgstr ""
|
|||||||
msgid "Import failed: %{error}"
|
msgid "Import failed: %{error}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:598
|
#: lib/bds/desktop/shell_live.ex:605
|
||||||
#: lib/bds/desktop/shell_live.ex:884
|
#: lib/bds/desktop/shell_live.ex:893
|
||||||
#: lib/bds/desktop/shell_live.ex:890
|
#: lib/bds/desktop/shell_live.ex:899
|
||||||
#: lib/bds/desktop/shell_live/sidebar_create.ex:47
|
#: lib/bds/desktop/shell_live/sidebar_create.ex:47
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Import media"
|
msgid "Import media"
|
||||||
@@ -1784,7 +1784,7 @@ msgstr ""
|
|||||||
msgid "Other (%{count})"
|
msgid "Other (%{count})"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:767
|
#: lib/bds/desktop/shell_live.ex:776
|
||||||
#: lib/bds/desktop/shell_live/panel_renderer.ex:83
|
#: lib/bds/desktop/shell_live/panel_renderer.ex:83
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Output"
|
msgid "Output"
|
||||||
@@ -2538,7 +2538,7 @@ msgstr ""
|
|||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:766
|
#: lib/bds/desktop/shell_live.ex:775
|
||||||
#: lib/bds/desktop/shell_live/panel_renderer.ex:54
|
#: lib/bds/desktop/shell_live/panel_renderer.ex:54
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Tasks"
|
msgid "Tasks"
|
||||||
@@ -3218,12 +3218,12 @@ msgstr ""
|
|||||||
msgid "Comparing database and filesystem metadata"
|
msgid "Comparing database and filesystem metadata"
|
||||||
msgstr "Comparing database and filesystem metadata"
|
msgstr "Comparing database and filesystem metadata"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:674
|
#: lib/bds/desktop/shell_live.ex:681
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Added %{count} images to post"
|
msgid "Added %{count} images to post"
|
||||||
msgstr "Added %{count} images to post"
|
msgstr "Added %{count} images to post"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:642
|
#: lib/bds/desktop/shell_live.ex:649
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Added %{title}"
|
msgid "Added %{title}"
|
||||||
msgstr "Added %{title}"
|
msgstr "Added %{title}"
|
||||||
@@ -3243,18 +3243,18 @@ msgstr ""
|
|||||||
msgid "Image Import Concurrency"
|
msgid "Image Import Concurrency"
|
||||||
msgstr "Image Import Concurrency"
|
msgstr "Image Import Concurrency"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:447
|
#: lib/bds/desktop/shell_live.ex:441
|
||||||
#: lib/bds/desktop/shell_live.ex:460
|
#: lib/bds/desktop/shell_live.ex:454
|
||||||
#: lib/bds/desktop/shell_live.ex:641
|
#: lib/bds/desktop/shell_live.ex:648
|
||||||
#: lib/bds/desktop/shell_live.ex:673
|
#: lib/bds/desktop/shell_live.ex:680
|
||||||
#: lib/bds/desktop/shell_live.ex:684
|
#: lib/bds/desktop/shell_live.ex:691
|
||||||
#: lib/bds/desktop/shell_live.ex:695
|
#: lib/bds/desktop/shell_live.ex:702
|
||||||
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:420
|
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:420
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Add Gallery Images"
|
msgid "Add Gallery Images"
|
||||||
msgstr "Add Gallery Images"
|
msgstr "Add Gallery Images"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:696
|
#: lib/bds/desktop/shell_live.ex:703
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Failed to process %{path}: %{reason}"
|
msgid "Failed to process %{path}: %{reason}"
|
||||||
msgstr "Failed to process %{path}: %{reason}"
|
msgstr "Failed to process %{path}: %{reason}"
|
||||||
@@ -3445,12 +3445,12 @@ msgstr ""
|
|||||||
msgid "untracked"
|
msgid "untracked"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:792
|
#: lib/bds/desktop/shell_live.ex:801
|
||||||
#, elixir-autogen, elixir-format, fuzzy
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
msgid "Blogmark"
|
msgid "Blogmark"
|
||||||
msgstr "Blogmark"
|
msgstr "Blogmark"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:835
|
#: lib/bds/desktop/shell_live.ex:844
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Open a project before importing a blogmark."
|
msgid "Open a project before importing a blogmark."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -3491,7 +3491,7 @@ msgstr ""
|
|||||||
msgid "Failed to copy bookmarklet to clipboard"
|
msgid "Failed to copy bookmarklet to clipboard"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:804
|
#: lib/bds/desktop/shell_live.ex:813
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "The project this blogmark targets does not exist here."
|
msgid "The project this blogmark targets does not exist here."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -3578,12 +3578,12 @@ msgstr ""
|
|||||||
msgid "Could not load models"
|
msgid "Could not load models"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:187
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:190
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Could not save AI settings"
|
msgid "Could not save AI settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:182
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:184
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Loaded %{count} models."
|
msgid "Loaded %{count} models."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -3593,7 +3593,17 @@ msgstr ""
|
|||||||
msgid "OK"
|
msgid "OK"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:173
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:174
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "The endpoint returned no models. You can still type a model name manually."
|
msgid "The endpoint returned no models. You can still type a model name manually."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/bds/tui.ex:28
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Blogging Desktop Server"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/bds/tui.ex:30
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Press q to quit."
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -71,8 +71,8 @@ msgid "AI Assistant"
|
|||||||
msgstr "Asistente de IA"
|
msgstr "Asistente de IA"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:93
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:93
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:190
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:193
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:208
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:211
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "AI Settings"
|
msgid "AI Settings"
|
||||||
msgstr "Configuración de IA"
|
msgstr "Configuración de IA"
|
||||||
@@ -336,7 +336,7 @@ msgstr "Autor"
|
|||||||
msgid "Auto"
|
msgid "Auto"
|
||||||
msgstr "Automático"
|
msgstr "Automático"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:448
|
#: lib/bds/desktop/shell_live.ex:442
|
||||||
#: lib/bds/desktop/shell_live/chat_editor.ex:234
|
#: lib/bds/desktop/shell_live/chat_editor.ex:234
|
||||||
#: lib/bds/desktop/shell_live/media_editor.ex:171
|
#: lib/bds/desktop/shell_live/media_editor.ex:171
|
||||||
#: lib/bds/desktop/shell_live/media_editor.ex:364
|
#: lib/bds/desktop/shell_live/media_editor.ex:364
|
||||||
@@ -486,7 +486,7 @@ msgstr "Valores predeterminados de categoría, opciones de renderizado y conexi
|
|||||||
msgid "Category name is required"
|
msgid "Category name is required"
|
||||||
msgstr "El nombre de la categoría es obligatorio"
|
msgstr "El nombre de la categoría es obligatorio"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:771
|
#: lib/bds/desktop/shell_live.ex:780
|
||||||
#: lib/bds/desktop/shell_live/chat_editor.ex:87
|
#: lib/bds/desktop/shell_live/chat_editor.ex:87
|
||||||
#: lib/bds/desktop/shell_live/chat_editor.ex:233
|
#: lib/bds/desktop/shell_live/chat_editor.ex:233
|
||||||
#: lib/bds/desktop/shell_live/chat_editor.ex:323
|
#: lib/bds/desktop/shell_live/chat_editor.ex:323
|
||||||
@@ -1063,7 +1063,7 @@ msgstr "Galeria"
|
|||||||
msgid "Generate Site"
|
msgid "Generate Site"
|
||||||
msgstr "Generar sitio"
|
msgstr "Generar sitio"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:772
|
#: lib/bds/desktop/shell_live.ex:781
|
||||||
#: lib/bds/desktop/shell_live/socket_state.ex:109
|
#: lib/bds/desktop/shell_live/socket_state.ex:109
|
||||||
#: lib/bds/ui/sidebar.ex:789
|
#: lib/bds/ui/sidebar.ex:789
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
@@ -1077,7 +1077,7 @@ msgid "Git Diff"
|
|||||||
msgstr "Diff de Git"
|
msgstr "Diff de Git"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_data.ex:226
|
#: lib/bds/desktop/shell_data.ex:226
|
||||||
#: lib/bds/desktop/shell_live.ex:768
|
#: lib/bds/desktop/shell_live.ex:777
|
||||||
#: lib/bds/desktop/shell_live/panel_renderer.ex:171
|
#: lib/bds/desktop/shell_live/panel_renderer.ex:171
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Git Log"
|
msgid "Git Log"
|
||||||
@@ -1200,9 +1200,9 @@ msgstr "Definiciones de importación"
|
|||||||
msgid "Import failed: %{error}"
|
msgid "Import failed: %{error}"
|
||||||
msgstr "La importación falló: %{error}"
|
msgstr "La importación falló: %{error}"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:598
|
#: lib/bds/desktop/shell_live.ex:605
|
||||||
#: lib/bds/desktop/shell_live.ex:884
|
#: lib/bds/desktop/shell_live.ex:893
|
||||||
#: lib/bds/desktop/shell_live.ex:890
|
#: lib/bds/desktop/shell_live.ex:899
|
||||||
#: lib/bds/desktop/shell_live/sidebar_create.ex:47
|
#: lib/bds/desktop/shell_live/sidebar_create.ex:47
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Import media"
|
msgid "Import media"
|
||||||
@@ -1784,7 +1784,7 @@ msgstr "Otros"
|
|||||||
msgid "Other (%{count})"
|
msgid "Other (%{count})"
|
||||||
msgstr "Otros (%{count})"
|
msgstr "Otros (%{count})"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:767
|
#: lib/bds/desktop/shell_live.ex:776
|
||||||
#: lib/bds/desktop/shell_live/panel_renderer.ex:83
|
#: lib/bds/desktop/shell_live/panel_renderer.ex:83
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Output"
|
msgid "Output"
|
||||||
@@ -2538,7 +2538,7 @@ msgstr "Nombre de la etiqueta"
|
|||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Etiquetas"
|
msgstr "Etiquetas"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:766
|
#: lib/bds/desktop/shell_live.ex:775
|
||||||
#: lib/bds/desktop/shell_live/panel_renderer.ex:54
|
#: lib/bds/desktop/shell_live/panel_renderer.ex:54
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Tasks"
|
msgid "Tasks"
|
||||||
@@ -3218,12 +3218,12 @@ msgstr "Bienvenido al asistente de IA"
|
|||||||
msgid "Comparing database and filesystem metadata"
|
msgid "Comparing database and filesystem metadata"
|
||||||
msgstr "Comparando metadatos de la base de datos y del sistema de archivos"
|
msgstr "Comparando metadatos de la base de datos y del sistema de archivos"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:674
|
#: lib/bds/desktop/shell_live.ex:681
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Added %{count} images to post"
|
msgid "Added %{count} images to post"
|
||||||
msgstr "%{count} imágenes añadidas a la publicación"
|
msgstr "%{count} imágenes añadidas a la publicación"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:642
|
#: lib/bds/desktop/shell_live.ex:649
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Added %{title}"
|
msgid "Added %{title}"
|
||||||
msgstr "%{title} añadido"
|
msgstr "%{title} añadido"
|
||||||
@@ -3243,18 +3243,18 @@ msgstr "Guía del usuario para flujos editoriales, medios, plantillas, traducci
|
|||||||
msgid "Image Import Concurrency"
|
msgid "Image Import Concurrency"
|
||||||
msgstr "Importación simultánea de imágenes"
|
msgstr "Importación simultánea de imágenes"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:447
|
#: lib/bds/desktop/shell_live.ex:441
|
||||||
#: lib/bds/desktop/shell_live.ex:460
|
#: lib/bds/desktop/shell_live.ex:454
|
||||||
#: lib/bds/desktop/shell_live.ex:641
|
#: lib/bds/desktop/shell_live.ex:648
|
||||||
#: lib/bds/desktop/shell_live.ex:673
|
#: lib/bds/desktop/shell_live.ex:680
|
||||||
#: lib/bds/desktop/shell_live.ex:684
|
#: lib/bds/desktop/shell_live.ex:691
|
||||||
#: lib/bds/desktop/shell_live.ex:695
|
#: lib/bds/desktop/shell_live.ex:702
|
||||||
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:420
|
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:420
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Add Gallery Images"
|
msgid "Add Gallery Images"
|
||||||
msgstr "Añadir imágenes a la galería"
|
msgstr "Añadir imágenes a la galería"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:696
|
#: lib/bds/desktop/shell_live.ex:703
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Failed to process %{path}: %{reason}"
|
msgid "Failed to process %{path}: %{reason}"
|
||||||
msgstr "No se pudo procesar %{path}: %{reason}"
|
msgstr "No se pudo procesar %{path}: %{reason}"
|
||||||
@@ -3445,12 +3445,12 @@ msgstr "renombrado"
|
|||||||
msgid "untracked"
|
msgid "untracked"
|
||||||
msgstr "sin seguimiento"
|
msgstr "sin seguimiento"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:792
|
#: lib/bds/desktop/shell_live.ex:801
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Blogmark"
|
msgid "Blogmark"
|
||||||
msgstr "Blogmark"
|
msgstr "Blogmark"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:835
|
#: lib/bds/desktop/shell_live.ex:844
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Open a project before importing a blogmark."
|
msgid "Open a project before importing a blogmark."
|
||||||
msgstr "Abre un proyecto antes de importar un blogmark."
|
msgstr "Abre un proyecto antes de importar un blogmark."
|
||||||
@@ -3491,7 +3491,7 @@ msgstr "Eliminar"
|
|||||||
msgid "Failed to copy bookmarklet to clipboard"
|
msgid "Failed to copy bookmarklet to clipboard"
|
||||||
msgstr "Error al copiar el bookmarklet al portapapeles"
|
msgstr "Error al copiar el bookmarklet al portapapeles"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:804
|
#: lib/bds/desktop/shell_live.ex:813
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "The project this blogmark targets does not exist here."
|
msgid "The project this blogmark targets does not exist here."
|
||||||
msgstr "El proyecto al que apunta este blogmark no existe aquí."
|
msgstr "El proyecto al que apunta este blogmark no existe aquí."
|
||||||
@@ -3578,12 +3578,12 @@ msgstr "Configuración de IA guardada."
|
|||||||
msgid "Could not load models"
|
msgid "Could not load models"
|
||||||
msgstr "No se pudieron cargar los modelos"
|
msgstr "No se pudieron cargar los modelos"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:187
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:190
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Could not save AI settings"
|
msgid "Could not save AI settings"
|
||||||
msgstr "No se pudo guardar la configuración de IA"
|
msgstr "No se pudo guardar la configuración de IA"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:182
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:184
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Loaded %{count} models."
|
msgid "Loaded %{count} models."
|
||||||
msgstr "%{count} modelos cargados."
|
msgstr "%{count} modelos cargados."
|
||||||
@@ -3593,7 +3593,17 @@ msgstr "%{count} modelos cargados."
|
|||||||
msgid "OK"
|
msgid "OK"
|
||||||
msgstr "OK"
|
msgstr "OK"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:173
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:174
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "The endpoint returned no models. You can still type a model name manually."
|
msgid "The endpoint returned no models. You can still type a model name manually."
|
||||||
msgstr "El endpoint no devolvió ningún modelo. Aún puedes escribir el nombre de un modelo manualmente."
|
msgstr "El endpoint no devolvió ningún modelo. Aún puedes escribir el nombre de un modelo manualmente."
|
||||||
|
|
||||||
|
#: lib/bds/tui.ex:28
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Blogging Desktop Server"
|
||||||
|
msgstr "Blogging Desktop Server"
|
||||||
|
|
||||||
|
#: lib/bds/tui.ex:30
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Press q to quit."
|
||||||
|
msgstr "Pulsa q para salir."
|
||||||
|
|||||||
@@ -71,8 +71,8 @@ msgid "AI Assistant"
|
|||||||
msgstr "Assistant IA"
|
msgstr "Assistant IA"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:93
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:93
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:190
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:193
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:208
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:211
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "AI Settings"
|
msgid "AI Settings"
|
||||||
msgstr "Paramètres IA"
|
msgstr "Paramètres IA"
|
||||||
@@ -336,7 +336,7 @@ msgstr "Auteur"
|
|||||||
msgid "Auto"
|
msgid "Auto"
|
||||||
msgstr "Automatique"
|
msgstr "Automatique"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:448
|
#: lib/bds/desktop/shell_live.ex:442
|
||||||
#: lib/bds/desktop/shell_live/chat_editor.ex:234
|
#: lib/bds/desktop/shell_live/chat_editor.ex:234
|
||||||
#: lib/bds/desktop/shell_live/media_editor.ex:171
|
#: lib/bds/desktop/shell_live/media_editor.ex:171
|
||||||
#: lib/bds/desktop/shell_live/media_editor.ex:364
|
#: lib/bds/desktop/shell_live/media_editor.ex:364
|
||||||
@@ -486,7 +486,7 @@ msgstr "Valeurs par défaut des catégories, options de rendu et liaison des mod
|
|||||||
msgid "Category name is required"
|
msgid "Category name is required"
|
||||||
msgstr "Le nom de la catégorie est requis"
|
msgstr "Le nom de la catégorie est requis"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:771
|
#: lib/bds/desktop/shell_live.ex:780
|
||||||
#: lib/bds/desktop/shell_live/chat_editor.ex:87
|
#: lib/bds/desktop/shell_live/chat_editor.ex:87
|
||||||
#: lib/bds/desktop/shell_live/chat_editor.ex:233
|
#: lib/bds/desktop/shell_live/chat_editor.ex:233
|
||||||
#: lib/bds/desktop/shell_live/chat_editor.ex:323
|
#: lib/bds/desktop/shell_live/chat_editor.ex:323
|
||||||
@@ -1063,7 +1063,7 @@ msgstr "Galerie"
|
|||||||
msgid "Generate Site"
|
msgid "Generate Site"
|
||||||
msgstr "Générer le site"
|
msgstr "Générer le site"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:772
|
#: lib/bds/desktop/shell_live.ex:781
|
||||||
#: lib/bds/desktop/shell_live/socket_state.ex:109
|
#: lib/bds/desktop/shell_live/socket_state.ex:109
|
||||||
#: lib/bds/ui/sidebar.ex:789
|
#: lib/bds/ui/sidebar.ex:789
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
@@ -1077,7 +1077,7 @@ msgid "Git Diff"
|
|||||||
msgstr "Diff Git"
|
msgstr "Diff Git"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_data.ex:226
|
#: lib/bds/desktop/shell_data.ex:226
|
||||||
#: lib/bds/desktop/shell_live.ex:768
|
#: lib/bds/desktop/shell_live.ex:777
|
||||||
#: lib/bds/desktop/shell_live/panel_renderer.ex:171
|
#: lib/bds/desktop/shell_live/panel_renderer.ex:171
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Git Log"
|
msgid "Git Log"
|
||||||
@@ -1200,9 +1200,9 @@ msgstr "Définitions d’import"
|
|||||||
msgid "Import failed: %{error}"
|
msgid "Import failed: %{error}"
|
||||||
msgstr "Échec de l’import : %{error}"
|
msgstr "Échec de l’import : %{error}"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:598
|
#: lib/bds/desktop/shell_live.ex:605
|
||||||
#: lib/bds/desktop/shell_live.ex:884
|
#: lib/bds/desktop/shell_live.ex:893
|
||||||
#: lib/bds/desktop/shell_live.ex:890
|
#: lib/bds/desktop/shell_live.ex:899
|
||||||
#: lib/bds/desktop/shell_live/sidebar_create.ex:47
|
#: lib/bds/desktop/shell_live/sidebar_create.ex:47
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Import media"
|
msgid "Import media"
|
||||||
@@ -1784,7 +1784,7 @@ msgstr "Autre"
|
|||||||
msgid "Other (%{count})"
|
msgid "Other (%{count})"
|
||||||
msgstr "Autres (%{count})"
|
msgstr "Autres (%{count})"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:767
|
#: lib/bds/desktop/shell_live.ex:776
|
||||||
#: lib/bds/desktop/shell_live/panel_renderer.ex:83
|
#: lib/bds/desktop/shell_live/panel_renderer.ex:83
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Output"
|
msgid "Output"
|
||||||
@@ -2538,7 +2538,7 @@ msgstr "Nom du mot-clé"
|
|||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Tags"
|
msgstr "Tags"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:766
|
#: lib/bds/desktop/shell_live.ex:775
|
||||||
#: lib/bds/desktop/shell_live/panel_renderer.ex:54
|
#: lib/bds/desktop/shell_live/panel_renderer.ex:54
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Tasks"
|
msgid "Tasks"
|
||||||
@@ -3218,12 +3218,12 @@ msgstr "Bienvenue dans l’assistant IA"
|
|||||||
msgid "Comparing database and filesystem metadata"
|
msgid "Comparing database and filesystem metadata"
|
||||||
msgstr "Comparaison des métadonnées entre la base et le système de fichiers"
|
msgstr "Comparaison des métadonnées entre la base et le système de fichiers"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:674
|
#: lib/bds/desktop/shell_live.ex:681
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Added %{count} images to post"
|
msgid "Added %{count} images to post"
|
||||||
msgstr "%{count} images ajoutées à l'article"
|
msgstr "%{count} images ajoutées à l'article"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:642
|
#: lib/bds/desktop/shell_live.ex:649
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Added %{title}"
|
msgid "Added %{title}"
|
||||||
msgstr "%{title} ajouté"
|
msgstr "%{title} ajouté"
|
||||||
@@ -3243,18 +3243,18 @@ msgstr "Guide utilisateur pour les flux éditoriaux, médias, modèles, traducti
|
|||||||
msgid "Image Import Concurrency"
|
msgid "Image Import Concurrency"
|
||||||
msgstr "Importation simultanée d'images"
|
msgstr "Importation simultanée d'images"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:447
|
#: lib/bds/desktop/shell_live.ex:441
|
||||||
#: lib/bds/desktop/shell_live.ex:460
|
#: lib/bds/desktop/shell_live.ex:454
|
||||||
#: lib/bds/desktop/shell_live.ex:641
|
#: lib/bds/desktop/shell_live.ex:648
|
||||||
#: lib/bds/desktop/shell_live.ex:673
|
#: lib/bds/desktop/shell_live.ex:680
|
||||||
#: lib/bds/desktop/shell_live.ex:684
|
#: lib/bds/desktop/shell_live.ex:691
|
||||||
#: lib/bds/desktop/shell_live.ex:695
|
#: lib/bds/desktop/shell_live.ex:702
|
||||||
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:420
|
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:420
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Add Gallery Images"
|
msgid "Add Gallery Images"
|
||||||
msgstr "Ajouter des images à la galerie"
|
msgstr "Ajouter des images à la galerie"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:696
|
#: lib/bds/desktop/shell_live.ex:703
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Failed to process %{path}: %{reason}"
|
msgid "Failed to process %{path}: %{reason}"
|
||||||
msgstr "Impossible de traiter %{path} : %{reason}"
|
msgstr "Impossible de traiter %{path} : %{reason}"
|
||||||
@@ -3445,12 +3445,12 @@ msgstr "renommé"
|
|||||||
msgid "untracked"
|
msgid "untracked"
|
||||||
msgstr "non suivi"
|
msgstr "non suivi"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:792
|
#: lib/bds/desktop/shell_live.ex:801
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Blogmark"
|
msgid "Blogmark"
|
||||||
msgstr "Blogmark"
|
msgstr "Blogmark"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:835
|
#: lib/bds/desktop/shell_live.ex:844
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Open a project before importing a blogmark."
|
msgid "Open a project before importing a blogmark."
|
||||||
msgstr "Ouvrez un projet avant d’importer un blogmark."
|
msgstr "Ouvrez un projet avant d’importer un blogmark."
|
||||||
@@ -3491,7 +3491,7 @@ msgstr "Supprimer"
|
|||||||
msgid "Failed to copy bookmarklet to clipboard"
|
msgid "Failed to copy bookmarklet to clipboard"
|
||||||
msgstr "Échec de la copie du bookmarklet dans le presse-papiers"
|
msgstr "Échec de la copie du bookmarklet dans le presse-papiers"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:804
|
#: lib/bds/desktop/shell_live.ex:813
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "The project this blogmark targets does not exist here."
|
msgid "The project this blogmark targets does not exist here."
|
||||||
msgstr "Le projet ciblé par ce blogmark n'existe pas ici."
|
msgstr "Le projet ciblé par ce blogmark n'existe pas ici."
|
||||||
@@ -3578,12 +3578,12 @@ msgstr "Paramètres IA enregistrés."
|
|||||||
msgid "Could not load models"
|
msgid "Could not load models"
|
||||||
msgstr "Impossible de charger les modèles"
|
msgstr "Impossible de charger les modèles"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:187
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:190
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Could not save AI settings"
|
msgid "Could not save AI settings"
|
||||||
msgstr "Impossible d'enregistrer les paramètres IA"
|
msgstr "Impossible d'enregistrer les paramètres IA"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:182
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:184
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Loaded %{count} models."
|
msgid "Loaded %{count} models."
|
||||||
msgstr "%{count} modèles chargés."
|
msgstr "%{count} modèles chargés."
|
||||||
@@ -3593,7 +3593,17 @@ msgstr "%{count} modèles chargés."
|
|||||||
msgid "OK"
|
msgid "OK"
|
||||||
msgstr "OK"
|
msgstr "OK"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:173
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:174
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "The endpoint returned no models. You can still type a model name manually."
|
msgid "The endpoint returned no models. You can still type a model name manually."
|
||||||
msgstr "Le point de terminaison n'a renvoyé aucun modèle. Vous pouvez toujours saisir un nom de modèle manuellement."
|
msgstr "Le point de terminaison n'a renvoyé aucun modèle. Vous pouvez toujours saisir un nom de modèle manuellement."
|
||||||
|
|
||||||
|
#: lib/bds/tui.ex:28
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Blogging Desktop Server"
|
||||||
|
msgstr "Blogging Desktop Server"
|
||||||
|
|
||||||
|
#: lib/bds/tui.ex:30
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Press q to quit."
|
||||||
|
msgstr "Appuyez sur q pour quitter."
|
||||||
|
|||||||
@@ -71,8 +71,8 @@ msgid "AI Assistant"
|
|||||||
msgstr "Assistente IA"
|
msgstr "Assistente IA"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:93
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:93
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:190
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:193
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:208
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:211
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "AI Settings"
|
msgid "AI Settings"
|
||||||
msgstr "Impostazioni IA"
|
msgstr "Impostazioni IA"
|
||||||
@@ -336,7 +336,7 @@ msgstr "Autore"
|
|||||||
msgid "Auto"
|
msgid "Auto"
|
||||||
msgstr "Automatico"
|
msgstr "Automatico"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:448
|
#: lib/bds/desktop/shell_live.ex:442
|
||||||
#: lib/bds/desktop/shell_live/chat_editor.ex:234
|
#: lib/bds/desktop/shell_live/chat_editor.ex:234
|
||||||
#: lib/bds/desktop/shell_live/media_editor.ex:171
|
#: lib/bds/desktop/shell_live/media_editor.ex:171
|
||||||
#: lib/bds/desktop/shell_live/media_editor.ex:364
|
#: lib/bds/desktop/shell_live/media_editor.ex:364
|
||||||
@@ -486,7 +486,7 @@ msgstr "Valori predefiniti delle categorie, opzioni di rendering e collegamento
|
|||||||
msgid "Category name is required"
|
msgid "Category name is required"
|
||||||
msgstr "Il nome della categoria è obbligatorio"
|
msgstr "Il nome della categoria è obbligatorio"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:771
|
#: lib/bds/desktop/shell_live.ex:780
|
||||||
#: lib/bds/desktop/shell_live/chat_editor.ex:87
|
#: lib/bds/desktop/shell_live/chat_editor.ex:87
|
||||||
#: lib/bds/desktop/shell_live/chat_editor.ex:233
|
#: lib/bds/desktop/shell_live/chat_editor.ex:233
|
||||||
#: lib/bds/desktop/shell_live/chat_editor.ex:323
|
#: lib/bds/desktop/shell_live/chat_editor.ex:323
|
||||||
@@ -1063,7 +1063,7 @@ msgstr "Galleria"
|
|||||||
msgid "Generate Site"
|
msgid "Generate Site"
|
||||||
msgstr "Genera sito"
|
msgstr "Genera sito"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:772
|
#: lib/bds/desktop/shell_live.ex:781
|
||||||
#: lib/bds/desktop/shell_live/socket_state.ex:109
|
#: lib/bds/desktop/shell_live/socket_state.ex:109
|
||||||
#: lib/bds/ui/sidebar.ex:789
|
#: lib/bds/ui/sidebar.ex:789
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
@@ -1077,7 +1077,7 @@ msgid "Git Diff"
|
|||||||
msgstr "Diff Git"
|
msgstr "Diff Git"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_data.ex:226
|
#: lib/bds/desktop/shell_data.ex:226
|
||||||
#: lib/bds/desktop/shell_live.ex:768
|
#: lib/bds/desktop/shell_live.ex:777
|
||||||
#: lib/bds/desktop/shell_live/panel_renderer.ex:171
|
#: lib/bds/desktop/shell_live/panel_renderer.ex:171
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Git Log"
|
msgid "Git Log"
|
||||||
@@ -1200,9 +1200,9 @@ msgstr "Definizioni di importazione"
|
|||||||
msgid "Import failed: %{error}"
|
msgid "Import failed: %{error}"
|
||||||
msgstr "Importazione non riuscita: %{error}"
|
msgstr "Importazione non riuscita: %{error}"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:598
|
#: lib/bds/desktop/shell_live.ex:605
|
||||||
#: lib/bds/desktop/shell_live.ex:884
|
#: lib/bds/desktop/shell_live.ex:893
|
||||||
#: lib/bds/desktop/shell_live.ex:890
|
#: lib/bds/desktop/shell_live.ex:899
|
||||||
#: lib/bds/desktop/shell_live/sidebar_create.ex:47
|
#: lib/bds/desktop/shell_live/sidebar_create.ex:47
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Import media"
|
msgid "Import media"
|
||||||
@@ -1784,7 +1784,7 @@ msgstr "Altro"
|
|||||||
msgid "Other (%{count})"
|
msgid "Other (%{count})"
|
||||||
msgstr "Altro (%{count})"
|
msgstr "Altro (%{count})"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:767
|
#: lib/bds/desktop/shell_live.ex:776
|
||||||
#: lib/bds/desktop/shell_live/panel_renderer.ex:83
|
#: lib/bds/desktop/shell_live/panel_renderer.ex:83
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Output"
|
msgid "Output"
|
||||||
@@ -2538,7 +2538,7 @@ msgstr "Nome del tag"
|
|||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Tag"
|
msgstr "Tag"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:766
|
#: lib/bds/desktop/shell_live.ex:775
|
||||||
#: lib/bds/desktop/shell_live/panel_renderer.ex:54
|
#: lib/bds/desktop/shell_live/panel_renderer.ex:54
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Tasks"
|
msgid "Tasks"
|
||||||
@@ -3218,12 +3218,12 @@ msgstr "Benvenuto nell’assistente IA"
|
|||||||
msgid "Comparing database and filesystem metadata"
|
msgid "Comparing database and filesystem metadata"
|
||||||
msgstr "Confronto tra i metadati del database e del filesystem"
|
msgstr "Confronto tra i metadati del database e del filesystem"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:674
|
#: lib/bds/desktop/shell_live.ex:681
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Added %{count} images to post"
|
msgid "Added %{count} images to post"
|
||||||
msgstr "%{count} immagini aggiunte al post"
|
msgstr "%{count} immagini aggiunte al post"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:642
|
#: lib/bds/desktop/shell_live.ex:649
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Added %{title}"
|
msgid "Added %{title}"
|
||||||
msgstr "%{title} aggiunto"
|
msgstr "%{title} aggiunto"
|
||||||
@@ -3243,18 +3243,18 @@ msgstr "Guida per l'utente finale per flussi editoriali, media, modelli, traduzi
|
|||||||
msgid "Image Import Concurrency"
|
msgid "Image Import Concurrency"
|
||||||
msgstr "Importazione simultanea immagini"
|
msgstr "Importazione simultanea immagini"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:447
|
#: lib/bds/desktop/shell_live.ex:441
|
||||||
#: lib/bds/desktop/shell_live.ex:460
|
#: lib/bds/desktop/shell_live.ex:454
|
||||||
#: lib/bds/desktop/shell_live.ex:641
|
#: lib/bds/desktop/shell_live.ex:648
|
||||||
#: lib/bds/desktop/shell_live.ex:673
|
#: lib/bds/desktop/shell_live.ex:680
|
||||||
#: lib/bds/desktop/shell_live.ex:684
|
#: lib/bds/desktop/shell_live.ex:691
|
||||||
#: lib/bds/desktop/shell_live.ex:695
|
#: lib/bds/desktop/shell_live.ex:702
|
||||||
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:420
|
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:420
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Add Gallery Images"
|
msgid "Add Gallery Images"
|
||||||
msgstr "Aggiungi immagini alla galleria"
|
msgstr "Aggiungi immagini alla galleria"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:696
|
#: lib/bds/desktop/shell_live.ex:703
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Failed to process %{path}: %{reason}"
|
msgid "Failed to process %{path}: %{reason}"
|
||||||
msgstr "Impossibile elaborare %{path}: %{reason}"
|
msgstr "Impossibile elaborare %{path}: %{reason}"
|
||||||
@@ -3445,12 +3445,12 @@ msgstr "rinominato"
|
|||||||
msgid "untracked"
|
msgid "untracked"
|
||||||
msgstr "non tracciato"
|
msgstr "non tracciato"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:792
|
#: lib/bds/desktop/shell_live.ex:801
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Blogmark"
|
msgid "Blogmark"
|
||||||
msgstr "Blogmark"
|
msgstr "Blogmark"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:835
|
#: lib/bds/desktop/shell_live.ex:844
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Open a project before importing a blogmark."
|
msgid "Open a project before importing a blogmark."
|
||||||
msgstr "Apri un progetto prima di importare un blogmark."
|
msgstr "Apri un progetto prima di importare un blogmark."
|
||||||
@@ -3491,7 +3491,7 @@ msgstr "Elimina"
|
|||||||
msgid "Failed to copy bookmarklet to clipboard"
|
msgid "Failed to copy bookmarklet to clipboard"
|
||||||
msgstr "Impossibile copiare il bookmarklet negli appunti"
|
msgstr "Impossibile copiare il bookmarklet negli appunti"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:804
|
#: lib/bds/desktop/shell_live.ex:813
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "The project this blogmark targets does not exist here."
|
msgid "The project this blogmark targets does not exist here."
|
||||||
msgstr "Il progetto a cui punta questo blogmark non esiste qui."
|
msgstr "Il progetto a cui punta questo blogmark non esiste qui."
|
||||||
@@ -3578,12 +3578,12 @@ msgstr "Impostazioni IA salvate."
|
|||||||
msgid "Could not load models"
|
msgid "Could not load models"
|
||||||
msgstr "Impossibile caricare i modelli"
|
msgstr "Impossibile caricare i modelli"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:187
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:190
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Could not save AI settings"
|
msgid "Could not save AI settings"
|
||||||
msgstr "Impossibile salvare le impostazioni IA"
|
msgstr "Impossibile salvare le impostazioni IA"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:182
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:184
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Loaded %{count} models."
|
msgid "Loaded %{count} models."
|
||||||
msgstr "Caricati %{count} modelli."
|
msgstr "Caricati %{count} modelli."
|
||||||
@@ -3593,7 +3593,17 @@ msgstr "Caricati %{count} modelli."
|
|||||||
msgid "OK"
|
msgid "OK"
|
||||||
msgstr "OK"
|
msgstr "OK"
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:173
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:174
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "The endpoint returned no models. You can still type a model name manually."
|
msgid "The endpoint returned no models. You can still type a model name manually."
|
||||||
msgstr "L'endpoint non ha restituito alcun modello. Puoi comunque digitare manualmente il nome di un modello."
|
msgstr "L'endpoint non ha restituito alcun modello. Puoi comunque digitare manualmente il nome di un modello."
|
||||||
|
|
||||||
|
#: lib/bds/tui.ex:28
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Blogging Desktop Server"
|
||||||
|
msgstr "Blogging Desktop Server"
|
||||||
|
|
||||||
|
#: lib/bds/tui.ex:30
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Press q to quit."
|
||||||
|
msgstr "Premi q per uscire."
|
||||||
|
|||||||
@@ -84,8 +84,8 @@ msgid "AI Assistant"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:93
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:93
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:190
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:193
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:208
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:211
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "AI Settings"
|
msgid "AI Settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -349,7 +349,7 @@ msgstr ""
|
|||||||
msgid "Auto"
|
msgid "Auto"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:448
|
#: lib/bds/desktop/shell_live.ex:442
|
||||||
#: lib/bds/desktop/shell_live/chat_editor.ex:234
|
#: lib/bds/desktop/shell_live/chat_editor.ex:234
|
||||||
#: lib/bds/desktop/shell_live/media_editor.ex:171
|
#: lib/bds/desktop/shell_live/media_editor.ex:171
|
||||||
#: lib/bds/desktop/shell_live/media_editor.ex:364
|
#: lib/bds/desktop/shell_live/media_editor.ex:364
|
||||||
@@ -499,7 +499,7 @@ msgstr ""
|
|||||||
msgid "Category name is required"
|
msgid "Category name is required"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:771
|
#: lib/bds/desktop/shell_live.ex:780
|
||||||
#: lib/bds/desktop/shell_live/chat_editor.ex:87
|
#: lib/bds/desktop/shell_live/chat_editor.ex:87
|
||||||
#: lib/bds/desktop/shell_live/chat_editor.ex:233
|
#: lib/bds/desktop/shell_live/chat_editor.ex:233
|
||||||
#: lib/bds/desktop/shell_live/chat_editor.ex:323
|
#: lib/bds/desktop/shell_live/chat_editor.ex:323
|
||||||
@@ -1076,7 +1076,7 @@ msgstr ""
|
|||||||
msgid "Generate Site"
|
msgid "Generate Site"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:772
|
#: lib/bds/desktop/shell_live.ex:781
|
||||||
#: lib/bds/desktop/shell_live/socket_state.ex:109
|
#: lib/bds/desktop/shell_live/socket_state.ex:109
|
||||||
#: lib/bds/ui/sidebar.ex:789
|
#: lib/bds/ui/sidebar.ex:789
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
@@ -1090,7 +1090,7 @@ msgid "Git Diff"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_data.ex:226
|
#: lib/bds/desktop/shell_data.ex:226
|
||||||
#: lib/bds/desktop/shell_live.ex:768
|
#: lib/bds/desktop/shell_live.ex:777
|
||||||
#: lib/bds/desktop/shell_live/panel_renderer.ex:171
|
#: lib/bds/desktop/shell_live/panel_renderer.ex:171
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Git Log"
|
msgid "Git Log"
|
||||||
@@ -1213,9 +1213,9 @@ msgstr ""
|
|||||||
msgid "Import failed: %{error}"
|
msgid "Import failed: %{error}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:598
|
#: lib/bds/desktop/shell_live.ex:605
|
||||||
#: lib/bds/desktop/shell_live.ex:884
|
#: lib/bds/desktop/shell_live.ex:893
|
||||||
#: lib/bds/desktop/shell_live.ex:890
|
#: lib/bds/desktop/shell_live.ex:899
|
||||||
#: lib/bds/desktop/shell_live/sidebar_create.ex:47
|
#: lib/bds/desktop/shell_live/sidebar_create.ex:47
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Import media"
|
msgid "Import media"
|
||||||
@@ -1797,7 +1797,7 @@ msgstr ""
|
|||||||
msgid "Other (%{count})"
|
msgid "Other (%{count})"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:767
|
#: lib/bds/desktop/shell_live.ex:776
|
||||||
#: lib/bds/desktop/shell_live/panel_renderer.ex:83
|
#: lib/bds/desktop/shell_live/panel_renderer.ex:83
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Output"
|
msgid "Output"
|
||||||
@@ -2551,7 +2551,7 @@ msgstr ""
|
|||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:766
|
#: lib/bds/desktop/shell_live.ex:775
|
||||||
#: lib/bds/desktop/shell_live/panel_renderer.ex:54
|
#: lib/bds/desktop/shell_live/panel_renderer.ex:54
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Tasks"
|
msgid "Tasks"
|
||||||
@@ -3231,12 +3231,12 @@ msgstr ""
|
|||||||
msgid "Comparing database and filesystem metadata"
|
msgid "Comparing database and filesystem metadata"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:674
|
#: lib/bds/desktop/shell_live.ex:681
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Added %{count} images to post"
|
msgid "Added %{count} images to post"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:642
|
#: lib/bds/desktop/shell_live.ex:649
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Added %{title}"
|
msgid "Added %{title}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -3256,18 +3256,18 @@ msgstr ""
|
|||||||
msgid "Image Import Concurrency"
|
msgid "Image Import Concurrency"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:447
|
#: lib/bds/desktop/shell_live.ex:441
|
||||||
#: lib/bds/desktop/shell_live.ex:460
|
#: lib/bds/desktop/shell_live.ex:454
|
||||||
#: lib/bds/desktop/shell_live.ex:641
|
#: lib/bds/desktop/shell_live.ex:648
|
||||||
#: lib/bds/desktop/shell_live.ex:673
|
#: lib/bds/desktop/shell_live.ex:680
|
||||||
#: lib/bds/desktop/shell_live.ex:684
|
#: lib/bds/desktop/shell_live.ex:691
|
||||||
#: lib/bds/desktop/shell_live.ex:695
|
#: lib/bds/desktop/shell_live.ex:702
|
||||||
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:420
|
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:420
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Add Gallery Images"
|
msgid "Add Gallery Images"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:696
|
#: lib/bds/desktop/shell_live.ex:703
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Failed to process %{path}: %{reason}"
|
msgid "Failed to process %{path}: %{reason}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -3458,12 +3458,12 @@ msgstr ""
|
|||||||
msgid "untracked"
|
msgid "untracked"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:792
|
#: lib/bds/desktop/shell_live.ex:801
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Blogmark"
|
msgid "Blogmark"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:835
|
#: lib/bds/desktop/shell_live.ex:844
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Open a project before importing a blogmark."
|
msgid "Open a project before importing a blogmark."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -3504,7 +3504,7 @@ msgstr ""
|
|||||||
msgid "Failed to copy bookmarklet to clipboard"
|
msgid "Failed to copy bookmarklet to clipboard"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live.ex:804
|
#: lib/bds/desktop/shell_live.ex:813
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "The project this blogmark targets does not exist here."
|
msgid "The project this blogmark targets does not exist here."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -3591,12 +3591,12 @@ msgstr ""
|
|||||||
msgid "Could not load models"
|
msgid "Could not load models"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:187
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:190
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Could not save AI settings"
|
msgid "Could not save AI settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:182
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:184
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Loaded %{count} models."
|
msgid "Loaded %{count} models."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -3606,7 +3606,17 @@ msgstr ""
|
|||||||
msgid "OK"
|
msgid "OK"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:173
|
#: lib/bds/desktop/shell_live/settings_editor/ai_settings.ex:174
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "The endpoint returned no models. You can still type a model name manually."
|
msgid "The endpoint returned no models. You can still type a model name manually."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/bds/tui.ex:28
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Blogging Desktop Server"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/bds/tui.ex:30
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Press q to quit."
|
||||||
|
msgstr ""
|
||||||
|
|||||||
62
specs/server.allium
Normal file
62
specs/server.allium
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
-- allium: 1
|
||||||
|
-- Headless Server Mode (issue #26, phase 1)
|
||||||
|
-- Scope: extension (client/server split — SSH transport for TUI and GUI)
|
||||||
|
-- Distilled from: lib/bds/server.ex, lib/bds/application.ex, lib/bds/tui.ex
|
||||||
|
|
||||||
|
entity BootMode {
|
||||||
|
kind: desktop | server
|
||||||
|
-- Resolved from the BDS_MODE environment variable at application start.
|
||||||
|
-- Anything other than "server" (case-insensitive) is desktop.
|
||||||
|
}
|
||||||
|
|
||||||
|
entity SshKeyMaterial {
|
||||||
|
dir: String -- <data dir>/ssh, next to the database
|
||||||
|
host_key: String -- ssh_host_rsa_key, generated on first boot
|
||||||
|
authorized_keys: String -- created empty (mode 600) on first boot
|
||||||
|
|
||||||
|
-- Invariant: key material lives in the private app data dir,
|
||||||
|
-- never in the repo or an application priv dir.
|
||||||
|
}
|
||||||
|
|
||||||
|
surface ServerRuntimeSurface {
|
||||||
|
facing _: ServerRuntime
|
||||||
|
|
||||||
|
provides:
|
||||||
|
ApplicationStarted(mode)
|
||||||
|
SshClientConnected()
|
||||||
|
}
|
||||||
|
|
||||||
|
rule ModeResolution {
|
||||||
|
when: ApplicationStarted(mode)
|
||||||
|
-- BDS_MODE environment variable decides the mode once per boot
|
||||||
|
ensures: BootMode.created(kind: mode)
|
||||||
|
}
|
||||||
|
|
||||||
|
rule DesktopBoot {
|
||||||
|
when: ApplicationStarted(mode: desktop)
|
||||||
|
-- Unchanged behavior: wx window shell, loopback HTTP endpoint.
|
||||||
|
ensures: DesktopWindowStarted()
|
||||||
|
}
|
||||||
|
|
||||||
|
rule ServerBoot {
|
||||||
|
when: ApplicationStarted(mode: server)
|
||||||
|
-- Headless: no wx children at all. Works on macOS, Windows, Linux.
|
||||||
|
ensures: LoopbackEndpointStarted()
|
||||||
|
-- HTTP endpoint stays bound to 127.0.0.1; never exposed directly
|
||||||
|
ensures: CliSyncWatcherStarted()
|
||||||
|
ensures: SshDaemonStarted()
|
||||||
|
-- ExRatatui.SSH.Daemon: public-key auth only (no passwords),
|
||||||
|
-- tcpip_tunnel_out enabled so GUI clients tunnel to the loopback
|
||||||
|
-- endpoint through the same SSH connection and the same keys
|
||||||
|
ensures: SshKeyMaterial.created()
|
||||||
|
-- host key generated and authorized_keys touched on first boot only
|
||||||
|
}
|
||||||
|
|
||||||
|
rule TuiSession {
|
||||||
|
when: SshClientConnected()
|
||||||
|
-- Each SSH client gets its own TUI app instance on the server;
|
||||||
|
-- only terminal cells cross the wire.
|
||||||
|
ensures: TuiAppMounted()
|
||||||
|
-- UI locale comes from the server-side UI language setting,
|
||||||
|
-- identical for every client
|
||||||
|
}
|
||||||
@@ -127,7 +127,9 @@ defmodule BDS.Scripting.JobTest do
|
|||||||
_running_job = wait_for_job(job.id, &(&1.status == :running))
|
_running_job = wait_for_job(job.id, &(&1.status == :running))
|
||||||
|
|
||||||
assert :ok = BDS.Scripting.cancel_job(job.id)
|
assert :ok = BDS.Scripting.cancel_job(job.id)
|
||||||
assert_receive :job_cleanup_ran, 1_000
|
# Generous timeout: cleanup runs in a separate shutdown path and 1s
|
||||||
|
# flakes when the full suite loads the machine.
|
||||||
|
assert_receive :job_cleanup_ran, 5_000
|
||||||
|
|
||||||
cancelled_job = wait_for_job(job.id, &(&1.status == :cancelled))
|
cancelled_job = wait_for_job(job.id, &(&1.status == :cancelled))
|
||||||
assert cancelled_job.finished_at != nil
|
assert cancelled_job.finished_at != nil
|
||||||
|
|||||||
111
test/bds/server_test.exs
Normal file
111
test/bds/server_test.exs
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
defmodule BDS.ServerTest do
|
||||||
|
use ExUnit.Case, async: false
|
||||||
|
|
||||||
|
alias BDS.Server
|
||||||
|
|
||||||
|
describe "mode/1" do
|
||||||
|
test "defaults to :desktop" do
|
||||||
|
assert Server.mode(nil) == :desktop
|
||||||
|
assert Server.mode("") == :desktop
|
||||||
|
end
|
||||||
|
|
||||||
|
test "recognizes server mode" do
|
||||||
|
assert Server.mode("server") == :server
|
||||||
|
assert Server.mode("SERVER") == :server
|
||||||
|
end
|
||||||
|
|
||||||
|
test "unknown values fall back to :desktop" do
|
||||||
|
assert Server.mode("garbage") == :desktop
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "ensure_ssh_dir!/1" do
|
||||||
|
setup do
|
||||||
|
dir = Path.join(System.tmp_dir!(), "bds-ssh-test-#{System.unique_integer([:positive])}")
|
||||||
|
on_exit(fn -> File.rm_rf!(dir) end)
|
||||||
|
{:ok, dir: dir}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "creates the directory and an empty authorized_keys file", %{dir: dir} do
|
||||||
|
assert Server.ensure_ssh_dir!(dir) == dir
|
||||||
|
assert File.dir?(dir)
|
||||||
|
|
||||||
|
keys_path = Path.join(dir, "authorized_keys")
|
||||||
|
assert File.exists?(keys_path)
|
||||||
|
assert File.read!(keys_path) == ""
|
||||||
|
|
||||||
|
%File.Stat{mode: mode} = File.stat!(keys_path)
|
||||||
|
assert Bitwise.band(mode, 0o777) == 0o600
|
||||||
|
end
|
||||||
|
|
||||||
|
test "leaves an existing authorized_keys file untouched", %{dir: dir} do
|
||||||
|
File.mkdir_p!(dir)
|
||||||
|
keys_path = Path.join(dir, "authorized_keys")
|
||||||
|
File.write!(keys_path, "ssh-ed25519 AAAA... user@host\n")
|
||||||
|
|
||||||
|
Server.ensure_ssh_dir!(dir)
|
||||||
|
|
||||||
|
assert File.read!(keys_path) == "ssh-ed25519 AAAA... user@host\n"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "daemon_opts/1" do
|
||||||
|
setup do
|
||||||
|
dir = Path.join(System.tmp_dir!(), "bds-ssh-test-#{System.unique_integer([:positive])}")
|
||||||
|
on_exit(fn -> File.rm_rf!(dir) end)
|
||||||
|
{:ok, dir: dir}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "serves the TUI app over public-key auth only, with GUI tunneling", %{dir: dir} do
|
||||||
|
opts = Server.daemon_opts(dir)
|
||||||
|
|
||||||
|
assert opts[:mod] == BDS.TUI
|
||||||
|
assert opts[:auth_methods] == ~c"publickey"
|
||||||
|
assert opts[:tcpip_tunnel_out] == true
|
||||||
|
refute Keyword.has_key?(opts, :pwdfun)
|
||||||
|
|
||||||
|
assert opts[:system_dir] == String.to_charlist(dir)
|
||||||
|
assert opts[:user_dir] == String.to_charlist(dir)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "generates a host key on first use and reuses it", %{dir: dir} do
|
||||||
|
Server.daemon_opts(dir)
|
||||||
|
key_path = Path.join(dir, "ssh_host_rsa_key")
|
||||||
|
assert File.exists?(key_path)
|
||||||
|
first = File.read!(key_path)
|
||||||
|
|
||||||
|
Server.daemon_opts(dir)
|
||||||
|
assert File.read!(key_path) == first
|
||||||
|
end
|
||||||
|
|
||||||
|
test "uses the configured SSH port", %{dir: dir} do
|
||||||
|
assert Server.daemon_opts(dir)[:port] == Application.get_env(:bds, :server)[:ssh_port]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "BDS.Application.mode_children/2" do
|
||||||
|
test "server mode starts endpoint, cli sync watcher, and the SSH daemon" do
|
||||||
|
children = BDS.Application.mode_children(:server, :prod)
|
||||||
|
|
||||||
|
assert {BDS.Desktop.Server, []} in children
|
||||||
|
assert BDS.CliSync.Watcher in children
|
||||||
|
# BDS.Server wraps ExRatatui.SSH.Daemon, deferring key generation to
|
||||||
|
# process start so building this list never touches the data dir.
|
||||||
|
assert BDS.Server in children
|
||||||
|
end
|
||||||
|
|
||||||
|
test "server mode starts no wx window children" do
|
||||||
|
children = BDS.Application.mode_children(:server, :prod)
|
||||||
|
|
||||||
|
refute Enum.any?(children, fn
|
||||||
|
{Desktop.Window, _} -> true
|
||||||
|
_other -> false
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "desktop mode delegates to desktop_children" do
|
||||||
|
assert BDS.Application.mode_children(:desktop, :test) ==
|
||||||
|
BDS.Application.desktop_children(:test)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user