Skip to content

himanshu-jadhav108/ResultOps

Repository files navigation

ResultOps Logo



ResultOps πŸŽ“

University-grade result processing platform β€” built for SPPU affiliated colleges

Python Streamlit Firebase Live App CI


Parse Β· Validate Β· Analyse Β· Export β€” all in one platform.


πŸš€ Key Features

Feature Description
πŸ“„ Automated PDF Parsing Extracts structured student data from text-based university ledger PDFs using pdfplumber
πŸ” Dynamic Metadata Detection Auto-detects university, college, department, session, and semester β€” zero hardcoding
🧬 Dynamic Subject Detection Subject codes detected at runtime β€” works for any department, any semester
🚫 Duplicate Protection Prevents re-upload of the same semester using a composite key check
βœ… Pre-save Validation Validates SGPA consistency, PRN format, and subject counts before saving
πŸ“Š Analytics Dashboard Pass/fail stats, SGPA distribution, subject-wise analytics, ranked student lists, and subject difficulty scoring
πŸ“₯ Selective Excel Export Choose which sheets to include β€” Summary, Rank List, Subject Analytics, SGPA Distribution
πŸ“‹ History Management View, audit, and admin-delete previously uploaded semesters
πŸ”₯ Firebase Backend Google Firebase Firestore β€” reliable, fast, reachable from any network
🎨 Dark / Light Theme Toggle between dark navy and clean white theme with a single click
πŸ” 3-Tier Authentication Separate READ, WRITE, and ADMIN passwords with admin-only features
πŸ“ˆ Semester Comparison Compare multiple semesters side-by-side with trend analysis
πŸ“š Subject Difficulty Weighted difficulty scoring: (Fail% Γ— 0.6) + ((100 βˆ’ AvgMarks) Γ— 0.4)

πŸ—‚οΈ Project Structure

ResultOps/
β”œβ”€β”€ app.py                          # Streamlit entry point β€” routing, theme, auth, sidebar
β”œβ”€β”€ logo.png                        # App logo (sidebar + README)
β”œβ”€β”€ setup.cfg                       # Tool configuration (flake8, mypy, pytest)
β”œβ”€β”€ requirements.txt                # Production dependencies
β”œβ”€β”€ requirements-dev.txt            # Dev dependencies (testing, linting, security)
β”œβ”€β”€ .env.example                    # Environment variable template
β”‚
β”œβ”€β”€ parser/                         # PDF extraction & parsing pipeline
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ pdf_parser.py               # Raw text extraction via pdfplumber
β”‚   β”œβ”€β”€ metadata_extractor.py       # University, college, department, session detection
β”‚   β”œβ”€β”€ student_parser.py           # Student block splitting + subject line parsing
β”‚   └── refactored_parser.py        # Unified pipeline β€” orchestrates metadata + students + confidence
β”‚
β”œβ”€β”€ database/
β”‚   β”œβ”€β”€ __init__.py
β”‚   └── db.py                       # Firebase Admin SDK client (Streamlit secrets + .env fallback)
β”‚
β”œβ”€β”€ analytics/
β”‚   β”œβ”€β”€ __init__.py
β”‚   └── analytics.py                # Queries, ranking, comparison, difficulty, SGPA distribution
β”‚
β”œβ”€β”€ services/
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ result_service.py           # Firestore writes, batch inserts, duplicate guard
β”‚   └── excel_export.py             # Styled multi-sheet Excel workbook generator
β”‚
β”œβ”€β”€ views/                          # Streamlit page views
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ upload_page.py              # PDF upload, parse preview, validation, save, inline Excel export
β”‚   β”œβ”€β”€ analytics_page.py           # Dashboard β€” charts, tables, view toggle, selective Excel download
β”‚   β”œβ”€β”€ history_page.py             # Upload history + admin-only delete
β”‚   └── system_stats.py             # System statistics (admin-only)
β”‚
β”œβ”€β”€ utils/
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ theme.py                    # Dark/light theme manager with full CSS injection
β”‚   β”œβ”€β”€ auth.py                     # 3-tier authentication (READ / WRITE / ADMIN)
β”‚   └── validators.py               # Pre-save data validation (SGPA, PRN, subjects)
β”‚
β”œβ”€β”€ test/
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ test_parser.py              # Unit + integration tests for parser and ranking
β”‚   └── test_connection.py          # Firebase connectivity check script
β”‚
β”œβ”€β”€ .github/workflows/
β”‚   └── ci.yml                      # GitHub Actions CI β€” black, flake8, mypy, pytest, bandit
β”‚
β”œβ”€β”€ .streamlit/
β”‚   └── config.toml                 # Streamlit server configuration
β”‚
β”œβ”€β”€ docs/
β”‚   β”œβ”€β”€ hosting.md                  # Step-by-step Streamlit Cloud deployment guide
β”‚   └── github_actions.md           # GitHub Actions CI/CD setup guide
β”‚
└── hash_password/                  # Utility to generate SHA-256 password hashes

πŸ—οΈ System Architecture

flowchart TD
    classDef user      fill:#1a4a8a,stroke:#2d8cff,stroke-width:2px,color:#e8f0fe
    classDef parser    fill:#7c4a00,stroke:#f5a623,stroke-width:2px,color:#fff8ee
    classDef validate  fill:#7a0022,stroke:#ff4d6d,stroke-width:2px,color:#ffe8ec
    classDef firebase  fill:#004d2e,stroke:#00d97e,stroke-width:2px,color:#e0fff4
    classDef analytics fill:#3b1f7a,stroke:#a78bfa,stroke-width:2px,color:#f0ebff
    classDef export    fill:#004a4a,stroke:#06d6c7,stroke-width:2px,color:#e0fffe
    classDef decision  fill:#1a3a1a,stroke:#00d97e,stroke-width:2px,color:#e0fff4

    subgraph USER["πŸ‘€  USER LAYER"]
        direction LR
        A["πŸ‘€ Faculty / Admin"]
        B["πŸ–₯️ Streamlit Web App<br/>app.py Β· Port 8501"]
    end

    subgraph PAGES["πŸ“‘  PAGE VIEWS"]
        direction LR
        P1["πŸ“€ Upload Page<br/>upload_page.py"]
        P2["πŸ“Š Analytics Page<br/>analytics_page.py"]
        P3["πŸ“‹ History Page<br/>history_page.py"]
        P4["βš™οΈ System Stats<br/>system_stats.py"]
    end

    subgraph PARSE["πŸ“„  PDF PROCESSING LAYER"]
        direction LR
        C["πŸ“„ PDF Parser<br/>pdf_parser.py<br/>pdfplumber text extraction"]
        D["πŸ” Metadata Extractor<br/>metadata_extractor.py<br/>University Β· College Β· Dept Β· Sem"]
        E["πŸ‘₯ Student Parser<br/>student_parser.py<br/>PRN Β· SGPA Β· Subjects"]
        F["πŸ”— Unified Pipeline<br/>refactored_parser.py<br/>Orchestrator + Confidence Score"]
    end

    subgraph AUTH["πŸ”  AUTH + VALIDATION"]
        direction LR
        G["πŸ” 3-Tier Auth<br/>auth.py<br/>READ Β· WRITE Β· ADMIN"]
        H["πŸ§ͺ Data Validator<br/>validators.py"]
        I{"🚫 Duplicate Guard<br/>Semester Key Check"}
    end

    subgraph FIRE["πŸ”₯  FIREBASE FIRESTORE"]
        direction LR
        J["πŸ”₯ Firebase SDK<br/>db.py"]
        K["πŸ“ semesters<br/>collection"]
        L["πŸ“‹ results<br/>collection"]
    end

    subgraph OUT["πŸ“Š  ANALYTICS + EXPORT"]
        direction LR
        M["πŸ“Š Analytics Engine<br/>analytics.py<br/>Ranking Β· Comparison Β· Difficulty"]
        N["πŸ“₯ Excel Export<br/>excel_export.py<br/>Selective Β· Styled Β· Multi-sheet"]
        O["⬇️ Browser Download<br/>.xlsx"]
    end

    A -->|"Login"| G
    G -->|"Authenticated"| B
    B --> P1 & P2 & P3 & P4

    P1 -->|"Upload PDF"| C
    C -->|"Raw text"| F
    F --> D & E
    D -->|"PDFMetadata"| F
    E -->|"StudentRecord list"| F

    F -->|"Parsed data"| H
    H -->|"Validated"| I
    I -->|"❌ Exists"| P1
    I -->|"βœ… New"| J

    J -->|"batch write"| K
    J -->|"batch write Γ— N"| L

    P2 -->|"Query"| M
    L -->|"docs"| M
    K -.-|"metadata"| M
    M -->|"DataFrames"| P2
    M --> N
    N --> O

    P3 -->|"List/Delete"| J
    P4 -->|"Stats"| J

    class A,B user
    class P1,P2,P3,P4 user
    class C,D,E,F parser
    class G,H validate
    class I decision
    class J,K,L firebase
    class M analytics
    class N,O export
Loading

Upload Data Flow:

PDF Upload β†’ Text Extract β†’ Metadata Detect β†’ Student Parse β†’ Confidence Score
    β†’ Validate β†’ Duplicate Check β†’ Firestore Write β†’ Excel Export

Firestore Collections:

Collection Doc ID Contents
semesters University|College|Dept|Sem|Session|Year Metadata + student count
results Auto-generated PRN, SGPA, Status, subjects[] nested array

πŸ” Security & Authentication

ResultOps uses 3-tier password authentication, all hashed with SHA-256:

Tier Access Level Features
🟒 READ View-only analytics Dashboard, analytics, history (view only)
🟑 WRITE Upload & save data Upload PDF, parse, save to database
πŸ”΄ ADMIN Full control System Stats, delete records from History

Setting Up Passwords

  1. Generate SHA-256 hashes for your passwords:

    python -c "import hashlib; print(hashlib.sha256('your_password'.encode()).hexdigest())"
  2. Add hashes to .env:

    READ_PASSWORD_HASH=<sha256_hash_of_read_password>
    WRITE_PASSWORD_HASH=<sha256_hash_of_write_password>
    ADMIN_PASSWORD_HASH=<sha256_hash_of_admin_password>

Current Defaults (.env.example)

Role Default Password
READ password
WRITE password
ADMIN password

⚠️ Change these immediately after first setup.


πŸ› οΈ Setup Instructions

1. Clone & Install

git clone https://github.com/himanshu-jadhav108/ResultOps.git
cd ResultOps
python -m venv venv
# Windows
venv\Scripts\activate
# macOS/Linux
source venv/bin/activate

pip install -r requirements.txt

2. Create Firebase Project

  1. Go to console.firebase.google.com
  2. Add Project β†’ name it ResultOps β†’ disable Analytics β†’ Create Project

3. Enable Firestore

  1. Build β†’ Firestore Database β†’ Create Database
  2. Choose Start in test mode β†’ Region: asia-south1 (Mumbai) β†’ Enable

4. Download Service Account Key

  1. βš™οΈ gear icon β†’ Project Settings β†’ Service Accounts
  2. Generate new private key β†’ Generate Key
  3. Rename to firebase_key.json β†’ place in project root

⚠️ Never commit firebase_key.json to GitHub. Already in .gitignore.

5. Configure Environment

cp .env.example .env

Edit .env with your password hashes:

FIREBASE_KEY_PATH=firebase_key.json
READ_PASSWORD_HASH=<your_read_hash>
WRITE_PASSWORD_HASH=<your_write_hash>
ADMIN_PASSWORD_HASH=<your_admin_hash>

6. Run the App

streamlit run app.py

Open http://localhost:8501


🎨 Theme System

ResultOps has a built-in dark/light theme toggle:

Theme Background Sidebar Text
πŸŒ™ Dark Navy #060e1f Gradient navyβ†’blue White #e8f0fe
β˜€οΈ Light Soft grey #f4f7fb Same dark gradient Dark #0f1e3a

Toggle via the sidebar button β€” all elements are fully styled for both themes.


πŸ“Š Analytics Dashboard Features

Feature Description
πŸ“ˆ Semester Overview 6 key metrics: students, avg SGPA, highest, distinctions, pass count/%
πŸ“‰ SGPA Distribution Bar chart + table with percentage breakdown
πŸ† Student Rankings Top 10 highlighted list, full rank list in expander, fail list
πŸ“š Subject Analytics Pass %, average marks, highest/lowest per subject with color-coded table
πŸ‘οΈ View Mode Toggle Switch between Charts Only / Tables Only / Both β€” fully reversible
⬇️ Selective Excel Download Choose sheets: Summary, Rank List, Subject Analytics, SGPA Distribution

πŸ“„ PDF Requirements

Requires text-based (not scanned) SPPU ledger PDFs. Structure:

PRN: XXXXX  SEAT NO.: YYY  NAME: Student Name
SEMESTER: 5

410241  45  18  20  --  83  4  O  10  40
...

Winter Session 2025 SGPA : 8.50  Credits Earned/Total : 24/24
SGPA: (SEM-5) 8.50

Quick check: Open PDF in Adobe Reader β†’ try to select/copy text. If it works, ResultOps can parse it.


πŸ”’ Environment Variables

Variable Description
FIREBASE_KEY_PATH Path to Firebase service account JSON key
READ_PASSWORD_HASH SHA-256 hash for read-only access
WRITE_PASSWORD_HASH SHA-256 hash for upload/write access
ADMIN_PASSWORD_HASH SHA-256 hash for admin access (stats, delete)

πŸ§ͺ CI/CD Pipeline

The GitHub Actions CI pipeline runs on every push to main and develop:

Step Tool What it checks
Formatting black --check . Code style consistency
Lint (strict) flake8 --select=E9,F63,F7,F82 Syntax errors, undefined names
Lint (warnings) flake8 --exit-zero Line length, complexity (non-blocking)
Type Check mypy Type annotations in parser/, utils/, analytics/
Tests pytest test/ -v 12 unit + integration tests
Security bandit -ll Common security vulnerabilities

⚑ Performance

Operation Target
Parse 100 students from PDF < 5 seconds
Firestore batch write (100 students) < 3 seconds
Analytics query < 1 second

πŸ”§ Troubleshooting

Error Fix
FileNotFoundError: firebase_key.json Place key file in project root
Invalid service account certificate Re-download key from Firebase Console
TransportError / network failure Check internet, switch to mobile hotspot
PermissionDenied Set Firestore rules to test mode
0 students detected PDF must be text-based, not scanned
Semester not detected PDF must contain SEMESTER: N pattern
Sidebar shows raw HTML Run pip install --upgrade streamlit
Light theme text invisible Clear browser cache, hard refresh (Ctrl+Shift+R)

πŸ“š Additional Documentation

Document Description
hosting.md Step-by-step guide to deploy on Streamlit Cloud
github_actions.md GitHub Actions CI/CD pipeline setup

πŸ›‘οΈ Security Notes

  • Firebase key used server-side only via firebase-admin SDK
  • firebase_key.json in .gitignore β€” never committed to version control
  • All passwords stored as SHA-256 hashes β€” no plaintext anywhere
  • Admin password gates destructive operations (delete, system stats)
  • Firestore in test mode for dev β€” restrict rules before going to production

πŸ‘¨β€πŸ’» About the Maintainer

Himanshu Jadhav Second-Year Engineering Student β€” AI & Data Science


GitHub LinkedIn Instagram Portfolio


Built with ❀️ for Savitribai Phule Pune University affiliated colleges


Β© 2025 Himanshu Jadhav Β· ResultOps v2.0 Β· Firebase Edition

About

ResultOps is a robust, university-grade result processing platform built using Streamlit and Firebase Firestore. The application is designed to streamline transcript parsing, validation, storage, and analysis for academic institutions.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages