Browse Source

Adding new function to tracim library needed for webdav support and deamon's implementation to start webdav's service

Nonolost 8 years ago
parent
commit
99fc9b2fa9
3 changed files with 158 additions and 0 deletions
  1. 28 0
      tracim/tracim/lib/content.py
  2. 127 0
      tracim/tracim/lib/daemons.py
  3. 3 0
      tracim/tracim/lib/workspace.py

+ 28 - 0
tracim/tracim/lib/content.py View File

@@ -364,6 +364,34 @@ class ContentApi(object):
364 364
 
365 365
         return self._base_query(workspace).filter(Content.content_id==content_id).filter(Content.type==content_type).one()
366 366
 
367
+    # TODO : temporary code for webdav support; make it clean !
368
+    def get_one_revision(self, revision_id: int = None) -> Content:
369
+
370
+        return DBSession.query(ContentRevisionRO).filter(ContentRevisionRO.revision_id == revision_id).one_or_none()
371
+
372
+    def get_one_revision2(self, revision_id: int = None):
373
+        ro = self.get_one_revision(revision_id)
374
+
375
+        return DBSession.query(Content).filter(Content.id == ro.content_id).one()
376
+
377
+    def get_one_by_label_and_parent(self, content_label: str, content_parent: Content = None,
378
+                                    workspace: Workspace = None) -> Content:
379
+
380
+        if not content_label:
381
+            return None
382
+
383
+        query = self._base_query(workspace)
384
+
385
+        parent_id = content_parent.content_id if content_parent else None
386
+
387
+        query = query.filter(Content.parent_id == parent_id)
388
+
389
+        res = query.filter(Content.label == content_label).one_or_none()
390
+
391
+        return res if res is not None else query.filter(Content.file_name==content_label).one_or_none()
392
+
393
+    # TODO : end of the webdav's code
394
+
367 395
     def get_all(self, parent_id: int, content_type: str, workspace: Workspace=None) -> Content:
368 396
         assert parent_id is None or isinstance(parent_id, int) # DYN_REMOVE
369 397
         assert content_type is not None# DYN_REMOVE

+ 127 - 0
tracim/tracim/lib/daemons.py View File

@@ -220,3 +220,130 @@ class RadicaleDaemon(Daemon):
220 220
         :param callback: callback to execute in daemon
221 221
         """
222 222
         self._server.append_thread_callback(callback)
223
+
224
+
225
+# TODO : webdav deamon, make it clean !
226
+
227
+import sys, os
228
+from wsgidav.wsgidav_app import DEFAULT_CONFIG
229
+from wsgidav.xml_tools import useLxml
230
+from wsgidav.wsgidav_app import WsgiDAVApp
231
+from wsgidav._version import __version__
232
+
233
+from inspect import isfunction
234
+import traceback
235
+
236
+DEFAULT_CONFIG_FILE = "wsgidav.conf"
237
+PYTHON_VERSION = "%s.%s.%s" % (sys.version_info[0], sys.version_info[1], sys.version_info[2])
238
+
239
+class WsgiDavDaemon(Daemon):
240
+
241
+    def __init__(self, *args, **kwargs):
242
+        super().__init__(*args, **kwargs)
243
+        self.config = self._initConfig()
244
+        self._server = None
245
+
246
+    def _initConfig(self):
247
+        """Setup configuration dictionary from default, command line and configuration file."""
248
+
249
+        # Set config defaults
250
+        config = DEFAULT_CONFIG.copy()
251
+        temp_verbose = config["verbose"]
252
+
253
+        # Configuration file overrides defaults
254
+        config_file = os.path.abspath(DEFAULT_CONFIG_FILE)
255
+        if config_file:
256
+            fileConf = self._readConfigFile(config_file, temp_verbose)
257
+            config.update(fileConf)
258
+        else:
259
+            if temp_verbose >= 2:
260
+                print("Running without configuration file.")
261
+
262
+        if not useLxml and config["verbose"] >= 1:
263
+            print(
264
+                "WARNING: Could not import lxml: using xml instead (slower). Consider installing lxml from http://codespeak.net/lxml/.")
265
+
266
+        if not config["provider_mapping"]:
267
+            print("ERROR: No DAV provider defined. Try --help option.", file=sys.stderr)
268
+            sys.exit(-1)
269
+
270
+        return config
271
+
272
+    def _readConfigFile(self, config_file, verbose):
273
+        """Read configuration file options into a dictionary."""
274
+
275
+        if not os.path.exists(config_file):
276
+            raise RuntimeError("Couldn't open configuration file '%s'." % config_file)
277
+
278
+        try:
279
+            import imp
280
+            conf = {}
281
+            configmodule = imp.load_source("configuration_module", config_file)
282
+
283
+            for k, v in vars(configmodule).items():
284
+                if k.startswith("__"):
285
+                    continue
286
+                elif isfunction(v):
287
+                    continue
288
+                conf[k] = v
289
+        except Exception as e:
290
+            exceptioninfo = traceback.format_exception_only(sys.exc_type, sys.exc_value)  # @UndefinedVariable
291
+            exceptiontext = ""
292
+            for einfo in exceptioninfo:
293
+                exceptiontext += einfo + "\n"
294
+
295
+            print("Failed to read configuration file: " + config_file + "\nDue to " + exceptiontext, file=sys.stderr)
296
+            raise
297
+
298
+        return conf
299
+
300
+    def run(self):
301
+        app = WsgiDAVApp(self.config)
302
+
303
+        # Try running WsgiDAV inside the following external servers:
304
+        self._runCherryPy(app, self.config, "cherrypy-bundled")
305
+
306
+    def _runCherryPy(self, app, config, mode):
307
+        """Run WsgiDAV using cherrypy.wsgiserver, if CherryPy is installed."""
308
+        assert mode in ("cherrypy", "cherrypy-bundled")
309
+
310
+        try:
311
+            from wsgidav.server.cherrypy import wsgiserver
312
+
313
+            version = "WsgiDAV/%s %s Python/%s" % (
314
+                __version__,
315
+                wsgiserver.CherryPyWSGIServer.version,
316
+                PYTHON_VERSION)
317
+
318
+            wsgiserver.CherryPyWSGIServer.version = version
319
+            protocol = "http"
320
+
321
+            if config["verbose"] >= 1:
322
+                print("Running %s" % version)
323
+                print("Listening on %s://%s:%s ..." % (protocol, config["host"], config["port"]))
324
+            self._server = wsgiserver.CherryPyWSGIServer(
325
+                (config["host"], config["port"]),
326
+                app,
327
+                server_name=version,
328
+            )
329
+
330
+            self._server.start()
331
+        except ImportError as e:
332
+            if config["verbose"] >= 1:
333
+                print("Could not import wsgiserver.CherryPyWSGIServer.")
334
+            return False
335
+        return True
336
+
337
+    def stop(self):
338
+        self._server.stop()
339
+        print("WsgiDav : je m'arrête")
340
+
341
+    def append_thread_callback(self, callback: collections.Callable) -> None:
342
+        """
343
+        Place here the logic who permit to execute a callback in your daemon.
344
+        To get an exemple of that, take a look at
345
+        socketserver.BaseServer#service_actions  and how we use it in
346
+        tracim.lib.daemons.TracimSocketServerMixin#service_actions .
347
+        :param callback: callback to execute in your thread.
348
+        """
349
+        raise NotImplementedError()

+ 3 - 0
tracim/tracim/lib/workspace.py View File

@@ -61,6 +61,9 @@ class WorkspaceApi(object):
61 61
     def get_one(self, id):
62 62
         return self._base_query().filter(Workspace.workspace_id==id).one()
63 63
 
64
+    def get_one_by_label(self, label: str):
65
+        return self._base_query().filter(Workspace.label==label).one()
66
+
64 67
     """
65 68
     def get_one_for_current_user(self, id):
66 69
         return self._base_query().filter(Workspace.workspace_id==id).\