mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-23 15:48:11 -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'
|
||||
'user': 'users/user_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'
|
||||
'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'
|
||||
MailTask = require '../mail/tasks/MailTask'
|
||||
User = require '../users/User'
|
||||
errors = require '../commons/errors'
|
||||
config = require '../../server_config'
|
||||
|
@ -6,11 +7,16 @@ LevelSession = require '../levels/sessions/LevelSession'
|
|||
Level = require '../levels/Level'
|
||||
log = require 'winston'
|
||||
sendwithus = require '../sendwithus'
|
||||
|
||||
if config.isProduction || true
|
||||
redis = require 'redis'
|
||||
redisClient = redis.createClient(config.redis.port,config.redis.host)
|
||||
|
||||
module.exports.setup = (app) ->
|
||||
app.all config.mail.mailchimpWebhook, handleMailchimpWebHook
|
||||
app.get '/mail/cron/ladder-update', handleLadderUpdate
|
||||
app.post '/mail/task', createMailTask
|
||||
|
||||
#setInterval(handleScheduledMail, 5000)
|
||||
|
||||
|
||||
DEBUGGING = false
|
||||
|
@ -28,6 +34,18 @@ isRequestFromDesignatedCronHandler = (req, res) ->
|
|||
return false
|
||||
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) ->
|
||||
log.info('Going to see about sending ladder update emails.')
|
||||
requestIsFromDesignatedCronHandler = isRequestFromDesignatedCronHandler req, res
|
||||
|
|
|
@ -12,6 +12,10 @@ config.mongo =
|
|||
host: process.env.COCO_MONGO_HOST or 'localhost'
|
||||
db: process.env.COCO_MONGO_DATABASE_NAME or 'coco'
|
||||
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
|
||||
config.port += 1
|
||||
|
|
Loading…
Reference in a new issue