Skip to content

Instantly share code, notes, and snippets.

@niku
Created March 19, 2009 11:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save niku/81758 to your computer and use it in GitHub Desktop.
Save niku/81758 to your computer and use it in GitHub Desktop.
# -*- coding: utf-8 -*-
# How To Use
#
# required three sources
# +-idm2kpx.rb(this)
# +-idm_parser.rb
# +-idm.xml('ID Manager' exported)
#
# %ruby idm2kpx.rb idm.xml keypassx.xml
#
module Idm2Kpx
class Database
require 'idm_parser'
require 'rexml/document'
def initialize idm_filename
@idm = IdmParser::IdmData.new(idm_filename)
@kpx = REXML::Document.new
@kpx = @kpx.add_element('database')
make_groups
end
def write keypassx_filename
File.open(keypassx_filename, 'w'){|f| f.write @kpx.to_s}
end
private
def make_groups
@idm.folders.each do |folder|
group = Group.new(folder)
@kpx.add_element(group.element)
end
end
end
class Group
attr_reader :element
def initialize folder
@folder = folder
@element = REXML::Element.new('group')
@element.add_element('title').add_text(folder.attributes['name'])
@element.add_element('icon').add_text('1')
add_items
@element
end
private
def add_items
@folder.items.each do |item|
entry = Entry.new(item)
@element.add_element(entry.element)
end
end
end
class Entry
require 'date'
attr_reader :element
def initialize item
@element = REXML::Element.new('entry')
@element.add_element('title').add_text(item.attributes['name'])
@element.add_element('username').add_text(item.account.text)
@element.add_element('password').add_text(item.password.text)
@element.add_element('url').add_text(item.url.text)
comments = [
"item1#{item.item1.attributes['name']}=#{item.item1.text}",
"item2#{item.item2.attributes['name']}=#{item.item2.text}",
"serialNumber=#{item.serial_number.text}",
"e-mail=#{item.e_mail.text}",
"file=#{item.file.text}"
]
@element.add_element('comment').add_text(comments.join("\n"))
@element.add_element('icon').add_text('0')
@element.add_element('creation').add_text(Date.parse(item.issue_date.text).to_s)
@element.add_element('lastaccess').add_text(Date.parse(item.issue_date.text).to_s)
@element.add_element('lastmod').add_text(Date.parse(item.issue_date.text).to_s)
@element.add_element('expire').add_text('Never')
@element
end
end
end
if __FILE__ == $0
base = Idm2Kpx::Database.new(ARGV[0].to_s)
base.write(ARGV[1].to_s)
end
# -*- coding: utf-8 -*-
module IdmParser
require 'rexml/document'
require 'forwardable'
class IdmData
extend Forwardable
def_delegators :@xml, :elements, :attributes
def initialize filename
@xml = REXML::Document.new(File.new(filename))
end
# TODO folders以外も気が向いたら作る
def folders
@xml.get_elements('/idmData/folder').map{|folder| Folder.new(folder)}
end
end
class Folder
extend Forwardable
def_delegators :@xml, :elements, :attributes
def initialize xml
@xml = xml
end
def items
@xml.get_elements('item').map{|item| Item.new(item)}
end
end
class Item
extend Forwardable
def_delegators :@xml, :elements, :attributes
def initialize xml
@xml = xml
end
def account
@xml.elements['account']
end
def password
@xml.elements['password']
end
def item1
@xml.elements['item1']
end
def item2
@xml.elements['item2']
end
def serial_number
@xml.elements['serialNumber']
end
def comment
@xml.elements['comment']
end
def url
@xml.elements['url']
end
def e_mail
@xml.elements['e-mail']
end
def file
@xml.elements['file']
end
def issue_date
@xml.elements['issueDate']
end
def expiration_date
@xml.elements['expirationDate']
end
def paste_type
@xml.elements['pasteType']
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment