ppc 1.3.0 → 1.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -1
  3. data/LICENSE +334 -17
  4. data/README.md +75 -3
  5. data/lib/ppc.rb +3 -1
  6. data/lib/ppc/api.rb +137 -2
  7. data/lib/ppc/api/baidu.rb +20 -99
  8. data/lib/ppc/api/baidu/account.rb +21 -21
  9. data/lib/ppc/api/baidu/bulk.rb +39 -3
  10. data/lib/ppc/api/baidu/creative.rb +33 -33
  11. data/lib/ppc/api/baidu/group.rb +14 -14
  12. data/lib/ppc/api/baidu/keyword.rb +57 -46
  13. data/lib/ppc/api/baidu/phone_new_creative.rb +51 -0
  14. data/lib/ppc/api/baidu/plan.rb +34 -31
  15. data/lib/ppc/api/baidu/rank.rb +23 -0
  16. data/lib/ppc/api/baidu/report.rb +100 -81
  17. data/lib/ppc/api/qihu.rb +150 -0
  18. data/lib/ppc/api/qihu/account.rb +86 -0
  19. data/lib/ppc/api/qihu/bulk.rb +35 -0
  20. data/lib/ppc/api/qihu/creative.rb +108 -0
  21. data/lib/ppc/api/qihu/group.rb +96 -0
  22. data/lib/ppc/api/qihu/keyword.rb +113 -0
  23. data/lib/ppc/api/qihu/plan.rb +64 -0
  24. data/lib/ppc/api/qihu/rank.rb +25 -0
  25. data/lib/ppc/api/qihu/report.rb +159 -0
  26. data/lib/ppc/api/qihu/sublink.rb +71 -0
  27. data/lib/ppc/api/shenma.rb +64 -0
  28. data/lib/ppc/api/shenma/report.rb +135 -0
  29. data/lib/ppc/api/sm.rb +50 -0
  30. data/lib/ppc/api/sm/account.rb +44 -0
  31. data/lib/ppc/api/sm/bulk.rb +69 -0
  32. data/lib/ppc/api/sm/creative.rb +86 -0
  33. data/lib/ppc/api/sm/group.rb +94 -0
  34. data/lib/ppc/api/sm/keyword.rb +132 -0
  35. data/lib/ppc/api/sm/phone_new_creative.rb +51 -0
  36. data/lib/ppc/api/sm/plan.rb +63 -0
  37. data/lib/ppc/api/sm/report.rb +136 -0
  38. data/lib/ppc/api/sogou.rb +118 -0
  39. data/lib/ppc/api/sogou/account.rb +42 -0
  40. data/lib/ppc/api/sogou/bulk.rb +69 -0
  41. data/lib/ppc/api/sogou/creative.rb +117 -0
  42. data/lib/ppc/api/sogou/group.rb +123 -0
  43. data/lib/ppc/api/sogou/keyword.rb +188 -0
  44. data/lib/ppc/api/sogou/plan.rb +66 -0
  45. data/lib/ppc/api/sogou/report.rb +129 -0
  46. data/lib/ppc/ext.rb +17 -0
  47. data/lib/ppc/operation.rb +50 -36
  48. data/lib/ppc/operation/account.rb +19 -7
  49. data/lib/ppc/operation/creative.rb +7 -7
  50. data/lib/ppc/operation/group.rb +2 -2
  51. data/lib/ppc/operation/keyword.rb +11 -8
  52. data/lib/ppc/operation/report.rb +23 -0
  53. data/ppc.gemspec +14 -4
  54. data/spec/baidu/api_baidu_account_spec.rb +16 -0
  55. data/spec/baidu/api_baidu_creative_spec.rb +73 -0
  56. data/spec/{api_baidu_group_spec.rb → baidu/api_baidu_group_spec.rb} +12 -17
  57. data/spec/baidu/api_baidu_keyword_spec.rb +61 -0
  58. data/spec/baidu/api_baidu_phone_spec.rb +22 -0
  59. data/spec/{api_baidu_plan_spec.rb → baidu/api_baidu_plan_spec.rb} +11 -10
  60. data/spec/baidu/api_baidu_report_spec.rb +44 -0
  61. data/spec/{api_baidu_spec.rb → baidu/api_baidu_spec.rb} +10 -15
  62. data/spec/operation/operation_baidu_report_spec.rb +17 -0
  63. data/spec/operation/operation_baidu_spec.rb +126 -0
  64. data/spec/operation/operation_qihu_report_spec.rb +18 -0
  65. data/spec/operation/operation_qihu_spec.rb +94 -0
  66. data/spec/operation/operation_sm_report_spec.rb +21 -0
  67. data/spec/operation/operation_sogou_report_spec.rb +17 -0
  68. data/spec/operation/operation_sogou_spec.rb +88 -0
  69. data/spec/{operation_spec_helper.rb → operation/operation_spec_helper.rb} +3 -5
  70. data/spec/qihu/api_qihu_account_spec.rb +29 -0
  71. data/spec/qihu/api_qihu_creative_spec.rb +48 -0
  72. data/spec/qihu/api_qihu_group_spec.rb +40 -0
  73. data/spec/qihu/api_qihu_keyword_spec.rb +50 -0
  74. data/spec/qihu/api_qihu_plan_spec.rb +39 -0
  75. data/spec/qihu/api_qihu_report_spec.rb +54 -0
  76. data/spec/qihu/api_qihu_sublink_spec.rb +36 -0
  77. data/spec/sm/api_sm_account_spec.rb +8 -0
  78. data/spec/sm/api_sm_creative_spec.rb +52 -0
  79. data/spec/sm/api_sm_group_spec.rb +75 -0
  80. data/spec/sm/api_sm_keyword_spec.rb +59 -0
  81. data/spec/sm/api_sm_plan_spec.rb +39 -0
  82. data/spec/sm/api_sm_report_spec.rb +30 -0
  83. data/spec/sogou/api_sogou_account_spec.rb +17 -0
  84. data/spec/sogou/api_sogou_creative_spec.rb +51 -0
  85. data/spec/sogou/api_sogou_group_spec.rb +50 -0
  86. data/spec/sogou/api_sogou_keyword_spec.rb +54 -0
  87. data/spec/sogou/api_sogou_plan_spec.rb +43 -0
  88. data/spec/sogou/api_sogou_report_spec.rb +51 -0
  89. data/spec/spec_helper.rb +49 -10
  90. metadata +140 -46
  91. data/lib/ppc/baidu.rb +0 -152
  92. data/lib/ppc/baidu/account.rb +0 -88
  93. data/lib/ppc/baidu/bulk.rb +0 -52
  94. data/lib/ppc/baidu/group.rb +0 -99
  95. data/lib/ppc/baidu/key.rb +0 -38
  96. data/lib/ppc/baidu/plan.rb +0 -85
  97. data/lib/ppc/baidu/report.rb +0 -82
  98. data/spec/api_baidu_account_spec.rb +0 -18
  99. data/spec/api_baidu_creative_spec.rb +0 -71
  100. data/spec/api_baidu_keyword_spec.rb +0 -64
  101. data/spec/api_baidu_report_spec.rb +0 -32
  102. data/spec/baidu_account_spec.rb +0 -32
  103. data/spec/baidu_bulk_spec.rb +0 -21
  104. data/spec/baidu_group_spec.rb +0 -56
  105. data/spec/baidu_plan_spec.rb +0 -129
  106. data/spec/baidu_report_spec.rb +0 -24
  107. 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