Skip to content

Instantly share code, notes, and snippets.

@bf4
Forked from bruno/campfire_export.rb
Created February 10, 2011 22:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bf4/821553 to your computer and use it in GitHub Desktop.
Save bf4/821553 to your computer and use it in GitHub Desktop.
campfire transcript export
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
---
BUNDLE_WITHOUT: ""
# 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
source :rubygems
#
gem 'fileutils'
gem 'httparty'
gem 'nokogiri'
---
dependencies:
fileutils:
group:
- :default
version: ">= 0"
httparty:
group:
- :default
version: ">= 0"
nokogiri:
group:
- :default
version: ">= 0"
specs:
- crack:
version: 0.1.8
- rmagick:
version: 2.13.1
- fileutils:
version: "0.6"
- httparty:
version: 0.7.3
- nokogiri:
version: 1.4.4
hash: ba3ddaf1ab1378d9ecc8c9e6d530ef4cb7e6c4e9
sources:
- Rubygems:
uri: http://gemcutter.org
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment