TrackChangesClient.coffee 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. async = require 'async'
  2. zlib = require 'zlib'
  3. request = require "request"
  4. Settings = require "settings-sharelatex"
  5. rclient = require("redis-sharelatex").createClient(Settings.redis.history) # Only works locally for now
  6. Keys = Settings.redis.history.key_schema
  7. {db, ObjectId} = require "../../../../app/js/mongojs"
  8. module.exports = TrackChangesClient =
  9. flushAndGetCompressedUpdates: (project_id, doc_id, callback = (error, updates) ->) ->
  10. TrackChangesClient.flushDoc project_id, doc_id, (error) ->
  11. return callback(error) if error?
  12. TrackChangesClient.getCompressedUpdates doc_id, callback
  13. flushDoc: (project_id, doc_id, callback = (error) ->) ->
  14. request.post {
  15. url: "http://localhost:3015/project/#{project_id}/doc/#{doc_id}/flush"
  16. }, (error, response, body) =>
  17. response.statusCode.should.equal 204
  18. callback(error)
  19. flushProject: (project_id, callback = (error) ->) ->
  20. request.post {
  21. url: "http://localhost:3015/project/#{project_id}/flush"
  22. }, (error, response, body) =>
  23. response.statusCode.should.equal 204
  24. callback(error)
  25. getCompressedUpdates: (doc_id, callback = (error, updates) ->) ->
  26. db.docHistory
  27. .find(doc_id: ObjectId(doc_id))
  28. .sort("meta.end_ts": 1)
  29. .toArray callback
  30. getProjectMetaData: (project_id, callback = (error, updates) ->) ->
  31. db.projectHistoryMetaData
  32. .find {
  33. project_id: ObjectId(project_id)
  34. },
  35. (error, projects) ->
  36. callback error, projects[0]
  37. setPreserveHistoryForProject: (project_id, callback = (error) ->) ->
  38. db.projectHistoryMetaData.update {
  39. project_id: ObjectId(project_id)
  40. }, {
  41. $set: { preserveHistory: true }
  42. }, {
  43. upsert: true
  44. }, callback
  45. pushRawUpdates: (project_id, doc_id, updates, callback = (error) ->) ->
  46. rclient.sadd Keys.docsWithHistoryOps({project_id}), doc_id, (error) ->
  47. return callback(error) if error?
  48. rclient.rpush Keys.uncompressedHistoryOps({doc_id}), (JSON.stringify(u) for u in updates)..., callback
  49. getDiff: (project_id, doc_id, from, to, callback = (error, diff) ->) ->
  50. request.get {
  51. url: "http://localhost:3015/project/#{project_id}/doc/#{doc_id}/diff?from=#{from}&to=#{to}"
  52. }, (error, response, body) =>
  53. response.statusCode.should.equal 200
  54. callback null, JSON.parse(body)
  55. getUpdates: (project_id, options, callback = (error, body) ->) ->
  56. request.get {
  57. url: "http://localhost:3015/project/#{project_id}/updates?before=#{options.before}&min_count=#{options.min_count}"
  58. }, (error, response, body) =>
  59. response.statusCode.should.equal 200
  60. callback null, JSON.parse(body)
  61. restoreDoc: (project_id, doc_id, version, user_id, callback = (error) ->) ->
  62. request.post {
  63. url: "http://localhost:3015/project/#{project_id}/doc/#{doc_id}/version/#{version}/restore"
  64. headers:
  65. "X-User-Id": user_id
  66. }, (error, response, body) =>
  67. response.statusCode.should.equal 204
  68. callback null
  69. pushDocHistory: (project_id, doc_id, callback = (error) ->) ->
  70. request.post {
  71. url: "http://localhost:3015/project/#{project_id}/doc/#{doc_id}/push"
  72. }, (error, response, body) =>
  73. response.statusCode.should.equal 204
  74. callback(error)
  75. pullDocHistory: (project_id, doc_id, callback = (error) ->) ->
  76. request.post {
  77. url: "http://localhost:3015/project/#{project_id}/doc/#{doc_id}/pull"
  78. }, (error, response, body) =>
  79. response.statusCode.should.equal 204
  80. callback(error)
  81. buildS3Options: (content, key)->
  82. return {
  83. aws:
  84. key: Settings.trackchanges.s3.key
  85. secret: Settings.trackchanges.s3.secret
  86. bucket: Settings.trackchanges.stores.doc_history
  87. timeout: 30 * 1000
  88. json: content
  89. uri:"https://#{Settings.trackchanges.stores.doc_history}.s3.amazonaws.com/#{key}"
  90. }
  91. getS3Doc: (project_id, doc_id, pack_id, callback = (error, body) ->) ->
  92. options = TrackChangesClient.buildS3Options(true, project_id+"/changes-"+doc_id+"/pack-"+pack_id)
  93. options.encoding = null
  94. request.get options, (err, res, body) ->
  95. return callback(error) if error?
  96. return callback(new Error("empty response from s3")) if not body?
  97. zlib.gunzip body, (err, result) ->
  98. return callback(err) if err?
  99. callback(null, JSON.parse(result.toString()))
  100. removeS3Doc: (project_id, doc_id, callback = (error, res, body) ->) ->
  101. options = TrackChangesClient.buildS3Options(true, "?prefix=" + project_id + "/changes-" +doc_id)
  102. request.get options, (error, res, body) ->
  103. keys = body.match /[0-9a-f]{24}\/changes-[0-9a-f]{24}\/pack-[0-9a-f]{24}/g
  104. async.eachSeries keys, (key, cb) ->
  105. options = TrackChangesClient.buildS3Options(true, key)
  106. request.del options, cb
  107. , callback