Skip to content

Commit

Permalink
Move the schemas
Browse files Browse the repository at this point in the history
  • Loading branch information
mmouchous-ledger committed Jan 17, 2025
1 parent 88bf59f commit 4df270f
Show file tree
Hide file tree
Showing 16 changed files with 194 additions and 168 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -159,4 +159,4 @@ cython_debug/
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
#.idea/
2 changes: 1 addition & 1 deletion docs/conf_file.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ laserstudio_generate_config
Here is an example of a configuration file:

```yaml
# yaml-language-server: $schema=https://raw.githubusercontent.com/Ledger-Donjon/laserstudio/main/config_schema/config.schema.json
# yaml-language-server: $schema=https://raw.githubusercontent.com/Ledger-Donjon/laserstudio/main/laserstudio/config_schema/config.schema.json
camera:
enable: true
label: "NIT IR Camera"
Expand Down
7 changes: 4 additions & 3 deletions laserstudio/config_generator/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from .config_generator import main
from .config_generator import main as main_cli
from .config_generator_wizard import main as main_gui
from .config_generator import ConfigGenerator
from .config_generator_ui import ConfigGeneratorWizard
from .config_generator_wizard import ConfigGeneratorWizard

__all__ = ["main", "ConfigGenerator", "ConfigGeneratorWizard"]
__all__ = ["main_cli", "main_gui", "ConfigGenerator", "ConfigGeneratorWizard"]
17 changes: 8 additions & 9 deletions laserstudio/config_generator/config_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ class ConfigGenerator:
def __init__(
self,
schema_uri="config.schema.json",
base_url="https://raw.githubusercontent.com/Ledger-Donjon/laserstudio/main/config_schema/",
base_url="https://raw.githubusercontent.com/Ledger-Donjon/laserstudio/main/laserstudio/config_schema/",
):
self.schema_uri = schema_uri
self.base_url = base_url
self.logger = logging.getLogger("Config Generator")
self.use_local = True
colorama_init()

@staticmethod
Expand Down Expand Up @@ -548,18 +549,16 @@ def get_flags(self):

# Check if -L flag is present for retrieve schema from local directory
if "-L" in sys.argv:
__dirname = os.path.dirname(
os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
)
self.base_url = os.path.join(__dirname, "config_schema")
__dirname = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
self.use_local = True

def load_schema(self):
def load_schema(self, local=True):
# Fetch the JSON schema from the URL
if self.use_local:
__dirname = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
self.base_url = os.path.join(__dirname, "config_schema")
set_base_url(self.base_url)
print("Loading schemas... ", end="")
sys.stdout.flush()
schema = resolve_references(self.schema_uri)
print("done.")
self.logger.info("Schema loaded successfully")
self.logger.debug(json.dumps(schema, indent=2))
self.schema = schema
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
#!/usr/bin/python3
from PyQt6.QtCore import Qt, QRegularExpression
from PyQt6.QtGui import QRegularExpressionValidator
from PyQt6.QtWidgets import QButtonGroup
from typing import Optional, Union
from PyQt6.QtWidgets import (
QWizardPage,
QWizard,
QVBoxLayout,
QPushButton,
QHBoxLayout,
QWidget,
QLabel,
QScrollArea,
QSpinBox,
QDoubleSpinBox,
QCheckBox,
Expand All @@ -23,48 +16,11 @@
QAbstractButton,
QStackedWidget,
QRadioButton,
QButtonGroup,
)
import sys
import yaml

try:
from .ref_resolve import set_base_url
from .config_generator import ConfigGenerator, validate, ValidationError
from ..utils.colors import LedgerPalette, LedgerStyle
except ImportError:
from laserstudio.config_generator.ref_resolve import set_base_url
from laserstudio.config_generator.config_generator import (
ConfigGenerator,
validate,
ValidationError,
)
from laserstudio.utils.colors import LedgerPalette, LedgerStyle

from PyQt6.QtWidgets import QApplication


class ConfigGeneratorWizard(QWizard):
def __init__(self, schema: dict, parent=None):
super().__init__(parent)
self.setWindowTitle("Configuration File Generator")
self.setWizardStyle(QWizard.WizardStyle.ModernStyle)

# Initiate the presentation/introduction page
self.addPage(ConfigGeneratorIntroductionPage(self))

self.schema = schema
# To be more readable, we will create a page for each top-property of the schema
self.config_generation_pages = list[ConfigPresentationPage]()
top_properties = schema.get("properties", {})
for key, subschema in top_properties.items():
self.config_generation_pages.append(
ConfigPresentationPage(self, key, subschema)
)
[self.addPage(p) for p in self.config_generation_pages]

# Add the result page
self.config_result_page = ConfigResultPage(self)
self.addPage(self.config_result_page)
from PyQt6.QtGui import QRegularExpressionValidator
from jsonschema import validate, ValidationError
from typing import Optional, Union


class AnyOf:
Expand Down Expand Up @@ -571,98 +527,3 @@ def validate(self):
error = QErrorMessage()
error.showMessage(f"Error on validation of {e.json_path[2:]}: {e.message}")
return True


class ConfigGeneratorIntroductionPage(QWizardPage):
def __init__(self, parent: "ConfigGeneratorWizard"):
super().__init__(parent)
self.setTitle("Introduction")
self.setSubTitle(
"This wizard will help you generate a Configuration File for Laser Studio"
)
layout = QVBoxLayout()
self.setLayout(layout)
label = QLabel(
"<p>For each page of the generator, fill the properties of the instruments with the desired values.</p>"
"<p>You can make optional properties not to be added in the file by unchecking the checkbox next to the field name.</p>"
"<p>If you need an information about a property, hover the cursor over its name to see the description.</p>"
"<p>At the end the Configuration File will be shown for you and you can save it.</p>"
"<p>Get more details about the schema in <a href='https://laserstudio.readthedocs.io/en/latest/'>the documentation</a>.</p>"
)
label.setTextFormat(Qt.TextFormat.RichText)
label.setWordWrap(True)
label.setTextInteractionFlags(Qt.TextInteractionFlag.TextBrowserInteraction)
label.setOpenExternalLinks(True)
label.linkActivated.connect(lambda url: print(url))
layout.addWidget(label)


class ConfigResultPage(QWizardPage):
def __init__(self, parent: "ConfigGeneratorWizard"):
super().__init__(parent)
self.setTitle("Configuration File Result")
self.setSubTitle("This is the generated Configuration File")
layout = QVBoxLayout()
self.setLayout(layout)
self.result_label = QLabel()
layout.addWidget(self.result_label)
scroll = QScrollArea()
scroll.setWidgetResizable(True)

def initializePage(self):
wiz = self.wizard()
assert isinstance(wiz, ConfigGeneratorWizard)
configs = {}
for config_page in wiz.config_generation_pages:
configs[config_page.schema_widget.key] = config_page.schema_widget.json()
self.config = configs
self.result_label.setText(yaml.dump(self.config, indent=2))

def validatePage(self) -> bool:
try:
wizard = self.wizard()
assert isinstance(wizard, ConfigGeneratorWizard)
validate(self.config, wizard.schema)
print("Validation successful", self.config)
return True
except ValidationError as e:
self.setSubTitle(
f"Generated JSON is <strong>invalid</strong> for '{'.'.join([str(k) for k in e.path])}'\n"
+ e.message
)
return False


class ConfigPresentationPage(QWizardPage):
def __init__(self, parent: "ConfigGeneratorWizard", key: str, schema: dict):
super().__init__(parent)
layout = QVBoxLayout()
self.setLayout(layout)
scroll = QScrollArea()
scroll.setWidgetResizable(True)
self.schema_widget = SchemaWidget(schema, key, make_flat=True)
scroll.setWidget(self.schema_widget)
layout.addWidget(scroll)
self.setTitle(schema.get("title"))
self.setSubTitle(schema.get("description"))

def validatePage(self) -> bool:
return self.schema_widget.validate()


if __name__ == "__main__":
config_generator = ConfigGenerator()
sys.argv.append("-L")
config_generator.get_flags()
set_base_url(config_generator.base_url)
# Load all schemas
config_generator.load_schema()
SCHEMA = config_generator.schema
assert type(SCHEMA) is dict

app = QApplication(sys.argv)
app.setStyle(LedgerStyle)
app.setPalette(LedgerPalette)
wizard = ConfigGeneratorWizard(config_generator.schema)
wizard.show()
sys.exit(app.exec())
Loading

0 comments on commit 4df270f

Please sign in to comment.