Browse Source

update template

master
Nils 2 years ago
parent
commit
b421840717
  1. 68
      template/calfbox/py/metadata.py
  2. 41
      template/documentation/build.py
  3. 31
      template/engine/session.py
  4. 8
      template/start.py

68
template/calfbox/py/metadata.py

@ -7,6 +7,8 @@ This file implements the JackIO Python side of Jack Medata as described here:
""" """
import os.path
#get_thing #get_thing
from calfbox._cbox2 import do_cmd from calfbox._cbox2 import do_cmd
@ -91,9 +93,73 @@ class Metadata:
for port, index in pDict.items(): for port, index in pDict.items():
Metadata.set_port_order(port, index) Metadata.set_port_order(port, index)
@staticmethod @staticmethod
def set_pretty_name(port, name): def set_pretty_name(port, name):
"""port is the portname as string including a client name System:out_1 """port is the portname as string including a client name System:out_1
Name however is just the port name, without a client.""" Name however is just the port name, without a client."""
Metadata.set_property(port, "http://jackaudio.org/metadata/pretty-name", name) Metadata.set_property(port, "http://jackaudio.org/metadata/pretty-name", name)
@staticmethod
def _set_icon_name(port, freeDeskopIconName):
"""Internal function used in set_icon_small and set_icon_large"""
if not os.path.splitext(freeDeskopIconName)[0] == freeDeskopIconName:
raise ValueEror(f"Icon name must not have a file extension. Expected {os.path.splitext(freeDeskopIconName)[0]} but was {freeDeskopIconName}")
if not os.path.basename(freeDeskopIconName) == freeDeskopIconName:
raise ValueError(f"Icon name must not be path. Expected {os.path.basename(freeDeskopIconName)} but was {freeDeskopIconName}")
self.set_property(port, "http://jackaudio.org/metadata/icon-name", freeDeskopIconName)
@staticmethod
def set_icon_small(port, freeDeskopIconName, base64png):
""" A value with a MIME type of "image/png;base64" that is an encoding of an
NxN (with 32 < N <= 128) image to be used when displaying a visual representation of that
client or port.
The name of the icon for the subject (typically client).
This is used for looking up icons on the system, possibly with many sizes or themes. Icons
should be searched for according to the freedesktop Icon
Theme Specification:
https://specifications.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html
The small icon of our JACK client.
Setting icons to ports seems to be technically possible, but this is not the function
for port-icons.
This function does not check if base64png has the correct format.
This also sets the name of the icon according to freedesktop specs.
The name is the basename without extension like so:
/usr/share/icons/hicolor/32x32/apps/patroneo.png -> "patroneo"
"""
self.set_property(port, "http://jackaudio.org/metadata/icon-small", base64png, jackPropertyType="image/png;base64")
self._set_icon_name(port, freeDeskopIconName)
@staticmethod
def set_icon_large(base64png):
""" A value with a MIME type of "image/png;base64" that is an encoding of an
NxN (with N <=32) image to be used when displaying a visual representation of that client
or port.
The name of the icon for the subject (typically client).
This is used for looking up icons on the system, possibly with many sizes or themes. Icons
should be searched for according to the freedesktop Icon
Theme Specification:
https://specifications.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html
The large icon of our JACK client.
Setting icons to ports seems to be technically possible, but this is not the function
for port-icons.
This function does not check if base64png has the correct format.
This also sets the name of the icon according to freedesktop specs.
The name is the basename without extension like so:
/usr/share/icons/hicolor/32x32/apps/patroneo.png -> "patroneo"
"""
self.set_property(port, "http://jackaudio.org/metadata/icon-large", base64png, jackPropertyType="image/png;base64")
self._set_icon_name(port, freeDeskopIconName)

41
template/documentation/build.py

@ -28,6 +28,7 @@ from os import getcwd
import os.path import os.path
assert os.path.exists(os.path.join(getcwd(), __file__)), (getcwd(), __file__) assert os.path.exists(os.path.join(getcwd(), __file__)), (getcwd(), __file__)
import datetime import datetime
import base64
#Readme #Readme
@ -64,28 +65,28 @@ with open ("../../documentation/index.adoc", "w") as w:
#print ("Built /documentation/index.adoc. You still need to run /documentation/build-documentation.sh manually") #print ("Built /documentation/index.adoc. You still need to run /documentation/build-documentation.sh manually")
#print ("Built /documentation/index.adoc") #print ("Built /documentation/index.adoc")
#Documentation #Documentation
METADATA["supportedLanguages"].update({"English":""}) METADATA["supportedLanguages"].update({"English":""})
for language in METADATA["supportedLanguages"].keys(): for language in METADATA["supportedLanguages"].keys():
language = language.lower() language = language.lower()
try: try:
with open(f"{language}.adoc.template", "r") as r: with open(f"{language}.adoc.template", "r") as r:
template = r.read() template = r.read()
except: except:
continue #language not yet supported as manual continue #language not yet supported as manual
for key, value in METADATA.items(): #all strings for key, value in METADATA.items(): #all strings
if type(value) is str: if type(value) is str:
template = template.replace(f"<{key}>", value) template = template.replace(f"<{key}>", value)
if language == "english": if language == "english":
template = template.replace("<english-only-description>", "== Introduction\n\n" + METADATA["description"]) template = template.replace("<english-only-description>", "== Introduction\n\n" + METADATA["description"])
with open (f"../../documentation/{language}.part.adoc", "r") as clientPart:
with open (f"../../documentation/{language}.part.adoc", "r") as clientPart:
template = template.replace("<manual>", clientPart.read()) template = template.replace("<manual>", clientPart.read())
with open (f"../../documentation/{language}.adoc", "w") as w: with open (f"../../documentation/{language}.adoc", "w") as w:
@ -115,11 +116,11 @@ settings and save directories.
Other modes of operations, mostly for testing, are: Other modes of operations, mostly for testing, are:
Run without session management and save in /tmp. Run without session management and save in /tmp.
{METADATA["shortName"]} --save /tmp {METADATA["shortName"]} --save /tmp
Run without audio and midi. Skips all JACK checks. Used to just look at the GUI, e.g. to make screenshots Run without audio and midi. Skips all JACK checks. Used to just look at the GUI, e.g. to make screenshots
{METADATA["shortName"]} --mute {METADATA["shortName"]} --mute
[see also] [see also]
The full documentation for {METADATA["name"]} is maintained as a multi-lingual html site to your systems doc-dir. The full documentation for {METADATA["name"]} is maintained as a multi-lingual html site to your systems doc-dir.
@ -136,5 +137,21 @@ command = f"help2man ../../{METADATA['shortName']} --no-info --include ../../doc
subprocess.run(command, capture_output=True, text=True, shell=True) subprocess.run(command, capture_output=True, text=True, shell=True)
#Convert 32x32 and 128x128 icons to base64 utf8 strings for jack metadata
txt_icon_32_base64_utf8 = os.path.join("../../engine/resources/", "icon_32_base64_utf8.txt")
with open (txt_icon_32_base64_utf8, "w") as icon32txt:
with open("../../desktop/images/32x32.png", "rb") as icon32png:
icon32txt.write(base64.b64encode(icon32png.read()).decode('utf-8'))
txt_icon_128_base64_utf8 = os.path.join("../../engine/resources/", "icon_128_base64_utf8.txt")
with open (txt_icon_128_base64_utf8, "w") as icon128txt:
with open("../../desktop/images/128x128.png", "rb") as icon128png:
icon128txt.write(base64.b64encode(icon128png.read()).decode('utf-8'))
#Done. Tell the world:
#print ("Built /documentation. You still need to run /documentation/build-documentation.sh manually") #print ("Built /documentation. You still need to run /documentation/build-documentation.sh manually")
print ("Built template part of documentation.") print ("Built template part of documentation.")

31
template/engine/session.py

@ -1,4 +1,4 @@
#! /usr/bin/env python3 #/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" """
Copyright 2021, Nils Hilbricht, Germany ( https://www.hilbricht.net ) Copyright 2021, Nils Hilbricht, Germany ( https://www.hilbricht.net )
@ -27,6 +27,7 @@ import os.path
import json import json
import atexit import atexit
from sys import exit as sysexit from sys import exit as sysexit
import base64 #for jack metadata icon
#Third Party Modules #Third Party Modules
from calfbox import cbox from calfbox import cbox
@ -34,6 +35,7 @@ from calfbox import cbox
#Our Template Modules #Our Template Modules
from .history import History from .history import History
from .duration import DB, DL, D1, D2, D4, D8, D16, D32, D64, D128, MAXIMUM_TICK_DURATION from .duration import DB, DL, D1, D2, D4, D8, D16, D32, D64, D128, MAXIMUM_TICK_DURATION
from ..start import PATHS
#User Data #User Data
from engine.config import * from engine.config import *
@ -114,6 +116,9 @@ class Session(object):
logger.error("Will not load or save because: " + e.__repr__()) logger.error("Will not load or save because: " + e.__repr__())
if not self.data: if not self.data:
self.data = Data(parentSession = self) self.data = Data(parentSession = self)
self.sendJackMetadataIcon()
logger.info("New/Open session complete") logger.info("New/Open session complete")
def openFromJson(self, absoluteJsonFilePath): def openFromJson(self, absoluteJsonFilePath):
@ -183,3 +188,27 @@ class Session(object):
logger.info("@atexit: Calfbox Audio stopped ") logger.info("@atexit: Calfbox Audio stopped ")
cbox.shutdown_engine() cbox.shutdown_engine()
logger.info("@atexit: Calfbox Engine shutdown ") logger.info("@atexit: Calfbox Engine shutdown ")
def sendJackMetadataIcon(self):
"""Convert our icon to base64 UTF-8 and send it to jack metadata.
Actually, the icon is already encoded in our codebase so we don't have to locate the file
on the users disk when installed
Sent once at the end of self.nsm_openOrNewCallback
"""
#testData = "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAAAAABWESUoAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAAAgcAAAIHASw6dZwAAAAHdElNRQfkBBEHMwXdauI0AAABrElEQVQ4y4XTv0vbQRzG8fc3Jv5WqqUKRvjaaKE6pE5RBFHBdlIQSp3yB3QouDh0q05K0UUzuZQMLdh/wFKhKEIERR1EOwlVxGhaUyqRSox5HBI1F5N423Gv4z6fu+fgwaGsEXqaObsPTtx2QXDVT21B8IEq/hQA3x1NY4QygcMoOOx3fX3Ej7xdJPqYVRBf3iPGGZa2sLbzgKWiZ2fSZTn+3CDiLtmQpCGK1nOB5CAzkqRF8MZzgI8MJVOyAybug1WXHZUkxffmoexnNvhnu0KS9PddNQC+RBYYYVKSfnmsDv/rJ8CcCY5LfFeS/nvbdiVdjEJT0gDTLEjSVMVRamMPrBjgVWVCkpobWgd2JCkAIwZw90rSPkDjuaQ96DRe87cNEAY43AQaLQ5TK2lgxQBanIDVABTXEDWAOwLweNIBbz0AcZxGHt6UnkmStma+SZLC0GwU+YlZI3qfYdAAsZr600zQDQHzqqd4eX63HoSKsAkuu+m6jftaGbzPfu7j59ROpCr9Ug3tsTSwULqbyPAyTu8L18XSAdSt2ekLyshkIlB/07rnNtcPf/5rhItvET2iDPMAAAAldEVYdGRhdGU6Y3JlYXRlADIwMjAtMDQtMTdUMDc6NTE6MDUrMDA6MDAudbalAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIwLTA0LTE3VDA3OjUxOjA1KzAwOjAwXygOGQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAAASUVORK5CYII="
logger.info("Sending program icons to jack metadata")
icon_32_base64_utf8 = os.path.join(PATHS["share"], "icon_32_base64_utf8.txt")
assert os.path.exists(icon_32_base64_utf8), icon_32_base64_utf8
with open(icon_32_base64_utf8, "r") as fSmall:
cbox.JackIO.Metadata.set_icon_small(fSmall.read())
icon_128_base64_utf8 = os.path.join(PATHS["share"], "icon_128_base64_utf8.txt")
assert os.path.exists(icon_128_base64_utf8), icon_128_base64_utf8
with open(icon_128_base64_utf8, "r") as fLarge:
cbox.JackIO.Metadata.set_icon_large(fLarge.read())
cbox.JackIO.Metadata.set_icon_name(METADATA["shortName"])

8
template/start.py

@ -50,11 +50,11 @@ parser.add_argument("-V", "--verbose", action='store_true', help="(Development)
args = parser.parse_args() args = parser.parse_args()
import logging import logging
if args.verbose: if args.verbose: #development
logging.basicConfig(level=logging.INFO) #development logging.basicConfig(level=logging.INFO, format='[' + METADATA["shortName"] + '] %(levelname)s %(asctime)s %(name)s: %(message)s',)
#logging.getLogger().setLevel(logging.INFO) #development #logging.getLogger().setLevel(logging.INFO) #development
else: else: #production
logging.basicConfig(level=logging.ERROR) #production logging.basicConfig(level=logging.ERROR, format='[' + METADATA["shortName"] + '] %(levelname)s %(asctime)s %(name)s: %(message)s',)
#logging.getLogger().setLevel(logging.ERROR) #production #logging.getLogger().setLevel(logging.ERROR) #production
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)

Loading…
Cancel
Save