Commit 1e8c059eee
1e8c059eeeafa07ff220a9e9f874d879cefff113
parent: b9daf53bf9
Verified · cmc
cmc <hello@cleberg.net> · 2026-08-23 21:37 UTC
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.
Layout: unified · split
README.nfo
+7 −6
| @@ -1,11 +1,12 @@ |
| 1 | ┌──────────────────────────────────────────────────────────────┐ |
1 | ┌──────────────────────────────────────────────────────────────┐ |
| 2 | │ O M A H A I N C I D E N T S [ KRZ ] krz.sh │ |
2 | │ O M A H A M E T R O B L O T T E R [ KRZ ] krz.sh │ |
| 3 | └──────────────────────────────────────────────────────────────┘ |
3 | └──────────────────────────────────────────────────────────────┘ |
| 4 | |
4 | |
| 5 | WHAT |
5 | WHAT |
| 6 | police activity across the omaha metro, pulled from the agencies' |
6 | an archive of police activity and alpr surveillance across the |
| 7 | own feeds and joined against alpr camera locations from |
7 | omaha metro, pulled from the agencies' own feeds. sarpy county, |
| 8 | openstreetmap. |
8 | council bluffs and the flock portals all serve rolling windows and |
| |
9 | delete what falls outside them; this keeps it. |
| 9 | |
10 | |
| 10 | COVERAGE |
11 | COVERAGE |
| 11 | omaha pd dcgis arcgis view, 2022-01-01 onward, |
12 | omaha pd dcgis arcgis view, 2022-01-01 onward, |
| @@ -42,7 +43,7 @@ USE |
| 42 | .venv/bin/python ingest.py --full # first run, backfill |
43 | .venv/bin/python ingest.py --full # first run, backfill |
| 43 | .venv/bin/python ingest.py # daily, last 30 days |
44 | .venv/bin/python ingest.py # daily, last 30 days |
| 44 | .venv/bin/python ingest.py cbpd sarpy # one source at a time |
45 | .venv/bin/python ingest.py cbpd sarpy # one source at a time |
| 45 | .venv/bin/python ingest.py opd_csv # 2015-2023 csv archive |
46 | .venv/bin/python ingest.py opd_archive # omaha 2015-2021 backfill |
| 46 | .venv/bin/python app.py |
47 | .venv/bin/python app.py |
| 47 | |
48 | |
| 48 | SITE |
49 | SITE |
| @@ -91,7 +92,7 @@ ARCHIVE |
| 91 | |
92 | |
| 92 | to run the pull locally instead: |
93 | to run the pull locally instead: |
| 93 | |
94 | |
| 94 | 0 6 * * * cd /path/to/omaha-incidents && .venv/bin/python ingest.py |
95 | 0 6 * * * cd /path/to/omaha-metro-blotter && .venv/bin/python ingest.py |
| 95 | |
96 | |
| 96 | RAW |
97 | RAW |
| 97 | raw_records keeps the feed's own json for every version of every |
98 | raw_records keeps the feed's own json for every version of every |
fetch_boundaries.py
+1 −1
| @@ -38,7 +38,7 @@ def fetch(layer): |
| 38 | "maxAllowableOffset": TOLERANCE, "f": "geojson"} |
38 | "maxAllowableOffset": TOLERANCE, "f": "geojson"} |
| 39 | url = layer["url"] + "/query?" + urllib.parse.urlencode(params) |
39 | url = layer["url"] + "/query?" + urllib.parse.urlencode(params) |
| 40 | # Sarpy's MapServer 403s the default Python-urllib agent |
40 | # Sarpy's MapServer 403s the default Python-urllib agent |
| 41 | req = urllib.request.Request(url, headers={"User-Agent": "omaha-incidents/1.0"}) |
41 | req = urllib.request.Request(url, headers={"User-Agent": "omaha-metro-blotter/1.0"}) |
| 42 | with urllib.request.urlopen(req, timeout=120, context=CTX) as r: |
42 | with urllib.request.urlopen(req, timeout=120, context=CTX) as r: |
| 43 | return json.load(r) |
43 | return json.load(r) |
| 44 | |
44 | |
ingest.py
+2 −2
| @@ -128,7 +128,7 @@ def get(url, params, retries=4): |
| 128 | for attempt in range(retries): |
128 | for attempt in range(retries): |
| 129 | try: |
129 | try: |
| 130 | req = urllib.request.Request(url, data=body, |
130 | req = urllib.request.Request(url, data=body, |
| 131 | headers={"User-Agent": "omaha-incidents/1.0"}) |
131 | headers={"User-Agent": "omaha-metro-blotter/1.0"}) |
| 132 | with urllib.request.urlopen(req, timeout=120, context=SSL_CTX) as r: |
132 | with urllib.request.urlopen(req, timeout=120, context=SSL_CTX) as r: |
| 133 | payload = json.load(r) |
133 | payload = json.load(r) |
| 134 | except (urllib.error.URLError, TimeoutError, json.JSONDecodeError) as e: |
134 | except (urllib.error.URLError, TimeoutError, json.JSONDecodeError) as e: |
| @@ -321,7 +321,7 @@ def ingest_opd_archive(conn, _since): |
| 321 | rows, seen = [], {} |
321 | rows, seen = [], {} |
| 322 | for year in OPD_ARCHIVE_YEARS: |
322 | for year in OPD_ARCHIVE_YEARS: |
| 323 | url = OPD_ARCHIVE.format(y=year) |
323 | url = OPD_ARCHIVE.format(y=year) |
| 324 | req = urllib.request.Request(url, headers={"User-Agent": "omaha-incidents/1.0"}) |
324 | req = urllib.request.Request(url, headers={"User-Agent": "omaha-metro-blotter/1.0"}) |
| 325 | with urllib.request.urlopen(req, timeout=180, context=SSL_CTX) as r: |
325 | with urllib.request.urlopen(req, timeout=180, context=SSL_CTX) as r: |
| 326 | text = r.read().decode("utf-8-sig", "replace") |
326 | text = r.read().decode("utf-8-sig", "replace") |
| 327 | reader = csv.DictReader(text.splitlines()) |
327 | reader = csv.DictReader(text.splitlines()) |
site_template.html
+1 −1
| @@ -152,7 +152,7 @@ footer a { color: var(--text-secondary); } |
| 152 | |
152 | |
| 153 | <footer> |
153 | <footer> |
| 154 | <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> |
154 | <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> |
| 155 | <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> |
155 | <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> |
| 156 | </footer> |
156 | </footer> |
| 157 | </div> |
157 | </div> |
| 158 | |
158 | |