2_doc_lines_delete_from_project.coffee 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. Settings = require "settings-sharelatex"
  2. fs = require("fs")
  3. mongojs = require("mongojs")
  4. ObjectId = mongojs.ObjectId
  5. db = mongojs(Settings.mongo.url, ['projects', 'docs'])
  6. _ = require("lodash")
  7. async = require("async")
  8. exec = require("child_process").exec
  9. finished_projects_path = "/tmp/finished-projects-2"
  10. all_projects_path = "/tmp/all-projects-2"
  11. unmigrated_docs_path = "/tmp/unmigrated-2"
  12. printProgress = ->
  13. exec "wc #{finished_projects_path}", (error, results) ->
  14. setTimeout printProgress, 1000 * 30
  15. checkIfFileHasBeenProcessed = (project_id, callback)->
  16. exec "grep #{project_id} #{finished_projects_path}", (error, results) ->
  17. hasBeenProcessed = _.include(results, project_id)
  18. callback(error, hasBeenProcessed)
  19. loadProjectIds = (callback)->
  20. console.log "loading project ids from #{all_projects_path}"
  21. fs.readFile all_projects_path, "utf-8", (err, data)->
  22. ids = data.split("\n")
  23. ids = _.filter ids, (id)-> id? and id.length == 24
  24. console.log "loaded #{ids.length} project ids from #{all_projects_path}"
  25. callback err, ids
  26. getAndWriteProjectids = (callback)->
  27. console.log "finding all project id's - #{new Date().toString()}"
  28. db.projects.find {}, {_id:1}, (err, ids)->
  29. console.log "total found projects in mongo #{ids.length} - #{new Date().toString()}"
  30. ids = _.pluck ids, '_id'
  31. ids = _.filter ids, (id)-> id?
  32. fileData = ids.join("\n")
  33. fs.writeFile all_projects_path, fileData, ->
  34. callback(err, ids)
  35. markDocAsUnmigrated = (project_id, doc_id, callback)->
  36. console.log "#{project_id} #{doc_id} unmigrated"
  37. markProjectAsProcessed project_id, (err)->
  38. fs.appendFile unmigrated_docs_path, "#{project_id} #{doc_id}\n", callback
  39. markUnmigratedDocs = (project_id, docs, callback)->
  40. console.log docs.length, project_id, "unmigrated"
  41. jobs = _.map docs, (doc)->
  42. (cb)->
  43. markDocAsUnmigrated project_id, doc._id, cb
  44. async.series jobs, callback
  45. getProjectIds = (callback)->
  46. exists = fs.existsSync all_projects_path
  47. if exists
  48. loadProjectIds callback
  49. else
  50. getAndWriteProjectids callback
  51. markProjectAsProcessed = (project_id, callback)->
  52. fs.appendFile finished_projects_path, "#{project_id}\n", callback
  53. getAllDocs = (project_id, callback = (error, docs) ->) ->
  54. excludes = {}
  55. for i in [0..12]
  56. excludes["rootFolder#{Array(i).join(".folders")}.docs.lines"] = 0
  57. db.projects.findOne _id: ObjectId(project_id.toString()), excludes, (error, project) ->
  58. return callback(error) if error?
  59. if !project?
  60. console.log "no such project #{project_id}"
  61. return callback()
  62. findAllDocsInProject project, (error, docs) ->
  63. return callback(error) if error?
  64. return callback null, docs, project
  65. findAllDocsInProject = (project, callback = (error, docs) ->) ->
  66. callback null, _findAllDocsInFolder project.rootFolder[0]
  67. findDocInProject = (project, doc_id, callback = (error, doc, mongoPath) ->) ->
  68. result = _findDocInFolder project.rootFolder[0], doc_id, "rootFolder.0"
  69. if result?
  70. callback null, result.doc, result.mongoPath
  71. else
  72. callback null, null, null
  73. _findDocInFolder = (folder = {}, doc_id, currentPath) ->
  74. for doc, i in folder.docs or []
  75. if doc?._id? and doc._id.toString() == doc_id.toString()
  76. return {
  77. doc: doc
  78. mongoPath: "#{currentPath}.docs.#{i}"
  79. }
  80. for childFolder, i in folder.folders or []
  81. result = _findDocInFolder childFolder, doc_id, "#{currentPath}.folders.#{i}"
  82. return result if result?
  83. return null
  84. _findAllDocsInFolder = (folder = {}) ->
  85. docs = folder.docs or []
  86. for childFolder in folder.folders or []
  87. docs = docs.concat _findAllDocsInFolder childFolder
  88. return docs
  89. isDocInDocCollection = (doc, callback)->
  90. if !doc?._id? or doc._id.length == 0
  91. return callback(null, true)
  92. db.docs.find({_id: ObjectId(doc._id+"")}, {_id: 1}).limit 1, (err, foundDocs)->
  93. exists = foundDocs.length > 0
  94. callback err, exists
  95. getWhichDocsCanBeDeleted = (docs, callback = (err, docsToBeDeleted, unmigratedDocs)->)->
  96. docsToBeDeleted = []
  97. unmigratedDocs = []
  98. jobs = _.map docs, (doc)->
  99. return (cb)->
  100. isDocInDocCollection doc, (err, exists)->
  101. if exists
  102. docsToBeDeleted.push doc
  103. else
  104. unmigratedDocs.push doc
  105. cb(err)
  106. async.series jobs, (err)->
  107. callback err, docsToBeDeleted, unmigratedDocs
  108. wipeDocLines = (project_id, mongoPath, callback)->
  109. update =
  110. $unset: {}
  111. update.$unset["#{mongoPath}.lines"] = ""
  112. update.$unset["#{mongoPath}.rev"] = ""
  113. db.projects.update _id: ObjectId(project_id+''), update, callback
  114. removeDocLinesFromProject = (docs, project, callback)->
  115. jobs = _.map docs, (doc)->
  116. (cb)->
  117. findDocInProject project, doc._id, (err, doc, mongoPath)->
  118. wipeDocLines project._id, mongoPath, cb
  119. async.parallelLimit jobs, 5, callback
  120. processNext = (project_id, callback)->
  121. if !project_id? or project_id.length == 0
  122. return callback()
  123. checkIfFileHasBeenProcessed project_id, (err, hasBeenProcessed)->
  124. if hasBeenProcessed
  125. console.log "#{project_id} already processed, skipping"
  126. return callback()
  127. console.log "#{project_id} processing"
  128. getAllDocs project_id, (err, docs, project)->
  129. if err?
  130. console.error err, project_id, "could not get all docs"
  131. return callback(err)
  132. else
  133. getWhichDocsCanBeDeleted docs, (err, docsToBeDeleted, unmigratedDocs)->
  134. if err?
  135. console.error err, project_id, "could not save docs into mongo"
  136. return callback(err)
  137. markUnmigratedDocs project_id, unmigratedDocs, (err)->
  138. removeDocLinesFromProject docsToBeDeleted, project, (err)->
  139. if err?
  140. return callback(err)
  141. markProjectAsProcessed project_id, (err)->
  142. setTimeout(
  143. -> callback(err)
  144. ,0)
  145. exports.migrate = (client, done = ->)->
  146. getProjectIds (err, ids)->
  147. printProgress()
  148. jobs = _.map ids, (id)->
  149. return (cb)->
  150. processNext(id, cb)
  151. async.series jobs, (err)->
  152. if err?
  153. console.error err, "at end of jobs"
  154. else
  155. console.log "finished"
  156. done(err)
  157. exports.rollback = (next)->
  158. next()