2020-05-01 20:15:39 +02:00
import os
try :
import ast
except ImportError :
log . warning ( ' --list modules will not work (module " ast " not found) ' )
2020-05-02 13:43:17 +02:00
from configparser import RawConfigParser
2020-05-01 20:15:39 +02:00
import sys
import glob
import textwrap
2020-01-19 15:36:52 +01:00
import argparse
2020-04-08 11:50:00 +02:00
import logging
2020-01-19 15:36:52 +01:00
2020-05-01 20:15:39 +02:00
import core . theme
2020-01-25 14:24:21 +01:00
import util . store
2020-04-02 16:54:57 +02:00
import util . format
2020-01-25 14:24:21 +01:00
2020-05-01 20:15:39 +02:00
import modules . core
import modules . contrib
2020-04-08 11:50:00 +02:00
log = logging . getLogger ( __name__ )
2020-02-09 13:46:56 +01:00
MODULE_HELP = ' Specify a space-separated list of modules to load. The order of the list determines their order in the i3bar (from left to right). Use <module>:<alias> to provide an alias in case you want to load the same module multiple times, but specify different parameters. '
PARAMETER_HELP = ' Provide configuration parameters in the form of <module>.<key>=<value> '
THEME_HELP = ' Specify the theme to use for drawing modules '
2020-01-19 15:36:52 +01:00
2020-05-01 20:15:39 +02:00
def all_modules ( ) :
""" Return a list of available modules """
result = { }
for path in [ modules . core . __file__ , modules . contrib . __file__ ] :
path = os . path . dirname ( path )
for mod in glob . iglob ( ' {} /*.py ' . format ( path ) ) :
result [ os . path . basename ( mod ) . replace ( ' .py ' , ' ' ) ] = 1
res = list ( result . keys ( ) )
res . sort ( )
return res
class print_usage ( argparse . Action ) :
def __init__ ( self , option_strings , dest , nargs = None , * * kwargs ) :
argparse . Action . __init__ ( self , option_strings , dest , nargs , * * kwargs )
self . _indent = ' ' * 2
def __call__ ( self , parser , namespace , value , option_string = None ) :
if value == ' modules ' :
self . _args = namespace
self . _format = ' plain '
self . print_modules ( )
elif value == ' modules-markdown ' :
self . _args = namespace
self . _format = ' markdown '
self . print_modules ( )
elif value == ' themes ' :
self . print_themes ( )
sys . exit ( 0 )
def print_themes ( self ) :
print ( ' , ' . join ( core . theme . themes ( ) ) )
def print_modules ( self ) :
if self . _format == ' markdown ' :
print ( ' # Table of modules ' )
print ( ' |Name |Description | ' )
print ( ' |-----|------------| ' )
for m in all_modules ( ) :
try :
basepath = os . path . abspath ( os . path . join ( os . path . dirname ( os . path . realpath ( __file__ ) ) , ' .. ' ) )
filename = os . path . join ( basepath , ' modules ' , ' core ' , ' {} .py ' . format ( m ) )
if not os . path . exists ( filename ) :
filename = os . path . join ( basepath , ' modules ' , ' contrib ' , ' {} .py ' . format ( m ) )
if not os . path . exists ( filename ) :
log . warning ( ' module {} not found ' . format ( m ) )
continue
doc = None
with open ( filename ) as f :
tree = ast . parse ( f . read ( ) )
doc = ast . get_docstring ( tree )
if not doc :
log . warning ( ' failed to find docstring for {} ' . format ( m ) )
continue
if self . _format == ' markdown ' :
doc = doc . replace ( ' < ' , ' \ < ' )
doc = doc . replace ( ' > ' , ' \ > ' )
doc = doc . replace ( ' \n ' , ' <br> ' )
print ( ' | {} | {} | ' . format ( m , doc ) )
else :
print ( textwrap . fill ( ' {} : ' . format ( m ) , 80 ,
initial_indent = self . _indent * 2 , subsequent_indent = self . _indent * 2 ) )
for line in doc . split ( ' \n ' ) :
print ( textwrap . fill ( line , 80 ,
initial_indent = self . _indent * 3 , subsequent_indent = self . _indent * 6 ) )
except Exception as e :
log . warning ( e )
2020-01-25 14:24:21 +01:00
class Config ( util . store . Store ) :
2020-01-19 15:36:52 +01:00
def __init__ ( self , args ) :
2020-01-25 14:24:21 +01:00
super ( Config , self ) . __init__ ( )
2020-01-19 15:36:52 +01:00
parser = argparse . ArgumentParser ( description = ' bumblebee-status is a modular, theme-able status line generator for the i3 window manager. https://github.com/tobi-wan-kenobi/bumblebee-status/wiki ' )
2020-02-09 13:46:56 +01:00
parser . add_argument ( ' -m ' , ' --modules ' , nargs = ' + ' , action = ' append ' , default = [ ] ,
2020-01-19 15:36:52 +01:00
help = MODULE_HELP )
2020-02-09 13:46:56 +01:00
parser . add_argument ( ' -p ' , ' --parameters ' , nargs = ' + ' , action = ' append ' , default = [ ] ,
2020-01-25 14:24:21 +01:00
help = PARAMETER_HELP )
2020-02-09 13:46:56 +01:00
parser . add_argument ( ' -t ' , ' --theme ' , default = ' default ' , help = THEME_HELP )
parser . add_argument ( ' -i ' , ' --iconset ' , default = ' auto ' ,
help = ' Specify the name of an iconset to use (overrides theme default) ' )
2020-03-29 14:13:21 +02:00
parser . add_argument ( ' -a ' , ' --autohide ' , nargs = ' + ' , default = [ ] ,
help = ' Specify a list of modules to hide when not in warning/error state ' )
2020-04-30 12:52:09 +02:00
parser . add_argument ( ' -d ' , ' --debug ' , action = ' store_true ' ,
2020-03-29 14:13:21 +02:00
help = ' Add debug fields to i3 output ' )
2020-05-01 09:41:06 +02:00
parser . add_argument ( ' -f ' , ' --logfile ' , help = ' destination for the debug log file, if -d|--debug is specified; defaults to stderr ' )
2020-05-01 15:17:55 +02:00
parser . add_argument ( ' -r ' , ' --right-to-left ' , action = ' store_true ' , help = ' Draw widgets from right to left, rather than left to right (which is the default) ' )
2020-05-01 20:15:39 +02:00
parser . add_argument ( ' -l ' , ' --list ' , choices = [ ' modules ' , ' themes ' , ' modules-markdown ' ] , help = ' Display a list of available themes or available modules, along with their parameters ' ,
action = print_usage )
2020-05-01 15:17:55 +02:00
2020-04-04 13:54:08 +02:00
self . __args = parser . parse_args ( args )
2020-01-19 15:36:52 +01:00
2020-05-02 13:43:17 +02:00
for cfg in [ ' ~/.bumblebee-status.conf ' , ' ~/.config/bumblebee-status.conf ' , ' ~/.config/bumblebee-status/config ' ] :
cfg = os . path . expanduser ( cfg )
self . load_config ( cfg )
2020-04-04 13:54:08 +02:00
parameters = [ item for sub in self . __args . parameters for item in sub ]
2020-01-25 14:24:21 +01:00
for param in parameters :
2020-04-08 11:50:00 +02:00
if not ' = ' in param :
log . error ( ' missing value for parameter " {} " - ignoring this parameter ' . format ( param ) )
continue
2020-02-09 13:46:56 +01:00
key , value = param . split ( ' = ' , 1 )
2020-01-25 14:24:21 +01:00
self . set ( key , value )
2020-05-02 13:43:17 +02:00
def load_config ( self , filename ) :
if os . path . exists ( filename ) :
log . info ( ' loading {} ' . format ( filename ) )
tmp = RawConfigParser ( )
tmp . read ( filename )
if tmp . has_section ( ' module-parameters ' ) :
for key , value in tmp . items ( ' module-parameters ' ) :
self . set ( key , value )
2020-01-19 15:36:52 +01:00
def modules ( self ) :
2020-04-04 13:54:08 +02:00
return [ item for sub in self . __args . modules for item in sub ]
2020-01-19 15:36:52 +01:00
2020-04-02 16:54:57 +02:00
def interval ( self , default = 1 ) :
return util . format . seconds ( self . get ( ' interval ' , default ) )
2020-02-09 13:46:56 +01:00
2020-03-29 14:13:21 +02:00
def debug ( self ) :
2020-04-04 13:54:08 +02:00
return self . __args . debug
2020-03-29 14:13:21 +02:00
2020-05-01 15:17:55 +02:00
def reverse ( self ) :
return self . __args . right_to_left
2020-05-01 09:41:06 +02:00
def logfile ( self ) :
return self . __args . logfile
2020-02-09 13:46:56 +01:00
def theme ( self ) :
2020-04-04 13:54:08 +02:00
return self . __args . theme
2020-02-09 13:46:56 +01:00
def iconset ( self ) :
2020-04-04 13:54:08 +02:00
return self . __args . iconset
2020-01-25 14:24:21 +01:00
2020-03-15 14:01:09 +01:00
def autohide ( self , name ) :
2020-04-04 13:54:08 +02:00
return name in self . __args . autohide
2020-03-15 14:01:09 +01:00
2020-01-19 15:36:52 +01:00
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4