import json,re,os,sqlite3
from pathlib import Path
B=Path('/opt/struktur/obsidian-graphiti-import'); cfg=json.loads((B/'config.json').read_text()); root=Path(cfg['vault']); deny=[x.lower() for x in cfg['deny_patterns']]; allow=set(cfg['allow_roots']); ext=set(x.lower() for x in cfg['extensions'])
counts={'denylist':0,'not-allowlisted':0,'content':0,'allowed':0,'errors':0}; multi=0; examples={}; total=0
for p in root.rglob('*'):
if not p.is_file(): continue
total+=1; rel=p.relative_to(root); s=str(rel).replace('\\','/').lower(); parts=rel.parts
flags={'extension_or_deny': p.suffix.lower() not in ext or any(x in s for x in deny),'root': (not allow or not parts or parts[0] not in allow),'content':False}
try: text=p.read_text(encoding='utf-8',errors='ignore'); flags['content']=len(text.strip())<cfg['min_chars'] or bool(re.search(r'(?im)^\s*(draft|private|no-graphiti|exclude-from-graphiti)\s*:\s*(true|yes)\b',text))
except Exception: counts['errors']+=1; continue
if sum(flags.values())>1: multi+=1
if flags['extension_or_deny']: reason='denylist'
elif flags['root']: reason='not-allowlisted'
elif flags['content']: reason='content'
else: reason='allowed'
counts[reason]+=1; examples.setdefault(reason,[]).append(str(rel))
print('CONFIG',json.dumps({'vault':cfg['vault'],'allow_roots':cfg['allow_roots'],'deny_patterns':cfg['deny_patterns'],'extensions':cfg['extensions'],'min_chars':cfg['min_chars'],'max_attempts':cfg['max_attempts']},ensure_ascii=False))
print('SNAPSHOT',json.dumps({'files_scanned':total,'first_reason_counts':counts,'multiple_conditions':multi,'examples':{k:v[:8] for k,v in examples.items()}},ensure_ascii=False))
# current latest importer run, read-only
c=sqlite3.connect('file:'+str(cfg['db'])+'?mode=ro',uri=True); c.row_factory=sqlite3.Row
print('LATEST_RUN',dict(c.execute('select * from runs order by id desc limit 1').fetchone()))
print('RUN_COUNT',c.execute('select count(*) from runs').fetchone()[0]); c.close()