From 86bf26f2372c4209c9fa4189b5069a8c772d4bf0 Mon Sep 17 00:00:00 2001 From: Todd Loupe Date: Tue, 5 Dec 2017 06:40:42 +0000 Subject: [PATCH 01/14] AWS emailer system in early stages --- Gemfile | 1 + Gemfile.lock | 13 +++++++- app.rb | 58 ++++++++++++++++++++++++++++++++++++ awsemailer.rb | 77 ++++++++++++++++++++++++++++++++++++++++++++++++ emailer.rb | 13 ++++++++ emailprovider.rb | 21 +++++++++++++ 6 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 awsemailer.rb create mode 100644 emailer.rb create mode 100644 emailprovider.rb diff --git a/Gemfile b/Gemfile index 543bc66..720f8af 100644 --- a/Gemfile +++ b/Gemfile @@ -12,6 +12,7 @@ gem 'uglifier', '~> 3.0' gem 'dotenv' gem 'google_drive' gem 'pony' +gem 'aws-sdk-ses' # database things gem 'pg' diff --git a/Gemfile.lock b/Gemfile.lock index ffbe50c..e971293 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,6 +3,15 @@ GEM specs: addressable (2.5.2) public_suffix (>= 2.0.2, < 4.0) + aws-partitions (1.40.0) + aws-sdk-core (3.9.0) + aws-partitions (~> 1.0) + aws-sigv4 (~> 1.0) + jmespath (~> 1.0) + aws-sdk-ses (1.4.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sigv4 (1.0.2) concurrent-ruby (1.0.5) declarative (0.0.10) declarative-option (0.1.0) @@ -31,6 +40,7 @@ GEM os (~> 0.9) signet (~> 0.7) httpclient (2.8.3) + jmespath (1.3.1) jwt (2.1.0) listen (3.1.5) rb-fsevent (~> 0.9, >= 0.9.4) @@ -108,6 +118,7 @@ PLATFORMS ruby DEPENDENCIES + aws-sdk-ses dotenv google_drive mustache-sinatra (~> 1) @@ -128,4 +139,4 @@ RUBY VERSION ruby 2.2.5p319 BUNDLED WITH - 1.15.4 + 1.16.0 diff --git a/app.rb b/app.rb index e520718..671c66d 100644 --- a/app.rb +++ b/app.rb @@ -3,10 +3,13 @@ require 'mustache' require 'dotenv' require 'pony' +require './emailprovider.rb' module WorkForwardNola # WFN app class App < Sinatra::Base + attr_reader :emailer + Dotenv.load register Sinatra::SequelExtension @@ -124,6 +127,7 @@ def worksheet worksheet.save mustache :jobsystem end + send_job_form_email(params['email_submission'], 'email_here', params) end get '/opportunity-center-info' do @@ -166,5 +170,59 @@ def worksheet @title = 'Manage Content' mustache :manage end + + private + + def send_job_form_email(recipient, oppCenter, params) + # Specify a configuration set. To use a configuration + # set, uncomment the next line and send it to the proper method + # configsetname = "ConfigSet" + subject = 'New Submission: Opportunity Center Sign Up' + + htmlbody = + " + Thank you for registering in the New Orleans job system. + +

We are evaluating which opportunity center can best meet your needs or barriers. + You'll get a reply by email of who to contact. + If you do not have email, someone will call you.

+
Here are your submissions:
+
First Name: #{params['first_name']}
+
Last Name: #{params['last_name']}
+
Best way to contact: #{params['best_way']}
+
Email: #{params['email_submission']}
+
Phone: #{params['phone_submission']}
+
Text: #{params['text_submission']}
+
Referred by: #{params['referral']}
+
Which neighborhood: #{params['neighborhood']}
+
Are you a young adult? #{params['young_adult']}
+
Are you a veteran? #{params['veteran']}
+
Do you have little access to transportaion? + #{params['no_transportation']}
+
Are you homeless or staying with someone temporarily? + #{params['homeless']}
+
I dont have a drivers license. #{params['no_drivers_license']}
+
I dont have a state-issued I.D. #{params['no_state_id']}
+
I am disabled. #{params['disabled']}
+
I need childcare. #{params['childcare']}
+
I have an open criminal charge. #{params['criminal']}
+
I have been previously incarcerated. + #{params['previously_incarcerated']}
+
I am using drugs and want to get help. #{params['using_drugs']}
+
None of the above. #{params['none']}
" + + + # The email body for recipients with non-HTML email clients. + textbody = "Thank you for registering in the New Orleans job system. + We are evaluating which opportunity center can best meet your needs + or barriers. You'll get a reply by email of who to contact. + If you do not have email, someone will call you." + emailer = EmailProvider.emailer + sender = EmailProvider.sender + owner = EmailProvider.owner + puts self.emailer.inspect + emailer.send_email(sender, recipient, subject, textbody, htmlbody, + oppCenter, owner) + end end end diff --git a/awsemailer.rb b/awsemailer.rb new file mode 100644 index 0000000..cd74ebf --- /dev/null +++ b/awsemailer.rb @@ -0,0 +1,77 @@ +require 'aws-sdk-ses' # v2: require 'aws-sdk' +require './emailer.rb' +require './app.rb' +require 'dotenv' + +module WorkForwardNola + class AwsEmailer < Emailer + + Dotenv.load + + def initialize access, secret + begin + Aws.config.update(credentials: Aws::Credentials.new(access, secret), region: 'us-east-1') + @ses = Aws::SES::Client.new + rescue Aws::SES::Errors::ServiceError => error + throw Aws::SES::Errors::ServiceError.new("Error configuring AWS SES client. Error message: #{error}") + end + end + + def send_email(sender, recipient, subject, text_body, html_body, cc = nil, bcc = nil) + encoding = 'UTF-8' + # Try to send the email. + begin + # Verify the emails + # check_emails sender + # check_emails recipient + # check_emails cc + # check_emails bcc + # check_emails reply_to + + # Provide the contents of the email. + email_config_data = { + destination: { to_addresses: [recipient, cc, bcc] }, + message: { + subject: { charset: encoding, data: subject }, + body: { + html: { charset: encoding, data: html_body }, + text: { charset: encoding, data: text_body } + } + }, + source: ENV['SENDER_EMAIL'] + } + # if not cc.nil? + # email_config_data[:destination][:cc_addresses] = as_email_array(cc) + # end + # if not bcc.nil? + # email_config_data[:destination][:bcc_addresses] = as_email_array(bcc) + # end + # if not reply_to.nil? + # email_config_data[:reply_to] = reply_to # not sure about the key on this one. + # end + resp = @ses.send_email(email_config_data) + puts "Email sent to #{recipient.inspect}: #{resp.inspect}" + rescue Aws::SES::Errors::ServiceError => error + # If something goes wrong, display an error message. + throw error + end + end + + private + + # Used to verify emails for use in AWS sandbox environment + def check_emails emails + return if emails.nil? + if emails.respond_to? :each + emails.each { |e| @ses.verify_email_identity email_address: e } + else + @ses.verify_email_identity email_address: emails + end + end + + def as_email_array emails + return emails if emails.respond_to? :each + [emails] + end + end +end \ No newline at end of file diff --git a/emailer.rb b/emailer.rb new file mode 100644 index 0000000..5310509 --- /dev/null +++ b/emailer.rb @@ -0,0 +1,13 @@ +require './awsemailer.rb' +require './app.rb' + +module WorkForwardNola + class Emailer + def initialize + end + + def send_email + throw Error("Emailer is an abstract class. Please use an implementation class.") + end + end +end \ No newline at end of file diff --git a/emailprovider.rb b/emailprovider.rb new file mode 100644 index 0000000..b0e55b6 --- /dev/null +++ b/emailprovider.rb @@ -0,0 +1,21 @@ +require './awsemailer.rb' + +module WorkForwardNola + class EmailProvider + @@emailer = AwsEmailer.new ENV['AWS_ACCESS'], ENV['AWS_SECRET'] + @@senderEmail = ENV['SENDER_EMAIL'] + @@ownerEmail = ENV['OWNER_EMAIL'] + + def self.emailer + @@emailer + end + + def self.sender + @@senderEmail + end + + def self.owner + @@ownerEmail + end + end +end From b99084e05548d3ad0a4879e35b038672e6651e2a Mon Sep 17 00:00:00 2001 From: Todd Loupe Date: Tue, 5 Dec 2017 08:21:04 +0000 Subject: [PATCH 02/14] Added in validation for emails, added redirect to contacts, and added some comments. --- app.rb | 14 +++++++++----- awsemailer.rb | 9 +++++++-- emailer.rb | 3 ++- emailprovider.rb | 1 + 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/app.rb b/app.rb index 671c66d..15b5110 100644 --- a/app.rb +++ b/app.rb @@ -127,7 +127,10 @@ def worksheet worksheet.save mustache :jobsystem end - send_job_form_email(params['email_submission'], 'email_here', params) + if params['email_submission'] != '' then + send_job_form_email(params['email_submission'], 'email_here', params) + end + redirect to ('/jobsystem') end get '/opportunity-center-info' do @@ -183,7 +186,8 @@ def send_job_form_email(recipient, oppCenter, params) " Thank you for registering in the New Orleans job system. -

We are evaluating which opportunity center can best meet your needs or barriers. +

We are evaluating which opportunity center can best meet your + needs or barriers. You'll get a reply by email of who to contact. If you do not have email, someone will call you.


Here are your submissions:
@@ -214,9 +218,9 @@ def send_job_form_email(recipient, oppCenter, params) # The email body for recipients with non-HTML email clients. textbody = "Thank you for registering in the New Orleans job system. - We are evaluating which opportunity center can best meet your needs - or barriers. You'll get a reply by email of who to contact. - If you do not have email, someone will call you." + We are evaluating which opportunity center can best meet your + needs or barriers. You'll get a reply by email of who to + contact. If you do not have email, someone will call you." emailer = EmailProvider.emailer sender = EmailProvider.sender owner = EmailProvider.owner diff --git a/awsemailer.rb b/awsemailer.rb index cd74ebf..c72dd4d 100644 --- a/awsemailer.rb +++ b/awsemailer.rb @@ -4,6 +4,7 @@ require 'dotenv' module WorkForwardNola + # Class for sending out emails through AWS class AwsEmailer < Emailer Dotenv.load @@ -21,7 +22,9 @@ def send_email(sender, recipient, subject, text_body, html_body, cc = nil, bcc = encoding = 'UTF-8' # Try to send the email. begin - # Verify the emails + # Verify the emails, this will add them to the verified emails + # if using sandboxes. + # check_emails sender # check_emails recipient # check_emails cc @@ -40,7 +43,9 @@ def send_email(sender, recipient, subject, text_body, html_body, cc = nil, bcc = }, source: ENV['SENDER_EMAIL'] } - # if not cc.nil? + + # Email validation? + # if not cc.nil? # email_config_data[:destination][:cc_addresses] = as_email_array(cc) # end # if not bcc.nil? diff --git a/emailer.rb b/emailer.rb index 5310509..0c5ba54 100644 --- a/emailer.rb +++ b/emailer.rb @@ -1,7 +1,8 @@ require './awsemailer.rb' require './app.rb' -module WorkForwardNola +module WorkForwardNola + # Abstract class for emailing systems class Emailer def initialize end diff --git a/emailprovider.rb b/emailprovider.rb index b0e55b6..fca465a 100644 --- a/emailprovider.rb +++ b/emailprovider.rb @@ -1,6 +1,7 @@ require './awsemailer.rb' module WorkForwardNola + # Sets up AWS SES variables through the environment file class EmailProvider @@emailer = AwsEmailer.new ENV['AWS_ACCESS'], ENV['AWS_SECRET'] @@senderEmail = ENV['SENDER_EMAIL'] From fa727e429e541350a31977d6e6d2790d898c0a28 Mon Sep 17 00:00:00 2001 From: Todd Loupe Date: Tue, 19 Dec 2017 23:15:30 +0000 Subject: [PATCH 03/14] Update readme and redirect --- README.md | 7 ++++--- app.rb | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b8f9cef..24a5c8f 100644 --- a/README.md +++ b/README.md @@ -41,9 +41,10 @@ We are not AWS experts, so if you have recommendations to improve the following, * For steps 5/6, select `Ruby` and `Ruby 2.2 (Puma)` * SSH login is optional, but convenient 3. At this point, you'll want to set up the DB. We created an integrated Postgres database instance (v. 9.5.2) as described in [here](http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features.managing.db.html). -4. Walk through [Create an Environment](http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_Ruby_sinatra.html#create_deploy_Ruby_eb_env) -5. ‼️ At this point, stop and check on the instance type. You may need to configure a VPC. -6. Try deploying: `eb deploy` +4. Setting up SES: `SENDER_EMAIL`, `OWNER_EMAIL`, `AWS_ACCESS`, `AWS_SECRET` must all be configured in .env for the SES to work through the job form. +5. Walk through [Create an Environment](http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_Ruby_sinatra.html#create_deploy_Ruby_eb_env) +6. ‼️ At this point, stop and check on the instance type. You may need to configure a VPC. +7. Try deploying: `eb deploy` Configuring the "email to yourself" feature requires extra configuration on EB. diff --git a/app.rb b/app.rb index 15b5110..572160a 100644 --- a/app.rb +++ b/app.rb @@ -128,9 +128,9 @@ def worksheet mustache :jobsystem end if params['email_submission'] != '' then - send_job_form_email(params['email_submission'], 'email_here', params) + send_job_form_email(params['email_submission'], 'ccemail_here', params) end - redirect to ('/jobsystem') + redirect to ('/') # where to redirect after submission? end get '/opportunity-center-info' do From 81d40927592ec7424ab1ccd6af3080f447307e19 Mon Sep 17 00:00:00 2001 From: Todd Loupe Date: Tue, 19 Dec 2017 23:35:08 +0000 Subject: [PATCH 04/14] Code quality changes and updated .env.example --- .env.example | 4 ++++ app.rb | 20 ++++++++++---------- awsemailer.rb | 29 +++++++++++++++-------------- emailer.rb | 6 +++--- emailprovider.rb | 6 +++--- 5 files changed, 35 insertions(+), 30 deletions(-) diff --git a/.env.example b/.env.example index 6246b68..9950fda 100644 --- a/.env.example +++ b/.env.example @@ -6,3 +6,7 @@ EMAIL_PORT=587 EMAIL_USER=stacy@mynonprofit.org EMAIL_PASSWORD=chat_this_password EMAIL_DOMAIN=mynonprofit.org +SENDER_EMAIL=sendfrom@mynonprofit.org +OWNER_EMAIL=owner@mynonprofit.org +AWS_ACCESS=AWS_ACCESS_KEY_HERE +AWS_SECRET=AWS_SECRET_KEY_HERE \ No newline at end of file diff --git a/app.rb b/app.rb index 572160a..c45728b 100644 --- a/app.rb +++ b/app.rb @@ -9,7 +9,7 @@ module WorkForwardNola # WFN app class App < Sinatra::Base attr_reader :emailer - + Dotenv.load register Sinatra::SequelExtension @@ -127,8 +127,8 @@ def worksheet worksheet.save mustache :jobsystem end - if params['email_submission'] != '' then - send_job_form_email(params['email_submission'], 'ccemail_here', params) + if params['email_submission'] != '' + send_job_form_email(params['email_submission'], 'oppcenter_email', params) end redirect to ('/') # where to redirect after submission? end @@ -173,10 +173,10 @@ def worksheet @title = 'Manage Content' mustache :manage end - + private - - def send_job_form_email(recipient, oppCenter, params) + + def send_job_form_email(recipient, oppcenter, params) # Specify a configuration set. To use a configuration # set, uncomment the next line and send it to the proper method # configsetname = "ConfigSet" @@ -203,7 +203,7 @@ def send_job_form_email(recipient, oppCenter, params)
Are you a veteran? #{params['veteran']}

Do you have little access to transportaion? #{params['no_transportation']}
-
Are you homeless or staying with someone temporarily? +
Are you homeless or staying with someone temporarily? #{params['homeless']}

I dont have a drivers license. #{params['no_drivers_license']}

I dont have a state-issued I.D. #{params['no_state_id']}
@@ -214,8 +214,8 @@ def send_job_form_email(recipient, oppCenter, params) #{params['previously_incarcerated']}

I am using drugs and want to get help. #{params['using_drugs']}

None of the above. #{params['none']}
" - - + + # The email body for recipients with non-HTML email clients. textbody = "Thank you for registering in the New Orleans job system. We are evaluating which opportunity center can best meet your @@ -226,7 +226,7 @@ def send_job_form_email(recipient, oppCenter, params) owner = EmailProvider.owner puts self.emailer.inspect emailer.send_email(sender, recipient, subject, textbody, htmlbody, - oppCenter, owner) + oppcenter, owner) end end end diff --git a/awsemailer.rb b/awsemailer.rb index c72dd4d..930d004 100644 --- a/awsemailer.rb +++ b/awsemailer.rb @@ -1,4 +1,4 @@ -require 'aws-sdk-ses' # v2: require 'aws-sdk' +require 'aws-sdk-ses' # v2: require 'aws-sdk' require './emailer.rb' require './app.rb' require 'dotenv' @@ -6,10 +6,10 @@ module WorkForwardNola # Class for sending out emails through AWS class AwsEmailer < Emailer - + Dotenv.load - - def initialize access, secret + + def initialize(access, secret) begin Aws.config.update(credentials: Aws::Credentials.new(access, secret), region: 'us-east-1') @ses = Aws::SES::Client.new @@ -17,20 +17,20 @@ def initialize access, secret throw Aws::SES::Errors::ServiceError.new("Error configuring AWS SES client. Error message: #{error}") end end - + def send_email(sender, recipient, subject, text_body, html_body, cc = nil, bcc = nil) encoding = 'UTF-8' # Try to send the email. begin # Verify the emails, this will add them to the verified emails # if using sandboxes. - + # check_emails sender # check_emails recipient # check_emails cc # check_emails bcc # check_emails reply_to - + # Provide the contents of the email. email_config_data = { destination: { to_addresses: [recipient, cc, bcc] }, @@ -41,7 +41,7 @@ def send_email(sender, recipient, subject, text_body, html_body, cc = nil, bcc = text: { charset: encoding, data: text_body } } }, - source: ENV['SENDER_EMAIL'] + source: sender } # Email validation? @@ -52,7 +52,8 @@ def send_email(sender, recipient, subject, text_body, html_body, cc = nil, bcc = # email_config_data[:destination][:bcc_addresses] = as_email_array(bcc) # end # if not reply_to.nil? - # email_config_data[:reply_to] = reply_to # not sure about the key on this one. + # email_config_data[:reply_to] = reply_to + # not sure about the key on this one. # end resp = @ses.send_email(email_config_data) puts "Email sent to #{recipient.inspect}: #{resp.inspect}" @@ -60,12 +61,12 @@ def send_email(sender, recipient, subject, text_body, html_body, cc = nil, bcc = # If something goes wrong, display an error message. throw error end - end - + end + private - + # Used to verify emails for use in AWS sandbox environment - def check_emails emails + def check_emails(emails) return if emails.nil? if emails.respond_to? :each emails.each { |e| @ses.verify_email_identity email_address: e } @@ -74,7 +75,7 @@ def check_emails emails end end - def as_email_array emails + def as_email_array(emails) return emails if emails.respond_to? :each [emails] end diff --git a/emailer.rb b/emailer.rb index 0c5ba54..38e8df1 100644 --- a/emailer.rb +++ b/emailer.rb @@ -1,14 +1,14 @@ require './awsemailer.rb' require './app.rb' -module WorkForwardNola +module WorkForwardNola # Abstract class for emailing systems class Emailer def initialize end - + def send_email throw Error("Emailer is an abstract class. Please use an implementation class.") end end -end \ No newline at end of file +end diff --git a/emailprovider.rb b/emailprovider.rb index fca465a..18314d0 100644 --- a/emailprovider.rb +++ b/emailprovider.rb @@ -6,15 +6,15 @@ class EmailProvider @@emailer = AwsEmailer.new ENV['AWS_ACCESS'], ENV['AWS_SECRET'] @@senderEmail = ENV['SENDER_EMAIL'] @@ownerEmail = ENV['OWNER_EMAIL'] - + def self.emailer @@emailer end - + def self.sender @@senderEmail end - + def self.owner @@ownerEmail end From f9804a86d9de708e7db2904bcb98c85037685ab6 Mon Sep 17 00:00:00 2001 From: Todd Loupe Date: Wed, 20 Dec 2017 23:06:28 +0000 Subject: [PATCH 05/14] Implemented AWS S3 for file storage. Additionally updates readmes for various aspects of the app. Last, updates job system template to properly read files. --- .env.example | 7 +++++-- Gemfile | 1 + Gemfile.lock | 8 ++++++++ README.md | 5 +++-- app.rb | 24 ++++++++++++++++++++++-- docs/career_assessment_how_to.md | 4 ++-- docs/updating_content.md | 2 +- templates/jobsystem.mustache | 30 +++++++++++++++--------------- 8 files changed, 57 insertions(+), 24 deletions(-) diff --git a/.env.example b/.env.example index 9950fda..f54bf27 100644 --- a/.env.example +++ b/.env.example @@ -6,7 +6,10 @@ EMAIL_PORT=587 EMAIL_USER=stacy@mynonprofit.org EMAIL_PASSWORD=chat_this_password EMAIL_DOMAIN=mynonprofit.org + SENDER_EMAIL=sendfrom@mynonprofit.org OWNER_EMAIL=owner@mynonprofit.org -AWS_ACCESS=AWS_ACCESS_KEY_HERE -AWS_SECRET=AWS_SECRET_KEY_HERE \ No newline at end of file + +AWS_ACCESS=aws_access_key +AWS_SECRET=aws_secret_key +AWS_BUCKET=aws_bucket_name \ No newline at end of file diff --git a/Gemfile b/Gemfile index 720f8af..b37abfc 100644 --- a/Gemfile +++ b/Gemfile @@ -13,6 +13,7 @@ gem 'dotenv' gem 'google_drive' gem 'pony' gem 'aws-sdk-ses' +gem 'aws-sdk-s3' # database things gem 'pg' diff --git a/Gemfile.lock b/Gemfile.lock index e971293..559e7d3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,6 +8,13 @@ GEM aws-partitions (~> 1.0) aws-sigv4 (~> 1.0) jmespath (~> 1.0) + aws-sdk-kms (1.3.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-s3 (1.8.0) + aws-sdk-core (~> 3) + aws-sdk-kms (~> 1) + aws-sigv4 (~> 1.0) aws-sdk-ses (1.4.0) aws-sdk-core (~> 3) aws-sigv4 (~> 1.0) @@ -118,6 +125,7 @@ PLATFORMS ruby DEPENDENCIES + aws-sdk-s3 aws-sdk-ses dotenv google_drive diff --git a/README.md b/README.md index 24a5c8f..1c1e6b0 100644 --- a/README.md +++ b/README.md @@ -42,8 +42,9 @@ We are not AWS experts, so if you have recommendations to improve the following, * SSH login is optional, but convenient 3. At this point, you'll want to set up the DB. We created an integrated Postgres database instance (v. 9.5.2) as described in [here](http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features.managing.db.html). 4. Setting up SES: `SENDER_EMAIL`, `OWNER_EMAIL`, `AWS_ACCESS`, `AWS_SECRET` must all be configured in .env for the SES to work through the job form. -5. Walk through [Create an Environment](http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_Ruby_sinatra.html#create_deploy_Ruby_eb_env) -6. ‼️ At this point, stop and check on the instance type. You may need to configure a VPC. +5. Setting up S3: Configure `AWS_BUCKET` in `.env` +6. Walk through [Create an Environment](http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_Ruby_sinatra.html#create_deploy_Ruby_eb_env) +7. ‼️ At this point, stop and check on the instance type. You may need to configure a VPC. 7. Try deploying: `eb deploy` Configuring the "email to yourself" feature requires extra configuration on EB. diff --git a/app.rb b/app.rb index c45728b..7ed1df5 100644 --- a/app.rb +++ b/app.rb @@ -4,6 +4,8 @@ require 'dotenv' require 'pony' require './emailprovider.rb' +require 'aws-sdk-s3' +require 'json' module WorkForwardNola # WFN app @@ -113,6 +115,7 @@ def worksheet end post '/contact' do + @resume_name = params[:resume][:filename] new_row = [params['first_name'], params['last_name'], params['best_way'], params['email_submission'], params['phone_submission'], params['text_submission'], params['referral'], @@ -121,17 +124,34 @@ def worksheet params['homeless'], params['no_drivers_license'], params['no_state_id'], params['disabled'], params['childcare'], params['criminal'], params['previously_incarcerated'], - params['using_drugs'], params['none'], params['resume']] + params['using_drugs'], params['none'], "#{@resume_name}"] + begin worksheet.insert_rows(worksheet.num_rows + 1, [new_row]) worksheet.save mustache :jobsystem end + + begin + @filename = params[:resume][:filename] + resume = params[:resume][:tempfile] + File.open("./public/#{@filename}", 'wb') do |f| + f.write(resume.read) + end + + s3 = Aws::S3::Client.new(access_key_id: ENV['AWS_ACCESS'], + secret_access_key: ENV['AWS_SECRET'], + region: 'us-east-1') + s3.put_object(bucket: ENV['AWS_BUCKET'], key: @filename, body: resume) + end + if params['email_submission'] != '' - send_job_form_email(params['email_submission'], 'oppcenter_email', params) + send_job_form_email(params['email_submission'], 'oppcenter', params) end + redirect to ('/') # where to redirect after submission? end + get '/opportunity-center-info' do @title = 'Opportunity Center Information' diff --git a/docs/career_assessment_how_to.md b/docs/career_assessment_how_to.md index 13db805..81b40ff 100644 --- a/docs/career_assessment_how_to.md +++ b/docs/career_assessment_how_to.md @@ -14,7 +14,7 @@ Matching an image with a trait can happen three ways: The career info is managed via a google spreadsheet that is manually synced with the site's database. Updating existing career info or adding a new career doesn't involve any code updates, but adding a new trait or changing the assessment does. ### The google spreadsheet -The current production version of this site uses [this spreadsheet](https://docs.google.com/spreadsheets/d/1lMeZZ_vu-xIVKLgo7obKlF0X4iJ3oHkLKl8uIrPsSt8) (current owners CfA NOLA Fellows). +The current production version of this site uses [this spreadsheet](https://docs.google.com/spreadsheets/d/1cXQCnOpP_IcJS_N8VOPD1z9prYVUPGhtb7rlgvGnJ8E/pubhtml) (current owners CfA NOLA Fellows). *When editing the content DO NOT change the column headers or the content will not update properly.* The columns `description`, ` foundational_skills`, and `training` accept HTML formatting. It's recommended to double check your HTML with a tool like https://jsfiddle.net/. @@ -29,7 +29,7 @@ After filling in the info, go to 'File' > 'Publish to Web' and publish it as a w To update the information about a career: edit your spreadsheet, then go to the ["manage" page](http://workforwardnola.com/manage) & enter the username and password. Enter the PUBLIC link to the spreadsheet (it ends in `/pubhtml`) (Like https://docs.google.com/spreadsheets/d/1lMeZZ_vu-xIVKLgo7obKlF0X4iJ3oHkLKl8uIrPsSt8/pubhtml), wait for the link to be validated, then click "Update content". If an error message appears, double check the content format. When the content updates successfully, there will be a message indicating how many careers and traits were updated. You're done! ### Adding new career -Add a new row to the google spreadsheet. The columns `name`, `sector`, and `experienced_wage` are required. The `traits` column is required to have the new career be included in assessment results. After filling in the new row in the spreadsheet, follow the instructions for the 'Updating Career info' step above to load and publish the new information. +Add a new row to the google spreadsheet. The columns `name`, `sector`, and `experienced_range` are required. The `traits` column is required to have the new career be included in assessment results. After filling in the new row in the spreadsheet, follow the instructions for the 'Updating Career info' step above to load and publish the new information. ## Adding new trait Adding a new trait to the assessment cannot be done without additional coding work. diff --git a/docs/updating_content.md b/docs/updating_content.md index d8083ff..58e98be 100644 --- a/docs/updating_content.md +++ b/docs/updating_content.md @@ -15,7 +15,7 @@ The careers are managed via a google spreadsheet (https://docs.google.com/spread To update the information about a career: edit that spreadsheet, then go to the ["manage" page](http://workforwardnola.com/manage) & enter the username and password. Enter the PUBLIC link to the spreadsheet (https://docs.google.com/spreadsheets/d/1lMeZZ_vu-xIVKLgo7obKlF0X4iJ3oHkLKl8uIrPsSt8/pubhtml), wait for the link to be validated, then click "Update content". -When editing the content DO NOT change the column headers or the content will not update properly. The columns `description`, ` foundational_skills`, and `training` accept HTML formatting. It's recommended to double check your HTML with a tool like https://jsfiddle.net/. You will need to copy and paste your HTML in the tool, and run it to see the changes. +When editing the content DO NOT change the column headers or the content will not update properly. The columns `description`, `general_duties`, `training`, `career_image`, and `alt_title` accept HTML formatting. It's recommended to double check your HTML with a tool like https://jsfiddle.net/. You will need to copy and paste your HTML in the tool, and run it to see the changes. The numbers in the `traits` column correspond to the `id` column in the traits spreadsheet tab. To add or remove a trait from a career, add or remove the corrsponding `id` number from the `traits` column (make sure they are comma-separated). diff --git a/templates/jobsystem.mustache b/templates/jobsystem.mustache index 2acb68a..4d57f75 100644 --- a/templates/jobsystem.mustache +++ b/templates/jobsystem.mustache @@ -9,7 +9,7 @@

Job System Sign-up Form

-
+ Whats your name? *
How did you learn about us? * @@ -71,21 +71,21 @@
-
-

Now that you know where to go, add your contact information so that - we can follow up and answer any questions you may have.


- What's the best way to contact you? *
- E-mail
-
- Phone Call
-
- Text Message
-
- If you have a resume, upload it here.
-

+
+
+

Now that you know where to go, add your contact information so that + we can follow up and answer any questions you may have.


+ What's the best way to contact you? *
+ E-mail
+
+ Phone Call
+
+ Text Message
+
+ If you have a resume, upload it here.
+

- +

From bcb5248fbc1b26722f9473233f0dad743445fe84 Mon Sep 17 00:00:00 2001 From: Todd Loupe Date: Wed, 20 Dec 2017 23:11:14 +0000 Subject: [PATCH 06/14] Updated wording for accessibility on both index and the job form. --- templates/index.mustache | 2 +- templates/jobsystem.mustache | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/index.mustache b/templates/index.mustache index de03dc3..dada82f 100644 --- a/templates/index.mustache +++ b/templates/index.mustache @@ -46,7 +46,7 @@

Visit the location that's right for you

Click on a pin below to see the open hours, address, phone number and website for each Opportunity Center.

-

You can also click here to see a text-only version of this information.

+

You can also click here to see a text-only version of this information.

Sign up for the Opportunity Center job system and receive a personalized recommendation for next steps and a follow-up from a career advisor.

Job system diff --git a/templates/jobsystem.mustache b/templates/jobsystem.mustache index 4d57f75..bbd434e 100644 --- a/templates/jobsystem.mustache +++ b/templates/jobsystem.mustache @@ -9,7 +9,7 @@

Job System Sign-up Form

-
+ Whats your name? *
How did you learn about us? * @@ -85,7 +85,7 @@ If you have a resume, upload it here.


- +

From 486bd2114e3db2c83607e0245440c9ca8599680b Mon Sep 17 00:00:00 2001 From: Todd Loupe Date: Thu, 21 Dec 2017 21:32:44 +0000 Subject: [PATCH 07/14] Edited file i/o and revised emailer logic --- app.rb | 18 +++++++++++------- awsemailer.rb | 5 +++++ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/app.rb b/app.rb index 7ed1df5..a03c062 100644 --- a/app.rb +++ b/app.rb @@ -135,7 +135,7 @@ def worksheet begin @filename = params[:resume][:filename] resume = params[:resume][:tempfile] - File.open("./public/#{@filename}", 'wb') do |f| + File.open(@filename, 'wb') do |f| f.write(resume.read) end @@ -145,9 +145,7 @@ def worksheet s3.put_object(bucket: ENV['AWS_BUCKET'], key: @filename, body: resume) end - if params['email_submission'] != '' - send_job_form_email(params['email_submission'], 'oppcenter', params) - end + send_job_email('oppcenter', params) redirect to ('/') # where to redirect after submission? end @@ -196,7 +194,7 @@ def worksheet private - def send_job_form_email(recipient, oppcenter, params) + def send_job_email(oppcenter, params) # Specify a configuration set. To use a configuration # set, uncomment the next line and send it to the proper method # configsetname = "ConfigSet" @@ -221,7 +219,7 @@ def send_job_form_email(recipient, oppcenter, params)
Which neighborhood: #{params['neighborhood']}

Are you a young adult? #{params['young_adult']}

Are you a veteran? #{params['veteran']}
-
Do you have little access to transportaion? +
Do you have little access to transportation? #{params['no_transportation']}

Are you homeless or staying with someone temporarily? #{params['homeless']}
@@ -245,8 +243,14 @@ def send_job_form_email(recipient, oppcenter, params) sender = EmailProvider.sender owner = EmailProvider.owner puts self.emailer.inspect - emailer.send_email(sender, recipient, subject, textbody, htmlbody, + if params['email_submission'] != '' + recipient = params['email_submission'] + emailer.send_email(sender, recipient, subject, textbody, htmlbody, oppcenter, owner) + else + emailer.send_email(sender, recipient, subject, textbody, htmlbody, + oppcenter, owner) + end end end end diff --git a/awsemailer.rb b/awsemailer.rb index 930d004..485d332 100644 --- a/awsemailer.rb +++ b/awsemailer.rb @@ -20,6 +20,9 @@ def initialize(access, secret) def send_email(sender, recipient, subject, text_body, html_body, cc = nil, bcc = nil) encoding = 'UTF-8' + if recipient == nil + recipient = cc + end # Try to send the email. begin # Verify the emails, this will add them to the verified emails @@ -32,6 +35,7 @@ def send_email(sender, recipient, subject, text_body, html_body, cc = nil, bcc = # check_emails reply_to # Provide the contents of the email. + email_config_data = { destination: { to_addresses: [recipient, cc, bcc] }, message: { @@ -43,6 +47,7 @@ def send_email(sender, recipient, subject, text_body, html_body, cc = nil, bcc = }, source: sender } + # Email validation? # if not cc.nil? From b97666de347e3fc6cb76c0f60015b598d2dc366b Mon Sep 17 00:00:00 2001 From: Todd Loupe Date: Wed, 25 Apr 2018 01:19:31 +0000 Subject: [PATCH 08/14] Switched to Raw Emails for sending attachments. additionally handles errors with attachments and emails. --- Gemfile | 2 + Gemfile.lock | 542 ++++++++++++++++++++++++++++++++++++++++++++++++++ app.rb | 46 +++-- awsemailer.rb | 39 +++- 4 files changed, 599 insertions(+), 30 deletions(-) diff --git a/Gemfile b/Gemfile index b37abfc..87e4ee5 100644 --- a/Gemfile +++ b/Gemfile @@ -14,6 +14,8 @@ gem 'google_drive' gem 'pony' gem 'aws-sdk-ses' gem 'aws-sdk-s3' +gem 'mime' +gem 'aws-sdk' # database things gem 'pg' diff --git a/Gemfile.lock b/Gemfile.lock index 559e7d3..c80d769 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -4,20 +4,559 @@ GEM addressable (2.5.2) public_suffix (>= 2.0.2, < 4.0) aws-partitions (1.40.0) + aws-sdk (3.0.1) + aws-sdk-resources (~> 3) + aws-sdk-acm (1.6.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-acmpca (1.0.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-alexaforbusiness (1.2.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-apigateway (1.10.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-applicationautoscaling (1.8.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-applicationdiscoveryservice (1.1.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-appstream (1.7.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-appsync (1.1.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-athena (1.0.1) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-autoscaling (1.5.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-autoscalingplans (1.2.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-batch (1.4.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-budgets (1.5.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-cloud9 (1.1.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-clouddirectory (1.2.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-cloudformation (1.4.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-cloudfront (1.2.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-cloudhsm (1.3.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-cloudhsmv2 (1.1.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-cloudsearch (1.0.1) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-cloudsearchdomain (1.0.1) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-cloudtrail (1.0.1) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-cloudwatch (1.5.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-cloudwatchevents (1.3.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-cloudwatchlogs (1.3.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-codebuild (1.7.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-codecommit (1.3.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-codedeploy (1.3.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-codepipeline (1.2.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-codestar (1.1.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-cognitoidentity (1.0.1) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-cognitoidentityprovider (1.3.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-cognitosync (1.0.1) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-comprehend (1.0.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-configservice (1.8.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-connect (1.0.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) aws-sdk-core (3.9.0) aws-partitions (~> 1.0) aws-sigv4 (~> 1.0) jmespath (~> 1.0) + aws-sdk-costandusagereportservice (1.0.1) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-costexplorer (1.3.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-databasemigrationservice (1.5.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-datapipeline (1.0.1) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-dax (1.0.1) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-devicefarm (1.5.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-directconnect (1.1.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-directoryservice (1.1.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-dynamodb (1.5.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-dynamodbstreams (1.0.1) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-ec2 (1.30.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-ecr (1.3.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-ecs (1.12.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-efs (1.0.1) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-elasticache (1.3.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-elasticbeanstalk (1.6.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-elasticloadbalancing (1.2.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-elasticloadbalancingv2 (1.8.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-elasticsearchservice (1.4.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-elastictranscoder (1.0.1) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-emr (1.1.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-firehose (1.2.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-fms (1.0.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-gamelift (1.3.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-glacier (1.6.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-glue (1.7.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-greengrass (1.3.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-guardduty (1.2.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-health (1.0.1) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-iam (1.4.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-importexport (1.0.1) + aws-sdk-core (~> 3) + aws-sigv2 (~> 1.0) + aws-sdk-inspector (1.3.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-iot (1.5.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-iotanalytics (1.0.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-iotdataplane (1.0.1) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-iotjobsdataplane (1.0.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-kinesis (1.2.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-kinesisanalytics (1.2.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-kinesisvideo (1.0.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-kinesisvideoarchivedmedia (1.0.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-kinesisvideomedia (1.0.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) aws-sdk-kms (1.3.0) aws-sdk-core (~> 3) aws-sigv4 (~> 1.0) + aws-sdk-lambda (1.5.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-lambdapreview (1.0.1) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-lex (1.3.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-lexmodelbuildingservice (1.5.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-lightsail (1.4.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-machinelearning (1.0.1) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-marketplacecommerceanalytics (1.0.1) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-marketplaceentitlementservice (1.0.1) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-marketplacemetering (1.0.1) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-mediaconvert (1.1.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-medialive (1.5.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-mediapackage (1.1.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-mediastore (1.1.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-mediastoredata (1.1.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-migrationhub (1.1.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-mobile (1.0.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-mq (1.0.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-mturk (1.3.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-opsworks (1.2.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-opsworkscm (1.2.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-organizations (1.8.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-pinpoint (1.4.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-polly (1.4.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-pricing (1.0.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-rds (1.16.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-redshift (1.2.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-rekognition (1.2.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-resourcegroups (1.0.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-resourcegroupstaggingapi (1.0.1) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-resources (3.15.0) + aws-sdk-acm (~> 1) + aws-sdk-acmpca (~> 1) + aws-sdk-alexaforbusiness (~> 1) + aws-sdk-apigateway (~> 1) + aws-sdk-applicationautoscaling (~> 1) + aws-sdk-applicationdiscoveryservice (~> 1) + aws-sdk-appstream (~> 1) + aws-sdk-appsync (~> 1) + aws-sdk-athena (~> 1) + aws-sdk-autoscaling (~> 1) + aws-sdk-autoscalingplans (~> 1) + aws-sdk-batch (~> 1) + aws-sdk-budgets (~> 1) + aws-sdk-cloud9 (~> 1) + aws-sdk-clouddirectory (~> 1) + aws-sdk-cloudformation (~> 1) + aws-sdk-cloudfront (~> 1) + aws-sdk-cloudhsm (~> 1) + aws-sdk-cloudhsmv2 (~> 1) + aws-sdk-cloudsearch (~> 1) + aws-sdk-cloudsearchdomain (~> 1) + aws-sdk-cloudtrail (~> 1) + aws-sdk-cloudwatch (~> 1) + aws-sdk-cloudwatchevents (~> 1) + aws-sdk-cloudwatchlogs (~> 1) + aws-sdk-codebuild (~> 1) + aws-sdk-codecommit (~> 1) + aws-sdk-codedeploy (~> 1) + aws-sdk-codepipeline (~> 1) + aws-sdk-codestar (~> 1) + aws-sdk-cognitoidentity (~> 1) + aws-sdk-cognitoidentityprovider (~> 1) + aws-sdk-cognitosync (~> 1) + aws-sdk-comprehend (~> 1) + aws-sdk-configservice (~> 1) + aws-sdk-connect (~> 1) + aws-sdk-costandusagereportservice (~> 1) + aws-sdk-costexplorer (~> 1) + aws-sdk-databasemigrationservice (~> 1) + aws-sdk-datapipeline (~> 1) + aws-sdk-dax (~> 1) + aws-sdk-devicefarm (~> 1) + aws-sdk-directconnect (~> 1) + aws-sdk-directoryservice (~> 1) + aws-sdk-dynamodb (~> 1) + aws-sdk-dynamodbstreams (~> 1) + aws-sdk-ec2 (~> 1) + aws-sdk-ecr (~> 1) + aws-sdk-ecs (~> 1) + aws-sdk-efs (~> 1) + aws-sdk-elasticache (~> 1) + aws-sdk-elasticbeanstalk (~> 1) + aws-sdk-elasticloadbalancing (~> 1) + aws-sdk-elasticloadbalancingv2 (~> 1) + aws-sdk-elasticsearchservice (~> 1) + aws-sdk-elastictranscoder (~> 1) + aws-sdk-emr (~> 1) + aws-sdk-firehose (~> 1) + aws-sdk-fms (~> 1) + aws-sdk-gamelift (~> 1) + aws-sdk-glacier (~> 1) + aws-sdk-glue (~> 1) + aws-sdk-greengrass (~> 1) + aws-sdk-guardduty (~> 1) + aws-sdk-health (~> 1) + aws-sdk-iam (~> 1) + aws-sdk-importexport (~> 1) + aws-sdk-inspector (~> 1) + aws-sdk-iot (~> 1) + aws-sdk-iotanalytics (~> 1) + aws-sdk-iotdataplane (~> 1) + aws-sdk-iotjobsdataplane (~> 1) + aws-sdk-kinesis (~> 1) + aws-sdk-kinesisanalytics (~> 1) + aws-sdk-kinesisvideo (~> 1) + aws-sdk-kinesisvideoarchivedmedia (~> 1) + aws-sdk-kinesisvideomedia (~> 1) + aws-sdk-kms (~> 1) + aws-sdk-lambda (~> 1) + aws-sdk-lambdapreview (~> 1) + aws-sdk-lex (~> 1) + aws-sdk-lexmodelbuildingservice (~> 1) + aws-sdk-lightsail (~> 1) + aws-sdk-machinelearning (~> 1) + aws-sdk-marketplacecommerceanalytics (~> 1) + aws-sdk-marketplaceentitlementservice (~> 1) + aws-sdk-marketplacemetering (~> 1) + aws-sdk-mediaconvert (~> 1) + aws-sdk-medialive (~> 1) + aws-sdk-mediapackage (~> 1) + aws-sdk-mediastore (~> 1) + aws-sdk-mediastoredata (~> 1) + aws-sdk-migrationhub (~> 1) + aws-sdk-mobile (~> 1) + aws-sdk-mq (~> 1) + aws-sdk-mturk (~> 1) + aws-sdk-opsworks (~> 1) + aws-sdk-opsworkscm (~> 1) + aws-sdk-organizations (~> 1) + aws-sdk-pinpoint (~> 1) + aws-sdk-polly (~> 1) + aws-sdk-pricing (~> 1) + aws-sdk-rds (~> 1) + aws-sdk-redshift (~> 1) + aws-sdk-rekognition (~> 1) + aws-sdk-resourcegroups (~> 1) + aws-sdk-resourcegroupstaggingapi (~> 1) + aws-sdk-route53 (~> 1) + aws-sdk-route53domains (~> 1) + aws-sdk-s3 (~> 1) + aws-sdk-sagemaker (~> 1) + aws-sdk-sagemakerruntime (~> 1) + aws-sdk-secretsmanager (~> 1) + aws-sdk-serverlessapplicationrepository (~> 1) + aws-sdk-servicecatalog (~> 1) + aws-sdk-servicediscovery (~> 1) + aws-sdk-ses (~> 1) + aws-sdk-shield (~> 1) + aws-sdk-simpledb (~> 1) + aws-sdk-sms (~> 1) + aws-sdk-snowball (~> 1) + aws-sdk-sns (~> 1) + aws-sdk-sqs (~> 1) + aws-sdk-ssm (~> 1) + aws-sdk-states (~> 1) + aws-sdk-storagegateway (~> 1) + aws-sdk-support (~> 1) + aws-sdk-swf (~> 1) + aws-sdk-transcribeservice (~> 1) + aws-sdk-translate (~> 1) + aws-sdk-waf (~> 1) + aws-sdk-wafregional (~> 1) + aws-sdk-workdocs (~> 1) + aws-sdk-workmail (~> 1) + aws-sdk-workspaces (~> 1) + aws-sdk-xray (~> 1) + aws-sdk-route53 (1.9.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-route53domains (1.1.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) aws-sdk-s3 (1.8.0) aws-sdk-core (~> 3) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.0) + aws-sdk-sagemaker (1.7.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-sagemakerruntime (1.0.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-secretsmanager (1.2.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-serverlessapplicationrepository (1.2.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-servicecatalog (1.4.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-servicediscovery (1.2.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) aws-sdk-ses (1.4.0) aws-sdk-core (~> 3) aws-sigv4 (~> 1.0) + aws-sdk-shield (1.1.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-simpledb (1.0.1) + aws-sdk-core (~> 3) + aws-sigv2 (~> 1.0) + aws-sdk-sms (1.0.1) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-snowball (1.2.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-sns (1.1.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-sqs (1.3.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-ssm (1.12.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-states (1.2.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-storagegateway (1.3.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-support (1.0.1) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-swf (1.0.1) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-transcribeservice (1.1.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-translate (1.1.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-waf (1.4.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-wafregional (1.4.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-workdocs (1.1.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-workmail (1.1.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-workspaces (1.1.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-xray (1.1.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sigv2 (1.0.1) aws-sigv4 (1.0.2) concurrent-ruby (1.0.5) declarative (0.0.10) @@ -60,6 +599,7 @@ GEM mail (2.7.0) mini_mime (>= 0.1.1) memoist (0.16.0) + mime (0.4.4) mime-types (3.1) mime-types-data (~> 3.2015) mime-types-data (3.2016.0521) @@ -125,10 +665,12 @@ PLATFORMS ruby DEPENDENCIES + aws-sdk aws-sdk-s3 aws-sdk-ses dotenv google_drive + mime mustache-sinatra (~> 1) pg pony diff --git a/app.rb b/app.rb index a03c062..d294c5e 100644 --- a/app.rb +++ b/app.rb @@ -5,6 +5,7 @@ require 'pony' require './emailprovider.rb' require 'aws-sdk-s3' +require 'mime' require 'json' module WorkForwardNola @@ -115,7 +116,7 @@ def worksheet end post '/contact' do - @resume_name = params[:resume][:filename] + @resume_name = if !params[:resume].nil? then params[:resume][:filename] else nil end new_row = [params['first_name'], params['last_name'], params['best_way'], params['email_submission'], params['phone_submission'], params['text_submission'], params['referral'], @@ -132,22 +133,21 @@ def worksheet mustache :jobsystem end - begin - @filename = params[:resume][:filename] + if @resume_name resume = params[:resume][:tempfile] - File.open(@filename, 'wb') do |f| + File.open(@resume_name, 'wb') do |f| f.write(resume.read) - end - s3 = Aws::S3::Client.new(access_key_id: ENV['AWS_ACCESS'], secret_access_key: ENV['AWS_SECRET'], region: 'us-east-1') - s3.put_object(bucket: ENV['AWS_BUCKET'], key: @filename, body: resume) + s3.put_object(bucket: ENV['AWS_BUCKET'], key: @resume_name, body: resume) + end end - - send_job_email('oppcenter', params) - - redirect to ('/') # where to redirect after submission? + + #TODO: send opportunity centers through + #use as string for testing until function works + send_job_email('oppcenters', params, resume) + redirect to '/' # where to redirect after submission? end @@ -194,12 +194,13 @@ def worksheet private - def send_job_email(oppcenter, params) + def send_job_email(oppcenter, params, resume = nil) # Specify a configuration set. To use a configuration # set, uncomment the next line and send it to the proper method # configsetname = "ConfigSet" subject = 'New Submission: Opportunity Center Sign Up' - + attachment = nil + attachment = resume.path() unless resume.nil? htmlbody = " Thank you for registering in the New Orleans job system. @@ -242,15 +243,16 @@ def send_job_email(oppcenter, params) emailer = EmailProvider.emailer sender = EmailProvider.sender owner = EmailProvider.owner - puts self.emailer.inspect - if params['email_submission'] != '' - recipient = params['email_submission'] - emailer.send_email(sender, recipient, subject, textbody, htmlbody, - oppcenter, owner) - else - emailer.send_email(sender, recipient, subject, textbody, htmlbody, - oppcenter, owner) - end + #puts self.emailer.inspect + # TODO: wire up oppcenter function param + # TODO: get city manager email + city_manager_email = 'placeholder@mail.com' + # TODO: get opportunity center email based on function param + recipients = [] + recipients.push params['email_submission'] if params['email_submission'] != '' + recipients.push city_manager_email + # recipients.push opp_center_email + emailer.send_email(recipients, sender, subject, textbody, htmlbody, attachment) end end end diff --git a/awsemailer.rb b/awsemailer.rb index 485d332..4d5386a 100644 --- a/awsemailer.rb +++ b/awsemailer.rb @@ -1,7 +1,9 @@ require 'aws-sdk-ses' # v2: require 'aws-sdk' +require 'aws-sdk' require './emailer.rb' require './app.rb' require 'dotenv' +require 'mime' module WorkForwardNola # Class for sending out emails through AWS @@ -18,11 +20,24 @@ def initialize(access, secret) end end - def send_email(sender, recipient, subject, text_body, html_body, cc = nil, bcc = nil) + def send_email(recipients, sender, subject, text_body, html_body, attachment_file = nil) encoding = 'UTF-8' - if recipient == nil - recipient = cc + if recipients == nil + recipients = cc end + msg_mixed = MIME::Multipart::Mixed.new + unless attachment_file.nil? + attachment = MIME::Application.new(Base64::encode64(open(attachment_file,"rb").read)) + attachment.transfer_encoding = 'base64' + attachment.disposition = 'attachment' + msg_mixed.attach(attachment, 'filename' => attachment_file) + end + msg_body = MIME::Multipart::Alternative.new + msg_body.add(MIME::Text.new(text_body,'plain')) + msg_body.add(MIME::Text.new(html_body,'html')) + msg_mixed.add(msg_body) + msg = MIME::Mail.new(msg_mixed) + msg.subject = subject # Try to send the email. begin # Verify the emails, this will add them to the verified emails @@ -35,7 +50,16 @@ def send_email(sender, recipient, subject, text_body, html_body, cc = nil, bcc = # check_emails reply_to # Provide the contents of the email. - + + resp = @ses.send_raw_email({ + source: sender, + destinations: recipients, + raw_message: { + data: msg.to_s + } + }) + #msg.headers.set('X-SES-CONFIGURATION-SET',configsetname) +=begin email_config_data = { destination: { to_addresses: [recipient, cc, bcc] }, message: { @@ -47,8 +71,7 @@ def send_email(sender, recipient, subject, text_body, html_body, cc = nil, bcc = }, source: sender } - - +=end # Email validation? # if not cc.nil? # email_config_data[:destination][:cc_addresses] = as_email_array(cc) @@ -60,8 +83,8 @@ def send_email(sender, recipient, subject, text_body, html_body, cc = nil, bcc = # email_config_data[:reply_to] = reply_to # not sure about the key on this one. # end - resp = @ses.send_email(email_config_data) - puts "Email sent to #{recipient.inspect}: #{resp.inspect}" + #resp = @ses.send_email(email_config_data) + puts "Email sent to #{recipients.inspect}: #{resp.inspect}" rescue Aws::SES::Errors::ServiceError => error # If something goes wrong, display an error message. throw error From 41557115d4a44724252300361456cef9042a9490 Mon Sep 17 00:00:00 2001 From: Todd Loupe Date: Wed, 25 Apr 2018 01:27:47 +0000 Subject: [PATCH 09/14] Fixed gems --- Gemfile | 2 +- app.rb | 1 - awsemailer.rb | 3 --- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index 87e4ee5..5725f1e 100644 --- a/Gemfile +++ b/Gemfile @@ -15,7 +15,7 @@ gem 'pony' gem 'aws-sdk-ses' gem 'aws-sdk-s3' gem 'mime' -gem 'aws-sdk' +#gem 'aws-sdk' # database things gem 'pg' diff --git a/app.rb b/app.rb index d294c5e..8095d04 100644 --- a/app.rb +++ b/app.rb @@ -5,7 +5,6 @@ require 'pony' require './emailprovider.rb' require 'aws-sdk-s3' -require 'mime' require 'json' module WorkForwardNola diff --git a/awsemailer.rb b/awsemailer.rb index 4d5386a..226c998 100644 --- a/awsemailer.rb +++ b/awsemailer.rb @@ -1,7 +1,5 @@ require 'aws-sdk-ses' # v2: require 'aws-sdk' -require 'aws-sdk' require './emailer.rb' -require './app.rb' require 'dotenv' require 'mime' @@ -21,7 +19,6 @@ def initialize(access, secret) end def send_email(recipients, sender, subject, text_body, html_body, attachment_file = nil) - encoding = 'UTF-8' if recipients == nil recipients = cc end From 694b1dfb06583118820b4a5a7120b15fccd3ea15 Mon Sep 17 00:00:00 2001 From: Todd Loupe Date: Wed, 25 Apr 2018 01:29:43 +0000 Subject: [PATCH 10/14] Fixed gems 2.0 --- Gemfile.lock | 540 --------------------------------------------------- 1 file changed, 540 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index c80d769..0683e7c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -4,559 +4,20 @@ GEM addressable (2.5.2) public_suffix (>= 2.0.2, < 4.0) aws-partitions (1.40.0) - aws-sdk (3.0.1) - aws-sdk-resources (~> 3) - aws-sdk-acm (1.6.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-acmpca (1.0.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-alexaforbusiness (1.2.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-apigateway (1.10.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-applicationautoscaling (1.8.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-applicationdiscoveryservice (1.1.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-appstream (1.7.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-appsync (1.1.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-athena (1.0.1) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-autoscaling (1.5.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-autoscalingplans (1.2.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-batch (1.4.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-budgets (1.5.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-cloud9 (1.1.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-clouddirectory (1.2.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-cloudformation (1.4.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-cloudfront (1.2.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-cloudhsm (1.3.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-cloudhsmv2 (1.1.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-cloudsearch (1.0.1) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-cloudsearchdomain (1.0.1) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-cloudtrail (1.0.1) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-cloudwatch (1.5.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-cloudwatchevents (1.3.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-cloudwatchlogs (1.3.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-codebuild (1.7.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-codecommit (1.3.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-codedeploy (1.3.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-codepipeline (1.2.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-codestar (1.1.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-cognitoidentity (1.0.1) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-cognitoidentityprovider (1.3.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-cognitosync (1.0.1) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-comprehend (1.0.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-configservice (1.8.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-connect (1.0.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) aws-sdk-core (3.9.0) aws-partitions (~> 1.0) aws-sigv4 (~> 1.0) jmespath (~> 1.0) - aws-sdk-costandusagereportservice (1.0.1) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-costexplorer (1.3.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-databasemigrationservice (1.5.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-datapipeline (1.0.1) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-dax (1.0.1) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-devicefarm (1.5.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-directconnect (1.1.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-directoryservice (1.1.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-dynamodb (1.5.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-dynamodbstreams (1.0.1) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-ec2 (1.30.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-ecr (1.3.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-ecs (1.12.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-efs (1.0.1) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-elasticache (1.3.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-elasticbeanstalk (1.6.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-elasticloadbalancing (1.2.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-elasticloadbalancingv2 (1.8.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-elasticsearchservice (1.4.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-elastictranscoder (1.0.1) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-emr (1.1.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-firehose (1.2.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-fms (1.0.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-gamelift (1.3.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-glacier (1.6.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-glue (1.7.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-greengrass (1.3.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-guardduty (1.2.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-health (1.0.1) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-iam (1.4.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-importexport (1.0.1) - aws-sdk-core (~> 3) - aws-sigv2 (~> 1.0) - aws-sdk-inspector (1.3.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-iot (1.5.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-iotanalytics (1.0.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-iotdataplane (1.0.1) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-iotjobsdataplane (1.0.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-kinesis (1.2.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-kinesisanalytics (1.2.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-kinesisvideo (1.0.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-kinesisvideoarchivedmedia (1.0.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-kinesisvideomedia (1.0.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) aws-sdk-kms (1.3.0) aws-sdk-core (~> 3) aws-sigv4 (~> 1.0) - aws-sdk-lambda (1.5.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-lambdapreview (1.0.1) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-lex (1.3.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-lexmodelbuildingservice (1.5.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-lightsail (1.4.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-machinelearning (1.0.1) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-marketplacecommerceanalytics (1.0.1) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-marketplaceentitlementservice (1.0.1) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-marketplacemetering (1.0.1) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-mediaconvert (1.1.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-medialive (1.5.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-mediapackage (1.1.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-mediastore (1.1.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-mediastoredata (1.1.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-migrationhub (1.1.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-mobile (1.0.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-mq (1.0.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-mturk (1.3.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-opsworks (1.2.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-opsworkscm (1.2.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-organizations (1.8.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-pinpoint (1.4.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-polly (1.4.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-pricing (1.0.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-rds (1.16.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-redshift (1.2.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-rekognition (1.2.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-resourcegroups (1.0.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-resourcegroupstaggingapi (1.0.1) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-resources (3.15.0) - aws-sdk-acm (~> 1) - aws-sdk-acmpca (~> 1) - aws-sdk-alexaforbusiness (~> 1) - aws-sdk-apigateway (~> 1) - aws-sdk-applicationautoscaling (~> 1) - aws-sdk-applicationdiscoveryservice (~> 1) - aws-sdk-appstream (~> 1) - aws-sdk-appsync (~> 1) - aws-sdk-athena (~> 1) - aws-sdk-autoscaling (~> 1) - aws-sdk-autoscalingplans (~> 1) - aws-sdk-batch (~> 1) - aws-sdk-budgets (~> 1) - aws-sdk-cloud9 (~> 1) - aws-sdk-clouddirectory (~> 1) - aws-sdk-cloudformation (~> 1) - aws-sdk-cloudfront (~> 1) - aws-sdk-cloudhsm (~> 1) - aws-sdk-cloudhsmv2 (~> 1) - aws-sdk-cloudsearch (~> 1) - aws-sdk-cloudsearchdomain (~> 1) - aws-sdk-cloudtrail (~> 1) - aws-sdk-cloudwatch (~> 1) - aws-sdk-cloudwatchevents (~> 1) - aws-sdk-cloudwatchlogs (~> 1) - aws-sdk-codebuild (~> 1) - aws-sdk-codecommit (~> 1) - aws-sdk-codedeploy (~> 1) - aws-sdk-codepipeline (~> 1) - aws-sdk-codestar (~> 1) - aws-sdk-cognitoidentity (~> 1) - aws-sdk-cognitoidentityprovider (~> 1) - aws-sdk-cognitosync (~> 1) - aws-sdk-comprehend (~> 1) - aws-sdk-configservice (~> 1) - aws-sdk-connect (~> 1) - aws-sdk-costandusagereportservice (~> 1) - aws-sdk-costexplorer (~> 1) - aws-sdk-databasemigrationservice (~> 1) - aws-sdk-datapipeline (~> 1) - aws-sdk-dax (~> 1) - aws-sdk-devicefarm (~> 1) - aws-sdk-directconnect (~> 1) - aws-sdk-directoryservice (~> 1) - aws-sdk-dynamodb (~> 1) - aws-sdk-dynamodbstreams (~> 1) - aws-sdk-ec2 (~> 1) - aws-sdk-ecr (~> 1) - aws-sdk-ecs (~> 1) - aws-sdk-efs (~> 1) - aws-sdk-elasticache (~> 1) - aws-sdk-elasticbeanstalk (~> 1) - aws-sdk-elasticloadbalancing (~> 1) - aws-sdk-elasticloadbalancingv2 (~> 1) - aws-sdk-elasticsearchservice (~> 1) - aws-sdk-elastictranscoder (~> 1) - aws-sdk-emr (~> 1) - aws-sdk-firehose (~> 1) - aws-sdk-fms (~> 1) - aws-sdk-gamelift (~> 1) - aws-sdk-glacier (~> 1) - aws-sdk-glue (~> 1) - aws-sdk-greengrass (~> 1) - aws-sdk-guardduty (~> 1) - aws-sdk-health (~> 1) - aws-sdk-iam (~> 1) - aws-sdk-importexport (~> 1) - aws-sdk-inspector (~> 1) - aws-sdk-iot (~> 1) - aws-sdk-iotanalytics (~> 1) - aws-sdk-iotdataplane (~> 1) - aws-sdk-iotjobsdataplane (~> 1) - aws-sdk-kinesis (~> 1) - aws-sdk-kinesisanalytics (~> 1) - aws-sdk-kinesisvideo (~> 1) - aws-sdk-kinesisvideoarchivedmedia (~> 1) - aws-sdk-kinesisvideomedia (~> 1) - aws-sdk-kms (~> 1) - aws-sdk-lambda (~> 1) - aws-sdk-lambdapreview (~> 1) - aws-sdk-lex (~> 1) - aws-sdk-lexmodelbuildingservice (~> 1) - aws-sdk-lightsail (~> 1) - aws-sdk-machinelearning (~> 1) - aws-sdk-marketplacecommerceanalytics (~> 1) - aws-sdk-marketplaceentitlementservice (~> 1) - aws-sdk-marketplacemetering (~> 1) - aws-sdk-mediaconvert (~> 1) - aws-sdk-medialive (~> 1) - aws-sdk-mediapackage (~> 1) - aws-sdk-mediastore (~> 1) - aws-sdk-mediastoredata (~> 1) - aws-sdk-migrationhub (~> 1) - aws-sdk-mobile (~> 1) - aws-sdk-mq (~> 1) - aws-sdk-mturk (~> 1) - aws-sdk-opsworks (~> 1) - aws-sdk-opsworkscm (~> 1) - aws-sdk-organizations (~> 1) - aws-sdk-pinpoint (~> 1) - aws-sdk-polly (~> 1) - aws-sdk-pricing (~> 1) - aws-sdk-rds (~> 1) - aws-sdk-redshift (~> 1) - aws-sdk-rekognition (~> 1) - aws-sdk-resourcegroups (~> 1) - aws-sdk-resourcegroupstaggingapi (~> 1) - aws-sdk-route53 (~> 1) - aws-sdk-route53domains (~> 1) - aws-sdk-s3 (~> 1) - aws-sdk-sagemaker (~> 1) - aws-sdk-sagemakerruntime (~> 1) - aws-sdk-secretsmanager (~> 1) - aws-sdk-serverlessapplicationrepository (~> 1) - aws-sdk-servicecatalog (~> 1) - aws-sdk-servicediscovery (~> 1) - aws-sdk-ses (~> 1) - aws-sdk-shield (~> 1) - aws-sdk-simpledb (~> 1) - aws-sdk-sms (~> 1) - aws-sdk-snowball (~> 1) - aws-sdk-sns (~> 1) - aws-sdk-sqs (~> 1) - aws-sdk-ssm (~> 1) - aws-sdk-states (~> 1) - aws-sdk-storagegateway (~> 1) - aws-sdk-support (~> 1) - aws-sdk-swf (~> 1) - aws-sdk-transcribeservice (~> 1) - aws-sdk-translate (~> 1) - aws-sdk-waf (~> 1) - aws-sdk-wafregional (~> 1) - aws-sdk-workdocs (~> 1) - aws-sdk-workmail (~> 1) - aws-sdk-workspaces (~> 1) - aws-sdk-xray (~> 1) - aws-sdk-route53 (1.9.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-route53domains (1.1.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) aws-sdk-s3 (1.8.0) aws-sdk-core (~> 3) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.0) - aws-sdk-sagemaker (1.7.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-sagemakerruntime (1.0.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-secretsmanager (1.2.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-serverlessapplicationrepository (1.2.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-servicecatalog (1.4.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-servicediscovery (1.2.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) aws-sdk-ses (1.4.0) aws-sdk-core (~> 3) aws-sigv4 (~> 1.0) - aws-sdk-shield (1.1.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-simpledb (1.0.1) - aws-sdk-core (~> 3) - aws-sigv2 (~> 1.0) - aws-sdk-sms (1.0.1) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-snowball (1.2.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-sns (1.1.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-sqs (1.3.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-ssm (1.12.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-states (1.2.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-storagegateway (1.3.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-support (1.0.1) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-swf (1.0.1) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-transcribeservice (1.1.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-translate (1.1.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-waf (1.4.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-wafregional (1.4.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-workdocs (1.1.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-workmail (1.1.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-workspaces (1.1.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-xray (1.1.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sigv2 (1.0.1) aws-sigv4 (1.0.2) concurrent-ruby (1.0.5) declarative (0.0.10) @@ -665,7 +126,6 @@ PLATFORMS ruby DEPENDENCIES - aws-sdk aws-sdk-s3 aws-sdk-ses dotenv From 899574bfa37a5c224c2f1d9b0cb36b44af5ce24e Mon Sep 17 00:00:00 2001 From: Todd Loupe Date: Thu, 17 May 2018 03:16:05 +0000 Subject: [PATCH 11/14] Finished the emailer system, updated READMES, squashed bug, and increased accessibility for job form. --- README.md | 18 ++++++++---- app.rb | 30 +++++++++++-------- awsemailer.rb | 5 ++-- docs/career_assessment_how_to.md | 2 +- docs/updating_content.md | 4 +-- emailprovider.rb | 5 ++-- models/oppcenter.rb | 2 +- templates/jobsystem.mustache | 50 ++++++++++++++------------------ templates/manage.mustache | 8 ++--- 9 files changed, 64 insertions(+), 60 deletions(-) diff --git a/README.md b/README.md index 1c1e6b0..7805e5d 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,14 @@ The Code for America NOLA fellows team is no longer actively developing this. We The "Email to yourself" career assessment feature requires the `EMAIL_xxxx` config variables to be set. We use the [pony](https://github.com/benprew/pony) gem to send emails, please see their documentation for more details. +Some changes have included various AWS services. In addition to SMTP from the pony gem, several config variables must be set for AWS services (S3 and SES). These are new additions added below the `EMAIL_xxxx` config variables. + +Setting up SES: `SENDER_EMAIL`, `OWNER_EMAIL`, `AWS_ACCESS`, `AWS_SECRET` must all be configured in `.env` for the SES to work through the job form. + +Setting up S3: Configure `AWS_BUCKET` in `.env` + +There is additionally an optional feature to write to google sheets using a file `client_secret.json`. An example is included in `client_secret.json.example`. If you do not wish to use this feature, do not create or use `client_secret.json`! You can find information on the [google-drive-ruby](https://github.com/gimite/google-drive-ruby) GitHub. + ## Updating content For details on updating content see other files under the `docs/` folder. Details on updating career info via spreadsheet specifically is in [docs/career_assessment_how_to.md](docs/career_assessment_how_to.md). @@ -37,14 +45,12 @@ We are not AWS experts, so if you have recommendations to improve the following, 1. Create an IAM user (as recommended by Amazon) with appropriate permissions for deployment credentials. @antislice has no idea what specific permissions are needed for EB deployment, so we tested with admin. 2. Install the Elastic Beanstalk client. -2. Follow the Create an Application steps in [this documentation](http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_Ruby_sinatra.html#create_deploy_Ruby_eb_init). +3. Follow the Create an Application steps in [this documentation](http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_Ruby_sinatra.html#create_deploy_Ruby_eb_init). * For steps 5/6, select `Ruby` and `Ruby 2.2 (Puma)` * SSH login is optional, but convenient -3. At this point, you'll want to set up the DB. We created an integrated Postgres database instance (v. 9.5.2) as described in [here](http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features.managing.db.html). -4. Setting up SES: `SENDER_EMAIL`, `OWNER_EMAIL`, `AWS_ACCESS`, `AWS_SECRET` must all be configured in .env for the SES to work through the job form. -5. Setting up S3: Configure `AWS_BUCKET` in `.env` -6. Walk through [Create an Environment](http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_Ruby_sinatra.html#create_deploy_Ruby_eb_env) -7. ‼️ At this point, stop and check on the instance type. You may need to configure a VPC. +4. At this point, you'll want to set up the DB. We created an integrated Postgres database instance (v. 9.5.2) as described in [here](http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features.managing.db.html). +5. Walk through [Create an Environment](http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_Ruby_sinatra.html#create_deploy_Ruby_eb_env) +6. ‼️ At this point, stop and check on the instance type. You may need to configure a VPC. 7. Try deploying: `eb deploy` Configuring the "email to yourself" feature requires extra configuration on EB. diff --git a/app.rb b/app.rb index 2fc6c63..17298da 100644 --- a/app.rb +++ b/app.rb @@ -172,8 +172,8 @@ def worksheet end end - send_job_email('oppcenters', params, resume) - redirect to('/') + send_job_email(params, @resume_name, resume) + redirect to '/' end get '/opportunity-center-info' do @@ -228,17 +228,16 @@ def worksheet end redirect to('/manage') end - end -end - -private - - def send_job_email(oppcenter, params, resume = nil) + + private + + def send_job_email(params, resume_name = nil, resume = nil) # Specify a configuration set. To use a configuration # set, uncomment the next line and send it to the proper method # configsetname = "ConfigSet" subject = 'New Submission: Opportunity Center Sign Up' attachment = nil + attachment_name = resume_name attachment = resume.path() unless resume.nil? htmlbody = " @@ -280,15 +279,22 @@ def send_job_email(oppcenter, params, resume = nil) needs or barriers. You'll get a reply by email of who to contact. If you do not have email, someone will call you." emailer = EmailProvider.emailer - sender = EmailProvider.sender owner = EmailProvider.owner + sender = EmailProvider.sender #puts self.emailer.inspect # TODO: wire up oppcenter function param # TODO: get city manager email - city_manager_email = 'placeholder@mail.com' + # city_manager_email = 'placeholder@mail.com' # TODO: get opportunity center email based on function param recipients = [] + recipients.push owner recipients.push params['email_submission'] if params['email_submission'] != '' - recipients.push city_manager_email + recipients.push params['job1'] if params['job1'] + recipients.push params['goodwill'] if params['goodwill'] + recipients.push params['tca'] if params['tca'] # recipients.push opp_center_email - emailer.send_email(recipients, sender, subject, textbody, htmlbody, attachment) + emailer.send_email(recipients, sender, subject, textbody, htmlbody, + attachment_name, attachment) + end + end +end \ No newline at end of file diff --git a/awsemailer.rb b/awsemailer.rb index 226c998..4842420 100644 --- a/awsemailer.rb +++ b/awsemailer.rb @@ -18,7 +18,8 @@ def initialize(access, secret) end end - def send_email(recipients, sender, subject, text_body, html_body, attachment_file = nil) + def send_email(recipients, sender, subject, text_body, html_body, + attachment_name = nil, attachment_file = nil) if recipients == nil recipients = cc end @@ -27,7 +28,7 @@ def send_email(recipients, sender, subject, text_body, html_body, attachment_fil attachment = MIME::Application.new(Base64::encode64(open(attachment_file,"rb").read)) attachment.transfer_encoding = 'base64' attachment.disposition = 'attachment' - msg_mixed.attach(attachment, 'filename' => attachment_file) + msg_mixed.attach(attachment, 'filename' => attachment_name) end msg_body = MIME::Multipart::Alternative.new msg_body.add(MIME::Text.new(text_body,'plain')) diff --git a/docs/career_assessment_how_to.md b/docs/career_assessment_how_to.md index 81b40ff..52bb083 100644 --- a/docs/career_assessment_how_to.md +++ b/docs/career_assessment_how_to.md @@ -14,7 +14,7 @@ Matching an image with a trait can happen three ways: The career info is managed via a google spreadsheet that is manually synced with the site's database. Updating existing career info or adding a new career doesn't involve any code updates, but adding a new trait or changing the assessment does. ### The google spreadsheet -The current production version of this site uses [this spreadsheet](https://docs.google.com/spreadsheets/d/1cXQCnOpP_IcJS_N8VOPD1z9prYVUPGhtb7rlgvGnJ8E/pubhtml) (current owners CfA NOLA Fellows). +The current production version of this site uses [this spreadsheet](https://docs.google.com/spreadsheets/d/1cXQCnOpP_IcJS_N8VOPD1z9prYVUPGhtb7rlgvGnJ8E/pubhtml) (current owners Loyola University New Orleans Department of Computer Science). *When editing the content DO NOT change the column headers or the content will not update properly.* The columns `description`, ` foundational_skills`, and `training` accept HTML formatting. It's recommended to double check your HTML with a tool like https://jsfiddle.net/. diff --git a/docs/updating_content.md b/docs/updating_content.md index 58e98be..d6f25b5 100644 --- a/docs/updating_content.md +++ b/docs/updating_content.md @@ -11,9 +11,9 @@ The basic html for each page can be found in a `*.mustache` file in the `/templa * Text-only Opportunity Center information from map: `opp_center_info.mustache` ## Career assessment -The careers are managed via a google spreadsheet (https://docs.google.com/spreadsheets/d/1lMeZZ_vu-xIVKLgo7obKlF0X4iJ3oHkLKl8uIrPsSt8, current owners CfA Fellows). +The careers are managed via a google spreadsheet (`https://docs.google.com/spreadsheets/d/1cXQCnOpP_IcJS_N8VOPD1z9prYVUPGhtb7rlgvGnJ8E`, current owners Loyola University New Orleans Department of Computer Science). -To update the information about a career: edit that spreadsheet, then go to the ["manage" page](http://workforwardnola.com/manage) & enter the username and password. Enter the PUBLIC link to the spreadsheet (https://docs.google.com/spreadsheets/d/1lMeZZ_vu-xIVKLgo7obKlF0X4iJ3oHkLKl8uIrPsSt8/pubhtml), wait for the link to be validated, then click "Update content". +To update the information about a career: edit that spreadsheet, then go to the ["manage" page](http://workforwardnola.com/manage) & enter the username and password. Enter the PUBLIC link to the spreadsheet (`https://docs.google.com/spreadsheets/d/1cXQCnOpP_IcJS_N8VOPD1z9prYVUPGhtb7rlgvGnJ8E/pubhtml`), wait for the link to be validated, then click "Update content". When editing the content DO NOT change the column headers or the content will not update properly. The columns `description`, `general_duties`, `training`, `career_image`, and `alt_title` accept HTML formatting. It's recommended to double check your HTML with a tool like https://jsfiddle.net/. You will need to copy and paste your HTML in the tool, and run it to see the changes. diff --git a/emailprovider.rb b/emailprovider.rb index 18314d0..8f64bcf 100644 --- a/emailprovider.rb +++ b/emailprovider.rb @@ -1,16 +1,15 @@ require './awsemailer.rb' - module WorkForwardNola # Sets up AWS SES variables through the environment file class EmailProvider @@emailer = AwsEmailer.new ENV['AWS_ACCESS'], ENV['AWS_SECRET'] - @@senderEmail = ENV['SENDER_EMAIL'] @@ownerEmail = ENV['OWNER_EMAIL'] + @@senderEmail = ENV['SENDER_EMAIL'] def self.emailer @@emailer end - + def self.sender @@senderEmail end diff --git a/models/oppcenter.rb b/models/oppcenter.rb index b27b613..8784022 100644 --- a/models/oppcenter.rb +++ b/models/oppcenter.rb @@ -3,7 +3,7 @@ module WorkForwardNola class OppCenter < Sequel::Model def self.bulk_create(data) # Clear oppcenter table - OppCenter.db.run 'TRUNCATE oppcenters CASCADE' + OppCenter.db.run 'TRUNCATE opp_centers CASCADE' data.each do |opp_c| OppCenter.create( center: opp_c['center'], diff --git a/templates/jobsystem.mustache b/templates/jobsystem.mustache index 4be6918..219a457 100644 --- a/templates/jobsystem.mustache +++ b/templates/jobsystem.mustache @@ -15,31 +15,25 @@

Job System Sign-up Form

- Whats your name? * -
- How did you learn about us? * -

- - - -
- -
-
- First Name                  - Last Name - - -
-

We're going to ask a couple of questions to figure out which + What's your name? * +
+ First Name:
+ Last Name: +

+ How did you learn about us? * +
+ + +
+

We're going to ask a couple of questions to figure out which Opportunity Center is the best match for you

Which of these apply to you? *

@@ -83,11 +77,11 @@ we can follow up and answer any questions you may have.
What's the best way to contact you? *
E-mail
-
+
Phone Call
-
+
Text Message
-
+
If you have a resume, upload it here.


diff --git a/templates/manage.mustache b/templates/manage.mustache index 721fdbb..9886736 100644 --- a/templates/manage.mustache +++ b/templates/manage.mustache @@ -9,6 +9,8 @@

+

Update Opportunity Center Information:

@@ -21,12 +23,8 @@

- -
- -

If you're starting from scratch, use this template. After all your data is in, publish it to the web ("File" > "Publish to Web") and use that url above.

+

If you're starting from scratch, use this as a reference. After all your data is in, publish it to the web ("File" > "Publish to Web") and use that url above.

If you're working with Code for America, use this url.

Trouble saving data? Make sure it adheres to the following:

    From b5afbfbfb4f8f9971483925ade94cc91eb4b3cef Mon Sep 17 00:00:00 2001 From: Todd Loupe Date: Thu, 17 May 2018 03:29:33 +0000 Subject: [PATCH 12/14] Rubocop --- app.rb | 60 +++++++++++++++++++++------------------------- awsemailer.rb | 62 +++++++++++++----------------------------------- emailer.rb | 7 +++--- emailprovider.rb | 30 +++++++++++------------ 4 files changed, 61 insertions(+), 98 deletions(-) diff --git a/app.rb b/app.rb index 17298da..547e7ca 100644 --- a/app.rb +++ b/app.rb @@ -61,11 +61,11 @@ def authorized? require './models/contact' require './models/oppcenter' end - + if File.exist?('./client_secret.json') def worksheet - @session ||= GoogleDrive::Session.from_service_account_key("client_secret.json") - @spreadsheet ||= @session.spreadsheet_by_title("contact") + @session ||= GoogleDrive::Session.from_service_account_key('client_secret.json') + @spreadsheet ||= @session.spreadsheet_by_title('contact') @worksheet ||= @spreadsheet.worksheets.first end end @@ -120,7 +120,7 @@ def worksheet end post '/contact' do - @resume_name = if !params[:resume].nil? then params[:resume][:filename] else nil end + @resume_name = !params[:resume].nil? ? params[:resume][:filename] : nil new_form = Contact.create( first_name: params['first_name'], last_name: params['last_name'], @@ -147,31 +147,31 @@ def worksheet if File.exist?('./client_secret.json') new_row = [params['first_name'], params['last_name'], params['best_way'], - params['email_submission'], params['phone_submission'], - params['text_submission'], params['referral'], - params['neighborhood'], params['young_adult'], - params['veteran'], params['no_transportation'], - params['homeless'], params['no_drivers_license'], - params['no_state_id'], params['disabled'], params['childcare'], - params['criminal'], params['previously_incarcerated'], - params['using_drugs'], params['none'], "#{@resume_name}"] + params['email_submission'], params['phone_submission'], + params['text_submission'], params['referral'], + params['neighborhood'], params['young_adult'], + params['veteran'], params['no_transportation'], + params['homeless'], params['no_drivers_license'], + params['no_state_id'], params['disabled'], params['childcare'], + params['criminal'], params['previously_incarcerated'], + params['using_drugs'], params['none'], "#{@resume_name}"] begin worksheet.insert_rows(worksheet.num_rows + 1, [new_row]) worksheet.save end end - + if @resume_name resume = params[:resume][:tempfile] File.open(@resume_name, 'wb') do |f| - f.write(resume.read) - s3 = Aws::S3::Client.new(access_key_id: ENV['AWS_ACCESS'], - secret_access_key: ENV['AWS_SECRET'], - region: 'us-east-1') - s3.put_object(bucket: ENV['AWS_BUCKET'], key: @resume_name, body: resume) + f.write(resume.read) + s3 = Aws::S3::Client.new(access_key_id: ENV['AWS_ACCESS'], + secret_access_key: ENV['AWS_SECRET'], + region: 'us-east-1') + s3.put_object(bucket: ENV['AWS_BUCKET'], key: @resume_name, body: resume) end end - + send_job_email(params, @resume_name, resume) redirect to '/' end @@ -228,9 +228,9 @@ def worksheet end redirect to('/manage') end - + private - + def send_job_email(params, resume_name = nil, resume = nil) # Specify a configuration set. To use a configuration # set, uncomment the next line and send it to the proper method @@ -238,7 +238,7 @@ def send_job_email(params, resume_name = nil, resume = nil) subject = 'New Submission: Opportunity Center Sign Up' attachment = nil attachment_name = resume_name - attachment = resume.path() unless resume.nil? + attachment = resume.path unless resume.nil? htmlbody = " Thank you for registering in the New Orleans job system. @@ -258,7 +258,7 @@ def send_job_email(params, resume_name = nil, resume = nil)
    Which neighborhood: #{params['neighborhood']}

    Are you a young adult? #{params['young_adult']}

    Are you a veteran? #{params['veteran']}
    -
    Do you have little access to transportation? +
    Do you have little access to transportation? #{params['no_transportation']}

    Are you homeless or staying with someone temporarily? #{params['homeless']}
    @@ -272,7 +272,6 @@ def send_job_email(params, resume_name = nil, resume = nil)
    I am using drugs and want to get help. #{params['using_drugs']}

    None of the above. #{params['none']}
    " - # The email body for recipients with non-HTML email clients. textbody = "Thank you for registering in the New Orleans job system. We are evaluating which opportunity center can best meet your @@ -281,20 +280,15 @@ def send_job_email(params, resume_name = nil, resume = nil) emailer = EmailProvider.emailer owner = EmailProvider.owner sender = EmailProvider.sender - #puts self.emailer.inspect - # TODO: wire up oppcenter function param - # TODO: get city manager email - # city_manager_email = 'placeholder@mail.com' - # TODO: get opportunity center email based on function param + # puts self.emailer.inspect recipients = [] recipients.push owner recipients.push params['email_submission'] if params['email_submission'] != '' recipients.push params['job1'] if params['job1'] recipients.push params['goodwill'] if params['goodwill'] recipients.push params['tca'] if params['tca'] - # recipients.push opp_center_email - emailer.send_email(recipients, sender, subject, textbody, htmlbody, - attachment_name, attachment) + emailer.send_email(recipients, sender, subject, textbody, htmlbody, + attachment_name, attachment) end end -end \ No newline at end of file +end diff --git a/awsemailer.rb b/awsemailer.rb index 4842420..e520122 100644 --- a/awsemailer.rb +++ b/awsemailer.rb @@ -6,33 +6,28 @@ module WorkForwardNola # Class for sending out emails through AWS class AwsEmailer < Emailer - Dotenv.load def initialize(access, secret) - begin - Aws.config.update(credentials: Aws::Credentials.new(access, secret), region: 'us-east-1') - @ses = Aws::SES::Client.new - rescue Aws::SES::Errors::ServiceError => error - throw Aws::SES::Errors::ServiceError.new("Error configuring AWS SES client. Error message: #{error}") - end + Aws.config.update(credentials: Aws::Credentials.new(access, secret), region: 'us-east-1') + @ses = Aws::SES::Client.new + rescue Aws::SES::Errors::ServiceError => error + throw Aws::SES::Errors::ServiceError.new("Error configuring AWS SES client. Error message: #{error}") end - def send_email(recipients, sender, subject, text_body, html_body, - attachment_name = nil, attachment_file = nil) - if recipients == nil - recipients = cc - end + def send_email(recipients, sender, subject, text_body, html_body, + attachment_name = nil, attachment_file = nil) + recipients = cc if recipients.nil? msg_mixed = MIME::Multipart::Mixed.new unless attachment_file.nil? - attachment = MIME::Application.new(Base64::encode64(open(attachment_file,"rb").read)) + attachment = MIME::Application.new(Base64.encode64(open(attachment_file, 'rb').read)) attachment.transfer_encoding = 'base64' attachment.disposition = 'attachment' msg_mixed.attach(attachment, 'filename' => attachment_name) end msg_body = MIME::Multipart::Alternative.new - msg_body.add(MIME::Text.new(text_body,'plain')) - msg_body.add(MIME::Text.new(html_body,'html')) + msg_body.add(MIME::Text.new(text_body, 'plain')) + msg_body.add(MIME::Text.new(html_body, 'html')) msg_mixed.add(msg_body) msg = MIME::Mail.new(msg_mixed) msg.subject = subject @@ -49,39 +44,14 @@ def send_email(recipients, sender, subject, text_body, html_body, # Provide the contents of the email. - resp = @ses.send_raw_email({ + resp = @ses.send_raw_email( source: sender, destinations: recipients, raw_message: { - data: msg.to_s + data: msg.to_s } - }) - #msg.headers.set('X-SES-CONFIGURATION-SET',configsetname) -=begin - email_config_data = { - destination: { to_addresses: [recipient, cc, bcc] }, - message: { - subject: { charset: encoding, data: subject }, - body: { - html: { charset: encoding, data: html_body }, - text: { charset: encoding, data: text_body } - } - }, - source: sender - } -=end - # Email validation? - # if not cc.nil? - # email_config_data[:destination][:cc_addresses] = as_email_array(cc) - # end - # if not bcc.nil? - # email_config_data[:destination][:bcc_addresses] = as_email_array(bcc) - # end - # if not reply_to.nil? - # email_config_data[:reply_to] = reply_to - # not sure about the key on this one. - # end - #resp = @ses.send_email(email_config_data) + ) + puts "Email sent to #{recipients.inspect}: #{resp.inspect}" rescue Aws::SES::Errors::ServiceError => error # If something goes wrong, display an error message. @@ -100,10 +70,10 @@ def check_emails(emails) @ses.verify_email_identity email_address: emails end end - + def as_email_array(emails) return emails if emails.respond_to? :each [emails] end end -end \ No newline at end of file +end diff --git a/emailer.rb b/emailer.rb index 38e8df1..29dee6d 100644 --- a/emailer.rb +++ b/emailer.rb @@ -4,11 +4,10 @@ module WorkForwardNola # Abstract class for emailing systems class Emailer - def initialize - end - + def initialize; end + def send_email - throw Error("Emailer is an abstract class. Please use an implementation class.") + throw Error('Emailer is an abstract class. Please use an implementation class.') end end end diff --git a/emailprovider.rb b/emailprovider.rb index 8f64bcf..11f0d57 100644 --- a/emailprovider.rb +++ b/emailprovider.rb @@ -1,21 +1,21 @@ require './awsemailer.rb' module WorkForwardNola - # Sets up AWS SES variables through the environment file - class EmailProvider - @@emailer = AwsEmailer.new ENV['AWS_ACCESS'], ENV['AWS_SECRET'] - @@ownerEmail = ENV['OWNER_EMAIL'] - @@senderEmail = ENV['SENDER_EMAIL'] + # Sets up AWS SES variables through the environment file + class EmailProvider + @@emailer = AwsEmailer.new ENV['AWS_ACCESS'], ENV['AWS_SECRET'] + @@owner_email = ENV['OWNER_EMAIL'] + @@sender_email = ENV['SENDER_EMAIL'] - def self.emailer - @@emailer - end - - def self.sender - @@senderEmail - end + def self.emailer + @@emailer + end + + def self.sender + @@sender_email + end - def self.owner - @@ownerEmail - end + def self.owner + @@owner_email end + end end From dd370666be4f64eb783a1f089034c422a64060c1 Mon Sep 17 00:00:00 2001 From: "Ryan B. Harvey" Date: Wed, 16 May 2018 23:55:06 -0500 Subject: [PATCH 13/14] Add default Rake task and .travis.yml file so Travis CI stops complaining. --- .travis.yml | 3 +++ Rakefile | 3 +++ 2 files changed, 6 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..881c9ba --- /dev/null +++ b/.travis.yml @@ -0,0 +1,3 @@ +language: ruby +rvm: + - 2.2.5 \ No newline at end of file diff --git a/Rakefile b/Rakefile index 51febe9..3a67298 100644 --- a/Rakefile +++ b/Rakefile @@ -45,4 +45,7 @@ namespace :db do desc 'Migrate & seed DB all in one' task :setup => [:migrate, :seed] + + desc 'Default task: setup' + task :default => [:setup] end From 9a1bae7c15c4423ccf042e46d60d41d55639f903 Mon Sep 17 00:00:00 2001 From: Todd Loupe Date: Thu, 17 May 2018 05:22:22 +0000 Subject: [PATCH 14/14] Fixed careers -> job system button --- templates/careers.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/careers.mustache b/templates/careers.mustache index 136c8cc..9fdfaf3 100644 --- a/templates/careers.mustache +++ b/templates/careers.mustache @@ -42,7 +42,7 @@

    Sign up for the Opportunity Center job system and receive a personalized recommendation for next steps and a follow-up from a career advisor.

    Find information on certification and training programs