SUUIDs

Observations — Tags: , , , — Ardekantur @ 6:26 pm

Mostly this is just farting around but I thought I’d post about it because it’s an interesting idea, at least in theory.

GUIDs are good but I wanted to do one better. So I created SUUIDs. Super Universally Unique IDs. The format of the current version, v2.0, is thus:

2/xxxxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxx-xxxx

Where x is a case-sensitive alphanumeric character. This gives us somewhere in the area of 3.35×10^64 possible combinations, and a lot of interesting characteristics.

  • For example, if the address space of a given ID is all hexadecimal, and the last four characters are IPv6, this functions just as well as an IPv6 address format. Thus, The IPv6 address 2001:0db8:0000:0000:0000:0000:1428:57ab is notated as 2/20010db8-00000000-00000000-142857ab-IPv6. If a field contains all the same character, you can replace the ending hyphen with a comma and the field with a single instance of that character, so that IP address could also be 2/20010db8-0,0,142857ab-IPv6.
  • In the same token, the same rules apply to a message that ends in 0MD5 — that’s an MD5 checksum as well as a unique address.

An implementation in Ruby:

	module SUUID
	  def self.gen
	   chars = ("a".."z").to_a + ("1".."9").to_a + ("A".."Z").to_a
	   x = [8, 8, 8, 8, 4]
	   x.map! {|i| i = Array.new(i, '').collect{chars[rand(chars.size)]}.join }
	   return "2/" + x.join('-')
	  end
	end

It’s not pretty, but it gets the job done. You could always throw a more random source of entropy at it, use the system date, time, whatever. Don’t particularly care about the implementation.

Here’s what a couple look like — to get used to the idea :-)

2/f9nuBgzm-HGTE4bSK-ZEfkfsRp-T3SXgpXA-5LNC
2/hoyOCd7o-V48NQGvv-OS5RBDIl-CG1FRNqG-Xd3j
2/sUZd6aGa-1J55rs9C-lxH1mvPA-I9PAvkOh-ZLVj

Additionally, you can omit the version number, which so far still allows for distinction between version 1 and version 2 (version 1 didn’t have lowercase letters). This means you have a nice set of directory names at your disposal.

mkdir /DOMejDTy-APESCioG-yyXpXBNL-lYAuQogL-Uep9
mkdir `curl -X POST http://example.com/suuid/provider`

I have no idea how checksums, hashes, verified randomness all fit into something like this. Just something fun and stupid to keep me occupied today.

Taskomaly 0.1.0 Released

Code Projects — Tags: , , — Ardekantur @ 9:08 pm

Taskomaly Logo

So, yeah. Taskomaly 0.1.0 (now 0.1.1 to deal with some things) is released, but I’m not too happy about it. It’s a very confining release. Here’s what you need to know, things that are implicit in the code, but not in the documentation.

  • Project names are converted into symbols for no real reason, but they lose their formatting in the process. “My IBM Project” will become :my_ibm_project, which will then get transformed into “My ibm project:” when the project name is formatted for a task file.
  • Comments are ignored and not parsed, and not brought into a formatted task file.

I think that’s it, but those are constricting things nonetheless. Tests pass, but only because I use special cases for these things. I know. I’m ashamed. I’m going to add better criteria for all the tests, and stick it out until the next release.

But basically anything that you want to do with papers, projects, and tasks is available for you. The README explains how to integrate it with Tasko.

Right. The whole thing needs an overhaul API wise. Already. I’m not sure if that’s a function of my using TDD naively, or if I’m just a bad programmer. Let’s say a little bit of both.

In any event, what there is, is well-documented. On top of that, if you have any issues or test cases you want to provide, throw them to me at my Lighthouse project for Taskomaly. Things like that would be wonderfully appreciated, since this is the sort of project that builds itself based on the most common habits of the people who use it.

Enjoy!

$ gem sources -a http://gems.github.com
$ sudo gem install ardekantur-taskomaly

If you get any version from GitHub that’s not 0.1.1, wait a couple minutes and try again. GitHub says it takes up to ten minutes to propagate a gem change, and I haven’t been keeping track of time.

Generating Multiple RSpec Files from a Design Document

Ruby, Software Tweaking, Test Driven Development, YAML — Tags: , , , , — Ardekantur @ 10:55 pm

Taking queues from Adam Wiggin’s first commit to his Rush project, simply a design document and some specs, and Err the Blog’s post about BDD and generating specs from YAML, I’ve written a small Rake task that will take a single file design document in YAML and separate it out into the components you specify. For example:

spec/design.yml

Website Integration:
    - should be able to log in from the front page and land at your profile
 
OpenID module:
    - should accept an OpenID URL
    - should return an error message if the URL cannot be reached
 
User:
    - should have a valid user name
    - should return an error if creating a duplicate user name is attempted

And then:

rake design

Takes the section headers, and flattens them as the filenames. So this particular design creates three different files, website_integration_spec.rb, openid_module_spec.rb, and user_spec.rb. They’ll look like this:

spec/user_spec.rb

require File.dirname(__FILE__) + '/spec_helper'
 
describe 'User' do
 
  it 'should have a valid user name'
  it 'should return an error if creating a duplicate user name is attempted'
 
end

And just like that, you have your specs, ready to go!

Here it is:

Please note that it will destroy those files if they already exist, replacing them! I really don’t care if you lose your existing specs! Back them up if you want to try this! You have been warned! This is more of a technique for a brand new project, anyway.

Also, please note that I’ve embedded the rake task as a GitHub Gist paste, so feel free to fork it and modify it. I’d be interested in seeing cleaner, more interesting implementations of my 30-second hack. Additionally, please choose view raw if you want to copy it, seeing as how GitHub seems to bork on a newline character in the code snippet.

Phusion, Rack, Sinatra, and sub-domains

I’ve spent the past couple of hours futzing around with Sinatra and Rack being hooked up to the latest Phusion Passenger, and I’ve come across a bizarre problem. Let’s see what I can illustrate.

I have a Slicehost VPS, and I threw a DynDNS address at it because I didn’t feel like registering a domain name for something that was essentially supposed to be a playground. I set it up so that subdomains would also get redirected to my slice, since I didn’t want Phusion interfering with some PHP, Trac, and SVN stuff I also have running on it. My configuration basically looks like this:

/etc/apache2/sites-available/phusion-passenger

<VirtualHost *:80>
        ServerAdmin webmaster@localhost
        ServerName  projects.example.com
        DocumentRoot /var/projects
        <Directory /var/projects>
                Options -Indexes
        </Directory>
        RackBaseURI /sinatra_test
</VirtualHost>

Then I set up /webapps/sinatra_test, along with the latest version of Sinatra, as outlined on the “Bleeding Edge” section of the Sinatra website. The Phusion Passenger documentation provides instructions on the proper way to format your Rack directories, which includes a tmp directory, a public directory, and a config.ru. Add my actual Sinatra application, and I have a setup that looks like this:

root@slice:/webapps/sinatra_test# ls -l
total 16
-rw-r--r-- 1 www-data www-data  326 Jul 27 15:19 config.ru
-rw-r--r-- 1 www-data www-data  235 Jul 27 15:44 myapp.rb
drwxr-xr-x 2 www-data www-data 4096 Jul 27 05:54 public
lrwxrwxrwx 1 www-data www-data   10 Jul 27 06:13 sinatra -> ../sinatra
drwxr-xr-x 2 www-data www-data 4096 Jul 27 15:46 tmp

All good to go, right? You’d think. There’s some bizarre things going on with Phusion, or Rack, or Sinatra, in terms of discerning correct actions and mapping them to URL endpoints.

My Sinatra application:

myapp.rb

  $:.unshift File.dirname(__FILE__) + '/sinatra/lib'
  require 'sinatra'
 
  get '' do
    "Rootless test"
  end
 
  get '/' do
    "Root test"
  end
 
  get '/other' do
    "Other application part"
  end
 
  get '/other/' do
    "This is a different endpoint"
  end

As well as the config.ru I’m using for it:

config.ru

  $:.unshift File.dirname(__FILE__) + '/sinatra/lib'
  require 'sinatra'
 
  Sinatra::Application.default_options.merge!(
    :run => false,
    :env => :development,
    :raise_errors => true,
    :app_file => 'myapp.rb'
  )
 
  log = File.new("sinatra.log", "a")
  STDOUT.reopen(log)
  STDERR.reopen(log)
 
  require 'myapp'
  run Sinatra.application

And this is what I get when I play with curl.

~ $ curl http://projects.example.com/sinatra_test/other
Other application part

~ $ curl http://projects.example.com/sinatra_test/other/
This is a different endpoint

~ $ curl http://projects.example.com/sinatra_test
Rootless test

~ $ curl http://projects.example.com/sinatra_test/
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /sinatra_test/
on this server.</p>
...

What’s going on? other and other/ are considered different endpoints, which makes sense, I imagine. I’m not an HTTP wizard. Even if the root of the sinatra_test directory and the same root with an ending slash are considered different endpoints, then why wouldn’t I be able to access the latter? Especially with it defined explicitly in my Sinatra application? Even more, especially since if this was a distinction, as in the case of other and other/, but isn’t working the same way for the root URL?

Curioser and curioser. I have no idea if the problem is with Sinatra, Rack, Phusion, or my Apache configuration, and I’ve played around with omitting or specifying explicitly an ending forward slash for the DocumentRoot and RackBaseURI. Some of you may point out that I’ve specified -Indexes for the VirtualHost configuration, but if that isn’t specified, then navigating to http://projects.example.com/sinatra_test/ generates an empty directory listing, since it is pointing to my empty public folder.

So that’s where I am. Any insight would be appreciated, but I’ll keep hacking at it.

EDIT Well, there’s some relief for me - disabling mod_autoindex in Apache does the trick. I’m still not sure how I feel about the two endpoints — one with trailing slash and one with — being distinct, but at least there’s a viable solution. If you don’t have a reason to use mod_autoindex, disable it, and it will stop the interference. If you do need it, I’m not entirely sure what you would do.

Taskomaly Keeps Chugging Along

Code Projects — Tags: , — Ardekantur @ 12:26 pm

Straight from the readme:

you need to clean your room

make it a project

 proj = Taskomaly::Project.new 'Room Cleaning'

add some tasks to it

 proj.add 'put away clean laundry'
 proj.add 'wash dirty dishes'

tag those suckas up

 proj.add 'file taxes @april @15'
 proj.tasks.last.tags                   # [:april, :"15"]
 
 proj.add 'organize shelf'
 proj.tasks.last.tag :knickknacks, 1000, 'september'
 proj.tasks.last.tags                   # [:knickknacks, :"1000", :september]

EDIT As usual, I omit all the pertinent information. You can see the code here and attempt to install the gem with instructions from my previous blog entry.

Next Page »
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License.
(c) 2008 Ardekantur | powered by WordPress with Barecity