Skip to content
sc0VuPublic

About

A fast cli to search house on funda.nl.

Resources

Stars

1 star

Watchers

1 watching

Forks

Repository files navigation

funda-cli v0.1

Project website: https://sc0vu.github.io/funda-cli/ (GitHub Pages; see site/README.md for setup).

A lightweight local CLI for personal Dutch housing research.

The first version deliberately separates three concerns:

  1. Discovery — read listing URLs from Funda sitemaps.
  2. Enrichment — optionally fetch structured details through an adapter.
  3. Search — query a local SQLite database without repeatedly hitting a remote service.

The bundled enrichment adapter calls Funda API, thanks for pyfunda. Funda does not provide a public consumer developer API; internal endpoints may change and use may be subject to Funda's terms. Keep request volume low and use this for personal research.

Requirements

  • Go 1.25+

Build

go mod tidy
go build -o funda ./cmd/funda

First run

Discover rental listings from the sitemap using a browser-profile Go HTTP client:

./funda sync --category rent --profile chrome

Available profiles are chrome, firefox, safari, edge, ios, and chrome_android. The transport reproduces browser-like TLS/HTTP behavior, but the CLI does not implement CAPTCHA/challenge solving, proxy rotation, or retries intended to defeat an explicit access restriction.

Review the references discovered by the sitemap with the same search command used for enriched listings:

./funda search --city utrecht --category rent

Only show references that do not have detail data yet:

./funda search --city utrecht --category rent --unfetched

Show the full Funda URL as well:

./funda search --unfetched --url

Unfetched rows show - for price, area, bedrooms, and energy label. These fields become available after detail enrichment.

Enrich a small batch:

./funda enrich --city utrecht --category rent --limit 20

Now search locally by structured fields:

./funda search \
  --city utrecht \
  --category rent \
  --max-price 2200 \
  --min-area 50 \
  --fetched

View one listing:

./funda view 12345678

Database

Default database: ./funda.db

Change it with:

export FUNDA_DB="$HOME/.local/share/funda/funda.db"

Tables:

listing_refs   sitemap-discovered IDs, URLs, city, category, lastmod
listings       API-enriched price, area, rooms, energy label, etc.

Why sitemap + local DB?

The CLI does not make a remote search request every time you type funda search. The normal workflow is:

sitemap -> listing_refs -> optional detail enrichment -> SQLite -> local search

This makes the user-facing search fast and keeps remote requests explicit and cacheable.

Next milestones

  • Throttle the request.
  • Detect changed sitemap lastmod values and refresh only stale details.
  • Add --refresh to search/view.
  • Add JSON output for shell pipelines.
  • Add saved searches and favorites.
  • Add a Bubble Tea TUI.
  • Add provider abstraction for other Dutch housing sources.

MVGM integration

MVGM / ikwilhuren.nu support has been added. See MVGM.md.

funda sync --source mvgm --city utrecht
funda enrich --source mvgm --city utrecht --limit 50
funda search --source mvgm --city utrecht --fetched --income 60000 --savings 50000

Terminal map

Fetched listings with latitude/longitude can be rendered as a Unicode Braille map using live OpenStreetMap data from the Overpass API:

./funda map --source funda 12345678
./funda map --source mvgm --radius 800 --width 100 --height 30 some-listing-id
./funda view --source funda --map 12345678

The renderer requests nearby roads, buildings, waterways, water, parks, and grass areas and rasterizes their real OSM geometry into a 2x4-dot Braille canvas per terminal cell. The property is marked by a cross at the center. --radius is in meters. Map rendering requires network access; normal local search/view behavior remains offline unless --map or the map command is used.

Games (experimental, offline)

Funda CLI includes two local games, each supporting buy and rent:

  • Guess the Price: Estimate the advertised asking price or monthly rent. Prices and source listing URLs are hidden until you submit your guess. Optional Detective hints cost 100 points.
  • House Hunter: Explore cached properties, schedule viewings, perform fictional inspections, and make simulated buying offers or rental applications. No real offers or applications are sent.

Games use enriched listings already stored in the local SQLite database. Run sync and enrich first; games do not fetch fresh property data.

# Five-round guessing games
./funda game guess --mode buy --city utrecht
./funda game guess --mode rent --city utrecht --detective

# Daily guessing challenges (UTC-based seed)
./funda game guess --mode buy --city utrecht --daily
./funda game guess --mode rent --city utrecht --daily

# House Hunter: buying and renting
./funda game hunter --mode buy --city utrecht --budget 375000
./funda game hunter --mode rent --city utrecht --income 4500 --income-multiplier 3

Daily challenges

--daily generates a deterministic seed from the UTC date, city, game, and mode. This does not guarantee identical properties for different players: rounds are selected from each player's local database. Scores should only be compared when datasets match. There is no online leaderboard or globally synchronized daily challenge.

Saving progress and scores

Completed game results are saved to a local history file by default. House Hunter also checkpoints progress so you can quit and resume later.

./funda game hunter --mode buy --city utrecht
./funda game hunter --mode buy --city utrecht --resume
./funda game hunter --mode buy --city utrecht --restart

# Disable local saving, or override its location
./funda game guess --mode buy --no-save
./funda game guess --mode buy --history-file ./game-history.json
./funda game hunter --mode buy --save-file ./hunter-save.json

The default history location is ~/.local/share/funda/game-history.json on Linux, ~/Library/Application Support/funda/game-history.json on macOS, and %AppData%\funda\game-history.json on Windows. House Hunter saves beside the default history file. Resume validates the saved property sequence and asking prices; if the local database has changed, restart the game instead.

Controls and images

In House Hunter, use v for viewing, i for a fictional inspection, e for cached details, a for a simulated bid/application, s to skip, and o to open the original listing in a browser. The simulation has a 20-turn limit.

Optional photo URLs can be supplied using --photos-file; the game currently displays links, not native inline photos. --image-mode auto|kitty|iterm2|link|none selects the image capability preference, but actual inline listing-image integration is not yet implemented. Automatic photo extraction is deferred.

Test and limitations

go test ./...
go test -race ./...
go build -o funda ./cmd/funda

Inspections, rival bids, and rental-selection outcomes are fictional. They must not be used to assess actual property condition, valuation, or application chances. The complete application test suite still requires verification in the project's configured Go environment. See GAMES.md for more details and RELEASE_CANDIDATE.md for release status.

Property monitoring (experimental)

The check and watch commands fetch/sync source listings, refresh missing or stale property details, match configured watches and deliver notifications. They use the same SQLite database as the existing CLI. Configuration is JSON (see examples/monitor.json). Environment variables hold credentials; do not store Telegram bot tokens in the config file.

export TELEGRAM_BOT_TOKEN='...'
export TELEGRAM_CHAT_ID='...'
funda notify test --config examples/monitor.json --provider telegram_personal
funda check --config examples/monitor.json
funda watch --config examples/monitor.json

Use funda check from cron or a systemd timer; watch is a long-running process. Do not run concurrent checks against the same database. The first successful check establishes a baseline when notify_existing is false. Each watch can name multiple providers, and delivery status is stored per watch/property/provider. Supported providers: Telegram and HTTPS JSON webhook. SMTP/email is planned, not yet implemented. A check refreshes up to enrich_limit missing/stale properties per watch, so a large initial backfill may require several checks. The crawler relies on source visibility and cannot guarantee immediate discovery. Check source terms and permitted reuse before running a public alert service.

Example cron entry (adjust binary and config paths):

*/10 * * * * /usr/local/bin/funda check --config /home/user/.config/funda/monitor.json

About

A fast cli to search house on funda.nl.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages