Skip to content

Instantly share code, notes, and snippets.

@schappim
Created June 20, 2012 22:34
Show Gist options
  • Save schappim/2962640 to your computer and use it in GitHub Desktop.
Save schappim/2962640 to your computer and use it in GitHub Desktop.
update_inventory.rb
#!/usr/bin/env ruby
# Version 00002
# Added notify script
# Version 00001
# Initial commit
require 'rubygems'
require 'mongo'
require 'mongo_mapper'
require 'open-uri'
require 'net/http'
require 'hpricot'
require 'progressbar'
require 'spinner'
# Setup the Mongo Database Connection
puts "--> Connecting to the Database."
MongoMapper.connection = Mongo::Connection.new("",)
MongoMapper.database = ''
MongoMapper.database.authenticate('', '')
puts "--> Authenticated to the Database."
# Define the Product Class
class MsProduct
include MongoMapper::Document
key :shopify_id, String
key :title, String
key :sku, String
key :shopify_inv, Integer
key :shopify_supplier_inv, Integer
key :supplier, String
key :price, Float
key :last_updated_in_shopify, Time
end
## Dump Products from Shopify
#
require 'active_resource'
require 'active_support'
require 'shopify_api'
KEY = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXc025f7e'
PASS = ''
BASE_SITE = "https://#{KEY}:#{PASS}@littlebirdstore.myshopify.com/admin"
ActiveResource::Base.site = BASE_SITE
puts "--> Successfully connected to Shopify."
@total_number_of_products = ShopifyAPI::Product.count
#
#@p_count = 0
#
#i = 0
#@pbar = ProgressBar.new("Shopify Dump", @total_number_of_products)
#while @p_count < @total_number_of_products + 1
# i = i + 1
# products = ShopifyAPI::Product.find(:all, :params => {:limit => 250, :page => i})
# products.each do |p|
# @p_count = @p_count + 1
# #puts @p_count
# @pbar.set(@p_count)
# #puts "#{@p_count}) #{p.variants.first.sku} | #{p.title} | #{p.id}"
#
# product = MsProduct.all(:shopify_id => "#{p.id}")
#
# if product.empty?
# ms_product = MsProduct.create({
# :shopify_id => p.id,
# :title => p.title,
# :sku => p.variants.first.sku,
# :shopify_inv => p.variants.first.inventory_quantity,
# #:shopify_supplier_inv => p.variants.first.option3,
# :price => p.variants.first.price
# })
# else
# end
# end
#end
#@pbar.finish
#
# Setup for Pololu Download
puts "--> Downloading Pololu Big Form"
doc = Hpricot.parse(open("http://www.pololu.com/catalog/bigorderform"))
table = doc.search('//table.product_comparison')
puts "--> Done downloading Pololu Big Form"
puts "--> Importing Pololu"
pbar = ProgressBar.new("Importing", table.search("//tr").length)
x = 0
table.search("//tr").each do |tr|
x = x + 1
pbar.set(x)
a = (tr/"a").first
unless a.nil?
sku = a.attributes['href'].gsub('/catalog/product/','')
inv = (tr/"td")[3].inner_html
product = MsProduct.all(:conditions => {'sku' => sku}).first
if product.respond_to?('sku')
old_shopify_supplier_inv = product.shopify_supplier_inv
new_shopify_supplier_inv = inv
product.shopify_supplier_inv = inv
product.supplier = "pololu"
product.save
#puts " --> Updating :#{sku}. (#{i}/#{(doc/:product).length})"
else
end
else
end
end
pbar.finish
pbar.clear
puts "--> Completed Pololu import"
# Get the latest Sparkfun product inventory XML file
puts "--> Downloading latest Sparkfun XML inventory file."
Net::HTTP.start('www.sparkfun.com') {|http|
req = Net::HTTP::Get.new('/distro/products.xml')
req.basic_auth '', ''
Spinner::with_spinner(:message=>"Downloading...") do |spin|
http.request(req) do |r|
@body = ""
r.read_body do |s|
spin.call
@body << s
end
end
end
#@body = response.body
}
puts "--> Download Complete."
# Parse the XML file
puts "--> Parsing XML File."
doc = Hpricot(@body)
puts "--> Done."
# Interate through the product list, and update inventory in Mongo
i = 0
puts "--> Importing Sparkfun inventory into MongoDB."
pbar = ProgressBar.new("Importing", (doc/:product).length)
(doc/:product).each do |xml_product|
@sf_qty = 0
i = i + 1
pbar.set(i)
sku = (xml_product/:sku).first.innerHTML
qty = (xml_product/:quantity).first.innerHTML
@sf_qty = (xml_product/:quantity).first.innerHTML # hack
product = MsProduct.all(:conditions => {'sku' => sku}).first
if product.respond_to?('sku')
old_shopify_supplier_inv = product.shopify_supplier_inv
new_shopify_supplier_inv = qty
product.shopify_supplier_inv = @sf_qty
product.supplier = "sparkfun"
product.save
#puts " --> Updating #{sku}. (#{i}/#{(doc/:product).length})"
else
end
end
pbar.finish
# Fetch all products from the Mongo Database
puts "--> Fetching all Products from Mongo."
products = MsProduct.where(:supplier => ['pololu','sparkfun'])
puts "--> Done."
# Connecting to Shopify
puts "--> Connecting to Shopify."
# Pushing Inventory over to Shopify
puts "--> Sending Inventory to Shopify."
@pbar = ProgressBar.new("Inventory Import", products.count)
prod_num = 0 #just a counter
products.each do |product|
prod_num = prod_num + 1
#puts "Doing product #{prod_num}/#{products.count}..."
@pbar.set(prod_num)
begin
shopify_product = ShopifyAPI::Product.find(product.shopify_id)
shopify_product.variants.first.compare_at_price = product.shopify_supplier_inv.to_i
puts "-> Updated stock of: #{shopify_product.variants.first.sku} to #{shopify_product.variants.first.compare_at_price}"
shopify_product.save
puts "\n\n"
puts product.inspect
rescue ActiveResource::ResourceNotFound
product.delete
puts "[Warning] Shopify does not have product #{product.inspect}"
puts "Our search string is ShopifyAPI::Product.find(#{product.shopify_id})"
rescue ActiveResource::ServerError
puts "-> Encoutered a server error"
sec = 0
while sec < 600
puts "Sleeping #{sec}/600"
sec = sec + 1
sleep(1)
end
begin
shopify_product = ShopifyAPI::Product.find(product.shopify_id)
shopify_product.variants.first.compare_at_price = product.shopify_supplier_inv.to_i
puts "-> Updated stock of: #{shopify_product.variants.first.sku} to #{shopify_product.variants.first.compare_at_price}"
if shopify_product.vendor == "Sparkfun" || "Pololu"
shopify_product.save
end
puts "\n\n"
puts product.inspect
rescue
end
end
end
@pbar.finish
# Run the "auto notify" script to let customers know what has come back in stock
`/root/tools/bin/notify.rb`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment