Introducing Snooker: Lightweight spam detection for blog comments

If you’ve been following the Magnificent Walrus dev logs, you’ll have read that I opted for the “Snook Algorithm” instead of adding an external dependency in the form of Akismet.

I’ve dubbed it the “Snook Algorithm” because as far as I know, it doesn’t have an official name. It’s the points-based system Jonathan uses (or perhaps used at this point) for filtering spam on snook.ca.

Continue Reading →

Baked commenting dev log n°1

After posting some initial thoughts about baked commenting yesterday, I spent some time making sure the data structure would work. After that, I started on development.

Status

I’m at a point where a comment can be POSTed from the version of this site I have running locally. That comment will then be parsed into JSON by the server, all of the expected metadata will be added to it, and it will be written to the site’s data folder.

Continue Reading →

Initial thoughts on baked commenting

A few posts ago I mentioned that I’ve been thinking about how commenting and static sites currently fit together.

There are already commenting services that can be used on static sites — services like Disqus and Muut — but I’ve yet to come across one that doesn’t require a large JavaScript file to not just work well but work at all. I want a system that won’t cripple performance. One were you load a page and the comments are already there, baked into the HTML.

I haven’t written any code yet, but I jotted down some thoughts on how this might work a couple of nights ago. What follows is an expanded version of those notes.

Continue Reading →

‘Programming still kicks my ass after doing it for over 40 years’ →

Dave Winer:

Programming still kicks my ass after doing it for over 40 years. I still learn new stuff, reach new heights, and know much less than I thought I did, all the time. It requires incredible concentration and memory and creativity to think of ways to do things that you can kind of describe in words but have no experience making work with ones and zeros.

It’s been many months since I last heard another programmer admit that we’re all just figuring this stuff out as we go along. I always appreciate it being said though, all the more so in this case due to Dave’s accomplishments over the years.

Whether everything’s rosy or I’m struggling to figure something out, it’s always reassuring to know that I’m on the right roller coaster.

How to show the full post unless there’s a user defined summary in Hugo

Hugo has two types of summaries: those automatically defined by Hugo and those manually defined by the user. What it doesn’t have is a way to know which type of summary each post has; something like an {{ .IsUserDefined }} boolean.

On the home page of this site I like to show the full contents of a post by default. If a post has a manually defined summary however, I show that instead with a “read more” link.

Accomplishing this in Hugo is a little more involved than it is in Jekyll, and as far as I can tell nobody has documented how to do it. Let’s fix that.

Continue Reading →

So your NGINX’s http to https redirect isn’t working?

Whilst configuring the Linode box running this site’s new setup, I eventually abandoned a bug in my NGINX config that was proving problematic.

The issue was this: Though port 80 had the following settings in its server block, the Observatory’s tests were telling me that http traffic wasn’t being redirected to https.

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    server_name elliotekj.com www.elliotekj.com;
    return 301 https://$host$request_uri;
}

This evening I revisited said bug with fresh eyes and, as happens so often in software development, quickly saw the mistake I had made: I had placed the SSL configuration options outside of the server block for port 443.

Simply moving ssl on and company into the correct server block — the one for port 443 — turned the http to https redirect test green.

Google Drive and Hugo: The new publishing setup for this blog

Back in April I wrote a post about moving this site from Jekyll to WordPress. The move was prompted by Jekyll’s poor compilation performance and the restrictions a git-centric workflow imposes on a blog (namely: editing on the go).

Ultimately unsatisfied with WordPress, I’ve changed how this site is pieced together again. This time ’round opting for a setup I’d had in the back of my mind for a while but had never experimented with. Before we get into the good stuff though, let’s get the basics out of the way.

Continue Reading →

How to find an available TCP port in Rust

Let’s say you’re writing your own deployment solution in Rust. The basic flow you have in mind might go something like this:

  1. Pull the latest commits down onto the server
  2. Build the app (if it’s written in a compiled language)
  3. Start the app
  4. Move traffic to the new version of the app
  5. Remove the old version

The problem is that you’ve already got the old version of the app running so the new version will fail to start because the port it requires is already taken. What you need is a way to find a port that’s available, tell the app to start on that port, and then redirect traffic upstream to it.

Continue Reading →

Receiving 3rd party webhooks on a locally hosted web app

I spent today integrating Paddle into Readership. Readership isn’t hosted anywhere publicly available yet, so I needed a way to feed Paddle’s webhooks to a URL on localhost.

Enter UltraHook. Having used it for a few hours, I really can’t fault it. It’s lightweight, it’s stable and it just works.

Continue Reading →

Proof of concept cyberattacks →

Andy Greenberg has written an excellent piece for Wired which looks at Russia’s quickly-becoming-annual proof of concept cyberattacks on the Ukrainian power grid:

Noting the precise time and the date, almost exactly a year since the December 2015 grid attack, Yasinsky felt sure that this was no normal blackout.

[…]

Yasinsky knows by now that even as he’s analyzing last year’s power grid attack, the seeds are already being sown for 2017’s December surprises.

Failing to plan is planning to fail. They planned:

Once the circuit breakers were open and the power for tens of thousands of Ukrainians had gone dead, the hackers launched another phase of the attack. They’d overwritten the firmware of the substations’ serial-to-­ethernet converters—tiny boxes in the stations’ server closets that translated internet protocols to communicate with older equipment. By rewriting the obscure code of those chunks of hardware—a trick that likely took weeks to devise—the hackers had permanently bricked the devices, shutting out the legitimate operators from further digital control of the breakers.

Concepts are proven for a reason. I suppose only time will tell if the reason this time ’round is to deter other nations or to engage them:

A grid attack on American utilities would almost certainly result in immediate, serious retaliation by the US. Some cybersecurity analysts argue that Russia’s goal is simply to hem in America’s own cyberwar strategy: By turning the lights out in Kiev—and by showing that it’s capable of penetrating the American grid—Moscow sends a message warning the US not to try a Stuxnet-style attack on Russia or its allies, like Syrian dictator Bashar al-Assad. In that view, it’s all a game of deterrence.

[…]

But for those who have been paying attention to Sandworm for almost three years, raising an alarm about the potential for an attack on the US grid is no longer crying wolf.

Handling optional trailing commas in macro_rules!

Here’s a nice little trick I discovered whilst dissecting the router! macro for iron-middlefiddle. You can optionally allow trailing commas in a macro with the following:

$(,)*

Continue Reading →

Introducing iron-middlefiddle: Route specific middleware made easy in Iron

Route specific middleware is a fairly common need in web apps. As soon as you introduce something like authentication into the mix, you’ll probably want a way to apply middleware to routes you only want users to be able to access if they’re logged in.

As things stand, route specific middleware in Iron is a repetitive and messy business, which is where iron_middlefiddle comes in. It provides a macro which turns the tricky into the trivial, allowing you to add middleware to any number of routes within a Router easily.

Continue Reading →

DeltaE 0.2.0

In the wee hours of this morning I released DeltaE 0.2.0, my Rust implementation of the CIEDE2000 colour differentiation algorithm. The update brings 2 main improvements:

  1. A new from_rgb method which will handle the conversions to LAB values for you and return the colour difference.

  2. An extensive test suite based on the data in Table 1 of “The CIEDE2000 Color-Difference Formula: implementation Notes, Supplementary Test Data, and Mathematical Observations”

With the addition of those tests, the library has reached a point where I feel comfortable in the thought of others using it. If no issues arise in the next month or so, I’ll bump this release to 1.0.0.

You’ll find DeltaE 0.2.0 in the usual places: crates.io & GitHub.

Setting Iron’s response MIME type with middleware

If your JSON API is powered by Iron, you may well have a lot of duplicate code that sets the MIME type of each Response. Something like this:

use iron::mime::Mime;

pub fn example_handler(req: &mut Request) -> IronResult<Response> {
    let mime = "application/json".parse::<Mime>().unwrap();

    // …

    Ok(Response::with((mime, status::Ok, some_json)))
}

As we can see above, the code for setting a MIME type is generic and doesn’t need anything except a Response to modify. It is therefore a prime AfterMiddleware candidate, which once implemented will remove the need for the code repetition in each and every one of our routes’ handlers. Here’s a very brief AfterMiddleware description from the docs:

AfterMiddleware receive both a Request and a Response and are responsible for doing any response post-processing.

Continue Reading →

Now in beta: DeltaE – a library for quantifying the difference between two colors

I have just published the first beta of my first public crate. DeltaE is a pure-Rust implementation of the International Commission on Illumination’s CIEDE2000 algorithm.

The goal of the algorithm is to put a number on the difference our eyes perceive when looking at two colours. If you’re interested in the details, then I recommend this rundown. In short though:

  • If the returned value is less than 1, then the human eye can’t distinguish between the two colours.
  • If the returned value is greater than 1, then we humans can see a difference when presented with the two colours.
  • The greater the return value, the more difference the human eye perceives.

This crate was written to be used in a project I’m currently tinkering with. It’ll come out of beta once I, and hopefully others, have used it some more and I have improved the test suite.

It is entirely based on Zachary Schuessler’s Javascript implementation of the algorithm. He is also the author of the aforementioned rundown so a huge thank you goes out to him for his work.

Jimmy Cuadra’s “The highs and lows of Rust” →

Back in February 2016, Jimmy Cuadra wrote a post about “The highs and lows of Rust”. He too came to Rust from dynamic web-focused languages and he too “clicked” with it:

Rust has a reputation of having a much higher learning curve [than Go], which of course affects its popularity. I really haven’t been able to understand why, but somehow Rust just clicks with my mental model of programming […]

I’ve been wondering what helped make Rust click for me. The best answer I have come up with is that its basic function structure is relatively familiar to anyone who’s worked with Javascript. function becomes fn, and the parameter and return types are typed but other than that it’s more or less the same. I think that that familiarity with such a core and highly used part of the language helps a lot.


The low points he addresses are interesting to look back on a year and a bit down the line. Serde has matured a lot, having recently reached 1.0.0, passed the 2 million downloads mark, reached number 9 on the “most downloaded” list and become the favoured serialization crate of the core Rust team who have deprecated their own serialization crate.

As for cryptography, all of the popular crates still rely on C libraries. There are pure implementations for things like argon2 and rust-crypto is “mostly pure” but there’s still plenty of work to be done in that domain.


His thoughts once again echo my own when it comes to Rust’s usefulness:

While the language is described as a “systems language” and is generally intended for lower level applications, my domain is in higher level applications, and I’ve found Rust to be just as suitable and strong for my purposes. It really is a fantastic general purpose language.

Compiling to a binary, and thus taking away the need to setup a whole environment to run Ruby, Python, etc. programs, adds a level of portability and flexibility that (amongst other reasons) has made Rust my go-to even for for day-to-day scripts.

Open fugitive’s diff view for each modified file

git status has a --porcelain option which formats the output in a way that’s easy to parse in scripts. It can, for example, be combined with awk to list the path to each modified file like so:

git status --porcelain | awk '{print $2}'

Continue Reading →

A workaround for box-shadow not passing through to the inside of a border

This is a problem more easily shown than explained. Take the following image:

It’s an indicator — the sort you’d find on any colorpicker — with a shadow. It seems simple enough, but how would you build it in CSS?

Continue Reading →

How to seed a Postgres database with Knex

Diesel is my ORM & query builder of choice for Rust projects, it doesn’t provide a way to seed a database though. I went looking for a seeding crate and came up empty handed, so settled on looking for a Node package instead. Though even NPM had a surprisingly limited number options, I found Knex which has served me well so far.

Though we’ll just be using Knex’s seeding functionality in this post, it too is a fully functional query builder. Though I haven’t used it for query building, it’s syntax looks pretty nice and I would certainly consider it for any future Node projects.

Let’s get cracking then. I’m going to assume that you already have Postgres setup on your machine.

Continue Reading →

Notes from building a WordPress theme in 2017

It’s been a good many years since I last put a WordPress theme together. I spent some time last weekend doing just that however, owing to the poor performance of WordPress’ default “Twenty Seventeen” theme which I had been using since switching back.

Over the course of the past 14 years, WordPress has grown to become the content management system of choice for a huge percentage of websites. With such a large reach, each decision has the potential to impact vast quantities of people, which is why I find the amount of stuff WP shoves into a webpage by default disturbing.

Continue Reading →