simple-feed 2.0.2 → 2.1.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.
Files changed (42) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/rubocop.yml +33 -0
  3. data/.github/workflows/ruby.yml +35 -0
  4. data/.relaxed-rubocop-2.4.yml +174 -0
  5. data/.rspec +1 -1
  6. data/.rubocop.yml +42 -1149
  7. data/.rubocop_todo.yml +134 -0
  8. data/.travis.yml +15 -8
  9. data/Gemfile +2 -0
  10. data/Guardfile +3 -3
  11. data/{README.md → README.adoc} +205 -140
  12. data/Rakefile +6 -7
  13. data/bin/console +1 -0
  14. data/examples/shared/provider_example.rb +10 -3
  15. data/lib/simple-feed.rb +2 -0
  16. data/lib/simple_feed.rb +2 -0
  17. data/lib/simplefeed.rb +9 -7
  18. data/lib/simplefeed/activity/base.rb +2 -0
  19. data/lib/simplefeed/activity/multi_user.rb +8 -6
  20. data/lib/simplefeed/activity/single_user.rb +5 -4
  21. data/lib/simplefeed/dsl.rb +3 -1
  22. data/lib/simplefeed/dsl/activities.rb +4 -3
  23. data/lib/simplefeed/dsl/formatter.rb +12 -12
  24. data/lib/simplefeed/event.rb +4 -3
  25. data/lib/simplefeed/feed.rb +19 -22
  26. data/lib/simplefeed/key/template.rb +5 -9
  27. data/lib/simplefeed/key/type.rb +4 -2
  28. data/lib/simplefeed/providers.rb +24 -9
  29. data/lib/simplefeed/providers/base/provider.rb +6 -3
  30. data/lib/simplefeed/providers/hash.rb +2 -0
  31. data/lib/simplefeed/providers/hash/paginator.rb +4 -2
  32. data/lib/simplefeed/providers/hash/provider.rb +11 -21
  33. data/lib/simplefeed/providers/key.rb +20 -11
  34. data/lib/simplefeed/providers/proxy.rb +13 -12
  35. data/lib/simplefeed/providers/redis.rb +2 -0
  36. data/lib/simplefeed/providers/redis/driver.rb +23 -23
  37. data/lib/simplefeed/providers/redis/provider.rb +35 -33
  38. data/lib/simplefeed/providers/redis/stats.rb +12 -13
  39. data/lib/simplefeed/response.rb +4 -2
  40. data/lib/simplefeed/version.rb +3 -1
  41. data/simple-feed.gemspec +16 -14
  42. metadata +58 -41
data/Rakefile CHANGED
@@ -1,30 +1,29 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/gem_tasks'
2
4
  require 'rspec/core/rake_task'
3
5
 
4
6
  require 'yard'
5
7
 
6
-
7
8
  def shell(*args)
8
9
  puts "running: #{args.join(' ')}"
9
10
  system(args.join(' '))
10
11
  end
11
12
 
12
13
  task :permissions do
13
- shell('rm -rf pkg/')
14
+ shell('rm -rf pkg/ tmp/ coverage/')
14
15
  shell("chmod -v o+r,g+r * */* */*/* */*/*/* */*/*/*/* */*/*/*/*/*")
15
16
  shell("find . -type d -exec chmod o+x,g+x {} \\;")
16
17
  end
17
18
 
18
- task :build => :permissions
19
-
19
+ task build: :permissions
20
20
 
21
21
  YARD::Rake::YardocTask.new(:doc) do |t|
22
22
  t.files = %w(lib/**/*.rb exe/*.rb - README.md LICENSE.txt)
23
23
  t.options.unshift('--title', '"SimpleFeed — Fast and Scalable "write-time" Simple Feed for Social Networks, with a Redis-based default backend implementation."')
24
- t.after = ->() { exec('open doc/index.html') } if RUBY_PLATFORM =~ /darwin/
24
+ t.after = -> { exec('open doc/index.html') } if RUBY_PLATFORM =~ /darwin/
25
25
  end
26
26
 
27
-
28
27
  RSpec::Core::RakeTask.new(:spec)
29
28
 
30
- task :default => :spec
29
+ task default: :spec
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require "bundler/setup"
4
5
  require "activity/feed"
@@ -5,9 +5,17 @@ $LOAD_PATH.unshift File.expand_path('../../../lib', __FILE__)
5
5
  raise ArgumentError, 'No @feed defined in the enclosing example' unless defined?(@feed)
6
6
 
7
7
  require 'simplefeed'
8
+ require 'uuid'
9
+
10
+ srand(Time.now.to_i % 100003)
11
+
12
+ @number_of_users = ARGV[0] ? ARGV[0].to_i : 2
13
+ @users = @number_of_users.times.map do |n|
14
+ n % 2 == 0 ? UUID.generate : rand(100003)
15
+ end
16
+
17
+ pp @users
8
18
 
9
- @number_of_users = ARGV[0] ? ARGV[0].to_i : 1
10
- @users = Array.new(@number_of_users) { rand(200_000_000...800_000_000) }
11
19
  @activity = @feed.activity(@users)
12
20
  @uid = @users.first
13
21
 
@@ -24,7 +32,6 @@ def p(*args)
24
32
  end
25
33
 
26
34
  with_activity(@activity) do
27
-
28
35
  header "#{@activity.feed.provider_type} provider example"
29
36
 
30
37
  wipe
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'simplefeed'
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'simplefeed'
@@ -1,5 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'hashie/extensions/symbolize_keys'
2
4
  require 'simplefeed/version'
5
+ require 'hashie'
3
6
 
4
7
  Hashie.logger = Logger.new(nil)
5
8
 
@@ -17,9 +20,7 @@ module SimpleFeed
17
20
 
18
21
  class << self
19
22
  # @return [Hash<Symbol, Feed>] the registry of the defined feeds
20
- def registry
21
- @registry
22
- end
23
+ attr_reader :registry
23
24
 
24
25
  # @param name [Symbol] feed name
25
26
  # @param options [Hash] any key-value pairs to set on the feed
@@ -27,9 +28,9 @@ module SimpleFeed
27
28
  # @return [Feed] the feed with the given name, and defined via options and a block
28
29
  def define(name, **options, &block)
29
30
  name = name.to_sym unless name.is_a?(Symbol)
30
- feed = registry[name] ? registry[name] : SimpleFeed::Feed.new(name)
31
+ feed = registry[name] || SimpleFeed::Feed.new(name)
31
32
  feed.configure(options) do
32
- block.call(feed) if block
33
+ block&.call(feed)
33
34
  end
34
35
  registry[name] = feed
35
36
  feed
@@ -50,11 +51,12 @@ module SimpleFeed
50
51
  def provider(provider_name, *args, **opts, &block)
51
52
  provider_class = SimpleFeed::Providers.registry[provider_name]
52
53
  raise ArgumentError, "No provider named #{provider_name} was found, #{SimpleFeed::Providers.registry.inspect}" unless provider_class
54
+
53
55
  provider_class.new(*args, **opts, &block)
54
56
  end
55
57
 
56
58
  # Forward all other method calls to the Provider
57
- def method_missing(name, *args, &block)
59
+ def method_missing(name, *args, **opts, &block)
58
60
  registry[name] || super
59
61
  end
60
62
  end
@@ -62,7 +64,7 @@ module SimpleFeed
62
64
  # Returns list of class attributes based on the setter methods.
63
65
  # Not fool-proof, but works in this context.
64
66
  def self.class_attributes(klass)
65
- klass.instance_methods.grep(%r{[^=!]=$}).map { |m| m.to_s.gsub(/=/, '').to_sym }
67
+ klass.instance_methods.grep(/[^=!]=$/).map { |m| m.to_s.gsub(/=/, '').to_sym }
66
68
  end
67
69
 
68
70
  # Shortcut method to symbolize hash keys, using Hashie::Extensions
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SimpleFeed
2
4
  module Activity
3
5
  class Base
@@ -1,10 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'forwardable'
2
4
  require_relative 'base'
3
5
 
4
6
  module SimpleFeed
5
7
  module Activity
6
8
  class MultiUser < Base
7
-
8
9
  attr_reader :user_ids
9
10
 
10
11
  extend Forwardable
@@ -16,7 +17,7 @@ module SimpleFeed
16
17
  # API Examples
17
18
  # ============
18
19
  #
19
- #```ruby
20
+ # ```ruby
20
21
  # @multi = SimpleFeed.get(:feed_name).activity(User.active.map(&:id))
21
22
  #
22
23
  # @multi.store(value:, at:)
@@ -54,15 +55,15 @@ module SimpleFeed
54
55
  # # => [Response] { user_id => [Time] last_read, ... }
55
56
  #
56
57
  # @multi.total_count
57
- # # => [Response] { user_id => [Integer] total_count, ... }
58
+ # # => [Response] { user_id => [Integer, String] total_count, ... }
58
59
  #
59
60
  # @multi.unread_count
60
- # # => [Response] { user_id => [Integer] unread_count, ... }
61
+ # # => [Response] { user_id => [Integer, String] unread_count, ... }
61
62
  #
62
63
  # @multi.last_read
63
64
  # # => [Response] { user_id => [Time] last_read, ... }
64
65
  #
65
- #```
66
+ # ```
66
67
 
67
68
  SimpleFeed::Providers.define_provider_methods(self) do |instance, method, *args, **opts, &block|
68
69
  opts.merge!(user_ids: instance.user_ids)
@@ -71,8 +72,9 @@ module SimpleFeed
71
72
  opts.delete(:event)
72
73
  end
73
74
  response = instance.feed.send(method, *args, **opts, &block)
74
- yield(response) if block_given?
75
+ block&.call(response)
75
76
  raise StandardError, "Nil response from provider #{instance.feed.provider&.provider&.class}, method #{method}(#{opts})" unless response
77
+
76
78
  response
77
79
  end
78
80
 
@@ -1,8 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'base'
2
4
 
3
5
  module SimpleFeed
4
6
  module Activity
5
-
6
7
  # Lazy implementation of SingleUser based on delegating an array of
7
8
  # one user_id to +MultiUser+
8
9
 
@@ -16,7 +17,7 @@ module SimpleFeed
16
17
  yield(user_id)
17
18
  end
18
19
 
19
- #```ruby
20
+ # ```ruby
20
21
  # @activity = SimpleFeed.get(:feed_name).activity(current_user.id)
21
22
  #
22
23
  # @activity.store(value:, at:)
@@ -61,14 +62,14 @@ module SimpleFeed
61
62
  # @activity.last_read
62
63
  # # => [Time] last_read
63
64
 
64
-
65
65
  SimpleFeed::Providers.define_provider_methods(self) do |instance, method, *args, **opts, &block|
66
66
  response = instance.user_activity.send(method, *args, **opts, &block)
67
67
  unless response.has_user?(instance.user_id)
68
68
  raise StandardError, "Nil response from provider #{instance.feed.provider&.provider&.class}, method #{method}(#{opts}) — user_id #{instance.user_id}"
69
69
  end
70
+
70
71
  response = response[instance.user_id]
71
- yield(response) if block_given?
72
+ block&.call(response)
72
73
  response
73
74
  end
74
75
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'providers'
2
4
  require 'simplefeed'
3
5
  require_relative 'dsl/activities'
@@ -22,7 +24,7 @@ module SimpleFeed
22
24
  attr_accessor :debug
23
25
 
24
26
  def debug?
25
- self.debug
27
+ debug
26
28
  end
27
29
  end
28
30
 
@@ -1,8 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'formatter'
2
4
  module SimpleFeed
3
5
  module DSL
4
6
  class Activities
5
-
6
7
  include SimpleFeed::DSL::Formatter
7
8
 
8
9
  attr_accessor :activity, :feed
@@ -14,7 +15,7 @@ module SimpleFeed
14
15
  self.class.instance_eval do
15
16
  attr_accessor key
16
17
  end
17
- self.send("#{key}=".to_sym, value)
18
+ send("#{key}=".to_sym, value)
18
19
  end
19
20
  end
20
21
 
@@ -60,7 +61,7 @@ module SimpleFeed
60
61
 
61
62
  def print_debug_info(method, **opts)
62
63
  brackets = opts.empty? ? ['', ''] : %w{( )}
63
- printf "\n#{self.feed.name.to_s.blue}.#{method.to_s.cyan.bold}#{brackets[0]}#{opts.to_s.gsub(/[{}]/, '').blue}#{brackets[1]} \n" if SimpleFeed::DSL.debug?
64
+ printf "\n#{feed.name.to_s.blue}.#{method.to_s.cyan.bold}#{brackets[0]}#{opts.to_s.gsub(/[{}]/, '').blue}#{brackets[1]} \n" if SimpleFeed::DSL.debug?
64
65
  response = yield if block_given?
65
66
  puts response.inspect.yellow if SimpleFeed::DSL.debug?
66
67
  response
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'simplefeed/dsl'
2
4
  require 'simplefeed/activity/single_user'
3
5
  require 'simplefeed/activity/multi_user'
@@ -13,9 +15,9 @@ module SimpleFeed
13
15
 
14
16
  def color_dump(this_activity = activity)
15
17
  this_activity = if this_activity.is_a?(SimpleFeed::Activity::SingleUser)
16
- this_activity.feed.activity([this_activity.user_id])
17
- else
18
- this_activity
18
+ this_activity.feed.activity([this_activity.user_id])
19
+ else
20
+ this_activity
19
21
  end
20
22
  _puts
21
23
 
@@ -32,8 +34,7 @@ module SimpleFeed
32
34
 
33
35
  [['User ID', user_id, "\n"],
34
36
  ['Activities', sprintf('%d total, %d unread', total_count[user_id], unread_count[user_id]), "\n"],
35
- ['Last Read', this_last_read ? Time.at(this_last_read) : 'N/A'],
36
- ].each do |field, value, *args|
37
+ ['Last Read', this_last_read ? Time.at(this_last_read) : 'N/A'],].each do |field, value, *args|
37
38
  field(field, value, *args)
38
39
  end
39
40
 
@@ -42,7 +43,6 @@ module SimpleFeed
42
43
  this_events = fetch[user_id]
43
44
  this_events_count = this_events.size
44
45
  this_events.each_with_index do |_event, _index|
45
-
46
46
  if this_last_event_at.nil? && _event.at < this_last_read
47
47
  print_last_read_separator(this_last_read)
48
48
  elsif this_last_event_at && this_last_read < this_last_event_at && this_last_read > _event.at
@@ -86,12 +86,12 @@ module SimpleFeed
86
86
 
87
87
  def field_value(value)
88
88
  case value
89
- when Numeric
90
- sprintf '%-20d', value
91
- when Time
92
- sprintf '%-30s', value.strftime(TIME_FORMAT)
93
- else
94
- sprintf '%-20s', value.to_s
89
+ when Numeric
90
+ sprintf '%-20d', value
91
+ when Time
92
+ sprintf '%-30s', value.strftime(TIME_FORMAT)
93
+ else
94
+ sprintf '%-20s', value.to_s
95
95
  end
96
96
  end
97
97
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'json'
2
4
 
3
5
  module SimpleFeed
@@ -6,7 +8,7 @@ module SimpleFeed
6
8
  include Comparable
7
9
 
8
10
  def initialize(*args, value: nil, at: Time.now)
9
- if args && args.size > 0
11
+ if args && !args.empty?
10
12
  self.value = args[0]
11
13
  self.at = args[1]
12
14
  end
@@ -44,7 +46,7 @@ module SimpleFeed
44
46
  self.value.hash
45
47
  end
46
48
 
47
- def to_json
49
+ def to_json(*_args)
48
50
  to_h.to_json
49
51
  end
50
52
 
@@ -75,6 +77,5 @@ module SimpleFeed
75
77
  raise ArgumentError, "Required arguments missing, value=[#{value}], at=[#{at}]"
76
78
  end
77
79
  end
78
-
79
80
  end
80
81
  end
@@ -1,10 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'providers'
2
4
  require_relative 'activity/base'
3
5
  require 'simplefeed/key/template'
4
6
 
5
7
  module SimpleFeed
6
8
  class Feed
7
-
8
9
  attr_accessor :per_page, :max_size, :batch_size, :meta, :namespace
9
10
  attr_reader :name
10
11
 
@@ -18,14 +19,10 @@ module SimpleFeed
18
19
  # set the defaults if not passed in
19
20
  @meta = {}
20
21
  @namespace = nil
21
- @per_page ||= 50
22
- @max_size ||= 1000
23
- @batch_size ||= 10
24
- @proxy = nil
25
- end
26
-
27
- def key_template
28
- SimpleFeed::Key::Template.new(namespace)
22
+ @per_page ||= 50
23
+ @max_size ||= 1000
24
+ @batch_size ||= 10
25
+ @proxy = nil
29
26
  end
30
27
 
31
28
  def provider=(definition)
@@ -38,10 +35,6 @@ module SimpleFeed
38
35
  @proxy
39
36
  end
40
37
 
41
- def key(user_id)
42
- SimpleFeed::Providers::Key.new(user_id, key_template)
43
- end
44
-
45
38
  def provider_type
46
39
  SimpleFeed::Providers::Base::Provider.class_to_registry(@proxy.provider.class)
47
40
  end
@@ -61,28 +54,32 @@ module SimpleFeed
61
54
  user_activity(one_or_more_users)
62
55
  end
63
56
 
64
- # @deprecated Please use {#activity} instead
65
- def for(*args)
66
- STDERR.puts 'WARNING: method #for is deprecated, please use #activity'
67
- activity(*args)
68
- end
69
-
70
57
  def configure(hash = {})
71
58
  SimpleFeed.symbolize!(hash)
72
59
  class_attrs.each do |attr|
73
- self.send("#{attr}=", hash[attr]) if hash.key?(attr)
60
+ send("#{attr}=", hash[attr]) if hash.key?(attr)
74
61
  end
75
62
  yield self if block_given?
76
63
  end
77
64
 
65
+ def key(user_id)
66
+ SimpleFeed::Providers::Key.new(user_id, key_template)
67
+ end
68
+
78
69
  def eql?(other)
79
70
  other.class == self.class &&
80
- %i(per_page max_size name).all? { |m| self.send(m).equal?(other.send(m)) } &&
81
- self.provider.provider.class == other.provider.provider.class
71
+ %i(per_page max_size name).all? { |m| send(m).equal?(other.send(m)) } &&
72
+ provider.provider.class == other.provider.provider.class
82
73
  end
83
74
 
84
75
  def class_attrs
85
76
  SimpleFeed.class_attributes(self.class)
86
77
  end
78
+
79
+ private
80
+
81
+ def key_template
82
+ SimpleFeed::Key::Template.new(namespace)
83
+ end
87
84
  end
88
85
  end
@@ -1,14 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'base62-rb'
2
4
  require 'hashie/mash'
3
5
 
4
6
  module SimpleFeed
5
7
  module Key
6
-
7
8
  class TextTemplate < Struct.new(:text)
8
9
  def render(params = {})
9
- output = self.text.dup
10
+ output = text.dup
10
11
  params.each_pair do |key, value|
11
- output.gsub!(%r[{{\s*#{key}\s*}}], value.to_s)
12
+ output.gsub!(/{{\s*#{key}\s*}}/, value.to_s)
12
13
  end
13
14
  output
14
15
  end
@@ -21,8 +22,7 @@ module SimpleFeed
21
22
 
22
23
  def initialize(namespace,
23
24
  key_types = DEFAULT_TYPES,
24
- text_template = DEFAULT_TEXT_TEMPLATE
25
- )
25
+ text_template = DEFAULT_TEXT_TEMPLATE)
26
26
 
27
27
  self.namespace = namespace
28
28
  self.key_types = key_types
@@ -43,10 +43,6 @@ module SimpleFeed
43
43
  def key_names
44
44
  key_types.map(&:name).map(&:to_s).sort
45
45
  end
46
-
47
- private
48
-
49
46
  end
50
47
  end
51
48
  end
52
-