2014-04-08 22:26:19 -04:00
|
|
|
mongoose = require('mongoose')
|
2014-06-27 15:30:31 -04:00
|
|
|
deltas = require '../../app/lib/deltas'
|
2014-04-08 22:26:19 -04:00
|
|
|
{handlers} = require '../commons/mapping'
|
|
|
|
|
2014-06-27 15:30:31 -04:00
|
|
|
PatchSchema = new mongoose.Schema({status: String}, {strict: false})
|
2014-04-08 22:26:19 -04:00
|
|
|
|
|
|
|
PatchSchema.pre 'save', (next) ->
|
|
|
|
return next() unless @isNew # patch can't be altered after creation, so only need to check data once
|
|
|
|
target = @get('target')
|
|
|
|
targetID = target.id
|
|
|
|
Handler = require '../commons/Handler'
|
|
|
|
if not Handler.isID(targetID)
|
|
|
|
err = new Error('Invalid input.')
|
2014-06-30 22:16:26 -04:00
|
|
|
err.response = {message: 'isn\'t a MongoDB id.', property: 'target.id'}
|
2014-04-08 22:26:19 -04:00
|
|
|
err.code = 422
|
|
|
|
return next(err)
|
2014-06-30 22:16:26 -04:00
|
|
|
|
2014-04-08 22:26:19 -04:00
|
|
|
collection = target.collection
|
|
|
|
handler = require('../' + handlers[collection])
|
|
|
|
handler.getDocumentForIdOrSlug targetID, (err, document) =>
|
|
|
|
if err
|
|
|
|
err = new Error('Server error.')
|
2014-06-30 22:16:26 -04:00
|
|
|
err.response = {message: '', property: 'target.id'}
|
2014-04-08 22:26:19 -04:00
|
|
|
err.code = 500
|
|
|
|
return next(err)
|
|
|
|
|
|
|
|
if not document
|
|
|
|
err = new Error('Target of patch not found.')
|
2014-06-30 22:16:26 -04:00
|
|
|
err.response = {message: 'was not found.', property: 'target.id'}
|
2014-04-08 22:26:19 -04:00
|
|
|
err.code = 404
|
|
|
|
return next(err)
|
|
|
|
|
|
|
|
target.id = document.get('_id')
|
|
|
|
if handler.modelClass.schema.uses_coco_versions
|
|
|
|
target.original = document.get('original')
|
|
|
|
version = document.get('version')
|
|
|
|
target.version = _.pick document.get('version'), 'major', 'minor'
|
|
|
|
@set('target', target)
|
|
|
|
else
|
|
|
|
target.original = targetID
|
2014-06-30 22:16:26 -04:00
|
|
|
|
2014-04-08 22:26:19 -04:00
|
|
|
patches = document.get('patches') or []
|
2014-04-17 18:44:19 -04:00
|
|
|
patches = _.clone patches
|
2014-04-08 22:26:19 -04:00
|
|
|
patches.push @_id
|
2014-04-17 18:44:19 -04:00
|
|
|
document.set 'patches', patches, {strict: false}
|
2014-04-17 20:09:01 -04:00
|
|
|
@targetLoaded = document
|
2014-04-08 22:26:19 -04:00
|
|
|
document.save (err) -> next(err)
|
|
|
|
|
2014-06-27 15:30:31 -04:00
|
|
|
PatchSchema.methods.isTranslationPatch = ->
|
2014-06-28 11:04:13 -04:00
|
|
|
expanded = deltas.flattenDelta @get('delta')
|
|
|
|
_.some expanded, (delta) -> 'i18n' in delta.dataPath
|
2014-06-27 15:30:31 -04:00
|
|
|
|
|
|
|
PatchSchema.methods.isMiscPatch = ->
|
2014-06-28 11:04:13 -04:00
|
|
|
expanded = deltas.flattenDelta @get('delta')
|
|
|
|
_.some expanded, (delta) -> 'i18n' not in delta.dataPath
|
2014-06-27 15:30:31 -04:00
|
|
|
|
2014-06-28 11:44:07 -04:00
|
|
|
# Keep track of when a patch is pending and newly approved.
|
2014-06-27 15:30:31 -04:00
|
|
|
PatchSchema.path('status').set (newVal) ->
|
|
|
|
@set '_wasPending', @status is 'pending' and newVal isnt 'pending'
|
2014-06-28 11:44:07 -04:00
|
|
|
@set '_newlyAccepted', newVal is 'accepted' and not @get('_newlyAccepted') # Only true on the first accept
|
2014-06-27 15:30:31 -04:00
|
|
|
newVal
|
|
|
|
|
2014-06-28 11:44:07 -04:00
|
|
|
PatchSchema.methods.isNewlyAccepted = -> @get('_newlyAccepted')
|
|
|
|
PatchSchema.methods.wasPending = -> @get '_wasPending'
|
|
|
|
|
2014-06-27 15:30:31 -04:00
|
|
|
PatchSchema.pre 'save', (next) ->
|
|
|
|
User = require '../users/User'
|
|
|
|
userID = @get('creator').toHexString()
|
|
|
|
|
|
|
|
if @get('status') is 'accepted'
|
|
|
|
User.incrementStat userID, 'stats.patchesContributed' # accepted patches
|
|
|
|
else if @get('status') is 'pending'
|
|
|
|
User.incrementStat userID, 'stats.patchesSubmitted' # submitted patches
|
|
|
|
|
|
|
|
next()
|
|
|
|
|
|
|
|
|
2014-04-08 22:26:19 -04:00
|
|
|
module.exports = mongoose.model('patch', PatchSchema)
|