Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 25 additions & 4 deletions browser_extension/background.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
let startTime;
let startTime = Date.now();

async function initializeStartTime() {
const data = await chrome.storage.local.get(['startTime']);
if (!data.startTime) {
startTime = Date.now();
chrome.storage.local.set({ startTime });
} else {
startTime = data.startTime;
Expand All @@ -12,10 +11,23 @@ async function initializeStartTime() {

initializeStartTime();

chrome.runtime.onStartup.addListener(function () {
startTime = Date.now();
chrome.storage.local.set({ startTime });
});

chrome.runtime.onInstalled.addListener(function (details) {
if (details.reason === 'install') {
chrome.storage.sync.set({ enabled: true, cookieTransferFile: true, cookieTransferVideo: true });
}

chrome.contextMenus.removeAll(() => {
chrome.contextMenus.create({
id: "download-with-varia",
title: "Download with Varia",
contexts: ["link", "image", "video", "audio"]
});
});
});

chrome.downloads.onCreated.addListener(function (downloadItem) {
Expand Down Expand Up @@ -121,7 +133,7 @@ async function sendToAria2(downloadItem, downloadType) {
const data = await response.json();
console.log("Aria2 response:", data);

if (downloadType === "file" && data.result) {
if (downloadType === "file" && data.result && downloadItem.id) {
chrome.downloads.cancel(downloadItem.id);
}

Expand Down Expand Up @@ -167,4 +179,13 @@ async function getCookies(downloadUrl, downloadType) {

return btoa(json);
}
}
}

chrome.contextMenus.onClicked.addListener(function (info, tab) {
if (info.menuItemId === "download-with-varia") {
let downloadUrl = info.linkUrl || info.srcUrl;
if (downloadUrl) {
sendToAria2({ url: downloadUrl }, "file");
}
}
});
3 changes: 2 additions & 1 deletion browser_extension/manifest-chromium.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"downloads",
"storage",
"tabs",
"cookies"
"cookies",
"contextMenus"
],
"host_permissions": [
"<all_urls>"
Expand Down
3 changes: 2 additions & 1 deletion browser_extension/manifest-firefox.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
"storage",
"<all_urls>",
"tabs",
"cookies"
"cookies",
"contextMenus"
],
"manifest_version": 3,
"background": {
Expand Down
27 changes: 27 additions & 0 deletions browser_extension/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "Varia Integrator",
"description": "Route all downloads to Varia if it's running.",
"version": "1.5.4",
"icons": {
"16": "icon16.png",
"48": "icon48.png",
"128": "icon128.png"
},
"action": {
"default_popup": "popup.html"
},
"permissions": [
"downloads",
"storage",
"tabs",
"cookies",
"contextMenus"
],
"host_permissions": [
"<all_urls>"
],
"manifest_version": 3,
"background": {
"service_worker": "background.js"
}
}
51 changes: 49 additions & 2 deletions src/download/actionrow.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
gi.require_version('Adw', '1')
from gi.repository import Gtk, Adw, Pango, GLib, Gio
from stringstorage import gettext as _
from download.thread import DownloadThread
from download.thread import DownloadThread, get_category_for_filename
from urllib.parse import urlparse
from download.details import show_download_details_dialog
import json
import os
Expand All @@ -20,6 +21,26 @@ def on_download_clicked(button, self, entry, downloadname, download, mode, video
video_options = json.loads(video_options)

if url:
is_torrent_url = url.startswith("magnet:") or url.lower().split('?')[0].endswith(".torrent")

if self.appconf.get("automatic_sorting_enabled", "0") == "1" and not is_torrent_url:
name_to_check = downloadname
if not name_to_check:
try:
parsed_url = urlparse(url)
name_to_check = os.path.basename(parsed_url.path)
except:
pass
category = get_category_for_filename(name_to_check)
if category:
if not dir.endswith(category) and os.path.basename(dir) != category:
dir = os.path.join(dir, category)
try:
if not os.path.exists(dir):
os.makedirs(dir)
except:
pass

if downloadname:
download_item = create_actionrow(self, downloadname)

Expand Down Expand Up @@ -72,6 +93,14 @@ def create_actionrow(self, filename):
percentage_label.set_margin_end(4)
percentage_and_filename_box.append(percentage_label)

non_resumable_badge = Gtk.Label()
non_resumable_badge.set_markup("<span foreground='#e01b24' size='small' weight='bold'>⚠️ " + _("No Resume") + "</span>")
non_resumable_badge.set_margin_end(6)
non_resumable_badge.set_valign(Gtk.Align.CENTER)
non_resumable_badge.set_visible(False)
non_resumable_badge.set_tooltip_text(_("This download does not support resuming. If paused, it will restart from the beginning."))
percentage_and_filename_box.append(non_resumable_badge)

filename_label = Gtk.Label(label=filename)
filename_label.set_ellipsize(Pango.EllipsizeMode.END)
filename_label.set_halign(Gtk.Align.START)
Expand Down Expand Up @@ -136,6 +165,7 @@ def create_actionrow(self, filename):
download_item.stop_button = stop_button
download_item.filename_label = filename_label
download_item.info_button = info_button
download_item.non_resumable_badge = non_resumable_badge

return download_item

Expand All @@ -144,7 +174,24 @@ def on_pause_clicked(button, self, pause_button, download_item, force_pause, run
download_item.download_thread.resume()

else:
download_item.download_thread.pause()
if download_item.download_thread.download_details.get('resumable') == _("No") and not force_pause:
dialog = Adw.AlertDialog()
dialog.set_heading(_("Pause Non-Resumable Download?"))
dialog.set_body(_("This download does not support resuming. If you pause it, the download will restart from 0% when you resume it. Are you sure you want to pause?"))
dialog.add_response("cancel", _("Cancel"))
dialog.add_response("pause", _("Pause Anyway"))
dialog.set_response_appearance("pause", Adw.ResponseAppearance.DESTRUCTIVE)
dialog.set_default_response("cancel")
dialog.set_close_response("cancel")

def handle_response(d, response):
if response == "pause":
download_item.download_thread.pause()

dialog.connect("response", handle_response)
dialog.present(self)
else:
download_item.download_thread.pause()

def on_stop_clicked(button, self, download_item):
download_item.download_thread.stop()
Expand Down
6 changes: 6 additions & 0 deletions src/download/details.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ def show_download_details_dialog(button, self, download_item):
actionrow_download_download_speed.add_suffix(label_download_speed)
group_1.add(actionrow_download_download_speed)

actionrow_download_resumable = Adw.ActionRow(title=_("Supports Resume"), tooltip_text=_("Supports Resume") + ": " + download_item.download_thread.download_details.get('resumable', '...'))
label_resumable = Gtk.Label(label=download_item.download_thread.download_details.get('resumable', '...'))
actionrow_download_resumable.add_suffix(label_resumable)
group_1.add(actionrow_download_resumable)

# Peers

scrolled_window = None
Expand Down Expand Up @@ -190,6 +195,7 @@ def update_details():
label_percentage.set_text(details.get('percentage', ''))
label_remaining.set_text(details.get('remaining', ''))
label_download_speed.set_text(details.get('download_speed', ''))
label_resumable.set_text(details.get('resumable', ''))

if self.details_dialog_message_actionrow_added == False and download_item and download_item.download_thread.download_message_shown and download_item.download_thread.download_details.get('message', '') != '':
label_download_message.set_text(download_item.download_thread.download_details.get('message', ''))
Expand Down
32 changes: 29 additions & 3 deletions src/download/manage_downloads.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
from stringstorage import gettext as _
import gi
gi.require_version('Gtk', '4.0')
from gi.repository import GLib
gi.require_version('Adw', '1')
from gi.repository import GLib, Adw

def pause_all(self, called_by_scheduler):
if len(self.downloads) > 0:
Expand All @@ -11,8 +12,33 @@ def pause_all(self, called_by_scheduler):
download_thread.resume(called_by_scheduler)

else:
for download_thread in self.downloads:
download_thread.pause(called_by_scheduler)
# Check if any active download is not resumable
active_non_resumable_downloads = []
for d in self.downloads:
if not d.is_complete and not d.cancelled and not d.paused:
if d.download_details.get('resumable') == _("No"):
active_non_resumable_downloads.append(d)

if active_non_resumable_downloads and not called_by_scheduler:
dialog = Adw.AlertDialog()
dialog.set_heading(_("Pause Non-Resumable Downloads?"))
dialog.set_body(_("One or more active downloads do not support resuming. If you pause them, their progress will be lost and they will restart from 0% when resumed. Are you sure you want to pause all?"))
dialog.add_response("cancel", _("Cancel"))
dialog.add_response("pause", _("Pause All Anyway"))
dialog.set_response_appearance("pause", Adw.ResponseAppearance.DESTRUCTIVE)
dialog.set_default_response("cancel")
dialog.set_close_response("cancel")

def handle_response(d, response):
if response == "pause":
for download_thread in self.downloads:
download_thread.pause(called_by_scheduler)

dialog.connect("response", handle_response)
dialog.present(self)
else:
for download_thread in self.downloads:
download_thread.pause(called_by_scheduler)

def stop_all(self, app, variaapp):
while self.downloads != []:
Expand Down
Loading