simple-feed 2.1.0 → 3.1.2
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 +4 -4
- data/.envrc +3 -0
- data/.github/workflows/rubocop.yml +20 -20
- data/.github/workflows/ruby.yml +19 -20
- data/.gitignore +2 -1
- data/.rubocop.yml +1 -1
- data/.rubocop_todo.yml +102 -33
- data/.travis.yml +3 -13
- data/CHANGELOG.md +120 -0
- data/Gemfile +2 -0
- data/README.adoc +197 -76
- data/Rakefile +1 -1
- data/codecov.yml +28 -0
- data/examples/shared/provider_example.rb +43 -25
- data/lib/simplefeed/activity/single_user.rb +2 -2
- data/lib/simplefeed/dsl/formatter.rb +67 -28
- data/lib/simplefeed/event.rb +48 -10
- data/lib/simplefeed/feed.rb +20 -9
- data/lib/simplefeed/providers/base/provider.rb +1 -1
- data/lib/simplefeed/providers/key.rb +57 -42
- data/lib/simplefeed/providers/proxy.rb +20 -7
- data/lib/simplefeed/providers/redis/driver.rb +2 -4
- data/lib/simplefeed/providers/redis/provider.rb +6 -6
- data/lib/simplefeed/providers.rb +0 -1
- data/lib/simplefeed/response.rb +3 -5
- data/lib/simplefeed/version.rb +1 -1
- data/lib/simplefeed.rb +20 -16
- data/man/running-example-redis-debug.png +0 -0
- data/man/running-example.png +0 -0
- data/man/sf-color-dump.png +0 -0
- data/simple-feed.gemspec +7 -2
- metadata +67 -13
- data/examples/hash_provider_example.rb +0 -24
- data/lib/simplefeed/key/template.rb +0 -48
- data/lib/simplefeed/key/type.rb +0 -28
- data/lib/simplefeed/providers/hash/paginator.rb +0 -33
- data/lib/simplefeed/providers/hash/provider.rb +0 -188
data/lib/simplefeed.rb
CHANGED
@@ -9,45 +9,49 @@ Hashie.logger = Logger.new(nil)
|
|
9
9
|
::Dir.glob(::File.expand_path('../simplefeed/*.rb', __FILE__)).each { |f| require_relative(f) }
|
10
10
|
|
11
11
|
require 'simplefeed/providers/redis'
|
12
|
-
require 'simplefeed/providers/hash'
|
13
12
|
require 'simplefeed/dsl'
|
13
|
+
require 'simplefeed/feed'
|
14
14
|
|
15
15
|
# Main namespace module for the SimpleFeed gem. It provides several shortcuts and entry
|
16
16
|
# points into the library, such as ability to define and fetch new feeds via +define+,
|
17
17
|
# and so on.
|
18
18
|
module SimpleFeed
|
19
|
+
TIME_FORMAT = '%Y-%m-%d %H:%M:%S.%L'
|
20
|
+
|
19
21
|
@registry = {}
|
20
22
|
|
21
23
|
class << self
|
22
|
-
# @return
|
24
|
+
# @return Hash<Symbol, Feed> the registry of the defined feeds
|
23
25
|
attr_reader :registry
|
24
26
|
|
25
|
-
# @param name
|
26
|
-
# @param options
|
27
|
+
# @param <Symbol> name of the feed
|
28
|
+
# @param <Hash> options any key-value pairs to set on the feed
|
27
29
|
#
|
28
|
-
# @return [Feed]
|
29
|
-
def define(name, **options
|
30
|
+
# @return [Feed] the feed with the given name, and defined via options and a block
|
31
|
+
def define(name, **options)
|
30
32
|
name = name.to_sym unless name.is_a?(Symbol)
|
31
|
-
|
32
|
-
|
33
|
-
|
33
|
+
|
34
|
+
registry[name] ||= Feed.new(name)
|
35
|
+
registry[name].tap do |feed|
|
36
|
+
feed.configure(options) do
|
37
|
+
yield(feed) if block_given?
|
38
|
+
end
|
34
39
|
end
|
35
|
-
registry[name] = feed
|
36
|
-
feed
|
37
40
|
end
|
38
41
|
|
39
|
-
# @
|
42
|
+
# @param [Symbol] name
|
43
|
+
# @return <Feed> the pre-defined feed with the given name
|
40
44
|
def get(name)
|
41
45
|
registry[name.to_sym]
|
42
46
|
end
|
43
47
|
|
44
48
|
# A factory method that constructs an instance of a provider based on the provider name and arguments.
|
45
49
|
#
|
46
|
-
# @param provider_name
|
47
|
-
# @
|
48
|
-
# @
|
50
|
+
# @param <Symbol> provider_name short name of the provider, eg, :redis, :hash, etc.
|
51
|
+
# @param <Array> args constructor array arguments of the provider
|
52
|
+
# @param <Hash, NilClass> opts constructor hash arguments of the provider
|
49
53
|
#
|
50
|
-
# @return
|
54
|
+
# @return <Provider>
|
51
55
|
def provider(provider_name, *args, **opts, &block)
|
52
56
|
provider_class = SimpleFeed::Providers.registry[provider_name]
|
53
57
|
raise ArgumentError, "No provider named #{provider_name} was found, #{SimpleFeed::Providers.registry.inspect}" unless provider_class
|
Binary file
|
data/man/running-example.png
CHANGED
Binary file
|
data/man/sf-color-dump.png
CHANGED
Binary file
|
data/simple-feed.gemspec
CHANGED
@@ -2,7 +2,8 @@
|
|
2
2
|
|
3
3
|
lib = File.expand_path('lib', __dir__)
|
4
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
-
|
5
|
+
# noinspection RubyResolve
|
6
|
+
load File.expand_path("#{lib}/simplefeed/version.rb")
|
6
7
|
|
7
8
|
Gem::Specification.new do |spec|
|
8
9
|
spec.name = 'simple-feed'
|
@@ -24,16 +25,20 @@ Gem::Specification.new do |spec|
|
|
24
25
|
spec.require_paths = ['lib']
|
25
26
|
|
26
27
|
spec.add_dependency 'activesupport'
|
28
|
+
spec.add_dependency 'awesome_print'
|
27
29
|
spec.add_dependency 'base62-rb'
|
28
30
|
spec.add_dependency 'colored2'
|
29
31
|
spec.add_dependency 'connection_pool', '~> 2'
|
30
32
|
spec.add_dependency 'hashie'
|
31
33
|
spec.add_dependency 'hiredis'
|
32
34
|
spec.add_dependency 'redis'
|
35
|
+
spec.add_dependency 'sorted_set'
|
36
|
+
spec.add_dependency 'tty-box'
|
37
|
+
spec.add_dependency 'tty-screen'
|
33
38
|
|
34
|
-
spec.add_development_dependency 'awesome_print'
|
35
39
|
spec.add_development_dependency 'bundler'
|
36
40
|
spec.add_development_dependency 'codeclimate-test-reporter'
|
41
|
+
spec.add_development_dependency 'codecov'
|
37
42
|
spec.add_development_dependency 'rake'
|
38
43
|
spec.add_development_dependency 'rspec'
|
39
44
|
spec.add_development_dependency 'rspec-its'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple-feed
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Konstantin Gredeskoul
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: awesome_print
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: base62-rb
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -109,13 +123,41 @@ dependencies:
|
|
109
123
|
- !ruby/object:Gem::Version
|
110
124
|
version: '0'
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
126
|
+
name: sorted_set
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
114
128
|
requirements:
|
115
129
|
- - ">="
|
116
130
|
- !ruby/object:Gem::Version
|
117
131
|
version: '0'
|
118
|
-
type: :
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: tty-box
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: tty-screen
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :runtime
|
119
161
|
prerelease: false
|
120
162
|
version_requirements: !ruby/object:Gem::Requirement
|
121
163
|
requirements:
|
@@ -150,6 +192,20 @@ dependencies:
|
|
150
192
|
- - ">="
|
151
193
|
- !ruby/object:Gem::Version
|
152
194
|
version: '0'
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: codecov
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - ">="
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '0'
|
202
|
+
type: :development
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - ">="
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: '0'
|
153
209
|
- !ruby/object:Gem::Dependency
|
154
210
|
name: rake
|
155
211
|
requirement: !ruby/object:Gem::Requirement
|
@@ -261,6 +317,7 @@ extensions: []
|
|
261
317
|
extra_rdoc_files: []
|
262
318
|
files:
|
263
319
|
- ".codeclimate.yml"
|
320
|
+
- ".envrc"
|
264
321
|
- ".github/workflows/rubocop.yml"
|
265
322
|
- ".github/workflows/ruby.yml"
|
266
323
|
- ".gitignore"
|
@@ -270,6 +327,7 @@ files:
|
|
270
327
|
- ".rubocop_todo.yml"
|
271
328
|
- ".travis.yml"
|
272
329
|
- ".yardopts"
|
330
|
+
- CHANGELOG.md
|
273
331
|
- Gemfile
|
274
332
|
- Guardfile
|
275
333
|
- LICENSE.txt
|
@@ -277,7 +335,7 @@ files:
|
|
277
335
|
- Rakefile
|
278
336
|
- bin/console
|
279
337
|
- bin/setup
|
280
|
-
-
|
338
|
+
- codecov.yml
|
281
339
|
- examples/redis_provider_example.rb
|
282
340
|
- examples/shared/provider_example.rb
|
283
341
|
- lib/simple-feed.rb
|
@@ -291,13 +349,9 @@ files:
|
|
291
349
|
- lib/simplefeed/dsl/formatter.rb
|
292
350
|
- lib/simplefeed/event.rb
|
293
351
|
- lib/simplefeed/feed.rb
|
294
|
-
- lib/simplefeed/key/template.rb
|
295
|
-
- lib/simplefeed/key/type.rb
|
296
352
|
- lib/simplefeed/providers.rb
|
297
353
|
- lib/simplefeed/providers/base/provider.rb
|
298
354
|
- lib/simplefeed/providers/hash.rb
|
299
|
-
- lib/simplefeed/providers/hash/paginator.rb
|
300
|
-
- lib/simplefeed/providers/hash/provider.rb
|
301
355
|
- lib/simplefeed/providers/key.rb
|
302
356
|
- lib/simplefeed/providers/proxy.rb
|
303
357
|
- lib/simplefeed/providers/redis.rb
|
@@ -316,7 +370,7 @@ homepage: https://github.com/kigster/simple-feed
|
|
316
370
|
licenses:
|
317
371
|
- MIT
|
318
372
|
metadata: {}
|
319
|
-
post_install_message:
|
373
|
+
post_install_message:
|
320
374
|
rdoc_options: []
|
321
375
|
require_paths:
|
322
376
|
- lib
|
@@ -331,8 +385,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
331
385
|
- !ruby/object:Gem::Version
|
332
386
|
version: '0'
|
333
387
|
requirements: []
|
334
|
-
rubygems_version: 3.
|
335
|
-
signing_key:
|
388
|
+
rubygems_version: 3.3.7
|
389
|
+
signing_key:
|
336
390
|
specification_version: 4
|
337
391
|
summary: Create multiple types of social networking activity feeds with simple-feed
|
338
392
|
gem, which uses a pluggable backend provider implementation, and ships with a Redis
|
@@ -1,24 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
# This is an executable example of working with a Redis feed, and storing
|
4
|
-
# events for various users.
|
5
|
-
#
|
6
|
-
# DEPENDENCIES:
|
7
|
-
# gem install colored2
|
8
|
-
# gem install awesome_print
|
9
|
-
#
|
10
|
-
# RUNNING
|
11
|
-
# ruby redis-feed.rb
|
12
|
-
#
|
13
|
-
|
14
|
-
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
15
|
-
|
16
|
-
require 'simplefeed'
|
17
|
-
|
18
|
-
@feed = SimpleFeed.define(:news) do |f|
|
19
|
-
f.provider = SimpleFeed.provider(:hash)
|
20
|
-
f.max_size = 1000
|
21
|
-
end
|
22
|
-
|
23
|
-
require_relative 'shared/provider_example'
|
24
|
-
|
@@ -1,48 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'base62-rb'
|
4
|
-
require 'hashie/mash'
|
5
|
-
|
6
|
-
module SimpleFeed
|
7
|
-
module Key
|
8
|
-
class TextTemplate < Struct.new(:text)
|
9
|
-
def render(params = {})
|
10
|
-
output = text.dup
|
11
|
-
params.each_pair do |key, value|
|
12
|
-
output.gsub!(/{{\s*#{key}\s*}}/, value.to_s)
|
13
|
-
end
|
14
|
-
output
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
DEFAULT_TEXT_TEMPLATE = TextTemplate.new('{{ namespace }}u.{{ base62_user_id }}.{{ key_marker }}')
|
19
|
-
|
20
|
-
class Template
|
21
|
-
attr_accessor :namespace, :key_types, :text_template
|
22
|
-
|
23
|
-
def initialize(namespace,
|
24
|
-
key_types = DEFAULT_TYPES,
|
25
|
-
text_template = DEFAULT_TEXT_TEMPLATE)
|
26
|
-
|
27
|
-
self.namespace = namespace
|
28
|
-
self.key_types = key_types
|
29
|
-
self.text_template = text_template
|
30
|
-
|
31
|
-
self.key_types.each do |type|
|
32
|
-
type.template ||= text_template if text_template
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def render_options
|
37
|
-
h = {}
|
38
|
-
h.merge!({ 'namespace' => namespace ? "#{namespace}|" : '' })
|
39
|
-
h
|
40
|
-
end
|
41
|
-
|
42
|
-
# Returns array of key names, such as [:meta, :data]
|
43
|
-
def key_names
|
44
|
-
key_types.map(&:name).map(&:to_s).sort
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
data/lib/simplefeed/key/type.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'template'
|
4
|
-
|
5
|
-
module SimpleFeed
|
6
|
-
module Key
|
7
|
-
class Type < Struct.new(:name, :marker)
|
8
|
-
attr_accessor :template
|
9
|
-
|
10
|
-
def initialize(name, marker, template = nil)
|
11
|
-
super(name, marker)
|
12
|
-
self.template = template
|
13
|
-
end
|
14
|
-
|
15
|
-
def render(opts = {})
|
16
|
-
template.render(opts.merge({ key_type: name,
|
17
|
-
key_marker: marker }))
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
DEFAULT_TYPES = [
|
22
|
-
{ name: :data, marker: 'd' },
|
23
|
-
{ name: :meta, marker: 'm' }
|
24
|
-
].map do |type|
|
25
|
-
Type.new(type[:name], type[:marker], DEFAULT_TEXT_TEMPLATE)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module SimpleFeed
|
4
|
-
module Providers
|
5
|
-
module Hash
|
6
|
-
# Include this module into any provider etc that has access to the +feed.fetch+
|
7
|
-
# methods, and it will provide +paginate+ method based on all.
|
8
|
-
#
|
9
|
-
# Of course this is not very efficient, because it requires fetching all events for the user.
|
10
|
-
module Paginator
|
11
|
-
def paginate(user_ids:, page: nil, per_page: feed.per_page, &block)
|
12
|
-
response = feed.fetch(user_ids: user_ids)
|
13
|
-
response = SimpleFeed::Response.new(response.to_h)
|
14
|
-
response.transform do |*, events|
|
15
|
-
paginate_items(order_events(events, &block), page: page, per_page: per_page)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def paginate_items(items, page: nil, per_page: nil)
|
20
|
-
page && page > 0 ? items[((page - 1) * per_page)...(page * per_page)] : items
|
21
|
-
end
|
22
|
-
|
23
|
-
def order_events(events, &block)
|
24
|
-
return nil unless events
|
25
|
-
|
26
|
-
events.sort do |a, b|
|
27
|
-
block ? yield(a, b) : b.at <=> a.at
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
@@ -1,188 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'base62-rb'
|
4
|
-
require 'hashie'
|
5
|
-
require 'set'
|
6
|
-
require 'objspace'
|
7
|
-
|
8
|
-
require 'simplefeed/event'
|
9
|
-
require_relative 'paginator'
|
10
|
-
require_relative '../key'
|
11
|
-
require_relative '../base/provider'
|
12
|
-
|
13
|
-
module SimpleFeed
|
14
|
-
module Providers
|
15
|
-
module Hash
|
16
|
-
class Provider < ::SimpleFeed::Providers::Base::Provider
|
17
|
-
attr_accessor :h
|
18
|
-
|
19
|
-
include SimpleFeed::Providers::Hash::Paginator
|
20
|
-
|
21
|
-
def self.from_yaml(file)
|
22
|
-
new(YAML.parse(File.read(file)))
|
23
|
-
end
|
24
|
-
|
25
|
-
def initialize(opts)
|
26
|
-
self.h = {}
|
27
|
-
h.merge!(opts)
|
28
|
-
end
|
29
|
-
|
30
|
-
def store(user_ids:, value:, at: Time.now)
|
31
|
-
event = create_event(value, at)
|
32
|
-
with_response_batched(user_ids) do |key|
|
33
|
-
add_event(event, key)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def delete(user_ids:, value:, at: nil)
|
38
|
-
event = create_event(value, at)
|
39
|
-
with_response_batched(user_ids) do |key|
|
40
|
-
changed_activity_size?(key) do
|
41
|
-
__delete(key, event)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def delete_if(user_ids:)
|
47
|
-
with_response_batched(user_ids) do |key|
|
48
|
-
activity(key).map do |event|
|
49
|
-
if yield(event, key.user_id)
|
50
|
-
__delete(key, event)
|
51
|
-
event
|
52
|
-
end
|
53
|
-
end.compact
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def wipe(user_ids:)
|
58
|
-
with_response_batched(user_ids) do |key|
|
59
|
-
deleted = !activity(key).empty?
|
60
|
-
wipe_user_record(key)
|
61
|
-
deleted
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
def paginate(user_ids:,
|
66
|
-
page:,
|
67
|
-
per_page: feed.per_page,
|
68
|
-
with_total: false,
|
69
|
-
reset_last_read: false)
|
70
|
-
|
71
|
-
reset_last_read_value(user_ids: user_ids, at: reset_last_read) if reset_last_read
|
72
|
-
|
73
|
-
with_response_batched(user_ids) do |key|
|
74
|
-
activity = activity(key)
|
75
|
-
result = page && page > 0 ? activity[((page - 1) * per_page)...(page * per_page)] : activity
|
76
|
-
with_total ? { events: result, total_count: activity.length } : result
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def fetch(user_ids:, since: nil, reset_last_read: false)
|
81
|
-
response = with_response_batched(user_ids) do |key|
|
82
|
-
if since == :unread
|
83
|
-
activity(key).reject { |event| event.at < user_record(key).last_read.to_f }
|
84
|
-
elsif since
|
85
|
-
activity(key).reject { |event| event.at < since.to_f }
|
86
|
-
else
|
87
|
-
activity(key)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
reset_last_read_value(user_ids: user_ids, at: reset_last_read) if reset_last_read
|
91
|
-
|
92
|
-
response
|
93
|
-
end
|
94
|
-
|
95
|
-
def reset_last_read(user_ids:, at: Time.now)
|
96
|
-
with_response_batched(user_ids) do |key|
|
97
|
-
user_record(key)[:last_read] = at
|
98
|
-
at
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
def total_count(user_ids:)
|
103
|
-
with_response_batched(user_ids) do |key|
|
104
|
-
activity(key).size
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
def unread_count(user_ids:)
|
109
|
-
with_response_batched(user_ids) do |key|
|
110
|
-
activity(key).count { |event| event.at > user_record(key).last_read.to_f }
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
def last_read(user_ids:)
|
115
|
-
with_response_batched(user_ids) do |key|
|
116
|
-
user_record(key).last_read
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
def total_memory_bytes
|
121
|
-
ObjectSpace.memsize_of(h)
|
122
|
-
end
|
123
|
-
|
124
|
-
def total_users
|
125
|
-
h.size
|
126
|
-
end
|
127
|
-
|
128
|
-
private
|
129
|
-
|
130
|
-
#===================================================================
|
131
|
-
# Methods below operate on a single user only
|
132
|
-
#
|
133
|
-
|
134
|
-
def changed_activity_size?(key)
|
135
|
-
ua = activity(key)
|
136
|
-
size_before = ua.size
|
137
|
-
yield(key, ua)
|
138
|
-
size_after = activity(key).size
|
139
|
-
(size_before > size_after)
|
140
|
-
end
|
141
|
-
|
142
|
-
def create_user_record
|
143
|
-
Hashie::Mash.new(
|
144
|
-
{ last_read: 0, activity: SortedSet.new }
|
145
|
-
)
|
146
|
-
end
|
147
|
-
|
148
|
-
def user_record(key)
|
149
|
-
h[key.data] ||= create_user_record
|
150
|
-
end
|
151
|
-
|
152
|
-
def wipe_user_record(key)
|
153
|
-
h[key.data] = create_user_record
|
154
|
-
end
|
155
|
-
|
156
|
-
def activity(key, event = nil)
|
157
|
-
user_record(key)[:activity] << event if event
|
158
|
-
user_record(key)[:activity].to_a
|
159
|
-
end
|
160
|
-
|
161
|
-
def add_event(event, key)
|
162
|
-
uas = user_record(key)[:activity]
|
163
|
-
if uas.include?(event)
|
164
|
-
false
|
165
|
-
else
|
166
|
-
uas << event.dup
|
167
|
-
if uas.size > feed.max_size
|
168
|
-
uas.delete(uas.to_a.last)
|
169
|
-
end
|
170
|
-
true
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
|
-
def __last_read(key, _value = nil)
|
175
|
-
user_record(key)[:last_read]
|
176
|
-
end
|
177
|
-
|
178
|
-
def __delete(key, event)
|
179
|
-
user_record(key)[:activity].delete(event)
|
180
|
-
end
|
181
|
-
|
182
|
-
def create_event(*args, **opts)
|
183
|
-
::SimpleFeed::Event.new(*args, **opts)
|
184
|
-
end
|
185
|
-
end
|
186
|
-
end
|
187
|
-
end
|
188
|
-
end
|