From 7b1a523abae99a607ecda94df1e60664760445a6 Mon Sep 17 00:00:00 2001 From: Rafa de la Torre Date: Fri, 12 Sep 2014 16:50:50 +0200 Subject: [PATCH] CDB-3949 Send an email upon completion of import --- Makefile | 1 + app/mailers/user_mailer.rb | 8 ++ app/models/data_import.rb | 4 +- .../user_mailer/data_import_finished.html.erb | 28 +++++++ lib/resque/user_jobs.rb | 9 +++ .../importer/lib/importer/mail_notifier.rb | 46 +++++++++++ .../importer/spec/unit/mail_notifier_spec.rb | 76 +++++++++++++++++++ 7 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 app/views/user_mailer/data_import_finished.html.erb create mode 100644 services/importer/lib/importer/mail_notifier.rb create mode 100644 services/importer/spec/unit/mail_notifier_spec.rb diff --git a/Makefile b/Makefile index 821ee6f7f3..5b58898e13 100644 --- a/Makefile +++ b/Makefile @@ -40,6 +40,7 @@ WORKING_SPECS_5 = \ spec/requests/api/geocodings_spec.rb \ services/importer/spec/unit/url_translator/osm_spec.rb \ services/importer/spec/unit/url_translator/osm2_spec.rb \ + services/importer/spec/unit/mail_notifier_spec.rb \ services/relocator/spec/relocator_spec.rb \ $(NULL) diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 6922a5dfc7..3a233ac288 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -44,5 +44,13 @@ class UserMailer < ActionMailer::Base mail :to => @user.email, :subject => "#{@visualization_owner_name} has stopped sharing a CartoDB visualization with you" end + + def data_import_finished(user, imported_tables, total_tables) + @imported_tables = imported_tables + @total_tables = total_tables + @link = "#{user.public_url}#{tables_index_url(only_path:true)}" + mail :to => user.email, + :subject => "Table import finished" + end end diff --git a/app/models/data_import.rb b/app/models/data_import.rb index 0e8a92e663..8e13abeed8 100644 --- a/app/models/data_import.rb +++ b/app/models/data_import.rb @@ -1,4 +1,4 @@ -# encoding: UTF-8' +# encoding: UTF-8 require 'sequel' require 'fileutils' require 'uuidtools' @@ -16,6 +16,7 @@ require_relative '../connectors/importer' require_relative '../../services/importer/lib/importer/datasource_downloader' require_relative '../../services/datasources/lib/datasources' +require_relative '../../services/importer/lib/importer/mail_notifier' include CartoDB::Datasources class DataImport < Sequel::Model @@ -438,6 +439,7 @@ class DataImport < Sequel::Model } import_log.merge!(decorate_log(self)) dataimport_logger.info(import_log.to_json) + CartoDB::Importer2::MailNotifier.new(self, results, ::Resque).notify_if_needed results.each { |result| CartoDB::Metrics.new.report(:import, payload_for(result)) } end diff --git a/app/views/user_mailer/data_import_finished.html.erb b/app/views/user_mailer/data_import_finished.html.erb new file mode 100644 index 0000000000..9e2bc88106 --- /dev/null +++ b/app/views/user_mailer/data_import_finished.html.erb @@ -0,0 +1,28 @@ +<% content_for(:header_color) {"3B7EBB"} %> +<% content_for(:header_img) {"top.png"} %> + +<% content_for :body do %> + +

Your table import just finished.

+

<%= @imported_tables %> out of <%= @total_tables %> <%= @total_tables == 1? 'was' : 'were' %> successfully imported.

+ + + + + + + + +
+ + + + + + +
+ View your tables +
+
 
+ +<% end %> diff --git a/lib/resque/user_jobs.rb b/lib/resque/user_jobs.rb index f21a63f248..8f3c68d1e0 100644 --- a/lib/resque/user_jobs.rb +++ b/lib/resque/user_jobs.rb @@ -54,6 +54,15 @@ module Resque end end + module DataImportFinished + @queue = :users + + def self.perform(user_id, imported_tables, total_tables) + user = User.where(id: user_id).first + UserMailer.data_import_finished(user, imported_tables, total_tables).deliver + end + end + end end end diff --git a/services/importer/lib/importer/mail_notifier.rb b/services/importer/lib/importer/mail_notifier.rb new file mode 100644 index 0000000000..1da24d2fe8 --- /dev/null +++ b/services/importer/lib/importer/mail_notifier.rb @@ -0,0 +1,46 @@ +# encoding: UTF-8 + +require_relative '../../../../lib/resque/user_jobs' + +module CartoDB + module Importer2 + + class MailNotifier + + MIN_IMPORT_TIME_TO_NOTIFY = 5 * 60 # seconds + + def initialize(data_import, results, resque) + @data_import = data_import + @results = results + @resque = resque + @mail_sent = false + end + + def notify_if_needed + send! if should_notify? + end + + def should_notify? + import_time >= MIN_IMPORT_TIME_TO_NOTIFY && @data_import.synchronization_id.nil? + end + + def import_time + @data_import.updated_at - @data_import.created_at + end + + def send! + user_id = @data_import.user_id + imported_tables = @results.select {|r| r.success }.length + total_tables = @results.length + @mail_sent = @resque.enqueue(::Resque::UserJobs::Mail::DataImportFinished, user_id, imported_tables, total_tables) + end + + def mail_sent? + return @mail_sent + end + + end + + end #Importer2 +end #CartoDB + diff --git a/services/importer/spec/unit/mail_notifier_spec.rb b/services/importer/spec/unit/mail_notifier_spec.rb new file mode 100644 index 0000000000..d6f828db59 --- /dev/null +++ b/services/importer/spec/unit/mail_notifier_spec.rb @@ -0,0 +1,76 @@ +# encoding: UTF-8 + +require 'rspec' +require_relative '../../lib/importer/mail_notifier' +require 'ruby-debug' #TODO remove + +RSpec.configure do |config| + config.mock_with :mocha +end + +describe CartoDB::Importer2::MailNotifier do + + START_TIME = 0 + + before(:each) do + @data_import = mock + @resque = mock + @result = mock + results = [@result] + @mail_notifier = CartoDB::Importer2::MailNotifier.new(@data_import, results, @resque) + end + + def set_import_duration duration + @data_import.stubs(:created_at).once.returns(START_TIME) + @data_import.stubs(:updated_at).once.returns(START_TIME + duration) + end + + describe '#notify_if_needed' do + + it 'should send a mail if the import took more than MIN_IMPORT_TIME_TO_NOTIFY' do + @data_import.stubs(:synchronization_id).once.returns(nil) + set_import_duration(CartoDB::Importer2::MailNotifier::MIN_IMPORT_TIME_TO_NOTIFY + 1) + @data_import.stubs(:user_id).once.returns(:any_user_id) + @result.stubs(:success).once.returns(true) + @resque.expects(:enqueue).with(::Resque::UserJobs::Mail::DataImportFinished, :any_user_id, 1, 1).returns(true) + + @mail_notifier.notify_if_needed + + @mail_notifier.mail_sent?.should == true + end + end + + describe '#should_notify?' do + it 'should return true if the import took more than MIN_IMPORT_TIME_TO_NOTIFY and was not a sync' do + set_import_duration(CartoDB::Importer2::MailNotifier::MIN_IMPORT_TIME_TO_NOTIFY + 1) + @data_import.stubs(:synchronization_id).once.returns(nil) + + @mail_notifier.should_notify?.should == true + end + + it 'should return false if the import took less than MIN_IMPORT_TIME_TO_NOTIFY' do + set_import_duration(CartoDB::Importer2::MailNotifier::MIN_IMPORT_TIME_TO_NOTIFY - 1) + + @mail_notifier.should_notify?.should == false + end + + it 'should return false if it was a sync import' do + set_import_duration(CartoDB::Importer2::MailNotifier::MIN_IMPORT_TIME_TO_NOTIFY + 1) + ANY_SYNC_ID = 1 + @data_import.stubs(:synchronization_id).once.returns(ANY_SYNC_ID) + + @mail_notifier.should_notify?.should == false + end + end + + describe '#send!' do + it 'should inconditionally send a mail to the user who triggered the import' do + @data_import.stubs(:user_id).once.returns(:any_user_id) + @resque.expects(:enqueue).with(::Resque::UserJobs::Mail::DataImportFinished, :any_user_id, 1, 1).returns(true) + @result.stubs(:success).once.returns(true) + @mail_notifier.send! + @mail_notifier.mail_sent?.should == true + end + end + +end