Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version window #248

Merged
merged 23 commits into from
Sep 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
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
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ Pinned requirements
.. code:: bash

pip install pip-tools
pip-compile requirements.in > requirements.txt
pip-compile --resolver=backtracking requirements.in > requirements.txt

GTK debugging
^^^^^^^^^^^^^
Expand Down
31 changes: 30 additions & 1 deletion dtool_lookup_gui/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
import dtoolcore
import dtool_lookup_api.core.config

from dtool_lookup_api.core.LookupClient import authenticate

import gi
gi.require_version('Gtk', '3.0')
gi.require_version('GtkSource', '4')
Expand All @@ -44,7 +46,9 @@

from .models.settings import settings


from .views.main_window import MainWindow
from .views.login_window import LoginWindow

from .utils.logging import _log_nested

Expand All @@ -56,7 +60,6 @@
import dtool_lookup_gui.widgets.progress_chart
import dtool_lookup_gui.widgets.progress_popover_menu


logger = logging.getLogger(__name__)

from . import __version__
Expand Down Expand Up @@ -225,6 +228,11 @@ def do_startup(self):
export_config_action.connect("activate", self.do_export_config)
self.add_action(export_config_action)

# renew-token action
renew_token_action = Gio.SimpleAction.new("renew-token", GLib.VariantType.new("(sss)"))
renew_token_action.connect("activate", self.do_renew_token)
self.add_action(renew_token_action)

Gtk.Application.do_startup(self)

# custom application-scoped actions
Expand Down Expand Up @@ -308,6 +316,27 @@ def do_dtool_config_changed(self):
first when emitting dtool-config-changed signal."""
logger.debug("method handler for 'dtool-config-changed' called.")

def do_renew_token(self, action, value):
"""Request new token."""

# Unpack the username, password, and auth_url from the tuple variant
username, password, auth_url = value.unpack()

async def retrieve_token(auth_url, username, password):
try:
token = await authenticate(auth_url, username, password)
except Exception as e:
logger.error(str(e))
return

dtool_lookup_api.core.config.Config.token = token
self.emit('dtool-config-changed')

asyncio.create_task(retrieve_token(
auth_url,
username,
password))


def run_gui():
GObject.type_register(GtkSource.View)
Expand Down
12 changes: 11 additions & 1 deletion dtool_lookup_gui/models/datasets.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import asyncio
import logging
import os
import json

import yaml
from concurrent.futures import ProcessPoolExecutor
Expand All @@ -37,6 +38,8 @@
from dtool_info.inventory import _dataset_info
from dtool_lookup_api.core.LookupClient import ConfigurationBasedLookupClient



from ..utils.logging import _log_nested
from ..utils.multiprocessing import StatusReportingChildProcessBuilder, process_initializer
from ..utils.progressbar import ProgressBar
Expand Down Expand Up @@ -280,12 +283,19 @@ async def query(cls, query_text, *args, **kwargs):
return [await cls.from_lookup(lookup_dict) for lookup_dict in datasets]

@classmethod
async def query_all(cls, page_number=1, page_size=8, pagination={}):
async def query_all(cls, page_number=1, page_size=10, pagination={}):
"""Query all datasets from the lookup server."""
async with ConfigurationBasedLookupClient() as lookup:
datasets = await lookup.all(page_number=page_number, page_size=page_size, pagination=pagination)
return [await cls.from_lookup(lookup_dict) for lookup_dict in datasets]

@classmethod
async def versions(cls):
"""To return version info from the server """
async with ConfigurationBasedLookupClient() as lookup:
version_info = await lookup.versions()
print(version_info)

def __str__(self):
return self._dataset_info['uri']

Expand Down
81 changes: 81 additions & 0 deletions dtool_lookup_gui/views/login_window.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import logging
import os
import dtoolcore
from gi.repository import Gio, GLib, Gtk, Gdk
from dtool_lookup_api.core.config import Config
from ..utils.about import pretty_version_text
from ..utils.logging import _log_nested
from .settings_dialog import SettingsDialog

# Initialize logging
logger = logging.getLogger(__name__)

@Gtk.Template(filename=f'{os.path.dirname(__file__)}/login_window.ui')
class LoginWindow(Gtk.Window):
__gtype_name__ = 'LoginWindow'

# Map GTK Template Child widgets to Python attributes
username_entry = Gtk.Template.Child()
password_entry = Gtk.Template.Child()
login_button = Gtk.Template.Child()
skip_button = Gtk.Template.Child()
settings_button = Gtk.Template.Child()

# Initialize the LoginWindow instance
def __init__(self, follow_up_action=None, *args, **kwargs):
super().__init__(*args, **kwargs)
self.application = self.get_application()
self.settings_dialog = SettingsDialog(application=self.application)
self._follow_up_action = follow_up_action

# Set the default values from the Config, ensuring they are not None
if Config.username is not None:
self.username_entry.set_text(Config.username)
if Config.password is not None: # Consider security implications
self.password_entry.set_text(Config.password)



# Handle the 'Login' button click event
@Gtk.Template.Callback()
def on_login_button_clicked(self, widget):



# Fetch entered username and password
username = self.username_entry.get_text()
password = self.password_entry.get_text()

# Create a GLib Variant tuple for authentication
user_pass_auth_variant = GLib.Variant.new_tuple(
GLib.Variant.new_string(username),
GLib.Variant.new_string(password),
GLib.Variant.new_string(Config.auth_url)
)

# Trigger the 'renew-token' action for authentication
self.get_action_group("app").activate_action('renew-token', user_pass_auth_variant)

if self._follow_up_action is not None:
self._follow_up_action()

self.close()

# Handle the 'Skip' button click event
@Gtk.Template.Callback()
def on_skip_button_clicked(self, widget):
# Close the login window
self.close()

@Gtk.Template.Callback()
def settings_button_clicked_cb(self, widget):
logger.info("Settings button clicked. Opening settings dialog.")
self.settings_dialog.show()

# Handle the window close event
@Gtk.Template.Callback()
def on_delete(self, widget, event):
# Hide the window instead of deleting it
return self.hide_on_delete()


193 changes: 193 additions & 0 deletions dtool_lookup_gui/views/login_window.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<interface>
<requires lib="gtk+" version="3.24"/>
<template class="LoginWindow" parent="GtkWindow">
<property name="can-focus">False</property>
<property name="default-width">400</property>
<property name="default-height">300</property>
<signal name="delete-event" handler="on_delete" swapped="no"/>
<child>
<!-- n-columns=3 n-rows=3 -->
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="margin-start">50</property>
<property name="margin-end">50</property>
<property name="margin-top">50</property>
<property name="margin-bottom">50</property>
<property name="orientation">vertical</property>
<child>
<!-- n-columns=3 n-rows=3 -->
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="row-spacing">12</property>
<property name="column-spacing">12</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">User Name</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="username_entry">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">Password</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="password_entry">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="hexpand">True</property>
<property name="visibility">False</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkButtonBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="layout-style">end</property>
<child>
<object class="GtkButton" id="skip_button">
<property name="label" translatable="yes">Skip</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<signal name="clicked" handler="on_skip_button_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="login_button">
<property name="label" translatable="yes">Login</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<signal name="clicked" handler="on_login_button_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
<property name="width">2</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
<child type="titlebar">
<object class="GtkHeaderBar">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="title" translatable="yes">Login</property>
<property name="show-close-button">True</property>
<child>
<object class="GtkButton" id="settings_button">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="halign">end</property>
<signal name="clicked" handler="settings_button_clicked_cb" swapped="no"/>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">preferences-system-symbolic</property>
</object>
</child>
</object>
</child>
</object>
</child>
</template>
</interface>
Loading
Loading