pyDiffTools 0.1.8__py3-none-any.whl

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.
@@ -0,0 +1,168 @@
1
+ import subprocess
2
+ import time
3
+ import shutil
4
+ from pathlib import Path
5
+ from watchdog.events import FileSystemEventHandler
6
+ from watchdog.observers import Observer
7
+ from pydifftools.command_registry import register_command
8
+ from .graph import write_dot_from_yaml
9
+
10
+
11
+ def _reload_svg(driver, svg_file: Path) -> None:
12
+ """Refresh the embedded SVG while preserving zoom and scroll."""
13
+ zoom = driver.execute_script("return window.visualViewport.scale")
14
+ scroll_x = driver.execute_script("return window.scrollX")
15
+ scroll_y = driver.execute_script("return window.scrollY")
16
+ svg_uri = svg_file.resolve().as_uri() + f"?t={time.time()}"
17
+ driver.execute_async_script(
18
+ "const [src,z,x,y,done]=arguments;const"
19
+ " s=document.getElementById('svg-view');s.onload=function()"
20
+ "{document.body.style.zoom=z;"
21
+ " window.scrollTo(x,y); done();};s.setAttribute('src', src);",
22
+ svg_uri,
23
+ zoom,
24
+ scroll_x,
25
+ scroll_y,
26
+ )
27
+
28
+
29
+ def build_graph(
30
+ yaml_file,
31
+ dot_file,
32
+ svg_file,
33
+ wrap_width,
34
+ order_by_date=False,
35
+ prev_data=None,
36
+ ):
37
+ # Graphviz is required for dot -> svg rendering.
38
+ if shutil.which("dot") is None:
39
+ raise RuntimeError(
40
+ "Graphviz is required to render flowcharts. Install it so the"
41
+ " 'dot' executable is available on your PATH."
42
+ )
43
+ data = write_dot_from_yaml(
44
+ str(yaml_file),
45
+ str(dot_file),
46
+ wrap_width=wrap_width,
47
+ order_by_date=order_by_date,
48
+ old_data=prev_data,
49
+ validate_due_dates=True,
50
+ )
51
+ subprocess.run(
52
+ ["dot", "-Tsvg", str(dot_file), "-o", str(svg_file)],
53
+ check=True,
54
+ )
55
+ return data
56
+
57
+
58
+ class GraphEventHandler(FileSystemEventHandler):
59
+ def __init__(
60
+ self,
61
+ yaml_file,
62
+ dot_file,
63
+ svg_file,
64
+ driver,
65
+ wrap_width,
66
+ data,
67
+ order_by_date=False,
68
+ debounce=0.25,
69
+ ):
70
+ self.yaml_file = Path(yaml_file)
71
+ self.dot_file = Path(dot_file)
72
+ self.svg_file = Path(svg_file)
73
+ self.driver = driver
74
+ self.wrap_width = wrap_width
75
+ self.data = data
76
+ self.order_by_date = order_by_date
77
+ self.debounce = debounce
78
+ self._last_handled = 0.0
79
+ self._last_mtime = None
80
+
81
+ def on_modified(self, event):
82
+ if Path(event.src_path) == self.yaml_file:
83
+ mtime = self.yaml_file.stat().st_mtime
84
+ if self._last_mtime is not None and mtime == self._last_mtime:
85
+ return
86
+ now = time.time()
87
+ if now - self._last_handled < self.debounce:
88
+ return
89
+ self._last_handled = now
90
+ self.data = build_graph(
91
+ self.yaml_file,
92
+ self.dot_file,
93
+ self.svg_file,
94
+ self.wrap_width,
95
+ self.order_by_date,
96
+ self.data,
97
+ )
98
+ _reload_svg(self.driver, self.svg_file)
99
+ self._last_mtime = self.yaml_file.stat().st_mtime
100
+
101
+
102
+ @register_command(
103
+ "Watch a flowchart YAML file, rebuild DOT/SVG output, and open the"
104
+ " preview",
105
+ help={
106
+ "yaml": "Path to the flowchart YAML file",
107
+ "wrap_width": "Line wrap width used when generating node labels",
108
+ "d": "Render nodes by date without showing connections",
109
+ },
110
+ )
111
+ def wgrph(yaml, wrap_width=55, d=False):
112
+ # Selenium is only required when actually launching the watcher, so it is
113
+ # imported here to avoid breaking the command-line tools when the optional
114
+ # dependency is not installed.
115
+ try:
116
+ from selenium import webdriver
117
+ from selenium.webdriver.chrome.options import Options
118
+ from selenium.common.exceptions import (
119
+ WebDriverException,
120
+ NoSuchWindowException,
121
+ )
122
+ except ImportError as exc:
123
+ raise ImportError(
124
+ "The 'watch_graph' command requires the 'selenium' package to be"
125
+ " installed."
126
+ ) from exc
127
+
128
+ yaml_file = Path(yaml)
129
+ if not yaml_file.exists():
130
+ raise FileNotFoundError(f"YAML file not found: {yaml_file}")
131
+
132
+ dot_file = yaml_file.with_suffix(".dot")
133
+ svg_file = yaml_file.with_suffix(".svg")
134
+ html_file = yaml_file.with_suffix(".html")
135
+
136
+ # Use date ordering when requested so boxes appear in calendar order.
137
+ data = build_graph(yaml_file, dot_file, svg_file, wrap_width, d)
138
+ html_file.write_text(
139
+ "<html><body style='margin:0'><embed id='svg-view'"
140
+ " type='image/svg+xml'"
141
+ f" src='{svg_file.name}?t={time.time()}'/></body></html>"
142
+ )
143
+ options = Options()
144
+ driver = webdriver.Chrome(options=options)
145
+ driver.get(html_file.resolve().as_uri())
146
+ event_handler = GraphEventHandler(
147
+ yaml_file, dot_file, svg_file, driver, wrap_width, data, d
148
+ )
149
+ observer = Observer()
150
+ observer.schedule(event_handler, yaml_file.parent, recursive=False)
151
+ observer.start()
152
+ try:
153
+ while True:
154
+ try:
155
+ _ = driver.window_handles
156
+ driver.execute_script("return 1")
157
+ except (NoSuchWindowException, WebDriverException):
158
+ break
159
+ time.sleep(1)
160
+ except KeyboardInterrupt:
161
+ pass
162
+ finally:
163
+ observer.stop()
164
+ observer.join()
165
+ try:
166
+ driver.quit()
167
+ except Exception:
168
+ pass
@@ -0,0 +1,33 @@
1
+ # again rerun
2
+ from lxml import html, etree
3
+ import os
4
+ from pyspecdata.fornotebook import *
5
+ from pyspecdata import *
6
+ import re
7
+
8
+ fp = open(sys.argv[1], "r")
9
+ content = fp.read()
10
+ fp.close()
11
+ doc = html.fromstring(content)
12
+ commentlabel_re = re.compile(r"\[([A-Z]+)([0-9])\]")
13
+ comment_dict = {}
14
+ # for j in doc.xpath('descendant::*[@style="mso-element:comment"]'):
15
+ newlist = []
16
+ thisbody = doc.find("body")
17
+ print("I found the body", lsafen(thisbody))
18
+ commentlist = etree.Element("div", style="mso-element:comment-list")
19
+ for j in doc.xpath('//span[@style="mso-element:comment"]'):
20
+ # for j in doc.xpath('//span[@style="mso-element:comment"]'):
21
+ # print 'found span with style:\n\n',lsafen(html.tostring(j),wrap = 60)
22
+ # if j.attrib['style'] == 'mso-element:comment':
23
+ print("found span with style:\n\n", lsafen(j.attrib, wrap=60))
24
+ newlist.append(j)
25
+ j.drop_tree()
26
+ commentlist.append(j)
27
+ thisbody.append(commentlist)
28
+ # print lsafen(map(html.tostring,newlist),wrap = 60)
29
+ newfile = re.sub(r"(.*)(\.htm.*)", r"\1_htmlcomm\2", sys.argv[1])
30
+ fp = open(newfile, "w")
31
+ content = html.tostring(doc)
32
+ fp.write(content)
33
+ fp.close()