mirror of
https://github.com/narrrl/proton-drive-linux.git
synced 2026-11-03 16:41:26 +01:00
Compare commits
19
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b093010b64 | ||
|
|
ab8fe0e61d | ||
|
|
b8295373f7 | ||
|
|
5bc0b5c58a | ||
|
|
73af39ee65 | ||
|
|
48aaad23ce | ||
|
|
e9577f953f | ||
|
|
437d14b0f5 | ||
|
|
b40ca797d9 | ||
|
|
c64bb23e3c | ||
|
|
8d4a005aa2 | ||
|
|
9460c93b50 | ||
|
|
bd50ba5959 | ||
|
|
27201914ee | ||
|
|
2775f0681d | ||
|
|
97277d41dd | ||
|
|
d49738bf0b | ||
|
|
48945b9c97 | ||
|
|
42f3a18177 |
No files matched your search
@@ -0,0 +1,122 @@
|
||||
//! Log priorities for journald.
|
||||
//!
|
||||
//! journald files each line a service writes at the unit's default priority,
|
||||
//! info, unless the line opens with a syslog `<N>` prefix. Without one every
|
||||
//! WARN and ERROR the daemon logs is stored as info, and the
|
||||
//! `journalctl -p warning` that the troubleshooting guide asks for shows
|
||||
//! nothing (`docs/BUGS.md` B258).
|
||||
|
||||
use std::fmt;
|
||||
use std::os::unix::fs::MetadataExt;
|
||||
|
||||
use tracing::{Event, Level, Subscriber};
|
||||
use tracing_subscriber::fmt::format::Writer;
|
||||
use tracing_subscriber::fmt::{FmtContext, FormatEvent, FormatFields};
|
||||
use tracing_subscriber::registry::LookupSpan;
|
||||
|
||||
/// Whether standard output is the journal stream systemd connected this
|
||||
/// process to.
|
||||
///
|
||||
/// `JOURNAL_STREAM` alone does not say so: a terminal started from a user unit
|
||||
/// inherits it, and every `pdfs` run in that terminal would print the
|
||||
/// prefixes. systemd sets it to the stream's `device:inode`, so it is compared
|
||||
/// against what fd 1 actually is.
|
||||
pub(crate) fn stdout_is_journal() -> bool {
|
||||
let Some(stream) = std::env::var_os("JOURNAL_STREAM") else {
|
||||
return false;
|
||||
};
|
||||
let Ok(stdout) = std::fs::metadata("/proc/self/fd/1") else {
|
||||
return false;
|
||||
};
|
||||
stream
|
||||
.to_str()
|
||||
.is_some_and(|value| names_stream(value, stdout.dev(), stdout.ino()))
|
||||
}
|
||||
|
||||
/// Whether a `JOURNAL_STREAM` value names the file `dev`:`ino`.
|
||||
fn names_stream(value: &str, dev: u64, ino: u64) -> bool {
|
||||
value
|
||||
.split_once(':')
|
||||
.is_some_and(|(d, i)| d.parse() == Ok(dev) && i.parse() == Ok(ino))
|
||||
}
|
||||
|
||||
/// The syslog priority journald should file a `level` line at.
|
||||
fn priority(level: &Level) -> u8 {
|
||||
match *level {
|
||||
Level::ERROR => 3,
|
||||
Level::WARN => 4,
|
||||
Level::INFO => 6,
|
||||
Level::DEBUG | Level::TRACE => 7,
|
||||
}
|
||||
}
|
||||
|
||||
/// An event format that opens each line with its `<N>` priority, then writes
|
||||
/// the line as `F` would.
|
||||
pub(crate) struct Prioritized<F>(pub(crate) F);
|
||||
|
||||
impl<S, N, F> FormatEvent<S, N> for Prioritized<F>
|
||||
where
|
||||
S: Subscriber + for<'a> LookupSpan<'a>,
|
||||
N: for<'a> FormatFields<'a> + 'static,
|
||||
F: FormatEvent<S, N>,
|
||||
{
|
||||
fn format_event(
|
||||
&self,
|
||||
ctx: &FmtContext<'_, S, N>,
|
||||
mut writer: Writer<'_>,
|
||||
event: &Event<'_>,
|
||||
) -> fmt::Result {
|
||||
write!(writer, "<{}>", priority(event.metadata().level()))?;
|
||||
self.0.format_event(ctx, writer, event)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::io;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Buf(Arc<Mutex<Vec<u8>>>);
|
||||
|
||||
impl io::Write for Buf {
|
||||
fn write(&mut self, bytes: &[u8]) -> io::Result<usize> {
|
||||
self.0.lock().unwrap().extend_from_slice(bytes);
|
||||
Ok(bytes.len())
|
||||
}
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn each_line_opens_with_the_priority_of_its_level() {
|
||||
let buf = Buf(Arc::new(Mutex::new(Vec::new())));
|
||||
let writer = buf.clone();
|
||||
let subscriber = tracing_subscriber::fmt()
|
||||
.with_max_level(Level::DEBUG)
|
||||
.with_ansi(false)
|
||||
.with_writer(move || writer.clone())
|
||||
.event_format(Prioritized(tracing_subscriber::fmt::format()))
|
||||
.finish();
|
||||
tracing::subscriber::with_default(subscriber, || {
|
||||
tracing::error!("e");
|
||||
tracing::warn!("w");
|
||||
tracing::info!("i");
|
||||
tracing::debug!("d");
|
||||
});
|
||||
let out = String::from_utf8(buf.0.lock().unwrap().clone()).unwrap();
|
||||
let prefixes: Vec<&str> = out.lines().map(|line| &line[..3]).collect();
|
||||
assert_eq!(prefixes, ["<3>", "<4>", "<6>", "<7>"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn journal_stream_must_name_the_same_file() {
|
||||
assert!(names_stream("8:12345", 8, 12345));
|
||||
assert!(!names_stream("8:12345", 8, 54321));
|
||||
assert!(!names_stream("9:12345", 8, 12345));
|
||||
assert!(!names_stream("8", 8, 12345));
|
||||
assert!(!names_stream("", 8, 12345));
|
||||
}
|
||||
}
|
||||
+115
-13
@@ -20,6 +20,8 @@ use pdfs_core::control::{
|
||||
use pdfs_core::db::Db;
|
||||
use pdfs_core::service;
|
||||
|
||||
mod journal;
|
||||
|
||||
/// `println!` for this binary, shadowing std's, which panics when stdout is
|
||||
/// closed: `pdfs ls | head` ended in a "Broken pipe" panic once `head` had its
|
||||
/// lines. This one hands the failure to [`stdout_written`] instead.
|
||||
@@ -879,15 +881,22 @@ fn cli_error(kind: ErrorKind, message: &str) -> String {
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
tracing_subscriber::fmt()
|
||||
.with_env_filter(
|
||||
tracing_subscriber::EnvFilter::try_from_default_env()
|
||||
// `pgp` logs a benign WARN when it re-serializes a Proton secret-key
|
||||
// packet with a longer (but equivalent) length encoding than the
|
||||
// original; drop it to error so normal runs stay quiet.
|
||||
.unwrap_or_else(|_| "info,pgp=error".into()),
|
||||
)
|
||||
.init();
|
||||
let filter = tracing_subscriber::EnvFilter::try_from_default_env()
|
||||
// `pgp` logs a benign WARN when it re-serializes a Proton secret-key
|
||||
// packet with a longer (but equivalent) length encoding than the
|
||||
// original; drop it to error so normal runs stay quiet.
|
||||
.unwrap_or_else(|_| "info,pgp=error".into());
|
||||
if journal::stdout_is_journal() {
|
||||
// journalctl colours lines by the priority the prefix gives them, so
|
||||
// the escape codes would only be noise in the stored text.
|
||||
tracing_subscriber::fmt()
|
||||
.with_env_filter(filter)
|
||||
.with_ansi(false)
|
||||
.event_format(journal::Prioritized(tracing_subscriber::fmt::format()))
|
||||
.init();
|
||||
} else {
|
||||
tracing_subscriber::fmt().with_env_filter(filter).init();
|
||||
}
|
||||
|
||||
let cli = Cli::parse();
|
||||
JSON_OUTPUT.store(cli.json, std::sync::atomic::Ordering::Relaxed);
|
||||
@@ -2375,12 +2384,21 @@ where
|
||||
/// an external unmount triggers a remount; errors back off and retry. This is
|
||||
/// the entry point for the systemd user service.
|
||||
fn cmd_daemon(mountpoint: Option<PathBuf>) -> Result<()> {
|
||||
let state_dir = AppDirs::new()?.state_dir();
|
||||
// A failure an earlier daemon recorded is not this one's.
|
||||
pdfs_core::mountfail::clear(&state_dir);
|
||||
let mut failure: Option<pdfs_core::mountfail::MountFailure> = None;
|
||||
loop {
|
||||
// Wait until a session is stored. The GUI enables this service on login,
|
||||
// but the service may also start at boot before the user has logged in.
|
||||
wait_for_session(auth::ready, pdfs_fuse::idle_sleep)?;
|
||||
|
||||
match mount_once(mountpoint.clone()) {
|
||||
let outcome = mount_once(mountpoint.clone());
|
||||
if outcome.is_ok() {
|
||||
// The mount came up, so the next failure starts a new run of them.
|
||||
failure = None;
|
||||
}
|
||||
match outcome {
|
||||
Ok(pdfs_fuse::MountOutcome::Shutdown) => {
|
||||
tracing::info!("daemon stopping");
|
||||
return Ok(());
|
||||
@@ -2395,13 +2413,51 @@ fn cmd_daemon(mountpoint: Option<PathBuf>) -> Result<()> {
|
||||
Err(e) => {
|
||||
// `{:#}` so the whole anyhow chain lands in the log — the top
|
||||
// context alone ("mount failed") never says *why*.
|
||||
tracing::error!(error = format!("{e:#}"), "mount failed; retrying in 5s");
|
||||
pdfs_fuse::idle_sleep(std::time::Duration::from_secs(5));
|
||||
let error = format!("{e:#}");
|
||||
let now = unix_now();
|
||||
let attempts = failure.as_ref().map_or(1, |f| f.attempts.saturating_add(1));
|
||||
let delay = mount_retry_delay(attempts);
|
||||
tracing::error!(
|
||||
error,
|
||||
attempts,
|
||||
retry_secs = delay.as_secs(),
|
||||
"mount failed; retrying"
|
||||
);
|
||||
let record = pdfs_core::mountfail::MountFailure {
|
||||
error: error.clone(),
|
||||
since: failure.as_ref().map_or(now, |f| f.since),
|
||||
attempts,
|
||||
next_attempt: now + delay.as_secs() as i64,
|
||||
};
|
||||
if let Err(e) = pdfs_core::mountfail::record(&state_dir, &record) {
|
||||
tracing::warn!(error = %e, "could not record the mount failure");
|
||||
}
|
||||
pdfs_fuse::notify_status(&format!("Mount failing: {error}"));
|
||||
failure = Some(record);
|
||||
pdfs_fuse::idle_sleep(delay);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// How long to wait before mount attempt `attempts + 1`, after `attempts`
|
||||
/// failures in a row.
|
||||
///
|
||||
/// Doubles from 5 s to a 2-minute ceiling. A flat 5 s retry sent about four
|
||||
/// requests to Proton per attempt, tens of thousands a day from an account
|
||||
/// whose mount fails on a key, which no retry fixes (`docs/BUGS.md` B263). The
|
||||
/// ceiling stays at minutes because a cold start without a network fails the
|
||||
/// same way, and must mount soon after the network returns.
|
||||
fn mount_retry_delay(attempts: u32) -> std::time::Duration {
|
||||
const BASE_SECS: u64 = 5;
|
||||
const MAX_SECS: u64 = 120;
|
||||
|
||||
let factor = 1u64
|
||||
.checked_shl(attempts.saturating_sub(1))
|
||||
.unwrap_or(u64::MAX);
|
||||
std::time::Duration::from_secs(BASE_SECS.saturating_mul(factor).min(MAX_SECS))
|
||||
}
|
||||
|
||||
/// One mount run: resume the session, mount, and block until the mount ends
|
||||
/// (clean shutdown or external unmount). Returns the [`MountOutcome`] so the
|
||||
/// daemon loop can decide whether to exit or remount.
|
||||
@@ -3096,6 +3152,24 @@ fn human_secs(secs: u64) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
/// The sync engine's line in `pdfs diagnostics`: whether it runs, and which
|
||||
/// folder's pass it is on.
|
||||
fn sync_engine_line(sync: &pdfs_core::control::SyncEngineState) -> String {
|
||||
let mut line = match (sync.running, sync.pass_folder) {
|
||||
(false, _) => "STOPPED; synced folders do not sync until the daemon restarts".to_string(),
|
||||
(true, None) => "idle".to_string(),
|
||||
(true, Some(folder)) => format!(
|
||||
"pass on folder {folder} for {}, last progress {} ago",
|
||||
human_secs(sync.pass_age_secs),
|
||||
human_secs(sync.pass_idle_secs),
|
||||
),
|
||||
};
|
||||
if sync.panics > 0 {
|
||||
line.push_str(&format!("; {} pass(es) panicked", sync.panics));
|
||||
}
|
||||
line
|
||||
}
|
||||
|
||||
fn cmd_diagnostics() -> Result<()> {
|
||||
let response = control_request(CtlRequest::Diagnostics)?;
|
||||
if emit_json(&response)? {
|
||||
@@ -3131,6 +3205,9 @@ fn cmd_diagnostics() -> Result<()> {
|
||||
human_secs(worker.age_secs)
|
||||
);
|
||||
}
|
||||
if let Some(sync) = &d.sync {
|
||||
println!("sync engine: {}", sync_engine_line(sync));
|
||||
}
|
||||
if d.inflight.is_empty() {
|
||||
println!("in-flight requests: none");
|
||||
} else {
|
||||
@@ -3857,7 +3934,23 @@ fn cmd_diagnose() -> Result<()> {
|
||||
" daemon responding",
|
||||
format!("stopped or unreachable: {e:#}"),
|
||||
);
|
||||
println!(" (start it with `systemctl --user start proton-drive.service`)");
|
||||
match pdfs_core::mountfail::read(&dirs.state_dir()) {
|
||||
// A daemon whose mount keeps failing never opens the socket,
|
||||
// so this is the only place its reason shows (B263).
|
||||
Some(failure) => report.finding(
|
||||
DiagnoseLevel::Fail,
|
||||
" mount",
|
||||
format!(
|
||||
"failing for {}, {} attempt(s): {}",
|
||||
human_secs(unix_now().saturating_sub(failure.since).max(0) as u64),
|
||||
failure.attempts,
|
||||
failure.error
|
||||
),
|
||||
),
|
||||
None => println!(
|
||||
" (start it with `systemctl --user start proton-drive.service`)"
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4017,6 +4110,15 @@ mod diagnose_tests {
|
||||
#[cfg(test)]
|
||||
mod login_wait_tests {
|
||||
use super::*;
|
||||
|
||||
/// The mount retry backs off from 5 s to a ceiling of minutes, rather than
|
||||
/// asking Proton every 5 s forever (`docs/BUGS.md` B263).
|
||||
#[test]
|
||||
fn a_failing_mount_backs_off_to_a_ceiling() {
|
||||
let secs: Vec<u64> = (1..=8).map(|n| mount_retry_delay(n).as_secs()).collect();
|
||||
assert_eq!(secs, [5, 10, 20, 40, 80, 120, 120, 120]);
|
||||
assert_eq!(mount_retry_delay(u32::MAX).as_secs(), 120);
|
||||
}
|
||||
use std::time::Duration;
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -1980,6 +1980,29 @@ pub struct Diagnostics {
|
||||
pub control_handler_limit: usize,
|
||||
/// Queued mutations not yet drained.
|
||||
pub pending_ops: u64,
|
||||
/// The folder-sync engine. `None` from a daemon that predates the field.
|
||||
#[serde(default)]
|
||||
pub sync: Option<SyncEngineState>,
|
||||
}
|
||||
|
||||
/// What the folder-sync engine is doing, for [`Diagnostics`].
|
||||
///
|
||||
/// The engine is one thread that runs every synced folder's passes in turn.
|
||||
/// Dead or stuck, it looked exactly like an idle one: workers idle, nothing
|
||||
/// queued, nothing in the journal (`docs/BUGS.md` B259).
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||
pub struct SyncEngineState {
|
||||
/// Whether the engine thread is running. Once it has ended, nothing syncs
|
||||
/// until the daemon restarts.
|
||||
pub running: bool,
|
||||
/// The synced folder whose pass is running, if one is.
|
||||
pub pass_folder: Option<i64>,
|
||||
/// How long that pass has been running.
|
||||
pub pass_age_secs: u64,
|
||||
/// How long since that pass last reported progress.
|
||||
pub pass_idle_secs: u64,
|
||||
/// Passes that ended in a panic since the daemon started.
|
||||
pub panics: u64,
|
||||
}
|
||||
|
||||
/// The daemon's reply to a [`Request`].
|
||||
|
||||
@@ -15,6 +15,7 @@ pub mod kernelkey;
|
||||
pub mod keycheck;
|
||||
pub mod localindex;
|
||||
pub mod menu;
|
||||
pub mod mountfail;
|
||||
pub mod mounts;
|
||||
pub mod opener;
|
||||
pub mod places;
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
//! Why the daemon's mount keeps failing, for the front ends to read.
|
||||
//!
|
||||
//! The control socket opens only once a mount has succeeded, so a daemon whose
|
||||
//! mount fails on every try had no way to say why. The app and the tray showed
|
||||
//! "Connecting…" for days while the reason sat in the journal (`docs/BUGS.md`
|
||||
//! B263). The daemon now writes its last failure to a small file in the state
|
||||
//! directory, next to the control socket, and removes it once a mount is up.
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// The file's name inside the state directory.
|
||||
const FILE_NAME: &str = "mount-failure.json";
|
||||
|
||||
/// The last failed mount attempt.
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
|
||||
pub struct MountFailure {
|
||||
/// The error, in English, as the journal has it.
|
||||
pub error: String,
|
||||
/// Unix seconds of the first failure in this run of failures.
|
||||
pub since: i64,
|
||||
/// Failed attempts in a row.
|
||||
pub attempts: u32,
|
||||
/// Unix seconds of the next attempt.
|
||||
pub next_attempt: i64,
|
||||
}
|
||||
|
||||
/// Where the failure is kept for the state directory `state_dir`.
|
||||
pub fn path(state_dir: &Path) -> PathBuf {
|
||||
state_dir.join(FILE_NAME)
|
||||
}
|
||||
|
||||
/// Record `failure`, replacing the one before it. Written to a temporary file
|
||||
/// and renamed, so a reader never sees half of it.
|
||||
pub fn record(state_dir: &Path, failure: &MountFailure) -> std::io::Result<()> {
|
||||
let json = serde_json::to_vec(failure).map_err(std::io::Error::other)?;
|
||||
let tmp = state_dir.join(format!("{FILE_NAME}.tmp"));
|
||||
std::fs::write(&tmp, json)?;
|
||||
std::fs::rename(&tmp, path(state_dir))
|
||||
}
|
||||
|
||||
/// Forget the failure: a mount is up, or a new daemon has started.
|
||||
pub fn clear(state_dir: &Path) {
|
||||
let _ = std::fs::remove_file(path(state_dir));
|
||||
}
|
||||
|
||||
/// The recorded failure, if there is one and it can be read.
|
||||
pub fn read(state_dir: &Path) -> Option<MountFailure> {
|
||||
let bytes = std::fs::read(path(state_dir)).ok()?;
|
||||
serde_json::from_slice(&bytes).ok()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn a_recorded_failure_reads_back_until_cleared() {
|
||||
let dir = std::env::temp_dir().join(format!("pdfs-mountfail-{}", std::process::id()));
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
assert_eq!(read(&dir), None);
|
||||
let failure = MountFailure {
|
||||
error: "fetch My Files root: missing key".into(),
|
||||
since: 1_700_000_000,
|
||||
attempts: 3,
|
||||
next_attempt: 1_700_000_040,
|
||||
};
|
||||
record(&dir, &failure).unwrap();
|
||||
assert_eq!(read(&dir), Some(failure));
|
||||
clear(&dir);
|
||||
assert_eq!(read(&dir), None);
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
}
|
||||
}
|
||||
@@ -989,9 +989,15 @@ impl Core {
|
||||
.db
|
||||
.sync_entries(id)
|
||||
.map_err(|e| SwitchBlocked::Failed(format!("db: {e:?}")))?;
|
||||
if let Some(reason) =
|
||||
sync::mirror_tree_unsynced(&local, &baseline, &self.ignore_rules(&local))
|
||||
{
|
||||
let rules = self.ignore_rules(&local);
|
||||
// Emptied before any pass saw it, the folder is still `idle`, and
|
||||
// the check below would refuse the switch for good. The push pass
|
||||
// of a queued switch forgets those paths instead (`docs/BUGS.md`
|
||||
// B255).
|
||||
if sync::mirror_tree_gone(&local, &baseline, &rules) {
|
||||
return Err(SwitchBlocked::NotNow);
|
||||
}
|
||||
if let Some(reason) = sync::mirror_tree_unsynced(&local, &baseline, &rules) {
|
||||
return Err(SwitchBlocked::Failed(format!(
|
||||
"going online-only would delete what is only on this computer: {reason}"
|
||||
)));
|
||||
|
||||
@@ -163,6 +163,7 @@ impl Core {
|
||||
control_handlers: super::control::active_handlers(),
|
||||
control_handler_limit: super::control::handler_limit(),
|
||||
pending_ops: self.pending_ops_quickly(),
|
||||
sync: Some(self.sync_engine.report()),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ use mount::{
|
||||
};
|
||||
use reads::{BlockFlight, BlockRing, PREFETCH_BUDGET, Prefetch, ReaderSlot, STREAM_BYPASS_MIN};
|
||||
use state::{Entry, Intervals, PendingRevision, State, StateGuard, WriteHandle};
|
||||
pub use systemd::idle_sleep;
|
||||
pub use systemd::{idle_sleep, status as notify_status};
|
||||
use tracing::{debug, error, info, warn};
|
||||
use transfers::{CountingWriter, JobGuard, OwnedCountingReader, TransferRegistry};
|
||||
use r#virtual::{
|
||||
@@ -728,6 +728,8 @@ struct Core {
|
||||
/// can say what a pass is doing rather than just "syncing". An entry exists
|
||||
/// only while that folder's reconcile pass is running.
|
||||
sync_progress: Arc<Mutex<HashMap<i64, SyncProgress>>>,
|
||||
/// Whether the folder-sync engine is alive, and which pass it is on.
|
||||
sync_engine: Arc<sync::EngineHealth>,
|
||||
/// Channel to the folder-sync engine: nudges it to
|
||||
/// reconcile a folder, reconcile everything, or re-scan its watch set.
|
||||
sync_tx: std::sync::mpsc::Sender<sync::SyncMsg>,
|
||||
@@ -5989,6 +5991,7 @@ impl Core {
|
||||
if let Some(p) = self.sync_progress.lock().get_mut(&folder_id) {
|
||||
f(p);
|
||||
}
|
||||
self.sync_engine.moved();
|
||||
}
|
||||
|
||||
/// Set the number of items the scan expects to check, from the size of the
|
||||
|
||||
@@ -507,6 +507,7 @@ pub(crate) fn mount_with(
|
||||
events: Arc::new(Default::default()),
|
||||
indexing: Arc::new(AtomicBool::new(false)),
|
||||
sync_progress: Arc::new(Mutex::new(HashMap::new())),
|
||||
sync_engine: Arc::default(),
|
||||
sync_tx,
|
||||
mounts: Arc::new(Mutex::new(SecondaryMountRegistry::default())),
|
||||
sync_locks: Arc::new(Mutex::new(HashMap::new())),
|
||||
@@ -540,12 +541,11 @@ pub(crate) fn mount_with(
|
||||
// and sweeps all operating on a mount that no longer exists (`docs/BUGS.md` B44).
|
||||
let mut workers: Vec<std::thread::JoinHandle<()>> = Vec::new();
|
||||
for worker in 0..DRAIN_WORKERS {
|
||||
let core = core.clone();
|
||||
workers.push(
|
||||
std::thread::Builder::new()
|
||||
.name(format!("pdfs-drain-{worker}"))
|
||||
.spawn(move || core.run_pending_drain(worker == 0))?,
|
||||
);
|
||||
let drain_core = core.clone();
|
||||
let spawned = std::thread::Builder::new()
|
||||
.name(format!("pdfs-drain-{worker}"))
|
||||
.spawn(move || drain_core.run_pending_drain(worker == 0));
|
||||
keep_or_abandon(&core, control_socket, &mut workers, spawned)?;
|
||||
}
|
||||
|
||||
// Start the folder-sync engine. It watches every mirror folder, polls the
|
||||
@@ -565,24 +565,22 @@ pub(crate) fn mount_with(
|
||||
info!("conflict sweep disabled by configuration");
|
||||
} else {
|
||||
info!(mode = ?sweep_mode, "conflict sweep enabled");
|
||||
let core = core.clone();
|
||||
workers.push(
|
||||
std::thread::Builder::new()
|
||||
.name("pdfs-conflict-sweep".into())
|
||||
.spawn(move || core.run_conflict_sweep_loop())?,
|
||||
);
|
||||
let sweep_core = core.clone();
|
||||
let spawned = std::thread::Builder::new()
|
||||
.name("pdfs-conflict-sweep".into())
|
||||
.spawn(move || sweep_core.run_conflict_sweep_loop());
|
||||
keep_or_abandon(&core, control_socket, &mut workers, spawned)?;
|
||||
}
|
||||
|
||||
// Watch the link for the life of the mount: a mount from the cache waits for
|
||||
// the network to come back, and an online one can lose it at any moment and
|
||||
// must notice it coming back just the same.
|
||||
{
|
||||
let core = core.clone();
|
||||
workers.push(
|
||||
std::thread::Builder::new()
|
||||
.name("pdfs-online-probe".into())
|
||||
.spawn(move || core.run_online_probe())?,
|
||||
);
|
||||
let probe_core = core.clone();
|
||||
let spawned = std::thread::Builder::new()
|
||||
.name("pdfs-online-probe".into())
|
||||
.spawn(move || probe_core.run_online_probe());
|
||||
keep_or_abandon(&core, control_socket, &mut workers, spawned)?;
|
||||
}
|
||||
|
||||
// Keep the launcher prompt's "This computer" index fresh. Its own thread:
|
||||
@@ -593,11 +591,10 @@ pub(crate) fn mount_with(
|
||||
let transfers = core.transfers.clone();
|
||||
let mountpoint = mountpoint.to_path_buf();
|
||||
let shutdown = core.shutdown.clone();
|
||||
workers.push(
|
||||
std::thread::Builder::new()
|
||||
.name("pdfs-localindex".into())
|
||||
.spawn(move || run_local_index(db, indexing, transfers, mountpoint, shutdown))?,
|
||||
);
|
||||
let spawned = std::thread::Builder::new()
|
||||
.name("pdfs-localindex".into())
|
||||
.spawn(move || run_local_index(db, indexing, transfers, mountpoint, shutdown));
|
||||
keep_or_abandon(&core, control_socket, &mut workers, spawned)?;
|
||||
}
|
||||
|
||||
// Bind the control socket before the FUSE session takes over the thread. A
|
||||
@@ -606,12 +603,18 @@ pub(crate) fn mount_with(
|
||||
let old_umask = unsafe { libc::umask(0o77) };
|
||||
let listener_res = UnixListener::bind(control_socket);
|
||||
unsafe { libc::umask(old_umask) };
|
||||
let listener = listener_res?;
|
||||
let listener = match listener_res {
|
||||
Ok(listener) => listener,
|
||||
Err(error) => {
|
||||
abandon_workers(&core, control_socket, workers);
|
||||
return Err(error);
|
||||
}
|
||||
};
|
||||
// Owner-only before anything can connect: a peer on this socket commands the
|
||||
// daemon's authenticated session without a credential of its own (B6).
|
||||
if let Err(e) = pdfs_core::config::restrict_socket(control_socket) {
|
||||
error!(error = %e, "cannot restrict control socket permissions; refusing to serve");
|
||||
let _ = std::fs::remove_file(control_socket);
|
||||
abandon_workers(&core, control_socket, workers);
|
||||
return Err(std::io::Error::other(format!(
|
||||
"control socket permissions: {e}"
|
||||
)));
|
||||
@@ -622,7 +625,7 @@ pub(crate) fn mount_with(
|
||||
let bg = match spawn_session(&core, mountpoint, root) {
|
||||
Ok(session) => session,
|
||||
Err(error) => {
|
||||
let _ = std::fs::remove_file(control_socket);
|
||||
abandon_workers(&core, control_socket, workers);
|
||||
return Err(error);
|
||||
}
|
||||
};
|
||||
@@ -642,7 +645,7 @@ pub(crate) fn mount_with(
|
||||
Err(error) => {
|
||||
// A failure here abandons the mount, so the background threads
|
||||
// started above have to be told to stop with it.
|
||||
stop_workers(&core, control_socket, workers);
|
||||
abandon_workers(&core, control_socket, workers);
|
||||
let secondaries = core.mounts.lock().close_and_drain();
|
||||
for (id, mount) in secondaries {
|
||||
if let Err(unmount_error) = mount.teardown() {
|
||||
@@ -692,8 +695,12 @@ pub(crate) fn mount_with(
|
||||
}
|
||||
}
|
||||
// The mount is live and the control socket answers: this is the moment the
|
||||
// unit is actually usable, which is what `Type=notify` reports.
|
||||
// unit is actually usable, which is what `Type=notify` reports. Whatever
|
||||
// failure an earlier attempt recorded for the front ends is over.
|
||||
systemd::ready();
|
||||
if let Some(state_dir) = control_socket.parent() {
|
||||
pdfs_core::mountfail::clear(state_dir);
|
||||
}
|
||||
|
||||
// Re-establish on-demand mounts only after the primary session is live.
|
||||
// Keep the worker so shutdown can close publication, wait for any in-flight
|
||||
@@ -859,6 +866,43 @@ fn stop_workers(core: &Core, control_socket: &Path, workers: Vec<std::thread::Jo
|
||||
// Say so before the joins: a teardown that takes a while must not be read as
|
||||
// a missed watchdog ping and turned into a kill.
|
||||
systemd::stopping();
|
||||
halt_workers(core, control_socket, workers);
|
||||
}
|
||||
|
||||
/// Stop the threads a mount attempt started before it failed.
|
||||
///
|
||||
/// The early returns used to leave them running: every retry started another
|
||||
/// set beside the last one's, and their `Core` kept the database open, so the
|
||||
/// next attempt could fail on its lock instead of the real error
|
||||
/// (`docs/BUGS.md` B264). Unlike [`stop_workers`] this does not tell systemd
|
||||
/// the daemon is stopping, because it is about to try again, and a manager
|
||||
/// told so would wait for the process to exit and then kill it.
|
||||
fn abandon_workers(core: &Core, control_socket: &Path, workers: Vec<std::thread::JoinHandle<()>>) {
|
||||
halt_workers(core, control_socket, workers);
|
||||
}
|
||||
|
||||
/// Keep a worker the mount just spawned, or, if the spawn failed, stop the
|
||||
/// ones already running and hand the error back.
|
||||
fn keep_or_abandon(
|
||||
core: &Core,
|
||||
control_socket: &Path,
|
||||
workers: &mut Vec<std::thread::JoinHandle<()>>,
|
||||
spawned: std::io::Result<std::thread::JoinHandle<()>>,
|
||||
) -> std::io::Result<()> {
|
||||
match spawned {
|
||||
Ok(handle) => {
|
||||
workers.push(handle);
|
||||
Ok(())
|
||||
}
|
||||
Err(error) => {
|
||||
abandon_workers(core, control_socket, std::mem::take(workers));
|
||||
Err(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Signal every worker to stop, then join them up to [`WORKER_JOIN_DEADLINE`].
|
||||
fn halt_workers(core: &Core, control_socket: &Path, workers: Vec<std::thread::JoinHandle<()>>) {
|
||||
core.shutdown.stop();
|
||||
core.wake_drain();
|
||||
let _ = core.sync_tx.send(sync::SyncMsg::Stop);
|
||||
|
||||
@@ -3002,4 +3002,69 @@ mod tests {
|
||||
assert!(matches!(daemon.stop(), Ok(MountOutcome::Shutdown)));
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
}
|
||||
|
||||
/// Emptied before any pass saw it, the folder is still `idle`, and the
|
||||
/// switch was refused for good: every path read as "deleted here but not on
|
||||
/// Proton Drive yet" (B255, found by the account run).
|
||||
#[test]
|
||||
#[ignore = "mounts FUSE: run with `cargo test -p pdfs-fuse sim:: -- --ignored`"]
|
||||
fn a_folder_emptied_before_any_pass_still_goes_on_demand() {
|
||||
let drive = FakeDrive::new();
|
||||
let dir = scratch("ondemand-emptied-idle");
|
||||
let daemon = Daemon::start(&dir, drive.client(1, Faults::lan())).unwrap();
|
||||
let local = dir.join("docs");
|
||||
let id = sync_folder(&daemon, &local, "mirror");
|
||||
std::fs::create_dir(local.join("sub")).unwrap();
|
||||
std::fs::write(local.join("sub/a.txt"), b"alpha").unwrap();
|
||||
std::fs::write(local.join("sub/b.txt"), b"beta").unwrap();
|
||||
daemon.request(&Request::SyncNow { id: Some(id) }).unwrap();
|
||||
let on_drive = |name: &str, content: &[u8]| {
|
||||
drive.tree().iter().any(|(path, entry)| {
|
||||
path.ends_with(name) && *entry == Entry::File(Arc::new(content.to_vec()))
|
||||
})
|
||||
};
|
||||
assert!(
|
||||
wait_until(Duration::from_secs(30), || on_drive("sub/a.txt", b"alpha")
|
||||
&& on_drive("sub/b.txt", b"beta")
|
||||
&& listed_folder(&daemon, id).is_some_and(|f| f.state == "idle")),
|
||||
"the folder synced: {:?}",
|
||||
listed_folder(&daemon, id)
|
||||
);
|
||||
|
||||
// In one rename, so no pass sees half of it, and asked at once, well
|
||||
// inside the watcher's debounce, so no pass sees it empty either.
|
||||
std::fs::rename(local.join("sub"), dir.join("moved-away")).unwrap();
|
||||
let asked = daemon.request(&Request::SetSyncFolderMode {
|
||||
id,
|
||||
mode: "ondemand".into(),
|
||||
});
|
||||
assert!(
|
||||
matches!(asked, Ok(Response::Ok { .. })),
|
||||
"the switch was refused: {asked:?}"
|
||||
);
|
||||
assert!(
|
||||
listed_folder(&daemon, id)
|
||||
.is_some_and(|f| f.pending_mode.as_deref() == Some("ondemand")),
|
||||
"the switch waits for a pass: {:?}",
|
||||
listed_folder(&daemon, id)
|
||||
);
|
||||
|
||||
assert!(
|
||||
wait_until(Duration::from_secs(30), || listed_folder(&daemon, id)
|
||||
.is_some_and(|f| f.mode == "ondemand" && f.pending_mode.is_none())
|
||||
&& is_mounted(&local)),
|
||||
"the queued switch landed: {:?}",
|
||||
listed_folder(&daemon, id)
|
||||
);
|
||||
assert_eq!(std::fs::read(local.join("sub/a.txt")).unwrap(), b"alpha");
|
||||
assert_eq!(std::fs::read(local.join("sub/b.txt")).unwrap(), b"beta");
|
||||
assert!(
|
||||
on_drive("sub/a.txt", b"alpha") && on_drive("sub/b.txt", b"beta"),
|
||||
"nothing was trashed on Drive: {:?}",
|
||||
drive.tree().keys().collect::<Vec<_>>()
|
||||
);
|
||||
|
||||
assert!(matches!(daemon.stop(), Ok(MountOutcome::Shutdown)));
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,11 @@ const TICK: Duration = Duration::from_secs(15);
|
||||
/// would train everyone to ignore the real one.
|
||||
const STALL_AFTER: Duration = Duration::from_secs(120);
|
||||
|
||||
/// How long a sync pass may go without reporting progress before it is called
|
||||
/// out. Much longer than [`STALL_AFTER`]: one large file in a pass reports
|
||||
/// nothing until its whole transfer is done.
|
||||
const SYNC_STALL_AFTER: Duration = Duration::from_secs(900);
|
||||
|
||||
/// How often resident size goes into the log.
|
||||
const RSS_EVERY: Duration = Duration::from_secs(300);
|
||||
|
||||
@@ -137,6 +142,26 @@ fn report_stalls(report: &pdfs_core::control::Diagnostics, last_completed: (u64,
|
||||
"the transfer lane has not completed a job since the last check"
|
||||
);
|
||||
}
|
||||
// The engine is one thread for every synced folder, so a dead or stuck one
|
||||
// stops all of them while the worker pool looks idle (B259).
|
||||
if let Some(sync) = &report.sync {
|
||||
if !sync.running {
|
||||
stalled = true;
|
||||
warn!(
|
||||
"the sync engine is not running; synced folders do not sync until the daemon restarts"
|
||||
);
|
||||
} else if let Some(folder) = sync.pass_folder
|
||||
&& sync.pass_idle_secs >= SYNC_STALL_AFTER.as_secs()
|
||||
{
|
||||
stalled = true;
|
||||
warn!(
|
||||
folder,
|
||||
age_secs = sync.pass_age_secs,
|
||||
idle_secs = sync.pass_idle_secs,
|
||||
"a sync pass has not reported progress for a long time"
|
||||
);
|
||||
}
|
||||
}
|
||||
stalled
|
||||
}
|
||||
|
||||
@@ -169,7 +194,7 @@ fn probe(control_socket: &Path) -> bool {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use pdfs_core::control::{Diagnostics, InflightRequest, WorkerState};
|
||||
use pdfs_core::control::{Diagnostics, InflightRequest, SyncEngineState, WorkerState};
|
||||
|
||||
fn busy_worker(age_secs: u64) -> WorkerState {
|
||||
WorkerState {
|
||||
@@ -226,4 +251,45 @@ mod tests {
|
||||
assert!(!report_stalls(&report, (0, 30)));
|
||||
assert!(report_stalls(&report, (0, 40)));
|
||||
}
|
||||
|
||||
fn with_sync(sync: SyncEngineState) -> Diagnostics {
|
||||
Diagnostics {
|
||||
sync: Some(sync),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// A sync engine that has ended stops every synced folder while the
|
||||
/// workers look idle, which is what issue #53 looked like (B259).
|
||||
#[test]
|
||||
fn a_stopped_sync_engine_is_a_stall() {
|
||||
assert!(report_stalls(
|
||||
&with_sync(SyncEngineState::default()),
|
||||
(0, 0)
|
||||
));
|
||||
}
|
||||
|
||||
/// A pass that keeps reporting progress is working, however long it runs;
|
||||
/// one that has gone quiet past the threshold is not.
|
||||
#[test]
|
||||
fn only_a_quiet_sync_pass_is_a_stall() {
|
||||
let busy = SyncEngineState {
|
||||
running: true,
|
||||
pass_folder: Some(3),
|
||||
pass_age_secs: SYNC_STALL_AFTER.as_secs() * 4,
|
||||
pass_idle_secs: 5,
|
||||
panics: 0,
|
||||
};
|
||||
assert!(!report_stalls(&with_sync(busy.clone()), (0, 0)));
|
||||
let quiet = SyncEngineState {
|
||||
pass_idle_secs: SYNC_STALL_AFTER.as_secs(),
|
||||
..busy
|
||||
};
|
||||
assert!(report_stalls(&with_sync(quiet), (0, 0)));
|
||||
let idle = SyncEngineState {
|
||||
running: true,
|
||||
..Default::default()
|
||||
};
|
||||
assert!(!report_stalls(&with_sync(idle), (0, 0)));
|
||||
}
|
||||
}
|
||||
@@ -49,7 +49,9 @@ mod local_scan;
|
||||
mod model;
|
||||
mod planner;
|
||||
pub(crate) use engine::SYNC_CONCURRENCY;
|
||||
pub(crate) use engine::{SyncMsg, spawn};
|
||||
pub(crate) use engine::{EngineHealth, SyncMsg, spawn};
|
||||
#[cfg(test)]
|
||||
use engine::{Running, burst_order, keep_wanted};
|
||||
#[cfg(test)]
|
||||
use engine::{classify, event_target, settle_with};
|
||||
#[cfg(test)]
|
||||
@@ -67,6 +69,11 @@ use planner::{
|
||||
plan_file, rel_to_path, remote_sig, remote_subtree_changed, revision_moved, tracked_baseline,
|
||||
unchanged_remote_size,
|
||||
};
|
||||
|
||||
/// A pass that took at least this long is logged at info even when it changed
|
||||
/// nothing, so the journal says where a slow engine spends its time.
|
||||
const SLOW_PASS: Duration = Duration::from_secs(30);
|
||||
|
||||
/// What a [`Pending`] op did, so the reconcile can update shared state on the
|
||||
/// engine thread (never inside a task).
|
||||
enum Applied {
|
||||
@@ -154,6 +161,14 @@ impl Core {
|
||||
// The cost is one small file read against a pass that is about to walk the
|
||||
// whole tree.
|
||||
let rules = self.ignore_rules(&local_root);
|
||||
// A first pass is the one a user waits on after adding or restoring a
|
||||
// folder, so it is said at info; the poll's passes stay at debug.
|
||||
if folder.last_sync == 0 {
|
||||
info!(id = folder.id, path = %folder.local_path, "sync: first pass starting");
|
||||
} else {
|
||||
debug!(id = folder.id, "sync: pass starting");
|
||||
}
|
||||
let started = Instant::now();
|
||||
self.progress_begin(folder.id);
|
||||
let result = if push_only {
|
||||
self.push_pass(folder.id, &local_root, &remote_root, &rules)
|
||||
@@ -195,6 +210,18 @@ impl Core {
|
||||
"idle"
|
||||
};
|
||||
let _ = self.db.sync_folder_set_state(folder.id, state, now_secs());
|
||||
let elapsed = started.elapsed();
|
||||
if folder.last_sync == 0 || !outcome.is_empty() || elapsed >= SLOW_PASS {
|
||||
info!(
|
||||
id = folder.id,
|
||||
state,
|
||||
elapsed_ms = elapsed.as_millis() as u64,
|
||||
summary = %outcome.summary(),
|
||||
"sync: pass finished"
|
||||
);
|
||||
} else {
|
||||
debug!(id = folder.id, state, "sync: pass finished");
|
||||
}
|
||||
self.report_unscanned(folder.id, name, &outcome.unscanned);
|
||||
// Summarise a pass that actually moved something. A poll over an
|
||||
// unchanged folder does nothing and says nothing — otherwise the
|
||||
@@ -2253,6 +2280,27 @@ pub(crate) fn mirror_tree_unsynced(
|
||||
.map(|r| format!("{r} was deleted here but not on Proton Drive yet"))
|
||||
}
|
||||
|
||||
/// Whether a mirror folder's local copy is gone in full: the folder is still
|
||||
/// there, but not one tracked path of its baseline is.
|
||||
///
|
||||
/// [`mirror_tree_unsynced`] reads that as deletions not carried up yet, which
|
||||
/// would refuse the switch to on-demand for good. It is the wipe guard's case
|
||||
/// instead, which the push pass a queued switch runs settles without trashing
|
||||
/// anything on Drive (#46), so the switch waits for that pass.
|
||||
pub(crate) fn mirror_tree_gone(
|
||||
root: &Path,
|
||||
baseline: &HashMap<String, StoredSyncEntry>,
|
||||
rules: &IgnoreRules,
|
||||
) -> bool {
|
||||
let tracked = filter_baseline(baseline, rules);
|
||||
root.is_dir()
|
||||
&& !tracked.is_empty()
|
||||
&& tracked.keys().all(|rel| {
|
||||
std::fs::symlink_metadata(root.join(rel_to_path(rel)))
|
||||
.is_err_and(|e| e.kind() == std::io::ErrorKind::NotFound)
|
||||
})
|
||||
}
|
||||
|
||||
/// The walk behind both checks. `rules`, when given, only names an ignored
|
||||
/// path as such in the reason; it is still something only this disk has.
|
||||
fn unsynced_local(
|
||||
@@ -2417,6 +2465,72 @@ fn system_mtime_ns(meta: &std::fs::Metadata) -> Option<i64> {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
/// A panic in a pass ends that pass and is counted; the engine is not
|
||||
/// left believing the pass still runs (`docs/BUGS.md` B259).
|
||||
#[test]
|
||||
fn a_panicking_pass_is_contained_and_counted() {
|
||||
let health = EngineHealth::default();
|
||||
assert!(!health.contain(7, || panic!("a pass that panics")));
|
||||
let report = health.report();
|
||||
assert_eq!(report.panics, 1);
|
||||
assert_eq!(report.pass_folder, None);
|
||||
assert!(health.contain(7, || {}));
|
||||
assert_eq!(health.report().panics, 1);
|
||||
}
|
||||
|
||||
/// Folders named by id run before the rest of a `ReconcileAll` in the
|
||||
/// same burst, so a folder just added does not wait behind a pass over
|
||||
/// every other folder (`docs/BUGS.md` B260).
|
||||
#[test]
|
||||
fn named_folders_run_before_the_rest_of_a_burst() {
|
||||
let ids: HashSet<i64> = [9, 4].into();
|
||||
assert_eq!(burst_order(&ids, &[1, 4, 6, 9]), [4, 9, 1, 6]);
|
||||
assert_eq!(burst_order(&HashSet::new(), &[1, 4]), [1, 4]);
|
||||
// A folder the list no longer has still gets the pass it asked for.
|
||||
assert_eq!(burst_order(&[12].into(), &[1]), [12, 1]);
|
||||
}
|
||||
|
||||
/// A folder removed and added again keeps its watch under the new id;
|
||||
/// a folder that is gone loses its watch (`docs/BUGS.md` B272).
|
||||
#[test]
|
||||
fn a_re_added_folder_keeps_its_watch_under_the_new_id() {
|
||||
let mut have = vec![(PathBuf::from("/a"), 1), (PathBuf::from("/b"), 2)];
|
||||
let dropped = keep_wanted(&mut have, &[(PathBuf::from("/a"), 7)]);
|
||||
assert_eq!(have, [(PathBuf::from("/a"), 7)]);
|
||||
assert_eq!(dropped, [PathBuf::from("/b")]);
|
||||
}
|
||||
|
||||
/// While a pass runs, the report names its folder, which is what tells a
|
||||
/// long pass apart from an idle engine.
|
||||
#[test]
|
||||
fn the_running_pass_is_reported() {
|
||||
let health = EngineHealth::default();
|
||||
let mut seen = None;
|
||||
health.contain(7, || seen = health.report().pass_folder);
|
||||
assert_eq!(seen, Some(7));
|
||||
}
|
||||
|
||||
/// The engine reads as running only while its thread lives, including
|
||||
/// when the thread ends in a panic.
|
||||
#[test]
|
||||
fn the_engine_reads_as_stopped_once_its_thread_ends() {
|
||||
let health = Arc::new(EngineHealth::default());
|
||||
let thread_health = health.clone();
|
||||
let (started_tx, started_rx) = std::sync::mpsc::channel();
|
||||
let (end_tx, end_rx) = std::sync::mpsc::channel::<()>();
|
||||
let thread = std::thread::spawn(move || {
|
||||
let _running = Running::start(&thread_health);
|
||||
started_tx.send(()).unwrap();
|
||||
let _ = end_rx.recv();
|
||||
panic!("the engine thread panics");
|
||||
});
|
||||
started_rx.recv().unwrap();
|
||||
assert!(health.report().running);
|
||||
end_tx.send(()).unwrap();
|
||||
assert!(thread.join().is_err());
|
||||
assert!(!health.report().running);
|
||||
}
|
||||
|
||||
/// A removal of something already gone has produced the state the sync
|
||||
/// engine wanted, so its baseline is dropped rather than retried forever.
|
||||
/// Anything else stays an error and keeps the baseline (`docs/BUGS.md` B42).
|
||||
@@ -3538,6 +3652,26 @@ mod tests {
|
||||
assert!(reason.unwrap().contains("link"));
|
||||
}
|
||||
|
||||
/// Emptied before any pass saw it, the folder waits for the push pass that
|
||||
/// forgets those paths, instead of being refused for good (B255).
|
||||
#[test]
|
||||
fn only_a_local_copy_gone_in_full_counts_as_gone() {
|
||||
let (root, baseline) = synced_subtree("evict-gone");
|
||||
let rules = rules_for(&[]);
|
||||
let whole = mirror_tree_gone(&root, &baseline, &rules);
|
||||
std::fs::remove_dir_all(root.join("dir/sub")).unwrap();
|
||||
let partly = mirror_tree_gone(&root, &baseline, &rules);
|
||||
std::fs::remove_dir_all(root.join("dir")).unwrap();
|
||||
let emptied = mirror_tree_gone(&root, &baseline, &rules);
|
||||
let none_synced = mirror_tree_gone(&root, &HashMap::new(), &rules);
|
||||
std::fs::remove_dir_all(&root).unwrap();
|
||||
let no_root = mirror_tree_gone(&root, &baseline, &rules);
|
||||
assert!(!whole && !partly, "a deletion with survivors is a real one");
|
||||
assert!(emptied);
|
||||
assert!(!none_synced, "an empty baseline has nothing to lose");
|
||||
assert!(!no_root, "a missing folder is the pass's error to report");
|
||||
}
|
||||
|
||||
/// The same rule one level up: if the sync root itself cannot be read, the
|
||||
/// pass sees nothing, and "nothing" must never mean "delete everything".
|
||||
#[test]
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
//! Filesystem watcher, polling, and debounce control plane.
|
||||
|
||||
use std::panic::AssertUnwindSafe;
|
||||
use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
|
||||
|
||||
use pdfs_core::control::SyncEngineState;
|
||||
use tracing::error;
|
||||
|
||||
use super::*;
|
||||
|
||||
/// How long the watcher must go quiet before a burst counts as finished.
|
||||
@@ -23,6 +29,9 @@ const POLL_INTERVAL: Duration = Duration::from_secs(120);
|
||||
/// unusable done one-at-a-time; this bounds concurrency like the bulk-upload
|
||||
/// engine does.
|
||||
pub(crate) const SYNC_CONCURRENCY: usize = 8;
|
||||
/// How long after a failed watch the engine tries the watches again. Each try
|
||||
/// walks the folder's whole tree, so not on every burst.
|
||||
const REWATCH_RETRY: Duration = Duration::from_secs(600);
|
||||
|
||||
/// A message to the sync engine's control thread.
|
||||
pub(crate) enum SyncMsg {
|
||||
@@ -53,32 +62,159 @@ pub(crate) fn spawn(core: Core, rx: Receiver<SyncMsg>) -> Option<std::thread::Jo
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether the engine is alive and which pass it is on, for
|
||||
/// [`Core::diagnostics`] and the supervisor.
|
||||
///
|
||||
/// A panic in a pass used to end the engine thread. Every later add, sync-now,
|
||||
/// file event and poll then went into a channel nobody read, the folder stayed
|
||||
/// `syncing`, and nothing said so until a restart (`docs/BUGS.md` B259).
|
||||
#[derive(Default)]
|
||||
pub(crate) struct EngineHealth {
|
||||
running: AtomicBool,
|
||||
pass: Mutex<Option<PassClock>>,
|
||||
panics: AtomicU64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct PassClock {
|
||||
folder: i64,
|
||||
started: Instant,
|
||||
moved: Instant,
|
||||
}
|
||||
|
||||
impl EngineHealth {
|
||||
/// Note that the running pass reported progress.
|
||||
pub(crate) fn moved(&self) {
|
||||
if let Some(pass) = self.pass.lock().as_mut() {
|
||||
pass.moved = Instant::now();
|
||||
}
|
||||
}
|
||||
|
||||
/// The engine's state now. `try_lock`, like the rest of the diagnostics:
|
||||
/// a report must not wait on the thing it reports about.
|
||||
pub(crate) fn report(&self) -> SyncEngineState {
|
||||
let pass = self.pass.try_lock().and_then(|pass| *pass);
|
||||
SyncEngineState {
|
||||
running: self.running.load(Ordering::Relaxed),
|
||||
pass_folder: pass.map(|p| p.folder),
|
||||
pass_age_secs: pass.map_or(0, |p| p.started.elapsed().as_secs()),
|
||||
pass_idle_secs: pass.map_or(0, |p| p.moved.elapsed().as_secs()),
|
||||
panics: self.panics.load(Ordering::Relaxed),
|
||||
}
|
||||
}
|
||||
|
||||
/// Run `pass` over `folder` as the current pass. Returns `false` when it
|
||||
/// panicked: the panic ends that pass, not the engine.
|
||||
pub(super) fn contain(&self, folder: i64, pass: impl FnOnce()) -> bool {
|
||||
let now = Instant::now();
|
||||
*self.pass.lock() = Some(PassClock {
|
||||
folder,
|
||||
started: now,
|
||||
moved: now,
|
||||
});
|
||||
let finished = std::panic::catch_unwind(AssertUnwindSafe(pass)).is_ok();
|
||||
*self.pass.lock() = None;
|
||||
if !finished {
|
||||
self.panics.fetch_add(1, Ordering::Relaxed);
|
||||
}
|
||||
finished
|
||||
}
|
||||
}
|
||||
|
||||
/// Marks the engine running for as long as it lives.
|
||||
pub(super) struct Running<'a>(&'a EngineHealth);
|
||||
|
||||
impl<'a> Running<'a> {
|
||||
pub(super) fn start(health: &'a EngineHealth) -> Self {
|
||||
health.running.store(true, Ordering::Relaxed);
|
||||
Self(health)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Running<'_> {
|
||||
fn drop(&mut self) {
|
||||
self.0.running.store(false, Ordering::Relaxed);
|
||||
if std::thread::panicking() {
|
||||
error!("sync engine stopped by a panic; nothing syncs until the daemon restarts");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// One folder's pass, contained: a panic in it sets the folder to `error` and
|
||||
/// leaves the engine running for the next one.
|
||||
fn run_pass(core: &Core, folder: &StoredSyncFolder) {
|
||||
if core
|
||||
.sync_engine
|
||||
.contain(folder.id, || core.reconcile_folder(folder))
|
||||
{
|
||||
return;
|
||||
}
|
||||
core.progress_end(folder.id);
|
||||
let _ = core
|
||||
.db
|
||||
.sync_folder_set_state(folder.id, "error", folder.last_sync);
|
||||
error!(
|
||||
id = folder.id,
|
||||
path = %folder.local_path,
|
||||
"sync: pass panicked; the folder is set to error and tried again on the next poll"
|
||||
);
|
||||
core.log_activity(
|
||||
ActivityKind::Sync,
|
||||
format!("sync failed for {}", base_name(&folder.local_path)),
|
||||
"an internal error stopped the pass; it is tried again on the next poll",
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
/// The pass a `Reconcile(id)` asked for. A folder removed since, or one the
|
||||
/// database cannot read, is said so rather than dropped in silence.
|
||||
fn run_pass_by_id(core: &Core, id: i64) {
|
||||
match core.db.sync_folder_get(id) {
|
||||
Ok(Some(folder)) => run_pass(core, &folder),
|
||||
Ok(None) => debug!(id, "sync: folder removed before its pass; skipping"),
|
||||
Err(e) => warn!(id, error = ?e, "sync: cannot read folder; skipping its pass"),
|
||||
}
|
||||
}
|
||||
|
||||
/// The engine control loop. Single-threaded so reconcile passes never overlap.
|
||||
fn engine_loop(core: Core, rx: Receiver<SyncMsg>) {
|
||||
let health = core.sync_engine.clone();
|
||||
let _running = Running::start(&health);
|
||||
// Paths the watcher currently covers, mapped to their folder id, so an event
|
||||
// path can be resolved back to the folder it belongs to.
|
||||
let watched: Arc<Mutex<Vec<(PathBuf, i64)>>> = Arc::new(Mutex::new(Vec::new()));
|
||||
|
||||
let tx_events = core.sync_tx.clone();
|
||||
let watched_events = watched.clone();
|
||||
let mut watcher =
|
||||
match notify::recommended_watcher(move |res: notify::Result<notify::Event>| {
|
||||
let Ok(event) = res else { return };
|
||||
// Ignore pure metadata/access noise; content changes are what matter.
|
||||
if matches!(event.kind, notify::EventKind::Access(_)) {
|
||||
return;
|
||||
}
|
||||
let msg = event_target(&watched_events.lock(), &event.paths);
|
||||
let _ = tx_events.send(msg);
|
||||
}) {
|
||||
Ok(w) => w,
|
||||
let handler = move |res: notify::Result<notify::Event>| {
|
||||
let event = match res {
|
||||
Ok(event) => event,
|
||||
// Running out of inotify watches for a new subfolder, say: that
|
||||
// subfolder's changes are then found by the poll only (B262).
|
||||
Err(e) => {
|
||||
warn!(error = %e, "filesystem watcher unavailable; sync is poll-only");
|
||||
// Still run the loop so polling and explicit SyncNow work.
|
||||
poll_only_loop(&core, rx);
|
||||
warn!(error = %e, "sync: filesystem watcher error");
|
||||
return;
|
||||
}
|
||||
};
|
||||
// Ignore pure metadata/access noise; content changes are what matter.
|
||||
if matches!(event.kind, notify::EventKind::Access(_)) {
|
||||
return;
|
||||
}
|
||||
let msg = event_target(&watched_events.lock(), &event.paths);
|
||||
let _ = tx_events.send(msg);
|
||||
};
|
||||
// The local walk skips symlinks, so following them here would only watch
|
||||
// trees outside the folder, and run passes over it for changes made there.
|
||||
let config = notify::Config::default().with_follow_symlinks(false);
|
||||
let mut watcher = match notify::RecommendedWatcher::new(handler, config) {
|
||||
Ok(w) => w,
|
||||
Err(e) => {
|
||||
warn!(error = %e, "filesystem watcher unavailable; sync is poll-only");
|
||||
// Still run the loop so polling and explicit SyncNow work.
|
||||
poll_only_loop(&core, rx);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
// Periodic remote poll.
|
||||
{
|
||||
@@ -96,8 +232,9 @@ fn engine_loop(core: Core, rx: Receiver<SyncMsg>) {
|
||||
.ok();
|
||||
}
|
||||
|
||||
rewatch(&core, &mut watcher, &watched);
|
||||
reconcile_all(&core);
|
||||
let mut unwatched = rewatch(&core, &mut watcher, &watched);
|
||||
let mut last_rewatch = Instant::now();
|
||||
run_burst(&core, &HashSet::new(), true);
|
||||
|
||||
while let Ok(msg) = rx.recv() {
|
||||
let mut ids: HashSet<i64> = HashSet::new();
|
||||
@@ -110,21 +247,16 @@ fn engine_loop(core: Core, rx: Receiver<SyncMsg>) {
|
||||
return;
|
||||
}
|
||||
|
||||
// A folder whose watch failed is tried again now and then, not only
|
||||
// when the folder set changes.
|
||||
if unwatched && last_rewatch.elapsed() >= REWATCH_RETRY {
|
||||
do_rewatch = true;
|
||||
}
|
||||
if do_rewatch {
|
||||
rewatch(&core, &mut watcher, &watched);
|
||||
}
|
||||
if all {
|
||||
reconcile_all(&core);
|
||||
} else {
|
||||
for id in ids {
|
||||
if core.sync_paused() {
|
||||
break;
|
||||
}
|
||||
if let Ok(Some(folder)) = core.db.sync_folder_get(id) {
|
||||
core.reconcile_folder(&folder);
|
||||
}
|
||||
}
|
||||
unwatched = rewatch(&core, &mut watcher, &watched);
|
||||
last_rewatch = Instant::now();
|
||||
}
|
||||
run_burst(&core, &ids, all);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +273,7 @@ fn poll_only_loop(core: &Core, rx: Receiver<SyncMsg>) {
|
||||
}
|
||||
});
|
||||
}
|
||||
reconcile_all(core);
|
||||
run_burst(core, &HashSet::new(), true);
|
||||
while let Ok(msg) = rx.recv() {
|
||||
let mut ids: HashSet<i64> = HashSet::new();
|
||||
let mut all = false;
|
||||
@@ -152,21 +284,59 @@ fn poll_only_loop(core: &Core, rx: Receiver<SyncMsg>) {
|
||||
info!("sync engine stopping");
|
||||
return;
|
||||
}
|
||||
if all {
|
||||
reconcile_all(core);
|
||||
} else {
|
||||
for id in ids {
|
||||
if core.sync_paused() {
|
||||
break;
|
||||
}
|
||||
if let Ok(Some(folder)) = core.db.sync_folder_get(id) {
|
||||
core.reconcile_folder(&folder);
|
||||
}
|
||||
run_burst(core, &ids, all);
|
||||
}
|
||||
}
|
||||
|
||||
/// Run the passes one burst asked for: the folders named by id, then, when the
|
||||
/// burst also holds a `ReconcileAll`, every other folder.
|
||||
///
|
||||
/// The named folders go first. A poll's `ReconcileAll` in the same burst used
|
||||
/// to take their place, and a folder just added, which has the highest id,
|
||||
/// waited behind a full pass over every other folder (`docs/BUGS.md` B260).
|
||||
///
|
||||
/// Skipped while sync is paused, and cut short when a pause lands between
|
||||
/// passes: the resume sends a fresh [`SyncMsg::ReconcileAll`], which walks
|
||||
/// everything the watcher reported meanwhile.
|
||||
fn run_burst(core: &Core, ids: &HashSet<i64>, all: bool) {
|
||||
if core.sync_paused() {
|
||||
debug!("sync: paused, skipping reconcile");
|
||||
return;
|
||||
}
|
||||
let folders = if all {
|
||||
match core.db.sync_folder_list() {
|
||||
Ok(folders) => folders,
|
||||
Err(e) => {
|
||||
warn!(error = ?e, "sync: cannot list folders");
|
||||
Vec::new()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
let listed: Vec<i64> = folders.iter().map(|f| f.id).collect();
|
||||
for id in burst_order(ids, &listed) {
|
||||
if core.sync_paused() {
|
||||
break;
|
||||
}
|
||||
// A folder named by id is read again: it may have been added or
|
||||
// changed after the list was read.
|
||||
match folders.iter().find(|f| f.id == id) {
|
||||
Some(folder) if !ids.contains(&id) => run_pass(core, folder),
|
||||
_ => run_pass_by_id(core, id),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The order of a burst's passes: the folders named by id, lowest first, then
|
||||
/// the rest of `listed` in its own order.
|
||||
pub(super) fn burst_order(ids: &HashSet<i64>, listed: &[i64]) -> Vec<i64> {
|
||||
let mut order: Vec<i64> = ids.iter().copied().collect();
|
||||
order.sort_unstable();
|
||||
order.extend(listed.iter().copied().filter(|id| !ids.contains(id)));
|
||||
order
|
||||
}
|
||||
|
||||
/// Absorb the rest of an event burst, returning once the watcher has been quiet
|
||||
/// for `quiet` or `cap` has elapsed since the first event — whichever comes
|
||||
/// first. The caller has already classified the event that opened the burst.
|
||||
@@ -238,26 +408,6 @@ pub(super) fn classify(
|
||||
true
|
||||
}
|
||||
|
||||
/// Reconcile every mirror folder in turn. Skipped while sync is paused: the
|
||||
/// resume sends a fresh [`SyncMsg::ReconcileAll`], which walks everything the
|
||||
/// watcher reported meanwhile.
|
||||
fn reconcile_all(core: &Core) {
|
||||
if core.sync_paused() {
|
||||
debug!("sync: paused, skipping reconcile");
|
||||
return;
|
||||
}
|
||||
let folders = match core.db.sync_folder_list() {
|
||||
Ok(f) => f,
|
||||
Err(e) => {
|
||||
warn!(error = ?e, "sync: cannot list folders");
|
||||
return;
|
||||
}
|
||||
};
|
||||
for folder in folders {
|
||||
core.reconcile_folder(&folder);
|
||||
}
|
||||
}
|
||||
|
||||
/// The reconcile a watcher event asks for: the one mirror folder all its paths
|
||||
/// lie in, so an edit in one folder does not walk every other one too. An event
|
||||
/// that spans folders, or that no watched folder claims (a watch list a moment
|
||||
@@ -278,7 +428,8 @@ pub(super) fn event_target(watched: &[(PathBuf, i64)], paths: &[PathBuf]) -> Syn
|
||||
}
|
||||
|
||||
/// Bring the filesystem watches in line with the current mirror-folder set:
|
||||
/// watch newly-added folders, drop removed ones.
|
||||
/// watch newly-added folders, drop removed ones. Returns whether a folder is
|
||||
/// left unwatched because its watch failed.
|
||||
///
|
||||
/// The watch calls run on a copy, outside the lock: the watcher's event
|
||||
/// callback takes the same lock, and a backend that hands a watch request to
|
||||
@@ -287,7 +438,7 @@ fn rewatch(
|
||||
core: &Core,
|
||||
watcher: &mut notify::RecommendedWatcher,
|
||||
watched: &Mutex<Vec<(PathBuf, i64)>>,
|
||||
) {
|
||||
) -> bool {
|
||||
let want: Vec<(PathBuf, i64)> = match core.db.sync_folder_list() {
|
||||
Ok(f) => f
|
||||
.into_iter()
|
||||
@@ -296,30 +447,60 @@ fn rewatch(
|
||||
.collect(),
|
||||
Err(e) => {
|
||||
warn!(error = ?e, "sync: cannot list folders to watch");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
let mut have = watched.lock().clone();
|
||||
// Drop watches no longer wanted.
|
||||
have.retain(|(path, _)| {
|
||||
if want.iter().any(|(p, _)| p == path) {
|
||||
true
|
||||
} else {
|
||||
let _ = watcher.unwatch(path);
|
||||
false
|
||||
}
|
||||
});
|
||||
for path in keep_wanted(&mut have, &want) {
|
||||
let _ = watcher.unwatch(&path);
|
||||
}
|
||||
// Add newly wanted watches.
|
||||
let mut failed = false;
|
||||
for (path, id) in &want {
|
||||
if have.iter().any(|(p, _)| p == path) {
|
||||
continue;
|
||||
}
|
||||
match watcher.watch(path, RecursiveMode::Recursive) {
|
||||
Ok(()) => have.push((path.clone(), *id)),
|
||||
Err(e) => warn!(path = %path.display(), error = %e, "sync: watch failed"),
|
||||
Err(e) => {
|
||||
// A recursive watch that fails partway keeps the watches it had
|
||||
// added. Their events would match no folder and run a pass over
|
||||
// every one, and they hold watches the next folder needs (B262).
|
||||
let _ = watcher.unwatch(path);
|
||||
failed = true;
|
||||
warn!(
|
||||
path = %path.display(),
|
||||
error = %e,
|
||||
"sync: watch failed; the poll finds this folder's changes until a retry \
|
||||
works. A low fs.inotify.max_user_watches is the usual cause"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
*watched.lock() = have;
|
||||
failed
|
||||
}
|
||||
|
||||
/// Keep the watches in `have` that `want` still asks for, and return the paths
|
||||
/// of the others, to unwatch.
|
||||
///
|
||||
/// A path is matched alone, but takes the id `want` gives it: a folder removed
|
||||
/// and added again in one burst keeps its watch, and its events go to the new
|
||||
/// row rather than to the removed one (`docs/BUGS.md` B272).
|
||||
pub(super) fn keep_wanted(have: &mut Vec<(PathBuf, i64)>, want: &[(PathBuf, i64)]) -> Vec<PathBuf> {
|
||||
let mut dropped = Vec::new();
|
||||
have.retain_mut(|(path, id)| match want.iter().find(|(p, _)| p == path) {
|
||||
Some((_, wanted)) => {
|
||||
*id = *wanted;
|
||||
true
|
||||
}
|
||||
None => {
|
||||
dropped.push(path.clone());
|
||||
false
|
||||
}
|
||||
});
|
||||
dropped
|
||||
}
|
||||
|
||||
// ---- reconcile ------------------------------------------------------------
|
||||
@@ -64,11 +64,19 @@ fn send_abstract(socket: &UnixDatagram, name: &str, message: &str) -> bool {
|
||||
/// so `systemctl --user start` returns when the mount actually works rather than
|
||||
/// when the process exists.
|
||||
pub(crate) fn ready() {
|
||||
if notify("READY=1\n") {
|
||||
if notify("READY=1\nSTATUS=Mounted\n") {
|
||||
debug!("notified systemd: ready");
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the one-line status `systemctl --user status` shows for the unit, such
|
||||
/// as why the mount keeps failing (`docs/BUGS.md` B263).
|
||||
pub fn status(text: &str) {
|
||||
// A newline would end the `STATUS=` line and start another variable.
|
||||
let line = text.replace('\n', " ");
|
||||
notify(&format!("STATUS={line}\n"));
|
||||
}
|
||||
|
||||
/// Tell the manager the daemon is still healthy.
|
||||
pub(crate) fn watchdog_ping() {
|
||||
let _ = notify("WATCHDOG=1\n");
|
||||
|
||||
@@ -1797,13 +1797,35 @@ pub(crate) fn service_unreachable(
|
||||
);
|
||||
return;
|
||||
}
|
||||
status(
|
||||
&ui,
|
||||
"network-idle-symbolic",
|
||||
&gettext("Connecting…"),
|
||||
&gettext("Waiting for the Proton Drive service to start."),
|
||||
false,
|
||||
);
|
||||
// Running but not answering may be a mount that fails on every try,
|
||||
// which never opens the socket. Its reason is in a file the daemon
|
||||
// keeps for this (B263); "Connecting…" alone looked like a slow start
|
||||
// for as long as it lasted.
|
||||
let state_dir = ui.dirs.state_dir();
|
||||
let failure = gio::spawn_blocking(move || pdfs_core::mountfail::read(&state_dir))
|
||||
.await
|
||||
.ok()
|
||||
.flatten();
|
||||
match failure {
|
||||
Some(failure) => status(
|
||||
&ui,
|
||||
"dialog-warning-symbolic",
|
||||
&gettext("Can't open your Drive"),
|
||||
// Translators: {error} is an error message, in English.
|
||||
&gettext_f(
|
||||
"The Proton Drive service keeps failing to start and tries again on its own. The last error was: {error}",
|
||||
&[("error", &failure.error)],
|
||||
),
|
||||
true,
|
||||
),
|
||||
None => status(
|
||||
&ui,
|
||||
"network-idle-symbolic",
|
||||
&gettext("Connecting…"),
|
||||
&gettext("Waiting for the Proton Drive service to start."),
|
||||
false,
|
||||
),
|
||||
}
|
||||
glib::timeout_add_local_once(CONNECT_RETRY_INTERVAL, move || {
|
||||
if ui.stack.visible_child_name().as_deref() == Some(page) {
|
||||
reload(&ui);
|
||||
|
||||
@@ -597,6 +597,19 @@ pub(crate) fn this_computer_subtitle(folders: &[SyncFolderInfo]) -> String {
|
||||
folders.len() as u64,
|
||||
&[],
|
||||
);
|
||||
// A folder whose first pass has not run is not backed up yet, whatever its
|
||||
// state column says (`docs/BUGS.md` B261).
|
||||
let waiting = folders.iter().filter(|f| never_synced(f)).count();
|
||||
let count = match waiting {
|
||||
0 => count,
|
||||
// Translators: {folders} is "N folders backed up"; {n} counts the folders whose first sync has not run yet.
|
||||
n => ngettext_f(
|
||||
"{folders} · {n} waiting for its first sync",
|
||||
"{folders} · {n} waiting for their first sync",
|
||||
n as u64,
|
||||
&[("folders", &count)],
|
||||
),
|
||||
};
|
||||
let attention = folders
|
||||
.iter()
|
||||
.filter(|f| f.state == "error" || f.state == "conflict")
|
||||
@@ -613,12 +626,21 @@ pub(crate) fn this_computer_subtitle(folders: &[SyncFolderInfo]) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
/// Human label for a synced folder's `state` column.
|
||||
pub(crate) fn sync_state_label(state: &str) -> String {
|
||||
/// Whether a synced folder is a mirror whose first pass has not finished.
|
||||
/// Its `state` starts out `idle`, which would read as "up to date".
|
||||
fn never_synced(folder: &SyncFolderInfo) -> bool {
|
||||
folder.mode == "mirror" && folder.last_sync == 0 && folder.state == "idle"
|
||||
}
|
||||
|
||||
/// Human label for a synced folder's `state` column. `never_synced` is a
|
||||
/// mirror folder whose first pass has not finished: its `state` starts out
|
||||
/// `idle`, and "up to date" would say the opposite of the truth (B261).
|
||||
pub(crate) fn sync_state_label(state: &str, never_synced: bool) -> String {
|
||||
match state {
|
||||
"syncing" => gettext("syncing…"),
|
||||
"error" => gettext("sync error"),
|
||||
"conflict" => gettext("needs attention"),
|
||||
_ if never_synced => gettext("waiting for first sync"),
|
||||
_ => gettext("up to date"),
|
||||
}
|
||||
}
|
||||
@@ -1274,7 +1296,7 @@ mod tests {
|
||||
remote_uid: "vol~link".into(),
|
||||
mode: "mirror".into(),
|
||||
state: state.into(),
|
||||
last_sync: 0,
|
||||
last_sync: 1_700_000_000,
|
||||
pending_mode: None,
|
||||
progress: None,
|
||||
paused: false,
|
||||
@@ -1286,6 +1308,33 @@ mod tests {
|
||||
assert_eq!(this_computer_subtitle(&[]), "No folders backed up yet");
|
||||
}
|
||||
|
||||
/// A folder added a moment ago is not backed up yet, and the row must not
|
||||
/// say it is (`docs/BUGS.md` B261). An on-demand folder has no first sync.
|
||||
#[test]
|
||||
fn a_folder_before_its_first_sync_is_not_counted_as_backed_up() {
|
||||
let new = SyncFolderInfo {
|
||||
last_sync: 0,
|
||||
..folder("idle")
|
||||
};
|
||||
assert_eq!(
|
||||
this_computer_subtitle(&[folder("idle"), new.clone()]),
|
||||
"2 folders backed up · 1 waiting for its first sync"
|
||||
);
|
||||
let failed = SyncFolderInfo {
|
||||
state: "error".into(),
|
||||
..new.clone()
|
||||
};
|
||||
assert_eq!(
|
||||
this_computer_subtitle(&[new.clone(), failed]),
|
||||
"2 folders backed up · 1 waiting for its first sync · 1 needs attention"
|
||||
);
|
||||
let on_demand = SyncFolderInfo {
|
||||
mode: "ondemand".into(),
|
||||
..new
|
||||
};
|
||||
assert_eq!(this_computer_subtitle(&[on_demand]), "1 folder backed up");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn folders_needing_attention_are_counted_not_hidden() {
|
||||
// The per-folder rows live on the Sync page, so this row is the only
|
||||
|
||||
@@ -1729,7 +1729,10 @@ pub(crate) fn location_subtitle(spec: &MountSpec) -> String {
|
||||
parts.push(match &spec.progress {
|
||||
Some(p) => sync_progress_label(p),
|
||||
None if spec.paused => pgettext("state", "paused"),
|
||||
None => sync_state_label(&spec.state).to_string(),
|
||||
None => sync_state_label(
|
||||
&spec.state,
|
||||
spec.mode == MountMode::Mirror && spec.last_sync == 0,
|
||||
),
|
||||
});
|
||||
}
|
||||
// Only the locations that are supposed to have a session report its absence:
|
||||
@@ -1775,7 +1778,25 @@ mod tests {
|
||||
MountMode::Mirror,
|
||||
false,
|
||||
);
|
||||
assert_eq!(location_subtitle(&spec), "Synced · waiting for first sync");
|
||||
}
|
||||
|
||||
/// A folder whose first pass has not run is not up to date, though its
|
||||
/// state column starts out `idle` (`docs/BUGS.md` B261).
|
||||
#[test]
|
||||
fn a_folder_reads_up_to_date_only_after_its_first_sync() {
|
||||
let mut spec = spec(
|
||||
MountKind::Device { sync_folder_id: 7 },
|
||||
MountMode::Mirror,
|
||||
false,
|
||||
);
|
||||
assert_eq!(location_subtitle(&spec), "Synced · waiting for first sync");
|
||||
spec.last_sync = 1_700_000_000;
|
||||
assert_eq!(location_subtitle(&spec), "Synced · up to date");
|
||||
// A folder that failed before it ever synced says so.
|
||||
spec.last_sync = 0;
|
||||
spec.state = "error".into();
|
||||
assert_eq!(location_subtitle(&spec), "Synced · sync error");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -194,6 +194,24 @@ fn poll_state(socket: &Path, default_mountpoint: &Path) -> DriveState {
|
||||
),
|
||||
Phase::Attention,
|
||||
),
|
||||
// A daemon whose mount fails on every try never opens the
|
||||
// socket; the app says why (B263).
|
||||
Ok(s)
|
||||
if socket
|
||||
.parent()
|
||||
.and_then(pdfs_core::mountfail::read)
|
||||
.is_some() =>
|
||||
{
|
||||
(
|
||||
// Translators: {username} is the Proton account name. The
|
||||
// service keeps failing to start; the app shows the error.
|
||||
gettext_f(
|
||||
"Signed in as {username} — can't open your Drive",
|
||||
&[("username", &s.username)],
|
||||
),
|
||||
Phase::Attention,
|
||||
)
|
||||
}
|
||||
Ok(s) => (
|
||||
// Translators: {username} is the Proton account name.
|
||||
gettext_f(
|
||||
|
||||
+450
-3
@@ -68,6 +68,14 @@ original wording.
|
||||
|
||||
| Entry | Title | What is left |
|
||||
|---|---|---|
|
||||
| [B273](#b273--a-restore-proposes-another-computers-paths-when-the-two-share-a-hostname) | A restore proposes another computer's paths when the two share a hostname | Not fixed |
|
||||
| [B271](#b271--one-failed-listing-makes-a-large-first-sync-start-over-from-nothing) | One failed listing makes a large first sync start over from nothing | Not fixed |
|
||||
| [B270](#b270--one-file-left-in-a-mirror-folder-clears-the-wipe-guard-for-all-the-others) | One file left in a mirror folder clears the wipe guard for all the others | Not fixed |
|
||||
| [B269](#b269--a-restore-that-skipped-every-folder-reports-success) | A restore that skipped every folder reports success | Not fixed |
|
||||
| [B268](#b268--pdfs-diagnose-says-no-problems-found-while-sync-is-stuck) | `pdfs diagnose` says "No problems found" while sync is stuck | Not fixed |
|
||||
| [B267](#b267--a-key-failure-at-a-start-from-a-warm-cache-shows-as-offline-for-good) | A key failure at a start from a warm cache shows as offline for good | Not fixed |
|
||||
| [B266](#b266--pin-unpin-search-and-node-loads-report-a-database-error-as-offline) | Pin, unpin, search and node loads report a database error as "offline" | Not fixed |
|
||||
| [B265](#b265--address-keys-whose-token-is-for-an-inactive-account-key-never-open) | Address keys whose token is for an inactive account key never open | Needs an SDK change; not reproduced |
|
||||
| [B134](#b134--a-file-deleted-online-while-the-drain-checks-its-write-is-kept-as-a-conflict-copy) | A file deleted online while the drain checks its write is kept as a conflict copy | Only with `local_first` off |
|
||||
| [B91](#b91--the-daemon-hung-overnight-and-nothing-could-say-what-it-was-waiting-on) | The daemon hung overnight, and nothing could say what it was waiting on | The cause is not diagnosed; the daemon now reports where it is stuck and is restarted |
|
||||
| [B67](#b67--fresh-state-restore-can-silently-select-a-new-device-high-22) | Fresh-state restore can silently select a new device (HIGH-22) | An ambiguous device after a loss of local state is not asked about |
|
||||
@@ -80,6 +88,9 @@ original wording.
|
||||
|
||||
| Entry | Title | What is left |
|
||||
|---|---|---|
|
||||
| [B263](#b263--a-mount-that-can-never-succeed-retries-every-5-s-and-tells-only-the-journal) | A mount that can never succeed retries every 5 s and tells only the journal | Errors no retry fixes back off like network errors |
|
||||
| [B262](#b262--watching-a-large-synced-folder-holds-up-the-sync-engine-and-a-failed-watch-is-never-retried) | Watching a large synced folder holds up the sync engine, and a failed watch is never retried | The first pass still waits for the watch; a failed watch is not shown in the app |
|
||||
| [B259](#b259--the-sync-engine-can-die-or-hang-and-nothing-shows-it-until-a-restart) | The sync engine can die or hang, and nothing shows it until a restart | No pass deadline; an ended engine is reported, not restarted; the trigger in #53 is not known |
|
||||
| [B199](#b199--a-stopped-share-stays-on-the-shared-by-me-page-for-minutes) | A stopped share stays on the Shared by me page for minutes | The share itself is not deleted; the SDK has no call for it |
|
||||
| [B88](#b88--pdfs-pin-rename-move-delete-and-sharing-still-cannot-name-a-path-under-a-secondary-mount) | `pdfs pin`, `rename`, `move`, `delete` and sharing still cannot name a path under a secondary mount | `pin`, `unpin`, opening a file, thumbnails, uploads, sharing and versions |
|
||||
| [B72](#b72--pdfs-trash-never-returns) | `pdfs trash` never returns | The slowness of the first refresh is unmeasured |
|
||||
@@ -100,6 +111,11 @@ a live account since.
|
||||
|
||||
| Entry | Title |
|
||||
|---|---|
|
||||
| [B264](#b264--a-mount-that-fails-after-starting-its-workers-leaves-them-running) | A mount that fails after starting its workers leaves them running |
|
||||
| [B261](#b261--a-folder-that-has-never-synced-reads-up-to-date) | A folder that has never synced reads "up to date" |
|
||||
| [B272](#b272--after-a-folder-is-removed-and-added-again-its-file-events-go-to-the-old-id) | After a folder is removed and added again, its file events go to the old id |
|
||||
| [B260](#b260--the-poll-pushes-a-new-folders-first-sync-behind-every-other-folder) | The poll pushes a new folder's first sync behind every other folder |
|
||||
| [B258](#b258--journalctl--p-warning-shows-nothing-whatever-the-daemon-logged) | `journalctl -p warning` shows nothing, whatever the daemon logged |
|
||||
| [B256](#b256--pdfs-copy-right-after-a-save-copies-the-old-version) | `pdfs copy` right after a save copies the old version |
|
||||
| [B255](#b255--a-synced-folder-whose-files-are-all-gone-here-is-stuck-for-good) | A synced folder whose files are all gone here is stuck for good |
|
||||
| [B254](#b254--an-edit-in-the-same-second-as-a-new-upload-never-arrives) | An edit in the same second as a new upload never arrives |
|
||||
@@ -359,6 +375,425 @@ a live account since.
|
||||
|
||||
Newest first.
|
||||
|
||||
### B273 — A restore proposes another computer's paths when the two share a hostname
|
||||
|
||||
**Status:** Open
|
||||
**Found:** 2026-10-31, code audit after issue #46.
|
||||
**Where:** `saved_folder` in `crates/pdfs-core/src/profile.rs`
|
||||
|
||||
**Repro:** Two computers with the same hostname, for example both left at a distribution's
|
||||
default `archlinux`, sync the same device. Restore a folder on one of them. The proposed local
|
||||
path and mode come from whichever of the two profiles is found first, not from this computer's.
|
||||
|
||||
**Cause.** `saved_folder` prefers the profile whose `hostname` matches. The machine id that
|
||||
B252 added tells computers apart, but this lookup does not use it.
|
||||
|
||||
**Fix.** Not done. Match on the machine id first, then fall back to the hostname for profiles
|
||||
written before it existed.
|
||||
|
||||
---
|
||||
|
||||
### B272 — After a folder is removed and added again, its file events go to the old id
|
||||
|
||||
**Status:** Fixed, not verified live
|
||||
**Found:** 2026-10-31, code audit after issue #53.
|
||||
**Where:** `rewatch` in `crates/pdfs-fuse/src/sync/engine.rs`
|
||||
|
||||
**Repro:** Remove a synced folder and add the same path again before the engine handles the
|
||||
first `Rewatch`, so both land in one burst. Edits in the folder are not synced until the
|
||||
two-minute poll, and the same goes for every later edit until the daemon restarts.
|
||||
|
||||
**Cause.** `rewatch` matches the watches it has against the ones it wants by path alone. The
|
||||
path is still wanted, so the old entry stays with the removed folder's id. Its events become
|
||||
`Reconcile(old id)`, `sync_folder_get` finds no row, and the request is dropped.
|
||||
|
||||
**Fix.** `keep_wanted` keeps a watch whose path is still wanted and gives it the id the
|
||||
folder list has now.
|
||||
|
||||
**Test:** `a_re_added_folder_keeps_its_watch_under_the_new_id` in `pdfs-fuse`.
|
||||
|
||||
---
|
||||
|
||||
### B271 — One failed listing makes a large first sync start over from nothing
|
||||
|
||||
**Status:** Open
|
||||
**Found:** 2026-10-31, code audit after issue #46: a folder of about 19,900 items restored on a
|
||||
second computer sat at `scanning…` with nothing downloaded, and the journal showed
|
||||
`RequestTimeout (http 408)`.
|
||||
**Where:** `walk_remote` in `crates/pdfs-fuse/src/sync.rs`
|
||||
|
||||
**Repro:** Restore or add a mirror folder with tens of thousands of items on Drive, on a link
|
||||
that drops a request now and then. The pass walks the whole remote tree before it downloads
|
||||
anything. When one folder's listing fails after the SDK's retries, the pass fails, and the
|
||||
next one walks the whole tree again. On a slow enough link it never gets past the walk.
|
||||
|
||||
**Cause.** Each `enumerate_folder_children_node_uids`, `enumerate_nodes_light` and
|
||||
`enumerate_nodes` call in the walk ends the whole walk through `?`. Nothing is applied until
|
||||
the walk is done. Files that did download keep their baseline rows, so only the walk is lost,
|
||||
but on a first sync that is all of it. Progress is also counted only after a folder's full
|
||||
listing, so a large folder shows `scanning…` with 0 checked for a long time.
|
||||
|
||||
**Fix.** Not done. Record a failed subtree as a gap, as undecryptable nodes already are: no
|
||||
deletions under it, and the rest of the pass still applies.
|
||||
|
||||
---
|
||||
|
||||
### B270 — One file left in a mirror folder clears the wipe guard for all the others
|
||||
|
||||
**Status:** Open
|
||||
**Found:** 2026-10-31, code audit after issue #46, whose reporter emptied a synced folder
|
||||
several times.
|
||||
**Where:** `guard_local_wipe` and `guard_remote_wipe` in `crates/pdfs-fuse/src/sync/planner.rs`
|
||||
|
||||
**Repro:** Sync a mirror folder with many files. Make all of them but one unavailable here: a
|
||||
half-mounted disk, a restored backup that brought back one file, or a script that emptied the
|
||||
folder and wrote one file back. The next pass trashes every other file on Drive. On a device
|
||||
that two computers sync, the other computer then deletes its copies too.
|
||||
|
||||
**Cause.** The guard refuses a pass only when every baseline path is missing. One surviving
|
||||
path is enough to clear it, so it guards against an empty folder and nothing short of that.
|
||||
The remote guard has the same shape.
|
||||
|
||||
**Fix.** Not done. Also refuse when most of a large baseline is missing at once, and leave the
|
||||
choice to the user: delete on the other side, or sync from scratch.
|
||||
|
||||
---
|
||||
|
||||
### B269 — A restore that skipped every folder reports success
|
||||
|
||||
**Status:** Open
|
||||
**Found:** 2026-10-31, code audit after issue #46: the journal showed `restore complete
|
||||
restored=0 skipped=1` several times, and the user saw nothing.
|
||||
**Where:** the `RestoreSyncFolders` and `RestoreDeviceFolders` handler in
|
||||
`crates/pdfs-fuse/src/control.rs`; `restore_sync_folders` in `crates/pdfs-fuse/src/profile.rs`
|
||||
|
||||
**Repro:** Restore a folder from another computer to a path that is already a sync root here,
|
||||
for example a folder left over from an earlier attempt. `pdfs devices join` prints `restoring
|
||||
folders`, and the app shows the same. Nothing downloads, and no error appears anywhere.
|
||||
|
||||
**Cause.** The daemon acks before it works, because a restore outlasts the socket timeout. The
|
||||
result, `restored 0 folder(s); skipped: …`, is then logged as a successful activity, so the
|
||||
reason is only in the activity text and the journal. When the database insert fails partway,
|
||||
the `?` also skips the `Rewatch` for the folders already restored.
|
||||
|
||||
**Fix.** Not done. Log a restore that skipped folders as a failure, name the reason in the app
|
||||
and the CLI, and offer to replace or reset the folder in the way. Send the `Rewatch` on every
|
||||
exit path.
|
||||
|
||||
---
|
||||
|
||||
### B268 — `pdfs diagnose` says "No problems found" while sync is stuck
|
||||
|
||||
**Status:** Open
|
||||
**Found:** 2026-10-31, issue #53: a folder that never synced, and `diagnose` found nothing.
|
||||
**Where:** `diagnose` in `crates/pdfs-cli/src/main.rs`
|
||||
|
||||
**Repro:** Leave a synced folder in `error`, or have queued writes that keep failing, or pause
|
||||
sync. `pdfs diagnose` reports every check `[ok]` and exits 0.
|
||||
|
||||
**Cause.** The `Status` reply is matched with `..`, which drops `failing_ops`, `failing_error`,
|
||||
`parked_uploads`, `staged_oldest_secs` and `paused`. `diagnose` never asks for the synced
|
||||
folders or for `Diagnostics`, so a folder in error and a stalled worker are not seen. A
|
||||
control socket file with no daemon behind it is also reported `[ok]`; only the next line says
|
||||
the daemon does not answer.
|
||||
|
||||
**Fix.** Not done. Warn on failing or parked writes, a pause, old staged data and folders in
|
||||
error, and report the sync engine's state once B259 exposes it.
|
||||
|
||||
---
|
||||
|
||||
### B267 — A key failure at a start from a warm cache shows as offline for good
|
||||
|
||||
**Status:** Open
|
||||
**Found:** 2026-10-31, code audit after issue #40. B202 fixed the same path for a refused
|
||||
session only.
|
||||
**Where:** `fetch_or_recall_root` in `crates/pdfs-fuse/src/mount.rs`; `run_online_probe` in
|
||||
`crates/pdfs-fuse/src/link.rs`
|
||||
|
||||
**Repro:** Sign in once so the cache holds the My Files root. Then start the daemon in a state
|
||||
where the root cannot be decrypted, for example the address-key failure of B265. The mount
|
||||
comes up "offline", the app says you are offline, and it stays so while the network is fine.
|
||||
|
||||
**Cause.** Any error from `get_my_files_folder` other than a revoked session becomes
|
||||
`Start::Offline` when a cached root exists. The online probe then retries the same call and
|
||||
logs its failures at debug level, so the journal at the default level says nothing.
|
||||
|
||||
**Fix.** Not done. Use `Start::Offline` only for an error `is_network_error` accepts, and
|
||||
report the others as their own state through `Status`.
|
||||
|
||||
---
|
||||
|
||||
### B266 — Pin, unpin, search and node loads report a database error as "offline"
|
||||
|
||||
**Status:** Open
|
||||
**Found:** 2026-10-31, code audit after issue #38. B205 fixed the photo upload path only.
|
||||
**Where:** `CoreError::from_api` in `crates/pdfs-core/src/error.rs`; its callers in
|
||||
`crates/pdfs-fuse/src/lib.rs` (`pin`, `unpin`, the searches, `load node`)
|
||||
|
||||
**Repro:** Pin a folder while the cache database is locked or full. The app says "You're
|
||||
offline" and drops the reason.
|
||||
|
||||
**Cause.** `from_api` classifies any error that is not a `ProtonError` as `Offline`, because
|
||||
it was written for SDK calls, where that means a transport error. These callers pass it
|
||||
`pdfs_core::Error` values from the cache and the database. A `ProtonError` wrapped in
|
||||
`pdfs_core::Error::Proton` also misses the downcast, since the source chain is not walked.
|
||||
|
||||
**Fix.** Not done. Use `CoreError::internal` at the database callers, and walk the source
|
||||
chain in `from_api` before falling back.
|
||||
|
||||
---
|
||||
|
||||
### B265 — Address keys whose token is for an inactive account key never open
|
||||
|
||||
**Status:** Open
|
||||
**Found:** 2026-10-31, code audit after issue #40: a Duo account whose mount failed on every
|
||||
start with `fetch My Files root: cryptography error: failed to decrypt: missing key`, after three
|
||||
`failed to decrypt address key token` warnings. The web app worked. B210's fix does not apply,
|
||||
because the account has an active volume.
|
||||
**Where:** `user_keys` and `decrypt_address` in `proton-sdk` (`crates/proton-sdk/src/account.rs`
|
||||
in `proton-sdk-rs`)
|
||||
|
||||
**Repro:** Not reproduced. An account whose address-key tokens are encrypted to an account key
|
||||
that is no longer active cannot open those address keys, and so cannot open the My Files share.
|
||||
|
||||
**Cause.** `user_keys` skips every inactive account key, even one the password opens, and the
|
||||
address-key tokens are decrypted only with what it returns. `keycheck.rs` in this repository
|
||||
already reports "token is for inactive account key", so the case is known. Separately,
|
||||
`addresses()` fails as a whole through `?` when one address has no usable primary key, which
|
||||
takes the working addresses down with it.
|
||||
|
||||
**Fix.** Not done, and it belongs in the SDK. Use every account key that opens for decrypting
|
||||
tokens, and only the active ones for signing. Skip and log an address that cannot be opened.
|
||||
|
||||
---
|
||||
|
||||
### B264 — A mount that fails after starting its workers leaves them running
|
||||
|
||||
**Status:** Fixed, not verified live
|
||||
**Found:** 2026-10-31, code audit after issue #40.
|
||||
**Where:** `run_mount` in `crates/pdfs-fuse/src/mount.rs`
|
||||
|
||||
**Repro:** Make the mount fail after the workers start: a busy mountpoint, or a control socket
|
||||
whose permissions cannot be set. The daemon retries every 5 s, and the drain, sync, sweep,
|
||||
probe and index threads of the failed attempt keep running beside the next one.
|
||||
|
||||
**Cause.** The early returns after the workers are spawned (the `?` on the socket bind, the
|
||||
permission check, a `spawn_session` error, and a `?` on a later thread spawn) skip
|
||||
`stop_workers`. The threads hold a `Core`, and the `Core` holds the database. If that keeps
|
||||
the `flock` held, every later attempt fails with "another daemon is using cache.db" instead
|
||||
of the real error. That part is inferred from the code and not observed.
|
||||
|
||||
**Fix.** Every early return in `mount` after the first worker starts stops the workers
|
||||
(`abandon_workers`, `keep_or_abandon` in `crates/pdfs-fuse/src/mount.rs`). Unlike a normal stop
|
||||
it does not send `STOPPING=1`, because the daemon is about to retry and systemd would
|
||||
otherwise wait for it to exit and then kill it. The control-thread failure path, which already
|
||||
stopped its workers, no longer sends it either.
|
||||
|
||||
**Test:** none of its own; the simulations (`sim::daemon`, 55 passed) cover the normal start
|
||||
and stop.
|
||||
|
||||
---
|
||||
|
||||
### B263 — A mount that can never succeed retries every 5 s and tells only the journal
|
||||
|
||||
**Status:** Partly fixed. Errors that no retry fixes are not told apart from network errors yet.
|
||||
**Found:** 2026-10-31, issue #40: the app showed "Connecting… waiting for the Proton Drive
|
||||
service" for days, `pdfs diagnose` only reported the control socket missing, and the reporter
|
||||
uninstalled.
|
||||
**Where:** the mount loop in `crates/pdfs-cli/src/main.rs`; `run_mount` in
|
||||
`crates/pdfs-fuse/src/mount.rs`
|
||||
|
||||
**Repro:** Start the daemon with a session whose keys cannot open My Files (B265). The journal
|
||||
shows `mount failed; retrying in 5s` forever. The app and the tray wait for the service, and
|
||||
nothing says why.
|
||||
|
||||
**Cause.** Every mount error gets the same 5 s retry, whether it is a network error or one that
|
||||
no retry fixes, such as a key or a 4xx answer. Each attempt builds a new client and sends about
|
||||
four requests, so a broken account sends tens of thousands a day, which may also feed
|
||||
Proton's sign-in blocks (#39). The control socket is bound only after the mount succeeds, and
|
||||
the error is written nowhere a front end can read it.
|
||||
|
||||
**Fix.**
|
||||
- The retry doubles from 5 s to a 2-minute ceiling (`mount_retry_delay` in
|
||||
`crates/pdfs-cli/src/main.rs`), about 720 attempts a day instead of 17,000. The ceiling stays
|
||||
at minutes because a cold start without a network fails the same way and has to mount soon
|
||||
after the network returns.
|
||||
- Each failure is written to `mount-failure.json` in the state directory
|
||||
(`crates/pdfs-core/src/mountfail.rs`), with the error, since when it fails and the attempt
|
||||
count. A mount that comes up removes it, and so does a new daemon.
|
||||
- The app shows "Can't open your Drive" with the error and a Retry button instead of
|
||||
"Connecting…". The tray says "Signed in as … — can't open your Drive". `pdfs diagnose` reports
|
||||
`[FAIL] mount: failing for …`. `systemctl --user status` shows the error as the unit's status.
|
||||
- Not done: key, `KeysLocked` and 4xx errors still retry like network errors, only less often.
|
||||
|
||||
**Test:** `a_failing_mount_backs_off_to_a_ceiling` in `pdfs-cli`;
|
||||
`a_recorded_failure_reads_back_until_cleared` in `pdfs-core`. On 2026-10-31 a second
|
||||
`pdfs daemon` beside the running one failed on the database lock three times in 18 s (at 0, 5
|
||||
and 15 s) and recorded `attempts: 3` with the lock error.
|
||||
|
||||
---
|
||||
|
||||
### B262 — Watching a large synced folder holds up the sync engine, and a failed watch is never retried
|
||||
|
||||
**Status:** Partly fixed. A watch is still set up before the first pass, and a failed watch
|
||||
is not shown in the folder's state.
|
||||
**Found:** 2026-10-31, code audit after issue #53.
|
||||
**Where:** `rewatch` and `engine_loop` in `crates/pdfs-fuse/src/sync/engine.rs`
|
||||
|
||||
**Repro:** Add a synced folder with many subfolders, or one that holds a symlink to a large
|
||||
tree, on a system near `fs.inotify.max_user_watches`. The new folder's first pass waits until
|
||||
the recursive watch is set up. When the watch fails, the journal has one `sync: watch failed`
|
||||
line, the folder is never watched, and later changes are found only by the two-minute poll.
|
||||
|
||||
**Cause.**
|
||||
- `rewatch` runs on the engine thread before the reconcile, and notify's recursive watch walks
|
||||
the whole tree, at startup for every folder.
|
||||
- notify follows symlinks by default, and the local walk does not.
|
||||
- When `watch` fails partway, the watches added before the failure stay registered, but the
|
||||
folder is not recorded as watched. Their events match no folder and become `ReconcileAll`,
|
||||
and they use up watches the next folder needs.
|
||||
- Errors the watcher reports later are dropped in its callback.
|
||||
|
||||
**Fix.**
|
||||
- A failed watch is unwatched, which removes the watches it had added under the folder, and
|
||||
is tried again every 10 minutes. The warning names `fs.inotify.max_user_watches`.
|
||||
- The watcher no longer follows symlinks.
|
||||
- Errors the watcher reports are logged.
|
||||
- Not done: the watch still runs before the folder's first pass. Watching first is what keeps
|
||||
a change made during the pass from being missed, so the order stays; the cost is one walk
|
||||
of a new folder's tree. A failed watch is not shown in the folder's state yet.
|
||||
|
||||
**Test:** none for the watch failure itself; it needs the inotify limit reached.
|
||||
|
||||
---
|
||||
|
||||
### B261 — A folder that has never synced reads "up to date"
|
||||
|
||||
**Status:** Fixed, not verified live
|
||||
**Found:** 2026-10-31, issue #53: "In Computers I add the folder. It appears as synced."
|
||||
**Where:** `sync_folder` in `crates/pdfs-core/src/db/migrations.rs`; `sync_state_label` in
|
||||
`crates/pdfs-gui/src/app/pages/devices.rs`; the location rows in
|
||||
`crates/pdfs-gui/src/app/pages/locations.rs`
|
||||
|
||||
**Repro:** Add a synced folder. Until its first pass starts, the app shows it as up to date.
|
||||
The same happens after a switch from on-demand to mirror, after **Sync From Scratch…**, and for
|
||||
every folder while sync is paused for the whole account.
|
||||
|
||||
**Cause.** The `state` column defaults to `idle`, and every state the label does not know reads
|
||||
"up to date". `last_sync` is 0 for a folder that has never synced, but the rows do not look at
|
||||
it, and a test pins the label for that case. The rows only show a folder's own pause, not the
|
||||
account-wide one.
|
||||
|
||||
**Fix.** A mirror folder whose `last_sync` is 0 and whose state is `idle` reads "waiting for
|
||||
first sync" on its row. The This computer row on the Computers page counts such folders, as in
|
||||
"2 folders backed up · 1 waiting for its first sync". An on-demand folder has no first sync,
|
||||
so it is left out. The account-wide pause stays where it already is, the pause card at the top
|
||||
of the page; repeating it on every row would only add noise.
|
||||
|
||||
**Test:** `a_folder_reads_up_to_date_only_after_its_first_sync` and
|
||||
`a_folder_before_its_first_sync_is_not_counted_as_backed_up` in `pdfs-gui`; the pinned test now
|
||||
expects the new label.
|
||||
|
||||
---
|
||||
|
||||
### B260 — The poll pushes a new folder's first sync behind every other folder
|
||||
|
||||
**Status:** Fixed, not verified live
|
||||
**Found:** 2026-10-31, code audit after issue #53.
|
||||
**Where:** `engine_loop` in `crates/pdfs-fuse/src/sync/engine.rs`
|
||||
|
||||
**Repro:** Sync a few large mirror folders whose passes take longer than two minutes, then add
|
||||
another folder. Its first pass waits until every other folder has been walked again, each
|
||||
time.
|
||||
|
||||
**Cause.** The poll sends `ReconcileAll` every two minutes whether or not a pass is still
|
||||
running. When a burst holds both a `ReconcileAll` and a folder's `Reconcile(id)`, the loop runs
|
||||
only `reconcile_all`, which goes in id order. A new folder has the highest id, so it always
|
||||
goes last.
|
||||
|
||||
**Fix.** `run_burst` runs the folders a burst names by id first, lowest id first, and then
|
||||
every other folder when the burst also holds a `ReconcileAll`. A named folder is read again
|
||||
before its pass. A pause that lands between passes now stops the rest of the burst.
|
||||
|
||||
**Test:** `named_folders_run_before_the_rest_of_a_burst` in `pdfs-fuse`.
|
||||
|
||||
---
|
||||
|
||||
### B259 — The sync engine can die or hang, and nothing shows it until a restart
|
||||
|
||||
**Status:** Partly fixed. A hung pass is reported but not ended, and a panic outside a pass
|
||||
still stops the engine; it is reported, not restarted.
|
||||
**Found:** 2026-10-31, issue #53: a newly added folder did not sync until the reporter restarted
|
||||
the app. All FUSE workers were idle, nothing was queued, and the warning-level journal was
|
||||
empty (B258).
|
||||
**Where:** `spawn` and `engine_loop` in `crates/pdfs-fuse/src/sync/engine.rs`;
|
||||
`reconcile_pass` in `crates/pdfs-fuse/src/sync.rs`; `crates/pdfs-fuse/src/diagnostics.rs`
|
||||
|
||||
**Repro:** Not reproduced. Make one pass panic, or block in a call that does not return. Every
|
||||
later add, `pdfs sync now`, file event and poll is dropped without a word. The folder that was
|
||||
syncing stays `syncing` with its last progress. A restart runs a pass over every folder, which
|
||||
is why it helps.
|
||||
|
||||
**Cause.**
|
||||
- The engine is one thread, and nothing catches a panic in a pass. When it unwinds, the
|
||||
receiver is gone and every `let _ = sync_tx.send(..)` fails silently. The poll thread stops
|
||||
at its first failed send.
|
||||
- The thread's `JoinHandle` is checked only at shutdown.
|
||||
- A pass has no overall deadline. Each request is bounded, but a pass is not; B165 dealt with
|
||||
the stop only.
|
||||
- Nothing logs a pass starting, or ending without changes. `Diagnostics` covers the FUSE
|
||||
workers and the request queue, not this thread, so "workers idle, nothing queued" says
|
||||
nothing about sync.
|
||||
- A database error when the engine reads a folder drops that folder's request without a log.
|
||||
|
||||
**Fix.**
|
||||
- Each pass runs under `catch_unwind` (`EngineHealth::contain` in
|
||||
`crates/pdfs-fuse/src/sync/engine.rs`). A panic ends that pass only: its progress is cleared,
|
||||
the folder is set to `error`, the activity feed says so, and the next poll tries again.
|
||||
- `Diagnostics` carries the engine's state: running or not, the folder of the running pass, how
|
||||
long it has run and how long since it last reported progress, and how many passes panicked.
|
||||
`pdfs diagnostics` prints it as `sync engine: …`.
|
||||
- The supervisor warns when the engine thread has ended, and when a pass has reported no
|
||||
progress for 15 minutes.
|
||||
- A first pass logs its start and end at info, as does any pass that changed something or
|
||||
took 30 s or more. A request for a folder the database cannot read is logged.
|
||||
- Not done: a deadline for a pass, and restarting an engine thread that has ended. The
|
||||
channel's receiver ends with the thread, so a restart needs a new channel in every `Core`
|
||||
clone.
|
||||
|
||||
**Test:** `a_panicking_pass_is_contained_and_counted`, `the_running_pass_is_reported` and
|
||||
`the_engine_reads_as_stopped_once_its_thread_ends` in `pdfs-fuse`;
|
||||
`a_stopped_sync_engine_is_a_stall` and `only_a_quiet_sync_pass_is_a_stall` in the supervisor.
|
||||
|
||||
---
|
||||
|
||||
### B258 — `journalctl -p warning` shows nothing, whatever the daemon logged
|
||||
|
||||
**Status:** Fixed, not verified live
|
||||
**Found:** 2026-10-31, issue #53: the reporter ran `journalctl --user -u proton-drive.service -b
|
||||
-p warning`, as `docs/TROUBLESHOOTING.md` tells them to, and got `-- No entries --`.
|
||||
**Where:** `main` in `crates/pdfs-cli/src/main.rs`; `packaging/proton-drive.service`
|
||||
|
||||
**Repro:** Make the daemon log a warning, then run the command above. It prints no entries.
|
||||
Without `-p` the warning is there.
|
||||
|
||||
**Cause.** The daemon logs with plain `tracing_subscriber::fmt()` to standard output. journald
|
||||
stores every line of a service's output at the unit's default priority, info, unless the line
|
||||
starts with a `<N>` prefix. So every `WARN` and `ERROR` line is stored as info, and the
|
||||
troubleshooting guide's filter hides all of them.
|
||||
|
||||
**Fix.** When standard output is the journal stream (`JOURNAL_STREAM` names the same
|
||||
device and inode as fd 1), each line starts with the `<N>` prefix for its level, and ANSI colours
|
||||
are off. A terminal that merely inherited `JOURNAL_STREAM` keeps the plain format
|
||||
(`crates/pdfs-cli/src/journal.rs`).
|
||||
|
||||
**Test:** `each_line_opens_with_the_priority_of_its_level` and
|
||||
`journal_stream_must_name_the_same_file` in `pdfs-cli`. On 2026-10-31, `pdfs diagnose` run with
|
||||
`RUST_LOG=debug` under `systemd-run --user -p StandardOutput=journal` stored its debug lines at
|
||||
`PRIORITY=7` and its report at 6.
|
||||
|
||||
---
|
||||
|
||||
### B256 — `pdfs copy` right after a save copies the old version
|
||||
|
||||
**Status:** Fixed, not verified live
|
||||
@@ -402,14 +837,20 @@ folder lost its files is not known yet.
|
||||
|
||||
**Fix.** The push pass for a switch to on-demand forgets the baseline rows of a local copy that
|
||||
is gone in full, instead of trashing them on Drive, so the switch goes ahead and the mount shows
|
||||
what Drive has. **Sync From Scratch…** in the app and `pdfs sync reset ID` clear a mirror
|
||||
what Drive has. A switch asked for before any pass saw the folder empty found it still `idle`,
|
||||
and the check for what only this computer has refused it at once: every path read as "deleted
|
||||
here but not on Proton Drive yet". The account run found that. Such a switch now waits for the
|
||||
same push pass (`mirror_tree_gone` in `crates/pdfs-fuse/src/sync.rs`, checked in
|
||||
`apply_sync_folder_mode`). **Sync From Scratch…** in the app and `pdfs sync reset ID` clear a mirror
|
||||
folder's baseline, so the next pass compares both sides as on the first sync: one-sided files
|
||||
are copied across, files that differ keep both versions, and nothing is deleted. Restore now
|
||||
logs why it skipped a folder.
|
||||
|
||||
**Test:** The simulations `a_folder_whose_local_copy_is_gone_still_goes_on_demand` (which
|
||||
failed in exactly the reported state before the fix) and
|
||||
`a_folder_whose_local_copy_is_gone_downloads_again_after_a_reset`.
|
||||
failed in exactly the reported state before the fix),
|
||||
`a_folder_emptied_before_any_pass_still_goes_on_demand` (which failed with the account run's
|
||||
error) and `a_folder_whose_local_copy_is_gone_downloads_again_after_a_reset`; the acceptance case
|
||||
"an emptied mirror folder switches to on-demand".
|
||||
|
||||
---
|
||||
|
||||
@@ -1517,6 +1958,8 @@ what it holds. What was synced in it is still deleted.
|
||||
### B210 — After a password reset, the mount retries "missing key" forever
|
||||
|
||||
**Status:** Fixed, not verified live
|
||||
**See also:** B265. The account in issue #40 has an active volume, so this fix does not run for
|
||||
it; its "missing key" comes from address keys that do not open.
|
||||
**Found:** 2026-10-15, issue #40: on a fresh 3.4.0 install the sign-in worked, but the daemon
|
||||
logged `mount failed: fetch My Files root: cryptography error: failed to decrypt: missing key`
|
||||
every 5 seconds. The app stayed on "Connecting…" because the daemon never got far enough to
|
||||
@@ -1662,6 +2105,7 @@ front-end is the stale one, and restarting the service would not help.
|
||||
### B205 — A photo upload the SDK refuses says "You're offline"
|
||||
|
||||
**Status:** Fixed, not verified live
|
||||
**See also:** B266, the same misclassification on the pin, unpin, search and node-load paths.
|
||||
**Found:** 2026-10-11, issue #38: uploading an image from the Photos page showed "You're offline"
|
||||
while other uploads went through. Each `upload_photo` failed about 5 µs after it started, with no
|
||||
request sent, and the journal gave no reason.
|
||||
@@ -1746,6 +2190,7 @@ taken as this session's, so the daemon keeps writing its later rotations.
|
||||
### B202 — A refused session shows as offline forever, and nothing says to sign in again
|
||||
|
||||
**Status:** Fixed, not verified live
|
||||
**See also:** B267. Other errors at a start from a warm cache still mount as offline.
|
||||
**Found:** 2026-10-09, issue #35: the tray and `pdfs diagnose` said "offline, 3 queued", and
|
||||
diagnose also said "keyring session: ok", while every call in the log failed with
|
||||
`InvalidRefreshToken (http 400)`. `pdfs sync now` and restarting the service changed nothing.
|
||||
@@ -2687,6 +3132,8 @@ fix).
|
||||
### B165 — A stop waits on a stuck thread until systemd kills the daemon
|
||||
|
||||
**Status:** Fixed (unverified).
|
||||
**See also:** B259. A pass still has no deadline while the daemon runs, and a stuck or dead
|
||||
sync engine is not reported.
|
||||
**Found:** 2026-10-04, by the account run on 2.10.0 (cleanup after on-demand pairing 2). The
|
||||
daemon was stopped at 15:53:04 and logged "control socket closing", but never "sync engine
|
||||
stopping" or "daemon stopping". systemd killed it 15 s later (`TimeoutStopSec`). The run's
|
||||
|
||||
+4
-3
@@ -70,9 +70,10 @@ Schema: **44**, unchanged.
|
||||
|
||||
- **A synced folder whose files were all gone from this computer no longer gets stuck** (#46).
|
||||
The sync still refuses to delete everything on Proton Drive, but a switch to online only now
|
||||
goes ahead and shows what Proton Drive has, instead of waiting for good. To download the
|
||||
files again instead, sync the folder from scratch. Restoring folders also logs why it
|
||||
skipped a folder.
|
||||
goes ahead and shows what Proton Drive has, instead of waiting for good. This includes a
|
||||
switch asked for right after the files went, which was refused with "… was deleted here but
|
||||
not on Proton Drive yet". To download the files again instead, sync the folder from scratch.
|
||||
Restoring folders also logs why it skipped a folder.
|
||||
|
||||
- **The first sync of a folder shows how far its scan got** (#46). Before anything downloads,
|
||||
the first pass reads every item on Proton Drive, which takes many minutes for a large folder.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pkgbase = proton-drive-for-linux-bin
|
||||
pkgdesc = Unofficial Proton Drive client: FUSE files-on-demand mount, CLI, GTK4 app, tray (binaries)
|
||||
pkgver = 3.5.0
|
||||
pkgver = 3.6.0
|
||||
pkgrel = 1
|
||||
url = https://proton-drive.narl.io
|
||||
install = proton-drive.install
|
||||
@@ -22,21 +22,21 @@ pkgbase = proton-drive-for-linux-bin
|
||||
optdepends = xdg-utils: "Open folder" action in the tray menu
|
||||
optdepends = fzf: search-as-you-type launcher (pdfs-prompt --fzf)
|
||||
optdepends = foot: terminal that hosts pdfs-prompt --fzf when started from a keybinding
|
||||
provides = proton-drive-for-linux=3.5.0
|
||||
provides = proton-drive-linux=3.5.0
|
||||
provides = proton-drive-for-linux=3.6.0
|
||||
provides = proton-drive-linux=3.6.0
|
||||
provides = pdfs
|
||||
conflicts = proton-drive-linux
|
||||
conflicts = proton-drive-for-linux
|
||||
conflicts = proton-drive-for-linux-git
|
||||
options = !strip
|
||||
options = !debug
|
||||
source = proton-drive-linux-3.5.0-x86_64.tar.gz::https://github.com/narrrl/proton-drive-linux/releases/download/v3.5.0/proton-drive-linux-3.5.0-x86_64.tar.gz
|
||||
source = io.narl.proton-drive-linux-3.5.0.desktop::https://raw.githubusercontent.com/narrrl/proton-drive-linux/v3.5.0/packaging/io.narl.proton-drive-linux.desktop
|
||||
source = io.narl.proton-drive-linux-tray-3.5.0.desktop::https://raw.githubusercontent.com/narrrl/proton-drive-linux/v3.5.0/packaging/io.narl.proton-drive-linux-tray.desktop
|
||||
source = io.narl.proton-drive-linux-3.5.0.svg::https://raw.githubusercontent.com/narrrl/proton-drive-linux/v3.5.0/packaging/io.narl.proton-drive-linux.svg
|
||||
source = proton-drive-3.5.0.service::https://raw.githubusercontent.com/narrrl/proton-drive-linux/v3.5.0/packaging/proton-drive.service
|
||||
source = LICENSE-3.5.0::https://raw.githubusercontent.com/narrrl/proton-drive-linux/v3.5.0/LICENSE
|
||||
sha256sums = 902f60de5f471cb15c84d0ecb29cb4644a0ac52ce36d2be54c16b4befeba8de0
|
||||
source = proton-drive-linux-3.6.0-x86_64.tar.gz::https://github.com/narrrl/proton-drive-linux/releases/download/v3.6.0/proton-drive-linux-3.6.0-x86_64.tar.gz
|
||||
source = io.narl.proton-drive-linux-3.6.0.desktop::https://raw.githubusercontent.com/narrrl/proton-drive-linux/v3.6.0/packaging/io.narl.proton-drive-linux.desktop
|
||||
source = io.narl.proton-drive-linux-tray-3.6.0.desktop::https://raw.githubusercontent.com/narrrl/proton-drive-linux/v3.6.0/packaging/io.narl.proton-drive-linux-tray.desktop
|
||||
source = io.narl.proton-drive-linux-3.6.0.svg::https://raw.githubusercontent.com/narrrl/proton-drive-linux/v3.6.0/packaging/io.narl.proton-drive-linux.svg
|
||||
source = proton-drive-3.6.0.service::https://raw.githubusercontent.com/narrrl/proton-drive-linux/v3.6.0/packaging/proton-drive.service
|
||||
source = LICENSE-3.6.0::https://raw.githubusercontent.com/narrrl/proton-drive-linux/v3.6.0/LICENSE
|
||||
sha256sums = 8e9b76b0df238af1c8978c33b4c27c0c548e1faa81b368d0d271ed564d0a76c7
|
||||
sha256sums = d190d6771fff0b975271fb62fd3fb0fa8bbf17d7278c10853c18557855b0c123
|
||||
sha256sums = 1d95e250370220e3bb6aead6ce34d1d6cc759f42c4803b75f1667e78ff47c6c0
|
||||
sha256sums = e598a93c2715c3a9fdc7fb937902083d4a1135e8fbdfe6fe7e37f0383ebbd828
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Maintainer: Nils Pukropp <contact@narl.io>
|
||||
|
||||
pkgname=proton-drive-for-linux-bin
|
||||
pkgver=3.5.0
|
||||
pkgver=3.6.0
|
||||
pkgrel=1
|
||||
pkgdesc="Unofficial Proton Drive client: FUSE files-on-demand mount, CLI, GTK4 app, tray (binaries)"
|
||||
arch=('x86_64')
|
||||
@@ -36,7 +36,7 @@ source=("proton-drive-linux-$pkgver-x86_64.tar.gz::$_repo/releases/download/$_ta
|
||||
"io.narl.proton-drive-linux-$pkgver.svg::$_raw/packaging/io.narl.proton-drive-linux.svg"
|
||||
"proton-drive-$pkgver.service::$_raw/packaging/proton-drive.service"
|
||||
"LICENSE-$pkgver::$_raw/LICENSE")
|
||||
sha256sums=('902f60de5f471cb15c84d0ecb29cb4644a0ac52ce36d2be54c16b4befeba8de0'
|
||||
sha256sums=('8e9b76b0df238af1c8978c33b4c27c0c548e1faa81b368d0d271ed564d0a76c7'
|
||||
'd190d6771fff0b975271fb62fd3fb0fa8bbf17d7278c10853c18557855b0c123'
|
||||
'1d95e250370220e3bb6aead6ce34d1d6cc759f42c4803b75f1667e78ff47c6c0'
|
||||
'e598a93c2715c3a9fdc7fb937902083d4a1135e8fbdfe6fe7e37f0383ebbd828'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pkgbase = proton-drive-for-linux-git
|
||||
pkgdesc = Unofficial Proton Drive client: FUSE files-on-demand mount, CLI, GTK4 app, tray (git)
|
||||
pkgver = 3.5.0.r0.geb25c16
|
||||
pkgver = 3.6.0.r0.g2720191
|
||||
pkgrel = 1
|
||||
url = https://proton-drive.narl.io
|
||||
install = proton-drive.install
|
||||
@@ -25,8 +25,8 @@ pkgbase = proton-drive-for-linux-git
|
||||
optdepends = xdg-utils: "Open folder" action in the tray menu
|
||||
optdepends = fzf: search-as-you-type launcher (pdfs-prompt --fzf)
|
||||
optdepends = foot: terminal that hosts pdfs-prompt --fzf when started from a keybinding
|
||||
provides = proton-drive-for-linux=3.5.0.r0.geb25c16
|
||||
provides = proton-drive-linux=3.5.0.r0.geb25c16
|
||||
provides = proton-drive-for-linux=3.6.0.r0.g2720191
|
||||
provides = proton-drive-linux=3.6.0.r0.g2720191
|
||||
provides = pdfs
|
||||
conflicts = proton-drive-linux
|
||||
conflicts = proton-drive-for-linux
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Maintainer: Nils Pukropp <contact@narl.io>
|
||||
|
||||
pkgname=proton-drive-for-linux-git
|
||||
pkgver=3.5.0.r0.geb25c16
|
||||
pkgver=3.6.0.r0.g2720191
|
||||
pkgrel=1
|
||||
pkgdesc="Unofficial Proton Drive client: FUSE files-on-demand mount, CLI, GTK4 app, tray (git)"
|
||||
arch=('x86_64')
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pkgbase = proton-drive-for-linux
|
||||
pkgdesc = Unofficial Proton Drive client: files-on-demand FUSE mount, CLI, GTK4 app and tray
|
||||
pkgver = 3.5.0
|
||||
pkgver = 3.6.0
|
||||
pkgrel = 1
|
||||
url = https://proton-drive.narl.io
|
||||
install = proton-drive.install
|
||||
@@ -24,13 +24,13 @@ pkgbase = proton-drive-for-linux
|
||||
optdepends = xdg-utils: "Open folder" action in the tray menu
|
||||
optdepends = fzf: search-as-you-type launcher (pdfs-prompt --fzf)
|
||||
optdepends = foot: terminal that hosts pdfs-prompt --fzf when started from a keybinding
|
||||
provides = proton-drive-linux=3.5.0
|
||||
provides = proton-drive-linux=3.6.0
|
||||
provides = pdfs
|
||||
conflicts = proton-drive-linux
|
||||
conflicts = proton-drive-for-linux-bin
|
||||
conflicts = proton-drive-for-linux-git
|
||||
options = !lto
|
||||
source = proton-drive-for-linux-3.5.0.tar.gz::https://github.com/narrrl/proton-drive-linux/archive/refs/tags/v3.5.0.tar.gz
|
||||
sha256sums = 5eb0e001ec2301ffb8b2b8429e907fab32810d6eba541bf978a0ea97867d8bc9
|
||||
source = proton-drive-for-linux-3.6.0.tar.gz::https://github.com/narrrl/proton-drive-linux/archive/refs/tags/v3.6.0.tar.gz
|
||||
sha256sums = d9b16b1027816a379d6a11c6396d779f751a6f94becaa16b17439420f561d13d
|
||||
|
||||
pkgname = proton-drive-for-linux
|
||||
@@ -1,7 +1,7 @@
|
||||
# Maintainer: Nils Pukropp <contact@narl.io>
|
||||
|
||||
pkgname=proton-drive-for-linux
|
||||
pkgver=3.5.0
|
||||
pkgver=3.6.0
|
||||
pkgrel=1
|
||||
pkgdesc="Unofficial Proton Drive client: files-on-demand FUSE mount, CLI, GTK4 app and tray"
|
||||
arch=('x86_64')
|
||||
@@ -26,7 +26,7 @@ options=('!lto')
|
||||
# Stops the running daemon before removal, so the mount stops mirroring deletes.
|
||||
install=proton-drive.install
|
||||
source=("$pkgname-$pkgver.tar.gz::$_repo/archive/refs/tags/v$pkgver.tar.gz")
|
||||
sha256sums=('5eb0e001ec2301ffb8b2b8429e907fab32810d6eba541bf978a0ea97867d8bc9')
|
||||
sha256sums=('d9b16b1027816a379d6a11c6396d779f751a6f94becaa16b17439420f561d13d')
|
||||
|
||||
_srcname="proton-drive-linux-$pkgver"
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: proton-drive-linux 2.1.0\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/narrrl/proton-drive-linux/issues\n"
|
||||
"POT-Creation-Date: 2026-10-26 22:26+0100\n"
|
||||
"POT-Creation-Date: 2026-10-31 19:26+0100\n"
|
||||
"PO-Revision-Date: 2026-09-23 12:00+0200\n"
|
||||
"Last-Translator: Proton Drive for Linux contributors\n"
|
||||
"Language-Team: German\n"
|
||||
@@ -249,13 +249,13 @@ msgstr ""
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1917
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2039
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2540
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:804
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:957
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:995
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1047
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1091
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1131
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1194
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:826
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:979
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1017
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1069
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1113
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1153
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1216
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:850
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1054
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1537
|
||||
@@ -350,7 +350,7 @@ msgstr "Raster / Liste"
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:298
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1896
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1918
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:996
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1018
|
||||
#: crates/pdfs-gui/src/app/widgets/details.rs:161
|
||||
msgid "Rename"
|
||||
msgstr "Umbenennen"
|
||||
@@ -424,14 +424,27 @@ msgstr "Nicht verbunden"
|
||||
msgid "The Proton Drive service isn't running."
|
||||
msgstr "Der Proton-Drive-Dienst läuft nicht."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1803
|
||||
#: crates/pdfs-gui/src/app/main.rs:1813
|
||||
msgid "Can't open your Drive"
|
||||
msgstr "Proton Drive kann nicht geöffnet werden"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1816
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"The Proton Drive service keeps failing to start and tries again on its own. "
|
||||
"The last error was: {error}"
|
||||
msgstr ""
|
||||
"Der Proton-Drive-Dienst kann wiederholt nicht starten und versucht es "
|
||||
"selbstständig erneut. Letzter Fehler: {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1824
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:355
|
||||
#: crates/pdfs-gui/src/hud/mod.rs:269 crates/pdfs-gui/src/hud/mod.rs:579
|
||||
#: crates/pdfs-gui/src/main.rs:475 crates/pdfs-gui/src/main.rs:517
|
||||
#: crates/pdfs-gui/src/main.rs:493 crates/pdfs-gui/src/main.rs:535
|
||||
msgid "Connecting…"
|
||||
msgstr "Verbindung wird hergestellt …"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1804
|
||||
#: crates/pdfs-gui/src/app/main.rs:1825
|
||||
msgid "Waiting for the Proton Drive service to start."
|
||||
msgstr "Warten auf den Start des Proton-Drive-Dienstes."
|
||||
|
||||
@@ -682,7 +695,7 @@ msgid "Couldn't add a sync folder"
|
||||
msgstr "Synchronisierungsordner konnte nicht hinzugefügt werden"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/activity_text.rs:58
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:839
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:861
|
||||
msgid "Couldn't restore folders"
|
||||
msgstr "Ordner konnten nicht wiederhergestellt werden"
|
||||
|
||||
@@ -1274,12 +1287,12 @@ msgstr "Alben konnten nicht geladen werden"
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1873
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2500
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2650
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:707
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:747
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:900
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1170
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1231
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1260
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:729
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:769
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:922
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1192
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1253
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1282
|
||||
#: crates/pdfs-gui/src/app/pages/duplicates.rs:221
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:577
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:824
|
||||
@@ -1929,7 +1942,7 @@ msgid "{status}. {message}"
|
||||
msgstr "{status}. {message}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1900
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:989
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1011
|
||||
msgid "New name"
|
||||
msgstr "Neuer Name"
|
||||
|
||||
@@ -1954,7 +1967,7 @@ msgstr "Den Zielordner auswählen."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1989
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1994
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1195
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1217
|
||||
msgid "Move Here"
|
||||
msgstr "Hierher verschieben"
|
||||
|
||||
@@ -2279,76 +2292,87 @@ msgid_plural "{n} folders backed up"
|
||||
msgstr[0] "{n} Ordner gesichert"
|
||||
msgstr[1] "{n} Ordner gesichert"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:608
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:607
|
||||
#, rust-format
|
||||
msgid "{folders} · {n} waiting for its first sync"
|
||||
msgid_plural "{folders} · {n} waiting for their first sync"
|
||||
msgstr[0] "{folders} · {n} wartet auf die erste Synchronisierung"
|
||||
msgstr[1] "{folders} · {n} warten auf die erste Synchronisierung"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:621
|
||||
#, rust-format
|
||||
msgid "{folders} · {n} needs attention"
|
||||
msgid_plural "{folders} · {n} need attention"
|
||||
msgstr[0] "{folders} · {n} erfordert Aufmerksamkeit"
|
||||
msgstr[1] "{folders} · {n} erfordern Aufmerksamkeit"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:619
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:640
|
||||
msgid "syncing…"
|
||||
msgstr "wird synchronisiert …"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:620
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:641
|
||||
msgid "sync error"
|
||||
msgstr "Synchronisierungsfehler"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:621
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:642
|
||||
msgid "needs attention"
|
||||
msgstr "erfordert Aufmerksamkeit"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:622
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:643
|
||||
msgid "waiting for first sync"
|
||||
msgstr "wartet auf erste Synchronisierung"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:644
|
||||
msgid "up to date"
|
||||
msgstr "aktuell"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:632
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:654
|
||||
msgid "checking for changes…"
|
||||
msgstr "wird auf Änderungen geprüft …"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:638
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:660
|
||||
#, rust-format
|
||||
msgid "checking for changes — {n} item checked"
|
||||
msgid_plural "checking for changes — {n} items checked"
|
||||
msgstr[0] "wird auf Änderungen geprüft – {n} Element geprüft"
|
||||
msgstr[1] "wird auf Änderungen geprüft – {n} Elemente geprüft"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:645
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:667
|
||||
#, rust-format
|
||||
msgid "checking for changes — {done} of {total}"
|
||||
msgstr "wird auf Änderungen geprüft – {done} von {total}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:657
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:679
|
||||
#, rust-format
|
||||
msgid "syncing {done} of {total}"
|
||||
msgstr "{done} von {total} wird synchronisiert"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:663
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:685
|
||||
#, rust-format
|
||||
msgid "syncing {file} — {done} of {total}"
|
||||
msgstr "{file} wird synchronisiert – {done} von {total}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:675
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:697
|
||||
msgid "Add Folder to Sync"
|
||||
msgstr "Ordner zur Synchronisierung hinzufügen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:699
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:721
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1559
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1686
|
||||
msgid "Syncing folder…"
|
||||
msgstr "Ordner wird synchronisiert …"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:702
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:706
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:724
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:728
|
||||
msgid "Couldn't add folder"
|
||||
msgstr "Ordner konnte nicht hinzugefügt werden"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:740
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:746
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:762
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:768
|
||||
msgid "Couldn't list folders to restore"
|
||||
msgstr "Wiederherstellbare Ordner konnten nicht aufgelistet werden"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:772
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:794
|
||||
msgid ""
|
||||
"Tick the folders to sync to this machine, and adjust where each one should "
|
||||
"live."
|
||||
@@ -2356,19 +2380,19 @@ msgstr ""
|
||||
"Die Ordner ankreuzen, die mit diesem Rechner synchronisiert werden sollen, "
|
||||
"und für jeden den Speicherort anpassen."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:798
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:820
|
||||
msgid "Restore Folders"
|
||||
msgstr "Ordner wiederherstellen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:805
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:827
|
||||
msgid "Restore"
|
||||
msgstr "Wiederherstellen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:838
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:860
|
||||
msgid "Restoring folders…"
|
||||
msgstr "Ordner werden wiederhergestellt …"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:850
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:872
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"These folders are backed up from “{name}”. Restored folders keep syncing "
|
||||
@@ -2377,37 +2401,37 @@ msgstr ""
|
||||
"Diese Ordner werden von „{name}“ gesichert. Wiederhergestellte Ordner werden "
|
||||
"weiterhin mit der Kopie dieses Computers synchronisiert."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:853
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:875
|
||||
msgid "These folders are backed up under this computer in Proton Drive."
|
||||
msgstr "Diese Ordner werden in Proton Drive unter diesem Computer gesichert."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:862
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:884
|
||||
#, rust-format
|
||||
msgid "Nothing to restore — “{name}”'s folders are all synced here."
|
||||
msgstr ""
|
||||
"Nichts wiederherzustellen – alle Ordner von „{name}“ werden bereits hier "
|
||||
"synchronisiert."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:865
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:887
|
||||
msgid "Nothing to restore — this computer's folders are all synced here."
|
||||
msgstr ""
|
||||
"Nichts wiederherzustellen – alle Ordner dieses Computers werden bereits hier "
|
||||
"synchronisiert."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:889
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:911
|
||||
msgid "Folder will switch to online only"
|
||||
msgstr "Ordner wird auf „Nur online“ umgestellt"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:891
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:913
|
||||
msgid "Folder will download and stay synced"
|
||||
msgstr "Ordner wird heruntergeladen und bleibt synchronisiert"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:895
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:899
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:917
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:921
|
||||
msgid "Couldn't change mode"
|
||||
msgstr "Modus konnte nicht geändert werden"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:931
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:953
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"Stop syncing “{path}”?\n"
|
||||
@@ -2425,7 +2449,7 @@ msgstr ""
|
||||
"Ordner auf „Synchronisiert“ umstellen und vor dem Entfernen warten, bis der "
|
||||
"Download abgeschlossen ist."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:937
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:959
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"Stop syncing “{path}”?\n"
|
||||
@@ -2439,68 +2463,68 @@ msgstr ""
|
||||
"mehr synchronisiert. Es kann zusätzlich ausgewählt werden, die Kopie in "
|
||||
"Proton Drive zu löschen."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:942
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:964
|
||||
msgid "Stop Syncing Folder?"
|
||||
msgstr "Synchronisierung des Ordners beenden?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:947
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:969
|
||||
msgid "Also delete from Proton Drive"
|
||||
msgstr "Auch aus Proton Drive löschen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:949
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:971
|
||||
msgid "Deletes the only copy of these files."
|
||||
msgstr "Löscht die einzige Kopie dieser Dateien."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:951
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:973
|
||||
msgid "The local copy is unaffected."
|
||||
msgstr "Die lokale Kopie bleibt unverändert."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:958
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:980
|
||||
msgid "Stop Syncing"
|
||||
msgstr "Synchronisierung beenden"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:971
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:993
|
||||
msgid "Stopped syncing folder"
|
||||
msgstr "Synchronisierung des Ordners beendet"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:972
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:994
|
||||
msgid "Couldn't stop syncing the folder"
|
||||
msgstr "Synchronisierung des Ordners konnte nicht beendet werden"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:983
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1005
|
||||
msgid "Rename Computer"
|
||||
msgstr "Computer umbenennen"
|
||||
|
||||
#. Translators: {name} is the computer's current name.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:985
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1007
|
||||
#, rust-format
|
||||
msgid "Rename “{name}”."
|
||||
msgstr "„{name}“ umbenennen."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1010
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1022
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1032
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1044
|
||||
msgid "Couldn't rename the computer"
|
||||
msgstr "Der Computer konnte nicht umbenannt werden"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1011
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1033
|
||||
msgid "A name is required."
|
||||
msgstr "Ein Name ist erforderlich."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1021
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1043
|
||||
msgid "Computer renamed"
|
||||
msgstr "Computer umbenannt"
|
||||
|
||||
#. Translators: {name} is the computer's name, which the user must type.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1034
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1056
|
||||
#, rust-format
|
||||
msgid "Type “{name}” to confirm"
|
||||
msgstr "Zur Bestätigung „{name}“ eingeben"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1039
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1061
|
||||
msgid "Remove Computer?"
|
||||
msgstr "Computer entfernen?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1042
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1064
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"Remove “{name}” from this account?\n"
|
||||
@@ -2515,26 +2539,26 @@ msgstr ""
|
||||
"gelöscht. Die Dateien auf dem Computer selbst bleiben unberührt – dies kann "
|
||||
"jedoch von hier aus nicht rückgängig gemacht werden."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1048
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1070
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1025
|
||||
#: crates/pdfs-gui/src/app/widgets/share_dialog.rs:634
|
||||
#: crates/pdfs-gui/src/app/widgets/share_dialog.rs:876
|
||||
msgid "Remove"
|
||||
msgstr "Entfernen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1065
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1087
|
||||
msgid "Computer removed"
|
||||
msgstr "Computer entfernt"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1066
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1088
|
||||
msgid "Couldn't remove the computer"
|
||||
msgstr "Der Computer konnte nicht entfernt werden"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1084
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1106
|
||||
msgid "Continue This Backup Here?"
|
||||
msgstr "Diese Sicherung hier fortsetzen?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1087
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1109
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"This computer takes over the backup of “{name}”, for example after a "
|
||||
@@ -2553,25 +2577,25 @@ msgstr ""
|
||||
"werden nicht verschoben. Mit „Auf diesem Computer wiederherstellen“ lässt "
|
||||
"sich danach zurückholen, was „{name}“ synchronisiert hat."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1092
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1114
|
||||
msgid "Continue Here"
|
||||
msgstr "Hier fortsetzen"
|
||||
|
||||
#. Translators: {name} is the name of the computer whose backup this one took over.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1099
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1121
|
||||
#, rust-format
|
||||
msgid "Now backing up as “{name}”"
|
||||
msgstr "Sicherung jetzt als „{name}“"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1108
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1130
|
||||
msgid "Couldn't continue that backup here"
|
||||
msgstr "Diese Sicherung konnte hier nicht fortgesetzt werden"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1124
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1146
|
||||
msgid "Sync With This Computer?"
|
||||
msgstr "Mit diesem Computer synchronisieren?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1127
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1149
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"This computer and “{name}” keep the same folders in step. A change or a "
|
||||
@@ -2588,25 +2612,25 @@ msgstr ""
|
||||
"„{name}“. Bereits hier synchronisierte Ordner bleiben, wo sie sind. Als "
|
||||
"Nächstes wählen Sie, welche seiner Ordner hier synchronisiert werden."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1132
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1154
|
||||
msgid "Sync Here"
|
||||
msgstr "Hier synchronisieren"
|
||||
|
||||
#. Translators: {name} is the name of the other computer this one now syncs with.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1139
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1161
|
||||
#, rust-format
|
||||
msgid "Now syncing with “{name}”"
|
||||
msgstr "Jetzt synchron mit „{name}“"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1155
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1177
|
||||
msgid "Couldn't sync with that computer"
|
||||
msgstr "Synchronisierung mit diesem Computer nicht möglich"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1187
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1209
|
||||
msgid "Move Backup to This Computer?"
|
||||
msgstr "Sicherung auf diesen Computer verschieben?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1190
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1212
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"The folders backed up by “{name}” move into this computer's backup in Proton "
|
||||
@@ -2623,12 +2647,12 @@ msgstr ""
|
||||
"verschwinden."
|
||||
|
||||
#. Translators: {name} is the name of the computer whose folders moved to this one.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1202
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1224
|
||||
#, rust-format
|
||||
msgid "Moved the backup of “{name}”"
|
||||
msgstr "Sicherung von „{name}“ verschoben"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1216
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1238
|
||||
msgid "Couldn't move that backup"
|
||||
msgstr "Diese Sicherung konnte nicht verschoben werden"
|
||||
|
||||
@@ -2908,7 +2932,7 @@ msgid "Sync paused until you resume"
|
||||
msgstr "Synchronisierung bis zur Fortsetzung pausiert"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:570
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1445 crates/pdfs-gui/src/main.rs:290
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1445 crates/pdfs-gui/src/main.rs:308
|
||||
msgid "Sync paused"
|
||||
msgstr "Synchronisierung pausiert"
|
||||
|
||||
@@ -3374,7 +3398,7 @@ msgid "paused"
|
||||
msgstr "pausiert"
|
||||
|
||||
#. Translators: a folder's files can't be opened right now.
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1742
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1745
|
||||
msgid "not available"
|
||||
msgstr "nicht verfügbar"
|
||||
|
||||
@@ -5136,7 +5160,7 @@ msgstr "Wird {time} fortgesetzt"
|
||||
msgid "Until you resume"
|
||||
msgstr "Bis zur manuellen Fortsetzung"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1464 crates/pdfs-gui/src/main.rs:292
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1464 crates/pdfs-gui/src/main.rs:310
|
||||
#, rust-format
|
||||
msgid "{n} change needs attention"
|
||||
msgid_plural "{n} changes need attention"
|
||||
@@ -6371,52 +6395,57 @@ msgstr "Proton Drive reagiert nicht"
|
||||
msgid "Signed in as {username} — locked"
|
||||
msgstr "Angemeldet als {username} – gesperrt"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:200
|
||||
#: crates/pdfs-gui/src/main.rs:209
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — can't open your Drive"
|
||||
msgstr "Angemeldet als {username} – Proton Drive kann nicht geöffnet werden"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:218
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — not connected"
|
||||
msgstr "Angemeldet als {username} – nicht verbunden"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:205
|
||||
#: crates/pdfs-gui/src/main.rs:223
|
||||
msgid "Not signed in"
|
||||
msgstr "Nicht angemeldet"
|
||||
|
||||
#. Translators: {error} is an error message, in English.
|
||||
#: crates/pdfs-gui/src/main.rs:208
|
||||
#: crates/pdfs-gui/src/main.rs:226
|
||||
#, rust-format
|
||||
msgid "Error: {error}"
|
||||
msgstr "Fehler: {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:230
|
||||
#: crates/pdfs-gui/src/main.rs:248
|
||||
msgid "Proton Drive sent an unexpected reply"
|
||||
msgstr "Proton Drive hat unerwartet geantwortet"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:284
|
||||
#: crates/pdfs-gui/src/main.rs:302
|
||||
msgid "Session expired — sign in again"
|
||||
msgstr "Sitzung abgelaufen – erneut anmelden"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:286
|
||||
#: crates/pdfs-gui/src/main.rs:304
|
||||
msgid "Sign-in not saved — unlock your keyring"
|
||||
msgstr "Anmeldung nicht gespeichert – Schlüsselbund entsperren"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:289
|
||||
#: crates/pdfs-gui/src/main.rs:307
|
||||
msgid "Update not finished — restart Proton Drive"
|
||||
msgstr "Update nicht abgeschlossen – Proton Drive neu starten"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:299
|
||||
#: crates/pdfs-gui/src/main.rs:317
|
||||
#, rust-format
|
||||
msgid "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgid_plural "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgstr[0] "Aktuell in {mountpoint} ({n} angeheftet)"
|
||||
msgstr[1] "Aktuell in {mountpoint} ({n} angeheftet)"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:306
|
||||
#: crates/pdfs-gui/src/main.rs:324
|
||||
#, rust-format
|
||||
msgid "Syncing — {queued} ({n} pinned)"
|
||||
msgid_plural "Syncing — {queued} ({n} pinned)"
|
||||
msgstr[0] "Wird synchronisiert – {queued} ({n} angeheftet)"
|
||||
msgstr[1] "Wird synchronisiert – {queued} ({n} angeheftet)"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:313
|
||||
#: crates/pdfs-gui/src/main.rs:331
|
||||
#, rust-format
|
||||
msgid "Offline — cached files only ({n} pinned)"
|
||||
msgid_plural "Offline — cached files only ({n} pinned)"
|
||||
@@ -6424,60 +6453,60 @@ msgstr[0] "Offline – nur zwischengespeicherte Dateien ({n} angeheftet)"
|
||||
msgstr[1] "Offline – nur zwischengespeicherte Dateien ({n} angeheftet)"
|
||||
|
||||
#. Translators: {queued} is a queue summary such as "3 uploads queued".
|
||||
#: crates/pdfs-gui/src/main.rs:319
|
||||
#: crates/pdfs-gui/src/main.rs:337
|
||||
#, rust-format
|
||||
msgid "Offline — {queued}"
|
||||
msgstr "Offline – {queued}"
|
||||
|
||||
#. Translators: a menu item that opens the list of failing changes.
|
||||
#: crates/pdfs-gui/src/main.rs:358
|
||||
#: crates/pdfs-gui/src/main.rs:376
|
||||
#, rust-format
|
||||
msgid "{n} issue — View"
|
||||
msgid_plural "{n} issues — View"
|
||||
msgstr[0] "{n} Problem – Anzeigen"
|
||||
msgstr[1] "{n} Probleme – Anzeigen"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:465
|
||||
#: crates/pdfs-gui/src/main.rs:483
|
||||
msgid "Sign In…"
|
||||
msgstr "Anmelden …"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:466
|
||||
#: crates/pdfs-gui/src/main.rs:484
|
||||
msgid "Sign In Again…"
|
||||
msgstr "Erneut anmelden …"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:469
|
||||
#: crates/pdfs-gui/src/main.rs:487
|
||||
msgid "Open Proton Drive"
|
||||
msgstr "Proton Drive öffnen"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:473
|
||||
#: crates/pdfs-gui/src/main.rs:491
|
||||
msgid "Restart Proton Drive"
|
||||
msgstr "Proton Drive neu starten"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:482
|
||||
#: crates/pdfs-gui/src/main.rs:500
|
||||
msgid "Open Folder"
|
||||
msgstr "Ordner öffnen"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:494
|
||||
#: crates/pdfs-gui/src/main.rs:512
|
||||
msgid "Resume Sync"
|
||||
msgstr "Synchronisierung fortsetzen"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:496
|
||||
#: crates/pdfs-gui/src/main.rs:514
|
||||
msgid "Pause Sync"
|
||||
msgstr "Synchronisierung pausieren"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:515
|
||||
#: crates/pdfs-gui/src/main.rs:533
|
||||
msgid "Connect"
|
||||
msgstr "Verbinden"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:522
|
||||
#: crates/pdfs-gui/src/main.rs:540
|
||||
msgid "Hide Tray Icon"
|
||||
msgstr "Symbol im Benachrichtigungsfeld ausblenden"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:526
|
||||
#: crates/pdfs-gui/src/main.rs:544
|
||||
msgid "Stop Proton Drive…"
|
||||
msgstr "Proton Drive beenden …"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:530
|
||||
#: crates/pdfs-gui/src/main.rs:548
|
||||
msgid "Quit"
|
||||
msgstr "Beenden"
|
||||
|
||||
|
||||
+139
-110
@@ -5,7 +5,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: proton-drive-linux 2.1.0\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/narrrl/proton-drive-linux/issues\n"
|
||||
"POT-Creation-Date: 2026-10-26 22:26+0100\n"
|
||||
"POT-Creation-Date: 2026-10-31 19:26+0100\n"
|
||||
"PO-Revision-Date: 2026-09-23 12:00+0200\n"
|
||||
"Last-Translator: Proton Drive for Linux contributors\n"
|
||||
"Language-Team: English (United Kingdom)\n"
|
||||
@@ -245,13 +245,13 @@ msgstr ""
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1917
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2039
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2540
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:804
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:957
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:995
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1047
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1091
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1131
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1194
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:826
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:979
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1017
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1069
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1113
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1153
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1216
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:850
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1054
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1537
|
||||
@@ -346,7 +346,7 @@ msgstr "Grid / list"
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:298
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1896
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1918
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:996
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1018
|
||||
#: crates/pdfs-gui/src/app/widgets/details.rs:161
|
||||
msgid "Rename"
|
||||
msgstr "Rename"
|
||||
@@ -420,14 +420,27 @@ msgstr "Not connected"
|
||||
msgid "The Proton Drive service isn't running."
|
||||
msgstr "The Proton Drive service isn't running."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1803
|
||||
#: crates/pdfs-gui/src/app/main.rs:1813
|
||||
msgid "Can't open your Drive"
|
||||
msgstr "Can't open your Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1816
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"The Proton Drive service keeps failing to start and tries again on its own. "
|
||||
"The last error was: {error}"
|
||||
msgstr ""
|
||||
"The Proton Drive service keeps failing to start and tries again on its own. "
|
||||
"The last error was: {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1824
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:355
|
||||
#: crates/pdfs-gui/src/hud/mod.rs:269 crates/pdfs-gui/src/hud/mod.rs:579
|
||||
#: crates/pdfs-gui/src/main.rs:475 crates/pdfs-gui/src/main.rs:517
|
||||
#: crates/pdfs-gui/src/main.rs:493 crates/pdfs-gui/src/main.rs:535
|
||||
msgid "Connecting…"
|
||||
msgstr "Connecting…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1804
|
||||
#: crates/pdfs-gui/src/app/main.rs:1825
|
||||
msgid "Waiting for the Proton Drive service to start."
|
||||
msgstr "Waiting for the Proton Drive service to start."
|
||||
|
||||
@@ -674,7 +687,7 @@ msgid "Couldn't add a sync folder"
|
||||
msgstr "Couldn't add a sync folder"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/activity_text.rs:58
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:839
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:861
|
||||
msgid "Couldn't restore folders"
|
||||
msgstr "Couldn't restore folders"
|
||||
|
||||
@@ -1262,12 +1275,12 @@ msgstr "Couldn't load albums"
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1873
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2500
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2650
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:707
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:747
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:900
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1170
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1231
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1260
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:729
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:769
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:922
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1192
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1253
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1282
|
||||
#: crates/pdfs-gui/src/app/pages/duplicates.rs:221
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:577
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:824
|
||||
@@ -1910,7 +1923,7 @@ msgid "{status}. {message}"
|
||||
msgstr "{status}. {message}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1900
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:989
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1011
|
||||
msgid "New name"
|
||||
msgstr "New name"
|
||||
|
||||
@@ -1935,7 +1948,7 @@ msgstr "Choose the folder to move into."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1989
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1994
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1195
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1217
|
||||
msgid "Move Here"
|
||||
msgstr "Move Here"
|
||||
|
||||
@@ -2256,76 +2269,87 @@ msgid_plural "{n} folders backed up"
|
||||
msgstr[0] "{n} folder backed up"
|
||||
msgstr[1] "{n} folders backed up"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:608
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:607
|
||||
#, rust-format
|
||||
msgid "{folders} · {n} waiting for its first sync"
|
||||
msgid_plural "{folders} · {n} waiting for their first sync"
|
||||
msgstr[0] "{folders} · {n} waiting for its first sync"
|
||||
msgstr[1] "{folders} · {n} waiting for their first sync"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:621
|
||||
#, rust-format
|
||||
msgid "{folders} · {n} needs attention"
|
||||
msgid_plural "{folders} · {n} need attention"
|
||||
msgstr[0] "{folders} · {n} needs attention"
|
||||
msgstr[1] "{folders} · {n} need attention"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:619
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:640
|
||||
msgid "syncing…"
|
||||
msgstr "syncing…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:620
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:641
|
||||
msgid "sync error"
|
||||
msgstr "sync error"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:621
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:642
|
||||
msgid "needs attention"
|
||||
msgstr "needs attention"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:622
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:643
|
||||
msgid "waiting for first sync"
|
||||
msgstr "waiting for first sync"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:644
|
||||
msgid "up to date"
|
||||
msgstr "up to date"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:632
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:654
|
||||
msgid "checking for changes…"
|
||||
msgstr "checking for changes…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:638
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:660
|
||||
#, rust-format
|
||||
msgid "checking for changes — {n} item checked"
|
||||
msgid_plural "checking for changes — {n} items checked"
|
||||
msgstr[0] "checking for changes — {n} item checked"
|
||||
msgstr[1] "checking for changes — {n} items checked"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:645
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:667
|
||||
#, rust-format
|
||||
msgid "checking for changes — {done} of {total}"
|
||||
msgstr "checking for changes — {done} of {total}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:657
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:679
|
||||
#, rust-format
|
||||
msgid "syncing {done} of {total}"
|
||||
msgstr "syncing {done} of {total}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:663
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:685
|
||||
#, rust-format
|
||||
msgid "syncing {file} — {done} of {total}"
|
||||
msgstr "syncing {file} — {done} of {total}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:675
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:697
|
||||
msgid "Add Folder to Sync"
|
||||
msgstr "Add Folder to Sync"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:699
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:721
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1559
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1686
|
||||
msgid "Syncing folder…"
|
||||
msgstr "Syncing folder…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:702
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:706
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:724
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:728
|
||||
msgid "Couldn't add folder"
|
||||
msgstr "Couldn't add folder"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:740
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:746
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:762
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:768
|
||||
msgid "Couldn't list folders to restore"
|
||||
msgstr "Couldn't list folders to restore"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:772
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:794
|
||||
msgid ""
|
||||
"Tick the folders to sync to this machine, and adjust where each one should "
|
||||
"live."
|
||||
@@ -2333,19 +2357,19 @@ msgstr ""
|
||||
"Tick the folders to sync to this machine, and adjust where each one should "
|
||||
"live."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:798
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:820
|
||||
msgid "Restore Folders"
|
||||
msgstr "Restore Folders"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:805
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:827
|
||||
msgid "Restore"
|
||||
msgstr "Restore"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:838
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:860
|
||||
msgid "Restoring folders…"
|
||||
msgstr "Restoring folders…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:850
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:872
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"These folders are backed up from “{name}”. Restored folders keep syncing "
|
||||
@@ -2354,33 +2378,33 @@ msgstr ""
|
||||
"These folders are backed up from “{name}”. Restored folders keep syncing "
|
||||
"with that computer's copy."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:853
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:875
|
||||
msgid "These folders are backed up under this computer in Proton Drive."
|
||||
msgstr "These folders are backed up under this computer in Proton Drive."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:862
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:884
|
||||
#, rust-format
|
||||
msgid "Nothing to restore — “{name}”'s folders are all synced here."
|
||||
msgstr "Nothing to restore — “{name}”'s folders are all synced here."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:865
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:887
|
||||
msgid "Nothing to restore — this computer's folders are all synced here."
|
||||
msgstr "Nothing to restore — this computer's folders are all synced here."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:889
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:911
|
||||
msgid "Folder will switch to online only"
|
||||
msgstr "Folder will switch to online only"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:891
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:913
|
||||
msgid "Folder will download and stay synced"
|
||||
msgstr "Folder will download and stay synced"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:895
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:899
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:917
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:921
|
||||
msgid "Couldn't change mode"
|
||||
msgstr "Couldn't change mode"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:931
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:953
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"Stop syncing “{path}”?\n"
|
||||
@@ -2397,7 +2421,7 @@ msgstr ""
|
||||
"copy, cancel, switch the folder to Synced, and wait for the download to "
|
||||
"finish before removing it."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:937
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:959
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"Stop syncing “{path}”?\n"
|
||||
@@ -2410,68 +2434,68 @@ msgstr ""
|
||||
"The local files stay on this disk and simply stop being synced. Choose "
|
||||
"whether to also delete the copy in Proton Drive."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:942
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:964
|
||||
msgid "Stop Syncing Folder?"
|
||||
msgstr "Stop Syncing Folder?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:947
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:969
|
||||
msgid "Also delete from Proton Drive"
|
||||
msgstr "Also delete from Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:949
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:971
|
||||
msgid "Deletes the only copy of these files."
|
||||
msgstr "Deletes the only copy of these files."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:951
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:973
|
||||
msgid "The local copy is unaffected."
|
||||
msgstr "The local copy is unaffected."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:958
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:980
|
||||
msgid "Stop Syncing"
|
||||
msgstr "Stop Syncing"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:971
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:993
|
||||
msgid "Stopped syncing folder"
|
||||
msgstr "Stopped syncing folder"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:972
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:994
|
||||
msgid "Couldn't stop syncing the folder"
|
||||
msgstr "Couldn't stop syncing the folder"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:983
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1005
|
||||
msgid "Rename Computer"
|
||||
msgstr "Rename Computer"
|
||||
|
||||
#. Translators: {name} is the computer's current name.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:985
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1007
|
||||
#, rust-format
|
||||
msgid "Rename “{name}”."
|
||||
msgstr "Rename “{name}”."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1010
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1022
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1032
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1044
|
||||
msgid "Couldn't rename the computer"
|
||||
msgstr "Couldn't rename the computer"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1011
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1033
|
||||
msgid "A name is required."
|
||||
msgstr "A name is required."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1021
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1043
|
||||
msgid "Computer renamed"
|
||||
msgstr "Computer renamed"
|
||||
|
||||
#. Translators: {name} is the computer's name, which the user must type.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1034
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1056
|
||||
#, rust-format
|
||||
msgid "Type “{name}” to confirm"
|
||||
msgstr "Type “{name}” to confirm"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1039
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1061
|
||||
msgid "Remove Computer?"
|
||||
msgstr "Remove Computer?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1042
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1064
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"Remove “{name}” from this account?\n"
|
||||
@@ -2486,26 +2510,26 @@ msgstr ""
|
||||
"on that computer itself are not touched — but this cannot be undone from "
|
||||
"here."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1048
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1070
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1025
|
||||
#: crates/pdfs-gui/src/app/widgets/share_dialog.rs:634
|
||||
#: crates/pdfs-gui/src/app/widgets/share_dialog.rs:876
|
||||
msgid "Remove"
|
||||
msgstr "Remove"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1065
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1087
|
||||
msgid "Computer removed"
|
||||
msgstr "Computer removed"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1066
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1088
|
||||
msgid "Couldn't remove the computer"
|
||||
msgstr "Couldn't remove the computer"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1084
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1106
|
||||
msgid "Continue This Backup Here?"
|
||||
msgstr "Continue This Backup Here?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1087
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1109
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"This computer takes over the backup of “{name}”, for example after a "
|
||||
@@ -2524,25 +2548,25 @@ msgstr ""
|
||||
"“Restore to This Computer” afterwards to bring back what “{name}” was "
|
||||
"syncing."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1092
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1114
|
||||
msgid "Continue Here"
|
||||
msgstr "Continue Here"
|
||||
|
||||
#. Translators: {name} is the name of the computer whose backup this one took over.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1099
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1121
|
||||
#, rust-format
|
||||
msgid "Now backing up as “{name}”"
|
||||
msgstr "Now backing up as “{name}”"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1108
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1130
|
||||
msgid "Couldn't continue that backup here"
|
||||
msgstr "Couldn't continue that backup here"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1124
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1146
|
||||
msgid "Sync With This Computer?"
|
||||
msgstr "Sync With This Computer?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1127
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1149
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"This computer and “{name}” keep the same folders in step. A change or a "
|
||||
@@ -2559,25 +2583,25 @@ msgstr ""
|
||||
"Folders already synced here stay where they are. Next you choose which of "
|
||||
"its folders to sync here."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1132
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1154
|
||||
msgid "Sync Here"
|
||||
msgstr "Sync Here"
|
||||
|
||||
#. Translators: {name} is the name of the other computer this one now syncs with.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1139
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1161
|
||||
#, rust-format
|
||||
msgid "Now syncing with “{name}”"
|
||||
msgstr "Now syncing with “{name}”"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1155
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1177
|
||||
msgid "Couldn't sync with that computer"
|
||||
msgstr "Couldn't sync with that computer"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1187
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1209
|
||||
msgid "Move Backup to This Computer?"
|
||||
msgstr "Move Backup to This Computer?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1190
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1212
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"The folders backed up by “{name}” move into this computer's backup in Proton "
|
||||
@@ -2593,12 +2617,12 @@ msgstr ""
|
||||
"Stop Proton Drive on “{name}” first. Otherwise it sees its folders disappear."
|
||||
|
||||
#. Translators: {name} is the name of the computer whose folders moved to this one.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1202
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1224
|
||||
#, rust-format
|
||||
msgid "Moved the backup of “{name}”"
|
||||
msgstr "Moved the backup of “{name}”"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1216
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1238
|
||||
msgid "Couldn't move that backup"
|
||||
msgstr "Couldn't move that backup"
|
||||
|
||||
@@ -2869,7 +2893,7 @@ msgid "Sync paused until you resume"
|
||||
msgstr "Sync paused until you resume"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:570
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1445 crates/pdfs-gui/src/main.rs:290
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1445 crates/pdfs-gui/src/main.rs:308
|
||||
msgid "Sync paused"
|
||||
msgstr "Sync paused"
|
||||
|
||||
@@ -3321,7 +3345,7 @@ msgid "paused"
|
||||
msgstr "paused"
|
||||
|
||||
#. Translators: a folder's files can't be opened right now.
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1742
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1745
|
||||
msgid "not available"
|
||||
msgstr "not available"
|
||||
|
||||
@@ -5035,7 +5059,7 @@ msgstr "Resumes {time}"
|
||||
msgid "Until you resume"
|
||||
msgstr "Until you resume"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1464 crates/pdfs-gui/src/main.rs:292
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1464 crates/pdfs-gui/src/main.rs:310
|
||||
#, rust-format
|
||||
msgid "{n} change needs attention"
|
||||
msgid_plural "{n} changes need attention"
|
||||
@@ -6246,52 +6270,57 @@ msgstr "Proton Drive isn't responding"
|
||||
msgid "Signed in as {username} — locked"
|
||||
msgstr "Signed in as {username} — locked"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:200
|
||||
#: crates/pdfs-gui/src/main.rs:209
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — can't open your Drive"
|
||||
msgstr "Signed in as {username} — can't open your Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:218
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — not connected"
|
||||
msgstr "Signed in as {username} — not connected"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:205
|
||||
#: crates/pdfs-gui/src/main.rs:223
|
||||
msgid "Not signed in"
|
||||
msgstr "Not signed in"
|
||||
|
||||
#. Translators: {error} is an error message, in English.
|
||||
#: crates/pdfs-gui/src/main.rs:208
|
||||
#: crates/pdfs-gui/src/main.rs:226
|
||||
#, rust-format
|
||||
msgid "Error: {error}"
|
||||
msgstr "Error: {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:230
|
||||
#: crates/pdfs-gui/src/main.rs:248
|
||||
msgid "Proton Drive sent an unexpected reply"
|
||||
msgstr "Proton Drive sent an unexpected reply"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:284
|
||||
#: crates/pdfs-gui/src/main.rs:302
|
||||
msgid "Session expired — sign in again"
|
||||
msgstr "Session expired — sign in again"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:286
|
||||
#: crates/pdfs-gui/src/main.rs:304
|
||||
msgid "Sign-in not saved — unlock your keyring"
|
||||
msgstr "Sign-in not saved — unlock your keyring"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:289
|
||||
#: crates/pdfs-gui/src/main.rs:307
|
||||
msgid "Update not finished — restart Proton Drive"
|
||||
msgstr "Update not finished — restart Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:299
|
||||
#: crates/pdfs-gui/src/main.rs:317
|
||||
#, rust-format
|
||||
msgid "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgid_plural "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgstr[0] "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgstr[1] "Up to date in {mountpoint} ({n} pinned)"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:306
|
||||
#: crates/pdfs-gui/src/main.rs:324
|
||||
#, rust-format
|
||||
msgid "Syncing — {queued} ({n} pinned)"
|
||||
msgid_plural "Syncing — {queued} ({n} pinned)"
|
||||
msgstr[0] "Syncing — {queued} ({n} pinned)"
|
||||
msgstr[1] "Syncing — {queued} ({n} pinned)"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:313
|
||||
#: crates/pdfs-gui/src/main.rs:331
|
||||
#, rust-format
|
||||
msgid "Offline — cached files only ({n} pinned)"
|
||||
msgid_plural "Offline — cached files only ({n} pinned)"
|
||||
@@ -6299,60 +6328,60 @@ msgstr[0] "Offline — cached files only ({n} pinned)"
|
||||
msgstr[1] "Offline — cached files only ({n} pinned)"
|
||||
|
||||
#. Translators: {queued} is a queue summary such as "3 uploads queued".
|
||||
#: crates/pdfs-gui/src/main.rs:319
|
||||
#: crates/pdfs-gui/src/main.rs:337
|
||||
#, rust-format
|
||||
msgid "Offline — {queued}"
|
||||
msgstr "Offline — {queued}"
|
||||
|
||||
#. Translators: a menu item that opens the list of failing changes.
|
||||
#: crates/pdfs-gui/src/main.rs:358
|
||||
#: crates/pdfs-gui/src/main.rs:376
|
||||
#, rust-format
|
||||
msgid "{n} issue — View"
|
||||
msgid_plural "{n} issues — View"
|
||||
msgstr[0] "{n} issue — View"
|
||||
msgstr[1] "{n} issues — View"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:465
|
||||
#: crates/pdfs-gui/src/main.rs:483
|
||||
msgid "Sign In…"
|
||||
msgstr "Sign In…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:466
|
||||
#: crates/pdfs-gui/src/main.rs:484
|
||||
msgid "Sign In Again…"
|
||||
msgstr "Sign In Again…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:469
|
||||
#: crates/pdfs-gui/src/main.rs:487
|
||||
msgid "Open Proton Drive"
|
||||
msgstr "Open Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:473
|
||||
#: crates/pdfs-gui/src/main.rs:491
|
||||
msgid "Restart Proton Drive"
|
||||
msgstr "Restart Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:482
|
||||
#: crates/pdfs-gui/src/main.rs:500
|
||||
msgid "Open Folder"
|
||||
msgstr "Open Folder"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:494
|
||||
#: crates/pdfs-gui/src/main.rs:512
|
||||
msgid "Resume Sync"
|
||||
msgstr "Resume Sync"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:496
|
||||
#: crates/pdfs-gui/src/main.rs:514
|
||||
msgid "Pause Sync"
|
||||
msgstr "Pause Sync"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:515
|
||||
#: crates/pdfs-gui/src/main.rs:533
|
||||
msgid "Connect"
|
||||
msgstr "Connect"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:522
|
||||
#: crates/pdfs-gui/src/main.rs:540
|
||||
msgid "Hide Tray Icon"
|
||||
msgstr "Hide Tray Icon"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:526
|
||||
#: crates/pdfs-gui/src/main.rs:544
|
||||
msgid "Stop Proton Drive…"
|
||||
msgstr "Stop Proton Drive…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:530
|
||||
#: crates/pdfs-gui/src/main.rs:548
|
||||
msgid "Quit"
|
||||
msgstr "Quit"
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: proton-drive-linux 2.1.0\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/narrrl/proton-drive-linux/issues\n"
|
||||
"POT-Creation-Date: 2026-10-26 22:26+0100\n"
|
||||
"POT-Creation-Date: 2026-10-31 19:26+0100\n"
|
||||
"PO-Revision-Date: 2026-09-23 12:00+0200\n"
|
||||
"Last-Translator: Proton Drive for Linux contributors\n"
|
||||
"Language-Team: Spanish\n"
|
||||
@@ -247,13 +247,13 @@ msgstr ""
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1917
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2039
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2540
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:804
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:957
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:995
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1047
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1091
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1131
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1194
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:826
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:979
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1017
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1069
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1113
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1153
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1216
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:850
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1054
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1537
|
||||
@@ -348,7 +348,7 @@ msgstr "Cuadrícula / lista"
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:298
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1896
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1918
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:996
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1018
|
||||
#: crates/pdfs-gui/src/app/widgets/details.rs:161
|
||||
msgid "Rename"
|
||||
msgstr "Renombrar"
|
||||
@@ -422,14 +422,27 @@ msgstr "Sin conexión"
|
||||
msgid "The Proton Drive service isn't running."
|
||||
msgstr "El servicio de Proton Drive no está en ejecución."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1803
|
||||
#: crates/pdfs-gui/src/app/main.rs:1813
|
||||
msgid "Can't open your Drive"
|
||||
msgstr "No se puede abrir Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1816
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"The Proton Drive service keeps failing to start and tries again on its own. "
|
||||
"The last error was: {error}"
|
||||
msgstr ""
|
||||
"El servicio de Proton Drive no consigue iniciarse y vuelve a intentarlo por "
|
||||
"sí solo. Último error: {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1824
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:355
|
||||
#: crates/pdfs-gui/src/hud/mod.rs:269 crates/pdfs-gui/src/hud/mod.rs:579
|
||||
#: crates/pdfs-gui/src/main.rs:475 crates/pdfs-gui/src/main.rs:517
|
||||
#: crates/pdfs-gui/src/main.rs:493 crates/pdfs-gui/src/main.rs:535
|
||||
msgid "Connecting…"
|
||||
msgstr "Conectando…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1804
|
||||
#: crates/pdfs-gui/src/app/main.rs:1825
|
||||
msgid "Waiting for the Proton Drive service to start."
|
||||
msgstr "Esperando a que se inicie el servicio de Proton Drive."
|
||||
|
||||
@@ -679,7 +692,7 @@ msgid "Couldn't add a sync folder"
|
||||
msgstr "No se pudo añadir una carpeta sincronizada"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/activity_text.rs:58
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:839
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:861
|
||||
msgid "Couldn't restore folders"
|
||||
msgstr "No se pudieron restaurar las carpetas"
|
||||
|
||||
@@ -1268,12 +1281,12 @@ msgstr "No se pudieron cargar los álbumes"
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1873
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2500
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2650
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:707
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:747
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:900
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1170
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1231
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1260
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:729
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:769
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:922
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1192
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1253
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1282
|
||||
#: crates/pdfs-gui/src/app/pages/duplicates.rs:221
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:577
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:824
|
||||
@@ -1921,7 +1934,7 @@ msgid "{status}. {message}"
|
||||
msgstr "{status}. {message}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1900
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:989
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1011
|
||||
msgid "New name"
|
||||
msgstr "Nombre nuevo"
|
||||
|
||||
@@ -1946,7 +1959,7 @@ msgstr "Elija la carpeta de destino."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1989
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1994
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1195
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1217
|
||||
msgid "Move Here"
|
||||
msgstr "Mover aquí"
|
||||
|
||||
@@ -2268,76 +2281,87 @@ msgid_plural "{n} folders backed up"
|
||||
msgstr[0] "{n} carpeta con copia de seguridad"
|
||||
msgstr[1] "{n} carpetas con copia de seguridad"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:608
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:607
|
||||
#, rust-format
|
||||
msgid "{folders} · {n} waiting for its first sync"
|
||||
msgid_plural "{folders} · {n} waiting for their first sync"
|
||||
msgstr[0] "{folders} · {n} espera su primera sincronización"
|
||||
msgstr[1] "{folders} · {n} esperan su primera sincronización"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:621
|
||||
#, rust-format
|
||||
msgid "{folders} · {n} needs attention"
|
||||
msgid_plural "{folders} · {n} need attention"
|
||||
msgstr[0] "{folders} · {n} requiere atención"
|
||||
msgstr[1] "{folders} · {n} requieren atención"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:619
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:640
|
||||
msgid "syncing…"
|
||||
msgstr "sincronizando…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:620
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:641
|
||||
msgid "sync error"
|
||||
msgstr "error de sincronización"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:621
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:642
|
||||
msgid "needs attention"
|
||||
msgstr "requiere atención"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:622
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:643
|
||||
msgid "waiting for first sync"
|
||||
msgstr "esperando la primera sincronización"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:644
|
||||
msgid "up to date"
|
||||
msgstr "actualizado"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:632
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:654
|
||||
msgid "checking for changes…"
|
||||
msgstr "buscando cambios…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:638
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:660
|
||||
#, rust-format
|
||||
msgid "checking for changes — {n} item checked"
|
||||
msgid_plural "checking for changes — {n} items checked"
|
||||
msgstr[0] "buscando cambios: {n} elemento revisado"
|
||||
msgstr[1] "buscando cambios: {n} elementos revisados"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:645
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:667
|
||||
#, rust-format
|
||||
msgid "checking for changes — {done} of {total}"
|
||||
msgstr "buscando cambios: {done} de {total}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:657
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:679
|
||||
#, rust-format
|
||||
msgid "syncing {done} of {total}"
|
||||
msgstr "sincronizando {done} de {total}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:663
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:685
|
||||
#, rust-format
|
||||
msgid "syncing {file} — {done} of {total}"
|
||||
msgstr "sincronizando {file}: {done} de {total}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:675
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:697
|
||||
msgid "Add Folder to Sync"
|
||||
msgstr "Añadir carpeta para sincronizar"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:699
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:721
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1559
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1686
|
||||
msgid "Syncing folder…"
|
||||
msgstr "Sincronizando la carpeta…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:702
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:706
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:724
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:728
|
||||
msgid "Couldn't add folder"
|
||||
msgstr "No se pudo añadir la carpeta"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:740
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:746
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:762
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:768
|
||||
msgid "Couldn't list folders to restore"
|
||||
msgstr "No se pudieron listar las carpetas para restaurar"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:772
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:794
|
||||
msgid ""
|
||||
"Tick the folders to sync to this machine, and adjust where each one should "
|
||||
"live."
|
||||
@@ -2345,19 +2369,19 @@ msgstr ""
|
||||
"Marque las carpetas que sincronizar con esta máquina y ajuste dónde debe "
|
||||
"estar cada una."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:798
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:820
|
||||
msgid "Restore Folders"
|
||||
msgstr "Restaurar carpetas"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:805
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:827
|
||||
msgid "Restore"
|
||||
msgstr "Restaurar"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:838
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:860
|
||||
msgid "Restoring folders…"
|
||||
msgstr "Restaurando carpetas…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:850
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:872
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"These folders are backed up from “{name}”. Restored folders keep syncing "
|
||||
@@ -2366,36 +2390,36 @@ msgstr ""
|
||||
"Estas carpetas tienen copia de seguridad desde “{name}”. Las carpetas "
|
||||
"restauradas siguen sincronizándose con la copia de ese equipo."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:853
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:875
|
||||
msgid "These folders are backed up under this computer in Proton Drive."
|
||||
msgstr ""
|
||||
"Estas carpetas tienen copia de seguridad bajo este equipo en Proton Drive."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:862
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:884
|
||||
#, rust-format
|
||||
msgid "Nothing to restore — “{name}”'s folders are all synced here."
|
||||
msgstr ""
|
||||
"Nada que restaurar: todas las carpetas de “{name}” ya se sincronizan aquí."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:865
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:887
|
||||
msgid "Nothing to restore — this computer's folders are all synced here."
|
||||
msgstr ""
|
||||
"Nada que restaurar: todas las carpetas de este equipo ya se sincronizan aquí."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:889
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:911
|
||||
msgid "Folder will switch to online only"
|
||||
msgstr "La carpeta pasará a solo en línea"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:891
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:913
|
||||
msgid "Folder will download and stay synced"
|
||||
msgstr "La carpeta se descargará y permanecerá sincronizada"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:895
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:899
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:917
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:921
|
||||
msgid "Couldn't change mode"
|
||||
msgstr "No se pudo cambiar el modo"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:931
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:953
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"Stop syncing “{path}”?\n"
|
||||
@@ -2412,7 +2436,7 @@ msgstr ""
|
||||
"Para conservar una copia local, cancele, cambie la carpeta a Sincronizada y "
|
||||
"espere a que termine la descarga antes de quitarla."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:937
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:959
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"Stop syncing “{path}”?\n"
|
||||
@@ -2425,68 +2449,68 @@ msgstr ""
|
||||
"Los archivos locales permanecen en este disco y simplemente dejan de "
|
||||
"sincronizarse. Elija si quiere eliminar también la copia en Proton Drive."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:942
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:964
|
||||
msgid "Stop Syncing Folder?"
|
||||
msgstr "¿Dejar de sincronizar la carpeta?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:947
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:969
|
||||
msgid "Also delete from Proton Drive"
|
||||
msgstr "Eliminar también de Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:949
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:971
|
||||
msgid "Deletes the only copy of these files."
|
||||
msgstr "Elimina la única copia de estos archivos."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:951
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:973
|
||||
msgid "The local copy is unaffected."
|
||||
msgstr "La copia local no se ve afectada."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:958
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:980
|
||||
msgid "Stop Syncing"
|
||||
msgstr "Dejar de sincronizar"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:971
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:993
|
||||
msgid "Stopped syncing folder"
|
||||
msgstr "Se dejó de sincronizar la carpeta"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:972
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:994
|
||||
msgid "Couldn't stop syncing the folder"
|
||||
msgstr "No se pudo dejar de sincronizar la carpeta"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:983
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1005
|
||||
msgid "Rename Computer"
|
||||
msgstr "Renombrar equipo"
|
||||
|
||||
#. Translators: {name} is the computer's current name.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:985
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1007
|
||||
#, rust-format
|
||||
msgid "Rename “{name}”."
|
||||
msgstr "Renombrar “{name}”."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1010
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1022
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1032
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1044
|
||||
msgid "Couldn't rename the computer"
|
||||
msgstr "No se pudo renombrar el equipo"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1011
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1033
|
||||
msgid "A name is required."
|
||||
msgstr "Se necesita un nombre."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1021
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1043
|
||||
msgid "Computer renamed"
|
||||
msgstr "Equipo renombrado"
|
||||
|
||||
#. Translators: {name} is the computer's name, which the user must type.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1034
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1056
|
||||
#, rust-format
|
||||
msgid "Type “{name}” to confirm"
|
||||
msgstr "Escriba “{name}” para confirmar"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1039
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1061
|
||||
msgid "Remove Computer?"
|
||||
msgstr "¿Quitar el equipo?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1042
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1064
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"Remove “{name}” from this account?\n"
|
||||
@@ -2500,26 +2524,26 @@ msgstr ""
|
||||
"Todo lo que respaldó en Proton Drive se eliminará con él. Los archivos de "
|
||||
"ese equipo no se tocan, pero esto no se puede deshacer desde aquí."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1048
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1070
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1025
|
||||
#: crates/pdfs-gui/src/app/widgets/share_dialog.rs:634
|
||||
#: crates/pdfs-gui/src/app/widgets/share_dialog.rs:876
|
||||
msgid "Remove"
|
||||
msgstr "Quitar"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1065
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1087
|
||||
msgid "Computer removed"
|
||||
msgstr "Equipo quitado"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1066
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1088
|
||||
msgid "Couldn't remove the computer"
|
||||
msgstr "No se pudo quitar el equipo"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1084
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1106
|
||||
msgid "Continue This Backup Here?"
|
||||
msgstr "¿Continuar esta copia de seguridad aquí?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1087
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1109
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"This computer takes over the backup of “{name}”, for example after a "
|
||||
@@ -2538,25 +2562,25 @@ msgstr ""
|
||||
"no se mueven. Después, use “Restaurar en este equipo” para recuperar lo que "
|
||||
"“{name}” sincronizaba."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1092
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1114
|
||||
msgid "Continue Here"
|
||||
msgstr "Continuar aquí"
|
||||
|
||||
#. Translators: {name} is the name of the computer whose backup this one took over.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1099
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1121
|
||||
#, rust-format
|
||||
msgid "Now backing up as “{name}”"
|
||||
msgstr "Ahora se hace copia de seguridad como “{name}”"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1108
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1130
|
||||
msgid "Couldn't continue that backup here"
|
||||
msgstr "No se pudo continuar esa copia de seguridad aquí"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1124
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1146
|
||||
msgid "Sync With This Computer?"
|
||||
msgstr "¿Sincronizar con este equipo?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1127
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1149
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"This computer and “{name}” keep the same folders in step. A change or a "
|
||||
@@ -2573,25 +2597,25 @@ msgstr ""
|
||||
"Proton Drive. Las carpetas ya sincronizadas aquí se quedan donde están. A "
|
||||
"continuación, elija qué carpetas suyas sincronizar aquí."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1132
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1154
|
||||
msgid "Sync Here"
|
||||
msgstr "Sincronizar aquí"
|
||||
|
||||
#. Translators: {name} is the name of the other computer this one now syncs with.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1139
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1161
|
||||
#, rust-format
|
||||
msgid "Now syncing with “{name}”"
|
||||
msgstr "Ahora se sincroniza con “{name}”"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1155
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1177
|
||||
msgid "Couldn't sync with that computer"
|
||||
msgstr "No se pudo sincronizar con ese equipo"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1187
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1209
|
||||
msgid "Move Backup to This Computer?"
|
||||
msgstr "¿Mover la copia de seguridad a este equipo?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1190
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1212
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"The folders backed up by “{name}” move into this computer's backup in Proton "
|
||||
@@ -2608,12 +2632,12 @@ msgstr ""
|
||||
"carpetas."
|
||||
|
||||
#. Translators: {name} is the name of the computer whose folders moved to this one.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1202
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1224
|
||||
#, rust-format
|
||||
msgid "Moved the backup of “{name}”"
|
||||
msgstr "Se movió la copia de seguridad de “{name}”"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1216
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1238
|
||||
msgid "Couldn't move that backup"
|
||||
msgstr "No se pudo mover esa copia de seguridad"
|
||||
|
||||
@@ -2891,7 +2915,7 @@ msgid "Sync paused until you resume"
|
||||
msgstr "Sincronización en pausa hasta que la reanude"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:570
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1445 crates/pdfs-gui/src/main.rs:290
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1445 crates/pdfs-gui/src/main.rs:308
|
||||
msgid "Sync paused"
|
||||
msgstr "Sincronización en pausa"
|
||||
|
||||
@@ -3348,7 +3372,7 @@ msgid "paused"
|
||||
msgstr "en pausa"
|
||||
|
||||
#. Translators: a folder's files can't be opened right now.
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1742
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1745
|
||||
msgid "not available"
|
||||
msgstr "no disponible"
|
||||
|
||||
@@ -5095,7 +5119,7 @@ msgstr "Se reanuda {time}"
|
||||
msgid "Until you resume"
|
||||
msgstr "Hasta que la reanude"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1464 crates/pdfs-gui/src/main.rs:292
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1464 crates/pdfs-gui/src/main.rs:310
|
||||
#, rust-format
|
||||
msgid "{n} change needs attention"
|
||||
msgid_plural "{n} changes need attention"
|
||||
@@ -6327,52 +6351,57 @@ msgstr "Proton Drive no responde"
|
||||
msgid "Signed in as {username} — locked"
|
||||
msgstr "Sesión iniciada como {username} — bloqueado"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:200
|
||||
#: crates/pdfs-gui/src/main.rs:209
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — can't open your Drive"
|
||||
msgstr "Sesión iniciada como {username} — no se puede abrir Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:218
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — not connected"
|
||||
msgstr "Sesión iniciada como {username} — sin conexión"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:205
|
||||
#: crates/pdfs-gui/src/main.rs:223
|
||||
msgid "Not signed in"
|
||||
msgstr "Sesión no iniciada"
|
||||
|
||||
#. Translators: {error} is an error message, in English.
|
||||
#: crates/pdfs-gui/src/main.rs:208
|
||||
#: crates/pdfs-gui/src/main.rs:226
|
||||
#, rust-format
|
||||
msgid "Error: {error}"
|
||||
msgstr "Error: {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:230
|
||||
#: crates/pdfs-gui/src/main.rs:248
|
||||
msgid "Proton Drive sent an unexpected reply"
|
||||
msgstr "Proton Drive envió una respuesta inesperada"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:284
|
||||
#: crates/pdfs-gui/src/main.rs:302
|
||||
msgid "Session expired — sign in again"
|
||||
msgstr "Sesión caducada: vuelva a iniciar sesión"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:286
|
||||
#: crates/pdfs-gui/src/main.rs:304
|
||||
msgid "Sign-in not saved — unlock your keyring"
|
||||
msgstr "Inicio de sesión no guardado: desbloquee el depósito de claves"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:289
|
||||
#: crates/pdfs-gui/src/main.rs:307
|
||||
msgid "Update not finished — restart Proton Drive"
|
||||
msgstr "Actualización sin terminar: reinicie Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:299
|
||||
#: crates/pdfs-gui/src/main.rs:317
|
||||
#, rust-format
|
||||
msgid "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgid_plural "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgstr[0] "Actualizado en {mountpoint} ({n} fijado)"
|
||||
msgstr[1] "Actualizado en {mountpoint} ({n} fijados)"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:306
|
||||
#: crates/pdfs-gui/src/main.rs:324
|
||||
#, rust-format
|
||||
msgid "Syncing — {queued} ({n} pinned)"
|
||||
msgid_plural "Syncing — {queued} ({n} pinned)"
|
||||
msgstr[0] "Sincronizando: {queued} ({n} anclado)"
|
||||
msgstr[1] "Sincronizando: {queued} ({n} anclados)"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:313
|
||||
#: crates/pdfs-gui/src/main.rs:331
|
||||
#, rust-format
|
||||
msgid "Offline — cached files only ({n} pinned)"
|
||||
msgid_plural "Offline — cached files only ({n} pinned)"
|
||||
@@ -6380,60 +6409,60 @@ msgstr[0] "Sin conexión: solo archivos en caché ({n} anclado)"
|
||||
msgstr[1] "Sin conexión: solo archivos en caché ({n} anclados)"
|
||||
|
||||
#. Translators: {queued} is a queue summary such as "3 uploads queued".
|
||||
#: crates/pdfs-gui/src/main.rs:319
|
||||
#: crates/pdfs-gui/src/main.rs:337
|
||||
#, rust-format
|
||||
msgid "Offline — {queued}"
|
||||
msgstr "Sin conexión: {queued}"
|
||||
|
||||
#. Translators: a menu item that opens the list of failing changes.
|
||||
#: crates/pdfs-gui/src/main.rs:358
|
||||
#: crates/pdfs-gui/src/main.rs:376
|
||||
#, rust-format
|
||||
msgid "{n} issue — View"
|
||||
msgid_plural "{n} issues — View"
|
||||
msgstr[0] "{n} problema: ver"
|
||||
msgstr[1] "{n} problemas: ver"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:465
|
||||
#: crates/pdfs-gui/src/main.rs:483
|
||||
msgid "Sign In…"
|
||||
msgstr "Iniciar sesión…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:466
|
||||
#: crates/pdfs-gui/src/main.rs:484
|
||||
msgid "Sign In Again…"
|
||||
msgstr "Volver a iniciar sesión…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:469
|
||||
#: crates/pdfs-gui/src/main.rs:487
|
||||
msgid "Open Proton Drive"
|
||||
msgstr "Abrir Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:473
|
||||
#: crates/pdfs-gui/src/main.rs:491
|
||||
msgid "Restart Proton Drive"
|
||||
msgstr "Reiniciar Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:482
|
||||
#: crates/pdfs-gui/src/main.rs:500
|
||||
msgid "Open Folder"
|
||||
msgstr "Abrir carpeta"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:494
|
||||
#: crates/pdfs-gui/src/main.rs:512
|
||||
msgid "Resume Sync"
|
||||
msgstr "Reanudar la sincronización"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:496
|
||||
#: crates/pdfs-gui/src/main.rs:514
|
||||
msgid "Pause Sync"
|
||||
msgstr "Pausar la sincronización"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:515
|
||||
#: crates/pdfs-gui/src/main.rs:533
|
||||
msgid "Connect"
|
||||
msgstr "Conectar"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:522
|
||||
#: crates/pdfs-gui/src/main.rs:540
|
||||
msgid "Hide Tray Icon"
|
||||
msgstr "Ocultar el icono de la bandeja"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:526
|
||||
#: crates/pdfs-gui/src/main.rs:544
|
||||
msgid "Stop Proton Drive…"
|
||||
msgstr "Detener Proton Drive…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:530
|
||||
#: crates/pdfs-gui/src/main.rs:548
|
||||
msgid "Quit"
|
||||
msgstr "Salir"
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: proton-drive-linux 2.1.0\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/narrrl/proton-drive-linux/issues\n"
|
||||
"POT-Creation-Date: 2026-10-26 22:26+0100\n"
|
||||
"POT-Creation-Date: 2026-10-31 19:26+0100\n"
|
||||
"PO-Revision-Date: 2026-09-23 12:00+0200\n"
|
||||
"Last-Translator: Proton Drive for Linux contributors\n"
|
||||
"Language-Team: French\n"
|
||||
@@ -249,13 +249,13 @@ msgstr ""
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1917
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2039
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2540
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:804
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:957
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:995
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1047
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1091
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1131
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1194
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:826
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:979
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1017
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1069
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1113
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1153
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1216
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:850
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1054
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1537
|
||||
@@ -350,7 +350,7 @@ msgstr "Grille / liste"
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:298
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1896
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1918
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:996
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1018
|
||||
#: crates/pdfs-gui/src/app/widgets/details.rs:161
|
||||
msgid "Rename"
|
||||
msgstr "Renommer"
|
||||
@@ -424,14 +424,27 @@ msgstr "Non connecté"
|
||||
msgid "The Proton Drive service isn't running."
|
||||
msgstr "Le service Proton Drive n’est pas en cours d’exécution."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1803
|
||||
#: crates/pdfs-gui/src/app/main.rs:1813
|
||||
msgid "Can't open your Drive"
|
||||
msgstr "Impossible d’ouvrir Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1816
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"The Proton Drive service keeps failing to start and tries again on its own. "
|
||||
"The last error was: {error}"
|
||||
msgstr ""
|
||||
"Le service Proton Drive n’arrive pas à démarrer et réessaie de lui-même. "
|
||||
"Dernière erreur : {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1824
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:355
|
||||
#: crates/pdfs-gui/src/hud/mod.rs:269 crates/pdfs-gui/src/hud/mod.rs:579
|
||||
#: crates/pdfs-gui/src/main.rs:475 crates/pdfs-gui/src/main.rs:517
|
||||
#: crates/pdfs-gui/src/main.rs:493 crates/pdfs-gui/src/main.rs:535
|
||||
msgid "Connecting…"
|
||||
msgstr "Connexion…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1804
|
||||
#: crates/pdfs-gui/src/app/main.rs:1825
|
||||
msgid "Waiting for the Proton Drive service to start."
|
||||
msgstr "En attente du démarrage du service Proton Drive."
|
||||
|
||||
@@ -682,7 +695,7 @@ msgid "Couldn't add a sync folder"
|
||||
msgstr "Impossible d’ajouter un dossier synchronisé"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/activity_text.rs:58
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:839
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:861
|
||||
msgid "Couldn't restore folders"
|
||||
msgstr "Impossible de restaurer les dossiers"
|
||||
|
||||
@@ -1279,12 +1292,12 @@ msgstr "Impossible de charger les albums"
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1873
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2500
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2650
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:707
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:747
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:900
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1170
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1231
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1260
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:729
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:769
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:922
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1192
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1253
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1282
|
||||
#: crates/pdfs-gui/src/app/pages/duplicates.rs:221
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:577
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:824
|
||||
@@ -1933,7 +1946,7 @@ msgid "{status}. {message}"
|
||||
msgstr "{status}. {message}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1900
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:989
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1011
|
||||
msgid "New name"
|
||||
msgstr "Nouveau nom"
|
||||
|
||||
@@ -1958,7 +1971,7 @@ msgstr "Choisissez le dossier de destination."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1989
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1994
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1195
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1217
|
||||
msgid "Move Here"
|
||||
msgstr "Déplacer ici"
|
||||
|
||||
@@ -2281,76 +2294,87 @@ msgid_plural "{n} folders backed up"
|
||||
msgstr[0] "{n} dossier sauvegardé"
|
||||
msgstr[1] "{n} dossiers sauvegardés"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:608
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:607
|
||||
#, rust-format
|
||||
msgid "{folders} · {n} waiting for its first sync"
|
||||
msgid_plural "{folders} · {n} waiting for their first sync"
|
||||
msgstr[0] "{folders} · {n} attend sa première synchronisation"
|
||||
msgstr[1] "{folders} · {n} attendent leur première synchronisation"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:621
|
||||
#, rust-format
|
||||
msgid "{folders} · {n} needs attention"
|
||||
msgid_plural "{folders} · {n} need attention"
|
||||
msgstr[0] "{folders} · {n} requiert votre attention"
|
||||
msgstr[1] "{folders} · {n} requièrent votre attention"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:619
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:640
|
||||
msgid "syncing…"
|
||||
msgstr "synchronisation…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:620
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:641
|
||||
msgid "sync error"
|
||||
msgstr "erreur de synchronisation"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:621
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:642
|
||||
msgid "needs attention"
|
||||
msgstr "attention requise"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:622
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:643
|
||||
msgid "waiting for first sync"
|
||||
msgstr "en attente de la première synchronisation"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:644
|
||||
msgid "up to date"
|
||||
msgstr "à jour"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:632
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:654
|
||||
msgid "checking for changes…"
|
||||
msgstr "recherche de modifications…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:638
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:660
|
||||
#, rust-format
|
||||
msgid "checking for changes — {n} item checked"
|
||||
msgid_plural "checking for changes — {n} items checked"
|
||||
msgstr[0] "recherche de modifications — {n} élément vérifié"
|
||||
msgstr[1] "recherche de modifications — {n} éléments vérifiés"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:645
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:667
|
||||
#, rust-format
|
||||
msgid "checking for changes — {done} of {total}"
|
||||
msgstr "recherche de modifications — {done} sur {total}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:657
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:679
|
||||
#, rust-format
|
||||
msgid "syncing {done} of {total}"
|
||||
msgstr "synchronisation de {done} sur {total}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:663
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:685
|
||||
#, rust-format
|
||||
msgid "syncing {file} — {done} of {total}"
|
||||
msgstr "synchronisation de {file} — {done} sur {total}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:675
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:697
|
||||
msgid "Add Folder to Sync"
|
||||
msgstr "Ajouter un dossier à synchroniser"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:699
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:721
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1559
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1686
|
||||
msgid "Syncing folder…"
|
||||
msgstr "Synchronisation du dossier…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:702
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:706
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:724
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:728
|
||||
msgid "Couldn't add folder"
|
||||
msgstr "Impossible d’ajouter le dossier"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:740
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:746
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:762
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:768
|
||||
msgid "Couldn't list folders to restore"
|
||||
msgstr "Impossible de lister les dossiers à restaurer"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:772
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:794
|
||||
msgid ""
|
||||
"Tick the folders to sync to this machine, and adjust where each one should "
|
||||
"live."
|
||||
@@ -2358,19 +2382,19 @@ msgstr ""
|
||||
"Cochez les dossiers à synchroniser sur cette machine et ajustez "
|
||||
"l’emplacement de chacun."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:798
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:820
|
||||
msgid "Restore Folders"
|
||||
msgstr "Restaurer les dossiers"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:805
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:827
|
||||
msgid "Restore"
|
||||
msgstr "Restaurer"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:838
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:860
|
||||
msgid "Restoring folders…"
|
||||
msgstr "Restauration des dossiers…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:850
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:872
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"These folders are backed up from “{name}”. Restored folders keep syncing "
|
||||
@@ -2379,35 +2403,35 @@ msgstr ""
|
||||
"Ces dossiers sont sauvegardés depuis « {name} ». Les dossiers restaurés "
|
||||
"restent synchronisés avec la copie de cet ordinateur."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:853
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:875
|
||||
msgid "These folders are backed up under this computer in Proton Drive."
|
||||
msgstr "Ces dossiers sont sauvegardés sous cet ordinateur dans Proton Drive."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:862
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:884
|
||||
#, rust-format
|
||||
msgid "Nothing to restore — “{name}”'s folders are all synced here."
|
||||
msgstr ""
|
||||
"Rien à restaurer — les dossiers de « {name} » sont tous synchronisés ici."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:865
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:887
|
||||
msgid "Nothing to restore — this computer's folders are all synced here."
|
||||
msgstr ""
|
||||
"Rien à restaurer — les dossiers de cet ordinateur sont tous synchronisés ici."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:889
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:911
|
||||
msgid "Folder will switch to online only"
|
||||
msgstr "Le dossier passera en ligne uniquement"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:891
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:913
|
||||
msgid "Folder will download and stay synced"
|
||||
msgstr "Le dossier va être téléchargé et rester synchronisé"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:895
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:899
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:917
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:921
|
||||
msgid "Couldn't change mode"
|
||||
msgstr "Impossible de changer de mode"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:931
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:953
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"Stop syncing “{path}”?\n"
|
||||
@@ -2424,7 +2448,7 @@ msgstr ""
|
||||
"arrêtée. Pour conserver une copie locale, annulez, passez le dossier en "
|
||||
"« Synchronisé » et attendez la fin du téléchargement avant de le retirer."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:937
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:959
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"Stop syncing “{path}”?\n"
|
||||
@@ -2438,68 +2462,68 @@ msgstr ""
|
||||
"synchronisés. Choisissez s’il faut aussi supprimer la copie dans Proton "
|
||||
"Drive."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:942
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:964
|
||||
msgid "Stop Syncing Folder?"
|
||||
msgstr "Arrêter la synchronisation du dossier ?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:947
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:969
|
||||
msgid "Also delete from Proton Drive"
|
||||
msgstr "Supprimer aussi de Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:949
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:971
|
||||
msgid "Deletes the only copy of these files."
|
||||
msgstr "Supprime l’unique copie de ces fichiers."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:951
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:973
|
||||
msgid "The local copy is unaffected."
|
||||
msgstr "La copie locale n’est pas affectée."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:958
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:980
|
||||
msgid "Stop Syncing"
|
||||
msgstr "Arrêter la synchronisation"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:971
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:993
|
||||
msgid "Stopped syncing folder"
|
||||
msgstr "Synchronisation du dossier arrêtée"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:972
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:994
|
||||
msgid "Couldn't stop syncing the folder"
|
||||
msgstr "Impossible d’arrêter la synchronisation du dossier"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:983
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1005
|
||||
msgid "Rename Computer"
|
||||
msgstr "Renommer l’ordinateur"
|
||||
|
||||
#. Translators: {name} is the computer's current name.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:985
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1007
|
||||
#, rust-format
|
||||
msgid "Rename “{name}”."
|
||||
msgstr "Renommer « {name} »."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1010
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1022
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1032
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1044
|
||||
msgid "Couldn't rename the computer"
|
||||
msgstr "Impossible de renommer l’ordinateur"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1011
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1033
|
||||
msgid "A name is required."
|
||||
msgstr "Un nom est requis."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1021
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1043
|
||||
msgid "Computer renamed"
|
||||
msgstr "Ordinateur renommé"
|
||||
|
||||
#. Translators: {name} is the computer's name, which the user must type.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1034
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1056
|
||||
#, rust-format
|
||||
msgid "Type “{name}” to confirm"
|
||||
msgstr "Saisissez « {name} » pour confirmer"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1039
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1061
|
||||
msgid "Remove Computer?"
|
||||
msgstr "Retirer l’ordinateur ?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1042
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1064
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"Remove “{name}” from this account?\n"
|
||||
@@ -2514,26 +2538,26 @@ msgstr ""
|
||||
"fichiers présents sur cet ordinateur ne sont pas touchés — mais cette action "
|
||||
"ne peut pas être annulée d’ici."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1048
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1070
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1025
|
||||
#: crates/pdfs-gui/src/app/widgets/share_dialog.rs:634
|
||||
#: crates/pdfs-gui/src/app/widgets/share_dialog.rs:876
|
||||
msgid "Remove"
|
||||
msgstr "Retirer"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1065
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1087
|
||||
msgid "Computer removed"
|
||||
msgstr "Ordinateur retiré"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1066
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1088
|
||||
msgid "Couldn't remove the computer"
|
||||
msgstr "Impossible de retirer l’ordinateur"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1084
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1106
|
||||
msgid "Continue This Backup Here?"
|
||||
msgstr "Continuer cette sauvegarde ici ?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1087
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1109
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"This computer takes over the backup of “{name}”, for example after a "
|
||||
@@ -2552,25 +2576,25 @@ msgstr ""
|
||||
"ne sont pas déplacés. Utilisez ensuite « Restaurer sur cet ordinateur » pour "
|
||||
"récupérer ce que « {name} » synchronisait."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1092
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1114
|
||||
msgid "Continue Here"
|
||||
msgstr "Continuer ici"
|
||||
|
||||
#. Translators: {name} is the name of the computer whose backup this one took over.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1099
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1121
|
||||
#, rust-format
|
||||
msgid "Now backing up as “{name}”"
|
||||
msgstr "Sauvegarde désormais en tant que « {name} »"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1108
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1130
|
||||
msgid "Couldn't continue that backup here"
|
||||
msgstr "Impossible de continuer cette sauvegarde ici"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1124
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1146
|
||||
msgid "Sync With This Computer?"
|
||||
msgstr "Synchroniser avec cet ordinateur ?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1127
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1149
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"This computer and “{name}” keep the same folders in step. A change or a "
|
||||
@@ -2587,25 +2611,25 @@ msgstr ""
|
||||
"dans Proton Drive. Les dossiers déjà synchronisés ici restent où ils sont. "
|
||||
"Vous choisissez ensuite lesquels de ses dossiers synchroniser ici."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1132
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1154
|
||||
msgid "Sync Here"
|
||||
msgstr "Synchroniser ici"
|
||||
|
||||
#. Translators: {name} is the name of the other computer this one now syncs with.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1139
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1161
|
||||
#, rust-format
|
||||
msgid "Now syncing with “{name}”"
|
||||
msgstr "Synchronisé désormais avec « {name} »"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1155
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1177
|
||||
msgid "Couldn't sync with that computer"
|
||||
msgstr "Impossible de synchroniser avec cet ordinateur"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1187
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1209
|
||||
msgid "Move Backup to This Computer?"
|
||||
msgstr "Déplacer la sauvegarde vers cet ordinateur ?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1190
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1212
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"The folders backed up by “{name}” move into this computer's backup in Proton "
|
||||
@@ -2622,12 +2646,12 @@ msgstr ""
|
||||
"disparaître."
|
||||
|
||||
#. Translators: {name} is the name of the computer whose folders moved to this one.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1202
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1224
|
||||
#, rust-format
|
||||
msgid "Moved the backup of “{name}”"
|
||||
msgstr "Sauvegarde de « {name} » déplacée"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1216
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1238
|
||||
msgid "Couldn't move that backup"
|
||||
msgstr "Impossible de déplacer cette sauvegarde"
|
||||
|
||||
@@ -2908,7 +2932,7 @@ msgid "Sync paused until you resume"
|
||||
msgstr "Synchronisation en pause jusqu’à la reprise"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:570
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1445 crates/pdfs-gui/src/main.rs:290
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1445 crates/pdfs-gui/src/main.rs:308
|
||||
msgid "Sync paused"
|
||||
msgstr "Synchronisation en pause"
|
||||
|
||||
@@ -3374,7 +3398,7 @@ msgid "paused"
|
||||
msgstr "en pause"
|
||||
|
||||
#. Translators: a folder's files can't be opened right now.
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1742
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1745
|
||||
msgid "not available"
|
||||
msgstr "non disponible"
|
||||
|
||||
@@ -5138,7 +5162,7 @@ msgstr "Reprise {time}"
|
||||
msgid "Until you resume"
|
||||
msgstr "Jusqu’à la reprise"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1464 crates/pdfs-gui/src/main.rs:292
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1464 crates/pdfs-gui/src/main.rs:310
|
||||
#, rust-format
|
||||
msgid "{n} change needs attention"
|
||||
msgid_plural "{n} changes need attention"
|
||||
@@ -6375,52 +6399,57 @@ msgstr "Proton Drive ne répond pas"
|
||||
msgid "Signed in as {username} — locked"
|
||||
msgstr "Connecté en tant que {username} — verrouillé"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:200
|
||||
#: crates/pdfs-gui/src/main.rs:209
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — can't open your Drive"
|
||||
msgstr "Connecté en tant que {username} — impossible d’ouvrir Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:218
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — not connected"
|
||||
msgstr "Connecté en tant que {username} — non connecté"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:205
|
||||
#: crates/pdfs-gui/src/main.rs:223
|
||||
msgid "Not signed in"
|
||||
msgstr "Non connecté"
|
||||
|
||||
#. Translators: {error} is an error message, in English.
|
||||
#: crates/pdfs-gui/src/main.rs:208
|
||||
#: crates/pdfs-gui/src/main.rs:226
|
||||
#, rust-format
|
||||
msgid "Error: {error}"
|
||||
msgstr "Erreur : {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:230
|
||||
#: crates/pdfs-gui/src/main.rs:248
|
||||
msgid "Proton Drive sent an unexpected reply"
|
||||
msgstr "Proton Drive a envoyé une réponse inattendue"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:284
|
||||
#: crates/pdfs-gui/src/main.rs:302
|
||||
msgid "Session expired — sign in again"
|
||||
msgstr "Session expirée — reconnectez-vous"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:286
|
||||
#: crates/pdfs-gui/src/main.rs:304
|
||||
msgid "Sign-in not saved — unlock your keyring"
|
||||
msgstr "Connexion non enregistrée — déverrouillez votre trousseau"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:289
|
||||
#: crates/pdfs-gui/src/main.rs:307
|
||||
msgid "Update not finished — restart Proton Drive"
|
||||
msgstr "Mise à jour inachevée — redémarrez Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:299
|
||||
#: crates/pdfs-gui/src/main.rs:317
|
||||
#, rust-format
|
||||
msgid "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgid_plural "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgstr[0] "À jour dans {mountpoint} ({n} épinglé)"
|
||||
msgstr[1] "À jour dans {mountpoint} ({n} épinglés)"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:306
|
||||
#: crates/pdfs-gui/src/main.rs:324
|
||||
#, rust-format
|
||||
msgid "Syncing — {queued} ({n} pinned)"
|
||||
msgid_plural "Syncing — {queued} ({n} pinned)"
|
||||
msgstr[0] "Synchronisation — {queued} ({n} épinglé)"
|
||||
msgstr[1] "Synchronisation — {queued} ({n} épinglés)"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:313
|
||||
#: crates/pdfs-gui/src/main.rs:331
|
||||
#, rust-format
|
||||
msgid "Offline — cached files only ({n} pinned)"
|
||||
msgid_plural "Offline — cached files only ({n} pinned)"
|
||||
@@ -6428,60 +6457,60 @@ msgstr[0] "Hors ligne — fichiers en cache uniquement ({n} épinglé)"
|
||||
msgstr[1] "Hors ligne — fichiers en cache uniquement ({n} épinglés)"
|
||||
|
||||
#. Translators: {queued} is a queue summary such as "3 uploads queued".
|
||||
#: crates/pdfs-gui/src/main.rs:319
|
||||
#: crates/pdfs-gui/src/main.rs:337
|
||||
#, rust-format
|
||||
msgid "Offline — {queued}"
|
||||
msgstr "Hors ligne — {queued}"
|
||||
|
||||
#. Translators: a menu item that opens the list of failing changes.
|
||||
#: crates/pdfs-gui/src/main.rs:358
|
||||
#: crates/pdfs-gui/src/main.rs:376
|
||||
#, rust-format
|
||||
msgid "{n} issue — View"
|
||||
msgid_plural "{n} issues — View"
|
||||
msgstr[0] "{n} problème — Afficher"
|
||||
msgstr[1] "{n} problèmes — Afficher"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:465
|
||||
#: crates/pdfs-gui/src/main.rs:483
|
||||
msgid "Sign In…"
|
||||
msgstr "Se connecter…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:466
|
||||
#: crates/pdfs-gui/src/main.rs:484
|
||||
msgid "Sign In Again…"
|
||||
msgstr "Se reconnecter…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:469
|
||||
#: crates/pdfs-gui/src/main.rs:487
|
||||
msgid "Open Proton Drive"
|
||||
msgstr "Ouvrir Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:473
|
||||
#: crates/pdfs-gui/src/main.rs:491
|
||||
msgid "Restart Proton Drive"
|
||||
msgstr "Redémarrer Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:482
|
||||
#: crates/pdfs-gui/src/main.rs:500
|
||||
msgid "Open Folder"
|
||||
msgstr "Ouvrir le dossier"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:494
|
||||
#: crates/pdfs-gui/src/main.rs:512
|
||||
msgid "Resume Sync"
|
||||
msgstr "Reprendre la synchronisation"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:496
|
||||
#: crates/pdfs-gui/src/main.rs:514
|
||||
msgid "Pause Sync"
|
||||
msgstr "Mettre en pause la synchronisation"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:515
|
||||
#: crates/pdfs-gui/src/main.rs:533
|
||||
msgid "Connect"
|
||||
msgstr "Connecter"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:522
|
||||
#: crates/pdfs-gui/src/main.rs:540
|
||||
msgid "Hide Tray Icon"
|
||||
msgstr "Masquer l’icône de la zone de notification"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:526
|
||||
#: crates/pdfs-gui/src/main.rs:544
|
||||
msgid "Stop Proton Drive…"
|
||||
msgstr "Arrêter Proton Drive…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:530
|
||||
#: crates/pdfs-gui/src/main.rs:548
|
||||
msgid "Quit"
|
||||
msgstr "Quitter"
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: proton-drive-linux 2.1.0\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/narrrl/proton-drive-linux/issues\n"
|
||||
"POT-Creation-Date: 2026-10-26 22:26+0100\n"
|
||||
"POT-Creation-Date: 2026-10-31 19:26+0100\n"
|
||||
"PO-Revision-Date: 2026-09-23 12:00+0200\n"
|
||||
"Last-Translator: Proton Drive for Linux contributors\n"
|
||||
"Language-Team: Italian\n"
|
||||
@@ -245,13 +245,13 @@ msgstr ""
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1917
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2039
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2540
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:804
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:957
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:995
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1047
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1091
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1131
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1194
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:826
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:979
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1017
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1069
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1113
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1153
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1216
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:850
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1054
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1537
|
||||
@@ -346,7 +346,7 @@ msgstr "Griglia / elenco"
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:298
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1896
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1918
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:996
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1018
|
||||
#: crates/pdfs-gui/src/app/widgets/details.rs:161
|
||||
msgid "Rename"
|
||||
msgstr "Rinomina"
|
||||
@@ -420,14 +420,27 @@ msgstr "Non connesso"
|
||||
msgid "The Proton Drive service isn't running."
|
||||
msgstr "Il servizio di Proton Drive non è in esecuzione."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1803
|
||||
#: crates/pdfs-gui/src/app/main.rs:1813
|
||||
msgid "Can't open your Drive"
|
||||
msgstr "Impossibile aprire Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1816
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"The Proton Drive service keeps failing to start and tries again on its own. "
|
||||
"The last error was: {error}"
|
||||
msgstr ""
|
||||
"Il servizio di Proton Drive non riesce ad avviarsi e riprova da solo. Ultimo "
|
||||
"errore: {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1824
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:355
|
||||
#: crates/pdfs-gui/src/hud/mod.rs:269 crates/pdfs-gui/src/hud/mod.rs:579
|
||||
#: crates/pdfs-gui/src/main.rs:475 crates/pdfs-gui/src/main.rs:517
|
||||
#: crates/pdfs-gui/src/main.rs:493 crates/pdfs-gui/src/main.rs:535
|
||||
msgid "Connecting…"
|
||||
msgstr "Connessione…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1804
|
||||
#: crates/pdfs-gui/src/app/main.rs:1825
|
||||
msgid "Waiting for the Proton Drive service to start."
|
||||
msgstr "In attesa dell’avvio del servizio di Proton Drive."
|
||||
|
||||
@@ -678,7 +691,7 @@ msgid "Couldn't add a sync folder"
|
||||
msgstr "Impossibile aggiungere una cartella sincronizzata"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/activity_text.rs:58
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:839
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:861
|
||||
msgid "Couldn't restore folders"
|
||||
msgstr "Impossibile ripristinare le cartelle"
|
||||
|
||||
@@ -1273,12 +1286,12 @@ msgstr "Impossibile caricare gli album"
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1873
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2500
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2650
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:707
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:747
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:900
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1170
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1231
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1260
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:729
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:769
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:922
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1192
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1253
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1282
|
||||
#: crates/pdfs-gui/src/app/pages/duplicates.rs:221
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:577
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:824
|
||||
@@ -1927,7 +1940,7 @@ msgid "{status}. {message}"
|
||||
msgstr "{status}. {message}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1900
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:989
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1011
|
||||
msgid "New name"
|
||||
msgstr "Nuovo nome"
|
||||
|
||||
@@ -1952,7 +1965,7 @@ msgstr "Scegli la cartella di destinazione."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1989
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1994
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1195
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1217
|
||||
msgid "Move Here"
|
||||
msgstr "Sposta qui"
|
||||
|
||||
@@ -2275,76 +2288,87 @@ msgid_plural "{n} folders backed up"
|
||||
msgstr[0] "{n} cartella sottoposta a backup"
|
||||
msgstr[1] "{n} cartelle sottoposte a backup"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:608
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:607
|
||||
#, rust-format
|
||||
msgid "{folders} · {n} waiting for its first sync"
|
||||
msgid_plural "{folders} · {n} waiting for their first sync"
|
||||
msgstr[0] "{folders} · {n} attende la prima sincronizzazione"
|
||||
msgstr[1] "{folders} · {n} attendono la prima sincronizzazione"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:621
|
||||
#, rust-format
|
||||
msgid "{folders} · {n} needs attention"
|
||||
msgid_plural "{folders} · {n} need attention"
|
||||
msgstr[0] "{folders} · {n} richiede attenzione"
|
||||
msgstr[1] "{folders} · {n} richiedono attenzione"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:619
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:640
|
||||
msgid "syncing…"
|
||||
msgstr "sincronizzazione…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:620
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:641
|
||||
msgid "sync error"
|
||||
msgstr "errore di sincronizzazione"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:621
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:642
|
||||
msgid "needs attention"
|
||||
msgstr "richiede attenzione"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:622
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:643
|
||||
msgid "waiting for first sync"
|
||||
msgstr "in attesa della prima sincronizzazione"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:644
|
||||
msgid "up to date"
|
||||
msgstr "aggiornato"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:632
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:654
|
||||
msgid "checking for changes…"
|
||||
msgstr "controllo delle modifiche…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:638
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:660
|
||||
#, rust-format
|
||||
msgid "checking for changes — {n} item checked"
|
||||
msgid_plural "checking for changes — {n} items checked"
|
||||
msgstr[0] "controllo delle modifiche: {n} elemento controllato"
|
||||
msgstr[1] "controllo delle modifiche: {n} elementi controllati"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:645
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:667
|
||||
#, rust-format
|
||||
msgid "checking for changes — {done} of {total}"
|
||||
msgstr "controllo delle modifiche: {done} di {total}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:657
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:679
|
||||
#, rust-format
|
||||
msgid "syncing {done} of {total}"
|
||||
msgstr "sincronizzazione {done} di {total}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:663
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:685
|
||||
#, rust-format
|
||||
msgid "syncing {file} — {done} of {total}"
|
||||
msgstr "sincronizzazione di {file}: {done} di {total}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:675
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:697
|
||||
msgid "Add Folder to Sync"
|
||||
msgstr "Aggiungi cartella da sincronizzare"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:699
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:721
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1559
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1686
|
||||
msgid "Syncing folder…"
|
||||
msgstr "Sincronizzazione della cartella…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:702
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:706
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:724
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:728
|
||||
msgid "Couldn't add folder"
|
||||
msgstr "Impossibile aggiungere la cartella"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:740
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:746
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:762
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:768
|
||||
msgid "Couldn't list folders to restore"
|
||||
msgstr "Impossibile elencare le cartelle da ripristinare"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:772
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:794
|
||||
msgid ""
|
||||
"Tick the folders to sync to this machine, and adjust where each one should "
|
||||
"live."
|
||||
@@ -2352,19 +2376,19 @@ msgstr ""
|
||||
"Seleziona le cartelle da sincronizzare su questa macchina e regola dove deve "
|
||||
"trovarsi ciascuna."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:798
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:820
|
||||
msgid "Restore Folders"
|
||||
msgstr "Ripristina cartelle"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:805
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:827
|
||||
msgid "Restore"
|
||||
msgstr "Ripristina"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:838
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:860
|
||||
msgid "Restoring folders…"
|
||||
msgstr "Ripristino delle cartelle…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:850
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:872
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"These folders are backed up from “{name}”. Restored folders keep syncing "
|
||||
@@ -2373,39 +2397,39 @@ msgstr ""
|
||||
"Queste cartelle sono sottoposte a backup da “{name}”. Le cartelle "
|
||||
"ripristinate continuano a sincronizzarsi con la copia di quel computer."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:853
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:875
|
||||
msgid "These folders are backed up under this computer in Proton Drive."
|
||||
msgstr ""
|
||||
"Queste cartelle sono sottoposte a backup sotto questo computer in Proton "
|
||||
"Drive."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:862
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:884
|
||||
#, rust-format
|
||||
msgid "Nothing to restore — “{name}”'s folders are all synced here."
|
||||
msgstr ""
|
||||
"Niente da ripristinare: le cartelle di “{name}” sono già tutte sincronizzate "
|
||||
"qui."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:865
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:887
|
||||
msgid "Nothing to restore — this computer's folders are all synced here."
|
||||
msgstr ""
|
||||
"Niente da ripristinare: le cartelle di questo computer sono già tutte "
|
||||
"sincronizzate qui."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:889
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:911
|
||||
msgid "Folder will switch to online only"
|
||||
msgstr "La cartella passerà a solo online"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:891
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:913
|
||||
msgid "Folder will download and stay synced"
|
||||
msgstr "La cartella verrà scaricata e resterà sincronizzata"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:895
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:899
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:917
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:921
|
||||
msgid "Couldn't change mode"
|
||||
msgstr "Impossibile cambiare modalità"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:931
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:953
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"Stop syncing “{path}”?\n"
|
||||
@@ -2423,7 +2447,7 @@ msgstr ""
|
||||
"cartella a Sincronizzata e attendi il completamento del download prima di "
|
||||
"rimuoverla."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:937
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:959
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"Stop syncing “{path}”?\n"
|
||||
@@ -2436,68 +2460,68 @@ msgstr ""
|
||||
"I file locali restano su questo disco e semplicemente smettono di essere "
|
||||
"sincronizzati. Scegli se eliminare anche la copia in Proton Drive."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:942
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:964
|
||||
msgid "Stop Syncing Folder?"
|
||||
msgstr "Interrompere la sincronizzazione della cartella?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:947
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:969
|
||||
msgid "Also delete from Proton Drive"
|
||||
msgstr "Elimina anche da Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:949
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:971
|
||||
msgid "Deletes the only copy of these files."
|
||||
msgstr "Elimina l'unica copia di questi file."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:951
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:973
|
||||
msgid "The local copy is unaffected."
|
||||
msgstr "La copia locale non viene modificata."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:958
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:980
|
||||
msgid "Stop Syncing"
|
||||
msgstr "Interrompi sincronizzazione"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:971
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:993
|
||||
msgid "Stopped syncing folder"
|
||||
msgstr "Sincronizzazione della cartella interrotta"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:972
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:994
|
||||
msgid "Couldn't stop syncing the folder"
|
||||
msgstr "Impossibile interrompere la sincronizzazione della cartella"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:983
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1005
|
||||
msgid "Rename Computer"
|
||||
msgstr "Rinomina computer"
|
||||
|
||||
#. Translators: {name} is the computer's current name.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:985
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1007
|
||||
#, rust-format
|
||||
msgid "Rename “{name}”."
|
||||
msgstr "Rinomina “{name}”."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1010
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1022
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1032
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1044
|
||||
msgid "Couldn't rename the computer"
|
||||
msgstr "Impossibile rinominare il computer"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1011
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1033
|
||||
msgid "A name is required."
|
||||
msgstr "È richiesto un nome."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1021
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1043
|
||||
msgid "Computer renamed"
|
||||
msgstr "Computer rinominato"
|
||||
|
||||
#. Translators: {name} is the computer's name, which the user must type.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1034
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1056
|
||||
#, rust-format
|
||||
msgid "Type “{name}” to confirm"
|
||||
msgstr "Digita “{name}” per confermare"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1039
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1061
|
||||
msgid "Remove Computer?"
|
||||
msgstr "Rimuovere il computer?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1042
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1064
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"Remove “{name}” from this account?\n"
|
||||
@@ -2512,26 +2536,26 @@ msgstr ""
|
||||
"insieme a esso. I file su quel computer non vengono toccati, ma questa "
|
||||
"operazione non può essere annullata da qui."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1048
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1070
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1025
|
||||
#: crates/pdfs-gui/src/app/widgets/share_dialog.rs:634
|
||||
#: crates/pdfs-gui/src/app/widgets/share_dialog.rs:876
|
||||
msgid "Remove"
|
||||
msgstr "Rimuovi"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1065
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1087
|
||||
msgid "Computer removed"
|
||||
msgstr "Computer rimosso"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1066
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1088
|
||||
msgid "Couldn't remove the computer"
|
||||
msgstr "Impossibile rimuovere il computer"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1084
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1106
|
||||
msgid "Continue This Backup Here?"
|
||||
msgstr "Continuare questo backup qui?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1087
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1109
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"This computer takes over the backup of “{name}”, for example after a "
|
||||
@@ -2550,25 +2574,25 @@ msgstr ""
|
||||
"qui non vengono spostate. Usa poi “Ripristina su questo computer” per "
|
||||
"recuperare ciò che “{name}” sincronizzava."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1092
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1114
|
||||
msgid "Continue Here"
|
||||
msgstr "Continua qui"
|
||||
|
||||
#. Translators: {name} is the name of the computer whose backup this one took over.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1099
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1121
|
||||
#, rust-format
|
||||
msgid "Now backing up as “{name}”"
|
||||
msgstr "Ora il backup avviene come “{name}”"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1108
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1130
|
||||
msgid "Couldn't continue that backup here"
|
||||
msgstr "Impossibile continuare quel backup qui"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1124
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1146
|
||||
msgid "Sync With This Computer?"
|
||||
msgstr "Sincronizzare con questo computer?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1127
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1149
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"This computer and “{name}” keep the same folders in step. A change or a "
|
||||
@@ -2585,25 +2609,25 @@ msgstr ""
|
||||
"in Proton Drive. Le cartelle già sincronizzate qui restano dove sono. Poi "
|
||||
"scegli quali delle sue cartelle sincronizzare qui."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1132
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1154
|
||||
msgid "Sync Here"
|
||||
msgstr "Sincronizza qui"
|
||||
|
||||
#. Translators: {name} is the name of the other computer this one now syncs with.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1139
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1161
|
||||
#, rust-format
|
||||
msgid "Now syncing with “{name}”"
|
||||
msgstr "Ora sincronizzato con “{name}”"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1155
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1177
|
||||
msgid "Couldn't sync with that computer"
|
||||
msgstr "Impossibile sincronizzare con quel computer"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1187
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1209
|
||||
msgid "Move Backup to This Computer?"
|
||||
msgstr "Spostare il backup su questo computer?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1190
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1212
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"The folders backed up by “{name}” move into this computer's backup in Proton "
|
||||
@@ -2620,12 +2644,12 @@ msgstr ""
|
||||
"cartelle."
|
||||
|
||||
#. Translators: {name} is the name of the computer whose folders moved to this one.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1202
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1224
|
||||
#, rust-format
|
||||
msgid "Moved the backup of “{name}”"
|
||||
msgstr "Backup di “{name}” spostato"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1216
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1238
|
||||
msgid "Couldn't move that backup"
|
||||
msgstr "Impossibile spostare quel backup"
|
||||
|
||||
@@ -2906,7 +2930,7 @@ msgid "Sync paused until you resume"
|
||||
msgstr "Sincronizzazione in pausa finché non riprendi"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:570
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1445 crates/pdfs-gui/src/main.rs:290
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1445 crates/pdfs-gui/src/main.rs:308
|
||||
msgid "Sync paused"
|
||||
msgstr "Sincronizzazione in pausa"
|
||||
|
||||
@@ -3366,7 +3390,7 @@ msgid "paused"
|
||||
msgstr "in pausa"
|
||||
|
||||
#. Translators: a folder's files can't be opened right now.
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1742
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1745
|
||||
msgid "not available"
|
||||
msgstr "non disponibile"
|
||||
|
||||
@@ -5114,7 +5138,7 @@ msgstr "Riprende {time}"
|
||||
msgid "Until you resume"
|
||||
msgstr "Finché non riprendi"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1464 crates/pdfs-gui/src/main.rs:292
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1464 crates/pdfs-gui/src/main.rs:310
|
||||
#, rust-format
|
||||
msgid "{n} change needs attention"
|
||||
msgid_plural "{n} changes need attention"
|
||||
@@ -6351,52 +6375,57 @@ msgstr "Proton Drive non risponde"
|
||||
msgid "Signed in as {username} — locked"
|
||||
msgstr "Accesso effettuato come {username} — bloccato"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:200
|
||||
#: crates/pdfs-gui/src/main.rs:209
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — can't open your Drive"
|
||||
msgstr "Accesso effettuato come {username} — impossibile aprire Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:218
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — not connected"
|
||||
msgstr "Accesso effettuato come {username} — non connesso"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:205
|
||||
#: crates/pdfs-gui/src/main.rs:223
|
||||
msgid "Not signed in"
|
||||
msgstr "Accesso non eseguito"
|
||||
|
||||
#. Translators: {error} is an error message, in English.
|
||||
#: crates/pdfs-gui/src/main.rs:208
|
||||
#: crates/pdfs-gui/src/main.rs:226
|
||||
#, rust-format
|
||||
msgid "Error: {error}"
|
||||
msgstr "Errore: {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:230
|
||||
#: crates/pdfs-gui/src/main.rs:248
|
||||
msgid "Proton Drive sent an unexpected reply"
|
||||
msgstr "Proton Drive ha inviato una risposta inattesa"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:284
|
||||
#: crates/pdfs-gui/src/main.rs:302
|
||||
msgid "Session expired — sign in again"
|
||||
msgstr "Sessione scaduta: accedi di nuovo"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:286
|
||||
#: crates/pdfs-gui/src/main.rs:304
|
||||
msgid "Sign-in not saved — unlock your keyring"
|
||||
msgstr "Accesso non salvato: sblocca il portachiavi"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:289
|
||||
#: crates/pdfs-gui/src/main.rs:307
|
||||
msgid "Update not finished — restart Proton Drive"
|
||||
msgstr "Aggiornamento non completato: riavvia Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:299
|
||||
#: crates/pdfs-gui/src/main.rs:317
|
||||
#, rust-format
|
||||
msgid "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgid_plural "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgstr[0] "Aggiornato in {mountpoint} ({n} fissato)"
|
||||
msgstr[1] "Aggiornato in {mountpoint} ({n} fissati)"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:306
|
||||
#: crates/pdfs-gui/src/main.rs:324
|
||||
#, rust-format
|
||||
msgid "Syncing — {queued} ({n} pinned)"
|
||||
msgid_plural "Syncing — {queued} ({n} pinned)"
|
||||
msgstr[0] "Sincronizzazione: {queued} ({n} fissato)"
|
||||
msgstr[1] "Sincronizzazione: {queued} ({n} fissati)"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:313
|
||||
#: crates/pdfs-gui/src/main.rs:331
|
||||
#, rust-format
|
||||
msgid "Offline — cached files only ({n} pinned)"
|
||||
msgid_plural "Offline — cached files only ({n} pinned)"
|
||||
@@ -6404,60 +6433,60 @@ msgstr[0] "Offline: solo file in cache ({n} fissato)"
|
||||
msgstr[1] "Offline: solo file in cache ({n} fissati)"
|
||||
|
||||
#. Translators: {queued} is a queue summary such as "3 uploads queued".
|
||||
#: crates/pdfs-gui/src/main.rs:319
|
||||
#: crates/pdfs-gui/src/main.rs:337
|
||||
#, rust-format
|
||||
msgid "Offline — {queued}"
|
||||
msgstr "Offline: {queued}"
|
||||
|
||||
#. Translators: a menu item that opens the list of failing changes.
|
||||
#: crates/pdfs-gui/src/main.rs:358
|
||||
#: crates/pdfs-gui/src/main.rs:376
|
||||
#, rust-format
|
||||
msgid "{n} issue — View"
|
||||
msgid_plural "{n} issues — View"
|
||||
msgstr[0] "{n} problema: visualizza"
|
||||
msgstr[1] "{n} problemi: visualizza"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:465
|
||||
#: crates/pdfs-gui/src/main.rs:483
|
||||
msgid "Sign In…"
|
||||
msgstr "Accedi…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:466
|
||||
#: crates/pdfs-gui/src/main.rs:484
|
||||
msgid "Sign In Again…"
|
||||
msgstr "Accedi di nuovo…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:469
|
||||
#: crates/pdfs-gui/src/main.rs:487
|
||||
msgid "Open Proton Drive"
|
||||
msgstr "Apri Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:473
|
||||
#: crates/pdfs-gui/src/main.rs:491
|
||||
msgid "Restart Proton Drive"
|
||||
msgstr "Riavvia Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:482
|
||||
#: crates/pdfs-gui/src/main.rs:500
|
||||
msgid "Open Folder"
|
||||
msgstr "Apri cartella"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:494
|
||||
#: crates/pdfs-gui/src/main.rs:512
|
||||
msgid "Resume Sync"
|
||||
msgstr "Riprendi sincronizzazione"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:496
|
||||
#: crates/pdfs-gui/src/main.rs:514
|
||||
msgid "Pause Sync"
|
||||
msgstr "Metti in pausa sincronizzazione"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:515
|
||||
#: crates/pdfs-gui/src/main.rs:533
|
||||
msgid "Connect"
|
||||
msgstr "Connetti"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:522
|
||||
#: crates/pdfs-gui/src/main.rs:540
|
||||
msgid "Hide Tray Icon"
|
||||
msgstr "Nascondi icona nell'area di notifica"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:526
|
||||
#: crates/pdfs-gui/src/main.rs:544
|
||||
msgid "Stop Proton Drive…"
|
||||
msgstr "Arresta Proton Drive…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:530
|
||||
#: crates/pdfs-gui/src/main.rs:548
|
||||
msgid "Quit"
|
||||
msgstr "Esci"
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: proton-drive-linux 2.1.0\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/narrrl/proton-drive-linux/issues\n"
|
||||
"POT-Creation-Date: 2026-10-26 22:26+0100\n"
|
||||
"POT-Creation-Date: 2026-10-31 19:26+0100\n"
|
||||
"PO-Revision-Date: 2026-09-23 12:00+0200\n"
|
||||
"Last-Translator: Proton Drive for Linux contributors\n"
|
||||
"Language-Team: Dutch\n"
|
||||
@@ -246,13 +246,13 @@ msgstr ""
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1917
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2039
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2540
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:804
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:957
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:995
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1047
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1091
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1131
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1194
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:826
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:979
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1017
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1069
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1113
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1153
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1216
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:850
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1054
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1537
|
||||
@@ -347,7 +347,7 @@ msgstr "Raster / lijst"
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:298
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1896
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1918
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:996
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1018
|
||||
#: crates/pdfs-gui/src/app/widgets/details.rs:161
|
||||
msgid "Rename"
|
||||
msgstr "Hernoemen"
|
||||
@@ -421,14 +421,27 @@ msgstr "Niet verbonden"
|
||||
msgid "The Proton Drive service isn't running."
|
||||
msgstr "De Proton Drive-service draait niet."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1803
|
||||
#: crates/pdfs-gui/src/app/main.rs:1813
|
||||
msgid "Can't open your Drive"
|
||||
msgstr "Kan Proton Drive niet openen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1816
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"The Proton Drive service keeps failing to start and tries again on its own. "
|
||||
"The last error was: {error}"
|
||||
msgstr ""
|
||||
"De Proton Drive-service kan steeds niet starten en probeert het zelf "
|
||||
"opnieuw. Laatste fout: {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1824
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:355
|
||||
#: crates/pdfs-gui/src/hud/mod.rs:269 crates/pdfs-gui/src/hud/mod.rs:579
|
||||
#: crates/pdfs-gui/src/main.rs:475 crates/pdfs-gui/src/main.rs:517
|
||||
#: crates/pdfs-gui/src/main.rs:493 crates/pdfs-gui/src/main.rs:535
|
||||
msgid "Connecting…"
|
||||
msgstr "Verbinden…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1804
|
||||
#: crates/pdfs-gui/src/app/main.rs:1825
|
||||
msgid "Waiting for the Proton Drive service to start."
|
||||
msgstr "Wachten tot de Proton Drive-service is gestart."
|
||||
|
||||
@@ -679,7 +692,7 @@ msgid "Couldn't add a sync folder"
|
||||
msgstr "Kon geen synchronisatiemap toevoegen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/activity_text.rs:58
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:839
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:861
|
||||
msgid "Couldn't restore folders"
|
||||
msgstr "Kon mappen niet terugzetten"
|
||||
|
||||
@@ -1269,12 +1282,12 @@ msgstr "Kon albums niet laden"
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1873
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2500
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2650
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:707
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:747
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:900
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1170
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1231
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1260
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:729
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:769
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:922
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1192
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1253
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1282
|
||||
#: crates/pdfs-gui/src/app/pages/duplicates.rs:221
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:577
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:824
|
||||
@@ -1921,7 +1934,7 @@ msgid "{status}. {message}"
|
||||
msgstr "{status}. {message}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1900
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:989
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1011
|
||||
msgid "New name"
|
||||
msgstr "Nieuwe naam"
|
||||
|
||||
@@ -1946,7 +1959,7 @@ msgstr "Kies de map waarnaar je wilt verplaatsen."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1989
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1994
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1195
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1217
|
||||
msgid "Move Here"
|
||||
msgstr "Hierheen verplaatsen"
|
||||
|
||||
@@ -2269,76 +2282,87 @@ msgid_plural "{n} folders backed up"
|
||||
msgstr[0] "{n} map in back-up"
|
||||
msgstr[1] "{n} mappen in back-up"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:608
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:607
|
||||
#, rust-format
|
||||
msgid "{folders} · {n} waiting for its first sync"
|
||||
msgid_plural "{folders} · {n} waiting for their first sync"
|
||||
msgstr[0] "{folders} · {n} wacht op de eerste synchronisatie"
|
||||
msgstr[1] "{folders} · {n} wachten op de eerste synchronisatie"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:621
|
||||
#, rust-format
|
||||
msgid "{folders} · {n} needs attention"
|
||||
msgid_plural "{folders} · {n} need attention"
|
||||
msgstr[0] "{folders} · {n} vereist aandacht"
|
||||
msgstr[1] "{folders} · {n} vereisen aandacht"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:619
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:640
|
||||
msgid "syncing…"
|
||||
msgstr "synchroniseren…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:620
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:641
|
||||
msgid "sync error"
|
||||
msgstr "synchronisatiefout"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:621
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:642
|
||||
msgid "needs attention"
|
||||
msgstr "vereist aandacht"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:622
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:643
|
||||
msgid "waiting for first sync"
|
||||
msgstr "wacht op eerste synchronisatie"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:644
|
||||
msgid "up to date"
|
||||
msgstr "bijgewerkt"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:632
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:654
|
||||
msgid "checking for changes…"
|
||||
msgstr "controleren op wijzigingen…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:638
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:660
|
||||
#, rust-format
|
||||
msgid "checking for changes — {n} item checked"
|
||||
msgid_plural "checking for changes — {n} items checked"
|
||||
msgstr[0] "controleren op wijzigingen — {n} item gecontroleerd"
|
||||
msgstr[1] "controleren op wijzigingen — {n} items gecontroleerd"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:645
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:667
|
||||
#, rust-format
|
||||
msgid "checking for changes — {done} of {total}"
|
||||
msgstr "controleren op wijzigingen — {done} van {total}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:657
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:679
|
||||
#, rust-format
|
||||
msgid "syncing {done} of {total}"
|
||||
msgstr "synchroniseren: {done} van {total}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:663
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:685
|
||||
#, rust-format
|
||||
msgid "syncing {file} — {done} of {total}"
|
||||
msgstr "{file} synchroniseren — {done} van {total}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:675
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:697
|
||||
msgid "Add Folder to Sync"
|
||||
msgstr "Map toevoegen aan synchronisatie"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:699
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:721
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1559
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1686
|
||||
msgid "Syncing folder…"
|
||||
msgstr "Map synchroniseren…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:702
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:706
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:724
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:728
|
||||
msgid "Couldn't add folder"
|
||||
msgstr "Kon map niet toevoegen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:740
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:746
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:762
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:768
|
||||
msgid "Couldn't list folders to restore"
|
||||
msgstr "Kon mappen om terug te zetten niet weergeven"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:772
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:794
|
||||
msgid ""
|
||||
"Tick the folders to sync to this machine, and adjust where each one should "
|
||||
"live."
|
||||
@@ -2346,19 +2370,19 @@ msgstr ""
|
||||
"Vink de mappen aan die je met dit apparaat wilt synchroniseren en pas aan "
|
||||
"waar elke map moet komen."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:798
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:820
|
||||
msgid "Restore Folders"
|
||||
msgstr "Mappen herstellen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:805
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:827
|
||||
msgid "Restore"
|
||||
msgstr "Terugzetten"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:838
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:860
|
||||
msgid "Restoring folders…"
|
||||
msgstr "Mappen terugzetten…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:850
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:872
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"These folders are backed up from “{name}”. Restored folders keep syncing "
|
||||
@@ -2367,38 +2391,38 @@ msgstr ""
|
||||
"Van deze mappen is een back-up gemaakt vanaf “{name}”. Teruggezette mappen "
|
||||
"blijven synchroniseren met de kopie van die computer."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:853
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:875
|
||||
msgid "These folders are backed up under this computer in Proton Drive."
|
||||
msgstr ""
|
||||
"Van deze mappen is een back-up gemaakt onder deze computer in Proton Drive."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:862
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:884
|
||||
#, rust-format
|
||||
msgid "Nothing to restore — “{name}”'s folders are all synced here."
|
||||
msgstr ""
|
||||
"Niets om terug te zetten — de mappen van “{name}” worden hier al allemaal "
|
||||
"gesynchroniseerd."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:865
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:887
|
||||
msgid "Nothing to restore — this computer's folders are all synced here."
|
||||
msgstr ""
|
||||
"Niets om terug te zetten — de mappen van deze computer worden hier al "
|
||||
"allemaal gesynchroniseerd."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:889
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:911
|
||||
msgid "Folder will switch to online only"
|
||||
msgstr "Map wordt alleen online"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:891
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:913
|
||||
msgid "Folder will download and stay synced"
|
||||
msgstr "Map wordt gedownload en blijft gesynchroniseerd"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:895
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:899
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:917
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:921
|
||||
msgid "Couldn't change mode"
|
||||
msgstr "Kon modus niet wijzigen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:931
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:953
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"Stop syncing “{path}”?\n"
|
||||
@@ -2415,7 +2439,7 @@ msgstr ""
|
||||
"kopie houden, annuleer dan, zet de map op Gesynchroniseerd en wacht tot de "
|
||||
"download klaar is voordat je hem verwijdert."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:937
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:959
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"Stop syncing “{path}”?\n"
|
||||
@@ -2428,68 +2452,68 @@ msgstr ""
|
||||
"De lokale bestanden blijven op deze schijf en worden gewoon niet meer "
|
||||
"gesynchroniseerd. Kies of je ook de kopie in Proton Drive wilt verwijderen."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:942
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:964
|
||||
msgid "Stop Syncing Folder?"
|
||||
msgstr "Synchroniseren van map stoppen?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:947
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:969
|
||||
msgid "Also delete from Proton Drive"
|
||||
msgstr "Ook uit Proton Drive verwijderen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:949
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:971
|
||||
msgid "Deletes the only copy of these files."
|
||||
msgstr "Verwijdert de enige kopie van deze bestanden."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:951
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:973
|
||||
msgid "The local copy is unaffected."
|
||||
msgstr "De lokale kopie blijft ongewijzigd."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:958
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:980
|
||||
msgid "Stop Syncing"
|
||||
msgstr "Synchroniseren stoppen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:971
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:993
|
||||
msgid "Stopped syncing folder"
|
||||
msgstr "Synchroniseren van map gestopt"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:972
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:994
|
||||
msgid "Couldn't stop syncing the folder"
|
||||
msgstr "Kon het synchroniseren van de map niet stoppen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:983
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1005
|
||||
msgid "Rename Computer"
|
||||
msgstr "Computer hernoemen"
|
||||
|
||||
#. Translators: {name} is the computer's current name.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:985
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1007
|
||||
#, rust-format
|
||||
msgid "Rename “{name}”."
|
||||
msgstr "“{name}” hernoemen."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1010
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1022
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1032
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1044
|
||||
msgid "Couldn't rename the computer"
|
||||
msgstr "Kon de computer niet hernoemen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1011
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1033
|
||||
msgid "A name is required."
|
||||
msgstr "Een naam is vereist."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1021
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1043
|
||||
msgid "Computer renamed"
|
||||
msgstr "Computer hernoemd"
|
||||
|
||||
#. Translators: {name} is the computer's name, which the user must type.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1034
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1056
|
||||
#, rust-format
|
||||
msgid "Type “{name}” to confirm"
|
||||
msgstr "Typ “{name}” om te bevestigen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1039
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1061
|
||||
msgid "Remove Computer?"
|
||||
msgstr "Computer verwijderen?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1042
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1064
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"Remove “{name}” from this account?\n"
|
||||
@@ -2504,26 +2528,26 @@ msgstr ""
|
||||
"mee verwijderd. De bestanden op die computer zelf blijven onaangeroerd — "
|
||||
"maar dit kan hier niet ongedaan worden gemaakt."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1048
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1070
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1025
|
||||
#: crates/pdfs-gui/src/app/widgets/share_dialog.rs:634
|
||||
#: crates/pdfs-gui/src/app/widgets/share_dialog.rs:876
|
||||
msgid "Remove"
|
||||
msgstr "Verwijderen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1065
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1087
|
||||
msgid "Computer removed"
|
||||
msgstr "Computer verwijderd"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1066
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1088
|
||||
msgid "Couldn't remove the computer"
|
||||
msgstr "Kon de computer niet verwijderen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1084
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1106
|
||||
msgid "Continue This Backup Here?"
|
||||
msgstr "Deze back-up hier voortzetten?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1087
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1109
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"This computer takes over the backup of “{name}”, for example after a "
|
||||
@@ -2542,25 +2566,25 @@ msgstr ""
|
||||
"gesynchroniseerd, worden niet verplaatst. Gebruik daarna “Terugzetten op "
|
||||
"deze computer” om terug te halen wat “{name}” synchroniseerde."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1092
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1114
|
||||
msgid "Continue Here"
|
||||
msgstr "Hier voortzetten"
|
||||
|
||||
#. Translators: {name} is the name of the computer whose backup this one took over.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1099
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1121
|
||||
#, rust-format
|
||||
msgid "Now backing up as “{name}”"
|
||||
msgstr "Back-up nu als “{name}”"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1108
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1130
|
||||
msgid "Couldn't continue that backup here"
|
||||
msgstr "Kon die back-up hier niet voortzetten"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1124
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1146
|
||||
msgid "Sync With This Computer?"
|
||||
msgstr "Synchroniseren met deze computer?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1127
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1149
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"This computer and “{name}” keep the same folders in step. A change or a "
|
||||
@@ -2577,25 +2601,25 @@ msgstr ""
|
||||
"Proton Drive. Mappen die hier al worden gesynchroniseerd, blijven waar ze "
|
||||
"zijn. Daarna kiest u welke van zijn mappen u hier synchroniseert."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1132
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1154
|
||||
msgid "Sync Here"
|
||||
msgstr "Hier synchroniseren"
|
||||
|
||||
#. Translators: {name} is the name of the other computer this one now syncs with.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1139
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1161
|
||||
#, rust-format
|
||||
msgid "Now syncing with “{name}”"
|
||||
msgstr "Nu gesynchroniseerd met “{name}”"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1155
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1177
|
||||
msgid "Couldn't sync with that computer"
|
||||
msgstr "Kon niet synchroniseren met die computer"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1187
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1209
|
||||
msgid "Move Backup to This Computer?"
|
||||
msgstr "Back-up naar deze computer verplaatsen?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1190
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1212
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"The folders backed up by “{name}” move into this computer's backup in Proton "
|
||||
@@ -2611,12 +2635,12 @@ msgstr ""
|
||||
"Stop Proton Drive eerst op “{name}”. Anders ziet het zijn mappen verdwijnen."
|
||||
|
||||
#. Translators: {name} is the name of the computer whose folders moved to this one.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1202
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1224
|
||||
#, rust-format
|
||||
msgid "Moved the backup of “{name}”"
|
||||
msgstr "Back-up van “{name}” verplaatst"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1216
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1238
|
||||
msgid "Couldn't move that backup"
|
||||
msgstr "Kon die back-up niet verplaatsen"
|
||||
|
||||
@@ -2896,7 +2920,7 @@ msgid "Sync paused until you resume"
|
||||
msgstr "Synchronisatie gepauzeerd totdat je hervat"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:570
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1445 crates/pdfs-gui/src/main.rs:290
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1445 crates/pdfs-gui/src/main.rs:308
|
||||
msgid "Sync paused"
|
||||
msgstr "Synchronisatie gepauzeerd"
|
||||
|
||||
@@ -3358,7 +3382,7 @@ msgid "paused"
|
||||
msgstr "gepauzeerd"
|
||||
|
||||
#. Translators: a folder's files can't be opened right now.
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1742
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1745
|
||||
msgid "not available"
|
||||
msgstr "niet beschikbaar"
|
||||
|
||||
@@ -5108,7 +5132,7 @@ msgstr "Hervat {time}"
|
||||
msgid "Until you resume"
|
||||
msgstr "Totdat je hervat"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1464 crates/pdfs-gui/src/main.rs:292
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1464 crates/pdfs-gui/src/main.rs:310
|
||||
#, rust-format
|
||||
msgid "{n} change needs attention"
|
||||
msgid_plural "{n} changes need attention"
|
||||
@@ -6337,52 +6361,57 @@ msgstr "Proton Drive reageert niet"
|
||||
msgid "Signed in as {username} — locked"
|
||||
msgstr "Aangemeld als {username} — vergrendeld"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:200
|
||||
#: crates/pdfs-gui/src/main.rs:209
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — can't open your Drive"
|
||||
msgstr "Aangemeld als {username} — kan Proton Drive niet openen"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:218
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — not connected"
|
||||
msgstr "Aangemeld als {username} — niet verbonden"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:205
|
||||
#: crates/pdfs-gui/src/main.rs:223
|
||||
msgid "Not signed in"
|
||||
msgstr "Niet aangemeld"
|
||||
|
||||
#. Translators: {error} is an error message, in English.
|
||||
#: crates/pdfs-gui/src/main.rs:208
|
||||
#: crates/pdfs-gui/src/main.rs:226
|
||||
#, rust-format
|
||||
msgid "Error: {error}"
|
||||
msgstr "Fout: {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:230
|
||||
#: crates/pdfs-gui/src/main.rs:248
|
||||
msgid "Proton Drive sent an unexpected reply"
|
||||
msgstr "Proton Drive gaf een onverwacht antwoord"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:284
|
||||
#: crates/pdfs-gui/src/main.rs:302
|
||||
msgid "Session expired — sign in again"
|
||||
msgstr "Sessie verlopen — meld je opnieuw aan"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:286
|
||||
#: crates/pdfs-gui/src/main.rs:304
|
||||
msgid "Sign-in not saved — unlock your keyring"
|
||||
msgstr "Aanmelding niet opgeslagen — ontgrendel je sleutelbos"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:289
|
||||
#: crates/pdfs-gui/src/main.rs:307
|
||||
msgid "Update not finished — restart Proton Drive"
|
||||
msgstr "Update niet voltooid — start Proton Drive opnieuw"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:299
|
||||
#: crates/pdfs-gui/src/main.rs:317
|
||||
#, rust-format
|
||||
msgid "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgid_plural "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgstr[0] "Bijgewerkt in {mountpoint} ({n} vastgezet)"
|
||||
msgstr[1] "Bijgewerkt in {mountpoint} ({n} vastgezet)"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:306
|
||||
#: crates/pdfs-gui/src/main.rs:324
|
||||
#, rust-format
|
||||
msgid "Syncing — {queued} ({n} pinned)"
|
||||
msgid_plural "Syncing — {queued} ({n} pinned)"
|
||||
msgstr[0] "Synchroniseren — {queued} ({n} vastgezet)"
|
||||
msgstr[1] "Synchroniseren — {queued} ({n} vastgezet)"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:313
|
||||
#: crates/pdfs-gui/src/main.rs:331
|
||||
#, rust-format
|
||||
msgid "Offline — cached files only ({n} pinned)"
|
||||
msgid_plural "Offline — cached files only ({n} pinned)"
|
||||
@@ -6390,60 +6419,60 @@ msgstr[0] "Offline — alleen bestanden in cache ({n} vastgezet)"
|
||||
msgstr[1] "Offline — alleen bestanden in cache ({n} vastgezet)"
|
||||
|
||||
#. Translators: {queued} is a queue summary such as "3 uploads queued".
|
||||
#: crates/pdfs-gui/src/main.rs:319
|
||||
#: crates/pdfs-gui/src/main.rs:337
|
||||
#, rust-format
|
||||
msgid "Offline — {queued}"
|
||||
msgstr "Offline — {queued}"
|
||||
|
||||
#. Translators: a menu item that opens the list of failing changes.
|
||||
#: crates/pdfs-gui/src/main.rs:358
|
||||
#: crates/pdfs-gui/src/main.rs:376
|
||||
#, rust-format
|
||||
msgid "{n} issue — View"
|
||||
msgid_plural "{n} issues — View"
|
||||
msgstr[0] "{n} probleem — Bekijken"
|
||||
msgstr[1] "{n} problemen — Bekijken"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:465
|
||||
#: crates/pdfs-gui/src/main.rs:483
|
||||
msgid "Sign In…"
|
||||
msgstr "Aanmelden…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:466
|
||||
#: crates/pdfs-gui/src/main.rs:484
|
||||
msgid "Sign In Again…"
|
||||
msgstr "Opnieuw aanmelden…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:469
|
||||
#: crates/pdfs-gui/src/main.rs:487
|
||||
msgid "Open Proton Drive"
|
||||
msgstr "Proton Drive openen"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:473
|
||||
#: crates/pdfs-gui/src/main.rs:491
|
||||
msgid "Restart Proton Drive"
|
||||
msgstr "Proton Drive opnieuw starten"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:482
|
||||
#: crates/pdfs-gui/src/main.rs:500
|
||||
msgid "Open Folder"
|
||||
msgstr "Map openen"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:494
|
||||
#: crates/pdfs-gui/src/main.rs:512
|
||||
msgid "Resume Sync"
|
||||
msgstr "Synchronisatie hervatten"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:496
|
||||
#: crates/pdfs-gui/src/main.rs:514
|
||||
msgid "Pause Sync"
|
||||
msgstr "Synchronisatie pauzeren"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:515
|
||||
#: crates/pdfs-gui/src/main.rs:533
|
||||
msgid "Connect"
|
||||
msgstr "Verbinden"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:522
|
||||
#: crates/pdfs-gui/src/main.rs:540
|
||||
msgid "Hide Tray Icon"
|
||||
msgstr "Pictogram in systeemvak verbergen"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:526
|
||||
#: crates/pdfs-gui/src/main.rs:544
|
||||
msgid "Stop Proton Drive…"
|
||||
msgstr "Proton Drive stoppen…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:530
|
||||
#: crates/pdfs-gui/src/main.rs:548
|
||||
msgid "Quit"
|
||||
msgstr "Afsluiten"
|
||||
|
||||
|
||||
+137
-110
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: proton-drive-linux 3.6.0\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/narrrl/proton-drive-linux/issues\n"
|
||||
"POT-Creation-Date: 2026-10-26 22:28+0100\n"
|
||||
"POT-Creation-Date: 2026-10-31 19:26+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -222,13 +222,13 @@ msgstr ""
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1917
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2039
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2540
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:804
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:957
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:995
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1047
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1091
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1131
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1194
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:826
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:979
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1017
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1069
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1113
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1153
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1216
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:850
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1054
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1537
|
||||
@@ -323,7 +323,7 @@ msgstr ""
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:298
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1896
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1918
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:996
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1018
|
||||
#: crates/pdfs-gui/src/app/widgets/details.rs:161
|
||||
msgid "Rename"
|
||||
msgstr ""
|
||||
@@ -397,14 +397,25 @@ msgstr ""
|
||||
msgid "The Proton Drive service isn't running."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1803
|
||||
#: crates/pdfs-gui/src/app/main.rs:1813
|
||||
msgid "Can't open your Drive"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1816
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"The Proton Drive service keeps failing to start and tries again on its own. "
|
||||
"The last error was: {error}"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1824
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:355
|
||||
#: crates/pdfs-gui/src/hud/mod.rs:269 crates/pdfs-gui/src/hud/mod.rs:579
|
||||
#: crates/pdfs-gui/src/main.rs:475 crates/pdfs-gui/src/main.rs:517
|
||||
#: crates/pdfs-gui/src/main.rs:493 crates/pdfs-gui/src/main.rs:535
|
||||
msgid "Connecting…"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1804
|
||||
#: crates/pdfs-gui/src/app/main.rs:1825
|
||||
msgid "Waiting for the Proton Drive service to start."
|
||||
msgstr ""
|
||||
|
||||
@@ -649,7 +660,7 @@ msgid "Couldn't add a sync folder"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/activity_text.rs:58
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:839
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:861
|
||||
msgid "Couldn't restore folders"
|
||||
msgstr ""
|
||||
|
||||
@@ -1227,12 +1238,12 @@ msgstr ""
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1873
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2500
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2650
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:707
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:747
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:900
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1170
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1231
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1260
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:729
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:769
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:922
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1192
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1253
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1282
|
||||
#: crates/pdfs-gui/src/app/pages/duplicates.rs:221
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:577
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:824
|
||||
@@ -1875,7 +1886,7 @@ msgid "{status}. {message}"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1900
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:989
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1011
|
||||
msgid "New name"
|
||||
msgstr ""
|
||||
|
||||
@@ -1900,7 +1911,7 @@ msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1989
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1994
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1195
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1217
|
||||
msgid "Move Here"
|
||||
msgstr ""
|
||||
|
||||
@@ -2221,127 +2232,138 @@ msgid_plural "{n} folders backed up"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:608
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:607
|
||||
#, rust-format
|
||||
msgid "{folders} · {n} waiting for its first sync"
|
||||
msgid_plural "{folders} · {n} waiting for their first sync"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:621
|
||||
#, rust-format
|
||||
msgid "{folders} · {n} needs attention"
|
||||
msgid_plural "{folders} · {n} need attention"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:619
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:640
|
||||
msgid "syncing…"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:620
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:641
|
||||
msgid "sync error"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:621
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:642
|
||||
msgid "needs attention"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:622
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:643
|
||||
msgid "waiting for first sync"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:644
|
||||
msgid "up to date"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:632
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:654
|
||||
msgid "checking for changes…"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:638
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:660
|
||||
#, rust-format
|
||||
msgid "checking for changes — {n} item checked"
|
||||
msgid_plural "checking for changes — {n} items checked"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:645
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:667
|
||||
#, rust-format
|
||||
msgid "checking for changes — {done} of {total}"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:657
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:679
|
||||
#, rust-format
|
||||
msgid "syncing {done} of {total}"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:663
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:685
|
||||
#, rust-format
|
||||
msgid "syncing {file} — {done} of {total}"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:675
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:697
|
||||
msgid "Add Folder to Sync"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:699
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:721
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1559
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1686
|
||||
msgid "Syncing folder…"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:702
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:706
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:724
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:728
|
||||
msgid "Couldn't add folder"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:740
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:746
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:762
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:768
|
||||
msgid "Couldn't list folders to restore"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:772
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:794
|
||||
msgid ""
|
||||
"Tick the folders to sync to this machine, and adjust where each one should "
|
||||
"live."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:798
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:820
|
||||
msgid "Restore Folders"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:805
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:827
|
||||
msgid "Restore"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:838
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:860
|
||||
msgid "Restoring folders…"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:850
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:872
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"These folders are backed up from “{name}”. Restored folders keep syncing "
|
||||
"with that computer's copy."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:853
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:875
|
||||
msgid "These folders are backed up under this computer in Proton Drive."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:862
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:884
|
||||
#, rust-format
|
||||
msgid "Nothing to restore — “{name}”'s folders are all synced here."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:865
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:887
|
||||
msgid "Nothing to restore — this computer's folders are all synced here."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:889
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:911
|
||||
msgid "Folder will switch to online only"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:891
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:913
|
||||
msgid "Folder will download and stay synced"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:895
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:899
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:917
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:921
|
||||
msgid "Couldn't change mode"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:931
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:953
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"Stop syncing “{path}”?\n"
|
||||
@@ -2352,7 +2374,7 @@ msgid ""
|
||||
"finish before removing it."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:937
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:959
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"Stop syncing “{path}”?\n"
|
||||
@@ -2361,68 +2383,68 @@ msgid ""
|
||||
"whether to also delete the copy in Proton Drive."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:942
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:964
|
||||
msgid "Stop Syncing Folder?"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:947
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:969
|
||||
msgid "Also delete from Proton Drive"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:949
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:971
|
||||
msgid "Deletes the only copy of these files."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:951
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:973
|
||||
msgid "The local copy is unaffected."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:958
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:980
|
||||
msgid "Stop Syncing"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:971
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:993
|
||||
msgid "Stopped syncing folder"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:972
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:994
|
||||
msgid "Couldn't stop syncing the folder"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:983
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1005
|
||||
msgid "Rename Computer"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: {name} is the computer's current name.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:985
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1007
|
||||
#, rust-format
|
||||
msgid "Rename “{name}”."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1010
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1022
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1032
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1044
|
||||
msgid "Couldn't rename the computer"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1011
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1033
|
||||
msgid "A name is required."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1021
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1043
|
||||
msgid "Computer renamed"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: {name} is the computer's name, which the user must type.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1034
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1056
|
||||
#, rust-format
|
||||
msgid "Type “{name}” to confirm"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1039
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1061
|
||||
msgid "Remove Computer?"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1042
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1064
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"Remove “{name}” from this account?\n"
|
||||
@@ -2432,26 +2454,26 @@ msgid ""
|
||||
"here."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1048
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1070
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1025
|
||||
#: crates/pdfs-gui/src/app/widgets/share_dialog.rs:634
|
||||
#: crates/pdfs-gui/src/app/widgets/share_dialog.rs:876
|
||||
msgid "Remove"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1065
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1087
|
||||
msgid "Computer removed"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1066
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1088
|
||||
msgid "Couldn't remove the computer"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1084
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1106
|
||||
msgid "Continue This Backup Here?"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1087
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1109
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"This computer takes over the backup of “{name}”, for example after a "
|
||||
@@ -2463,25 +2485,25 @@ msgid ""
|
||||
"syncing."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1092
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1114
|
||||
msgid "Continue Here"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: {name} is the name of the computer whose backup this one took over.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1099
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1121
|
||||
#, rust-format
|
||||
msgid "Now backing up as “{name}”"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1108
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1130
|
||||
msgid "Couldn't continue that backup here"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1124
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1146
|
||||
msgid "Sync With This Computer?"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1127
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1149
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"This computer and “{name}” keep the same folders in step. A change or a "
|
||||
@@ -2492,25 +2514,25 @@ msgid ""
|
||||
"its folders to sync here."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1132
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1154
|
||||
msgid "Sync Here"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: {name} is the name of the other computer this one now syncs with.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1139
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1161
|
||||
#, rust-format
|
||||
msgid "Now syncing with “{name}”"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1155
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1177
|
||||
msgid "Couldn't sync with that computer"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1187
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1209
|
||||
msgid "Move Backup to This Computer?"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1190
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1212
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"The folders backed up by “{name}” move into this computer's backup in Proton "
|
||||
@@ -2521,12 +2543,12 @@ msgid ""
|
||||
msgstr ""
|
||||
|
||||
#. Translators: {name} is the name of the computer whose folders moved to this one.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1202
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1224
|
||||
#, rust-format
|
||||
msgid "Moved the backup of “{name}”"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1216
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1238
|
||||
msgid "Couldn't move that backup"
|
||||
msgstr ""
|
||||
|
||||
@@ -2788,7 +2810,7 @@ msgid "Sync paused until you resume"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:570
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1445 crates/pdfs-gui/src/main.rs:290
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1445 crates/pdfs-gui/src/main.rs:308
|
||||
msgid "Sync paused"
|
||||
msgstr ""
|
||||
|
||||
@@ -3210,7 +3232,7 @@ msgid "paused"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: a folder's files can't be opened right now.
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1742
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1745
|
||||
msgid "not available"
|
||||
msgstr ""
|
||||
|
||||
@@ -4883,7 +4905,7 @@ msgstr ""
|
||||
msgid "Until you resume"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1464 crates/pdfs-gui/src/main.rs:292
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1464 crates/pdfs-gui/src/main.rs:310
|
||||
#, rust-format
|
||||
msgid "{n} change needs attention"
|
||||
msgid_plural "{n} changes need attention"
|
||||
@@ -6071,52 +6093,57 @@ msgstr ""
|
||||
msgid "Signed in as {username} — locked"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:200
|
||||
#: crates/pdfs-gui/src/main.rs:209
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — can't open your Drive"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:218
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — not connected"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:205
|
||||
#: crates/pdfs-gui/src/main.rs:223
|
||||
msgid "Not signed in"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: {error} is an error message, in English.
|
||||
#: crates/pdfs-gui/src/main.rs:208
|
||||
#: crates/pdfs-gui/src/main.rs:226
|
||||
#, rust-format
|
||||
msgid "Error: {error}"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:230
|
||||
#: crates/pdfs-gui/src/main.rs:248
|
||||
msgid "Proton Drive sent an unexpected reply"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:284
|
||||
#: crates/pdfs-gui/src/main.rs:302
|
||||
msgid "Session expired — sign in again"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:286
|
||||
#: crates/pdfs-gui/src/main.rs:304
|
||||
msgid "Sign-in not saved — unlock your keyring"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:289
|
||||
#: crates/pdfs-gui/src/main.rs:307
|
||||
msgid "Update not finished — restart Proton Drive"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:299
|
||||
#: crates/pdfs-gui/src/main.rs:317
|
||||
#, rust-format
|
||||
msgid "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgid_plural "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:306
|
||||
#: crates/pdfs-gui/src/main.rs:324
|
||||
#, rust-format
|
||||
msgid "Syncing — {queued} ({n} pinned)"
|
||||
msgid_plural "Syncing — {queued} ({n} pinned)"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:313
|
||||
#: crates/pdfs-gui/src/main.rs:331
|
||||
#, rust-format
|
||||
msgid "Offline — cached files only ({n} pinned)"
|
||||
msgid_plural "Offline — cached files only ({n} pinned)"
|
||||
@@ -6124,60 +6151,60 @@ msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#. Translators: {queued} is a queue summary such as "3 uploads queued".
|
||||
#: crates/pdfs-gui/src/main.rs:319
|
||||
#: crates/pdfs-gui/src/main.rs:337
|
||||
#, rust-format
|
||||
msgid "Offline — {queued}"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: a menu item that opens the list of failing changes.
|
||||
#: crates/pdfs-gui/src/main.rs:358
|
||||
#: crates/pdfs-gui/src/main.rs:376
|
||||
#, rust-format
|
||||
msgid "{n} issue — View"
|
||||
msgid_plural "{n} issues — View"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:465
|
||||
#: crates/pdfs-gui/src/main.rs:483
|
||||
msgid "Sign In…"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:466
|
||||
#: crates/pdfs-gui/src/main.rs:484
|
||||
msgid "Sign In Again…"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:469
|
||||
#: crates/pdfs-gui/src/main.rs:487
|
||||
msgid "Open Proton Drive"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:473
|
||||
#: crates/pdfs-gui/src/main.rs:491
|
||||
msgid "Restart Proton Drive"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:482
|
||||
#: crates/pdfs-gui/src/main.rs:500
|
||||
msgid "Open Folder"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:494
|
||||
#: crates/pdfs-gui/src/main.rs:512
|
||||
msgid "Resume Sync"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:496
|
||||
#: crates/pdfs-gui/src/main.rs:514
|
||||
msgid "Pause Sync"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:515
|
||||
#: crates/pdfs-gui/src/main.rs:533
|
||||
msgid "Connect"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:522
|
||||
#: crates/pdfs-gui/src/main.rs:540
|
||||
msgid "Hide Tray Icon"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:526
|
||||
#: crates/pdfs-gui/src/main.rs:544
|
||||
msgid "Stop Proton Drive…"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:530
|
||||
#: crates/pdfs-gui/src/main.rs:548
|
||||
msgid "Quit"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: proton-drive-linux 2.1.0\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/narrrl/proton-drive-linux/issues\n"
|
||||
"POT-Creation-Date: 2026-10-26 22:26+0100\n"
|
||||
"POT-Creation-Date: 2026-10-31 19:26+0100\n"
|
||||
"PO-Revision-Date: 2026-09-23 12:00+0200\n"
|
||||
"Last-Translator: Proton Drive for Linux contributors\n"
|
||||
"Language-Team: Polish\n"
|
||||
@@ -250,13 +250,13 @@ msgstr ""
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1917
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2039
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2540
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:804
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:957
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:995
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1047
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1091
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1131
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1194
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:826
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:979
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1017
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1069
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1113
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1153
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1216
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:850
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1054
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1537
|
||||
@@ -351,7 +351,7 @@ msgstr "Siatka/lista"
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:298
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1896
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1918
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:996
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1018
|
||||
#: crates/pdfs-gui/src/app/widgets/details.rs:161
|
||||
msgid "Rename"
|
||||
msgstr "Zmień nazwę"
|
||||
@@ -425,14 +425,27 @@ msgstr "Brak połączenia"
|
||||
msgid "The Proton Drive service isn't running."
|
||||
msgstr "Usługa Proton Drive nie jest uruchomiona."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1803
|
||||
#: crates/pdfs-gui/src/app/main.rs:1813
|
||||
msgid "Can't open your Drive"
|
||||
msgstr "Nie można otworzyć Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1816
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"The Proton Drive service keeps failing to start and tries again on its own. "
|
||||
"The last error was: {error}"
|
||||
msgstr ""
|
||||
"Usługa Proton Drive nie może się uruchomić i sama ponawia próby. Ostatni "
|
||||
"błąd: {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1824
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:355
|
||||
#: crates/pdfs-gui/src/hud/mod.rs:269 crates/pdfs-gui/src/hud/mod.rs:579
|
||||
#: crates/pdfs-gui/src/main.rs:475 crates/pdfs-gui/src/main.rs:517
|
||||
#: crates/pdfs-gui/src/main.rs:493 crates/pdfs-gui/src/main.rs:535
|
||||
msgid "Connecting…"
|
||||
msgstr "Łączenie…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1804
|
||||
#: crates/pdfs-gui/src/app/main.rs:1825
|
||||
msgid "Waiting for the Proton Drive service to start."
|
||||
msgstr "Oczekiwanie na uruchomienie usługi Proton Drive."
|
||||
|
||||
@@ -696,7 +709,7 @@ msgid "Couldn't add a sync folder"
|
||||
msgstr "Nie można dodać katalogu synchronizacji"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/activity_text.rs:58
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:839
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:861
|
||||
msgid "Couldn't restore folders"
|
||||
msgstr "Nie można przywrócić katalogów"
|
||||
|
||||
@@ -1300,12 +1313,12 @@ msgstr "Nie można wczytać albumów"
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1873
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2500
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2650
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:707
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:747
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:900
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1170
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1231
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1260
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:729
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:769
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:922
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1192
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1253
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1282
|
||||
#: crates/pdfs-gui/src/app/pages/duplicates.rs:221
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:577
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:824
|
||||
@@ -1969,7 +1982,7 @@ msgid "{status}. {message}"
|
||||
msgstr "{status}. {message}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1900
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:989
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1011
|
||||
msgid "New name"
|
||||
msgstr "Nowa nazwa"
|
||||
|
||||
@@ -1994,7 +2007,7 @@ msgstr "Proszę wybrać katalog docelowy."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1989
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1994
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1195
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1217
|
||||
msgid "Move Here"
|
||||
msgstr "Przenieś tutaj"
|
||||
|
||||
@@ -2327,7 +2340,15 @@ msgstr[0] "{n} katalog z kopią zapasową"
|
||||
msgstr[1] "{n} katalogi z kopią zapasową"
|
||||
msgstr[2] "{n} katalogów z kopią zapasową"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:608
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:607
|
||||
#, rust-format
|
||||
msgid "{folders} · {n} waiting for its first sync"
|
||||
msgid_plural "{folders} · {n} waiting for their first sync"
|
||||
msgstr[0] "{folders} · {n} czeka na pierwszą synchronizację"
|
||||
msgstr[1] "{folders} · {n} czekają na pierwszą synchronizację"
|
||||
msgstr[2] "{folders} · {n} czeka na pierwszą synchronizację"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:621
|
||||
#, rust-format
|
||||
msgid "{folders} · {n} needs attention"
|
||||
msgid_plural "{folders} · {n} need attention"
|
||||
@@ -2335,27 +2356,31 @@ msgstr[0] "{folders} · {n} wymaga uwagi"
|
||||
msgstr[1] "{folders} · {n} wymagają uwagi"
|
||||
msgstr[2] "{folders} · {n} wymaga uwagi"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:619
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:640
|
||||
msgid "syncing…"
|
||||
msgstr "synchronizowanie…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:620
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:641
|
||||
msgid "sync error"
|
||||
msgstr "błąd synchronizacji"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:621
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:642
|
||||
msgid "needs attention"
|
||||
msgstr "wymaga uwagi"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:622
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:643
|
||||
msgid "waiting for first sync"
|
||||
msgstr "oczekiwanie na pierwszą synchronizację"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:644
|
||||
msgid "up to date"
|
||||
msgstr "aktualne"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:632
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:654
|
||||
msgid "checking for changes…"
|
||||
msgstr "sprawdzanie zmian…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:638
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:660
|
||||
#, rust-format
|
||||
msgid "checking for changes — {n} item checked"
|
||||
msgid_plural "checking for changes — {n} items checked"
|
||||
@@ -2363,42 +2388,42 @@ msgstr[0] "sprawdzanie zmian — sprawdzono {n} element"
|
||||
msgstr[1] "sprawdzanie zmian — sprawdzono {n} elementy"
|
||||
msgstr[2] "sprawdzanie zmian — sprawdzono {n} elementów"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:645
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:667
|
||||
#, rust-format
|
||||
msgid "checking for changes — {done} of {total}"
|
||||
msgstr "sprawdzanie zmian — {done} z {total}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:657
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:679
|
||||
#, rust-format
|
||||
msgid "syncing {done} of {total}"
|
||||
msgstr "synchronizowanie {done} z {total}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:663
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:685
|
||||
#, rust-format
|
||||
msgid "syncing {file} — {done} of {total}"
|
||||
msgstr "synchronizowanie {file} — {done} z {total}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:675
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:697
|
||||
msgid "Add Folder to Sync"
|
||||
msgstr "Dodaj katalog do synchronizacji"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:699
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:721
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1559
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1686
|
||||
msgid "Syncing folder…"
|
||||
msgstr "Synchronizowanie katalogu…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:702
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:706
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:724
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:728
|
||||
msgid "Couldn't add folder"
|
||||
msgstr "Nie można dodać katalogu"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:740
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:746
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:762
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:768
|
||||
msgid "Couldn't list folders to restore"
|
||||
msgstr "Nie można wyświetlić listy katalogów do przywrócenia"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:772
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:794
|
||||
msgid ""
|
||||
"Tick the folders to sync to this machine, and adjust where each one should "
|
||||
"live."
|
||||
@@ -2406,19 +2431,19 @@ msgstr ""
|
||||
"Należy zaznaczyć katalogi do synchronizacji z tym komputerem i dostosować "
|
||||
"położenie każdego z nich."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:798
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:820
|
||||
msgid "Restore Folders"
|
||||
msgstr "Przywróć katalogi"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:805
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:827
|
||||
msgid "Restore"
|
||||
msgstr "Przywróć"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:838
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:860
|
||||
msgid "Restoring folders…"
|
||||
msgstr "Przywracanie katalogów…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:850
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:872
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"These folders are backed up from “{name}”. Restored folders keep syncing "
|
||||
@@ -2427,37 +2452,37 @@ msgstr ""
|
||||
"Te katalogi mają kopię zapasową z komputera „{name}”. Przywrócone katalogi "
|
||||
"nadal będą synchronizowane z kopią tego komputera."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:853
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:875
|
||||
msgid "These folders are backed up under this computer in Proton Drive."
|
||||
msgstr "Te katalogi mają kopię zapasową w Proton Drive pod tym komputerem."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:862
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:884
|
||||
#, rust-format
|
||||
msgid "Nothing to restore — “{name}”'s folders are all synced here."
|
||||
msgstr ""
|
||||
"Nie ma nic do przywrócenia — wszystkie katalogi komputera „{name}” są tutaj "
|
||||
"synchronizowane."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:865
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:887
|
||||
msgid "Nothing to restore — this computer's folders are all synced here."
|
||||
msgstr ""
|
||||
"Nie ma nic do przywrócenia — wszystkie katalogi tego komputera są tutaj "
|
||||
"synchronizowane."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:889
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:911
|
||||
msgid "Folder will switch to online only"
|
||||
msgstr "Katalog przejdzie w tryb tylko online"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:891
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:913
|
||||
msgid "Folder will download and stay synced"
|
||||
msgstr "Katalog zostanie pobrany i będzie synchronizowany"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:895
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:899
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:917
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:921
|
||||
msgid "Couldn't change mode"
|
||||
msgstr "Nie można zmienić trybu"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:931
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:953
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"Stop syncing “{path}”?\n"
|
||||
@@ -2474,7 +2499,7 @@ msgstr ""
|
||||
"pusty. Aby zachować lokalną kopię, należy anulować, przełączyć katalog na "
|
||||
"tryb Synchronizowany i poczekać na ukończenie pobierania przed usunięciem."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:937
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:959
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"Stop syncing “{path}”?\n"
|
||||
@@ -2487,68 +2512,68 @@ msgstr ""
|
||||
"Lokalne pliki pozostaną na tym dysku i po prostu przestaną być "
|
||||
"synchronizowane. Można też usunąć kopię w Proton Drive."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:942
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:964
|
||||
msgid "Stop Syncing Folder?"
|
||||
msgstr "Zatrzymać synchronizację katalogu?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:947
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:969
|
||||
msgid "Also delete from Proton Drive"
|
||||
msgstr "Usuń także z Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:949
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:971
|
||||
msgid "Deletes the only copy of these files."
|
||||
msgstr "Usuwa jedyną kopię tych plików."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:951
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:973
|
||||
msgid "The local copy is unaffected."
|
||||
msgstr "Lokalna kopia pozostanie bez zmian."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:958
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:980
|
||||
msgid "Stop Syncing"
|
||||
msgstr "Zatrzymaj synchronizację"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:971
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:993
|
||||
msgid "Stopped syncing folder"
|
||||
msgstr "Zatrzymano synchronizację katalogu"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:972
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:994
|
||||
msgid "Couldn't stop syncing the folder"
|
||||
msgstr "Nie można zatrzymać synchronizacji katalogu"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:983
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1005
|
||||
msgid "Rename Computer"
|
||||
msgstr "Zmiana nazwy komputera"
|
||||
|
||||
#. Translators: {name} is the computer's current name.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:985
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1007
|
||||
#, rust-format
|
||||
msgid "Rename “{name}”."
|
||||
msgstr "Proszę podać nową nazwę komputera „{name}”."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1010
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1022
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1032
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1044
|
||||
msgid "Couldn't rename the computer"
|
||||
msgstr "Nie można zmienić nazwy komputera"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1011
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1033
|
||||
msgid "A name is required."
|
||||
msgstr "Nazwa jest wymagana."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1021
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1043
|
||||
msgid "Computer renamed"
|
||||
msgstr "Zmieniono nazwę komputera"
|
||||
|
||||
#. Translators: {name} is the computer's name, which the user must type.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1034
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1056
|
||||
#, rust-format
|
||||
msgid "Type “{name}” to confirm"
|
||||
msgstr "Proszę wpisać „{name}”, aby potwierdzić"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1039
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1061
|
||||
msgid "Remove Computer?"
|
||||
msgstr "Usunąć komputer?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1042
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1064
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"Remove “{name}” from this account?\n"
|
||||
@@ -2563,26 +2588,26 @@ msgstr ""
|
||||
"z nim. Pliki na samym komputerze pozostaną nietknięte — ale tej operacji nie "
|
||||
"można tutaj cofnąć."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1048
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1070
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1025
|
||||
#: crates/pdfs-gui/src/app/widgets/share_dialog.rs:634
|
||||
#: crates/pdfs-gui/src/app/widgets/share_dialog.rs:876
|
||||
msgid "Remove"
|
||||
msgstr "Usuń"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1065
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1087
|
||||
msgid "Computer removed"
|
||||
msgstr "Usunięto komputer"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1066
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1088
|
||||
msgid "Couldn't remove the computer"
|
||||
msgstr "Nie można usunąć komputera"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1084
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1106
|
||||
msgid "Continue This Backup Here?"
|
||||
msgstr "Kontynuować tę kopię zapasową tutaj?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1087
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1109
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"This computer takes over the backup of “{name}”, for example after a "
|
||||
@@ -2601,25 +2626,25 @@ msgstr ""
|
||||
"przeniesione. Aby odzyskać to, co synchronizował „{name}”, proszę potem użyć "
|
||||
"opcji „Przywróć na tym komputerze”."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1092
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1114
|
||||
msgid "Continue Here"
|
||||
msgstr "Kontynuuj tutaj"
|
||||
|
||||
#. Translators: {name} is the name of the computer whose backup this one took over.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1099
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1121
|
||||
#, rust-format
|
||||
msgid "Now backing up as “{name}”"
|
||||
msgstr "Kopia zapasowa jest teraz tworzona jako „{name}”"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1108
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1130
|
||||
msgid "Couldn't continue that backup here"
|
||||
msgstr "Nie można kontynuować tej kopii zapasowej tutaj"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1124
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1146
|
||||
msgid "Sync With This Computer?"
|
||||
msgstr "Synchronizować z tym komputerem?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1127
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1149
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"This computer and “{name}” keep the same folders in step. A change or a "
|
||||
@@ -2636,25 +2661,25 @@ msgstr ""
|
||||
"Drive. Katalogi już tu synchronizowane zostaną tam, gdzie są. Następnie "
|
||||
"proszę wybrać, które z jego katalogów synchronizować tutaj."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1132
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1154
|
||||
msgid "Sync Here"
|
||||
msgstr "Synchronizuj tutaj"
|
||||
|
||||
#. Translators: {name} is the name of the other computer this one now syncs with.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1139
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1161
|
||||
#, rust-format
|
||||
msgid "Now syncing with “{name}”"
|
||||
msgstr "Teraz synchronizowane z „{name}”"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1155
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1177
|
||||
msgid "Couldn't sync with that computer"
|
||||
msgstr "Nie można synchronizować z tym komputerem"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1187
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1209
|
||||
msgid "Move Backup to This Computer?"
|
||||
msgstr "Przenieść kopię zapasową na ten komputer?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1190
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1212
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"The folders backed up by “{name}” move into this computer's backup in Proton "
|
||||
@@ -2672,12 +2697,12 @@ msgstr ""
|
||||
"jego foldery znikają."
|
||||
|
||||
#. Translators: {name} is the name of the computer whose folders moved to this one.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1202
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1224
|
||||
#, rust-format
|
||||
msgid "Moved the backup of “{name}”"
|
||||
msgstr "Przeniesiono kopię zapasową „{name}”"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1216
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1238
|
||||
msgid "Couldn't move that backup"
|
||||
msgstr "Nie można przenieść tej kopii zapasowej"
|
||||
|
||||
@@ -2961,7 +2986,7 @@ msgid "Sync paused until you resume"
|
||||
msgstr "Wstrzymano synchronizację do czasu wznowienia"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:570
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1445 crates/pdfs-gui/src/main.rs:290
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1445 crates/pdfs-gui/src/main.rs:308
|
||||
msgid "Sync paused"
|
||||
msgstr "Wstrzymano synchronizację"
|
||||
|
||||
@@ -3423,7 +3448,7 @@ msgid "paused"
|
||||
msgstr "wstrzymany"
|
||||
|
||||
#. Translators: a folder's files can't be opened right now.
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1742
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1745
|
||||
msgid "not available"
|
||||
msgstr "niedostępne"
|
||||
|
||||
@@ -5188,7 +5213,7 @@ msgstr "Wznowienie {time}"
|
||||
msgid "Until you resume"
|
||||
msgstr "Do czasu wznowienia"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1464 crates/pdfs-gui/src/main.rs:292
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1464 crates/pdfs-gui/src/main.rs:310
|
||||
#, rust-format
|
||||
msgid "{n} change needs attention"
|
||||
msgid_plural "{n} changes need attention"
|
||||
@@ -6439,38 +6464,43 @@ msgstr "Proton Drive nie odpowiada"
|
||||
msgid "Signed in as {username} — locked"
|
||||
msgstr "Zalogowano jako {username} — zablokowane"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:200
|
||||
#: crates/pdfs-gui/src/main.rs:209
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — can't open your Drive"
|
||||
msgstr "Zalogowano jako {username} — nie można otworzyć Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:218
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — not connected"
|
||||
msgstr "Zalogowano jako {username} — brak połączenia"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:205
|
||||
#: crates/pdfs-gui/src/main.rs:223
|
||||
msgid "Not signed in"
|
||||
msgstr "Nie zalogowano"
|
||||
|
||||
#. Translators: {error} is an error message, in English.
|
||||
#: crates/pdfs-gui/src/main.rs:208
|
||||
#: crates/pdfs-gui/src/main.rs:226
|
||||
#, rust-format
|
||||
msgid "Error: {error}"
|
||||
msgstr "Błąd: {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:230
|
||||
#: crates/pdfs-gui/src/main.rs:248
|
||||
msgid "Proton Drive sent an unexpected reply"
|
||||
msgstr "Proton Drive wysłał nieoczekiwaną odpowiedź"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:284
|
||||
#: crates/pdfs-gui/src/main.rs:302
|
||||
msgid "Session expired — sign in again"
|
||||
msgstr "Sesja wygasła — zaloguj się ponownie"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:286
|
||||
#: crates/pdfs-gui/src/main.rs:304
|
||||
msgid "Sign-in not saved — unlock your keyring"
|
||||
msgstr "Logowanie nie zostało zapisane — odblokuj bazę kluczy"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:289
|
||||
#: crates/pdfs-gui/src/main.rs:307
|
||||
msgid "Update not finished — restart Proton Drive"
|
||||
msgstr "Aktualizacja niedokończona — uruchom ponownie Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:299
|
||||
#: crates/pdfs-gui/src/main.rs:317
|
||||
#, rust-format
|
||||
msgid "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgid_plural "Up to date in {mountpoint} ({n} pinned)"
|
||||
@@ -6478,7 +6508,7 @@ msgstr[0] "Aktualne w {mountpoint} ({n} przypięty)"
|
||||
msgstr[1] "Aktualne w {mountpoint} ({n} przypięte)"
|
||||
msgstr[2] "Aktualne w {mountpoint} ({n} przypiętych)"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:306
|
||||
#: crates/pdfs-gui/src/main.rs:324
|
||||
#, rust-format
|
||||
msgid "Syncing — {queued} ({n} pinned)"
|
||||
msgid_plural "Syncing — {queued} ({n} pinned)"
|
||||
@@ -6486,7 +6516,7 @@ msgstr[0] "Synchronizowanie — {queued} (przypięte: {n})"
|
||||
msgstr[1] "Synchronizowanie — {queued} (przypięte: {n})"
|
||||
msgstr[2] "Synchronizowanie — {queued} (przypięte: {n})"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:313
|
||||
#: crates/pdfs-gui/src/main.rs:331
|
||||
#, rust-format
|
||||
msgid "Offline — cached files only ({n} pinned)"
|
||||
msgid_plural "Offline — cached files only ({n} pinned)"
|
||||
@@ -6495,13 +6525,13 @@ msgstr[1] "Offline — tylko pliki w pamięci podręcznej (przypięte: {n})"
|
||||
msgstr[2] "Offline — tylko pliki w pamięci podręcznej (przypięte: {n})"
|
||||
|
||||
#. Translators: {queued} is a queue summary such as "3 uploads queued".
|
||||
#: crates/pdfs-gui/src/main.rs:319
|
||||
#: crates/pdfs-gui/src/main.rs:337
|
||||
#, rust-format
|
||||
msgid "Offline — {queued}"
|
||||
msgstr "Offline — {queued}"
|
||||
|
||||
#. Translators: a menu item that opens the list of failing changes.
|
||||
#: crates/pdfs-gui/src/main.rs:358
|
||||
#: crates/pdfs-gui/src/main.rs:376
|
||||
#, rust-format
|
||||
msgid "{n} issue — View"
|
||||
msgid_plural "{n} issues — View"
|
||||
@@ -6509,47 +6539,47 @@ msgstr[0] "{n} problem — wyświetl"
|
||||
msgstr[1] "{n} problemy — wyświetl"
|
||||
msgstr[2] "{n} problemów — wyświetl"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:465
|
||||
#: crates/pdfs-gui/src/main.rs:483
|
||||
msgid "Sign In…"
|
||||
msgstr "Zaloguj się…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:466
|
||||
#: crates/pdfs-gui/src/main.rs:484
|
||||
msgid "Sign In Again…"
|
||||
msgstr "Zaloguj się ponownie…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:469
|
||||
#: crates/pdfs-gui/src/main.rs:487
|
||||
msgid "Open Proton Drive"
|
||||
msgstr "Otwórz Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:473
|
||||
#: crates/pdfs-gui/src/main.rs:491
|
||||
msgid "Restart Proton Drive"
|
||||
msgstr "Uruchom ponownie Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:482
|
||||
#: crates/pdfs-gui/src/main.rs:500
|
||||
msgid "Open Folder"
|
||||
msgstr "Otwórz katalog"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:494
|
||||
#: crates/pdfs-gui/src/main.rs:512
|
||||
msgid "Resume Sync"
|
||||
msgstr "Wznów synchronizację"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:496
|
||||
#: crates/pdfs-gui/src/main.rs:514
|
||||
msgid "Pause Sync"
|
||||
msgstr "Wstrzymaj synchronizację"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:515
|
||||
#: crates/pdfs-gui/src/main.rs:533
|
||||
msgid "Connect"
|
||||
msgstr "Połącz"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:522
|
||||
#: crates/pdfs-gui/src/main.rs:540
|
||||
msgid "Hide Tray Icon"
|
||||
msgstr "Ukryj ikonę w obszarze powiadamiania"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:526
|
||||
#: crates/pdfs-gui/src/main.rs:544
|
||||
msgid "Stop Proton Drive…"
|
||||
msgstr "Zatrzymaj Proton Drive…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:530
|
||||
#: crates/pdfs-gui/src/main.rs:548
|
||||
msgid "Quit"
|
||||
msgstr "Zakończ"
|
||||
|
||||
|
||||
+139
-110
@@ -5,7 +5,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: proton-drive-linux 2.1.0\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/narrrl/proton-drive-linux/issues\n"
|
||||
"POT-Creation-Date: 2026-10-26 22:26+0100\n"
|
||||
"POT-Creation-Date: 2026-10-31 19:26+0100\n"
|
||||
"PO-Revision-Date: 2026-09-23 12:00+0200\n"
|
||||
"Last-Translator: Proton Drive for Linux contributors\n"
|
||||
"Language-Team: Portuguese (Brazil)\n"
|
||||
@@ -245,13 +245,13 @@ msgstr ""
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1917
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2039
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2540
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:804
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:957
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:995
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1047
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1091
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1131
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1194
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:826
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:979
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1017
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1069
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1113
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1153
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1216
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:850
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1054
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1537
|
||||
@@ -346,7 +346,7 @@ msgstr "Grade / lista"
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:298
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1896
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1918
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:996
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1018
|
||||
#: crates/pdfs-gui/src/app/widgets/details.rs:161
|
||||
msgid "Rename"
|
||||
msgstr "Renomear"
|
||||
@@ -420,14 +420,27 @@ msgstr "Não conectado"
|
||||
msgid "The Proton Drive service isn't running."
|
||||
msgstr "O serviço do Proton Drive não está em execução."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1803
|
||||
#: crates/pdfs-gui/src/app/main.rs:1813
|
||||
msgid "Can't open your Drive"
|
||||
msgstr "Não foi possível abrir o Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1816
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"The Proton Drive service keeps failing to start and tries again on its own. "
|
||||
"The last error was: {error}"
|
||||
msgstr ""
|
||||
"O serviço do Proton Drive não consegue iniciar e tenta de novo sozinho. "
|
||||
"Último erro: {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1824
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:355
|
||||
#: crates/pdfs-gui/src/hud/mod.rs:269 crates/pdfs-gui/src/hud/mod.rs:579
|
||||
#: crates/pdfs-gui/src/main.rs:475 crates/pdfs-gui/src/main.rs:517
|
||||
#: crates/pdfs-gui/src/main.rs:493 crates/pdfs-gui/src/main.rs:535
|
||||
msgid "Connecting…"
|
||||
msgstr "Conectando…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1804
|
||||
#: crates/pdfs-gui/src/app/main.rs:1825
|
||||
msgid "Waiting for the Proton Drive service to start."
|
||||
msgstr "Aguardando o serviço do Proton Drive iniciar."
|
||||
|
||||
@@ -678,7 +691,7 @@ msgid "Couldn't add a sync folder"
|
||||
msgstr "Não foi possível adicionar uma pasta sincronizada"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/activity_text.rs:58
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:839
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:861
|
||||
msgid "Couldn't restore folders"
|
||||
msgstr "Não foi possível restaurar as pastas"
|
||||
|
||||
@@ -1270,12 +1283,12 @@ msgstr "Não foi possível carregar os álbuns"
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1873
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2500
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:2650
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:707
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:747
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:900
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1170
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1231
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1260
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:729
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:769
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:922
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1192
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1253
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1282
|
||||
#: crates/pdfs-gui/src/app/pages/duplicates.rs:221
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:577
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:824
|
||||
@@ -1921,7 +1934,7 @@ msgid "{status}. {message}"
|
||||
msgstr "{status}. {message}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1900
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:989
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1011
|
||||
msgid "New name"
|
||||
msgstr "Novo nome"
|
||||
|
||||
@@ -1946,7 +1959,7 @@ msgstr "Escolha a pasta de destino."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1989
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1994
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1195
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1217
|
||||
msgid "Move Here"
|
||||
msgstr "Mover para cá"
|
||||
|
||||
@@ -2268,76 +2281,87 @@ msgid_plural "{n} folders backed up"
|
||||
msgstr[0] "{n} pasta com backup"
|
||||
msgstr[1] "{n} pastas com backup"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:608
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:607
|
||||
#, rust-format
|
||||
msgid "{folders} · {n} waiting for its first sync"
|
||||
msgid_plural "{folders} · {n} waiting for their first sync"
|
||||
msgstr[0] "{folders} · {n} aguarda a primeira sincronização"
|
||||
msgstr[1] "{folders} · {n} aguardam a primeira sincronização"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:621
|
||||
#, rust-format
|
||||
msgid "{folders} · {n} needs attention"
|
||||
msgid_plural "{folders} · {n} need attention"
|
||||
msgstr[0] "{folders} · {n} requer atenção"
|
||||
msgstr[1] "{folders} · {n} requerem atenção"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:619
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:640
|
||||
msgid "syncing…"
|
||||
msgstr "sincronizando…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:620
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:641
|
||||
msgid "sync error"
|
||||
msgstr "erro de sincronização"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:621
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:642
|
||||
msgid "needs attention"
|
||||
msgstr "requer atenção"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:622
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:643
|
||||
msgid "waiting for first sync"
|
||||
msgstr "aguardando a primeira sincronização"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:644
|
||||
msgid "up to date"
|
||||
msgstr "atualizado"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:632
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:654
|
||||
msgid "checking for changes…"
|
||||
msgstr "verificando alterações…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:638
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:660
|
||||
#, rust-format
|
||||
msgid "checking for changes — {n} item checked"
|
||||
msgid_plural "checking for changes — {n} items checked"
|
||||
msgstr[0] "verificando alterações — {n} item verificado"
|
||||
msgstr[1] "verificando alterações — {n} itens verificados"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:645
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:667
|
||||
#, rust-format
|
||||
msgid "checking for changes — {done} of {total}"
|
||||
msgstr "verificando alterações — {done} de {total}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:657
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:679
|
||||
#, rust-format
|
||||
msgid "syncing {done} of {total}"
|
||||
msgstr "sincronizando {done} de {total}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:663
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:685
|
||||
#, rust-format
|
||||
msgid "syncing {file} — {done} of {total}"
|
||||
msgstr "sincronizando {file} — {done} de {total}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:675
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:697
|
||||
msgid "Add Folder to Sync"
|
||||
msgstr "Adicionar pasta à sincronização"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:699
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:721
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1559
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1686
|
||||
msgid "Syncing folder…"
|
||||
msgstr "Sincronizando pasta…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:702
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:706
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:724
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:728
|
||||
msgid "Couldn't add folder"
|
||||
msgstr "Não foi possível adicionar a pasta"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:740
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:746
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:762
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:768
|
||||
msgid "Couldn't list folders to restore"
|
||||
msgstr "Não foi possível listar as pastas para restaurar"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:772
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:794
|
||||
msgid ""
|
||||
"Tick the folders to sync to this machine, and adjust where each one should "
|
||||
"live."
|
||||
@@ -2345,19 +2369,19 @@ msgstr ""
|
||||
"Marque as pastas a sincronizar com esta máquina e ajuste onde cada uma deve "
|
||||
"ficar."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:798
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:820
|
||||
msgid "Restore Folders"
|
||||
msgstr "Restaurar pastas"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:805
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:827
|
||||
msgid "Restore"
|
||||
msgstr "Restaurar"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:838
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:860
|
||||
msgid "Restoring folders…"
|
||||
msgstr "Restaurando pastas…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:850
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:872
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"These folders are backed up from “{name}”. Restored folders keep syncing "
|
||||
@@ -2366,36 +2390,36 @@ msgstr ""
|
||||
"Estas pastas têm backup a partir de “{name}”. As pastas restauradas "
|
||||
"continuam sincronizando com a cópia daquele computador."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:853
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:875
|
||||
msgid "These folders are backed up under this computer in Proton Drive."
|
||||
msgstr "Estas pastas têm backup sob este computador no Proton Drive."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:862
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:884
|
||||
#, rust-format
|
||||
msgid "Nothing to restore — “{name}”'s folders are all synced here."
|
||||
msgstr ""
|
||||
"Nada a restaurar — as pastas de “{name}” já estão todas sincronizadas aqui."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:865
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:887
|
||||
msgid "Nothing to restore — this computer's folders are all synced here."
|
||||
msgstr ""
|
||||
"Nada a restaurar — as pastas deste computador já estão todas sincronizadas "
|
||||
"aqui."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:889
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:911
|
||||
msgid "Folder will switch to online only"
|
||||
msgstr "A pasta passará a ser somente online"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:891
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:913
|
||||
msgid "Folder will download and stay synced"
|
||||
msgstr "A pasta será baixada e permanecerá sincronizada"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:895
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:899
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:917
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:921
|
||||
msgid "Couldn't change mode"
|
||||
msgstr "Não foi possível alterar o modo"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:931
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:953
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"Stop syncing “{path}”?\n"
|
||||
@@ -2412,7 +2436,7 @@ msgstr ""
|
||||
"uma cópia local, cancele, mude a pasta para Sincronizada e aguarde o "
|
||||
"download terminar antes de removê-la."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:937
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:959
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"Stop syncing “{path}”?\n"
|
||||
@@ -2425,68 +2449,68 @@ msgstr ""
|
||||
"Os arquivos locais permanecem neste disco e simplesmente deixam de ser "
|
||||
"sincronizados. Escolha se também deseja excluir a cópia no Proton Drive."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:942
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:964
|
||||
msgid "Stop Syncing Folder?"
|
||||
msgstr "Parar de sincronizar a pasta?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:947
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:969
|
||||
msgid "Also delete from Proton Drive"
|
||||
msgstr "Também excluir do Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:949
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:971
|
||||
msgid "Deletes the only copy of these files."
|
||||
msgstr "Exclui a única cópia destes arquivos."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:951
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:973
|
||||
msgid "The local copy is unaffected."
|
||||
msgstr "A cópia local não é afetada."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:958
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:980
|
||||
msgid "Stop Syncing"
|
||||
msgstr "Parar de sincronizar"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:971
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:993
|
||||
msgid "Stopped syncing folder"
|
||||
msgstr "A pasta deixou de ser sincronizada"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:972
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:994
|
||||
msgid "Couldn't stop syncing the folder"
|
||||
msgstr "Não foi possível parar de sincronizar a pasta"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:983
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1005
|
||||
msgid "Rename Computer"
|
||||
msgstr "Renomear computador"
|
||||
|
||||
#. Translators: {name} is the computer's current name.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:985
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1007
|
||||
#, rust-format
|
||||
msgid "Rename “{name}”."
|
||||
msgstr "Renomear “{name}”."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1010
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1022
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1032
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1044
|
||||
msgid "Couldn't rename the computer"
|
||||
msgstr "Não foi possível renomear o computador"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1011
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1033
|
||||
msgid "A name is required."
|
||||
msgstr "Um nome é obrigatório."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1021
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1043
|
||||
msgid "Computer renamed"
|
||||
msgstr "Computador renomeado"
|
||||
|
||||
#. Translators: {name} is the computer's name, which the user must type.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1034
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1056
|
||||
#, rust-format
|
||||
msgid "Type “{name}” to confirm"
|
||||
msgstr "Digite “{name}” para confirmar"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1039
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1061
|
||||
msgid "Remove Computer?"
|
||||
msgstr "Remover computador?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1042
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1064
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"Remove “{name}” from this account?\n"
|
||||
@@ -2501,26 +2525,26 @@ msgstr ""
|
||||
"naquele próprio computador não são tocados — mas isso não pode ser desfeito "
|
||||
"daqui."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1048
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1070
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1025
|
||||
#: crates/pdfs-gui/src/app/widgets/share_dialog.rs:634
|
||||
#: crates/pdfs-gui/src/app/widgets/share_dialog.rs:876
|
||||
msgid "Remove"
|
||||
msgstr "Remover"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1065
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1087
|
||||
msgid "Computer removed"
|
||||
msgstr "Computador removido"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1066
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1088
|
||||
msgid "Couldn't remove the computer"
|
||||
msgstr "Não foi possível remover o computador"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1084
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1106
|
||||
msgid "Continue This Backup Here?"
|
||||
msgstr "Continuar este backup aqui?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1087
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1109
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"This computer takes over the backup of “{name}”, for example after a "
|
||||
@@ -2539,25 +2563,25 @@ msgstr ""
|
||||
"movidas. Depois, use “Restaurar neste computador” para recuperar o que "
|
||||
"“{name}” sincronizava."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1092
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1114
|
||||
msgid "Continue Here"
|
||||
msgstr "Continuar aqui"
|
||||
|
||||
#. Translators: {name} is the name of the computer whose backup this one took over.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1099
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1121
|
||||
#, rust-format
|
||||
msgid "Now backing up as “{name}”"
|
||||
msgstr "Agora fazendo backup como “{name}”"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1108
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1130
|
||||
msgid "Couldn't continue that backup here"
|
||||
msgstr "Não foi possível continuar esse backup aqui"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1124
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1146
|
||||
msgid "Sync With This Computer?"
|
||||
msgstr "Sincronizar com este computador?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1127
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1149
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"This computer and “{name}” keep the same folders in step. A change or a "
|
||||
@@ -2574,25 +2598,25 @@ msgstr ""
|
||||
"Drive. As pastas já sincronizadas aqui ficam onde estão. Em seguida, você "
|
||||
"escolhe quais pastas dele sincronizar aqui."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1132
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1154
|
||||
msgid "Sync Here"
|
||||
msgstr "Sincronizar aqui"
|
||||
|
||||
#. Translators: {name} is the name of the other computer this one now syncs with.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1139
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1161
|
||||
#, rust-format
|
||||
msgid "Now syncing with “{name}”"
|
||||
msgstr "Agora sincronizando com “{name}”"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1155
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1177
|
||||
msgid "Couldn't sync with that computer"
|
||||
msgstr "Não foi possível sincronizar com esse computador"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1187
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1209
|
||||
msgid "Move Backup to This Computer?"
|
||||
msgstr "Mover o backup para este computador?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1190
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1212
|
||||
#, rust-format
|
||||
msgid ""
|
||||
"The folders backed up by “{name}” move into this computer's backup in Proton "
|
||||
@@ -2609,12 +2633,12 @@ msgstr ""
|
||||
"pastas sumirem."
|
||||
|
||||
#. Translators: {name} is the name of the computer whose folders moved to this one.
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1202
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1224
|
||||
#, rust-format
|
||||
msgid "Moved the backup of “{name}”"
|
||||
msgstr "Backup de “{name}” movido"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1216
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:1238
|
||||
msgid "Couldn't move that backup"
|
||||
msgstr "Não foi possível mover esse backup"
|
||||
|
||||
@@ -2892,7 +2916,7 @@ msgid "Sync paused until you resume"
|
||||
msgstr "Sincronização pausada até você retomar"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:570
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1445 crates/pdfs-gui/src/main.rs:290
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1445 crates/pdfs-gui/src/main.rs:308
|
||||
msgid "Sync paused"
|
||||
msgstr "Sincronização pausada"
|
||||
|
||||
@@ -3351,7 +3375,7 @@ msgid "paused"
|
||||
msgstr "pausada"
|
||||
|
||||
#. Translators: a folder's files can't be opened right now.
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1742
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1745
|
||||
msgid "not available"
|
||||
msgstr "indisponível"
|
||||
|
||||
@@ -5093,7 +5117,7 @@ msgstr "Retoma {time}"
|
||||
msgid "Until you resume"
|
||||
msgstr "Até você retomar"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1464 crates/pdfs-gui/src/main.rs:292
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1464 crates/pdfs-gui/src/main.rs:310
|
||||
#, rust-format
|
||||
msgid "{n} change needs attention"
|
||||
msgid_plural "{n} changes need attention"
|
||||
@@ -6324,52 +6348,57 @@ msgstr "O Proton Drive não está respondendo"
|
||||
msgid "Signed in as {username} — locked"
|
||||
msgstr "Conectado como {username} — bloqueado"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:200
|
||||
#: crates/pdfs-gui/src/main.rs:209
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — can't open your Drive"
|
||||
msgstr "Conectado como {username} — não foi possível abrir o Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:218
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — not connected"
|
||||
msgstr "Conectado como {username} — sem conexão"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:205
|
||||
#: crates/pdfs-gui/src/main.rs:223
|
||||
msgid "Not signed in"
|
||||
msgstr "Não conectado"
|
||||
|
||||
#. Translators: {error} is an error message, in English.
|
||||
#: crates/pdfs-gui/src/main.rs:208
|
||||
#: crates/pdfs-gui/src/main.rs:226
|
||||
#, rust-format
|
||||
msgid "Error: {error}"
|
||||
msgstr "Erro: {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:230
|
||||
#: crates/pdfs-gui/src/main.rs:248
|
||||
msgid "Proton Drive sent an unexpected reply"
|
||||
msgstr "O Proton Drive enviou uma resposta inesperada"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:284
|
||||
#: crates/pdfs-gui/src/main.rs:302
|
||||
msgid "Session expired — sign in again"
|
||||
msgstr "Sessão expirada — entre novamente"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:286
|
||||
#: crates/pdfs-gui/src/main.rs:304
|
||||
msgid "Sign-in not saved — unlock your keyring"
|
||||
msgstr "Login não salvo — desbloqueie o chaveiro"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:289
|
||||
#: crates/pdfs-gui/src/main.rs:307
|
||||
msgid "Update not finished — restart Proton Drive"
|
||||
msgstr "Atualização não concluída — reinicie o Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:299
|
||||
#: crates/pdfs-gui/src/main.rs:317
|
||||
#, rust-format
|
||||
msgid "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgid_plural "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgstr[0] "Atualizado em {mountpoint} ({n} fixado)"
|
||||
msgstr[1] "Atualizado em {mountpoint} ({n} fixados)"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:306
|
||||
#: crates/pdfs-gui/src/main.rs:324
|
||||
#, rust-format
|
||||
msgid "Syncing — {queued} ({n} pinned)"
|
||||
msgid_plural "Syncing — {queued} ({n} pinned)"
|
||||
msgstr[0] "Sincronizando — {queued} ({n} fixado)"
|
||||
msgstr[1] "Sincronizando — {queued} ({n} fixados)"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:313
|
||||
#: crates/pdfs-gui/src/main.rs:331
|
||||
#, rust-format
|
||||
msgid "Offline — cached files only ({n} pinned)"
|
||||
msgid_plural "Offline — cached files only ({n} pinned)"
|
||||
@@ -6377,60 +6406,60 @@ msgstr[0] "Offline — somente arquivos em cache ({n} fixado)"
|
||||
msgstr[1] "Offline — somente arquivos em cache ({n} fixados)"
|
||||
|
||||
#. Translators: {queued} is a queue summary such as "3 uploads queued".
|
||||
#: crates/pdfs-gui/src/main.rs:319
|
||||
#: crates/pdfs-gui/src/main.rs:337
|
||||
#, rust-format
|
||||
msgid "Offline — {queued}"
|
||||
msgstr "Offline — {queued}"
|
||||
|
||||
#. Translators: a menu item that opens the list of failing changes.
|
||||
#: crates/pdfs-gui/src/main.rs:358
|
||||
#: crates/pdfs-gui/src/main.rs:376
|
||||
#, rust-format
|
||||
msgid "{n} issue — View"
|
||||
msgid_plural "{n} issues — View"
|
||||
msgstr[0] "{n} problema — Ver"
|
||||
msgstr[1] "{n} problemas — Ver"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:465
|
||||
#: crates/pdfs-gui/src/main.rs:483
|
||||
msgid "Sign In…"
|
||||
msgstr "Entrar…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:466
|
||||
#: crates/pdfs-gui/src/main.rs:484
|
||||
msgid "Sign In Again…"
|
||||
msgstr "Entrar novamente…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:469
|
||||
#: crates/pdfs-gui/src/main.rs:487
|
||||
msgid "Open Proton Drive"
|
||||
msgstr "Abrir o Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:473
|
||||
#: crates/pdfs-gui/src/main.rs:491
|
||||
msgid "Restart Proton Drive"
|
||||
msgstr "Reiniciar o Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:482
|
||||
#: crates/pdfs-gui/src/main.rs:500
|
||||
msgid "Open Folder"
|
||||
msgstr "Abrir pasta"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:494
|
||||
#: crates/pdfs-gui/src/main.rs:512
|
||||
msgid "Resume Sync"
|
||||
msgstr "Retomar sincronização"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:496
|
||||
#: crates/pdfs-gui/src/main.rs:514
|
||||
msgid "Pause Sync"
|
||||
msgstr "Pausar sincronização"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:515
|
||||
#: crates/pdfs-gui/src/main.rs:533
|
||||
msgid "Connect"
|
||||
msgstr "Conectar"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:522
|
||||
#: crates/pdfs-gui/src/main.rs:540
|
||||
msgid "Hide Tray Icon"
|
||||
msgstr "Ocultar ícone da bandeja"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:526
|
||||
#: crates/pdfs-gui/src/main.rs:544
|
||||
msgid "Stop Proton Drive…"
|
||||
msgstr "Parar o Proton Drive…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:530
|
||||
#: crates/pdfs-gui/src/main.rs:548
|
||||
msgid "Quit"
|
||||
msgstr "Sair"
|
||||
|
||||
|
||||
@@ -787,7 +787,9 @@ def test_server_copy_never_copies_an_old_version(ctx: Context) -> None:
|
||||
root = ctx.root
|
||||
path = root / "being-written.txt"
|
||||
write_durable(path, b"first version")
|
||||
dest = root / "copies"
|
||||
# Its own folder: every case of a run shares the root, and "pdfs copy"
|
||||
# already made "copies" there.
|
||||
dest = root / "b256-copies"
|
||||
dest.mkdir()
|
||||
daemon.wait_for_queue()
|
||||
|
||||
@@ -4012,30 +4014,36 @@ class Janitor:
|
||||
return [
|
||||
f"{name} ({entry['uid']}) is still in the trash"
|
||||
for entry in matches
|
||||
if not self.purge(entry["uid"], name)
|
||||
if not self.purge(entry["uid"], name, listed=True)
|
||||
]
|
||||
|
||||
def purge(self, uid: str, name: str) -> bool:
|
||||
def purge(self, uid: str, name: str, listed: bool = False) -> bool:
|
||||
"""Permanently delete one trashed node the run owns, by uid.
|
||||
|
||||
By uid and never by name: a name can match something of the user's, a
|
||||
uid cannot. The node has to show up in the trash first, which is also
|
||||
what proves the trash step before it worked, and it has to be gone from
|
||||
a fresh listing afterwards.
|
||||
a fresh listing afterwards. `listed` says the caller just found it in
|
||||
the trash.
|
||||
|
||||
The server's own answer comes first, though: it only deletes a node
|
||||
that is in the trash, and it answers per uid. A listing is a whole-trash
|
||||
enumeration, which on a large trash can time out on every attempt and
|
||||
would otherwise keep a folder the server would delete on request.
|
||||
"""
|
||||
with contextlib.suppress(Exception):
|
||||
last_error = ""
|
||||
try:
|
||||
reply = self.daemon.command("delete-forever", uid, stdin="yes\n")
|
||||
if re.search(r"\bpermanently deleted 1 item", reply):
|
||||
print(f"[cleanup] permanently deleted {name}")
|
||||
return True
|
||||
except Exception as error: # noqa: BLE001 - retried, then reported
|
||||
last_error = f": {error}"
|
||||
deadline = time.monotonic() + self.daemon.timeout
|
||||
attempted = False
|
||||
last_error = ""
|
||||
# A node seen in the trash before that delete and gone after it was
|
||||
# deleted by it, whatever it answered. Counting it as never sent kept
|
||||
# waiting for a node that was already gone, and failed the run.
|
||||
attempted = listed
|
||||
while True:
|
||||
try:
|
||||
if self.daemon.trashed(uid):
|
||||
@@ -4147,7 +4155,7 @@ class Janitor:
|
||||
for entry in trashed:
|
||||
if STALE_ROOT.match(entry["name"]) and entry["name"] not in live_names:
|
||||
print(f"[reap] permanently deleting an abandoned root from the trash: {entry['name']}")
|
||||
if not orphan.purge(entry["uid"], entry["name"]):
|
||||
if not orphan.purge(entry["uid"], entry["name"], listed=True):
|
||||
leftovers.append(f"{entry['name']} ({entry['uid']}) is still in the trash")
|
||||
return leftovers
|
||||
|
||||
|
||||
Reference in new issue
Block a user