formatters.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. from __future__ import division
  2. import math
  3. from BTL.translation import _
  4. def percentify(fraction, completed):
  5. if fraction is None:
  6. return None
  7. if completed and fraction >= 1.0:
  8. percent = 100.0
  9. else:
  10. percent = min(99.9, math.floor(fraction * 1000.0) / 10.0)
  11. return percent
  12. class Size(long):
  13. """displays size in human-readable format"""
  14. size_labels = ['','K','M','G','T','P','E','Z','Y']
  15. radix = 2**10
  16. def __new__(cls, value=None, precision=None):
  17. if value is None:
  18. self = long.__new__(cls, 0)
  19. self.empty = True
  20. else:
  21. self = long.__new__(cls, value)
  22. self.empty = False
  23. return self
  24. def __init__(self, value, precision=0):
  25. long.__init__(self, value)
  26. self.precision = precision
  27. def __str__(self, precision=None):
  28. if self.empty:
  29. return ''
  30. if precision is None:
  31. precision = self.precision
  32. value = self
  33. for unitname in self.size_labels:
  34. if value < self.radix and precision < self.radix:
  35. break
  36. value /= self.radix
  37. precision /= self.radix
  38. if unitname and value < 10 and precision < 1:
  39. return '%.1f %sB' % (value, unitname)
  40. else:
  41. return '%.0f %sB' % (value, unitname)
  42. class Rate(Size):
  43. """displays rate in human-readable format"""
  44. def __init__(self, value=None, precision=2**10):
  45. Size.__init__(self, value, precision)
  46. def __str__(self, precision=2**10):
  47. if self.empty:
  48. return ''
  49. return '%s/s'% Size.__str__(self, precision=precision)
  50. class Duration(float):
  51. """displays duration in human-readable format"""
  52. def __new__(cls, value=None):
  53. if value == None:
  54. self = float.__new__(cls, 0)
  55. self.empty = True
  56. else:
  57. self = float.__new__(cls, value)
  58. self.empty = False
  59. return self
  60. def __str__(self):
  61. if self.empty or self > 365 * 24 * 60 * 60:
  62. return ''
  63. elif self >= 172800:
  64. return _("%d days") % round(self/86400) # 2 days or longer
  65. elif self >= 86400:
  66. return _("1 day %d hours") % ((self-86400)//3600) # 1-2 days
  67. elif self >= 3600:
  68. return _("%d:%02d hours") % (self//3600, (self%3600)//60) # 1 h - 1 day
  69. elif self >= 60:
  70. return _("%d:%02d minutes") % (self//60, self%60) # 1 minute to 1 hour
  71. elif self >= 0:
  72. return _("%d seconds") % int(self)
  73. else:
  74. return _("0 seconds")