Naglfar release

Posted by labria on February 21, 2010

I finally found time in my schedule to release the Naglfar project. I've been thinking for a long time of a project to use the beautiful name, and I suddenly realized that the name itself is quite enough for me =)

To install, just do the usual:

gem install naglfar

The gem does almost nothing, actually. It declares the Naglfar singleton class with one useless method, and prints a message to stdout after you require it.

From now on, i'll require it in every ruby project I'll be doing. I do think that having a Naglfar in your project will bring it good luck, so don't hesitate to require it too!

PS: I plan to release something much more useful soon, so watch this space.

My first working Erlang code.

Posted by labria on September 15, 2009

I wrote my first working bit of Erlang code. Wasn't much code, actually. Here it is:

 
<erl>
out(A) ->
    {ok, Challenge} = queryvar(A,"hub.challenge"),
    {html,io_lib:format('~s', [Challenge])}.
</erl>
 

Wow... my highlighter doesn't even support Erlang! now it does

This a complete and finished piece of code, yes. If you heard of PubSubHubbub — that's the code to confirm all subscriptions in async mode.

The funny thing about it is the amount of code I would user to do the same in Rails/Sinatra/Whatever + erb:

 
<%= params["hub.challenge"]%>
 

A wonderful way to list your project files 9

Posted by labria on September 10, 2009

This article is published as a reply to the last few articles on the thoughtbot blog.

Some time or another during the project development you may wonder: «What files does my project include?» or «Why am I a Star Wars fan anyway?». This article will focus on the first question, leaving the second to your own reflection.

Any shell you might be using comes with a lot of useful tools. The one of interest today is ls

Here's the most simple example of its usage in a Rails project

 
sample_project $ ls
README		app		db		lib		public		test		vendor
Rakefile	config		doc		log		script		tmp
 

As a little more complex example, you might want to get the list of your model files:

 
sample_project $ ls app/models/
comment.rb	post.rb
 

Or, it even can do crazy stuff, like list all your model files AND controller files AND helper files! Now thats some useful magic, isn't it?

 
sample_project $ ls app/*
app/controllers:
application_controller.rb	comments_controller.rb		posts_controller.rb
 
app/helpers:
application_helper.rb	comments_helper.rb	posts_helper.rb
 
app/models:
comment.rb	post.rb
 
app/views:
comments	layouts		posts
 

ls can do much. much more. Go check out the manual page here, you'll be amazed.

Note to Windows users: you also have a similar command, named dir.

Freckle API. 1

Posted by labria on July 11, 2009

UPD: Freckle updated the API and docs. The new ones are here.

I'm a Freckle user, and I love the service. The only thing I really miss is a simple client to store my time entries without visiting the site.

So, I sat down to write that simple client app, knowing Freckle has an API.

Alas, things aren't that simple. The only thing you can in fact do using the API description is to get the list of your projects. But after a bit of digging and trial and error i figured out some of the real API, and wanted to share it with anyone who might want to use it.

In all the examples yourfreckle is your Freckle domain name, and refet7vjpj01elltewf2fbqd9znkbh9 is your API key. All examples use JSON, but should work with XML too, just replace .json with .xml

Getting the list of projects. This is done by a simple GET request to http://yourfreckle.letsfreckle.com/api/projects.json?token=refet7vjpj01elltewf2fbqd9znkbh9, which will return a JSON array of projects in the form of

[
{"project": {"name": "Bibla", "updated_at": "2009-06-30T14:52:51Z", "account_id": 3279, "id": 5120,
"enabled": true, "user_id": null, "stepping": 15, "budget": null, "created_at": "2009-06-30T14:52:51Z"}},
{"project": {"name": "Inventure", "updated_at": "2009-06-30T14:02:15Z", "account_id": 3279, "id": 5114,
"enabled": true, "user_id": null, "stepping": 15, "budget": null, "created_at": "2009-06-30T14:02:15Z"}},
{"project": {"name": "OMD", "updated_at": "2009-06-30T14:27:20Z", "account_id": 3279, "id": 5118,
"enabled": true, "user_id": null, "stepping": 15, "budget": null, "created_at": "2009-06-30T14:27:20Z"}}
]
 

The significant bits here are the "name" and "id" fields. You will surely need both of them later on.

Getting the list of entries. This one is not quite what we want it to be. You can get only the last 100 entries, and no filters. To obtain this you need to do a GET request to http://yourfreckle.letsfreckle.com/api/entries.json?token=refet7vjpj01elltewf2fbqd9znkbh9, but you will only get the latest entries for all users on all projects. I found no way to filter them yet, the RESTful approach didn't work, so you have to filter them yourself in your app, if needed. The entries come back in the following form:

 
[{"entry": {"updated_at": "2009-07-10T18:34:16Z", "project_id": 5151, "billable": true, "minutes": 300, "date": "2009-07-10", "url": null, "id": 51177,
"time_to": null, "time_from": null, "description": "A sample entry description", "formatted_description": "A sample entry description", "user_id": 3635, "created_at": "2009-07-10T18:26:09Z"}},
{"entry": {"updated_at": "2009-07-11T02:03:37Z", "project_id": 5120, "billable": true, "minutes": 30, "date": "2009-07-10", "url": null, "id": 51253,
"time_to": null, "time_from": null, "description": "A second sample entry description", "formatted_description": "", "user_id": 3574, "created_at": "2009-07-11T02:03:37Z"}},
{"entry": {"updated_at": "2009-07-10T18:25:29Z", "project_id": 5151, "billable": true, "minutes": 120, "date": "2009-07-10", "url": null, "id": 51176,
"time_to": null, "time_from": null, "description": "A third sample entry description", "formatted_description": "A third sample entry description", "user_id": 3635, "created_at": "2009-07-10T18:25:29Z"}},
{"entry": {"updated_at": "2009-07-10T18:24:14Z", "project_id": 5151, "billable": true, "minutes": 120, "date": "2009-07-10", "url": null, "id": 51175,
"time_to": null, "time_from": null, "description": "And one more sample entry description", "formatted_description": "And one more sample entry description", "user_id": 3635, "created_at": "2009-07-10T18:24:14Z"}},
{"entry": {"updated_at": "2009-07-10T19:27:29Z", "project_id": 5112, "billable": true, "minutes": 60, "date": "2009-07-10", "url": null, "id": 51195,
"time_to": null, "time_from": null, "description": "haha haha", "formatted_description": "", "user_id": 3572, "created_at": "2009-07-10T19:27:29Z"}}...]
 

As you can see, entries don't mention project or user names, only reference them by id, so if you really wanna know who did what you need to do the user and project mappings yourself.

Getting the list of account users. GET to http://yourfreckle.letsfreckle.com/api/users.json?token=refet7vjpj01elltewf2fbqd9znkbh9, resulting in something like that:

 
[{"user": {"id": 3570, "first_name": "Alexey", "time_format": "hours_minutes", "login": "wolfson", "last_name": "Wolfson", "email": "wolfson@gmail.com"}},
{"user": {"id": 3572, "first_name": "Dmitry", "time_format": "fraction", "login": "labria", "last_name": "Krassovski", "email": "labria@startika.com"}},
{"user": {"id": 3571, "first_name": "Maxim", "time_format": "hours_minutes", "login": "boork", "last_name": "Boork", "email": "boork@gmail.com"}}
]

This one was simple, right? :)

Creating stuff. To create things you do POST requests with parameters in the request body. The parameters, contrary to the API description, are not JSON, but simple string params, in the form of object_name[property]=something&object_name[other_property]=something_else. This is the usual Rails way of sending parameters. Just don't forget to URL encode them before sending =)

Creating a project. POST to http://yourfreckle.letsfreckle.com/api/projects.json?token=refet7vjpj01elltewf2fbqd9znkbh9 with the body set to "project[name]=SomeProjectName". The reply body will be empty, just watch the HTTP code, 201 means you've created the project, anything else is probably an error (but don't expect to get any meaningful error description)

Creating an entry. This is where you need the project ids that you obtained earlier. POST to http://yourfreckle.letsfreckle.com/api/entries.json?token=refet7vjpj01elltewf2fbqd9znkbh9 with the body set to "entry[minutes]=15&entry[project_id]=5151&entry[user]=labria&entry[description]=foobar&entry[date]=2009-07-10". Here, project_id is the id of the project you want to post to, and user is the username of the user you want to post it to, everything else is quite obvious. Funny thing: using your own API key you can post entries for any user on your team.

Well, thats about it. There may be more stuff i don't yet know about, but the things described here should be enough to create a simple client application. You can't do much about reporting, as 100 entries is surely not enough, but I hope this improves in some way over time.

PS: Thanks to the Freckle team for the nice and easy to use service.

PPS: No, I didn't write any client app that does more than getting the list of your projects yet. I'll post a follow up when I do =)

PPPS: This by no means isn't a good technical description of the API, but it should get you going. Maybe I'll write a better one later.

Weird RSpec practice.

Posted by labria on June 25, 2009

I recently found myself doing a wierd thing. While writing specs i add this spec to the end of the file:

 
it "should fail" do
  raise "foo"
end
 

The reason to do it? Simple: every time i have all the specs passing in the current file, autospec begins running all the specs in my project, breaking my red-green cycle for about 30 seconds. Adding a failing spec prevents it from doing it, and speeds up my work.

Am I doing something wrong?

A new version of my First App. *updated*

Posted by labria on April 28, 2009

After quite some time with the docs and google (and help on IRC from some a nice guy named Sidnicious) I finally made my app behave as it should, and now it shortens the URLs you drop on it (as was requested by one of my very few users).

UPD: It now has Growl integration! Hooray!

You can grab the new version here

Seems the last thing to do is to add some configuration (api key for instance).

Heroku pricing.

Posted by labria on April 24, 2009

Heroku announced their pricing today. As with all rails-centric hosting solutions, the price is sky high. You can get a LOT more if you just go and get Amazon EC2 and set everything up yourself. Yes, they do provide you with automatic and painless scaling, but for the price difference I would prefer the pain of scaling, once i get to the point of needing it.

Anybody needs Amazon deployment? Feel free to contact me =)

My first Cocoa app.

Posted by labria on April 20, 2009

I love Objective-C.

I understood that while writing my first app, a dead simple bit.ly client. The app is a bleeding beta yet, but it works.
The thing is simple, you copy a link, run the app (from the dock, its faster to do it that way), and you get a short link in your clipboard to paste.
One of the current limitations is that it only works with URLs without parameters. It will silently fail if the URL is too complex, leaving you with an empty clipboard =)

Update: The new version handles all urls, it seems.

The todo list is as follows:

  • Let the user change the api key used.
  • Handle all kinds of urls.
  • maybe: run in background monitoring the clipboard and shorten urls if found =)

Download it: cocobit.zip

Feedback is welcome =)

At last!

Posted by labria on April 17, 2009

They made it!
Phusion has released passenger with nginx support.
No more bloated apache installs, hooray!
I've been waiting for this since the day passenger was first released.
UPD: well, it has some issues as of now, but I'm sure it's all gonna be fixed soon enough!

Status update.

Posted by labria on March 22, 2009

It's been awhile since I last wrote here. Quite a lot happened in the meantime.

I now work at a really nice russian company named Getalime. It's small, very friendly and cozy. Funny thing is that 2 weeks after joining it I moved to live in Israel, so I never met any of my coworkers =)

I've been involved in a lot of Rails (and even one Merb) projects. My first patch has been accepted to the Rails core. I'm one of the two first russian regular ruby podcasters, with 100+ RSS subscribers and around 400 listeners of each episode. I'm not sure if it's a lot or not, but I'm happy anyway =)

Now I've decided that it was about time to revive this blog, and so I will try! See you soon, i hope.