|
1 #!/usr/bin/ruby |
|
2 # vim: set nosta noet ts=4 sw=4: |
|
3 # |
|
4 # A collection of messages for a specific archive thread. |
|
5 # |
|
6 # thread = Ezmlm::List::Thread.new( list, 'acgcbmbmeapgpfckcdol' ) |
|
7 # thread.subject #=> "Help - navigate on interface?" |
|
8 # thread.first.date.to_s #=> "2017-05-07T14:55:05-07:00" |
|
9 # |
|
10 # |
|
11 # == Version |
|
12 # |
|
13 # $Id$ |
|
14 # |
|
15 #--- |
|
16 |
|
17 require 'pathname' |
|
18 require 'ezmlm' unless defined?( Ezmlm ) |
|
19 |
|
20 |
|
21 ### A collection of messages for a specific archive thread. |
|
22 ### |
|
23 class Ezmlm::List::Thread |
|
24 include Enumerable |
|
25 |
|
26 ### Instantiate a new thread of messages given |
|
27 ### a +list+ and a +thread_id+. |
|
28 ### |
|
29 def initialize( list, thread_id ) |
|
30 raise ArgumentError, "Unknown list object." unless list.respond_to?( :listdir ) |
|
31 raise ArgumentError, "Malformed Thread ID." unless thread_id =~ /^\w{20}$/ |
|
32 raise "Thread indexing is not enabled." unless list.threaded? |
|
33 |
|
34 @list = list |
|
35 @id = thread_id |
|
36 @subject = nil |
|
37 @messages = nil |
|
38 |
|
39 self.load_thread |
|
40 end |
|
41 |
|
42 |
|
43 # The list object this message is stored in. |
|
44 attr_reader :list |
|
45 |
|
46 # The thread's identifier. |
|
47 attr_reader :id |
|
48 |
|
49 # The subject line of the thread. |
|
50 attr_reader :subject |
|
51 |
|
52 # An array of member messages. |
|
53 attr_reader :messages |
|
54 |
|
55 # An array of member authors. |
|
56 attr_reader :authors |
|
57 |
|
58 |
|
59 ### Enumerable API: Lazy load each message ID as a |
|
60 ### Ezmlm::List::Message, yielding it to the block. |
|
61 ### |
|
62 def each |
|
63 self.load_thread # refresh for any thread updates since object was created |
|
64 self.messages.each do |id| |
|
65 yield Ezmlm::List::Message.new( self.list, id ) |
|
66 end |
|
67 end |
|
68 |
|
69 |
|
70 ######### |
|
71 protected |
|
72 ######### |
|
73 |
|
74 ### Parse the subject index into an array of Messages. |
|
75 ### |
|
76 def load_thread |
|
77 @messages = [] |
|
78 @authors = [] |
|
79 path = self.thread_path |
|
80 raise "Unknown thread: %p" % [ self.id ] unless path.exist? |
|
81 |
|
82 path.each_line.with_index do |line, i| |
|
83 if i.zero? |
|
84 @subject = line.match( /^\w+ (.+)/ )[1] |
|
85 else |
|
86 match = line.match( /^(\d+):\d+:(\w+) / ) or next |
|
87 self.messages << match[1].to_i |
|
88 self.authors << match[2] |
|
89 end |
|
90 end |
|
91 end |
|
92 |
|
93 |
|
94 ### Return the path on disk for the thread index. |
|
95 ### |
|
96 def thread_path |
|
97 prefix = self.id[ 0 .. 1 ] |
|
98 hash = self.id[ 2 .. -1 ] |
|
99 return self.list.listdir + 'archive' + 'subjects' + prefix + hash |
|
100 end |
|
101 |
|
102 end # class Ezmlm::List::Thread |