Last active
December 17, 2015 13:59
-
-
Save hara/5620760 to your computer and use it in GitHub Desktop.
Friends Note の CSV を Google Contacts の Google CSV 形式に変換するスクリプト
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# coding: utf-8 | |
require 'csv' | |
module GoogleContacts | |
class Contacts | |
attr_reader :cards | |
def initialize | |
@cards = [] | |
end | |
def header | |
fields = [] | |
fields << 'Given Name' | |
fields << 'Additional Name' | |
fields << 'Family Name' | |
fields << 'Given Name Yomi' | |
fields << 'Additional Name Yomi' | |
fields << 'Family Name Yomi' | |
fields << 'Name Prefix' | |
fields << 'Name Suffix' | |
fields << 'Nickname' | |
fields << 'Notes' | |
fields << 'Group Membership' | |
1.upto(email_header_length).each do |i| | |
fields << "E-mail #{i} - Type" | |
fields << "E-mail #{i} - Value" | |
end | |
1.upto(im_header_length).each do |i| | |
fields << "IM #{i} - Type" | |
fields << "IM #{i} - Service" | |
fields << "IM #{i} - Value" | |
end | |
1.upto(phone_header_length).each do |i| | |
fields << "Phone #{i} - Type" | |
fields << "Phone #{i} - Value" | |
end | |
1.upto(address_header_length).each do |i| | |
fields << "Address #{i} - Type" | |
fields << "Address #{i} - Street" | |
fields << "Address #{i} - City" | |
fields << "Address #{i} - PO Box" | |
fields << "Address #{i} - Region" | |
fields << "Address #{i} - Postal Code" | |
fields << "Address #{i} - Country" | |
end | |
1.upto(organization_header_length).each do |i| | |
fields << "Organization #{i} - Type" | |
fields << "Organization #{i} - Name" | |
fields << "Organization #{i} - Yomi Name" | |
fields << "Organization #{i} - Title" | |
fields << "Organization #{i} - Department" | |
fields << "Organization #{i} - Symbol" | |
fields << "Organization #{i} - Location" | |
fields << "Organization #{i} - Job Description" | |
end | |
fields | |
end | |
def records | |
rows = [] | |
rows << header | |
cards.each do |card| | |
fields = [] | |
fields << card.given_name | |
fields << card.additional_name | |
fields << card.family_name | |
fields << card.given_name_yomi | |
fields << card.additional_name_yomi | |
fields << card.family_name_yomi | |
fields << card.name_prefix | |
fields << card.name_suffix | |
fields << card.nickname | |
fields << card.notes | |
fields << card.group | |
card.emails.each do |email| | |
fields << email.type | |
fields << email.value | |
end | |
1.upto(email_header_length - card.emails.length).each do | |
fields << '' << '' | |
end | |
card.ims.each do |im| | |
fields << im.type | |
fields << im.service | |
fields << im.value | |
end | |
1.upto(im_header_length - card.ims.length).each do | |
fields << '' << '' << '' | |
end | |
card.phones.each do |phone| | |
fields << phone.type | |
fields << phone.value | |
end | |
1.upto(phone_header_length - card.phones.length).each do | |
fields << '' << '' | |
end | |
card.addresses.each do |address| | |
fields << address.type | |
fields << address.street | |
fields << address.city | |
fields << address.pobox | |
fields << address.region | |
fields << address.postal | |
fields << address.country | |
end | |
1.upto(address_header_length - card.addresses.length).each do | |
fields << '' << '' << '' << '' << '' << '' << '' | |
end | |
card.organizations.each do |organization| | |
fields << organization.type | |
fields << organization.name | |
fields << organization.yomi_name | |
fields << organization.title | |
fields << organization.department | |
fields << organization.symbol | |
fields << organization.location | |
fields << organization.description | |
end | |
1.upto(organization_header_length - card.organizations.length).each do | |
fields << '' << '' << '' << '' << '' << '' << '' << '' | |
end | |
rows << fields | |
end | |
rows | |
end | |
private | |
def email_header_length | |
self.cards.max_by { |card| card.emails.length }.emails.length | |
end | |
def im_header_length | |
self.cards.max_by { |card| card.ims.length }.ims.length | |
end | |
def phone_header_length | |
self.cards.max_by { |card| card.phones.length }.phones.length | |
end | |
def address_header_length | |
self.cards.max_by { |card| card.addresses.length }.addresses.length | |
end | |
def organization_header_length | |
self.cards.max_by { |card| card.organizations.length }.organizations.length | |
end | |
end | |
class Email | |
attr_accessor :type, :value | |
end | |
class IM | |
attr_accessor :type, :service, :value | |
end | |
class Phone | |
attr_accessor :type, :value | |
end | |
class Address | |
attr_accessor :type, | |
:street, | |
:city, | |
:pobox, | |
:region, | |
:postal, | |
:country | |
end | |
class Organization | |
attr_accessor :type, | |
:name, | |
:yomi_name, | |
:title, | |
:department, | |
:symbol, | |
:location, | |
:description | |
end | |
class Card | |
attr_accessor :given_name, | |
:additional_name, | |
:family_name, | |
:given_name_yomi, | |
:additional_name_yomi, | |
:family_name_yomi, | |
:name_prefix, | |
:name_suffix, | |
:nickname, | |
:notes, | |
:group | |
attr_reader :emails, | |
:ims, | |
:phones, | |
:addresses, | |
:organizations | |
def initialize | |
@emails = [] | |
@ims = [] | |
@phones = [] | |
@addresses = [] | |
@organizations = [] | |
end | |
def add_email(type, value) | |
email = Email.new | |
email.type = type | |
email.value = value | |
emails << email | |
end | |
def add_im(type, service, value) | |
im = IM.new | |
im.type = type | |
im.service = service | |
im.value = value | |
ims << im | |
end | |
def add_phone(type, value) | |
phone = Phone.new | |
phone.type = type | |
phone.value = value | |
phones << phone | |
end | |
end | |
end | |
def fields_empty?(row, *labels) | |
labels.all? { |label| row[label] == "" } | |
end | |
include GoogleContacts | |
if ARGV.length != 2 | |
abort 'Usage: ruby fn2google.rb FriendsNote_export_yyyymmddHHMMSS.csv output.csv' | |
end | |
contacts = Contacts.new | |
CSV.foreach(ARGV[0], encoding: 'Shift_JIS:UTF-8', headers: true) do |row| | |
card = Card.new | |
card.given_name = row['名'] | |
card.given_name_yomi = row['名(フリガナ)'] | |
card.additional_name = row['ミドルネーム'] | |
card.additional_name_yomi = row['ミドルネーム(フリガナ)'] | |
card.family_name = row['姓'] | |
card.family_name_yomi = row['姓(フリガナ)'] | |
card.name_prefix = row['プリフィックス'] | |
card.name_suffix = row['サフィックス'] | |
card.nickname = row['ニックネーム'] | |
card.notes = row['メモ'] | |
card.group = 1.upto(10).map { |i| row["グループ#{i}"] }.delete_if { |group| group == "" }.join(' ::: ') | |
1.upto(10).each do |i| | |
next if fields_empty?(row, | |
"メールアドレス#{i}の属性", | |
"メールアドレス#{i}") | |
card.add_email(row["メールアドレス#{i}の属性"], | |
row["メールアドレス#{i}"]) | |
end | |
1.upto(10).each do |i| | |
next if fields_empty?(row, | |
"IM#{i}の属性", | |
"IMアカウント#{i}", | |
"IM#{i}のプロトコル種別") | |
card.add_im(row["IM#{i}の属性"], | |
row["IM#{i}のプロトコル種別"], | |
row["IMアカウント#{i}"]) | |
end | |
1.upto(10).each do |i| | |
next if fields_empty?(row, | |
"電話番号#{i}の属性", | |
"電話番号#{i}") | |
card.add_phone(row["電話番号#{i}の属性"], | |
row["電話番号#{i}"]) | |
end | |
1.upto(10).each do |i| | |
next if fields_empty?(row, | |
"住所#{i}の属性", | |
"住所#{i}(郵便番号)", | |
"住所#{i}(国)", | |
"住所#{i}(県)", | |
"住所#{i}(市区町村)", | |
"住所#{i}(番地)", | |
"住所#{i}(部屋番号)", | |
"住所#{i}(私書箱)") | |
address = Address.new | |
address.type = row["住所#{i}の属性"] | |
address.postal = row["住所#{i}(郵便番号)"] | |
address.country = row["住所#{i}(国)"] | |
address.region = row["住所#{i}(県)"] | |
address.city = row["住所#{i}(市区町村)"] | |
address.street = row["住所#{i}(番地)"] + "\n" + row["住所#{i}(部屋番号)"] | |
address.pobox = row["住所#{i}(私書箱)"] | |
card.addresses << address | |
end | |
1.upto(10).each do |i| | |
next if fields_empty?(row, | |
"企業#{i}の属性", | |
"企業#{i}(企業名)", | |
"企業#{i}(肩書)", | |
"企業#{i}(所在地)", | |
"企業#{i}(会社名フリガナ)", | |
"企業#{i}(部署名)", | |
"企業#{i}(職種)", | |
"企業#{i}(会社名略称)") | |
organization = Organization.new | |
organization.type = row["企業#{i}の属性"] | |
organization.name = row["企業#{i}(企業名)"] | |
organization.title = row["企業#{i}(肩書)"] | |
organization.location = row["企業#{i}(所在地)"] | |
organization.yomi_name = row["企業#{i}(会社名フリガナ)"] | |
organization.department = row["企業#{i}(部署名)"] | |
organization.description = row["企業#{i}(職種)"] | |
organization.symbol = row["企業#{i}(会社名略称)"] | |
card.organizations << organization | |
end | |
contacts.cards << card | |
end | |
CSV.open(ARGV[1], 'wb') do |csv| | |
contacts.records.each do |record| | |
csv << record | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment