Package pyrobase :: Module fmt
[hide private]
[frames] | no frames]

Source Code for Module pyrobase.fmt

  1  # -*- coding: utf-8 -*- 
  2  """ Data Formatting. 
  3   
  4      Copyright (c) 2009, 2011 The PyroScope Project <pyroscope.project@gmail.com> 
  5  """ 
  6  # This program is free software; you can redistribute it and/or modify 
  7  # it under the terms of the GNU General Public License as published by 
  8  # the Free Software Foundation; either version 2 of the License, or 
  9  # (at your option) any later version. 
 10  # 
 11  # This program is distributed in the hope that it will be useful, 
 12  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 13  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 14  # GNU General Public License for more details. 
 15  # 
 16  # You should have received a copy of the GNU General Public License along 
 17  # with this program; if not, write to the Free Software Foundation, Inc., 
 18  # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 
 19  import time 
 20  import codecs 
 21  import logging 
 22  import datetime 
 23   
 24  log = logging.getLogger(__name__) 
 25   
 26   
27 -def human_size(size):
28 """ Return a human-readable representation of a byte size. 29 30 @param size: Number of bytes as an integer or string. 31 @return: String of length 10 with the formatted result. 32 """ 33 if isinstance(size, basestring): 34 size = int(size, 10) 35 36 if size < 0: 37 return "-??? bytes" 38 39 if size < 1024: 40 return "%4d bytes" % size 41 for unit in ("KiB", "MiB", "GiB"): 42 size /= 1024.0 43 if size < 1024: 44 return "%6.1f %s" % (size, unit) 45 46 return "%6.1f GiB" % size
47 48
49 -def iso_datetime(timestamp=None):
50 """ Convert UNIX timestamp to ISO datetime string. 51 52 @param timestamp: UNIX epoch value (default: the current time). 53 @return: Timestamp formatted as "YYYY-mm-dd HH:MM:SS". 54 """ 55 if timestamp is None: 56 timestamp = time.time() 57 return datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:19]
58 59
60 -def iso_datetime_optional(timestamp):
61 """ Convert UNIX timestamp to ISO datetime string, or "never". 62 63 @param timestamp: UNIX epoch value. 64 @return: Timestamp formatted as "YYYY-mm-dd HH:MM:SS", or "never" for false values. 65 """ 66 if timestamp: 67 return iso_datetime(timestamp) 68 return "never"
69 70
71 -def human_duration(time1, time2=None, precision=0, short=False):
72 """ Return a human-readable representation of a time delta. 73 74 @param time1: Relative time value. 75 @param time2: Time base (C{None} for now; 0 for a duration in C{time1}). 76 @param precision: How many time units to return (0 = all). 77 @param short: Use abbreviations, and right-justify the result to always the same length. 78 @return: Formatted duration. 79 """ 80 if time2 is None: 81 time2 = time.time() 82 83 duration = (time1 or 0) - time2 84 direction = ( 85 " ago" if duration < 0 else 86 ("+now" if short else " from now") if time2 else "" 87 ) 88 duration = abs(duration) 89 parts = [ 90 ("weeks", duration // (7*86400)), 91 ("days", duration // 86400 % 7), 92 ("hours", duration // 3600 % 24), 93 ("mins", duration // 60 % 60), 94 ("secs", duration % 60), 95 ] 96 97 # Kill leading zero parts 98 while len(parts) > 1 and parts[0][1] == 0: 99 parts = parts[1:] 100 101 # Limit to # of parts given by precision 102 if precision: 103 parts = parts[:precision] 104 105 numfmt = ("%d", "%d"), ("%4d", "%2d") 106 fmt = "%1.1s" if short else " %s" 107 sep = " " if short else ", " 108 result = sep.join((numfmt[bool(short)][bool(idx)] + fmt) % (val, key[:-1] if val == 1 else key) 109 for idx, (key, val) in enumerate(parts) 110 if val #or (short and precision) 111 ) + direction 112 113 if not time1: 114 result = "never" if time2 else "N/A" 115 116 if precision and short: 117 return result.rjust(1 + precision*4 + (4 if time2 else 0)) 118 else: 119 return result
120 121
122 -def to_unicode(text):
123 """ Return a decoded unicode string. 124 False values are returned untouched. 125 """ 126 if not text or isinstance(text, unicode): 127 return text 128 129 try: 130 # Try UTF-8 first 131 return text.decode("UTF-8") 132 except UnicodeError: 133 try: 134 # Then Windows Latin-1 135 return text.decode("CP1252") 136 except UnicodeError: 137 # Give up, return byte string in the hope things work out 138 return text
139 140
141 -def to_utf8(text):
142 """ Enforce UTF8 encoding. 143 """ 144 # return empty/false stuff unaltered 145 if not text: 146 if isinstance(text, basestring): 147 text = "" 148 return text 149 150 try: 151 # Is it a unicode string, or pure ascii? 152 return text.encode("utf8") 153 except UnicodeDecodeError: 154 try: 155 # Is it a utf8 byte string? 156 if text.startswith(codecs.BOM_UTF8): 157 text = text[len(codecs.BOM_UTF8):] 158 return text.decode("utf8").encode("utf8") 159 except UnicodeDecodeError: 160 # Check BOM 161 if text.startswith(codecs.BOM_UTF16_LE): 162 encoding = "utf-16le" 163 text = text[len(codecs.BOM_UTF16_LE):] 164 elif text.startswith(codecs.BOM_UTF16_BE): 165 encoding = "utf-16be" 166 text = text[len(codecs.BOM_UTF16_BE):] 167 else: 168 # Assume CP-1252 169 encoding = "cp1252" 170 171 try: 172 return text.decode(encoding).encode("utf8") 173 except UnicodeDecodeError, exc: 174 for line in text.splitlines(): 175 try: 176 line.decode(encoding).encode("utf8") 177 except UnicodeDecodeError: 178 log.warn("Cannot transcode the following into UTF8 cause of %s: %r" % (exc, line)) 179 break 180 return text # Use as-is and hope the best
181 182
183 -def to_console(text):
184 """ Return a byte string intended for console output. 185 """ 186 if isinstance(text, str): 187 # For now, leave byte strings as-is (ignoring possible display problems) 188 return text 189 190 # Convert other stuff into an UTF-8 string 191 return unicode(text).encode("utf8")
192