Merge branch 'master' into pr-human-readable-logs
|
@ -17,6 +17,8 @@ module.exports = (grunt) ->
|
|||
grunt.loadNpmTasks 'grunt-contrib-watch'
|
||||
grunt.loadNpmTasks 'grunt-parallel'
|
||||
grunt.loadNpmTasks 'grunt-exec'
|
||||
grunt.loadNpmTasks 'grunt-contrib-imagemin'
|
||||
grunt.loadNpmTasks 'grunt-contrib-cssmin'
|
||||
|
||||
config =
|
||||
|
||||
|
@ -27,7 +29,7 @@ module.exports = (grunt) ->
|
|||
|
||||
watch:
|
||||
coffee:
|
||||
files: '**/*.coffee'
|
||||
files: 'public/**/*.coffee'
|
||||
tasks: ['quickcompile:coffee']
|
||||
options: {}
|
||||
|
||||
|
@ -44,6 +46,21 @@ module.exports = (grunt) ->
|
|||
grunt:true
|
||||
stream:true
|
||||
|
||||
|
||||
imagemin:
|
||||
dynamic:
|
||||
files: [{
|
||||
expand: true
|
||||
cwd: 'public/img/'
|
||||
src: ['**/*.{png,jpg,gif}']
|
||||
dest: 'public/img/'
|
||||
}]
|
||||
options:
|
||||
interlaced:false
|
||||
optimizationLevel: 7
|
||||
|
||||
|
||||
|
||||
coffee:
|
||||
app_dir:
|
||||
expand: true,
|
||||
|
@ -108,6 +125,11 @@ module.exports = (grunt) ->
|
|||
files:
|
||||
"public/stylesheets/style.css": "public/stylesheets/style.less"
|
||||
|
||||
cssmin:
|
||||
target:
|
||||
files:
|
||||
"public/stylesheets/style.css": "public/stylesheets/style.css"
|
||||
|
||||
env:
|
||||
run:
|
||||
add:
|
||||
|
@ -332,7 +354,7 @@ module.exports = (grunt) ->
|
|||
grunt.registerTask 'compile:server', 'Compile the server side coffee script', ['clean:app', 'coffee:app', 'coffee:app_dir', 'compile:modules:server']
|
||||
grunt.registerTask 'compile:client', 'Compile the client side coffee script', ['coffee:client', 'coffee:sharejs', 'wrap_sharejs', "compile:modules:client", 'compile:modules:inject_clientside_includes']
|
||||
grunt.registerTask 'compile:css', 'Compile the less files to css', ['less']
|
||||
grunt.registerTask 'compile:minify', 'Concat and minify the client side js', ['requirejs', "file_append"]
|
||||
grunt.registerTask 'compile:minify', 'Concat and minify the client side js', ['requirejs', "file_append", "cssmin"]
|
||||
grunt.registerTask 'compile:unit_tests', 'Compile the unit tests', ['clean:unit_tests', 'coffee:unit_tests']
|
||||
grunt.registerTask 'compile:acceptance_tests', 'Compile the acceptance tests', ['clean:acceptance_tests', 'coffee:acceptance_tests']
|
||||
grunt.registerTask 'compile:smoke_tests', 'Compile the smoke tests', ['coffee:smoke_tests']
|
||||
|
|
|
@ -44,11 +44,20 @@ module.exports = CompileController =
|
|||
}
|
||||
|
||||
_compileAsUser: (req, callback) ->
|
||||
# callback with user_id if isolated flag is set on request, undefined otherwise
|
||||
isolated = req.query?.isolated is "true"
|
||||
if isolated
|
||||
AuthenticationController.getLoggedInUserId req, callback
|
||||
AuthenticationController.getLoggedInUserId req, callback # -> (error, user_id)
|
||||
else
|
||||
callback()
|
||||
callback() # do a per-project compile, not per-user
|
||||
|
||||
_downloadAsUser: (req, callback) ->
|
||||
# callback with user_id if isolated flag or user_id param is set on request, undefined otherwise
|
||||
isolated = req.query?.isolated is "true" or req.params.user_id?
|
||||
if isolated
|
||||
AuthenticationController.getLoggedInUserId req, callback # -> (error, user_id)
|
||||
else
|
||||
callback() # do a per-project compile, not per-user
|
||||
|
||||
downloadPdf: (req, res, next = (error) ->)->
|
||||
Metrics.inc "pdf-downloads"
|
||||
|
@ -82,7 +91,9 @@ module.exports = CompileController =
|
|||
logger.log project_id:project_id, ip:req.ip, "rate limit hit downloading pdf"
|
||||
res.send 500
|
||||
else
|
||||
CompileController.proxyToClsi(project_id, "/project/#{project_id}/output/output.pdf", req, res, next)
|
||||
CompileController._downloadAsUser req, (error, user_id) ->
|
||||
url = CompileController._getFileUrl project_id, user_id, req.params.build_id, "output.pdf"
|
||||
CompileController.proxyToClsi(project_id, url, req, res, next)
|
||||
|
||||
deleteAuxFiles: (req, res, next) ->
|
||||
project_id = req.params.Project_id
|
||||
|
@ -92,29 +103,37 @@ module.exports = CompileController =
|
|||
return next(error) if error?
|
||||
res.sendStatus(200)
|
||||
|
||||
# this is only used by templates, so is not called with a user_id
|
||||
compileAndDownloadPdf: (req, res, next)->
|
||||
project_id = req.params.project_id
|
||||
CompileController._compileAsUser req, (error, user_id) ->
|
||||
return next(error) if error?
|
||||
CompileManager.compile project_id, user_id, {}, (err)->
|
||||
if err?
|
||||
logger.err err:err, project_id:project_id, "something went wrong compile and downloading pdf"
|
||||
res.sendStatus 500
|
||||
url = "/project/#{project_id}/output/output.pdf"
|
||||
CompileController.proxyToClsi project_id, url, req, res, next
|
||||
# pass user_id as null, since templates are an "anonymous" compile
|
||||
CompileManager.compile project_id, null, {}, (err)->
|
||||
if err?
|
||||
logger.err err:err, project_id:project_id, "something went wrong compile and downloading pdf"
|
||||
res.sendStatus 500
|
||||
url = "/project/#{project_id}/output/output.pdf"
|
||||
CompileController.proxyToClsi project_id, url, req, res, next
|
||||
|
||||
getFileFromClsi: (req, res, next = (error) ->) ->
|
||||
project_id = req.params.Project_id
|
||||
build_id = req.params.build_id
|
||||
user_id = req.params.user_id
|
||||
if user_id? and build_id?
|
||||
url = "/project/#{project_id}/user/#{user_id}/build/#{build_id}/output/#{req.params.file}"
|
||||
else if build_id?
|
||||
url = "/project/#{project_id}/build/#{build_id}/output/#{req.params.file}"
|
||||
else
|
||||
url = "/project/#{project_id}/output/#{req.params.file}"
|
||||
CompileController.proxyToClsi(project_id, url, req, res, next)
|
||||
CompileController._downloadAsUser req, (error, user_id) ->
|
||||
return next(error) if error?
|
||||
url = CompileController._getFileUrl project_id, user_id, req.params.build_id, req.params.file
|
||||
CompileController.proxyToClsi(project_id, url, req, res, next)
|
||||
|
||||
# compute a GET file url for a given project, user (optional), build (optional) and file
|
||||
_getFileUrl: (project_id, user_id, build_id, file) ->
|
||||
if user_id? and build_id?
|
||||
url = "/project/#{project_id}/user/#{user_id}/build/#{build_id}/output/#{file}"
|
||||
else if user_id?
|
||||
url = "/project/#{project_id}/user/#{user_id}/output/#{file}"
|
||||
else if build_id?
|
||||
url = "/project/#{project_id}/build/#{build_id}/output/#{file}"
|
||||
else
|
||||
url = "/project/#{project_id}/output/#{file}"
|
||||
return url
|
||||
|
||||
# compute a POST url for a project, user (optional) and action
|
||||
_getUrl: (project_id, user_id, action) ->
|
||||
path = "/project/#{project_id}"
|
||||
path += "/user/#{user_id}" if user_id?
|
||||
|
|
|
@ -106,7 +106,9 @@ module.exports = class Router
|
|||
webRouter.post '/project/:Project_id/settings/admin', AuthorizationMiddlewear.ensureUserCanAdminProject, ProjectController.updateProjectAdminSettings
|
||||
|
||||
webRouter.post '/project/:Project_id/compile', AuthorizationMiddlewear.ensureUserCanReadProject, CompileController.compile
|
||||
webRouter.get '/Project/:Project_id/output/output.pdf', AuthorizationMiddlewear.ensureUserCanReadProject, CompileController.downloadPdf
|
||||
# Used by the web download buttons, adds filename header
|
||||
webRouter.get '/project/:Project_id/output/output.pdf', AuthorizationMiddlewear.ensureUserCanReadProject, CompileController.downloadPdf
|
||||
# Used by the pdf viewers
|
||||
webRouter.get /^\/project\/([^\/]*)\/output\/(.*)$/,
|
||||
((req, res, next) ->
|
||||
params =
|
||||
|
@ -236,8 +238,8 @@ module.exports = class Router
|
|||
res.send("websharelatex is up")
|
||||
|
||||
|
||||
webRouter.get '/health_check', HealthCheckController.check
|
||||
webRouter.get '/health_check/redis', HealthCheckController.checkRedis
|
||||
apiRouter.get '/health_check', HealthCheckController.check
|
||||
apiRouter.get '/health_check/redis', HealthCheckController.checkRedis
|
||||
|
||||
apiRouter.get "/status/compiler/:Project_id", AuthorizationMiddlewear.ensureUserCanReadProject, (req, res) ->
|
||||
sendRes = _.once (statusCode, message)->
|
||||
|
|
|
@ -27,7 +27,7 @@ block content
|
|||
.col-md-12
|
||||
if user.betaProgram
|
||||
p #{translate("beta_program_already_participating")}
|
||||
form(method="post", action="/beta/opt-out", novalidate)
|
||||
form(id="beta-program-opt-out", method="post", action="/beta/opt-out", novalidate)
|
||||
.form-group
|
||||
input(type="hidden", name="_csrf", value=csrfToken)
|
||||
button.btn.btn-primary(
|
||||
|
@ -37,7 +37,7 @@ block content
|
|||
.form-group
|
||||
a(href="/project").btn.btn-info #{translate("back_to_your_projects")}
|
||||
else
|
||||
form(method="post", action="/beta/opt-in", novalidate)
|
||||
form(id="beta-program-opt-in", method="post", action="/beta/opt-in", novalidate)
|
||||
.form-group
|
||||
input(type="hidden", name="_csrf", value=csrfToken)
|
||||
button.btn.btn-primary(
|
||||
|
|
|
@ -66,7 +66,6 @@ html(itemscope, itemtype='http://schema.org/Product')
|
|||
block scripts
|
||||
script(src="#{jsPath}libs/jquery-1.11.1.min.js")
|
||||
script(src="#{jsPath}libs/angular-1.3.15.min.js")
|
||||
include sentry
|
||||
script.
|
||||
window.sharelatex = {
|
||||
siteUrl: '#{settings.siteUrl}',
|
||||
|
@ -141,6 +140,7 @@ html(itemscope, itemtype='http://schema.org/Product')
|
|||
)
|
||||
|
||||
include contact-us-modal
|
||||
|
||||
include sentry
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -108,7 +108,7 @@ block content
|
|||
p.small
|
||||
| #{translate("beta_program_already_participating")}
|
||||
div
|
||||
a(href="/beta/participate") #{translate("manage_beta_program_membership")}
|
||||
a(id="beta-program-participate-link" href="/beta/participate") #{translate("manage_beta_program_membership")}
|
||||
|
||||
hr
|
||||
|
||||
|
|
|
@ -69,17 +69,18 @@
|
|||
"grunt-bunyan": "0.5.0",
|
||||
"grunt-contrib-clean": "0.5.0",
|
||||
"grunt-contrib-coffee": "0.10.0",
|
||||
"grunt-contrib-cssmin": "^1.0.1",
|
||||
"grunt-contrib-imagemin": "^1.0.1",
|
||||
"grunt-contrib-less": "0.9.0",
|
||||
"grunt-contrib-requirejs": "0.4.1",
|
||||
"grunt-contrib-watch": "^1.0.0",
|
||||
"grunt-env": "0.4.4",
|
||||
"grunt-exec": "^0.4.7",
|
||||
"grunt-parallel": "^0.5.1",
|
||||
|
||||
"grunt-file-append": "0.0.6",
|
||||
"grunt-git-rev-parse": "^0.1.4",
|
||||
"grunt-mocha-test": "0.9.0",
|
||||
"grunt-newer": "^1.2.0",
|
||||
"grunt-parallel": "^0.5.1",
|
||||
"grunt-sed": "^0.1.1",
|
||||
"sandboxed-module": "0.2.0",
|
||||
"sinon": "",
|
||||
|
|
|
@ -2,7 +2,7 @@ define [
|
|||
"base"
|
||||
"libs/moment-2.9.0"
|
||||
], (App, moment) ->
|
||||
moment.locale "en", calendar:
|
||||
moment.updateLocale "en", calendar:
|
||||
lastDay : '[Yesterday]'
|
||||
sameDay : '[Today]'
|
||||
nextDay : '[Tomorrow]'
|
||||
|
|
|
@ -19,6 +19,11 @@ define [
|
|||
else
|
||||
$scope.modifierKey = "Ctrl"
|
||||
|
||||
# utility for making a query string from a hash, could use jquery $.param
|
||||
createQueryString = (args) ->
|
||||
qs_args = ("#{k}=#{v}" for k, v of args)
|
||||
if qs_args.length then "?" + qs_args.join("&") else ""
|
||||
|
||||
$scope.$on "project:joined", () ->
|
||||
return if !autoCompile
|
||||
autoCompile = false
|
||||
|
@ -112,10 +117,14 @@ define [
|
|||
qs.clsiserverid = response.clsiServerId
|
||||
ide.clsiServerId = response.clsiServerId
|
||||
# convert the qs hash into a query string and append it
|
||||
qs_args = ("#{k}=#{v}" for k, v of qs)
|
||||
$scope.pdf.qs = if qs_args.length then "?" + qs_args.join("&") else ""
|
||||
$scope.pdf.qs = createQueryString qs
|
||||
$scope.pdf.url += $scope.pdf.qs
|
||||
$scope.pdf.downloadUrl = "/Project/#{$scope.project_id}/output/output.pdf" + $scope.pdf.qs
|
||||
# special case for the download url
|
||||
if perUserCompile
|
||||
qs.isolated = true
|
||||
# Save all downloads as files
|
||||
qs.popupDownload = true
|
||||
$scope.pdf.downloadUrl = "/project/#{$scope.project_id}/output/output.pdf" + createQueryString(qs)
|
||||
|
||||
fetchLogs(fileByPath['output.log'], fileByPath['output.blg'])
|
||||
|
||||
|
@ -131,10 +140,12 @@ define [
|
|||
file.name = "#{file.path.replace(/^output\./, "")} file"
|
||||
else
|
||||
file.name = file.path
|
||||
if not file.url?
|
||||
file.url = "/project/#{project_id}/output/#{file.path}"
|
||||
qs = {}
|
||||
if perUserCompile
|
||||
qs.isolated = true
|
||||
if response.clsiServerId?
|
||||
file.url = file.url + "?clsiserverid=#{response.clsiServerId}"
|
||||
qs.clsiserverid = response.clsiServerId
|
||||
file.url = "/project/#{project_id}/output/#{file.path}" + createQueryString qs
|
||||
$scope.pdf.outputFiles.push file
|
||||
|
||||
|
||||
|
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 7 KiB |
Before Width: | Height: | Size: 9 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 9.6 KiB |
Before Width: | Height: | Size: 9.5 KiB After Width: | Height: | Size: 6.3 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 593 B After Width: | Height: | Size: 592 B |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.3 KiB |
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 7.6 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 219 KiB After Width: | Height: | Size: 186 KiB |
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 141 KiB After Width: | Height: | Size: 131 KiB |
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 4 KiB |
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 4 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 7.9 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 865 B |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 792 B After Width: | Height: | Size: 780 B |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 8.9 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 635 KiB After Width: | Height: | Size: 632 KiB |
Before Width: | Height: | Size: 217 KiB After Width: | Height: | Size: 145 KiB |
Before Width: | Height: | Size: 490 KiB After Width: | Height: | Size: 349 KiB |
Before Width: | Height: | Size: 288 B After Width: | Height: | Size: 216 B |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 199 B After Width: | Height: | Size: 114 B |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |