koalagator 2.1.1 → 4.0.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.
- checksums.yaml +4 -4
- data/app/controllers/calagator/application_controller.rb +3 -3
- data/app/controllers/paper_trail_manager/changes_controller.rb +131 -0
- data/app/helpers/paper_trail_manager/changes_helper.rb +82 -0
- data/app/models/calagator/event/ical_renderer.rb +3 -2
- data/app/models/calagator/event.rb +2 -2
- data/app/models/calagator/venue.rb +1 -1
- data/app/views/paper_trail_manager/changes/_version.html.erb +40 -0
- data/app/views/paper_trail_manager/changes/index.atom.builder +48 -0
- data/app/views/paper_trail_manager/changes/index.html.erb +35 -0
- data/app/views/paper_trail_manager/changes/show.html.erb +10 -0
- data/bin/calagator +4 -5
- data/config/initializers/observers.rb +3 -1
- data/config/routes.rb +6 -2
- data/lib/calagator/duplicate_checking.rb +1 -1
- data/lib/calagator/engine.rb +1 -0
- data/lib/calagator/version.rb +2 -1
- data/lib/generators/calagator/install_generator.rb +18 -5
- data/lib/paper_trail_manager.rb +67 -0
- data/rails_template.rb +7 -10
- metadata +44 -74
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e109fa9b8048c1833edf302f80b740a47708b789b36c6462a2af32a3b23827e0
|
4
|
+
data.tar.gz: '039a9c1466b32fd07ca4b0489b753a3e2be0b59258bf94ecb9778abdaa8e0e25'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 17489cd62b0f43b196d0bd6b6f2e6c59e1059552411230d127076d45fcccea52f0696b7c548cadacc51deefd8ab9f1f844a5d16b1e3540e8a1abcadaa475a03d
|
7
|
+
data.tar.gz: 3a40b16d6d02c6e8fc1b46a1b0588aca1d2d185521585c72efc3fe00cec1c40477c0da4306932e4ccf14f89c09318ae1da5efe3ac08b3769ef1844bc07ead0a0
|
@@ -33,11 +33,11 @@ module Calagator
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def self.require_admin(options = {})
|
36
|
+
return false unless Calagator.admin_username && Calagator.admin_password
|
36
37
|
http_basic_authenticate_with(
|
37
|
-
options.reverse_merge(
|
38
|
+
**options.reverse_merge(
|
38
39
|
name: Calagator.admin_username,
|
39
|
-
password: Calagator.admin_password
|
40
|
-
if: proc { Calagator.admin_username && Calagator.admin_password }
|
40
|
+
password: Calagator.admin_password
|
41
41
|
)
|
42
42
|
)
|
43
43
|
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Allow the parent class of ChangesController to be configured in the host app
|
4
|
+
PaperTrailManager::ChangesController = Class.new(PaperTrailManager.base_controller.constantize)
|
5
|
+
|
6
|
+
class PaperTrailManager
|
7
|
+
class ChangesController
|
8
|
+
# Default number of changes to list on a pagenated index page.
|
9
|
+
PER_PAGE = 50
|
10
|
+
|
11
|
+
helper PaperTrailManager.route_helpers if PaperTrailManager.route_helpers
|
12
|
+
helper PaperTrailManager::ChangesHelper
|
13
|
+
layout PaperTrailManager.layout if PaperTrailManager.layout
|
14
|
+
|
15
|
+
# List changes
|
16
|
+
def index
|
17
|
+
unless change_index_allowed?
|
18
|
+
flash[:error] = 'You do not have permission to list changes.'
|
19
|
+
return(redirect_to root_url)
|
20
|
+
end
|
21
|
+
|
22
|
+
@versions = PaperTrail::Version.order('created_at DESC, id DESC')
|
23
|
+
@versions = @versions.where(item_type: params[:type]) if params[:type]
|
24
|
+
@versions = @versions.where(item_id: params[:id]) if params[:id]
|
25
|
+
|
26
|
+
# Ensure pagination parameters have sensible values
|
27
|
+
@page = params[:page].to_i
|
28
|
+
@page = nil if @page.zero?
|
29
|
+
|
30
|
+
@per_page = params[:per_page].to_i
|
31
|
+
@per_page = nil if @per_page.zero?
|
32
|
+
|
33
|
+
@versions = if defined?(WillPaginate)
|
34
|
+
@versions.paginate(page: @page, per_page: @per_page)
|
35
|
+
else
|
36
|
+
@versions.page(@page).per(@per_page)
|
37
|
+
end
|
38
|
+
|
39
|
+
respond_to do |format|
|
40
|
+
format.html # index.html.erb
|
41
|
+
format.atom # index.atom.builder
|
42
|
+
format.json { render json: @versions }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Show a change
|
47
|
+
def show
|
48
|
+
begin
|
49
|
+
@version = PaperTrail::Version.find(params[:id])
|
50
|
+
rescue ActiveRecord::RecordNotFound
|
51
|
+
flash[:error] = 'No such version.'
|
52
|
+
return(redirect_to action: :index)
|
53
|
+
end
|
54
|
+
|
55
|
+
unless change_show_allowed?(@version)
|
56
|
+
flash[:error] = 'You do not have permission to show that change.'
|
57
|
+
return(redirect_to action: :index)
|
58
|
+
end
|
59
|
+
|
60
|
+
respond_to do |format|
|
61
|
+
format.html # show.html.erb
|
62
|
+
format.json { render json: @version }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Rollback a change
|
67
|
+
def update
|
68
|
+
begin
|
69
|
+
@version = PaperTrail::Version.find(params[:id])
|
70
|
+
rescue ActiveRecord::RecordNotFound
|
71
|
+
flash[:error] = 'No such version.'
|
72
|
+
return(redirect_to(changes_path))
|
73
|
+
end
|
74
|
+
|
75
|
+
unless change_revert_allowed?(@version)
|
76
|
+
flash[:error] = 'You do not have permission to revert this change.'
|
77
|
+
return(redirect_to changes_path)
|
78
|
+
end
|
79
|
+
|
80
|
+
if @version.event == 'create'
|
81
|
+
@record = @version.item_type.constantize.find(@version.item_id)
|
82
|
+
@result = @record.destroy
|
83
|
+
else
|
84
|
+
@record = @version.reify
|
85
|
+
@result = @record.save
|
86
|
+
end
|
87
|
+
|
88
|
+
if @result
|
89
|
+
if @version.event == 'create'
|
90
|
+
flash[:notice] = 'Rolled back newly-created record by destroying it.'
|
91
|
+
redirect_to changes_path
|
92
|
+
else
|
93
|
+
flash[:notice] = 'Rolled back changes to this record.'
|
94
|
+
redirect_to change_item_url(@version)
|
95
|
+
end
|
96
|
+
else
|
97
|
+
flash[:error] = "Couldn't rollback. Sorry."
|
98
|
+
redirect_to changes_path
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
protected
|
103
|
+
|
104
|
+
# Return the URL for the item represented by the +version+, e.g. a Company record instance referenced by a version.
|
105
|
+
def change_item_url(version)
|
106
|
+
version_type = version.item_type.underscore.split('/').last
|
107
|
+
send("#{version_type}_url", version.item_id)
|
108
|
+
rescue NoMethodError
|
109
|
+
nil
|
110
|
+
end
|
111
|
+
helper_method :change_item_url
|
112
|
+
|
113
|
+
# Allow index?
|
114
|
+
def change_index_allowed?
|
115
|
+
PaperTrailManager.allow_index?(self)
|
116
|
+
end
|
117
|
+
helper_method :change_index_allowed?
|
118
|
+
|
119
|
+
# Allow show?
|
120
|
+
def change_show_allowed?(version)
|
121
|
+
PaperTrailManager.allow_show?(self, version)
|
122
|
+
end
|
123
|
+
helper_method :change_show_allowed?
|
124
|
+
|
125
|
+
# Allow revert?
|
126
|
+
def change_revert_allowed?(version)
|
127
|
+
PaperTrailManager.allow_revert?(self, version)
|
128
|
+
end
|
129
|
+
helper_method :change_revert_allowed?
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class PaperTrailManager
|
4
|
+
module ChangesHelper
|
5
|
+
# Return HTML representing the +object+, which is either its text or a stylized "nil".
|
6
|
+
def text_or_nil(object)
|
7
|
+
if object.nil?
|
8
|
+
content_tag('em', 'nil')
|
9
|
+
else
|
10
|
+
h(object)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Return an hash of changes for the given +PaperTrail::Version+ record. The resulting
|
15
|
+
# data structure is a hash whose keys are the names of changed columns and
|
16
|
+
# values containing a hash with current and previous value. E.g.,:
|
17
|
+
#
|
18
|
+
# {
|
19
|
+
# "my_column_name" => {
|
20
|
+
# :previous => "past value",
|
21
|
+
# :current => "current_value",
|
22
|
+
# },
|
23
|
+
# "title" => {
|
24
|
+
# :previous => "puppies",
|
25
|
+
# :current => "kittens",
|
26
|
+
# },
|
27
|
+
# ...
|
28
|
+
# }
|
29
|
+
def changes_for(version)
|
30
|
+
case version.event
|
31
|
+
when 'create', 'update'
|
32
|
+
return {} unless version.changeset
|
33
|
+
|
34
|
+
version.changeset.inject({}) do |changes, (attr, (prev, curr))|
|
35
|
+
changes.store(attr, { previous: prev, current: curr }) && changes
|
36
|
+
end
|
37
|
+
when 'destroy'
|
38
|
+
record = version_reify(version)
|
39
|
+
return {} unless record
|
40
|
+
|
41
|
+
record.attributes.reject { |_k, v| v.nil? }.inject({}) do |changes, (attr, value)|
|
42
|
+
changes.store(attr, { previous: value, current: nil }) && changes
|
43
|
+
end
|
44
|
+
else
|
45
|
+
raise ArgumentError, "Unknown event: #{version.event}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Returns string title for the versioned record.
|
50
|
+
def change_title_for(version)
|
51
|
+
if PaperTrailManager.item_name_method
|
52
|
+
record = version_reify(version) || version.next.try(:reify) || version.item
|
53
|
+
name = record.send(PaperTrailManager.item_name_method)
|
54
|
+
else
|
55
|
+
name = "#{version.item_type} #{version.item_id}"
|
56
|
+
end
|
57
|
+
|
58
|
+
h(name)
|
59
|
+
end
|
60
|
+
|
61
|
+
def change_item_types
|
62
|
+
ActiveRecord::Base.subclasses.select do |klass|
|
63
|
+
klass.include?(PaperTrail::Model::InstanceMethods)
|
64
|
+
end.map(&:to_s)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns HTML link for the item stored in the version, e.g. a link to a Company record stored in the version.
|
68
|
+
def change_item_link(version)
|
69
|
+
if (url = change_item_url(version))
|
70
|
+
link_to(change_title_for(version), url, class: 'change_item')
|
71
|
+
else
|
72
|
+
content_tag(:span, change_title_for(version), class: 'change_item')
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def version_reify(version)
|
77
|
+
version.reify
|
78
|
+
rescue ArgumentError
|
79
|
+
nil
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -24,7 +24,7 @@ module Calagator
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def self.render_icalendar(events, opts)
|
27
|
-
RiCal.Calendar do |calendar|
|
27
|
+
cal = RiCal.Calendar do |calendar|
|
28
28
|
calendar.prodid = "-//Calagator//EN"
|
29
29
|
|
30
30
|
Array(events).each do |event|
|
@@ -32,7 +32,8 @@ module Calagator
|
|
32
32
|
new(event, opts).add_event_to(entry)
|
33
33
|
end
|
34
34
|
end
|
35
|
-
end
|
35
|
+
end
|
36
|
+
cal.export
|
36
37
|
end
|
37
38
|
|
38
39
|
def self.add_name(output)
|
@@ -49,8 +49,8 @@ module Calagator
|
|
49
49
|
include ActiveModel::Serializers::Xml
|
50
50
|
|
51
51
|
# Associations
|
52
|
-
belongs_to :venue, counter_cache: true
|
53
|
-
belongs_to :source
|
52
|
+
belongs_to :venue, counter_cache: true, optional: true
|
53
|
+
belongs_to :source, optional: true
|
54
54
|
|
55
55
|
# Validations
|
56
56
|
validates :title, :description, :url, denylist: true
|
@@ -51,7 +51,7 @@ module Calagator
|
|
51
51
|
|
52
52
|
# Associations
|
53
53
|
has_many :events, -> { non_duplicates }, dependent: :nullify
|
54
|
-
belongs_to :source
|
54
|
+
belongs_to :source, optional: true
|
55
55
|
|
56
56
|
# Triggers
|
57
57
|
strip_whitespace! :title, :description, :address, :url, :street_address, :locality, :region, :postal_code, :country, :email, :telephone
|
@@ -0,0 +1,40 @@
|
|
1
|
+
<tr class='change_row <%= "change_event_#{version.event} #{version.event} #{version.event}, #{version.item_type.downcase}" %>'>
|
2
|
+
<td class='change_time'>
|
3
|
+
<span class='change_id'>Change #<%= version.id %></span>
|
4
|
+
<div class='date'> <%= version.created_at.strftime('%Y-%m-%d') %> </div>
|
5
|
+
<div class='time'> <%= version.created_at.strftime('%H:%M:%S') %> </div>
|
6
|
+
</td>
|
7
|
+
<td class='change_details'>
|
8
|
+
<p class='change_details_description'>
|
9
|
+
<strong class='event'><%= version.event %></strong>
|
10
|
+
<%= change_item_link(version) %>
|
11
|
+
<% if PaperTrailManager.whodunnit_class && version.whodunnit %>
|
12
|
+
<% if user = PaperTrailManager.whodunnit_class.find(version.whodunnit) rescue nil %>
|
13
|
+
<% if PaperTrailManager.user_path_method && user %>
|
14
|
+
by <%= link_to(h(user.send(PaperTrailManager.whodunnit_name_method)), send(:user_path_method, user)) %>
|
15
|
+
<% else %>
|
16
|
+
by <%= h(user.send(PaperTrailManager.whodunnit_name_method)) %>
|
17
|
+
<% end %>
|
18
|
+
<% else %>
|
19
|
+
by <%= version.whodunnit %>
|
20
|
+
<% end %>
|
21
|
+
<% end %>
|
22
|
+
<% if change_revert_allowed?(version) %>
|
23
|
+
<%= link_to 'Roll back', change_path(version), :method => 'put', :class => 'rollback', :data => { :confirm => 'Are you sure?' } %>
|
24
|
+
<% end %>
|
25
|
+
</p>
|
26
|
+
<% if version.event == 'update' or version.event == 'create' %>
|
27
|
+
<% changes = changes_for(version) %>
|
28
|
+
<table class='change_details_table'>
|
29
|
+
<% changes.keys.sort.each_with_index do |key, i| %>
|
30
|
+
<tr class='<%= i%2==0 ? 'even' : 'odd' %>'>
|
31
|
+
<td class='change_detail_key previous'><%= key %></td>
|
32
|
+
<td class='change_detail_value previous'><%= text_or_nil(changes[key][:previous]) %></td>
|
33
|
+
<td class='change_detail_spacer'> → </td>
|
34
|
+
<td class='change_detail_value current'><%= text_or_nil(changes[key][:current]) %></td>
|
35
|
+
</tr>
|
36
|
+
<% end %>
|
37
|
+
</table>
|
38
|
+
<% end %>
|
39
|
+
</td>
|
40
|
+
</tr>
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
atom_feed do |feed|
|
4
|
+
feed.title('Changes')
|
5
|
+
date = @versions.first.try(:created_at) || Time.zone.at(0)
|
6
|
+
feed.updated(date)
|
7
|
+
|
8
|
+
@versions.each do |version|
|
9
|
+
next unless change_show_allowed?(version)
|
10
|
+
|
11
|
+
feed.entry(version, url: change_url(version)) do |entry|
|
12
|
+
changes = changes_for(version)
|
13
|
+
|
14
|
+
user = if PaperTrailManager.whodunnit_class && version.whodunnit
|
15
|
+
begin
|
16
|
+
PaperTrailManager.whodunnit_class.find(version.whodunnit)
|
17
|
+
rescue StandardError
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
entry.title "#{version.event.upcase} #{version.item_type} «#{change_title_for(version)}» #{user ? 'by ' + user.send(PaperTrailManager.whodunnit_name_method) : ''}"
|
23
|
+
entry.updated version.created_at.utc.xmlschema
|
24
|
+
|
25
|
+
xm = ::Builder::XmlMarkup.new
|
26
|
+
xm.div do
|
27
|
+
xm.p do
|
28
|
+
xm.span << 'Go to: '
|
29
|
+
xm.span << link_to('Change', change_url(version))
|
30
|
+
xm.span << ' | '
|
31
|
+
xm.span << link_to('Record', change_item_url(version))
|
32
|
+
end
|
33
|
+
xm.table do
|
34
|
+
changes.keys.sort.each do |key|
|
35
|
+
xm.tr do
|
36
|
+
xm.td { xm.b key }
|
37
|
+
xm.td changes[key][:previous].inspect
|
38
|
+
xm.td { xm.span << '→' }
|
39
|
+
xm.td changes[key][:current].inspect
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
entry.content(xm.to_s, type: 'html')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
<h1>Changes</h1>
|
2
|
+
|
3
|
+
<p class='changes_feed'><%= link_to 'Changes feed', changes_path(:format => 'atom') %></p>
|
4
|
+
|
5
|
+
<p>
|
6
|
+
Show:
|
7
|
+
<%= ([link_to('All', changes_path)] + change_item_types.map { |type| link_to(type.pluralize, changes_path(:type => type)) }).join(' | ').html_safe %>
|
8
|
+
</p>
|
9
|
+
|
10
|
+
<table class='changes_table'>
|
11
|
+
<tfoot>
|
12
|
+
<tr>
|
13
|
+
<td colspan='2'>
|
14
|
+
<%= paginate @versions %>
|
15
|
+
</td>
|
16
|
+
</tr>
|
17
|
+
</tfoot>
|
18
|
+
<thead>
|
19
|
+
<tr class='changes_header'>
|
20
|
+
<th class='change_time'>Time</th>
|
21
|
+
<th class='change_details'>Attribute with previous and current values</th>
|
22
|
+
</tr>
|
23
|
+
</thead>
|
24
|
+
<tbody>
|
25
|
+
<% if @versions.any? %>
|
26
|
+
<% @versions.each do |version| %>
|
27
|
+
<% next unless change_show_allowed?(version) %>
|
28
|
+
<%= render :partial => 'version', :object => version %>
|
29
|
+
<% end %>
|
30
|
+
<% else %>
|
31
|
+
<td rowspan='2'> — No changes found — </td>
|
32
|
+
<% end %>
|
33
|
+
</tbody>
|
34
|
+
</table>
|
35
|
+
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<h1>Change <%= @version.id %></h1>
|
2
|
+
|
3
|
+
<table class='changes_table'>
|
4
|
+
<tr class='changes_header'>
|
5
|
+
<th class='change_time'>Time</th>
|
6
|
+
<th class='change_details'>Attribute with previous and current values</th>
|
7
|
+
<%= render :partial => 'version', :object => @version %>
|
8
|
+
</tr>
|
9
|
+
</table>
|
10
|
+
|
data/bin/calagator
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require_relative '../lib/calagator/version'
|
5
|
+
|
4
6
|
USAGE = <<~END
|
7
|
+
Calagator: v#{Calagator::VERSION}
|
5
8
|
calagator: setup Calagator in a new or existing Rails application
|
6
9
|
|
7
10
|
Usage:
|
@@ -17,10 +20,6 @@ USAGE = <<~END
|
|
17
20
|
In the case of `calagator new`, all other options will be passed along
|
18
21
|
to `rails new`; see `rails new --help` for supported options.
|
19
22
|
|
20
|
-
To generate an app using a specific Rails version, e.g. for 4.2.1:
|
21
|
-
|
22
|
-
calagator _4.2.1_ new my_great_calendar
|
23
|
-
|
24
23
|
calagator install: install Calagator into an existing Rails application
|
25
24
|
|
26
25
|
Options:
|
@@ -33,7 +32,7 @@ command = ARGV.shift
|
|
33
32
|
|
34
33
|
case command
|
35
34
|
when /_\d+\.\d+\.\d+_/, 'new'
|
36
|
-
system "rails #{command} #{ARGV.join(' ')} -m #{TEMPLATE_PATH} --skip-bundle"
|
35
|
+
system "rails #{command} #{ARGV.join(' ')} -m #{TEMPLATE_PATH} --skip-bundle --skip-javascript" # Skip Webpack on Rails 6 as we're on our way to Rails 7.
|
37
36
|
when 'install'
|
38
37
|
system "bundle exec rake rails:template LOCATION=#{TEMPLATE_PATH}"
|
39
38
|
else
|
data/config/routes.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
Calagator::Engine.routes.draw do
|
4
|
+
# Not sure why, but routes is getting loaded twice. This ignores the second load.
|
5
|
+
return unless Calagator::Engine.routes.empty?
|
6
|
+
|
7
|
+
root "site#index"
|
8
|
+
|
4
9
|
get "omfg" => "site#omfg"
|
5
10
|
get "hello" => "site#hello"
|
6
11
|
|
@@ -52,7 +57,6 @@ Calagator::Engine.routes.draw do
|
|
52
57
|
get "css/:name" => "site#style"
|
53
58
|
get "css/:name.:format" => "site#style"
|
54
59
|
|
55
|
-
get "/" => "site#index", :as => :root
|
56
60
|
get "/index" => "site#index"
|
57
61
|
get "/index.:format" => "site#index"
|
58
|
-
end
|
62
|
+
end
|
@@ -92,7 +92,7 @@ module Calagator
|
|
92
92
|
cattr_accessor(:_duplicate_finding_scope) { -> { all } }
|
93
93
|
cattr_accessor(:_after_squashing_duplicates) { ->(primary) {} }
|
94
94
|
|
95
|
-
belongs_to :duplicate_of, class_name: name, foreign_key: DUPLICATE_MARK_COLUMN
|
95
|
+
belongs_to :duplicate_of, class_name: name, foreign_key: DUPLICATE_MARK_COLUMN, optional: true
|
96
96
|
has_many :duplicates, class_name: name, foreign_key: DUPLICATE_MARK_COLUMN
|
97
97
|
|
98
98
|
scope :marked_duplicates, -> { where("#{table_name}.#{DUPLICATE_MARK_COLUMN} IS NOT NULL") }
|
data/lib/calagator/engine.rb
CHANGED
data/lib/calagator/version.rb
CHANGED
@@ -8,6 +8,7 @@ module Calagator
|
|
8
8
|
|
9
9
|
def install
|
10
10
|
add_route
|
11
|
+
add_yaml_config
|
11
12
|
add_initializers
|
12
13
|
add_javascripts
|
13
14
|
add_stylesheets
|
@@ -15,9 +16,9 @@ module Calagator
|
|
15
16
|
add_seeds
|
16
17
|
run "rm -f public/index.html"
|
17
18
|
unless options[:test_app]
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
rails_command "calagator:install:migrations"
|
20
|
+
rails_command "db:migrate"
|
21
|
+
rails_command "db:test:prepare"
|
21
22
|
end
|
22
23
|
end
|
23
24
|
|
@@ -27,6 +28,13 @@ module Calagator
|
|
27
28
|
inject_into_file "config/routes.rb", "\s\smount Calagator::Engine => '/'\n", after: "routes.draw do\n"
|
28
29
|
end
|
29
30
|
|
31
|
+
# PaperTrail needs Time and BigDecimal as supported YAML classes
|
32
|
+
def add_yaml_config
|
33
|
+
inject_into_file "config/application.rb",
|
34
|
+
"\s\s\s\sconfig.active_record.yaml_column_permitted_classes = [Time, BigDecimal]",
|
35
|
+
after: /config.load_defaults.+\n/
|
36
|
+
end
|
37
|
+
|
30
38
|
def add_initializers
|
31
39
|
initializer "01_calagator.rb", File.read(File.expand_path("templates/config/initializers/01_calagator.rb", __dir__))
|
32
40
|
initializer "02_geokit.rb", File.read(File.expand_path("templates/config/initializers/02_geokit.rb", __dir__))
|
@@ -34,11 +42,16 @@ module Calagator
|
|
34
42
|
end
|
35
43
|
|
36
44
|
def add_javascripts
|
37
|
-
|
45
|
+
create_file "app/assets/javascripts/application.js", "//= require calagator"
|
38
46
|
end
|
39
47
|
|
40
48
|
def add_stylesheets
|
41
|
-
|
49
|
+
insert_into_file "app/assets/stylesheets/application.css", before: "*/" do
|
50
|
+
<<-STR.strip_heredoc
|
51
|
+
|
52
|
+
//= require calagator
|
53
|
+
STR
|
54
|
+
end
|
42
55
|
end
|
43
56
|
|
44
57
|
def add_assets
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails'
|
4
|
+
require 'paper_trail'
|
5
|
+
|
6
|
+
begin
|
7
|
+
require 'will_paginate'
|
8
|
+
rescue LoadError
|
9
|
+
begin
|
10
|
+
require 'kaminari'
|
11
|
+
rescue LoadError
|
12
|
+
raise LoadError, 'will_paginate or kaminari must be in Gemfile or load_path'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class PaperTrailManager < Rails::Engine
|
17
|
+
initializer 'paper_trail_manager.pagination' do
|
18
|
+
::ActionView::Base.send(:alias_method, :paginate, :will_paginate) if defined?(WillPaginate)
|
19
|
+
end
|
20
|
+
|
21
|
+
@@whodunnit_name_method = :name
|
22
|
+
cattr_accessor :whodunnit_class, :whodunnit_name_method, :route_helpers,
|
23
|
+
:layout, :base_controller, :user_path_method, :item_name_method
|
24
|
+
|
25
|
+
self.base_controller = 'ApplicationController'
|
26
|
+
self.user_path_method = :user_path
|
27
|
+
|
28
|
+
(Pathname(__FILE__).dirname + '..').tap do |base|
|
29
|
+
paths['app/controller'] = base + 'app/controllers'
|
30
|
+
paths['app/view'] = base + 'app/views'
|
31
|
+
end
|
32
|
+
|
33
|
+
cattr_accessor :allow_index_block, :allow_show_block, :allow_revert_block
|
34
|
+
|
35
|
+
block = proc { true }
|
36
|
+
self.allow_index_block = block
|
37
|
+
self.allow_show_block = block
|
38
|
+
self.allow_revert_block = block
|
39
|
+
|
40
|
+
def self.allow_index_when(&block)
|
41
|
+
self.allow_index_block = block
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.allow_index?(controller)
|
45
|
+
allow_index_block.call controller
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.allow_show_when(&block)
|
49
|
+
self.allow_show_block = block
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.allow_show?(controller, version)
|
53
|
+
allow_index_block.call controller, version
|
54
|
+
end
|
55
|
+
|
56
|
+
# Describe when to allow reverts. Call this with a block that accepts
|
57
|
+
# arguments for +controller+ and +version+.
|
58
|
+
def self.allow_revert_when(&block)
|
59
|
+
self.allow_revert_block = block
|
60
|
+
end
|
61
|
+
|
62
|
+
# Allow revert given the +controller+ and +version+? If no
|
63
|
+
# ::allow_revert_when was specified, always return +true+.
|
64
|
+
def self.allow_revert?(controller, version)
|
65
|
+
allow_revert_block.call controller, version
|
66
|
+
end
|
67
|
+
end
|
data/rails_template.rb
CHANGED
@@ -2,15 +2,14 @@
|
|
2
2
|
|
3
3
|
require "rubygems"
|
4
4
|
require "pathname"
|
5
|
-
|
6
|
-
RAILS_REQUIREMENT = "~> 5.2"
|
5
|
+
require_relative './lib/calagator/version'
|
7
6
|
|
8
7
|
def assert_minimum_rails_version
|
9
|
-
requirement = Gem::Requirement.new(
|
8
|
+
requirement = Gem::Requirement.new(Calagator::RAILS_VERSION)
|
10
9
|
rails_version = Gem::Version.new(Rails::VERSION::STRING)
|
11
10
|
return if requirement.satisfied_by?(rails_version)
|
12
11
|
|
13
|
-
puts "Calagator requires Rails #{
|
12
|
+
puts "Calagator requires Rails #{Calagator::RAILS_VERSION}. You are using #{rails_version}."
|
14
13
|
exit 1
|
15
14
|
end
|
16
15
|
|
@@ -42,17 +41,15 @@ gem_group :development, :test do
|
|
42
41
|
end
|
43
42
|
end
|
44
43
|
|
45
|
-
gem "calagator", (generating_test_app
|
44
|
+
gem "calagator", Calagator::VERSION, (generating_test_app ? {path: relative_calagator_path.to_s} : {})
|
46
45
|
run "bundle install"
|
47
|
-
|
46
|
+
rails_command "db:create"
|
48
47
|
inside("app/assets") do
|
49
|
-
|
48
|
+
append_to_file("config/manifest.js") do
|
50
49
|
<<-MANIFEST.strip_heredoc
|
51
50
|
//= link application.js
|
52
51
|
//= link application.css
|
53
|
-
//= link calagator/manifest.js
|
54
52
|
MANIFEST
|
55
53
|
end
|
56
54
|
end
|
57
|
-
generate "calagator:install",
|
58
|
-
generate "sunspot_rails:install"
|
55
|
+
generate "calagator:install", "--test-app #{generating_test_app}"
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: koalagator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 4.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Koalagator team
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date: 2025-
|
10
|
+
date: 2025-03-20 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: rails
|
@@ -16,14 +15,28 @@ dependencies:
|
|
16
15
|
requirements:
|
17
16
|
- - "~>"
|
18
17
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
18
|
+
version: '7.0'
|
20
19
|
type: :runtime
|
21
20
|
prerelease: false
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
23
22
|
requirements:
|
24
23
|
- - "~>"
|
25
24
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
25
|
+
version: '7.0'
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: sprockets-rails
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
27
40
|
- !ruby/object:Gem::Dependency
|
28
41
|
name: activemodel-serializers-xml
|
29
42
|
requirement: !ruby/object:Gem::Requirement
|
@@ -246,66 +259,46 @@ dependencies:
|
|
246
259
|
version: '0.1'
|
247
260
|
- !ruby/object:Gem::Dependency
|
248
261
|
name: microformats
|
249
|
-
requirement: !ruby/object:Gem::Requirement
|
250
|
-
requirements:
|
251
|
-
- - ">="
|
252
|
-
- !ruby/object:Gem::Version
|
253
|
-
version: 4.0.7
|
254
|
-
- - "<"
|
255
|
-
- !ruby/object:Gem::Version
|
256
|
-
version: 4.5.0
|
257
|
-
type: :runtime
|
258
|
-
prerelease: false
|
259
|
-
version_requirements: !ruby/object:Gem::Requirement
|
260
|
-
requirements:
|
261
|
-
- - ">="
|
262
|
-
- !ruby/object:Gem::Version
|
263
|
-
version: 4.0.7
|
264
|
-
- - "<"
|
265
|
-
- !ruby/object:Gem::Version
|
266
|
-
version: 4.5.0
|
267
|
-
- !ruby/object:Gem::Dependency
|
268
|
-
name: nokogiri
|
269
262
|
requirement: !ruby/object:Gem::Requirement
|
270
263
|
requirements:
|
271
264
|
- - "~>"
|
272
265
|
- !ruby/object:Gem::Version
|
273
|
-
version:
|
266
|
+
version: '4.5'
|
274
267
|
type: :runtime
|
275
268
|
prerelease: false
|
276
269
|
version_requirements: !ruby/object:Gem::Requirement
|
277
270
|
requirements:
|
278
271
|
- - "~>"
|
279
272
|
- !ruby/object:Gem::Version
|
280
|
-
version:
|
273
|
+
version: '4.5'
|
281
274
|
- !ruby/object:Gem::Dependency
|
282
|
-
name:
|
275
|
+
name: nokogiri
|
283
276
|
requirement: !ruby/object:Gem::Requirement
|
284
277
|
requirements:
|
285
278
|
- - "~>"
|
286
279
|
- !ruby/object:Gem::Version
|
287
|
-
version:
|
280
|
+
version: 1.14.5
|
288
281
|
type: :runtime
|
289
282
|
prerelease: false
|
290
283
|
version_requirements: !ruby/object:Gem::Requirement
|
291
284
|
requirements:
|
292
285
|
- - "~>"
|
293
286
|
- !ruby/object:Gem::Version
|
294
|
-
version:
|
287
|
+
version: 1.14.5
|
295
288
|
- !ruby/object:Gem::Dependency
|
296
|
-
name:
|
289
|
+
name: paper_trail
|
297
290
|
requirement: !ruby/object:Gem::Requirement
|
298
291
|
requirements:
|
299
292
|
- - "~>"
|
300
293
|
- !ruby/object:Gem::Version
|
301
|
-
version:
|
294
|
+
version: '15.1'
|
302
295
|
type: :runtime
|
303
296
|
prerelease: false
|
304
297
|
version_requirements: !ruby/object:Gem::Requirement
|
305
298
|
requirements:
|
306
299
|
- - "~>"
|
307
300
|
- !ruby/object:Gem::Version
|
308
|
-
version:
|
301
|
+
version: '15.1'
|
309
302
|
- !ruby/object:Gem::Dependency
|
310
303
|
name: rack-contrib
|
311
304
|
requirement: !ruby/object:Gem::Requirement
|
@@ -382,14 +375,14 @@ dependencies:
|
|
382
375
|
requirements:
|
383
376
|
- - "~>"
|
384
377
|
- !ruby/object:Gem::Version
|
385
|
-
version: 0.
|
378
|
+
version: 0.10.0
|
386
379
|
type: :runtime
|
387
380
|
prerelease: false
|
388
381
|
version_requirements: !ruby/object:Gem::Requirement
|
389
382
|
requirements:
|
390
383
|
- - "~>"
|
391
384
|
- !ruby/object:Gem::Version
|
392
|
-
version: 0.
|
385
|
+
version: 0.10.0
|
393
386
|
- !ruby/object:Gem::Dependency
|
394
387
|
name: sassc-rails
|
395
388
|
requirement: !ruby/object:Gem::Requirement
|
@@ -486,42 +479,28 @@ dependencies:
|
|
486
479
|
requirements:
|
487
480
|
- - "~>"
|
488
481
|
- !ruby/object:Gem::Version
|
489
|
-
version:
|
482
|
+
version: 1.5.9
|
490
483
|
type: :runtime
|
491
484
|
prerelease: false
|
492
485
|
version_requirements: !ruby/object:Gem::Requirement
|
493
486
|
requirements:
|
494
487
|
- - "~>"
|
495
488
|
- !ruby/object:Gem::Version
|
496
|
-
version:
|
489
|
+
version: 1.5.9
|
497
490
|
- !ruby/object:Gem::Dependency
|
498
491
|
name: sqlite3
|
499
492
|
requirement: !ruby/object:Gem::Requirement
|
500
493
|
requirements:
|
501
494
|
- - "~>"
|
502
495
|
- !ruby/object:Gem::Version
|
503
|
-
version: 1.
|
504
|
-
type: :runtime
|
505
|
-
prerelease: false
|
506
|
-
version_requirements: !ruby/object:Gem::Requirement
|
507
|
-
requirements:
|
508
|
-
- - "~>"
|
509
|
-
- !ruby/object:Gem::Version
|
510
|
-
version: 1.5.4
|
511
|
-
- !ruby/object:Gem::Dependency
|
512
|
-
name: listen
|
513
|
-
requirement: !ruby/object:Gem::Requirement
|
514
|
-
requirements:
|
515
|
-
- - "~>"
|
516
|
-
- !ruby/object:Gem::Version
|
517
|
-
version: 3.1.5
|
496
|
+
version: 1.6.9
|
518
497
|
type: :runtime
|
519
498
|
prerelease: false
|
520
499
|
version_requirements: !ruby/object:Gem::Requirement
|
521
500
|
requirements:
|
522
501
|
- - "~>"
|
523
502
|
- !ruby/object:Gem::Version
|
524
|
-
version:
|
503
|
+
version: 1.6.9
|
525
504
|
- !ruby/object:Gem::Dependency
|
526
505
|
name: appraisal
|
527
506
|
requirement: !ruby/object:Gem::Requirement
|
@@ -570,14 +549,14 @@ dependencies:
|
|
570
549
|
requirements:
|
571
550
|
- - "~>"
|
572
551
|
- !ruby/object:Gem::Version
|
573
|
-
version: '
|
552
|
+
version: '5.2'
|
574
553
|
type: :development
|
575
554
|
prerelease: false
|
576
555
|
version_requirements: !ruby/object:Gem::Requirement
|
577
556
|
requirements:
|
578
557
|
- - "~>"
|
579
558
|
- !ruby/object:Gem::Version
|
580
|
-
version: '
|
559
|
+
version: '5.2'
|
581
560
|
- !ruby/object:Gem::Dependency
|
582
561
|
name: faker
|
583
562
|
requirement: !ruby/object:Gem::Requirement
|
@@ -682,14 +661,14 @@ dependencies:
|
|
682
661
|
requirements:
|
683
662
|
- - "~>"
|
684
663
|
- !ruby/object:Gem::Version
|
685
|
-
version: 4.
|
664
|
+
version: '4.18'
|
686
665
|
type: :development
|
687
666
|
prerelease: false
|
688
667
|
version_requirements: !ruby/object:Gem::Requirement
|
689
668
|
requirements:
|
690
669
|
- - "~>"
|
691
670
|
- !ruby/object:Gem::Version
|
692
|
-
version: 4.
|
671
|
+
version: '4.18'
|
693
672
|
- !ruby/object:Gem::Dependency
|
694
673
|
name: simplecov
|
695
674
|
requirement: !ruby/object:Gem::Requirement
|
@@ -760,20 +739,6 @@ dependencies:
|
|
760
739
|
- - "~>"
|
761
740
|
- !ruby/object:Gem::Version
|
762
741
|
version: 4.2.0
|
763
|
-
- !ruby/object:Gem::Dependency
|
764
|
-
name: webdrivers
|
765
|
-
requirement: !ruby/object:Gem::Requirement
|
766
|
-
requirements:
|
767
|
-
- - "~>"
|
768
|
-
- !ruby/object:Gem::Version
|
769
|
-
version: 5.2.0
|
770
|
-
type: :development
|
771
|
-
prerelease: false
|
772
|
-
version_requirements: !ruby/object:Gem::Requirement
|
773
|
-
requirements:
|
774
|
-
- - "~>"
|
775
|
-
- !ruby/object:Gem::Version
|
776
|
-
version: 5.2.0
|
777
742
|
- !ruby/object:Gem::Dependency
|
778
743
|
name: webmock
|
779
744
|
requirement: !ruby/object:Gem::Requirement
|
@@ -866,6 +831,7 @@ files:
|
|
866
831
|
- app/controllers/calagator/sources_controller.rb
|
867
832
|
- app/controllers/calagator/venues_controller.rb
|
868
833
|
- app/controllers/calagator/versions_controller.rb
|
834
|
+
- app/controllers/paper_trail_manager/changes_controller.rb
|
869
835
|
- app/helpers/calagator/application_helper.rb
|
870
836
|
- app/helpers/calagator/events_helper.rb
|
871
837
|
- app/helpers/calagator/google_event_export_helper.rb
|
@@ -873,6 +839,7 @@ files:
|
|
873
839
|
- app/helpers/calagator/sources_helper.rb
|
874
840
|
- app/helpers/calagator/tags_helper.rb
|
875
841
|
- app/helpers/calagator/time_range_helper.rb
|
842
|
+
- app/helpers/paper_trail_manager/changes_helper.rb
|
876
843
|
- app/models/calagator/application_record.rb
|
877
844
|
- app/models/calagator/event.rb
|
878
845
|
- app/models/calagator/event/browse.rb
|
@@ -949,6 +916,10 @@ files:
|
|
949
916
|
- app/views/layouts/calagator/_global_search.html.erb
|
950
917
|
- app/views/layouts/calagator/_header.html.erb
|
951
918
|
- app/views/layouts/calagator/application.html.erb
|
919
|
+
- app/views/paper_trail_manager/changes/_version.html.erb
|
920
|
+
- app/views/paper_trail_manager/changes/index.atom.builder
|
921
|
+
- app/views/paper_trail_manager/changes/index.html.erb
|
922
|
+
- app/views/paper_trail_manager/changes/show.html.erb
|
952
923
|
- bin/calagator
|
953
924
|
- config/initializers/dates.rb
|
954
925
|
- config/initializers/formtastic.rb
|
@@ -1015,6 +986,7 @@ files:
|
|
1015
986
|
- lib/generators/calagator/templates/config/initializers/01_calagator.rb
|
1016
987
|
- lib/generators/calagator/templates/config/initializers/02_geokit.rb
|
1017
988
|
- lib/generators/calagator/templates/config/initializers/03_recaptcha.rb
|
989
|
+
- lib/paper_trail_manager.rb
|
1018
990
|
- lib/tasks/auto_annotate_models.rake
|
1019
991
|
- lib/tasks/spec_db.rake
|
1020
992
|
- lib/tasks/sunspot_reindex_calagator.rake
|
@@ -1041,7 +1013,6 @@ homepage: https://github.com/koalagator/koalagator
|
|
1041
1013
|
licenses:
|
1042
1014
|
- AGPL-3.0-or-later
|
1043
1015
|
metadata: {}
|
1044
|
-
post_install_message:
|
1045
1016
|
rdoc_options: []
|
1046
1017
|
require_paths:
|
1047
1018
|
- lib
|
@@ -1056,8 +1027,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
1056
1027
|
- !ruby/object:Gem::Version
|
1057
1028
|
version: '0'
|
1058
1029
|
requirements: []
|
1059
|
-
rubygems_version: 3.
|
1060
|
-
signing_key:
|
1030
|
+
rubygems_version: 3.6.6
|
1061
1031
|
specification_version: 4
|
1062
1032
|
summary: A calendar for communities
|
1063
1033
|
test_files: []
|