Compare commits

...

9 Commits
v1.0.0 ... main

Author SHA1 Message Date
51a7ae829d docs: correct preset navigation path to Druckeroptionen → Auftragszählung
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 23:47:09 +02:00
c2f8673171 docs: add printer options configuration step to installation guide
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 23:43:02 +02:00
dfe839531f docs: add macOS installation guide with cost center preset instructions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 23:34:38 +02:00
Oliver Hofmann
9cb8657aa7 chore: bump version to 1.0.1 2026-06-06 23:11:18 +02:00
Oliver Hofmann
118b0faca0 fix: rewrite filter as bash+awk to avoid Python/xcode-select dependency 2026-06-06 20:56:28 +02:00
Oliver Hofmann
5bd9a0277a fix: use absolute python3 path to avoid xcode-select in CUPS root context 2026-06-06 20:51:54 +02:00
Oliver Hofmann
49c0a1f848 fix: prevent set -e from killing build when grep finds no matches 2026-06-06 16:54:17 +02:00
Oliver Hofmann
04cbaf92da fix: tighten PPD validation to only catch structural errors 2026-06-06 16:50:31 +02:00
Oliver Hofmann
4f9daa2d75 chore: add install.sh for manual installation 2026-06-06 16:19:45 +02:00
5 changed files with 151 additions and 66 deletions

View File

@ -26,7 +26,8 @@
"Read(//usr/bin/**)", "Read(//usr/bin/**)",
"Read(//usr/libexec/cups/**)", "Read(//usr/libexec/cups/**)",
"Bash(lsbom /tmp/kydriv_pkg_inspect/Bom)", "Bash(lsbom /tmp/kydriv_pkg_inspect/Bom)",
"Bash(csrutil status *)" "Bash(csrutil status *)",
"Bash(xcrun notarytool *)"
] ]
} }
} }

View File

@ -0,0 +1,79 @@
# Kyocera TASKalfa 3505ci Treiber-Installation unter macOS (Apple Silicon)
## Hintergrund
Der offizielle Kyocera-Treiber überträgt seit einer neueren Version keine Kostenstellen-Codes mehr an den Drucker. Dieser alternative Treiber stellt diese Funktion wieder her.
---
## Voraussetzungen
- Mac mit Apple Silicon (M1 oder neuer)
- macOS 13 Ventura oder neuer
- Netzwerkzugang zum Drucker (IP `141.75.11.43`)
---
## 1. Treiber installieren
1. `kydriv-driver-1.0.1.pkg` herunterladen
2. Doppelklick auf die Datei → Installer folgen
3. Das Paket ist von Apple notariell beglaubigt, eine Gatekeeper-Warnung erscheint **nicht**
Der Installer kopiert:
- den PPD in `/Library/Printers/PPDs/Contents/Resources/`
- den Filter `kyofilter` in `/usr/libexec/cups/filter/`
---
## 2. Drucker einrichten
1. **Systemeinstellungen → Drucker & Scanner** öffnen
2. `+` klicken → Reiter **IP**
3. Felder ausfüllen:
| Feld | Wert |
|---|---|
| Protokoll | **LPD** |
| Adresse | `141.75.11.43` |
| Warteschlange | *(leer lassen)* |
| Name | `Kyocera TASKalfa 3505ci` |
4. Bei **Verwenden****Andere auswählen…** → PPD-Datei `TA3505ci_AS.ppd` aus dem Finder wählen (liegt nach der Installation unter `/Library/Printers/PPDs/Contents/Resources/`)
5. **Hinzufügen** klicken
6. Es erscheint ein Konfigurationsdialog für installierte Optionen. Folgende Werte einstellen:
| Option | Wert |
|---|---|
| Papierzuführungen | `Kassetten 3, 4` |
| Finisher | `4000-Blatt-Finisher` |
| Optionaler Datenträger | `Festplatte` |
| Innere Auftragstrennung | aus |
| Rechte Auftragstrennung | aus |
| Mailbox | aus |
| Stanzeinheit | aus |
| Falteinheit | aus |
Anschließend **OK** klicken.
---
## 3. Preset mit Kostenstellen-Code einrichten
Damit der Drucker den Auftrag der richtigen Kostenstelle zuordnet, muss der Code bei jedem Druckjob übergeben werden. Das geht am einfachsten über ein gespeichertes Preset.
1. Ein beliebiges Dokument öffnen und **Ablage → Drucken** (`⌘P`) aufrufen
2. Sicherstellen, dass `Kyocera TASKalfa 3505ci` als Drucker ausgewählt ist
3. Den Abschnitt **Optionen** aufklappen und auf **Druckeroptionen** klicken
4. Im erscheinenden Dialog bei **Optionengruppen**`Auftragszählung` wählen
5. Bei **Auftragszählung** den eigenen Kostenstellen-Code auswählen (z. B. `Code 39321`) → **OK**
6. Oben im Druckdialog auf **Voreinstellungen → Aktuelle Einstellungen als Voreinstellung sichern…** klicken
7. Einen Namen vergeben (z. B. `Kostenstelle 39321`) und auf **OK** klicken
Ab sofort steht das Preset im Druckdialog unter **Voreinstellungen** zur Verfügung der Code wird automatisch mitgeschickt.
---
## Weitere Kostenstellen-Codes
Soll ein weiterer Code im Treiber ergänzt werden, bitte bei der IT-Administration melden. Das erfordert eine neue Treiberversion.

View File

@ -1,65 +1,48 @@
#!/usr/bin/env python3 #!/bin/bash
"""CUPS filter for TA 3505ci - injects department code into PostScript stream.""" # CUPS filter for TA 3505ci - injects department code into PostScript stream.
import sys # Uses bash+awk only, no Python dependency.
if [ $# -lt 5 ]; then
echo "Usage: kyofilter job-id user title copies options [file]" >&2
exit 1
fi
def parse_options(options_str): OPTIONS="${5:-}"
options = {} INFILE="${6:-}"
for token in options_str.split():
if '=' in token:
k, v = token.split('=', 1)
options[k] = v
else:
options[token] = 'true'
return options
# Extract department code: KmManagment=MGxxxxx -> xxxxx
CODE=""
for OPT in $OPTIONS; do
if [[ "$OPT" =~ ^KmManagment=MG([0-9]+)$ ]]; then
CODE="${BASH_REMATCH[1]}"
break
fi
done
def get_account_code(options): # Pure passthrough when no code selected
km = options.get('KmManagment', 'Default') if [ -z "$CODE" ]; then
if km == 'Default' or not km.startswith('MG'): if [ -n "$INFILE" ]; then
return None cat "$INFILE"
code = km[2:] else
if not code.isdigit(): cat
return None fi
return code # raw digits, no zero-padding — matches kyofilter_E behaviour exit 0
fi
# Inject PostScript command before %%EndSetup (fallback: before %%Page:)
INJECT="($CODE) statusdict /setmanagementnumber get exec"
INPUT="${INFILE:--}"
def process_stream(lines, account_code): awk -v inject="$INJECT" '
if not account_code: BEGIN { injected = 0 }
yield from lines !injected && /^%%EndSetup/ {
return print inject
injected = 1
inject = f"({account_code}) statusdict /setmanagementnumber get exec\n".encode() }
injected = False !injected && /^%%Page:/ {
print inject
for line in lines: injected = 1
stripped = line.rstrip(b'\r\n') }
if not injected and (stripped.rstrip() == b'%%EndSetup' or stripped.startswith(b'%%Page:')): { print }
yield inject END { if (!injected) print "kyofilter: WARNING: no injection point found" > "/dev/stderr" }
injected = True ' "$INPUT"
yield line
if not injected:
sys.stderr.write("kyofilter: WARNING: no injection point found in PostScript stream\n")
def main():
if len(sys.argv) < 6:
sys.stderr.write("Usage: kyofilter job-id user title copies options [file]\n")
sys.exit(1)
options = parse_options(sys.argv[5])
account_code = get_account_code(options)
infile = open(sys.argv[6], 'rb') if len(sys.argv) > 6 else sys.stdin.buffer
try:
for chunk in process_stream(infile, account_code):
sys.stdout.buffer.write(chunk)
finally:
if len(sys.argv) > 6:
infile.close()
if __name__ == '__main__':
main()

18
install.sh Executable file
View File

@ -0,0 +1,18 @@
#!/bin/bash
set -e
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
echo "kydriv - Kyocera 3505ci Treiber installieren"
echo ""
sudo cp "$SCRIPT_DIR/ppd/TA3505ci_AS.ppd" \
/Library/Printers/PPDs/Contents/Resources/TA3505ci_AS.ppd
sudo cp "$SCRIPT_DIR/filter/kyofilter" \
/usr/libexec/cups/filter/kyofilter
sudo chmod 755 /usr/libexec/cups/filter/kyofilter
sudo chown root:wheel /usr/libexec/cups/filter/kyofilter
sudo launchctl kickstart -k system/org.cups.cupsd
echo "Fertig. Jetzt in Systemeinstellungen → Drucker & Scanner:"
echo " + → IP → Adresse eingeben → Verwenden: '3505ci (kydriv)'"

View File

@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
set -e set -e
VERSION="1.0.0" VERSION="1.0.1"
IDENTIFIER="de.kydriv.driver" IDENTIFIER="de.kydriv.driver"
PKG_NAME="kydriv-driver-${VERSION}.pkg" PKG_NAME="kydriv-driver-${VERSION}.pkg"
@ -15,12 +15,16 @@ cp filter/kyofilter \
installer/root/usr/libexec/cups/filter/ installer/root/usr/libexec/cups/filter/
chmod 755 installer/root/usr/libexec/cups/filter/kyofilter chmod 755 installer/root/usr/libexec/cups/filter/kyofilter
# Validate PPD (fail if it cannot be parsed at all) # Validate PPD — fail only on structural errors, not on known pre-existing issues
echo "Validating PPD..." echo "Validating PPD..."
cupstestppd installer/root/Library/Printers/PPDs/Contents/Resources/TA3505ci_AS.ppd 2>&1 \ UNEXPECTED=$(cupstestppd installer/root/Library/Printers/PPDs/Contents/Resources/TA3505ci_AS.ppd 2>&1 \
| grep -v "WARN\|8-Bit\|Übersetzung\|sollte\|Präfix\|übliches\|Seite\|Abschnitt" \ | grep "\*\*FAIL\*\*" \
| grep -v "FeedingEdgeConstraint\|kyofilter" \ | grep -v "FeedingEdgeConstraint\|kyofilter\|Übersetzungsstring\|Übersetzung") || true
| grep "FEHLER" && { echo "ERROR: PPD has unexpected errors" >&2; exit 1; } || true if [ -n "$UNEXPECTED" ]; then
echo "ERROR: PPD has unexpected structural errors:" >&2
echo "$UNEXPECTED" >&2
exit 1
fi
echo "PPD OK" echo "PPD OK"
# Build (unsigned if SIGN_IDENTITY not set) # Build (unsigned if SIGN_IDENTITY not set)