← Terug naar projects
7 min
Garen Collectie: een garen-inventaris-app voor mijn moeder

Garen Collectie: een garen-inventaris-app voor mijn moeder

Een Android-app waarmee mijn moeder haar Gütermann naaigaren-collectie bijhoudt. De app combineert een volledige catalogus van alle 400 garenkleuren, gescraped van een Nederlandse fournituren-webshop, met een persoonlijke inventaris, zodat ze altijd weet welke kleuren ze al heeft voordat ze nieuwe koopt.
  • Kotlin
  • Android
  • Jetpack Compose
  • Python

Inhoudsopgave

  1. Het probleem: 400 kleuren en geen overzicht
  2. De oplossing: catalogus plus inventaris
  3. Een groeiende collectie beheren
  4. De data ophalen: 400 kleuren scrapen
  5. Het technische fundament
  6. Waarvoor ik het heb gebouwd
  7. Huidige status

Mijn moeder naait veel, en in de loop der jaren heeft ze een flinke collectie Gütermann naaigaren opgebouwd. Het probleem is herkenbaar voor iedereen met een hobby vol materialen: in de winkel wist ze nooit meer welke kleuren ze al thuis had liggen. Zo kocht ze telkens dubbele kleuren die ze al bezat en miste ze juist de kleuren die ze echt nodig had. Een handgeschreven lijstje hield het nooit lang vol, want Gütermann verkoopt zo’n 400 kleuren en veel daarvan lijken sprekend op elkaar.

Ik wilde haar iets beters geven dan een notitieblok, dus bouwde ik Garen Collectie, een kleine Android-app die één ding goed doet: het complete Gütermann-kleurenpalet tonen en precies bijhouden welke klosjes ze in huis heeft.

Het probleem: 400 kleuren en geen overzicht

Het naaigaren van Gütermann is er in ongeveer 400 tinten, verkocht in twee klosmaten: kleine klosjes van 200m en grote klosjes van 1000m. De kleuren worden aangeduid met een nummer, niet alleen een naam, en veel ervan zijn subtiele variaties op dezelfde tint. Zonder het klosje in je hand is het echt lastig om “muisgrijs” van “donkergrijs” te onderscheiden, of om te onthouden of je nu 615 of 635 hebt.

Voor wie garen gaat kopen, levert dat twee terugkerende frustraties op: een kleur kopen die je al hebt, of voor het rek staan zonder te weten of een kleur die je nodig hebt nog in je collectie ontbreekt. Wat ze nodig had, was één overzicht van het hele assortiment, met een duidelijke markering bij de kleuren die ze al bezit.

De oplossing: catalogus plus inventaris

De app heeft twee schermen. Het eerste is de volledige catalogus van alle 400 Gütermann-kleuren, elk met het officiële nummer, de Nederlandse kleurnaam en een foto van het echte klosje. Het tweede is haar persoonlijke inventaris, de selectie die ze bezit, met de aantallen die ze van elke kleur heeft.

De catalogus, het kleurdetailscherm en de persoonlijke inventaris

De catalogus, het kleurdetailscherm en de persoonlijke inventaris.

Door op een kleur te tikken opent een detailscherm waarin ze kan vastleggen hoeveel kleine (200m) en grote (1000m) klosjes ze heeft, en een kleur kan markeren als bijna op, zodat die op de volgende boodschappenlijst belandt. Het inventarisscherm vat de hele collectie vervolgens in één oogopslag samen: hoeveel kleuren, hoeveel klosjes, en welke bijna leeg zijn.

Het resultaat is dat de vraag “heb ik deze kleur al?” nu een direct antwoord heeft in haar broekzak, en de vervolgvraag “welke raken bijna op?” net zo goed.

Een groeiende collectie beheren

Een grote collectie kleur voor kleur bewerken wordt al snel omslachtig, dus het inventarisscherm ondersteunt multiselectie. Ze kan meerdere kleuren tegelijk selecteren en ze allemaal als bijna op markeren zodat ze op de boodschappenlijst belanden, ze weer als aangevuld markeren, of ze in één keer verwijderen.

Omdat alles op het toestel staat, heb ik ook een eenvoudige back-up en herstel toegevoegd via het menu. De hele inventaris kan naar een JSON-bestand geëxporteerd worden en later teruggezet, of door de huidige collectie te vervangen of door samen te voegen, waarbij de aantallen bij elkaar worden opgeteld. Een nieuwe telefoon of een herinstallatie betekent zo nooit dat de lijst met de hand opnieuw opgebouwd moet worden.

De data ophalen: 400 kleuren scrapen

Een app als deze is alleen zo goed als zijn catalogus, en ik had geen zin om 400 kleuren en hun foto’s met de hand in te typen. Gütermann publiceert geen nette, machine-leesbare kleurenlijst, dus ik ging op zoek naar een bron die alle kleuren al overzichtelijk had staan, met een consistente foto per tint.

Die vond ik bij fourniturenkraam.nl, een Nederlandse fournituren-webshop die elke Gütermann-kleur als apart product verkoopt, compleet met een nette studiofoto van het klosje. De webshop draait op Shopify, en dat bleek de sleutel die het scrapen eenvoudig en netjes maakte: elke Shopify-collectie heeft een gepagineerde JSON-feed op /collections/<handle>/products.json. Daardoor hoefde ik nooit broze HTML te parsen, maar kon ik de gestructureerde productdata rechtstreeks uitlezen.

De losse klosjes van 200m staan allemaal in één collectie, en elke producttitel bevat precies de twee gegevens die ik nodig had:

"Gutermann naaigaren | 200m | 000 zwart"   ->  code "000", naam "zwart"
"Gütermann garen | 200m | 100 donker mint" ->  code "100", naam "donker mint"

De scraper blijft daardoor piepklein. Hij pagineert door de JSON-feed, haalt de kleurcode en Nederlandse naam uit het deel van de titel na de laatste |, en downloadt de eerste productfoto. Dat is in essentie het hele ding:

while products := json.loads(get(FEED.format(page)))["products"]:
    for product in products:
        code, _, name = product["title"].split("|")[-1].strip().partition(" ")
        if not code.isdigit() or not product["images"]:
            continue  # sla de kleurenkaart en alles zonder foto over
        (ASSETS / f"images/{code}.jpg").write_bytes(get(product["images"][0]["src"].split("?")[0]))
        catalog[code] = {"code": code, "name": name, "image": f"images/{code}.jpg"}
    page += 1

De uitvoer is één gutermann-colors.json-bestand plus een map met afbeeldingen, beide rechtstreeks weggeschreven in de assets/-map van de app, zodat de app ze offline inleest zonder enige backend. Twee kleine details houden het robuust: de parser slaat elke titel over waarvan het laatste deel niet met een cijfer begint (zo valt het product van de kleurenkaart af), en hij stuurt een eerlijke gutermann-color-scraper/1.0 User-Agent mee, omdat de botbeveiliging van de webshop een 403 geeft bij een vervalste browser-variant.

Het script staat in de repo, zodat de catalogus opnieuw gegenereerd kan worden zodra de webshop een kleur toevoegt of hernoemt. Het gebruikt alleen de Python-standaardbibliotheek, dus er valt niets te installeren:

python3 scripts/scrape_gutermann_colors.py

Het technische fundament

Garen Collectie is een native Android-app, geschreven in Kotlin met Jetpack Compose en Material 3 voor de interface. De architectuur is een rechttoe rechtaan MVVM-opzet met een repository-laag. De persoonlijke inventaris staat lokaal in een Room-database (SQLite), terwijl de kleurencatalogus uit de meegeleverde JSON wordt geladen en met Gson wordt geparset. De klosfoto’s komen uit de assets van de app via Coil. Alles draait op het toestel, zonder server en zonder account, wat past bij een app voor één gebruiker die gewoon betrouwbaar moet werken in een stoffenwinkel met slecht bereik.

Waarvoor ik het heb gebouwd

Dit project ging niet om de techniek. Mijn moeder is de enige gebruiker, en het succes laat zich simpel meten: ze koopt geen garen meer dat ze al heeft en raakt niet meer door de kleuren heen die ze het meest gebruikt. Het bouwen was een mooie aanleiding om een klein, compleet Android-project van begin tot eind te doen, van het scrapen van de brondata tot een verzorgde Compose-interface, maar de echte beloning is dat het echt nuttig is voor iemand die me dierbaar is.

Huidige status

De app is af en wordt regelmatig gebruikt. De catalogus dekt het volledige Gütermann-assortiment, de inventaris doet precies wat nodig is, en de scraper staat in de repo zodat de kleurenlijst ververst kan worden zodra de bronwinkel verandert. Wil je hem zelf gebruiken, dan kun je de app downloaden via de releases-pagina.