top_notify 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.
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +52 -0
- data/Rakefile +10 -0
- data/lib/top_notify.rb +57 -0
- data/lib/top_notify/connection.rb +30 -0
- data/lib/top_notify/consumer.rb +11 -0
- data/lib/top_notify/exception.rb +4 -0
- data/lib/top_notify/logger.rb +27 -0
- data/lib/top_notify/server.rb +39 -0
- data/lib/top_notify/sign.rb +10 -0
- data/lib/top_notify/version.rb +3 -0
- data/test/macros/config_macros.rb +9 -0
- data/test/test_helper.rb +11 -0
- data/test/unit/connection_test.rb +13 -0
- data/test/unit/consumer_test.rb +14 -0
- data/test/unit/logger_test.rb +26 -0
- data/test/unit/server_test.rb +13 -0
- data/test/unit/setup_test.rb +13 -0
- data/test/unit/sign_test.rb +15 -0
- data/top_notify.gemspec +27 -0
- metadata +155 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 kenshin54
|
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,52 @@
|
|
1
|
+
# TopNotify
|
2
|
+
|
3
|
+
TopNotify use to process notification stream from TOP. (http://open.taobao.com/doc/detail.htm?spm=0.0.0.198.PfQSxk&id=1065#s7)
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'top_notify'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install top_notify
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
configure your app_key and app_secret
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
TopNotify.setup do |config|
|
25
|
+
config.app_key = your_app_key
|
26
|
+
config.app_secret = your_app_secret
|
27
|
+
end
|
28
|
+
```
|
29
|
+
|
30
|
+
write your consumer
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
class MyConsumer < TopNotify::Consumer
|
34
|
+
def receive_msg(data)
|
35
|
+
# ... your code
|
36
|
+
end
|
37
|
+
end
|
38
|
+
```
|
39
|
+
|
40
|
+
start server
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
TopNotify::Server.new(MyConsumer.new).start
|
44
|
+
```
|
45
|
+
|
46
|
+
## Contributing
|
47
|
+
|
48
|
+
1. Fork it
|
49
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
50
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
51
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
52
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/lib/top_notify.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require "top_notify/version"
|
2
|
+
|
3
|
+
module TopNotify
|
4
|
+
|
5
|
+
TYPE = {
|
6
|
+
200 => {:method => :connected, :msg => "connect to taobao server"},
|
7
|
+
201 => {:method => :heartbreak, :msg => "receive heartbreak"},
|
8
|
+
202 => {:method => :receive_msg, :msg => "receive msg"},
|
9
|
+
203 => {:method => :discard_msg, :msg => "receive discard msg"},
|
10
|
+
101 => {:method => :connect_reach_max_time, :msg => "connection reach max time"},
|
11
|
+
102 => {:method => :server_upgrate, :msg => "taobao server under upgrade"},
|
12
|
+
103 => {:method => :server_rehash, :msg => "taobao server close the connection"},
|
13
|
+
104 => {:method => :client_kickoff, :msg => "client kickoff"},
|
14
|
+
105 => {:method => :server_kickoff, :msg => "server kickoff"},
|
15
|
+
0 => {:method => :unknown_msg, :msg => "unknown msg"}
|
16
|
+
}
|
17
|
+
|
18
|
+
class << self
|
19
|
+
|
20
|
+
def setup
|
21
|
+
yield self
|
22
|
+
end
|
23
|
+
|
24
|
+
def app_key=(app_key)
|
25
|
+
@app_key = app_key
|
26
|
+
end
|
27
|
+
|
28
|
+
def app_secret=(app_secret)
|
29
|
+
@app_secret = app_secret
|
30
|
+
end
|
31
|
+
|
32
|
+
def logger=(device)
|
33
|
+
@logger = device
|
34
|
+
end
|
35
|
+
|
36
|
+
def logger
|
37
|
+
@logger
|
38
|
+
end
|
39
|
+
|
40
|
+
def app_key
|
41
|
+
@app_key
|
42
|
+
end
|
43
|
+
|
44
|
+
def app_secret
|
45
|
+
@app_secret
|
46
|
+
end
|
47
|
+
|
48
|
+
def service_url
|
49
|
+
@service_url ||= 'http://stream.api.taobao.com/stream'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
require 'top_notify/server'
|
56
|
+
require 'top_notify/exception'
|
57
|
+
require 'top_notify/connection'
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'uri'
|
3
|
+
require 'top_notify/sign'
|
4
|
+
|
5
|
+
module TopNotify
|
6
|
+
class Connection
|
7
|
+
|
8
|
+
include Sign
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
if TopNotify.app_key.to_s.empty? || TopNotify.app_secret.to_s.empty?
|
12
|
+
raise ConfigurationNotFoundError.new('You need to set app_key and app_secret first before use top_notfiy.')
|
13
|
+
end
|
14
|
+
@params = {:app_key => TopNotify.app_key, :timestamp => Time.now.strftime('%F %T'), :sign_method => 'md5'}
|
15
|
+
@params.merge!(:sign => sign(@params))
|
16
|
+
@uri = URI.parse(TopNotify.service_url)
|
17
|
+
@request = Net::HTTP::Post.new(uri.request_uri)
|
18
|
+
@request.set_form_data(@params)
|
19
|
+
end
|
20
|
+
|
21
|
+
def uri
|
22
|
+
@uri
|
23
|
+
end
|
24
|
+
|
25
|
+
def request
|
26
|
+
@request
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module TopNotify
|
2
|
+
class Logger
|
3
|
+
def initialize(device)
|
4
|
+
@device = if device.respond_to?(:write)
|
5
|
+
device
|
6
|
+
else
|
7
|
+
File.open(device, 'a')
|
8
|
+
end
|
9
|
+
@device.sync = true if @device.respond_to?(:sync)
|
10
|
+
end
|
11
|
+
|
12
|
+
def log(msg)
|
13
|
+
@device.write(msg)
|
14
|
+
end
|
15
|
+
|
16
|
+
def log_stream(data, msg = nil)
|
17
|
+
content = "# #{time}"
|
18
|
+
content += " (#{msg})" if msg
|
19
|
+
content += " [#{data}]\n"
|
20
|
+
log content
|
21
|
+
end
|
22
|
+
|
23
|
+
def time
|
24
|
+
Time.now.strftime('%Y-%m-%d %H:%M:%S')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'uri'
|
3
|
+
require 'multi_json'
|
4
|
+
require 'top_notify/logger'
|
5
|
+
require 'top_notify/consumer'
|
6
|
+
|
7
|
+
module TopNotify
|
8
|
+
class Server
|
9
|
+
def initialize(consumer = Consumer.new)
|
10
|
+
@conn = Connection.new
|
11
|
+
@consumer = consumer
|
12
|
+
end
|
13
|
+
|
14
|
+
def start
|
15
|
+
Net::HTTP.start(@conn.uri.host, @conn.uri.port) do |http|
|
16
|
+
http.request @conn.request do |response|
|
17
|
+
if response.code.to_i == 400
|
18
|
+
raise ConfigurationError.new('Your configuration is not correct, please check it.')
|
19
|
+
end
|
20
|
+
response.read_body do |chunk|
|
21
|
+
data = MultiJson.load(chunk.strip)['packet']
|
22
|
+
result = TYPE[data['code'].to_i] || TYPE[0]
|
23
|
+
logger.log_stream(data, result[:msg])
|
24
|
+
@consumer.send(result[:method], data) if @consumer.respond_to?(result[:method])
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
def logger
|
32
|
+
@logger ||= if TopNotify.logger
|
33
|
+
Logger.new(TopNotify.logger)
|
34
|
+
else
|
35
|
+
Logger.new(STDOUT)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe TopNotify::Connection do
|
4
|
+
|
5
|
+
it "should raise exception when configuration not be set" do
|
6
|
+
proc { TopNotify::Connection.new }.must_raise(TopNotify::ConfigurationNotFoundError)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should create connection object successfully" do
|
10
|
+
config_setup
|
11
|
+
TopNotify::Connection.new.must_be_instance_of TopNotify::Connection
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe TopNotify::Consumer do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@consumer = TopNotify::Consumer.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should respond_to methods which define in TopNotify::TYPE" do
|
10
|
+
TopNotify::TYPE.each_pair do |code, const|
|
11
|
+
@consumer.must_respond_to const[:method]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe TopNotify::Logger do
|
4
|
+
|
5
|
+
it "should write to STDOUT" do
|
6
|
+
STDOUT.expects(:write).with("Foo!")
|
7
|
+
logger = TopNotify::Logger.new STDOUT
|
8
|
+
logger.log('Foo!')
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should write stream data" do
|
12
|
+
STDOUT.expects(:write).with("# 2012-12-22 11:00:00 (uoho) [#{{:foo => 'bar'}}]\n")
|
13
|
+
logger = TopNotify::Logger.new STDOUT
|
14
|
+
logger.stubs(:time).returns('2012-12-22 11:00:00')
|
15
|
+
logger.log_stream({:foo => 'bar'}, 'uoho')
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'file log' do
|
19
|
+
it "should write to file" do
|
20
|
+
File.any_instance.expects(:write).with('Foo!')
|
21
|
+
logger = TopNotify::Logger.new 'myfile.log'
|
22
|
+
logger.log('Foo!')
|
23
|
+
end
|
24
|
+
after { File.delete('myfile.log') }
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe TopNotify::Server do
|
4
|
+
before do
|
5
|
+
config_setup
|
6
|
+
@consumer = TopNotify::Consumer.new
|
7
|
+
@server = TopNotify::Server.new(@consumer)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should raise ConfigurationError" do
|
11
|
+
proc { @server.start }.must_raise TopNotify::ConfigurationError
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe TopNotify::Sign do
|
4
|
+
|
5
|
+
before do
|
6
|
+
config_setup
|
7
|
+
@dummy = Object.new
|
8
|
+
@dummy.extend(TopNotify::Sign)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should return signed string with params" do
|
12
|
+
params = {:app_key => TopNotify.app_key, :timestamp => Time.parse('2012/12/22'), :sign_method => 'md5'}
|
13
|
+
@dummy.sign(params).must_equal '33B18B20935190054796B67624B1AC3F'
|
14
|
+
end
|
15
|
+
end
|
data/top_notify.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'top_notify/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "top_notify"
|
8
|
+
gem.version = TopNotify::VERSION
|
9
|
+
gem.authors = ["kenshin54"]
|
10
|
+
gem.email = ["himurakenshin54@gmail.com"]
|
11
|
+
gem.description = %q{TopNotify use to process notification stream from TOP.}
|
12
|
+
gem.summary = %q{TopNotify use to process notification stream from TOP.}
|
13
|
+
gem.homepage = ""
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_development_dependency 'rake', '~> 0.9.2'
|
21
|
+
gem.add_development_dependency 'bundler', '~> 1.1'
|
22
|
+
gem.add_development_dependency 'minitest', '~> 3.3.0'
|
23
|
+
gem.add_development_dependency 'mocha', '~> 0.13.0'
|
24
|
+
|
25
|
+
|
26
|
+
gem.add_dependency "multi_json", "~> 1.3.7"
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: top_notify
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- kenshin54
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-12-03 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.9.2
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.9.2
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: bundler
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '1.1'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '1.1'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: minitest
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 3.3.0
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 3.3.0
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: mocha
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 0.13.0
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 0.13.0
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: multi_json
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 1.3.7
|
86
|
+
type: :runtime
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 1.3.7
|
94
|
+
description: TopNotify use to process notification stream from TOP.
|
95
|
+
email:
|
96
|
+
- himurakenshin54@gmail.com
|
97
|
+
executables: []
|
98
|
+
extensions: []
|
99
|
+
extra_rdoc_files: []
|
100
|
+
files:
|
101
|
+
- .gitignore
|
102
|
+
- Gemfile
|
103
|
+
- LICENSE.txt
|
104
|
+
- README.md
|
105
|
+
- Rakefile
|
106
|
+
- lib/top_notify.rb
|
107
|
+
- lib/top_notify/connection.rb
|
108
|
+
- lib/top_notify/consumer.rb
|
109
|
+
- lib/top_notify/exception.rb
|
110
|
+
- lib/top_notify/logger.rb
|
111
|
+
- lib/top_notify/server.rb
|
112
|
+
- lib/top_notify/sign.rb
|
113
|
+
- lib/top_notify/version.rb
|
114
|
+
- test/macros/config_macros.rb
|
115
|
+
- test/test_helper.rb
|
116
|
+
- test/unit/connection_test.rb
|
117
|
+
- test/unit/consumer_test.rb
|
118
|
+
- test/unit/logger_test.rb
|
119
|
+
- test/unit/server_test.rb
|
120
|
+
- test/unit/setup_test.rb
|
121
|
+
- test/unit/sign_test.rb
|
122
|
+
- top_notify.gemspec
|
123
|
+
homepage: ''
|
124
|
+
licenses: []
|
125
|
+
post_install_message:
|
126
|
+
rdoc_options: []
|
127
|
+
require_paths:
|
128
|
+
- lib
|
129
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
130
|
+
none: false
|
131
|
+
requirements:
|
132
|
+
- - ! '>='
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '0'
|
135
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
136
|
+
none: false
|
137
|
+
requirements:
|
138
|
+
- - ! '>='
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
141
|
+
requirements: []
|
142
|
+
rubyforge_project:
|
143
|
+
rubygems_version: 1.8.24
|
144
|
+
signing_key:
|
145
|
+
specification_version: 3
|
146
|
+
summary: TopNotify use to process notification stream from TOP.
|
147
|
+
test_files:
|
148
|
+
- test/macros/config_macros.rb
|
149
|
+
- test/test_helper.rb
|
150
|
+
- test/unit/connection_test.rb
|
151
|
+
- test/unit/consumer_test.rb
|
152
|
+
- test/unit/logger_test.rb
|
153
|
+
- test/unit/server_test.rb
|
154
|
+
- test/unit/setup_test.rb
|
155
|
+
- test/unit/sign_test.rb
|