Cody Woolaver

Software engineer portfolio

This is my personal site: part portfolio, part project notebook, and part place to keep useful little web tools alive. I'm updating it into a clearer home for my work, my background, and the experiments I want to keep building over time.

Site Update · June 3, 2026

Building my own contact form spam check

While updating the contact form, I wanted a small barrier that fit the site instead of dropping in a large third-party widget. I could have used reCAPTCHA and moved on quickly, and for some products that would be the right call. For this site, part of the fun was treating the form as a small design problem: how far could I get with a focused, understandable solution that I owned end to end?

The weak spot was obvious. If the text is printed directly into the HTML, a basic script can collect it almost as well as a person can. So the server now creates a simple arithmetic check, breaks the characters into shuffled fragments, and stores those fragments in the markup in a lightly encoded form. The browser puts the text back together for visitors, while the raw page source is less useful to a drive-by bot.

The important part still happens on the server. The hidden token includes the issue time, a random nonce, and a keyed digest of the expected answer. When the form is submitted, the server checks the signature, rejects stale tokens, and compares the submitted value with the signed digest. That means the page can display the check without trusting the browser to decide whether it was solved.

This is not meant to be a universal anti-spam system. A determined attacker could inspect the JavaScript and automate around it. But for a personal contact form, the goal is more practical: avoid the simplest automated submissions, keep the experience quiet for real visitors, and learn from building the moving parts myself instead of immediately handing the job to another service.

Site Update · June 2, 2026

Adding practical local services

I added a new page for local services outside of software: hauling, dump trailer work, flatbed trailer work, small-acreage tractor help, cleanup, and light chainsaw services around the Nashwaak Valley and Greater Fredericton area.

As much as I have a passion for building good technology, there is something deeply satisfying about using my hands to finish practical work. Moving material, clearing a property, preparing a garden area, or helping someone get a small job unstuck has a directness that I value. The work is visible, useful, and grounded in the place I live.

The new services page gives those jobs their own home on the site, with photos of the equipment, a clear description of what I can help with, and a simple way to call when someone wants to talk through whether a job is a good fit.

View local services

Site Update · May 30, 2026

Taking image hosting back home

The ShareX project started from a practical itch: I wanted to stop leaning on public image-hosting services that I do not own. Those services are convenient until links rot, policies change, files get harder to move, or I simply want to know exactly where my screenshots and small uploads live. Wiring ShareX into this site gives me short public links on infrastructure I control.

The project ended up being more than an upload endpoint. It accepts screenshots, files, and text uploads behind a bearer token, writes incoming files through temporary storage, detects common image, video, and text types, and stores enough metadata to keep the original filename, size, media kind, and generated public path around. Public links serve images, videos, and text inline, while unknown files download instead.

Caching was one of the details that mattered. Public files get cache headers so repeated views are cheap, while responses also set nosniff and noindex so the links behave more like unlisted personal uploads than a searchable gallery. The admin side is where the system becomes manageable: I can upload manually, copy the custom ShareX config, sort by creation time, last view, or download count, see thumbnails and metadata, and mark files for deletion without immediately losing the bytes on disk.

The less glamorous parts were the real challenge: generating short URLs without collisions, keeping storage stable across Docker restarts, handling large uploads without reading everything into memory, tracking last-viewed and download counts without turning it into a full analytics system, and making deleted links stop resolving while still leaving room for recovery. It is small infrastructure, but it is mine, and that was the point.

Site Update · May 25, 2026

Bringing this place back up to date

I have been refreshing this site from the inside out. Some of the work is visible, like the cleaner home and about pages and the Minesweeper project. A lot of it is quieter: updated dependencies, a more reliable asset build, Dockerized deployment, migrations, safer defaults, and a clearer path for keeping the app maintained.

The site is still intentionally small. It is a Pyramid application I have kept around because I like having a personal web space that is not only a profile page. I want it to be a place where I can show the practical software I build, write short notes about the decisions behind it, and leave useful projects online long enough for them to become part of the story.

I used modern coding tools here and there while doing the cleanup, but the point of the update is not the tooling. The point is to make the site feel more like mine again: easier to run, easier to change, and honest about where things are still in progress.

Over time I plan to add more project writeups, more detail about my work history, and a few small interactive pieces that are fun to use instead of just read about. For now, this is the start of turning the site from a placeholder back into a living portfolio.