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,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