Updated CHANGELOG.md, documented a bunch of stuff and fixed a lot of warnings.
This commit is contained in:
parent
be2f789652
commit
af8365675d
9 changed files with 204 additions and 89 deletions
14
CHANGELOG.md
14
CHANGELOG.md
|
@ -2,17 +2,17 @@
|
||||||
|
|
||||||
Commit 1
|
Commit 1
|
||||||
- Removed `on_shutdown` function from `src/main.rs`, as it was uselessly dropping memory that was automatically dropped right after the function ended.
|
- Removed `on_shutdown` function from `src/main.rs`, as it was uselessly dropping memory that was automatically dropped right after the function ended.
|
||||||
- Finished the documentation for `src/main.rs`, `src/packages/installed.rs`, `src/packages/browse.rs`, and `src/packages/mod.rs`
|
- Finished the documentation for `src/main.rs`, `src/packages/installed.rs`, `src/packages/browse.rs`, and `src/packages/mod.rs`.
|
||||||
- Renamed `show_installed_package` to `show_package`, and merged it into `src/packages/mod.rs` instead of having copies in two files.
|
- Renamed `show_installed_package` to `show_package`, and merged it into `src/packages/mod.rs` instead of having copies in two files.
|
||||||
- Added this changelog.
|
- Added this changelog.
|
||||||
- Updated `inst.sh` so that it no longer copies `style.css` to the `/usr/share/oreon-system-manager` directory.
|
- Updated `inst.sh` so that it no longer copies `style.css` to the `/usr/share/oreon-system-manager` directory.
|
||||||
|
|
||||||
Commit 2
|
Commit 2
|
||||||
- Moved `drivers` to it's own module folder
|
- Moved `drivers` to it's own module folder.
|
||||||
- Added `src/drivers/mod.rs` and `src/drivers/objects.rs`
|
- Added `src/drivers/mod.rs` and `src/drivers/objects.rs`.
|
||||||
|
|
||||||
Commit 3
|
Commit 3
|
||||||
- Fixed crash on package description fetch
|
- Fixed crash on package description fetch.
|
||||||
|
|
||||||
Commit 4
|
Commit 4
|
||||||
- Added very basic support for Docker images.
|
- Added very basic support for Docker images.
|
||||||
|
@ -20,3 +20,9 @@ Commit 4
|
||||||
Commit 5
|
Commit 5
|
||||||
- Added almost full support for Docker images.
|
- Added almost full support for Docker images.
|
||||||
- Created an interface between Rust and the `docker image inspect` command using Serde.
|
- Created an interface between Rust and the `docker image inspect` command using Serde.
|
||||||
|
|
||||||
|
Commit 6
|
||||||
|
- Documented everything in the containers module.
|
||||||
|
- Switched to using `cargo clippy` and fixed all of the warnings that it showed.
|
||||||
|
- Renamed `src/containers/core.rs` to `src/containers/api.rs`.
|
||||||
|
- Moved the `Image` struct to the `api` submodule instead of having it in the main `containers` module.
|
||||||
|
|
|
@ -2,6 +2,38 @@ use std::collections::BTreeMap;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Struct for a docker image, with the basic
|
||||||
|
details from the `docker images` command.
|
||||||
|
*/
|
||||||
|
pub struct Image {
|
||||||
|
pub repository: String,
|
||||||
|
pub tag: String,
|
||||||
|
pub id: String,
|
||||||
|
pub created: String,
|
||||||
|
pub size: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Implement `FromStr` for `Image` so that
|
||||||
|
the output of the `docker images` command
|
||||||
|
can be parsed into computer-interpretable
|
||||||
|
data.
|
||||||
|
*/
|
||||||
|
impl std::str::FromStr for Image {
|
||||||
|
type Err = String;
|
||||||
|
fn from_str(value: &str) -> Result<Self, String> {
|
||||||
|
let parts: Vec<String> = value.split_whitespace().map(|x| x.to_owned()).collect();
|
||||||
|
Ok(Self {
|
||||||
|
repository: parts[0].clone(),
|
||||||
|
tag: parts[1].clone(),
|
||||||
|
id: parts[2].clone(),
|
||||||
|
created: parts[3..(parts.len() - 1)].join(" "),
|
||||||
|
size: parts[parts.len() - 1].clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A struct for handling the output of the `docker image inspect`
|
A struct for handling the output of the `docker image inspect`
|
||||||
command.
|
command.
|
||||||
|
@ -25,6 +57,10 @@ pub struct ImageInspectData {
|
||||||
pub metadata: IIMetadata,
|
pub metadata: IIMetadata,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Implementation to allow for testing data, should be removed
|
||||||
|
in release versions to reduce the file size and line count.
|
||||||
|
*/
|
||||||
impl Default for ImageInspectData {
|
impl Default for ImageInspectData {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
ImageInspectData {
|
ImageInspectData {
|
||||||
|
@ -47,6 +83,7 @@ impl Default for ImageInspectData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The struct for the `config` property of `ImageInspectData`
|
||||||
#[derive(Clone, Serialize, Deserialize, Debug)]
|
#[derive(Clone, Serialize, Deserialize, Debug)]
|
||||||
pub struct IIConfig {
|
pub struct IIConfig {
|
||||||
pub hostname: String,
|
pub hostname: String,
|
||||||
|
@ -70,6 +107,10 @@ pub struct IIConfig {
|
||||||
pub labels: Option<IIConfigLabels>,
|
pub labels: Option<IIConfigLabels>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Implementation to allow for testing data, should be removed
|
||||||
|
in release versions to reduce the file size and line count.
|
||||||
|
*/
|
||||||
impl Default for IIConfig {
|
impl Default for IIConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
IIConfig {
|
IIConfig {
|
||||||
|
@ -94,14 +135,20 @@ impl Default for IIConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Type for the `labels` property of `IIConfig`
|
||||||
pub type IIConfigLabels = BTreeMap<String, String>;
|
pub type IIConfigLabels = BTreeMap<String, String>;
|
||||||
|
|
||||||
|
/// Struct for the `graph_driver` property of `ImageInspectData`
|
||||||
#[derive(Clone, Serialize, Deserialize, Debug)]
|
#[derive(Clone, Serialize, Deserialize, Debug)]
|
||||||
pub struct IIGraphDriver {
|
pub struct IIGraphDriver {
|
||||||
pub data: GraphDriverData,
|
pub data: GraphDriverData,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Implementation to allow for testing data, should be removed
|
||||||
|
in release versions to reduce the file size and line count.
|
||||||
|
*/
|
||||||
impl Default for IIGraphDriver {
|
impl Default for IIGraphDriver {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
IIGraphDriver {
|
IIGraphDriver {
|
||||||
|
@ -111,12 +158,18 @@ impl Default for IIGraphDriver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The `data` property of `IIGraphDriver`
|
||||||
#[derive(Clone, Serialize, Deserialize, Debug)]
|
#[derive(Clone, Serialize, Deserialize, Debug)]
|
||||||
pub struct GraphDriverData {
|
pub struct GraphDriverData {
|
||||||
pub merged_dir: String,
|
pub merged_dir: String,
|
||||||
pub upper_dir: String,
|
pub upper_dir: String,
|
||||||
pub work_dir: String,
|
pub work_dir: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Implementation to allow for testing data, should be removed
|
||||||
|
in release versions to reduce the file size and line count.
|
||||||
|
*/
|
||||||
impl Default for GraphDriverData {
|
impl Default for GraphDriverData {
|
||||||
fn default() -> GraphDriverData {
|
fn default() -> GraphDriverData {
|
||||||
GraphDriverData {
|
GraphDriverData {
|
||||||
|
@ -127,12 +180,17 @@ impl Default for GraphDriverData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Struct for defining the `rootfs` property of `ImageInspectData`
|
||||||
#[derive(Clone, Serialize, Deserialize, Debug)]
|
#[derive(Clone, Serialize, Deserialize, Debug)]
|
||||||
pub struct IIRootFS {
|
pub struct IIRootFS {
|
||||||
pub r#type: String,
|
pub r#type: String,
|
||||||
pub layers: Vec<String>,
|
pub layers: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Implementation to allow for testing data, should be removed
|
||||||
|
in release versions to reduce the file size and line count.
|
||||||
|
*/
|
||||||
impl Default for IIRootFS {
|
impl Default for IIRootFS {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
IIRootFS {
|
IIRootFS {
|
||||||
|
@ -142,11 +200,16 @@ impl Default for IIRootFS {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Struct for the `metadata` property of `ImageInspectData`
|
||||||
#[derive(Clone, Serialize, Deserialize, Debug)]
|
#[derive(Clone, Serialize, Deserialize, Debug)]
|
||||||
pub struct IIMetadata {
|
pub struct IIMetadata {
|
||||||
pub last_tag_time: String,
|
pub last_tag_time: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Implementation to allow for testing data, should be removed
|
||||||
|
in release versions to reduce the file size and line count.
|
||||||
|
*/
|
||||||
impl Default for IIMetadata {
|
impl Default for IIMetadata {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
IIMetadata {
|
IIMetadata {
|
|
@ -4,13 +4,17 @@ use gtk::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
containers::{self, core::ImageInspectData},
|
containers::api::{change_keys, Image, ImageInspectData},
|
||||||
pkexec,
|
pkexec,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::Image;
|
/**
|
||||||
|
Subsection of the containers page to display
|
||||||
|
Docker imags provided from the `docker images`
|
||||||
|
command.
|
||||||
|
*/
|
||||||
pub fn images() -> gtk::Box {
|
pub fn images() -> gtk::Box {
|
||||||
|
// Box for displaying the list of images.
|
||||||
let images_box = gtk::Box::builder()
|
let images_box = gtk::Box::builder()
|
||||||
.orientation(gtk::Orientation::Vertical)
|
.orientation(gtk::Orientation::Vertical)
|
||||||
.build();
|
.build();
|
||||||
|
@ -26,6 +30,7 @@ pub fn images() -> gtk::Box {
|
||||||
.map(|x| x.parse::<Image>().unwrap())
|
.map(|x| x.parse::<Image>().unwrap())
|
||||||
.collect::<Vec<Image>>();
|
.collect::<Vec<Image>>();
|
||||||
|
|
||||||
|
// Test image, remove in the main build.
|
||||||
images.push(Image {
|
images.push(Image {
|
||||||
repository: "Test".to_owned(),
|
repository: "Test".to_owned(),
|
||||||
tag: "something".to_owned(),
|
tag: "something".to_owned(),
|
||||||
|
@ -34,12 +39,22 @@ pub fn images() -> gtk::Box {
|
||||||
size: "100MB".to_owned(),
|
size: "100MB".to_owned(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
Loop through each of the images listed
|
||||||
|
from the `docker images` command and
|
||||||
|
create buttons and details for each of
|
||||||
|
them.
|
||||||
|
*/
|
||||||
for image in images {
|
for image in images {
|
||||||
let image_box = gtk::Box::builder()
|
let image_box = gtk::Box::builder()
|
||||||
.orientation(gtk::Orientation::Vertical)
|
.orientation(gtk::Orientation::Vertical)
|
||||||
.css_classes(["image-box"])
|
.css_classes(["image-box"])
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Generate boxes for each of these that show
|
||||||
|
[property name]: [value]
|
||||||
|
*/
|
||||||
image_box.append(&gen_box("Repository", &image.repository));
|
image_box.append(&gen_box("Repository", &image.repository));
|
||||||
image_box.append(&gen_box("Tag", &image.tag));
|
image_box.append(&gen_box("Tag", &image.tag));
|
||||||
image_box.append(&gen_box("Image ID", &image.id));
|
image_box.append(&gen_box("Image ID", &image.id));
|
||||||
|
@ -52,7 +67,12 @@ pub fn images() -> gtk::Box {
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
image_button.connect_clicked(|x| {
|
image_button.connect_clicked(|x| {
|
||||||
|
/*
|
||||||
|
Show the details for the image through a
|
||||||
|
function.
|
||||||
|
*/
|
||||||
show_image(
|
show_image(
|
||||||
|
// Get the image's unique image ID.
|
||||||
x.child()
|
x.child()
|
||||||
.expect("Failed to get image_button child!")
|
.expect("Failed to get image_button child!")
|
||||||
.downcast::<gtk::Box>()
|
.downcast::<gtk::Box>()
|
||||||
|
@ -79,17 +99,37 @@ pub fn images() -> gtk::Box {
|
||||||
images_box
|
images_box
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show_image(image_id: &str) {
|
/**
|
||||||
|
Function for showing the details of a Docker
|
||||||
|
image as a new window.
|
||||||
|
*/
|
||||||
|
pub fn show_image(image_id: &str) {
|
||||||
|
/*
|
||||||
|
Parse the details of the docker image inspect
|
||||||
|
command output through the `core.rs` interface.
|
||||||
|
*/
|
||||||
let image_details: Vec<ImageInspectData> =
|
let image_details: Vec<ImageInspectData> =
|
||||||
serde_json::from_str::<Vec<ImageInspectData>>(&containers::core::change_keys(
|
serde_json::from_str::<Vec<ImageInspectData>>(&change_keys(
|
||||||
pkexec("docker image inspect ".to_owned() + image_id, false)
|
pkexec("docker image inspect ".to_owned() + image_id, false)
|
||||||
.expect("This error should never occur"),
|
.expect("This error should never occur"),
|
||||||
))
|
))
|
||||||
.expect("Failed to get data");
|
.expect("Failed to get data");
|
||||||
|
|
||||||
|
/*
|
||||||
|
Shadow it with the first value, since there
|
||||||
|
will only be one item in the list when using
|
||||||
|
the image's ID.
|
||||||
|
|
||||||
|
TODO: Check that this is true.
|
||||||
|
*/
|
||||||
let image_details = image_details[0].clone();
|
let image_details = image_details[0].clone();
|
||||||
|
|
||||||
// TODO: Display the data.
|
/*
|
||||||
|
Create a window to store all of the image's
|
||||||
|
data from the inspect command.
|
||||||
|
|
||||||
|
TODO: Display the data.
|
||||||
|
*/
|
||||||
let image_window = Window::builder()
|
let image_window = Window::builder()
|
||||||
.title(format!("Image ID {image_id}").as_str())
|
.title(format!("Image ID {image_id}").as_str())
|
||||||
.default_width(600)
|
.default_width(600)
|
||||||
|
@ -101,6 +141,12 @@ fn show_image(image_id: &str) {
|
||||||
.css_classes(["image-showbox"])
|
.css_classes(["image-showbox"])
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Generate boxes for each of the components
|
||||||
|
of the image in the following format:
|
||||||
|
|
||||||
|
[component name]: [value]
|
||||||
|
*/
|
||||||
main_box.append(&gen_box("Author", &image_details.author));
|
main_box.append(&gen_box("Author", &image_details.author));
|
||||||
main_box.append(&gen_box("Comment", &image_details.comment));
|
main_box.append(&gen_box("Comment", &image_details.comment));
|
||||||
main_box.append(&gen_box("Id", &image_details.id));
|
main_box.append(&gen_box("Id", &image_details.id));
|
||||||
|
@ -117,6 +163,14 @@ fn show_image(image_id: &str) {
|
||||||
image_window.present();
|
image_window.present();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Function to generate a box for a property
|
||||||
|
of some object, in the following format:
|
||||||
|
|
||||||
|
[property name]: [value]
|
||||||
|
|
||||||
|
Where [property name] is in bold.
|
||||||
|
*/
|
||||||
pub fn gen_box(name: &str, content: &str) -> gtk::Box {
|
pub fn gen_box(name: &str, content: &str) -> gtk::Box {
|
||||||
let return_box = gtk::Box::builder()
|
let return_box = gtk::Box::builder()
|
||||||
.orientation(gtk::Orientation::Horizontal)
|
.orientation(gtk::Orientation::Horizontal)
|
||||||
|
|
|
@ -1,16 +1,13 @@
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
use gtk::{prelude::BoxExt, Stack, StackSidebar};
|
use gtk::{prelude::BoxExt, Stack, StackSidebar};
|
||||||
use images::images;
|
use images::images;
|
||||||
|
|
||||||
pub mod core;
|
pub mod api;
|
||||||
pub mod images;
|
pub mod images;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Page for managing Docker containers and images.
|
Page for managing Docker containers and images.
|
||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
- Move to it's own file/folder
|
|
||||||
- Add the following pages: "Containers", "Images", "Browse"
|
- Add the following pages: "Containers", "Images", "Browse"
|
||||||
*/
|
*/
|
||||||
pub fn containers() -> gtk::Box {
|
pub fn containers() -> gtk::Box {
|
||||||
|
@ -20,6 +17,7 @@ pub fn containers() -> gtk::Box {
|
||||||
.css_classes(["containers-box"])
|
.css_classes(["containers-box"])
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
// Stack to contain each of the pages.
|
||||||
let containers_stack = Stack::builder()
|
let containers_stack = Stack::builder()
|
||||||
.halign(gtk::Align::Fill)
|
.halign(gtk::Align::Fill)
|
||||||
.valign(gtk::Align::Fill)
|
.valign(gtk::Align::Fill)
|
||||||
|
@ -27,12 +25,14 @@ pub fn containers() -> gtk::Box {
|
||||||
.vexpand(true)
|
.vexpand(true)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
// Sidebar to allow the user to switch between pages.
|
||||||
let containers_sidebar = StackSidebar::builder()
|
let containers_sidebar = StackSidebar::builder()
|
||||||
.stack(&containers_stack)
|
.stack(&containers_stack)
|
||||||
.halign(gtk::Align::Start)
|
.halign(gtk::Align::Start)
|
||||||
.valign(gtk::Align::Fill)
|
.valign(gtk::Align::Fill)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
// Add each of the pages to the stack.
|
||||||
containers_stack.add_titled(&images(), Some("images"), "Images");
|
containers_stack.add_titled(&images(), Some("images"), "Images");
|
||||||
|
|
||||||
// Start the docker daemon if it isn't running.
|
// Start the docker daemon if it isn't running.
|
||||||
|
@ -40,31 +40,13 @@ pub fn containers() -> gtk::Box {
|
||||||
crate::pkexec("dockerd".to_owned(), true);
|
crate::pkexec("dockerd".to_owned(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append a new label as a title and return the box.
|
/*
|
||||||
|
Append the page switcher sidebar and the stack, in that order.
|
||||||
|
This is necessary, since otherwise the sidebar will be on the
|
||||||
|
wrong side.
|
||||||
|
*/
|
||||||
containers_box.append(&containers_sidebar);
|
containers_box.append(&containers_sidebar);
|
||||||
containers_box.append(&containers_stack);
|
containers_box.append(&containers_stack);
|
||||||
|
|
||||||
containers_box
|
containers_box
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Image {
|
|
||||||
pub repository: String,
|
|
||||||
pub tag: String,
|
|
||||||
pub id: String,
|
|
||||||
pub created: String,
|
|
||||||
pub size: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FromStr for Image {
|
|
||||||
type Err = String;
|
|
||||||
fn from_str(value: &str) -> Result<Self, String> {
|
|
||||||
let parts: Vec<String> = value.split_whitespace().map(|x| x.to_owned()).collect();
|
|
||||||
Ok(Self {
|
|
||||||
repository: parts[0].clone(),
|
|
||||||
tag: parts[1].clone(),
|
|
||||||
id: parts[2].clone(),
|
|
||||||
created: parts[3..(parts.len() - 2)].join(" "),
|
|
||||||
size: parts[(parts.len() - 2)..parts.len()].join(" "),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -126,15 +126,13 @@ pub fn installed_list() -> ScrolledWindow {
|
||||||
list.append(&btn);
|
list.append(&btn);
|
||||||
}
|
}
|
||||||
|
|
||||||
let scrollable = ScrolledWindow::builder()
|
ScrolledWindow::builder()
|
||||||
.child(&list)
|
.child(&list)
|
||||||
.width_request(300)
|
.width_request(300)
|
||||||
.height_request(600)
|
.height_request(600)
|
||||||
.halign(Align::Start)
|
.halign(Align::Start)
|
||||||
.css_classes(["installed_list"])
|
.css_classes(["installed_list"])
|
||||||
.build();
|
.build()
|
||||||
|
|
||||||
scrollable
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_driver_details() -> Vec<String> {
|
pub fn get_driver_details() -> Vec<String> {
|
||||||
|
@ -175,7 +173,7 @@ pub fn get_driver_details() -> Vec<String> {
|
||||||
.lines()
|
.lines()
|
||||||
.filter(|x| x.trim().contains("driver"))
|
.filter(|x| x.trim().contains("driver"))
|
||||||
.map(|x| {
|
.map(|x| {
|
||||||
x.split(":")
|
x.split(':')
|
||||||
.nth(1)
|
.nth(1)
|
||||||
.expect("Failed to find colon in driver definition.")
|
.expect("Failed to find colon in driver definition.")
|
||||||
.trim()
|
.trim()
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#![allow(clippy::assigning_clones)]
|
||||||
|
|
||||||
use gtk::{
|
use gtk::{
|
||||||
prelude::{BoxExt, ButtonExt, EditableExt},
|
prelude::{BoxExt, ButtonExt, EditableExt},
|
||||||
Button, PositionType,
|
Button, PositionType,
|
||||||
|
@ -44,7 +46,7 @@ pub fn browse() -> gtk::Box {
|
||||||
List of names to skip when searching, this is to remove the
|
List of names to skip when searching, this is to remove the
|
||||||
labels "Available Packages", "Last refreshed at ..." and "Installed Packages"
|
labels "Available Packages", "Last refreshed at ..." and "Installed Packages"
|
||||||
*/
|
*/
|
||||||
let skip_list = vec!["available", "installed", "last"];
|
let skip_list = ["available", "installed", "last"];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Initialize the packages list, needs to be a static
|
Initialize the packages list, needs to be a static
|
||||||
|
@ -75,14 +77,14 @@ pub fn browse() -> gtk::Box {
|
||||||
.split_whitespace()
|
.split_whitespace()
|
||||||
.next()
|
.next()
|
||||||
.unwrap_or("")
|
.unwrap_or("")
|
||||||
.split(".")
|
.split('.')
|
||||||
.next()
|
.next()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
b.to_string()
|
b.to_string()
|
||||||
})
|
})
|
||||||
.filter(|x| {
|
.filter(|x| {
|
||||||
!x.trim().is_empty()
|
!x.trim().is_empty()
|
||||||
&& !x.contains("=")
|
&& !x.contains('=')
|
||||||
&& !skip_list.contains(&x.to_lowercase().trim())
|
&& !skip_list.contains(&x.to_lowercase().trim())
|
||||||
})
|
})
|
||||||
.dedup()
|
.dedup()
|
||||||
|
@ -103,7 +105,7 @@ pub fn browse() -> gtk::Box {
|
||||||
package and a button for it in the memory at the same time,
|
package and a button for it in the memory at the same time,
|
||||||
which has caused as much as 1.4GB of RAM usage during tests.
|
which has caused as much as 1.4GB of RAM usage during tests.
|
||||||
*/
|
*/
|
||||||
for pkg in FULL_PKG_LIST[0..(50.min(FULL_PKG_LIST.len()))].to_vec() {
|
for pkg in FULL_PKG_LIST[0..(50.min(FULL_PKG_LIST.len()))].iter() {
|
||||||
PKG_LIST_INDEX += 1;
|
PKG_LIST_INDEX += 1;
|
||||||
let pkg_btn = Button::builder()
|
let pkg_btn = Button::builder()
|
||||||
.label(pkg)
|
.label(pkg)
|
||||||
|
@ -139,9 +141,11 @@ pub fn browse() -> gtk::Box {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.connect_edge_reached(|_, edge| {
|
.connect_edge_reached(|_, edge| {
|
||||||
if edge == PositionType::Bottom {
|
if edge == PositionType::Bottom {
|
||||||
for i in PKG_LIST_INDEX..((PKG_LIST_INDEX + 50).min(PKG_LIST.len())) {
|
for i in
|
||||||
|
PKG_LIST[PKG_LIST_INDEX..((PKG_LIST_INDEX + 50).min(PKG_LIST.len()))].iter()
|
||||||
|
{
|
||||||
let pkg_btn = Button::builder()
|
let pkg_btn = Button::builder()
|
||||||
.label(PKG_LIST[i].as_str())
|
.label(i.as_str())
|
||||||
.css_classes(["package-name"])
|
.css_classes(["package-name"])
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
@ -202,7 +206,7 @@ unsafe fn search(f: &SearchEntry) {
|
||||||
x.to_lowercase()
|
x.to_lowercase()
|
||||||
.contains(f.text().to_string().to_lowercase().as_str())
|
.contains(f.text().to_string().to_lowercase().as_str())
|
||||||
})
|
})
|
||||||
.map(|x| x.clone())
|
.cloned()
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -233,7 +237,7 @@ unsafe fn search(f: &SearchEntry) {
|
||||||
either 50 or the length of the list, whichever
|
either 50 or the length of the list, whichever
|
||||||
is less, and make buttons in the list for each
|
is less, and make buttons in the list for each
|
||||||
*/
|
*/
|
||||||
for pkg in PKG_LIST[0..(50.min(PKG_LIST.len()))].to_vec() {
|
for pkg in PKG_LIST[0..(50.min(PKG_LIST.len()))].iter() {
|
||||||
PKG_LIST_INDEX += 1;
|
PKG_LIST_INDEX += 1;
|
||||||
let pkg_btn = Button::builder()
|
let pkg_btn = Button::builder()
|
||||||
.label(pkg)
|
.label(pkg)
|
||||||
|
|
|
@ -51,7 +51,7 @@ pub fn installed() -> gtk::Box {
|
||||||
List of names to skip when searching, this is to remove the
|
List of names to skip when searching, this is to remove the
|
||||||
labels "Available Packages", "Last refreshed at ..." and "Installed Packages"
|
labels "Available Packages", "Last refreshed at ..." and "Installed Packages"
|
||||||
*/
|
*/
|
||||||
let skip_list = vec!["available", "installed", "last"];
|
let skip_list = ["available", "installed", "last"];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Initialize the packages list, needs to be a static
|
Initialize the packages list, needs to be a static
|
||||||
|
@ -88,14 +88,14 @@ pub fn installed() -> gtk::Box {
|
||||||
.split_whitespace()
|
.split_whitespace()
|
||||||
.next()
|
.next()
|
||||||
.unwrap_or("")
|
.unwrap_or("")
|
||||||
.split(".")
|
.split('.')
|
||||||
.next()
|
.next()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
b.to_string()
|
b.to_string()
|
||||||
})
|
})
|
||||||
.filter(|x| {
|
.filter(|x| {
|
||||||
!x.trim().is_empty()
|
!x.trim().is_empty()
|
||||||
&& !x.contains("=")
|
&& !x.contains('=')
|
||||||
&& !skip_list.contains(&x.to_lowercase().trim())
|
&& !skip_list.contains(&x.to_lowercase().trim())
|
||||||
})
|
})
|
||||||
.dedup()
|
.dedup()
|
||||||
|
@ -107,7 +107,7 @@ pub fn installed() -> gtk::Box {
|
||||||
package and a button for it in the memory at the same time,
|
package and a button for it in the memory at the same time,
|
||||||
which has caused as much as 1.4GB of RAM usage during tests.
|
which has caused as much as 1.4GB of RAM usage during tests.
|
||||||
*/
|
*/
|
||||||
for pkg in FULL_PKG_LIST[0..(50.min(FULL_PKG_LIST.len()))].to_vec() {
|
for pkg in FULL_PKG_LIST[0..(50.min(FULL_PKG_LIST.len()))].iter() {
|
||||||
PKG_LIST_INDEX += 1;
|
PKG_LIST_INDEX += 1;
|
||||||
let pkg_btn = Button::builder()
|
let pkg_btn = Button::builder()
|
||||||
.label(pkg)
|
.label(pkg)
|
||||||
|
@ -143,19 +143,23 @@ pub fn installed() -> gtk::Box {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.connect_edge_reached(|_, edge| {
|
.connect_edge_reached(|_, edge| {
|
||||||
if edge == PositionType::Bottom {
|
if edge == PositionType::Bottom {
|
||||||
for i in PKG_LIST_INDEX..((PKG_LIST_INDEX + 50).min(FULL_PKG_LIST.len())) {
|
(PKG_LIST_INDEX..((PKG_LIST_INDEX + 50).min(FULL_PKG_LIST.len()))).for_each(
|
||||||
let pkg_btn = Button::builder()
|
|i| {
|
||||||
.label(FULL_PKG_LIST[i].as_str())
|
let pkg_btn = Button::builder()
|
||||||
.css_classes(["package-name"])
|
.label(FULL_PKG_LIST[i].as_str())
|
||||||
.build();
|
.css_classes(["package-name"])
|
||||||
|
.build();
|
||||||
|
|
||||||
pkg_btn.connect_clicked(|x| {
|
pkg_btn.connect_clicked(|x| {
|
||||||
show_package(x.label().map(|x| x.to_string()).unwrap_or("".to_owned()));
|
show_package(
|
||||||
});
|
x.label().map(|x| x.to_string()).unwrap_or("".to_owned()),
|
||||||
PACKAGES_LIST.as_ref().unwrap().append(&pkg_btn);
|
);
|
||||||
|
});
|
||||||
|
PACKAGES_LIST.as_ref().unwrap().append(&pkg_btn);
|
||||||
|
|
||||||
PKG_LIST_INDEX += 1;
|
PKG_LIST_INDEX += 1;
|
||||||
}
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
@ -204,7 +208,7 @@ unsafe fn search(f: &SearchEntry) {
|
||||||
x.to_lowercase()
|
x.to_lowercase()
|
||||||
.contains(f.text().to_string().to_lowercase().as_str())
|
.contains(f.text().to_string().to_lowercase().as_str())
|
||||||
})
|
})
|
||||||
.map(|x| x.clone())
|
.cloned()
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -235,7 +239,7 @@ unsafe fn search(f: &SearchEntry) {
|
||||||
either 50 or the length of the list, whichever
|
either 50 or the length of the list, whichever
|
||||||
is less, and make buttons in the list for each
|
is less, and make buttons in the list for each
|
||||||
*/
|
*/
|
||||||
for pkg in PKG_LIST[0..(50.min(PKG_LIST.len()))].to_vec() {
|
for pkg in PKG_LIST[0..(50.min(PKG_LIST.len()))].iter() {
|
||||||
PKG_LIST_INDEX += 1;
|
PKG_LIST_INDEX += 1;
|
||||||
let pkg_btn = Button::builder()
|
let pkg_btn = Button::builder()
|
||||||
.label(pkg)
|
.label(pkg)
|
||||||
|
|
|
@ -112,11 +112,11 @@ fn show_package(pkg: String) {
|
||||||
*/
|
*/
|
||||||
for line in info.lines() {
|
for line in info.lines() {
|
||||||
if let Some(e) = line.trim().strip_prefix("Version") {
|
if let Some(e) = line.trim().strip_prefix("Version") {
|
||||||
version = e.split_once(":").unwrap().1.trim();
|
version = e.split_once(':').unwrap().1.trim();
|
||||||
} else if let Some(e) = line.trim().strip_prefix("Size") {
|
} else if let Some(e) = line.trim().strip_prefix("Size") {
|
||||||
size = e.split_once(":").unwrap().1.trim();
|
size = e.split_once(':').unwrap().1.trim();
|
||||||
} else if let Some(e) = line.trim().strip_prefix("License") {
|
} else if let Some(e) = line.trim().strip_prefix("License") {
|
||||||
license = e.split_once(":").unwrap().1.trim();
|
license = e.split_once(':').unwrap().1.trim();
|
||||||
}
|
}
|
||||||
if line.trim().starts_with("Description") {
|
if line.trim().starts_with("Description") {
|
||||||
break;
|
break;
|
||||||
|
@ -135,12 +135,12 @@ fn show_package(pkg: String) {
|
||||||
("", info)
|
("", info)
|
||||||
})
|
})
|
||||||
.1
|
.1
|
||||||
.split_once(":")
|
.split_once(':')
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.1
|
.1
|
||||||
.trim()
|
.trim()
|
||||||
.lines()
|
.lines()
|
||||||
.map(|x| x.split_once(":").unwrap_or(("", x)).1.trim().to_owned() + "\n")
|
.map(|x| x.split_once(':').unwrap_or(("", x)).1.trim().to_owned() + "\n")
|
||||||
.collect::<String>();
|
.collect::<String>();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -51,7 +51,7 @@ pub fn updates() -> gtk::Box {
|
||||||
List of names to skip when searching, this is to remove the
|
List of names to skip when searching, this is to remove the
|
||||||
labels "Available Packages", "Last refreshed at ..." and "Installed Packages"
|
labels "Available Packages", "Last refreshed at ..." and "Installed Packages"
|
||||||
*/
|
*/
|
||||||
let skip_list = vec!["available", "installed", "last"];
|
let skip_list = ["available", "installed", "last"];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Initialize the packages list, needs to be a static
|
Initialize the packages list, needs to be a static
|
||||||
|
@ -88,14 +88,14 @@ pub fn updates() -> gtk::Box {
|
||||||
.split_whitespace()
|
.split_whitespace()
|
||||||
.next()
|
.next()
|
||||||
.unwrap_or("")
|
.unwrap_or("")
|
||||||
.split(".")
|
.split('.')
|
||||||
.next()
|
.next()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
b.to_string()
|
b.to_string()
|
||||||
})
|
})
|
||||||
.filter(|x| {
|
.filter(|x| {
|
||||||
!x.trim().is_empty()
|
!x.trim().is_empty()
|
||||||
&& !x.contains("=")
|
&& !x.contains('=')
|
||||||
&& !skip_list.contains(&x.to_lowercase().trim())
|
&& !skip_list.contains(&x.to_lowercase().trim())
|
||||||
})
|
})
|
||||||
.dedup()
|
.dedup()
|
||||||
|
@ -107,7 +107,7 @@ pub fn updates() -> gtk::Box {
|
||||||
package and a button for it in the memory at the same time,
|
package and a button for it in the memory at the same time,
|
||||||
which has caused as much as 1.4GB of RAM usage during tests.
|
which has caused as much as 1.4GB of RAM usage during tests.
|
||||||
*/
|
*/
|
||||||
for pkg in FULL_PKG_LIST[0..(50.min(FULL_PKG_LIST.len()))].to_vec() {
|
for pkg in FULL_PKG_LIST[0..(50.min(FULL_PKG_LIST.len()))].iter() {
|
||||||
PKG_LIST_INDEX += 1;
|
PKG_LIST_INDEX += 1;
|
||||||
let pkg_btn = Button::builder()
|
let pkg_btn = Button::builder()
|
||||||
.label(pkg)
|
.label(pkg)
|
||||||
|
@ -143,19 +143,23 @@ pub fn updates() -> gtk::Box {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.connect_edge_reached(|_, edge| {
|
.connect_edge_reached(|_, edge| {
|
||||||
if edge == PositionType::Bottom {
|
if edge == PositionType::Bottom {
|
||||||
for i in PKG_LIST_INDEX..((PKG_LIST_INDEX + 50).min(FULL_PKG_LIST.len())) {
|
(PKG_LIST_INDEX..((PKG_LIST_INDEX + 50).min(FULL_PKG_LIST.len()))).for_each(
|
||||||
let pkg_btn = Button::builder()
|
|i| {
|
||||||
.label(FULL_PKG_LIST[i].as_str())
|
let pkg_btn = Button::builder()
|
||||||
.css_classes(["package-name"])
|
.label(FULL_PKG_LIST[i].as_str())
|
||||||
.build();
|
.css_classes(["package-name"])
|
||||||
|
.build();
|
||||||
|
|
||||||
pkg_btn.connect_clicked(|x| {
|
pkg_btn.connect_clicked(|x| {
|
||||||
show_package(x.label().map(|x| x.to_string()).unwrap_or("".to_owned()));
|
show_package(
|
||||||
});
|
x.label().map(|x| x.to_string()).unwrap_or("".to_owned()),
|
||||||
PACKAGES_LIST.as_ref().unwrap().append(&pkg_btn);
|
);
|
||||||
|
});
|
||||||
|
PACKAGES_LIST.as_ref().unwrap().append(&pkg_btn);
|
||||||
|
|
||||||
PKG_LIST_INDEX += 1;
|
PKG_LIST_INDEX += 1;
|
||||||
}
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
@ -204,7 +208,7 @@ unsafe fn search(f: &SearchEntry) {
|
||||||
x.to_lowercase()
|
x.to_lowercase()
|
||||||
.contains(f.text().to_string().to_lowercase().as_str())
|
.contains(f.text().to_string().to_lowercase().as_str())
|
||||||
})
|
})
|
||||||
.map(|x| x.clone())
|
.cloned()
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -235,7 +239,7 @@ unsafe fn search(f: &SearchEntry) {
|
||||||
either 50 or the length of the list, whichever
|
either 50 or the length of the list, whichever
|
||||||
is less, and make buttons in the list for each
|
is less, and make buttons in the list for each
|
||||||
*/
|
*/
|
||||||
for pkg in PKG_LIST[0..(50.min(PKG_LIST.len()))].to_vec() {
|
for pkg in PKG_LIST[0..(50.min(PKG_LIST.len()))].iter() {
|
||||||
PKG_LIST_INDEX += 1;
|
PKG_LIST_INDEX += 1;
|
||||||
let pkg_btn = Button::builder()
|
let pkg_btn = Button::builder()
|
||||||
.label(pkg)
|
.label(pkg)
|
||||||
|
|
Loading…
Reference in a new issue