mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-30 03:53:05 -05:00
Merge branch 'sk-linked-files-mendeley'
This commit is contained in:
commit
0777e44abf
9 changed files with 95 additions and 27 deletions
|
@ -6,7 +6,6 @@ logger = require 'logger-sharelatex'
|
||||||
_ = require 'underscore'
|
_ = require 'underscore'
|
||||||
LinkedFilesHandler = require './LinkedFilesHandler'
|
LinkedFilesHandler = require './LinkedFilesHandler'
|
||||||
{
|
{
|
||||||
|
|
||||||
UrlFetchFailedError,
|
UrlFetchFailedError,
|
||||||
InvalidUrlError,
|
InvalidUrlError,
|
||||||
OutputFileFetchFailedError,
|
OutputFileFetchFailedError,
|
||||||
|
@ -16,16 +15,23 @@ LinkedFilesHandler = require './LinkedFilesHandler'
|
||||||
ProjectNotFoundError,
|
ProjectNotFoundError,
|
||||||
V1ProjectNotFoundError,
|
V1ProjectNotFoundError,
|
||||||
SourceFileNotFoundError,
|
SourceFileNotFoundError,
|
||||||
|
NotOriginalImporterError,
|
||||||
|
FeatureNotAvailableError,
|
||||||
|
RemoteServiceError
|
||||||
} = require './LinkedFilesErrors'
|
} = require './LinkedFilesErrors'
|
||||||
|
Modules = require '../../infrastructure/Modules'
|
||||||
|
|
||||||
|
|
||||||
module.exports = LinkedFilesController = {
|
module.exports = LinkedFilesController = {
|
||||||
|
|
||||||
Agents: {
|
Agents: _.extend(
|
||||||
url: require('./UrlAgent'),
|
{
|
||||||
project_file: require('./ProjectFileAgent'),
|
url: require('./UrlAgent'),
|
||||||
project_output_file: require('./ProjectOutputFileAgent')
|
project_file: require('./ProjectFileAgent'),
|
||||||
}
|
project_output_file: require('./ProjectOutputFileAgent'),
|
||||||
|
},
|
||||||
|
Modules.linkedFileAgentsIncludes()
|
||||||
|
)
|
||||||
|
|
||||||
_getAgent: (provider) ->
|
_getAgent: (provider) ->
|
||||||
if !LinkedFilesController.Agents.hasOwnProperty(provider)
|
if !LinkedFilesController.Agents.hasOwnProperty(provider)
|
||||||
|
@ -117,6 +123,22 @@ module.exports = LinkedFilesController = {
|
||||||
"Your URL is not valid. Please check it and try again."
|
"Your URL is not valid. Please check it and try again."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
else if error instanceof NotOriginalImporterError
|
||||||
|
res.status(400).send(
|
||||||
|
"You are not the user who originally imported this file"
|
||||||
|
)
|
||||||
|
|
||||||
|
else if error instanceof FeatureNotAvailableError
|
||||||
|
res.status(400).send(
|
||||||
|
"This feature is not enabled on your account"
|
||||||
|
)
|
||||||
|
|
||||||
|
else if error instanceof RemoteServiceError
|
||||||
|
res.status(502).send(
|
||||||
|
"The remote service produced an error"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
else
|
else
|
||||||
next(error)
|
next(error)
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,6 +70,30 @@ SourceFileNotFoundError = (message) ->
|
||||||
SourceFileNotFoundError.prototype.__proto__ = Error.prototype
|
SourceFileNotFoundError.prototype.__proto__ = Error.prototype
|
||||||
|
|
||||||
|
|
||||||
|
NotOriginalImporterError = (message) ->
|
||||||
|
error = new Error(message)
|
||||||
|
error.name = 'NotOriginalImporter'
|
||||||
|
error.__proto__ = NotOriginalImporterError.prototype
|
||||||
|
return error
|
||||||
|
NotOriginalImporterError.prototype.__proto__ = Error.prototype
|
||||||
|
|
||||||
|
|
||||||
|
FeatureNotAvailableError = (message) ->
|
||||||
|
error = new Error(message)
|
||||||
|
error.name = 'FeatureNotAvailable'
|
||||||
|
error.__proto__ = FeatureNotAvailableError.prototype
|
||||||
|
return error
|
||||||
|
FeatureNotAvailableError.prototype.__proto__ = Error.prototype
|
||||||
|
|
||||||
|
|
||||||
|
RemoteServiceError = (message) ->
|
||||||
|
error = new Error(message)
|
||||||
|
error.name = 'RemoteService'
|
||||||
|
error.__proto__ = RemoteServiceError.prototype
|
||||||
|
return error
|
||||||
|
RemoteServiceError.prototype.__proto__ = Error.prototype
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
||||||
UrlFetchFailedError,
|
UrlFetchFailedError,
|
||||||
|
@ -81,4 +105,7 @@ module.exports = {
|
||||||
ProjectNotFoundError,
|
ProjectNotFoundError,
|
||||||
V1ProjectNotFoundError,
|
V1ProjectNotFoundError,
|
||||||
SourceFileNotFoundError,
|
SourceFileNotFoundError,
|
||||||
|
NotOriginalImporterError,
|
||||||
|
FeatureNotAvailableError,
|
||||||
|
RemoteServiceError
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ module.exports = Modules =
|
||||||
for module in @modules
|
for module in @modules
|
||||||
module.nonCsrfRouter?.apply(webRouter, privateApiRouter, publicApiRouter)
|
module.nonCsrfRouter?.apply(webRouter, privateApiRouter, publicApiRouter)
|
||||||
module.router?.applyNonCsrfRouter?(webRouter, privateApiRouter, publicApiRouter)
|
module.router?.applyNonCsrfRouter?(webRouter, privateApiRouter, publicApiRouter)
|
||||||
|
|
||||||
viewIncludes: {}
|
viewIncludes: {}
|
||||||
loadViewIncludes: (app) ->
|
loadViewIncludes: (app) ->
|
||||||
@viewIncludes = {}
|
@viewIncludes = {}
|
||||||
|
@ -32,7 +32,7 @@ module.exports = Modules =
|
||||||
@viewIncludes[view] ||= []
|
@viewIncludes[view] ||= []
|
||||||
filePath = Path.join(MODULE_BASE_PATH, module.name, "app/views", partial + ".pug")
|
filePath = Path.join(MODULE_BASE_PATH, module.name, "app/views", partial + ".pug")
|
||||||
@viewIncludes[view].push pug.compileFile(filePath, doctype: "html")
|
@viewIncludes[view].push pug.compileFile(filePath, doctype: "html")
|
||||||
|
|
||||||
moduleIncludes: (view, locals) ->
|
moduleIncludes: (view, locals) ->
|
||||||
compiledPartials = Modules.viewIncludes[view] or []
|
compiledPartials = Modules.viewIncludes[view] or []
|
||||||
html = ""
|
html = ""
|
||||||
|
@ -43,7 +43,7 @@ module.exports = Modules =
|
||||||
|
|
||||||
moduleIncludesAvailable: (view) ->
|
moduleIncludesAvailable: (view) ->
|
||||||
return (Modules.viewIncludes[view] or []).length > 0
|
return (Modules.viewIncludes[view] or []).length > 0
|
||||||
|
|
||||||
moduleAssetFiles: (pathPrefix) ->
|
moduleAssetFiles: (pathPrefix) ->
|
||||||
assetFiles = []
|
assetFiles = []
|
||||||
for module in @modules
|
for module in @modules
|
||||||
|
@ -51,18 +51,25 @@ module.exports = Modules =
|
||||||
assetFiles.push "#{pathPrefix}#{assetFile}"
|
assetFiles.push "#{pathPrefix}#{assetFile}"
|
||||||
return assetFiles
|
return assetFiles
|
||||||
|
|
||||||
|
linkedFileAgentsIncludes: () ->
|
||||||
|
agents = {}
|
||||||
|
for module in @modules
|
||||||
|
for name, agentFunction of module.linkedFileAgents
|
||||||
|
agents[name] = agentFunction()
|
||||||
|
return agents
|
||||||
|
|
||||||
attachHooks: () ->
|
attachHooks: () ->
|
||||||
for module in @modules
|
for module in @modules
|
||||||
if module.hooks?
|
if module.hooks?
|
||||||
for hook, method of module.hooks
|
for hook, method of module.hooks
|
||||||
Modules.hooks.attach hook, method
|
Modules.hooks.attach hook, method
|
||||||
|
|
||||||
hooks:
|
hooks:
|
||||||
_hooks: {}
|
_hooks: {}
|
||||||
attach: (name, method) ->
|
attach: (name, method) ->
|
||||||
@_hooks[name] ?= []
|
@_hooks[name] ?= []
|
||||||
@_hooks[name].push method
|
@_hooks[name].push method
|
||||||
|
|
||||||
fire: (name, args..., callback) ->
|
fire: (name, args..., callback) ->
|
||||||
methods = @_hooks[name] or []
|
methods = @_hooks[name] or []
|
||||||
call_methods = methods.map (method) ->
|
call_methods = methods.map (method) ->
|
||||||
|
@ -70,5 +77,5 @@ module.exports = Modules =
|
||||||
async.series call_methods, (error, results) ->
|
async.series call_methods, (error, results) ->
|
||||||
return callback(error) if error?
|
return callback(error) if error?
|
||||||
return callback null, results
|
return callback null, results
|
||||||
|
|
||||||
Modules.loadModules()
|
Modules.loadModules()
|
||||||
|
|
|
@ -78,6 +78,8 @@ div.binary-file.full-size(
|
||||||
|
|
|
|
||||||
| at {{ openFile.created | formatDate:'h:mm a' }} {{ openFile.created | relativeDate }}
|
| at {{ openFile.created | formatDate:'h:mm a' }} {{ openFile.created | relativeDate }}
|
||||||
|
|
||||||
|
!= moduleIncludes("binaryFile:linkedFileInfo", locals)
|
||||||
|
|
||||||
// Bottom Controls
|
// Bottom Controls
|
||||||
span(ng-if="openFile.linkedFileData.provider")
|
span(ng-if="openFile.linkedFileData.provider")
|
||||||
button.btn.btn-success(
|
button.btn.btn-success(
|
||||||
|
@ -95,7 +97,10 @@ div.binary-file.full-size(
|
||||||
i.fa.fa-fw.fa-download
|
i.fa.fa-fw.fa-download
|
||||||
|
|
|
|
||||||
| #{translate("download")}
|
| #{translate("download")}
|
||||||
div(ng-if="refreshError")
|
|
||||||
|
// Refresh Error
|
||||||
|
div(ng-if="refreshError").row
|
||||||
br
|
br
|
||||||
.alert.alert-danger.col-md-6.col-md-offset-3
|
.alert.alert-danger.col-md-6.col-md-offset-3
|
||||||
| Error: {{ refreshError}}
|
| Error: {{ refreshError}}
|
||||||
|
!= moduleIncludes("binaryFile:linkedFileRefreshError", locals)
|
||||||
|
|
|
@ -26,6 +26,8 @@ script(type='text/ng-template', id='newFileModalTemplate')
|
||||||
i.fa.fa-fw.fa-globe
|
i.fa.fa-fw.fa-globe
|
||||||
|
|
|
|
||||||
| From External URL
|
| From External URL
|
||||||
|
!= moduleIncludes("newFileModal:selector", locals)
|
||||||
|
|
||||||
td(class="modal-new-file--body modal-new-file--body-{{type}}")
|
td(class="modal-new-file--body modal-new-file--body-{{type}}")
|
||||||
div(ng-if="type == 'doc'", ng-controller="NewDocModalController")
|
div(ng-if="type == 'doc'", ng-controller="NewDocModalController")
|
||||||
form(novalidate, name="newDocForm")
|
form(novalidate, name="newDocForm")
|
||||||
|
@ -178,6 +180,9 @@ script(type='text/ng-template', id='newFileModalTemplate')
|
||||||
div(ng-switch="error")
|
div(ng-switch="error")
|
||||||
span(ng-switch-when="already exists") #{translate("file_already_exists")}
|
span(ng-switch-when="already exists") #{translate("file_already_exists")}
|
||||||
span(ng-switch-default) {{error}}
|
span(ng-switch-default) {{error}}
|
||||||
|
|
||||||
|
!= moduleIncludes("newFileModal:panel", locals)
|
||||||
|
|
||||||
.modal-footer
|
.modal-footer
|
||||||
button.btn.btn-default(
|
button.btn.btn-default(
|
||||||
ng-disabled="state.inflight"
|
ng-disabled="state.inflight"
|
||||||
|
|
|
@ -17,7 +17,7 @@ services:
|
||||||
PROJECT_HISTORY_ENABLED: 'true'
|
PROJECT_HISTORY_ENABLED: 'true'
|
||||||
ENABLED_LINKED_FILE_TYPES: 'url'
|
ENABLED_LINKED_FILE_TYPES: 'url'
|
||||||
LINKED_URL_PROXY: 'http://localhost:6543'
|
LINKED_URL_PROXY: 'http://localhost:6543'
|
||||||
ENABLED_LINKED_FILE_TYPES: 'url,project_file,project_output_file'
|
ENABLED_LINKED_FILE_TYPES: 'url,project_file,project_output_file,mendeley'
|
||||||
SHARELATEX_CONFIG: /app/test/acceptance/config/settings.test.coffee
|
SHARELATEX_CONFIG: /app/test/acceptance/config/settings.test.coffee
|
||||||
depends_on:
|
depends_on:
|
||||||
- redis
|
- redis
|
||||||
|
|
|
@ -606,19 +606,16 @@ CodeMirror
|
||||||
}
|
}
|
||||||
|
|
||||||
.referencesImportModal {
|
.referencesImportModal {
|
||||||
.referencesImportPreview {
|
.referencesImportPreviewScroller {
|
||||||
margin-top: 15px;
|
font-family: monospace;
|
||||||
.referencesImportPreviewScroller {
|
font-size: 0.8em;
|
||||||
font-family: monospace;
|
max-height: 360px;
|
||||||
font-size: 0.8em;
|
overflow: scroll;
|
||||||
max-height: 360px;
|
white-space: pre;
|
||||||
overflow: scroll;
|
padding: 8px 12px;
|
||||||
white-space: pre;
|
margin-bottom: 15px;
|
||||||
padding: 8px 12px;
|
border: 1px solid @gray-lighter;
|
||||||
margin-bottom: 15px;
|
background-color: @gray-lightest;
|
||||||
border: 1px solid @gray-lighter;
|
|
||||||
background-color: @gray-lightest;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -107,6 +107,7 @@ describe "LinkedFiles", ->
|
||||||
source_project_id: @project_two_id,
|
source_project_id: @project_two_id,
|
||||||
source_entity_path: "/#{@source_doc_name}",
|
source_entity_path: "/#{@source_doc_name}",
|
||||||
}, (error, response, body) =>
|
}, (error, response, body) =>
|
||||||
|
expect(response.statusCode).to.equal 200
|
||||||
new_file_id = body.new_file_id
|
new_file_id = body.new_file_id
|
||||||
@existing_file_id = new_file_id
|
@existing_file_id = new_file_id
|
||||||
expect(new_file_id).to.exist
|
expect(new_file_id).to.exist
|
||||||
|
@ -127,6 +128,7 @@ describe "LinkedFiles", ->
|
||||||
url: "/project/#{@project_one_id}/linked_file/#{@existing_file_id}/refresh",
|
url: "/project/#{@project_one_id}/linked_file/#{@existing_file_id}/refresh",
|
||||||
json: true
|
json: true
|
||||||
}, (error, response, body) =>
|
}, (error, response, body) =>
|
||||||
|
expect(response.statusCode).to.equal 200
|
||||||
new_file_id = body.new_file_id
|
new_file_id = body.new_file_id
|
||||||
expect(new_file_id).to.exist
|
expect(new_file_id).to.exist
|
||||||
expect(new_file_id).to.not.equal @existing_file_id
|
expect(new_file_id).to.not.equal @existing_file_id
|
||||||
|
|
|
@ -32,6 +32,9 @@ class User
|
||||||
get: (callback = (error, user)->) ->
|
get: (callback = (error, user)->) ->
|
||||||
db.users.findOne { _id: ObjectId(@_id) }, callback
|
db.users.findOne { _id: ObjectId(@_id) }, callback
|
||||||
|
|
||||||
|
mongoUpdate: (updateOp, callback=(error)->) ->
|
||||||
|
db.users.update {_id: ObjectId(@_id)}, updateOp, callback
|
||||||
|
|
||||||
register: (callback = (error, user) ->) ->
|
register: (callback = (error, user) ->) ->
|
||||||
return callback(new Error('User already registered')) if @_id?
|
return callback(new Error('User already registered')) if @_id?
|
||||||
@getCsrfToken (error) =>
|
@getCsrfToken (error) =>
|
||||||
|
|
Loading…
Reference in a new issue