ppc 0.3.0

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 (68) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +37 -0
  3. data/.rspec +2 -0
  4. data/LICENSE +339 -0
  5. data/README.md +78 -0
  6. data/lib/ppc.rb +17 -0
  7. data/lib/ppc/api.rb +10 -0
  8. data/lib/ppc/api/baidu.rb +138 -0
  9. data/lib/ppc/api/baidu/account.rb +47 -0
  10. data/lib/ppc/api/baidu/bulk.rb +41 -0
  11. data/lib/ppc/api/baidu/creative.rb +125 -0
  12. data/lib/ppc/api/baidu/group.rb +111 -0
  13. data/lib/ppc/api/baidu/keyword.rb +204 -0
  14. data/lib/ppc/api/baidu/plan.rb +68 -0
  15. data/lib/ppc/api/baidu/report.rb +143 -0
  16. data/lib/ppc/api/qihu.rb +107 -0
  17. data/lib/ppc/api/qihu/account.rb +86 -0
  18. data/lib/ppc/api/qihu/creative.rb +106 -0
  19. data/lib/ppc/api/qihu/group.rb +113 -0
  20. data/lib/ppc/api/qihu/keyword.rb +111 -0
  21. data/lib/ppc/api/qihu/plan.rb +64 -0
  22. data/lib/ppc/api/qihu/report.rb +159 -0
  23. data/lib/ppc/api/shenma.rb +64 -0
  24. data/lib/ppc/api/shenma/report.rb +135 -0
  25. data/lib/ppc/api/sogou.rb +122 -0
  26. data/lib/ppc/api/sogou/account.rb +42 -0
  27. data/lib/ppc/api/sogou/creative.rb +117 -0
  28. data/lib/ppc/api/sogou/group.rb +116 -0
  29. data/lib/ppc/api/sogou/keyword.rb +182 -0
  30. data/lib/ppc/api/sogou/plan.rb +66 -0
  31. data/lib/ppc/api/sogou/report.rb +129 -0
  32. data/lib/ppc/ext.rb +9 -0
  33. data/lib/ppc/operation.rb +196 -0
  34. data/lib/ppc/operation/account.rb +53 -0
  35. data/lib/ppc/operation/creative.rb +28 -0
  36. data/lib/ppc/operation/group.rb +59 -0
  37. data/lib/ppc/operation/keyword.rb +32 -0
  38. data/lib/ppc/operation/plan.rb +47 -0
  39. data/lib/ppc/operation/report.rb +19 -0
  40. data/ppc.gemspec +26 -0
  41. data/spec/baidu/api_baidu_account_spec.rb +15 -0
  42. data/spec/baidu/api_baidu_creative_spec.rb +67 -0
  43. data/spec/baidu/api_baidu_group_spec.rb +45 -0
  44. data/spec/baidu/api_baidu_keyword_spec.rb +61 -0
  45. data/spec/baidu/api_baidu_plan_spec.rb +43 -0
  46. data/spec/baidu/api_baidu_report_spec.rb +44 -0
  47. data/spec/baidu/api_baidu_spec.rb +55 -0
  48. data/spec/operation/operation_baidu_report_spec.rb +17 -0
  49. data/spec/operation/operation_baidu_spec.rb +78 -0
  50. data/spec/operation/operation_qihu_report_spec.rb +18 -0
  51. data/spec/operation/operation_qihu_spec.rb +51 -0
  52. data/spec/operation/operation_sogou_report_spec.rb +17 -0
  53. data/spec/operation/operation_sogou_spec.rb +51 -0
  54. data/spec/operation/operation_spec_helper.rb +51 -0
  55. data/spec/qihu/api_qihu_account_spec.rb +25 -0
  56. data/spec/qihu/api_qihu_creative_spec.rb +48 -0
  57. data/spec/qihu/api_qihu_group_spec.rb +40 -0
  58. data/spec/qihu/api_qihu_keyword_spec.rb +50 -0
  59. data/spec/qihu/api_qihu_plan_spec.rb +39 -0
  60. data/spec/qihu/api_qihu_report_spec.rb +54 -0
  61. data/spec/sogou/api_sogou_account_spec.rb +15 -0
  62. data/spec/sogou/api_sogou_creative_spec.rb +48 -0
  63. data/spec/sogou/api_sogou_group_spec.rb +45 -0
  64. data/spec/sogou/api_sogou_keyword_spec.rb +50 -0
  65. data/spec/sogou/api_sogou_plan_spec.rb +39 -0
  66. data/spec/sogou/api_sogou_report_spec.rb +51 -0
  67. data/spec/spec_helper.rb +134 -0
  68. metadata +177 -0
@@ -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, debug = false)
22
+ response = request(auth,Service,'getAccountInfo' )
23
+ return process( response, 'accountInfoType', debug ){ |x|reverse_type(x)[0] }
24
+ end
25
+
26
+ def self.update(auth, param = {}, debug = false)
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
+ return process( response, 'accountInfoType', debug ){ |x|reverse_type(x)[0] }
37
+ end
38
+
39
+ end
40
+ end
41
+ end
42
+ 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, debug = false )
29
+ body = { cpcIdeaTypes: make_type( creatives ) }
30
+ response = request( auth, Service, 'addCpcIdea', body )
31
+ process( response, 'cpcIdeaTypes', debug ){ |x| reverse_type(x) }
32
+ end
33
+
34
+ def self.get( auth, ids, getTemp = 0, debug = false )
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', debug ){ |x| reverse_type(x) }
44
+ end
45
+
46
+ def self.update( auth, creatives, debug = false )
47
+ '''
48
+ 根据实际使用情况,更新的时候creative title为必填选
49
+ '''
50
+ body = { cpcIdeaTypes: make_type( creatives ) }
51
+ response = request( auth, Service, 'updateCpcIdea', body )
52
+ process( response, 'cpcIdeaTypes', debug ){ |x| reverse_type(x) }
53
+ end
54
+
55
+ def self.delete( auth, ids, debug = false )
56
+ ids = [ ids ] unless ids.is_a? Array
57
+ body = { cpcIdeaIds: ids }
58
+ response = request( auth, Service, 'deleteCpcIdea', body )
59
+ process( response, 'nil', debug ){ |x| x }
60
+ end
61
+
62
+ def self.status( auth, ids, getTemp = 0, debug = false )
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', debug ){ |x| reverse_type(x, @status_map) }
67
+ end
68
+
69
+ def self.search_id_by_group_id( auth, ids, getTemp = 0, debug = false )
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', debug ){ |x| make_groupCreativeIds( x ) }
79
+ end
80
+
81
+ def self.search_by_group_id( auth, ids, getTemp = 0, debug = false )
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', debug ){ |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,116 @@
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, debug = false )
21
+ """
22
+ @return : Array of cpcPlanGrpIdTypes
23
+ """
24
+ response = request( auth, Service , "getAllCpcGrpId" )
25
+ #此处返回值与key与开发文档不同
26
+ process( response, 'cpcPlanGrpIds', debug ){ |x| make_planGroupIds( x ) }
27
+ end
28
+
29
+ def self.get( auth, ids, debug = false )
30
+ ids = [ ids ] unless ids.is_a? Array
31
+ body = { cpcGrpIds: ids }
32
+ response = request(auth, Service, "getCpcGrpByCpcGrpId",body )
33
+ process( response, 'cpcGrpTypes', debug ){ |x| reverse_type(x) }
34
+ end
35
+
36
+ def self.add( auth, groups, debug = false )
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', debug ){ |x| reverse_type(x) }
47
+ end
48
+
49
+ def self.update( auth, groups, debug = false )
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', debug ){ |x| reverse_type(x) }
59
+ end
60
+
61
+ def self.delete( auth, ids, debug = false )
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, 'nil', debug ){ |x| x }
69
+ end
70
+
71
+ def self.search_by_plan_id( auth, ids, debug = false )
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', debug ){ |x| make_planGroups( x ) }
77
+ end
78
+
79
+ def self.search_id_by_plan_id( auth, ids, debug = false )
80
+ ids = [ ids ] unless ids.is_a? Array
81
+ body = { cpcPlanIds: ids }
82
+ response = request( auth, Service ,"getCpcGrpIdByCpcPlanId", body )
83
+ process( response, 'cpcPlanGrpIds', debug ){ |x| make_planGroupIds( x ) }
84
+ end
85
+
86
+ private
87
+ def self.make_planGroupIds( cpcPlanGrpIdTypes )
88
+ cpcPlanGrpIdTypes = [cpcPlanGrpIdTypes] unless cpcPlanGrpIdTypes.is_a? Array
89
+ planGroupIds = []
90
+ cpcPlanGrpIdTypes.each do |cpcPlanGrpIdType|
91
+ planGroupId = { }
92
+ planGroupId[:plan_id] = cpcPlanGrpIdType[:cpc_plan_id]
93
+ planGroupId[:group_ids] = cpcPlanGrpIdType[:cpc_grp_ids]
94
+ planGroupIds << planGroupId
95
+ end
96
+ return planGroupIds
97
+ end
98
+
99
+ private
100
+ def self.make_planGroups( cpcPlanGrpTypes )
101
+ # 多加一行change成array
102
+ cpcPlanGrpTypes = [cpcPlanGrpTypes] unless cpcPlanGrpTypes.is_a? Array
103
+ planGroups = []
104
+ cpcPlanGrpTypes.each do |cpcPlanGrpType|
105
+ planGroup = {}
106
+ planGroup[:plan_id] = cpcPlanGrpType[:cpc_plan_id]
107
+ planGroup[:groups] = reverse_type( cpcPlanGrpType[:cpc_grp_types] )
108
+ planGroups << planGroup
109
+ end
110
+ return planGroups
111
+ end
112
+
113
+ end # class group
114
+ end # class baidu
115
+ end # API
116
+ end # module
@@ -0,0 +1,182 @@
1
+ # -*- coding:utf-8 -*-
2
+ module PPC
3
+ module API
4
+ class Sogou
5
+ class Keyword< Sogou
6
+ Service = 'Cpc'
7
+
8
+ Match_type = { 'exact' => 0, 'wide' => 1,0 => 'exact', 1 => 'wide' }
9
+
10
+ @map = [
11
+ [:id,:cpcId],
12
+ [:group_id,:cpcGrpId],
13
+ [:keyword,:cpc],
14
+ [:price,:price],
15
+ [:pc_destination,:visitUrl],
16
+ [:mobile_destination,:mobileVisitUrl],
17
+ [:match_type,:matchType],
18
+ [:pause,:pause],
19
+ [:status,:status],
20
+ [:quality,:cpcQuality]
21
+ ]
22
+ @quality_map = [
23
+ [:id,:cpcId],
24
+ [:quality,:cpcQuality]
25
+ ]
26
+
27
+ @status_map = [
28
+ [:id,:cpcId],
29
+ [:status,:status]
30
+ ]
31
+
32
+ # 后面改成info方法
33
+ def self.get( auth, ids, debug = false )
34
+ '''
35
+ getCpcByCpcId
36
+ '''
37
+ ids = [ ids ] unless ids.is_a? Array
38
+ body = { cpcIds: ids}
39
+ response = request( auth, Service, 'getCpcByCpcId', body )
40
+ process(response, 'cpcTypes', debug){|x| reverse_type( x ) }
41
+ end
42
+
43
+ def self.add( auth, keywords, debug = false )
44
+ '''
45
+ '''
46
+ cpcTypes = make_type( keywords )
47
+ body = { cpcTypes: cpcTypes }
48
+ response = request( auth, Service, "addCpc", body )
49
+ process(response, 'cpcTypes', debug){|x| reverse_type(x) }
50
+ end
51
+
52
+ def self.update( auth, keywords, debug = false )
53
+ '''
54
+ '''
55
+ cpcTypes = make_type( keywords )
56
+ body = { cpcTypes: cpcTypes }
57
+ response = request( auth, Service, "updateCpc", body )
58
+ process(response, 'cpcTypes', debug){|x| reverse_type(x) }
59
+ end
60
+
61
+ def self.delete( auth, ids, debug = false )
62
+ """
63
+ """
64
+ ids = [ ids ] unless ids.is_a? Array
65
+ body = { cpcIds: ids}
66
+ response = request( auth, Service, 'deleteCpc', body )
67
+ process(response, 'nil', debug){|x| x }
68
+ end
69
+
70
+ def self.search_by_group_id( auth, group_ids, debug = false )
71
+ """
72
+ getKeywordByGroupIds
73
+ @input: list of group id
74
+ @output: list of groupKeyword
75
+ """
76
+ group_ids = [ group_ids ] unless group_ids.is_a? Array
77
+ body = { cpcGrpIds: group_ids }
78
+ response = request( auth, Service, "getCpcByCpcGrpId", body )
79
+ process(response, 'cpcGrpCpcs', debug){|x| make_groupKeywords( x ) }
80
+ end
81
+
82
+ def self.search_id_by_group_id( auth, group_ids, debug = false )
83
+ group_ids = [ group_ids ] unless group_ids.is_a? Array
84
+ body = { cpcGrpIds: group_ids }
85
+ response = request( auth, Service, "getCpcIdByCpcGrpId", body )
86
+ process(response, 'cpcGrpCpcIds', debug){|x| make_groupKeywordIds( x ) }
87
+ end
88
+
89
+ # sogou的keyword服务不提供质量度
90
+ def self.status( auth, ids, debug = false )
91
+ '''
92
+ Return [ { id: id, status: status} ... ]
93
+ '''
94
+ ids = [ ids ] unless ids.is_a? Array
95
+ body = { cpcIds: ids}
96
+ response = request( auth, Service, 'getCpcByCpcId', body )
97
+
98
+ process(response, 'cpcTypes', debug){ |x| reverse_type(x, @status_map) }
99
+ end
100
+
101
+ def self.quality( auth ,ids, debug = false )
102
+ '''
103
+ Return [ { id: id, quality: quality} ... ]
104
+ '''
105
+ ids = [ ids ] unless ids.is_a? Array
106
+ body = { cpcIds: ids}
107
+ response = request( auth, Service, 'getCpcByCpcId', { cpcIds: ids} )
108
+ process(response, 'cpcTypes', debug){ |x| reverse_type(x, @quality_map) }
109
+ end
110
+
111
+ private
112
+ def self.make_groupKeywordIds( cpcGrpCpcIdTypes )
113
+ cpcGrpCpcIdTypes = [cpcGrpCpcIdTypes] unless cpcGrpCpcIdTypes.is_a? Array
114
+ group_keyword_ids = []
115
+ cpcGrpCpcIdTypes.each do |cpcGrpCpcIdType|
116
+ group_keyword_id = { }
117
+ group_keyword_id[:group_id] = cpcGrpCpcIdType[:cpc_grp_id]
118
+ group_keyword_id[:keyword_ids] = cpcGrpCpcIdType[:cpc_ids]
119
+ group_keyword_ids << group_keyword_id
120
+ end
121
+ return group_keyword_ids
122
+ end
123
+
124
+ private
125
+ def self.make_groupKeywords( cpcGrpCpcTypes )
126
+ cpcGrpCpcTypes = [cpcGrpCpcTypes] unless cpcGrpCpcTypes.is_a? Array
127
+ group_keywords = []
128
+ cpcGrpCpcTypes.each do |cpcGrpCpcType|
129
+ group_keyword = {}
130
+ group_keyword[:group_id] = cpcGrpCpcType[:cpc_grp_id]
131
+ group_keyword[:keywords] = reverse_type( cpcGrpCpcType[:cpc_types] )
132
+ group_keywords << group_keyword
133
+ end
134
+ return group_keywords
135
+ end
136
+
137
+ # Override
138
+ def self.make_type( params, map = @map)
139
+ params = [ params ] unless params.is_a? Array
140
+ types = []
141
+ params.each do |param|
142
+ type = {}
143
+ map.each do |key|
144
+ # 增加对matchtype的自动转换
145
+ if key[0] == :match_type
146
+ value = param[ key[0] ]
147
+ type[ key[1] ] = Match_type[ value ] if value
148
+ else
149
+ value = param[ key[0] ]
150
+ type[ key[1] ] = value if value != nil
151
+ end
152
+ end
153
+ types << type
154
+ end
155
+ return types
156
+ end
157
+
158
+ # Overwrite
159
+ def self.reverse_type( types, map = @map )
160
+ types = [ types ] unless types.is_a? Array
161
+ params = []
162
+ types.each do |type|
163
+ param = {}
164
+ # 增加对matchtype的自动转换
165
+ map.each do |key|
166
+ if key[0] == :match_type
167
+ value = type[ key[1].to_s.snake_case.to_sym]
168
+ param[ key[0] ] = Match_type[ value ] if value
169
+ else
170
+ value = type[ key[1].to_s.snake_case.to_sym ]
171
+ param[ key[0] ] = value if value != nil
172
+ end
173
+ end # map.each
174
+ params << param
175
+ end # types.each
176
+ return params
177
+ end
178
+
179
+ end # keyword
180
+ end # Baidu
181
+ end # API
182
+ end # PPC