I blog about anything I find interesting, and since I have a lot of varied interests, my blog entries are kind of all over the place. You can browse my tags to sort them by topic and see which ones I frequently write about, or the archive has a complete history of my posts, dating back to 2008!
Besides my blog, I have pages for my creative projects, which are linked to on the navigation bar.
I write a lot about Linux and Android, Minecraft, and I like to rant about stuff. Generally anything that makes me curious. Also check out my Bookmarks for all sorts of cool websites about various topics I'm interested in.
For the geeks: this website respects your privacy and doesn't run any third party ads or analytics. This site speaks HTTP and doesn't require any JavaScript to work.
A review of Linux desktop environmentsThe next version of Fedora (24) is coming out soon, so I decided a couple weeks ago that I'd take a tour of all the different desktop environments and see if I like any of them enough to switch from Xfce. My original desktop environment of choice was GNOME 2, and I had jumped ship to Xfce after GNOME 3 was released because I was no fan of the tablet-focused, feature-stripped interface of the new desktop and GNOME 2.32 was, in my opinion, the pinnacle of the desktop metaphor for Linux.
...and I don't mean by writing this post. ;)
I run Kirsle.net on a custom Python CMS I wrote called Rophako and I just added a bunch of improvements to the blog platform in it.
I've been wanting to start working on some larger blog articles, things that could take me a few days to write, and my blog had no support for saving drafts. You had to write and publish your blog posts in one sitting. The only alternative was to make the posts "private," where only the site admin(s) can see them, but that would still cause them to "go live" and be listed along with normal public posts and was a messy workaround.
So now my blogging platform has proper support for saving drafts; they stay invisible (even for admins) on all of the normal blog pages, and can only be seen in bulk on a dedicated "drafts" page. While I was putting all that together, I added similar support for private posts, giving them their own index too where you can see only those posts rather than have to go hunting for them.
For visibility purposes, draft and private posts get little tags next to their author/date lines so an admin can tell at a glance what they're looking at. Normal end users won't see those, though. ;)
I've also finally implemented a feature I wanted to from the beginning: sticky posts. The blog database schema has always had a "sticky" field, but it was always set to false
and the Create/Edit Post page gave no way to change that value. The back-end code did have logic to bucket sticky posts higher on the index list than normal ones, but there was no (easy) way to make a post sticky to begin with.
Sticky posts will also get a little "[Sticky]" tag next to their author/date lines, and those ones can be seen by normal end users.
I also fixed a handful of smaller bugs/problems. I've removed the ability to set a custom date/time when editing a blog post. This caused confusion between your web browser's local time and the time zone of the server. So instead, the server always picks the latest UTC Unix time on new entries. When editing an existing entry, there's a checkbox option to reset the time to latest when saving, if you want to bump an old post to the top.
In user interface and software design, the principle of least astonishment states that "if a necessary feature has a high astonishment factor, it may be necessary to redesign the feature." It means that your user interface should behave in a way that the user expects, based on their prior knowledge of how similar interfaces behave.
This is a rant about Mac OS X.
This is a cool tip I picked up from checking out other peoples' Go projects.
When you're new to Go, the documentation tells you about $GOPATH
which tells Go where to install packages and where the source codes to your project and its dependencies live. A lot of people might set $GOPATH
to be $HOME/go
, and work on their projects out of ~/go/src/github.com/myname/myproject
.
If you're a JavaScript developer (in the Node.js world), you're probably used to typing in commands like sudo npm install -g gulp-cli
(unless you installed Node via Homebrew on Mac OS X so that your local user account owns /usr/local
). But I never liked the idea of having files installed under /usr/local
(root-owned or otherwise) that my package manager didn't know about, and would prefer to have these global npm commands installed into a user-specific root instead.
Here's how to set this up.
First, edit your .bashrc
(or .bash_profile
or .zshrc
) to add some environment variables:
# Node/npm
export NPM_PACKAGES="${HOME}/.npm-global-pkg"
export NODE_PATH="${NPM_PACKAGES}/lib/node_modules:${NODE_PATH}"
export PATH="${NPM_PACKAGES}/bin:$PATH"
What this does:
$NPM_PACKAGES
is a variable we use so we don't have to define the path more than once (Node/npm doesn't use this variable itself). We want our global modules to be installed under ~/.npm-global-pkg
$NODE_PATH
is used by Node when you require()
a module; if the module isn't in the local project's directory it will try to import it from our new global directory.$PATH
to add ~/.npm-global-pkg/bin
, so when we install a global npm package that contains a command line program (like gulp
, coffee
, bower
, etc.) it's available as a command in our shell.Then, create or edit the file ~/.npmrc
to specify the same path from $NPM_PACKAGES
as your npm prefix:
prefix = ${HOME}/.npm-global-pkg
This tells Node where to install packages when you run npm install -g
.
Restart your terminal session or re-source your configuration so the environment variables take effect. Now, when you run a command like (the sudo-less!) npm install -g coffee-script
, it will place its binary in ~/.npm-global-pkg/bin/coffee
.
PSA: The "battery optimization" feature in Android 6.0 Marshmallow may be causing your Gmail to not notify you of e-mails until it's way too late and other apps to not notify you about anything ever.
I first caught on to this when I stumbled upon a Reddit thread on /r/Android. Essentially, Android 6.0 added a feature called Doze which puts apps to sleep while the phone is locked/not in use, giving them only brief windows of opportunity to check for any new notifications before being put back to sleep. The frequency between these wake opportunities depends on how long the phone has been locked. It sounds like a good idea in theory, but the execution was done very poorly.
That thread was specifically about apps like Gmail and Inbox. Users were seeing issues where Gmail wouldn't notify them about new e-mails until several hours after the e-mails came in. This is because the Gmail app was getting "dozed" and was unable to check for any new messages (or receive push notifications, or whatever it does). The work-around is to disable the "battery optimization" for the Gmail app.
To do so:
Doze makes it sound like not optimizing apps will hurt your battery life. This may be true for poorly written apps, but it's pretty safe to allow Gmail to not be put to sleep. Before Android 6.0, Doze wasn't even a feature anyway and there weren't a lot of complaints about battery life. Personally, I just disabled battery optimization for a small handful of apps that I care more about, including Gmail and Hangouts.
In addition to Gmail, a few other apps I found to be completely broken when they're being "optimized":
Google Opinion Rewards: Get Google Play credit for answering surveys. I noticed I wasn't getting any surveys offered for several weeks, and figured the Doze feature was to blame. I disabled it on the Google Opinion Rewards last night, and got a survey this morning.
My theory is that this app only receives surveys if there is one available at the time the app asks for it. Since the app was checking very infrequently, it was missing all the surveys.
Tasker: I have a Tasker task set up to automatically connect to my VPN when my phone joins certain WiFi networks. I was noticing that it was failing to do this the majority of the time. I'd have to open Tasker and manually play the Connect VPN task and then it would sorta work, but sometimes it would fail to run the Disconnect VPN task when I left the WiFi network.
Disabling battery optimization for Tasker fixed this problem.
Tumblr: I was getting no notifications at all from this app, ever. Disabling battery optimization fixed this problem.
Reddit Sync Pro: I was getting no notifications of new messages on this app until I manually opened it. Again, disabling the optimization helped.
So if you have any apps that have been oddly quiet for the past several weeks or months and you're running Android 6.0, check if the "battery optimization" feature is to blame.
The free SSL certificate authority Let's Encrypt went into public beta earlier this month, and I updated all of my sites to use SSL now. I still had several more months before kirsle.net's old certificate from Namecheap expired, but I switched to the Let's Encrypt certificate because I could include all my subdomains instead of only the www
one.
Check out their website and get free SSL certificates for your sites, too. I'm just writing this blog with some personal tips for how I configured my nginx server and a Python script I wrote to automate the process of renewing my certificates every month (Let's Encrypt certs expire every 90 days).
This is something I wanted to rant about for a while: event loops in programming.
This post is specifically talking about programming languages that don't have their own built-in async model, and instead left it up to the community to create their own event loop modules instead. And how most of those modules don't get along well with the others.
Something pretty odd that's happened to me on more than a couple of occasions:
I'll wake up in the morning, and then a couple minutes later people start sending me messages on Google Hangouts, so my phone's making a bunch of noise. If it's early enough in the morning, some of those messages will even say things like, "you're up early."
The thing is though, I didn't even touch my phone yet. I didn't even look at my phone.
Messages like this don't tend to wake me up, but instead I don't start getting messages until just after I'm awake.
Over the last couple months I've been slowly working on rewriting RiveScript in yet another programming language: Google's Go language! It's also my first project in Go, which is what tends to be the case (rewriting RiveScript in Java and Python were my first projects in those languages, too).
But this is the last time I'm going to be rewriting RiveScript from scratch.
0.0019s
.