mkv2cast 1.2.7.post4__py3-none-any.whl
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.
- mkv2cast/__init__.py +77 -0
- mkv2cast/__main__.py +14 -0
- mkv2cast/cli.py +1886 -0
- mkv2cast/config.py +638 -0
- mkv2cast/converter.py +1454 -0
- mkv2cast/history.py +389 -0
- mkv2cast/i18n.py +179 -0
- mkv2cast/integrity.py +176 -0
- mkv2cast/json_progress.py +311 -0
- mkv2cast/locales/de/LC_MESSAGES/mkv2cast.mo +0 -0
- mkv2cast/locales/de/LC_MESSAGES/mkv2cast.po +382 -0
- mkv2cast/locales/en/LC_MESSAGES/mkv2cast.mo +0 -0
- mkv2cast/locales/en/LC_MESSAGES/mkv2cast.po +382 -0
- mkv2cast/locales/es/LC_MESSAGES/mkv2cast.mo +0 -0
- mkv2cast/locales/es/LC_MESSAGES/mkv2cast.po +382 -0
- mkv2cast/locales/fr/LC_MESSAGES/mkv2cast.mo +0 -0
- mkv2cast/locales/fr/LC_MESSAGES/mkv2cast.po +430 -0
- mkv2cast/locales/it/LC_MESSAGES/mkv2cast.mo +0 -0
- mkv2cast/locales/it/LC_MESSAGES/mkv2cast.po +382 -0
- mkv2cast/notifications.py +196 -0
- mkv2cast/pipeline.py +641 -0
- mkv2cast/ui/__init__.py +26 -0
- mkv2cast/ui/legacy_ui.py +136 -0
- mkv2cast/ui/rich_ui.py +462 -0
- mkv2cast/ui/simple_rich.py +243 -0
- mkv2cast/watcher.py +293 -0
- mkv2cast-1.2.7.post4.dist-info/METADATA +1411 -0
- mkv2cast-1.2.7.post4.dist-info/RECORD +31 -0
- mkv2cast-1.2.7.post4.dist-info/WHEEL +4 -0
- mkv2cast-1.2.7.post4.dist-info/entry_points.txt +2 -0
- mkv2cast-1.2.7.post4.dist-info/licenses/LICENSE +50 -0
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
# Italian translations for mkv2cast
|
|
2
|
+
# Copyright (C) 2024-2026 voldardard
|
|
3
|
+
# This file is distributed under the GPL-3.0 license.
|
|
4
|
+
#
|
|
5
|
+
msgid ""
|
|
6
|
+
msgstr ""
|
|
7
|
+
"Project-Id-Version: mkv2cast 1.1.0\n"
|
|
8
|
+
"Report-Msgid-Bugs-To: https://github.com/voldardard/mkv2cast/issues\n"
|
|
9
|
+
"POT-Creation-Date: 2026-01-18 00:00+0000\n"
|
|
10
|
+
"PO-Revision-Date: 2026-01-18 00:00+0000\n"
|
|
11
|
+
"Last-Translator: voldardard\n"
|
|
12
|
+
"Language-Team: Italian\n"
|
|
13
|
+
"Language: it\n"
|
|
14
|
+
"MIME-Version: 1.0\n"
|
|
15
|
+
"Content-Type: text/plain; charset=UTF-8\n"
|
|
16
|
+
"Content-Transfer-Encoding: 8bit\n"
|
|
17
|
+
|
|
18
|
+
# General
|
|
19
|
+
msgid "Processing file: {filename}"
|
|
20
|
+
msgstr "Elaborazione file: {filename}"
|
|
21
|
+
|
|
22
|
+
msgid "Conversion complete"
|
|
23
|
+
msgstr "Conversione completata"
|
|
24
|
+
|
|
25
|
+
msgid "Conversion failed"
|
|
26
|
+
msgstr "Conversione fallita"
|
|
27
|
+
|
|
28
|
+
msgid "Skipped: {reason}"
|
|
29
|
+
msgstr "Saltato: {reason}"
|
|
30
|
+
|
|
31
|
+
msgid "No MKV files to process."
|
|
32
|
+
msgstr "Nessun file MKV da elaborare."
|
|
33
|
+
|
|
34
|
+
msgid "Backend selected"
|
|
35
|
+
msgstr "Backend selezionato"
|
|
36
|
+
|
|
37
|
+
# Progress
|
|
38
|
+
msgid "Checking integrity..."
|
|
39
|
+
msgstr "Verifica integrità..."
|
|
40
|
+
|
|
41
|
+
msgid "Encoding..."
|
|
42
|
+
msgstr "Codifica..."
|
|
43
|
+
|
|
44
|
+
msgid "Waiting for file stability..."
|
|
45
|
+
msgstr "Attesa stabilità del file..."
|
|
46
|
+
|
|
47
|
+
msgid "Done"
|
|
48
|
+
msgstr "Fatto"
|
|
49
|
+
|
|
50
|
+
msgid "Failed"
|
|
51
|
+
msgstr "Fallito"
|
|
52
|
+
|
|
53
|
+
msgid "Skipped"
|
|
54
|
+
msgstr "Saltato"
|
|
55
|
+
|
|
56
|
+
# Summary
|
|
57
|
+
msgid "Summary"
|
|
58
|
+
msgstr "Riepilogo"
|
|
59
|
+
|
|
60
|
+
msgid "Total files seen"
|
|
61
|
+
msgstr "File totali visti"
|
|
62
|
+
|
|
63
|
+
msgid "Transcoded OK"
|
|
64
|
+
msgstr "Transcodificati OK"
|
|
65
|
+
|
|
66
|
+
msgid "Total time"
|
|
67
|
+
msgstr "Tempo totale"
|
|
68
|
+
|
|
69
|
+
# Notifications
|
|
70
|
+
msgid "mkv2cast - Conversion Complete"
|
|
71
|
+
msgstr "mkv2cast - Conversione completata"
|
|
72
|
+
|
|
73
|
+
msgid "Successfully converted 1 file in {time}"
|
|
74
|
+
msgstr "1 file convertito con successo in {time}"
|
|
75
|
+
|
|
76
|
+
msgid "Successfully converted {count} files in {time}"
|
|
77
|
+
msgstr "{count} file convertiti con successo in {time}"
|
|
78
|
+
|
|
79
|
+
msgid "mkv2cast - Conversion Failed"
|
|
80
|
+
msgstr "mkv2cast - Conversione fallita"
|
|
81
|
+
|
|
82
|
+
msgid "Failed to convert 1 file"
|
|
83
|
+
msgstr "Impossibile convertire 1 file"
|
|
84
|
+
|
|
85
|
+
msgid "Failed to convert {count} files"
|
|
86
|
+
msgstr "Impossibile convertire {count} file"
|
|
87
|
+
|
|
88
|
+
msgid "mkv2cast - Processing Complete"
|
|
89
|
+
msgstr "mkv2cast - Elaborazione completata"
|
|
90
|
+
|
|
91
|
+
msgid "{count} converted"
|
|
92
|
+
msgstr "{count} convertito/i"
|
|
93
|
+
|
|
94
|
+
msgid "{count} failed"
|
|
95
|
+
msgstr "{count} fallito/i"
|
|
96
|
+
|
|
97
|
+
msgid "{count} skipped"
|
|
98
|
+
msgstr "{count} saltato/i"
|
|
99
|
+
|
|
100
|
+
msgid "mkv2cast - Interrupted"
|
|
101
|
+
msgstr "mkv2cast - Interrotto"
|
|
102
|
+
|
|
103
|
+
msgid "Processing was interrupted by user"
|
|
104
|
+
msgstr "L'elaborazione è stata interrotta dall'utente"
|
|
105
|
+
|
|
106
|
+
# Errors
|
|
107
|
+
msgid "File not found"
|
|
108
|
+
msgstr "File non trovato"
|
|
109
|
+
|
|
110
|
+
msgid "Only .mkv files supported"
|
|
111
|
+
msgstr "Solo file .mkv supportati"
|
|
112
|
+
|
|
113
|
+
msgid "integrity check failed"
|
|
114
|
+
msgstr "verifica integrità fallita"
|
|
115
|
+
|
|
116
|
+
msgid "compatible"
|
|
117
|
+
msgstr "compatibile"
|
|
118
|
+
|
|
119
|
+
# CLI
|
|
120
|
+
msgid "Smart MKV -> Cast compatible converter with VAAPI/QSV hardware acceleration."
|
|
121
|
+
msgstr "Convertitore intelligente MKV -> Cast con accelerazione hardware VAAPI/QSV."
|
|
122
|
+
|
|
123
|
+
msgid "Optional .mkv file to process"
|
|
124
|
+
msgstr "File .mkv opzionale da elaborare"
|
|
125
|
+
|
|
126
|
+
msgid "Output settings"
|
|
127
|
+
msgstr "Impostazioni output"
|
|
128
|
+
|
|
129
|
+
msgid "Scan settings"
|
|
130
|
+
msgstr "Impostazioni scansione"
|
|
131
|
+
|
|
132
|
+
msgid "Debug/test"
|
|
133
|
+
msgstr "Debug/test"
|
|
134
|
+
|
|
135
|
+
msgid "Enable debug output"
|
|
136
|
+
msgstr "Abilita output di debug"
|
|
137
|
+
|
|
138
|
+
msgid "Dry run"
|
|
139
|
+
msgstr "Modalità simulazione"
|
|
140
|
+
|
|
141
|
+
msgid "Codec decisions"
|
|
142
|
+
msgstr "Decisioni codec"
|
|
143
|
+
|
|
144
|
+
msgid "Encoding quality"
|
|
145
|
+
msgstr "Qualità codifica"
|
|
146
|
+
|
|
147
|
+
msgid "Hardware acceleration"
|
|
148
|
+
msgstr "Accelerazione hardware"
|
|
149
|
+
|
|
150
|
+
msgid "Integrity checks"
|
|
151
|
+
msgstr "Verifiche integrità"
|
|
152
|
+
|
|
153
|
+
msgid "UI settings"
|
|
154
|
+
msgstr "Impostazioni interfaccia"
|
|
155
|
+
|
|
156
|
+
msgid "Pipeline mode"
|
|
157
|
+
msgstr "Modalità pipeline"
|
|
158
|
+
|
|
159
|
+
msgid "Parallelism"
|
|
160
|
+
msgstr "Parallelismo"
|
|
161
|
+
|
|
162
|
+
msgid "Notifications"
|
|
163
|
+
msgstr "Notifiche"
|
|
164
|
+
|
|
165
|
+
msgid "Send desktop notification when done (default: enabled)"
|
|
166
|
+
msgstr "Invia notifica desktop al termine (default: abilitato)"
|
|
167
|
+
|
|
168
|
+
msgid "Disable desktop notifications"
|
|
169
|
+
msgstr "Disabilita notifiche desktop"
|
|
170
|
+
|
|
171
|
+
msgid "Internationalization"
|
|
172
|
+
msgstr "Internazionalizzazione"
|
|
173
|
+
|
|
174
|
+
msgid "Force language (default: auto-detect)"
|
|
175
|
+
msgstr "Forza lingua (default: auto-rilevamento)"
|
|
176
|
+
|
|
177
|
+
msgid "Utility commands"
|
|
178
|
+
msgstr "Comandi utilità"
|
|
179
|
+
|
|
180
|
+
# Utility
|
|
181
|
+
msgid "Requirements Check"
|
|
182
|
+
msgstr "Verifica requisiti"
|
|
183
|
+
|
|
184
|
+
msgid "System requirements"
|
|
185
|
+
msgstr "Requisiti di sistema"
|
|
186
|
+
|
|
187
|
+
msgid "mandatory"
|
|
188
|
+
msgstr "obbligatorio"
|
|
189
|
+
|
|
190
|
+
msgid "Optional dependencies"
|
|
191
|
+
msgstr "Dipendenze opzionali"
|
|
192
|
+
|
|
193
|
+
msgid "All requirements satisfied"
|
|
194
|
+
msgstr "Tutti i requisiti soddisfatti"
|
|
195
|
+
|
|
196
|
+
msgid "Some requirements missing"
|
|
197
|
+
msgstr "Alcuni requisiti mancanti"
|
|
198
|
+
|
|
199
|
+
msgid "directories"
|
|
200
|
+
msgstr "directory"
|
|
201
|
+
|
|
202
|
+
msgid "User directories"
|
|
203
|
+
msgstr "Directory utente"
|
|
204
|
+
|
|
205
|
+
msgid "Removed"
|
|
206
|
+
msgstr "Rimosso"
|
|
207
|
+
|
|
208
|
+
msgid "temp files"
|
|
209
|
+
msgstr "file temporanei"
|
|
210
|
+
|
|
211
|
+
msgid "log files older than"
|
|
212
|
+
msgstr "file log più vecchi di"
|
|
213
|
+
|
|
214
|
+
msgid "days"
|
|
215
|
+
msgstr "giorni"
|
|
216
|
+
|
|
217
|
+
msgid "history entries"
|
|
218
|
+
msgstr "voci cronologia"
|
|
219
|
+
|
|
220
|
+
msgid "No conversion history found."
|
|
221
|
+
msgstr "Nessuna cronologia conversioni trovata."
|
|
222
|
+
|
|
223
|
+
msgid "Recent conversions"
|
|
224
|
+
msgstr "Conversioni recenti"
|
|
225
|
+
|
|
226
|
+
msgid "last"
|
|
227
|
+
msgstr "ultime"
|
|
228
|
+
|
|
229
|
+
msgid "Conversion statistics"
|
|
230
|
+
msgstr "Statistiche conversione"
|
|
231
|
+
|
|
232
|
+
msgid "Total conversions"
|
|
233
|
+
msgstr "Conversioni totali"
|
|
234
|
+
|
|
235
|
+
msgid "Average encode time"
|
|
236
|
+
msgstr "Tempo medio codifica"
|
|
237
|
+
|
|
238
|
+
msgid "Total encode time"
|
|
239
|
+
msgstr "Tempo totale codifica"
|
|
240
|
+
|
|
241
|
+
msgid "Stopping"
|
|
242
|
+
msgstr "Arresto"
|
|
243
|
+
|
|
244
|
+
msgid "processes"
|
|
245
|
+
msgstr "processi"
|
|
246
|
+
|
|
247
|
+
msgid "All processes stopped"
|
|
248
|
+
msgstr "Tutti i processi arrestati"
|
|
249
|
+
|
|
250
|
+
# Pipeline mode strings
|
|
251
|
+
msgid "Backend"
|
|
252
|
+
msgstr "Backend"
|
|
253
|
+
|
|
254
|
+
msgid "Workers"
|
|
255
|
+
msgstr "Worker"
|
|
256
|
+
|
|
257
|
+
msgid "encode"
|
|
258
|
+
msgstr "codifica"
|
|
259
|
+
|
|
260
|
+
msgid "integrity"
|
|
261
|
+
msgstr "integrità"
|
|
262
|
+
|
|
263
|
+
msgid "Files"
|
|
264
|
+
msgstr "File"
|
|
265
|
+
|
|
266
|
+
msgid "to process"
|
|
267
|
+
msgstr "da elaborare"
|
|
268
|
+
|
|
269
|
+
msgid "Found"
|
|
270
|
+
msgstr "Trovati"
|
|
271
|
+
|
|
272
|
+
msgid "file(s) to process"
|
|
273
|
+
msgstr "file da elaborare"
|
|
274
|
+
|
|
275
|
+
msgid "Converted"
|
|
276
|
+
msgstr "Convertiti"
|
|
277
|
+
|
|
278
|
+
# Rich UI strings
|
|
279
|
+
msgid "SKIP"
|
|
280
|
+
msgstr "SALTATO"
|
|
281
|
+
|
|
282
|
+
msgid "DONE"
|
|
283
|
+
msgstr "FATTO"
|
|
284
|
+
|
|
285
|
+
msgid "FAIL"
|
|
286
|
+
msgstr "FALLITO"
|
|
287
|
+
|
|
288
|
+
msgid "QUEUE"
|
|
289
|
+
msgstr "CODA"
|
|
290
|
+
|
|
291
|
+
msgid "CHECK"
|
|
292
|
+
msgstr "VERIF"
|
|
293
|
+
|
|
294
|
+
msgid "ENCODE"
|
|
295
|
+
msgstr "CODIF"
|
|
296
|
+
|
|
297
|
+
msgid "int"
|
|
298
|
+
msgstr "ver"
|
|
299
|
+
|
|
300
|
+
msgid "enc"
|
|
301
|
+
msgstr "cod"
|
|
302
|
+
|
|
303
|
+
msgid "tot"
|
|
304
|
+
msgstr "tot"
|
|
305
|
+
|
|
306
|
+
msgid "error"
|
|
307
|
+
msgstr "errore"
|
|
308
|
+
|
|
309
|
+
msgid "check"
|
|
310
|
+
msgstr "verif"
|
|
311
|
+
|
|
312
|
+
msgid "in queue"
|
|
313
|
+
msgstr "in coda"
|
|
314
|
+
|
|
315
|
+
msgid "Waiting for check"
|
|
316
|
+
msgstr "In attesa di verifica"
|
|
317
|
+
|
|
318
|
+
msgid "file(s)"
|
|
319
|
+
msgstr "file"
|
|
320
|
+
|
|
321
|
+
msgid "Initializing..."
|
|
322
|
+
msgstr "Inizializzazione..."
|
|
323
|
+
|
|
324
|
+
msgid "output exists"
|
|
325
|
+
msgstr "output esistente"
|
|
326
|
+
|
|
327
|
+
msgid "tmp exists"
|
|
328
|
+
msgstr "file temp esistente"
|
|
329
|
+
|
|
330
|
+
msgid "dryrun"
|
|
331
|
+
msgstr "simulazione"
|
|
332
|
+
|
|
333
|
+
msgid "integrity failed"
|
|
334
|
+
msgstr "integrità fallita"
|
|
335
|
+
|
|
336
|
+
msgid "integrity error"
|
|
337
|
+
msgstr "errore integrità"
|
|
338
|
+
|
|
339
|
+
msgid "analysis error"
|
|
340
|
+
msgstr "errore analisi"
|
|
341
|
+
|
|
342
|
+
msgid "encode error"
|
|
343
|
+
msgstr "errore codifica"
|
|
344
|
+
|
|
345
|
+
msgid "move error"
|
|
346
|
+
msgstr "errore spostamento"
|
|
347
|
+
|
|
348
|
+
msgid "interrupted"
|
|
349
|
+
msgstr "interrotto"
|
|
350
|
+
|
|
351
|
+
msgid "OK"
|
|
352
|
+
msgstr "OK"
|
|
353
|
+
|
|
354
|
+
msgid "in"
|
|
355
|
+
msgstr "in"
|
|
356
|
+
|
|
357
|
+
msgid "FAILED"
|
|
358
|
+
msgstr "FALLITO"
|
|
359
|
+
|
|
360
|
+
msgid "Already compatible"
|
|
361
|
+
msgstr "Già compatibile"
|
|
362
|
+
|
|
363
|
+
# Multi-user cleanup
|
|
364
|
+
msgid "Running as root - cleaning tmp for all users..."
|
|
365
|
+
msgstr "Esecuzione come root - pulizia tmp per tutti gli utenti..."
|
|
366
|
+
|
|
367
|
+
msgid "Running as root - cleaning logs for all users..."
|
|
368
|
+
msgstr "Esecuzione come root - pulizia log per tutti gli utenti..."
|
|
369
|
+
|
|
370
|
+
msgid "files removed"
|
|
371
|
+
msgstr "file rimossi"
|
|
372
|
+
|
|
373
|
+
msgid "Total removed"
|
|
374
|
+
msgstr "Totale rimossi"
|
|
375
|
+
|
|
376
|
+
# AMD AMF
|
|
377
|
+
msgid "AMD AMF quality (0-51)"
|
|
378
|
+
msgstr "Qualità AMD AMF (0-51)"
|
|
379
|
+
|
|
380
|
+
# JSON Progress
|
|
381
|
+
msgid "Output JSON progress for integration with other applications"
|
|
382
|
+
msgstr "Output JSON del progresso per integrazione con altre applicazioni"
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Desktop notification support for mkv2cast.
|
|
3
|
+
|
|
4
|
+
Sends system notifications when conversions complete.
|
|
5
|
+
Uses notify-send (libnotify) as primary method with plyer as fallback.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import shutil
|
|
9
|
+
import subprocess
|
|
10
|
+
from typing import Literal, Optional
|
|
11
|
+
|
|
12
|
+
from mkv2cast.i18n import _
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# Check for notification capabilities
|
|
16
|
+
def _has_notify_send() -> bool:
|
|
17
|
+
"""Check if notify-send is available."""
|
|
18
|
+
return shutil.which("notify-send") is not None
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _has_plyer() -> bool:
|
|
22
|
+
"""Check if plyer is available."""
|
|
23
|
+
try:
|
|
24
|
+
from plyer import notification # noqa: F401
|
|
25
|
+
|
|
26
|
+
return True
|
|
27
|
+
except ImportError:
|
|
28
|
+
return False
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
NOTIFY_SEND_AVAILABLE = _has_notify_send()
|
|
32
|
+
PLYER_AVAILABLE = _has_plyer()
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def send_notification(
|
|
36
|
+
title: str,
|
|
37
|
+
message: str,
|
|
38
|
+
urgency: Literal["low", "normal", "critical"] = "normal",
|
|
39
|
+
icon: str = "video-x-generic",
|
|
40
|
+
timeout: int = 10,
|
|
41
|
+
) -> bool:
|
|
42
|
+
"""
|
|
43
|
+
Send a desktop notification.
|
|
44
|
+
|
|
45
|
+
Tries notify-send first (Linux standard), then falls back to plyer
|
|
46
|
+
if available.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
title: Notification title.
|
|
50
|
+
message: Notification body text.
|
|
51
|
+
urgency: Urgency level - "low", "normal", or "critical".
|
|
52
|
+
icon: Icon name (XDG icon spec) or path.
|
|
53
|
+
timeout: Notification timeout in seconds.
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
True if notification was sent successfully, False otherwise.
|
|
57
|
+
"""
|
|
58
|
+
# Try notify-send first (Linux standard via libnotify)
|
|
59
|
+
if NOTIFY_SEND_AVAILABLE:
|
|
60
|
+
try:
|
|
61
|
+
cmd = [
|
|
62
|
+
"notify-send",
|
|
63
|
+
"--urgency",
|
|
64
|
+
urgency,
|
|
65
|
+
"--app-name",
|
|
66
|
+
"mkv2cast",
|
|
67
|
+
"--icon",
|
|
68
|
+
icon,
|
|
69
|
+
"--expire-time",
|
|
70
|
+
str(timeout * 1000), # Convert to ms
|
|
71
|
+
title,
|
|
72
|
+
message,
|
|
73
|
+
]
|
|
74
|
+
subprocess.run(cmd, check=True, capture_output=True, timeout=5)
|
|
75
|
+
return True
|
|
76
|
+
except (subprocess.CalledProcessError, subprocess.TimeoutExpired):
|
|
77
|
+
pass
|
|
78
|
+
|
|
79
|
+
# Fallback to plyer
|
|
80
|
+
if PLYER_AVAILABLE:
|
|
81
|
+
try:
|
|
82
|
+
from plyer import notification
|
|
83
|
+
|
|
84
|
+
notification.notify(
|
|
85
|
+
title=title,
|
|
86
|
+
message=message,
|
|
87
|
+
app_name="mkv2cast",
|
|
88
|
+
app_icon=icon if icon.startswith("/") else None,
|
|
89
|
+
timeout=timeout,
|
|
90
|
+
)
|
|
91
|
+
return True
|
|
92
|
+
except Exception:
|
|
93
|
+
pass
|
|
94
|
+
|
|
95
|
+
return False
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def notify_success(converted_count: int, total_time: str) -> bool:
|
|
99
|
+
"""
|
|
100
|
+
Send a success notification.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
converted_count: Number of files successfully converted.
|
|
104
|
+
total_time: Total processing time as formatted string.
|
|
105
|
+
|
|
106
|
+
Returns:
|
|
107
|
+
True if notification sent successfully.
|
|
108
|
+
"""
|
|
109
|
+
title = _("mkv2cast - Conversion Complete")
|
|
110
|
+
|
|
111
|
+
if converted_count == 1:
|
|
112
|
+
message = _("Successfully converted 1 file in {time}").format(time=total_time)
|
|
113
|
+
else:
|
|
114
|
+
message = _("Successfully converted {count} files in {time}").format(count=converted_count, time=total_time)
|
|
115
|
+
|
|
116
|
+
return send_notification(title=title, message=message, urgency="normal", icon="dialog-information")
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def notify_failure(failed_count: int, error_summary: Optional[str] = None) -> bool:
|
|
120
|
+
"""
|
|
121
|
+
Send a failure notification.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
failed_count: Number of files that failed.
|
|
125
|
+
error_summary: Optional brief error description.
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
True if notification sent successfully.
|
|
129
|
+
"""
|
|
130
|
+
title = _("mkv2cast - Conversion Failed")
|
|
131
|
+
|
|
132
|
+
if failed_count == 1:
|
|
133
|
+
message = _("Failed to convert 1 file")
|
|
134
|
+
else:
|
|
135
|
+
message = _("Failed to convert {count} files").format(count=failed_count)
|
|
136
|
+
|
|
137
|
+
if error_summary:
|
|
138
|
+
message += f"\n{error_summary}"
|
|
139
|
+
|
|
140
|
+
return send_notification(title=title, message=message, urgency="critical", icon="dialog-error")
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def notify_partial(ok_count: int, failed_count: int, skipped_count: int, total_time: str) -> bool:
|
|
144
|
+
"""
|
|
145
|
+
Send a notification for partial success (some files converted, some failed/skipped).
|
|
146
|
+
|
|
147
|
+
Args:
|
|
148
|
+
ok_count: Number of successful conversions.
|
|
149
|
+
failed_count: Number of failed conversions.
|
|
150
|
+
skipped_count: Number of skipped files.
|
|
151
|
+
total_time: Total processing time as formatted string.
|
|
152
|
+
|
|
153
|
+
Returns:
|
|
154
|
+
True if notification sent successfully.
|
|
155
|
+
"""
|
|
156
|
+
title = _("mkv2cast - Processing Complete")
|
|
157
|
+
|
|
158
|
+
parts = []
|
|
159
|
+
if ok_count > 0:
|
|
160
|
+
parts.append(_("{count} converted").format(count=ok_count))
|
|
161
|
+
if failed_count > 0:
|
|
162
|
+
parts.append(_("{count} failed").format(count=failed_count))
|
|
163
|
+
if skipped_count > 0:
|
|
164
|
+
parts.append(_("{count} skipped").format(count=skipped_count))
|
|
165
|
+
|
|
166
|
+
message = ", ".join(parts)
|
|
167
|
+
message += f" ({total_time})"
|
|
168
|
+
|
|
169
|
+
urgency: Literal["low", "normal", "critical"] = "normal" if failed_count == 0 else "critical"
|
|
170
|
+
icon = "dialog-information" if failed_count == 0 else "dialog-warning"
|
|
171
|
+
|
|
172
|
+
return send_notification(title=title, message=message, urgency=urgency, icon=icon)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def notify_interrupted() -> bool:
|
|
176
|
+
"""Send a notification when processing was interrupted by the user."""
|
|
177
|
+
return send_notification(
|
|
178
|
+
title=_("mkv2cast - Interrupted"),
|
|
179
|
+
message=_("Processing was interrupted by user"),
|
|
180
|
+
urgency="normal",
|
|
181
|
+
icon="dialog-warning",
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def check_notification_support() -> dict:
|
|
186
|
+
"""
|
|
187
|
+
Check available notification methods.
|
|
188
|
+
|
|
189
|
+
Returns:
|
|
190
|
+
Dict with 'notify_send' and 'plyer' boolean keys indicating availability.
|
|
191
|
+
"""
|
|
192
|
+
return {
|
|
193
|
+
"notify_send": NOTIFY_SEND_AVAILABLE,
|
|
194
|
+
"plyer": PLYER_AVAILABLE,
|
|
195
|
+
"any": NOTIFY_SEND_AVAILABLE or PLYER_AVAILABLE,
|
|
196
|
+
}
|