sogou 0.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.
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