public
Last active — forked from bruno/campfire_export.rb

campfire transcript export

  • Download Gist
.bundle/config
1 2
---
BUNDLE_WITHOUT: ""
.bundle/environment.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259
# DO NOT MODIFY THIS FILE
# Generated by Bundler 0.9.26
 
require 'digest/sha1'
require 'yaml'
require 'pathname'
require 'rubygems'
Gem.source_index # ensure Rubygems is fully loaded in Ruby 1.9
 
module Gem
class Dependency
if !instance_methods.map { |m| m.to_s }.include?("requirement")
def requirement
version_requirements
end
end
end
end
 
module Bundler
class Specification < Gem::Specification
attr_accessor :relative_loaded_from
 
def self.from_gemspec(gemspec)
spec = allocate
gemspec.instance_variables.each do |ivar|
spec.instance_variable_set(ivar, gemspec.instance_variable_get(ivar))
end
spec
end
 
def loaded_from
return super unless relative_loaded_from
source.path.join(relative_loaded_from).to_s
end
 
def full_gem_path
Pathname.new(loaded_from).dirname.expand_path.to_s
end
end
 
module SharedHelpers
attr_accessor :gem_loaded
 
def default_gemfile
gemfile = find_gemfile
gemfile or raise GemfileNotFound, "Could not locate Gemfile"
Pathname.new(gemfile)
end
 
def in_bundle?
find_gemfile
end
 
def env_file
default_gemfile.dirname.join(".bundle/environment.rb")
end
 
private
 
def find_gemfile
return ENV['BUNDLE_GEMFILE'] if ENV['BUNDLE_GEMFILE']
 
previous = nil
current = File.expand_path(Dir.pwd)
 
until !File.directory?(current) || current == previous
filename = File.join(current, 'Gemfile')
return filename if File.file?(filename)
current, previous = File.expand_path("..", current), current
end
end
 
def clean_load_path
# handle 1.9 where system gems are always on the load path
if defined?(::Gem)
me = File.expand_path("../../", __FILE__)
$LOAD_PATH.reject! do |p|
next if File.expand_path(p).include?(me)
p != File.dirname(__FILE__) &&
Gem.path.any? { |gp| p.include?(gp) }
end
$LOAD_PATH.uniq!
end
end
 
def reverse_rubygems_kernel_mixin
# Disable rubygems' gem activation system
::Kernel.class_eval do
if private_method_defined?(:gem_original_require)
alias rubygems_require require
alias require gem_original_require
end
 
undef gem
end
end
 
def cripple_rubygems(specs)
reverse_rubygems_kernel_mixin
 
executables = specs.map { |s| s.executables }.flatten
Gem.source_index # ensure RubyGems is fully loaded
 
::Kernel.class_eval do
private
def gem(*) ; end
end
 
::Kernel.send(:define_method, :gem) do |dep, *reqs|
if executables.include? File.basename(caller.first.split(':').first)
return
end
opts = reqs.last.is_a?(Hash) ? reqs.pop : {}
 
unless dep.respond_to?(:name) && dep.respond_to?(:requirement)
dep = Gem::Dependency.new(dep, reqs)
end
 
spec = specs.find { |s| s.name == dep.name }
 
if spec.nil?
e = Gem::LoadError.new "#{dep.name} is not part of the bundle. Add it to Gemfile."
e.name = dep.name
e.version_requirement = dep.requirement
raise e
elsif dep !~ spec
e = Gem::LoadError.new "can't activate #{dep}, already activated #{spec.full_name}. " \
"Make sure all dependencies are added to Gemfile."
e.name = dep.name
e.version_requirement = dep.requirement
raise e
end
 
true
end
 
# === Following hacks are to improve on the generated bin wrappers ===
 
# Yeah, talk about a hack
source_index_class = (class << Gem::SourceIndex ; self ; end)
source_index_class.send(:define_method, :from_gems_in) do |*args|
source_index = Gem::SourceIndex.new
source_index.spec_dirs = *args
source_index.add_specs(*specs)
source_index
end
 
# OMG more hacks
gem_class = (class << Gem ; self ; end)
gem_class.send(:define_method, :bin_path) do |name, *args|
exec_name, *reqs = args
 
spec = nil
 
if exec_name
spec = specs.find { |s| s.executables.include?(exec_name) }
spec or raise Gem::Exception, "can't find executable #{exec_name}"
else
spec = specs.find { |s| s.name == name }
exec_name = spec.default_executable or raise Gem::Exception, "no default executable for #{spec.full_name}"
end
 
gem_bin = File.join(spec.full_gem_path, spec.bindir, exec_name)
gem_from_path_bin = File.join(File.dirname(spec.loaded_from), spec.bindir, exec_name)
File.exist?(gem_bin) ? gem_bin : gem_from_path_bin
end
end
 
extend self
end
end
 
module Bundler
ENV_LOADED = true
LOCKED_BY = '0.9.26'
FINGERPRINT = "ba3ddaf1ab1378d9ecc8c9e6d530ef4cb7e6c4e9"
HOME = '/Users/bfleischer/.bundle/ruby/1.8/bundler'
AUTOREQUIRES = {:default=>[["fileutils", false], ["httparty", false], ["nokogiri", false]]}
SPECS = [
{:load_paths=>["/Users/bfleischer/.rvm/gems/ruby-1.8.7-p174@metromix/gems/crack-0.1.8/lib"], :loaded_from=>"/Users/bfleischer/.rvm/gems/ruby-1.8.7-p174@metromix/specifications/crack-0.1.8.gemspec", :name=>"crack"},
{:load_paths=>["/Users/bfleischer/.rvm/gems/ruby-1.8.7-p174@metromix/gems/rmagick-2.13.1/lib", "/Users/bfleischer/.rvm/gems/ruby-1.8.7-p174@metromix/gems/rmagick-2.13.1/ext"], :loaded_from=>"/Users/bfleischer/.rvm/gems/ruby-1.8.7-p174@metromix/specifications/rmagick-2.13.1.gemspec", :name=>"rmagick"},
{:load_paths=>["/Users/bfleischer/.rvm/gems/ruby-1.8.7-p174@metromix/gems/fileutils-0.6/lib"], :loaded_from=>"/Users/bfleischer/.rvm/gems/ruby-1.8.7-p174@metromix/specifications/fileutils-0.6.gemspec", :name=>"fileutils"},
{:load_paths=>["/Users/bfleischer/.rvm/gems/ruby-1.8.7-p174@metromix/gems/httparty-0.7.3/lib"], :loaded_from=>"/Users/bfleischer/.rvm/gems/ruby-1.8.7-p174@metromix/specifications/httparty-0.7.3.gemspec", :name=>"httparty"},
{:load_paths=>["/Users/bfleischer/.bundle/ruby/1.8/gems/nokogiri-1.4.4/lib"], :loaded_from=>"/Users/bfleischer/.bundle/ruby/1.8/specifications/nokogiri-1.4.4.gemspec", :name=>"nokogiri"},
].map do |hash|
if hash[:virtual_spec]
spec = eval(hash[:virtual_spec], TOPLEVEL_BINDING, "<virtual spec for '#{hash[:name]}'>")
else
dir = File.dirname(hash[:loaded_from])
spec = Dir.chdir(dir){ eval(File.read(hash[:loaded_from]), TOPLEVEL_BINDING, hash[:loaded_from]) }
end
spec.loaded_from = hash[:loaded_from]
spec.require_paths = hash[:load_paths]
if spec.loaded_from.include?(HOME)
Bundler::Specification.from_gemspec(spec)
else
spec
end
end
 
extend SharedHelpers
 
def self.configure_gem_path_and_home(specs)
# Fix paths, so that Gem.source_index and such will work
paths = specs.map{|s| s.installation_path }
paths.flatten!; paths.compact!; paths.uniq!; paths.reject!{|p| p.empty? }
ENV['GEM_PATH'] = paths.join(File::PATH_SEPARATOR)
ENV['GEM_HOME'] = paths.first
Gem.clear_paths
end
 
def self.match_fingerprint
lockfile = File.expand_path('../../Gemfile.lock', __FILE__)
lock_print = YAML.load(File.read(lockfile))["hash"] if File.exist?(lockfile)
gem_print = Digest::SHA1.hexdigest(File.read(File.expand_path('../../Gemfile', __FILE__)))
 
unless gem_print == lock_print
abort 'Gemfile changed since you last locked. Please run `bundle lock` to relock.'
end
 
unless gem_print == FINGERPRINT
abort 'Your bundled environment is out of date. Run `bundle install` to regenerate it.'
end
end
 
def self.setup(*groups)
match_fingerprint
clean_load_path
cripple_rubygems(SPECS)
configure_gem_path_and_home(SPECS)
SPECS.each do |spec|
Gem.loaded_specs[spec.name] = spec
spec.require_paths.each do |path|
$LOAD_PATH.unshift(path) unless $LOAD_PATH.include?(path)
end
end
self
end
 
def self.require(*groups)
groups = [:default] if groups.empty?
groups.each do |group|
(AUTOREQUIRES[group.to_sym] || []).each do |file, explicit|
if explicit
Kernel.require file
else
begin
Kernel.require file
rescue LoadError
end
end
end
end
end
 
# Set up load paths unless this file is being loaded after the Bundler gem
setup unless defined?(Bundler::GEM_LOADED)
end
Gemfile
Ruby
1 2 3 4 5
source :rubygems
#
gem 'fileutils'
gem 'httparty'
gem 'nokogiri'
campfire_export.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
require 'rubygems'
require 'time'
require 'fileutils'
require 'httparty'
require 'nokogiri'
require 'pp'
 
# 1) set the start date on line 77
APIToken = '' # 2) your-api-token-goes-here, see your campfire profile
subdomain = '' # 3) your subdomain goes here
APIServer = 'https://#{subdomain}.campfirenow.com'
 
def get(path, params = {})
HTTParty.get "#{APIServer}#{path}",
:query => params,
:basic_auth => {:username => APIToken, :password => 'X'}
end
 
def username(id)
@usernames ||= {}
@usernames[id] ||= begin
doc = Nokogiri::XML get("/users/#{id}.xml").body
doc.css('name').text
end
end
 
def message_to_string(message)
user = username message.css('user-id').text
type = message.css('type').text
body = message.css('body').text
time = Time.parse message.css('created-at').text
prefix = time.strftime '[%H:%M:%S]'
case type
when 'EnterMessage'
"#{prefix} #{user} has entered the room"
when 'KickMessage', 'LeaveMessage'
"#{prefix} #{user} has left the room"
when 'TextMessage'
"#{prefix} #{user}: #{body}"
when 'UploadMessage'
"#{prefix} #{user} uploaded '#{body}'"
when 'PasteMessage'
"#{prefix} #{user} pasted:\n#{body}"
when 'TopicChangeMessage'
"#{prefix} #{user} changed the topic to '#{body}'"
when 'ConferenceCreatedMessage'
"#{prefix} #{user} created conference #{body}"
when 'TweetMessage'
"#{prefix} #{user} tweeted #{body}"
when 'AdvertisementMessage'
"#{prefix} Advertisement #{body}" #Do we want to print this?
else
"****Unknown Message Type: #{type} - '#{body}'" # don't want to raise and crash it
end
end
 
def file_name(date)
file_name = date.year.to_s
file_name << '-'
file_name << '0' if date.mon < 10
file_name << date.mon.to_s
file_name << '-'
file_name << '0' if date.mday < 10
file_name << date.mday.to_s
file_name + '.txt'
end
 
doc = Nokogiri::XML get('/rooms.xml').body
doc.css('room').each do |room_xml|
puts room_xml.css('name').text
id = room_xml.css('id').text
FileUtils.mkdir_p("campfire/#{id}")
 
date = Date.civil 2010, 1, 26
# date = Date.civil 2011, 1, 1
 
while date < Date.today
puts "#{date.year} #{date.mon} #{date.mday}"
transcript = Nokogiri::XML get("/room/#{id}/transcript/#{date.year}/#{date.mon}/#{date.mday}.xml").body
output = "#{room_xml.css('name').text} Transcript\n"
transcript.css('message').each do |message|
next if message.css('type').text == 'TimestampMessage'
output << message_to_string(message) << "\n"
 
if message.css('type').text == "UploadMessage"
# We get the HTML page because the XML doesn't contain the URL for the uploaded file :(
html_transcript = Nokogiri::XML get("/room/#{id}/transcript/#{date.year}/#{date.mon}/#{date.mday}")
file_name = "#{message.css('body').text}"
# I am sure there's a better way than cycling through all the hyperlinks
html_transcript.css('a').each do |link|
if link.text == file_name
open("campfire/#{id}/#{link.text}", "wb") { |file|
file.write(get(link.attr("href")))
}
# We break because there are two links with the same file on the HTML page
break
end
end
end
end
open("campfire/#{id}/#{file_name date}", 'w') do |f|
f.puts output
end
date = date.next
end
end

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.