caesura/utils/fs/
path_manager.rs1use std::fs::create_dir;
2use std::path::PathBuf;
3
4use di::{Ref, injectable};
5use rogue_logging::Error;
6
7use crate::dependencies::*;
8use crate::options::*;
9use crate::utils::*;
10#[injectable]
11pub struct PathManager {
12 shared_options: Ref<SharedOptions>,
13 cache_options: Ref<CacheOptions>,
14}
15
16impl PathManager {
17 #[must_use]
18 pub fn get_cache_dir(&self) -> PathBuf {
19 self.cache_options
20 .cache
21 .clone()
22 .expect("cache should be set")
23 }
24
25 #[must_use]
26 pub fn get_source_torrent_path(&self, source: &Source) -> PathBuf {
27 let id = source.torrent.id;
28 let indexer = self
29 .shared_options
30 .indexer
31 .clone()
32 .expect("indexer should be set");
33 let torrents_dir = self.get_cache_dir().join("torrents");
34 if !torrents_dir.is_dir() {
35 let _ = create_dir(&torrents_dir);
36 }
37 torrents_dir.join(format!("{id}.{indexer}.torrent"))
38 }
39
40 #[must_use]
41 pub fn get_output_dir(&self) -> PathBuf {
42 self.shared_options
43 .output
44 .clone()
45 .expect("output should be set")
46 }
47
48 #[must_use]
49 pub fn get_spectrogram_dir(&self, source: &Source) -> PathBuf {
50 self.get_output_dir()
51 .join(SpectrogramName::get(&source.metadata))
52 }
53
54 #[must_use]
55 pub fn get_transcode_target_dir(&self, source: &Source, target: TargetFormat) -> PathBuf {
56 self.get_output_dir()
57 .join(TranscodeName::get(&source.metadata, target))
58 }
59
60 #[must_use]
61 pub fn get_transcode_path(
62 &self,
63 source: &Source,
64 target: TargetFormat,
65 flac: &FlacFile,
66 ) -> PathBuf {
67 let extension = target.get_file_extension();
68 let filename = flac.file_name.clone() + "." + extension.as_str();
69 let sub_path = flac.sub_dir.join(filename);
70 self.get_transcode_target_dir(source, target).join(sub_path)
71 }
72
73 #[must_use]
74 pub fn get_torrent_path(
75 &self,
76 source: &Source,
77 target: TargetFormat,
78 include_indexer: bool,
79 ) -> PathBuf {
80 let mut filename = TranscodeName::get(&source.metadata, target);
81 if include_indexer {
82 let indexer = self
83 .shared_options
84 .indexer
85 .clone()
86 .expect("indexer should be set");
87 filename.push('.');
88 filename.push_str(&indexer);
89 }
90 filename.push_str(".torrent");
91 self.get_output_dir().join(filename)
92 }
93
94 pub async fn get_or_duplicate_existing_torrent_path(
108 &self,
109 source: &Source,
110 target: TargetFormat,
111 ) -> Result<Option<PathBuf>, Error> {
112 let path_with_indexer = self.get_torrent_path(source, target, true);
113 if path_with_indexer.is_file() {
114 return Ok(Some(path_with_indexer));
115 }
116 let path_without_indexer = self.get_torrent_path(source, target, false);
117 if !path_without_indexer.is_file() {
118 return Ok(None);
119 }
120 let transcode_dir = self.get_transcode_target_dir(source, target);
121 let announce_url = self
122 .shared_options
123 .announce_url
124 .clone()
125 .expect("announce should be set");
126 let indexer = self
127 .shared_options
128 .indexer
129 .clone()
130 .expect("indexer should be set")
131 .to_lowercase();
132 let success = ImdlCommand::duplicate_torrent(
133 &path_without_indexer,
134 &path_with_indexer,
135 &transcode_dir,
136 announce_url,
137 indexer,
138 )
139 .await?;
140 if success {
141 Ok(Some(path_with_indexer))
142 } else {
143 Ok(None)
144 }
145 }
146}