koalagator 4.1.0 → 5.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.
Files changed (134) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.md +661 -0
  3. data/README.md +74 -21
  4. data/app/assets/config/calagator/manifest.js +5 -1
  5. data/app/assets/images/external_sites/mastodon.png +0 -0
  6. data/app/assets/images/nav_marker.png +0 -0
  7. data/app/assets/javascripts/calagator/forms.js +7 -0
  8. data/app/assets/stylesheets/calagator/custom/calendar.css +137 -0
  9. data/app/assets/stylesheets/calagator/errors.css +2 -4
  10. data/app/assets/stylesheets/calagator/forms.scss +5 -0
  11. data/app/assets/stylesheets/calagator/layout.scss +31 -9
  12. data/app/assets/stylesheets/calagator/typography.scss +39 -9
  13. data/app/assets/stylesheets/calagator/utils.scss +44 -0
  14. data/app/controllers/calagator/admin/curations_controller.rb +62 -0
  15. data/app/controllers/calagator/admin/users_controller.rb +79 -0
  16. data/app/controllers/calagator/application_controller.rb +29 -5
  17. data/app/controllers/calagator/curations_controller.rb +32 -0
  18. data/app/controllers/calagator/events_controller.rb +6 -0
  19. data/app/controllers/calagator/paper_trail_manager_controller.rb +5 -0
  20. data/app/controllers/calagator/passwords_controller.rb +4 -0
  21. data/app/controllers/calagator/registrations_controller.rb +5 -0
  22. data/app/controllers/calagator/sessions_controller.rb +4 -0
  23. data/app/controllers/calagator/site_controller.rb +10 -0
  24. data/app/controllers/calagator/sources_controller.rb +2 -0
  25. data/app/controllers/calagator/venues_controller.rb +5 -1
  26. data/app/controllers/calagator/versions_controller.rb +1 -1
  27. data/app/controllers/paper_trail_manager/changes_controller.rb +16 -16
  28. data/app/helpers/calagator/application_helper.rb +32 -3
  29. data/app/helpers/calagator/time_range_helper.rb +1 -1
  30. data/app/helpers/paper_trail_manager/changes_helper.rb +7 -7
  31. data/app/javascript/calagator/calendar/calendar.js +82 -0
  32. data/app/javascript/calagator/calendar/event.js +94 -0
  33. data/app/javascript/calagator/calendar/lib/components.js +120 -0
  34. data/app/javascript/calagator/calendar/lib/utils.js +67 -0
  35. data/app/models/calagator/curation.rb +32 -0
  36. data/app/models/calagator/event/browse.rb +3 -2
  37. data/app/models/calagator/event/cloner.rb +1 -1
  38. data/app/models/calagator/event/ical_renderer.rb +1 -1
  39. data/app/models/calagator/event/overview.rb +3 -1
  40. data/app/models/calagator/event/saver.rb +6 -1
  41. data/app/models/calagator/event/search.rb +1 -1
  42. data/app/models/calagator/event/search_engine.rb +1 -1
  43. data/app/models/calagator/event.rb +22 -5
  44. data/app/models/calagator/source/parser/hcal.rb +1 -1
  45. data/app/models/calagator/source/parser.rb +3 -3
  46. data/app/models/calagator/source.rb +23 -6
  47. data/app/models/calagator/user.rb +50 -0
  48. data/app/models/calagator/venue/geocoder.rb +1 -1
  49. data/app/models/calagator/venue/search.rb +1 -1
  50. data/app/models/calagator/venue/search_engine.rb +1 -1
  51. data/app/models/calagator/venue.rb +20 -1
  52. data/app/models/concerns/calagator/event_filterable.rb +22 -0
  53. data/app/views/calagator/admin/curations/_form.html.erb +56 -0
  54. data/app/views/calagator/admin/curations/_index.html.erb +12 -0
  55. data/app/views/calagator/admin/curations/edit.html.erb +2 -0
  56. data/app/views/calagator/admin/curations/index.html.erb +21 -0
  57. data/app/views/calagator/admin/curations/new.html.erb +2 -0
  58. data/app/views/calagator/admin/index.html.erb +6 -2
  59. data/app/views/calagator/admin/users/_form.html.erb +28 -0
  60. data/app/views/calagator/admin/users/edit.html.erb +7 -0
  61. data/app/views/calagator/admin/users/index.html.erb +38 -0
  62. data/app/views/calagator/admin/users/invite.html.erb +19 -0
  63. data/app/views/calagator/admin/users/new.html.erb +3 -0
  64. data/app/views/calagator/curations/show.html.erb +17 -0
  65. data/app/views/calagator/events/_index.html.erb +59 -0
  66. data/app/views/calagator/events/_item.html.erb +10 -3
  67. data/app/views/calagator/events/_subnav.html.erb +7 -2
  68. data/app/views/calagator/events/_subnav_custom.html.erb +0 -0
  69. data/app/views/calagator/events/index.atom.builder +1 -1
  70. data/app/views/calagator/events/index.html.erb +9 -60
  71. data/app/views/calagator/events/show.html.erb +5 -3
  72. data/app/views/calagator/shared/_calendar.html.erb +7 -0
  73. data/app/views/calagator/shared/_subnav_curations.html.erb +5 -0
  74. data/app/views/calagator/shared/_subnav_pinned_venues.html.erb +5 -0
  75. data/app/views/calagator/site/_contact.html.erb +1 -0
  76. data/app/views/calagator/site/_description.html.erb +2 -2
  77. data/app/views/calagator/site/about.html.erb +9 -0
  78. data/app/views/calagator/site/closed_registrations.html.erb +2 -0
  79. data/app/views/calagator/site/embed.html.erb +16 -0
  80. data/app/views/calagator/site/index.html.erb +1 -1
  81. data/app/views/calagator/sources/index.html.erb +1 -1
  82. data/app/views/calagator/sources/show.html.erb +1 -1
  83. data/app/views/calagator/venues/_form.html.erb +5 -1
  84. data/app/views/calagator/venues/_subnav.html.erb +9 -1
  85. data/app/views/calagator/venues/_subnav_custom.html.erb +0 -0
  86. data/app/views/calagator/venues/show.html.erb +1 -1
  87. data/app/views/layouts/calagator/_devise.html.erb +17 -0
  88. data/app/views/layouts/calagator/_footer.html.erb +3 -1
  89. data/app/views/layouts/calagator/_head.html.erb +0 -0
  90. data/app/views/layouts/calagator/_header.html.erb +3 -0
  91. data/app/views/layouts/calagator/application.html.erb +3 -0
  92. data/app/views/layouts/calagator/embed.html.erb +15 -0
  93. data/app/views/paper_trail_manager/changes/_version.html.erb +5 -5
  94. data/app/views/paper_trail_manager/changes/index.atom.builder +12 -12
  95. data/bin/{calagator → koalagator} +12 -14
  96. data/config/importmap.rb +11 -0
  97. data/config/initializers/admin_user.rb +15 -0
  98. data/config/initializers/observers.rb +1 -1
  99. data/config/initializers/paper_trail_manager.rb +1 -1
  100. data/config/locales/devise.en.yml +65 -0
  101. data/config/routes.rb +26 -1
  102. data/db/migrate/20240319042449_devise_create_calagator_users.rb +43 -0
  103. data/db/migrate/20240319061154_add_admin_flag_to_calagator_user.rb +5 -0
  104. data/db/migrate/20240320043535_add_name_to_calagator_user.rb +8 -0
  105. data/db/migrate/20240322035554_add_created_by_to_records.rb +12 -0
  106. data/db/migrate/20240510051940_create_calagator_curations.rb +15 -0
  107. data/db/migrate/20240628055300_add_pinned_to_venue.rb +5 -0
  108. data/db/seeds.rb +49 -0
  109. data/lib/calagator/decode_html_entities_hack.rb +1 -1
  110. data/lib/calagator/engine.rb +16 -1
  111. data/lib/calagator/machine_tag.rb +1 -1
  112. data/lib/calagator/strip_whitespace.rb +1 -1
  113. data/lib/calagator/vcalendar.rb +4 -4
  114. data/lib/calagator/version.rb +4 -1
  115. data/lib/generators/calagator/install_generator.rb +9 -1
  116. data/lib/generators/calagator/templates/app/views/devise/registrations/edit.html.erb +48 -0
  117. data/lib/generators/calagator/templates/app/views/devise/registrations/new.html.erb +29 -0
  118. data/lib/generators/calagator/templates/config/initializers/01_calagator.rb +34 -6
  119. data/lib/generators/calagator/templates/config/initializers/04_devise.rb +314 -0
  120. data/lib/{calagator.rb → koalagator.rb} +15 -3
  121. data/lib/paper_trail_manager.rb +11 -11
  122. data/lib/theme_reader.rb +1 -1
  123. data/rails_template.rb +6 -6
  124. data/vendor/javascript/@event-calendar--core.js +10 -0
  125. data/vendor/javascript/@event-calendar--day-grid.js +2 -0
  126. data/vendor/javascript/@event-calendar--list.js +2 -0
  127. data/vendor/javascript/ical.js.js +2 -0
  128. metadata +145 -92
  129. data/MIT-LICENSE.txt +0 -23
  130. data/app/models/calagator/event/search_engine/apache_sunspot.rb +0 -106
  131. data/app/models/calagator/venue/search_engine/apache_sunspot.rb +0 -85
  132. data/lib/tasks/sunspot_reindex_calagator.rake +0 -20
  133. data/lib/tasks/sunspot_solr_restart_enhancements.rake +0 -20
  134. data/lib/wait_for_solr.rb +0 -26
@@ -1,106 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Calagator
4
- class Event < Calagator::ApplicationRecord
5
- class SearchEngine
6
- class ApacheSunspot < Struct.new(:query, :opts)
7
- # Return an Array of non-duplicate Event instances matching the search +query+..
8
- #
9
- # Options:
10
- # * :order => How to order the entries? Defaults to :score. Permitted values:
11
- # * :score => Sort with most relevant matches first
12
- # * :date => Sort by date
13
- # * :name => Sort by event title
14
- # * :title => same as :name
15
- # * :venue => Sort by venue title
16
- # * :limit => Maximum number of entries to return. Defaults to 50.
17
- # * :skip_old => Return old entries? Defaults to false.
18
- def self.search(*args)
19
- new(*args).all
20
- end
21
-
22
- def self.score?
23
- true
24
- end
25
-
26
- def self.configure
27
- Event.searchable do
28
- text :title, default_boost: 3
29
- string :title
30
-
31
- text :description
32
-
33
- text :tag_list, default_boost: 3
34
-
35
- text :url
36
-
37
- time :start_time
38
- time :end_time
39
-
40
- text(:venue_title) { venue.try(:title) }
41
- string(:venue_title) { venue.try(:title) }
42
-
43
- boolean(:duplicate) { duplicate? }
44
- end
45
- end
46
-
47
- def self.configured?
48
- Event.respond_to?(:solr_search)
49
- end
50
-
51
- def initialize(*args)
52
- super
53
- self.class.configure unless self.class.configured?
54
- end
55
-
56
- def all
57
- current_events + past_events
58
- end
59
-
60
- private
61
-
62
- def current_events
63
- search(true)
64
- end
65
-
66
- def past_events
67
- skip_old ? [] : search(false)
68
- end
69
-
70
- def search(current)
71
- Event.solr_search do
72
- keywords query
73
- order_by(*order)
74
- order_by :start_time, :desc
75
- with :duplicate, false
76
- data_accessor_for(Event).include = [:venue]
77
-
78
- method = current ? :greater_than_or_equal_to : :less_than
79
- with(:start_time).send(method, Date.yesterday.to_time)
80
- end.results.take(limit)
81
- end
82
-
83
- def order
84
- case opts[:order].try(:to_sym)
85
- when :date
86
- %i[start_time desc]
87
- when :venue, :location
88
- %i[venue_title asc]
89
- when :name, :title
90
- %i[title asc]
91
- else
92
- %i[score desc]
93
- end
94
- end
95
-
96
- def skip_old
97
- opts[:skip_old] == true
98
- end
99
-
100
- def limit
101
- opts[:limit] || 50
102
- end
103
- end
104
- end
105
- end
106
- end
@@ -1,85 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Calagator
4
- class Venue < Calagator::ApplicationRecord
5
- class SearchEngine
6
- class ApacheSunspot < Struct.new(:query, :opts)
7
- # Return an Array of non-duplicate Venue instances matching the search +query+..
8
- #
9
- # Options:
10
- # * :order => How to order the entries? Defaults to :score. Permitted values:
11
- # * :score => Sort with most relevant matches first
12
- # * :name => Sort by event title
13
- # * :title => same as :name
14
- # * :limit => Maximum number of entries to return. Defaults to 50.
15
- # * :wifi => Require wifi
16
- # * :include_closed => Include closed venues? Defaults to false.
17
- def self.search(*args)
18
- new(*args).search
19
- end
20
-
21
- def self.configure
22
- Venue.searchable do
23
- text :title, default_boost: 3
24
- string :title
25
- text :description
26
- text :address
27
- text :street_address
28
- text :postal_code
29
- text :locality
30
- text :region
31
- text :tag_list, default_boost: 3
32
- text :url
33
- boolean :closed
34
- boolean :wifi
35
- boolean :duplicate_for_solr do |record|
36
- record.duplicate_of_id.present?
37
- end
38
- end
39
- end
40
-
41
- def self.configured?
42
- Venue.respond_to?(:solr_search)
43
- end
44
-
45
- def initialize(*args)
46
- super
47
- self.class.configure unless self.class.configured?
48
- end
49
-
50
- def search
51
- Venue.solr_search do
52
- keywords query
53
- order_by(*order)
54
- with :duplicate_for_solr, false
55
- with :wifi, true if wifi
56
- with :closed, false unless include_closed
57
- end.results.take(limit)
58
- end
59
-
60
- private
61
-
62
- def order
63
- case opts[:order].try(:to_sym)
64
- when :name, :title
65
- %i[title asc]
66
- else
67
- %i[score desc]
68
- end
69
- end
70
-
71
- def wifi
72
- opts[:wifi]
73
- end
74
-
75
- def include_closed
76
- opts[:include_closed]
77
- end
78
-
79
- def limit
80
- opts[:limit] || 50
81
- end
82
- end
83
- end
84
- end
85
- end
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- desc "Reindex Calagator models with Sunspot"
4
- task "sunspot:reindex:calagator" do
5
- # Silence warnings about already-initialized constants caused by
6
- # sunspot-rails' aggressive eager loading of all engine files.
7
- original_verbosity = $VERBOSE
8
- $VERBOSE = nil
9
-
10
- puts "Reindexing Venues…"
11
- Rake.application["sunspot:solr:reindex"].invoke(500, "Calagator::Venue")
12
-
13
- Rake.application["sunspot:solr:reindex"].reenable
14
- Rake.application["sunspot:reindex"].reenable
15
-
16
- puts "Reindexing Events…"
17
- Rake.application["sunspot:solr:reindex"].invoke(500, "Calagator::Event")
18
-
19
- $VERBOSE = original_verbosity
20
- end
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "wait_for_solr"
4
-
5
- task "sunspot:solr:start_with_waiting" => :environment do
6
- port = Sunspot::Rails.configuration.port
7
-
8
- next puts "Solr already running" if WaitForSolr.running_on?(port)
9
-
10
- puts "Starting Solr ..."
11
-
12
- # is namespaced within app when invoked from the engine repo
13
- task = Rake::Task.task_defined?("app:sunspot:solr:start") ? "app:sunspot:solr:start" : "sunspot:solr:start"
14
- Rake.application.invoke_task(task)
15
-
16
- print "Waiting for Solr "
17
- WaitForSolr.on(port, 30) { print "." }
18
-
19
- puts " done"
20
- end
data/lib/wait_for_solr.rb DELETED
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "timeout"
4
-
5
- class WaitForSolr < Struct.new(:port, :timeout)
6
- def self.on(port, timeout, &block)
7
- new(port, timeout).wait(&block)
8
- end
9
-
10
- def self.running_on?(port)
11
- new(port).responding?
12
- end
13
-
14
- def wait
15
- Timeout.timeout timeout do
16
- until responding?
17
- yield
18
- sleep 1
19
- end
20
- end
21
- end
22
-
23
- def responding?
24
- system %(curl -o /dev/null "http://localhost:#{port}/solr" > /dev/null 2>&1)
25
- end
26
- end