Permalink
Browse files

updating to 1.5.0

git-svn-id: svn+ssh://rubyforge.org/var/svn/shipping/trunk@30 5fa28239-6e07-0410-8d82-af6b04b6240c
  • Loading branch information...
1 parent 660d467 commit e9ac7012f1793b08fd5c1af0b759dc965a487bfc cardmagic committed Jul 11, 2007
Showing with 1,355 additions and 501 deletions.
  1. +12 −17 README
  2. +159 −4 Rakefile
  3. +11 −0 lib/extensions.rb
  4. +9 −2 lib/shipping.rb
  5. +159 −79 lib/shipping/base.rb
  6. +444 −283 lib/shipping/fedex.rb
  7. +432 −83 lib/shipping/ups.rb
  8. +10 −4 test/base/base_test.rb
  9. +57 −23 test/fedex/fedex_test.rb
  10. +62 −6 test/ups/ups_test.rb
View
29 README
@@ -1,6 +1,6 @@
== Welcome to Shipping
-Shipping is a module that connects APIs for various shippers like UPS and FedEx.
+Shipping is a module that connects APIs for various shippers like UPS and FedEx. Shipping currently supports pricing, shipping, labeling and voiding for UPS and FedEx through their XML APIs.
== Download
@@ -9,47 +9,42 @@ Shipping is a module that connects APIs for various shippers like UPS and FedEx.
* svn co http://rufy.com/svn/shipping/trunk
=== Usage
-
-There is going to be some data that will persist for all
-connections. For example, you will not want to repeat the fedex
-account number every time in your implementation code. To set default
-values, set up a file called .shipping.yml in the home directory of
-the user who will be using this library. An example file would be:
+There is going to be some data that will persist for all connections. For example, you will not want to repeat the fedex account number every time in your implementation code. To set default values, setup a file called .shipping.yml in the home directory of the user who will be using this library. An example file would be:
fedex_url: https://gatewaybeta.fedex.com/GatewayDC
fedex_account: 1234556
fedex_meter: 387878
- ups_account: 7B4F74E3075AEEFF
+ ups_url: https://wwwcie.ups.com/ups.app/xml
+ ups_license_number: 7B4F74E3075AEEFF
ups_user: username
ups_password: password
+ ups_shipper_number: 855AA0
-You can set as many default values as you would like in this file.
-Its name, location, and values are overridable on a per-connection
-basis.
-When it comes to actually getting a shipping quote, do something like this:
+You can set as many default values as you would like in this file.
require 'shipping'
- ups = Shipping::UPS.new :zip => 97202, :sender_zip => 10001, :weight => 2
- ups.price => 8.77
+ ups = Shipping::UPS.new :zip => 97202, :state => "OR", :sender_zip => 10001, :weight => 2
+ ups.price => 5.8
ups.valid_address? => false
ups.city = "Portland"
ups.valid_address? => true
-Alternately, you can instantiate the base class and then see both UPS and FedEx information:
+Alternately, you can instantiate the base class and then see both UPS and FedEx information.
ship = Shipping::Base.new :zip => 97202, :state => "OR", :sender_zip => 10001, :weight => 2
- ship.ups.price => 8.77
- ship.fedex.price => 5.17
+ ship.ups.price => 5.8
+ ship.fedex.price => 5.8
ship.city = "Portland"
ship.ups.valid_address? => true
== Authors
* Lucas Carlson (mailto:lucas@rufy.com)
+* Noah Zoschke (mailto:noah@bitscribe.net)
This library is released under the terms of the GNU LGPL.
View
163 Rakefile
@@ -4,8 +4,14 @@ require 'rake/testtask'
require 'rake/rdoctask'
require 'rake/gempackagetask'
require 'rake/contrib/rubyforgepublisher'
+require File.dirname(__FILE__) + '/lib/shipping'
-PKG_VERSION = "1.0.0"
+PKG_VERSION = Shipping::VERSION
+PKG_NAME = "shipping"
+PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
+RUBY_FORGE_PROJECT = "shipping"
+RUBY_FORGE_USER = ENV['RUBY_FORGE_USER'] || "cardmagic"
+RELEASE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
PKG_FILES = FileList[
"lib/**/*", "bin/*", "test/**/*", "[A-Z]*", "Rakefile", "doc/**/*"
@@ -32,7 +38,7 @@ end
desc "Create documentation"
Rake::RDocTask.new("doc") { |rdoc|
rdoc.title = "Ruby Shipping - UPS, FedEx, USPS"
- rdoc.rdoc_dir = 'doc'
+ rdoc.rdoc_dir = 'html'
rdoc.rdoc_files.include('README')
rdoc.rdoc_files.include('lib/**/*.rb')
}
@@ -90,7 +96,156 @@ end
desc "Publish new documentation"
task :publish do
- `ssh rufy update-shipping-doc`
- `scp pkg/shipping-1.0.0.* rufy:www/shipping.rufy.com/docs/`
Rake::RubyForgePublisher.new('shipping', 'cardmagic').upload
+ `ssh rufy update-shipping-doc`
+end
+
+desc "Publish the release files to RubyForge."
+task :upload => [:package] do
+ files = ["gem", "tgz", "zip"].map { |ext| "pkg/#{PKG_FILE_NAME}.#{ext}" }
+
+ if RUBY_FORGE_PROJECT then
+ require 'net/http'
+ require 'open-uri'
+
+ project_uri = "http://rubyforge.org/projects/#{RUBY_FORGE_PROJECT}/"
+ project_data = open(project_uri) { |data| data.read }
+ group_id = project_data[/[?&]group_id=(\d+)/, 1]
+ raise "Couldn't get group id" unless group_id
+
+ # This echos password to shell which is a bit sucky
+ if ENV["RUBY_FORGE_PASSWORD"]
+ password = ENV["RUBY_FORGE_PASSWORD"]
+ else
+ password = Proc.new do
+ sync = STDOUT.sync
+ begin
+ echo false
+ STDOUT.sync = true
+ print "#{RUBY_FORGE_USER}@rubyforge.org's password: "
+ STDIN.gets.chomp
+ ensure
+ echo true
+ STDOUT.sync = sync
+ puts
+ end
+ end.call
+ end
+
+ login_response = Net::HTTP.start("rubyforge.org", 80) do |http|
+ data = [
+ "login=1",
+ "form_loginname=#{RUBY_FORGE_USER}",
+ "form_pw=#{password}"
+ ].join("&")
+ http.post("/account/login.php", data)
+ end
+
+ cookie = login_response["set-cookie"]
+ raise "Login failed" unless cookie
+ headers = { "Cookie" => cookie }
+
+ release_uri = "http://rubyforge.org/frs/admin/?group_id=#{group_id}"
+ release_data = open(release_uri, headers) { |data| data.read }
+ package_id = release_data[/[?&]package_id=(\d+)/, 1]
+ raise "Couldn't get package id" unless package_id
+
+ first_file = true
+ release_id = ""
+
+ files.each do |filename|
+ basename = File.basename(filename)
+ file_ext = File.extname(filename)
+ file_data = File.open(filename, "rb") { |file| file.read }
+
+ puts "Releasing #{basename}..."
+
+ release_response = Net::HTTP.start("rubyforge.org", 80) do |http|
+ release_date = Time.now.strftime("%Y-%m-%d %H:%M")
+ type_map = {
+ ".zip" => "3000",
+ ".tgz" => "3110",
+ ".gz" => "3110",
+ ".gem" => "1400"
+ }; type_map.default = "9999"
+ type = type_map[file_ext]
+ boundary = "rubyqMY6QN9bp6e4kS21H4y0zxcvoor"
+
+ query_hash = if first_file then
+ {
+ "group_id" => group_id,
+ "package_id" => package_id,
+ "release_name" => RELEASE_NAME,
+ "release_date" => release_date,
+ "type_id" => type,
+ "processor_id" => "8000", # Any
+ "release_notes" => "",
+ "release_changes" => "",
+ "preformatted" => "1",
+ "submit" => "1"
+ }
+ else
+ {
+ "group_id" => group_id,
+ "release_id" => release_id,
+ "package_id" => package_id,
+ "step2" => "1",
+ "type_id" => type,
+ "processor_id" => "8000", # Any
+ "submit" => "Add This File"
+ }
+ end
+
+ query = "?" + query_hash.map do |(name, value)|
+ [name, URI.encode(value)].join("=")
+ end.join("&")
+
+ data = [
+ "--" + boundary,
+ "Content-Disposition: form-data; name=\"userfile\"; filename=\"#{basename}\"",
+ "Content-Type: application/octet-stream",
+ "Content-Transfer-Encoding: binary",
+ "", file_data, ""
+ ].join("\x0D\x0A")
+
+ release_headers = headers.merge(
+ "Content-Type" => "multipart/form-data; boundary=#{boundary}"
+ )
+
+ target = first_file ? "/frs/admin/qrs.php" : "/frs/admin/editrelease.php"
+ http.post(target + query, data, release_headers)
+ end
+
+ if first_file then
+ release_id = release_response.body[/release_id=(\d+)/, 1]
+ raise("Couldn't get release id") unless release_id
+ end
+
+ first_file = false
+ end
+ end
+end
+
+begin
+ if !defined?(USE_TERMIOS) || USE_TERMIOS
+ require 'termios'
+ else
+ raise LoadError
+ end
+
+ # Enable or disable stdin echoing to the terminal.
+ def echo(enable)
+ term = Termios::getattr(STDIN)
+
+ if enable
+ term.c_lflag |= (Termios::ECHO | Termios::ICANON)
+ else
+ term.c_lflag &= ~Termios::ECHO
+ end
+
+ Termios::setattr(STDIN, Termios::TCSANOW, term)
+ end
+rescue LoadError
+ def echo(enable)
+ end
end
View
@@ -0,0 +1,11 @@
+class Object
+ def blank?
+ if respond_to? :empty?
+ empty?
+ elsif respond_to? :zero?
+ zero?
+ else
+ !self
+ end
+ end
+end
View
@@ -24,17 +24,24 @@
# Copyright:: Copyright (c) 2005 Lucas Carlson
# License:: LGPL
+$:.unshift(File.dirname(__FILE__))
+
begin
require 'rubygems'
- require_gem 'builder', '~> 1.2'
rescue LoadError
- require 'builder'
+ nil
end
+require 'builder'
require 'yaml'
require 'rexml/document'
require 'net/http'
require 'net/https'
+require 'base64'
+require 'fileutils'
+require 'tempfile'
+
+require 'extensions'
require 'shipping/base'
require 'shipping/fedex'
require 'shipping/ups'
Oops, something went wrong.

0 comments on commit e9ac701

Please sign in to comment.