├── .gitignore ├── COPYING ├── INSTALL ├── MANIFEST.in ├── README ├── README.md ├── changelog ├── pydf ├── pydf.1 ├── pydf1.png ├── pydf2.png ├── pydfrc ├── setup.cfg └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | *.egg-info/ 23 | .installed.cfg 24 | *.egg 25 | 26 | # PyInstaller 27 | # Usually these files are written by a python script from a template 28 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 29 | *.manifest 30 | *.spec 31 | 32 | # Installer logs 33 | pip-log.txt 34 | pip-delete-this-directory.txt 35 | 36 | # Unit test / coverage reports 37 | htmlcov/ 38 | .tox/ 39 | .coverage 40 | .coverage.* 41 | .cache 42 | nosetests.xml 43 | coverage.xml 44 | *,cover 45 | 46 | # Translations 47 | *.mo 48 | *.pot 49 | 50 | # Django stuff: 51 | *.log 52 | 53 | # Sphinx documentation 54 | docs/_build/ 55 | 56 | # PyBuilder 57 | target/ 58 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | This package was written by Radovan Garabík 2 | 3 | Copyright: 4 | 5 | Public domain. Do whatever you want to do with this program. 6 | 7 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | You must have python installed (at least version 2.3, or version 2.2. 2 | with optparse package). 3 | 4 | Python3 is recommended, though. 5 | 6 | edit first line of pydf to point to your python interpreter, 7 | copy pydf somewhere into your path, 8 | copy pydf.1 where your manpages reside (e.g. /usr/local/man/man1) 9 | and copy pydfrc into /etc/pydfrc, or ~/.pydfrc 10 | 11 | Modify /etc/pydfrc according to your taste. 12 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include COPYING 2 | include pydf.1 3 | include changelog 4 | include INSTALL 5 | include pydfrc 6 | global-exclude *~ 7 | global-exclude *.pyc 8 | prune .DS_Store 9 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | pydf is all-singing, all-dancing, fully colourised df(1)-clone 2 | written in python. 3 | 4 | Requirements: 5 | pydf was written for linux, using specific linux features. 6 | The fact it runs on other systems is pure coincidence, 7 | but neverthless it happens to work on wide range of modern 8 | unix systems. 9 | 10 | System-wide configuration is in /etc/pydfrc, per-user 11 | configuration in ~/.pydfrc (format of these files is the same) 12 | 13 | Colours are one of: 14 | none, default, bold, underline, blink, reverse, concealed, 15 | black, green, yellow, blue, magenta, cyan, white, 16 | on_black, on_green, on_yellow, on_blue, on_magenta, on_cyan, on_white 17 | beep 18 | on_red means that the background (instead of foreground) is painted 19 | with red etc... 20 | 21 | 22 | pydf recognizes following parameters: 23 | 24 | --help show this help message 25 | -a, --all include filesystems having 0 blocks 26 | -h, --human-readable print sizes in human readable format (e.g., 1K 234M 2G) 27 | -H, --si likewise, but use powers of 1000 not 1024 28 | -bBLOCKSIZE, --block-size=BLOCKSIZE 29 | use SIZE-byte blocks 30 | -l, --local limit listing to local filesystems 31 | -k, --kilobytes like --block-size=1024 32 | -m, --megabytes like --block-size=1048576 33 | -g, --gigabytes like --block-size=1073741824 34 | --blocks use filesystem native block size 35 | --bw do not use colours 36 | --mounts=MOUNTS_FILE File to get mount information from. On normal linux 37 | system, only /etc/mtab or proc/mounts make sense. Some 38 | other unices use /etc/mnttab. Use /proc/mounts when 39 | /etc/mtab is corrupted or inaccesable (the output 40 | looks a bit weird in this case). 41 | -B, --show-binds show also mount --bind mounted filesystems 42 | 43 | Written by Radovan Garabík . 44 | For new versions, look at http://kassiopeia.juls.savba.sk/~garabik/software/pydf/ 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PyPI package for pydf 2 | 3 | **NOTE**: *This repo is used for generating a [PyPI package](https://pypi.python.org/pypi/pydf) for [pydf tool](http://kassiopeia.juls.savba.sk/~garabik/software/pydf/) written by [Radovan Garabík](http://kassiopeia.juls.savba.sk/~garabik/). This makes it possible to install pydf with the familiar `pip` command. I have not written 'pydf'; I just hope to maintain the package and possibly fix some bugs. Improvements to `setup.py` and related files are welcome in the form of PRs. --k4rtik* 4 | 5 | This repo is just for the PyPI package. **Please file issues and send pull requests for `pydf` at https://github.com/garabik/pydf.** 6 | 7 | Original README with some additional formatting and screenshots follow. 8 | 9 | --- 10 | 11 | ## pydf 12 | 13 | pydf is all-singing, all-dancing, fully colourised `df(1)`-clone 14 | written in python. 15 | 16 | ### Requirements: 17 | pydf was written for linux, using specific linux features. 18 | The fact it runs on other systems is pure coincidence, 19 | but neverthless it happens to work on wide range of modern 20 | unix systems. 21 | 22 | System-wide configuration is in `/etc/pydfrc`, per-user 23 | configuration in `~/.pydfrc` (format of these files is the same) 24 | 25 | ### Colours are one of: 26 | > none, default, bold, underline, blink, reverse, concealed, 27 | black, green, yellow, blue, magenta, cyan, white, 28 | on_black, on_green, on_yellow, on_blue, on_magenta, on_cyan, on_white 29 | beep 30 | 31 | on_red means that the background (instead of foreground) is painted 32 | with red etc... 33 | 34 | 35 | ### pydf recognizes following parameters: 36 | ``` 37 | --help show this help message 38 | -a, --all include filesystems having 0 blocks 39 | -h, --human-readable print sizes in human readable format (e.g., 1K 234M 2G) 40 | -H, --si likewise, but use powers of 1000 not 1024 41 | -bBLOCKSIZE, --block-size=BLOCKSIZE 42 | use SIZE-byte blocks 43 | -l, --local limit listing to local filesystems 44 | -k, --kilobytes like --block-size=1024 45 | -m, --megabytes like --block-size=1048576 46 | -g, --gigabytes like --block-size=1073741824 47 | --blocks use filesystem native block size 48 | --bw do not use colours 49 | --mounts=MOUNTS_FILE File to get mount information from. On normal linux 50 | system, only /etc/mtab or proc/mounts make sense. Some 51 | other unices use /etc/mnttab. Use /proc/mounts when 52 | /etc/mtab is corrupted or inaccesable (the output 53 | looks a bit weird in this case). 54 | -B, --show-binds show also mount --bind mounted filesystems 55 | ``` 56 | 57 | Written by [Radovan Garabík](mailto:garabik@kassiopeia.juls.savba.sk). 58 | For new versions, look at http://kassiopeia.juls.savba.sk/~garabik/software/pydf/ 59 | 60 | --- 61 | 62 | ### Screenshots 63 | ![](pydf1.png) 64 | ![](pydf2.png) 65 | -------------------------------------------------------------------------------- /changelog: -------------------------------------------------------------------------------- 1 | pydf (12) unstable; urgency=low 2 | 3 | * better python3 compatibility; escape control and invalid characters in 4 | mountpoint names 5 | 6 | -- Radovan Garabík Fri, 26 Dec 2014 22:35:40 +0100 7 | 8 | pydf (11) unstable; urgency=low 9 | 10 | * add nfs4 to the list of remote filesystems (thanks to Markus Hauschild) 11 | * add fallback if resize does not work (closes: #577454) 12 | * somewhat better dealing with possible errors in 'resize' fallback 13 | * add several Debian/kFreeBSD special filesystems 14 | 15 | -- Radovan Garabík Sun, 27 Jan 2013 20:42:24 +0200 16 | 17 | pydf (10) unstable; urgency=low 18 | 19 | * normal_colour was not interpreting colour codes properly 20 | (thanks to Juhapekka Tolvanen and Norman Rasmussen for 21 | pointing this out) 22 | (closes: #577595, #582462) 23 | * if termios reports zero for terminal width, use fallback 24 | (closes: #577454) 25 | * added devtmpfs to the list of special filesystems 26 | (closes: #577453), both bugreports thanks to Romain Francoise 27 | * use subprocess or commands depending on major python version 28 | (closes: #579936), patch thanks to Emmanuel Bouthenot 29 | * remove parentheses in class definition, to enable 30 | python2.4 compatibility (thanks to Clint Savage) 31 | * add patch for /dev/mapper links, thanks to Ernest Beinrohr 32 | 33 | -- Radovan Garabík Sun, 11 Dec 2011 15:06:41 +0200 34 | 35 | pydf (9) unstable; urgency=low 36 | 37 | * remove stray ANSI escape sequence when using --bw mode 38 | * convert to run with python3 (thanks to Dror Levin) 39 | 40 | -- Radovan Garabík Mon, 29 Mar 2010 23:06:15 +0200 41 | 42 | pydf (8) unstable; urgency=low 43 | 44 | * run pylint & pychecker -- fix some previously unnoticed bugs 45 | * treat "special" filesystems and those with 0 blocks the same 46 | (i.e. do not display them unless -a option is given) 47 | * add fuse.sshfs to the list of networked filesystems 48 | 49 | -- Radovan Garabík Sat, 24 Oct 2009 17:40:14 +0200 50 | 51 | pydf (7) unstable; urgency=low 52 | 53 | * add 'inodes' option (closes: #51044), patch thanks to Thomas Rösner 54 | * change 'blocks-size' option into 'block-size', as originally intended 55 | * if the used percentage is meaningless, display '-' instead of 0 56 | * minor documentation updates 57 | 58 | -- Radovan Garabík Fri, 10 Apr 2009 14:40:00 +0200 59 | 60 | pydf (6) unstable; urgency=low 61 | 62 | * add the 'hidebinds' options (thanks to Martin von Wittich) 63 | 64 | -- Radovan Garabík Thu, 17 Apr 2008 22:24:03 +0200 65 | 66 | pydf (5) unstable; urgency=low 67 | 68 | * make the bar stretchable, to fill the whole screen width 69 | 70 | -- Radovan Garabík Fri, 10 Aug 2007 13:53:49 +0200 71 | 72 | pydf (4) unstable; urgency=low 73 | 74 | * fix scrolling artefacts at the bottom of terminal 75 | * fix accidentally removed possibility to use colour sequences 76 | 77 | -- Radovan Garabík Thu, 19 Jul 2007 14:54:15 +0200 78 | 79 | pydf (3) unstable; urgency=low 80 | 81 | * completely rewrited formatting code, now utilizes better 82 | screen width (closes: #421118) 83 | * display special filesystems with block_size != 0 in different colour 84 | 85 | -- Radovan Garabík Sun, 15 Jul 2007 19:36:05 +0200 86 | 87 | pydf (2) unstable; urgency=low 88 | 89 | * use termios to get terminal size, does not need resize(1) anymore 90 | (thanks to Josip Rodin for the idea) 91 | 92 | -- Radovan Garabík Sun, 13 May 2007 10:14:45 +0200 93 | 94 | pydf (1) unstable; urgency=low 95 | 96 | * show read only mounted filesystems in different colour (thanks 97 | to Michał J. Gajda and Bastian Kleineidam) 98 | * add binary-arch target to debian/rules (closes: #395633) 99 | * work around python statvfs 32-bit overflow (closes: #396298) 100 | 101 | -- Radovan Garabík Wed, 1 Nov 2006 17:09:52 +0200 102 | 103 | pydf (0.9.9) unstable; urgency=low 104 | 105 | * find automatically mountpoints for arguments (closes: #140483), 106 | thanks to Jürgen A. Erhard 107 | 108 | -- Radovan Garabík Thu, 30 Mar 2006 18:34:49 +0200 109 | 110 | pydf (0.9.8.5) unstable; urgency=low 111 | 112 | * added sshfs to the list of remote filesystems 113 | * added udf to the list of filesystem that are always full 114 | (thanks to Benoît Dejean) 115 | 116 | -- Radovan Garabík Fri, 2 Sep 2005 23:12:41 +0200 117 | 118 | pydf (0.9.8.4) unstable; urgency=low 119 | 120 | * mountfile can be a list now, pydf will try each of them 121 | * fallback to parsing mount(1) output if no mountfile is available 122 | (this adds support for many different operating systems, e.g. MacOSX) 123 | 124 | -- Radovan Garabík Mon, 22 Aug 2005 11:01:01 +0200 125 | 126 | pydf (0.9.8.3) unstable; urgency=low 127 | 128 | * failback to default size when 'resize' is not present (closes: #320564) 129 | * Suggest xutils (for 'resize') 130 | * better barsize rounding 131 | 132 | -- Radovan Garabík Wed, 3 Aug 2005 10:24:40 +0200 133 | 134 | pydf (0.9.8.2) unstable; urgency=low 135 | 136 | * use F_BSIZE instead of F_FRSIZE (closes: #289527) 137 | 138 | -- Radovan Garabík Tue, 2 Aug 2005 12:54:30 +0200 139 | 140 | pydf (0.9.8.1) unstable; urgency=low 141 | 142 | * change forgotten FILL_THRESH value from ridiculously low value back 143 | to 0.95, thanks to Lasse Pommerenke for noticing (closes: #318968) 144 | 145 | -- Radovan Garabík Tue, 19 Jul 2005 09:34:41 +0200 146 | 147 | pydf (0.9.8) unstable; urgency=low 148 | 149 | * try to detect terminal size 150 | * round values to nearest number (closes: #278683, #315273), note that df(1) 151 | sometimes rounds the values incorrectly 152 | 153 | -- Radovan Garabík Sat, 30 Apr 2005 16:05:11 +0200 154 | 155 | pydf (0.9.7) unstable; urgency=low 156 | 157 | * overall reworking, brought up in sync with newer python versions 158 | * accepts mountpoints as arguments (closes: #140483), thanks to Josip Rodin 159 | * only necessary filesystems are queried (closes: #280907) 160 | 161 | -- Radovan Garabik Wed, 5 Jan 2005 20:28:28 +0100 162 | 163 | pydf (0.9.6) unstable; urgency=low 164 | 165 | * modified dependencies for new python numbering scheme (closes: #118248) 166 | * mention /etc/pydfrc in manpage (closes: #108167) 167 | 168 | -- Radovan Garabik Mon, 5 Nov 2001 10:47:10 +0100 169 | 170 | pydf (0.9.5) unstable; urgency=low 171 | 172 | * corercted typo in manpage (closes #99878). 173 | 174 | -- Radovan Garabik Mon, 4 Jun 2001 13:07:06 +0200 175 | 176 | pydf (0.9.4) unstable; urgency=low 177 | 178 | * move Build-Depends where it belongs. 179 | * depends on python | python2 180 | 181 | -- Radovan Garabik Fri, 23 Feb 2001 21:41:04 +0100 182 | 183 | pydf (0.9.3) unstable; urgency=low 184 | 185 | * rebuilt with a new GPG key 186 | 187 | -- Radovan Garabik Fri, 1 Sep 2000 08:27:58 +0200 188 | 189 | pydf (0.9.2) unstable; urgency=low 190 | 191 | * added debhelper to Build-Depends 192 | 193 | -- Radovan Garabik Wed, 16 Feb 2000 16:08:24 +0100 194 | 195 | pydf (0.9.1) unstable; urgency=low 196 | 197 | * Fixed stupid bug affecting those with broken python on RedHat. 198 | Thanks to Keith M. Briggs for pointing this out. 199 | 200 | -- Radovan Garabik Fri, 14 Jan 2000 13:09:13 +0100 201 | 202 | pydf (0.9) unstable; urgency=low 203 | 204 | * More colour definitions 205 | * Upgraded Standards-Version 206 | * Corrected typo in the manpage 207 | * Included pointer to stat(1) in README 208 | 209 | -- Radovan Garabik Thu, 6 Jan 2000 17:24:32 +0100 210 | 211 | pydf (0.8.1) unstable; urgency=low 212 | 213 | * NMU (sponsored). 214 | * Set control file so Radovan is listed properly as the maintainer. 215 | 216 | -- Chris Lawrence Tue, 4 Jan 2000 02:11:01 -0600 217 | 218 | pydf (0.8) unstable; urgency=low 219 | 220 | * statvfs checks for errors - e.g., if you do not have rights to statfs 221 | the filesystem, pydf would not crash 222 | * use getopt for argument parsing 223 | * added --block-size, --local, --all options 224 | * Radovan Garabik is the person 225 | responsible for this package; I am his sponsor and uploading it on his 226 | behalf. 227 | 228 | -- Chris Lawrence Tue, 5 Oct 1999 20:25:25 +0200 229 | 230 | pydf (0.7) unstable; urgency=low 231 | 232 | * build with new debhelper - FHS compliant 233 | * a couple of spelling errors in README fixed 234 | 235 | -- Radovan Garabik Sat, 18 Sep 1999 10:34:28 +0200 236 | 237 | pydf (0.6) unstable; urgency=low 238 | 239 | * now displays size correctly for filesystem with FRSIZE != BSIZE, 240 | workaround for some broked pythons (see 0.3) still valid 241 | * documentation update 242 | * increased version number from 0.4 :-) 243 | 244 | -- Radovan Garabik Wed, 15 Sep 1999 20:52:21 +0200 245 | 246 | pydf (0.5) unstable; urgency=low 247 | 248 | * fixed typo preventing correct display of small sizes 249 | 250 | -- Radovan Garabik Wed, 1 Sep 1999 13:19:38 +0200 251 | 252 | pydf (0.4) unstable; urgency=low 253 | 254 | * network filesystems with block size 0 are now recognized as network 255 | filesystems, not as special filesystems 256 | * workaround for older python interpreter without os.statvfs function 257 | 258 | -- Radovan Garabik Mon, 30 Aug 1999 19:53:50 +0200 259 | 260 | pydf (0.3) unstable; urgency=low 261 | 262 | * Restore original colour after itself 263 | * Should work on RedHat 6.0 now 264 | * Improved colour scheme 265 | * Added --mounts option 266 | 267 | -- Radovan Garabik Fri, 27 Aug 1999 17:24:45 +0200 268 | 269 | pydf (0.2) unstable; urgency=low 270 | 271 | * Initial Release. 272 | 273 | -- Radovan Garabik Thu, 26 Aug 1999 19:16:29 +0200 274 | 275 | Local variables: 276 | mode: debian-changelog 277 | End: 278 | -------------------------------------------------------------------------------- /pydf: -------------------------------------------------------------------------------- 1 | #! /usr/bin/python 2 | 3 | import sys, os, re, string, struct, unicodedata 4 | from optparse import OptionParser 5 | 6 | from math import log 7 | 8 | if not 'lexists' in dir(os.path): 9 | # for python < 2.4 10 | # will not give the same result for broken symbolic links, but who cares... 11 | os.path.lexists = os.path.exists 12 | 13 | if sys.version_info[0] < 3: 14 | # getoutput() and getstatusoutput() methods have 15 | # been moved from commands to the subprocess module 16 | # with Python >= 3.x 17 | import commands as my_subprocess 18 | else: 19 | import subprocess as my_subprocess 20 | 21 | str_ljust = str.ljust 22 | str_rjust = str.rjust 23 | str_center = str.center 24 | 25 | 26 | # again an ugly hack for python < 2.4 27 | try: 28 | str_ljust('dummy', 1, '.') 29 | except TypeError: 30 | str_ljust = lambda x, y, z: string.ljust (x, y).replace(' ', z) 31 | str_rjust = lambda x, y, z: string.rjust (x, y).replace(' ', z) 32 | str_center = lambda x, y, z: string.center (x, y).replace(' ', z) 33 | 34 | class Bar: 35 | def __init__(self, percentage=0, width=2, header=False): 36 | self.percentage = percentage 37 | self.width = width 38 | self.header = header 39 | 40 | def __len__(self): 41 | return self.width 42 | 43 | def __str__(self): 44 | return self.format(self, 'l') 45 | 46 | def format(self, pos): 47 | if self.header: 48 | return ' '*self.width 49 | size = int(round(self.percentage*(self.width-2))) 50 | return '['+manglestring(size*barchar, self.width-2, pos, bar_fillchar)+']' 51 | 52 | 53 | def get_terminal_width_termios(): 54 | try: 55 | import fcntl, termios 56 | except ImportError: 57 | return None 58 | s = struct.pack("HHHH", 0, 0, 0, 0) 59 | try: 60 | lines, cols, xpixels, ypixels = \ 61 | struct.unpack( 62 | "HHHH", 63 | fcntl.ioctl(sys.stdout.fileno(), 64 | termios.TIOCGWINSZ, s) 65 | ) 66 | except (IOError, AttributeError): 67 | return None 68 | return cols 69 | 70 | def get_terminal_width_resize(): 71 | status, output = my_subprocess.getstatusoutput('resize') 72 | if status!=0: # error in running resize 73 | return None 74 | c = output.split('\n') 75 | c = [x for x in c if x.startswith('COLUMNS=')] 76 | if c: 77 | c = c[0] 78 | dummy, c = c.split('=', 1) 79 | if c[-1] == ';': 80 | c = c[:-1] 81 | if c: 82 | return int(c) 83 | else: 84 | return None 85 | 86 | def get_terminal_width_dumb(): 87 | return 80 88 | 89 | def get_terminal_width(): 90 | handlers = [get_terminal_width_termios, get_terminal_width_resize, get_terminal_width_dumb] 91 | for handler in handlers: 92 | width = handler() 93 | if width: 94 | return width 95 | return 80 # fallback, should not happen 96 | 97 | 98 | def find_mountpoint(path): 99 | if not os.path.lexists(path): 100 | sys.stderr.write('pydf: %s: No such file or directory\n' % repr(path)) 101 | return None 102 | while not os.path.ismount(path): 103 | path = os.path.dirname(path) 104 | return path 105 | 106 | 107 | 108 | #some default definitions 109 | colours = { 110 | 'none' : "", 111 | 'default' : "\033[0m", 112 | 'bold' : "\033[1m", 113 | 'underline' : "\033[4m", 114 | 'blink' : "\033[5m", 115 | 'reverse' : "\033[7m", 116 | 'concealed' : "\033[8m", 117 | 118 | 'black' : "\033[30m", 119 | 'red' : "\033[31m", 120 | 'green' : "\033[32m", 121 | 'yellow' : "\033[33m", 122 | 'blue' : "\033[34m", 123 | 'magenta' : "\033[35m", 124 | 'cyan' : "\033[36m", 125 | 'white' : "\033[37m", 126 | 127 | 'on_black' : "\033[40m", 128 | 'on_red' : "\033[41m", 129 | 'on_green' : "\033[42m", 130 | 'on_yellow' : "\033[43m", 131 | 'on_blue' : "\033[44m", 132 | 'on_magenta' : "\033[45m", 133 | 'on_cyan' : "\033[46m", 134 | 'on_white' : "\033[47m", 135 | 136 | 'beep' : "\007" 137 | } 138 | 139 | 140 | normal_colour = 'default' 141 | header_colour = 'yellow' 142 | local_fs_colour = 'default' 143 | remote_fs_colour = 'green' 144 | special_fs_colour = 'blue' 145 | readonly_fs_colour = 'cyan' 146 | filled_fs_colour = 'red' 147 | full_fs_colour = 'on_red' 148 | custom_device_colour = {} #TODO 149 | 150 | sizeformat = "-h" 151 | column_separator = ' ' 152 | column_separator_colour = 'none' 153 | row_separator = '' 154 | hidebinds = True 155 | 156 | stretch_screen = 0.3 157 | 158 | do_total_sum = False 159 | 160 | FILL_THRESH = 95.0 161 | FULL_THRESH = 99.0 162 | 163 | 164 | format = [ 165 | ('fs', 10, "l"), ('size', 5, "r"), 166 | ('used', 5, "r"), ('avail', 5, "r"), ('perc', 4, "r"), 167 | ('bar', 0.1, "l"), ('on', 11, "l") 168 | ] 169 | 170 | 171 | barchar = '#' 172 | bar_fillchar = '.' 173 | 174 | mountfile = ['/etc/mtab', '/etc/mnttab', '/proc/mounts'] 175 | 176 | 177 | #end of default definitions 178 | 179 | # read configuration file 180 | for conffile in ["/etc/pydfrc", os.environ['HOME']+"/.pydfrc"]: 181 | if os.path.isfile(conffile): 182 | exec(compile(open(conffile).read(), conffile, 'exec')) 183 | 184 | 185 | header = { 186 | 'fs' : "Filesystem", 187 | 'size' : "Size", 188 | 'used' : "Used", 189 | 'avail' : "Avail", 190 | 'on' : "Mounted on", 191 | 'fstype' : "Type", 192 | 'perc' : "Use%", 193 | 'bar' : Bar(header=True), 194 | } 195 | 196 | def sanitize_output(s): 197 | "sanitize nonprintable characters for printing" 198 | r = '' 199 | for c in s: 200 | if ord(c)<32: 201 | r += r'\x%02x' % ord(c) 202 | # surrogate characters encoding non-decodable bytes in the names of mountpoints 203 | elif 0xdc80 <= ord(c) <= 0xdcff: 204 | r += r'\x%02x' % (ord(c)-0xdc00) 205 | # in python2, we have str, not unicode here - just give up and do not test for strange unicode characters 206 | elif sys.version_info[0] >= 3 and (unicodedata.category(c)[0]=='C' or unicodedata.category(c) in ('Zl', 'Zp')): 207 | if ord(c) <= 0xffff: 208 | r += r'\u%04X' % ord(c) 209 | else: 210 | r += r'\U%08X' % ord(c) 211 | else: 212 | r += c 213 | return r 214 | 215 | def out(s): 216 | try: 217 | sys.stdout.write(s) 218 | except UnicodeEncodeError: 219 | sys.stdout.write(s.encode('ascii', 'ignore').decode()) 220 | 221 | class DumbStatus: 222 | "emulates statvfs results with only zero values" 223 | f_bsize = f_frsize = f_blocks = f_bfree = f_bavail = f_files = f_ffree = f_favail = f_flag = f_namemax =0 224 | 225 | def hfnum(size, base): 226 | "human readable number" 227 | if size == 0: 228 | return "0" 229 | if size < 0: 230 | return "?" 231 | if inodes: 232 | units = [""] 233 | else: 234 | units = ["B"] 235 | units += ["k", "M", "G", "T", "P", "Z", "Y"] 236 | power = int(log(size)/log(base)) 237 | if power < 0: 238 | power = 0 239 | if power >= len(units): 240 | power = len(units)-1 241 | nsize = int(round(1.*size/(base**power))) 242 | if nsize < 10 and power >= 1: 243 | power -= 1 244 | nsize = int(round(1.*size/(base**power))) 245 | r = str(nsize) + units[power] 246 | return r 247 | 248 | 249 | def myformat(number, sizeformat, fs_blocksize): 250 | "format number as file size. fs_blocksize here is a filesysem blocksize" 251 | size = int(number)*fs_blocksize 252 | if blocksize: # that is, blocksize was explicitly set up 253 | sn = round(1.*size/blocksize) 254 | sn = int(sn) 255 | return str(sn) 256 | if sizeformat == "-k": 257 | sn = round(size/1024.) 258 | sn = int(sn) 259 | return str(sn) 260 | elif sizeformat == "-m": 261 | sn = round(size/(1024.*1024)) 262 | sn = int(sn) 263 | return str(sn) 264 | elif sizeformat == "-g": 265 | sn = round(size/(1024.*1024*1024)) 266 | sn = int(sn) 267 | return str(sn) 268 | elif sizeformat == "-h": 269 | return hfnum(size, 1024) 270 | elif sizeformat == "-H": 271 | return hfnum(size, 1000) 272 | elif sizeformat == "--blocks": 273 | return str(number) 274 | else: # this should not happen 275 | raise ValueError("Impossible error, contact the author, sizeformat="+repr(sizeformat)) 276 | 277 | 278 | def manglestring(s, l, pos, fillchar=' '): 279 | "cut string to fit exactly into l chars" 280 | if pos == "r": 281 | ns = str_rjust(s, l, fillchar) 282 | elif pos == "l": 283 | ns = str_ljust(s, l, fillchar) 284 | elif pos == "c": 285 | ns = str_center(s, l, fillchar) 286 | else: 287 | raise ValueError('Error in manglestring') 288 | if len(ns) > l: 289 | ns = ns[:int(l/2)] + "~" + ns[-int(l/2)+1:] 290 | return ns 291 | 292 | def makecolour(clist): 293 | "take list (or tuple or just one name) of colour names and return string of ANSI definitions" 294 | s = "" 295 | if type(clist) == str: 296 | lclist = [clist] 297 | else: 298 | lclist = clist 299 | for i in lclist: 300 | s = s + colours[i] 301 | return s 302 | 303 | def version(): 304 | return '12' 305 | 306 | def get_all_mountpoints(): 307 | "return all mountpoints in fs" 308 | 309 | # fallback when nothing else works 310 | dummy_result = {'/': ('/', '')} 311 | 312 | if isinstance(mountfile, str): 313 | f = open(mountfile,"rb") 314 | else: 315 | for i in mountfile: 316 | if os.path.exists(i): 317 | f = open(i,"rb") 318 | break 319 | else: 320 | # fallback, first try to parse mount output 321 | status, mout = my_subprocess.getstatusoutput('mount') 322 | if status !=0: 323 | return dummy_result 324 | mlines = mout.split('\n') 325 | r = {} 326 | for line in mlines: 327 | if not ' on ' in line: 328 | continue 329 | device, on = line.split(' on ', 1) 330 | device = device.split()[0] 331 | onparts = on.split() 332 | on = onparts[0] 333 | # option format: (a,b,..) 334 | opts = onparts[-1][1:-1].split(',') 335 | r[on] = (device, '', opts) 336 | 337 | if r: 338 | return r 339 | else: 340 | return dummy_result 341 | 342 | mountlines = f.readlines() # bytes in python3 343 | 344 | # convert to representable strings (for python3) 345 | # unfortunately, we cannot keep it as bytes, because of a known bug 346 | # in python3 forcing us to use string, not bytes as filename for os.statvfs 347 | if sys.version_info[0]>=3: 348 | errhandler = 'surrogateescape' 349 | if sys.version_info[1]<1: 350 | errhandler = 'replace' 351 | mountlines = [x.decode(sys.stdin.encoding, errhandler) for x in mountlines] 352 | r = {} 353 | for l in mountlines: 354 | spl = l.split() 355 | if len(spl)<4: 356 | print("Error in", mountfile) 357 | print(repr(l)) 358 | continue 359 | device, mp, typ, opts = spl[0:4] 360 | opts = opts.split(',') 361 | r[mp] = (device, typ, opts) 362 | return r 363 | 364 | def niceprint_fs(fs): 365 | "print LVM as nice symlink" 366 | matchObj = re.search( r'^\/dev\/mapper\/(.*)-(.*)', str(fs)) # will fail in python3if fs canot be converted to unicode 367 | if matchObj: 368 | return "/dev/" + matchObj.group(1) + "/" + matchObj.group(2) 369 | else: 370 | return fs 371 | 372 | def get_row_mp(mp): 373 | # for python3, mp is bytes, not str 374 | if mp: 375 | if mp in mountpoints: 376 | device, fstype, opts = mountpoints[mp] 377 | device = niceprint_fs(device) 378 | else: 379 | # oops, the mountpoint is not in /etc/mtab or equivalent 380 | # return dummy values 381 | device, fstype, opts = '-', '-', '-' 382 | rdonly = 'ro' in opts or fstype in ("iso9660", "udf") 383 | bind = 'bind' in opts or 'rbind' in opts 384 | 385 | try: 386 | status = os.statvfs(mp) 387 | except (OSError, IOError): 388 | status = DumbStatus() 389 | fs_blocksize = status.f_bsize 390 | if fs_blocksize == 0: 391 | fs_blocksize = status.f_frsize 392 | free = status.f_bfree 393 | size = status.f_blocks 394 | avail = status.f_bavail 395 | inodes_free = status.f_ffree 396 | inodes_size = status.f_files 397 | inodes_avail = status.f_favail 398 | if (size==0 or is_special_fs(fstype)) and not allfss: 399 | return 400 | if bind and hidebinds: 401 | return 402 | used = size-free 403 | inodes_used = inodes_size - inodes_free 404 | 405 | if inodes: 406 | size_f = myformat(inodes_size, sizeformat, 1) 407 | used_f = myformat(inodes_used, sizeformat, 1) 408 | avail_f = myformat(inodes_avail, sizeformat, 1) 409 | try: 410 | perc = round(100.*inodes_used/inodes_size, 1) 411 | perc_f = str(perc) 412 | except ZeroDivisionError: 413 | perc = 0 414 | perc_f = '-' 415 | else: 416 | size_f = myformat(size, sizeformat, fs_blocksize) 417 | used_f = myformat(used, sizeformat, fs_blocksize) 418 | avail_f = myformat(avail, sizeformat, fs_blocksize) 419 | try: 420 | perc = round(100.*used/size, 1) 421 | perc_f = str(perc) 422 | except ZeroDivisionError: 423 | perc = 0 424 | perc_f = '-' 425 | 426 | 427 | info = { 428 | 'fs' : device, 429 | 'size' : size_f, 430 | 'used' : used_f, 431 | 'avail' : avail_f, 432 | 'on' : mp, 433 | 'fstype' : fstype, 434 | 'perc' : perc_f, 435 | 'bar' : None, 436 | } 437 | current_colour = local_fs_colour 438 | if is_remote_fs(fstype): 439 | current_colour = remote_fs_colour 440 | elif size == 0 or is_special_fs(fstype): 441 | current_colour = special_fs_colour 442 | else: # header 443 | current_colour = header_colour 444 | 445 | row = [] 446 | 447 | for j in format: 448 | 449 | if j[0]=='bar': 450 | width = j[1] 451 | if 0 FULL_THRESH: 459 | current_colour = full_fs_colour 460 | elif perc > FILL_THRESH: 461 | current_colour = filled_fs_colour 462 | if j[0]=='bar': 463 | info['bar'] = Bar(perc/100., width) 464 | 465 | text = info[j[0]] 466 | # if there are control or invalid unicode characters in mountpoint names 467 | if not isinstance(text, Bar): 468 | text = sanitize_output(text) 469 | 470 | else: 471 | text = header[j[0]] 472 | if j[0]=='bar': 473 | text.width = width 474 | 475 | column = [current_colour, text] 476 | row.append(column) 477 | 478 | return row 479 | 480 | 481 | def is_remote_fs(fs): 482 | "test if fs (as type) is a remote one" 483 | fs = fs.lower() 484 | 485 | return fs in [ "nfs", "smbfs", "cifs", "ncpfs", "afs", "coda", 486 | "ftpfs", "mfs", "sshfs", "fuse.sshfs", "nfs4" ] 487 | 488 | def is_special_fs(fs): 489 | "test if fs (as type) is a special one" 490 | "in addition, a filesystem is special if it has number of blocks equal to 0" 491 | fs = fs.lower() 492 | return fs in [ "tmpfs", "devpts", "devtmpfs", "proc", "sysfs", "usbfs", "devfs", "fdescfs", "linprocfs" ] 493 | 494 | def get_table(mps): 495 | "table is a list of rows" 496 | "row is a list of columns" 497 | "column is a list of [colour code, content]" 498 | "content is a string, unless it is a Bar() instance" 499 | rows = [get_row_mp(None)] 500 | for mp in mps: 501 | row = get_row_mp(mp) 502 | if row is not None: 503 | rows.append(row) 504 | return rows 505 | 506 | 507 | def squeeze_table(table, desired_width): 508 | "squeeze table to fit into width characters" 509 | 510 | cols = len(table[0]) 511 | 512 | # build a row of minimal (possible, from format) cell sizes 513 | minrow = [] 514 | for j in format: 515 | width = j[1] 516 | if 0 < width < 1: # i.e. percentage 517 | width = int(width*terminal_width)-1 518 | minrow.append(width) 519 | 520 | # row of maximal cell sizes 521 | maxrow = [0]*cols 522 | 523 | for row in table: 524 | for col in range(cols): 525 | colsize = len(row[col][1]) 526 | maxrow[col] = max(maxrow[col], colsize) 527 | 528 | # maximal differences between (real cell size - minimal possible cell size) 529 | deltarow = [maxrow[i]-minrow[i] for i in range(cols)] 530 | 531 | deltas = list(zip(deltarow, list(range(cols)))) 532 | deltas.sort() 533 | deltas.reverse() 534 | 535 | # how many characters we need to cut off from table width 536 | to_reduce = sum(maxrow) + (cols-1)*len(column_separator) - desired_width 537 | 538 | to_stretch = 0 539 | # if there is free space 540 | if to_reduce < 0 and stretch_screen: 541 | # -to_reduce is now number of spare characters 542 | to_stretch = int(-to_reduce * stretch_screen) 543 | 544 | new_maxrow = maxrow[:] # new sizes 545 | for delta, i in deltas: 546 | if to_reduce < 0: 547 | # we have finished 548 | break 549 | if delta >= to_reduce: 550 | new_maxrow[i] -= to_reduce 551 | # and we finished 552 | to_reduce = 0 553 | break 554 | else: 555 | new_maxrow[i] -= delta # now it contains the minimal possible width 556 | to_reduce -= delta 557 | 558 | if to_reduce > 0: 559 | # we were not able to reduce the size enough 560 | # since it will wrap anywway, we might as well display 561 | # complete long lines 562 | new_maxrow = maxrow 563 | for row in table: 564 | for col in range(cols): 565 | cell_content = row[col][1] 566 | if isinstance(cell_content, Bar): 567 | cell_content.width += to_stretch 568 | formatted_cell_content = cell_content.format(format[col][2]) 569 | else: 570 | formatted_cell_content = manglestring(cell_content, new_maxrow[col], format[col][2]) 571 | row[col][1] = formatted_cell_content 572 | 573 | 574 | def display_table(table, terminal_width): 575 | "display our internal output table" 576 | 577 | squeeze_table(table, terminal_width-1) 578 | 579 | colsepcol = makecolour(column_separator_colour) 580 | for row in table: 581 | firstcol = True 582 | for colourcode, text in row: 583 | if firstcol: 584 | firstcol = False 585 | else: 586 | out(colsepcol) 587 | out(column_separator) 588 | out(makecolour(colourcode)) 589 | out(text) 590 | out(row_separator) 591 | out(makecolour(normal_colour)) 592 | out('\n') 593 | 594 | 595 | 596 | # the fun begins here 597 | 598 | parser = OptionParser(usage="usage: %prog [options] arg", add_help_option=False) 599 | 600 | parser.version = '%prog version ' + version() 601 | 602 | parser.add_option("", "--help", action="help", help="show this help message") 603 | parser.add_option("-v", "--version", action="version", help="show version") 604 | 605 | parser.add_option("-a", "--all", 606 | action="store_true", dest="show_all", default=False, 607 | help="include filesystems having 0 blocks") 608 | parser.add_option("-h", "--human-readable", 609 | action="store_const", const='-h', dest="sizeformat", 610 | help="print sizes in human readable format (e.g., 1K 234M 2G)") 611 | parser.add_option("-H", "--si", 612 | action="store_const", const='-H', dest="sizeformat", 613 | help="likewise, but use powers of 1000 not 1024") 614 | parser.add_option("-b", "--block-size", 615 | action="store", dest="blocksize", default=0, type="int", 616 | help="use BLOCKSIZE-byte blocks") 617 | parser.add_option("-l", "--local", 618 | action="store_true", dest="local_only", default=False, 619 | help="limit listing to local filesystems") 620 | parser.add_option("-k", "--kilobytes", 621 | action="store_const", const='-k', dest="sizeformat", 622 | help="like --block-size=1024") 623 | parser.add_option("-m", "--megabytes", 624 | action="store_const", const='-m', dest="sizeformat", 625 | help="like --block-size=1048576") 626 | parser.add_option("-g", "--gigabytes", 627 | action="store_const", const='-g', dest="sizeformat", 628 | help="like --block-size=1073741824") 629 | parser.add_option("", "--blocks", 630 | action="store_const", const='--blocks', dest="sizeformat", 631 | help="use filesystem native block size") 632 | parser.add_option("", "--bw", 633 | action="store_true", dest="b_w", default=False, 634 | help="do not use colours") 635 | #parser.add_option("", "--sum", 636 | # action="store_true", dest="do_total_sum", default=False, 637 | # help="display sum of all the displayed sizes") 638 | parser.add_option("", "--mounts", 639 | action="store", dest="mounts_file", type="string", 640 | help="""File to get mount information from. 641 | On normal Linux systems only /etc/mtab or /proc/mounts make sense. 642 | Some other Unices use /etc/mnttab. 643 | Use /proc/mounts when /etc/mtab is corrupted or inaccessible 644 | (the output looks a bit weird in this case).""") 645 | parser.add_option("-B", "--show-binds", 646 | action="store_false", dest="hidebinds", default=hidebinds, 647 | help="show 'mount --bind' mounts") 648 | parser.add_option("-i", "--inodes", 649 | action="store_true", dest="inodes", default=False, 650 | help="show inode instead of block usage") 651 | 652 | (options, args) = parser.parse_args() 653 | 654 | blocksize = options.blocksize 655 | allfss = options.show_all 656 | localonly = options.local_only 657 | hidebinds = options.hidebinds 658 | inodes = options.inodes 659 | if inodes: 660 | header["size"] = "Nodes" 661 | 662 | if options.sizeformat: 663 | sizeformat = options.sizeformat 664 | 665 | #if options.do_total_sum: 666 | # do_total_sum = True 667 | 668 | if options.b_w: 669 | normal_colour = header_colour = local_fs_colour = remote_fs_colour = special_fs_colour = filled_fs_colour = full_fs_colour = 'none' 670 | if options.mounts_file: 671 | mountfile = options.mounts_file 672 | 673 | terminal_width = get_terminal_width() 674 | 675 | mountpoints = get_all_mountpoints() 676 | 677 | if args: 678 | mp_to_display = [find_mountpoint(os.path.realpath(x)) for x in args] 679 | mp_to_display = [x for x in mp_to_display if x is not None] 680 | else: 681 | mp_to_display = list(mountpoints.keys()) 682 | if localonly: 683 | mp_to_display = [x for x in mp_to_display if not is_remote_fs(mountpoints[x][1])] 684 | mp_to_display.sort() 685 | 686 | table = get_table(mp_to_display) 687 | display_table(table, terminal_width) 688 | 689 | 690 | -------------------------------------------------------------------------------- /pydf.1: -------------------------------------------------------------------------------- 1 | .TH PYDF 1 2 | .SH NAME 3 | pydf \- report colourised filesystem disk space usage 4 | .SH SYNOPSIS 5 | .B pydf 6 | .I "[options]" 7 | .I "[file]" 8 | .SH "DESCRIPTION" 9 | .B pydf 10 | is a python script that displays the amount of disk space available 11 | on the mounted filesystems, using different colours for different 12 | types of filesystems. Output format is completely customizable. 13 | .TP 14 | If an optional 15 | .I "file" 16 | argument is given, pydf displays just information about filesystem 17 | containing the file(s), otherwise it displays information about all 18 | mounted filesystems. 19 | 20 | .SH OPTIONS 21 | .TP 22 | .B \-\-help 23 | Show summary of options. 24 | .TP 25 | .B \-v, \-\-version 26 | Show version of program. 27 | .TP 28 | .B \-a, \-\-all 29 | include filesystems having 0 blocks 30 | .TP 31 | .B \-h, \-\-human-readable 32 | print sizes in human readable format (e.g., 133K 2341M 2448G) 33 | .TP 34 | .B \-H, \-\-si 35 | likewise, but use powers of 1000 not 1024 36 | .TP 37 | .B \-\-block-size=SIZE 38 | use SIZE-byte blocks 39 | .TP 40 | .B \-k, \-\-kilobytes 41 | like --block-size=1024 42 | .TP 43 | .B \-i, \-\-inodes 44 | show information about inodes instead of blocks 45 | .TP 46 | .B \-l, \-\-local 47 | limit listing to local filesystems 48 | .TP 49 | .B \-m, \-\-megabytes 50 | like --block-size=1048576 51 | .TP 52 | .B \-g, \-\-gigabytes 53 | like --block-size=1073741824 54 | .TP 55 | .B \-\-blocks 56 | use filesystem native block size 57 | .TP 58 | .B \-\-bw 59 | do not use colours 60 | .TP 61 | .B --mounts=FILE 62 | file to get mount information from. 63 | On normal linux system, only /etc/mtab or /proc/mounts make sense. 64 | Use /proc/mounts when /etc/mtab is corrupted or inaccessible 65 | (the output looks a bit weird in this case though) 66 | .TP 67 | .B \-B, \-\-show\-binds 68 | Show also mount --bind mounted filesystems. 69 | .SH "BUGS" 70 | When running with python3, mountpoints with out-of-locale non ASCII 71 | names will not be displayed (due to inability of os.statvfs to use bytes 72 | instead of strings). 73 | .SH "FILES" 74 | .TP 75 | .B /etc/pydfrc 76 | main configuration file 77 | .TP 78 | .B ~/.pydfrc 79 | per-user configuration file 80 | .SH "SEE ALSO" 81 | .BR df "(1) 82 | .SH AUTHOR 83 | Radovan Garab\('ik 84 | -------------------------------------------------------------------------------- /pydf1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k4rtik/pydf-pypi/663379293c773d547e12761be98a856553a39d0f/pydf1.png -------------------------------------------------------------------------------- /pydf2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k4rtik/pydf-pypi/663379293c773d547e12761be98a856553a39d0f/pydf2.png -------------------------------------------------------------------------------- /pydfrc: -------------------------------------------------------------------------------- 1 | # Configuration file for pydf 2 | # 3 | # 4 | # colours can be: 5 | # 'none' - no change from previous colour 6 | # 'default' - default system colour 7 | # 8 | # special attributes: 9 | # 'bold' 10 | # 'underline' 11 | # 'blink' 12 | # 'reverse' 13 | # 'concealed' 14 | # 15 | # foreground: 16 | # 'black' 17 | # 'red' 18 | # 'green' 19 | # 'yellow' 20 | # 'blue' 21 | # 'magenta' 22 | # 'cyan' 23 | # 'white' 24 | # 25 | # background: 26 | # 'on_black' 27 | # 'on_red' 28 | # 'on_green' 29 | # 'on_yellow' 30 | # 'on_blue' 31 | # 'on_magenta' 32 | # 'on_cyan' 33 | # 'on_white' 34 | # 35 | # beep: 36 | # 'beep' 37 | # 38 | # 39 | # or any combination of these, separated with commas 40 | 41 | 42 | # normal text colour - used to switch to after one row is displayed 43 | normal_colour = 'default' 44 | 45 | # colour of the header 46 | header_colour = 'yellow' 47 | 48 | # colour for local filesystems 49 | local_fs_colour = 'default' 50 | 51 | # colour for remote filesystems (such as nfs, samba, afs....) 52 | remote_fs_colour = 'green' 53 | 54 | # colour for special filesystems (such as proc, pty) 55 | special_fs_colour = 'blue' 56 | 57 | # colour for readonly mounted filesystems 58 | readonly_fs_colour = 'cyan' 59 | 60 | # colour for filesystems with usage > FILL_THRESH 61 | filled_fs_colour = 'red' 62 | 63 | # colour for filesystems with usage > FULL_THRESH 64 | full_fs_colour = 'on_red', 'green', 'blink' 65 | 66 | # custom device names - not implemented yet 67 | #custom_devices_colour = { 68 | # '/dev/loop' : ('green', 'blink') 69 | #} 70 | 71 | 72 | # default format for displaying sizes "-h" or "-H" or "-m" or "-k" or "--blocks" 73 | sizeformat = "-h" 74 | 75 | # string used to separace columns in the table 76 | column_separator = ' ' 77 | 78 | # colour of the string 79 | column_separator_colour = 'none' 80 | 81 | # if the screen is wider than necessary, stretch the bar: 82 | # 0 - do not stretch 83 | # 1 - stretch to fill the whole screen 84 | # real number in between - stretch by this ratio of free space 85 | stretch_screen = 0.3 86 | 87 | # filesystem filled up over this limit (in percents) is displayed 88 | # with filled_fs_colour (to show it is dangerously filled up) 89 | FILL_THRESH = 95.0 90 | 91 | # filesystem filled up over this limit is displayed with 92 | # full_fs_colour (to show it is FULL) 93 | FULL_THRESH = 99.0 94 | 95 | # Format used to display information: (keyword, size, justify). 96 | # keyword - one of 'fs' 'fstype' 'size' 'used' 'avail' 'perc' 'bar' 'on'. 97 | # size - if 'size' is integer, it is a minimal possible column width of the entry 98 | # if 'size' is float, it is a minimal column width in percent of screen width 99 | # 100 | # justify is either "l" for left justify, "r" for right justify or "c" for 101 | # center. 102 | # You can use any order and any combination of keywords, but 103 | # be careful not to exceed the size of your screen 104 | 105 | 106 | #format = [ 107 | # ('fs', 15, "l"), ('size', 9, "r"), 108 | # ('used', 9, "r"), ('avail', 9, "r"), ('perc', 5, "r"), 109 | # ('bar', 8, "l"), ('on', 16, "l") 110 | # ] 111 | 112 | # this is somewhat conservative 113 | # use fixed width for everything, since you want it readable 114 | # only the bar is specified by percentage, because you want it dynamic 115 | format = [ 116 | ('fs', 10, "l"), ('size', 5, "r"), 117 | ('used', 5, "r"), ('avail', 5, "r"), ('perc', 5, "r"), 118 | ('bar', 0.1, "l"), ('on', 11, "l") 119 | ] 120 | 121 | 122 | # character to display filesystem size bar 123 | barchar = '#' 124 | 125 | # fill the empty space of the size bar with this character 126 | bar_fillchar = '.' 127 | 128 | # hide 'mount --bind' binds? 129 | hidebinds = True 130 | 131 | # list of files to try to get mount information from 132 | # on normal linux systems only /etc/mtab or /proc/mounts make sense 133 | mountfile = ['/etc/mtab', '/etc/mnttab', '/proc/mounts'] 134 | 135 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [bdist_wheel] 2 | universal=1 3 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | try: 3 | from setuptools import setup 4 | except ImportError: 5 | from distutils.core import setup 6 | 7 | setup( 8 | name='pydf', 9 | version='12', 10 | description='colourised df(1)-clone', 11 | long_description=""" 12 | pydf is a python script that displays the amount of disk space available 13 | on the mounted filesystems, using different colours for different 14 | types of filesystems. Output format is completely customizable. 15 | """, 16 | url='http://kassiopeia.juls.savba.sk/~garabik/software/pydf/', 17 | author='Radovan Garabík', 18 | author_email='garabik@kassiopeia.juls.savba.sk', 19 | maintainer='Kartik Singhal', 20 | maintainer_email='kartiksinghal@gmail.com', 21 | license='Public Domain', 22 | classifiers=[ 23 | 'Development Status :: 4 - Beta', 24 | 'Environment :: Console', 25 | 'Intended Audience :: End Users/Desktop', 26 | 'Intended Audience :: System Administrators', 27 | 'License :: Public Domain', 28 | 'Operating System :: POSIX :: Linux', 29 | 'Programming Language :: Python :: 2', 30 | 'Programming Language :: Python :: 3', 31 | 'Topic :: System', 32 | 'Topic :: System :: Filesystems', 33 | 'Topic :: System :: Systems Administration', 34 | 'Topic :: Utilities', 35 | ], 36 | keywords='df disk space colours filesystems', 37 | scripts=['pydf'] 38 | ) 39 | --------------------------------------------------------------------------------