ppc 1.3.0 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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