"Fossies" - the Fresh Open Source Software Archive

Member "pysize-0.2/pysize/core/compute_size.py" (11 Mar 2007, 3599 Bytes) of package /linux/privat/old/pysize-0.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

    1 # This program is free software; you can redistribute it and/or modify
    2 # it under the terms of the GNU General Public License as published by
    3 # the Free Software Foundation; either version 2 of the License, or
    4 # (at your option) any later version.
    5 #
    6 # This program is distributed in the hope that it will be useful,
    7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
    8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    9 # GNU Library General Public License for more details.
   10 #
   11 # You should have received a copy of the GNU General Public License
   12 # along with this program; if not, write to the Free Software
   13 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   14 #
   15 # See the COPYING file for license information.
   16 #
   17 # Copyright (c) 2006, 2007 Guillaume Chazarain <guichaz@yahoo.fr>
   18 
   19 import os
   20 import stat
   21 
   22 from pysize.core import chdir_browsing
   23 from pysize.core.observable import observable
   24 from pysize.core.pysize_global_fs_cache import get_dev_ino, cache_add_dir
   25 from pysize.core.pysize_global_fs_cache import cache_add_hardlink
   26 from pysize.core.pysize_global_fs_cache import cache_get_dir_size
   27 from pysize.core.deletion import get_subtracted
   28 
   29 size_observable = observable()
   30 
   31 def log_error(text, e):
   32     print text, e
   33 
   34 def _fast(path, dir_ino, cross_device, error_cb):
   35     """Return the size of the file or directory at path, using or updating the
   36     cache. dir_ino is the inode of the directory containing the path, it is
   37     used only with hardlinks.
   38     """
   39     try:
   40         size_observable.fire_observers()
   41         st = os.lstat(path)
   42         if stat.S_ISDIR(st.st_mode): # Directory
   43             dev_ino = st.st_dev, st.st_ino
   44             cached_size = cache_get_dir_size(dev_ino)
   45             if cached_size is None:
   46                 size = st.st_blocks * 512
   47                 dir_ino = st.st_ino
   48                 cookie = chdir_browsing.init(path)
   49                 try:
   50                     for child in chdir_browsing.browsedir(cookie, cross_device,
   51                                                         account_deletion=False):
   52                         size += _fast(child, dir_ino, cross_device, error_cb)
   53                 finally:
   54                     chdir_browsing.finalize(cookie)
   55                 cache_add_dir(dev_ino, size)
   56             else:
   57                 size = cached_size
   58         elif st.st_nlink > 1: # Hardlink
   59             if cache_add_hardlink(st.st_dev, st.st_ino, dir_ino, path):
   60                 size = st.st_blocks * 512
   61             else:
   62                 size = 0
   63         else: # File
   64             size = st.st_blocks * 512
   65         return size
   66     except OSError, e:
   67         error_cb('(%s) size.fast(%s)' % (os.getcwd(), path), e)
   68         return 0
   69 
   70 def slow(path, cross_device=True, error_cb=log_error, account_deletion=True):
   71     """Same as _size_fast(path, dir_ino), except that dir_ino is computed."""
   72     def parent_inode():
   73         """Return the inode of the parent directory"""
   74         path_st = os.lstat(path)
   75         if stat.S_ISDIR(path_st.st_mode):
   76             parent_path = path + '/..'
   77         else:
   78             parent_path = os.path.dirname(path) or '.'
   79         return get_dev_ino(parent_path)[1]
   80     try:
   81         parent_ino = parent_inode()
   82     except OSError, e:
   83         error_cb('size.slow(%s)' % (path), e)
   84         return 0
   85     size = _fast(path, parent_ino, cross_device, error_cb)
   86     if account_deletion:
   87         size -= get_subtracted(path)
   88     return size
   89 
   90 def slow_sum(paths, cross_device=True, error_cb=log_error):
   91     res = 0
   92     for p in paths:
   93         res += slow(p, cross_device, error_cb)
   94     return res