Planet ALUG

Syndicate content
Planet ALUG - http://planet.alug.org.uk/
Updated: 1 hour 57 min ago

Chris Lamb: 2014: Selected highlights

Wed, 31/12/2014 - 17:23

Previously: 2012 & 2013.


January

Was lent a 15-course baroque lute.

February

Grandpa's funeral. In December he was posthumously awarded the Ushakov Medal (pictured) for his service in the Royal Navy's Arctic Convoys during the Second World War.

March

A lot of triathlon training but also got back into cooking.

April

Returned to the Cambridge Duathlon.

May

Raced 50 and 100 mile cycling time trials & visited the Stratford Olympic pool (pictured).

June

Ironman Austria.

July

Paced my sister at the Downtow-Upflow Half-marathon. Also released the first version of the Strava Enhancement Suite.

August

Visited Cornwall for my cousin's wedding (pictured). Another month for sport including my first ultramarathon and my first sub-20 minute 5k.

September

Entered a London—Oxford—London cycling brevet, my longest single-ride to date (269 km). Also visited the Tour of Britain and the Sri Chomnoy 24-hour endurance race.

October

London—Paris—London cycling tour (588 km).

November

Performed Handel's Messiah in Kettering.

December

Left Thread.com.

Categories: LUG Community Blogs

MJ Ray: GPG Transition Statement

Tue, 30/12/2014 - 10:34

Rather late but I guess that just confirms it’s really me, right? The signed text and IDs should be at http://mjr.towers.org.uk/transition-statement.txt

Thank you if you help me out here I’ll resign keys in a while.

Categories: LUG Community Blogs

Chris Lamb: find(1), trailing slashes and symbolic links to directories

Wed, 24/12/2014 - 23:06

Here's a nice little "gotcha" in find(1).

First, let's create a directory and a symlink to that directory. We'll add an empty file just underneath to illustrate what is going on:

$ mkdir a $ ln -s a b $ touch a/file

If we invoke find with a trailing slash, everything works as expected:

$ find a/ a/ a/file $ find b/ b/ b/file

... but if we omit the trailing slash, find does not traverse the symlink:

$ find a a a/file $ find b b

This implies that any normal-looking invokation of find such as:

find /path/to/dir -name 'somefile.ext' ...

... is subtly buggy as it won't accomodate the sysadmin replacing that path with a symlink.

This is, of course, well-covered in the find(1) manpage (spoiler: the safest option is to specify -H, or simply to append the trailing slash), but I would still class this as a "gotcha" because of the subtle difference between the trailing and non-trailing slash variants.

Putting it another way, it's completely reasonable that find doesn't follow symlinks, but when this behaviour based on the presence of the trailing slash—a usually meaningless syntactic distinction—it crosses the rubicon to being counter-intutive.

Categories: LUG Community Blogs

Chris Lamb: 8:20AM. Sunday, 22 December 2013

Wed, 24/12/2014 - 20:39

Running east into the sun, he hadn't seen another human for over half an hour. He navigates Westferry Circus and heads south, cutting from the road through to the riverside pathway. He keeps is breathing steady - no reason to hurry.

The wind catches him from Westminster. It smells slightly salty but it's an ersatz attempt, nowhere near bracing enough to be a real sea breeze.

Pressing on, the vacant citadel of Canary Wharf disappears behind him. But as the peninsula curves around, a man appears in the distance. Even half a mile away he looks out of place, or rather—given the hour—time. He's walking purposefully, but it doesn't feel the kind of route someone would be taking to work. He's not wearing quite enough clothes for the weather either, and homeless people are rarely made to feel welcome in the Docklands. His supermarket denim visibly flaps in the breeze. "Relaxed fit", they call it.

When he gets within earshot the man cocks his head, not expecting to hear the regular cadence of approaching footsteps. He turns slightly to reveal he's cradling a large bottle of Coca-Cola, meekly wrapped in the swathing bands of two anonymously blue corner-shop plastic bags.

The runner eyes the Coke greedily but can quickly see that it has already been opened, tainted. Although only a mouthful or so has gone, a brown froth sloshes against the top of the container. Amateur, he thinks. He'll regret that later.

He looks back up to the man, who is now smiling at him. His left hand bccomes visible as he strides: a four-pack of Carling. The man laughs.

"Oh, you and me mate are worlds apart!" the man shouts.

It's immediately friendly. He starts to raise his Carling as but thinks better of it. It's momentarily awkward.

"Worlds apart mate", the man continues. "Have a good one!"

The runner smiles back.

Only in time, the runner thinks. They both can't stop.

Categories: LUG Community Blogs

Mick Morgan: merry christmas 2014

Wed, 24/12/2014 - 18:26

As I have noted before, 24 December is trivia’s birthday. Since my first post dates from 24 December 2006, today is trivia’s eighth birthday. It seems like only yesterday.

I haven’t posted much in the last few months. I have a lot of material I need to cover, and a backlog of articles I want (or at least wanted) to write so I will endeavour to get back into a writing routine as soon as I can. Meanwhile, since it is yet again christmas time, and it’s trivia’s birthday, I couldn’t let today pass unblogged.

Let’s hope 2015 brings all that you wish for.

Best Wishes

Mick

Categories: LUG Community Blogs

Mick Morgan: solidarity with the tor project

Sat, 13/12/2014 - 19:16

On Thursday 11 December, Roger Dingledine of the Tor project posted the following email to the “tor-talk” mail list (to which I am subscribed).

I’d like to draw your attention to

https://blog.torproject.org/blog/solidarity-against-online-harassment
https://twitter.com/torproject/status/543154161236586496

One of our colleagues has been the target of a sustained campaign of harassment for the past several months. We have decided to publish this statement to publicly declare our support for her, for every member of our organization, and for every member of our community who experiences this harassment. She is not alone and her experience has catalyzed us to action. This statement is a start.

Roger asked those who deplored on-line harassment (of any person, for any reason) and who supported the Tor project’s action in publicly condemning the harassment of one of the Tor developers to add their name and voice to the blog post.

I am proud to have done so.

Categories: LUG Community Blogs

Ben Francis: The Times They Are A Changin’ (Open Web Remix)

Thu, 11/12/2014 - 11:26

In the run up to the “Mozlandia” work week in Portland, and in reflection of the last three years of the Firefox OS project, for a bit of fun I’ve reworked a Bob Dylan song to celebrate our incredible journey so far.

Here’s a video featuring some of my memories from the last three years, with Siobhan (my fiancée) and me singing the song at you! There are even lyrics so you can sing along

“Keep on rockin’ the free web” — Potch

Categories: LUG Community Blogs

Chris Lamb: Starting IPython automatically from zsh

Wed, 10/12/2014 - 18:07

Instead of a calculator, I tend to use IPython for those quotidian bits of "mental" arithmetic:

In [1]: 17 * 22.2 Out [1]: 377.4

However, I often forget to actually start IPython, resulting in me running the following in my shell:

$ 17 * 22.2 zsh: command not found: 17

Whilst I could learn do this maths within Zsh itself, I would prefer to dump myself into IPython instead — being able to use "_" and Python modules generally is just too useful.

After following this pattern too many times, I put together the following snippet that will detect whether I have prematurely attempted a calculation inside zsh and pretend that I ran it in IPython all along:

zmodload zsh/pcre math_regex='^[\d\-][\d\.\s\+\*\/\-]*$' function math_precmd() { if [ "${?}" = 0 ] then return fi if [ -z "${math_command}" ] then return fi if whence -- "$math_command" 2>&1 >/dev/null then return fi if [ "${math_command}" -pcre-match "${math_regex}" ] then echo ipython -i -c "_=${math_command}; print _" fi } function math_preexec() { typeset -g math_command="${1}" } typeset -ga precmd_functions typeset -ga preexec_functions precmd_functions+=math_precmd preexec_functions+=math_preexec

For example:

lamby@seriouscat:~% 17 * 22.2 zsh: command not found: 17 377.4 In [1]: _ + 1 Out [1]: 378.4

(Canonical version from my zshrc.d)

Categories: LUG Community Blogs

Steve Engledow (stilvoid): Testing a Django app with Docker

Tue, 09/12/2014 - 01:00

I've been playing around with Docker a fair bit and recently hit upon a configuration that works nicely for me when testing code at work.

The basic premise is that I run a docker container that pretty well emulates the exact environment that the code will run in down to the OS so I don't need to care that I'm not running the same distribution as the servers we deploy to and that I can test my code at any time without having to rebuild the docker image.

Here's an annotated Dockerfile with the project-specific details removed.

# We start with ubuntu 14.04 FROM ubuntu:14.04 MAINTAINER Steve Engledow <steve@offend.me.uk> USER root # Install OS packages # This list of packages is what gets installed by default # on Amazon's Ubuntu 14.04 AMI plus python-virtualenv RUN apt-get update \ && apt-get -y install software-properties-common git \ ssh python-dev python-virtualenv libmysqlclient-dev \ libqrencode-dev swig libssl-dev curl screen # Configure custom apt repositories # and install project-specific packages COPY apt-key.list apt-repo.list apt.list /tmp/ # Not as nice as this could be as docker defaults to sh rather than bash RUN while read key; do curl --silent "$key" | apt-key add -; done < /tmp/apt-key.list RUN while read repo; do add-apt-repository -y "$repo"; done < /tmp/apt-repo.list RUN apt-get -qq update RUN while read package; do apt-get -qq -y install "$package"; done < /tmp/apt.list # Now we create a normal user and switch to it RUN useradd -s /bin/bash -m ubuntu \ && chown -R ubuntu:ubuntu /home/ubuntu \ && passwd -d ubuntu USER ubuntu WORKDIR /home/ubuntu ENV HOME /home/ubuntu # Set up a virtualenv andinstall python packages # from the requirements file COPY requirements.txt /tmp/ RUN mkdir .myenv \ && virtualenv -p /usr/bin/python2.7 ~/.myenv \ && . ~/.myenv/bin/activate \ && pip install -r /tmp/requirements.txt \ # Set PYTHONPATH and activate the virtualenv in .bashrc RUN echo "export PYTHONPATH=~/myapp/src" > .bashrc \ && echo ". ~/.myenv/bin/activate" >> .bashrc # Copy the entrypoint script COPY entrypoint.sh /home/ubuntu/ EXPOSE 8000 ENTRYPOINT ["/bin/bash", "entrypoint.sh"]

And here's the entrypoint script that nicely wraps up running the django application:

#!/bin/bash . ./.bashrc cd myapp/src ./manage.py $*

You generate the base docker image from these files with docker build -t myapp ./.

Then, when you're ready to run a test suite, you need the following invocation:

docker run -ti --rm -P -v ~/code/myapp:/home/ubuntu/myapp myapp test

This mounts ~/code/myapp and /home/ubuntu/myapp within the Docker container meaning that you're running the exact code that you're working on from inside the container :)

I have an alias that expands that for me so I only need to type docked myapp test.

Obviously, you can substitute test for runserver, syncdb or whatever :)

This is all a bit rough and ready but it's working very well for me now and is repeatable enough that I can use more-or-less the same script for a number of different django projects.

Categories: LUG Community Blogs

Chris Lamb: Don't ask your questions in private

Thu, 04/12/2014 - 12:55

(If I've linked you to this page, it is my feeble attempt to provide a more convincing justification.)


I often receive instant messages or emails requesting help or guidance at work or on one of my various programming projects.

When asked why they asked privately, the responses vary; mostly along the lines of it simply being an accident, not knowing where else to ask, as well as not wishing to "disturb" others with their bespoke question. Some will be more candid and simply admit that they were afraid of looking unknowledgable in front of others.

It is always tempting to simply reply with the answer, especially as helping another human is inherently rewarding unless one is a psychopath. However, one can actually do more good overall by insisting the the question is re-asked in a more public forum.

This is for many reasons. Most obviously, public questions are simply far more efficient as soon as more than one person asks that question — the response can be found in a search engine or linked to in the future. These time savings soon add up, meaning that simply more stuff can be done in any given day. After all, most questions are not as unique as people think.

Secondly, a private communication cannot be corrected or elaborated on if someone else notices it is incorrect or incomplete. Even this rather banal point is more subtle that it first appears — the lack of possible corrections deprives both the person asking and the person responding of the true and correct answer.

Lastly, conversations that happen in private are depriving others of the answer as well. Perhaps someone was curious but hadn't got around to asking? Maybe the answer—or even the question!—contains a clue to solving some other issue. None of this can happen if this is occurs behind closed doors.

(There are lots of subtler reasons too — in a large organisation or team, simply knowing what other people are curious about can be curiously valuable information.)

Note that this is not—as you might immediately suspect—simply a way of ensuring that one gets the public recognition or "kudos" from being seen helping others.

I wouldn't deny that technical communities work on a gift economy basis to some degree, but to attribute all acts of assistance as "selfish" and value-extracting would be to take the argument too far in the other direction. Saying that, the lure and appeal of public recognition should not be understated and can certainly provide an incentive to elaborate and provide a generally superior response.


More philosophically, there's also something fundamentally "honest" about airing issues in an appropriately public and transparent manner. I feel it promotes a culture of egoless conversations, of being able to admit one's mistakes and ultimately a healthy personal mindset.

So please, take care not only in the way you phrase and frame your question, but also consider wider context in which you are asking it. And don't take it too personally if I ask you to re-ask elsewhere...

Categories: LUG Community Blogs

MJ Ray: Autumn Statement #AS2014, the Google tax and how it relates to Free Software

Thu, 04/12/2014 - 04:34

One of the attention-grabbing measures in the Autumn Statement by Chancellor George Osborne was the google tax on profits going offshore, which may prove unworkable (The Independent). This is interesting because a common mechanism for moving the profits around is so-called transfer pricing, where the business in one country pays an inflated price to its sibling in another country for some supplies. It sounds like the intended way to deal with that is by inspecting company accounts and assessing the underlying profits.

So what’s this got to do with Free Software? Well, one thing the company might buy from itself is a licence to use some branding, paying a fee for reachuse. The main reason this is possible is because copyright is usually a monopoly, so there is no supplier of a replacement product, which makes it hard to assess how much the price has been inflated.

One possible method of assessing the overpayment would be to compare with how much other businesses pay for their branding licences. It would be interesting if Revenue and Customs decide that there’s lots of Royalty Free licensing out there – including Free Software – and so all licence fees paid to related companies are a tax avoidance ruse. Similarly, any premium for a particular self-branded product over a generic equivalent could be classed as profit transfer.

This could have amusing implications for proprietary software producers who sell to sister companies but I doubt that the government will be that radical, so we’ll continue to see absurdities like Starbucks buying all their coffee from famous coffee producing countries Switzerland and the Netherlands. Shouldn’t this be stopped, really?

Categories: LUG Community Blogs

Steve Engledow (stilvoid): Just call me Anneka

Mon, 01/12/2014 - 00:16

I had an idea a few days ago to create a Pebble watchface that works like an advent calendar; you get a new christmas-themed picture every day.

Here it is :)

The fun part however, was that I completely forgot about the idea until today. Family life and my weekly squash commitment meant that I didn't have a chance to start work on it until around 22:00 and I really wanted to get it into the Pebble store by midnight (in time for the 1st of December).

I submitted the first release at 23:55!

Enjoy :)

I'll put the source on GitHub soon. Before that, it's time for some sleep.

Categories: LUG Community Blogs

Mick Morgan: independent hit

Thu, 27/11/2014 - 11:33

On trying to reach the website of the Independent newspaper today (the Grauniad is trying my patience of late), I received the following response:

Closing the popup takes you to this page:

I haven’t checked whether this is simply a DNS redirect or an actual compromise of the Indy site, but however the graffiti was added, it indicates that the Indy has a problem.

Categories: LUG Community Blogs

Chris Lamb: Validating Django model attribute assignment

Tue, 25/11/2014 - 14:54

Ever done the following?

>>> user = User.objects.get(pk=102) >>> user.superuser = True >>> user.save() # Argh, why is this user now not a superuser...

Here's a dirty hack to validate these:

import sys from django.db import models from django.conf import settings FIELDS = {} EXCEPTIONS = { 'auth.User': ('backend',), } def setattr_validate(self, name, value): super(models.Model, self).__setattr__(name, value) # Real field names cannot start with underscores if name.startswith('_'): return # Magic if name == 'pk': return k = '%s.%s' % (self._meta.app_label, self._meta.object_name) try: fields = FIELDS[k] except KeyError: fields = FIELDS[k] = set( getattr(x, y) for x in self._meta.fields for y in ('attname', 'name') ) # Field is in allowed list if name in fields: return # Field is in known exceptions if name in EXCEPTIONS.get(k, ()): return # Always allow Django internals to set values (eg. aggregates) if 'django/db/models' in sys._getframe().f_back.f_code.co_filename: return raise ValueError( "Refusing to set unknown attribute '%s' on %s instance. " "(Did you misspell %s?)" % (name, k, ', '.join(fields)) ) # Let's assume we have good test coverage if settings.DEBUG: models.Model.__setattr__ = setattr_validate

Now:

>>> user = User.objects.get(pk=102) >>> user.superuser = True ... ValueError: Refusing to set unknown attribute 'superuser' on auth.User instance. (Did you misspell 'username', 'first_name', 'last_name', 'is_active', 'email', 'is_superuser', 'is_staff', 'last_login', 'password', 'id', 'date_joined')

(Django can be a little schizophrenic on this — Model.save()'s update_fields keyword argument validates its fields, as does prefetch_related, but it's taking select_related a little while to land.)

Categories: LUG Community Blogs

Chris Lamb: Calculating the number of pedal turns on a bike ride

Mon, 17/11/2014 - 09:34

If you have a cadence sensor on your bike such as the Garmin GSC-10, you can approximate the number of pedal turns you made on the bike ride using the following script (requires GPSBabel):

#!/bin/sh STYLE="$(mktemp)" cat >${STYLE} <<EOF FIELD_DELIMITER COMMA RECORD_DELIMITER NEWLINE OFIELD CADENCE,"","%d" EOF exec gpsbabel -i garmin_fit -f "${1}" -o xcsv,style=${STYLE} -F- | awk '{x += $1} END {print int(x / 60)}'

... then call with:

$ sh cadence.sh ~/path/to/2014-11-16-14-46-05.fit 24344

Unfortunately the Garmin .fit format doesn't store the actual number of pedal turns, only the average for each particular second. However, it should be reasonably accurate given that one keeps a reasonably steady cadence.

As a bonus, using a small amount of shell plumbing you can then sum an entire year's worth of riding like so:

$ for X in ~/path/to/2014-*.fit; do sh cadence.sh ${X}; done | awk '{x += $1} END { print x }' 749943
Categories: LUG Community Blogs

Steve Engledow (stilvoid): Stony Silence

Sat, 08/11/2014 - 23:27

I just bought a Pebble - it's great!

I'd been toying with the idea of buying a wristwatch for several months. My main reason was that I'd noticed I'd fallen into the following pattern:

  • Wonder what the time is
  • Take phone out of pocket
  • Get distracted by email/twitter/app updates/something
  • Put phone back in pocker
  • Realise I didn't note or don't remember the time

I have a friend who owns a Pebble and after quizzing him about it, I decided that might help me achieve an even better goal: to dramatically reduce the amount of time I spend looking at my phone altogether.

After a week with my new Pebble, I'd say it's going well. The watch receives notifications from my phone so whenever an email arrives, I can quickly glance at my watch to decide whether I need to bother reading it now (most of the time, not). Despite requiring that my phone's bluetooth be switched on all the time, I've noticed that the battery has lasted slightly longer than normal - the Android battery usage charts tell me that's because of the reduced amount of screen usage.

My favourite thing about the Pebble is how hackable it is. The SDK is pretty good and simple to use. It's only been a week and I've already written, three, watch faces. The latest of which has resulted in a few emails from people saying how much they liked it :)

In unrelated news - OR IS IT?! - I had a panic attack the other day for the first time in over a year :S I managed to keep on top of it as I know what to do now, but the effects lasted for much longer than on previous occasions; I didn't feel alright until 10am the following day - 17 hours after it started. I still don't feel quite right.

Does anyone reading have any experience of panic attacks and whether it's worth seeing a doctor? I get them very rarely and I can make my way through them without help now but they leave me feeling awful for hours afterwards when they do happen. I'm not interested in taking regular meds to prevent them when they occur but I would be interested to know if there's something that could halt an attack when it starts or at least reduce the after-effects.

I don't really know what brought this one on but I rarely do. Caffeine seems to be a trigger (and I'd drunk a few teas and coffees that day) but it can't be a trigger on its own as I've drunk that much caffeine on other occasions and been fine.

Bleh.

Categories: LUG Community Blogs

Chris Lamb: Generating gradiented fade images using ImageMagick

Mon, 03/11/2014 - 08:42

Whilst gradienting images is certainly possible with CSS, current browser support means that it can still make sense to do it yourself, especially if front-end performance is a concern.

However, to avoid manual work in Gimp or Photoshop, you can use ImageMagick to generate them for you:

$ wget --quiet -Obackground.jpg http://i.imgur.com/WCjlJ.jpg $ convert background.jpg \ -alpha set -channel A \ -sparse-color Barycentric '%w,%[fx:h-300] opaque %w,%h transparent' \ -background '#ffcc32' -flatten \ background-gradiented.jpg

300 here refers to the height or "speed" of the gradient and the target colour is specified by with -background.

Before:

After:

Categories: LUG Community Blogs

Chris Lamb: Are you building an internet fridge?

Thu, 30/10/2014 - 18:00

Mikkel Rasmussen:

If you look at the idea of "The Kitchen of Tomorrow" as IKEA thought about it is the core idea is that cooking is slavery.

It's the idea that technology can free us from making food. It can do it for us. It can recognise who we are, we don't have to be tied to the kitchen all day, we don't have to think about it.

Now if you're an anthropologist, they would tell you that cooking is perhaps one of the most complicated things you can think about when it comes to the human condition. If you think about your own cooking habits they probably come from your childhood, the nation you're from, the region you're from. It takes a lot of skill to cook. It's not so easy.

And actually, it's quite fun to cook. there's also a lot of improvisation. I don't know if you ever tried to come home to a fridge and you just look into the fridge: oh, there's a carrot and some milk and some white wine and you figure it out. That's what cooking is like – it's a very human thing to do.

The physical version of your smart recipe site?


Therefore, if you think about it, having anything that automates this for you or decides for you or improvises for you is actually not doing anything to help you with what you want to do, which is that it's nice to cook.

More generally, if you make technology—for example—that has at its core the idea that cooking is slavery and that idea is wrong, then your technology will fail. Not because of the technology, but because it simply gets people wrong.

This happens all the time. You cannot swing a cat these days without hitting one of those refrigerator companies that make smart fridges. I don't know you've ever seen them, like a "intelligent fridge". There's so many of them that there is actually a website called "Fuck your internet fridge" by a guy who tracks failed prototypes on intelligent fridges.

Why? Because the idea is wrong. Not the technology, but the idea about who we are - that we do not want the kitchen to be automated for us.

We want to cook. We want Japanese knives. We want complicated cooking. And so what we are saying here is not that technology is wrong as such. It's just you need to base it—especially when you are innovating really big ideas—on something that's a true human insight. And cooking as slavery is not a true human insight and therefore the prototypes will fail.

(I hereby nominate "internet fridge" as the term to describe products or ideas that—whilst technologically sound—is based on fundamentally flawed anthropology.)

Hearing "I hate X" and thinking that simply removing X will provide real value to your users is short-sighted, especially when you don't really understand why humans are doing X in the first place.

Categories: LUG Community Blogs

Steve Engledow (stilvoid): When all the things went wrong

Mon, 27/10/2014 - 23:34

The last few weeks have seen several bits of technology fail that affect my everyday life.

It started with the locks on my car beginning to seize up. To begin with, they were just a bit stiff, then one of them stopped working altogether. Then they all stopped working with any regularity. I took the car to a garage who told me it's a common problem with this exact model and charged me £100 to replace the driver's side lock. Apparently, a full set would cost around £600.

So now I'm left with two car keys; one to get in, and one for the ignition.

Second, I somehow left the cable for my bicycle light charger hanging out of the car door on a journey. When I arrived, I found it looking quite mangled.

Thirdly, last night when my wife came home, she and I both turned our keys in the lock at the same time from different sides of the front door (without realising). This somehow broke the damn lock. Now the key doesn't turn all the way and the door can be locked but the key must remain in it.

So now we have to leave by the back door.

Fourth, while at rehearsal tonight with my band, my keyboard started playing up; it complains that the battery is low whilst running off mains power. Thinking maybe the adapter was playing up, I tried another with the same result.

Bleh.

Categories: LUG Community Blogs

Steve Engledow (stilvoid): Things

Thu, 16/10/2014 - 00:05
Ogg(camp|tober|sford)

OggCamp was fantastic. If I can remember all the talks I went to I'll do a brief write up. The event certainly left me with a few little ideas for things to write and do.

Down with dynamic things!

One small example is that I've rewritten the build script for this blog. No more scripted generation of the final HTML; I just wget -m the development server and that's everything built. Then it's all just served up as static content through nginx. Simples and I don't know why I didn't think of just snapshotting it like that before.

Click

I've reached a point in my career now where I find myself wanting to create and present slide decks. WTF?

I'm still writing code fairly regularly but there's so much other stuff I spend my time doing that I'm not even sure I can account for. It still feels important.

Clock

I think I'm going to buy a Pebble to wean myself off the phone-checking habit that I've developed over the years.

Relatedly, I wrote this post on my phone. It wasn't nearly as painful as I'd expected.

Categories: LUG Community Blogs