pamfaxr 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.bundle/config ADDED
@@ -0,0 +1,2 @@
1
+ ---
2
+ BUNDLE_DISABLE_SHARED_GEMS: "1"
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'mime-types'
4
+ gem 'json'
5
+
6
+ group :development do
7
+ gem "rspec", "~> 2.3.0"
8
+ gem "bundler", "~> 1.0.0"
9
+ gem "jeweler", "~> 1.5.2"
10
+ gem "rcov", ">= 0"
11
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,32 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ diff-lcs (1.1.2)
5
+ git (1.2.5)
6
+ jeweler (1.5.2)
7
+ bundler (~> 1.0.0)
8
+ git (>= 1.2.5)
9
+ rake
10
+ json (1.5.1)
11
+ mime-types (1.16)
12
+ rake (0.8.7)
13
+ rcov (0.9.9)
14
+ rspec (2.3.0)
15
+ rspec-core (~> 2.3.0)
16
+ rspec-expectations (~> 2.3.0)
17
+ rspec-mocks (~> 2.3.0)
18
+ rspec-core (2.3.1)
19
+ rspec-expectations (2.3.0)
20
+ diff-lcs (~> 1.1.2)
21
+ rspec-mocks (2.3.0)
22
+
23
+ PLATFORMS
24
+ ruby
25
+
26
+ DEPENDENCIES
27
+ bundler (~> 1.0.0)
28
+ jeweler (~> 1.5.2)
29
+ json
30
+ mime-types
31
+ rcov
32
+ rspec (~> 2.3.0)
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2010 Voxeo Corporation
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,45 @@
1
+ PamFaxr
2
+ =======
3
+
4
+ Ruby library for sending faxes via the [PamFax](http://pamfax.com) Simple API.
5
+
6
+ Overview
7
+ --------
8
+
9
+ You may send faxes using the PamFax API. See the [PamFax Developer](http://www.pamfax.biz/en/extensions/developers/) page for more details and how to get your developer key.
10
+
11
+ Requirements
12
+ ------------
13
+
14
+ Requires these gems, also in the Gemfile:
15
+
16
+ * json
17
+ * mime-types
18
+
19
+ Example
20
+ -------
21
+
22
+ # Create a new PamFaxr object
23
+ pamfaxr = PamFaxr.new :base_uri => 'https://sandbox-api.pamfax.biz',
24
+ :key => 'your_api_key',
25
+ :secret => 'your_api_secret',
26
+ :username => 'your_username',
27
+ :password => 'your_password'
28
+ # Create a new FaxJob
29
+ pamfaxr.create_fax_job
30
+ # Add the cover sheet
31
+ covers = pamfaxr.list_available_covers
32
+ pamfaxr.set_cover(covers['Covers']['content'][1]['id'], 'Foobar is here!')
33
+ # Add files
34
+ pamfaxr.add_remote_file('https://s3.amazonaws.com/pamfax-test/R-intro.pdf')
35
+ pamfaxr.add_file('examples/R-intro.pdf')
36
+ # Add a recipient
37
+ pamfaxr.add_recipient('+14155551212')
38
+ # Loop until the fax is ready to send
39
+ loop do
40
+ fax_state = pamfaxr.get_state
41
+ break if fax_state['FaxContainer']['state'] == 'ready_to_send'
42
+ sleep 5
43
+ end
44
+ # Send the fax
45
+ pamfaxr.send_fax
data/Rakefile ADDED
@@ -0,0 +1,46 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'rake'
11
+
12
+ require 'jeweler'
13
+ Jeweler::Tasks.new do |gem|
14
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
15
+ gem.name = "pamfaxr"
16
+ gem.homepage = "http://github.com/tropo/pamfaxr"
17
+ gem.license = "MIT"
18
+ gem.summary = "Ruby library for the PamFax API."
19
+ gem.description = "Ruby library for the FaxJob portion of the PamFax API."
20
+ gem.email = "jsgoecke@voxeo.com"
21
+ gem.authors = ["Jason Goecke"]
22
+ end
23
+ Jeweler::RubygemsDotOrgTasks.new
24
+
25
+ require 'rspec/core'
26
+ require 'rspec/core/rake_task'
27
+ RSpec::Core::RakeTask.new(:spec) do |spec|
28
+ spec.pattern = FileList['spec/**/*_spec.rb']
29
+ end
30
+
31
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
32
+ spec.pattern = 'spec/**/*_spec.rb'
33
+ spec.rcov = true
34
+ end
35
+
36
+ task :default => :spec
37
+
38
+ require 'rake/rdoctask'
39
+ Rake::RDocTask.new do |rdoc|
40
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
41
+
42
+ rdoc.rdoc_dir = 'rdoc'
43
+ rdoc.title = "foobar #{version}"
44
+ rdoc.rdoc_files.include('README*')
45
+ rdoc.rdoc_files.include('lib/**/*.rb')
46
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
Binary file
@@ -0,0 +1,93 @@
1
+ require 'rubygems'
2
+ require 'lib/pamfaxr'
3
+ require 'awesome_print'
4
+
5
+ PAMFAX_URI = 'https://sandbox-api.pamfax.biz'
6
+ PAMFAX_KEY = 'your_key'
7
+ PAMFAX_SECRET = 'your_secret'
8
+ PAMFAX_USERNAME = 'your_username'
9
+ PAMFAX_PASSWORD = 'your_password'
10
+
11
+ pamfaxr = PamFaxr.new :base_uri => PAMFAX_URI,
12
+ :key => PAMFAX_KEY,
13
+ :secret => PAMFAX_SECRET,
14
+ :username => PAMFAX_USERNAME,
15
+ :password => PAMFAX_PASSWORD
16
+
17
+ # Create a faxjob
18
+ faxjob = pamfaxr.create_fax_job
19
+ ap 'Creating a fax job'
20
+ ap '*'*10
21
+ ap faxjob
22
+
23
+ # Add a cover
24
+ covers = pamfaxr.list_available_covers
25
+ ap 'Listing available covers'
26
+ ap '*'*10
27
+ ap covers
28
+ ap 'Adding a cover'
29
+ ap '*'*10
30
+ ap pamfaxr.set_cover(covers['Covers']['content'][1]['id'], 'Foobar is here!')
31
+
32
+ ap 'Adding a remote file'
33
+ ap '*'*10
34
+ ap pamfaxr.add_remote_file('https://s3.amazonaws.com/pamfax-test/R-intro.pdf')
35
+
36
+ ap 'Adding a local file'
37
+ ap '*'*10
38
+ file = pamfaxr.add_file('examples/R-intro.pdf')
39
+ ap file
40
+
41
+ ap 'Removing a file'
42
+ ap '*'*10
43
+ ap pamfaxr.remove_file(file['FaxContainerFile']['file_uuid'])
44
+
45
+ ap 'Adding a recipient'
46
+ ap '*'*10
47
+ ap pamfaxr.add_recipient('+14155551212')
48
+
49
+ ap 'Adding a second recipient'
50
+ ap '*'*10
51
+ recipient = pamfaxr.add_recipient('+13035551212')
52
+ ap recipient
53
+
54
+ ap 'Removing a recipient'
55
+ ap '*'*10
56
+ ap pamfaxr.remove_file(recipient['FaxRecipient']['number'])
57
+
58
+ ap 'Listing a recipient'
59
+ ap '*'*10
60
+ ap pamfaxr.list_recipients
61
+
62
+ ap 'Listing associated fax files'
63
+ ap '*'*10
64
+ ap pamfaxr.list_fax_files
65
+
66
+ ap 'Checking state'
67
+ ap '*'*10
68
+ time = 0
69
+ loop do
70
+ fax_state = pamfaxr.get_state
71
+ ap fax_state
72
+ converting = true
73
+ break if fax_state['FaxContainer']['state'] == 'ready_to_send'
74
+ sleep 2
75
+ time += 2
76
+ ap "#{time.to_s} seconds elapsed..."
77
+ end
78
+
79
+ ap 'Preview the fax'
80
+ ap '*'*10
81
+ ap pamfaxr.get_preview(faxjob['FaxContainer']['uuid'])
82
+
83
+ ap 'Sent the fax'
84
+ ap '*'*10
85
+ ap pamfaxr.send_fax
86
+
87
+ ap 'Sent the fax later'
88
+ ap '*'*10
89
+ ap pamfaxr.send_fax_later
90
+
91
+ ap 'Cloning the fax'
92
+ ap '*'*10
93
+ ap pamfaxr.clone_fax(faxjob['FaxContainer']['uuid'])
@@ -0,0 +1,75 @@
1
+ # Takes a hash of string and file parameters and returns a string of text
2
+ # formatted to be sent as a multipart form post.
3
+ #
4
+ # Author:: Cody Brimhall <mailto:cbrimhall@ucdavis.edu>
5
+ # Created:: 22 Feb 2008
6
+
7
+ module Multipart
8
+ VERSION = "1.0.0" unless const_defined?(:VERSION)
9
+
10
+ # Formats a given hash as a multipart form post
11
+ # If a hash value responds to :string or :read messages, then it is
12
+ # interpreted as a file and processed accordingly; otherwise, it is assumed
13
+ # to be a string
14
+ class Post
15
+ # We have to pretend like we're a web browser...
16
+ USERAGENT = "Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/523.10.6 (KHTML, like Gecko) Version/3.0.4 Safari/523.10.6" unless const_defined?(:USERAGENT)
17
+ BOUNDARY = "0123456789ABLEWASIEREISAWELBA9876543210" unless const_defined?(:BOUNDARY)
18
+ CONTENT_TYPE = "multipart/form-data; boundary=#{ BOUNDARY }" unless const_defined?(:CONTENT_TYPE)
19
+ HEADER = { "Content-Type" => CONTENT_TYPE, "User-Agent" => USERAGENT } unless const_defined?(:HEADER)
20
+
21
+ def self.prepare_query(params)
22
+ fp = []
23
+
24
+ params.each do |k, v|
25
+ # Are we trying to make a file parameter?
26
+ if v.respond_to?(:path) and v.respond_to?(:read) then
27
+ fp.push(FileParam.new(k, v.path, v.read))
28
+ # We must be trying to make a regular parameter
29
+ else
30
+ fp.push(StringParam.new(k, v))
31
+ end
32
+ end
33
+
34
+ # Assemble the request body using the special multipart format
35
+ query = fp.collect {|p| "--" + BOUNDARY + "\r\n" + p.to_multipart }.join("") + "--" + BOUNDARY + "--"
36
+ return query, HEADER
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ # Formats a basic string key/value pair for inclusion with a multipart post
43
+ class StringParam
44
+ attr_accessor :k, :v
45
+
46
+ def initialize(k, v)
47
+ @k = k
48
+ @v = v
49
+ end
50
+
51
+ def to_multipart
52
+ return "Content-Disposition: form-data; name=\"#{CGI::escape(k)}\"\r\n\r\n#{v}\r\n"
53
+ end
54
+ end
55
+
56
+ # Formats the contents of a file or string for inclusion with a multipart
57
+ # form post
58
+ class FileParam
59
+ attr_accessor :k, :filename, :content
60
+
61
+ def initialize(k, filename, content)
62
+ @k = k
63
+ @filename = filename
64
+ @content = content
65
+ end
66
+
67
+ def to_multipart
68
+ # If we can tell the possible mime-type from the filename, use the
69
+ # first in the list; otherwise, use "application/octet-stream"
70
+ mime_type = MIME::Types.type_for(filename)[0] || MIME::Types["application/octet-stream"][0]
71
+ return "Content-Disposition: form-data; name=\"#{CGI::escape(k)}\"; filename=\"#{ filename }\"\r\n" +
72
+ "Content-Type: #{ mime_type.simplified }\r\n\r\n#{ content }\r\n"
73
+ end
74
+ end
75
+ end