Tuimoji: A terminal based emoji picker
&& [ linux ] && 0 comments
Tuimoji is a terminal (text) based emoji chooser, similar to gnome-characters, but with less suck. 🔥🔥💻🔥🔥
I wrote tuimoji because searching for the appropriate emoji always seemed cumbersome and was one of the least optimized portions of my workflow. Welcome to my life.
As of now it only supports Linux. It requires python3 and xclip to be installed.
You can install it using pip:
pip3 install tuimoji
There is also a package available on the Arch Linux AUR.
The sources, as usual, are available on Github.
Customizing grml-zsh-config
&& [ linux ] && 0 comments
Ever heard of grml-zsh-config? Maybe not, but it’s possible you may have used it. It’s the zsh config for the Arch linux installer, as well as some Debian systems.
Grml is a nice alternative to heavy and bloated config frameworks like oh-my-zsh and pretzo (even on a modern machine I’ve seen zsh take over a second to load using oh-my-zsh with just a few plugins enabled).
Unfortunately, grml is not that easy to configure, and the available documentation is a little lacking. With a few tweaks though, I managed to get a proper shell out of grml.
Grml provides almost everything I’d like out of zsh by default. Here’s the out of the box prompt:
{{< highlight shell >}}
austin@nightmare ~/Documents/pdpv2 (git)-[master] %
{{< / highlight >}}
Not bad, but room for improvement. Let’s make some changes. All code below belongs
in your .zshrc
Change the prompt layout.
There are a few items in the prompt that make it unnecessarily long and redundant.
I don’t often forget who I am or where I’m at, so let’s remove the user@host
nonsense. I also like my prompt to contain a newline, so input is consistently
placed on the far left.
{{< highlight shell >}}
zstyle ':prompt:grml:left:setup' items rc change-root path vcs newline percent
{{< / highlight >}}
Now you’ll end up with something like this:
{{< highlight shell >}}
~/Documents/pdpv2 (git)-[master]
%
{{< / highlight >}}
Better git information.
It’d be nice to see if there are any unstaged/staged changes in the current
working directory. While we’re at it, let’s get rid of the lame (git)- part of
the prompt. Nobody uses svn anymore, right?
Place this above the zstyle ':prompt:grml:left:setup' line in your .zshrc:
{{< highlight shell >}}
autoload -U colors && colors
zstyle ':vcs_info:*' enable git
zstyle ':vcs_info:*' check-for-changes true
zstyle ':vcs_info:*' unstagedstr '!'
zstyle ':vcs_info:*' stagedstr '+'
zstyle ':vcs_info:git*' formats "%{${fg[cyan]}%}[%{${fg[blue]}%}%b%{${fg[yellow]}%}%m%u%c%{${fg[cyan]}%}]%{$reset_color%}"
{{< / highlight >}}
This will load only git support, check for changes in the working directory and add some icons to the prompt if there are changes. It also gets rid of the vcs type display and adds some pretty colors. Your prompt should look something like this now:
{{< highlight shell >}}
~/Documents/pdpv2 [master!]
%
{{< / highlight >}}
Add the current virtualenv.
Every self respecting python developer wants the currently activated virtualenv to appear in their prompt. Due to the way grml configures itself virtualenv’s normal mechanism does not work. Here’s how with grml. In your .zshrc:
{{< highlight shell >}}
source /usr/bin/virtualenvwrapper.sh
function virtual_env_prompt () {
REPLY=${VIRTUAL_ENV+(${VIRTUAL_ENV:t}) }
}
grml_theme_add_token virtual-env -f virtual_env_prompt '%F{magenta}' '%f'
{{< / highlight >}}
Lastly, add the new virtual-env token to the layout:
{{< highlight shell >}}
zstyle ':prompt:grml:left:setup' items rc change-root path virtual-env vcs newline percent
{{< / highlight >}}
You should end up with something like this if in the “testenv” virtualenv:
{{< highlight shell >}}
~/Documents/pdpv2 (testenv) [master]
%
{{< / highlight >}}
Check out the cheat sheet
Grml is a lot more than just a prompt. It adds a bunch of aliases and functions as well. Check out the exhaustive cheat sheet if you’d like to learn more. Enjoy!
ArchLabs Linux Review (and tips)
&& [ linux ] && 0 comments
Today I’m writing a review of the ArchLabs linux distro. Have you ever wanted a badass Arch linux install, complete with an openbox window manager, conky, and dark gtk themes, worthy of the top spot on /r/unixporn? Of course you do, but if you’re anything like me, you’re a busier person than you were when you were 15, and you no longer have the time, or the inclination.
Enter ArchLabs, elite Arch Linux for the lazy:
Installation
To start, the ArchLabs ISO is a bootable live environment, so you can test it out right away. You’ll get a fairly minimal Openbox desktop, with a panel, conky, and some other goodies. Once you decide to install, because why wouldn’t you, the curses based installer will launch in a new terminal:
The installer is amazing, and way easier to use than many of the other fully graphical ones I have used. I am seriously impressed with how simply and easily it’ll bootstrap a system for you, with plenty of options (including LuKS and LVM) but perfectly sane defaults. The entire install took about 5 minutes.
First Boot
Once you boot into your system, you’re greeted with a post-install script, which is also a delight to use:
This post-install script gives you the option to install additional desktop environments, a login manager, nvidia drivers, and some other stuff. Super cool.
Once you’re done with that, you’re asked to reboot one more time (probably only necessary if you’ve chosen to install a login manager or video drivers) and then you’re done, and using your new install.
Fixes
While my first impressions of ArchLabs are that it’s a very well put together distro, there were still some things I needed to fix/tweak once I started actually using it. Theses might come in handy for others, but hopefully they quickly become irrelevant.
Firefox text inputs are unreadable.
The dreaded dark gtk theme/Firefox combo. You’d thing we’d be past this by now,
but alas, not so. Luckily I found
this bug and comment
which suggested adding widget.content.gtk-theme-override to Adwaita:light
in about:config (right click, new, add that key and value).
Audacious can’t play audio streams.
What am I to do without my Defcon radio? This is just due to a missing package:
$ aurman -S neon
No shortcut for locking the screen!
ArchLabs provides a bunch of keyboard shortcuts for all sorts of stuff, but not activating the screen lock. How does that make any sense?
Edit ~./config/openbox/rc.xml and add the following contents to the
<keyboard> section (just place it next to another keybind):
{{< highlight xml >}}
<keybind key="W-l">
<action name="Execute">
<command>i3lock-fancy</command>
</action>
</keybind>
{{< / highlight >}}
There is already a keybind for W-l, one of the many unmaximize ones, delete that one too. Now you can use super (windows key) + l to the lock the screen.
P.S. i3lock-fancy is really cool.
No image viewer
There just isn’t one included at all, oddly enough. Try feh:
aurman -S feh
Dynamic Module Loading in Python
&& [ code, python ] && 0 comments
There are some cases where dynamically loading code that your application doesn’t know about ahead of time can be useful. For example, perhaps you’re writing a text editor and you want it to be extendible via plugins. Or you are writing a library and you’d like your users to be able to provide their own integrations for 3rd party services. In any case, this pattern is very achievable in python.
For this post, let’s write a program that collects the latest top stories from
various news aggregator sites like Reddit, Hacker News, etc. Let’s call it
ubernews.py. We want to make it super easy for anyone who downloads UberNews
to add their own modules for their favorite news sites. So UberNews needs to
be able to access modules which aren’t part of it’s own codebase.
Since UberNews is pretty lame, it’s only going to ship with Reddit support by default. Once we have Reddit working, we’ll write a module for Hacker News (as if we were another developer) and load it into the main application.
First, some requirements. We’ll be making some http calls and
since I’m not a masochist, we’ll be using the requests library, so make
sure you install it into a virtualenv or have access to it globally.
Additionally, we’re going to explore some cool new features of Python 3.7, specifically Data Classes so make sure you are running at least Python 3.7.
Ok, let’s get started with a boilerplate ubernews.py:
{{< highlight python >}}
!/bin/env python3
from dataclasses import dataclass from datetime import datetime
@dataclass class NewsItem(): score: int title: str url: str time: datetime
class RedditNews: def get_news(self): return [ NewsItem(score=1, title=’test’, url=’example.com’, time=datetime.now()) ]
def main(): print(‘Top news for today:’) reddit = RedditNews() for news_item in reddit.get_news(): print(news_item)
if name == ‘main’: main()
{{< / highlight >}}
And the output:
$ ./ubernews.py
Top news for today:
NewsItem(score=1, title='test', url='example.com', time=datetime.datetime(2018, 8, 23, 17, 24, 8, 417234))
Let’s go through the members of this module.
First, we have the NewsItem dataclass. If you are not familiar with Python
Data Classes, basically they are syntatic sugar for generating classes with
auto generated methods, like __init__() and __repr__. Here we are simply
using it do define a class with a few attributes, without needing to write
a boilerplate __init__() function. We’ll get into some of the more useful
features of Data Classes later.
Next we have the RedditNews class. It has a single method, get_news().
All it does is return a list of NewsItems, and for now a single, fake one.
Next, our main() function simply prints out a banner message and all of
redditNews’s news items.
Let’s make this program actually do something:
A Not so Dramatiq Change: A Celery Alternative
&& [ code, astronomy ] && 3 comments
Both Celery and Dramatiq are asynchronous task
processing libraries. You’d use them when you want to be able to parallelize Python code,
and you need more than the multiprocess module offers, like persistent distributes queues, automatic
retries, and result handling.
I’ve been using Celery for almost my entire career, and it’s treated me well. Recently I’ve started to become frustrated with it. There have been numerous regressions that have broken my code, as well as some totally inexplicable issues in the last few months (that last one is the reason I started looking for alternatives).
I know Celery is an open source project maintained by volunteers, and I am grateful for all the hard work that has been put into it over the years. I just can no longer in good faith recommend it for new projects.
I recently started a new project of my own in which I need to process and store millions of images of transient astronomical phenomena from a stream of alerts coming from the Zwicky Transient Facility. A perfect use case for a task queue.
Enter Dramatiq: “a distributed task processing library for Python with a focus on simplicity, reliability and performance”. A quick look at the User Guide gives the impression that the library is easy to use.
Setting up Dramatiq is indeed simple. You’ll need a broker though, either Rabbitmq or Redis. I chose Redis as it is in general a kickass piece of software that has many other uses. Unfortunately the Dramatiq docs assume you are using Rabbitmq and it took me some sleuthing to figure out how to hook it up to Redis. Fortunately, it’s pretty easy. To use a Redis broker with Dramatiq:
{{< highlight python >}} import dramatiq from dramatiq.brokers.redis import RedisBroker
redis_broker = RedisBroker(url=f’redis://{REDIS_HOST}:6379/0’) dramatiq.set_broker(redis_broker)
{{< / highlight >}}
You like that format string literal I threw in there? Guess what, Dramatiq only supports Python >= 3.5.
All that was left to do was add the @dramatiq.actor annotation to my ingest method, start a worker,
and boom, I was processing tasks in parallel. Even the default error handling is to retry the task with an exponential backoff, which is exactly what I
wanted. Amazing what you can do with 3 lines of code.
Once I was processing tasks I did notice one issue: the logging. By default Dramatiq logs all arguments to all tasks received. That’s fine if all you’re doing is sending an email now and then, but not if you’re processing millions of images with huge arguments.
This is where some lack of documentation and “internet history” for Dramatiq shows. I could not find a clear method for disabling or reducing the logging. Luckily the api reference shows that you can directly access the logger on an Actor. Here is an example of the method I used to disable logging from Dramatiq actors:
{{< highlight python >}}
@dramatiq.actor def do_stuff(): print(‘Im a task!’)
do_stuff.logger.setLevel(logging.CRITICAL)
{{< / highlight >}}
Setting the level of the Actor logger to CRITICAL quiets anything less than critical, and I think the logs I were seeing were either INFO or DEBUG. Not the cleanest solution, but it works.
Despite not being an exhaustive test, I’m so far impressed with Dramatiq. It’s chugging away nicely as I write this. Assuming development continues, I’ll probably continue to use it instead of Celery for future projects.
Hugo Pagination Partial for Bootstrap4
&& [ code ] && 0 comments
Hugo’s internal template for pagination claims it works with Bootstrap styles. That may have been the case for Bootstrap3, but now that 4 is out, it requires a few more classes.
Below is a template that can be used as a partial in your theme based on Hugo’s internal template with additional Bootstrap4 classes. You can see it in action on this blog’s front page.
{{< highlight go-html-template >}} {{ $pag := $.Paginator }} {{ if gt $pag.TotalPages 1 }}
-
{{ with $pag.First }}
- {{ end }}
- {{ $.Scratch.Set "__paginator.ellipsed" false }} {{ range $pag.Pagers }} {{ $right := sub .TotalPages .PageNumber }} {{ $showNumber := or (le .PageNumber 3) (eq $right 0) }} {{ $showNumber := or $showNumber (and (gt .PageNumber (sub $pag.PageNumber 2)) (lt .PageNumber (add $pag.PageNumber 2))) }} {{ if $showNumber }} {{ $.Scratch.Set "__paginator.ellipsed" false }} {{ $.Scratch.Set "__paginator.shouldEllipse" false }} {{ else }} {{ $.Scratch.Set "__paginator.shouldEllipse" (not ($.Scratch.Get "__paginator.ellipsed") ) }} {{ $.Scratch.Set "__paginator.ellipsed" true }} {{ end }} {{ if $showNumber }}
- {{ .PageNumber }} {{ else if ($.Scratch.Get "__paginator.shouldEllipse") }}
- {{ end }} {{ end }}
- {{ with $pag.Last }}
- {{ end }}
{{ end }} {{< / highlight >}}
Imaging the Space Tesla
&& [ astronomy ] && 0 comments
Back in the beginning of February SpaceX launched their Falcon Heavy rocket to much fanfare and excitement. This test launch also had a test payload: Starman, a mannequin in a prototype SpaceX space suit behind the wheel of a cherry red Tesla Roadster. Spaceman was successfully inserted into a heliocentric orbit and there he’ll remain for millions of years.
For a few days Spaceman was close enough to earth to be visible by professional grade telescopes. As an employee of a company that builds and deploys a network of robotic telescopes I had to see if I could get an image of this guy.
Dr. Tim lister and I both set up observations, but of course Tim’s (who studies near earth objects) came back in better quality. I did some stacking and scaling and ended up with a .gif. Ladies and gentlemen, I present to you Starman in 9 parts:

The image consists of 9x32 second exposures on one of our 1 Meter telescopes in Cerro Tololo, Chile. The images were captured around 2018-02-09 08:43 UTC.
See if you can find the faintly visible galaxy in the top left corner of the image.
Godspeed, Starman.
Line by Line Simple but Usable VIM Config
&& [ code ] && 0 comments
VIM is a great editor, but it’s defaults are a little lacking. Fortunately
it’s also extremely configurable. This leads many people (myself included),
to scour the internet for lines of internet wisdom to copy in paste into
their .vimrc files until they get something that works for them. Before
you know it you have 300 lines of unintelligible gobblegook. In this post,
(which I’ve started writing in vanilla vim) I’m going to go line by line
through individual config items to construct a simple but usable .vimrc
without too much magic or frills.
You can download the .vimrc in full as a github gist
Tabs vs. Spaces
I’m a spaces guy, so let’s make vim use spaces instead of tabs. While we’re at it we should make tabs use 4 spaces by default (since I’m also a python guy)
{{< highlight vimrc >}} set expandtab ” tabs are spaces set shiftwidth=4 ” size of indents in spaces set softtabstop=4 ” simulate tabs with this many spaces {{< / highlight >}}
It’s possible to change the indent level for different filetypes:
{{< highlight vimrc >}}
” FileType specific tab overrides
filetype plugin indent on ” Enable filetype detection and
Line numbers
It’s nice to have line numbers, so let’s turn those on. Once you do this it get’s annoying to select text with the mouse, though. So let’s also enable mouse in auto mode so that vim doesn’t select line numbers (and goes into visual mode).
{{< highlight vimrc >}} ” Line numbers and mouse set number ” enable line numbers set mouse=a ” enable mouse in auto mode {{< / highlight >}}
Searching
Searching in vim by default is pretty good but there are a few options to make it even better.
{{< highlight vimrc >}} ” Searching set incsearch ” don’t wait for the enter key to start searching set hlsearch ” highlight search results {{< / highlight >}}
Syntax highlighting and themes
It’d be nice to have some pretty syntax highlighting, so we’ll enable it and also set a nicer theme than default.
{{< highlight vimrc >}} ” Syntax and colors syntax enable ” turn on syntax highlighting colorscheme slate ” use the slate theme {{< / highlight >}}
Tabs
You can navigate tabs in vim using gT and gt to move backwards and forwards, respectively. But what about navigating to the previously used tab? I’ll admit, what follows is still magic to me.
{{< highlight vimrc >}}
” Map gl to the previously used tab
let g:lasttab = 1
nmap gl :exe “tabn “.g:lasttab
Trimming trailing whitespace
If you’re editor doesn’t trim trailing whitespace and you work with other people using version control, shame on you. The following command will trim trailing whitespace from all lines in a file. Additionally, we will call it every time we save the file.
{{< highlight vimrc >}} ” Strip trailing whitespace fun! TrimWhitespace() let l:save = winsaveview() %s/\s+$//e call winrestview(l:save) endfun
autocmd BufWritePre * :call TrimWhitespace() ” Call TrimWhitespace on save {{< / highlight >}}
Miscellaneous
Theses are settings I find useful, but don’t fit in any other category
{{< highlight vimrc >}} ” Misc set wildmenu ” show tab completions for commands inline
” Files to ignore for various auto completion commands set wildignore+=/tmp/,.so,.swp,.zip,.pyc,pycache,node_modules
” Remap the dd shortcut to not nuke whatever was in the yank buffer nnoremap d “_d vnoremap d “_d {{< / highlight >}}
Going further
That concludes all the settings I feel make vim a useful text editor. If you want to use vim as a full fledged IDE, there are hundreds of extra settings and plugins to choose from. In my old age, I much prefer simplicity. If I need a fully fledged IDE, I’ll reach for something like sublime text instead.
GNOME Notifications for Remote Weechat
&& [ code ] && 0 comments
I ❤ Weechat. It’s my IRC client of choice. But I also use it for gtalk and Slack. All my conversations in one convenient interface. Even better, I run it in a remote tmux session so I can pick up wherever I left off from anywhere.
The only annoying thing about this setup was the lack of real notifications for private messages or mentions. So I wrote Weelisten.

Weelisten is a small python script that leverages Weechat’s relay protocol, python 3 asyncio and libnotify so I can get awesome native notifications on my desktop.
Sounds useful? Get it on Github
Turn Off Mobile Data
&& [ other ] && 0 comments
There’s a lot of talk on the web about the dangers of always on technology and addictive social media. I’m here to give you a life pro tip.
Turn off mobile data.
You’ll have wireless in most places anyway, but not being connected outside of wifi means less distractions on walks, at dinner, or in the movies. You can still turn on data if you really need it, but the barrier is high enough that you’re unlikely to use it to get a quick hit of reddit.
I started doing this when AT&T made me give up my trusty nokia dumb phone and I got a smart phone. Seems to work great.


