ppc 0.3.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
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,68 +0,0 @@
1
- module PPC
2
- module API
3
- class Baidu
4
- class Plan< Baidu
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
- [:device,:device],
19
- [:price_ratio,:priceRatio],
20
- [:is_dynamic,:isDynamicCreative],
21
- [:pause,:pause],
22
- [:status,:status]
23
- ]
24
-
25
- def self.all( auth )
26
- response = request( auth, Service, 'getAllCampaign' )
27
- process( response, 'campaignTypes' ){ |x| reverse_type(x) }
28
- end
29
-
30
- def self.ids( auth )
31
- response = request( auth, Service, 'getAllCampaignId' )
32
- process( response, 'campaignIds' ){ |x| x }
33
- end
34
-
35
- def self.get( auth, ids )
36
- ids = [ ids ] unless ids.is_a? Array
37
- body = { campaignIds: ids }
38
- response = request( auth, Service, 'getCampaignByCampaignId', body)
39
- process( response, 'campaignTypes' ){ |x| reverse_type(x) }
40
- end
41
-
42
- def self.add( auth, plans )
43
- campaigntypes = make_type( plans )
44
- # set extended = 1 to allow change of isDynamicCreative
45
- body = { campaignTypes: campaigntypes, extended:1 }
46
- response = request( auth, Service, 'addCampaign', body)
47
- process( response, 'campaignTypes' ){ |x| reverse_type(x) }
48
- end
49
-
50
- def self.update(auth,plans )
51
- campaigntypes = make_type( plans )
52
- # set extended = 1 to allow change of isDynamicCreative
53
- body = { campaignTypes: campaigntypes, extended:1 }
54
- response = request( auth, Service, 'updateCampaign', body)
55
- process( response, 'campaignTypes' ){ |x| reverse_type(x) }
56
- end
57
-
58
- def self.delete(auth, ids )
59
- ids = [ ids ] unless ids.class == Array
60
- body = { campaignIds: ids }
61
- response = request( auth, Service, 'deleteCampaign', body)
62
- process( response, 'result' ){ |x| x }
63
- end
64
-
65
- end # Service
66
- end # baidu
67
- end # API
68
- end # PPC
@@ -1,143 +0,0 @@
1
- # -*- coding:utf-8 -*-
2
- module PPC
3
- module API
4
- class Baidu
5
- class Report< Baidu
6
- Service = 'Report'
7
-
8
- # 需要用到的映射集合
9
- Type_map = { 'account' => 2, 'plan'=> 10, 'group'=> 11,
10
- 'keyword'=> 14, 'creative'=> 12, 'pair'=> 15,
11
- 'region'=> 3, 'wordid'=> 9 , 'query'=>6 }
12
-
13
- Level_map = { 'account' => 2, 'plan' => 3, 'group' => 5,
14
- 'creative'=> 7, 'keywordid' => 11, 'pair' => 12,
15
- 'wordid' => 6 }
16
-
17
- Device_map = { 'all' => 0, 'pc' => 1, 'mobile' => 2 }
18
-
19
- Unit_map = { 'day' => 5, 'week' => 4, 'month' => 3, 'year' => 1, 'hour' => 7 }
20
-
21
- ########################
22
- # API wraping function #
23
- ########################
24
- def self.get_id( auth, params )
25
- request = make_reportrequest( params )
26
- body = { reportRequestType: request }
27
- response = request( auth, Service, 'getProfessionalReportId' ,body)
28
- process( response, 'reportId' ){ |x| x }
29
- end
30
-
31
- def self.get_state( auth, id )
32
- '''
33
- input id should be string
34
- '''
35
- status = {1=>'Waiting' ,2=>'Opearting' ,3=>'Finished'}
36
- body = { reportId: id }
37
- response = request( auth, Service, 'getReportState' ,body)
38
- process( response, 'isGenerated' ){ |x| status[x] }
39
- end
40
-
41
- def self.get_url( auth, id )
42
- body = { reportId: id }
43
- response = request( auth, Service, 'getReportFileUrl' ,body)
44
- process( response, 'reportFilePath' ){ |x| x }
45
- end
46
-
47
- private
48
- def self.make_reportrequest( param )
49
- """
50
- make RepoerRequestType
51
- ==============
52
- @Input : :fields,:type,:level,:range,:unit,:device,:id_only,:startDate:endDate
53
- ==============
54
- Note:
55
- We cast [ type, level, range, unit,device ] from int to string.
56
- For more information please see those map at the begining of the file
57
- """
58
- requesttype = {}
59
- requesttype[:performanceData] = param[:fields] || %w(click impression)
60
- requesttype[:reportType] = Type_map[ param[:type] ] if param[:type]
61
- requesttype[:levelOfDetails] = Level_map[ param[:level] ] if param[:level]
62
- requesttype[:statRange] = Level_map[ param[:range] ] if param[:range]
63
- requesttype[:unitOfTime] = Unit_map[ param[:unit] ] if param[:unit]
64
- requesttype[:device] = Device_map[ param[:device] ] if param[:device]
65
- requesttype[:idOnly] = param[:id_only] || false
66
- requesttype[:startDate] = parse_date( param[:startDate] )
67
- requesttype[:endDate] = parse_date( param[:endDate] )
68
- return requesttype
69
- end
70
-
71
- private
72
- def self.parse_date( date )
73
- """
74
- Cast string to time:
75
- 'YYYYMMDD' => Time
76
- """
77
- if date
78
- y = date[0..3]
79
- m = date[4..5]
80
- d = date[6..7]
81
- date = Time.new( y, m, d )
82
- else
83
- date = (Time.now - 24*3600)
84
- end
85
- date
86
- end
87
-
88
- #################################
89
- # useful function for operation #
90
- #################################
91
- def self.query_report( auth, param = nil, debug = false )
92
- param = {} if not param
93
- param[:type] ||= 'query'
94
- param[:fields] ||= %w(click impression)
95
- param[:level] ||= 'pair'
96
- param[:range] ||= 'account'
97
- param[:unit] ||= 'day'
98
- download_report( auth, param, debug )
99
- end
100
-
101
- def self.creative_report( auth, param = nil, debug = false )
102
- param = {} if not param
103
- param[:type] ||= 'creative'
104
- param[:fields] ||= %w(impression click cpc cost ctr cpm position conversion)
105
- param[:level] ||= 'creative'
106
- param[:range] ||= 'creative'
107
- param[:unit] ||= 'day'
108
- download_report( auth, param, debug )
109
- end
110
-
111
- def self.keyword_report( auth, param = nil, debug = false )
112
- param = {} if not param
113
- param[:type] ||= 'keyword'
114
- param[:fields] ||= %w(impression click cpc cost ctr cpm position conversion)
115
- param[:level] ||= 'keywordid'
116
- param[:range] ||= 'keywordid'
117
- param[:unit] ||= 'day'
118
- download_report( auth, param, debug )
119
- end
120
-
121
- def self.download_report( auth, param, debug = false )
122
- p param
123
- response = get_id( auth, param )
124
- if response[:succ]
125
- id = response[:result]
126
- p "Got report id:" + id.to_s if debug
127
- loop do
128
- sleep 2
129
- break if get_state( auth, id )[:result] == 'Finished'
130
- p "Report is not generated, waiting..." if debug
131
- end
132
-
133
- url = get_url( auth, id )[:result]
134
- return open(url).read.force_encoding('gb18030').encode('utf-8')
135
- else
136
- raise response[:failure][0]["message"]
137
- end
138
- end
139
-
140
- end # Repost
141
- end # Baidu
142
- end # API
143
- end # PPC
data/lib/ppc/api/qihu.rb DELETED
@@ -1,107 +0,0 @@
1
- # -*- coding:utf-8 -*-
2
- require 'ppc/api/qihu/account'
3
- require 'ppc/api/qihu/plan'
4
- require 'ppc/api/qihu/group'
5
- require 'ppc/api/qihu/keyword'
6
- require 'ppc/api/qihu/creative'
7
- require 'ppc/api/qihu/report'
8
- require 'httparty'
9
- require 'json'
10
-
11
- module PPC
12
- module API
13
- class Qihu
14
-
15
- def self.request( auth, service, method, params = {} )
16
- url = "https://api.e.360.cn/2.0/#{service}/#{method}"
17
- # 日后考虑将httpparty用Net/http代替
18
- response = HTTParty.post(url,
19
- body: params,
20
- headers: {'apiKey' => auth[:token],
21
- 'accessToken' => auth[:accessToken],
22
- 'serveToken' => Time.now.to_i.to_s }
23
- )
24
- response.parsed_response
25
- end
26
-
27
- def self.process( response, key, failure_key = '', &func )
28
- response_key = response.keys[0]
29
- content = response[ response_key ]
30
- # special case solution
31
- if content == nil
32
- return{ succ:true, failure:nil, result:nil }
33
- end
34
-
35
- result = { }
36
- if content['failures'] != nil
37
- result[:succ] = false
38
- result[:failure] = content['failures']['item']
39
- result[:result] = nil
40
- else
41
- result[:succ] = true
42
- result[:result] = func[ key==''? content : content[ key ] ]
43
- result[:failure] = failure_key == ''? nil : content[ failure_key ]
44
- end
45
- return result
46
- end
47
-
48
- def self.to_json_string( items )
49
- '''
50
- convert list of string/int to list of json string
51
- '''
52
- return '' if items == nil
53
- items = [items] unless items.is_a? Array
54
- items_str = []
55
- items.each{ |x| items_str << x.to_s }
56
- items_str.to_json
57
- end
58
-
59
- def self.to_id_list( ids_str )
60
- return [] if ids_str == nil
61
- ids_str = [ids_str] unless ids_str.is_a? Array
62
- ids_i = []
63
- ids_str.each{ |id| ids_i<<id.to_i }
64
- ids_i
65
- end
66
-
67
- def self.make_type( params, map = @map)
68
- '''
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
-
86
- def self.reverse_type( types, map = @map )
87
- '''
88
- '''
89
- types = [ types ] unless types.is_a? Array
90
-
91
- params = []
92
- types.each do |type|
93
- param = {}
94
-
95
- map.each do |key|
96
- value = type[ key[1].to_s ]
97
- param[ key[0] ] = value if value != nil
98
- end
99
-
100
- params << param
101
- end
102
- return params
103
- end
104
-
105
- end
106
- end
107
- end
@@ -1,86 +0,0 @@
1
- # -*- coding:utf-8 -*-
2
- require 'json'
3
- module PPC
4
- module API
5
- class Qihu
6
- class Account < Qihu
7
- Service = 'account'
8
-
9
- @map = [
10
- [ :id, :uid ],
11
- [ :name, :userName ],
12
- [ :email, :email],
13
- [ :company, :companyName],
14
- [ :industry1, :industry1],
15
- [ :industry2, :industry2],
16
- [ :balance, :balance],
17
- [ :budget, :budget],
18
- [ :resources, :resources],
19
- [ :open_domains, :allowDomain]
20
- ]
21
-
22
- def self.info( auth )
23
- response = request( auth, Service, 'getInfo' )
24
- process( response, '' ){ |x| reverse_type( x )[0]}
25
- end
26
-
27
- def self.update( auth, params )
28
- '''
29
- 对奇虎两个update的在封装。如果所有操作成功,succ为true,否则为false
30
- failure中以字符串方式返回失败的操作
31
- '''
32
- result = {}
33
- result[:succ] = true
34
- result[:failure] = []
35
- result[:result] = []
36
-
37
- if params[:budget] != nil
38
- budget_result = update_budget( auth, params[:budget] )
39
- result[:succ] = result[:succ] && budget_result[:succ]
40
- result[:failure] << 'budget' unless budget_result[:succ]
41
- end
42
-
43
- if params[:exclude_ip] != nil
44
- ip_result = update_exclude_ip( auth, params[:exclude_ip] )
45
- result[:succ] = result[:succ] && ip_result[:succ]
46
- result[:failure] << 'exclude_ip' unless budget_result[:succ]
47
- end
48
-
49
- return result
50
- end
51
-
52
- def self.get_all_object( auth, ids )
53
- #文档上面写的输入类型是String?
54
- body = { 'idList' => ids }
55
- response = request( auth, Service, 'getAllObjects' )
56
- process( response, 'account_getAllObjects_response' ){ |x| x }
57
- end
58
-
59
- def self.get_file_state( auth, id )
60
- body = { 'fileId' => id }
61
- response = request( auth, Service, 'getAllObjects' , body )
62
- process( response, 'account_getFileState_response' ){ |x| x }
63
- end
64
-
65
- def self.get_exclude_ip( auth )
66
- response = request( auth, Service, 'getExcludeIp' )
67
- process( response, 'excludeIpList' ){ |x| x['item'] }
68
- end
69
-
70
- private
71
- def self.update_budget( auth, budget )
72
- response = request( auth, Service, 'updateBudget', { budget:budget })
73
- process( response, 'affectedRecords' ){ | x | x.to_i==1?'success':'failure' }
74
- end
75
-
76
- private
77
- def self.update_exclude_ip( auth, ips )
78
- ips = to_json_string( ips )
79
- response = request( auth, Service, 'updateExcludeIp', { excludeIpList: ips } )
80
- process( response, 'excludeIpList' ){ | x | x }
81
- end
82
-
83
- end
84
- end
85
- end
86
- end
@@ -1,106 +0,0 @@
1
- # -*- coding:utf-8 -*-
2
- module PPC
3
- module API
4
- class Qihu
5
- class Creative< Qihu
6
- Service = 'creative'
7
-
8
- @map = [
9
- [:id,:id] ,
10
- [:group_id, :groupId],
11
- [:title,:title],
12
- [:description1, :description1],
13
- [:description2, :description2],
14
- [:pc_destination, :destinationUrl],
15
- [:pc_display, :displayUrl]
16
- ]
17
-
18
- @status_map = [
19
- [:id,:id],
20
- [:quality,:qualityScore],
21
- [:status,:status]
22
- ]
23
-
24
- def self.get( auth, ids )
25
- body = { 'idList' => to_json_string( ids ) }
26
- response = request( auth, Service, 'getInfoByIdList', body )
27
- process( response, 'creativeList'){ |x| reverse_type( x['item'] ) }
28
- end
29
-
30
- def self.add( auth, creatives )
31
- creative_types = make_type( creatives ).to_json
32
- body = { 'creatives' => creative_types}
33
- response = request( auth, Service, 'add', body )
34
- process( response, 'creativeIdList'){ |x| to_id_hash_list( x['item'] ) }
35
- end
36
-
37
- # helper function for self.add() method
38
- private
39
- def self.to_id_hash_list( str )
40
- reuturn [] if str == nil
41
- str = [str] unless str.is_a?Array
42
- x= []
43
- str.each{ |i| x << { id: i.to_i } }
44
- return x
45
- end
46
-
47
- def self.update( auth, creatives )
48
- creative_types = make_type( creatives ).to_json
49
- body = { 'creatives' => creative_types}
50
- response = request( auth, Service, 'update', body )
51
- process( response, 'affectedRecords', 'failCreativeIds' ){ |x| x }
52
- end
53
-
54
- # 对update的再封装实现activate方法,未测试
55
- def self.activate( auth, ids )
56
- creatives = []
57
- ids.each{ |id| creatives << { id: id, status:'enable'} }
58
- update( auth, creatives )
59
- end
60
-
61
- def self.delete( auth, ids )
62
- ids = to_json_string( ids )
63
- body = { 'idList' => ids }
64
- response = request( auth, Service, 'deleteByIdList', body )
65
- process( response, 'affectedRecords' ){ |x|x }
66
- end
67
-
68
- def self.status( auth, ids )
69
- body = { idList: to_json_string( ids ) }
70
- response = request( auth, Service, 'getStatusByIdList', body )
71
- process( response, 'creativeList' ){ |x| reverse_type( x['item'], @status_map ) }
72
- end
73
-
74
- # quality 本质上和 status 在一个方法里面
75
- def self.quality( auth, ids )
76
- status( auth, ids)
77
- end
78
-
79
- def self.search_id_by_group_id( auth, id, status = nil)
80
- # 处理条件
81
- body = {}
82
- body['status'] = status if status
83
- body['groupId'] = id
84
- response = request( auth, Service, 'getIdListByGroupId', body )
85
- # 伪装成百度接口
86
- process( response, 'creativeIdList' ){
87
- |x|
88
- [ { group_id:id, creative_ids:to_id_list( x==nil ? nil: x['item'] ) } ]
89
- }
90
- end
91
-
92
- # combine two methods to provide another mether
93
- def self.search_by_group_id( auth, id )
94
- creative_ids = search_id_by_group_id( auth, id )
95
- response = get( auth , creative_ids )
96
- # 伪装成百度接口
97
- if response[:succ]
98
- response[:result] = [ { group_id:id, creatives:response[:result ] } ]
99
- end
100
- return response
101
- end
102
-
103
- end
104
- end
105
- end
106
- end