dcparker-shopify 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+