Last active
December 17, 2015 02:08
-
-
Save sharapeco/5533495 to your computer and use it in GitHub Desktop.
某ミーショップ在庫更新API。あらかじめ書き込み可能なディレクトリ data を作っておいてください。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Web API として使うためのファイル (1) | |
# Web サーバ上の適当なディレクトリに置いて使う。 | |
# mod_rewrite が必要 | |
<IfModule mod_rewrite.c> | |
RewriteEngine On | |
RewriteCond %{REQUEST_FILENAME} !-d | |
RewriteCond %{REQUEST_FILENAME} !-f | |
RewriteRule ^(.*)$ index.rb?url=$1 [QSA,L] | |
</IfModule> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/ruby | |
# Ruby からそのまま使う場合のサンプル | |
require 'rubygems' | |
require 'mechanize' | |
require './ColorMe' | |
$KCODE = 'UTF-8' | |
api = ColorMe.new({'username' => 'ログインID', 'password' => 'パスワード'}) | |
# ログインできるかどうかテスト | |
ret = api.simple_login([]) | |
pp ret | |
# 在庫を更新する | |
# 在庫を更新する | |
ret = api.send('update_stock', ['型番', 22]) | |
pp ret | |
# オプションがある場合 | |
api.send('update_stock', ['型番', 12, 'オプション値1']) | |
api.send('update_stock', ['型番', 12, 'オプション値1', 'オプション値2']) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rubygems' | |
require 'mechanize' | |
require 'logger' | |
class ColorMe | |
def initialize(account) | |
@use_sleep = false | |
@account = account | |
@session_file = 'data/session' | |
@agent = Mechanize.new { |a| a.log = Logger.new('data/colorme.log') } | |
@agent.user_agent_alias = 'Mac Safari' | |
@agent.request_headers = { | |
'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', | |
'Accept-language' => 'ja-jp', | |
'Accept-charset' => '', | |
'Accept-encoding' => 'gzip, deflate', | |
'Keep-alive' => nil | |
} | |
loadSession | |
end | |
def simple_login(args) | |
page = @agent.get('https://admin.shop-pro.jp/') | |
login() if not loggedIn? | |
{:result => 'OK'} | |
end | |
def update_stock(args) | |
model = args.shift | |
stock = args.shift | |
options = args.join(" × ") | |
page = @agent.get('http://admin.shop-pro.jp/?mode=stock_mng&type=SRH') | |
if not loggedIn? | |
login() | |
page = @agent.get('http://admin.shop-pro.jp/?mode=stock_mng&type=SRH') | |
end | |
@agent.page.encoding = 'EUC-JP' | |
# 商品を検索する | |
form = page.form_with(:name => 'frm') | |
form.action = 'http://admin.shop-pro.jp/?mode=stock_mng&type=SRH' | |
form['category_id'] = '' | |
form['stock_num'] = '' | |
form['srh_product_id'] = '' | |
form['srh_model_number'] = model | |
form['disp_num'] = '100' # 念のためたくさん取得 | |
form['srh_product_name1'] = '' | |
form['srh_product_name2'] = '' | |
form['srh_product_name_type'] = '0' | |
form['d_model'] = '1' | |
form['d_option'] = '1' | |
page = form.submit | |
@agent.page.encoding = 'EUC-JP' | |
# データのあるテーブル | |
tables = page.search('.TBL') | |
raise 'invalid form' if tables.length < 2 | |
table = tables[1] | |
trs = table.search('tr') | |
# 表のヘッダを取得 | |
headers = [] | |
thead = trs.shift | |
thead.search('td').each { |td| headers << td.text } | |
# 表の中身を調べる | |
product = nil | |
trs.each do |tr| | |
row = {} | |
i = 0 | |
tr.search('td').each do |td| | |
row[ headers[i] ] = td.text.gsub(/\302\240/, ' ').strip | |
i += 1 | |
end | |
row['stock'] = tr.search('input[name^="stock_num_"]')[0]['value'] | |
row['option_data_id'] = tr.search('input[name^="option_data_id_"]')[0]['value'] | |
if row['型番'] == model and row['オプション'] == options | |
product = row | |
break | |
end | |
end | |
# pp product | |
raise 'product not found' if not product | |
form = page.form_with(:name => 'frm') | |
form.action = 'http://admin.shop-pro.jp/?mode=stock_mng&type=UPD' | |
form['upd_product_id'] = product['商品ID'] | |
form['upd_option_data_id'] = product['option_data_id'] | |
form['upd_stock_num'] = stock | |
page = form.submit | |
true | |
end | |
private | |
def loggedIn? | |
@agent.page.encoding = 'EUC-JP' | |
@agent.page.link_with(:href => /logout/i) | |
end | |
def login | |
#print 'Try to login...' | |
form = @agent.page.form_with(:name => 'frm') | |
form.action = 'https://admin.shop-pro.jp/?mode=login&exec=1' | |
form['login_id'] = @account['username'] | |
form['password'] = @account['password'] | |
form['href'] = '' | |
sleep 1 if @use_sleep | |
page = form.submit() | |
if not loggedIn? | |
raise 'Login failed' | |
end | |
saveSession | |
#puts 'OK' | |
page | |
end | |
def loadSession | |
if File.exist?(@session_file) | |
session_id = File.read(@session_file).chomp | |
#puts 'session id: ' + session_id | |
session_cookie = Mechanize::Cookie.new('PHPSESSID', session_id, | |
:domain => 'admin.shop-pro.jp', :for_domain => true, :path => '/') | |
@agent.cookie_jar.add!(session_cookie) | |
end | |
end | |
def saveSession | |
@agent.cookie_jar.each do |cookie| | |
if cookie.name == 'PHPSESSID' | |
#puts 'session id: ' + cookie.value | |
File.open(@session_file, 'w') { |f| f.write cookie.value } | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/ruby | |
# Web API として使うためのファイル (2) | |
# | |
# パラメータはスラッシュで区切って渡す。値は適宜 URL エンコードを施す。 | |
# http://path/to/api/update_stock/型番/在庫数 | |
# http://path/to/api/update_stock/型番/在庫数/オプション値1 | |
# http://path/to/api/update_stock/型番/在庫数/オプション値1/オプション値2 | |
# | |
# 戻り値は JSON で返す。 | |
# 成功の場合 true | |
# 失敗した場合は {"error":"メッセージ"} のような値が返ってくる | |
require 'rubygems' | |
require 'cgi' | |
require 'json' | |
require './ColorMe' | |
def main | |
cgi = CGI.new | |
args = cgi['url'].split('/') | |
methodName = args.shift | |
mydie('Empty method name') if methodName == '' | |
account = {'username' => 'ログインID', 'password' => 'パスワード'} | |
begin | |
api = ColorMe.new(account) | |
result = api.send(methodName, args) | |
printHeader | |
print result.to_json | |
rescue NoMethodError | |
mydie('No method') | |
rescue => e | |
mydie(e) | |
end | |
end | |
def mydie(message) | |
e = {:error => message} | |
printHeader | |
print e.to_json | |
exit | |
end | |
def printHeader | |
print "Content-type: application/json; charset=UTF-8\n\n" | |
end | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment