diff options
| author | Harry (Open ERP) <hmo@tinyerp.com> | 2010-04-06 18:04:29 +0530 |
|---|---|---|
| committer | Harry (Open ERP) <hmo@tinyerp.com> | 2010-04-06 18:04:29 +0530 |
| commit | 85c42e9270d9689e08b2864a5292ae801ecbfd67 (patch) | |
| tree | d013befdb389847c9320f980f4e8ec824fda3bee /addons/document_webdav | |
| parent | d07c7bc4d6f85d593071e1d5a4900771d32545d1 (diff) | |
| parent | aa70854c09a1e287342e830318c873131bf9744f (diff) | |
[MERGE]
bzr revid: hmo@tinyerp.com-20100406123429-hu7m4lnflo0amjr5
Diffstat (limited to 'addons/document_webdav')
26 files changed, 447 insertions, 2043 deletions
diff --git a/addons/document_webdav/DAV/BufferingHTTPServer.py b/addons/document_webdav/DAV/BufferingHTTPServer.py deleted file mode 100644 index 37520421432..00000000000 --- a/addons/document_webdav/DAV/BufferingHTTPServer.py +++ /dev/null @@ -1,99 +0,0 @@ -#!/usr/bin/env python - -""" - Buffering HTTP Server - Copyright (C) 1999 Christian Scholz (ruebe@aachen.heimat.de) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -""" - - -from utils import VERSION, AUTHOR -__version__ = VERSION -__author__ = AUTHOR - -from BaseHTTPServer import BaseHTTPRequestHandler -import os -class BufferedHTTPRequestHandler(BaseHTTPRequestHandler): - """ - Buffering HTTP Request Handler - - This class is an extension to the BaseHTTPRequestHandler - class which buffers the whole output and sends it at once - after the processing if the request is finished. - - This makes it possible to work together with some clients - which otherwise would break (e.g. cadaver) - - """ - - - def _init_buffer(self): - """initialize the buffer. - - If you override the handle() method remember to call - this (see below) - """ - self.__buffer="" - self.__outfp=os.tmpfile() - - def _append(self,s): - """ append a string to the buffer """ - self.__buffer=self.__buffer+s - - def _flush(self): - """ flush the buffer to wfile """ - self.wfile.write(self.__buffer) - self.__outfp.write(self.__buffer) - self.__outfp.flush() - self.wfile.flush() - self.__buffer="" - - def handle(self): - """ Handle a HTTP request """ - self._init_buffer() - BaseHTTPRequestHandler.handle(self) - self._flush() - - def send_header(self, keyword, value): - """Send a MIME header.""" - if self.request_version != 'HTTP/0.9': - self._append("%s: %s\r\n" % (keyword, value)) - - def end_headers(self): - """Send the blank line ending the MIME headers.""" - if self.request_version != 'HTTP/0.9': - self._append("\r\n") - - def send_response(self, code, message=None): - self.log_request(code) - - if message is None: - if self.responses.has_key(code): - message = self.responses[code][0] - else: - message = '' - - if self.request_version != 'HTTP/0.9': - self._append("%s %s %s\r\n" % - (self.protocol_version, str(code), message)) - - self.send_header('Server', self.version_string()) - self.send_header('Connection', 'close') - self.send_header('Date', self.date_time_string()) - - protocol_version="HTTP/1.1" - diff --git a/addons/document_webdav/DAV/WebDAVServer.py b/addons/document_webdav/DAV/WebDAVServer.py deleted file mode 100644 index 5f409773c18..00000000000 --- a/addons/document_webdav/DAV/WebDAVServer.py +++ /dev/null @@ -1,379 +0,0 @@ -""" - Python WebDAV Server. - Copyright (C) 1999 Christian Scholz (ruebe@aachen.heimat.de) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -This module builds on AuthServer by implementing the standard DAV -methods. - -Subclass this class and specify an IFACE_CLASS. See example. - -""" - -DEBUG=None - -from utils import VERSION, AUTHOR -__version__ = VERSION -__author__ = AUTHOR - - -import os -import sys -import time -import socket -import string -import posixpath -import base64 -import urlparse -import urllib - -from propfind import PROPFIND -from delete import DELETE -from davcopy import COPY -from davmove import MOVE - -from string import atoi,split -from status import STATUS_CODES -from errors import * - -import BaseHTTPServer - -class DAVRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): - """Simple DAV request handler with - - - GET - - HEAD - - PUT - - OPTIONS - - PROPFIND - - PROPPATCH - - MKCOL - - It uses the resource/collection classes for serving and - storing content. - - """ - - server_version = "DAV/" + __version__ - protocol_version = 'HTTP/1.1' - - ### utility functions - def _log(self, message): - pass - - def _append(self,s): - """ write the string to wfile """ - self.wfile.write(s) - - def send_body(self,DATA,code,msg,desc,ctype='application/octet-stream',headers=None): - """ send a body in one part """ - - if not headers: - headers = {} - self.send_response(code,message=msg) - self.send_header("Connection", "keep-alive") - self.send_header("Accept-Ranges", "bytes") - - for a,v in headers.items(): - self.send_header(a,v) - - if DATA: - self.send_header("Content-Length", str(len(DATA))) - self.send_header("Content-Type", ctype) - else: - self.send_header("Content-Length", "0") - - self.end_headers() - if DATA: - self._append(DATA) - - def send_body_chunks(self,DATA,code,msg,desc,ctype='text/xml; encoding="utf-8"'): - """ send a body in chunks """ - - self.responses[207]=(msg,desc) - self.send_response(code,message=msg) - self.send_header("Content-type", ctype) - self.send_header("Connection", "keep-alive") - self.send_header("Transfer-Encoding", "chunked") - self.end_headers() - self._append(hex(len(DATA))[2:]+"\r\n") - self._append(DATA) - self._append("\r\n") - self._append("0\r\n") - self._append("\r\n") - - ### HTTP METHODS - - def do_OPTIONS(self): - """return the list of capabilities """ - self.send_response(200) - self.send_header("Allow", "GET, HEAD, COPY, MOVE, POST, PUT, PROPFIND, PROPPATCH, OPTIONS, MKCOL, DELETE, TRACE") - self.send_header("Content-Type", "text/plain") - self.send_header("Connection", "keep-alive") - self.send_header("DAV", "1") - self.end_headers() - - def do_PROPFIND(self): - - dc=self.IFACE_CLASS - # read the body - body=None - if self.headers.has_key("Content-Length"): - l=self.headers['Content-Length'] - body=self.rfile.read(atoi(l)) - alt_body = """<?xml version="1.0" encoding="utf-8"?> - <propfind xmlns="DAV:"><prop> - <getcontentlength xmlns="DAV:"/> - <getlastmodified xmlns="DAV:"/> - <getcreationdate xmlns="DAV:"/> - <checked-in xmlns="DAV:"/> - <executable xmlns="http://apache.org/dav/props/"/> - <displayname xmlns="DAV:"/> - <resourcetype xmlns="DAV:"/> - <checked-out xmlns="DAV:"/> - </prop></propfind>""" - #self.wfile.write(body) - - # which Depth? - if self.headers.has_key('Depth'): - d=self.headers['Depth'] - else: - d="infinity" - - uri=self.geturi() - pf=PROPFIND(uri,dc,d) - - if body: - pf.read_propfind(body) - - try: - DATA=pf.createResponse() - DATA=DATA+"\n" - # print "Data:", DATA - except DAV_NotFound,(ec,dd): - return self.send_notFound(dd, uri) - except DAV_Error, (ec,dd): - return self.send_error(ec,dd) - - self.send_body_chunks(DATA,207,"Multi-Status","Multiple responses") - - def geturi(self): - buri = self.IFACE_CLASS.baseuri - if buri[-1] == '/': - return urllib.unquote(buri[:-1]+self.path) - else: - return urllib.unquote(buri+self.path) - - def do_GET(self): - """Serve a GET request.""" - dc=self.IFACE_CLASS - uri=self.geturi() - - # get the last modified date - try: - lm=dc.get_prop(uri,"DAV:","getlastmodified") - except: - lm="Sun, 01 Dec 2014 00:00:00 GMT" # dummy! - headers={"Last-Modified":lm , "Connection": "keep-alive"} - - # get the content type - try: - ct=dc.get_prop(uri,"DAV:","getcontenttype") - except: - ct="application/octet-stream" - - # get the data - try: - data=dc.get_data(uri) - except DAV_Error, (ec,dd): - self.send_status(ec) - return - - # send the data - self.send_body(data,200,"OK","OK",ct,headers) - - def do_HEAD(self): - """ Send a HEAD response """ - dc=self.IFACE_CLASS - uri=self.geturi() - - # get the last modified date - try: - lm=dc.get_prop(uri,"DAV:","getlastmodified") - except: - lm="Sun, 01 Dec 2014 00:00:00 GMT" # dummy! - - headers={"Last-Modified":lm, "Connection": "keep-alive"} - - # get the content type - try: - ct=dc.get_prop(uri,"DAV:","getcontenttype") - except: - ct="application/octet-stream" - - try: - data=dc.get_data(uri) - headers["Content-Length"]=str(len(data)) - except DAV_NotFound: - self.send_body(None,404,"Not Found","") - return - - self.send_body(None,200,"OK","OK",ct,headers) - - def do_POST(self): - self.send_error(404,"File not found") - - def do_MKCOL(self): - """ create a new collection """ - - dc=self.IFACE_CLASS - uri=self.geturi() - try: - res = dc.mkcol(uri) - if res: - self.send_body(None,201,"Created",'') - else: - self.send_body(None,415,"Cannot create",'') - #self.send_header("Connection", "keep-alive") - # Todo: some content, too - except DAV_Error, (ec,dd): - self.send_body(None,int(ec),dd,dd) - - def do_DELETE(self): - """ delete an resource """ - dc=self.IFACE_CLASS - uri=self.geturi() - dl=DELETE(uri,dc) - if dc.is_collection(uri): - res=dl.delcol() - else: - res=dl.delone() - - if res: - self.send_status(207,body=res) - else: - self.send_status(204) - - def do_PUT(self): - dc=self.IFACE_CLASS - - # read the body - body=None - if self.headers.has_key("Content-Length"): - l=self.headers['Content-Length'] - body=self.rfile.read(atoi(l)) - uri=self.geturi() - - ct=None - if self.headers.has_key("Content-Type"): - ct=self.headers['Content-Type'] - try: - dc.put(uri,body,ct) - except DAV_Error, (ec,dd): - self.send_status(ec) - return - self.send_status(201) - - def do_COPY(self): - """ copy one resource to another """ - try: - self.copymove(COPY) - except DAV_Error, (ec,dd): - self.send_status(ec) - - def do_MOVE(self): - """ move one resource to another """ - try: - self.copymove(MOVE) - except DAV_Error, (ec,dd): - self.send_status(ec) - - def copymove(self,CLASS): - """ common method for copying or moving objects """ - dc=self.IFACE_CLASS - - # get the source URI - source_uri=self.geturi() - - # get the destination URI - dest_uri=self.headers['Destination'] - dest_uri=urllib.unquote(dest_uri) - - # Overwrite? - overwrite=1 - result_code=204 - if self.headers.has_key("Overwrite"): - if self.headers['Overwrite']=="F": - overwrite=None - result_code=201 - - # instanciate ACTION class - cp=CLASS(dc,source_uri,dest_uri,overwrite) - - # Depth? - d="infinity" - if self.headers.has_key("Depth"): - d=self.headers['Depth'] - - if d!="0" and d!="infinity": - self.send_status(400) - return - - if d=="0": - res=cp.single_action() - self.send_status(res) - return - - # now it only can be "infinity" but we nevertheless check for a collection - if dc.is_collection(source_uri): - try: - res=cp.tree_action() - except DAV_Error, (ec,dd): - self.send_status(ec) - return - else: - try: - res=cp.single_action() - except DAV_Error, (ec,dd): - self.send_status(ec) - return - - if res: - self.send_body_chunks(res,207,STATUS_CODES[207],STATUS_CODES[207], - ctype='text/xml; charset="utf-8"') - else: - self.send_status(result_code) - - def get_userinfo(self,user,pw): - """ Dummy method which lets all users in """ - - return 1 - - def send_status(self,code=200,mediatype='text/xml; charset="utf-8"', \ - msg=None,body=None): - - if not msg: msg=STATUS_CODES[code] - self.send_body(body,code,STATUS_CODES[code],msg,mediatype) - - def send_notFound(self,descr,uri): - body = """<?xml version="1.0" encoding="utf-8" ?> - <D:response xmlns:D="DAV:"> - <D:href>%s</D:href> - <D:error/> - <D:responsedescription>%s</D:responsedescription> - </D:response> - """ - return self.send_status(404,descr, body=body % (uri,descr)) diff --git a/addons/document_webdav/DAV/__init__.py b/addons/document_webdav/DAV/__init__.py deleted file mode 100644 index 10abdb40014..00000000000 --- a/addons/document_webdav/DAV/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -""" - python davserver - Copyright (C) 1999 Christian Scholz (ruebe@aachen.heimat.de) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -""" - - diff --git a/addons/document_webdav/DAV/constants.py b/addons/document_webdav/DAV/constants.py deleted file mode 100644 index e858ac519c2..00000000000 --- a/addons/document_webdav/DAV/constants.py +++ /dev/null @@ -1,18 +0,0 @@ -""" - -constants definition - - -""" - -# definition for resourcetype -COLLECTION=1 -OBJECT=None -DAV_PROPS=['creationdate', 'displayname', 'getcontentlanguage', 'getcontentlength', 'getcontenttype', 'getetag', 'getlastmodified', 'lockdiscovery', 'resourcetype', 'source', 'supportedlock'] - - -# Request classes in propfind - -RT_ALLPROP=1 -RT_PROPNAME=2 -RT_PROP=3 diff --git a/addons/document_webdav/DAV/davcmd.py b/addons/document_webdav/DAV/davcmd.py deleted file mode 100644 index 5c6be3ff9f7..00000000000 --- a/addons/document_webdav/DAV/davcmd.py +++ /dev/null @@ -1,218 +0,0 @@ -""" - -davcmd.py ---------- - -containts commands like copy, move, delete for normal -resources and collections - -""" - -from string import split,replace,joinfields -import urlparse - -from utils import create_treelist, is_prefix -from errors import * - -def deltree(dc,uri,exclude={}): - """ delete a tree of resources - - dc -- dataclass to use - uri -- root uri to delete - exclude -- an optional list of uri:error_code pairs which should not - be deleted. - - returns dict of uri:error_code tuples from which - another method can create a multistatus xml element. - - Also note that we only know Depth=infinity thus we don't have - to test for it. - - """ - - tlist=create_treelist(dc,uri) - result={} - - for i in range(len(tlist),0,-1): - problem_uris=result.keys() - element=tlist[i-1] - - # test here, if an element is a prefix of an uri which - # generated an error before. - # note that we walk here from childs to parents, thus - # we cannot delete a parent if a child made a problem. - # (see example in 8.6.2.1) - ok=1 - for p in problem_uris: - if is_prefix(element,p): - ok=None - break - - if not ok: continue - - # here we test for the exclude list which is the other way round! - for p in exclude.keys(): - if is_prefix(p,element): - ok=None - break - - if not ok: continue - - # now delete stuff - try: - delone(dc,element) - except DAV_Error, (ec,dd): - result[element]=ec - - return result - -def delone(dc,uri): - """ delete a single object """ - if dc.is_collection(uri): - dc.rmcol(uri) # should be empty - else: - dc.rm(uri) - -### -### COPY -### - -# helper function - -def copy(dc,src,dst): - """ only copy the element - - This is just a helper method factored out from copy and - copytree. It will not handle the overwrite or depth header. - - """ - - # destination should have been deleted before - if dc.exists(dst): raise DAV_Error, 412 - - # source should exist also - if not dc.exists(src): raise DAV_NotFound - - if dc.is_collection(src): - dc.copycol(src,dst) # an exception will be passed thru - else: - dc.copy(src,dst) # an exception will be passed thru - - -# the main functions - -def copyone(dc,src,dst,overwrite=None): - """ copy one resource to a new destination """ - - if overwrite and dc.exists(dst): - delres=deltree(dc,dst) - else: - delres={} - - # if we cannot delete everything, then do not copy! - if delres: return delres - - try: - copy(dc,src,dst) # pass thru exceptions - except DAV_Error, (ec,dd): - return ec - -def copytree(dc,src,dst,overwrite=None): - """ copy a tree of resources to another location - - dc -- dataclass to use - src -- src uri from where to copy - dst -- dst uri - overwrite -- if 1 then delete dst uri before - - returns dict of uri:error_code tuples from which - another method can create a multistatus xml element. - - """ - - - # first delete the destination resource - if overwrite and dc.exists(dst): - delres=deltree(dc,dst) - else: - delres={} - - # if we cannot delete everything, then do not copy! - if delres: return delres - - # get the tree we have to copy - tlist=create_treelist(dc,src) - result={} - - # prepare destination URIs (get the prefix) - dpath=urlparse.urlparse(dst)[2] - - for element in tlist: - problem_uris=result.keys() - - # now URIs get longer and longer thus we have - # to test if we had a parent URI which we were not - # able to copy in problem_uris which is the prefix - # of the actual element. If it is, then we cannot - # copy this as well but do not generate another error. - ok=1 - for p in problem_uris: - if is_prefix(p,element): - ok=None - break - - if not ok: continue - - # now create the destination URI which corresponds to - # the actual source URI. -> actual_dst - # ("subtract" the base src from the URI and prepend the - # dst prefix to it.) - esrc=replace(element,src,"") - actual_dst=dpath+esrc - - # now copy stuff - try: - copy(dc,element,actual_dst) - except DAV_Error, (ec,dd): - result[element]=ec - - return result - - - -### -### MOVE -### - - -def moveone(dc,src,dst,overwrite=None): - """ move a single resource - - This is done by first copying it and then deleting - the original. - """ - - # first copy it - copyone(dc,src,dst,overwrite) - - # then delete it - dc.rm(src) - -def movetree(dc,src,dst,overwrite=None): - """ move a collection - - This is done by first copying it and then deleting - the original. - - PROBLEM: if something did not copy then we have a problem - when deleting as the original might get deleted! - """ - - # first copy it - res=copytree(dc,src,dst,overwrite) - - # then delete it - res=deltree(dc,src,exclude=res) - - return res - diff --git a/addons/document_webdav/DAV/davcopy.py b/addons/document_webdav/DAV/davcopy.py deleted file mode 100755 index ec44931b107..00000000000 --- a/addons/document_webdav/DAV/davcopy.py +++ /dev/null @@ -1,133 +0,0 @@ -#!/usr/bin/env python - -""" - python davserver - Copyright (C) 1999 Christian Scholz (ruebe@aachen.heimat.de) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -""" - - -from xml.dom import ext -from xml.dom.Document import Document - -import sys -import string -import urlparse -import urllib -from StringIO import StringIO - -import utils -from constants import COLLECTION, OBJECT, DAV_PROPS, RT_ALLPROP, RT_PROPNAME, RT_PROP -from errors import * -from utils import create_treelist, quote_uri, gen_estring - -class COPY: - """ copy resources and eventually create multistatus responses - - This module implements the COPY class which is responsible for - copying resources. Usually the normal copy work is done in the - interface class. This class only creates error messages if error - occur. - - """ - - - def __init__(self,dataclass,src_uri,dst_uri,overwrite): - self.__dataclass=dataclass - self.__src=src_uri - self.__dst=dst_uri - self.__overwrite=overwrite - - - def single_action(self): - """ copy a normal resources. - - We try to copy it and return the result code. - This is for Depth==0 - - """ - - dc=self.__dataclass - base=self.__src - - ### some basic tests - # test if dest exists and overwrite is false - if dc.exists(self.__dst) and not self.__overwrite: raise DAV_Error, 412 - # test if src and dst are the same - # (we assume that both uris are on the same server!) - ps=urlparse.urlparse(self.__src)[2] - pd=urlparse.urlparse(self.__dst)[2] - if ps==pd: raise DAV_Error, 403 - - return dc.copyone(self.__src,self.__dst,self.__overwrite) - - #return copyone(dc,self.__src,self.__dst,self.__overwrite) - - def tree_action(self): - """ copy a tree of resources (a collection) - - Here we return a multistatus xml element. - - """ - dc=self.__dataclass - base=self.__src - - ### some basic tests - # test if dest exists and overwrite is false - if dc.exists(self.__dst) and not self.__overwrite: raise DAV_Error, 412 - # test if src and dst are the same - # (we assume that both uris are on the same server!) - ps=urlparse.urlparse(self.__src)[2] - pd=urlparse.urlparse(self.__dst)[2] - if ps==pd: raise DAV_Error, 403 - - - result=dc.copytree(self.__src,self.__dst,self.__overwrite) - #result=copytree(dc,self.__src,self.__dst,self.__overwrite) - - if not result: return None - - ### - ### create the multistatus XML element - ### (this is also the same as in delete.py. - ### we might make a common method out of it) - ### - - doc = Document(None) - ms=doc.createElement("D:multistatus") - ms.setAttribute("xmlns:D","DAV:") - doc.appendChild(ms) - - for el,ec in result.items(): - re=doc.createElement("D:response") - hr=doc.createElement("D:href") - st=doc.createElement("D:status") - huri=doc.createTextNode(quote_uri(el)) - t=doc.createTextNode(gen_estring(ec)) - st.appendChild(t) - hr.appendChild(huri) - re.appendChild(hr) - re.appendChild(st) - ms.appendChild(re) - - sfile=StringIO() - ext.PrettyPrint(doc,stream=sfile) - s=sfile.getvalue() - sfile.close() - return s - diff --git a/addons/document_webdav/DAV/davmove.py b/addons/document_webdav/DAV/davmove.py deleted file mode 100755 index 78c1e649389..00000000000 --- a/addons/document_webdav/DAV/davmove.py +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/env python - -""" - python davserver - Copyright (C) 1999 Christian Scholz (ruebe@aachen.heimat.de) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -""" - - -import sys -import string -import urlparse -import urllib -from StringIO import StringIO - -import utils -from constants import COLLECTION, OBJECT, DAV_PROPS -from constants import RT_ALLPROP, RT_PROPNAME, RT_PROP -from errors import * -from utils import create_treelist, quote_uri, gen_estring, make_xmlresponse -from davcmd import moveone, movetree - -class MOVE: - """ move resources and eventually create multistatus responses - - This module implements the MOVE class which is responsible for - moving resources. - - MOVE is implemented by a COPY followed by a DELETE of the old - resource. - - """ - - - def __init__(self,dataclass,src_uri,dst_uri,overwrite): - self.__dataclass=dataclass - self.__src=src_uri - self.__dst=dst_uri - self.__overwrite=overwrite - - - def single_action(self): - """ move a normal resources. - - We try to move it and return the result code. - This is for Depth==0 - - """ - - dc=self.__dataclass - base=self.__src - - ### some basic tests - # test if dest exists and overwrite is false - if dc.exists(self.__dst) and not self.__overwrite: raise DAV_Error, 412 - # test if src and dst are the same - # (we assume that both uris are on the same server!) - ps=urlparse.urlparse(self.__src)[2] - pd=urlparse.urlparse(self.__dst)[2] - if ps==pd: raise DAV_Error, 403 - - return dc.moveone(self.__src,self.__dst,self.__overwrite) - - def tree_action(self): - """ move a tree of resources (a collection) - - Here we return a multistatus xml element. - - """ - dc=self.__dataclass - base=self.__src - - ### some basic tests - # test if dest exists and overwrite is false - if dc.exists(self.__dst) and not self.__overwrite: raise DAV_Error, 412 - # test if src and dst are the same - # (we assume that both uris are on the same server!) - ps=urlparse.urlparse(self.__src)[2] - pd=urlparse.urlparse(self.__dst)[2] - if ps==pd: raise DAV_Error, 403 - - result=dc.movetree(self.__src,self.__dst,self.__overwrite) - if not result: return None - - # create the multistatus XML element - return make_xmlresponse(result) - diff --git a/addons/document_webdav/DAV/delete.py b/addons/document_webdav/DAV/delete.py deleted file mode 100755 index ed017e53b6d..00000000000 --- a/addons/document_webdav/DAV/delete.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python - -""" - - python davserver - Copyright (C) 1999 Christian Scholz (ruebe@aachen.heimat.de) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -""" -import os -import string -import urllib -from StringIO import StringIO - -from status import STATUS_CODES -from utils import gen_estring, quote_uri, make_xmlresponse -from davcmd import deltree - -class DELETE: - - def __init__(self,uri,dataclass): - self.__dataclass=dataclass - self.__uri=uri - - def delcol(self): - """ delete a collection """ - - dc=self.__dataclass - result=dc.deltree(self.__uri) - - if not len(result.items()): - return None # everything ok - - # create the result element - return make_xmlresponse(result) - - def delone(self): - """ delete a resource """ - - dc=self.__dataclass - result=dc.delone(self.__uri) - - if not result: return None - if not len(result.items()): - return None # everything ok - - # create the result element - return make_xmlresponse(result) - diff --git a/addons/document_webdav/DAV/errors.py b/addons/document_webdav/DAV/errors.py deleted file mode 100755 index 9c0e7667913..00000000000 --- a/addons/document_webdav/DAV/errors.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env python -""" - - Exceptions for the DAVserver implementation - -""" - -class DAV_Error(Exception): - """ in general we can have the following arguments: - - 1. the error code - 2. the error result element, e.g. a <multistatus> element - """ - - def __init__(self,*args): - if len(args)==1: - self.args=(args[0],"") - else: - self.args=args - -class DAV_Secret(DAV_Error): - """ the user is not allowed to know anything about it - - returning this for a property value means to exclude it - from the response xml element. - """ - - def __init__(self): - DAV_Error.__init__(self,0) - pass - -class DAV_NotFound(DAV_Error): - """ a requested property was not found for a resource """ - - def __init__(self,*args): - if len(args): - if isinstance(args[0],list): - stre = "Path %s not found!"%('/'.join(args[0])) - else: - stre = args[0] - DAV_Error.__init__(self,404,stre) - else: - DAV_Error.__init__(self,404) - - pass - -class DAV_Forbidden(DAV_Error): - """ a method on a resource is not allowed """ - - def __init__(self,*args): - if len(args): - DAV_Error.__init__(self,403,args[0]) - else: - DAV_Error.__init__(self,403) - pass - diff --git a/addons/document_webdav/DAV/iface.py b/addons/document_webdav/DAV/iface.py deleted file mode 100644 index c8f5fe2594d..00000000000 --- a/addons/document_webdav/DAV/iface.py +++ /dev/null @@ -1,263 +0,0 @@ -""" - -basic interface class - -use this for subclassing when writing your own interface -class. - -""" - -from errors import * - -import time -from string import lower - -class dav_interface: - """ interface class for implementing DAV servers """ - - ### defined properties (modify this but let the DAV stuff there!) - ### the format is namespace: [list of properties] - - PROPS={"DAV:" : ('creationdate', - 'displayname', - 'getcontentlanguage', - 'getcontentlength', - 'getcontenttype', - 'getetag', - 'getlastmodified', - 'lockdiscovery', - 'resourcetype', - 'source', - 'supportedlock'), - "NS2" : ("p1","p2") - } - - # here we define which methods handle which namespace - # the first item is the namespace URI and the second one - # the method prefix - # e.g. for DAV:getcontenttype we call dav_getcontenttype() - M_NS={"DAV:" : "_get_dav", - "NS2" : "ns2" } - - def get_propnames(self,uri): - """ return the property names allowed for the given URI - - In this method we simply return the above defined properties - assuming that they are valid for any resource. - You can override this in order to return a different set - of property names for each resource. - - """ - return self.PROPS - - def get_prop2(self,uri,ns,pname): - """ return the value of a property - """ - if lower(ns)=="dav:": return self.get_dav(uri,pname) - - raise DAV_NotFound - - def get_prop(self,uri,ns,propname): - """ return the value of a given property - - uri -- uri of the object to get the property of - ns -- namespace of the property - pname -- name of the property - """ - if self.M_NS.has_key(ns): - prefix=self.M_NS[ns] - else: - print "No namespace:",ns, "( for prop:", propname,")" - raise DAV_NotFound - mname=prefix+"_"+propname - if not hasattr(self,mname): - raise DAV_NotFound - - try: - m=getattr(self,mname) - r=m(uri) - return r - except AttributeError, e: - print 'Property %s not supported' % propname - print "Exception:", e - raise DAV_NotFound - - ### - ### DATA methods (for GET and PUT) - ### - - def get_data(self,uri): - """ return the content of an object - - return data or raise an exception - - """ - raise DAV_NotFound - - def put(self,uri,data): - """ write an object to the repository - - return a result code or raise an exception - """ - - raise DAV_Forbidden - - ### - ### Methods for DAV properties - ### - - def _get_dav_creationdate(self,uri): - """ return the creationdate of a resource """ - d=self.get_creationdate(uri) - # format it - if isinstance(d, int) or isinstance(d, float): - d = time.localtimetime(d) - return time.strftime("%Y-%m-%dT%H:%M:%S%Z",d) - - def _get_dav_getlastmodified(self,uri): - """ return the last modified date of a resource """ - d=self.get_lastmodified(uri) - if isinstance(d, int) or isinstance(d, float): - d = time.localtime(d) - # format it - return time.asctime(d) - - - ### - ### OVERRIDE THESE! - ### - - def get_creationdate(self,uri): - """ return the creationdate of the resource """ - return time.time() - - def get_lastmodified(self,uri): - """ return the last modification date of the resource """ - return time.time() - - - ### - ### COPY MOVE DELETE - ### - - ### methods for deleting a resource - - def rmcol(self,uri): - """ delete a collection - - This should not delete any children! This is automatically done - before by the DELETE class in DAV/delete.py - - return a success code or raise an exception - - """ - raise DAV_NotFound - - def rm(self,uri): - """ delete a single resource - - return a success code or raise an exception - - """ - raise DAV_NotFound - - """ - - COPY/MOVE HANDLER - - These handler are called when a COPY or MOVE method is invoked by - a client. In the default implementation it works as follows: - - - the davserver receives a COPY/MOVE method - - the davcopy or davmove module will be loaded and the corresponding - class will be initialized - - this class parses the query and decides which method of the interface class - to call: - - copyone for a single resource to copy - copytree for a tree to copy (collection) - (the same goes for move of course). - - - the interface class has now two options: - 1. to handle the action directly (e.g. cp or mv on filesystems) - 2. to let it handle via the copy/move methods in davcmd. - - ad 1) The first approach can be used when we know that no error can - happen inside a tree or when the action can exactly tell which - element made which error. We have to collect these and return - it in a dict of the form {uri: error_code, ...} - - ad 2) The copytree/movetree/... methods of davcmd.py will do the recursion - themselves and call for each resource the copy/move method of the - interface class. Thus method will then only act on a single resource. - (Thus a copycol on a normal unix filesystem actually only needs to do - an mkdir as the content will be copied by the davcmd.py function. - The davcmd.py method will also automatically collect all errors and - return the dictionary described above. - When you use 2) you also have to implement the copy() and copycol() - methods in your interface class. See the example for details. - - To decide which approach is the best you have to decide if your application - is able to generate errors inside a tree. E.g. a function which completely - fails on a tree if one of the tree's childs fail is not what we need. Then - 2) would be your way of doing it. - Actually usually 2) is the better solution and should only be replaced by - 1) if you really need it. - - The remaining question is if we should do the same for the DELETE method. - - """ - - ### MOVE handlers - - def moveone(self,src,dst,overwrite): - """ move one resource with Depth=0 """ - return moveone(self,src,dst,overwrite) - - def movetree(self,src,dst,overwrite): - """ move a collection with Depth=infinity """ - return movetree(self,src,dst,overwrite) - - ### COPY handlers - - def copyone(self,src,dst,overwrite): - """ copy one resource with Depth=0 """ - return copyone(self,src,dst,overwrite) - - def copytree(self,src,dst,overwrite): - """ copy a collection with Depth=infinity """ - return copytree(self,src,dst,overwrite) - - - ### low level copy methods (you only need these for method 2) - def copy(self,src,dst): - """ copy a resource with depth==0 - - You don't need to bother about overwrite or not. - This has been done already. - - return a success code or raise an exception if something fails - """ - return 201 - - - def copycol(self,src,dst): - """ copy a resource with depth==infinity - - You don't need to bother about overwrite or not. - This has been done already. - - return a success code or raise an exception if something fails - """ - return 201 - - ### some utility functions you need to implement - - def exists(self,uri): - """ return 1 or None depending on if a resource exists """ - return None # no - - def is_collection(self,uri): - """ return 1 or None depending on if a resource is a collection """ - return None # no - diff --git a/addons/document_webdav/DAV/propfind.py b/addons/document_webdav/DAV/propfind.py deleted file mode 100755 index 0fb9c229c03..00000000000 --- a/addons/document_webdav/DAV/propfind.py +++ /dev/null @@ -1,372 +0,0 @@ -#!/usr/bin/env python - -""" - python davserver - Copyright (C) 1999 Christian Scholz (ruebe@aachen.heimat.de) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -""" - - -from xml.dom import ext -from xml.dom.Document import Document - -import sys -import string -import urlparse -import urllib -from StringIO import StringIO - -import utils -from constants import COLLECTION, OBJECT, DAV_PROPS, RT_ALLPROP, RT_PROPNAME, RT_PROP -from errors import * - -def utf8str(st): - if isinstance(st,unicode): - return st.encode('utf8') - else: - return str(st) - -class PROPFIND: - """ parse a propfind xml element and extract props - - It will set the following instance vars: - - request_class : ALLPROP | PROPNAME | PROP - proplist : list of properties - nsmap : map of namespaces - - The list of properties will contain tuples of the form - (element name, ns_prefix, ns_uri) - - - """ - - - def __init__(self,uri,dataclass,depth): - self.request_type=None - self.nsmap={} - self.proplist={} - self.default_ns=None - self.__dataclass=dataclass - self.__depth=str(depth) - self.__uri=uri - self.use_full_urls=True - self.__has_body=None # did we parse a body? - - def read_propfind(self,xml_doc): - self.request_type,self.proplist,self.namespaces=utils.parse_propfind(xml_doc) - - # a violation of the expected logic: client (korganizer) will ask for DAV:resourcetype - # but we also have to return the http://groupdav.org/:resourcetype property! - if self.proplist.has_key('DAV:') and 'resourcetype' in self.proplist['DAV:']: - if not self.proplist.has_key('http://groupdav.org/'): - self.proplist['http://groupdav.org/'] = [] - self.proplist['http://groupdav.org/'].append('resourcetype') - if 'DAV:' in self.namespaces: #TMP - self.namespaces.append('http://groupdav.org/') - - def createResponse(self): - """ create the multistatus response - - This will be delegated to the specific method - depending on which request (allprop, propname, prop) - was found. - - If we get a PROPNAME then we simply return the list with empty - values which we get from the interface class - - If we get an ALLPROP we first get the list of properties and then - we do the same as with a PROP method. - - If the uri doesn't exist, return an xml response with a 404 status - - """ - - if not self.__dataclass.exists(self.__uri): - raise DAV_NotFound("Path %s doesn't exist" % self.__uri) - - if self.request_type==RT_ALLPROP: - return self.create_allprop() - - if self.request_type==RT_PROPNAME: - return self.create_propname() - - if self.request_type==RT_PROP: - return self.create_prop() - - # no body means ALLPROP! - return self.create_allprop() - - def create_propname(self): - """ create a multistatus response for the prop names """ - - dc=self.__dataclass - # create the document generator - doc = Document(None) - ms=doc.createElement("D:multistatus") - ms.setAttribute("xmlns:D","DAV:") - doc.appendChild(ms) - - if self.__depth=="0": - pnames=dc.get_propnames(self.__uri) - re=self.mk_propname_response(self.__uri,pnames,doc) - ms.appendChild(re) - - elif self.__depth=="1": - pnames=dc.get_propnames(self.__uri) - re=self.mk_propname_response(self.__uri,pnames,doc) - ms.appendChild(re) - - for newuri in dc.get_childs(self.__uri): - pnames=dc.get_propnames(newuri) - re=self.mk_propname_response(newuri,pnames,doc) - ms.appendChild(re) - # *** depth=="infinity" - - sfile=StringIO() - ext.PrettyPrint(doc,stream=sfile) - s=sfile.getvalue() - sfile.close() - return s - - def create_allprop(self): - """ return a list of all properties """ - self.proplist={} - self.namespaces=[] - for ns,plist in self.__dataclass.get_propnames(self.__uri).items(): - self.proplist[ns]=plist - self.namespaces.append(ns) - - return self.create_prop() - - def create_prop(self): - """ handle a <prop> request - - This will - - 1. set up the <multistatus>-Framework - - 2. read the property values for each URI - (which is dependant on the Depth header) - This is done by the get_propvalues() method. - - 3. For each URI call the append_result() method - to append the actual <result>-Tag to the result - document. - - We differ between "good" properties, which have been - assigned a value by the interface class and "bad" - properties, which resulted in an error, either 404 - (Not Found) or 403 (Forbidden). - - """ - - - # create the document generator - doc = Document(None) - ms=doc.createElement("D:multistatus") - ms.setAttribute("xmlns:D","DAV:") - doc.appendChild(ms) - - if self.__depth=="0": - gp,bp=self.get_propvalues(self.__uri) - res=self.mk_prop_response(self.__uri,gp,bp,doc) - ms.appendChild(res) - - elif self.__depth=="1": - gp,bp=self.get_propvalues(self.__uri) - res=self.mk_prop_response(self.__uri,gp,bp,doc) - ms.appendChild(res) - - try: - for newuri in self.__dataclass.get_childs(self.__uri): - gp,bp=self.get_propvalues(newuri) - res=self.mk_prop_response(newuri,gp,bp,doc) - ms.appendChild(res) - except DAV_NotFound: - # If no children, never mind. - pass - - sfile=StringIO() - ext.PrettyPrint(doc,stream=sfile) - s=sfile.getvalue() - sfile.close() - return s - - - def mk_propname_response(self,uri,propnames,doc): - """ make a new <prop> result element for a PROPNAME request - - This will simply format the propnames list. - propnames should have the format {NS1 : [prop1, prop2, ...], NS2: ...} - - """ - re=doc.createElement("D:response") - - # write href information - href=doc.createElement("D:href") - if self.use_full_urls: - huri=doc.createTextNode(uri) - else: - uparts=urlparse.urlparse(uri) - fileloc=uparts[2] - huri=doc.createTextNode(urllib.quote(fileloc.encode('utf8'))) - href.appendChild(huri) - re.appendChild(href) - - ps=doc.createElement("D:propstat") - nsnum=0 - - for ns,plist in propnames.items(): - # write prop element - pr=doc.createElement("D:prop") - nsp="ns"+str(nsnum) - pr.setAttribute("xmlns:"+nsp,ns) - nsnum=nsnum+1 - - # write propertynames - for p in plist: - pe=doc.createElement(nsp+":"+p) - pr.appendChild(pe) - - ps.appendChild(pr) - - re.appendChild(ps) - - return re - - def mk_prop_response(self,uri,good_props,bad_props,doc): - """ make a new <prop> result element - - We differ between the good props and the bad ones for - each generating an extra <propstat>-Node (for each error - one, that means). - - """ - re=doc.createElement("D:response") - # append namespaces to response - nsnum=0 - for nsname in self.namespaces: - re.setAttribute("xmlns:ns"+str(nsnum),nsname) - nsnum=nsnum+1 - - # write href information - href=doc.createElement("D:href") - if self.use_full_urls: - huri=doc.createTextNode(uri) - else: - uparts=urlparse.urlparse(uri) - fileloc=uparts[2] - huri=doc.createTextNode(urllib.quote(fileloc.encode('utf8'))) - href.appendChild(huri) - re.appendChild(href) - - # write good properties - if good_props and len(good_props.items()): - ps=doc.createElement("D:propstat") - - gp=doc.createElement("D:prop") - for ns in good_props.keys(): - ns_prefix="ns"+str(self.namespaces.index(ns))+":" - for p,v in good_props[ns].items(): - pe=doc.createElement(ns_prefix+str(p)) - if v == None: - pass - elif ns=='DAV:' and p=="resourcetype": - if v == 1: - ve=doc.createElement("D:collection") - pe.appendChild(ve) - elif isinstance(v,tuple) and v[1] == ns: - ve=doc.createElement(ns_prefix+v[0]) - pe.appendChild(ve) - else: - ve=doc.createTextNode(utf8str(v)) - pe.appendChild(ve) - - gp.appendChild(pe) - if gp.hasChildNodes(): - re.appendChild(ps) - ps.appendChild(gp) - s=doc.createElement("D:status") - t=doc.createTextNode("HTTP/1.1 200 OK") - s.appendChild(t) - ps.appendChild(s) - re.appendChild(ps) - - # now write the errors! - if len(bad_props.items()): - - # write a propstat for each error code - for ecode in bad_props.keys(): - ps=doc.createElement("D:propstat") - re.appendChild(ps) - bp=doc.createElement("D:prop") - ps.appendChild(bp) - - for ns in bad_props[ecode].keys(): - ns_prefix="ns"+str(self.namespaces.index(ns))+":" - - for p in bad_props[ecode][ns]: - pe=doc.createElement(ns_prefix+str(p)) - bp.appendChild(pe) - - s=doc.createElement("D:status") - t=doc.createTextNode(utils.gen_estring(ecode)) - s.appendChild(t) - ps.appendChild(s) - re.appendChild(ps) - - # return the new response element - return re - - def get_propvalues(self,uri): - """ create lists of property values for an URI - - We create two lists for an URI: the properties for - which we found a value and the ones for which we - only got an error, either because they haven't been - found or the user is not allowed to read them. - - """ - good_props={} - bad_props={} - - for (ns,plist) in self.proplist.items(): - good_props[ns]={} - bad_props={} - ec = 0 - for prop in plist: - try: - ec = 0 - r=self.__dataclass.get_prop(uri,ns,prop) - good_props[ns][prop]=r - except DAV_Error, error_code: - ec=error_code[0] - - # ignore props with error_code if 0 (invisible) - if ec==0: continue - - if bad_props.has_key(ec): - if bad_props[ec].has_key(ns): - bad_props[ec][ns].append(prop) - else: - bad_props[ec][ns]=[prop] - else: - bad_props[ec]={ns:[prop]} - - return good_props, bad_props - diff --git a/addons/document_webdav/DAV/status.py b/addons/document_webdav/DAV/status.py deleted file mode 100644 index 62cb323c4fb..00000000000 --- a/addons/document_webdav/DAV/status.py +++ /dev/null @@ -1,31 +0,0 @@ -""" - -status codes for DAV services - - -""" - - -STATUS_CODES={ - 102: "Processing", - 200: "Ok", - 201: "Created", - 204: "No Content", - 207: "Multi-Status", - 201: "Created", - 400: "Bad Request", - 403: "Forbidden", - 404: "Not Found", - 405: "Method Not Allowed", - 409: "Conflict", - 412: "Precondition failed", - 423: "Locked", - 415: "Unsupported Media Type", - 507: "Insufficient Storage", - 422: "Unprocessable Entity", - 423: "Locked", - 424: "Failed Dependency", - 502: "Bad Gateway", - 507: "Insufficient Storage", - 999: "Some error in Create Method please check the data of create method" -} diff --git a/addons/document_webdav/DAV/utils.py b/addons/document_webdav/DAV/utils.py deleted file mode 100755 index c4bb4d1a4c0..00000000000 --- a/addons/document_webdav/DAV/utils.py +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env python - -""" - -UTILITIES - -- parse a propfind request body into a list of props - -""" - -from xml.dom import ext -from xml.dom.Document import Document -from xml.dom.ext.reader import PyExpat -from xml.dom import Node -from xml.dom import NodeIterator, NodeFilter - -from string import lower, split, atoi, joinfields -import urlparse -from StringIO import StringIO - -from constants import RT_ALLPROP, RT_PROPNAME, RT_PROP -from status import STATUS_CODES - -VERSION = '0.6' -AUTHOR = 'Simon Pamies <s.pamies@banality.de>' - - -def gen_estring(ecode): - """ generate an error string from the given code """ - ec=atoi(str(ecode)) - if STATUS_CODES.has_key(ec): - return "HTTP/1.1 %s %s" %(ec,STATUS_CODES[ec]) - else: - return "HTTP/1.1 %s" %(ec) - -def parse_propfind(xml_doc): - """ parse an propfind xml file and return a list of props - - returns: - - request_type -- ALLPROP, PROPNAME, PROP - proplist -- list of properties found - namespaces -- list of namespaces found - - """ - doc = PyExpat.Reader().fromString(xml_doc) - snit = doc.createNodeIterator(doc, NodeFilter.NodeFilter.SHOW_ELEMENT, None, None) - - request_type=None - props={} - namespaces=[] - - while 1: - curr_elem = snit.nextNode() - if not curr_elem: break - ename=fname=lower(curr_elem.nodeName) - if ":" in fname: - ename=split(fname,":")[1] - if ename=="prop": request_type=RT_PROP; continue - if ename=="propfind": continue - if ename=="allprop": request_type=RT_ALLPROP; continue - if ename=="propname": request_type=RT_PROPNAME; continue - - # rest should be names of attributes - - ns = curr_elem.namespaceURI - if props.has_key(ns): - props[ns].append(ename) - else: - props[ns]=[ename] - namespaces.append(ns) - - return request_type,props,namespaces - - -def create_treelist(dataclass,uri): - """ create a list of resources out of a tree - - This function is used for the COPY, MOVE and DELETE methods - - uri - the root of the subtree to flatten - - It will return the flattened tree as list - - """ - queue=[uri] - list=[uri] - while len(queue): - element=queue[-1] - if dataclass.is_collection(element): - childs=dataclass.get_childs(element) - else: - childs=[] - if len(childs): - list=list+childs - # update queue - del queue[-1] - if len(childs): - queue=queue+childs - return list - -def is_prefix(uri1,uri2): - """ returns 1 of uri1 is a prefix of uri2 """ - if uri2[:len(uri1)]==uri1: - return 1 - else: - return None - -def quote_uri(uri): - """ quote an URL but not the protocol part """ - import urlparse - import urllib - - up=urlparse.urlparse(uri) - np=urllib.quote(up[2]) - return urlparse.urlunparse((up[0],up[1],np,up[3],up[4],up[5])) - -def get_uriparentpath(uri): - """ extract the uri path and remove the last element """ - up=urlparse.urlparse(uri) - return joinfields(split(up[2],"/")[:-1],"/") - -def get_urifilename(uri): - """ extract the uri path and return the last element """ - up=urlparse.urlparse(uri) - return split(up[2],"/")[-1] - -def get_parenturi(uri): - """ return the parent of the given resource""" - up=urlparse.urlparse(uri) - np=joinfields(split(up[2],"/")[:-1],"/") - return urlparse.urlunparse((up[0],up[1],np,up[3],up[4],up[5])) - -### XML utilities - -def make_xmlresponse(result): - """ construct a response from a dict of uri:error_code elements """ - doc = Document(None) - ms=doc.createElement("D:multistatus") - ms.setAttribute("xmlns:D","DAV:") - doc.appendChild(ms) - - for el,ec in result.items(): - re=doc.createElement("D:response") - hr=doc.createElement("D:href") - st=doc.createElement("D:status") - huri=doc.createTextNode(quote_uri(el)) - t=doc.createTextNode(gen_estring(ec)) - st.appendChild(t) - hr.appendChild(huri) - re.appendChild(hr) - re.appendChild(st) - ms.appendChild(re) - - sfile=StringIO() - ext.PrettyPrint(doc,stream=sfile) - s=sfile.getvalue() - sfile.close() - return s - diff --git a/addons/document_webdav/__terp__.py b/addons/document_webdav/__terp__.py index ce11511d0fa..24893c275e1 100644 --- a/addons/document_webdav/__terp__.py +++ b/addons/document_webdav/__terp__.py @@ -34,8 +34,9 @@ "author" : "Tiny", "category" : "Generic Modules/Others", "website": "http://www.openerp.com", - "description": """ With this module, the WebDAV server for the documents is activated. You can then use any compatible browser to remotely see the attachments of OpenObject. - + "description": """ With this module, the WebDAV server for the documents is activated. + You can then use any compatible browser to remotely see the attachments of OpenObject. + After installation, the webDAV server can be controlled by a [webdav] section in the server's config. """, "depends" : ["base", "document"], diff --git a/addons/document_webdav/dav_fs.py b/addons/document_webdav/dav_fs.py index 1acbfd7d5ec..9ef91e0f9a6 100644 --- a/addons/document_webdav/dav_fs.py +++ b/addons/document_webdav/dav_fs.py @@ -59,67 +59,47 @@ class tinydav_handler(dav_interface): """ This class models a Tiny ERP interface for the DAV server """ - PROPS={'DAV:': dav_interface.PROPS['DAV:'], } + PROPS={'DAV:': dav_interface.PROPS['DAV:'],} - M_NS={ "DAV:" : dav_interface.M_NS['DAV:'], } + M_NS={ "DAV:" : dav_interface.M_NS['DAV:'],} - def __init__(self, parent, verbose=False): + def __init__(self, parent, verbose=False): self.db_name = False self.directory_id=False self.db_name_list=[] self.parent = parent self.baseuri = parent.baseuri - - def get_propnames(self,uri): - props = self.PROPS - self.parent.log_message('get propnames: %s' % uri) - if uri[-1]=='/':uri=uri[:-1] - cr, uid, pool, dbname, uri2 = self.get_cr(uri) - if not dbname: - cr.close() - return props - node = self.uri2object(cr,uid,pool, uri2) - if node: - props.update(node.get_dav_props(cr)) - cr.close() - return props - - def get_prop(self,uri,ns,propname): - """ return the value of a given property - - uri -- uri of the object to get the property of - ns -- namespace of the property - pname -- name of the property - """ - if self.M_NS.has_key(ns): - return dav_interface.get_prop(self,uri,ns,propname) - - if uri[-1]=='/':uri=uri[:-1] - cr, uid, pool, dbname, uri2 = self.get_cr(uri) - if not dbname: - cr.close() - raise DAV_NotFound - node = self.uri2object(cr,uid,pool, uri2) - if not node: - cr.close() - raise DAV_NotFound - res = node.get_dav_eprop(cr,ns,propname) - cr.close() - return res - -# -# def get_db(self,uri): -# names=self.uri2local(uri).split('/') -# self.db_name=False -# if len(names) > 1: -# self.db_name=self.uri2local(uri).split('/')[1] -# if self.db_name=='': -# raise Exception,'Plese specify Database name in folder' -# return self.db_name -# - - def later_get_db_from_path(self,path): - return "aaa" + self.verbose = verbose + + def get_propnames(self,uri): + props = self.PROPS + return props + + def _get_dav_lockdiscovery(self, uri): + raise DAV_NotFound + + def _get_dav_supportedlock(self, uri): + raise DAV_NotFound + def get_prop(self,uri,ns,propname): + """ return the value of a given property + + uri -- uri of the object to get the property of + ns -- namespace of the property + pname -- name of the property + """ + if self.M_NS.has_key(ns): + return dav_interface.get_prop(self,uri,ns,propname) + raise DAV_NotFound + + def get_db(self,uri): + names=self.uri2local(uri).split('/') + self.db_name=False + if len(names) > 1: + self.db_name=self.uri2local(uri).split('/')[1] + if self.db_name=='': + raise Exception,'Plese specify Database name in folder' + return self.db_name + def urijoin(self,*ajoin): """ Return the base URI of this request, or even join it with the @@ -130,7 +110,7 @@ class tinydav_handler(dav_interface): @memoize(4) def db_list(self): s = netsvc.ExportService.getService('db') - result = s.list() + result = s.exp_list() self.db_name_list=[] for db_name in result: db = pooler.get_db_only(db_name) @@ -146,16 +126,17 @@ class tinydav_handler(dav_interface): """ return the child objects as self.baseuris for the given URI """ self.parent.log_message('get childs: %s' % uri) if uri[-1]=='/':uri=uri[:-1] - cr, uid, pool, dbname, uri2 = self.get_cr(uri) + cr, uid, pool, dbname, uri2 = self.get_cr(uri) - if not dbname: - s = netsvc.ExportService.getService('db') - cr.close() - return map(lambda x: self.urijoin(x), self.db_list()) + if not dbname: + if cr: cr.close() + res = map(lambda x: self.urijoin(x), self.db_list()) + return res result = [] node = self.uri2object(cr,uid,pool, uri2[:]) + if not node: - cr.close() + if cr: cr.close() raise DAV_NotFound(uri2) else: fp = node.full_path() @@ -165,12 +146,13 @@ class tinydav_handler(dav_interface): else: fp = None for d in node.children(cr): - self.parent.log_message('child: %s' % d.path) + self.parent.log_message('child: %s' % d.path) if fp: result.append( self.urijoin(dbname,fp,d.path) ) else: result.append( self.urijoin(dbname,d.path) ) - cr.close() + if cr: cr.close() + return result def uri2local(self, uri): @@ -183,24 +165,28 @@ class tinydav_handler(dav_interface): # # pos: -1 to get the parent of the uri # - def get_cr(self, uri): + def get_cr(self, uri): pdb = self.parent.auth_proxy.last_auth reluri = self.uri2local(uri) try: - dbname = reluri.split('/')[2] + dbname = reluri.split('/')[1] except: - dbname = False + dbname = False if not dbname: return None, None, None, False, None if not pdb and dbname: # if dbname was in our uri, we should have authenticated # against that. raise Exception("Programming error") - assert pdb == dbname, " %s != %s" %(pdb, dbname) - user, passwd, dbn2, uid = self.parent.auth_proxy.auth_creds[pdb] + #assert pdb == dbname, " %s != %s" %(pdb, dbname) + res = self.parent.auth_proxy.auth_creds.get(dbname, False) + if not res: + self.parent.auth_proxy.checkRequest(self.parent, uri, dbname) + res = self.parent.auth_proxy.auth_creds[dbname] + user, passwd, dbn2, uid = res db,pool = pooler.get_db_and_pool(dbname) cr = db.cursor() - uri2 = reluri.split('/')[3:] + uri2 = reluri.split('/')[2:] return cr, uid, pool, dbname, uri2 def uri2object(self, cr,uid, pool,uri): @@ -208,20 +194,20 @@ class tinydav_handler(dav_interface): return None return pool.get('document.directory').get_object(cr, uid, uri) - def get_data(self,uri): + def get_data(self,uri): self.parent.log_message('GET: %s' % uri) if uri[-1]=='/':uri=uri[:-1] cr, uid, pool, dbname, uri2 = self.get_cr(uri) try: if not dbname: raise DAV_Error, 409 - node = self.uri2object(cr,uid,pool, uri2) + node = self.uri2object(cr,uid,pool, uri2) if not node: raise DAV_NotFound(uri2) try: datas = node.get_data(cr) except TypeError,e: - import traceback + import traceback self.parent.log_error("GET typeError: %s", str(e)) self.parent.log_message("Exc: %s",traceback.format_exc()) raise DAV_Forbidden @@ -235,11 +221,11 @@ class tinydav_handler(dav_interface): raise DAV_Error, 409 return datas finally: - cr.close() + if cr: cr.close() @memoize(CACHE_SIZE) def _get_dav_resourcetype(self,uri): - """ return type of object """ + """ return type of object """ self.parent.log_message('get RT: %s' % uri) if uri[-1]=='/':uri=uri[:-1] cr, uid, pool, dbname, uri2 = self.get_cr(uri) @@ -253,7 +239,7 @@ class tinydav_handler(dav_interface): return COLLECTION return OBJECT finally: - cr.close() + if cr: cr.close() def _get_dav_displayname(self,uri): self.parent.log_message('get DN: %s' % uri) @@ -271,14 +257,14 @@ class tinydav_handler(dav_interface): @memoize(CACHE_SIZE) def _get_dav_getcontentlength(self,uri): - """ return the content length of an object """ + """ return the content length of an object """ self.parent.log_message('get length: %s' % uri) if uri[-1]=='/':uri=uri[:-1] result = 0 - cr, uid, pool, dbname, uri2 = self.get_cr(uri) + cr, uid, pool, dbname, uri2 = self.get_cr(uri) if not dbname: - cr.close() - return '0' + if cr: cr.close() + return str(result) node = self.uri2object(cr, uid, pool, uri2) if not node: cr.close() @@ -311,9 +297,9 @@ class tinydav_handler(dav_interface): if uri[-1]=='/':uri=uri[:-1] today = time.time() cr, uid, pool, dbname, uri2 = self.get_cr(uri) - try: - if not dbname: - return today + if not dbname: + return today + try: node = self.uri2object(cr,uid,pool, uri2) if not node: raise DAV_NotFound(uri2) @@ -322,36 +308,35 @@ class tinydav_handler(dav_interface): else: return today finally: - cr.close() + if cr: cr.close() @memoize(CACHE_SIZE) def get_creationdate(self,uri): - """ return the last modified date of the object """ - + """ return the last modified date of the object """ if uri[-1]=='/':uri=uri[:-1] cr, uid, pool, dbname, uri2 = self.get_cr(uri) - try: - if not dbname: - raise DAV_Error, 409 + if not dbname: + raise DAV_Error, 409 + try: node = self.uri2object(cr,uid,pool, uri2) if not node: - raise DAV_NotFound(uri2) + raise DAV_NotFound(uri2) if node.create_date: - result = time.strptime(node.create_date,'%Y-%m-%d %H:%M:%S') + result = time.mktime(time.strptime(node.create_date,'%Y-%m-%d %H:%M:%S')) else: - result = time.gmtime() + result = time.time() return result finally: - cr.close() + if cr: cr.close() @memoize(CACHE_SIZE) def _get_dav_getcontenttype(self,uri): self.parent.log_message('get contenttype: %s' % uri) if uri[-1]=='/':uri=uri[:-1] cr, uid, pool, dbname, uri2 = self.get_cr(uri) - try: - if not dbname: - return 'httpd/unix-directory' + if not dbname: + return 'httpd/unix-directory' + try: node = self.uri2object(cr,uid,pool, uri2) if not node: raise DAV_NotFound(uri2) @@ -359,8 +344,8 @@ class tinydav_handler(dav_interface): return result #raise DAV_NotFound, 'Could not find %s' % path finally: - cr.close() - + if cr: cr.close() + def mkcol(self,uri): """ create a new collection """ self.parent.log_message('MKCOL: %s' % uri) @@ -401,7 +386,7 @@ class tinydav_handler(dav_interface): def put(self,uri,data,content_type=None): """ put the object into the filesystem """ - self.parent.log_message('Putting %s (%d), %s'%( misc.ustr(uri), len(data), content_type)) + self.parent.log_message('Putting %s (%d), %s'%( misc.ustr(uri), data and len(data) or 0, content_type)) parent='/'.join(uri.split('/')[:-1]) cr, uid, pool,dbname, uri2 = self.get_cr(uri) if not dbname: @@ -633,7 +618,7 @@ class tinydav_handler(dav_interface): result = False cr, uid, pool,dbname, uri2 = self.get_cr(uri) if not dbname: - cr.close() + if cr: cr.close() return True try: node = self.uri2object(cr,uid,pool, uri2) diff --git a/addons/document_webdav/i18n/bg.po b/addons/document_webdav/i18n/bg.po index 9451c33b577..1a13fa82450 100644 --- a/addons/document_webdav/i18n/bg.po +++ b/addons/document_webdav/i18n/bg.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-11 05:05+0000\n" +"X-Launchpad-Export-Date: 2010-03-30 04:16+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: document_webdav_old diff --git a/addons/document_webdav/i18n/cs.po b/addons/document_webdav/i18n/cs.po index 361163c0b5c..13fafd57c49 100644 --- a/addons/document_webdav/i18n/cs.po +++ b/addons/document_webdav/i18n/cs.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-11 05:05+0000\n" +"X-Launchpad-Export-Date: 2010-03-30 04:16+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: document_webdav_old diff --git a/addons/document_webdav/i18n/de.po b/addons/document_webdav/i18n/de.po index e4e13ad5676..fd265104057 100644 --- a/addons/document_webdav/i18n/de.po +++ b/addons/document_webdav/i18n/de.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-11 05:05+0000\n" +"X-Launchpad-Export-Date: 2010-03-30 04:16+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: document_webdav_old diff --git a/addons/document_webdav/i18n/es.po b/addons/document_webdav/i18n/es.po index 0b5a0e57f8b..d480732519a 100644 --- a/addons/document_webdav/i18n/es.po +++ b/addons/document_webdav/i18n/es.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-11 05:05+0000\n" +"X-Launchpad-Export-Date: 2010-03-30 04:16+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: document_webdav_old diff --git a/addons/document_webdav/i18n/hr.po b/addons/document_webdav/i18n/hr.po index aa00f7164f5..72927b920b1 100644 --- a/addons/document_webdav/i18n/hr.po +++ b/addons/document_webdav/i18n/hr.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-11 05:05+0000\n" +"X-Launchpad-Export-Date: 2010-03-30 04:16+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: document_webdav_old diff --git a/addons/document_webdav/i18n/pt.po b/addons/document_webdav/i18n/pt.po index e1e72dd3917..a82237dfdfe 100644 --- a/addons/document_webdav/i18n/pt.po +++ b/addons/document_webdav/i18n/pt.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-11 05:05+0000\n" +"X-Launchpad-Export-Date: 2010-03-30 04:16+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: document_webdav_old diff --git a/addons/document_webdav/i18n/pt_BR.po b/addons/document_webdav/i18n/pt_BR.po new file mode 100644 index 00000000000..057d27ed21c --- /dev/null +++ b/addons/document_webdav/i18n/pt_BR.po @@ -0,0 +1,31 @@ +# Brazilian Portuguese translation for openobject-addons +# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR <EMAIL@ADDRESS>, 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" +"POT-Creation-Date: 2009-05-30 15:14+0000\n" +"PO-Revision-Date: 2010-03-24 01:18+0000\n" +"Last-Translator: Pedro_Maschio <pedro.bicudo@tgtconsult.com.br>\n" +"Language-Team: Brazilian Portuguese <pt_BR@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2010-03-30 04:16+0000\n" +"X-Generator: Launchpad (build Unknown)\n" + +#. module: document_webdav_old +#: model:ir.module.module,description:document_webdav_old.module_meta_information +msgid "" +"This is a complete document management system:\n" +"\t* WebDav Interface\n" +"\t* User Authentification\n" +"\t* Document Indexation\n" +msgstr "" +"Este é um gerenciador de documentos completo:\n" +"\t* WebDav Interface\n" +"\t* User Authentification\n" +"\t* Document Indexation\n" diff --git a/addons/document_webdav/i18n/sl.po b/addons/document_webdav/i18n/sl.po index c31fb814d12..71e574e1c98 100644 --- a/addons/document_webdav/i18n/sl.po +++ b/addons/document_webdav/i18n/sl.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-11 05:05+0000\n" +"X-Launchpad-Export-Date: 2010-03-30 04:16+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: document_webdav_old diff --git a/addons/document_webdav/i18n/sv.po b/addons/document_webdav/i18n/sv.po index d3bf8a5ca01..d88fb7be7e9 100644 --- a/addons/document_webdav/i18n/sv.po +++ b/addons/document_webdav/i18n/sv.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-11 05:05+0000\n" +"X-Launchpad-Export-Date: 2010-03-30 04:16+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: document_webdav_old diff --git a/addons/document_webdav/i18n/zh_CN.po b/addons/document_webdav/i18n/zh_CN.po index a7bf9604416..0fbb3657c57 100644 --- a/addons/document_webdav/i18n/zh_CN.po +++ b/addons/document_webdav/i18n/zh_CN.po @@ -1,20 +1,19 @@ -# Chinese (Simplified) translation for openobject-addons -# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR <EMAIL@ADDRESS>, 2010. +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# * document_ics # msgid "" msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" +"Project-Id-Version: OpenERP Server 5.0.6\n" +"Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2009-05-30 15:14+0000\n" -"PO-Revision-Date: 2010-01-10 01:57+0000\n" -"Last-Translator: Wei \"oldrev\" Li <oldrev@gmail.com>\n" -"Language-Team: Chinese (Simplified) <zh_CN@li.org>\n" +"PO-Revision-Date: 2010-03-20 08:21+0000\n" +"Last-Translator: Black Jack <onetimespeed@hotmail.com>\n" +"Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-11 05:05+0000\n" +"X-Launchpad-Export-Date: 2010-03-30 04:16+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: document_webdav_old @@ -29,3 +28,185 @@ msgstr "" "\t* WebDav 接口\n" "\t* 用户认证\n" "\t* 文档索引\n" + +#~ msgid "" +#~ "The Object name must start with x_ and not contain any special character !" +#~ msgstr "对象名必须要以X_开头并且不能含有特殊字符!" + +#~ msgid "Error! You can not create recursive Directories." +#~ msgstr "错误:你无法建立递归的目录" + +#~ msgid "Jobs Hiring Process" +#~ msgstr "招聘过程" + +#~ msgid "Configure Calendars for CRM Sections" +#~ msgstr "客户关系管理部分设置日程表" + +#~ msgid "Helpdesk" +#~ msgstr "求助" + +#~ msgid "Open ERP Field" +#~ msgstr "系统字段" + +#~ msgid "Next" +#~ msgstr "下一个" + +#~ msgid "Content" +#~ msgstr "内容" + +#~ msgid "Calendar of Meetings" +#~ msgstr "会议日程表" + +#~ msgid "Shared Calendar Meetings" +#~ msgstr "共享的会议日程表" + +#~ msgid "Invalid model name in the action definition." +#~ msgstr "在这动作定义中有无效的模块名" + +#~ msgid "Used by companies to track bugs and support requests on softwares" +#~ msgstr "公司用于跟踪缺陷和支持请求的软件" + +#~ msgid "" +#~ "This Configuration step use to create Calendars in document for all Case " +#~ "Sections" +#~ msgstr "这设置步骤用于创建在所有业务个案项文档的日程表" + +#~ msgid "dtend" +#~ msgstr "结束" + +#~ msgid "" +#~ "Help you to organise the jobs hiring process: evaluation, meetings, email " +#~ "integration..." +#~ msgstr "帮助你组织招聘过程:评论,会议,电子邮件一体化" + +#~ msgid "description" +#~ msgstr "说明" + +#~ msgid "Configure Calendars for Sections " +#~ msgstr "部分设置日程表 " + +#~ msgid "Tracks identified business opportunities for your sales pipeline." +#~ msgstr "从你的销售管线跟踪出销售机会" + +#~ msgid "" +#~ "This may help associations in their fund raising process and tracking." +#~ msgstr "这可能有助于协会在资助和投资过程和跟踪" + +#~ msgid "Manages an Helpdesk service." +#~ msgstr "管理求助服务" + +#~ msgid "Fund Raising Operations" +#~ msgstr "资助和投资行动" + +#~ msgid "Object" +#~ msgstr "对象" + +#~ msgid "Error ! You cannot create recursive sections." +#~ msgstr "错误!你不能创建递归的项" + +#~ msgid "Support for iCal based on Document Management System" +#~ msgstr "支持iCal的文档管理系统" + +#~ msgid "" +#~ " Will allow you to synchronise your Open ERP calendars with your phone, " +#~ "outlook, Sunbird, ical, ..." +#~ msgstr " 允许同步系统日程表,电话等等" + +#~ msgid "location" +#~ msgstr "本地" + +#~ msgid "ICS Calendar" +#~ msgstr "ICS日程表" + +#~ msgid "ICS Value" +#~ msgstr "ICS值" + +#~ msgid "Allows to synchronise calendars with others applications." +#~ msgstr "允许的同步其它应用日程表" + +#~ msgid "Invalid XML for View Architecture!" +#~ msgstr "无效XML视图结构!" + +#~ msgid "" +#~ "Allows you to track and manage prospects which are pre-sales requests or " +#~ "contacts, the very first contact with a customer request." +#~ msgstr "允许你跟踪管理潜在客户的售前请求和联系,初次联系客户的请求" + +#~ msgid "Name" +#~ msgstr "名称" + +#~ msgid "Manages the calendar of meetings of the users." +#~ msgstr "管理用户的会议日程表" + +#~ msgid "Domain" +#~ msgstr "隶属" + +#~ msgid "" +#~ "Manages the supplier and customers claims, including your corrective or " +#~ "preventive actions." +#~ msgstr "管理这支援和客户服务要求包括你的纠正或预防" + +#~ msgid "last-modified" +#~ msgstr "最近修改" + +#~ msgid "ICS Mapping" +#~ msgstr "ICS一览" + +#~ msgid "Duration(In Hour)" +#~ msgstr "持续时间(小时)" + +#~ msgid "Shared Calendar" +#~ msgstr "共享的日程表" + +#~ msgid "Claims" +#~ msgstr "服务要求" + +#~ msgid "" +#~ "Help you to encode the result of a phone call or to planify a list of phone " +#~ "calls to process." +#~ msgstr "帮助你编电话呼叫结果或编制电话呼叫处理的列表" + +#~ msgid "dtstart" +#~ msgstr "开始" + +#~ msgid "Phone Calls" +#~ msgstr "电话呼叫" + +#~ msgid "Bug Tracking" +#~ msgstr "缺陷跟踪" + +#~ msgid "categories" +#~ msgstr "分类" + +#~ msgid "Prospect" +#~ msgstr "潜在客户" + +#~ msgid "Create Pre-Configured Calendars" +#~ msgstr "创建预先设置的日程表" + +#~ msgid "created" +#~ msgstr "创建" + +#~ msgid "Calendar Code" +#~ msgstr "日程表代码" + +#~ msgid "summary" +#~ msgstr "参考" + +#~ msgid "attendee" +#~ msgstr "出勤者" + +#~ msgid "document.directory.ics.fields" +#~ msgstr "字段" + +#~ msgid "Fields Mapping" +#~ msgstr "字段一览" + +#~ msgid "Cancel" +#~ msgstr "取消" + +#~ msgid "Business Opportunities" +#~ msgstr "销售机会" + +#~ msgid "dtstamp" +#~ msgstr "标记" diff --git a/addons/document_webdav/webdav_server.py b/addons/document_webdav/webdav_server.py index 15e8e030824..f2c129dd608 100644 --- a/addons/document_webdav/webdav_server.py +++ b/addons/document_webdav/webdav_server.py @@ -28,10 +28,113 @@ import netsvc +import tools from dav_fs import tinydav_handler from tools.config import config from DAV.WebDAVServer import DAVRequestHandler from service.websrv_lib import HTTPDir,FixSendError +from DAV.propfind import PROPFIND + +import xml.dom.minidom +domimpl = xml.dom.minidom.getDOMImplementation() +import urlparse +import urllib +from DAV import utils + +super_mk_prop_response = PROPFIND.mk_prop_response +def mk_prop_response(self,uri,good_props,bad_props,doc): + """ make a new <prop> result element + + We differ between the good props and the bad ones for + each generating an extra <propstat>-Node (for each error + one, that means). + + """ + re=doc.createElement("D:response") + # append namespaces to response + nsnum=0 + for nsname in self.namespaces: + re.setAttribute("xmlns:ns"+str(nsnum),nsname) + nsnum=nsnum+1 + + # write href information + uparts=urlparse.urlparse(uri) + fileloc=uparts[2] + href=doc.createElement("D:href") + huri=doc.createTextNode(uparts[0]+'://'+'/'.join(uparts[1:2]) + urllib.quote(fileloc)) + href.appendChild(huri) + re.appendChild(href) + + # write good properties + ps=doc.createElement("D:propstat") + if good_props: + re.appendChild(ps) + + gp=doc.createElement("D:prop") + for ns in good_props.keys(): + ns_prefix="ns"+str(self.namespaces.index(ns))+":" + for p,v in good_props[ns].items(): + if not v: + pass + pe=doc.createElement(ns_prefix+str(p)) + if hasattr(v, '__class__') and v.__class__.__name__ == 'Element': + pe.appendChild(v) + else: + if p=="resourcetype": + if v==1: + ve=doc.createElement("D:collection") + pe.appendChild(ve) + else: + ve=doc.createTextNode(tools.ustr(v)) + pe.appendChild(ve) + + gp.appendChild(pe) + + ps.appendChild(gp) + s=doc.createElement("D:status") + t=doc.createTextNode("HTTP/1.1 200 OK") + s.appendChild(t) + ps.appendChild(s) + re.appendChild(ps) + + # now write the errors! + if len(bad_props.items()): + + # write a propstat for each error code + for ecode in bad_props.keys(): + ps=doc.createElement("D:propstat") + re.appendChild(ps) + bp=doc.createElement("D:prop") + ps.appendChild(bp) + + for ns in bad_props[ecode].keys(): + ns_prefix="ns"+str(self.namespaces.index(ns))+":" + + for p in bad_props[ecode][ns]: + pe=doc.createElement(ns_prefix+str(p)) + bp.appendChild(pe) + + s=doc.createElement("D:status") + t=doc.createTextNode(utils.gen_estring(ecode)) + s.appendChild(t) + ps.appendChild(s) + re.appendChild(ps) + + # return the new response element + return re + + +PROPFIND.mk_prop_response = mk_prop_response + +def OpenDAVConfig(**kw): + class OpenDAV: + def __init__(self, **kw): + self.__dict__.update(**kw) + + class Config: + DAV = OpenDAV(**kw) + + return Config() class DAVHandler(FixSendError,DAVRequestHandler): verbose = False @@ -43,16 +146,24 @@ class DAVHandler(FixSendError,DAVRequestHandler): netsvc.Logger().notifyChannel("webdav",netsvc.LOG_DEBUG,message) def handle(self): - pass + self._init_buffer() def finish(self): pass + def get_db_from_path(self, uri): + if uri or uri == '/': + dbs = self.IFACE_CLASS.db_list() + res = len(dbs) and dbs[0] or False + else: + res = self.IFACE_CLASS.get_db(uri) + return res + def setup(self): - davpath = '/'+config.get_misc('webdav','vdir','webdav')+'/' - self.baseuri = "http://%s:%d%s"% (self.server.server_name,self.server.server_port,davpath) - self.IFACE_CLASS = tinydav_handler(self) - pass + davpath = '/'+config.get_misc('webdav','vdir','webdav') + self.baseuri = "http://%s:%d/"% (self.server.server_name,self.server.server_port) + self.IFACE_CLASS = tinydav_handler(self, self.verbose) + def log_message(self, format, *args): netsvc.Logger().notifyChannel('webdav',netsvc.LOG_DEBUG_RPC,format % args) @@ -62,14 +173,23 @@ class DAVHandler(FixSendError,DAVRequestHandler): try: - from service.http_server import reg_http_service,OpenERPAuthProvider + from service.http_server import reg_http_service,OpenERPAuthProvider + if (config.get_misc('webdav','enable',True)): - davpath = '/'+config.get_misc('webdav','vdir','webdav')+'/' + directory = '/'+config.get_misc('webdav','vdir','webdav') handler = DAVHandler - handler.verbose = config.get_misc('webdav','verbose',True) + verbose = config.get_misc('webdav','verbose',True) handler.debug = config.get_misc('webdav','debug',True) - reg_http_service(HTTPDir(davpath,DAVHandler,OpenERPAuthProvider())) - netsvc.Logger().notifyChannel('webdav',netsvc.LOG_INFO,"WebDAV service registered at path: %s/ "% davpath) + _dc = { 'verbose' : verbose, + 'directory' : directory, + 'lockemulation' : False, + + } + + conf = OpenDAVConfig(**_dc) + handler._config = conf + reg_http_service(HTTPDir(directory,DAVHandler,OpenERPAuthProvider())) + netsvc.Logger().notifyChannel('webdav',netsvc.LOG_INFO,"WebDAV service registered at path: %s/ "% directory) except Exception, e: logger = netsvc.Logger() logger.notifyChannel('webdav', netsvc.LOG_ERROR, 'Cannot launch webdav: %s' % e) |
