mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-23 23:58:02 -05:00
Basic email structure plus distributed locking system
This commit is contained in:
parent
d22e8dbde1
commit
013ace65f6
10 changed files with 128 additions and 1 deletions
16
app/schemas/models/mail_sent.coffee
Normal file
16
app/schemas/models/mail_sent.coffee
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
c = require './../schemas'
|
||||||
|
#This will represent transactional emails which have been sent
|
||||||
|
|
||||||
|
MailSentSchema = c.object {
|
||||||
|
title: 'Sent mail'
|
||||||
|
description: 'Emails which have been sent through the system'
|
||||||
|
}
|
||||||
|
_.extend MailSentSchema.properties,
|
||||||
|
mailTask: c.objectId {}
|
||||||
|
user: c.objectId links: [{rel: 'extra', href: '/db/user/{($)}'}]
|
||||||
|
sent: c.date title: 'Sent', readOnly: true
|
||||||
|
|
||||||
|
c.extendBasicProperties MailSentSchema, 'mail.sent'
|
||||||
|
|
||||||
|
module.exports = MailSentSchema
|
||||||
|
|
21
app/schemas/models/mail_task.coffee
Normal file
21
app/schemas/models/mail_task.coffee
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
c = require './../schemas'
|
||||||
|
#This will represent transactional emails which have been sent
|
||||||
|
|
||||||
|
MailTaskSchema = c.object {
|
||||||
|
title: 'Mail task'
|
||||||
|
description: 'Mail tasks to call at certain intervals'
|
||||||
|
}
|
||||||
|
_.extend MailTaskSchema.properties,
|
||||||
|
url:
|
||||||
|
title: 'URL'
|
||||||
|
description: 'The associated URL of the mailtask to call'
|
||||||
|
type: 'string'
|
||||||
|
frequency:
|
||||||
|
title: 'Frequency'
|
||||||
|
description: 'The number of seconds the servers should check whether or not to send the email'
|
||||||
|
type: 'integer'
|
||||||
|
|
||||||
|
c.extendBasicProperties MailTaskSchema, 'mail.task'
|
||||||
|
|
||||||
|
module.exports = MailTaskSchema
|
||||||
|
|
24
server/commons/LockManager.coffee
Normal file
24
server/commons/LockManager.coffee
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
config = require '../../server_config'
|
||||||
|
redis = require 'redis'
|
||||||
|
class LockManager
|
||||||
|
constructor: ->
|
||||||
|
unless config.isProduction or config.redis.host isnt "localhost"
|
||||||
|
throw "You shouldn't be instantiating distributed locks unless in production."
|
||||||
|
@redisClient = redis.createClient config.redis.port, config.redis.host
|
||||||
|
@lockValues = {}
|
||||||
|
@unlockScript = "if redis.call(\"get\",KEYS[1]) == ARGV[1] then return redis.call(\"del\",KEYS[1]) else return 0 end"
|
||||||
|
|
||||||
|
setLock: (lockName, timeoutMs, cb) =>
|
||||||
|
randomNumber = Math.floor(Math.random() * 1000000000)
|
||||||
|
@redisClient.set [lockName,randomNumber, "NX", "PX", timeoutMs], (err, res) ->
|
||||||
|
if err? then return cb err, null
|
||||||
|
@lockValues[lockName] = randomNumber
|
||||||
|
cb null, res
|
||||||
|
|
||||||
|
releaseLock: (lockName, cb) =>
|
||||||
|
@redisClient.eval [@unlockScript, 1, lockName, @lockValues[lockName]], (err, res) ->
|
||||||
|
if err? then return cb err, null
|
||||||
|
#1 represents success, 0 failure
|
||||||
|
cb null, Boolean(Number(res))
|
||||||
|
|
||||||
|
module.exports = new RedisLock()
|
|
@ -9,6 +9,8 @@ module.exports.handlers =
|
||||||
'thang_type': 'levels/thangs/thang_type_handler'
|
'thang_type': 'levels/thangs/thang_type_handler'
|
||||||
'user': 'users/user_handler'
|
'user': 'users/user_handler'
|
||||||
'user_remark': 'users/remarks/user_remark_handler'
|
'user_remark': 'users/remarks/user_remark_handler'
|
||||||
|
'mail_task': 'mail/tasks/mail_task_handler'
|
||||||
|
'mail_sent': 'mail/sent/mail_sent_handler'
|
||||||
'achievement': 'achievements/achievement_handler'
|
'achievement': 'achievements/achievement_handler'
|
||||||
'earned_achievement': 'achievements/earned_achievement_handler'
|
'earned_achievement': 'achievements/earned_achievement_handler'
|
||||||
|
|
||||||
|
|
11
server/mail/sent/MailSent.coffee
Normal file
11
server/mail/sent/MailSent.coffee
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
mongoose = require 'mongoose'
|
||||||
|
plugins = require '../../plugins/plugins'
|
||||||
|
jsonschema = require '../../../app/schemas/models/mail_sent'
|
||||||
|
|
||||||
|
MailSent = new mongoose.Schema({
|
||||||
|
sent:
|
||||||
|
type: Date
|
||||||
|
'default': Date.now
|
||||||
|
}, {strict: false})
|
||||||
|
|
||||||
|
module.exports = MailSent = mongoose.model('mailSent', MailSent)
|
12
server/mail/sent/mail_sent_handler.coffee
Normal file
12
server/mail/sent/mail_sent_handler.coffee
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
MailSent = require './MailSent'
|
||||||
|
Handler = require '../../commons/Handler'
|
||||||
|
|
||||||
|
class MailSentHandler extends Handler
|
||||||
|
modelClass: MailSent
|
||||||
|
editableProperties: ['mailTask','user','sent']
|
||||||
|
jsonSchema: require '../../../app/schemas/models/mail_sent'
|
||||||
|
|
||||||
|
hasAccess: (req) ->
|
||||||
|
req.user?.isAdmin()
|
||||||
|
|
||||||
|
module.exports = new MailSentHandler()
|
7
server/mail/tasks/MailTask.coffee
Normal file
7
server/mail/tasks/MailTask.coffee
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
mongoose = require 'mongoose'
|
||||||
|
plugins = require '../../plugins/plugins'
|
||||||
|
jsonschema = require '../../../app/schemas/models/mail_task'
|
||||||
|
|
||||||
|
MailTaskSchema = new mongoose.Schema({}, {strict: false})
|
||||||
|
|
||||||
|
module.exports = MailTask = mongoose.model('mail.task', MailTaskSchema)
|
12
server/mail/tasks/mail_task_handler.coffee
Normal file
12
server/mail/tasks/mail_task_handler.coffee
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
MailTask = require './MailTask'
|
||||||
|
Handler = require '../../commons/Handler'
|
||||||
|
|
||||||
|
class MailTaskHandler extends Handler
|
||||||
|
modelClass: MailTask
|
||||||
|
editableProperties: ['url','frequency']
|
||||||
|
jsonSchema: require '../../../app/schemas/models/mail_task'
|
||||||
|
|
||||||
|
hasAccess: (req) ->
|
||||||
|
req.user?.isAdmin()
|
||||||
|
|
||||||
|
module.exports = new MailTaskHandler()
|
|
@ -1,4 +1,5 @@
|
||||||
mail = require '../commons/mail'
|
mail = require '../commons/mail'
|
||||||
|
MailTask = require '../mail/tasks/MailTask'
|
||||||
User = require '../users/User'
|
User = require '../users/User'
|
||||||
errors = require '../commons/errors'
|
errors = require '../commons/errors'
|
||||||
config = require '../../server_config'
|
config = require '../../server_config'
|
||||||
|
@ -6,11 +7,16 @@ LevelSession = require '../levels/sessions/LevelSession'
|
||||||
Level = require '../levels/Level'
|
Level = require '../levels/Level'
|
||||||
log = require 'winston'
|
log = require 'winston'
|
||||||
sendwithus = require '../sendwithus'
|
sendwithus = require '../sendwithus'
|
||||||
|
if config.isProduction || true
|
||||||
|
redis = require 'redis'
|
||||||
|
redisClient = redis.createClient(config.redis.port,config.redis.host)
|
||||||
|
|
||||||
module.exports.setup = (app) ->
|
module.exports.setup = (app) ->
|
||||||
app.all config.mail.mailchimpWebhook, handleMailchimpWebHook
|
app.all config.mail.mailchimpWebhook, handleMailchimpWebHook
|
||||||
app.get '/mail/cron/ladder-update', handleLadderUpdate
|
app.get '/mail/cron/ladder-update', handleLadderUpdate
|
||||||
|
app.post '/mail/task', createMailTask
|
||||||
|
|
||||||
|
#setInterval(handleScheduledMail, 5000)
|
||||||
|
|
||||||
|
|
||||||
DEBUGGING = false
|
DEBUGGING = false
|
||||||
|
@ -28,6 +34,18 @@ isRequestFromDesignatedCronHandler = (req, res) ->
|
||||||
return false
|
return false
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
createMailTask = (req, res) ->
|
||||||
|
#unless req.user?.isAdmin() then return errors.forbidden(res)
|
||||||
|
unless req.body.url and req.body.frequency then return errors.badInput(res)
|
||||||
|
console.log "Creating mail task with url #{req.body.url} and frequency #{req.body.frequency}"
|
||||||
|
newMailTask = new MailTask {}
|
||||||
|
newMailTask.set("url",req.body.url)
|
||||||
|
newMailTask.set("frequency",req.body.frequency)
|
||||||
|
newMailTask.save (err) ->
|
||||||
|
if err? then return errors.serverError(res, err)
|
||||||
|
res.send("Created mail task!")
|
||||||
|
res.end()
|
||||||
|
|
||||||
handleLadderUpdate = (req, res) ->
|
handleLadderUpdate = (req, res) ->
|
||||||
log.info('Going to see about sending ladder update emails.')
|
log.info('Going to see about sending ladder update emails.')
|
||||||
requestIsFromDesignatedCronHandler = isRequestFromDesignatedCronHandler req, res
|
requestIsFromDesignatedCronHandler = isRequestFromDesignatedCronHandler req, res
|
||||||
|
|
|
@ -12,6 +12,10 @@ config.mongo =
|
||||||
host: process.env.COCO_MONGO_HOST or 'localhost'
|
host: process.env.COCO_MONGO_HOST or 'localhost'
|
||||||
db: process.env.COCO_MONGO_DATABASE_NAME or 'coco'
|
db: process.env.COCO_MONGO_DATABASE_NAME or 'coco'
|
||||||
mongoose_replica_string: process.env.COCO_MONGO_MONGOOSE_REPLICA_STRING or ''
|
mongoose_replica_string: process.env.COCO_MONGO_MONGOOSE_REPLICA_STRING or ''
|
||||||
|
|
||||||
|
config.redis =
|
||||||
|
port: process.env.COCO_REDIS_PORT or 6379
|
||||||
|
host: process.env.COCO_REDIS_HOST or 'localhost'
|
||||||
|
|
||||||
if config.unittest
|
if config.unittest
|
||||||
config.port += 1
|
config.port += 1
|
||||||
|
|
Loading…
Reference in a new issue