Reccenter.com LLC

How to Fix IE Issues With Flash Popover Using Jquery

Problem: Flash or embeds are “popping through” your carefully designed transparent stuff.

You have lots of posts loading in through the tumblr api, some of which have random embeds from soundcloud, youtube, vimeo, etc. none of these have their wmode set. You say to yourself “no problem, i’ll add it with jquery”. And you do. And it works. Except in IE6/7/8/9.

Doh. Or – “How do i fix this madness?”

The issue here is that IE doesnt care if you change “object” tags. after they have been rendered by the browser. jQuery be damned!

My (hard-won) solution is to remove the original object tag and replace it with a clone. I hide the container div prior to loading in the JSON and changing the wmode on all embeds, then display everything at once.

$("#the-posts").hide();

// grab ALL object tags, clone them, then remove the original and add the cloned element.

$("#the-posts object").each(function(idx,item){
  if($(item).attr('id') == 'html5'){
    // nope
  } else {
    var the_parent = $(item).parent();
    var the_new_object = $($(item).clone()).remove().html();
    the_parent.remove($(item));
    $(item).remove();
    the_parent.append(the_new_object);
  }
});

// set the wmode on the container objects and embed tags for Safari/Firefox/Chrome.

$("#the-posts embed").attr("wmode",'opaque');
$("#the-posts object").attr("wmode",'opaque'); 

// set the wmode on the params tags.

$("#the-posts param[name=wmode]").attr('value', 'opaque');

// append wmode for youtube/vimeo iframe embeds, making sure to either use an ? or & depending on existing query string.  And leave the facebook connect frame alone.

$("#the-posts iframe").each(function(idx,item){ 
  if($(item).attr('id') == 'fdbk_iframe'){
    // leave it alone
  } else {
    if($(item).attr('src') && $(item).attr('src').match(/\?/i)){
      $(item).attr('src', $(item).attr('src')+"&wmode=opaque");
    } else {
      $(item).attr('src', $(item).attr('src')+"?wmode=opaque");
    }
  }
});
$("#the-posts").show();

Automated Asset Sync to Amazon S3 With Engineyard Deploy

I recently moved all static assets for a client project off the main application server and onto Amazon S3. I needed an easy way for these assets to be synced to S3 on every deploy so that all of my team members could continue to work and deploy as the normally do, and that required hooking into the Engineyard CLI deploy process using deploy hooks. Additionally i wanted the sync to happen on the server since moving files to S3 from an EC2 instance is much faster than syncing from local machines. This required a custom chef recipe to install my S3 syncing library of choice, s3cmd *note that there are several tools with the same name - we only want the python one from http://s3tools.org/s3cmd.

I keep all required cookbooks with the application in the /cookbooks directory similar to my setup for the seamless_database_pool plugin on engineyard with n-slaves, so i created the appropriate directories and files:

/cookbooks
  /main
    /recipes
      default.rb # enable the cookbook here by including "require 's3cmd'"
  /s3cmd
    /recipes
      default.rb # utilize the following code

And added the chef code to install and link the s3cmd binary:

# /cookbooks/s3cmd/recipes/default.rb
# Cookbook Name:: s3cmd
# Recipe:: default

s3cmd_tar_gz = "/engineyard/portage/distfiles/s3cmd-1.0.0.tar.gz"

remote_file s3cmd_tar_gz do
  checksum "e82f0246479015ce50a09d8d4ada8429"
  source "http://downloads.sourceforge.net/project/s3tools/s3cmd/1.0.0/s3cmd-1.0.0.tar.gz"
end

bash "install s3cmd 1.0.0" do
  cwd "/engineyard/portage/distfiles/"
  code <<-EOH
    tar -zxf #{s3cmd_tar_gz}
    cd /engineyard/portage/distfiles/s3cmd-1.0.0 && sudo ln -nfs $PWD/s3cmd /usr/local/bin/s3cmd
  EOH
  not_if { ::FileTest.exists?("/usr/local/bin/s3cmd") }
end

Once this was setup, I applied the recipe to my server using the engineyard cli:

ey recipes upload
ey recipes apply
# if you have issues check your custom log on the ey cloud panel

I then set about creating a rake task that could be run on every deploy that would be FAST and not duplicate efforts using s3cmd. I created the config using s3cmd --configure to reference in the rake task. This file must also exist on the server so make sure your rake task can find it both places.

# /lib/tasks/asset_deploy.rake
require 'rubygems'
require 'aws/s3'

## You should probably pull these from elsewhere with YAML or ENV['CONSTANT]. I am not here to judge you.
AWS_BUCKET = "YOUR_S3_BUCKET_"

## I like to namespeace my rake tasks. 
namespace :assets do 
  desc "Deploy all assets in public/**/* to S3/Cloudfront"
  task :deploy do
    STDOUT.sync = true
    installed = system("which s3cmd > /dev/null 2>&1")
    unless installed
      print "run `brew install s3cmd` and try again - you do not have the s3cmd binary installed."
    else
      print "== Uploading assets to S3"
      # you can specify as many directories as you like - make sure your local and remote match up properly. i use gsub because i am lazy
      ["public/images/*","public/stylesheets/*", "public/assets/*", "themes/*"].each do |local_path|
        remote_path = local_path.gsub("*", "").gsub("public/", "")
        print "Uploading #{local_path} to #{remote_path} \n"
        # my theme directory also has templates, but i dont want them on S3. read the docs for the other options explanations
        print `s3cmd -c .s3cfg --skip-existing  --rexclude=".*\.erb|.*\.haml" --acl-public -rvMH sync #{local_path} s3://#{AWS_BUCKET}/#{remote_path}`
      end
      
      print "== Done uploading assets to S3"
    end
    STDOUT.sync = false
  end

end

And the final piece of the puzzle that makes this all work like magic - the deploy hook. I chose “/deploy/before_migrate.rb” and included the following:

# i only want this to run once, and from the master is fine. easier to target than some random non-master.
if ['app_master'].include?(node[:instance_role])
  run "cd #{release_path} && bundle exec rake assets:deploy"
end

Fin. Any Questions? How do you keep your assets in order?

Utilizing Jekyll With Sinatra on Heroku for a Facebook App

Guest post from Chris Sloan

I love working with Jekyll. It’s very nerdy for what it does since the final output is a static HTML server which is awesome for smallish projects not utilizing a database. Low and behold, most Facebook apps are just that — a show case of some special feature that only fans of the page can access. Forget using Flash anymore, this is quicker and simpler and of course you can mixing some HTML5.

Using Jekyll, Sinatra (for the Rack aspect) and hosting it on the awesome Heroku stack makes creating Facebook apps a breeze — if you know the steps to begin with.

Things you will need and know

  1. A Heroku account - free to signup and also provides a free development account
  2. Jekyll installed - Check out the docs for setup and installation
  3. Basic knowledge on how to create a Jekyll project
  4. A Facebook developer account to create the app - this post is not about creating one or setting up the app on Facebook. You should have a working knowledge of creating the app through their tools.

Before I get started with the basic code, I want to extend thanks to Jesse Storimer on his post to get me started with how to run Jekyll output on Heroku and also this Stack Overflow response for the JavaScript “Like” gate solution.

The setup

In order to run a Jekyll project on Heroku, you need to fake out Heroku into thinking it’s a Rack app. This is done by making the project run through Sinatra. Using Jesse’s masquerade code with some minor modifications for ability to run on Facebook you can create these files in your base Jekyll project folder.

Gemfile (always good to utilize this)

source ‘http://rubygems.org'
gem ‘sinatra’

configu.ru

require './masquerade'
run Sinatra::Application

masquerade.rb

require 'rubygems'
require 'sinatra'

set :public, Proc.new { File.join(root, "_site") }

# This before filter ensures that your pages are only ever served 
# once (per deploy) by Sinatra, and then by Varnish after that
before do
    response.headers['Cache-Control'] = 'public, max-age=31557600' # 1 year
end

get '/' do
    File.read('_site/index.html')
end

post '/' do
    File.read('_site/index.html')
end

Things of note

The masquerade.rb file sets up Sinatra to default to the site/index.html structure from which the app runs.

In the config.ru file I changed the path to the required masquerade file. Heroku would throw an error and crash because it could not find the required rb file when launched. Better to explicitly tell it were to find the file than not.

For Facebook iFrame tabs, Facebook sends a POST request to your app for it to return the actual page data. I added to the masquerade.rb file the route for the POST request. Initially, I only had the GET request so the app would return Facebook a 404 error thus resulting in an ugly h1 tag wrapping “Not Found”. Good luck finding a solution that until you check your heroku logs.

Extra credit - make visitors like your page

Since this post is about a static HTML application, there was no need for a dynamic language such as Ruby on Rails using Ruby or even PHP to utilize the Facebook SDK. If you want to setup what is known as a Like Gate you would need to add the ability to check the current user session information. Unfortunately, you can’t do that very easy with JavaScript, but you can utilize the JavaScript SDK and a simple query of current user ID and page ID. Easiest way is to wrap all of below in the asynchronous solution Facebook provides

FB.init({
appId: ‘YOUR APP ID’, 
status: true, 
cookie: true,
xfbml: true
        });
FB.login(function(response) {
    if (response.session) {
    var user_id = response.session.uid;
    var page_id = “YOUR PAGE ID”; 
    var fql_query = "SELECT uid FROM page_fan WHERE page_id = "+page_id+"and uid="+user_id;
    var the_query = FB.Data.query(fql_query);
    the_query.wait(function(rows) {
    if (rows.length == 1 && rows[0].uid == user_id) {
    // The user has liked your page
    } else {
    // The user has NOT liked your page
    }
    });
    } else {
    // user is not logged in
    }
});

Hope this helps whomever has stumbled upon this post. I know I will utilize it to remember the hoops I had to jump through to get this to work.

RVM –default Broken With ZSH?

RVM have amnesia when using ZSH and oh-my-zsh? Check the $PATH in your .zshrc

I needed to remove an entry for the rvm bin directory that showed up at some point.

$HOME/.rvm/bin

Master/Multiple Slave Engineyard Database Cluster Setup

So you have multiple database instances on Engineyard and you want to use the additional instances for reads, but you dont know where to start? Google “master slave engineyard” sometime. Report back if you ever find anything useful beyond this post about Using Masochism which is very helpful if you never plan to expand beyond a single slave.

  1. Install the seamless database pool plugin and follow the setup instructions, making sure to include the appropriate code in your ApplicationController.
    class ApplicationController < ActionController::Base
       include SeamlessDatabasePool::ControllerFilter
       use_database_pool :all => :persistent, [:create, :update, :destroy] => :master
     end
  2. Add the extra N instances of database slaves to your EngineYard environment.
  3. Grab my seamless_database_pool cookbook from github and add to your cookbooks directory. I am not 100% sure this is correct or accepted, but i like to keep my cookbooks with the app they are associated with, so i have a /cookbooks directory at the root of my applicaton. you will want to rename it “seamless_database_pool”. i added ey-chef- to make it easier to find.
  4. Add the seamless_database_pool recipe to your main cookbook at /cookbooks/main/recipes/default.rb
    require_recipe "seamless_database_pool"
  5. Add the following to your /deploy/before_migration.rb
    run "ln -nfs #{release_path}/config/database_cluster.yml  #{release_path}/config/database.yml"
  6. Commit and push everything
  7. Load the recipe onto your environment via the engineyard cli, waiting
    $ ey recipes upload
    $ ey recipes apply
    $ ey deploy
  8. Hammer your server with your performance testing tool (I recommend Siege) and verify that the slaves are getting read requests. The “Graphs” for the instances is a great place to verify without SSH Spelunking.

Got a better way? See something wrong? Let me know below.

Installing and Using Ruby-filemagic and Libmagic on OS X Lion With Homebrew & Paperclip

Much of my work has to do with uploaded audio and video, and checking mime-types from uploaded audio and video not fun. The only reliable way i have found to check files is with the libmagic library, using the ruby-filemagic gem to cross the bridge from ruby to that library.

Whenever possible i install all libraries and software with Homebrew for OS X.

Installing libmagic used to be a multistep error-prone process. Fortunately it has gotten easier, but still causes trip-ups due to the need to “link” the libmagic libraries.

$ brew install libmagic
$ brew link libmagic

Now you can install ruby-filemagic gem

$ [sudo] gem install ruby-filemagic

EDIT - I will be releasing code to reuse this as a paperclip preprocessor. The more I look at this the messier i think it is.

I use a before_filter to check mime-types because the Paperclip mime-type checker coupled with Firefox is notoriously terrible, especially when dealing with mp3 audio. Note that this should likely be a Paperclip Preprocessor.

Add the ruby-filemagic gem to your Gemfile.

gem "ruby-filemagic"

And setup your model’s before_validation .

has_attached_file :attachment

def before_validation
  self.audio_content_type = FileMagic.new(FileMagic::MAGIC_MIME).file(self.audio.to_file.path).gsub(/\n/,"").split(";").first

  if @song.audio_content_type != 'audio/mpeg' && @song.audio_content_type != 'audio/mp3'
    @song.errors.add_to_base("This file is not an MP3 - it's mimetype is #{@song.audio_content_type}.")
  else
    begin
      mp3_info = Mp3Info.open(audio_data.path)
      if mp3_info.vbr
        @song.errors.add_to_base("This MP3 is VBR (variable bit rate) — we only support CBR (constant bit rate).")
        # VBR mp3s do odd things when streaming.
      end

      if mp3_info.samplerate != 44100 
        @song.errors.add_to_base("This MP3 has an unsupported sample rate - it is #{ "%.3f" % (mp3_info.samplerate.to_f / 1000.0)}khz — we only support 44.100khz.")
        # MP3s with odd sample rates are buggy when streaming via flash
      end

      if mp3_info.bitrate > 320
        @song.errors.add_to_base("This MP3 has an unsupported bitrate - it is #{mp3_info.bitrate}kbps — we only support up to 320kbps.")
        # A bit rate higher than 320 is ridiculous
      end
    rescue
      @song.errors.add_to_base("This file does not appear to be an MP3.")
    end
  end
end

Any questions? Have a better way?

RecCenter Blog First Post [My Favorite Rubygems and Brew Packages]

Statistics show that every blog can only have one first post, so why waste it writing about what your blog is about or what purpose it will or will not serve.

Instead, here is a list of my most utilized rubygems and homebrew installed software.

my core rubygems

  • blavosync A Rubygem i wrote to help my less techincally inclined team members get the latest database and uploaded assets for local development. Previously the generally accepted way of developing was by deploying every commit to the production server for testing. Seriously.
  • bundler If you are doing Rails/Sinatra/Ruby (or even PHP with rack-legacy) you cannot live without bundler!
  • capistrano I use capistrano for all deploy management (unless we’re going deploy to Heroku or Engine Yard – they have their own gems). There are other ways including chef and puppet, but capistrano makes sense for my mental model.
  • capistrano-ext An extension to capistrano that allows me to easily set up multistage deploys for having a “staging” or “sandbox” application.
  • engineyard I dont always deploy to engine yard, but when i do, i use their Command Line Interface (CLI).
  • heroku Heroku is my new favorite deployment platform. We can deploy rapid prototypes with non-IP address domain names in under a minute. And did i mention it’s FREE!?
  • mysql2 Mysql has been my database of choice since i started developing for the web in 2001. The mysql gem no longer works properly for various versions of rails, and i got tired of trying to debug the issues, which inevitable led me to downgrading to the 2.7 version of mysql. That is until i read about mysql2. All problems have been solved until recently – the 0.3.x versions of the mysql2 gem only work with Rails 3.1, which is still in release candidate status.
  • powder I have switched to using Pow as my local development server. This has been largely positive positive, and less resource intensive than passenger. The Powder gem makes using Pow so simple that i have forgotten the manual way of adding Pow hosts.
  • ssh-forever I can’t remember passwords, and when i can i have a hard time typing them. Luckily the process of putting my public key on a server for passwordless ssh is as simple as adding (-forever) the first time i have to SSH into a new server.
  • ruby-filemagic Much of my work has to do with uploaded audio and video, and checking mime-types from uploaded audio and video not fun. The only reliable way i have found to check files is with the libmagic library, using the ruby-filemagic gem to cross the bridge from ruby to that library. Installation can be tricky. Expect post #2 on this subject.

my homebrew packages

  • git We use Version Control on every project, from landing pages and banner ads, to mobile applications and web applications.
  • imagemagick Every web application we build does some form of image resizing and cropping. Imagemagick is the best way we have found to do that, coupled with the paperclip rubygem.
  • libmagic This is needed to use ruby-filemagick. Installation can be tricky. Expect post #2 on this subject.
  • memcached All of our web apps that need caching use memcached. My favorite rubygems for this connection is Dalli.
  • mysql The database. Facebook and Flickr use it.
  • node Node.js is a great server-side javascript framework for building stupid fast applications.
  • php I don’t use php often, but when i do, i use the php-cgi variety so that i can keep running POW via rack-legacy.
  • wget I have always hated curl, so one of the first applications i install on any server is wget.

manually installed (yuck)

  • rvm We develop all new ruby and rails applications in 1.9.2. Rvm allows us to still patch bugs and add features to ruby 1.8.7 applications.
  • pow Pow is a minimalist development server that mostly stays out of the way.

What do you use? Why? Sound off below.