imap_processor 1.7 → 1.8.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
- checksums.yaml.gz.sig +0 -0
- data/History.rdoc +15 -1
- data/Manifest.txt +2 -0
- data/bin/imap_tidy +5 -0
- data/lib/imap_processor/archive.rb +1 -7
- data/lib/imap_processor/tidy.rb +106 -0
- data/lib/imap_processor.rb +14 -4
- data/lib/net/imap/date.rb +26 -4
- data.tar.gz.sig +2 -2
- metadata +19 -16
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ce222f1cb8f32b1db12c7d73f70df7651435e2a2a84c0a6a50bd22dc3a07d8b5
|
4
|
+
data.tar.gz: 6bc68677e713f0d6414995ef51861166d3316131b6ada39c4e506f2fba4c6b7c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 07f96e7acb7aae8846b6f5c95c8abf4ac981f0ca0ea18506c0d596380fd57687d40b5bddaca06fd8b2383484c1d8da42596e3a93c1558195d111ab396ac1893f
|
7
|
+
data.tar.gz: 2c869d58045ea7b20916ee5b7f65570af46e1938dc4034e20ab2d9ae11557ea58d9b4a9e568c0e6d35b6c418fbdfb4b681e5bed18b34bc6d02c7f8cb5b4a4c4f
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/History.rdoc
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
=== 1.8.0 / 2023-01-09
|
2
|
+
|
3
|
+
* 1 major enhancement:
|
4
|
+
|
5
|
+
* Added imap_tidy, a hybrid between cleanse and archive.
|
6
|
+
|
7
|
+
* 1 minor enhancement:
|
8
|
+
|
9
|
+
* Added Time.imapdate(s), Time.imapdatetime(s), and #yyyy_mm.
|
10
|
+
|
11
|
+
* 2 bug fixes:
|
12
|
+
|
13
|
+
* Fixes for net/imap changes in ruby 3.x.
|
14
|
+
* Removed unused last_month from IMAPProcessor::Archive
|
15
|
+
|
1
16
|
=== 1.7 / 2020-06-04
|
2
17
|
|
3
18
|
* 4 minor enhancements:
|
@@ -100,4 +115,3 @@
|
|
100
115
|
|
101
116
|
* 1 major enhancement
|
102
117
|
* Birthday!
|
103
|
-
|
data/Manifest.txt
CHANGED
@@ -10,6 +10,7 @@ bin/imap_idle
|
|
10
10
|
bin/imap_keywords
|
11
11
|
bin/imap_learn
|
12
12
|
bin/imap_mkdir
|
13
|
+
bin/imap_tidy
|
13
14
|
lib/imap_processor.rb
|
14
15
|
lib/imap_processor/archive.rb
|
15
16
|
lib/imap_processor/cleanse.rb
|
@@ -19,6 +20,7 @@ lib/imap_processor/idle.rb
|
|
19
20
|
lib/imap_processor/keywords.rb
|
20
21
|
lib/imap_processor/learn.rb
|
21
22
|
lib/imap_processor/mkdir.rb
|
23
|
+
lib/imap_processor/tidy.rb
|
22
24
|
lib/imap_sasl_plain.rb
|
23
25
|
lib/net/imap/date.rb
|
24
26
|
lib/net/imap/idle.rb
|
data/bin/imap_tidy
ADDED
@@ -60,11 +60,6 @@ imap_archive archives old mail on IMAP server by moving it to dated mailboxen.
|
|
60
60
|
Time.local(t.year, t.month, 1)
|
61
61
|
end
|
62
62
|
|
63
|
-
def last_month
|
64
|
-
t = the_first - 1
|
65
|
-
Time.local(t.year, t.month, 1).strftime("%Y-%m")
|
66
|
-
end
|
67
|
-
|
68
63
|
##
|
69
64
|
# Makes a SEARCH argument set from +keywords+
|
70
65
|
|
@@ -82,8 +77,7 @@ imap_archive archives old mail on IMAP server by moving it to dated mailboxen.
|
|
82
77
|
next if uids_by_date.empty?
|
83
78
|
|
84
79
|
unless split then
|
85
|
-
|
86
|
-
d = today - 86400 * today.day
|
80
|
+
d = the_first - 1 # one second back into last month
|
87
81
|
latest = [d.year, d.month]
|
88
82
|
|
89
83
|
uids_by_date = {
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require "imap_processor"
|
2
|
+
require "net/imap/date"
|
3
|
+
|
4
|
+
##
|
5
|
+
# Whereas Archive moves all mail before this month into a dated mailbox, and
|
6
|
+
# whereas Cleanse deletes all read unflagged mail over N days old,
|
7
|
+
# Tidy moves all read unflagged mail into a dated mailbox.
|
8
|
+
#
|
9
|
+
# It's somewhere in-between Archive and Cleanse in that it is used for
|
10
|
+
# mail you want to keep, but also keep out of the way of your active
|
11
|
+
# inbox.
|
12
|
+
|
13
|
+
class IMAPProcessor::Tidy < IMAPProcessor
|
14
|
+
|
15
|
+
##
|
16
|
+
# Whether to move the mail or just display. default:false
|
17
|
+
|
18
|
+
attr_accessor :move
|
19
|
+
|
20
|
+
def self.process_args args # :nodoc:
|
21
|
+
required_options = {
|
22
|
+
:move => false,
|
23
|
+
}
|
24
|
+
|
25
|
+
super __FILE__, args, required_options do |opts, options|
|
26
|
+
opts.banner << <<~EOF
|
27
|
+
imap_tidy moves older messages from your mailboxen into dated mailboxen.
|
28
|
+
EOF
|
29
|
+
|
30
|
+
opts.on "--days=N", Integer, "Override age to move messages" do |n|
|
31
|
+
options[:age] = n
|
32
|
+
end
|
33
|
+
|
34
|
+
opts.on "--[no-]move", "Move the messages (off by default)" do |move|
|
35
|
+
options[:move] = move
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def initialize options # :nodoc:
|
41
|
+
super
|
42
|
+
|
43
|
+
log "Tidy: #{options[:Host]}"
|
44
|
+
|
45
|
+
self.move = options[:move]
|
46
|
+
|
47
|
+
connection = connect
|
48
|
+
|
49
|
+
@imap = connection.imap
|
50
|
+
end
|
51
|
+
|
52
|
+
##
|
53
|
+
# Select a mailbox
|
54
|
+
# TODO: push up
|
55
|
+
|
56
|
+
def select mailbox
|
57
|
+
log "SELECT #{mailbox}"
|
58
|
+
imap.select mailbox
|
59
|
+
end
|
60
|
+
|
61
|
+
##
|
62
|
+
# Search a selected mailbox with +args+
|
63
|
+
# TODO: push up
|
64
|
+
|
65
|
+
def search args
|
66
|
+
log "SEARCH #{args.join " "}"
|
67
|
+
imap.search args
|
68
|
+
end
|
69
|
+
|
70
|
+
def uids_to_dates uids
|
71
|
+
imap
|
72
|
+
.fetch(uids, "INTERNALDATE")
|
73
|
+
.to_h { |fd| [fd.seqno, Time.imapdate(fd.attr["INTERNALDATE"]).yyyy_mm] }
|
74
|
+
end
|
75
|
+
|
76
|
+
def run
|
77
|
+
@boxes.each do |mailbox, days_old|
|
78
|
+
select mailbox
|
79
|
+
|
80
|
+
before_date = Time.now - 86_400 * (options[:age] || days_old)
|
81
|
+
uids = search %W[SEEN UNFLAGGED BEFORE #{before_date.imapdate}]
|
82
|
+
|
83
|
+
next if uids.empty?
|
84
|
+
|
85
|
+
log "FOUND %p" % [uids]
|
86
|
+
|
87
|
+
uids_to_dates(uids) # id => "YYYY-MM"
|
88
|
+
.multi_invert # "YYYY-MM" => [id,...]
|
89
|
+
.sort
|
90
|
+
.each do |date, uids|
|
91
|
+
destination = "%s-%s" % [mailbox, date]
|
92
|
+
show_messages uids
|
93
|
+
move_messages uids, destination, false if move
|
94
|
+
end
|
95
|
+
|
96
|
+
log "EXPUNGE"
|
97
|
+
imap.expunge if move unless noop?
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
class Hash
|
103
|
+
def multi_invert
|
104
|
+
keys.group_by { |k| self[k] }.to_h
|
105
|
+
end
|
106
|
+
end
|
data/lib/imap_processor.rb
CHANGED
@@ -5,6 +5,8 @@ require 'net/imap/date'
|
|
5
5
|
require 'imap_sasl_plain'
|
6
6
|
require 'yaml'
|
7
7
|
|
8
|
+
Net::IMAP::Authenticators.send :public, :authenticators
|
9
|
+
|
8
10
|
##
|
9
11
|
# IMAPProcessor is a client for processing messages on an IMAP server.
|
10
12
|
#
|
@@ -26,7 +28,7 @@ class IMAPProcessor
|
|
26
28
|
##
|
27
29
|
# The version of IMAPProcessor you are using
|
28
30
|
|
29
|
-
VERSION = "1.
|
31
|
+
VERSION = "1.8.0"
|
30
32
|
|
31
33
|
##
|
32
34
|
# Base IMAPProcessor error class
|
@@ -210,7 +212,7 @@ class IMAPProcessor
|
|
210
212
|
options[:Password] = password
|
211
213
|
end
|
212
214
|
|
213
|
-
authenticators = Net::IMAP.
|
215
|
+
authenticators = Net::IMAP.authenticators
|
214
216
|
auth_types = authenticators.keys.sort.join ', '
|
215
217
|
opts.on("-a", "--auth AUTH", auth_types,
|
216
218
|
"IMAP authentication type override",
|
@@ -351,7 +353,14 @@ Example ~/.#{@@opts_file_name}:
|
|
351
353
|
data = res.data
|
352
354
|
|
353
355
|
if data.code and data.code.name == 'CAPABILITY' then
|
354
|
-
data.code.data
|
356
|
+
case data.code.data
|
357
|
+
when Array then
|
358
|
+
data.code.data
|
359
|
+
when String then
|
360
|
+
data.code.data.split ' '
|
361
|
+
else
|
362
|
+
raise ArgumentError, "unknown type: #{data.code.data.class}"
|
363
|
+
end
|
355
364
|
else
|
356
365
|
imap.capability
|
357
366
|
end
|
@@ -550,7 +559,8 @@ Example ~/.#{@@opts_file_name}:
|
|
550
559
|
|
551
560
|
def move_messages uids, destination, expunge = true
|
552
561
|
return if uids.empty?
|
553
|
-
|
562
|
+
verb = expunge ? "MOVE" : "COPY"
|
563
|
+
log "%s %d uids to %s:" % [verb, uids.size, destination]
|
554
564
|
|
555
565
|
begin
|
556
566
|
imap.copy uids, destination unless noop?
|
data/lib/net/imap/date.rb
CHANGED
@@ -1,11 +1,28 @@
|
|
1
|
+
require "time"
|
1
2
|
|
2
|
-
class Time
|
3
|
+
class Time # :nodoc:
|
4
|
+
IMAPDATE = "%d-%b-%Y" # :nodoc:
|
5
|
+
IMAPDATETIME = "%d-%b-%Y %H:%M %Z" # :nodoc:
|
6
|
+
|
7
|
+
##
|
8
|
+
# Parse an IMAP date formatted string into a Time.
|
9
|
+
|
10
|
+
def self.imapdate str
|
11
|
+
Time.strptime str, IMAPDATE
|
12
|
+
end
|
13
|
+
|
14
|
+
##
|
15
|
+
# Parse an IMAP datetime formatted string into a Time.
|
16
|
+
|
17
|
+
def self.imapdatetime str
|
18
|
+
Time.strptime str, IMAPDATETIME
|
19
|
+
end
|
3
20
|
|
4
21
|
##
|
5
22
|
# Formats this Time as an IMAP-style date.
|
6
23
|
|
7
24
|
def imapdate
|
8
|
-
strftime
|
25
|
+
strftime IMAPDATE
|
9
26
|
end
|
10
27
|
|
11
28
|
##
|
@@ -17,8 +34,13 @@ class Time
|
|
17
34
|
# Go Mr. Leatherpants!
|
18
35
|
|
19
36
|
def imapdatetime
|
20
|
-
strftime
|
37
|
+
strftime IMAPDATETIME
|
21
38
|
end
|
22
39
|
|
23
|
-
|
40
|
+
##
|
41
|
+
# Format a date into YYYY-MM, common for mailbox extensions.
|
24
42
|
|
43
|
+
def yyyy_mm
|
44
|
+
strftime("%Y-%m")
|
45
|
+
end
|
46
|
+
end
|
data.tar.gz.sig
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
$��q�h�n�D��ǁ��:8�����9rzV��#���� ��yz(�������ګIg,����
|
2
|
+
I5K�a�P>"4�Ql�3�r��ݣhӻ~%�嶌[���4��J���23�}����
|
metadata
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: imap_processor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Davis
|
8
8
|
- Eric Hodel
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain:
|
12
12
|
- |
|
13
13
|
-----BEGIN CERTIFICATE-----
|
14
|
-
|
14
|
+
MIIDPjCCAiagAwIBAgIBBzANBgkqhkiG9w0BAQsFADBFMRMwEQYDVQQDDApyeWFu
|
15
15
|
ZC1ydWJ5MRkwFwYKCZImiZPyLGQBGRYJemVuc3BpZGVyMRMwEQYKCZImiZPyLGQB
|
16
|
-
|
16
|
+
GRYDY29tMB4XDTIzMDEwMTA3NTExN1oXDTI0MDEwMTA3NTExN1owRTETMBEGA1UE
|
17
17
|
AwwKcnlhbmQtcnVieTEZMBcGCgmSJomT8ixkARkWCXplbnNwaWRlcjETMBEGCgmS
|
18
18
|
JomT8ixkARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALda
|
19
19
|
b9DCgK+627gPJkB6XfjZ1itoOQvpqH1EXScSaba9/S2VF22VYQbXU1xQXL/WzCkx
|
@@ -23,14 +23,14 @@ cert_chain:
|
|
23
23
|
qhtV7HJxNKuPj/JFH0D2cswvzznE/a5FOYO68g+YCuFi5L8wZuuM8zzdwjrWHqSV
|
24
24
|
gBEfoTEGr7Zii72cx+sCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAw
|
25
25
|
HQYDVR0OBBYEFEfFe9md/r/tj/Wmwpy+MI8d9k/hMA0GCSqGSIb3DQEBCwUAA4IB
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
26
|
+
AQAkg3y+PBnBAPWdxxITm5sPHqdWQgSyCpRA20o4LTuWr8BWhSXBkfQNa7cY6fOn
|
27
|
+
xyM34VPzBFbExv6XOGDfOMFBVaYTHuN9peC/5/umL7kLl+nflXzL2QA7K6LYj5Bg
|
28
|
+
sM574Onr0dZDM6Vn69bzQ7rBIFDfK/OhlPzqKZad4nsdcsVH8ODCiT+ATMIZyz5K
|
29
|
+
WCnNtqlyiWXI8tdTpahDgcUwfcN/oN7v4K8iU5IbLJX6HQ5DKgmKjfb6XyMth16k
|
30
|
+
ROfWo9Uyp8ba/j9eVG14KkYRaLydAY1MNQk2yd3R5CGfeOpD1kttxjoypoUJ2dOG
|
31
|
+
nsNBRuQJ1UfiCG97a6DNm+Fr
|
32
32
|
-----END CERTIFICATE-----
|
33
|
-
date:
|
33
|
+
date: 2023-01-09 00:00:00.000000000 Z
|
34
34
|
dependencies:
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
36
|
name: rdoc
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '4.0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '4.0'
|
69
69
|
description: |-
|
70
70
|
IMAPProcessor is a client for processing messages on an IMAP server. It
|
71
71
|
provides some basic mechanisms for connecting to an IMAP server, determining
|
@@ -92,6 +92,7 @@ executables:
|
|
92
92
|
- imap_keywords
|
93
93
|
- imap_learn
|
94
94
|
- imap_mkdir
|
95
|
+
- imap_tidy
|
95
96
|
extensions: []
|
96
97
|
extra_rdoc_files:
|
97
98
|
- History.rdoc
|
@@ -110,6 +111,7 @@ files:
|
|
110
111
|
- bin/imap_keywords
|
111
112
|
- bin/imap_learn
|
112
113
|
- bin/imap_mkdir
|
114
|
+
- bin/imap_tidy
|
113
115
|
- lib/imap_processor.rb
|
114
116
|
- lib/imap_processor/archive.rb
|
115
117
|
- lib/imap_processor/cleanse.rb
|
@@ -119,6 +121,7 @@ files:
|
|
119
121
|
- lib/imap_processor/keywords.rb
|
120
122
|
- lib/imap_processor/learn.rb
|
121
123
|
- lib/imap_processor/mkdir.rb
|
124
|
+
- lib/imap_processor/tidy.rb
|
122
125
|
- lib/imap_sasl_plain.rb
|
123
126
|
- lib/net/imap/date.rb
|
124
127
|
- lib/net/imap/idle.rb
|
@@ -128,7 +131,7 @@ licenses:
|
|
128
131
|
- MIT
|
129
132
|
metadata:
|
130
133
|
homepage_uri: https://github.com/seattlerb/imap_processor
|
131
|
-
post_install_message:
|
134
|
+
post_install_message:
|
132
135
|
rdoc_options:
|
133
136
|
- "--main"
|
134
137
|
- README.rdoc
|
@@ -145,8 +148,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
145
148
|
- !ruby/object:Gem::Version
|
146
149
|
version: '0'
|
147
150
|
requirements: []
|
148
|
-
rubygems_version: 3.
|
149
|
-
signing_key:
|
151
|
+
rubygems_version: 3.4.1
|
152
|
+
signing_key:
|
150
153
|
specification_version: 4
|
151
154
|
summary: IMAPProcessor is a client for processing messages on an IMAP server
|
152
155
|
test_files: []
|
metadata.gz.sig
CHANGED
Binary file
|