@@ -1499,6 +1499,67 @@ async def toggle_plugin(request: Request, plugin_name: str, enabled: dict):
14991499 raise HTTPException (status_code = 500 , detail = safe_error_message (e , "Failed to toggle plugin" ))
15001500
15011501
1502+ # ============================================================================
1503+ # Stats Endpoint (for dashboards)
1504+ # ============================================================================
1505+
1506+ @api_router .get ("/stats" , tags = ["Stats" ])
1507+ @limiter .limit ("30/minute" )
1508+ async def get_stats (request : Request ):
1509+ """
1510+ Get application statistics at a glance.
1511+
1512+ Designed for dashboard widgets (e.g., Homepage) - lightweight and cached.
1513+ Returns counts of notes, folders, tags, templates, media, and other metadata.
1514+ """
1515+ try :
1516+ notes_dir = config ['storage' ]['notes_dir' ]
1517+
1518+ # Get notes and folders (cached)
1519+ notes , folders = scan_notes_fast_walk (notes_dir , include_media = True )
1520+
1521+ # Separate notes from media
1522+ note_items = [n for n in notes if n .get ('type' ) == 'note' ]
1523+ media_items = [n for n in notes if n .get ('type' ) != 'note' ]
1524+
1525+ # Count unique tags
1526+ all_tags = set ()
1527+ for note in note_items :
1528+ all_tags .update (note .get ('tags' , []))
1529+
1530+ # Get templates count
1531+ templates = get_templates (notes_dir )
1532+
1533+ # Calculate total size
1534+ total_size = sum (n .get ('size' , 0 ) for n in notes )
1535+
1536+ # Get last modified (notes are already sorted by modified desc)
1537+ last_modified = note_items [0 ].get ('modified' ) if note_items else None
1538+
1539+ # Count enabled plugins
1540+ enabled_plugins = sum (1 for p in plugin_manager .plugins .values () if p .enabled )
1541+
1542+ # Read version
1543+ version = "unknown"
1544+ version_file = Path (__file__ ).parent .parent / "VERSION"
1545+ if version_file .exists ():
1546+ version = version_file .read_text ().strip ()
1547+
1548+ return {
1549+ "notes_count" : len (note_items ),
1550+ "folders_count" : len (folders ),
1551+ "tags_count" : len (all_tags ),
1552+ "templates_count" : len (templates ),
1553+ "media_count" : len (media_items ),
1554+ "total_size_bytes" : total_size ,
1555+ "last_modified" : last_modified ,
1556+ "plugins_enabled" : enabled_plugins ,
1557+ "version" : version
1558+ }
1559+ except Exception as e :
1560+ raise HTTPException (status_code = 500 , detail = safe_error_message (e , "Failed to get stats" ))
1561+
1562+
15021563# ============================================================================
15031564# Share Token Endpoints (authenticated)
15041565# ============================================================================
0 commit comments