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,132 @@
1
+ # -*- coding:utf-8 -*-
2
+ module PPC
3
+ module API
4
+ class Sm
5
+ class Keyword < Sm
6
+ Service = 'keyword'
7
+
8
+ Match_type = { 'exact' => 0, 'phrase' => 1, 'wide' => 2, 0 => 'exact', 1 => 'phrase' , 2 => 'wide' }
9
+
10
+ @map = [
11
+ [:id, :keywordId],
12
+ [:group_id, :adgroupId],
13
+ [:keyword, :keyword],
14
+ [:price, :price],
15
+ [:mobile_destination, :destinationUrl],
16
+ [:match_type, :matchType],
17
+ [:status, :status],
18
+ [:pause, :pause]
19
+ ]
20
+
21
+ def self.get(auth, ids)
22
+ ids = [ids] unless ids.is_a? Array
23
+ body = {keywordIds: ids}
24
+ response = request(auth, Service, 'getKeywordByKeywordId', body)
25
+ return process(response, 'keywordTypes'){|x| reverse_type(x)}
26
+ end
27
+
28
+ def self.add(auth, keywords)
29
+ keyword_types = make_type(keywords)
30
+ body = {keywordTypes: keyword_types}
31
+ response = request(auth, Service, "addKeyword", body)
32
+ return process(response, 'keywordTypes'){|x| reverse_type(x)}
33
+ end
34
+
35
+ def self.update(auth, keywords)
36
+ keyword_types = make_type(keywords)
37
+ body = {keywordTypes: keyword_types}
38
+ response = request(auth, Service, "updateKeyword", body)
39
+ return process(response, 'keywordTypes'){|x| reverse_type(x)}
40
+ end
41
+
42
+ def self.delete(auth, ids)
43
+ ids = [ids] unless ids.is_a? Array
44
+ body = {keywordIds: ids}
45
+ response = request(auth, Service, 'deleteKeyword', body, 'delete')
46
+ return process(response, 'result'){|x| x }
47
+ end
48
+
49
+ def self.search_by_group_id(auth, group_ids)
50
+ group_ids = [group_ids] unless group_ids.is_a? Array
51
+ body = {adgroupIds: group_ids}
52
+ response = request(auth, Service, "getKeywordByAdgroupId", body)
53
+ return process(response, 'groupKeywords'){|x| make_groupKeywords(x)}
54
+ end
55
+
56
+ def self.search_id_by_group_id(auth, group_ids)
57
+ group_ids = [group_ids] unless group_ids.is_a? Array
58
+ body = {adgroupIds: group_ids}
59
+ response = request(auth, Service, "getKeywordIdByAdgroupId", body)
60
+ return process(response, 'groupKeywordIds'){|x| make_groupKeywordIds(x)}
61
+ end
62
+
63
+ private
64
+ def self.make_groupKeywordIds( groupKeywordIds )
65
+ group_keyword_ids = []
66
+ groupKeywordIds.each do |groupKeywordId|
67
+ group_keyword_id = { }
68
+ group_keyword_id[:group_id] = groupKeywordId['adgroupId']
69
+ group_keyword_id[:keyword_ids] = groupKeywordId['keywordIds']
70
+ group_keyword_ids << group_keyword_id
71
+ end
72
+ return group_keyword_ids
73
+ end
74
+
75
+ private
76
+ def self.make_groupKeywords( groupKeywords )
77
+ group_keywords = []
78
+ groupKeywords.each do |groupKeyword|
79
+ group_keyword = {}
80
+ group_keyword[:group_id] = groupKeyword['adgroupId']
81
+ group_keyword[:keywords] = reverse_type( groupKeyword['keywordTypes'] )
82
+ group_keywords << group_keyword
83
+ end
84
+ return group_keywords
85
+ end
86
+
87
+ # Override
88
+ def self.make_type( params, map = @map)
89
+ params = [ params ] unless params.is_a? Array
90
+ types = []
91
+ params.each do |param|
92
+ type = {}
93
+ map.each do |key|
94
+ # 增加对matchtype的自动转换
95
+ if key[0] == :match_type
96
+ value = param[ key[0] ]
97
+ type[ key[1] ] = Match_type[ value ] if value
98
+ else
99
+ value = param[ key[0] ]
100
+ type[ key[1] ] = value if value
101
+ end
102
+ end
103
+ types << type
104
+ end
105
+ return types
106
+ end
107
+
108
+ # Overwrite
109
+ def self.reverse_type( types, map = @map )
110
+ types = [ types ] unless types.is_a? Array
111
+ params = []
112
+ types.each do |type|
113
+ param = {}
114
+ # 增加对matchtype的自动转换
115
+ map.each do |key|
116
+ if key[0] == :match_type
117
+ value = type[ key[1].to_s ]
118
+ param[ key[0] ] = Match_type[ value ] if value
119
+ else
120
+ value = type[ key[1].to_s ]
121
+ param[ key[0] ] = value if value
122
+ end
123
+ end # map.each
124
+ params << param
125
+ end # types.each
126
+ return params
127
+ end
128
+
129
+ end # keyword
130
+ end # Sm
131
+ end # API
132
+ end # PPC
@@ -0,0 +1,51 @@
1
+ # -*- coding:utf-8 -*-
2
+ module PPC
3
+ module API
4
+ class Sm
5
+ class Phone < Sm
6
+ Service = 'NewCreative'
7
+
8
+ @map =[
9
+ [:id,:phoneId],
10
+ [:group_id,:adgroupId],
11
+ [:phone_num,:phoneNum],
12
+ [:pause,:pause],
13
+ ]
14
+
15
+ def self.update( auth, phones )
16
+ '''
17
+ 根据实际使用情况,更新的时候creative title为必填选
18
+ '''
19
+ body = { phoneTypes: make_type( phones ) }
20
+ response = request( auth, Service, 'updatePhone', body )
21
+ process( response, 'phoneTypes' ){ |x| reverse_type(x) }
22
+ end
23
+
24
+ def self.search_id_by_group_id( auth, ids, getTemp = 0 )
25
+ '''
26
+ \'getPhoneIdByAdgroupId\'
27
+ @ input: group ids
28
+ @ output: groupPhoneIds
29
+ '''
30
+ ids = [ ids ] unless ids.is_a? Array
31
+ body = { adgroupIds: ids, getTemp: getTemp }
32
+ response = request( auth, Service, 'getPhoneIdByAdgroupId', body )
33
+ process( response, 'groupPhoneIds' ){ |x| make_groupPhoneIds( x ) }
34
+ end
35
+
36
+ private
37
+ def self.make_groupPhoneIds( groupPhoneIds )
38
+ group_phone_ids = []
39
+ groupPhoneIds.each do |phone_id|
40
+ group_phone_id = { }
41
+ group_phone_id[:group_id] = phone_id['adgroupId']
42
+ group_phone_id[:phone_ids] = phone_id['phoneIds']
43
+ group_phone_ids << group_phone_id
44
+ end
45
+ return group_phone_ids
46
+ end
47
+
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,63 @@
1
+ module PPC
2
+ module API
3
+ class Sm
4
+ class Plan < Sm
5
+ Service = 'campaign'
6
+
7
+ @map = [
8
+ [:id,:campaignId],
9
+ [:name,:campaignName],
10
+ [:budget,:budget],
11
+ [:region,:regionTarget],
12
+ [:ip,:excludeIp] ,
13
+ [:negative,:negativeWords],
14
+ [:exact_negative,:exactNegativeWords],
15
+ [:schedule,:schedule],
16
+ [:budget_offline_time,:budgetOfflineTime],
17
+ [:show_prob,:showProb],
18
+ [:pause,:pause],
19
+ [:status,:status]
20
+ ]
21
+
22
+ def self.all( auth )
23
+ response = request( auth, Service, 'getAllCampaign' )
24
+ process( response, 'campaignTypes' ){ |x| reverse_type(x) }
25
+ end
26
+
27
+ def self.ids( auth )
28
+ response = request( auth, Service, 'getAllCampaignID' )
29
+ process( response, 'campaignIds' ){ |x| x }
30
+ end
31
+
32
+ def self.get( auth, ids )
33
+ ids = [ ids ] unless ids.is_a? Array
34
+ body = { campaignIds: ids }
35
+ response = request( auth, Service, 'getCampaignByCampaignId', body)
36
+ process( response, 'campaignTypes' ){ |x| reverse_type(x) }
37
+ end
38
+
39
+ def self.add( auth, plans )
40
+ campaign_types = make_type( plans )
41
+ body = { campaignTypes: campaign_types }
42
+ response = request( auth, Service, 'addCampaign', body)
43
+ process( response, 'campaignTypes' ){ |x| reverse_type(x) }
44
+ end
45
+
46
+ def self.update(auth,plans )
47
+ campaign_types = make_type( plans )
48
+ body = { campaignTypes: campaign_types }
49
+ response = request( auth, Service, 'updateCampaign', body)
50
+ process( response, 'campaignTypes' ){ |x| reverse_type(x) }
51
+ end
52
+
53
+ def self.delete(auth, ids )
54
+ ids = [ ids ] unless ids.is_a? Array
55
+ body = { campaignIds: ids }
56
+ response = request( auth, Service, 'deleteCampaign', body, "delete")
57
+ process( response, 'result' ){ |x| x }
58
+ end
59
+
60
+ end # Service
61
+ end # baidu
62
+ end # API
63
+ end # PPC
@@ -0,0 +1,136 @@
1
+ # -*- coding:utf-8 -*-
2
+ module PPC
3
+ module API
4
+ class Sm
5
+ class Report< Sm
6
+ Service = 'Report'
7
+
8
+ # 需要用到的映射集合
9
+ Type_map = { 'account' => 2, 'plan'=> 10, 'group'=> 11,
10
+ 'keyword'=> 14, 'creative'=> 12,
11
+ 'region'=> 3, 'query'=>6, 'trail' => 21, "tel" => 22,
12
+ "app" => 23, "none" => 24}
13
+
14
+ Level_map = { 'account' => 2, 'plan' => 3, 'group' => 5,
15
+ 'creative'=> 7, 'keywordid' => 11, 'trail' => 21, "tel" => 22,
16
+ "app" => 23, 'query_creative' => 12}
17
+
18
+ Device_map = { 'all' => 0, 'pc' => 1, 'mobile' => 2 }
19
+
20
+ Unit_map = { 'day' => 5, 'month' => 3, 'range' => 8 }
21
+
22
+ ########################
23
+ # API wraping function #
24
+ ########################
25
+ def self.get_id( auth, params )
26
+ body = make_reportrequest( params )
27
+ response = request( auth, 'report' , 'getReport' ,body)
28
+ process( response, 'taskId' ){ |x| x }
29
+ end
30
+
31
+ def self.get_state( auth, id )
32
+ '''
33
+ input id should be string
34
+ '''
35
+ body = { taskId: id }
36
+ response = request( auth, 'task' , 'getTaskState' ,body)
37
+ process( response, 'status' ){ |x| x }
38
+ end
39
+
40
+ def self.get_fileId( auth, id )
41
+ body = { taskId: id }
42
+ response = request( auth, 'task' , 'getTaskState' ,body)
43
+ process( response, 'fileId' ){ |x| x }
44
+ end
45
+
46
+ def self.get_file( auth, id )
47
+ body = { fileId: id }
48
+ response = request( auth, 'file' , 'download' ,body)
49
+ end
50
+
51
+ private
52
+ def self.make_reportrequest( param )
53
+ """
54
+ make RepoerRequestType
55
+ ==============
56
+ @Input : :fields,:type,:level,:range,:unit,:device,:id_only,:startDate:endDate
57
+ ==============
58
+ Note:
59
+ We cast [ type, level, range, unit,device ] from int to string.
60
+ For more information please see those map at the begining of the file
61
+ """
62
+ requesttype = {}
63
+ requesttype[:performanceData] = param[:fields] || %w(click impression cost cpc ctr)
64
+ requesttype[:reportType] = Type_map[ param[:type] ] if param[:type]
65
+ requesttype[:levelOfDetails] = Level_map[ param[:level] ] if param[:level]
66
+ requesttype[:statRange] = Level_map[ param[:range] ] if param[:range]
67
+ requesttype[:unitOfTime] = Unit_map[ param[:unit] ] if param[:unit]
68
+ requesttype[:device] = Device_map[ param[:device] ] if param[:device]
69
+ requesttype[:idOnly] = param[:id_only] || false
70
+ requesttype[:startDate] = parse_date( param[:startDate] )
71
+ requesttype[:endDate] = parse_date( param[:endDate] )
72
+ requesttype[:statIds] = param[:statIds] if param[:type] == "keyword" && param[:range] != "account"
73
+ return requesttype
74
+ end
75
+
76
+ private
77
+ def self.parse_date( date )
78
+ """
79
+ Cast string to time:
80
+ 'YYYYMMDD' => Time
81
+ """
82
+ if date
83
+ date = Date.parse(date)
84
+ else
85
+ date = Date.today
86
+ end
87
+ end
88
+
89
+ #################################
90
+ # useful function for operation #
91
+ #################################
92
+ def self.query_report( auth, param = {}, debug = false )
93
+ param[:type] ||= 'query'
94
+ param[:fields] ||= %w(click impression)
95
+ param[:range] ||= 'account'
96
+ param[:unit] ||= 'day'
97
+ download_report( auth, param, debug )
98
+ end
99
+
100
+ def self.creative_report( auth, param = {}, debug = false )
101
+ param[:type] ||= 'creative'
102
+ param[:fields] ||= %w(click impression)
103
+ param[:range] ||= 'account'
104
+ param[:unit] ||= 'day'
105
+ download_report( auth, param, debug )
106
+ end
107
+
108
+ def self.keyword_report( auth, param = {}, debug = false )
109
+ param[:type] ||= 'keyword'
110
+ param[:fields] ||= %w(click impression cost cpc ctr)
111
+ param[:range] ||= 'account'
112
+ param[:unit] ||= 'day'
113
+ download_report( auth, param, debug )
114
+ end
115
+
116
+ def self.download_report( auth, param, debug = false )
117
+ response = get_id( auth, param )
118
+ if response[:succ]
119
+ id = response[:result]
120
+ p "Got report id:" + id.to_s if debug
121
+ loop do
122
+ sleep 2
123
+ break if get_state( auth, id )[:result] == 'FINISHED'
124
+ p "Report is not generated, waiting..." if debug
125
+ end
126
+ fileId = get_fileId(auth, id)[:result]
127
+ return get_file(auth, fileId).force_encoding("utf-8")
128
+ else
129
+ raise response[:failure][0]["message"]
130
+ end
131
+ end
132
+
133
+ end # Repost
134
+ end # Sm
135
+ end # API
136
+ end # PPC
@@ -0,0 +1,118 @@
1
+ require 'ppc/api/sogou/account'
2
+ require 'ppc/api/sogou/plan'
3
+ require 'ppc/api/sogou/group'
4
+ require 'ppc/api/sogou/keyword'
5
+ require 'ppc/api/sogou/report'
6
+ require 'ppc/api/sogou/creative'
7
+ require 'ppc/api/sogou/bulk'
8
+
9
+ module PPC
10
+ module API
11
+ class Sogou
12
+
13
+ extend ::PPC::API
14
+
15
+ def self.request( auth, service, method, params = {})
16
+ '''
17
+ ps. in savon3, .hash method will turn CamelXML to snake hash
18
+ preprocess response, extract
19
+ '''
20
+
21
+ service = service + "Service"
22
+ client = Savon.new( "http://api.agent.sogou.com:8080/sem/sms/v1/#{service}?wsdl" )
23
+ operation = client.operation( service, service, method )
24
+
25
+ operation.header = {
26
+ AuthHeader:{
27
+ username: auth[:username],
28
+ password: auth[:password],
29
+ token: auth[:token]
30
+ }
31
+ }
32
+ operation.body = { (method+'Request').to_sym => params }
33
+ # debug print
34
+ debug_print( operation ) if @debug
35
+ result = operation.call.hash[:envelope]
36
+ #extract header and body
37
+ response = { }
38
+ response[:header] = result[:header][:res_header]
39
+ response[:body] = result[:body][ (method + "Response").snake_case.to_sym ]
40
+ # debug print
41
+ puts response if @debug
42
+ return response
43
+ end
44
+
45
+ def self.debug_print( operation )
46
+ puts '{:header=>' + operation.header.to_s + ', :body=>' + operation.body.to_s + '}'
47
+ end
48
+
49
+ def self.process( response, key, &func )
50
+ '''
51
+ @input
52
+ : type key : string
53
+ : param key : type name, we will transfer camel string
54
+ into snake_case symbol inside the method
55
+ '''
56
+ result = {}
57
+ result[:succ] = response[:header][:desc]=='success'? true : false
58
+ result[:failure] = response[:header][:failures]
59
+ result[:no_quota] = is_no_quota(response[:header][:failures], '18')
60
+ unless response[:body].nil? or response[:body][key.snake_case.to_sym].nil?
61
+ result[:result] = func[ response[:body][ key.snake_case.to_sym ] ]
62
+ end
63
+ return result
64
+ end
65
+
66
+ # def self.make_type( params, map = @map)
67
+ # '''
68
+ # For more info visit ::PPC::API::sogou:make_type
69
+ # '''
70
+ # params = [ params ] unless params.is_a? Array
71
+ #
72
+ # types = []
73
+ # params.each do |param|
74
+ # type = {}
75
+ #
76
+ # map.each do |key|
77
+ # value = param[ key[0] ]
78
+ # type[ key[1] ] = value if value != nil
79
+ # end
80
+ #
81
+ # types << type
82
+ # end
83
+ # return types
84
+ # end
85
+ def self.reverse_type( types, maps = @map )
86
+ types = [ types ] unless types.is_a? Array
87
+ types.map do |item|
88
+ maps.each{|m| item.filter_and_replace_key(m[0],m[1].to_s.snake_case.to_sym)}
89
+ item
90
+ end
91
+ end
92
+
93
+ # def self.reverse_type( types, map = @map )
94
+ # '''
95
+ # For more info visit ::PPC::API::sogou:reverse_type
96
+ # Here, the camel key will be turn into snake key
97
+ # '''
98
+ # types = [ types ] unless types.is_a? Array
99
+ #
100
+ # params = []
101
+ # types.each do |type|
102
+ # param = {}
103
+ #
104
+ # map.each do |key|
105
+ # # 这里做两次转换并不是十分高效的方法,考虑maintain两张map
106
+ # value = type[ key[1].to_s.snake_case.to_sym ]
107
+ # param[ key[0] ] = value if value != nil
108
+ # end
109
+
110
+ # params << param
111
+ # end
112
+ # return params
113
+ # end
114
+
115
+ end
116
+ end
117
+ end
118
+