Home > Uncategorized

Uncategorized Archive

Rubigraph

Summary

I wrote a Rubigraph, a Ruby wrapper for Ubigraph .

What is Ubigraph

I recently found Ubigraph, a nice visualization tool. Though I’m also big fan of Graphviz, which generates static graph visualization, I got falling in love with Ubigraph because it’s so dynamic. Ubigraph can add, remove and change nodes, edges, and their attributes. It’s amazing! See demonstration movie.

It is based on client/server architecture. Though the server source code is closed, its XML-RPC API is open, and we can write our client application easily. It has Mac OS X and Linux binaries.

What is Rubigraph

But, I cannot put up with writing XML-RPC by referencing API manual every time ! So I made a small Ruby wrap for it, and released it as Rubigraph.

Install

Type gem install rubygraph. Its place in Rubyforge is here.

Source code

How do I write a graph

require 'rubigraph'
 
Rubigraph.init        # initialize XML-RPC client.
 
v1  = Vertex.new
v2  = Vertex.new
e12 = Edge.new(v1, v2)
 
v1.color  = '#003366'
v2.shape  = 'sphere'
e12.label = 'edge between 1 and 2'

It seems easy, isn’t it?

Conclusion

It’s a fun to visualize some data dynamically. I’m using it for tracing function calls, feeling so convinient. Ubigraph++.

IDAvailability

I made a small web application, IDAvailability that checks how available the entered ID is in the world.

Web services

I added only 8 web services at the begenning. However, web service information is stored in wedata, a wiki-like data store that everyone can edit, everybody can add web services to it (for now, 28 web services has been added). Database is here.

You can add a web service from Create New Item, and enter following information.

  • name : name of web service (any)
  • urlToCheck : URL embedded #{ID} variable (like http://nantokakanto.ka/user/#{ID})
  • condition : a XPath expression to check whether the ID is used when the server response is HTTP 200 , not ”404 Not Found” while accessing urlToCheck. (for example, see flickr)

Code

ToDo

  • Move check functions to client-side (retrieving HTML via Ajax, examining XPath…)
  • Better looks

Try and enjoy it, also add your favorite web service missing.

Gainer++ - use Gainer from C++

I wrote a C++ wrapper library for Gainer, based on its Ruby library (gainer-ruby). The code is submitted to CodeRepos as Gainer++, here.

So Far

It supports following functions:

  • mode switch by constructor
  • analog inputs
  • digital inputs

It has some examples, like blinking LED on Gainer I/O module (gainer-led.cc).


Feel free to use, modify, and commit to it.

infowi.se

I was invited to join a project, named infowi.se, by a person who read this entry about QSTwitter. As I saw this, team consists of one European, two Americans, one Japanese (me). Wow, what an exciting opportunity!

So far I don’t know how it’s going, I’m feeling happy to contribute, make something special :)

started en.mootoh.log

Today, I decided to write English blog about my recent works (Japanese version is here). Hope you will enjoy it.

Write a Quicksilver plugin with RubyCocoa

I wrote a Quicksilver plugin with RubyCocoa, that adds “hello world” to the passed string.

  • Xcode project codes : in CodeRepos
  • License : revised BSD

It should work on Tiger/Leopard if RubyCocoa is installed.

How does it work

As I mentioned in QuartzComposer CustomPatch with RubyCocoa, we just call RBBundleInit() function in plugin initializaiton phase to write some plugin with RubyCocoa. But wait, where should be the initializaiton code in Quicksilver plugin ?

We write actual plugin behavior in the class that inherits QSActionProvider, so I tried to call RBBundleInit() in the init() method in that class… however, that resulted in crashing Quicksilver :(

Then I called RBBundleInit() at only first time in performActionOnObject() of the actual Action class, and made references between Objective-C and Ruby class instances.

After that, I implemented an actual action behavior in Ruby class, and delegates from Objective-C to Ruby method, thats’ all. This is ugly, confusing, … I know, but it does work well :)

Code Snippets

ActionProvider in Objective-C:

 (QSObject *)performActionOnObject:(QSObject *)dObject{
  // initialize RubyCocoa
  static bool loaded = false;
  if (!loaded) {
    if (RBBundleInit("qs_action.rb", [self class], self)) {
      NSLog(@"[RubyCocoaPluginAction.performActionOnObject] RBBundleInit failed"
);
      abort();
    }
    loaded = true;
  }
 
  // delegate actual action to Ruby class
  QSObject *ret = [QSObject objectWithString:[rb_ act:dObject]];
  return ret;
}

RubyCocoa side:

class Action
  def initialize(logger)
    @logger = logger
  end
 
  # write something great :)
  #  - arg : QSObject
  def act(arg)
    val = arg.stringValue
    @logger.info(val)
    'Hello world, ' + val
  end
end # Action
 
require 'osx/cocoa'
OSX.init_for_bundle do |bdl, owner, log|
  # bdl    - the bundle related with the 2nd argument of RBBundleInit
  # owner  - the 3rd argument of RBBundleInit as optional data
  # log    - logger for this block
 
  act = Action.new(log)
  owner.setInstance act
end

Future works

  • Better initializaiton. It should be in constractor of some class)
  • Inherits QSActionProvider by Ruby class (more pure Ruby)
  • Use ns_import ?

It should not be “With RubyCocoa”, but rather “By RubyCocoa”.

Conclusion

I made a start point to write a Quicksilver plugin by RubyCocoa. It is timing of initialization that is to be considered about writing some bundle in RubyCocoa. I made it in this article somehow. This article is for someone who wants to create Quicksilver plugin by Ruby, not learning unfamiliar Objective-C.

Reference

Ticket2RTM

A Trac plugin that synchronizes Trac tickets and Remember the Milk tasks.

  • when a ticket is created, a RTM task also will be added.
  • when you close a ticket, the associated RTM task will be completed.

Screenshot

Screencast

Download

ticket2rtm-0.1.zip

Benefits

  • unified Task List
  • check tickets from mobile

Install

build

  1. edit Makefile and set PLUGINS_DIR to your Trac plugin dir
  2. make

or:

  1. python setup.py –bdist_egg
  2. copy dist/TracTicket2RTMPlugin*.egg into your Trac plugin dir

RTM API key, token

This plugin requires RTM API key, shared secret, and write-permitted token. You can obtain your API key and shared secret from here.

After acquired key and shared secret, you can get your token by using bundled script. Run as follow:

% python get_token.py <API key> <shared secret>

Configuration

  1. copy/paste contents of trac_ini_sample.txt to your trac.ini
  2. set rtm_api_key, rtm_api_secret, rtm_api_token to ones acquired above
  3. enjoy !

Quicksilver Twitter Plugin

I wrote a small Quicksilver plugin to send messages to Twitter directly.

Advantages

  • Easy to install. No additional software required to be installed
  • Configurable via Quicksilver Preference
  • You can send messages containing non-ASCII characters

Download

QSTwitter.zip (1.2) (2008.01.23)

Environment

Tested under Leopard 10.5.1, Quicksilver B53 3814.

Install

Unzip the downloaded file and double-click it. that’s all !

Configuration

You will find “Twitter option” in the Quicksilver preference pane. Enter your screen name and password there.

Usage

  1. Activate Quicksilver (by Ctrl-SPACE or so)
  2. type . (period/dot) key to enter text input mode
  3. type a message
  4. hit TAB to move into Action
  5. type “Twitter”
  6. return !

The more familar you are with it, the faster you can send messages than ever.

Screencast

Seeing is Believing, as you know :) I don’t know why the video is collapsing for first 15 seconds. Sorry for inconvinience.

Code

You can see the code in CodeRepos.

License

Considering…

Restriction

  • I could not post messages throught HTTP proxy. Let me know if anyone succeeded to make it.

ChangeLog

  • 1.2 (2008.01.23) : fixes the bug that ‘+’ is not shown in status, uses pretty girl icon .
  • 1.1 (2007.12.22) : now it shows “QSTwitter” in your post on “from …” .
  • 1.0 (2007.12.13) : initial release.

There seems no comprehensive documents to develop Quicksilver plugin as far as I searched. In order to share my experience to avoid falling into pitfalls, I will write an tutorial developing a Quicksilver plugin under up-to-date environment later.

TwitterBot by Ruby

This tutorial describes how to write your own Twitter bot by Ruby.

Plan

  • Recieves DirectMessages, parses them and sends back responses.
  • Keeps on being connected in Twitter via Jabber protocol.
  • Written in Ruby !

Preparation

Twitter account

You need a twitter account for your bot.

Jabber ID

You need a Jabber ID for your bot to sit in Twitter. I use Jabber.JP service (free!), but you can choice whatever Jabber service you like.

If you use a GMail address for your bot, you can skip above step. (I could not connect to GTalk by GMail sub account, so took a different way)

Requirements

Code

#  Tiny Twitter Bot.
#
require 'rubygems'
require 'xmpp4r'
require 'kconv'
 
class Reciever
  attr_accessor :client
 
  # user : Jabber ID
  # pass : Password
  def initialize(user, pass)
    @end = false
    Jabber::debug = true
 
    # connect Jabber client to the Server
    @client = Jabber::Client.new(Jabber::JID.new(user), false)
    @client.connect
    @client.auth(pass)
    @client.send(Jabber::Presence::new)
 
    thread = Thread.current
 
    # a callback to parse recieved messages
    @client.add_message_callback do |message|
      unless message.type == :error
        if message.body =~ /Direct from (.*):/ # who sends DirectMessage ?
          sender = $1
          msg = message.body.split(/\r?\n/)
          msg.shift # cut Direct from ...
          msg.pop # cut last line, too
          body = msg.join
 
          # 
          # do whatever you like in following lines :)
          #
          if body =~ /!abort/ # finish if told 'abort'
            @client.send(Jabber::Message::new(message.from, "d #{sender} aborting...").set_type(:chat))
            thread.wakeup
          else
            # it just echoes in this example
            xxx = Kconv.toutf8("d #{sender}\n#{message.body}")
            @client.send(Jabber::Message::new(message.from, xxx).set_type(:chat))
          end # if body
        end # if direct
      end # unless error
    end # callback
 
    @watcher = Thread.new do
      while not @end
        # saying "I'm alive!" to the Jabber server
        @client.send(Jabber::Presence::new)
        sleep 30
      end
    end
  end
 
  def close
    @client.close
    @end = true
    @watcher.join
  end
end # Reciever

After that, the only step remains is to create this Reciever class instance from main routine. To kill the bot, send Ctrl-C from the command line.

Let’s do some neat hacks at the lines parsing body by regexp.

Auto Follow

You need to follow your bot.

You may want your bot to counter-follow you automatically. I wrote a simple Procmail recipe and a tiny Ruby script. (original idea is にぽたん研究所::Twitter でイチイチ follow するのが面倒くさい

Procmail recipe

.procmailrc:

:0
* ^To:.your@bot.address
| counter_follow.rb

Ruby script to follow

counter_follow.rb:

#!/opt/local/bin/ruby
require 'open-uri'
 
ID = 'jabber bot ID'
PASSWORD = 'jabber bot password'
 
msg = ARGF.read
msg =~ /\s+http:\/\/twitter.com\/(\w+)$/
screen_name = $1
exit 1 unless screen_name
 
auth = {'Authorization' => 'Basic '+[ID+':'+PASSWORD].pack('m')}
open('http://twitter.com/friendships/create/'+screen_name+'.json', auth)

Usage

  1. Follow your bot from you Twitter account.

    follow bot_account

  2. Send a DirectMessage to your bot.

    d bot_account hello bot !

Conclusion

Wrapped up a recipe how to create a tiny Twitter bot.

There were some pitfalls (it can hang up if you don’t send messages in ‘chat type’, cannot get any responses if you send something periodically, or …) in creating Twitter bot. I hope this tutorial help someone creating their own Twitter bot.


Any feedbacks make me happy :)

WordPress CalendarCloud plugin

What ?

A WordPress TemplateTag plugin that displays yearly calendars containing 12 months weighed by their post counts, like Tag Cloud.

Example

and, live demo is placed in the sidebar of this blog.

Download

calendar_cloud.zip (20KB)

Install

  1. Upload and unzip calendar_cloud.zip to the /wp-content/plugins/ directory
  2. Activate the plugin through the ‘Plugins’ menu in WordPress

Use css to customize look & feel. See an example in style.css.

Usage

put following line in your template:

<?php calendar_cloud(); ?>

ChangeLog

  • 0.2 : accordance with WordPress Coding Standard.
  • 0.1 : initial release.

Feel free to send any feedbacks.

Home > Uncategorized

Feeds

Return to page top