- Fixed 104 broken references in 59 files - Consolidated 40+ duplicate status files - Archived duplicates to reports/archive/duplicates/ - Created scripts for reference fixing and consolidation - Updated content inconsistency reports All optional cleanup tasks complete.
200 lines
6.4 KiB
Python
Executable File
200 lines
6.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Fix Broken References Script
|
|
Automatically fixes broken markdown links based on file moves during cleanup
|
|
"""
|
|
|
|
import re
|
|
import json
|
|
from pathlib import Path
|
|
from collections import defaultdict
|
|
|
|
# Mapping of old paths to new paths (from cleanup)
|
|
PATH_MAPPINGS = {
|
|
# Root → reports/status/
|
|
r'^BESU_.*\.md$': 'reports/status/',
|
|
r'^FIREFLY_.*\.md$': 'reports/status/',
|
|
r'^DBIS_.*\.md$': 'reports/status/',
|
|
r'^.*STATUS.*\.md$': 'reports/status/',
|
|
r'^.*COMPLETE.*\.md$': 'reports/status/',
|
|
r'^.*FINAL.*\.md$': 'reports/status/',
|
|
r'^.*REPORT.*\.md$': 'reports/status/',
|
|
|
|
# Root → reports/analyses/
|
|
r'^.*ANALYSIS.*\.md$': 'reports/analyses/',
|
|
r'^IP_CONFLICT.*\.md$': 'reports/analyses/',
|
|
r'^PHASE1_IP.*\.md$': 'reports/analyses/',
|
|
|
|
# Root → docs/
|
|
r'^CLOUDFLARE_API_SETUP\.md$': 'docs/04-configuration/',
|
|
r'^CLOUDFLARE_TUNNEL.*\.md$': 'docs/04-configuration/',
|
|
r'^SETUP_TUNNEL.*\.md$': 'docs/04-configuration/',
|
|
r'^TUNNEL.*\.md$': 'docs/04-configuration/',
|
|
r'^NGINX_CONFIGURATIONS.*\.md$': 'docs/04-configuration/',
|
|
r'^NO_SSH_ACCESS.*\.md$': 'docs/09-troubleshooting/',
|
|
r'^TROUBLESHOOT.*\.md$': 'docs/09-troubleshooting/',
|
|
r'^FIX_TUNNEL.*\.md$': 'docs/09-troubleshooting/',
|
|
r'^R630-04.*\.md$': 'docs/09-troubleshooting/',
|
|
r'^LIST_VMS.*\.md$': 'docs/01-getting-started/',
|
|
r'^THIRDWEB_RPC.*\.md$': 'docs/01-getting-started/',
|
|
r'^CHAIN138_TOKEN.*\.md$': 'docs/11-references/',
|
|
r'^OMADA.*\.md$': 'docs/11-references/',
|
|
r'^GET_EMAIL.*\.md$': 'docs/11-references/',
|
|
|
|
# Specific file mappings
|
|
'docs/ENV_STANDARDIZATION.md': 'docs/04-configuration/ENV_STANDARDIZATION.md',
|
|
'docs/MCP_SETUP.md': 'docs/04-configuration/MCP_SETUP.md',
|
|
'MCP_SETUP.md': 'docs/04-configuration/MCP_SETUP.md',
|
|
}
|
|
|
|
# Exclude submodules from fixing
|
|
EXCLUDE_PATHS = [
|
|
'ProxmoxVE/',
|
|
'smom-dbis-138/',
|
|
'explorer-monorepo/',
|
|
'metamask-integration/',
|
|
'metaverseDubai/',
|
|
'miracles_in_motion/',
|
|
'dbis_core/',
|
|
'gru-docs/',
|
|
'node_modules/',
|
|
'.git/',
|
|
]
|
|
|
|
def should_process_file(file_path):
|
|
"""Check if file should be processed"""
|
|
path_str = str(file_path)
|
|
# Don't process submodules
|
|
if any(exclude in path_str for exclude in EXCLUDE_PATHS):
|
|
return False
|
|
# Only process files in our main project
|
|
return True
|
|
|
|
def find_file_in_new_location(filename):
|
|
"""Find where a file was moved to"""
|
|
# Check reports/status/
|
|
if Path(f'reports/status/{filename}').exists():
|
|
return f'reports/status/{filename}'
|
|
|
|
# Check reports/analyses/
|
|
if Path(f'reports/analyses/{filename}').exists():
|
|
return f'reports/analyses/{filename}'
|
|
|
|
# Check reports/
|
|
if Path(f'reports/{filename}').exists():
|
|
return f'reports/{filename}'
|
|
|
|
# Check docs subdirectories
|
|
for subdir in ['01-getting-started', '04-configuration', '09-troubleshooting', '11-references']:
|
|
if Path(f'docs/{subdir}/{filename}').exists():
|
|
return f'docs/{subdir}/{filename}'
|
|
|
|
return None
|
|
|
|
def fix_references_in_file(file_path):
|
|
"""Fix broken references in a single file"""
|
|
try:
|
|
with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
|
|
content = f.read()
|
|
|
|
original_content = content
|
|
changes = []
|
|
|
|
# Pattern for markdown links: [text](path)
|
|
link_pattern = r'\[([^\]]+)\]\(([^)]+)\)'
|
|
|
|
def replace_link(match):
|
|
link_text = match.group(1)
|
|
link_path = match.group(2)
|
|
|
|
# Skip external links
|
|
if link_path.startswith('http'):
|
|
return match.group(0)
|
|
|
|
# Skip anchors only
|
|
if link_path.startswith('#'):
|
|
return match.group(0)
|
|
|
|
# Extract filename
|
|
if '#' in link_path:
|
|
file_part, anchor = link_path.split('#', 1)
|
|
anchor_part = '#' + anchor
|
|
else:
|
|
file_part = link_path
|
|
anchor_part = ''
|
|
|
|
filename = Path(file_part).name
|
|
|
|
# Try to find file in new location
|
|
new_location = find_file_in_new_location(filename)
|
|
|
|
if new_location:
|
|
# Calculate relative path
|
|
current_dir = file_path.parent
|
|
new_path = Path(new_location)
|
|
try:
|
|
relative_path = new_path.relative_to(current_dir)
|
|
new_link = f'[{link_text}]({relative_path}{anchor_part})'
|
|
changes.append(f" Fixed: {link_path} → {relative_path}{anchor_part}")
|
|
return new_link
|
|
except ValueError:
|
|
# Paths don't share common ancestor, use absolute from root
|
|
new_link = f'[{link_text}](/{new_location}{anchor_part})'
|
|
changes.append(f" Fixed: {link_path} → /{new_location}{anchor_part}")
|
|
return new_link
|
|
|
|
return match.group(0)
|
|
|
|
content = re.sub(link_pattern, replace_link, content)
|
|
|
|
if content != original_content:
|
|
with open(file_path, 'w', encoding='utf-8') as f:
|
|
f.write(content)
|
|
return changes
|
|
|
|
return []
|
|
|
|
except Exception as e:
|
|
return [f" Error: {e}"]
|
|
|
|
def main():
|
|
"""Main function"""
|
|
root = Path('.')
|
|
fixed_count = 0
|
|
total_changes = []
|
|
|
|
print("🔧 Fixing broken references...")
|
|
print("")
|
|
|
|
# Process markdown files
|
|
for md_file in root.rglob('*.md'):
|
|
if not should_process_file(md_file):
|
|
continue
|
|
|
|
changes = fix_references_in_file(md_file)
|
|
if changes:
|
|
fixed_count += 1
|
|
print(f"✅ Fixed: {md_file}")
|
|
for change in changes:
|
|
print(change)
|
|
total_changes.extend([(str(md_file), c) for c in changes])
|
|
|
|
print("")
|
|
print(f"✅ Fixed references in {fixed_count} files")
|
|
print(f" Total changes: {len(total_changes)}")
|
|
|
|
# Save report
|
|
report = {
|
|
'files_fixed': fixed_count,
|
|
'total_changes': len(total_changes),
|
|
'changes': total_changes
|
|
}
|
|
|
|
with open('REFERENCE_FIXES_REPORT.json', 'w') as f:
|
|
json.dump(report, f, indent=2)
|
|
|
|
print("✅ Report saved: REFERENCE_FIXES_REPORT.json")
|
|
|
|
if __name__ == '__main__':
|
|
main()
|