fragment identifiers

June 12th, 2008

Q: how in Routes/Markaby do we implement fragment identifiers # as in www.foo.bar/pedro#here, for named anchor jumps ?
H(int): is it necessary to parse the controller ?
H(int): can a regexp solve it ? ‘/foo/(\w+)#(\w+)’ doesn’t…
A: …


AR::migrations

June 9th, 2008

ActiveRecord database schema migration info is stored in the main database, so that if one needs to manually hack a migration (fastforward/rewind), just update TABLENAME_schema_infos column ‘version’ to a new value and manually change your schema. Next ‘boot’ may generate (or not) new migrations.

riverside=# select * from foobar_schema_infos;
id | version
—+———
1 | 1.4
(1 row)

In a self note, forget not to set option :id => false on join tables for has_and_belongs_to_many relations.


god.pt

June 6th, 2008

god.pt is well described here, @ karlus. We and some more fine guys will be focusing on Gathering of Developers in our city, Porto::Portugal::Europe. We’ll be doing presentations (mostly but not only technical ones), debating ideas, working together hopefully on projects, networking and building business (well, one of the first meetings was partially dedicated to push Nuno sysadminin’ skills to start a “pro” hosting company). Barcamp, First Tuesday, TechMeet, we’ll be having a bit of ‘em all.

The starting group talks Python (Nuno), Ruby (me and Mario), media and communication (Carlos), Php (and domain registering savoir-faire ;) Karlus), and guess what: we’re all on Twitter, like godevel is.

The developers part of GOD isn’t restricted to code_monkeys. We speak business, startup’ing, venture capital, economy, talks (long or lightning), beer, unix, languages, hw, sw, media, web, web, web, servers, life, laptops, frameworks, gossip, gadgets, working environments, projects, code, code, scripts, threads, scaling, architectures. We’ll be focusing less on ideas, more on work. Implementations. On doing it.

I look forward a code_day in wich we’ll be coding for ourselves/others under a strong networking environment, during wich lightning-talks will hopefully rise.

More to come soon…
As for now, I’m fighting threads and forks in Ruby…


class Monstar

June 5th, 2008

I recently had to move from using FastCGI on Camping Ruby framework, to sweet Mongrel because of getting too much 500 HTTP errors under some load tests. Yes irc::zimbatm, me too.
When on FastCGI behing Lighttpd, upon each request, the code is loaded so after changing its source, it gets updated.

Now, under development, Mongrel(s), behind the same Lighttpd frontend, need to be restarted upon source code changes in the models, views, controllers or helpers (yet not CSS files, since they are taken care by lighty). Instead of moving to the xterm, kill the process and restart it i decided to automate it.
Since i was disconnected from the webz, I’ve done this script to detect file changes from a pre-specified array of files, monitored under a certain interval in seconds, with an action to start, kill, and restart an app (in my case, a Mongreled Camping web app).

Problem: Threads
Solution: Process::fork

The app load (in this case I load/execute ruby scripts) is done via Process::fork. A new process starts up each time this method is fired up upon a File.open(f, 'r').ctime change:

def load_app
@pid = Process.fork { load(@app) }
end

Before loading up a new updated instance of the app, the previous one must be terminated. Threads behaviour was problematic because of the thread tree termination in time. This is well done, in a safe mode, with Process::kill(signal, pid) and Process::wait(pid) that waits the pid process termination, essential in the case of Mongrel server.

def kill_app
Process.kill("KILL", @pid)
Process.wait(@pid)
end

As one can see jump to flickr in this screenshot the main app process holds on while the child, in this case our Mongrel’ed Camping web app, is terminated and created a new one. jump to flickr Verbose mode to assert its behaviour. Suits this specific need.

This is very usefull to make tests (Test::Unit:TestCase) run automatically upon source changes (will get to an Autotest clone).

Changing from load(@app) to system(@app), one can get any command be executed. ftp, cp, etc…

The script is here do download under a Ruby License.

Usage: monstar [options]
-a, --app SCRIPT.RB,PARAMS,...
-i, --interval VAL
-f, --files FILE,FILE1,...
-h, --help


2008 ACM-ICPC Programming Results

April 13th, 2008

Draft configuration for the programming environment at 2008 ACM-ICPC World Finals.
“Pascal has been dropped as a World Finals Language”… I miss Delphi (Object Pascal)

Look at the final results.
Now lets see 2007 standings.

Geo pattern ?


blog with Vim script

April 10th, 2008

… after severall exchanged emails between me and Andrei Thorp about the Vim blogging ruby script, we made some changes. So instead of the initial test for Vim compiled with +ruby message s:ErrMsg, we now have an echo.

Andrei’s git (yep, they are git fans too, git rocks!) commit was calling another Vim from his machine. That was not a +ruby vim. So an error was fired upon git commits. Now we fixed it. This is now, vimblog 1.1. Thanks Andrei.

Open Source++


Rubinius documentation

April 7th, 2008

self note for a nice read: Introduction to the Rubinius compiler


Shoes.rb on Github

April 4th, 2008

_why posted in Shoes mailinglist that he will be moving source code to Github.com. Since I am using Git for some months, this is good news.

In short, Shoes.rb repository:
http://github.com/why/shoes
You can clone the repository with:
git clone git://github.com/why/shoes.git

Ditz, (“a simple, light-weight distributed issue tracker designed to work with distributed version control systems like darcs and git”) will be used as an issue tracker. The YAML database file is included in the commits, since it becomes a project source file. Its Ruby coded and produces quite nice HTML pages.

…nice move _why


the spirit that lives in the computer

April 2nd, 2008

“We are about to study the idea of a computational process. Computational processes are abstract beings that inhabit computers. As they evolve, processes manipulate other abstract things called data. The evolution of a process is directed by a pattern of rules called a program. People create programs to direct processes. In effect, we conjure the spirits of the computer with our spells.”

“Structure and Interpretation of Computer Programs”


Twittershoes: programming in Shoes.rb

February 22nd, 2008

I have to share this piece of code, wich results look indeed nice. You’ll see in the next blog post…

def string_alert
  c = (LIMIT-@iSay.text.length)
  @remaining.style :stroke => "#3276BA"
  c > 10 ? (@remaining.style :stroke => orange) : (@remaining.style :stroke => red) if (c < 21)
  c > 0 ? “#{c.to_s} chars” : “Too Long!”
end

[update]: Twittershoes.rb is born: screenshot here


first repo at github.com

February 15th, 2008

… just got my github.com invitation and proceeded to the registration.
They say its free while in Beta. Hosted in Engine Yard.
I created my first repo there, and the design seems clear, simple, effective.
Info is presented clearly, and i enjoyed the way they went after the creation of my repo, showing “Next Steps”. Nice.

I’ll work there for this project.


pg_upgradecluster 8.2 main

February 12th, 2008

PostgreSQL 8.3 is here. After apt-get’ing it, the upgrade didn’t move the 8.2 cluster up. Having 8.2 running in a custom port, made 8.3 go use the standard 5432 port.
8.3 created a main cluster.

Check ports:
$ sudo netstat -anput | grep postgres

Check wich configuration files and wich versions are running:
$ ps -Af | grep postgres

pg_upgradecluster when upgrading the existing PostgreSQL cluster, will check ports of the new and old version (check both 8.2 and /etc/postgresql/8.3/main$ grep 'port' postgresql.conf), and make the newer version use the older version’s port number. Then the older version will use an available port number. This keeps the original Port # in use.

Stop and drop the newly created 8.3 main cluster:
$ sudo pg_dropcluster --stop 8.3 main

Time to upgrade the 8.2 main cluster to 8.3
$ sudo pg_upgradecluster 8.2 main

After checking everything is ok we could remove the older cluster:
$ sudo pg_dropcluster --stop 8.2 main

and “apt-get remove” the 8.2 version.

docs:
$ man pg_dropcluster
$ man pg_upgradecluster


JSON Ruby and Smallr API

February 3rd, 2008

Nuno’s smallr.net API talks JSON. So what about accessing it with Ruby ?
Well, quite easy thanks to Florian’s JSON implementation for Ruby. So:

$ sudo gem install json_pure

Now, just need some attention on the use of the address / (slash) just after json and before the query, or you’ll get a HTTP 301 Status Code.
Code follows:

require 'rubygems'
require 'net/http'
require 'json/pure'

url = 'http://www.google.pt/search?q=json+ruby'
escaped_url = URI.escape(url, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
call = Net::HTTP.get_response(URI.parse("http://smallr.net/json/?url=#{escaped_url}"))
res = JSON.parse(call.body)

puts res['status'] # ok
puts res['url'] # http://smallr.net/925


on URI Ruby escaping

February 3rd, 2008

URI.escape method with no options doesn’t provide a trully good escape, and i just noticed it upon the need to access an API.

url = 'http://www.ruby-lang.org'
bad = URI.escape(url)
good = URI.escape(url, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))

The difference is:

bad => "http://www.ruby-lang.org"
good => "http%3A%2F%2Fwww.ruby-lang.org"

(via snippets.dzone => Matt Zukowski)


The Ruby Programming Language

January 29th, 2008

… next buy.

“Bestselling author David Flanagan teams up with Ruby creator Yukihiro "Matz" Matsumoto and writer/cartoonist/programmer why the lucky stiff to bring you the authoritative guide to Ruby. Covering versions 1.9 and 1.8, this book helps you learn Ruby’s lexical structure, primary expressions, conditionals, syntax, classes, the data it manipulates, and more. For experienced programmers who want to look at this language in depth, this guide is invaluable.”


flash-like implementation

January 13th, 2008

Flash is a Ruby on Rails method to show (mainly warning/error) messages. Camping has no such method, so i implemented an approach for error messages. The thing is, after a post method in the controller, the redirect creates a new instance for the controller, loosing the class instance variables set before.
So, after talking a bit with Zimbatm at #camping, we setup what could be a good solution: to use the @state session variable.

@state.error = ‘The unit is still operational, Dave. But it will fail within seventy-two hours’

The variable is cleared on the View layout method. Flash means just it. Show and clear. The layout code includes:

div(:class => 'error') { p @state.error.to_s; @state.error = ''; } unless @state.error.blank?

and the CSS .error class wraps the message inside a lightred box with a nice solid red border (say RoR?).


Camping on IRB

December 22nd, 2007

IRB is a great tool. What about testing parts of a Camping app in IRB (meaning App::Models module) ? Just require the app, but do not forget to establish the (in case of using it) ActiveRecord connection, that problably is specified in dispatch.rb
Try this, using _Why’s Blog webapp example:

$ cd /path/to/blog/app
$ irb
irb(main):001:0> require 'rubygems'
irb(main):002:0> require 'blog'
irb(main):003:0> Camping::Models::Base.establish_connection :adapter => 'postgresql', :host => 'trees', :port => 54321, :database => 'beautifull', :username => 'green', :password => 'forest'
irb(main):004:0> Blog::Models::Post.find(1)

Answers from lines:
[#3] => #< ActiveRecord::Base::ConnectionSpecification:0xb77499a8 @adapter_method="postgresql_connection", @config={:host=>“trees”, :password=>”forest”, :port=>54321, :database=>”beautifull”, :adapter=>”postgresql”, :username=>”green”}>
[#4] => #< Blog::Models::Post:0xb7736e5c @attributes={"body"=>“… this is the first post on Why’s blog web app for testing Camping functionalities. \r\n\r\nIts cool. It’s Ruby. Its Lighttpd. Its Postgres (well, at least in my implementation) via Active Record.\r\n\r\nCamping(TM) of WhyTheLuckyStiff”, “title”=>”camping is fine”, “id”=>”1″, “user_id”=>”1″}>

[#4] is the first row from postgres ‘beautifull’ database ‘blog_posts’ table. Fetched via ActiveRecord, via Blog::Models module, via Blog Camping app.


ActiveRecord connection adapters

December 22nd, 2007

…because of Camping::Models I’m using ActiveRecord Ruby implementation gem. Because source code is pretty well documented I maintain an opened xterm to check how things are done. Since I’m not using SQLite but PostgreSQL, i had to dig for the other parameters for the connection and I noticed AR has now connectors for severall DMBS:

$ cat /var/lib/gems/1.8/gems/activerecord-1.15.3/lib/active_record.rb
[…]
unless defined?(RAILS_CONNECTION_ADAPTERS)
  RAILS_CONNECTION_ADAPTERS = %w( mysql postgresql sqlite firebird sqlserver db2 oracle sybase openbase frontbase )
end

[…]


… on git

December 9th, 2007

Melo will be focusing on git

Once you get used to git, you won’t be needing “anything else” to maintain your code. Git is gaining more and more traction, now that bigger (distributed) projects (or parts of them) are running away from other scm’s into this one (Gnome ?, Kde, …). CVS, SVN user base is still huge, though. From the questions at Google Tech Talks, seems that Google has a very centralized && protected development environment, wich is not that strange attending to their business core and innovative material under maintenance/production (they shut the camera/video down sometimes due to their non disclosure politics). That kind of environment, generally speaking, seems to fit for git usage, since it does ssh and its built-in cryptographic authentication of history ensures revisions purity.
He added a Randal Schwartz video also at Google, in addition to the Linus one i referred here a while ago (the last time i saw Randal, he was talking about the wonders of Smalltalk at #git :-) in a very interesting debate)

[append]
pfig first-try screencast on git. well done.
[append]
to wrap up, this podcast, on Floss (not that) Weekly, a talk between the gitster (maintainer) Junio Hamano, Leo Laporte and Randal.


msg upload to gmail ruby class (imap)

December 4th, 2007

… moving to Google Hosted (Google Apps), there was the need to upload some thousands of e-mail messages. Since they were (mt) MediaTemple Berkeley mbox stores, i scp’d them locally (backup) and them imported them into Evolution local folders.
The problem was the copy/move to the google hosted imap mail server. Evolution couldn’t finish the task on severall tries. Mozilla Iceape (Seamonkey) had a similar behaviour, suffering from server disconnects, thus stopping the operation. Because i had severall folders, the task needed lot’s of attention, and i wanted the machine to do it all by itself…

Solution: let’s code !! What response is the server sending… ?

Shugo Maeda’s Ruby net/imap.rb class (stdlib) is simple and trusty.
Not wasting lots of time in it, i made a new class with the following usage, to send specified mbox file mail messages to a gmail (google hosted) account:

$ ./2gmail.rb MBOXFILE GMAILFOLDER [STARTINGMESSAGE]

If GMAILFOLDER doesn’t exist, gets created (i prefered messages in temporary folders) upthere.
If it breaks, you can:

$ tail 2Gmail.log

to see the last message sent, and restart the process in that message. I could have threaded the whole thing, but this is done just once, so lets keep in focus…
Usual problems during the tests, msg headers/body separation, timestamps, etc…
Class Mail in mailread.rb does a great job creating an Hash for the Message Headers. Sweet…

Everything is logged, so that it’s easy to ‘grep’ for errors in the 2Gmail.log file.
I had one only problem on a message with a 25MB attachment (gmail didn’t accept it).
All the messages are now up there, nobody knows for certain where (EU ? US ? both ?…)

The code needs one or two more Exception Handling, but it works very well. I had 6 xterm’s uploading at the same time. And yes, I could have openned 6 tabs in Gnome Terminal since we have them for ages, Mr. Leopard ones! Hey, we can even detach Tabs to independent Terminal windows via drag-n-drop (like in Epiphany, way way long ago… way…)

There are some thousands more messages to be uploaded, from ancient backups… maybe next week.

Operation screenshot: at Flickr as usual
Wanna try ? Get it here (ready for Debian & Ubuntu. For other distros, check line 1 or just prepend ruby interpreter on call)

$ chmod u+x 2gmail.rb
$ ./2gmail.rb MBOXFILE GMAILFOLDER [STARTINGMESSAGE]