Thursday, November 02, 2006

Some interesting Ruby Code

Just so I don't forget, this has some good examples of reading and scanning files and building a new config file out of it. Incidentally, this creates a Django admin interface from a RoR schema.rb file. But that is not the purpose of me posting it here, this is more as a future reference type thingy. :)

The same thing, in nice ruby syntax hightlighted form is available at "Rails to Django" pastie.

#!/usr/local/bin/ruby

def tablize(word)
a = word.split(/_/).map {|l| l.capitalize}.join("")
a[-1].chr[/s/i] ? a[0..-2] : a
end

def args_mapper(args)
@float = nil
hash = args.split(/,\s+/).inject({}) do |hsh, cur|
key, value = cur.split(" => ")
key.strip!
key = key[/^:/] ? key[1..-1] : key
value = value.capitalize if ["true", "false"].include?(value)
@float = true if key.eql?("default") and value[/^\d+\.\d+$/] and @float.nil?
case key
when "limit"
hsh["maxlength"] = value
else
hsh[key] = value unless value.empty?
end
hsh
end
if @float
hash["max_digits"] = hash.delete("maxlength")
hash["decimal_places"] = 2
end
hash
end

def column_mapper(column)
case column
when "string"
column = "Char"
when "datetime"
column = "DateTime"
else
column = tablize(column)
end
column + "Field"
end

def mapper(line)
line.scan(/t.column\s+"(\w+)".*?:(\w+),?(.*)/) do |column, column_type, args|
if fk = column[/(\w+)_id/, 1]
return [fk, "ForeignKey", "'%s'" % tablize(fk)]
end
return [column, column_mapper(column_type), args_mapper(args)]
end
end

schema = IO.read("schema.rb")
django = ["from django.db import models", "import datetime"]
schema.scan(/create_table\s(.*?)end/m).flatten.each do |chunk|
chunk.scan(/(\w+)",\s:force\s=>\strue\sdo\s\|t\|\n(.*)$/m).each do |table, data|
django << "class %s(models.Model):" % tablize(table)
data.chomp.split("\n").each do |line|
column, column_type, args = mapper(line)
args["maxlength"] = 255 if column_type.eql?("CharField") and args["maxlength"].nil?
unless column.nil? or column_type.nil? or args.nil?
@first = column if @first.nil? and not column_type.eql?("ForeignKey")
args = args.is_a?(Hash) ? args.map {|k, v| "%s=%s" % [k, v]}.join(", ") : args
django << " %s = models.%s(%s)" % [column, column_type, args]
end
end
django << " class Meta:"
django << " db_table = '%s'" % table
django << " class Admin:"
django << " pass"
unless @first.nil?
django << " def __str__(self):"
django << " return self.%s" % @first
end
end
django << "\n\n"
@first = nil
end

open("django.txt", "w+") do |file|
file.write(django.join("\n"))
end

0 comments: