mirror of
https://github.com/ankitects/anki.git
synced 2025-12-10 21:36:55 -05:00
fix sync download failing when temp dir on different mount
https://forums.ankiweb.net/t/problems-with-2-1-41-on-arch-linux/8103
This commit is contained in:
parent
b81e2c0265
commit
7ce75479b2
4 changed files with 29 additions and 10 deletions
|
|
@ -189,7 +189,7 @@ impl Backend {
|
||||||
fn download(&self) -> Result<Vec<u8>> {
|
fn download(&self) -> Result<Vec<u8>> {
|
||||||
let server = Box::new(self.col_into_server()?);
|
let server = Box::new(self.col_into_server()?);
|
||||||
let mut rt = Runtime::new().unwrap();
|
let mut rt = Runtime::new().unwrap();
|
||||||
let file = rt.block_on(server.full_download())?;
|
let file = rt.block_on(server.full_download(None))?;
|
||||||
let path = file.into_temp_path().keep()?;
|
let path = file.into_temp_path().keep()?;
|
||||||
Ok(path.to_str().expect("path was not in utf8").into())
|
Ok(path.to_str().expect("path was not in utf8").into())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -142,11 +142,19 @@ impl SyncServer for HTTPSyncClient {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Download collection into a temporary file, returning it.
|
/// Download collection into a temporary file, returning it. Caller should
|
||||||
/// Caller should persist the file in the correct path after checking it.
|
/// persist the file in the correct path after checking it. Progress func
|
||||||
/// Progress func must be set first.
|
/// must be set first. The caller should pass the collection's folder in as
|
||||||
async fn full_download(mut self: Box<Self>) -> Result<NamedTempFile> {
|
/// the temp folder if it wishes to atomically .persist() it.
|
||||||
let mut temp_file = NamedTempFile::new()?;
|
async fn full_download(
|
||||||
|
mut self: Box<Self>,
|
||||||
|
col_folder: Option<&Path>,
|
||||||
|
) -> Result<NamedTempFile> {
|
||||||
|
let mut temp_file = if let Some(folder) = col_folder {
|
||||||
|
NamedTempFile::new_in(folder)
|
||||||
|
} else {
|
||||||
|
NamedTempFile::new()
|
||||||
|
}?;
|
||||||
let (size, mut stream) = self.download_inner().await?;
|
let (size, mut stream) = self.download_inner().await?;
|
||||||
let mut progress = FullSyncProgress {
|
let mut progress = FullSyncProgress {
|
||||||
transferred_bytes: 0,
|
transferred_bytes: 0,
|
||||||
|
|
@ -410,7 +418,7 @@ mod test {
|
||||||
syncer.set_full_sync_progress_fn(Some(Box::new(|progress, _throttle| {
|
syncer.set_full_sync_progress_fn(Some(Box::new(|progress, _throttle| {
|
||||||
println!("progress: {:?}", progress);
|
println!("progress: {:?}", progress);
|
||||||
})));
|
})));
|
||||||
let out_path = syncer.full_download().await?;
|
let out_path = syncer.full_download(None).await?;
|
||||||
|
|
||||||
let mut syncer = Box::new(HTTPSyncClient::new(None, 0));
|
let mut syncer = Box::new(HTTPSyncClient::new(None, 0));
|
||||||
syncer.set_full_sync_progress_fn(Some(Box::new(|progress, _throttle| {
|
syncer.set_full_sync_progress_fn(Some(Box::new(|progress, _throttle| {
|
||||||
|
|
|
||||||
|
|
@ -672,8 +672,11 @@ impl Collection {
|
||||||
|
|
||||||
pub(crate) async fn full_download_inner(self, server: Box<dyn SyncServer>) -> Result<()> {
|
pub(crate) async fn full_download_inner(self, server: Box<dyn SyncServer>) -> Result<()> {
|
||||||
let col_path = self.col_path.clone();
|
let col_path = self.col_path.clone();
|
||||||
|
let col_folder = col_path
|
||||||
|
.parent()
|
||||||
|
.ok_or_else(|| AnkiError::invalid_input("couldn't get col_folder"))?;
|
||||||
self.close(false)?;
|
self.close(false)?;
|
||||||
let out_file = server.full_download().await?;
|
let out_file = server.full_download(Some(col_folder)).await?;
|
||||||
// check file ok
|
// check file ok
|
||||||
let db = open_and_check_sqlite_file(out_file.path())?;
|
let db = open_and_check_sqlite_file(out_file.path())?;
|
||||||
db.execute_batch("update col set ls=mod")?;
|
db.execute_batch("update col set ls=mod")?;
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,10 @@ pub trait SyncServer {
|
||||||
/// If `can_consume` is true, the local server will move or remove the file, instead
|
/// If `can_consume` is true, the local server will move or remove the file, instead
|
||||||
/// creating a copy. The remote server ignores this argument.
|
/// creating a copy. The remote server ignores this argument.
|
||||||
async fn full_upload(self: Box<Self>, col_path: &Path, can_consume: bool) -> Result<()>;
|
async fn full_upload(self: Box<Self>, col_path: &Path, can_consume: bool) -> Result<()>;
|
||||||
async fn full_download(self: Box<Self>) -> Result<NamedTempFile>;
|
/// If the calling code intends to .persist() the named temp file to
|
||||||
|
/// atomically update the collection, it should pass in the collection's
|
||||||
|
/// folder, as .persist() can't work across filesystems.
|
||||||
|
async fn full_download(self: Box<Self>, temp_folder: Option<&Path>) -> Result<NamedTempFile>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct LocalServer {
|
pub struct LocalServer {
|
||||||
|
|
@ -199,7 +202,12 @@ impl SyncServer for LocalServer {
|
||||||
fs::rename(col_path, &target_col_path).map_err(Into::into)
|
fs::rename(col_path, &target_col_path).map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn full_download(mut self: Box<Self>) -> Result<NamedTempFile> {
|
/// The provided folder is ignored, as in the server case the local data
|
||||||
|
/// will be sent over the network, instead of written into a local file.
|
||||||
|
async fn full_download(
|
||||||
|
mut self: Box<Self>,
|
||||||
|
_col_folder: Option<&Path>,
|
||||||
|
) -> Result<NamedTempFile> {
|
||||||
// bump usn/mod & close
|
// bump usn/mod & close
|
||||||
self.col.transact(None, |col| col.storage.increment_usn())?;
|
self.col.transact(None, |col| col.storage.increment_usn())?;
|
||||||
let col_path = self.col.col_path.clone();
|
let col_path = self.col.col_path.clone();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue