Track and send notifications when individuals are added or removed from a compatible municipal jail roster https://jailarr.com
  • JavaScript 38.9%
  • Python 27.8%
  • HTML 19.6%
  • CSS 13.2%
  • Dockerfile 0.4%
  • Other 0.1%
Find a file
Kurtis Ward 80a524603e
Some checks failed
Build and Push Docker Image / build (push) Has been cancelled
Merge pull request 'new-ui-test' (#6) from new-ui-test into main
Reviewed-on: #6
2026-02-01 13:14:06 -05:00
.forgejo/workflows use Forgejo as registry 2026-01-15 17:58:54 -05:00
static move css back to external file 2026-02-01 13:12:33 -05:00
templates v4 2026-02-01 13:13:20 -05:00
.dockerignore add dockerfile and Forgejo builds 2026-01-15 17:56:16 -05:00
Dockerfile add dockerfile and Forgejo builds 2026-01-15 17:56:16 -05:00
entrypoint.sh Add single container option 2026-01-15 17:52:22 -05:00
jailarr.py cleanup 2026-01-23 01:55:57 -05:00
README.md Add filtering and logic for placeholder mugshots 2026-01-23 00:59:43 -05:00
web.py cleanup 2026-01-23 01:55:57 -05:00

Jailarr

A Python-based monitoring system that tracks and stores MyOCV-based jail inmate rosters, and displays them in a simple web interface. It also sends real-time notifications via Apprise (supporting 80+ notification services).

Main Screen Analytics
Awards Detective Mode

Core Features

  • Multi-Agency Support — Monitor multiple MyOCV-based jail rosters simultaneously
  • Real-time Monitoring — Customizable check interval (default: 1 hour)
  • Flexible Notifications — Supports Telegram, Discord, Slack, email, Pushover, and 80+ other services via Apprise
  • Modern Web Interface — Simple and intuitive web interface
  • Booking Alerts — Sends notifications with mugshot photos for new arrests
  • Release Tracking — Automatically detects and logs when inmates are released
  • Change Detection — Tracks updates to charges, mugshots, and other inmate details
  • Mugshot Versioning — Detects mugshot changes via image hashing and preserves old versions
  • Image Archiving — Downloads and stores inmate mugshots locally
  • Change History — Full audit log of all record modifications

Web Interface Features

  • Inmate Awards — Optionally shows a small badge for inmates that excel in certain areas (enable it to find out more)
  • Analytics — View statistics and trends over time
  • Detective Mode — A mini game where you can practice your detective skills. In the game, you will be presented with three random mugshots and their associated lists of charges. Your goal is to correctly match the charges to the mugshots.

Configuration

The monitor is configured through environment variables:

Variable Description Required Default
JSON_URLS Agency JSON endpoint(s), comma or newline separated Yes empty
APPRISE_URLS Notification service URL(s), comma-separated No empty
DB_PATH Path to SQLite database file No /data/inmates.db
CHECK_INTERVAL Time between scans in seconds No 3600
WEB_PORT Port for web server No 5000
ENABLE_AWARDS Enable inmate awards No false
NOTIFY_NEW New inmate bookings No true
NOTIFY_MUGSHOT Mugshot updates No true
NOTIFY_CHARGES Charges updates No false
NOTIFY_UPDATES Other field updates No false
NOTIFY_STARTUP Send a message when the service starts No true
PLACEHOLDER_MUGSHOT_HASHES Comma-separated MD5 hashes of placeholder mugshots No a859a5e7da5999c932a52430e95bbe78
NOTIFY_PLACEHOLDER_CHANGES Enable notifications for all placeholder transitions No false

Note: If APPRISE_URLS is not set, all notifications are disabled and the monitor runs in silent/archive mode.

JSON Endpoints

This app ONLY works with jail rosters that use the MyOCV platform. You must provide the JSON URL(s) for the roster(s) you want to monitor. The URLs are not public, and may require a bit of work to obtain. Read the wiki page to find out how to find the endpoint URLs.

Known JSON Endpoints

Municipality Agency ID JSON URL
Chippewa County, MI a20449768 https://cdn.myocv.com/ocvapps/a20449768/Chippewainmates.json
Dickinson County, MI a135649801 https://cdn.myocv.com/ocvapps/a135649801/Dickinsoninmates.json
Houghton County, MI a134149931 https://cdn.myocv.com/ocvapps/a134149931/Houghtoninmates.json
Mackinac County, MI a109249781 https://cdn.myocv.com/ocvapps/a109249781/Mackinacinmates.json
Marquette County, MI a39949855 https://cdn.myocv.com/ocvapps/a39949855/Marquetteinmates.json

Notifications

Notification Services (Apprise)

Jailarr uses Apprise for notifications. Configure one or more services via URL:

Multiple services: Comma-separate URLs to notify multiple services simultaneously:

APPRISE_URLS=tgram://bot/chat,discord://id/token,ntfy://mytopic

See the full list of supported services.

Notification Types

Event Title Includes Photo
New booking 🚨 New Inmate Booking Yes
Mugshot updated 📷 Mugshot Updated Yes
Charges updated ⚖️ Charges Updated No
Record updated 📝 Inmate Record Updated No

First Run Behavior

On the first run (empty database), all inmates are added silently without sending notifications. This prevents a flood of alerts when initially populating the database. A startup message is still sent to confirm the monitor is online.

Example Notification

🚨 New Inmate Booking

Name: Smith, John

Age: 35
Gender: M
Booking Date: 2026-01-15 10:30:00

Charges:
OWI - OPERATING WHILE INTOXICATED - 1000.00
DRIVING WHILE LICENSE SUSPENDED - 500.00

Installation

Local

Prerequisites

  • Python 3.11+
  • pip
  1. Clone the repository:

    git clone https://github.com/yourusername/jailarr.git
    cd jailarr
    
  2. Install dependencies:

    pip install requests apprise python-dateutil flask
    
  3. Set environment variables:

    # Single agency
    export JSON_URLS="https://cdn.myocv.com/ocvapps/a39949855/Marquetteinmates.json"
    
    # Or multiple agencies (comma-separated)
    export JSON_URLS="https://cdn.myocv.com/ocvapps/a39949855/Marquetteinmates.json,https://cdn.myocv.com/ocvapps/a135649801/Dickinsoninmates.json"
    
    export APPRISE_URLS="tgram://your_bot_token/your_chat_id"
    export DB_PATH="./data/inmates.db"
    
  4. Run the monitor:

    python jailarr.py
    

Docker

Option 1: Using Pre-built Image (placeholder. images coming soon)

services:
  jailarr:
    image: placeholder-registry/jailarr:latest
    container_name: jailarr
    restart: unless-stopped
    environment:
      - JSON_URLS=https://cdn.myocv.com/ocvapps/a39949855/Marquetteinmates.json
      - APPRISE_URLS=tgram://bot_token/chat_id
      - CHECK_INTERVAL=3600
    ports:
      - "5000:5000"
    volumes:
      - ./data:/data

Option 2: Building the Image

# Build locally
docker build -t jailarr .

# Or with docker compose
docker compose build

Option 3: Mount Source Files (No Build)

If you prefer to mount the source files directly without building an image:

services:
  jailarr:
    image: python:3.11-slim
    container_name: jailarr
    restart: unless-stopped
    command: >
      sh -c "pip install requests apprise python-dateutil flask && sh /app/entrypoint.sh"
    environment:
      - PYTHONUNBUFFERED=1
      - JSON_URLS=https://cdn.myocv.com/ocvapps/a39949855/Marquetteinmates.json
      - APPRISE_URLS=tgram://bot_token/chat_id
      - DB_PATH=/app/data/inmates.db
      - CHECK_INTERVAL=3600
    ports:
      - "5000:5000"
    volumes:
      - ./jailarr:/app

Data Storage

The monitor stores data in two locations:

Database (/data/inmates.db)

inmates table:

Column Description
record_id Composite key: {agency}_{inmate_id}
agency Source roster (e.g., Marquette, Dickinson)
inmate_id Original ID from the source roster
name Inmate name
age, gender, race Demographics
height, weight Physical description (if available)
booking_date Date/time of booking
charges List of charges
arresting_agency Agency that made the arrest (if available)
image_url Original mugshot URL
image_hash MD5 hash for change detection
first_seen Unix timestamp when first detected
last_seen Unix timestamp of last scan
status active or released

change_history table:

Column Description
record_id Links to inmate
field_name Which field changed
old_value Previous value
new_value Updated value
changed_at Unix timestamp

Images (/data/images/)

  • Current mugshots: {arrest_no}.jpg
  • Previous versions: {arrest_no}_v1.jpg, {arrest_no}_v2.jpg, etc.