mirror of
https://codeberg.org/demostf/backup.git
synced 2026-06-03 09:54:18 +02:00
use api-client::save
This commit is contained in:
parent
3029b5ef79
commit
08319e0dc9
5 changed files with 12 additions and 46 deletions
11
Cargo.lock
generated
11
Cargo.lock
generated
|
|
@ -30,14 +30,10 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
name = "backup"
|
name = "backup"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
|
||||||
"demostf-client",
|
"demostf-client",
|
||||||
"dotenv",
|
"dotenv",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"hex",
|
|
||||||
"main_error",
|
"main_error",
|
||||||
"md5",
|
|
||||||
"serde",
|
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
|
@ -76,18 +72,21 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "demostf-client"
|
name = "demostf-client"
|
||||||
version = "0.3.1"
|
version = "0.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7ba6215021299e2f440f91c6c32bb5dd8f19ae7e94c9c692124f52daa9ec5b57"
|
checksum = "0ec005bc832bfc50b85c2f70c11342d6e0f5ed125464a7e70a1109fef32465b6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"hex",
|
"hex",
|
||||||
|
"md5",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
"steamid-ng",
|
"steamid-ng",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"time",
|
"time",
|
||||||
|
"tinyvec",
|
||||||
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
||||||
|
|
@ -5,17 +5,13 @@ authors = ["Robin Appelman <robin@icewind.nl>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = { version = "1.0.136", features = ["derive"] }
|
|
||||||
thiserror = "1.0.30"
|
thiserror = "1.0.30"
|
||||||
md5 = "0.7.0"
|
|
||||||
hex = "0.4.3"
|
|
||||||
dotenv = "0.15.0"
|
dotenv = "0.15.0"
|
||||||
main_error = "0.1.2"
|
main_error = "0.1.2"
|
||||||
demostf-client = { version = "0.3.1", default-features = false, features = ["rustls-tls"] }
|
demostf-client = { version = "0.3.3", default-features = false, features = ["rustls-tls"] }
|
||||||
tokio = { version = "1.17.0", features = ["rt-multi-thread", "macros"] }
|
tokio = { version = "1.17.0", features = ["rt-multi-thread", "macros"] }
|
||||||
tracing = "0.1.33"
|
tracing = "0.1.33"
|
||||||
tracing-subscriber = "0.3.11"
|
tracing-subscriber = "0.3.11"
|
||||||
bytes = "1.1.0"
|
|
||||||
futures-util = "0.3.21"
|
futures-util = "0.3.21"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
|
|
|
||||||
|
|
@ -19,19 +19,11 @@ impl Backup {
|
||||||
#[instrument(skip_all, fields(demo.id = demo.id, demo.name = name))]
|
#[instrument(skip_all, fields(demo.id = demo.id, demo.name = name))]
|
||||||
async fn backup_demo(&self, name: &str, demo: &Demo) -> Result<(), Error> {
|
async fn backup_demo(&self, name: &str, demo: &Demo) -> Result<(), Error> {
|
||||||
info!("backing up");
|
info!("backing up");
|
||||||
let chunks = demo.download(&self.client).await?;
|
|
||||||
|
|
||||||
let digest = self.store.store(name, chunks).await?;
|
let mut file = self.store.create(name).await?;
|
||||||
|
|
||||||
if digest == demo.hash || digest == [0; 16] {
|
demo.save(&self.client, &mut file).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
|
||||||
let _ = self.store.remove(name);
|
|
||||||
Err(Error::DigestMismatch {
|
|
||||||
expected: demo.hash,
|
|
||||||
got: digest,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(self))]
|
#[instrument(skip(self))]
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,6 @@ pub enum Error {
|
||||||
Request(#[from] std::io::Error),
|
Request(#[from] std::io::Error),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Api(#[from] demostf_client::Error),
|
Api(#[from] demostf_client::Error),
|
||||||
#[error("MD5 digest mismatch for downloaded demo, expected {expected:?}, received {got:?}")]
|
|
||||||
DigestMismatch { expected: [u8; 16], got: [u8; 16] },
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
|
|
|
||||||
25
src/store.rs
25
src/store.rs
|
|
@ -1,13 +1,8 @@
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
use bytes::Bytes;
|
|
||||||
use futures_util::{Stream, StreamExt};
|
|
||||||
use md5::Context;
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::fs::{File, Permissions};
|
use std::fs::{File, Permissions};
|
||||||
use std::io::Write;
|
|
||||||
use std::os::unix::fs::PermissionsExt;
|
use std::os::unix::fs::PermissionsExt;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use tokio::pin;
|
|
||||||
|
|
||||||
pub struct Store {
|
pub struct Store {
|
||||||
basedir: PathBuf,
|
basedir: PathBuf,
|
||||||
|
|
@ -20,28 +15,14 @@ impl Store {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn store(
|
pub async fn create(&self, name: &str) -> Result<File, Error> {
|
||||||
&self,
|
|
||||||
name: &str,
|
|
||||||
data: impl Stream<Item = Result<Bytes, demostf_client::Error>>,
|
|
||||||
) -> Result<[u8; 16], Error> {
|
|
||||||
let path = self.generate_path(name);
|
let path = self.generate_path(name);
|
||||||
fs::create_dir_all(path.parent().unwrap())?;
|
fs::create_dir_all(path.parent().unwrap())?;
|
||||||
|
|
||||||
let mut file = File::create(&path)?;
|
let file = File::create(&path)?;
|
||||||
|
|
||||||
let mut context = Context::new();
|
|
||||||
|
|
||||||
pin!(data);
|
|
||||||
// copy the file and compute the digest was we go
|
|
||||||
while let Some(chunk) = data.next().await {
|
|
||||||
let chunk = chunk?;
|
|
||||||
context.consume(&chunk);
|
|
||||||
file.write_all(&chunk)?;
|
|
||||||
}
|
|
||||||
file.set_permissions(Permissions::from_mode(0o644))?;
|
file.set_permissions(Permissions::from_mode(0o644))?;
|
||||||
|
|
||||||
Ok(context.compute().0)
|
Ok(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exists(&self, name: &str) -> bool {
|
pub fn exists(&self, name: &str) -> bool {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue