ppc 1.0.3 → 1.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +4 -0
- data/lib/ppc.rb +14 -2
- data/lib/ppc/baidu.rb +27 -24
- data/lib/ppc/baidu/account.rb +46 -0
- data/lib/ppc/baidu/bulk.rb +9 -0
- data/lib/ppc/baidu/plan.rb +1 -2
- data/lib/ppc/baidu/report.rb +50 -0
- data/lib/ppc/sogou.rb +125 -0
- data/lib/ppc/sogou/bulk.rb +48 -0
- data/ppc.gemspec +2 -2
- data/spec/bulk_spec.rb +29 -15
- data/spec/report_spec.rb +24 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ef00fb5a5d3113cf2ae07e909ed79dedd8923722
|
4
|
+
data.tar.gz: 4cf8d77c5e0107f635f5248c8a73e04449b01ca5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c1b4cf5437ed71cfe043a63b2473d229b89020d56c2ca2c341d880a6707fa5812927a9a3a08c9675b5963d59cd8bed3032b1b2df138a71bb567fd6300b05eb61
|
7
|
+
data.tar.gz: 141eb3bb4df485429a22e5e707cf65bbcc51f7ba3ea4919e233a8c235cb8fe337dfd27708cbf0293cedcf6b51885de7e7a67d3d23560716d2a2a296312f9b297
|
data/.gitignore
CHANGED
data/lib/ppc.rb
CHANGED
@@ -1,8 +1,20 @@
|
|
1
1
|
require 'ppc/baidu'
|
2
|
+
require 'ppc/sogou'
|
2
3
|
module PPC
|
3
|
-
VERSION = "1.0.
|
4
|
+
VERSION = "1.0.6"
|
4
5
|
attr_reader :header,:body,:rquota,:quota,:status,:desc,:oprs,:oprtime,:code,:message
|
5
6
|
attr_accessor :username,:password,:token,:debug
|
6
7
|
def initialize(params = {})
|
7
8
|
end
|
8
|
-
|
9
|
+
|
10
|
+
protected
|
11
|
+
def print_debug(var,varname=nil)
|
12
|
+
puts '=' * 10 + varname.to_s + '=' * 10
|
13
|
+
if var.is_a? String
|
14
|
+
puts var
|
15
|
+
else
|
16
|
+
ap var
|
17
|
+
end
|
18
|
+
puts '=' * 10 + varname.to_s + '=' * 10
|
19
|
+
end
|
20
|
+
end
|
data/lib/ppc/baidu.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'ppc/baidu/account'
|
2
2
|
require 'ppc/baidu/plan'
|
3
3
|
require 'ppc/baidu/bulk'
|
4
|
+
require 'ppc/baidu/report'
|
4
5
|
require 'awesome_print'
|
5
6
|
require 'savon'
|
6
7
|
module PPC
|
@@ -24,15 +25,14 @@ module PPC
|
|
24
25
|
operation.body = {
|
25
26
|
method+'Request' =>params
|
26
27
|
}
|
27
|
-
|
28
|
-
|
28
|
+
print_debug(operation.body,'operation.body') if @debug
|
29
|
+
print_debug(operation.build,'operation.build') if @debug
|
29
30
|
response = operation.call.hash
|
30
31
|
process_response(response)
|
31
|
-
|
32
|
+
print_debug(response,'response') if @debug
|
32
33
|
response
|
33
34
|
end
|
34
35
|
|
35
|
-
|
36
36
|
def operations
|
37
37
|
@client.operations(@service,@service)
|
38
38
|
end
|
@@ -62,32 +62,34 @@ module PPC
|
|
62
62
|
puts "#{file_id} is ready" if @debug
|
63
63
|
return bulk.path(file_id)
|
64
64
|
rescue
|
65
|
-
@header = bulk.header
|
66
|
-
@oprs = bulk.oprs
|
67
|
-
@oprtime = bulk.oprtime
|
68
|
-
@quota = bulk.quota
|
69
|
-
@rquota = bulk.rquota
|
70
|
-
@status = bulk.status
|
71
|
-
|
72
|
-
@desc = bulk.desc
|
73
|
-
|
74
|
-
case @desc
|
75
|
-
when 'success'
|
76
|
-
when 'failure'
|
77
|
-
|
78
|
-
|
79
|
-
when 'system failure'
|
80
|
-
|
81
|
-
|
82
|
-
else
|
83
|
-
|
84
|
-
end
|
65
|
+
# @header = bulk.header
|
66
|
+
# @oprs = bulk.oprs
|
67
|
+
# @oprtime = bulk.oprtime
|
68
|
+
# @quota = bulk.quota
|
69
|
+
# @rquota = bulk.rquota
|
70
|
+
# @status = bulk.status
|
71
|
+
|
72
|
+
# @desc = bulk.desc
|
73
|
+
|
74
|
+
# case @desc
|
75
|
+
# when 'success'
|
76
|
+
# when 'failure'
|
77
|
+
# @code = bulk.code
|
78
|
+
# @message = bulk.message
|
79
|
+
# when 'system failure'
|
80
|
+
# @code = bulk.code
|
81
|
+
# @message = bulk.message
|
82
|
+
# else
|
83
|
+
# raise "unknown desc from baidu: #{@desc}"
|
84
|
+
# end
|
85
|
+
raise BulkException.new(file_id,bulk)
|
85
86
|
end
|
86
87
|
|
87
88
|
return false
|
88
89
|
end
|
89
90
|
|
90
91
|
private
|
92
|
+
|
91
93
|
def make_operation(operation_name)
|
92
94
|
@client.operation(@service,@service,operation_name)
|
93
95
|
end
|
@@ -117,6 +119,7 @@ module PPC
|
|
117
119
|
|
118
120
|
def process_response(response)
|
119
121
|
body = response[:envelope]
|
122
|
+
print_debug(body,'response.envelope') if @debug
|
120
123
|
@header = body[:header]
|
121
124
|
res_header = header[:res_header]
|
122
125
|
|
data/lib/ppc/baidu/account.rb
CHANGED
@@ -9,6 +9,52 @@ module PPC
|
|
9
9
|
def all(params = {})
|
10
10
|
download(params)
|
11
11
|
end
|
12
|
+
|
13
|
+
def query_report(params = {})
|
14
|
+
report = ::PPC::Baidu::Report.new({
|
15
|
+
username: @username,
|
16
|
+
password: @password,
|
17
|
+
token: @token,
|
18
|
+
debug: @debug
|
19
|
+
})
|
20
|
+
|
21
|
+
begin
|
22
|
+
@file_id = report.file_id_of_query(params)
|
23
|
+
print_debug(@file_id,'file_id') if @debug
|
24
|
+
|
25
|
+
loop do
|
26
|
+
state = report.state(@file_id)
|
27
|
+
raise "invalid file state: #{state}" unless %w(1 2 3 null).include? state
|
28
|
+
break if state == '3'
|
29
|
+
print_debug(state,'file_id.state') if @debug
|
30
|
+
sleep 3
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
return report.path(@file_id)
|
35
|
+
rescue Exception => e
|
36
|
+
# @header = bulk.header
|
37
|
+
# @oprs = bulk.oprs
|
38
|
+
# @oprtime = bulk.oprtime
|
39
|
+
# @quota = bulk.quota
|
40
|
+
# @rquota = bulk.rquota
|
41
|
+
# @status = bulk.status
|
42
|
+
|
43
|
+
# @desc = bulk.desc
|
44
|
+
|
45
|
+
# case @desc
|
46
|
+
# when 'success'
|
47
|
+
# when 'failure'
|
48
|
+
# @code = bulk.code
|
49
|
+
# @message = bulk.message
|
50
|
+
# when 'system failure'
|
51
|
+
# @code = bulk.code
|
52
|
+
# @message = bulk.message
|
53
|
+
# else
|
54
|
+
raise ReportException.new(@file_id,report,e)#,"unknown desc from baidu: #{@desc}"
|
55
|
+
# end
|
56
|
+
end
|
57
|
+
end
|
12
58
|
end
|
13
59
|
end
|
14
60
|
end
|
data/lib/ppc/baidu/bulk.rb
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
module PPC
|
2
2
|
class Baidu
|
3
|
+
class BulkException < Exception
|
4
|
+
attr_reader :file_id,:bulk,:exception
|
5
|
+
def initialize(file_id,bulk,exception)
|
6
|
+
@file_id = file_id
|
7
|
+
@bulk = bulk
|
8
|
+
@exception = exception
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
3
12
|
class Bulk < ::PPC::Baidu
|
4
13
|
def initialize(params = {})
|
5
14
|
params[:service] = 'BulkJob'
|
data/lib/ppc/baidu/plan.rb
CHANGED
@@ -2,12 +2,11 @@ module PPC
|
|
2
2
|
class Baidu
|
3
3
|
class Plan < ::PPC::Baidu
|
4
4
|
def initialize(params = {})
|
5
|
-
params[:service] = '
|
5
|
+
params[:service] = 'Campaign'
|
6
6
|
@se_id = params[:se_id]
|
7
7
|
super(params)
|
8
8
|
end
|
9
9
|
|
10
|
-
|
11
10
|
def all(params = {})
|
12
11
|
params[:plan_ids] = [@se_id]
|
13
12
|
download(params)
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module PPC
|
2
|
+
class Baidu
|
3
|
+
class ReportException < Exception
|
4
|
+
attr_reader :file_id,:report,:exception
|
5
|
+
def initialize(file_id,report,exception)
|
6
|
+
@file_id = file_id
|
7
|
+
@report = report
|
8
|
+
@exception = exception
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class Report < ::PPC::Baidu
|
13
|
+
def initialize(params = {})
|
14
|
+
params[:service] = 'Report'
|
15
|
+
super
|
16
|
+
end
|
17
|
+
|
18
|
+
def file_id_of_query(params = {})
|
19
|
+
options = {
|
20
|
+
performanceData: params[:fields] || %w(click impression),
|
21
|
+
startDate: params[:start] || (Time.now - 2*24*3600).utc.iso8601,
|
22
|
+
endDate: params[:end] || (Time.now - 24*3600).utc.iso8601,
|
23
|
+
idOnly: params[:id_only]|| false,
|
24
|
+
levelOfDetails: params[:level] || 7,
|
25
|
+
# attributes: nil,
|
26
|
+
format: params[:format] || 2,
|
27
|
+
reportType: params[:type] || 6,
|
28
|
+
# statIds: params[:ids] || nil,
|
29
|
+
statRange: params[:range] || 2,
|
30
|
+
unitOfTime: params[:unit] || 5,
|
31
|
+
device: params[:device] || 0
|
32
|
+
}
|
33
|
+
options = {'reportRequestType'=>options}
|
34
|
+
response = request('getProfessionalReportId',options)
|
35
|
+
body = response[:envelope][:body]
|
36
|
+
raise "no result" if body.nil?
|
37
|
+
body[:get_professional_report_id_response][:report_id]
|
38
|
+
end
|
39
|
+
|
40
|
+
def state(id)
|
41
|
+
raise "empty id" if id.nil? or id.empty?
|
42
|
+
request('getReportState',{reportId:id})[:envelope][:body][:get_report_state_response][:is_generated]
|
43
|
+
end
|
44
|
+
|
45
|
+
def path(id)
|
46
|
+
request('getReportFileUrl',{reportId:id})[:envelope][:body][:get_report_file_url_response][:report_file_path]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/ppc/sogou.rb
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'ppc/sogou/account'
|
2
|
+
require 'ppc/sogou/plan'
|
3
|
+
require 'ppc/sogou/bulk'
|
4
|
+
require 'awesome_print'
|
5
|
+
require 'savon'
|
6
|
+
|
7
|
+
module PPC
|
8
|
+
class Sogou
|
9
|
+
include ::PPC
|
10
|
+
|
11
|
+
def initialize(params = {})
|
12
|
+
@service = params[:service] + 'Service'
|
13
|
+
@port_name = params[:service] + 'Service'
|
14
|
+
@username = params[:username]
|
15
|
+
@password = params[:password]
|
16
|
+
@token = params[:token]
|
17
|
+
@client = Savon.new("http://api.agent.sogou.com:8080/sem/sms/v1/#{@service}?wsdl")
|
18
|
+
|
19
|
+
@debug = params[:debug] || false
|
20
|
+
end
|
21
|
+
|
22
|
+
def request(method,params = {})
|
23
|
+
operation = make_operation(method)
|
24
|
+
operation.header = operation_header
|
25
|
+
operation.body = {
|
26
|
+
method+'Request' =>params
|
27
|
+
}
|
28
|
+
print_debug(operation.body,'operation.body') if @debug
|
29
|
+
print_debug(operation.build,'operation.build') if @debug
|
30
|
+
response = operation.call.hash
|
31
|
+
process_response(response)
|
32
|
+
print_debug(response,'response') if @debug
|
33
|
+
response
|
34
|
+
end
|
35
|
+
|
36
|
+
def operations
|
37
|
+
@client.operations(@service,@service)
|
38
|
+
end
|
39
|
+
|
40
|
+
protected
|
41
|
+
def download(params = {})
|
42
|
+
bulk = ::PPC::Sogou::Bulk.new({
|
43
|
+
username: @username,
|
44
|
+
password: @password,
|
45
|
+
token: @token,
|
46
|
+
debug: @debug
|
47
|
+
})
|
48
|
+
|
49
|
+
params[:extended] = params[:extended] || 2
|
50
|
+
|
51
|
+
begin
|
52
|
+
file_id = bulk.file_id_of_all(params)
|
53
|
+
puts "file_id: #{file_id}" if @debug
|
54
|
+
|
55
|
+
loop do
|
56
|
+
state = bulk.state(file_id)
|
57
|
+
raise "invalid file state: #{state}" unless %w(1 2 3 null).include? state
|
58
|
+
break if state == '3'
|
59
|
+
puts "waiting for #{file_id} to be ready. current state:#{state}" if @debug
|
60
|
+
sleep 3
|
61
|
+
end
|
62
|
+
puts "#{file_id} is ready" if @debug
|
63
|
+
return bulk.path(file_id)
|
64
|
+
rescue Exception => e
|
65
|
+
raise PPC::Sogou::BulkException.new(file_id,bulk,e)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
def make_operation(operation_name)
|
71
|
+
@client.operation(@service,@service,operation_name)
|
72
|
+
end
|
73
|
+
|
74
|
+
def operation_header
|
75
|
+
{
|
76
|
+
:AuthHeader=>
|
77
|
+
{
|
78
|
+
username: @username,
|
79
|
+
password: @password,
|
80
|
+
token: @token
|
81
|
+
}
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
def example(operation,with_header=false)
|
86
|
+
operation = make_operation(operation)
|
87
|
+
if with_header
|
88
|
+
{
|
89
|
+
example_header: operation.example_header,
|
90
|
+
example_body: operation.example_body
|
91
|
+
}
|
92
|
+
else
|
93
|
+
operation.example_body
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def process_response(response)
|
98
|
+
body = response[:envelope]
|
99
|
+
@header = body[:header]
|
100
|
+
res_header = header[:res_header]
|
101
|
+
|
102
|
+
@oprs = res_header[:oprs]
|
103
|
+
@oprtime = res_header[:oprtime]
|
104
|
+
@quota = res_header[:quota]
|
105
|
+
@rquota = res_header[:rquota]
|
106
|
+
@status = res_header[:status]
|
107
|
+
|
108
|
+
@desc = res_header[:desc]
|
109
|
+
case @desc
|
110
|
+
when 'success'
|
111
|
+
when 'failure'
|
112
|
+
failures = res_header[:failures]
|
113
|
+
@code = failures[:code]
|
114
|
+
@message = failures[:message]
|
115
|
+
when 'system failure'
|
116
|
+
failures = res_header[:failures]
|
117
|
+
@code = failures[:code]
|
118
|
+
@message = failures[:message]
|
119
|
+
else
|
120
|
+
raise "unknown desc from sogou: #{@desc}"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module PPC
|
2
|
+
class Sogou
|
3
|
+
class BulkException < Exception
|
4
|
+
attr_reader :file_id,:bulk,:exception
|
5
|
+
def initialize(file_id,bulk,exception)
|
6
|
+
@file_id = file_id
|
7
|
+
@bulk = bulk
|
8
|
+
@exception = exception
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class Bulk < ::PPC::Sogou
|
13
|
+
def initialize(params = {})
|
14
|
+
params[:service] = 'AccountDownload'
|
15
|
+
super(params)
|
16
|
+
end
|
17
|
+
|
18
|
+
def file_id_of_all(params = {})
|
19
|
+
plan_ids = params[:plan_ids]
|
20
|
+
|
21
|
+
unless plan_ids.nil?
|
22
|
+
plan_ids = plan_ids.class == Array ? plan_ids : [plan_ids]
|
23
|
+
end
|
24
|
+
|
25
|
+
options = {
|
26
|
+
cpcPlanIds: plan_ids || [] ,
|
27
|
+
includeQuality: params[:quality] || true ,
|
28
|
+
includeTemp: params[:temp] || false ,
|
29
|
+
format: params[:format] || 1
|
30
|
+
}
|
31
|
+
response = request('getAccountFile',options)
|
32
|
+
|
33
|
+
body = response[:envelope][:body]
|
34
|
+
raise "no result" if body.nil?
|
35
|
+
body[:get_account_file_response][:accountFileId]
|
36
|
+
end
|
37
|
+
|
38
|
+
def state(id)
|
39
|
+
raise "empty id" if id.nil? or id.empty?
|
40
|
+
request('getAccountFileStatus',{accountFileId:id})[:envelope][:body][:get_account_file_status_response][:is_generated]
|
41
|
+
end
|
42
|
+
|
43
|
+
def path(id)
|
44
|
+
request('getAccountFilePath',{accountFileId:id})[:envelope][:body][:get_account_file_path_response][:account_file_path]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/ppc.gemspec
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
lib = File.expand_path('../lib', __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
|
4
|
+
require 'ppc'
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "ppc"
|
7
|
-
spec.version =
|
7
|
+
spec.version = PPC::VERSION
|
8
8
|
spec.authors = ["charles"]
|
9
9
|
spec.email = ["charles.liu@corp.elong.com"]
|
10
10
|
spec.summary = %q{ppc api for google baidu etc}
|
data/spec/bulk_spec.rb
CHANGED
@@ -1,21 +1,35 @@
|
|
1
|
-
describe ::PPC::Baidu::Bulk do
|
2
|
-
|
1
|
+
# describe ::PPC::Baidu::Bulk do
|
2
|
+
# subject{::PPC::Baidu::Bulk.new(
|
3
|
+
# debug:true,
|
4
|
+
# username:'',
|
5
|
+
# password:'',
|
6
|
+
# token:'')
|
7
|
+
# }
|
8
|
+
# it "could get file_id_of_all" do
|
9
|
+
# begin
|
10
|
+
# result = subject.file_id_of_all
|
11
|
+
# rescue
|
12
|
+
# expect(subject.code).to eq '901162'
|
13
|
+
# end
|
14
|
+
|
15
|
+
# if result.nil?
|
16
|
+
# expect(subject.code).to eq '901162'
|
17
|
+
# else
|
18
|
+
# expect(result.size).to eq 32
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
|
23
|
+
describe ::PPC::Sogou::Bulk do
|
24
|
+
subject{::PPC::Sogou::Bulk.new(
|
3
25
|
debug:true,
|
4
|
-
username:'',
|
5
|
-
password:'',
|
6
|
-
token:'')
|
26
|
+
username:'zongheelongexact1@sogou.com',
|
27
|
+
password:'elongsem2014J',
|
28
|
+
token:'a2c5a0b092c0aeb63923b92c03aaa5ea')
|
7
29
|
}
|
8
30
|
it "could get file_id_of_all" do
|
9
|
-
|
10
|
-
result = subject.file_id_of_all
|
11
|
-
rescue
|
12
|
-
expect(subject.code).to eq '901162'
|
13
|
-
end
|
31
|
+
# result = subject.file_id_of_all
|
14
32
|
|
15
|
-
|
16
|
-
expect(subject.code).to eq '901162'
|
17
|
-
else
|
18
|
-
expect(result.size).to eq 32
|
19
|
-
end
|
33
|
+
p subject.path('2ee48aa67a06bf05c3fd54f84c6a4656')
|
20
34
|
end
|
21
35
|
end
|
data/spec/report_spec.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
describe ::PPC::Baidu::Report do
|
2
|
+
subject{
|
3
|
+
::PPC::Baidu::Report.new(
|
4
|
+
debug:true,
|
5
|
+
username:'',
|
6
|
+
password:'',
|
7
|
+
token:'')
|
8
|
+
}
|
9
|
+
it "could get report_id" do
|
10
|
+
file_id = subject.file_id_of_query
|
11
|
+
expect(file_id.size).to eq 32
|
12
|
+
times = 0
|
13
|
+
state = 0
|
14
|
+
loop do
|
15
|
+
state = subject.state(file_id)
|
16
|
+
break if state == 3 or times >= 3
|
17
|
+
times += 1
|
18
|
+
sleep 5
|
19
|
+
end
|
20
|
+
expect(state).to eq 3
|
21
|
+
path = subject.path(file_id)
|
22
|
+
expect(path).to begin_with? 'https://'
|
23
|
+
end
|
24
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ppc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- charles
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-08-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -56,12 +56,16 @@ files:
|
|
56
56
|
- lib/ppc/baidu/account.rb
|
57
57
|
- lib/ppc/baidu/bulk.rb
|
58
58
|
- lib/ppc/baidu/plan.rb
|
59
|
+
- lib/ppc/baidu/report.rb
|
59
60
|
- lib/ppc/qihu.rb
|
60
61
|
- lib/ppc/qihu/account.rb
|
62
|
+
- lib/ppc/sogou.rb
|
63
|
+
- lib/ppc/sogou/bulk.rb
|
61
64
|
- ppc.gemspec
|
62
65
|
- spec/account_spec.rb
|
63
66
|
- spec/bulk_spec.rb
|
64
67
|
- spec/plan_spec.rb
|
68
|
+
- spec/report_spec.rb
|
65
69
|
- spec/spec_helper.rb
|
66
70
|
homepage: http://github.com/seoaqua/ppc
|
67
71
|
licenses:
|
@@ -91,4 +95,5 @@ test_files:
|
|
91
95
|
- spec/account_spec.rb
|
92
96
|
- spec/bulk_spec.rb
|
93
97
|
- spec/plan_spec.rb
|
98
|
+
- spec/report_spec.rb
|
94
99
|
- spec/spec_helper.rb
|