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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 72f8712a5ef672d537bed87b595cb922df6e99b950337ce5334c684f60a91bf7
4
- data.tar.gz: 75a69edda40e9d88de1e63f7f367e134f0fc4a45577a17b7d9e4043c9c127708
3
+ metadata.gz: e109fa9b8048c1833edf302f80b740a47708b789b36c6462a2af32a3b23827e0
4
+ data.tar.gz: '039a9c1466b32fd07ca4b0489b753a3e2be0b59258bf94ecb9778abdaa8e0e25'
5
5
  SHA512:
6
- metadata.gz: 45aea74561e345bede5e08ec98f188e5fc82eeeabc22e4048d6facf5cbe33ad006fbf36b1ff3ab4fe29039836a23c67730c3fcb26a1bff8e6ec1fb49c083a0fd
7
- data.tar.gz: fe9df256d44b947aa56ad5fd36f22dfaa249682d3cd6de6e46b14419a123f2d326b13a5dd6e8d2c60c8f7200f00d40988de25c7042dfb572e842f3788765b965
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.export
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'> &rarr; </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 << '&rarr;' }
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'> &mdash; No changes found &mdash; </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
@@ -1,3 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- ApplicationRecord.observers << Calagator::CacheObserver
3
+ Rails.configuration.after_initialize do
4
+ ApplicationRecord.observers << Calagator::CacheObserver
5
+ end
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") }
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "rack/contrib/jsonp"
4
+ require 'sprockets/railtie'
4
5
 
5
6
  module Calagator
6
7
  class Engine < ::Rails::Engine
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Calagator
4
- VERSION = "2.1.1"
4
+ VERSION = "4.0.0"
5
+ RAILS_VERSION = "~> 7.0"
5
6
  end
@@ -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
- rake "calagator:install:migrations"
19
- rake "db:migrate"
20
- rake "db:test:prepare"
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
- append_file "app/assets/javascripts/application.js", "//= require calagator"
45
+ create_file "app/assets/javascripts/application.js", "//= require calagator"
38
46
  end
39
47
 
40
48
  def add_stylesheets
41
- append_file "app/assets/stylesheets/application.css", "//= require calagator"
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(RAILS_REQUIREMENT)
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 #{RAILS_REQUIREMENT}. You are using #{rails_version}."
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 && {path: relative_calagator_path.to_s})
44
+ gem "calagator", Calagator::VERSION, (generating_test_app ? {path: relative_calagator_path.to_s} : {})
46
45
  run "bundle install"
47
- rake "db:create"
46
+ rails_command "db:create"
48
47
  inside("app/assets") do
49
- create_file("config/manifest.js") do
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", (generating_test_app && "--test_app")
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: 2.1.1
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-01-01 00:00:00.000000000 Z
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: '5.2'
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: '5.2'
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: 1.13.10
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: 1.13.10
273
+ version: '4.5'
281
274
  - !ruby/object:Gem::Dependency
282
- name: paper_trail
275
+ name: nokogiri
283
276
  requirement: !ruby/object:Gem::Requirement
284
277
  requirements:
285
278
  - - "~>"
286
279
  - !ruby/object:Gem::Version
287
- version: 10.3.1
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: 10.3.1
287
+ version: 1.14.5
295
288
  - !ruby/object:Gem::Dependency
296
- name: paper_trail_manager_rails_5
289
+ name: paper_trail
297
290
  requirement: !ruby/object:Gem::Requirement
298
291
  requirements:
299
292
  - - "~>"
300
293
  - !ruby/object:Gem::Version
301
- version: 0.7.2
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: 0.7.2
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.9.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.9.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: 0.19.0
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: 0.19.0
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.5.4
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: 3.1.5
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: '6.2'
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: '6.2'
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.1.0
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.1.0
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.2.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: []