From 3743aceb3130bddd988c47f4c61522dd010074e9 Mon Sep 17 00:00:00 2001 From: Martin Wendt Date: Mon, 13 Aug 2018 15:11:56 +0200 Subject: [PATCH] Cleanup --- doc/sample_wsgidav.conf | 2 - sample_wsgidav.yaml | 7 - wsgidav.conf | 3 +- wsgidav/addons/dir_browser/__init__.py | 8 +- wsgidav/addons/dir_browser/htdocs/script.js | 71 +- ...der.py.8eb0d6b5bff31a093fe4427eb7319dcf.py | 628 ------------------ wsgidav/server/server_cli.py | 2 + 7 files changed, 18 insertions(+), 703 deletions(-) delete mode 100644 wsgidav/addons/hg_dav_provider.py.8eb0d6b5bff31a093fe4427eb7319dcf.py diff --git a/doc/sample_wsgidav.conf b/doc/sample_wsgidav.conf index c45c7b5e..61d1bf74 100644 --- a/doc/sample_wsgidav.conf +++ b/doc/sample_wsgidav.conf @@ -151,8 +151,6 @@ dir_browser = { "davmount": False, # Send response if request URL contains '?davmount' "ms_mount": False, # Add an 'open as webfolder' link (requires Windows) "ms_sharepoint_support": True, # Invoke MS Offce documents for editing using WebDAV - ; "ms_sharepoint_plugin": False, # Invoke MS Offce documents for editing using WebDAV - ; "ms_sharepoint_urls": False, # Prepend 'ms-word:ofe|u|' to URL for MS Offce documents # "app_class": MyBrowser, # (DEPRECATED with 2.4.0) Used instead of WsgiDavDirBrowser } diff --git a/sample_wsgidav.yaml b/sample_wsgidav.yaml index 479c9c78..e50f6d32 100644 --- a/sample_wsgidav.yaml +++ b/sample_wsgidav.yaml @@ -161,13 +161,6 @@ dir_browser: #: https://docs.microsoft.com/en-us/previous-versions/office/developer/sharepoint-2010/ff407576(v%3Doffice.14) #: - Otherwise the Office URL prefix is used (e.g. 'ms-word:ofe|u|http://server/path/file.docx') ms_sharepoint_support: true - # #: Invoke MS Office documents for editing using WebDAV by adding JavaScript - # #: code that invokes the SharePoint plugin ActiveXObject("SharePoint.OpenDocuments") - # #: (Requires MS IE 8-11, but not Edge) - # ms_sharepoint_plugin: false - # #: Prepend 'ms-word:ofe|u|' to URLs for MS Office documents - # #: (This option is ignored if ms_sharepoint_plugin is true.) - # ms_sharepoint_urls: false # ---------------------------------------------------------------------------- diff --git a/wsgidav.conf b/wsgidav.conf index e109ec58..b586fa76 100644 --- a/wsgidav.conf +++ b/wsgidav.conf @@ -77,8 +77,7 @@ dir_browser = { "response_trailer": "", # Raw HTML code, appended as footer "davmount": True, # Send response if request URL contains '?davmount' "ms_mount": True, # Add an 'open as webfolder' link (requires Windows) - "ms_sharepoint_plugin": True, # Invoke MS Offce documents for editing using WebDAV - "ms_sharepoint_urls": False, # Prepend 'ms-word:ofe|u|' to URL for MS Offce documents + "ms_sharepoint_support": True, # Invoke MS Offce documents for editing using WebDAV } diff --git a/wsgidav/addons/dir_browser/__init__.py b/wsgidav/addons/dir_browser/__init__.py index c62c98cd..e312f36e 100644 --- a/wsgidav/addons/dir_browser/__init__.py +++ b/wsgidav/addons/dir_browser/__init__.py @@ -186,10 +186,10 @@ def _get_context(self, environ, davres): if dirConfig.get("ms_sharepoint_support"): ofe_prefix = "ms-{}:ofe|u|".format(officeType) a_classes.append("msoffice") - elif dirConfig.get("ms_sharepoint_plugin"): - a_classes.append("msoffice") - elif dirConfig.get("ms_sharepoint_urls"): - href = "ms-{}:ofe|u|{}".format(officeType, href) + # elif dirConfig.get("ms_sharepoint_plugin"): + # a_classes.append("msoffice") + # elif dirConfig.get("ms_sharepoint_urls"): + # href = "ms-{}:ofe|u|{}".format(officeType, href) entry = { "href": href, diff --git a/wsgidav/addons/dir_browser/htdocs/script.js b/wsgidav/addons/dir_browser/htdocs/script.js index 94713c83..07a6d20a 100644 --- a/wsgidav/addons/dir_browser/htdocs/script.js +++ b/wsgidav/addons/dir_browser/htdocs/script.js @@ -7,7 +7,9 @@ function onLoad() { /** + * Find (and cache) an available ActiveXObject Sharepoint plugin. * + * @returns {ActiveXObject} or null */ function getSharePointPlugin() { if( sharePointPlugin !== undefined ) { @@ -31,7 +33,7 @@ function getSharePointPlugin() { try { plugin = new ActiveXObject("SharePoint.OpenDocuments.1"); // Office 2000/XP } catch(e3) { - window.console && console.warn("Could not create ActiveXObject('SharePoint.OpenDocuments'): (requires IE <= 11 and check security settings."); + window.console && console.warn("Could not create ActiveXObject('SharePoint.OpenDocuments'): (requires IE <= 11 and matching security settings."); } } } @@ -45,25 +47,18 @@ function getSharePointPlugin() { /** + * Open an MS Office document either with SharePoint plugin or using the 'ms-' URL prefix. * * @param {object} opts + * @returns {boolean} true if the URL could be opened */ function openWebDavDocument(opts) { - var //webDavPath = opts.webDavPath, - // URL with a prefix like '' - ofe_link = opts.ofe + opts.href, // (e.g. 'ms-word:ofe|u|http://server/path/file.docx') + var ofe_link = opts.ofe + opts.href, // (e.g. 'ms-word:ofe|u|http://server/path/file.docx') url = opts.href; - // url = window.location.protocol + "//" + window.location.host + opts.href; - // webDavPlugin = document.getElementById("winFirefoxPlugin"), - // fileExt = opts.fileName.split(".").pop(), - // errorMsg = "Could not open '" + webDavPath + "'. check MS Office installation and security settings."; - // errorMsg = getContext("msg_could_not_open_document_make_sure_program_for_file_type_installed_fmt").replace("{file_ext}", fileExt); var plugin = getSharePointPlugin(); var res = false; - alert("url " + url + ", " + ofe_link) - if( plugin ) { try { res = plugin.EditDocument(url); @@ -78,60 +73,16 @@ function openWebDavDocument(opts) { if( ofe_link ) { window.console && console.log("Could not use SharePoint plugin: trying " + ofe_link); window.open(ofe_link, "_self"); - return false; + res = true; } } return res; } -// /** -// * -// * @param {*} url -// */ -// function openWithSharePointPlugin(url) { -// var res = false, -// control = null, -// isFF = false; - -// // Get the most recent version of the SharePoint plugin -// if( "ActiveXObject" in window ){ -// try { -// control = new ActiveXObject("SharePoint.OpenDocuments.3"); // Office 2007+ -// } catch(e) { -// try { -// control = new ActiveXObject("SharePoint.OpenDocuments.2"); // Office 2003 -// } catch(e2) { -// try { -// control = new ActiveXObject("SharePoint.OpenDocuments.1"); // Office 2000/XP -// } catch(e3) { -// window.console && console.warn("Could not create ActiveXObject('SharePoint.OpenDocuments'). Check your browsers security settings."); -// return false; -// } -// } -// } -// if( !control ){ -// window.console && console.warn("Cannot instantiate the required ActiveX control to open the document. This is most likely because you do not have Office installed or you have an older version of Office."); -// } -// } else { -// window.console && console.warn("Non-IE: trying FFWinPlugin Plug-in..."); -// control = document.getElementById("winFirefoxPlugin"); -// isFF = true; -// } - -// try { -// res = control.EditDocument(url); -// if( !res ){ -// window.console && console.warn("SharePoint.OpenDocuments.EditDocument('" + url + "') returned false."); -// } -// } catch (e){ -// window.console && console.warn("SharePoint.OpenDocuments.EditDocument('" + url + "') failed.", e); -// } -// return res; -// } - - -/* Event delegation handler for clicks on a-tags with class 'msoffice'. */ +/** + * Event delegation handler for clicks on a-tags with class 'msoffice'. + */ function onClickTable(event) { var target = event.target || event.srcElement, opts = { @@ -141,7 +92,7 @@ function onClickTable(event) { if( target.className === "msoffice" ){ if( openWebDavDocument(opts) ){ - // prevent default processing + // prevent default processing if the document could be opened return false; } } diff --git a/wsgidav/addons/hg_dav_provider.py.8eb0d6b5bff31a093fe4427eb7319dcf.py b/wsgidav/addons/hg_dav_provider.py.8eb0d6b5bff31a093fe4427eb7319dcf.py deleted file mode 100644 index 6f19eea9..00000000 --- a/wsgidav/addons/hg_dav_provider.py.8eb0d6b5bff31a093fe4427eb7319dcf.py +++ /dev/null @@ -1,628 +0,0 @@ -# -*- coding: utf-8 -*- -# (c) 2009-2018 Martin Wendt and contributors; see WsgiDAV https://github.com/mar10/wsgidav -# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php -""" -DAV provider that publishes a Mercurial repository. - -Note: This is **not** production code! - -The repository is rendered as three top level collections. - -edit: - Contains the working directory, i.e. all files. This includes uncommitted - changes and untracked new files. - This folder is writable. -released: - Contains the latest committed files, also known as 'tip'. - This folder is read-only. -archive: - Contains the last 10 revisions as sub-folders. - This folder is read-only. - -Sample layout:: - - // - edit/ - server/ - ext_server.py - README.txt - released/ - archive/ - 19/ - 18/ - ... - -Supported features: - -#. Copying or moving files from ``/edit/..`` to the ``/edit/..`` folder will - result in a ``hg copy`` or ``hg rename``. -#. Deleting resources from ``/edit/..`` will result in a ``hg remove``. -#. Copying or moving files from ``/edit/..`` to the ``/released`` folder will - result in a ``hg commit``. - Note that the destination path is ignored, instead the source path is used. - So a user can drag a file or folder from somewhere under the ``edit/..`` - directory and drop it directly on the ``released`` directory to commit - changes. -#. To commit all changes, simply drag'n'drop the ``/edit`` folder on the - ``/released`` folder. -#. Creating new collections results in creation of a file called ``.directory``, - which is then ``hg add`` ed since Mercurial doesn't track directories. -#. Some attributes are published as live properties, such as ``{hg:}date``. - - -Known limitations: - -#. This 'commit by drag-and-drop' only works, if the WebDAV clients produces - MOVE or COPY requests. Alas, some clients will send PUT, MKCOL, ... sequences - instead. -#. Adding and then removing a file without committing after the 'add' will - leave this file on disk (untracked) - This happens for example whit lock files that Open Office Write and other - applications will create. -#. Dragging the 'edit' folder onto 'released' with Windows File Explorer will - remove the folder in the explorer view, although WsgiDAV did not delete it. - This seems to be done by the client. - - -See: - http://mercurial.selenic.com/wiki/MercurialApi -Requirements: - ``easy_install mercurial`` or install the API as non-standalone version - from here: http://mercurial.berkwood.com/ - http://mercurial.berkwood.com/binaries/mercurial-1.4.win32-py2.6.exe -""" -from __future__ import print_function - -import os -import sys -import time -from hashlib import md5 -from pprint import pprint - -from wsgidav import compat, util -from wsgidav.dav_error import HTTP_FORBIDDEN, DAVError -from wsgidav.dav_provider import DAVProvider, _DAVResource -from wsgidav.samples.dav_provider_tools import VirtualCollection - -try: - import mercurial.ui - from mercurial.__version__ import version as hgversion - from mercurial import commands, hg - - # from mercurial import util as hgutil -except ImportError: - print( - "Could not import Mercurial API. Try 'easy_install -U mercurial'.", - file=sys.stderr, - ) - raise - -__docformat__ = "reStructuredText en" - -_logger = util.get_module_logger(__name__) - -BUFFER_SIZE = 8192 - - -# ============================================================================ -# HgResource -# ============================================================================ -class HgResource(_DAVResource): - """Abstract base class for all resources.""" - - def __init__(self, path, is_collection, environ, rev, localHgPath): - super(HgResource, self).__init__(path, is_collection, environ) - self.rev = rev - self.localHgPath = localHgPath - self.absFilePath = self._getFilePath() - assert "\\" not in self.localHgPath - assert "/" not in self.absFilePath - - if is_collection: - self.fctx = None - else: - # Change Context for the requested revision: - # rev=None: current working dir - # rev="tip": TIP - # rev=: Revision ID - wdctx = self.provider.repo[self.rev] - self.fctx = wdctx[self.localHgPath] - - # util.status("HgResource: path=%s, rev=%s, localHgPath=%s, fctx=%s" % ( - # self.path, self.rev, self.localHgPath, self.fctx)) - # util.status("HgResource: name=%s, dn=%s, abspath=%s" % ( - # self.name, self.get_display_name(), self.absFilePath)) - - def _getFilePath(self, *addParts): - parts = self.localHgPath.split("/") - if addParts: - parts.extend(addParts) - return os.path.join(self.provider.repo.root, *parts) - - def _commit(self, message): - user = self.environ.get("http_authenticator.username") or "Anonymous" - commands.commit( - self.provider.ui, - self.provider.repo, - self.localHgPath, - addremove=True, - user=user, - message=message, - ) - - def _check_write_access(self): - """Raise HTTP_FORBIDDEN, if resource is unwritable.""" - if self.rev is not None: - # Only working directory may be edited - raise DAVError(HTTP_FORBIDDEN) - - def get_content_length(self): - if self.is_collection: - return None - return self.fctx.size() - - def get_content_type(self): - if self.is_collection: - return None - # (mimetype, _mimeencoding) = mimetypes.guess_type(self.path) - # if not mimetype: - # return "application/octet-stream" - # return mimetype - return util.guess_mime_type(self.path) - - def get_creation_date(self): - # statresults = os.stat(self._filePath) - # return statresults[stat.ST_CTIME] - return None # TODO - - def get_display_name(self): - if self.is_collection or self.fctx.filerev() is None: - return self.name - return "%s@%s" % (self.name, self.fctx.filerev()) - - def get_etag(self): - return ( - md5(self.path).hexdigest() - + "-" - + compat.to_native(self.get_last_modified()) - + "-" - + str(self.get_content_length()) - ) - - def get_last_modified(self): - if self.is_collection: - return None - # (secs, tz-ofs) - return self.fctx.date()[0] - - def support_ranges(self): - return False - - def get_member_names(self): - assert self.is_collection - cache = self.environ["wsgidav.hg.cache"][compat.to_native(self.rev)] - dirinfos = cache["dirinfos"] - if self.localHgPath not in dirinfos: - return [] - return dirinfos[self.localHgPath][0] + dirinfos[self.localHgPath][1] - - # return self.provider._listMembers(self.path) - - def get_member(self, name): - # Rely on provider to get member oinstances - assert self.is_collection - return self.provider.get_resource_inst( - util.join_uri(self.path, name), self.environ - ) - - def get_display_info(self): - if self.is_collection: - return {"type": "Directory"} - return {"type": "File"} - - def get_property_names(self, isAllProp): - """Return list of supported property names in Clark Notation. - - See DAVResource.get_property_names() - """ - # Let base class implementation add supported live and dead properties - propNameList = super(HgResource, self).get_property_names(isAllProp) - # Add custom live properties (report on 'allprop' and 'propnames') - if self.fctx: - propNameList.extend( - [ - "{hg:}branch", - "{hg:}date", - "{hg:}description", - "{hg:}filerev", - "{hg:}rev", - "{hg:}user", - ] - ) - return propNameList - - def get_property_value(self, propname): - """Return the value of a property. - - See get_property_value() - """ - # Supported custom live properties - if propname == "{hg:}branch": - return self.fctx.branch() - elif propname == "{hg:}date": - # (secs, tz-ofs) - return compat.to_native(self.fctx.date()[0]) - elif propname == "{hg:}description": - return self.fctx.description() - elif propname == "{hg:}filerev": - return compat.to_native(self.fctx.filerev()) - elif propname == "{hg:}rev": - return compat.to_native(self.fctx.rev()) - elif propname == "{hg:}user": - return compat.to_native(self.fctx.user()) - - # Let base class implementation report live and dead properties - return super(HgResource, self).get_property_value(propname) - - def set_property_value(self, propname, value, dryRun=False): - """Set or remove property value. - - See DAVResource.set_property_value() - """ - raise DAVError(HTTP_FORBIDDEN) - - def prevent_locking(self): - """Return True, to prevent locking. - - See prevent_locking() - """ - if self.rev is not None: - # Only working directory may be locked - return True - return False - - def create_empty_resource(self, name): - """Create and return an empty (length-0) resource as member of self. - - See DAVResource.create_empty_resource() - """ - assert self.is_collection - self._check_write_access() - filepath = self._getFilePath(name) - f = open(filepath, "w") - f.close() - commands.add(self.provider.ui, self.provider.repo, filepath) - # get_resource_inst() won't work, because the cached manifest is outdated - # return self.provider.get_resource_inst(self.path.rstrip("/")+"/"+name, self.environ) - return HgResource( - self.path.rstrip("/") + "/" + name, - False, - self.environ, - self.rev, - self.localHgPath + "/" + name, - ) - - def create_collection(self, name): - """Create a new collection as member of self. - - A dummy member is created, because Mercurial doesn't handle folders. - """ - assert self.is_collection - self._check_write_access() - collpath = self._getFilePath(name) - os.mkdir(collpath) - filepath = self._getFilePath(name, ".directory") - f = open(filepath, "w") - f.write("Created by WsgiDAV.") - f.close() - commands.add(self.provider.ui, self.provider.repo, filepath) - - def get_content(self): - """Open content as a stream for reading. - - See DAVResource.get_content() - """ - assert not self.is_collection - d = self.fctx.data() - return compat.StringIO(d) - - def begin_write(self, contentType=None): - """Open content as a stream for writing. - - See DAVResource.begin_write() - """ - assert not self.is_collection - self._check_write_access() - mode = "wb" - # GC issue 57: always store as binary - # if contentType and contentType.startswith("text"): - # mode = "w" - return open(self.absFilePath, mode, BUFFER_SIZE) - - def end_write(self, withErrors): - """Called when PUT has finished writing. - - See DAVResource.end_write() - """ - if not withErrors: - commands.add(self.provider.ui, self.provider.repo, self.localHgPath) - - # def handle_delete(self): - # """Handle a DELETE request natively. - # - # """ - # self._check_write_access() - # return False - - def support_recursive_delete(self): - """Return True, if delete() may be called on non-empty collections - (see comments there).""" - return True - - def delete(self): - """Remove this resource (recursive).""" - self._check_write_access() - filepath = self._getFilePath() - commands.remove(self.provider.ui, self.provider.repo, filepath, force=True) - - def handle_copy(self, destPath, depthInfinity): - """Handle a COPY request natively. - - """ - destType, destHgPath = util.pop_path(destPath) - destHgPath = destHgPath.strip("/") - ui = self.provider.ui - repo = self.provider.repo - _logger.info("handle_copy %s -> %s" % (self.localHgPath, destHgPath)) - if self.rev is None and destType == "edit": - # COPY /edit/a/b to /edit/c/d: turn into 'hg copy -f a/b c/d' - commands.copy(ui, repo, self.localHgPath, destHgPath, force=True) - elif self.rev is None and destType == "released": - # COPY /edit/a/b to /released/c/d - # This is interpreted as 'hg commit a/b' (ignoring the dest. path) - self._commit("WsgiDAV commit (COPY %s -> %s)" % (self.path, destPath)) - else: - raise DAVError(HTTP_FORBIDDEN) - # Return True: request was handled - return True - - def handle_move(self, destPath): - """Handle a MOVE request natively. - - """ - destType, destHgPath = util.pop_path(destPath) - destHgPath = destHgPath.strip("/") - ui = self.provider.ui - repo = self.provider.repo - _logger.info("handle_copy %s -> %s" % (self.localHgPath, destHgPath)) - if self.rev is None and destType == "edit": - # MOVE /edit/a/b to /edit/c/d: turn into 'hg rename -f a/b c/d' - commands.rename(ui, repo, self.localHgPath, destHgPath, force=True) - elif self.rev is None and destType == "released": - # MOVE /edit/a/b to /released/c/d - # This is interpreted as 'hg commit a/b' (ignoring the dest. path) - self._commit("WsgiDAV commit (MOVE %s -> %s)" % (self.path, destPath)) - else: - raise DAVError(HTTP_FORBIDDEN) - # Return True: request was handled - return True - - -# ============================================================================ -# HgResourceProvider -# ============================================================================ - - -class HgResourceProvider(DAVProvider): - """ - DAV provider that serves a VirtualResource derived structure. - """ - - def __init__(self, repoRoot): - super(HgResourceProvider, self).__init__() - self.repoRoot = repoRoot - print("Mercurial version %s" % hgversion) - self.ui = mercurial.ui.ui() - self.repo = hg.repository(self.ui, repoRoot) - self.ui.status("Connected to repository %s\n" % self.repo.root) - self.repoRoot = self.repo.root - - # Some commands (remove) seem to expect cwd set to the repo - # TODO: try to go along without this, because it prevents serving - # multiple repos. Instead pass absolute paths to the commands. - # print(os.getcwd()) - os.chdir(self.repo.root) - - # Verify integrity of the repository - _logger.warn("Verify repository '%s' tree..." % self.repo.root) - commands.verify(self.ui, self.repo) - - # self.ui.status("Changelog: %s\n" % self.repo.changelog) - print("Status:") - pprint(self.repo.status()) - self.repo.ui.status( - "the default username to be used in commits: %s\n" % self.repo.ui.username() - ) - # self.repo.ui.status("a short form of user name USER %s\n" % self.repo.ui.shortuser(user)) - self.ui.status("Expandpath: %s\n" % self.repo.ui.expandpath(repoRoot)) - - print("Working directory state summary:") - self.ui.pushbuffer() - commands.summary(self.ui, self.repo, remote=False) - res = self.ui.popbuffer().strip() - reslines = [tuple(line.split(":", 1)) for line in res.split("\n")] - pprint(reslines) - - print("Repository state summary:") - self.ui.pushbuffer() - commands.identify(self.ui, self.repo, num=True, id=True, branch=True, tags=True) - res = self.ui.popbuffer().strip() - reslines = [tuple(line.split(":", 1)) for line in res.split("\n")] - pprint(reslines) - - self._get_log() - - def _get_log(self, limit=None): - """Read log entries into a list of dictionaries.""" - self.ui.pushbuffer() - commands.log(self.ui, self.repo, limit=limit, date=None, rev=None, user=None) - res = self.ui.popbuffer().strip() - - logList = [] - for logentry in res.split("\n\n"): - log = {} - logList.append(log) - for line in logentry.split("\n"): - k, v = line.split(":", 1) - assert k in ("changeset", "tag", "user", "date", "summary") - log[k.strip()] = v.strip() - log["parsed_date"] = util.parse_time_string(log["date"]) - local_id, unid = log["changeset"].split(":") - log["local_id"] = int(local_id) - log["unid"] = unid - # pprint(logList) - return logList - - def _get_repo_info(self, environ, rev, reload=False): - """Return a dictionary containing all files under source control. - - dirinfos: - Dictionary containing direct members for every collection. - {folderpath: (collectionlist, filelist), ...} - files: - Sorted list of all file paths in the manifest. - filedict: - Dictionary containing all files under source control. - - :: - - {'dirinfos': {'': (['wsgidav', - 'tools', - 'WsgiDAV.egg-info', - 'tests'], - ['index.rst', - 'wsgidav MAKE_DAILY_BUILD.launch', - 'wsgidav run_server.py DEBUG.launch', - 'wsgidav-paste.conf', - ... - 'setup.py']), - 'wsgidav': (['addons', 'samples', 'server', 'interfaces'], - ['__init__.pyc', - 'dav_error.pyc', - 'dav_provider.pyc', - ... - 'wsgidav_app.py']), - }, - 'files': ['.hgignore', - 'ADDONS.txt', - 'wsgidav/addons/mysql_dav_provider.py', - ... - ], - 'filedict': {'.hgignore': True, - 'README.txt': True, - 'WsgiDAV.egg-info/PKG-INFO': True, - } - } - """ - caches = environ.setdefault("wsgidav.hg.cache", {}) - if caches.get(compat.to_native(rev)) is not None: - _logger.debug("_get_repo_info(%s): cache hit." % rev) - return caches[compat.to_native(rev)] - - start_time = time.time() - self.ui.pushbuffer() - commands.manifest(self.ui, self.repo, rev) - res = self.ui.popbuffer() - files = [] - dirinfos = {} - filedict = {} - for file in res.split("\n"): - if file.strip() == "": - continue - file = file.replace("\\", "/") - # add all parent directories to 'dirinfos' - parents = file.split("/") - if len(parents) >= 1: - p1 = "" - for i in range(0, len(parents) - 1): - p2 = parents[i] - dir = dirinfos.setdefault(p1, ([], [])) - if p2 not in dir[0]: - dir[0].append(p2) - if p1 == "": - p1 = p2 - else: - p1 = "%s/%s" % (p1, p2) - dirinfos.setdefault(p1, ([], []))[1].append(parents[-1]) - filedict[file] = True - files.sort() - - cache = {"files": files, "dirinfos": dirinfos, "filedict": filedict} - caches[compat.to_native(rev)] = cache - _logger.info("_getRepoInfo(%s) took %.3f" % (rev, time.time() - start_time)) - return cache - - # def _listMembers(self, path, rev=None): - # """Return a list of all non-collection members""" - # # Pattern for direct members: - # glob = "glob:" + os.path.join(path, "*").lstrip("/") - # print(glob) - # self.ui.pushbuffer() - # commands.status(self.ui, self.repo, - # glob, - # all=True) - # lines = self.ui.popbuffer().strip().split("\n") - # pprint(lines) - # return dict - - def get_resource_inst(self, path, environ): - """Return HgResource object for path. - - See DAVProvider.get_resource_inst() - """ - self._count_getResourceInst += 1 - - # HG expects the resource paths without leading '/' - localHgPath = path.strip("/") - rev = None - cmd, rest = util.pop_path(path) - - if cmd == "": - return VirtualCollection( - path, environ, "root", ["edit", "released", "archive"] - ) - elif cmd == "edit": - localHgPath = rest.strip("/") - rev = None - elif cmd == "released": - localHgPath = rest.strip("/") - rev = "tip" - elif cmd == "archive": - if rest == "/": - # Browse /archive: return a list of revision folders: - loglist = self._get_log(limit=10) - members = [compat.to_native(l["local_id"]) for l in loglist] - return VirtualCollection(path, environ, "Revisions", members) - revid, rest = util.pop_path(rest) - try: - int(revid) - except Exception: - # Tried to access /archive/anyname - return None - # Access /archive/19 - rev = revid - localHgPath = rest.strip("/") - else: - return None - - # read mercurial repo into request cache - cache = self._get_repo_info(environ, rev) - - if localHgPath in cache["filedict"]: - # It is a version controlled file - return HgResource(path, False, environ, rev, localHgPath) - - if localHgPath in cache["dirinfos"] or localHgPath == "": - # It is an existing folder - return HgResource(path, True, environ, rev, localHgPath) - return None diff --git a/wsgidav/server/server_cli.py b/wsgidav/server/server_cli.py index d6e1891a..58ee1454 100644 --- a/wsgidav/server/server_cli.py +++ b/wsgidav/server/server_cli.py @@ -343,6 +343,8 @@ def _init_config(): config["provider_mapping"]["/"] = FilesystemProvider(root_path) if config["verbose"] >= 5: + # TODO: remove passwords from user_mapping + # config_cleaned = copy.deepcopy(config) print("Configuration({}):\n{}".format(cli_opts["config_file"], pformat(config))) if not config["provider_mapping"]: