Просмотр исходного кода

Merge pull request #613 from sharelatex/hb-extract-v1-templates-to-web

Extract v1 templates code to web
Hugh O'Brien 8 лет назад
Родитель
Сommit
a79c9b94a8

+ 80 - 0
services/web/app/coffee/Features/Templates/TemplatesController.coffee

@@ -0,0 +1,80 @@
+path = require('path')
+Project = require('../../../js/models/Project').Project
+ProjectUploadManager = require('../../../js/Features/Uploads/ProjectUploadManager')
+ProjectOptionsHandler = require('../../../js/Features/Project/ProjectOptionsHandler')
+AuthenticationController = require('../../../js/Features/Authentication/AuthenticationController')
+settings = require('settings-sharelatex')
+fs = require('fs')
+request = require('request')
+uuid = require('uuid')
+logger = require('logger-sharelatex')
+async = require("async")
+
+
+module.exports = TemplatesController =
+
+	getV1Template: (req, res)->
+		templateVersionId = req.params.Template_version_id
+		templateId = req.query.id
+		if !/^[0-9]+$/.test(templateVersionId) || !/^[0-9]+$/.test(templateId)
+			logger.err templateVersionId:templateVersionId, templateId: templateId, "invalid template id or version"
+			return res.sendStatus 400
+		data = {}
+		data.templateVersionId = templateVersionId
+		data.templateId = templateId
+		data.name = req.query.templateName
+		data.compiler = req.query.latexEngine
+		res.render path.resolve(__dirname, "../../../views/project/editor/new_from_template"), data
+
+	createProjectFromV1Template: (req, res)->
+		currentUserId = AuthenticationController.getLoggedInUserId(req)
+		zipUrl =	"#{settings.apis.v1.url}/api/v1/sharelatex/templates/#{req.body.templateVersionId}"
+		zipReq = request(zipUrl, {
+			'auth': {
+				'user': settings.apis.v1.user,
+				'pass': settings.apis.v1.pass
+			}
+		})
+
+		TemplatesController.createFromZip(
+			zipReq,
+			{
+				templateName: req.body.templateName,
+				currentUserId: currentUserId,
+				compiler: req.body.compiler
+				docId: req.body.docId
+				templateId: req.body.templateId
+				templateVersionId: req.body.templateVersionId
+			},
+			req,
+			res
+		)
+
+	createFromZip: (zipReq, options, req, res)->
+		dumpPath = "#{settings.path.dumpFolder}/#{uuid.v4()}"
+		writeStream = fs.createWriteStream(dumpPath)
+
+		zipReq.on "error", (error) ->
+			logger.error err: error, "error getting zip from template API"
+		zipReq.pipe(writeStream)
+		writeStream.on 'close', ->
+			ProjectUploadManager.createProjectFromZipArchive options.currentUserId, options.templateName, dumpPath, (err, project)->
+				if err?
+					logger.err err:err, zipReq:zipReq, "problem building project from zip"
+					return res.sendStatus 500
+				setCompiler project._id, options.compiler, ->
+					fs.unlink dumpPath, ->
+					delete req.session.templateData
+					conditions = {_id:project._id}
+					update = {
+						fromV1TemplateId:options.templateId,
+						fromV1TemplateVersionId:options.templateVersionId
+					}
+					Project.update conditions, update, {}, (err)->
+						res.redirect "/project/#{project._id}"
+
+setCompiler = (project_id, compiler, callback)->
+	if compiler?
+		ProjectOptionsHandler.setCompiler project_id, compiler, callback
+	else
+		callback()

+ 8 - 0
services/web/app/coffee/Features/Templates/TemplatesMiddlewear

@@ -0,0 +1,8 @@
+settings = require("settings-sharelatex")
+logger = require("logger-sharelatex")
+
+module.exports =
+	saveTemplateDataInSession: (req, res, next)->
+		if req.query.templateName
+			req.session.templateData = req.query
+		next()

+ 9 - 0
services/web/app/coffee/Features/Templates/TemplatesMiddlewear.coffee

@@ -0,0 +1,9 @@
+settings = require("settings-sharelatex")
+logger = require("logger-sharelatex")
+
+
+module.exports =
+	saveTemplateDataInSession: (req, res, next)->
+		if req.query.templateName
+			req.session.templateData = req.query
+		next()

+ 10 - 0
services/web/app/coffee/Features/Templates/TemplatesRouter.coffee

@@ -0,0 +1,10 @@
+AuthenticationController = require('../Authentication/AuthenticationController')
+TemplatesController = require("./TemplatesController")
+TemplatesMiddlewear = require('./TemplatesMiddlewear')
+
+module.exports = 
+	apply: (app)->
+
+		app.get '/project/new/template/:Template_version_id', TemplatesMiddlewear.saveTemplateDataInSession, AuthenticationController.requireLogin(), TemplatesController.getV1Template
+
+		app.post '/project/new/template', AuthenticationController.requireLogin(), TemplatesController.createProjectFromV1Template

+ 2 - 1
services/web/app/coffee/router.coffee

@@ -48,6 +48,7 @@ MetaController = require('./Features/Metadata/MetaController')
 TokenAccessController = require('./Features/TokenAccess/TokenAccessController')
 Features = require('./infrastructure/Features')
 LinkedFilesRouter = require './Features/LinkedFiles/LinkedFilesRouter'
+TemplatesRouter = require './Features/Templates/TemplatesRouter'
 
 logger = require("logger-sharelatex")
 _ = require("underscore")
@@ -80,10 +81,10 @@ module.exports = class Router
 		ContactRouter.apply(webRouter, privateApiRouter)
 		AnalyticsRouter.apply(webRouter, privateApiRouter, publicApiRouter)
 		LinkedFilesRouter.apply(webRouter, privateApiRouter, publicApiRouter)
+		TemplatesRouter.apply(webRouter)
 
 		Modules.applyRouter(webRouter, privateApiRouter, publicApiRouter)
 
-
 		if Settings.enableSubscriptions
 			webRouter.get  '/user/bonus', AuthenticationController.requireLogin(), ReferalController.bonus
 

+ 26 - 0
services/web/app/views/project/editor/new_from_template.pug

@@ -0,0 +1,26 @@
+extends ../../layout
+
+block content
+  script.
+    $(document).ready(function(){
+      $('#create_form').submit();
+    });
+
+  .editor.full-size
+    .loading-screen()
+      .loading-screen-brand-container
+        .loading-screen-brand(
+          style="height: 20%;"
+        )
+
+      h3.loading-screen-label() #{translate("Opening template")}
+        span.loading-screen-ellip .
+        span.loading-screen-ellip .
+        span.loading-screen-ellip .
+
+  form(id='create_form' method='POST' action='/project/new/template/')
+    input(type="hidden", name="_csrf", value=csrfToken)
+    input(type="hidden" name="templateId" value=templateId)
+    input(type="hidden" name="templateVersionId" value=templateVersionId)
+    input(type="hidden" name="templateName" value=name)
+    input(type="hidden" name="compiler" value=compiler)

+ 76 - 0
services/web/test/unit/coffee/Templates/TemplatesControllerTests.coffee

@@ -0,0 +1,76 @@
+should = require('chai').should()
+SandboxedModule = require('sandboxed-module')
+assert = require('assert')
+path = require('path')
+sinon = require('sinon')
+modulePath = '../../../../app/js/Features/Templates/TemplatesController'
+
+
+describe 'TemplatesController', ->
+
+	project_id = "213432"
+
+	beforeEach ->
+		@request = sinon.stub()
+		@request.returns {
+			pipe:->
+			on:->
+		}
+		@fs = {
+			unlink : sinon.stub()
+			createWriteStream : sinon.stub().returns(on:(_, cb)->cb())
+		}
+		@ProjectUploadManager = {createProjectFromZipArchive : sinon.stub().callsArgWith(3, null, {_id:project_id})}
+		@dumpFolder = "dump/path"
+		@ProjectOptionsHandler = {setCompiler:sinon.stub().callsArgWith(2)}
+		@uuid = "1234"
+		@ProjectDetailsHandler =
+			getProjectDescription:sinon.stub()
+		@Project =
+			update: sinon.stub().callsArgWith(3, null)
+		@controller = SandboxedModule.require modulePath, requires:
+			'../../../js/Features/Uploads/ProjectUploadManager':@ProjectUploadManager
+			'../../../js/Features/Project/ProjectOptionsHandler':@ProjectOptionsHandler
+			'../../../js/Features/Authentication/AuthenticationController': @AuthenticationController = {getLoggedInUserId: sinon.stub()}
+			'./TemplatesPublisher':@TemplatesPublisher
+			"logger-sharelatex":
+				log:->
+				err:->
+			"settings-sharelatex":
+				path:
+					dumpFolder:@dumpFolder
+				siteUrl: @siteUrl = "http://localhost:3000"
+				apis:
+					v1:
+						url: @v1Url="http://overleaf.com"
+						user: "sharelatex"
+						pass: "password"
+				overleaf:
+					host: @v1Url
+			"uuid":v4:=>@uuid
+			"request": @request
+			"fs":@fs
+			"../../../../app/js/models/Project": {Project: @Project}
+		@zipUrl = "%2Ftemplates%2F52fb86a81ae1e566597a25f6%2Fv%2F4%2Fzip&templateName=Moderncv%20Banking&compiler=pdflatex"
+		@templateName = "project name here"
+		@user_id = "1234"
+		@req =
+			session:
+				user: _id:@user_id
+				templateData:
+					zipUrl: @zipUrl
+					templateName: @templateName
+		@redirect = {}
+		@AuthenticationController.getLoggedInUserId.returns(@user_id)
+
+	describe 'v1Templates', ->
+
+		it "should fetch zip from v1 based on template id", (done)->
+			@templateVersionId = 15
+			@req.body = {templateVersionId: @templateVersionId}
+
+			redirect = =>
+				@request.calledWith("#{@v1Url}/api/v1/sharelatex/templates/#{@templateVersionId}").should.equal true
+				done()
+			res = redirect:redirect
+			@controller.createProjectFromV1Template @req, res