fatboy 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 14480b9fa576ac0e81318733af2789f82f5caaa8
4
+ data.tar.gz: 987e8724d2cd01bfad21a66853cf3f53803cd0a6
5
+ SHA512:
6
+ metadata.gz: 78061dc924ed74f6205bfb8715eb3c7edcbf91eb14b2c2c8066e01137396b0bcca307a46d5058e4118c5eb7f5e2cffa51760b869da8195b856371101fbcab939
7
+ data.tar.gz: 48a20e5e25c67f52e6a0e0631beab08abe409cd512e32e0fc9d995b1948e05ed9fe9de9d5decdfbb800347dfda444b6e4fc171f5a65ef5fcd3a89f4cc2f274b0
data/.gitignore ADDED
@@ -0,0 +1,23 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
23
+ *.swp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fatboy.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Anthony Super
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,97 @@
1
+ # Fatboy
2
+ ##### See views, right here, right now
3
+ Fatboy is a gem which manages view counts on ActiveRecord objects (or things that quack like them).
4
+ It's great for seeing the most (and least) viewed models on your website.
5
+ To make things even better, Fatboy will store view counts by day, month, year,
6
+ and all-time.
7
+
8
+ It doesn't touch your SQL database.
9
+ Fatboy stays slim in Redis.
10
+
11
+ NOTE: This is currenlty not production-ready.
12
+ It will be soon, though.
13
+ ## Installation
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ gem 'fatboy'
18
+
19
+ And then execute:
20
+
21
+ $ bundle
22
+
23
+ Or install it yourself as:
24
+
25
+ $ gem install fatboy
26
+
27
+ ## Usage
28
+
29
+ Fatboy is easy to set up. First, initialize it:
30
+
31
+ ```ruby
32
+ # if you don't provide your own redis, fatoby will create one
33
+ # with Redis.new
34
+ fatboy = Fatboy.new(redis: redis)
35
+ ```
36
+
37
+ Then, just tell it what your users look at.
38
+
39
+ ```ruby
40
+ # As long as the variable you're passing in responds to
41
+ # .id, this will work
42
+ fatboy.view(image)
43
+ # You can also use the shorthand method:
44
+ # fatboy[image]
45
+ ```
46
+
47
+ Now, managing views is pretty useless if you can't retrieve them later.
48
+ Thankfully, fatboy makes this easy as well:
49
+
50
+ ```ruby
51
+ fatboy.views_for(image) # => 1
52
+ ```
53
+
54
+ Don't worry if that's a brand-new Fatboy instance---as long as the Redis is the same, Fatboy's view count will be the same.
55
+
56
+ #### Getting Top Viewed
57
+
58
+ Fatboy makes it easy to retrieve a list of the most-popular records in your database.
59
+ Check it now now:
60
+ ```ruby
61
+ fatboy.popular(Image).today.most # => most viewed image today
62
+ fatboy.popular("Image").all_time.most # => Top viewed image of all time
63
+ ```
64
+
65
+ Want it from other days?
66
+
67
+ ```ruby
68
+ # most popular image a month ago
69
+ fatboy.popular(Image).day(Time.now << 1).most
70
+ # Or with active support
71
+ fatboy.popular(Image).day(1.months.ago).most
72
+ ```
73
+ Don't want just the most popular?
74
+ Maybe you'd like the least popular?
75
+
76
+ ```ruby
77
+ fatboy.popular(Image).day(Time.now).least
78
+ fatboy.popular(Image).month(Time.now).least
79
+ ```
80
+
81
+ Or perhaps a range?
82
+
83
+ ```ruby
84
+ fatboy.popular(Image).this_month.range(10..20)
85
+ # or, a range for a while ago
86
+ fatboy.popular(Image).month(3.months.ago).range(10..20)
87
+ ```
88
+
89
+ Fatboy makes it easier. See the rdoc for details.
90
+ ## Contributing
91
+
92
+ 1. Fork it ( https://github.com/[my-github-username]/fatboy/fork )
93
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
94
+ 3. Write functionality and tests
95
+ 4. Commit your changes (`git commit -am 'Add some feature'`)
96
+ 5. Push to the branch (`git push origin my-new-feature`)
97
+ 6. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/fatboy.gemspec ADDED
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'fatboy/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "fatboy"
8
+ spec.version = Fatboy::VERSION
9
+ spec.authors = ["Anthony Super"]
10
+ spec.email = ["anthony@noided.media"]
11
+ spec.summary = %q{Fatboy keeps track of your models's views, right here, right now.}
12
+ spec.description = %q{
13
+ Fatboy is a gem designed to easily keep track of views.
14
+ It doesn't touch your SQL, and stays slim in redis.
15
+ It also makes it easy to query based on how viewed something is.
16
+ }
17
+ spec.homepage = "http://github.com/AnthonySuper/fatboy"
18
+ spec.license = "MIT"
19
+
20
+ spec.files = `git ls-files -z`.split("\x0")
21
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
22
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
23
+ spec.require_paths = ["lib"]
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.6"
26
+ spec.add_development_dependency "rake"
27
+ spec.add_development_dependency "rspec"
28
+ spec.add_development_dependency "timecop"
29
+ spec.add_development_dependency "mock_redis"
30
+ spec.add_development_dependency "simplecov"
31
+ spec.add_runtime_dependency "redis"
32
+ spec.required_ruby_version = ">= 2.0"
33
+
34
+ end
@@ -0,0 +1,44 @@
1
+ class Fatboy
2
+ ##
3
+ # Common helper functions, which are used across many
4
+ # classes.
5
+ module Helpers
6
+ ##
7
+ # Given a model_name and the properly formated hour, day, etc. string,
8
+ # give the name of the key views are stored in
9
+ def self.format_store(model_name, store_name)
10
+ "#{model_name}-#{store_name}"
11
+ end
12
+ ##
13
+ # Properly format the time to retrieve or set an hour
14
+ def self.hour_format(hr)
15
+ hr.utc.strftime(Fatboy::HOUR_FORMAT_STR)
16
+ end
17
+
18
+ ##
19
+ # Properly format the time to retrieve or set a day
20
+ def self.day_format(day)
21
+ day.utc.strftime(Fatboy::DAY_FORMAT_STR)
22
+ end
23
+
24
+ ##
25
+ # Properly format the time to retrieve or set a month
26
+ def self.month_format(mth)
27
+ mth.utc.strftime(Fatboy::MONTH_FORMAT_STR)
28
+ end
29
+
30
+ ##
31
+ # Properly format the time to retrieve or set a year
32
+ def self.year_format(yr)
33
+ yr.utc.strftime(Fatboy::YEAR_FORMAT_STR)
34
+ end
35
+ ##
36
+ # Get an array of the hour format, the day format, the month format, and
37
+ # the year format
38
+ def self.all_format(time)
39
+ [:hour_format, :day_format, :month_format, :year_format].map do |func|
40
+ self.send(func, time)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,70 @@
1
+ require_relative './time_based_popularity'
2
+ class Fatboy
3
+ ##
4
+ # This class is used to query how popular something is.
5
+ class Popularity
6
+ ##
7
+ # We always pass in a redis
8
+ def initialize(model, redis)
9
+ @redis = redis
10
+ @model_name = model.to_s
11
+ end
12
+ ##
13
+ # Get a Fatboy::TimeBasedPopularity for a specific hour in time.
14
+ # Arguments:
15
+ # * +time+: a DateTime or Time containing the hour in time you wish to query
16
+ def hour(time)
17
+ fmt_tim = Fatboy::Helpers.hour_format(time.utc)
18
+ store_name = Fatboy::Helpers.format_store(@model_name, fmt_tim)
19
+ Fatboy::TimeBasedPopularity.new(@redis, store_name)
20
+ end
21
+ ##
22
+ # Get a Fatboy::TimeBasedPopularity for a specific day in time.
23
+ # Arguments:
24
+ # * +time+: A Datetime or Time in the day you wish to query.
25
+ def day(time)
26
+ fmt_time = Fatboy::Helpers.day_format(time.utc)
27
+ store_name = Fatboy::Helpers.format_store(@model_name, fmt_time)
28
+
29
+ Fatboy::TimeBasedPopularity.new(@redis, store_name)
30
+ end
31
+ ##
32
+ # Get a Fatboy::TimeBasedPopularity for a specific month in time.
33
+ # Arguments:
34
+ # * +time+: A time within the month you wish to query.
35
+ def month(time)
36
+ fmt_time = Fatboy::Helpers.month_format(time.utc)
37
+ store_name = Fatboy::Helpers.format_store(@model_name, fmt_time)
38
+ Fatboy::TimeBasedPopularity.new(@redis, store_name)
39
+ end
40
+ ##
41
+ # Get a Fatboy::TimeBasedPopularity for a specific year in time.
42
+ # Arguments:
43
+ # * +time+: A DateTime or Time in the year you wish to query.
44
+ def year(time)
45
+ fmt_time = Fatboy::Helpers.year_format(time.utc)
46
+ store_name = Fatboy::Helpers.format_store(@model_name, fmt_time)
47
+ Fatboy::TimeBasedPopularity.new(@redis, store_name)
48
+ end
49
+ ##
50
+ # Get a Fatboy::TimeBasedPopularity for this hour.
51
+ def this_hour
52
+ hour(Time.now)
53
+ end
54
+ ##
55
+ # Get a Fatboy::TimeBasedPopularity for this day.
56
+ def today
57
+ day(Time.now)
58
+ end
59
+ ##
60
+ # Get a Fatboy::TimeBasedPopularity for this month.
61
+ def this_month
62
+ month(Time.now)
63
+ end
64
+ ##
65
+ # Get a Fatboy::TimeBasedPopularity for this year.
66
+ def this_year
67
+ year(Time.now)
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,63 @@
1
+ require_relative './viewed_item'
2
+ class Fatboy
3
+ ##
4
+ # TimeBasedPopularity measures the popularity based on a set period of time.
5
+ # You should probably never initialize this yourself.
6
+ class TimeBasedPopularity
7
+ ##
8
+ # What redis to look in, and what sorted set we're using.
9
+ # Probably don't ever initialize this yourself.
10
+ def initialize(redis, store)
11
+ @redis = redis
12
+ @store = store
13
+ end
14
+ ##
15
+ # Get an enumerator of all viewed items, as a Fatboy::ViewedItem, in
16
+ # rank order.
17
+ # Pretty useful for lazy operations and such.
18
+ def enumerator
19
+ Enumerator.new(size) do |yielder|
20
+ range(0..(size-1)).each{|x| yielder.yield x}
21
+ end
22
+ end
23
+ ##
24
+ # Get the most viewed item.
25
+ # Returns a Fatboy::ViewedItem
26
+ def most
27
+ range(0..1).first
28
+ end
29
+ ##
30
+ # Get the least viewed item.
31
+ # Returns a Fatboy::ViewedItem
32
+ def least
33
+ range(-1..-2).first
34
+ end
35
+
36
+ ##
37
+ # Get the total number of items viewed.
38
+ def size
39
+ @redis.zcard(@store)
40
+ end
41
+
42
+ ##
43
+ # Specify a range of ranks, and gets them.
44
+ # Returns an array of Fatboy::ViewedItem
45
+ def range(rng)
46
+ start = rng.first
47
+ stop = rng.last
48
+ ##
49
+ # Build up a list of pairs: [id, score]
50
+ pairs = @redis.zrevrange(@store, start, stop, withscores: true)
51
+ ##
52
+ # Get rid of nils, zip up list with range of rank
53
+ triplets = pairs.reject{|p| !p}.zip(start..stop)
54
+ # After the zip, we have [[[id, score], rank], [[id, score], rank]]
55
+ # So we flatten out the inner arrays, giving us
56
+ # [[id, score, rank], [id, score, rank]]
57
+ triplets.map!(&:flatten)
58
+ ##
59
+ # Use the array splat to more easily pass in the 3 arguments
60
+ triplets.map{|trip| Fatboy::ViewedItem.new(*trip)}
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,5 @@
1
+ class Fatboy
2
+ ##
3
+ # Gem version of Fatboy
4
+ VERSION = "0.0.1"
5
+ end
@@ -0,0 +1,28 @@
1
+ class Fatboy
2
+ ##
3
+ # The viewed item class provides a (very) simple interface for interacting
4
+ # with views on Models.
5
+ # Almost always obtained from a TimeBasedPopularity, this struct simply
6
+ # shows the id of the model, the number of views, and the rank.
7
+ # NOTE: The highest-ranked item has rank 0. Ranks are 0-indexed.
8
+ class ViewedItem
9
+ def initialize(id, views, rank)
10
+ @id = id.to_i
11
+ @views = views.to_i
12
+ @rank = rank.to_i
13
+ end
14
+ ##
15
+ # Id of the model contained this this ViewedItem
16
+ attr_reader :id
17
+ ##
18
+ # Amount this ViewedItem has been viewed in a time period.
19
+ # This time period was pre-set on construction.
20
+ attr_reader :views
21
+ ##
22
+ # The rank, 0 being the most viewed, of this item.
23
+ # The time period was pre-set on construction, typically from a
24
+ # Fatboy::TimeBasedView
25
+ attr_reader :rank
26
+ end
27
+ end
28
+
data/lib/fatboy.rb ADDED
@@ -0,0 +1,56 @@
1
+ require "fatboy/version"
2
+ require 'redis'
3
+ require_relative './fatboy/popularity'
4
+ require_relative './fatboy/helpers'
5
+ ##
6
+ # Fatboy is the main class for interacting with the system.
7
+ # It provides a variety of functionality.
8
+ class Fatboy
9
+ ##
10
+ # Create a new Fatboy.
11
+ # Options:
12
+ # * +redis:+ : The redis to store views in. By default, Redis.new
13
+ def initialize(redis: Redis.new)
14
+ @redis = redis
15
+ end
16
+ ##
17
+ # Say that you have viewed an object, making the proper records for
18
+ # hour, day, month, and year.
19
+ # * +model+ - a model of some sort. Should quack like an ActiveRecord model (that is, responding to .id)
20
+ def view(obj)
21
+ throw ArgumentError.new("That doesn't quack like a model!") unless obj.respond_to?(:id)
22
+ stores = Fatboy::Helpers.all_format(Time.now).map do |time|
23
+ Fatboy::Helpers.format_store(obj.class.to_s, time)
24
+ end
25
+ stores.map{|store| inc_member(store, obj.id)}
26
+ end
27
+ ##
28
+ # let users view with a shorthand
29
+ alias :[] view
30
+ ##
31
+ # This method returns a Fatboy::Popularity, the main interface for
32
+ # determining the popularity of your models.
33
+ # Example:
34
+ # fatboy.popular(Image)
35
+ # fatboy.popular("Image")
36
+ # fatboy.popular(model.class)
37
+ def popular(model)
38
+ Popularity.new(model, @redis)
39
+ end
40
+ ##
41
+ # Format string we use to store the views per hour
42
+ HOUR_FORMAT_STR = "%Y%m%d%H"
43
+ ##
44
+ # Format string we use to store the views per day
45
+ DAY_FORMAT_STR = "%Y%m%d"
46
+ ##
47
+ # Format string we use to store the views per month
48
+ MONTH_FORMAT_STR = "%Y%m"
49
+ ##
50
+ # Format string we use to store the views per year
51
+ YEAR_FORMAT_STR = "%Y"
52
+ private
53
+ def inc_member(store, id)
54
+ @redis.zincrby(store, 1, id)
55
+ end
56
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+ RSpec.describe Fatboy do
3
+ it "can be initialized" do
4
+ expect{Fatboy.new}.to_not raise_error
5
+ end
6
+ let(:redis){MockRedis.new}
7
+ let(:f){Fatboy.new(redis: redis)}
8
+ describe "storage" do
9
+ before(:each){Timecop.freeze(Date.today)}
10
+ after(:each){Timecop.return}
11
+ it "ads to the redis" do
12
+ l = Fatboy::Helpers.day_format(Time.now)
13
+ l = Fatboy::Helpers.format_store("Model", l)
14
+ expect{
15
+ f.view(Model.new(10))
16
+ }.to change{redis.zcount(l, -100, 100)}.from(0).to(1)
17
+ f.view(Model.new(11))
18
+ expect(redis.zscore(l, 11)).to eq(1)
19
+ end
20
+
21
+ end
22
+ describe "ordering" do
23
+
24
+ before(:each){Timecop.freeze(Date.today)}
25
+ after(:each){Timecop.return}
26
+ it "orders views by day" do
27
+ 2.times{f.view(Model.new(10))}
28
+ 1.times{f.view(Model.new(11))}
29
+ expect(f.popular(Model).today.most.id).to eq(10)
30
+ end
31
+ it "orders views by month" do
32
+ 2.times{f.view(Model.new(10))}
33
+ 1.times{f.view(Model.new(11))}
34
+ expect(f.popular(Model).this_month.most.id).to eq(10)
35
+ end
36
+ it "orders views by year" do
37
+ 2.times{f.view(Model.new(10))}
38
+ 1.times{f.view(Model.new(11))}
39
+ expect(f.popular(Model).this_year.most.id).to eq(10)
40
+ end
41
+ end
42
+ describe "popularity finding" do
43
+ it "doesn't throw an error" do
44
+ expect{f.popular(Model)}.to_not raise_error
45
+ end
46
+ it "returns a popularity" do
47
+ expect(f.popular(Model)).to be_instance_of(Fatboy::Popularity)
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,8 @@
1
+ ##
2
+ # Insanely simple mock model class.
3
+ class Model
4
+ def initialize(id)
5
+ @id = id
6
+ end
7
+ attr_accessor :id
8
+ end
@@ -0,0 +1,13 @@
1
+ require 'bundler/setup'
2
+ Bundler.setup
3
+ require 'simplecov'
4
+ SimpleCov.start
5
+ require 'fatboy'
6
+ require_relative './mocks/model.rb'
7
+ require 'timecop'
8
+ require 'mock_redis'
9
+
10
+ RSpec.configure do |config|
11
+ # Don't need to actually do anything
12
+ end
13
+
metadata ADDED
@@ -0,0 +1,163 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fatboy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Anthony Super
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: timecop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: mock_redis
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: redis
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: "\n Fatboy is a gem designed to easily keep track of views.\n It doesn't
112
+ touch your SQL, and stays slim in redis.\n It also makes it easy to query based
113
+ on how viewed something is.\n "
114
+ email:
115
+ - anthony@noided.media
116
+ executables: []
117
+ extensions: []
118
+ extra_rdoc_files: []
119
+ files:
120
+ - ".gitignore"
121
+ - Gemfile
122
+ - LICENSE.txt
123
+ - README.md
124
+ - Rakefile
125
+ - fatboy.gemspec
126
+ - lib/fatboy.rb
127
+ - lib/fatboy/helpers.rb
128
+ - lib/fatboy/popularity.rb
129
+ - lib/fatboy/time_based_popularity.rb
130
+ - lib/fatboy/version.rb
131
+ - lib/fatboy/viewed_item.rb
132
+ - spec/fatboy_spec.rb
133
+ - spec/mocks/model.rb
134
+ - spec/spec_helper.rb
135
+ homepage: http://github.com/AnthonySuper/fatboy
136
+ licenses:
137
+ - MIT
138
+ metadata: {}
139
+ post_install_message:
140
+ rdoc_options: []
141
+ require_paths:
142
+ - lib
143
+ required_ruby_version: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ version: '2.0'
148
+ required_rubygems_version: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ requirements: []
154
+ rubyforge_project:
155
+ rubygems_version: 2.2.2
156
+ signing_key:
157
+ specification_version: 4
158
+ summary: Fatboy keeps track of your models's views, right here, right now.
159
+ test_files:
160
+ - spec/fatboy_spec.rb
161
+ - spec/mocks/model.rb
162
+ - spec/spec_helper.rb
163
+ has_rdoc: