summaryrefslogtreecommitdiffstats
path: root/py3status/modules/volume_status.py
blob: a3951089b61dc900cb12f3e4cb1fc3beaaeff6c7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
"""
Show current volume from amixer.
Reads the current Master volume from amixer.
Configuration parameters:
	- format : format the output, available variables: {percentage}
	- format_mute : format the output when the volume is muted
	- cache_timeout : 0 by default, you usually want continuous monitoring
	- threshold_degraded : 50 by default, percentage to change color to color_degraded
	- threshold_bad : 20 by default, percentage to change color to color_bad
	- color_good : #00FF00 by default, good volume color
	- color_degraded : #FFFF00 by default, degraded volume color
	- color_bad : #FF0000 by default, bad volume color
	- channel : "Master" by default, alsamixer channel to track
@author <Jan T> <jans.tuomi@gmail.com>
@license BSD
"""

from time import time
import re
from subprocess import check_output


class Py3status:
	format = "{percentage}%"
	format_mute = "mute"
	cache_timeout = 0

	threshold_degraded = 50
	threshold_bad = 20

	color_good = "#00FF00"
	color_degraded = "#FFFF00"
	color_bad = "#FF0000"

	channel = "Master"

	def __init__(self):
		self.text = ""

	def _perc_to_color(self, string):
		try:
			value = int(string)
		except ValueError:
			return self.color_bad

		if value < self.threshold_bad:
			return self.color_bad
		elif value < self.threshold_degraded:
			return self.color_degraded
		else:
			return self.color_good

	# return the format string formatted with available variables
	def _format_output(self, format, percentage):
		text = format
		text = text.replace("{percentage}", percentage)
		return text

	# return the current channel volume value as a string
	def _get_percentage(self, output):
		prog = re.compile(r"\[\d{1,3}%\]")
		text = prog.findall(output)[0][1:-2]
		return text

	# returns True if the channel is muted
	def _get_muted(self, output):
		prog = re.compile(r"\[\w{2,3}\]")
		text = prog.findall(output)[0][1:-1]
		return text == "off"

	# this method is ran by py3status
	# returns a response dict
	def current_volume(self, i3s_output_list, i3s_config):

		# call amixer
		output = check_output(["amixer", "sget", self.channel]).decode()
	
		# get the current percentage value
		perc = self._get_percentage(output)

		# get info about channel mute status
		muted = self._get_muted(output)

		# determine the color based on the current volume level
		color = self._perc_to_color(perc)

		# format the output
		text = self._format_output(self.format_mute if muted else self.format, perc)

		# if the text has been changed, update the cached text and
		# set transformed to True
		transformed = text != self.text
		self.text = text

		# create response dict
		response = {
			'cached_until': time() + self.cache_timeout,
			'full_text': text,
			'transformed': transformed,
			'color': color
		}
		return response

	# open alsamixer on click
	def on_click(self, i3s_output_list, i3s_config, event):
		check_output(["i3-sensible-terminal", "-e", "alsamixer"])

# test if run directly
if __name__ == "__main__":
	from time import sleep
	x = Py3status()
	config = {}

	while True:
		print(x.current_volume([], config))
		sleep(1)