Linked files from Mendeley.

This commit is contained in:
Shane Kilkelly 2018-06-26 10:15:45 +01:00
parent d411f960ff
commit b32c9be8ca
9 changed files with 95 additions and 27 deletions

View file

@ -6,7 +6,6 @@ logger = require 'logger-sharelatex'
_ = require 'underscore'
LinkedFilesHandler = require './LinkedFilesHandler'
{
UrlFetchFailedError,
InvalidUrlError,
OutputFileFetchFailedError,
@ -16,16 +15,23 @@ LinkedFilesHandler = require './LinkedFilesHandler'
ProjectNotFoundError,
V1ProjectNotFoundError,
SourceFileNotFoundError,
NotOriginalImporterError,
FeatureNotAvailableError,
RemoteServiceError
} = require './LinkedFilesErrors'
Modules = require '../../infrastructure/Modules'
module.exports = LinkedFilesController = {
Agents: {
url: require('./UrlAgent'),
project_file: require('./ProjectFileAgent'),
project_output_file: require('./ProjectOutputFileAgent')
}
Agents: _.extend(
{
url: require('./UrlAgent'),
project_file: require('./ProjectFileAgent'),
project_output_file: require('./ProjectOutputFileAgent'),
},
Modules.linkedFileAgentsIncludes()
)
_getAgent: (provider) ->
if !LinkedFilesController.Agents.hasOwnProperty(provider)
@ -117,6 +123,22 @@ module.exports = LinkedFilesController = {
"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
next(error)
}

View file

@ -70,6 +70,30 @@ SourceFileNotFoundError = (message) ->
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 = {
UrlFetchFailedError,
@ -81,4 +105,7 @@ module.exports = {
ProjectNotFoundError,
V1ProjectNotFoundError,
SourceFileNotFoundError,
NotOriginalImporterError,
FeatureNotAvailableError,
RemoteServiceError
}

View file

@ -23,7 +23,7 @@ module.exports = Modules =
for module in @modules
module.nonCsrfRouter?.apply(webRouter, privateApiRouter, publicApiRouter)
module.router?.applyNonCsrfRouter?(webRouter, privateApiRouter, publicApiRouter)
viewIncludes: {}
loadViewIncludes: (app) ->
@viewIncludes = {}
@ -32,7 +32,7 @@ module.exports = Modules =
@viewIncludes[view] ||= []
filePath = Path.join(MODULE_BASE_PATH, module.name, "app/views", partial + ".pug")
@viewIncludes[view].push pug.compileFile(filePath, doctype: "html")
moduleIncludes: (view, locals) ->
compiledPartials = Modules.viewIncludes[view] or []
html = ""
@ -43,7 +43,7 @@ module.exports = Modules =
moduleIncludesAvailable: (view) ->
return (Modules.viewIncludes[view] or []).length > 0
moduleAssetFiles: (pathPrefix) ->
assetFiles = []
for module in @modules
@ -51,18 +51,25 @@ module.exports = Modules =
assetFiles.push "#{pathPrefix}#{assetFile}"
return assetFiles
linkedFileAgentsIncludes: () ->
agents = {}
for module in @modules
for name, agentFunction of module.linkedFileAgents
agents[name] = agentFunction()
return agents
attachHooks: () ->
for module in @modules
if module.hooks?
for hook, method of module.hooks
Modules.hooks.attach hook, method
hooks:
_hooks: {}
attach: (name, method) ->
@_hooks[name] ?= []
@_hooks[name].push method
fire: (name, args..., callback) ->
methods = @_hooks[name] or []
call_methods = methods.map (method) ->
@ -70,5 +77,5 @@ module.exports = Modules =
async.series call_methods, (error, results) ->
return callback(error) if error?
return callback null, results
Modules.loadModules()

View file

@ -78,6 +78,8 @@ div.binary-file.full-size(
|
| at {{ openFile.created | formatDate:'h:mm a' }} {{ openFile.created | relativeDate }}
!= moduleIncludes("binaryFile:linkedFileInfo", locals)
// Bottom Controls
span(ng-if="openFile.linkedFileData.provider")
button.btn.btn-success(
@ -95,7 +97,10 @@ div.binary-file.full-size(
i.fa.fa-fw.fa-download
|
| #{translate("download")}
div(ng-if="refreshError")
// Refresh Error
div(ng-if="refreshError").row
br
.alert.alert-danger.col-md-6.col-md-offset-3
| Error: {{ refreshError}}
!= moduleIncludes("binaryFile:linkedFileRefreshError", locals)

View file

@ -26,6 +26,8 @@ script(type='text/ng-template', id='newFileModalTemplate')
i.fa.fa-fw.fa-globe
|
| From External URL
!= moduleIncludes("newFileModal:selector", locals)
td(class="modal-new-file--body modal-new-file--body-{{type}}")
div(ng-if="type == 'doc'", ng-controller="NewDocModalController")
form(novalidate, name="newDocForm")
@ -175,6 +177,9 @@ script(type='text/ng-template', id='newFileModalTemplate')
div(ng-switch="error")
span(ng-switch-when="already exists") #{translate("file_already_exists")}
span(ng-switch-default) {{error}}
!= moduleIncludes("newFileModal:panel", locals)
.modal-footer
button.btn.btn-default(
ng-disabled="state.inflight"

View file

@ -17,7 +17,7 @@ services:
PROJECT_HISTORY_ENABLED: 'true'
ENABLED_LINKED_FILE_TYPES: 'url'
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
depends_on:
- redis

View file

@ -606,19 +606,16 @@ CodeMirror
}
.referencesImportModal {
.referencesImportPreview {
margin-top: 15px;
.referencesImportPreviewScroller {
font-family: monospace;
font-size: 0.8em;
max-height: 360px;
overflow: scroll;
white-space: pre;
padding: 8px 12px;
margin-bottom: 15px;
border: 1px solid @gray-lighter;
background-color: @gray-lightest;
}
.referencesImportPreviewScroller {
font-family: monospace;
font-size: 0.8em;
max-height: 360px;
overflow: scroll;
white-space: pre;
padding: 8px 12px;
margin-bottom: 15px;
border: 1px solid @gray-lighter;
background-color: @gray-lightest;
}
}

View file

@ -107,6 +107,7 @@ describe "LinkedFiles", ->
source_project_id: @project_two_id,
source_entity_path: "/#{@source_doc_name}",
}, (error, response, body) =>
expect(response.statusCode).to.equal 200
new_file_id = body.new_file_id
@existing_file_id = new_file_id
expect(new_file_id).to.exist
@ -127,6 +128,7 @@ describe "LinkedFiles", ->
url: "/project/#{@project_one_id}/linked_file/#{@existing_file_id}/refresh",
json: true
}, (error, response, body) =>
expect(response.statusCode).to.equal 200
new_file_id = body.new_file_id
expect(new_file_id).to.exist
expect(new_file_id).to.not.equal @existing_file_id

View file

@ -32,6 +32,9 @@ class User
get: (callback = (error, user)->) ->
db.users.findOne { _id: ObjectId(@_id) }, callback
mongoUpdate: (updateOp, callback=(error)->) ->
db.users.update {_id: ObjectId(@_id)}, updateOp, callback
register: (callback = (error, user) ->) ->
return callback(new Error('User already registered')) if @_id?
@getCsrfToken (error) =>