truenorth 0.2.4 → 0.2.5

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: 982552fcfe24f6754f7800b67df719b05c74a2afc33827e1d5ef1b175e9e76bb
4
- data.tar.gz: b9663b76cbcedaf763373b09c1748f123dbe87da63eeb402307873b569d9d39d
3
+ metadata.gz: 63c9a467b51f61d550f8c48a37109dbc647d5b599044beffc55333f0bade9e48
4
+ data.tar.gz: 12211afbaf407921821f41c2cddcc9c9581ad9e6f8e1ffef20ef83a8ec6df91e
5
5
  SHA512:
6
- metadata.gz: 46620ae876dd0a7bc8e7c7a149c0680b23ccc7860eab02bc5614f3d20194c33b011f60934af42bf39858fd29a0e0b5c0b578ad6ccea280b1797abc051c79cd6a
7
- data.tar.gz: 85ec92c5e279d090d3390a73c931d88990247a5ccfaec8b287df1010f5efee801534f33ac8c4b313bec548e4f3a955e835944f92361a19cd3acbc5170bd5c36f
6
+ metadata.gz: 2c0538cf12be2ff1a20f5950206b381537683bf3e5cfe87ee9895e7fe677154bebbd636df6837ed3ad0a136018060f982f697d875d456e1402cc4ef4d57e161a
7
+ data.tar.gz: 7874967a9ce9b6a7342e82ca8a5346dbd1fc0ccfe87a099dbeda0ac0201e9765ea9a8fbe3a36f8e9eff1eece1fb4ac12719f8ff5eb9777da2bef98560dfd7be4
data/lib/truenorth/cli.rb CHANGED
@@ -59,23 +59,28 @@ module Truenorth
59
59
  exit 1
60
60
  end
61
61
 
62
- desc 'book TIME', 'Book a slot at the specified time'
62
+ desc 'book TIME_OR_DESCRIPTION', 'Book a slot (e.g., "10am", "feb 15 10am", "squash feb 15 10am")'
63
63
  option :date, aliases: '-d', desc: 'Date (YYYY-MM-DD, or +N for days from today)'
64
64
  option :court, aliases: '-c', desc: 'Preferred court (e.g., "Court 1", "Squash Court 2")'
65
65
  option :activity, aliases: '-a', default: 'squash', desc: 'Activity type'
66
66
  option :dry_run, type: :boolean, aliases: '-n', desc: 'Test without actually booking'
67
- def book(time)
68
- date = parse_date(options[:date])
67
+ def book(time_or_description)
68
+ # Parse natural language input
69
+ parsed = parse_booking_request(time_or_description, options[:date], options[:activity])
70
+
71
+ date = parsed[:date]
72
+ time = parsed[:time]
73
+ activity = parsed[:activity]
69
74
  client = Client.new
70
75
 
71
76
  mode = options[:dry_run] ? ' (DRY RUN)' : ''
72
- say "Booking #{options[:activity]} at #{time} on #{date}#{mode}...", :cyan
77
+ say "Booking #{activity} at #{time} on #{date}#{mode}...", :cyan
73
78
 
74
79
  result = client.book(
75
80
  time,
76
81
  date: date,
77
82
  court: options[:court],
78
- activity: options[:activity],
83
+ activity: activity,
79
84
  dry_run: options[:dry_run]
80
85
  )
81
86
 
@@ -317,6 +322,65 @@ module Truenorth
317
322
  "#{text[0...max_length - 1]}…"
318
323
  end
319
324
 
325
+ def parse_booking_request(input, date_option, activity_option)
326
+ # Extract activity if mentioned (squash, golf, music, room)
327
+ activity = activity_option
328
+ if input =~ /\b(squash|golf|music|room)\b/i
329
+ activity = ::Regexp.last_match(1).downcase
330
+ input = input.gsub(/\b(squash|golf|music|room)\b/i, '').strip
331
+ end
332
+
333
+ # Extract date if present
334
+ date = nil
335
+ input_lower = input.downcase
336
+
337
+ # Try patterns like "feb 15", "february 15th", "2/15"
338
+ if input_lower =~ /\b(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)[a-z]*\s+(\d{1,2})(st|nd|rd|th)?\b/i
339
+ month_str = ::Regexp.last_match(1)
340
+ day = ::Regexp.last_match(2).to_i
341
+
342
+ month_map = {
343
+ 'jan' => 1, 'feb' => 2, 'mar' => 3, 'apr' => 4,
344
+ 'may' => 5, 'jun' => 6, 'jul' => 7, 'aug' => 8,
345
+ 'sep' => 9, 'oct' => 10, 'nov' => 11, 'dec' => 12
346
+ }
347
+
348
+ month = month_map[month_str[0..2].downcase]
349
+ year = Date.today.year
350
+ year += 1 if month && month < Date.today.month # Next year if month has passed
351
+
352
+ date = Date.new(year, month, day) if month
353
+ input = input.gsub(/\b(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)[a-z]*\s+(\d{1,2})(st|nd|rd|th)?\b/i, '').strip
354
+ elsif input =~ %r{\b(\d{1,2})/(\d{1,2})\b}
355
+ month = ::Regexp.last_match(1).to_i
356
+ day = ::Regexp.last_match(2).to_i
357
+ year = Date.today.year
358
+ date = Date.new(year, month, day)
359
+ input = input.gsub(%r{\b\d{1,2}/\d{1,2}\b}, '').strip
360
+ end
361
+
362
+ # Remove day names (monday, tuesday, etc.)
363
+ input = input.gsub(/\b(monday|tuesday|wednesday|thursday|friday|saturday|sunday)\b/i, '').strip
364
+
365
+ # Extract time - look for patterns like "10am", "10:00am", "10:00 AM", "10"
366
+ time = nil
367
+ if input =~ /\b(\d{1,2})(:(\d{2}))?\s*(am|pm)?\b/i
368
+ hour = ::Regexp.last_match(1).to_i
369
+ minute = ::Regexp.last_match(3) || '00'
370
+ period = ::Regexp.last_match(4) || (hour < 8 ? 'PM' : 'AM')
371
+
372
+ time = "#{hour}:#{minute} #{period.upcase}"
373
+ end
374
+
375
+ # Use provided date option if date wasn't extracted
376
+ date ||= parse_date(date_option)
377
+
378
+ # If no time found, use the remaining input as-is
379
+ time ||= input.strip
380
+
381
+ { date: date, time: time, activity: activity }
382
+ end
383
+
320
384
  def parse_date(date_str)
321
385
  return Date.today if date_str.nil? || date_str.empty?
322
386
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Truenorth
4
- VERSION = '0.2.4'
4
+ VERSION = '0.2.5'
5
5
  end
data/truenorth.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = 'truenorth'
5
- spec.version = '0.2.4'
5
+ spec.version = '0.2.5'
6
6
  spec.authors = ['usiegj00']
7
7
  spec.email = ['112138+usiegj00@users.noreply.github.com']
8
8
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: truenorth
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - usiegj00