Commits

Stephan Diehl committed 87e354d

before the weekend checkin...

Comments (0)

Files changed (1)

abl/vpath/dokuwiki/plugin.py

 from __future__ import with_statement, absolute_import
 
 from contextlib import closing
+from cStringIO import StringIO
 import logging
+import xmlrpclib
 
-from abl.vpath.base.fs import BaseUri, FileSystem
+from abl.vpath.base.fs import BaseUri, FileSystem, URI, with_connection
 
 LOGGER = logging.getLogger(__name__)
 
-class DokuWikiFileSystemUri(BaseUri):pass
+class DokuWikiFileSystemUri(BaseUri):
+
+    @with_connection
+    def init_backend(self):
+        self.connection._initialize_cache('people:std')
 
 class DokuWikiFileSystem(FileSystem):
 
     uri = DokuWikiFileSystemUri
 
     def _initialize(self):
-        pass
+        url = self.vpath_connector
+        if not '?' in url and self.username and self.password:
+            url += '?u=%s&p=%s' % (self.username, self.password)
+        self._server = xmlrpclib.ServerProxy(url)
+        # cache the directory structure
+        # TODO: do we need unique memory fs location?
+        self._cache = URI('memory:///')
+        self._cache_is_hot = False
+
+    def _initialize_cache(self, path, force=False):
+        namespace = self._path_to_namespace(path)
+        if self._cache_is_hot and not force:
+            return
+        all_files = self._server.dokuwiki.getPagelist(namespace, [])
+        for item in all_files:
+            parts = item['id'].split(':')
+            dirparts = parts[:-1]
+            cpath = self._cache / '/'.join(dirparts)
+            if not cpath.isdir():
+                cpath.makedirs()
+            fpath = self._cache / '/'.join(parts)
+            with fpath.open('w') as fd:
+                fd.write(str(item['rev']))
+        self._cache_is_hot = True
+
+
+    def _path_to_namespace(self, path):
+        path_str = path.path
+        if path_str.startswith('/'):
+            path_str = path_str[1:]
+        path_parts = path_str.split('/')
+
+        return ':'.join(path_parts)
+
+
+    def _mirror(self, path):
+        pathstr = path.path
+        if pathstr.startswith('/'):
+            pathstr = pathstr[1:]
+
+        return self._cache / pathstr
+
+
+    def _ensure_cache(self, path):
+        if not self._cache_is_hot:
+            self._initialize_cache(path)
+
+    def listdir(self, path, recursive=False):
+        self._ensure_cache(path)
+        return self._mirror(path).listdir()
+
+
+    def exists(self, path):
+        self._ensure_cache(path)
+        return self._mirror(path).exists()
+
+
+    def isfile(self, path):
+        self._ensure_cache(path)
+        return self._mirror(path).isfile()
+
+
+    def isdir(self, path):
+        self._ensure_cache(path)
+        return self._mirror(path).isdir()
+
+
+    def open(self, path, options=None):
+        if options is None:
+            options = 'r'
+        if 'r' in options:
+            content = self._server.wiki.getPage(self._path_to_namespace)
+            return closing(StringIO(content))