lacuscore 1.13.5__tar.gz → 1.13.7__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: lacuscore
3
- Version: 1.13.5
3
+ Version: 1.13.7
4
4
  Summary: Core of Lacus, usable as a module
5
5
  License: BSD-3-Clause
6
6
  Author: Raphaël Vinot
@@ -26,7 +26,7 @@ Requires-Dist: async-timeout (>=5.0.1) ; python_version < "3.11"
26
26
  Requires-Dist: defang (>=0.5.3)
27
27
  Requires-Dist: dnspython (>=2.7.0)
28
28
  Requires-Dist: eval-type-backport (>=0.2.2) ; python_version < "3.10"
29
- Requires-Dist: playwrightcapture[recaptcha] (>=1.28.2)
29
+ Requires-Dist: playwrightcapture[recaptcha] (>=1.28.3)
30
30
  Requires-Dist: pydantic (>=2.10.6)
31
31
  Requires-Dist: redis[hiredis] (>=5.2.1)
32
32
  Requires-Dist: requests (>=2.32.3)
@@ -5,6 +5,7 @@ from __future__ import annotations
5
5
  import json
6
6
  import sys
7
7
 
8
+ from datetime import datetime, timedelta
8
9
  from enum import IntEnum, unique
9
10
  from logging import LoggerAdapter
10
11
  from typing import Any, Literal
@@ -127,6 +128,7 @@ class CaptureSettings(BaseModel):
127
128
  java_script_enabled: bool = True
128
129
  viewport: dict[str, int] | None = None
129
130
  referer: str | None = None
131
+ with_screenshot: bool = True
130
132
  with_favicon: bool = True
131
133
  allow_tracking: bool = False
132
134
  headless: bool = True
@@ -218,6 +220,28 @@ class CaptureSettings(BaseModel):
218
220
  @field_validator('cookies', mode='before')
219
221
  @classmethod
220
222
  def load_cookies_json(cls, cookies: Any) -> list[dict[str, Any]] | None:
223
+
224
+ def __prepare_cookie(cookie: dict[str, Any]) -> dict[str, str | float | bool]:
225
+ if len(cookie) == 1:
226
+ # {'name': 'value'} => {'name': 'name', 'value': 'value'}
227
+ name, value = cookie.popitem()
228
+ if name and value:
229
+ cookie = {'name': name, 'value': value}
230
+ if not cookie.get('name') or not cookie.get('value'):
231
+ # invalid cookie, ignoring
232
+ return {}
233
+
234
+ if 'expires' in cookie and isinstance(cookie['expires'], str):
235
+ # Make it a float, as expected by Playwright
236
+ try:
237
+ cookie['expires'] = datetime.fromisoformat(cookie['expires']).timestamp()
238
+ except ValueError:
239
+ # if it ends with a Z, it fails in python < 3.12
240
+ # And we don't really care.
241
+ # make it expire 10 days from now
242
+ cookie['expires'] = (datetime.now() + timedelta(days=10)).timestamp()
243
+ return cookie
244
+
221
245
  if not cookies:
222
246
  return None
223
247
  if isinstance(cookies, str):
@@ -236,16 +260,7 @@ class CaptureSettings(BaseModel):
236
260
  to_return = []
237
261
  for cookie in cookies:
238
262
  if isinstance(cookie, dict):
239
- if 'name' in cookie and 'value' in cookie:
240
- to_return.append(cookie)
241
- elif len(cookie) == 1:
242
- # {'name': 'value'} => {'name': 'name', 'value': 'value'}
243
- name, value = cookie.popitem()
244
- if name and value:
245
- to_return.append({'name': name, 'value': value})
246
- else:
247
- # invalid cookie, ignoring
248
- pass
263
+ to_return.append(__prepare_cookie(cookie))
249
264
  return to_return
250
265
  return None
251
266
 
@@ -144,6 +144,7 @@ class LacusCore():
144
144
  viewport: dict[str, int] | None=None,
145
145
  referer: str | None=None,
146
146
  rendered_hostname_only: bool=True,
147
+ with_screenshot: bool=True,
147
148
  with_favicon: bool=False,
148
149
  allow_tracking: bool=False,
149
150
  headless: bool=True,
@@ -176,6 +177,7 @@ class LacusCore():
176
177
  viewport: dict[str, int] | None=None,
177
178
  referer: str | None=None,
178
179
  rendered_hostname_only: bool=True,
180
+ with_screenshot: bool=True,
179
181
  with_favicon: bool=False,
180
182
  allow_tracking: bool=False,
181
183
  headless: bool=True,
@@ -210,6 +212,7 @@ class LacusCore():
210
212
  :param viewport: The viewport of the browser used for capturing
211
213
  :param referer: The referer URL for the capture
212
214
  :param rendered_hostname_only: If depth > 0: only capture URLs with the same hostname as the rendered page
215
+ :param with_screenshot: If False, PlaywrightCapture won't take a screenshot of the rendered URL
213
216
  :param with_favicon: If True, PlaywrightCapture will attempt to get the potential favicons for the rendered URL. It is a dirty trick, see this issue for details: https://github.com/Lookyloo/PlaywrightCapture/issues/45
214
217
  :param allow_tracking: If True, PlaywrightCapture will attempt to click through the cookie banners. It is totally dependent on the framework used on the website.
215
218
  :param headless: Whether to run the browser in headless mode. WARNING: requires to run in a graphical environment.
@@ -232,7 +235,8 @@ class LacusCore():
232
235
  'http_credentials': http_credentials, 'geolocation': geolocation,
233
236
  'timezone_id': timezone_id, 'locale': locale,
234
237
  'color_scheme': color_scheme, 'java_script_enabled': java_script_enabled,
235
- 'viewport': viewport, 'referer': referer, 'with_favicon': with_favicon,
238
+ 'viewport': viewport, 'referer': referer,
239
+ 'with_screenshot': with_screenshot, 'with_favicon': with_favicon,
236
240
  'allow_tracking': allow_tracking,
237
241
  # Quietly force it to true if headed is not allowed.
238
242
  'headless': headless if self.headed_allowed else True,
@@ -530,6 +534,7 @@ class LacusCore():
530
534
  url, referer=to_capture.referer,
531
535
  depth=to_capture.depth,
532
536
  rendered_hostname_only=to_capture.rendered_hostname_only,
537
+ with_screenshot=to_capture.with_screenshot,
533
538
  with_favicon=to_capture.with_favicon,
534
539
  allow_tracking=to_capture.allow_tracking,
535
540
  max_depth_capture_time=self.max_capture_time)
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "lacuscore"
3
- version = "1.13.5"
3
+ version = "1.13.7"
4
4
  description = "Core of Lacus, usable as a module"
5
5
  authors = [
6
6
  {name="Raphaël Vinot", email="raphael.vinot@circl.lu"}
@@ -15,7 +15,7 @@ dynamic = [ "classifiers" ]
15
15
 
16
16
  dependencies = [
17
17
  "requests (>=2.32.3)",
18
- "playwrightcapture[recaptcha] (>=1.28.2)",
18
+ "playwrightcapture[recaptcha] (>=1.28.3)",
19
19
  "defang (>=0.5.3)",
20
20
  "ua-parser[regex] (>=1.0.1)",
21
21
  "redis [hiredis] (>=5.2.1)",
File without changes
File without changes