Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
195 changes: 123 additions & 72 deletions martin/src/config/file/file_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,111 @@ pub async fn resolve_files<T: TileSourceConfiguration>(
resolve_int(config, idr, extension).await
}

#[cfg(feature = "_tiles")]
async fn resolve_one_source_int<T: TileSourceConfiguration>(
custom: &T,
idr: &IdResolver,
id: &String,
source: FileConfigSrc,
files: &mut HashSet<PathBuf>,
configs: &mut BTreeMap<String, FileConfigSrc>,
) -> MartinResult<Vec<BoxedSource>> {
let mut results = Vec::new();

if let Some(url) = parse_url(T::parse_urls(), source.get_path())? {
let dup = !files.insert(source.get_path().clone());
let dup = if dup { "duplicate " } else { "" };
let id = idr.resolve(&id, url.to_string());
configs.insert(id.clone(), source);
results.push(custom.new_sources_url(id.clone(), url.clone()).await?);
info!("Configured {dup}source {id} from {}", sanitize_url(&url));
} else {
let can = source.abs_path()?;
if !can.is_file() {
log::warn!("The file: {} does not exist", can.display());
}

let dup = !files.insert(can.clone());
let dup = if dup { "duplicate " } else { "" };
let id = idr.resolve(&id, can.to_string_lossy().to_string());
info!("Configured {dup}source {id} from {}", can.display());
configs.insert(id.clone(), source.clone());
results.push(custom.new_sources(id, source.into_path()).await?);
}

Ok(results)
}

#[cfg(feature = "_tiles")]
async fn resolve_one_path_int<T: TileSourceConfiguration>(
custom: &T,
idr: &IdResolver,
extension: &[&str],
path: PathBuf,
files: &mut HashSet<PathBuf>,
directories: &mut Vec<PathBuf>,
configs: &mut BTreeMap<String, FileConfigSrc>,
) -> MartinResult<Vec<BoxedSource>> {
let mut results = Vec::new();

if let Some(url) = parse_url(T::parse_urls(), &path)? {
let target_ext = extension.iter().find(|&e| url.to_string().ends_with(e));
let id = if let Some(ext) = target_ext {
url.path_segments()
.and_then(Iterator::last)
.and_then(|s| {
// Strip extension and trailing dot, or keep the original string
s.strip_suffix(ext)
.and_then(|s| s.strip_suffix('.'))
.or(Some(s))
})
.unwrap_or("web_source")
} else {
"web_source"
};

let id = idr.resolve(id, url.to_string());
configs.insert(id.clone(), FileConfigSrc::Path(path));
results.push(custom.new_sources_url(id.clone(), url.clone()).await?);
info!("Configured source {id} from URL {}", sanitize_url(&url));
} else {
let is_dir = path.is_dir();
let dir_files = if is_dir {
// directories will be kept in the config just in case there are new files
directories.push(path.clone());
collect_files_with_extension(&path, extension)?
} else if path.is_file() {
vec![path]
} else {
return Err(MartinError::from(ConfigFileError::InvalidFilePath(
path.canonicalize().unwrap_or(path),
)));
};
for path in dir_files {
let can = path
.canonicalize()
.map_err(|e| ConfigFileError::IoError(e, path.clone()))?;
if files.contains(&can) {
if !is_dir {
warn!("Ignoring duplicate MBTiles path: {}", can.display());
}
continue;
}
let id = path.file_stem().map_or_else(
|| "_unknown".to_string(),
|s| s.to_string_lossy().to_string(),
);
let id = idr.resolve(&id, can.to_string_lossy().to_string());
info!("Configured source {id} from {}", can.display());
files.insert(can);
configs.insert(id.clone(), FileConfigSrc::Path(path.clone()));
results.push(custom.new_sources(id, path).await?);
}
}

Ok(results)
}

#[cfg(feature = "_tiles")]
async fn resolve_int<T: TileSourceConfiguration>(
config: &mut FileConfigEnum<T>,
Expand All @@ -290,83 +395,29 @@ async fn resolve_int<T: TileSourceConfiguration>(

if let Some(sources) = cfg.sources {
for (id, source) in sources {
if let Some(url) = parse_url(T::parse_urls(), source.get_path())? {
let dup = !files.insert(source.get_path().clone());
let dup = if dup { "duplicate " } else { "" };
let id = idr.resolve(&id, url.to_string());
configs.insert(id.clone(), source);
results.push(cfg.custom.new_sources_url(id.clone(), url.clone()).await?);
info!("Configured {dup}source {id} from {}", sanitize_url(&url));
} else {
let can = source.abs_path()?;
if !can.is_file() {
log::warn!("The file: {} does not exist", can.display());
}

let dup = !files.insert(can.clone());
let dup = if dup { "duplicate " } else { "" };
let id = idr.resolve(&id, can.to_string_lossy().to_string());
info!("Configured {dup}source {id} from {}", can.display());
configs.insert(id.clone(), source.clone());
results.push(cfg.custom.new_sources(id, source.into_path()).await?);
match resolve_one_source_int(&cfg.custom, idr, &id, source, &mut files, &mut configs)
.await
{
Ok(mut sources) => results.append(&mut sources),
Err(e) => warn!("Failed to resolve source {}: {}", id, e),
}
}
}

for path in cfg.paths {
if let Some(url) = parse_url(T::parse_urls(), &path)? {
let target_ext = extension.iter().find(|&e| url.to_string().ends_with(e));
let id = if let Some(ext) = target_ext {
url.path_segments()
.and_then(Iterator::last)
.and_then(|s| {
// Strip extension and trailing dot, or keep the original string
s.strip_suffix(ext)
.and_then(|s| s.strip_suffix('.'))
.or(Some(s))
})
.unwrap_or("web_source")
} else {
"web_source"
};

let id = idr.resolve(id, url.to_string());
configs.insert(id.clone(), FileConfigSrc::Path(path));
results.push(cfg.custom.new_sources_url(id.clone(), url.clone()).await?);
info!("Configured source {id} from URL {}", sanitize_url(&url));
} else {
let is_dir = path.is_dir();
let dir_files = if is_dir {
// directories will be kept in the config just in case there are new files
directories.push(path.clone());
collect_files_with_extension(&path, extension)?
} else if path.is_file() {
vec![path]
} else {
return Err(MartinError::from(ConfigFileError::InvalidFilePath(
path.canonicalize().unwrap_or(path),
)));
};
for path in dir_files {
let can = path
.canonicalize()
.map_err(|e| ConfigFileError::IoError(e, path.clone()))?;
if files.contains(&can) {
if !is_dir {
warn!("Ignoring duplicate MBTiles path: {}", can.display());
}
continue;
}
let id = path.file_stem().map_or_else(
|| "_unknown".to_string(),
|s| s.to_string_lossy().to_string(),
);
let id = idr.resolve(&id, can.to_string_lossy().to_string());
info!("Configured source {id} from {}", can.display());
files.insert(can);
configs.insert(id.clone(), FileConfigSrc::Path(path.clone()));
results.push(cfg.custom.new_sources(id, path).await?);
}
match resolve_one_path_int(
&cfg.custom,
idr,
extension,
path,
&mut files,
&mut directories,
&mut configs,
)
.await
{
Ok(mut sources) => results.append(&mut sources),
Err(e) => warn!("Failed to resolve sources from path: {}", e),
}
}

Expand Down
Loading