mms2r 2.2.0 → 2.3.0
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/.gitignore +1 -0
- data/History.txt +21 -0
- data/Manifest.txt +3 -0
- data/README.txt +51 -40
- data/Rakefile +4 -4
- data/conf/mms2r_media.yml +18 -11
- data/conf/vzwpix.com.yml +2 -2
- data/init.rb +1 -0
- data/lib/mms2r.rb +10 -3
- data/lib/mms2r/media.rb +141 -87
- data/lib/mms2r/media/sprint.rb +2 -2
- data/lib/tmail_ext.rb +5 -0
- data/mms2r.gemspec +27 -13
- data/test/fixtures/iphone-image-01.mail +62 -0
- data/test/fixtures/vzwpix.com-image-01.mail +50 -0
- data/test/test_mms2r_media.rb +8 -4
- data/test/test_vzwpix_com.rb +31 -7
- metadata +63 -8
    
        data/.gitignore
    CHANGED
    
    
    
        data/History.txt
    CHANGED
    
    | @@ -1,3 +1,24 @@ | |
| 1 | 
            +
            ### 2.3.0 / 2008-08-30 (Snakes 'n' Barrels Greatest Hits)
         | 
| 2 | 
            +
            * 5 new features
         | 
| 3 | 
            +
              * detect smartphone status/type based on model metadata from jpeg and tiff
         | 
| 4 | 
            +
                exif data using exifr gem, access exif data with MMS2R::Media#exif
         | 
| 5 | 
            +
              * make MMS2R Rails gem packaging friendly with an init.rb - Scott Taylor,
         | 
| 6 | 
            +
                smtlaissezfaire
         | 
| 7 | 
            +
              * delegate missing methods to mms2r's tmail object so that mms2r behaves as
         | 
| 8 | 
            +
                if it were a tmail object - Sai Emrys, saizai
         | 
| 9 | 
            +
              * default_media can return an attachment of application content type -
         | 
| 10 | 
            +
                Brendan Lim, brendanlim
         | 
| 11 | 
            +
              * MMS2R.parse(raw_mail) convenience class method that parses and returns an
         | 
| 12 | 
            +
                mms2r from a mail file - saizai
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            * 4 minor enhancements
         | 
| 15 | 
            +
              * make examples more 'mail' specific to enforce the fact that an mms is a
         | 
| 16 | 
            +
                multipart email - saizai
         | 
| 17 | 
            +
              * update for text in vzwpix.com default carrier message
         | 
| 18 | 
            +
              * detecting smartphone (blackberries and iphones for now) is more versatile
         | 
| 19 | 
            +
                from reading mail headers
         | 
| 20 | 
            +
              * expanded filtering of carrier advertising text in mms from smartphones
         | 
| 21 | 
            +
             | 
| 1 22 | 
             
            ### 2.2.0 / 2009-01-04 (Rikki Kixx - owner of a franchise of rehab centers)
         | 
| 2 23 |  | 
| 3 24 | 
             
            * 3 new features
         | 
    
        data/Manifest.txt
    CHANGED
    
    | @@ -40,6 +40,7 @@ conf/waw.plspictures.com.yml | |
| 40 40 | 
             
            dev_tools/anonymizer.rb
         | 
| 41 41 | 
             
            dev_tools/debug_sprint_hpricot_parsing.rb
         | 
| 42 42 | 
             
            dev_tools/github.rb
         | 
| 43 | 
            +
            init.rb
         | 
| 43 44 | 
             
            lib/mms2r.rb
         | 
| 44 45 | 
             
            lib/mms2r/media.rb
         | 
| 45 46 | 
             
            lib/mms2r/media/sprint.rb
         | 
| @@ -74,6 +75,7 @@ test/fixtures/iconv-fr-text-01.mail | |
| 74 75 | 
             
            test/fixtures/indosat-image-01.mail
         | 
| 75 76 | 
             
            test/fixtures/indosat-image-02.mail
         | 
| 76 77 | 
             
            test/fixtures/info2go-image-01.mail
         | 
| 78 | 
            +
            test/fixtures/iphone-image-01.mail
         | 
| 77 79 | 
             
            test/fixtures/luxgsm-image-01.mail
         | 
| 78 80 | 
             
            test/fixtures/maroctelecom-france-mms-01.mail
         | 
| 79 81 | 
             
            test/fixtures/mediamessaging_o2_co_uk-image-01.mail
         | 
| @@ -129,6 +131,7 @@ test/fixtures/vodacom4me-co-za-02.mail | |
| 129 131 | 
             
            test/fixtures/vodacom4me-southafrica-mms-01.mail
         | 
| 130 132 | 
             
            test/fixtures/vodacom4me-southafrica-mms-04.mail
         | 
| 131 133 | 
             
            test/fixtures/vtext-text-01.mail
         | 
| 134 | 
            +
            test/fixtures/vzwpix.com-image-01.mail
         | 
| 132 135 | 
             
            test/fixtures/waw.plspictures.com-image-01.mail
         | 
| 133 136 | 
             
            test/test_1nbox_net.rb
         | 
| 134 137 | 
             
            test/test_bell_canada.rb
         | 
    
        data/README.txt
    CHANGED
    
    | @@ -1,23 +1,23 @@ | |
| 1 1 | 
             
            = mms2r
         | 
| 2 2 |  | 
| 3 | 
            +
              http://mms2r.rubyforge.org/
         | 
| 3 4 | 
             
              by Mike Mondragon
         | 
| 4 | 
            -
              http:// | 
| 5 | 
            -
              http://rubyforge.org/tracker/?group_id=3065 
         | 
| 5 | 
            +
              http://rubyforge.org/tracker/?group_id=3065
         | 
| 6 6 | 
             
              http://github.com/monde/mms2r/tree/master
         | 
| 7 7 | 
             
              http://peepcode.com/products/mms2r-pdf
         | 
| 8 8 |  | 
| 9 9 | 
             
            == DESCRIPTION
         | 
| 10 | 
            -
             | 
| 11 | 
            -
            MMS2R is a library that decodes the parts of an MMS message to disk while | 
| 12 | 
            -
            stripping out advertising injected by the mobile carriers.  MMS messages are | 
| 10 | 
            +
             | 
| 11 | 
            +
            MMS2R is a library that decodes the parts of an MMS message to disk while
         | 
| 12 | 
            +
            stripping out advertising injected by the mobile carriers.  MMS messages are
         | 
| 13 13 | 
             
            multipart email and the carriers often inject branding into these messages.  Use
         | 
| 14 14 | 
             
            MMS2R if you want to get at the real user generated content from a MMS without
         | 
| 15 15 | 
             
            having to deal with the cruft from the carriers.
         | 
| 16 16 |  | 
| 17 | 
            -
            If MMS2R is not aware of a particular carrier no extra processing is done to the | 
| 17 | 
            +
            If MMS2R is not aware of a particular carrier no extra processing is done to the
         | 
| 18 18 | 
             
            MMS other than decoding and consolidating its media.
         | 
| 19 19 |  | 
| 20 | 
            -
            Contact the author to add additional carriers to be processed by the library. | 
| 20 | 
            +
            Contact the author to add additional carriers to be processed by the library.
         | 
| 21 21 | 
             
            Suggestions and patches appreciated and welcomed!
         | 
| 22 22 |  | 
| 23 23 | 
             
            Corpus of carriers currently processed by MMS2R:
         | 
| @@ -25,7 +25,7 @@ Corpus of carriers currently processed by MMS2R: | |
| 25 25 | 
             
            * 1nbox/Idea: 1nbox.net
         | 
| 26 26 | 
             
            * 3 Ireland: mms.3ireland.ie
         | 
| 27 27 | 
             
            * Alltel: mms.alltel.com
         | 
| 28 | 
            -
            * AT&T/Cingular/Legacy: mms.att.net, txt.att.net, mmode.com, mms.mycingular.com, | 
| 28 | 
            +
            * AT&T/Cingular/Legacy: mms.att.net, txt.att.net, mmode.com, mms.mycingular.com,
         | 
| 29 29 | 
             
              cingularme.com, mobile.mycingular.com pics.cingularme.com
         | 
| 30 30 | 
             
            * Bell Canada: txt.bell.ca
         | 
| 31 31 | 
             
            * Bell South / Suncom: bellsouth.net
         | 
| @@ -50,7 +50,7 @@ Corpus of carriers currently processed by MMS2R: | |
| 50 50 | 
             
            * T-Mobile: tmomail.net, mmsreply.t-mobile.co.uk, tmo.blackberry.net
         | 
| 51 51 | 
             
            * TELUS Corporation (Canada): mms.telusmobility.com, msg.telus.com
         | 
| 52 52 | 
             
            * UAE MMS: mms.ae
         | 
| 53 | 
            -
            * Unicel: unicel.com, info2go.com | 
| 53 | 
            +
            * Unicel: unicel.com, info2go.com
         | 
| 54 54 | 
             
              (note: mobile number is tucked away in a text/plain part for unicel.com)
         | 
| 55 55 | 
             
            * Verizon: vzwpix.com, vtext.com
         | 
| 56 56 | 
             
            * Virgin Mobile: vmpix.com
         | 
| @@ -59,8 +59,8 @@ Corpus of carriers currently processed by MMS2R: | |
| 59 59 |  | 
| 60 60 | 
             
            == FEATURES
         | 
| 61 61 |  | 
| 62 | 
            -
            * #default_media and #default_text methods return a File that can be used in | 
| 63 | 
            -
              attachment_fu | 
| 62 | 
            +
            * #default_media and #default_text methods return a File that can be used in
         | 
| 63 | 
            +
              attachment_fu
         | 
| 64 64 | 
             
            * #process supports blocks to for enumerating over the content of the MMS
         | 
| 65 65 | 
             
            * #process can be made lazy when :process => :lazy is passed to new
         | 
| 66 66 | 
             
            * logging is enabled when :logger => your_logger is passed to new
         | 
| @@ -79,59 +79,75 @@ http://peepcode.com/products/mms2r-pdf | |
| 79 79 | 
             
              require 'tmail'
         | 
| 80 80 | 
             
              require 'fileutils'
         | 
| 81 81 |  | 
| 82 | 
            -
              mail =  | 
| 83 | 
            -
               | 
| 82 | 
            +
              mail = MMS2R.parse mail
         | 
| 83 | 
            +
              # mail = MMS2R.parse File.read('some_saved_mail.file')
         | 
| 84 84 |  | 
| 85 | 
            -
              puts " | 
| 85 | 
            +
              puts "mail has default carrier subject" if mail.subject.empty?
         | 
| 86 86 |  | 
| 87 87 | 
             
              # access the sender's phone number
         | 
| 88 | 
            -
              puts " | 
| 88 | 
            +
              puts "mail was from phone #{mail.number}"
         | 
| 89 89 |  | 
| 90 | 
            -
              # most  | 
| 90 | 
            +
              # most mail are either image or video, default_media will return the largest
         | 
| 91 91 | 
             
              # (non-advertising) video or image found
         | 
| 92 | 
            -
              file =  | 
| 93 | 
            -
              puts " | 
| 92 | 
            +
              file = mail.default_media
         | 
| 93 | 
            +
              puts "mail had a media: #{file.inspect}" unless file.nil?
         | 
| 94 94 |  | 
| 95 95 | 
             
              # finds the largest (non-advertising) text found
         | 
| 96 | 
            -
              file =  | 
| 97 | 
            -
              puts " | 
| 96 | 
            +
              file = mail.default_text
         | 
| 97 | 
            +
              puts "mail had some text: #{file.inspect}" unless file.nil?
         | 
| 98 98 |  | 
| 99 | 
            -
              #  | 
| 99 | 
            +
              # mail.media is a hash that is indexed by mime-type.
         | 
| 100 100 | 
             
              # The mime-type key returns an array of filepaths
         | 
| 101 | 
            -
              # to media that were extract from the  | 
| 101 | 
            +
              # to media that were extract from the mail and
         | 
| 102 102 | 
             
              # are of that type
         | 
| 103 | 
            -
               | 
| 104 | 
            -
               | 
| 103 | 
            +
              mail.media['image/jpeg'].each {|f| puts "#{f}"}
         | 
| 104 | 
            +
              mail.media['text/plain'].each {|f| puts "#{f}"}
         | 
| 105 105 |  | 
| 106 | 
            -
              # print the text (assumes  | 
| 107 | 
            -
              text = IO.readlines( | 
| 106 | 
            +
              # print the text (assumes mail had text)
         | 
| 107 | 
            +
              text = IO.readlines(mail.media['text/plain'].first).join
         | 
| 108 108 | 
             
              puts text
         | 
| 109 109 |  | 
| 110 | 
            -
              # save the image (assumes  | 
| 111 | 
            -
              FileUtils.cp  | 
| 110 | 
            +
              # save the image (assumes mail had a jpeg)
         | 
| 111 | 
            +
              FileUtils.cp mail.media['image/jpeg'].first, '/some/where/useful', :verbose => true
         | 
| 112 | 
            +
             | 
| 113 | 
            +
              puts "does the mail have quicktime video? #{!mail.media['video/quicktime'].nil?}"
         | 
| 114 | 
            +
             | 
| 115 | 
            +
              puts "plus run anything that TMail provides, e.g. #{mail.to.inspect}"
         | 
| 116 | 
            +
             | 
| 117 | 
            +
              # check if the mail is from a mobile phone
         | 
| 118 | 
            +
              puts "mail is from a mobile phone #{mail.is_mobile?}"
         | 
| 112 119 |  | 
| 113 | 
            -
               | 
| 120 | 
            +
              # inspect default media's exif data if exifr gem is installed and default
         | 
| 121 | 
            +
              # media is a jpeg or tiff
         | 
| 122 | 
            +
              puts "mail is from a mobile phone #{mail.is_mobile?}"
         | 
| 123 | 
            +
              puts "mail's default media's exif data is:"
         | 
| 124 | 
            +
              puts mms.exif.inspect
         | 
| 114 125 |  | 
| 115 126 | 
             
              # Block support, process and receive all media types of video.
         | 
| 116 | 
            -
               | 
| 127 | 
            +
              mail.process do |media_type, files|
         | 
| 117 128 | 
             
                # assumes a Clip model that is an AttachmentFu
         | 
| 118 129 | 
             
                Clip.create(:uploaded_data => files.first, :title => "From phone") if media_type =~ /video/
         | 
| 119 130 | 
             
              end
         | 
| 120 131 |  | 
| 121 132 | 
             
              # Another AttachmentFu example, Picture model is an AttachmentFu
         | 
| 122 133 | 
             
              picture = Picture.new
         | 
| 123 | 
            -
              picture.title =  | 
| 124 | 
            -
              picture.uploaded_data =  | 
| 134 | 
            +
              picture.title = mail.subject
         | 
| 135 | 
            +
              picture.uploaded_data = mail.default_media
         | 
| 125 136 | 
             
              picture.save!
         | 
| 126 137 |  | 
| 127 138 | 
             
              #remove all the media that was put to temporary disk
         | 
| 128 | 
            -
               | 
| 139 | 
            +
              mail.purge
         | 
| 129 140 |  | 
| 130 141 | 
             
            == REQUIREMENTS
         | 
| 131 142 |  | 
| 132 143 | 
             
            * Hpricot
         | 
| 133 144 | 
             
            * TMail
         | 
| 134 145 |  | 
| 146 | 
            +
            == OPTIONAL
         | 
| 147 | 
            +
             | 
| 148 | 
            +
            * exifr - install exifr for exif access on default jpeg or tiff media, and
         | 
| 149 | 
            +
                      smart phone detection
         | 
| 150 | 
            +
             | 
| 135 151 | 
             
            == INSTALL
         | 
| 136 152 |  | 
| 137 153 | 
             
            conventional
         | 
| @@ -146,13 +162,6 @@ github | |
| 146 162 | 
             
            git clone git://github.com/monde/mms2r.git
         | 
| 147 163 | 
             
            svn co svn://rubyforge.org/var/svn/mms2r/trunk mms2r
         | 
| 148 164 |  | 
| 149 | 
            -
            == CONTRIBUTE
         | 
| 150 | 
            -
             | 
| 151 | 
            -
            If you contribute a patch that is accepted then you'll get developer rights 
         | 
| 152 | 
            -
            for the project on RubyForge.  Please ensure your work includes 100% test 
         | 
| 153 | 
            -
            converage.  The library is ZenTest autotest discovery enabled so running 
         | 
| 154 | 
            -
            autotest in the root of the project is very helpful during development.
         | 
| 155 | 
            -
             | 
| 156 165 | 
             
            == AUTHORS
         | 
| 157 166 |  | 
| 158 167 | 
             
            Copyright (c) 2007-2008 by Mike Mondragon (blog[http://blog.mondragon.cc/])
         | 
| @@ -174,6 +183,8 @@ MMS2R's Flickr page[http://www.flickr.com/photos/8627919@N05/] | |
| 174 183 | 
             
            * Matt Conway
         | 
| 175 184 | 
             
            * Kai Kai
         | 
| 176 185 | 
             
            * Michael DelGaudio
         | 
| 186 | 
            +
            * Sai Emrys (blog[http://saizai.com])
         | 
| 187 | 
            +
            * Brendan Lim (github profile[http://github.com/brendanlim])
         | 
| 177 188 |  | 
| 178 189 | 
             
            == LICENSE
         | 
| 179 190 |  | 
    
        data/Rakefile
    CHANGED
    
    | @@ -16,11 +16,11 @@ Hoe.new('mms2r', MMS2R::Media::VERSION) do |p| | |
| 16 16 | 
             
              p.author = 'Mike Mondragon'
         | 
| 17 17 | 
             
              p.email = 'mikemondragon@gmail.com'
         | 
| 18 18 | 
             
              p.summary = 'Extract user media from MMS (and not carrier cruft)'
         | 
| 19 | 
            -
              p.description = p.paragraphs_of('README.txt', 2.. | 
| 19 | 
            +
              p.description = p.paragraphs_of('README.txt', 2..7).join("\n\n")
         | 
| 20 20 | 
             
              p.url = p.paragraphs_of('README.txt', 1).first.strip
         | 
| 21 | 
            -
              p.changes = p.paragraphs_of('History.txt', 0.. | 
| 22 | 
            -
              p.extra_deps << ['hpricot' | 
| 23 | 
            -
              p.extra_deps << ['tmail' | 
| 21 | 
            +
              p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
         | 
| 22 | 
            +
              p.extra_deps << ['hpricot']
         | 
| 23 | 
            +
              p.extra_deps << ['tmail']
         | 
| 24 24 | 
             
              p.clean_globs << 'coverage'
         | 
| 25 25 | 
             
            end
         | 
| 26 26 |  | 
    
        data/conf/mms2r_media.yml
    CHANGED
    
    | @@ -1,9 +1,13 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            ignore:
         | 
| 3 | 
            -
             | 
| 4 | 
            -
             | 
| 5 | 
            -
              | 
| 6 | 
            -
             | 
| 3 | 
            +
              text/plain:
         | 
| 4 | 
            +
              - /^\(no subject\)$/i
         | 
| 5 | 
            +
              - /\ASent via BlackBerry (from|by) .*$/im
         | 
| 6 | 
            +
              - /\ASent from my Verizon Wireless BlackBerry$/im
         | 
| 7 | 
            +
              - /\ASent from (my|your) iPhone.?$/im
         | 
| 8 | 
            +
              - /\ASent on the Sprint.* Now Network.*$/im
         | 
| 9 | 
            +
              multipart/mixed:
         | 
| 10 | 
            +
              - "/^Attachment: /i"
         | 
| 7 11 | 
             
            transform: 
         | 
| 8 12 | 
             
              text/plain: 
         | 
| 9 13 | 
             
              - - /\A(.*?)Sent via BlackBerry (from|by) .*$/im
         | 
| @@ -14,11 +18,14 @@ transform: | |
| 14 18 | 
             
                - "\1"
         | 
| 15 19 | 
             
              - - /\A(.*?)\s+image\/jpeg$/im
         | 
| 16 20 | 
             
                - "\1"
         | 
| 21 | 
            +
              - - /\A(.*?)Sent on the Sprint.* Now Network.*$/im
         | 
| 22 | 
            +
                - "\1"
         | 
| 17 23 | 
             
            device_types: 
         | 
| 18 | 
            -
              headers: | 
| 19 | 
            -
                 | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
                 | 
| 23 | 
            -
             | 
| 24 | 
            -
                - | 
| 24 | 
            +
              headers:
         | 
| 25 | 
            +
                x-mailer:
         | 
| 26 | 
            +
                  :iphone: !ruby/regexp /iPhone Mail/i
         | 
| 27 | 
            +
                  :blackberry: !ruby/regexp /Palm webOS/i
         | 
| 28 | 
            +
                mime-version:
         | 
| 29 | 
            +
                  :iphone: !ruby/regexp /iPhone Mail/i
         | 
| 30 | 
            +
                x-rim-org-msg-ref-id:
         | 
| 31 | 
            +
                  :blackberry: !ruby/regexp /.+/
         | 
    
        data/conf/vzwpix.com.yml
    CHANGED
    
    | @@ -1,8 +1,8 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            ignore:
         | 
| 3 3 | 
             
              text/plain: 
         | 
| 4 | 
            -
              - /\AThis message was sent using  | 
| 4 | 
            +
              - /\AThis message was sent using .* from Verizon Wireless!.*/m
         | 
| 5 5 | 
             
            transform: 
         | 
| 6 6 | 
             
              text/plain: 
         | 
| 7 | 
            -
              - - /\A(.+?)\s+This message was sent using  | 
| 7 | 
            +
              - - /\A(.+?)\s+This message was sent using .* from Verizon Wireless!.*/m
         | 
| 8 8 | 
             
                - "\1"
         | 
    
        data/init.rb
    ADDED
    
    | @@ -0,0 +1 @@ | |
| 1 | 
            +
            require File.dirname(__FILE__) + "/lib/mms2r"
         | 
    
        data/lib/mms2r.rb
    CHANGED
    
    | @@ -1,5 +1,5 @@ | |
| 1 1 | 
             
            #--
         | 
| 2 | 
            -
            # Copyright (c) 2007 | 
| 2 | 
            +
            # Copyright (c) 2007-2010 by Mike Mondragon (mikemondragon@gmail.com)
         | 
| 3 3 | 
             
            #
         | 
| 4 4 | 
             
            # Please see the LICENSE file for licensing information.
         | 
| 5 5 | 
             
            #++
         | 
| @@ -39,14 +39,21 @@ module MMS2R | |
| 39 39 | 
             
                ##
         | 
| 40 40 | 
             
                # MMS2R library version
         | 
| 41 41 |  | 
| 42 | 
            -
                VERSION = '2. | 
| 42 | 
            +
                VERSION = '2.3.0'
         | 
| 43 43 |  | 
| 44 44 | 
             
              end
         | 
| 45 45 |  | 
| 46 | 
            +
              # Simple convenience function to make it a one-liner:
         | 
| 47 | 
            +
              # MMS2R.parse raw_mail or MMS2R.parse File.load(raw_mail)
         | 
| 48 | 
            +
              # Combined w/ the method_missing delegation, this should behave as an enhanced TMail object, more or less.
         | 
| 49 | 
            +
              def self.parse raw_mail
         | 
| 50 | 
            +
                mail = TMail::Mail.parse raw_mail
         | 
| 51 | 
            +
                MMS2R::Media.new(mail)
         | 
| 52 | 
            +
              end
         | 
| 53 | 
            +
             | 
| 46 54 | 
             
            end
         | 
| 47 55 |  | 
| 48 56 | 
             
            require 'rubygems'
         | 
| 49 | 
            -
            gem 'tmail', '>= 1.2.3'
         | 
| 50 57 | 
             
            require 'tmail/mail'
         | 
| 51 58 | 
             
            require 'fileutils'
         | 
| 52 59 | 
             
            require 'pathname'
         | 
    
        data/lib/mms2r/media.rb
    CHANGED
    
    | @@ -1,22 +1,22 @@ | |
| 1 1 | 
             
            #--
         | 
| 2 | 
            -
            # Copyright (c) 2007 | 
| 2 | 
            +
            # Copyright (c) 2007-2010 by Mike Mondragon (mikemondragon@gmail.com)
         | 
| 3 3 | 
             
            #
         | 
| 4 | 
            -
            # Please see the LICENSE file for licensing information
         | 
| 4 | 
            +
            # Please see the LICENSE file for licensing information.
         | 
| 5 5 | 
             
            #++
         | 
| 6 6 |  | 
| 7 7 | 
             
            ##
         | 
| 8 8 | 
             
            # = Synopsis
         | 
| 9 9 | 
             
            #
         | 
| 10 | 
            -
            # MMS2R is a library to collect media files from MMS messages.  MMS messages | 
| 11 | 
            -
            # are multipart emails and mobile carriers often inject branding into these | 
| 12 | 
            -
            # messages.  MMS2R strips the advertising from an MMS leaving the actual user | 
| 10 | 
            +
            # MMS2R is a library to collect media files from MMS messages.  MMS messages
         | 
| 11 | 
            +
            # are multipart emails and mobile carriers often inject branding into these
         | 
| 12 | 
            +
            # messages.  MMS2R strips the advertising from an MMS leaving the actual user
         | 
| 13 13 | 
             
            # generated media.
         | 
| 14 14 | 
             
            #
         | 
| 15 | 
            -
            # The Tracker for MMS2R is located at | 
| 15 | 
            +
            # The Tracker for MMS2R is located at
         | 
| 16 16 | 
             
            # http://rubyforge.org/tracker/?group_id=3065
         | 
| 17 17 | 
             
            # Please submit bugs and feature requests using the Tracker.
         | 
| 18 18 | 
             
            #
         | 
| 19 | 
            -
            # If MMS from a carrier not known by MMS2R is encountered please submit a | 
| 19 | 
            +
            # If MMS from a carrier not known by MMS2R is encountered please submit a
         | 
| 20 20 | 
             
            # sample to the author for inclusion in this project.
         | 
| 21 21 | 
             
            #
         | 
| 22 22 | 
             
            # == Stand Alone Example
         | 
| @@ -48,31 +48,31 @@ | |
| 48 48 | 
             
            # == Built In Configuration
         | 
| 49 49 | 
             
            #
         | 
| 50 50 | 
             
            # A custom configuration can be created for processing the MMS from carriers
         | 
| 51 | 
            -
            # that are not currently known by MMS2R.  In the  conf/ directory create a | 
| 52 | 
            -
            # YAML file named by combining the domain name of the MMS sender plus a .yml | 
| 53 | 
            -
            # extension.  For instance the configuration of senders from AT&T's cellular | 
| 54 | 
            -
            # service with a Sender pattern of 2065551212@mms.att.net have a configuration | 
| 51 | 
            +
            # that are not currently known by MMS2R.  In the  conf/ directory create a
         | 
| 52 | 
            +
            # YAML file named by combining the domain name of the MMS sender plus a .yml
         | 
| 53 | 
            +
            # extension.  For instance the configuration of senders from AT&T's cellular
         | 
| 54 | 
            +
            # service with a Sender pattern of 2065551212@mms.att.net have a configuration
         | 
| 55 55 | 
             
            # named conf/mms.att.net.yml
         | 
| 56 56 | 
             
            #
         | 
| 57 57 | 
             
            # The YAML configuration contains a Hash with instructions for determining what
         | 
| 58 58 | 
             
            # is content generated by the user and what is content inserted by the carrier.
         | 
| 59 59 | 
             
            #
         | 
| 60 | 
            -
            # The root hash itself has two hashes under the keys 'ignore' and 'transform', | 
| 60 | 
            +
            # The root hash itself has two hashes under the keys 'ignore' and 'transform',
         | 
| 61 61 | 
             
            # and an array under the 'number' key.
         | 
| 62 62 | 
             
            # Each hash is itself keyed by mime-type.  The value pointed to by the mime-type
         | 
| 63 | 
            -
            # key is an array.  The ignore arrays are first evaluated as a regular expressions | 
| 63 | 
            +
            # key is an array.  The ignore arrays are first evaluated as a regular expressions
         | 
| 64 64 | 
             
            # and if the evaluation fails as a equality for a string filename.  Ignores
         | 
| 65 65 | 
             
            # work by filename for the multi-part of the MMS that is being inspected.  The
         | 
| 66 | 
            -
            # array pointed to by the 'number' key represents an alternate mail header where | 
| 67 | 
            -
            # the sender's number can be found with a regular expression and replacement | 
| 66 | 
            +
            # array pointed to by the 'number' key represents an alternate mail header where
         | 
| 67 | 
            +
            # the sender's number can be found with a regular expression and replacement
         | 
| 68 68 | 
             
            # value for a gsub eval.
         | 
| 69 69 | 
             
            #
         | 
| 70 70 | 
             
            # The transform arrays are themselves an array of two element arrays.  The elements
         | 
| 71 71 | 
             
            # are parameters for gsub and will be evaluated from within the ruby code.
         | 
| 72 72 | 
             
            #
         | 
| 73 | 
            -
            # Ignore instructions are honored first then transform instructions.  In the sample, | 
| 74 | 
            -
            # masthead.jpg is ignored as a regular expression, and spacer.gif is ignored as a | 
| 75 | 
            -
            # filename comparison.  The transform has a match and a replacement, see the gsub | 
| 73 | 
            +
            # Ignore instructions are honored first then transform instructions.  In the sample,
         | 
| 74 | 
            +
            # masthead.jpg is ignored as a regular expression, and spacer.gif is ignored as a
         | 
| 75 | 
            +
            # filename comparison.  The transform has a match and a replacement, see the gsub
         | 
| 76 76 | 
             
            # documentation for more information about match and replace.
         | 
| 77 77 | 
             
            #
         | 
| 78 78 | 
             
            # --
         | 
| @@ -92,9 +92,9 @@ | |
| 92 92 | 
             
            #   - /^([^\s]+)\s.*/
         | 
| 93 93 | 
             
            #   - "\1"
         | 
| 94 94 | 
             
            #
         | 
| 95 | 
            -
            # Carriers often provide their services under many different domain names. | 
| 96 | 
            -
            # The conf/aliases.yml is a YAML file with a hash that maps alternative or | 
| 97 | 
            -
            # legacy carrier names to the most common name of their service.  For example | 
| 95 | 
            +
            # Carriers often provide their services under many different domain names.
         | 
| 96 | 
            +
            # The conf/aliases.yml is a YAML file with a hash that maps alternative or
         | 
| 97 | 
            +
            # legacy carrier names to the most common name of their service.  For example
         | 
| 98 98 | 
             
            # in terms of MMS2R txt.att.net is an alias for mms.att.net.  Therefore when
         | 
| 99 99 | 
             
            # an MMS with a Sender of txt.att.net is processed MMS2R will use the
         | 
| 100 100 | 
             
            # mms.att.net configuration to process the message.
         | 
| @@ -114,20 +114,26 @@ module MMS2R | |
| 114 114 | 
             
                  end
         | 
| 115 115 | 
             
                end
         | 
| 116 116 |  | 
| 117 | 
            +
                # Pass off everything we don't do to the TMail object
         | 
| 118 | 
            +
                # TODO: refactor to explicit addition a la http://blog.jayfields.com/2008/02/ruby-replace-methodmissing-with-dynamic.html
         | 
| 119 | 
            +
                def method_missing method, *args, &block
         | 
| 120 | 
            +
                  mail.send method, *args, &block
         | 
| 121 | 
            +
                end
         | 
| 122 | 
            +
             | 
| 117 123 | 
             
                ##
         | 
| 118 124 | 
             
                # TMail object that the media files were derived from.
         | 
| 119 125 |  | 
| 120 126 | 
             
                attr_reader :mail
         | 
| 121 127 |  | 
| 122 128 | 
             
                ##
         | 
| 123 | 
            -
                # media returns the hash of media.  The media hash is keyed by mime-type | 
| 124 | 
            -
                # such as 'text/plain' and the value mapped to the key is an array of | 
| 129 | 
            +
                # media returns the hash of media.  The media hash is keyed by mime-type
         | 
| 130 | 
            +
                # such as 'text/plain' and the value mapped to the key is an array of
         | 
| 125 131 | 
             
                # media that are of that type.
         | 
| 126 132 |  | 
| 127 133 | 
             
                attr_reader :media
         | 
| 128 134 |  | 
| 129 135 | 
             
                ##
         | 
| 130 | 
            -
                # Carrier is the domain name of the carrier.  If the carrier is not known | 
| 136 | 
            +
                # Carrier is the domain name of the carrier.  If the carrier is not known
         | 
| 131 137 | 
             
                # the carrier will be set to 'mms2r.media'
         | 
| 132 138 |  | 
| 133 139 | 
             
                attr_reader :carrier
         | 
| @@ -143,14 +149,14 @@ module MMS2R | |
| 143 149 | 
             
                MULTIPARTS_TO_SPLIT = [ 'multipart/related', 'multipart/alternative', 'multipart/mixed', 'multipart/appledouble' ]
         | 
| 144 150 |  | 
| 145 151 | 
             
                ##
         | 
| 146 | 
            -
                # Factory method that creates MMS2R::Media products based on the domain | 
| 147 | 
            -
                # name of the carrier from which the MMS originated.  mail is a TMail | 
| 152 | 
            +
                # Factory method that creates MMS2R::Media products based on the domain
         | 
| 153 | 
            +
                # name of the carrier from which the MMS originated.  mail is a TMail
         | 
| 148 154 | 
             
                # object.
         | 
| 149 155 |  | 
| 150 156 | 
             
                def self.create(mail)
         | 
| 151 157 | 
             
                  d = lambda{ ['mms2r.media', MMS2R::Media] } #sets a default to detect
         | 
| 152 158 | 
             
                  from_domain = self.domain(mail)
         | 
| 153 | 
            -
                  processor = MMS2R::CARRIERS.detect(d) do |domain, klass| | 
| 159 | 
            +
                  processor = MMS2R::CARRIERS.detect(d) do |domain, klass|
         | 
| 154 160 | 
             
                    return klass, domain if from_domain == domain
         | 
| 155 161 | 
             
                  end
         | 
| 156 162 | 
             
                  [MMS2R::Media, from_domain]
         | 
| @@ -158,8 +164,8 @@ module MMS2R | |
| 158 164 |  | 
| 159 165 | 
             
                ##
         | 
| 160 166 | 
             
                # Determine if return-path or from is going to be used to desiginate the
         | 
| 161 | 
            -
                # origin carrier.  If the domain in the From header is listed in | 
| 162 | 
            -
                # conf/from.yaml then that is the carrier domain.  Else if there is a | 
| 167 | 
            +
                # origin carrier.  If the domain in the From header is listed in
         | 
| 168 | 
            +
                # conf/from.yaml then that is the carrier domain.  Else if there is a
         | 
| 163 169 | 
             
                # Return-Path header its address's domain is the carrier doamin, else
         | 
| 164 170 | 
             
                # use From header's address domain.
         | 
| 165 171 |  | 
| @@ -211,7 +217,7 @@ module MMS2R | |
| 211 217 | 
             
                  log("#{self.class} created", :info)
         | 
| 212 218 | 
             
                  @carrier = opts[:domain]
         | 
| 213 219 | 
             
                  @dir_count = 0
         | 
| 214 | 
            -
                  @media_dir = File.join(self.tmp_dir(), | 
| 220 | 
            +
                  @media_dir = File.join(self.tmp_dir(),
         | 
| 215 221 | 
             
                                 self.safe_message_id(@mail.message_id))
         | 
| 216 222 | 
             
                  @media = {}
         | 
| 217 223 | 
             
                  @was_processed = false
         | 
| @@ -220,7 +226,7 @@ module MMS2R | |
| 220 226 | 
             
                  @body = nil
         | 
| 221 227 | 
             
                  @default_media = nil
         | 
| 222 228 | 
             
                  @default_text = nil
         | 
| 223 | 
            -
             | 
| 229 | 
            +
             | 
| 224 230 | 
             
                  f = File.join(self.conf_dir(), "aliases.yml")
         | 
| 225 231 | 
             
                  @aliases = YAML::load_file(f) rescue {}
         | 
| 226 232 |  | 
| @@ -234,9 +240,9 @@ module MMS2R | |
| 234 240 | 
             
                end
         | 
| 235 241 |  | 
| 236 242 | 
             
                ##
         | 
| 237 | 
            -
                # Get the phone number associated with this MMS if it exists.  The value | 
| 238 | 
            -
                # returned is simplistic, it is just the user name of the from address | 
| 239 | 
            -
                # before the @ symbol.  Validation of the number is left to you.  Most | 
| 243 | 
            +
                # Get the phone number associated with this MMS if it exists.  The value
         | 
| 244 | 
            +
                # returned is simplistic, it is just the user name of the from address
         | 
| 245 | 
            +
                # before the @ symbol.  Validation of the number is left to you.  Most
         | 
| 240 246 | 
             
                # carriers are using the real phone number as the username.
         | 
| 241 247 |  | 
| 242 248 | 
             
                def number
         | 
| @@ -268,8 +274,8 @@ module MMS2R | |
| 268 274 | 
             
                  @subject
         | 
| 269 275 | 
             
                end
         | 
| 270 276 |  | 
| 271 | 
            -
                # Convenience method that returns a string including all the text of the | 
| 272 | 
            -
                # first text/plain file found.  Returns empty string if no body text | 
| 277 | 
            +
                # Convenience method that returns a string including all the text of the
         | 
| 278 | 
            +
                # first text/plain file found.  Returns empty string if no body text
         | 
| 273 279 | 
             
                # is found.
         | 
| 274 280 |  | 
| 275 281 | 
             
                def body
         | 
| @@ -279,22 +285,22 @@ module MMS2R | |
| 279 285 | 
             
                end
         | 
| 280 286 |  | 
| 281 287 | 
             
                # Returns a File with the most likely candidate for the user-submitted
         | 
| 282 | 
            -
                # media.  Given that most MMS messages only have one file attached, this | 
| 283 | 
            -
                # method will try to return that file.  Singleton methods are added to | 
| 284 | 
            -
                # the File object so it can be used in place of a CGI upload (local_path, | 
| 288 | 
            +
                # media.  Given that most MMS messages only have one file attached, this
         | 
| 289 | 
            +
                # method will try to return that file.  Singleton methods are added to
         | 
| 290 | 
            +
                # the File object so it can be used in place of a CGI upload (local_path,
         | 
| 285 291 | 
             
                # original_filename, size, and content_type) such as in conjunction with
         | 
| 286 292 | 
             
                # AttachementFu.  The largest file found in terms of bytes is returned.
         | 
| 287 293 | 
             
                #
         | 
| 288 294 | 
             
                # Returns nil if there are not any video or image Files found.
         | 
| 289 295 |  | 
| 290 296 | 
             
                def default_media
         | 
| 291 | 
            -
                  @default_media ||= attachment(['video', 'image', 'text'])
         | 
| 297 | 
            +
                  @default_media ||= attachment(['video', 'image', 'application', 'text'])
         | 
| 292 298 | 
             
                end
         | 
| 293 299 |  | 
| 294 300 | 
             
                # Returns a File with the most likely candidate that is text, or nil
         | 
| 295 | 
            -
                # otherwise.  It also adds singleton methods to the File object so it can be | 
| 296 | 
            -
                # used in place of a CGI upload (local_path, original_filename, size, and | 
| 297 | 
            -
                # content_type) such as in conjunction with AttachmentFu.  The largest file | 
| 301 | 
            +
                # otherwise.  It also adds singleton methods to the File object so it can be
         | 
| 302 | 
            +
                # used in place of a CGI upload (local_path, original_filename, size, and
         | 
| 303 | 
            +
                # content_type) such as in conjunction with AttachmentFu.  The largest file
         | 
| 298 304 | 
             
                # found in terms of bytes is returned.
         | 
| 299 305 | 
             
                #
         | 
| 300 306 | 
             
                # Returns nil if there are not any text Files found
         | 
| @@ -305,9 +311,9 @@ module MMS2R | |
| 305 311 |  | 
| 306 312 | 
             
                ##
         | 
| 307 313 | 
             
                # process is a template method and collects all the media in a MMS.
         | 
| 308 | 
            -
                # Override helper methods to this template to clean out advertising and/or | 
| 309 | 
            -
                # ignore media that are advertising.  This method should not be overridden | 
| 310 | 
            -
                # unless there is an extreme special case in processing the media of a MMS | 
| 314 | 
            +
                # Override helper methods to this template to clean out advertising and/or
         | 
| 315 | 
            +
                # ignore media that are advertising.  This method should not be overridden
         | 
| 316 | 
            +
                # unless there is an extreme special case in processing the media of a MMS
         | 
| 311 317 | 
             
                # (like Sprint)
         | 
| 312 318 | 
             
                #
         | 
| 313 319 | 
             
                # Helper methods for the process template:
         | 
| @@ -315,7 +321,7 @@ module MMS2R | |
| 315 321 | 
             
                # * process_media -- retrieves media to temporary file, returns path to file.
         | 
| 316 322 | 
             
                # * transform_text -- called by process_media, strips out advertising.
         | 
| 317 323 | 
             
                # * temp_file -- creates a temporary filepath based on information from the part.
         | 
| 318 | 
            -
                # | 
| 324 | 
            +
                #
         | 
| 319 325 | 
             
                # Block support:
         | 
| 320 326 | 
             
                # Call process() with a block to automatically iterate through media.
         | 
| 321 327 | 
             
                # For example, to process and receive only media of video type:
         | 
| @@ -329,11 +335,11 @@ module MMS2R | |
| 329 335 | 
             
                def process() # :yields: media_type, file
         | 
| 330 336 | 
             
                  unless @was_processed
         | 
| 331 337 | 
             
                    log("#{self.class} processing", :info)
         | 
| 332 | 
            -
             | 
| 338 | 
            +
             | 
| 333 339 | 
             
                    parts = mail.multipart? ? mail.parts : [mail]
         | 
| 334 | 
            -
             | 
| 335 | 
            -
                    # Double check for multipart/related, if it exists replace it with its | 
| 336 | 
            -
                    # children parts.  Do this twice as multipart/alternative can have | 
| 340 | 
            +
             | 
| 341 | 
            +
                    # Double check for multipart/related, if it exists replace it with its
         | 
| 342 | 
            +
                    # children parts.  Do this twice as multipart/alternative can have
         | 
| 337 343 | 
             
                    # children and we want to fold everything down
         | 
| 338 344 | 
             
                    for i in 1..2
         | 
| 339 345 | 
             
                      flat = []
         | 
| @@ -343,10 +349,10 @@ module MMS2R | |
| 343 349 | 
             
                        else
         | 
| 344 350 | 
             
                          flat << p
         | 
| 345 351 | 
             
                        end
         | 
| 346 | 
            -
                      end | 
| 352 | 
            +
                      end
         | 
| 347 353 | 
             
                      parts = flat.dup
         | 
| 348 | 
            -
                    end | 
| 349 | 
            -
             | 
| 354 | 
            +
                    end
         | 
| 355 | 
            +
             | 
| 350 356 | 
             
                    # get to work
         | 
| 351 357 | 
             
                    parts.each do |p|
         | 
| 352 358 | 
             
                      t = p.part_type?
         | 
| @@ -369,8 +375,8 @@ module MMS2R | |
| 369 375 | 
             
                end
         | 
| 370 376 |  | 
| 371 377 | 
             
                ##
         | 
| 372 | 
            -
                # Helper for process template method to determine if media contained in a | 
| 373 | 
            -
                # part should be ignored.  Producers should override this method to return | 
| 378 | 
            +
                # Helper for process template method to determine if media contained in a
         | 
| 379 | 
            +
                # part should be ignored.  Producers should override this method to return
         | 
| 374 380 | 
             
                # true for media such as images that are advertising, carrier logos, etc.
         | 
| 375 381 | 
             
                # See the ignore section in the discussion of the built-in configuration.
         | 
| 376 382 |  | 
| @@ -379,18 +385,18 @@ module MMS2R | |
| 379 385 | 
             
                  ignore = ignores.detect{|test| filename?(part) == test}
         | 
| 380 386 | 
             
                  ignore ||= ignores.detect{|test| filename?(part) =~ eval(test) if test.index('/') == 0 }
         | 
| 381 387 | 
             
                  ignore ||= ignores.detect{|test| part.body.strip =~ eval(test) if test.index('/') == 0 }
         | 
| 382 | 
            -
                  ignore ||= (part.body.strip.size == 0 ? true : nil) | 
| 388 | 
            +
                  ignore ||= (part.body.strip.size == 0 ? true : nil)
         | 
| 383 389 | 
             
                  ignore.nil? ? false : true
         | 
| 384 390 | 
             
                end
         | 
| 385 391 |  | 
| 386 392 | 
             
                ##
         | 
| 387 | 
            -
                # Helper for process template method to decode the part based on its type | 
| 388 | 
            -
                # and write its content to a temporary file.  Returns path to temporary | 
| 389 | 
            -
                # file that holds the content.  Parts with a main type of text will have | 
| 393 | 
            +
                # Helper for process template method to decode the part based on its type
         | 
| 394 | 
            +
                # and write its content to a temporary file.  Returns path to temporary
         | 
| 395 | 
            +
                # file that holds the content.  Parts with a main type of text will have
         | 
| 390 396 | 
             
                # their contents transformed with a call to transform_text
         | 
| 391 397 | 
             
                #
         | 
| 392 | 
            -
                # Producers should only override this method if the parts of the MMS need | 
| 393 | 
            -
                # special treatment besides what is expected for a normal mime part (like | 
| 398 | 
            +
                # Producers should only override this method if the parts of the MMS need
         | 
| 399 | 
            +
                # special treatment besides what is expected for a normal mime part (like
         | 
| 394 400 | 
             
                # Sprint).
         | 
| 395 401 | 
             
                #
         | 
| 396 402 | 
             
                # Returns a tuple of content type, file path
         | 
| @@ -399,7 +405,7 @@ module MMS2R | |
| 399 405 | 
             
                  # TMail body auto-magically decodes quoted
         | 
| 400 406 | 
             
                  # printable for text/html type.
         | 
| 401 407 | 
             
                  file = temp_file(part)
         | 
| 402 | 
            -
                  if part.main_type('text') == 'text' || | 
| 408 | 
            +
                  if part.main_type('text') == 'text' ||
         | 
| 403 409 | 
             
                     part.content_type == 'application/smil'
         | 
| 404 410 | 
             
                    type, content = transform_text_part(part)
         | 
| 405 411 | 
             
                    mode = 'w'
         | 
| @@ -421,11 +427,11 @@ module MMS2R | |
| 421 427 |  | 
| 422 428 | 
             
                ##
         | 
| 423 429 | 
             
                # Helper for process_media template method to transform text.
         | 
| 424 | 
            -
                # See the transform section in the discussion of the built-in | 
| 430 | 
            +
                # See the transform section in the discussion of the built-in
         | 
| 425 431 | 
             
                # configuration.
         | 
| 426 432 |  | 
| 427 433 | 
             
                def transform_text(type, text, original_nencoding = 'ISO-8859-1')
         | 
| 428 | 
            -
                  return type, text unless transforms = config['transform'][type] | 
| 434 | 
            +
                  return type, text unless transforms = config['transform'][type]
         | 
| 429 435 |  | 
| 430 436 | 
             
                  #convert to UTF-8
         | 
| 431 437 | 
             
                  begin
         | 
| @@ -441,7 +447,7 @@ module MMS2R | |
| 441 447 | 
             
                    r = transform.last
         | 
| 442 448 | 
             
                    utf_t = utf_t.gsub(eval(p), r) rescue utf_t
         | 
| 443 449 | 
             
                  end
         | 
| 444 | 
            -
             | 
| 450 | 
            +
             | 
| 445 451 | 
             
                  return type, utf_t
         | 
| 446 452 | 
             
                end
         | 
| 447 453 |  | 
| @@ -455,12 +461,12 @@ module MMS2R | |
| 455 461 | 
             
                end
         | 
| 456 462 |  | 
| 457 463 | 
             
                ##
         | 
| 458 | 
            -
                # Helper for process template method to name a temporary filepath based on | 
| 459 | 
            -
                # information in the part.  This version attempts to honor the name of the | 
| 460 | 
            -
                # media as labeled in the part header and creates a unique temporary | 
| 464 | 
            +
                # Helper for process template method to name a temporary filepath based on
         | 
| 465 | 
            +
                # information in the part.  This version attempts to honor the name of the
         | 
| 466 | 
            +
                # media as labeled in the part header and creates a unique temporary
         | 
| 461 467 | 
             
                # directory for writing the file so filename collision does not occur.
         | 
| 462 | 
            -
                # Consumers of this method expect the directory structure to the file | 
| 463 | 
            -
                # exists, if the method is overridden it is mandatory that this behavior is | 
| 468 | 
            +
                # Consumers of this method expect the directory structure to the file
         | 
| 469 | 
            +
                # exists, if the method is overridden it is mandatory that this behavior is
         | 
| 464 470 | 
             
                # retained.
         | 
| 465 471 |  | 
| 466 472 | 
             
                def temp_file(part)
         | 
| @@ -469,7 +475,7 @@ module MMS2R | |
| 469 475 | 
             
                end
         | 
| 470 476 |  | 
| 471 477 | 
             
                ##
         | 
| 472 | 
            -
                # Purges the unique MMS2R::Media.media_dir directory created | 
| 478 | 
            +
                # Purges the unique MMS2R::Media.media_dir directory created
         | 
| 473 479 | 
             
                # for this producer and all of the media that it contains.
         | 
| 474 480 |  | 
| 475 481 | 
             
                def purge()
         | 
| @@ -486,7 +492,7 @@ module MMS2R | |
| 486 492 | 
             
                end
         | 
| 487 493 |  | 
| 488 494 | 
             
                ##
         | 
| 489 | 
            -
                # Helper to temp_file to create a unique temporary directory that is a | 
| 495 | 
            +
                # Helper to temp_file to create a unique temporary directory that is a
         | 
| 490 496 | 
             
                # child of tmp_dir  This version is based on the message_id of the mail.
         | 
| 491 497 |  | 
| 492 498 | 
             
                def msg_tmp_dir()
         | 
| @@ -519,7 +525,7 @@ module MMS2R | |
| 519 525 | 
             
                    base = File.basename(name, ext)
         | 
| 520 526 | 
             
                    name = "#{base[0, 255 - ext.size]}#{ext}"
         | 
| 521 527 | 
             
                  end
         | 
| 522 | 
            -
             | 
| 528 | 
            +
             | 
| 523 529 | 
             
                  name
         | 
| 524 530 | 
             
                end
         | 
| 525 531 |  | 
| @@ -528,28 +534,76 @@ module MMS2R | |
| 528 534 | 
             
                end
         | 
| 529 535 |  | 
| 530 536 | 
             
                ##
         | 
| 531 | 
            -
                # Best guess of the mobile device type.  Simple heuristics thus far for | 
| 532 | 
            -
                # :iphone :blackberry :handset :unknown .  Could be expanded for exif | 
| 537 | 
            +
                # Best guess of the mobile device type.  Simple heuristics thus far for
         | 
| 538 | 
            +
                # :iphone :blackberry :handset :unknown .  Could be expanded for exif
         | 
| 533 539 | 
             
                # probing or shifting mail header schemes
         | 
| 534 540 |  | 
| 535 541 | 
             
                def device_type?
         | 
| 542 | 
            +
                  begin
         | 
| 543 | 
            +
                    # rely on native exif first with exifr gem if its loaded
         | 
| 544 | 
            +
                    require 'exifr'
         | 
| 545 | 
            +
                    file = attachment(['image'])
         | 
| 546 | 
            +
                    if file
         | 
| 547 | 
            +
                      original = file.original_filename
         | 
| 548 | 
            +
                      @exif = case original
         | 
| 549 | 
            +
                              when /\.jpg$/i
         | 
| 550 | 
            +
                                EXIFR::JPEG.new(file)
         | 
| 551 | 
            +
                              when /\.jepg$/i
         | 
| 552 | 
            +
                                EXIFR::JPEG.new(file)
         | 
| 553 | 
            +
                              when /\.tif$/i
         | 
| 554 | 
            +
                                EXIFR::TIFF.new(file)
         | 
| 555 | 
            +
                              when /\.tiff$/i
         | 
| 556 | 
            +
                                EXIFR::TIFF.new(file)
         | 
| 557 | 
            +
                              end
         | 
| 558 | 
            +
                      if @exif
         | 
| 559 | 
            +
                        # TODO do something about the assortment of camera models that have 
         | 
| 560 | 
            +
                        # been seen:
         | 
| 561 | 
            +
                        # 1.3 Megapixel, 2.0 Megapixel, BlackBerry, CU920, G'z One TYPE-S,
         | 
| 562 | 
            +
                        # Hermes, iPhone, LG8700, LSI_S5K4AAFA, Micron MT9M113 1.3MP YUV,
         | 
| 563 | 
            +
                        # Motorola Phone, Omni_vision-9650, Pre,
         | 
| 564 | 
            +
                        # Seoul Electronics & Telecom SIM120B 1.3M, SGH-T729, SGH-T819,
         | 
| 565 | 
            +
                        # SPH-M540, SPH-M800, SYSTEMLSI S5K4BAFB 2.0 MP, VX-9700
         | 
| 566 | 
            +
                        case @exif.model
         | 
| 567 | 
            +
                        when/iPhone/i
         | 
| 568 | 
            +
                          return :iphone
         | 
| 569 | 
            +
                        when/BlackBerry/i
         | 
| 570 | 
            +
                          return :blackberry
         | 
| 571 | 
            +
                        end
         | 
| 572 | 
            +
                      end
         | 
| 573 | 
            +
                    end
         | 
| 574 | 
            +
                  rescue LoadError => err
         | 
| 575 | 
            +
                  end
         | 
| 576 | 
            +
             | 
| 536 577 | 
             
                  headers = config['device_types']['headers'] rescue {}
         | 
| 537 578 | 
             
                  headers.keys.each do |header|
         | 
| 538 579 | 
             
                    if mail.header[header.downcase]
         | 
| 539 | 
            -
                       | 
| 540 | 
            -
                       | 
| 580 | 
            +
                      # headers[header] refers to a hash of smart phone types with regex values
         | 
| 581 | 
            +
                      # that if they match the header signals the type should be returned
         | 
| 582 | 
            +
                      headers[header].each do |type, regex|
         | 
| 583 | 
            +
                        # HACK to get at the full value of the header before TMail parses according to spec
         | 
| 584 | 
            +
                        # see @body in and ensure_parsed in lib/tmail/header.rb
         | 
| 585 | 
            +
                        return type if mail.header[header.downcase].instance_variable_get(:@body) =~ regex
         | 
| 586 | 
            +
                      end
         | 
| 541 587 | 
             
                    end
         | 
| 542 588 | 
             
                  end
         | 
| 543 589 |  | 
| 544 590 | 
             
                  return :handset if File.exist?(File.join(self.conf_dir,
         | 
| 545 591 | 
             
                                                 "#{self.aliases[self.carrier] || self.carrier}.yml"))
         | 
| 546 | 
            -
             | 
| 592 | 
            +
             | 
| 547 593 | 
             
                  :unknown
         | 
| 548 594 | 
             
                end
         | 
| 549 595 |  | 
| 596 | 
            +
                ##
         | 
| 597 | 
            +
                # exif object on default image from exifr gem
         | 
| 598 | 
            +
             | 
| 599 | 
            +
                def exif
         | 
| 600 | 
            +
                  device_type? unless @exif
         | 
| 601 | 
            +
                  @exif
         | 
| 602 | 
            +
                end
         | 
| 603 | 
            +
             | 
| 550 604 | 
             
                ##
         | 
| 551 605 | 
             
                # The source of the MMS was some sort of mobile or smart phone
         | 
| 552 | 
            -
             | 
| 606 | 
            +
             | 
| 553 607 | 
             
                def is_mobile?
         | 
| 554 608 | 
             
                  self.device_type? != :unknown
         | 
| 555 609 | 
             
                end
         | 
| @@ -596,7 +650,7 @@ module MMS2R | |
| 596 650 | 
             
                  if MMS2R::EXT[content_type]
         | 
| 597 651 | 
             
                    MMS2R::EXT[content_type]
         | 
| 598 652 | 
             
                  elsif content_type
         | 
| 599 | 
            -
                    content_type.split('/').last | 
| 653 | 
            +
                    content_type.split('/').last
         | 
| 600 654 | 
             
                  end
         | 
| 601 655 | 
             
                end
         | 
| 602 656 |  | 
| @@ -633,7 +687,7 @@ module MMS2R | |
| 633 687 |  | 
| 634 688 | 
             
                ##
         | 
| 635 689 | 
             
                # convenience accessor for self.class.conf_dir
         | 
| 636 | 
            -
             | 
| 690 | 
            +
             | 
| 637 691 | 
             
                def conf_dir
         | 
| 638 692 | 
             
                  self.class.conf_dir
         | 
| 639 693 | 
             
                end
         | 
| @@ -654,14 +708,14 @@ module MMS2R | |
| 654 708 |  | 
| 655 709 | 
             
                ##
         | 
| 656 710 | 
             
                # convenience accessor for self.class.safe_message_id
         | 
| 657 | 
            -
             | 
| 711 | 
            +
             | 
| 658 712 | 
             
                def safe_message_id(message_id)
         | 
| 659 713 | 
             
                  self.class.safe_message_id(message_id)
         | 
| 660 714 | 
             
                end
         | 
| 661 715 |  | 
| 662 716 | 
             
                ##
         | 
| 663 717 | 
             
                # convenience accessor for self.class.initialize_confg
         | 
| 664 | 
            -
             | 
| 718 | 
            +
             | 
| 665 719 | 
             
                def initialize_config(config)
         | 
| 666 720 | 
             
                  self.class.initialize_config(config)
         | 
| 667 721 | 
             
                end
         | 
| @@ -686,13 +740,13 @@ module MMS2R | |
| 686 740 |  | 
| 687 741 | 
             
                ##
         | 
| 688 742 | 
             
                # used by #default_media and #text to return the biggest attachment type
         | 
| 689 | 
            -
                # listed in the types array | 
| 743 | 
            +
                # listed in the types array
         | 
| 690 744 |  | 
| 691 745 | 
             
                def attachment(types)
         | 
| 692 746 |  | 
| 693 747 | 
             
                  # get all the files that are of the major types passed in
         | 
| 694 748 | 
             
                  files = []
         | 
| 695 | 
            -
             | 
| 749 | 
            +
             | 
| 696 750 | 
             
                  types.each do |type|
         | 
| 697 751 | 
             
                    media.keys.find_all{|k| type.include?("/") ? k == type : k.index(type) == 0 }.each do |key|
         | 
| 698 752 | 
             
                      files += media[key]
         | 
| @@ -710,7 +764,7 @@ module MMS2R | |
| 710 764 | 
             
                    if File.size(f) > size
         | 
| 711 765 | 
             
                      size = File.size(f)
         | 
| 712 766 | 
             
                      file = File.new(f)
         | 
| 713 | 
            -
                      mime_type = media.detect{|type,files| files.detect{|fl| fl == f}}[0] | 
| 767 | 
            +
                      mime_type = media.detect{|type,files| files.detect{|fl| fl == f}}[0]
         | 
| 714 768 | 
             
                    end
         | 
| 715 769 | 
             
                  end
         | 
| 716 770 |  |