Review plant-id 0299fca — EXIF extraction, iNaturalist enrichment, geo-status layout #11
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What changed
Commit
0299fcaonplant-idmain.Features
1. EXIF GPS + datetime priority (new
extract_exif_geo_dt()inapp.py)GPSInfoIFD (tag 34853) andDateTimeOriginal(tag 36867) from the first uploaded image usingPillow'sImage.getexif()/.get_ifd()DateTimeOriginalpresent → used ascreated_atinstead oftime.time()try/except Exceptionwithlogger.debugon failure; always rewinds file to 0 infinallynot (-90 <= lat <= 90 and -180 <= lng <= 180)→ nulled2. iNaturalist read-only observation counts (new
/inat-obsroute)api.inaturalist.org/v1/observations?taxon_name=<name>&quality_grade=research&per_page=1total_resultsas observation countinat_cache(scientific_name PRIMARY KEY, observation_count, cached_at)table, 7-day TTL<a>tag) linking to iNaturalist species pagePlantID-App/1.0 (https://plants.tblindustries.be)3. Geo-status inline with Single/Batch toggle — pure CSS/HTML layout change. Low risk.
Files changed
app.py(+114 lines) —extract_exif_geo_dt(),/inat-obsroute,inat_cachetable init,INAT_API/INAT_CACHE_DAYSconstantsstatic/js/identify.js(+25 lines) —fetchInatCounts(), call inrenderResults()static/css/main.css(+10 lines) —.form-top-row,a.care-chipstylestemplates/index.html(+8 lines) —.form-top-rowwrapper,#geo-statusmovedAreas to review
EXIF extraction
Image.getexif()on untrusted upload — Pillow's EXIF parser has had CVEs historically (e.g. PIL 9.x decompression bombs in certain tag types). Isimg.verify()invalidate_image()sufficient to catch malformed EXIF, or does it not validate EXIF at all?get_ifd(34853)— does Pillow raise or silently return{}on malformed GPS IFD? The broadexcept Exceptioncatches it either way, but worth knowing.DateTimeOriginalcould be any date — past (photo from 2010) or future (malformed/spoofed).created_atordering in history would be wrong but not exploitable. Any concern with extreme timestamps in MariaDBFROM_UNIXTIME()queries in stats?iNaturalist API
taxon_nameparameter is passed directly fromrequest.argsto the external API as a query param (viarequests.get params=).requestsURL-encodes it automatically — any injection surface here?total_resultsfrom iNat JSON is trusted as an integer —.get("total_results", 0)with no bounds check before storing inINTcolumn. Max plausible value is ~10M for common species; MariaDBINTmax is ~2.1B. Fine.Not flagged (looks OK)
extract_exif_geo_dtalways rewindsfile_storageto 0 infinally— subsequentconvert_image()call gets the full file ✓inat_cacheusesscientific_name VARCHAR(255) PRIMARY KEY— same pattern asspeciestable ✓a.care-chiphref is constructed fromencodeURIComponent(r.scientific_name)— XSS safe ✓get_current_user()on/inat-obs✓