#!/usr/bin/env bash # Prints the set of jobs the user has ALREADY engaged with, for deduplication # during a job search — so the same job is never found/imported twice, also on # LATER runs. Combines existing Bewerbungen (/applications) and already-imported # Jobangebote (/joboffers) from the Bewerbungs-Tracker API. # # Output: EINE Zeile pro bereits erfasster FIRMA (company-level), tab-separated: # firma_slug firma stelle ort quelle_url external_id # # firma_slug = robuster Firmen-Schlüssel (lowercase, Umlaute ae/oe/ue/ss, # Diakritika entfernt, (m/w/d) raus, End-Rechtsform-Tokens wie # gmbh/ag/kg entfernt, mit "-" verbunden). Identisch zu firmaSlug # in lib/blacklist.js des Servers — deckt Schreibweisen-/ # Rechtsform-/Umlaut-Varianten EINER Firma ab. # # Regel: eine FIRMA darf nur EINMAL gefunden werden. Ein neuer Treffer gilt als # Dublette (→ verwerfen), wenn seine Firma zu EINER Zeile hier passt: # * gleicher firma_slug, ODER # * ein firma_slug ist ein führendes Bindestrich-Präfix des anderen (≥2 Tokens) # — d. h. Kurzname vs. voller Firmenname ("it-problemloeser" ⊂ # "it-problemloeser-verwaltungs-und-handels"), ODER # * gleiche quelle_url ODER gleiche external_id. # Es wird bewusst NICHT mehr nach Stellentitel unterschieden — eine bereits # erfasste Firma taucht mit KEINEM (auch nicht neuem) Titel wieder auf. # HTML-Entities werden dekodiert. # # 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 "applied-set.sh: bewerbungs-tracker helper not found at $BT" >&2 exit 2 fi # In Tempdateien schreiben (NICHT in Env-Vars): die kombinierte JSON aus # /applications + /joboffers wird groß; als Env-Var würde sie ARG_MAX (argv+envp) # sprengen ("Argument list too long" beim python3-Start). Dateien lesen umgeht das. TMPDIR_AS="$(mktemp -d)" trap 'rm -rf "$TMPDIR_AS"' EXIT APPS_FILE="$TMPDIR_AS/apps.json" OFFERS_FILE="$TMPDIR_AS/offers.json" "$BT" GET '/applications?limit=500' > "$APPS_FILE" "$BT" GET '/joboffers' > "$OFFERS_FILE" APPS_FILE="$APPS_FILE" OFFERS_FILE="$OFFERS_FILE" python3 <<'PY' import os, json, html, re, sys, unicodedata def load(name): with open(os.environ[name], encoding='utf-8') as fh: raw = fh.read().split(' 1 and kept[-1] in _LEGAL_FORMS: kept.pop() return '-'.join(kept if kept else words) # Eine Firma nur EINMAL: pro firma_slug genau eine Zeile (erste gewinnt). seen = set() def emit(firma, stelle, ort, url, ext): slug = firma_slug(firma) if not slug or slug in seen: return seen.add(slug) print('\t'.join([slug, clean(firma), clean(stelle), clean(ort), clean(url), clean(ext)])) for a in load('APPS_FILE'): emit(a.get('firma'), a.get('stelle'), a.get('ort'), a.get('quelle_url'), '') for o in load('OFFERS_FILE'): emit(o.get('firma'), o.get('stelle'), o.get('ort'), o.get('quelle_url'), o.get('external_id')) print(f'# {len(seen)} bereits erfasste Firmen (Bewerbungen + Jobangebote)', file=sys.stderr) PY