Permalink
Browse files

Merge branch 'develop'

  • Loading branch information...
2 parents 19f3a45 + 884df44 commit 411efabcb6a4578c2a9bed58e916bff120d0f2e2 Michael van Rooijen committed Mar 29, 2011
View
@@ -4,6 +4,7 @@ GEM
activesupport (3.0.5)
addressable (2.2.4)
builder (3.0.0)
+ crack (0.1.8)
diff-lcs (1.1.2)
dropbox (1.2.3)
json (>= 1.2.0)
@@ -32,6 +33,8 @@ GEM
rspec-instafail (~> 0.1.4)
ruby-progressbar (~> 0.0.9)
hashie (1.0.0)
+ httparty (0.7.4)
+ crack (= 0.1.8)
i18n (0.5.0)
infinity_test (1.0.2)
notifiers (>= 1.1.0)
@@ -90,7 +93,9 @@ DEPENDENCIES
dropbox (~> 1.2.3)
fog (~> 0.7.0)
fuubar
+ httparty (~> 0.7.4)
infinity_test
+ json (~> 1.5.1)
mail (~> 2.2.15)
mocha
net-scp (~> 1.0.4)
View
@@ -19,7 +19,7 @@ Gem::Specification.new do |gem|
server through FTP, SFTP, SCP and RSync), it provide Syncers (RSync, S3) for efficient backups,
it can archive files and directories, it can cycle backups, it can do incremental backups, it
can compress backups, it can encrypt backups (OpenSSL or GPG), it can notify you about
- successful and/or failed backups (Email or Twitter). It is very extensible and easy to add new
+ successful and/or failed backups (Email, Twitter and Campfire). It is very extensible and easy to add new
functionality to. It\'s easy to use.'
##
View
@@ -21,7 +21,7 @@ module Backup
COMPRESSORS = ['Gzip']
ENCRYPTORS = ['OpenSSL', 'GPG']
SYNCERS = ['RSync', 'S3']
- NOTIFIERS = ['Mail', 'Twitter']
+ NOTIFIERS = ['Mail', 'Twitter', 'Campfire']
##
# Backup's internal paths
@@ -62,6 +62,7 @@ module Notifier
autoload :Base, File.join(CONFIGURATION_PATH, 'notifier', 'base')
autoload :Mail, File.join(CONFIGURATION_PATH, 'notifier', 'mail')
autoload :Twitter, File.join(CONFIGURATION_PATH, 'notifier', 'twitter')
+ autoload :Campfire, File.join(CONFIGURATION_PATH, 'notifier', 'campfire')
end
module Encryptor
@@ -150,10 +151,11 @@ module Encryptor
##
# Autoload notification files
module Notifier
- autoload :Base, File.join(NOTIFIER_PATH, 'base')
- autoload :Binder, File.join(NOTIFIER_PATH, 'binder')
- autoload :Mail, File.join(NOTIFIER_PATH, 'mail')
- autoload :Twitter, File.join(NOTIFIER_PATH, 'twitter')
+ autoload :Base, File.join(NOTIFIER_PATH, 'base')
+ autoload :Binder, File.join(NOTIFIER_PATH, 'binder')
+ autoload :Mail, File.join(NOTIFIER_PATH, 'mail')
+ autoload :Twitter, File.join(NOTIFIER_PATH, 'twitter')
+ autoload :Campfire, File.join(NOTIFIER_PATH, 'campfire')
end
##
@@ -0,0 +1,17 @@
+# encoding: utf-8
+
+module Backup
+ module Configuration
+ module Notifier
+ class Campfire < Base
+ class << self
+
+ ##
+ # Campfire credentials
+ attr_accessor :token, :subdomain, :room_id
+
+ end
+ end
+ end
+ end
+end
View
@@ -55,7 +55,19 @@ def self.all
'twitter' => {
:require => 'twitter',
:version => '~> 1.1.2',
- :for => 'Send Twitter Updates (Twitter Notifier)'
+ :for => 'Sending Twitter Updates (Twitter Notifier)'
+ },
+
+ 'httparty' => {
+ :require => 'httparty',
+ :version => '~> 0.7.4',
+ :for => 'Sending Http Updates'
+ },
+
+ 'json' => {
+ :require => 'json',
+ :version => '~> 1.5.1',
+ :for => 'Parsing JSON for HTTParty'
}
}
end
View
@@ -240,7 +240,7 @@ def perform!
# becomes a single (transferrable) packaged file.
def package!
Logger.message "Backup started packaging everything to a single archive file."
- run("#{ utility(:tar) } -c -C '#{ TMP_PATH }' '#{ TRIGGER }' > '#{ File.join(TMP_PATH, "#{TIME}.#{TRIGGER}.tar") }'")
+ run(%|#{ utility(:tar) } -c -f '#{ File.join(TMP_PATH, "#{TIME}.#{TRIGGER}.tar") }' -C '#{ TMP_PATH }' '#{ TRIGGER }'|)
end
##
@@ -0,0 +1,179 @@
+# encoding: utf-8
+
+##
+# If the Ruby version of this process is 1.8.x or less
+# then use the JSON gem. Otherwise if the current process is running
+# Ruby 1.9.x or later then it is built in and we can load it from the Ruby core lib
+if RUBY_VERSION < '1.9.0'
+ Backup::Dependency.load('json')
+else
+ require 'json'
+end
+
+##
+# Load the HTTParty library from the gem
+Backup::Dependency.load('httparty')
+
+module Backup
+ module Notifier
+ class Campfire < Base
+
+ ##
+ # Campfire credentials
+ attr_accessor :token, :subdomain, :room_id
+
+ ##
+ # Container for the Model object
+ attr_accessor :model
+
+ ##
+ # Instantiates a new Backup::Notifier::Campfire object
+ def initialize(&block)
+ load_defaults!
+
+ instance_eval(&block) if block_given?
+
+ set_defaults!
+ end
+
+ ##
+ # Performs the notification
+ # Takes an exception object that might've been created if an exception occurred.
+ # If this is the case it'll invoke notify_failure!(exception), otherwise, if no
+ # error was raised, it'll go ahead and notify_success!
+ #
+ # If'll only perform these if on_success is true or on_failure is true
+ def perform!(model, exception = false)
+ @model = model
+
+ if notify_on_success? and exception.eql?(false)
+ log!
+ notify_success!
+ elsif notify_on_failure? and not exception.eql?(false)
+ log!
+ notify_failure!(exception)
+ end
+ end
+
+ private
+
+ ##
+ # Sends a message informing the user that the backup operation
+ # proceeded without any errors
+ def notify_success!
+ send_message("[Backup::Succeeded] #{model.label} (#{ File.basename(Backup::Model.file) })")
+ end
+
+ ##
+ # Sends a message informing the user that the backup operation
+ # raised an exception
+ def notify_failure!(exception)
+ send_message("[Backup::Failed] #{model.label} (#{ File.basename(Backup::Model.file) })")
+ end
+
+ ##
+ # Setting up credentials
+ def set_defaults!
+ @campfire_client = {
+ :token => @token,
+ :subdomain => @subdomain,
+ :room_id => @room_id
+ }
+ end
+
+ ##
+ # Creates a new Campfire::Interface object and passes in the
+ # campfire clients "room_id", "subdomain" and "token". Using this object
+ # the provided "message" will be sent to the desired Campfire chat room
+ def send_message(message)
+ room = Interface.room(
+ @campfire_client[:room_id],
+ @campfire_client[:subdomain],
+ @campfire_client[:token]
+ )
+ room.message(message)
+ end
+
+ ##
+ # The Campfire::Interface acts as the Interface for the Campfire class.
+ # It uses the HTTParty library and the Campfire::Room class to communicate
+ # with the Campfire rooms. HTTParty provides the Campfire::Interface with the methods
+ # necessary to communicate (inside the HTTParty module) such as the class methods:
+ # * post
+ # * base_uri
+ # * basic_auth
+ class Interface
+ include HTTParty
+
+ ##
+ # We communicate using the JSON data format
+ headers 'Content-Type' => 'application/json'
+
+ ##
+ # Instantiates a new Campfire::Room object with
+ # the provided arguments and returns this object
+ def self.room(room_id, subdomain, token)
+ Room.new(room_id, subdomain, token)
+ end
+ end
+
+ ##
+ # The Campfire::Room acts as a model for an actual room on the Campfire service.
+ # And it uses the Campfire::Interface's (HTTParty) class methods to communicate based
+ # on the provided parameters (room_id, subdomain and token)
+ class Room
+
+ ##
+ # These are the necessary attributes that Campfire requires
+ # in order to communicate with the correct chat rooms
+ attr_reader :room_id, :subdomain, :token
+
+ ##
+ # Instantiates a new Campfire::Room object and sets all the
+ # necessary arguments (@room_id, @subdomain, @token)
+ def initialize(room_id, subdomain, token)
+ @room_id = room_id
+ @subdomain = subdomain
+ @token = token
+ end
+
+ ##
+ # Wrapper method for the #send_message (private) method
+ def message(message)
+ send_message(message)
+ end
+
+ private
+
+ ##
+ # Takes a "message" as argument, the "type" defaults to "Textmessage".
+ # This method builds up a POST request with the necessary params (serialized to JSON format)
+ # and sends it to the Campfire service in order to submit the message
+ def send_message(message, type = 'Textmessage')
+ post 'speak', :body => {
+ :message => {
+ :body => message,
+ :type => type
+ }
+ }.to_json
+ end
+
+ ##
+ # Builds/sets up the Campfire::Interface attributes and submits
+ # the POST request that was built in the #send_message (private) method
+ def post(action, options = {})
+ Interface.base_uri("https://#{subdomain}.campfirenow.com")
+ Interface.basic_auth(token, 'x')
+ Interface.post(room_url_for(action), options)
+ end
+
+ ##
+ # Returns the url for the specified room (in JSON format)
+ def room_url_for(action)
+ "/room/#{room_id}/#{action}.json"
+ end
+ end
+
+ end
+ end
+end
View
@@ -13,7 +13,7 @@ class Version
# Defines the minor version
# PATCH:
# Defines the patch version
- MAJOR, MINOR, PATCH = 3, 0, 11
+ MAJOR, MINOR, PATCH = 3, 0, 12
##
# Returns the major version ( big release based off of multiple minor releases )
View
@@ -205,7 +205,7 @@ def initialize(&block); end
it 'should package the folder' do
model.expects(:utility).with(:tar).returns(:tar)
- model.expects(:run).with("tar -c -C '#{ Backup::TMP_PATH }' '#{ Backup::TRIGGER }' > '#{ File.join( Backup::TMP_PATH, "#{ Backup::TIME }.#{ Backup::TRIGGER }.tar" ) }'")
+ model.expects(:run).with(%|tar -c -f '#{ File.join( Backup::TMP_PATH, "#{ Backup::TIME }.#{ Backup::TRIGGER }.tar" ) }' -C '#{ Backup::TMP_PATH }' '#{ Backup::TRIGGER }'|)
model.send(:package!)
end
Oops, something went wrong.

0 comments on commit 411efab

Please sign in to comment.