Monday, 2 July 2012

Starting my next project

I have completed part 1 of 4 of my project. But before I start part 2, I want to make sure that from now on, I know exactly when my app is down, since they will be all deployed on the cloud (and I have no idea if the cloud is happy or sad). Therefore I'm going to build http://www.404hound.com. The idea is simple -- use a screen scraping tool every X minute to look for certain keywords which would indicate that the site is up. If it isn't, then I will send a message to the site owner.

I'm going to do this on Node because I think it'll be great for this kind of app and I think Javascript is cool. I have my libraries picked out:

- Node.js / Express (for serving)
- Node.io (for screen scraping)
- Jade (for rendering templates)
- ampq (for messaging)
- node_mailer (for emailing using SendGrid)

Stay tuned for all the experiences I'll have with node =)

Saturday, 30 June 2012

JQuery $.on() function and the 'click' handler

So I am using the $.on() function to assign the 'click' event to one of my buttons, and on certain browsers things worked well, but on Firefox there was a problem, specifically the button would refresh.
My original code:


      self.init = function() { 
           $('.search-btn').on('click', function() {
                var searchTerm = $('#searchTerm').val();
                self.doSearch(searchTerm);
           });
      };  


It turns out it was a mistake I made by not returning a value from the annoymous function, so it would stop flow of execution.



      self.init = function() { 
           $('.search-btn').on('click', function() {
                var searchTerm = $('#searchTerm').val();
                self.doSearch(searchTerm);
                return false;
           });
      };  


Monday, 25 June 2012

oauth twitter plugin grails problem with production

My production app is deployed via cloudfoundry, so I get a url like myapp.cloudfoundry.com. However, I wanted my main domain, myapp.com to forward to that domain. Everything worked initially until the point where it forwards the user to sign in with twitter. All I got was a blank page. Turned out that I need to set the production environment variables in Datasource.groovy like so:

production {
  ...
grails.serverURL = "http://www.myapp.com/" //needed b/c of spring security and url createlinks
grails.app.context = "/"
  ...
}

get app context in grails view

I have a custom link that I need to render so the search engines can index the search terms more effectively. Specifically, I wanted to generate something like this:

http://mytestdomain.local:8080/tweetcommendation/review/business-name/1_Informotion%20Software_Vancouver,%20BC

However, I found that I couldn't do this using createLink, because it only had the concept of controller / action mapping, and my /review/business-name/${businessName} is not mapped to a controller (it's just defined in DataSource.groovy).

Originally, I had something like this:
${request.contextPath}/review/business-name/${it.id}_${it.name}_${it.location}

That way works. However, I actually found a cleaner solution that I thought I'd share:

${resource(file: "review/business-name/${it.id}_${it.name}_${it.location}")}

Sunday, 24 June 2012

Grails app on cloudfondry: Caused by: java.lang.OutOfMemoryError: PermGen space

So I was deploying my app to production (yay) on cloud foundry today. The deployment was successful, but then the system would crap out whenever I goto any of the pages:

504 Gateway Time-out nginx

I checked the logs:

vmc log

...and it appeared to be a permgen issue:

Caused by: java.lang.OutOfMemoryError: PermGen space



To solve it, type this in:

vmc env-add tweetcommendation "JAVA_OPTS=-XX:MaxPermSize=512m"

 To check that you have correctly set the value:

me@tommy:~/repo/tweetcommendation/target$ vmc env tweetcommendation

+-----------+----------------------+
| Variable  | Value                |
+-----------+----------------------+
| JAVA_OPTS | -XX:MaxPermSize=512m |
+-----------+----------------------+

Friday, 22 June 2012

Grails - Twitter Bootstrap with the resources plugin stops working

I was mucking around last night with the intention of making my resources load more efficiently, and all of a sudden my Twitter Bootstrap enabled  drop downs are no longer working. This was what I had in my declaration initially (after I was mucking around):



 modules = { 

      core { 

           dependsOn 'jquery, jquery-ui, jquery-theme, bootstrap, utils'  

           resource url: '/js/spin.js', disposition: 'head' 

           resource url: '/js/jquery.spin.js', disposition: 'head' 

           resource url: '/js/bootstrap.min.js', disposition: 'head' 

      } 

}


It turned out that was a really bad mistake, as the bootstrap module already declares a bootstrap.js. By re declaring the dependency elsewhere, you get into weirdness with some of the bootstrap plugins not working the way it should, in my case the dropdowns.




Tuesday, 19 June 2012

Shorten urls using the bit.ly api without using oauth

There is a poorly documented feature of bit.ly, and that is using their shortening url without using oauth, as long as you're fine with stats being posted to your account (which is what you want in most cases when shortening urls anyways).

In their api for shorten (located @ http://dev.bitly.com/links.html#v3_shorten), it appears that it only accepts an oauth access_token.

However, there is a small blurb on another page allow the user to use the parameters apiKey and login. Just goto http://bitly.com/a/your_api_key and you will see your login and apiKey information. Use these two parameters instead of the access_token, and then you'll be in business.

So an example would look like this:


/v3/shorten?apiKey=blah&login=blah&longUrl=http%3A%2F%2Fgoogle.com%2F

Hope that saves someone the ten minutes I took to figure it out!