Permalink
Browse files

initial commit

  • Loading branch information...
0 parents commit 8a57ca1264377022ae206b2f23260c12e00e7859 Russell Norris committed Jan 13, 2009
@@ -0,0 +1,4 @@
+.DS_Store
+doc
+github-test.rb
+*.gem
@@ -0,0 +1,20 @@
+Copyright (c) 2008 Saiku Desarrollos S.L.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,13 @@
+= slideshare
+
+A Ruby wrapper library for the SlideShare API
+
+== Requirements
+
+You will need to install HTTParty[http://github.com/jnunemaker/httparty/tree/master] and Curb[http://curb.rubyforge.org/] gems.
+
+== Caveats
+
+This gem is still in its infancy.
+
+copyright (c) 2009 Saiku Desarrollos S.L., released under the MIT license
@@ -0,0 +1,35 @@
+require "rake"
+require "rake/rdoctask"
+
+desc "Generate RDoc documentation for SlideShare library"
+Rake::RDocTask.new(:rdoc) do |rdoc|
+ rdoc.rdoc_dir = "doc"
+ rdoc.title = "SlideShare API Ruby Library"
+ rdoc.options << "--line-numbers" << "--inline-source"
+ rdoc.rdoc_files.include("README")
+ rdoc.rdoc_files.include("lib/**/*.rb")
+end
+
+begin
+ require 'spec'
+rescue LoadError
+ require 'rubygems'
+ require 'spec'
+end
+begin
+ require 'spec/rake/spectask'
+rescue LoadError
+ puts <<-EOS
+ To use rspec for testing you must install rspec gem:
+ gem install rspec
+EOS
+ exit 0
+end
+
+task :default => :spec
+
+desc "Run the specs for SlideShare library"
+Spec::Rake::SpecTask.new do |t|
+ t.spec_opts = ["--options", "spec/spec.opts"]
+ t.spec_files = FileList["spec/**/*_spec.rb"]
+end
@@ -0,0 +1 @@
+require "slide_share"
@@ -0,0 +1,79 @@
+require "digest/sha1"
+
+module SlideShare
+ class Base
+ include HTTParty
+ base_uri "http://www.slideshare.net/api/2"
+ format :xml
+
+ attr_accessor :api_key, :shared_secret
+
+ # Returns an instance of <tt>SlideShare::Base</tt>. Takes the following options:
+ #
+ # * <tt>:api_key</tt> - SlideShare API key
+ # * <tt>:shared_pass</tt> - SlideShared shared secret
+ #
+ # Alternatively, this method may take the path to a YAML file containing
+ # this data. Examples (of both):
+ #
+ # # Using the options hash
+ # @slideshare = SlideShare::Base.new(:api_key => "4815162342", :shared_secret => "dharma")
+ # # Using the YAML file
+ # @slideshare = SlideShare::Base.new("path/to/file.yml")
+ def initialize(hash_or_yaml)
+ config = hash_or_yaml.is_a?(Hash) ? hash_or_yaml :
+ YAML.load_file(hash_or_yaml)
+ self.api_key = config[:api_key]
+ self.shared_secret = config[:shared_secret]
+ unless api_key && shared_secret
+ raise ArgumentError, "Configuration must have values for :api_key and :shared_secret"
+ end
+ end
+
+ # OO abstraction for <tt>SlideShare::Slideshow</tt> namespace. Example usage:
+ #
+ # @slideshare = SlideShare::Base.new("path/to/file.yml")
+ # @slideshow = @slideshare.slideshows.find(815)
+ #
+ # This is recommended over initializing and accessing a <tt>SlideShare::Slideshow</tt>
+ # object directly.
+ def slideshows
+ @slideshow ||= Slideshows.new(self)
+ end
+
+ private
+ def get(*args)
+ catch_errors self.class.get(args.first,
+ {:query => add_required_params(args.extract_options!)})
+ end
+
+ def post(*args)
+ options = add_required_params(args.extract_options!)
+ catch_errors self.class.post(args.first,
+ {:query => options})
+ end
+
+ def add_required_params(options)
+ now = Time.now.to_i.to_s
+ hashed = Digest::SHA1.hexdigest("#{shared_secret}#{now}")
+ options.merge(:api_key => api_key, :ts => now, :hash => hashed)
+ end
+
+ def catch_errors(response)
+ if error = response.delete("SlideShareServiceError")
+ case error["Message"]
+ when /failed user authentication/i
+ raise FailedUserAuthentication
+ when /insufficient permission/i
+ raise InsufficientPermission
+ when /slideshow not found/i
+ raise SlideshowNotFound
+ else
+ raise ServiceError, error["Message"]
+ end
+ else
+ response
+ end
+ end
+ end
+end
@@ -0,0 +1,17 @@
+module SlideShare
+ # Raised when API method requires username and password but none
+ # was provided
+ class InsufficientPermission < StandardError; end
+
+ # Raised when API method was given incorrect username and/or password
+ class FailedUserAuthentication < StandardError; end
+
+ # Raised when no slideshow matches the supplied slideshow_id
+ class SlideshowNotFound < StandardError; end
+
+ # Raised when the application has made more than 1000 calls a day
+ class AccountExceededDailyLimit < StandardError; end
+
+ # Raised when none of the other errors match
+ class ServiceError < StandardError; end
+end
@@ -0,0 +1,127 @@
+module SlideShare
+ class Slideshows
+ attr_accessor :base
+
+ # This method should only be called internally from an instance of
+ # <tt>SlideShare::Base</tt>.
+ def initialize(base) # :nodoc:
+ self.base = base
+ end
+
+ # Returns id of newly created slideshow if successful or raises an appropriate
+ # exception if not. Takes the following options:
+ #
+ # * <tt>:slideshow_description</tt> - Description for the slideshow
+ # * <tt>:slideshow_tags</tt> - Tags for the slideshow. Multiple tags should be separated
+ # by spaces, using quotes to create individual multiple word tags.
+ # * <tt>:make_src_public</tt> - Set to <tt>true/false</tt> to allow users to download
+ # the slideshow
+ # * <tt>:make_slideshow_private</tt> - Set to <tt>true/false</tt> to change the privacy
+ # setting appropriately
+ #
+ # The following options will only be used if <tt>:make_slideshow_private</tt> is set
+ # <tt>true</tt>:
+ #
+ # * <tt>:generate_secret_url</tt> - Set to <tt>true/false</tt> to generate a secret URL
+ # * <tt>:allow_embeds</tt> - Set to <tt>true/false</tt> to allow websites to embed
+ # the private slideshow
+ # * <tt>:share_with_contacts</tt> - Set to <tt>true/false</tt> to allow your contacts to
+ # view the private slideshow
+ def create(title, filename, username, password, options = {})
+ force_boolean_params_to_letters! options
+ options.merge!(:username => username, :password => password,
+ :slideshow_title => title)
+ params = base.send(:add_required_params, options).map do |key, value|
+ Curl::PostField.content(key.to_s, value)
+ end
+ params << Curl::PostField.file("slideshow_srcfile", File.expand_path(filename))
+
+ curl = Curl::Easy.new("#{SlideShare::Base.base_uri}/upload_slideshow") do |c|
+ c.multipart_form_post = true
+ end
+ curl.http_post(*params)
+
+ body = ToHashParser.from_xml(curl.body_str)
+ response = base.send(:catch_errors, body)
+ # I'd presume the id returned was an integer
+ response["SlideShowUploaded"]["SlideShowID"].to_i
+ end
+
+ # Returns hash of attributes for slideshow if successful or raises an appropriate
+ # exception if not. Takes the following options:
+ #
+ # * <tt>:username</tt> - SlideShare username of the user _making_ the request
+ # * <tt>:password</tt> - SlideShare password of the user _making_ the request
+ # * <tt>:detailed</tt> - Set to <tt>true</tt> to return additional, detailed information
+ # about the slideshow (see the official API documentation here[http://www.slideshare.net/developers/documentation]
+ # for more information). Default is <tt>false</tt>.
+ def find(id, options = {})
+ detailed = convert_to_number(options.delete(:detailed))
+ options[:detailed] = detailed unless detailed.nil?
+ base.send :get, "/get_slideshow", options.merge(:slideshow_id => id)
+ end
+
+ # Returns true if successful or raises an appropriate exception if not.
+ # Takes the following options:
+ #
+ # * <tt>:slideshow_title</tt> - Title for the slideshow
+ # * <tt>:slideshow_description</tt> - Description for the slideshow
+ # * <tt>:slideshow_tags</tt> - Tags for the slideshow. Multiple tags should be separated
+ # by spaces, using quotes to create individual multiple word tags.
+ # * <tt>:make_slideshow_private</tt> - Set to <tt>true/false</tt> to change the privacy
+ # setting appropriately
+ #
+ # The following options will only be used if <tt>:make_slideshow_private</tt> is set
+ # <tt>true</tt>:
+ #
+ # * <tt>:generate_secret_url</tt> - Set to <tt>true/false</tt> to generate a secret URL
+ # * <tt>:allow_embeds</tt> - Set to <tt>true/false</tt> to allow websites to embed
+ # the private slideshow
+ # * <tt>:share_with_contacts</tt> - Set to <tt>true/false</tt> to allow your contacts to
+ # view the private slideshow
+ def update(id, username, password, options = {})
+ force_boolean_params_to_letters! options
+ base.send(:post, "/edit_slideshow", options.merge(:slideshow_id => id,
+ :username => username, :password => password))
+ true # This might be too naïve but should have already raised exception if unsuccessful
+ end
+
+ # Returns true if successful or raises an appropriate exception if not.
+ def delete(id, username, password)
+ base.send :post, "/delete_slideshow", :slideshow_id => id,
+ :username => username, :password => password
+ true # This might be too naïve but should have already raised exception if unsuccessful
+ end
+
+ private
+ def force_boolean_params_to_letters!(hash)
+ [
+ :make_src_public, :make_slideshow_private, :generate_secret_url,
+ :allow_embeds, :share_with_contacts
+ ].each do |key|
+ value = hash.delete(key)
+ unless value.nil?
+ hash[key] = convert_to_letter(value, true)
+ end
+ end
+ end
+
+ def convert_to_letter(value, force = false)
+ case value
+ when false, "N", nil
+ force ? "N" : nil
+ when true, "Y"
+ "Y"
+ end
+ end
+
+ def convert_to_number(value, force = false)
+ case value
+ when false, 0, nil
+ force ? 0 : nil
+ when true, 1
+ 1
+ end
+ end
+ end
+end
@@ -0,0 +1,16 @@
+require "rubygems"
+require "httparty"
+require "curb"
+
+require "slide_share/errors"
+require "slide_share/base"
+require "slide_share/slideshows"
+
+unless Array.new.respond_to?(:extract_options!)
+ # Via ActiveSupport
+ class Array
+ def extract_options!
+ last.is_a?(Hash) ? pop : {}
+ end
+ end
+end
@@ -0,0 +1,62 @@
+Gem::Specification.new do |s|
+ s.name = "slideshare"
+ s.version = "0.1.0"
+
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
+ s.rubygems_version = "1.3.1"
+
+ s.date = "2009-1-13"
+ s.summary = "Ruby interface for SlideShare API"
+ s.email = "pablo@saiku.es"
+ s.homepage = "http://github.com/saiku/slideshare"
+ s.description = "Ruby interface for SlideShare API"
+ s.authors = ["Saiku.es", "Russell Norris"]
+ s.files = %w{
+ init.rb
+ lib/slideshare.rb
+ lib/slide_share/base.rb
+ lib/slide_share/errors.rb
+ lib/slide_share/slideshows.rb
+ MIT-LICENSE
+ Rakefile
+ README.rdoc
+ slideshare.gemspec
+ spec/spec.opts
+ spec/spec_helpers.rb
+ spec/fixtures/config.yml
+ spec/fixtures/config_missing_api_key.yml
+ spec/fixtures/config_missing_shared_secret.yml
+ spec/fixtures/delete_slideshow.xml
+ spec/fixtures/edit_slideshow.xml
+ spec/fixtures/error_failed_auth.xml
+ spec/fixtures/error_not_found.xml
+ spec/fixtures/error_permissions.xml
+ spec/fixtures/error_failed_auth.xml
+ spec/fixtures/get_slideshow.xml
+ spec/fixtures/get_slideshow_detailed.xml
+ spec/fixtures/sample.txt
+ spec/fixtures/upload_slideshow.xml
+ spec/slide_share/base_spec.rb
+ spec/slide_share/slideshows_spec.rb
+ }
+ s.require_paths = %w{lib}
+ s.has_rdoc = true
+ s.extra_rdoc_files = %w{MIT-LICENSE README.rdoc}
+ s.rdoc_options = %w{--main README.rdoc --charset utf-8 --line-numbers}
+
+ if s.respond_to? :specification_version then
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
+ s.specification_version = 2
+
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
+ s.add_runtime_dependency("httparty", [">= 0.2.6"])
+ s.add_runtime_dependency("curb", [">= 0.1.4"])
+ else
+ s.add_dependency("httparty", [">= 0.2.6"])
+ s.add_dependency("curb", [">= 0.1.4"])
+ end
+ else
+ s.add_dependency("httparty", [">= 0.2.6"])
+ s.add_dependency("curb", [">= 0.1.4"])
+ end
+end
@@ -0,0 +1,2 @@
+:api_key: this is not a real api key
+:shared_secret: this is not a real shared secret
Oops, something went wrong.

0 comments on commit 8a57ca1

Please sign in to comment.