This commit is contained in:
2025-04-09 08:42:30 +02:00
parent 1f155d1bfb
commit 2eec3be632
4 changed files with 261 additions and 211 deletions

View File

@@ -9,29 +9,20 @@ fn main() -> Result<()> {
.about("A tool to manage document collections")
.subcommand(
SubCommand::with_name("scan")
.about("Scan a directory and create a collection")
.about("Scan a directory for .collection files and create collections")
.arg(Arg::with_name("path").required(true).help("Path to the directory"))
.arg(Arg::with_name("name").required(true).help("Name of the collection")),
.arg(Arg::with_name("doctree").long("doctree").takes_value(true).help("Name of the doctree (default: 'default')")),
)
.subcommand(
SubCommand::with_name("list")
.about("List collections"),
)
.subcommand(
SubCommand::with_name("scan-collections")
.about("Recursively scan directories for .collection files")
.arg(Arg::with_name("path").required(true).help("Root path to scan for collections")),
)
.subcommand(
SubCommand::with_name("scan-and-info")
.about("Scan collections and show detailed information")
.arg(Arg::with_name("path").required(true).help("Root path to scan for collections"))
.arg(Arg::with_name("collection").help("Name of the collection (optional)")),
.about("List collections")
.arg(Arg::with_name("doctree").long("doctree").takes_value(true).help("Name of the doctree (default: 'default')")),
)
.subcommand(
SubCommand::with_name("info")
.about("Show detailed information about collections")
.arg(Arg::with_name("collection").help("Name of the collection (optional)")),
.arg(Arg::with_name("collection").help("Name of the collection (optional)"))
.arg(Arg::with_name("doctree").long("doctree").takes_value(true).help("Name of the doctree (default: 'default')")),
)
.subcommand(
SubCommand::with_name("get")
@@ -51,87 +42,39 @@ fn main() -> Result<()> {
.short("f".chars().next().unwrap())
.long("format")
.takes_value(true)
.help("Output format (html or markdown, default: markdown)")),
.help("Output format (html or markdown, default: markdown)"))
.arg(Arg::with_name("doctree").long("doctree").takes_value(true).help("Name of the doctree (default: 'default')")),
)
.subcommand(
SubCommand::with_name("html")
.about("Get page content as HTML")
.arg(Arg::with_name("collection").required(true).help("Name of the collection"))
.arg(Arg::with_name("page").required(true).help("Name of the page")),
.arg(Arg::with_name("page").required(true).help("Name of the page"))
.arg(Arg::with_name("doctree").long("doctree").takes_value(true).help("Name of the doctree (default: 'default')")),
)
.subcommand(
SubCommand::with_name("delete-collection")
.about("Delete a collection from Redis")
.arg(Arg::with_name("collection").required(true).help("Name of the collection")),
.arg(Arg::with_name("collection").required(true).help("Name of the collection"))
.arg(Arg::with_name("doctree").long("doctree").takes_value(true).help("Name of the doctree (default: 'default')")),
)
.subcommand(
SubCommand::with_name("reset")
.about("Delete all collections from Redis"),
.about("Delete all collections from Redis")
.arg(Arg::with_name("doctree").long("doctree").takes_value(true).help("Name of the doctree (default: 'default')")),
)
.get_matches();
// Create a Redis storage instance
let storage = RedisStorage::new("redis://localhost:6379")?;
// Create a DocTree instance
let mut doctree = DocTree::builder()
.with_storage(storage)
.build()?;
// Handle subcommands
if let Some(matches) = matches.subcommand_matches("scan") {
let path = matches.value_of("path").unwrap();
let name = matches.value_of("name").unwrap();
println!("Scanning directory: {}", path);
doctree.add_collection(Path::new(path), name)?;
println!("Collection '{}' created successfully", name);
} else if let Some(_) = matches.subcommand_matches("list") {
let collections = doctree.list_collections();
if collections.is_empty() {
println!("No collections found");
} else {
println!("Collections:");
for collection in collections {
println!("- {}", collection);
}
}
} else if let Some(matches) = matches.subcommand_matches("get") {
let collection = matches.value_of("collection");
let page = matches.value_of("page").unwrap();
let format = matches.value_of("format").unwrap_or("markdown");
if format.to_lowercase() == "html" {
let html = doctree.page_get_html(collection, page)?;
println!("{}", html);
} else {
let content = doctree.page_get(collection, page)?;
println!("{}", content);
}
} else if let Some(matches) = matches.subcommand_matches("html") {
let collection = matches.value_of("collection").unwrap();
let page = matches.value_of("page").unwrap();
let html = doctree.page_get_html(Some(collection), page)?;
println!("{}", html);
} else if let Some(matches) = matches.subcommand_matches("delete-collection") {
let collection = matches.value_of("collection").unwrap();
println!("Deleting collection '{}' from Redis...", collection);
doctree.delete_collection(collection)?;
println!("Collection '{}' deleted successfully", collection);
} else if let Some(_) = matches.subcommand_matches("reset") {
println!("Deleting all collections from Redis...");
doctree.delete_all_collections()?;
println!("All collections deleted successfully");
} else if let Some(matches) = matches.subcommand_matches("scan-collections") {
let path = matches.value_of("path").unwrap();
let doctree_name = matches.value_of("doctree").unwrap_or("default");
println!("Recursively scanning for collections in: {}", path);
println!("Using doctree name: {}", doctree_name);
// Use the from_directory function to create a DocTree with all collections
let doctree = from_directory(Path::new(path))?;
let doctree = from_directory(Path::new(path), Some(doctree_name))?;
// Print the discovered collections
let collections = doctree.list_collections();
@@ -143,28 +86,92 @@ fn main() -> Result<()> {
println!("- {}", collection);
}
}
} else if let Some(matches) = matches.subcommand_matches("scan-and-info") {
let path = matches.value_of("path").unwrap();
let collection_name = matches.value_of("collection");
} else if let Some(matches) = matches.subcommand_matches("list") {
let doctree_name = matches.value_of("doctree").unwrap_or("default");
println!("Recursively scanning for collections in: {}", path);
// Create a storage with the specified doctree name
let mut storage = RedisStorage::new("redis://localhost:6379")?;
storage.set_doctree_name(doctree_name);
// Use the from_directory function to create a DocTree with all collections
let doctree = from_directory(Path::new(path))?;
// Create a DocTree with the specified doctree name
let doctree = DocTree::builder()
.with_storage(storage)
.with_doctree_name(doctree_name)
.build()?;
// Print the discovered collections
let collections = doctree.list_collections();
if collections.is_empty() {
println!("No collections found");
return Ok(());
println!("No collections found in doctree '{}'", doctree_name);
} else {
println!("Collections in doctree '{}':", doctree_name);
for collection in collections {
println!("- {}", collection);
}
}
} else if let Some(matches) = matches.subcommand_matches("get") {
let collection = matches.value_of("collection");
let page = matches.value_of("page").unwrap();
let format = matches.value_of("format").unwrap_or("markdown");
let doctree_name = matches.value_of("doctree").unwrap_or("default");
println!("Discovered collections:");
for collection in &collections {
println!("- {}", collection);
// Create a storage with the specified doctree name
let mut storage = RedisStorage::new("redis://localhost:6379")?;
storage.set_doctree_name(doctree_name);
// Create a DocTree with the specified doctree name
let mut doctree = DocTree::builder()
.with_storage(storage)
.with_doctree_name(doctree_name)
.build()?;
// Load collections from Redis
doctree.load_collections_from_redis()?;
if format.to_lowercase() == "html" {
let html = doctree.page_get_html(collection, page)?;
println!("{}", html);
} else {
let content = doctree.page_get(collection, page)?;
println!("{}", content);
}
} else if let Some(matches) = matches.subcommand_matches("html") {
let collection = matches.value_of("collection").unwrap();
let page = matches.value_of("page").unwrap();
let doctree_name = matches.value_of("doctree").unwrap_or("default");
println!("\nDetailed Collection Information:");
// Create a storage with the specified doctree name
let mut storage = RedisStorage::new("redis://localhost:6379")?;
storage.set_doctree_name(doctree_name);
// Create a DocTree with the specified doctree name
let mut doctree = DocTree::builder()
.with_storage(storage)
.with_doctree_name(doctree_name)
.build()?;
// Load collections from Redis
doctree.load_collections_from_redis()?;
let html = doctree.page_get_html(Some(collection), page)?;
println!("{}", html);
} else if let Some(matches) = matches.subcommand_matches("info") {
let doctree_name = matches.value_of("doctree").unwrap_or("default");
// Create a storage with the specified doctree name
let mut storage = RedisStorage::new("redis://localhost:6379")?;
storage.set_doctree_name(doctree_name);
// Create a DocTree with the specified doctree name
let mut doctree = DocTree::builder()
.with_storage(storage)
.with_doctree_name(doctree_name)
.build()?;
// Load collections from Redis
doctree.load_collections_from_redis()?;
let collection_name = matches.value_of("collection");
if let Some(name) = collection_name {
// Show info for a specific collection
@@ -172,7 +179,7 @@ fn main() -> Result<()> {
Ok(collection) => {
println!("Collection Information for '{}':", name);
println!(" Path: {:?}", collection.path);
println!(" Redis Key: collections:{}", collection.name);
println!(" Redis Key: {}:collections:{}", doctree_name, collection.name);
// List documents
match collection.page_list() {
@@ -181,7 +188,7 @@ fn main() -> Result<()> {
for page in pages {
match collection.page_get_path(&page) {
Ok(path) => {
println!(" - {} => Redis: collections:{} / {}", path, collection.name, page);
println!(" - {} => Redis: {}:collections:{} / {}", path, doctree_name, collection.name, page);
},
Err(_) => {
println!(" - {}", page);
@@ -206,7 +213,7 @@ fn main() -> Result<()> {
println!(" Images ({}):", images.len());
for image in images {
println!(" - {} => Redis: collections:{} / {}", image, collection.name, image);
println!(" - {} => Redis: {}:collections:{} / {}", image, doctree_name, collection.name, image);
}
// Filter other files
@@ -220,97 +227,7 @@ fn main() -> Result<()> {
println!(" Other Files ({}):", other_files.len());
for file in other_files {
println!(" - {} => Redis: collections:{} / {}", file, collection.name, file);
}
},
Err(e) => println!(" Error listing files: {}", e),
}
},
Err(e) => println!("Error: {}", e),
}
} else {
// Show info for all collections
for name in collections {
if let Ok(collection) = doctree.get_collection(&name) {
println!("- {} (Redis Key: collections:{})", name, collection.name);
println!(" Path: {:?}", collection.path);
// Count documents and images
if let Ok(pages) = collection.page_list() {
println!(" Documents: {}", pages.len());
}
if let Ok(files) = collection.file_list() {
let image_count = files.iter()
.filter(|f|
f.ends_with(".png") || f.ends_with(".jpg") ||
f.ends_with(".jpeg") || f.ends_with(".gif") ||
f.ends_with(".svg"))
.count();
println!(" Images: {}", image_count);
println!(" Other Files: {}", files.len() - image_count);
}
}
}
}
} else if let Some(matches) = matches.subcommand_matches("info") {
let collection_name = matches.value_of("collection");
if let Some(name) = collection_name {
// Show info for a specific collection
match doctree.get_collection(name) {
Ok(collection) => {
println!("Collection Information for '{}':", name);
println!(" Path: {:?}", collection.path);
println!(" Redis Key: collections:{}", collection.name);
// List documents
match collection.page_list() {
Ok(pages) => {
println!(" Documents ({}):", pages.len());
for page in pages {
match collection.page_get_path(&page) {
Ok(path) => {
println!(" - {} => Redis: collections:{} / {}", path, collection.name, page);
},
Err(_) => {
println!(" - {}", page);
}
}
}
},
Err(e) => println!(" Error listing documents: {}", e),
}
// List files
match collection.file_list() {
Ok(files) => {
// Filter images
let images: Vec<String> = files.iter()
.filter(|f|
f.ends_with(".png") || f.ends_with(".jpg") ||
f.ends_with(".jpeg") || f.ends_with(".gif") ||
f.ends_with(".svg"))
.cloned()
.collect();
println!(" Images ({}):", images.len());
for image in images {
println!(" - {} => Redis: collections:{} / {}", image, collection.name, image);
}
// Filter other files
let other_files: Vec<String> = files.iter()
.filter(|f|
!f.ends_with(".png") && !f.ends_with(".jpg") &&
!f.ends_with(".jpeg") && !f.ends_with(".gif") &&
!f.ends_with(".svg"))
.cloned()
.collect();
println!(" Other Files ({}):", other_files.len());
for file in other_files {
println!(" - {} => Redis: collections:{} / {}", file, collection.name, file);
println!(" - {} => Redis: {}:collections:{} / {}", file, doctree_name, collection.name, file);
}
},
Err(e) => println!(" Error listing files: {}", e),
@@ -324,10 +241,10 @@ fn main() -> Result<()> {
if collections.is_empty() {
println!("No collections found");
} else {
println!("Collections:");
println!("Collections in doctree '{}':", doctree_name);
for name in collections {
if let Ok(collection) = doctree.get_collection(&name) {
println!("- {} (Redis Key: collections:{})", name, collection.name);
println!("- {} (Redis Key: {}:collections:{})", name, doctree_name, collection.name);
println!(" Path: {:?}", collection.path);
// Count documents and images
@@ -337,9 +254,9 @@ fn main() -> Result<()> {
if let Ok(files) = collection.file_list() {
let image_count = files.iter()
.filter(|f|
f.ends_with(".png") || f.ends_with(".jpg") ||
f.ends_with(".jpeg") || f.ends_with(".gif") ||
.filter(|f|
f.ends_with(".png") || f.ends_with(".jpg") ||
f.ends_with(".jpeg") || f.ends_with(".gif") ||
f.ends_with(".svg"))
.count();
println!(" Images: {}", image_count);
@@ -349,6 +266,39 @@ fn main() -> Result<()> {
}
}
}
} else if let Some(matches) = matches.subcommand_matches("delete-collection") {
let collection = matches.value_of("collection").unwrap();
let doctree_name = matches.value_of("doctree").unwrap_or("default");
// Create a storage with the specified doctree name
let mut storage = RedisStorage::new("redis://localhost:6379")?;
storage.set_doctree_name(doctree_name);
// Create a DocTree with the specified doctree name
let mut doctree = DocTree::builder()
.with_storage(storage)
.with_doctree_name(doctree_name)
.build()?;
println!("Deleting collection '{}' from Redis in doctree '{}'...", collection, doctree_name);
doctree.delete_collection(collection)?;
println!("Collection '{}' deleted successfully", collection);
} else if let Some(matches) = matches.subcommand_matches("reset") {
let doctree_name = matches.value_of("doctree").unwrap_or("default");
// Create a storage with the specified doctree name
let mut storage = RedisStorage::new("redis://localhost:6379")?;
storage.set_doctree_name(doctree_name);
// Create a DocTree with the specified doctree name
let mut doctree = DocTree::builder()
.with_storage(storage)
.with_doctree_name(doctree_name)
.build()?;
println!("Deleting all collections from Redis in doctree '{}'...", doctree_name);
doctree.delete_all_collections()?;
println!("All collections deleted successfully");
} else {
println!("No command specified. Use --help for usage information.");
}