Class: Mailinglist

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
app/models/mailinglist.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.find_all_by_domain_id(domain_id) ⇒ Object



84
85
86
87
88
# File 'app/models/mailinglist.rb', line 84

def self.find_all_by_domain_id domain_id
    Mailinglist.find(:all).find_all do |ml| # yes, you're reading that right
        ml.domain.id == domain_id
    end
end

.find_by_address(addr) ⇒ Object

NOTE: THIS RETURNS AN ARRAY!!!! the ML object is the [0]‘th index of the array



164
165
166
167
168
169
170
171
172
173
174
175
# File 'app/models/mailinglist.rb', line 164

def self.find_by_address addr
    if ml = find_by_basic_address(addr) then
        return [ml,:mail]
    elsif info = find_by_proxy_address(addr) then
        ml, address_id = info
        return [ml, :proxy, address_id]
    elsif(ml = find_by_bounces_address(addr)) then
        return [ml, :bounces]
    elsif(ml = find_by_request_address(addr)) then
        return [ml, :request]
    end
end

.find_by_basic_address(addr) ⇒ Object



177
178
179
180
181
182
183
184
185
# File 'app/models/mailinglist.rb', line 177

def self.find_by_basic_address addr
    (ml_name, domain_name) = addr.split "@"
    domain=Domain.find_by_name domain_name
    if domain
        ml=Mailinglist.find_all_by_name(ml_name).find do |ml|
            ml.domain.id == domain.id
        end
    end
end

.find_by_bounces_address(bounces_addr) ⇒ Object



201
202
203
# File 'app/models/mailinglist.rb', line 201

def self.find_by_bounces_address bounces_addr
    find_by_basic_address bounces_addr.sub(/-bounces\@/,"@")
end

.find_by_proxy_address(addr) ⇒ Object



187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'app/models/mailinglist.rb', line 187

def self.find_by_proxy_address addr
    if matchdata=addr.match(/#{Regexp.escape(SysConfig.address_separator)}([0-9]+)\@/) then
        proxy_id=matchdata[1].to_i
        if ml=find_by_basic_address(addr.sub(/-[0-9]+\@/,"@")) then
            begin
                proxy=ProxyLink.find(proxy_id)
                return ml, proxy.address
            rescue
                nil
            end
        end
    end
end

.find_by_request_address(request_addr) ⇒ Object



205
206
207
# File 'app/models/mailinglist.rb', line 205

def self.find_by_request_address request_addr
    find_by_basic_address request_addr.sub(/-request\@/,"@")
end

Instance Method Details

#addressObject


These are all to make it work with rumble (as a replacement for rumble’s mailing-list class).




143
144
145
146
# File 'app/models/mailinglist.rb', line 143

def address
    name + "@" + user.domain.name
    # "#{name}@#{user.domain.name}"
end

#addresses_by_searchstring_and_filter(searchstring, filter) ⇒ Object

this function is for the GUI’s search



218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'app/models/mailinglist.rb', line 218

def addresses_by_searchstring_and_filter(searchstring, filter)
    addresses_filtered = addresses.find(:all, :conditions => ['address like ?', searchstring+'%'])
    case filter
    when 'confirmed'
        addresses_filtered.each do |addr|
            if addr.confirmed? then addr end
        end    
    when 'unconfirmed'
        addresses_filtered.each do |addr|
            if not addr.confirmed? then addr end
        end
    else
        #assume 'all'
        addresses_filtered
    end
end

#before_saveObject



116
117
118
119
120
121
122
123
124
125
126
# File 'app/models/mailinglist.rb', line 116

def before_save
    welcome_admin_message   ||= 
        AdminMessage.find SysConfig.default_welcome_admin_message_id
    confirmed_admin_message ||=
        AdminMessage.find SysConfig.default_confirmed_admin_message_id
    sayonara_admin_message ||=
        AdminMessage.find SysConfig.default_farewell_admin_message_id
    # welcome_admin_message   ||= AdminMessage.find 1 # XXX MAGIC CONSTANT 
    # confirmed_admin_message ||= AdminMessage.find 2 # XXX MAGIC CONSTANT
    # sayonara_admin_message  ||= AdminMessage.find 3 # XXX MAGIC CONSTANT
end

#bounceaddressObject



148
149
150
151
152
# File 'app/models/mailinglist.rb', line 148

def bounceaddress
    name + SysConfig.address_separator + SysConfig.bounce_suffix + "@" +
        user.domain.name
    # "#{name}-bounce@#{user.domain.name}"   # XXX MAGIC CONSTANT XXX
end

#canonical_address?Boolean

Returns true if this mailing list’s address is the canonical address of a User.

Returns:

  • (Boolean)


107
108
109
# File 'app/models/mailinglist.rb', line 107

def canonical_address?
    id == user.mailinglist_id
end

#confirm(address, confirmationcode) ⇒ Object



329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
# File 'app/models/mailinglist.rb', line 329

def confirm address,confirmationcode
    addr=nil

    if Address === address
        addr=address
    else
        addr=Address.find_by_address(address)
    end

    if addr then
        if confirmation? then
            if Confirmationcode.confirm(self, addr, confirmationcode) then
                save
                confirmed_admin_message.send_mail bounceaddress, 
                    addr.address,
                    :address => addr.address,
                    :domain => domain.name,
                    :name => name, 
                    :description => description,
                    :requestaddress => requestaddress
                return true
            else
                return false
            end
        else
            return true
        end
    end
end

#confirmed?(addr) ⇒ Boolean

Returns:

  • (Boolean)


209
210
211
212
213
214
215
# File 'app/models/mailinglist.rb', line 209

def confirmed? addr
    if confirmation? then
        Confirmationcode.confirmed? self.id, addr.id
    else 
        true
    end
end

#confirmed_addressesObject



235
236
237
# File 'app/models/mailinglist.rb', line 235

def confirmed_addresses
    addresses.find_all { |addr| confirmed? addr }
end

#domainObject



264
# File 'app/models/mailinglist.rb', line 264

def domain; user.domain; end

#expand_addressesObject



245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
# File 'app/models/mailinglist.rb', line 245

def expand_addresses
    address_list = addresses
    expanded = false
    until expanded
        foundsome = false
        new_address_list = address_list.map do |addr|
            if ml = Mailinglist.find_by_address(addr.address) then
                foundsome = true
                ml[0].addresses
            else
                addr
            end
        end.flatten
        expanded = ! foundsome
        address_list = new_address_list
    end
    address_list
end

#handle_request(requestmessage) ⇒ Object



382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
# File 'app/models/mailinglist.rb', line 382

def handle_request requestmessage
    subject=requestmessage.headers["Subject"][0].contents
    matches=requestmessage.body.match(/^\W*subscribe\s+(\S+@[a-z0-9.-]+)
                       (?:\s+([a-z0-9]{16}))?$/x)
    if matches then
        # puts "Found subscription request: #{matches[0]}"
        
        addresscandidate=matches[1]
        confirmationcode=matches[2] # returns nil if there isn'tone
        
        # Since you can have mailing lists that require confirmation, but
        # they're not joinable, check for the confirmationcode case first.
        if confirmationcode then
            return subscribe(addresscandidate, confirmationcode)
        else
            if joinable? then
                return subscribe(addresscandidate)
            end
        end
    end
    
    # TODO: actually implement confirmed unsubscribing down in the
    # model.  (This is, of course, to prevent pranksters from
    # unsubscribing you from a mailing list behind your back.)
    matches=requesmessage.body.match(/^\W*unsubscribe\s+(\S+@[a-z0-9.-]+)
                        (?:\s+([a-z0-9]{16}))?$/x)
    if matches then
        addresscandidate=matches[1]
        confirmationcode=matches[2]
        
        return unsubscribe(addresscandidate, confirmationcode)
    end
end

#has_address?(addr) ⇒ Boolean

Returns true if the address addr is subscribed to this mailing list.

Returns:

  • (Boolean)


112
113
114
# File 'app/models/mailinglist.rb', line 112

def has_address? addr
    expand_addresses.map { |a| a.address }.member? addr
end

#openpostingObject



416
417
418
# File 'app/models/mailinglist.rb', line 416

def openposting
   return false
end

#pending_addressesObject Also known as: unconfirmed_addresses



239
240
241
# File 'app/models/mailinglist.rb', line 239

def pending_addresses
    addresses.find_all { |addr| not confirmed? addr }
end

#requestaddressObject



154
155
156
157
158
# File 'app/models/mailinglist.rb', line 154

def requestaddress
    name + SysConfig.address_separator + SysConfig.request_suffix + "@" +
        user.domain.name
    # "#{name}-request@#{user.domain.name}"  # XXX MAGIC CONSTANT XXX
end

#send_message(message) ⇒ Object



268
269
270
# File 'app/models/mailinglist.rb', line 268

def send_message message
    message.deliver
end

#send_welcome_message(addr) ⇒ Object



309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
# File 'app/models/mailinglist.rb', line 309

def send_welcome_message(addr)
    c=Confirmationcode.find_by_address_id_and_mailinglist_id addr.id, id
    unless c
        c=Confirmationcode.new
        c.address_id=addr.id
        c.mailinglist_id=id
        c.save
    end

    unless c.confirmed?
        welcome_admin_message.send_mail bounceaddress, addr.address,
            :address => addr.address,
            :command => "subscribe #{addr.address} #{c.code}",
            :domain => domain.name,
            :name => name,
            :description => description,
            :requestaddress => requestaddress
        end
end

#store_message(message) ⇒ Object



266
# File 'app/models/mailinglist.rb', line 266

def store_message message; messages << message; end

#subscribe(address, confirmationcode = nil) ⇒ Object



272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
# File 'app/models/mailinglist.rb', line 272

def subscribe(address,confirmationcode = nil)
    if Address === address then
        addr = address
    else
        addr = Address.find_or_create_by_address(address)
    end

    if confirmation? 
        if confirmed_addresses.member? addr
            true
        else
            if confirmationcode then
                confirm addr, confirmationcode
            else
                begin
                    addresses << addr
                    send_welcome_message(addr)
                rescue AlreadySubscribedError
                    true
                rescue ForwardingAlreadySubscribedError
                    errors.add "address", "already has a forwarding address"
                    false
                end
            end
        end
    else
        begin
            addresses << addr
        rescue AlreadySubscribedError
            true
        rescue ForwardingAlreadySubscribedError
            errors.add "address", "already has a forwarding address"
            false
        end
    end
end

#unsubscribe(address, send_mail = true) ⇒ Object



359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
# File 'app/models/mailinglist.rb', line 359

def unsubscribe(address, send_mail = true)
    addr=nil

    unless Address === address
        addr=Address.find_by_address address
    else
        addr=address
    end

    if addresses.member? addr then
        if send_mail
            sayonara_admin_message.send_mail bounceaddress, 
                addr.address,
                :address => addr.address,
                :domain => domain.name,
                :name => name, 
                :description => description,
                :requestaddress => requestaddress
        end
        addresses.delete addr
    end
end

#validate_no_duplicate_forwarding(address) ⇒ Object



64
65
66
67
68
# File 'app/models/mailinglist.rb', line 64

def validate_no_duplicate_forwarding address
    if Address.proxyaddress(address.address) and mailinglist_class.id == 1 #XXX MAGIC CONSTANT XXX
        raise ForwardingAlreadySubscribedError 
    end
end

#validate_unique_address(address) ⇒ Object



58
59
60
61
62
# File 'app/models/mailinglist.rb', line 58

def validate_unique_address address
    if addresses.member? address
        raise AlreadySubscribedError 
    end
end