157 lines
4.7 KiB
Ruby
157 lines
4.7 KiB
Ruby
module JamRuby
|
|
class EmailBatchScheduledSessions < EmailBatchPeriodic
|
|
|
|
BATCH_SIZE = 500
|
|
SINCE_DAYS = 2
|
|
MIN_HOURS_START = 2
|
|
|
|
TMP_SESS = 'tmp_candidate_sessions'
|
|
TMP_RECIP = 'tmp_candidate_recipients'
|
|
TMP_MATCH = 'tmp_matches'
|
|
|
|
def self.subject
|
|
"New sessions have been scheduled that may be a good match for you!"
|
|
end
|
|
|
|
# inserts eligible sessions to temp table
|
|
def _collect_eligible_sessions
|
|
ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS #{TMP_SESS}")
|
|
sql =<<SQL
|
|
SELECT
|
|
msess.id AS session_id,
|
|
msess.user_id AS creator_id,
|
|
users.last_jam_locidispid AS creator_score_idx,
|
|
rs.instrument_id
|
|
INTO TEMP TABLE #{TMP_SESS}
|
|
FROM music_sessions msess
|
|
INNER JOIN users ON users.id = msess.user_id
|
|
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
|
|
WHERE
|
|
musician_access = 't' AND
|
|
approval_required = 'f' AND
|
|
msess.created_at > '#{time_since_last_batch(SINCE_DAYS)}' AND
|
|
msess.created_at < '#{self.created_at}' 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 _collect_eligible_recipients
|
|
ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS #{TMP_RECIP}")
|
|
# load eligible recipients into tmp table
|
|
sql =<<SQL
|
|
SELECT
|
|
users.id AS receiver_id,
|
|
users.last_jam_locidispid AS receiver_score_idx
|
|
INTO TEMP TABLE #{TMP_RECIP}
|
|
FROM users
|
|
INNER JOIN musicians_instruments AS mi ON mi.user_id = users.id
|
|
JOIN #{TMP_SESS} ON #{TMP_SESS}.instrument_id = mi.instrument_id
|
|
WHERE
|
|
users.musician = 't' AND
|
|
users.subscribe_email = 't'
|
|
SQL
|
|
ActiveRecord::Base.connection.execute(sql)
|
|
end
|
|
|
|
def _collect_scored_recipients
|
|
ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS #{TMP_MATCH}")
|
|
sql =<<SQL
|
|
SELECT
|
|
DISTINCT #{TMP_RECIP}.receiver_id,
|
|
#{TMP_SESS}.session_id,
|
|
scores.score AS latency
|
|
INTO TEMP TABLE #{TMP_MATCH}
|
|
FROM scores
|
|
INNER JOIN #{TMP_SESS} ON #{TMP_SESS}.creator_score_idx = scores.alocidispid
|
|
INNER JOIN #{TMP_RECIP} ON #{TMP_RECIP}.receiver_score_idx = scores.blocidispid
|
|
WHERE
|
|
scores.score < #{Score::MAX_YELLOW_LATENCY} AND
|
|
#{TMP_RECIP}.receiver_id != #{TMP_SESS}.creator_id
|
|
GROUP BY
|
|
#{TMP_RECIP}.receiver_id,
|
|
#{TMP_SESS}.session_id,
|
|
latency
|
|
SQL
|
|
ActiveRecord::Base.connection.execute(sql)
|
|
end
|
|
|
|
# select recipients whose score is below minimum threshold
|
|
def _select_scored_recipients(offset=0)
|
|
if 0 > offset
|
|
sql =<<SQL
|
|
SELECT DISTINCT COUNT(receiver_id) AS num
|
|
FROM #{TMP_MATCH}
|
|
GROUP BY receiver_id
|
|
SQL
|
|
rr = ActiveRecord::Base.connection.execute(sql)
|
|
return 0 < rr.count ? rr[0]['num'].to_i : 0
|
|
else
|
|
sql =<<SQL
|
|
SELECT DISTINCT receiver_id
|
|
FROM #{TMP_MATCH}
|
|
GROUP BY receiver_id
|
|
ORDER BY receiver_id ASC
|
|
LIMIT #{@per_page}
|
|
OFFSET #{offset}
|
|
SQL
|
|
return ActiveRecord::Base.connection.execute(sql)
|
|
end
|
|
end
|
|
|
|
def fetch_recipients(per_page=500)
|
|
objs = []
|
|
|
|
# load eligible sessions into tmp table
|
|
self._collect_eligible_sessions
|
|
|
|
# load eligible mail recipients into tmp table
|
|
self._collect_eligible_recipients
|
|
|
|
# load mail recipients with minimum score into tmp table
|
|
self._collect_scored_recipients
|
|
|
|
@per_page = per_page
|
|
num_recip = _select_scored_recipients(-1)
|
|
loops = (num_recip / @per_page) + (num_recip % @per_page) - 1
|
|
|
|
0.upto(loops) do |nn|
|
|
offset = nn * @per_page
|
|
# now just get the sessions/latency for each distinct mail recipient
|
|
_select_scored_recipients(offset).each do |result|
|
|
receiver = User.find_by_id(result['receiver_id'])
|
|
sessions = MusicSession.select("music_sessions.*, #{TMP_MATCH}.latency")
|
|
.joins("INNER JOIN #{TMP_MATCH} ON #{TMP_MATCH}.session_id = music_sessions.id")
|
|
.where(["#{TMP_MATCH}.receiver_id = ?", receiver.id])
|
|
.includes([:genre, :creator])
|
|
block_given? ? yield(receiver, sessions) : objs << [receiver, sessions]
|
|
end
|
|
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
|