sogou 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 34ca740ff610ccc11d870a62c19a27598d665774
4
+ data.tar.gz: 2c8c3d3e28e7243cfbf26fbbd7098c6ccca0614f
5
+ SHA512:
6
+ metadata.gz: 7ce3c4afc5e97a99795a243c41e0719a3bad53b16c97d9334efaed7443e13cf8e3c81ad2f84cef3fba778b86211df8a4a6073bb0ea92e47984880521bf314130
7
+ data.tar.gz: 307392307a8daaa544c8ef86fbec772db420963058aed0c13383ff6749058b45876bc3bccf730be8100f16adbc72c14b2808e2a6ae6a73836801fcf65801fc96
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
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
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://ruby.taobao.org'
2
+
3
+ # Specify your gem's dependencies in sogou.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 刘明
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,58 @@
1
+ # Sogou
2
+
3
+ Sogou SEM Services
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'sogou'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install sogou
18
+
19
+ ## Knowledge
20
+ camel命名法,用于request数据格式
21
+ snake命名法,用于response数据格式
22
+
23
+ ## Rspec
24
+ 先修改spec/spec_helper.rb
25
+
26
+ ```ruby
27
+
28
+ $username = ''
29
+ $password = ''
30
+ $token = ''
31
+
32
+ ```
33
+
34
+ ## Usage
35
+
36
+ SEM
37
+
38
+ ```ruby
39
+ require 'sogou'
40
+
41
+ auth = Sogou::Auth.new
42
+ auth.username = 'username'
43
+ auth.password = 'password'
44
+ auth.token = 'token'
45
+
46
+ ss = Sogou::SEM::SearchService.new(auth)
47
+ res = ss.getAccountInfo({})
48
+ res = ss.getAccountInfo({},true) #debug=true
49
+ ```
50
+
51
+
52
+ ## Contributing
53
+
54
+ 1. Fork it
55
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
56
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
57
+ 4. Push to the branch (`git push origin my-new-feature`)
58
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/lib/sogou/auth.rb ADDED
@@ -0,0 +1,5 @@
1
+ module Sogou
2
+ class Auth
3
+ attr_accessor :username,:password,:token
4
+ end
5
+ end
data/lib/sogou/ext.rb ADDED
@@ -0,0 +1,46 @@
1
+ class String
2
+ def snake_case
3
+ self.gsub(/::/, '/').
4
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
5
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
6
+ tr("-", "_").
7
+ downcase
8
+ end
9
+ end
10
+ class Savon
11
+ class Response
12
+ def header
13
+ hash[:envelope][:header]
14
+ end
15
+ def res_header
16
+ header[:res_header]
17
+ end
18
+ def desc
19
+ res_header[:desc]
20
+ end
21
+ def quota
22
+ res_header[:quota]
23
+ end
24
+ def rquota
25
+ res_header[:rquota]
26
+ end
27
+ def oprs
28
+ res_header[:oprs]
29
+ end
30
+ def oprtime
31
+ res_header[:oprtime]
32
+ end
33
+ def failures
34
+ res_header[:failures]
35
+ end
36
+ def code
37
+ failures[:code] if failures
38
+ end
39
+ def message
40
+ failures[:message] if failures
41
+ end
42
+ def status
43
+ res_header[:status]
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,15 @@
1
+ module Sogou
2
+ class Response
3
+ attr_accessor :header,:body,:rquota,:quota,:status,:desc,:oprs,:oprtime
4
+ def initialize(response,name_response_sym)
5
+ @header = response.header[:res_header]
6
+ @body = response.body[name_response_sym]
7
+ @rquota = @header[:rquota].to_i
8
+ @quota = @header[:quota].to_i
9
+ @status = @header[:status].to_i
10
+ @desc = @header[:desc]
11
+ @oprs = @header[:oprs]
12
+ @oprtime = @header[:oprtime]
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,6 @@
1
+ module Sogou
2
+ module SEM
3
+ class AccountService < Base
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Sogou
2
+ module SEM
3
+ class AdgroupService < Base
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,100 @@
1
+ module Sogou
2
+ module SEM
3
+ class Base
4
+ attr_accessor :username,:password,:token
5
+ attr_accessor :debug
6
+
7
+ def initialize(auth)
8
+ classname = self.class.name.split('::').last
9
+ @service_name =
10
+ case classname
11
+ when 'CampaignService'
12
+ 'CpcPlanService'
13
+ when 'AccountService'
14
+ 'AccountService'
15
+ when 'AdgroupService'
16
+ 'CpcGrpService'
17
+ when 'KeywordService'
18
+ 'CpcService'
19
+ when 'CreativeService'
20
+ 'CpcIdeaService'
21
+ when 'ReportService'
22
+ 'ReportService'
23
+ when 'DownloadService'
24
+ 'AccountDownloadService'
25
+ when 'KRService'
26
+ 'KRService'
27
+ end
28
+
29
+ @port_name = @service_name
30
+ @username = auth.username
31
+ @password = auth.password
32
+ @token = auth.token
33
+ @client = Savon.new("http://api.agent.sogou.com:8080/sem/sms/v1/#{@service_name}?wsdl")
34
+
35
+ # Savon.new(@base_uri+service_name+'?wsdl')
36
+ end
37
+ def method_missing(name, *args, &block)
38
+ options,debug = args[0],args[1]
39
+ options = {} if options.nil?
40
+ name = name.to_s
41
+ name_snake = name.snake_case
42
+ # p name
43
+
44
+
45
+ name_request_sym = (name +'Request').to_sym #if %w(getCampaignByCampaignId getAllCampaign addCampaign updateCampaign deleteCampaign).include?name
46
+ # puts name_request_sym
47
+ name_response_sym = (name+'Response').snake_case.to_sym
48
+ operation = make_operation(name)
49
+ operation.header = operation_header
50
+ operation.body = {
51
+ name_request_sym => options
52
+ }
53
+ ap operation.body if debug
54
+ puts operation.build if debug
55
+ response = operation.call
56
+ ap response if debug
57
+ # ap response.failures if debug
58
+ if response.failures
59
+ raise response.failures.to_s
60
+ else
61
+ Sogou::Response.new(response,name_response_sym)
62
+ end
63
+ end
64
+ def operations
65
+ @client.operations(@service_name,@port_name)
66
+ end
67
+
68
+ def make_operation(operation_name)
69
+ @client.operation(@service_name,@port_name,operation_name)
70
+ end
71
+
72
+ def operation_header
73
+ {
74
+ :AuthHeader=>
75
+ {
76
+ :username=>@username,
77
+ :password=>@password,
78
+ :token=>@token
79
+ }
80
+ }
81
+ end
82
+
83
+ def example(operation,with_header=false)
84
+ operation = make_operation(operation)
85
+ if with_header
86
+ {
87
+ :example_header => operation.example_header,
88
+ :example_body => operation.example_body
89
+ }
90
+ else
91
+ operation.example_body
92
+ end
93
+ end
94
+
95
+ # def invalid_options?(options,necessary_options)
96
+ # return true if necessary_options.any?{|necessary_option|!options.has_key?necessary_option}
97
+ # end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,6 @@
1
+ module Sogou
2
+ module SEM
3
+ class CampaignService < Base
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Sogou
2
+ module SEM
3
+ class CreativeService < Base
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,70 @@
1
+ module Sogou
2
+ module SEM
3
+ module Format
4
+ CSV = 2
5
+ end
6
+
7
+ module ReportState
8
+ PENDING = 1 #等待中
9
+ DOING = 2 #处理中
10
+ DONE = 3 #处理成功
11
+ end
12
+
13
+
14
+ module PerformanceData
15
+ COST = 'cost' #消费
16
+ CPC = 'cpc' #每个点击的消费
17
+ CLICK = 'click' #点击数
18
+ IMPRESSION = 'impression' #展示量
19
+ CTR = 'ctr' #转化率
20
+ CPM = 'cpm' #?
21
+ POSITION = 'position' #?
22
+ CONVERSION = 'conversion' #?
23
+ end
24
+
25
+ module LevelOfDetails
26
+ PORTFOLIO = 2 #账户粒度
27
+ CAMPAIGN = 3 #计划粒度
28
+ ADGROUP = 5 #单元粒度
29
+ CREATIVE = 7 #创意粒度
30
+ KEYWORDID = 11 #关键词(keywordid)粒度
31
+ KEYWORD = 12 #关键词(keywordid)+创意粒度
32
+ end
33
+
34
+ module ReportType
35
+ PORTFOLIO = 2 #账户
36
+ CAMPAIGN = 10 #计划
37
+ ADGROUP = 11 #单元
38
+ KEYWORDID = 14 #关键词(keywordid)
39
+ CREATIVE = 12 #创意
40
+ PAIR = 15 #配对
41
+ REGION = 3 #地域
42
+ QUERY = 6 #搜索词
43
+ WORD = 9 #关键词(wordid)
44
+ end
45
+
46
+ module StatRange #注意:统计范围不能细于当前的统计 粒度,例如统计粒度为计划,则统计 范围不能细到单元
47
+ PORTFOLIO = 2 #账户范围
48
+ CAMPAIGN = 3 #计划范围
49
+ ADGROUP = 5 #单元范围
50
+ CREATIVE = 7 #创意范围
51
+ KEYWORDID = 11 #关键词(keywordid)范围
52
+ WORD = 6 #关键词(wordid)范围
53
+ end
54
+
55
+ module UnitOfTime
56
+ DAY = 5 #分日
57
+ WEEK = 4 #分周
58
+ MONTH = 3 #分月
59
+ YEAR = 1 #分年
60
+ HOUR = 7 #分小时
61
+ TIME = 8 #请求时间段汇总(endDate-StartDate)
62
+ end
63
+
64
+ module Device
65
+ ALL = 0 #全部搜索推广设备
66
+ PC = 1 #仅计算机
67
+ MOBILE = 2 #仅移动 
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,6 @@
1
+ module Sogou
2
+ module SEM
3
+ class KeywordService < Base
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Sogou
2
+ module SEM
3
+ class ReportService < Base
4
+ end
5
+ end
6
+ end
data/lib/sogou/sem.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'sogou/sem/base'
2
+ require 'sogou/sem/account'
3
+ require 'sogou/sem/campaign'
4
+ require 'sogou/sem/adgroup'
5
+ require 'sogou/sem/keyword'
6
+ require 'sogou/sem/creative'
7
+ require 'sogou/sem/enum'
8
+ require 'sogou/sem/report'
@@ -0,0 +1,3 @@
1
+ module Sogou
2
+ VERSION = "0.0.1"
3
+ end
data/lib/sogou.rb ADDED
@@ -0,0 +1,11 @@
1
+ require "sogou/version"
2
+ require "sogou/auth"
3
+ require "sogou/sem"
4
+ require "sogou/response"
5
+ require "sogou/ext"
6
+ require 'savon'
7
+ require 'awesome_print'
8
+
9
+ module Sogou
10
+ # Your code goes here...
11
+ end
data/sogou.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'sogou/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "sogou"
8
+ spec.version = Sogou::VERSION
9
+ spec.authors = ["seoaqua"]
10
+ spec.email = ["seoaqua@me.com"]
11
+ spec.description = %q{sogou web services}
12
+ spec.summary = %q{sogou sem services}
13
+ spec.homepage = "http://github.com/seoaqua/sogou"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_dependency "savon","~> 3.0"
24
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe Sogou::SEM::AccountService do
4
+ subject{Sogou::SEM::AccountService.new($auth)}
5
+ let(:options){options = {}}
6
+ describe "#getAccountInfo" do
7
+ it "getAccountInfo" do
8
+ response = subject.getAccountInfo(options)
9
+ response.status.should == 0
10
+ response.desc.should == 'success'
11
+ # expect{ApiResponse.verify(response.body)}.not_to raise_error
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,120 @@
1
+ require 'spec_helper'
2
+
3
+ describe Sogou::SEM::AdgroupService do
4
+ subject{Sogou::SEM::AdgroupService.new($auth)}
5
+ describe '#getAllCpcGrpId' do
6
+ it "should return hash with correct format calling getAllCpcGrpId " do
7
+
8
+ response = subject.getAllCpcGrpId
9
+ response.status.should == 0
10
+ response.desc.should == 'success'
11
+ response.quota.should > 0
12
+ response.rquota.should > 0
13
+ # expect{ApiResponse.verify(response.body)}.not_to raise_error
14
+ # response.class.should == Hash
15
+ # response.should have_key :campaign_adgroup_ids
16
+ # response = response[:campaign_adgroup_ids]
17
+ # response.first.should have_key :campaign_id
18
+ # response.first.should have_key :adgroup_ids
19
+ # campaign_id = response.first[:campaign_id]
20
+ # campaign_id.to_i.to_s.should == campaign_id
21
+ # response.first[:adgroup_ids].class.should == Array
22
+ # adgroup_id = response.first[:adgroup_ids].first
23
+ # adgroup_id.to_i.to_s.should == adgroup_id
24
+ end
25
+ end
26
+
27
+ describe '#getCpcGrpByCpcGrpId' do
28
+ # subject{Sogou::SEM::AdgroupService.new($auth)}
29
+ it "should return hash with correct format calling getCpcGrpByCpcGrpId" do
30
+ response = subject.getCpcGrpByCpcGrpId({:cpcGrpIds=>[$adgroup_id]})
31
+ response.status.should == 0
32
+ response.desc.should == 'success'
33
+ response.quota.should > 0
34
+ response.rquota.should > 0
35
+ # expect{ApiResponse.verify(response.body)}.not_to raise_error
36
+ end
37
+ end
38
+
39
+ describe '#getCpcGrpIdByCpcPlanId' do
40
+ # subject{Sogou::SEM::AdgroupService.new($auth)}
41
+ it "should return hash with correct format calling getCpcGrpIdByCpcPlanId" do
42
+ response = subject.getCpcGrpIdByCpcPlanId({:cpcPlanIds=>[$campaign_id]})
43
+ response.status.should == 0
44
+ response.desc.should == 'success'
45
+ response.quota.should > 0
46
+ response.rquota.should > 0
47
+ # expect{ApiResponse.verify(response.body)}.not_to raise_error
48
+ # response.class.should == Hash
49
+ # response.should have_key :campaign_adgroups
50
+ end
51
+ end
52
+
53
+ # describe '#getAdgroupByAdgroupId' do
54
+ # # subject{Sogou::SEM::AdgroupService.new($auth)}
55
+ # it "should return hash with correct format calling getAdgroupByAdgroupId" do
56
+ # pending
57
+ # response = subject.getAdgroupByAdgroupId({:adgroupIds => $adgroup_ids})
58
+ # response.status.should == 0
59
+ # response.desc.should == 'success'
60
+ # response.quota.should == 2
61
+ # response.rquota.should > 0
62
+ # expect{ApiResponse.verify(response.body)}.not_to raise_error
63
+ # end
64
+ # end
65
+
66
+ describe '#addCpcGrp #updateCpcGrp #getCpcGrpByCpcGrpId #deleteCpcGrp' do
67
+ # subject {Sogou::SEM::AdgroupService.new($aut)}
68
+ it "is not ready yet" do
69
+ #addCpcGrp
70
+ adgroupType_add = {:cpcPlanId=>$campaign_id,:cpcGrpName=>'adgroupName1',:maxPrice=>2}
71
+
72
+ response = subject.addCpcGrp({:cpcGrpTypes => [adgroupType_add]})
73
+ response.status.should == 0
74
+ response.desc.should == 'success'
75
+ response.quota.should > 0
76
+ response.rquota.should > 0
77
+ # ap response.body
78
+ # expect{ApiResponse.verify(response.body)}.not_to raise_error
79
+
80
+ #parse and verify adgroup_id
81
+ adgroup_id = response.body[:cpc_grp_types][:cpc_grp_id]
82
+ adgroup_id.to_i.to_s.should == adgroup_id
83
+
84
+ #updateCpcGrp
85
+ adgroupType_update = {:cpcGrpId => adgroup_id, :cpcGrpName => 'adgroupName2'}
86
+ # ap adgroupType
87
+ response = subject.updateCpcGrp({:cpcGrpTypes=>[adgroupType_update]})
88
+ response.status.should == 0
89
+ response.desc.should == 'success'
90
+ response.quota.should > 0
91
+ response.rquota.should > 0
92
+ # ap response.body
93
+ # expect{ApiResponse.verify(response.body)}.not_to raise_error
94
+
95
+ #getCpcGrpByCpcGrpId
96
+ response = subject.getCpcGrpByCpcGrpId({:cpcGrpIds=>[adgroup_id]})
97
+ response.status.should == 0
98
+ response.desc.should == 'success'
99
+ response.quota.should >= 0
100
+ response.rquota.should > 0
101
+ # expect{ApiResponse.verify(response.body)}.not_to raise_error
102
+ # response.body[:adgroup_types][:adgroup_name].should == 'adgroupName2'
103
+
104
+
105
+ #deleteCpcGrp
106
+ response = subject.deleteCpcGrp({:cpcGrpIds => [adgroup_id]})
107
+ response.status.should == 0
108
+ response.desc.should == 'success'
109
+ response.quota.should > 0
110
+ response.rquota.should > 0
111
+ # ap response.body
112
+ # expect{ApiResponse.verify(response.body)}.not_to raise_error
113
+ # ap response.body
114
+ # it "is not implemented yet" do
115
+ # pending("this is pending before we have testing-purpose account")
116
+ # end
117
+ end
118
+ end
119
+
120
+ end
@@ -0,0 +1,94 @@
1
+ require 'spec_helper'
2
+ describe Sogou::SEM::CampaignService do
3
+ subject{Sogou::SEM::CampaignService.new($auth)}
4
+
5
+ describe '#addCampaign #updateCampaign #getCpcPlanByCpcPlanId #deleteCampaign' do
6
+ pending
7
+ it "should not raise errors when add, update, and delete a temp campaign" do
8
+ # ap subject.example('deleteCpcPlan')
9
+ # pending
10
+ #addCampaign
11
+ campaign_type_add = {
12
+ :cpcPlanName=> 'campaignName18',
13
+ :budget => '100',
14
+ :negativeWords => ['7day'],
15
+ :exactNegativeWords => ['7daysin']
16
+ }
17
+ options = {:cpcPlanTypes => [campaign_type_add]}
18
+ response = subject.addCpcPlan(options)
19
+ response.status.should == 0
20
+ response.desc.should == 'success'
21
+ response.quota.should == 1
22
+ response.rquota.should > 0
23
+ # expect{ApiResponse.verify(response.body)}.not_to raise_error
24
+ #parse and verify campaign_id
25
+ campaign_id = response.body[:cpc_plan_types][:cpc_plan_id]
26
+ campaign_id.to_i.to_s.should == campaign_id
27
+
28
+ #updateCpcPlan
29
+ campaign_type_update =
30
+ {
31
+ :cpcPlanId => campaign_id,
32
+ :cpcPlanName => 'campaignName19',
33
+ :budget => '101',
34
+ :negativeWords => ['8day'],
35
+ :exactNegativeWords => ['8daysin']
36
+ }
37
+ sleep 2
38
+ options = {:cpcPlanTypes => [campaign_type_update]}
39
+ response = subject.updateCpcPlan(options)
40
+ response.status.should == 0
41
+ response.desc.should == 'success'
42
+ response.quota.should == 1
43
+ response.rquota.should > 0
44
+ # expect{ApiResponse.verify(response.body)}.not_to raise_error
45
+ #check the result of updateCpcPlan by getCpcPlanByCpcPlanId
46
+ response = subject.getCpcPlanByCpcPlanId({:cpcPlanIds => [campaign_id]})
47
+ response.status.should == 0
48
+ response.desc.should == 'success'
49
+ response.quota.should == 1
50
+ response.rquota.should > 0
51
+ sleep 2
52
+ # expect{ApiResponse.verify(response.body)}.not_to raise_error
53
+ # ap response.body
54
+ response.body[:cpc_plan_types][:cpc_plan_name].should == 'campaignName19'
55
+ response.body[:cpc_plan_types][:budget].should == '101.0'
56
+ response.body[:cpc_plan_types][:negative_words].should == '8day'
57
+ response.body[:cpc_plan_types][:exact_negative_words].should == "8daysin"
58
+
59
+ #deleteCpcPlan
60
+ response = subject.deleteCpcPlan({:cpcPlanIds=>[campaign_id]})
61
+ response.status.should == 0
62
+ response.desc.should == 'success'
63
+ response.quota.should == 1
64
+ response.rquota.should > 0
65
+ # expect{ApiResponse.verify(response.body)}.not_to raise_error
66
+ end
67
+ end
68
+
69
+ # describe '#getCpcPlanByCpcPlanId' do
70
+ # it "getCpcPlanByCpcPlanId" do
71
+ # # puts '==============='
72
+ # # puts subject.example('getAllCampaign')
73
+ # # {:GetCampaignByCampaignIdRequest=>{:campaignIds=>["long"]}}
74
+ # # puts '==============='
75
+ # response = subject.getCpcPlanByCpcPlanId({:campaignIds=>[$campaign_id]})
76
+ # response.status.should == 0
77
+ # response.desc.should == 'success'
78
+ # response.quota.should == 2
79
+ # response.rquota.should > 0
80
+ # expect{ApiResponse.verify(response.body)}.not_to raise_error
81
+ # end
82
+ # end
83
+
84
+ describe '#getAllCpcPlan' do
85
+ it "getAllCpcPlan" do
86
+ response = subject.getAllCpcPlan({})
87
+ response.status.should == 0
88
+ response.desc.should == 'success'
89
+ response.quota.should > 0
90
+ response.rquota.should > 0
91
+ # expect{ApiResponse.verify(response.body)}.not_to raise_error
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+ require 'uri'
3
+ describe Sogou::SEM::CreativeService do
4
+ subject{Sogou::SEM::CreativeService.new($auth)}
5
+ let(:new_title){'新测试创意标题b'}
6
+ it '#addCpcIdea #updateCpcIdea #getCpcIdeaByCpcGrpId #deleteCreative' do
7
+ # ap subject.operations
8
+ # ap subject.example('deleteCpcIdea')
9
+ # pending
10
+ #addCpcIdea
11
+ creativeType = {
12
+ :cpcGrpId => $adgroup_id,
13
+ :title => '测试创意标题d',
14
+ :description1 => '测试创意首行测试创意首行测试创意首行',
15
+ :description2 => '测试创意次行测试创意次行测试创意次行',
16
+ :visitUrl => $pcDestinationUrl,
17
+ :showUrl=> URI($pcDestinationUrl).host,
18
+ :mobileVisitUrl => $mobileDestinationUrl,
19
+ :mobileShowUrl=> URI($mobileDestinationUrl).host
20
+ }
21
+ # {:creativeTypes=>[{
22
+ # :creativeId=>"long",
23
+ # :adgroupId=>"long",
24
+ # :title=>"string",
25
+ # :description1=>"string",
26
+ # :description2=>"string",
27
+ # :pcDestinationUrl=>"string",
28
+ # :pcDisplayUrl=>"string",
29
+ # :mobileDestinationUrl=>"string",
30
+ # :mobileDisplayUrl=>"string",
31
+ # :pause=>"boolean",
32
+ # :status=>"int"}]
33
+ # }
34
+ # }
35
+
36
+ # puts subject.example('addCpcIdea')
37
+ response = subject.addCpcIdea({:cpcIdeaTypes => [creativeType]})
38
+ response.status.should == 0
39
+ response.desc.should == 'success'
40
+ response.quota.should == 1
41
+ response.rquota.should > 0
42
+ # expect{ApiResponse.verify(response.body)}.not_to raise_error
43
+ creative_id = response.body[:cpc_idea_types][:cpc_idea_id]
44
+
45
+
46
+ # updateCpcIdea
47
+ sleep 3
48
+ creativeType = {
49
+ :cpcIdeaId=>creative_id,
50
+ :title => new_title,
51
+ :description1 => '艺龙酒店测试创意首行测试创意首行测试创意首行',
52
+ :description2 => '艺龙酒店测试创意首行测试创意首行测试创意次行',
53
+ :visitUrl => 'http://hotel.elong.com/beijing/'
54
+ }
55
+ response = subject.updateCpcIdea(:cpcIdeaTypes => [creativeType])
56
+ response.status.should == 0
57
+ response.desc.should == 'success'
58
+ response.quota.should == 1
59
+ response.rquota.should > 0
60
+ ap response.body
61
+ # expect{ApiResponse.verify(response.body)}.not_to raise_error
62
+
63
+ #getCpcIdeaByCpcGrpId
64
+ sleep 3
65
+ response = subject.getCpcIdeaByCpcGrpId(:cpcGrpIds => [creative_id])
66
+ response.status.should == 0
67
+ response.desc.should == 'success'
68
+ response.quota.should == 1
69
+ response.rquota.should > 0
70
+ ap response.body
71
+ response.body[:cpc_idea_types][:title].should == new_title
72
+ # expect{ApiResponse.verify(response.body)}.not_to raise_error
73
+
74
+ #deleteCpcIdea
75
+ response = subject.deleteCpcIdea({:cpcIdeaIds => [creative_id]})
76
+ response.status.should == 0
77
+ response.desc.should == 'success'
78
+ response.quota.should == 1
79
+ response.rquota.should > 0
80
+ # expect{ApiResponse.verify(response.body)}.not_to raise_error
81
+ end
82
+
83
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+ describe Sogou::SEM::KeywordService do
3
+ subject{Sogou::SEM::KeywordService.new($auth)}
4
+ let(:keyword_sample){'XJK测试关键词o'}
5
+ it "#addCpc #updateCpc #getCpcByCpcId #deleteCpc " do
6
+ # ap subject.example('updateCpc')
7
+ # pending
8
+ #addCpc
9
+ # puts $adgroup_id
10
+ keywordType = {:cpcGrpId => $adgroup_id,:cpc=>keyword_sample,:matchType => 1,:price => 1}
11
+ response = subject.addCpc({:cpcTypes => [keywordType]})
12
+ response.status.should == 0
13
+ response.desc.should == 'success'
14
+ response.quota.should == 1
15
+ response.rquota.should > 0
16
+ keyword_id = response.body[:cpc_types][:cpc_id]
17
+
18
+ #updateCpc
19
+ keywordType = {:cpcId=> keyword_id,:price => 2}
20
+ response = subject.updateCpc({:cpcTypes=>[keywordType]})
21
+ response.status.should == 0
22
+ response.desc.should == 'success'
23
+ response.quota.should == 1
24
+ response.rquota.should > 0
25
+
26
+ #getCpcByCpcId
27
+ sleep 3
28
+ response = subject.getCpcByCpcId({:cpcIds => [keyword_id]})
29
+ response.status.should == 0
30
+ response.desc.should == 'success'
31
+ response.quota.should == 1
32
+ response.rquota.should > 0
33
+ keyword = response.body[:cpc_types]
34
+ (keyword.is_a?Hash).should == true
35
+ keyword[:cpc_id].should == keyword_id
36
+ keyword[:cpc_grp_id].should == $adgroup_id
37
+ keyword[:cpc].should == keyword_sample
38
+ keyword[:price].should == "2.0"
39
+
40
+ #deleteCpc
41
+ sleep 3
42
+ response = subject.deleteCpc({:cpcIds => [keyword_id]})
43
+ response.status.should == 0
44
+ response.desc.should == 'success'
45
+ response.quota.should == 1
46
+ response.rquota.should > 0
47
+ # response.body[:result].should == '1'
48
+ end
49
+ end
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+ describe Sogou::SEM::ReportService do
3
+ subject{Sogou::SEM::ReportService.new($auth)}
4
+ it 'should not raise error on #getReportId #getReportState #getReportPath series test' do
5
+ pending('Report type and report range do not match')
6
+ #getReportId
7
+ options = {
8
+ :performanceData => [Sogou::SEM::PerformanceData::IMPRESSION, Sogou::SEM::PerformanceData::CLICK, Sogou::SEM::PerformanceData::CPC],
9
+ :startDate => (Time.now - 2*24*3600).utc.iso8601,
10
+ :endDate => (Time.now - 24*3600).utc.iso8601,
11
+ :statIds => [$campaign_id],
12
+ :idOnly => true
13
+ # :levelOfDetails => Sogou::SEM::LevelOfDetails::CAMPAIGN,
14
+ # :reportType => Sogou::SEM::ReportType::CAMPAIGN,
15
+ # :statRange => Sogou::SEM::StatRange::CAMPAIGN
16
+ }
17
+
18
+ response = subject.getReportId({:reportRequestType => options},true)
19
+ response.status.should == 0
20
+ response.desc.should == 'success'
21
+ response.quota.should == 2
22
+ response.rquota.should > 0
23
+
24
+ #parse report_id
25
+ report_id = response.body[:report_id]
26
+
27
+ #getReportState
28
+ try_count = 0
29
+ loop do
30
+ response = subject.getReportState({:reportId => report_id})
31
+ response.status.should == 0
32
+ response.desc.should == 'success'
33
+ response.quota.should == 2
34
+ response.rquota.should > 0
35
+ #verify is_generated status
36
+ is_generated = response.body[:is_generated]
37
+ break if is_generated == '3' or try_count > 10
38
+ sleep 1
39
+ try_count +=1
40
+ end
41
+
42
+
43
+ #getReportPath
44
+ response = subject.getReportPath({:reportId => report_id})
45
+ response.status.should == 0
46
+ response.desc.should == 'success'
47
+ response.quota.should == 2
48
+ response.rquota.should > 0
49
+
50
+ end
51
+
52
+ it "处理过期/无效id,应返回false" do
53
+ expect{subject.getReportState({:reportId=>'7da8438bc705c9e6e747959fafce91f2'}).body}.to raise_error
54
+ expect{subject.getReportState({:reportId=>'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'}).body}.to raise_error
55
+ end
56
+ end
@@ -0,0 +1,26 @@
1
+ require 'Sogou'
2
+ require 'time'
3
+ #请根据自己实际情况填写
4
+ $username = '' #用户名
5
+ $password = '' #密码
6
+ $token = '' #token
7
+ $auth = Sogou::Auth.new
8
+ $auth.username = $username
9
+ $auth.password = $password
10
+ $auth.token = $token
11
+ $startDate = (Time.now - 24*3600).utc.iso8601
12
+ $endDate = Time.now.utc.iso8601
13
+ $pcDestinationUrl = 'http://www.elong.com/'
14
+ $mobileDestinationUrl = 'http://www.elong.com/'
15
+
16
+
17
+ cs = Sogou::SEM::CampaignService.new($auth)
18
+ campaigns = cs.getAllCpcPlan
19
+ campaign = campaigns.body[:cpc_plan_types].first
20
+ $campaign_id = campaign[:cpc_plan_id]
21
+ $campaign_name = campaign[:cpc_plan_name]
22
+
23
+ ac = Sogou::SEM::AdgroupService.new($auth)
24
+
25
+ adgroups = ac.getCpcGrpByCpcPlanId({:cpcPlanIds=>[$campaign_id]})
26
+ $adgroup_id = adgroups.body[:cpc_plan_grps][:cpc_grp_types].first[:cpc_grp_id]
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sogou
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - seoaqua
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-10-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: savon
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description: sogou web services
56
+ email:
57
+ - seoaqua@me.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - .gitignore
63
+ - Gemfile
64
+ - LICENSE.txt
65
+ - README.md
66
+ - Rakefile
67
+ - lib/sogou.rb
68
+ - lib/sogou/auth.rb
69
+ - lib/sogou/ext.rb
70
+ - lib/sogou/response.rb
71
+ - lib/sogou/sem.rb
72
+ - lib/sogou/sem/account.rb
73
+ - lib/sogou/sem/adgroup.rb
74
+ - lib/sogou/sem/base.rb
75
+ - lib/sogou/sem/campaign.rb
76
+ - lib/sogou/sem/creative.rb
77
+ - lib/sogou/sem/enum.rb
78
+ - lib/sogou/sem/keyword.rb
79
+ - lib/sogou/sem/report.rb
80
+ - lib/sogou/version.rb
81
+ - sogou.gemspec
82
+ - spec/sem_account_spec.rb
83
+ - spec/sem_adgroup_spec.rb
84
+ - spec/sem_campaign_spec.rb
85
+ - spec/sem_creative_spec.rb
86
+ - spec/sem_keyword_spec.rb
87
+ - spec/sem_report_spec.rb
88
+ - spec/spec_helper.rb
89
+ homepage: http://github.com/seoaqua/sogou
90
+ licenses:
91
+ - MIT
92
+ metadata: {}
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - '>='
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubyforge_project:
109
+ rubygems_version: 2.1.5
110
+ signing_key:
111
+ specification_version: 4
112
+ summary: sogou sem services
113
+ test_files:
114
+ - spec/sem_account_spec.rb
115
+ - spec/sem_adgroup_spec.rb
116
+ - spec/sem_campaign_spec.rb
117
+ - spec/sem_creative_spec.rb
118
+ - spec/sem_keyword_spec.rb
119
+ - spec/sem_report_spec.rb
120
+ - spec/spec_helper.rb