mirror of
https://github.com/thegeneralist01/archivr
synced 2026-05-30 08:36:47 +02:00
* chore: specify non-ignored `.md` files * refactor: rename youtube downloader to ytdlp More generic name since yt-dlp supports many sites beyond YouTube. * feat: add local file downloader Supports file:// URLs for archiving local files. * deps: add regex crate for URL pattern matching * feat: expand source detection with granular YouTube types - Split Source::YouTube into YouTubeVideo, YouTubePlaylist, YouTubeChannel - Add Source::X for Twitter/X posts - Add Source::Local for file:// URLs - Add regex-based URL pattern matching for YouTube URLs - Add shorthand schemes (yt:video/ID, youtube:playlist/ID, etc.) - Add comprehensive tests for all URL patterns * docs: update README milestones Mark YouTube videos, Twitter videos, and local files as done. * chore: update flake.lock * feat: add shorthand schemes for X/Twitter media * chore: move docs into docs dir * Remove temp file using timestamp path Delete the temp entry at store_path/temp/<timestamp> in both the hash-exists and success paths. Stop constructing the full filename with extension and remove the early process::exit to de-duplicate cleanup. * Add Nix caches and default flake package * Add social platform source detection and update milestones * Tighten social URL matching to avoid false positives * Mark media archiving milestone complete
28 lines
929 B
Rust
28 lines
929 B
Rust
use anyhow::{Context, Result, bail};
|
|
use std::{path::Path, process::Command};
|
|
|
|
use crate::hash::hash_file;
|
|
|
|
pub fn save(path: String, store_path: &Path, timestamp: &String) -> Result<String> {
|
|
println!("Saving path: {path}");
|
|
|
|
let temp_dir = store_path.join("temp").join(timestamp);
|
|
std::fs::create_dir_all(&temp_dir)?;
|
|
|
|
let in_file = Path::new(path.trim_start_matches("file://"));
|
|
let extension = in_file
|
|
.extension()
|
|
.map_or(String::new(), |ext| format!(".{}", ext.to_string_lossy()));
|
|
let out_file = temp_dir.join(format!("{timestamp}{extension}"));
|
|
|
|
let mut binding = Command::new("cp");
|
|
let cmd = binding.arg(in_file).arg(&out_file);
|
|
let out = cmd.output().with_context(|| "failed to spawn cp process")?;
|
|
|
|
if !out.status.success() {
|
|
let stderr = String::from_utf8_lossy(&out.stderr);
|
|
bail!("yt-dlp failed: {stderr}");
|
|
}
|
|
|
|
hash_file(&out_file)
|
|
}
|