Skip to content

Commit a57db5b

Browse files
committed
feedback
1 parent d0576d8 commit a57db5b

4 files changed

Lines changed: 70 additions & 37 deletions

File tree

src/config.rs

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -324,21 +324,13 @@ impl Config {
324324
"embedded" => {
325325
// No validation needed - embedded indexers are built-in
326326
}
327-
"prowlarr" => {
328-
// Prowlarr mode requires prowlarr config
327+
"prowlarr" | "both" => {
328+
// Prowlarr or both mode requires prowlarr config
329329
if self.prowlarr.is_none() {
330-
return Err(ConfigError::ValidationError(
331-
"indexers.mode is 'prowlarr' but prowlarr config is missing".to_string(),
332-
));
333-
}
334-
self.validate_prowlarr_config()?;
335-
}
336-
"both" => {
337-
// Both mode requires prowlarr config
338-
if self.prowlarr.is_none() {
339-
return Err(ConfigError::ValidationError(
340-
"indexers.mode is 'both' but prowlarr config is missing".to_string(),
341-
));
330+
return Err(ConfigError::ValidationError(format!(
331+
"indexers.mode is '{}' but prowlarr config is missing",
332+
self.indexers.mode
333+
)));
342334
}
343335
self.validate_prowlarr_config()?;
344336
}

src/indexers/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,13 +105,16 @@ impl IndexerManager {
105105

106106
let mut all_results = Vec::new();
107107

108+
// Convert query to String once, then clone for each indexer
109+
let query = query.to_string();
110+
108111
// Create search tasks for all enabled indexers
109112
let search_futures: Vec<_> = self
110113
.indexers
111114
.iter()
112115
.filter(|indexer| indexer.is_enabled())
113116
.map(|indexer| {
114-
let query = query.to_string();
117+
let query = query.clone();
115118
async move {
116119
let name = indexer.name();
117120
match indexer.search(&query, categories).await {

src/indexers/x1337.rs

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use super::{IndexerError, TorrentIndexer, common};
44
use crate::torznab::TorrentResult;
55
use async_trait::async_trait;
6+
use futures::future::join_all;
67
use reqwest::Client;
78
use scraper::{Html, Selector};
89

@@ -42,6 +43,25 @@ impl X1337Indexer {
4243
Ok(response.text().await?)
4344
}
4445

46+
/// Fetch the magnet URL from a 1337x detail page
47+
async fn fetch_magnet_url(&self, detail_url: &str) -> Result<String, IndexerError> {
48+
let html = self.fetch_html(detail_url).await?;
49+
let document = Html::parse_document(&html);
50+
51+
// The magnet link is in an anchor with href starting with "magnet:"
52+
let magnet_selector = Selector::parse("a[href^='magnet:']")
53+
.map_err(|e| IndexerError::ParseError(format!("Invalid selector: {}", e)))?;
54+
55+
document
56+
.select(&magnet_selector)
57+
.next()
58+
.and_then(|elem| elem.value().attr("href"))
59+
.map(String::from)
60+
.ok_or_else(|| {
61+
IndexerError::ParseError("Magnet link not found on detail page".to_string())
62+
})
63+
}
64+
4565
fn parse_results(&self, html: &str) -> Result<Vec<TorrentResult>, IndexerError> {
4666
let document = Html::parse_document(html);
4767

@@ -132,9 +152,33 @@ impl TorrentIndexer for X1337Indexer {
132152
tracing::debug!(url, "1337x: searching");
133153

134154
let html = self.fetch_html(&url).await?;
135-
let results = self.parse_results(&html)?;
155+
let mut results = self.parse_results(&html)?;
156+
157+
tracing::debug!(
158+
count = results.len(),
159+
"1337x: found results, fetching magnet URLs"
160+
);
161+
162+
// Fetch magnet URLs from detail pages in parallel
163+
let detail_urls: Vec<_> = results.iter().filter_map(|r| r.link.clone()).collect();
164+
let magnet_futures: Vec<_> = detail_urls
165+
.iter()
166+
.map(|detail_url| self.fetch_magnet_url(detail_url))
167+
.collect();
168+
169+
let magnets = join_all(magnet_futures).await;
170+
171+
// Update results with fetched magnet URLs
172+
for (result, magnet_result) in results.iter_mut().zip(magnets.into_iter()) {
173+
if let Ok(magnet) = magnet_result {
174+
result.magnet_url = Some(magnet);
175+
}
176+
}
177+
178+
// Filter out results without magnet URLs
179+
results.retain(|r| r.magnet_url.is_some());
136180

137-
tracing::debug!(count = results.len(), "1337x: found results");
181+
tracing::debug!(count = results.len(), "1337x: results with magnet URLs");
138182

139183
if results.is_empty() {
140184
Err(IndexerError::NotFound)

src/tui/mod.rs

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2574,19 +2574,16 @@ fn apply_settings_edit(app: &App, config: &mut Config) {
25742574

25752575
match app.settings_section {
25762576
SettingsSection::Prowlarr => {
2577-
// Ensure prowlarr config exists
2578-
if config.prowlarr.is_none() {
2579-
config.prowlarr = Some(crate::config::ProwlarrConfig {
2577+
let prowlarr = config
2578+
.prowlarr
2579+
.get_or_insert_with(|| crate::config::ProwlarrConfig {
25802580
url: String::new(),
25812581
apikey: String::new(),
25822582
});
2583-
}
2584-
if let Some(ref mut prowlarr) = config.prowlarr {
2585-
match app.settings_field_index {
2586-
0 => prowlarr.url = value,
2587-
1 => prowlarr.apikey = value,
2588-
_ => {}
2589-
}
2583+
match app.settings_field_index {
2584+
0 => prowlarr.url = value,
2585+
1 => prowlarr.apikey = value,
2586+
_ => {}
25902587
}
25912588
}
25922589
SettingsSection::Tmdb => {
@@ -2746,19 +2743,16 @@ fn apply_wizard_edit(app: &App, config: &mut Config) {
27462743

27472744
match app.wizard_step {
27482745
WizardStep::Prowlarr => {
2749-
// Ensure prowlarr config exists
2750-
if config.prowlarr.is_none() {
2751-
config.prowlarr = Some(crate::config::ProwlarrConfig {
2746+
let prowlarr = config
2747+
.prowlarr
2748+
.get_or_insert_with(|| crate::config::ProwlarrConfig {
27522749
url: String::new(),
27532750
apikey: String::new(),
27542751
});
2755-
}
2756-
if let Some(ref mut prowlarr) = config.prowlarr {
2757-
match app.wizard_field_index {
2758-
0 => prowlarr.url = value,
2759-
1 => prowlarr.apikey = value,
2760-
_ => {}
2761-
}
2752+
match app.wizard_field_index {
2753+
0 => prowlarr.url = value,
2754+
1 => prowlarr.apikey = value,
2755+
_ => {}
27622756
}
27632757
}
27642758
WizardStep::Tmdb => {

0 commit comments

Comments
 (0)