"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