88 lines
2.6 KiB
Python
88 lines
2.6 KiB
Python
|
|
#!/usr/bin/env python3
|
||
|
|
"""
|
||
|
|
Clean up LiveSync database - removes orphaned docs and fixes corruption
|
||
|
|
"""
|
||
|
|
import couchdb
|
||
|
|
import time
|
||
|
|
from urllib.parse import quote
|
||
|
|
|
||
|
|
USER = "admin"
|
||
|
|
PASSWORD = "DonCucarach0!?"
|
||
|
|
IP_ADDRESS = "100.100.112.48"
|
||
|
|
PORT = "5984"
|
||
|
|
DB_NAME = "obsidiandb"
|
||
|
|
|
||
|
|
def cleanup_db():
|
||
|
|
safe_password = quote(PASSWORD, safe="")
|
||
|
|
safe_username = quote(USER, safe="")
|
||
|
|
url = f"http://{safe_username}:{safe_password}@{IP_ADDRESS}:{PORT}/"
|
||
|
|
|
||
|
|
server = couchdb.Server(url)
|
||
|
|
db = server[DB_NAME]
|
||
|
|
|
||
|
|
print("Scanning for issues...")
|
||
|
|
|
||
|
|
files_to_fix = []
|
||
|
|
|
||
|
|
# Find all file metadata docs
|
||
|
|
for row in db.view('_all_docs', include_docs=True):
|
||
|
|
doc = row.doc
|
||
|
|
|
||
|
|
# Skip non-file docs
|
||
|
|
if 'children' not in doc:
|
||
|
|
continue
|
||
|
|
|
||
|
|
# Check if missing required LiveSync fields
|
||
|
|
missing_fields = []
|
||
|
|
if 'type' not in doc:
|
||
|
|
missing_fields.append('type')
|
||
|
|
if 'size' not in doc:
|
||
|
|
missing_fields.append('size')
|
||
|
|
if 'ctime' not in doc:
|
||
|
|
missing_fields.append('ctime')
|
||
|
|
if 'eden' not in doc:
|
||
|
|
missing_fields.append('eden')
|
||
|
|
|
||
|
|
if missing_fields:
|
||
|
|
files_to_fix.append((doc['_id'], doc, missing_fields))
|
||
|
|
print(f"❌ {doc.get('path', doc['_id'])}: missing {missing_fields}")
|
||
|
|
|
||
|
|
if not files_to_fix:
|
||
|
|
print("\n✅ No issues found!")
|
||
|
|
return
|
||
|
|
|
||
|
|
print(f"\nFound {len(files_to_fix)} files to fix")
|
||
|
|
print("Fixing...")
|
||
|
|
|
||
|
|
for doc_id, doc, missing in files_to_fix:
|
||
|
|
# Add missing fields with sensible defaults
|
||
|
|
if 'type' in missing:
|
||
|
|
doc['type'] = 'plain'
|
||
|
|
if 'size' in missing:
|
||
|
|
# Calculate size from chunks
|
||
|
|
doc['size'] = 0
|
||
|
|
for chunk_id in doc.get('children', []):
|
||
|
|
if chunk_id in db:
|
||
|
|
chunk = db[chunk_id]
|
||
|
|
data = chunk.get('data', chunk.get('content', ''))
|
||
|
|
doc['size'] += len(str(data))
|
||
|
|
if 'ctime' in missing:
|
||
|
|
doc['ctime'] = doc.get('mtime', int(time.time() * 1000))
|
||
|
|
if 'eden' in missing:
|
||
|
|
doc['eden'] = {}
|
||
|
|
|
||
|
|
# Update mtime to trigger sync
|
||
|
|
doc['mtime'] = int(time.time() * 1000)
|
||
|
|
|
||
|
|
try:
|
||
|
|
db.save(doc)
|
||
|
|
print(f"✓ Fixed: {doc.get('path', doc_id)}")
|
||
|
|
except Exception as e:
|
||
|
|
print(f"✗ Failed to fix {doc_id}: {e}")
|
||
|
|
|
||
|
|
print("\n✅ Cleanup complete!")
|
||
|
|
print("Now run force_sync.py to trigger Obsidian re-sync")
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
cleanup_db()
|