Metadata-Version: 2.4
Name: cap-oet
Version: 0.1.0
Summary: OASIS Event Terms (OET v1.2) for CAP, with an SVG icon per event code.
Author: WMO RAF
License-Expression: MIT
Project-URL: Homepage, https://github.com/wmo-raf/cap-oet
Project-URL: Bug Tracker, https://github.com/wmo-raf/cap-oet/issues
Classifier: Intended Audience :: Developers
Classifier: Framework :: Django
Classifier: Framework :: Wagtail
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Dynamic: license-file

# CAP OASIS Event Terms (OET) + SVG Icons

[OASIS Event Terms (OET v1.2)](https://docs.oasis-open.org/emergency/cap-etl/v1.2/cap-etl-v1.2.html) for the Common
Alerting Protocol, packaged with an **SVG icon for every one of the 224
event codes**.

> ### ⚠️ Not an official icon set
>
> **This is not an official or standardised set of icons for the OASIS Event Terms.**
> No standards body — OASIS, OCHA, WMO or anyone else — has endorsed these mappings.
>
> It is an internal effort to standardise the icons used across the warning tools built
> at [github.com/wmo-raf](https://github.com/wmo-raf) — including **cap-composer**,
> **cap-aggregator** and **ClimWeb** — so that the same event type looks the same
> wherever it is displayed or communicated.
>
> The choice of icon for each event code is a **judgement call**, not a specification.
> The icons themselves are vendored from the OCHA Humanitarian Icons and Font Awesome
> Free (see [LICENSE](LICENSE)); neither project endorses this mapping.
>
> The event terms themselves *are* standard — they come from the
> [OASIS CAP Event Terms List v1.2](https://docs.oasis-open.org/emergency/cap-etl/v1.2/cap-etl-v1.2.html).

## Browse the icons

**→ [Browse all 224 icons here](https://wmo-raf.github.io/cap-oet/)**

## What's inside

```
src/cap_oet/                 # the installable package
├── data/oet_v1_2.py         # the 224 OASIS event terms + lookup exports
├── mapping.py               # OET code -> source icon (OCHA name or "fa:<name>")
├── icons.py                 # get_icon_name / get_icon_svg / get_wagtail_icons
├── templatetags/cap_oet.py  # {% oet_icon "OET-079" %}
└── templates/cap_oet/icons/ # OET-000.svg ... OET-223.svg (fill=currentColor)

tools/build_site.py          # dev tool: builds docs/ — not shipped in the package
docs/                        # generated GitHub Pages site — not shipped either
```

## Install

```bash
pip install cap-oet
```

Add to Django `INSTALLED_APPS` so the templates load:

```python
INSTALLED_APPS = [..., "cap_oet"]
```

## Use

Data:

```python
from cap_oet import OASIS_EVENT_TERMS_BY_CODE, OASIS_EVENT_TERMS_AS_CHOICES

OASIS_EVENT_TERMS_BY_CODE["OET-079"]
# {'code': 'OET-079', 'term': 'flash flood', 'categories': ['Met']}
```

Icons in a template (colour via CSS because icons use `currentColor`):

```html
{% load cap_oet %}
<span style="color:#d00">{% oet_icon "OET-079" class="oet-icon" width="24" height="24" %}</span>
```

Icons in Python:

```python
from cap_oet import get_icon_svg, get_icon_name

get_icon_name("OET-079")  # "cap_oet/icons/OET-079.svg"
```

## Wagtail icons

Every SVG carries `id="icon-oet-<nnn>"`, Wagtail's icon convention, so the icons can go
into the admin icon sprite.

`get_wagtail_icons()` returns the template paths for Wagtail's `register_icons` hook.
Register them from your own `wagtail_hooks.py`:

```python
from wagtail import hooks
from cap_oet import get_wagtail_icons


@hooks.register("register_icons")
def register_icons(icons):
    return icons + get_wagtail_icons()  # all 224
    # return icons + get_wagtail_icons(["OET-159", "OET-079"])  # or just what you need
```

Then render with Wagtail's own tag:

```html
{% load wagtailadmin_tags cap_oet %}
{% icon name="oet-159" %}
{% icon name=alert.event_code|oet_icon_name %}   {# OET-159 -> oet-159 #}
```

> **Registering all 224 adds them to the admin sprite on every page (~170 KB).** Pass a
> subset if you only need a few. `get_wagtail_icons()` lives in `icons.py` and imports
> fine without Wagtail installed.

`{% oet_icon %}` inlines the SVG and strips the `id`, so rendering the same icon twice
on a page can't produce duplicate DOM ids.

## Coverage

All 224 codes have an icon — there are no placeholders and no original artwork. Each is
vendored from an existing open set and recoloured to `currentColor`:

| Source                    | Count | Listed in                  |
|---------------------------|-------|----------------------------|
| OCHA Humanitarian Icons   | 132   | `mapping.py::OCHA_SOURCED` |
| Font Awesome Free (solid) | 92    | `mapping.py::FA_SOURCED`   |

Font Awesome fills the concepts OCHA doesn't cover (radiation, bomb, smog, icicles,
plane-circle-xmark, …) and is normalized into the same 48×48 viewBox. Because the two
sets are drawn in different styles, the family isn't perfectly uniform — `STYLE_GUIDE.md`
records the OCHA rules as the target if any icon is redrawn later.

## Icon explorer

**→ [Browse all 224 icons](https://wmo-raf.github.io/cap-oet/)** ·
[Usage examples](https://wmo-raf.github.io/cap-oet/usage.html)

Filter by category, grouping and source; search; resize; recolour; click any icon to
copy its SVG. Every icon also has a stable URL, e.g.
[`icons/OET-079.svg`](https://wmo-raf.github.io/cap-oet/icons/OET-079.svg), and
[`manifest.json`](https://wmo-raf.github.io/cap-oet/manifest.json) is a machine-readable
index of the whole set.

To rebuild it — the builder reads the icon SVGs, `mapping.py` and the OET data directly
(no Django, no settings), so the output can't drift from the icon set:

```bash
python tools/build_site.py --out docs
```

```
docs/
├── index.html          explorer: filter by category, grouping and source; search;
│                       size slider; colour + dark-mode toggle; click to copy an SVG;
│                       shareable deep links (?cat=Met&grouping=fire)
├── manifest.json       224 × {code, term, grouping, categories, source, shared}
├── icons.svg           sprite of <symbol id="OET-079">, referenced via <use>
└── icons/OET-079.svg   every icon as its own file — stable public URL
```
