Skip to content

Instantly share code, notes, and snippets.

@garrettdimon
Created September 12, 2015 10:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save garrettdimon/17c188ee9d911c43305d to your computer and use it in GitHub Desktop.
Save garrettdimon/17c188ee9d911c43305d to your computer and use it in GitHub Desktop.
A basic script for downloading and saving attachments from a Sifter export file.
#!/usr/bin/env ruby
# To use this file, you'll need Ruby and Nokogiri installed.
# http://www.nokogiri.org
#
# If you're all set there simply place this file in the same folder as your
# Sifter export XML file and then run...
#
# `ruby fetch.rb`
#
# That will generate a folder and a set of subfolders for each project and all
# of its children issues *if* they have attachments. Otherwise, it skips
# any projects and issues that don't have attachments.
class SifterExport
require 'fileutils'
require 'nokogiri'
require 'open-uri'
include FileUtils
def self.create(name)
file_dir = "./#{name.gsub('.xml', '').downcase}"
create_directory(file_dir)
build_projects(file_dir, name)
end
def self.build_projects(file_dir, filename)
f = File.open("./#{filename}")
doc = Nokogiri::XML(f)
projects = doc.css("project")
companies = doc.css("company")
# Loop through the projects...
projects.each do |project|
# Let's not create a folder if the project has no attachments
next unless project.css("attachment").any?
project_path = create_project_folder(project, companies, file_dir)
# Loop through all of the issues in a project...
project.css("issue").each do |issue|
issue_number = issue.css("> number").text
issue_path = "#{project_path}/#{issue_number}"
# Loop through all of the attachments for the issue...
issue.css("> comment > attachment").each do |attachment|
begin
create_directory(issue_path)
attachment_url = attachment.css("> url").text
attachment_name = attachment.css("> filename").text
download_file(issue_path, attachment_url, attachment_name)
puts " ##{issue_number.to_s} - #{attachment_name}"
rescue => e
puts " Exception (#{e.message} - #{issue_number.to_s} - #{attachment_name}"
end
end
end
end
f.close
end
def self.create_project_folder(project, companies, file_dir)
project_name = project.css("> name").text
puts "------------------------------------------------------"
puts project_name
project_company_name = ""
primary_company_id = project.css("> primary-company-id").text
companies.each do |company|
if company.css("> id").text == primary_company_id
project_company_name = company.css("> name").text
end
end
project_path = "#{file_dir}/#{project_company_name}-#{project_name}"
create_directory(project_path)
return project_path
end
def self.download_file(issue_path, attachment_url, attachment_name)
unless File.exist?("#{issue_path}/#{attachment_name}")
File.open("#{issue_path}/#{attachment_name}", "wb") do |saved_file|
open(attachment_url, "rb") do |read_file|
saved_file.write(read_file.read)
end
end
end
end
def self.create_directory(dir)
unless Dir.exist?(dir)
FileUtils.mkdir(dir)
end
end
end
files = Dir.glob("*.xml")
files.each do |file|
puts "======================================================"
puts "#{file}"
SifterExport.create(file)
puts "\n\n"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment