This commit is contained in:
despiegk 2025-05-03 05:52:42 +04:00
parent 28a7ef3a94
commit 2fae059512
3 changed files with 197 additions and 47 deletions

View File

@ -202,7 +202,7 @@ Add doctree to your Cargo.toml:
```toml
[dependencies]
doctree = { path = "path/to/doctree" }
doctree = { git = "https://git.ourworld.tf/herocode/doctree", branch = "main", package = "doctree", path = "doctree/src" }
```
Basic usage:

View File

@ -10,6 +10,8 @@ pub struct RedisStorage {
connection: Arc<Mutex<Connection>>,
// Doctree name for key prefixing
doctree_name: Arc<Mutex<String>>,
// Debug mode flag
debug: Arc<Mutex<bool>>,
}
impl RedisStorage {
@ -34,6 +36,7 @@ impl RedisStorage {
client,
connection: Arc::new(Mutex::new(connection)),
doctree_name: Arc::new(Mutex::new("default".to_string())),
debug: Arc::new(Mutex::new(false)),
})
}
@ -47,6 +50,26 @@ impl RedisStorage {
*doctree_name = name.to_string();
}
/// Set the debug mode
///
/// # Arguments
///
/// * `enable` - Whether to enable debug mode
pub fn set_debug(&self, enable: bool) {
let mut debug = self.debug.lock().unwrap();
*debug = enable;
}
/// Check if debug mode is enabled
///
/// # Returns
///
/// true if debug mode is enabled, false otherwise
fn is_debug_enabled(&self) -> bool {
let debug = self.debug.lock().unwrap();
*debug
}
/// Get the doctree name
///
/// # Returns
@ -71,7 +94,10 @@ impl RedisStorage {
pub fn store_collection_entry(&self, collection: &str, key: &str, value: &str) -> Result<()> {
let doctree_name = self.get_doctree_name();
let redis_key = format!("{}:collections:{}", doctree_name, collection);
if self.is_debug_enabled() {
println!("DEBUG: Redis operation - HSET {} {} {}", redis_key, key, value);
}
// Get a connection from the pool
let mut conn = self.connection.lock().unwrap();
@ -83,8 +109,10 @@ impl RedisStorage {
.arg(value)
.execute(&mut *conn);
if self.is_debug_enabled() {
println!("DEBUG: Stored entry in Redis - collection: '{}', key: '{}', value: '{}'",
collection, key, value);
}
Ok(())
}
@ -102,7 +130,10 @@ impl RedisStorage {
pub fn get_collection_entry(&self, collection: &str, key: &str) -> Result<String> {
let doctree_name = self.get_doctree_name();
let collection_key = format!("{}:collections:{}", doctree_name, collection);
if self.is_debug_enabled() {
println!("DEBUG: Redis operation - HGET {} {}", collection_key, key);
}
// Get a connection from the pool
let mut conn = self.connection.lock().unwrap();
@ -117,13 +148,17 @@ impl RedisStorage {
// Check if the entry exists
match result {
Some(value) => {
if self.is_debug_enabled() {
println!("DEBUG: Retrieved entry from Redis - collection: '{}', key: '{}', value: '{}'",
collection, key, value);
}
Ok(value)
},
None => {
if self.is_debug_enabled() {
println!("DEBUG: Entry not found in Redis - collection: '{}', key: '{}'",
collection, key);
}
Err(DocTreeError::FileNotFound(key.to_string()))
}
}
@ -142,7 +177,10 @@ impl RedisStorage {
pub fn delete_collection_entry(&self, collection: &str, key: &str) -> Result<()> {
let doctree_name = self.get_doctree_name();
let collection_key = format!("{}:collections:{}", doctree_name, collection);
if self.is_debug_enabled() {
println!("DEBUG: Redis operation - HDEL {} {}", collection_key, key);
}
// Get a connection from the pool
let mut conn = self.connection.lock().unwrap();
@ -163,8 +201,10 @@ impl RedisStorage {
.arg(key)
.execute(&mut *conn);
if self.is_debug_enabled() {
println!("DEBUG: Deleted entry from Redis - collection: '{}', key: '{}'",
collection, key);
}
Ok(())
}
@ -181,7 +221,10 @@ impl RedisStorage {
pub fn list_collection_entries(&self, collection: &str) -> Result<Vec<String>> {
let doctree_name = self.get_doctree_name();
let collection_key = format!("{}:collections:{}", doctree_name, collection);
if self.is_debug_enabled() {
println!("DEBUG: Redis operation - HKEYS {}", collection_key);
}
// Get a connection from the pool
let mut conn = self.connection.lock().unwrap();
@ -201,9 +244,11 @@ impl RedisStorage {
.arg(&collection_key)
.query(&mut *conn)
.map_err(|e| DocTreeError::RedisError(format!("Redis error: {}", e)))?;
if self.is_debug_enabled() {
println!("DEBUG: Listed {} entries from Redis - collection: '{}'",
keys.len(), collection);
}
Ok(keys)
}
@ -220,7 +265,10 @@ impl RedisStorage {
pub fn delete_collection(&self, collection: &str) -> Result<()> {
let doctree_name = self.get_doctree_name();
let redis_key = format!("{}:collections:{}", doctree_name, collection);
if self.is_debug_enabled() {
println!("DEBUG: Redis operation - DEL {}", redis_key);
}
// Get a connection from the pool
let mut conn = self.connection.lock().unwrap();
@ -230,7 +278,9 @@ impl RedisStorage {
.arg(&redis_key)
.execute(&mut *conn);
if self.is_debug_enabled() {
println!("DEBUG: Deleted collection from Redis - collection: '{}'", collection);
}
Ok(())
}
@ -247,7 +297,10 @@ impl RedisStorage {
pub fn collection_exists(&self, collection: &str) -> Result<bool> {
let doctree_name = self.get_doctree_name();
let collection_key = format!("{}:collections:{}", doctree_name, collection);
if self.is_debug_enabled() {
println!("DEBUG: Redis operation - EXISTS {}", collection_key);
}
// Get a connection from the pool
let mut conn = self.connection.lock().unwrap();
@ -258,8 +311,10 @@ impl RedisStorage {
.query(&mut *conn)
.map_err(|e| DocTreeError::RedisError(format!("Redis error: {}", e)))?;
if self.is_debug_enabled() {
println!("DEBUG: Collection exists check - collection: '{}', exists: {}",
collection, exists);
}
Ok(exists)
}
@ -271,7 +326,10 @@ impl RedisStorage {
/// A vector of collection names or an error
pub fn list_all_collections(&self) -> Result<Vec<String>> {
let doctree_name = self.get_doctree_name();
if self.is_debug_enabled() {
println!("DEBUG: Redis operation - KEYS {}:collections:*", doctree_name);
}
// Get a connection from the pool
let mut conn = self.connection.lock().unwrap();
@ -297,7 +355,9 @@ impl RedisStorage {
})
.collect();
if self.is_debug_enabled() {
println!("DEBUG: Found {} collections in Redis", keys.len());
}
Ok(collections)
}
@ -309,7 +369,10 @@ impl RedisStorage {
/// Ok(()) on success or an error
pub fn delete_all_collections(&self) -> Result<()> {
let doctree_name = self.get_doctree_name();
if self.is_debug_enabled() {
println!("DEBUG: Redis operation - KEYS {}:collections:*", doctree_name);
}
// Get a connection from the pool
let mut conn = self.connection.lock().unwrap();
@ -320,17 +383,23 @@ impl RedisStorage {
.arg(&pattern)
.query(&mut *conn)
.map_err(|e| DocTreeError::RedisError(format!("Redis error: {}", e)))?;
if self.is_debug_enabled() {
println!("DEBUG: Found {} collections in Redis", keys.len());
}
// Delete each collection
for key in keys {
if self.is_debug_enabled() {
println!("DEBUG: Redis operation - DEL {}", key);
}
redis::cmd("DEL")
.arg(&key)
.execute(&mut *conn);
if self.is_debug_enabled() {
println!("DEBUG: Deleted collection from Redis - key: '{}'", key);
}
}
Ok(())
}
@ -348,7 +417,10 @@ impl RedisStorage {
pub fn store_collection_path(&self, collection: &str, path: &str) -> Result<()> {
let doctree_name = self.get_doctree_name();
let redis_key = format!("{}:collections:{}:path", doctree_name, collection);
if self.is_debug_enabled() {
println!("DEBUG: Redis operation - SET {} {}", redis_key, path);
}
// Get a connection from the pool
let mut conn = self.connection.lock().unwrap();
@ -359,8 +431,10 @@ impl RedisStorage {
.arg(path)
.execute(&mut *conn);
if self.is_debug_enabled() {
println!("DEBUG: Stored collection path in Redis - collection: '{}', path: '{}'",
collection, path);
}
Ok(())
}
@ -377,7 +451,10 @@ impl RedisStorage {
pub fn get_collection_path(&self, collection: &str) -> Result<String> {
let doctree_name = self.get_doctree_name();
let redis_key = format!("{}:collections:{}:path", doctree_name, collection);
if self.is_debug_enabled() {
println!("DEBUG: Redis operation - GET {}", redis_key);
}
// Get a connection from the pool
let mut conn = self.connection.lock().unwrap();
@ -391,13 +468,17 @@ impl RedisStorage {
// Check if the path exists
match result {
Some(path) => {
if self.is_debug_enabled() {
println!("DEBUG: Retrieved collection path from Redis - collection: '{}', path: '{}'",
collection, path);
}
Ok(path)
},
None => {
if self.is_debug_enabled() {
println!("DEBUG: Collection path not found in Redis - collection: '{}'",
collection);
}
Err(DocTreeError::CollectionNotFound(collection.to_string()))
}
}
@ -415,6 +496,7 @@ impl Clone for RedisStorage {
client: self.client.clone(),
connection: Arc::new(Mutex::new(connection)),
doctree_name: self.doctree_name.clone(),
debug: self.debug.clone(),
}
}
}

View File

@ -7,6 +7,12 @@ fn main() -> Result<()> {
.version("0.1.0")
.author("Your Name")
.about("A tool to manage document collections")
.arg(
Arg::with_name("debug")
.long("debug")
.help("Enable debug logging")
.takes_value(false)
)
.subcommand(
SubCommand::with_name("scan")
.about("Scan a directory for .collection files and create collections")
@ -65,9 +71,16 @@ fn main() -> Result<()> {
)
.get_matches();
// Check if debug mode is enabled
let debug_mode = matches.is_present("debug");
// Handle subcommands
if let Some(matches) = matches.subcommand_matches("scan") {
let path = matches.value_of("path").unwrap();
if debug_mode {
println!("DEBUG: Scanning path: {}", path);
}
let doctree_name = matches.value_of("doctree").unwrap_or("default");
println!("Recursively scanning for collections in: {}", path);
@ -89,17 +102,21 @@ fn main() -> Result<()> {
} else if let Some(matches) = matches.subcommand_matches("list") {
let doctree_name = matches.value_of("doctree").unwrap_or("default");
if debug_mode {
println!("DEBUG: Listing collections for doctree: {}", doctree_name);
}
// Create a storage with the specified doctree name
let storage = RedisStorage::new("redis://localhost:6379")?;
storage.set_doctree_name(doctree_name);
storage.set_debug(debug_mode);
// Create a DocTree with the specified doctree name
let doctree = DocTree::builder()
.with_storage(storage)
.with_doctree_name(doctree_name)
.build()?;
if debug_mode {
println!("DEBUG: Connected to Redis storage");
}
let collections = doctree.list_collections();
// Get collections directly from Redis to avoid debug output from DocTree
let collections = storage.list_all_collections()?;
if collections.is_empty() {
println!("No collections found in doctree '{}'", doctree_name);
@ -115,9 +132,19 @@ fn main() -> Result<()> {
let format = matches.value_of("format").unwrap_or("markdown");
let doctree_name = matches.value_of("doctree").unwrap_or("default");
if debug_mode {
println!("DEBUG: Getting page '{}' from collection '{}' in doctree '{}' with format '{}'",
page, collection.unwrap_or("(default)"), doctree_name, format);
}
// Create a storage with the specified doctree name
let storage = RedisStorage::new("redis://localhost:6379")?;
storage.set_doctree_name(doctree_name);
storage.set_debug(debug_mode);
if debug_mode {
println!("DEBUG: Connected to Redis storage");
}
// Create a DocTree with the specified doctree name
let mut doctree = DocTree::builder()
@ -140,9 +167,19 @@ fn main() -> Result<()> {
let page = matches.value_of("page").unwrap();
let doctree_name = matches.value_of("doctree").unwrap_or("default");
if debug_mode {
println!("DEBUG: Getting HTML for page '{}' from collection '{}' in doctree '{}'",
page, collection, doctree_name);
}
// Create a storage with the specified doctree name
let storage = RedisStorage::new("redis://localhost:6379")?;
storage.set_doctree_name(doctree_name);
storage.set_debug(debug_mode);
if debug_mode {
println!("DEBUG: Connected to Redis storage");
}
// Create a DocTree with the specified doctree name
let mut doctree = DocTree::builder()
@ -157,10 +194,24 @@ fn main() -> Result<()> {
println!("{}", html);
} else if let Some(matches) = matches.subcommand_matches("info") {
let doctree_name = matches.value_of("doctree").unwrap_or("default");
let collection_name = matches.value_of("collection");
if debug_mode {
if let Some(name) = collection_name {
println!("DEBUG: Getting info for collection '{}' in doctree '{}'", name, doctree_name);
} else {
println!("DEBUG: Getting info for all collections in doctree '{}'", doctree_name);
}
}
// Create a storage with the specified doctree name
let storage = RedisStorage::new("redis://localhost:6379")?;
storage.set_doctree_name(doctree_name);
storage.set_debug(debug_mode);
if debug_mode {
println!("DEBUG: Connected to Redis storage");
}
// Create a DocTree with the specified doctree name
let mut doctree = DocTree::builder()
@ -270,9 +321,17 @@ fn main() -> Result<()> {
let collection = matches.value_of("collection").unwrap();
let doctree_name = matches.value_of("doctree").unwrap_or("default");
if debug_mode {
println!("DEBUG: Deleting collection '{}' from doctree '{}'", collection, doctree_name);
}
// Create a storage with the specified doctree name
let storage = RedisStorage::new("redis://localhost:6379")?;
storage.set_doctree_name(doctree_name);
storage.set_debug(debug_mode);
if debug_mode {
println!("DEBUG: Connected to Redis storage");
}
// Create a DocTree with the specified doctree name
let mut doctree = DocTree::builder()
@ -286,9 +345,18 @@ fn main() -> Result<()> {
} else if let Some(matches) = matches.subcommand_matches("reset") {
let doctree_name = matches.value_of("doctree").unwrap_or("default");
if debug_mode {
println!("DEBUG: Resetting all collections in doctree '{}'", doctree_name);
}
// Create a storage with the specified doctree name
let storage = RedisStorage::new("redis://localhost:6379")?;
storage.set_doctree_name(doctree_name);
storage.set_debug(debug_mode);
if debug_mode {
println!("DEBUG: Connected to Redis storage");
}
// Create a DocTree with the specified doctree name
let mut doctree = DocTree::builder()