Skip to content

Commit

Permalink
feat: custom partial path for downloads
Browse files Browse the repository at this point in the history
  • Loading branch information
TBS1996 committed Apr 21, 2024
1 parent efe678e commit 40602f4
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 31 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "talecast"
version = "0.1.32"
version = "0.1.33"
edition = "2021"
description = "Simple CLI podcatcher"
license = "MIT"
Expand Down
47 changes: 29 additions & 18 deletions src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,27 @@ use std::io::{self, Read};
use std::path::Path;
use std::path::PathBuf;

struct MimeMap;

impl MimeMap {
fn get_mime(url: &str) -> Option<String> {
let hashed = hashed_url(url);
let path = Self::path();
utils::get_file_map_val(&path, &hashed)
}

fn append(url: &str, mime: &str) -> Option<()> {
let path = Self::path();
let hashed = hashed_url(url);
utils::append_to_config(&path, &hashed, &mime).ok()?;
Some(())
}

fn path() -> PathBuf {
utils::cache_dir().join("mime_types")
}
}

fn read_file_to_vec(path: &Path) -> io::Result<Vec<u8>> {
let mut file = fs::File::open(path)?;
let mut data = Vec::new();
Expand All @@ -25,11 +46,11 @@ fn cached_image(url: &str) -> Option<Vec<u8>> {
read_file_to_vec(&path).ok()
}

async fn write_image(url: &str) {
async fn write_image(url: &str) -> Option<()> {
use std::io::Write;

let hashed = hashed_url(url);
let response = reqwest::get(url).await.unwrap();
let response = reqwest::get(url).await.ok()?;
if response.status().is_success() {
let mime_type = response
.headers()
Expand All @@ -39,21 +60,11 @@ async fn write_image(url: &str) {
.to_string();
let data = response.bytes().await.unwrap().to_vec();
let path = utils::cache_dir().join(&hashed);
let mut file = fs::File::create(&path).unwrap();
file.write_all(&data).unwrap();
let mime_path = mime_types_path();
utils::append_to_config(&mime_path, &hashed, &mime_type).unwrap();
let mut file = fs::File::create(&path).ok()?;
file.write_all(&data).ok()?;
MimeMap::append(url, &mime_type)?;
}
}

fn mime_types_path() -> PathBuf {
utils::cache_dir().join("mime_types")
}

fn get_mime_type(url: &str) -> Option<String> {
let hashed = hashed_url(url);
let path = mime_types_path();
utils::get_file_map_val(&path, &hashed)
Some(())
}

pub async fn get_image(
Expand All @@ -63,12 +74,12 @@ pub async fn get_image(
let data = match cached_image(url) {
Some(data) => data,
None => {
write_image(url).await;
write_image(url).await?;
cached_image(url)?
}
};

let mime_type = get_mime_type(url)?;
let mime_type = MimeMap::get_mime(url)?;

let pic = id3::frame::Picture {
data,
Expand Down
11 changes: 11 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ pub struct Config {
pub name_pattern: FullPattern,
pub id_pattern: FullPattern,
pub download_path: FullPattern,
pub partial_path: Option<FullPattern>,
pub tracker_path: FullPattern,
pub symlink: Option<FullPattern>,
pub id3_tags: HashMap<String, String>,
Expand Down Expand Up @@ -222,6 +223,11 @@ impl Config {
.or(global_config.symlink.clone())
.map(|str| FullPattern::from_str(&str));

let partial_path = podcast_config
.partial_path
.or(global_config.partial_path.clone())
.map(|s| FullPattern::from_str(&s));

Self {
url,
name_pattern,
Expand All @@ -232,6 +238,7 @@ impl Config {
download_path,
tracker_path,
symlink,
partial_path,
}
}
}
Expand Down Expand Up @@ -335,6 +342,7 @@ impl IndicatifSettings {
pub struct GlobalConfig {
#[serde(default = "default_download_path", alias = "path")]
download_path: String,
partial_path: Option<String>,
#[serde(default = "default_name_pattern")]
name_pattern: String,
#[serde(default = "default_id_pattern")]
Expand Down Expand Up @@ -445,6 +453,7 @@ impl Default for GlobalConfig {
search: Default::default(),
symlink: None,
user_agent: None,
partial_path: None,
}
}
}
Expand Down Expand Up @@ -659,6 +668,7 @@ pub struct PodcastConfig {
id_pattern: Option<String>,
#[serde(alias = "path")]
download_path: Option<String>,
partial_path: Option<String>,
backlog_start: Option<String>,
backlog_interval: Option<i64>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
Expand Down Expand Up @@ -687,6 +697,7 @@ impl PodcastConfig {
download_hook: Default::default(),
tracker_path: Default::default(),
symlink: Default::default(),
partial_path: Default::default(),
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/download_tracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ impl DownloadedEpisodes {
}

pub fn load(path: &Path) -> Self {
let s = match std::fs::read_to_string(path) {
let s = match fs::read_to_string(path) {
Ok(s) => s,
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
return Self::default();
Expand Down Expand Up @@ -43,10 +43,10 @@ impl DownloadedEpisodes {
}

if let Some(parent) = path.parent() {
fs::create_dir_all(&parent).unwrap();
utils::create_dir(&parent)
}

let mut file = std::fs::OpenOptions::new()
let mut file = fs::OpenOptions::new()
.append(true)
.create(true)
.open(path)
Expand Down
18 changes: 15 additions & 3 deletions src/podcast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,10 +263,22 @@ impl Podcast {
fn download_path(&self, episode: &Episode<'_>) -> PathBuf {
let evaluated = self.config.download_path.evaluate(self, episode);
let path = PathBuf::from(evaluated);
fs::create_dir_all(&path).unwrap();
utils::create_dir(&path);
path.join(episode.partial_name())
}

fn partial_path(&self, episode: &Episode<'_>) -> PathBuf {
match self.config().partial_path.as_ref() {
Some(p) => {
let p = p.evaluate(self, episode);
let path = PathBuf::from(p);
utils::create_dir(&path);
path.join(episode.partial_name())
}
None => self.download_path(episode),
}
}

fn episodes(&self) -> Vec<Episode<'_>> {
let mut vec = vec![];

Expand Down Expand Up @@ -388,7 +400,7 @@ impl Podcast {
ui: &DownloadBar,
episode: Episode<'a>,
) -> DownloadedEpisode<'a> {
let partial_path = self.download_path(&episode);
let partial_path = self.partial_path(&episode);

let mut file = fs::OpenOptions::new()
.write(true)
Expand Down Expand Up @@ -421,7 +433,7 @@ impl Podcast {
}

let path = {
let mut path = partial_path.clone();
let mut path = self.download_path(&episode).clone();
path.set_extension(extension);
path
};
Expand Down
19 changes: 14 additions & 5 deletions src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::config;
use crate::episode::Episode;
use crate::utils;
use regex::Regex;
use serde::Serialize;
use serde_json::Value;
Expand Down Expand Up @@ -35,7 +36,7 @@ pub fn config_dir() -> PathBuf {
}
.join(crate::APPNAME);

std::fs::create_dir_all(&path).unwrap();
utils::create_dir(&path);

path
}
Expand All @@ -47,7 +48,7 @@ pub fn cache_dir() -> PathBuf {
}
.join(crate::APPNAME);

std::fs::create_dir_all(&path).unwrap();
utils::create_dir(&path);

path
}
Expand All @@ -58,9 +59,9 @@ pub fn current_unix() -> Unix {
}

pub fn default_download_path() -> PathBuf {
let p = dirs::home_dir().unwrap().join(crate::APPNAME);
std::fs::create_dir_all(&p).unwrap();
p
let path = dirs::home_dir().unwrap().join(crate::APPNAME);
utils::create_dir(&path);
path
}

pub fn truncate_string(s: &str, max_width: usize, append_dots: bool) -> String {
Expand Down Expand Up @@ -422,3 +423,11 @@ pub fn append_to_config(file_path: &Path, key: &str, value: &str) -> io::Result<

Ok(())
}

pub fn create_dir(path: &Path) {
if let Err(e) = fs::create_dir_all(path) {
eprintln!("failed to create following directory: {:?}", path);
eprintln!("error: {:?}", e);
process::exit(1);
}
}

0 comments on commit 40602f4

Please sign in to comment.