Allow 'edit anyway' option for non-text files

fixes #50
This commit is contained in:
joshuaboud 2022-10-26 17:37:56 -03:00
parent d70d66f650
commit f91fd9aea0
No known key found for this signature in database
GPG Key ID: 17EFB59E2A8BF50E

View File

@ -41,18 +41,18 @@ export class NavFile extends NavEntry {
* @param {Event} e * @param {Event} e
*/ */
handleEvent(e) { handleEvent(e) {
switch(e.type){ switch (e.type) {
case "click": case "click":
if (this.double_click) { if (this.double_click) {
if(this.timeout) if (this.timeout)
clearTimeout(this.timeout); clearTimeout(this.timeout);
this.double_click = false; this.double_click = false;
this.open(); this.open();
return; return;
} else { // single click } else { // single click
this.double_click = true; this.double_click = true;
if(this.timeout) if (this.timeout)
clearTimeout(this.timeout) clearTimeout(this.timeout);
this.timeout = setTimeout(() => { this.timeout = setTimeout(() => {
this.double_click = false; this.double_click = false;
}, 500); }, 500);
@ -77,7 +77,7 @@ export class NavFile extends NavEntry {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
var proc = cockpit.spawn( var proc = cockpit.spawn(
["rm", "-f", this.path_str()], ["rm", "-f", this.path_str()],
{superuser: "try", err: "out"} { superuser: "try", err: "out" }
); );
proc.done((data) => { proc.done((data) => {
resolve(); resolve();
@ -89,18 +89,19 @@ export class NavFile extends NavEntry {
} }
async open() { async open() {
var proc_output = await cockpit.spawn(["file", "--mime-type", this.path_str()], {superuser: "try"}); async function isEditable(path, fileSize) {
var fields = proc_output.split(/:(?=[^:]+$)/); // ensure it's the last : with lookahead if (fileSize === 0)
var type = fields[1].trim(); return true; // empty file always editable
const encoding = (await cockpit.spawn(["file", "-bL", "--mime-encoding", path], { superuser: "try" })).trim();
if (/^text/.test(type) || /^inode\/x-empty$/.test(type) || this.stat["size"] === 0 || (/^application\/octet-stream/.test(type) && this.stat["size"] === 1)) { if (['us-ascii', 'utf-8'].includes(encoding))
this.show_edit_file_contents(); return true;
} else { if (fileSize === 1 && ['\n', '\t', ' '].includes(await cockpit.file(path).read()))
console.log("Unknown mimetype: " + type); return true; // special case for empty file with newline, shows as `application/octet-stream; charset=binary`
if (await this.nav_window_ref.modal_prompt.confirm("Can't open " + this.filename + " for editing.", "Download it instead?")) { return false;
var download = new NavDownloader(this);
download.download();
} }
if (await isEditable(this.path_str(), this.stat['size']) || await this.nav_window_ref.modal_prompt.confirm(`'${this.filename}' is not a text file. Open it anyway?`, "WARNING: this may lead to file corruption.", true)) {
this.show_edit_file_contents();
} }
} }
@ -109,7 +110,7 @@ export class NavFile extends NavEntry {
this.nav_window_ref.disable_buttons_for_editing(); this.nav_window_ref.disable_buttons_for_editing();
var contents = ""; var contents = "";
try { try {
contents = await cockpit.file(this.path_str(), {superuser: "try"}).read(); contents = await cockpit.file(this.path_str(), { superuser: "try" }).read();
} catch (e) { } catch (e) {
this.nav_window_ref.enable_buttons(); this.nav_window_ref.enable_buttons();
this.nav_window_ref.modal_prompt.alert(e.message); this.nav_window_ref.modal_prompt.alert(e.message);
@ -145,7 +146,7 @@ export class NavFile extends NavEntry {
} }
} }
export class NavFileLink extends NavFile{ export class NavFileLink extends NavFile {
/** /**
* *
* @param {string} path * @param {string} path
@ -187,7 +188,7 @@ export class NavFileLink extends NavFile{
async open() { async open() {
var target_path = this.get_link_target_path(); var target_path = this.get_link_target_path();
var proc_output = await cockpit.spawn(["file", "--mime-type", target_path], {superuser: "try"}); var proc_output = await cockpit.spawn(["file", "--mime-type", target_path], { superuser: "try" });
var fields = proc_output.split(/:(?=[^:]+$)/); // ensure it's the last : with lookahead var fields = proc_output.split(/:(?=[^:]+$)/); // ensure it's the last : with lookahead
var type = fields[1].trim(); var type = fields[1].trim();
@ -206,8 +207,8 @@ export class NavFileLink extends NavFile{
var target_path = this.get_link_target_path(); var target_path = this.get_link_target_path();
var contents = ""; var contents = "";
try { try {
contents = await cockpit.file(target_path, {superuser: "try"}).read(); contents = await cockpit.file(target_path, { superuser: "try" }).read();
} catch(e) { } catch (e) {
this.nav_window_ref.enable_buttons(); this.nav_window_ref.enable_buttons();
this.nav_window_ref.modal_prompt.alert(e.message); this.nav_window_ref.modal_prompt.alert(e.message);
return; return;