Skip to main content

Automation assistant for attendance management.

Project description

Always Attend

An automation helper to submit weekly attendance codes. Now in Public Beta.
⚠️ Use responsibly and follow your institution’s policies.

中文文档

[!WARNING]
This project is currently in Public Beta. Features may change and bugs are expected.
Receive Feedback Here: Open Issue

📥 Download This Project

Choose one method to get the folder onto your computer:

Option 1 — Git (recommended)

git clone https://github.com/bunizao/always-attend.git
cd always-attend
  • Windows (PowerShell or Command Prompt):
git clone https://github.com/bunizao/always-attend.git
cd always-attend

Option 2 — Download ZIP (no Git needed)

After download

  • macOS: double‑click Always-Attend.command
  • Windows: double‑click Always-Attend.bat or right‑click Always-Attend.ps1 → Run with PowerShell
  • The first run will guide setup automatically

🚀 Easy Launch

Double‑click to run with the enhanced first‑time setup:

  • macOS: double‑click Always-Attend.command
  • Windows: double‑click Always-Attend.bat (or run Always-Attend.ps1)

🪄 Quick Share Launcher (launch.py)

Want to drop a single file on another machine and get going? Run the bundled launch.py script:

  • Prompts for the install location (defaults to the current folder)
  • Clones always-attend, creates/updates .venv, installs dependencies, and copies .env.example
  • Lets you choose UI login, headless mode, or --dry-run, then runs main.py or prints the launch command
  • Perfect for rapid sharing in chats or classrooms—just send launch.py, then run python launch.py

📋 Application Workflow

The application follows a structured 4-step workflow with multiple execution modes:

Core Workflow

  1. Environment Setup - Bootstrap and install dependencies
  2. Python Check - Verify Python environment and packages
  3. App Start - Load config, privacy policy, and first-run setup
  4. Choose Mode - Select execution mode:

Execution Modes

  • 🔍 Stats (--stats) - View attendance statistics (read-only)
  • 📤 Submit (default) - Main workflow for code submission
  • 🔑 Login Only (--login-only) - Refresh session and exit

Submit Workflow Path

When using Submit mode, the application follows this sequence:

  1. Session Check → Sign-in if needed
  2. Submission → Dry-run or submit codes
  3. Done → Save results and exit

Login Only Workflow Path

When using Login Only mode:

  1. Session Check → Sign-in if needed
  2. Done → Exit after refreshing session

Quick Start

# Basic execution
attend

# View statistics
attend stats

# Refresh login session
attend login

# Run specific week
attend week 4

# Show browser (headed mode)
attend --headed

Install from PyPI:

pip install always-attend
attend --help

python main.py remains available as a compatibility launcher inside the repository checkout.

🧰 CLI Environment Setup

Option A — uv (recommended)

Why uv?

  • 🔒 Deterministic installs via uv.lock so every machine shares the same dependency graph.
  • ⚡ Rust-powered resolver/installer that is noticeably faster than pip + venv.
  • 🧪 uv sync keeps the virtual env fresh without manual activation juggling (uv run … handles it).
  • 🌍 Handles Python download/management when the requested interpreter is missing.
  1. Install uv if it is not already available:
    curl -LsSf https://astral.sh/uv/install.sh | sh
    
  2. From the project root, sync dependencies and refresh the local virtual environment:
    uv sync
    
  3. Install the Chromium browser bundle for Playwright:
    uv run python -m playwright install chromium
    
  4. Launch the CLI (examples):
    uv run attend --dry-run
    uv run attend login
    

Option B — Standard venv + pip

python3 -m venv .venv
source .venv/bin/activate    # Windows: .\.venv\Scripts\activate
pip install -U pip
pip install -e .
python -m playwright install chromium
attend

What the launchers do:

  • Check for Python (and Git if available)
  • Create/activate a virtualenv and install dependencies on first run
  • Run a first‑time setup wizard (portal URL, credentials, week, browser)
  • Auto‑detect the latest week from data/*/*.json and set WEEK_NUMBER

Update later:

git pull

📦 Attendance Database

Always Attend now reads attendance codes exclusively from the data/ directory (or the folder specified by CODES_DB_PATH). Each course gets its own subfolder and every week is represented by a JSON file:

data/
  FIT1045/
    3.json     # [{"slot": "Workshop 01", "code": "LCPPH"}, ...]
  FIT1047/
    7.json

If you maintain your codes in a separate Git repository, point the tool at it:

export CODES_DB_REPO="git@github.com:you/attendance-db.git"
export CODES_DB_BRANCH="main"

On every run the repository is cloned (if missing) or updated before submission. Without a repository the tool simply reads whatever JSON files already exist under data/.

📊 Statistics Tracking

The tool now automatically tracks your attendance submission statistics:

# View detailed statistics
attend stats

# Or use the stats module directly
python stats.py

Statistics include:

  • Total runs and success rate
  • Codes submitted per course
  • Recent activity timeline
  • Error history

✨ Rich CLI Experience

Always Attend ships with a polished terminal UI powered by Rich:

  • Animated Monash-blue typewriter banner with optional spark highlights (auto-disables on non-TTY output).
  • Live, single-line progress bars with square block fills and cached ASCII spinners when CLI_PROGRESS_RICH=1.
  • Animated logging for major workflow steps without leaking ANSI fragments when launched via .command/.bat.

UI Control Flags

Variable Values Effect
CLI_STYLE fancy (default), simple, minimal Toggle banner + log animations
FORCE_ANIMATIONS true / false Override TTY detection (useful for debugging)
CLI_PROGRESS_RICH 1 / 0 Enable/disable Rich live progress tracker

Examples

# Full experience: animated banner, live block progress
CLI_STYLE=fancy CLI_PROGRESS_RICH=1 attend --dry-run

# Quiet fallback suitable for basic terminals
CLI_STYLE=minimal CLI_PROGRESS_RICH=0 attend

Set these in your .env to persist the chosen style across runs.

Troubleshooting

  • If login keeps asking for MFA: re-run the headed login to refresh storage_state.json
  • If the browser fails to launch: make sure Google Chrome or Microsoft Edge is installed, or set BROWSER_CHANNEL to chrome/msedge.
  • On Windows, if activation fails, run PowerShell as Administrator once, then try .venv\Scripts\Activate.ps1 again.
  • When running, please do NOT use a VPN, as this may cause Okta to refuse the connection.

FAQ (Windows)

  • Use py instead of python: If python isn't found or points to another version, use py (e.g., py -m venv .venv, py main.py).
  • Switching between Git Bash and PowerShell: In terminals like VS Code, use the dropdown to open a new Git Bash or PowerShell window. Some commands (e.g., source) only work in Git Bash, while PowerShell uses .\ for scripts.
  • Path escaping issues: PowerShell uses backslashes (\) and may treat them as escape characters. Wrap paths in quotes or use double backslashes like C:\path\to\file. Git Bash uses forward slashes (/).

Command-Line Arguments

Primary command: attend

Argument Type Description Example
--browser string Browser engine (chromium/firefox/webkit) --browser chromium
--channel string System browser channel (chromium only: chrome, chrome-beta, msedge, etc.) --channel chrome
--headed flag Show browser UI (sets HEADLESS=0) --headed
--dry-run flag Print parsed codes and exit without submitting --dry-run
--week int Submit codes for a specific week (sets WEEK_NUMBER) --week 4
--login-only flag Refresh the session and exit without submitting --login-only
--stats flag Display cached attendance statistics and exit --stats
--setup flag Launch the configuration wizard interactively --setup
--debug flag Enable debug logging profile --debug
--verbose flag Enable verbose logging profile --verbose
--skip-update flag Skip the git update check before running --skip-update

Release Automation

  • Push a version tag such as v0.1.0 to trigger .github/workflows/release.yml.
  • The workflow validates that the tag matches pyproject.toml, builds sdist and wheel, creates a GitHub Release, and publishes to PyPI.
  • PyPI publishing is configured for Trusted Publishing, so the GitHub repository still needs to be registered as a trusted publisher in the target PyPI project.

Environment Variables

Variable Type Required Description Example
PORTAL_URL string URL Yes Attendance portal base URL https://attendance.monash.edu.my
CODES_DB_PATH string path No Root folder containing COURSE/WEEK.json files /srv/attendance-data
CODES_DB_REPO string URL No Git repository that mirrors the data tree git@github.com:you/attendance-db.git
CODES_DB_BRANCH string No Branch to checkout when syncing the repository main
WEEK_NUMBER int No Force a specific week instead of auto-detecting 4
SUBMIT_CONCURRENCY int No Maximum courses processed concurrently 2
SUBMIT_TARGET_CONCURRENCY int No Parallel submission workers per course 3
USERNAME string No Okta username for auto-login student@example.edu
PASSWORD string No Okta password for auto-login correcthorsebattery
TOTP_SECRET string (base32) No MFA TOTP secret for auto-login JBSWY3DPEHPK3PXP
AUTO_LOGIN flag (0/1) No Toggle automatic login 1
BROWSER string No Engine override (chromium/firefox/webkit) chromium
BROWSER_CHANNEL string No System channel (chrome/msedge/etc.) chrome
HEADLESS flag (0/1 or true/false) No Run without UI (0 disables) 0
USER_DATA_DIR string path No Persistent browser profile directory ~/.always-attend-profile
LOG_PROFILE string No Logging profile (user/quiet/debug/verbose) verbose
LOG_FILE string path No Optional log file destination /tmp/always-attend.log
SKIP_UPDATE_CHECK flag (0/1 or true/false) No Skip remote git pull when set 1

Disclaimer

  • This project is for educational and personal use only. Use it responsibly and follow your institution’s policies and the website’s terms of use.
  • This project is not affiliated with, endorsed by, or sponsored by any university or service provider. All product names, logos, and brands are property of their respective owners.
  • You are solely responsible for any use of this tool and any consequences that may arise. The authors provide no guarantee that it will work for your specific setup.

License

  • This project is licensed under the GNU General Public License v3.0 (GPL‑3.0). See the full text in the LICENSE file.
  • You may copy, modify, and distribute this software under the terms of the GPL‑3.0. It is provided “as is”, without any warranty.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

always_attend-0.1.0.tar.gz (79.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

always_attend-0.1.0-py3-none-any.whl (87.4 kB view details)

Uploaded Python 3

File details

Details for the file always_attend-0.1.0.tar.gz.

File metadata

  • Download URL: always_attend-0.1.0.tar.gz
  • Upload date:
  • Size: 79.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for always_attend-0.1.0.tar.gz
Algorithm Hash digest
SHA256 52c5fb63f3c745cf8bafeed89591ec551312f13f3c298beab0e2f7e32f7b4ae7
MD5 e33050214d5febd52a82f7bf86a34364
BLAKE2b-256 a4d320e530a501028ce78e901cf0108f4f65d4a876ac925742d6cb2505d9b60c

See more details on using hashes here.

Provenance

The following attestation bundles were made for always_attend-0.1.0.tar.gz:

Publisher: release.yml on bunizao/always-attend

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file always_attend-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: always_attend-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 87.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for always_attend-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4ca3765944ca9f0c223457a9ce681b2a01e14b3df130e8e0b77609efa2eaa741
MD5 540ffde416fb05c0a421af6e0c97b2fb
BLAKE2b-256 6b179e4597a5182ded17e868dcbfb5325bf1955b21de115da099213e3b9a2800

See more details on using hashes here.

Provenance

The following attestation bundles were made for always_attend-0.1.0-py3-none-any.whl:

Publisher: release.yml on bunizao/always-attend

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page