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
|
|