ppc 1.0.6 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +31 -23
  3. data/LICENSE +22 -0
  4. data/README.md +5 -28
  5. data/lib/ppc/api/baidu/account.rb +47 -0
  6. data/lib/ppc/api/baidu/bulk.rb +41 -0
  7. data/lib/ppc/api/baidu/creative.rb +125 -0
  8. data/lib/ppc/api/baidu/group.rb +111 -0
  9. data/lib/ppc/api/baidu/keyword.rb +193 -0
  10. data/lib/ppc/api/baidu/plan.rb +65 -0
  11. data/lib/ppc/api/baidu/report.rb +124 -0
  12. data/lib/ppc/api/baidu.rb +132 -0
  13. data/lib/ppc/api.rb +8 -0
  14. data/lib/ppc/baidu/account.rb +55 -27
  15. data/lib/ppc/baidu/group.rb +99 -0
  16. data/lib/ppc/baidu/key.rb +38 -0
  17. data/lib/ppc/baidu/plan.rb +69 -0
  18. data/lib/ppc/baidu/report.rb +45 -13
  19. data/lib/ppc/baidu.rb +28 -25
  20. data/lib/ppc/operation/account.rb +40 -0
  21. data/lib/ppc/operation/creative.rb +28 -0
  22. data/lib/ppc/operation/group.rb +59 -0
  23. data/lib/ppc/operation/keyword.rb +32 -0
  24. data/lib/ppc/operation/plan.rb +47 -0
  25. data/lib/ppc/operation.rb +161 -0
  26. data/lib/ppc.rb +3 -7
  27. data/ppc.gemspec +4 -4
  28. data/spec/api_baidu_account_spec.rb +18 -0
  29. data/spec/api_baidu_creative_spec.rb +71 -0
  30. data/spec/api_baidu_group_spec.rb +50 -0
  31. data/spec/api_baidu_keyword_spec.rb +64 -0
  32. data/spec/api_baidu_plan_spec.rb +42 -0
  33. data/spec/api_baidu_report_spec.rb +32 -0
  34. data/spec/api_baidu_spec.rb +60 -0
  35. data/spec/baidu_account_spec.rb +32 -0
  36. data/spec/baidu_bulk_spec.rb +21 -0
  37. data/spec/baidu_group_spec.rb +56 -0
  38. data/spec/baidu_plan_spec.rb +129 -0
  39. data/spec/{report_spec.rb → baidu_report_spec.rb} +0 -0
  40. data/spec/operation_spec.rb +87 -0
  41. data/spec/operation_spec_helper.rb +53 -0
  42. data/spec/spec_helper.rb +18 -1
  43. metadata +53 -22
  44. data/Gemfile +0 -4
  45. data/LICENSE.txt +0 -22
  46. data/Rakefile +0 -2
  47. data/lib/ppc/qihu/account.rb +0 -0
  48. data/lib/ppc/qihu.rb +0 -0
  49. data/lib/ppc/sogou/bulk.rb +0 -48
  50. data/lib/ppc/sogou.rb +0 -125
  51. data/spec/account_spec.rb +0 -16
  52. data/spec/bulk_spec.rb +0 -35
  53. data/spec/plan_spec.rb +0 -17
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ef00fb5a5d3113cf2ae07e909ed79dedd8923722
4
- data.tar.gz: 4cf8d77c5e0107f635f5248c8a73e04449b01ca5
3
+ metadata.gz: 66b985632890e757ec89f2c6900764a37f83338e
4
+ data.tar.gz: dc4a8c7f6e28d9786e8ee89c05673c4abff0cb3d
5
5
  SHA512:
6
- metadata.gz: c1b4cf5437ed71cfe043a63b2473d229b89020d56c2ca2c341d880a6707fa5812927a9a3a08c9675b5963d59cd8bed3032b1b2df138a71bb567fd6300b05eb61
7
- data.tar.gz: 141eb3bb4df485429a22e5e707cf65bbcc51f7ba3ea4919e233a8c235cb8fe337dfd27708cbf0293cedcf6b51885de7e7a67d3d23560716d2a2a296312f9b297
6
+ metadata.gz: 865cf3580b0a1714812b9d106ea2e17027a82efecbd42b92beb04ba55104166f89614544fcdb5ac4550b0599aba12166910e6a1978d008831e0708e285c2254e
7
+ data.tar.gz: bbd5984fb1247f4bb37e340d6d2b86397a4f713b7cf33ecaee6834fc95799f8f7b8b43c36dbf5ab52de0cb3952b70c7bd5a9760c21cae0cdff12e37d6ea13074
data/.gitignore CHANGED
@@ -1,28 +1,36 @@
1
1
  *.gem
2
2
  *.rbc
3
- .bundle
4
- .config
5
- .yardoc
6
- Gemfile.lock
7
- InstalledFiles
8
- _yardoc
9
- coverage
10
- doc/
11
- lib/bundler/man
12
- pkg
13
- rdoc
14
- spec/reports
15
- test/tmp
16
- test/version_tmp
17
- tmp
18
- *.bundle
19
- *.so
20
- *.o
21
- *.a
22
- mkmf.log
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /test/tmp/
9
+ /test/version_tmp/
10
+ /tmp/
23
11
 
24
- .DS_Store
12
+ ## Specific to RubyMotion:
13
+ .dat*
14
+ .repl_history
15
+ build/
16
+
17
+ ## Documentation cache and generated files:
18
+ /.yardoc/
19
+ /_yardoc/
20
+ /doc/
21
+ /rdoc/
22
+
23
+ ## Environment normalisation:
24
+ /.bundle/
25
+ /lib/bundler/man/
26
+
27
+ # for a library or gem, you might want to ignore these files since the code is
28
+ # intended to run in multiple environments; otherwise, check them in:
29
+ # Gemfile.lock
30
+ # .ruby-version
31
+ # .ruby-gemset
32
+
33
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
34
+ .rvmrc
25
35
 
26
- .tags
27
36
 
28
- .tags_sorted_by_file
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 seoaqua
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
data/README.md CHANGED
@@ -1,29 +1,6 @@
1
- # Ppc
1
+ ppc
2
+ ===
2
3
 
3
- TODO: Write a gem description
4
-
5
- ## Installation
6
-
7
- Add this line to your application's Gemfile:
8
-
9
- gem 'ppc'
10
-
11
- And then execute:
12
-
13
- $ bundle
14
-
15
- Or install it yourself as:
16
-
17
- $ gem install ppc
18
-
19
- ## Usage
20
-
21
- TODO: Write usage instructions here
22
-
23
- ## Contributing
24
-
25
- 1. Fork it ( https://github.com/[my-github-username]/ppc/fork )
26
- 2. Create your feature branch (`git checkout -b my-new-feature`)
27
- 3. Commit your changes (`git commit -am 'Add some feature'`)
28
- 4. Push to the branch (`git push origin my-new-feature`)
29
- 5. Create a new Pull Request
4
+ ppc for 'pay per click'.
5
+ #####This is a toolkit designed to provide consistent search engine account managing experience.
6
+ #####For more information please checkout oop branch
@@ -0,0 +1,47 @@
1
+ module PPC
2
+ module API
3
+ class Baidu
4
+ class Account< Baidu
5
+ Service = 'Account'
6
+
7
+ @map = [
8
+ [:id,:userid],
9
+ [:balance,:balance],
10
+ [:cost,:cost],
11
+ [:payment,:payment],
12
+ [:status,:userStat],
13
+ [:budget_type,:budgetType],
14
+ [:budget,:budget],
15
+ [:region,:regionTarget],
16
+ [:exclude_ip,:excludeIp],
17
+ [:isdynamic,:isDynamicCreative],
18
+ [:dynamic_param,:dynamicCreativeParam],
19
+ [:open_domains,:openDomains],
20
+ [:reg_domain,:regDomain],
21
+ [:offline_time,:budgetOfflineTime],
22
+ [:weekly_budget,:weeklyBudget],
23
+ [:opt,:opt]
24
+ ]
25
+
26
+ def self.info(auth, debug = false)
27
+ response = request(auth,Service,'getAccountInfo' )
28
+ return process( response, 'accountInfoType', debug ){ |x|reverse_type(x) }
29
+ end
30
+
31
+ def self.update(auth, param = {}, debug = false)
32
+ """
33
+ update account info
34
+ @ params : account_info_type
35
+ @return : account info_type
36
+ """
37
+ # for account service, there is not bulk operation
38
+ infoType = make_type( param )[0]
39
+ body = { accountInfoType: infoType }
40
+ response = request(auth,Service,'updateAccountInfo', body)
41
+ return process( response, 'accountInfoType', debug ){ |x|reverse_type(x) }
42
+ end
43
+
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,41 @@
1
+ module PPC
2
+ module API
3
+ class Baidu
4
+ class Bulk < Baidu
5
+ Service = 'BulkJob'
6
+
7
+ def self.get_all_object( auth,params = {})
8
+
9
+ plan_ids = params[:plan_ids]
10
+
11
+ unless plan_ids.nil?
12
+ plan_ids = plan_ids.class == Array ? plan_ids : [plan_ids]
13
+ end
14
+
15
+ options = {
16
+ campaignIds: plan_ids || [] ,
17
+ includeQuality: params[:quality] || true ,
18
+ includeTemp: params[:temp] || false ,
19
+ format: params[:format] || 1 ,
20
+ newCreativeFiles: params[:adcopy] || 0 ,
21
+ includeTempNewCreatives: params[:temp_adcopy] || 0 ,
22
+ includePhraseType: params[:phrase] || 0 ,
23
+ extended: params[:extended] || 0
24
+ }
25
+ response = request( auth, Service, 'getAllObjects',options )
26
+ response[:get_all_objects_response][:file_id]
27
+ end
28
+
29
+ def self.state( auth, id)
30
+ raise "empty id" if id.nil? or id.empty?
31
+ request(auth, Service, 'getFileState',{fileId:id})[:get_file_state_response][:is_generated]
32
+ end
33
+
34
+ def self.path( auth, id)
35
+ request( auth, Service, 'getFilePath',{fileId:id})[:get_file_path_response][:file_paths]
36
+ end
37
+
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,125 @@
1
+ # -*- coding:utf-8 -*-
2
+ module PPC
3
+ module API
4
+ class Baidu
5
+ class Creative< Baidu
6
+ Service = 'Creative'
7
+
8
+ @map =[
9
+ [:id,:creativeId],
10
+ [:group_id,:adgroupId],
11
+ [:title,:title],
12
+ [:description1,:description1],
13
+ [:description2,:description2],
14
+ [:pc_destination,:pcDestinationUrl],
15
+ [:pc_display,:pcDisplayUrl],
16
+ [:moile_destination,:mobileDestinationUrl],
17
+ [:mobile_display,:mobileDisplayUrl],
18
+ [:pause,:pause],
19
+ [:preference,:devicePreference]
20
+ ]
21
+
22
+ def self.add( auth, creatives, debug = false )
23
+ body = { creativeTypes: make_type( creatives ) }
24
+ response = request( auth, Service, 'addCreative', body )
25
+ process( response, 'creativeTypes', debug ){ |x| reverse_type(x) }
26
+ end
27
+
28
+ def self.get( auth, ids, getTemp = 0, debug = false )
29
+ '''
30
+ \'getCreativeByCreativeId\'
31
+ @ input : creative ids
32
+ @ output: creative informations
33
+ '''
34
+ ids = [ ids ] unless ids.is_a? Array
35
+ body = { creativeIds: ids, getTemp: getTemp }
36
+ response = request( auth, Service, 'getCreativeByCreativeId', body )
37
+ process( response, 'creativeTypes', debug ){ |x| reverse_type(x) }
38
+ end
39
+
40
+ def self.update( auth, creatives, debug = false )
41
+ '''
42
+ 根据实际使用情况,更新的时候creative title为必填选
43
+ '''
44
+ body = { creativeTypes: make_type( creatives ) }
45
+ response = request( auth, Service, 'addCreative', body )
46
+ process( response, 'creativeTypes', debug ){ |x| reverse_type(x) }
47
+ end
48
+
49
+ def self.delete( auth, ids, debug = false )
50
+ ids = [ ids ] unless ids.is_a? Array
51
+ body = { creativeIds: ids }
52
+ response = request( auth, Service, 'deleteCreative', body )
53
+ process( response, 'result', debug ){ |x| x }
54
+ end
55
+
56
+ def self.activate( auth, ids, debug = false )
57
+ ids = [ ids ] unless ids.is_a? Array
58
+ body = { creativeIds: ids }
59
+ response = request( auth, Service, 'activateCreative', body )
60
+ process( response, 'creativeTypes', debug ){ |x| reverse_type(x) }
61
+ end
62
+
63
+ def self.status( auth, ids, type, debug = false )
64
+ ids = [ ids ] unless ids.is_a? Array
65
+
66
+ type = case type
67
+ when 'plan' then 3
68
+ when 'group' then 5
69
+ when 'creative' then 7
70
+ else
71
+ Exception.new( 'type must among: \'plan\',\'group\' and \'key\' ')
72
+ end
73
+
74
+ body = { ids: ids, type: type }
75
+ response = request( auth, Service, 'getCreativeStatus', body )
76
+ process( response, 'CreativeStatus', debug ){ |x| x }
77
+ end
78
+
79
+ def self.search_id_by_group_id( auth, ids, getTemp = 0, debug = false )
80
+ '''
81
+ \'getCreativeIdByAdgroupId\'
82
+ @ input: group ids
83
+ @ output: groupCreativeIds
84
+ '''
85
+ ids = [ ids ] unless ids.is_a? Array
86
+ body = { adgroupIds: ids, getTemp: getTemp }
87
+ response = request( auth, Service, 'getCreativeIdByAdgroupId', body )
88
+ process( response, 'groupCreativeIds', debug ){ |x| make_groupCreativeIds( x ) }
89
+ end
90
+
91
+ def self.search_by_group_id( auth, ids, getTemp = 0, debug = false )
92
+ ids = [ ids ] unless ids.is_a? Array
93
+ body = { adgroupIds: ids, getTemp: getTemp }
94
+ response = request( auth, Service, 'getCreativeByAdgroupId', body )
95
+ process( response, 'groupCreatives', debug ){ |x| make_groupCreatives( x ) }
96
+ end
97
+
98
+ private
99
+ def self.make_groupCreativeIds( groupCreativeIds )
100
+ group_creative_ids = []
101
+ groupCreativeIds.each do |groupCreativeId|
102
+ group_creative_id = { }
103
+ group_creative_id[:group_id] = groupCreativeId['adgroupIds']
104
+ group_creative_id[:creative_ids] = groupCreativeId['creativeIds']
105
+ group_creative_ids << group_creative_id
106
+ end
107
+ return group_creative_ids
108
+ end
109
+
110
+ private
111
+ def self.make_groupCreatives( groupCreatives )
112
+ group_creatives = []
113
+ groupCreative.each do |groupKeyword|
114
+ group_creative = {}
115
+ group_creative[:group_id] = groupCreative['adgroupId']
116
+ group_creative[:keywords] = reverse_type( groupCreative['keywordTypes'] )
117
+ group_creatives << group_creative
118
+ end
119
+ return group_creatives
120
+ end
121
+
122
+ end
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,111 @@
1
+ # -*- coding:utf-8 -*-
2
+ module PPC
3
+ module API
4
+ class Baidu
5
+ class Group< Baidu
6
+ Service = 'Adgroup'
7
+
8
+ @map =[
9
+ [:plan_id, :campaignId],
10
+ [:id, :adgroupId],
11
+ [:name, :adgroupName],
12
+ [:price, :maxPrice],
13
+ [:negative, :negativeWords],
14
+ [:exact_negative, :exactNegativeWords],
15
+ [:pause, :pause],
16
+ [:status, :status],
17
+ [:reserved, :reserved]
18
+ ]
19
+
20
+ def self.ids(auth, debug = false )
21
+ """
22
+ @return : Array of campaignAdgroupIds
23
+ """
24
+ response = request( auth, Service , "getAllAdgroupId" )
25
+ process( response, 'campaignAdgroupIds', debug ){ |x| make_planGroupIds( x ) }
26
+ end
27
+
28
+ def self.get( auth, ids, debug = false )
29
+ ids = [ ids ] unless ids.is_a? Array
30
+ body = { adgroupIds: ids }
31
+ response = request(auth, Service, "getAdgroupByAdgroupId",body )
32
+ process( response, 'adgroupTypes', debug ){ |x| reverse_type(x) }
33
+ end
34
+
35
+ def self.add( auth, groups, debug = false )
36
+ """
37
+ @ input : one or list of AdgroupType
38
+ @ output : list of AdgroupType
39
+ """
40
+ adgrouptypes = make_type( groups )
41
+
42
+ body = {adgroupTypes: adgrouptypes }
43
+
44
+ response = request( auth, Service, "addAdgroup", body )
45
+ process( response, 'adgroupTypes', debug ){ |x| reverse_type(x) }
46
+ end
47
+
48
+ def self.update( auth, groups, debug = false )
49
+ """
50
+ @ input : one or list of AdgroupType
51
+ @ output : list of AdgroupType
52
+ """
53
+ adgrouptypes = make_type( groups )
54
+ body = {adgroupTypes: adgrouptypes}
55
+
56
+ response = request( auth, Service, "updateAdgroup",body )
57
+ process( response, 'adgroupTypes', debug ){ |x| reverse_type(x) }
58
+ end
59
+
60
+ def self.delete( auth, ids, debug = false )
61
+ """
62
+ delete group body has no message
63
+ """
64
+ ids = [ ids ] unless ids.is_a? Array
65
+ body = { adgroupIds: ids }
66
+ response = request( auth, Service,"deleteAdgroup", body )
67
+ process( response, 'nil', debug ){ |x| x }
68
+ end
69
+
70
+ def self.search_by_plan_id( auth, ids, debug = false )
71
+ ids = [ ids ] unless ids.class == Array
72
+ body = { campaignIds: ids }
73
+ response = request( auth, Service ,"getAdgroupByCampaignId", body )
74
+ process( response, 'campaignAdgroups', debug ){ |x| make_planGroups( x ) }
75
+ end
76
+
77
+ def self.search_id_by_plan_id( auth, ids, debug = false )
78
+ ids = [ ids ] unless ids.class == Array
79
+ body = { campaignIds: ids }
80
+ response = request( auth, Service ,"getAdgroupIdByCampaignId", body )
81
+ process( response, 'campaignAdgroupIds', debug ){ |x| make_planGroupIds( x ) }
82
+ end
83
+
84
+ private
85
+ def self.make_planGroupIds( campaignAdgroupIds )
86
+ planGroupIds = []
87
+ campaignAdgroupIds.each do |campaignAdgroupId|
88
+ planGroupId = { }
89
+ planGroupId[:plan_id] = campaignAdgroupId['campaignId']
90
+ planGroupId[:group_ids] = campaignAdgroupId['adgroupIds']
91
+ planGroupIds << planGroupId
92
+ end
93
+ return planGroupIds
94
+ end
95
+
96
+ private
97
+ def self.make_planGroups( campaignAdgroups )
98
+ planGroups = []
99
+ campaignAdgroups.each do |campaignAdgroup|
100
+ planGroup = {}
101
+ planGroup[:plan_id] = campaignAdgroup['campaignId']
102
+ planGroup[:groups] = reverse_type( campaignAdgroup['adgroupTypes'] )
103
+ planGroups << planGroup
104
+ end
105
+ return planGroups
106
+ end
107
+
108
+ end # class group
109
+ end # class baidu
110
+ end # API
111
+ end # module
@@ -0,0 +1,193 @@
1
+ # -*- coding:utf-8 -*-
2
+ module PPC
3
+ module API
4
+ class Baidu
5
+ class Keyword< Baidu
6
+ Service = 'Keyword'
7
+
8
+ Match_type = { 'exact' => 1, 'pharse' => 2, 'wide' => 3 }
9
+ Match_type_r = { 1 => 'exact', 2=> 'pharse' , 3 => 'wide' }
10
+
11
+ Device = { 'pc' => 0, 'mobile' => 1, 'all' => 2 }
12
+ Type = { 'plan' => 3, 'group' => 5, 'keyword' => 11 }
13
+
14
+ @map = [
15
+ [:id,:keywordId],
16
+ [:group_id,:adgroupId],
17
+ [:keyword,:keyword],
18
+ [:price,:price],
19
+ [:pc_destination,:pcDestinationUrl],
20
+ [:mobile_destination,:mobileDestinationUrl],
21
+ [:match_type,:matchType],
22
+ [:phrase_type,:phraseType]
23
+ ]
24
+
25
+ @quality10_map = [
26
+ [ :id, :id ],
27
+ [ :group_id, :adgroupId ],
28
+ [ :plan_id, :Campaigned ],
29
+ [ :pc_quality, :pcQuality ],
30
+ [ :pc_reliable, :pcReliable ],
31
+ [ :pc_reason, :pcReason ],
32
+ [ :pc_scale, :pcScale ],
33
+ [ :mobile_quality, :mobileQuality ],
34
+ [ :mobile_reliable, :mobileReliable ],
35
+ [ :mobile_reason, :mobileReason ],
36
+ [ :mobile_scale, :mobileScale ]
37
+ ]
38
+
39
+ # 后面改成info方法
40
+ def self.get( auth, ids, debug = false )
41
+ '''
42
+ getKeywordByKeywordId
43
+ '''
44
+ ids = [ ids ] unless ids.is_a? Array
45
+ body = { keywordIds: ids}
46
+ response = request( auth, Service, 'getKeywordByKeywordId', body )
47
+ return process(response, 'keywordTypes', debug){|x| reverse_type( x ) }
48
+ end
49
+
50
+ def self.add( auth, keywords, debug = false )
51
+ '''
52
+ '''
53
+ keywordtypes = make_type( keywords )
54
+ body = { keywordTypes: keywordtypes }
55
+ response = request( auth, Service, "addKeyword", body )
56
+ return process(response, 'keywordTypes', debug){|x| reverse_type(x) }
57
+ end
58
+
59
+ def self.update( auth, keywords, debug = false )
60
+ '''
61
+ '''
62
+ keywordtypes = make_type( keywords )
63
+ body = { keywordTypes: keywordtypes }
64
+ response = request( auth, Service, "updateKeyword", body )
65
+ return process(response, 'keywordTypes', debug){|x| reverse_type(x) }
66
+ end
67
+
68
+ def self.delete( auth, ids, debug = false )
69
+ """
70
+ """
71
+ ids = [ ids ] unless ids.is_a? Array
72
+ body = { keywordIds: ids}
73
+ response = request( auth, Service, 'deleteKeyword', body )
74
+ return process(response, 'result', debug){|x| x }
75
+ end
76
+
77
+ def self.activate( auth, ids, debug =false )
78
+ """
79
+ """
80
+ ids = [ ids ] unless ids.is_a? Array
81
+ body = { keywordIds: ids }
82
+ response = request( auth, Service, 'activateKeyword', body)
83
+ return process(response, 'keywordTypes', debug){|x| reverse_type(x) }
84
+ end
85
+
86
+ def self.search_by_group_id( auth, group_ids, debug = false )
87
+ """
88
+ getKeywordByGroupIds
89
+ @input: list of group id
90
+ @output: list of groupKeyword
91
+ """
92
+ group_ids = [ group_ids ] unless group_ids.is_a? Array
93
+ body = { adgroupIds: group_ids }
94
+ response = request( auth, Service, "getKeywordByAdgroupId", body )
95
+ return process(response, 'groupKeywords', debug){|x| make_groupKeywords( x ) }
96
+ end
97
+
98
+ def self.search_id_by_group_id( auth, group_ids, debug = false )
99
+ group_ids = [ group_ids ] unless group_ids.is_a? Array
100
+ body = { adgroupIds: group_ids }
101
+ response = request( auth, Service, "getKeywordIdByAdgroupId", body )
102
+ return process(response, 'groupKeywordIds', debug){|x| make_groupKeywordIds( x ) }
103
+ end
104
+
105
+ # 下面三个操作操作对象包括计划,组和关键字
106
+ # 不知道放在这里合不合适
107
+ def self.status( auth, ids, type, debug = false )
108
+ ids = [ ids ] unless ids.is_a? Array
109
+ body = { ids: ids, type: Type[type]}
110
+ response = request( auth, Service, 'getKeywordStatus', body )
111
+ return process(response, 'keywordStatus', debug){|x| reverse_type( x ) }
112
+ end
113
+
114
+ def self.quality( auth ,ids, type, device, debug = false )
115
+ '''
116
+ Return 10Quanlity *Not the old Quality* of given ketword id
117
+ '''
118
+ ids = [ ids ] unless ids.is_a? Array
119
+ body = { ids: ids, type: Type[type], device:Device[device] }
120
+ response = request( auth, Service, 'getKeyword10Quality', body )
121
+ return process(response, 'keyword10Quality', debug){|x| reverse_type( x, @quality10_map ) }
122
+ end
123
+
124
+ private
125
+ def self.make_groupKeywordIds( groupKeywordIds )
126
+ group_keyword_ids = []
127
+ groupKeywordIds.each do |groupKeywordId|
128
+ group_keyword_id = { }
129
+ group_keyword_id[:group_id] = groupKeywordId['adgroupIds']
130
+ group_keyword_id[:keyword_ids] = groupKeywordId['keywordIds']
131
+ group_keyword_ids << group_keyword_id
132
+ end
133
+ return group_keyword_ids
134
+ end
135
+
136
+ private
137
+ def self.make_groupKeywords( groupKeywords )
138
+ group_keywords = []
139
+ groupKeywords.each do |groupKeyword|
140
+ group_keyword = {}
141
+ group_keyword[:group_id] = groupKeyword['adgroupId']
142
+ group_keyword[:keywords] = reverse_type( groupKeyword['keywordTypes'] )
143
+ group_keywords << group_keyword
144
+ end
145
+ return group_keywords
146
+ end
147
+
148
+ # Override
149
+ def self.make_type( params, map = @map)
150
+ params = [ params ] unless params.is_a? Array
151
+ types = []
152
+ params.each do |param|
153
+ type = {}
154
+ map.each do |key|
155
+ # 增加对matchtype的自动转换
156
+ if key[0] == :match_type
157
+ value = param[ key[0] ]
158
+ type[ key[1] ] = Match_type[ value ] if value
159
+ else
160
+ value = param[ key[0] ]
161
+ type[ key[1] ] = value if value
162
+ end
163
+ end
164
+ types << type
165
+ end
166
+ return types
167
+ end
168
+
169
+ # Overwrite
170
+ def self.reverse_type( types, map = @map )
171
+ types = [ types ] unless types.is_a? Array
172
+ params = []
173
+ types.each do |type|
174
+ param = {}
175
+ # 增加对matchtype的自动转换
176
+ map.each do |key|
177
+ if key[0] == :match_type
178
+ value = type[ key[1].to_s ]
179
+ param[ key[0] ] = Match_type_r[ value ] if value
180
+ else
181
+ value = type[ key[1].to_s ]
182
+ param[ key[0] ] = value if value
183
+ end
184
+ end # map.each
185
+ params << param
186
+ end # types.each
187
+ return params
188
+ end
189
+
190
+ end # keyword
191
+ end # Baidu
192
+ end # API
193
+ end # PPC