Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade from main source due to moving to new Shopify Inventory API #4

Open
wants to merge 68 commits into
base: quick-n-dirty-redo-request-if-error-is-temporary-rails-4-plus
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
ce3f84e
calculate credit_limit per shop
aalfson Jul 3, 2015
f88f3d3
remove application_id param from listing endpoints
Apr 26, 2017
f970a80
Merge pull request #354 from Shopify/remove_parameter_from_listings
peterjm Apr 27, 2017
bb0cff8
Packaging for release 4.7.0
Apr 27, 2017
4a908de
Merge pull request #355 from Shopify/gembump
peterjm Apr 27, 2017
cda62c5
fix bug with listing classes
Apr 27, 2017
5bb93ee
use the correct version number in the changelog
Apr 27, 2017
b74f47f
Merge pull request #356 from Shopify/fix_listing_bug
peterjm Apr 27, 2017
1ede895
Add new Engagement resource and new method for creating new marketing…
Apr 27, 2017
2802bef
Add new engagement json payload and new method for specs
Apr 27, 2017
ae00a5f
Add post call to spec
Apr 27, 2017
5eaaa6c
Properly call method in test
Apr 28, 2017
145abe6
Add space in hash
Apr 28, 2017
de375e7
Remove Engagement resource
May 2, 2017
4630049
Remove old instance of Engagement resource
May 2, 2017
51b6210
Properly access hash value
May 2, 2017
2257298
Build trigger
May 2, 2017
ae8b55d
Build trigger
May 3, 2017
fca167b
add URL parameters to metafiels
julian-huff Nov 21, 2016
df92861
Merge pull request #320 from rewindit/#215_metafields_pagination
exterm May 3, 2017
4aed8ed
Properly convert single hash to array of hashes
May 4, 2017
31a1701
Merge pull request #357 from kingscott/master
meunierd May 9, 2017
9dafa4b
Bump Gemfile version to 4.8.0
meunierd May 9, 2017
0b1cc17
Merge pull request #360 from Shopify/version-bump
meunierd May 9, 2017
24d15aa
Clarify session instantiation in README
jamiemtdwyer May 14, 2017
14002a2
Merge pull request #362 from Shopify/jamiemtdwyer-patch-1
jamiemtdwyer May 15, 2017
62d4ce1
fix link to Shopify API reference
djones May 18, 2017
efff684
Merge pull request #363 from djones/master
ShayneP May 23, 2017
3bb7b35
Updating two links
May 24, 2017
3102440
Remove unneeded Rails 5 instructions
jeromedalbert May 27, 2017
9615ddb
Adds price rule class
jordanliddle Mar 8, 2017
c8d1d5a
Adds tests for price rules
jordanliddle Mar 9, 2017
7d6c323
Merge pull request #335 from Shopify/price-rules
jordanliddle May 29, 2017
deede47
Bump gem to version 4.9.0
jordanliddle May 29, 2017
7d4ef9d
Merge pull request #368 from Shopify/bump-version
jordanliddle May 29, 2017
4834275
Merge pull request #365 from Shopify/update_readme
ShayneP Jun 6, 2017
81474d2
Merge pull request #366 from jeromedalbert/remove-rails-5-instructions
jamiemtdwyer Jun 20, 2017
fcdd350
Merge pull request #197 from aalfson/master
jamiemtdwyer Jun 23, 2017
01748fa
Rename customer_invite_message.rb to customer_invite.rb
jamiemtdwyer Jan 26, 2018
4db2d83
Merge pull request #408 from Shopify/rename-customer-invite
jamiemtdwyer Jan 26, 2018
a9063f2
Remove deprecated Discount resource
jamiemtdwyer Jan 26, 2018
cc412df
Merge pull request #409 from Shopify/remove-discount-resource
jamiemtdwyer Jan 29, 2018
f774731
Fetch order with Bold Options properties
rebeccajfriedman Jan 28, 2018
bbe8e79
Merge pull request #410 from Shopify/order_with_bold_options
rebeccajfriedman Feb 12, 2018
86e5fd4
release version 4.9.1
rebeccajfriedman Feb 12, 2018
fcec962
Merge pull request #412 from Shopify/bump_version
rebeccajfriedman Feb 12, 2018
37e5f53
Add Access Scope
ayronshopify Feb 22, 2018
02bc44d
Merge pull request #413 from Shopify/add-access-scope
ayronshopify Feb 23, 2018
6dc2651
Bump gem version to 4.10.0
ayronshopify Feb 23, 2018
36ac117
Merge pull request #414 from Shopify/bump_version
ayronshopify Feb 23, 2018
0b37ca8
Unwrap close and open methods
vinibrsl Feb 26, 2018
2c3d3d3
Remove trailing whitespaces from lib/
Feb 28, 2018
e9419be
add inventory api
jtgrenz Feb 23, 2018
4a4bca7
add location inventory_levels method
jtgrenz Mar 5, 2018
f05c460
code style adjustments
jtgrenz Mar 7, 2018
fcac5d3
Merge pull request #416 from vnbrs/patch-1
jamiemtdwyer Mar 7, 2018
e1d8988
Merge pull request #417 from vnbrs/remove-trailing-whitespaces
jamiemtdwyer Mar 12, 2018
3a9c0de
Merge pull request #415 from Shopify/inventory_api
jtgrenz Mar 12, 2018
2b91667
packaging for release 4.11.0
jtgrenz Mar 12, 2018
f2fd0d6
Merge pull request #422 from Shopify/locations-api-release
jtgrenz Mar 12, 2018
b351a81
typo in change log v4.11.0
jtgrenz Mar 12, 2018
eae44b2
Add a quick and dirty implementation of redoing a request in case of
DanielVartanov Mar 21, 2014
564a56d
Allow us to prevent automatic retries for the current thread
721p Apr 15, 2015
f6cd5c3
Use correct syntax of Object.in?
DanielVartanov Oct 27, 2016
fdbff69
Enrich response 4xx error message with body error text
vbyno Dec 4, 2019
74ca461
Merge pull request #2 from vbyno/enriched_messages
ulandj Dec 9, 2019
d1783c6
Take into account semantical 'errors' key in JSON body
vbyno Jan 29, 2020
69144f6
Merge pull request #3 from vbyno/quick-n-dirty-redo-request-if-error-…
ulandj Jan 30, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,36 @@
== Version 4.11.0

* Added `ShopifyAPI::InventoryItem`
* Added `ShopifyAPI::InventoryLevel`
* Added `#inventory_levels` method to `ShopifyAPI::Location`

== Version 4.10.0

* Added `ShopifyAPI::AccessScope`

== Version 4.9.1

* Fix a bug with custom properties for orders

== Version 4.9.0

* Added `ShopifyAPI::PriceRule`
* Added `ShopifyAPI::DiscountCode`

== Version 4.8.0

* Added `add_engagements` to `ShopifyAPI::MarketingEvent`

== Version 4.7.1

* Added support for URL parameter (e.g. limit & page) to ShopifyAPI::Metafields
* Added support for URL parameter (e.g. limit & page) to metafield operator in ShopifyAPI::Shop

== Version 4.7.0

* Removed the mandatory `application_id` parameter from `ShopifyAPI::ProductListing` and `ShopifyAPI::CollectionListing`
* Fixed a bug related to the non-standard primary key for `ShopifyAPI::ProductListing` and `ShopifyAPI::CollectionListing`

== Version 4.6.0

* Added `ShopifyAPI::Report`
Expand Down
15 changes: 3 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ All API usage happens through Shopify applications, created by either shop owner
* Shop owners can create applications for themselves through their own admin: https://docs.shopify.com/api/authentication/creating-a-private-app
* Shopify Partners create applications through their admin: http://app.shopify.com/services/partners

For more information and detailed documentation about the API visit http://api.shopify.com
For more information and detailed documentation about the API visit https://developers.shopify.com/

#### Ruby version

Expand All @@ -39,15 +39,6 @@ Or install via [gem](http://rubygems.org/)
gem install shopify_api
```

#### Rails 5

shopify_api is compatible with Rails 5 but since the latest ActiveResource release (4.1) is locked on Rails 4.x, you'll need to use the unreleased master version:

```ruby
gem 'shopify_api'
gem 'activeresource', github: 'rails/activeresource'
```

### Getting Started

ShopifyAPI uses ActiveResource to communicate with the REST web service. ActiveResource has to be configured with a fully authorized URL of a particular store first. To obtain that URL you can follow these steps:
Expand All @@ -59,7 +50,7 @@ ShopifyAPI uses ActiveResource to communicate with the REST web service. ActiveR
2. For a private App you just need to set the base site url as follows:

```ruby
shop_url = "https://#{API_KEY}:#{PASSWORD}@SHOP_NAME.myshopify.com/admin"
shop_url = "https://#{API_KEY}:#{PASSWORD}@#{SHOP_NAME}.myshopify.com/admin"
ShopifyAPI::Base.site = shop_url
```

Expand Down Expand Up @@ -246,7 +237,7 @@ rake install

## Additional Resources

API Docs: http://docs.shopify.com/api
API Reference: https://help.shopify.com/api/reference

Ask questions on the forums: http://ecommerce.shopify.com/c/shopify-apis-and-technology

Expand Down
1 change: 1 addition & 0 deletions lib/active_resource/connection_ext.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ class Connection

prepend ShopifyAPI::Connection::ResponseCapture
prepend ShopifyAPI::Connection::RequestNotification
prepend ShopifyAPI::Connection::RedoIfTemporaryError
end
end
1 change: 1 addition & 0 deletions lib/shopify_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ module ShopifyAPI
require 'shopify_api/countable'
require 'shopify_api/resources'
require 'shopify_api/session'
require 'shopify_api/message_enricher'
require 'shopify_api/connection'

if ShopifyAPI::Base.respond_to?(:connection_class)
Expand Down
25 changes: 24 additions & 1 deletion lib/shopify_api/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class Connection < ActiveResource::Connection

module ResponseCapture
def handle_response(response)
@response = super
@response = super(ShopifyAPI::MessageEnricher.new(response))
end
end

Expand All @@ -29,5 +29,28 @@ def notify_about_request(response, arguments)
end

include RequestNotification

module RedoIfTemporaryError
def request(*args)
super
rescue ActiveResource::ClientError, ActiveResource::ServerError => e
if should_retry? && e.response.class.in?([Net::HTTPTooManyRequests, Net::HTTPInternalServerError])
wait
request *args
else
raise
end
end

def wait
sleep 0.5
end

def should_retry?
[true, nil].include? Thread.current[:retry_temporary_errors]
end
end

include RedoIfTemporaryError
end
end
3 changes: 1 addition & 2 deletions lib/shopify_api/limits.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ def credit_maxed?
# @return {Integer}
#
def credit_limit(scope=:shop)
@api_credit_limit ||= {}
@api_credit_limit[scope] ||= api_credit_limit_param(scope).pop.to_i - 1
api_credit_limit_param(scope).pop.to_i - 1
end
alias_method :call_limit, :credit_limit

Expand Down
23 changes: 23 additions & 0 deletions lib/shopify_api/message_enricher.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true

class ShopifyAPI::MessageEnricher < SimpleDelegator
def message
return super unless (400...500).include?(code.to_i)

@_cached_message ||= begin
detailed_error = begin
parsed_body = JSON.parse(body)

if parsed_body['error']
parsed_body['error'].to_s
elsif parsed_body['errors']
Array(parsed_body['errors']).join('; ')
end
rescue JSON::ParserError
nil
end

detailed_error.present? ? "#{super} (#{detailed_error})" : super
end
end
end
6 changes: 4 additions & 2 deletions lib/shopify_api/metafields.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
module ShopifyAPI
module Metafields
def metafields
Metafield.find(:all, :params => {:resource => self.class.collection_name, :resource_id => id})
def metafields(**options)
options.merge! resource: self.class.collection_name, resource_id: id

Metafield.find :all, params: options
end

def add_metafield(metafield)
Expand Down
5 changes: 5 additions & 0 deletions lib/shopify_api/resources/access_scope.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module ShopifyAPI
class AccessScope < Base
self.prefix = '/admin/oauth/'
end
end
16 changes: 8 additions & 8 deletions lib/shopify_api/resources/asset.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def self.element_path(id, prefix_options = {}, query_options = nil) #:nodoc:
prefix_options, query_options = split_options(prefix_options) if query_options.nil?
"#{prefix(prefix_options)}#{collection_name}.#{format.extension}#{query_string(query_options)}"
end

# find an asset by key:
# ShopifyAPI::Asset.find('layout/theme.liquid', :params => {:theme_id => 99})
def self.find(*args)
Expand All @@ -57,36 +57,36 @@ def self.find(*args)
resource
end
end

# For text assets, Shopify returns the data in the 'value' attribute.
# For binary assets, the data is base-64-encoded and returned in the
# 'attachment' attribute. This accessor returns the data in both cases.
def value
attributes['value'] ||
(attributes['attachment'] ? Base64.decode64(attributes['attachment']) : nil)
end

def attach(data)
self.attachment = Base64.encode64(data)
end

def destroy
connection.delete(element_path(prefix_options.merge(:asset => {:key => key})), self.class.headers)
end

def new?
false
end

def method_missing(method_symbol, *arguments) #:nodoc:
if %w{value= attachment= src= source_key=}.include?(method_symbol)
wipe_value_attributes
end
super
end

private

def wipe_value_attributes
%w{value attachment src source_key}.each do |attr|
attributes.delete(attr)
Expand Down
2 changes: 1 addition & 1 deletion lib/shopify_api/resources/billing_address.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module ShopifyAPI
class BillingAddress < Base
end
end
end
6 changes: 3 additions & 3 deletions lib/shopify_api/resources/collection_listing.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
module ShopifyAPI
class CollectionListing < Base
init_prefix :application
self.primary_key = :collection_id

def product_ids(options = {})
get("#{collection_id}/product_ids", options[:params])
def product_ids
get(:product_ids)
end
end
end
6 changes: 3 additions & 3 deletions lib/shopify_api/resources/custom_collection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ class CustomCollection < Base
def products
Product.find(:all, :params => {:collection_id => self.id})
end

def add_product(product)
Collect.create(:collection_id => self.id, :product_id => product.id)
end

def remove_product(product)
collect = Collect.find(:first, :params => {:collection_id => self.id, :product_id => product.id})
collect.destroy if collect
end
end
end
end
11 changes: 0 additions & 11 deletions lib/shopify_api/resources/discount.rb

This file was deleted.

9 changes: 9 additions & 0 deletions lib/shopify_api/resources/discount_code.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module ShopifyAPI
class DiscountCode < Base
init_prefix :price_rule

def price_rule_id
@prefix_options[:price_rule_id]
end
end
end
4 changes: 2 additions & 2 deletions lib/shopify_api/resources/image.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
module ShopifyAPI
class Image < Base
init_prefix :product

# generate a method for each possible image variant
[:pico, :icon, :thumb, :small, :compact, :medium, :large, :grande, :original].each do |m|
reg_exp_match = "/\\1_#{m}.\\2"
define_method(m) { src.gsub(/\/(.*)\.(\w{2,4})/, reg_exp_match) }
end

def attach_image(data, filename = nil)
attributes['attachment'] = Base64.encode64(data)
attributes['filename'] = filename unless filename.nil?
Expand Down
6 changes: 6 additions & 0 deletions lib/shopify_api/resources/inventory_item.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

module ShopifyAPI
class InventoryItem < Base
end
end
55 changes: 55 additions & 0 deletions lib/shopify_api/resources/inventory_level.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# frozen_string_literal: true

module ShopifyAPI
class InventoryLevel < Base

# The default path structure in ActiveResource for delete would result in:
# /admin/inventory_levels/#{ inventory_level.id }.json?#{ params }, but since
# InventroyLevels are a second class resource made up of a Where and a What
# (Location and InventoryItem), it does not have a resource ID. Here we
# redefine element_path to remove the id so HTTP DELETE requests go to
# /admin/inventory_levels.json?#{ params } instead.
#
def self.element_path(prefix_options = {}, query_options = nil)
prefix_options, query_options = split_options(prefix_options) if query_options.nil?
"#{prefix(prefix_options)}#{collection_name}.#{format.extension}#{query_string(query_options)}"
end

def destroy
load_attributes_from_response(
self.class.delete('/', location_id: location_id, inventory_item_id: inventory_item_id)
)
end

def connect(relocate_if_necessary: nil)
body = { location_id: location_id, inventory_item_id: inventory_item_id }
body[:relocate_if_necessary] = relocate_if_necessary unless relocate_if_necessary.nil?
load_attributes_from_response(
self.class.post(:connect, {}, body.to_json)
)
end

def set(new_available, disconnect_if_necessary: nil)
body = {
location_id: location_id,
inventory_item_id: inventory_item_id,
available: new_available
}
body[:disconnect_if_necessary] = disconnect_if_necessary unless disconnect_if_necessary.nil?
load_attributes_from_response(
self.class.post(:set, {}, body.to_json)
)
end

def adjust(available_adjustment)
body = {
location_id: location_id,
inventory_item_id: inventory_item_id,
available_adjustment: available_adjustment
}
load_attributes_from_response(
self.class.post(:adjust, {}, body.to_json)
)
end
end
end
10 changes: 9 additions & 1 deletion lib/shopify_api/resources/line_item.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
module ShopifyAPI
class LineItem < Base
class LineItem < Base
class Property < Base
def initialize(*args)
attributes = args[0] || {}
persisted = args[1] || false
super
rescue NameError
attributes = attributes.to_hash
self
end
end
end
end
Loading