www/py-binarycookies: new port had been added (+)
Apple's Safari web browser binary cookies format (de)serializer written in Python. Our modifications to the original sources include the fix for "the year 2038 problem" on 32-bit systems, Netscape traditional `cookies.txt' file format support, and use of Pydantic V1 which does not pull in Rust unlike V2 which the project needlessly assumes by default.
This commit is contained in:
@@ -1487,6 +1487,7 @@
|
||||
SUBDIR += py-beaker
|
||||
SUBDIR += py-beautifulsoup
|
||||
SUBDIR += py-betamax
|
||||
SUBDIR += py-binarycookies
|
||||
SUBDIR += py-biscuits
|
||||
SUBDIR += py-bjoern
|
||||
SUBDIR += py-bleach
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
PORTNAME= binarycookies
|
||||
PORTVERSION= 2.1.5
|
||||
CATEGORIES= www python
|
||||
MASTER_SITES= PYPI
|
||||
PKGNAMEPREFIX= ${PYTHON_PKGNAMEPREFIX}
|
||||
|
||||
MAINTAINER= danfe@FreeBSD.org
|
||||
COMMENT= Binary cookies (de)serializer written in Python
|
||||
WWW= https://pypi.org/project/binarycookies/
|
||||
|
||||
LICENSE= MIT
|
||||
|
||||
RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}pydantic>=0:devel/py-pydantic@${PY_FLAVOR} \
|
||||
${PYTHON_PKGNAMEPREFIX}typer>=0.12.3:devel/py-typer@${PY_FLAVOR}
|
||||
|
||||
USES= python
|
||||
USE_PYTHON= autoplist distutils
|
||||
|
||||
NO_ARCH= yes
|
||||
|
||||
post-patch:
|
||||
# Do not pick up leftovers (*.orig files etc.) when making the package
|
||||
@${REINPLACE_CMD} -e '/^package_data =/,+1s,\*,&.py,' \
|
||||
${WRKSRC}/${PYSETUP}
|
||||
|
||||
.include <bsd.port.mk>
|
||||
@@ -0,0 +1,3 @@
|
||||
TIMESTAMP = 1744141848
|
||||
SHA256 (binarycookies-2.1.5.tar.gz) = ff28a8e90e6ba02bc82fb2ff0d1d9a4a3be1ee9289a58f74a653d264928a31f3
|
||||
SIZE (binarycookies-2.1.5.tar.gz) = 8448
|
||||
@@ -0,0 +1,49 @@
|
||||
--- src/binarycookies/__main__.py.orig 2025-04-08 19:50:17 UTC
|
||||
+++ src/binarycookies/__main__.py
|
||||
@@ -5,6 +5,8 @@ from sys import stdout
|
||||
from typing import Type
|
||||
|
||||
import typer
|
||||
+# https://github.com/Textualize/rich/issues/271
|
||||
+println = print
|
||||
from rich import print
|
||||
|
||||
from binarycookies import load
|
||||
@@ -20,6 +22,7 @@ class DateTimeEncoder(json.JSONEncoder):
|
||||
class OutputType(str, Enum):
|
||||
json = "json"
|
||||
ascii = "ascii"
|
||||
+ netscape = "netscape"
|
||||
|
||||
|
||||
def cli(file_path: str, output: str = "json"):
|
||||
@@ -27,7 +30,7 @@ def cli(file_path: str, output: str = "json"):
|
||||
with open(file_path, "rb") as f:
|
||||
cookies = load(f)
|
||||
if output == OutputType.json:
|
||||
- json.dump([cookie.model_dump() for cookie in cookies], indent=2, cls=DateTimeEncoder, fp=stdout)
|
||||
+ json.dump([cookie.dict() for cookie in cookies], indent=2, cls=DateTimeEncoder, fp=stdout)
|
||||
elif output == OutputType.ascii:
|
||||
for cookie in cookies:
|
||||
print(f"Name: {cookie.name}")
|
||||
@@ -38,6 +41,20 @@ def cli(file_path: str, output: str = "json"):
|
||||
print(f"Expires: {cookie.expiry_datetime.isoformat()}")
|
||||
print(f"Flag: {cookie.flag.value}")
|
||||
print("-" * 40)
|
||||
+ elif output == OutputType.netscape:
|
||||
+ # http://www.cookiecentral.com/faq/#3.5
|
||||
+ println("# Netscape HTTP Cookie File")
|
||||
+ for cookie in cookies:
|
||||
+ println("%(domain)s\t%(flag)s\t%(path)s\t%(secure)s\t%(expiry)d\t%(name)s\t%(value)s" % dict(
|
||||
+ domain = cookie.url,
|
||||
+ flag = str(cookie.url.startswith('.')).upper(),
|
||||
+ path = cookie.path,
|
||||
+ secure = str('Secure' in cookie.flag.value).upper(),
|
||||
+ expiry = cookie.expiry_datetime.timestamp(),
|
||||
+ name = cookie.name,
|
||||
+ value = cookie.value))
|
||||
+ else:
|
||||
+ print(f"Unsupported output format, can only do {', '.join('[green]%s[/green]' % ot.name for ot in OutputType)}.")
|
||||
|
||||
|
||||
def main():
|
||||
@@ -0,0 +1,21 @@
|
||||
--- src/binarycookies/_deserialize.py.orig 2025-04-08 19:50:17 UTC
|
||||
+++ src/binarycookies/_deserialize.py
|
||||
@@ -1,6 +1,7 @@
|
||||
from datetime import datetime, timezone
|
||||
from io import BytesIO
|
||||
from struct import unpack
|
||||
+from sys import maxsize
|
||||
from typing import BinaryIO, List, Union
|
||||
|
||||
from binarycookies.models import (
|
||||
@@ -28,7 +29,9 @@ def interpret_flag(flags: int) -> Flag:
|
||||
|
||||
def mac_epoch_to_date(epoch: int) -> datetime:
|
||||
"""Converts a mac epoch time to a datetime object."""
|
||||
- return datetime.fromtimestamp(epoch + 978307200, tz=timezone.utc)
|
||||
+ unix_epoch = epoch + 978307200
|
||||
+ if unix_epoch > maxsize: unix_epoch = maxsize
|
||||
+ return datetime.fromtimestamp(unix_epoch, tz=timezone.utc)
|
||||
|
||||
|
||||
def read_string(data: BytesIO, size: int) -> str:
|
||||
@@ -0,0 +1,6 @@
|
||||
Python library and command-line tool for reading and writing binary
|
||||
cookies files used by Apple's Safari web browser on macOS and iOS.
|
||||
|
||||
The `bcparser' program supports three output types: JSON (default),
|
||||
ASCII (line-by-line text format), and Netscape legacy `cookies.txt'
|
||||
format used by popular tools such as curl, wget, yt-dlp, and others.
|
||||
Reference in New Issue
Block a user