Heroku on Windows 7

heroku, programming, Windows

Prerequisites

Git installed and on PATH

Installation

Sign up for a Heroku account.  Note the user email address and password.

Download and install the Heroku Toolbelt. (see https://devcenter.heroku.com/articles/quickstart)

Even if you have your own version of Ruby, it’s better to have the Heroku Toolbelt install its own copy (default behavior).  Normally it will be installed in the “ruby-1.9.3” (may be different as new versions are used by the time you read this) subdirectory which is sibling of “bin” and “data”.

Make sure heroku.exe is on the PATH:

C:devprojects>heroku version
heroku/toolbelt/3.10.1 (i386-mingw32) ruby/1.9.3

Run “heroku login” to generate a key-pair under %HOMEPATH%.ssh

Project setup

Create a git project (either via “git clone” or “git init“).

CD to your project root and run “heroku create” to setup Heroku and add the hooks into your project.

Follow instructions on how to set up your app’s auxiliary files, such as adding a “Procfile” file to your project root and adding properties files.

Project deployment

Deployment is normally done simply by running “git push heroku master” to push your code up into Heroku’s Git repo (that was set up by “heroku create” earlier).

One possible error at this point is:

C:devprojectsherokuruby-sample>git push heroku master
Permission denied (publickey).
fatal: Could not read from remote repository.

I found that git looks at %HOME%/.ssh for SSH key files, but normally %HOME% isn’t set.  So modify your environment variables to add this setting:

set HOME=%HOMEPATH%

After the above, “git push” should work.  If not, then there may be a discrepancy between the %%HOME%.sshid_rsa and %HOMEPATH%.sshid_rsa.pub files and what the SSH keys settings are in your Heroku account.

 

Grails’s RESTClient

Grails, groovy, programming

The groovy.net.http.RESTClient class is a subclass of a more general groovyx.net.http.HttpBuilder class and comes with the “rest” plugin (http://grails.org/plugin/rest).

GET

A simple GET request with query parameters:

def rest = new RESTClient('http://www.my.com')
try {
// equivalent to: http://www.my.com/abc/123?param1=p1&param2=p2&param3=p3a&param3=p3b
def response = rest.get([
path:'/abc/123',
contentType:'application/json',
query:[param1:'p1', param2:'p2', param3:['p3a','p3b']])

// Assuming the server respects Content-Type and returns a JSON,
// the follow will provide the JSONObject or JSONArray
// for the returned results
def json = response.data
...
} catch (HttpResponseException ex) {
// errors and response status codes >= 400 end up here
}

POST

A sample for POSTing data w/ JSON

def rest = new RESTClient('http://www.my.com')
try {
// equivalent to: POST http://www.my.com/abc/123 with body of '{"param1": 1, "param2": "2"}'
def response = rest.post(path:'/abc/123',
contentType:'application/json',
body: [param1: 1, param2: "2"])
json = response.data
} catch (HttpResponseException ex) {
...
}

groovy.net.http.HttpBuilder uses the RequestConfigDelegate class to parse the map provided to get() and post(). The map supports these keys:

  • uri — used to specify the complete URL for the request, excluding the query component.  If used with path, then this should be the base URL. This value overrides the value passed to the ctor of RESTClient
  • query — used to specify a map of values representing the query parameters.  Lists are supported (see the GET example above).
  • path — used in conjunction with uri if you want to separate the path and base components of a URL.
  • contentType — the Content-Type to use and accept (either a String literal such as ‘application/json’ or a groovyx.net.http.ContentType constant).
  • requestContentType — if the request body type is different than the response (Accepts) body type, then this value is used to specify the request’s content type.
  • body — the body of the request
  • headers — used to specify a map of headers for the request

No support for URL fragments (as of rest-0.8)

You will need to create a java.net.URI instance with the entire URL w/ query and fragment and pass it to the ctor of RESTClient.

Response

By default, get() and post() will return an instance of groovyx.net.http.HttpResponseDecorator.  Commonly used methods are isSuccess() and getData().

  • isSuccess() returns true if the HTTP status code is < 400.
  • getData() will return the parsed body, and the type depends on the contentType used for the get() or post() method.

 

Debugging Rails 3 in (Aptana 3.4.2, Windows 7)

programming, rails

More Rails stuff.

I was using command line & vim to do some Rails stuff until fingers got tired of switching between files.

So I did a some searches and came up with a short list of IDEs for Rails and tried installing Aptana (currently 3.4.2).

As expected, problems came up despite having:

  1. Installed git, (on top of ruby/rails/gem)
  2. Made sure all these are accessible from the Command Prompt
  3. Installed ruby-debug-base 0.10.4 gem
  4. Installed ruby-debug-ide 0.4.22 gem

The error in the Console was:

Fast Debugger (ruby-debug-ide 0.4.22, ruby-debug-base 0.10.4) listens on 127.0.0.1:49946
=> Booting WEBrick
=> Rails 3.0.3 application starting in development on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
9632: Exception in DebugThread loop: wrong number of arguments (0 for 1)
Backtrace:
c:/dev/tools/ruby187/lib/ruby/gems/1.8/gems/ruby-debug-ide-0.4.22/lib/ruby-debug-ide/ide_processor.rb:84:in `read_command'
from: c:/dev/tools/ruby187/lib/ruby/gems/1.8/gems/ruby-debug-ide-0.4.22/lib/ruby-debug-ide/ide_processor.rb:84:in `process_commands'
from: c:/dev/tools/ruby187/lib/ruby/gems/1.8/gems/ruby-debug-ide-0.4.22/lib/ruby-debug-ide.rb:122:in `start_control'
from: c:/dev/tools/ruby187/lib/ruby/gems/1.8/gems/ruby-debug-ide-0.4.22/lib/ruby-debug-ide.rb:103:in `initialize'
from: c:/dev/tools/ruby187/lib/ruby/gems/1.8/gems/ruby-debug-ide-0.4.22/lib/ruby-debug-ide.rb:103:in `new'
from: c:/dev/tools/ruby187/lib/ruby/gems/1.8/gems/ruby-debug-ide-0.4.22/lib/ruby-debug-ide.rb:103:in `start_control'
from: c:/dev/tools/ruby187/lib/ruby/gems/1.8/gems/ruby-debug-ide-0.4.22/lib/ruby-debug-ide.rb:65:in `start_server'
from: c:/dev/tools/ruby187/lib/ruby/gems/1.8/gems/ruby-debug-ide-0.4.22/lib/ruby-debug-ide.rb:69:in Exiting
`prepare_debugger'
from: c:/dev/tools/ruby187/lib/ruby/gems/1.8/gems/ruby-debug-ide-0.4.22/lib/ruby-debug-ide.rb:83:in `debug_program'
from: c:/dev/tools/ruby187/lib/ruby/gems/1.8/gems/ruby-debug-ide-0.4.22/bin/rdebug-ide:110
from: c:/dev/tools/ruby187/bin/rdebug-ide:23:in `load'
from: c:/dev/tools/ruby187/bin/rdebug-ide:23

The main problem is: 9632: Exception in DebugThread loop: wrong number of arguments (0 for 1)

Did some search and turned out I HAD to remove the ruby-debug gem from my app’s Gemfile:

# To use debugger (ruby-debug for Ruby 1.8.7+, ruby-debug19 for Ruby 1.9.2+)
# gem ‘ruby-debug’
# gem ‘ruby-debug19’

After commenting out that line above, reran bundle-install on the app, the debugger was working fine.

Rails w/ MySQL (Windows 7-64)

mysql, programming, rails

Mainly notes on setting up the following (suitable for Dreamhost’s Rails setup):

  • Ruby 1.8.7-p374
  • Rails 3.0.3
  • Ruby devkit  (from http://rubyinstaller.org/downloads/)
  • MySQL Installer 5.6.17 Community Server 64-bit
  • mysql2 GEM ‘0.2.22’

Install Ruby 1.8.7 by going to: http://rubyinstaller.org/downloads/

Install Rails 3.0.3 by: gem install rails -v 3.0.3

Latest MySQL: http://dev.mysql.com/downloads/mysql/

mysql2 GEM:

  1. Get mysql-connector-c-6.1.3-win32.zip from http://dev.mysql.com/downloads/connector/c/. Unzip to C:devtools (or wherever).
  2. Run: gem install mysql2 -v '0.2.22' -- --with-mysql-dir="c:devtoolsmysql-connector-c-6.1.3-win32"  (Use whatever path you unzipped the connector above.)

Go to the Rails app and modify the GemFile:

...
gem 'mysql2', '0.2.22'
...

Run: bundle install

Copy c:devtoolsmysql-connector-c-6.1.3-win32liblibmysql.dll to %RUBY_HOME%bin

 

Developing with Moto X

android, mobile, Moto X, programming

Just recently upgraded from an Android 2.1 device (HTC Aria) to an Android 4.4 device (Moto X).

To enable the developer USB feature that allows installing and running (let alone debugging) programs, two things need to be done:

  • Install the Motorola USB drivers (https://motorola-global-portal.custhelp.com/app/answers/detail/a_id/88481/action/auth)
  • Enable the Developer feature on the phone:
    • Go to Settings
    • Scroll to the “About phone” option under the “SYSTEM” section and click the option 7 times (after clicking it 3-4 times you should see a message saying something like “you are X steps away from being a developer”)
    • After clicking it 7 times, you will “become a developer” and will then see a “{ } Developer options” entry under the “SYSTEM” section where you will be presented with a LOT more settings.

 

New home!

Uncategorized

THEREALVAN.COM has moved to a new home!  The previous hosting company had a good introductory rate, but the regular rate was too high for a relatively inactive site like this one.

The switch went smoother than I expected.  I exported the WordPress stuff from the old one and imported it here.  And that was that.  The font sizes were a bit off, and I had to hunt down the Syntax Highlighter plug-in that I used before.  But after about 30 minutes, the site is back up.

 

xml.MarkupBuilder in Groovy

groovy, programming

Typical use of the builder starts with:

import groovy.xml.MarkupBuilder

def writer = new StringWriter()
def xml = new MarkupBuilder(writer)

...

String generatedXml = writer.toString()

Then the “building” part is what’s not documented all that well.

Fundamentals

To get element and value:

xml.Outer("hello") 

Output:

<Outer>hello</Outer>

To add attributes, pass them as a map to the function:

xml.Outer(xmlns:'http://www.abc.com/blahblahblah')

Output:

<Outer xmlns:"http://www.abc.com/blahblahblah" />

To add children, add a closure in which to add more tags:

xml.Outer(xmlns:'http://www.abc.com/blahblahblah') {
   Inner("inner val")
}

Output:

<Outer xmlns:"http://www.abc.com/blahblahblah">
   <Inner>inner val</Inner>
</Outer>

Adding some attributes AND value to Inner:

xml.Outer(xmlns:'http://www.abc.com/blahblahblah') {
   Inner(id:"myId", "inner val")
}

Output:

<Outer xmlns:"http://www.abc.com/blahblahblah">
   <Inner id="myId">inner val</Inner>
</Outer>

NOTE how the Inner() call: it’s a Map followed by a String.

Loops

Turns out we can add code (such as loops) inside the closure:

xml.Outer(xmlns:'http://www.abc.com/blahblahblah') {
   Inner(id:"myId", "inner val")
   (1..5).each {i -> 
      MoreInner("innerChild ${i}")
   }
}

Output:

<Outer xmlns='http://www.abc.com/blahblahblah'>
  <Inner id='myId'>inner val</Inner>
  <MoreInner>innerChild 1</MoreInner>
  <MoreInner>innerChild 2</MoreInner>
  <MoreInner>innerChild 3</MoreInner>
  <MoreInner>innerChild 4</MoreInner>
  <MoreInner>innerChild 5</MoreInner>
</Outer>

Other than loops, more sophisticated code can be used. But that will complicate the code. Which brings us to functions.

Function calls

def addInnerChildren(builder) {
   builder.Inner(id:"myId", "inner val") {
      (1..5).each {i -> 
         MoreInner("innerChild ${i}")
      }
   }
}

xml.Outer(xmlns:'http://www.abc.com/blahblahblah') {
   addInnerChildren(xml)
}

Output:

<Outer xmlns='http://www.abc.com/blahblahblah'>
  <Inner id='myId'>inner val</Inner>
  <MoreInner>innerChild 1</MoreInner>
  <MoreInner>innerChild 2</MoreInner>
  <MoreInner>innerChild 3</MoreInner>
  <MoreInner>innerChild 4</MoreInner>
  <MoreInner>innerChild 5</MoreInner>
</Outer>

Prefix for namespace

It’s a bit cumbersome; we have to quote the “tag”:

xml.'hahaha:Outer'('xmlns:hahaha': 'http://www.abc.com/blahblahblah') {
   whatever('floats')
   'hahaha:your'('boat')
}

Output:

<hahaha:Outer xmlns:hahaha='http://www.abc.com/blahblahblah'>
  <whatever>floats</whatever>
  <hahaha:your>boat</hahaha:your>
</hahaha:Outer>

Dynamic tags

Finally, if we do not know the exact tag yet:

String tag = "hahaha"

...

xml."${tag}"(xmlns: 'http://www.abc.com/blahblahblah') {
   whatever('floats your boat')
}

Output:

<hahaha xmlns='http://www.abc.com/blahblahblah'>
  <whatever>floats your boat</whatever>
</hahaha>