Done? Needs tests.

pull/325/merge
Rick Carlino 2017-05-25 09:17:59 -05:00
parent cd57c3c9a2
commit 9dbc7f3223
12 changed files with 87 additions and 5 deletions

View File

@ -13,9 +13,13 @@ module Api
.select { |i| i.meta["type"] != "fun"} # Don't save jokes
.map { |i| i.as_json }
.tap { |i| Log.create(i) }
.tap { |i| maybe_deliver(i) }
when Hash
outcome = new_log(raw_json)
outcome.result.save if outcome.success?
if outcome.success?
outcome.result.save!
maybe_deliver(outcome.result)
end
return mutate outcome
else
sorry "Post a JSON array or object.", 422
@ -36,5 +40,9 @@ private
def new_log(input)
Logs::Create.run(input, device: current_device)
end
def maybe_deliver(log_or_logs)
LogDispatch.deliver(current_device, log_or_logs)
end
end
end

View File

@ -0,0 +1,14 @@
class LogDeliveryMailer < ApplicationMailer
def log_digest(device)
if LogDispatch.where(sent_at: 1.hours.ago..Time.now).count > 20
raise "Device #{device.id} is sending too many emails!!! (> 20 / hr)"
end
ld = LogDispatch.where(sent_at: nil, device: device)
logs = Log.find(ld.pluck(:log_id))
@emails = device.users.pluck(:email)
@messages = logs.map(&:message)
mail(to: @emails, subject: '🌱 New message from FarmBot!')
ld.update_all(sent_at: Time.now)
end
end

View File

@ -1,4 +1,16 @@
class LogDispatch < ApplicationRecord
belongs_to :device
belongs_to :log
# If this method grows, create a mutation.
def self.deliver(device, log_or_logs)
Array
.wrap(log_or_logs)
.select { |log | (log["channels"] || []).include?("email") }
.map { |log | { device: device, log: log }}
.tap { |logs| self.create!(logs) }
LogDeliveryMailer
.log_digest(device)
.deliver_later
end
end

View File

@ -0,0 +1 @@
<%= yield %>

View File

@ -0,0 +1,7 @@
Farmbot sent you an email.
Here's what your device had to say:
<% @messages.each do |msg| %>
* <%= msg %>
<% end %>

View File

@ -8,7 +8,6 @@ class CreateLogDispatches < ActiveRecord::Migration[5.1]
t.timestamps
end
add_index :log_dispatches, :device_id
add_index :log_dispatches, :sent_at
end
end

View File

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20170518182029) do
ActiveRecord::Schema.define(version: 20170525111655) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -66,6 +66,17 @@ ActiveRecord::Schema.define(version: 20170518182029) do
t.index ["device_id"], name: "index_images_on_device_id"
end
create_table "log_dispatches", force: :cascade do |t|
t.bigint "device_id"
t.bigint "log_id"
t.datetime "sent_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["device_id"], name: "index_log_dispatches_on_device_id"
t.index ["log_id"], name: "index_log_dispatches_on_log_id"
t.index ["sent_at"], name: "index_log_dispatches_on_sent_at"
end
create_table "logs", id: :serial, force: :cascade do |t|
t.text "message"
t.text "meta"
@ -189,6 +200,8 @@ ActiveRecord::Schema.define(version: 20170518182029) do
t.index ["email"], name: "index_users_on_email", unique: true
end
add_foreign_key "log_dispatches", "devices"
add_foreign_key "log_dispatches", "logs"
add_foreign_key "peripherals", "devices"
add_foreign_key "points", "devices"
add_foreign_key "sequence_dependencies", "sequences"

View File

@ -106,5 +106,24 @@ describe Api::LogsController do
expect(user.device.reload.logs.count).to be < before
expect(user.device.logs.count).to eq(0)
end
it 'delivers emails for logs marked as `email`' do
sign_in user
empty_mail_bag
before = LogDispatch.count
body = { meta: { x: 1, y: 2, z: 3, type: "info" },
channels: ["email"],
message: "one" }.to_json
before_count = Log.count
post :create, body: body, params: {format: :json}
after = LogDispatch.count
expect(response.status).to eq(200)
expect(last_email).to be
sleep 1
binding.pry
end
it "batches multiple messages"
it "throttles excess requests"
end
end

View File

@ -12,7 +12,7 @@ describe Api::PasswordResetsController do
post :create, params: params
expect(response.status).to eq(200)
expect(ActionMailer::Base.deliveries.length).to be > old_email_count
message = last_mail_delivery.to_s
message = last_email.to_s
expect(message).to include("password reset")
end

View File

@ -0,0 +1,5 @@
require "spec_helper"
RSpec.describe LogDeliveryMailer, type: :mailer do
pending "add some examples to (or delete) #{__FILE__}"
end

View File

@ -0,0 +1,4 @@
# Preview all emails at http://localhost:3000/rails/mailers/log_delivery
class LogDeliveryPreview < ActionMailer::Preview
end

View File

@ -11,7 +11,7 @@ module Helpers
MAGIC_NUMBER_TOOL_ID = "8888"
AST_FIXTURE = File.read("./spec/lib/celery_script/ast_fixture3.json")
def last_mail_delivery
def last_email
ActionMailer::Base.deliveries.last
end