#!/usr/bin/env bash # Prints the Bewerbungs-Tracker BLACKLIST in a matchable, tab-separated form, so # a job-search run can discard candidates that are blocked BEFORE listing or # importing them (server also rejects blocked offers with 409 on POST /joboffers, # but we don't want to even present them). # # Output: one blacklist entry per line, tab-separated: # id typ firma stelle ort domain url_norm firma_norm firma_slug stelle_norm ort_norm grund # # typ = url | domain | firma | firma_stelle | auto # # firma_slug = robuster Firmen-Schlüssel (Umlaut-Translit, End-Rechtsform raus, # mit "-" verbunden) — identisch zu applied-set.sh und firmaSlug() # in lib/blacklist.js. Damit greift die Firmen-Sperre auch bei # abweichender Schreibweise/Rechtsform. # # A candidate is BLOCKED when one entry matches: # typ=url -> candidate URL (normalized) == url_norm # typ=domain -> candidate URL host == domain (also matches subdomains) # typ=firma -> SAME company: candidate firma_slug == firma_slug, OR one # firma_slug is a leading hyphen-prefix of the other (>=2 # tokens); firma_norm only as fallback for legacy rows. # typ=firma_stelle -> same company (firma_slug, wie oben) AND stelle_norm equal # (ort_norm only narrows further when set) # typ=auto -> treat like the concrete fields it carries (url/firma_stelle) # # The server already provides the *_norm fields (lowercased, tracking params # stripped, gender/legal-form removed), so compare against those. # # Reuses the bewerbungs-tracker skill's helper for auth/base-URL. set -euo pipefail BT="${BT_SCRIPT:-$HOME/.claude/skills/bewerbungs-tracker/scripts/bt.sh}" if [[ ! -x "$BT" ]]; then echo "blacklist-set.sh: bewerbungs-tracker helper not found at $BT" >&2 exit 2 fi bl="$("$BT" GET '/joboffers/blacklist')" BL_JSON="$bl" python3 <<'PY' import os, json, html, sys def load(name): raw = os.environ[name].split('