lib/scribd_fu.rb in mdarby-scribd_fu-1.2.3.2 vs lib/scribd_fu.rb in mdarby-scribd_fu-2.0
- old
+ new
@@ -1,108 +1,250 @@
-require 'attachment_fu/methods'
-require 'paperclip/methods'
-
module ScribdFu
- # A list of content types supported by scribd.
- CONTENT_TYPES = ['application/pdf', 'image/jpeg', 'image/pjpeg',
- 'image/gif', 'image/png', 'image/x-png', 'image/jpg',
- 'application/msword', 'application/mspowerpoint',
- 'application/vnd.ms-powerpoint', 'application/excel',
- 'application/vnd.ms-excel', 'application/postscript',
- 'text/plain', 'application/rtf',
- 'application/vnd.oasis.opendocument.text',
- 'application/vnd.oasis.opendocument.presentation',
- 'application/vnd.oasis.opendocument.spreadsheet',
- 'application/vnd.sun.xml.writer',
- 'application/vnd.sun.xml.impress',
- 'application/vnd.sun.xml.calc',
- # OOXML, AKA `the MIME types from hell'. Seriously, these are long enough to
- # start their own dictionary...
+
+ ConfigPath = "#{RAILS_ROOT}/config/scribd_fu.yml".freeze
+
+ # A list of content types supported by iPaper.
+ ContentTypes = [
+ 'application/pdf',
+ 'application/msword',
+ 'application/mspowerpoint',
+ 'application/vnd.ms-powerpoint',
+ 'application/excel',
+ 'application/vnd.ms-excel',
+ 'application/postscript',
+ 'text/plain',
+ 'application/rtf',
+ 'application/vnd.oasis.opendocument.text',
+ 'application/vnd.oasis.opendocument.presentation',
+ 'application/vnd.oasis.opendocument.spreadsheet',
+ 'application/vnd.sun.xml.writer',
+ 'application/vnd.sun.xml.impress',
+ 'application/vnd.sun.xml.calc',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
'application/vnd.openxmlformats-officedocument.presentationml.template',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
- 'application/vnd.openxmlformats-officedocument.wordprocessingml.template']
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.template'
+ ]
- def self.included(base)
- base.extend ActsAsScribdDocument
+ # Available parameters for the JS API
+ # http://www.scribd.com/publisher/api/api?method_name=Javascript+API
+ Available_JS_Params = [ :height, :width, :page, :my_user_id, :search_query,
+ :jsapi_version, :disable_related_docs, :mode, :auto_size ]
+
+ class ScribdFuError < StandardError #:nodoc:
end
- module ActsAsScribdDocument
- # Synonym for <tt>has_scribdable_attachment(nil)</tt>.
- def acts_as_scribd_document
- has_scribdable_attachment
+ class ScribdFuUploadError < ScribdFuError #:nodoc:
+ end
+
+
+ class << self
+
+ def included(base) #:nodoc:
+ base.extend ClassMethods
end
- # Marks the given +attribute+ as a scribdable document file. If +attribute+
- # is nil, assumes this is an Attachment_fu model and deals with the setup
- # accordingly; otherwise, assumes a +paperclip+ model and sets up scribding
- # related to the particular given attribute.
- def has_scribdable_attachment(attribute = nil)
- class_eval do
- include ScribdFu::InstanceMethods
+ # Login, store, and return a handle to the Scribd user account
+ def scribd_user
+ begin
+ # Ensure we can login to Scribd, and get a handle on the account
+ Scribd::API.instance.key = config[:key]
+ Scribd::API.instance.secret = config[:secret]
+ @scribd_user = Scribd::User.login(config[:user], config[:password])
+ rescue
+ raise ScribdFuError, "Your Scribd credentials are incorrect"
+ end
+ end
- if attribute.nil?
- include ScribdFu::AttachmentFu::InstanceMethods
- else
- include ScribdFu::Paperclip::InstanceMethods # ignored if already done
+ # Upload a file to Scribd
+ def upload(obj, file_path)
+ begin
+ res = scribd_user.upload(:file => "#{file_path}", :access => access_level)
+ obj.update_attributes({:ipaper_id => res.doc_id, :ipaper_access_key => res.access_key})
+ rescue
+ raise ScribdFuUploadError, "Sorry, but #{obj.class} ##{obj.id} could not be uploaded to Scribd"
+ end
+ end
- add_scribd_attribute attribute # class method added by above include
- end
+ # Delete an iPaper document
+ def destroy(document)
+ document.destroy
+ end
+
+ # Read, store, and return the ScribdFu config file's contents
+ def config
+ raise ScribdFuError, "#{ConfigPath} does not exist" unless File.file?(ConfigPath)
+
+ # Load the config file and strip any whitespace from the values
+ @config ||= YAML.load_file(ConfigPath).each_pair{|k,v| {k=>v.to_s.strip}}.symbolize_keys!
+ end
+
+ # Get the preferred access level for iPaper documents
+ def access_level
+ config[:access] || 'private'
+ end
+
+ # Load, store, and return the associated iPaper document
+ def load_ipaper_document(id)
+ begin
+ @document ||= scribd_user.find_document(id)
+ rescue
+ raise ScribdFuError, "Scribd Document ##{id} not found!"
end
end
+
end
- module InstanceMethods
- # Sets up Scribd configuration info when this module is included.
- def self.included(base)
- base.extend ClassMethods
+ module ClassMethods
- mattr_reader :scribd_config, :scribd_login
+ # Load and inject ScribdFu goodies
+ def has_ipaper_and_uses(str)
+ check_environment
+ load_base_plugin(str)
- begin
- require 'rscribd'
- rescue LoadError
- raise RequiredLibraryNotFoundError.new('rscribd could not be loaded')
+ include InstanceMethods
+
+ after_save :upload_to_scribd # This *MUST* be an after_save
+ before_destroy :destroy_ipaper_document
+ end
+
+ private
+
+ # Configure ScribdFu for this particular environment
+ def check_environment
+ load_rscribd
+ check_config
+ check_fields
end
- begin
- unless @@scribd_login
- @@scribd_config = YAML.load_file("#{RAILS_ROOT}/config/scribd.yml").symbolize_keys
- @@scribd_config = @@scribd_config[:scribd]
+ def check_config
+ ScribdFu::config
+ end
- # Ensure we can connect to the Service
- Scribd::API.instance.key = @@scribd_config['key'].to_s.strip
- Scribd::API.instance.secret = @@scribd_config['secret'].to_s.strip
+ # Load the rscribd gem
+ def load_rscribd
+ begin
+ require 'rscribd'
+ rescue LoadError
+ raise ScribdFuError, 'Please install the rscribd gem'
+ end
+ end
- @@scribd_login = Scribd::User.login @@scribd_config['user'].to_s.strip, @@scribd_config['password'].to_s.strip
+ # Load Attachment_Fu specific methods and files
+ def load_attachment_fu
+ require 'scribd_fu/attachment_fu'
+ include ScribdFu::AttachmentFu::InstanceMethods
+ end
+
+ # Load Paperclip specific methods and files
+ def load_paperclip
+ require 'scribd_fu/paperclip'
+ include ScribdFu::Paperclip::InstanceMethods
+ end
+
+ # Ensure ScribdFu-centric attributes exist
+ def check_fields
+ fields = %w{ipaper_id ipaper_access_key}.inject([]){|stack, f| stack << "#{name}##{f}" unless column_names.include?(f); stack}
+ raise ScribdFuError, "These fields are missing: #{fields.to_sentence}" if fields.size > 0
+ end
+
+ # Load either AttachmentFu or Paperclip-specific methods
+ def load_base_plugin(str)
+ if str == 'AttachmentFu'
+ load_attachment_fu
+ elsif str == 'Paperclip'
+ load_paperclip
+ else
+ raise ScribdFuError, "Sorry, only Attachment_fu and Paperclip are supported."
end
- rescue
- raise "config/scribd.yml file not found, or your credentials are incorrect."
end
+
+ end
+
+ module InstanceMethods
+
+ def self.included(base)
+ base.extend ClassMethods
end
- def access_level
- if self.respond_to?(:is_public) && self.is_public != nil
- scribd_access = self.is_public ? 'public' : 'private'
- else
- scribd_access = scribd_config['access']
- end
+ # Upload the associated file to Scribd for iPaper conversion
+ # This is called +after_save+ and cannot be called earlier,
+ # so don't get any ideas.
+ def upload_to_scribd
+ ScribdFu::upload(self, file_path) if scribdable?
+ end
- scribd_access
+ # Checks whether the associated file is convertable to iPaper
+ def scribdable?
+ ContentTypes.include?(get_content_type) && ipaper_id.blank?
end
- end
- module ClassMethods
- # Sets up the scribd_options accessor, a before_destroy hook to ensure the
- # deletion of associated Scribd documents, and an after_save hook to upload
- # to scribd.
- def self.extended(base)
- base.class_inheritable_accessor :scribd_options
+ # Responds true if the conversion is converting
+ def conversion_processing?
+ !(conversion_complete? || conversion_successful? || conversion_error?)
+ end
- base.before_destroy :destroy_scribd_documents
- base.before_validation :upload_to_scribd
+ # Responds true if the conversion is complete -- note that this gives no
+ # indication as to whether the conversion had an error or was succesful,
+ # just that the conversion completed.
+ def conversion_complete?
+ ipaper_document && ipaper_document.conversion_status != 'PROCESSING'
end
+
+ # Responds true if the document has been converted.
+ def conversion_successful?
+ ipaper_document && ipaper_document.conversion_status =~ /^DISPLAYABLE|DONE$/
+ end
+
+ # Responds true if there was a conversion error while converting to iPaper.
+ def conversion_error?
+ ipaper_document && ipaper_document.conversion_status == 'ERROR'
+ end
+
+ # Responds the Scribd::Document associated with this model, or nil if it does not exist.
+ def ipaper_document
+ @document ||= ScribdFu::load_ipaper_document(ipaper_id)
+ end
+
+ # Destroys the scribd document for this record. This is called +before_destroy+
+ def destroy_ipaper_document
+ ScribdFu::destroy(ipaper_document) if ipaper_document
+ end
+
+ # Display the iPaper document in a view
+ def display_ipaper(options = {})
+ alt = options.has_key?(:alt) ? options[:alt] : ""
+
+ <<-END
+ <script type="text/javascript" src="http://www.scribd.com/javascripts/view.js"></script>
+ <div id="embedded_flash">#{alt}</div>
+ <script type="text/javascript">
+ var scribd_doc = scribd.Document.getDoc(#{ipaper_id}, '#{ipaper_access_key}');
+ #{js_params(options)}
+ scribd_doc.write("embedded_flash");
+ </script>
+ END
+ end
+
+
+ private
+
+ # Check and collect any Javascript params that might have been passed in
+ def js_params(options)
+ opt = []
+
+ options.each_pair do |k, v|
+ opt << "scribd_doc.addParam('#{k}', '#{v}');" if Available_JS_Params.include?(k)
+ end
+
+ opt.compact.join("\n")
+ end
+
end
+
end
+
+# Let's do this.
+ActiveRecord::Base.send(:include, ScribdFu) if Object.const_defined?("ActiveRecord")
\ No newline at end of file