systemprompt_cli/commands/web/sitemap/
show.rs1use anyhow::{Context, Result};
7use clap::Args;
8use std::fs;
9
10use crate::CliConfig;
11use crate::shared::CommandOutput;
12use systemprompt_config::ProfileBootstrap;
13use systemprompt_logging::CliService;
14use systemprompt_models::content_config::ContentConfigRaw;
15
16use super::super::types::SitemapRoute;
17
18#[derive(Debug, Clone, Copy, Args)]
19pub struct ShowArgs {
20 #[arg(long, help = "Show XML preview")]
21 pub preview: bool,
22}
23
24pub(super) fn execute(args: ShowArgs, config: &CliConfig) -> Result<CommandOutput> {
25 let profile = ProfileBootstrap::get().context("Failed to get profile")?;
26 execute_with_config_path(args, config, profile.paths.content_config().as_str())
27}
28
29pub fn execute_with_config_path(
30 args: ShowArgs,
31 _config: &CliConfig,
32 content_config_path: &str,
33) -> Result<CommandOutput> {
34 let content = fs::read_to_string(content_config_path)
35 .with_context(|| format!("Failed to read content config at {}", content_config_path))?;
36
37 let config: ContentConfigRaw = serde_yaml::from_str(&content)
38 .with_context(|| format!("Failed to parse content config at {}", content_config_path))?;
39
40 let mut routes: Vec<SitemapRoute> = Vec::new();
41
42 for (name, source) in &config.content_sources {
43 if !source.enabled {
44 continue;
45 }
46
47 if let Some(sitemap) = &source.sitemap {
48 if !sitemap.enabled {
49 continue;
50 }
51
52 if let Some(parent) = &sitemap.parent_route
53 && parent.enabled
54 {
55 routes.push(SitemapRoute {
56 url: parent.url.clone(),
57 priority: parent.priority,
58 changefreq: parent.changefreq.clone(),
59 source: format!("{} (parent)", name),
60 });
61 }
62
63 routes.push(SitemapRoute {
64 url: sitemap.url_pattern.clone(),
65 priority: sitemap.priority,
66 changefreq: sitemap.changefreq.clone(),
67 source: name.clone(),
68 });
69 }
70 }
71
72 routes.sort_by(|a, b| {
73 b.priority
74 .partial_cmp(&a.priority)
75 .unwrap_or(std::cmp::Ordering::Equal)
76 });
77
78 if args.preview {
79 let xml = generate_xml_preview(&routes);
80 CliService::output(&xml);
81 }
82
83 Ok(
84 CommandOutput::table_of(vec!["url", "priority", "changefreq", "source"], &routes)
85 .with_title("Sitemap Configuration"),
86 )
87}
88
89fn generate_xml_preview(routes: &[SitemapRoute]) -> String {
90 let mut xml = String::from(concat!(
91 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
92 "<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n"
93 ));
94
95 for route in routes {
96 xml.push_str(&format!(
97 " <url>\n <loc>{}</loc>\n <priority>{:.1}</priority>\n \
98 <changefreq>{}</changefreq>\n </url>\n",
99 route.url, route.priority, route.changefreq
100 ));
101 }
102
103 xml.push_str("</urlset>\n");
104 xml
105}