hit_counter 1.0.0 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- metadata +4 -52
- checksums.yaml.gz.sig +0 -0
- data/.document +0 -5
- data/.github/ISSUE_TEMPLATE/bug_report.md +0 -23
- data/.github/ISSUE_TEMPLATE/feature_request.md +0 -17
- data/.github/ISSUE_TEMPLATE/task.md +0 -21
- data/.github/PULL_REQUEST_TEMPLATE.md +0 -31
- data/.github/dependabot.yml +0 -11
- data/.github/workflows/test.yml +0 -34
- data/.gitignore +0 -8
- data/.rspec +0 -1
- data/.rubocop.yml +0 -7
- data/.simplecov +0 -15
- data/CODE_OF_CONDUCT.md +0 -10
- data/CONTRIBUTING.md +0 -34
- data/LICENSE.txt +0 -20
- data/README.md +0 -120
- data/SECURITY.md +0 -16
- data/certs/ivanoblomov.pem +0 -26
- data/hit_counter.gemspec +0 -26
- data/lib/version.rb +0 -7
- data/spec/lib/hit_counter_spec.rb +0 -173
- data/spec/spec_helper.rb +0 -63
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 89d0d1a4065e5c9e788a9a3c01edfa904aa6b6e7aad75ee9ecc47c4a6a1618e0
|
4
|
+
data.tar.gz: 68ed08ca3ce41d738e0ab84d2cb74cded78a93faa4cd97ae200656e3a6bc94a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 25c8022ec4dbc94637f287149cd715d45677e29d5c58adee93fc52d1b118ee8e048ae0707ffabcceea9f4c5cb9b5517308c08e0100e401e025e14a49dcbb4fe6
|
7
|
+
data.tar.gz: 757187427c156efd6aef351f85dab4d15fdb25e5e362a3cf6e965b973ba2c778ee9d0b046ce054a85d90c030cbc96672031e52d2bfc018ce9cf11b0bdcb6975a
|
data/Gemfile
CHANGED
metadata
CHANGED
@@ -1,41 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hit_counter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Roderick Monje
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
|
-
cert_chain:
|
11
|
-
-
|
12
|
-
-----BEGIN CERTIFICATE-----
|
13
|
-
MIIEeDCCAuCgAwIBAgIBATANBgkqhkiG9w0BAQsFADBBMQwwCgYDVQQDDANyb2Qx
|
14
|
-
HDAaBgoJkiaJk/IsZAEZFgxmb3ZlYWNlbnRyYWwxEzARBgoJkiaJk/IsZAEZFgNj
|
15
|
-
b20wHhcNMjQwMzI5MjIzNDUxWhcNMjUwMzI5MjIzNDUxWjBBMQwwCgYDVQQDDANy
|
16
|
-
b2QxHDAaBgoJkiaJk/IsZAEZFgxmb3ZlYWNlbnRyYWwxEzARBgoJkiaJk/IsZAEZ
|
17
|
-
FgNjb20wggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQC6asLzbFQpchSv
|
18
|
-
u+05KuCzQW39QZq65t3c0kfUsIx+WREjBw2QlM6jVItYj4euRRszLwxhSMCtMsno
|
19
|
-
Fhas9eZ47esUhxIElQngrsBP0kwLUHQj/EYCDVN2xnMlicoE0zgOXiUkk6PTZZme
|
20
|
-
8SYSFJANVDOdRgr5Q17nWQKPS1l3OqoD+fkM+kO/ey2KTXvv4AFxfwe9o/bk6LjF
|
21
|
-
f4AzxKPmxsYbtgJHiu38gYb2IMh5JE5B0dUQ5pnQJbdTNtHI9YWoVpyIhIj/aOwN
|
22
|
-
t9lKjWhObPgfQ7Z5bEWSWvuPnGD1zj0/Y1MNJ99M4Bt1t5OkS3L1zjg1H3ulYRlB
|
23
|
-
VWFIwC8esooXXWqG5s2XCtVjugOo1seXv8PIOCPM1HBLfYjlWAwGy0oA0kAtAs+4
|
24
|
-
OlciDLHwCJO/ChIeLNaW3f6WiDmcwI8MeyxXxw64kX9QSKP0muM4+GtE9619hPFK
|
25
|
-
RMXUFKNUlrZ6gcpyX5weP2OKwd9Z7LkVsK/lgyxyaDqGwuajBGkCAwEAAaN7MHkw
|
26
|
-
CQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFO1rwHyxg39rlp0MN5Kj
|
27
|
-
s1uxvHyiMB8GA1UdEQQYMBaBFHJvZEBmb3ZlYWNlbnRyYWwuY29tMB8GA1UdEgQY
|
28
|
-
MBaBFHJvZEBmb3ZlYWNlbnRyYWwuY29tMA0GCSqGSIb3DQEBCwUAA4IBgQBg9aO1
|
29
|
-
1OhvQMbzefkcxE1QxuqwGzBh8kNiE2JL5FSGTtgFbXKqM1eeA0GWeZnksSVXOX40
|
30
|
-
01HDxW8CHdBnyNGorJPgbypZNI+gpi5bYKox0en7jj+88k9VA4fIbR+a/6sUSDsZ
|
31
|
-
82qpicz/Q+qkfnhQxHJ1Cj0lrZBq0Kuc+ooNxE4U3VT25CQCvUN9dlgyMZsH15ND
|
32
|
-
DpektzMLDzH4suOVGK09j7C3sTyVdwI5UkN8ix27Me0N4zPxjjYo0HFXIRNhEjVF
|
33
|
-
DWm9LGr9npmhQtd3A3ZyASawp+UUZ5pdc57YaBRDrJdFZr9056MpeByj+Fsg5Jkh
|
34
|
-
4o08iHs5bMPDyXBcj5XsYDLwAwTANPjGWGRNvrnY3KGGWdRMgtni3NJyMRCZ5tIT
|
35
|
-
UNicoJ8NJMgduyTPvZBJtvUPddQr1yAL66/l+CFewbGb/1DbqfSvA2atfUobhDrG
|
36
|
-
zYKOF/ofPEZhX7sqLK5GzDW4x1QDHAgr1YIdttVxhHADOxF4EVSJCHH0RGw=
|
37
|
-
-----END CERTIFICATE-----
|
38
|
-
date: 2024-11-04 00:00:00.000000000 Z
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-12-21 00:00:00.000000000 Z
|
39
12
|
dependencies:
|
40
13
|
- !ruby/object:Gem::Dependency
|
41
14
|
name: addressable
|
@@ -87,31 +60,12 @@ executables: []
|
|
87
60
|
extensions: []
|
88
61
|
extra_rdoc_files: []
|
89
62
|
files:
|
90
|
-
- ".document"
|
91
|
-
- ".github/ISSUE_TEMPLATE/bug_report.md"
|
92
|
-
- ".github/ISSUE_TEMPLATE/feature_request.md"
|
93
|
-
- ".github/ISSUE_TEMPLATE/task.md"
|
94
|
-
- ".github/PULL_REQUEST_TEMPLATE.md"
|
95
|
-
- ".github/dependabot.yml"
|
96
|
-
- ".github/workflows/test.yml"
|
97
|
-
- ".gitignore"
|
98
|
-
- ".rspec"
|
99
|
-
- ".rubocop.yml"
|
100
|
-
- ".simplecov"
|
101
|
-
- CODE_OF_CONDUCT.md
|
102
|
-
- CONTRIBUTING.md
|
103
63
|
- Gemfile
|
104
|
-
- LICENSE.txt
|
105
|
-
- README.md
|
106
64
|
- Rakefile
|
107
|
-
- SECURITY.md
|
108
|
-
- certs/ivanoblomov.pem
|
109
65
|
- config/initializers/mime_types.rb
|
110
66
|
- config/mongoid.yml
|
111
|
-
- hit_counter.gemspec
|
112
67
|
- lib/hit_counter.rb
|
113
68
|
- lib/tasks/install.rake
|
114
|
-
- lib/version.rb
|
115
69
|
- public/images/digits/celtic/0.png
|
116
70
|
- public/images/digits/celtic/1.png
|
117
71
|
- public/images/digits/celtic/2.png
|
@@ -142,8 +96,6 @@ files:
|
|
142
96
|
- public/images/digits/scout/7.png
|
143
97
|
- public/images/digits/scout/8.png
|
144
98
|
- public/images/digits/scout/9.png
|
145
|
-
- spec/lib/hit_counter_spec.rb
|
146
|
-
- spec/spec_helper.rb
|
147
99
|
homepage: https://github.com/FoveaCentral/hit_counter
|
148
100
|
licenses:
|
149
101
|
- MIT
|
@@ -164,7 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
164
116
|
- !ruby/object:Gem::Version
|
165
117
|
version: '0'
|
166
118
|
requirements: []
|
167
|
-
rubygems_version: 3.
|
119
|
+
rubygems_version: 3.3.27
|
168
120
|
signing_key:
|
169
121
|
specification_version: 4
|
170
122
|
summary: Self-hosted Ruby version of that old 90s chestnut, the web-site hit counter.
|
checksums.yaml.gz.sig
DELETED
Binary file
|
data/.document
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
---
|
2
|
-
name: Bug report
|
3
|
-
about: Create a report to help us improve
|
4
|
-
labels: 'bug'
|
5
|
-
---
|
6
|
-
|
7
|
-
# Description
|
8
|
-
|
9
|
-
Provide as much background as you need to get the implementer up to speed on the problem to be solved. This can also include screenshots and links to other issues or pull requests.
|
10
|
-
|
11
|
-
# Steps to Reproduce
|
12
|
-
|
13
|
-
Don't forget to point out the difference between what *should* happen and what *does* happen. Here's an example:
|
14
|
-
|
15
|
-
1. Try getting the count on cnn.com:
|
16
|
-
```ruby
|
17
|
-
HitCounter.get 'cnn.com'
|
18
|
-
```
|
19
|
-
2. The returned count is nil:
|
20
|
-
```ruby
|
21
|
-
HitCounter.get 'cnn.com'
|
22
|
-
=> nil
|
23
|
-
```
|
@@ -1,17 +0,0 @@
|
|
1
|
-
---
|
2
|
-
name: Feature request
|
3
|
-
about: Suggest an idea for this project
|
4
|
-
labels: 'feature'
|
5
|
-
---
|
6
|
-
|
7
|
-
# Goal
|
8
|
-
Explain this issue's purpose. Focus on the problem that needs to be solved and *not* a particular solution. For example: "Make it easier for users to reset their passwords."
|
9
|
-
|
10
|
-
# Description
|
11
|
-
1. Provide as much background as you need to familiarize the implementer with the problem to be solved.
|
12
|
-
2. Include:
|
13
|
-
* screenshots
|
14
|
-
* links to other issues or pull requests
|
15
|
-
|
16
|
-
# Success Criteria
|
17
|
-
How would a stakeholder test whether the feature was completed successfully?
|
@@ -1,21 +0,0 @@
|
|
1
|
-
---
|
2
|
-
name: Task
|
3
|
-
about: Define a task to complete
|
4
|
-
title: ''
|
5
|
-
labels: 'task'
|
6
|
-
assignees: ''
|
7
|
-
|
8
|
-
---
|
9
|
-
# Task
|
10
|
-
|
11
|
-
## Goal
|
12
|
-
|
13
|
-
Explain the goal of this task.
|
14
|
-
|
15
|
-
## Description
|
16
|
-
|
17
|
-
Provide whatever background the assignee would need to complete the task. This can include screenshots or links to other issues or pull requests.
|
18
|
-
|
19
|
-
## Success Criteria
|
20
|
-
|
21
|
-
How can stakeholders tell whether the task was completed successfully or not?
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# Closes: #
|
2
|
-
|
3
|
-
## Goal
|
4
|
-
What problem does this pull request solve? This should be close to the goal of the issue this pull request addresses.
|
5
|
-
|
6
|
-
## Approach
|
7
|
-
1. **Describe, in numbered steps, the approach you chose** to solve the above problem.
|
8
|
-
1. This will help code reviewers get oriented quickly.
|
9
|
-
2. It will also document for future maintainers exactly what changed (and why) when this PR was merged.
|
10
|
-
2. **Add specs** that either *reproduce the bug* or *cover the new feature*. In the former's case, *make sure it fails without the fix!*
|
11
|
-
3. Document any new public methods using standard RDoc syntax, or update the existing RDoc for any modified public methods. As an example, see the RDoc for `HitCounter.get`:
|
12
|
-
|
13
|
-
```ruby
|
14
|
-
# Returns a <code>HitCounter</code> matching the specified URL. The HitCounter
|
15
|
-
# is created if no matching one is found. In the latter case, the hits
|
16
|
-
# argument specifies the starting count.
|
17
|
-
#
|
18
|
-
# @param url [String] the URL for the site being counted
|
19
|
-
# @param hits [Integer] the number of hits to start with
|
20
|
-
# @return [HitCounter] the site's HitCounter
|
21
|
-
# @example
|
22
|
-
# hc = HitCounter.get 'cnn.com'
|
23
|
-
# hc = HitCounter.get 'cnn.com', 100
|
24
|
-
def self.get(url, hits = 0)
|
25
|
-
args = { url: normalize_url(url) }
|
26
|
-
args[:hits] = hits unless where(conditions: args).exists?
|
27
|
-
find_or_create_by args
|
28
|
-
end
|
29
|
-
```
|
30
|
-
|
31
|
-
Signed-off-by: YOUR NAME <YOUR.EMAIL@EXAMPLE.COM>
|
data/.github/dependabot.yml
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
# To get started with Dependabot version updates, you'll need to specify which
|
2
|
-
# package ecosystems to update and where the package manifests are located.
|
3
|
-
# Please see the documentation for all configuration options:
|
4
|
-
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
5
|
-
|
6
|
-
version: 2
|
7
|
-
updates:
|
8
|
-
- package-ecosystem: 'bundler' # See documentation for possible values
|
9
|
-
directory: '/' # Location of package manifests
|
10
|
-
schedule:
|
11
|
-
interval: 'daily'
|
data/.github/workflows/test.yml
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
# Download the latest Ruby patch versions, install dependencies, and run tests.
|
2
|
-
name: test
|
3
|
-
on:
|
4
|
-
push:
|
5
|
-
paths-ignore:
|
6
|
-
- '**.md'
|
7
|
-
- '**.txt'
|
8
|
-
jobs:
|
9
|
-
test:
|
10
|
-
environment: staging
|
11
|
-
runs-on: ubuntu-latest
|
12
|
-
name: Ruby ${{ matrix.ruby-version }}
|
13
|
-
strategy:
|
14
|
-
matrix:
|
15
|
-
ruby-version: [3.1, 3.2, 3.3]
|
16
|
-
steps:
|
17
|
-
- uses: actions/checkout@main
|
18
|
-
- uses: supercharge/mongodb-github-action@main
|
19
|
-
with:
|
20
|
-
mongodb-version: '4.4'
|
21
|
-
- uses: ruby/setup-ruby@master
|
22
|
-
with:
|
23
|
-
ruby-version: ${{ matrix.ruby-version }}
|
24
|
-
bundler-cache: true # 'bundle install' and cache
|
25
|
-
- run: bundle exec rake
|
26
|
-
- uses: amancevice/setup-code-climate@main
|
27
|
-
with:
|
28
|
-
cc_test_reporter_id: ${{ secrets.CC_TEST_REPORTER_ID }}
|
29
|
-
- run: cc-test-reporter after-build --coverage-input-type lcov
|
30
|
-
- uses: coverallsapp/github-action@master
|
31
|
-
with:
|
32
|
-
github-token: ${{ secrets.GITHUB_TOKEN }}
|
33
|
-
- run: bundle exec rubocop
|
34
|
-
- run: bundle exec inch --pedantic
|
data/.gitignore
DELETED
data/.rspec
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
--color
|
data/.rubocop.yml
DELETED
data/.simplecov
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'simplecov-lcov'
|
4
|
-
|
5
|
-
SimpleCov::Formatter::LcovFormatter.config do |c|
|
6
|
-
c.report_with_single_file = true
|
7
|
-
c.single_report_path = 'coverage/lcov.info'
|
8
|
-
end
|
9
|
-
SimpleCov.formatters = SimpleCov::Formatter::MultiFormatter.new(
|
10
|
-
[
|
11
|
-
SimpleCov::Formatter::HTMLFormatter,
|
12
|
-
SimpleCov::Formatter::LcovFormatter
|
13
|
-
]
|
14
|
-
)
|
15
|
-
SimpleCov.start
|
data/CODE_OF_CONDUCT.md
DELETED
@@ -1,10 +0,0 @@
|
|
1
|
-
# The Ruby Community Conduct Guideline
|
2
|
-
|
3
|
-
We have picked the following conduct guideline based on an early proposed draft of the PostgreSQL CoC, for Ruby developers community for safe, productive collaboration. Each Ruby related community (conference etc.) may pick their own Code of Conduct.
|
4
|
-
|
5
|
-
This document provides community guidelines for a safe, respectful, productive, and collaborative place for any person who is willing to contribute to the Ruby community. It applies to all “collaborative space”, which is defined as community communications channels (such as mailing lists, submitted patches, commit comments, etc.).
|
6
|
-
|
7
|
-
* Participants will be tolerant of opposing views.
|
8
|
-
* Participants must ensure that their language and actions are free of personal attacks and disparaging personal remarks.
|
9
|
-
* When interpreting the words and actions of others, participants should always assume good intentions.
|
10
|
-
* Behaviour which can be reasonably considered harassment will not be tolerated.
|
data/CONTRIBUTING.md
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
# How to contribute
|
2
|
-
|
3
|
-
## **New to open-source?**
|
4
|
-
|
5
|
-
Try your hand at one of the small tasks ideal for new or casual contributors that are [up-for-grabs](https://github.com/FoveaCentral/hit_counter/issues?q=is%3Aissue+is%3Aopen+label%3Aup-for-grabs). Welcome to the community!
|
6
|
-
|
7
|
-
## **Did you find a bug?**
|
8
|
-
|
9
|
-
1. **Ensure the bug was not already reported** by searching on GitHub under [Issues](https://github.com/FoveaCentral/hit_counter/issues).
|
10
|
-
|
11
|
-
2. If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/FoveaCentral/hit_counter/issues/new/choose). Be sure to include:
|
12
|
-
1. a **title and clear description**
|
13
|
-
2. as much **relevant information** as possible
|
14
|
-
3. a **code sample** or an **executable test case** demonstrating the expected behavior that is not occurring.
|
15
|
-
|
16
|
-
## **Did you write a patch that fixes a bug or adds a new feature?**
|
17
|
-
|
18
|
-
1. **Add specs** that either *reproduce the bug* or *cover the new feature*. In the former's case, *make sure it fails without the fix!*
|
19
|
-
|
20
|
-
2. **Confirm your last build passes** on your GitHub branch or PR.
|
21
|
-
|
22
|
-
3. **Update the inline documentation.** Format it with [YARD](https://www.rubydoc.info/gems/yard/file/docs/GettingStarted.md). For example, see [`HitCounter.get`](../lib/hit_counter/hit_counter.rb).
|
23
|
-
|
24
|
-
4. [Open a pull request](https://github.com/FoveaCentral/hit_counter/compare) with the patch or feature. Follow the template's directions.
|
25
|
-
|
26
|
-
## Developer Certificate of Origin (DCO)
|
27
|
-
|
28
|
-
All contributions (including pull requests) must agree to the [Developer Certificate of Origin (DCO) version 1.1](https://developercertificate.org). This is a developer's certification that he or she has the right to submit the patch for inclusion into the project.
|
29
|
-
|
30
|
-
Simply submitting a contribution implies this agreement, however, please include a `Signed-off-by` tag in the PR (this tag is a conventional way to confirm that you agree to the DCO).
|
31
|
-
|
32
|
-
It's not practical to fix old contributions in git, so if one is forgotten, do not try to fix them. We presume that if someone sometimes used a DCO, a commit without a DCO is an accident and the DCO still applies.
|
33
|
-
|
34
|
-
## Thanks for contributing!
|
data/LICENSE.txt
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
Copyright (c) 2011-2024 Roderick Monje
|
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
DELETED
@@ -1,120 +0,0 @@
|
|
1
|
-
# HitCounter
|
2
|
-
|
3
|
-
[![Build status](https://github.com/FoveaCentral/hit_counter/workflows/test/badge.svg)](https://github.com/FoveaCentral/hit_counter/actions/workflows/test.yml)
|
4
|
-
[![Code Climate](https://codeclimate.com/github/FoveaCentral/hit_counter.svg)](https://codeclimate.com/github/FoveaCentral/hit_counter)
|
5
|
-
[![Coveralls](https://coveralls.io/repos/FoveaCentral/hit_counter/badge.svg?branch=master&service=github)](https://coveralls.io/github/FoveaCentral/hit_counter?branch=master)
|
6
|
-
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/5375/badge)](https://bestpractices.coreinfrastructure.org/projects/5375)
|
7
|
-
[![Gem Version](https://badge.fury.io/rb/hit_counter.svg)](https://badge.fury.io/rb/hit_counter)
|
8
|
-
|
9
|
-
Self-hosted Ruby version of that old 90s chestnut, `<BLINK>`the web-site hit counter`</BLINK>`.
|
10
|
-
|
11
|
-
## Installation
|
12
|
-
|
13
|
-
1. Install the gem and supporting files.
|
14
|
-
|
15
|
-
`Gemfile`
|
16
|
-
```ruby
|
17
|
-
gem 'hit_counter'
|
18
|
-
```
|
19
|
-
|
20
|
-
Run:
|
21
|
-
|
22
|
-
```sh
|
23
|
-
bundle
|
24
|
-
rake hit_counter:install
|
25
|
-
```
|
26
|
-
|
27
|
-
### Security note
|
28
|
-
|
29
|
-
`HitCounter` is cryptographically signed. To insure the gem you install hasn’t been tampered with, add my public key as a trusted certificate and then install:
|
30
|
-
|
31
|
-
```sh
|
32
|
-
gem cert --add <(curl -Ls https://raw.github.com/FoveaCentral/hit_counter/master/certs/ivanoblomov.pem)
|
33
|
-
gem install hit_counter -P HighSecurity
|
34
|
-
```
|
35
|
-
|
36
|
-
2. Add a controller action to your app.
|
37
|
-
|
38
|
-
`application_controller.rb`
|
39
|
-
```ruby
|
40
|
-
def hit_counter
|
41
|
-
return if params[:url].blank?
|
42
|
-
|
43
|
-
# find or create a hit counter for this URL
|
44
|
-
hc = HitCounter.get params[:url]
|
45
|
-
|
46
|
-
# increase the tally by one
|
47
|
-
hc.increment
|
48
|
-
|
49
|
-
# get the image as a blob and stream it to the browser
|
50
|
-
send_data hc.image(params[:style]).to_blob,
|
51
|
-
disposition: 'inline',
|
52
|
-
filename: "#{hc.hits}.png",
|
53
|
-
type: :png
|
54
|
-
end
|
55
|
-
```
|
56
|
-
|
57
|
-
`routes.rb`
|
58
|
-
```ruby
|
59
|
-
get 'hit-counter' => 'application#hit_counter'
|
60
|
-
# technically should be POST/PUT, but GET makes integration simpler
|
61
|
-
````
|
62
|
-
|
63
|
-
3. Add the hit-counter image tag to your site's HTML:
|
64
|
-
|
65
|
-
```html
|
66
|
-
<img alt="Hit Counter" border="0" src="/hit-counter?url=https://cnn.com&style=1" />
|
67
|
-
````
|
68
|
-
|
69
|
-
Or try it out in `irb` with:
|
70
|
-
|
71
|
-
```ruby
|
72
|
-
require './spec/spec_helper'
|
73
|
-
hc = HitCounter.get('cnn.com')
|
74
|
-
```
|
75
|
-
|
76
|
-
## Customizing the Hit-Counter Image
|
77
|
-
|
78
|
-
### Use an Existing Style
|
79
|
-
|
80
|
-
| Name | Style number |
|
81
|
-
| -------- | --------------------------------------------------------------------- |
|
82
|
-
| Celtic | ![image of 3 in celtic style](/public/images/digits/celtic/3.png) |
|
83
|
-
| Odometer | ![image of 1 in odometer style](/public/images/digits/odometer/1.png) |
|
84
|
-
| Scout | ![image of 2 in scout style](/public/images/digits/scout/2.png) |
|
85
|
-
|
86
|
-
You can use one of the three included styles by specifying a different `style` param in the HTML:
|
87
|
-
|
88
|
-
```html
|
89
|
-
<img alt="Hit Counter" border="0" src="/hit-counter?url=cnn.com&style=1" />
|
90
|
-
```
|
91
|
-
|
92
|
-
### Create Your Own Style
|
93
|
-
|
94
|
-
1. To add your own style, create a PNG for each of the digits, `0.png` through `9.png`. Save the images in a folder named after your new style in `public/images/digits`.
|
95
|
-
|
96
|
-
2. In your controller, declare a new `STYLES` constant and add the folder name to it:
|
97
|
-
|
98
|
-
```ruby
|
99
|
-
HitCounter::STYLES = %w(odometer scout celtic folder_name)
|
100
|
-
```
|
101
|
-
|
102
|
-
3. In your HTML, specify the new style with a `style` param equal to its index in the array plus one (unlike arrays, the `style` param's index is one-based):
|
103
|
-
|
104
|
-
```html
|
105
|
-
<img alt="Hit Counter" border="0" src="/hit-counter?url=cnn.com&style=4" />
|
106
|
-
```
|
107
|
-
|
108
|
-
## Documentation
|
109
|
-
|
110
|
-
Complete RDoc documentation is available at [RubyDoc.info](https://www.rubydoc.info/gems/hit_counter).
|
111
|
-
|
112
|
-
## [Contributing to HitCounter](CONTRIBUTING.md)
|
113
|
-
|
114
|
-
## Cheers!
|
115
|
-
|
116
|
-
<a href="https://www.buymeacoffee.com/oblomov" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-green.png" alt="Buy Me A Coffee" height="41" width="174" ></a>
|
117
|
-
|
118
|
-
## Copyright
|
119
|
-
|
120
|
-
Copyright © 2011-2024 Roderick Monje. See LICENSE.txt for further details.
|
data/SECURITY.md
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
# Security Policy
|
2
|
-
|
3
|
-
## Supported Versions
|
4
|
-
|
5
|
-
[Dependabot](https://docs.github.com/en/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/about-dependabot-version-updates) automatically [patches known vulnerabilities](https://github.com/FoveaCentral/hit_counter/pulls?q=is%3Apr+is%3Aclosed+author%3Aapp%2Fdependabot).
|
6
|
-
|
7
|
-
| Version | Supported |
|
8
|
-
| ------- | ------------------ |
|
9
|
-
| 1.0.0 | :white_check_mark: |
|
10
|
-
| < 1.0.0 | :x: |
|
11
|
-
|
12
|
-
## Reporting a Vulnerability
|
13
|
-
|
14
|
-
1. To report a security vulnerability, [open an issue](https://github.com/FoveaCentral/hit_counter/issues/new/choose).
|
15
|
-
2. Updates are made within 48 hours.
|
16
|
-
3. If the vulnerability is accepted, we'll try to patch it within a week.
|
data/certs/ivanoblomov.pem
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
-----BEGIN CERTIFICATE-----
|
2
|
-
MIIEeDCCAuCgAwIBAgIBATANBgkqhkiG9w0BAQsFADBBMQwwCgYDVQQDDANyb2Qx
|
3
|
-
HDAaBgoJkiaJk/IsZAEZFgxmb3ZlYWNlbnRyYWwxEzARBgoJkiaJk/IsZAEZFgNj
|
4
|
-
b20wHhcNMjQwMzI5MjIzNDUxWhcNMjUwMzI5MjIzNDUxWjBBMQwwCgYDVQQDDANy
|
5
|
-
b2QxHDAaBgoJkiaJk/IsZAEZFgxmb3ZlYWNlbnRyYWwxEzARBgoJkiaJk/IsZAEZ
|
6
|
-
FgNjb20wggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQC6asLzbFQpchSv
|
7
|
-
u+05KuCzQW39QZq65t3c0kfUsIx+WREjBw2QlM6jVItYj4euRRszLwxhSMCtMsno
|
8
|
-
Fhas9eZ47esUhxIElQngrsBP0kwLUHQj/EYCDVN2xnMlicoE0zgOXiUkk6PTZZme
|
9
|
-
8SYSFJANVDOdRgr5Q17nWQKPS1l3OqoD+fkM+kO/ey2KTXvv4AFxfwe9o/bk6LjF
|
10
|
-
f4AzxKPmxsYbtgJHiu38gYb2IMh5JE5B0dUQ5pnQJbdTNtHI9YWoVpyIhIj/aOwN
|
11
|
-
t9lKjWhObPgfQ7Z5bEWSWvuPnGD1zj0/Y1MNJ99M4Bt1t5OkS3L1zjg1H3ulYRlB
|
12
|
-
VWFIwC8esooXXWqG5s2XCtVjugOo1seXv8PIOCPM1HBLfYjlWAwGy0oA0kAtAs+4
|
13
|
-
OlciDLHwCJO/ChIeLNaW3f6WiDmcwI8MeyxXxw64kX9QSKP0muM4+GtE9619hPFK
|
14
|
-
RMXUFKNUlrZ6gcpyX5weP2OKwd9Z7LkVsK/lgyxyaDqGwuajBGkCAwEAAaN7MHkw
|
15
|
-
CQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFO1rwHyxg39rlp0MN5Kj
|
16
|
-
s1uxvHyiMB8GA1UdEQQYMBaBFHJvZEBmb3ZlYWNlbnRyYWwuY29tMB8GA1UdEgQY
|
17
|
-
MBaBFHJvZEBmb3ZlYWNlbnRyYWwuY29tMA0GCSqGSIb3DQEBCwUAA4IBgQBg9aO1
|
18
|
-
1OhvQMbzefkcxE1QxuqwGzBh8kNiE2JL5FSGTtgFbXKqM1eeA0GWeZnksSVXOX40
|
19
|
-
01HDxW8CHdBnyNGorJPgbypZNI+gpi5bYKox0en7jj+88k9VA4fIbR+a/6sUSDsZ
|
20
|
-
82qpicz/Q+qkfnhQxHJ1Cj0lrZBq0Kuc+ooNxE4U3VT25CQCvUN9dlgyMZsH15ND
|
21
|
-
DpektzMLDzH4suOVGK09j7C3sTyVdwI5UkN8ix27Me0N4zPxjjYo0HFXIRNhEjVF
|
22
|
-
DWm9LGr9npmhQtd3A3ZyASawp+UUZ5pdc57YaBRDrJdFZr9056MpeByj+Fsg5Jkh
|
23
|
-
4o08iHs5bMPDyXBcj5XsYDLwAwTANPjGWGRNvrnY3KGGWdRMgtni3NJyMRCZ5tIT
|
24
|
-
UNicoJ8NJMgduyTPvZBJtvUPddQr1yAL66/l+CFewbGb/1DbqfSvA2atfUobhDrG
|
25
|
-
zYKOF/ofPEZhX7sqLK5GzDW4x1QDHAgr1YIdttVxhHADOxF4EVSJCHH0RGw=
|
26
|
-
-----END CERTIFICATE-----
|
data/hit_counter.gemspec
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require File.expand_path 'lib/version', __dir__
|
4
|
-
Gem::Specification.new do |s|
|
5
|
-
s.name = 'hit_counter'
|
6
|
-
s.version = HitCounter::VERSION.dup
|
7
|
-
s.licenses = ['MIT']
|
8
|
-
s.summary = 'Self-hosted Ruby version of that old 90s chestnut, the web-site hit counter.'
|
9
|
-
s.description = 'Why roast this chestnut by that open fire, you ask? Cause ' \
|
10
|
-
'thousands and thousands of Internet vets are still using the one we ' \
|
11
|
-
"wrote in PHP eons ago and we don't want to be squandering any incidental " \
|
12
|
-
"Google juice, that's why."
|
13
|
-
s.homepage = 'https://github.com/FoveaCentral/hit_counter'
|
14
|
-
s.authors = ['Roderick Monje']
|
15
|
-
s.cert_chain = ['certs/ivanoblomov.pem']
|
16
|
-
s.signing_key = File.expand_path('~/.ssh/gem-private_key.pem') if $PROGRAM_NAME.end_with?('gem')
|
17
|
-
|
18
|
-
s.add_dependency 'addressable'
|
19
|
-
s.add_dependency 'mongoid'
|
20
|
-
s.add_dependency 'rmagick'
|
21
|
-
|
22
|
-
s.files = `git ls-files`.split "\n"
|
23
|
-
s.require_paths = ['lib']
|
24
|
-
s.required_ruby_version = '>= 3.1'
|
25
|
-
s.metadata['rubygems_mfa_required'] = 'true'
|
26
|
-
end
|
data/lib/version.rb
DELETED
@@ -1,173 +0,0 @@
|
|
1
|
-
# Copyright the HitCounter contributors.
|
2
|
-
# SPDX-License-Identifier: MIT
|
3
|
-
# frozen_string_literal: true
|
4
|
-
|
5
|
-
require "#{File.dirname(__FILE__)}/../spec_helper"
|
6
|
-
|
7
|
-
JAVASCRIPT_HACK = %q(eval("console.log('All your base belong to us!')"))
|
8
|
-
# rubocop:disable Metrics/BlockLength
|
9
|
-
describe HitCounter do
|
10
|
-
subject(:hit_counter) { described_class.get 'www.google.com' }
|
11
|
-
|
12
|
-
describe '.get' do
|
13
|
-
context 'with existing URL' do
|
14
|
-
let!(:hit_counter2) { described_class.get hit_counter.url, 10 }
|
15
|
-
|
16
|
-
# rubocop:disable RSpec/NestedGroups
|
17
|
-
describe '.count' do
|
18
|
-
it { expect(described_class.count).to eq 1 }
|
19
|
-
end
|
20
|
-
|
21
|
-
context 'with starting count 10' do
|
22
|
-
describe '#hits' do
|
23
|
-
it { expect(hit_counter2.hits).to eq 10 }
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
context 'with new URL' do
|
29
|
-
before { described_class.get 'www.cnn.com' }
|
30
|
-
|
31
|
-
describe '.count' do
|
32
|
-
it { expect(described_class.count).to eq 2 }
|
33
|
-
end
|
34
|
-
|
35
|
-
context 'with blank starting count' do
|
36
|
-
describe '#hits' do
|
37
|
-
it do
|
38
|
-
expect(described_class.get('www.nytimes.com', nil).hits).to eq 0
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
context 'with starting count 10' do
|
44
|
-
describe '#hits' do
|
45
|
-
it { expect(described_class.get('online.wsj.com', 10).hits).to eq 10 }
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
context 'with JavaScript' do
|
51
|
-
subject(:hit_counter) { described_class.get(JAVASCRIPT_HACK) }
|
52
|
-
|
53
|
-
before { described_class.delete_all }
|
54
|
-
|
55
|
-
it do
|
56
|
-
hit_counter.save
|
57
|
-
expect(hit_counter).to be_invalid
|
58
|
-
end
|
59
|
-
# rubocop:enable RSpec/NestedGroups
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
describe '.install' do
|
64
|
-
before do
|
65
|
-
allow(Object).to receive(:system)
|
66
|
-
described_class.install
|
67
|
-
end
|
68
|
-
|
69
|
-
it('copies configuration files and images') do
|
70
|
-
expect(Object).to have_received(:system).twice.with match(/config|public/)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
describe '#hits' do
|
75
|
-
it { expect(hit_counter.hits).to eq 0 }
|
76
|
-
|
77
|
-
context 'when incremented' do
|
78
|
-
before { hit_counter.increment }
|
79
|
-
|
80
|
-
it { expect(hit_counter.hits).to eq 1 }
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
describe '#hits=' do
|
85
|
-
context 'with JavaScript' do
|
86
|
-
before { hit_counter.hits = JAVASCRIPT_HACK }
|
87
|
-
|
88
|
-
it { expect(hit_counter.hits).to eq 0 }
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
describe '#image' do
|
93
|
-
context 'with a valid :style_number' do
|
94
|
-
it { expect(hit_counter.image('1').filename).to eq "./public/images/digits/odometer/#{hit_counter.hits}.png" }
|
95
|
-
end
|
96
|
-
|
97
|
-
context 'with JavaScript' do
|
98
|
-
it {
|
99
|
-
expect(hit_counter.image(JAVASCRIPT_HACK).filename)
|
100
|
-
.to eq "./public/images/digits/odometer/#{hit_counter.hits}.png"
|
101
|
-
}
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
describe '#url=' do
|
106
|
-
context 'with JavaScript' do
|
107
|
-
before do
|
108
|
-
hit_counter.url = JAVASCRIPT_HACK
|
109
|
-
hit_counter.save
|
110
|
-
end
|
111
|
-
|
112
|
-
it { expect(hit_counter).to be_invalid }
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
describe '.normalize_style_number' do
|
117
|
-
context 'with nil' do
|
118
|
-
it { expect(described_class.send(:normalize_style_number, nil)).to be_zero }
|
119
|
-
end
|
120
|
-
|
121
|
-
context 'with empty string' do
|
122
|
-
it { expect(described_class.send(:normalize_style_number, '')).to be_zero }
|
123
|
-
end
|
124
|
-
|
125
|
-
context 'with JavaScript' do
|
126
|
-
it { expect(described_class.send(:normalize_style_number, JAVASCRIPT_HACK)).to be_zero }
|
127
|
-
end
|
128
|
-
|
129
|
-
context 'with number in range' do
|
130
|
-
{
|
131
|
-
'1' => 0,
|
132
|
-
'3' => 2
|
133
|
-
}.each do |input, output|
|
134
|
-
# rubocop:disable RSpec/NestedGroups
|
135
|
-
context "with '#{input}'" do
|
136
|
-
it do
|
137
|
-
expect(described_class.send(:normalize_style_number, input)).to eq output
|
138
|
-
end
|
139
|
-
end
|
140
|
-
# rubocop:enable RSpec/NestedGroups
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
context 'with number outside range' do
|
145
|
-
{
|
146
|
-
'-31' => 2,
|
147
|
-
'-1' => 2,
|
148
|
-
'4' => 0,
|
149
|
-
'34' => 0
|
150
|
-
}.each do |input, output|
|
151
|
-
# rubocop:disable RSpec/NestedGroups
|
152
|
-
context "with '#{input}'" do
|
153
|
-
it do
|
154
|
-
expect(described_class.send(:normalize_style_number, input)).to eq output
|
155
|
-
end
|
156
|
-
end
|
157
|
-
# rubocop:enable RSpec/NestedGroups
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
describe '.normalize_url' do
|
163
|
-
{
|
164
|
-
'cnn.com' => 'http://cnn.com',
|
165
|
-
'http://www.nytimes.com' => 'http://www.nytimes.com'
|
166
|
-
}.each do |input, output|
|
167
|
-
context "with '#{input}'" do
|
168
|
-
it { expect(described_class.send(:normalize_url, input)).to eq output }
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|
172
|
-
end
|
173
|
-
# rubocop:enable Metrics/BlockLength
|
data/spec/spec_helper.rb
DELETED
@@ -1,63 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'simplecov'
|
4
|
-
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
5
|
-
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
6
|
-
require 'addressable/uri'
|
7
|
-
require 'mongoid'
|
8
|
-
require 'rmagick'
|
9
|
-
require 'rspec'
|
10
|
-
|
11
|
-
require 'hit_counter'
|
12
|
-
|
13
|
-
Mongoid.load! 'config/mongoid.yml', :test
|
14
|
-
Mongo::Logger.logger.level = Logger::WARN
|
15
|
-
|
16
|
-
# Stub Rails root during tests.
|
17
|
-
module Rails
|
18
|
-
def self.root
|
19
|
-
'.'
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
require 'rake'
|
24
|
-
|
25
|
-
# load rake tasks
|
26
|
-
# https://dev.to/cassidycodes/how-to-test-rake-tasks-with-rspec-without-rails-3mhb
|
27
|
-
module TaskFormat
|
28
|
-
extend ActiveSupport::Concern
|
29
|
-
included do
|
30
|
-
let(:task_name) { self.class.top_level_description.delete_prefix('rake ') }
|
31
|
-
let(:tasks) { Rake::Task }
|
32
|
-
# Make the Rake task available as `task` in your examples:
|
33
|
-
subject(:task) { tasks[task_name] }
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
RSpec.configure do |config|
|
38
|
-
config.before(:suite) do
|
39
|
-
Dir.glob('lib/tasks/*.rake').each { |r| Rake::DefaultLoader.new.load r }
|
40
|
-
end
|
41
|
-
|
42
|
-
# Tag Rake specs with `:task` metadata or put them in the spec/tasks dir
|
43
|
-
config.define_derived_metadata(file_path: %r{/spec/tasks/}) do |metadata|
|
44
|
-
metadata[:type] = :task
|
45
|
-
end
|
46
|
-
|
47
|
-
config.include TaskFormat, type: :task
|
48
|
-
end
|
49
|
-
|
50
|
-
# silence output
|
51
|
-
RSpec.configure do |config|
|
52
|
-
original_stderr = $stderr
|
53
|
-
original_stdout = $stdout
|
54
|
-
config.before(:all) do
|
55
|
-
# Redirect stderr and stdout
|
56
|
-
$stderr = File.open(File::NULL, 'w')
|
57
|
-
$stdout = File.open(File::NULL, 'w')
|
58
|
-
end
|
59
|
-
config.after(:all) do
|
60
|
-
$stderr = original_stderr
|
61
|
-
$stdout = original_stdout
|
62
|
-
end
|
63
|
-
end
|
data.tar.gz.sig
DELETED
Binary file
|
metadata.gz.sig
DELETED
Binary file
|