Joel, sometimes @jayroh

menu

Auto-delivering Downloaded Kindle Books

30 Mar 2014

I will often buy self-published programming books and send them to my kindle (and iPad, and iPhone) via email. Amazon's kindle platform will allow you to distribute documents (books) to your devices via custom email addresses. As mentioned I have three devices that I will often read from and need to send emails to those three with a downloaded mobi attachment. This is far from difficult but annoying enough that it could probably be automated. So I did.

You will need to allow an email address of yours to send the documents to kindle. Visit your kindle settings page and approve the email address you will be using (your Gmail address).

Tools necessary:

  1. Hazel. Download and purchase it. It's worth it.
  2. sendemail. Install with homebrew - brew install sendemail. Done!

Open up Hazel's preferences, select the Downloads directory, and add a new rule:

image

Where the embedded script looks similar to the command below. Note that the important part here is -a $1 where this interpolates the path to the mobi file and sets it as the attached file.

sendemail \
 -t your.kindle.email@kindle.com your.other.email@kindle.com \
 -f your.google.username@gmail.com \
 -u "New book" \
 -m "See attached" \
 -a $1 \
 -s smtp.gmail.com:587 \
 -o tls=yes \
 -xu your.google.username \
 -xp your_google_password

That's it!

When you download a mobi file it will (semi-)instantly delivered to your kindle-capable devices. VoilĂ !

Timezones

17 Feb 2014

Maintain Style with Rubocop

06 Feb 2014

Have you heard of this Rubocop yet? It's a static code analysis tool that enforces many of the guidelines outlined in the community Ruby Style Guide. Despite my initial hesitance — it felt a little "cargo-cult'y" — there are several reasons why I consider something like Rubocop valuable and fantastic.

As a development team grows the importance of keeping everyone moving in the same direction increases. The time spent discussing and commenting on pull-requests over innocuous details like trailing whitespace, tabs vs spaces, single vs double quotes, single line {} vs multi-line do; end; blocks. Over time it adds up. Why waste time when it can be automated?

It effectively helps remove a bit of human emotion from the code review process - the possibility that someone could misconstrue a litany of style-related comments in a pull-request as being personal. When someone gets hits with a few dozen "white-space" or "single quotes" comments in a PR, said person might consider it an exercise in nit-picking.

"This asshole is having a blast nit-picking my code" 1

This happens. Like it or not. We're human. We have feelings, however irrational they may be. Offloading this responsibility to a machine effectively takes this off the table. Nothing personal, right?

Last but certainly not least, even though I've been working with ruby for a long while, there are the occasional tidbits of style or best-practice that have fallen through the cracks - I had just not seen them. In going through the process of adjusting my own code these are bubbled up to the surface.

Now for something practical

Having said that - here are a few tips on getting Rubocop into your codebase today! 2

  • Create a full Rubocop config with all of the "cops" set to false. Turn them on one by one and clean things up offense by offense. Running everything all at once may be overwhelming. Open up that YAML and start turning things on incrementally.
rubocop --auto-gen-config && mv rubocop-todo.yml .rubocop.yml
" run rubocop through the entire project in my tmux window and pane of choice
map <leader>bc :call Send_to_Tmux("rubocop\n")<CR> 

" run rubocop on the current file in my tmux window and pane of choice
map <leader>bo :call Send_to_Tmux("rubocop ". expand('%:p') ."\n")<CR>
  • After your codebase is in a clean state, pull it in with your other default rake tasks. After adding and bundling rubocop to your project, a hypothetical Rakefile with rspec and Rubocop as the default tasks could look like:
require File.expand_path('../config/application', __FILE__)
MyApp::Application.load_tasks

if %w(development test).include? Rails.env
  require 'rubocop/rake_task'
  Rubocop::RakeTask.new

  task(:default).clear
  task default: [:spec, :rubocop]
end

At this point you wouldn't have to think about running rubocop as it acts as a part of your test suite.

Last thought - it speaks volumes when a language adopts this idea as a core part of its feature-set. Just look at Go.

So what are you waiting for? Try it out and let me know what you think!


1 A worthwhile read regarding this - you are not your code.

2 It may be a good idea to start by create a feature branch tackling just the task of cleaning up a single section of a codebase. Start with one bucket - like your models for example.

close
Joel Oliveira

Hi, I'm Joel.

I'm a software engineer in Boston working at an early stage startup. You can follow me on twitter at @jayroh.

Articles from 2012

Articles from 2007