mlist 0.1.20 → 0.1.21
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.
- data/Gemfile +7 -6
- data/Gemfile.lock +48 -0
- data/Rakefile +3 -4
- data/VERSION.yml +2 -2
- data/lib/mlist/mail_list.rb +12 -0
- data/lib/mlist/thread.rb +20 -20
- data/spec/models/thread_spec.rb +18 -14
- metadata +208 -8
data/Gemfile
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
source
|
1
|
+
source 'http://rubygems.org'
|
2
2
|
|
3
|
+
gem 'bundler', '>= 1.0.1'
|
3
4
|
gem 'activerecord', '= 2.3.4'
|
4
5
|
gem 'activesupport', '= 2.3.4'
|
5
6
|
gem 'uuid', '>= 2.0.1'
|
@@ -8,10 +9,10 @@ gem 'tmail', '= 1.2.1'
|
|
8
9
|
|
9
10
|
group :development do
|
10
11
|
gem 'jeweler'
|
11
|
-
gem 'dataset'
|
12
|
+
gem 'dataset', '= 1.3.2'
|
12
13
|
gem 'rake'
|
13
|
-
gem
|
14
|
-
gem
|
15
|
-
gem
|
16
|
-
gem
|
14
|
+
gem 'sqlite3-ruby'
|
15
|
+
gem 'rspec', '= 1.3.1'
|
16
|
+
gem 'rr', '0.10.0'
|
17
|
+
gem 'ruby-debug'
|
17
18
|
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
activerecord (2.3.4)
|
5
|
+
activesupport (= 2.3.4)
|
6
|
+
activesupport (2.3.4)
|
7
|
+
columnize (0.3.2)
|
8
|
+
dataset (1.3.2)
|
9
|
+
activerecord (>= 2.3.0)
|
10
|
+
activesupport (>= 2.3.0)
|
11
|
+
git (1.2.5)
|
12
|
+
hpricot (0.8.3)
|
13
|
+
jeweler (1.5.1)
|
14
|
+
bundler (~> 1.0.0)
|
15
|
+
git (>= 1.2.5)
|
16
|
+
rake
|
17
|
+
linecache (0.43)
|
18
|
+
macaddr (1.0.0)
|
19
|
+
rake (0.8.7)
|
20
|
+
rr (0.10.0)
|
21
|
+
rspec (1.3.1)
|
22
|
+
ruby-debug (0.10.4)
|
23
|
+
columnize (>= 0.1)
|
24
|
+
ruby-debug-base (~> 0.10.4.0)
|
25
|
+
ruby-debug-base (0.10.4)
|
26
|
+
linecache (>= 0.3)
|
27
|
+
sqlite3-ruby (1.3.2)
|
28
|
+
tmail (1.2.1)
|
29
|
+
uuid (2.3.1)
|
30
|
+
macaddr (~> 1.0)
|
31
|
+
|
32
|
+
PLATFORMS
|
33
|
+
ruby
|
34
|
+
|
35
|
+
DEPENDENCIES
|
36
|
+
activerecord (= 2.3.4)
|
37
|
+
activesupport (= 2.3.4)
|
38
|
+
bundler (>= 1.0.1)
|
39
|
+
dataset (= 1.3.2)
|
40
|
+
hpricot (>= 0.8.2)
|
41
|
+
jeweler
|
42
|
+
rake
|
43
|
+
rr (= 0.10.0)
|
44
|
+
rspec (= 1.3.1)
|
45
|
+
ruby-debug
|
46
|
+
sqlite3-ruby
|
47
|
+
tmail (= 1.2.1)
|
48
|
+
uuid (>= 2.0.1)
|
data/Rakefile
CHANGED
@@ -1,6 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require "bundler"
|
3
|
-
Bundler.setup
|
1
|
+
require "rubygems"
|
2
|
+
require "bundler/setup"
|
4
3
|
|
5
4
|
require 'spec/rake/spectask'
|
6
5
|
|
@@ -26,4 +25,4 @@ begin
|
|
26
25
|
Jeweler::GemcutterTasks.new
|
27
26
|
rescue LoadError
|
28
27
|
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
29
|
-
end
|
28
|
+
end
|
data/VERSION.yml
CHANGED
data/lib/mlist/mail_list.rb
CHANGED
@@ -24,8 +24,20 @@ module MList
|
|
24
24
|
|
25
25
|
belongs_to :manager_list, :polymorphic => true
|
26
26
|
|
27
|
+
# Deletes any Email records that exist for this MailList. While this could
|
28
|
+
# be done by loading each Message, we do it here to make things go a bit
|
29
|
+
# faster.
|
30
|
+
#
|
27
31
|
before_destroy :delete_unreferenced_email
|
32
|
+
|
33
|
+
# Answers the Messages that belong to this MailList. delete_all can be used
|
34
|
+
# for dependents because delete_unreferenced_email will clean up Email
|
35
|
+
# instances that are only referenced by Messages in this MailList.
|
36
|
+
#
|
28
37
|
has_many :messages, :class_name => 'MList::Message', :dependent => :delete_all
|
38
|
+
|
39
|
+
# Answers the Threads that belong to this MailList.
|
40
|
+
#
|
29
41
|
has_many :threads, :class_name => 'MList::Thread', :dependent => :delete_all
|
30
42
|
|
31
43
|
delegate :address, :label, :post_url, :to => :list
|
data/lib/mlist/thread.rb
CHANGED
@@ -1,32 +1,32 @@
|
|
1
1
|
module MList
|
2
2
|
class Thread < ActiveRecord::Base
|
3
3
|
set_table_name 'mlist_threads'
|
4
|
-
|
4
|
+
|
5
5
|
belongs_to :mail_list, :class_name => 'MList::MailList', :counter_cache => :threads_count
|
6
|
-
has_many :messages, :class_name => 'MList::Message', :dependent => :
|
7
|
-
|
6
|
+
has_many :messages, :class_name => 'MList::Message', :dependent => :destroy
|
7
|
+
|
8
8
|
def first?(message)
|
9
9
|
tree_order.first == message
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
def last?(message)
|
13
13
|
tree_order.last == message
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
def next(message)
|
17
17
|
i = tree_order.index(message)
|
18
18
|
tree_order[i + 1] unless messages.size < i
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
def previous(message)
|
22
22
|
i = tree_order.index(message)
|
23
23
|
tree_order[i - 1] if i > 0
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
def subject
|
27
27
|
messages.first.subject
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
# Answers a tree of messages.
|
31
31
|
#
|
32
32
|
# The nodes of the tree are decorated to act like a linked list, providing
|
@@ -37,26 +37,26 @@ module MList
|
|
37
37
|
build_tree unless @tree
|
38
38
|
@tree
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
41
|
def tree_order
|
42
42
|
build_tree unless @tree
|
43
43
|
@tree_order
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
private
|
47
47
|
def build_tree
|
48
48
|
nodes = messages.collect do |m|
|
49
49
|
m.parent = messages.detect {|pm| pm.id == m.parent_id}
|
50
50
|
Node.new(m)
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
nodes.each do |node|
|
54
54
|
if parent_node = nodes.detect {|n| n == node.parent}
|
55
55
|
node.parent_node = parent_node
|
56
56
|
parent_node.children << node
|
57
57
|
end
|
58
58
|
end
|
59
|
-
|
59
|
+
|
60
60
|
@tree_order = []
|
61
61
|
previous_node = nil
|
62
62
|
nodes.first.visit do |node|
|
@@ -67,32 +67,32 @@ module MList
|
|
67
67
|
end
|
68
68
|
previous_node = node
|
69
69
|
end
|
70
|
-
|
70
|
+
|
71
71
|
@tree = @tree_order.first
|
72
72
|
end
|
73
|
-
|
73
|
+
|
74
74
|
class Node < DelegateClass(Message)
|
75
75
|
attr_accessor :parent_node, :previous, :next
|
76
76
|
attr_reader :children
|
77
|
-
|
77
|
+
|
78
78
|
def initialize(message)
|
79
79
|
super
|
80
80
|
@children = []
|
81
81
|
end
|
82
|
-
|
82
|
+
|
83
83
|
def leaf?
|
84
84
|
children.empty?
|
85
85
|
end
|
86
|
-
|
86
|
+
|
87
87
|
def root?
|
88
88
|
parent_node.nil?
|
89
89
|
end
|
90
|
-
|
90
|
+
|
91
91
|
def visit(&visitor)
|
92
92
|
visitor.call self
|
93
93
|
children.each {|c| c.visit(&visitor)}
|
94
94
|
end
|
95
95
|
end
|
96
|
-
|
96
|
+
|
97
97
|
end
|
98
|
-
end
|
98
|
+
end
|
data/spec/models/thread_spec.rb
CHANGED
@@ -6,15 +6,19 @@ describe MList::Thread do
|
|
6
6
|
@thread = MList::Thread.new
|
7
7
|
stub(@thread).messages {@messages}
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
it 'should answer subject by way of the first message' do
|
11
11
|
@thread.subject.should == '1'
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
it 'should have messages counted' do
|
15
15
|
MList::Message.reflect_on_association(:thread).counter_cache_column.should == :messages_count
|
16
16
|
MList::Thread.column_names.should include('messages_count')
|
17
17
|
end
|
18
|
+
|
19
|
+
it 'should destroy dependent messages, so that they may clean up email' do
|
20
|
+
MList::Thread.reflections[:messages].options[:dependent].should == :destroy
|
21
|
+
end
|
18
22
|
end
|
19
23
|
|
20
24
|
describe MList::Thread, 'tree' do
|
@@ -24,21 +28,21 @@ describe MList::Thread, 'tree' do
|
|
24
28
|
@messages[2].parent_id = @messages[1].id
|
25
29
|
@messages[3].parent_id = @messages[0].id
|
26
30
|
@messages[4].parent_id = @messages[3].id
|
27
|
-
|
31
|
+
|
28
32
|
@thread = MList::Thread.new
|
29
33
|
stub(@thread).messages {@messages}
|
30
|
-
|
34
|
+
|
31
35
|
@tree = @thread.tree
|
32
36
|
end
|
33
|
-
|
37
|
+
|
34
38
|
it 'should answer the first message as the root of the tree' do
|
35
39
|
@tree.should == @messages[0]
|
36
40
|
end
|
37
|
-
|
41
|
+
|
38
42
|
it 'should connect the nodes into a tree' do
|
39
43
|
@tree.children.should == [@messages[1], @messages[3]]
|
40
44
|
end
|
41
|
-
|
45
|
+
|
42
46
|
it 'should connect next and previous to each node' do
|
43
47
|
@tree.previous.should be_nil
|
44
48
|
@tree.next.should == @messages[1]
|
@@ -46,38 +50,38 @@ describe MList::Thread, 'tree' do
|
|
46
50
|
@tree.next.next.should == @messages[2]
|
47
51
|
@tree.next.next.next.should == @messages[3]
|
48
52
|
end
|
49
|
-
|
53
|
+
|
50
54
|
it 'should know if a message is the root' do
|
51
55
|
@tree.root?.should be_true
|
52
56
|
@tree.next.root?.should be_false
|
53
57
|
end
|
54
|
-
|
58
|
+
|
55
59
|
it 'should know if a message is a leaf' do
|
56
60
|
@tree.leaf?.should be_false
|
57
61
|
@tree.next.leaf?.should be_false
|
58
62
|
@tree.next.next.leaf?.should be_true
|
59
63
|
end
|
60
|
-
|
64
|
+
|
61
65
|
it 'should answer when a message is last in the thread' do
|
62
66
|
@thread.first?(@messages[0]).should be_true
|
63
67
|
@thread.first?(@messages[1]).should be_false
|
64
68
|
@thread.first?(@messages[2]).should be_false
|
65
69
|
end
|
66
|
-
|
70
|
+
|
67
71
|
it 'should answer when a message is last in the thread' do
|
68
72
|
@thread.last?(@messages[0]).should be_false
|
69
73
|
@thread.last?(@messages[1]).should be_false
|
70
74
|
@thread.last?(@messages[4]).should be_true
|
71
75
|
end
|
72
|
-
|
76
|
+
|
73
77
|
it 'should answer the message next to given' do
|
74
78
|
@thread.next(@messages[0]).should == @messages[1]
|
75
79
|
@thread.next(@messages[2]).should == @messages[3]
|
76
80
|
@thread.next(@messages[4]).should be_nil
|
77
81
|
end
|
78
|
-
|
82
|
+
|
79
83
|
it 'should answer the message previous to given' do
|
80
84
|
@thread.previous(@messages[0]).should be_nil
|
81
85
|
@thread.previous(@messages[2]).should == @messages[1]
|
82
86
|
end
|
83
|
-
end
|
87
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mlist
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 49
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 21
|
10
|
+
version: 0.1.21
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Adam Williams
|
@@ -15,10 +15,209 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-11-15 00:00:00 -05:00
|
19
19
|
default_executable:
|
20
|
-
dependencies:
|
21
|
-
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 21
|
30
|
+
segments:
|
31
|
+
- 1
|
32
|
+
- 0
|
33
|
+
- 1
|
34
|
+
version: 1.0.1
|
35
|
+
name: bundler
|
36
|
+
requirement: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - "="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 11
|
46
|
+
segments:
|
47
|
+
- 2
|
48
|
+
- 3
|
49
|
+
- 4
|
50
|
+
version: 2.3.4
|
51
|
+
name: activerecord
|
52
|
+
requirement: *id002
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - "="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
hash: 11
|
62
|
+
segments:
|
63
|
+
- 2
|
64
|
+
- 3
|
65
|
+
- 4
|
66
|
+
version: 2.3.4
|
67
|
+
name: activesupport
|
68
|
+
requirement: *id003
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
hash: 13
|
78
|
+
segments:
|
79
|
+
- 2
|
80
|
+
- 0
|
81
|
+
- 1
|
82
|
+
version: 2.0.1
|
83
|
+
name: uuid
|
84
|
+
requirement: *id004
|
85
|
+
- !ruby/object:Gem::Dependency
|
86
|
+
type: :runtime
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
hash: 59
|
94
|
+
segments:
|
95
|
+
- 0
|
96
|
+
- 8
|
97
|
+
- 2
|
98
|
+
version: 0.8.2
|
99
|
+
name: hpricot
|
100
|
+
requirement: *id005
|
101
|
+
- !ruby/object:Gem::Dependency
|
102
|
+
type: :runtime
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: &id006 !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - "="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
hash: 29
|
110
|
+
segments:
|
111
|
+
- 1
|
112
|
+
- 2
|
113
|
+
- 1
|
114
|
+
version: 1.2.1
|
115
|
+
name: tmail
|
116
|
+
requirement: *id006
|
117
|
+
- !ruby/object:Gem::Dependency
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: &id007 !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
hash: 3
|
126
|
+
segments:
|
127
|
+
- 0
|
128
|
+
version: "0"
|
129
|
+
name: jeweler
|
130
|
+
requirement: *id007
|
131
|
+
- !ruby/object:Gem::Dependency
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: &id008 !ruby/object:Gem::Requirement
|
135
|
+
none: false
|
136
|
+
requirements:
|
137
|
+
- - "="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
hash: 31
|
140
|
+
segments:
|
141
|
+
- 1
|
142
|
+
- 3
|
143
|
+
- 2
|
144
|
+
version: 1.3.2
|
145
|
+
name: dataset
|
146
|
+
requirement: *id008
|
147
|
+
- !ruby/object:Gem::Dependency
|
148
|
+
type: :development
|
149
|
+
prerelease: false
|
150
|
+
version_requirements: &id009 !ruby/object:Gem::Requirement
|
151
|
+
none: false
|
152
|
+
requirements:
|
153
|
+
- - ">="
|
154
|
+
- !ruby/object:Gem::Version
|
155
|
+
hash: 3
|
156
|
+
segments:
|
157
|
+
- 0
|
158
|
+
version: "0"
|
159
|
+
name: rake
|
160
|
+
requirement: *id009
|
161
|
+
- !ruby/object:Gem::Dependency
|
162
|
+
type: :development
|
163
|
+
prerelease: false
|
164
|
+
version_requirements: &id010 !ruby/object:Gem::Requirement
|
165
|
+
none: false
|
166
|
+
requirements:
|
167
|
+
- - ">="
|
168
|
+
- !ruby/object:Gem::Version
|
169
|
+
hash: 3
|
170
|
+
segments:
|
171
|
+
- 0
|
172
|
+
version: "0"
|
173
|
+
name: sqlite3-ruby
|
174
|
+
requirement: *id010
|
175
|
+
- !ruby/object:Gem::Dependency
|
176
|
+
type: :development
|
177
|
+
prerelease: false
|
178
|
+
version_requirements: &id011 !ruby/object:Gem::Requirement
|
179
|
+
none: false
|
180
|
+
requirements:
|
181
|
+
- - "="
|
182
|
+
- !ruby/object:Gem::Version
|
183
|
+
hash: 25
|
184
|
+
segments:
|
185
|
+
- 1
|
186
|
+
- 3
|
187
|
+
- 1
|
188
|
+
version: 1.3.1
|
189
|
+
name: rspec
|
190
|
+
requirement: *id011
|
191
|
+
- !ruby/object:Gem::Dependency
|
192
|
+
type: :development
|
193
|
+
prerelease: false
|
194
|
+
version_requirements: &id012 !ruby/object:Gem::Requirement
|
195
|
+
none: false
|
196
|
+
requirements:
|
197
|
+
- - "="
|
198
|
+
- !ruby/object:Gem::Version
|
199
|
+
hash: 55
|
200
|
+
segments:
|
201
|
+
- 0
|
202
|
+
- 10
|
203
|
+
- 0
|
204
|
+
version: 0.10.0
|
205
|
+
name: rr
|
206
|
+
requirement: *id012
|
207
|
+
- !ruby/object:Gem::Dependency
|
208
|
+
type: :development
|
209
|
+
prerelease: false
|
210
|
+
version_requirements: &id013 !ruby/object:Gem::Requirement
|
211
|
+
none: false
|
212
|
+
requirements:
|
213
|
+
- - ">="
|
214
|
+
- !ruby/object:Gem::Version
|
215
|
+
hash: 3
|
216
|
+
segments:
|
217
|
+
- 0
|
218
|
+
version: "0"
|
219
|
+
name: ruby-debug
|
220
|
+
requirement: *id013
|
22
221
|
description: A Ruby mailing list library designed to be integrated into other applications.
|
23
222
|
email: adam@thewilliams.ws
|
24
223
|
executables: []
|
@@ -31,6 +230,7 @@ extra_rdoc_files:
|
|
31
230
|
files:
|
32
231
|
- CHANGELOG
|
33
232
|
- Gemfile
|
233
|
+
- Gemfile.lock
|
34
234
|
- README
|
35
235
|
- Rakefile
|
36
236
|
- TODO
|
@@ -86,8 +286,8 @@ homepage: http://github.com/aiwilliams/mlist
|
|
86
286
|
licenses: []
|
87
287
|
|
88
288
|
post_install_message:
|
89
|
-
rdoc_options:
|
90
|
-
|
289
|
+
rdoc_options: []
|
290
|
+
|
91
291
|
require_paths:
|
92
292
|
- lib
|
93
293
|
required_ruby_version: !ruby/object:Gem::Requirement
|