imapcli 3.0.0 → 3.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5a1983fc995c34ea7b3a8d03cdbc45d644090aa0cc60527fe824cd7ae5227300
4
- data.tar.gz: f688ac2337ae9c3f0cb5d6d62df60a345bb5fabc0dab771d518be5d1ce1b18a1
3
+ metadata.gz: b57f2a82c06e43ef1d25ef4876ca78a746e01e2c985977ddb8f4789728992f5c
4
+ data.tar.gz: 7623524c875de285af386fcf521ec59893e1022ee5e09284d4aa30950eba2786
5
5
  SHA512:
6
- metadata.gz: 23e6aaf015e5ffb731e4f5a6e6d926ff0b8988ba3ea92503df7615aff9217e1b1b55a4c5236a9aabade45dffe53f7bf2912e6084886c25ec0f0d83202fc220f9
7
- data.tar.gz: 5cae5a577598c723f2c9621ad5ad173aa246bf93ffaff740f57e5ab6ce4f3c21b0d124daddf55b801f22b60e677a37a93ae1d20a913da82eff3d644818899833
6
+ metadata.gz: 76857de95667a5d6ea600244cd48c54cc91257da559ed1968273822e1cc1fc08bb7e5e94955fd0b7a9f1b21b7514d970e1aa342941e640c78f279a702b706fcd
7
+ data.tar.gz: eabd2e90a25f8f8a2939208505d87dfd40828bee5db598810df9d1c6d186cd984f5b093f90ca89254276fbbeb20289fc6c94922345bdbb6006ea099f47bf02c9
@@ -3,7 +3,7 @@
3
3
  {
4
4
  "name": "Ruby",
5
5
  // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
6
- "image": "mcr.microsoft.com/devcontainers/ruby:1-3.3-bullseye"
6
+ "image": "mcr.microsoft.com/devcontainers/ruby:1-3.4-bullseye"
7
7
 
8
8
  // Features to add to the dev container. More info: https://containers.dev/features.
9
9
  // "features": {},
data/CHANGELOG.md CHANGED
@@ -5,6 +5,29 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [Version 3.1.0 (2026-02-11)][v3.0.1]
9
+
10
+ ### CHanged
11
+
12
+ - Increase resilience against IMAP errors. Added an option `--[no-]skip-errors`, which
13
+ is enabled by default, but can be disabled to error out on IMAP folder errors.
14
+
15
+ ## [Version 3.0.1 (2025-06-29)][v3.0.1]
16
+
17
+ ### Changed
18
+
19
+ - Updated dependencies.
20
+
21
+ ### Fixed
22
+
23
+ - Docker image now works again for real (finally fixes #10?).
24
+
25
+ ## [Version 3.0.0 (2025-04-21)][v3.0.0]
26
+
27
+ ### Fixed
28
+
29
+ - Docker image now works again (fixes #10).
30
+
8
31
  ## [Version 3.0.0 (2025-04-21)][v3.0.0]
9
32
 
10
33
  ### Changed
@@ -87,6 +110,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
87
110
  - Fix: Docker image.
88
111
  - Fix: Options error message.
89
112
 
113
+ [v3.0.1]: https://github.com/bovender/imapcli/releases/tag/v3.0.1
90
114
  [v3.0.0]: https://github.com/bovender/imapcli/releases/tag/v3.0.0
91
115
  [v2.1.0]: https://github.com/bovender/imapcli/releases/tag/v2.1.0
92
116
  [v2.0.1]: https://github.com/bovender/imapcli/releases/tag/v2.0.1
data/Dockerfile CHANGED
@@ -1,18 +1,22 @@
1
- FROM ruby:3.4-alpine
2
- LABEL maintainer="bovender@bovender.de"
3
- LABEL description="Command-line tool to query IMAP servers, collect stats etc."
4
-
5
- WORKDIR /
6
- ADD . /imapcli
7
- RUN apk add --no-cache git build-base && \
1
+ FROM ruby:4 AS builder
2
+ WORKDIR /imapcli
3
+ COPY Gemfile Gemfile.lock imapcli.gemspec .
4
+ COPY lib/imapcli/version.rb lib/imapcli/version.rb
5
+ RUN apt-get update -qq && \
6
+ apt-get install -y build-essential libc6 && \
8
7
  gem update --system && \
9
- cd imapcli && \
10
8
  bundle config set --local without development test && \
11
9
  bundle config set --local deployment true && \
12
- bundle install && \
13
- apk del build-base && \
14
- rm -rf /var/cache/apk/*
10
+ bundle install
15
11
 
12
+ FROM ruby:4-slim
13
+ LABEL maintainer="bovender@bovender.de"
14
+ LABEL description="Command-line tool to query IMAP servers, collect stats etc."
16
15
  WORKDIR /imapcli
16
+ RUN apt-get update -qq && \
17
+ apt-get install -y git && \
18
+ apt-get clean && rm -rf /var/lib/apt/lists/*
19
+ COPY --from=builder /usr/local/bundle /usr/local/bundle
20
+ COPY --from=builder /imapcli/vendor /imapcli/vendor
21
+ COPY . .
17
22
  ENTRYPOINT ["bundle", "exec", "exe/imapcli"]
18
-
data/Gemfile.lock CHANGED
@@ -1,13 +1,12 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- imapcli (2.1.0)
4
+ imapcli (3.0.1)
5
5
  activesupport (~> 8.0)
6
6
  csv
7
7
  descriptive_statistics (~> 2.5)
8
8
  dotenv (~> 3.1)
9
9
  gli (~> 2.22)
10
- multi_json (~> 1.15)
11
10
  net-imap
12
11
  oj (~> 3.16)
13
12
  tty-progressbar (~> 0.18)
@@ -18,58 +17,58 @@ PATH
18
17
  GEM
19
18
  remote: https://rubygems.org/
20
19
  specs:
21
- activesupport (8.0.2)
20
+ activesupport (8.1.2)
22
21
  base64
23
- benchmark (>= 0.3)
24
22
  bigdecimal
25
23
  concurrent-ruby (~> 1.0, >= 1.3.1)
26
24
  connection_pool (>= 2.2.5)
27
25
  drb
28
26
  i18n (>= 1.6, < 2)
27
+ json
29
28
  logger (>= 1.4.2)
30
29
  minitest (>= 5.1)
31
30
  securerandom (>= 0.3)
32
31
  tzinfo (~> 2.0, >= 2.0.5)
33
32
  uri (>= 0.13.1)
34
- ast (2.4.2)
35
- base64 (0.2.0)
36
- benchmark (0.4.0)
37
- bigdecimal (3.1.9)
33
+ ast (2.4.3)
34
+ base64 (0.3.0)
35
+ bigdecimal (4.0.1)
38
36
  coderay (1.1.3)
39
- concurrent-ruby (1.3.5)
40
- connection_pool (2.5.0)
41
- csv (3.3.2)
42
- date (3.4.1)
43
- debug (1.10.0)
37
+ concurrent-ruby (1.3.6)
38
+ connection_pool (3.0.2)
39
+ csv (3.3.5)
40
+ date (3.5.1)
41
+ debug (1.11.1)
44
42
  irb (~> 1.10)
45
43
  reline (>= 0.3.8)
46
44
  descriptive_statistics (2.5.1)
47
- diff-lcs (1.6.0)
45
+ diff-lcs (1.6.2)
48
46
  docile (1.4.1)
49
- dotenv (3.1.7)
50
- drb (2.2.1)
51
- ffi (1.17.1)
52
- ffi (1.17.1-aarch64-linux-gnu)
53
- ffi (1.17.1-aarch64-linux-musl)
54
- ffi (1.17.1-arm-linux-gnu)
55
- ffi (1.17.1-arm-linux-musl)
56
- ffi (1.17.1-arm64-darwin)
57
- ffi (1.17.1-x86-linux-gnu)
58
- ffi (1.17.1-x86-linux-musl)
59
- ffi (1.17.1-x86_64-darwin)
60
- ffi (1.17.1-x86_64-linux-gnu)
61
- ffi (1.17.1-x86_64-linux-musl)
62
- formatador (1.1.0)
47
+ dotenv (3.2.0)
48
+ drb (2.2.3)
49
+ erb (6.0.1)
50
+ ffi (1.17.3)
51
+ ffi (1.17.3-aarch64-linux-gnu)
52
+ ffi (1.17.3-aarch64-linux-musl)
53
+ ffi (1.17.3-arm-linux-gnu)
54
+ ffi (1.17.3-arm-linux-musl)
55
+ ffi (1.17.3-arm64-darwin)
56
+ ffi (1.17.3-x86-linux-gnu)
57
+ ffi (1.17.3-x86-linux-musl)
58
+ ffi (1.17.3-x86_64-darwin)
59
+ ffi (1.17.3-x86_64-linux-gnu)
60
+ ffi (1.17.3-x86_64-linux-musl)
61
+ formatador (1.2.3)
62
+ reline
63
63
  gli (2.22.2)
64
64
  ostruct
65
- guard (2.19.1)
65
+ guard (2.20.1)
66
66
  formatador (>= 0.2.4)
67
67
  listen (>= 2.7, < 4.0)
68
68
  logger (~> 1.6)
69
69
  lumberjack (>= 1.0.12, < 2.0)
70
70
  nenv (~> 0.1)
71
71
  notiffany (~> 0.0)
72
- ostruct (~> 0.6)
73
72
  pry (>= 0.13.0)
74
73
  shellany (~> 0.0)
75
74
  thor (>= 0.18.1)
@@ -78,26 +77,28 @@ GEM
78
77
  guard (~> 2.1)
79
78
  guard-compat (~> 1.1)
80
79
  rspec (>= 2.99.0, < 4.0)
81
- i18n (1.14.7)
80
+ i18n (1.14.8)
82
81
  concurrent-ruby (~> 1.0)
83
- io-console (0.8.0)
84
- irb (1.15.1)
82
+ io-console (0.8.2)
83
+ irb (1.17.0)
85
84
  pp (>= 0.6.0)
85
+ prism (>= 1.3.0)
86
86
  rdoc (>= 4.0.0)
87
87
  reline (>= 0.4.2)
88
- json (2.10.2)
89
- language_server-protocol (3.17.0.4)
88
+ json (2.18.1)
89
+ language_server-protocol (3.17.0.5)
90
90
  lint_roller (1.1.0)
91
- listen (3.9.0)
91
+ listen (3.10.0)
92
+ logger
92
93
  rb-fsevent (~> 0.10, >= 0.10.3)
93
94
  rb-inotify (~> 0.9, >= 0.9.10)
94
- logger (1.6.6)
95
- lumberjack (1.2.10)
95
+ logger (1.7.0)
96
+ lumberjack (1.4.2)
96
97
  method_source (1.1.0)
97
- minitest (5.25.5)
98
- multi_json (1.15.0)
98
+ minitest (6.0.1)
99
+ prism (~> 1.5)
99
100
  nenv (0.3.0)
100
- net-imap (0.5.6)
101
+ net-imap (0.6.2)
101
102
  date
102
103
  net-protocol
103
104
  net-protocol (0.2.2)
@@ -105,50 +106,54 @@ GEM
105
106
  notiffany (0.1.3)
106
107
  nenv (~> 0.1)
107
108
  shellany (~> 0.0)
108
- oj (3.16.10)
109
+ oj (3.16.15)
109
110
  bigdecimal (>= 3.0)
110
111
  ostruct (>= 0.2)
111
- ostruct (0.6.1)
112
- parallel (1.26.3)
113
- parser (3.3.7.1)
112
+ ostruct (0.6.3)
113
+ parallel (1.27.0)
114
+ parser (3.3.10.1)
114
115
  ast (~> 2.4.1)
115
116
  racc
116
117
  pastel (0.8.0)
117
118
  tty-color (~> 0.5)
118
- pp (0.6.2)
119
+ pp (0.6.3)
119
120
  prettyprint
120
121
  prettyprint (0.2.0)
121
- pry (0.15.2)
122
+ prism (1.9.0)
123
+ pry (0.16.0)
122
124
  coderay (~> 1.1)
123
125
  method_source (~> 1.0)
124
- psych (5.2.3)
126
+ reline (>= 0.6.0)
127
+ psych (5.3.1)
125
128
  date
126
129
  stringio
127
130
  racc (1.8.1)
128
131
  rainbow (3.1.1)
129
- rake (13.2.1)
132
+ rake (13.3.1)
130
133
  rb-fsevent (0.11.2)
131
134
  rb-inotify (0.11.1)
132
135
  ffi (~> 1.0)
133
- rdoc (6.12.0)
136
+ rdoc (7.2.0)
137
+ erb
134
138
  psych (>= 4.0.0)
135
- regexp_parser (2.10.0)
136
- reline (0.6.0)
139
+ tsort
140
+ regexp_parser (2.11.3)
141
+ reline (0.6.3)
137
142
  io-console (~> 0.5)
138
- rspec (3.13.0)
143
+ rspec (3.13.2)
139
144
  rspec-core (~> 3.13.0)
140
145
  rspec-expectations (~> 3.13.0)
141
146
  rspec-mocks (~> 3.13.0)
142
- rspec-core (3.13.3)
147
+ rspec-core (3.13.6)
143
148
  rspec-support (~> 3.13.0)
144
- rspec-expectations (3.13.3)
149
+ rspec-expectations (3.13.5)
145
150
  diff-lcs (>= 1.2.0, < 2.0)
146
151
  rspec-support (~> 3.13.0)
147
- rspec-mocks (3.13.2)
152
+ rspec-mocks (3.13.7)
148
153
  diff-lcs (>= 1.2.0, < 2.0)
149
154
  rspec-support (~> 3.13.0)
150
- rspec-support (3.13.2)
151
- rubocop (1.74.0)
155
+ rspec-support (3.13.7)
156
+ rubocop (1.84.1)
152
157
  json (~> 2.3)
153
158
  language_server-protocol (~> 3.17.0.2)
154
159
  lint_roller (~> 1.1.0)
@@ -156,21 +161,22 @@ GEM
156
161
  parser (>= 3.3.0.2)
157
162
  rainbow (>= 2.2.2, < 4.0)
158
163
  regexp_parser (>= 2.9.3, < 3.0)
159
- rubocop-ast (>= 1.38.0, < 2.0)
164
+ rubocop-ast (>= 1.49.0, < 2.0)
160
165
  ruby-progressbar (~> 1.7)
161
166
  unicode-display_width (>= 2.4.0, < 4.0)
162
- rubocop-ast (1.39.0)
163
- parser (>= 3.3.1.0)
164
- rubocop-performance (1.24.0)
167
+ rubocop-ast (1.49.0)
168
+ parser (>= 3.3.7.2)
169
+ prism (~> 1.7)
170
+ rubocop-performance (1.26.1)
165
171
  lint_roller (~> 1.1)
166
- rubocop (>= 1.72.1, < 2.0)
167
- rubocop-ast (>= 1.38.0, < 2.0)
172
+ rubocop (>= 1.75.0, < 2.0)
173
+ rubocop-ast (>= 1.47.1, < 2.0)
168
174
  rubocop-rake (0.7.1)
169
175
  lint_roller (~> 1.1)
170
176
  rubocop (>= 1.72.1)
171
- rubocop-rspec (3.5.0)
177
+ rubocop-rspec (3.9.0)
172
178
  lint_roller (~> 1.1)
173
- rubocop (~> 1.72, >= 1.72.1)
179
+ rubocop (~> 1.81)
174
180
  ruby-progressbar (1.13.0)
175
181
  securerandom (0.4.1)
176
182
  shellany (0.0.1)
@@ -178,16 +184,17 @@ GEM
178
184
  docile (~> 1.1)
179
185
  simplecov-html (~> 0.11)
180
186
  simplecov_json_formatter (~> 0.1)
181
- simplecov-html (0.13.1)
187
+ simplecov-html (0.13.2)
182
188
  simplecov_json_formatter (0.1.4)
183
- stringio (3.1.5)
189
+ stringio (3.2.0)
184
190
  strings (0.2.1)
185
191
  strings-ansi (~> 0.2)
186
192
  unicode-display_width (>= 1.5, < 3.0)
187
193
  unicode_utils (~> 1.4)
188
194
  strings-ansi (0.2.0)
189
- thor (1.3.2)
190
- timeout (0.4.3)
195
+ thor (1.5.0)
196
+ timeout (0.6.0)
197
+ tsort (0.2.0)
191
198
  tty-color (0.6.0)
192
199
  tty-cursor (0.7.1)
193
200
  tty-progressbar (0.18.3)
@@ -211,9 +218,9 @@ GEM
211
218
  concurrent-ruby (~> 1.0)
212
219
  unicode-display_width (2.6.0)
213
220
  unicode_utils (1.4.0)
214
- uri (1.0.3)
221
+ uri (1.1.1)
215
222
  wisper (2.0.1)
216
- zeitwerk (2.7.2)
223
+ zeitwerk (2.7.4)
217
224
 
218
225
  PLATFORMS
219
226
  aarch64-linux-gnu
@@ -243,4 +250,4 @@ DEPENDENCIES
243
250
  simplecov
244
251
 
245
252
  BUNDLED WITH
246
- 2.6.5
253
+ 4.0.6
data/README.md CHANGED
@@ -332,10 +332,11 @@ the `Gemfile` for other work that this tool depends on.
332
332
 
333
333
  - [@bovender](https://github.com/bovender)
334
334
  - [@n-rodriguez](https://github.com/n-rodriguez)
335
+ - [@d4nyl0](https://github.com/d4nyl0)
335
336
 
336
337
  ## License
337
338
 
338
- &copy; 2017-2025 Daniel Kraus (@bovender)
339
+ &copy; 2017-2026 Daniel Kraus (@bovender)
339
340
 
340
341
  Licensed under the Apache License, Version 2.0 (the "License");
341
342
  you may not use this file except in compliance with the License.
data/lib/imapcli/cli.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'multi_json'
4
3
  require 'oj'
5
4
 
6
5
  module Imapcli
@@ -70,6 +69,12 @@ module Imapcli
70
69
  c.switch %i[H human],
71
70
  desc: 'Convert byte counts to human-friendly formats',
72
71
  negatable: false
72
+
73
+ c.switch %i[skip-errors],
74
+ desc: 'Skip folders (IMAP mailboxes) that cannot be accessed',
75
+ negatable: true,
76
+ default_value: true
77
+
73
78
  c.flag %i[o sort],
74
79
  desc: 'Ordered (sorted) results',
75
80
  arg_name: 'sort_property',
@@ -86,9 +91,11 @@ module Imapcli
86
91
  raise unless @validator.stats_options_valid?(options, args)
87
92
 
88
93
  progress_bar = nil
94
+ skipped_mailboxes = []
89
95
 
90
96
  head = ['Mailbox', 'Count', 'Total size', 'Min', 'Q1', 'Median', 'Q3', 'Max']
91
- body = @command.stats(args, options) do |n|
97
+
98
+ body = @command.stats(args, options, skipped_mailboxes) do |n|
92
99
  if progress_bar
93
100
  progress_bar.advance
94
101
  else
@@ -99,6 +106,7 @@ module Imapcli
99
106
  )
100
107
  end
101
108
  end
109
+
102
110
  formatted_body = body.map do |row|
103
111
  row[0..1] + row[2..].map { |cell| format_bytes(cell, options[:human]) }
104
112
  end
@@ -131,6 +139,14 @@ module Imapcli
131
139
  @prompt.warn "#{Imapcli::Command.unknown_mailbox_prefix}unknown mailbox"
132
140
  end
133
141
  end
142
+
143
+ unless skipped_mailboxes.empty?
144
+ @prompt.say ""
145
+ @prompt.warn "Skipped #{skipped_mailboxes.length} folder(s) (IMAP mailbox(es)) due to errors:"
146
+ skipped_mailboxes.each do |info|
147
+ @prompt.warn " - #{info[:name]}: #{info[:error]}"
148
+ end
149
+ end
134
150
  end
135
151
  end
136
152
 
@@ -46,7 +46,7 @@ module Imapcli
46
46
  #
47
47
  # If a block is given, it is called with the current mailbox count and the
48
48
  # total mailbox count so that current progress can be computed.
49
- def stats(mailbox_names = [], options = {}) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
49
+ def stats(mailbox_names = [], options = {}, skipped_mailboxes = []) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
50
50
  mailbox_names = [mailbox_names] unless mailbox_names.is_a? Array
51
51
  perform do
52
52
  # Map the command line arguments to Imapcli::Mailbox objects
@@ -59,11 +59,14 @@ module Imapcli
59
59
  current_count = 0
60
60
  yield list.length if block_given?
61
61
  total_stats = Stats.new
62
+
63
+ skip_errors = options.fetch(:'skip-errors', true)
64
+
62
65
  list.each do |mailbox|
63
66
  # Since we are working on a flat list of mailboxes, set the maximum
64
67
  # level to 0 when collecting stats.
65
- mailbox.collect_stats(@client, 0) do |stats|
66
- total_stats.add(stats)
68
+ mailbox.collect_stats(@client, 0, skip_errors: skip_errors, skipped_mailboxes: skipped_mailboxes) do |stats|
69
+ total_stats.add(stats) if stats
67
70
  current_count += 1
68
71
  yield current_count if block_given?
69
72
  end
@@ -74,8 +77,8 @@ module Imapcli
74
77
  else
75
78
  sorted_list(list, options)
76
79
  end.map do |mailbox|
77
- stats_to_table(mailbox.full_name, mailbox.stats)
78
- end
80
+ mailbox.stats ? stats_to_table(mailbox.full_name, mailbox.stats) : nil
81
+ end.compact
79
82
  output << stats_to_table('Total', total_stats) if list.length > 1
80
83
  output
81
84
  end
@@ -106,15 +106,30 @@ module Imapcli
106
106
  #
107
107
  # If a block is given, it is called with the Imapcli::Stats object for this
108
108
  # mailbox.
109
- def collect_stats(client, max_level = nil, &block)
109
+ def collect_stats(client, max_level = nil, skip_errors: true, skipped_mailboxes: nil, &block)
110
110
  return if @stats
111
111
 
112
- @stats = Stats.new(client.message_sizes(full_name)) if full_name # proceed only if this is a mailbox of its own
113
- yield @stats if block_given?
112
+ # proceed only if this is a mailbox of its own
113
+ if full_name
114
+ begin
115
+ @stats = Stats.new(client.message_sizes(full_name))
116
+ yield @stats if block_given?
117
+ rescue Net::IMAP::NoResponseError => e
118
+ # Errore IMAP: mailbox non esiste o non è accessibile
119
+ handle_mailbox_error(e, skip_errors, skipped_mailboxes)
120
+ rescue Net::IMAP::ByeResponseError => e
121
+ # Server ha chiuso la connessione
122
+ handle_mailbox_error(e, skip_errors, skipped_mailboxes)
123
+ rescue StandardError => e
124
+ # Altro tipo di errore
125
+ handle_mailbox_error(e, skip_errors, skipped_mailboxes)
126
+ end
127
+ end
128
+
114
129
  return unless max_level.nil? || level < max_level
115
130
 
116
131
  @children.each_value do |child|
117
- child.collect_stats(client, max_level, &block)
132
+ child.collect_stats(client, max_level, skip_errors: skip_errors, skipped_mailboxes: skipped_mailboxes, &block)
118
133
  end
119
134
  end
120
135
 
@@ -175,5 +190,31 @@ module Imapcli
175
190
  end
176
191
  end
177
192
 
193
+ private
194
+
195
+ # Handle errors during stats collection
196
+ def handle_mailbox_error(error, skip_errors, skipped_mailboxes)
197
+ error_message = case error
198
+ when Net::IMAP::NoResponseError
199
+ error.message
200
+ when Net::IMAP::ByeResponseError
201
+ "Server closed connection: #{error.message}"
202
+ else
203
+ "#{error.class}: #{error.message}"
204
+ end
205
+
206
+ if skip_errors
207
+ if skipped_mailboxes.is_a?(Array)
208
+ skipped_mailboxes << {
209
+ name: full_name,
210
+ error: error_message
211
+ }
212
+ end
213
+ nil
214
+ else
215
+ raise error
216
+ end
217
+ end
218
+
178
219
  end
179
220
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Imapcli
4
- VERSION = '3.0.0'
4
+ VERSION = '3.1.0'
5
5
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: imapcli
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Kraus (bovender)
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-04-21 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: activesupport
@@ -198,7 +198,6 @@ files:
198
198
  - lib/imapcli/option_validator.rb
199
199
  - lib/imapcli/stats.rb
200
200
  - lib/imapcli/version.rb
201
- - logoutput.json
202
201
  - spec/lib/imapcli/client_spec.rb
203
202
  - spec/lib/imapcli/command_spec.rb
204
203
  - spec/lib/imapcli/mailbox_spec.rb
@@ -227,7 +226,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
227
226
  - !ruby/object:Gem::Version
228
227
  version: '0'
229
228
  requirements: []
230
- rubygems_version: 3.6.2
229
+ rubygems_version: 3.6.9
231
230
  specification_version: 4
232
231
  summary: Command-line tool to query IMAP servers
233
232
  test_files: []
data/logoutput.json DELETED
@@ -1,527 +0,0 @@
1
- [
2
- {
3
- ":imap_command":"list",
4
- ":imap_response":{
5
- "FLAGS":[
6
- [
7
- ":Answered",
8
- ":Flagged",
9
- ":Deleted",
10
- ":Seen",
11
- ":Draft",
12
- "NonJunk",
13
- "Junk",
14
- "$label2",
15
- "$forwarded",
16
- "$label5",
17
- "Old",
18
- "$label4",
19
- "$label3",
20
- "$SIGNED",
21
- "$JUNK",
22
- "$ATTACHMENT",
23
- "$NOTJUNK",
24
- "$INVITATION",
25
- "$label1",
26
- "$TODO"
27
- ]
28
- ],
29
- "OK":[
30
- {
31
- "^u":[
32
- "Net::IMAP::ResponseText",
33
- {
34
- "^u":[
35
- "Net::IMAP::ResponseCode",
36
- "PERMANENTFLAGS",
37
- []]},
38
- "Read-only mailbox."]},
39
- {
40
- "^u":[
41
- "Net::IMAP::ResponseText",
42
- {
43
- "^u":[
44
- "Net::IMAP::ResponseCode",
45
- "UNSEEN",
46
- 6]},
47
- "First unseen."]},
48
- {
49
- "^u":[
50
- "Net::IMAP::ResponseText",
51
- {
52
- "^u":[
53
- "Net::IMAP::ResponseCode",
54
- "UIDVALIDITY",
55
- 1435851445]},
56
- "UIDs valid"]},
57
- {
58
- "^u":[
59
- "Net::IMAP::ResponseText",
60
- {
61
- "^u":[
62
- "Net::IMAP::ResponseCode",
63
- "UIDNEXT",
64
- 104489]},
65
- "Predicted next UID"]},
66
- {
67
- "^u":[
68
- "Net::IMAP::ResponseText",
69
- {
70
- "^u":[
71
- "Net::IMAP::ResponseCode",
72
- "HIGHESTMODSEQ",
73
- 309489]},
74
- "Highest"]}
75
- ],
76
- "PERMANENTFLAGS":[
77
- []
78
- ],
79
- "EXISTS":[
80
- 6
81
- ],
82
- "RECENT":[
83
- 0
84
- ],
85
- "UNSEEN":[
86
- 6
87
- ],
88
- "UIDVALIDITY":[
89
- 1435851445
90
- ],
91
- "UIDNEXT":[
92
- 104489
93
- ],
94
- "HIGHESTMODSEQ":[
95
- 309489
96
- ],
97
- "ESEARCH":[],
98
- "BYE":[
99
- {
100
- "^u":[
101
- "Net::IMAP::ResponseText",
102
- null,
103
- "Logging out"]}
104
- ]
105
- }
106
- },
107
- {
108
- ":imap_command":"list('')",
109
- ":imap_response":{
110
- "FLAGS":[
111
- [
112
- ":Answered",
113
- ":Flagged",
114
- ":Deleted",
115
- ":Seen",
116
- ":Draft",
117
- "NonJunk",
118
- "Junk",
119
- "$label2",
120
- "$forwarded",
121
- "$label5",
122
- "Old",
123
- "$label4",
124
- "$label3",
125
- "$SIGNED",
126
- "$JUNK",
127
- "$ATTACHMENT",
128
- "$NOTJUNK",
129
- "$INVITATION",
130
- "$label1",
131
- "$TODO"
132
- ]
133
- ],
134
- "OK":[
135
- {
136
- "^u":[
137
- "Net::IMAP::ResponseText",
138
- {
139
- "^u":[
140
- "Net::IMAP::ResponseCode",
141
- "PERMANENTFLAGS",
142
- []]},
143
- "Read-only mailbox."]},
144
- {
145
- "^u":[
146
- "Net::IMAP::ResponseText",
147
- {
148
- "^u":[
149
- "Net::IMAP::ResponseCode",
150
- "UNSEEN",
151
- 6]},
152
- "First unseen."]},
153
- {
154
- "^u":[
155
- "Net::IMAP::ResponseText",
156
- {
157
- "^u":[
158
- "Net::IMAP::ResponseCode",
159
- "UIDVALIDITY",
160
- 1435851445]},
161
- "UIDs valid"]},
162
- {
163
- "^u":[
164
- "Net::IMAP::ResponseText",
165
- {
166
- "^u":[
167
- "Net::IMAP::ResponseCode",
168
- "UIDNEXT",
169
- 104489]},
170
- "Predicted next UID"]},
171
- {
172
- "^u":[
173
- "Net::IMAP::ResponseText",
174
- {
175
- "^u":[
176
- "Net::IMAP::ResponseCode",
177
- "HIGHESTMODSEQ",
178
- 309489]},
179
- "Highest"]}
180
- ],
181
- "PERMANENTFLAGS":[
182
- []
183
- ],
184
- "EXISTS":[
185
- 6
186
- ],
187
- "RECENT":[
188
- 0
189
- ],
190
- "UNSEEN":[
191
- 6
192
- ],
193
- "UIDVALIDITY":[
194
- 1435851445
195
- ],
196
- "UIDNEXT":[
197
- 104489
198
- ],
199
- "HIGHESTMODSEQ":[
200
- 309489
201
- ],
202
- "ESEARCH":[],
203
- "BYE":[
204
- {
205
- "^u":[
206
- "Net::IMAP::ResponseText",
207
- null,
208
- "Logging out"]}
209
- ]
210
- }
211
- },
212
- {
213
- ":imap_command":"examine('INBOX')",
214
- ":imap_response":{
215
- "FLAGS":[
216
- [
217
- ":Answered",
218
- ":Flagged",
219
- ":Deleted",
220
- ":Seen",
221
- ":Draft",
222
- "NonJunk",
223
- "Junk",
224
- "$label2",
225
- "$forwarded",
226
- "$label5",
227
- "Old",
228
- "$label4",
229
- "$label3",
230
- "$SIGNED",
231
- "$JUNK",
232
- "$ATTACHMENT",
233
- "$NOTJUNK",
234
- "$INVITATION",
235
- "$label1",
236
- "$TODO"
237
- ]
238
- ],
239
- "OK":[
240
- {
241
- "^u":[
242
- "Net::IMAP::ResponseText",
243
- {
244
- "^u":[
245
- "Net::IMAP::ResponseCode",
246
- "PERMANENTFLAGS",
247
- []]},
248
- "Read-only mailbox."]},
249
- {
250
- "^u":[
251
- "Net::IMAP::ResponseText",
252
- {
253
- "^u":[
254
- "Net::IMAP::ResponseCode",
255
- "UNSEEN",
256
- 6]},
257
- "First unseen."]},
258
- {
259
- "^u":[
260
- "Net::IMAP::ResponseText",
261
- {
262
- "^u":[
263
- "Net::IMAP::ResponseCode",
264
- "UIDVALIDITY",
265
- 1435851445]},
266
- "UIDs valid"]},
267
- {
268
- "^u":[
269
- "Net::IMAP::ResponseText",
270
- {
271
- "^u":[
272
- "Net::IMAP::ResponseCode",
273
- "UIDNEXT",
274
- 104489]},
275
- "Predicted next UID"]},
276
- {
277
- "^u":[
278
- "Net::IMAP::ResponseText",
279
- {
280
- "^u":[
281
- "Net::IMAP::ResponseCode",
282
- "HIGHESTMODSEQ",
283
- 309489]},
284
- "Highest"]}
285
- ],
286
- "PERMANENTFLAGS":[
287
- []
288
- ],
289
- "EXISTS":[
290
- 6
291
- ],
292
- "RECENT":[
293
- 0
294
- ],
295
- "UNSEEN":[
296
- 6
297
- ],
298
- "UIDVALIDITY":[
299
- 1435851445
300
- ],
301
- "UIDNEXT":[
302
- 104489
303
- ],
304
- "HIGHESTMODSEQ":[
305
- 309489
306
- ],
307
- "ESEARCH":[],
308
- "BYE":[
309
- {
310
- "^u":[
311
- "Net::IMAP::ResponseText",
312
- null,
313
- "Logging out"]}
314
- ]
315
- }
316
- },
317
- {
318
- ":imap_command":"search('ALL')",
319
- ":imap_response":{
320
- "FLAGS":[
321
- [
322
- ":Answered",
323
- ":Flagged",
324
- ":Deleted",
325
- ":Seen",
326
- ":Draft",
327
- "NonJunk",
328
- "Junk",
329
- "$label2",
330
- "$forwarded",
331
- "$label5",
332
- "Old",
333
- "$label4",
334
- "$label3",
335
- "$SIGNED",
336
- "$JUNK",
337
- "$ATTACHMENT",
338
- "$NOTJUNK",
339
- "$INVITATION",
340
- "$label1",
341
- "$TODO"
342
- ]
343
- ],
344
- "OK":[
345
- {
346
- "^u":[
347
- "Net::IMAP::ResponseText",
348
- {
349
- "^u":[
350
- "Net::IMAP::ResponseCode",
351
- "PERMANENTFLAGS",
352
- []]},
353
- "Read-only mailbox."]},
354
- {
355
- "^u":[
356
- "Net::IMAP::ResponseText",
357
- {
358
- "^u":[
359
- "Net::IMAP::ResponseCode",
360
- "UNSEEN",
361
- 6]},
362
- "First unseen."]},
363
- {
364
- "^u":[
365
- "Net::IMAP::ResponseText",
366
- {
367
- "^u":[
368
- "Net::IMAP::ResponseCode",
369
- "UIDVALIDITY",
370
- 1435851445]},
371
- "UIDs valid"]},
372
- {
373
- "^u":[
374
- "Net::IMAP::ResponseText",
375
- {
376
- "^u":[
377
- "Net::IMAP::ResponseCode",
378
- "UIDNEXT",
379
- 104489]},
380
- "Predicted next UID"]},
381
- {
382
- "^u":[
383
- "Net::IMAP::ResponseText",
384
- {
385
- "^u":[
386
- "Net::IMAP::ResponseCode",
387
- "HIGHESTMODSEQ",
388
- 309489]},
389
- "Highest"]}
390
- ],
391
- "PERMANENTFLAGS":[
392
- []
393
- ],
394
- "EXISTS":[
395
- 6
396
- ],
397
- "RECENT":[
398
- 0
399
- ],
400
- "UNSEEN":[
401
- 6
402
- ],
403
- "UIDVALIDITY":[
404
- 1435851445
405
- ],
406
- "UIDNEXT":[
407
- 104489
408
- ],
409
- "HIGHESTMODSEQ":[
410
- 309489
411
- ],
412
- "ESEARCH":[],
413
- "BYE":[
414
- {
415
- "^u":[
416
- "Net::IMAP::ResponseText",
417
- null,
418
- "Logging out"]}
419
- ]
420
- }
421
- },
422
- {
423
- ":imap_command":"fetch(...)",
424
- ":imap_response":{
425
- "FLAGS":[
426
- [
427
- ":Answered",
428
- ":Flagged",
429
- ":Deleted",
430
- ":Seen",
431
- ":Draft",
432
- "NonJunk",
433
- "Junk",
434
- "$label2",
435
- "$forwarded",
436
- "$label5",
437
- "Old",
438
- "$label4",
439
- "$label3",
440
- "$SIGNED",
441
- "$JUNK",
442
- "$ATTACHMENT",
443
- "$NOTJUNK",
444
- "$INVITATION",
445
- "$label1",
446
- "$TODO"
447
- ]
448
- ],
449
- "OK":[
450
- {
451
- "^u":[
452
- "Net::IMAP::ResponseText",
453
- {
454
- "^u":[
455
- "Net::IMAP::ResponseCode",
456
- "PERMANENTFLAGS",
457
- []]},
458
- "Read-only mailbox."]},
459
- {
460
- "^u":[
461
- "Net::IMAP::ResponseText",
462
- {
463
- "^u":[
464
- "Net::IMAP::ResponseCode",
465
- "UNSEEN",
466
- 6]},
467
- "First unseen."]},
468
- {
469
- "^u":[
470
- "Net::IMAP::ResponseText",
471
- {
472
- "^u":[
473
- "Net::IMAP::ResponseCode",
474
- "UIDVALIDITY",
475
- 1435851445]},
476
- "UIDs valid"]},
477
- {
478
- "^u":[
479
- "Net::IMAP::ResponseText",
480
- {
481
- "^u":[
482
- "Net::IMAP::ResponseCode",
483
- "UIDNEXT",
484
- 104489]},
485
- "Predicted next UID"]},
486
- {
487
- "^u":[
488
- "Net::IMAP::ResponseText",
489
- {
490
- "^u":[
491
- "Net::IMAP::ResponseCode",
492
- "HIGHESTMODSEQ",
493
- 309489]},
494
- "Highest"]}
495
- ],
496
- "PERMANENTFLAGS":[
497
- []
498
- ],
499
- "EXISTS":[
500
- 6
501
- ],
502
- "RECENT":[
503
- 0
504
- ],
505
- "UNSEEN":[
506
- 6
507
- ],
508
- "UIDVALIDITY":[
509
- 1435851445
510
- ],
511
- "UIDNEXT":[
512
- 104489
513
- ],
514
- "HIGHESTMODSEQ":[
515
- 309489
516
- ],
517
- "ESEARCH":[],
518
- "BYE":[
519
- {
520
- "^u":[
521
- "Net::IMAP::ResponseText",
522
- null,
523
- "Logging out"]}
524
- ]
525
- }
526
- }
527
- ]