sphinxcontrib-screenshot 0.2.0__py3-none-any.whl → 0.2.2__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.
Potentially problematic release.
This version of sphinxcontrib-screenshot might be problematic. Click here for more details.
- sphinxcontrib/screenshot.py +97 -24
- {sphinxcontrib_screenshot-0.2.0.dist-info → sphinxcontrib_screenshot-0.2.2.dist-info}/METADATA +1 -1
- sphinxcontrib_screenshot-0.2.2.dist-info/RECORD +6 -0
- sphinxcontrib_screenshot-0.2.0.dist-info/RECORD +0 -6
- {sphinxcontrib_screenshot-0.2.0.dist-info → sphinxcontrib_screenshot-0.2.2.dist-info}/LICENSE +0 -0
- {sphinxcontrib_screenshot-0.2.0.dist-info → sphinxcontrib_screenshot-0.2.2.dist-info}/WHEEL +0 -0
- {sphinxcontrib_screenshot-0.2.0.dist-info → sphinxcontrib_screenshot-0.2.2.dist-info}/top_level.txt +0 -0
sphinxcontrib/screenshot.py
CHANGED
|
@@ -40,6 +40,9 @@ Meta = typing.TypedDict('Meta', {
|
|
|
40
40
|
'parallel_write_safe': bool
|
|
41
41
|
})
|
|
42
42
|
|
|
43
|
+
ContextBuilder = typing.Optional[typing.Callable[[Browser, str, str],
|
|
44
|
+
BrowserContext]]
|
|
45
|
+
|
|
43
46
|
|
|
44
47
|
class ScreenshotDirective(SphinxDirective, Figure):
|
|
45
48
|
"""Sphinx Screenshot Dirctive.
|
|
@@ -79,6 +82,24 @@ class ScreenshotDirective(SphinxDirective, Figure):
|
|
|
79
82
|
.. screenshot:: http://www.example.com
|
|
80
83
|
:pdf:
|
|
81
84
|
```
|
|
85
|
+
|
|
86
|
+
You can take a screenshot of a local file using a root-relative path.
|
|
87
|
+
|
|
88
|
+
```rst
|
|
89
|
+
.. screenshot:: /static/example.html
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Or you can use a document-relative path.
|
|
93
|
+
|
|
94
|
+
```rst
|
|
95
|
+
.. screenshot:: ./example.html
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The `file://` protocol is also supported.
|
|
99
|
+
|
|
100
|
+
```rst
|
|
101
|
+
.. screenshot:: file:///path/to/your/file.html
|
|
102
|
+
```
|
|
82
103
|
"""
|
|
83
104
|
|
|
84
105
|
required_arguments = 1 # URL
|
|
@@ -93,21 +114,25 @@ class ScreenshotDirective(SphinxDirective, Figure):
|
|
|
93
114
|
'full-page': directives.flag,
|
|
94
115
|
'context': str,
|
|
95
116
|
'headers': directives.unchanged,
|
|
117
|
+
'locale': str,
|
|
118
|
+
'timezone': str,
|
|
119
|
+
'device-scale-factor': directives.positive_int,
|
|
96
120
|
}
|
|
97
121
|
pool = ThreadPoolExecutor()
|
|
98
122
|
|
|
99
123
|
@staticmethod
|
|
100
|
-
def take_screenshot(
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
124
|
+
def take_screenshot(url: str, browser_name: str, viewport_width: int,
|
|
125
|
+
viewport_height: int, filepath: str, init_script: str,
|
|
126
|
+
interactions: str, generate_pdf: bool,
|
|
127
|
+
color_scheme: ColorScheme, full_page: bool,
|
|
128
|
+
context_builder: ContextBuilder, headers: dict,
|
|
129
|
+
device_scale_factor: int, locale: typing.Optional[str],
|
|
130
|
+
timezone: typing.Optional[str]):
|
|
107
131
|
"""Takes a screenshot with Playwright's Chromium browser.
|
|
108
132
|
|
|
109
133
|
Args:
|
|
110
134
|
url (str): The HTTP/HTTPS URL of the webpage to screenshot.
|
|
135
|
+
browser_name (str): Browser to use ('chromium', 'firefox' or 'webkit').
|
|
111
136
|
viewport_width (int): The width of the screenshot in pixels.
|
|
112
137
|
viewport_height (int): The height of the screenshot in pixels.
|
|
113
138
|
filepath (str): The path to save the screenshot to.
|
|
@@ -118,10 +143,16 @@ class ScreenshotDirective(SphinxDirective, Figure):
|
|
|
118
143
|
after the page was loaded.
|
|
119
144
|
generate_pdf (bool): Generate a PDF file along with the screenshot.
|
|
120
145
|
color_scheme (str): The preferred color scheme. Can be 'light' or 'dark'.
|
|
146
|
+
full_page (bool): Take a full page screenshot.
|
|
121
147
|
context: A method to build the Playwright context.
|
|
148
|
+
headers (dict): Custom request header.
|
|
149
|
+
device_scale_factor (int): The device scale factor for the screenshot.
|
|
150
|
+
This can be thought of as DPR (device pixel ratio).
|
|
151
|
+
locale (str, optional): User locale for the request.
|
|
152
|
+
timezone (str, optional): User timezone for the request.
|
|
122
153
|
"""
|
|
123
154
|
with sync_playwright() as playwright:
|
|
124
|
-
browser = getattr(playwright, browser_name).launch()
|
|
155
|
+
browser: Browser = getattr(playwright, browser_name).launch()
|
|
125
156
|
|
|
126
157
|
if context_builder:
|
|
127
158
|
try:
|
|
@@ -131,7 +162,11 @@ class ScreenshotDirective(SphinxDirective, Figure):
|
|
|
131
162
|
'Timeout error occured at %s in executing py init script %s' %
|
|
132
163
|
(url, context_builder.__name__))
|
|
133
164
|
else:
|
|
134
|
-
context = browser.new_context(
|
|
165
|
+
context = browser.new_context(
|
|
166
|
+
color_scheme=color_scheme,
|
|
167
|
+
locale=locale,
|
|
168
|
+
timezone_id=timezone,
|
|
169
|
+
device_scale_factor=device_scale_factor)
|
|
135
170
|
|
|
136
171
|
page = context.new_page()
|
|
137
172
|
page.set_default_timeout(10000)
|
|
@@ -173,14 +208,33 @@ class ScreenshotDirective(SphinxDirective, Figure):
|
|
|
173
208
|
|
|
174
209
|
def run(self) -> typing.Sequence[nodes.Node]:
|
|
175
210
|
screenshot_init_script: str = self.env.config.screenshot_init_script or ''
|
|
211
|
+
docdir = os.path.dirname(self.env.doc2path(self.env.docname))
|
|
176
212
|
|
|
177
213
|
# Ensure the screenshots directory exists
|
|
178
214
|
ss_dirpath = os.path.join(self.env.app.outdir, '_static', 'screenshots')
|
|
179
215
|
os.makedirs(ss_dirpath, exist_ok=True)
|
|
180
216
|
|
|
181
217
|
# Parse parameters
|
|
182
|
-
|
|
183
|
-
|
|
218
|
+
raw_path = self.arguments[0]
|
|
219
|
+
url_or_filepath = self.evaluate_substitutions(raw_path)
|
|
220
|
+
|
|
221
|
+
# Check if the path is a local file path.
|
|
222
|
+
if urlparse(url_or_filepath).scheme == '':
|
|
223
|
+
# root-relative path
|
|
224
|
+
if url_or_filepath.startswith('/'):
|
|
225
|
+
url_or_filepath = os.path.join(self.env.srcdir,
|
|
226
|
+
url_or_filepath.lstrip('/'))
|
|
227
|
+
# document-relative path
|
|
228
|
+
else:
|
|
229
|
+
url_or_filepath = os.path.join(docdir, url_or_filepath)
|
|
230
|
+
url_or_filepath = "file://" + os.path.normpath(url_or_filepath)
|
|
231
|
+
|
|
232
|
+
if urlparse(url_or_filepath).scheme not in {'http', 'https', 'file'}:
|
|
233
|
+
raise RuntimeError(
|
|
234
|
+
f'Invalid URL: {url_or_filepath}. ' +
|
|
235
|
+
'Only HTTP/HTTPS/FILE URLs or root/document-relative file paths ' +
|
|
236
|
+
'are supported.')
|
|
237
|
+
|
|
184
238
|
interactions = self.options.get('interactions', '')
|
|
185
239
|
browser = self.options.get('browser',
|
|
186
240
|
self.env.config.screenshot_default_browser)
|
|
@@ -193,25 +247,28 @@ class ScreenshotDirective(SphinxDirective, Figure):
|
|
|
193
247
|
pdf = 'pdf' in self.options
|
|
194
248
|
full_page = ('full-page' in self.options or
|
|
195
249
|
self.env.config.screenshot_default_full_page)
|
|
250
|
+
locale = self.options.get('locale',
|
|
251
|
+
self.env.config.screenshot_default_locale)
|
|
252
|
+
timezone = self.options.get('timezone',
|
|
253
|
+
self.env.config.screenshot_default_timezone)
|
|
196
254
|
context = self.options.get('context', '')
|
|
197
255
|
headers = self.options.get('headers', '')
|
|
198
|
-
|
|
256
|
+
device_scale_factor = self.options.get(
|
|
257
|
+
'device-scale-factor',
|
|
258
|
+
self.env.config.screenshot_default_device_scale_factor)
|
|
199
259
|
request_headers = {**self.env.config.screenshot_default_headers}
|
|
200
260
|
if headers:
|
|
201
261
|
for header in headers.strip().split("\n"):
|
|
202
262
|
name, value = header.split(" ", 1)
|
|
203
263
|
request_headers[name] = value
|
|
204
264
|
|
|
205
|
-
if urlparse(url).scheme not in {'http', 'https'}:
|
|
206
|
-
raise RuntimeError(
|
|
207
|
-
f'Invalid URL: {url}. Only HTTP/HTTPS URLs are supported.')
|
|
208
|
-
|
|
209
265
|
# Generate filename based on hash of parameters
|
|
210
266
|
hash_input = "_".join([
|
|
211
|
-
|
|
267
|
+
raw_path, browser,
|
|
212
268
|
str(viewport_height),
|
|
213
269
|
str(viewport_width), color_scheme, context, interactions,
|
|
214
|
-
str(full_page)
|
|
270
|
+
str(full_page),
|
|
271
|
+
str(device_scale_factor)
|
|
215
272
|
])
|
|
216
273
|
filename = hashlib.md5(hash_input.encode()).hexdigest() + '.png'
|
|
217
274
|
filepath = os.path.join(ss_dirpath, filename)
|
|
@@ -224,15 +281,15 @@ class ScreenshotDirective(SphinxDirective, Figure):
|
|
|
224
281
|
|
|
225
282
|
# Check if the file already exists. If not, take a screenshot
|
|
226
283
|
if not os.path.exists(filepath):
|
|
227
|
-
fut = self.pool.submit(ScreenshotDirective.take_screenshot,
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
color_scheme, full_page,
|
|
231
|
-
request_headers
|
|
284
|
+
fut = self.pool.submit(ScreenshotDirective.take_screenshot,
|
|
285
|
+
url_or_filepath, browser, viewport_width,
|
|
286
|
+
viewport_height, filepath, screenshot_init_script,
|
|
287
|
+
interactions, pdf, color_scheme, full_page,
|
|
288
|
+
context_builder, request_headers,
|
|
289
|
+
device_scale_factor, locale, timezone)
|
|
232
290
|
fut.result()
|
|
233
291
|
|
|
234
292
|
# Create image and figure nodes
|
|
235
|
-
docdir = os.path.dirname(self.env.doc2path(self.env.docname))
|
|
236
293
|
rel_ss_dirpath = os.path.relpath(ss_dirpath, start=docdir)
|
|
237
294
|
rel_filepath = os.path.join(rel_ss_dirpath, filename).replace(os.sep, '/')
|
|
238
295
|
|
|
@@ -311,6 +368,22 @@ def setup(app: Sphinx) -> Meta:
|
|
|
311
368
|
'screenshot_default_headers', {},
|
|
312
369
|
'env',
|
|
313
370
|
description="The default headers to pass in requests")
|
|
371
|
+
app.add_config_value(
|
|
372
|
+
'screenshot_default_device_scale_factor',
|
|
373
|
+
1,
|
|
374
|
+
'env',
|
|
375
|
+
description="The default device scale factor " +
|
|
376
|
+
"a.k.a. DPR (device pixel ratio)")
|
|
377
|
+
app.add_config_value(
|
|
378
|
+
'screenshot_default_locale',
|
|
379
|
+
None,
|
|
380
|
+
'env',
|
|
381
|
+
description="The default locale in requests")
|
|
382
|
+
app.add_config_value(
|
|
383
|
+
'screenshot_default_timezone',
|
|
384
|
+
None,
|
|
385
|
+
'env',
|
|
386
|
+
description="The default timezone in requests")
|
|
314
387
|
app.add_config_value(
|
|
315
388
|
'screenshot_apps', {},
|
|
316
389
|
'env',
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
sphinxcontrib/screenshot.py,sha256=Kb4oC4w-fv9qBYi251u5WeN_xvSLjwv0k3Ybs0R8xi4,14096
|
|
2
|
+
sphinxcontrib_screenshot-0.2.2.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
3
|
+
sphinxcontrib_screenshot-0.2.2.dist-info/METADATA,sha256=S52Ju_7SvfeT5xDFia9m7ABh1f1egPSRMTVrey6ivok,2868
|
|
4
|
+
sphinxcontrib_screenshot-0.2.2.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
5
|
+
sphinxcontrib_screenshot-0.2.2.dist-info/top_level.txt,sha256=VJrV3_vaiKQVgVpR0I1iecxoO0drzGu-M0j40PVP2QQ,14
|
|
6
|
+
sphinxcontrib_screenshot-0.2.2.dist-info/RECORD,,
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
sphinxcontrib/screenshot.py,sha256=03cVsF1d9zuWMsVBwtZU_EQ_GMMsYyPa2a3vBmzC4f8,11342
|
|
2
|
-
sphinxcontrib_screenshot-0.2.0.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
3
|
-
sphinxcontrib_screenshot-0.2.0.dist-info/METADATA,sha256=pwaSBQlzvflzW2BSv7ByJ8GvbwDrYF0xn8bftw3dPC0,2868
|
|
4
|
-
sphinxcontrib_screenshot-0.2.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
5
|
-
sphinxcontrib_screenshot-0.2.0.dist-info/top_level.txt,sha256=VJrV3_vaiKQVgVpR0I1iecxoO0drzGu-M0j40PVP2QQ,14
|
|
6
|
-
sphinxcontrib_screenshot-0.2.0.dist-info/RECORD,,
|
{sphinxcontrib_screenshot-0.2.0.dist-info → sphinxcontrib_screenshot-0.2.2.dist-info}/LICENSE
RENAMED
|
File without changes
|
|
File without changes
|
{sphinxcontrib_screenshot-0.2.0.dist-info → sphinxcontrib_screenshot-0.2.2.dist-info}/top_level.txt
RENAMED
|
File without changes
|