From eeca60680200596b56e2d5917247a7b8d52a6266 Mon Sep 17 00:00:00 2001 From: tropicoo Date: Sun, 7 May 2023 00:09:11 +0300 Subject: [PATCH] Update media text formatting --- hikcamerabot/common/video/tasks/videogif.py | 4 +++ hikcamerabot/event_engine/events/outbound.py | 16 ++++++++--- hikcamerabot/event_engine/handlers/inbound.py | 1 + .../event_engine/handlers/outbound.py | 27 ++++++++++++------- .../alarm/camera/tasks/notifications.py | 1 + hikcamerabot/utils/file.py | 18 +++++++++++++ 6 files changed, 54 insertions(+), 13 deletions(-) create mode 100644 hikcamerabot/utils/file.py diff --git a/hikcamerabot/common/video/tasks/videogif.py b/hikcamerabot/common/video/tasks/videogif.py index e12edde..4982fdf 100644 --- a/hikcamerabot/common/video/tasks/videogif.py +++ b/hikcamerabot/common/video/tasks/videogif.py @@ -4,6 +4,7 @@ import signal import socket import time +from datetime import datetime from typing import TYPE_CHECKING, Optional from urllib.parse import urlsplit @@ -28,6 +29,7 @@ VideoOutboundEvent, ) from hikcamerabot.event_engine.queue import get_result_queue +from hikcamerabot.utils.file import file_size from hikcamerabot.utils.shared import bold, format_ts, gen_random_str from hikcamerabot.utils.task import wrap @@ -196,6 +198,8 @@ async def _send_result(self) -> None: thumb_path=self._thumb_path if self._thumb_created else None, cam=self._cam, message=self._message, + file_size=file_size(self._file_path), + create_ts=int(datetime.now().timestamp()), ) ) diff --git a/hikcamerabot/event_engine/events/outbound.py b/hikcamerabot/event_engine/events/outbound.py index 806e5f2..90c6363 100644 --- a/hikcamerabot/event_engine/events/outbound.py +++ b/hikcamerabot/event_engine/events/outbound.py @@ -7,19 +7,29 @@ from hikcamerabot.enums import Alarm, Detection, Event, ServiceType, Stream from hikcamerabot.event_engine.events.abstract import BaseOutboundEvent +from hikcamerabot.utils.file import format_bytes @dataclass -class VideoOutboundEvent(BaseOutboundEvent): +class FileSizeMixin: + file_size: int + + def file_size_human(self) -> str: + return format_bytes(num=self.file_size) + + +@dataclass +class VideoOutboundEvent(BaseOutboundEvent, FileSizeMixin): thumb_path: Optional[str] video_path: str video_duration: int video_height: int video_width: int + create_ts: int @dataclass -class AlertSnapshotOutboundEvent(BaseOutboundEvent): +class AlertSnapshotOutboundEvent(BaseOutboundEvent, FileSizeMixin): img: BytesIO ts: int resized: bool @@ -28,7 +38,7 @@ class AlertSnapshotOutboundEvent(BaseOutboundEvent): @dataclass -class SnapshotOutboundEvent(BaseOutboundEvent): +class SnapshotOutboundEvent(BaseOutboundEvent, FileSizeMixin): img: BytesIO create_ts: int taken_count: int diff --git a/hikcamerabot/event_engine/handlers/inbound.py b/hikcamerabot/event_engine/handlers/inbound.py index 73c20bc..9d00384 100644 --- a/hikcamerabot/event_engine/handlers/inbound.py +++ b/hikcamerabot/event_engine/handlers/inbound.py @@ -59,6 +59,7 @@ async def _handle(self, event: GetPicEvent) -> None: resized=event.resize, message=event.message, cam=event.cam, + file_size=img.getbuffer().nbytes, ) ) diff --git a/hikcamerabot/event_engine/handlers/outbound.py b/hikcamerabot/event_engine/handlers/outbound.py index 1c65501..d54e992 100644 --- a/hikcamerabot/event_engine/handlers/outbound.py +++ b/hikcamerabot/event_engine/handlers/outbound.py @@ -127,8 +127,11 @@ async def _upload_video(self, event: VideoOutboundEvent) -> None: cam = event.cam message = event.message caption = ( - f'Video from {cam.description} {cam.hashtag}\n/cmds_{cam.id}, ' - f'/list_cams' + f'📷 {bold("Camera:")} [{cam.id}] {cam.description}\n' + f'🗓️ {bold("Date:")} {format_ts(event.create_ts)}\n' + f'#️⃣ {bold("Hashtag:")} {cam.hashtag}\n' + f'📏 {bold("Size:")} {event.file_size_human()}\n' + f'🤖 {bold("Commands:")} /cmds_{cam.id}, /list_cams' ) await self._bot.send_chat_action( message.chat.id, action=ChatAction.UPLOAD_VIDEO @@ -251,13 +254,14 @@ async def _handle(self, event: SnapshotOutboundEvent) -> None: async def _send_resized_photo(self, event: SnapshotOutboundEvent) -> None: cam = event.cam message = event.message - caption = ( - f'[{cam.conf.description}] ' - f'Snapshot taken on {format_ts(event.create_ts)} ' - f'(snapshot #{event.taken_count}) {cam.hashtag}' + f'📷 {bold("Camera:")} [{cam.id}] {cam.description}\n' + f'🗓️ {bold("Date:")} {format_ts(event.create_ts)}\n' + f'#️⃣ {bold("Hashtag:")} {cam.hashtag}\n' + f'🔢 {bold("Count:")} {event.taken_count}\n' + f'📏 {bold("Size:")} {event.file_size_human()}\n' + f'🤖 {bold("Commands:")} /cmds_{cam.id}, /list_cams' ) - caption = f'{caption}\n/cmds_{cam.id}, /list_cams' self._log.info('Sending resized cam snapshot') await self._bot.send_chat_action( @@ -274,10 +278,13 @@ async def _send_full_photo(self, event: SnapshotOutboundEvent) -> None: datetime_str = format_ts(event.create_ts) filename = f'Full snapshot {datetime_str}.jpg' caption = ( - f'[{cam.description}] Full snapshot on {datetime_str} ' - f'(snapshot #{event.taken_count}) {cam.hashtag}' + f'📷 {bold("Camera:")} [{cam.id}] {cam.description}\n' + f'🗓️ {bold("Date:")} {datetime_str}\n' + f'#️⃣ {bold("Hashtag:")} {cam.hashtag}\n' + f'🔢 {bold("Count:")} {event.taken_count}\n' + f'📏 {bold("Size:")} {event.file_size_human()}\n' + f'🤖 {bold("Commands:")} /cmds_{cam.id}, /list_cams' ) - caption = f'{caption}\n/cmds_{cam.id}, /list_cams' self._log.info('Sending full cam snapshot') await self._bot.send_chat_action( diff --git a/hikcamerabot/services/alarm/camera/tasks/notifications.py b/hikcamerabot/services/alarm/camera/tasks/notifications.py index ee256dd..5c11ea0 100644 --- a/hikcamerabot/services/alarm/camera/tasks/notifications.py +++ b/hikcamerabot/services/alarm/camera/tasks/notifications.py @@ -87,5 +87,6 @@ async def _send_pic(self) -> None: detection_type=self._detection_type, alert_count=self._alert_count, message=None, + file_size=photo.getbuffer().nbytes, ) ) diff --git a/hikcamerabot/utils/file.py b/hikcamerabot/utils/file.py new file mode 100644 index 0000000..0648dbe --- /dev/null +++ b/hikcamerabot/utils/file.py @@ -0,0 +1,18 @@ +import os + +_UNIT_SIZE_NAMES = ('', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi') +_BASE = 1024.0 + + +def format_bytes(num: int, suffix: str = "B") -> str: + """Format bytes to human-readable size.""" + for unit in _UNIT_SIZE_NAMES: + if abs(num) < _BASE: + return f"{num:3.1f}{unit}{suffix}" + num /= _BASE + return f"{num:.1f}Yi{suffix}" + + +def file_size(filepath: str) -> int: + """Return file size in bytes.""" + return os.path.getsize(filepath)