koalagator 4.1.0 → 5.0.1
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/LICENSE.md +661 -0
- data/README.md +74 -21
- data/app/assets/config/calagator/manifest.js +5 -1
- data/app/assets/images/external_sites/mastodon.png +0 -0
- data/app/assets/images/nav_marker.png +0 -0
- data/app/assets/javascripts/calagator/forms.js +7 -0
- data/app/assets/stylesheets/calagator/custom/calendar.css +137 -0
- data/app/assets/stylesheets/calagator/errors.css +2 -4
- data/app/assets/stylesheets/calagator/forms.scss +5 -0
- data/app/assets/stylesheets/calagator/layout.scss +31 -9
- data/app/assets/stylesheets/calagator/typography.scss +39 -9
- data/app/assets/stylesheets/calagator/utils.scss +44 -0
- data/app/controllers/calagator/admin/curations_controller.rb +62 -0
- data/app/controllers/calagator/admin/users_controller.rb +79 -0
- data/app/controllers/calagator/application_controller.rb +29 -5
- data/app/controllers/calagator/curations_controller.rb +32 -0
- data/app/controllers/calagator/events_controller.rb +6 -0
- data/app/controllers/calagator/paper_trail_manager_controller.rb +5 -0
- data/app/controllers/calagator/passwords_controller.rb +4 -0
- data/app/controllers/calagator/registrations_controller.rb +5 -0
- data/app/controllers/calagator/sessions_controller.rb +4 -0
- data/app/controllers/calagator/site_controller.rb +10 -0
- data/app/controllers/calagator/sources_controller.rb +2 -0
- data/app/controllers/calagator/venues_controller.rb +5 -1
- data/app/controllers/calagator/versions_controller.rb +1 -1
- data/app/controllers/paper_trail_manager/changes_controller.rb +16 -16
- data/app/helpers/calagator/application_helper.rb +32 -3
- data/app/helpers/calagator/time_range_helper.rb +1 -1
- data/app/helpers/paper_trail_manager/changes_helper.rb +7 -7
- data/app/javascript/calagator/calendar/calendar.js +82 -0
- data/app/javascript/calagator/calendar/event.js +94 -0
- data/app/javascript/calagator/calendar/lib/components.js +120 -0
- data/app/javascript/calagator/calendar/lib/utils.js +67 -0
- data/app/models/calagator/curation.rb +32 -0
- data/app/models/calagator/event/browse.rb +3 -2
- data/app/models/calagator/event/cloner.rb +1 -1
- data/app/models/calagator/event/ical_renderer.rb +1 -1
- data/app/models/calagator/event/overview.rb +3 -1
- data/app/models/calagator/event/saver.rb +6 -1
- data/app/models/calagator/event/search.rb +1 -1
- data/app/models/calagator/event/search_engine.rb +1 -1
- data/app/models/calagator/event.rb +22 -5
- data/app/models/calagator/source/parser/hcal.rb +1 -1
- data/app/models/calagator/source/parser.rb +3 -3
- data/app/models/calagator/source.rb +23 -6
- data/app/models/calagator/user.rb +50 -0
- data/app/models/calagator/venue/geocoder.rb +1 -1
- data/app/models/calagator/venue/search.rb +1 -1
- data/app/models/calagator/venue/search_engine.rb +1 -1
- data/app/models/calagator/venue.rb +20 -1
- data/app/models/concerns/calagator/event_filterable.rb +22 -0
- data/app/views/calagator/admin/curations/_form.html.erb +56 -0
- data/app/views/calagator/admin/curations/_index.html.erb +12 -0
- data/app/views/calagator/admin/curations/edit.html.erb +2 -0
- data/app/views/calagator/admin/curations/index.html.erb +21 -0
- data/app/views/calagator/admin/curations/new.html.erb +2 -0
- data/app/views/calagator/admin/index.html.erb +6 -2
- data/app/views/calagator/admin/users/_form.html.erb +28 -0
- data/app/views/calagator/admin/users/edit.html.erb +7 -0
- data/app/views/calagator/admin/users/index.html.erb +38 -0
- data/app/views/calagator/admin/users/invite.html.erb +19 -0
- data/app/views/calagator/admin/users/new.html.erb +3 -0
- data/app/views/calagator/curations/show.html.erb +17 -0
- data/app/views/calagator/events/_index.html.erb +59 -0
- data/app/views/calagator/events/_item.html.erb +10 -3
- data/app/views/calagator/events/_subnav.html.erb +7 -2
- data/app/views/calagator/events/_subnav_custom.html.erb +0 -0
- data/app/views/calagator/events/index.atom.builder +1 -1
- data/app/views/calagator/events/index.html.erb +9 -60
- data/app/views/calagator/events/show.html.erb +5 -3
- data/app/views/calagator/shared/_calendar.html.erb +7 -0
- data/app/views/calagator/shared/_subnav_curations.html.erb +5 -0
- data/app/views/calagator/shared/_subnav_pinned_venues.html.erb +5 -0
- data/app/views/calagator/site/_contact.html.erb +1 -0
- data/app/views/calagator/site/_description.html.erb +2 -2
- data/app/views/calagator/site/about.html.erb +9 -0
- data/app/views/calagator/site/closed_registrations.html.erb +2 -0
- data/app/views/calagator/site/embed.html.erb +16 -0
- data/app/views/calagator/site/index.html.erb +1 -1
- data/app/views/calagator/sources/index.html.erb +1 -1
- data/app/views/calagator/sources/show.html.erb +1 -1
- data/app/views/calagator/venues/_form.html.erb +5 -1
- data/app/views/calagator/venues/_subnav.html.erb +9 -1
- data/app/views/calagator/venues/_subnav_custom.html.erb +0 -0
- data/app/views/calagator/venues/show.html.erb +1 -1
- data/app/views/layouts/calagator/_devise.html.erb +17 -0
- data/app/views/layouts/calagator/_footer.html.erb +3 -1
- data/app/views/layouts/calagator/_head.html.erb +0 -0
- data/app/views/layouts/calagator/_header.html.erb +3 -0
- data/app/views/layouts/calagator/application.html.erb +3 -0
- data/app/views/layouts/calagator/embed.html.erb +15 -0
- data/app/views/paper_trail_manager/changes/_version.html.erb +5 -5
- data/app/views/paper_trail_manager/changes/index.atom.builder +12 -12
- data/bin/{calagator → koalagator} +12 -14
- data/config/importmap.rb +11 -0
- data/config/initializers/admin_user.rb +15 -0
- data/config/initializers/observers.rb +1 -1
- data/config/initializers/paper_trail_manager.rb +1 -1
- data/config/locales/devise.en.yml +65 -0
- data/config/routes.rb +26 -1
- data/db/migrate/20240319042449_devise_create_calagator_users.rb +43 -0
- data/db/migrate/20240319061154_add_admin_flag_to_calagator_user.rb +5 -0
- data/db/migrate/20240320043535_add_name_to_calagator_user.rb +8 -0
- data/db/migrate/20240322035554_add_created_by_to_records.rb +12 -0
- data/db/migrate/20240510051940_create_calagator_curations.rb +15 -0
- data/db/migrate/20240628055300_add_pinned_to_venue.rb +5 -0
- data/db/seeds.rb +49 -0
- data/lib/calagator/decode_html_entities_hack.rb +1 -1
- data/lib/calagator/engine.rb +16 -1
- data/lib/calagator/machine_tag.rb +1 -1
- data/lib/calagator/strip_whitespace.rb +1 -1
- data/lib/calagator/vcalendar.rb +4 -4
- data/lib/calagator/version.rb +4 -1
- data/lib/generators/calagator/install_generator.rb +9 -1
- data/lib/generators/calagator/templates/app/views/devise/registrations/edit.html.erb +48 -0
- data/lib/generators/calagator/templates/app/views/devise/registrations/new.html.erb +29 -0
- data/lib/generators/calagator/templates/config/initializers/01_calagator.rb +34 -6
- data/lib/generators/calagator/templates/config/initializers/04_devise.rb +314 -0
- data/lib/{calagator.rb → koalagator.rb} +15 -3
- data/lib/paper_trail_manager.rb +11 -11
- data/lib/theme_reader.rb +1 -1
- data/rails_template.rb +6 -6
- data/vendor/javascript/@event-calendar--core.js +10 -0
- data/vendor/javascript/@event-calendar--day-grid.js +2 -0
- data/vendor/javascript/@event-calendar--list.js +2 -0
- data/vendor/javascript/ical.js.js +2 -0
- metadata +146 -93
- data/MIT-LICENSE.txt +0 -23
- data/app/models/calagator/event/search_engine/apache_sunspot.rb +0 -106
- data/app/models/calagator/venue/search_engine/apache_sunspot.rb +0 -85
- data/lib/tasks/sunspot_reindex_calagator.rake +0 -20
- data/lib/tasks/sunspot_solr_restart_enhancements.rake +0 -20
- data/lib/wait_for_solr.rb +0 -26
@@ -32,6 +32,9 @@
|
|
32
32
|
<!-- JavaScripts, inserted -->
|
33
33
|
<%= yield :javascript_insert %>
|
34
34
|
|
35
|
+
<!-- Additional head -->
|
36
|
+
<%= render partial: "layouts/calagator/head" %>
|
37
|
+
|
35
38
|
<!-- Auto-discovery, static -->
|
36
39
|
<%= auto_discovery_link_tag(:atom, events_url(:format => 'atom'), :title => 'Atom: All Events' )%>
|
37
40
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6
|
+
<meta name="googlebot" content="noindex,indexifembedded">
|
7
|
+
|
8
|
+
<%= javascript_importmap_tags %>
|
9
|
+
<%= yield :head if content_for?(:head) %>
|
10
|
+
</head>
|
11
|
+
|
12
|
+
<body>
|
13
|
+
<%= yield %>
|
14
|
+
</body>
|
15
|
+
</html>
|
@@ -5,7 +5,7 @@
|
|
5
5
|
<div class='time'> <%= version.created_at.strftime('%H:%M:%S') %> </div>
|
6
6
|
</td>
|
7
7
|
<td class='change_details'>
|
8
|
-
<
|
8
|
+
<span class='change_details_description'>
|
9
9
|
<strong class='event'><%= version.event %></strong>
|
10
10
|
<%= change_item_link(version) %>
|
11
11
|
<% if PaperTrailManager.whodunnit_class && version.whodunnit %>
|
@@ -19,10 +19,10 @@
|
|
19
19
|
by <%= version.whodunnit %>
|
20
20
|
<% end %>
|
21
21
|
<% end %>
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
</span>
|
23
|
+
<% if change_revert_allowed?(version) %>
|
24
|
+
<%= button_to 'Roll back', change_path(version), class: "rollback a-like", form_class: "inline change_details_description", :method => 'put', :data => { :confirm => 'Are you sure?' } %>
|
25
|
+
<% end %>
|
26
26
|
<% if version.event == 'update' or version.event == 'create' %>
|
27
27
|
<% changes = changes_for(version) %>
|
28
28
|
<table class='change_details_table'>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
atom_feed do |feed|
|
4
|
-
feed.title(
|
4
|
+
feed.title("Changes")
|
5
5
|
date = @versions.first.try(:created_at) || Time.zone.at(0)
|
6
6
|
feed.updated(date)
|
7
7
|
|
@@ -12,37 +12,37 @@ atom_feed do |feed|
|
|
12
12
|
changes = changes_for(version)
|
13
13
|
|
14
14
|
user = if PaperTrailManager.whodunnit_class && version.whodunnit
|
15
|
-
|
15
|
+
begin
|
16
16
|
PaperTrailManager.whodunnit_class.find(version.whodunnit)
|
17
|
-
|
18
|
-
|
17
|
+
rescue
|
18
|
+
nil
|
19
19
|
end
|
20
|
-
|
20
|
+
end
|
21
21
|
|
22
|
-
entry.title "#{version.event.upcase} #{version.item_type} «#{change_title_for(version)}» #{user ?
|
22
|
+
entry.title "#{version.event.upcase} #{version.item_type} «#{change_title_for(version)}» #{user ? "by " + user.send(PaperTrailManager.whodunnit_name_method) : ""}"
|
23
23
|
entry.updated version.created_at.utc.xmlschema
|
24
24
|
|
25
25
|
xm = ::Builder::XmlMarkup.new
|
26
26
|
xm.div do
|
27
27
|
xm.p do
|
28
|
-
xm.span <<
|
29
|
-
xm.span << link_to(
|
30
|
-
xm.span <<
|
31
|
-
xm.span << link_to(
|
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
32
|
end
|
33
33
|
xm.table do
|
34
34
|
changes.keys.sort.each do |key|
|
35
35
|
xm.tr do
|
36
36
|
xm.td { xm.b key }
|
37
37
|
xm.td changes[key][:previous].inspect
|
38
|
-
xm.td { xm.span <<
|
38
|
+
xm.td { xm.span << "→" }
|
39
39
|
xm.td changes[key][:current].inspect
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
entry.content(xm.to_s, type:
|
45
|
+
entry.content(xm.to_s, type: "html")
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
@@ -4,31 +4,29 @@
|
|
4
4
|
require_relative '../lib/calagator/version'
|
5
5
|
|
6
6
|
USAGE = <<~END
|
7
|
-
|
8
|
-
|
7
|
+
Koalagator: v#{Calagator::VERSION}
|
8
|
+
koalagator: setup Koalagator in a new or existing Rails application
|
9
9
|
|
10
10
|
Usage:
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
koalagator new APP_PATH [options]
|
12
|
+
koalagator install
|
13
|
+
koalagator --version, -v
|
14
14
|
|
15
|
-
|
15
|
+
koalagator new: generates a new Rails app and install Koalagator into it
|
16
16
|
|
17
17
|
Options:
|
18
|
-
--test_app # Generates an app suitable for use in spec/test_app for
|
18
|
+
--test_app # Generates an app suitable for use in spec/test_app for Koalagator
|
19
19
|
# development and testing
|
20
20
|
|
21
|
-
In the case of `
|
21
|
+
In the case of `koalagator new`, all other options will be passed along
|
22
22
|
to `rails new`; see `rails new --help` for supported options.
|
23
23
|
|
24
|
-
|
24
|
+
koalagator install: install Koalagator into an existing Rails application
|
25
25
|
|
26
26
|
Options:
|
27
27
|
none
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
Prints version info
|
29
|
+
koalagator --version, -v: prints version info
|
32
30
|
END
|
33
31
|
|
34
32
|
TEMPLATE_PATH = File.expand_path('../rails_template.rb', __dir__)
|
@@ -39,9 +37,9 @@ case command
|
|
39
37
|
when /_\d+\.\d+\.\d+_/, 'new'
|
40
38
|
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.
|
41
39
|
when 'install'
|
42
|
-
system "bundle exec rake
|
40
|
+
system "bundle exec rake app:template LOCATION=#{TEMPLATE_PATH}"
|
43
41
|
when '--version', '-v'
|
44
|
-
puts "Calagator v#{Calagator::VERSION}"
|
42
|
+
puts "#{Calagator::NAME} v#{Calagator::VERSION}"
|
45
43
|
else
|
46
44
|
puts USAGE
|
47
45
|
end
|
data/config/importmap.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
def js(path) = Calagator::Engine.root.join("app/javascript").join(path)
|
2
|
+
|
3
|
+
pin "ical.js" # @2.0.1
|
4
|
+
pin "@event-calendar/core", to: "@event-calendar--core.js" # @3.4.0
|
5
|
+
pin "svelte", to: "https://ga.jspm.io/npm:svelte@4.2.18/src/runtime/index.js" # @4.2.18
|
6
|
+
pin "svelte/internal", to: "https://ga.jspm.io/npm:svelte@4.2.18/src/runtime/internal/index.js" # @4.2.18
|
7
|
+
pin "svelte/store", to: "https://ga.jspm.io/npm:svelte@4.2.18/src/runtime/store/index.js" # @4.2.18
|
8
|
+
pin "@event-calendar/list", to: "@event-calendar--list.js" # @3.4.0
|
9
|
+
pin "@event-calendar/day-grid", to: "@event-calendar--day-grid.js" # @3.4.0
|
10
|
+
|
11
|
+
pin_all_from js("calagator/calendar"), under: "calendar", to: "calagator/calendar"
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Calagator
|
2
|
+
Rails.application.config.after_initialize do
|
3
|
+
next unless Calagator.devise_enabled
|
4
|
+
next unless Calagator.admin_username.present? && Calagator.admin_email.present? && Calagator.admin_password.present?
|
5
|
+
begin
|
6
|
+
next if User.admin.any?
|
7
|
+
User.create(
|
8
|
+
name: Calagator.admin_username, email: Calagator.admin_email,
|
9
|
+
password: Calagator.admin_password, password_confirmation: Calagator.admin_password,
|
10
|
+
admin: true
|
11
|
+
)
|
12
|
+
rescue ActiveRecord::StatementInvalid
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
PaperTrailManager.route_helpers = Calagator::Engine.routes.url_helpers
|
4
|
-
PaperTrailManager.base_controller = "Calagator::
|
4
|
+
PaperTrailManager.base_controller = "Calagator::PaperTrailManagerController"
|
5
5
|
PaperTrailManager.item_name_method = :title
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# Additional translations at https://github.com/heartcombo/devise/wiki/I18n
|
2
|
+
|
3
|
+
en:
|
4
|
+
devise:
|
5
|
+
confirmations:
|
6
|
+
confirmed: "Your email address has been successfully confirmed."
|
7
|
+
send_instructions: "You will receive an email with instructions for how to confirm your email address in a few minutes."
|
8
|
+
send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions for how to confirm your email address in a few minutes."
|
9
|
+
failure:
|
10
|
+
already_authenticated: "You are already signed in."
|
11
|
+
inactive: "Your account is not activated yet."
|
12
|
+
invalid: "Invalid %{authentication_keys} or password."
|
13
|
+
locked: "Your account is locked."
|
14
|
+
last_attempt: "You have one more attempt before your account is locked."
|
15
|
+
not_found_in_database: "Invalid %{authentication_keys} or password."
|
16
|
+
timeout: "Your session expired. Please sign in again to continue."
|
17
|
+
unauthenticated: "You need to sign in or sign up before continuing."
|
18
|
+
unconfirmed: "You have to confirm your email address before continuing."
|
19
|
+
mailer:
|
20
|
+
confirmation_instructions:
|
21
|
+
subject: "Confirmation instructions"
|
22
|
+
reset_password_instructions:
|
23
|
+
subject: "Reset password instructions"
|
24
|
+
unlock_instructions:
|
25
|
+
subject: "Unlock instructions"
|
26
|
+
email_changed:
|
27
|
+
subject: "Email Changed"
|
28
|
+
password_change:
|
29
|
+
subject: "Password Changed"
|
30
|
+
omniauth_callbacks:
|
31
|
+
failure: "Could not authenticate you from %{kind} because \"%{reason}\"."
|
32
|
+
success: "Successfully authenticated from %{kind} account."
|
33
|
+
passwords:
|
34
|
+
no_token: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided."
|
35
|
+
send_instructions: "You will receive an email with instructions on how to reset your password in a few minutes."
|
36
|
+
send_paranoid_instructions: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes."
|
37
|
+
updated: "Your password has been changed successfully. You are now signed in."
|
38
|
+
updated_not_active: "Your password has been changed successfully."
|
39
|
+
registrations:
|
40
|
+
destroyed: "Bye! Your account has been successfully cancelled. We hope to see you again soon."
|
41
|
+
signed_up: "Welcome! You have signed up successfully."
|
42
|
+
signed_up_but_inactive: "You have signed up successfully. However, we could not sign you in because your account is not yet activated."
|
43
|
+
signed_up_but_locked: "You have signed up successfully. However, we could not sign you in because your account is locked."
|
44
|
+
signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please follow the link to activate your account."
|
45
|
+
update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and follow the confirmation link to confirm your new email address."
|
46
|
+
updated: "Your account has been updated successfully."
|
47
|
+
updated_but_not_signed_in: "Your account has been updated successfully, but since your password was changed, you need to sign in again."
|
48
|
+
sessions:
|
49
|
+
signed_in: "Signed in successfully."
|
50
|
+
signed_out: "Signed out successfully."
|
51
|
+
already_signed_out: "Signed out successfully."
|
52
|
+
unlocks:
|
53
|
+
send_instructions: "You will receive an email with instructions for how to unlock your account in a few minutes."
|
54
|
+
send_paranoid_instructions: "If your account exists, you will receive an email with instructions for how to unlock it in a few minutes."
|
55
|
+
unlocked: "Your account has been unlocked successfully. Please sign in to continue."
|
56
|
+
errors:
|
57
|
+
messages:
|
58
|
+
already_confirmed: "was already confirmed, please try signing in"
|
59
|
+
confirmation_period_expired: "needs to be confirmed within %{period}, please request a new one"
|
60
|
+
expired: "has expired, please request a new one"
|
61
|
+
not_found: "not found"
|
62
|
+
not_locked: "was not locked"
|
63
|
+
not_saved:
|
64
|
+
one: "1 error prohibited this %{resource} from being saved:"
|
65
|
+
other: "%{count} errors prohibited this %{resource} from being saved:"
|
data/config/routes.rb
CHANGED
@@ -6,6 +6,18 @@ Calagator::Engine.routes.draw do
|
|
6
6
|
|
7
7
|
root "site#index"
|
8
8
|
|
9
|
+
# Change routes if registrations are closed
|
10
|
+
if Calagator.open_registration
|
11
|
+
devise_for :users, class_name: "Calagator::User" if Calagator.devise_enabled
|
12
|
+
else
|
13
|
+
devise_for :users, skip: [:registrations], class_name: "Calagator::User" if Calagator.devise_enabled
|
14
|
+
as :user do
|
15
|
+
get "users/sign_up" => "site#closed_registrations", :as => "new_user_registration"
|
16
|
+
get "users/edit" => "devise/registrations#edit", :as => "edit_user_registration"
|
17
|
+
put "users" => "devise/registrations#update", :as => "user_registration"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
9
21
|
get "omfg" => "site#omfg"
|
10
22
|
get "hello" => "site#hello"
|
11
23
|
|
@@ -19,6 +31,19 @@ Calagator::Engine.routes.draw do
|
|
19
31
|
get "admin/events"
|
20
32
|
post "lock_event" => "admin#lock_event"
|
21
33
|
|
34
|
+
namespace :admin do
|
35
|
+
resources :curations, except: :show
|
36
|
+
if Calagator.devise_enabled
|
37
|
+
resources :users do
|
38
|
+
get :invite, as: :invite
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
get "embed", to: "site#embed", as: "embed"
|
44
|
+
get "curations", to: redirect("/")
|
45
|
+
resources :curations, only: :show
|
46
|
+
|
22
47
|
resources :events do
|
23
48
|
collection do
|
24
49
|
post :squash_many_duplicates
|
@@ -59,4 +84,4 @@ Calagator::Engine.routes.draw do
|
|
59
84
|
|
60
85
|
get "/index" => "site#index"
|
61
86
|
get "/index.:format" => "site#index"
|
62
|
-
end
|
87
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class DeviseCreateCalagatorUsers < ActiveRecord::Migration[7.1]
|
4
|
+
def change
|
5
|
+
create_table :calagator_users do |t|
|
6
|
+
## Database authenticatable
|
7
|
+
t.string :email, null: false, default: ""
|
8
|
+
t.string :encrypted_password, null: false, default: ""
|
9
|
+
|
10
|
+
## Recoverable
|
11
|
+
t.string :reset_password_token
|
12
|
+
t.datetime :reset_password_sent_at
|
13
|
+
|
14
|
+
## Rememberable
|
15
|
+
t.datetime :remember_created_at
|
16
|
+
|
17
|
+
## Trackable
|
18
|
+
# t.integer :sign_in_count, default: 0, null: false
|
19
|
+
# t.datetime :current_sign_in_at
|
20
|
+
# t.datetime :last_sign_in_at
|
21
|
+
# t.string :current_sign_in_ip
|
22
|
+
# t.string :last_sign_in_ip
|
23
|
+
|
24
|
+
## Confirmable
|
25
|
+
# t.string :confirmation_token
|
26
|
+
# t.datetime :confirmed_at
|
27
|
+
# t.datetime :confirmation_sent_at
|
28
|
+
# t.string :unconfirmed_email # Only if using reconfirmable
|
29
|
+
|
30
|
+
## Lockable
|
31
|
+
# t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
|
32
|
+
# t.string :unlock_token # Only if unlock strategy is :email or :both
|
33
|
+
# t.datetime :locked_at
|
34
|
+
|
35
|
+
t.timestamps null: false
|
36
|
+
end
|
37
|
+
|
38
|
+
add_index :calagator_users, :email, unique: true
|
39
|
+
add_index :calagator_users, :reset_password_token, unique: true
|
40
|
+
# add_index :calagator_users, :confirmation_token, unique: true
|
41
|
+
# add_index :calagator_users, :unlock_token, unique: true
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class AddCreatedByToRecords < ActiveRecord::Migration[7.1]
|
2
|
+
def change
|
3
|
+
add_column :events, :created_by_name, :string
|
4
|
+
add_reference :events, :created_by, foreign_key: {to_table: :calagator_users}
|
5
|
+
|
6
|
+
add_column :venues, :created_by_name, :string
|
7
|
+
add_reference :venues, :created_by, foreign_key: {to_table: :calagator_users}
|
8
|
+
|
9
|
+
add_column :sources, :created_by_name, :string
|
10
|
+
add_reference :sources, :created_by, foreign_key: {to_table: :calagator_users}
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class CreateCalagatorCurations < ActiveRecord::Migration[7.1]
|
2
|
+
def change
|
3
|
+
create_table :calagator_curations do |t|
|
4
|
+
t.string :name, null: false
|
5
|
+
t.string :display_name
|
6
|
+
t.string :description
|
7
|
+
t.integer :priority, null: false, default: 0
|
8
|
+
t.boolean :unlisted, null: false, default: false
|
9
|
+
|
10
|
+
t.timestamps
|
11
|
+
end
|
12
|
+
|
13
|
+
add_index :calagator_curations, :name, unique: true
|
14
|
+
end
|
15
|
+
end
|
data/db/seeds.rb
CHANGED
@@ -9,6 +9,20 @@ rescue LoadError
|
|
9
9
|
exit 1
|
10
10
|
end
|
11
11
|
|
12
|
+
TAGS = [
|
13
|
+
"gardening",
|
14
|
+
"birdwatching",
|
15
|
+
"camping",
|
16
|
+
"hiking",
|
17
|
+
"nature",
|
18
|
+
"public lecture",
|
19
|
+
"book launch"
|
20
|
+
].freeze
|
21
|
+
|
22
|
+
def random_tags
|
23
|
+
TAGS.sample(rand(2..4)).join(", ")
|
24
|
+
end
|
25
|
+
|
12
26
|
FactoryBot.define do
|
13
27
|
factory :seed_venue, class: Calagator::Venue do
|
14
28
|
title { Faker::Company.name }
|
@@ -54,6 +68,8 @@ FactoryBot.define do
|
|
54
68
|
created_at { start_time - 1.day }
|
55
69
|
end_time { start_time + 3.hours }
|
56
70
|
|
71
|
+
tag_list { random_tags }
|
72
|
+
|
57
73
|
trait :with_venue do
|
58
74
|
before(:create) do |seed_event|
|
59
75
|
venue = create(:seed_venue)
|
@@ -63,6 +79,39 @@ FactoryBot.define do
|
|
63
79
|
end
|
64
80
|
end
|
65
81
|
|
82
|
+
Calagator::Curation.create(
|
83
|
+
description: "events related to being around the home",
|
84
|
+
display_name: "at home",
|
85
|
+
name: "at_home",
|
86
|
+
priority: 0,
|
87
|
+
block_list: "",
|
88
|
+
require_list: "gardening, nature",
|
89
|
+
deny_list: "",
|
90
|
+
allow_list: ""
|
91
|
+
)
|
92
|
+
|
93
|
+
Calagator::Curation.create(
|
94
|
+
description: "events related to being outdoors",
|
95
|
+
display_name: "outdoors",
|
96
|
+
name: "outdoors",
|
97
|
+
priority: 1,
|
98
|
+
block_list: "",
|
99
|
+
require_list: "birdwatching, hiking, camping, nature",
|
100
|
+
deny_list: "",
|
101
|
+
allow_list: ""
|
102
|
+
)
|
103
|
+
|
104
|
+
Calagator::Curation.create(
|
105
|
+
description: "events related to civic engagement",
|
106
|
+
display_name: "civic engagement",
|
107
|
+
name: "civic_engagement",
|
108
|
+
priority: 2,
|
109
|
+
block_list: "",
|
110
|
+
require_list: "public lecture, book launch",
|
111
|
+
deny_list: "",
|
112
|
+
allow_list: ""
|
113
|
+
)
|
114
|
+
|
66
115
|
puts "Seeding database with sample data..."
|
67
116
|
FactoryBot.create_list(:seed_venue, 25, :with_events)
|
68
117
|
FactoryBot.create_list(:seed_venue, 25)
|
@@ -25,7 +25,7 @@ module Calagator
|
|
25
25
|
attributes.each do |field, value|
|
26
26
|
decoded_content = HTMLEntities.new.decode(value)
|
27
27
|
if decoded_content.present? && decoded_content != value
|
28
|
-
send("#{field}=", decoded_content)
|
28
|
+
send(:"#{field}=", decoded_content)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
data/lib/calagator/engine.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "rack/contrib/jsonp"
|
4
|
-
require
|
4
|
+
require "sprockets/railtie"
|
5
|
+
require "importmap-rails"
|
5
6
|
|
6
7
|
module Calagator
|
7
8
|
class Engine < ::Rails::Engine
|
@@ -9,9 +10,18 @@ module Calagator
|
|
9
10
|
|
10
11
|
config.middleware.use Rack::JSONP
|
11
12
|
|
13
|
+
# https://stackoverflow.com/questions/69635552/how-to-set-up-importmap-rails-in-rails-7-engine
|
14
|
+
initializer "calagator.importmap", before: "importmap" do |app|
|
15
|
+
app.config.importmap.paths << root.join("config/importmap.rb")
|
16
|
+
app.config.importmap.cache_sweepers +=
|
17
|
+
["vendor/javascript", "app/javascript"].map { |str| root.join(str) }
|
18
|
+
end
|
19
|
+
|
20
|
+
config.assets.paths += %w[app/javascript vendor/javascript].map { |path| root.join(path) }
|
12
21
|
config.assets.precompile += %w[
|
13
22
|
*.png
|
14
23
|
*.gif
|
24
|
+
*.js
|
15
25
|
calagator/errors.css
|
16
26
|
leaflet.js
|
17
27
|
leaflet_google_layer.js
|
@@ -21,6 +31,11 @@ module Calagator
|
|
21
31
|
leaflet
|
22
32
|
]
|
23
33
|
|
34
|
+
config.to_prepare do
|
35
|
+
# Include custom helpers from parent app
|
36
|
+
Calagator::ApplicationController.helper Rails.application.helpers
|
37
|
+
end
|
38
|
+
|
24
39
|
config.after_initialize do
|
25
40
|
Calagator.configure_search_engine
|
26
41
|
end
|
@@ -65,7 +65,7 @@ module Calagator
|
|
65
65
|
private
|
66
66
|
|
67
67
|
# Regular expression for parsing machine tags
|
68
|
-
MACHINE_TAG_PATTERN = /(?<namespace>[^:]+):(?<predicate>[^=]+)=(?<value>.+)
|
68
|
+
MACHINE_TAG_PATTERN = /(?<namespace>[^:]+):(?<predicate>[^=]+)=(?<value>.+)/
|
69
69
|
|
70
70
|
def matches
|
71
71
|
name.match(MACHINE_TAG_PATTERN) || {}
|
@@ -9,7 +9,7 @@ module StripWhitespace
|
|
9
9
|
def strip_whitespace!(*fields)
|
10
10
|
before_validation do |record|
|
11
11
|
fields.each do |field|
|
12
|
-
setter = "#{field}="
|
12
|
+
setter = :"#{field}="
|
13
13
|
value = record.send(field.to_sym)
|
14
14
|
if value.respond_to?(:strip) && record.respond_to?(setter)
|
15
15
|
record.send(setter, value.strip)
|
data/lib/calagator/vcalendar.rb
CHANGED
@@ -4,9 +4,9 @@ require "ri_cal"
|
|
4
4
|
|
5
5
|
module Calagator
|
6
6
|
class VCalendar < Struct.new(:ri_cal_calendar)
|
7
|
-
VENUE_CONTENT_RE = /^BEGIN:VVENUE$.*?^END:VVENUE$/m
|
7
|
+
VENUE_CONTENT_RE = /^BEGIN:VVENUE$.*?^END:VVENUE$/m
|
8
8
|
def self.parse(raw_ical)
|
9
|
-
raw_ical = raw_ical.gsub(
|
9
|
+
raw_ical = raw_ical.gsub("\r\n", "\n") # normalize line endings
|
10
10
|
raw_ical = raw_ical.gsub(/;TZID=GMT:(.*)/, ':\1Z') # normalize timezones
|
11
11
|
ri_cal = RiCal.parse_string(raw_ical)
|
12
12
|
ri_cal.map do |ri_cal_calendar|
|
@@ -34,7 +34,7 @@ module Calagator
|
|
34
34
|
end
|
35
35
|
|
36
36
|
class VEvent < Struct.new(:ri_cal_event, :vvenues)
|
37
|
-
VCARD_LINES_RE = /^(?<key>[^;]+?)(?<qualifier>;[^:]*?)?:(?<value>.*)
|
37
|
+
VCARD_LINES_RE = /^(?<key>[^;]+?)(?<qualifier>;[^:]*?)?:(?<value>.*)$/
|
38
38
|
def old?
|
39
39
|
cutoff = Time.now.in_time_zone.yesterday
|
40
40
|
(ri_cal_event.dtend || ri_cal_event.dtstart).to_time < cutoff
|
@@ -76,7 +76,7 @@ module Calagator
|
|
76
76
|
end
|
77
77
|
|
78
78
|
class VVenue < Struct.new(:raw_ical_venue)
|
79
|
-
VCARD_LINES_RE = /^(?<key>[^;]+?)(?<qualifier>;[^:]*?)?:(?<value>.*)
|
79
|
+
VCARD_LINES_RE = /^(?<key>[^;]+?)(?<qualifier>;[^:]*?)?:(?<value>.*)$/
|
80
80
|
def uid
|
81
81
|
raw_ical_venue.match(/^UID:(?<uid>.+)$/)[:uid]
|
82
82
|
end
|
data/lib/calagator/version.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "fileutils"
|
4
|
+
|
3
5
|
module Calagator
|
4
6
|
class InstallGenerator < Rails::Generators::Base
|
5
7
|
source_root File.expand_path("templates", __dir__)
|
@@ -12,6 +14,7 @@ module Calagator
|
|
12
14
|
add_initializers
|
13
15
|
add_javascripts
|
14
16
|
add_stylesheets
|
17
|
+
add_devise_views
|
15
18
|
add_assets
|
16
19
|
add_seeds
|
17
20
|
run "rm -f public/index.html"
|
@@ -31,7 +34,7 @@ module Calagator
|
|
31
34
|
# PaperTrail needs Time and BigDecimal as supported YAML classes
|
32
35
|
def add_yaml_config
|
33
36
|
inject_into_file "config/application.rb",
|
34
|
-
"\s\s\s\sconfig.active_record.yaml_column_permitted_classes = [Time, BigDecimal]",
|
37
|
+
"\s\s\s\sconfig.active_record.yaml_column_permitted_classes = [ActiveSupport::TimeWithZone, ActiveSupport::TimeZone, Time, BigDecimal]",
|
35
38
|
after: /config.load_defaults.+\n/
|
36
39
|
end
|
37
40
|
|
@@ -39,6 +42,7 @@ module Calagator
|
|
39
42
|
initializer "01_calagator.rb", File.read(File.expand_path("templates/config/initializers/01_calagator.rb", __dir__))
|
40
43
|
initializer "02_geokit.rb", File.read(File.expand_path("templates/config/initializers/02_geokit.rb", __dir__))
|
41
44
|
initializer "03_recaptcha.rb", File.read(File.expand_path("templates/config/initializers/03_recaptcha.rb", __dir__))
|
45
|
+
initializer "04_devise.rb", File.read(File.expand_path("templates/config/initializers/04_devise.rb", __dir__))
|
42
46
|
end
|
43
47
|
|
44
48
|
def add_javascripts
|
@@ -59,6 +63,10 @@ module Calagator
|
|
59
63
|
run "cp #{File.expand_path("../../../app/assets/images/site-icon.png", __dir__)} app/assets/images/"
|
60
64
|
end
|
61
65
|
|
66
|
+
def add_devise_views
|
67
|
+
FileUtils.cp_r(File.expand_path("./templates/app/views/devise/", __dir__), "app/views/")
|
68
|
+
end
|
69
|
+
|
62
70
|
def add_seeds
|
63
71
|
append_file "db/seeds.rb", "Calagator::Engine.load_seed"
|
64
72
|
end
|