A collection of standalone Python scripts for managing a sports card selling operation.
Sends a daily iMessage via Claude API and macOS Shortcuts. Runs on cron.
python ai_text_me.py # send daily text (fact, haiku, history, science)
python ai_text_me.py --card # send a random card photo with a player fact
python ai_text_me.py --test # dry run: print card filename + caption, no sendCron schedule:
- 7:00am daily — daily text
- 9:15pm Mon/Thu/Sat — card + fact
Card facts rotate across 10 categories (early life, season stats, records, quirky stories, etc.) and track the last 20 facts per player in ~/.card_facts_history.json to avoid repeats. Edit that file directly to seed or remove facts.
Requires: anthropic, typer
Credentials: ANTHROPIC_API_KEY env var or .anthropic-api-key.txt in repo root or ~
Detects the destination country from a shipping label photo and copies an appropriate iMessage to the clipboard.
python international_shipping.py # uses newest image in ~/Downloads
python international_shipping.py photo.heic # specific file
python international_shipping.py --plural # use plural phrasingConverts the image via sips, sends to OpenAI Vision to detect the country, renames the output as YYYY-MM-DD_COUNTRY.jpg in /Volumes/Dutton 2TB/Sales/shipping/, and moves the original to processed/ if confidence > 0.75.
Requires: openai, pyperclip
Credentials: OPENAI_API_KEY env var or .openai-api-key.txt
Tracks eBay purchases by scanning Gmail. Persists state to ~/.ebay_tracker.json.
python ebay_tracker.py # interactive mode (offline, reads state file)
python ebay_tracker.py --cron # fetch Gmail, update state, mark read
python ebay_tracker.py --refresh # fetch then go interactive
python ebay_tracker.py --init # one-time deep scan of all eBay emailsCredentials: Gmail OAuth via ~/.gmail-mcp/gcp-oauth.keys.json, token cached at ~/.gmail-mcp/ebay-tracker-token.json
Minimal starter for the eBay Developer API. Fetches an app token and searches public listings through the Browse API.
python ebay_api_demo.py token
python ebay_api_demo.py search "Nikola Jokic Select"
python ebay_api_demo.py search "Caitlin Clark Prizm" --limit 10
python ebay_api_demo.py search "Michael Jordan Fleer" --sandboxCredentials: EBAY_CLIENT_ID and EBAY_CLIENT_SECRET in env vars or .env
Bulk-updates My Cost, Source, My Notes, and Date Acquired on app.collectors.com for cards in a CSV matched by PSA cert number.
python collectors_update.py # update all cards in CSV
python collectors_update.py --dry-run # print plan without savingCSV path is hardcoded to My Collection YYYYMMDD.csv in the repo root — update the filename when exporting a new one. Uses Playwright + playwright-stealth to bypass Cloudflare.
Requires: pip install playwright playwright-stealth python-dotenv and playwright install chromium
Credentials: PSA_USER and PSA_PASS in .env
Downloads front and back card images from PSA's public API by cert number.
python psa_download.py fetch <cert_number>
python psa_download.py fetch <cert> --out-dir /path/to/dir --verboseUses curl by default (bypasses WAF) with requests as fallback. Downloads and resizes images to 75% at quality 65.
Credentials: --token arg, or .psa-token.txt in repo root or ~/.psa-token.txt
Wraps psa_download.py to process a PSA collection export in daily batches and keep download state in JSON.
python psa_dutton.py run
python psa_dutton.py status
python psa_dutton.py install-cronDefault behavior:
- reads
My Collection CSV - All.csvfrom the repo root - writes all downloaded images directly into
psa_cron_output/ - tracks progress in
/Users/geoff/code/card_stuff/.psa_dutton_state.json - installs a daily
7:00amcron job that downloads40pending certs per run - waits
2seconds between cards by default
Merges card front/back photos into a side-by-side grid image.
python card_merge.py card*.jpg # merge odd-numbered files (fronts)
python card_merge.py -e card*.jpg # merge even-numbered files (backs)Adjusts the merged image's timestamp so it sorts as the newest file.
Auto-rotates and crops card images.
python cropper.py -i "*.jpg" # process all JPGs
python cropper.py -i file.jpg -o # overwrite in placeCreates and prints the current month's sales directory path.
python sale.py # current month
python sale.py --date 2024-03 # specific monthA local HTML tool for searching cards. Open directly in a browser.
This repo contains both a newer SwiftUI macOS app and older PyQt5 desktop apps.
Native macOS SwiftUI app that combines two workflows:
Card Namer: batch-renames card image pairs using OCR + OpenAIeBay Titles: generates optimized eBay titles for checked card pairs
Directory sources:
Incoming (⌘1)->/Users/geoff/incoming cardsCollection (⌘2)->/Volumes/Dutton 2TB/Cards/MixCurrent Sales (⌘3)-> current~/Sales/YYYY/MMor$SALES_ROOT/YYYY/MM, matchingsale.py
Current behavior:
- active image source is shown above the left card list
- eBay title results open in a separate window when generation finishes
- if
description.csvexists in the active source folder,Display Titlesreopens that results window from disk
Build for local use:
- Open
Neddog_Cards_App/Neddog Cards.xcodeproj - Select the
CardNamerscheme andMy Mac - Use
Product > Build - Use
Product > Show Build Folder in Finder - Copy the built
CardNamer.appsomewhere stable such as/Applications
For local-only use on your own Mac, you do not need Distribute App. The archive/distribution flow requires signing team setup and is only needed for broader distribution.
Credentials: OPENAI_API_KEY via the app Settings UI
Older PyQt5 app for batch-renaming card image files using OCR (pytesseract) + OpenAI Vision.
Credentials: OPENAI_API_KEY env var or .openai-api-key.txt
Older PyQt5 app for generating optimized eBay listing titles for cards.
PyQt5 app that tracks physical mail with TinyURL-shortened tracking links.
PyQt5 app that prints envelopes with address formatting.
Helper scripts for filling in missing purchase cost data on cards.
search_costs.py— searches Gmail for eBay purchase emails matching cards inmissingcost.csv, extracts price + shipping + tax, writesmissingcost_with_email_total.csvmatch_ebay_report.py— matches cards inmissingcost_with_email_total.csvagainst an eBay purchase history HTML export
| Script | Credential | Where |
|---|---|---|
ai_text_me.py |
ANTHROPIC_API_KEY |
env var or .anthropic-api-key.txt |
international_shipping.py, Card Namer App |
OPENAI_API_KEY |
env var or .openai-api-key.txt |
psa_download.py |
PSA token | --token arg or .psa-token.txt |
ebay_tracker.py, psa_update/search_costs.py |
Gmail OAuth | ~/.gmail-mcp/gcp-oauth.keys.json |
collectors_update.py |
PSA_USER, PSA_PASS |
.env in repo root |