ppc 1.3.0 → 1.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +4 -1
- data/LICENSE +334 -17
- data/README.md +75 -3
- data/lib/ppc.rb +3 -1
- data/lib/ppc/api.rb +137 -2
- data/lib/ppc/api/baidu.rb +20 -99
- data/lib/ppc/api/baidu/account.rb +21 -21
- data/lib/ppc/api/baidu/bulk.rb +39 -3
- data/lib/ppc/api/baidu/creative.rb +33 -33
- data/lib/ppc/api/baidu/group.rb +14 -14
- data/lib/ppc/api/baidu/keyword.rb +57 -46
- data/lib/ppc/api/baidu/phone_new_creative.rb +51 -0
- data/lib/ppc/api/baidu/plan.rb +34 -31
- data/lib/ppc/api/baidu/rank.rb +23 -0
- data/lib/ppc/api/baidu/report.rb +100 -81
- data/lib/ppc/api/qihu.rb +150 -0
- data/lib/ppc/api/qihu/account.rb +86 -0
- data/lib/ppc/api/qihu/bulk.rb +35 -0
- data/lib/ppc/api/qihu/creative.rb +108 -0
- data/lib/ppc/api/qihu/group.rb +96 -0
- data/lib/ppc/api/qihu/keyword.rb +113 -0
- data/lib/ppc/api/qihu/plan.rb +64 -0
- data/lib/ppc/api/qihu/rank.rb +25 -0
- data/lib/ppc/api/qihu/report.rb +159 -0
- data/lib/ppc/api/qihu/sublink.rb +71 -0
- data/lib/ppc/api/shenma.rb +64 -0
- data/lib/ppc/api/shenma/report.rb +135 -0
- data/lib/ppc/api/sm.rb +50 -0
- data/lib/ppc/api/sm/account.rb +44 -0
- data/lib/ppc/api/sm/bulk.rb +69 -0
- data/lib/ppc/api/sm/creative.rb +86 -0
- data/lib/ppc/api/sm/group.rb +94 -0
- data/lib/ppc/api/sm/keyword.rb +132 -0
- data/lib/ppc/api/sm/phone_new_creative.rb +51 -0
- data/lib/ppc/api/sm/plan.rb +63 -0
- data/lib/ppc/api/sm/report.rb +136 -0
- data/lib/ppc/api/sogou.rb +118 -0
- data/lib/ppc/api/sogou/account.rb +42 -0
- data/lib/ppc/api/sogou/bulk.rb +69 -0
- data/lib/ppc/api/sogou/creative.rb +117 -0
- data/lib/ppc/api/sogou/group.rb +123 -0
- data/lib/ppc/api/sogou/keyword.rb +188 -0
- data/lib/ppc/api/sogou/plan.rb +66 -0
- data/lib/ppc/api/sogou/report.rb +129 -0
- data/lib/ppc/ext.rb +17 -0
- data/lib/ppc/operation.rb +50 -36
- data/lib/ppc/operation/account.rb +19 -7
- data/lib/ppc/operation/creative.rb +7 -7
- data/lib/ppc/operation/group.rb +2 -2
- data/lib/ppc/operation/keyword.rb +11 -8
- data/lib/ppc/operation/report.rb +23 -0
- data/ppc.gemspec +14 -4
- data/spec/baidu/api_baidu_account_spec.rb +16 -0
- data/spec/baidu/api_baidu_creative_spec.rb +73 -0
- data/spec/{api_baidu_group_spec.rb → baidu/api_baidu_group_spec.rb} +12 -17
- data/spec/baidu/api_baidu_keyword_spec.rb +61 -0
- data/spec/baidu/api_baidu_phone_spec.rb +22 -0
- data/spec/{api_baidu_plan_spec.rb → baidu/api_baidu_plan_spec.rb} +11 -10
- data/spec/baidu/api_baidu_report_spec.rb +44 -0
- data/spec/{api_baidu_spec.rb → baidu/api_baidu_spec.rb} +10 -15
- data/spec/operation/operation_baidu_report_spec.rb +17 -0
- data/spec/operation/operation_baidu_spec.rb +126 -0
- data/spec/operation/operation_qihu_report_spec.rb +18 -0
- data/spec/operation/operation_qihu_spec.rb +94 -0
- data/spec/operation/operation_sm_report_spec.rb +21 -0
- data/spec/operation/operation_sogou_report_spec.rb +17 -0
- data/spec/operation/operation_sogou_spec.rb +88 -0
- data/spec/{operation_spec_helper.rb → operation/operation_spec_helper.rb} +3 -5
- data/spec/qihu/api_qihu_account_spec.rb +29 -0
- data/spec/qihu/api_qihu_creative_spec.rb +48 -0
- data/spec/qihu/api_qihu_group_spec.rb +40 -0
- data/spec/qihu/api_qihu_keyword_spec.rb +50 -0
- data/spec/qihu/api_qihu_plan_spec.rb +39 -0
- data/spec/qihu/api_qihu_report_spec.rb +54 -0
- data/spec/qihu/api_qihu_sublink_spec.rb +36 -0
- data/spec/sm/api_sm_account_spec.rb +8 -0
- data/spec/sm/api_sm_creative_spec.rb +52 -0
- data/spec/sm/api_sm_group_spec.rb +75 -0
- data/spec/sm/api_sm_keyword_spec.rb +59 -0
- data/spec/sm/api_sm_plan_spec.rb +39 -0
- data/spec/sm/api_sm_report_spec.rb +30 -0
- data/spec/sogou/api_sogou_account_spec.rb +17 -0
- data/spec/sogou/api_sogou_creative_spec.rb +51 -0
- data/spec/sogou/api_sogou_group_spec.rb +50 -0
- data/spec/sogou/api_sogou_keyword_spec.rb +54 -0
- data/spec/sogou/api_sogou_plan_spec.rb +43 -0
- data/spec/sogou/api_sogou_report_spec.rb +51 -0
- data/spec/spec_helper.rb +49 -10
- metadata +140 -46
- data/lib/ppc/baidu.rb +0 -152
- data/lib/ppc/baidu/account.rb +0 -88
- data/lib/ppc/baidu/bulk.rb +0 -52
- data/lib/ppc/baidu/group.rb +0 -99
- data/lib/ppc/baidu/key.rb +0 -38
- data/lib/ppc/baidu/plan.rb +0 -85
- data/lib/ppc/baidu/report.rb +0 -82
- data/spec/api_baidu_account_spec.rb +0 -18
- data/spec/api_baidu_creative_spec.rb +0 -71
- data/spec/api_baidu_keyword_spec.rb +0 -64
- data/spec/api_baidu_report_spec.rb +0 -32
- data/spec/baidu_account_spec.rb +0 -32
- data/spec/baidu_bulk_spec.rb +0 -21
- data/spec/baidu_group_spec.rb +0 -56
- data/spec/baidu_plan_spec.rb +0 -129
- data/spec/baidu_report_spec.rb +0 -24
- data/spec/operation_spec.rb +0 -87
@@ -0,0 +1,42 @@
|
|
1
|
+
module PPC
|
2
|
+
module API
|
3
|
+
class Sogou
|
4
|
+
class Account < Sogou
|
5
|
+
Service = 'Account'
|
6
|
+
|
7
|
+
@map = [
|
8
|
+
[:id,:accountid],
|
9
|
+
[:balance,:balance],
|
10
|
+
[:cost,:totalCost],
|
11
|
+
[:payment,:totalPay],
|
12
|
+
[:budget_type,:type],
|
13
|
+
[:budget,:budget],
|
14
|
+
[:region,:regions],
|
15
|
+
[:exclude_ip,:excludeIps],
|
16
|
+
[:open_domains,:domains],
|
17
|
+
[:offline_time,:budgetOfflineTime],
|
18
|
+
[:opt,:opt]
|
19
|
+
]
|
20
|
+
|
21
|
+
def self.info(auth)
|
22
|
+
response = request(auth,Service,'getAccountInfo' )
|
23
|
+
process( response, 'accountInfoType' ){ |x|reverse_type(x)[0] }
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.update(auth, param = {})
|
27
|
+
"""
|
28
|
+
update account info
|
29
|
+
@ params : account_info_type
|
30
|
+
@return : account info_type
|
31
|
+
"""
|
32
|
+
# for account service, there is not bulk operation
|
33
|
+
infoType = make_type( param )[0]
|
34
|
+
body = { accountInfoType: infoType }
|
35
|
+
response = request(auth,Service,'updateAccountInfo', body)
|
36
|
+
process( response, 'accountInfoType' ){ |x|reverse_type(x)[0] }
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# -*- coding:utf-8 -*-
|
2
|
+
module PPC
|
3
|
+
module API
|
4
|
+
class Sogou
|
5
|
+
class Bulk < Sogou
|
6
|
+
Service = 'AccountDownload'
|
7
|
+
|
8
|
+
def self.get_all_object( auth, ids )
|
9
|
+
#文档上面写的输入类型是String?
|
10
|
+
body = nil
|
11
|
+
body = { 'cpcPlanIds' => ids } if ids
|
12
|
+
response = request( auth, Service, 'getAccountFile', body )
|
13
|
+
process( response, 'accountFileId' ){ |x| x }
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.get_file_state( auth, id )
|
17
|
+
body = { 'accountFileId' => id }
|
18
|
+
response = request( auth, Service, 'getAccountFileStatus' , body )
|
19
|
+
process( response, 'isGenerated' ){ |x| x }
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.get_file_path(auth, id)
|
23
|
+
body = {'accountFileId' => id}
|
24
|
+
response = request(auth, Service, 'getAccountFilePath', body)
|
25
|
+
process(response, 'accountFilePath'){|x| x}
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.download( auth, ids = nil)
|
29
|
+
result = get_all_object(auth, ids)
|
30
|
+
field_id = result[:result]
|
31
|
+
loop do
|
32
|
+
status = get_file_state(auth, field_id)
|
33
|
+
return get_file_path(auth, field_id) if status[:result] == '1'
|
34
|
+
sleep 15
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.get_cpc_rank(auth, device)
|
39
|
+
body = {'deviceType' => device}
|
40
|
+
response = request(auth, 'CpcRank', 'getCpcRankId', body)
|
41
|
+
process(response, 'rankId'){|x| x}
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.get_cpc_rank_status(auth, rank_id)
|
45
|
+
body = {'rankId' => rank_id}
|
46
|
+
response = request(auth, 'CpcRank', 'getCpcRankStatus', body)
|
47
|
+
process(response, 'isGenerated' ){|x| x }
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.get_cpc_rank_path(auth, rank_id)
|
51
|
+
body = {'rankId' => rank_id}
|
52
|
+
response = request(auth, 'CpcRank', 'getCpcRankPath', body)
|
53
|
+
process(response, 'rankPath'){|x| x}
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.download_cpc_rank(auth, device = 0)
|
57
|
+
result = get_cpc_rank(auth, device)
|
58
|
+
rank_id = result[:result]
|
59
|
+
loop do
|
60
|
+
status = get_cpc_rank_status(auth, rank_id)
|
61
|
+
return get_cpc_rank_path(auth, rank_id) if status[:result] == '1'
|
62
|
+
sleep 15
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# -*- coding:utf-8 -*-
|
2
|
+
module PPC
|
3
|
+
module API
|
4
|
+
class Sogou
|
5
|
+
class Creative< Sogou
|
6
|
+
Service = 'CpcIdea'
|
7
|
+
|
8
|
+
@map =[
|
9
|
+
[:id,:cpcIdeaId],
|
10
|
+
[:group_id,:cpcGrpId],
|
11
|
+
[:title,:title],
|
12
|
+
[:description1,:description1],
|
13
|
+
[:description2,:description2],
|
14
|
+
[:pc_destination,:visitUrl],
|
15
|
+
[:pc_display,:showUrl],
|
16
|
+
[:moile_destination,:mobileVisitUrl],
|
17
|
+
[:mobile_display,:mobileShowUrl],
|
18
|
+
[:pause,:pause],
|
19
|
+
[:status,:status]
|
20
|
+
]
|
21
|
+
|
22
|
+
@status_map = [
|
23
|
+
[:id,:cpcIdeaId],
|
24
|
+
[:status,:status]
|
25
|
+
]
|
26
|
+
|
27
|
+
|
28
|
+
def self.add( auth, creatives )
|
29
|
+
body = { cpcIdeaTypes: make_type( creatives ) }
|
30
|
+
response = request( auth, Service, 'addCpcIdea', body )
|
31
|
+
process( response, 'cpcIdeaTypes' ){ |x| reverse_type(x) }
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.get( auth, ids, getTemp = 0 )
|
35
|
+
'''
|
36
|
+
\'getCreativeByCreativeId\'
|
37
|
+
@ input : creative ids
|
38
|
+
@ output: creative informations
|
39
|
+
'''
|
40
|
+
ids = [ ids ] unless ids.is_a? Array
|
41
|
+
body = { cpcIdeaIds: ids, getTemp: getTemp }
|
42
|
+
response = request( auth, Service, 'getCpcIdeaByCpcIdeaId', body )
|
43
|
+
process( response, 'cpcIdeaTypes' ){ |x| reverse_type(x) }
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.update( auth, creatives )
|
47
|
+
'''
|
48
|
+
根据实际使用情况,更新的时候creative title为必填选
|
49
|
+
'''
|
50
|
+
body = { cpcIdeaTypes: make_type( creatives ) }
|
51
|
+
response = request( auth, Service, 'updateCpcIdea', body )
|
52
|
+
process( response, 'cpcIdeaTypes' ){ |x| reverse_type(x) }
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.delete( auth, ids )
|
56
|
+
ids = [ ids ] unless ids.is_a? Array
|
57
|
+
body = { cpcIdeaIds: ids }
|
58
|
+
response = request( auth, Service, 'deleteCpcIdea', body )
|
59
|
+
process( response, '' ){ |x| x }
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.status( auth, ids, getTemp = 0 )
|
63
|
+
ids = [ ids ] unless ids.is_a? Array
|
64
|
+
body = { cpcIdeaIds: ids, getTemp: getTemp }
|
65
|
+
response = request( auth, Service, 'getCpcIdeaByCpcIdeaId', body )
|
66
|
+
process( response, 'cpcIdeaTypes' ){ |x| reverse_type(x, @status_map) }
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.search_id_by_group_id( auth, ids, getTemp = 0 )
|
70
|
+
'''
|
71
|
+
\'getCreativeIdByAdgroupId\'
|
72
|
+
@ input: group ids
|
73
|
+
@ output: groupCreativeIds
|
74
|
+
'''
|
75
|
+
ids = [ ids ] unless ids.is_a? Array
|
76
|
+
body = { cpcGrpIds: ids, getTemp: getTemp }
|
77
|
+
response = request( auth, Service, 'getCpcIdeaIdByCpcGrpId', body )
|
78
|
+
process( response, 'cpcGrpIdeaIds' ){ |x| make_groupCreativeIds( x ) }
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.search_by_group_id( auth, ids, getTemp = 0 )
|
82
|
+
ids = [ ids ] unless ids.is_a? Array
|
83
|
+
body = { cpcGrpIds: ids, getTemp: getTemp }
|
84
|
+
response = request( auth, Service, 'getCpcIdeaByCpcGrpId', body )
|
85
|
+
process( response, 'cpcGrpIdeas' ){ |x| make_groupCreatives( x ) }
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
def self.make_groupCreativeIds( cpcGrpIdeaIdTypes )
|
90
|
+
cpcGrpIdeaIdTypes = [cpcGrpIdeaIdTypes] unless cpcGrpIdeaIdTypes.is_a? Array
|
91
|
+
group_creative_ids = []
|
92
|
+
cpcGrpIdeaIdTypes.each do |cpcGrpIdeaIdType|
|
93
|
+
group_creative_id = { }
|
94
|
+
group_creative_id[:group_id] = cpcGrpIdeaIdType[:cpc_grp_id]
|
95
|
+
group_creative_id[:creative_ids] = cpcGrpIdeaIdType[:cpc_idea_ids]
|
96
|
+
group_creative_ids << group_creative_id
|
97
|
+
end
|
98
|
+
return group_creative_ids
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
def self.make_groupCreatives( cpcGrpIdeaTypes )
|
103
|
+
cpcGrpIdeaTypes = [cpcGrpIdeaTypes] unless cpcGrpIdeaTypes.is_a? Array
|
104
|
+
group_creatives = []
|
105
|
+
cpcGrpIdeaTypes.each do |cpcGrpIdeaType|
|
106
|
+
group_creative = {}
|
107
|
+
group_creative[:group_id] = cpcGrpIdeaType[:cpc_grp_id]
|
108
|
+
group_creative[:creatives] = reverse_type( cpcGrpIdeaType[:cpc_idea_types] )
|
109
|
+
group_creatives << group_creative
|
110
|
+
end
|
111
|
+
return group_creatives
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
# -*- coding:utf-8 -*-
|
2
|
+
module PPC
|
3
|
+
module API
|
4
|
+
class Sogou
|
5
|
+
class Group< Sogou
|
6
|
+
Service = 'CpcGrp'
|
7
|
+
|
8
|
+
@map =[
|
9
|
+
[:plan_id, :cpcPlanId],
|
10
|
+
[:id, :cpcGrpId],
|
11
|
+
[:name, :cpcGrpName],
|
12
|
+
[:price, :maxPrice],
|
13
|
+
[:negative, :negativeWords],
|
14
|
+
[:exact_negative, :exactNegativeWords],
|
15
|
+
[:pause, :pause],
|
16
|
+
[:status, :status],
|
17
|
+
[:opt, :opt]
|
18
|
+
]
|
19
|
+
|
20
|
+
def self.ids( auth )
|
21
|
+
"""
|
22
|
+
@return : Array of cpcPlanGrpIdTypes
|
23
|
+
"""
|
24
|
+
response = request( auth, Service , "getAllCpcGrpId" )
|
25
|
+
#此处返回值与key与开发文档不同
|
26
|
+
process( response, 'cpcPlanGrpIds' ){ |x| make_planGroupIds( x ) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.get( auth, ids )
|
30
|
+
ids = [ ids ] unless ids.is_a? Array
|
31
|
+
body = { cpcGrpIds: ids }
|
32
|
+
response = request(auth, Service, "getCpcGrpByCpcGrpId",body )
|
33
|
+
process( response, 'cpcGrpTypes' ){ |x| reverse_type(x) }
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.add( auth, groups )
|
37
|
+
"""
|
38
|
+
@ input : one or list of AdgroupType
|
39
|
+
@ output : list of AdgroupType
|
40
|
+
"""
|
41
|
+
cpcGrpTypes = make_type( groups )
|
42
|
+
|
43
|
+
body = {cpcGrpTypes: cpcGrpTypes }
|
44
|
+
|
45
|
+
response = request( auth, Service, "addCpcGrp", body )
|
46
|
+
process( response, 'cpcGrpTypes' ){ |x| reverse_type(x) }
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.update( auth, groups )
|
50
|
+
"""
|
51
|
+
@ input : one or list of AdgroupType
|
52
|
+
@ output : list of AdgroupType
|
53
|
+
"""
|
54
|
+
cpcGrpTypes = make_type( groups )
|
55
|
+
body = {cpcGrpTypes: cpcGrpTypes}
|
56
|
+
|
57
|
+
response = request( auth, Service, "updateCpcGrp",body )
|
58
|
+
process( response, 'cpcGrpTypes' ){ |x| reverse_type(x) }
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.delete( auth, ids )
|
62
|
+
"""
|
63
|
+
delete group body has no message
|
64
|
+
"""
|
65
|
+
ids = [ ids ] unless ids.is_a? Array
|
66
|
+
body = { cpcGrpIds: ids }
|
67
|
+
response = request( auth, Service,"deleteCpcGrp", body )
|
68
|
+
process( response, '' ){ |x| x }
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.search_by_plan_id( auth, ids )
|
72
|
+
ids = [ ids ] unless ids.is_a? Array
|
73
|
+
body = { cpcPlanIds: ids }
|
74
|
+
response = request( auth, Service ,"getCpcGrpByCpcPlanId", body )
|
75
|
+
# 此处key与开发文档不同
|
76
|
+
process( response, 'cpcPlanGrps' ){ |x| make_planGroups( x ) }
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.search_id_by_plan_id( auth, ids )
|
80
|
+
ids = [ ids ] unless ids.is_a? Array
|
81
|
+
body = { cpcPlanIds: ids }
|
82
|
+
response = request( auth, Service ,"getCpcGrpIdByCpcPlanId", body )
|
83
|
+
process( response, 'cpcPlanGrpIds' ){ |x| make_planGroupIds( x ) }
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
def self.make_planGroupIds( cpcPlanGrpIdTypes )
|
88
|
+
"""
|
89
|
+
Transfer Sogou API to PPC API
|
90
|
+
Item: cpc_plan_group_ids
|
91
|
+
"""
|
92
|
+
cpcPlanGrpIdTypes = [cpcPlanGrpIdTypes] unless cpcPlanGrpIdTypes.is_a? Array
|
93
|
+
planGroupIds = []
|
94
|
+
cpcPlanGrpIdTypes.each do |cpcPlanGrpIdType|
|
95
|
+
planGroupId = {}
|
96
|
+
planGroupId[:plan_id] = cpcPlanGrpIdType[:cpc_plan_id]
|
97
|
+
planGroupId[:group_ids] = cpcPlanGrpIdType[:cpc_grp_ids]
|
98
|
+
planGroupIds << planGroupId
|
99
|
+
end
|
100
|
+
return planGroupIds
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
def self.make_planGroups( cpcPlanGrpTypes )
|
105
|
+
"""
|
106
|
+
Transfer Sogou API to PPC API
|
107
|
+
"""
|
108
|
+
# 多加一行change成array
|
109
|
+
cpcPlanGrpTypes = [cpcPlanGrpTypes] unless cpcPlanGrpTypes.is_a? Array
|
110
|
+
planGroups = []
|
111
|
+
cpcPlanGrpTypes.each do |cpcPlanGrpType|
|
112
|
+
planGroup = {}
|
113
|
+
planGroup[:plan_id] = cpcPlanGrpType[:cpc_plan_id]
|
114
|
+
planGroup[:groups] = reverse_type( cpcPlanGrpType[:cpc_grp_types] )
|
115
|
+
planGroups << planGroup
|
116
|
+
end
|
117
|
+
return planGroups
|
118
|
+
end
|
119
|
+
|
120
|
+
end # class group
|
121
|
+
end # class baidu
|
122
|
+
end # API
|
123
|
+
end # module
|
@@ -0,0 +1,188 @@
|
|
1
|
+
# -*- coding:utf-8 -*-
|
2
|
+
"""
|
3
|
+
Todo: Implement Activate Method
|
4
|
+
"""
|
5
|
+
module PPC
|
6
|
+
module API
|
7
|
+
class Sogou
|
8
|
+
class Keyword< Sogou
|
9
|
+
Service = 'Cpc'
|
10
|
+
|
11
|
+
#Match_type = { 'exact' => 0, 'wide' => 1,0 => 'exact', 1 => 'wide' }
|
12
|
+
Match_type = { 'exact' => 0, 'phrase' => 2, 'wide' => 1,'0' => 'exact', '2' => 'phrase', '1' => 'wide' }
|
13
|
+
|
14
|
+
@map = [
|
15
|
+
[:id,:cpcId],
|
16
|
+
[:group_id,:cpcGrpId],
|
17
|
+
[:keyword,:cpc],
|
18
|
+
[:price,:price],
|
19
|
+
[:pc_destination,:visitUrl],
|
20
|
+
[:mobile_destination,:mobileVisitUrl],
|
21
|
+
[:match_type,:matchType],
|
22
|
+
[:pause,:pause],
|
23
|
+
[:status,:status],
|
24
|
+
[:quality,:cpcQuality]
|
25
|
+
]
|
26
|
+
@quality_map = [
|
27
|
+
[:id,:cpcId],
|
28
|
+
[:quality,:cpcQuality]
|
29
|
+
]
|
30
|
+
|
31
|
+
@status_map = [
|
32
|
+
[:id,:cpcId],
|
33
|
+
[:status,:status]
|
34
|
+
]
|
35
|
+
|
36
|
+
# 后面改成info方法
|
37
|
+
def self.get( auth, ids )
|
38
|
+
'''
|
39
|
+
getCpcByCpcId
|
40
|
+
'''
|
41
|
+
ids = [ ids ] unless ids.is_a? Array
|
42
|
+
body = { cpcIds: ids}
|
43
|
+
response = request( auth, Service, 'getCpcByCpcId', body )
|
44
|
+
process(response, 'cpcTypes'){|x| reverse_type( x ) }
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.add( auth, keywords )
|
48
|
+
'''
|
49
|
+
'''
|
50
|
+
cpcTypes = make_type( keywords )
|
51
|
+
body = { cpcTypes: cpcTypes }
|
52
|
+
response = request( auth, Service, "addCpc", body )
|
53
|
+
process(response, 'cpcTypes'){|x| reverse_type(x) }
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.update( auth, keywords )
|
57
|
+
'''
|
58
|
+
'''
|
59
|
+
cpcTypes = make_type( keywords )
|
60
|
+
body = { cpcTypes: cpcTypes }
|
61
|
+
response = request( auth, Service, "updateCpc", body )
|
62
|
+
process(response, 'cpcTypes'){|x| reverse_type(x) }
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.delete( auth, ids )
|
66
|
+
"""
|
67
|
+
"""
|
68
|
+
ids = [ ids ] unless ids.is_a? Array
|
69
|
+
body = { cpcIds: ids}
|
70
|
+
response = request( auth, Service, 'deleteCpc', body )
|
71
|
+
process(response, ''){|x| x }
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.search_by_group_id( auth, group_ids )
|
75
|
+
"""
|
76
|
+
getKeywordByGroupIds
|
77
|
+
@input: list of group id
|
78
|
+
@output: list of groupKeyword
|
79
|
+
"""
|
80
|
+
group_ids = [ group_ids ] unless group_ids.is_a? Array
|
81
|
+
body = { cpcGrpIds: group_ids }
|
82
|
+
response = request( auth, Service, "getCpcByCpcGrpId", body )
|
83
|
+
process(response, 'cpcGrpCpcs'){|x| make_groupKeywords( x ) }
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.search_id_by_group_id( auth, group_ids )
|
87
|
+
group_ids = [ group_ids ] unless group_ids.is_a? Array
|
88
|
+
body = { cpcGrpIds: group_ids }
|
89
|
+
response = request( auth, Service, "getCpcIdByCpcGrpId", body )
|
90
|
+
process(response, 'cpcGrpCpcIds'){|x| make_groupKeywordIds( x ) }
|
91
|
+
end
|
92
|
+
|
93
|
+
# sogou的keyword服务不提供质量度和状态,从getInfo方法中查询
|
94
|
+
def self.status( auth, ids )
|
95
|
+
'''
|
96
|
+
Return [ { id: id, status: status} ... ]
|
97
|
+
'''
|
98
|
+
ids = [ ids ] unless ids.is_a? Array
|
99
|
+
body = { cpcIds: ids}
|
100
|
+
response = request( auth, Service, 'getCpcByCpcId', body )
|
101
|
+
process(response, 'cpcTypes'){ |x| reverse_type(x, @status_map) }
|
102
|
+
end
|
103
|
+
|
104
|
+
def self.quality( auth ,ids )
|
105
|
+
'''
|
106
|
+
Return [ { id: id, quality: quality} ... ]
|
107
|
+
'''
|
108
|
+
ids = [ ids ] unless ids.is_a? Array
|
109
|
+
body = { cpcIds: ids}
|
110
|
+
response = request( auth, Service, 'getCpcByCpcId', { cpcIds: ids} )
|
111
|
+
process(response, 'cpcTypes'){ |x| reverse_type(x, @quality_map) }
|
112
|
+
end
|
113
|
+
|
114
|
+
private
|
115
|
+
def self.make_groupKeywordIds( cpcGrpCpcIdTypes )
|
116
|
+
"""
|
117
|
+
Transfer Sogou API to PPC API
|
118
|
+
"""
|
119
|
+
cpcGrpCpcIdTypes = [cpcGrpCpcIdTypes] unless cpcGrpCpcIdTypes.is_a? Array
|
120
|
+
group_keyword_ids = []
|
121
|
+
cpcGrpCpcIdTypes.each do |cpcGrpCpcIdType|
|
122
|
+
group_keyword_id = { }
|
123
|
+
group_keyword_id[:group_id] = cpcGrpCpcIdType[:cpc_grp_id]
|
124
|
+
group_keyword_id[:keyword_ids] = cpcGrpCpcIdType[:cpc_ids]
|
125
|
+
group_keyword_ids << group_keyword_id
|
126
|
+
end
|
127
|
+
return group_keyword_ids
|
128
|
+
end
|
129
|
+
|
130
|
+
private
|
131
|
+
def self.make_groupKeywords( cpcGrpCpcTypes )
|
132
|
+
cpcGrpCpcTypes = [cpcGrpCpcTypes] unless cpcGrpCpcTypes.is_a? Array
|
133
|
+
group_keywords = []
|
134
|
+
cpcGrpCpcTypes.each do |cpcGrpCpcType|
|
135
|
+
group_keyword = {}
|
136
|
+
group_keyword[:group_id] = cpcGrpCpcType[:cpc_grp_id]
|
137
|
+
group_keyword[:keywords] = reverse_type( cpcGrpCpcType[:cpc_types] )
|
138
|
+
group_keywords << group_keyword
|
139
|
+
end
|
140
|
+
return group_keywords
|
141
|
+
end
|
142
|
+
|
143
|
+
# Override
|
144
|
+
def self.make_type( params, map = @map)
|
145
|
+
params = [ params ] unless params.is_a? Array
|
146
|
+
types = []
|
147
|
+
params.each do |param|
|
148
|
+
type = {}
|
149
|
+
map.each do |key|
|
150
|
+
# 增加对matchtype的自动转换
|
151
|
+
if key[0] == :match_type
|
152
|
+
value = param[ key[0] ]
|
153
|
+
type[ key[1] ] = Match_type[ value ] if value
|
154
|
+
else
|
155
|
+
value = param[ key[0] ]
|
156
|
+
type[ key[1] ] = value if value != nil
|
157
|
+
end
|
158
|
+
end
|
159
|
+
types << type
|
160
|
+
end
|
161
|
+
return types
|
162
|
+
end
|
163
|
+
|
164
|
+
# Overwrite
|
165
|
+
def self.reverse_type( types, map = @map )
|
166
|
+
types = [ types ] unless types.is_a? Array
|
167
|
+
params = []
|
168
|
+
types.each do |type|
|
169
|
+
param = {}
|
170
|
+
# 增加对matchtype的自动转换
|
171
|
+
map.each do |key|
|
172
|
+
if key[0] == :match_type
|
173
|
+
value = type[ key[1].to_s.snake_case.to_sym]
|
174
|
+
param[ key[0] ] = Match_type[ value ] if value
|
175
|
+
else
|
176
|
+
value = type[ key[1].to_s.snake_case.to_sym ]
|
177
|
+
param[ key[0] ] = value if value != nil
|
178
|
+
end
|
179
|
+
end # map.each
|
180
|
+
params << param
|
181
|
+
end # types.each
|
182
|
+
return params
|
183
|
+
end
|
184
|
+
|
185
|
+
end # keyword
|
186
|
+
end # Baidu
|
187
|
+
end # API
|
188
|
+
end # PPC
|