imap_mogura 0.2.2 → 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.
- checksums.yaml +4 -4
- data/lib/imap_mogura/cli.rb +32 -18
- data/lib/imap_mogura/debug_util.rb +15 -0
- data/lib/imap_mogura/rules_parser/rule_elements.rb +49 -21
- data/lib/imap_mogura/version.rb +1 -1
- data/lib/imap_mogura.rb +1 -0
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3889ab4ffaf619e936cb0a0dcf3aa0dd8eb7b5613866028c75ccc10c274f933e
|
4
|
+
data.tar.gz: e3c626aba3ffab681a53e9ccb8b8f436ba86ee3d790c373ba486b81e26daf6c1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d4c0fe1d4db3a23912e681cbd17a1bf13ba8b02f961a04ce44497659ec672b22b166a737bb6a258e5c6c10c7d067810064833e595063b56ba1aea25967da9378
|
7
|
+
data.tar.gz: 30a8d4e087f2c3d0aba2ca58237afba9c9fc1e6da17fef7006822dbbecce1c80164cbf7c3f02b0b95d451303e0e8003346c93bc33bf5989bb5ceee5765986302
|
data/lib/imap_mogura/cli.rb
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
require "thor"
|
4
4
|
require "base64"
|
5
5
|
|
6
|
+
require_relative "debug_util"
|
7
|
+
|
6
8
|
module ImapMogura
|
7
9
|
class CustomOptionError < Thor::Error
|
8
10
|
def initialize(msg = "Custom option error message")
|
@@ -29,6 +31,7 @@ module ImapMogura
|
|
29
31
|
option :filter_unseen, type: :boolean, default: true
|
30
32
|
option :create_directory, type: :boolean, default: true
|
31
33
|
option :dry_run, type: :boolean, default: false
|
34
|
+
option :debug, type: :boolean, default: false
|
32
35
|
def start(host)
|
33
36
|
port = options[:port]
|
34
37
|
starttls = options[:starttls]
|
@@ -41,6 +44,9 @@ module ImapMogura
|
|
41
44
|
filter_unseen = options[:filter_unseen]
|
42
45
|
create_directory = options[:create_directory]
|
43
46
|
dry_run = options[:dry_run]
|
47
|
+
debug = options[:debug]
|
48
|
+
|
49
|
+
DebugUtil.enable_debug if debug
|
44
50
|
|
45
51
|
search_keys = ["RECENT", *(["UNSEEN"] if filter_unseen)]
|
46
52
|
|
@@ -53,9 +59,11 @@ module ImapMogura
|
|
53
59
|
monitor_recents_on_mailbox(imap_handler, target_mailbox) do
|
54
60
|
# find mails with search keys on the target mailbox and handle them
|
55
61
|
imap_handler.find_and_handle_mails(target_mailbox, search_keys) do |message_id|
|
56
|
-
warn "mail
|
62
|
+
warn "a mail is recent on \"#{target_mailbox}\""
|
57
63
|
|
58
64
|
filter_mail(imap_handler, rules, target_mailbox, message_id, dry_run: dry_run)
|
65
|
+
|
66
|
+
imap_handler.close_operation_for_mailbox(target_mailbox)
|
59
67
|
end
|
60
68
|
end
|
61
69
|
end
|
@@ -75,6 +83,7 @@ module ImapMogura
|
|
75
83
|
option :filter_only_unseen, type: :boolean, default: false
|
76
84
|
option :create_directory, type: :boolean, default: true
|
77
85
|
option :dry_run, type: :boolean, default: false
|
86
|
+
option :debug, type: :boolean, default: false
|
78
87
|
def filter(host)
|
79
88
|
port = options[:port]
|
80
89
|
starttls = options[:starttls]
|
@@ -89,9 +98,12 @@ module ImapMogura
|
|
89
98
|
filter_only_unseen = options[:filter_only_unseen]
|
90
99
|
create_directory = options[:create_directory]
|
91
100
|
dry_run = options[:dry_run]
|
101
|
+
debug = options[:debug]
|
92
102
|
|
93
103
|
raise CustomOptionError, "--all-mailbox (-a) or --target-mailbox (-b) is required" if !all_mailbox && target_mailbox.nil?
|
94
104
|
|
105
|
+
DebugUtil.enable_debug if debug
|
106
|
+
|
95
107
|
search_keys = if filter_only_unseen
|
96
108
|
["UNSEEN"]
|
97
109
|
else
|
@@ -219,7 +231,7 @@ module ImapMogura
|
|
219
231
|
handle_mail_fetch_error_and_preprocess_retrying(e, retry_count)
|
220
232
|
|
221
233
|
# retry monitor recents on mailbox itself with retry count to be incremented
|
222
|
-
warn "retry monitoring mails on #{e.mailbox}..."
|
234
|
+
warn "retry monitoring mails on \"#{e.mailbox}\"..."
|
223
235
|
|
224
236
|
monitor_recents_on_mailbox(imap_handler, mailbox, retry_count + 1)
|
225
237
|
end
|
@@ -228,43 +240,32 @@ module ImapMogura
|
|
228
240
|
imap_handler.find_and_handle_mails(mailbox, search_keys) do |message_id|
|
229
241
|
filter_mail(imap_handler, rules, mailbox, message_id, dry_run: dry_run)
|
230
242
|
end
|
243
|
+
|
244
|
+
imap_handler.close_operation_for_mailbox(mailbox)
|
231
245
|
rescue IMAPHandler::MailFetchError => e
|
232
246
|
handle_mail_fetch_error_and_preprocess_retrying(e, retry_count)
|
233
247
|
|
234
248
|
# retry filter all mails itself with retry count to be incremented
|
235
|
-
warn "retry filtering all mails on #{e.mailbox}"
|
249
|
+
warn "retry filtering all mails on \"#{e.mailbox}\""
|
236
250
|
|
237
251
|
filter_mails(imap_handler, rules, mailbox, search_keys, retry_count + 1, dry_run: dry_run)
|
238
252
|
end
|
239
253
|
|
240
|
-
def handle_mail_fetch_error_and_preprocess_retrying(error, retry_count)
|
241
|
-
warn "failed to fetch mail (id = #{error.message_id} on mailbox #{error.mailbox}): #{error.bad_response_error_message}"
|
242
|
-
|
243
|
-
# if retry_count is over the threshold, abort processing
|
244
|
-
raise Thor::Error, "retry count is over the threshold, stop processing" unless retry_count < 3
|
245
|
-
|
246
|
-
warn "wait a moment..."
|
247
|
-
|
248
|
-
sleep 10
|
249
|
-
end
|
250
|
-
|
251
254
|
def filter_mail(imap_handler, rules, mailbox, message_id, dry_run: false)
|
252
255
|
mail = imap_handler.fetch_header(mailbox, message_id)
|
253
256
|
|
254
257
|
warn "# filtering mail on \"#{mailbox}\" of subject \"#{mail.subject}\"..."
|
255
258
|
|
256
259
|
rules.each do |rule_set|
|
257
|
-
try_to_filter_mail_for_rule_set(imap_handler, rule_set, mailbox, message_id, mail, dry_run: dry_run)
|
260
|
+
break if try_to_filter_mail_for_rule_set(imap_handler, rule_set, mailbox, message_id, mail, dry_run: dry_run)
|
258
261
|
end
|
259
|
-
|
260
|
-
imap_handler.close_operation_for_mailbox(mailbox)
|
261
262
|
end
|
262
263
|
|
263
264
|
def try_to_filter_mail_for_rule_set(imap_handler, rule_set, mailbox, message_id, mail, dry_run: false)
|
264
265
|
dst_mailbox = rule_set.destination
|
265
266
|
rule = rule_set.rule
|
266
267
|
|
267
|
-
return unless rule.match?(mail)
|
268
|
+
return nil unless rule.match?(mail)
|
268
269
|
|
269
270
|
warn "the mail matches for the rule of the destination \"#{dst_mailbox}\""
|
270
271
|
warn "moving the mail..."
|
@@ -279,6 +280,19 @@ module ImapMogura
|
|
279
280
|
warn "moving skipped because the destination is the same with the current mailbox \"#{mailbox}\""
|
280
281
|
end
|
281
282
|
end
|
283
|
+
|
284
|
+
dst_mailbox
|
285
|
+
end
|
286
|
+
|
287
|
+
def handle_mail_fetch_error_and_preprocess_retrying(error, retry_count)
|
288
|
+
warn "failed to fetch the mail on \"#{error.mailbox}\": #{error.bad_response_error_message}"
|
289
|
+
|
290
|
+
# if retry_count is over the threshold, abort processing
|
291
|
+
raise Thor::Error, "retry count is over the threshold, stop processing" unless retry_count < 3
|
292
|
+
|
293
|
+
warn "wait a moment..."
|
294
|
+
|
295
|
+
sleep 10
|
282
296
|
end
|
283
297
|
end
|
284
298
|
end
|
@@ -1,10 +1,26 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "../debug_util"
|
4
|
+
|
3
5
|
module ImapMogura
|
4
6
|
class RuleElement
|
5
7
|
def match?(mail)
|
6
8
|
raise NotImplementedError
|
7
9
|
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def debug_out_before_trying_rule(msg)
|
14
|
+
DebugUtil.debug "## checking if it matches the rule: #{msg}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def debug_out_if_it_matches_rule(match_result)
|
18
|
+
if match_result
|
19
|
+
DebugUtil.debug "## it matches the rule"
|
20
|
+
else
|
21
|
+
DebugUtil.debug "## it doesn't match"
|
22
|
+
end
|
23
|
+
end
|
8
24
|
end
|
9
25
|
|
10
26
|
class LogicalOperator < RuleElement
|
@@ -47,46 +63,57 @@ module ImapMogura
|
|
47
63
|
|
48
64
|
class FromMatcher < SpecialFieldMatcher
|
49
65
|
def match?(mail)
|
50
|
-
|
51
|
-
|
52
|
-
mail.from
|
53
|
-
|
54
|
-
|
55
|
-
|
66
|
+
debug_out_before_trying_rule("From #{mail.from.inspect} matches the regexp #{@regexp}")
|
67
|
+
debug_out_if_it_matches_rule(
|
68
|
+
case mail.from
|
69
|
+
when Enumerable
|
70
|
+
mail.from.any? { |address| address&.match?(@regexp) }
|
71
|
+
else
|
72
|
+
mail.from&.match?(@regexp)
|
73
|
+
end
|
74
|
+
)
|
56
75
|
end
|
57
76
|
end
|
58
77
|
|
59
78
|
class SenderMatcher < SpecialFieldMatcher
|
60
79
|
def match?(mail)
|
61
|
-
mail.sender
|
80
|
+
debug_out_before_trying_rule("Sender #{mail.sender.inspect} matches the regexp #{@regexp}")
|
81
|
+
debug_out_if_it_matches_rule(mail.sender&.match?(@regexp))
|
62
82
|
end
|
63
83
|
end
|
64
84
|
|
65
85
|
class ToMatcher < SpecialFieldMatcher
|
66
86
|
def match?(mail)
|
67
|
-
|
68
|
-
|
69
|
-
mail.to
|
70
|
-
|
71
|
-
|
72
|
-
|
87
|
+
debug_out_before_trying_rule("To #{mail.to.inspect} matches the regexp #{@regexp}")
|
88
|
+
debug_out_if_it_matches_rule(
|
89
|
+
case mail.to
|
90
|
+
when Enumerable
|
91
|
+
mail.to.any? { |address| address&.match?(@regexp) }
|
92
|
+
else
|
93
|
+
mail.to&.match?(@regexp)
|
94
|
+
end
|
95
|
+
)
|
73
96
|
end
|
74
97
|
end
|
75
98
|
|
76
99
|
class CcMatcher < SpecialFieldMatcher
|
77
100
|
def match?(mail)
|
78
|
-
|
79
|
-
|
80
|
-
mail.cc
|
81
|
-
|
82
|
-
|
83
|
-
|
101
|
+
debug_out_before_trying_rule("Cc #{mail.cc.inspect} matches the regexp #{@regexp}")
|
102
|
+
debug_out_if_it_matches_rule(
|
103
|
+
case mail.cc
|
104
|
+
when Enumerable
|
105
|
+
mail.cc.any? { |address| address&.match?(@regexp) }
|
106
|
+
else
|
107
|
+
mail.cc&.match?(@regexp)
|
108
|
+
end
|
109
|
+
)
|
84
110
|
end
|
85
111
|
end
|
86
112
|
|
87
113
|
class SubjectMatcher < SpecialFieldMatcher
|
88
114
|
def match?(mail)
|
89
|
-
mail.subject
|
115
|
+
debug_out_before_trying_rule("Subject \"#{mail.subject}\" matches the regexp #{@regexp}")
|
116
|
+
debug_out_if_it_matches_rule(mail.subject&.match?(@regexp))
|
90
117
|
end
|
91
118
|
end
|
92
119
|
|
@@ -105,7 +132,8 @@ module ImapMogura
|
|
105
132
|
end
|
106
133
|
|
107
134
|
def match?(mail)
|
108
|
-
mail.headers[@field_name]&.value
|
135
|
+
debug_out_before_trying_rule("header field \"#{@field_name}\" with value \"#{mail.headers[@field_name]&.value}\" matches the regexp #{@regexp}")
|
136
|
+
debug_out_if_it_matches_rule(mail.headers[@field_name]&.value&.match?(@regexp))
|
109
137
|
end
|
110
138
|
end
|
111
139
|
end
|
data/lib/imap_mogura/version.rb
CHANGED
data/lib/imap_mogura.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: imap_mogura
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ysk
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-01-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: base64
|
@@ -84,6 +84,7 @@ files:
|
|
84
84
|
- lib/imap_mogura/cli.rb
|
85
85
|
- lib/imap_mogura/config_parser.rb
|
86
86
|
- lib/imap_mogura/config_parser/errors.rb
|
87
|
+
- lib/imap_mogura/debug_util.rb
|
87
88
|
- lib/imap_mogura/imap_handler.rb
|
88
89
|
- lib/imap_mogura/rules_parser.rb
|
89
90
|
- lib/imap_mogura/rules_parser/errors.rb
|
@@ -97,7 +98,7 @@ licenses:
|
|
97
98
|
metadata:
|
98
99
|
homepage_uri: https://github.com/yskuniv/imap_mogura
|
99
100
|
source_code_uri: https://github.com/yskuniv/mogura
|
100
|
-
post_install_message:
|
101
|
+
post_install_message:
|
101
102
|
rdoc_options: []
|
102
103
|
require_paths:
|
103
104
|
- lib
|
@@ -113,7 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
113
114
|
version: '0'
|
114
115
|
requirements: []
|
115
116
|
rubygems_version: 3.5.22
|
116
|
-
signing_key:
|
117
|
+
signing_key:
|
117
118
|
specification_version: 4
|
118
119
|
summary: A mail filtering tool for IMAP.
|
119
120
|
test_files: []
|