almicube 0.0.1 → 0.0.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/README.md +3 -1
- data/lib/almicube/builder/average_ranking_builder.rb +35 -0
- data/lib/almicube/builder/countable_ranking_builder.rb +35 -0
- data/lib/almicube/builder.rb +41 -0
- data/lib/almicube/model.rb +7 -5
- data/lib/almicube/ranged_ranking.rb +16 -3
- data/lib/almicube/ranking.rb +4 -3
- data/lib/almicube/version.rb +1 -1
- data/lib/almicube.rb +6 -0
- metadata +4 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f5974ef075edf11c09d6e8c44485968661fcc8a5
|
4
|
+
data.tar.gz: ff7ca640f98417dc29d755aa314a57a8ebefca42
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 999950f31e8406189ebfce9726f6c5a6b99f7d4c389bb54e644dbcc9538d30c16e50169c449b35cbb86ce2cd3b3e214166a3c1acc0b2fd0b95d77d06c825f001
|
7
|
+
data.tar.gz: ae64515586232c660796d417702a84e3d72907aa0f1e89563548a44c40d04617f56c653eaca9aedf74fed83ab555bcbbf15aa6316af3aa96ddb4abfbd06f8c05
|
data/README.md
CHANGED
@@ -12,7 +12,7 @@ class Item < ActiveRecord::Base
|
|
12
12
|
end
|
13
13
|
```
|
14
14
|
|
15
|
-
in `app/controllers/
|
15
|
+
in `app/controllers/items_controller.rb`
|
16
16
|
|
17
17
|
```ruby
|
18
18
|
class ItemsController
|
@@ -20,6 +20,7 @@ class ItemsController
|
|
20
20
|
@items = Item.access_ranking.page params[:page]
|
21
21
|
end
|
22
22
|
end
|
23
|
+
```
|
23
24
|
|
24
25
|
in `app/views/items/index.html.erb`
|
25
26
|
|
@@ -35,3 +36,4 @@ Note
|
|
35
36
|
--------
|
36
37
|
|
37
38
|
- Almicube uses Redis for DataStore.
|
39
|
+
- Example Project: https://github.com/niaeashes/almicube-sample
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Almicube
|
2
|
+
module Builder
|
3
|
+
class AverageRankingBuilder
|
4
|
+
extend Base
|
5
|
+
|
6
|
+
register :average
|
7
|
+
|
8
|
+
def initialize(options)
|
9
|
+
@options = self.default_options.merge(options)
|
10
|
+
end
|
11
|
+
|
12
|
+
def default_options
|
13
|
+
{ ranking_class: Almicube::Ranking, aggregate: :std }
|
14
|
+
end
|
15
|
+
|
16
|
+
def build(date)
|
17
|
+
ranking_class.new(ranking_options(date))
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
|
22
|
+
RANKING_OPTIONS = %i[class_name as date_format attribute_name per_page aggregate default_score]
|
23
|
+
|
24
|
+
def ranking_options(date = Date.today)
|
25
|
+
( @options.select{ |k| self.class::RANKING_OPTIONS.include? k } ).merge( date: date )
|
26
|
+
end
|
27
|
+
|
28
|
+
%i[ranking_class].each do |name|
|
29
|
+
define_method(name) do
|
30
|
+
@options[name]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Almicube
|
2
|
+
module Builder
|
3
|
+
class CountableRankingBuilder
|
4
|
+
extend Base
|
5
|
+
|
6
|
+
register :countable
|
7
|
+
|
8
|
+
def initialize(options)
|
9
|
+
@options = self.default_options.merge(options)
|
10
|
+
end
|
11
|
+
|
12
|
+
def default_options
|
13
|
+
{ ranking_class: Almicube::Ranking, aggregate: :sum }
|
14
|
+
end
|
15
|
+
|
16
|
+
def build(date)
|
17
|
+
ranking_class.new(ranking_options(date))
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
|
22
|
+
RANKING_OPTIONS = %i[class_name as date_format attribute_name per_page aggregate default_score]
|
23
|
+
|
24
|
+
def ranking_options(date = Date.today)
|
25
|
+
( @options.select{ |k| self.class::RANKING_OPTIONS.include? k } ).merge( date: date )
|
26
|
+
end
|
27
|
+
|
28
|
+
%i[ranking_class].each do |name|
|
29
|
+
define_method(name) do
|
30
|
+
@options[name]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Almicube
|
2
|
+
module Builder
|
3
|
+
class << self
|
4
|
+
def instance(name, options={})
|
5
|
+
raise ArgumentError, "invalid #1 name" unless has_builder? name
|
6
|
+
builders[name].new options
|
7
|
+
end
|
8
|
+
|
9
|
+
def register(name, builder_class)
|
10
|
+
raise TypeError, 'invalid builder class' unless builder_class.kind_of? Builder::Base
|
11
|
+
builders[name] = builder_class
|
12
|
+
end
|
13
|
+
|
14
|
+
def has_builder?(name)
|
15
|
+
load_builder name
|
16
|
+
builders.has_key? name
|
17
|
+
end
|
18
|
+
|
19
|
+
def builders
|
20
|
+
@builders ||= {}
|
21
|
+
end
|
22
|
+
|
23
|
+
def load_builder(name)
|
24
|
+
"Almicube::Builder::#{"#{name}_ranking_builder".classify}".constantize
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
module Base
|
29
|
+
def self.included(base)
|
30
|
+
base.include InstanceMethods
|
31
|
+
end
|
32
|
+
|
33
|
+
def register(name)
|
34
|
+
Builder.register(name, self)
|
35
|
+
end
|
36
|
+
|
37
|
+
class InstanceMethods
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/almicube/model.rb
CHANGED
@@ -8,16 +8,18 @@ module Almicube
|
|
8
8
|
|
9
9
|
def ranking_with(ranker, options={})
|
10
10
|
ranker = ranker.to_s
|
11
|
-
options.symbolize_keys!.merge(
|
11
|
+
options = options.symbolize_keys!.merge(class_name: self, attribute_name: ranker.to_sym)
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
builder_name = options.delete :builder
|
14
|
+
builder_name = :countable unless builder_name
|
15
|
+
|
16
|
+
@ranking_builders ||= {}
|
17
|
+
@ranking_builders[ranker.to_sym] = Almicube::Builder.instance(builder_name, options)
|
16
18
|
|
17
19
|
class_eval <<-EVAL
|
18
20
|
def self.#{ranker}_ranking(date = Date.today)
|
19
21
|
@rankings ||= {}
|
20
|
-
@rankings[:"#{ranker}:\#{date.to_s}"] ||=
|
22
|
+
@rankings[:"#{ranker}:\#{date.to_s}"] ||= @ranking_builders[:#{ranker}].build(date)
|
21
23
|
end
|
22
24
|
|
23
25
|
def #{ranker}_ranking(date = Date.today)
|
@@ -12,7 +12,18 @@ module Almicube
|
|
12
12
|
keys << key if connection.exists key
|
13
13
|
keys
|
14
14
|
end
|
15
|
-
|
15
|
+
if %i[sum max min].include? aggregate_method
|
16
|
+
connection.zunionstore key, keys, aggregate: aggregate_method
|
17
|
+
elsif aggregate_method == :std
|
18
|
+
weights = Array.new keys.length, (1.0/keys.length)
|
19
|
+
connection.zunionstore key, keys, aggregate: :sum, weights: weights
|
20
|
+
else
|
21
|
+
connection.zunionstore key, keys, aggregate: :sum
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def date
|
26
|
+
super - 1.days
|
16
27
|
end
|
17
28
|
|
18
29
|
def range
|
@@ -23,6 +34,10 @@ module Almicube
|
|
23
34
|
:weekly
|
24
35
|
end
|
25
36
|
|
37
|
+
def aggregate_method
|
38
|
+
aggregate = @options.fetch(:aggregate, :sum)
|
39
|
+
end
|
40
|
+
|
26
41
|
protected
|
27
42
|
|
28
43
|
def range_days(range, default = nil)
|
@@ -31,8 +46,6 @@ module Almicube
|
|
31
46
|
1
|
32
47
|
when :weekly
|
33
48
|
7
|
34
|
-
when :twice_weekly
|
35
|
-
14
|
36
49
|
when :monthly
|
37
50
|
30
|
38
51
|
else
|
data/lib/almicube/ranking.rb
CHANGED
@@ -14,7 +14,8 @@ module Almicube
|
|
14
14
|
date: Date.today,
|
15
15
|
per_page: 10,
|
16
16
|
as: Float,
|
17
|
-
default_score: 0
|
17
|
+
default_score: 0,
|
18
|
+
class_name: nil }
|
18
19
|
end
|
19
20
|
|
20
21
|
def connection
|
@@ -49,7 +50,7 @@ module Almicube
|
|
49
50
|
def page(page=1)
|
50
51
|
page = [1, page.to_i].max
|
51
52
|
revrange = connection.zrevrange(key, (page - 1) * per_page, page * per_page - 1)
|
52
|
-
records = target_class.
|
53
|
+
records = target_class.where("id IN (?)", revrange).all
|
53
54
|
revrange.inject([]) { |l, v| l << records.detect { |r| r.to_param == v } }
|
54
55
|
end
|
55
56
|
|
@@ -122,7 +123,7 @@ module Almicube
|
|
122
123
|
end
|
123
124
|
|
124
125
|
def key_format(key_base, options)
|
125
|
-
key = key_base.clone
|
126
|
+
key = key_base.to_s.clone
|
126
127
|
tmp_options = options.merge date: options.fetch(:date, Date.today).strftime(@options[:date_format])
|
127
128
|
key.match( self.class::KEY_PATTERN ) do |m|
|
128
129
|
key.gsub! m[0], tmp_options.fetch(m[1].to_sym, '').to_s
|
data/lib/almicube/version.rb
CHANGED
data/lib/almicube.rb
CHANGED
@@ -4,6 +4,12 @@ module Almicube
|
|
4
4
|
autoload :Model, 'almicube/model'
|
5
5
|
autoload :AssociationProxy, 'almicube/proxy/association_proxy'
|
6
6
|
|
7
|
+
autoload :Builder, 'almicube/builder'
|
8
|
+
module Builder
|
9
|
+
autoload :CountableRankingBuilder, 'almicube/builder/countable_ranking_builder'
|
10
|
+
autoload :AverageRankingBuilder, 'almicube/builder/average_ranking_builder'
|
11
|
+
end
|
12
|
+
|
7
13
|
if defined? ActiveRecord
|
8
14
|
ActiveRecord::Base.send :include, Almicube::Model
|
9
15
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: almicube
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- niaeashes
|
@@ -52,6 +52,9 @@ files:
|
|
52
52
|
- README.md
|
53
53
|
- almicube.gemspec
|
54
54
|
- lib/almicube.rb
|
55
|
+
- lib/almicube/builder.rb
|
56
|
+
- lib/almicube/builder/average_ranking_builder.rb
|
57
|
+
- lib/almicube/builder/countable_ranking_builder.rb
|
55
58
|
- lib/almicube/model.rb
|
56
59
|
- lib/almicube/proxy/association_proxy.rb
|
57
60
|
- lib/almicube/ranged_ranking.rb
|