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.