visitors 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.
- data/.gitignore +4 -0
- data/.rspec +1 -0
- data/.rvmrc +1 -0
- data/Gemfile +4 -0
- data/Guardfile +5 -0
- data/README.md +12 -0
- data/Rakefile +2 -0
- data/bin/visitors +11 -0
- data/config.yml +5 -0
- data/lib/visitors.rb +26 -0
- data/lib/visitors/archiver.rb +25 -0
- data/lib/visitors/cli.rb +13 -0
- data/lib/visitors/config.rb +32 -0
- data/lib/visitors/helpers.rb +55 -0
- data/lib/visitors/models.rb +25 -0
- data/lib/visitors/resource.rb +41 -0
- data/lib/visitors/version.rb +3 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/visitors/config_spec.rb +18 -0
- data/spec/visitors/models_spec.rb +10 -0
- data/spec/visitors/resource_spec.rb +37 -0
- data/spec/visitors_spec.rb +14 -0
- data/visitors.gemspec +37 -0
- metadata +192 -0
data/.gitignore
ADDED
data/.rspec
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
--profile
|
data/.rvmrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
rvm use 1.9.2@visitors
|
data/Gemfile
ADDED
data/Guardfile
ADDED
data/README.md
ADDED
data/Rakefile
ADDED
data/bin/visitors
ADDED
data/config.yml
ADDED
data/lib/visitors.rb
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
$:.push File.expand_path('..', __FILE__)
|
|
2
|
+
require 'visitors/helpers'
|
|
3
|
+
|
|
4
|
+
module Visitors
|
|
5
|
+
extend self
|
|
6
|
+
|
|
7
|
+
autoload :Config, 'visitors/config'
|
|
8
|
+
autoload :Resource, 'visitors/resource'
|
|
9
|
+
|
|
10
|
+
autoload :Archiver, 'visitors/archiver'
|
|
11
|
+
autoload :Day, 'visitors/models'
|
|
12
|
+
autoload :Month, 'visitors/models'
|
|
13
|
+
autoload :Year, 'visitors/models'
|
|
14
|
+
|
|
15
|
+
def config
|
|
16
|
+
@config ||= Config.load
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def find(id)
|
|
20
|
+
Resource.find(id)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def increment(id, field)
|
|
24
|
+
Resource.new(id).increment(field)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
class Visitors::Archiver
|
|
2
|
+
Day = Visitors::Day
|
|
3
|
+
Month = Visitors::Month
|
|
4
|
+
Year = Visitors::Year
|
|
5
|
+
|
|
6
|
+
def archive_yesterday
|
|
7
|
+
Day.all.map do |day|
|
|
8
|
+
execute()
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def save_today
|
|
13
|
+
Day.destroy
|
|
14
|
+
|
|
15
|
+
Visitors.store.slice.map do |id, stats|
|
|
16
|
+
Day.create(stats.merge(:resource_id => id))
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def execute(*args)
|
|
23
|
+
Day.repository.adapter.select(*args)
|
|
24
|
+
end
|
|
25
|
+
end
|
data/lib/visitors/cli.rb
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require 'thor'
|
|
2
|
+
|
|
3
|
+
class Visitors::CLI < Thor
|
|
4
|
+
desc 'store', 'start the redis in-memory store'
|
|
5
|
+
def store
|
|
6
|
+
say "You're running in development, do it yourself!", :blue
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
desc 'web', 'start the web console (NOT IMPLEMENTED)'
|
|
10
|
+
def web
|
|
11
|
+
say 'Not implemented yet', :red
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
class Visitors::Config
|
|
2
|
+
class MissingEnvironmentError < StandardError; end
|
|
3
|
+
|
|
4
|
+
def self.load
|
|
5
|
+
new.tap { |instance| instance.send(:define_methods_from_yaml) }
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def all
|
|
9
|
+
return yaml[env] if yaml[env]
|
|
10
|
+
raise MissingEnvironmentError, "#{env.inspect} environment not configured"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def inspect
|
|
14
|
+
all.inspect
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def yaml
|
|
20
|
+
@yaml ||= YAML.load_file(File.expand_path('../../../config.yml', __FILE__))
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def env
|
|
24
|
+
ENV['VISITORS_ENV'] || 'development'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def define_methods_from_yaml
|
|
28
|
+
all.each do |key, value|
|
|
29
|
+
self.class.send(:define_method, key) { value }
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
require 'redis'
|
|
2
|
+
require 'redis-namespace'
|
|
3
|
+
|
|
4
|
+
module Helpers
|
|
5
|
+
class UnsupportedField < StandardError; end
|
|
6
|
+
|
|
7
|
+
FIELDS = [:show, :search, :email, :website]
|
|
8
|
+
SET_NAME = 'resource_ids'
|
|
9
|
+
|
|
10
|
+
def redis
|
|
11
|
+
@redis ||= Redis::Namespace.new(Visitors.config.redis_namespace,
|
|
12
|
+
:redis => redis_connection)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def fields
|
|
16
|
+
FIELDS
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def assert_valid_field!(name)
|
|
20
|
+
unless fields.include?(name)
|
|
21
|
+
error_message = "Invalid field #{name.inspect}. Valid fields are #{fields.inspect}"
|
|
22
|
+
raise UnsupportedField, error_message
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def stats_for(key)
|
|
27
|
+
redis.hgetall(key)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def count
|
|
31
|
+
redis.scard(SET_NAME)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def known_ids
|
|
35
|
+
redis.smembers(SET_NAME)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def parse_date(date)
|
|
39
|
+
date = date.to_s
|
|
40
|
+
case date
|
|
41
|
+
when /\d{4}/
|
|
42
|
+
date
|
|
43
|
+
when /\d{1,2}/
|
|
44
|
+
Time.now.strftime("#{'%02d' % date}%y")
|
|
45
|
+
else
|
|
46
|
+
Time.now.strftime('%m%y')
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def redis_connection
|
|
53
|
+
@redis_connection ||= Redis.new(Visitors.config.redis_config)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'dm-core'
|
|
2
|
+
require 'dm-migrations'
|
|
3
|
+
|
|
4
|
+
DataMapper.setup(:default, Visitors.config.database)
|
|
5
|
+
|
|
6
|
+
MODEL_NAMES = %w[Day Month Year]
|
|
7
|
+
|
|
8
|
+
MODEL_NAMES.each do |class_name|
|
|
9
|
+
Visitors.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
|
10
|
+
class Visitors::#{class_name}
|
|
11
|
+
include DataMapper::Resource
|
|
12
|
+
|
|
13
|
+
property :id, Serial
|
|
14
|
+
property :archived, Time
|
|
15
|
+
property :resource_id, Integer, :required => true
|
|
16
|
+
|
|
17
|
+
Visitors::Resource.fields.each do |field|
|
|
18
|
+
property field, Integer, :default => 0, :required => true
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
RUBY
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
DataMapper.finalize
|
|
25
|
+
DataMapper.auto_migrate!
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
class Visitors::Resource
|
|
2
|
+
include Helpers
|
|
3
|
+
extend Helpers
|
|
4
|
+
|
|
5
|
+
MONTHS = (1..12).to_a
|
|
6
|
+
|
|
7
|
+
class << self
|
|
8
|
+
def find(resource_id)
|
|
9
|
+
Hash[*MONTHS.map do |month|
|
|
10
|
+
[month, stats_for(new(resource_id, month).to_redis_key)]
|
|
11
|
+
end.flatten]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def increment(resource_id, field)
|
|
15
|
+
new(resource_id).increment(field)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
alias :incr :increment
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
attr_reader :id, :date
|
|
22
|
+
|
|
23
|
+
def initialize(id, date = nil)
|
|
24
|
+
raise ArgumentError, 'Invalid id' unless id
|
|
25
|
+
@id = id
|
|
26
|
+
@date = parse_date(date)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def to_redis_key
|
|
30
|
+
[id, date].join(':')
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
alias :key :to_redis_key
|
|
34
|
+
|
|
35
|
+
def increment(field)
|
|
36
|
+
assert_valid_field!(field.to_sym)
|
|
37
|
+
|
|
38
|
+
redis.sadd(SET_NAME, id)
|
|
39
|
+
redis.hincrby(key, field, 1)
|
|
40
|
+
end
|
|
41
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Visitors::Config do
|
|
4
|
+
describe '#all' do
|
|
5
|
+
it 'uses the config.yml file to return a hash of configuration information' do
|
|
6
|
+
File.stub!(:expand_path => '/path/to/config.yml')
|
|
7
|
+
YAML.should_receive(:load_file).with('/path/to/config.yml').and_return('development' => {})
|
|
8
|
+
Visitors::Config.load.all
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it 'raises when an environment is not defined' do
|
|
12
|
+
expect {
|
|
13
|
+
YAML.stub!(:load_file => {})
|
|
14
|
+
Visitors::Config.load.all
|
|
15
|
+
}.to raise_error(Visitors::Config::MissingEnvironmentError)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Visitors::Resource do
|
|
4
|
+
def resource(id = nil, date = nil)
|
|
5
|
+
@resource ||= Visitors::Resource.new(id, date)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
describe '#key' do
|
|
9
|
+
context 'with an integer id' do
|
|
10
|
+
context 'with no date' do
|
|
11
|
+
it 'returns the resource id and the current date' do
|
|
12
|
+
Time.stub!(:now => double('time', :strftime => '0311'))
|
|
13
|
+
resource(1).key.should == '1:0311'
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
context 'with a timestamp of the form mmyy' do
|
|
18
|
+
it 'uses the id and the supplied timestamp' do
|
|
19
|
+
resource(1, '0311').key.should == '1:0311'
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
context 'with a nil date' do
|
|
24
|
+
it 'ignores the date and returns the id with the current date' do
|
|
25
|
+
Time.stub!(:now => double('time', :strftime => '0311'))
|
|
26
|
+
resource(1, nil).key.should == '1:0311'
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
context 'with no id' do
|
|
33
|
+
it 'returns an empty key' do
|
|
34
|
+
expect { resource(nil).key }.to raise_error(ArgumentError)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Visitors do
|
|
4
|
+
describe '.assert_valid_field!' do
|
|
5
|
+
it 'protects against using unknown fields' do
|
|
6
|
+
error_message = %{Invalid field "invalid_field". Valid fields are []}
|
|
7
|
+
|
|
8
|
+
expect {
|
|
9
|
+
Visitors.stub!(:fields => %w[])
|
|
10
|
+
Visitors.assert_valid_field!('invalid_field')
|
|
11
|
+
}.to raise_error(Visitors::UnsupportedField, error_message)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
data/visitors.gemspec
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
$:.push File.expand_path('../lib', __FILE__)
|
|
3
|
+
require 'visitors/version'
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |s|
|
|
6
|
+
s.name = 'visitors'
|
|
7
|
+
s.version = Visitors::VERSION
|
|
8
|
+
s.platform = Gem::Platform::RUBY
|
|
9
|
+
s.authors = ['James Conroy-Finn']
|
|
10
|
+
s.email = ['james@logi.cl']
|
|
11
|
+
s.homepage = 'http://github.com/jcf/visitors'
|
|
12
|
+
s.summary = %q{All-in-one fast logging system for your Rails application}
|
|
13
|
+
s.description = %q{Redis-backed activity storage to track visits to different parts of your Ruby web app in real-time.}
|
|
14
|
+
|
|
15
|
+
s.rubyforge_project = 'visitors'
|
|
16
|
+
|
|
17
|
+
s.files = `git ls-files`.split("\n")
|
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
20
|
+
s.require_paths = ['lib']
|
|
21
|
+
|
|
22
|
+
{
|
|
23
|
+
'redis' => '2.1.1',
|
|
24
|
+
'redis-namespace' => '0.10.0',
|
|
25
|
+
'dm-core' => '1.0.2',
|
|
26
|
+
'dm-migrations' => '1.0.2',
|
|
27
|
+
'dm-postgres-adapter' => '1.0.2',
|
|
28
|
+
'sinatra' => '1.1.3',
|
|
29
|
+
'thor' => '0.14.6'
|
|
30
|
+
}.each { |gem, version| s.add_dependency gem, "~> #{version}" }
|
|
31
|
+
|
|
32
|
+
{
|
|
33
|
+
'rspec' => '2.5.0',
|
|
34
|
+
'guard-rspec' => '0.1.9',
|
|
35
|
+
'rb-fsevent' => '0.3.10'
|
|
36
|
+
}.each { |gem, version| s.add_development_dependency gem, "~> #{version}" }
|
|
37
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: visitors
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
prerelease:
|
|
5
|
+
version: 0.0.1
|
|
6
|
+
platform: ruby
|
|
7
|
+
authors:
|
|
8
|
+
- James Conroy-Finn
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
|
|
13
|
+
date: 2011-02-28 00:00:00 +00:00
|
|
14
|
+
default_executable:
|
|
15
|
+
dependencies:
|
|
16
|
+
- !ruby/object:Gem::Dependency
|
|
17
|
+
name: redis
|
|
18
|
+
prerelease: false
|
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
|
20
|
+
none: false
|
|
21
|
+
requirements:
|
|
22
|
+
- - ~>
|
|
23
|
+
- !ruby/object:Gem::Version
|
|
24
|
+
version: 2.1.1
|
|
25
|
+
type: :runtime
|
|
26
|
+
version_requirements: *id001
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: redis-namespace
|
|
29
|
+
prerelease: false
|
|
30
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
|
31
|
+
none: false
|
|
32
|
+
requirements:
|
|
33
|
+
- - ~>
|
|
34
|
+
- !ruby/object:Gem::Version
|
|
35
|
+
version: 0.10.0
|
|
36
|
+
type: :runtime
|
|
37
|
+
version_requirements: *id002
|
|
38
|
+
- !ruby/object:Gem::Dependency
|
|
39
|
+
name: dm-core
|
|
40
|
+
prerelease: false
|
|
41
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
|
42
|
+
none: false
|
|
43
|
+
requirements:
|
|
44
|
+
- - ~>
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: 1.0.2
|
|
47
|
+
type: :runtime
|
|
48
|
+
version_requirements: *id003
|
|
49
|
+
- !ruby/object:Gem::Dependency
|
|
50
|
+
name: dm-migrations
|
|
51
|
+
prerelease: false
|
|
52
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
|
53
|
+
none: false
|
|
54
|
+
requirements:
|
|
55
|
+
- - ~>
|
|
56
|
+
- !ruby/object:Gem::Version
|
|
57
|
+
version: 1.0.2
|
|
58
|
+
type: :runtime
|
|
59
|
+
version_requirements: *id004
|
|
60
|
+
- !ruby/object:Gem::Dependency
|
|
61
|
+
name: dm-postgres-adapter
|
|
62
|
+
prerelease: false
|
|
63
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
|
64
|
+
none: false
|
|
65
|
+
requirements:
|
|
66
|
+
- - ~>
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: 1.0.2
|
|
69
|
+
type: :runtime
|
|
70
|
+
version_requirements: *id005
|
|
71
|
+
- !ruby/object:Gem::Dependency
|
|
72
|
+
name: sinatra
|
|
73
|
+
prerelease: false
|
|
74
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
|
75
|
+
none: false
|
|
76
|
+
requirements:
|
|
77
|
+
- - ~>
|
|
78
|
+
- !ruby/object:Gem::Version
|
|
79
|
+
version: 1.1.3
|
|
80
|
+
type: :runtime
|
|
81
|
+
version_requirements: *id006
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: thor
|
|
84
|
+
prerelease: false
|
|
85
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
|
86
|
+
none: false
|
|
87
|
+
requirements:
|
|
88
|
+
- - ~>
|
|
89
|
+
- !ruby/object:Gem::Version
|
|
90
|
+
version: 0.14.6
|
|
91
|
+
type: :runtime
|
|
92
|
+
version_requirements: *id007
|
|
93
|
+
- !ruby/object:Gem::Dependency
|
|
94
|
+
name: rspec
|
|
95
|
+
prerelease: false
|
|
96
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
|
97
|
+
none: false
|
|
98
|
+
requirements:
|
|
99
|
+
- - ~>
|
|
100
|
+
- !ruby/object:Gem::Version
|
|
101
|
+
version: 2.5.0
|
|
102
|
+
type: :development
|
|
103
|
+
version_requirements: *id008
|
|
104
|
+
- !ruby/object:Gem::Dependency
|
|
105
|
+
name: guard-rspec
|
|
106
|
+
prerelease: false
|
|
107
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
|
108
|
+
none: false
|
|
109
|
+
requirements:
|
|
110
|
+
- - ~>
|
|
111
|
+
- !ruby/object:Gem::Version
|
|
112
|
+
version: 0.1.9
|
|
113
|
+
type: :development
|
|
114
|
+
version_requirements: *id009
|
|
115
|
+
- !ruby/object:Gem::Dependency
|
|
116
|
+
name: rb-fsevent
|
|
117
|
+
prerelease: false
|
|
118
|
+
requirement: &id010 !ruby/object:Gem::Requirement
|
|
119
|
+
none: false
|
|
120
|
+
requirements:
|
|
121
|
+
- - ~>
|
|
122
|
+
- !ruby/object:Gem::Version
|
|
123
|
+
version: 0.3.10
|
|
124
|
+
type: :development
|
|
125
|
+
version_requirements: *id010
|
|
126
|
+
description: Redis-backed activity storage to track visits to different parts of your Ruby web app in real-time.
|
|
127
|
+
email:
|
|
128
|
+
- james@logi.cl
|
|
129
|
+
executables:
|
|
130
|
+
- visitors
|
|
131
|
+
extensions: []
|
|
132
|
+
|
|
133
|
+
extra_rdoc_files: []
|
|
134
|
+
|
|
135
|
+
files:
|
|
136
|
+
- .gitignore
|
|
137
|
+
- .rspec
|
|
138
|
+
- .rvmrc
|
|
139
|
+
- Gemfile
|
|
140
|
+
- Guardfile
|
|
141
|
+
- README.md
|
|
142
|
+
- Rakefile
|
|
143
|
+
- bin/visitors
|
|
144
|
+
- config.yml
|
|
145
|
+
- lib/visitors.rb
|
|
146
|
+
- lib/visitors/archiver.rb
|
|
147
|
+
- lib/visitors/cli.rb
|
|
148
|
+
- lib/visitors/config.rb
|
|
149
|
+
- lib/visitors/helpers.rb
|
|
150
|
+
- lib/visitors/models.rb
|
|
151
|
+
- lib/visitors/resource.rb
|
|
152
|
+
- lib/visitors/version.rb
|
|
153
|
+
- spec/spec_helper.rb
|
|
154
|
+
- spec/visitors/config_spec.rb
|
|
155
|
+
- spec/visitors/models_spec.rb
|
|
156
|
+
- spec/visitors/resource_spec.rb
|
|
157
|
+
- spec/visitors_spec.rb
|
|
158
|
+
- visitors.gemspec
|
|
159
|
+
has_rdoc: true
|
|
160
|
+
homepage: http://github.com/jcf/visitors
|
|
161
|
+
licenses: []
|
|
162
|
+
|
|
163
|
+
post_install_message:
|
|
164
|
+
rdoc_options: []
|
|
165
|
+
|
|
166
|
+
require_paths:
|
|
167
|
+
- lib
|
|
168
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
169
|
+
none: false
|
|
170
|
+
requirements:
|
|
171
|
+
- - ">="
|
|
172
|
+
- !ruby/object:Gem::Version
|
|
173
|
+
version: "0"
|
|
174
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
175
|
+
none: false
|
|
176
|
+
requirements:
|
|
177
|
+
- - ">="
|
|
178
|
+
- !ruby/object:Gem::Version
|
|
179
|
+
version: "0"
|
|
180
|
+
requirements: []
|
|
181
|
+
|
|
182
|
+
rubyforge_project: visitors
|
|
183
|
+
rubygems_version: 1.5.2
|
|
184
|
+
signing_key:
|
|
185
|
+
specification_version: 3
|
|
186
|
+
summary: All-in-one fast logging system for your Rails application
|
|
187
|
+
test_files:
|
|
188
|
+
- spec/spec_helper.rb
|
|
189
|
+
- spec/visitors/config_spec.rb
|
|
190
|
+
- spec/visitors/models_spec.rb
|
|
191
|
+
- spec/visitors/resource_spec.rb
|
|
192
|
+
- spec/visitors_spec.rb
|