/powerline/segments/battery.py

https://github.com/Nemo157/.configs · Python · 126 lines · 109 code · 16 blank · 1 comment · 36 complexity · 7f5e27e93916066bc8dd23ece4b9efd3 MD5 · raw file

  1. # vim:fileencoding=utf-8:et:sw=2:ts=2
  2. from __future__ import absolute_import
  3. import os
  4. import sys
  5. import re
  6. from datetime import datetime
  7. import socket
  8. from multiprocessing import cpu_count as _cpu_count
  9. from powerline.lib import add_divider_highlight_group
  10. from powerline.lib.url import urllib_read, urllib_urlencode
  11. from powerline.lib.vcs import guess, tree_status
  12. from powerline.lib.threaded import ThreadedSegment, KwThreadedSegment, with_docstring
  13. from powerline.lib.monotonic import monotonic
  14. from powerline.lib.humanize_bytes import humanize_bytes
  15. from powerline.theme import requires_segment_info
  16. from collections import namedtuple
  17. def _run_cmd(cmd):
  18. from subprocess import Popen, PIPE
  19. try:
  20. p = Popen(cmd, stdout=PIPE)
  21. stdout, err = p.communicate()
  22. except OSError as e:
  23. sys.stderr.write('Could not execute command ({0}): {1}\n'.format(e, cmd))
  24. return None
  25. return stdout.strip()
  26. _current_source_regex = re.compile('(Currently|Now) drawing from \'(.*)\'')
  27. _current_percent_regex = re.compile('(\\d+)%')
  28. _charging_regex = re.compile('charging')
  29. _discharging_regex = re.compile('discharging')
  30. _not_charging_regex = re.compile('not charging')
  31. _time_remaining_regex = re.compile('((\d+):(\d+)) remaining')
  32. def _get_battery_info():
  33. raw = _run_cmd(['/usr/bin/pmset', '-g', 'batt'])
  34. current_source = _current_source_regex.search(raw)
  35. if current_source is not None:
  36. current_source = current_source.group(2)
  37. current_percent = _current_percent_regex.search(raw)
  38. if current_percent is not None:
  39. current_percent = int(current_percent.group(1))
  40. charging = not not (_charging_regex.search(raw) and not _discharging_regex.search(raw) and not _not_charging_regex.search(raw))
  41. discharging = not not _discharging_regex.search(raw)
  42. time_remaining = _time_remaining_regex.search(raw)
  43. if time_remaining is not None:
  44. hours_remaining = int(time_remaining.group(2))
  45. minutes_remaining = int(time_remaining.group(3))
  46. time_remaining = time_remaining.group(1)
  47. if time_remaining is None or time_remaining == '0:00':
  48. hours_remaining = 0
  49. minutes_remaining = 0
  50. time_remaining = ''
  51. return {
  52. "current_source": current_source,
  53. "current_percent": current_percent,
  54. "charging": charging,
  55. "discharging": discharging,
  56. "time_remaining": time_remaining,
  57. "hours_remaining": hours_remaining,
  58. "minutes_remaining": minutes_remaining
  59. }
  60. def _calculate_fuzzy_time_remaining(hours, minutes):
  61. if hours < 1:
  62. if minutes < 2:
  63. return str(minutes) + ' minute'
  64. else:
  65. return str(minutes) + ' minutes'
  66. elif hours < 2:
  67. if minutes < 30:
  68. return str(minutes + 60) + ' minutes'
  69. else:
  70. return str((hours + 1)) + ' hours'
  71. else:
  72. if minutes < 30:
  73. return str(hours) + ' hours'
  74. else:
  75. return str((hours + 1)) + ' hours'
  76. @requires_segment_info
  77. def current_source(pl, segment_info, AC_text=None, battery_text=None):
  78. battery_info = _get_battery_info()
  79. result = battery_info['current_source']
  80. if AC_text is not None and result == 'AC Power':
  81. result = AC_text
  82. if battery_text is not None and result == 'Battery Power':
  83. result = battery_text
  84. return result
  85. @requires_segment_info
  86. def current_percent(pl, segment_info):
  87. battery_info = _get_battery_info()
  88. return battery_info['current_percent'] + '%'
  89. @requires_segment_info
  90. def charging(pl, segment_info, charging_text='charging', discharging_text='discharging', not_charging_text=None):
  91. battery_info = _get_battery_info()
  92. return charging_text if battery_info['charging'] else (discharging_text if battery_info['discharging'] else not_charging_text)
  93. @requires_segment_info
  94. def time_remaining(pl, segment_info):
  95. battery_info = _get_battery_info()
  96. return battery_info['time_remaining']
  97. @requires_segment_info
  98. def format(pl, segment_info, format, time_format=None, AC_text=None, battery_text=None, charging_text='charging', discharging_text='discharging', not_charging_text=''):
  99. battery_info = _get_battery_info()
  100. battery_info['charging_state'] = charging_text if battery_info['charging'] else (discharging_text if battery_info['discharging'] else not_charging_text)
  101. if AC_text is not None and battery_info['current_source'] == 'AC Power':
  102. battery_info['current_source'] = AC_text
  103. if battery_text is not None and battery_info['current_source'] == 'Battery Power':
  104. battery_info['current_source'] = battery_text
  105. if time_format is not None:
  106. battery_info['fuzzy_time_remaining'] = _calculate_fuzzy_time_remaining(battery_info['hours_remaining'], battery_info['minutes_remaining'])
  107. battery_info['formatted_time_remaining'] = time_format % battery_info
  108. if battery_info['time_remaining'] == '':
  109. battery_info['formatted_time_remaining'] = ''
  110. return format % battery_info