-
-
+
+
+
-
-
+
+
- Windows support is experimental.
-
- If you're not sure, get the Installer file.
-
- The portable version extracts the files into a temporary folder before automatically running it.
+
+ Installer is recommended.
+
+ The portable version does not have automatic updates.
+
+ Varia may trigger a safety warning on Windows because it was not signed with a very expensive digital signature.
+
-
-
+
+
-
Download quickly.
@@ -163,7 +169,7 @@
GITHUB®, the GITHUB® logo design, the INVERTOCAT logo design, OCTOCAT®, and the OCTOCAT® logo design are trademarks of GitHub, Inc., registered in the United States and other countries. The OCTOCAT design is the exclusive property of GitHub, Inc and has been federally registered with the United States Copyright Office.
- The download icon used in the Download for Windows section is part of the Feater icons set, licensed under the MIT license. feathericons.com
+ The package icon used in the Download for Windows section is part of the Feather icons set, licensed under the MIT license. feathericons.com
diff --git a/docs/packageIcon.png b/docs/packageIcon.png
new file mode 100644
index 0000000..4cd1911
Binary files /dev/null and b/docs/packageIcon.png differ
diff --git a/docs/style.css b/docs/style.css
index eac5312..1e25e13 100644
--- a/docs/style.css
+++ b/docs/style.css
@@ -118,21 +118,24 @@ p {
}
.linux-instructions {
- max-height: 1000px;
overflow: hidden;
border-radius: 15px;
background: #EBEBEB;
padding: 20px;
filter: drop-shadow(rgba(0, 0, 0, 0.5) 0rem 0.3rem 8px);
width: 800px;
- transition: max-height 0.5s ease-in-out, padding 0.25s ease-in-out, border-radius 0.25s ease-in-out;
- margin: 5px;
+ transition: transform 0.25s ease-in-out, padding 0.25s ease-in-out, max-height 0.25s ease-in-out;
+ transform: scaleY(1);
+ transform-origin: top;
+ display: block;
+ max-height: 1000px;
}
.linux-instructions.hidden {
- max-height: 0;
+ transform: scaleY(0);
+ display: hidden;
+ max-height: 0px;
padding: 0px;
- border-radius: 0px;
}
@media (prefers-color-scheme: dark) {
diff --git a/io.github.giantpinkrobots.varia.json b/io.github.giantpinkrobots.varia.json
index fa388b6..65e6fc6 100644
--- a/io.github.giantpinkrobots.varia.json
+++ b/io.github.giantpinkrobots.varia.json
@@ -1,62 +1,62 @@
{
- "app-id" : "io.github.giantpinkrobots.varia",
- "runtime" : "org.gnome.Platform",
- "runtime-version" : "46",
- "sdk" : "org.gnome.Sdk",
- "command" : "varia",
- "//": "Justifications for the permissions: This program utilizes aria2c, and aria2c requires the networking permission and the xdg-download directory in order to download files. It also has a 'shut down once all downloads are completed' feature that requires access to org.freedesktop.login1.",
- "finish-args" : [
- "--share=network",
- "--share=ipc",
- "--socket=fallback-x11",
- "--device=dri",
- "--socket=wayland",
- "--filesystem=xdg-download",
- "--system-talk-name=org.freedesktop.login1"
- ],
- "cleanup" : [
- "/include",
- "/lib/pkgconfig",
- "/man",
- "/share/doc",
- "/share/gtk-doc",
- "/share/man",
- "/share/pkgconfig",
- "*.la",
- "*.a"
- ],
- "modules" : [
- "./python3-aria2p.json",
- {
- "name" : "aria2",
- "buildsystem" : "autotools",
- "config-opts": [
- "--without-libxml2",
- "--without-sqlite3",
- "--without-appletls",
- "--without-gnutls",
- "--without-libgmp",
- "--without-libnettle",
- "--without-libgcrypt",
- "--without-libssh2",
- "--without-cppunit",
- "--without-libz",
- "--without-libcunit",
- "--without-libcares",
- "--without-libaria2",
- "--disable-nls",
- "--with-openssl",
- "--disable-ftp"
- ],
- "sources" : [
- {
- "type" : "archive",
- "url" : "https://github.com/aria2/aria2/releases/download/release-1.37.0/aria2-1.37.0.tar.xz",
- "sha256" : "60a420ad7085eb616cb6e2bdf0a7206d68ff3d37fb5a956dc44242eb2f79b66b"
- }
- ]
- },
- {
+ "id" : "io.github.giantpinkrobots.varia",
+ "runtime" : "org.gnome.Platform",
+ "runtime-version" : "47",
+ "sdk" : "org.gnome.Sdk",
+ "command" : "varia",
+ "//" : "Justifications for the permissions: This program utilizes aria2c, and aria2c requires the networking permission and the xdg-download directory in order to download files. It also has a 'shut down once all downloads are completed' feature that requires access to org.freedesktop.login1.",
+ "finish-args" : [
+ "--share=network",
+ "--share=ipc",
+ "--socket=fallback-x11",
+ "--device=dri",
+ "--socket=wayland",
+ "--filesystem=xdg-download",
+ "--system-talk-name=org.freedesktop.login1"
+ ],
+ "cleanup" : [
+ "/include",
+ "/lib/pkgconfig",
+ "/man",
+ "/share/doc",
+ "/share/gtk-doc",
+ "/share/man",
+ "/share/pkgconfig",
+ "*.la",
+ "*.a"
+ ],
+ "modules" : [
+ "./python3-aria2p.json",
+ {
+ "name" : "aria2",
+ "buildsystem" : "autotools",
+ "config-opts" : [
+ "--without-libxml2",
+ "--without-sqlite3",
+ "--without-appletls",
+ "--without-gnutls",
+ "--without-libgmp",
+ "--without-libnettle",
+ "--without-libgcrypt",
+ "--without-libssh2",
+ "--without-cppunit",
+ "--without-libz",
+ "--without-libcunit",
+ "--without-libcares",
+ "--without-libaria2",
+ "--disable-nls",
+ "--with-openssl",
+ "--disable-ftp"
+ ],
+ "sources" : [
+ {
+ "type" : "archive",
+ "url" : "https://github.com/aria2/aria2/releases/download/release-1.37.0/aria2-1.37.0.tar.xz",
+ "sha256" : "60a420ad7085eb616cb6e2bdf0a7206d68ff3d37fb5a956dc44242eb2f79b66b"
+ }
+ ]
+ },
+ {
"name" : "varia",
"builddir" : true,
"buildsystem" : "meson",
@@ -67,5 +67,5 @@
}
]
}
- ]
-}
\ No newline at end of file
+ ]
+}
diff --git a/meson.build b/meson.build
index b37079d..df608bc 100644
--- a/meson.build
+++ b/meson.build
@@ -1,5 +1,5 @@
project('varia',
- version: 'v2024.5.7',
+ version: 'v2024.11.7',
meson_version: '>= 0.62.0',
default_options: [ 'warning_level=2', 'werror=false', ],
)
diff --git a/po/LINGUAS b/po/LINGUAS
index 3f98100..1f132c7 100644
--- a/po/LINGUAS
+++ b/po/LINGUAS
@@ -1,3 +1,4 @@
+bg
de
hi
it
@@ -13,3 +14,4 @@ nb
ja
es
fa
+zh_CN
diff --git a/po/Varia.pot b/po/Varia.pot
index 4dc502f..f9f6a14 100644
--- a/po/Varia.pot
+++ b/po/Varia.pot
@@ -314,6 +314,52 @@ msgstr ""
msgid "Remove cookies.txt"
msgstr ""
+msgid "remaining"
+msgstr ""
+
+msgid "Start in Background Mode"
+msgstr ""
+
+msgid "Remote Timestamp"
+msgstr ""
+
+msgid "Torrent"
+msgstr ""
+
+#Updater
+msgid "Checking for updates..."
+msgstr ""
+
+msgid "A new version of Varia is available. Do you want to update?"
+msgstr ""
+
+msgid "Update available"
+msgstr ""
+
+msgid "Update"
+msgstr ""
+
+msgid "Downloading update..."
+msgstr ""
+
+msgid "Download failed."
+msgstr ""
+
+msgid "Yes"
+msgstr ""
+
+msgid "No"
+msgstr ""
+
+msgid "Automatically Check for Updates"
+msgstr ""
+
+msgid "Check Now"
+msgstr ""
+
+msgid "Do you want to check for updates on startup?"
+msgstr ""
+
#: src/gtk/help-overlay.ui:11
msgctxt "shortcut window"
msgid "General"
diff --git a/po/bg.po b/po/bg.po
new file mode 100644
index 0000000..2d223f6
--- /dev/null
+++ b/po/bg.po
@@ -0,0 +1,348 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR
, YEAR.
+# twlvnn kraftwerk , 2024.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: varia\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-11-30 03:17+0300\n"
+"PO-Revision-Date: 2024-09-22 12:29+0200\n"
+"Last-Translator: twlvnn kraftwerk \n"
+"Language-Team: Bulgarian \n"
+"Language: bg\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+"X-Generator: Gtranslator 46.1\n"
+
+#. Translators: Do NOT translate or localize the application name.
+#: data/io.github.giantpinkrobots.varia.desktop.in:4
+#: data/io.github.giantpinkrobots.varia.metainfo.xml.in:3
+msgid "Varia"
+msgstr "Varia"
+
+#. Translators: These are search terms to find this application. Do NOT translate or localize the semicolons. The list MUST also end with a semicolon.
+#: data/io.github.giantpinkrobots.varia.desktop.in:11
+msgid "varia;aria;download;manager;"
+msgstr "мениджър за изтегляне;изтегляне;мениджър;"
+
+#: data/io.github.giantpinkrobots.varia.metainfo.xml.in:4
+msgid "Download manager based on aria2"
+msgstr "Мениджър за изтегляне основан на aria2"
+
+#: data/io.github.giantpinkrobots.varia.metainfo.xml.in:16
+msgid ""
+"Varia is a download manager based on aria2 that utilizes GTK4 and Libadwaita "
+"to provide a easy to use interface that integrates well with the GNOME "
+"desktop."
+msgstr ""
+"„Varia“ е мениджър за изтегляне основан на aria2, който използва GTK4 и "
+"Libadwaita, за да осигури лесен за използване потребителски интерфейс, който "
+"се интегрира добре с GNOME работната среда."
+
+#: src/variamain.py:45
+msgid "This is not a valid URL."
+msgstr "Това не е правилен адрес."
+
+#: src/variamain.py:125
+msgid "All"
+msgstr "Всички"
+
+#: src/variamain.py:137
+msgid "In Progress"
+msgstr "Изпълнява се"
+
+#: src/variamain.py:148
+msgid "Completed"
+msgstr "Завършено"
+
+#: src/variamain.py:171
+msgid "About Varia"
+msgstr "Относно „Varia“"
+
+#: src/variamain.py:177
+msgid "URL"
+msgstr "URL адрес, или само адрес"
+
+#: src/variamain.py:178
+msgid "Download"
+msgstr "Изтегляне"
+
+#: src/variamain.py:184
+msgid "Open Download Folder"
+msgstr "Отваряне на изтеглянията"
+
+#: src/variamain.py:196
+msgid "Speed Limit"
+msgstr "Ограничение на скоростта"
+
+#: src/variamain.py:203 src/variamain.py:423
+msgid "Pause All"
+msgstr "Пауза на всички"
+
+#: src/variamain.py:212
+msgid "Speed"
+msgstr "Скорост"
+
+#: src/variamain.py:215
+msgid "Set Speed Limit"
+msgstr "Задаване на ограничение на скоростта"
+
+#: src/variamain.py:216
+msgid "Cancel All"
+msgstr "Отменяне на всички"
+
+#: src/variamain.py:235
+msgid "/s"
+msgstr "/с"
+
+#: src/variamain.py:238
+msgid "No limit"
+msgstr "Без ограничение"
+
+#: src/variamain.py:274
+msgid "Download complete."
+msgstr "Изтеглянето завърши."
+
+#: src/variamain.py:276
+msgid "Download speed is limited."
+msgstr "Скоростта на изтегляне е ограничена."
+
+#: src/variamain.py:277
+msgid "An error occurred:"
+msgstr "Възникна грешка:"
+
+#: src/variamain.py:292
+msgid "MB/s"
+msgstr "МБ/с"
+
+#: src/variamain.py:294
+msgid "KB/s"
+msgstr "КБ/с"
+
+#: src/variamain.py:298
+msgid "0 B/s"
+msgstr "0 Б/с"
+
+#: src/variamain.py:300
+msgid " MB/s"
+msgstr "МБ/с"
+
+#: src/variamain.py:302
+msgid " KB/s"
+msgstr "КБ/с"
+
+#: src/variamain.py:304
+msgid " B/s"
+msgstr "Б/с"
+
+#: src/variamain.py:404
+msgid "Simultaneous Download Amount"
+msgstr "Количество едновременни изтегляния"
+
+#: src/variamain.py:410
+msgid "Resume All"
+msgstr "Пускане на всички"
+
+#: src/variamain.py:443
+msgid "aria2 based download manager utilizing GTK4 and Libadwaita."
+msgstr "Мениджър за изтегляне основан на aria2, използващ GTK4 и Libadwaita."
+
+#: src/variamain.py:777
+msgid "This application relies on the following pieces of software:"
+msgstr "Това приложение разчита на следния софтуер:"
+
+#: src/variamain.py:777
+msgid ""
+"The licenses of all of these pieces of software can be found in the "
+"dependencies_information directory in this application's app directory."
+msgstr ""
+"Лицензите на целия този софтуер можете да намерите в папката "
+"„dependencies_information“ в папката „app“ на това приложение."
+
+#: src/variamain.py:449
+msgid "translator-credits"
+msgstr "twlvnn kraftwerk "
+
+#: src/variamain.py:457
+msgid "Download Directory"
+msgstr "Папка за изтегляне"
+
+#: src/variamain.py:460
+msgid "Change"
+msgstr "Променяне"
+
+#: src/variamain.py:463
+msgid "Speed limited"
+msgstr "Скоростта е ограничена"
+
+#: src/variamain.py:519
+msgid "Authentication"
+msgstr "Удостоверяване"
+
+#: src/variamain.py:532
+msgid "Username"
+msgstr "Потребителско име"
+
+#: src/variamain.py:534
+msgid "Password"
+msgstr "Парола"
+
+#: src/variamain.py:554
+msgid "Authorization failed."
+msgstr "Упълномощяването е неуспешно."
+
+#: src/variamain.py:806
+msgid "Failed to open directory."
+msgstr "Папката не може да бъде отворена."
+
+msgid "Remote Mode"
+msgstr "Режим „Дистанционно“"
+
+msgid "Remote aria2 IP"
+msgstr "Отдалечено aria2 IP"
+
+msgid "Remote aria2 Port"
+msgstr "Отдалечен aria2 порт"
+
+msgid "Remote aria2 RPC Secret"
+msgstr "Отдалечен aria2 RPC Secret"
+
+msgid "Remote Download Location"
+msgstr "Отдалечено място за изтегляне"
+
+msgid "Exiting Varia..."
+msgstr "Спиране на „Varia“…"
+
+msgid "Background Mode"
+msgstr "Фонов режим"
+
+msgid "Continuing the downloads in the background."
+msgstr "Продължаване на изтеглянето във фонов режим."
+
+msgid "Browser Extension"
+msgstr "Браузър разширение"
+
+msgid "Shutdown on Completion"
+msgstr "Изключване при завършване"
+
+msgid "Varia is about to shut down your computer."
+msgstr "„Varia“ ще изключи компютъра ви."
+
+msgid "Press Cancel to cancel and disable."
+msgstr "Натиснете „Отказване“, за да откажете и изключите."
+
+msgid "Cancel"
+msgstr "Отказване"
+
+msgid "Warning"
+msgstr "Предупреждение"
+
+msgid "Monday"
+msgstr "Понеделник"
+
+msgid "Tuesday"
+msgstr "Вторник"
+
+msgid "Wednesday"
+msgstr "Сряда"
+
+msgid "Thursday"
+msgstr "Четвъртък"
+
+msgid "Friday"
+msgstr "Петък"
+
+msgid "Saturday"
+msgstr "Събота"
+
+msgid "Sunday"
+msgstr "Неделя"
+
+msgid "Start (h/m):"
+msgstr "Начало (ч/м):"
+
+msgid "End (h/m):"
+msgstr "Край (ч/м):"
+
+msgid "Scheduler enabled"
+msgstr "Scheduler е активиран"
+
+msgid "Scheduler"
+msgstr "Scheduler"
+
+msgid "Enabled"
+msgstr "Активирано"
+
+msgid "Start downloading in these times"
+msgstr "Стартиране на изтеглянето по това време"
+
+msgid "Stop downloading in these times"
+msgstr "Спиране на изтеглянето по това време"
+
+msgid "Add Timespan"
+msgstr "Добавяне на времеви интервал"
+
+msgid "Seeding"
+msgstr "Разпръскване"
+
+msgid "Failed"
+msgstr "Неуспешен"
+
+msgid "Completion Options"
+msgstr "Настройки за завършване"
+
+msgid "Exit on Completion"
+msgstr "Спиране на програмата при завършване"
+
+msgid "Varia is about to quit."
+msgstr "„Varia“ ще спре."
+
+msgid "Preferences"
+msgstr "Настройки"
+
+msgid "Other"
+msgstr "Друго"
+
+msgid "Basic Settings"
+msgstr "Основни настройки"
+
+msgid "Advanced Settings"
+msgstr "Допълнителни настройки"
+
+msgid "Use cookies.txt"
+msgstr "Използване на бисквитки.txt"
+
+msgid "Import cookies.txt"
+msgstr "Внасяне на бисквитки.txt"
+
+msgid "Remove cookies.txt"
+msgstr "Премахване на бисквитки.txt"
+
+msgid "remaining"
+msgstr "остава"
+
+msgid "Start in Background Mode"
+msgstr "Стартиране във фонов режим"
+
+msgid "Remote Timestamp"
+msgstr "Дата на отдалеченото място"
+
+#: src/gtk/help-overlay.ui:11
+msgctxt "shortcut window"
+msgid "General"
+msgstr "Общи"
+
+#: src/gtk/help-overlay.ui:14
+msgctxt "shortcut window"
+msgid "Show Shortcuts"
+msgstr "Показване на клавишните комбинации"
+
+#: src/gtk/help-overlay.ui:20
+msgctxt "shortcut window"
+msgid "Quit"
+msgstr "Спиране на програмата"
diff --git a/po/es.po b/po/es.po
index bef7bbb..22d674d 100644
--- a/po/es.po
+++ b/po/es.po
@@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-11-30 03:17+0300\n"
-"PO-Revision-Date: 2024-03-29 16:50-0300\n"
+"PO-Revision-Date: 2024-09-23 11:35-0300\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 3.4.2\n"
+"X-Generator: Poedit 3.4.4\n"
#. Translators: Do NOT translate or localize the application name.
#: data/io.github.giantpinkrobots.varia.desktop.in:4
@@ -241,6 +241,96 @@ msgstr "Cancelar"
msgid "Warning"
msgstr "Advertencia"
+msgid "Monday"
+msgstr "Lunes"
+
+msgid "Tuesday"
+msgstr "Martes"
+
+msgid "Wednesday"
+msgstr "Miércoles"
+
+msgid "Thursday"
+msgstr "Jueves"
+
+msgid "Friday"
+msgstr "Viernes"
+
+msgid "Saturday"
+msgstr "Sábado"
+
+msgid "Sunday"
+msgstr "Domingo"
+
+msgid "Start (h/m):"
+msgstr "Inicio (h/m):"
+
+msgid "End (h/m):"
+msgstr "Fin (h/m):"
+
+msgid "Scheduler enabled"
+msgstr "Planificador activado"
+
+msgid "Scheduler"
+msgstr "Planificador"
+
+msgid "Enabled"
+msgstr "Activado"
+
+msgid "Start downloading in these times"
+msgstr "Empezar a descargar en estos tiempos"
+
+msgid "Stop downloading in these times"
+msgstr "Dejar de descargar en estos tiempos"
+
+msgid "Add Timespan"
+msgstr "Añadir intervalo de tiempo"
+
+msgid "Seeding"
+msgstr "Compartiendo"
+
+msgid "Failed"
+msgstr "Fallido"
+
+msgid "Completion Options"
+msgstr "Opciones de finalización"
+
+msgid "Exit on Completion"
+msgstr "Salir al finalizar"
+
+msgid "Varia is about to quit."
+msgstr "Varia está a punto de salir."
+
+msgid "Preferences"
+msgstr "Preferencias"
+
+msgid "Other"
+msgstr "Otras"
+
+msgid "Basic Settings"
+msgstr "Configuración básica"
+
+msgid "Advanced Settings"
+msgstr "Configuración avanzada"
+
+msgid "Use cookies.txt"
+msgstr "Utilizar cookies.txt"
+
+msgid "Import cookies.txt"
+msgstr "Importar cookies.txt"
+
+msgid "Remove cookies.txt"
+msgstr "Eliminar cookies.txt"
+
+msgid "remaining"
+msgstr "restante"
+
+msgid "Start in Background Mode"
+msgstr "Iniciar en segundo plano"
+
+msgid "Remote Timestamp"
+msgstr "Marca de tiempo remota"
+
#: src/gtk/help-overlay.ui:11
msgctxt "shortcut window"
msgid "General"
diff --git a/po/it.po b/po/it.po
index 717e4f1..3647d3a 100644
--- a/po/it.po
+++ b/po/it.po
@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-11-30 03:17+0300\n"
-"PO-Revision-Date: 2024-01-26 17:31+0100\n"
-"Last-Translator: Albano Battistella \n"
+"PO-Revision-Date: 2024-08-24 17:20+0100\n"
+"Last-Translator: Neko the gamer \n"
"Language-Team: Italian \n"
"Language: it\n"
"MIME-Version: 1.0\n"
@@ -25,11 +25,11 @@ msgstr "Varia"
#. Translators: These are search terms to find this application. Do NOT translate or localize the semicolons. The list MUST also end with a semicolon.
#: data/io.github.giantpinkrobots.varia.desktop.in:11
msgid "varia;aria;download;manager;"
-msgstr ""
+msgstr "varia;aria;download;gestore;"
#: data/io.github.giantpinkrobots.varia.metainfo.xml.in:4
msgid "Download manager based on aria2"
-msgstr "Gestore di download basato su aria2"
+msgstr "Gestore download basato su aria2"
#: data/io.github.giantpinkrobots.varia.metainfo.xml.in:16
msgid ""
@@ -45,6 +45,18 @@ msgstr ""
msgid "This is not a valid URL."
msgstr "Questo non è un URL valido."
+#: src/variamain.py:125
+msgid "All"
+msgstr "Tutti"
+
+#: src/variamain.py:137
+msgid "In Progress"
+msgstr "In corso"
+
+#: src/variamain.py:148
+msgid "Completed"
+msgstr "Completati"
+
#: src/variamain.py:171
msgid "About Varia"
msgstr "Informazioni su Varia"
@@ -55,23 +67,23 @@ msgstr "URL"
#: src/variamain.py:178
msgid "Download"
-msgstr "Download"
+msgstr "Scarica"
#: src/variamain.py:184
msgid "Open Download Folder"
-msgstr "Apri la cartella di download"
+msgstr "Apri cartella download"
#: src/variamain.py:196
msgid "Speed Limit"
-msgstr "Limite di velocità"
+msgstr "Limite velocità"
#: src/variamain.py:203 src/variamain.py:423
msgid "Pause All"
-msgstr "Metti tutto in pausa"
+msgstr "Metti in pausa tutti"
#: src/variamain.py:212
msgid "Speed"
-msgstr "vELOCITÀ"
+msgstr "Velocità"
#: src/variamain.py:215
msgid "Set Speed Limit"
@@ -79,7 +91,7 @@ msgstr "Imposta limite di velocità"
#: src/variamain.py:216
msgid "Cancel All"
-msgstr "Annulla tutto"
+msgstr "Cancella tutti"
#: src/variamain.py:235
msgid "/s"
@@ -91,11 +103,11 @@ msgstr "Nessun limite"
#: src/variamain.py:274
msgid "Download complete."
-msgstr "Download completo."
+msgstr "Download completato."
#: src/variamain.py:276
msgid "Download speed is limited."
-msgstr "La velocità di download è limitata."
+msgstr "La velocità del download è limitata"
#: src/variamain.py:277
msgid "An error occurred:"
@@ -125,33 +137,39 @@ msgstr " KB/s"
msgid " B/s"
msgstr " B/s"
+#: src/variamain.py:404
+msgid "Simultaneous Download Amount"
+msgstr "Quantità di download simultanei"
+
#: src/variamain.py:410
msgid "Resume All"
-msgstr "Riprendi tutto"
+msgstr "Riprendi tutti"
#: src/variamain.py:443
msgid "aria2 based download manager utilizing GTK4 and Libadwaita."
-msgstr "Gestore di download basato su aria2 che utilizza GTK4 e Libadwaita."
+msgstr "Gestore di download basato su aria2 e utilizza GTK4 con Libadwaita"
#: src/variamain.py:777
msgid "This application relies on the following pieces of software:"
-msgstr "Questa applicazione si basa sui seguenti software:"
+msgstr "Questa applicazione dipende dai seguenti software:"
#: src/variamain.py:777
msgid "The licenses of all of these pieces of software can be found in the dependencies_information directory in this application's app directory."
-msgstr "Le licenze di tutti questi software si trovano nella directory dependencies_information nella directory dell'app di questa applicazione."
+msgstr "Le licenze di tutti questi software si trovano nella cartella dependencies_information nella cartella dell'app di questa applicazione."
#: src/variamain.py:449
msgid "translator-credits"
-msgstr "Albano Battistella "
+msgstr ""
+"Albano Battistella \n"
+"Neko the gamer "
#: src/variamain.py:457
msgid "Download Directory"
-msgstr "Directory di download"
+msgstr "Cartella download"
#: src/variamain.py:460
msgid "Change"
-msgstr "Modifica"
+msgstr "Cambia"
#: src/variamain.py:463
msgid "Speed limited"
@@ -163,20 +181,147 @@ msgstr "Autenticazione"
#: src/variamain.py:532
msgid "Username"
-msgstr "Nome Utente"
+msgstr "Nome utente"
#: src/variamain.py:534
msgid "Password"
-msgstr "Passwrd"
+msgstr "Password"
#: src/variamain.py:554
msgid "Authorization failed."
msgstr "Autorizzazione fallita."
+#: src/variamain.py:806
+msgid "Failed to open directory."
+msgstr "Impossibile aprire la cartella"
+
+msgid "Remote Mode"
+msgstr "Nodo remoto"
+
+msgid "Remote aria2 IP"
+msgstr "IP remoto aria2"
+
+msgid "Remote aria2 Port"
+msgstr "Porta remota aria2"
+
+msgid "Remote aria2 RPC Secret"
+msgstr "Segreto RPC remoto aria2"
+
+msgid "Remote Download Location"
+msgstr "Posizione download remota"
+
+msgid "Exiting Varia..."
+msgstr "Uscendo da Varia..."
+
+msgid "Background Mode"
+msgstr "Modalità in background"
+
+msgid "Continuing the downloads in the background."
+msgstr "Continua i download in background."
+
+msgid "Browser Extension"
+msgstr "Estensione browser"
+
+msgid "Shutdown on Completion"
+msgstr "Spegni a download completato"
+
+msgid "Varia is about to shut down your computer."
+msgstr "Varia sta per spegnere il tuo computer."
+
+msgid "Press Cancel to cancel and disable."
+msgstr "Premi annulla per annullare e disattivare."
+
+msgid "Cancel"
+msgstr "Annulla"
+
+msgid "Warning"
+msgstr "Attenzione"
+
+msgid "Monday"
+msgstr "Lunedì"
+
+msgid "Tuesday"
+msgstr "Martedì"
+
+msgid "Wednesday"
+msgstr "Mercoledì"
+
+msgid "Thursday"
+msgstr "Giovedì"
+
+msgid "Friday"
+msgstr "Venerdì"
+
+msgid "Saturday"
+msgstr "Sabato"
+
+msgid "Sunday"
+msgstr "Domenica"
+
+msgid "Start (h/m):"
+msgstr "Inizio (h/m):"
+
+msgid "End (h/m):"
+msgstr "Fine (h/m):"
+
+msgid "Scheduler enabled"
+msgstr "Scheduler attivato"
+
+msgid "Scheduler"
+msgstr "Scheduler"
+
+msgid "Enabled"
+msgstr "Attivato"
+
+msgid "Start downloading in these times"
+msgstr "Inizia a scaricare in questo periodo"
+
+msgid "Stop downloading in these times"
+msgstr "Smetti di scaricare in questo periodo"
+
+msgid "Add Timespan"
+msgstr "Aggiungi tempo"
+
+msgid "Seeding"
+msgstr "In seeding"
+
+msgid "Failed"
+msgstr "Falliti"
+
+msgid "Completion Options"
+msgstr "Opzioni completamento"
+
+msgid "Exit on Completion"
+msgstr "Esci al completamento"
+
+msgid "Varia is about to quit."
+msgstr "Varia sta per uscire."
+
+msgid "Preferences"
+msgstr "Preferenze"
+
+msgid "Other"
+msgstr "Altro"
+
+msgid "Basic Settings"
+msgstr "Impostazioni base"
+
+msgid "Advanced Settings"
+msgstr "Impostazioni avanzate"
+
+msgid "Use cookies.txt"
+msgstr "Usa cookies.txt"
+
+msgid "Import cookies.txt"
+msgstr "Importa cookies.txt"
+
+msgid "Remove cookies.txt"
+msgstr "Rimuovi cookies.txt"
+
#: src/gtk/help-overlay.ui:11
msgctxt "shortcut window"
msgid "General"
-msgstr "Generale"
+msgstr "Generali"
#: src/gtk/help-overlay.ui:14
msgctxt "shortcut window"
diff --git a/po/ja.po b/po/ja.po
index 3001832..cb8cfaa 100644
--- a/po/ja.po
+++ b/po/ja.po
@@ -1,7 +1,7 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR , YEAR.
+# The Japanese translation of Varia.
+# Copyright (C) YEAR THE Varia'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the Varia package.
+# Gnuey56 , 2024.
#
#, fuzzy
msgid ""
@@ -9,14 +9,14 @@ msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-11-30 03:17+0300\n"
-"PO-Revision-Date: 2024-03-04 22:21+0900\n"
+"PO-Revision-Date: 2024-09-23 11:46+0900\n"
"Last-Translator: Gnuey56 \n"
"Language-Team: \n"
"Language: ja\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 3.4.2\n"
+"X-Generator: Poedit 3.5\n"
#. Translators: Do NOT translate or localize the application name.
#: data/io.github.giantpinkrobots.varia.desktop.in:4
@@ -27,7 +27,7 @@ msgstr "Varia"
#. Translators: These are search terms to find this application. Do NOT translate or localize the semicolons. The list MUST also end with a semicolon.
#: data/io.github.giantpinkrobots.varia.desktop.in:11
msgid "varia;aria;download;manager;"
-msgstr "varia;aria;download;manager;"
+msgstr "varia;aria;download;manager;ダウンロード;マネージャー;"
#: data/io.github.giantpinkrobots.varia.metainfo.xml.in:4
msgid "Download manager based on aria2"
@@ -77,7 +77,7 @@ msgstr "ダウンロードフォルダを開く"
#: src/variamain.py:196
msgid "Speed Limit"
-msgstr "スピード制限"
+msgstr "速度制限"
#: src/variamain.py:203 src/variamain.py:423
msgid "Pause All"
@@ -85,11 +85,11 @@ msgstr "すべてを一時停止"
#: src/variamain.py:212
msgid "Speed"
-msgstr "スピード"
+msgstr "速度"
#: src/variamain.py:215
msgid "Set Speed Limit"
-msgstr "スピード制限を設定"
+msgstr "速度制限を設定"
#: src/variamain.py:216
msgid "Cancel All"
@@ -109,7 +109,7 @@ msgstr "ダウンロードが完了しました。"
#: src/variamain.py:276
msgid "Download speed is limited."
-msgstr "ダウンロードスピードが制限されています。"
+msgstr "ダウンロード速度が制限されています。"
#: src/variamain.py:277
msgid "An error occurred:"
@@ -178,7 +178,7 @@ msgstr "変更"
#: src/variamain.py:463
msgid "Speed limited"
-msgstr "スピードが制限されています"
+msgstr "速度が制限されています"
#: src/variamain.py:519
msgid "Authentication"
@@ -216,7 +216,7 @@ msgid "Remote Download Location"
msgstr "リモートのダウンロード場所"
msgid "Exiting Varia..."
-msgstr "Varia を終了しています..."
+msgstr "Varia を終了中..."
msgid "Background Mode"
msgstr "バックグラウンドモード"
@@ -227,6 +227,111 @@ msgstr "バックグラウンドでダウンロードを続けます。"
msgid "Browser Extension"
msgstr "ブラウザ拡張機能"
+msgid "Shutdown on Completion"
+msgstr "完了時にシャットダウンする"
+
+msgid "Varia is about to shut down your computer."
+msgstr "Varia はこのコンピューターをシャットダウンしようとしています。"
+
+msgid "Press Cancel to cancel and disable."
+msgstr "キャンセルを押して取り消しできます。"
+
+msgid "Cancel"
+msgstr "キャンセル"
+
+msgid "Warning"
+msgstr "警告"
+
+msgid "Monday"
+msgstr "月曜日"
+
+msgid "Tuesday"
+msgstr "火曜日"
+
+msgid "Wednesday"
+msgstr "水曜日"
+
+msgid "Thursday"
+msgstr "木曜日"
+
+msgid "Friday"
+msgstr "金曜日"
+
+msgid "Saturday"
+msgstr "土曜日"
+
+msgid "Sunday"
+msgstr "日曜日"
+
+msgid "Start (h/m):"
+msgstr "開始 (時/分):"
+
+msgid "End (h/m):"
+msgstr "終了 (時/分):"
+
+msgid "Scheduler enabled"
+msgstr "スケジューラーが有効になっています"
+
+msgid "Scheduler"
+msgstr "スケジューラー"
+
+msgid "Enabled"
+msgstr "有効"
+
+msgid "Start downloading in these times"
+msgstr "これらの時間にダウンロードを開始する"
+
+msgid "Stop downloading in these times"
+msgstr "これらの時間にダウンロードを終了する"
+
+msgid "Add Timespan"
+msgstr "タイムスパンを追加"
+
+msgid "Seeding"
+msgstr "シード中"
+
+msgid "Failed"
+msgstr "失敗"
+
+msgid "Completion Options"
+msgstr "ダウンロード完了時のオプション"
+
+msgid "Exit on Completion"
+msgstr "完了時に終了する"
+
+msgid "Varia is about to quit."
+msgstr "Varia は終了しようとしています。"
+
+msgid "Preferences"
+msgstr "設定"
+
+msgid "Other"
+msgstr "その他"
+
+msgid "Basic Settings"
+msgstr "基本設定"
+
+msgid "Advanced Settings"
+msgstr "詳細設定"
+
+msgid "Use cookies.txt"
+msgstr "cookies.txt を使用"
+
+msgid "Import cookies.txt"
+msgstr "cookies.txt をインポート"
+
+msgid "Remove cookies.txt"
+msgstr "cookies.txt を削除"
+
+msgid "remaining"
+msgstr "残り"
+
+msgid "Start in Background Mode"
+msgstr "バックグラウンドモードで開始"
+
+msgid "Remote Timestamp"
+msgstr "リモートのタイムスタンプ"
+
#: src/gtk/help-overlay.ui:11
msgctxt "shortcut window"
msgid "General"
diff --git a/po/ru.po b/po/ru.po
index 0a52950..0dc969e 100644
--- a/po/ru.po
+++ b/po/ru.po
@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: Varia\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-11-30 03:17+0300\n"
-"PO-Revision-Date: 2024-04-25 1:50+0300\n"
+"PO-Revision-Date: 2024-10-10 18:43+0300\n"
"Last-Translator: Aleksandr Melman \n"
"Language-Team: \n"
"Language: ru\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n"
-"X-Generator: Poedit 3.4.2\n"
+"X-Generator: Poedit 3.5\n"
#. Translators: Do NOT translate or localize the application name.
#: data/io.github.giantpinkrobots.varia.desktop.in:4
@@ -302,6 +302,72 @@ msgstr "Выйти после завершения"
msgid "Varia is about to quit."
msgstr "Приложение завершает работу."
+msgid "Preferences"
+msgstr "Настройки"
+
+msgid "Other"
+msgstr "Другое"
+
+msgid "Basic Settings"
+msgstr "Базовые настройки"
+
+msgid "Advanced Settings"
+msgstr "Дополнительные настройки"
+
+msgid "Use cookies.txt"
+msgstr "Использовать cookies.txt"
+
+msgid "Import cookies.txt"
+msgstr "Импортировать cookies.txt"
+
+msgid "Remove cookies.txt"
+msgstr "Удалить cookies.txt"
+
+msgid "remaining"
+msgstr "осталось"
+
+msgid "Start in Background Mode"
+msgstr "Запуск в фоновом режиме"
+
+msgid "Remote Timestamp"
+msgstr "Удаленная временная метка"
+
+msgid "Torrent"
+msgstr "Торрент"
+
+msgid "Checking for updates..."
+msgstr "Проверка обновлений..."
+
+msgid "A new version of Varia is available. Do you want to update?"
+msgstr "Доступна новая версия Varia. Хотите обновиться?"
+
+msgid "Update available"
+msgstr "Доступно обновление"
+
+msgid "Update"
+msgstr "Обновить"
+
+msgid "Downloading update..."
+msgstr "Загрузка обновления..."
+
+msgid "Download failed."
+msgstr "Не удалось загрузить."
+
+msgid "Yes"
+msgstr "Да"
+
+msgid "No"
+msgstr "Нет"
+
+msgid "Automatically Check for Updates"
+msgstr "Автоматическая проверка обновлений"
+
+msgid "Check Now"
+msgstr "Проверить сейчас"
+
+msgid "Do you want to check for updates on startup?"
+msgstr "Хотите ли вы проверять наличие обновлений при запуске?"
+
#: src/gtk/help-overlay.ui:11
msgctxt "shortcut window"
msgid "General"
diff --git a/po/tr.po b/po/tr.po
index 096f8cc..4b92da4 100644
--- a/po/tr.po
+++ b/po/tr.po
@@ -318,6 +318,51 @@ msgstr "cookies.txt İçe Aktar"
msgid "Remove cookies.txt"
msgstr "cookies.txt'i Sil"
+msgid "remaining"
+msgstr "kaldı"
+
+msgid "Start in Background Mode"
+msgstr "Arkaplan Modunda Başlat"
+
+msgid "Remote Timestamp"
+msgstr "Uzak Zaman Damgası"
+
+msgid "Torrent"
+msgstr "Torrent"
+
+msgid "Checking for updates..."
+msgstr "Güncellemeler denetleniyor..."
+
+msgid "A new version of Varia is available. Do you want to update?"
+msgstr "Varia'nın yeni bir sürümü mevcut. Güncellemek ister misiniz?"
+
+msgid "Update available"
+msgstr "Güncelleme mevcut"
+
+msgid "Update"
+msgstr "Güncelle"
+
+msgid "Downloading update..."
+msgstr "Güncelleme indiriliyor..."
+
+msgid "Download failed."
+msgstr "İndirme başarısız."
+
+msgid "Yes"
+msgstr "Evet"
+
+msgid "No"
+msgstr "Hayır"
+
+msgid "Automatically Check for Updates"
+msgstr "Güncellemeleri Otomatik Olarak Kontrol Et"
+
+msgid "Check Now"
+msgstr "Şimdi Kontrol Et"
+
+msgid "Do you want to check for updates on startup?"
+msgstr "Uygulama başlangıcında güncelleme kontrolü yapılmasını ister misiniz?"
+
#: src/gtk/help-overlay.ui:11
msgctxt "shortcut window"
msgid "General"
diff --git a/po/zh_CN.po b/po/zh_CN.po
new file mode 100644
index 0000000..2b24a6d
--- /dev/null
+++ b/po/zh_CN.po
@@ -0,0 +1,346 @@
+# Chinese translation for Varia.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# lumingzh , 2024.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: varia main\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-11-30 03:17+0300\n"
+"PO-Revision-Date: 2024-09-22 17:57+0800\n"
+"Last-Translator: lumingzh \n"
+"Language-Team: Chinese (China) \n"
+"Language: zh_CN\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Gtranslator 46.1\n"
+
+#. Translators: Do NOT translate or localize the application name.
+#: data/io.github.giantpinkrobots.varia.desktop.in:4
+#: data/io.github.giantpinkrobots.varia.metainfo.xml.in:3
+msgid "Varia"
+msgstr "Varia"
+
+#. Translators: These are search terms to find this application. Do NOT translate or localize the semicolons. The list MUST also end with a semicolon.
+#: data/io.github.giantpinkrobots.varia.desktop.in:11
+msgid "varia;aria;download;manager;"
+msgstr "varia;aria;download;manager;下载;管理器;bt;bittorrent;"
+
+#: data/io.github.giantpinkrobots.varia.metainfo.xml.in:4
+msgid "Download manager based on aria2"
+msgstr "基于 aria2 的下载管理器"
+
+#: data/io.github.giantpinkrobots.varia.metainfo.xml.in:16
+msgid ""
+"Varia is a download manager based on aria2 that utilizes GTK4 and Libadwaita "
+"to provide a easy to use interface that integrates well with the GNOME "
+"desktop."
+msgstr ""
+"Varia 是一个基于 aria2 的下载管理器,利用 GTK4 和 Libadwaita 提供了与 GNOME "
+"桌面良好集成的易用界面。"
+
+#: src/variamain.py:45
+msgid "This is not a valid URL."
+msgstr "这不是有效的 URL。"
+
+#: src/variamain.py:125
+msgid "All"
+msgstr "全部"
+
+#: src/variamain.py:137
+msgid "In Progress"
+msgstr "进行中"
+
+#: src/variamain.py:148
+msgid "Completed"
+msgstr "已完成"
+
+#: src/variamain.py:171
+msgid "About Varia"
+msgstr "关于 Varia"
+
+#: src/variamain.py:177
+msgid "URL"
+msgstr "URL"
+
+#: src/variamain.py:178
+msgid "Download"
+msgstr "下载"
+
+#: src/variamain.py:184
+msgid "Open Download Folder"
+msgstr "打开下载文件夹"
+
+#: src/variamain.py:196
+msgid "Speed Limit"
+msgstr "速度限制"
+
+#: src/variamain.py:203 src/variamain.py:423
+msgid "Pause All"
+msgstr "全部暂停"
+
+#: src/variamain.py:212
+msgid "Speed"
+msgstr "速度"
+
+#: src/variamain.py:215
+msgid "Set Speed Limit"
+msgstr "设定速度限制"
+
+#: src/variamain.py:216
+msgid "Cancel All"
+msgstr "全部取消"
+
+#: src/variamain.py:235
+msgid "/s"
+msgstr "/s"
+
+#: src/variamain.py:238
+msgid "No limit"
+msgstr "无限制"
+
+#: src/variamain.py:274
+msgid "Download complete."
+msgstr "下载完成。"
+
+#: src/variamain.py:276
+msgid "Download speed is limited."
+msgstr "已限制下载速度。"
+
+#: src/variamain.py:277
+msgid "An error occurred:"
+msgstr "发生了错误:"
+
+#: src/variamain.py:292
+msgid "MB/s"
+msgstr "MB/s"
+
+#: src/variamain.py:294
+msgid "KB/s"
+msgstr "KB/s"
+
+#: src/variamain.py:298
+msgid "0 B/s"
+msgstr "0 B/s"
+
+#: src/variamain.py:300
+msgid " MB/s"
+msgstr " MB/s"
+
+#: src/variamain.py:302
+msgid " KB/s"
+msgstr " KB/s"
+
+#: src/variamain.py:304
+msgid " B/s"
+msgstr " B/s"
+
+#: src/variamain.py:404
+msgid "Simultaneous Download Amount"
+msgstr "同时下载数量"
+
+#: src/variamain.py:410
+msgid "Resume All"
+msgstr "全部恢复"
+
+#: src/variamain.py:443
+msgid "aria2 based download manager utilizing GTK4 and Libadwaita."
+msgstr "基于 aria2 使用 GTK4 和 Libadwaita 的下载管理器。"
+
+#: src/variamain.py:777
+msgid "This application relies on the following pieces of software:"
+msgstr "该应用程序依赖于下列软件:"
+
+#: src/variamain.py:777
+msgid ""
+"The licenses of all of these pieces of software can be found in the "
+"dependencies_information directory in this application's app directory."
+msgstr ""
+"所有这些软件的许可证可以在该应用程序应用目录里的 dependencies_information 目"
+"录找到。"
+
+#: src/variamain.py:449
+msgid "translator-credits"
+msgstr "lumingzh , 2024"
+
+#: src/variamain.py:457
+msgid "Download Directory"
+msgstr "下载目录"
+
+#: src/variamain.py:460
+msgid "Change"
+msgstr "更改"
+
+#: src/variamain.py:463
+msgid "Speed limited"
+msgstr "已限制速度"
+
+#: src/variamain.py:519
+msgid "Authentication"
+msgstr "认证"
+
+#: src/variamain.py:532
+msgid "Username"
+msgstr "用户名"
+
+#: src/variamain.py:534
+msgid "Password"
+msgstr "密码"
+
+#: src/variamain.py:554
+msgid "Authorization failed."
+msgstr "认证失败。"
+
+#: src/variamain.py:806
+msgid "Failed to open directory."
+msgstr "打开目录失败。"
+
+msgid "Remote Mode"
+msgstr "远程模式"
+
+msgid "Remote aria2 IP"
+msgstr "远程 aria2 IP"
+
+msgid "Remote aria2 Port"
+msgstr "远程 aria2 端口"
+
+msgid "Remote aria2 RPC Secret"
+msgstr "远程 aria2 RPC 安全"
+
+msgid "Remote Download Location"
+msgstr "远程下载位置"
+
+msgid "Exiting Varia..."
+msgstr "正在退出 Varia…"
+
+msgid "Background Mode"
+msgstr "后台模式"
+
+msgid "Continuing the downloads in the background."
+msgstr "在后台继续下载。"
+
+msgid "Browser Extension"
+msgstr "浏览器扩展"
+
+msgid "Shutdown on Completion"
+msgstr "完成时关机"
+
+msgid "Varia is about to shut down your computer."
+msgstr "Varia 即将关闭您的计算机。"
+
+msgid "Press Cancel to cancel and disable."
+msgstr "按“取消”以取消和禁用。"
+
+msgid "Cancel"
+msgstr "取消"
+
+msgid "Warning"
+msgstr "警告"
+
+msgid "Monday"
+msgstr "星期一"
+
+msgid "Tuesday"
+msgstr "星期二"
+
+msgid "Wednesday"
+msgstr "星期三"
+
+msgid "Thursday"
+msgstr "星期四"
+
+msgid "Friday"
+msgstr "星期五"
+
+msgid "Saturday"
+msgstr "星期六"
+
+msgid "Sunday"
+msgstr "星期日"
+
+msgid "Start (h/m):"
+msgstr "开始(h/m):"
+
+msgid "End (h/m):"
+msgstr "结束(h/m):"
+
+msgid "Scheduler enabled"
+msgstr "调度程序已启用"
+
+msgid "Scheduler"
+msgstr "调度程序"
+
+msgid "Enabled"
+msgstr "已启用"
+
+msgid "Start downloading in these times"
+msgstr "在这些时间开始下载"
+
+msgid "Stop downloading in these times"
+msgstr "在这些时间停止下载"
+
+msgid "Add Timespan"
+msgstr "添加时间间隔"
+
+msgid "Seeding"
+msgstr "正在做种"
+
+msgid "Failed"
+msgstr "已失败"
+
+msgid "Completion Options"
+msgstr "完成选项"
+
+msgid "Exit on Completion"
+msgstr "完成时退出"
+
+msgid "Varia is about to quit."
+msgstr "Varia 即将退出。"
+
+msgid "Preferences"
+msgstr "首选项"
+
+msgid "Other"
+msgstr "其它"
+
+msgid "Basic Settings"
+msgstr "基础设置"
+
+msgid "Advanced Settings"
+msgstr "高级设置"
+
+msgid "Use cookies.txt"
+msgstr "使用 cookies.txt"
+
+msgid "Import cookies.txt"
+msgstr "导入 cookies.txt"
+
+msgid "Remove cookies.txt"
+msgstr "移除 cookies.txt"
+
+msgid "remaining"
+msgstr "剩余时间"
+
+msgid "Start in Background Mode"
+msgstr "以后台模式启动"
+
+msgid "Remote Timestamp"
+msgstr "远程时间戳"
+
+#: src/gtk/help-overlay.ui:11
+msgctxt "shortcut window"
+msgid "General"
+msgstr "常规"
+
+#: src/gtk/help-overlay.ui:14
+msgctxt "shortcut window"
+msgid "Show Shortcuts"
+msgstr "显示快捷键"
+
+#: src/gtk/help-overlay.ui:20
+msgctxt "shortcut window"
+msgid "Quit"
+msgstr "退出"
diff --git a/python3-aria2p.json b/python3-aria2p.json
index ed5cb50..3e872d5 100644
--- a/python3-aria2p.json
+++ b/python3-aria2p.json
@@ -17,18 +17,18 @@
},
{
"type": "file",
- "url": "https://files.pythonhosted.org/packages/ba/06/a07f096c664aeb9f01624f858c3add0a4e913d6c96257acb4fce61e7de14/certifi-2024.2.2-py3-none-any.whl",
- "sha256": "dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"
+ "url": "https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl",
+ "sha256": "922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"
},
{
"type": "file",
- "url": "https://files.pythonhosted.org/packages/63/09/c1bc53dab74b1816a00d8d030de5bf98f724c52c1635e07681d312f20be8/charset-normalizer-3.3.2.tar.gz",
- "sha256": "f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"
+ "url": "https://files.pythonhosted.org/packages/f2/4f/e1808dc01273379acc506d18f1504eb2d299bd4131743b9fc54d7be4df1e/charset_normalizer-3.4.0.tar.gz",
+ "sha256": "223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"
},
{
"type": "file",
- "url": "https://files.pythonhosted.org/packages/c2/e7/a82b05cf63a603df6e68d59ae6a68bf5064484a0718ea5033660af4b54a9/idna-3.6-py3-none-any.whl",
- "sha256": "c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"
+ "url": "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl",
+ "sha256": "946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"
},
{
"type": "file",
@@ -37,18 +37,18 @@
},
{
"type": "file",
- "url": "https://files.pythonhosted.org/packages/70/8e/0e2d847013cb52cd35b38c009bb167a1a26b2ce6cd6965bf26b47bc0bf44/requests-2.31.0-py3-none-any.whl",
- "sha256": "58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"
+ "url": "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl",
+ "sha256": "70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"
},
{
"type": "file",
- "url": "https://files.pythonhosted.org/packages/a2/73/a68704750a7679d0b6d3ad7aa8d4da8e14e151ae82e6fee774e6e0d05ec8/urllib3-2.2.1-py3-none-any.whl",
- "sha256": "450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"
+ "url": "https://files.pythonhosted.org/packages/ce/d9/5f4c13cecde62396b0d3fe530a50ccea91e7dfc1ccf0e09c228841bb5ba8/urllib3-2.2.3-py3-none-any.whl",
+ "sha256": "ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"
},
{
"type": "file",
- "url": "https://files.pythonhosted.org/packages/1e/70/1e88138a9afbed1d37093b85f0bebc3011623c4f47c166431599fe9d6c93/websocket_client-1.7.0-py3-none-any.whl",
- "sha256": "f4c3d22fec12a2461427a29957ff07d35098ee2d976d3ba244e688b8b4057588"
+ "url": "https://files.pythonhosted.org/packages/5a/84/44687a29792a70e111c5c477230a72c4b957d88d16141199bf9acb7537a3/websocket_client-1.8.0-py3-none-any.whl",
+ "sha256": "17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526"
}
]
}
\ No newline at end of file
diff --git a/screenshots/Screenshot-Varia-1.png b/screenshots/Screenshot-Varia-1.png
index 6e72b18..7916505 100644
Binary files a/screenshots/Screenshot-Varia-1.png and b/screenshots/Screenshot-Varia-1.png differ
diff --git a/screenshots/Screenshot-Varia-2.png b/screenshots/Screenshot-Varia-2.png
index 608e2d4..c709871 100644
Binary files a/screenshots/Screenshot-Varia-2.png and b/screenshots/Screenshot-Varia-2.png differ
diff --git a/screenshots/Screenshot-Varia-3.png b/screenshots/Screenshot-Varia-3.png
index 9efb256..58633b4 100644
Binary files a/screenshots/Screenshot-Varia-3.png and b/screenshots/Screenshot-Varia-3.png differ
diff --git a/screenshots/Screenshot-Varia-4.png b/screenshots/Screenshot-Varia-4.png
index 04820b0..222f968 100644
Binary files a/screenshots/Screenshot-Varia-4.png and b/screenshots/Screenshot-Varia-4.png differ
diff --git a/screenshots/Screenshot-Varia-5.png b/screenshots/Screenshot-Varia-5.png
index 656087b..a89fd00 100644
Binary files a/screenshots/Screenshot-Varia-5.png and b/screenshots/Screenshot-Varia-5.png differ
diff --git a/src/download/actionrow.py b/src/download/actionrow.py
index c06f2a5..9262103 100644
--- a/src/download/actionrow.py
+++ b/src/download/actionrow.py
@@ -1,7 +1,7 @@
import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
-from gi.repository import Gtk, Adw
+from gi.repository import Gtk, Adw, Pango
from gettext import gettext as _
from window.content import create_status_page
@@ -15,10 +15,6 @@ def on_download_clicked(button, self, entry, DownloadThread):
download_thread.start()
def create_actionrow(self, filename):
- filename_shortened = filename[:40]
- if (filename != filename_shortened):
- filename_shortened = filename_shortened + "..."
-
download_item = Adw.Bin()
style_context = download_item.get_style_context()
style_context.add_class('card')
@@ -35,7 +31,8 @@ def create_actionrow(self, filename):
download_item.set_child(box_2)
- filename_label = Gtk.Label(label=filename_shortened)
+ filename_label = Gtk.Label(label=filename)
+ filename_label.set_ellipsize(Pango.EllipsizeMode.END)
filename_label.set_halign(Gtk.Align.START)
box.append(filename_label)
@@ -43,21 +40,23 @@ def create_actionrow(self, filename):
speed_label = Gtk.Label()
speed_label.set_halign(Gtk.Align.START)
+ speed_label.get_style_context().add_class("dim-label")
box.append(speed_label)
button_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5)
+ button_box.set_margin_start(10)
pause_button = Gtk.Button.new_from_icon_name("media-playback-pause-symbolic")
pause_button.set_valign(Gtk.Align.CENTER)
pause_button.get_style_context().add_class("circular")
pause_button.connect("clicked", on_pause_clicked, self, pause_button, download_item, False)
- self.pause_buttons.append(pause_button)
button_box.append(pause_button)
stop_button = Gtk.Button.new_from_icon_name("process-stop-symbolic")
stop_button.set_valign(Gtk.Align.CENTER)
stop_button.get_style_context().add_class("circular")
+ stop_button.get_style_context().add_class("destructive-action")
stop_button.connect("clicked", on_stop_clicked, self, download_item)
button_box.append(stop_button)
@@ -76,7 +75,7 @@ def create_actionrow(self, filename):
create_status_page(self, 1)
- return [progress_bar, speed_label, self.pause_buttons[len(self.pause_buttons)-1], download_item, filename_label]
+ return [progress_bar, speed_label, pause_button, download_item, filename_label]
def on_pause_clicked(button, self, pause_button, download_item, force_pause):
download_thread = self.downloads[download_item.index]
diff --git a/src/download/listen.py b/src/download/listen.py
index bf6208c..0489771 100644
--- a/src/download/listen.py
+++ b/src/download/listen.py
@@ -1,16 +1,14 @@
-import aria2p
-import requests
-import json
import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
-from gi.repository import Gtk, Adw, GLib, Gio
+from gi.repository import Adw, GLib, Gio
from download.actionrow import create_actionrow
from download.thread import DownloadThread
-import threading
import string
import random
import textwrap
+import os
+from gettext import gettext as _
def listen_to_aria2(self, variaapp):
if not (self.terminating) and not (self.shutdown_dialog_raised):
@@ -37,7 +35,6 @@ def listen_to_aria2(self, variaapp):
return
try:
if (download_item.download.status == "active" or download_item.download.status == "waiting" or download_item.download.status == "paused"):
- downloads_in_frontend.append(download_item)
for download_file in download_item.files:
downloads_in_frontend_files.append(download_file)
except:
@@ -86,7 +83,7 @@ def add_download_to_ui(self, download_item_to_be_added, variaapp):
download_thread = DownloadThread(self, download_item_url, *objectlist, download_item_to_be_added, None)
self.downloads.append(download_thread)
download_thread.start()
- download_thread.pause_button.show()
+ download_thread.pause_button.set_visible(True)
def raise_shutdown_dialog(variamain, variaapp):
while (True):
@@ -117,11 +114,15 @@ def shutdown_dialog_cancel_pressed(dialog, response_id, variamain, variaapp):
def initiate_shutdown(variamain, shutdown_id):
if (variamain.shutdown_dialog_raised == True) and (shutdown_id == variamain.shutdown_id):
- bus = Gio.bus_get_sync(Gio.BusType.SYSTEM, None)
- proxy = Gio.DBusProxy.new_sync(bus, Gio.DBusProxyFlags.NONE, None,
- 'org.freedesktop.login1', '/org/freedesktop/login1',
- 'org.freedesktop.login1.Manager', None)
- proxy.call_sync('PowerOff', GLib.Variant('(b)', (True,)), Gio.DBusCallFlags.NONE, -1, None)
+ if os.name == 'nt':
+ os.system('shutdown -s -t 0')
+ else:
+ bus = Gio.bus_get_sync(Gio.BusType.SYSTEM, None)
+ proxy = Gio.DBusProxy.new_sync(bus, Gio.DBusProxyFlags.NONE, None,
+ 'org.freedesktop.login1', '/org/freedesktop/login1',
+ 'org.freedesktop.login1.Manager', None)
+ proxy.call_sync('PowerOff', GLib.Variant('(b)', (True,)), Gio.DBusCallFlags.NONE, -1, None)
+
exit()
def raise_exit_dialog(variamain, variaapp):
diff --git a/src/download/scheduler.py b/src/download/scheduler.py
index b079c32..6878798 100644
--- a/src/download/scheduler.py
+++ b/src/download/scheduler.py
@@ -1,9 +1,6 @@
import datetime
-import aria2p
-from gi.repository import GLib
-from download.communicate import set_aria2c_download_simultaneous_amount
-import requests
-import json
+from gi.repository import Gtk, GLib
+from gettext import gettext as _
def schedule_downloads(self, previous_state):
if self.appconf["schedule_enabled"] == 1:
@@ -36,12 +33,14 @@ def schedule_downloads(self, previous_state):
if previous_state != self.scheduler_currently_downloading:
if self.scheduler_currently_downloading == True:
- self.download_button.set_label(_("Download"))
+ self.download_button_icon.set_from_icon_name("folder-download-symbolic")
+ self.download_button_text.set_label(_("Download"))
self.all_paused = True
self.pause_all(self.header_pause_content)
else:
- self.download_button.set_label(_("Schedule"))
+ self.download_button_icon.set_from_icon_name("alarmt-symbolic")
+ self.download_button_text.set_label(_("Schedule"))
self.all_paused = False
self.pause_all(self.header_pause_content)
diff --git a/src/download/thread.py b/src/download/thread.py
index bcc9e4c..bf468da 100644
--- a/src/download/thread.py
+++ b/src/download/thread.py
@@ -1,15 +1,13 @@
import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
-from gi.repository import Gtk, Adw, GLib, Gio
+from gi.repository import GLib
import threading
-from urllib.parse import unquote, urlparse
+from urllib.parse import urlparse
import requests
-import textwrap
import time
import os
import json
-import http.cookiejar
from gettext import gettext as _
from download.actionrow import on_pause_clicked
@@ -46,17 +44,18 @@ def run(self):
if (self.download == None):
if (self.url == "sus"):
try:
+ # Lol nice - Caleb (N0tACyb0rg)
GLib.idle_add(self.show_message("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣤⣤⣤⣀⣀⣀⣀⡀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⠟⠉⠉⠉⠉⠉⠉⠉⠙⠻⢶⣄⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⣷⡀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⡟⠀⣠⣶⠛⠛⠛⠛⠛⠛⠳⣦⡀⠀⠘⣿⡄⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⠁⠀⢹⣿⣦⣀⣀⣀⣀⣀⣠⣼⡇⠀⠀⠸⣷⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⡏⠀⠀⠀⠉⠛⠿⠿⠿⠿⠛⠋⠁⠀⠀⠀⠀⣿⡄⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢻⡇⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⣸⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡇⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣧⠀\n⠀⠀⠀⠀⠀⠀⠀⢸⡿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣿⠀\n⠀⠀⠀⠀⠀⠀⠀⣾⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀\n⠀⠀⠀⠀⠀⠀⠀⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀\n⠀⠀⠀⠀⠀⠀⢰⣿⠀⠀⠀⠀⣠⡶⠶⠿⠿⠿⠿⢷⣦⠀⠀⠀⠀⠀⠀⠀⣿⠀\n⠀⠀⣀⣀⣀⠀⣸⡇⠀⠀⠀⠀⣿⡀⠀⠀⠀⠀⠀⠀⣿⡇⠀⠀⠀⠀⠀⠀⣿⠀\n⣠⡿⠛⠛⠛⠛⠻⠀⠀⠀⠀⠀⢸⣇⠀⠀⠀⠀⠀⠀⣿⠇⠀⠀⠀⠀⠀⠀⣿⠀\n⢻⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⡟⠀⠀⢀⣤⣤⣴⣿⠀⠀⠀⠀⠀⠀⠀⣿⠀\n⠈⠙⢷⣶⣦⣤⣤⣤⣴⣶⣾⠿⠛⠁⢀⣶⡟⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡟⠀\n⠀⠀⠀⠀⠉⠉⠉⠉⠉⠀⠀⠀⠀⠀⠈⣿⣆⡀⠀⠀⠀⠀⠀⠀⢀⣠⣴⡾⠃⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠛⠻⢿⣿⣾⣿⡿⠿⠟⠋⠁⠀⠀⠀"))
except:
pass
- self.pause_button.hide()
- self.progress_bar.hide()
+ GLib.idle_add(self.pause_button.set_visible, False)
+ GLib.idle_add(self.progress_bar.set_visible, False)
return
if (self.url.startswith("magnet:") == False):
if not (self.is_valid_url()):
try:
- GLib.idle_add(self.show_message(_("This is not a valid URL.")))
+ GLib.idle_add(self.show_message, _("This is not a valid URL."))
print("Error: Not a valid url.")
except:
print("Error: Couldn't display 'not a valid url' error, for some reason.")
@@ -87,8 +86,7 @@ def run(self):
self.download.resume()
else:
on_pause_clicked(self.app, self.app, self.pause_button, self.actionrow, True)
-
- downloadname = self.download.name
+
print("Download added. | " + self.download.gid + "\n" + self.downloaddir + "\n" + self.url)
GLib.idle_add(self.update_header_pause_button)
self.previous_filename = ""
@@ -97,12 +95,12 @@ def run(self):
while (self.cancelled == False):
try:
self.download.update()
- GLib.idle_add(self.set_filename_label)
- GLib.idle_add(self.update_labels_and_things)
+ GLib.idle_add(self.filename_label.set_text, self.download.name)
+ self.update_labels_and_things()
if ((self.download.is_complete) and (self.download.is_metadata == False)):
print('Download complete: ' + self.download.gid)
- if os.path.exists(os.path.join(self.downloaddir,(self.download.gid + ".varia.json"))):
- os.remove(os.path.join(self.downloaddir,(self.download.gid + ".varia.json")))
+ if os.path.exists(os.path.join(self.downloaddir,(self.download.gid + ".varia"))):
+ os.remove(os.path.join(self.downloaddir,(self.download.gid + ".varia")))
break
elif ((self.download.is_torrent) and (self.download.seeder)):
print('Torrent complete, seeding: ' + self.download.gid)
@@ -113,14 +111,6 @@ def run(self):
return
time.sleep(1)
- def set_filename_label(self):
- filename_shortened = self.download.name[:40]
- if (self.download.name != filename_shortened):
- filename_shortened = filename_shortened + "..."
- if (filename_shortened != self.previous_filename):
- self.filename_label.set_text(filename_shortened)
- self.previous_filename = filename_shortened
-
def update_header_pause_button(self):
self.app.all_paused = False
self.app.header_pause_content.set_icon_name("media-playback-pause-symbolic")
@@ -131,21 +121,38 @@ def show_message(self, message):
self.speed_label.set_text(message)
def update_labels_and_things(self):
- self.progress_bar.set_fraction(self.download.progress / 100)
+ GLib.idle_add(self.progress_bar.set_fraction, self.download.progress / 100)
if ((self.download.is_torrent) and (self.download.seeder)):
GLib.idle_add(self.show_message(_("Seeding torrent")))
return
download_speed_mb = (self.download.download_speed / 1024 / 1024)
+
+ download_delta = self.download.eta
+
+ download_seconds = download_delta.total_seconds()
+ download_seconds = abs(int(download_seconds))
+ download_hours, download_seconds = divmod(download_seconds, 3600)
+ download_minutes, download_seconds = divmod(download_seconds, 60)
+
+ download_hours = str(download_hours).zfill(2)
+ download_minutes = str(download_minutes).zfill(2)
+ download_seconds = str(download_seconds).zfill(2)
+
+ if self.download.download_speed == 0:
+ download_remaining_string = "∞"
+ else:
+ download_remaining_string = f"{download_hours}:{download_minutes}:{download_seconds}"
+
if int(str(download_speed_mb)[0]) == 0:
download_speed_kb = (self.download.download_speed / 1024)
if int(str(download_speed_kb)[0]) == 0:
- self.speed_label.set_text(f"{round(self.download.progress)}% | {round(self.download.download_speed, 2)} B/s")
+ GLib.idle_add(self.speed_label.set_text, f"{round(self.download.progress)}% · {round(self.download.download_speed, 2)} {_(' B/s')} · {download_remaining_string} {_('remaining')}")
else:
- self.speed_label.set_text(f"{round(self.download.progress)}% | {round(self.download.download_speed / 1024, 2)} KB/s")
+ GLib.idle_add(self.speed_label.set_text, f"{round(self.download.progress)}% · {round(self.download.download_speed / 1024, 2)} {_(' KB/s')} · {download_remaining_string} {_('remaining')}")
else:
- self.speed_label.set_text(f"{round(self.download.progress)}% | {round(self.download.download_speed / 1024 / 1024, 2)} MB/s")
+ GLib.idle_add(self.speed_label.set_text, f"{round(self.download.progress)}% · {round(self.download.download_speed / 1024 / 1024, 2)} {_(' MB/s')} · {download_remaining_string} {_('remaining')}")
def pause(self):
if self.download:
@@ -173,7 +180,7 @@ def resume(self):
print ("Download paused.")
except:
try:
- self.speed_label.set_text(_("An error occurred:") + " " + self.download.error_message.split("status=")[1])
+ GLib.idle_add(self.speed_label.set_text, _("An error occurred:") + " " + self.download.error_message.split("status=")[1])
print ("An error occurred when resuming. " + self.download.error_message.split("status=")[1])
except:
pass
@@ -186,8 +193,8 @@ def stop(self, deletefiles):
self.download.remove(force=True)
if not self.download.is_complete:
if (deletefiles == True):
- if os.path.exists(os.path.join(self.downloaddir,(downloadgid + ".varia.json"))):
- os.remove(os.path.join(self.downloaddir,(downloadgid + ".varia.json")))
+ if os.path.exists(os.path.join(self.downloaddir,(downloadgid + ".varia"))):
+ os.remove(os.path.join(self.downloaddir,(downloadgid + ".varia")))
if os.path.exists(os.path.join(self.downloaddir, downloadname)):
os.remove(os.path.join(self.downloaddir, downloadname))
print ("Download stopped.")
@@ -206,7 +213,7 @@ def save_state(self):
'url': self.url,
'filename': self.download.name
}
- with open(os.path.join(self.downloaddir, f'{self.download.gid}.varia.json'), 'w') as f:
+ with open(os.path.join(self.downloaddir, f'{self.download.gid}.varia'), 'w') as f:
json.dump(state, f)
print ("State saved for download.")
@@ -227,4 +234,3 @@ def load_state(cls, app, filename, url, progress_bar, speed_label, pause_button,
os.remove(os.path.join(app.appconf["download_directory"], filename))
instance = cls(app, state['url'], progress_bar, speed_label, pause_button, actionrow, filename_label, None, downloadname)
return instance
-
diff --git a/src/initiate.py b/src/initiate.py
index 74c3f27..ee1ff19 100644
--- a/src/initiate.py
+++ b/src/initiate.py
@@ -3,19 +3,16 @@
import json
import gi
import requests
-import sys
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
-from gi.repository import Gtk, Adw, GLib
+from gi.repository import Gtk, Adw
from gettext import gettext as _
-def initiate(self, variaVersion):
+def initiate(self, variaapp, variaVersion, first_run):
self.downloaddir = self.appconf["download_directory"]
self.applied_filter = "show_all"
- remote_successful = False
-
if (self.appconf['remote'] == '1'):
self.aria2cLocation = self.appconf['remote_protocol'] + self.appconf['remote_ip'] + ':' + self.appconf['remote_port']
token = "token:" + self.appconf['remote_secret']
@@ -29,7 +26,7 @@ def initiate(self, variaVersion):
response = requests.post(self.aria2cLocation + '/jsonrpc', headers={'Content-Type': 'application/json'}, data=json.dumps(json_request))
print(response)
if (response.status_code == 200):
- remote_successful = True
+ self.remote_successful = True
self.api = aria2p.API(
aria2p.Client(
host=self.appconf['remote_protocol'] + self.appconf['remote_ip'],
@@ -41,16 +38,16 @@ def initiate(self, variaVersion):
pass
if (self.appconf['remote'] == '1'):
- if (remote_successful == False):
+ if (self.remote_successful == False):
self.appconf["remote"] = "0"
self.save_appconf()
- dialog = Adw.MessageDialog()
+ dialog = Adw.AlertDialog()
dialog.set_body(_("Couldn't connect to remote aria2c instance. Disabling remote mode. Please restart Varia."))
dialog.add_response("ok", _("OK"))
dialog.set_default_response("ok")
dialog.set_close_response("ok")
- dialog.connect("response", on_dialog_dismiss)
- dialog.show()
+ dialog.connect("response", on_dialog_dismiss, self)
+ dialog.present()
return -1
else:
self.api = aria2p.API(
@@ -62,23 +59,21 @@ def initiate(self, variaVersion):
self.aria2cLocation = "http://localhost:6801"
+ self.set_title("Varia")
self.set_default_size(800, 600)
self.set_size_request(650, 450)
self.total_download_speed = ""
self.terminating = False
- if ("dev" not in variaVersion):
- self.set_title("Varia")
- else:
- self.set_title("Varia (dev)")
+ if ("dev" in variaVersion):
+ self.get_style_context().add_class("devel")
Gtk.Settings.get_default().set_property("gtk-icon-theme-name", "Adwaita")
self.overlay_split_view = Adw.OverlaySplitView.new()
self.set_content(self.overlay_split_view)
self.downloads = []
- self.pause_buttons = []
self.all_paused = False
self.shutdown_mode = False
@@ -88,6 +83,27 @@ def initiate(self, variaVersion):
self.exit_mode = False
self.exit_dialog_raised = False
-def on_dialog_dismiss(dialog, response_id):
- dialog.destroy()
+ if (os.name == 'nt') and (first_run == True) and (os.path.exists("./updater-function-enabled")):
+ dialog = Adw.AlertDialog()
+ dialog.set_body(_("Do you want to check for updates on startup?"))
+ dialog.add_response("yes", _("Yes"))
+ dialog.add_response("no", _("No"))
+ dialog.set_response_appearance("yes", Adw.ResponseAppearance.SUGGESTED)
+ dialog.connect("response", set_auto_updates, self, variaapp, variaVersion)
+ dialog.set_close_response("no")
+ dialog.present(self)
+
+def set_auto_updates(dialog, response_id, self, variaapp, variaVersion):
+ if response_id == "yes":
+ self.appconf["check_for_updates_on_startup_enabled"] = "1"
+ else:
+ self.appconf["check_for_updates_on_startup_enabled"] = "0"
+
+ self.save_appconf()
+
+ from window.updater import windows_updater
+ windows_updater(None, self, variaapp, None, variaVersion, 0)
+def on_dialog_dismiss(dialog, response_id, self):
+ dialog.force_close()
+ self.destroy()
diff --git a/src/meson.build b/src/meson.build
index a3dbf9f..2a908cf 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -39,6 +39,7 @@ varia_sources_window = [
'window/sidebar.py',
'window/preferences.py',
'window/scheduler.py',
+ 'window/updater.py',
]
varia_sources_download = [
diff --git a/src/variamain.py b/src/variamain.py
index 5496a29..e8fff5e 100644
--- a/src/variamain.py
+++ b/src/variamain.py
@@ -1,32 +1,35 @@
-variaVersion = "v2024.5.7"
+variaVersion = "v2024.11.7"
import gi
import sys
-from gettext import gettext as _
import time
import json
import os
import threading
import subprocess
-from pathlib import Path
+
+from window.content import create_status_page
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
-from gi.repository import Gtk, Adw, GLib, Gio
-import requests
-
-from window.sidebar import window_create_sidebar
-from window.content import window_create_content, create_status_page
-from download.actionrow import create_actionrow, on_pause_clicked, on_stop_clicked
-from download.thread import DownloadThread
-from download.communicate import set_speed_limit, set_aria2c_download_directory, set_aria2c_download_simultaneous_amount, set_aria2c_custom_global_option, set_aria2c_cookies
-from initiate import initiate
-from download.listen import listen_to_aria2
-from download.scheduler import schedule_downloads
+from gi.repository import Gtk, Adw, GLib, Gio, Gdk
+
+if os.name != 'nt':
+ from gettext import gettext as _
class MainWindow(Adw.ApplicationWindow):
- def __init__(self, variaapp, appdir, appconf, aria2c_subprocess, aria2cexec, *args, **kwargs):
+ def __init__(self, variaapp, appdir, appconf, first_run, aria2c_subprocess, aria2cexec, *args, **kwargs):
super().__init__(*args, **kwargs)
- self.set_hide_on_close(True)
+
+ from window.sidebar import window_create_sidebar
+ from window.content import window_create_content
+ from window.updater import windows_updater
+ from download.actionrow import create_actionrow
+ from download.thread import DownloadThread
+ from download.communicate import set_speed_limit, set_aria2c_download_directory, set_aria2c_download_simultaneous_amount, set_aria2c_custom_global_option, set_aria2c_cookies
+ from initiate import initiate
+ from download.listen import listen_to_aria2
+ from download.scheduler import schedule_downloads
+
self.connect('close-request', self.exitProgram, variaapp, False)
self.scheduler_currently_downloading = False
@@ -34,9 +37,12 @@ def __init__(self, variaapp, appdir, appconf, aria2c_subprocess, aria2cexec, *ar
self.appconf = appconf
self.aria2c_subprocess = aria2c_subprocess
self.bindir = aria2cexec[:-6]
+ self.aria2cexec = aria2cexec
+ self.remote_successful = False
+ self.update_executable = None
# Set up variables and all:
- aria2_connection_successful = initiate(self, variaVersion)
+ aria2_connection_successful = initiate(self, variaapp, variaVersion, first_run)
if (aria2_connection_successful == -1):
return
@@ -50,10 +56,10 @@ def __init__(self, variaapp, appdir, appconf, aria2c_subprocess, aria2cexec, *ar
# Check if the download path still exists:
if not (os.path.exists(self.appconf["download_directory"])):
- if (os.path.exists(GLib.get_user_special_dir(GLib.USER_DIRECTORY_DOWNLOAD))):
- self.appconf["download_directory"] = GLib.get_user_special_dir(GLib.USER_DIRECTORY_DOWNLOAD)
+ if (os.path.exists(GLib.get_user_special_dir(GLib.DIRECTORY_DOWNLOAD))):
+ self.appconf["download_directory"] = GLib.get_user_special_dir(GLib.DIRECTORY_DOWNLOAD)
else:
- self.appconf["download_directory"] = GLib.get_user_special_dir(GLib.USER_DIRECTORY_HOME)
+ self.appconf["download_directory"] = GLib.get_user_special_dir(GLib.DIRECTORY_HOME)
self.save_appconf()
# Set download speed limit from appconf:
@@ -80,27 +86,40 @@ def __init__(self, variaapp, appdir, appconf, aria2c_subprocess, aria2cexec, *ar
set_aria2c_cookies(self)
# Listen to aria2c:
- thread = threading.Thread(target=listen_to_aria2(self, variaapp))
+ thread = threading.Thread(target=lambda: listen_to_aria2(self, variaapp))
thread.start()
# Begin the scheduler:
- thread = threading.Thread(target=schedule_downloads(self, True))
+ thread = threading.Thread(target=lambda: schedule_downloads(self, True))
thread.start()
+ # Windows only stuff:
+ if (os.name == 'nt'):
+ icon_theme = Gtk.IconTheme.get_for_display(Gdk.Display.get_default())
+ icon_theme.add_search_path("./")
+ if (self.appconf["check_for_updates_on_startup_enabled"] == '1') and (os.path.exists("./updater-function-enabled")):
+ windows_updater(None, self, variaapp, None, variaVersion, 0)
+
# Load incomplete downloads:
default_state = {"url": None, "filename": None}
for filename in os.listdir(self.appconf["download_directory"]):
- if filename.endswith('.varia.json'):
+ if (os.path.isdir(filename) == False) and ( (filename.endswith('.varia.json')) or (filename.endswith('.varia')) ):
+ if (filename.endswith(".varia.json")):
+ current_filename = filename.replace(".json", "")
+ os.rename(os.path.join(self.appconf["download_directory"], filename), os.path.join(self.appconf["download_directory"], current_filename))
+ else:
+ current_filename = filename
- with open(os.path.join(self.appconf["download_directory"], filename), 'r') as f:
+ with open(os.path.join(self.appconf["download_directory"], current_filename), 'r') as f:
loaded_state = json.load(f)
+ print(filename)
state = {**default_state, **loaded_state}
objectlist = create_actionrow(self, state['url'])
- download_thread = DownloadThread.load_state(self, filename, state['url'], objectlist[0], objectlist[1], objectlist[2], objectlist[3], objectlist[4], None, state['filename'])
+ download_thread = DownloadThread.load_state(self, current_filename, state['url'], objectlist[0], objectlist[1], objectlist[2], objectlist[3], objectlist[4], None, state['filename'])
self.downloads.append(download_thread)
- download_thread.start()
+ GLib.idle_add(download_thread.start)
# Start in background mode if it was enabled in preferences:
if (self.appconf["default_mode"] == "background"):
@@ -120,21 +139,21 @@ def filter_download_list(self, button, filter_mode):
if (filter_mode == "show_all"):
self.applied_filter = "show_all"
for download_thread in self.downloads:
- download_thread.actionrow.show()
+ download_thread.actionrow.set_visible(True)
self.filter_button_show_all.set_active(True)
else:
for download_thread in self.downloads:
- download_thread.actionrow.hide()
+ download_thread.actionrow.set_visible(False)
if (filter_mode == "show_downloading"):
self.applied_filter = "show_downloading"
for download_thread in self.downloads:
if (download_thread.download):
if (((download_thread.download.status == "waiting") or (download_thread.download.status == "active")) and (download_thread.download.seeder != True)):
- download_thread.actionrow.show()
+ download_thread.actionrow.set_visible(True)
else:
- download_thread.actionrow.show()
+ download_thread.actionrow.set_visible(True)
self.filter_button_show_downloading.set_active(True)
elif (filter_mode == "show_completed"):
@@ -142,7 +161,7 @@ def filter_download_list(self, button, filter_mode):
for download_thread in self.downloads:
if (download_thread.download):
if (download_thread.download.status == "complete"):
- download_thread.actionrow.show()
+ download_thread.actionrow.set_visible(True)
self.filter_button_show_completed.set_active(True)
elif (filter_mode == "show_seeding"):
@@ -150,7 +169,7 @@ def filter_download_list(self, button, filter_mode):
for download_thread in self.downloads:
if (download_thread.download):
if (download_thread.download.seeder == True):
- download_thread.actionrow.show()
+ download_thread.actionrow.set_visible(True)
self.filter_button_show_seeding.set_active(True)
else:
@@ -158,7 +177,7 @@ def filter_download_list(self, button, filter_mode):
for download_thread in self.downloads:
if (download_thread.download):
if (download_thread.download.status == "error"):
- download_thread.actionrow.show()
+ download_thread.actionrow.set_visible(True)
self.filter_button_show_failed.set_active(True)
def check_download_status(self):
@@ -170,7 +189,7 @@ def check_download_status(self):
if (download_thread.download.is_complete == 1):
download_thread.cancelled = True
download_thread.speed_label.set_text(_("Download complete."))
- self.pause_buttons[i].hide()
+ GLib.idle_add(download_thread.pause_button.set_visible, False)
self.filter_download_list("no", self.applied_filter)
elif (download_thread.download.status == "error") or (download_thread.download.status == "removed"):
@@ -183,10 +202,10 @@ def check_download_status(self):
download_thread.speed_label.set_text(_("An error occurred:") + " " + str(download_thread.download.error_code))
download_thread.stop(False)
- self.pause_buttons[i].hide()
+ GLib.idle_add(download_thread.pause_button.set_visible, False)
self.filter_download_list("no", self.applied_filter)
except:
- self.pause_buttons[i].hide()
+ GLib.idle_add(download_thread.pause_button.set_visible, False)
self.filter_download_list("no", self.applied_filter)
pass
i += 1
@@ -200,22 +219,8 @@ def total_download_speed_get(self, downloads, total_download_speed_label):
download_thread.download.update()
except:
continue
- try:
- speed_label_text_first_digit = download_thread.speed_label.get_text()[0]
- except:
- speed_label_text_first_digit = "0"
- try:
- if (speed_label_text_first_digit.isdigit()):
- download_speed = (float(download_thread.speed_label.get_text().split(" ")[4]))
- if (download_thread.speed_label.get_text().split(" ")[5] == _("GB/s")):
- download_speed = download_speed * 1024 * 1024 * 1024
- elif (download_thread.speed_label.get_text().split(" ")[5] == _("MB/s")):
- download_speed = download_speed * 1024 * 1024
- elif (download_thread.speed_label.get_text().split(" ")[5] == _("KB/s")):
- download_speed = download_speed * 1024
- total_download_speed = total_download_speed + download_speed
- except:
- continue
+ total_download_speed += download_thread.download.download_speed
+
if (total_download_speed == 0):
download_speed_text = "0" + _(" B/s")
elif (total_download_speed < 1024):
@@ -225,7 +230,7 @@ def total_download_speed_get(self, downloads, total_download_speed_label):
else:
download_speed_text = str(round(total_download_speed / 1024 / 1024, 2)) + _(" MB/s")
- total_download_speed_label.set_text(download_speed_text)
+ GLib.idle_add(total_download_speed_label.set_text, download_speed_text)
time.sleep(1)
def pause_all(self, header_pause_content):
@@ -237,7 +242,7 @@ def pause_all(self, header_pause_content):
pause_button_images.append(Gtk.Image.new())
pause_button_images[i].set_from_icon_name("media-playback-start-symbolic")
- self.pause_buttons[i].set_child(pause_button_images[i])
+ download_thread.pause_button.set_child(pause_button_images[i])
download_thread.save_state()
@@ -252,7 +257,7 @@ def pause_all(self, header_pause_content):
pause_button_images.append(Gtk.Image.new())
pause_button_images[i].set_from_icon_name("media-playback-pause-symbolic")
- self.pause_buttons[i].set_child(pause_button_images[i])
+ download_thread.pause_button.set_child(pause_button_images[i])
i += 1
if ((header_pause_content != "no") and (i > 0)):
@@ -285,40 +290,39 @@ def save_appconf(self):
def exitProgram(self, app, variaapp, background):
if (background == True):
- self.hide()
+ self.set_visible(False)
notification = Gio.Notification.new(_("Background Mode"))
notification.set_body(_("Continuing the downloads in the background."))
notification.set_title(_("Background Mode")),
variaapp.send_notification(None, notification)
print('Background mode')
+
else:
self.terminating = True
-
- self.set_sensitive(False)
self.all_paused = False
- if (self.appconf['remote'] == '0'):
+ if (self.remote_successful == False):
self.pause_all("no")
self.api.client.shutdown()
- if (self.is_visible() == True):
- self.hide()
- exiting_dialog = Adw.MessageDialog()
- exiting_dialog_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=25)
- exiting_dialog.set_child(exiting_dialog_box)
- exiting_dialog_box.set_margin_top(30)
- exiting_dialog_box.set_margin_bottom(30)
- exiting_dialog_spinner = Gtk.Spinner()
- exiting_dialog_spinner.set_size_request(30, 30)
- exiting_dialog_spinner.start()
- exiting_dialog_box.append(exiting_dialog_spinner)
- exiting_dialog_label = Gtk.Label(label=_("Exiting Varia..."))
- exiting_dialog_label.get_style_context().add_class("title-1")
- exiting_dialog_box.append(exiting_dialog_label)
- exiting_dialog.set_transient_for(self)
- GLib.idle_add(exiting_dialog.show)
- else:
- exiting_dialog = None
+ if (self.is_visible() == False):
+ self.set_visible(True)
+
+ exiting_dialog = Adw.AlertDialog()
+ exiting_dialog_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=25)
+ exiting_dialog.set_child(exiting_dialog_box)
+ exiting_dialog_box.set_margin_top(30)
+ exiting_dialog_box.set_margin_bottom(30)
+ exiting_dialog_box.set_margin_start(60)
+ exiting_dialog_box.set_margin_end(60)
+ exiting_dialog_spinner = Adw.Spinner()
+ exiting_dialog_spinner.set_size_request(30, 30)
+ exiting_dialog_box.append(exiting_dialog_spinner)
+ exiting_dialog_label = Gtk.Label(label=_("Exiting Varia..."))
+ exiting_dialog_label.get_style_context().add_class("title-1")
+ exiting_dialog_box.append(exiting_dialog_label)
+ exiting_dialog.set_can_close(False)
+ GLib.idle_add(exiting_dialog.present, self)
GLib.timeout_add(3000, self.aria2c_exiting_check, app, 0, variaapp, exiting_dialog)
@@ -326,6 +330,11 @@ def exitProgram(self, app, variaapp, background):
self.destroy()
variaapp.quit()
+ if self.update_executable != None:
+ os.system(self.update_executable)
+
+ return True
+
def aria2c_exiting_check(self, app, counter, variaapp, exiting_dialog):
print(counter)
if ((counter < 20) and (self.aria2c_subprocess.poll() is None)):
@@ -335,11 +344,15 @@ def aria2c_exiting_check(self, app, counter, variaapp, exiting_dialog):
self.aria2c_subprocess.terminate()
self.aria2c_subprocess.wait()
if (exiting_dialog is not None):
- exiting_dialog.destroy()
+ exiting_dialog.force_close()
self.destroy()
variaapp.quit()
for thread in threading.enumerate():
print(thread.name)
+
+ if self.update_executable != None:
+ os.system(self.update_executable)
+
return
def quit_action_received(self, variaapp):
@@ -347,19 +360,24 @@ def quit_action_received(self, variaapp):
self.exitProgram(variaapp, variaapp, False)
class MyApp(Adw.Application):
- def __init__(self, appdir, appconf, aria2c_subprocess, aria2cexec, **kwargs):
+ def __init__(self, appdir, appconf, first_run, aria2c_subprocess, aria2cexec, **kwargs):
super().__init__(**kwargs)
- self.connect('activate', self.on_activate, appdir, appconf, aria2c_subprocess, aria2cexec)
+ self.connect('activate', self.on_activate, appdir, appconf, first_run, aria2c_subprocess, aria2cexec)
quit_action = Gio.SimpleAction.new("quit", None)
quit_action.connect("activate", self.quit_action)
self.add_action(quit_action)
self.initiated = False
- def on_activate(self, app, appdir, appconf, aria2c_subprocess, aria2cexec):
+ def on_activate(self, app, appdir, appconf, first_run, aria2c_subprocess, aria2cexec):
if not hasattr(self, 'win'):
- self.win = MainWindow(application=app, variaapp=self, appdir=appdir, appconf=appconf, aria2c_subprocess=aria2c_subprocess, aria2cexec=aria2cexec)
- if ((self.win.terminating == False) and ((appconf["default_mode"] == "visible") or (self.initiated == True))):
- self.win.present()
+ self.win = MainWindow(application=app, variaapp=self, appdir=appdir, appconf=appconf, first_run=first_run, aria2c_subprocess=aria2c_subprocess, aria2cexec=aria2cexec)
+
+ try:
+ if ((self.win.terminating == False) and ((appconf["default_mode"] == "visible") or (self.initiated == True))):
+ self.win.present()
+ except:
+ return -1
+
self.initiated = True
def quit_action(self, action, parameter):
@@ -376,12 +394,13 @@ def main(version, aria2cexec):
download_directory = ''
try:
- if (os.path.exists(GLib.get_user_special_dir(GLib.USER_DIRECTORY_DOWNLOAD))):
- download_directory = GLib.get_user_special_dir(GLib.USER_DIRECTORY_DOWNLOAD)
+ if (os.path.exists(GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DOWNLOAD))):
+ download_directory = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DOWNLOAD)
else:
- download_directory = GLib.get_user_special_dir(GLib.USER_DIRECTORY_HOME)
- except:
- download_directory = GLib.get_user_special_dir(GLib.USER_DIRECTORY_HOME)
+ download_directory = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_HOME)
+ except AttributeError:
+ print("Can't find GLib user special dirs")
+ download_directory = os.path.expanduser("~")
appconf = {
'download_speed_limit_enabled': '0',
@@ -402,32 +421,48 @@ def main(version, aria2cexec):
'schedule_mode': 'inclusive',
'schedule': [],
'remote_time': '0',
- 'cookies_txt': '0'}
+ 'cookies_txt': '0',
+ 'check_for_updates_on_startup_enabled': '0'}
if os.path.exists(os.path.join(appdir, 'varia.conf')):
+ first_run = False
with open(os.path.join(appdir, 'varia.conf'), 'r') as f:
appconf.update(json.load(f))
else:
+ first_run = True
with open(os.path.join(appdir, 'varia.conf'), 'w') as f:
json.dump(appconf, f)
aria2c_subprocess = None
if (appconf['remote'] == '0'):
if (os.name == 'nt'):
- aria2c_subprocess = subprocess.Popen([aria2cexec, "--enable-rpc", "--rpc-listen-port=6801", "--follow-torrent=mem"], shell=True)
+ aria2c_subprocess = subprocess.Popen([aria2cexec, "--enable-rpc", "--rpc-listen-port=6801", "--follow-torrent=mem", "--allow-overwrite=true"], shell=True)
else:
- aria2c_subprocess = subprocess.Popen([aria2cexec, "--enable-rpc", "--rpc-listen-port=6801", "--follow-torrent=mem"])
+ if hasattr(os, 'posix_fallocate'):
+ print("fallocate enabled.")
+ aria2c_subprocess = subprocess.Popen([aria2cexec, "--enable-rpc", "--rpc-listen-port=6801", "--follow-torrent=mem", "--allow-overwrite=true", "--file-allocation=falloc"])
+ else:
+ aria2c_subprocess = subprocess.Popen([aria2cexec, "--enable-rpc", "--rpc-listen-port=6801", "--follow-torrent=mem", "--allow-overwrite=true"])
arguments = sys.argv
if (len(arguments) > 1):
arguments = arguments[:-1]
- app = MyApp(appdir, appconf, aria2c_subprocess, aria2cexec, application_id="io.github.giantpinkrobots.varia")
- try:
- app.run(arguments)
- except:
- pass
+ app = MyApp(appdir, appconf, first_run, aria2c_subprocess, aria2cexec, application_id="io.github.giantpinkrobots.varia")
+ app.run(arguments),
if ((__name__ == '__main__') and (os.name == 'nt')):
- sys.exit(main(variaVersion, "aria2c"))
-
+ import gettext
+ import ctypes
+ import locale
+
+ windll = ctypes.windll.kernel32
+ lang_id = windll.GetUserDefaultUILanguage()
+ current_locale = locale.windows_locale.get(lang_id)
+ print(current_locale)
+
+ translation = gettext.translation('varia', localedir='./locale', languages=[current_locale], fallback=True)
+ gettext.gettext = translation.gettext
+ from gettext import gettext as _
+
+ sys.exit(main(variaVersion, "aria2c"))
\ No newline at end of file
diff --git a/src/window/content.py b/src/window/content.py
index 4297c99..46888c6 100644
--- a/src/window/content.py
+++ b/src/window/content.py
@@ -1,12 +1,11 @@
import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
-from gi.repository import Gtk, Adw, GLib, Gio
+from gi.repository import Gtk, Adw
from gettext import gettext as _
-import os
def window_create_content(self, threading):
- content_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
+ self.content_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
header_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
self.total_download_speed_label = Gtk.Label(label=self.total_download_speed)
@@ -33,24 +32,21 @@ def window_create_content(self, threading):
header_box.append(header_expanding_box_1)
header_box.append(header_button_box)
- header_bar = Adw.HeaderBar()
- header_bar.get_style_context().add_class('flat')
- header_bar.set_title_widget(header_box)
- content_box.append(header_bar)
-
- if (os.name == 'nt'):
- self.status_page_widget = Gtk.Box()
- else:
- self.status_page_widget = Adw.StatusPage(icon_name="io.github.giantpinkrobots.varia-symbolic")
- self.status_page_widget.set_hexpand(True)
- self.status_page_widget.set_vexpand(True)
-
+ self.header_bar = Adw.HeaderBar()
+ self.header_bar.get_style_context().add_class('flat')
+ self.header_bar.set_title_widget(header_box)
+ self.content_box.append(self.header_bar)
+
+ self.status_page_widget = Adw.StatusPage(icon_name="io.github.giantpinkrobots.varia-symbolic")
+ self.status_page_widget.set_hexpand(True)
+ self.status_page_widget.set_vexpand(True)
+
self.download_list_box = Gtk.Box()
self.download_list = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
self.download_list.set_margin_start(6)
self.download_list.set_margin_end(6)
self.download_list.set_margin_bottom(6)
- self.download_list.set_margin_top(6)
+ self.download_list.set_margin_top(1)
self.download_list_box.set_hexpand(True)
self.download_list_box.set_vexpand(True)
@@ -60,8 +56,8 @@ def window_create_content(self, threading):
scrolled_window.set_child(self.download_list)
self.download_list_box.append(scrolled_window)
- content_box.append(self.download_list_box)
- self.overlay_split_view.set_content(content_box)
+ self.content_box.append(self.download_list_box)
+ self.overlay_split_view.set_content(self.content_box)
self.total_download_speed_calculator_thread = threading.Thread(target=self.total_download_speed_get, args=(self.downloads, self.total_download_speed_label))
self.total_download_speed_calculator_thread.start()
diff --git a/src/window/preferences.py b/src/window/preferences.py
index 00b6d85..13599fb 100644
--- a/src/window/preferences.py
+++ b/src/window/preferences.py
@@ -7,19 +7,41 @@
from download.communicate import set_speed_limit, set_aria2c_download_directory, set_aria2c_download_simultaneous_amount, set_aria2c_custom_global_option, set_aria2c_cookies
from window.scheduler import show_scheduler_dialog
+from window.updater import windows_updater
-def show_preferences(button, self, app):
- preferences = Adw.PreferencesDialog()
+def show_preferences(button, self, app, variaVersion):
+ preferences = Adw.PreferencesDialog(title=_("Preferences"))
+ preferences.set_search_enabled(True)
- page = Adw.PreferencesPage(title=_("Preferences"))
+ page = Adw.PreferencesPage()
preferences.add(page)
- group_extensions = Adw.PreferencesGroup(title=_("Browser Extension"))
+ group_extensions = Adw.PreferencesGroup()
page.add(group_extensions)
group_1 = Adw.PreferencesGroup(title=_("Basic Settings"))
page.add(group_1)
group_2 = Adw.PreferencesGroup(title=_("Advanced Settings"))
page.add(group_2)
+ # Updater section for Windows:
+
+ if (os.name == 'nt') and (os.path.exists("./updater-function-enabled")):
+ update_actionrow = Adw.SwitchRow()
+ update_actionrow.set_title(_("Automatically Check for Updates"))
+ update_actionrow.connect("notify::active", on_switch_auto_update_check, self)
+
+ update_button = Gtk.Button(label=_("Check Now"))
+ update_button.set_halign(Gtk.Align.START)
+ update_button.set_valign(Gtk.Align.CENTER)
+ update_button.get_style_context().add_class("suggested-action")
+ update_button.connect("clicked", lambda clicked: windows_updater(None, self, app, preferences, variaVersion, 1))
+
+ update_actionrow.add_suffix(update_button)
+
+ group_extensions.add(update_actionrow)
+
+ if (self.appconf["check_for_updates_on_startup_enabled"] == '1'):
+ update_actionrow.set_active("active")
+
# Browser extensions section:
browser_extension_actionrow = Adw.ActionRow()
@@ -28,7 +50,7 @@ def show_preferences(button, self, app):
browser_extension_firefox_button = Gtk.Button(label="Firefox")
browser_extension_firefox_button.set_halign(Gtk.Align.START)
browser_extension_firefox_button.set_valign(Gtk.Align.CENTER)
- browser_extension_chrome_button = Gtk.Button(label="Chrome")
+ browser_extension_chrome_button = Gtk.Button(label="Chrome, Edge, Opera...")
browser_extension_chrome_button.set_halign(Gtk.Align.START)
browser_extension_chrome_button.set_valign(Gtk.Align.CENTER)
@@ -40,7 +62,7 @@ def show_preferences(button, self, app):
browser_extension_buttons_box.append(browser_extension_chrome_button)
browser_extension_actionrow.add_suffix(browser_extension_buttons_box)
-
+
group_extensions.add(browser_extension_actionrow)
# Download directory:
@@ -130,7 +152,7 @@ def show_preferences(button, self, app):
scheduler_actionrow_edit_button.set_valign(Gtk.Align.CENTER)
scheduler_actionrow_edit_button.get_style_context().add_class("suggested-action")
- scheduler_actionrow_edit_button.connect("clicked", lambda clicked: show_scheduler_dialog(self, preferences, app, show_preferences))
+ scheduler_actionrow_edit_button.connect("clicked", lambda clicked: show_scheduler_dialog(self, preferences, app, show_preferences, variaVersion))
scheduler_actionrow_buttons_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
scheduler_actionrow_buttons_box.append(scheduler_actionrow_edit_button)
@@ -139,23 +161,11 @@ def show_preferences(button, self, app):
# Simultaneous download amount:
- simultaneous_download_amount_unit_names = Gio.ListStore.new(Gtk.StringObject)
- simultaneous_download_amount_unit_names.append(Gtk.StringObject.new(" 1"))
- simultaneous_download_amount_unit_names.append(Gtk.StringObject.new(" 2"))
- simultaneous_download_amount_unit_names.append(Gtk.StringObject.new(" 3"))
- simultaneous_download_amount_unit_names.append(Gtk.StringObject.new(" 4"))
- simultaneous_download_amount_unit_names.append(Gtk.StringObject.new(" 5"))
- simultaneous_download_amount_unit_names.append(Gtk.StringObject.new(" 6"))
- simultaneous_download_amount_unit_names.append(Gtk.StringObject.new(" 7"))
- simultaneous_download_amount_unit_names.append(Gtk.StringObject.new(" 8"))
- simultaneous_download_amount_unit_names.append(Gtk.StringObject.new(" 9"))
- simultaneous_download_amount_unit_names.append(Gtk.StringObject.new(" 10"))
-
- simultaneous_download_amount_unit_names_box = Adw.ComboRow()
- simultaneous_download_amount_unit_names_box.set_model(simultaneous_download_amount_unit_names)
- simultaneous_download_amount_unit_names_box.set_title(_("Simultaneous Download Amount"))
- simultaneous_download_amount_unit_names_box.set_selected(int(self.appconf["download_simultaneous_amount"])- 1)
- simultaneous_download_amount_unit_names_box.connect("notify::selected", on_simultaneous_download_amount_changed, self)
+ simultaneous_download_amount_spinrow = Adw.SpinRow(adjustment=Gtk.Adjustment(step_increment=1.0))
+ simultaneous_download_amount_spinrow.set_title(_("Simultaneous Download Amount"))
+ simultaneous_download_amount_spinrow.set_range(1.0, 15.0)
+ simultaneous_download_amount_spinrow.set_value(float(self.appconf["download_simultaneous_amount"]))
+ simultaneous_download_amount_spinrow.connect("changed", on_simultaneous_download_amount_changed, self)
# Start in background:
@@ -171,7 +181,7 @@ def show_preferences(button, self, app):
group_1.add(download_directory_actionrow)
group_1.add(speed_limit_expander_box)
group_1.add(scheduler_actionrow)
- group_1.add(simultaneous_download_amount_unit_names_box)
+ group_1.add(simultaneous_download_amount_spinrow)
group_1.add(start_in_background)
# Remote aria2:
@@ -336,9 +346,22 @@ def show_preferences(button, self, app):
group_2.add(remote_time)
group_2.add(cookies_txt_action)
group_2.add(cookies_txt_action)
+ group_2.add(remote_aria2_expander_box)
preferences.present(self)
+def on_switch_auto_update_check(switch, state, self):
+ state = switch.get_active()
+ if state:
+ self.appconf["check_for_updates_on_startup_enabled"] = '1'
+ else:
+ self.appconf["check_for_updates_on_startup_enabled"] = '0'
+ if hasattr(self, 'update_available_banner'):
+ if self.update_available_banner != None:
+ self.update_available_banner.set_revealed(False)
+
+ self.save_appconf()
+
def speed_limit_text_filter(entry, self):
text = entry.get_text()
new_text = ""
@@ -452,9 +475,9 @@ def set_auth_credentials(self, username_entry, password_entry, switch):
self.save_appconf()
-def on_simultaneous_download_amount_changed(comborow, parameters, self):
- self.appconf["download_simultaneous_amount"] = str(comborow.get_selected() + 1)
- print(str(comborow.get_selected() + 1))
+def on_simultaneous_download_amount_changed(spinrow, self):
+ self.appconf["download_simultaneous_amount"] = str(int(spinrow.get_value()))
+ print(str(int(spinrow.get_value())))
self.save_appconf()
set_aria2c_download_simultaneous_amount(self)
@@ -508,13 +531,14 @@ def on_cookies_txt_import(file_dialog, result, cookies_txt_import_button, cookie
file = file_dialog.open_finish(result).get_path()
except:
return
- with open(file, 'r') as file:
- data = file.read()
- with open(os.path.join(self.appdir, 'cookies.txt'), 'w') as cookies_txt_file:
- cookies_txt_file.write(data)
- cookies_txt_action_switch.set_sensitive(True)
- cookies_txt_import_button.set_visible(False)
- cookies_txt_remove_button.set_visible(True)
+ if file.endswith(".txt"):
+ with open(file, 'r') as file:
+ data = file.read()
+ with open(os.path.join(self.appdir, 'cookies.txt'), 'w') as cookies_txt_file:
+ cookies_txt_file.write(data)
+ cookies_txt_action_switch.set_sensitive(True)
+ cookies_txt_import_button.set_visible(False)
+ cookies_txt_remove_button.set_visible(True)
def on_switch_cookies_txt(switch, state, self):
state = switch.get_active()
diff --git a/src/window/scheduler.py b/src/window/scheduler.py
index 1ffb944..630c7ce 100644
--- a/src/window/scheduler.py
+++ b/src/window/scheduler.py
@@ -1,7 +1,8 @@
import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
-from gi.repository import Gtk, Adw, Gio
+from gi.repository import Gtk, Adw
+from gettext import gettext as _
def add_timespan_clicked(button, self, timespans_box, day, start_h, start_m, end_h, end_m, switch_enabled):
timespan_row = Adw.Bin()
@@ -11,10 +12,10 @@ def add_timespan_clicked(button, self, timespans_box, day, start_h, start_m, end
switch_enabled.set_sensitive(True)
box = Gtk.Box()
- box.set_margin_start(10)
- box.set_margin_end(10)
- box.set_margin_top(10)
- box.set_margin_bottom(10)
+ box.set_margin_start(5)
+ box.set_margin_end(5)
+ box.set_margin_top(5)
+ box.set_margin_bottom(5)
timespan_row.set_child(box)
days_combobox = Gtk.ComboBoxText()
@@ -30,9 +31,9 @@ def add_timespan_clicked(button, self, timespans_box, day, start_h, start_m, end
Gtk.Widget.set_hexpand(box_expanding_1, True)
box.append(box_expanding_1)
- timespan_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8, halign=Gtk.Align.END)
- start_timespan_box = Gtk.Box(spacing=4, halign=Gtk.Align.END)
- end_timespan_box = Gtk.Box(spacing=4, halign=Gtk.Align.END)
+ timespan_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=4, halign=Gtk.Align.END)
+ start_timespan_box = Gtk.Box(spacing=2, halign=Gtk.Align.END)
+ end_timespan_box = Gtk.Box(spacing=2, halign=Gtk.Align.END)
start_timespan_label = Gtk.Label(label=_("Start (h/m):"))
start_timespan_spin_h = Gtk.SpinButton.new_with_range(0, 23, 1)
@@ -92,7 +93,7 @@ def change_schedule_mode(switch, state, self, mode, switch_mode_1, switch_mode_2
else:
switch_mode_1.set_active(True)
-def save_schedule(preferencesDialog, self, switch_mode_1, switch_enabled, show_preferences, variaapp):
+def save_schedule(preferencesDialog, self, switch_mode_1, switch_enabled, show_preferences, variaapp, variaVersion):
if switch_enabled.get_state():
self.appconf["schedule_enabled"] = 1
self.sidebar_scheduler_label.set_label(_("Scheduler enabled"))
@@ -118,7 +119,7 @@ def save_schedule(preferencesDialog, self, switch_mode_1, switch_enabled, show_p
self.appconf["schedule"] = timespan_appconf
self.save_appconf()
- show_preferences('no', self, variaapp)
+ show_preferences('no', self, variaapp, variaVersion)
def if_there_are_any_timespans(self, switch_enabled):
if self.timespans_list == []:
@@ -128,9 +129,9 @@ def if_there_are_any_timespans(self, switch_enabled):
self.sidebar_scheduler_label.set_label("")
self.save_appconf()
-def show_scheduler_dialog(self, preferencesWindow, variaapp, show_preferences):
+def show_scheduler_dialog(self, preferencesWindow, variaapp, show_preferences, variaVersion):
schedulerDialog = Adw.PreferencesDialog(title=_("Scheduler"))
- schedulerDialog.set_size_request(650, 450)
+ schedulerDialog.set_follows_content_size(True)
self.timespans_list = []
@@ -141,7 +142,8 @@ def show_scheduler_dialog(self, preferencesWindow, variaapp, show_preferences):
page.add(group_1)
main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12)
-
+ main_box.set_size_request(550, 350)
+
group_1.add(main_box)
modes_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
@@ -197,16 +199,18 @@ def show_scheduler_dialog(self, preferencesWindow, variaapp, show_preferences):
main_box.append(separator_2)
timespans_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
-
+
add_timespan_button = Gtk.Button(label=_("Add Timespan"))
+ add_timespan_button.set_halign(Gtk.Align.CENTER)
add_timespan_button.get_style_context().add_class("pill")
add_timespan_button.get_style_context().add_class("suggested-action")
add_timespan_button.connect("clicked", add_timespan_clicked, self, timespans_box, 0, 0, 0, 0, 0, switch_enabled)
+
main_box.append(add_timespan_button)
main_box.append(timespans_box)
- schedulerDialog.connect("closed", save_schedule, self, switch_mode_1, switch_enabled, show_preferences, variaapp)
+ schedulerDialog.connect("closed", save_schedule, self, switch_mode_1, switch_enabled, show_preferences, variaapp, variaVersion)
# Build timespans from appconf:
for item in self.appconf["schedule"]:
diff --git a/src/window/sidebar.py b/src/window/sidebar.py
index 5edc51c..786c075 100644
--- a/src/window/sidebar.py
+++ b/src/window/sidebar.py
@@ -3,7 +3,7 @@
import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
-from gi.repository import Gtk, Adw, GLib, Gio
+from gi.repository import Gtk, Adw, Gio
from gettext import gettext as _
import textwrap
@@ -12,7 +12,7 @@
def window_create_sidebar(self, variaapp, DownloadThread, variaVersion):
sidebar_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
- sidebar_content_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
+ sidebar_content_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=2)
header_bar = Adw.HeaderBar()
header_bar.get_style_context().add_class('flat')
@@ -20,7 +20,7 @@ def window_create_sidebar(self, variaapp, DownloadThread, variaVersion):
preferences_button = Gtk.Button(tooltip_text=_("Preferences"))
preferences_button.set_icon_name("emblem-system-symbolic")
- preferences_button.connect("clicked", show_preferences, self, variaapp)
+ preferences_button.connect("clicked", show_preferences, self, variaapp, variaVersion)
hamburger_button = Gtk.MenuButton(tooltip_text=_("Other"))
hamburger_button.set_icon_name("open-menu-symbolic")
@@ -80,14 +80,47 @@ def window_create_sidebar(self, variaapp, DownloadThread, variaVersion):
header_bar.pack_start(preferences_button)
header_bar.pack_end(hamburger_button)
+ box_add_download = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=2)
+ box_add_download.set_margin_start(8)
+ box_add_download.set_margin_end(8)
+ box_add_download.set_margin_top(8)
+ box_add_download.set_margin_bottom(8)
+
download_entry = Gtk.Entry()
download_entry.set_placeholder_text(_("URL"))
- self.download_button = Gtk.Button(label=_("Download"))
- self.download_button.get_style_context().add_class("pill")
+ self.download_button_icon = Gtk.Image.new_from_icon_name("folder-download-symbolic")
+ self.download_button_text = Gtk.Label(label=_("Download"))
+ download_button_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=8)
+ download_button_box.append(self.download_button_icon)
+ download_button_box.append(self.download_button_text)
+
+ self.download_button = Gtk.Button()
+ self.download_button.set_child(download_button_box)
self.download_button.get_style_context().add_class("suggested-action")
+ self.download_button.set_sensitive(False)
self.download_button.connect("clicked", on_download_clicked, self, download_entry, DownloadThread)
+ download_entry.connect('changed', on_download_entry_changed, self.download_button)
+
+ torrent_button_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=8)
+ torrent_button_box.append(Gtk.Image.new_from_icon_name("document-open-symbolic"))
+ torrent_button_box.append(Gtk.Label(label=_("Torrent")))
+
+ add_torrent_button = Gtk.Button()
+ add_torrent_button.get_style_context().add_class("suggested-action")
+ add_torrent_button.set_child(torrent_button_box)
+ add_torrent_button.connect("clicked", on_add_torrent_clicked, self)
+
+ box_add_download.append(download_entry)
+ box_add_download.append(self.download_button)
+ box_add_download.append(Gtk.Separator(margin_top=8, margin_bottom=8))
+ box_add_download.append(add_torrent_button)
+
+ frame_add_download = Gtk.Frame()
+ frame_add_download.set_margin_bottom(8)
+ frame_add_download.set_child(box_add_download)
+
self.filter_button_show_all = Gtk.ToggleButton()
self.filter_button_show_all.get_style_context().add_class('flat')
filter_button_show_all_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10)
@@ -149,13 +182,6 @@ def window_create_sidebar(self, variaapp, DownloadThread, variaVersion):
self.filter_button_show_failed.set_child(filter_button_show_failed_box)
self.filter_button_show_failed.connect("clicked", self.filter_download_list, "show_failed")
- sidebar_separator = Gtk.Separator()
- sidebar_separator.set_margin_top(8)
- sidebar_separator.set_margin_bottom(8)
-
- sidebar_expanding_box = Gtk.Box()
- Gtk.Widget.set_vexpand(sidebar_expanding_box, True)
-
self.sidebar_shutdown_mode_label = Gtk.Label()
self.sidebar_remote_mode_label = Gtk.Label()
if (self.appconf['remote'] == '1'):
@@ -165,7 +191,6 @@ def window_create_sidebar(self, variaapp, DownloadThread, variaVersion):
sidebar_content_box.set_margin_start(6)
sidebar_content_box.set_margin_end(6)
- sidebar_content_box.set_margin_top(6)
sidebar_content_box.set_margin_bottom(6)
sidebar_filter_buttons_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=2)
@@ -175,11 +200,9 @@ def window_create_sidebar(self, variaapp, DownloadThread, variaVersion):
sidebar_filter_buttons_box.append(self.filter_button_show_seeding)
sidebar_filter_buttons_box.append(self.filter_button_show_failed)
- sidebar_content_box.append(download_entry)
- sidebar_content_box.append(self.download_button)
- sidebar_content_box.append(sidebar_separator)
+ sidebar_content_box.append(frame_add_download)
sidebar_content_box.append(sidebar_filter_buttons_box)
- sidebar_content_box.append(sidebar_expanding_box)
+ sidebar_content_box.append(Gtk.Box(vexpand=True))
sidebar_content_box.append(self.sidebar_shutdown_mode_label)
sidebar_content_box.append(self.sidebar_remote_mode_label)
sidebar_content_box.append(self.sidebar_speed_limited_label)
@@ -188,6 +211,26 @@ def window_create_sidebar(self, variaapp, DownloadThread, variaVersion):
self.overlay_split_view.set_sidebar(sidebar_box)
+def on_download_entry_changed(entry, download_button):
+ if entry.get_text() != "":
+ download_button.set_sensitive(True)
+ else:
+ download_button.set_sensitive(False)
+
+def on_add_torrent_clicked(self, variaapp):
+ file_filter = Gtk.FileFilter()
+ file_filter.add_pattern("*.torrent")
+ dialog = Gtk.FileDialog(default_filter=file_filter)
+ dialog.open(variaapp, None, on_add_torrent, variaapp)
+
+def on_add_torrent(file_dialog, result, self):
+ try:
+ file = file_dialog.open_finish(result).get_path()
+ except:
+ return
+ if file.endswith(".torrent"):
+ self.api.add_torrent(file)
+
def background_mode(app, variaapp1, self, variaapp):
self.exitProgram(app=app, variaapp=variaapp, background=True)
@@ -207,17 +250,18 @@ def show_about(app, variaapp, self, variaVersion):
dialog.set_application_icon("io.github.giantpinkrobots.varia")
dialog.set_translator_credits(_("translator-credits"))
dialog.set_artists(["Jakub Steiner"])
- dialog.set_release_notes_version("v2024.5.7")
+ dialog.set_release_notes_version("v2024.11.7")
dialog.set_release_notes('''
- Download scheduling: Start or stop downloading in given timespans.
- cookies.txt file import support.
- Remote timestamp support.
- Options to filter by seeding and failed downloads in the sidebar.
- Quit on completion option.
- Start in background mode option.
- Spanish language support.
- Persian language support.
- Hindi language support. ''')
+ Support for opening .torrent files.
+ Downloads now show the estimated time remaining.
+ UI tweaks and fixes for a better layout.
+ Remote mode option is available again.
+ A lot of under the hood changes to fix bugs and improve performance.
+ Update to the GNOME 47 runtime and new Libadwaita widgets.
+ Support for Bulgarian and Chinese (China) languages.
+ (Only on Windows) Automatic update function.
+ (Only on Windows) Support for localization.
+ (Only on Windows) All icons are shown properly everywhere. ''')
dialog.present(self)
diff --git a/src/window/updater.py b/src/window/updater.py
new file mode 100644
index 0000000..b88d693
--- /dev/null
+++ b/src/window/updater.py
@@ -0,0 +1,184 @@
+import gi
+gi.require_version('Gtk', '4.0')
+gi.require_version('Adw', '1')
+from gi.repository import Gtk, Adw, GLib
+from gettext import gettext as _
+import json
+import threading
+import os
+import subprocess
+
+update_download_progress = 0
+
+def windows_updater(bannerButton, app, variaapp, parentWindow, variaVersion, mode):
+ if mode == 1:
+ if parentWindow is not None:
+ parentWindow.close()
+
+ # Show checking for updates dialog
+ checking_dialog = Adw.AlertDialog()
+ checking_dialog_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=25)
+ checking_dialog.set_child(checking_dialog_box)
+ checking_dialog_box.set_margin_top(30)
+ checking_dialog_box.set_margin_bottom(30)
+ checking_dialog_box.set_margin_start(60)
+ checking_dialog_box.set_margin_end(60)
+ checking_dialog_spinner = Adw.Spinner()
+ checking_dialog_spinner.set_size_request(30, 30)
+ checking_dialog_box.append(checking_dialog_spinner)
+ checking_dialog_label = Gtk.Label(label=_("Checking for updates..."))
+ checking_dialog_label.get_style_context().add_class("title-1")
+ checking_dialog_box.append(checking_dialog_label)
+ checking_dialog.set_can_close(False)
+ checking_dialog.present(app)
+
+ else:
+ checking_dialog = None
+
+ if os.path.exists(os.path.join(app.appdir, 'updater-all-releases.txt')):
+ os.remove(os.path.join(app.appdir, 'updater-all-releases.txt'))
+
+ thread = threading.Thread(target=lambda: start_update_check(variaVersion, app, variaapp, checking_dialog, mode))
+ thread.start()
+
+def start_update_check(variaVersion, app, variaapp, checking_dialog, mode):
+ print(os.path.join(app.appdir, 'updater-all-releases.txt'))
+ process = subprocess.Popen(
+ [os.path.join(os.getcwd(), app.aria2cexec), '--quiet=true', '--console-log-level=warn', '--download-result=hide',
+ '--out=updater-all-releases.txt', 'https://api.github.com/repos/giantpinkrobots/varia/releases'],
+ text=True, shell=True, cwd = app.appdir
+ )
+
+ process.wait()
+
+ if os.path.exists(os.path.join(app.appdir, 'updater-all-releases.txt')):
+ all_releases = open(os.path.join(app.appdir, 'updater-all-releases.txt')).read()
+ os.remove(os.path.join(app.appdir, 'updater-all-releases.txt'))
+ else:
+ latest_name_for_windows = "failed"
+
+ i = 0
+ while True:
+ try:
+ contents = json.loads(all_releases)[i]
+ except:
+ print("Couldn't check for updates.")
+ latest_name_for_windows = "failed"
+ break
+
+ latest_name_for_windows = contents["name"]
+ latest_windows_binary_url = 'https://github.com/giantpinkrobots/varia/releases/download/' + latest_name_for_windows + '/varia-windows-setup-amd64.exe'
+
+ if latest_windows_binary_url in all_releases:
+ break
+ else:
+ i += 1
+ if i > len(json.loads(all_releases)):
+ print("Couldn't check for updates.")
+ latest_name_for_windows = "failed"
+ break
+
+ if checking_dialog != None:
+ checking_dialog.set_can_close(True)
+ checking_dialog.close()
+
+ if latest_name_for_windows != variaVersion and latest_name_for_windows != "failed":
+ if mode == 1:
+ GLib.idle_add(show_update_question_dialog, update_pressed, latest_windows_binary_url, latest_name_for_windows, app, variaapp)
+ else:
+ GLib.idle_add(show_update_available_banner, windows_updater, app, variaapp, variaVersion)
+
+def show_update_question_dialog(update_pressed, latest_windows_binary_url, latest_name_for_windows, app, variaapp):
+ update_question_dialog = Adw.AlertDialog()
+ update_question_dialog.set_body(_("A new version of Varia is available. Do you want to update?"))
+ update_question_dialog.add_response("yes", _("Yes"))
+ update_question_dialog.add_response("no", _("No"))
+ update_question_dialog.set_response_appearance("yes", Adw.ResponseAppearance.SUGGESTED)
+ update_question_dialog.connect("response", update_pressed, latest_windows_binary_url, latest_name_for_windows, app, variaapp)
+ update_question_dialog.set_close_response("no")
+ update_question_dialog.present(app)
+
+def show_update_available_banner(windows_updater, app, variaapp, variaVersion):
+ app.update_available_banner = Adw.Banner(title=_("Update available"))
+ app.update_available_banner.set_button_label(_("Update"))
+ app.update_available_banner.connect("button-clicked", windows_updater, app, variaapp, None, variaVersion, 1)
+ app.update_available_banner.set_revealed(True)
+ app.content_box.insert_child_after(app.update_available_banner, app.header_bar)
+
+def update_pressed(dialog, response_id, latest_windows_binary_url, latest_name_for_windows, app, variaapp):
+ dialog.set_can_close(True)
+ dialog.close()
+ dialog = None
+
+ if response_id == "no":
+ print("Don't update")
+ else:
+ print("Begin update")
+
+ update_downloading_dialog = Adw.AlertDialog()
+ update_downloading_dialog_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=25)
+ update_downloading_dialog.set_child(update_downloading_dialog_box)
+ update_downloading_dialog_box.set_margin_top(30)
+ update_downloading_dialog_box.set_margin_bottom(30)
+ update_downloading_dialog_box.set_margin_start(60)
+ update_downloading_dialog_box.set_margin_end(60)
+
+ update_downloading_dialog_spinner = Adw.Spinner()
+ update_downloading_dialog_spinner.set_size_request(30, 30)
+ update_downloading_dialog_box.append(update_downloading_dialog_spinner)
+
+ update_downloading_dialog_label = Gtk.Label(label=_("Downloading update..."))
+ update_downloading_dialog_label.get_style_context().add_class("title-1")
+ update_downloading_dialog_box.append(update_downloading_dialog_label)
+
+ update_downloading_dialog_progress_bar = Gtk.ProgressBar()
+ update_downloading_dialog_box.append(update_downloading_dialog_progress_bar)
+
+ update_downloading_dialog.set_can_close(False)
+ update_downloading_dialog.present(app)
+
+ def download_update():
+ global update_download_progress
+ process = subprocess.Popen(
+ [app.aria2cexec, '--dir=' + app.appconf['download_directory'], '--out=variaUpdate-' + latest_name_for_windows + '.exe', '--quiet=false', '--summary-interval=1', latest_windows_binary_url],
+ shell=True, text=True, bufsize=1, stdout=subprocess.PIPE, stderr=subprocess.STDOUT
+ )
+
+ while(True):
+ if process.poll() != None:
+ break
+
+ i = 0
+ latest_output = ""
+
+ try:
+ for line in iter(process.stdout.readline, b''):
+ latest_output = latest_output + line
+ i += 1
+ if i == 2:
+ break
+
+ if ('(' in latest_output) and ('%' in latest_output):
+ open_parenthesis_location = latest_output.find('(') + 1
+ percent_location = latest_output.find('%')
+ current_percentage = int(latest_output[open_parenthesis_location: percent_location]) / 100
+ GLib.idle_add(update_downloading_dialog_progress_bar.set_fraction, current_percentage)
+ except:
+ pass
+
+ update_downloading_dialog.set_can_close(True)
+ update_downloading_dialog.close()
+
+ if process.returncode == 0:
+ update_downloading_dialog_progress_bar.set_fraction(100)
+ app.update_executable = os.path.join(app.appconf['download_directory'], "variaUpdate-" + latest_name_for_windows + ".exe")
+ app.exitProgram(variaapp, variaapp, background=False)
+ else:
+ dialog = Adw.AlertDialog()
+ dialog.set_body(_("Download failed."))
+ dialog.add_response("ok", _("OK"))
+ dialog.set_close_response("ok")
+ dialog.present(app)
+
+ thread = threading.Thread(target=download_update)
+ thread.start()