Upload stats
This commit is contained in:
parent
3aff20006c
commit
a555ad0e19
|
@ -215,8 +215,8 @@ class MatrixClient(nio.AsyncClient):
|
|||
|
||||
try:
|
||||
await self._send_file(item_uuid, room_id, path)
|
||||
except asyncio.CancelledError:
|
||||
del self.models[Upload, room_id][item_uuid]
|
||||
except (nio.TransferCancelledError, asyncio.CancelledError):
|
||||
del self.models[Upload, room_id][str(item_uuid)]
|
||||
|
||||
|
||||
async def _send_file(
|
||||
|
@ -235,18 +235,27 @@ class MatrixClient(nio.AsyncClient):
|
|||
|
||||
task = asyncio.Task.current_task()
|
||||
upload_item = Upload(item_uuid, task, path, total_size=size)
|
||||
self.models[Upload, room_id][upload_item.uuid] = upload_item
|
||||
self.models[Upload, room_id][str(item_uuid)] = upload_item
|
||||
|
||||
def on_transfered(transfered: int) -> None:
|
||||
upload_item.uploaded = transfered
|
||||
upload_item.time_left = monitor.remaining_time
|
||||
|
||||
def on_speed_change(speed: float) -> None:
|
||||
upload_item.speed = speed
|
||||
|
||||
monitor = nio.TransferMonitor(size, on_transfered, on_speed_change)
|
||||
|
||||
try:
|
||||
url, mime, crypt_dict = await self.upload(
|
||||
path, filename=path.name, encrypt=encrypt,
|
||||
path, filename=path.name, encrypt=encrypt, monitor=monitor,
|
||||
)
|
||||
except (MatrixError, OSError) as err:
|
||||
upload_item.status = UploadStatus.Error
|
||||
upload_item.error = type(err)
|
||||
upload_item.error_args = err.args
|
||||
|
||||
# Wait for cancellation, see parent send_file() method
|
||||
# Wait for cancellation from UI, see parent send_file() method
|
||||
while True:
|
||||
await asyncio.sleep(0.1)
|
||||
|
||||
|
@ -606,9 +615,10 @@ class MatrixClient(nio.AsyncClient):
|
|||
async def upload(
|
||||
self,
|
||||
data: UploadData,
|
||||
mime: Optional[str] = None,
|
||||
filename: Optional[str] = None,
|
||||
encrypt: bool = False,
|
||||
mime: Optional[str] = None,
|
||||
filename: Optional[str] = None,
|
||||
encrypt: bool = False,
|
||||
monitor: Optional[nio.TransferMonitor] = None,
|
||||
) -> UploadReturn:
|
||||
|
||||
mime = mime or await utils.guess_mime(data)
|
||||
|
@ -618,6 +628,7 @@ class MatrixClient(nio.AsyncClient):
|
|||
"application/octet-stream" if encrypt else mime,
|
||||
filename,
|
||||
encrypt,
|
||||
monitor,
|
||||
)
|
||||
|
||||
if isinstance(response, nio.UploadError):
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import asyncio
|
||||
import re
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timedelta
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, List, Optional, Tuple, Type, Union
|
||||
from uuid import UUID
|
||||
|
@ -114,12 +114,16 @@ class UploadStatus(AutoStrEnum):
|
|||
|
||||
@dataclass
|
||||
class Upload(ModelItem):
|
||||
uuid: UUID = field()
|
||||
task: asyncio.Task = field()
|
||||
filepath: Path = field()
|
||||
uuid: UUID = field()
|
||||
task: asyncio.Task = field()
|
||||
filepath: Path = field()
|
||||
|
||||
total_size: int = 0
|
||||
uploaded: int = 0
|
||||
speed: float = 0
|
||||
time_left: Optional[timedelta] = None
|
||||
|
||||
status: UploadStatus = UploadStatus.Uploading
|
||||
total_size: int = 0
|
||||
uploaded: int = 0
|
||||
error: OptionalExceptionType = type(None)
|
||||
error_args: Tuple[Any, ...] = ()
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import inspect
|
|||
import io
|
||||
import logging as log
|
||||
import xml.etree.cElementTree as xml_etree # FIXME: bandit warning
|
||||
from datetime import timedelta
|
||||
from enum import Enum
|
||||
from enum import auto as autostr
|
||||
from pathlib import Path
|
||||
|
@ -140,6 +141,9 @@ def serialize_value_for_qml(value: Any) -> Any:
|
|||
if isinstance(value, UUID):
|
||||
return str(value)
|
||||
|
||||
if isinstance(value, timedelta):
|
||||
return value.total_seconds() * 1000
|
||||
|
||||
if inspect.isclass(value):
|
||||
return value.__name__
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ Rectangle {
|
|||
.arg(fileName) :
|
||||
|
||||
model.error === "IsADirectoryError" ?
|
||||
qsTr("Can't upload folders: %1")
|
||||
qsTr("Can't upload folders, need a file: %1")
|
||||
.arg(filePath) :
|
||||
|
||||
model.error === "FileNotFoundError" ?
|
||||
|
@ -128,6 +128,13 @@ Rectangle {
|
|||
|
||||
readonly property string filePath:
|
||||
model.filepath.replace(/^file:\/\//, "")
|
||||
|
||||
HoverHandler { id: statusLabelHover }
|
||||
|
||||
HToolTip {
|
||||
text: parent.truncated ? parent.text : ""
|
||||
visible: text && statusLabelHover.hovered
|
||||
}
|
||||
}
|
||||
|
||||
HSpacer {}
|
||||
|
@ -135,7 +142,11 @@ Rectangle {
|
|||
HLabel {
|
||||
id: uploadCountLabel
|
||||
visible: Layout.preferredWidth > 0
|
||||
text: qsTr("%1")
|
||||
text: qsTr("-%1 %2/s %3/%4")
|
||||
.arg(model.time_left ?
|
||||
Utils.formatDuration(msLeft) : "∞")
|
||||
.arg(CppUtils.formattedBytes(model.speed))
|
||||
.arg(CppUtils.formattedBytes(uploaded))
|
||||
.arg(CppUtils.formattedBytes(model.total_size))
|
||||
|
||||
topPadding: theme.spacing / 2
|
||||
|
@ -146,6 +157,12 @@ Rectangle {
|
|||
Layout.preferredWidth:
|
||||
model.status === "Uploading" ? implicitWidth : 0
|
||||
|
||||
property int msLeft: model.time_left || -1
|
||||
property int uploaded: model.uploaded
|
||||
|
||||
Behavior on msLeft { HNumberAnimation { duration: 1000 } }
|
||||
Behavior on uploaded { HNumberAnimation { duration: 1000 }}
|
||||
|
||||
Behavior on Layout.preferredWidth { HNumberAnimation {} }
|
||||
}
|
||||
|
||||
|
@ -153,20 +170,15 @@ Rectangle {
|
|||
onTapped: if (model.status !== "Error")
|
||||
statusLabel.expand = ! statusLabel.expand
|
||||
}
|
||||
|
||||
HoverHandler { id: infoRowHover }
|
||||
|
||||
HToolTip {
|
||||
id: statusToolTip
|
||||
text: statusLabel.truncated ? statusLabel.text : ""
|
||||
visible: text && infoRowHover.hovered
|
||||
}
|
||||
}
|
||||
|
||||
HProgressBar {
|
||||
id: progressBar
|
||||
visible: Layout.maximumHeight !== 0
|
||||
indeterminate: true
|
||||
indeterminate: model.status !== "Uploading"
|
||||
value: model.uploaded
|
||||
to: model.total_size
|
||||
|
||||
foregroundColor:
|
||||
model.status === "Error" ?
|
||||
theme.controls.progressBar.errorForeground :
|
||||
|
@ -176,6 +188,7 @@ Rectangle {
|
|||
Layout.maximumHeight:
|
||||
model.status === "Error" && indeterminate ? 0 : -1
|
||||
|
||||
Behavior on value { HNumberAnimation { duration: 1000 } }
|
||||
Behavior on Layout.maximumHeight { HNumberAnimation {} }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user