Fixing a Matias switch with keychatter on a KPB V80

So I have this beautiful matias quiet click keyboard that I sort of love for its tactility. The sounds is slightly less impressive though, but still way better than my floss modded IBM M Spacesaver. But the real bummer with this keyword is, you guessed it, keychatter. Now the reason for this is most probably the way the switches are lubed and not properly tested by QA. I have several keys that drive me mad. Let me show you how to fix this if you’re in the same condition.

  • remove the keycap of the switch to “repair” and the ones next to it so you have a little wiggle room

  • use two toothpicks to gently allow the upper part of the switch to be pulled up and released. Do this gently, very very very gently.

  • once the switch is disassembled remove the tactile leaf and clean it with alcohol

disassemble and clean matias switch

  • air spray the bottom of the switch

  • reassemble with care

That should be it. I was able to repair some of the keys and have a way better typing experience now. Hope this helps somebody. There are tons of videos on youtube on how to disassemble alps and matias switches. If the keychatter persists you probably need a new switch and get soldering.

Adding a 10g spring to a topre 45 keyboard

So I’m back to crazy keyboard mods. I have a topre Novatouch that is 45 grams actuation force. It’s nice but it’s definitely lighter and a little less “thock” than a 45 gram uniform Realforce. So I decided I’d try to add a 10g spring. The actuation on a topre board depends on the rubber dome and not on the spring force like with cherry compatible switches so adding an external spring will change tactility and feedback, not just add force. I knew that the feel would be slightly different but… I’m not offended by it in the least. When you hit a topre key you usually face a little bit of resistance high up on the keystroke and then, after a tactile bump, the rest of the travel goes down real fast until you hear the “thock” sound (ok, I don’t, not really because I’ve also silence-modded this baby). With the external spring you need more strength (should be around 55gram actuation ideally) but the weird thing is that instead of the initial resistance-bump-drop-to-the-bottom thing there now is more of a uniform resistance, slighter bump and the key jumps back up. This is much more similar to an IBM Model M but without the sound or (if you exclude the tactile feedback) to a cherry mx black old school. So it’s a completely different beast. I like it, but it’s not topre any more. It’s a ModelM/Topre/MX Black hybrid and (as fatigued as my fingers are at the end of the day) I LOVE IT.

From SQL to ORM and back

Let’s face it, we’ve all been there. We started our career with SQL, found it cumbersome and difficult to remember, had too many DataManager classes around to encapsulate queries and got tired of all that work. Then suddenly we were hit by the light at the end of the tunnel.. an ORM.. in my case Hibernate was love at first sight. No more fussing with SQL dialects, no more Stored Procedures on Oracle, something reusable, write once run on any DB, real java style. And then just sometimes you’d hit a wall where some really crazy query or nested selects weren’t as easy without having to really know every nuance of the library, and even then it sometimes wouldn’t work. And then there was the Heap growing like crazy, garbage collection to tame, too many objects being pulled into memory during a massive select. Of course there was also data mapping, but that was even more xml, no thanks. Then came Ruby on Rails with ActiveRecord and all its beauty and ease. Everything was a breeze. Except it wasn’t and sometimes you’d still need to do some nasty native query. But hey it was nice. Most of the time. Until of course it took more code and workarounds to make AR behave like a very specific native query that just couldn’t be mapped. And maybe it ended up with more code, more loops and more memory than necessary. And don’t even get me started on performance! And so recently (like a couple of years now) I came to know Go. Go is plain but in a subtle way. But database wise it doesn’t come with a lot of extras attached. So I went back to having structs mapped to tables (well not only) and to using plain old native SQL (yes I have the luxury of saying I want Postgres because Heroku or other services will just allow me to). And so everything became sort of “simple” again. Of course there’s more work involved. I have query files that are pure SQL and call them from my code. I need to cycle through results or just assign a query result to an array and all. But.. and this is very important, I have two big wins: 1) I have complete control 2) I have super performant code

The only downside is you need to really know your SQL.. but hey… SQL is something that will never die, just like C and Linux. So learning it is investing in a lifelong skill anyway. Plus the amount of control is simply stunning. No more walls. No more coding around a barrier or lack of implementation in a library. This feels like home. Yep.

NSImage tinted as easily as a UIImage

I was looking for a simple way of tinting an NSImage the way I’m used to doing with UIImage but it appears that Cocoa is a little behind Cocoa Touch in this regard. I found many different solutions but none of them worked out of the box with Swift 4. This is what I came up with eventually and works as expected.

extension NSImage {
    func tinting(with tintColor: NSColor) -> NSImage {
        guard let cgImage = self.cgImage(forProposedRect: nil, context: nil, hints: nil) else { return self }
        return NSImage(size: size, flipped: false) { bounds in
            guard let context = NSGraphicsContext.current?.cgContext else { return false }
            context.clip(to: bounds, mask: cgImage)
            return true

NSColor from/to HTML colors

Here’s a nice little extension I wrote to create NSColors given an html string and vice versa getting an html string from an existing NSColor. Hope it’s useful.

extension NSColor {
    public convenience init?(htmlString: String) {
        let hexColor = htmlString.replacingOccurrences(of: "#", with: "")
        let scanner = Scanner(string: hexColor)
        var hexNumber: UInt64 = 0
        if scanner.scanHexInt64(&hexNumber) {
            let red = CGFloat(((hexNumber & 0xFF0000) >> 16)) / 255.0
            let green = CGFloat(((hexNumber & 0x00FF00) >> 8)) / 255.0
            let blue = CGFloat(((hexNumber & 0x0000FF) >> 0)) / 255.0
            self.init(red: red, green: green, blue: blue, alpha: 1.0)

        return nil
    func toHTMLString() -> String {
        var r: CGFloat = 0
        var g: CGFloat = 0
        var b: CGFloat = 0
        var a: CGFloat = 0
        self.getRed(&r, green: &g, blue: &b, alpha: &a)
        return String(
            format: "#%02X%02X%02X",
            Int(r * 0xff),
            Int(g * 0xff),
            Int(b * 0xff)


Multisite WordPress with A2

After looking at several options I settled with A2 hosting at around 12$/month but at least I have a bunch of domains on a single network wordpress installation and everything is working great.

Here’s the steps involved:

  • Go to your CPanel and install WordPress from Softaculous (not the optimized version)
  • Make sure it’s networking is turned on
  • To add an existing domain go to CPanel-> Addon Domains and let’s add an alias to our domain like this:

  • Then it will be automatically added to the DNS zone editor
  • If you have the domain on another provider (mine’s godaddy for example) you’ll need to set the dns to point to A2

  • Now back to your wordpress on A2 (yoursite/wp-admin). Go to My Sites, Network Admin->Sites

  • Make sure that you have your main domain / a desired wordpress folder. This is a hack basically. The real wp network site will live in that folder

  • The real trick happens in the Settings. The siteurl can be pointed to the actual domain we registered in the cpanel dns zone section

  • Now install the MU WP Domain mapping plugin and follow the installation guide.
  • Now the last step is to go to My Sites -> Settings -> Domains and add the unique site id (number .. you can see it when opening My Sites site in the url as the id parameter) and the new domain there (primary should be set to no otherwise it will simply redirect to your main site! Happened to me and made me waste a little time so beware ):

All set. If you visit your domain you should see your wordpress blog. Enjoy!

Time to wash some records

During our vacation I spent some time buying used records in Amsterdam. I ended up with quite some good stuff among which Porcupine and Ocean Rain by Echo and the Bunnymen, Japanese Whispers and Staring at the sea by the Cure, Closer by Joy Division, Keith Jarret’s Koln concert and the list goes on and on. Needless to say most of them, even if in great condition, needed a thorough washing. I use the Disco Antistat and, having finished their cleaning fluid, I decided to try and make some homemade based on the London Jazz Collector’s recipe. I know this was meant for RCMs but it does work with the Antistat too. I must say that the results were pretty good. At least as good as with the original fluid but with no residue at all! It does take more time to dry though, but that’s ok. All in all I’m really happy with it and, being a lot cheaper, I can just throw it away every 15 or so vinyls cleaned.

Granite PBT set for Matias/Alps – a short review

Signature Plastics released the awesome Granite set by Matt3o for Alps switches recently. It was like a dream come true and I promptly placed an order. I now have them on my KBParadise V60 with Matias quiet click switches. I must say the looks and the feel are awesome.

But… there’s always a but… it appears that they got the stabs completely wrong. And when I say completely wrong it means that they’re not compatible with the Matias stabilisers that usually come on the board. And using a cherry stabiliser instead will not fix it, it’s not centred and too tall so in the end they’re basically unusable. The only one that works, fortunately enough, is the spacebar. Luckily enough on my V60 everything seems to work just fine without stabilisers. Maybe because of the smaller form factor, or who knows, but I got away without using them and so I can still enjoy the new set. The rest of the build quality is super as usual. And I love the DSA profile.

Here’s a link to the set with reviews.

Quick Dokku Cheat Sheet


#Get running containers:
docker ps

#Get all containers:
docker ps -a

#Stop container:
docker stop container_id

#Remove container:
docker rm container_id


#Start/Stop/Restart app:
dokku ps:start myapp; 
dokku ps:stop myapp; 
dokku ps:restart myapp

#Restart ALL:
dokku ps:restartall


#Read app log:
dokku logs myapp


#Add domain:
dokku domains:add myapp mydomain; 

#Remove domain:
dokku domains:remove myapp mydomain


#Set env var:
dokku config:set myapp MY_ENV_VAR='value'

#Unset env var:
dokku config:unset myapp MY_ENV_VAR

#Set global env var:
dokku config:set MY_ENV_VAR='value' --global

How I set up my wordpress sites on digitalocean with dokku

I recently discovered two great joys in my IT life: one is digitalocean where I can set up a droplet and have my own server in no time, the other one is docker/dokku. Docker alone is great, but dokku makes deployments a breeze.. it is so close to the heroku experience that it’s almost poignant. I took the easy road and created a dokku droplet.

I’m skipping a lot of steps here such as actually creating a DigitalOcean droplet for dokku and so on but that info can be found here. Also I’d like to say that this specific recipe works for me but your mileage may vary. There’s a lot of resources about setting up wp on dokku out there.

 1. Get wordpress

git clone blog
cd blog

2. Modify wordpress according to your needs

Your wp-config should have the following:

$table_prefix  = 'myblog_';

This is especially useful as you have more than one blog on the same mysql instance. I usually just create one mysql docker instance for all blogs and let each of them use a different table prefix. Works like a charm and limits resources.

And the database settings as follows:

define('DB_NAME', getenv('BLOGS_DB_NAME'));
define('DB_USER', getenv('BLOGS_DB_USER'));
define('DB_PASSWORD', getenv('BLOGS_DB_PASSWORD'));
define('DB_HOST', getenv('BLOGS_DB_HOST'));

3. Set the dokku remote

git remote add dokku dokku@:

If your server is and your blog is called myblog this would be:

4. Creating the database

Now with the mysql plugin for dokku installed we can do:

dokku mysql:create blogs_database

And the configuration vars we have set in the wp_config. I’m using one for all so I’m setting these configurations with the –global flag:

dokku config:set --global BLOGS_DB_NAME='blogs_database'
dokku config:set --global BLOGS_DB_USER='mysql'
dokku config:set --global BLOGS_DB_PASSWORD='8920734jfdsakljfFDAFD7897432987'
dokku config:set --global BLOGS_DB_HOST='dokku-mysql-blogs-database:3306'

Finally we’ll link it to the app we’ll deploy (can be done for multiple apps):

dokku mysqldb:link blogs_database myblog

5. Push to deploy

This ideally should be as simple as doing:

git push dokku master

If nothing happens after pushing probably the ssh key on dokku is incorrect. It will simply silently fail and do nothing. Check the authorized_keys file (~/.ssh/authorized_keys). If your authorized_keys file on the Dokku droplet starts with “ssh-rsa” instead of “command=” remove the ssh-rsa line.

6. Choose your domain

If you have set one or more domains on your droplet you can use them setting them on your app like this:

dokku domains:add myblog

Otherwise you’ll get

7. Storage!

Use docker-options for this. It works fine. If you omit this step you will NOT have persistent plugins/themes/uploads and everything will be wiped clean each time you restart the server or redeploy your apps!

Create directories for your blogs. In case of myblog I like keeping them in the dokku home under a directory I call “volumes”. So:

su - dokku # So we don't need to change owner/permissions later
cd /home/dokku
mkdir volumes
cd volumes
mkdir myblog
cd myblog
mkdir plugins; mkdir themes; mkdir uploads;
#chmod them all to have public read/write access

Now back to root:

su - root

And now the real storage part:

dokku docker-options:add myblog run -v /home/dokku/volumes/homecoffeecode/themes:/app/wp-content/themes
dokku docker-options:add myblog run -v /home/dokku/volumes/homecoffeecode/plugins:/app/wp-content/plugins
dokku docker-options:add myblog run -v /home/dokku/volumes/homecoffeecode/uploads:/app/wp-content/uploads

This is very important! Failing to set this will result in losing all assets/themes/plugins upon restarting any of your wordpress instances.

Also very important is the file upload limit (by default 2mb) that must be set in the nginx configuration as follows:

mkdir /home/dokku/myblog/nginx.conf.d/
echo 'client_max_body_size 50M;' > /home/dokku/myblog/nginx.conf.d/upload.conf
chown dokku:dokku /home/dokku/myblog/nginx.conf.d/upload.conf
service nginx reload

8. Memory

The dokku droplet needs memory… so the 1GB is the minimum viable option. Also the best thing is to just add some swap to make things easier during deployments (especially wordpress or rails). To add swap space do the following:

as root:

dd if=/dev/zero of=/extraswap bs=1M count=512
mkswap /extraswap