slk 0.2.0 → 0.4.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.
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'time'
4
+
5
+ module Slk
6
+ module Support
7
+ # Parses date strings into timestamps for Slack API queries
8
+ # Supports duration formats (1d, 7d, 1w, 1m) and ISO dates (YYYY-MM-DD)
9
+ class DateParser
10
+ DURATION_PATTERN = /\A(\d+)([dwm])\z/i
11
+ ISO_DATE_PATTERN = /\A\d{4}-\d{2}-\d{2}\z/
12
+
13
+ # Parse a date string and return a Unix timestamp
14
+ # @param input [String] duration (1d, 7d, 1w, 1m) or ISO date (YYYY-MM-DD)
15
+ # @return [Integer] Unix timestamp
16
+ # @raise [ArgumentError] if format is invalid
17
+ def self.parse(input)
18
+ new.parse(input)
19
+ end
20
+
21
+ # Parse a date string and return a Slack-formatted timestamp (with microseconds)
22
+ # @param input [String] duration or ISO date
23
+ # @return [String] Slack timestamp like "1234567890.000000"
24
+ def self.to_slack_timestamp(input)
25
+ "#{parse(input)}.000000"
26
+ end
27
+
28
+ def parse(input)
29
+ input = input.to_s.strip
30
+
31
+ case input
32
+ when DURATION_PATTERN
33
+ parse_duration(input)
34
+ when ISO_DATE_PATTERN
35
+ parse_iso_date(input)
36
+ else
37
+ raise ArgumentError, "Invalid date format: #{input}. Use duration (1d, 7d, 1w, 1m) or ISO date (YYYY-MM-DD)"
38
+ end
39
+ end
40
+
41
+ private
42
+
43
+ def parse_duration(input)
44
+ match = input.match(DURATION_PATTERN)
45
+ amount = match[1].to_i
46
+ unit = match[2].downcase
47
+
48
+ seconds_ago = case unit
49
+ when 'd' then amount * 86_400 # days
50
+ when 'w' then amount * 7 * 86_400 # weeks
51
+ when 'm' then amount * 30 * 86_400 # months (approximate)
52
+ end
53
+
54
+ Time.now.to_i - seconds_ago
55
+ end
56
+
57
+ def parse_iso_date(input)
58
+ Time.parse("#{input} 00:00:00").to_i
59
+ rescue ArgumentError
60
+ raise ArgumentError, "Invalid ISO date: #{input}"
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Slk
4
+ module Support
5
+ # Cross-platform utilities for OS-specific operations
6
+ module Platform
7
+ module_function
8
+
9
+ def windows?
10
+ Gem.win_platform?
11
+ end
12
+
13
+ def macos?
14
+ RUBY_PLATFORM.include?('darwin')
15
+ end
16
+
17
+ def linux?
18
+ RUBY_PLATFORM.include?('linux')
19
+ end
20
+
21
+ # Open a URL or file with the system's default handler.
22
+ # Uses: open (macOS), start (Windows), xdg-open (Linux)
23
+ def open_url(url)
24
+ if windows?
25
+ system('start', '', url)
26
+ elsif macos?
27
+ system('open', url)
28
+ else
29
+ system('xdg-open', url)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -2,22 +2,40 @@
2
2
 
3
3
  module Slk
4
4
  module Support
5
- # XDG-compliant paths for config and cache directories
5
+ # Cross-platform paths for config and cache directories.
6
+ # Uses XDG Base Directory spec on Unix, APPDATA/LOCALAPPDATA on Windows.
6
7
  class XdgPaths
8
+ WINDOWS = Gem.win_platform?
9
+
7
10
  def config_dir
8
- @config_dir ||= File.join(
9
- ENV.fetch('XDG_CONFIG_HOME', File.join(Dir.home, '.config')),
10
- 'slk'
11
- )
11
+ @config_dir ||= normalize_path(File.join(default_config_base, 'slk'))
12
12
  end
13
13
 
14
14
  def cache_dir
15
- @cache_dir ||= File.join(
16
- ENV.fetch('XDG_CACHE_HOME', File.join(Dir.home, '.cache')),
17
- 'slk'
18
- )
15
+ @cache_dir ||= normalize_path(File.join(default_cache_base, 'slk'))
16
+ end
17
+
18
+ private
19
+
20
+ def default_config_base
21
+ return ENV.fetch('XDG_CONFIG_HOME', File.join(Dir.home, '.config')) unless WINDOWS
22
+
23
+ ENV.fetch('APPDATA', File.join(Dir.home, 'AppData', 'Roaming'))
19
24
  end
20
25
 
26
+ def default_cache_base
27
+ return ENV.fetch('XDG_CACHE_HOME', File.join(Dir.home, '.cache')) unless WINDOWS
28
+
29
+ ENV.fetch('LOCALAPPDATA', File.join(Dir.home, 'AppData', 'Local'))
30
+ end
31
+
32
+ # Normalize path separators to forward slashes for Dir.glob compatibility on Windows
33
+ def normalize_path(path)
34
+ WINDOWS ? path.tr('\\', '/') : path
35
+ end
36
+
37
+ public
38
+
21
39
  def config_file(filename)
22
40
  File.join(config_dir, filename)
23
41
  end
data/lib/slk/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Slk
4
- VERSION = '0.2.0'
4
+ VERSION = '0.4.0'
5
5
  end
data/lib/slk.rb CHANGED
@@ -32,6 +32,7 @@ module Slk
32
32
  autoload :User, 'slk/models/user'
33
33
  autoload :Channel, 'slk/models/channel'
34
34
  autoload :Preset, 'slk/models/preset'
35
+ autoload :SearchResult, 'slk/models/search_result'
35
36
  end
36
37
 
37
38
  # Application services for configuration, caching, and API communication
@@ -39,6 +40,8 @@ module Slk
39
40
  autoload :ApiClient, 'slk/services/api_client'
40
41
  autoload :Configuration, 'slk/services/configuration'
41
42
  autoload :TokenStore, 'slk/services/token_store'
43
+ autoload :TokenLoader, 'slk/services/token_loader'
44
+ autoload :TokenSaver, 'slk/services/token_saver'
42
45
  autoload :CacheStore, 'slk/services/cache_store'
43
46
  autoload :PresetStore, 'slk/services/preset_store'
44
47
  autoload :Encryption, 'slk/services/encryption'
@@ -50,6 +53,7 @@ module Slk
50
53
  autoload :UnreadMarker, 'slk/services/unread_marker'
51
54
  autoload :TargetResolver, 'slk/services/target_resolver'
52
55
  autoload :SetupWizard, 'slk/services/setup_wizard'
56
+ autoload :UserLookup, 'slk/services/user_lookup'
53
57
  end
54
58
 
55
59
  # Output formatters for messages, durations, and emoji
@@ -64,6 +68,7 @@ module Slk
64
68
  autoload :ActivityFormatter, 'slk/formatters/activity_formatter'
65
69
  autoload :AttachmentFormatter, 'slk/formatters/attachment_formatter'
66
70
  autoload :BlockFormatter, 'slk/formatters/block_formatter'
71
+ autoload :SearchFormatter, 'slk/formatters/search_formatter'
67
72
  end
68
73
 
69
74
  # CLI commands implementing user-facing functionality
@@ -77,6 +82,7 @@ module Slk
77
82
  autoload :Unread, 'slk/commands/unread'
78
83
  autoload :Catchup, 'slk/commands/catchup'
79
84
  autoload :Activity, 'slk/commands/activity'
85
+ autoload :Search, 'slk/commands/search'
80
86
  autoload :Preset, 'slk/commands/preset'
81
87
  autoload :Workspaces, 'slk/commands/workspaces'
82
88
  autoload :Cache, 'slk/commands/cache'
@@ -96,6 +102,7 @@ module Slk
96
102
  autoload :Threads, 'slk/api/threads'
97
103
  autoload :Usergroups, 'slk/api/usergroups'
98
104
  autoload :Activity, 'slk/api/activity'
105
+ autoload :Search, 'slk/api/search'
99
106
  end
100
107
 
101
108
  # Utility classes for paths, parsing, and helpers
@@ -108,5 +115,6 @@ module Slk
108
115
  autoload :UserResolver, 'slk/support/user_resolver'
109
116
  autoload :TextWrapper, 'slk/support/text_wrapper'
110
117
  autoload :InteractivePrompt, 'slk/support/interactive_prompt'
118
+ autoload :DateParser, 'slk/support/date_parser'
111
119
  end
112
120
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Boehs
@@ -21,7 +21,10 @@ files:
21
21
  - CHANGELOG.md
22
22
  - LICENSE
23
23
  - README.md
24
+ - bin/ci
25
+ - bin/coverage
24
26
  - bin/slk
27
+ - bin/test
25
28
  - lib/slk.rb
26
29
  - lib/slk/api/activity.rb
27
30
  - lib/slk/api/bots.rb
@@ -29,6 +32,7 @@ files:
29
32
  - lib/slk/api/conversations.rb
30
33
  - lib/slk/api/dnd.rb
31
34
  - lib/slk/api/emoji.rb
35
+ - lib/slk/api/search.rb
32
36
  - lib/slk/api/threads.rb
33
37
  - lib/slk/api/usergroups.rb
34
38
  - lib/slk/api/users.rb
@@ -44,6 +48,8 @@ files:
44
48
  - lib/slk/commands/messages.rb
45
49
  - lib/slk/commands/presence.rb
46
50
  - lib/slk/commands/preset.rb
51
+ - lib/slk/commands/search.rb
52
+ - lib/slk/commands/ssh_key_manager.rb
47
53
  - lib/slk/commands/status.rb
48
54
  - lib/slk/commands/thread.rb
49
55
  - lib/slk/commands/unread.rb
@@ -58,11 +64,13 @@ files:
58
64
  - lib/slk/formatters/message_formatter.rb
59
65
  - lib/slk/formatters/output.rb
60
66
  - lib/slk/formatters/reaction_formatter.rb
67
+ - lib/slk/formatters/search_formatter.rb
61
68
  - lib/slk/models/channel.rb
62
69
  - lib/slk/models/duration.rb
63
70
  - lib/slk/models/message.rb
64
71
  - lib/slk/models/preset.rb
65
72
  - lib/slk/models/reaction.rb
73
+ - lib/slk/models/search_result.rb
66
74
  - lib/slk/models/status.rb
67
75
  - lib/slk/models/user.rb
68
76
  - lib/slk/models/workspace.rb
@@ -79,12 +87,17 @@ files:
79
87
  - lib/slk/services/reaction_enricher.rb
80
88
  - lib/slk/services/setup_wizard.rb
81
89
  - lib/slk/services/target_resolver.rb
90
+ - lib/slk/services/token_loader.rb
91
+ - lib/slk/services/token_saver.rb
82
92
  - lib/slk/services/token_store.rb
83
93
  - lib/slk/services/unread_marker.rb
94
+ - lib/slk/services/user_lookup.rb
95
+ - lib/slk/support/date_parser.rb
84
96
  - lib/slk/support/error_logger.rb
85
97
  - lib/slk/support/help_formatter.rb
86
98
  - lib/slk/support/inline_images.rb
87
99
  - lib/slk/support/interactive_prompt.rb
100
+ - lib/slk/support/platform.rb
88
101
  - lib/slk/support/slack_url_parser.rb
89
102
  - lib/slk/support/text_wrapper.rb
90
103
  - lib/slk/support/user_resolver.rb