Iacutone.rb

coding and things

Amazon S3, Part 2

| Comments

So we have Carrierwave uploading pictures to our local server. Perhaps we want the pictures stored on a third party cloud provider. Amazon S3 and Carrierwave work very well together. This blog post describes how to upload your pictures to the Amazon S3 cloud. Again, thanks to Ryan Bates and Railscasts for the great information.

In order to upload files to Amazon S3, we will be using the Fog Gem. The Carrierwave gem handles the Fog interaction with Amazon S3 behind the scenes.

  • Sign up for an Amazon AWS account.
  • Create a S3 bucket to store your files (photos)
  • Input your credentials in:
initializers/carrierwave.rb
1
2
3
4
5
6
7
8
CarrierWave.configure do |config|
  config.fog_credentials = {
    :provider               => 'AWS',
    :aws_access_key_id      => ENV['AWS_ACCESS_KEY_ID'],
    :aws_secret_access_key  => ENV['AWS_SECRET_ACCESS_KEY']
  }
  config.fog_directory  = ENV['AWS_S3_BUCKET']
end

I put my ENV variables in the Figaro Gem.

You also need to modify your code in the avatar_uploader we created in the last blog post to :

avatar_uploader.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# encoding: utf-8

class AvatarUploader < CarrierWave::Uploader::Base
  # include CarrierWaveDirect::Uploader

  # Include RMagick or MiniMagick support:
  include CarrierWave::RMagick
  # include CarrierWave::MiniMagick

  # Include the Sprockets helpers for Rails 3.1+ asset pipeline compatibility:
  include Sprockets::Helpers::RailsHelper
  include Sprockets::Helpers::IsolatedHelper

  # Choose what kind of storage to use for this uploader:
  # storage :file
  storage :fog

  include CarrierWave::MimeTypes
  process :set_content_type

  # Override the directory where uploaded files will be stored.
  # This is a sensible default for uploaders that are meant to be mounted:
  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  # Provide a default URL as a default if there hasn't been a file uploaded:
  # def default_url
  #   # For Rails 3.1+ asset pipeline compatibility:
  #   # asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
  #
  #   "/images/fallback/" + [version_name, "default.png"].compact.join('_')
  # end

  # Process files as they are uploaded:
  # process :scale => [200, 300]
  #
  # def scale(width, height)
  #   # do something
  # end

  # Create different versions of your uploaded files:
  version :thumb do
    process :resize_to_limit => [150, 150]
  end

  version :profile do
    process :resize_to_limit => [350, 350]
  end

  # Add a white list of extensions which are allowed to be uploaded.
  # For images you might use something like this:
  # def extension_white_list
  #   %w(jpg jpeg gif png)
  # end

  # Override the filename of the uploaded files:
  # Avoid using model.id or version_name here, see uploader/store.rb for details.
  # def filename
  #   "something.jpg" if original_filename
  # end

end

That is it. Your photos are now added to your Amazon S3 bucket! Just be careful, you only get so much space on the cloud for free. In the next blog post, I will explain how to increase efficiency with a background task via Sidekiq.

Carrierwave Railscast
Uploading to Amazon S3 Railscast
Sidekiq Railscast

Carrierwave Gem, Part 1

| Comments

I have been developing a CMS for students at the Flatiron School. Some gems I used for the first time include Sidekiq, Amazon S3, Carrierwave and Fog. This blog post is a walkthrough of how to implement these gems in your own Rails app. Furthermore, h/t to Ryan Bates of Railscasts for the invaluable information in his videos. This blog post will be broken down into different parts, implementing Carrierwave is the objective of this post.

The first step is to initiate the Carrierwave Gem in order to upload pictures to the app. So, the typical steps:

Add 'carrierwave' to your Gemfile

<div class='bogus-wrapper'><notextile><figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>

$ rails g uploader avatar

1
$ rails g migration add_avatar_to_profiles avatar:string

1
$ rake db:migrate

Now, our Profile table has an avatar attribute. An uploader folder was also added to your app route directory named after your attribute name, in this case avatar_uploader.rb. Here is the code in the file.

avatar_uploader.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# encoding: utf-8

class AvatarUploader < CarrierWave::Uploader::Base
  # include CarrierWaveDirect::Uploader

  # Include RMagick or MiniMagick support:
  include CarrierWave::RMagick
  # include CarrierWave::MiniMagick

  # Include the Sprockets helpers for Rails 3.1+ asset pipeline compatibility:
  # include Sprockets::Helpers::RailsHelper
  # include Sprockets::Helpers::IsolatedHelper

  # Choose what kind of storage to use for this uploader:
  storage :file
  # storage :fog

  # include CarrierWave::MimeTypes
  # process :set_content_type

  # Override the directory where uploaded files will be stored.
  # This is a sensible default for uploaders that are meant to be mounted:
  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  # Provide a default URL as a default if there hasn't been a file uploaded:
  # def default_url
  #   # For Rails 3.1+ asset pipeline compatibility:
  #   # asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
  #
  #   "/images/fallback/" + [version_name, "default.png"].compact.join('_')
  # end

  # Process files as they are uploaded:
  # process :scale => [200, 300]
  #
  # def scale(width, height)
  #   # do something
  # end

  # Create different versions of your uploaded files:
  version :thumb do
    process :resize_to_limit => [150, 150]
  end

  version :profile do
    process :resize_to_limit => [350, 350]
  end

  # Add a white list of extensions which are allowed to be uploaded.
  # For images you might use something like this:
  # def extension_white_list
  #   %w(jpg jpeg gif png)
  # end

  # Override the filename of the uploaded files:
  # Avoid using model.id or version_name here, see uploader/store.rb for details.
  # def filename
  #   "something.jpg" if original_filename
  # end

end

There is a lot of code in here commented out which will be used in later posts for using both Fog and Amazon S3. I like being able to create different sizes under the version sections, for example

<div class='bogus-wrapper'><notextile><figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>

2 3 4

 version :thumb do
    process :resize_to_limit => [150, 150]
  end


to add elegant versatility to the sizes of your images.

In your Profile model add:

    <div class='bogus-wrapper'><notextile><figure class='code'><figcaption><span>profile.rb </span></figcaption>
1
2
     mount_uploader :avatar, AvatarUploader
      

To display the avatar in your View:

    <div class='bogus-wrapper'><notextile><figure class='code'><figcaption><span>show.html.erb </span></figcaption>
1
2
     <%= image_tag image_url(:thumb) %>
      

In your form:

    <div class='bogus-wrapper'><notextile><figure class='code'><figcaption><span>new.html.erb </span></figcaption>
1
2
     <%= f.file_field :avatar %>
      

That is all, you can now add images of specific sizes to your Rails app!

Carrierwave Railscast
Uploading to Amazon S3 Railscast
Sidekiq Railscast

Binary Search Trees

| Comments

Properties

  1. The left subtree of a node contains only nodes with keys less than the node's key.
  2. The right subtree of a node contains only nodes with keys greater than the node's key.
  3. The left and right subtree must each also be a binary search tree.
  4. There must be no duplicate nodes.

Benefits

BST Invariant

For any node x, every key in the left subtree of x is <= x’s key

For any node x, every key in the right subtree of x is >= x’s key


Inorder traversal of a binary search tree visits nodes in sorted order, the left of root (18) are displayed before the right.

Operations

Entry Find (Object k)


How to find smallest key >= k or largest key <= k?

When searching down the tree for a key k that is not in the tree, we encounter both.


<p>Ex. search for 27 as k (from above pic)</p>
<ul>
    <li>Keeps searching nodes to the right, gets to 28 and returns nil</li>
    <li>encounters 25 < k and 28 > k</li>
</ul>

Entry first();
-If empty return null, otherwise start at root and walk down left repeatedly until you reach node with no left child, that node has minimum key.

Entry last();
-Mirror of left, but walks down right tree

Entry insert(Object k, Object v);

The delete operations (where shit gets complex)

Entry remove(Object k);


h/t Jonathan Shewchuk at UC Berkeley

His lecture via Youtube

The Yipit API and Whenever Gem

| Comments

Last week Alex and I presented Platt101 at our NYC on Rails Meetup, at the Flatiron School. Platt101 let's a user write reviews about restaurants they have been to and renders those restaurants on a Google Map. The restaurants are based on the 101 best according to New York Magazine. The restaurants a user has been to render in a different color than restaurants a user hasn't had the pleasure of dining. A fellow student (h/t Anthony) suggested we impliment a GroupOn link in our restaurant list in order for a user to provide the user incentive to go dine at given restaurants.

We decided to use the Yipit API in order to aggregate all discount incentives from numerous discount sites such as GroupOn. We accessed the Yipit API via the Yipit gem for Ruby on Rails, created by Gangster. Aside from our client session running a few times, the gem provided for all of our data parsing needs. The Yelp API we used to seed our database with relevant restaurant information included phone numbers. We searched the phone numbers in our database against phone numbers on Yipit in order to find deals for the given restaurants on our list. This functionality is provided with a rake task. Here is the code:


The rake task provides us the ability to use the Whenever gem in order to run the rake task everyday. This way our database in reseeded with new data about restaurant deals on a daily basis. The Whenever gem was easy to impliment.


This code is automatically added to your config > schedule.rb when you run whenever . in terminal. You can customize Whenever to run whenever you want.

Now, this all works well in development, but Platt101 is deployed on Heroku. In production, we needed to reset up the Whenever gem. This is also easy to accomplish on Heroku. Use Heroku Scheduler in order to run a chron job in production. They do make you use input your credit card info, which is whack, but it says free... we shall see.

Platt101 can be found here.

Jambox

| Comments

AirPlay

Learning how Airplay works: it allows wireless streaming of audio, video and photos.

My original idea was to rip the music information going onto the Flatiron AirPlay, then automatically tweet this information via Twitter. I liked this idea because we play so much cool and unfamiliar music. It would be great to keep track of what is playing. Over time, I opened a myriad of tabs and discovered many interesting API's. These include a few API's which mirror AirPlay on a laptop (AirParrot. and AirServer.). Also, many music API's were discovered. These include Echonest, Soundcloud and many others.

The original idea went down in flames when I learned how difficult it is to hack the AirPlay. This blog post illustrated how this hacker tried to gain access to the AirPlay from WiFi packets via KisMAC, a derivative of WireShark. Also, there are problems jailbreaking the DRM encryption. The idea is possible, but a crazy task. Idea aborted...

GitHub Play deserves some special recognition. It allows the GitHub offices to wirelessly create playlists synchronously in all of their offices around the globe. The next iteration of our goal was to get the GitHub Play to work locally. You can clone it at the link above. However, GitHub Play relies on an old version of iTunes which includes iTunes DJ. Also, Play ran on Ruby 1.8.7, and the dependencies were a mess. So, our group threw this idea of out the window.

GitHub Play

Our groups next iteration is to simplify the GitHub Play. Currently we are setting up a server where people can upload their mp3's. Directions to create your own streaming music player in Ruby can be found here. The goal of this project is to eventually create a service where a group of people can all upload their songs onto a server and they will be played in sequence on a playlist. For example, if you are at a party, everyone can put songs on a playlist, so that no one person will have complete control of the music. We also want to implement a Reddit-esque leaderboard so people on the server can upvote/downvote songs. If a song gets too many downvotes, it will be erased from the playlist.

Adventures in Code

| Comments

One can run into some cataclysmic errors trying to setup and deploy an Octopress account. Personally, I kept raking new themes from Github to my Octopress account and finally, my blog broke. In order to keep the same url, I deleted my Github repository and recreated an Octopress account.

Things I learned

Knowing:

$ subl .

This saves so much time. The code snipped will open the entire current directory in your terminal.

Now, things are going well and I begin to play with some HTML, CSS and JS code. I stumbled upon this gold nugget. Sweet animated clouds here.

...and a tutorial to recreate animated clouds by the author here.

It was loads of fun messing with the CSS and JS source code and I manipulated the code into this:

Awesome! I created this a massive randomly generated semi-transparent smiley face. Now, how do I implement this information to Octopress? The CSS ans JS code is hard core and I do not understand how works very well. What do I do now?

Bonsai JS is a Javascript graphics library with step-by-step tutorials on how to implement all sorts of useful code such as rendering shapes, gradients and animation. It also has a built in editor to play with said code. With the editor and tutorials I can quickly learned how to do code graphics with JS. An example of what can be created with Bonsai is below.

Sweet. Thanks to my fellow Flatiron students who helped me along the way!

Git Commandments

| Comments

Don’t change master.

$ git pull ––rebase

-to pull from the master and then create new branch

-now you have an up to date branch to code your magic

$ git status

-run after you change things in your branch

-shows you what changed

$ git add .

$ git commit -m “Your message”

$ git co master

-checkout master before your merge

$ git pull ––rebase

-ensure that there haven’t been any changes before you merge to master branch

$ git merge -m “Your message”

$ git push

-data now updated on git!