Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 42 additions & 17 deletions app/jobs/sync_journal_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -211,33 +211,58 @@ def rewrite_image_urls(content, raw_base)
MONTH_NAMES = (Date::MONTHNAMES.compact + Date::ABBR_MONTHNAMES.compact).map(&:downcase).uniq.freeze
MONTH_ALTERNATION = MONTH_NAMES.join("|").freeze
ISO_DATE_PATTERN = /\b(\d{4})-(\d{1,2})-(\d{1,2})\b/.freeze
DAY_FIRST_PATTERN = Regexp.new("\\b(\\d{1,2})(?:st|nd|rd|th)?\\s+(#{MONTH_ALTERNATION})\\b\\.?(?:[\\s,]+(\\d{4}))?", Regexp::IGNORECASE).freeze
MONTH_FIRST_PATTERN = Regexp.new("\\b(#{MONTH_ALTERNATION})\\b\\.?\\s+(\\d{1,2})(?:[\\s,]+(\\d{4}))?", Regexp::IGNORECASE).freeze
DATE_LINE_PATTERN = /^.*\bdate\b.*$/i
DAY_FIRST_PATTERN = Regexp.new("\\b(\\d{1,2})(?!\\d)(?:st|nd|rd|th)?\\s+(#{MONTH_ALTERNATION})\\b\\.?(?:[\\s,]+(\\d{4}))?", Regexp::IGNORECASE).freeze
MONTH_FIRST_PATTERN = Regexp.new("\\b(#{MONTH_ALTERNATION})\\b\\.?\\s+(\\d{1,2})(?!\\d)(?:st|nd|rd|th)?(?:[\\s,]+(\\d{4}))?", Regexp::IGNORECASE).freeze
DATE_LINE_PATTERN = /^[ \t*_#>-]*date\b[^\n]*$/i
ENTRY_COUNTER_PATTERN = /\b(?:day|entry|log|devlog|part)[ \t]*(?:#[ \t]*)?\z/i
COUNTER_LOOKBACK = 16

# An explicit "Date:" line wins over prose, and "16 July" is read day-first
# before "July 16" is tried — otherwise a day-first entry matches the month
# and takes the clock time that follows it as the day.
# before "July 16" is tried. A day-first match right after an entry counter
# ("Day 15 August 28") is only used when nothing else in the source parses.
def extract_entry_date(entry, today = Date.current)
sources = [ entry[:content].to_s[DATE_LINE_PATTERN], "#{entry[:title]} #{entry[:content]}" ].compact

sources.each do |source|
if (m = source.match(ISO_DATE_PATTERN))
return build_safe_date(m[1].to_i, m[2].to_i, m[3].to_i, today)
end
date = match_date(source, today)
return date if date
end

if (m = source.match(DAY_FIRST_PATTERN))
month = month_number(m[2])
return build_safe_date(m[3]&.to_i || today.year, month, m[1].to_i, today) if month
end
nil
end

if (m = source.match(MONTH_FIRST_PATTERN))
month = month_number(m[1])
return build_safe_date(m[3]&.to_i || today.year, month, m[2].to_i, today) if month
end
def match_date(source, today)
if (m = source.match(ISO_DATE_PATTERN))
date = build_safe_date(m[1].to_i, m[2].to_i, m[3].to_i, today)
return date if date
end

nil
after_counter = nil
position = 0

while (m = DAY_FIRST_PATTERN.match(source, position))
position = m.end(0)
month = month_number(m[2])
next unless month

date = build_safe_date(m[3]&.to_i || today.year, month, m[1].to_i, today)
next unless date
return date unless entry_counter_before?(source, m.begin(0))

after_counter ||= date
end

if (m = source.match(MONTH_FIRST_PATTERN))
month = month_number(m[1])
date = month ? build_safe_date(m[3]&.to_i || today.year, month, m[2].to_i, today) : nil
return date if date
end

after_counter
end

def entry_counter_before?(source, index)
ENTRY_COUNTER_PATTERN.match?(source[[ index - COUNTER_LOOKBACK, 0 ].max...index])
end

def month_number(name)
Expand Down
21 changes: 21 additions & 0 deletions test/jobs/sync_journal_job_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,27 @@ def run_job(journal, commit_date: nil, clear: false)
assert_nil Devlog.find_by(project: @project, title: "Afternoon")
end

test "a day-first entry is credited to its own day" do
date = @today - 1
run_job("# #{date.day} #{Date::MONTHNAMES[date.month]} #{date.year} 10 PM\n\n**Total time spent: 2h**\n", commit_date: @today)

assert_equal date, Devlog.last.entry_date
end

test "an entry counter is not read as the day of the month" do
date = @today - 1
run_job("# Day 15 #{Date::MONTHNAMES[date.month]} #{date.day}, #{date.year}\n\n**Total time spent: 2h**\n", commit_date: @today)

assert_equal date, Devlog.last.entry_date
end

test "a date mentioned mid-sentence does not override the title" do
date = @today - 1
run_job("# #{date.day} #{Date::MONTHNAMES[date.month]} #{date.year}\n\npushed back the release date: #{Date::MONTHNAMES[date.month]} #{date.day} next year\n\n**Total time spent: 2h**\n", commit_date: @today)

assert_equal date, Devlog.last.entry_date
end

test "sync stamps journal_synced_at so the sweep can skip fresh projects" do
run_job("# Wiring\n\n**Total time spent: 2h**\n", commit_date: @today)

Expand Down
Loading