faye_tracking 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 +7 -0
- data/.gitignore +14 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +47 -0
- data/Rakefile +2 -0
- data/faye_tracking.gemspec +27 -0
- data/lib/faye_tracking/version.rb +3 -0
- data/lib/faye_tracking.rb +45 -0
- data/spec/faye_tracking/abstract_store.rb +23 -0
- data/spec/faye_tracking/faye_extension.rb +27 -0
- data/spec/faye_tracking/faye_extension_spec.rb +4 -0
- data/spec/faye_tracking/redis_store.rb +27 -0
- data/spec/faye_tracking/tracker.rb +33 -0
- data/spec/faye_tracking_spec.rb +60 -0
- data/spec/spec_helper.rb +12 -0
- metadata +138 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2d0123db7eee9e890395eddb139417be75a34c2e
|
4
|
+
data.tar.gz: 7c3500c63e854c2682d09380e186a7964f882bbe
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7170d0eedd7970a7a40a9cf6d9bca655838d2ee52eae058557da61aa49fe9946124cf4d43633d8ba11987ba253e474425c83762653c143b42ff65c833e606a76
|
7
|
+
data.tar.gz: b125a07324654a66d5201893bec935e04f53d19368af8e9f17ab11cd4d7ed0caeb816261b3f1b651647c6b8b2f62ee1be3c6600553c2759c16adbba4274d4bcf
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Lin He
|
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,47 @@
|
|
1
|
+
# FayeTracking
|
2
|
+
|
3
|
+
A Faye extension for tracking user subscriptions, i.e. can be used for
|
4
|
+
checking if a user is online.
|
5
|
+
|
6
|
+
## Prerequisites
|
7
|
+
|
8
|
+
* Faye
|
9
|
+
* Redis
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Add this line to your application's Gemfile:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
gem 'faye_tracking'
|
17
|
+
```
|
18
|
+
|
19
|
+
And then execute:
|
20
|
+
|
21
|
+
$ bundle
|
22
|
+
|
23
|
+
Or install it yourself as:
|
24
|
+
|
25
|
+
$ gem install faye_tracking
|
26
|
+
|
27
|
+
## Usage
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
FayeTracking.configure do |config|
|
31
|
+
config.redis = Redis.new
|
32
|
+
end
|
33
|
+
|
34
|
+
FayeTracking.all_users_in_channel('/chat/1')
|
35
|
+
FayeTracking.user_in_any_channel?('/user_1')
|
36
|
+
FayeTracking.user_in_channel?('/user_1', '/chat/1')
|
37
|
+
|
38
|
+
client.add_extension(FayeTracking.faye_extension)
|
39
|
+
```
|
40
|
+
|
41
|
+
## Contributing
|
42
|
+
|
43
|
+
1. Fork it ( https://github.com/he9lin/faye_tracking/fork )
|
44
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
45
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
46
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
47
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'faye_tracking/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "faye_tracking"
|
8
|
+
spec.version = FayeTracking::VERSION
|
9
|
+
spec.authors = ["Lin He"]
|
10
|
+
spec.email = ["he9lin@gmail.com"]
|
11
|
+
spec.summary = %q{Faye extension for tracking user subscriptions}
|
12
|
+
spec.description = %q{Faye extension for tracking user subscriptions, i.e. can be used for checking if a user is online.}
|
13
|
+
spec.homepage = "https://github.com/he9lin/faye_tracking"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
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_runtime_dependency "redis", "~> 3.0"
|
22
|
+
|
23
|
+
spec.add_development_dependency "redis-namespace", "~> 1.5"
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
25
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
26
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
27
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'redis'
|
2
|
+
require 'redis-namespace'
|
3
|
+
require "faye_tracking/version"
|
4
|
+
|
5
|
+
module FayeTracking
|
6
|
+
class << self
|
7
|
+
attr_accessor :redis
|
8
|
+
|
9
|
+
def configure(&block)
|
10
|
+
block.call(self)
|
11
|
+
end
|
12
|
+
|
13
|
+
def reset_store
|
14
|
+
redis.keys('*').each {|k| redis.del k}
|
15
|
+
end
|
16
|
+
|
17
|
+
def faye_extension
|
18
|
+
@_faye_extension ||= FayeExtension.new(tracker)
|
19
|
+
end
|
20
|
+
|
21
|
+
def user_in_any_channel?(user)
|
22
|
+
!tracker.channels_for_user(user).empty?
|
23
|
+
end
|
24
|
+
|
25
|
+
def user_in_channel?(user, channel)
|
26
|
+
tracker.user_in_channel?(user, channel)
|
27
|
+
end
|
28
|
+
|
29
|
+
def all_users_in_channel(channel)
|
30
|
+
tracker.users_in_channel(channel)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def tracker
|
36
|
+
raise 'redis is not set' unless redis
|
37
|
+
@_tracker ||= Tracker.new(RedisStore.new(redis))
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
require "faye_tracking/faye_extension"
|
43
|
+
require "faye_tracking/abstract_store"
|
44
|
+
require "faye_tracking/redis_store"
|
45
|
+
require "faye_tracking/tracker"
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module FayeTracking
|
2
|
+
class AbstractStore
|
3
|
+
def add(key, value)
|
4
|
+
raise NotImplementedError
|
5
|
+
end
|
6
|
+
|
7
|
+
def remove(key, value)
|
8
|
+
raise NotImplementedError
|
9
|
+
end
|
10
|
+
|
11
|
+
def member?(key, value)
|
12
|
+
raise NotImplementedError
|
13
|
+
end
|
14
|
+
|
15
|
+
def members(key)
|
16
|
+
raise NotImplementedError
|
17
|
+
end
|
18
|
+
|
19
|
+
def empty?(key)
|
20
|
+
raise NotImplementedError
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module FayeTracking
|
2
|
+
class FayeExtension
|
3
|
+
MONITORED_CHANNELS = [ '/meta/subscribe', '/meta/disconnect' ]
|
4
|
+
|
5
|
+
def initialize(tracker)
|
6
|
+
@tracker = tracker
|
7
|
+
end
|
8
|
+
|
9
|
+
def incoming(message, callback)
|
10
|
+
return callback.call(message) unless MONITORED_CHANNELS.include? message['channel']
|
11
|
+
|
12
|
+
unless message['error']
|
13
|
+
subs_channel = message['subscription']
|
14
|
+
app_client_id = message['ext']['faye_tracking_client_id']
|
15
|
+
|
16
|
+
case message['channel']
|
17
|
+
when '/meta/subscribe'
|
18
|
+
@tracker.add(subs_channel, app_client_id)
|
19
|
+
when '/meta/disconnect'
|
20
|
+
@tracker.remove(subs_channel, app_client_id)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
callback.call(message)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module FayeTracking
|
2
|
+
class RedisStore < AbstractStore
|
3
|
+
def initialize(redis)
|
4
|
+
@redis = redis
|
5
|
+
end
|
6
|
+
|
7
|
+
def add(key, value)
|
8
|
+
@redis.sadd key, value
|
9
|
+
end
|
10
|
+
|
11
|
+
def remove(key, value)
|
12
|
+
@redis.srem key, value
|
13
|
+
end
|
14
|
+
|
15
|
+
def member?(key, value)
|
16
|
+
@redis.sismember key, value
|
17
|
+
end
|
18
|
+
|
19
|
+
def members(key)
|
20
|
+
@redis.smembers key
|
21
|
+
end
|
22
|
+
|
23
|
+
def empty?(key)
|
24
|
+
@redis.smembers(key).empty?
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module FayeTracking
|
2
|
+
class Tracker
|
3
|
+
def initialize(store)
|
4
|
+
@store = store
|
5
|
+
end
|
6
|
+
|
7
|
+
def add(channel, user)
|
8
|
+
@store.add(channel, user)
|
9
|
+
@store.add(user, channel)
|
10
|
+
end
|
11
|
+
|
12
|
+
def remove(channel, user)
|
13
|
+
@store.remove(channel, user)
|
14
|
+
@store.remove(user, channel)
|
15
|
+
end
|
16
|
+
|
17
|
+
def channels_for_user(user)
|
18
|
+
@store.members(user)
|
19
|
+
end
|
20
|
+
|
21
|
+
def users_in_channel(channel)
|
22
|
+
@store.members(channel)
|
23
|
+
end
|
24
|
+
|
25
|
+
def user_in_channel?(user, channel)
|
26
|
+
@store.member?(user, channel)
|
27
|
+
end
|
28
|
+
|
29
|
+
def channel_has_user?(channel, user)
|
30
|
+
@store.member?(channel, user)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe FayeTracking do
|
4
|
+
before(:each) do
|
5
|
+
FayeTracking.reset_store
|
6
|
+
end
|
7
|
+
|
8
|
+
def faye_run(meta_action, channel, user)
|
9
|
+
message = {"channel" => meta_action, "ext" => {}}
|
10
|
+
message["subscription"] = channel
|
11
|
+
message["ext"]["faye_tracking_client_id"] = user
|
12
|
+
FayeTracking.faye_extension.incoming(message, lambda { |m| m })
|
13
|
+
end
|
14
|
+
|
15
|
+
def faye_subscribe(channel, user)
|
16
|
+
faye_run('/meta/subscribe', channel, user)
|
17
|
+
end
|
18
|
+
|
19
|
+
def faye_disconnect(channel, user)
|
20
|
+
faye_run('/meta/disconnect', channel, user)
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'subscribing to a channel' do
|
24
|
+
before do
|
25
|
+
faye_subscribe 'room', 'user_1'
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'adds user to the subscription channel' do
|
29
|
+
expect(described_class.user_in_any_channel?('user_1')).to be_truthy
|
30
|
+
expect(described_class.user_in_channel?('user_1', 'room')).to be_truthy
|
31
|
+
expect(described_class.user_in_channel?('user_2', 'room')).to be_falsey
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'returns all users in a channel' do
|
35
|
+
faye_subscribe 'room', 'user_2'
|
36
|
+
expect(described_class.all_users_in_channel('room')).to match_array(['user_1', 'user_2'])
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'disconnecting to a channel' do
|
41
|
+
before do
|
42
|
+
faye_subscribe 'room', 'user_1'
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'removes a user from a subscription channel' do
|
46
|
+
faye_disconnect 'room', 'user_1'
|
47
|
+
expect(described_class.user_in_any_channel?('user_1')).to be_falsey
|
48
|
+
expect(described_class.all_users_in_channel('rooom')).to eq([])
|
49
|
+
|
50
|
+
faye_subscribe 'room', 'user_2'
|
51
|
+
expect(described_class.user_in_any_channel?('user_2')).to be_truthy
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'does not raise error when removing a non-existing user' do
|
55
|
+
expect {
|
56
|
+
faye_disconnect 'room', 'user_2'
|
57
|
+
}.to_not raise_error
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.join File.dirname(__FILE__), '..', 'lib')
|
2
|
+
|
3
|
+
require 'faye_tracking'
|
4
|
+
|
5
|
+
FayeTracking.configure do |config|
|
6
|
+
config.redis = Redis::Namespace.new(:faye_tracking_test, redis: Redis.new)
|
7
|
+
end
|
8
|
+
|
9
|
+
RSpec.configure do |config|
|
10
|
+
config.filter_run focus: true
|
11
|
+
config.run_all_when_everything_filtered = true
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: faye_tracking
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Lin He
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-06-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: redis
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: redis-namespace
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.5'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.5'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.7'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.7'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.0'
|
83
|
+
description: Faye extension for tracking user subscriptions, i.e. can be used for
|
84
|
+
checking if a user is online.
|
85
|
+
email:
|
86
|
+
- he9lin@gmail.com
|
87
|
+
executables: []
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files: []
|
90
|
+
files:
|
91
|
+
- ".gitignore"
|
92
|
+
- Gemfile
|
93
|
+
- LICENSE.txt
|
94
|
+
- README.md
|
95
|
+
- Rakefile
|
96
|
+
- faye_tracking.gemspec
|
97
|
+
- lib/faye_tracking.rb
|
98
|
+
- lib/faye_tracking/version.rb
|
99
|
+
- spec/faye_tracking/abstract_store.rb
|
100
|
+
- spec/faye_tracking/faye_extension.rb
|
101
|
+
- spec/faye_tracking/faye_extension_spec.rb
|
102
|
+
- spec/faye_tracking/redis_store.rb
|
103
|
+
- spec/faye_tracking/tracker.rb
|
104
|
+
- spec/faye_tracking_spec.rb
|
105
|
+
- spec/spec_helper.rb
|
106
|
+
homepage: https://github.com/he9lin/faye_tracking
|
107
|
+
licenses:
|
108
|
+
- MIT
|
109
|
+
metadata: {}
|
110
|
+
post_install_message:
|
111
|
+
rdoc_options: []
|
112
|
+
require_paths:
|
113
|
+
- lib
|
114
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
requirements: []
|
125
|
+
rubyforge_project:
|
126
|
+
rubygems_version: 2.4.5
|
127
|
+
signing_key:
|
128
|
+
specification_version: 4
|
129
|
+
summary: Faye extension for tracking user subscriptions
|
130
|
+
test_files:
|
131
|
+
- spec/faye_tracking/abstract_store.rb
|
132
|
+
- spec/faye_tracking/faye_extension.rb
|
133
|
+
- spec/faye_tracking/faye_extension_spec.rb
|
134
|
+
- spec/faye_tracking/redis_store.rb
|
135
|
+
- spec/faye_tracking/tracker.rb
|
136
|
+
- spec/faye_tracking_spec.rb
|
137
|
+
- spec/spec_helper.rb
|
138
|
+
has_rdoc:
|