def player_mpd(self, pl, host='localhost', port=6600): try: import mpd except ImportError: now_playing = run_cmd(pl, ['mpc', 'current', '-f', '%album%\n%artist%\n%title%\n%time%', '-h', str(host), '-p', str(port)]) if not now_playing: return now_playing = now_playing.split('\n') return { 'album': now_playing[0], 'artist': now_playing[1], 'title': now_playing[2], 'total': now_playing[3], } else: client = mpd.MPDClient() client.connect(host, port) now_playing = client.currentsong() if not now_playing: return status = client.status() client.close() client.disconnect() return { 'state': status.get('state'), 'state_symbol': self.STATE_SYMBOLS.get(status.get('state')), 'album': now_playing.get('album'), 'artist': now_playing.get('artist'), 'title': now_playing.get('title'), 'elapsed': self._convert_seconds(now_playing.get('elapsed', 0)), 'total': self._convert_seconds(now_playing.get('time', 0)), }
def player_mpd(self, pl, host="localhost", port=6600): try: import mpd except ImportError: now_playing = run_cmd( pl, ["mpc", "current", "-f", "%album%\n%artist%\n%title%\n%time%", "-h", str(host), "-p", str(port)] ) if not now_playing: return now_playing = now_playing.split("\n") return {"album": now_playing[0], "artist": now_playing[1], "title": now_playing[2], "total": now_playing[3]} else: client = mpd.MPDClient() client.connect(host, port) now_playing = client.currentsong() if not now_playing: return status = client.status() client.close() client.disconnect() return { "state": status.get("state"), "state_symbol": self.STATE_SYMBOLS.get(status.get("state")), "album": now_playing.get("album"), "artist": now_playing.get("artist"), "title": now_playing.get("title"), "elapsed": self._convert_seconds(now_playing.get("elapsed", 0)), "total": self._convert_seconds(now_playing.get("time", 0)), }
def get_player_status(self, pl): """ Returns MOC player information. mocp -i returns data with multi level information i.e. State: PAUSE File: <file_name> Title: <full_title> Artist: <artist_name> SongTitle: <track_title> ... """ now_playing_str = run_cmd(pl, ['mocp', '-i']) if not now_playing_str: return now_playing = dict((parts[0], parts[1]) for parts in [line.split(": ") for line in now_playing_str.split("\n")]) state = _convert_state(now_playing.get("State")) return { 'state': state, 'album': now_playing.get('Album', ''), 'artist': now_playing.get('Artist', ''), 'title': now_playing.get('SongTitle', ''), 'elapsed': _convert_seconds(int(now_playing.get('CurrentSec', 0))), 'total': _convert_seconds(int(now_playing.get('TotalSec', 0))) }
def get_connected_xrandr_outputs(pl): '''Iterate over xrandr outputs Outputs are represented by a dictionary with ``name``, ``width``, ``height``, ``primary``, ``x`` and ``y`` keys. ''' return (match.groupdict() for match in XRANDR_OUTPUT_RE.finditer( run_cmd(pl, ['xrandr', '-q']) ))
def player_rhythmbox(self, pl): now_playing = run_cmd(pl, ['rhythmbox-client', '--no-start', '--no-present', '--print-playing-format', '%at\n%aa\n%tt\n%te\n%td']) if not now_playing: return now_playing = now_playing.split('\n') return { 'album': now_playing[0], 'artist': now_playing[1], 'title': now_playing[2], 'elapsed': now_playing[3], 'total': now_playing[4], }
def get_amixer_stats(self, device, pl): amixer_output = run_cmd(pl, ['amixer', '-M', 'get', '-D', 'pulse', device]) for line in amixer_output.split("\n"): cleaned_line = line.strip() if cleaned_line.startswith("Front Left"): match = VOLUME_PATTERN.search(cleaned_line) if match is not None: left = match.group(1) elif cleaned_line.startswith("Front Right"): match = VOLUME_PATTERN.search(cleaned_line) if match is not None: right = match.group(1) return (left, right)
def player_rhythmbox(self, pl): now_playing = run_cmd( pl, ["rhythmbox-client", "--no-start", "--no-present", "--print-playing-format", "%at\n%aa\n%tt\n%te\n%td"] ) if not now_playing: return now_playing = now_playing.split("\n") return { "album": now_playing[0], "artist": now_playing[1], "title": now_playing[2], "elapsed": now_playing[3], "total": now_playing[4], }
def get_player_status(self, pl): now_playing = run_cmd(pl, [ 'rhythmbox-client', '--no-start', '--no-present', '--print-playing-format', '%at\n%aa\n%tt\n%te\n%td' ], strip=False) if not now_playing: return now_playing = now_playing.split('\n') return { 'album': now_playing[0], 'artist': now_playing[1], 'title': now_playing[2], 'elapsed': now_playing[3], 'total': now_playing[4], }
def clip(pl, hide_empty=True, cutoff=10): '''Return the current clipboard content using xsel. :param bool hide_empty: Hide the segment if the clipboard is empty. :param int cutoff: Max. number of characters to display. Highlight groups used: ``clip``. ''' clp = run_cmd(pl, ['xsel', '-bo']) if len(clp) < 1 and hide_empty: return None return [{ 'contents': (clp[0:cutoff] + '…' if len(clp) > cutoff else clp) if cutoff != 0 else clp, 'highlight_groups': ['clip'] }]
def get_player_status(self, pl): '''Return cmus player information. cmus-remote -Q returns data with multi-level information i.e. status playing file <file_name> tag artist <artist_name> tag title <track_title> tag .. tag n set continue <true|false> set repeat <true|false> set .. set n For the information we are looking for we don’t really care if we’re on the tag level or the set level. The dictionary comprehension in this method takes anything in ignore_levels and brings the key inside that to the first level of the dictionary. ''' now_playing_str = run_cmd(pl, ['cmus-remote', '-Q']) if not now_playing_str: return ignore_levels = ( 'tag', 'set', ) now_playing = dict( ((token[0] if token[0] not in ignore_levels else token[1], (' '.join(token[1:]) if token[0] not in ignore_levels else ' '.join(token[2:]))) for token in [line.split(' ') for line in now_playing_str.split('\n')[:-1]])) state = _convert_state(now_playing.get('status')) return { 'state': state, 'album': now_playing.get('album'), 'artist': now_playing.get('artist'), 'title': now_playing.get('title'), 'elapsed': _convert_seconds(now_playing.get('position', 0)), 'total': _convert_seconds(now_playing.get('duration', 0)), 'elapsed_raw': int(now_playing.get('position', 0)), 'total_raw': int(now_playing.get('duration', 0)), }
def get_player_status(self, pl, host='localhost', password=None, port=6600): try: import mpd except ImportError: if password: host = password + '@' + host now_playing = run_cmd(pl, [ 'mpc', 'current', '-f', '%album%\n%artist%\n%title%\n%time%', '-h', host, '-p', str(port) ], strip=False) if not now_playing: return now_playing = now_playing.split('\n') return { 'album': now_playing[0], 'artist': now_playing[1], 'title': now_playing[2], 'total': now_playing[3], } else: client = mpd.MPDClient() client.connect(host, port) if password: client.password(password) now_playing = client.currentsong() if not now_playing: return status = client.status() client.close() client.disconnect() return { 'state': status.get('state'), 'album': now_playing.get('album'), 'artist': now_playing.get('artist'), 'title': now_playing.get('title'), 'elapsed': _convert_seconds(now_playing.get('elapsed', 0)), 'total': _convert_seconds(now_playing.get('time', 0)), }
def get_player_status(self, pl, host='localhost', password=None, port=6600): try: import mpd except ImportError: if password: host = password + '@' + host now_playing = run_cmd(pl, [ 'mpc', 'current', '-f', '%album%\n%artist%\n%title%\n%time%', '-h', host, '-p', str(port) ], strip=False) if not now_playing: return now_playing = now_playing.split('\n') return { 'album': now_playing[0], 'artist': now_playing[1], 'title': now_playing[2], 'total': now_playing[3], } else: try: client = mpd.MPDClient(use_unicode=True) except TypeError: # python-mpd 1.x does not support use_unicode client = mpd.MPDClient() client.connect(host, port) if password: client.password(password) now_playing = client.currentsong() if not now_playing: return status = client.status() client.close() client.disconnect() return { 'state': status.get('state'), 'album': now_playing.get('album'), 'artist': now_playing.get('artist'), 'title': now_playing.get('title'), 'elapsed': _convert_seconds(status.get('elapsed', 0)), 'total': _convert_seconds(now_playing.get('time', 0)), }
def get_player_status(self, pl): '''Return Music On Console (mocp) player information. ``mocp -i`` returns current information i.e. .. code-block:: File: filename.format Title: full title Artist: artist name SongTitle: song title Album: album name TotalTime: 00:00 TimeLeft: 00:00 TotalSec: 000 CurrentTime: 00:00 CurrentSec: 000 Bitrate: 000kbps AvgBitrate: 000kbps Rate: 00kHz For the information we are looking for we don’t really care if we have extra-timing information or bit rate level. The dictionary comprehension in this method takes anything in ignore_info and brings the key inside that to the right info of the dictionary. ''' now_playing_str = run_cmd(pl, ['mocp', '-i']) if not now_playing_str: return now_playing = dict(( line.split(': ', 1) for line in now_playing_str.split('\n')[:-1] )) state = _convert_state(now_playing.get('State', 'stop')) return { 'state': state, 'album': now_playing.get('Album', ''), 'artist': now_playing.get('Artist', ''), 'title': now_playing.get('SongTitle', ''), 'elapsed': _convert_seconds(now_playing.get('CurrentSec', 0)), 'total': _convert_seconds(now_playing.get('TotalSec', 0)), }
def player_cmus(self, pl): """Return cmus player information. cmus-remote -Q returns data with multi-level information i.e. status playing file <file_name> tag artist <artist_name> tag title <track_title> tag .. tag n set continue <true|false> set repeat <true|false> set .. set n For the information we are looking for we don't really care if we're on the tag level or the set level. The dictionary comprehension in this method takes anything in ignore_levels and brings the key inside that to the first level of the dictionary. """ now_playing_str = run_cmd(pl, ["cmus-remote", "-Q"]) if not now_playing_str: return ignore_levels = ("tag", "set") now_playing = dict( ( ( token[0] if token[0] not in ignore_levels else token[1], (" ".join(token[1:]) if token[0] not in ignore_levels else " ".join(token[2:])), ) for token in [line.split(" ") for line in now_playing_str.split("\n")[:-1]] ) ) state = self._convert_state(now_playing.get("status")) return { "state": state, "state_symbol": self.STATE_SYMBOLS.get(state), "album": now_playing.get("album"), "artist": now_playing.get("artist"), "title": now_playing.get("title"), "elapsed": self._convert_seconds(now_playing.get("position", 0)), "total": self._convert_seconds(now_playing.get("duration", 0)), }
def generic_shell(pl, command, highlight_groups=["generic_shell"]): '''Execute the given command in a shell and return its result :param string command: The command to execute. :param string_list highlight_groups: The highlight groups to use. Click values supplied: ``contents`` (string) ''' contents = run_cmd(pl, ['/bin/sh'], command + '\n').strip('\n ') return [{ 'contents': contents, 'click_values': { 'contents': contents }, 'highlight_groups': highlight_groups }]
def battery(pl): """Return the battery segment.""" stats = run_cmd(pl, ['pmset', '-g', 'batt']) plugged_in = bool(BATTERY_AC_POWER.search(stats)) charging = bool(BATTERY_CHARGING.search(stats)) percent = int(BATTERY_PERCENT.search(stats).group(1)) warning = BATTERY_STATUS.search(stats) try: remaining = BATTERY_TIME.search(stats).group(1) except: remaining = 'no estimate' remaining ret = [] fmt = '{value}%' if plugged_in: gradient_level = 0 if charging: # highlight_groups = ['battery_gradient_ac'] highlight_groups = ['battery_ac_charging'] else: # highlight_groups = ['battery_gradient_ac_charged'] highlight_groups = ['battery_ac_not_charging'] ret.append({ 'contents': '●', 'highlight_groups': highlight_groups, }) else: gradient_level = 100 - percent if warning: if warning.group(1) == 'Final': highlight_groups = ['warning:critical'] else: highlight_groups = ['warning:regular'] else: highlight_groups = ['battery_gradient'] ret.append({ 'contents': fmt.format(value=percent), 'highlight_groups': highlight_groups, 'gradient_level': gradient_level }) ret[0]['divider_highlight_group'] = 'background:divider' return ret
def test_run_cmd(self): pl = Pl() self.assertEqual(run_cmd(pl, ['xxx_nonexistent_command_xxx']), None) self.assertEqual(len(pl.exceptions), 1) pl = Pl() self.assertEqual(run_cmd(pl, ['echo', ' test ']), 'test') self.assertFalse(pl) self.assertEqual(run_cmd(pl, ['echo', ' test '], strip=True), 'test') self.assertFalse(pl) self.assertEqual(run_cmd(pl, ['echo', ' test '], strip=False), ' test \n') self.assertFalse(pl) self.assertEqual(run_cmd(pl, ['cat'], stdin='test'), 'test') self.assertFalse(pl) self.assertEqual(run_cmd(pl, ['sh', '-c', 'cat >&2'], stdin='test'), '') self.assertFalse(pl)
def player_mpd(self, pl, host='localhost', port=6600): try: import mpd except ImportError: now_playing = run_cmd(pl, [ 'mpc', 'current', '-f', '%album%\n%artist%\n%title%\n%time%', '-h', str(host), '-p', str(port) ]) if not now_playing: return now_playing = now_playing.split('\n') return { 'album': now_playing[0], 'artist': now_playing[1], 'title': now_playing[2], 'total': now_playing[3], } else: client = mpd.MPDClient() client.connect(host, port) now_playing = client.currentsong() if not now_playing: return status = client.status() client.close() client.disconnect() return { 'state': status.get('state'), 'state_symbol': self.STATE_SYMBOLS.get(status.get('state')), 'album': now_playing.get('album'), 'artist': now_playing.get('artist'), 'title': now_playing.get('title'), 'elapsed': self._convert_seconds(now_playing.get('elapsed', 0)), 'total': self._convert_seconds(now_playing.get('time', 0)), }
def cpu_temperature(pl): '''Return cpu temperature. :param nix ''' smc = "/Users/Kassi/Applications/smcFanControl.app/Contents/Resources/smc" sensor = "TC0P" status = run_cmd(pl, [smc, '-r', '-k', sensor]) if not status: return p = re.compile('(\d+)\.\d+') m = p.findall(status) temp = int(m[0]) ret = [] ret.append({ 'contents': str(m[0]) + "°C", 'highlight_groups': ['battery_gradient', 'battery'], 'gradient_level': (temp-30)*2 }) return ret
def player_cmus(self, pl): '''Return cmus player information. cmus-remote -Q returns data with multi-level information i.e. status playing file <file_name> tag artist <artist_name> tag title <track_title> tag .. tag n set continue <true|false> set repeat <true|false> set .. set n For the information we are looking for we don't really care if we're on the tag level or the set level. The dictionary comprehension in this method takes anything in ignore_levels and brings the key inside that to the first level of the dictionary. ''' now_playing_str = run_cmd(pl, ['cmus-remote', '-Q']) if not now_playing_str: return ignore_levels = ('tag', 'set',) now_playing = dict(((token[0] if token[0] not in ignore_levels else token[1], (' '.join(token[1:]) if token[0] not in ignore_levels else ' '.join(token[2:]))) for token in [line.split(' ') for line in now_playing_str.split('\n')[:-1]])) state = self._convert_state(now_playing.get('status')) return { 'state': state, 'state_symbol': self.STATE_SYMBOLS.get(state), 'album': now_playing.get('album'), 'artist': now_playing.get('artist'), 'title': now_playing.get('title'), 'elapsed': self._convert_seconds(now_playing.get('position', 0)), 'total': self._convert_seconds(now_playing.get('duration', 0)), }
def brightness(pl): '''Return the monitor's brightness according to xbacklight.''' # It doesn't want to go right from float to int. brightness = int(round(float(run_cmd(pl, ["xbacklight", "-get"])), 0)) return "{}%".format(str(brightness))
def get_data(pl, pid): return run_cmd(pl,['ps', '-o', 'ppid=', '-o', 'cmd=', '-p', str(pid)]).split(None, 1)
def _get_capacity(pl): import re battery_summary = run_cmd(pl, ['pmset', '-g', 'batt']) battery_percent = re.search(r'(\d+)%', battery_summary).group(1) return int(battery_percent)
def _get_battery_status(pl): battery_summary = run_cmd(pl, ['pmset', '-g', 'batt']) battery_percent = BATTERY_PERCENT_RE.search(battery_summary).group(1) ac_charging = 'AC' in battery_summary return int(battery_percent), ac_charging
def _get_capacity(pl): battery_summary = run_cmd(pl, ['pmset', '-g', 'batt']) battery_percent = BATTERY_PERCENT_RE.search(battery_summary).group(1) return int(battery_percent)
def _get_capacity(pl): import re battery_summary = run_cmd(pl, ["pmset", "-g", "batt"]) battery_percent = re.search(r"(\d+)%", battery_summary).group(1) return int(battery_percent)
def get_tmux_output(pl, *args): '''Run tmux command and return its output''' return _run_tmux(lambda cmd: run_cmd(pl, cmd), args)
def _get_battery_status(pl): battery_summary = run_cmd(pl, ['pmset', '-g', 'batt']) battery_percent = BATTERY_PERCENT_RE.search(battery_summary).group(1) ac_charging = 'AC' in battery_summary estimated_time = BATTERY_ESTIMATED_TIME_RE.search(battery_summary).group(1) if '(no estimate)' not in battery_summary else '-:-' return int(battery_percent), ac_charging, estimated_time