Files
herolib/lib/data/atlas/atlas.v
Mahmoud-Emad 04e1e2375f refactor: Remove docusaurus dev server and path_meta flag
- Remove 'dev' flag from run command
- Remove 'path_meta' flag from run command
- Remove docusaurus integration from playcmds
- Add `validate_links` and `fix_links` to Atlas
- Refactor page link processing for clarity and export mode
2025-11-05 15:25:50 +02:00

164 lines
3.7 KiB
V

module atlas
import incubaid.herolib.core.texttools
import incubaid.herolib.core.pathlib
import incubaid.herolib.ui.console
import incubaid.herolib.data.paramsparser
@[heap]
pub struct Atlas {
pub mut:
name string
collections map[string]&Collection
groups map[string]&Group // name -> Group mapping
}
// Create a new collection
fn (mut self Atlas) add_collection(mut path pathlib.Path) !Collection {
mut name := path.name_fix_no_ext()
mut filepath := path.file_get('.collection')!
content := filepath.read()!
if content.trim_space() != '' {
mut params := paramsparser.parse(content)!
if params.exists('name') {
name = params.get('name')!
}
}
name = texttools.name_fix(name)
console.print_item("Adding collection '${name}' to Atlas '${self.name}' at path '${path.path}'")
if name in self.collections {
return error('Collection ${name} already exists in Atlas ${self.name}')
}
mut c := Collection{
name: name
path: path.path // absolute path
atlas: &self // Set atlas reference
error_cache: map[string]bool{}
}
c.init_pre()!
self.collections[name] = &c
return c
}
// Get a collection by name
pub fn (a Atlas) get_collection(name string) !&Collection {
return a.collections[name] or {
return CollectionNotFound{
name: name
msg: 'Collection not found in Atlas ${a.name}'
}
}
}
// Validate all links in all collections
pub fn (mut a Atlas) init_post() ! {
for _, mut col in a.collections {
col.init_post()!
}
}
// Validate all links in all collections
pub fn (mut a Atlas) validate_links() ! {
for _, mut col in a.collections {
col.validate_links()!
}
}
// Fix all links in all collections (rewrite source files)
pub fn (mut a Atlas) fix_links() ! {
for _, mut col in a.collections {
col.fix_links()!
}
}
// Add a group to the atlas
pub fn (mut a Atlas) group_add(mut group Group) ! {
if group.name in a.groups {
return error('Group ${group.name} already exists')
}
a.groups[group.name] = &group
}
// Get a group by name
pub fn (a Atlas) group_get(name string) !&Group {
name_lower := texttools.name_fix(name)
return a.groups[name_lower] or { return error('Group ${name} not found') }
}
// Get all groups matching a session's email
pub fn (a Atlas) groups_get(session Session) []&Group {
mut matching := []&Group{}
email_lower := session.email.to_lower()
for _, group in a.groups {
if group.matches(email_lower) {
matching << group
}
}
return matching
}
//////////////////SCAN
// Scan a path for collections
@[params]
pub struct ScanArgs {
pub mut:
path string @[required]
ignore []string // list of directory names to ignore
}
pub fn (mut a Atlas) scan(args ScanArgs) ! {
mut path := pathlib.get_dir(path: args.path)!
mut ignore := args.ignore.clone()
ignore = ignore.map(it.to_lower())
a.scan_(mut path, ignore)!
}
// Scan a directory for collections
fn (mut a Atlas) scan_(mut dir pathlib.Path, ignore_ []string) ! {
console.print_item('Scanning directory: ${dir.path}')
if !dir.is_dir() {
return error('Path is not a directory: ${dir.path}')
}
// Check if this directory is a collection
if dir.file_exists('.collection') {
collname := dir.name_fix_no_ext()
if collname.to_lower() in ignore_ {
return
}
mut col := a.add_collection(mut dir)!
if collname == 'groups' {
col.scan_groups()!
}
return
}
// Scan subdirectories
mut entries := dir.list(recursive: false)!
for mut entry in entries.paths {
if !entry.is_dir() || should_skip_dir(entry) {
continue
}
mut mutable_entry := entry
a.scan_(mut mutable_entry, ignore_)!
}
}
// Check if directory should be skipped
fn should_skip_dir(entry pathlib.Path) bool {
name := entry.name()
return name.starts_with('.') || name.starts_with('_')
}