buildframework/helium/sf/python/pythoncore/lib/fileutils.py
author wbernard
Fri, 13 Aug 2010 14:59:05 +0300
changeset 628 7c4a911dc066
parent 588 c7c26511138f
child 645 b8d81fa19e7d
permissions -rw-r--r--
helium_11.0.0-e00f171ca185
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
     1
#============================================================================ 
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
     2
#Name        : fileutils.py 
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
     3
#Part of     : Helium 
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
     4
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
     5
#Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
     6
#All rights reserved.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
     7
#This component and the accompanying materials are made available
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
     8
#under the terms of the License "Eclipse Public License v1.0"
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
     9
#which accompanies this distribution, and is available
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    10
#at the URL "http://www.eclipse.org/legal/epl-v10.html".
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    11
#
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    12
#Initial Contributors:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    13
#Nokia Corporation - initial contribution.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    14
#
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    15
#Contributors:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    16
#
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    17
#Description:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    18
#===============================================================================
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    19
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    20
"""
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    21
File manipulation related functionalities:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    22
 * Filescanner
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    23
 * rmtree (fixed version)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    24
 * move (fixed version)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    25
"""
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    26
import codecs
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    27
import locale
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    28
import logging
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    29
import os
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    30
import re
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    31
import sys
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    32
import shutil
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    33
import hashlib
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    34
import subprocess
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    35
import string
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    36
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    37
import pathaddition.match
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    38
import stat
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    39
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    40
if os.name == 'nt':
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    41
    import win32api
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    42
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    43
LOGGER = logging.getLogger('fileutils')
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    44
LOGGER_LOCK = logging.getLogger('fileutils.lock')
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    45
#LOGGER.addHandler(logging.FileHandler('default.log'))
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    46
#logging.basicConfig(level=logging.DEBUG)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    47
#LOGGER.setLevel(logging.DEBUG)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    48
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    49
class AbstractScanner(object):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    50
    """ This class implements all the required infrastructure for filescanning. """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    51
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    52
    def __init__(self):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    53
        """ Initialization. """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    54
        self.includes = []
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    55
        self.excludes = []
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    56
        self.includes_files = []
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    57
        self.excludes_files = []
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    58
        self.selectors = []
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    59
        self.filetypes = []
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    60
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    61
    def add_include(self, include):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    62
        """ Adds an include path to the scanner. """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    63
        if include.endswith('/') or include.endswith('\\'):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    64
            include = include + '**'
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    65
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    66
        self.includes.append(include)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    67
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    68
    def add_exclude(self, exclude):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    69
        """ Adds an exclude path to the scanner. """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    70
        if exclude.endswith('/') or exclude.endswith('\\'):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    71
            exclude = exclude + '**'
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    72
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    73
        self.excludes.append(exclude)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    74
        
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    75
    def add_exclude_file(self, exclude):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    76
        """ Adds an exclude file to the scanner. """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    77
        self.excludes_files.append(exclude)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    78
    
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    79
    def add_selector(self, selector):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    80
        """ Add selector to the scanner. """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    81
        self.selectors.append(selector)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    82
        
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    83
    def add_filetype(self, filetype):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    84
        """ Adds a filetype selection to the scanner. """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    85
        self.filetypes.append(filetype)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    86
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    87
    def is_included(self, path):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    88
        """ Returns if path is included by the scanner. """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    89
        LOGGER.debug("is_included: path = " + path)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    90
        if path.replace('\\', '/') in self.includes_files or path in self.includes_files:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    91
            return True
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    92
        for inc in self.includes:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    93
            if self.match(path, inc):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    94
                LOGGER.debug("Included: " + path + " by " + inc)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    95
                return True
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    96
        return False
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    97
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    98
    def is_excluded(self, path):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    99
        """ Returns if path is excluded by the scanner. """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   100
        LOGGER.debug("is_excluded: path = " + path)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   101
        if path.replace('\\', '/') in self.excludes_files or path in self.excludes_files:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   102
            return True
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   103
        for ex in self.excludes:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   104
            if self.match(path, ex):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   105
                LOGGER.debug("Excluded: " + path + " by " + ex)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   106
                return True
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   107
        return False
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   108
    
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   109
    def is_selected(self, path):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   110
        """ Returns if path is selected by all selectors in the scanner. """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   111
        LOGGER.debug("is_selected: path = " + path)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   112
        for selector in self.selectors:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   113
            if not selector.is_selected(path):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   114
                return False
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   115
        LOGGER.debug("Selected: " + path)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   116
        return True
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   117
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   118
    def is_filetype(self, path):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   119
        """ Test if a file matches one filetype. """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   120
        if len(self.filetypes) == 0:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   121
            return True
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   122
        LOGGER.debug("is_filetype: path = " + path)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   123
        for filetype in self.filetypes:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   124
            if self.match(path, filetype):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   125
                LOGGER.debug("Filetype: " + path + " by " + filetype)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   126
                return True
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   127
        return False
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   128
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   129
    def match(self, filename, pattern):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   130
        """ Is filename matching pattern? """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   131
        return pathaddition.match.ant_match(filename, pattern, casesensitive=(os.sep != '\\'))
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   132
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   133
    def test_path(self, root, relpath):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   134
        """ Test if a path matches filetype, include, exclude, and selection process."""
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   135
        return self.is_filetype(relpath) and self.is_included(relpath) \
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   136
                         and not self.is_excluded(relpath) and \
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   137
                         self.is_selected(os.path.join(root, relpath))
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   138
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   139
    def __str__(self):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   140
        """ Returns a string representing this instance. """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   141
        content = []
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   142
        for inc in self.includes:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   143
            content.append('include:' + os.path.normpath(inc))
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   144
        for ex in self.excludes:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   145
            content.append('exclude:' + os.path.normpath(ex))
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   146
        return ';'.join(content)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   147
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   148
    def __repr__(self):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   149
        """ Returns a string representing this instance. """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   150
        return self.__str__()
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   151
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   152
    def scan(self):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   153
        """ Abstract method which much be overriden to implement the scanning process. """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   154
        raise Exception("scan method must be overriden")
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   155
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   156
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   157
class FileScanner(AbstractScanner):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   158
    """Scans the filesystem for files that match the selection paths.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   159
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   160
    The scanner is configured with a root directory. Any number of include
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   161
    and exclude paths can be added. The scan() method is a generator that
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   162
    returns matching files one at a time when called as an iterator.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   163
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   164
    This is a revisited implementation of the filescanner. It now relies on
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   165
    the module pathaddition.match that implements a Ant-like regular expression matcher.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   166
    
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   167
    Rules:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   168
    - Includes and excludes should not start with *
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   169
    - Includes and excludes should not have wildcard searches ending with ** (e.g. wildcard**)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   170
    
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   171
    Supported includes and excludes:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   172
    - filename.txt
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   173
    - filename.*
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   174
    - dir/
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   175
    - dir/*
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   176
    - dir/**    
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   177
    """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   178
    def __init__(self, root_dir):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   179
        """ Initialization. """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   180
        AbstractScanner.__init__(self)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   181
        self.root_dir = os.path.normpath(root_dir)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   182
        if not self.root_dir.endswith(os.sep):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   183
            self.root_dir = self.root_dir + os.sep
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   184
        # Add 1 so the final path separator is removed
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   185
        #self.root_dirLength = len(self.root_dir) + 1
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   186
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   187
    def scan(self):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   188
        """ Scans the files required to zip"""
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   189
        #paths_cache = []
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   190
        
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   191
        excludescopy = self.excludes[:]
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   192
        for f_file in excludescopy:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   193
            if os.path.exists(os.path.normpath(os.path.join(self.root_dir, f_file))):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   194
                self.excludes_files.append(f_file)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   195
                self.excludes.remove(f_file)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   196
        
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   197
        includescopy = self.includes[:]
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   198
        for f_file in includescopy:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   199
            if os.path.exists(os.path.normpath(os.path.join(self.root_dir, f_file))):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   200
                self.includes_files.append(f_file)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   201
                self.includes.remove(f_file)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   202
        
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   203
        LOGGER.debug('Scanning sub-root directories')
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   204
        for root_dir in self.find_subroots():
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   205
            for dirpath, subdirs, files in os.walk(unicode(root_dir)):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   206
                # Let's save the len before it's getting modified.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   207
                subdirsLen = len(subdirs)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   208
                subroot = dirpath[len(self.root_dir):]
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   209
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   210
                dirs_to_remove = []
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   211
                for subdir in subdirs:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   212
                    if self.is_excluded(os.path.join(subroot, subdir)):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   213
                        dirs_to_remove.append(subdir)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   214
                
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   215
                for dir_remove in dirs_to_remove:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   216
                    subdirs.remove(dir_remove)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   217
                
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   218
                LOGGER.debug('Scanning directory: ' + dirpath)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   219
                for file_ in files:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   220
                    path = os.path.join(subroot, file_)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   221
                    if self.is_filetype(path) and self.is_included(path) and \
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   222
                        self.is_selected(os.path.join(dirpath, file_)) and not self.is_excluded(path):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   223
                        ret_path = os.path.join(dirpath, file_)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   224
                        yield ret_path
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   225
            
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   226
                LOGGER.debug('Checking for empty directory: ' + dirpath)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   227
                # Check for including empty directories
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   228
                if self.is_included(subroot) and not self.is_excluded(subroot):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   229
                    if len(files) == 0 and subdirsLen == 0:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   230
                        LOGGER.debug('Including empty dir: ' + dirpath)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   231
                        yield dirpath
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   232
                    
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   233
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   234
    def find_subroots(self):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   235
        """Finds all the subdirectory roots based on the include paths.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   236
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   237
        Often large archive operations define a number of archives from the root
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   238
        of the drive. Walking the tree from the root is very time-consuming, so
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   239
        selecting more specific subdirectory roots improves performance.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   240
        """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   241
        def splitpath(path):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   242
            """ Returns the splitted path"""
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   243
            return path.split(os.sep)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   244
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   245
        root_dirs = []
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   246
        
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   247
        # Look for includes that start with wildcards.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   248
        subdirs_not_usable = False
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   249
        for inc in self.includes + self.includes_files:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   250
            first_path_segment = splitpath(os.path.normpath(inc))[0]
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   251
            if first_path_segment.find('*') != -1:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   252
                subdirs_not_usable = True
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   253
                
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   254
        # Parse all includes for sub-roots
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   255
        if not subdirs_not_usable:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   256
            for inc in self.includes + self.includes_files:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   257
                include = None
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   258
                LOGGER.debug("===> inc %s" % inc)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   259
                contains_globs = False                
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   260
                for pathcomp in splitpath(os.path.normpath(inc)):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   261
                    if pathcomp.find('*') != -1:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   262
                        contains_globs = True
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   263
                        break
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   264
                    else:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   265
                        if include == None:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   266
                            include = pathcomp
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   267
                        else:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   268
                            include = os.path.join(include, pathcomp)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   269
                if not contains_globs:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   270
                    include = os.path.dirname(include) 
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   271
    
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   272
                LOGGER.debug("include %s" % include)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   273
                if include != None:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   274
                    root_dir = os.path.normpath(os.path.join(self.root_dir, include))
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   275
                    is_new_root = True
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   276
                    for root in root_dirs[:]:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   277
                        if destinsrc(root, root_dir):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   278
                            LOGGER.debug("root contains include, skip it")
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   279
                            is_new_root = False
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   280
                            break
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   281
                        if destinsrc(root_dir, root):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   282
                            LOGGER.debug("include contains root, so remove root")
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   283
                            root_dirs.remove(root)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   284
                    if is_new_root:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   285
                        root_dirs.append(root_dir)    
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   286
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   287
        if len(root_dirs) == 0:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   288
            root_dirs = [os.path.normpath(self.root_dir)]
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   289
        LOGGER.debug('Roots = ' + str(root_dirs))
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   290
        return root_dirs
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   291
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   292
    def __str__(self):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   293
        return os.path.normpath(self.root_dir) + ';' + AbstractScanner.__str__(self) 
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   294
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   295
    def __repr__(self):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   296
        return self.__str__()
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   297
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   298
        
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   299
def move(src, dst):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   300
    """Recursively move a file or directory to another location.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   301
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   302
    If the destination is on our current filesystem, then simply use
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   303
    rename.  Otherwise, copy src to the dst and then remove src.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   304
    A lot more could be done here...  A look at a mv.c shows a lot of
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   305
    the issues this implementation glosses over.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   306
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   307
    """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   308
    try:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   309
        os.rename(src, dst)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   310
    except OSError:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   311
        if os.path.isdir(src):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   312
            if destinsrc(src, dst):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   313
                raise Exception, "Cannot move a directory '%s' into itself '%s'." % (src, dst)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   314
            shutil.copytree(src, dst, symlinks=True)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   315
            rmtree(src)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   316
        else:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   317
            shutil.copy2(src, dst)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   318
            os.unlink(src)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   319
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   320
def rmtree(rootdir):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   321
    """ Catch shutil.rmtree failures on Windows when files are read-only. Thanks Google!""" 
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   322
    if sys.platform == 'win32':
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   323
        rootdir = os.path.normpath(rootdir)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   324
        if not os.path.isabs(rootdir):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   325
            rootdir = os.path.join(os.path.abspath('.'), rootdir)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   326
        if not rootdir.startswith('\\\\'):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   327
            rootdir = u"\\\\?\\" + rootdir
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   328
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   329
    def cb_handle_error(fcn, path, excinfo):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   330
        """ Error handler, removing readonly and deleting the file. """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   331
        os.chmod(path, 0666)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   332
        if os.path.isdir(path):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   333
            rmdir(path)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   334
        elif os.path.isfile(path):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   335
            remove(path)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   336
        else:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   337
            fcn(path)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   338
    
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   339
    if 'java' in sys.platform:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   340
        import java.io
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   341
        import org.apache.commons.io.FileUtils
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   342
        f_file = java.io.File(rootdir)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   343
        org.apache.commons.io.FileUtils.deleteDirectory(f_file)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   344
    else:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   345
        return shutil.rmtree(rootdir, onerror=cb_handle_error)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   346
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   347
def destinsrc(src, dst):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   348
    """ Fixed version of destinscr, that doesn't match dst with same root name."""
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   349
    if os.sep == '\\':
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   350
        src = src.lower()
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   351
        dst = dst.lower()
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   352
    src = os.path.abspath(src)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   353
    dst = os.path.abspath(dst)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   354
    if not src.endswith(os.path.sep):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   355
        src += os.path.sep
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   356
    if not dst.endswith(os.path.sep):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   357
        dst += os.path.sep
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   358
    return dst.startswith(src)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   359
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   360
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   361
def which(executable):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   362
    """ Search for executable in the PATH."""
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   363
    pathlist = os.environ['PATH'].split(os.pathsep)
588
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   364
    pathexts = ['']
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   365
    if os.sep == '\\':
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   366
        pathexts = os.environ['PATHEXT'].split(os.pathsep)
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   367
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   368
    for folder in pathlist:
588
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   369
        for pathext in pathexts:
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   370
            exename = executable
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   371
            if os.sep == '\\' and not exename.lower().endswith(pathext.lower()):
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   372
                exename = exename + pathext
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   373
            filename = os.path.join(folder, exename)
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   374
            try:
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   375
                status = os.stat(filename)
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   376
            except os.error:
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   377
                continue
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   378
            # Check if the path is a regular file
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   379
            if stat.S_ISREG(status[stat.ST_MODE]):
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   380
                mode = stat.S_IMODE(status[stat.ST_MODE])
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   381
                if mode & 0111:
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   382
                    return os.path.normpath(filename)
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   383
    return None
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   384
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   385
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   386
def read_policy_content(filename):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   387
    """ Read the policy number from the policy file.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   388
        strict allows to activate the new policy scanning.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   389
    """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   390
    value = None
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   391
    error = ""
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   392
    try:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   393
        LOGGER.debug('Opening policy file: ' + filename)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   394
        policy_data = load_policy_content(filename)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   395
        match = re.match(r'^((?:\d+)|(?:0842[0-9a-zA-Z]{3}))\s*$', policy_data, re.M|re.DOTALL)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   396
        if match != None:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   397
            value = match.group(1)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   398
        else:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   399
            error = "Content of '%s' doesn't match r'^\d+|0842[0-9a-zA-Z]{3}\s*$'." % filename
628
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   400
    except IOError, exc:
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   401
        error = str(exc)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   402
    if value is not None:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   403
        return value
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   404
    # worse case....
628
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   405
    raise IOError(error)
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   406
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   407
def load_policy_content(filename):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   408
    """ Testing policy content loading. """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   409
    data = ''
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   410
    try:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   411
        fileh = codecs.open(filename, 'r', 'ascii')
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   412
        data = fileh.read()
628
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   413
    except ValueError:
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   414
        raise IOError("Error loading '%s' as an ASCII file." % filename)
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   415
    finally:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   416
        fileh.close()
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   417
    return data
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   418
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   419
ENCODING_MATRIX = {
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   420
   codecs.BOM_UTF8: 'utf_8',
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   421
   codecs.BOM_UTF16: 'utf_16',
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   422
   codecs.BOM_UTF16_BE: 'utf_16_be',
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   423
   codecs.BOM_UTF16_LE: 'utf_16_le',
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   424
}
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   425
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   426
def guess_encoding(data):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   427
    """Given a byte string, guess the encoding.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   428
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   429
    First it tries for UTF8/UTF16 BOM.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   430
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   431
    Next it tries the standard 'UTF8', 'ISO-8859-1', and 'cp1252' encodings,
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   432
    Plus several gathered from locale information.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   433
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   434
    The calling program *must* first call locale.setlocale(locale.LC_ALL, '')
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   435
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   436
    If successful it returns (decoded_unicode, successful_encoding)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   437
    If unsuccessful it raises a ``UnicodeError``.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   438
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   439
    This was taken from http://www.voidspace.org.uk/python/articles/guessing_encoding.shtml
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   440
    """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   441
    for bom, enc in ENCODING_MATRIX.items():
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   442
        if data.startswith(bom):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   443
            return data.decode(enc), enc
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   444
    encodings = ['ascii', 'UTF-8']
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   445
    successful_encoding = None
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   446
    try:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   447
        encodings.append(locale.getlocale()[1])
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   448
    except (AttributeError, IndexError):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   449
        pass
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   450
    try:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   451
        encodings.append(locale.getdefaultlocale()[1])
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   452
    except (AttributeError, IndexError):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   453
        pass
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   454
    # latin-1
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   455
    encodings.append('ISO8859-1')
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   456
    encodings.append('cp1252')
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   457
    for enc in encodings:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   458
        if not enc:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   459
            continue
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   460
        try:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   461
            decoded = unicode(data, enc)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   462
            successful_encoding = enc
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   463
            break
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   464
        except (UnicodeError, LookupError):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   465
            pass
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   466
    if successful_encoding is None:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   467
        raise UnicodeError('Unable to decode input data. Tried the'
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   468
                           ' following encodings: %s.' %
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   469
                           ', '.join([repr(enc) for enc in encodings if enc]))
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   470
    else:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   471
        if successful_encoding == 'ascii':
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   472
            # our default ascii encoding
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   473
            successful_encoding = 'ISO8859-1'
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   474
        return (decoded, successful_encoding)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   475
        
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   476
def getmd5(fullpath, chunk_size=2**16):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   477
    """ returns the md5 value"""
588
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   478
    for trial in range(3):
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   479
        try:
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   480
            file_handle = open(fullpath, "rb")
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   481
            md5 = hashlib.md5()
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   482
            while 1:
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   483
                chunk = file_handle.read(chunk_size)
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   484
                if not chunk:
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   485
                    break
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   486
                md5.update(chunk)
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   487
            file_handle.close()
628
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   488
        except IOError, exc:
588
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   489
            LOGGER.warning("Error happened on %d trial: %s" % (trial, str(exc)))
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   490
    return md5.hexdigest()
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   491
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   492
def read_symbian_policy_content(filename):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   493
    """ Read the policy category from the policy file. """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   494
    value = None
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   495
    error = ""
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   496
    try:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   497
        LOGGER.debug('Opening symbian policy file: ' + filename)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   498
        try:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   499
            fileh = codecs.open(filename, 'r', 'ascii')
628
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   500
        except ValueError:
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   501
            raise IOError("Error loading '%s' as an ASCII file." % filename)        
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   502
        for line in fileh:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   503
            match = re.match(r'^Category\s+([A-Z])\s*$', line, re.M|re.DOTALL)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   504
            if match != None:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   505
                value = match.group(1)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   506
                fileh.close()
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   507
                return value
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   508
        fileh.close()
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   509
        if match == None:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   510
            error = "Content of '%s' doesn't match r'^Category\s+([A-Z])\s*$'." % filename
628
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   511
    except IOError, exc:
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   512
        error = str(exc)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   513
    if value is not None:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   514
        return value
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   515
    # worse case....
628
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   516
    raise IOError(error)
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   517
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   518
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   519
class LockFailedException(Exception):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   520
    """ This class is used to indicate the failure in obtaining a Lock. """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   521
    pass
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   522
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   523
if os.name == 'nt':
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   524
    import win32file
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   525
    import win32con
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   526
    import winerror
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   527
    import time
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   528
    import win32netcon
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   529
    import win32wnet
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   530
    
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   531
    class Lock:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   532
        """ This object implement file locking for windows. """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   533
        
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   534
        def __init__(self, filename):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   535
            LOGGER_LOCK.debug("__init__")
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   536
            self._filename = filename
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   537
            self.f_desc = None
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   538
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   539
        def lock(self, wait=False):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   540
            """lock the file"""
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   541
            LOGGER_LOCK.debug("lock")
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   542
            # Open the file
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   543
            if self.f_desc == None:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   544
                self.f_desc = open(self._filename, "w+")
628
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   545
            # pylint: disable=W0212
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   546
            wfd = win32file._get_osfhandle(self.f_desc.fileno())
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   547
            if not wait:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   548
                try:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   549
                    win32file.LockFile(wfd, 0, 0, 0xffff, 0)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   550
                except:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   551
                    raise LockFailedException()
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   552
            else:    
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   553
                while True:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   554
                    try:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   555
                        win32file.LockFile(wfd, 0, 0, 0xffff, 0)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   556
                        break
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   557
                    except win32file.error, exc:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   558
                        if exc[0] != winerror.ERROR_LOCK_VIOLATION:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   559
                            raise exc
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   560
                    LOGGER_LOCK.debug("waiting")
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   561
                    time.sleep(1)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   562
                    
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   563
        def unlock(self):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   564
            """unlock the file"""
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   565
            LOGGER_LOCK.debug("unlock")
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   566
            if self.f_desc == None:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   567
                LOGGER_LOCK.debug("already unlocked")
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   568
                return
628
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   569
            # pylint: disable=W0212
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   570
            wfd = win32file._get_osfhandle(self.f_desc.fileno())
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   571
            try:
628
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   572
                # pylint: disable=E1101
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   573
                win32file.UnlockFile(wfd, 0 , 0, 0xffff, 0)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   574
                self.f_desc.close()
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   575
                self.f_desc = None
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   576
            except win32file.error, exc:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   577
                if exc[0] != 158:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   578
                    raise
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   579
            
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   580
            
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   581
        def __del__(self):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   582
            LOGGER_LOCK.debug("__del__")
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   583
            self.unlock()
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   584
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   585
    def rmdir(path):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   586
        """ Catch os.rmdir failures on Windows when path is too long (more than 256 chars)."""
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   587
        path = win32api.GetShortPathName(path)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   588
        win32file.RemoveDirectory(path)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   589
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   590
    def remove(filename):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   591
        """ Catch os.rmdir failures on Windows when path is too long (more than 256 chars)."""
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   592
        filename = win32api.GetShortPathName(filename)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   593
        filename = filename.lstrip("\\\\?\\")
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   594
        os.remove(filename)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   595
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   596
    def mount(drive, unc, username=None, password=None, persistent=False):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   597
        """ Windows helper function to map a network drive. """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   598
        flags = 0
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   599
        if persistent:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   600
            flags = win32netcon.CONNECT_UPDATE_PROFILE
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   601
        win32wnet.WNetAddConnection2(win32netcon.RESOURCETYPE_DISK, drive, unc, None, username, password, flags)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   602
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   603
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   604
    def umount(drive):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   605
        """ Windows helper function to map a network drive. """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   606
        drive_type = win32file.GetDriveType(drive)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   607
        if drive_type == win32con.DRIVE_REMOTE:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   608
            win32wnet.WNetCancelConnection2(drive, win32netcon.CONNECT_UPDATE_PROFILE, 1)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   609
        else:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   610
            raise Exception("%s couldn't be umount." % drive)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   611
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   612
else:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   613
    def rmdir(path):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   614
        """remove directory"""
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   615
        return os.rmdir(path)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   616
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   617
    def remove(path):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   618
        """remove the files and folders"""
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   619
        return os.remove(path)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   620
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   621
    class Lock:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   622
        """ This class represents a dummy lock """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   623
        def __init__(self, filename):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   624
            pass
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   625
        def lock(self, wait=False):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   626
            """lock file - do nothing """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   627
            pass
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   628
        def unlock(self):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   629
            """un lock file -do nothing """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   630
            pass
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   631
            
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   632
if os.sep == '\\':
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   633
    def get_next_free_drive():
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   634
        """ Return the first free drive found else it raise an exception. """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   635
        if os.name == 'nt':
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   636
            drive_labels = sorted(list(set(string.ascii_uppercase) - set(win32api.GetLogicalDriveStrings())), reverse=True)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   637
            if len(drive_labels) != 0 :
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   638
                return drive_labels[0] + ":"
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   639
            raise OSError("No free drive left.")
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   640
        if 'java' in sys.platform:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   641
            import java.io
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   642
            used = []
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   643
            for _xx in java.io.File.listRoots():
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   644
                used.append(str(_xx).replace(':\\', ''))
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   645
            drive_labels = sorted(list(set(string.ascii_uppercase) - set(used)), reverse=True)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   646
            if len(drive_labels) != 0 :
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   647
                return drive_labels[0] + ":"
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   648
            raise OSError("No free drive left.")
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   649
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   650
    def subst(drive, path):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   651
        """ Substing path as a drive. """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   652
        path = os.path.normpath(path)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   653
        p_subst = subprocess.Popen("subst %s %s" % (drive, path),  shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   654
        errmsg = p_subst.communicate()[0]
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   655
        if p_subst.returncode != 0:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   656
            raise Exception("Error substing '%s' under '%s': %s" % (path, drive, errmsg))
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   657
    
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   658
    def unsubst(drive):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   659
        """ Unsubsting the drive. """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   660
        p_subst = subprocess.Popen("subst /D %s" % (drive), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   661
        errmsg = p_subst.communicate()[0]
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   662
        if p_subst.returncode != 0:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   663
            raise Exception("Error unsubsting '%s': %s" % (drive, errmsg))
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   664
    
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   665
    def getSubstedDrives():
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   666
        """get substituted drive"""
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   667
        driveInformation = {}
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   668
        subStedDriveList = []
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   669
        p_subst = subprocess.Popen("subst",  shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   670
        subStedDriveList = re.split('\\n', p_subst.communicate()[0])
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   671
        del subStedDriveList[len(subStedDriveList)-1]
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   672
        for path in subStedDriveList:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   673
            subStedDrivePath = []
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   674
            if(re.search(r'UNC', path) is not None):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   675
                subStedDrivePath = re.split('=>', path)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   676
                (drive_to_unsubst, _) = os.path.splitdrive(os.path.normpath(subStedDrivePath[0]))
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   677
                uncPath = re.sub('UNC', r'\\', subStedDrivePath[1].strip())
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   678
                if(uncPath != subStedDrivePath[1].strip()):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   679
                    driveInformation[drive_to_unsubst] = uncPath
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   680
            else:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   681
                subStedDrivePath = re.split('=>', path)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   682
                (drive_to_unsubst, _) = os.path.splitdrive(os.path.normpath(subStedDrivePath[0]))
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   683
                driveInformation[drive_to_unsubst] = os.path.normpath(subStedDrivePath[1].strip())
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   684
    
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   685
        return driveInformation
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   686
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   687
def touch(srcdir):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   688
    """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   689
    Recursively touches all the files in the source path mentioned.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   690
    It does not touch the directories.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   691
    """
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   692
    srcnames = os.listdir(srcdir)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   693
    for name in srcnames:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   694
        srcfname = os.path.join(srcdir, name)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   695
        if os.path.isdir(srcfname):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   696
            touch(srcfname)
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   697
        else:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   698
            if os.path.exists(srcfname):
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   699
                os.utime(srcfname, None)