Created
May 19, 2010 05:47
-
-
Save zenhob/405992 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
#!/usr/bin/env ruby -rubygems | |
require 'faraday' | |
require 'trollop' | |
require 'fileutils' | |
class ZenDesk2Tender | |
include FileUtils | |
attr_reader :opts, :conn | |
EXPORT_DIR = '.export-data' | |
def initialize | |
@author_email = {} | |
@opts = Trollop::options do | |
banner <<-EOM | |
Usage: | |
#{$0} -e <email> -p <password> -s <subdomain> | |
Prerequisites: | |
# Ruby gems | |
gem install faraday -v "~>0.4.5" | |
gem install trollop | |
gem install yajl-ruby | |
# Python tools (must be in your PATH) | |
html2text.py: http://www.aaronsw.com/2002/html2text/ | |
Options: | |
EOM | |
opt :email, "user email address", :type => String | |
opt :password, "user password", :type => String | |
opt :subdomain, "subdomain", :type => String | |
end | |
[:email, :password, :subdomain ].each do |option| | |
Trollop::die option, "is required" if opts[option].nil? | |
end | |
if `which html2text.py`.empty? | |
puts 'missing prerequisite: html2text.py is not in your PATH' | |
exit | |
end | |
@conn = Faraday::Connection.new("http://#{opts[:subdomain]}.zendesk.com") do |b| | |
b.adapter :net_http | |
b.response :yajl | |
end | |
conn.basic_auth(opts[:email], opts[:password]) | |
end | |
def export_users | |
response = conn.get('users.json') | |
if response.success? | |
dir_name = File.join(EXPORT_DIR,'users') | |
mkdir_p dir_name | |
response.body.each do |user| | |
File.open(File.join(dir_name, "#{user['email'].gsub(/\W+/,'_')}.json"), "w") do |file| | |
@author_email[user['id']] = user['email'] | |
file.puts(Yajl::Encoder.encode( | |
:name => user['name'], | |
:email => user['email'], | |
:created_at => user['created_at'], | |
:updated_at => user['updated_at'], | |
:state => %w[user support support][user['roles']] | |
)) | |
end | |
end | |
else | |
puts "failed to get users:" | |
puts response.inspect | |
end | |
end | |
def export_categories | |
response = conn.get('forums.json') | |
if response.success? | |
dir_name = File.join(EXPORT_DIR,'categories') | |
mkdir_p dir_name | |
response.body.each do |forum| | |
File.open(File.join(dir_name, "#{forum['id']}.json"), "w") do |file| | |
file.puts(Yajl::Encoder.encode( | |
:name => forum['name'], | |
:summary => forum['description'] | |
)) | |
end | |
export_discussions(forum['id']) | |
end | |
else | |
puts "failed to get categories:" | |
puts response.inspect | |
end | |
end | |
def author_email user_id | |
@author_email[user_id] ||= begin | |
# the cache should be populated during export_users but we'll attempt | |
# to fetch unrecognized ids just in case | |
conn.get("users/#{user_id}.json").body['email'] rescue nil | |
end | |
end | |
def dump_body entry, body | |
File.open(File.join("tmp", "#{entry['id']}_body.html"), "w") do |file| | |
file.write(body) | |
end | |
end | |
def load_body entry | |
`html2text.py /$PWD/tmp/#{entry['id']}_body.html` | |
end | |
def export_discussions forum_id | |
response = conn.get("forums/#{forum_id}/entries.json") | |
if response.success? | |
dir_name = File.join(EXPORT_DIR,'categories', forum_id.to_s) | |
mkdir_p dir_name | |
mkdir_p 'tmp' | |
response.body.each do |entry| | |
File.open(File.join(dir_name, "#{entry['id']}.json"), "w") do |file| | |
comments = entry['posts'].map do |post| | |
dump_body entry, post['body'] | |
{ | |
:body => load_body(entry), | |
:author_email => author_email(post['user_id']), | |
:created_at => post['created_at'], | |
:updated_at => post['updated_at'], | |
} | |
end | |
dump_body entry, entry['body'] | |
file.puts(Yajl::Encoder.encode( | |
:title => entry['title'], | |
:comments => [{ | |
:body => load_body(entry), | |
:author_email => author_email(entry['submitter_id']), | |
:created_at => entry['created_at'], | |
:updated_at => entry['updated_at'], | |
}] + comments | |
)) | |
rm "tmp/#{entry['id']}_body.html" | |
end | |
end | |
else | |
puts "failed to get entries for forum #{forum_id}:" | |
puts response.inspect | |
end | |
end | |
def create_archive | |
export_file = "export_#{opts[:subdomain]}.tgz" | |
system "tar -zcf #{export_file} -C #{EXPORT_DIR} ." | |
system "rm -rf #{EXPORT_DIR}" | |
puts "created #{export_file}" | |
end | |
def self.run | |
exporter = new | |
exporter.export_users | |
exporter.export_categories | |
exporter.create_archive | |
end | |
end | |
ZenDesk2Tender.run |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment