simple-feed 2.1.0 → 3.2.0

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.
@@ -1,12 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'redis'
4
- require 'redis/connection/hiredis'
5
4
  require 'connection_pool'
6
5
  require 'colored2'
7
6
  require 'hashie/mash'
8
7
  require 'yaml'
9
- require 'pp'
10
8
 
11
9
  module SimpleFeed
12
10
  module Providers
@@ -99,7 +97,7 @@ module SimpleFeed
99
97
  end
100
98
 
101
99
  if redis_proc
102
- self.pool = ::ConnectionPool.new(size: (opts[:pool_size] || 2)) do
100
+ self.pool = ::ConnectionPool.new(size: opts[:pool_size] || 2) do
103
101
  redis_proc.call
104
102
  end
105
103
  end
@@ -139,12 +137,10 @@ module SimpleFeed
139
137
  end
140
138
  end
141
139
 
142
- def with_pipelined
140
+ def with_pipelined(&block)
143
141
  with_retries do
144
142
  with_redis do |redis|
145
- redis.pipelined do
146
- yield(redis)
147
- end
143
+ redis.pipelined(&block)
148
144
  end
149
145
  end
150
146
  end
@@ -51,9 +51,9 @@ module SimpleFeed
51
51
  raise ArgumentError, '#delete_if must be called with a block that receives (user_id, event) as arguments.' unless block_given?
52
52
 
53
53
  with_response_batched(user_ids) do |key|
54
- fetch(user_ids: [key.user_id])[key.user_id].map do |event|
54
+ fetch(user_ids: [key.consumer])[key.consumer].map do |event|
55
55
  with_redis do |redis|
56
- if yield(event, key.user_id)
56
+ if yield(event, key.consumer)
57
57
  redis.zrem(key.data, event.value) ? event : nil
58
58
  end
59
59
  end
@@ -90,7 +90,7 @@ module SimpleFeed
90
90
 
91
91
  response = with_response_pipelined(user_ids) do |redis, key|
92
92
  if since == :unread
93
- redis.zrevrangebyscore(key.data, '+inf', (last_read_response.delete(key.user_id) || 0).to_f, withscores: true)
93
+ redis.zrevrangebyscore(key.data, '+inf', (last_read_response.delete(key.consumer) || 0).to_f, withscores: true)
94
94
  elsif since
95
95
  redis.zrevrangebyscore(key.data, '+inf', since.to_f, withscores: true)
96
96
  else
@@ -120,7 +120,7 @@ module SimpleFeed
120
120
  get_users_last_read(redis, key)
121
121
  end
122
122
  with_response_pipelined(response.user_ids, response) do |redis, key, _response|
123
- last_read = _response.delete(key.user_id).to_f
123
+ last_read = _response.delete(key.consumer).to_f
124
124
  redis.zcount(key.data, last_read, '+inf')
125
125
  end
126
126
  end
@@ -223,7 +223,7 @@ module SimpleFeed
223
223
  def with_response_pipelined(user_ids, response = nil)
224
224
  with_response(response) do |response|
225
225
  batch_pipelined(user_ids) do |redis, key|
226
- response.for(key.user_id) { yield(redis, key, response) }
226
+ response.for(key.consumer) { yield(redis, key, response) }
227
227
  end
228
228
  end
229
229
  end
@@ -231,7 +231,7 @@ module SimpleFeed
231
231
  def with_response_multi(user_ids, response = nil)
232
232
  with_response(response) do |response|
233
233
  batch_multi(user_ids) do |redis, key|
234
- response.for(key.user_id) { yield(redis, key, response) }
234
+ response.for(key.consumer) { yield(redis, key, response) }
235
235
  end
236
236
  end
237
237
  end
@@ -52,5 +52,4 @@ module SimpleFeed
52
52
  end
53
53
  end
54
54
 
55
- require_relative 'providers/hash'
56
55
  require_relative 'providers/redis'
@@ -12,11 +12,9 @@ module SimpleFeed
12
12
 
13
13
  include Enumerable
14
14
 
15
- def each
15
+ def each(&block)
16
16
  if block_given?
17
- @result.each_pair do |user_id, result|
18
- yield(user_id, result)
19
- end
17
+ @result.each_pair(&block)
20
18
  else
21
19
  @result.keys.to_enum
22
20
  end
@@ -28,7 +26,7 @@ module SimpleFeed
28
26
 
29
27
  def for(key_or_user_id, result = nil)
30
28
  user_id = key_or_user_id.is_a?(SimpleFeed::Providers::Key) ?
31
- key_or_user_id.user_id :
29
+ key_or_user_id.consumer :
32
30
  key_or_user_id
33
31
 
34
32
  @result[user_id] = result || yield(@result[user_id])
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SimpleFeed
4
- VERSION = '2.1.0'
4
+ VERSION ||= '3.2.0'
5
5
  end
data/lib/simplefeed.rb CHANGED
@@ -6,48 +6,52 @@ require 'hashie'
6
6
 
7
7
  Hashie.logger = Logger.new(nil)
8
8
 
9
- ::Dir.glob(::File.expand_path('../simplefeed/*.rb', __FILE__)).each { |f| require_relative(f) }
9
+ ::Dir.glob(::File.expand_path('../simplefeed/*.rb', __FILE__)).sort.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 [Hash<Symbol, Feed>] the registry of the defined feeds
24
+ # @return Hash<Symbol, Feed> the registry of the defined feeds
23
25
  attr_reader :registry
24
26
 
25
- # @param name [Symbol] feed name
26
- # @param options [Hash] any key-value pairs to set on the feed
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] the feed with the given name, and defined via options and a block
29
- def define(name, **options, &block)
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
- feed = registry[name] || SimpleFeed::Feed.new(name)
32
- feed.configure(options) do
33
- block&.call(feed)
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
- # @return [Feed] the pre-defined feed with the given name
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 [Symbol] short name of the provider, eg, :redis, :hash, etc.
47
- # @params args [Array] constructor array arguments of the provider
48
- # @params opts [Hash] constructor hash arguments of the provider
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 [Provider]
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
Binary file
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
- require 'simplefeed/version'
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,19 @@ 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
- spec.add_dependency 'hiredis'
32
33
  spec.add_dependency 'redis'
34
+ spec.add_dependency 'sorted_set'
35
+ spec.add_dependency 'tty-box'
36
+ spec.add_dependency 'tty-screen'
33
37
 
34
- spec.add_development_dependency 'awesome_print'
35
38
  spec.add_development_dependency 'bundler'
36
39
  spec.add_development_dependency 'codeclimate-test-reporter'
40
+ spec.add_development_dependency 'codecov'
37
41
  spec.add_development_dependency 'rake'
38
42
  spec.add_development_dependency 'rspec'
39
43
  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: 2.1.0
4
+ version: 3.2.0
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: 2020-05-24 00:00:00.000000000 Z
11
+ date: 2024-07-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
@@ -81,7 +95,7 @@ dependencies:
81
95
  - !ruby/object:Gem::Version
82
96
  version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
- name: hiredis
98
+ name: redis
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
101
  - - ">="
@@ -95,7 +109,7 @@ dependencies:
95
109
  - !ruby/object:Gem::Version
96
110
  version: '0'
97
111
  - !ruby/object:Gem::Dependency
98
- name: redis
112
+ name: sorted_set
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
115
  - - ">="
@@ -109,13 +123,27 @@ dependencies:
109
123
  - !ruby/object:Gem::Version
110
124
  version: '0'
111
125
  - !ruby/object:Gem::Dependency
112
- name: awesome_print
126
+ name: tty-box
113
127
  requirement: !ruby/object:Gem::Requirement
114
128
  requirements:
115
129
  - - ">="
116
130
  - !ruby/object:Gem::Version
117
131
  version: '0'
118
- type: :development
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-screen
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :runtime
119
147
  prerelease: false
120
148
  version_requirements: !ruby/object:Gem::Requirement
121
149
  requirements:
@@ -150,6 +178,20 @@ dependencies:
150
178
  - - ">="
151
179
  - !ruby/object:Gem::Version
152
180
  version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: codecov
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
153
195
  - !ruby/object:Gem::Dependency
154
196
  name: rake
155
197
  requirement: !ruby/object:Gem::Requirement
@@ -261,6 +303,7 @@ extensions: []
261
303
  extra_rdoc_files: []
262
304
  files:
263
305
  - ".codeclimate.yml"
306
+ - ".envrc"
264
307
  - ".github/workflows/rubocop.yml"
265
308
  - ".github/workflows/ruby.yml"
266
309
  - ".gitignore"
@@ -270,14 +313,16 @@ files:
270
313
  - ".rubocop_todo.yml"
271
314
  - ".travis.yml"
272
315
  - ".yardopts"
316
+ - CHANGELOG.md
273
317
  - Gemfile
274
318
  - Guardfile
275
319
  - LICENSE.txt
276
320
  - README.adoc
321
+ - README.pdf
277
322
  - Rakefile
278
323
  - bin/console
279
324
  - bin/setup
280
- - examples/hash_provider_example.rb
325
+ - codecov.yml
281
326
  - examples/redis_provider_example.rb
282
327
  - examples/shared/provider_example.rb
283
328
  - lib/simple-feed.rb
@@ -291,13 +336,9 @@ files:
291
336
  - lib/simplefeed/dsl/formatter.rb
292
337
  - lib/simplefeed/event.rb
293
338
  - lib/simplefeed/feed.rb
294
- - lib/simplefeed/key/template.rb
295
- - lib/simplefeed/key/type.rb
296
339
  - lib/simplefeed/providers.rb
297
340
  - lib/simplefeed/providers/base/provider.rb
298
341
  - lib/simplefeed/providers/hash.rb
299
- - lib/simplefeed/providers/hash/paginator.rb
300
- - lib/simplefeed/providers/hash/provider.rb
301
342
  - lib/simplefeed/providers/key.rb
302
343
  - lib/simplefeed/providers/proxy.rb
303
344
  - lib/simplefeed/providers/redis.rb
@@ -316,7 +357,7 @@ homepage: https://github.com/kigster/simple-feed
316
357
  licenses:
317
358
  - MIT
318
359
  metadata: {}
319
- post_install_message:
360
+ post_install_message:
320
361
  rdoc_options: []
321
362
  require_paths:
322
363
  - lib
@@ -331,8 +372,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
331
372
  - !ruby/object:Gem::Version
332
373
  version: '0'
333
374
  requirements: []
334
- rubygems_version: 3.1.3
335
- signing_key:
375
+ rubygems_version: 3.5.9
376
+ signing_key:
336
377
  specification_version: 4
337
378
  summary: Create multiple types of social networking activity feeds with simple-feed
338
379
  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
@@ -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