import threading import subprocess import i3_lemonbar_config as config import i3_lemonbar_common as common import i3_lemonbar_parser as parser class LemonModule(threading.Thread): # Module generates some status message, parses it, and handles on click actions # Every module runs in its own thread def __init__(self): super().__init__() self._start_module() # TODO if exists dummy data send it def run(self): while True: line = self.status_handle.readline() if not line: common.logger.info('Reached end of module {}'.format(self.name)) common.health_logger.info('Reached end of module {}'.format(self.name)) break parsed = self.parse(line) common.parsing_queue.put([parsed]) # TODO Wrapped in list, temporary solution def stop(self): self._stop_module() def parse(self, line): # TODO get rid of prefix data = line[len(self.prefix):].split() self._parse_data(data) # Update correct field formatted_line = parser.format_line() # Construct entire line return formatted_line class ConkyFastModule(LemonModule): def __init__(self): self.prefix = 'CNK_FAST' super().__init__() def _start_module(self): self.p_handle = subprocess.Popen(['conky', '-c', config.path+'conky_fast'], stdout=subprocess.PIPE, text=True) self.status_handle = self.p_handle.stdout common.logger.debug('Started conky fast module') def _stop_module(self): if self.p_handle is not None: self.p_handle.terminate() def _parse_data(self, data): mute = data[4] == 'MUTE' or data[4] == 'NONE' (vol,vols) = (-1,'×') if mute else (int(data[4]), data[4]+'%') icon_v = config.icon_vol_mute if vol == 0 else \ config.icon_vol_low if vol < 50 else config.icon_vol parser.volume = parser.single_sect(icon=icon_v, click='pavu', text=vols , alt=parser.COLOR_SCHEME.A2) tme = data[3] if common.show_secs else data[3][:-3] parser.date = parser.single_sect(icon=config.icon_clock, click='date' , text=' '.join(data[0:3]), alt=parser.COLOR_SCHEME.A1) parser.time = parser.single_sect(click='toggle_secs', text=tme, alt=parser.COLOR_SCHEME.SPECIAL) parser.update_net(data[5:9]) class ConkySlowModule(LemonModule): def __init__(self): self.prefix = 'CNK_SLOW' super().__init__() def _start_module(self): self.p_handle = subprocess.Popen(['conky', '-c', config.path+'conky_slow'], stdout=subprocess.PIPE, text=True) self.status_handle = self.p_handle.stdout common.logger.debug('Started conky slow module') def _stop_module(self): if self.p_handle is not None: self.p_handle.terminate() def _parse_data(self, data): # System load if int(data[0]) > int(config.cpu_alert): cpu_alt = parser.COLOR_SCHEME.CPU_ALERT else: cpu_alt = parser.COLOR_SCHEME.A2 parser.sys_load = ''.join([ parser.double_sect(text1 = (data[0] + '%'), text2 = data[1], icon1 = config.icon_cpu , icon2 = config.icon_mem, alt=cpu_alt , click = 'load') , parser.double_sect(text1 = (data[2] + '%'), text2 = (data[3] + '%') , icon1 = config.icon_hd, icon2 = config.icon_home, alt=parser.COLOR_SCHEME.A1) ]) # cpu mem disk_r disk_home #sec_color = config.color_sec_b1 if (b == 1) else config.color_sec_b2 (batt_stat, batt) = (data[4][0], int(data[4][1:])) icon_batt = config.icon_charging if batt_stat == 'C' else \ config.icon_charged if batt_stat == 'F' else \ config.icon_batt_0 if batt < 20 else \ config.icon_batt_1 if batt < 40 else \ config.icon_batt_2 if batt < 60 else \ config.icon_batt_3 if batt < 80 else \ config.icon_batt_4 battery = parser.single_sect(icon=icon_batt, click='dpms', text=(str(batt)+'%') , alt=parser.COLOR_SCHEME.A2) parser.update_bright([data[5]]) parser.update_lang([data[6]]) def start_all(): global m_conky_fast, m_conky_slow m_conky_fast = ConkyFastModule() m_conky_slow = ConkySlowModule() m_conky_fast.start() m_conky_slow.start() def stop_all(): global m_conky_fast, m_conky_slow m_conky_fast.stop() m_conky_slow.stop()