Thursday, August 16, 2012

Blues

Last post in June. My Rails learning activity is totally stopped... Maybe to continue after I am done with my web service study.

Today, I learned about Blues. My teacher asked me, how are you going to explain Blues if someone ask. I said... err... I can only recall it's from the (黑人) Negros.. It's a way to express or sing about their life. That's all.

My teacher asked me to Google later, but she did explain the basic "technical" aspect of Blues. It's a 12-bar chord progression looping, and it takes only 3 chords.

||: I7 | I7  | I7 |  I7  |
 | IV7 | IV7 | I7 |  I7  |
 |  V  | IV7 | I7 | (V) :||

Writing this out making me feel like writing a code. :P

Found the wiki page for Blues. It's a long long page to be digested. :|

Tuesday, June 19, 2012

Extracting alternate items from an array in Perl

Hmm.. I forgot which web page I referred to, but this is a 2-liner code to extract the odd-th numbered items, or even-th numbered items in an array. :)




use Data::Dumper;$Data::Dumper::Indent = 3;


@array = ( 1, 2, 3, 4, 5, 6, 7 );


$flag = 0;
@oddth = grep {$flag ^= 1} @array;


print Dumper(\@oddth);
print "\n";


$flag = 1;
@eventh = grep {$flag ^= 1} @array;


print Dumper(\@eventh);
print "\n";



output :



Rails - to create a blog site Part 3 [basic validation]

By default, there is no validation on the input on the form that we have created. The validation code shall be put in the model file.

Oh, I just realize that I did not mention about MVC. MVC stand for Model-View-Controller. It is a kind of software pattern that separate the application into 3 components. The model is the application object, the controller defines the application interface, while the view defines the presentation. For more information, can go wiki to check it out. :)

The model file resides in <root directory>/app/models. For my example, the file is blog/app/models/test_j.rb.



The TestJ class is a sub class of ActiveRecord::Base. The attr_accessible is to specify what are the attributes can be updated.

I tried to remove the tag from the attr_accessible and try to create a new record, this is the error observed.



This is only experimental testing. I am not sure how this is to be done to have the error message displayed nicely instead of giving internal error. The best way I can figure out is, remove the input from create new page directly. :)

Back to the topic that I want to discuss here. Normally, in a form, we'll have required field. To validate the required field(s) has been filled, add the lines to validate the presence of the input. The length attribute controls the required length of the input of the field.



For length, you can specified :in, :is, :minimum or :maximum.

The application will have the default error message printed on the form if the validation failed.




More information about the validation, please visit http://guides.rubyonrails.org/active_record_validations_callbacks.html

Wednesday, May 30, 2012

Rails - to create a blog site Part 2

Creating a resource.

The format used is as follow :

$ rails generate scaffold <resource name> <list of fields>

Example :
$ rails generate scaffold test_j author:string title:string tag:string content:text create_datetime:timestamp


Create associated table in the database.

$ rake db:migrate

Then you are done! This new resource can be accessed by http://0.0.0.0:3000/<resource name>/

For the example that I used, it would be http://http://0.0.0.0:3000/test_js/


Click on the New Test_j link will give you the form that we created with the one line command earlier.


Note that, the date time is showing current GMT time. I haven't figured out why/how matters. :)


Rails - to create a blog site Part 1

Tutorial that I am following is from this site : http://guides.rubyonrails.org/getting_started.html


I choose to sudo as root to avoid the permission issue.
$ sudo su 

Install Ruby
$ apt-get install rubygems

Install Rails
$ gem install rails

Create a blog application
$ rails new blog

Note : You might encounter this error.
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension

To solve this, install sqlite before create the blog application.
$ apt-get install libsqlite3-dev
$ gem install sqlite3 -v '1.3.6'

Create a database
$ rake db:create

You might encounter this error.
rake aborted!
Could not find a JavaScript runtime. See https://github.com/sstephenson/execjs for a list of available runtimes.

Go to the created blog directory. Edit this file : Gemfile.
Uncomment this line :
gem 'therubyracer', :platform => :ruby
Run this (installing nodejs and also reinstall rails) :
$ apt-get install nodejs
$ bundle install

To start the web server
$ rails server

You can access the new project site at http://0.0.0.0:3000.


P/S : I am running on Ubuntu 12.04.

Thursday, March 22, 2012

Function prototyping in Perl

Today, I studied some old codes from year 2003. It has very weird Perl syntax which I have never seen before. I did some testing using the following code. Of course, I did try and error until I got what the $;$ means.

They are actually representing argument that is passing to the subroutine. One $ represent one argument. The ones before ; are required arguments, and the ones after the ; are optional arguments.

My colleague is smarter, she found this link online : http://perldoc.perl.org/perlsub.html#Prototypes. There are a lot more to learn in Perl!




use strict;

use Data::Dumper;
$Data::Dumper::Indent = 3;


sub sub0 () {
  print Dumper(@_);
}


sub subA ($;$) { 
  unshift @_, 'new from a';
  print Dumper(@_);
  goto &sub0;
}


sub subB () {
  subA("a", "b");
  subA("c");
}


subB();

1;

Wednesday, March 21, 2012

Blogger API - create a new post using JavaScript

I am a heavy Blogger user.I write blogs. I never thought of wanted to know Blogger API, but I do thought of get to know Google API. I am glad that my work gives me an opportunity to explore this, for work and for myself. :) 

I'd like to thank Brett Morgan and also those responded to Issue 42 in gdata-java​script-cli​ent. Without them, I won't be able to complete this piece of code. And also, not forgetting the original source code that provide me the baseline to start to work at available here.

This piece of code will do the Google account authentication and authorization process, it will then grab your blog list, and provide a simple form for you to select a blog, taking your new post entry's title and content, and then post it. I have tested on FF3.2.26, Safari 5, Chrome, and IE8. There'll be some prompts to proceed depends on the browser that you are using.

Some special handlings were happened during my weeks of getting this piece of code in place. I can only recall a few of them.
  1. You must include an image in your html file. However, I just put a <img> tag, but the image actually does not exist, works fine.
  2. I was testing using https://localhost. It worked fine for all browsers. However, during preparing the last version of code, after Issue 42 is resolved, it doesn't work on Safari anymore. It might due to Safari update, I didn't check this out.
  3. I spent most time on authentication and authorization. The original code doesn't work on my testing. It only work fine if pre-login to Google account. Found another login methodology which work perfectly for me, which you can check out on the source code below. :) 
Not forgetting, this documentation helps most on Google API. Here's my source code, too bad, I am not able to embed it in this blog post. :P


<!DOCTYPE html>
<html>
  <head>
    <meta charset='utf-8' />
    <script src="https://www.google.com/jsapi?key=<Your key>" type="text/javascript"></script>
    <script type="text/javascript">
     
      google.load("gdata", "1");
     
      // To enter one or more authentication scopes, refer to the documentation for the API.
      var scopes = 'http://www.blogger.com/feeds';
     
      var bloggerService;
      var targetBlog;
      var targetBlogTitle;

      function checkAuth() {
        google.gdata.client.init(handleError);
        var authorizeButton = document.getElementById('authorize-button');
        var blogEntryForm = document.getElementById('blogEntryForm');
        var myToken = google.accounts.user.checkLogin(scopes);
        bloggerService = new google.gdata.blogger.BloggerService('<your apps name>');
        if (google.accounts.user.checkLogin(scopes)) {
          authorizeButton.style.visibility = 'hidden';
          blogEntryForm.style.visibility = '';
          bloggerService.getBlogFeed('http://www.blogger.com/feeds/default/blogs', setupBlogList, handleError);
        }
        else {
          authorizeButton.style.visibility = '';
          blogEntryForm.style.visibility = 'hidden';
        }
      }
      google.setOnLoadCallback(checkAuth);


      function myLogin() {
        var authorizeButton = document.getElementById('authorize-button');
        authorizeButton.style.visibility = 'hidden';
        google.accounts.user.login(scopes);
      }

      function postIt() {
        if (document.forms['myForm'].elements['inputTitle'].value.length < 1) {
            alert ("Error : Please insert a title!");
            return false;
        }
        var FeedURI = document.forms['myForm'].elements['href'].value;
        bloggerService.getBlogPostFeed(FeedURI, insertMyEntry, handleError);
        return;
      }

    function setupBlogList(blogEntry) {
        var targetCombo = document.getElementById('combo');
        var options;
        var entries = blogEntry.feed.entry;
        for (entry in entries) {
            options += "<option value='" + entries[entry].getEntryPostLink().href + "'>" + entries[entry].getTitle().getText() + "</option>";
         }
        targetCombo.innerHTML = "<select name=href id=href>" + options + "</select>";
    }

    function insertMyEntry(myResultFeedRoot) {
      targetBlog = myResultFeedRoot.feed.getHtmlLink().href;
      targetBlogTitle = myResultFeedRoot.feed.getTitle().getText();
      var inputTitle = document.forms['myForm'].elements['inputTitle'].value;
      var inputText = document.forms['myForm'].elements['inputText'].value;
      var blogEntry = new google.gdata.blogger.PostEntry({
        title : {
            type: 'text',
            text: inputTitle
        },
        content: {
            type: 'text',
            text: inputText
        }
      });
      myResultFeedRoot.feed.insertEntry(blogEntry, handleMyInsertedEntry, handleError);
    }

    function handleMyInsertedEntry(postEntry) {
      alert('Successful insert a blog entry!! :D');
      window.open(postEntry.entry.getHtmlLink().href, postEntry.entry.getHtmlLink().title, target='_blank');
    }

    function handleError(e) {
      alert(e.cause ? e.cause.statusText : e.message);
    }

    </script>
  </head>
  <body>
    <script src="https://apis.google.com/js/client.js"></script>
    <input type=button value=Authorize id="authorize-button" style="visibility: hidden" onclick="myLogin()">
    <div id=blogEntryForm style="visibility: hidden">
    <form id=myForm>
        <table>
            <tr>
            <td>Select a blog...</td>
            <td id='combo'>
               
            </td>
            </tr>
            <tr>
            <td>Title</td>
            <td><input type=text id=inputTitle name=inputTitle size=32></td>
            </tr>
            <tr><td colspan=2>&nbsp;</td></tr>
            <tr>
            <td>Content</td>
            <td><textarea id=inputText name=inputText rows=6 cols=26></textarea></td>
            </tr>
            <tr><td colspan=2>&nbsp;</td></tr>
            <tr><td colspan=2><input type=button value=Submit onclick="postIt()"></td></tr>
        </table>
       
    </form>
    </div>


    <div id=hidethis style="visibility: hidden">
    <p>Maybe I should add in some text here to display....</p>
    <img src=a.png>
    </div>
  </body>
</html>

Thursday, March 15, 2012

git stash

To save a change without commit. This is to enable checkouts.


git stash save "Your comments"

To see the list of stashed changes.

git stash list

To apply the saved change.

git stash apply

To delete the stashed changes.

git stash clear


Reference : http://book.git-scm.com/4_stashing.html

Tuesday, March 13, 2012

Basic commands of git


1. To initialize and setup a git central repository
> git --bare init central_repo

2. To push to central repo from clone
> git push origin master

3. To check available branches
> git branch

4. To create a branch
> git checkout -b <branch name> origin/master
> git checkout -b <branch name> origin/<existing branch name>

5. To reset changes on branch
> git reset --hard <old branch name>


http://help.github.com/git-cheat-sheets/