notches 0.3.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.
- data/.gitignore +7 -0
- data/Gemfile +3 -0
- data/HISTORY +2 -0
- data/LICENSE +20 -0
- data/README.md +54 -0
- data/Rakefile +11 -0
- data/app/assets/images/notches/hit.gif +0 -0
- data/app/controllers/notches/hits_controller.rb +18 -0
- data/app/models/notches/date.rb +6 -0
- data/app/models/notches/hit.rb +37 -0
- data/app/models/notches/ip.rb +8 -0
- data/app/models/notches/session.rb +8 -0
- data/app/models/notches/time.rb +6 -0
- data/app/models/notches/url.rb +8 -0
- data/app/models/notches/user_agent.rb +5 -0
- data/config.ru +7 -0
- data/config/routes.rb +3 -0
- data/db/migrate/20120323111734_create_notches.rb +55 -0
- data/db/migrate/20120713142636_create_notches_user_agents.rb +34 -0
- data/lib/notches.rb +3 -0
- data/lib/notches/engine.rb +5 -0
- data/lib/notches/version.rb +3 -0
- data/notches.gemspec +28 -0
- data/spec/controllers/notches/hits_controller_spec.rb +26 -0
- data/spec/internal/config/database.yml +3 -0
- data/spec/internal/config/routes.rb +5 -0
- data/spec/internal/db/schema.rb +2 -0
- data/spec/internal/log/.gitignore +1 -0
- data/spec/internal/public/favicon.ico +0 -0
- data/spec/models/notches/hit_spec.rb +156 -0
- data/spec/spec_helper.rb +12 -0
- metadata +155 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/HISTORY
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Hyper Tiny
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
Notches
|
2
|
+
-------
|
3
|
+
|
4
|
+
A Rails Engine for tracking your web traffic.
|
5
|
+
|
6
|
+
Installation
|
7
|
+
------------
|
8
|
+
|
9
|
+
Add this to your Gemfile and run the `bundle` command.
|
10
|
+
|
11
|
+
gem 'notches', '~> 0.1.0'
|
12
|
+
|
13
|
+
And then install and run the necessary migrations.
|
14
|
+
|
15
|
+
rake notches:install:migrations
|
16
|
+
rake db:migrate
|
17
|
+
|
18
|
+
Mount your engine at your desired location in `config/routes.rb`.
|
19
|
+
|
20
|
+
mount Notches::Engine => '/notches'
|
21
|
+
|
22
|
+
Finally to start recording hits include the notch pixel image at the bottom of your views.
|
23
|
+
|
24
|
+
<%= image_tag "/notches/hits/new.gif?url=#{request.url}" %>
|
25
|
+
|
26
|
+
Counting hits
|
27
|
+
-------------
|
28
|
+
|
29
|
+
For a URL:
|
30
|
+
|
31
|
+
Notches::Hit.joins(:url).where('url like ?', '/posts').count
|
32
|
+
|
33
|
+
For an IP:
|
34
|
+
|
35
|
+
Notches::Hit.joins(:ip).where('ip = ?', '127.0.0.1').count
|
36
|
+
|
37
|
+
For a session id:
|
38
|
+
|
39
|
+
Notches::Hit.joins(:session).where('session_id = ?', 'abcd').count
|
40
|
+
|
41
|
+
For a date:
|
42
|
+
|
43
|
+
Notches::Hit.joins(:date).where('date = ?', Date.today).count
|
44
|
+
|
45
|
+
For a particular time of day:
|
46
|
+
|
47
|
+
Notches::Hit.joins(:time).where('time between ?', '09:00:00', '17:00:00').count
|
48
|
+
|
49
|
+
Or a user agent:
|
50
|
+
|
51
|
+
Notches::Hit.joins(:user_agent).where('user_agent like ?', '%Mobile%').count
|
52
|
+
|
53
|
+
To get a better idea of how Notches is setup check out the
|
54
|
+
[Notches::Hit](http://github.com/hypertiny/notches/blob/master/app/models/notches/hit.rb) model.
|
data/Rakefile
ADDED
Binary file
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class Notches::HitsController < ActionController::Base
|
2
|
+
def new
|
3
|
+
session[:notches]
|
4
|
+
Notches::Hit.log(
|
5
|
+
:url => params[:url],
|
6
|
+
:user_agent => request.env["HTTP_USER_AGENT"],
|
7
|
+
:session_id => request.session_options[:id],
|
8
|
+
:ip => request.remote_ip
|
9
|
+
)
|
10
|
+
|
11
|
+
# Don't cache the image.
|
12
|
+
response.header["Last-Modified"] = Time.now.httpdate
|
13
|
+
|
14
|
+
send_file Notches::Engine.root.join("app/assets/images/notches/hit.gif"),
|
15
|
+
:type => "image/gif",
|
16
|
+
:disposition => "inline"
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class Notches::Hit < ActiveRecord::Base
|
2
|
+
self.table_name = "notches_hits"
|
3
|
+
|
4
|
+
validates :url, :presence => true
|
5
|
+
validates :session, :presence => true
|
6
|
+
validates :ip, :presence => true
|
7
|
+
|
8
|
+
validates_associated :url, :session, :ip
|
9
|
+
|
10
|
+
belongs_to :url, :foreign_key => :notches_url_id, :class_name => "URL"
|
11
|
+
belongs_to :user_agent, :foreign_key => :notches_user_agent_id
|
12
|
+
belongs_to :session, :foreign_key => :notches_session_id
|
13
|
+
belongs_to :ip, :foreign_key => :notches_ip_id, :class_name => "IP"
|
14
|
+
belongs_to :date, :foreign_key => :notches_date_id
|
15
|
+
belongs_to :time, :foreign_key => :notches_time_id
|
16
|
+
|
17
|
+
scope :unique, group("notches_url_id, notches_session_id, notches_ip_id")
|
18
|
+
|
19
|
+
def self.log(attributes)
|
20
|
+
hit = self.new
|
21
|
+
hit.transaction do
|
22
|
+
Rails.logger.info("[Notches] Tracking #{attributes.inspect} at #{Date.today} #{Time.now}")
|
23
|
+
hit.url = Notches::URL.find_or_create_by_url(attributes[:url])
|
24
|
+
hit.user_agent = Notches::UserAgent.find_or_create_by_user_agent(attributes[:user_agent])
|
25
|
+
hit.session = Notches::Session.find_or_create_by_session_id(attributes[:session_id])
|
26
|
+
hit.ip = Notches::IP.find_or_create_by_ip(attributes[:ip])
|
27
|
+
hit.date = Notches::Date.find_or_create_by_date(Date.today)
|
28
|
+
hit.time = Notches::Time.find_or_create_by_time(Time.now)
|
29
|
+
begin
|
30
|
+
hit.save!
|
31
|
+
rescue #ActiveRecord::RecordNotUnique
|
32
|
+
Rails.logger.info "Skipping non-unique hit"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
hit
|
36
|
+
end
|
37
|
+
end
|
data/config.ru
ADDED
data/config/routes.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
class CreateNotches < ActiveRecord::Migration
|
2
|
+
def up
|
3
|
+
create_table :notches_urls do |t|
|
4
|
+
t.string :url
|
5
|
+
end
|
6
|
+
create_table :notches_sessions do |t|
|
7
|
+
t.string :session_id
|
8
|
+
end
|
9
|
+
create_table :notches_ips do |t|
|
10
|
+
t.string :ip
|
11
|
+
end
|
12
|
+
create_table :notches_dates do |t|
|
13
|
+
t.date :date
|
14
|
+
end
|
15
|
+
create_table :notches_times do |t|
|
16
|
+
t.time :time
|
17
|
+
end
|
18
|
+
create_table :notches_hits do |t|
|
19
|
+
t.integer :notches_url_id, :null => false
|
20
|
+
t.integer :notches_session_id, :null => false
|
21
|
+
t.integer :notches_ip_id, :null => false
|
22
|
+
t.integer :notches_date_id, :null => false
|
23
|
+
t.integer :notches_time_id, :null => false
|
24
|
+
end
|
25
|
+
add_index :notches_urls, :url
|
26
|
+
add_index :notches_sessions, :session_id
|
27
|
+
add_index :notches_ips, :ip
|
28
|
+
add_index :notches_dates, :date
|
29
|
+
add_index :notches_times, :time
|
30
|
+
add_index :notches_hits, [
|
31
|
+
:notches_time_id,
|
32
|
+
:notches_date_id,
|
33
|
+
:notches_ip_id,
|
34
|
+
:notches_session_id,
|
35
|
+
:notches_url_id
|
36
|
+
], :name => :notches_index, :unique => true
|
37
|
+
end
|
38
|
+
|
39
|
+
def down
|
40
|
+
remove_index :notches_urls, :url
|
41
|
+
remove_index :notches_sessions, :session_id
|
42
|
+
remove_index :notches_ips, :ip
|
43
|
+
remove_index :notches_dates, :date
|
44
|
+
remove_index :notches_times, :time
|
45
|
+
change_table :notches_hits do |t|
|
46
|
+
t.remove_index :name => :notches_index
|
47
|
+
end
|
48
|
+
drop_table :notches_urls
|
49
|
+
drop_table :notches_sessions
|
50
|
+
drop_table :notches_ips
|
51
|
+
drop_table :notches_dates
|
52
|
+
drop_table :notches_times
|
53
|
+
drop_table :notches_hits
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class CreateNotchesUserAgents < ActiveRecord::Migration
|
2
|
+
def up
|
3
|
+
create_table :notches_user_agents do |t|
|
4
|
+
t.text :user_agent
|
5
|
+
end
|
6
|
+
add_column :notches_hits, :notches_user_agent_id, :integer
|
7
|
+
change_table :notches_hits do |t|
|
8
|
+
t.remove_index :name => :notches_index
|
9
|
+
end
|
10
|
+
add_index :notches_hits, [
|
11
|
+
:notches_time_id,
|
12
|
+
:notches_date_id,
|
13
|
+
:notches_ip_id,
|
14
|
+
:notches_session_id,
|
15
|
+
:notches_url_id,
|
16
|
+
:notches_user_agent_id
|
17
|
+
], :name => :notches_index, :unique => true
|
18
|
+
end
|
19
|
+
|
20
|
+
def down
|
21
|
+
change_table :notches_hits do |t|
|
22
|
+
t.remove_index :name => :notches_index
|
23
|
+
end
|
24
|
+
add_index :notches_hits, [
|
25
|
+
:notches_time_id,
|
26
|
+
:notches_date_id,
|
27
|
+
:notches_ip_id,
|
28
|
+
:notches_session_id,
|
29
|
+
:notches_url_id
|
30
|
+
], :name => :notches_index, :unique => true
|
31
|
+
remove_column :notches_hits, :notches_user_agent_id
|
32
|
+
drop_table :notches_user_agents
|
33
|
+
end
|
34
|
+
end
|
data/lib/notches.rb
ADDED
data/notches.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "notches/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'notches'
|
7
|
+
s.version = Notches::VERSION
|
8
|
+
s.authors = ["Cillian O'Ruanaidh", "Paul Campbell"]
|
9
|
+
s.email = ['contact@cilliano.com']
|
10
|
+
s.homepage = 'http://github.com/hypertiny/notches'
|
11
|
+
s.summary = %q{Simple Rails web traffic counter}
|
12
|
+
s.description = %q{A Rails Engine for tracking your web traffic.}
|
13
|
+
|
14
|
+
s.rubyforge_project = 'notches'
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f|
|
19
|
+
File.basename(f)
|
20
|
+
}
|
21
|
+
s.require_paths = ['lib']
|
22
|
+
|
23
|
+
s.add_runtime_dependency 'rails', '~> 3.1'
|
24
|
+
|
25
|
+
s.add_development_dependency 'combustion', '~> 0.3.2'
|
26
|
+
s.add_development_dependency 'rspec-rails', '~> 2.11'
|
27
|
+
s.add_development_dependency 'sqlite3', '~> 1.3.4'
|
28
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Notches::HitsController do
|
4
|
+
describe "#new" do
|
5
|
+
it "returns an image" do
|
6
|
+
get :new, :url => '/posts', :format => 'gif'
|
7
|
+
|
8
|
+
response.headers["Content-Type"].should == 'image/gif'
|
9
|
+
end
|
10
|
+
|
11
|
+
it "logs the hit" do
|
12
|
+
@request.env['HTTP_USER_AGENT'] = 'FeedBurner/1.0'
|
13
|
+
@request.stub(:remote_ip => '234.101.82.14')
|
14
|
+
@request.stub(:session_options => { :id => 'abcd' })
|
15
|
+
|
16
|
+
get :new, :url => '/posts', :format => 'gif'
|
17
|
+
|
18
|
+
Notches::Hit.count.should == 1
|
19
|
+
hit = Notches::Hit.first
|
20
|
+
hit.url.url.should == '/posts'
|
21
|
+
hit.user_agent.user_agent.should == 'FeedBurner/1.0'
|
22
|
+
hit.ip.ip.should == '234.101.82.14'
|
23
|
+
hit.session.session_id.should == 'abcd'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
*.log
|
File without changes
|
@@ -0,0 +1,156 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Notches::Hit do
|
4
|
+
describe "validations" do
|
5
|
+
let(:hit) do
|
6
|
+
Notches::Hit.new(
|
7
|
+
:url => Notches::URL.new(:url => "/posts"),
|
8
|
+
:session => Notches::Session.new(:session_id => '1234'),
|
9
|
+
:ip => Notches::IP.new(:ip => '209.85.143.94')
|
10
|
+
)
|
11
|
+
end
|
12
|
+
|
13
|
+
its "valid with valid attributes" do
|
14
|
+
hit.should be_valid
|
15
|
+
end
|
16
|
+
|
17
|
+
it "requires an ip" do
|
18
|
+
hit.ip = nil
|
19
|
+
hit.should have(1).error_on(:ip)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "requires a session" do
|
23
|
+
hit.session = nil
|
24
|
+
hit.should have(1).error_on(:session)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "requires a " do
|
28
|
+
hit.url = nil
|
29
|
+
hit.should have(1).error_on(:url)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "does not validate if its IP's ip blank" do
|
33
|
+
hit.ip = Notches::IP.new(:ip => '')
|
34
|
+
hit.should have(1).error_on(:ip)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "does not validate if its Session's session_id is blank" do
|
38
|
+
hit.session = Notches::Session.new(:session_id => '')
|
39
|
+
hit.should have(1).error_on(:session)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "does not validate if its URL's url is blank" do
|
43
|
+
hit.url = Notches::URL.new(:url => '')
|
44
|
+
hit.should have(1).error_on(:url)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe ".log" do
|
49
|
+
|
50
|
+
context "with valid attributes" do
|
51
|
+
let(:today) { Date.today }
|
52
|
+
let(:now) { Time.now }
|
53
|
+
before do
|
54
|
+
Date.stub(:today => today)
|
55
|
+
Time.stub(:now => now)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "creates a hit for today and current time with those attributes" do
|
59
|
+
Notches::Hit.log({
|
60
|
+
:url => '/posts',
|
61
|
+
:user_agent => 'FeedBurner/1.0',
|
62
|
+
:session_id => '1',
|
63
|
+
:ip => '0.0.0.1'
|
64
|
+
})
|
65
|
+
hit = Notches::Hit.first
|
66
|
+
hit.should be_present
|
67
|
+
hit.url.url.should == '/posts'
|
68
|
+
hit.session.session_id.should == '1'
|
69
|
+
hit.ip.ip.should == '0.0.0.1'
|
70
|
+
hit.date.date.should == today
|
71
|
+
hit.time.time.strftime('%H:%M:%S').should == now.strftime('%H:%M:%S')
|
72
|
+
hit.user_agent.user_agent.should == 'FeedBurner/1.0'
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
let(:existing_hit) {
|
77
|
+
Notches::Hit.log(
|
78
|
+
:url => "/posts/1",
|
79
|
+
:user_agent => 'FeedBurner/1.0',
|
80
|
+
:session_id => '1',
|
81
|
+
:ip => '0.0.0.1'
|
82
|
+
)
|
83
|
+
}
|
84
|
+
|
85
|
+
it "does not create a new IP record if there's a record for that IP already" do
|
86
|
+
hit = Notches::Hit.log(
|
87
|
+
:url => "/posts/2",
|
88
|
+
:session_id => '2',
|
89
|
+
:ip => existing_hit.ip.ip
|
90
|
+
)
|
91
|
+
hit.ip.id.should == existing_hit.ip.id
|
92
|
+
end
|
93
|
+
|
94
|
+
it "does not create a new URL record if there's a record for that URL already" do
|
95
|
+
hit = Notches::Hit.log(
|
96
|
+
:url => existing_hit.url.url,
|
97
|
+
:session_id => '2',
|
98
|
+
:ip => '0.0.0.2'
|
99
|
+
)
|
100
|
+
hit.url.id.should == existing_hit.url.id
|
101
|
+
end
|
102
|
+
|
103
|
+
it "does not create a new Session record there's a record for that session id already" do
|
104
|
+
hit = Notches::Hit.log(
|
105
|
+
:url => "/posts/2",
|
106
|
+
:session_id => existing_hit.session.session_id,
|
107
|
+
:ip => '0.0.0.2'
|
108
|
+
)
|
109
|
+
hit.session.id.should == existing_hit.session.id
|
110
|
+
end
|
111
|
+
|
112
|
+
it "does not create a new Date record there's a record for that Date already" do
|
113
|
+
hit = Notches::Hit.log(
|
114
|
+
:url => '/posts/2',
|
115
|
+
:session_id => '2',
|
116
|
+
:ip => '0.0.0.2'
|
117
|
+
)
|
118
|
+
hit.date.id.should == existing_hit.date.id
|
119
|
+
end
|
120
|
+
|
121
|
+
it "does not create a new Time record there's a record for that Time already" do
|
122
|
+
Time.stub(:now => existing_hit.time.time)
|
123
|
+
hit = Notches::Hit.log(
|
124
|
+
:url => '/posts/2',
|
125
|
+
:session_id => '2',
|
126
|
+
:ip => '0.0.0.2'
|
127
|
+
)
|
128
|
+
hit.time.id.should == existing_hit.time.id
|
129
|
+
end
|
130
|
+
|
131
|
+
it "does not create a new UserAgent record if there's a record for that UserAgent already" do
|
132
|
+
hit = Notches::Hit.log(
|
133
|
+
:url => '/post/2',
|
134
|
+
:user_agent => 'FeedBurner/1.0',
|
135
|
+
:session_id => '2',
|
136
|
+
:ip => '0.0.0.2'
|
137
|
+
)
|
138
|
+
hit.user_agent.id.should == existing_hit.user_agent.id
|
139
|
+
end
|
140
|
+
|
141
|
+
context "a hit with the same url, session, ip, date and time exists already" do
|
142
|
+
it "does not log the hit" do
|
143
|
+
Date.stub(:today => existing_hit.date.date)
|
144
|
+
Time.stub(:now => existing_hit.time.time)
|
145
|
+
expect {
|
146
|
+
hit = Notches::Hit.log(
|
147
|
+
:url => existing_hit.url.url,
|
148
|
+
:user_agent => 'FeedBurner/1.0',
|
149
|
+
:session_id => existing_hit.session.session_id,
|
150
|
+
:ip => existing_hit.ip.ip
|
151
|
+
)
|
152
|
+
}.to_not change { Notches::Hit.count }
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: notches
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Cillian O'Ruanaidh
|
9
|
+
- Paul Campbell
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2012-07-22 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rails
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ~>
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '3.1'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ~>
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '3.1'
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: combustion
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
35
|
+
requirements:
|
36
|
+
- - ~>
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: 0.3.2
|
39
|
+
type: :development
|
40
|
+
prerelease: false
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ~>
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 0.3.2
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rspec-rails
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.11'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ~>
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '2.11'
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: sqlite3
|
65
|
+
requirement: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ~>
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: 1.3.4
|
71
|
+
type: :development
|
72
|
+
prerelease: false
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ~>
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: 1.3.4
|
79
|
+
description: A Rails Engine for tracking your web traffic.
|
80
|
+
email:
|
81
|
+
- contact@cilliano.com
|
82
|
+
executables: []
|
83
|
+
extensions: []
|
84
|
+
extra_rdoc_files: []
|
85
|
+
files:
|
86
|
+
- .gitignore
|
87
|
+
- Gemfile
|
88
|
+
- HISTORY
|
89
|
+
- LICENSE
|
90
|
+
- README.md
|
91
|
+
- Rakefile
|
92
|
+
- app/assets/images/notches/hit.gif
|
93
|
+
- app/controllers/notches/hits_controller.rb
|
94
|
+
- app/models/notches/date.rb
|
95
|
+
- app/models/notches/hit.rb
|
96
|
+
- app/models/notches/ip.rb
|
97
|
+
- app/models/notches/session.rb
|
98
|
+
- app/models/notches/time.rb
|
99
|
+
- app/models/notches/url.rb
|
100
|
+
- app/models/notches/user_agent.rb
|
101
|
+
- config.ru
|
102
|
+
- config/routes.rb
|
103
|
+
- db/migrate/20120323111734_create_notches.rb
|
104
|
+
- db/migrate/20120713142636_create_notches_user_agents.rb
|
105
|
+
- lib/notches.rb
|
106
|
+
- lib/notches/engine.rb
|
107
|
+
- lib/notches/version.rb
|
108
|
+
- notches.gemspec
|
109
|
+
- spec/controllers/notches/hits_controller_spec.rb
|
110
|
+
- spec/internal/config/database.yml
|
111
|
+
- spec/internal/config/routes.rb
|
112
|
+
- spec/internal/db/schema.rb
|
113
|
+
- spec/internal/log/.gitignore
|
114
|
+
- spec/internal/public/favicon.ico
|
115
|
+
- spec/models/notches/hit_spec.rb
|
116
|
+
- spec/spec_helper.rb
|
117
|
+
homepage: http://github.com/hypertiny/notches
|
118
|
+
licenses: []
|
119
|
+
post_install_message:
|
120
|
+
rdoc_options: []
|
121
|
+
require_paths:
|
122
|
+
- lib
|
123
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
124
|
+
none: false
|
125
|
+
requirements:
|
126
|
+
- - ! '>='
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
segments:
|
130
|
+
- 0
|
131
|
+
hash: 1181156043935805657
|
132
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
|
+
none: false
|
134
|
+
requirements:
|
135
|
+
- - ! '>='
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
138
|
+
segments:
|
139
|
+
- 0
|
140
|
+
hash: 1181156043935805657
|
141
|
+
requirements: []
|
142
|
+
rubyforge_project: notches
|
143
|
+
rubygems_version: 1.8.24
|
144
|
+
signing_key:
|
145
|
+
specification_version: 3
|
146
|
+
summary: Simple Rails web traffic counter
|
147
|
+
test_files:
|
148
|
+
- spec/controllers/notches/hits_controller_spec.rb
|
149
|
+
- spec/internal/config/database.yml
|
150
|
+
- spec/internal/config/routes.rb
|
151
|
+
- spec/internal/db/schema.rb
|
152
|
+
- spec/internal/log/.gitignore
|
153
|
+
- spec/internal/public/favicon.ico
|
154
|
+
- spec/models/notches/hit_spec.rb
|
155
|
+
- spec/spec_helper.rb
|