imap.rb 0.7.0 → 0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f9f5b0c607f3b3e66d7284613916d45c077de9a0e97f50f960fa8e63fd7b5586
4
- data.tar.gz: 4529940cbd85a56bfbd4ef9d472536234852cd4cabf6349f90763644905ab953
3
+ metadata.gz: 45cf03dcb336e9795a5ef5339e6ac0c6e3b2f5e79014f3462684f39f79aae98f
4
+ data.tar.gz: e204d83b456b966f0f9a9c3a55acfb492564da65a2b2be22d8c27326104ba755
5
5
  SHA512:
6
- metadata.gz: 7279ae1bb4fd2456fa2acf57cad565a0af28d2be5795e1e6bf9924b2b9f6583acf2e4a71735944c8bf3f3dc56d403d3abba5943eb87ea15054f12c718665bab9
7
- data.tar.gz: 060c6a1b974e983979130cf62d03e0630ef548b64b9e80a522c6064c031126385de84f762cb1a158fd50b03711902f1430038b8aa0b3f63864c7dc4e85366548
6
+ metadata.gz: 20938befdd15cc9da7f5679b0043facbdbc0d3a69b04f93a0100c43b4314b6832ecfed375484d1429221ee60703dfc94ac3abdd1f4ff40060ed528828187fcf4
7
+ data.tar.gz: e467e3aed0b2b09cc86e175a1b3f940e37922232e4efb97998c5dc7a959b5a3f9b8f012bb1a8ff6505d7dff83f488e418c5e7d8670fe5b4db7333991ff683d77
data/CHANGELOG CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  ## 20260917
4
4
 
5
+ 0.8.0: + Imap::Message.for, the fetch without the search, and a class a program can subclass.
6
+
7
+ 1. + Imap::Message.for(imap_client, message_ids): the batched fetch on its own, .search now being the search and then this. A program which builds its own search keys had no way in: .search couples the two, so search-mail had 159 lines of its own Hit reimplementing the fetch beside it.
8
+ 2. ~ Imap::Message.for: builds with new rather than Imap::Message.new, so that a subclass is handed back its own kind. A program which wants a message of its own, with a mailbox or a decoded body upon it, subclasses rather than starts again.
9
+ 3. + 4 tests: that .for builds for ids searched elsewhere, that it fetches once, that it is empty where nothing was found, and that a subclass gets itself back.
10
+ 4. ~ Imap::VERSION: /0.7.0/0.8.0/
11
+
5
12
  0.7.0: ~ Imap::Message: + #uid, #flags, #seen?, #size, #received_at, #sent_at, #cc, #from_address, #from_domain, #attachment?, #attachment_filenames, #source, .decode; + Imap#mailboxes
6
13
 
7
14
  1. + Imap::Message#uid, #flags, #seen?, #size, #received_at, #sent_at, #cc, #from_address, #from_domain, #attachment?, #attachment_filenames, #source. Everything a search had to go around the gem to Net::IMAP for.
data/lib/Imap/Message.rb CHANGED
@@ -3,16 +3,17 @@
3
3
 
4
4
  # Usage:
5
5
  # 1. Imap::Message.search(imap_client, {from: 'noreply@example.com'})
6
- # 2. Imap::Message.new(message_id, imap_client)
7
- # 3. Imap::Message.new(message_id, imap_client).body
8
- # 4. Imap::Message.new(message_id, imap_client).urls
9
- # 5. Imap::Message.new(message_id, imap_client).mark_as_read
10
- # 6. Imap::Message.new(message_id, imap_client).subject
11
- # 7. Imap::Message.new(message_id, imap_client).from
12
- # 8. Imap::Message.new(message_id, imap_client).to
13
- # 9. Imap::Message.new(message_id, imap_client).received_at
14
- # 10. Imap::Message.new(message_id, imap_client).attachment_filenames
15
- # 11. Imap::Message.new(message_id, imap_client).source
6
+ # 2. Imap::Message.for(imap_client, imap_client.imap.search(['ALL']))
7
+ # 3. Imap::Message.new(message_id, imap_client)
8
+ # 4. Imap::Message.new(message_id, imap_client).body
9
+ # 5. Imap::Message.new(message_id, imap_client).urls
10
+ # 6. Imap::Message.new(message_id, imap_client).mark_as_read
11
+ # 7. Imap::Message.new(message_id, imap_client).subject
12
+ # 8. Imap::Message.new(message_id, imap_client).from
13
+ # 9. Imap::Message.new(message_id, imap_client).to
14
+ # 10. Imap::Message.new(message_id, imap_client).received_at
15
+ # 11. Imap::Message.new(message_id, imap_client).attachment_filenames
16
+ # 12. Imap::Message.new(message_id, imap_client).source
16
17
 
17
18
  require 'time'
18
19
 
@@ -29,18 +30,23 @@ class Imap
29
30
 
30
31
  class << self
31
32
 
33
+ def search(imap_client, **search_criteria)
34
+ self.for(imap_client, Imap::Search.new(imap_client, search_criteria).message_ids)
35
+ end
36
+ alias_method :find, :search
37
+
32
38
  # One fetch for a slice of messages rather than one per attribute per
33
39
  # message. A hundred messages cost a round trip apiece for the subject and
34
40
  # another apiece for the from; they cost one for the hundred now.
35
- def search(imap_client, **search_criteria)
36
- message_ids = Imap::Search.new(imap_client, search_criteria).message_ids
41
+ #
42
+ # new and not Imap::Message.new, so that a subclass gets its own kind back.
43
+ def for(imap_client, message_ids)
37
44
  message_ids.each_slice(SLICE).flat_map do |slice|
38
45
  imap_client.imap.fetch(slice, FETCH_ATTRIBUTES).collect do |data|
39
- Imap::Message.new(data.seqno, imap_client, data)
46
+ new(data.seqno, imap_client, data)
40
47
  end
41
48
  end
42
49
  end
43
- alias_method :find, :search
44
50
 
45
51
  # RFC 2047: =?charset?B?base64?= and =?charset?Q?quoted-printable?=, which
46
52
  # headers carry wherever the subject or a name is not ASCII.
data/lib/Imap/VERSION.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class Imap
2
- VERSION = '0.7.0'
2
+ VERSION = '0.8.0'
3
3
  end
@@ -30,6 +30,29 @@ describe Imap::Message do
30
30
  end
31
31
  end
32
32
 
33
+ describe '.for' do
34
+ it 'builds messages for ids the caller searched for itself' do
35
+ messages = Imap::Message.for(client, [1, 2, 3])
36
+ _(messages.size).must_equal 3
37
+ _(messages.first).must_be_instance_of Imap::Message
38
+ _(messages.first.subject).must_match(/Mock Subject/)
39
+ end
40
+
41
+ it 'fetches once for the whole slice' do
42
+ Imap::Message.for(client, [1, 2, 3])
43
+ _(client.imap.fetch_count).must_equal 1
44
+ end
45
+
46
+ it 'is empty where nothing was found' do
47
+ _(Imap::Message.for(client, [])).must_equal []
48
+ end
49
+
50
+ it 'gives a subclass back its own kind' do
51
+ hit = Class.new(Imap::Message)
52
+ _(hit.for(client, [1]).first).must_be_instance_of hit
53
+ end
54
+ end
55
+
33
56
  describe 'the batched fetch' do
34
57
  it 'fetches once for the whole slice rather than once per message' do
35
58
  messages = Imap::Message.search(client, from: 'test@example.com')
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: imap.rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - thoran