git: 754a7c04e588 - main - deskutils/calibre: Update to 8.1.1

From: Guido Falsi <madpilot_at_FreeBSD.org>
Date: Sat, 29 Mar 2025 08:45:28 UTC
The branch main has been updated by madpilot:

URL: https://cgit.FreeBSD.org/ports/commit/?id=754a7c04e588d5ef33355076f92cd80efbe630c9

commit 754a7c04e588d5ef33355076f92cd80efbe630c9
Author:     Guido Falsi <madpilot@FreeBSD.org>
AuthorDate: 2025-03-29 08:42:53 +0000
Commit:     Guido Falsi <madpilot@FreeBSD.org>
CommitDate: 2025-03-29 08:42:53 +0000

    deskutils/calibre: Update to 8.1.1
    
    - Remove upstreamed patch
---
 deskutils/calibre/Makefile                         |   5 +-
 deskutils/calibre/distinfo                         |  10 +-
 .../calibre/files/patch-UDisks2-Device-Mounting    | 288 ---------------------
 deskutils/calibre/files/user-agent-data.json       | 120 ++++-----
 deskutils/calibre/pkg-plist                        |   1 +
 5 files changed, 68 insertions(+), 356 deletions(-)

diff --git a/deskutils/calibre/Makefile b/deskutils/calibre/Makefile
index 50790983f9bc..a4afff836685 100644
--- a/deskutils/calibre/Makefile
+++ b/deskutils/calibre/Makefile
@@ -1,5 +1,5 @@
 PORTNAME=	calibre
-PORTVERSION=	8.0.1
+PORTVERSION=	8.1.1
 CATEGORIES=	deskutils python
 MASTER_SITES=	https://download.calibre-ebook.com/${PORTVERSION}/:DEFAULT \
 		https://raw.githubusercontent.com/rhasspy/piper/${PIPER_VOICES_HASH}/:piper
@@ -68,7 +68,7 @@ USES=		desktop-file-utils gettext-runtime:build gl localbase:ldflags \
 		pkgconfig pyqt:6 python:3.11+ qt:6 shared-mime-info shebangfix sqlite ssl \
 		tar:xz xorg
 USE_GITHUB=	nodefault
-GH_TUPLE=	kovidgoyal:calibre-translations:288b823:translations \
+GH_TUPLE=	kovidgoyal:calibre-translations:b74d31a:translations \
 		LibreOffice:dictionaries:1b8d1d5:hypenation
 PIPER_VOICES_HASH=	c0670df63daf07070c9be36b5c4bed270ad72383
 USE_GL=		opengl
@@ -104,7 +104,6 @@ post-extract:
 	@${CP} ${FILESDIR}/user-agent-data.json ${WRKSRC}/resources
 
 post-patch:
-	@${RM} ${WRKSRC}/src/calibre/devices/usbms/hal.py
 	@${REINPLACE_CMD} -e "s|#!/usr/bin/env python{py_major_version}|#!${PYTHON_CMD}|" \
 			-e "s|#!/usr/bin/env python|#!${PYTHON_CMD}|" \
 		${WRKSRC}/setup/install.py \
diff --git a/deskutils/calibre/distinfo b/deskutils/calibre/distinfo
index d7c25c38d081..8652aca7b477 100644
--- a/deskutils/calibre/distinfo
+++ b/deskutils/calibre/distinfo
@@ -1,9 +1,9 @@
-TIMESTAMP = 1742549723
-SHA256 (calibre/calibre-8.0.1.tar.xz) = a2937a9eb0fb394a92db570496b2ea5b38066a01735385e46993bbd121068d2a
-SIZE (calibre/calibre-8.0.1.tar.xz) = 43932180
+TIMESTAMP = 1743151624
+SHA256 (calibre/calibre-8.1.1.tar.xz) = 973f9096b6a3223036bafa3a22899e8e4f58f9d8c38d434f01de41653dc3cf96
+SIZE (calibre/calibre-8.1.1.tar.xz) = 43905360
 SHA256 (calibre/VOICES.md) = a70bfdebf2f35d077b26a00378a8903509d26db04e97a9777caead04415a320d
 SIZE (calibre/VOICES.md) = 38861
-SHA256 (calibre/kovidgoyal-calibre-translations-288b823_GH0.tar.gz) = e09f3ff8749c932de6bb0263413d98599685f12622a7057ee0c07c6e20affad0
-SIZE (calibre/kovidgoyal-calibre-translations-288b823_GH0.tar.gz) = 74670184
+SHA256 (calibre/kovidgoyal-calibre-translations-b74d31a_GH0.tar.gz) = 0dfed2d33c82e64f5369507b75626a5db8d7615f8c5811afcec03653b4311166
+SIZE (calibre/kovidgoyal-calibre-translations-b74d31a_GH0.tar.gz) = 74368733
 SHA256 (calibre/LibreOffice-dictionaries-1b8d1d5_GH0.tar.gz) = 5ea31eb76245ea30ddcd8c9f3ec149abe7b18cb0de9d878bebb66efd3a850934
 SIZE (calibre/LibreOffice-dictionaries-1b8d1d5_GH0.tar.gz) = 117894352
diff --git a/deskutils/calibre/files/patch-UDisks2-Device-Mounting b/deskutils/calibre/files/patch-UDisks2-Device-Mounting
deleted file mode 100644
index ae54d9a80b3e..000000000000
--- a/deskutils/calibre/files/patch-UDisks2-Device-Mounting
+++ /dev/null
@@ -1,288 +0,0 @@
-From 6f3987721824d02a425578561ee5da49a4458607 Mon Sep 17 00:00:00 2001
-From: Guido Falsi <mad@madpilot.net>
-Date: Thu, 13 Feb 2025 17:46:43 +0100
-Subject: [PATCH] Implement FreeBSD support using UDisk2
-
----
- src/calibre/devices/udisks.py       |  70 ++++++++++++--
- src/calibre/devices/usbms/device.py |  93 +++++++++++++++----
- src/calibre/devices/usbms/hal.py    | 137 ----------------------------
- 3 files changed, 140 insertions(+), 160 deletions(-)
- delete mode 100644 src/calibre/devices/usbms/hal.py
-
-diff --git a/src/calibre/devices/udisks.py b/src/calibre/devices/udisks.py
-index c8e5ee00b1..aadd031f54 100644
---- src/calibre/devices/udisks.py
-+++ src/calibre/devices/udisks.py
-@@ -5,9 +5,12 @@
- __copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
- __docformat__ = 'restructuredtext en'
- 
-+import json
- import os
- import re
-+import subprocess
- from contextlib import suppress
-+from calibre.constants import isfreebsd
- 
- 
- def node_mountpoint(node):
-@@ -19,11 +22,18 @@ def de_mangle(raw):
-         return raw.replace(b'\\040', b' ').replace(b'\\011', b'\t').replace(b'\\012',
-                 b'\n').replace(b'\\0134', b'\\').decode('utf-8')
- 
--    with open('/proc/mounts', 'rb') as src:
--        for line in src.readlines():
--            line = line.split()
--            if line[0] == node:
--                return de_mangle(line[1])
-+    if isfreebsd:
-+        cmd = subprocess.run(['mount', '-p', '--libxo', 'json'], capture_output=True, encoding='UTF-8')
-+        stdout = json.loads(cmd.stdout)
-+        for row in stdout['mount']['fstab']:
-+            if (row['device'].encode('utf-8') == node):
-+                return de_mangle(row['mntpoint'].encode('utf-8'))
-+    else:
-+        with open('/proc/mounts', 'rb') as src:
-+            for line in src.readlines():
-+                line = line.split()
-+                if line[0] == node:
-+                    return de_mangle(line[1])
-     return None
- 
- 
-@@ -37,6 +47,7 @@ class UDisks:
-     BLOCK = f'{BUS_NAME}.Block'
-     FILESYSTEM = f'{BUS_NAME}.Filesystem'
-     DRIVE = f'{BUS_NAME}.Drive'
-+    OBJECTMANAGER = 'org.freedesktop.DBus.ObjectManager'
-     PATH = '/org/freedesktop/UDisks2'
- 
-     def __enter__(self):
-@@ -78,6 +89,37 @@ def iter_block_devices(self):
-             with suppress(Exception):
-                 yield devname, self.get_device_node_path(devname)
- 
-+    def find_device_vols_by_serial(self, serial):
-+        from jeepney import DBusAddress, new_method_call
-+
-+        def decodePath(encoded):
-+            ret = ''
-+            for c in encoded:
-+                if (c != 0):
-+                    ret += str(c)
-+            return ret
-+
-+        drives = []
-+        blocks = []
-+        vols = []
-+        a = DBusAddress(self.PATH, bus_name=self.BUS_NAME, interface=self.OBJECTMANAGER)
-+        msg = new_method_call(a, 'GetManagedObjects')
-+        r = self.send(msg)
-+        for k,v in r.body[0].items():
-+            if os.path.join(self.PATH, '/block_devices') in k:
-+                blocks.append({'k': k, 'v': v.get(f'{self.BUS_NAME}.Block', {})})
-+            if os.path.join(self.PATH, '/drives') in k:
-+                drive = v.get(f'{self.BUS_NAME}.Drive', {})
-+                if drive.get('ConnectionBus')[1] == 'usb' and drive.get('Removable')[1] and drive.get('Serial')[1] == serial:
-+                    drives.append(k)
-+        for block in blocks:
-+            if block['v']['Drive'][1] in drives:
-+                vols.append({
-+                    'Block': block['k'],
-+                    'Device': block['v']['Device'][1].decode('ascii').strip('\x00'),
-+                })
-+        return vols
-+
-     def device(self, device_node_path):
-         device_node_path = os.path.realpath(device_node_path)
-         devname = device_node_path.split('/')[-1]
-@@ -101,7 +143,8 @@ def filesystem_operation_message(self, device_node_path, function_name, **kw):
-     def mount(self, device_node_path):
-         msg = self.filesystem_operation_message(device_node_path, 'Mount', options=('s', ','.join(basic_mount_options())))
-         try:
--            self.send(msg)
-+            r = self.send(msg)
-+            return r.body[0]
-         except Exception:
-             # May be already mounted, check
-             mp = node_mountpoint(str(device_node_path))
-@@ -130,6 +173,14 @@ def eject(self, device_node_path):
-         },))
-         self.send(msg)
- 
-+    def rescan(self, device_node_path):
-+        from jeepney import new_method_call
-+        devname = self.device(device_node_path)
-+        a = self.address(f'block_devices/{devname}', self.BLOCK)
-+        msg = new_method_call(a, 'Rescan', 'a{sv}', ({
-+            'auth.no_user_interaction': ('b', True),
-+        },))
-+        self.send(msg)
- 
- def get_udisks():
-     return UDisks()
-@@ -149,6 +200,13 @@ def umount(node_path):
-     with get_udisks() as u:
-         u.unmount(node_path)
- 
-+def rescan(node_path):
-+    with get_udisks() as u:
-+        u.rescan(node_path)
-+
-+def find_device_vols_by_serial(serial):
-+    with get_udisks() as u:
-+        return u.find_device_vols_by_serial(serial)
- 
- def test_udisks():
-     import sys
-diff --git a/src/calibre/devices/usbms/device.py b/src/calibre/devices/usbms/device.py
-index d4b79e9f26..ee61182b5c 100644
---- src/calibre/devices/usbms/device.py
-+++ src/calibre/devices/usbms/device.py
-@@ -20,7 +20,7 @@
- from itertools import repeat
- 
- from calibre import prints
--from calibre.constants import is_debugging, isfreebsd, islinux, ismacos, iswindows
-+from calibre.constants import DEBUG, is_debugging, isfreebsd, islinux, ismacos, iswindows
- from calibre.devices.errors import DeviceError
- from calibre.devices.interface import FAKE_DEVICE_SERIAL, DevicePlugin, ModelMetadata
- from calibre.devices.usbms.deviceconfig import DeviceConfig
-@@ -696,12 +696,14 @@ def is_readonly(mp):
- #  open for FreeBSD
- #      find the device node or nodes that match the S/N we already have from the scanner
- #      and attempt to mount each one
--#              1.  get list of devices in /dev with matching s/n etc.
-+#              1.  get list of devices via DBUS UDisk2 with matching s/n etc.
- #              2.  get list of volumes associated with each
--#              3.  attempt to mount each one using Hal
-+#              3.  attempt to mount each one using UDisks2
- #              4.  when finished, we have a list of mount points and associated dbus nodes
- #
-     def open_freebsd(self):
-+        from calibre.devices.udisks import find_device_vols_by_serial
-+
-         # There should be some way to access the -v arg...
-         verbose = False
- 
-@@ -711,18 +713,80 @@ def open_freebsd(self):
- 
-         if not d.serial:
-             raise DeviceError("Device has no S/N.  Can't continue")
--        from .hal import get_hal
--        hal = get_hal()
--        vols = hal.get_volumes(d)
-+
-+        vols = find_device_vols_by_serial(d.serial)
-+
-         if verbose:
-             print('FBSD:\t', vols)
- 
--        ok, mv = hal.mount_volumes(vols)
-+        ok, mv = self.freebsd_mount_volumes(vols)
-         if not ok:
-             raise DeviceError(_('Unable to mount the device'))
-         for k, v in mv.items():
-             setattr(self, k, v)
- 
-+    def freebsd_mount_volumes(self, vols):
-+        def fmount(node):
-+            mp = self.node_mountpoint(node)
-+            if mp is not None:
-+                # Already mounted
-+                return mp
-+
-+            from calibre.devices.udisks import mount, rescan
-+            for i in range(6):
-+                try:
-+                    mp = mount(node)
-+                    break
-+                except Exception as e:
-+                    if i < 5:
-+                        rescan(node)
-+                        time.sleep(1)
-+                    else:
-+                        print('Udisks mount call failed:')
-+                        import traceback
-+                        traceback.print_exc()
-+
-+            return mp
-+
-+        mp = None
-+        mtd = 0
-+        ans = {
-+            '_main_prefix': None, '_main_vol': None,
-+            '_card_a_prefix': None, '_card_a_vol': None,
-+            '_card_b_prefix': None, '_card_b_vol': None,
-+        }
-+        for vol in vols:
-+            try:
-+                mp = fmount(vol['Device'])
-+            except Exception as e:
-+                print('Failed to mount: ' + vol['Device'])
-+                import traceback
-+                traceback.print_exc()
-+
-+            if mp is None:
-+                continue
-+
-+            # Mount Point becomes Mount Path
-+            mp += '/'
-+            if DEBUG:
-+                print('FBSD:\tmounted', vol['Device'], 'on', mp)
-+            if mtd == 0:
-+                ans['_main_prefix'], ans['_main_vol'] = mp, vol['Device']
-+                if DEBUG:
-+                    print('FBSD:\tmain = ', mp)
-+            elif mtd == 1:
-+                ans['_card_a_prefix'], ans['_card_a_vol'] = mp, vol['Device']
-+                if DEBUG:
-+                    print('FBSD:\tcard a = ', mp)
-+            elif mtd == 2:
-+                ans['_card_b_prefix'], ans['_card_b_vol'] = mp, vol['Device']
-+                if DEBUG:
-+                    print('FBSD:\tcard b = ', mp)
-+                break
-+            mtd += 1
-+
-+        return mtd > 0, ans
-+
- #
- # ------------------------------------------------------
- #
-@@ -731,14 +795,13 @@ def open_freebsd(self):
- #        mounted filesystems, using the stored volume object
- #
-     def eject_freebsd(self):
--        from .hal import get_hal
--        hal = get_hal()
-+        from calibre.devices.udisks import umount
-         if self._main_prefix:
--            hal.unmount(self._main_vol)
-+            umount(self._main_vol)
-         if self._card_a_prefix:
--            hal.unmount(self._card_a_vol)
-+            umount(self._card_a_vol)
-         if self._card_b_prefix:
--            hal.unmount(self._card_b_vol)
-+            umount(self._card_b_vol)
- 
-         self._main_prefix = self._main_vol = None
-         self._card_a_prefix = self._card_a_vol = None
-@@ -786,11 +849,7 @@ def open(self, connected_device, library_uuid):
-                     self.open_linux()
-             if isfreebsd:
-                 self._main_vol = self._card_a_vol = self._card_b_vol = None
--                try:
--                    self.open_freebsd()
--                except DeviceError:
--                    time.sleep(2)
--                    self.open_freebsd()
-+                self.open_freebsd()
-             if iswindows:
-                 self.open_windows()
-             if ismacos:
--- 
-2.49.0
-
diff --git a/deskutils/calibre/files/user-agent-data.json b/deskutils/calibre/files/user-agent-data.json
index a85aa63446a2..8cca1f41d57a 100644
--- a/deskutils/calibre/files/user-agent-data.json
+++ b/deskutils/calibre/files/user-agent-data.json
@@ -6,12 +6,14 @@
     "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36",
     "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.6778.33 Safari/537.36",
     "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:133.0) Gecko/20100101 Firefox/133.0",
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36",
     "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:135.0) Gecko/20100101 Firefox/135.0",
     "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/133.0.0.0",
     "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:134.0) Gecko/20100101 Firefox/134.0",
     "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 Edg/132.0.0.0",
     "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36",
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:136.0) Gecko/20100101 Firefox/136.0",
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Edg/134.0.0.0",
     "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.3 Safari/605.1.15",
     "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.2 Safari/605.1.15",
     "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36",
@@ -19,11 +21,10 @@
     "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.6 Safari/605.1.15",
     "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 OPR/115.0.0.0",
     "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:133.0) Gecko/20100101 Firefox/133.0",
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 OPR/114.0.0.0",
     "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36",
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 OPR/114.0.0.0",
     "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36",
     "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:134.0) Gecko/20100101 Firefox/134.0",
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:136.0) Gecko/20100101 Firefox/136.0",
     "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36",
     "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0",
     "Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.19044; en-US) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 (compatible; Liquit-SetupStore; +https://www.liquit.com/products/release-patch-management/)",
@@ -33,13 +34,13 @@
     "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.1 Safari/605.1.15",
     "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36",
     "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0",
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:132.0) Gecko/20100101 Firefox/132.0",
     "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
-    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36",
     "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36",
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:132.0) Gecko/20100101 Firefox/132.0",
+    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36",
     "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0.1 Safari/605.1.15",
-    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0",
     "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0",
+    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0",
     "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
     "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6.1 Safari/605.1.15",
     "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36",
@@ -47,67 +48,66 @@
     "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",
     "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Safari/605.1.15",
     "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0",
-    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4.1 Safari/605.1.15",
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36 Edg/127.0.0.0"
+    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4.1 Safari/605.1.15"
   ],
   "desktop_platforms": [
+    "Macintosh; Intel Mac OS X 10_15_7",
     "Windows NT 10.0; Microsoft Windows 10.0.19044; en-US",
     "Windows NT 10.0",
+    "Windows NT 10.0; Win64; x64",
     "Macintosh; Intel Mac OS X 10.15",
-    "Macintosh; Intel Mac OS X 10_15_7",
-    "Windows NT 6.1; Win64; x64",
-    "Windows NT 10.0; Win64; x64"
+    "Windows NT 6.1; Win64; x64"
   ],
-  "timestamp": "2025-03-21T09:35:47.732952+00:00",
+  "timestamp": "2025-03-28T08:51:25.427829+00:00",
   "user_agents_popularity": {
-    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:133.0) Gecko/20100101 Firefox/133.0": 18535,
-    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:134.0) Gecko/20100101 Firefox/134.0": 13800,
-    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36": 40561,
-    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36": 3300,
-    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36": 4633,
-    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36": 6052,
-    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36": 102141,
-    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0": 4268,
-    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6.1 Safari/605.1.15": 3540,
-    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Safari/605.1.15": 3201,
-    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4.1 Safari/605.1.15": 2817,
-    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Safari/605.1.15": 7533,
-    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.6 Safari/605.1.15": 23319,
-    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0.1 Safari/605.1.15": 4311,
-    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.1 Safari/605.1.15": 6721,
-    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.1.1 Safari/605.1.15": 32669,
-    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.2 Safari/605.1.15": 50304,
-    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.3 Safari/605.1.15": 56115,
-    "Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.19044; en-US) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 (compatible; Liquit-SetupStore; +https://www.liquit.com/products/release-patch-management/)": 7550,
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36": 15837,
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36": 4893,
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36": 3838,
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36": 7088,
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36": 12378,
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36": 3272,
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36 Edg/127.0.0.0": 2645,
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36": 4624,
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 OPR/114.0.0.0": 16671,
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36": 3299,
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0": 2870,
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36": 15076,
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0": 5800,
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 OPR/115.0.0.0": 20659,
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36": 547227,
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0": 280269,
+    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:133.0) Gecko/20100101 Firefox/133.0": 18567,
+    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:134.0) Gecko/20100101 Firefox/134.0": 13938,
+    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36": 45517,
+    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36": 3475,
+    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36": 4851,
+    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36": 6170,
+    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36": 102545,
+    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0": 4289,
+    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6.1 Safari/605.1.15": 3725,
+    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Safari/605.1.15": 3419,
+    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4.1 Safari/605.1.15": 2973,
+    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Safari/605.1.15": 7874,
+    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.6 Safari/605.1.15": 24514,
+    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0.1 Safari/605.1.15": 4460,
+    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.1 Safari/605.1.15": 6996,
+    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.1.1 Safari/605.1.15": 33023,
+    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.2 Safari/605.1.15": 50761,
+    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.3 Safari/605.1.15": 58592,
+    "Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.19044; en-US) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 (compatible; Liquit-SetupStore; +https://www.liquit.com/products/release-patch-management/)": 8028,
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36": 17023,
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36": 5613,
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36": 3949,
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36": 7476,
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36": 13512,
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36": 3425,
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36": 5055,
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 OPR/114.0.0.0": 16693,
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36": 3440,
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0": 2982,
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36": 15535,
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0": 5981,
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 OPR/115.0.0.0": 20664,
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36": 548171,
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0": 280918,
     "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.6778.33 Safari/537.36": 225956,
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36": 237635,
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 Edg/132.0.0.0": 133780,
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36": 275088,
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/133.0.0.0": 142066,
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36": 70797,
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0": 11016,
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:132.0) Gecko/20100101 Firefox/132.0": 4965,
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:133.0) Gecko/20100101 Firefox/133.0": 175447,
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:134.0) Gecko/20100101 Firefox/134.0": 134988,
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:135.0) Gecko/20100101 Firefox/135.0": 168049,
-    "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:136.0) Gecko/20100101 Firefox/136.0": 12497,
-    "Mozilla/5.0 (Windows NT 10.0; rv:128.0) Gecko/20100101 Firefox/128.0": 6752,
-    "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0": 4139
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36": 238645,
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 Edg/132.0.0.0": 135056,
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36": 277390,
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/133.0.0.0": 143547,
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36": 174901,
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Edg/134.0.0.0": 61992,
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0": 12343,
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:132.0) Gecko/20100101 Firefox/132.0": 5040,
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:133.0) Gecko/20100101 Firefox/133.0": 175645,
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:134.0) Gecko/20100101 Firefox/134.0": 135283,
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:135.0) Gecko/20100101 Firefox/135.0": 169277,
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:136.0) Gecko/20100101 Firefox/136.0": 70321,
+    "Mozilla/5.0 (Windows NT 10.0; rv:128.0) Gecko/20100101 Firefox/128.0": 7213,
+    "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0": 4457
   }
 }
diff --git a/deskutils/calibre/pkg-plist b/deskutils/calibre/pkg-plist
index 453624a937cf..1ffc930f5241 100644
--- a/deskutils/calibre/pkg-plist
+++ b/deskutils/calibre/pkg-plist
@@ -1416,6 +1416,7 @@ lib/calibre/calibre/utils/rcc/__init__.py
 lib/calibre/calibre/utils/recycle_bin.py
 lib/calibre/calibre/utils/resources.py
 lib/calibre/calibre/utils/run_tests.py
+lib/calibre/calibre/utils/safe_atexit.py
 lib/calibre/calibre/utils/search_query_parser.py
 lib/calibre/calibre/utils/search_query_parser_test.py
 lib/calibre/calibre/utils/serialize.py