mirror of
https://github.com/ankitects/anki.git
synced 2025-09-24 08:46:37 -04:00
defer errors on upload to media check
This commit is contained in:
parent
d38c2c12d5
commit
98279add15
6 changed files with 42 additions and 21 deletions
|
@ -97,6 +97,8 @@ message SyncError {
|
|||
CLIENT_TOO_OLD = 3;
|
||||
AUTH_FAILED = 4;
|
||||
SERVER_MESSAGE = 5;
|
||||
MEDIA_CHECK_REQUIRED = 6;
|
||||
RESYNC_REQUIRED = 7;
|
||||
}
|
||||
SyncErrorKind kind = 2;
|
||||
}
|
||||
|
|
|
@ -44,20 +44,6 @@ class MediaSyncState:
|
|||
removed_files: int = 0
|
||||
|
||||
|
||||
# fixme: sync.rs fixmes
|
||||
# fixme: maximum size when uploading
|
||||
# fixme: concurrent modifications during upload step
|
||||
# fixme: mediaSanity
|
||||
# elif evt == "mediaSanity":
|
||||
# showWarning(
|
||||
# _(
|
||||
# """\
|
||||
# A problem occurred while syncing media. Please use Tools>Check Media, then \
|
||||
# sync again to correct the issue."""
|
||||
# )
|
||||
# )
|
||||
|
||||
|
||||
LogEntry = Union[MediaSyncState, str]
|
||||
|
||||
|
||||
|
@ -170,6 +156,14 @@ class MediaSyncer:
|
|||
"AnkiWeb encountered a problem. Please try again in a few minutes."
|
||||
)
|
||||
)
|
||||
elif kind == SyncErrorKind.MEDIA_CHECK_REQUIRED:
|
||||
showWarning(_("Please use the Tools>Check Media menu option."))
|
||||
elif kind == SyncErrorKind.RESYNC_REQUIRED:
|
||||
showWarning(
|
||||
_(
|
||||
"Please sync again, and post on the support forum if this message keeps appearing."
|
||||
)
|
||||
)
|
||||
else:
|
||||
showWarning(_("Unexpected error: {}").format(str(exc)))
|
||||
elif isinstance(exc, NetworkError):
|
||||
|
|
|
@ -87,6 +87,8 @@ impl std::convert::From<SyncErrorKind> for i32 {
|
|||
SyncErrorKind::ClientTooOld => V::ClientTooOld,
|
||||
SyncErrorKind::AuthFailed => V::AuthFailed,
|
||||
SyncErrorKind::ServerMessage => V::ServerMessage,
|
||||
SyncErrorKind::MediaCheckRequired => V::MediaCheckRequired,
|
||||
SyncErrorKind::ResyncRequired => V::ResyncRequired,
|
||||
SyncErrorKind::Other => V::Other,
|
||||
}) as i32
|
||||
}
|
||||
|
|
|
@ -129,6 +129,8 @@ pub enum SyncErrorKind {
|
|||
AuthFailed,
|
||||
ServerMessage,
|
||||
Other,
|
||||
MediaCheckRequired,
|
||||
ResyncRequired,
|
||||
}
|
||||
|
||||
fn error_for_status_code(info: String, code: StatusCode) -> AnkiError {
|
||||
|
|
|
@ -244,6 +244,12 @@ delete from media where fname=?"
|
|||
.collect();
|
||||
Ok(map?)
|
||||
}
|
||||
|
||||
pub(super) fn force_resync(&mut self) -> Result<()> {
|
||||
self.db
|
||||
.execute_batch("delete from media; update meta set lastUsn=0, usn=0")
|
||||
.map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
use crate::err::{AnkiError, Result};
|
||||
use crate::err::{AnkiError, Result, SyncErrorKind};
|
||||
use crate::media::database::{MediaDatabaseContext, MediaDatabaseMetadata, MediaEntry};
|
||||
use crate::media::files::{
|
||||
add_file_from_ankiweb, data_for_file, normalize_filename, remove_files, AddedFile,
|
||||
|
@ -22,6 +22,10 @@ use std::{io, time};
|
|||
|
||||
static SYNC_MAX_FILES: usize = 25;
|
||||
static SYNC_MAX_BYTES: usize = (2.5 * 1024.0 * 1024.0) as usize;
|
||||
static SYNC_SINGLE_FILE_MAX_BYTES: usize = 100 * 1024 * 1024;
|
||||
|
||||
// fixme: non-normalized filenames on ankiweb
|
||||
// fixme: concurrent modifications during upload step
|
||||
|
||||
/// The counts are not cumulative - the progress hook should accumulate them.
|
||||
#[derive(Debug)]
|
||||
|
@ -182,8 +186,11 @@ where
|
|||
if data == "OK" {
|
||||
Ok(())
|
||||
} else {
|
||||
// fixme: force resync, handle better
|
||||
Err(AnkiError::server_message("resync required"))
|
||||
self.ctx.transact(|ctx| ctx.force_resync())?;
|
||||
Err(AnkiError::SyncError {
|
||||
info: "".into(),
|
||||
kind: SyncErrorKind::ResyncRequired,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
Err(AnkiError::server_message(resp.err))
|
||||
|
@ -556,16 +563,17 @@ fn zip_files(media_folder: &Path, files: &[MediaEntry]) -> Result<Vec<u8>> {
|
|||
|
||||
let normalized = normalize_filename(&file.fname);
|
||||
if let Cow::Owned(_) = normalized {
|
||||
// fixme: non-string err, or should ignore instead
|
||||
return Err(AnkiError::sync_misc("invalid file found"));
|
||||
return Err(media_check_required());
|
||||
}
|
||||
|
||||
let file_data = data_for_file(media_folder, &file.fname)?;
|
||||
|
||||
if let Some(data) = &file_data {
|
||||
if data.is_empty() {
|
||||
// fixme: should ignore these, not error
|
||||
return Err(AnkiError::sync_misc("0 byte file found"));
|
||||
return Err(media_check_required());
|
||||
}
|
||||
if data.len() > SYNC_SINGLE_FILE_MAX_BYTES {
|
||||
return Err(media_check_required());
|
||||
}
|
||||
accumulated_size += data.len();
|
||||
zip.start_file(format!("{}", idx), options)?;
|
||||
|
@ -605,6 +613,13 @@ fn version_string() -> String {
|
|||
format!("anki,{},{}", version(), std::env::consts::OS)
|
||||
}
|
||||
|
||||
fn media_check_required() -> AnkiError {
|
||||
AnkiError::SyncError {
|
||||
info: "".into(),
|
||||
kind: SyncErrorKind::MediaCheckRequired,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct FinalizeRequest {
|
||||
local: u32,
|
||||
|
|
Loading…
Reference in a new issue