use std::fs;
use camino::Utf8Path;
use miette::IntoDiagnostic;
use miette::Result;
use relative_path::RelativePathBuf;
use time::OffsetDateTime;
use time_tz::OffsetDateTimeExt as _;
use crate::ImporterProtocol;
#[tracing::instrument(fields(importer = importer.name()))]
pub(crate) fn file_name(
importer: &dyn ImporterProtocol<Error = miette::Report>,
file: &Utf8Path,
buffer: &[u8],
) -> Result<RelativePathBuf> {
let account = importer.account(buffer)?;
let binding = importer.filename(buffer).transpose()?;
let name = binding
.as_deref()
.unwrap_or_else(|| file.file_name().unwrap());
let date = importer.date(buffer).unwrap_or_else(|| {
let metadata = file.metadata().into_diagnostic()?;
let ctime = metadata.created().into_diagnostic()?;
let ctime = OffsetDateTime::from(ctime);
let tz = time_tz::system::get_timezone().into_diagnostic()?;
let ctime = ctime.to_timezone(tz);
Ok(ctime.date())
})?;
// The returned filename cannot contain the file path separator character.
miette::ensure!(
!name.contains(std::path::MAIN_SEPARATOR),
"filename contains path separator character"
);
/*
TODO "if re.match(r'\d\d\d\d-\d\d-\d\d\.', filename):
raise Error("The name contains what looks like a date.")
*/
// Prepend account directory and date prefix.
let mut path = RelativePathBuf::new();
path.extend(account.segments().map(|seg| &**seg));
let file_name = format!("{date}.{name}");
path.push(file_name);
Ok(path)
}
#[tracing::instrument]
pub(crate) fn move_file(file: &Utf8Path, destination: &Utf8Path) -> Result<()> {
if let Some(path) = destination.parent() {
fs::create_dir_all(path).into_diagnostic()?;
}
fs::rename(file, destination).into_diagnostic()?;
Ok(())
}