Posts Tagged 'Ruby'

Dynamically Generating Embedded Google Calendars with GCal4Ruby

One of the great features of Google Calendar is the ability to embed a calendar view into any webpage using the <iframe> tag.  Google makes this especially simple by providing a great tool that allows you to choose formatting options, which calendar you want to display, color, etc.  This is great, however it only generates the static tag, and there is no easy way to dynamically produce the correct <iframe> tag.

With the latest release of GCal4Ruby, I’ve included three helper methods for producing a dynamically generated <iframe> tag on demand.  This is great for AJAX applications where you want to create your own user interface for the calendar, say to select different calendars to show in one combined calendar view.  GCal4Ruby makes this impressively easy:

service = Service.new()
service.authenticate('account', 'password')
cal = service.calendars.first
cal.to_iframe

Which outputs the following<iframe> tag:

<iframe src='http://www.google.com/calendar/embed?&amp;height=600&amp;bgcolor=%23FFFFFF&amp;width=600&amp;color=%232952A3&amp;src=iowacity1%40seabourneconsulting.com&amp;' style='0 px solid;' width='600' height='600' frameborder='0' scrolling='no'></iframe>

You also have the ability to specify all the standard formatting features using GCal4Ruby.  The following code produces a calendar with no navigation controls in the agenda view:

cal.to_iframe({:showTitle => false,
               :showNav => false,
               :showPrint => false,
               :showTabs => false,
               :showCalendars => false,
               :showTimezone => false,
               :viewMode => 'AGENDA'})

You can also include multiple calendars in one embedded view by using the Service#to_iframe method.  You can display all calendars in the service using the :all token, or you can pass an array of calendar ids:

cals = ['calendarid@gmail.com', '23209384lkjdf9lakdjd@gmail.com']
service.to_iframe(cals)

You can use the same options to choose which calendar elements to display.

Lastly, if you already know the calendar id, and don’t want to authenticate, you can use the to_iframe class method, which looks like this:

Calendar.to_iframe('calendar_id@gmail.com')

Using the class method means you don’t have to authenticate the service and create the calendar instance, which reduces latency by bypassing all communications with the Google Calendar API, as long as you know the Calendar ID ahead of time.

For more information, and all the options you can pass, check out the documentation.

New Ruby Google Calendar API Gem: GCal4Ruby

I’ve written a few previous posts about using the Google Calendar API with Ruby and Ruby on Rails, but I’ve wanted to create my own library that includes the functionality I’ve had to monkey patch into others’.  So, I’ve gone ahead and created GCal4Ruby, a full featured Google Calendar API wrapper for Ruby available as a Gem.  You can download the source here or with ’sudo gem install gcal4ruby’.  Some of the features:

  • Clean, ActiveRecord style syntax and code structure
  • Full querying of calendars and events
  • Full calendar creation, editing and deletion
  • Setting public/private permissions for calendars
  • Event creation/editing/deletion
  • Support for full event recurrence
  • Support for event reminders
  • Support for event attendees

All of the major features have been implemented, and over the next couple of days I hope to complete the smaller outstanding todos.  Any help testing is much appreciated.  Below are some example uses.  For more information, check out the documentation.

Get all calendars for an account

       service = Service.new
       service.authenticate("user@gmail.com", "password")
       calendars = service.calendars

Create a new Calendar

       cal = Calendar.new(service)

Find an existing Calendar

       cal = Calendar.find(service, "New Calendar", {:scope => :first})

Find all calendars containing the search term

       cal = Calendar.find(service, "Soccer Team")

Find a calendar by ID

       cal = Calendar.find(service, id)

Create a new Event

       event = Event.new(calendar)
       event.title = "Soccer Game"
       event.start = Time.parse("12-06-2009 at 12:30 PM")
       event.end = Time.parse("12-06-2009 at 1:30 PM")
       event.where = "Merry Playfields"
       event.save

Find an existing Event

       event = Event.find(cal, "Soccer Game", {:scope => :first})

Find all events containing the search term

       event = Event.find(cal, "Soccer Game")

Create a recurring event for every Saturday

       event = Event.new(calendar)
       event.title = "Baseball Game"
       event.where = "Municipal Stadium"
       event.recurrence = Recurrence.new
       event.recurrence.start = Time.parse("13-06-2009 at 4:30 PM")
       event.recurrence.end = Time.parse("13-06-2009 at 6:30 PM")
       event.recurrence.frequency = {"weekly" => ["SA"]}
       event.save

Create an event with a 15 minute email reminder

       event = Event.new(calendar)
       event.title = "Dinner with Kate"
       event.start = Time.parse("20-06-2009 at 5 pm")
       event.end = Time.parse("20-06-209 at 8 pm")
       event.where = "Luigi's"
       event.reminder = {:minutes => 15, :method => 'email'}
       event.save

Create an event with attendees

       event = Event.new(calendar)
       event.title = "Dinner with Kate"
       event.start = Time.parse("20-06-2009 at 5 pm")
       event.end = Time.parse("20-06-209 at 8 pm")
       event.attendees => {:name => "Kate", :email => "kate@gmail.com"}
       event.save

Creating a Ruby Gem

Ruby Gems are a the most common mechanism for extending the functionality of the Ruby language through plug-ins.  Similar to CPAN or PEAR, the Gem infrastructure allows users to download additional libraries from a central online repository and install it locally.  All you need to do is start a project at rubyforge.org, upload your finished Gem, and it will automatically appear in the central gem listing. As I was researching the steps for creating a gem, it was pretty clear that there wasn’t much of a comprehensive guide out there for beginners.  I’m hoping this article will help out those who are interested in creating gems, and save you some time as well.

Background
Building a Gem is actually pretty straightforward.  A gem is basically just a package of ruby code that has been assembled using the ‘gem build’ command.  If you’ve developed debian packages or RPMs, you are already familiar with this concept.  Essentially, the gem builder assembles the package, compresses it, and adds some metadata to help with the organization and installation of  your code onto any computer.

Getting Started
To create a gem, you’ll need some code (which I’m assuming you’ve already developed as a module), a pretty basic folder structure and a gemspec file.  First, lets take a look at a folder structure:

booksearch/
  README
  demo.rb
  lib/
    booksearch.rb
    booksearch/
      base.rb
      search.rb
  test/
    unit.rb

The folder structure above is for a gem called BookSearch.  Under the root directory, there is a README file, a demo.rb file and two directories, lib/ and test/.  The test/ directory contains a unit test file to verify the gem, and the lib/ directory is where all the code for the library is stored.  Directly in the lib/ directory is a file called booksearch.rb which is the file that is run when calling ‘require’ to load the gem.  All this file needs to do is load/require the correct files under the lib/booksearch/ directory.  Obviously then, the booksearch/ directory contains the actual code for the gem.  In the example above, there is the base.rb and search.rb files.  You can, of course, add other files and change the directory structure to suit your needs, but every gem will have a structure basically similar to this.

The Gemspec File
The core of the gem build process is the gemspec file.  This files contains all the metadata about the packaged gem, in additional to basic build instructions, similar to a configuration file.  Below is the gemspec file for my BookSearch gem:

Gem::Specification.new do |s|
   s.name = %q{booksearch}
   s.version = "0.1.0"
   s.date = %q{2009-06-02}
   s.authors = ["Mike Reich"]
   s.email = %q{mike@seabourneconsulting.com}
   s.summary = %q{A full featured Book Search API}
   s.homepage = %q{http://xxx.rubyforge.org/}
   s.description = %q{A full featured Book Search API}
   s.files = ["lib/booksearch.rb", "lib/booksearch/base.rb", "lib/booksearch/search.rb", "test/unit.rg", "demo.rb" "README"]
   s.rubyforge_project = 'booksearch'
   s.has_rdoc = true
   s.test_files = ['test/unit.rb']
end

There are a few key elements worth mentioning.  The ‘has_rdoc’ setting will alert Gem to the fact that your source code is commented to support RDoc documentation.  When a user installs your gem, RDoc will then be run on the source automatically to generate the documentation.  The ‘test_files’ setting is an array that should point to your unit test files, so that a user can choose to run the unit tests associated with your project through the gem command line tool.  You can see all the possible values of a gemspec file in the documentation.

Building Your Gem
Building a gem is a one step process.  You’ll want to place the gemspec file in the root directory of your gem, and then enter the command

gem build booksearch.gemspec

where ‘booksearch’ is the name of your gem.  The output of that command will be the fully constructed gem that you can install with the command

sudo gem install booksearch-0.1.0.gem

At this point, you can choose to distribute your gem any number of ways.

Conclusions
Overall, creating a Ruby Gem is much less complicated that creating a Debian package or RPM package.  The tools are well documented and clean, and the resulting package can be a powerful way to distribute your code to the world.

Creating Public Calendars with Google Calendar API

Update: I’ve got a new Ruby Gem that improves upon the functionality described below.  Check it out here.

In my previous post I covered how to create and manage google calendars using the Google Calendar API and Ruby on Rails.  One feature I really wanted in order to make my project really user friendly was the ability to make a newly created calendar public without having to log in to the Google Calendar website and make the permissions change manually.  Unfortunately, the documentation for how to do this is sparse at best.

Background
The key to making a public calendar lies in the Google Calendar Access Control Lists (ACL).  Like all other parts of the API, this is simply an Atom RSS feed that you can POST or GET from.  Essentially, ACLs allow you to specify the major permissions for each user that is added to a calendar.  The first problem I ran into was trying to figure out the correct url to POST to.  The google documentation only lists how to change the ACL for a specific user (and by default their primary calendar) rather than for a secondary calendar.  With a little sluething, I was able find a forum post that gives the calendar url:

"http://www.google.com/calendar/feeds/#{cal_id}/acl/full"

Where ‘cal_id’ is the unique calendar id.

To change a permission, you post a new rule to the feed above.  For example, to add a user with basic read permissions, you would POST the following code the to ACL feed url:

<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gAcl='http://schemas.google.com/acl/2007'>
  <category scheme='http://schemas.google.com/g/2005#kind'
    term='http://schemas.google.com/acl/2007#accessRule'/>
  <gAcl:scope type='user' value='darcy@gmail.com'></gAcl:scope>
  <gAcl:role
    value='http://schemas.google.com/gCal/2005#read'>
  </gAcl:role>
</entry>

The code above is pretty straightforward, and the google documentation gives a nice overview of what each part of the XML represents. However, I don’t want to add specific users to my calendars – rather I want to make them public to everyone by default.

After looking more at the documentation and at some forum posts, I figured out that instead of specifying a user, you can set the ’scope’ type to ‘default’ and omit the value attribute.  The role value can then be ‘read’ to allow for read only access to the public.  Therefore, the XML to create a public calendar looks like this:

<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gAcl='http://schemas.google.com/acl/2007'>
  <category scheme='http://schemas.google.com/g/2005#kind'
    term='http://schemas.google.com/acl/2007#accessRule'/>
  <gAcl:scope type='default'></gAcl:scope>
  <gAcl:role
    value='http://schemas.google.com/gCal/2005#read'>
  </gAcl:role>
</entry>

Extend GCalAPI
The code for adding this to the GCapAPI code, as I did in my previous post, is as follows:

class GoogleCalendar::ServiceBase
  def make_calendar_public(cal_id)
    #change permissions on the calendar to public
    path = "http://www.google.com/calendar/feeds/#{cal_id}/acl/full"
    request = "<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gAcl='http://schemas.google.com/acl/2007'>
                    <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/acl/2007#accessRule'/>
                     <gAcl:scope type='default'></gAcl:scope>
                     <gAcl:role value='http://schemas.google.com/gCal/2005#read'></gAcl:role>
                  </entry>"
    uri = URI.parse(path)
    res = do_post(uri, {"Content-Type" => "application/atom+xml", "Content-Length" => request.length.to_s}, request)
    if res.code.to_i != 201
      raise "Could not change permissions on calendar: "+res.body
    end
  end
end

You can now add the ‘make_calendar_public’ function call wherever you need, passing the relevant calendar id.

iPhone Web Applications with iUI and Ruby on Rails – Part 1

Since my last post outlining the different iPhone web apps, I’ve had a chance to play around with iUI a little more and get a successful app (for my side project, Notes/Tasks) up and running.  As there still is not a lot of documentation on using iUI, I figured I would sit and write down some of what I’ve learned.  As I’ve been developing the backend in Ruby on Rails, I figured I’d also add some tips and tricks for getting iUI to work well with dynamic content.  This article will cover the basic of creating a web application with iUI, including creating buttons, using forms and lists, and also how to integrate it with rails’ MVC framework.

Background
The app I’m using for demonstration is a side project of mine – building a web interface for a notes and tasks desktop application that synchs with an online server.  The desired functionality for the web is fairly simple: it needs restrict access to uses who have logged in, be able to display lists of notes and tasks, details for each individual note or task, edit the text of a note, mark a task as completed, and create new notes and tasks.  I’ve already written the API for the server (also in rails) so this project will focus on creating the user front end, rather than the backend application code.

Continue reading ‘iPhone Web Applications with iUI and Ruby on Rails – Part 1′