mirror of
https://github.com/morgan9e/warehouse
synced 2026-04-14 00:04:08 +09:00
Continue work on data pages
This commit is contained in:
@@ -238,6 +238,7 @@ class HostInfo:
|
||||
icon_theme.add_search_path(f"{i}/exports/share/icons")
|
||||
|
||||
flatpaks = []
|
||||
id_to_flatpak = {}
|
||||
ref_to_flatpak = {}
|
||||
remotes = {}
|
||||
installations = []
|
||||
@@ -248,6 +249,7 @@ class HostInfo:
|
||||
def get_flatpaks(this, callback=None):
|
||||
# Callback is a function to run after the host flatpaks are found
|
||||
this.flatpaks.clear()
|
||||
this.id_to_flatpak.clear()
|
||||
this.ref_to_flatpak.clear()
|
||||
this.remotes.clear()
|
||||
this.installations.clear()
|
||||
@@ -336,6 +338,7 @@ class HostInfo:
|
||||
for i in lines:
|
||||
package = Flatpak(i.split("\t"))
|
||||
this.flatpaks.append(package)
|
||||
this.id_to_flatpak[package.info["id"]] = package
|
||||
this.ref_to_flatpak[package.info["ref"]] = package
|
||||
|
||||
# Dependant Runtimes
|
||||
|
||||
@@ -63,12 +63,14 @@ class WarehouseWindow(Adw.ApplicationWindow):
|
||||
page.instance.start_loading()
|
||||
|
||||
def end_loading(self, *args):
|
||||
for _, page in self.pages.items():
|
||||
if page.instance:
|
||||
page.instance.end_loading()
|
||||
for _, page in self.pages.items():
|
||||
if page.instance:
|
||||
page.instance.end_loading()
|
||||
self.refresh_button.set_sensitive(True)
|
||||
|
||||
def refresh_handler(self, *args):
|
||||
self.start_loading()
|
||||
self.refresh_button.set_sensitive(False)
|
||||
HostInfo.get_flatpaks(callback=self.end_loading)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
|
||||
@@ -12,8 +12,7 @@ blueprints = custom_target('blueprints',
|
||||
'properties_page/properties_page.blp',
|
||||
'user_data_page/data_box.blp',
|
||||
'user_data_page/user_data_page.blp',
|
||||
'user_data_page/active_data_page.blp',
|
||||
'user_data_page/leftover_data_page.blp',
|
||||
'user_data_page/data_subpage.blp',
|
||||
'change_version_page/change_version_page.blp',
|
||||
),
|
||||
output: '.',
|
||||
@@ -66,8 +65,7 @@ warehouse_sources = [
|
||||
'change_version_page/change_version_page.py',
|
||||
'user_data_page/data_box.py',
|
||||
'user_data_page/user_data_page.py',
|
||||
'user_data_page/active_data_page.py',
|
||||
'user_data_page/leftover_data_page.py',
|
||||
'user_data_page/data_subpage.py',
|
||||
'../data/style.css',
|
||||
]
|
||||
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
using Gtk 4.0;
|
||||
using Adw 1;
|
||||
|
||||
template $ActiveDataPage : ScrolledWindow {
|
||||
Box {
|
||||
orientation: vertical;
|
||||
Box {
|
||||
orientation: vertical;
|
||||
margin-start: 24;
|
||||
margin-end: 24;
|
||||
Label {
|
||||
label: _("Active User Data");
|
||||
styles ["title-1"]
|
||||
hexpand: true;
|
||||
halign: start;
|
||||
}
|
||||
Label {
|
||||
label: "32 Items - 39.7 GB";
|
||||
styles ["title-3"]
|
||||
hexpand: true;
|
||||
halign: start;
|
||||
}
|
||||
}
|
||||
Separator {
|
||||
margin-start: 12;
|
||||
margin-end: 12;
|
||||
margin-top: 9;
|
||||
margin-bottom: 6;
|
||||
}
|
||||
FlowBox flow_box {
|
||||
styles ["boxed-list"]
|
||||
homogeneous: true;
|
||||
valign: start;
|
||||
selection-mode: none;
|
||||
max-children-per-line: 6;
|
||||
margin-start: 12;
|
||||
margin-end: 12;
|
||||
margin-bottom: 12;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
from gi.repository import Adw, Gtk, GLib, Gio, Pango
|
||||
from .host_info import HostInfo
|
||||
from .error_toast import ErrorToast
|
||||
from .data_box import DataBox
|
||||
import pathlib, os
|
||||
|
||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/user_data_page/active_data_page.ui")
|
||||
class ActiveDataPage(Gtk.ScrolledWindow):
|
||||
__gtype_name__ = 'ActiveDataPage'
|
||||
gtc = Gtk.Template.Child
|
||||
|
||||
flow_box = gtc()
|
||||
|
||||
def generate_list(self, *args):
|
||||
data = f"{HostInfo.home}/.var/app"
|
||||
for folder in os.listdir(data):
|
||||
print(folder)
|
||||
|
||||
def __init__(self, main_window, data_page, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.generate_list()
|
||||
|
||||
# self.select_button.connect("toggled", lambda *_: self.set_selection_mode(self.select_button.get_active()))
|
||||
# self.flow_box.connect("child-activated", lambda _, item: (cb := (row := item.get_child()).check_button).set_active((not cb.get_active()) if row.get_activatable() else False))
|
||||
|
||||
# Extra Object Creation
|
||||
|
||||
# Apply
|
||||
|
||||
# Connections
|
||||
@@ -13,7 +13,7 @@ template $DataBox : ListBox {
|
||||
Box title_box {
|
||||
margin-top: 12;
|
||||
margin-bottom: 12;
|
||||
Image app_icon {
|
||||
Image image {
|
||||
margin-start: 12;
|
||||
margin-end: 12;
|
||||
icon-name: "application-x-executable-symbolic";
|
||||
@@ -31,7 +31,7 @@ template $DataBox : ListBox {
|
||||
}
|
||||
Label subtitle_label {
|
||||
label: "No subtitle set";
|
||||
hexpand: true;
|
||||
// hexpand: true;
|
||||
halign: start;
|
||||
ellipsize: middle;
|
||||
margin-end: 12;
|
||||
@@ -43,6 +43,9 @@ template $DataBox : ListBox {
|
||||
margin-start: 12;
|
||||
margin-end: 6;
|
||||
margin-bottom: 6;
|
||||
Spinner spinner {
|
||||
spinning: true;
|
||||
}
|
||||
Label size_label {
|
||||
label: "No size set";
|
||||
halign: start;
|
||||
|
||||
@@ -1,13 +1,32 @@
|
||||
from gi.repository import Adw, Gtk, GLib, Gio, Pango
|
||||
from .host_info import HostInfo
|
||||
import subprocess
|
||||
|
||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/user_data_page/data_box.ui")
|
||||
class DataBox(Gtk.ListBox):
|
||||
__gtype_name__ = 'DataBox'
|
||||
gtc = Gtk.Template.Child
|
||||
|
||||
image = gtc()
|
||||
title_label = gtc()
|
||||
subtitle_label = gtc()
|
||||
size_label = gtc()
|
||||
check_button = gtc()
|
||||
|
||||
def __init__(self, main_window, path, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
def idle_stuff(self):
|
||||
self.title_label.set_label(self.title)
|
||||
self.subtitle_label.set_label(self.subtitle)
|
||||
if self.icon_path:
|
||||
self.image.add_css_class("icon-dropshadow")
|
||||
self.image.set_from_file(self.icon_path)
|
||||
|
||||
def __init__(self, title, subtitle, data_path, icon_path=None, callback=None, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.title = title
|
||||
self.subtitle = subtitle
|
||||
self.icon_path = icon_path
|
||||
self.data_path = data_path
|
||||
self.callback = callback
|
||||
|
||||
self.idle_stuff()
|
||||
|
||||
60
src/user_data_page/data_subpage.blp
Normal file
60
src/user_data_page/data_subpage.blp
Normal file
@@ -0,0 +1,60 @@
|
||||
using Gtk 4.0;
|
||||
using Adw 1;
|
||||
|
||||
template $DataSubpage : ScrolledWindow {
|
||||
Box {
|
||||
orientation: vertical;
|
||||
Box {
|
||||
orientation: vertical;
|
||||
margin-start: 24;
|
||||
margin-end: 24;
|
||||
Label title {
|
||||
label: _("No Title Set");
|
||||
styles ["title-1"]
|
||||
hexpand: true;
|
||||
halign: start;
|
||||
}
|
||||
Box {
|
||||
Label subtitle {
|
||||
label: "No Subtutle Set";
|
||||
styles ["title-3"]
|
||||
}
|
||||
Image {
|
||||
icon-name: "dot-symbolic";
|
||||
margin-start: 6;
|
||||
margin-end: 6;
|
||||
margin-top: 3;
|
||||
valign: center;
|
||||
}
|
||||
Spinner spinner {
|
||||
spinning: true;
|
||||
valign: center;
|
||||
margin-top: 3;
|
||||
margin-end: 6;
|
||||
}
|
||||
Label size_label {
|
||||
label: _("Loading Size…");
|
||||
styles ["title-3"]
|
||||
hexpand: true;
|
||||
halign: start;
|
||||
}
|
||||
}
|
||||
}
|
||||
Separator {
|
||||
margin-start: 12;
|
||||
margin-end: 12;
|
||||
margin-top: 9;
|
||||
margin-bottom: 6;
|
||||
}
|
||||
FlowBox flow_box {
|
||||
styles ["boxed-list"]
|
||||
homogeneous: true;
|
||||
valign: start;
|
||||
selection-mode: none;
|
||||
max-children-per-line: 6;
|
||||
margin-start: 12;
|
||||
margin-end: 12;
|
||||
margin-bottom: 12;
|
||||
}
|
||||
}
|
||||
}
|
||||
86
src/user_data_page/data_subpage.py
Normal file
86
src/user_data_page/data_subpage.py
Normal file
@@ -0,0 +1,86 @@
|
||||
from gi.repository import Adw, Gtk, GLib, Gio, Pango
|
||||
from .host_info import HostInfo
|
||||
from .error_toast import ErrorToast
|
||||
from .data_box import DataBox
|
||||
from .host_info import HostInfo
|
||||
import subprocess
|
||||
|
||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/user_data_page/data_subpage.ui")
|
||||
class DataSubpage(Gtk.ScrolledWindow):
|
||||
__gtype_name__ = 'DataSubpage'
|
||||
gtc = Gtk.Template.Child
|
||||
|
||||
title = gtc()
|
||||
subtitle = gtc()
|
||||
spinner = gtc()
|
||||
size_label = gtc()
|
||||
flow_box = gtc()
|
||||
|
||||
def human_readable_size(self, size):
|
||||
units = ['KB', 'MB', 'GB', 'TB']
|
||||
# size *= 1024
|
||||
for unit in units:
|
||||
if size < 1024:
|
||||
return f"~ {round(size)} {unit}"
|
||||
size /= 1024
|
||||
return f"~ {round(size)} PB"
|
||||
|
||||
def get_size(self, path):
|
||||
sed = "sed 's/K/ KB/; s/M/ MB/; s/G/ GB/; s/T/ TB/; s/P/ PB/;'"
|
||||
self.total_size += int(subprocess.run(['du', '-s', path], capture_output=True, text=True).stdout.split("\t")[0])
|
||||
|
||||
def show_size(self, data):
|
||||
for folder in data:
|
||||
self.get_size(f"{HostInfo.home}/.var/app/{folder}")
|
||||
|
||||
self.size_label.set_label(self.human_readable_size(self.total_size))
|
||||
self.spinner.set_visible(False)
|
||||
|
||||
def generate_list(self, sort_mode, data=None, paks=None):
|
||||
self.total_size = 0
|
||||
Gio.Task().run_in_thread(lambda *_: self.show_size(data))
|
||||
self.flow_box.remove_all()
|
||||
total = len(data)
|
||||
GLib.idle_add(lambda *_z: self.subtitle.set_label(_("{} Items").format(total)))
|
||||
self.boxes.clear()
|
||||
|
||||
def thread(sort_mode, data, paks):
|
||||
if paks:
|
||||
for package in paks:
|
||||
folder = package.info["id"]
|
||||
box = DataBox(package.info["name"], folder, f"{HostInfo.home}/.var/app/{folder}", package.icon_path)
|
||||
self.boxes.append(box)
|
||||
else:
|
||||
for folder in data:
|
||||
box = DataBox(folder.split('.')[-1], folder, f"{HostInfo.home}/.var/app/{folder}")
|
||||
self.boxes.append(box)
|
||||
|
||||
def callback(sort_mode):
|
||||
if sort_mode == "name":
|
||||
self.boxes = sorted(self.boxes, key=lambda box: box.title)
|
||||
elif sort_mode == "id":
|
||||
self.boxes = sorted(self.boxes, key=lambda box: box.subtitle)
|
||||
else:
|
||||
pass
|
||||
|
||||
for box in self.boxes:
|
||||
self.flow_box.append(box)
|
||||
|
||||
Gio.Task.new(None, None, lambda *_: callback(sort_mode)).run_in_thread(lambda *_: thread(sort_mode, data, paks))
|
||||
|
||||
def __init__(self, title, main_window, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
GLib.idle_add(lambda *_: self.title.set_label(title))
|
||||
|
||||
# self.select_button.connect("toggled", lambda *_: self.set_selection_mode(self.select_button.get_active()))
|
||||
# self.flow_box.connect("child-activated", lambda _, item: (cb := (row := item.get_child()).check_button).set_active((not cb.get_active()) if row.get_activatable() else False))
|
||||
|
||||
# Extra Object Creation
|
||||
self.main_window = main_window
|
||||
self.total_size = 0
|
||||
self.boxes = []
|
||||
|
||||
# Apply
|
||||
|
||||
# Connections
|
||||
@@ -1,41 +0,0 @@
|
||||
using Gtk 4.0;
|
||||
using Adw 1;
|
||||
|
||||
template $LeftoverDataPage : ScrolledWindow {
|
||||
Box {
|
||||
orientation: vertical;
|
||||
Box {
|
||||
orientation: vertical;
|
||||
margin-start: 24;
|
||||
margin-end: 24;
|
||||
Label {
|
||||
label: _("Leftover User Data");
|
||||
styles ["title-1"]
|
||||
hexpand: true;
|
||||
halign: start;
|
||||
}
|
||||
Label {
|
||||
label: "25 Items - 18.6 GB";
|
||||
styles ["title-3"]
|
||||
hexpand: true;
|
||||
halign: start;
|
||||
}
|
||||
}
|
||||
Separator {
|
||||
margin-start: 12;
|
||||
margin-end: 12;
|
||||
margin-top: 9;
|
||||
margin-bottom: 6;
|
||||
}
|
||||
FlowBox {
|
||||
styles ["boxed-list"]
|
||||
homogeneous: true;
|
||||
valign: start;
|
||||
selection-mode: none;
|
||||
max-children-per-line: 6;
|
||||
margin-start: 12;
|
||||
margin-end: 12;
|
||||
margin-bottom: 12;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
from gi.repository import Adw, Gtk, GLib, Gio, Pango
|
||||
from .host_info import HostInfo
|
||||
from .error_toast import ErrorToast
|
||||
from .data_box import DataBox
|
||||
|
||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/user_data_page/leftover_data_page.ui")
|
||||
class LeftoverDataPage(Gtk.ScrolledWindow):
|
||||
__gtype_name__ = 'LeftoverDataPage'
|
||||
gtc = Gtk.Template.Child
|
||||
|
||||
def __init__(self, main_window, data_page, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Extra Object Creation
|
||||
|
||||
# Apply
|
||||
|
||||
# Connections
|
||||
@@ -1,7 +1,9 @@
|
||||
from gi.repository import Adw, Gtk, GLib, Gio, Pango
|
||||
from .error_toast import ErrorToast
|
||||
from .active_data_page import ActiveDataPage
|
||||
from .leftover_data_page import LeftoverDataPage
|
||||
from .data_box import DataBox
|
||||
from .data_subpage import DataSubpage
|
||||
from .host_info import HostInfo
|
||||
import os
|
||||
|
||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/user_data_page/user_data_page.ui")
|
||||
class UserDataPage(Adw.BreakpointBin):
|
||||
@@ -47,11 +49,33 @@ class UserDataPage(Adw.BreakpointBin):
|
||||
# elif self.switcher_bar.get_reveal():
|
||||
# self.header_bar.set_show_title(False)
|
||||
|
||||
def sort_data(self, *args):
|
||||
self.data_flatpaks.clear()
|
||||
self.active_data.clear()
|
||||
self.leftover_data.clear()
|
||||
# paks = dict(HostInfo.id_to_flatpak)
|
||||
|
||||
for folder in os.listdir(f"{HostInfo.home}/.var/app"):
|
||||
try:
|
||||
self.data_flatpaks.append(HostInfo.id_to_flatpak[folder])
|
||||
self.active_data.append(folder)
|
||||
except KeyError:
|
||||
self.leftover_data.append(folder)
|
||||
|
||||
def start_loading(self, *args):
|
||||
self.adp.size_label.set_label("Loading Size…")
|
||||
self.adp.spinner.set_visible(True)
|
||||
self.ldp.size_label.set_label("Loading Size…")
|
||||
self.ldp.spinner.set_visible(True)
|
||||
pass
|
||||
|
||||
def end_loading(self, *args):
|
||||
pass
|
||||
self.sort_mode = "id"
|
||||
def callback(*args):
|
||||
self.adp.generate_list(self.sort_mode, data=self.active_data, paks=self.data_flatpaks)
|
||||
self.ldp.generate_list(self.sort_mode, data=self.leftover_data)
|
||||
|
||||
Gio.Task.new(None, None, callback).run_in_thread(self.sort_data)
|
||||
|
||||
def __init__(self, main_window, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
@@ -59,16 +83,22 @@ class UserDataPage(Adw.BreakpointBin):
|
||||
# Extra Object Creation
|
||||
self.__class__.instance = self
|
||||
# self.adj = self.scrolled_window.get_vadjustment()
|
||||
self.adp = DataSubpage(_("Active Data"), main_window)
|
||||
self.ldp = DataSubpage(_("Leftover Data"), main_window)
|
||||
self.data_flatpaks = []
|
||||
self.active_data = []
|
||||
self.leftover_data = []
|
||||
self.total_items = 0
|
||||
|
||||
# Apply
|
||||
self.stack.add_titled_with_icon(
|
||||
child=ActiveDataPage(main_window, self),
|
||||
child=self.adp,
|
||||
name="active",
|
||||
title=_("Active Data"),
|
||||
icon_name="file-manager-symbolic",
|
||||
)
|
||||
self.stack.add_titled_with_icon(
|
||||
child=LeftoverDataPage(main_window, self),
|
||||
child=self.ldp,
|
||||
name="leftover",
|
||||
title=_("Leftover Data"),
|
||||
icon_name="folder-templates-symbolic",
|
||||
|
||||
@@ -11,8 +11,7 @@
|
||||
<file preprocess="xml-stripblanks">change_version_page/change_version_page.ui</file>
|
||||
<file preprocess="xml-stripblanks">user_data_page/data_box.ui</file>
|
||||
<file preprocess="xml-stripblanks">user_data_page/user_data_page.ui</file>
|
||||
<file preprocess="xml-stripblanks">user_data_page/active_data_page.ui</file>
|
||||
<file preprocess="xml-stripblanks">user_data_page/leftover_data_page.ui</file>
|
||||
<file preprocess="xml-stripblanks">user_data_page/data_subpage.ui</file>
|
||||
<!-- <file preprocess="xml-stripblanks">../data/io.github.flattool.Warehouse.metainfo.xml.in</file> -->
|
||||
</gresource>
|
||||
<gresource prefix="/io/github/flattool/Warehouse/icons/scalable/actions/">
|
||||
|
||||
Reference in New Issue
Block a user