krz/omaha-metro-blotter

Archive of police activity and ALPR surveillance across the Omaha metro.

clone: git clone https://gitbay.org/krz/omaha-metro-blotter.git

1e8c059eeeafa07ff220a9e9f874d879cefff113

verified · cmc

author: Christian Cleberg <hello@cleberg.net> · 2026-08-23T21:37:15Z

Rename the project to omaha-metro-blotter

The repo covers six agencies across two states, ALPR camera locations
and Flock search audits, not just Omaha incidents. Updates the user
agent, the site footer link, the nfo banner and a stale opd_csv
reference in the usage block.
 README.nfo          | 13 +++++++------
 fetch_boundaries.py |  2 +-
 ingest.py           |  4 ++--
 site_template.html  |  2 +-
 4 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/README.nfo b/README.nfo
index 2d52792..ed76620 100644
--- a/README.nfo
+++ b/README.nfo
@@ -1,11 +1,12 @@
 ┌──────────────────────────────────────────────────────────────┐
-│  O M A H A   I N C I D E N T S             [ KRZ ]   krz.sh  │
+│  O M A H A   M E T R O   B L O T T E R     [ KRZ ]   krz.sh  │
 └──────────────────────────────────────────────────────────────┘
 
 WHAT
-  police activity across the omaha metro, pulled from the agencies'
-  own feeds and joined against alpr camera locations from
-  openstreetmap.
+  an archive of police activity and alpr surveillance across the
+  omaha metro, pulled from the agencies' own feeds. sarpy county,
+  council bluffs and the flock portals all serve rolling windows and
+  delete what falls outside them; this keeps it.
 
 COVERAGE
   omaha pd                dcgis arcgis view, 2022-01-01 onward,
@@ -42,7 +43,7 @@ USE
       .venv/bin/python ingest.py --full        # first run, backfill
       .venv/bin/python ingest.py               # daily, last 30 days
       .venv/bin/python ingest.py cbpd sarpy    # one source at a time
-      .venv/bin/python ingest.py opd_csv       # 2015-2023 csv archive
+      .venv/bin/python ingest.py opd_archive   # omaha 2015-2021 backfill
       .venv/bin/python app.py
 
 SITE
@@ -91,7 +92,7 @@ ARCHIVE
 
   to run the pull locally instead:
 
-      0 6 * * *  cd /path/to/omaha-incidents && .venv/bin/python ingest.py
+      0 6 * * *  cd /path/to/omaha-metro-blotter && .venv/bin/python ingest.py
 
 RAW
   raw_records keeps the feed's own json for every version of every
diff --git a/fetch_boundaries.py b/fetch_boundaries.py
index 7b727ed..345908a 100644
--- a/fetch_boundaries.py
+++ b/fetch_boundaries.py
@@ -38,7 +38,7 @@ def fetch(layer):
               "maxAllowableOffset": TOLERANCE, "f": "geojson"}
     url = layer["url"] + "/query?" + urllib.parse.urlencode(params)
     # Sarpy's MapServer 403s the default Python-urllib agent
-    req = urllib.request.Request(url, headers={"User-Agent": "omaha-incidents/1.0"})
+    req = urllib.request.Request(url, headers={"User-Agent": "omaha-metro-blotter/1.0"})
     with urllib.request.urlopen(req, timeout=120, context=CTX) as r:
         return json.load(r)
 
diff --git a/ingest.py b/ingest.py
index 03c84a6..d84cb0a 100644
--- a/ingest.py
+++ b/ingest.py
@@ -128,7 +128,7 @@ def get(url, params, retries=4):
     for attempt in range(retries):
         try:
             req = urllib.request.Request(url, data=body,
-                                         headers={"User-Agent": "omaha-incidents/1.0"})
+                                         headers={"User-Agent": "omaha-metro-blotter/1.0"})
             with urllib.request.urlopen(req, timeout=120, context=SSL_CTX) as r:
                 payload = json.load(r)
         except (urllib.error.URLError, TimeoutError, json.JSONDecodeError) as e:
@@ -321,7 +321,7 @@ def ingest_opd_archive(conn, _since):
     rows, seen = [], {}
     for year in OPD_ARCHIVE_YEARS:
         url = OPD_ARCHIVE.format(y=year)
-        req = urllib.request.Request(url, headers={"User-Agent": "omaha-incidents/1.0"})
+        req = urllib.request.Request(url, headers={"User-Agent": "omaha-metro-blotter/1.0"})
         with urllib.request.urlopen(req, timeout=180, context=SSL_CTX) as r:
             text = r.read().decode("utf-8-sig", "replace")
         reader = csv.DictReader(text.splitlines())
diff --git a/site_template.html b/site_template.html
index 9564642..09cd4a3 100644
--- a/site_template.html
+++ b/site_template.html
@@ -152,7 +152,7 @@ footer a { color: var(--text-secondary); }
 
 <footer>
   <p>Built from the agencies' own published feeds: the Omaha Police incident view on DCGIS, the Sarpy County PublicCrimeMap, the Council Bluffs public calls-for-service feed, and the Flock Safety transparency portals. Camera locations from OpenStreetMap contributors, <a href="https://opendatacommons.org/licenses/odbl/">ODbL</a>.</p>
-  <p>The Sarpy County and Council Bluffs feeds keep a rolling twelve months and drop what falls outside it. This archive keeps what they drop. Source and the full database: <a href="https://github.com/krazywarez/omaha-incidents">github.com/krazywarez/omaha-incidents</a>.</p>
+  <p>The Sarpy County and Council Bluffs feeds keep a rolling twelve months and drop what falls outside it. This archive keeps what they drop. Source and the full database: <a href="https://github.com/krazywarez/omaha-metro-blotter">github.com/krazywarez/omaha-metro-blotter</a>.</p>
 </footer>
 </div>