207 lines
5.9 KiB
Python
207 lines
5.9 KiB
Python
from .. import protocol, var
|
|
from ..extensions import WebExtensions
|
|
from ..functions import connect
|
|
from ..widgets import FileChooser
|
|
|
|
|
|
class WebContext(WebKit2.WebContext):
|
|
def __init__(self, app):
|
|
self.app = app
|
|
|
|
## Setup storage
|
|
self.storage = WebKit2.WebsiteDataManager(
|
|
base_data_directory = app.path.storage,
|
|
base_cache_directory = app.path.cache
|
|
)
|
|
|
|
super().__init__(website_data_manager = self.storage)
|
|
|
|
self.extensions = WebExtensions(self)
|
|
|
|
self.set_property('use-system-appearance-for-scrollbars', True)
|
|
#self.set_web_extensions_initialization_user_data(GLib.Variant.new_string('heck'))
|
|
self.set_spell_checking_enabled(True)
|
|
self.set_favicon_database_directory(app.path.favicon)
|
|
self.set_web_extensions_directory(app.path.script.join('bin'))
|
|
self.set_cache_model(WebKit2.CacheModel(1))
|
|
self.set_use_system_appearance_for_scrollbars(True)
|
|
|
|
## Setup Cookie storage
|
|
self.cookiemanager = self.get_cookie_manager()
|
|
self.cookiemanager.set_persistent_storage(app.path.cookies, WebKit2.CookiePersistentStorage(1))
|
|
self.cookiemanager.set_accept_policy(WebKit2.CookieAcceptPolicy(2))
|
|
|
|
## Register local uri schemes
|
|
self.security_manager = self.get_security_manager()
|
|
self.security_manager.register_uri_scheme_as_local(var.local) #Local webui
|
|
self.security_manager.register_uri_scheme_as_local('bsweb://')
|
|
self.security_manager.register_uri_scheme_as_local('local://') #Renamed "file://" handler
|
|
self.security_manager.register_uri_scheme_as_secure('oauth://')
|
|
|
|
## Setup custom protocols
|
|
self.register_uri_scheme(var.local_proto, protocol.Local)
|
|
self.register_uri_scheme('bsweb', protocol.LocalWeb)
|
|
self.register_uri_scheme('sftp', protocol.Sftp)
|
|
self.register_uri_scheme('source', protocol.Source)
|
|
self.register_uri_scheme(protocol.Oauth.protocol, protocol.Oauth)
|
|
|
|
## Webkit won't let me set these normally
|
|
self.register_uri_scheme('filetp', protocol.Ftp)
|
|
self.register_uri_scheme('local', protocol.File)
|
|
|
|
## Connect context signals
|
|
self.connect('download-started', self.handle_new_download)
|
|
self.connect('user-message-received', self.extensions.handle_command)
|
|
|
|
|
|
@property
|
|
def window(self):
|
|
return self.app.window
|
|
|
|
|
|
def handle_new_download(self, context, download):
|
|
NewDownload(self, download)
|
|
|
|
|
|
class NewDownload(Gtk.Builder):
|
|
# Might use a response instead of a class var for the dialog
|
|
response = DotDict(
|
|
accept = Gtk.ResponseType.ACCEPT,
|
|
reject = Gtk.ResponseType.REJECT,
|
|
close = Gtk.ResponseType.CLOSE,
|
|
none = Gtk.ResponseType.NONE
|
|
)
|
|
|
|
|
|
def __init__(self, context, download):
|
|
super().__init__()
|
|
self.add_from_file(context.app.path.resources.join('download.ui'))
|
|
|
|
with context.app.db.session as s:
|
|
download_dir = s.get_config('download_dir')
|
|
|
|
self.app = context.app
|
|
self.context = context
|
|
self.window = context.window
|
|
self.download = download
|
|
self.cancel = False
|
|
self.data = DotDict(
|
|
filename = None,
|
|
path = download_dir,
|
|
url = download.get_request().get_uri()
|
|
)
|
|
|
|
self.dialog = self['download-window']
|
|
self.dialog.set_attached_to(context.window)
|
|
self.download.set_allow_overwrite(True)
|
|
|
|
# Connect dialog signals
|
|
self.Connect('download-filename', 'changed', self.handle_dialog_change_filename)
|
|
self.Connect('download-filename-set', 'clicked', self.handle_dialog_set_filename)
|
|
self.Connect('download-cancel', 'clicked', self.handle_dialog_close, True)
|
|
self.Connect('download-save', 'clicked', self.handle_dialog_close, False)
|
|
self.Connect('download-window', 'delete-event', self.dialog.destroy)
|
|
|
|
# Connect download signals
|
|
connect(download, 'decide-destination', self.handle_download_decide_destination, original_args=True)
|
|
connect(download, 'created-destination', self.handle_download_created_destination)
|
|
connect(download, 'failed', self.handle_download_failed, original_args=True)
|
|
connect(download, 'finished', self.handle_download_finish)
|
|
|
|
|
|
def __getitem__(self, key):
|
|
return self.get_object(key)
|
|
|
|
|
|
@property
|
|
def filename(self):
|
|
return Path(self['download-filename'].get_text())
|
|
|
|
|
|
@filename.setter
|
|
def filename(self, text):
|
|
self['download-filename'].set_text(text or '')
|
|
|
|
|
|
@property
|
|
def url(self):
|
|
return self['download-url'].get_text()
|
|
|
|
|
|
@url.setter
|
|
def url(self, text):
|
|
self['download-url'].set_text(text or '')
|
|
|
|
|
|
def Connect(self, name, signal, callback, *args, **kwargs):
|
|
return connect(self[name], signal, callback, *args, **kwargs)
|
|
|
|
|
|
def target_path(self, full=True):
|
|
path = self.data.path.join(self.data.filename)
|
|
|
|
if full:
|
|
return f'file://{path}'
|
|
|
|
return path
|
|
|
|
|
|
def handle_dialog_close(self, cancel):
|
|
self.cancel = cancel
|
|
self.dialog.destroy()
|
|
|
|
|
|
def handle_dialog_change_filename(self):
|
|
self.data.path, self.data.filename = self.filename.parent, self.filename.name
|
|
|
|
self['download-save'].set_label('Overwrite' if self.filename.exists() else 'Save')
|
|
|
|
|
|
def handle_dialog_set_filename(self):
|
|
with FileChooser(self.dialog, self.data.path, self.data.filename) as fc:
|
|
if not fc:
|
|
logging.verbose('Canceled file selector')
|
|
return
|
|
|
|
self.filename = fc
|
|
|
|
|
|
def handle_download_created_destination(self):
|
|
logging.debug(f'Created desination for file: {self.target_path(False)}')
|
|
|
|
|
|
def handle_download_decide_destination(self, download, filename):
|
|
self.data.filename = filename
|
|
self.url = self.data.url
|
|
self.filename = self.target_path(False)
|
|
self.handle_dialog_change_filename()
|
|
|
|
self.dialog.run()
|
|
|
|
if self.cancel:
|
|
download.cancel()
|
|
|
|
else:
|
|
download.set_destination(self.target_path())
|
|
|
|
|
|
def handle_download_failed(self, download, error):
|
|
if error.code == 400:
|
|
self.cancel = True
|
|
return
|
|
|
|
data = DotDict({
|
|
'args': error.args,
|
|
'code': error.code,
|
|
'domain': error.domain,
|
|
'message': error.message
|
|
})
|
|
|
|
logging.debug(data.to_json(4))
|
|
self.window.notification(f'Download failed: {self.target_path(False)}', system=True)
|
|
|
|
|
|
def handle_download_finish(self):
|
|
if not self.cancel:
|
|
self.window.notification(f'Download finished: {self.target_path(False)}', system=True)
|