aboutsummaryrefslogtreecommitdiff
path: root/i3/bin/i3status.py
blob: 1a2d166507a47c01d94106a434af1121ae730337 (plain) (blame)
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
#!/usr/bin/env python
import json
from select import select
from subprocess import check_output, Popen, PIPE
import sys

def remove_empty_outputs(obj):
    return [o for o in obj if o['full_text'].strip() != '']

first = True
def print_i3stat(j):
    global first
    j = remove_empty_outputs(j)
    sys.stdout.write(('' if first else ',') + json.dumps(j) + '\n')
    sys.stdout.flush()
    first = False

def parse_i3stat(s):
    if s[0] == ',':
        s = s[1:]
    j = json.loads(s)
    return j

def parse_kbdlayout(s):
    colors = { 'us(intl)' : '#66ccff',
            'us(dvorak-intl)' : '#dc68fc',
            'ru(phonetic)' : '#ff3300',
            'il(biblicalSIL)' : '#66ff66'
            }
    try:
        color = colors[s]
    except:
        color = '#cccccc'
    return [{'full_text': s, 'color': color}]

def print_album_and_artist(info, parentheses):
    if 'album' in info:
        if 'artist' in info:
            if parentheses:
                return info['album'] + ' (' + info['artist'] + ')'
            else:
                return info['album'] + ', ' + info['artist']
        else:
            return info['album']
    elif 'artist' in info:
        return info['artist']
    else:
        return None

def get_cmus_song():
    result = check_output(['cmus-remote', '-Q'])
    info = {}
    for line in result.split('\n'):
        if line[:10] == 'tag title ':
            info['title'] = line[10:]
        elif line[:10] == 'tag album ':
            info['album'] = line[10:]
        elif line[:11] == 'tag artist ':
            info['artist'] = line[11:]

    album_and_artist = print_album_and_artist(info, 'title' not in info)
    text = None
    if album_and_artist is None:
        if 'title' in info:
            text = info['title']
    elif 'title' in info:
        text = info['title'] + ' (' + album_and_artist + ')'
    else:
        text = album_and_artist

    if text is None:
        return []
    else:
        return [{'full_text': text}]

def merge_status_items(*args):
    return [item for sublist in args for item in sublist]

if __name__ == '__main__':
    timeout = 0.1

    # open subprocesses
    i3stat = Popen(['i3status'], stdout=PIPE, bufsize=1, close_fds=True)
    kbdlayout = Popen(['unbuffer', 'kbdlayout'], 
            stdout=PIPE, bufsize=1, close_fds=True)
    # skip i3status header
    sys.stdout.write(i3stat.stdout.readline())
    sys.stdout.write(i3stat.stdout.readline())

    stat, kbd, cmus = [], [], []
    try:
        stdouts = [p.stdout for p in [i3stat, kbdlayout]]
        while True:
            fs = select(stdouts, [], [])[0]
            for f in fs:
                line = f.readline()[:-1]
                if f == kbdlayout.stdout:
                    kbd = parse_kbdlayout(line)
                elif f == i3stat.stdout:
                    stat = parse_i3stat(line)

            try:
                cmus = get_cmus_song()
            except:
                cmus = []
    
            print_i3stat(merge_status_items(kbd, cmus, stat))

    except Exception, e:
        print(e)
        i3stat.kill()
        kbdlayout.kill()