nowa-top4r 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +5 -0
- data/MIT-LICENSE +20 -0
- data/README +20 -0
- data/TODO +0 -0
- data/bin/top4rsh +2 -0
- data/lib/top4r/client/base.rb +135 -0
- data/lib/top4r/client/shipping.rb +45 -0
- data/lib/top4r/client/suite.rb +17 -0
- data/lib/top4r/client/trade.rb +48 -0
- data/lib/top4r/client/user.rb +31 -0
- data/lib/top4r/client.rb +23 -0
- data/lib/top4r/config.rb +74 -0
- data/lib/top4r/console.rb +29 -0
- data/lib/top4r/core.rb +57 -0
- data/lib/top4r/ext/stdlib.rb +17 -0
- data/lib/top4r/ext.rb +1 -0
- data/lib/top4r/meta.rb +56 -0
- data/lib/top4r/model/shipping.rb +76 -0
- data/lib/top4r/model/suite.rb +17 -0
- data/lib/top4r/model/trade.rb +109 -0
- data/lib/top4r/model/user.rb +92 -0
- data/lib/top4r/model.rb +111 -0
- data/lib/top4r/version.rb +17 -0
- data/lib/top4r.rb +26 -0
- metadata +88 -0
data/CHANGES
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Nowa Zhu <nowazhu@gmail.com>, http://nowa.me.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
'Software'), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
17
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
18
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
19
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
20
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
= TOP4R
|
2
|
+
|
3
|
+
* http://top4r.labs.nowa.me
|
4
|
+
* Thanks Twitter4R <http://twitter4r.rubyforge.org>.
|
5
|
+
|
6
|
+
== DESCRIPTION:
|
7
|
+
|
8
|
+
TOP4R封装了淘宝开发平台的接口,帮助你快速构建基于TOP的应用程序。
|
9
|
+
|
10
|
+
== FEATURES/PROBLEMS:
|
11
|
+
|
12
|
+
* 待续...
|
13
|
+
|
14
|
+
== REQUIREMENTS:
|
15
|
+
|
16
|
+
* rubygems
|
17
|
+
|
18
|
+
== INSTALL:
|
19
|
+
|
20
|
+
sudo gem install nowa-top4r -s http://gems.github.com
|
data/TODO
ADDED
File without changes
|
data/bin/top4rsh
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
class Top4R::Client
|
2
|
+
alias :old_inspect :inspect
|
3
|
+
attr_accessor :total_results
|
4
|
+
attr_reader :login
|
5
|
+
|
6
|
+
def inspect
|
7
|
+
s = old_inspect
|
8
|
+
s.gsub!(/@app_secret=".*?"/, '@app_secret="XXXX"')
|
9
|
+
end
|
10
|
+
|
11
|
+
def init
|
12
|
+
total_results = 0
|
13
|
+
if @parameters and @session
|
14
|
+
@parameters = Base64.decode64(@parameters).split('&').inject({}) do |hsh, i| kv = i.split('='); hsh[kv[0]] = kv[1]; hsh end
|
15
|
+
@login = user(@parameters['visitor_nick'])
|
16
|
+
# puts "login: #{@login.inspect}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
attr_accessor :app_key, :app_secret, :parameters, :session
|
22
|
+
|
23
|
+
def login_required(model, method)
|
24
|
+
return if logged_in?
|
25
|
+
raise Top4R::LoginRequiredError.new({:model => model, :method => method})
|
26
|
+
end
|
27
|
+
|
28
|
+
def http_connect(body=nil, &block)
|
29
|
+
require_block(block_given?)
|
30
|
+
connection = create_http_connection
|
31
|
+
connection.start do |connection|
|
32
|
+
request = yield connection if block_given?
|
33
|
+
# puts "conn: #{connection.inspect}"
|
34
|
+
# puts "request: #{request.inspect}"
|
35
|
+
response = connection.request(request, body)
|
36
|
+
puts "response: #{response.body}"
|
37
|
+
handle_rest_response(response)
|
38
|
+
response
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# "Blesses" model object with client information
|
43
|
+
def bless_model(model)
|
44
|
+
model.bless(self) if model
|
45
|
+
end
|
46
|
+
|
47
|
+
def bless_models(list)
|
48
|
+
return bless_model(list) if list.respond_to?(:client=)
|
49
|
+
list.collect { |model| bless_model(model) } if list.respond_to?(:collect)
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
@@http_header = nil
|
54
|
+
|
55
|
+
def valid_method(method, methods, model, force_login = false)
|
56
|
+
login_required(model, method) if (@@no_login_required_methods[model].is_a?(Hash) and !@@no_login_required_methods[model].keys.member?(method)) or force_login
|
57
|
+
raise ArgumentError, "Invalid #{model} method: #{method}" unless methods.keys.member?(method)
|
58
|
+
end
|
59
|
+
|
60
|
+
def raise_rest_error(response, uri = nil)
|
61
|
+
map = JSON.parse(response.body)
|
62
|
+
raise Top4R::RESTError.new(:code => response.code,
|
63
|
+
:message => response.message,
|
64
|
+
:error => map["error_rsp"],
|
65
|
+
:uri => uri)
|
66
|
+
end
|
67
|
+
|
68
|
+
def handle_rest_response(response, uri = nil)
|
69
|
+
unless response.is_a?(Net::HTTPSuccess)
|
70
|
+
raise_rest_error(response, uri)
|
71
|
+
end
|
72
|
+
|
73
|
+
map = JSON.parse(response.body)
|
74
|
+
raise Top4R::RESTError.new(:code => map["error_rsp"]["code"],
|
75
|
+
:message => map["error_rsp"]["msg"],
|
76
|
+
:error => map["error_rsp"],
|
77
|
+
:uri => uri) if map["error_rsp"].is_a?(Hash)
|
78
|
+
end
|
79
|
+
|
80
|
+
def create_http_connection
|
81
|
+
protocol, host, port = (@@config.env == :production ? @@config.protocol : @@config.test_protocol), (@@config.env == :production ? @@config.host : @@config.test_host), (@@config.env == :production ? @@config.port : @@config.test_port)
|
82
|
+
conn = Net::HTTP.new(host, port,
|
83
|
+
@@config.proxy_host, @@config.proxy_port,
|
84
|
+
@@config.proxy_user, @@config.proxy_pass)
|
85
|
+
if protocol == :ssl
|
86
|
+
conn.use_ssl = true
|
87
|
+
conn.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
88
|
+
end
|
89
|
+
conn
|
90
|
+
end
|
91
|
+
|
92
|
+
def http_header
|
93
|
+
# can cache this in class variable since all "variables" used to
|
94
|
+
# create the contents of the HTTP header are determined by other
|
95
|
+
# class variables that are not designed to change after instantiation.
|
96
|
+
@@http_header ||= {
|
97
|
+
'User-Agent' => "Top4R v#{Top4R::Version.to_version} [#{@@config.user_agent}]",
|
98
|
+
'Accept' => 'text/x-json',
|
99
|
+
'X-TOP-Client' => @@config.application_name,
|
100
|
+
'X-TOP-Client-Version' => @@config.application_version,
|
101
|
+
'X-TOP-Client-URL' => @@config.application_url,
|
102
|
+
}
|
103
|
+
@@http_header
|
104
|
+
end
|
105
|
+
|
106
|
+
def append_top_params(params)
|
107
|
+
params = params.merge({
|
108
|
+
:session => @session,
|
109
|
+
:timestamp => Time.now.strftime("%Y-%m-%d %H:%M:%S"),
|
110
|
+
:format => "#{@@config.format}",
|
111
|
+
:app_key => @app_key,
|
112
|
+
:v => "1.0"
|
113
|
+
})
|
114
|
+
params = params.merge({
|
115
|
+
:sign => Digest::MD5.hexdigest(params.sort {|a,b| "#{a[0]}"<=>"#{b[0]}"}.flatten.unshift(@app_secret).join).upcase
|
116
|
+
})
|
117
|
+
end
|
118
|
+
|
119
|
+
def create_http_get_request(method, params = {})
|
120
|
+
uri = @@config.env == :production ? @@config.rest_uri : @@config.test_rest_uri
|
121
|
+
params = append_top_params(params.merge({:method => method}))
|
122
|
+
path = (params.size > 0) ? "#{uri}?#{params.to_http_str}" : uri
|
123
|
+
puts "path: #{path}"
|
124
|
+
Net::HTTP::Get.new(path, http_header)
|
125
|
+
end
|
126
|
+
|
127
|
+
def create_http_post_request(uri)
|
128
|
+
Net::HTTP::Post.new(uri, http_header)
|
129
|
+
end
|
130
|
+
|
131
|
+
def create_http_delete_request(uri, params = {})
|
132
|
+
path = (params.size > 0) ? "#{uri}?#{params.to_http_str}" : uri
|
133
|
+
Net::HTTP::Delete.new(path, http_header)
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class Top4R::Client
|
2
|
+
@@AREA_METHODS = {
|
3
|
+
:list => 'taobao.areas.get'
|
4
|
+
}
|
5
|
+
|
6
|
+
@@LOGISTIC_COMPANY_METHODS = {
|
7
|
+
:list => 'taobao.logisticcompanies.get'
|
8
|
+
}
|
9
|
+
|
10
|
+
@@DELIVERY_METHODS = {
|
11
|
+
:send => 'taobao.delivery.send'
|
12
|
+
}
|
13
|
+
|
14
|
+
def areas(method = :list, options = {}, &block)
|
15
|
+
valid_method(method, @@AREA_METHODS, :area)
|
16
|
+
params = {:fields => Top4R::Area.fields}.merge(options)
|
17
|
+
response = http_connect {|conn| create_http_get_request(@@AREA_METHODS[method], params)}
|
18
|
+
areas = Top4R::Area.unmarshal(JSON.parse(response.body)["rsp"]["areas"])
|
19
|
+
areas.each {|area| bless_model(area); yield area if block_given?}
|
20
|
+
areas
|
21
|
+
end
|
22
|
+
|
23
|
+
def logistic_companies(method = :list, options = {}, &block)
|
24
|
+
valid_method(method, @@LOGISTIC_COMPANY_METHODS, :logistic_company)
|
25
|
+
params = {:fields => Top4R::LogisticCompany.fields}.merge(options)
|
26
|
+
response = http_connect {|conn| create_http_get_request(@@LOGISTIC_COMPANY_METHODS[method], params)}
|
27
|
+
logistic_companies = Top4R::LogisticCompany.unmarshal(JSON.parse(response.body)["rsp"]["logistic_companies"])
|
28
|
+
logistic_companies.each {|logistic_company| bless_model(logistic_company); yield logistic_company if block_given?}
|
29
|
+
logistic_companies
|
30
|
+
end
|
31
|
+
|
32
|
+
def deliver_trade(t, method = :send, options = {})
|
33
|
+
valid_method(method, @@DELIVERY_METHODS, :delivery)
|
34
|
+
params = {}
|
35
|
+
if t.is_a?(Top4R::Delivery)
|
36
|
+
params = t.to_hash
|
37
|
+
else
|
38
|
+
t = t.tid if t.is_a?(Top4R::Trade)
|
39
|
+
params = options.merge(:tid => t)
|
40
|
+
end
|
41
|
+
response = http_connect {|conn| create_http_get_request(@@DELIVERY_METHODS[method], params)}
|
42
|
+
json = JSON.parse(response.body)
|
43
|
+
json.is_a?(Hash) ? json["rsp"]["is_success"] : false
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Top4R::Client
|
2
|
+
@@SUITE_METHODS = {
|
3
|
+
:list => 'taobao.suites.get',
|
4
|
+
}
|
5
|
+
|
6
|
+
def suites(u, service_code, method = :list, options = {}, &block)
|
7
|
+
valid_method(method, @@SUITE_METHODS, :suite)
|
8
|
+
u = u.nick if u.is_a?(Top4R::User)
|
9
|
+
params = {:service_code => service_code}.merge(options).merge(:nick => u)
|
10
|
+
response = http_connect {|conn| create_http_get_request(@@SUITE_METHODS[method], params)}
|
11
|
+
suites = Top4R::Suite.unmarshal(JSON.parse(response.body)["rsp"]["suite"])
|
12
|
+
suites.each {|suite| bless_model(suite); yield suite if block_given?}
|
13
|
+
# puts "\nsuites: #{suites.inspect}"
|
14
|
+
@total_results = JSON.parse(response.body)["rsp"]["totalResults"].to_i
|
15
|
+
suites
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
class Top4R::Client
|
2
|
+
@@TRADE_METHODS = {
|
3
|
+
:bought_list => 'taobao.trades.bought.get',
|
4
|
+
:sold_list => 'taobao.trades.sold.get',
|
5
|
+
:increments_list => 'taobao.trades.sold.increment.get',
|
6
|
+
:info => 'taobao.trade.get',
|
7
|
+
:fullinfo => 'taobao.trade.fullinfo.get',
|
8
|
+
:close => 'taobao.trade.close',
|
9
|
+
:add_memo => 'taobao.trade.memo.add',
|
10
|
+
:update_memo => 'taobao.trade.memo.update',
|
11
|
+
:confirmfee => 'taobao.trade.confirmfee.get'
|
12
|
+
}
|
13
|
+
|
14
|
+
def trades_for(method = :bought_list, options = {}, &block)
|
15
|
+
valid_method(method, @@TRADE_METHODS, :trade)
|
16
|
+
params = {:fields => Top4R::Trade.fields}.merge(options)
|
17
|
+
if method == :increments_list
|
18
|
+
now = Time.now
|
19
|
+
params = {:start_modified => (now - 24.hours).strftime("%Y-%m-%d %H:%M:%S"), :end_modified => now.strftime("%Y-%m-%d %H:%M:%S")}.merge(params)
|
20
|
+
end
|
21
|
+
response = http_connect {|conn| create_http_get_request(@@TRADE_METHODS[method], params)}
|
22
|
+
trades = Top4R::Trade.unmarshal(JSON.parse(response.body)["rsp"]["trades"])
|
23
|
+
trades.each {|trade| bless_model(trade); yield trade if block_given?}
|
24
|
+
# puts "\ntrades: #{trades.inspect}"
|
25
|
+
@total_results = JSON.parse(response.body)["rsp"]["totalResults"].to_i
|
26
|
+
trades
|
27
|
+
end
|
28
|
+
|
29
|
+
def trade(t, method = :info, options = {})
|
30
|
+
valid_method(method, @@TRADE_METHODS, :trade)
|
31
|
+
t = t.tid if t.is_a?(Top4R::Trade)
|
32
|
+
params = {:fields => Top4R::Trade.fields}.merge(options).merge(:tid => t)
|
33
|
+
response = http_connect {|conn| create_http_get_request(@@TRADE_METHODS[method], params)}
|
34
|
+
parsed_body = JSON.parse(response.body)
|
35
|
+
|
36
|
+
if [:info, :fullinfo].member?(method)
|
37
|
+
trades = Top4R::Trade.unmarshal(parsed_body["rsp"]["trades"])
|
38
|
+
bless_model(trades.first)
|
39
|
+
elsif method == :confirmfee
|
40
|
+
confirmfees = Top4R::TradeConfirmFee.unmarshal(parsed_body["rsp"]["confirmFees"])
|
41
|
+
bless_models(confirmfees)
|
42
|
+
elsif [:close, :update_memo].member?(method)
|
43
|
+
parsed_body["rsp"]["modified"]
|
44
|
+
elsif method == :add_memo
|
45
|
+
parsed_body["rsp"]["created"]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class Top4R::Client
|
2
|
+
@@USER_METHODS = {
|
3
|
+
:info => 'taobao.user.get',
|
4
|
+
:multi_info => 'taobao.users.get'
|
5
|
+
}
|
6
|
+
|
7
|
+
def logged_in?
|
8
|
+
@login.is_a?(Top4R::User) ? true : false
|
9
|
+
end
|
10
|
+
|
11
|
+
def user(u, method = :info, options = {})
|
12
|
+
valid_method(method, @@USER_METHODS, :user)
|
13
|
+
u = u.nick if u.is_a?(Top4R::User)
|
14
|
+
users = user_request(u, method, options)
|
15
|
+
method == :info ? bless_model(users.first) : bless_models(users)
|
16
|
+
end
|
17
|
+
|
18
|
+
def my(method, options = {})
|
19
|
+
valid_method(method, @@USER_METHODS, :user, true)
|
20
|
+
users = user_request(@login.nick, method, options)
|
21
|
+
method == :info ? bless_model(users.first) : bless_models(users)
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
|
26
|
+
def user_request(u, method, options)
|
27
|
+
params = {:fields => Top4R::User.fields}.merge(options).merge(:nick => u)
|
28
|
+
response = http_connect {|conn| create_http_get_request(@@USER_METHODS[method], params)}
|
29
|
+
Top4R::User.unmarshal(JSON.parse(response.body)["rsp"]["users"])
|
30
|
+
end
|
31
|
+
end
|
data/lib/top4r/client.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
class Top4R::Client
|
2
|
+
include Top4R::ClassUtilMixin
|
3
|
+
|
4
|
+
@@no_login_required_methods = {
|
5
|
+
:user => {
|
6
|
+
:info => 'taobao.user.get',
|
7
|
+
:multi_info => 'taobao.users.get'
|
8
|
+
},
|
9
|
+
:trade => {},
|
10
|
+
:area => {
|
11
|
+
:list => 'taobao.areas.get'
|
12
|
+
},
|
13
|
+
:logistic_company => {
|
14
|
+
:list => 'taobao.logisticcompanies.get'
|
15
|
+
}
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
require 'top4r/client/base'
|
20
|
+
require 'top4r/client/user'
|
21
|
+
require 'top4r/client/shipping'
|
22
|
+
require 'top4r/client/trade'
|
23
|
+
require 'top4r/client/suite'
|
data/lib/top4r/config.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
module Top4R
|
2
|
+
# A rails like config object
|
3
|
+
class Config
|
4
|
+
include ClassUtilMixin
|
5
|
+
@@ATTRIBUTES = [
|
6
|
+
:env,
|
7
|
+
:host,
|
8
|
+
:rest_uri,
|
9
|
+
:port,
|
10
|
+
:protocol,
|
11
|
+
:test_host,
|
12
|
+
:test_rest_uri,
|
13
|
+
:test_port,
|
14
|
+
:test_protocol,
|
15
|
+
:proxy_host,
|
16
|
+
:proxy_port,
|
17
|
+
:proxy_user,
|
18
|
+
:proxy_pass,
|
19
|
+
:format,
|
20
|
+
:application_name,
|
21
|
+
:application_key,
|
22
|
+
:application_secret,
|
23
|
+
:application_version,
|
24
|
+
:application_url,
|
25
|
+
:user_agent,
|
26
|
+
:source
|
27
|
+
]
|
28
|
+
attr_accessor *@@ATTRIBUTES
|
29
|
+
|
30
|
+
# Override of Object#eql? to ensure RSpec specifications run
|
31
|
+
# correctly. Also done to follow Ruby best practices.
|
32
|
+
def eql?(other)
|
33
|
+
return true if self == other
|
34
|
+
@@ATTRIBUTES.each do |att|
|
35
|
+
return false unless self.send(att).eql?(other.send(att))
|
36
|
+
end
|
37
|
+
true
|
38
|
+
end
|
39
|
+
end # Config class
|
40
|
+
|
41
|
+
class Client
|
42
|
+
@@defaults = {
|
43
|
+
:env => :test,
|
44
|
+
:host => 'gw.api.taobao.com',
|
45
|
+
:rest_uri => '/router/rest',
|
46
|
+
:port => 80,
|
47
|
+
:protocol => :http,
|
48
|
+
:test_host => 'gw.sandbox.taobao.com',
|
49
|
+
:test_rest_uri => '/router/rest',
|
50
|
+
:test_port => 80,
|
51
|
+
:test_protocol => :http,
|
52
|
+
:proxy_host => nil,
|
53
|
+
:proxy_port => nil,
|
54
|
+
:format => :json,
|
55
|
+
:application_name => 'Top4R',
|
56
|
+
:application_key => '12000224',
|
57
|
+
:application_secret => '2f26cb1a99570aa72daee12a1db88e63',
|
58
|
+
:application_version => Top4R::Version.to_version,
|
59
|
+
:application_url => 'http://top4r.nowa.me',
|
60
|
+
:user_agent => 'default',
|
61
|
+
:source => 'top4r'
|
62
|
+
}
|
63
|
+
@@config = Top4R::Config.new(@@defaults)
|
64
|
+
|
65
|
+
# Top4R::Client class methods
|
66
|
+
class << self
|
67
|
+
# Yields to given <tt>block</tt> to configure the Twitter4R API.
|
68
|
+
def configure(&block)
|
69
|
+
raise ArgumentError, "Block must be provided to configure" unless block_given?
|
70
|
+
yield @@config
|
71
|
+
end # configure
|
72
|
+
end # class << self
|
73
|
+
end # Client class
|
74
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
module Top4R
|
4
|
+
class Client
|
5
|
+
class << self
|
6
|
+
# Helper method mostly for irb shell prototyping.
|
7
|
+
#
|
8
|
+
# Reads in app_key/app_secret from YAML file
|
9
|
+
# found at the location given by <tt>config_file</tt> that has
|
10
|
+
# the following format:
|
11
|
+
# envname:
|
12
|
+
# app_key: application key
|
13
|
+
# app_secret: application secret
|
14
|
+
#
|
15
|
+
#
|
16
|
+
# Where <tt>envname</tt> is the name of the environment like 'test',
|
17
|
+
# 'dev' or 'prod'. The <tt>env</tt> argument defaults to 'test'.
|
18
|
+
#
|
19
|
+
# To use this in the shell you would do something like the following
|
20
|
+
# examples:
|
21
|
+
# top = Top4R::Client.from_config('config/top.yml', 'dev')
|
22
|
+
# top = Top4R::Client.from_config('config/top.yml')
|
23
|
+
def from_config(config_file, env = 'test')
|
24
|
+
yaml_hash = YAML.load(File.read(config_file))
|
25
|
+
self.new yaml_hash[env]
|
26
|
+
end
|
27
|
+
end # class << self
|
28
|
+
end
|
29
|
+
end
|
data/lib/top4r/core.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
module Top4R
|
2
|
+
# Core
|
3
|
+
module ClassUtilMixin
|
4
|
+
module ClassMethods
|
5
|
+
|
6
|
+
end
|
7
|
+
|
8
|
+
module InstanceMethods
|
9
|
+
def initialize(params = {})
|
10
|
+
others = {}
|
11
|
+
params.each do |key,val|
|
12
|
+
if self.respond_to? key
|
13
|
+
self.send("#{key}=", val)
|
14
|
+
else
|
15
|
+
others[key] = val
|
16
|
+
end
|
17
|
+
end
|
18
|
+
self.send("#{:other_attrs}=", others) if self.respond_to? :other_attrs and others.size > 0
|
19
|
+
self.send(:init) if self.respond_to? :init
|
20
|
+
end
|
21
|
+
|
22
|
+
protected
|
23
|
+
def require_block(block_given)
|
24
|
+
raise ArgumentError, "Must provide a block" unless block_given
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.included(receiver)
|
29
|
+
receiver.extend ClassMethods
|
30
|
+
receiver.send :include, InstanceMethods
|
31
|
+
end
|
32
|
+
end # ClassUtilMixin module
|
33
|
+
|
34
|
+
class RESTError < RuntimeError
|
35
|
+
include ClassUtilMixin
|
36
|
+
@@ATTRIBUTES = [:code, :message, :uri, :error]
|
37
|
+
attr_accessor *@@ATTRIBUTES
|
38
|
+
|
39
|
+
# Returns string in following format:
|
40
|
+
# "HTTP #{@code}: #{@message} at #{@uri}"
|
41
|
+
# For example,
|
42
|
+
# "HTTP 404: Resource Not Found at /i_am_crap.json"
|
43
|
+
def to_s
|
44
|
+
"HTTP #{@code}: #{@message} at #{@uri}"
|
45
|
+
end
|
46
|
+
end # RESTError
|
47
|
+
|
48
|
+
class LoginRequiredError < RuntimeError
|
49
|
+
include ClassUtilMixin
|
50
|
+
@@ATTRIBUTES = [:model, :method]
|
51
|
+
attr_accessor *@@ATTRIBUTES
|
52
|
+
|
53
|
+
def to_s
|
54
|
+
"#{@method} method at model #{@model} requires you to be logged in first"
|
55
|
+
end
|
56
|
+
end # LoginRequiredError
|
57
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Extension to Hash to create URL encoded string from key-values
|
2
|
+
class Hash
|
3
|
+
# Returns string formatted for HTTP URL encoded name-value pairs.
|
4
|
+
# For example,
|
5
|
+
# {:id => 'thomas_hardy'}.to_http_str
|
6
|
+
# # => "id=thomas_hardy"
|
7
|
+
# {:id => 23423, :since => Time.now}.to_http_str
|
8
|
+
# # => "since=Thu,%2021%20Jun%202007%2012:10:05%20-0500&id=23423"
|
9
|
+
def to_http_str
|
10
|
+
result = ''
|
11
|
+
return result if self.empty?
|
12
|
+
self.each do |key, val|
|
13
|
+
result << "#{key}=#{CGI.escape(val.to_s)}&"
|
14
|
+
end
|
15
|
+
result.chop # remove the last '&' character, since it can be discarded
|
16
|
+
end
|
17
|
+
end
|
data/lib/top4r/ext.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require_local('top4r/ext/stdlib')
|
data/lib/top4r/meta.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# meta.rb contains <tt>Twitter::Meta</tt> and related classes that
|
2
|
+
# help define the metadata of the <tt>Twitter4R</tt> project.
|
3
|
+
|
4
|
+
require('rubygems')
|
5
|
+
require('erb')
|
6
|
+
|
7
|
+
class Top4R::Meta #:nodoc:
|
8
|
+
attr_accessor :root_dir
|
9
|
+
attr_reader :gem_spec, :project_files, :spec_files
|
10
|
+
|
11
|
+
# Initializer for Twitter::Meta class. Takes <tt>root_dir</tt> as parameter.
|
12
|
+
def initialize(root_dir)
|
13
|
+
@root_dir = root_dir
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns package information defined in <tt>root_dir</tt>/pkg-info.yml
|
17
|
+
def pkg_info
|
18
|
+
yaml_file = File.join(@root_dir, 'pkg-info.yml')
|
19
|
+
ryaml = ERB.new(File.read(yaml_file), 0)
|
20
|
+
s = ryaml.result(binding)
|
21
|
+
YAML.load(s)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns RubyGems spec information
|
25
|
+
def spec_info
|
26
|
+
self.pkg_info['spec'] if self.pkg_info
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns list of project files
|
30
|
+
def project_files
|
31
|
+
@project_files ||= Dir.glob(File.join(@root_dir, 'lib/**/*.rb'))
|
32
|
+
@project_files
|
33
|
+
end
|
34
|
+
|
35
|
+
# Returns list of specification files
|
36
|
+
def spec_files
|
37
|
+
@spec_files ||= Dir.glob(File.join(@root_dir, 'spec/**/*_spec.rb'))
|
38
|
+
@spec_files
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns RubyGem specification for Twitter4R project
|
42
|
+
def gem_spec
|
43
|
+
@gem_spec ||= Gem::Specification.new do |spec|
|
44
|
+
self.spec_info.each do |key, val|
|
45
|
+
if val.is_a?(Hash)
|
46
|
+
val.each do |k, v|
|
47
|
+
spec.send(key, k, v)
|
48
|
+
end
|
49
|
+
else
|
50
|
+
spec.send("#{key}=", val)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
@gem_spec
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Top4R
|
2
|
+
# Area model
|
3
|
+
class Area
|
4
|
+
include ModelMixin
|
5
|
+
@@ATTRIBUTES = [:id, :area_id, :area_type, :area_name, :parent_id, :zip]
|
6
|
+
attr_accessor *@@ATTRIBUTES
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def attributes; @@ATTRIBUTES; end
|
10
|
+
|
11
|
+
def default_public_fields
|
12
|
+
["area_id", "area_type", "area_name", "parent_id", "zip"]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def unmarshal_other_attrs
|
17
|
+
@id = @area_id
|
18
|
+
self
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# LogisticCompany model
|
23
|
+
class LogisticCompany
|
24
|
+
include ModelMixin
|
25
|
+
@@ATTRIBUTES = [:id, :company_id, :company_code, :company_name]
|
26
|
+
attr_accessor *@@ATTRIBUTES
|
27
|
+
|
28
|
+
class << self
|
29
|
+
def attributes; @@ATTRIBUTES; end
|
30
|
+
|
31
|
+
def default_public_fields
|
32
|
+
["company_id", "company_code", "company_name"]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def unmarshal_other_attrs
|
37
|
+
@id = @company_id
|
38
|
+
self
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Delivery model
|
43
|
+
class Delivery
|
44
|
+
include ModelMixin
|
45
|
+
@@ATTRIBUTES = [:tid, :order_type, :company_code, :out_sid, :seller_name, :seller_area_id,
|
46
|
+
:seller_address, :seller_zip, :seller_phone, :seller_mobile, :memo]
|
47
|
+
attr_accessor *@@ATTRIBUTES
|
48
|
+
|
49
|
+
class << self
|
50
|
+
def attributes; @@ATTRIBUTES; end
|
51
|
+
end
|
52
|
+
end # Delivery model
|
53
|
+
|
54
|
+
# Shipping model
|
55
|
+
class Shipping
|
56
|
+
include ModelMixin
|
57
|
+
@@ATTRIBUTES = [:id, :tid, :seller_nick, :buyer_nick, :delivery_start, :delivery_end,
|
58
|
+
:out_sid, :item_title, :receiver_name, :receiver_phone, :receiver_mobile, :receiver_location,
|
59
|
+
:status, :type, :freight_payer, :seller_confirm, :company_name]
|
60
|
+
attr_accessor *@@ATTRIBUTES
|
61
|
+
|
62
|
+
class << self
|
63
|
+
def attributes; @@ATTRIBUTES; end
|
64
|
+
end
|
65
|
+
|
66
|
+
def unmarshal_other_attrs
|
67
|
+
@id = @out_sid
|
68
|
+
if @receiver_location && @receiver_location.size > 0
|
69
|
+
@receiver_location = Location.new(@receiver_location)
|
70
|
+
else
|
71
|
+
@receiver_location = nil
|
72
|
+
end
|
73
|
+
self
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Top4R
|
2
|
+
# Suite model
|
3
|
+
class Suite
|
4
|
+
include ModelMixin
|
5
|
+
@@ATTRIBUTES = [:id, :nick, :suite_name, :start_date, :end_date]
|
6
|
+
attr_accessor *@@ATTRIBUTES
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def attributes; @@ATTRIBUTES; end
|
10
|
+
end
|
11
|
+
|
12
|
+
def unmarshal_other_attrs
|
13
|
+
@id = 0
|
14
|
+
self
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
module Top4R
|
2
|
+
# Order model
|
3
|
+
class Order
|
4
|
+
include ModelMixin
|
5
|
+
@@ATTRIBUTES = [:id, :iid, :sku_id, :sku_properties_name, :item_meal_name, :num, :title,
|
6
|
+
:price, :pic_path, :seller_nick, :buyer_nick, :type, :created, :refund_status, :tid,
|
7
|
+
:outer_iid, :outer_sku_id, :total_fee, :payment, :discount_fee, :adjust_fee, :status,
|
8
|
+
:snapshot_url, :timeout_action_time]
|
9
|
+
attr_accessor *@@ATTRIBUTES
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def attributes; @@ATTRIBUTES; end
|
13
|
+
|
14
|
+
def default_public_fields
|
15
|
+
["orders.title", "orders.price", "orders.num", "orders.iid", "orders.status", "orders.tid",
|
16
|
+
"orders.total_fee", "orders.payment", "orders.pic_path"]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def confirm_fees
|
21
|
+
@client.trade(@tid, :confirmfee, {:is_detail => "IS_CHILD"})
|
22
|
+
end
|
23
|
+
|
24
|
+
def unmarshal_other_attrs
|
25
|
+
@id = 0
|
26
|
+
self
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# TradeConfirmFee model
|
31
|
+
class TradeConfirmFee
|
32
|
+
include ModelMixin
|
33
|
+
@@ATTRIBUTES = [:id, :confirm_fee, :confirm_post_fee, :is_last_detail_order]
|
34
|
+
attr_accessor *@@ATTRIBUTES
|
35
|
+
|
36
|
+
class << self
|
37
|
+
def attributes; @@ATTRIBUTES; end
|
38
|
+
end
|
39
|
+
|
40
|
+
def unmarshal_other_attrs
|
41
|
+
@id = 0
|
42
|
+
self
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Trade model
|
47
|
+
class Trade
|
48
|
+
include ModelMixin
|
49
|
+
@@ATTRIBUTES = [:id, :seller_nick, :buyer_nick, :title, :type, :created, :iid, :price,
|
50
|
+
:pic_path, :num, :tid, :buyer_message, :sid, :shipping_type, :alipay_no, :payment,
|
51
|
+
:discount_fee, :adjust_fee, :snapshot_url, :status, :seller_rate, :buyer_rate,
|
52
|
+
:buyer_memo, :seller_memo, :pay_time, :end_time, :modified, :buyer_obtain_point_fee,
|
53
|
+
:point_fee, :real_point_fee, :total_fee, :post_fee, :buyer_alipay_no, :receiver_name,
|
54
|
+
:receiver_state, :receiver_city, :receiver_district, :receiver_address, :receiver_zip,
|
55
|
+
:receiver_mobile, :receiver_phone, :consign_time, :buyer_email, :commission_fee,
|
56
|
+
:seller_alipay_no, :seller_mobile, :seller_phone, :seller_name, :seller_email,
|
57
|
+
:available_confirm_fee, :has_postFee, :received_payment, :cod_fee, :timeout_action_time, :orders]
|
58
|
+
attr_accessor *@@ATTRIBUTES
|
59
|
+
|
60
|
+
class << self
|
61
|
+
def attributes; @@ATTRIBUTES; end
|
62
|
+
|
63
|
+
def default_public_fields
|
64
|
+
["buyer_nick", "seller_nick", "tid", "modified", "title", "type", "status", "created", "price",
|
65
|
+
"sid", "pic_path", "iid", "payment", "alipay_no", "shipping_type", "pay_time", "end_time",
|
66
|
+
"orders"] + Top4R::Order.default_public_fields
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def close(reason = "现关闭本交易!")
|
71
|
+
@client.trade(@tid, :close, {:close_reason => reason})
|
72
|
+
end
|
73
|
+
|
74
|
+
def add_memo(memo)
|
75
|
+
valid_memo(memo)
|
76
|
+
@client.trade(@tid, :add_memo, {:memo => memo})
|
77
|
+
end
|
78
|
+
|
79
|
+
def update_memo(memo)
|
80
|
+
valid_memo(memo)
|
81
|
+
@client.trade(@tid, :update_memo, {:memo => memo})
|
82
|
+
end
|
83
|
+
|
84
|
+
def confirm_fees
|
85
|
+
@client.trade(@tid, :confirmfee, {:is_detail => "IS_FATHER"})
|
86
|
+
end
|
87
|
+
|
88
|
+
def deliver(options = {}, &block)
|
89
|
+
delivery = Delivery.new(options)
|
90
|
+
yield delivery if block_given?
|
91
|
+
delivery.tid = @tid
|
92
|
+
@client.deliver_trade(delivery)
|
93
|
+
end
|
94
|
+
|
95
|
+
def unmarshal_other_attrs
|
96
|
+
@id = @tid
|
97
|
+
if @orders.is_a?(Array)
|
98
|
+
@orders = @orders.map{|order| Order.new(order)}
|
99
|
+
end
|
100
|
+
self
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
def valid_memo(memo)
|
105
|
+
raise ArgumentError, "Invalid param: memo" if memo
|
106
|
+
raise ArgumentError, "Invalid param length: Memo must be less than 1000 characters" if memo.size > 1000
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module Top4R
|
2
|
+
module LoggedInUserMixin
|
3
|
+
module InstanceMethods
|
4
|
+
def trades(method = :bought_list, options = {})
|
5
|
+
@client.trades_for(method, options)
|
6
|
+
end
|
7
|
+
|
8
|
+
def suites(service_code, options = {})
|
9
|
+
@client.suites(self.nick, service_code, :list, options)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.included(receiver)
|
14
|
+
receiver.send :include, InstanceMethods
|
15
|
+
end
|
16
|
+
end # LoggedInUserMixin module
|
17
|
+
|
18
|
+
# Location Model
|
19
|
+
class Location
|
20
|
+
include ModelMixin
|
21
|
+
@@ATTRIBUTES = [:zip, :address, :city, :state, :country, :district]
|
22
|
+
attr_accessor *@@ATTRIBUTES
|
23
|
+
|
24
|
+
class << self
|
25
|
+
def attributes
|
26
|
+
@@ATTRIBUTES
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end # Location model
|
30
|
+
|
31
|
+
# UserCredit Model
|
32
|
+
class UserCredit
|
33
|
+
include ModelMixin
|
34
|
+
@@ATTRIBUTES = [:level, :score, :total_num, :good_num]
|
35
|
+
attr_accessor *@@ATTRIBUTES
|
36
|
+
|
37
|
+
class << self
|
38
|
+
def attributes; @@ATTRIBUTES; end
|
39
|
+
end
|
40
|
+
end # UserCredit model
|
41
|
+
|
42
|
+
# User Model
|
43
|
+
class User
|
44
|
+
include ModelMixin
|
45
|
+
@@ATTRIBUTES = [:id, :user_id, :nick, :sex, :buyer_credit, :seller_credit, :location,
|
46
|
+
:created, :last_visit, :birthday, :type, :has_more_pic, :item_img_num, :item_img_size,
|
47
|
+
:prop_img_num, :prop_img_size, :auto_repost, :promoted_type, :status, :alipay_bind,
|
48
|
+
:consumer_protection, :other_attrs]
|
49
|
+
attr_accessor *@@ATTRIBUTES
|
50
|
+
|
51
|
+
class << self
|
52
|
+
def attributes; @@ATTRIBUTES; end
|
53
|
+
|
54
|
+
def default_public_fields
|
55
|
+
["user_id", "nick", "sex", "buyer_credit", "seller_credit",
|
56
|
+
"location.city", "location.state", "location.country", "created", "last_visit"]
|
57
|
+
end
|
58
|
+
|
59
|
+
def default_private_fields
|
60
|
+
["location.zip", "birthday"]
|
61
|
+
end
|
62
|
+
|
63
|
+
def find(u, client)
|
64
|
+
client.user(u)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def bless(client)
|
69
|
+
basic_bless(client)
|
70
|
+
self.instance_eval(%{
|
71
|
+
self.class.send(:include, Top4R::LoggedInUserMixin)
|
72
|
+
}) if self.is_me? and not self.respond_to?(:trades)
|
73
|
+
self
|
74
|
+
end
|
75
|
+
|
76
|
+
def is_me?
|
77
|
+
@nick == @client.instance_eval("@parameters['visitor_nick']")
|
78
|
+
end
|
79
|
+
|
80
|
+
def unmarshal_other_attrs
|
81
|
+
@id = @user_id
|
82
|
+
if @location && @location.size > 0
|
83
|
+
@location = Location.new(@location)
|
84
|
+
else
|
85
|
+
@location = nil
|
86
|
+
end
|
87
|
+
@buyer_credit = UserCredit.new(@buyer_credit) if @buyer_credit && @buyer_credit.size > 0
|
88
|
+
@seller_credit = UserCredit.new(@seller_credit) if @seller_credit && @seller_credit.size > 0
|
89
|
+
self
|
90
|
+
end
|
91
|
+
end # User model
|
92
|
+
end
|
data/lib/top4r/model.rb
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
module Top4R
|
2
|
+
module ModelMixin
|
3
|
+
module ClassMethods
|
4
|
+
def default_public_fields; []; end
|
5
|
+
|
6
|
+
def default_private_fields; []; end
|
7
|
+
|
8
|
+
# Unmarshal object singular or plural array of model objects
|
9
|
+
# from JSON serialization. Currently JSON is only supported.
|
10
|
+
def unmarshal(raw)
|
11
|
+
# input = JSON.parse(raw)
|
12
|
+
input = raw
|
13
|
+
# puts "\ninput: #{input.inspect}"
|
14
|
+
def unmarshal_model(hash)
|
15
|
+
mine = self.new(hash)
|
16
|
+
# puts "\n mine: #{mine.inspect}"
|
17
|
+
mine.unmarshal_other_attrs if mine.respond_to? :unmarshal_other_attrs
|
18
|
+
mine
|
19
|
+
end
|
20
|
+
return unmarshal_model(input) if input.is_a?(Hash) # singular case
|
21
|
+
result = []
|
22
|
+
input.each do |hash|
|
23
|
+
model = unmarshal_model(hash) if hash.is_a?(Hash)
|
24
|
+
result << model
|
25
|
+
end if input.is_a?(Array)
|
26
|
+
result # plural case
|
27
|
+
end
|
28
|
+
|
29
|
+
def fields
|
30
|
+
(self.default_public_fields + self.default_private_fields).uniq.join(',')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
module InstanceMethods
|
35
|
+
attr_accessor :client
|
36
|
+
|
37
|
+
# Equality method override of Object#eql? default.
|
38
|
+
#
|
39
|
+
# Relies on the class using this mixin to provide a <tt>attributes</tt>
|
40
|
+
# class method that will return an Array of attributes to check are
|
41
|
+
# equivalent in this #eql? override.
|
42
|
+
#
|
43
|
+
# It is by design that the #eql? method will raise a NoMethodError
|
44
|
+
# if no <tt>attributes</tt> class method exists, to alert you that
|
45
|
+
# you must provide it for a meaningful result from this #eql? override.
|
46
|
+
# Otherwise this will return a meaningless result.
|
47
|
+
def eql?(other)
|
48
|
+
attrs = self.class.attributes
|
49
|
+
attrs.each do |att|
|
50
|
+
return false unless self.send(att).eql?(other.send(att))
|
51
|
+
end
|
52
|
+
true
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns integer representation of model object instance.
|
56
|
+
#
|
57
|
+
# For example,
|
58
|
+
# product = Top4R::Product.new(:id => 234343)
|
59
|
+
# product.to_i #=> 234343
|
60
|
+
def to_i
|
61
|
+
@id
|
62
|
+
end
|
63
|
+
|
64
|
+
# Returns hash representation of model object instance.
|
65
|
+
#
|
66
|
+
# For example,
|
67
|
+
# u = Top4R::User.new(:id => 2342342, :screen_name => 'tony_blair_is_the_devil')
|
68
|
+
# u.to_hash #=> {:id => 2342342, :screen_name => 'tony_blair_is_the_devil'}
|
69
|
+
#
|
70
|
+
# This method also requires that the class method <tt>attributes</tt> be
|
71
|
+
# defined to return an Array of attributes for the class.
|
72
|
+
def to_hash
|
73
|
+
attrs = self.class.attributes
|
74
|
+
result = {}
|
75
|
+
attrs.each do |att|
|
76
|
+
value = self.send(att)
|
77
|
+
value = value.to_hash if value.respond_to?(:to_hash)
|
78
|
+
result[att] = value if value
|
79
|
+
end
|
80
|
+
result
|
81
|
+
end
|
82
|
+
|
83
|
+
# "Blesses" model object.
|
84
|
+
#
|
85
|
+
# Should be overridden by model class if special behavior is expected
|
86
|
+
#
|
87
|
+
# Expected to return blessed object (usually <tt>self</tt>)
|
88
|
+
def bless(client)
|
89
|
+
self.basic_bless(client)
|
90
|
+
end
|
91
|
+
|
92
|
+
protected
|
93
|
+
# Basic "blessing" of model object
|
94
|
+
def basic_bless(client)
|
95
|
+
self.client = client
|
96
|
+
self
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.included(receiver)
|
101
|
+
receiver.extend ClassMethods
|
102
|
+
receiver.send :include, Top4R::ClassUtilMixin
|
103
|
+
receiver.send :include, InstanceMethods
|
104
|
+
end
|
105
|
+
end # ModelMixin module
|
106
|
+
end
|
107
|
+
|
108
|
+
require 'top4r/model/user'
|
109
|
+
require 'top4r/model/shipping'
|
110
|
+
require 'top4r/model/trade'
|
111
|
+
require 'top4r/model/suite'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Top4R::Version
|
2
|
+
MAJOR = 0
|
3
|
+
MINOR = 0
|
4
|
+
REVISION = 1
|
5
|
+
|
6
|
+
class << self
|
7
|
+
# Returns X.Y.Z formatted version string
|
8
|
+
def to_version
|
9
|
+
"#{MAJOR}.#{MINOR}.#{REVISION}"
|
10
|
+
end
|
11
|
+
|
12
|
+
# Returns X-Y-Z formatted version name
|
13
|
+
def to_name
|
14
|
+
"#{MAJOR}_#{MINOR}_#{REVISION}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/top4r.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__))
|
2
|
+
|
3
|
+
module Top4R; end
|
4
|
+
|
5
|
+
def require_local(suffix)
|
6
|
+
require(File.expand_path(File.join(File.dirname(__FILE__), suffix)))
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'digest/md5'
|
10
|
+
require 'net/http'
|
11
|
+
require 'net/https'
|
12
|
+
require 'uri'
|
13
|
+
require 'cgi'
|
14
|
+
require 'json'
|
15
|
+
require 'yaml'
|
16
|
+
require 'iconv'
|
17
|
+
require 'activesupport'
|
18
|
+
|
19
|
+
require_local('top4r/ext')
|
20
|
+
require_local('top4r/version')
|
21
|
+
require_local('top4r/meta')
|
22
|
+
require_local('top4r/core')
|
23
|
+
require_local('top4r/model')
|
24
|
+
require_local('top4r/config')
|
25
|
+
require_local('top4r/client')
|
26
|
+
require_local('top4r/console')
|
metadata
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nowa-top4r
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nowa Zhu
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-05-16 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: json
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.1.1
|
24
|
+
version:
|
25
|
+
description:
|
26
|
+
email: nowazhu@gmail.com
|
27
|
+
executables:
|
28
|
+
- top4rsh
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- README
|
33
|
+
- CHANGES
|
34
|
+
- TODO
|
35
|
+
- MIT-LICENSE
|
36
|
+
files:
|
37
|
+
- lib/top4r/client/base.rb
|
38
|
+
- lib/top4r/client/shipping.rb
|
39
|
+
- lib/top4r/client/suite.rb
|
40
|
+
- lib/top4r/client/trade.rb
|
41
|
+
- lib/top4r/client/user.rb
|
42
|
+
- lib/top4r/client.rb
|
43
|
+
- lib/top4r/config.rb
|
44
|
+
- lib/top4r/console.rb
|
45
|
+
- lib/top4r/core.rb
|
46
|
+
- lib/top4r/ext/stdlib.rb
|
47
|
+
- lib/top4r/ext.rb
|
48
|
+
- lib/top4r/meta.rb
|
49
|
+
- lib/top4r/model/shipping.rb
|
50
|
+
- lib/top4r/model/suite.rb
|
51
|
+
- lib/top4r/model/trade.rb
|
52
|
+
- lib/top4r/model/user.rb
|
53
|
+
- lib/top4r/model.rb
|
54
|
+
- lib/top4r/version.rb
|
55
|
+
- lib/top4r.rb
|
56
|
+
- README
|
57
|
+
- CHANGES
|
58
|
+
- TODO
|
59
|
+
- MIT-LICENSE
|
60
|
+
has_rdoc: true
|
61
|
+
homepage: http://top4r.labs.nowa.me
|
62
|
+
licenses:
|
63
|
+
post_install_message:
|
64
|
+
rdoc_options: []
|
65
|
+
|
66
|
+
require_paths:
|
67
|
+
- lib
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: "0"
|
73
|
+
version:
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: "0"
|
79
|
+
version:
|
80
|
+
requirements: []
|
81
|
+
|
82
|
+
rubyforge_project: top4r
|
83
|
+
rubygems_version: 1.3.5
|
84
|
+
signing_key:
|
85
|
+
specification_version: 2
|
86
|
+
summary: TOP4R is a library that can help you build plugin for TaoBao.com quickly in pure Ruby.
|
87
|
+
test_files: []
|
88
|
+
|