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.
- checksums.yaml +5 -5
- data/.github/workflows/rubocop.yml +33 -0
- data/.github/workflows/ruby.yml +35 -0
- data/.relaxed-rubocop-2.4.yml +174 -0
- data/.rspec +1 -1
- data/.rubocop.yml +42 -1149
- data/.rubocop_todo.yml +134 -0
- data/.travis.yml +15 -8
- data/Gemfile +2 -0
- data/Guardfile +3 -3
- data/{README.md → README.adoc} +205 -140
- data/Rakefile +6 -7
- data/bin/console +1 -0
- data/examples/shared/provider_example.rb +10 -3
- data/lib/simple-feed.rb +2 -0
- data/lib/simple_feed.rb +2 -0
- data/lib/simplefeed.rb +9 -7
- data/lib/simplefeed/activity/base.rb +2 -0
- data/lib/simplefeed/activity/multi_user.rb +8 -6
- data/lib/simplefeed/activity/single_user.rb +5 -4
- data/lib/simplefeed/dsl.rb +3 -1
- data/lib/simplefeed/dsl/activities.rb +4 -3
- data/lib/simplefeed/dsl/formatter.rb +12 -12
- data/lib/simplefeed/event.rb +4 -3
- data/lib/simplefeed/feed.rb +19 -22
- data/lib/simplefeed/key/template.rb +5 -9
- data/lib/simplefeed/key/type.rb +4 -2
- data/lib/simplefeed/providers.rb +24 -9
- data/lib/simplefeed/providers/base/provider.rb +6 -3
- data/lib/simplefeed/providers/hash.rb +2 -0
- data/lib/simplefeed/providers/hash/paginator.rb +4 -2
- data/lib/simplefeed/providers/hash/provider.rb +11 -21
- data/lib/simplefeed/providers/key.rb +20 -11
- data/lib/simplefeed/providers/proxy.rb +13 -12
- data/lib/simplefeed/providers/redis.rb +2 -0
- data/lib/simplefeed/providers/redis/driver.rb +23 -23
- data/lib/simplefeed/providers/redis/provider.rb +35 -33
- data/lib/simplefeed/providers/redis/stats.rb +12 -13
- data/lib/simplefeed/response.rb +4 -2
- data/lib/simplefeed/version.rb +3 -1
- data/simple-feed.gemspec +16 -14
- 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 :
|
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 = ->
|
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 :
|
29
|
+
task default: :spec
|
data/bin/console
CHANGED
@@ -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
|
data/lib/simple-feed.rb
CHANGED
data/lib/simple_feed.rb
CHANGED
data/lib/simplefeed.rb
CHANGED
@@ -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
|
-
|
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]
|
31
|
+
feed = registry[name] || SimpleFeed::Feed.new(name)
|
31
32
|
feed.configure(options) do
|
32
|
-
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(
|
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,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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
72
|
+
block&.call(response)
|
72
73
|
response
|
73
74
|
end
|
74
75
|
|
data/lib/simplefeed/dsl.rb
CHANGED
@@ -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
|
-
|
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#{
|
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
|
-
|
17
|
-
|
18
|
-
|
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
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
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
|
|
data/lib/simplefeed/event.rb
CHANGED
@@ -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.
|
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
|
data/lib/simplefeed/feed.rb
CHANGED
@@ -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
|
22
|
-
@max_size
|
23
|
-
@batch_size
|
24
|
-
@proxy
|
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
|
-
|
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|
|
81
|
-
|
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 =
|
10
|
+
output = text.dup
|
10
11
|
params.each_pair do |key, value|
|
11
|
-
output.gsub!(
|
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
|
-
|