fix static directory
This commit is contained in:
135
controldeck.py
135
controldeck.py
@@ -61,9 +61,17 @@ APP_NAME = "ControlDeck"
|
|||||||
COLOR_PRIME = "blue-grey-8" # "blue-grey-7" "blue-grey-8" 'light-blue-9'
|
COLOR_PRIME = "blue-grey-8" # "blue-grey-7" "blue-grey-8" 'light-blue-9'
|
||||||
COLOR_PRIME_TEXT = "blue-grey-7"
|
COLOR_PRIME_TEXT = "blue-grey-7"
|
||||||
COLOR_SELECT = "light-blue-9"
|
COLOR_SELECT = "light-blue-9"
|
||||||
|
DEBUG = False
|
||||||
|
|
||||||
CONFIG_FILE = '~/.config/controldeck/controldeck.conf'
|
CONFIG_DIR = path.join(path.expanduser("~"), '.config', APP_NAME.lower())
|
||||||
CONFIG_FILE_FULL = path.expanduser(CONFIG_FILE)
|
CONFIG_FILE_NAME = APP_NAME.lower() + '.conf'
|
||||||
|
CONFIG_FILE = path.join(CONFIG_DIR, CONFIG_FILE_NAME)
|
||||||
|
CACHE_DIR = path.join(path.expanduser('~'), '.cache', APP_NAME.lower())
|
||||||
|
STATIC_DIR = path.join(CACHE_DIR, 'static')
|
||||||
|
|
||||||
|
# justpy config overwrite
|
||||||
|
import jpcore.justpy_config
|
||||||
|
jpcore.justpy_config.STATIC_DIRECTORY = STATIC_DIR
|
||||||
|
|
||||||
def tohtml(text):
|
def tohtml(text):
|
||||||
return text.replace("\n", "<br>")
|
return text.replace("\n", "<br>")
|
||||||
@@ -94,17 +102,18 @@ def process(command_line, shell=False, output=True, stdout=PIPE, stderr=STDOUT):
|
|||||||
|
|
||||||
def config_load(conf=''):
|
def config_load(conf=''):
|
||||||
config = ConfigParser(strict=False)
|
config = ConfigParser(strict=False)
|
||||||
|
# fist check if file is given
|
||||||
if conf:
|
if conf:
|
||||||
full_config_file_path = conf
|
config_file_path = conf
|
||||||
else:
|
else:
|
||||||
config_file = "controldeck.conf"
|
# check if config file is located at the script's location
|
||||||
full_config_file_path = path.dirname(path.realpath(__file__)) + sep + config_file
|
config_file = path.dirname(path.realpath(__file__)) + sep + CONFIG_FILE_NAME # realpath; resolve symlink
|
||||||
if not path.exists(config_file):
|
if not path.exists(config_file):
|
||||||
config_folder = path.join(path.expanduser("~"), '.config', APP_NAME.lower())
|
# if not, use the file inside .config
|
||||||
makedirs(config_folder, exist_ok=True)
|
makedirs(CONFIG_DIR, exist_ok=True)
|
||||||
full_config_file_path = path.join(config_folder, config_file)
|
config_file = CONFIG_FILE
|
||||||
try:
|
try:
|
||||||
config.read(full_config_file_path)
|
config.read(path.expanduser(config_file))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"{e}")
|
print(f"{e}")
|
||||||
#print(config.sections())
|
#print(config.sections())
|
||||||
@@ -148,9 +157,13 @@ class Button(QBtn):
|
|||||||
self.style += "min-height: 77px;" # image + 2 text lines
|
self.style += "min-height: 77px;" # image + 2 text lines
|
||||||
self.style += "line-height: 1em;"
|
self.style += "line-height: 1em;"
|
||||||
if self.image and path.exists(self.image):
|
if self.image and path.exists(self.image):
|
||||||
static_dir = getcwd() + '/static'
|
# copy image files into the static folder
|
||||||
shutil.copy2(self.image, static_dir)
|
|
||||||
basename = path.basename(self.image)
|
basename = path.basename(self.image)
|
||||||
|
staticfile = path.join(STATIC_DIR, basename)
|
||||||
|
if not path.exists(staticfile):
|
||||||
|
shutil.copy2(self.image, staticfile)
|
||||||
|
if DEBUG:
|
||||||
|
print(f'[DEBUG] copy {self.image} to {staticfile}')
|
||||||
self.icon = f"img:/static/{basename}"
|
self.icon = f"img:/static/{basename}"
|
||||||
# <q-icon name="img:data:image/svg+xml;charset=utf8,<svg xmlns='http://www.w3.org/2000/svg' height='140' width='500'><ellipse cx='200' cy='80' rx='100' ry='50' style='fill:yellow;stroke:purple;stroke-width:2' /></svg>" />
|
# <q-icon name="img:data:image/svg+xml;charset=utf8,<svg xmlns='http://www.w3.org/2000/svg' height='140' width='500'><ellipse cx='200' cy='80' rx='100' ry='50' style='fill:yellow;stroke:purple;stroke-width:2' /></svg>" />
|
||||||
# <q-btn icon="img:data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" ... />
|
# <q-btn icon="img:data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" ... />
|
||||||
@@ -572,9 +585,9 @@ async def application(request):
|
|||||||
|
|
||||||
def toggle_edit_config(self, msg):
|
def toggle_edit_config(self, msg):
|
||||||
self.dialog.value = True
|
self.dialog.value = True
|
||||||
if path.exists(CONFIG_FILE_FULL):
|
if path.exists(CONFIG_FILE):
|
||||||
self.dialog_label.text = CONFIG_FILE
|
self.dialog_label.text = CONFIG_FILE
|
||||||
with open(CONFIG_FILE_FULL, encoding='utf-8') as file:
|
with open(CONFIG_FILE, encoding='utf-8') as file:
|
||||||
self.dialog_input.value = file.read()
|
self.dialog_input.value = file.read()
|
||||||
def edit_dialog_after(self, msg):
|
def edit_dialog_after(self, msg):
|
||||||
self.dialog_input.remove_class('changed')
|
self.dialog_input.remove_class('changed')
|
||||||
@@ -594,8 +607,8 @@ async def application(request):
|
|||||||
QSpace(a=edit_dialog_bar)
|
QSpace(a=edit_dialog_bar)
|
||||||
QSeparator(vertical=True,spaced=True,a=edit_dialog_bar)
|
QSeparator(vertical=True,spaced=True,a=edit_dialog_bar)
|
||||||
def edit_dialog_save(self, msg):
|
def edit_dialog_save(self, msg):
|
||||||
if path.exists(CONFIG_FILE_FULL):
|
if path.exists(CONFIG_FILE):
|
||||||
with open(CONFIG_FILE_FULL, mode='w', encoding='utf-8') as file:
|
with open(CONFIG_FILE, mode='w', encoding='utf-8') as file:
|
||||||
file.write(self.dialog_input.value)
|
file.write(self.dialog_input.value)
|
||||||
self.dialog_input.remove_class('changed')
|
self.dialog_input.remove_class('changed')
|
||||||
edit_dialog_btn_save = QBtn(
|
edit_dialog_btn_save = QBtn(
|
||||||
@@ -786,86 +799,6 @@ async def application(request):
|
|||||||
self.qnotify.notify = False
|
self.qnotify.notify = False
|
||||||
test_btn.on('after', test_btn_after)
|
test_btn.on('after', test_btn_after)
|
||||||
|
|
||||||
# tmp = process('pactl -f json list sink-inputs', stderr=None)
|
|
||||||
# print('')
|
|
||||||
# #print(tmp)
|
|
||||||
# #print(len(tmp))
|
|
||||||
# tmp = json.loads(tmp)
|
|
||||||
# print(tmp)
|
|
||||||
# print(len(tmp))
|
|
||||||
# if tmp:
|
|
||||||
# print('mute:', tmp[0]['mute'])
|
|
||||||
# print('volume:', tmp[0]['volume']['front-left']['value_percent'][:-1])
|
|
||||||
# print('application.process.binary:', tmp[0]['properties']['application.process.binary'])
|
|
||||||
# print('application.process.id:', tmp[0]['properties']['application.process.id'])
|
|
||||||
# if 'application.icon_name' in tmp[0]['properties']:
|
|
||||||
# print('application.icon_name:', tmp[0]['properties']['application.icon_name'])
|
|
||||||
# if 'media.icon_name' in tmp[0]['properties']:
|
|
||||||
# print('media.icon_name:', tmp[0]['properties']['media.icon_name'])
|
|
||||||
# print('media.name:', tmp[0]['properties']['media.name'])
|
|
||||||
# print('')
|
|
||||||
|
|
||||||
#tmp2 = process('pactl list sink-inputs | grep media.name', shell=True, stderr=None)
|
|
||||||
#print(tmp2)
|
|
||||||
# remove ' name.media = ' and remove quotation marks at front and back
|
|
||||||
# print([i[1:-1] for i in re.sub('[ \t]*media.name = ', '', tmp2, re.S).split('\n')])
|
|
||||||
|
|
||||||
# own pactl list sink-inputs parser (pactl 16.1, Compiled with libpulse 16.1.0)
|
|
||||||
tmp2 = process("pactl list sink-inputs", shell=True, stderr=None)
|
|
||||||
#print(tmp2)
|
|
||||||
tmp3 = []
|
|
||||||
for i in tmp2.split('Sink Input #'): # split block
|
|
||||||
if i:
|
|
||||||
tmp4 = {}
|
|
||||||
for j,k in enumerate(i.split('\n')): # split on every line
|
|
||||||
if j == 0: # fist entry
|
|
||||||
tmp4['id'] = k # is the id
|
|
||||||
tmp4['properties'] = {} # initialize
|
|
||||||
if k: # others are attributes
|
|
||||||
if 'Driver: ' in k:
|
|
||||||
tmp4['driver'] = re.sub('[ \t]*Driver: ', '', k)
|
|
||||||
elif 'Mute: ' in k:
|
|
||||||
tmp5 = re.sub('[ \t]*Mute: ', '', k)
|
|
||||||
tmp5 = tmp5.replace('no', 'false')
|
|
||||||
tmp5 = tmp5.replace('yes', 'true')
|
|
||||||
tmp4['mute'] = tmp5
|
|
||||||
elif 'Volume: ' in k:
|
|
||||||
tmp4['volume'] = {}
|
|
||||||
for l in re.sub('[ \t]*Volume: ', '', k).split(','):
|
|
||||||
tmp5 = l.split(': ')
|
|
||||||
tmp6 = tmp5[1].split(' / ')
|
|
||||||
tmp4['volume'][tmp5[0].strip()] = {
|
|
||||||
'value': tmp6[0], 'value_percent': tmp6[1], 'db': tmp6[2]}
|
|
||||||
# Properties
|
|
||||||
elif 'application.name = ' in k:
|
|
||||||
# remove '\t\tapplication.name = ' and remove quotation marks at front and back
|
|
||||||
tmp4['properties']['application.name'] = re.sub('[ \t]*application.name = ', '', k)[1:-1]
|
|
||||||
elif 'application.process.id = ' in k:
|
|
||||||
# remove '\t\tapplication.process.id = ' and remove quotation marks at front and back
|
|
||||||
tmp4['properties']['application.process.id'] = re.sub('[ \t]*application.process.id = ', '', k)[1:-1]
|
|
||||||
elif 'application.process.binary = ' in k:
|
|
||||||
# remove '\t\tapplication.process.binary = ' and remove quotation marks at front and back
|
|
||||||
tmp4['properties']['application.process.binary'] = re.sub('[ \t]*application.process.binary = ', '', k)[1:-1]
|
|
||||||
elif 'media.icon_name = ' in k:
|
|
||||||
# remove '\t\tmedia.icon_name = ' and remove quotation marks at front and back
|
|
||||||
tmp4['properties']['media.icon_name'] = re.sub('[ \t]*media.icon_name = ', '', k)[1:-1] # only pipewire?
|
|
||||||
elif 'application.icon_name = ' in k:
|
|
||||||
# remove '\t\tapplication.icon_name = ' and remove quotation marks at front and back
|
|
||||||
tmp4['properties']['application.icon_name'] = re.sub('[ \t]*application.icon_name = ', '', k)[1:-1] # only pulseaudio? (seen on wsl)
|
|
||||||
elif 'media.name = ' in k:
|
|
||||||
# remove '\t\tmedia.name = ' and remove quotation marks at front and back
|
|
||||||
tmp4['properties']['media.name'] = re.sub('[ \t]*media.name = ', '', k)[1:-1]
|
|
||||||
elif 'node.name = ' in k:
|
|
||||||
# remove '\t\tnode.name = ' and remove quotation marks at front and back
|
|
||||||
tmp4['properties']['node.name'] = re.sub('[ \t]*node.name = ', '', k)[1:-1]
|
|
||||||
tmp3.append(tmp4)
|
|
||||||
#import xdg.IconTheme
|
|
||||||
#print(tmp3)
|
|
||||||
#icon_name = ''
|
|
||||||
#icon_name = i['properties']['application.icon_name'] if 'application.icon_name' in i['properties'] else icon_name
|
|
||||||
#icon_name = i['properties']['media.icon_name'] if 'media.icon_name' in i['properties'] else icon_name
|
|
||||||
#icon = 'img:' + xdg.IconTheme.getIconPath(icon_name, size=None, extensions=['svg', 'png']),
|
|
||||||
|
|
||||||
# TODO: change reference wp.components to ...
|
# TODO: change reference wp.components to ...
|
||||||
if not wp.components:
|
if not wp.components:
|
||||||
# config not found or empty, therefore insert an empty div to not get an error
|
# config not found or empty, therefore insert an empty div to not get an error
|
||||||
@@ -887,9 +820,14 @@ def main(args):
|
|||||||
config = config_load(args.config)
|
config = config_load(args.config)
|
||||||
host = config.get('default', 'host', fallback='0.0.0.0')
|
host = config.get('default', 'host', fallback='0.0.0.0')
|
||||||
port = config.get('default', 'port', fallback='8000')
|
port = config.get('default', 'port', fallback='8000')
|
||||||
justpy(host=host, port=port, static_directory="./static")
|
|
||||||
|
if not path.exists(STATIC_DIR):
|
||||||
|
makedirs(STATIC_DIR, exist_ok=True)
|
||||||
|
justpy(host=host, port=port, start_server=True)
|
||||||
|
# this process will run as main loop
|
||||||
|
|
||||||
def cli():
|
def cli():
|
||||||
|
global DEBUG
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description=__doc__, prefix_chars='-',
|
description=__doc__, prefix_chars='-',
|
||||||
formatter_class=argparse.RawTextHelpFormatter,
|
formatter_class=argparse.RawTextHelpFormatter,
|
||||||
@@ -901,7 +839,10 @@ def cli():
|
|||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if args.debug:
|
if args.debug:
|
||||||
print(args)
|
DEBUG = True
|
||||||
|
print('[DEBUG] args:', args)
|
||||||
|
print('[DEBUG] __file__:', __file__)
|
||||||
|
print('[DEBUG] cwd:', getcwd())
|
||||||
|
|
||||||
main(args)
|
main(args)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user