fatboy 0.0.1

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 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: