Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

School Analytics

A personal learning diagnostic tool: ingests grades, assignments, calendar events, and Obsidian vault notes, then generates a local analytics dashboard.

Made for my own classes. It answers one question: am I actually learning this, or just writing it down?

Requires Python 3.7+. The core (grades, assignments, dashboard) uses only the standard library. The calendar command additionally needs the Google client libs (pip install -r requirements.txt). No other dependencies.

Features

  • Grade ingestion from Infinite Campus, either from an _Ingest.md note or piped via stdin
  • Assignment ingestion from Google Classroom
  • Calendar fetch/add via Google Calendar
  • Vault analysis over an Obsidian school vault: note counts, study materials, concept coverage, weak spots (classes with notes but no study), and cross-class concepts
  • Dashboard generation as a single self-contained HTML file with Chart.js visualizations
  • doctor command that checks your install and tells you what's missing

Usage

python analytics.py <command>
Command Description
setup First-run scaffold: creates config.json, the vault folders, and ingest templates
chat-ingest grades Pipe grade data via stdin and ingest
chat-ingest assignments Pipe assignment data via stdin and ingest
sync-vault Scan vault: notes, concepts, study gaps, cross-class links
calendar Fetch upcoming events (requires auth first run)
calendar-add 'Summary|2026-07-29T14:32:00|2026-07-29T15:00:00|[calendar]' Add a calendar event
build Generate the analytics dashboard
open Build the dashboard and open it in a browser
doctor Check the install: config, vault, data, calendar auth

Legacy ingest mode (reads from _Ingest.md instead of stdin):

python analytics.py ingest grades
python analytics.py ingest assignments

Layout

  • analytics.py — CLI entry point and dashboard renderer
  • sources/ — ingest modules:
    • infinite_campus.py — grade parsing
    • google_classroom.py — assignment parsing
    • calendar.py — Google Calendar read/write
    • vault.py — Obsidian vault analysis
  • dashboard/ — generated HTML output
  • data/ — JSON store (grades, assignments, calendar events, vault insights), created on first run
  • config.json — your local settings (gitignored)

Configuration

Copy config.example.json to config.json and set vault_path to your Obsidian vault root. Or skip the file and use export SCHOOL_VAULT=/path/to/vault or --vault <path> per run.

{
  "vault_path": "C:/Users/YOU/Path/To/Your/Obsidian/Vault",
  "timezone": "America/Denver"
}
  • timezone in config.json defaults to America/Denver; change it if you're elsewhere.
  • Calendar auth stores a local token.json on first run (kept out of git via .gitignore).

First run

The core (grades, assignments, dashboard) needs only Python stdlib. The calendar command additionally needs the Google client libs:

pip install -r requirements.txt

Then scaffold everything for zero setup:

python analytics.py setup

setup creates config.json (defaulting the vault to a local ./school_vault folder), the vault folder skeleton, a blank Course Registry.md, and a blank _Ingest.md. Nothing else to configure:

python analytics.py doctor
python analytics.py sync-vault
python analytics.py open

To use your real Obsidian vault instead of the local default, edit config.json and set vault_path to your vault root (or export SCHOOL_VAULT=/path/to/vault, or pass --vault <path> per run):

{
  "vault_path": "C:/Users/YOU/Path/To/Your/Obsidian/Vault",
  "timezone": "America/Denver"
}

Then run setup again to create the folders inside your real vault.

doctor prints a checklist of what's present and what's missing, so a broken setup fails loudly instead of silently.

The vault must use this exact folder layout (setup creates it for you):

<Vault>/
  01 Classes/<ClassName>/
    Notes/          # .md notes
    Study/          # .md study materials
  03 Museum/
  04 Meta/
    Analytics/
      _Ingest.md    # legacy ingest reads its tables from here
    Course Registry.md
  05 Tags/
  06 Concepts/

If the layout is wrong, sync-vault will print exactly which folders it looked for. Concept extraction reads a line like concepts: [x, y, z] from the top of each note.

Grades/assignments can be piped in without any vault setup:

echo "| class | assignment | score |" | python analytics.py chat-ingest grades

Calendar setup

The calendar commands talk to the Google Calendar API and need your own OAuth client:

  1. Go to Google Cloud Console, create a project, and enable the Google Calendar API.
  2. Under APIs & Services → Credentials, create an OAuth client ID of type Desktop app.
  3. Download the JSON and save it as client_secret.json in this folder.
  4. Run python analytics.py calendar. A browser window opens; authorize the app. A token.json is saved locally and reused from then on.

Both client_secret.json and token.json are gitignored. The redirect goes to http://127.0.0.1:42813/callback, so the OAuth client must allow that port.

Data safety

  • config.json, client_secret.json, token.json, and everything in data/ are gitignored. Your vault path and credentials never land in the repo.
  • Ingests dedupe by class + assignment: pasting the same table twice won't duplicate rows, and a re-ingest with a corrected score overwrites the old one.

About

No description or website provided.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages