Merge branch 'feature/scheduled_sessions' of bitbucket.org:jamkazam/jam-cloud into feature/scheduled_sessions
This commit is contained in:
commit
5b438ffaef
|
|
@ -43,6 +43,7 @@ require "jam_ruby/resque/scheduled/icecast_source_check"
|
|||
require "jam_ruby/resque/scheduled/cleanup_facebook_signup"
|
||||
require "jam_ruby/resque/scheduled/unused_music_notation_cleaner"
|
||||
require "jam_ruby/resque/scheduled/user_progress_emailer"
|
||||
require "jam_ruby/resque/scheduled/daily_session_emailer"
|
||||
require "jam_ruby/resque/google_analytics_event"
|
||||
require "jam_ruby/mq_router"
|
||||
require "jam_ruby/base_manager"
|
||||
|
|
@ -149,6 +150,7 @@ require "jam_ruby/models/email_batch"
|
|||
require "jam_ruby/models/email_batch_periodic"
|
||||
require "jam_ruby/models/email_batch_new_musician"
|
||||
require "jam_ruby/models/email_batch_progression"
|
||||
require "jam_ruby/models/email_batch_scheduled_sessions"
|
||||
require "jam_ruby/models/email_batch_set"
|
||||
require "jam_ruby/models/email_error"
|
||||
require "jam_ruby/app/mailers/async_mailer"
|
||||
|
|
|
|||
|
|
@ -391,6 +391,24 @@
|
|||
end
|
||||
end
|
||||
|
||||
def scheduled_session_daily(receiver, sessions_and_latency)
|
||||
sendgrid_category "Notification"
|
||||
sendgrid_unique_args :type => "scheduled_session_daily"
|
||||
|
||||
sendgrid_recipients([receiver.email])
|
||||
sendgrid_substitute('@USERID', [receiver.id])
|
||||
|
||||
@user = receiver
|
||||
@sessions_and_latency = sessions_and_latency
|
||||
|
||||
@title = 'New Scheduled Sessions Matched to You'
|
||||
mail(:to => receiver.email,
|
||||
:subject => EmailBatchScheduledSessions.subject) do |format|
|
||||
format.text
|
||||
format.html
|
||||
end
|
||||
end
|
||||
|
||||
def band_session_join(email, msg, session_id)
|
||||
subject = "A band that you follow has joined a session"
|
||||
unique_args = {:type => "band_session_join"}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
<% provide(:title, @title) %>
|
||||
|
||||
<p>Hello <%= @user.first_name %> --
|
||||
</p>
|
||||
|
||||
<p>The following new sessions that that have been posted during the last 24 hours:
|
||||
</p>
|
||||
<ol>
|
||||
<li>Need someone who plays an instrument that you play</li>
|
||||
<li>Were posted by someone to whom you have either a good or medium latency connection</li>
|
||||
</ol>
|
||||
|
||||
<p>Take a look through these new sessions below, and just click the RSVP button on the far right side of the row for any session in which you'd like to play. This will let the session organizer know you're interested, and you'll be notified if the session organizer accepts your request to play in that session!
|
||||
</p>
|
||||
|
||||
<table style="margin-top:6px; width:98%; font-size:11px; color:#fff; background-color:#262626; border:solid 1px #4d4d4d;" cellspacing="0" cellpadding="0" border="0">
|
||||
<!-- header -->
|
||||
<tr>
|
||||
<th align="left" width="20%">GENRE</th>
|
||||
<th align="left" width="60%">DESCRIPTION</th>
|
||||
<th width="20%" style="text-align:center">LATENCY</th>
|
||||
</tr>
|
||||
<!-- session row goes here -->
|
||||
<% @sessions_and_latency.each do |sess| %>
|
||||
<tr>
|
||||
<td><%= sess.genre.description %></td>
|
||||
<td><%= sess.description %></td>
|
||||
<td style="text-align:center"><%= sess.latency_store %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
|
||||
<p>To see ALL the scheduled sessions that you might be interested in joining, view our Find Session page at: <a href="http://www.jamkazam.com/client#/findSession">http://www.jamkazam.com/client#/findSession</a>.
|
||||
</p>
|
||||
|
||||
<p>Best Regards,</p>
|
||||
|
||||
Team JamKazam
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<% provide(:title, @title) %>
|
||||
|
||||
Hello <%= @user.first_name %> --
|
||||
|
||||
The following new sessions that that have been posted during the last 24 hours:
|
||||
|
||||
1. Need someone who plays an instrument that you play
|
||||
2. Were posted by someone to whom you have either a good or medium latency connection
|
||||
|
||||
Take a look through these new sessions below, and just click the RSVP button on the far right side of the row for any session in which you'd like to play. This will let the session organizer know you're interested, and you'll be notified if the session organizer accepts your request to play in that session!
|
||||
|
||||
GENRE | DESCRIPTION | LATENCY
|
||||
<% @sessions_and_latency.each do |sess| %>
|
||||
<%= sess.genre.description %> | <%= sess.description %> | <%= sess.latency_store %>
|
||||
<% end %>
|
||||
|
||||
To see ALL the scheduled sessions that you might be interested in joining, view our Find Session page at: http://www.jamkazam.com/client#/findSession.
|
||||
|
||||
Best Regards,
|
||||
|
||||
Team JamKazam
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
module JamRuby
|
||||
class EmailBatchScheduledSessions < EmailBatchPeriodic
|
||||
|
||||
BATCH_SIZE = 500
|
||||
SINCE_DAYS = 2
|
||||
MIN_HOURS_START = 2
|
||||
|
||||
TMP_SNAP = 'scheduled_session_snapshot'
|
||||
TMP_USER = 'scheduled_session_user'
|
||||
|
||||
def self.subject
|
||||
"New sessions have been scheduled that may be a good match for you!"
|
||||
end
|
||||
|
||||
# def fetch_sessions
|
||||
# objs = []
|
||||
# MusicSession.open_sessions
|
||||
# .where(['created_at > ?', time_since_last_batch(SINCE_DAYS)])
|
||||
# .where(['scheduled_start >= ?', Time.now() + MIN_HOURS_START.hours])
|
||||
# .find_each do |ss|
|
||||
# block_given? ? yield(ss) : objs << ss
|
||||
# end
|
||||
# objs
|
||||
# end
|
||||
|
||||
# inserts eligible sessions to temp table
|
||||
def prep_tmp_table
|
||||
ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS #{TMP_SNAP}")
|
||||
sql =<<SQL
|
||||
SELECT
|
||||
rs.instrument_id AS instrument_id,
|
||||
msess.id AS session_id,
|
||||
msess.user_id AS creator_id,
|
||||
users.last_jam_locidispid AS creator_score_idx
|
||||
INTO TEMP TABLE #{TMP_SNAP}
|
||||
FROM music_sessions msess
|
||||
INNER JOIN rsvp_slots AS rs ON rs.music_session_id = msess.id
|
||||
LEFT JOIN rsvp_requests_rsvp_slots AS rrrs ON rrrs.rsvp_slot_id = rs.id
|
||||
INNER JOIN users ON users.id = msess.user_id
|
||||
WHERE
|
||||
musician_access = 't' AND
|
||||
approval_required = 'f' AND
|
||||
msess.created_at > '#{time_since_last_batch(SINCE_DAYS)}' AND
|
||||
scheduled_start >= '#{Time.now() + MIN_HOURS_START.hours}' AND
|
||||
(rrrs.rsvp_slot_id IS NULL OR rrrs.chosen != 't')
|
||||
SQL
|
||||
ActiveRecord::Base.connection.execute(sql)
|
||||
end
|
||||
|
||||
def fetch_recipients
|
||||
objs = []
|
||||
# load eligible sessions into tmp table
|
||||
self.prep_tmp_table
|
||||
ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS #{TMP_USER}")
|
||||
|
||||
# load eligible recipients into tmp table
|
||||
sql =<<SQL
|
||||
SELECT
|
||||
users.id AS user_id,
|
||||
users.last_jam_locidispid AS user_score_idx,
|
||||
tmp.session_id AS session_id,
|
||||
tmp.creator_id AS creator_id,
|
||||
tmp.creator_score_idx AS creator_score_idx
|
||||
INTO TEMP TABLE #{TMP_USER}
|
||||
FROM users
|
||||
INNER JOIN musicians_instruments AS mi ON mi.user_id = users.id
|
||||
LEFT JOIN #{TMP_SNAP} AS tmp ON tmp.instrument_id = mi.instrument_id
|
||||
WHERE
|
||||
users.musician = 't' AND
|
||||
users.subscribe_email = 't' AND
|
||||
tmp.session_id IS NOT NULL
|
||||
GROUP BY users.id, tmp.session_id, tmp.creator_id, tmp.creator_score_idx
|
||||
SQL
|
||||
ActiveRecord::Base.connection.execute(sql)
|
||||
|
||||
# select recipients whose score is below minimum threshold
|
||||
sql =<<SQL
|
||||
SELECT DISTINCT user_id, scores.score AS latency
|
||||
FROM #{TMP_USER}
|
||||
INNER JOIN scores ON scores.alocidispid = #{TMP_USER}.creator_score_idx AND scores.blocidispid = #{TMP_USER}.user_score_idx
|
||||
WHERE
|
||||
scores.score < #{Score::MAX_YELLOW_LATENCY}
|
||||
SQL
|
||||
results = ActiveRecord::Base.connection.execute(sql)
|
||||
|
||||
# now just get the sessions/latency for each distinct mail recipient
|
||||
results.each do |result|
|
||||
sql =<<SQL
|
||||
SELECT session_id
|
||||
FROM #{TMP_USER}
|
||||
WHERE
|
||||
user_id = '#{result['user_id']}'
|
||||
SQL
|
||||
user = User.find_by_id(result['user_id'])
|
||||
sessions = ActiveRecord::Base.connection.execute(sql).collect do |rr|
|
||||
msess = MusicSession.where(['id = ?',rr['session_id']])
|
||||
.limit(1)
|
||||
.includes([:genre, :creator])
|
||||
.first
|
||||
msess.latency_store = result['latency']
|
||||
msess
|
||||
end
|
||||
block_given? ? yield(user, sessions) : objs << [user, sessions]
|
||||
end
|
||||
objs
|
||||
end
|
||||
|
||||
def deliver_batch_sets!
|
||||
self.opt_in_count = 0
|
||||
sent = 0
|
||||
self.fetch_recipients do |receiver, sessions_and_latency|
|
||||
self.opt_in_count += 1
|
||||
sent += 1
|
||||
bset = EmailBatchSet.scheduled_session_set(self, receiver, sessions_and_latency)
|
||||
UserMailer.scheduled_session_daily(receiver, sessions_and_latency).deliver
|
||||
end
|
||||
self.sent_count = sent
|
||||
self.save
|
||||
self.did_batch_run!
|
||||
end
|
||||
|
||||
def self.send_daily_session_batch
|
||||
oo = self.create
|
||||
oo..deliver_batch
|
||||
oo
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -27,6 +27,17 @@ module JamRuby
|
|||
bset
|
||||
end
|
||||
|
||||
def self.scheduled_session_set(batch, receiver, sessions)
|
||||
bset = self.new
|
||||
bset.email_batch = batch
|
||||
bset.user = receiver
|
||||
bset.user_ids = sessions.map(&:id).join(',')
|
||||
bset.started_at = Time.now
|
||||
bset.batch_count = 1
|
||||
bset.save!
|
||||
bset
|
||||
end
|
||||
|
||||
def subject
|
||||
unless sub_type.blank?
|
||||
return EmailBatchProgression.subject(self.sub_type.to_sym)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ module JamRuby
|
|||
|
||||
attr_accessor :legal_terms, :recurring_mode, :language_description, :scheduled_start_time, :access_description
|
||||
|
||||
attr_accessor :latency_store
|
||||
|
||||
self.table_name = "music_sessions"
|
||||
|
||||
self.primary_key = 'id'
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ require 'ipaddr'
|
|||
module JamRuby
|
||||
class Score < ActiveRecord::Base
|
||||
|
||||
MAX_YELLOW_LATENCY = 40
|
||||
|
||||
self.table_name = 'scores'
|
||||
|
||||
attr_accessible :alocidispid, :anodeid, :aaddr, :blocidispid, :bnodeid, :baddr, :score, :score_dt, :scorer, :scoring_data
|
||||
|
|
@ -31,5 +33,6 @@ module JamRuby
|
|||
def self.score_conns(c1, c2, score)
|
||||
self.createx(c1.locidispid, c1.client_id, c1.addr, c2.locidispid, c2.client_id, c2.addr, score)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
module JamRuby
|
||||
class DailySessionEmailer
|
||||
extend Resque::Plugins::LonelyJob
|
||||
|
||||
@queue = :scheduled_daily_session_emailer
|
||||
@@log = Logging.logger[DailySessionEmailer]
|
||||
|
||||
def self.perform
|
||||
@@log.debug("waking up")
|
||||
EmailBatchScheduledSessions.send_daily_session_batch
|
||||
@@log.debug("done")
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -457,6 +457,9 @@ FactoryGirl.define do
|
|||
factory :email_batch_progression, :class => JamRuby::EmailBatchProgression do
|
||||
end
|
||||
|
||||
factory :email_batch_scheduled_session, :class => JamRuby::EmailBatchScheduledSessions do
|
||||
end
|
||||
|
||||
factory :notification, :class => JamRuby::Notification do
|
||||
|
||||
factory :notification_text_message do
|
||||
|
|
@ -474,7 +477,7 @@ FactoryGirl.define do
|
|||
factory :rsvp_slot, class: JamRuby::RsvpSlot do
|
||||
association :instrument, factory: :instrument
|
||||
association :music_session, factory: :music_session
|
||||
association :rsvp_request_slot, factory: :rsvp_request_slot
|
||||
# association :rsvp_request_slot, factory: :rsvp_request_slot
|
||||
proficiency_level 'beginner'
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,106 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe EmailBatch do
|
||||
|
||||
after(:each) do
|
||||
Timecop.return
|
||||
end
|
||||
|
||||
before(:each) do
|
||||
UserMailer.deliveries.clear
|
||||
end
|
||||
|
||||
describe 'daily scheduled' do
|
||||
# before { pending }
|
||||
|
||||
let (:scheduled_batch) { FactoryGirl.create(:email_batch_scheduled_session) }
|
||||
|
||||
let (:drums) { FactoryGirl.create(:instrument, :description => 'drums') }
|
||||
let (:guitar) { FactoryGirl.create(:instrument, :description => 'guitar') }
|
||||
let (:bass) { FactoryGirl.create(:instrument, :description => 'bass') }
|
||||
let (:vocals) { FactoryGirl.create(:instrument, :description => 'vocal') }
|
||||
|
||||
let (:drummer) { FactoryGirl.create(:user,
|
||||
:last_jam_locidispid => 1,
|
||||
:last_jam_addr => 1) }
|
||||
let (:guitarist) { FactoryGirl.create(:user,
|
||||
:last_jam_locidispid => 1,
|
||||
:last_jam_addr => 1) }
|
||||
let (:bassist) { FactoryGirl.create(:user,
|
||||
:last_jam_locidispid => 1,
|
||||
:last_jam_addr => 1) }
|
||||
let (:vocalist) { FactoryGirl.create(:user,
|
||||
:last_jam_locidispid => 1,
|
||||
:last_jam_addr => 1) }
|
||||
let (:loser) { FactoryGirl.create(:user,
|
||||
:last_jam_locidispid => 2,
|
||||
:last_jam_addr => 2) }
|
||||
|
||||
let (:session1) do
|
||||
FactoryGirl.create(:music_session,
|
||||
:creator => drummer,
|
||||
:scheduled_start => Time.now() + 2.days,
|
||||
:musician_access => true,
|
||||
:approval_required => false)
|
||||
end
|
||||
let (:session2) do
|
||||
FactoryGirl.create(:music_session,
|
||||
:creator => drummer,
|
||||
:scheduled_start => Time.now() + 2.days,
|
||||
:musician_access => true,
|
||||
:approval_required => false)
|
||||
end
|
||||
|
||||
before(:each) do
|
||||
MusicianInstrument.delete_all
|
||||
RsvpSlot.delete_all
|
||||
JamRuby::Score.delete_all
|
||||
|
||||
drummer.musician_instruments << FactoryGirl.build(:musician_instrument, user: drummer, instrument: drums, proficiency_level: 2)
|
||||
drummer.musician_instruments << FactoryGirl.build(:musician_instrument, user: drummer, instrument: guitar, proficiency_level: 2)
|
||||
|
||||
guitarist.musician_instruments << FactoryGirl.build(:musician_instrument, user: guitarist, instrument: guitar, proficiency_level: 2)
|
||||
guitarist.musician_instruments << FactoryGirl.build(:musician_instrument, user: guitarist, instrument: bass, proficiency_level: 2)
|
||||
|
||||
bassist.musician_instruments << FactoryGirl.build(:musician_instrument, user: bassist, instrument: bass, proficiency_level: 2)
|
||||
bassist.musician_instruments << FactoryGirl.build(:musician_instrument, user: bassist, instrument: guitar, proficiency_level: 2)
|
||||
|
||||
vocalist.musician_instruments << FactoryGirl.build(:musician_instrument, user: vocalist, instrument: vocals, proficiency_level: 2)
|
||||
|
||||
loser.musician_instruments << FactoryGirl.build(:musician_instrument, user: loser, instrument: vocals, proficiency_level: 2)
|
||||
loser.musician_instruments << FactoryGirl.build(:musician_instrument, user: loser, instrument: drums, proficiency_level: 2)
|
||||
|
||||
FactoryGirl.create(:rsvp_slot, :instrument => drums, :music_session => session1)
|
||||
FactoryGirl.create(:rsvp_slot, :instrument => guitar, :music_session => session1)
|
||||
FactoryGirl.create(:rsvp_slot, :instrument => bass, :music_session => session1)
|
||||
|
||||
FactoryGirl.create(:rsvp_slot, :instrument => drums, :music_session => session2)
|
||||
FactoryGirl.create(:rsvp_slot, :instrument => guitar, :music_session => session2)
|
||||
FactoryGirl.create(:rsvp_slot, :instrument => bass, :music_session => session2)
|
||||
# oo = FactoryGirl.create(:rsvp_slot, :instrument => vocals, :music_session => session1)
|
||||
# oo.rsvp_request_slot.update_attributes(chosen: true)
|
||||
# oo = FactoryGirl.create(:rsvp_request, :user => vocalist, :rsvp_slot => oo)
|
||||
# oo.rsvp_request_slot.update_attributes(chosen: true)
|
||||
|
||||
JamRuby::Score.createx(1, 'a', 1, 1, 'a', 1, 10)
|
||||
JamRuby::Score.createx(1, 'a', 1, 2, 'a', 2, Score::MAX_YELLOW_LATENCY + 1)
|
||||
end
|
||||
|
||||
before(:each) do
|
||||
end
|
||||
|
||||
it 'sets up data properly' do
|
||||
expect(drummer.instruments.include?(drums)).to eq(true)
|
||||
expect(drummer.instruments.include?(guitar)).to eq(true)
|
||||
obj = scheduled_batch.fetch_recipients
|
||||
expect(obj.count).to eq(3)
|
||||
end
|
||||
|
||||
it 'sends email' do
|
||||
ebatch = scheduled_batch
|
||||
ebatch.deliver_batch
|
||||
expect(UserMailer.deliveries.length).to eq(3)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -33,3 +33,8 @@ UserProgressEmailer:
|
|||
cron: "30 21 * * *"
|
||||
class: "JamRuby::UserProgressEmailer"
|
||||
description: "Sends periodic user progress emails"
|
||||
|
||||
DailySessionEmailer:
|
||||
cron: "0 6 * * *"
|
||||
class: "JamRuby::DailySessionEmailer"
|
||||
description: "Sends daily scheduled session emails"
|
||||
|
|
|
|||
Loading…
Reference in New Issue