2014-07-01 10:16:26 +08:00
mongoose = require ' mongoose '
jsonschema = require ' ../../app/schemas/models/achievement '
2014-05-21 19:47:17 +02:00
log = require ' winston '
2014-11-28 17:49:41 -08:00
utils = require ' ../../app/core/utils '
2014-06-09 17:28:35 +02:00
plugins = require ( ' ../plugins/plugins ' )
2014-06-13 18:04:25 +02:00
AchievablePlugin = require ' ../plugins/achievements '
2014-08-29 12:41:25 -07:00
TreemaUtils = require ' ../../bower_components/treema/treema-utils.js '
2015-03-21 21:49:32 -04:00
config = require ' ../../server_config '
2014-05-13 22:46:56 +02:00
# `pre` and `post` are not called for update operations executed directly on the database,
# including `Model.update`,`.findByIdAndUpdate`,`.findOneAndUpdate`, `.findOneAndRemove`,and `.findByIdAndRemove`.order
# to utilize `pre` or `post` middleware, you should `find()` the document, and call the `init`, `validate`, `save`,
# or `remove` functions on the document. See [explanation](http://github.com/LearnBoost/mongoose/issues/964).
AchievementSchema = new mongoose . Schema ( {
2014-05-21 19:47:17 +02:00
userField: String
2015-03-21 21:49:32 -04:00
} , { strict: false , read: config . mongo . readpref } )
2014-05-13 22:46:56 +02:00
2015-01-27 10:02:47 -08:00
AchievementSchema . index (
{
_fts: ' text '
_ftsx: 1
} ,
{
name: ' search index '
sparse: true
weights: { name: 1 }
default_language: ' english '
' language_override ' : ' language '
' textIndexVersion ' : 2
} )
AchievementSchema . index ( { i18nCoverage: 1 } , { name: ' translation coverage index ' , sparse: true } )
AchievementSchema . index ( { slug: 1 } , { name: ' slug index ' , sparse: true , unique: true } )
2015-12-03 11:15:34 -08:00
AchievementSchema . index ( { related: 1 } , { name: ' related index ' , sparse: true } )
2015-01-27 10:02:47 -08:00
2014-06-03 12:40:47 +02:00
AchievementSchema.methods.objectifyQuery = ->
2014-05-21 19:47:17 +02:00
try
2014-07-01 10:16:26 +08:00
@ set ( ' query ' , JSON . parse ( @ get ( ' query ' ) ) ) if typeof @ get ( ' query ' ) == ' string '
2014-05-21 19:47:17 +02:00
catch error
2014-05-24 20:45:53 +02:00
log . error " Couldn ' t convert query string to object because of #{ error } "
2014-05-21 19:47:17 +02:00
@ set ( ' query ' , { } )
2014-06-03 12:40:47 +02:00
AchievementSchema.methods.stringifyQuery = ->
2014-07-01 10:16:26 +08:00
@ set ( ' query ' , JSON . stringify ( @ get ( ' query ' ) ) ) if typeof @ get ( ' query ' ) != ' string '
2014-05-21 19:47:17 +02:00
2014-06-14 15:34:23 +02:00
AchievementSchema.methods.getExpFunction = ->
2014-08-29 12:41:25 -07:00
func = @ get ( ' function ' ) ? { }
TreemaUtils . populateDefaults ( func , jsonschema . properties . function )
return utils . functionCreators [ func . kind ] ( func . parameters ) if func . kind of utils . functionCreators
2014-06-03 12:40:47 +02:00
2014-06-14 20:12:17 +02:00
AchievementSchema.statics.jsonschema = jsonschema
2015-02-13 17:10:30 -08:00
AchievementSchema.statics.achievementCollections = { }
2014-06-14 15:34:23 +02:00
2014-06-24 13:49:54 +02:00
# Reloads all achievements into memory.
# TODO might want to tweak this to only load new achievements
2014-06-14 15:34:23 +02:00
AchievementSchema.statics.loadAchievements = (done) ->
AchievementSchema . statics . resetAchievements ( )
2016-04-06 10:56:06 -07:00
Achievement = require ( ' ./Achievement ' )
2014-11-20 22:08:49 -08:00
query = Achievement . find ( { collection: { $ne: ' level.sessions ' } } )
2014-06-14 15:34:23 +02:00
query . exec (err, docs) ->
_ . each docs , (achievement) ->
2015-02-13 17:10:30 -08:00
collection = achievement . get ' collection '
AchievementSchema . statics . achievementCollections [ collection ] ? = [ ]
if _ . find AchievementSchema . statics . achievementCollections [ collection ] , ( (a) -> a . get ( ' _id ' ) . toHexString ( ) is achievement . get ( ' _id ' ) . toHexString ( ) )
log . warn " Uh oh, we tried to add another copy of the same achievement #{ achievement . get ( ' _id ' ) } #{ achievement . get ( ' name ' ) } to the #{ collection } achievement list... "
2015-02-13 16:33:03 -08:00
else
2015-02-13 17:10:30 -08:00
AchievementSchema . statics . achievementCollections [ collection ] . push achievement
2015-02-13 16:33:03 -08:00
unless achievement . get ( ' query ' )
log . error " Uh oh, there is an achievement with an empty query: #{ achievement } "
2016-04-08 15:06:05 -07:00
done ? ( AchievementSchema . statics . achievementCollections ) # TODO: Return with err as first parameter
2014-06-14 15:34:23 +02:00
AchievementSchema.statics.getLoadedAchievements = ->
2015-02-13 17:10:30 -08:00
AchievementSchema . statics . achievementCollections
2014-06-14 15:34:23 +02:00
AchievementSchema.statics.resetAchievements = ->
2015-02-13 17:10:30 -08:00
delete AchievementSchema . statics . achievementCollections [ collection ] for collection of AchievementSchema . statics . achievementCollections
2016-04-11 11:59:51 -07:00
AchievementSchema.statics.editableProperties = [
' name '
' query '
' worth '
' collection '
' description '
' userField '
' proportionalTo '
' icon '
' function '
' related '
' difficulty '
' category '
' rewards '
' i18n '
' i18nCoverage '
]
AchievementSchema.statics.jsonSchema = require ' ../../app/schemas/models/achievement '
2014-06-14 15:34:23 +02:00
2014-06-24 13:49:54 +02:00
# Queries are stored as JSON strings, objectify them upon loading
2014-06-13 18:04:25 +02:00
AchievementSchema . post ' init ' , (doc) -> doc . objectifyQuery ( )
2014-05-21 19:47:17 +02:00
2014-06-13 18:04:25 +02:00
AchievementSchema . pre ' save ' , (next) ->
2014-05-21 19:47:17 +02:00
@ stringifyQuery ( )
next ( )
2014-06-13 18:04:25 +02:00
# Reload achievements upon save
2015-02-13 16:33:03 -08:00
# This is going to basically not work when there is more than one application server, right?
2014-06-14 15:34:23 +02:00
AchievementSchema . post ' save ' , -> @ constructor . loadAchievements ( )
2014-05-21 19:47:17 +02:00
2014-05-19 23:20:50 +02:00
AchievementSchema . plugin ( plugins . NamedPlugin )
2014-05-31 23:19:55 +02:00
AchievementSchema . plugin ( plugins . SearchablePlugin , { searchable: [ ' name ' ] } )
2014-10-27 17:11:48 -07:00
AchievementSchema . plugin plugins . TranslationCoveragePlugin
2015-02-05 12:01:19 -08:00
AchievementSchema . plugin plugins . PatchablePlugin
2014-06-09 17:28:35 +02:00
2014-07-03 21:20:06 +02:00
module.exports = Achievement = mongoose . model ( ' Achievement ' , AchievementSchema , ' achievements ' )
2014-06-10 20:05:32 +02:00
2014-06-14 15:34:23 +02:00
AchievementSchema . statics . loadAchievements ( )