<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0"><id>tag:blogger.com,1999:blog-7975027231082637331</id><updated>2013-06-14T08:07:41.369-07:00</updated><category term="Heroku ruby sinatra PATSY" /><category term="solr" /><category term="viruses" /><category term="ruby mongo mongoid mongomapper mysql" /><category term="canvas2image" /><category term="metasearch" /><category term="AWS S3" /><category term="path" /><category term="html5" /><category term="web speech" /><category term="snow leopard" /><category term="html5 textarea spellcheck" /><category term="Apache SSL Certificates" /><category term="ruby  bundler" /><category term="malware" /><category term="lab automation" /><category term="Mac laptop disk error repair" /><category term="web audio" /><category term="api" /><category term="ruby rvm gem rails" /><category term="'mac os x'" /><category term="ghostscript" /><category term="jetpack" /><category term="soda" /><category term="firefox" /><category term="Flash" /><category term="'Mac OS X' PDF Preview &quot;Snow Leopard&quot;" /><category term="git github lightouse" /><category term="popup" /><category term="passenger" /><category term="css" /><category term="has_many" /><category term="render" /><category term="git" /><category term="gem" /><category term="window" /><category term="latitude" /><category term="nginx" /><category term="bookmarklet" /><category term="migrations" /><category term="rails" /><category term="autoupdate" /><category term="environment variables" /><category term="date ruby rails" /><category term="Mac" /><category term="biotechnology" /><category term="ruby mongo mongoid mongomapper" /><category term="ruby utf-8 character encodings" /><category term="ruby regex" /><category term="Mongo ruby mongoid authentication" /><category term="mcafee" /><category term="Rails3" /><category term="simple-tooltip" /><category term="comm" /><category term="javascript date browsers Mac" /><category term="jQuery image rollover" /><category term="open-uri" /><category term="bing maps" /><category term="unix shell" /><category term="safari" /><category term="Adobe" /><category term="mod_fastcgi" /><category term="searchlogic" /><category term="opencv" /><category term="MySQL import export" /><category term="java" /><category term="google maps" /><category term="mysql" /><category term="authentication" /><category term="text to speech" /><category term="httpd" /><category term="sequence" /><category term="AIR" /><category term="rails routes" /><category term="utf-8" /><category term="chef aws ec2 ubuntu ruby" /><category term="browser hijack" /><category term="bash" /><category term="biotech" /><category term="iterm2" /><category term="oracle" /><category term="yaml" /><category term="timezone" /><category term="patent" /><category term="numpy" /><category term="JSONP" /><category term="PostgreSQL" /><category term="trackball" /><category term="homebrew" /><category term="habtm" /><category term="html5 chrome forms" /><category term="nokogiri" /><category term="sinatra" /><category term="plugins" /><category term="longitude" /><category term="rails devise authentication" /><category term="ActionMailer" /><category term="ruby" /><category term="craic" /><category term="Intel Core 2 Duo" /><category term="meta_search" /><category term="Win XP" /><category term="sqipdb.com" /><category term="javascript" /><category term="AppleScript" /><category term="seqid" /><category term="ipad" /><category term="Ruby terminal ANSI escape codes" /><category term="rails testing machinist factory_girl" /><category term="AWS ec2 ubuntu" /><category term="paperclip" /><category term="CORS" /><category term="github" /><category term="rails has_many through testing simple_form" /><category term="tomcat" /><category term="fedora" /><category term="logit" /><category term="antibody" /><category term="rail update gem" /><category term="string" /><category term="console" /><category term="street intersection" /><category term="listing" /><category term="excel" /><category term="raphael" /><category term="ruby-oci8" /><category term="rails heroku homebrew gem taps sqlite3" /><category term="sqip" /><category term="open" /><category term="imagemagick" /><category term="getJSON" /><category term="x86_64" /><category term="canvas" /><category term="ruby rvm shell script" /><category term="csv" /><category term="JSON" /><category term="html form" /><category term="rake" /><category term="database" /><category term="ActiveRecords" /><category term="linux" /><category term="apache" /><category term="Heroku" /><category term="asus P5B" /><category term="MacPymol" /><category term="socrata" /><category term="chrome rails login" /><category term="bing translate" /><category term="sass" /><category term="internet explorer" /><category term="ajax" /><category term="osascript" /><category term="ubuntu rvm ruby" /><category term="sorting" /><category term="mac os x" /><category term="amazon s3" /><category term="migration" /><category term="&quot;Mac OS X&quot;" /><category term="Ruby Jruby 1.5.3" /><category term="ruby logical operators" /><category term="redcloth" /><category term="google chrome" /><category term="time" /><category term="regex" /><category term="jquery" /><category term="select menu" /><category term="antivirus" /><category term="ruby erb rails" /><category term="tika" /><category term="unix" /><category term="Ruby 1.9 Sinatra Heroku" /><category term="captain beefheart" /><category term="codemirror" /><category term="history" /><category term="Rails 3" /><category term="microsoft" /><category term="devise" /><category term="microtiter plate map" /><category term="html5 firefox security" /><category term="model" /><category term="less" /><category term="unzip" /><title type="text">Craic Computing Tech Tips</title><subtitle type="html">A collection of computer systems and programming tips that you may find useful.
&lt;br&gt; &lt;br&gt;
Brought to you by &lt;a href="http://www.craic.com"&gt;Craic Computing LLC&lt;/a&gt;, a bioinformatics consulting company.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://craiccomputing.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://craiccomputing.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default?start-index=26&amp;max-results=25" /><author><name>Robert Jones</name><uri>http://www.blogger.com/profile/13582954721486542844</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_f8EIq63pOsk/SdzN4VmaUoI/AAAAAAAAAAM/lS_mySaOTlQ/S220/craic_logo.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>223</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/CraicComputingTechTips" /><feedburner:info uri="craiccomputingtechtips" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry><id>tag:blogger.com,1999:blog-7975027231082637331.post-6230578863430000475</id><published>2013-06-13T15:29:00.001-07:00</published><updated>2013-06-13T15:38:19.438-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="habtm" /><category scheme="http://www.blogger.com/atom/ns#" term="has_many" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="migrations" /><category scheme="http://www.blogger.com/atom/ns#" term="rake" /><title type="text">Migrating from Rails HABTM to has_many :through</title><content type="html">I had a &lt;span style="color: red;"&gt;has_and_belongs_to_many&lt;/span&gt; (HABTM) association that I needed to convert to &lt;span style="color: red;"&gt;has_many through&lt;/span&gt; with an explicit model that contains additional columns.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;In my example a &lt;span style="color: red;"&gt;User&lt;/span&gt; knows about many &lt;span style="color: red;"&gt;Words&lt;/span&gt; and each &lt;span style="color: red;"&gt;Word&lt;/span&gt; is known by many &lt;span style="color: red;"&gt;Users&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;You can find many pages on the web about the differences. The consensus is that has_many :through is the way to go from the start - and after this process I agree.&lt;br /&gt;&lt;br /&gt;Making the change in itself is not a big deal - drop the existing joining table 'users_words', create the new one, update the User and Word models and you're good to go.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;Problem is that I already had data in the joining table...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;And because the standard way of setting up a HABTM joining table &lt;span style="color: red;"&gt;does not include an id column&lt;/span&gt;, you can't just use that table or directly copy each record from it. Dang it...&lt;br /&gt;&lt;br /&gt;Here were my steps - hopefully I got them all - don't skip any !&lt;br /&gt;&lt;br /&gt;1: Backup your database and prevent users from accessing it&lt;br /&gt;&lt;br /&gt;2: Do not touch any of the old associations, table, etc&lt;br /&gt;&lt;br /&gt;3: Create the new table and model with a different name from the old joining table.&lt;br /&gt;My HABTM table was users_words and my new table is user_work_links&lt;br /&gt;&lt;br /&gt;4: Update the two models&lt;br /&gt;My original association was this - do not change it yet !&lt;br /&gt;&lt;pre&gt;&lt;span style="color: red;"&gt;  has_and_belongs_to_many :words, :uniq =&amp;gt; true&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;The new association is this - &lt;span style="color: blue;"&gt;NOTE the second line is commented out for now - VERY important !&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="color: red;"&gt;  has_many :user_word_links, :dependent =&amp;gt; :destroy&lt;br /&gt;  # has_many :words, :through =&amp;gt; :user_word_links, :uniq =&amp;gt; true&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;5: Copy over the data from the old joining table with a rake task&lt;br /&gt;You need to go through the existing associations one by one to get the ids for records in the two tables.&lt;br /&gt;Here is my script:&lt;br /&gt;&lt;pre&gt;&lt;span style="color: red;"&gt;namespace :craic do&lt;br /&gt;  desc "move user word data"&lt;br /&gt;  task :move_user_word_data =&amp;gt; :environment  do&lt;br /&gt;    users = User.all&lt;br /&gt;    users.each do |user|&lt;br /&gt;      user.words.each do |word|&lt;br /&gt;        record = UserWordLink.new({ :user_id =&amp;gt; user.id, :word_id =&amp;gt; word.id })&lt;br /&gt;        record.save&lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;6: Update the two models&lt;br /&gt;Now you can comment out the old associations and uncomment the new ones&lt;br /&gt;&lt;pre&gt;&lt;span style="color: red;"&gt;  # has_and_belongs_to_many :words, :uniq =&amp;gt; true&lt;br /&gt;  has_many :user_word_links, :dependent =&amp;gt; :destroy&lt;br /&gt;  has_many :words, :through =&amp;gt; :user_word_links, :uniq =&amp;gt; true&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;In the &lt;span style="color: red;"&gt;attr_accessible&lt;/span&gt; lists in the two models be sure to add &lt;span style="color: red;"&gt;:user_ids&lt;/span&gt; in the Word model and &lt;span style="color: red;"&gt;:word_ids&lt;/span&gt; in the User model. If your forget this it will silently fail to create the records&lt;br /&gt;&lt;br /&gt;7: Test Test Test&lt;br /&gt;You should be back up and running with the new model&lt;br /&gt;&lt;br /&gt;8: Remove the old table&lt;br /&gt;Finally create a migration that drops the old table and run it&lt;br /&gt;&lt;br /&gt;Not too bad as long as you think it through before you start and don't rush the steps&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/CraicComputingTechTips/~4/5uZhzPE62dY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craiccomputing.blogspot.com/feeds/6230578863430000475/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7975027231082637331&amp;postID=6230578863430000475" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/6230578863430000475" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/6230578863430000475" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CraicComputingTechTips/~3/5uZhzPE62dY/migrating-from-rails-habtm-to-hasmany.html" title="Migrating from Rails HABTM to has_many :through" /><author><name>Robert Jones</name><uri>http://www.blogger.com/profile/07503053614730814672</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://craiccomputing.blogspot.com/2013/06/migrating-from-rails-habtm-to-hasmany.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7975027231082637331.post-6561150283475326273</id><published>2013-06-07T14:23:00.001-07:00</published><updated>2013-06-07T14:24:33.631-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="unix" /><category scheme="http://www.blogger.com/atom/ns#" term="comm" /><title type="text">Unix command 'comm' for comparing files</title><content type="html">I needed a simple way to compare two similar files and only output lines that were unique to the second file.  Sounded like a job for '&lt;span style="color: red;"&gt;diff&lt;/span&gt;' but I was not finding the right options to give me what I needed. And then I stumbled across '&lt;span style="color: red;"&gt;comm&lt;/span&gt;' - a standard UNIX command that I don't think I have ever used.  That does exactly what I needed. My two files look like this&lt;br /&gt; File A&lt;pre&gt;A&lt;br /&gt;B&lt;br /&gt;D&lt;br /&gt;E&lt;br /&gt;&lt;/pre&gt;File B&lt;pre&gt;A&lt;br /&gt;B&lt;br /&gt;C&lt;br /&gt;D&lt;br /&gt;&lt;/pre&gt;I want the command to just output 'C'  By default comm compares two files and produces 3 columns of text - lines that are only in file A, lines that are only in file B and lines that are in both. So with these two files I get: &lt;br /&gt;&lt;pre&gt;&lt;span style="color: red;"&gt;$ comm tmp_A tmp_B&lt;/span&gt;&lt;br /&gt;      A&lt;br /&gt;      B&lt;br /&gt;   C&lt;br /&gt;      D&lt;br /&gt;E&lt;/pre&gt;Ugly, and not what I want... But then you can suppress the output of one or more of these columns using -1, -2, -3 options and combinations of those. I want to suppress lines that are only in file A and those in common: &lt;br /&gt;&lt;pre&gt;&lt;span style="color: red;"&gt;$ comm -13 tmp_A tmp_B&lt;/span&gt;&lt;br /&gt;C&lt;/pre&gt;Simple - does exactly what I need - can't believe I didn't know about it... &amp;nbsp; &lt;img src="http://feeds.feedburner.com/~r/CraicComputingTechTips/~4/zjaXYA9LL6o" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craiccomputing.blogspot.com/feeds/6561150283475326273/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7975027231082637331&amp;postID=6561150283475326273" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/6561150283475326273" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/6561150283475326273" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CraicComputingTechTips/~3/zjaXYA9LL6o/unix-command-comm-for-comparing-files.html" title="Unix command 'comm' for comparing files" /><author><name>Robert Jones</name><uri>http://www.blogger.com/profile/07503053614730814672</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://craiccomputing.blogspot.com/2013/06/unix-command-comm-for-comparing-files.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7975027231082637331.post-1988127624263605324</id><published>2013-05-31T09:51:00.000-07:00</published><updated>2013-05-31T10:07:45.077-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ActiveRecords" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="rake" /><title type="text">Listing all the models and numbers of records in a Rails application</title><content type="html">Here is a rake task that will list all the ActiveRecord models in a Rails application along with the number of database records in each  and the last time that database table was updated. Note the call to eager_load which ensure that all models are loaded.&lt;br /&gt;&lt;br /&gt;This is a simple but very useful way to assess the contents of your database.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;  desc "List model in application"&lt;br /&gt;  task :list_models =&gt; :environment  do&lt;br /&gt;    Rails.application.eager_load!&lt;br /&gt;&lt;br /&gt;    ActiveRecord::Base.descendants.each do |model|&lt;br /&gt;      name = model.name&lt;br /&gt;      count = model.count&lt;br /&gt;      last_date = count == 0 ? 'no data' : model.order('updated_at desc').first.updated_at&lt;br /&gt;      printf "%-20s   %9d   %s\n", name, count, last_date&lt;br /&gt;    end&lt;br /&gt;  end&lt;/pre&gt; &lt;br/&gt;&lt;img src="http://feeds.feedburner.com/~r/CraicComputingTechTips/~4/5seM4zGQ8QU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craiccomputing.blogspot.com/feeds/1988127624263605324/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7975027231082637331&amp;postID=1988127624263605324" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/1988127624263605324" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/1988127624263605324" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CraicComputingTechTips/~3/5seM4zGQ8QU/listing-all-models-and-numbers-of.html" title="Listing all the models and numbers of records in a Rails application" /><author><name>Robert Jones</name><uri>http://www.blogger.com/profile/07503053614730814672</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://craiccomputing.blogspot.com/2013/05/listing-all-models-and-numbers-of.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7975027231082637331.post-4749578608683409344</id><published>2013-04-17T10:02:00.002-07:00</published><updated>2013-04-18T10:09:14.508-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="AWS S3" /><category scheme="http://www.blogger.com/atom/ns#" term="firefox" /><category scheme="http://www.blogger.com/atom/ns#" term="html5" /><category scheme="http://www.blogger.com/atom/ns#" term="CORS" /><category scheme="http://www.blogger.com/atom/ns#" term="google chrome" /><title type="text">Gotchas when working with HTML5 Audio</title><content type="html">I've run into a few issues while building a demo web app that plays audio files, so I wanted to post my experiences...&lt;br /&gt;&lt;br /&gt;1: &lt;span style="color: #cc0000;"&gt;Firefox does NOT play MP3 files&lt;/span&gt; (as of 2013-04-17)&lt;br /&gt;&lt;br /&gt;This is because the MPEG format is proprietary and the Firefox/Mozilla folks insist on only open source formats. You need to use .wav, .ogg or .webm. See&amp;nbsp;&lt;a href="https://developer.mozilla.org/en-US/docs/HTML/Supported_media_formats"&gt;https://developer.mozilla.org/en-US/docs/HTML/Supported_media_formats&lt;/a&gt; for the allowed options.&lt;br /&gt;&lt;br /&gt;Unfortunately they do not seem to produce a useful error message if you try and play an MP3 file.&lt;br /&gt;&lt;br /&gt;Google Chrome plays anything - so your application may appear to work fine but may fail on Firefox.&lt;br /&gt;&lt;br /&gt;2: &lt;span style="color: #cc0000;"&gt;Firefox is VERY strict in regard to Cross-Origin Resource Sharing&lt;/span&gt; (CORS)&lt;br /&gt;&lt;br /&gt;Firefox will refuse to play an audio file on a host other than the one that served the original web page. So you can't store an audio file on, say, Amazon S3, and play it on your web site. The same goes for Ajax requests to another site. The Firefox console will, or may, display an error but this is not necessarily clear.&lt;br /&gt;&lt;br /&gt;Google Chrome doesn't seem to care about this restriction.&lt;br /&gt;&lt;br /&gt;See this page for more details &lt;a href="https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS"&gt;https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;To work around this you can specify a header for the audio file which means that as the owner of the audio file you allow it to be referenced from any other site.&lt;br /&gt;&lt;span style="color: blue; font-family: Courier New, Courier, monospace;"&gt;"Access-Control-Allow-Origin" = "*"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To work around the problem with Ajax requests you can use JSONP instead of JSON as &lt;a href="http://json-jsonp-tutorial.craic.com/"&gt;I have described.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The special header ought to work with AWS S3... except....&lt;br /&gt;&lt;br /&gt;3: &lt;span style="color: #cc0000;"&gt;AWS S3 does NOT allow the&amp;nbsp;Access-Control-Allow-Origin header&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;You can set metadata headers with S3 files but not this one. The Amazon support forums are full of requests/complaints about this but it does not seem to have been resolved.&lt;br /&gt;&lt;br /&gt;There does seem to be a way round this on Amazon Cloudfront, which pretty much exists to server assets for other sites, but from what I've seen this is pretty ugly.&lt;br /&gt;&lt;br /&gt;My workaround for this was to add a proxy method to my server. The client requests a file that resides on S3 from the proxy. It fetches it from S3 and echoes it to the client, which sees it as coming from the originating server. This introduces an unnecessary delay but works file. Here is a snippet of code in Ruby for a Sinatra server. It uses the aws-sdk gem and leaves out set up for that.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue; font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; get '/proxy' do&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue; font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; s3obj = bucket.objects[params['file']]&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue; font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; response["Access-Control-Allow-Origin"] = "*"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue; font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; content_type 'audio/wav'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue; font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; s3obj.read&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue; font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Apparently Google's equivalent of S3 does not have this issue - I've not tried it.&lt;br /&gt;&lt;br /&gt;4: &lt;span style="color: #cc0000;"&gt;You cannot play audio files from localhost&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This makes testing a pain. Your audio files must be hosted on a server other than localhost. I recommend &lt;a href="http://heroku.com/"&gt;Heroku&lt;/a&gt; as a way to get development servers up and running quickly and at no initial cost.&lt;br /&gt;&lt;br /&gt;If you don't realize this, then there is no error message in the browser console - it simply doesn't work and you are left scratching your head until you figure it out. I hate stuff like that...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/CraicComputingTechTips/~4/RKHqyQl13N8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craiccomputing.blogspot.com/feeds/4749578608683409344/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7975027231082637331&amp;postID=4749578608683409344" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/4749578608683409344" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/4749578608683409344" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CraicComputingTechTips/~3/RKHqyQl13N8/gotchas-when-working-with-htm5-audio.html" title="Gotchas when working with HTML5 Audio" /><author><name>Robert Jones</name><uri>http://www.blogger.com/profile/07503053614730814672</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://craiccomputing.blogspot.com/2013/04/gotchas-when-working-with-htm5-audio.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7975027231082637331.post-4924908329608255943</id><published>2013-04-16T15:01:00.000-07:00</published><updated>2013-04-16T15:01:32.936-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Heroku" /><category scheme="http://www.blogger.com/atom/ns#" term="bing translate" /><category scheme="http://www.blogger.com/atom/ns#" term="text to speech" /><category scheme="http://www.blogger.com/atom/ns#" term="ajax" /><category scheme="http://www.blogger.com/atom/ns#" term="amazon s3" /><category scheme="http://www.blogger.com/atom/ns#" term="sinatra" /><title type="text">Web Text To Speech using Bing Translate - Demonstration Sinatra App</title><content type="html">Given the variety of sophisticated web services available today, it is surprising that a good Text To Speech API (TTS) is not readily available.&lt;br /&gt;&lt;br /&gt;Google has one as part of its Translation API but it is not publicized or actively supported. The Bing/Microsoft Translate API also has a TTS feature and this is supported. In my experience this works very well and allows you to specify the language of the text, which changes the voice and pronunciation that is used.&lt;br /&gt;&lt;br /&gt;Accessing this API is easy enough using a wrapper library, such as&amp;nbsp;&lt;a href="https://github.com/CodeBlock/bing_translator-gem"&gt;https://github.com/CodeBlock/bing_translator-gem&lt;/a&gt;&amp;nbsp;(disclaimer: I added the speak() function to this ruby gem) but it returns binary data that represents an MP3 file. The HTML5 audio tag allows you play audio files, but not, apparently, to play the data itself.&lt;br /&gt;&lt;br /&gt;The result is that the TTS output must be first written to a file and then played via the audio tag.&lt;br /&gt;&lt;br /&gt;To demonstrate how these different pieces fit together, I have written a TTS demo app that consists of a Javascript in a web page that sends the query text to a Sinatra app, using ajax. The server in turn sends this to Bing and get back the audio. The server then writes this to a file on Amazon S3 and returns the URL for this back to the web page where the audio is played.&lt;br /&gt;&lt;br /&gt;The Live Demo for this is at&amp;nbsp;&lt;a href="http://bing-translate-tts-demo.craic.com/"&gt;http://bing-translate-tts-demo.craic.com/&lt;/a&gt;&amp;nbsp;and the code required to implement the whole thing is freely available at&amp;nbsp;&lt;a href="https://github.com/craic/bing_translate_text_to_speech"&gt;https://github.com/craic/bing_translate_text_to_speech&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The demo has several moving parts and setting it up for yourself requires experience with Sinatra, S3, etc.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/CraicComputingTechTips/~4/lb-ajqo_6MY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craiccomputing.blogspot.com/feeds/4924908329608255943/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7975027231082637331&amp;postID=4924908329608255943" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/4924908329608255943" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/4924908329608255943" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CraicComputingTechTips/~3/lb-ajqo_6MY/web-text-to-speech-using-bing-translate.html" title="Web Text To Speech using Bing Translate - Demonstration Sinatra App" /><author><name>Robert Jones</name><uri>http://www.blogger.com/profile/07503053614730814672</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://craiccomputing.blogspot.com/2013/04/web-text-to-speech-using-bing-translate.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7975027231082637331.post-1778660079988254095</id><published>2013-04-12T13:55:00.000-07:00</published><updated>2013-04-12T13:55:24.336-07:00</updated><title type="text">Zillow Neighborhood Boundaries in GeoJSON and KML for Seattle</title><content type="html">&lt;br /&gt;&lt;div style="border: 0px; color: #333333; line-height: 22px; margin-bottom: 15px; padding: 0px;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;The good people at&amp;nbsp;&lt;a href="http://www.zillow.com/" style="border: 0px; color: #4183c4; margin: 0px; padding: 0px; text-decoration: none;"&gt;Zillow&lt;/a&gt;&amp;nbsp;have invested a lot of time defining the boundaries of around 7,000 neighborhoods in cities around the USA.&lt;/span&gt;&lt;/div&gt;&lt;div style="border: 0px; color: #333333; line-height: 22px; margin-bottom: 15px; margin-top: 15px; padding: 0px;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;These are in the form of&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Shapefile" style="border: 0px; color: #4183c4; margin: 0px; padding: 0px; text-decoration: none;"&gt;ESRI ARC Shapefiles&lt;/a&gt;&amp;nbsp;that can be used as overlays on maps.&lt;/span&gt;&lt;/div&gt;&lt;div style="border: 0px; color: #333333; line-height: 22px; margin-bottom: 15px; margin-top: 15px; padding: 0px;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;You can find these at&amp;nbsp;&lt;a href="http://www.zillow.com/howto/api/neighborhood-boundaries.htm" style="border: 0px; color: #4183c4; margin: 0px; padding: 0px; text-decoration: none;"&gt;Zillow Neighborhood Boundaries&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;&lt;div style="border: 0px; color: #333333; line-height: 22px; margin-bottom: 15px; margin-top: 15px; padding: 0px;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;Zillow have kindly made these available to the rest of us under a&amp;nbsp;&lt;a href="http://creativecommons.org/licenses/by-sa/3.0/" style="border: 0px; color: #4183c4; margin: 0px; padding: 0px; text-decoration: none;"&gt;Creative Commons license&lt;/a&gt;. This allows you to share and modify the data but you need to attribute Zillow and must distribute any derivative forms of the data under the same or similar licenses. Attribution should take the form of including their logo with a link back to their site.&lt;/span&gt;&lt;/div&gt;&lt;div style="border: 0px; color: #333333; line-height: 22px; margin-bottom: 15px; margin-top: 15px; padding: 0px;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;ESRI shapefiles can be read by many types of mapping software, but one big exception to this is&amp;nbsp;&lt;a href="https://maps.google.com/" style="border: 0px; color: #4183c4; margin: 0px; padding: 0px; text-decoration: none;"&gt;Google Maps&lt;/a&gt;. Overlays in Google Maps are loaded from&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Keyhole_Markup_Language" style="border: 0px; color: #4183c4; margin: 0px; padding: 0px; text-decoration: none;"&gt;KML format&lt;/a&gt;&amp;nbsp;files. In addition&amp;nbsp;&lt;a href="http://www.geojson.org/" style="border: 0px; color: #4183c4; margin: 0px; padding: 0px; text-decoration: none;"&gt;GeoJSON&lt;/a&gt;&amp;nbsp;is a JSON-based format that is gaining in popularity.&lt;/span&gt;&lt;/div&gt;&lt;div style="border: 0px; color: #333333; line-height: 22px; margin-bottom: 15px; margin-top: 15px; padding: 0px;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;I needed neighborhood boundaries for the City of Seattle in KML format so I can use them in Google Maps. I couldn't find a convenient way to convert from Shapefile directly to KML (although these do exist in some GIS packages) and the solution I came up with involved converting first from Shapefile to GeoJSON and them from GeoJSON to KML. I'll make that software available elsewhere.&lt;/span&gt;&lt;/div&gt;&lt;div style="border: 0px; margin-bottom: 15px; margin-top: 15px; padding: 0px;"&gt;&lt;span style="color: #333333; font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span style="line-height: 22px;"&gt;My Github Project&amp;nbsp;&lt;a href="https://github.com/craic/zillow_seattle_neighborhoods"&gt;zillow_seattle_neighborhoods&lt;/a&gt; contains&amp;nbsp;the GeoJSON and KML files for the 78 Seattle neighborhoods defined in Zillow's dataset.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="border: 0px; color: #333333; line-height: 22px; margin-bottom: 15px; margin-top: 15px; padding: 0px;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;The same approach could be applied to derive GeoJSON and KML files for the entire Zillow US city dataset. I'll see if I can do that in the future... for now it just covers Seattle.&lt;/span&gt;&lt;/div&gt;&lt;div style="border: 0px; color: #333333; line-height: 22px; margin-bottom: 15px; margin-top: 15px; padding: 0px;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="border: 0px; color: #333333; line-height: 22px; margin-bottom: 15px; margin-top: 15px; padding: 0px;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;Using the Files&lt;/span&gt;&lt;/div&gt;&lt;div style="border: 0px; color: #333333; line-height: 22px; margin-bottom: 15px; margin-top: 15px; padding: 0px;"&gt;&lt;/div&gt;&lt;div style="border: 0px; margin-bottom: 15px; padding: 0px;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;You can use either format of file in many GIS packages and mapping programs. Here are a few ideas for people who are new to this area of coding.&lt;/span&gt;&lt;/div&gt;&lt;div style="border: 0px; margin-bottom: 15px; margin-top: 15px; padding: 0px;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;You can load KML files into your own maps using&amp;nbsp;&lt;a href="https://maps.google.com/" style="border: 0px; color: #4183c4; margin: 0px; padding: 0px; text-decoration: none;"&gt;Google Maps&lt;/a&gt;&amp;nbsp;directly. Look under 'My Places' -&amp;gt; 'Create Map' -&amp;gt; 'Import'. See Google Maps documentation for details.&lt;/span&gt;&lt;/div&gt;&lt;div style="border: 0px; margin-bottom: 15px; margin-top: 15px; padding: 0px;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;You can load the KML files into Google Earth for a different experience. The command 'open .kml' on a Mac with Google Earth installed should be enough.&lt;/span&gt;&lt;/div&gt;&lt;div style="border: 0px; margin-bottom: 15px; margin-top: 15px; padding: 0px;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;To use these overlays in custom Google Maps you want to use the&amp;nbsp;&lt;a href="https://developers.google.com/maps/documentation/javascript/" style="border: 0px; color: #4183c4; margin: 0px; padding: 0px; text-decoration: none;"&gt;Google Maps JavaScript API&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;&lt;div style="border: 0px; margin-bottom: 15px; margin-top: 15px; padding: 0px;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;I'll add an example HTML page that shows how to do this in due course...&lt;/span&gt;&lt;/div&gt;&lt;div style="border: 0px; margin-bottom: 15px; margin-top: 15px; padding: 0px;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;Two important things to note about testing KML overlays in Google Maps in your own HTML pages&lt;/span&gt;&lt;/div&gt;&lt;div style="border: 0px; margin-bottom: 15px; margin-top: 15px; padding: 0px;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;1: Your KML files MUST be hosted on a remote server. They will be ignored if you give try and host them from a server on localhost !&lt;/span&gt;&lt;/div&gt;&lt;div style="border: 0px; margin-bottom: 15px; margin-top: 15px; padding: 0px;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;2: KML files are CACHED in web pages, just like images. So if you are changing the files, such as changing the colors, these will not be visible unless you work around the caching issue. The easiest way to do this is to add a question mark followed by a random string at the end of the url for the KML file, and change this on every page reload.&lt;/span&gt;&lt;/div&gt;&lt;div style="border: 0px; margin-bottom: 15px; margin-top: 15px; padding: 0px;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;For example:&amp;nbsp;&lt;a href="http://yourserver.net/yourfile.kml?1234567" style="border: 0px; color: #4183c4; margin: 0px; padding: 0px; text-decoration: none;"&gt;http://yourserver.net/yourfile.kml?1234567&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="border: 0px; margin-bottom: 15px; margin-top: 15px; padding: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/CraicComputingTechTips/~4/0GbLudSPzSA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craiccomputing.blogspot.com/feeds/1778660079988254095/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7975027231082637331&amp;postID=1778660079988254095" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/1778660079988254095" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/1778660079988254095" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CraicComputingTechTips/~3/0GbLudSPzSA/zillow-neighborhood-boundaries-in.html" title="Zillow Neighborhood Boundaries in GeoJSON and KML for Seattle" /><author><name>Robert Jones</name><uri>http://www.blogger.com/profile/07503053614730814672</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://craiccomputing.blogspot.com/2013/04/zillow-neighborhood-boundaries-in.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7975027231082637331.post-1983502708623420381</id><published>2013-04-05T15:21:00.000-07:00</published><updated>2013-04-05T15:47:51.222-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="timezone" /><category scheme="http://www.blogger.com/atom/ns#" term="time" /><title type="text">Fixing incorrect timezones in Ruby</title><content type="html">Timezones can be tricky to manage and sometimes I just get them wrong - like now...&lt;br /&gt;&lt;br /&gt;I had been parsing strings representing local times in Seattle and then storing these without an explicit timezone on a machine which uses UTC by default - so they got stored as that time in UTC (not converted to UTC - the exact time string in UTC.&lt;br /&gt;&lt;br /&gt;For example:&amp;nbsp;&lt;span style="color: red;"&gt;Fri, 05 Apr 2013 14:24:39&lt;/span&gt; (the local time in Seattle) was stored as &lt;span style="color: red;"&gt;Fri, 05 Apr 2013 14:24:39 UTC +00:00&lt;/span&gt; which is 7 hours earlier than it should be.&lt;br /&gt;&lt;br /&gt;The easiest way to fix this, that I found is to convert back to a string, strip of any record of a timezone and then parse it back into a time, having temporarily set the &lt;span style="color: red;"&gt;TZ&lt;/span&gt; environment variable to the correct local timezone.&lt;br /&gt;&lt;br /&gt;NOTE that this works on UNIX/Mac OS X systems - not sure about Windows...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;puts&amp;nbsp;ENV['TZ']&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color: #999999;"&gt;=&amp;gt; nil&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;puts t &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;span style="color: #999999;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: blue;"&gt;2013-04-05 14:24:39 UTC&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;s = t.to_s&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;puts s &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;span style="color: #999999;"&gt;=&amp;gt; "2013-04-05 14:24:39 UTC"&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;s.sub!(/\s+UTC/, '')&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;puts s &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;span style="color: #999999;"&gt;=&amp;gt; "2013-04-05 14:24:39"&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;ENV['TZ'] = 'US/Pacific'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;t1 = Time.parse(s)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;ENV['TZ'] = nil&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;puts t1 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color: #999999;"&gt;=&amp;gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: red;"&gt;2013-04-05 14:24:39 -0700&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Remember to reset the TZ environment variable back to nil&lt;br /&gt;&lt;br /&gt;Be very careful about using &lt;span style="color: red;"&gt;gmtime&lt;/span&gt; and &lt;span style="color: red;"&gt;localtime&lt;/span&gt; as these methods operate&lt;span style="color: blue;"&gt; in place&lt;/span&gt;. &lt;span style="color: red;"&gt;So ALWAYS make a copy of your time before applying those conversions&lt;/span&gt;&lt;br /&gt;&lt;span style="color: red; font-family: Courier New, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: red; font-family: Courier New, Courier, monospace;"&gt;t &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;=&amp;gt; 2013-04-05 15:25:41 -0700&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;t1 = t.dup&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;t.gmtime &amp;nbsp; &amp;nbsp; =&amp;gt; 2013-04-05 22:25:41 UTC&lt;/span&gt;&lt;br /&gt;&lt;span style="color: red; font-family: Courier New, Courier, monospace;"&gt;t &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;=&amp;gt; 2013-04-05 22:25:41 UTC&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;t1 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; =&amp;gt; 2013-04-05 15:25:41 -0700&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Times, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: Times, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;img src="http://feeds.feedburner.com/~r/CraicComputingTechTips/~4/b8B1VybkDa8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craiccomputing.blogspot.com/feeds/1983502708623420381/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7975027231082637331&amp;postID=1983502708623420381" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/1983502708623420381" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/1983502708623420381" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CraicComputingTechTips/~3/b8B1VybkDa8/fixing-incorrect-timezones-in-ruby.html" title="Fixing incorrect timezones in Ruby" /><author><name>Robert Jones</name><uri>http://www.blogger.com/profile/07503053614730814672</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://craiccomputing.blogspot.com/2013/04/fixing-incorrect-timezones-in-ruby.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7975027231082637331.post-2390922191667612715</id><published>2013-04-03T14:13:00.003-07:00</published><updated>2013-04-03T14:13:40.767-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="longitude" /><category scheme="http://www.blogger.com/atom/ns#" term="latitude" /><category scheme="http://www.blogger.com/atom/ns#" term="bing maps" /><category scheme="http://www.blogger.com/atom/ns#" term="google maps" /><title type="text">Using Latitude and Longitude with Google and Bing Maps</title><content type="html">When you work with maps you sometimes want to extract a Latitude/Longitude pair from the map, or you want to enter a pair and see the corresponding map.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://maps.google.com/"&gt;Google Maps&lt;/a&gt; and &lt;a href="http://www.bing.com/maps/"&gt;Bing Maps&lt;/a&gt; do things slightly differently. In general I go with Google but there is not a lot in it. Here are how you work with Latitude/Longitude in both of them:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #45818e;"&gt;1: Enter an Address and get the Latitude/Longitude pair&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;Bing&lt;/span&gt; - Enter the address - the Lat/Lon pair will be shown below the Address in the left hand panel&lt;br /&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;Google&lt;/span&gt; - Enter the address - then Right Click the marker and select &lt;span style="color: red;"&gt;What's here?&lt;/span&gt; - the Lat/Lon pair will appear in the address entry box&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #45818e;"&gt;2: Browse to a Location and get the Latitude/Longitude pair&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;Bing&lt;/span&gt; - Browse to the location - then Right Click and the Lat/Lon pair will be shown in the popup&lt;br /&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;Google&lt;/span&gt; - Browse to the location - then Right Click the marker and select 'What's Here - the Lat/Lon pair will appear in the address entry box&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #45818e;"&gt;3: Enter a Latitude/Longitude pair and view the Location&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;Bing&lt;/span&gt; and &lt;span style="color: red;"&gt;Google&lt;/span&gt; - Enter the Lat/Lon pair, separated by a comma, into the address box (e.g.&amp;nbsp;47.619905,-122.320844) - Google makes a better choice of zoom level in my opinion.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/CraicComputingTechTips/~4/q6TFQo4IY1I" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craiccomputing.blogspot.com/feeds/2390922191667612715/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7975027231082637331&amp;postID=2390922191667612715" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/2390922191667612715" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/2390922191667612715" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CraicComputingTechTips/~3/q6TFQo4IY1I/using-latitude-and-longitude-with.html" title="Using Latitude and Longitude with Google and Bing Maps" /><author><name>Robert Jones</name><uri>http://www.blogger.com/profile/07503053614730814672</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://craiccomputing.blogspot.com/2013/04/using-latitude-and-longitude-with.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7975027231082637331.post-7517918756855817957</id><published>2013-03-21T08:39:00.001-07:00</published><updated>2013-03-21T08:39:31.543-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="soda" /><category scheme="http://www.blogger.com/atom/ns#" term="JSON" /><category scheme="http://www.blogger.com/atom/ns#" term="api" /><category scheme="http://www.blogger.com/atom/ns#" term="open-uri" /><category scheme="http://www.blogger.com/atom/ns#" term="socrata" /><title type="text">SODA - Socrata Open Data API</title><content type="html">&lt;a href="http://www.socrata.com/"&gt;Socrata&lt;/a&gt; is a company that helps organizations make their data available to outside users. They work with people like the World Bank and a number of city governments, including the &lt;a href="https://data.seattle.gov/"&gt;City of Seattle&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;You can access these public data sources via &lt;a href="http://dev.socrata.com/"&gt;SODA - the&amp;nbsp;Socrata Open Data API&lt;/a&gt;&amp;nbsp;which provides a &lt;a href="http://dev.socrata.com/docs/queries"&gt;SQL-like query language (SoQL)&lt;/a&gt; that you submit via HTTP request to an API endpoint for that resource. The default response is JSON but you can get CSV, XML and RDF.&lt;br /&gt;&lt;br /&gt;They provide quite a bit of &lt;a href="http://dev.socrata.com/consumers/getting-started/"&gt;documentation&lt;/a&gt; but it is a bit short on examples and I had to poke around a bit to get the right syntax for the data sources that I am interested in.&lt;br /&gt;&lt;br /&gt;A very useful resource is the &lt;a href="http://live-docs.socrata.com/soda.demo.socrata.com/explore/earthquakes?$where=magnitude%20%3E%205"&gt;'live' query console&lt;/a&gt; they provide for a test dataset, which lets you try various queries.&lt;br /&gt;&lt;br /&gt;I access their resources from Ruby. I generate the URL, use open-uri to fetch the data and then parse the JSON response. Here is an example fo the process:&lt;br /&gt;&lt;br /&gt;The data source I want to query list the &lt;a href="https://data.seattle.gov/Public-Safety/Seattle-Real-Time-Fire-911-Calls/kzjm-xkqj"&gt;Seattle Fire Department 911 calls&lt;/a&gt;. That page lets you create custom views and download the data. If you click on 'Export' you can see the column names used in the database as well as the url for the API endpoint.&lt;br /&gt;&lt;br /&gt;I want to get all records in the past hour, so I need a query along the lines of 'where datetime &amp;gt; my_timestamp'. Specifically I need to build a URL similar to this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="color: #cc0000;"&gt;http://data.seattle.gov/resource/kzjm-xkqj.json?$where datetime &amp;gt; my_time_stamp&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;This is not a real query just yet but note a couple of things...&lt;br /&gt;&lt;br /&gt;The API endpoint is &lt;span style="color: #cc0000;"&gt;http://data.seattle.gov/resource/kzjm-xkqj.json&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This version ends in '&lt;span style="color: #cc0000;"&gt;.json&lt;/span&gt;' and so it will return the response in JSON. If you want CSV then replace '.json' with '.csv' - same goes for XML and RDF.&lt;br /&gt;&lt;br /&gt;Also note the dollar sign before the 'where' - it is easy to overlook - that signifies the following word is a SoQL clause and not the name of a column.&lt;br /&gt;&lt;br /&gt;A big problem I ran into was figuring out the format for timestamps. The web page showing the table formats them as '&lt;span style="color: #cc0000;"&gt;03/21/2013 07:35:00 AM -0700&lt;/span&gt;' whereas the JSON response uses &lt;span style="color: #cc0000;"&gt;"datetime" : 1363872960&lt;/span&gt;. But neither of these works in a query... and the documentation on data types does not describe what you should use. Trial and error with that console page led me to the correct format of '&lt;span style="color: #cc0000;"&gt;2013-03-21 07:00:00&lt;/span&gt;' which is similar to the ISO 8601 format.&lt;br /&gt;&lt;br /&gt;Also note that the time &lt;span style="color: #cc0000;"&gt;needs to be quoted&lt;/span&gt;... again, apparently not in the documentation&lt;br /&gt;&lt;br /&gt;So my query should now look something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="color: #cc0000;"&gt;http://data.seattle.gov/resource/kzjm-xkqj.json?$where datetime &amp;gt; '2013-03-21 07:00:00'&lt;/span&gt;&lt;/pre&gt;&lt;div&gt;&lt;span style="color: #cc0000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;But that URL needs to be escaped before submission. That was the other issue - URI.escape() handles the spaces, quotes, etc but for some reason it does not escape the dollar sign. So I had to do that for myself.&lt;br /&gt;&lt;br /&gt;Here is a chunk of Ruby code that gets all the 911 calls in the past hour:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="color: #cc0000;"&gt;require 'open-uri'&lt;br /&gt;require 'time'&lt;br /&gt;require 'json'&lt;br /&gt;&lt;br /&gt;endpoint = 'http://data.seattle.gov/resource/kzjm-xkqj.json'&lt;br /&gt;timestamp = (Time.now - (60 * 60)).strftime("%F %H:%M:%S")&lt;br /&gt;&lt;br /&gt;query = "$where=datetime &amp;gt; '#{timestamp}'"&lt;br /&gt;&lt;br /&gt;url = "#{endpoint}?#{query}"&lt;br /&gt;url = URI.escape(url)&lt;br /&gt;url.gsub!(/\$/, '%24')&lt;br /&gt;&lt;br /&gt;puts "query: #{query}&lt;br /&gt;puts "url: #{url}&lt;br /&gt;&lt;br /&gt;json = open(url).read&lt;br /&gt;puts json&lt;br /&gt;&lt;br /&gt;result = JSON.parse(json)&lt;br /&gt;puts result.length&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That will show you the query, the escaped URL, the JSON returned and the number of records in the parsed JSON - enough to get you started. Different data sources will use different column names and perhaps different formats for date/time (always be aware of time zone issues).&lt;br /&gt;&lt;br /&gt;Having a common API to many government/public data sources is great but the Socrata-backed sources that I've looked a so far don't seem to be quite as consistent as one would hope. This is an issue for the different data providers - it's not a Socrata issue.&lt;br /&gt;&lt;br /&gt;I would hope that one could query the endpoint in some way and get a listing of all the column names and data types. There is one for SODA v1.0 but this now &lt;a href="http://dev.socrata.com/deprecated/accessing-view-metadata"&gt;deprecated&lt;/a&gt;... so perhaps there is a newer version but it has not been documented.&lt;br /&gt;&lt;br /&gt;Part of the answer lies in two custom HTTP response headers (X-SODA2-Fields and X-SODA2-Types) that are returned with your data. Here they are for the data source used here:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="color: #cc0000;"&gt;X-SODA2-Fields: [":updated_at","address","longitude",":id","latitude","incident_number","datetime","type",":created_at","report_location"]&lt;br /&gt;X-SODA2-Types: ["meta_data","text","number","meta_data","number","text","date","text","meta_data","location"]&lt;br /&gt;X-SODA2-Legacy-Types: true&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;You can see the headers if you use '&lt;span style="color: #cc0000;"&gt;curl -i "your_url"&lt;/span&gt;' on the command line with your escaped url.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/CraicComputingTechTips/~4/LLQbtz_-U-I" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craiccomputing.blogspot.com/feeds/7517918756855817957/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7975027231082637331&amp;postID=7517918756855817957" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/7517918756855817957" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/7517918756855817957" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CraicComputingTechTips/~3/LLQbtz_-U-I/soda-socrata-open-data-api.html" title="SODA - Socrata Open Data API" /><author><name>Robert Jones</name><uri>http://www.blogger.com/profile/07503053614730814672</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://craiccomputing.blogspot.com/2013/03/soda-socrata-open-data-api.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7975027231082637331.post-3096284999836280616</id><published>2013-03-08T14:31:00.000-08:00</published><updated>2013-03-08T14:31:10.743-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="web speech" /><category scheme="http://www.blogger.com/atom/ns#" term="html5" /><category scheme="http://www.blogger.com/atom/ns#" term="web audio" /><category scheme="http://www.blogger.com/atom/ns#" term="google chrome" /><category scheme="http://www.blogger.com/atom/ns#" term="google maps" /><title type="text">HTML5 and web API code examples</title><content type="html">Whenever I am learning a new feature of HTML5, JavaScript/Jquery or a new API, such as Google Maps, I always look for example code that I can learn from.&lt;br /&gt;&lt;br /&gt;In many cases the examples are great, but in others they can be too clever and too heavily styled, such that it can be hard to understand the core of the feature that they are demonstrating.&lt;br /&gt;&lt;br /&gt;So in writing my own example code I try and strip things down to the bare minimum - very little styling and code that tries to do one, and only one, thing.&lt;br /&gt;&lt;br /&gt;I've been collecting examples that I think have some substance and that can help others learn about a feature with the minimum of confusion.&lt;br /&gt;&lt;br /&gt;Take a look at &lt;a href="http://html5-examples.craic.com/"&gt;http://html5-examples.craic.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This site has working examples of a number of HTML5-related features, including Data Attributes, Geolocation, Web Audio and Speech Recognition.&lt;br /&gt;&lt;br /&gt;Look at the Source for each of these pages to see annotated JavaScript, etc. which illustrates the target feature of each page.&lt;br /&gt;&lt;br /&gt;All the code is distributed freely under the terms of the MIT license and you are encouraged to build your own applications using it.&lt;br /&gt;&lt;br /&gt;Note that some of the examples involve new web technologies, so they may not work in some browsers and what does work now may not work in the future as the APIs mature.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/CraicComputingTechTips/~4/eIViV7mYlKI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craiccomputing.blogspot.com/feeds/3096284999836280616/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7975027231082637331&amp;postID=3096284999836280616" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/3096284999836280616" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/3096284999836280616" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CraicComputingTechTips/~3/eIViV7mYlKI/html5-and-web-api-code-examples.html" title="HTML5 and web API code examples" /><author><name>Robert Jones</name><uri>http://www.blogger.com/profile/07503053614730814672</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://craiccomputing.blogspot.com/2013/03/html5-and-web-api-code-examples.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7975027231082637331.post-2754441255072236593</id><published>2013-02-26T13:23:00.000-08:00</published><updated>2013-02-26T13:23:16.815-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="devise" /><category scheme="http://www.blogger.com/atom/ns#" term="authentication" /><title type="text">General approach to building Rails applications with Devise</title><content type="html">I have built a number of complex Rails applications that include user authentication. I want to describe my general approach to getting these up and running.&lt;br /&gt;&lt;br /&gt;In most of them I chose the &lt;a href="https://github.com/plataformatec/devise"&gt;Devise&lt;/a&gt; gem to handle authentication and added a number of custom fields to the User model (first name, last name, etc). The gem documentation and this &lt;a href="http://railscasts.com/episodes/209-devise-revised"&gt;Railscast&lt;/a&gt; can help you get started with all that.&lt;br /&gt;&lt;br /&gt;One approach is to build your core application without authentication and then add it in at a later stage but I don't like that.&lt;br /&gt;&lt;br /&gt;Authentication can quickly get very complicated once you start adding user confirmation via email, an admin role and other custom fields. I prefer to get all that machinery up and running in the context of a &lt;i&gt;very simple application&lt;/i&gt; and only then add my real application code into it.&lt;br /&gt;&lt;br /&gt;Similarly, when I'm starting with a new application I don't usually hit on the right data architecture right away. That leads to me adding new columns to my database tables and models over time and it always involves quite a lot of 'rake db:rollback / rake db:migrate' operations. I prefer to go through this phase &lt;i&gt;without the extra baggage of authentication&lt;/i&gt;, and often, without worrying a lot about CSS etc. I just need to try several alternate views of the problem before I settle on a final design.&lt;br /&gt;&lt;br /&gt;So may approach is to build two applications side by side. The first is a minimal application with, say, a single table (usually called 'posts') to which I add Devise and configure all the options that I want.&lt;br /&gt;&lt;br /&gt;This is a very useful piece of code for other applications, so I always create a good README and store a copy of the code for future use.&lt;br /&gt;&lt;br /&gt;Separately I work through my core application and, once that is working, I condense all the migrations that add/remove/rename columns into a few 'clean', simple migrations.&lt;br /&gt;&lt;br /&gt;Finally I add the core application code to the minimal authenticated application. That way it is easier for me to update the controllers, etc. to use authentication.&lt;br /&gt;&lt;br /&gt;The bottom line is that you want to &lt;i&gt;minimize the number of moving parts&lt;/i&gt; in the early stages of a new application design. This is a simple approach that works very well for me.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/CraicComputingTechTips/~4/J_zCsgvcdTU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craiccomputing.blogspot.com/feeds/2754441255072236593/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7975027231082637331&amp;postID=2754441255072236593" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/2754441255072236593" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/2754441255072236593" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CraicComputingTechTips/~3/J_zCsgvcdTU/general-approach-to-building-rails.html" title="General approach to building Rails applications with Devise" /><author><name>Robert Jones</name><uri>http://www.blogger.com/profile/07503053614730814672</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://craiccomputing.blogspot.com/2013/02/general-approach-to-building-rails.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7975027231082637331.post-7198620397814663853</id><published>2013-02-14T10:48:00.002-08:00</published><updated>2013-02-14T10:48:39.087-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="street intersection" /><category scheme="http://www.blogger.com/atom/ns#" term="google maps" /><title type="text">Street Intersections in Google Maps</title><content type="html">I need to display &lt;a href="https://developers.google.com/maps/documentation/javascript/tutorial"&gt;Google Maps&lt;/a&gt; with markers placed at street intersections, starting with an address that looks like '&lt;span style="color: red;"&gt;13 Av E / E John St, Seattle, WA&lt;/span&gt;'.&lt;br /&gt;&lt;br /&gt;Google Maps doesn't know how to parse this and gives me a location on John Street but it's not correct.&lt;br /&gt;&lt;br /&gt;Various sources on the web tell you use 'at' as the conjugation between the two streets - so '&lt;span style="color: red;"&gt;13 Av E at E John St, Seattle, WA&lt;/span&gt;'&lt;br /&gt;&lt;br /&gt;This works fine in most cases but in some, like this one, it fails - this gives the intersection of 13th Ave East and E Prospect (7 blocks away).&lt;br /&gt;&lt;br /&gt;What seems to work much better is to use 'and' ... '&lt;span style="color: red;"&gt;13 Av E and E John St, Seattle, WA&lt;/span&gt;' is spot on.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/CraicComputingTechTips/~4/oVbUaL98lrc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craiccomputing.blogspot.com/feeds/7198620397814663853/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7975027231082637331&amp;postID=7198620397814663853" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/7198620397814663853" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/7198620397814663853" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CraicComputingTechTips/~3/oVbUaL98lrc/street-intersections-in-google-maps.html" title="Street Intersections in Google Maps" /><author><name>Robert Jones</name><uri>http://www.blogger.com/profile/07503053614730814672</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://craiccomputing.blogspot.com/2013/02/street-intersections-in-google-maps.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7975027231082637331.post-8032977780184483257</id><published>2013-02-08T15:54:00.000-08:00</published><updated>2013-02-19T08:07:21.814-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="jquery" /><title type="text">Jquery snippet to disable / enable links on a page</title><content type="html">Here are two approaches to hiding all the anchor (a) tags on a page while retaining the html that was contained within the tags. They both use &lt;a href="http://jquery.com/"&gt;Jquery&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Approach #1 - Remove all the 'a' tags while retaining their content - no way to retrieve the links, etc.&lt;br /&gt;&lt;br /&gt;This lets you effectively disable all the links without losing any text. Using the .html() call instead of simply .text() means that any images or other formatting is preserved.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;    $("a").each(function() {&lt;br /&gt;      var t = $(this).html();&lt;br /&gt;      $(this).replaceWith(t);&lt;br /&gt;    });&lt;/pre&gt;&lt;br /&gt;Approach #2 - Reversibly Hide and Show the tags&lt;br /&gt;&lt;br /&gt;Replace the 'a' tags with 'span' tags and store the original tag pair in a &lt;a href="http://html5doctor.com/html5-custom-data-attributes/"&gt;custom data attribute&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Custom data attributes all have the prefix 'data-' followed by a unique name. You can store arbitrary data in these. With this approach I am storing the original 'a' tag pair and its contents.&lt;br /&gt;&lt;br /&gt;In the example, my custom data attribute is called 'data-craic' and note that the 'span' tags are given a unique class (I'm using 'hidden-link') that allows you to identify them&lt;br /&gt;&lt;br /&gt;To hide/disable the links:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;  $("a").each(function() {&lt;br /&gt;    // Get the html within the 'a' tag pair&lt;br /&gt;    var t = $(this).html();&lt;/pre&gt;&lt;pre&gt;    // Get the entire tag pair as text by wrapping in an in-memory 'p' tag and fetching its html&lt;br /&gt;    var original_tag = $(this).clone().wrap('&amp;lt;p&amp;gt;').parent().html();&lt;/pre&gt;&lt;pre&gt;    // Replace the 'a' tag with a 'span' - put the original tag in the data attribute&lt;br /&gt;    $(this).replaceWith("&amp;lt;span class='hidden-link' data-craic='" + original_tag + "'&amp;gt;" + t + "&amp;lt;/span&amp;gt;"); &lt;br /&gt;  });&lt;/pre&gt;&lt;br /&gt;To show/enable the links:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;  $(".hidden-link").each(function() {&lt;br /&gt;    // Retrieve the original tag from the data attribute&lt;br /&gt;    var original_tag = this.dataset.craic;&lt;/pre&gt;&lt;pre&gt;    // Replace the 'span' with it&lt;br /&gt;    $(this).replaceWith(original_tag);&lt;br /&gt;  });&lt;/pre&gt;&lt;br /&gt;At least in my use cases I have not had to encode the original 'a' tag pairs but base64 encoding might be a good idea to avoid any possible unintended consequences.&lt;br /&gt;&lt;br /&gt;Custom data attributes are extremely useful and were the perfect to solution to this problem&lt;br /&gt;&lt;br /&gt;You can find a self contained web page with these scripts at&amp;nbsp;&lt;a href="https://gist.github.com/craic/4987192"&gt;https://gist.github.com/craic/4987192&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/CraicComputingTechTips/~4/XJgvwEzEP58" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craiccomputing.blogspot.com/feeds/8032977780184483257/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7975027231082637331&amp;postID=8032977780184483257" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/8032977780184483257" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/8032977780184483257" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CraicComputingTechTips/~3/XJgvwEzEP58/jquery-snippet-to-remove-links-from-page.html" title="Jquery snippet to disable / enable links on a page" /><author><name>Robert Jones</name><uri>http://www.blogger.com/profile/07503053614730814672</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://craiccomputing.blogspot.com/2013/02/jquery-snippet-to-remove-links-from-page.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7975027231082637331.post-3448455670756892984</id><published>2013-01-28T15:45:00.001-08:00</published><updated>2013-01-28T15:45:54.493-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="JSONP" /><category scheme="http://www.blogger.com/atom/ns#" term="getJSON" /><category scheme="http://www.blogger.com/atom/ns#" term="JSON" /><category scheme="http://www.blogger.com/atom/ns#" term="jquery" /><category scheme="http://www.blogger.com/atom/ns#" term="ajax" /><category scheme="http://www.blogger.com/atom/ns#" term="sinatra" /><title type="text">JSON versus JSONP Tutorial</title><content type="html">I recently found myself a bit confused on how to convert a &lt;a href="http://api.jquery.com/jQuery.getJSON/"&gt;JQuery $.getJSON()&lt;/a&gt; call to use &lt;a href="http://en.wikipedia.org/wiki/JSONP"&gt;JSONP&lt;/a&gt; (JSON with Padding).&lt;br /&gt;&lt;br /&gt;JSONP is a way to get around the Same Origin Policy&amp;nbsp;restriction&amp;nbsp;when a script in one domain wants to fetch JSON data from a server in a different domain.&lt;br /&gt;&lt;br /&gt;The approach is simple enough but I had trouble finding a clear explanation. So I wrote up a simple example in both JSON and JSONP with server and client code.&lt;br /&gt;&lt;br /&gt;The live demo is at &lt;a href="http://json-jsonp-tutorial.craic.com/"&gt;http://json-jsonp-tutorial.craic.com&lt;/a&gt; and all the code is on Github at&amp;nbsp;&lt;a href="https://github.com/craic/json_jsonp_tutorial"&gt;https://github.com/craic/json_jsonp_tutorial&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I hope that you find it useful...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/CraicComputingTechTips/~4/TvP0cNLRUhU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craiccomputing.blogspot.com/feeds/3448455670756892984/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7975027231082637331&amp;postID=3448455670756892984" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/3448455670756892984" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/3448455670756892984" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CraicComputingTechTips/~3/TvP0cNLRUhU/json-versus-jsonp-tutorial.html" title="JSON versus JSONP Tutorial" /><author><name>Robert Jones</name><uri>http://www.blogger.com/profile/07503053614730814672</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://craiccomputing.blogspot.com/2013/01/json-versus-jsonp-tutorial.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7975027231082637331.post-7419179783074398634</id><published>2012-12-05T13:12:00.000-08:00</published><updated>2012-12-05T13:12:37.942-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="canvas2image" /><category scheme="http://www.blogger.com/atom/ns#" term="Heroku" /><category scheme="http://www.blogger.com/atom/ns#" term="sinatra" /><category scheme="http://www.blogger.com/atom/ns#" term="canvas" /><title type="text">Tool to help Count Features in Images</title><content type="html">Craic has released a new tool to help count features in images. This can be used in a range of applications such as counting buildings in satellite images, bacterial colonies and cell types in histology images.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It takes the form of a Ruby Sinatra application that fetches remote images and Javascript in the client web page that&amp;nbsp;implements the marking and counting functions.&lt;br /&gt;&lt;br /&gt;The user can choose the shape and color of the marker. The current total is updated as features are clicked and the&amp;nbsp;coordinates of each point are stored internally.&lt;br /&gt;&lt;br /&gt;The image with the user's marks can then be saved to a PNG format file and the list of coordinate pairs can be displayed in a separate window.&lt;br /&gt;&lt;br /&gt;The graphics and interaction are implemented with Canvas and Javascript and make use of the wonderful &lt;a href="http://www.nihilogic.dk/labs/canvas2image/"&gt;Canvas2Image&lt;/a&gt; code from&amp;nbsp;Jacob Seidelin which allows the current state of a canvas element to be saved to an image file.&lt;br /&gt;&lt;br /&gt;The live application is hosted at &lt;a href="http://heroku.com/"&gt;Heroku&lt;/a&gt;&amp;nbsp;and can be accessed at &lt;a href="http://counter.craic.com/"&gt;http://counter.craic.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The code is distributed freely under the terms of the MIT license and is archived at &lt;a href="https://github.com/craic/feature_counter"&gt;Github&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/CraicComputingTechTips/~4/MWBR3SaMZms" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craiccomputing.blogspot.com/feeds/7419179783074398634/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7975027231082637331&amp;postID=7419179783074398634" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/7419179783074398634" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/7419179783074398634" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CraicComputingTechTips/~3/MWBR3SaMZms/tool-to-help-count-features-in-images.html" title="Tool to help Count Features in Images" /><author><name>Robert Jones</name><uri>http://www.blogger.com/profile/07503053614730814672</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://craiccomputing.blogspot.com/2012/12/tool-to-help-count-features-in-images.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7975027231082637331.post-3750017615194039809</id><published>2012-12-04T08:29:00.000-08:00</published><updated>2012-12-04T08:29:14.931-08:00</updated><title type="text">Counting Temporary Shelters in Satellite Images using OpenCV</title><content type="html">&lt;br /&gt;A number of areas of data analysis are dominated by sophisticated algorithms, intensive computation and, in some cases, limited access to raw data. Examples include the analysis of satellite imagery, feature extraction from video, protein structure analysis and language processing.&lt;br /&gt;&lt;br /&gt;I am interested in how simple, approximate methods can be used to extend the application of these technologies. While simple approaches will clearly not match the accuracy and resolution of complex methods, they can, by nature of their simplicity, be implemented and deployed more easily and hence more widely.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I have just posted the code for one of these projects to the &lt;a href="https://github.com/craic"&gt;Craic Github site&lt;/a&gt;. The application involves image processing of satellite images downloaded from Google Maps in order to estimate the number of temporary dwellings or shacks in the slums of Port-au-Prince in Haiti.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The satellite images of Port-au-Prince show large areas covered with &lt;a href="http://goo.gl/maps/7ObKv"&gt;small white, blue and rust colored squares.&lt;/a&gt; These are the slums of the city in areas such as St.Martin, Cite Soleil and others.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The blue features are very distinctive and most likely represent the ubiquitous blue plastic tarpaulins the you can find at any hardware store.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Using the Python interface to the wonderful &lt;a href="http://opencv.org/"&gt;OpenCV image processing library&lt;/a&gt;, I wrote a simple application that identifies blue features below a cutoff size and then computes their area. By fetching adjacent squares that tile across the city, and calculating the area of blue features, I can come up with an matrix showing the relative density of the slums.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The approach is undoubtedly simplistic (the code is only about 35 lines of Python) but it demonstrates how simple approaches can be successfully applied to complex and sophisticated types of data. You do not always need access to expensive commercial software and proprietary datasets in order to work in these fields.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The code is made freely available at&amp;nbsp;&lt;a href="https://github.com/craic/count_shelters"&gt;https://github.com/craic/count_shelters&lt;/a&gt;&amp;nbsp;and you can read my write up of the work so far, with example images &lt;a href="http://www.craic.com/documents/BlueTarpQuantificationReport.pdf"&gt;HERE&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CraicComputingTechTips/~4/h7DlR1er9pM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craiccomputing.blogspot.com/feeds/3750017615194039809/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7975027231082637331&amp;postID=3750017615194039809" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/3750017615194039809" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/3750017615194039809" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CraicComputingTechTips/~3/h7DlR1er9pM/counting-temporary-shelters-in.html" title="Counting Temporary Shelters in Satellite Images using OpenCV" /><author><name>Robert Jones</name><uri>http://www.blogger.com/profile/07503053614730814672</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://craiccomputing.blogspot.com/2012/12/counting-temporary-shelters-in.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7975027231082637331.post-1169284481147991830</id><published>2012-11-01T13:09:00.001-07:00</published><updated>2012-11-01T13:09:21.710-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="bookmarklet" /><category scheme="http://www.blogger.com/atom/ns#" term="jquery" /><title type="text">Tutorial on JS/JQuery Bookmarklets</title><content type="html">I recently needed to implement a JavaScript bookmarklet for a new project. There are many web resources available but even so I had a bit of a learning curve to contend with.&lt;br /&gt;&lt;br /&gt;In the hope of lessening that burden on future users, I've written up a tutorial on two types of bookmarklets with simple, annotated examples and posted all the code on our &lt;a href="https://github.com/craic/bookmarklet_tutorial"&gt;Github page&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The simplest form of bookmarklet is a chunk of JS code contained in the Bookmarklet URL that invokes some action.&amp;nbsp;This is a direct approach - you select some text, you click the bookmarklet and you get a result. If you want to repeat the process with some other text on the page then you have to click the bookmarklet link again.&lt;br /&gt;&lt;br /&gt;However, for many applications you need to invoke an action multiple times on a single page - looking up words in a dictionary would be a good example. Having to click on a Bookmarklet link every time is not a good solution. Instead you want to modify the behaviour of the page by injecting a custom JS script. A bookmarklet can be used to initiate this. So you end up with three scripts, two of which are slightly modified, general purpose scripts.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The bulk of the code for this second approach comes from &lt;a href="http://www.latentmotion.com/how-to-create-a-jquery-bookmarklet/"&gt;how-to-create-a-jquery-bookmarklet&lt;/a&gt;, written by Brett Barros of latentmotion.com, with some code input from Paul Irish.&lt;br /&gt;&lt;br /&gt;To fully benefit from the tutorial, you should download the project, run 'bundle install' and 'rackup -p 4567' to set up a local Sinatra server, then point your browser to http://localhost:4567&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/CraicComputingTechTips/~4/inrMRCwky60" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craiccomputing.blogspot.com/feeds/1169284481147991830/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7975027231082637331&amp;postID=1169284481147991830" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/1169284481147991830" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/1169284481147991830" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CraicComputingTechTips/~3/inrMRCwky60/tutorial-on-jsjquery-bookmarklets.html" title="Tutorial on JS/JQuery Bookmarklets" /><author><name>Robert Jones</name><uri>http://www.blogger.com/profile/07503053614730814672</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://craiccomputing.blogspot.com/2012/11/tutorial-on-jsjquery-bookmarklets.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7975027231082637331.post-1236462768976559396</id><published>2012-10-29T14:09:00.000-07:00</published><updated>2012-10-29T14:09:23.317-07:00</updated><title type="text">Rails 3.2 Asset Pipeline - 'require_tree' is evil !</title><content type="html">I have been battling the &lt;a href="http://guides.rubyonrails.org/asset_pipeline.html"&gt;Asset Pipeline&lt;/a&gt; in Rails 3 for a couple of days - and finally I've got it working&lt;br /&gt;&lt;br /&gt;An important part of the Asset Pipeline is the use of Manifest files in app/assets/javascripts and stylesheets which determine the specific files to include and, in some cases, the order in which they are processed.&lt;br /&gt;&lt;br /&gt;The default javascripts Manifest file has these lines:&lt;br /&gt;&lt;pre class='brush: javascript'&gt;//= require jquery&lt;br /&gt;//= require jquery_ujs&lt;br /&gt;//= require_self&lt;br /&gt;//= require_tree .&lt;/pre&gt;&lt;br /&gt;That reads as:&lt;br /&gt;- process jquery, then jquery_ujs&lt;br /&gt;- process anything in this file (self)&lt;br /&gt;- process all the files in this directory tree (require_tree)&lt;br /&gt;&lt;br /&gt;I don't have many JS files in my app - three custom JS files written by myself and a couple of third party libraries.&lt;br /&gt;&lt;br /&gt;I try and follow defaults as far as possible but require_tree has two BIG problems.&lt;br /&gt;&lt;br /&gt;First is that it processes ALL the files in the directory tree.&lt;br /&gt;Second is that the ORDER is UNDEFINED.&lt;br /&gt;&lt;br /&gt;It is common for JS libraries to distribute their code along with examples and minimized versions of the code. In the past I would just drop these distributions in the javascripts directory and then specify which of the files should be included in my app.&lt;br /&gt;&lt;br /&gt;So one problem with require_tree is that it will process both a 'native' and minimized version of the same library is both are present. That results in the same functions being defined multiple times - and that seems to be a real problem if a library includes it's own copy of jQuery.&lt;br /&gt;&lt;br /&gt;Not specifying the order of processing is the other BIG issue. For libraries with a 'core' JS file along with others will typically require that the core library is processed first.&lt;br /&gt;&lt;br /&gt;The solution is to avoid require_tree at all costs. Put only the JS files that you absolutely need in app/assets/javascripts and specify them EXPLICITLY in the order they should be processed.&lt;br /&gt;&lt;br /&gt;In my example, my application.js file becomes:&lt;br /&gt;&lt;pre class='brush: javascript'&gt;//= require jquery&lt;br /&gt;//= require jquery_ujs&lt;br /&gt;//= require ./tabs_timeline_simple&lt;br /&gt;//= require ./tandem_select&lt;br /&gt;//= require ./raphael-min&lt;br /&gt;//= require ./facebox&lt;/pre&gt;&lt;br /&gt;I strongly recommend that you start out with everything clearly defined like this. Once you have it all working then you can remove unused files and simplify application.js - if not, you risk going through the same debugging misery that I just went through.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/CraicComputingTechTips/~4/2f8V5hQUQfc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craiccomputing.blogspot.com/feeds/1236462768976559396/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7975027231082637331&amp;postID=1236462768976559396" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/1236462768976559396" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/1236462768976559396" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CraicComputingTechTips/~3/2f8V5hQUQfc/rails-32-asset-pipeline-requiretree-is.html" title="Rails 3.2 Asset Pipeline - 'require_tree' is evil !" /><author><name>Robert Jones</name><uri>http://www.blogger.com/profile/07503053614730814672</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://craiccomputing.blogspot.com/2012/10/rails-32-asset-pipeline-requiretree-is.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7975027231082637331.post-5179182982012507250</id><published>2012-10-25T11:35:00.001-07:00</published><updated>2012-10-25T11:35:36.596-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><title type="text">Upgrading from Rails 3.0 to 3.1 - Issues with Javascripts</title><content type="html">I have been upgrading a Rails app from 3.0.10 to 3.1.5.&lt;br /&gt;&lt;br /&gt;The BIG difference with 3.1 is the use of the Assets pipeline which requires that you move images, stylesheets and javascripts from public/* to app/assets/*. In the case of Stylesheets and Javascripts you also put these under the control of a Sprockets Manifest file: application.js or application.css.scss&lt;br /&gt;&lt;br /&gt;That Manifest file caused me problems with my javascripts...&lt;br /&gt;&lt;br /&gt;I followed the advice in the &lt;a href="http://railscasts.com/episodes/282-upgrading-to-rails-3-1"&gt;Railscasts Episode 282&lt;/a&gt;&amp;nbsp;(which I recommend you look at) and put these lines into my application.js&lt;br /&gt;&lt;pre class="brush: ruby"&gt;//= require jquery&lt;br /&gt;//= require jquery_ujs&lt;br /&gt;//= require_self&lt;br /&gt;//= require_tree .&lt;/pre&gt;But when I ran my app none of my javascript functions were working. Looking at the source for one of the pages I saw this link&lt;br /&gt;&lt;pre class="brush: html"&gt;&amp;nbsp; &amp;lt;script src="/assets/application.js" type="text/javascript"&amp;gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;Clicking on brought up a message, instead of a JS file,&amp;nbsp;&amp;nbsp;saying that Sprockets was unable to find the file 'jquery'&lt;br /&gt;&lt;br /&gt;Jquery is supposed to 'just be there' if you have the jquery-rails gem installed.&lt;br /&gt;&lt;br /&gt;I think there were a two, maybe three, issues.&lt;br /&gt;&lt;br /&gt;1: Sprockets requires that there are NO BLANK LINES in the Manifest file BEFORE the end of the lines that should be processed. In Rails 3.2 the default file says that explicitly but if you are creating your own that is an easy thing to overlook.&lt;br /&gt;&lt;br /&gt;2: Look at the 4 lines shown above. The first two are 'require', followed by a SPACE and then the name of the javascript file.&lt;br /&gt;&lt;br /&gt;The Third is 'require_self' - underscore, no space - that means process any JS code in this file.&lt;br /&gt;The Fourth is 'require_tree' - underscore, no space - and that means process ALL JS files in this directory.&lt;br /&gt;&lt;br /&gt;If you type these lines in and happen to use a space instead of the underscore then Sprockets will look for JS file called 'self' and 'tree' - and won't find them. So be very careful tying those in.&lt;br /&gt;&lt;br /&gt;3: The main problem was the require_tree line&lt;br /&gt;&lt;br /&gt;I have a number of JS files that are included as needed in certain views. At the top of each view page I specify those with a content_for block like this:&lt;br /&gt;&lt;pre class="brush: javascript"&gt;&amp;lt;% content_for :custom_javascript_includes do %&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;%= javascript_include_tag "raphael.js" %&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;%= javascript_include_tag "tabs_timeline_simple.js" %&amp;gt;&lt;br /&gt;&amp;lt;% end %&amp;gt;&lt;/pre&gt;and in my application.html file I have&lt;br /&gt;&lt;pre class="brush: javascript"&gt;&amp;nbsp; &amp;lt;%= javascript_include_tag "application" %&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;%= yield :custom_javascript_includes %&amp;gt;&lt;/pre&gt;&lt;br /&gt;That has worked just fine in the past and I kept all the custom JS files in the javascripts directory. But require_tree will load ALL of them on EVERY page. I assume that there are some variable/function names that are duplicated and/or conflicting and so with all that loaded, nothing worked.&lt;br /&gt;&lt;br /&gt;The solution is to get rid of the require_tree line completely.&lt;br /&gt;&lt;br /&gt;If I had JS files that should be included in each page then I would 'require' each of them explicitly. This is the same approach that Ryan Bates suggests for CSS files. It just gives you more flexibility.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/CraicComputingTechTips/~4/W_qgUcXzEN8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craiccomputing.blogspot.com/feeds/5179182982012507250/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7975027231082637331&amp;postID=5179182982012507250" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/5179182982012507250" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/5179182982012507250" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CraicComputingTechTips/~3/W_qgUcXzEN8/upgrading-from-rails-30-to-31-issues.html" title="Upgrading from Rails 3.0 to 3.1 - Issues with Javascripts" /><author><name>Robert Jones</name><uri>http://www.blogger.com/profile/07503053614730814672</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://craiccomputing.blogspot.com/2012/10/upgrading-from-rails-30-to-31-issues.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7975027231082637331.post-6384229142746439278</id><published>2012-10-24T17:00:00.000-07:00</published><updated>2012-10-24T17:01:09.396-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="Heroku" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="PostgreSQL" /><title type="text">Uploading contents of a PostgreSQL database to Heroku without db:push</title><content type="html">I just created a new Rails app on my local machine and want to deploy it to &lt;a href="http://heroku.com/"&gt;Heroku&lt;/a&gt;. I've done this before and the uploading of the code typically works great - and it did today.&lt;br /&gt;&lt;br /&gt;Then I wanted to upload the contents of a small PostgreSQL database to Heroku - and that's where I ran into issues.&lt;br /&gt;&lt;br /&gt;Heroku has recently switched from a Heroku gem to &lt;a href="https://toolbelt.heroku.com/"&gt;Heroku Toolbelt&lt;/a&gt;&amp;nbsp;which I installed onto my Mac OS X machine.&lt;br /&gt;&lt;br /&gt;I should be able to run 'heroku db:push' from my Rails app and the data would get moved over using the &lt;a href="https://github.com/ricardochimal"&gt;taps&lt;/a&gt;&amp;nbsp;gem. But it failed with this error:&lt;br /&gt;&lt;pre class="brush: shell"&gt;$ heroku db:push&lt;br /&gt;! Taps Load Error: cannot load such file -- taps/operation&lt;br /&gt;! You may need to install or update the taps gem to use db commands.&lt;br /&gt;! On most systems this will be:&lt;br /&gt;!&lt;br /&gt;! sudo gem install taps&lt;/pre&gt; I have taps installed, so what is going on? Well, I'm not sure but I run my rubies under &lt;a href="https://github.com/sstephenson/rbenv"&gt;rbenv&lt;/a&gt;&amp;nbsp;which allows you to manage multiple versions - and Heroku's client doesn't seem able to figure out where the gems are located with rbenv.&lt;br /&gt;&lt;br /&gt;I dug around in /usr/local/heroku and hacked&amp;nbsp;/usr/local/heroku/lib/heroku/command/db.rb to tell me what it thought the load path for ruby gems was, using this line:&lt;br /&gt;&lt;pre class="brush: ruby"&gt;STDERR.puts "DEBUG: load path &amp;nbsp;#{$:}"&lt;/pre&gt; The paths given in that were all in&amp;nbsp;/usr/local/heroku/vendor/gems and my gem paths were nowhere to be found. I tried installing the taps, sqlite3 and sequel gems to that directory and I was able to get a bit further but I still couldn't get all the way - so I gave up on that path.&lt;br /&gt;&lt;br /&gt;And then I found mention of a page on Heroku's site that deals with the &lt;a href="https://devcenter.heroku.com/articles/pgbackups"&gt;pgbackups addon&lt;/a&gt;. Part of that describes how to import from a PostgreSQL backup directly, without having to use the heroku clients or taps.&lt;br /&gt;&lt;br /&gt;I followed that and it worked great - here are the steps involved. Your starting data must be in PostgreSQL and you need to have an account on Amazon S3 (and know how to use it)&lt;br /&gt;&lt;br /&gt;1: On your machine create a backup of your PostgreSQL database - 'mydb' is your database name and 'myuser' is your database user.&lt;br /&gt;&lt;pre class="brush: shell"&gt;$ pg_dump -Fc --no-acl --no-owner -h localhost -U myuser mydatabase &amp;gt; mydb.dump&lt;/pre&gt; 2: Transfer that to an Amazon S3 bucket and either make it world readable or set a temporary access url.&lt;br /&gt;&lt;br /&gt;3: Check that you can get the file back out of S3 using curl&lt;br /&gt;&lt;pre class="brush: shell"&gt;$&amp;nbsp;curl 'https://s3.amazonaws.com/mybucket/mydb.dump' &amp;gt; tmp&lt;br /&gt;$ ls -l tmp&lt;/pre&gt; 4: Enable the pgbackups addon in Heroku&lt;br /&gt;&lt;pre class="brush: shell"&gt;$ heroku addons:add pgbackups&lt;/pre&gt; 5: Get the name of the Heroku database that you will restore to, by capturing a backup from the empty heroku db:&lt;br /&gt;&lt;pre class="brush: shell"&gt;$ heroku pgbackups:capture&lt;br /&gt;&lt;br /&gt;HEROKU_POSTGRESQL_CRIMSON_URL (DATABASE_URL) &amp;nbsp;----backup---&amp;gt; &amp;nbsp;b001&lt;br /&gt;&lt;br /&gt;Capturing... done&lt;br /&gt;Storing... done&lt;/pre&gt; &lt;div&gt;6: Restore to that database from the S3 URL&lt;/div&gt;&lt;pre class="brush: shell"&gt;$ heroku pgbackups:restore HEROKU_POSTGRESQL_CRIMSON_URL 'https://s3.amazonaws.com/mybucket/mydb.dump'&lt;/pre&gt; &lt;div&gt;7: Test it out - my app was already up so I just had to browse to the appropriate page and there were all my records.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;8: Remove your S3 file&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;DONE !&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/CraicComputingTechTips/~4/1oxTYZYaE-I" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craiccomputing.blogspot.com/feeds/6384229142746439278/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7975027231082637331&amp;postID=6384229142746439278" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/6384229142746439278" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/6384229142746439278" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CraicComputingTechTips/~3/1oxTYZYaE-I/uploading-contents-of-postgresql.html" title="Uploading contents of a PostgreSQL database to Heroku without db:push" /><author><name>Robert Jones</name><uri>http://www.blogger.com/profile/07503053614730814672</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://craiccomputing.blogspot.com/2012/10/uploading-contents-of-postgresql.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7975027231082637331.post-4747351280468677382</id><published>2012-09-27T16:11:00.001-07:00</published><updated>2012-09-27T16:11:10.827-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Rails 3" /><category scheme="http://www.blogger.com/atom/ns#" term="model" /><title type="text">Rails 3 - New Model is not recognized </title><content type="html">I created a new Model in a Rails 3 application, along with a database table - but because I was not creating a controller or views I did not use a rails generator and just created the file by hand.&lt;br /&gt;&lt;br /&gt;The contents followed exactly the format of other Model files and I was careful to use a Plural name for &amp;nbsp;the database table and a Singular name for the model class.&lt;br /&gt;&lt;br /&gt;But when I ran the application, either in the console or as a server, I kept getting an error reporting the &amp;nbsp;Model name as an 'uninitialized constant'.&lt;br /&gt;&lt;br /&gt;I double and triple checked everything but no luck getting it to work. Poking around the web I found mention of the Lazy Loading feature in Rails whereby classes are not loaded until they are needed.&lt;br /&gt;&lt;br /&gt;Along with that was mention that using the command 'Rails.application.eager_load!' in the console might solve the problem. indeed it did - but only in&amp;nbsp;the Rails console...&lt;br /&gt;&lt;br /&gt;The problem turned out to be that the model FILE name was PLURAL. The Model class itself was singular - which is correct - but the lazy loading mechanism was using this (I assume) to define the filename in which to find the Model. Because my was plural it could not find the file and because it did not find a model it assumed that my Model name was a constant and then found that to be uninitialized.&lt;br /&gt;&lt;br /&gt;It's a confusing error message and I wonder if there might be a way for Rails to figure out that I wanted a model. But I figure this is a side effect of the Rails machinery for inferring model, controller, etc. names.&lt;br /&gt;&lt;br /&gt;Ah well... live and learn...&lt;br /&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/CraicComputingTechTips/~4/GubwMO7VxzU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craiccomputing.blogspot.com/feeds/4747351280468677382/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7975027231082637331&amp;postID=4747351280468677382" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/4747351280468677382" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/4747351280468677382" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CraicComputingTechTips/~3/GubwMO7VxzU/rails-3-new-model-is-not-recognized.html" title="Rails 3 - New Model is not recognized " /><author><name>Robert Jones</name><uri>http://www.blogger.com/profile/07503053614730814672</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://craiccomputing.blogspot.com/2012/09/rails-3-new-model-is-not-recognized.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7975027231082637331.post-5183376093753881641</id><published>2012-09-20T13:46:00.000-07:00</published><updated>2012-09-20T13:46:10.071-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="autoupdate" /><category scheme="http://www.blogger.com/atom/ns#" term="microsoft" /><title type="text">Microsoft AutoUpdate doesn't...</title><content type="html">I got this message when I started up MS Word on my Mac this morning:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-qJPrqL6ppGo/UFt_1uG_3eI/AAAAAAAAABE/WAbWB876P_I/s1600/update_message.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="62" src="http://1.bp.blogspot.com/-qJPrqL6ppGo/UFt_1uG_3eI/AAAAAAAAABE/WAbWB876P_I/s400/update_message.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;In other words, Microsoft AutoUpdate does not auto update... &amp;nbsp;:^{&lt;br /&gt;&lt;br /&gt;Compare that to the Google Chrome web browser which auto updates itself without requiring any action from myself and without requiring a browser restart.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/CraicComputingTechTips/~4/sOC1gXQCW1g" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craiccomputing.blogspot.com/feeds/5183376093753881641/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7975027231082637331&amp;postID=5183376093753881641" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/5183376093753881641" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/5183376093753881641" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CraicComputingTechTips/~3/sOC1gXQCW1g/microsoft-autoupdate-doesnt.html" title="Microsoft AutoUpdate doesn't..." /><author><name>Robert Jones</name><uri>http://www.blogger.com/profile/07503053614730814672</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-qJPrqL6ppGo/UFt_1uG_3eI/AAAAAAAAABE/WAbWB876P_I/s72-c/update_message.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://craiccomputing.blogspot.com/2012/09/microsoft-autoupdate-doesnt.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7975027231082637331.post-8256856713203067150</id><published>2012-08-27T13:37:00.002-07:00</published><updated>2012-08-27T13:37:53.703-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="csv" /><category scheme="http://www.blogger.com/atom/ns#" term="excel" /><title type="text">Preventing Excel from wrongly interpreting Strings in CSV files as Exponential numbers</title><content type="html">MS Excel and Apple Numbers both attempt to guess the format of the contents of each cell when they open up a CSV file. Most of the time this is fine but in some cases it causes a big problem.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you have a string with numbers and the letter E then both programs will treat this as a number in exponential notation.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For example, the string 229E10 will be converted to 2.29E+12&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What makes it worse is that you cannot change it back to the original text using the cell format options.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I run into this problem with strings that represent microtiter plate and well assignments. For example, 229E10 refers to plate 229 row E column 10.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I just want the spreadsheet program to take what I give it as text. Putting the string in single or double quotes can work but then the value remains in quotes in the spreadsheet.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The best way to do this seems to be to use double quotes around the string AND prefix that with an equals sign - like this:&lt;/div&gt;&lt;div&gt;="229E10"&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For reasons that I do not understand, Excel will strip the extra formatting off the string and treat the contents as plain text. This also works for arbitrary strings, such as ="ABC"&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CraicComputingTechTips/~4/BoUgJD9wGrw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craiccomputing.blogspot.com/feeds/8256856713203067150/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7975027231082637331&amp;postID=8256856713203067150" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/8256856713203067150" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/8256856713203067150" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CraicComputingTechTips/~3/BoUgJD9wGrw/preventing-excel-from-wrongly.html" title="Preventing Excel from wrongly interpreting Strings in CSV files as Exponential numbers" /><author><name>Robert Jones</name><uri>http://www.blogger.com/profile/07503053614730814672</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://craiccomputing.blogspot.com/2012/08/preventing-excel-from-wrongly.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7975027231082637331.post-1363077181103145533</id><published>2012-08-14T15:50:00.001-07:00</published><updated>2012-08-14T15:50:29.137-07:00</updated><title type="text">Installing OpenCV Ruby gem on mac OS X</title><content type="html">In my previous post I showed how to &lt;a href="http://craiccomputing.blogspot.com/2012/08/installing-opencv-library-on-mac-os-x.html"&gt;Install the OpenCV computer vision library on Mac OS X Lion&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I want to use the Ruby interface to the library and of the various project forks I went with&amp;nbsp;&lt;a href="https://github.com/ruby-opencv/ruby-opencv"&gt;https://github.com/ruby-opencv/ruby-opencv&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The github page has several alternate ways to install the interface, but installing it as a gem is the most mainstream. Even so, you need to do a bit more work than usual. First create an install directory for the 'raw' gem and clone it from github: &lt;br /&gt;&lt;pre class="brush: shell"&gt;$ mkdir opencv_install&lt;br /&gt;$ cd opencv_install/&lt;br /&gt;$ git clone git://github.com/ruby-opencv/ruby-opencv.git&lt;br /&gt;$ cd ruby-opencv/&lt;br /&gt;$ git checkout master&lt;br /&gt;$ bundle install&lt;br /&gt;$ rake gem&lt;br /&gt;$ gem install pkg/opencv-*.gem -- --with-opencv-dir=/usr/local/Cellar/opencv/2.4.2&lt;/pre&gt;Your opencv directory may not be identical to mine but this is where homebrew should place it.  For me, that was all I needed to do before copying the examples from the github page and trying things out !  Here is my version of the basic image display program: &lt;br /&gt;&lt;pre class="brush: ruby"&gt;#!/usr/bin/env ruby&lt;br /&gt;require "opencv"&lt;br /&gt;abort "Usage: #{$0} &lt;img file="file" /&gt;" unless ARGV.length == 1&lt;br /&gt;image = OpenCV::IplImage.load(ARGV[0])&lt;br /&gt;window = OpenCV::GUI::Window.new("preview")&lt;br /&gt;window.show(image)&lt;br /&gt;OpenCV::GUI::wait_key&lt;/pre&gt;When you run the script with an image file, you can quit by typing 'q' in the resulting image window.  Now for the fun stuff. Here is my version of the github page face detection script. Face detection uses 'haarcascade' classifier files which live in your OpenCV library directory. With my Homebrew installation these are found in &lt;span style="font-family: Courier New, Courier, monospace;"&gt;/usr/local/Cellar/opencv/2.4.2/share/OpenCV/haarcascades&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Get yourself an image file with a few faces (looking directly at the camera) to test it on. &lt;br /&gt;&lt;pre class="brush: ruby"&gt;#!/usr/bin/env ruby&lt;br /&gt;require "opencv"&lt;br /&gt;abort "Usage: #{$0} source_image_file  dest_image_file" unless ARGV.length == 2&lt;br /&gt;classifiers_dir = "/usr/local/Cellar/opencv/2.4.2/share/OpenCV/haarcascades"&lt;br /&gt;data = File.join(classifiers_dir, "haarcascade_frontalface_alt.xml")&lt;br /&gt;detector = OpenCV::CvHaarClassifierCascade::load(data)&lt;br /&gt;image = OpenCV::IplImage.load(ARGV[0])&lt;br /&gt;detector.detect_objects(image).each do |region|&lt;br /&gt;  color = OpenCV::CvColor::Red&lt;br /&gt;  image.rectangle! region.top_left, region.bottom_right, :color =&amp;gt; color&lt;br /&gt;end&lt;br /&gt;image.save_image(ARGV[1])&lt;/pre&gt;Make the file executable, run the script and then view the output file &lt;br /&gt;&lt;pre class="brush: ruby"&gt;$ chmod a+x findface.rb&lt;br /&gt;$ ./findface.rb smiths.jpg output.jpg&lt;br /&gt;$ open output.jpg&lt;/pre&gt;And you should something along the lines of this:&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-QpmUv0tfb3E/UCrVVQZ969I/AAAAAAAAAA0/JMLh-mEHqBQ/s1600/out.jpg" imageanchor="1"&gt;&lt;img border="0" height="184" src="http://3.bp.blogspot.com/-QpmUv0tfb3E/UCrVVQZ969I/AAAAAAAAAA0/JMLh-mEHqBQ/s320/out.jpg" width="273" /&gt;&lt;/a&gt;&lt;br /&gt;Pretty amazing, if you ask me - Not perfect but three out of four ain't bad !  &lt;br /&gt;Now on to some real experiments with &lt;a href="http://opencv.willowgarage.com/wiki/Welcome"&gt;OpenCV&lt;/a&gt; - I can't wait... &lt;br /&gt;&amp;nbsp; &lt;img src="http://feeds.feedburner.com/~r/CraicComputingTechTips/~4/3hryZmvQJgE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craiccomputing.blogspot.com/feeds/1363077181103145533/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7975027231082637331&amp;postID=1363077181103145533" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/1363077181103145533" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/1363077181103145533" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CraicComputingTechTips/~3/3hryZmvQJgE/installing-opencv-ruby-gem-on-mac-os-x.html" title="Installing OpenCV Ruby gem on mac OS X" /><author><name>Robert Jones</name><uri>http://www.blogger.com/profile/07503053614730814672</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-QpmUv0tfb3E/UCrVVQZ969I/AAAAAAAAAA0/JMLh-mEHqBQ/s72-c/out.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://craiccomputing.blogspot.com/2012/08/installing-opencv-ruby-gem-on-mac-os-x.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7975027231082637331.post-6129269694354754989</id><published>2012-08-14T14:57:00.000-07:00</published><updated>2012-08-14T14:57:32.053-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="mac os x" /><category scheme="http://www.blogger.com/atom/ns#" term="numpy" /><category scheme="http://www.blogger.com/atom/ns#" term="opencv" /><title type="text">Installing the OpenCV library on Mac OS X Lion using Homebrew</title><content type="html">&lt;a href="http://opencv.willowgarage.com/wiki/Welcome"&gt;OpenCV (Open Source Computer Vision)&lt;/a&gt; is a remarkable library of functions for real time computer vision.&lt;br /&gt;&lt;br /&gt;I'm interested in using it on to recognize buildings in satellite/aerial photographs - I'll explain more if I get the idea to work.&lt;br /&gt;&lt;br /&gt;The first step is to get OpenCV up and running on my Mac (OS X Lion 10.7.4). The library has a lot of dependencies that need to be installed but thankfully there is a &lt;a href="http://mxcl.github.com/homebrew/"&gt;Homebrew&lt;/a&gt; recipe for doing all of the heavy lifting... almost... I ran into a few problems but here is what I needed to do.&lt;br /&gt;&lt;br /&gt;In principle all you need is:&lt;br /&gt;&lt;pre class="brush: shell"&gt;$ brew update&lt;br /&gt;$ brew install opencv&lt;/pre&gt;But I got two errors:&lt;br /&gt;1: brew wanted me to update my version of Xcode from 4.2 to 4.3&lt;br /&gt;On Lion you update Xcode via the App store and it turns out that 4.4 is available. So I installed that and reran 'brew install opencv'&lt;br /&gt;2: brew then complained that the Python package &lt;a href="http://numpy.scipy.org/"&gt;'numby' (Numerical Python)&lt;/a&gt; was not installed. Brew does not install Python dependencies but suggested that I do this with:&lt;br /&gt;&lt;pre class="brush: shell"&gt;$ easy_install numby&lt;/pre&gt;I did that but I still got the error.&lt;br /&gt;&lt;br /&gt;I've got two versions of python installed (via homebrew)&lt;br /&gt;&lt;pre class="brush: shell"&gt;$ python --version&lt;br /&gt;Python 2.7.3&lt;br /&gt;$ python3 --version&lt;br /&gt;Python 3.2.3&lt;/pre&gt;For our purposes you only want to deal with Python 2 - version 3 should work but the homebrew package seems to want version 2&lt;br /&gt;&lt;br /&gt;Given the problem with easy_install, I went with a manual installation&lt;br /&gt;1: Download the tar file for the latest stable version of numby&lt;br /&gt;&lt;a href="http://sourceforge.net/projects/numpy/files/NumPy/1.6.2/"&gt;http://sourceforge.net/projects/numpy/files/NumPy/1.6.2/&lt;/a&gt;&lt;br /&gt;2: Unpack the file into a temporary directory and cd into it&lt;br /&gt;3: Run the python setup script&lt;br /&gt;&lt;pre class="brush: shell"&gt;$ python setup.py install&lt;/pre&gt;Sit back and relax as this takes a while. Everything went smoothly for me and hopefully for you too.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;All being well you can now run  &lt;br /&gt;&lt;pre class="brush: shell"&gt;$ brew install opencv&lt;/pre&gt;Again this takes a while - about 9 minutes on my box. You will get a message at the end of the output telling you to add the following to your .bash_profile &lt;br /&gt;&lt;pre class="brush: shell"&gt;export PYTHONPATH="/usr/local/lib/python2.7/site-packages:$PYTHONPATH"&lt;/pre&gt;OpenCV has an excellent interface to Python, but I work primarily in Ruby so the next step for me is to get an OpenCV ruby gem set up and start to do some image processing. The next post on this blog will cover that.  &lt;img src="http://feeds.feedburner.com/~r/CraicComputingTechTips/~4/3yvw6SyJg5E" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craiccomputing.blogspot.com/feeds/6129269694354754989/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7975027231082637331&amp;postID=6129269694354754989" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/6129269694354754989" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7975027231082637331/posts/default/6129269694354754989" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CraicComputingTechTips/~3/3yvw6SyJg5E/installing-opencv-library-on-mac-os-x.html" title="Installing the OpenCV library on Mac OS X Lion using Homebrew" /><author><name>Robert Jones</name><uri>http://www.blogger.com/profile/07503053614730814672</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://craiccomputing.blogspot.com/2012/08/installing-opencv-library-on-mac-os-x.html</feedburner:origLink></entry></feed>
