LearnedWordsManager.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. const { db } = require('./mongodb')
  2. const mongoCache = require('./MongoCache')
  3. const logger = require('logger-sharelatex')
  4. const metrics = require('@overleaf/metrics')
  5. const { promisify } = require('util')
  6. const OError = require('@overleaf/o-error')
  7. const LearnedWordsManager = {
  8. learnWord(userToken, word, callback) {
  9. if (callback == null) {
  10. callback = () => {}
  11. }
  12. mongoCache.del(userToken)
  13. return db.spellingPreferences.updateOne(
  14. {
  15. token: userToken
  16. },
  17. {
  18. $addToSet: { learnedWords: word }
  19. },
  20. {
  21. upsert: true
  22. },
  23. callback
  24. )
  25. },
  26. unlearnWord(userToken, word, callback) {
  27. if (callback == null) {
  28. callback = () => {}
  29. }
  30. mongoCache.del(userToken)
  31. return db.spellingPreferences.updateOne(
  32. {
  33. token: userToken
  34. },
  35. {
  36. $pull: { learnedWords: word }
  37. },
  38. callback
  39. )
  40. },
  41. getLearnedWords(userToken, callback) {
  42. if (callback == null) {
  43. callback = () => {}
  44. }
  45. const mongoCachedWords = mongoCache.get(userToken)
  46. if (mongoCachedWords != null) {
  47. metrics.inc('mongoCache', 0.1, { status: 'hit' })
  48. return callback(null, mongoCachedWords)
  49. }
  50. metrics.inc('mongoCache', 0.1, { status: 'miss' })
  51. logger.info({ userToken }, 'mongoCache miss')
  52. db.spellingPreferences.findOne({ token: userToken }, function (
  53. error,
  54. preferences
  55. ) {
  56. if (error != null) {
  57. return callback(OError.tag(error))
  58. }
  59. let words =
  60. (preferences != null ? preferences.learnedWords : undefined) || []
  61. if (words) {
  62. // remove duplicates
  63. words = words.filter(
  64. (value, index, self) => self.indexOf(value) === index
  65. )
  66. }
  67. mongoCache.set(userToken, words)
  68. callback(null, words)
  69. })
  70. },
  71. deleteUsersLearnedWords(userToken, callback) {
  72. if (callback == null) {
  73. callback = () => {}
  74. }
  75. db.spellingPreferences.deleteOne({ token: userToken }, callback)
  76. }
  77. }
  78. const promises = {
  79. learnWord: promisify(LearnedWordsManager.learnWord),
  80. unlearnWord: promisify(LearnedWordsManager.unlearnWord),
  81. getLearnedWords: promisify(LearnedWordsManager.getLearnedWords),
  82. deleteUsersLearnedWords: promisify(
  83. LearnedWordsManager.deleteUsersLearnedWords
  84. )
  85. }
  86. LearnedWordsManager.promises = promises
  87. module.exports = LearnedWordsManager
  88. ;['learnWord', 'unlearnWord', 'getLearnedWords'].map((method) =>
  89. metrics.timeAsyncMethod(
  90. LearnedWordsManager,
  91. method,
  92. 'mongo.LearnedWordsManager',
  93. logger
  94. )
  95. )