Tuesday, March 31, 2015

Designing for String/Message and Layout Localization

As you'd imagine, localization is a deep topic since it touches language, local/cultural history of formatting and user interfaces, etc. I was familiar with a little of this (e.g. differences in date formats, reading right to left vs. left to right vs. ...).

Searching around a bit, I found a several resources about string localization and layout that might be helpful:

Anyone have any book or site suggestions that discuss the (non-development language/framework) specifics of localization?

Saturday, March 14, 2015

Happy Pi Day

Today is arguably the most Pi Day we will probably ever experience until 3015, 3/14/15 (unless you round up, then it would be 3/14/16). The Julian Calendar was introduced in 45 BC, so prior to that, it's tough for me to say which dates were more Pi.

Although any March 14th is Pi Day, here is a partial list of some of the "most" Pi Days in Base 10 in order of precedence, in my opinion:

Base 10 M/DD/YY, M/DD/YYY, or M/DD/YYYY format:

  • March 14th, 1592 AD (or BC) - known as Ultimate Pi Day: the largest correspondence between calendar dates and significant digits of pi since the introduction of the Julian calendar (according to Wikipedia).
  • March 14th, 159 AD (or BC) - debatable: 3/14/0159 is less Pi because of the 0
  • March 14th, 15 AD (or BC) and 16 may also be acceptable if you round up
  • March 14th, 1 AD (or BC)
  • March 14th on any year ending in 15 (or 16 if you round up), e.g. 3/14/15 (or 3/14/16)

Output Network Outages to a File with Netout

If you want to just to check that an individual computer has connectivity, pinging can be a decent way to do that. While you can just start up a ping, you may be looking for something that only outputs the time periods of outages. After a connectivity problem at work after an office move that seemed to only affect my computer, I went home and wrote a small script called netout to help me identify and quantify these outages.

Though it can take more options, it's simplest usage is this:

netout 

Which logs any problems pinging 8.8.8.8 (google-public-dns-a.google.com) to outages_8.8.8.8.txt, e.g.:

Outage started 2015-03-13 22:05:56 -0400 (No route to host) and ended 2015-03-13 22:06:06 -0400
Outage started 2015-03-13 22:06:12 -0400 (No route to host) and ended 2015-03-13 22:06:16 -0400
Outage started 2015-03-13 22:06:32 -0400 (No route to host) and ended 2015-03-13 22:06:36 -0400

If you want to tail that file, in another terminal window, or even on another computer if you log to a share, do:

tail -f outages_8.8.8.8.txt

The output is not 100% accurate because long ping times (over 500ms by default) would be considered an outage, where it really may be a latency issue. Also, the reason specified for the outage is only the first error that comes back from what is assumed to be a failed ping, and that reason could change over time. Netout assumes you care more about the outages and their duration over a longer time period and logging those to a file. That's all it does.

And if you need something more, here are some other free tools:

  • Ping - Just using "ping 8.8.8.8 >> ping.log" is a great way to collect data to provide to an ISP, etc. about outages.
  • Nagios - free monitoring tool that's been around a long time and is a good choice for your organization, but overkill for simple monitoring.
  • MRTG - I remember this being used many years ago and is a great free tool. It is also overkill for just logging ping outages. This is what you use if you want to tinker and create your own outage page.
  • Smokeping - seems like a good tool, but at the time of writing, there was no (OS X) Homebrew recipe for it, and I didn't have time to perform the installation.
  • mtr - also been around a long time. It is like a minified console version of the above types of graphing tools with a one character status for checks, so it is easy to see status of lot of hosts at once.

See also this question on superuser.

Friday, March 13, 2015

Multiple SSH Tunnels on Login in OS X with Meerkat vs. SSH Tunnel Manager

Tried out a couple of apps to automate SSH tunneling today in OS X: Meerkat and SSH Tunnel Manager. Both are free apps that allow you to automatically SSH into multiple servers using those connections for multiple SSH tunnels.

Meerkat

Pros: free app that was abandoned but is still downloadable and free license provided by its author. Tested and seems to work at least partially in OS X 10.9.

Cons: is no longer maintained. I had one connection work and another not work. I manually killed one of its ssh processes and it didn't seem to restart it, at least not within a short time.

How to get setup:

  1. Download Meercat.
  2. Open the dmg and drag into Applications.
  3. Control-click open.
  4. Right-click on taskbar to mark as open on login.
  5. Use the wizard and plus buttons on each tab to setup your SSH connections and tunnels (read up on SSH tunneling to understand more).
  6. Mark everything to automatically open on start.
  7. Go to Quote, so that it will complain about a license.
  8. Download the Meercat license from the same page.
  9. Rename the file to zip, because it is a zip.
  10. Double-click to unzip.
  11. Double-click on the uncompressed license file which will install itself into Meerkat.

SSH Tunnel Manager

Pros: free app. Tested and seems to work in OS X 10.9. Much more featureful than Meerkat in terms of the encryption, etc. options to use with ssh. I manually killed one of its ssh processes and it restarted it quickly.

Cons: UI is not very polished and a little more complicated.

How to get setup:

  1. Download/install SSH Tunnel Manager from the App Store.
  2. Right-click on taskbar to mark as open on login.
  3. Here are some example instructions for configuration.
  4. Click options button and check auto connect.

Others/Alternatives

These are just a few of the options available. Also, just manually using SSH to tunnel or something like autossh to automatically restart might be a good solution.

Wednesday, February 11, 2015

Rails 4.x and Mail Gem Message Interceptors vs. Custom Delivery Methods

Currently in mailer you can write an interceptor (e.g. as an initializer) like:

  class MyInterceptor
    def self.delivering_email(message)
      # ... would do something with every email here, even if we don't actually send
    rescue => e
      # ... error handling code that tries to ensure an error won't be raised if you mail errors
    end
  end

ActionMailer::Base.register_interceptor(MyInterceptor)

and then if you wanted to only do the action with the message object in MyInterceptor but didn't want to actually send and you only want to not send in certain environments (like development, etc.), then in your Rails config you could do:

  config.action_mailer.raise_delivery_errors = false
  config.action_mailer.smtp_settings = {
      :address => nil
  }

But, that's a little clunky.

Instead, use a custom delivery method as described here and alluded to in Rails documentation, and currently barely mentioned in the Mail gem. For example:

In lib/my_mail_delivery_methods.rb:

require 'mail'

# these must be loaded prior to application configuration, but are too bulky to put into application.rb
# in anything but a require.

module AbleToDoSomethingToMail
  def do_something(message)
    # even though is in lib, still has access to models, etc.
  rescue => e
    begin
      # be careful about anything we do on recovery so we don't send email on error, if you have that set-up
    rescue => e2
      puts "#{e.message}\n#{e.backtrace.join("\n")}"
    end
  end
end

class DoSomethingToMailWithoutSend
  include AbleToDoSomethingToMail
  def initialize(values)
  end

  def deliver!(mail)
    persist_mail_message(mail)
  end
end

class DoSomethingToMailAndSendViaSmtp < ::Mail::SMTP 
  include AbleToDoSomethingToMail
  def initialize(values)
    super(values)
  end

  def deliver!(mail)
    persist_mail_message(mail)
    super(mail)
  end
end

Then in config/environments/development.rb, etc.:

  # ActionMailer settings
  config.action_mailer.perform_deliveries = true
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.delivery_method = DoSomethingToMailWithoutSend

And in config/environments/production.rb:

  # ActionMailer settings
  config.action_mailer.perform_deliveries = true
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.delivery_method = DoSomethingToMailAndSendViaSmtp
  config.action_mailer.smtp_settings = {
      :address => "your.mail.host"
  }

Sunday, January 11, 2015

Flashing a microSDHC in OS X 10.10 Yosemite for the Raspberry Pi Model B+

First, check out the Quick-start if you're totally new or the Installing Operating System Images on Mac OS documentation which hopefully should be up-to-date and more comprehensive. I'm just documenting this here from what I did a few weeks ago so that I don't lose it! :) I'm going to write this though for the non-tech savvy, just in case someone gets a Raspberry Pi B+ and really doesn't know what to do.

DO THE FOLLOWING AT YOUR OWN RISK. DOING THIS INCORRECTLY COULD LOSE ALL OR PART OF THE DATA ON YOUR COMPUTER. BE WARNED! I AM NOT RESPONSIBLE FOR YOUR ACTIONS.

First, if you didn't get one already, you'll need a microSDHC card and probably a MicroSDHC to SD Adapter.

Now download a disk image, probably from the Raspberry Pi Downloads page. This may take a long time.

In spotlight (click the magnifying glass to the upper-right), type terminal and enter.

In terminal, type:

diskutil list

This is the incredibly important part (and I'm not kidding). There is something on the left of each section that is output that tells you the identifier for each disk device, like /dev/disk0, /dev/disk1, /dev/disk2. Probably the first few will have things like Apple_CoreStorage, Apple_Boot, or Apple_HFS somewhere next to them. Those are NOT the ones you want. You need to look for the SD card, under that. It may not be obvious what it is, so be careful and don't accidentally erase an external drive, etc. In my case, it was /dev/disk2. Write that down!

Now, to attempt to unmount the card if it has been mounted, do this, replacing /dev/disk2 in the command with whatever disk is your SD:

sudo diskutil unmountDisk /dev/disk2

To flash your SD/microSDHC card, do this, replacing the part after if= with the pathname of your image and replacing the part after of= with whatever disk is your SD:

sudo dd bs=1m if=~/Downloads/2014-12-24-wheezy-raspbian.img of=/dev/disk2

That will probably also take a long time, and it just sits there, so don't assume it's locked up. After it's complete, remove the card and the microSDHC from that card and put the microSDHC into your Pi (it's a non-descript port on the side of the Pi), then just power it on after connecting a monitor or TV to the HDMI port. At the very least, you'll also want to plug a USB keyboard into it. When it comes on, it will go into setup. Note that after you setup and reboot, the default user is pi and default password is raspberry if you didn't change it.

Last thing: LATER if you want to erase the SD you flashed and make it a normal blank FAT32 formatted SD for use in a camera, etc., you'll need to erase the MBR (master boot record). To do that, use diskutil again to get the right disk number and do this command, replacing the part after of= with whatever disk is your SD:

sudo diskutil eraseDisk FAT32 SDCARD MBRFormat /dev/disk2

Monday, December 29, 2014

Casting Floats to BigDecimal in Ruby or Ruby on Rails

Rails requires 'bigdecimal' by default it seems, so only in (plain) Ruby (off Rails) do you need:

2.1.2 :001 > require 'bigdecimal'

In both Ruby and Ruby on Rails (though the stack is different):

2.1.2 :002 > BigDecimal.new(0.2342334)
ArgumentError: can't omit precision for a Float.
...

Some might be inclined to specify the number of significant digits as nil/0, such that the number of significant digits is determined from the initial value. But that leads to the following in Rails Console:

2.1.1 :006 > BigDecimal.new(0.2342334, 0)
 => #<BigDecimal:10bad84f8,'0.2342334000 0000000826 7520001936 645713E0',36(54)>
2.1.1 :008 > BigDecimal.new(0.2342334, 0).to_s
 => "0.234233400000000008267520001936645713"

Note: in irb/vanilla Ruby, to_s includes "E0" at the end:

2.1.2 :003 > BigDecimal.new(0.2342334, 0).to_s
 => "0.234233400000000008267520001936645713E0"

A workaround is to:

2.1.1 :007 > (BigDecimal.new(1) * 0.2342334).to_s
 => "0.2342334"

I've not looked into this, but I think what is going on is that to_s on Float in Ruby tosses some of the digits in this case that might be including the floating-point inaccuracy, and that when you multiply BigDecimal it may be using to_s and using that string representation of the Float as the value for the BigDecimal constructor.