For this Xmas week I'll be playing with a BBC Micro:bit. Check out my projects on the dedicated stream.
Alex and I are getting married later on this year, in March. We both dislike traditional weddings, with fancy invites, wedding lists, huge parties where you have to invite all your extended family and acquaintances etc.
We were trying to think out of the box a little bit and find ways to have fun!
So, for the handful of friends that will be attending, we decided to deliver our invite in the form of a webpage.
What would a good website be without a fancy domain? After spending some good time playing around with the search tools I found thisinvite.rocks
was up for grabs! Click purchased!
I'm not a designer, so it felt easier to fetch some image resources like background patterns and create a rough version of the page in Macaw. This sped up the generation of HTML/CSS and I was pleasantly surprised by the good quality output.
Looking for doge, cat patterns and dinosaur gifs on the internet was fun!
Macaw is nice, but its support for additional CSS and JS is very limited (maybe their upcoming version will cover this?). I went back to the code editor for this. No fancy JS frameworks were used/needed. To give the page an early-internet parallax feel I used:
You can go visit the page at thisinvite.rocks. It uses github pages for hosting. Here's the unimpressive code.
PS: If the link above stop working I took a gif screengrab too.
Today I wrote an extension to BeardedSpice, to make it work with my favourite online jazz radio, Radio Swiss Jazz. BeardedSpice is an OSX tool that makes your keyboard's media keys compatible with a great number of media providers (including browser based ones).
It's been a while since I last did anything with Objective C, so that was fun :)
img
title attribute combined with artist.Here's the commit and the main bit of code.
A simple technique, stolen from someone who stole this from Coding Horror who stole this from this comic.
Opbeat is undeniably awesome. It logs all the things, it provides useful traces, and it often let's you know things are broken before your users even start suspecting anything.
When using it with Django
it's generally very helpful, logging all unhandled exceptions and allowing you to add nice extra context to your logs, like request information (URL and header data for the request etc).
There are some situations however where the request object might not be available, for example when manually logging something quite deep in the stack (away from the view).
In those cases the request information might still be very important for debugging when things go wrong!
Googling for solutions didn't help much, but looking in opbeat's python code I stumbled upon OpbeatLogMiddleware
. I was unable to find it documented anywhere. The installation instructions recommend enabling only OpbeatAPMMiddleware
.
After having a play with enabling it and trying things out, it turns out it does exactly what we need.
How to?
To enable request logging away from the view/for manual logging further down the stack you just need to change your setup to:
MIDDLEWARE_CLASSES = (
'opbeat.contrib.django.middleware.OpbeatAPMMiddleware',
'opbeat.contrib.django.middleware.OpbeatLogMiddleware',
# ...
)
and you're good to go!
The way this works is, the middleware will store the current request to the local thread. The log handler will then try to grab it from there when possible and append it to the captured data.
When working with an ORM it is often easy to forget that whatever you write is ultimately translated to SQL queries.
Consider this script:
bookings = task.contractor.bookings.all()
task.delete()
bookings.delete()
This will run with no errors.
As you would expecttask
will be deleted, however the bookings
will persist in the db! What's going on?
The code above will result in 2 SQL queries:
As the task is deleted in the 1st query, then the 2nd query will yield no results (as the specific task id will no longer exist).
For this to work we just need to reverse the order of operations:
bookings = task.contractor.bookings.all()
bookings.delete()
task.delete()
I've been learning Elixir
for the past couple of weeks and it has been great refreshing fun.
Solving exercises on Exercism has been helpful to start learning various patterns, both from building my own solutions and from seeing how more experienced people implement them.