pub mod archive;
pub mod cli;
pub mod config;
pub mod crawler;
pub mod errors;
pub mod export;
pub mod fetch;
pub mod ocr;
pub mod parse;
pub mod render;
pub mod search;
pub mod storage;
pub mod tui;
pub use archive::{ArchiveLayout, ArchiveManifest, CrawlStats, ThesaSidecarSummary};
pub use config::{ArchiveOutputProfile, Config};
pub use crawler::{
ArchiveProgress, ArchiveProgressPhase, ArchiveProgressSender, ArchiveRunOptions, ArchiveSummary,
};
pub use errors::{Result, SiteforgeError};
pub use export::ExportFormat;
pub use storage::{SearchResult, StoredAsset, StoredPage};
#[derive(Debug, Clone)]
pub struct Siteforge {
config: Config,
}
impl Siteforge {
pub fn new(config: Config) -> Self {
Self { config }
}
pub fn config(&self) -> &Config {
&self.config
}
pub fn config_mut(&mut self) -> &mut Config {
&mut self.config
}
pub fn archive_layout(&self, archive_id: &str) -> Result<ArchiveLayout> {
Ok(ArchiveLayout::new(
self.config.resolved_archive_root()?,
archive_id.to_string(),
))
}
pub async fn archive(&self, options: ArchiveRunOptions) -> Result<ArchiveSummary> {
crawler::run_archive(self.config.clone(), options).await
}
pub async fn archive_page(&self, url: impl AsRef<str>) -> Result<ArchiveSummary> {
let options = ArchiveRunOptions::single_page_url(url, &self.config)?;
self.archive(options).await
}
pub async fn archive_page_with_progress(
&self,
url: impl AsRef<str>,
progress: ArchiveProgressSender,
) -> Result<ArchiveSummary> {
let options = ArchiveRunOptions::single_page_url(url, &self.config)?;
self.archive_with_progress(options, progress).await
}
pub async fn archive_full_site(&self, url: impl AsRef<str>) -> Result<ArchiveSummary> {
let options = ArchiveRunOptions::full_site_url(url, &self.config)?;
self.archive(options).await
}
pub async fn archive_full_site_with_progress(
&self,
url: impl AsRef<str>,
progress: ArchiveProgressSender,
) -> Result<ArchiveSummary> {
let options = ArchiveRunOptions::full_site_url(url, &self.config)?;
self.archive_with_progress(options, progress).await
}
pub async fn archive_with_progress(
&self,
options: ArchiveRunOptions,
progress: ArchiveProgressSender,
) -> Result<ArchiveSummary> {
crawler::run_archive_with_progress(self.config.clone(), options, progress).await
}
pub async fn resume(&self, archive_id: &str) -> Result<ArchiveSummary> {
crawler::resume_archive(self.config.clone(), archive_id).await
}
pub async fn resume_with_progress(
&self,
archive_id: &str,
progress: ArchiveProgressSender,
) -> Result<ArchiveSummary> {
crawler::resume_archive_with_progress(self.config.clone(), archive_id, progress).await
}
pub fn list_archives(&self) -> Result<Vec<ArchiveManifest>> {
archive::list_archives(&self.config)
}
pub fn search(
&self,
archive_id: Option<&str>,
query: &str,
limit: usize,
) -> Result<Vec<SearchResult>> {
search::search_archives(&self.config, archive_id, query, limit)
}
pub fn export(
&self,
archive_id: &str,
format: ExportFormat,
output: Option<&std::path::Path>,
) -> Result<std::path::PathBuf> {
export::export_archive(&self.config, archive_id, format, output)
}
pub fn create_ai_packs(
&self,
archive_id: &str,
max_tokens: Option<usize>,
) -> Result<Vec<std::path::PathBuf>> {
export::create_ai_packs(&self.config, archive_id, max_tokens)
}
pub fn verify(&self, archive_id: &str) -> Result<Vec<String>> {
archive::verify_archive(&self.config, archive_id)
}
}
impl Default for Siteforge {
fn default() -> Self {
Self::new(Config::default())
}
}
impl From<Config> for Siteforge {
fn from(config: Config) -> Self {
Self::new(config)
}
}