shiplog 0.2.0 → 0.3.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.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +74 -0
  3. data/README.md +172 -7
  4. data/app/controllers/shiplog/admin/area_detections_controller.rb +15 -0
  5. data/app/controllers/shiplog/admin/area_translations_controller.rb +19 -0
  6. data/app/controllers/shiplog/admin/areas/merges_controller.rb +19 -0
  7. data/app/controllers/shiplog/admin/areas/moves_controller.rb +13 -0
  8. data/app/controllers/shiplog/admin/areas_controller.rb +48 -0
  9. data/app/controllers/shiplog/admin/entries/images/moves_controller.rb +20 -0
  10. data/app/controllers/shiplog/admin/entries/images_controller.rb +76 -0
  11. data/app/controllers/shiplog/admin/entries/translations/retranslations_controller.rb +23 -0
  12. data/app/controllers/shiplog/admin/entries/translations_controller.rb +35 -0
  13. data/app/controllers/shiplog/admin/entries_controller.rb +9 -3
  14. data/app/controllers/shiplog/changelog_entries_controller.rb +26 -0
  15. data/app/controllers/shiplog/changelog_feeds_controller.rb +19 -0
  16. data/app/controllers/shiplog/changelogs_controller.rb +21 -5
  17. data/app/controllers/shiplog/public_controller.rb +57 -0
  18. data/app/controllers/shiplog/roadmaps_controller.rb +3 -1
  19. data/app/frontend/shiplog/admin.css +9 -0
  20. data/app/frontend/shiplog/shiplog.css +47 -2
  21. data/app/helpers/shiplog/admin/entries_helper.rb +15 -0
  22. data/app/helpers/shiplog/head_helper.rb +95 -0
  23. data/app/helpers/shiplog/head_tags_helper.rb +24 -0
  24. data/app/helpers/shiplog/permalink_helper.rb +149 -0
  25. data/app/helpers/shiplog/roadmap_helper.rb +9 -0
  26. data/app/helpers/shiplog/structured_data_helper.rb +74 -0
  27. data/app/helpers/shiplog/unseen_helper.rb +9 -0
  28. data/app/jobs/shiplog/detect_areas_job.rb +18 -0
  29. data/app/jobs/shiplog/rewrite_entry_job.rb +4 -1
  30. data/app/jobs/shiplog/translate_area_job.rb +25 -0
  31. data/app/jobs/shiplog/translate_entry_job.rb +25 -0
  32. data/app/models/shiplog/area.rb +156 -0
  33. data/app/models/shiplog/area_detector.rb +146 -0
  34. data/app/models/shiplog/area_translator.rb +77 -0
  35. data/app/models/shiplog/entry/images.rb +127 -0
  36. data/app/models/shiplog/entry.rb +204 -5
  37. data/app/models/shiplog/entry_translation.rb +15 -0
  38. data/app/models/shiplog/image_fetcher/downloader.rb +98 -0
  39. data/app/models/shiplog/image_fetcher/sources.rb +41 -0
  40. data/app/models/shiplog/image_fetcher.rb +72 -0
  41. data/app/models/shiplog/image_type.rb +111 -0
  42. data/app/models/shiplog/rewriter/prompt.rb +31 -7
  43. data/app/models/shiplog/rewriter.rb +41 -23
  44. data/app/models/shiplog/setting.rb +19 -0
  45. data/app/models/shiplog/translator/prompt.rb +40 -0
  46. data/app/models/shiplog/translator.rb +99 -0
  47. data/app/views/layouts/shiplog/application.html.erb +1 -1
  48. data/app/views/shiplog/_empty.html.erb +1 -1
  49. data/app/views/shiplog/_head_tags.html.erb +5 -0
  50. data/app/views/shiplog/_pagination.html.erb +3 -3
  51. data/app/views/shiplog/admin/_nav.html.erb +2 -1
  52. data/app/views/shiplog/admin/areas/index.html.erb +78 -0
  53. data/app/views/shiplog/admin/entries/_entry_row.html.erb +3 -0
  54. data/app/views/shiplog/admin/entries/_images.html.erb +41 -0
  55. data/app/views/shiplog/admin/entries/_translations.html.erb +42 -0
  56. data/app/views/shiplog/admin/entries/edit.html.erb +12 -0
  57. data/app/views/shiplog/changelog_entries/show.html.erb +23 -0
  58. data/app/views/shiplog/changelog_feeds/show.atom.builder +24 -0
  59. data/app/views/shiplog/changelogs/_areas.html.erb +8 -0
  60. data/app/views/shiplog/changelogs/_entry.html.erb +2 -5
  61. data/app/views/shiplog/changelogs/_entry_content.html.erb +10 -0
  62. data/app/views/shiplog/changelogs/_search.html.erb +4 -2
  63. data/app/views/shiplog/changelogs/show.html.erb +13 -7
  64. data/app/views/shiplog/head/_feed.html.erb +1 -0
  65. data/app/views/shiplog/head/_meta.html.erb +3 -0
  66. data/app/views/shiplog/head/_open_graph.html.erb +6 -0
  67. data/app/views/shiplog/head/_structured_data.html.erb +1 -0
  68. data/app/views/shiplog/roadmaps/_card.html.erb +2 -2
  69. data/app/views/shiplog/roadmaps/_column.html.erb +3 -3
  70. data/app/views/shiplog/roadmaps/_shipped.html.erb +1 -1
  71. data/app/views/shiplog/roadmaps/show.html.erb +5 -2
  72. data/config/admin_routes.rb +16 -0
  73. data/config/locales/en.yml +85 -0
  74. data/config/locales/es.yml +223 -0
  75. data/config/routes.rb +5 -0
  76. data/db/migrate/20261027000002_shiplog_0_3_0.rb +105 -0
  77. data/lib/generators/shiplog/install/install_generator.rb +10 -1
  78. data/lib/generators/shiplog/install/templates/initializer.rb.tt +58 -1
  79. data/lib/shiplog/classes.rb +10 -1
  80. data/lib/shiplog/configuration.rb +105 -3
  81. data/lib/shiplog/engine.rb +8 -0
  82. data/lib/shiplog/github/queries.rb +13 -1
  83. data/lib/shiplog/version.rb +1 -1
  84. data/lib/shiplog.rb +73 -0
  85. data/lib/tasks/shiplog.rake +29 -0
  86. metadata +47 -1
data/lib/shiplog.rb CHANGED
@@ -12,5 +12,78 @@ module Shiplog
12
12
  def config = (@config ||= Configuration.new)
13
13
  def configure = yield(config)
14
14
  def reset_config! = (@config = nil)
15
+
16
+ # The number of approved features and changes approved after `since`, or all of them while it is nil, capped
17
+ # at 99. Counted on approved_at (when the entry was approved), not released_on (the list's order). The host supplies the timestamp (Shiplog doesn't know its users): see config.on_changelog_seen.
18
+ def unseen_count(since: nil) = Entry.unseen_count(since:)
19
+
20
+ ACTIVE_STORAGE_TABLES = %w[active_storage_attachments active_storage_blobs].freeze
21
+
22
+ # Whether the host loaded Active Storage (its engine and the model macros). The declaration on Entry needs
23
+ # only this, so it never touches the database.
24
+ def active_storage_loaded? = !!(defined?(ActiveStorage::Engine) && ActiveRecord::Base.respond_to?(:has_many_attached))
25
+
26
+ # Whether screenshots can work: Active Storage is loaded and its tables exist (a host that loads
27
+ # `rails/all` but never ran active_storage:install would otherwise fail on every query). Without either,
28
+ # every image feature stays off instead of failing.
29
+ def active_storage? = active_storage_loaded? && active_storage_tables?
30
+
31
+ # Whether the Active Storage tables exist. Checked lazily, on first use, then remembered for the life of the
32
+ # process, so public pages never look at the schema again. When the database can't be reached (at boot, say)
33
+ # the answer is "not yet known": false for now, and asked again next time. The reason is logged once.
34
+ def active_storage_tables?
35
+ return @active_storage_tables unless @active_storage_tables.nil?
36
+
37
+ present = ActiveRecord::Base.with_connection { |connection| ACTIVE_STORAGE_TABLES.all? { |table| connection.data_source_exists?(table) } }
38
+ log_images_off("Active Storage's tables are missing (#{ACTIVE_STORAGE_TABLES.join(", ")}). Run bin/rails active_storage:install and db:migrate to enable them.") unless present || !config.images
39
+ @active_storage_tables = present
40
+ rescue ActiveRecord::ActiveRecordError
41
+ false
42
+ end
43
+
44
+ # Forgets what was learned about the schema and what was logged (tests, and hosts that create the tables at runtime).
45
+ def reset_images_checks!
46
+ @active_storage_tables = nil
47
+ @images_off_logged = nil
48
+ @image_variants = nil
49
+ end
50
+
51
+ # Logged once at boot (see Shiplog::Engine): screenshots wanted but Active Storage missing. A missing
52
+ # table is logged by the check itself, the first time it runs.
53
+ def log_images_status
54
+ return unless config.images
55
+
56
+ if !active_storage_loaded? then log_images_off("Active Storage is not loaded. Require active_storage/engine to enable them.")
57
+ else active_storage_tables?
58
+ end
59
+ end
60
+
61
+ # Whether the admin can show thumbnails as variants: the image_processing gem is loaded and so is a
62
+ # processor for it (ruby-vips, which must load, or mini_magick). Otherwise the originals are shown.
63
+ def image_variants?
64
+ return @image_variants unless @image_variants.nil?
65
+
66
+ @image_variants = Gem.loaded_specs.key?("image_processing") && (vips_loads? || Gem.loaded_specs.key?("mini_magick"))
67
+ end
68
+
69
+ # Whether screenshots are in use: config.images and Active Storage.
70
+ def images? = config.images && active_storage?
71
+
72
+ private
73
+
74
+ def vips_loads?
75
+ return true if defined?(::Vips)
76
+
77
+ Gem.loaded_specs.key?("ruby-vips") && require("vips")
78
+ rescue LoadError
79
+ false
80
+ end
81
+
82
+ def log_images_off(reason)
83
+ @images_off_logged ||= Set.new
84
+ return unless @images_off_logged.add?(reason)
85
+
86
+ Rails.logger&.info("[shiplog] Screenshots are off: #{reason}")
87
+ end
15
88
  end
16
89
  end
@@ -0,0 +1,29 @@
1
+ # Shiplog::Engine and Shiplog::Admin::Engine share the gem's root, so Rails loads this file once for each: the
2
+ # guard keeps every task from running twice.
3
+ unless Rake::Task.task_defined?("shiplog:backfill_slugs")
4
+ namespace :shiplog do
5
+ desc "Give approved changelog entries that have no permalink slug one (entries approved by code older than 0.3.0 after the migration ran)"
6
+ task backfill_slugs: :environment do
7
+ count = Shiplog::Entry.backfill_slugs
8
+ puts "Shiplog: gave #{count} #{count == 1 ? "entry" : "entries"} a slug."
9
+ end
10
+
11
+ desc "Translate approved entries and area names that have no current translation into config.locales (entries approved before 0.3.0 get none). BATCH_SIZE=100"
12
+ task translate_approved: :environment do
13
+ if Shiplog.config.locales.empty?
14
+ puts "Shiplog: config.locales is empty, nothing to translate."
15
+ elsif Shiplog.config.rewriter.nil?
16
+ puts "Shiplog: config.rewriter is not set, so nothing can be translated."
17
+ else
18
+ result = Shiplog::Entry.enqueue_missing_translations(batch_size: ENV.fetch("BATCH_SIZE", 100).to_i.clamp(1, 10_000))
19
+ approved = result[:approved]
20
+ puts "Shiplog: #{approved} approved #{approved == 1 ? "entry" : "entries"}."
21
+ result[:enqueued].each do |locale, count|
22
+ puts "Shiplog: #{locale}: #{count} enqueued, #{approved - count} current."
23
+ end
24
+ areas = Shiplog::Area.enqueue_missing_translations
25
+ puts "Shiplog: #{areas} #{areas == 1 ? "area" : "areas"} enqueued for name translation."
26
+ end
27
+ end
28
+ end
29
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shiplog
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Trackberry
@@ -40,14 +40,25 @@ files:
40
40
  - MIT-LICENSE
41
41
  - README.md
42
42
  - app/controllers/shiplog/admin/application_controller.rb
43
+ - app/controllers/shiplog/admin/area_detections_controller.rb
44
+ - app/controllers/shiplog/admin/area_translations_controller.rb
45
+ - app/controllers/shiplog/admin/areas/merges_controller.rb
46
+ - app/controllers/shiplog/admin/areas/moves_controller.rb
47
+ - app/controllers/shiplog/admin/areas_controller.rb
43
48
  - app/controllers/shiplog/admin/boards_controller.rb
44
49
  - app/controllers/shiplog/admin/entries/approvals_controller.rb
45
50
  - app/controllers/shiplog/admin/entries/discards_controller.rb
51
+ - app/controllers/shiplog/admin/entries/images/moves_controller.rb
52
+ - app/controllers/shiplog/admin/entries/images_controller.rb
46
53
  - app/controllers/shiplog/admin/entries/rewrites_controller.rb
54
+ - app/controllers/shiplog/admin/entries/translations/retranslations_controller.rb
55
+ - app/controllers/shiplog/admin/entries/translations_controller.rb
47
56
  - app/controllers/shiplog/admin/entries_controller.rb
48
57
  - app/controllers/shiplog/admin/inbox_filters.rb
49
58
  - app/controllers/shiplog/admin/syncs_controller.rb
50
59
  - app/controllers/shiplog/application_controller.rb
60
+ - app/controllers/shiplog/changelog_entries_controller.rb
61
+ - app/controllers/shiplog/changelog_feeds_controller.rb
51
62
  - app/controllers/shiplog/changelogs_controller.rb
52
63
  - app/controllers/shiplog/frontends_controller.rb
53
64
  - app/controllers/shiplog/public_controller.rb
@@ -61,21 +72,38 @@ files:
61
72
  - app/helpers/shiplog/application_helper.rb
62
73
  - app/helpers/shiplog/callable_helper.rb
63
74
  - app/helpers/shiplog/frontend_helper.rb
75
+ - app/helpers/shiplog/head_helper.rb
76
+ - app/helpers/shiplog/head_tags_helper.rb
64
77
  - app/helpers/shiplog/host_routes_helper.rb
78
+ - app/helpers/shiplog/permalink_helper.rb
65
79
  - app/helpers/shiplog/roadmap_helper.rb
80
+ - app/helpers/shiplog/structured_data_helper.rb
66
81
  - app/helpers/shiplog/styling_helper.rb
67
82
  - app/helpers/shiplog/switcher_helper.rb
83
+ - app/helpers/shiplog/unseen_helper.rb
68
84
  - app/jobs/shiplog/application_job.rb
85
+ - app/jobs/shiplog/detect_areas_job.rb
69
86
  - app/jobs/shiplog/refresh_job.rb
70
87
  - app/jobs/shiplog/rewrite_entry_job.rb
71
88
  - app/jobs/shiplog/scan_changes_job.rb
72
89
  - app/jobs/shiplog/sync_job.rb
90
+ - app/jobs/shiplog/translate_area_job.rb
91
+ - app/jobs/shiplog/translate_entry_job.rb
73
92
  - app/models/shiplog/application_record.rb
93
+ - app/models/shiplog/area.rb
94
+ - app/models/shiplog/area_detector.rb
95
+ - app/models/shiplog/area_translator.rb
74
96
  - app/models/shiplog/board_arrangement.rb
75
97
  - app/models/shiplog/change_candidates.rb
76
98
  - app/models/shiplog/commit.rb
77
99
  - app/models/shiplog/drafter.rb
78
100
  - app/models/shiplog/entry.rb
101
+ - app/models/shiplog/entry/images.rb
102
+ - app/models/shiplog/entry_translation.rb
103
+ - app/models/shiplog/image_fetcher.rb
104
+ - app/models/shiplog/image_fetcher/downloader.rb
105
+ - app/models/shiplog/image_fetcher/sources.rb
106
+ - app/models/shiplog/image_type.rb
79
107
  - app/models/shiplog/issue.rb
80
108
  - app/models/shiplog/issue_form.rb
81
109
  - app/models/shiplog/issue_link.rb
@@ -86,17 +114,21 @@ files:
86
114
  - app/models/shiplog/rewriter/prompt.rb
87
115
  - app/models/shiplog/roadmap.rb
88
116
  - app/models/shiplog/roadmap/column_resolver.rb
117
+ - app/models/shiplog/setting.rb
89
118
  - app/models/shiplog/sync/commit_scanner.rb
90
119
  - app/models/shiplog/sync/issue_importer.rb
91
120
  - app/models/shiplog/sync/node_attributes.rb
92
121
  - app/models/shiplog/sync/pull_request_importer.rb
93
122
  - app/models/shiplog/sync/repository_sync.rb
94
123
  - app/models/shiplog/sync/upgrade_detector.rb
124
+ - app/models/shiplog/translator.rb
125
+ - app/models/shiplog/translator/prompt.rb
95
126
  - app/models/shiplog/webhook_delivery.rb
96
127
  - app/models/shiplog/webhook_signature.rb
97
128
  - app/views/layouts/shiplog/admin.html.erb
98
129
  - app/views/layouts/shiplog/application.html.erb
99
130
  - app/views/shiplog/_empty.html.erb
131
+ - app/views/shiplog/_head_tags.html.erb
100
132
  - app/views/shiplog/_page.html.erb
101
133
  - app/views/shiplog/_page_header.html.erb
102
134
  - app/views/shiplog/_pagination.html.erb
@@ -105,26 +137,39 @@ files:
105
137
  - app/views/shiplog/admin/_custom_head.html.erb
106
138
  - app/views/shiplog/admin/_nav.html.erb
107
139
  - app/views/shiplog/admin/_page.html.erb
140
+ - app/views/shiplog/admin/areas/index.html.erb
108
141
  - app/views/shiplog/admin/boards/_card.html.erb
109
142
  - app/views/shiplog/admin/boards/show.html.erb
110
143
  - app/views/shiplog/admin/entries/_badges.html.erb
111
144
  - app/views/shiplog/admin/entries/_entry_row.html.erb
145
+ - app/views/shiplog/admin/entries/_images.html.erb
146
+ - app/views/shiplog/admin/entries/_translations.html.erb
112
147
  - app/views/shiplog/admin/entries/edit.html.erb
113
148
  - app/views/shiplog/admin/entries/index.html.erb
114
149
  - app/views/shiplog/admin/syncs/show.html.erb
150
+ - app/views/shiplog/changelog_entries/show.html.erb
151
+ - app/views/shiplog/changelog_feeds/show.atom.builder
152
+ - app/views/shiplog/changelogs/_areas.html.erb
115
153
  - app/views/shiplog/changelogs/_entry.html.erb
154
+ - app/views/shiplog/changelogs/_entry_content.html.erb
116
155
  - app/views/shiplog/changelogs/_month.html.erb
117
156
  - app/views/shiplog/changelogs/_search.html.erb
118
157
  - app/views/shiplog/changelogs/show.html.erb
158
+ - app/views/shiplog/head/_feed.html.erb
159
+ - app/views/shiplog/head/_meta.html.erb
160
+ - app/views/shiplog/head/_open_graph.html.erb
161
+ - app/views/shiplog/head/_structured_data.html.erb
119
162
  - app/views/shiplog/roadmaps/_card.html.erb
120
163
  - app/views/shiplog/roadmaps/_column.html.erb
121
164
  - app/views/shiplog/roadmaps/_shipped.html.erb
122
165
  - app/views/shiplog/roadmaps/show.html.erb
123
166
  - config/admin_routes.rb
124
167
  - config/locales/en.yml
168
+ - config/locales/es.yml
125
169
  - config/routes.rb
126
170
  - db/migrate/20261026000001_create_shiplog_tables.rb
127
171
  - db/migrate/20261027000001_create_shiplog_pull_request_upgrades.rb
172
+ - db/migrate/20261027000002_shiplog_0_3_0.rb
128
173
  - lib/generators/shiplog/install/install_generator.rb
129
174
  - lib/generators/shiplog/install/templates/initializer.rb.tt
130
175
  - lib/generators/shiplog/install/templates/shiplog-feature.yml
@@ -137,6 +182,7 @@ files:
137
182
  - lib/shiplog/github/errors.rb
138
183
  - lib/shiplog/github/queries.rb
139
184
  - lib/shiplog/version.rb
185
+ - lib/tasks/shiplog.rake
140
186
  homepage: https://github.com/Trackberry/shiplog
141
187
  licenses:
142
188
  - MIT