ppc 0.3.0 → 1.0.1

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 (76) hide show
  1. checksums.yaml +4 -4
  2. data/.autotest +25 -0
  3. data/.gemtest +0 -0
  4. data/History.txt +6 -0
  5. data/Manifest.txt +8 -0
  6. data/README.txt +80 -0
  7. data/Rakefile +19 -0
  8. data/bin/ppc +3 -0
  9. data/lib/ppc.rb +6 -15
  10. data/test/test_ppc.rb +0 -0
  11. metadata +41 -130
  12. data/.gitignore +0 -37
  13. data/.rspec +0 -2
  14. data/LICENSE +0 -339
  15. data/README.md +0 -78
  16. data/lib/ppc/api.rb +0 -10
  17. data/lib/ppc/api/baidu.rb +0 -138
  18. data/lib/ppc/api/baidu/account.rb +0 -47
  19. data/lib/ppc/api/baidu/bulk.rb +0 -41
  20. data/lib/ppc/api/baidu/creative.rb +0 -125
  21. data/lib/ppc/api/baidu/group.rb +0 -111
  22. data/lib/ppc/api/baidu/keyword.rb +0 -204
  23. data/lib/ppc/api/baidu/plan.rb +0 -68
  24. data/lib/ppc/api/baidu/report.rb +0 -143
  25. data/lib/ppc/api/qihu.rb +0 -107
  26. data/lib/ppc/api/qihu/account.rb +0 -86
  27. data/lib/ppc/api/qihu/creative.rb +0 -106
  28. data/lib/ppc/api/qihu/group.rb +0 -113
  29. data/lib/ppc/api/qihu/keyword.rb +0 -111
  30. data/lib/ppc/api/qihu/plan.rb +0 -64
  31. data/lib/ppc/api/qihu/report.rb +0 -159
  32. data/lib/ppc/api/shenma.rb +0 -64
  33. data/lib/ppc/api/shenma/report.rb +0 -135
  34. data/lib/ppc/api/sogou.rb +0 -122
  35. data/lib/ppc/api/sogou/account.rb +0 -42
  36. data/lib/ppc/api/sogou/creative.rb +0 -117
  37. data/lib/ppc/api/sogou/group.rb +0 -116
  38. data/lib/ppc/api/sogou/keyword.rb +0 -182
  39. data/lib/ppc/api/sogou/plan.rb +0 -66
  40. data/lib/ppc/api/sogou/report.rb +0 -129
  41. data/lib/ppc/ext.rb +0 -9
  42. data/lib/ppc/operation.rb +0 -196
  43. data/lib/ppc/operation/account.rb +0 -53
  44. data/lib/ppc/operation/creative.rb +0 -28
  45. data/lib/ppc/operation/group.rb +0 -59
  46. data/lib/ppc/operation/keyword.rb +0 -32
  47. data/lib/ppc/operation/plan.rb +0 -47
  48. data/lib/ppc/operation/report.rb +0 -19
  49. data/ppc.gemspec +0 -26
  50. data/spec/baidu/api_baidu_account_spec.rb +0 -15
  51. data/spec/baidu/api_baidu_creative_spec.rb +0 -67
  52. data/spec/baidu/api_baidu_group_spec.rb +0 -45
  53. data/spec/baidu/api_baidu_keyword_spec.rb +0 -61
  54. data/spec/baidu/api_baidu_plan_spec.rb +0 -43
  55. data/spec/baidu/api_baidu_report_spec.rb +0 -44
  56. data/spec/baidu/api_baidu_spec.rb +0 -55
  57. data/spec/operation/operation_baidu_report_spec.rb +0 -17
  58. data/spec/operation/operation_baidu_spec.rb +0 -78
  59. data/spec/operation/operation_qihu_report_spec.rb +0 -18
  60. data/spec/operation/operation_qihu_spec.rb +0 -51
  61. data/spec/operation/operation_sogou_report_spec.rb +0 -17
  62. data/spec/operation/operation_sogou_spec.rb +0 -51
  63. data/spec/operation/operation_spec_helper.rb +0 -51
  64. data/spec/qihu/api_qihu_account_spec.rb +0 -25
  65. data/spec/qihu/api_qihu_creative_spec.rb +0 -48
  66. data/spec/qihu/api_qihu_group_spec.rb +0 -40
  67. data/spec/qihu/api_qihu_keyword_spec.rb +0 -50
  68. data/spec/qihu/api_qihu_plan_spec.rb +0 -39
  69. data/spec/qihu/api_qihu_report_spec.rb +0 -54
  70. data/spec/sogou/api_sogou_account_spec.rb +0 -15
  71. data/spec/sogou/api_sogou_creative_spec.rb +0 -48
  72. data/spec/sogou/api_sogou_group_spec.rb +0 -45
  73. data/spec/sogou/api_sogou_keyword_spec.rb +0 -50
  74. data/spec/sogou/api_sogou_plan_spec.rb +0 -39
  75. data/spec/sogou/api_sogou_report_spec.rb +0 -51
  76. data/spec/spec_helper.rb +0 -134
@@ -1,64 +0,0 @@
1
- module PPC
2
- module API
3
- class Baidu
4
- @map = nil
5
- @@debug = false
6
-
7
- def self.debug_on
8
- @@debug = true
9
- end
10
-
11
- def self.debug_off
12
- @@debug = false
13
- end
14
-
15
- def self.request( auth, path, params = {} )
16
- '''
17
- request should return whole http response including header
18
- '''
19
- uri = URI("https://e.sm.cn#{path}")
20
- http_body = {
21
- header: {
22
- username: auth[:username],
23
- password: auth[:password],
24
- token: auth[:token],
25
- target: auth[:tarvget]
26
- },
27
- body: params
28
- }.to_json
29
-
30
- http_header = {
31
- 'Content-Type' => 'application/json; charset=UTF-8'
32
- }
33
-
34
- http = Net::HTTP.new(uri.host, 443)
35
- # 是否显示http通信输出
36
- http.set_debug_output( $stdout ) if @@debug
37
- http.use_ssl = true
38
-
39
- response = http.post(uri.path, http_body, http_header)
40
- response = JSON.parse( response.body )
41
- end
42
-
43
- def self.process( response, key, &func)
44
- '''
45
- Process Http response. If operation successes, return value of given keys.
46
- You can process the result using function &func, or do nothing by passing
47
- block {|x|x}
48
- ===========================
49
- @Output: resultType{ desc: boolean, failure: Array, result: Array }
50
-
51
- failure is the failures part of response\'s header
52
- result is the processed response body.
53
- '''
54
- p response
55
- result = {}
56
- result[:succ] = response['header']['desc']=='success'? true : false
57
- result[:failure] = response['header']['failures']
58
- result[:result] = func[ response['body'][key] ]
59
- return result
60
- end # process
61
-
62
- end
63
- end
64
- end
@@ -1,135 +0,0 @@
1
- # -*- coding:utf-8 -*-
2
- module PPC
3
- module API
4
- class Shenma
5
- class Report< Shenma
6
- Service = 'Report'
7
-
8
- # 需要用到的映射集合
9
- Type_map = { 'account' =>2, 'plan'=> 10, 'group'=> 11,
10
- 'keyword'=> 14, 'creative'=> 12, 'region'=> 3,
11
- 'query'=> 6, 'phone' => 22, 'app' => 23 }
12
-
13
- Level_map = { 'account' => 2, 'plan' => 3, 'group' => 5,
14
- 'creative' => 7, 'keyword' => 11, 'phone' => 22,
15
- 'app' => 23, 'pair' => 12 }
16
-
17
- Unit_map = { 'day' => 5, 'month' => 3, 'default' => 8 }
18
-
19
- def self.get_id( auth, params, debug = false )
20
- request = make_reportrequest( params )
21
- body = { ReportRequestType: request }
22
- response = request( auth, '/report/getReport' ,body)
23
- process( response, 'reportId', debug ){ |x| x }
24
- end
25
-
26
- def self.get_state( auth, id, debug = false)
27
- '''
28
- input id should be string
29
- '''
30
- status = {1=>'Waiting' ,2=>'Opearting' ,3=>'Finished'}
31
- body = { taskId: id }
32
- response = request( auth, '/task/getTaskState' ,body)
33
- process( response, 'isGenerated', debug ){ |x| status[x] }
34
- end
35
-
36
- # todo : rewrite method
37
- def self.download( auth, id, debug = false )
38
- body = { fileId: id }
39
- response = request( auth, '/file/download' ,body)
40
- process( response, 'reportPath', debug ){ |x| x }
41
- end
42
-
43
- private
44
- def self.make_reportrequest( param )
45
- '''
46
- make RepoerRequestType
47
- ======================
48
- For more docs please have a look at
49
- ::PPC::API::Baidu::Report:make_reportrequest()
50
- '''
51
- requesttype = {}
52
- requesttype[:performanceData] = param[:fields]
53
- requesttype[:reportType] = Type_map[ param[:type] ] if param[:type]
54
- requesttype[:levelOfDetails] = Level_map[ param[:level] ] if param[:level]
55
- requesttype[:statRange] = Level_map[ param[:range] ] if param[:range]
56
- requesttype[:unitOfTime] = Unit_map[ param[:unit] ] if param[:unit]
57
- requesttype[:idOnly] = param[:id_only] || false
58
- requesttype[:statIds] = param[:ids] if param[:ids] != nil
59
- requesttype[:startDate] = parse_date( param[:startDate] )
60
- requesttype[:endDate] = parse_date( param[:endDate] )
61
- return requesttype
62
- end
63
-
64
- private
65
- def self.parse_date( date )
66
- """
67
- Cast string to time:
68
- 'YYYYMMDD' => Time
69
- """
70
- if date
71
- y = date[0..3]
72
- m = date[4..5]
73
- d = date[6..7]
74
- date = Time.new( y, m, d )
75
- else
76
- date = (Time.now - 24*3600)
77
- end
78
- date.to_s[0,10]
79
- end
80
-
81
- def download_report( auth, param, debug = false )
82
- response = call('report').get_id( auth, param )
83
- if response[:succ]
84
- id = response[:result]
85
- p "Got report id:" + id.to_s if debug
86
- loop do
87
- sleep 2
88
- break if call('report').get_state( auth, id )[:result] == 'Finished'
89
- p "Report is not generated, waiting..." if debug
90
- end
91
- # need to rewrite the download method here.
92
- url = call('report').get_url( auth, id )[:result]
93
- return open(url).read.force_encoding('gb18030').encode('utf-8')
94
- else
95
- raise response[:failure][0]["message"]
96
- end
97
- end
98
-
99
- ###########################
100
- # intreface for Operation #
101
- ###########################
102
- def query_report( auth, param = nil, debug = false )
103
- param = {} if not param
104
- param[:type] ||= 'query'
105
- param[:fields] ||= %w(click)
106
- param[:level] ||= 'pair'
107
- param[:range] ||= 'account'
108
- param[:unit] ||= 'day'
109
- download_report( param, debug )
110
- end
111
-
112
- def creative_report( auth, param = nil, debug = false )
113
- param = {} if not param
114
- param[:type] ||= 'creative'
115
- param[:fields] ||= %w( cost cpc click impression ctr )
116
- param[:level] ||= 'creative'
117
- param[:range] ||= 'creative'
118
- param[:unit] ||= 'day'
119
- download_report( param, debug )
120
- end
121
-
122
- def keyword_report( auth, param = nil, debug = false )
123
- param = {} if not param
124
- param[:type] ||= 'keyword'
125
- param[:fields] ||= %w( cost cpc click impression ctr )
126
- param[:level] ||= 'keywordid'
127
- param[:range] ||= 'keywordid'
128
- param[:unit] ||= 'day'
129
- download_report( param, debug )
130
- end
131
-
132
- end # Repost
133
- end # Baidu
134
- end # API
135
- end # PPC
data/lib/ppc/api/sogou.rb DELETED
@@ -1,122 +0,0 @@
1
- require 'savon'
2
- require 'active_support'
3
- require 'ppc/api/sogou/account'
4
- require 'ppc/api/sogou/plan'
5
- require 'ppc/api/sogou/group'
6
- require 'ppc/api/sogou/keyword'
7
- require 'ppc/api/sogou/report'
8
- require 'ppc/api/sogou/creative'
9
-
10
- module PPC
11
- module API
12
- class Sogou
13
-
14
- @map = nil
15
- @@debug = false
16
-
17
- def self.debug_on
18
- @@debug = true
19
- end
20
-
21
- def self.debug_off
22
- @@debug = false
23
- end
24
-
25
- def self.request( auth, service, method, params = {})
26
- '''
27
- ps. in savon3, .hash method will turn CamelXML to snake hash
28
- preprocess response, extract
29
- '''
30
-
31
- service = service + "Service"
32
- client = Savon.new( "http://api.agent.sogou.com:8080/sem/sms/v1/#{service}?wsdl" )
33
- operation = client.operation( service, service, method )
34
-
35
- operation.header = {
36
- AuthHeader:{
37
- username: auth[:username],
38
- password: auth[:password],
39
- token: auth[:token]
40
- }
41
- }
42
- operation.body = { (method+'Request').to_sym => params }
43
- # debug print
44
- debug_print( operation ) if @@debug
45
- result = operation.call.hash[:envelope]
46
- #extract header and body
47
- response = { }
48
- response[:header] = result[:header][:res_header]
49
- response[:body] = result[:body][ (method + "Response").snake_case.to_sym ]
50
- # debug print
51
- p response if @@debug
52
- return response
53
- end
54
-
55
- def self.debug_print( operation )
56
- p '{:header=>' + operation.header.to_s + ', :body=>' + operation.body.to_s + '}'
57
- end
58
-
59
- def self.process( response, key, debug = false, &func )
60
- '''
61
- @input
62
- : type key : string
63
- : param key : type name, we will transfer camel string
64
- into snake_case symbol inside the method
65
- '''
66
- return response if debug
67
-
68
- result = {}
69
- result[:succ] = response[:header][:desc]=='success'? true : false
70
- result[:failure] = response[:header][:failures]
71
- result[:result] = func[ response[:body][ key.snake_case.to_sym ] ]
72
- return result
73
- end
74
-
75
- def self.make_type( params, map = @map)
76
- '''
77
- For more info visit ::PPC::API::sogou:make_type
78
- '''
79
- params = [ params ] unless params.is_a? Array
80
-
81
- types = []
82
- params.each do |param|
83
- type = {}
84
-
85
- map.each do |key|
86
- value = param[ key[0] ]
87
- type[ key[1] ] = value if value != nil
88
- end
89
-
90
- types << type
91
- end
92
- return types
93
- end
94
-
95
- def self.reverse_type( types, map = @map )
96
- '''
97
- For more info visit ::PPC::API::sogou:reverse_type
98
- Here, the camel key will be turn into snake key
99
- '''
100
- types = [ types ] unless types.is_a? Array
101
-
102
- params = []
103
- types.each do |type|
104
- param = {}
105
-
106
- map.each do |key|
107
- # 这里做两次转换并不是十分高效的方法,考虑maintain两张map
108
- value = type[ key[1].to_s.snake_case.to_sym ]
109
- param[ key[0] ] = value if value != nil
110
- end
111
-
112
- params << param
113
- end
114
- return params
115
- end
116
-
117
-
118
-
119
- end
120
- end
121
- end
122
-
@@ -1,42 +0,0 @@
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
@@ -1,117 +0,0 @@
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