Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src/webdav/Utils.py
blob: ec05755d251e160ce37f810af10cf6eb57837d8d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# pylint: disable-msg=W0141,R0912
#
# Copyright 2008 German Aerospace Center (DLR)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


"""
The module contains functions to support use of the WebDav functionalities.
"""


import os
import sys

from webdav.WebdavClient import CollectionStorer, ResourceStorer
from webdav.Constants import NS_DAV, PROP_RESOURCE_TYPE, CODE_NOT_FOUND, PROP_RESOURCE_TYPE_RESOURCE
from webdav.Connection import WebdavError


__version__ = "$Revision$"[11:-2]


def resourceExists(node, name = None, resourceType = PROP_RESOURCE_TYPE_RESOURCE):
    """
    Check if resource exists.
    
    Usage:
      - resourceExists(ResourceStorer-object):
        check if resource exists
      - resourceExists(CollectionStorer-object, name):
        check if resource name exists in collection
    
    @param node: node that has to be checked or node of collection
    @type node: L{ResourceStorer<webdav.WebdavClient.ResourceStorer>}
    @param name: name of resource (in collection node) that has to be checked
    @type name: string
    
    @return: boolean
    
    @raise WebdavError: all WebDAV errors except WebDAV error 404 (not found)
    """
    
    exists = False
    if not node:
        return exists
    try:
        myResourceType = ""
        if name:
            # make sure it's unicode:
            if not isinstance(name, unicode):
                name = name.decode(sys.getfilesystemencoding())
            url = node.url
            if url.endswith("/"):
                url = url  + name
            else:
                url = url + "/" + name
            newNode = ResourceStorer(url, node.connection)
            element = newNode.readProperty(NS_DAV, PROP_RESOURCE_TYPE)
        else: # name is "None":
            element = node.readProperty(NS_DAV, PROP_RESOURCE_TYPE)
        
        if len(element.children) > 0:
            myResourceType = element.children[0].name
        if resourceType == myResourceType or resourceType == PROP_RESOURCE_TYPE_RESOURCE:
            exists = True
        else:
            exists = False
    except WebdavError, wderr:
        if wderr.code == CODE_NOT_FOUND:
            # node doesn't exist -> exists = False:
            exists = False
        else:
            # another exception occured -> "re-raise" it:
            raise
    return exists


def downloadCollectionContent(destinationPath, collectionToDownload):
    """
    Downloads the resources contained to the given directory.
    
    @param destinationPath: Path to download the files to, will be created if it not exists.
    @type destinationPath: C{String}
    @param collectionToDownload: Collection to download the content from.
    @type collectionToDownload: instance of L{CollectionStorer<webdav.WebdavClient.CollectionStorer>}
    
    @raise  WebdavError: If something goes wrong.
    """
    
    from time import mktime, gmtime

    downloadCount = 0

    listOfItems = collectionToDownload.getCollectionContents()
    
    if not os.path.exists(destinationPath):
        try:
            os.makedirs(destinationPath)
        except OSError:
            errorMessage = "Cannot create download destination directory '%s'." % destinationPath
            raise WebdavError(errorMessage)
        
    try:
        itemsInPath = os.listdir(destinationPath)
    except OSError:
        errorMessage = "Cannot read the content of download destination directory '%s'." % destinationPath
        raise WebdavError(errorMessage)
    
    for item in listOfItems:
        # skip collections
        if not isinstance(item[0], CollectionStorer):
            itemSavePath = os.path.join(destinationPath, item[0].name)
            existsItemSavePath = os.path.exists(itemSavePath)
            
            # update?
            if existsItemSavePath:
                try:
                    isUpdateNecessary = mktime(item[1].getLastModified()) > mktime(gmtime(os.path.getmtime(itemSavePath)))
                except (ValueError, OverflowError):
                    isUpdateNecessary = True
                # windows is not case sensitive
                for realItem in itemsInPath:
                    if realItem.lower() == item[0].name.lower():
                        itemsInPath.remove(realItem)
            else:
                isUpdateNecessary = True
            
            # download
            if not existsItemSavePath or (existsItemSavePath and isUpdateNecessary):
                item[0].downloadFile(itemSavePath)
                downloadCount = downloadCount + 1
    
    # delete old items
    try:
        for item in itemsInPath:
            os.remove(os.path.join(destinationPath, item))
    except OSError, e:
        if e.errno == 13:    # permission error
            sys.stderr.write("permission problem on '%s' in %s\n" % (e.filename, e.strerror))
        else:
            raise  
        
    return downloadCount