dcparker-shopify 0.1.0

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/CHANGELOG ADDED
@@ -0,0 +1 @@
1
+ v0.1.0 First release, a rewrite of Shopify's own Rails plugin, turned into a gem with similar workings.
data/LICENSE ADDED
File without changes
data/Manifest ADDED
@@ -0,0 +1,13 @@
1
+ CHANGELOG
2
+ lib/shopify/address.rb
3
+ lib/shopify/order.rb
4
+ lib/shopify/product.rb
5
+ lib/shopify/sale.rb
6
+ lib/shopify/session.rb
7
+ lib/shopify/shop.rb
8
+ lib/shopify/site.rb
9
+ lib/shopify.rb
10
+ LICENSE
11
+ Manifest
12
+ README
13
+ shopify.gemspec
data/README ADDED
@@ -0,0 +1,9 @@
1
+ Example Usage:
2
+
3
+ Shopify.current_session = Shopify::Session.new('store_name', 'api-key', 'api-secret')
4
+ Shopify.current_session.token = 'api-session-token'
5
+ Shopify.apply_current_session!
6
+
7
+ Shopify::Shop.current
8
+ Shopify::Product.find(:first)
9
+ Shopify::Order.find(:first)
data/lib/shopify.rb ADDED
@@ -0,0 +1,93 @@
1
+ module Shopify
2
+ autoload :Session, 'shopify/session'
3
+ autoload :Shop, 'shopify/shop'
4
+ autoload :Product, 'shopify/product'
5
+ autoload :Variant, 'shopify/product'
6
+ autoload :Image, 'shopify/product'
7
+ autoload :Order, 'shopify/order'
8
+ autoload :LineItem, 'shopify/order'
9
+ autoload :ShippingLine, 'shopify/order'
10
+ autoload :CustomCollection, 'shopify/order'
11
+ autoload :ShippingAddress, 'shopify/address'
12
+ autoload :BillingAddress, 'shopify/address'
13
+ autoload :Country, 'shopify/address'
14
+ autoload :Province, 'shopify/address'
15
+ autoload :Sale, 'shopify/sale'
16
+ autoload :Authorization, 'shopify/sale'
17
+ autoload :Payment, 'shopify/sale'
18
+ autoload :Page, 'shopify/site'
19
+ autoload :Blog, 'shopify/site'
20
+ autoload :Article, 'shopify/site'
21
+
22
+ class << self
23
+ attr_reader :key, :secret
24
+
25
+ # Lists the session stack.
26
+ def sessions
27
+ @sessions ||= []
28
+ end
29
+
30
+ # Returns the last session on the sessions stack.
31
+ def current_session
32
+ sessions.last
33
+ end
34
+
35
+ # Sets the current_session / appends a session to the sessions stack.
36
+ def current_session=(session)
37
+ sessions << session
38
+ end
39
+
40
+ # Injects the generated site (with basic auth params) into the ActiveResource::Base subclasses.
41
+ def apply_current_session!
42
+ current_session.apply!
43
+ end
44
+
45
+ # Perform a block within a specific session, and reset the current session to the previous after execution.
46
+ def with_session(session,&block)
47
+ sessions << session
48
+ apply_current_session!
49
+ result = yield
50
+ sessions.pop
51
+ apply_current_session!
52
+ return result
53
+ end
54
+ end
55
+ end
56
+
57
+ # To fix a silly bug in ActiveResource loading... :(
58
+ module Enumerable # :nodoc: all
59
+ def group_by
60
+ end
61
+ end
62
+
63
+ # Load ActiveResource
64
+ gem 'activeresource', '>= 2.1.0'
65
+ require 'active_resource'
66
+ module ActiveResource # :nodoc: all
67
+ class Base
68
+ class << self
69
+ def site
70
+ # Not using superclass_delegating_reader because don't want subclasses to modify superclass instance
71
+ #
72
+ # With superclass_delegating_reader
73
+ #
74
+ # Parent.site = 'http://anonymous@test.com'
75
+ # Subclass.site # => 'http://anonymous@test.com'
76
+ # Subclass.site.user = 'david'
77
+ # Parent.site # => 'http://david@test.com'
78
+ #
79
+ # Without superclass_delegating_reader (expected behaviour)
80
+ #
81
+ # Parent.site = 'http://anonymous@test.com'
82
+ # Subclass.site # => 'http://anonymous@test.com'
83
+ # Subclass.site.user = 'david' # => TypeError: can't modify frozen object
84
+ #
85
+ if defined?(@site)
86
+ @site
87
+ elsif superclass != Object && superclass.site
88
+ superclass.site.dup.freeze
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,17 @@
1
+ module Shopify
2
+ class ShippingAddress < ActiveResource::Base
3
+ end
4
+
5
+ class BillingAddress < ActiveResource::Base
6
+ def name
7
+ "#{first_name} #{last_name}"
8
+ end
9
+ end
10
+
11
+ class Country < ActiveResource::Base
12
+ end
13
+
14
+ class Province < ActiveResource::Base
15
+ self.prefix = "/admin/countries/:country_id/"
16
+ end
17
+ end
@@ -0,0 +1,36 @@
1
+ module Shopify
2
+ class Order < ActiveResource::Base
3
+ def fulfilled?
4
+ !!fulfillment_status
5
+ end
6
+
7
+ def closed?
8
+ closed_at < Time.now
9
+ end
10
+
11
+ def close
12
+ load_attributes_from_response(post(:close))
13
+ end
14
+
15
+ def open
16
+ load_attributes_from_response(post(:open))
17
+ end
18
+
19
+ def payments
20
+ Payment.get
21
+ end
22
+
23
+ def capture(amount=nil)
24
+ load_attributes_from_response(post(:capture, :amount => amount))
25
+ end
26
+ end
27
+
28
+ class LineItem < ActiveResource::Base
29
+ end
30
+
31
+ class ShippingLine < ActiveResource::Base
32
+ end
33
+
34
+ class CustomCollection < ActiveResource::Base
35
+ end
36
+ end
@@ -0,0 +1,45 @@
1
+ module Shopify
2
+ class Product < ActiveResource::Base
3
+ class << self
4
+ # Share all items of this store with the shopify marketplace
5
+ def share_all
6
+ post :share
7
+ end
8
+ # Stop sharing all items of this store with the shopify marketplace
9
+ def unshare_all
10
+ delete :share
11
+ end
12
+ end
13
+
14
+ # Auto-compute the price range
15
+ def price_range
16
+ prices = variants.collect(&:price)
17
+ format = "%0.2f"
18
+ if prices.min != prices.max
19
+ "#{format % prices.min} - #{format % prices.max}"
20
+ else
21
+ format % prices.min
22
+ end
23
+ end
24
+ end
25
+
26
+ class Variant < ActiveResource::Base
27
+ self.prefix = "/admin/products/:product_id/"
28
+ end
29
+
30
+ class Image < ActiveResource::Base
31
+ self.prefix = "/admin/products/:product_id/"
32
+
33
+ # generate a method for each possible image variant
34
+ [:pico, :icon, :thumb, :small, :medium, :large, :original].each do |m|
35
+ reg_exp_match = "/\\1_#{m}.\\2"
36
+ define_method(m) { src.gsub(/\/(.*)\.(\w{2,4})/, reg_exp_match) }
37
+ end
38
+
39
+ # Attach an image to a product.
40
+ def attach_image(data, filename = nil)
41
+ attributes[:attachment] = Base64.encode64(data)
42
+ attributes[:filename] = filename unless filename.nil?
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,11 @@
1
+ module Shopify
2
+ class Sale < Payment
3
+ end
4
+
5
+ class Authorization < Payment
6
+ end
7
+
8
+ class Payment < ActiveResource::Base
9
+ self.prefix = "/admin/orders/:order_id/"
10
+ end
11
+ end
@@ -0,0 +1,83 @@
1
+ require 'digest/md5'
2
+
3
+ module Shopify
4
+ # Shopify Session
5
+ #
6
+ # Example:
7
+ # class LoginController < ApplicationController
8
+ # layout 'empty'
9
+ #
10
+ # before { Shopify.sessions << Shopify::Session.new(session[:store_name] || params[:store_name], session[:shopify_token], SHOPIFY_APP_SECRET) if Shopify.sessions.empty? && (session[:store_name] || params[:store_name]) }
11
+ #
12
+ # def signin
13
+ # # ask user for his myshopify.com address.
14
+ # end
15
+ #
16
+ # # POST to this with the store name
17
+ # def login
18
+ # # Set the store_name into the session for future requests.
19
+ # session[:store_name] = params[:store_name]
20
+ # # This will redirect the user to their Shopify store to authorize your application.
21
+ # # Shopify will redirect the user back to your :finalize action when finished.
22
+ # redirect Shopify.current_session.permission_url
23
+ # end
24
+ #
25
+ # def finalize
26
+ # Shopify.current_session.token = params[:t]
27
+ # Shopify.apply_current_session!
28
+ # if Shopify.current_session.signed_in?
29
+ # redirect # logged in area
30
+ # else
31
+ # flash[:notice] = "Couldn't sign in to your shopify store."
32
+ # redirect url(:signin)
33
+ # end
34
+ # end
35
+ # end
36
+ #
37
+ class Session
38
+ cattr_accessor :protocol
39
+ self.protocol = 'http'
40
+
41
+ attr_accessor :host, :key, :secret, :token
42
+
43
+ def initialize(host, key=nil, secret=nil, token=nil)
44
+ host.gsub!(/https?:\/\//, '') # remove http://
45
+ host = "#{host}.myshopify.com" unless host.include?('.') # extend url to myshopify.com if no host is given
46
+
47
+ self.host = host
48
+ self.key = key
49
+ self.secret = secret
50
+ self.token = token
51
+ end
52
+
53
+ # mode can be either r to request read rights or w to request read/write rights.
54
+ def permission_url(mode='w')
55
+ "http://#{host}/admin/api/auth?api_key=#{key}&mode=#{mode}"
56
+ end
57
+
58
+ def apply!
59
+ ActiveResource::Base.site = site if signed_in?
60
+ end
61
+
62
+ # use this to initialize ActiveResource:
63
+ #
64
+ # ActiveResource::Base.site = Shopify.current_session.site
65
+ #
66
+ def site
67
+ "#{protocol}://#{key}:#{password}@#{host}/admin"
68
+ end
69
+
70
+ def signed_in?
71
+ [host, key, secret, token].all?
72
+ end
73
+
74
+ private
75
+
76
+ # The secret is computed by taking the shared_secret which we got when
77
+ # registring this third party application and concating the request_to it,
78
+ # and then calculating a MD5 hexdigest.
79
+ def password
80
+ Digest::MD5.hexdigest("#{secret.chomp}#{token.chomp}")
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,8 @@
1
+ module Shopify
2
+ class Shop
3
+ # Retrieves information from Shopify about your signed-in shop.
4
+ def self.current
5
+ ActiveResource::Base.find(:one, :from => "/admin/shop.xml")
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,14 @@
1
+ module Shopify
2
+ class Page < ActiveResource::Base
3
+ end
4
+
5
+ class Blog < ActiveResource::Base
6
+ def articles
7
+ Article.get
8
+ end
9
+ end
10
+
11
+ class Article < ActiveResource::Base
12
+ self.prefix = "/admin/blogs/:blog_id/"
13
+ end
14
+ end
data/shopify.gemspec ADDED
@@ -0,0 +1,37 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{shopify}
5
+ s.version = "0.1.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Daniel Parker"]
9
+ s.date = %q{2008-12-10}
10
+ s.description = %q{Easily communicate with Shopify.com's restful API.}
11
+ s.email = %q{gems@behindlogic.com}
12
+ s.extra_rdoc_files = ["CHANGELOG", "lib/shopify/address.rb", "lib/shopify/order.rb", "lib/shopify/product.rb", "lib/shopify/sale.rb", "lib/shopify/session.rb", "lib/shopify/shop.rb", "lib/shopify/site.rb", "lib/shopify.rb", "LICENSE", "README"]
13
+ s.files = ["CHANGELOG", "lib/shopify/address.rb", "lib/shopify/order.rb", "lib/shopify/product.rb", "lib/shopify/sale.rb", "lib/shopify/session.rb", "lib/shopify/shop.rb", "lib/shopify/site.rb", "lib/shopify.rb", "LICENSE", "Manifest", "README", "shopify.gemspec"]
14
+ s.has_rdoc = true
15
+ s.homepage = %q{http://github.com/dcparker/shopify/tree}
16
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Shopify", "--main", "README"]
17
+ s.require_paths = ["lib"]
18
+ s.rubyforge_project = %q{shopify}
19
+ s.rubygems_version = %q{1.3.1}
20
+ s.summary = %q{Easily communicate with Shopify.com's restful API.}
21
+
22
+ if s.respond_to? :specification_version then
23
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
24
+ s.specification_version = 2
25
+
26
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
27
+ s.add_runtime_dependency(%q<activeresource>, [">= 0", "= 2.1.0"])
28
+ s.add_development_dependency(%q<echoe>, [">= 0"])
29
+ else
30
+ s.add_dependency(%q<activeresource>, [">= 0", "= 2.1.0"])
31
+ s.add_dependency(%q<echoe>, [">= 0"])
32
+ end
33
+ else
34
+ s.add_dependency(%q<activeresource>, [">= 0", "= 2.1.0"])
35
+ s.add_dependency(%q<echoe>, [">= 0"])
36
+ end
37
+ end
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dcparker-shopify
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Daniel Parker
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-12-10 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activeresource
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
23
+ - - "="
24
+ - !ruby/object:Gem::Version
25
+ version: 2.1.0
26
+ version:
27
+ - !ruby/object:Gem::Dependency
28
+ name: echoe
29
+ version_requirement:
30
+ version_requirements: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ version:
36
+ description: Easily communicate with Shopify.com's restful API.
37
+ email: gems@behindlogic.com
38
+ executables: []
39
+
40
+ extensions: []
41
+
42
+ extra_rdoc_files:
43
+ - CHANGELOG
44
+ - lib/shopify/address.rb
45
+ - lib/shopify/order.rb
46
+ - lib/shopify/product.rb
47
+ - lib/shopify/sale.rb
48
+ - lib/shopify/session.rb
49
+ - lib/shopify/shop.rb
50
+ - lib/shopify/site.rb
51
+ - lib/shopify.rb
52
+ - LICENSE
53
+ - README
54
+ files:
55
+ - CHANGELOG
56
+ - lib/shopify/address.rb
57
+ - lib/shopify/order.rb
58
+ - lib/shopify/product.rb
59
+ - lib/shopify/sale.rb
60
+ - lib/shopify/session.rb
61
+ - lib/shopify/shop.rb
62
+ - lib/shopify/site.rb
63
+ - lib/shopify.rb
64
+ - LICENSE
65
+ - Manifest
66
+ - README
67
+ - shopify.gemspec
68
+ has_rdoc: true
69
+ homepage: http://github.com/dcparker/shopify/tree
70
+ post_install_message:
71
+ rdoc_options:
72
+ - --line-numbers
73
+ - --inline-source
74
+ - --title
75
+ - Shopify
76
+ - --main
77
+ - README
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: "0"
85
+ version:
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: "1.2"
91
+ version:
92
+ requirements: []
93
+
94
+ rubyforge_project: shopify
95
+ rubygems_version: 1.2.0
96
+ signing_key:
97
+ specification_version: 2
98
+ summary: Easily communicate with Shopify.com's restful API.
99
+ test_files: []
100
+