aiwilliams-mlist 0.1.0 → 0.1.1
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/README +98 -37
- data/VERSION.yml +1 -1
- data/lib/mlist/email_server/smtp.rb +1 -2
- data/lib/mlist/manager/database.rb +4 -0
- data/lib/mlist/server.rb +3 -1
- data/lib/mlist/util/header_sanitizer.rb +9 -6
- metadata +1 -1
data/README
CHANGED
@@ -1,21 +1,34 @@
|
|
1
|
-
=
|
1
|
+
= MList
|
2
2
|
|
3
3
|
http://aiwilliams.github.com/mlist
|
4
4
|
|
5
5
|
== DESCRIPTION:
|
6
6
|
|
7
|
-
An insane attempt to build a mail list server library that can be used
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
An insane attempt to build a mail list server library that can be used in other
|
8
|
+
applications very easily. The first target is Ruby applications that can load
|
9
|
+
MList models for direct, embedded integration. It will later have a RESTful API
|
10
|
+
so that any language/architecture can be easily integrated. That may depend
|
11
|
+
heavily on community involvement...
|
12
12
|
|
13
13
|
== FEATURES/PROBLEMS:
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
If you have any experience with mailing lists, things can be understood most
|
16
|
+
quickly with this: MList is the mailing list server and database, your
|
17
|
+
application is the list manager.
|
18
|
+
|
19
|
+
MList is being used in a production environment as a Ruby gem/Rails plugin. I
|
20
|
+
decided not to use other list software primarily because a) we already had a
|
21
|
+
running, sophisticated list manager that I didn't care to synchronize with
|
22
|
+
something else, b) we have an exceptional UI design for listing messages in
|
23
|
+
threads and ultimately will have search and c) integration options for the other
|
24
|
+
software looked to be a problem in themselves.
|
25
|
+
|
26
|
+
And then there's the fame and glory that comes with building something like
|
27
|
+
this...
|
28
|
+
|
29
|
+
There is a LOT to do: segmenting, i18n, backscatter - only the Mailman developers
|
30
|
+
know what else. I have enough experience to know that rewrites are NEVER as easy
|
31
|
+
as they seem. Alas, I go boldly forward.
|
19
32
|
|
20
33
|
==== Extracting 'from' IP address from emails is not implemented
|
21
34
|
|
@@ -29,9 +42,9 @@ required once at initialization, there will always only be one instance of the
|
|
29
42
|
model class, and therefore, many instances of the observer class (all but the
|
30
43
|
most recent invalid, since they were undefined) registered with it.
|
31
44
|
|
32
|
-
There are a number of ways to solve this, the best being the one that makes
|
33
|
-
'just work' such that I can delete this part of the document. For now, do
|
34
|
-
following in environment.rb:
|
45
|
+
There are a number of ways to solve this, the best being the one that makes
|
46
|
+
things 'just work' such that I can delete this part of the document. For now, do
|
47
|
+
the following in environment.rb:
|
35
48
|
|
36
49
|
* remove the observer from the Rails' config.active_record.observers list
|
37
50
|
* after the Rails::Initializer.run block, "require 'myobserver'"
|
@@ -42,11 +55,11 @@ class you are observing.
|
|
42
55
|
|
43
56
|
== SYNOPSIS:
|
44
57
|
|
45
|
-
Let's say you want your web application to have a mailing list feature.
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
58
|
+
Let's say you want your web application to have a mailing list feature. Let's
|
59
|
+
also say you care about the UI, and you don't want to learn all about creating
|
60
|
+
the correct HTML structures for a mailing list. You want to have lots of power
|
61
|
+
for searching the mail, and you have your own strategy for managing the lists.
|
62
|
+
You love Ruby. You want MList.
|
50
63
|
|
51
64
|
== REQUIREMENTS:
|
52
65
|
|
@@ -58,7 +71,57 @@ You'll need some gems.
|
|
58
71
|
|
59
72
|
== INSTALL:
|
60
73
|
|
61
|
-
|
74
|
+
sudo gem install mlist (you'll need to have github as a source).
|
75
|
+
|
76
|
+
For now, copy the mlist_ tables from the spec/fixtures/schema.rb file and move
|
77
|
+
them to a new migration in your application. Fun the migration.
|
78
|
+
|
79
|
+
Now you'll need to create the MList::Server and provide it with a list manager
|
80
|
+
and MList::EmailServer::Default instance. Something like this in your
|
81
|
+
environment.rb after the initialize block (our gem needs to have been loaded):
|
82
|
+
|
83
|
+
Rails::Initializer.run do |config|
|
84
|
+
# Please do specify a version, and check for the latest!
|
85
|
+
config.gem "mlist", :version => '0.1.0'
|
86
|
+
end
|
87
|
+
|
88
|
+
MLIST_SERVER = MList::Server.new(
|
89
|
+
:list_manager => MList::Manager::Database.new,
|
90
|
+
:email_server => MList::EmailServer::Default.new(
|
91
|
+
MList::EmailServer::Pop.new(
|
92
|
+
:ssl => false,
|
93
|
+
:server => 'pop.gmail.com',
|
94
|
+
:port => '995',
|
95
|
+
:username => 'yourusername',
|
96
|
+
:password => 'yourpassword'
|
97
|
+
),
|
98
|
+
MList::EmailServer::Smtp.new(
|
99
|
+
ActionMailer::Base.smtp_settings # probably good enough!
|
100
|
+
)
|
101
|
+
)
|
102
|
+
)
|
103
|
+
|
104
|
+
Your list manager needs to implement only two methods. Check out (and use if you
|
105
|
+
like) the MList::Manager::Database for more information.
|
106
|
+
|
107
|
+
You'll need something to trigger the incoming server process. Take your pick from
|
108
|
+
http://wiki.rubyonrails.org/rails/pages/HowToRunBackgroundJobsInRails. In the
|
109
|
+
end, if you don't write your own incoming server thing and go with the POP GMail
|
110
|
+
example above, your background process will "MLIST_SERVER.email_server.execute".
|
111
|
+
|
112
|
+
Take a look at MList::EmailPost if you're building a UI. It can be posted to a
|
113
|
+
list something like this:
|
114
|
+
|
115
|
+
class MyList # instances of these are given by your list manager
|
116
|
+
def post(attributes)
|
117
|
+
email = MList::EmailPost.new({
|
118
|
+
:mailer => 'MyApplication'
|
119
|
+
}.merge(attributes))
|
120
|
+
raise 'You can validate these' unless email.valid?
|
121
|
+
message = MLIST_SERVER.mail_list(self).post(email)
|
122
|
+
# do what you will with message. it's already saved.
|
123
|
+
end
|
124
|
+
end
|
62
125
|
|
63
126
|
== LICENSE:
|
64
127
|
|
@@ -66,21 +129,19 @@ You'll need some gems.
|
|
66
129
|
|
67
130
|
Copyright (c) 2008 Adam Williams (aiwilliams)
|
68
131
|
|
69
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
86
|
-
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
132
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
133
|
+
this software and associated documentation files (the 'Software'), to deal in the
|
134
|
+
Software without restriction, including without limitation the rights to use,
|
135
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
136
|
+
Software, and to permit persons to whom the Software is furnished to do so,
|
137
|
+
subject to the following conditions:
|
138
|
+
|
139
|
+
The above copyright notice and this permission notice shall be included in all
|
140
|
+
copies or substantial portions of the Software.
|
141
|
+
|
142
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
143
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
144
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
145
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
146
|
+
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
147
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/VERSION.yml
CHANGED
@@ -5,10 +5,9 @@ module MList
|
|
5
5
|
|
6
6
|
class Smtp < Base
|
7
7
|
def deliver(tmail, destinations)
|
8
|
-
sender = tmail['return-path'] || tmail.from
|
9
8
|
Net::SMTP.start(settings[:address], settings[:port], settings[:domain],
|
10
9
|
settings[:user_name], settings[:password], settings[:authentication]) do |smtp|
|
11
|
-
smtp.sendmail(tmail.encoded, sender, destinations)
|
10
|
+
smtp.sendmail(tmail.encoded, tmail['sender'], destinations)
|
12
11
|
end
|
13
12
|
end
|
14
13
|
|
data/lib/mlist/server.rb
CHANGED
@@ -10,7 +10,9 @@ module MList
|
|
10
10
|
|
11
11
|
def receive_email(email)
|
12
12
|
lists = list_manager.lists(email)
|
13
|
-
if
|
13
|
+
if lists.empty?
|
14
|
+
list_manager.no_lists_found(email)
|
15
|
+
elsif email.bounce?
|
14
16
|
process_bounce(lists.first, email)
|
15
17
|
else
|
16
18
|
process_post(lists, email)
|
@@ -38,15 +38,18 @@ module MList
|
|
38
38
|
self['reply-to'] = quoter(:quote_any_address_if_necessary)
|
39
39
|
self['subject'] = quoter(:quote_any_if_necessary)
|
40
40
|
|
41
|
+
self['sender'] = quoter(:quote_address_if_necessary)
|
42
|
+
self['errors-to'] = quoter(:quote_address_if_necessary)
|
41
43
|
self['in-reply-to'] = quoter(:quote_any_address_if_necessary)
|
42
44
|
self['x-mailer'] = quoter(:quote_if_necessary, false)
|
43
45
|
|
44
|
-
self['
|
45
|
-
self['
|
46
|
-
self['
|
47
|
-
self['
|
48
|
-
self['
|
49
|
-
self['
|
46
|
+
self['list-id'] = quoter(:quote_address_if_necessary)
|
47
|
+
self['list-help'] = quoter(:quote_address_if_necessary)
|
48
|
+
self['list-subscribe'] = quoter(:quote_address_if_necessary)
|
49
|
+
self['list-unsubscribe'] = quoter(:quote_address_if_necessary)
|
50
|
+
self['list-post'] = quoter(:quote_address_if_necessary)
|
51
|
+
self['list-owner'] = quoter(:quote_address_if_necessary)
|
52
|
+
self['list-archive'] = quoter(:quote_address_if_necessary)
|
50
53
|
end
|
51
54
|
|
52
55
|
def [](key)
|