atomicules

Push propelled program tinkerer and picture maker.

LINK: NetBSD Current-Users archive: /var/db/entropy-file not present

For some reason I never noticed this on the ye-olde laptop (it was running NetBSD 6.1.3, but I don't think that was why), but on this NetBSD 7 machine I noticed this exact error message on boot. Even if I manually created it using sudo rndctl -S /var/db/entropy-file it would still disappear at some point.

After reading this thread I now understand why and what is meant to happen:

  1. When the system shuts down the entropy-file should be created
  2. When the system next boots the entropy-file is loaded and then deleted

It turns out I'd also been falling foul of shutting down incorrectly: I've always used poweroff. I don't know where I learnt that from, but I never realised I should be using shutdown instead because poweroff doesn't run the shutdown scripts. Whoops.

Phoenix Assumes That Our Postgrsql Database Will Have A Postgres User

"Phoenix assumes that our PostgreSQL database will have a 'postgres' user account with the correct permissions and a password of 'postgres'. If that isn't the case, please see the instructions for the ecto.create mix task."

Alternatively, just edit the .exs files in config/.

On NetBSD the default PostgreSQL user is called pgsql. Rather than add yet another user to PostgreSQL you can just edit the Phoenix config files. I pulled out the username and password details from config/dev.exs, config/prod.secret.exs and config/test.exs and added this to the top of config/config.exs instead (just after use Mix.Config):

# Configures the database
config :hello_phoenix, HelloPhoenix.Repo, adaptor: Ecto.Adaptors.Postgres,
  username: "pgsql",
  password: "pgsql"

This, for example, is what remained in config/test.exs:

# Configure your database
config :hello_phoenix, HelloPhoenix.Repo,
  adapter: Ecto.Adapters.Postgres,
  database: "hello_phoenix_test",
  hostname: "localhost",
  pool: Ecto.Adapters.SQL.Sandbox

How I listen to the radio on NetBSD

Lacking in blog posts this month as I've been busy... oddly, given my current predicament, but there you go. I do have a whole heap lined up, but just no time to write them, or it would be inappropriate to write them... yet. So in the meantime this will have to do.

tl;dr:

  1. mpv http://149.202.90.221:9036/; or mpv http://a.files.bbci.co.uk/media/live/manifesto/audio/simulcast/hls/uk/high/ak/bbc_6music.m3u8
  2. mixerctl -w outputs.master2=170,170

I appreciate that most people take audio and listening to music on their computers entirely for granted, but for me on a NetBSD machine this is whole new ground for me. Not because NetBSD can't do audio, rather the hardware I've used couldn't; Well, even then, technically it could, but in a choice between wifi and audio I chose wifi; It sincerely wasn't worth my time figuring out the address conflict.

On that note: Why did I bother building my own kernel when I could have just disabled everything via userconf on boot?

There are really only two things I really want need to listen to:

  1. The Remix - Eddy Temple Morris, on Soho Radio London.
  2. Lauren Laverne on BBC 6 Music.

(There's also Jo Whiley on BBC2, Steve Lamacq on 6 Music, Annie Mac on Radio 1, Shoplifters on Soho, Simone Marie on Soho, John Kennedy on Radio X... but, but, I can cope without them).

Since my only current computer is a Dell Optiplex which I had no intention of running anything else but NetBSD on I was a bit concerned about missing out on 6 Music and The Remix. Technically, we do have a DAB radio in the house, like, technically, we have a couple of iPads and a Macbook Air, but that doesn't mean I get to use them. And that would only solve the 6 Music problem anyway.

To date, because of lack of home computing power, I have listened to The Remix via catch-up on Mixcloud at work. The good thing about the Optiplex is I now have a whopping 1GB of RAM compared to 128MB, and two 3.4GHz processors instead of one 497 MHz processor. So I can run Firefox on this thing NO PROBLEM. Technically, that also means I can run Flash (although practically I think that doesn't mean it'll have any more success than getting pulseaudio working) which means I could use Mixcloud on this machine, but I really don't want to run Flash anyway if I can help it. Fortunately, many, many other people think Mixcloud only offering streaming, and only offering that via Flash, is complete pants: The best site for finding downloads is Offliberty, but if that fails there is the much more spammy/pop-up Savedeo; There maybe command line tools, but it's finding a maintained one that is tricky (and investigating writing my own hardly seems worth it for once a week; although...).

I used to listen to 6 Music at work via iPlayer which also uses Flash, but thankfully I already knew there were workarounds thanks to this excellent BBC on Linux post. So I installed VLC via pkgin only to have it crash every single time I tried to open a stream. Everything else seemed to work, just not the one thing I wanted it for. I'd used cmus a lot under Arch Linux and thought I'd look to see if that supports streaming; It does, supposedly, but I couldn't get it to work. I almost wobbled and looked at getting Flash working, but then remembered reading mentions of mplayer as an alternative to VLC; I'd not used it for years and then never for streaming. So I went looking for mplayer only to not find it available via pkgin (even though it was in pkgsrc); this confused me for bit, until I eventually somehow discovered that mpv is the mplayer replacement and available via pkgin!

mpv is superb. And easy to use; the man page is probably the longest man page I've ever seen though. You just supply it the argument for whatver you want to watch/listen to and that's it:

mpv http://a.files.bbci.co.uk/media/live/manifesto/audio/simulcast/hls/uk/high/ak/bbc_6music.m3u8

Or for listening to a download:

mpv the-remix-with-eddy-temple-morris-06052016.m4a

Or for listening to an album:

mpv Wolf_Alice-My_Love_is_Cool/

Which automatically creates a playlist for that directories tracks. I see no reason to use anything other than mpv from now on.

There are lots of commands, but the only ones I'm using at the moment are:

  • space - to pause/resume.
  • Q - to quit, but remember playback position when you play that file again.

For controlling the volume, I'm doing that outside of mpv:

mixerctl -w outputs.master2=170,170

(255,255 is ridiculously loud, even by my standards).

As said, I only used Mixcloud for Soho because I couldn't listen live at home. Soho, like 6 Music, is streamed on the internet, but unlike 6 Music that is the only live way of listening. It is trivial to find the streaming url for Soho Radio London, although it is a little odd: http://149.202.90.221:9036/; (that semi-colon is the filename). Now I just need Mixcloud for the week's I've missed as long as I can orchestrate being incredibly anti-social with my wife so I can sit and listen to The Remix on a Friday night, which will be the first time since Eddy TM left Xfm that I'll have had a chance to listen live!

Headphones. I just need new headphones. Next month!

They might as well make them use baskets on their handlebars

It was recently the Tour de Yorkshire and in the run up to it I was very excited to read that the women's race would "...compete over 135km on exactly the same course as the men, who tackle the route later the same day". Great! Fantastic idea and it makes sense to run one in the morning and one in the afternoon - it's also a bonus for spectators. But then I realised it was only for Stage Two (the second day), i.e. the women would not feature on the first or final third day and so are still getting a token event even if it is an improvement(!) over past races.

Ok, it is only 2016, perhaps we shouldn't rush towards equality. At least the women's event was televised. On a saturday morning as well! I tuned in to watch at 10am on ITV4 and WHERE WAS THE CYCLING?! No where to be seen. "Subject to final changes". I guess they decided in the end the women's race wasn't worth broadcasting.

I went and did some gardening instead in a huff and didn't watch any more of the TdY at all.

I'm entirely likely to watch the TdF because it is the TdF afterall, but even I'm getting bored of this crap.

Note: Finally (FINALLY!) finished reading the Harry Potter books to the youngest. I think I started in 2013? Can't actually remember now

LINK: Friction DARE (Hold It Down) on The Remix

From 57:36 to 1:01:38

Behind the times that are behind the times: I'm playing a bit of catch-up on the last two shows I've missed and I'm working so kind of listening in the background and then this pops right out of the subconcious. It's AMAZING. Turns out even EddyTM is (slightly) behind with this as it was being played as a bootleg (I guess to those people who still have lives and go out) before being turned into this proper release.

Linking to EddyTM's show as that's where I heard it, but there is a video on the ukf.com page of just that track

Note: Back to cycling and I've reached my one year anniversary of a "temporary" fix to my wheels and forks that was meant to last about two weeks

One Year Anniversary Of A Fix That Was Meant To Last Two Weeks

"Hopefully, though, this doesn't have to last forever, just until next month (famous last words)."

Words fail me, hence why I'm just regurgiatating those again.

LINK: Boardman CX Team, dream.

Missed this one in my Descending the ladder of bike dreams post. Slots somewhere inbetween the Pipe-dream and dream levels.

Not sure why it's got a 44 tooth chainring though, seems too high, but I guess this is 1x equivalent of the 50/34 chainring setups on 2x "CX" bikes. I wouldn't actually complain though.

Note: Survived the first quarter of the year of cycling. Now a week off. Yay!

Note: Other years I've immediately felt the benefit of switching off winter tyres. Not this year. Hope it's just this interminable cold/flu.

Reducing Cyclomatic Complexity in Simplenote.py

As a result of mrtazz's post on Taking Pride in Your Code I thought that since I'm the maintainer of his simplenote.py code I better pull my finger out and bring that in line.

After adding in a Code Climate badge I discovered a few issues with cyclomatic complexity and code duplication.

I am quite lazy with code quality tools. I've used HLint for Haskell before because I found it made genuinely good suggestions. And I've been through various code quality tools with Java in the past, but those made much more dubious "improvements"; Ok, I'm not an expert programmer, but I still think code quality tools should be used as an aid, not as an enforced tollgate. Generally though I don't use them and I probably should.

Code Climate uses radon for Python code. Radon is very easy to install locally and very easy to use which means you don't have to publicly embarrass yourself by pushing your code to Github and having Code Climate do the work. You can quickly try out simple changes locally to see if it affects the code score. Or not as was the case with my first attempts.

At first I thought the issues were due to lots of nested if and try statements that (I thought) were necessary and (I thought) would be difficult to remove. I.e. sections of code like:

params = 'auth={0}&email={1}&length={2}'.format(self.get_token(), self.username, NOTE_FETCH_LENGTH)
if since is not None:
    try:
        sinceUT = time.mktime(datetime.datetime.strptime(since, "%Y-%m-%d").timetuple())
        params += '&since={0}'.format(sinceUT)
    except ValueError:
        pass

# ***perform initial HTTP request***
try:
    request = Request(INDX_URL+params)
    response = urllib2.urlopen(request)
    notes_index = json.loads(response.read().decode('utf-8'))
    notes["data"].extend(notes_index["data"])
except IOError:
    status = -1
# ***end initial HTTP request***

while "mark" in notes_index:
    params = 'auth={0}&email={1}&mark={2}&length={3}'.format(self.get_token(), self.username, notes_index["mark"], NOTE_FETCH_LENGTH)
    if since is not None:
        try:
            sinceUT = time.mktime(datetime.datetime.strptime(since, "%Y-%m-%d").timetuple())
            params += '&since=%s' % sinceUT
        except ValueError:
            pass

    # ***perform the actual HTTP request***
    try:
        request = Request(INDX_URL+params)
        response = urllib2.urlopen(request)
        notes_index = json.loads(response.read().decode('utf-8'))
        notes["data"].extend(notes_index["data"])
    except IOError:
        status = -1
    # ***end actual HTTP request***

There is obvious duplication here from performing the initial request and then the actual one, but both are actually needed. However, there is indication of some obvious maintainer apathy at play here as I hadn't even noticed this bit until this review:

params += '&since={0}'.format(sinceUT)

and

params += '&since=%s' % sinceUT

As to how and why I had no consistency here I don't know.

Anyway, with a bit of effort it was possible (who knew!?) to improve this and add a private method for the HTTP request:

def __get_notes(self, notes, params, since):

    notes_index = {}

    if since is not None:
        try:
            sinceUT = time.mktime(datetime.datetime.strptime(since, "%Y-%m-%d").timetuple())
            params += '&since={0}'.format(sinceUT)
        except ValueError:
            pass
    # perform HTTP request
    try:
        request = Request(INDX_URL+params)
        response = urllib2.urlopen(request)
        notes_index = json.loads(response.read().decode('utf-8'))
        notes["data"].extend(notes_index["data"])
        status = 0
    except IOError:
        status = -1
    if "mark" not in notes_index:
        self.mark = False
    return notes, status

And then the original bit of code ends up something just like this:

self.mark = True

while self.mark:
    notes, status = self.__get_notes(notes, params, since)

I wasn't sure whether to use the instance variable approach (self.mark) or pass it as a result/argument of the method. I.e:

def __get_notes(self, notes, params, since, mark):

# code...

return notes, status, mark

Both approaches work. I think self.mark is cleaner, even if the instance variable doesn't make much sense externally. I could have called it _mark to indicate it is private, but it doesn't actually make any difference to how things work.

When I first got the Code Climate results I just assumed it was going to require me to do some "proper" programming and so I put it on the back-burner for awhile, but in the end, in this case anyway, the code duplication and the cylcomatic complexity were linked; Fixing one fixed the other. And it wasn't as tricky as I thought.

I'm going to try to start using some code metric/quality/review tools a bit more. If only because they force a fresh look on code you have glossed over for ages.

See here and here for the relevant commits.

[EDIT: 2016-04-03] And here. Sigh.

Note: And a very happy No More Winter Tyres Day to me.

Note: With the equinox past I guess that means I have officially survived another winter of cycling.

Yet Another "Nowt, but Fixed Gear" Anniversary

Which makes it two solid years of fixed gear; excepting the one morning I rode my daughter's bike in, but surely that counts for even more points?!

I've had the first year and three-quarters of this commute on fixed gear, then two years of it on a road bike, but very much interspersed with fixed gear riding due to breakages and winter, and then the last two years of fixed gear. Of course, prior to this was another three-quarters of a year on fixed, but a very much smaller commute.

I've had my fix of fixed.

Note: Finally feeling like spring today: Felt stupid in mittens, on studded tyres and a 2:1 ratio; Saw lambs; And home for sunset.

Note: Had to "work" from home for last two days as rear wheel bearings needed replacing. Last set survived less than two months! #cycling

Battling Winter Winning Spring

"Battling Winter: Winning Spring"

by Me

This winter has felt so long. Mud, wind, floods, snow, ice and yet more mud. So much mud.

It's the first winter I've ever used a front tyre with no side studs and I have fallen off because of icy ruts, but then again I've fallen off with both front and rear full Marathon Winters so can't say for sure it is lack of side studs. Perhaps I just need to develop more skill, which you'd think I'd have after six winters of this?

The saddest thing, though, about this winter's cycling is that (depending on how things work out; although it is looking pretty damn likely) I'll make it to spring, having had an extremely arduous time on this muddy track with just one gear, but then I'll be doing a new commute somewhere else and so won't see the benefit of a dry track.

Perhaps I don't really win spring this year?

These are the ten most recent posts (not counting the note drivel), for older posts see the Archive.