Skip to content

Commit

Permalink
Release v0.5.4
Browse files Browse the repository at this point in the history
  • Loading branch information
joshuaboud committed Jul 20, 2021
2 parents 6114161 + 2ece66d commit 79ba268
Show file tree
Hide file tree
Showing 22 changed files with 530 additions and 190 deletions.
8 changes: 5 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
## Cockpit Navigator 0.5.3-1
## Cockpit Navigator 0.5.4-1

* Implement inline filename editing.
* Add information popup button.
* Add fuzzy search.
* Optimize folder uploads.
* Fix bugs with selecting entries and renaming files.
* Stop user from deleting or renaming system-critical paths.
21 changes: 10 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,39 +23,38 @@ With no command line use needed, you can:
# Installation
## From Github Release
### Ubuntu
1. `$ wget https://github.com/45Drives/cockpit-navigator/releases/download/v0.5.3/cockpit-navigator_0.5.3-1focal_all.deb`
1. `# apt install ./cockpit-navigator_0.5.3-1focal_all.deb`
1. `$ wget https://github.com/45Drives/cockpit-navigator/releases/download/v0.5.4/cockpit-navigator_0.5.4-1focal_all.deb`
1. `# apt install ./cockpit-navigator_0.5.4-1focal_all.deb`
### EL7
1. `# yum install https://github.com/45Drives/cockpit-navigator/releases/download/v0.5.3/cockpit-navigator-0.5.3-1.el7.noarch.rpm`
1. `# yum install https://github.com/45Drives/cockpit-navigator/releases/download/v0.5.4/cockpit-navigator-0.5.4-1.el7.noarch.rpm`
### EL8
1. `# dnf install https://github.com/45Drives/cockpit-navigator/releases/download/v0.5.3/cockpit-navigator-0.5.3-1.el8.noarch.rpm`
1. `# dnf install https://github.com/45Drives/cockpit-navigator/releases/download/v0.5.4/cockpit-navigator-0.5.4-1.el8.noarch.rpm`
## From Source
1. Ensure dependencies are installed: `cockpit`, `python3`, `rsync`, `zip`.
1. `$ git clone https://github.com/45Drives/cockpit-navigator.git`
1. `$ cd cockpit-navigator`
1. `$ git checkout <version>` (v0.5.2 is latest)
1. `$ git checkout <version>` (v0.5.4 is latest)
1. `# make install`
## From 45Drives Repositories
### Ubuntu
1. Import GPG Key
```sh
wget -qO - http://repo.45drives.com/key.asc | sudo apt-key add -
wget -qO - https://repo.45drives.com/key/gpg.asc | gpg --dearmor -o /usr/share/keyrings/45drives-archive-keyring.gpg
```
2. Add 45drives.list
2. Add 45drives.sources
```sh
cd /etc/apt/sources.list.d
sudo wget http://repo.45drives.com/debian/45drives.list
curl -sSL https://repo.45drives.com/lists/45drives.sources -o /etc/apt/sources.list.d/45drives.sources
sudo apt update
```
3. Install Package
```sh
sudo apt install cockpit-navigator
```
### EL7/EL8
1. Add Repository
1. Add 45drives.repo
```sh
cd /etc/yum.repos.d
sudo wget http://repo.45drives.com/rhel/45drives.repo
curl -sSL https://repo.45drives.com/lists/45drives.repo -o /etc/yum.repos.d/45drives.repo
sudo yum clean all
```
2. Install Package
Expand Down
4 changes: 2 additions & 2 deletions manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "cockpit-navigator",
"title": "Cockpit Navigator",
"prerelease": false,
"version": "0.5.3",
"version": "0.5.4",
"buildVersion": "1",
"author": "Josh Boudreau <jboudreau@45drives.com>",
"url": "https://github.com/45Drives/cockpit-navigator",
Expand Down Expand Up @@ -54,7 +54,7 @@
],
"changelog": {
"urgency": "medium",
"version": "0.5.3",
"version": "0.5.4",
"buildVersion": "1",
"ignore": [],
"date": null,
Expand Down
49 changes: 29 additions & 20 deletions navigator/components/FileUpload.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,42 +41,39 @@ export class FileUpload {
this.reader = new FileReader();
this.chunks = this.slice_file(file);
this.chunk_index = 0;
this.timestamp = Date.now();
this.modal_prompt = new ModalPrompt();
this.using_webkit = true;
}

check_if_exists() {
return new Promise((resolve, reject) => {
var proc = cockpit.spawn(["/usr/share/cockpit/navigator/scripts/fail-if-exists.py3", this.path], {superuser: "try"});
proc.done((data) => {resolve(false)});
proc.fail((e, data) => {resolve(true)});
});
this.make_html_element();
}

make_html_element() {
var notification = document.createElement("div");
var notification = this.dom_element = document.createElement("div");
notification.classList.add("nav-notification");

var header = document.createElement("div");
header.classList.add("nav-notification-header");
notification.appendChild(header);
header.innerText = "Uploading " + this.filename;
header.style.position = "relative";
header.style.paddingRight = "1em";
header.style.display = "grid";
header.style.gridTemplateColumns = "1fr 20px";
header.style.gap = "5px";

var title = document.createElement("p");
title.innerText = "Uploading " + this.filename;
title.title = this.filename;

var cancel = document.createElement("i");
cancel.classList.add("fa", "fa-times");
cancel.style.position = "absolute"
cancel.style.right = "0";
cancel.style.justifySelf = "center";
cancel.style.alignSelf = "center";
cancel.style.cursor = "pointer";
cancel.onclick = () => {
if (this.proc) {
this.reader.onload = () => {};
this.done();
}
}
header.appendChild(cancel);

header.append(title, cancel);

var info = document.createElement("div");
info.classList.add("flex-row", "space-between");
Expand Down Expand Up @@ -129,16 +126,19 @@ export class FileUpload {
}

async upload() {
this.make_html_element();
this.timestamp = Date.now();
this.dom_element.style.display = "flex";
this.proc = cockpit.spawn(["/usr/share/cockpit/navigator/scripts/write-chunks.py3", this.path], {err: "out", superuser: "try"});
this.proc.fail((e, data) => {
this.reader.onload = () => {}
this.done();
this.nav_window_ref.modal_prompt.alert(e, data);
})
this.proc.done((data) => {
this.nav_window_ref.refresh();
if (!this.done_hook)
this.nav_window_ref.refresh();
})
this.proc.always(() => this?.done_hook?.());
this.reader.onerror = (evt) => {
this.modal_prompt.alert("Failed to read file: " + this.filename, "Upload of directories not supported.");
this.done();
Expand All @@ -164,6 +164,7 @@ export class FileUpload {
}
this.done();
}
this.update_rates_interval = setInterval(this.display_xfr_rate.bind(this), 1000);
}

/**
Expand Down Expand Up @@ -199,19 +200,27 @@ export class FileUpload {
done() {
this.proc.input(); // close stdin
this.remove_html_element();
clearInterval(this.update_rates_interval);
}

update_xfr_rate() {
var now = Date.now();
var elapsed = (now - this.timestamp) / 1000;
this.timestamp = now;
var rate = this.chunk_size / elapsed;
this.rate.innerText = cockpit.format_bytes_per_sec(rate);
this.rate_avg = (this.rate_avg)
? (0.125 * rate + (0.875 * this.rate_avg))
: rate;
// keep exponential moving average of chunk time for eta
this.chunk_time = (this.chunk_time)
? (0.125 * elapsed + (0.875 * this.chunk_time))
: elapsed;
var eta = (this.num_chunks - this.chunk_index) * this.chunk_time;
this.eta.innerText = format_time_remaining(eta);
this.eta_avg = eta;
}

display_xfr_rate() {
this.rate.innerText = cockpit.format_bytes_per_sec(this.rate_avg);
this.eta.innerText = format_time_remaining(this.eta_avg);
}
}
62 changes: 62 additions & 0 deletions navigator/components/FileUploadManager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
Cockpit Navigator - A File System Browser for Cockpit.
Copyright (C) 2021 Josh Boudreau <jboudreau@45drives.com>
Copyright (C) 2021 Sam Silver <ssilver@45drives.com>
Copyright (C) 2021 Dawson Della Valle <ddellavalle@45drives.com>
This file is part of Cockpit Navigator.
Cockpit Navigator is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cockpit Navigator is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cockpit Navigator. If not, see <https://www.gnu.org/licenses/>.
*/

import {FileUpload} from "./FileUpload.js";
import {NavWindow} from "./NavWindow.js";

export class FileUploadManager {
/**
*
* @param {NavWindow} nav_window_ref
* @param {number} max_concurrent
*/
constructor(nav_window_ref, max_concurrent = 10) {
this.nav_window_ref = nav_window_ref;
this.running = 0;
this.remaining_uploads = [];
this.max_concurrent = max_concurrent;
this.start_next = () => {
let next_upload = this.remaining_uploads.pop();
if (next_upload) {
next_upload?.upload?.();
this.running++;
}
}
}

/**
*
* @param {...FileUpload} uploads
*/
add(...uploads) {
let done_hook = () => {
this.running--;
this.start_next();
if (!this.running)
this.nav_window_ref.refresh();
}
for (let upload of uploads) {
upload.done_hook = done_hook;
this.remaining_uploads.unshift(upload);
}
while (this.remaining_uploads.length && this.running < this.max_concurrent) {
this.start_next();
}
}
}
11 changes: 9 additions & 2 deletions navigator/components/NavContextMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export class NavContextMenu {
new_link(e) {
var default_target = "";
if (this.nav_window_ref.selected_entries.size <= 1 && this.target !== this.nav_window_ref.pwd())
default_target = this.target.filename();
default_target = this.target.filename;
this.nav_window_ref.ln(default_target);
}

Expand All @@ -90,7 +90,14 @@ export class NavContextMenu {

async rename(e) {
this.hide();
this.target.show_edit(this.target.dom_element.nav_item_title);
if (this.target.is_dangerous_path()) {
await this.nav_window_ref.modal_prompt.alert(
"Cannot rename system-critical paths.",
"If you think you need to, use the terminal."
);
} else {
this.target.show_edit(this.target.dom_element.nav_item_title);
}
e.stopPropagation();
}

Expand Down
12 changes: 12 additions & 0 deletions navigator/components/NavDir.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,18 @@ export class NavDir extends NavEntry {
}
super.show_properties(extra_properties);
}

style_selected() {
this.dom_element.nav_item_icon.classList.remove("fa-folder");
this.dom_element.nav_item_icon.classList.add("fa-folder-open");
super.style_selected();
}

unstyle_selected() {
this.dom_element.nav_item_icon.classList.add("fa-folder");
this.dom_element.nav_item_icon.classList.remove("fa-folder-open");
super.unstyle_selected();
}
}

export class NavDirLink extends NavDir{
Expand Down
2 changes: 1 addition & 1 deletion navigator/components/NavDownloader.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export class NavDownloader {
*/
constructor(file) {
this.path = file.path_str();
this.filename = file.filename();
this.filename = file.filename;
this.read_size = file.stat["size"];
}

Expand Down
34 changes: 29 additions & 5 deletions navigator/components/NavDragDrop.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@
*/

import {FileUpload} from "./FileUpload.js";
import { ModalPrompt } from "./ModalPrompt.js";
import {ModalPrompt} from "./ModalPrompt.js";
import {NavWindow} from "./NavWindow.js";
import {FileUploadManager} from "./FileUploadManager.js";

export class NavDragDrop {
/**
Expand All @@ -35,6 +36,7 @@ export class NavDragDrop {
this.drop_area = drop_area;
this.nav_window_ref = nav_window_ref;
this.modal_prompt = new ModalPrompt();
this.upload_manager = new FileUploadManager(this.nav_window_ref, 6);
}

/**
Expand Down Expand Up @@ -82,7 +84,6 @@ export class NavDragDrop {
let path = "";
if (item) {
let new_uploads = await this.scan_files(item, path);
console.log(new_uploads);
uploads.push(... new_uploads);
} else {
reject();
Expand All @@ -98,10 +99,29 @@ export class NavDragDrop {
* @returns {FileUpload[]}
*/
async handle_conflicts(uploads) {
let test_paths = [];
for (let upload of uploads)
test_paths.push(upload.path);
let proc = cockpit.spawn(
["/usr/share/cockpit/navigator/scripts/return-exists.py3", ... test_paths],
{error: "out", superuser: "try"}
);
let exist_result;
proc.done((data) => {
exist_result = JSON.parse(data);
});
proc.fail((e, data) => {
this.nav_window_ref.modal_prompt.alert(e, data);
});
try {
await proc;
} catch {
return;
}
let keepers = [];
let requests = {};
for (let upload of uploads) {
if (!await upload.check_if_exists()) {
if (!exist_result[upload.path]) {
keepers.push(upload.filename);
continue;
}
Expand Down Expand Up @@ -147,6 +167,7 @@ export class NavDragDrop {
this.drop_area.classList.remove("drag-enter");
break;
case "drop":
this.nav_window_ref.start_load();
let uploads;
let items = e.dataTransfer.items;
e.preventDefault();
Expand All @@ -162,10 +183,13 @@ export class NavDragDrop {
}
}
this.drop_area.classList.remove("drag-enter");
if (uploads.length === 0)
if (uploads.length === 0) {
this.nav_window_ref.stop_load();
break;
}
uploads = await this.handle_conflicts(uploads);
uploads.forEach((upload) => {upload.upload()});
this.nav_window_ref.stop_load();
this.upload_manager.add(... uploads);
break;
default:
this.drop_area.classList.remove("drag-enter");
Expand Down
Loading

0 comments on commit 79ba268

Please sign in to comment.