mlist 0.1.14 → 0.1.16
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/CHANGELOG +8 -0
- data/VERSION.yml +1 -1
- data/lib/mlist/email_server/imap.rb +16 -12
- data/lib/mlist/mail_list.rb +13 -4
- data/spec/integration/imap_email_server_spec.rb +22 -25
- data/spec/models/mail_list_spec.rb +16 -3
- metadata +3 -3
    
        data/CHANGELOG
    CHANGED
    
    | @@ -1,3 +1,11 @@ | |
| 1 | 
            +
            *0.1.16 [Bug Fix] (2010-04-13)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            * Fixed bug where encoding was lost when adding footers. [aiwilliams]
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            *0.1.15 [Bug Fix] (2010-04-02)
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            * Fixed mistakes in lifecycle management of imap connection. [aiwilliams]
         | 
| 8 | 
            +
             | 
| 1 9 | 
             
            *0.1.14 [Bug Fix] (2010-04-02)
         | 
| 2 10 |  | 
| 3 11 | 
             
            * Better to ask for not deleted messages, and expunging after processing. [aiwilliams]
         | 
    
        data/VERSION.yml
    CHANGED
    
    
| @@ -6,11 +6,6 @@ module MList | |
| 6 6 | 
             
                class Imap < Base
         | 
| 7 7 | 
             
                  def initialize(settings)
         | 
| 8 8 | 
             
                    super(settings)
         | 
| 9 | 
            -
                    @imap = Net::IMAP.new(
         | 
| 10 | 
            -
                      settings[:server],
         | 
| 11 | 
            -
                      settings[:port],
         | 
| 12 | 
            -
                      settings[:ssl]
         | 
| 13 | 
            -
                    )
         | 
| 14 9 | 
             
                  end
         | 
| 15 10 |  | 
| 16 11 | 
             
                  def deliver(tmail)
         | 
| @@ -18,7 +13,12 @@ module MList | |
| 18 13 | 
             
                  end
         | 
| 19 14 |  | 
| 20 15 | 
             
                  def execute
         | 
| 21 | 
            -
                     | 
| 16 | 
            +
                    begin
         | 
| 17 | 
            +
                      connect
         | 
| 18 | 
            +
                      process_folders
         | 
| 19 | 
            +
                    ensure
         | 
| 20 | 
            +
                      disconnect
         | 
| 21 | 
            +
                    end
         | 
| 22 22 | 
             
                  end
         | 
| 23 23 |  | 
| 24 24 | 
             
                  def archive_message_id(id)
         | 
| @@ -27,12 +27,16 @@ module MList | |
| 27 27 | 
             
                  end
         | 
| 28 28 |  | 
| 29 29 | 
             
                  def connect
         | 
| 30 | 
            +
                    @imap = Net::IMAP.new(
         | 
| 31 | 
            +
                      settings[:server],
         | 
| 32 | 
            +
                      settings[:port],
         | 
| 33 | 
            +
                      settings[:ssl]
         | 
| 34 | 
            +
                    )
         | 
| 30 35 | 
             
                    @imap.login(settings[:username], settings[:password])
         | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
                    end
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  def disconnect
         | 
| 39 | 
            +
                    @imap.disconnect if @imap && !@imap.disconnected?
         | 
| 36 40 | 
             
                  end
         | 
| 37 41 |  | 
| 38 42 | 
             
                  def process_folders
         | 
| @@ -47,7 +51,7 @@ module MList | |
| 47 51 | 
             
                      process_message_id(message_id)
         | 
| 48 52 | 
             
                      archive_message_id(message_id)
         | 
| 49 53 | 
             
                    end
         | 
| 50 | 
            -
                    @imap. | 
| 54 | 
            +
                    @imap.close
         | 
| 51 55 | 
             
                  end
         | 
| 52 56 |  | 
| 53 57 | 
             
                  def process_message_id(id)
         | 
    
        data/lib/mlist/mail_list.rb
    CHANGED
    
    | @@ -1,5 +1,7 @@ | |
| 1 1 | 
             
            module MList
         | 
| 2 2 | 
             
              class MailList < ActiveRecord::Base
         | 
| 3 | 
            +
                include Util::Quoting
         | 
| 4 | 
            +
             | 
| 3 5 | 
             
                set_table_name 'mlist_mail_lists'
         | 
| 4 6 |  | 
| 5 7 | 
             
                # Provides the MailList for a given implementation of MList::List,
         | 
| @@ -237,24 +239,31 @@ module MList | |
| 237 239 |  | 
| 238 240 | 
             
                  def prepare_html_footer(part, footer)
         | 
| 239 241 | 
             
                    return unless part
         | 
| 240 | 
            -
             | 
| 242 | 
            +
             | 
| 243 | 
            +
                    content = part.body('utf-8')
         | 
| 241 244 | 
             
                    content.gsub!(%r(<p>\s*#{FOOTER_BLOCK_START_RE}.*?#{FOOTER_BLOCK_END_RE}\s*<\/p>)im, '')
         | 
| 242 245 | 
             
                    content.strip!
         | 
| 246 | 
            +
             | 
| 243 247 | 
             
                    html_footer = "<p>#{auto_link_urls(text_to_html(footer))}</p>"
         | 
| 244 248 |  | 
| 245 249 | 
             
                    unless content.sub!(/<\/body>/, "#{html_footer}</body>")
         | 
| 246 250 | 
             
                      # no body was there, substitution failed
         | 
| 247 251 | 
             
                      content << html_footer
         | 
| 248 252 | 
             
                    end
         | 
| 249 | 
            -
             | 
| 253 | 
            +
             | 
| 254 | 
            +
                    part.charset = 'utf-8'
         | 
| 255 | 
            +
                    part.content_transfer_encoding = 'quoted-printable'
         | 
| 256 | 
            +
                    part.body = [normalize_new_lines(content)].pack("M*")
         | 
| 250 257 | 
             
                  end
         | 
| 251 258 |  | 
| 252 259 | 
             
                  def prepare_text_footer(part, footer)
         | 
| 253 260 | 
             
                    return unless part
         | 
| 254 | 
            -
                    content = strip_list_footers(part.body)
         | 
| 261 | 
            +
                    content = strip_list_footers(part.body('utf-8'))
         | 
| 255 262 | 
             
                    content << "\n\n" unless content.end_with?("\n\n")
         | 
| 256 263 | 
             
                    content << footer
         | 
| 257 | 
            -
                    part. | 
| 264 | 
            +
                    part.charset = 'utf-8'
         | 
| 265 | 
            +
                    part.content_transfer_encoding = 'quoted-printable'
         | 
| 266 | 
            +
                    part.body = [normalize_new_lines(content)].pack("M*")
         | 
| 258 267 | 
             
                  end
         | 
| 259 268 |  | 
| 260 269 | 
             
                  def list_footer(message)
         | 
| @@ -1,50 +1,47 @@ | |
| 1 1 | 
             
            require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
         | 
| 2 2 | 
             
            require 'mlist/email_server/imap'
         | 
| 3 3 |  | 
| 4 | 
            -
            describe MList::EmailServer::Imap, ' | 
| 5 | 
            -
              it 'should use the provided credentials' do
         | 
| 6 | 
            -
                 | 
| 7 | 
            -
                 | 
| 8 | 
            -
              end
         | 
| 9 | 
            -
             | 
| 10 | 
            -
              it 'should login with the provided credentials, process the folders, close on completion' do
         | 
| 11 | 
            -
                imap_server = Object.new
         | 
| 12 | 
            -
                stub(Net::IMAP).new { imap_server }
         | 
| 13 | 
            -
             | 
| 4 | 
            +
            describe MList::EmailServer::Imap, 'execute' do
         | 
| 5 | 
            +
              it 'should use the provided credentials when connecting' do
         | 
| 6 | 
            +
                imap_server = 'mock_imap_server'
         | 
| 7 | 
            +
                mock(Net::IMAP).new('host', 993, true) { imap_server }
         | 
| 14 8 | 
             
                mock(imap_server).login('aahh', 'eeya')
         | 
| 15 | 
            -
                mock(imap_server).close
         | 
| 16 9 |  | 
| 17 10 | 
             
                imap = MList::EmailServer::Imap.new(
         | 
| 11 | 
            +
                  :server => 'host', :port => 993, :ssl => true,
         | 
| 18 12 | 
             
                  :username => 'aahh', :password => 'eeya'
         | 
| 19 13 | 
             
                )
         | 
| 20 | 
            -
                 | 
| 21 | 
            -
                imap.execute
         | 
| 14 | 
            +
                imap.connect
         | 
| 22 15 | 
             
              end
         | 
| 23 16 |  | 
| 24 | 
            -
              it 'should process the  | 
| 25 | 
            -
                 | 
| 26 | 
            -
                 | 
| 27 | 
            -
                imap | 
| 28 | 
            -
             | 
| 29 | 
            -
                 | 
| 30 | 
            -
                mock(imap).process_folder('Inbox')
         | 
| 31 | 
            -
                mock(imap).process_folder('Spam')
         | 
| 32 | 
            -
                imap.process_folders
         | 
| 17 | 
            +
              it 'should connect, process the folders, disconnect on execution' do
         | 
| 18 | 
            +
                imap = MList::EmailServer::Imap.new({})
         | 
| 19 | 
            +
                mock(imap).connect
         | 
| 20 | 
            +
                mock(imap).process_folders
         | 
| 21 | 
            +
                mock(imap).disconnect
         | 
| 22 | 
            +
                imap.execute
         | 
| 33 23 | 
             
              end
         | 
| 34 24 | 
             
            end
         | 
| 35 25 |  | 
| 36 26 | 
             
            describe MList::EmailServer::Imap, 'processing' do
         | 
| 37 27 | 
             
              before do
         | 
| 38 28 | 
             
                @imap_server = 'mock_imap_server'
         | 
| 39 | 
            -
                stub(Net::IMAP).new { @imap_server }
         | 
| 40 29 | 
             
                @imap = MList::EmailServer::Imap.new({:archive_folder => 'Archive'})
         | 
| 30 | 
            +
                @imap.instance_variable_set('@imap', @imap_server)
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
              it 'should process the provided folders' do
         | 
| 34 | 
            +
                imap = MList::EmailServer::Imap.new(:source_folders => ['Inbox', 'Spam'])
         | 
| 35 | 
            +
                mock(imap).process_folder('Inbox')
         | 
| 36 | 
            +
                mock(imap).process_folder('Spam')
         | 
| 37 | 
            +
                imap.process_folders
         | 
| 41 38 | 
             
              end
         | 
| 42 39 |  | 
| 43 | 
            -
              it 'should  | 
| 40 | 
            +
              it 'should select the folder, process each message, close the folder' do
         | 
| 44 41 | 
             
                message_ids = [1,2]
         | 
| 45 42 | 
             
                mock(@imap_server).select('folder')
         | 
| 46 43 | 
             
                mock(@imap_server).search(['NOT','DELETED']) { message_ids }
         | 
| 47 | 
            -
                mock(@imap_server). | 
| 44 | 
            +
                mock(@imap_server).close
         | 
| 48 45 | 
             
                mock(@imap).process_message_id(1)
         | 
| 49 46 | 
             
                mock(@imap).archive_message_id(1)
         | 
| 50 47 | 
             
                mock(@imap).process_message_id(2)
         | 
| @@ -396,7 +396,7 @@ describe MList::MailList do | |
| 396 396 | 
             
                it 'should append the list footer to text/plain emails' do
         | 
| 397 397 | 
             
                  @post_tmail.body = "My Email\n\n\n\n\n"
         | 
| 398 398 | 
             
                  mock(@manager_list).footer_content(is_a(MList::Message)) { 'my footer' }
         | 
| 399 | 
            -
                  process_post.body.should == "My Email\n\n\n\n\n#{MList::MailList::FOOTER_BLOCK_START}\nmy footer\n#{MList::MailList::FOOTER_BLOCK_END}"
         | 
| 399 | 
            +
                  process_post.body.should == "My Email\n\n\n\n\n#{MList::MailList::FOOTER_BLOCK_START}\nmy footer\n#{MList::MailList::FOOTER_BLOCK_END}=\n"
         | 
| 400 400 | 
             
                end
         | 
| 401 401 |  | 
| 402 402 | 
             
                it 'should append the list footer to multipart/alternative, text/plain part of emails' do
         | 
| @@ -414,7 +414,7 @@ describe MList::MailList do | |
| 414 414 | 
             
                it 'should handle whitespace well when appending footer' do
         | 
| 415 415 | 
             
                  @post_tmail.body = "My Email"
         | 
| 416 416 | 
             
                  mock(@manager_list).footer_content(is_a(MList::Message)) { 'my footer' }
         | 
| 417 | 
            -
                  process_post.body.should == "My Email\n\n#{MList::MailList::FOOTER_BLOCK_START}\nmy footer\n#{MList::MailList::FOOTER_BLOCK_END}"
         | 
| 417 | 
            +
                  process_post.body.should == "My Email\n\n#{MList::MailList::FOOTER_BLOCK_START}\nmy footer\n#{MList::MailList::FOOTER_BLOCK_END}=\n"
         | 
| 418 418 | 
             
                end
         | 
| 419 419 |  | 
| 420 420 | 
             
                it 'should strip out any existing text footers from the list' do
         | 
| @@ -433,7 +433,7 @@ describe MList::MailList do | |
| 433 433 | 
             
            this is without any in front
         | 
| 434 434 | 
             
            #{MList::MailList::FOOTER_BLOCK_END}
         | 
| 435 435 | 
             
                  }
         | 
| 436 | 
            -
                  process_post.body.should == "My Email\n\n#{MList::MailList::FOOTER_BLOCK_START}\nmy footer\n#{MList::MailList::FOOTER_BLOCK_END}"
         | 
| 436 | 
            +
                  process_post.body.should == "My Email\n\n#{MList::MailList::FOOTER_BLOCK_START}\nmy footer\n#{MList::MailList::FOOTER_BLOCK_END}=\n"
         | 
| 437 437 | 
             
                end
         | 
| 438 438 |  | 
| 439 439 | 
             
                it 'should strip out any existing html footers from the list' do
         | 
| @@ -457,6 +457,19 @@ this is without any in front | |
| 457 457 | 
             
                  process_post.parts[1].body.should == "<p>My Email</p>\n<blockquote>\n   <p> Stuff in my email</p>\n\n>>  not in our p!<p>#{MList::MailList::FOOTER_BLOCK_START}<br />\nmy footer<br />\n#{MList::MailList::FOOTER_BLOCK_END}</p>"
         | 
| 458 458 | 
             
                end
         | 
| 459 459 |  | 
| 460 | 
            +
                it 'should properly reflect the new encoding when adding footers' do
         | 
| 461 | 
            +
                  @post_tmail = tmail_fixture('content_types/multipart_alternative_encoded')
         | 
| 462 | 
            +
                  stub(@manager_list).footer_content { 'my footer' }
         | 
| 463 | 
            +
             | 
| 464 | 
            +
                  part = process_post.parts[0]
         | 
| 465 | 
            +
                  part.charset.should == 'utf-8'
         | 
| 466 | 
            +
                  part.body.should == "Hi Friends and Neighbors:\n\nLike you, we have many concerns about what is going on in our country.  This\nyear in our homeschool, we've spent a lot more time learning about the\nhistory of our country, and the mindset of the founders that caused them to\nbreak away from the British empire and put together our great founding\ndocuments of the Declaration of Independence and U.S. Constitution.  How far\nwe have fallen!\n\n-- \nBob Bold\nThe Edge of Your Seat Experience Compny™\n\n\n#{MList::MailList::FOOTER_BLOCK_START}\nmy footer\n#{MList::MailList::FOOTER_BLOCK_END}"
         | 
| 467 | 
            +
             | 
| 468 | 
            +
                  part = process_post.parts[1]
         | 
| 469 | 
            +
                  part.charset.should == 'utf-8'
         | 
| 470 | 
            +
                  part.body.should == "<div class=\"gmail_quote\"><br><div class=\"gmail_quote\"><div><span style=\"font-family:arial, sans-serif;font-size:13px;border-collapse:collapse\"><div>\nHi Friends and Neighbors:</div><div><br></div><div>Like you, we have many concerns about what is going on in our country.  This year in our homeschool, we've spent a lot more time learning about the history of our country, and the mindset of the founders that caused them to break away from the British empire and put together our great founding documents of the Declaration of Independence and U.S. Constitution.  How far we have fallen!</div>\n\n<div><span style=\"font-size:small\"><br></span></div></span></div></div>-- <br>Bob Bold<br>The Edge of Your Seat Experience Compny™ <br>Beaverton Heights               919-555-5555 (v)<br>1234 Checkstone St            919-555-5555 (f)<br><p>#{MList::MailList::FOOTER_BLOCK_START}<br />\nmy footer<br />\n#{MList::MailList::FOOTER_BLOCK_END}</p>"
         | 
| 471 | 
            +
                end
         | 
| 472 | 
            +
             | 
| 460 473 | 
             
                describe 'time' do
         | 
| 461 474 | 
             
                  include TMail::TextUtils
         | 
| 462 475 |  | 
    
        metadata
    CHANGED
    
    | @@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version | |
| 5 5 | 
             
              segments: 
         | 
| 6 6 | 
             
              - 0
         | 
| 7 7 | 
             
              - 1
         | 
| 8 | 
            -
              -  | 
| 9 | 
            -
              version: 0.1. | 
| 8 | 
            +
              - 16
         | 
| 9 | 
            +
              version: 0.1.16
         | 
| 10 10 | 
             
            platform: ruby
         | 
| 11 11 | 
             
            authors: 
         | 
| 12 12 | 
             
            - Adam Williams
         | 
| @@ -14,7 +14,7 @@ autorequire: | |
| 14 14 | 
             
            bindir: bin
         | 
| 15 15 | 
             
            cert_chain: []
         | 
| 16 16 |  | 
| 17 | 
            -
            date: 2010-04- | 
| 17 | 
            +
            date: 2010-04-13 00:00:00 -04:00
         | 
| 18 18 | 
             
            default_executable: 
         | 
| 19 19 | 
             
            dependencies: []
         | 
| 20 20 |  |