bible270 0.15.2 → 0.15.3

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: 30168f88726808151fb47d82b1ccca08afdbdec56f1005d41d64575d85e21384
4
- data.tar.gz: 9e63ced217294948d3e9e248ca0fc88da6b6be56e5d1b7988ac0b999661024a4
3
+ metadata.gz: 3bac102109d922307b87047b9151aa16354f5aacbfa1829a1419ca3bd02dc251
4
+ data.tar.gz: 825c3e6d6da35d724ea0cb7ece96244ac8555251c4c8b2165492139f49c7c4d1
5
5
  SHA512:
6
- metadata.gz: 0b01ce5346e5a2689c8a203f2962edc2a6b826ebcab1952a0a44a1ffcfe43a56b570c7f3c3806da442c822e6b58d7bc409708e9f2f507fb387df9d628f05d776
7
- data.tar.gz: 132d37fcdaa158e96a3e293ab293cb5934064c1514736df913743189b24cf75bacd980b2b333b0ea71407a629e4edbbf15faf289ad59c8f4533b914d2946ea23
6
+ metadata.gz: 54bb44c5d582ad4f4795a68a09d1facd54a0c4b8a77890ed0fb900c7d357ece4cb4e0656570c4bb15241fbb6cf9c6ef161f4a3d11962dd706aa41f03241b1f98
7
+ data.tar.gz: 961462928a89a8d3b060a4101996851115f2b8d479567a3741c3613f83823e7a78225113af1c82f1fc125d04101b93a5ee2ac2b2c554909fef1e6d859151e050
data/CHANGELOG.md CHANGED
@@ -6,7 +6,49 @@ All notable changes to bible270. Format follows [Keep a Changelog](https://keepa
6
6
 
7
7
  See the changes since the last release:
8
8
 
9
- **[Full Changelog](https://github.com/avonderluft/bible270/compare/v0.15.0...main)**
9
+ **[Full Changelog](https://github.com/avonderluft/bible270/compare/v0.15.3...main)**
10
+
11
+ ## [0.15.3] - 2026-08-04
12
+
13
+ **[Full Changelog](https://github.com/avonderluft/bible270/compare/v0.15.2...v0.15.2)**
14
+
15
+ ### Added
16
+
17
+ - `Bible270::Checkoff.reset_column_information` to migrations to prevent `UnknownAttributeError` during backfills.
18
+ - more tests (reader identity, sign-ins, and token management) to increase coverage to > 93%
19
+
20
+ ### Changed
21
+
22
+ - 'Today' now derived from system time, not UTC
23
+
24
+ ## [0.15.2] - 2026-08-04
25
+
26
+ **[Full Changelog](https://github.com/avonderluft/bible270/compare/v0.15.1...v0.15.2)**
27
+
28
+ ### Added
29
+
30
+ - app icon to shared header partial
31
+
32
+ ### Changed
33
+
34
+ - consistent reader sort order by first name in 'People' and 'Admin'
35
+
36
+ ## [0.15.1] - 2026-08-03
37
+
38
+ **[Full Changelog](https://github.com/avonderluft/bible270/compare/v0.15.0...v0.15.1)**
39
+
40
+ ### Added
41
+
42
+ - CSV file with versification by day
43
+
44
+ ### Changed
45
+
46
+ - refactor 'progress' and 'reflections' into partials to be more DRY
47
+ - update Coverage badge to be less cached
48
+
49
+ ### Removed
50
+
51
+ - old zip file of tests
10
52
 
11
53
  ## [0.15.0] - 2026-08-02
12
54
 
@@ -317,6 +359,12 @@ This is the initial public release.
317
359
 
318
360
  * Email sign-in requires working Action Mailer delivery in the host application. Set `config.mailer_from`; delivery is inline by default, or set `email_sign_in_deliver_later` when a queue backend is available.
319
361
 
362
+ [0.15.3]: https://github.com/avonderluft/bible270/releases/tag/v0.15.3
363
+ [0.15.2]: https://github.com/avonderluft/bible270/releases/tag/v0.15.2
364
+ [0.15.1]: https://github.com/avonderluft/bible270/releases/tag/v0.15.1
365
+ [0.15.0]: https://github.com/avonderluft/bible270/releases/tag/v0.15.0
366
+ [0.14.1]: https://github.com/avonderluft/bible270/releases/tag/v0.14.1
367
+ [0.14.0]: https://github.com/avonderluft/bible270/releases/tag/v0.14.0
320
368
  [0.13.1]: https://github.com/avonderluft/bible270/releases/tag/v0.13.1
321
369
  [0.13.0]: https://github.com/avonderluft/bible270/releases/tag/v0.13.0
322
370
  [0.12.0]: https://github.com/avonderluft/bible270/releases/tag/v0.12.0
@@ -348,7 +348,7 @@ module Bible270
348
348
 
349
349
  # Put this reader on `day` as of `on` — i.e. back-date the start so that the
350
350
  # given date lands on the given day of the plan.
351
- def restart_on!(day:, on: Date.current)
351
+ def restart_on!(day:, on: Bible270.today)
352
352
  day = day.to_i
353
353
  return false unless Plan.valid_day?(day)
354
354
 
@@ -406,7 +406,7 @@ module Bible270
406
406
 
407
407
  # The plan day that today corresponds to (clamped into range), or nil when undated.
408
408
  def calendar_day
409
- Plan.day_for(Date.current, effective_start_date)
409
+ Plan.day_for(Bible270.today, effective_start_date)
410
410
  end
411
411
 
412
412
  # Raw, unclamped — lets callers distinguish "not started yet" / "finished".
@@ -425,15 +425,15 @@ module Bible270
425
425
  end
426
426
 
427
427
  def raw_calendar_day
428
- Plan.day_for(Date.current, effective_start_date, clamp: false)
428
+ Plan.day_for(Bible270.today, effective_start_date, clamp: false)
429
429
  end
430
430
 
431
431
  def not_started_yet?
432
- Plan.before_start?(Date.current, effective_start_date)
432
+ Plan.before_start?(Bible270.today, effective_start_date)
433
433
  end
434
434
 
435
435
  def past_end_date?
436
- Plan.after_end?(Date.current, effective_start_date)
436
+ Plan.after_end?(Bible270.today, effective_start_date)
437
437
  end
438
438
 
439
439
  def plan_end_date
@@ -492,7 +492,7 @@ module Bible270
492
492
  return if started_on.present?
493
493
  return if config.start_date.present?
494
494
 
495
- update!(started_on: Date.current)
495
+ update!(started_on: Bible270.today)
496
496
  end
497
497
  end
498
498
  end
@@ -54,9 +54,15 @@ module Bible270
54
54
 
55
55
  # Too many outstanding requests for one address in the window.
56
56
  def self.rate_limited?(address)
57
+ # Normalised, because issue! stores a normalised address: querying the raw
58
+ # one let 'Eager@example.org' and 'eager@example.org' each have their own
59
+ # allowance, so varying the case bypassed the limit entirely.
60
+ email = EmailSignIn.normalize_email(address)
61
+ return false if email.nil?
62
+
57
63
  window = Bible270.config.email_sign_in_window
58
64
  max = Bible270.config.email_sign_in_max_per_window
59
- where(email: address).where(created_at: (Time.current - window)..).count >= max
65
+ where(email: email).where(created_at: (Time.current - window)..).count >= max
60
66
  end
61
67
 
62
68
  # Housekeeping: drop spent and stale rows. Safe to run from a cron/rake task.
@@ -8,7 +8,7 @@
8
8
  <% end %>
9
9
  · finishes <%= reader.plan_end_date.strftime("%B %-d, %Y") %>
10
10
  <% if reader.not_started_yet? %>
11
- · <em>begins in <%= (reader.effective_start_date - Date.current).to_i %> days</em>
11
+ · <em>begins in <%= (reader.effective_start_date - Bible270.today).to_i %> days</em>
12
12
  <% elsif reader.past_end_date? %>
13
13
  · <em>the 270 days have elapsed</em>
14
14
  <% elsif (off = reader.days_off_pace) %>
@@ -12,6 +12,11 @@ class AddPartToBible270Checkoffs < ActiveRecord::Migration[7.0]
12
12
  add_index :bible270_checkoffs, %i[reader_id day track part], unique: true,
13
13
  name: 'idx_b270_checkoffs_part_unique'
14
14
 
15
+ # The backfill goes through the model, which caches its columns. If Checkoff
16
+ # was loaded before this ran — likely, since the app boots first — it does not
17
+ # know about `part` yet and insert_all raises UnknownAttributeError.
18
+ Bible270::Checkoff.reset_column_information
19
+
15
20
  expand_existing_checkoffs
16
21
  end
17
22
 
@@ -28,6 +33,10 @@ class AddPartToBible270Checkoffs < ActiveRecord::Migration[7.0]
28
33
  add_index :bible270_checkoffs, %i[reader_id day track], unique: true,
29
34
  name: 'idx_b270_checkoffs_unique'
30
35
  remove_column :bible270_checkoffs, :part
36
+
37
+ # Likewise on the way back down: leaving the cached column in place makes the
38
+ # model try to write one the table no longer has.
39
+ Bible270::Checkoff.reset_column_information
31
40
  end
32
41
 
33
42
  private
@@ -292,7 +292,7 @@ module Bible270
292
292
  # from, so without this the notice names the reader but cannot link to them.
293
293
  attr_accessor :mailer_host
294
294
 
295
- attr_accessor :after_sign_out_path, :email_sign_in_max_per_window, :passage_url_builder, :tagline, :footer_html, :footer, :favicon, :avatar_max_bytes, :chapter_breaks, :admin_emails, :admin_resolver, :bible_version, :remember_for, :require_sign_in_to_participate
295
+ attr_accessor :after_sign_out_path, :email_sign_in_max_per_window, :passage_url_builder, :tagline, :footer_html, :footer, :favicon, :avatar_max_bytes, :chapter_breaks, :admin_emails, :admin_resolver, :bible_version, :header_mark, :remember_for, :require_sign_in_to_participate
296
296
 
297
297
  # Public labels.
298
298
  attr_accessor :app_name
@@ -321,7 +321,13 @@ module Bible270
321
321
  # The mark beside the title in the header. nil uses the built-in loaf, false
322
322
  # shows none, and a string is used as an image source — so a host can put its
323
323
  # own logo there without overriding the partial.
324
- attr_accessor :header_mark
324
+ # Which clock decides what day it is. nil follows the machine's own time zone,
325
+ # which is what a self-hosted plan usually wants — Rails defaults Time.zone to
326
+ # UTC, so a reader in Los Angeles saw the next day's reading from 4pm.
327
+ #
328
+ # config.time_zone = nil # the system clock (default)
329
+ # config.time_zone = 'America/Los_Angeles' # a named zone
330
+ attr_accessor :time_zone
325
331
 
326
332
  def remember_signed_in?
327
333
  remember_for.to_i.positive?
@@ -343,6 +349,7 @@ module Bible270
343
349
  end
344
350
  @app_name = 'Daily Bread'
345
351
  @tagline = 'Journeying through Scripture in 9 months'
352
+ @time_zone = nil
346
353
  @header_mark = nil
347
354
  @remember_for = 365 * 24 * 60 * 60
348
355
  @require_sign_in_to_participate = true
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bible270
4
- VERSION = '0.15.2'
4
+ VERSION = '0.15.3'
5
5
  end
data/lib/bible270.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'date'
4
+
3
5
  require 'bible270/version'
4
6
  require 'bible270/plan'
5
7
  require 'bible270/email_sign_in'
@@ -11,4 +13,18 @@ require 'bible270/configuration'
11
13
  require 'bible270/engine' if defined?(Rails::Engine)
12
14
 
13
15
  module Bible270
16
+ module_function
17
+
18
+ # The plan's idea of today.
19
+ #
20
+ # Date.current follows Rails' Time.zone, which is UTC unless the host app sets
21
+ # it; Date.today follows the machine. A self-hosted reading plan wants the
22
+ # latter, so that is the default, with config.time_zone to override.
23
+ def today
24
+ zone = config.time_zone
25
+ return Date.today if zone.nil? || zone.to_s.empty?
26
+
27
+ found = Time.respond_to?(:find_zone) ? Time.find_zone(zone) : nil
28
+ found ? found.today : Date.today
29
+ end
14
30
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bible270
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.2
4
+ version: 0.15.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew vonderLuft