WebHooks on AppJet

Posted by on 23-Feb-2009

Hi everybody,
I created a small lib-webhook library and a small companion hooks application for easy working with webhooks on AppJet. Like maybe you know, webhooks are one of the current hot topics. They are a very easy way to implement a real-time communications between remote applications.

What you can use it for:

  1. Notify your AppJet based application about changes (commits etc.) in your GitHub repository - have for example ChangeLog + user notifications to some ML:

    Just go to GitHub Admin|Hooks page and if the already defined hooks are not enough put http://youhooks.appjet.net/github/SomeSecret/ there.

  2. Post to your AppJet based application by Jabber (XMPP) or from an iPhone:

    go to https://ping.fm/custom/ and enter http://youhooks.appjet/pingfm/SomeSecret/ . ping.fm have a XMPP bot and an iPhone application which you can use.

  3. Post to your AppJet application by email:

    http://www.smtp2web.com/ , define some email address and point the URL to http://youhooks.appjet.net/something/SomeSecret/. In fact I’m first pointing it to one small application on GAE itself, because parsing multipart/rfc-822 coded message parameter will be difficult on AppJet. So I’m parsing it with message.get_payload() and repacking it in JSON payload. After this it can be send to AppJet.

  4. Posting to XMPP from AppJet - it still missing on AppJet, so I have a small Heroku-hosted Sinatra application to implement this feature. So http://youhooks.appjet.net/xmpp/SomeSecret/ will in turn call that Sinatra application. If you do not trust me with your XMPP information, just create your own application somewhere, where XMPP is possible and call it with a webhooks API (your_url, JSON(payload),JSON(data)).

How to use lib-webhook and hooks application:

  1. Clone the hooks application to (for example) http://youhooks.appjet.net/
  2. Set your secret token - it will be added to the end of the URLs:
      // from the shell
      import ("storage", "lib-webhook");
      storage.token = "SomeSecret";
    
  3. Define users for the hooks, that needed them. I need for example user/password for the XMPP hook and user/key for the http://bit.ly/ URL shortening service. In this way they will be not visible in your application sources.
    // from the shell
    HOOK.addUser("xmpp", {user:"...", password:"..."});
    

    In the moment my hooks application just inserting the user’s data with the same name as the hook, if such user exists:

    data = HOOK.addUserData(data, hook);
    

The library itself provide two main functions:

// universal caller - remote or local hooks:
string callH(url, JSON(payload), JSON(data));
// call local hooks by name
string callLocalH(name, payload, data);

The rest are just some small helpers for user’s data management.

I’ll be very happy to see clones of hooks application with some interesting webhooks (http://pbwiki.com/ for example also supporting webhooks. and by the way PayPal also wink ). And about lib-webhook - will add twitter, identi.ca and maybe some others local hooks ASAP.

Let’s the source be with you.

Ruby Sinatra: uninitialized constant Rack::File::MIME_TYPES

Posted by on 27-Jan-2009

Original: rack newb problem w/ 0.9.0

When tried to run a sinatra based application, I received an error message:

./sinatra/lib/sinatra.rb:1156:in `mime': uninitialized constant Rack::File::MIME_TYPES (NameError)

According to Ryan Tomayko “…MIME_TYPES constant got shuffled around in this release (rack release)…”.
The solution (temporary) is to define Rack::File::MIME_TYPES by yourself before requiring sinatra:

require 'rack/file'
class Rack::File
   MIME_TYPES = Hash.new { |hash, key|
   Rack::Mime::MIME_TYPES[".#{key}"] }
end
require 'sinatra'
...

Subscribe to this blog via XMPP (Jabber)

Posted by on 09-Jan-2009

If you have http://notifixio.us/ account, you can receive notifications, for articles, posted to this blog via email, XMPP etc. I installed Notifixious Plugin (see the sidebar, Notifixio.us section). Need JavaScript enabled.

How to use Archlinux Pacman?

Posted by on 07-Nov-2008

  • Packages installation:
    pacman -Sy package_name - packages installation and local packages db sync
    pacman -S package_name - packages installation along with dependencies
    pacman -Sl repository_name - display packages list of a given repository
    pacman -Sv package_name - information about operation
    
  • Removing packages:
    pacman -R package_name - removing package without dependencies
    pacman -Rs package_name - removing package along with dependencies
    pacman -Rn package_name - purging package
    
  • System update:
    pacman -Su - update all the packages
    pacman -Syu - update all the packages and synchronize local packages database
    
  • Database queries:
    pacman -Ss keyword - search for all packages matching the keyword
                                   (where the keyword is a part of the package name)
    pacman -Qi package_name - information about package
    pacman -Ql package_name - list files that a given package consist of
    pacman -Qs package_name - search files installed on hard disk
    
  • Other commands:
    pacman -Sw package_name - download package without installation
    pacman -A /file/path/file.tar - install package
    pacman -Sc - clean cache (old files)
    pacman -Scc - clean cache (all files)
    

Original article

GMail backup

Posted by on 09-Oct-2008

After the rumors about locked GMail accounts, decided to backup my important emails. The article How to back up your Gmail on Linux in four easy steps helped me a lot. My setting in ~/.getmail/getmail.gmail are (IMAP, Maildir):

[retriever]
type = SimpleIMAPSSLRetriever
server = imap.gmail.com
username = my_name
password = my_secret
mailboxes = (”personal”,”important”)

[destination]
type = Maildir
path = ~/gmail-archive/

[options]
verbose = 2
message_log = ~/.getmail/gmail.log

The backup itself was done via:

$ getmail -r ~/.getmail/getmail.gmail

github error: failed to push some refs

Posted by on 29-Sep-2008

When trying to push to github received:

$ git push
To git@github.com:zh/laconica.git
 ! [rejected]        master -> master (non-fast forward)
error: failed to push some refs to 'git@github.com:zh/laconica.git'

The solution

$ git pull
....
$ git push

Install merb from git

Posted by on 16-Sep-2008

Trying to install the development version of merb , i’ve got:

no such file to load -- extlib/tasks/release

Seems the extlib gem is too old for merb. Fix:

$ git clone git://github.com/sam/extlib.git
$ cd extlib
$ rake gem
$ sudo gem install pkg/extlib-0.9.4.gem

The rest of installation process:

$ sudo gem install sake erubis mime-types
$ sake -i http://merbivore.com/merb-dev.sake
$ mkdir ~/merb_src && cd ~/merb_src
$ sake merb:clone
$ sake merb:install:all

Your first application:

$ merb-gen app my_app --flat && cd my_app

TinyURL Ramaze Application

Posted by on 28-May-2008

Created tinyurl ramaze applicationeverything in one file – model, view, controller. Required gems: sqlite3-ruby, sequel, validatable, ramaze .Even have an API:

$ curl -O turl.rb http://zhware.net/code/ruby/ramaze/turl.rb.txt
$ ruby turl.rb
# browse http://localhost:7000/
# shorten url
$ curl http://admin:secret@localhost:7000/_api?turl=http://zhware.net/code/ruby/
# restore the original url
$ curl http://admin:secret@localhost:7000/_api?url=abc
# number of hits for given turl
$ curl http://admin:secret@localhost:7000/_api?hits=abc

Do not forget to change the BASE_URL and LOGINS values. By default the database file (sqlite3) will be created in the same directory with turl.rb . If this is not acceptable, change the DB_FILE line.

Update: created the turl project on github

26th Ruby Kansai Workshop in Kyoto

Posted by on 19-May-2008

On 17-May-2008 there was 26th Ruby Kansai Workshop in Kyoto . A lot of fun like always :) The chatlog from the presentations is available on lingr.

I gave a presentation “Ruby off Rails” about developing web applications in Ruby, but without Rails – Sequel, Rack, Ramaze etc. talk. The presentation slides:

The sources from the talk (plus some extras – rack middleware examples) are available on Google sites for download.

There was no time to speek about Tamanegi – my feeds aggregator in Ramaze , but maybe on some other meeting…

There are also another two presentations:

“5 ways to run Ruby on Rails web applications”

by okkez-san

presentation slides

Benchmarking CGI, FastCGI, mod_ruby, mod_rails and mongrel_cluster. Received very good documentation with configs for all mentioned deployment options.

Okkez-san is using Rabbit – very cool presentation tool, written in Ruby! Just needed ruby-gnome. Will try it soon maybe.

Some notes:

  • ebb is still a pain to install
  • mod_ruby is not bad deployment option
  • webrick overperforms fastcgi for simple installs (still a valuable option for intranet for example)
  • thin is fast

I think thin is faster because of the underlaying EventMachine TCP stack implementation in C. The others are just pure Ruby-based, so there is nothing to compare for simple requests (ab benchmarks).

“Agile web posting with Ruby”

by ujihisa-san

presentation slides

There are sooooo many web services around. Can the posting to them be automated, using Ruby-based tools?

!!! Big Fat Warning: The presented tools will make you very ‘productive’. Maybe your friends will stop following you. Use on your own risk! ;)

Main working horse – www:mechanize ruby port :

gem install mechanize

So far so good. But can you post directly from VIM? Seems there is vimscript – i way to customize vim in different languages. Try:

vim --version

and if you see +ruby you can use ruby in vimscripts like:

# ~/.vim/plugins/some_plugin.vim
...
VIM.evaluate(’..’) evaluate %[sdfsds]
...

And even better: there are already a lot of ready ruby-based VIM plugins in the CodeRepos vim repository

20th “Ruby for beginners” lesson

With a ‘little’ help from google my answers was:

FizzBuzz

(‘Aho’,’Bow’ and also say ‘Aho’ for numbers that contain ‘3’):

puts (1..100).map { |i| (s=(i%3==0?'Aho':'')+(i%5==0?'Bow':'')+(i.to_s =~ /3/?'Aho':''))==""?i:s }

99 bottles of beer

I like Jeremy Voorhis’ implementation . Just modified it to handle 1 bottle situation:

#!/usr/bin/env ruby

def expensive
  @expensive ||=
    begin
      n = 99
      buf = ""
      begin
        buf << "#{n} bottle#{n>1?'s':''} of beer on the wall\n"
        n -= 1
      end while n > 0
      buf << "no more bottles of beer"
    end
end

puts expensive

‘X-Sendfile’ for Rack , take 2

Posted by on 11-May-2008

In the spirit of “Fork me if you like me” I forked the Rack project on github and applied my ‘X-Sendfile’ related changes. Now you can have download acceleration with:

use Rack::Static, :urls => ["/files"], :root => "public",
    :extra => { 'X-Sendfile' => 'yes' }

I just made a small change to pass the extra parameter down to Rack::File and adding ‘X-Sendfile’ related headers for nginx, apache and lighttpd.
extra parameter can also contain others, non x-sendfile related headers (like cache-control etc.):

use Rack::Static, :urls => ["/css","/images"], :root => "public", :extra => {
  'Cache-Control' => 'max-age=86400, public',
  'Expires' => (Time.now + 86400).utc.rfc2822
}

I also added some examples for rackup and middleware to the examples/ directory. Merged the josh’s daemonize fork too, but today (11-May-2008) it was merged to the master branch.