PyDMConverter 1.0.2__tar.gz → 1.0.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/PKG-INFO +1 -1
  2. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/PyDMConverter.egg-info/PKG-INFO +1 -1
  3. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/PyDMConverter.egg-info/SOURCES.txt +4 -0
  4. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/docs/arguments.md +20 -0
  5. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/docs/user_guide.md +6 -1
  6. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/pydmconverter/__main__.py +16 -10
  7. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/pydmconverter/edm/converter.py +8 -4
  8. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/pydmconverter/edm/converter_helpers.py +514 -394
  9. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/pydmconverter/edm/menumux.py +4 -1
  10. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/pydmconverter/edm/parser.py +14 -13
  11. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/pydmconverter/edm/parser_helpers.py +3 -5
  12. pydmconverter-1.0.3/pydmconverter/exceptions.py +17 -0
  13. pydmconverter-1.0.3/pydmconverter/sites/__init__.py +12 -0
  14. pydmconverter-1.0.3/pydmconverter/sites/slac.py +2 -0
  15. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/pydmconverter/widgets.py +14 -4
  16. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/pydmconverter/widgets_helpers.py +24 -29
  17. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/tests/edm/test_converter.py +124 -0
  18. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/tests/edm/test_parser.py +5 -0
  19. pydmconverter-1.0.3/tests/test_sites.py +16 -0
  20. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/tests/test_widgets.py +64 -0
  21. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
  22. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/.github/ISSUE_TEMPLATE/feature-request.yml +0 -0
  23. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/.github/workflows/gh-pages.yml +0 -0
  24. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/.github/workflows/lint.yml +0 -0
  25. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/.github/workflows/pypi_release.yml +0 -0
  26. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/.github/workflows/tests.yml +0 -0
  27. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/.gitignore +0 -0
  28. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/.pre-commit-config.yaml +0 -0
  29. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/LICENSE +0 -0
  30. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/PyDMConverter.egg-info/dependency_links.txt +0 -0
  31. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/PyDMConverter.egg-info/entry_points.txt +0 -0
  32. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/PyDMConverter.egg-info/requires.txt +0 -0
  33. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/PyDMConverter.egg-info/top_level.txt +0 -0
  34. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/README.md +0 -0
  35. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/app/resources/file_minus.png +0 -0
  36. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/app/resources/file_plus.png +0 -0
  37. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/app/resources/file_x.png +0 -0
  38. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/app/resources/folder_plus.png +0 -0
  39. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/app/resources/folder_search.png +0 -0
  40. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/app/resources/play_circle_outline.png +0 -0
  41. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/app/resources/settings.png +0 -0
  42. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/app/src/model/__init__.py +0 -0
  43. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/app/src/model/app_model.py +0 -0
  44. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/app/src/model/options_model.py +0 -0
  45. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/app/src/view/__init__.py +0 -0
  46. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/app/src/view/file_select_widget.py +0 -0
  47. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/app/src/view/main_window.py +0 -0
  48. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/app/src/view/main_window.ui +0 -0
  49. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/app/src/view/options_window.py +0 -0
  50. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/app/src/view/output_select_dialog.py +0 -0
  51. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/docs/images/pydmconverter.png +0 -0
  52. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/docs/index.md +0 -0
  53. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/docs/reference/custom_types.md +0 -0
  54. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/docs/reference/edm/converter.md +0 -0
  55. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/docs/reference/edm/converter_helpers.md +0 -0
  56. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/docs/reference/edm/menumux.md +0 -0
  57. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/docs/reference/edm/parser.md +0 -0
  58. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/docs/reference/edm/parser_helpers.md +0 -0
  59. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/docs/reference/index.md +0 -0
  60. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/docs/reference/pydm-converter-tool.md +0 -0
  61. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/docs/reference/widgets.md +0 -0
  62. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/docs/reference/widgets_helpers.md +0 -0
  63. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/environment.yml +0 -0
  64. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/examples/TEM_mapping.edl +0 -0
  65. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/examples/all_bsy0_main.edl +0 -0
  66. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/examples/all_bsy0_main_with_groups.edl +0 -0
  67. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/examples/prosilica.edl +0 -0
  68. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/mkdocs.yml +0 -0
  69. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/pydmconverter/__init__.py +0 -0
  70. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/pydmconverter/custom_types.py +0 -0
  71. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/pydmconverter/edm/__init__.py +0 -0
  72. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/pydmconverter/launch_gui.sh +0 -0
  73. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/pyproject.toml +0 -0
  74. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/setup.cfg +0 -0
  75. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/tests/__init__.py +0 -0
  76. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/tests/edm/test_converter_helpers.py +0 -0
  77. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/tests/edm/test_parser_helpers.py +0 -0
  78. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/tests/test_main.py +0 -0
  79. {pydmconverter-1.0.2 → pydmconverter-1.0.3}/tests/test_widgets_helpers.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PyDMConverter
3
- Version: 1.0.2
3
+ Version: 1.0.3
4
4
  Summary: converter to generate pydm .ui files from other display managers.
5
5
  Author: Devan Agrawal, Zach Domke, Ryan McClanahan, Alexander Ng, Logan Somoza, Alexandria Ikuma
6
6
  Author-email: Yekta Yazar <yazar@slac.stanford.edu>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PyDMConverter
3
- Version: 1.0.2
3
+ Version: 1.0.3
4
4
  Summary: converter to generate pydm .ui files from other display managers.
5
5
  Author: Devan Agrawal, Zach Domke, Ryan McClanahan, Alexander Ng, Logan Somoza, Alexandria Ikuma
6
6
  Author-email: Yekta Yazar <yazar@slac.stanford.edu>
@@ -54,6 +54,7 @@ examples/prosilica.edl
54
54
  pydmconverter/__init__.py
55
55
  pydmconverter/__main__.py
56
56
  pydmconverter/custom_types.py
57
+ pydmconverter/exceptions.py
57
58
  pydmconverter/launch_gui.sh
58
59
  pydmconverter/widgets.py
59
60
  pydmconverter/widgets_helpers.py
@@ -63,8 +64,11 @@ pydmconverter/edm/converter_helpers.py
63
64
  pydmconverter/edm/menumux.py
64
65
  pydmconverter/edm/parser.py
65
66
  pydmconverter/edm/parser_helpers.py
67
+ pydmconverter/sites/__init__.py
68
+ pydmconverter/sites/slac.py
66
69
  tests/__init__.py
67
70
  tests/test_main.py
71
+ tests/test_sites.py
68
72
  tests/test_widgets.py
69
73
  tests/test_widgets_helpers.py
70
74
  tests/edm/test_converter.py
@@ -15,6 +15,26 @@ This argument allows users to override the output file if it already exists. Mos
15
15
 
16
16
  This argument adds scroll bars to converted screens. It will ad a horizontal and vertical scroll bar. If this argument is not included, the screen will not contain a scroll bar.
17
17
 
18
+ ## Site
19
+
20
+ `--site <name>`
21
+
22
+ This argument applies site-specific conversion rules during the conversion process. Some facilities have EDM widgets or patterns that have no equivalent in PyDM and should be skipped or handled differently. The `--site` flag lets you opt into these rules without affecting the default conversion behavior.
23
+
24
+ **Available sites:**
25
+
26
+ | Site | Rules Applied |
27
+ |--------|---------------|
28
+ | `slac` | Skips `activeExitButtonClass` (exit buttons present on every SLAC EDM screen that have no PyDM equivalent) |
29
+
30
+ **Usage:**
31
+ ``` bash
32
+ pydmconverter /path/to/file.edl output.ui --site slac
33
+ ```
34
+
35
+ **Adding a new site:**
36
+ To add conversion rules for a new site, create a new module in `pydmconverter/sites/` (e.g. `mysite.py`) that defines a `SKIP_WIDGETS` set, then register it in `pydmconverter/sites/__init__.py`.
37
+
18
38
  ## Help
19
39
 
20
40
  `-h` or `--help`
@@ -69,5 +69,10 @@ pydmconverter /afs/slac/g/lcls/edm/file.edl file.ui`
69
69
  ```
70
70
  To convert EDM files in a folder called "edm" to PYDM file in the current folder :
71
71
  ``` bash
72
- pydmconverter /afs/slac/g/lcls/edm . .edl`
72
+ pydmconverter /afs/slac/g/lcls/edm . .edl
73
+ ```
74
+
75
+ To convert with SLAC-specific rules (e.g. skipping exit buttons):
76
+ ``` bash
77
+ pydmconverter /afs/slac/g/lcls/edm/file.edl file.ui --site slac
73
78
  ```
@@ -7,7 +7,7 @@ from pydmconverter.edm.converter import convert
7
7
  from pathlib import Path
8
8
  import logging
9
9
 
10
- logging.basicConfig(level=logging.INFO)
10
+ logging.basicConfig(level=logging.WARNING)
11
11
 
12
12
 
13
13
  IMAGE_FILE_SUFFIXES = {".png", ".jpg", ".jpeg", ".gif"}
@@ -29,7 +29,7 @@ def run_gui() -> None:
29
29
  subprocess.run(["bash", str(launch_script)], check=True)
30
30
 
31
31
 
32
- def run(input_file, output_file, input_file_type=".edl", override=False, scrollable=False):
32
+ def run(input_file, output_file, input_file_type=".edl", override=False, scrollable=False, site=None):
33
33
  input_path: Path = Path(input_file)
34
34
  output_path: Path = Path(output_file)
35
35
 
@@ -39,7 +39,7 @@ def run(input_file, output_file, input_file_type=".edl", override=False, scrolla
39
39
  if output_path.is_file() and not override:
40
40
  raise FileExistsError(f"Output file '{output_path}' already exists. Use --override or -o to overwrite it.")
41
41
  copy_img_files(input_path.parent, output_path.parent)
42
- convert(str(input_path), str(output_path), scrollable)
42
+ convert(str(input_path), str(output_path), scrollable, site=site)
43
43
  else:
44
44
  if input_file_type[0] != ".": # prepending . so it will not pick up other file types with same suffix
45
45
  input_file_type = "." + input_file_type
@@ -47,7 +47,7 @@ def run(input_file, output_file, input_file_type=".edl", override=False, scrolla
47
47
  files_found: int
48
48
  files_failed: list[str]
49
49
  files_found, files_failed = convert_files_in_folder(
50
- input_path, output_path, input_file_type, override, scrollable
50
+ input_path, output_path, input_file_type, override, scrollable, site=site
51
51
  )
52
52
 
53
53
  if files_found == 0:
@@ -76,7 +76,8 @@ def run_cli(args: argparse.Namespace) -> None:
76
76
  input_file_type: str = args.output_type
77
77
  override: bool = args.override
78
78
  scrollable: bool = args.scrollable
79
- run(input_file, output_file, input_file_type, override, scrollable)
79
+ site: str = args.site
80
+ run(input_file, output_file, input_file_type, override, scrollable, site=site)
80
81
 
81
82
 
82
83
  """
@@ -98,7 +99,7 @@ def run_cli(args: argparse.Namespace) -> None:
98
99
  files_found: int
99
100
  files_failed: list[str]
100
101
  files_found, files_failed = convert_files_in_folder(
101
- input_path, output_path, input_file_type, override, scrollable
102
+ input_path, output_path, input_file_type, override, scrollable, site=site
102
103
  )
103
104
 
104
105
  if files_found == 0:
@@ -125,7 +126,7 @@ def copy_img_files(input_path: Path, output_path: Path) -> None:
125
126
 
126
127
 
127
128
  def convert_files_in_folder(
128
- input_path: Path, output_path: Path, input_file_type: str, override: bool, scrollable: bool
129
+ input_path: Path, output_path: Path, input_file_type: str, override: bool, scrollable: bool, site=None
129
130
  ) -> tuple[int, list[str]]:
130
131
  """Recursively runs convert on files in directory and subdirectories
131
132
 
@@ -161,17 +162,16 @@ def convert_files_in_folder(
161
162
  logging.warning(f"Skipped: {output_file_path} already exists. Use --override or -o to overwrite it.")
162
163
  else:
163
164
  try:
164
- convert(file, output_file_path, scrollable)
165
+ convert(file, output_file_path, scrollable, site=site)
165
166
  except Exception as e:
166
167
  files_failed.append(str(file))
167
168
  logging.warning(f"Failed to convert {file}: {e}")
168
- breakpoint()
169
169
  continue
170
170
 
171
171
  subdirectories = [item for item in input_path.iterdir() if item.is_dir()]
172
172
  for subdir in subdirectories:
173
173
  sub_found, sub_failed = convert_files_in_folder(
174
- subdir, output_path / subdir.name, input_file_type, override, scrollable
174
+ subdir, output_path / subdir.name, input_file_type, override, scrollable, site=site
175
175
  )
176
176
  files_found += sub_found
177
177
  files_failed += sub_failed
@@ -227,6 +227,12 @@ def main() -> None:
227
227
  action="store_true",
228
228
  help="create scrollable pydm windows that replicate edm windows (may cause spacing issues for embedded displays)",
229
229
  )
230
+ parser.add_argument(
231
+ "--site",
232
+ type=str,
233
+ default=None,
234
+ help="Apply site-specific conversion rules (e.g., slac)",
235
+ )
230
236
  args: argparse.Namespace = parser.parse_args()
231
237
 
232
238
  if args.input_file:
@@ -2,7 +2,7 @@ from pydmconverter.edm.parser import EDMFileParser, EDMObject
2
2
  import xml.etree.ElementTree as ET
3
3
  from pydmconverter.edm.converter_helpers import convert_edm_to_pydm_widgets
4
4
  import logging
5
- from pprint import pprint
5
+
6
6
  from pydmconverter.widgets_helpers import PageHeader
7
7
 
8
8
  logger = logging.getLogger(__name__)
@@ -50,10 +50,9 @@ CUSTOM_WIDGET_DEFINITIONS = {
50
50
  }
51
51
 
52
52
 
53
- def convert(input_path, output_path, scrollable=False):
53
+ def convert(input_path, output_path, scrollable=False, site=None):
54
54
  try:
55
55
  edm_parser = EDMFileParser(input_path, output_path)
56
- pprint(edm_parser.ui, indent=2)
57
56
  logger.info(f"Successfully parsed EDM file: {input_path}")
58
57
  except FileNotFoundError:
59
58
  logger.error("File Not Found")
@@ -61,7 +60,7 @@ def convert(input_path, output_path, scrollable=False):
61
60
 
62
61
  # edm_parser.ui, _, _ = replace_calc_and_loc_in_edm_content(edm_parser.ui, input_path)
63
62
 
64
- pydm_widgets, used_classes = convert_edm_to_pydm_widgets(edm_parser)
63
+ pydm_widgets, used_classes = convert_edm_to_pydm_widgets(edm_parser, site=site)
65
64
  logger.info(f"Converted EDM objects to {len(pydm_widgets)} PyDM widgets.")
66
65
 
67
66
  page_header = PageHeader()
@@ -87,10 +86,15 @@ def convert(input_path, output_path, scrollable=False):
87
86
  tree.write(output_path, encoding="utf-8", xml_declaration=True)
88
87
 
89
88
 
89
+ QT_BASE_CLASSES = {"QPushButton", "QTabWidget", "QFrame", "QLabel", "QWidget", "QLineEdit", "QComboBox", "QTableWidget"}
90
+
91
+
90
92
  def build_customwidgets_element(used_classes: set) -> ET.Element:
91
93
  customwidgets_el = ET.Element("customwidgets")
92
94
 
93
95
  for cls_name in sorted(used_classes):
96
+ if cls_name in QT_BASE_CLASSES:
97
+ continue
94
98
  if cls_name not in CUSTOM_WIDGET_DEFINITIONS:
95
99
  logger.warning(f"Could not find custom widget {cls_name} in CUSTOM_WIDGET_DEFINITIONS")
96
100
  continue