Files
antigravity-skills-reference/web-app/public/skills/notebooklm/scripts/cleanup_manager.py

302 lines
9.5 KiB
Python

#!/usr/bin/env python3
"""
Cleanup Manager for NotebookLM Skill
Manages cleanup of skill data and browser state
"""
import shutil
import argparse
from pathlib import Path
from typing import Dict, List, Any
class CleanupManager:
"""
Manages cleanup of NotebookLM skill data
Features:
- Preview what will be deleted
- Selective cleanup options
- Library preservation
- Safe deletion with confirmation
"""
def __init__(self):
"""Initialize the cleanup manager"""
# Skill directory paths
self.skill_dir = Path(__file__).parent.parent
self.data_dir = self.skill_dir / "data"
def get_cleanup_paths(self, preserve_library: bool = False) -> Dict[str, Any]:
"""
Get paths that would be cleaned up
Args:
preserve_library: Keep library.json if True
Returns:
Dict with paths and sizes
Note: .venv is NEVER deleted - it's part of the skill infrastructure
"""
paths = {
'browser_state': [],
'sessions': [],
'library': [],
'auth': [],
'other': []
}
total_size = 0
if self.data_dir.exists():
# Browser state
browser_state_dir = self.data_dir / "browser_state"
if browser_state_dir.exists():
for item in browser_state_dir.iterdir():
size = self._get_size(item)
paths['browser_state'].append({
'path': str(item),
'size': size,
'type': 'dir' if item.is_dir() else 'file'
})
total_size += size
# Sessions
sessions_file = self.data_dir / "sessions.json"
if sessions_file.exists():
size = sessions_file.stat().st_size
paths['sessions'].append({
'path': str(sessions_file),
'size': size,
'type': 'file'
})
total_size += size
# Library (unless preserved)
if not preserve_library:
library_file = self.data_dir / "library.json"
if library_file.exists():
size = library_file.stat().st_size
paths['library'].append({
'path': str(library_file),
'size': size,
'type': 'file'
})
total_size += size
# Auth info
auth_info = self.data_dir / "auth_info.json"
if auth_info.exists():
size = auth_info.stat().st_size
paths['auth'].append({
'path': str(auth_info),
'size': size,
'type': 'file'
})
total_size += size
# Other files in data dir (but NEVER .venv!)
for item in self.data_dir.iterdir():
if item.name not in ['browser_state', 'sessions.json', 'library.json', 'auth_info.json']:
size = self._get_size(item)
paths['other'].append({
'path': str(item),
'size': size,
'type': 'dir' if item.is_dir() else 'file'
})
total_size += size
return {
'categories': paths,
'total_size': total_size,
'total_items': sum(len(items) for items in paths.values())
}
def _get_size(self, path: Path) -> int:
"""Get size of file or directory in bytes"""
if path.is_file():
return path.stat().st_size
elif path.is_dir():
total = 0
try:
for item in path.rglob('*'):
if item.is_file():
total += item.stat().st_size
except Exception:
pass
return total
return 0
def _format_size(self, size: int) -> str:
"""Format size in human-readable form"""
for unit in ['B', 'KB', 'MB', 'GB']:
if size < 1024:
return f"{size:.1f} {unit}"
size /= 1024
return f"{size:.1f} TB"
def perform_cleanup(
self,
preserve_library: bool = False,
dry_run: bool = False
) -> Dict[str, Any]:
"""
Perform the actual cleanup
Args:
preserve_library: Keep library.json if True
dry_run: Preview only, don't delete
Returns:
Dict with cleanup results
"""
cleanup_data = self.get_cleanup_paths(preserve_library)
deleted_items = []
failed_items = []
deleted_size = 0
if dry_run:
return {
'dry_run': True,
'would_delete': cleanup_data['total_items'],
'would_free': cleanup_data['total_size']
}
# Perform deletion
for category, items in cleanup_data['categories'].items():
for item_info in items:
path = Path(item_info['path'])
try:
if path.exists():
if path.is_dir():
shutil.rmtree(path)
else:
path.unlink()
deleted_items.append(str(path))
deleted_size += item_info['size']
print(f" ✅ Deleted: {path.name}")
except Exception as e:
failed_items.append({
'path': str(path),
'error': str(e)
})
print(f" ❌ Failed: {path.name} ({e})")
# Recreate browser_state dir if everything was deleted
if not preserve_library and not failed_items:
browser_state_dir = self.data_dir / "browser_state"
browser_state_dir.mkdir(parents=True, exist_ok=True)
return {
'deleted_items': deleted_items,
'failed_items': failed_items,
'deleted_size': deleted_size,
'deleted_count': len(deleted_items),
'failed_count': len(failed_items)
}
def print_cleanup_preview(self, preserve_library: bool = False):
"""Print a preview of what will be cleaned"""
data = self.get_cleanup_paths(preserve_library)
print("\n🔍 Cleanup Preview")
print("=" * 60)
for category, items in data['categories'].items():
if items:
print(f"\n📁 {category.replace('_', ' ').title()}:")
for item in items:
path = Path(item['path'])
size_str = self._format_size(item['size'])
type_icon = "📂" if item['type'] == 'dir' else "📄"
print(f" {type_icon} {path.name:<30} {size_str:>10}")
print("\n" + "=" * 60)
print(f"Total items: {data['total_items']}")
print(f"Total size: {self._format_size(data['total_size'])}")
if preserve_library:
print("\n📚 Library will be preserved")
print("\nThis preview shows what would be deleted.")
print("Use --confirm to actually perform the cleanup.")
def main():
"""Command-line interface for cleanup management"""
parser = argparse.ArgumentParser(
description='Clean up NotebookLM skill data',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
# Preview what will be deleted
python cleanup_manager.py
# Perform cleanup (delete everything)
python cleanup_manager.py --confirm
# Cleanup but keep library
python cleanup_manager.py --confirm --preserve-library
# Force cleanup without preview
python cleanup_manager.py --confirm --force
"""
)
parser.add_argument(
'--confirm',
action='store_true',
help='Actually perform the cleanup (without this, only preview)'
)
parser.add_argument(
'--preserve-library',
action='store_true',
help='Keep the notebook library (library.json)'
)
parser.add_argument(
'--force',
action='store_true',
help='Skip confirmation prompt'
)
args = parser.parse_args()
# Initialize manager
manager = CleanupManager()
if args.confirm:
# Show preview first unless forced
if not args.force:
manager.print_cleanup_preview(args.preserve_library)
print("\n⚠️ WARNING: This will delete the files shown above!")
print(" Note: .venv is preserved (part of skill infrastructure)")
response = input("Are you sure? (yes/no): ")
if response.lower() != 'yes':
print("Cleanup cancelled.")
return
# Perform cleanup
print("\n🗑️ Performing cleanup...")
result = manager.perform_cleanup(args.preserve_library, dry_run=False)
print(f"\n✅ Cleanup complete!")
print(f" Deleted: {result['deleted_count']} items")
print(f" Freed: {manager._format_size(result['deleted_size'])}")
if result['failed_count'] > 0:
print(f" ⚠️ Failed: {result['failed_count']} items")
else:
# Just show preview
manager.print_cleanup_preview(args.preserve_library)
print("\n💡 Note: Virtual environment (.venv) is never deleted")
print(" It's part of the skill infrastructure, not user data")
if __name__ == "__main__":
main()