hit_counter 0.1.8 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 93717639fc45d01a8822cd4f42fa765a06105f20542b1a713aeba2993ee8c9b3
4
- data.tar.gz: c5074a4f499350d9b2595ddc7c190374eaeea79de71c45366639e0a3a4465c6f
3
+ metadata.gz: 89d0d1a4065e5c9e788a9a3c01edfa904aa6b6e7aad75ee9ecc47c4a6a1618e0
4
+ data.tar.gz: 68ed08ca3ce41d738e0ab84d2cb74cded78a93faa4cd97ae200656e3a6bc94a1
5
5
  SHA512:
6
- metadata.gz: fea3b77836c49377d3bb4be377f411cd381190c79da5e2cf149f68e0379f60403a418aec2658a025e59dffa027585a344abc6fdf1d6ce25d121320d8836d9adc
7
- data.tar.gz: e3d4a13182c7c0db504c3e414c6f04ad28baa9ab925446dcde7617760975790a462d17fd68e6ac7e3c4f128a4db2eb7e81dd6078314e7a696700d2826757c884
6
+ metadata.gz: 25c8022ec4dbc94637f287149cd715d45677e29d5c58adee93fc52d1b118ee8e048ae0707ffabcceea9f4c5cb9b5517308c08e0100e401e025e14a49dcbb4fe6
7
+ data.tar.gz: 757187427c156efd6aef351f85dab4d15fdb25e5e362a3cf6e965b973ba2c778ee9d0b046ce054a85d90c030cbc96672031e52d2bfc018ce9cf11b0bdcb6975a
data/Gemfile CHANGED
@@ -3,12 +3,14 @@
3
3
  source 'https://rubygems.org'
4
4
  gemspec
5
5
 
6
- gem 'inch', '~> 0.8'
7
- gem 'pry', '~> 0.14.1'
8
- gem 'rake', '>= 12.3.3', '~> 13.0'
9
- gem 'rspec', '~> 3'
10
- gem 'rubocop', '< 1.29'
11
- gem 'rubocop-rake', '~> 0'
12
- gem 'rubocop-rspec', '~> 2'
13
- gem 'simplecov', '~> 0.18'
14
- gem 'simplecov-lcov', '~> 0.8'
6
+ gem 'gem-release'
7
+ gem 'inch'
8
+ gem 'pry'
9
+ gem 'rake'
10
+ gem 'rspec'
11
+ gem 'rubocop'
12
+ gem 'rubocop-performance'
13
+ gem 'rubocop-rake'
14
+ gem 'rubocop-rspec'
15
+ gem 'simplecov'
16
+ gem 'simplecov-lcov'
data/lib/hit_counter.rb CHANGED
@@ -124,8 +124,8 @@ class HitCounter
124
124
  private_class_method def self.cat_image(number, style_index, images = Magick::ImageList.new)
125
125
  return images.append(false) if number.blank?
126
126
 
127
- cat_image(number[1..-1], style_index, images <<
128
- Magick::Image.read("#{Rails.root}/public/images/digits/"\
127
+ cat_image(number[1..], style_index, images <<
128
+ Magick::Image.read("#{Rails.root}/public/images/digits/" \
129
129
  "#{STYLES[style_index]}/#{number[0..0]}.png").first)
130
130
  end
131
131
 
@@ -139,6 +139,6 @@ class HitCounter
139
139
  end
140
140
 
141
141
  private_class_method def self.normalize_url(value)
142
- value !~ %r{^http://} ? "http://#{value}" : value
142
+ %r{^http://}.match?(value) ? value : "http://#{value}"
143
143
  end
144
144
  end
metadata CHANGED
@@ -1,109 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hit_counter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
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
- MIIEQDCCAqigAwIBAgIBATANBgkqhkiG9w0BAQsFADAlMSMwIQYDVQQDDBpyb2Qv
14
- REM9Zm92ZWFjZW50cmFsL0RDPWNvbTAeFw0yMTExMTUwMzEwMTRaFw0yMjExMTUw
15
- MzEwMTRaMCUxIzAhBgNVBAMMGnJvZC9EQz1mb3ZlYWNlbnRyYWwvREM9Y29tMIIB
16
- ojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAsMm8RdCTuhYTnbH5a8pesLYn
17
- BD7cLPkeNfPWp8ohGVXL3988lRBYHwI/LRhxKXncmwmjYFWjuyR1m3e+EgmpBO3e
18
- gCn4G9paWlwvPF+dSBF4pjhPtYBSXMFDfoeUTyHuNCcQOFJUMSAxo1pg9S9KvslC
19
- Y1fpstOJtVnUjoeT8BRQAqV0WZuzFhgj74oSoHP/ETEd7Uzw/ST/kKgtNGcxoIYu
20
- FEqAfEsqEpV0d6FbExYmVTR12288MaGGrfc6Y/QC1VC6RhEYG8Sn8a3utqkn7y47
21
- 0J6SROECo5x9TWU0s3HDco06jYb5sV1cGsDYXFpEczxJ9i1YVX2IDvYrpZsSJLzq
22
- tfCdJ2jIj4rnMjGMg/kschfDnBKRIt8p7LlDhc0p/m0fYO4JQpWbvCc/F5vmUzpF
23
- kRbiNr30dkYqDbfvcdQUWBOa5rSyZOIQiW6kfK9ZbLjBGFeP8pwSNME+yfJsZObS
24
- AIiSqYtcP4mMriBLi+x981z1kpjTGZSWOpZrgAELAgMBAAGjezB5MAkGA1UdEwQC
25
- MAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBQzajljgeoJIjO/4h4X7ve/jYWVSDAf
26
- BgNVHREEGDAWgRRyb2RAZm92ZWFjZW50cmFsLmNvbTAfBgNVHRIEGDAWgRRyb2RA
27
- Zm92ZWFjZW50cmFsLmNvbTANBgkqhkiG9w0BAQsFAAOCAYEAqqybBWM9gIPn8Quj
28
- R8L0HPEE/1NjNLrlNG1DhJ8MAbYFA7mo4bWp4kjXwVdw+TMQZfrLjXLgmfiTvzxV
29
- cE10liYjCWQNxectkkYmOsCBlEDfOngNKdl3QJ+Y5+SEsqfKYhZXZypn+SwuXx8F
30
- LuVPsP7/R6VlrI8WbtPU1oSfM+rmdpUZzDcvmtvy1S+tPfFWalo8tSXPg0gE3Nis
31
- UZAwHu8x3v5N7lxtjJa+s9ARkH/BO5Uytz1XrUmUWLQqo9ZJtqbZ/iV9HEWhG+xx
32
- lR8SnXcsohvP/eIY2BTyBay0eOb9BwGHmnAVRiiAfLvCftzHtBEBr6jCKESSYDuc
33
- bUIRDNLzRjl2KOoNLjKymicWrBdz1roBpy8cFIDzi6ebE45ve/xoZbsGJ3zaLo9T
34
- G5iWAeYsmSjJxz7iOZOsx+vPCwMy7j6nWF2CDbaxioGR/hIqNbVBveCCRyjyunD3
35
- kvv576EuULmQcLpOKwB3RlxAG7j8JJl4ueqjF+rz7x1lBqEU
36
- -----END CERTIFICATE-----
37
- date: 2022-08-11 00:00:00.000000000 Z
10
+ cert_chain: []
11
+ date: 2024-12-21 00:00:00.000000000 Z
38
12
  dependencies:
39
13
  - !ruby/object:Gem::Dependency
40
14
  name: addressable
41
15
  requirement: !ruby/object:Gem::Requirement
42
16
  requirements:
43
- - - "~>"
44
- - !ruby/object:Gem::Version
45
- version: '2'
46
- type: :runtime
47
- prerelease: false
48
- version_requirements: !ruby/object:Gem::Requirement
49
- requirements:
50
- - - "~>"
51
- - !ruby/object:Gem::Version
52
- version: '2'
53
- - !ruby/object:Gem::Dependency
54
- name: bson_ext
55
- requirement: !ruby/object:Gem::Requirement
56
- requirements:
57
- - - "~>"
17
+ - - ">="
58
18
  - !ruby/object:Gem::Version
59
- version: '1'
19
+ version: '0'
60
20
  type: :runtime
61
21
  prerelease: false
62
22
  version_requirements: !ruby/object:Gem::Requirement
63
23
  requirements:
64
- - - "~>"
24
+ - - ">="
65
25
  - !ruby/object:Gem::Version
66
- version: '1'
26
+ version: '0'
67
27
  - !ruby/object:Gem::Dependency
68
28
  name: mongoid
69
29
  requirement: !ruby/object:Gem::Requirement
70
30
  requirements:
71
31
  - - ">="
72
32
  - !ruby/object:Gem::Version
73
- version: '7'
74
- - - "<"
75
- - !ruby/object:Gem::Version
76
- version: '9'
33
+ version: '0'
77
34
  type: :runtime
78
35
  prerelease: false
79
36
  version_requirements: !ruby/object:Gem::Requirement
80
37
  requirements:
81
38
  - - ">="
82
39
  - !ruby/object:Gem::Version
83
- version: '7'
84
- - - "<"
85
- - !ruby/object:Gem::Version
86
- version: '9'
40
+ version: '0'
87
41
  - !ruby/object:Gem::Dependency
88
42
  name: rmagick
89
43
  requirement: !ruby/object:Gem::Requirement
90
44
  requirements:
91
45
  - - ">="
92
46
  - !ruby/object:Gem::Version
93
- version: '2'
94
- - - "<"
95
- - !ruby/object:Gem::Version
96
- version: '5'
47
+ version: '0'
97
48
  type: :runtime
98
49
  prerelease: false
99
50
  version_requirements: !ruby/object:Gem::Requirement
100
51
  requirements:
101
52
  - - ">="
102
53
  - !ruby/object:Gem::Version
103
- version: '2'
104
- - - "<"
105
- - !ruby/object:Gem::Version
106
- version: '5'
54
+ version: '0'
107
55
  description: Why roast this chestnut by that open fire, you ask? Cause thousands and
108
56
  thousands of Internet vets are still using the one we wrote in PHP eons ago and
109
57
  we don't want to be squandering any incidental Google juice, that's why.
@@ -112,30 +60,12 @@ executables: []
112
60
  extensions: []
113
61
  extra_rdoc_files: []
114
62
  files:
115
- - ".document"
116
- - ".github/ISSUE_TEMPLATE/bug_report.md"
117
- - ".github/ISSUE_TEMPLATE/feature_request.md"
118
- - ".github/ISSUE_TEMPLATE/task.md"
119
- - ".github/PULL_REQUEST_TEMPLATE.md"
120
- - ".github/dependabot.yml"
121
- - ".github/workflows/test.yml"
122
- - ".gitignore"
123
- - ".rspec"
124
- - ".simplecov"
125
- - CODE_OF_CONDUCT.md
126
- - CONTRIBUTING.md
127
63
  - Gemfile
128
- - LICENSE.txt
129
- - README.md
130
64
  - Rakefile
131
- - SECURITY.md
132
- - certs/ivanoblomov.pem
133
65
  - config/initializers/mime_types.rb
134
66
  - config/mongoid.yml
135
- - hit_counter.gemspec
136
67
  - lib/hit_counter.rb
137
68
  - lib/tasks/install.rake
138
- - lib/version.rb
139
69
  - public/images/digits/celtic/0.png
140
70
  - public/images/digits/celtic/1.png
141
71
  - public/images/digits/celtic/2.png
@@ -166,11 +96,11 @@ files:
166
96
  - public/images/digits/scout/7.png
167
97
  - public/images/digits/scout/8.png
168
98
  - public/images/digits/scout/9.png
169
- - spec/lib/hit_counter_spec.rb
170
- - spec/spec_helper.rb
171
99
  homepage: https://github.com/FoveaCentral/hit_counter
172
- licenses: []
173
- metadata: {}
100
+ licenses:
101
+ - MIT
102
+ metadata:
103
+ rubygems_mfa_required: 'true'
174
104
  post_install_message:
175
105
  rdoc_options: []
176
106
  require_paths:
@@ -179,14 +109,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
179
109
  requirements:
180
110
  - - ">="
181
111
  - !ruby/object:Gem::Version
182
- version: '2.5'
112
+ version: '3.1'
183
113
  required_rubygems_version: !ruby/object:Gem::Requirement
184
114
  requirements:
185
115
  - - ">="
186
116
  - !ruby/object:Gem::Version
187
117
  version: '0'
188
118
  requirements: []
189
- rubygems_version: 3.1.6
119
+ rubygems_version: 3.3.27
190
120
  signing_key:
191
121
  specification_version: 4
192
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,5 +0,0 @@
1
- lib/**/*.rb
2
- bin/*
3
- -
4
- features/**/*.feature
5
- LICENSE.txt
@@ -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>
@@ -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'
@@ -1,42 +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: [2.5, 2.6, 2.7, '3.0']
16
- steps:
17
- - name: Checkout code
18
- uses: actions/checkout@v2
19
- - name: Set up Ruby ${{ matrix.ruby-version }}
20
- uses: ruby/setup-ruby@v1
21
- with:
22
- ruby-version: ${{ matrix.ruby-version }}
23
- bundler-cache: true # 'bundle install' and cache
24
- - name: Start MongoDB
25
- uses: supercharge/mongodb-github-action@1.7.0
26
- with:
27
- mongodb-version: '4.4'
28
- - name: Run tests
29
- run: bundle exec rake
30
- - name: Send Code Climate coverage
31
- uses: amancevice/setup-code-climate@v0
32
- with:
33
- cc_test_reporter_id: ${{ secrets.CC_TEST_REPORTER_ID }}
34
- - run: cc-test-reporter after-build --coverage-input-type lcov
35
- - name: Send Coveralls coverage
36
- uses: coverallsapp/github-action@master
37
- with:
38
- github-token: ${{ secrets.GITHUB_TOKEN }}
39
- - name: Run RuboCop
40
- run: bundle exec rubocop
41
- - name: Run Inch
42
- run: bundle exec inch --pedantic
data/.gitignore DELETED
@@ -1,8 +0,0 @@
1
- *.gem
2
- .DS_Store
3
- .bundle
4
- Gemfile.lock
5
- coverage
6
- doc
7
- git.rake
8
- tmp
data/.rspec DELETED
@@ -1 +0,0 @@
1
- --color
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-2022 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-2022 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
- | 0.1.8 | :white_check_mark: |
10
- | < 0.1.8 | :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.
@@ -1,25 +0,0 @@
1
- -----BEGIN CERTIFICATE-----
2
- MIIEQDCCAqigAwIBAgIBATANBgkqhkiG9w0BAQsFADAlMSMwIQYDVQQDDBpyb2Qv
3
- REM9Zm92ZWFjZW50cmFsL0RDPWNvbTAeFw0yMTExMTUwMzEwMTRaFw0yMjExMTUw
4
- MzEwMTRaMCUxIzAhBgNVBAMMGnJvZC9EQz1mb3ZlYWNlbnRyYWwvREM9Y29tMIIB
5
- ojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAsMm8RdCTuhYTnbH5a8pesLYn
6
- BD7cLPkeNfPWp8ohGVXL3988lRBYHwI/LRhxKXncmwmjYFWjuyR1m3e+EgmpBO3e
7
- gCn4G9paWlwvPF+dSBF4pjhPtYBSXMFDfoeUTyHuNCcQOFJUMSAxo1pg9S9KvslC
8
- Y1fpstOJtVnUjoeT8BRQAqV0WZuzFhgj74oSoHP/ETEd7Uzw/ST/kKgtNGcxoIYu
9
- FEqAfEsqEpV0d6FbExYmVTR12288MaGGrfc6Y/QC1VC6RhEYG8Sn8a3utqkn7y47
10
- 0J6SROECo5x9TWU0s3HDco06jYb5sV1cGsDYXFpEczxJ9i1YVX2IDvYrpZsSJLzq
11
- tfCdJ2jIj4rnMjGMg/kschfDnBKRIt8p7LlDhc0p/m0fYO4JQpWbvCc/F5vmUzpF
12
- kRbiNr30dkYqDbfvcdQUWBOa5rSyZOIQiW6kfK9ZbLjBGFeP8pwSNME+yfJsZObS
13
- AIiSqYtcP4mMriBLi+x981z1kpjTGZSWOpZrgAELAgMBAAGjezB5MAkGA1UdEwQC
14
- MAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBQzajljgeoJIjO/4h4X7ve/jYWVSDAf
15
- BgNVHREEGDAWgRRyb2RAZm92ZWFjZW50cmFsLmNvbTAfBgNVHRIEGDAWgRRyb2RA
16
- Zm92ZWFjZW50cmFsLmNvbTANBgkqhkiG9w0BAQsFAAOCAYEAqqybBWM9gIPn8Quj
17
- R8L0HPEE/1NjNLrlNG1DhJ8MAbYFA7mo4bWp4kjXwVdw+TMQZfrLjXLgmfiTvzxV
18
- cE10liYjCWQNxectkkYmOsCBlEDfOngNKdl3QJ+Y5+SEsqfKYhZXZypn+SwuXx8F
19
- LuVPsP7/R6VlrI8WbtPU1oSfM+rmdpUZzDcvmtvy1S+tPfFWalo8tSXPg0gE3Nis
20
- UZAwHu8x3v5N7lxtjJa+s9ARkH/BO5Uytz1XrUmUWLQqo9ZJtqbZ/iV9HEWhG+xx
21
- lR8SnXcsohvP/eIY2BTyBay0eOb9BwGHmnAVRiiAfLvCftzHtBEBr6jCKESSYDuc
22
- bUIRDNLzRjl2KOoNLjKymicWrBdz1roBpy8cFIDzi6ebE45ve/xoZbsGJ3zaLo9T
23
- G5iWAeYsmSjJxz7iOZOsx+vPCwMy7j6nWF2CDbaxioGR/hIqNbVBveCCRyjyunD3
24
- kvv576EuULmQcLpOKwB3RlxAG7j8JJl4ueqjF+rz7x1lBqEU
25
- -----END CERTIFICATE-----
data/hit_counter.gemspec DELETED
@@ -1,25 +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.summary = 'Self-hosted Ruby version of that old 90s chestnut, the web-site hit counter.'
8
- s.description = 'Why roast this chestnut by that open fire, you ask? Cause '\
9
- 'thousands and thousands of Internet vets are still using the one we '\
10
- "wrote in PHP eons ago and we don't want to be squandering any incidental "\
11
- "Google juice, that's why."
12
- s.homepage = 'https://github.com/FoveaCentral/hit_counter'
13
- s.authors = ['Roderick Monje']
14
- s.cert_chain = ['certs/ivanoblomov.pem']
15
- s.signing_key = File.expand_path('~/.ssh/gem-private_key.pem') if $PROGRAM_NAME =~ /gem\z/
16
-
17
- s.add_runtime_dependency 'addressable', '~> 2'
18
- s.add_runtime_dependency 'bson_ext', '~> 1'
19
- s.add_runtime_dependency 'mongoid', '>= 7', '< 9'
20
- s.add_runtime_dependency 'rmagick', '>= 2', '< 5'
21
-
22
- s.files = `git ls-files`.split "\n"
23
- s.require_paths = ['lib']
24
- s.required_ruby_version = '>= 2.5'
25
- end
data/lib/version.rb DELETED
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Self-hosted Ruby version of that old 90s chestnut, <BLINK>the web-site hit counter</BLINK>
4
- class HitCounter
5
- # This gem's version
6
- VERSION = '0.1.8' unless defined?(HitCounter::VERSION)
7
- end
@@ -1,150 +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
- before(:all) { described_class.delete_all }
11
-
12
- subject { described_class.get 'www.google.com' }
13
-
14
- describe '.get' do
15
- context 'with existing URL' do
16
- let!(:hit_counter2) { described_class.get subject.url, 10 }
17
-
18
- describe '.count' do
19
- it { expect(described_class.count).to eq 1 }
20
- end
21
-
22
- context 'with starting count 10' do
23
- describe '#hits' do
24
- it { expect(hit_counter2.hits).to eq 10 }
25
- end
26
- end
27
- end
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
- context 'with starting count 10' do
43
- describe '#hits' do
44
- it { expect(described_class.get('online.wsj.com', 10).hits).to eq 10 }
45
- end
46
- end
47
- end
48
- context 'with JavaScript' do
49
- before { described_class.delete_all }
50
-
51
- subject { described_class.get(JAVASCRIPT_HACK) }
52
-
53
- it do
54
- subject.save
55
- expect(subject).to be_invalid
56
- end
57
- end
58
- end
59
- describe '.install' do
60
- before do
61
- expect_any_instance_of(Object).to receive(:system).twice.with match(/config|public/)
62
- end
63
-
64
- it('copies configuration files and images') { described_class.install }
65
- end
66
- describe '#hits' do
67
- it { expect(subject.hits).to eq 0 }
68
-
69
- context 'when incremented' do
70
- before { subject.increment }
71
-
72
- it { expect(subject.hits).to eq 1 }
73
- end
74
- end
75
- describe '#hits=' do
76
- context 'with JavaScript' do
77
- before { subject.hits = JAVASCRIPT_HACK }
78
-
79
- it { expect(subject.hits).to eq 0 }
80
- end
81
- end
82
- describe '#image' do
83
- context 'with a valid :style_number' do
84
- it { expect(subject.image('1').filename).to eq "./public/images/digits/odometer/#{subject.hits}.png" }
85
- end
86
- context 'with JavaScript' do
87
- it {
88
- expect(subject.image(JAVASCRIPT_HACK).filename).to eq "./public/images/digits/odometer/#{subject.hits}.png"
89
- }
90
- end
91
- end
92
- describe '#url=' do
93
- context 'with JavaScript' do
94
- before do
95
- subject.url = JAVASCRIPT_HACK
96
- subject.save
97
- end
98
-
99
- it { expect(subject).to be_invalid }
100
- end
101
- end
102
- describe '.normalize_style_number' do
103
- context 'with nil' do
104
- it { expect(described_class.send(:normalize_style_number, nil)).to be_zero }
105
- end
106
- context 'with empty string' do
107
- it { expect(described_class.send(:normalize_style_number, '')).to be_zero }
108
- end
109
- context 'with JavaScript' do
110
- it { expect(described_class.send(:normalize_style_number, JAVASCRIPT_HACK)).to be_zero }
111
- end
112
- context 'with number in range' do
113
- {
114
- '1' => 0,
115
- '3' => 2
116
- }.each do |input, output|
117
- context "with '#{input}'" do
118
- it do
119
- expect(described_class.send(:normalize_style_number, input)).to eq output
120
- end
121
- end
122
- end
123
- end
124
- context 'with number outside range' do
125
- {
126
- '-31' => 2,
127
- '-1' => 2,
128
- '4' => 0,
129
- '34' => 0
130
- }.each do |input, output|
131
- context "with '#{input}'" do
132
- it do
133
- expect(described_class.send(:normalize_style_number, input)).to eq output
134
- end
135
- end
136
- end
137
- end
138
- end
139
- describe '.normalize_url' do
140
- {
141
- 'cnn.com' => 'http://cnn.com',
142
- 'http://www.nytimes.com' => 'http://www.nytimes.com'
143
- }.each do |input, output|
144
- context "with '#{input}'" do
145
- it { expect(described_class.send(:normalize_url, input)).to eq output }
146
- end
147
- end
148
- end
149
- end
150
- # 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.sub(/\Arake /, '') }
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