First Friday Jams - Pool Lights

Lucas Hogg had a new album come out last month. It's really great, and it has been a staple in my "albums-to-work-to" since. Check it out, and if you like it, buy it.

Uploading Images To A Rails Api

Receiving an uploaded image at an API endpoint is a bit different than just processing form data. With form data, gems like Carrierwave or Paperclip abstract away the complexity of handling uploaded files. With an API, the client needs to be converting the image to Base64 data, and then uploading the data for the API to decode.

First, if you aren't already, you need to process your JSON so that it plays nicely with strong parameters. In this example I will assume you have a User model with a picture attribute.

def user_params
    # get raw json
    json = JSON.parse(request.raw_post)
    params = ActionController::Parameters.new(json)

    # process through strong params
    params = params.require(:user).permit(:picture_data)

    # call method to decode picture data
    params[:picture] = decode_picture_data(params[:picture_data])
end

Next, we need to decode the picture data. I use Carrierwave, and this is what I needed to do to make it happy. However, if you use something else it shouldn't be that different.

def decode_picture_data picture_data
    # decode the base64
    data = StringIO.new(Base64.decode64(picture_data))

    # assign some attributes for carrierwave processing
    data.class.class_eval { attr_accessor :original_filename, :content_type }
    data.original_filename = "upload.png"
    data.content_type = "image/png"

    # return decoded data
    data
end

The important step there was converting decoding the Base64 data. The other steps were useful in talking to Carrierwave. Now you should be able to save your User record without any issue.

@user.update!(user_params)

Alfred 2 Base CRM Workflow

Alfred 2 Base CRM Workflow

After posting my Basecamp Alfred workflow a couple weeks ago, someone contacted me about making one for Base CRM. I was not familiar with Base, but I was provided a trial account and did some research.

Today, I am open-sourcing version 1.0.0 of the workflow. It will pull in your leads, contacts, and deals from Base. All you need is an API key. I hope it helps those of you that use it. Let me know if you have any comments, and pull requests are always welcome on Github.

Alfred 2 Screenshot

After downloading, open the file to install, then:

  1. Right click on the “ba” Script Filter and click “Configure”.
  2. Fill in your Base CRM api key.
  3. Start being productive.

Validating Credit Card Numbers

Ever wonder how credit card numbers are generated? No? Me either, but then I had to figure it out this week. The process for generating and validating the numbers is known as the Luhn algorithm.

There are a couple different variations to the Luhn algorithm that ultimately end up with the same result. Here are the steps I took to validate an existing card number, using the fake card 4716961168571677:

  1. Remove the last digit: [4, 7, 1, 6, 9, 6, 1, 1, 6, 8, 5, 7, 1, 6, 7]
  2. Reverse the digits: [7, 6, 1, 7, 5, 8, 6, 1, 1, 6, 9, 6, 1, 7, 4]
  3. Multiply the odd digits by 2: [14, 6, 2, 7, 10, 8, 12, 1, 2, 6, 18, 6, 2, 7, 8]
  4. Subtract 9 if greater than 9: [5, 6, 2, 7, 1, 8, 3, 1, 2, 6, 9, 6, 2, 7, 8]
  5. Add digits together: 73
  6. Multiply by 9: 657
  7. Mod 10 (remainder of division by 10): 7

Step 7 should be the last digit of the card number that you originally removed in step 1. You could just as easily generate a card number by taking a 15 digit number and using these same steps to find the 16th digit.

I, of course, did not calculate these by hand. I wrote a ruby script:

def validate_card_number(num)
  # convert int to array of ints
  digits = num.to_s.chars.map(&:to_i)

  # remove last digit
  last_digit = digits.pop

  # reverse the digits
  digits.reverse!

  # multiply odd digits by 2
  # subtract 9 if greater than 9
  digits.collect!.with_index do |digit, i|
    digit *= 2 if i % 2 == 0
    digit -= 9 if digit > 9
    digit
  end

  # add digits together
  sum = digits.inject(:+)
  # multiply by 9
  sum *= 9

  # mod should equal last digit
  return sum % 10 == last_digit

end

Automated iMessages (or, How To Make Your Friends Really Mad)

A while back, some of my friends and I decided it would be hilarious if we could repeatedly send iMessages to someone as a prank. So, I wrote an Applescript. This little guy is dangerous. Please do not do anything malicious with it. I accept no responsiblity.

set VICTIM to "999-999-9999"
set MSG to "something"
set APPLE_ID to "E:your@email.com"

repeat while true
    tell application "Messages"
        send MSG to buddy VICTIM of service APPLE_ID
        delay 1
    end tell
end repeat

I put the delay 1 in there to prevent the iMessages from getting throttled and erroring out. The iMessage server will start rejecting them if they come too fast.

Usage

  1. Clone the repo and open iMessage.scpt in Script Editor.
  2. Change VICTIM to the phone number of the person who is about to be mad.
  3. Change MSG to the message you want to send that person.
  4. Change APPLE_ID to the email (including the 'E:') of the Apple ID you want to send from.
  5. Press the play button and then hide.

With great power comes great responsiblity. Now that you hold the key, don't make anyone mad.

With that said, have fun.