HomeHome ArchiveArchive

gem doesn’t know about Debian

There’s some interesting piece of software that I want to experiment with. It includes an example Rails application. Nice:

# apt-get install rails
$ cd interesting-example-rails-app
$ ./script/server
Missing the Rails 2.0.2 gem. Please `gem install -v=2.0.2 rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.

Uhm, well, why?

$ dpkg -s rails | grep Version
Version: 2.0.2-1ubuntu1

Executing the app with the debugger:

$ ruby -rdebug script/server

actually tells me what’s wrong. config/boot.rb checks whether it should run the Rails version that shipped with the Rails app, that is, by convention, put under vendor/rails.

By default, Debian’s own rails command (wrapper) will symlink everything needed, including vendor/rails to it’s own, packaged Ruby libraries/applications:

ls -l vendor/
insgesamt 0
lrwxrwxrwx 1 joe joe 29 2008-09-16 20:50 actionmailer -> /usr/share/rails/actionmailer
lrwxrwxrwx 1 joe joe 27 2008-09-16 20:50 actionpack -> /usr/share/rails/actionpack
lrwxrwxrwx 1 joe joe 28 2008-09-16 20:50 active_ldap -> /usr/share/rails/active_ldap
lrwxrwxrwx 1 joe joe 28 2008-09-16 20:50 activemodel -> /usr/share/rails/activemodel
lrwxrwxrwx 1 joe joe 29 2008-09-16 20:50 activerecord -> /usr/share/rails/activerecord
lrwxrwxrwx 1 joe joe 31 2008-09-16 20:50 activeresource -> /usr/share/rails/activeresource
lrwxrwxrwx 1 joe joe 30 2008-09-16 20:50 activesupport -> /usr/share/rails/activesupport
lrwxrwxrwx 1 joe joe 16 2008-09-16 20:50 rails -> /usr/share/rails
lrwxrwxrwx 1 joe joe 25 2008-09-16 20:50 railties -> /usr/share/rails/railties

and thus, a Debian rails generated application will allways use Debian’s own versions of Rails and the Active* libraries.

Thus, following Debian’s lead we can “debianize” any downloaded Rails app, by inserting the same set of links into vendor/. Mission accomplished. You can use this script to do this automatically for you.

That however won’t answer the question, why the downloaded Rails app won’t find Debian’s own Rails installation. I’m guessing, the problem is, that gem, here Debian’s gem, doesn’t know anything about Debian’s own Ruby libraries… feels a bit like two parties not wanting to speak to each other. Somewhat surprising, since software is suposed to be .. soft … and flexible…

Debian’s stance on the problem
Inclusion of this explanation into Debian

(all of this of course also applies to Ubuntu and all the other derivatives AFAIK)

improved mybackup

Here’s an improved version of mybackup, a MySql database backup tool. The changes against 0.9.5c are:

0.9.6:

  • option to exclude databases
  • by default exclude MySql’s information_schema metainfo DB
  • access TABLE STATUS rows by name instead of position
  • use the standard ‘-‘ for STDOUT instead of ‘BLANK’ which wouldn’t work
  • open log file before writing any output

Tomas Pospisek, tpo at sourcepole.ch

ical to timeline

Allthough this being a hack to scratch my itch named KDE Bug 34682, it took me about 11h all the same. Find a ruby programm attached that dumps a timeline.

This is fork ware. It does what I want but if you need to tune it to your needs then fork it, send me a note and link back to this page, Thanks.

Tomas Pospisek, tpo_deb at sourcepole.ch

MapLayers plugin for Rails

MapLayers map

Update July 31, 2008

The current version is now hosted and documented on github.

Getting Started

Install the latest version of the plugin:

  ./script/plugin install http://www.sourcepole.ch/svn/plugins/map_layers/trunk

Create a controller and a view

  ./script/generate controller Map index

Initialization of the map

Add the map viewer initialization to the index action in the controller:

  @map = MapLayers::Map.new("map") do |map, page|
    page << map.add_layer(MapLayers::GOOGLE)
    page << map.zoom_to_max_extent()
  end

Add this to the head of your view:

  <%= map_layers_includes :google => "ABQIAAAA3HdfrnxFAPWyY-aiJUxmqRTJQa0g3IQ9GZqIMmInSLzwtGDKaBQ0KYLwBEKSM7F9gCevcsIf6WPuIQ" %>

Put a map in the body your view:

  <div id="map" style="width: 512px; height: 256px;"></div>

  <%= @map.to_html %>

Test your basic map with localhost:3000/map

Multiple layers

Add a second layer and some more controls in the controller action:

  @map = MapLayers::Map.new("map") do |map, page|
    page << map.add_layer(MapLayers::GOOGLE)
    page << map.add_layer(MapLayers::YAHOO_HYBRID)

    page << map.add_control(Control::LayerSwitcher.new)
    page << map.add_control(Control::Permalink.new('permalink'))
    page << map.add_control(Control::MousePosition.new)

    page << map.zoom_to_max_extent()
  end

Add the Yahoo Javascript library to the includes:

  <%= map_layers_includes :google => "ABQIAAAA3HdfrnxFAPWyY-aiJUxmqRTJQa0g3IQ9GZqIMmInSLzwtGDKaBQ0KYLwBEKSM7F9gCevcsIf6WPuIQ", :yahoo => "euzuro-openlayers" %>

There are many more predefined layer types available: GOOGLE_SATELLITE, GOOGLE_HYBRID, GOOGLE_PHYSICAL, VE_ROAD, VE_AERIAL, VE_HYBRID, YAHOO, YAHOO_SATELLITE, YAHOO_HYBRID, MULTIMAP, OPENSTREETMAP, NASA_GLOBAL_MOSAIC, WORLDWIND, WORLDWIND_URBAN, WORLDWIND_BATHY

To include all Javascript APIs, insert your API keys in the following statement:

  <%= map_layers_includes :google => "ABQIAAAA3HdfrnxFAPWyY-aiJUxmqRTJQa0g3IQ9GZqIMmInSLzwtGDKaBQ0KYLwBEKSM7F9gCevcsIf6WPuIQ", :multimap => "metacarta_04", :virtualearth => true, :yahoo => "euzuro-openlayers" %>

Updating the map

Now we want to add some simple markers in an Ajax action. First we add a link in the view:

  <%= link_to_remote "Add marker", :url => { :action => "add_marker" } %>

This requires including the prototype library:

  <%= javascript_include_tag 'prototype' %>

Then we include a marker layer in the map. Put this after the add_map_layer statements in the controller:

  page.assign("markers", Layer::Markers.new('Markers'))
  page << map.addLayer(:markers)

and then we implement the Ajax action:

  def add_marker
    render :update do |page|
      @markers = JsVar.new('markers')
      page << @markers.add_marker(OpenLayers::Marker.new(OpenLayers::LonLat.new(rand*50,rand*50)))
    end
  end

For accessing the marker layer in the Ajax action, we declare a Javascript variable with page.assign and access the variable later with the JsVar wrapper.

Publish your own data

Create a model:

  ./script/generate model --skip-timestamps --skip-fixture Place placeName:string countryCode:string postalCode:string lat:float lng:float
  rake db:migrate

Import some places:

  ./script/runner "Geonames::Postalcode.search('Sidney').each { |pc| Place.create(pc.attributes.slice('placeName', 'postalCode', 'countryCode', 'lat', 'lng')) }"

Add a new controller with a map_layer:

  class PlacesController < ApplicationController

    map_layer :place, :text => :placeName

  end

And add a layer to the map:

  page << map.addLayer(Layer::GeoRSS.new("GeoRSS", "/places/georss"))

Other types of served layers:

  page << map.add_layer(Layer::GML.new("Places KML", "/places/kml", {:format=> JsExpr.new("OpenLayers.Format.KML")}))

  page << map.add_layer(Layer::WFS.new("Places WFS", "/places/wfs", {:typename => "places"}, {:featureClass => JsExpr.new("OpenLayers.Feature.WFS")}))

Spatial database support

Using a spatial database requires GeoRuby and the Spatial Adapter for Rails:

  sudo gem install georuby
  ruby script/plugin install svn://rubyforge.org/var/svn/georuby/SpatialAdapter/trunk/spatial_adapter

Install spatial functions in your DB (e.g. Postgis 8.1):

  DB=map_layers_dev
  createlang plpgsql $DB
  psql -d $DB -q -f /usr/share/postgresql-8.1-postgis/lwpostgis.sql

Create a model:

  ./script/generate model --skip-timestamps --skip-fixture WeatherStation name:string geom:point
  rake db:migrate

Import some station:

  ./script/runner "Geonames::Weather.weather(:north => 44.1, :south => -9.9, :east => -22.4, :west => 55.2).each { |st| WeatherStation.create(:name => st.stationName, :geom => Point.from_x_y(st.lng, st.lat)) }"

Add a new controller with a map_layer:

  class WeatherStationsController < ApplicationController

    map_layer :weater_stations, :geometry => :geom

  end

And add a WFS layer to the map:

  page << map.add_layer(Layer::WFS.new("Weather Stations", "/weather_stations/wfs", {:typename => "weather_stations"}, {:featureClass => JsExpr.new("OpenLayers.Feature.WFS")}))

License

The MapLayers plugin for Rails is released under the MIT license.

Support

For any questions, enhancement proposals, bug notifications or corrections visit rubyforge.org/projects/map-layers or send a mail to

pka at sourcepole.ch

Copyright (c) 2008 Pirmin Kalberer, Sourcepole AG