reelagram-mail 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 90ae045d790e210a92350ceef2886b4e85313d93
4
+ data.tar.gz: f66c8c65867e75cd4bdaff261d846c3f814efa29
5
+ SHA512:
6
+ metadata.gz: 806b02ef106b007ced6fcde921ff000ce34099e8e920f40eca87e79066eead04e5af8d3e3abcfa18ac7f217b27f38002b67ec8d10dd1c3f8f1d849c4b4d0586a
7
+ data.tar.gz: 08f5058dc5650c3a83becfc068b576e5cdf16835c92249525b3b009a4a53f16805a9bf21fa31b526ca3cd3b43967eb74f91959be1f22b8fe67d18b747d9efb19
data/.gitignore ADDED
@@ -0,0 +1,35 @@
1
+ .bundle
2
+ db/*.sqlite3
3
+ log/*.log
4
+ tmp/
5
+ .DS_Store
6
+ *.gem
7
+ *.rbc
8
+ *.swp
9
+ *.tmproj
10
+ *~
11
+ .idea/
12
+ .\#*
13
+ .config
14
+ .yardoc
15
+ .bundle_cache
16
+ .tm_properties
17
+ InstalledFiles
18
+ \#*
19
+ _yardoc
20
+ coverage
21
+ lib/bundler/man
22
+ pkg
23
+ rdoc
24
+ spec/reports
25
+ test/tmp
26
+ test/version_tmp
27
+ tmp
28
+ tmtags
29
+ public/static
30
+ REVISION
31
+ .tm_properties
32
+ snapshot.sql
33
+ custom_plan.rb
34
+ zeus.json
35
+ .env
data/.ruby-gemset ADDED
@@ -0,0 +1,2 @@
1
+ reelagram-mail
2
+
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.1.1
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in reelagram.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,29 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ reelagram-mail (0.0.1)
5
+ ruby-gmail (= 0.3.1)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ dotenv (0.11.1)
11
+ mail (2.6.1)
12
+ mime-types (>= 1.16, < 3)
13
+ mime (0.4.2)
14
+ mime-types (2.3)
15
+ rake (0.9.6)
16
+ ruby-gmail (0.3.1)
17
+ mail (>= 2.2.1)
18
+ mime (>= 0.1)
19
+ shared-mime-info
20
+ shared-mime-info (0.2.5)
21
+
22
+ PLATFORMS
23
+ ruby
24
+
25
+ DEPENDENCIES
26
+ bundler (~> 1.3)
27
+ dotenv (= 0.11.1)
28
+ rake (~> 0)
29
+ reelagram-mail!
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Jon Wheeler
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # Reelagram
2
+
3
+ ## Installation
4
+
5
+ Add this line to your application's Gemfile:
6
+
7
+ gem 'reelagram-mail'
8
+
9
+ And then execute:
10
+
11
+ $ bundle
12
+
13
+ Or install it yourself as:
14
+
15
+ $ gem install reelagram-mail
16
+
17
+ ## Usage
18
+
19
+ ### Configure
20
+
21
+ ```ruby
22
+ Reelagram::Mail.configure do |c|
23
+ c.email = ENV["EMAIL_ACCOUNT"]
24
+ c.password = ENV["EMAIL_PASSWORD"]
25
+ end
26
+ ```
27
+
28
+ ### Shipping Emails
29
+
30
+ ```ruby
31
+ Reelagram::Mail.process_shipping_emails
32
+ ```
33
+
34
+ ## Contributing
35
+
36
+ 1. Fork it
37
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
38
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
39
+ 4. Push to the branch (`git push origin my-new-feature`)
40
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ task default: :test
4
+
5
+ task :test do
6
+ Dir.glob('./test/**/*_test.rb').each { |file| require file}
7
+ end
8
+
9
+ task :console do
10
+ $LOAD_PATH << "./lib"
11
+
12
+ require "irb"
13
+ require "irb/completion"
14
+ require "pp"
15
+ require "reelagram"
16
+
17
+ ARGV.clear
18
+ IRB.start
19
+ end
data/lib/reelagram.rb ADDED
@@ -0,0 +1,6 @@
1
+ require "reelagram/version"
2
+ require "reelagram/errors"
3
+ require "reelagram/mail"
4
+
5
+ module Reelagram
6
+ end
@@ -0,0 +1,3 @@
1
+ module Reelagram
2
+ class NotConfiguredError < StandardError ; end
3
+ end
@@ -0,0 +1,31 @@
1
+ require "reelagram/version"
2
+ require "reelagram/errors"
3
+ require "reelagram/mail/parsers"
4
+ require "reelagram/mail/processors"
5
+ require "reelagram/mail/fetchers"
6
+ require "reelagram/mail/configuration"
7
+
8
+ module Reelagram
9
+ module Mail
10
+ class << self
11
+ attr_accessor :configuration
12
+ end
13
+
14
+ def self.configure
15
+ self.configuration ||= Configuration.new
16
+ yield(configuration)
17
+ configured?
18
+ end
19
+
20
+ def self.configured?
21
+ return false if configuration.nil?
22
+ configuration.configured?
23
+ end
24
+
25
+ def self.process_shipping_emails
26
+ emails = Fetchers::ShippingFetcher.new.fetch
27
+ parser = Parsers::ShippingParser.new
28
+ Processors::ShippingProcessor.new(emails, parser).run
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,11 @@
1
+ module Reelagram
2
+ module Mail
3
+ class Configuration
4
+ attr_accessor :email, :password
5
+
6
+ def configured?
7
+ !email.nil? && !password.nil?
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,2 @@
1
+ require "reelagram/mail/fetchers/base_fetcher"
2
+ require "reelagram/mail/fetchers/shipping_fetcher"
@@ -0,0 +1,119 @@
1
+ require "gmail"
2
+ require "fileutils"
3
+
4
+ module Reelagram
5
+ module Mail
6
+ module Fetchers
7
+ class EmailFetcher
8
+ attr_reader :email, :password, :label, :after, :save_path
9
+
10
+ # Available options:
11
+ #
12
+ # - :email - Gmail mailbox email
13
+ # - :password - Mailbox password
14
+ # - :label - Mailbox label
15
+ # - :after - Start date
16
+ # - :save_path - Temporary location for pdf files
17
+ #
18
+ def initialize(options = {})
19
+ raise NotConfiguredError, "Configuration is required" unless Reelagram::Mail.configured?
20
+
21
+ @email = Mail.configuration.email
22
+ @password = Mail.configuration.password
23
+ @label = options[:label] || self.class::DEFAULT_LABEL
24
+ @after = options[:after]
25
+ @save_path = options[:save_path] || "/tmp"
26
+
27
+ unless File.exists?(@save_path)
28
+ FileUtils.mkdir_p(@save_path)
29
+ end
30
+ end
31
+
32
+ # Fetch invoices and yied a saved pdf file for further processing
33
+ #
34
+ # Fetcher establishes connection to the google mail server with provided
35
+ # credentials and performs an iteration over emails with label defined by
36
+ # SEARCH_LABEL constant. Emails without any attachments are ignored.
37
+ # If attachment file already exists locally it will be overwritten.
38
+ #
39
+ # @return [Array<String>] array with saved pdf files locations
40
+ #
41
+ def fetch(include_attachments = false)
42
+ results = emails.map do |message|
43
+ STDOUT.puts "Processing email: #{message_title(message)}"
44
+
45
+ {
46
+ from: message.from,
47
+ subject: message.subject,
48
+ body: message.body.decoded,
49
+ attachments: get_attachments(message, include_attachments) || []
50
+ }
51
+ end
52
+ # Close connection
53
+ connection.logout
54
+
55
+ # Return all fetched files
56
+ results
57
+ end
58
+
59
+ private
60
+
61
+ def connection
62
+ @connection ||= Gmail.new(@email, @password)
63
+ end
64
+
65
+ def mailbox
66
+ connection.mailbox(@label)
67
+ end
68
+
69
+ def emails
70
+ if @after
71
+ mailbox.emails(after: @after)
72
+ else
73
+ mailbox.emails(:unread)
74
+ end
75
+ end
76
+
77
+ def get_attachments(message, include_attachments)
78
+ return unless include_attachments
79
+
80
+ if message.attachments.size == 0
81
+ STDOUT.puts "No attachments found, skipped."
82
+ return
83
+ end
84
+
85
+ atts = []
86
+
87
+ message.attachments.each do |attachment|
88
+ path = File.join(@save_path, attachment.filename)
89
+
90
+ if File.exists?(path)
91
+ STDOUT.puts "File #{path} already exists, overwriting..."
92
+ File.unlink(path)
93
+ end
94
+
95
+ if save_attachment(attachment, path)
96
+ atts << path
97
+ yield path if block_given?
98
+ end
99
+ end
100
+
101
+ atts
102
+ end
103
+
104
+ def save_attachment(attachment, path)
105
+ file = File.new("#{@save_path}/#{attachment.filename}", "w+")
106
+ file << attachment.decoded
107
+ file.close
108
+
109
+ true
110
+ end
111
+
112
+ def message_title(message)
113
+ "#{message.subject} (from #{message.from.first})"
114
+ end
115
+
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,10 @@
1
+ module Reelagram
2
+ module Mail
3
+ module Fetchers
4
+ class ShippingFetcher < EmailFetcher
5
+ DEFAULT_LABEL = "Shipped!"
6
+ end
7
+ end
8
+ end
9
+ end
10
+
@@ -0,0 +1 @@
1
+ require "reelagram/mail/parsers/shipping_parser"
@@ -0,0 +1,36 @@
1
+ module Reelagram
2
+ module Mail
3
+ module Parsers
4
+ class ShippingParser
5
+ attr_reader :string
6
+
7
+ def run(string)
8
+ @string = string
9
+ self
10
+ end
11
+
12
+ def order_number
13
+ string.scan(/(?<=Purchase Order Number: ).*/).first
14
+ end
15
+
16
+ def carrier
17
+ shipping_info[0...-1].join(" ")
18
+ end
19
+
20
+ def tracking_number
21
+ shipping_info[-1]
22
+ end
23
+
24
+ private
25
+
26
+ def shipping_info
27
+ string.scan(/(?<=Shipped By Tracking Number).*(?=\<http)/m).
28
+ first.
29
+ gsub(/\n/, " ").
30
+ strip.
31
+ split(" ")
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1 @@
1
+ require "reelagram/mail/processors/shipping_processor"
@@ -0,0 +1,34 @@
1
+ module Reelagram
2
+ module Mail
3
+ module Processors
4
+ class ShippingProcessor
5
+ attr_reader :data, :parser
6
+ attr_reader :current_string
7
+ attr_reader :results
8
+
9
+ def initialize(data, parser)
10
+ @data = [data].flatten
11
+ @parser = parser
12
+ end
13
+
14
+ def run
15
+ data.map { |email| process_email(email[:body]) }
16
+ end
17
+
18
+ private
19
+
20
+ def process_email(email)
21
+ build_email_hash(parser.run(email))
22
+ end
23
+
24
+ def build_email_hash(email)
25
+ {
26
+ order_id: email.order_number,
27
+ carrier: email.carrier,
28
+ tracking_number: email.tracking_number
29
+ }
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,3 @@
1
+ module Reelagram
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'reelagram/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "reelagram-mail"
8
+ spec.version = Reelagram::VERSION
9
+ spec.authors = ["Jon Wheeler"]
10
+ spec.email = ["jon@doejo.com"]
11
+ spec.description = %q{Handles mail from orders@reelagram.com}
12
+ spec.summary = %q{Handles mail from orders@reelagram.com}
13
+ spec.homepage = "https://gitlab.doejo.com/reelagram/reelagram-mail"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_runtime_dependency "ruby-gmail", "0.3.1"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rake", "~> 0"
25
+ spec.add_development_dependency "dotenv", "0.11.1"
26
+ end
@@ -0,0 +1,32 @@
1
+ require "./test/test_helper"
2
+
3
+ class ConfgurationTest < MiniTest::Unit::TestCase
4
+ def test_configured_returns_false_when_not_configured
5
+ ConfigHelper.reset
6
+ assert_equal(false, Reelagram::Mail.configured?)
7
+ end
8
+
9
+ def test_confiures_the_email_address
10
+ ConfigHelper.confgure_mail
11
+ assert_equal(Reelagram::Mail.configuration.email, "foo@example.com")
12
+ end
13
+
14
+ def test_confiures_the_password
15
+ ConfigHelper.confgure_mail
16
+ assert_equal(Reelagram::Mail.configuration.password, "zomgLOLZ")
17
+ end
18
+
19
+ def test_when_configured_returns_true_for_configured?
20
+ ConfigHelper.confgure_mail
21
+ assert(Reelagram::Mail.configured?)
22
+ end
23
+
24
+ def test_when_not_configured_returns_false_for_configured?
25
+ ConfigHelper.reset
26
+ refute(Reelagram::Mail.configured?)
27
+ end
28
+
29
+ def test_configuration_returns_true
30
+ assert_equal(true, ConfigHelper.confgure_mail)
31
+ end
32
+ end
@@ -0,0 +1,11 @@
1
+ require "./test/test_helper"
2
+
3
+ class EmailFetcherTest < MiniTest::Unit::TestCase
4
+
5
+ def test_it_raises_error_if_not_configured
6
+ ConfigHelper.reset
7
+ assert_raises(Reelagram::NotConfiguredError) do
8
+ Reelagram::Mail::Fetchers::EmailFetcher.new.fetch
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ require "./test/test_helper"
2
+
3
+ class ShippingEmailFetcherTest < MiniTest::Unit::TestCase
4
+ def test_fetches_the_emails
5
+ ConfigHelper.configure_for_testing
6
+ STDOUT.stub(:puts, "") do
7
+ emails = Reelagram::Mail::Fetchers::ShippingFetcher.new.fetch
8
+ assert_equal(1, emails.size)
9
+ end
10
+ end
11
+
12
+ def test_default_label_is_shipped
13
+ assert_equal(Reelagram::Mail::Fetchers::ShippingFetcher::DEFAULT_LABEL, "Shipped!")
14
+ end
15
+ end
@@ -0,0 +1,310 @@
1
+ --001a11c0ed789583e404fe2af1ad
2
+ Content-Type: text/plain; charset=UTF-8
3
+
4
+ [image: Image3D] <http://www.image3d.com/store/index.php/> Hello, Sait
5
+ Mesutcan Ilhaner
6
+
7
+
8
+ We are happy to say that your order is complete and has left our facility!
9
+ You can check the status of your shipment by clicking the tracking number
10
+ below.
11
+ Please know that tracking numbers can take up to 24 hours to be updated.
12
+
13
+ Be sure to sign up for our E-Newsltter <http://bit.ly/I3Demails> to get the
14
+ latest deals and info, you even get a coupon just for subscribing! Then,
15
+ follow the fun on Facebook <https://www.facebook.com/USA.Image3D>, Twitter
16
+ <https://twitter.com/Image3Dusa>, YouTube
17
+ <http://www.youtube.com/image3dusa>, and Pinterest
18
+ <http://pinterest.com/image3d/>.
19
+
20
+
21
+ If you have any questions, email us at Celebrate@image3d.com or give us a
22
+ ring at 503-632-2470.
23
+
24
+ Your Order #27780000265 (placed on July 5, 2014 9:49:00 PM PDT) Billing
25
+ Information: Payment Method: Sait Mesutcan Ilhaner
26
+ 2400 W. Empire Ave Ste 300
27
+ Burbank, CA, 91504
28
+
29
+ T: 510-289-9049
30
+ Purchase Order
31
+
32
+ Purchase Order Number: 7780000265
33
+ Shipping Information: Shipping Method: Sait Mesutcan Ilhaner
34
+ 2400 W. Empire Ave Ste 300
35
+ Burbank, CA, 91504
36
+
37
+ T: 510-289-9049 Shipped By Tracking Number United States Postal
38
+ Service 92748999982943513015002409
39
+ <http://wwwapps.ups.com/WebTracking/track?HTMLVersion=5.0&loc=en_US&Requester=UPSHome&WBPM_lid=homepage%2Fct1.html_pnl_trk&trackNums=92748999982943513015002409&track.x=Track%20target=>
40
+
41
+ Please allow 24 hours for your tracking number to update
42
+ Item Sku Qty Subtotal *Reel & Viewer Set* *Reel ID* *Viewer Color* Black
43
+ VIEWER-4510 1 $29.95 Subtotal $29.95 Shipping & Handling $7.50 *Grand
44
+ Total* *$37.45*
45
+
46
+ Thank you!*Image3D*
47
+
48
+ --001a11c0ed789583e404fe2af1ad
49
+ Content-Type: text/html; charset=UTF-8
50
+ Content-Transfer-Encoding: quoted-printable
51
+
52
+ <div dir=3D"ltr"><div class=3D"gmail_quote"><br>
53
+ <div style=3D"background:#f6f6f6;font-family:Verdana,Arial,Helvetica,sans-s=
54
+ erif;font-size:12px;margin:0;padding:0">
55
+ <div style=3D"background:#f6f6f6;font-family:Verdana,Arial,Helvetica,sans-s=
56
+ erif;font-size:12px;margin:0;padding:0">
57
+ <table cellspacing=3D"0" cellpadding=3D"0" border=3D"0" width=3D"100%">
58
+ <tbody><tr>
59
+ <td align=3D"center" valign=3D"top" style=3D"padding:20px 0 20px 0">
60
+ <table bgcolor=3D"#FFFFFF" cellspacing=3D"0" cellpadding=3D"10" bor=
61
+ der=3D"0" width=3D"650" style=3D"border:1px solid #e0e0e0">
62
+ =20
63
+ <tbody><tr>
64
+ <td valign=3D"top"><a href=3D"http://www.image3d.com/store/=
65
+ index.php/" target=3D"_blank"><img src=3D"https://www.image3d.com/store/med=
66
+ ia/email/logo/default/logosmall1.jpg" alt=3D"Image3D" style=3D"margin-botto=
67
+ m:10px" border=3D"0"></a></td>
68
+
69
+ </tr>
70
+ =20
71
+ <tr>
72
+ <td valign=3D"top">
73
+ <h1 style=3D"font-size:22px;font-weight:normal;line-hei=
74
+ ght:22px;margin:0 0 11px 0">Hello, Sait Mesutcan Ilhaner</h1>
75
+ <p style=3D"font-size:12px;line-height:16px;margin:0">
76
+ <br>
77
+ We are happy to say that your order is complete and has left our facility!=
78
+ =20
79
+ <br>You can check the status of your shipment by clicking the tracking numb=
80
+ er below.=20
81
+ <br>Please know that tracking numbers can take up to 24 hours to be updated=
82
+ .=20
83
+ =20
84
+ <br><br> </p><p style=3D"font-size:12px;line-height:16px;mar=
85
+ gin:0">Be sure to sign up for our <a href=3D"http://bit.ly/I3Demails" targe=
86
+ t=3D"_blank">E-Newsltter</a> to get the latest deals and info, you even get=
87
+ a coupon just for subscribing! Then, follow the fun on <a href=3D"https://=
88
+ www.facebook.com/USA.Image3D" title=3D"Image3D on Facebook" target=3D"_blan=
89
+ k">Facebook</a>, <a href=3D"https://twitter.com/Image3Dusa" title=3D"Image3=
90
+ D on Twitter" target=3D"_blank">Twitter</a>, <a href=3D"http://www.youtube.=
91
+ com/image3dusa" title=3D"Image3D on YouTube" target=3D"_blank">YouTube</a>,=
92
+ and <a href=3D"http://pinterest.com/image3d/" title=3D"Image3D on Pinteres=
93
+ t" target=3D"_blank">Pinterest</a>. </p>
94
+
95
+
96
+ <br><br> If you have any questions, email us at <a href=3D"mailto:Celebra=
97
+ te@image3d.com" style=3D"color:#1e7ec8" target=3D"_blank">Celebrate@image3d=
98
+ .com</a> or give us a ring at <span><a href=3D"tel:503-632-2470" value=3D"+=
99
+ 15036322470" target=3D"_blank">503-632-2470</a></span>.
100
+ <p></p>
101
+ </td></tr>
102
+ <tr>
103
+ <td>
104
+ <h2 style=3D"font-size:18px;font-weight:normal;margin:0=
105
+ ">Your Order #27780000265 <small>(placed on July 5, 2014 9:49:00 PM PDT)</s=
106
+ mall></h2>
107
+ </td>
108
+ </tr>
109
+ <tr>
110
+ <td>
111
+ <table cellspacing=3D"0" cellpadding=3D"0" border=3D"0"=
112
+ width=3D"650">
113
+ <thead>
114
+ <tr>
115
+ <th align=3D"left" width=3D"325" bgcolor=3D"#EA=
116
+ EAEA" style=3D"font-size:13px;padding:5px 9px 6px 9px;line-height:1em">Bill=
117
+ ing Information:</th>
118
+ <th width=3D"10"></th>
119
+ <th align=3D"left" width=3D"325" bgcolor=3D"#EA=
120
+ EAEA" style=3D"font-size:13px;padding:5px 9px 6px 9px;line-height:1em">Paym=
121
+ ent Method:</th>
122
+ </tr>
123
+ </thead>
124
+ <tbody>
125
+ <tr>
126
+ <td valign=3D"top" style=3D"font-size:12px;padd=
127
+ ing:7px 9px 9px 9px;border-left:1px solid #eaeaea;border-bottom:1px solid #=
128
+ eaeaea;border-right:1px solid #eaeaea">
129
+ Sait Mesutcan Ilhaner<br>
130
+
131
+ 2400 W. Empire Ave Ste 300<br>
132
+
133
+
134
+
135
+ Burbank, CA, 91504<br>
136
+ <br>
137
+ T: <a href=3D"tel:510-289-9049" value=3D"+15102899049" target=3D"_blank">51=
138
+ 0-289-9049</a>
139
+
140
+
141
+ </td>
142
+ <td>=C2=A0</td>
143
+ <td valign=3D"top" style=3D"font-size:12px;padd=
144
+ ing:7px 9px 9px 9px;border-left:1px solid #eaeaea;border-bottom:1px solid #=
145
+ eaeaea;border-right:1px solid #eaeaea">
146
+ <br>Purchase Order <br><br>Purchase Order Nu=
147
+ mber: 7780000265
148
+
149
+
150
+
151
+
152
+
153
+ </td>
154
+ </tr>
155
+ </tbody>
156
+ </table>
157
+ <br>
158
+ =20
159
+ <table cellspacing=3D"0" cellpadding=3D"0" border=3D"0"=
160
+ width=3D"650">
161
+ <thead>
162
+ <tr>
163
+ <th align=3D"left" width=3D"325" bgcolor=3D"#EA=
164
+ EAEA" style=3D"font-size:13px;padding:5px 9px 6px 9px;line-height:1em">Ship=
165
+ ping Information:</th>
166
+ <th width=3D"10"></th>
167
+ <th align=3D"left" width=3D"325" bgcolor=3D"#EA=
168
+ EAEA" style=3D"font-size:13px;padding:5px 9px 6px 9px;line-height:1em">Ship=
169
+ ping Method:</th>
170
+ </tr>
171
+ </thead>
172
+ <tbody>
173
+ <tr>
174
+ <td valign=3D"top" width=3D"50%" style=3D"font-=
175
+ size:12px;padding:7px 9px 9px 9px;border-left:1px solid #eaeaea;border-bott=
176
+ om:1px solid #eaeaea;border-right:1px solid #eaeaea">
177
+ Sait Mesutcan Ilhaner<br>
178
+
179
+ 2400 W. Empire Ave Ste 300<br>
180
+
181
+
182
+
183
+ Burbank, CA, 91504<br>
184
+ <br>
185
+ T: <a href=3D"tel:510-289-9049" value=3D"+15102899049" target=3D"_blank">51=
186
+ 0-289-9049</a>
187
+
188
+
189
+ =C2=A0
190
+ </td>
191
+ <td>=C2=A0</td>
192
+ <td valign=3D"top" width=3D"50%" style=3D"font-=
193
+ size:12px;padding:7px 9px 9px 9px;border-left:1px solid #eaeaea;border-bott=
194
+ om:1px solid #eaeaea;border-right:1px solid #eaeaea">
195
+ <table cellspacing=3D"0" cellpadding=
196
+ =3D"0" border=3D"0" width=3D"300" style=3D"border:1px solid #eaeaea">
197
+ <thead>
198
+ <tr>
199
+ <th align=3D"left" bgcolor=3D"#EAEAEA" style=3D"font-size:13px;=
200
+ padding:3px 9px">Shipped By</th>
201
+ <th align=3D"center" bgcolor=3D"#EAEAEA" style=3D"font-size:13p=
202
+ x;padding:3px 9px">Tracking Number</th>
203
+ </tr>
204
+ </thead>
205
+ <tbody>
206
+ <tr bgcolor=3D"#F6F6F6">
207
+ <td align=3D"left" valign=3D"top" style=3D"padding:3px 9px">Uni=
208
+ ted States Postal Service</td>
209
+ <td align=3D"center" valign=3D"top" style=3D"padding:3px 9px"><=
210
+ a href=3D"http://wwwapps.ups.com/WebTracking/track?HTMLVersion=3D5.0&amp;lo=
211
+ c=3Den_US&amp;Requester=3DUPSHome&amp;WBPM_lid=3Dhomepage%2Fct1.html_pnl_tr=
212
+ k&amp;trackNums=3D92748999982943513015002409&amp;track.x=3DTrack%20target=
213
+ =3D" target=3D"_blank">92748999982943513015002409</a><br>
214
+ <br>Please allow 24 hours for your tracking number to update</td>
215
+ </tr>
216
+ </tbody>
217
+ </table>
218
+
219
+
220
+ </td>
221
+ </tr>
222
+ </tbody>
223
+ </table>
224
+ <br>
225
+ =20
226
+ <table cellspacing=3D"0" cellpadding=3D"0" border=3D"0"=
227
+ width=3D"650" style=3D"border:1px solid #eaeaea">
228
+ <thead>
229
+ <tr>
230
+ <th align=3D"left" bgcolor=3D"#EAEAEA" style=3D"font-size:13px;=
231
+ padding:3px 9px">Item</th>
232
+ <th align=3D"left" bgcolor=3D"#EAEAEA" style=3D"font-size:13px;=
233
+ padding:3px 9px">Sku</th>
234
+ <th align=3D"center" bgcolor=3D"#EAEAEA" style=3D"font-size:13p=
235
+ x;padding:3px 9px">Qty</th>
236
+ <th align=3D"right" bgcolor=3D"#EAEAEA" style=3D"font-size:13px=
237
+ ;padding:3px 9px">Subtotal</th>
238
+ </tr>
239
+ </thead>
240
+
241
+ <tbody bgcolor=3D"#F6F6F6">
242
+ <tr>
243
+ <td align=3D"left" valign=3D"top" style=3D"font-size:11px;padding:3px 9=
244
+ px;border-bottom:1px dotted #cccccc">
245
+ <strong style=3D"font-size:11px">Reel &amp; Viewer Set</strong>
246
+ <dl style=3D"margin:0;padding:0">
247
+ <dt><strong><em>Reel ID</em></strong></dt>
248
+ <dd style=3D"margin:0;padding:0 0 0 9px">
249
+ </dd>
250
+ <dt><strong><em>Viewer Color</em></strong></dt>
251
+ <dd style=3D"margin:0;padding:0 0 0 9px">
252
+ Black </dd>
253
+ </dl>
254
+ </td>
255
+ <td align=3D"left" valign=3D"top" style=3D"font-size:11px;padding:3px 9=
256
+ px;border-bottom:1px dotted #cccccc">VIEWER-4510</td>
257
+ <td align=3D"center" valign=3D"top" style=3D"font-size:11px;padding:3px=
258
+ 9px;border-bottom:1px dotted #cccccc">1</td>
259
+ <td align=3D"right" valign=3D"top" style=3D"font-size:11px;padding:3px =
260
+ 9px;border-bottom:1px dotted #cccccc">
261
+ <span>$29.95</span> =
262
+ =20
263
+
264
+ =20
265
+
266
+ </td>
267
+ </tr>
268
+ </tbody>
269
+ =20
270
+ <tbody>
271
+ <tr>
272
+ <td colspan=3D"3" align=3D"right" style=3D"padding:3px 9px">
273
+ Subtotal </td>
274
+ <td align=3D"right" style=3D"padding:3px 9px">
275
+ <span>$29.95</span> </td>
276
+ </tr>
277
+ <tr>
278
+ <td colspan=3D"3" align=3D"right" style=3D"padding:3px 9px">
279
+ Shipping &amp; Handling </td>
280
+ <td align=3D"right" style=3D"padding:3px 9px">
281
+ <span>$7.50</span> </td>
282
+ </tr>
283
+ <tr>
284
+ <td colspan=3D"3" align=3D"right" style=3D"padding:3px 9px">
285
+ <strong>Grand Total</strong>
286
+ </td>
287
+ <td align=3D"right" style=3D"padding:3px 9px">
288
+ <strong><span>$37.45</span></strong>
289
+ </td>
290
+ </tr>
291
+ </tbody>
292
+ </table>
293
+
294
+ <p style=3D"font-size:12px;margin:0 0 10px 0"></p>
295
+ </td>
296
+ </tr>
297
+ <tr>
298
+ <td bgcolor=3D"#EAEAEA" align=3D"center" style=3D"backgroun=
299
+ d:#eaeaea;text-align:center"><center><p style=3D"font-size:12px;margin:0">T=
300
+ hank you!<strong>Image3D</strong></p></center></td>
301
+ </tr>
302
+ </tbody></table>
303
+ </td>
304
+ </tr>
305
+ </tbody></table>
306
+ </div>
307
+ </div>
308
+ </div><br></div>
309
+
310
+ --001a11c0ed789583e404fe2af1ad--
@@ -0,0 +1,32 @@
1
+ require "./test/test_helper"
2
+
3
+ class ShippingParserTest < MiniTest::Unit::TestCase
4
+ attr_reader :parser
5
+
6
+ def test_run_returns_a_parser
7
+ assert_kind_of(Reelagram::Mail::Parsers::ShippingParser, parser.run("foo"))
8
+ end
9
+
10
+ def test_order_number_returns_the_order_number
11
+ parsed_string = parser.run(data)
12
+ assert_equal("7780000265", parsed_string.order_number)
13
+ end
14
+
15
+ def test_carrier_returns_the_carrier
16
+ parsed_string = parser.run(data)
17
+ assert_equal("United States Postal Service", parsed_string.carrier)
18
+ end
19
+
20
+ def test_tracking_number_returns_the_tracking_number
21
+ parsed_string = parser.run(data)
22
+ assert_equal("92748999982943513015002409", parsed_string.tracking_number)
23
+ end
24
+
25
+ def parser
26
+ @parser ||= Reelagram::Mail::Parsers::ShippingParser.new
27
+ end
28
+
29
+ def data
30
+ FixtureHelper.fixture("email_body.txt")
31
+ end
32
+ end
@@ -0,0 +1,36 @@
1
+ require "./test/test_helper"
2
+
3
+ class ShippingUpdateProcessorTest < MiniTest::Unit::TestCase
4
+ attr_reader :processor, :parser
5
+
6
+ def test_run_returns_an_array
7
+ assert_kind_of(Array, processor.run)
8
+ end
9
+
10
+ def test_run_returns_an_empty_array_when_there_is_no_data
11
+ process_nothing = Reelagram::Mail::Processors::ShippingProcessor.new([], parser)
12
+ assert_equal([], process_nothing.run)
13
+ end
14
+
15
+ def test_run_returns_the_parsed_data_from_the_email
16
+ parsed_data = {
17
+ order_id: "7780000265",
18
+ carrier: "United States Postal Service",
19
+ tracking_number: "92748999982943513015002409"
20
+ }
21
+ assert_equal(parsed_data, processor.run.first)
22
+ end
23
+
24
+ def parser
25
+ @parser ||= Reelagram::Mail::Parsers::ShippingParser.new
26
+ end
27
+
28
+ def processor
29
+ @processor ||= Reelagram::Mail::Processors::ShippingProcessor.new(email_data, parser)
30
+ end
31
+
32
+ def email_data
33
+ [{ body: FixtureHelper.fixture("email_body.txt") }]
34
+ end
35
+ end
36
+
@@ -0,0 +1,19 @@
1
+ module ConfigHelper
2
+ def self.confgure_mail
3
+ Reelagram::Mail.configure do |c|
4
+ c.email = "foo@example.com"
5
+ c.password = "zomgLOLZ"
6
+ end
7
+ end
8
+
9
+ def self.reset
10
+ Reelagram::Mail.configuration = nil
11
+ end
12
+
13
+ def self.configure_for_testing # TODO stub this shit
14
+ Reelagram::Mail.configure do |c|
15
+ c.email = ENV["TEST_EMAIL"]
16
+ c.password = ENV["TEST_PASSWORD"]
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,10 @@
1
+ module FixtureHelper
2
+ def self.fixture_path(filename = nil)
3
+ path = File.expand_path("../../fixtures", __FILE__)
4
+ filename.nil? ? path : File.join(path, filename)
5
+ end
6
+
7
+ def self.fixture(file)
8
+ File.read(File.join(fixture_path, file))
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ require "minitest/unit"
2
+ require "minitest/autorun"
3
+ require "minitest/pride"
4
+
5
+ require "./test/support/config_helper"
6
+ require "./test/support/fixture_helper"
7
+ require "./lib/reelagram"
8
+
9
+ require "dotenv"
10
+
11
+ Dotenv.load
metadata ADDED
@@ -0,0 +1,139 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: reelagram-mail
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jon Wheeler
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-07-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ruby-gmail
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 0.3.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.3.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: dotenv
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 0.11.1
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '='
67
+ - !ruby/object:Gem::Version
68
+ version: 0.11.1
69
+ description: Handles mail from orders@reelagram.com
70
+ email:
71
+ - jon@doejo.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".ruby-gemset"
78
+ - ".ruby-version"
79
+ - Gemfile
80
+ - Gemfile.lock
81
+ - LICENSE.txt
82
+ - README.md
83
+ - Rakefile
84
+ - lib/reelagram.rb
85
+ - lib/reelagram/errors.rb
86
+ - lib/reelagram/mail.rb
87
+ - lib/reelagram/mail/configuration.rb
88
+ - lib/reelagram/mail/fetchers.rb
89
+ - lib/reelagram/mail/fetchers/base_fetcher.rb
90
+ - lib/reelagram/mail/fetchers/shipping_fetcher.rb
91
+ - lib/reelagram/mail/parsers.rb
92
+ - lib/reelagram/mail/parsers/shipping_parser.rb
93
+ - lib/reelagram/mail/processors.rb
94
+ - lib/reelagram/mail/processors/shipping_processor.rb
95
+ - lib/reelagram/version.rb
96
+ - reelagram-mail.gemspec
97
+ - test/configuration_test.rb
98
+ - test/fetchers/base_fetcher_test.rb
99
+ - test/fetchers/shipping_fetcher_test.rb
100
+ - test/fixtures/email_body.txt
101
+ - test/parsers/shipping_parser_test.rb
102
+ - test/processors/shipping_processor_test.rb
103
+ - test/support/config_helper.rb
104
+ - test/support/fixture_helper.rb
105
+ - test/test_helper.rb
106
+ homepage: https://gitlab.doejo.com/reelagram/reelagram-mail
107
+ licenses:
108
+ - MIT
109
+ metadata: {}
110
+ post_install_message:
111
+ rdoc_options: []
112
+ require_paths:
113
+ - lib
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ requirements: []
125
+ rubyforge_project:
126
+ rubygems_version: 2.2.2
127
+ signing_key:
128
+ specification_version: 4
129
+ summary: Handles mail from orders@reelagram.com
130
+ test_files:
131
+ - test/configuration_test.rb
132
+ - test/fetchers/base_fetcher_test.rb
133
+ - test/fetchers/shipping_fetcher_test.rb
134
+ - test/fixtures/email_body.txt
135
+ - test/parsers/shipping_parser_test.rb
136
+ - test/processors/shipping_processor_test.rb
137
+ - test/support/config_helper.rb
138
+ - test/support/fixture_helper.rb
139
+ - test/test_helper.rb