analytic 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +41 -13
- data/Rakefile +12 -2
- data/app/assets/builds/analytic/application.css +810 -0
- data/app/assets/builds/analytic/application.js +54498 -0
- data/app/assets/builds/analytic/application.js.map +7 -0
- data/app/assets/config/analytic_manifest.js +0 -0
- data/app/controllers/analytic/application_controller.rb +6 -0
- data/app/controllers/analytic/dashboard_controller.rb +13 -0
- data/app/controllers/concerns/analytic/trackable.rb +38 -0
- data/app/helpers/analytic/application_helper.rb +6 -0
- data/app/jobs/analytic/application_job.rb +6 -0
- data/app/jobs/analytic/track_job.rb +23 -0
- data/app/mailers/analytic/application_mailer.rb +7 -0
- data/app/models/analytic/application_record.rb +7 -0
- data/app/models/analytic/dashboard.rb +65 -0
- data/app/models/analytic/view.rb +23 -0
- data/app/packs/analytic/application/index.ts +1 -0
- data/app/packs/analytic/application/initializers/fontawesome.ts +23 -0
- data/app/packs/analytic/application/initializers/index.ts +1 -0
- data/app/packs/analytic/entrypoints/application.tailwind.css +65 -0
- data/app/packs/analytic/entrypoints/application.ts +1 -0
- data/app/views/analytic/dashboard/show.html.erb +84 -0
- data/app/views/layouts/analytic/application.html.erb +42 -0
- data/bin/dev +3 -0
- data/bin/rails +11 -0
- data/config/routes.rb +7 -0
- data/db/migrate/20240805210911_create_analytic_views.rb +20 -0
- data/lib/analytic/config.rb +12 -0
- data/lib/analytic/engine.rb +7 -0
- data/lib/analytic/version.rb +3 -1
- data/lib/analytic.rb +15 -3
- metadata +36 -13
- data/lib/analytic/railtie.rb +0 -4
- data/lib/tasks/analytic_tasks.rake +0 -4
- /data/{MIT-LICENSE → LICENSE} +0 -0
File without changes
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Analytic
|
4
|
+
class DashboardController < ApplicationController
|
5
|
+
include Analytic::Trackable
|
6
|
+
before_action { analytic_track! }
|
7
|
+
|
8
|
+
# GET /
|
9
|
+
def show
|
10
|
+
@dashboard = Dashboard.new(period: params[:period])
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Analytic
|
4
|
+
module Trackable
|
5
|
+
# @param params [Hash]
|
6
|
+
def analytic_track!(params: {})
|
7
|
+
Analytic::View.create!(
|
8
|
+
timestamp: Time.current,
|
9
|
+
session_id: analytic_session_id,
|
10
|
+
visitor_id: analytic_visitor_id,
|
11
|
+
host: request.host,
|
12
|
+
path: request.path,
|
13
|
+
params:
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
# @param params [Hash]
|
18
|
+
def analytic_enqueue_track_job!(params: {})
|
19
|
+
Analytic::TrackJob.perform_later(
|
20
|
+
session_id: analytic_session_id,
|
21
|
+
visitor_id: analytic_visitor_id,
|
22
|
+
host: request.host,
|
23
|
+
path: request.path,
|
24
|
+
params:
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [String]
|
29
|
+
def analytic_session_id
|
30
|
+
session[:analytic_session_id] ||= SecureRandom.uuid
|
31
|
+
end
|
32
|
+
|
33
|
+
# @return [String]
|
34
|
+
def analytic_visitor_id
|
35
|
+
cookies.permanent[:analytic_visitor_id] ||= SecureRandom.uuid
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Analytic
|
4
|
+
class TrackJob < ApplicationJob
|
5
|
+
queue_as :default
|
6
|
+
|
7
|
+
# @param timestamp [Timestamp]
|
8
|
+
# @param session_id [String]
|
9
|
+
# @param visitor_id [String]
|
10
|
+
# @param host [String]
|
11
|
+
# @param path [String]
|
12
|
+
# @param params [Hash]
|
13
|
+
def perform(session_id:, visitor_id:, host:, path:, timestamp: Time.current, params: {})
|
14
|
+
Analytic::View.create!(
|
15
|
+
session_id:,
|
16
|
+
visitor_id:,
|
17
|
+
host:,
|
18
|
+
path:,
|
19
|
+
params:
|
20
|
+
)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Analytic
|
4
|
+
class Dashboard
|
5
|
+
PAGES_LIMIT = 8
|
6
|
+
|
7
|
+
# @param period [String] today, yesterday, week, month, year
|
8
|
+
def initialize(period:)
|
9
|
+
@period = period
|
10
|
+
end
|
11
|
+
|
12
|
+
# @return [Integer]
|
13
|
+
delegate :count, to: :views
|
14
|
+
|
15
|
+
# @return [Integer]
|
16
|
+
delegate :distinct_visitors_count, to: :views
|
17
|
+
|
18
|
+
# @return [Integer]
|
19
|
+
delegate :distinct_sessions_count, to: :views
|
20
|
+
|
21
|
+
# @return [String]
|
22
|
+
def name
|
23
|
+
if @period
|
24
|
+
"#{@period.capitalize} | Dashboard"
|
25
|
+
else
|
26
|
+
'Dashboard'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [Array<Array(String, String, Integer)>]
|
31
|
+
def pages
|
32
|
+
views
|
33
|
+
.group(:host)
|
34
|
+
.group(:path)
|
35
|
+
.order(count: :desc)
|
36
|
+
.limit(PAGES_LIMIT)
|
37
|
+
.pluck(:host, :path, Arel.sql('COUNT(*) AS count'))
|
38
|
+
end
|
39
|
+
|
40
|
+
protected
|
41
|
+
|
42
|
+
# @return [Analytic::View::ActiveRecord_Relation]
|
43
|
+
def views
|
44
|
+
@views ||= Analytic::View.within(range)
|
45
|
+
end
|
46
|
+
|
47
|
+
# @return [Range<Time>]
|
48
|
+
def range
|
49
|
+
return unless @period
|
50
|
+
|
51
|
+
case @period
|
52
|
+
when 'today' then timezone.today.all_day
|
53
|
+
when 'yesterday' then timezone.yesterday.all_day
|
54
|
+
when 'week' then timezone.now.all_week
|
55
|
+
when 'month' then timezone.now.all_month
|
56
|
+
when 'year' then timezone.now.all_year
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# @return [ActiveSupport::TimeZone]
|
61
|
+
def timezone
|
62
|
+
Analytic.config.timezone || Time.zone
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Analytic
|
4
|
+
class View < ApplicationRecord
|
5
|
+
validates :timestamp, presence: true
|
6
|
+
validates :visitor_id, presence: true
|
7
|
+
validates :session_id, presence: true
|
8
|
+
validates :path, presence: true
|
9
|
+
validates :host, presence: true
|
10
|
+
|
11
|
+
scope :within, ->(range) { where(timestamp: range) if range }
|
12
|
+
|
13
|
+
# @return [Integer]
|
14
|
+
def self.distinct_visitors_count
|
15
|
+
count('DISTINCT "analytic_views"."visitor_id"')
|
16
|
+
end
|
17
|
+
|
18
|
+
# @return [Integer]
|
19
|
+
def self.distinct_sessions_count
|
20
|
+
count('DISTINCT "analytic_views"."session_id"')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
import "./initializers";
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import "@fortawesome/fontawesome-free";
|
2
|
+
|
3
|
+
import { library } from "@fortawesome/fontawesome-svg-core";
|
4
|
+
|
5
|
+
import { faClock } from "@fortawesome/free-solid-svg-icons/faClock";
|
6
|
+
import { faEye } from "@fortawesome/free-solid-svg-icons/faEye";
|
7
|
+
import { faFileCode } from "@fortawesome/free-solid-svg-icons/faFileCode";
|
8
|
+
import { faGauge } from "@fortawesome/free-solid-svg-icons/faGauge";
|
9
|
+
import { faGlobe } from "@fortawesome/free-solid-svg-icons/faGlobe";
|
10
|
+
import { faHouse } from "@fortawesome/free-solid-svg-icons/faHouse";
|
11
|
+
import { faSliders } from "@fortawesome/free-solid-svg-icons/faSliders";
|
12
|
+
import { faUsers } from "@fortawesome/free-solid-svg-icons/faUsers";
|
13
|
+
|
14
|
+
library.add(
|
15
|
+
faClock,
|
16
|
+
faEye,
|
17
|
+
faGauge,
|
18
|
+
faGlobe,
|
19
|
+
faHouse,
|
20
|
+
faSliders,
|
21
|
+
faUsers,
|
22
|
+
faFileCode
|
23
|
+
);
|
@@ -0,0 +1 @@
|
|
1
|
+
import "./fontawesome";
|
@@ -0,0 +1,65 @@
|
|
1
|
+
@tailwind base;
|
2
|
+
@tailwind components;
|
3
|
+
@tailwind utilities;
|
4
|
+
|
5
|
+
@layer components {
|
6
|
+
.pill {
|
7
|
+
@apply bg-slate-200 text-slate-800 hover:text-white hover:bg-indigo-600 rounded-full px-3 py-2;
|
8
|
+
}
|
9
|
+
|
10
|
+
.card {
|
11
|
+
@apply shadow-md rounded bg-white;
|
12
|
+
}
|
13
|
+
|
14
|
+
.card__header {
|
15
|
+
@apply px-5 py-4 border-b border-slate-200;
|
16
|
+
}
|
17
|
+
|
18
|
+
.card__footer {
|
19
|
+
@apply px-5 py-4 border-t border-slate-200;
|
20
|
+
}
|
21
|
+
|
22
|
+
.card__content {
|
23
|
+
@apply px-5 py-4
|
24
|
+
}
|
25
|
+
|
26
|
+
.card__title {
|
27
|
+
@apply uppercase text-slate-600 font-semibold text-sm flex gap-2 items-center;
|
28
|
+
}
|
29
|
+
|
30
|
+
.card__value {
|
31
|
+
@apply uppercase text-slate-800 font-extrabold text-lg;
|
32
|
+
}
|
33
|
+
|
34
|
+
.table {
|
35
|
+
@apply w-full divide-y divide-slate-200;
|
36
|
+
}
|
37
|
+
|
38
|
+
.table tbody {
|
39
|
+
@apply divide-y divide-slate-200;
|
40
|
+
}
|
41
|
+
|
42
|
+
.table td {
|
43
|
+
@apply px-3 py-2 text-left;
|
44
|
+
}
|
45
|
+
|
46
|
+
.table th {
|
47
|
+
@apply px-3 py-2 text-left;
|
48
|
+
}
|
49
|
+
|
50
|
+
.table td:first-child {
|
51
|
+
@apply pl-0;
|
52
|
+
}
|
53
|
+
|
54
|
+
.table td:last-child {
|
55
|
+
@apply pr-0;
|
56
|
+
}
|
57
|
+
|
58
|
+
.table th:first-child {
|
59
|
+
@apply pl-0;
|
60
|
+
}
|
61
|
+
|
62
|
+
.table th:last-child {
|
63
|
+
@apply pr-0;
|
64
|
+
}
|
65
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
import "../application";
|
@@ -0,0 +1,84 @@
|
|
1
|
+
<%- provide(:title, @dashboard.name) %>
|
2
|
+
|
3
|
+
<div class="space-y-4">
|
4
|
+
<div class="flex gap-2">
|
5
|
+
<%= link_to 'Today', analytic.dashboard_path(period: 'today'), class: 'pill' %>
|
6
|
+
<%= link_to 'Yesterday', analytic.dashboard_path(period: 'yesterday'), class: 'pill' %>
|
7
|
+
<%= link_to 'Week', analytic.dashboard_path(period: 'week'), class: 'pill' %>
|
8
|
+
<%= link_to 'Month', analytic.dashboard_path(period: 'month'), class: 'pill' %>
|
9
|
+
<%= link_to 'Year', analytic.dashboard_path(period: 'year'), class: 'pill' %>
|
10
|
+
</div>
|
11
|
+
|
12
|
+
<div class="grid grid-flow-col justify-stretch gap-4">
|
13
|
+
<div class="card">
|
14
|
+
<div class="card__header">
|
15
|
+
<div class="card__title">
|
16
|
+
<%= tag.i class: "fa-solid fa-users" %>
|
17
|
+
Visitors
|
18
|
+
</div>
|
19
|
+
</div>
|
20
|
+
<div class="card__content">
|
21
|
+
<div class="card__value">
|
22
|
+
<%= number_with_delimiter @dashboard.distinct_visitors_count %>
|
23
|
+
</div>
|
24
|
+
</div>
|
25
|
+
</div>
|
26
|
+
|
27
|
+
<div class="card">
|
28
|
+
<div class="card__header">
|
29
|
+
<div class="card__title">
|
30
|
+
<%= tag.i class: "fa-solid fa-globe" %>
|
31
|
+
Sessions
|
32
|
+
</div>
|
33
|
+
</div>
|
34
|
+
<div class="card__content">
|
35
|
+
<div class="card__value">
|
36
|
+
<%= number_with_delimiter @dashboard.distinct_sessions_count %>
|
37
|
+
</div>
|
38
|
+
</div>
|
39
|
+
</div>
|
40
|
+
|
41
|
+
<div class="card">
|
42
|
+
<div class="card__header">
|
43
|
+
<div class="card__title">
|
44
|
+
<%= tag.i class: "fa-solid fa-eye" %>
|
45
|
+
Views
|
46
|
+
</div>
|
47
|
+
</div>
|
48
|
+
<div class="card__content">
|
49
|
+
<div class="card__value">
|
50
|
+
<%= number_with_delimiter @dashboard.count %>
|
51
|
+
</div>
|
52
|
+
</div>
|
53
|
+
</div>
|
54
|
+
</div>
|
55
|
+
|
56
|
+
<div class="card">
|
57
|
+
<div class="card__header">
|
58
|
+
<div class="card__title">
|
59
|
+
<%= tag.i class: "fa-solid fa-file-code" %>
|
60
|
+
Pages
|
61
|
+
</div>
|
62
|
+
</div>
|
63
|
+
<div class="card__content">
|
64
|
+
<table class="table">
|
65
|
+
<thead>
|
66
|
+
<tr>
|
67
|
+
<th scope="col">Host</th>
|
68
|
+
<th scope="col">Path</th>
|
69
|
+
<th scope="col">Views</th>
|
70
|
+
</tr>
|
71
|
+
</thead>
|
72
|
+
<tbody>
|
73
|
+
<%- @dashboard.pages.each do |(host, path, views)| -%>
|
74
|
+
<tr>
|
75
|
+
<td><%= host %></td>
|
76
|
+
<td><%= path %></td>
|
77
|
+
<td><%= number_with_delimiter views %></td>
|
78
|
+
</tr>
|
79
|
+
<%- end -%>
|
80
|
+
</tbody>
|
81
|
+
</table>
|
82
|
+
</div>
|
83
|
+
</div>
|
84
|
+
</div>
|
@@ -0,0 +1,42 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title><%= yield(:title) %> | Analytic</title>
|
5
|
+
<%= csrf_meta_tags %>
|
6
|
+
<%= csp_meta_tag %>
|
7
|
+
<%= javascript_include_tag 'analytic/application' %>
|
8
|
+
<%= stylesheet_link_tag 'analytic/application' %>
|
9
|
+
<%= %>
|
10
|
+
</head>
|
11
|
+
<body class="bg-slate-50">
|
12
|
+
|
13
|
+
<header class="bg-indigo-600 text-white py-2">
|
14
|
+
<div class="container mx-auto px-4">
|
15
|
+
<div class="flex justify-between">
|
16
|
+
<nav class="flex gap-2">
|
17
|
+
<%= link_to analytic.root_path, class: "flex gap-2 rounded items-center px-3 py-2 font-semibold hover:bg-indigo-800" do %>
|
18
|
+
<%= tag.i class: "fa-solid fa-gauge" %>
|
19
|
+
Analytic
|
20
|
+
<% end %>
|
21
|
+
</nav>
|
22
|
+
<nav class="flex gap-2">
|
23
|
+
<%= link_to analytic.root_path, class: "flex gap-2 rounded items-center px-3 py-2 hover:bg-indigo-800" do %>
|
24
|
+
<%= tag.i class: "fa-solid fa-house" %>
|
25
|
+
Dashboard
|
26
|
+
<% end %>
|
27
|
+
</nav>
|
28
|
+
</div>
|
29
|
+
</div>
|
30
|
+
</header>
|
31
|
+
|
32
|
+
<main class="container mx-auto px-4 py-8">
|
33
|
+
<%= yield %>
|
34
|
+
</main>
|
35
|
+
|
36
|
+
<footer class="container mx-auto px-4 text-center">
|
37
|
+
<div class="flex gap-2 justify-center">
|
38
|
+
<%= time_tag(Time.current) %>
|
39
|
+
</div>
|
40
|
+
</footer>
|
41
|
+
</body>
|
42
|
+
</html>
|
data/bin/dev
ADDED
data/bin/rails
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
ENGINE_ROOT = File.expand_path("..", __dir__)
|
4
|
+
ENGINE_PATH = File.expand_path("../lib/analytic/engine", __dir__)
|
5
|
+
APP_PATH = File.expand_path("../spec/dummy/config/application", __dir__)
|
6
|
+
|
7
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
|
8
|
+
require "bundler/setup" if File.exist?(ENV["BUNDLE_GEMFILE"])
|
9
|
+
|
10
|
+
require "rails/all"
|
11
|
+
require "rails/engine/commands"
|
data/config/routes.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class CreateAnalyticViews < ActiveRecord::Migration[7.1]
|
4
|
+
def change
|
5
|
+
create_table :analytic_views do |t|
|
6
|
+
t.uuid :visitor_id, null: false
|
7
|
+
t.uuid :session_id, null: false
|
8
|
+
t.string :path, null: false
|
9
|
+
t.string :host, null: false
|
10
|
+
t.jsonb :params, null: false, default: {}
|
11
|
+
t.datetime :timestamp, null: false
|
12
|
+
|
13
|
+
t.timestamps
|
14
|
+
|
15
|
+
t.index %i[timestamp path]
|
16
|
+
t.index %i[timestamp visitor_id]
|
17
|
+
t.index %i[timestamp session_id]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/analytic/version.rb
CHANGED
data/lib/analytic.rb
CHANGED
@@ -1,6 +1,18 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'analytic/config'
|
4
|
+
require 'analytic/version'
|
5
|
+
require 'analytic/engine'
|
3
6
|
|
4
7
|
module Analytic
|
5
|
-
#
|
8
|
+
# @return [Analytic::Config]
|
9
|
+
def self.config
|
10
|
+
@config ||= Config.new
|
11
|
+
end
|
12
|
+
|
13
|
+
# @yield [config]
|
14
|
+
# @yieldparam config [Analytic::Config]
|
15
|
+
def self.configure
|
16
|
+
yield config
|
17
|
+
end
|
6
18
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: analytic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Sylvestre
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-08-
|
11
|
+
date: 2024-08-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -16,35 +16,58 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
27
|
-
description:
|
26
|
+
version: '0'
|
27
|
+
description: Analytic
|
28
28
|
email:
|
29
29
|
- kevin@ksylvest.com
|
30
30
|
executables: []
|
31
31
|
extensions: []
|
32
32
|
extra_rdoc_files: []
|
33
33
|
files:
|
34
|
-
-
|
34
|
+
- LICENSE
|
35
35
|
- README.md
|
36
36
|
- Rakefile
|
37
|
+
- app/assets/builds/analytic/application.css
|
38
|
+
- app/assets/builds/analytic/application.js
|
39
|
+
- app/assets/builds/analytic/application.js.map
|
40
|
+
- app/assets/config/analytic_manifest.js
|
41
|
+
- app/controllers/analytic/application_controller.rb
|
42
|
+
- app/controllers/analytic/dashboard_controller.rb
|
43
|
+
- app/controllers/concerns/analytic/trackable.rb
|
44
|
+
- app/helpers/analytic/application_helper.rb
|
45
|
+
- app/jobs/analytic/application_job.rb
|
46
|
+
- app/jobs/analytic/track_job.rb
|
47
|
+
- app/mailers/analytic/application_mailer.rb
|
48
|
+
- app/models/analytic/application_record.rb
|
49
|
+
- app/models/analytic/dashboard.rb
|
50
|
+
- app/models/analytic/view.rb
|
51
|
+
- app/packs/analytic/application/index.ts
|
52
|
+
- app/packs/analytic/application/initializers/fontawesome.ts
|
53
|
+
- app/packs/analytic/application/initializers/index.ts
|
54
|
+
- app/packs/analytic/entrypoints/application.tailwind.css
|
55
|
+
- app/packs/analytic/entrypoints/application.ts
|
56
|
+
- app/views/analytic/dashboard/show.html.erb
|
57
|
+
- app/views/layouts/analytic/application.html.erb
|
58
|
+
- bin/dev
|
59
|
+
- bin/rails
|
60
|
+
- config/routes.rb
|
61
|
+
- db/migrate/20240805210911_create_analytic_views.rb
|
37
62
|
- lib/analytic.rb
|
38
|
-
- lib/analytic/
|
63
|
+
- lib/analytic/config.rb
|
64
|
+
- lib/analytic/engine.rb
|
39
65
|
- lib/analytic/version.rb
|
40
|
-
- lib/tasks/analytic_tasks.rake
|
41
66
|
homepage: https://github.com/ksylvest/analytic
|
42
67
|
licenses:
|
43
68
|
- MIT
|
44
69
|
metadata:
|
45
|
-
|
46
|
-
source_code_uri: https://github.com/ksylvest/analytic
|
47
|
-
changelog_uri: https://github.com/ksylvest/analytic
|
70
|
+
rubygems_mfa_required: 'true'
|
48
71
|
post_install_message:
|
49
72
|
rdoc_options: []
|
50
73
|
require_paths:
|
@@ -53,7 +76,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
53
76
|
requirements:
|
54
77
|
- - ">="
|
55
78
|
- !ruby/object:Gem::Version
|
56
|
-
version:
|
79
|
+
version: 3.3.0
|
57
80
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
81
|
requirements:
|
59
82
|
- - ">="
|
@@ -63,5 +86,5 @@ requirements: []
|
|
63
86
|
rubygems_version: 3.5.11
|
64
87
|
signing_key:
|
65
88
|
specification_version: 4
|
66
|
-
summary:
|
89
|
+
summary: Analytic
|
67
90
|
test_files: []
|
data/lib/analytic/railtie.rb
DELETED
/data/{MIT-LICENSE → LICENSE}
RENAMED
File without changes
|