diff options
Diffstat (limited to 'core/js/files')
-rw-r--r-- | core/js/files/client.js | 756 | ||||
-rw-r--r-- | core/js/files/fileinfo.js | 138 | ||||
-rw-r--r-- | core/js/files/iedavclient.js | 157 |
3 files changed, 0 insertions, 1051 deletions
diff --git a/core/js/files/client.js b/core/js/files/client.js deleted file mode 100644 index 0bf5a69e19c..00000000000 --- a/core/js/files/client.js +++ /dev/null @@ -1,756 +0,0 @@ -/* - * Copyright (c) 2015 - * - * This file is licensed under the Affero General Public License version 3 - * or later. - * - * See the COPYING-README file. - * - */ - -/* global dav */ - -(function(OC, FileInfo) { - /** - * @class OC.Files.Client - * @classdesc Client to access files on the server - * - * @param {Object} options - * @param {String} options.host host name - * @param {int} [options.port] port - * @param {boolean} [options.useHTTPS] whether to use https - * @param {String} [options.root] root path - * @param {String} [options.userName] user name - * @param {String} [options.password] password - * - * @since 8.2 - */ - var Client = function(options) { - this._root = options.root; - if (this._root.charAt(this._root.length - 1) === '/') { - this._root = this._root.substr(0, this._root.length - 1); - } - - var url = 'http://'; - if (options.useHTTPS) { - url = 'https://'; - } - - url += options.host + this._root; - this._defaultHeaders = options.defaultHeaders || { - 'X-Requested-With': 'XMLHttpRequest', - 'requesttoken': OC.requestToken - }; - this._baseUrl = url; - - var clientOptions = { - baseUrl: this._baseUrl, - xmlNamespaces: { - 'DAV:': 'd', - 'http://owncloud.org/ns': 'oc' - } - }; - if (options.userName) { - clientOptions.userName = options.userName; - } - if (options.password) { - clientOptions.password = options.password; - } - this._client = new dav.Client(clientOptions); - this._client.xhrProvider = _.bind(this._xhrProvider, this); - }; - - Client.NS_OWNCLOUD = 'http://owncloud.org/ns'; - Client.NS_DAV = 'DAV:'; - Client._PROPFIND_PROPERTIES = [ - /** - * Modified time - */ - [Client.NS_DAV, 'getlastmodified'], - /** - * Etag - */ - [Client.NS_DAV, 'getetag'], - /** - * Mime type - */ - [Client.NS_DAV, 'getcontenttype'], - /** - * Resource type "collection" for folders, empty otherwise - */ - [Client.NS_DAV, 'resourcetype'], - /** - * File id - */ - [Client.NS_OWNCLOUD, 'fileid'], - /** - * Letter-coded permissions - */ - [Client.NS_OWNCLOUD, 'permissions'], - //[Client.NS_OWNCLOUD, 'downloadURL'], - /** - * Folder sizes - */ - [Client.NS_OWNCLOUD, 'size'], - /** - * File sizes - */ - [Client.NS_DAV, 'getcontentlength'] - ]; - - /** - * @memberof OC.Files - */ - Client.prototype = { - - /** - * Root path of the Webdav endpoint - * - * @type string - */ - _root: null, - - /** - * Client from the library - * - * @type dav.Client - */ - _client: null, - - /** - * Array of file info parsing functions. - * - * @type Array<OC.Files.Client~parseFileInfo> - */ - _fileInfoParsers: [], - - /** - * Returns the configured XHR provider for davclient - * @return {XMLHttpRequest} - */ - _xhrProvider: function() { - var headers = this._defaultHeaders; - var xhr = new XMLHttpRequest(); - var oldOpen = xhr.open; - // override open() method to add headers - xhr.open = function() { - var result = oldOpen.apply(this, arguments); - _.each(headers, function(value, key) { - xhr.setRequestHeader(key, value); - }); - return result; - }; - - OC.registerXHRForErrorProcessing(xhr); - return xhr; - }, - - /** - * Prepends the base url to the given path sections - * - * @param {...String} path sections - * - * @return {String} base url + joined path, any leading or trailing slash - * will be kept - */ - _buildUrl: function() { - var path = this._buildPath.apply(this, arguments); - if (path.charAt([path.length - 1]) === '/') { - path = path.substr(0, path.length - 1); - } - if (path.charAt(0) === '/') { - path = path.substr(1); - } - return this._baseUrl + '/' + path; - }, - - /** - * Append the path to the root and also encode path - * sections - * - * @param {...String} path sections - * - * @return {String} joined path, any leading or trailing slash - * will be kept - */ - _buildPath: function() { - var path = OC.joinPaths.apply(this, arguments); - var sections = path.split('/'); - var i; - for (i = 0; i < sections.length; i++) { - sections[i] = encodeURIComponent(sections[i]); - } - path = sections.join('/'); - return path; - }, - - /** - * Parse headers string into a map - * - * @param {string} headersString headers list as string - * - * @return {Object.<String,Array>} map of header name to header contents - */ - _parseHeaders: function(headersString) { - var headerRows = headersString.split('\n'); - var headers = {}; - for (var i = 0; i < headerRows.length; i++) { - var sepPos = headerRows[i].indexOf(':'); - if (sepPos < 0) { - continue; - } - - var headerName = headerRows[i].substr(0, sepPos); - var headerValue = headerRows[i].substr(sepPos + 2); - - if (!headers[headerName]) { - // make it an array - headers[headerName] = []; - } - - headers[headerName].push(headerValue); - } - return headers; - }, - - /** - * Parses the etag response which is in double quotes. - * - * @param {string} etag etag value in double quotes - * - * @return {string} etag without double quotes - */ - _parseEtag: function(etag) { - if (etag.charAt(0) === '"') { - return etag.split('"')[1]; - } - return etag; - }, - - /** - * Parse Webdav result - * - * @param {Object} response XML object - * - * @return {Array.<FileInfo>} array of file info - */ - _parseFileInfo: function(response) { - var path = response.href; - if (path.substr(0, this._root.length) === this._root) { - path = path.substr(this._root.length); - } - - if (path.charAt(path.length - 1) === '/') { - path = path.substr(0, path.length - 1); - } - - path = decodeURIComponent(path); - - if (response.propStat.length === 0 || response.propStat[0].status !== 'HTTP/1.1 200 OK') { - return null; - } - - var props = response.propStat[0].properties; - - var data = { - id: props['{' + Client.NS_OWNCLOUD + '}fileid'], - path: OC.dirname(path) || '/', - name: OC.basename(path), - mtime: (new Date(props['{' + Client.NS_DAV + '}getlastmodified'])).getTime() - }; - - var etagProp = props['{' + Client.NS_DAV + '}getetag']; - if (!_.isUndefined(etagProp)) { - data.etag = this._parseEtag(etagProp); - } - - var sizeProp = props['{' + Client.NS_DAV + '}getcontentlength']; - if (!_.isUndefined(sizeProp)) { - data.size = parseInt(sizeProp, 10); - } - - sizeProp = props['{' + Client.NS_OWNCLOUD + '}size']; - if (!_.isUndefined(sizeProp)) { - data.size = parseInt(sizeProp, 10); - } - - var contentType = props['{' + Client.NS_DAV + '}getcontenttype']; - if (!_.isUndefined(contentType)) { - data.mimetype = contentType; - } - - var resType = props['{' + Client.NS_DAV + '}resourcetype']; - var isFile = true; - if (!data.mimetype && resType) { - var xmlvalue = resType[0]; - if (xmlvalue.namespaceURI === Client.NS_DAV && xmlvalue.nodeName.split(':')[1] === 'collection') { - data.mimetype = 'httpd/unix-directory'; - isFile = false; - } - } - - data.permissions = OC.PERMISSION_READ; - var permissionProp = props['{' + Client.NS_OWNCLOUD + '}permissions']; - if (!_.isUndefined(permissionProp)) { - var permString = permissionProp || ''; - data.mountType = null; - for (var i = 0; i < permString.length; i++) { - var c = permString.charAt(i); - switch (c) { - // FIXME: twisted permissions - case 'C': - case 'K': - data.permissions |= OC.PERMISSION_CREATE; - if (!isFile) { - data.permissions |= OC.PERMISSION_UPDATE; - } - break; - case 'W': - data.permissions |= OC.PERMISSION_UPDATE; - break; - case 'D': - data.permissions |= OC.PERMISSION_DELETE; - break; - case 'R': - data.permissions |= OC.PERMISSION_SHARE; - break; - case 'M': - if (!data.mountType) { - // TODO: how to identify external-root ? - data.mountType = 'external'; - } - break; - case 'S': - // TODO: how to identify shared-root ? - data.mountType = 'shared'; - break; - } - } - } - - // extend the parsed data using the custom parsers - _.each(this._fileInfoParsers, function(parserFunction) { - _.extend(data, parserFunction(response) || {}); - }); - - return new FileInfo(data); - }, - - /** - * Parse Webdav multistatus - * - * @param {Array} responses - */ - _parseResult: function(responses) { - var self = this; - return _.map(responses, function(response) { - return self._parseFileInfo(response); - }); - }, - - /** - * Returns whether the given status code means success - * - * @param {int} status status code - * - * @return true if status code is between 200 and 299 included - */ - _isSuccessStatus: function(status) { - return status >= 200 && status <= 299; - }, - - /** - * Returns the default PROPFIND properties to use during a call. - * - * @return {Array.<Object>} array of properties - */ - getPropfindProperties: function() { - if (!this._propfindProperties) { - this._propfindProperties = _.map(Client._PROPFIND_PROPERTIES, function(propDef) { - return '{' + propDef[0] + '}' + propDef[1]; - }); - } - return this._propfindProperties; - }, - - /** - * Lists the contents of a directory - * - * @param {String} path path to retrieve - * @param {Object} [options] options - * @param {boolean} [options.includeParent=false] set to true to keep - * the parent folder in the result list - * @param {Array} [options.properties] list of Webdav properties to retrieve - * - * @return {Promise} promise - */ - getFolderContents: function(path, options) { - if (!path) { - path = ''; - } - options = options || {}; - var self = this; - var deferred = $.Deferred(); - var promise = deferred.promise(); - var properties; - if (_.isUndefined(options.properties)) { - properties = this.getPropfindProperties(); - } else { - properties = options.properties; - } - - this._client.propFind( - this._buildUrl(path), - properties, - 1 - ).then(function(result) { - if (self._isSuccessStatus(result.status)) { - var results = self._parseResult(result.body); - if (!options || !options.includeParent) { - // remove root dir, the first entry - results.shift(); - } - deferred.resolve(result.status, results); - } else { - deferred.reject(result.status); - } - }); - return promise; - }, - - /** - * Fetches a flat list of files filtered by a given filter criteria. - * (currently only system tags is supported) - * - * @param {Object} filter filter criteria - * @param {Object} [filter.systemTagIds] list of system tag ids to filter by - * @param {Object} [options] options - * @param {Array} [options.properties] list of Webdav properties to retrieve - * - * @return {Promise} promise - */ - getFilteredFiles: function(filter, options) { - options = options || {}; - var self = this; - var deferred = $.Deferred(); - var promise = deferred.promise(); - var properties; - if (_.isUndefined(options.properties)) { - properties = this.getPropfindProperties(); - } else { - properties = options.properties; - } - - if (!filter || !filter.systemTagIds || !filter.systemTagIds.length) { - throw 'Missing filter argument'; - } - - // root element with namespaces - var body = '<oc:filter-files '; - var namespace; - for (namespace in this._client.xmlNamespaces) { - body += ' xmlns:' + this._client.xmlNamespaces[namespace] + '="' + namespace + '"'; - } - body += '>\n'; - - // properties query - body += ' <' + this._client.xmlNamespaces['DAV:'] + ':prop>\n'; - _.each(properties, function(prop) { - var property = self._client.parseClarkNotation(prop); - body += ' <' + self._client.xmlNamespaces[property.namespace] + ':' + property.name + ' />\n'; - }); - - body += ' </' + this._client.xmlNamespaces['DAV:'] + ':prop>\n'; - - // rules block - body += ' <oc:filter-rules>\n'; - _.each(filter.systemTagIds, function(systemTagIds) { - body += ' <oc:systemtag>' + escapeHTML(systemTagIds) + '</oc:systemtag>\n'; - }); - body += ' </oc:filter-rules>\n'; - - // end of root - body += '</oc:filter-files>\n'; - - this._client.request( - 'REPORT', - this._buildUrl(), - {}, - body - ).then(function(result) { - if (self._isSuccessStatus(result.status)) { - var results = self._parseResult(result.body); - deferred.resolve(result.status, results); - } else { - deferred.reject(result.status); - } - }); - return promise; - }, - - /** - * Returns the file info of a given path. - * - * @param {String} path path - * @param {Array} [options.properties] list of Webdav properties to retrieve - * - * @return {Promise} promise - */ - getFileInfo: function(path, options) { - if (!path) { - path = ''; - } - options = options || {}; - var self = this; - var deferred = $.Deferred(); - var promise = deferred.promise(); - var properties; - if (_.isUndefined(options.properties)) { - properties = this.getPropfindProperties(); - } else { - properties = options.properties; - } - - // TODO: headers - this._client.propFind( - this._buildUrl(path), - properties, - 0 - ).then( - function(result) { - if (self._isSuccessStatus(result.status)) { - deferred.resolve(result.status, self._parseResult([result.body])[0]); - } else { - deferred.reject(result.status); - } - } - ); - return promise; - }, - - /** - * Returns the contents of the given file. - * - * @param {String} path path to file - * - * @return {Promise} - */ - getFileContents: function(path) { - if (!path) { - throw 'Missing argument "path"'; - } - var self = this; - var deferred = $.Deferred(); - var promise = deferred.promise(); - - this._client.request( - 'GET', - this._buildUrl(path) - ).then( - function(result) { - if (self._isSuccessStatus(result.status)) { - deferred.resolve(result.status, result.body); - } else { - deferred.reject(result.status); - } - } - ); - return promise; - }, - - /** - * Puts the given data into the given file. - * - * @param {String} path path to file - * @param {String} body file body - * @param {Object} [options] - * @param {String} [options.contentType='text/plain'] content type - * @param {bool} [options.overwrite=true] whether to overwrite an existing file - * - * @return {Promise} - */ - putFileContents: function(path, body, options) { - if (!path) { - throw 'Missing argument "path"'; - } - var self = this; - var deferred = $.Deferred(); - var promise = deferred.promise(); - options = options || {}; - var headers = {}; - var contentType = 'text/plain;charset=utf-8'; - if (options.contentType) { - contentType = options.contentType; - } - - headers['Content-Type'] = contentType; - - if (_.isUndefined(options.overwrite) || options.overwrite) { - // will trigger 412 precondition failed if a file already exists - headers['If-None-Match'] = '*'; - } - - this._client.request( - 'PUT', - this._buildUrl(path), - headers, - body || '' - ).then( - function(result) { - if (self._isSuccessStatus(result.status)) { - deferred.resolve(result.status); - } else { - deferred.reject(result.status); - } - } - ); - return promise; - }, - - _simpleCall: function(method, path) { - if (!path) { - throw 'Missing argument "path"'; - } - - var self = this; - var deferred = $.Deferred(); - var promise = deferred.promise(); - - this._client.request( - method, - this._buildUrl(path) - ).then( - function(result) { - if (self._isSuccessStatus(result.status)) { - deferred.resolve(result.status); - } else { - deferred.reject(result.status); - } - } - ); - return promise; - }, - - /** - * Creates a directory - * - * @param {String} path path to create - * - * @return {Promise} - */ - createDirectory: function(path) { - return this._simpleCall('MKCOL', path); - }, - - /** - * Deletes a file or directory - * - * @param {String} path path to delete - * - * @return {Promise} - */ - remove: function(path) { - return this._simpleCall('DELETE', path); - }, - - /** - * Moves path to another path - * - * @param {String} path path to move - * @param {String} destinationPath destination path - * @param {boolean} [allowOverwrite=false] true to allow overwriting, - * false otherwise - * - * @return {Promise} promise - */ - move: function(path, destinationPath, allowOverwrite) { - if (!path) { - throw 'Missing argument "path"'; - } - if (!destinationPath) { - throw 'Missing argument "destinationPath"'; - } - - var self = this; - var deferred = $.Deferred(); - var promise = deferred.promise(); - var headers = { - 'Destination' : this._buildUrl(destinationPath) - }; - - if (!allowOverwrite) { - headers['Overwrite'] = 'F'; - } - - this._client.request( - 'MOVE', - this._buildUrl(path), - headers - ).then( - function(response) { - if (self._isSuccessStatus(response.status)) { - deferred.resolve(response.status); - } else { - deferred.reject(response.status); - } - } - ); - return promise; - }, - - /** - * Add a file info parser function - * - * @param {OC.Files.Client~parseFileInfo>} - */ - addFileInfoParser: function(parserFunction) { - this._fileInfoParsers.push(parserFunction); - } - - }; - - /** - * File info parser function - * - * This function receives a list of Webdav properties as input and - * should return a hash array of parsed properties, if applicable. - * - * @callback OC.Files.Client~parseFileInfo - * @param {Object} XML Webdav properties - * @return {Array} array of parsed property values - */ - - if (!OC.Files) { - /** - * @namespace OC.Files - * - * @since 8.2 - */ - OC.Files = {}; - } - - /** - * Returns the default instance of the files client - * - * @return {OC.Files.Client} default client - * - * @since 8.2 - */ - OC.Files.getClient = function() { - if (OC.Files._defaultClient) { - return OC.Files._defaultClient; - } - - var client = new OC.Files.Client({ - host: OC.getHost(), - port: OC.getPort(), - root: OC.linkToRemoteBase('webdav'), - useHTTPS: OC.getProtocol() === 'https' - }); - OC.Files._defaultClient = client; - return client; - }; - - OC.Files.Client = Client; -})(OC, OC.Files.FileInfo); - diff --git a/core/js/files/fileinfo.js b/core/js/files/fileinfo.js deleted file mode 100644 index 3bf68d88b15..00000000000 --- a/core/js/files/fileinfo.js +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2015 - * - * This file is licensed under the Affero General Public License version 3 - * or later. - * - * See the COPYING-README file. - * - */ - -(function(OC) { - - /** - * @class OC.Files.FileInfo - * @classdesc File information - * - * @param {Object} data file data, see attributes for details - * - * @since 8.2 - */ - var FileInfo = function(data) { - var self = this; - _.each(data, function(value, key) { - if (!_.isFunction(value)) { - self[key] = value; - } - }); - - if (!_.isUndefined(this.id)) { - this.id = parseInt(data.id, 10); - } - - // TODO: normalize path - this.path = data.path || ''; - - if (this.type === 'dir') { - this.mimetype = 'httpd/unix-directory'; - } else { - this.mimetype = this.mimetype || 'application/octet-stream'; - } - - if (!this.type) { - if (this.mimetype === 'httpd/unix-directory') { - this.type = 'dir'; - } else { - this.type = 'file'; - } - } - }; - - /** - * @memberof OC.Files - */ - FileInfo.prototype = { - /** - * File id - * - * @type int - */ - id: null, - - /** - * File name - * - * @type String - */ - name: null, - - /** - * Path leading to the file, without the file name, - * and with a leading slash. - * - * @type String - */ - path: null, - - /** - * Mime type - * - * @type String - */ - mimetype: null, - - /** - * Icon URL. - * - * Can be used to override the mime type icon. - * - * @type String - */ - icon: null, - - /** - * File type. 'file' for files, 'dir' for directories. - * - * @type String - * @deprecated rely on mimetype instead - */ - type: null, - - /** - * Permissions. - * - * @see OC#PERMISSION_ALL for permissions - * @type int - */ - permissions: null, - - /** - * Modification time - * - * @type int - */ - mtime: null, - - /** - * Etag - * - * @type String - */ - etag: null, - - /** - * Mount type. - * - * One of null, "external-root", "shared" or "shared-root" - * - * @type string - */ - mountType: null - }; - - if (!OC.Files) { - OC.Files = {}; - } - OC.Files.FileInfo = FileInfo; -})(OC); - diff --git a/core/js/files/iedavclient.js b/core/js/files/iedavclient.js deleted file mode 100644 index 9e83f5b9a22..00000000000 --- a/core/js/files/iedavclient.js +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2015 - * - * This file is licensed under the Affero General Public License version 3 - * or later. - * - * See the COPYING-README file. - * - */ - -/* global dav */ -(function(dav) { - - /** - * Override davclient.js methods with IE-compatible logic - */ - dav.Client.prototype = _.extend({}, dav.Client.prototype, { - - /** - * Performs a HTTP request, and returns a Promise - * - * @param {string} method HTTP method - * @param {string} url Relative or absolute url - * @param {Object} headers HTTP headers as an object. - * @param {string} body HTTP request body. - * @return {Promise} - */ - request : function(method, url, headers, body) { - - var self = this; - var xhr = this.xhrProvider(); - - if (this.userName) { - headers['Authorization'] = 'Basic ' + btoa(this.userName + ':' + this.password); - // xhr.open(method, this.resolveUrl(url), true, this.userName, this.password); - } - xhr.open(method, this.resolveUrl(url), true); - var ii; - for(ii in headers) { - xhr.setRequestHeader(ii, headers[ii]); - } - - if (body === undefined) { - xhr.send(); - } else { - xhr.send(body); - } - - return new Promise(function(fulfill, reject) { - - xhr.onreadystatechange = function() { - - if (xhr.readyState !== 4) { - return; - } - - var resultBody = xhr.response; - if (xhr.status === 207) { - resultBody = self.parseMultiStatus(xhr.responseXML); - } - - fulfill({ - body: resultBody, - status: xhr.status, - xhr: xhr - }); - - }; - - xhr.ontimeout = function() { - - reject(new Error('Timeout exceeded')); - - }; - - }); - - }, - - _getElementsByTagName: function(node, name, resolver) { - var parts = name.split(':'); - var tagName = parts[1]; - var namespace = resolver(parts[0]); - if (node.getElementsByTagNameNS) { - return node.getElementsByTagNameNS(namespace, tagName); - } - return node.getElementsByTagName(name); - }, - - /** - * Parses a multi-status response body. - * - * @param {string} xmlBody - * @param {Array} - */ - parseMultiStatus : function(doc) { - var result = []; - var resolver = function(foo) { - var ii; - for(ii in this.xmlNamespaces) { - if (this.xmlNamespaces[ii] === foo) { - return ii; - } - } - }.bind(this); - - var responses = this._getElementsByTagName(doc, 'd:response', resolver); - var i; - for (i = 0; i < responses.length; i++) { - var responseNode = responses[i]; - var response = { - href : null, - propStat : [] - }; - - var hrefNode = this._getElementsByTagName(responseNode, 'd:href', resolver)[0]; - - response.href = hrefNode.textContent || hrefNode.text; - - var propStatNodes = this._getElementsByTagName(responseNode, 'd:propstat', resolver); - var j = 0; - - for (j = 0; j < propStatNodes.length; j++) { - var propStatNode = propStatNodes[j]; - var statusNode = this._getElementsByTagName(propStatNode, 'd:status', resolver)[0]; - - var propStat = { - status : statusNode.textContent || statusNode.text, - properties : [] - }; - - var propNode = this._getElementsByTagName(propStatNode, 'd:prop', resolver)[0]; - if (!propNode) { - continue; - } - var k = 0; - for (k = 0; k < propNode.childNodes.length; k++) { - var prop = propNode.childNodes[k]; - var value = this._parsePropNode(prop); - propStat.properties['{' + prop.namespaceURI + '}' + (prop.localName || prop.baseName)] = value; - - } - response.propStat.push(propStat); - } - - result.push(response); - } - - return result; - - } - - - }); - -})(dav); - |