progress, dont really know what to put in here...
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1 +1 @@
|
||||
32aac83d-ce2b-4def-977c-dcdcb6f514eg
|
||||
32aac83d-ce2b-4def-977c-dcdcb6f514ed
|
||||
@@ -19,7 +19,7 @@ export type TimeStamps = {
|
||||
mTime: Date;
|
||||
cTime: Date;
|
||||
aTime: Date;
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: Finish this
|
||||
// TODO: Change into a type instead of an enum for performance (low priority)
|
||||
@@ -103,13 +103,14 @@ export class Bash {
|
||||
if (command.root) {
|
||||
if (this.hasSudoPerms(this.user.uid)) {
|
||||
let out: Result = command.method.call(this, args);
|
||||
this.appendNewResult(this.getPwd(), out, this.user.history[0]);
|
||||
this.appendNewResult(this.getCwd(), out, this.user.history[0]);
|
||||
}
|
||||
this.throwError(result);
|
||||
}
|
||||
|
||||
let out: Result = command.method.call(this, args);
|
||||
this.appendNewResult(this.getPwd(), out.data?.data, this.user.history[0]);
|
||||
console.log(out);
|
||||
this.appendNewResult(this.getCwd(), out.data?.data, this.user.history[0]);
|
||||
}
|
||||
|
||||
throwError(result: Result): void {
|
||||
@@ -135,6 +136,7 @@ export class Bash {
|
||||
output: output,
|
||||
cmd: cmd
|
||||
};
|
||||
console.log(data);
|
||||
this._terminal.PrintOutput(data);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ export const cmd_cd = function (this: Bash, args: CommandArgs): Result {
|
||||
|
||||
this.getFs().pwd = this.getFs().cwd;
|
||||
targetNode = this.getFs().resolvePath(path); // Conversion from STRING path to TREENODE
|
||||
console.log(targetNode, path, 'CD OUTPUT');
|
||||
|
||||
if (targetNode === null) return result;
|
||||
if (targetNode.type !== Type.Directory) return result;
|
||||
@@ -34,7 +35,6 @@ export const cmd_cd = function (this: Bash, args: CommandArgs): Result {
|
||||
|
||||
this.getFs().cwd = targetNode.inode; // CD was successfull, change current dir to the verified target dir
|
||||
result.exitCode = ExitCode.SUCCESS;
|
||||
console.log(this.getCwd());
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
@@ -71,27 +71,26 @@ function result_ls(this: Bash, data: any, args: CommandArgs): HTMLElement {
|
||||
|
||||
const f_a: boolean = flagInfo.has('a') || flagInfo.has('f');
|
||||
const f_h: boolean = flagInfo.has('h');
|
||||
const f_U: boolean = flagInfo.has('U');
|
||||
const f_f: boolean = flagInfo.has('f');
|
||||
|
||||
if (flagInfo.has('l') || flagInfo.has('g') || flagInfo.has('o')) {
|
||||
const w: HTMLElement = document.createElement('div');
|
||||
|
||||
for (const node of nodes) {
|
||||
const elem: HTMLElement = document.createElement('div');
|
||||
let children: TreeNode[] = [];
|
||||
const children: TreeNode[] = node.children.map((child) => this.getFs().getNodeByINode(child));
|
||||
const rows: string[] = [];
|
||||
|
||||
if (!flagInfo.has('U') && !flagInfo.has('f')) {
|
||||
if (!f_U && !f_f) {
|
||||
//TODO: Add sort by option later on
|
||||
children: TreeNode[] = Sort.nodeArraySort.call(this, node.children, flagInfo.has('r'));
|
||||
console.log('had U or f');
|
||||
Sort.nodeArraySort.call(this, children, flagInfo.has('r'));
|
||||
}
|
||||
|
||||
const sizes = node.children.map((child) => (this.getFs().getNodeByINode(child).size));
|
||||
const sizes = children.map((child) => child.size);
|
||||
const maxSizeWidth = Math.max(...sizes.map((size) => size));
|
||||
|
||||
for (let i = 0; i < node.children.length; i++) {
|
||||
const child: TreeNode = children[i];
|
||||
|
||||
for (const child of children) {
|
||||
if (child.name.startsWith('.') && !(f_a || flagInfo.has('A'))) continue;
|
||||
|
||||
const cols: LsEntry = {
|
||||
@@ -118,18 +117,17 @@ function result_ls(this: Bash, data: any, args: CommandArgs): HTMLElement {
|
||||
let parent: LsEntry = {
|
||||
...current,
|
||||
name: '..'
|
||||
}
|
||||
if(node.parent) {
|
||||
};
|
||||
if (node.parent) {
|
||||
const parentNode: TreeNode = this.getFs().getNodeByINode(node.parent);
|
||||
parent = {
|
||||
perms: formatPermission(parentNode),
|
||||
children: formatChildren(parentNode),
|
||||
owners: formatOwners.call(this, parentNode, flagInfo),
|
||||
size: formatSize.call(this, f_h, parentNode, maxSizeWidth),
|
||||
modt: formatModtime(parentNode),
|
||||
name: '..'
|
||||
}
|
||||
|
||||
children: formatChildren(parentNode),
|
||||
owners: formatOwners.call(this, parentNode, flagInfo),
|
||||
size: formatSize.call(this, f_h, parentNode, maxSizeWidth),
|
||||
modt: formatModtime(parentNode),
|
||||
name: '..'
|
||||
};
|
||||
}
|
||||
|
||||
if (flagInfo.has('r')) {
|
||||
@@ -179,19 +177,16 @@ function formatOwners(this: Bash, node: TreeNode, flag: any): string {
|
||||
const group: string = this.getGroupByGid(node.group).groupname;
|
||||
|
||||
if (flag.has('G') || flag.has('o')) {
|
||||
if (flag.has('n'))
|
||||
return `${node.owner}`;
|
||||
if (flag.has('n')) return `${node.owner}`;
|
||||
return `${owner}`;
|
||||
}
|
||||
|
||||
if (flag.has('g')) {
|
||||
if (flag.has('n'))
|
||||
return `${node.group}`;
|
||||
if (flag.has('n')) return `${node.group}`;
|
||||
return `${group}`;
|
||||
}
|
||||
|
||||
if (flag.has('n'))
|
||||
return `${node.owner} ${node.group}`;
|
||||
if (flag.has('n')) return `${node.owner} ${node.group}`;
|
||||
|
||||
return `${owner} ${group}`;
|
||||
}
|
||||
@@ -201,6 +196,9 @@ function formatPermission(node: TreeNode): string {
|
||||
}
|
||||
|
||||
function formatChildren(node: TreeNode): string {
|
||||
if (node.type !== Type.Directory) return ' 0';
|
||||
if (!node.children) throw new Error('children array is null on this node');
|
||||
|
||||
const c = node.children.length.toString();
|
||||
return c.length > 1 ? c : ` ${c}`;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import type { readonly } from 'svelte/store';
|
||||
import type { Permission, TimeStamps, User } from './bash';
|
||||
import { Stack } from '../stack';
|
||||
|
||||
export enum Type {
|
||||
Directory = 16384,
|
||||
@@ -57,22 +55,16 @@ export class VirtualFS {
|
||||
}
|
||||
|
||||
private _iNodeToPathString(inode: number): string {
|
||||
let components: Stack<string> = new Stack<string>();
|
||||
let currentNode = this.FsTable.get(inode);
|
||||
let path: string = '';
|
||||
if (!currentNode) throw new Error('iNode does not exist,');
|
||||
|
||||
components.push(currentNode.name);
|
||||
const currentNode = this.FsTable.get(inode);
|
||||
if (!currentNode)
|
||||
throw new Error('could not find the node in the fs table - inodetopathstring');
|
||||
|
||||
if (!currentNode.parent) {
|
||||
for (let i = 0; i < components.size(); i++) {
|
||||
path += components.pop() + '/';
|
||||
}
|
||||
} else {
|
||||
this._iNodeToPathString(currentNode.parent);
|
||||
return '/';
|
||||
}
|
||||
|
||||
return path;
|
||||
const parentPath: string = this._iNodeToPathString(currentNode.parent);
|
||||
return parentPath === '/' ? `/${currentNode.name}` : `${parentPath}/${currentNode.name}`;
|
||||
}
|
||||
|
||||
//TODO: Make all backend methods NOT throw errors. Just return null, and let more closely connected with bash functions call throwError() so user can see the error.
|
||||
@@ -82,6 +74,8 @@ export class VirtualFS {
|
||||
const normalizedPath = path.replace(/^\/+|\/+$/g, '');
|
||||
const pathComponents = normalizedPath.split('/').filter((component) => component.length > 0);
|
||||
|
||||
console.log(path, 'pathstringtoinode');
|
||||
|
||||
if (pathComponents.length === 0) return this.rootINode;
|
||||
|
||||
let currentNode = this.FsTable.get(this.rootINode);
|
||||
@@ -96,6 +90,8 @@ export class VirtualFS {
|
||||
|
||||
currentNode = nextNode;
|
||||
}
|
||||
|
||||
console.log(path, currentNode.inode);
|
||||
return currentNode.inode;
|
||||
}
|
||||
|
||||
@@ -119,7 +115,9 @@ export class VirtualFS {
|
||||
}
|
||||
|
||||
formatPath(path: string): string {
|
||||
console.log(path, 'formatPath');
|
||||
const prefix = this._iNodeToPathString(this.home);
|
||||
|
||||
if (path.startsWith(prefix)) {
|
||||
return path.replace(prefix, '~');
|
||||
} else return path;
|
||||
@@ -127,18 +125,20 @@ export class VirtualFS {
|
||||
|
||||
resolvePath(path: string): TreeNode {
|
||||
if (path === '/') return this.getNodeByINode(this.rootINode);
|
||||
let parsedPath: string = path;
|
||||
|
||||
if (!this._isAbsolutePath(path)) {
|
||||
const trail: string = this._iNodeToPathString(this.cwd);
|
||||
path = trail + path;
|
||||
} else if (path.startsWith('~')) {
|
||||
parsedPath = `${trail}/${path}`;
|
||||
console.log(parsedPath);
|
||||
}
|
||||
if (path.startsWith('~')) {
|
||||
const trail: string = this._iNodeToPathString(this.home);
|
||||
path = trail + path;
|
||||
parsedPath = `${trail}/${path.replace('~', '')}`;
|
||||
console.log(parsedPath);
|
||||
}
|
||||
|
||||
console.log(path);
|
||||
|
||||
const INode: number = this._pathStringToINode(path);
|
||||
const INode: number = this._pathStringToINode(parsedPath);
|
||||
const Node: TreeNode = this.getNodeByINode(INode);
|
||||
|
||||
return Node;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { TreeNode } from "./fs";
|
||||
import type { Bash } from "./bash";
|
||||
import type { TreeNode } from './fs';
|
||||
import type { Bash } from './bash';
|
||||
|
||||
export enum SortBy {
|
||||
export enum SortNodeBy {
|
||||
NAME,
|
||||
INODE,
|
||||
SIZE,
|
||||
@@ -9,17 +9,21 @@ export enum SortBy {
|
||||
TYPE,
|
||||
MTIME = 'mTime',
|
||||
ATIME = 'aTime',
|
||||
CTIME = 'cTime',
|
||||
CTIME = 'cTime'
|
||||
}
|
||||
|
||||
export class Sort {
|
||||
|
||||
public static nodeArraySort(this: Bash, nodes: TreeNode[] | number[], reverse: boolean = false, sortBy: SortBy = SortBy.NAME): TreeNode[] {
|
||||
if(nodes.length === 0) throw new Error('Tried to sort an empty node array!');
|
||||
public static nodeArraySort(
|
||||
this: Bash,
|
||||
nodes: TreeNode[] | number[],
|
||||
reverse: boolean = false,
|
||||
sortBy: SortNodeBy = SortNodeBy.NAME
|
||||
): TreeNode[] {
|
||||
if (nodes.length === 0) throw new Error('Tried to sort an empty node array!');
|
||||
const parsedNodes: TreeNode[] = [];
|
||||
|
||||
if(typeof nodes[0] === 'number') {
|
||||
for(const inode of nodes as number[]) {
|
||||
|
||||
if (typeof nodes[0] === 'number') {
|
||||
for (const inode of nodes as number[]) {
|
||||
const node = this.getFs().getNodeByINode(inode);
|
||||
parsedNodes.push(node);
|
||||
}
|
||||
@@ -33,26 +37,37 @@ export class Sort {
|
||||
}
|
||||
}
|
||||
|
||||
private static nodeQSort(array: TreeNode[], reverse: boolean, sortBy: SortBy, start: number, end: number) {
|
||||
if(end <= start) return;
|
||||
private static nodeQSort(
|
||||
array: TreeNode[],
|
||||
reverse: boolean,
|
||||
sortBy: SortNodeBy,
|
||||
start: number,
|
||||
end: number
|
||||
) {
|
||||
if (end <= start) return;
|
||||
|
||||
let pivot: number = this.nodePartition(array, reverse, sortBy, start, end);
|
||||
this.nodeQSort(array, reverse, sortBy, start, pivot - 1);
|
||||
this.nodeQSort(array, reverse, sortBy, pivot + 1, end);
|
||||
|
||||
}
|
||||
|
||||
private static nodePartition(part: TreeNode[], reverse: boolean, sortBy: SortBy, start: number, end: number): number {
|
||||
private static nodePartition(
|
||||
part: TreeNode[],
|
||||
reverse: boolean,
|
||||
sortBy: SortNodeBy,
|
||||
start: number,
|
||||
end: number
|
||||
): number {
|
||||
let pivot: TreeNode = part[end];
|
||||
let i: number = start - 1;
|
||||
|
||||
|
||||
for (let j = start; j <= end; j++) {
|
||||
if(this.nodeCompareElements(part[j], pivot, sortBy, reverse) < 0) {
|
||||
if (this.nodeCompareElements(part[j], pivot, sortBy, reverse) < 0) {
|
||||
i++;
|
||||
let temp = part[i];
|
||||
part[i] = part[j];
|
||||
part[j] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
i++;
|
||||
let temp = part[i];
|
||||
@@ -62,12 +77,17 @@ export class Sort {
|
||||
return i;
|
||||
}
|
||||
|
||||
private static nodeCompareElements(a: TreeNode, b: TreeNode, sortBy: SortBy, reverse: boolean): number {
|
||||
switch(sortBy) {
|
||||
case SortBy.NAME: {
|
||||
private static nodeCompareElements(
|
||||
a: TreeNode,
|
||||
b: TreeNode,
|
||||
sortBy: SortNodeBy,
|
||||
reverse: boolean
|
||||
): number {
|
||||
switch (sortBy) {
|
||||
case SortNodeBy.NAME: {
|
||||
const minLength = Math.min(a.name.length, b.name.length);
|
||||
|
||||
for(let i = 0; i < minLength; i++) {
|
||||
for (let i = 0; i < minLength; i++) {
|
||||
const charCodeA = a.name.charCodeAt(i);
|
||||
const charCodeB = b.name.charCodeAt(i);
|
||||
|
||||
@@ -77,25 +97,25 @@ export class Sort {
|
||||
}
|
||||
return reverse ? b.name.length - a.name.length : a.name.length - b.name.length;
|
||||
}
|
||||
case SortBy.MTIME:
|
||||
case SortBy.ATIME:
|
||||
case SortBy.CTIME: {
|
||||
// The sortBy serves as the lookup key in the timestamps object.
|
||||
case SortNodeBy.MTIME:
|
||||
case SortNodeBy.ATIME:
|
||||
case SortNodeBy.CTIME: {
|
||||
// The sortBy serves as the lookup key in the timestamps object.
|
||||
// It works because the times in SortBy enum have assigned values matching the names of the keys in the TreeNode object
|
||||
const timeA: number = a.timestamps[sortBy].getTime();
|
||||
const timeB: number = b.timestamps[sortBy].getTime();
|
||||
|
||||
return reverse ? timeA - timeB : timeB - timeA;
|
||||
}
|
||||
case SortBy.SIZE: {
|
||||
case SortNodeBy.SIZE: {
|
||||
return reverse ? a.size - b.size : b.size - a.size;
|
||||
}
|
||||
case SortBy.EXTENSION: {
|
||||
case SortNodeBy.EXTENSION: {
|
||||
const extA: string = a.name.split('.').pop() ?? '';
|
||||
const extB: string = b.name.split('.').pop() ?? '';
|
||||
const minLength = Math.min(extA.length, extB.length);
|
||||
|
||||
for(let i = 0; i < minLength; i++) {
|
||||
for (let i = 0; i < minLength; i++) {
|
||||
const charCodeA = extA.charCodeAt(i);
|
||||
const charCodeB = extB.charCodeAt(i);
|
||||
|
||||
@@ -105,14 +125,14 @@ export class Sort {
|
||||
}
|
||||
return reverse ? extB.length - extA.length : extA.length - extB.length;
|
||||
}
|
||||
case SortBy.INODE: {
|
||||
case SortNodeBy.INODE: {
|
||||
return reverse ? b.inode - a.inode : a.inode - b.inode;
|
||||
}
|
||||
case SortBy.TYPE: {
|
||||
case SortNodeBy.TYPE: {
|
||||
return reverse ? b.type - a.type : a.type - b.type;
|
||||
}
|
||||
default:
|
||||
throw new Error(`Sorting basis outside of the declared scope. - `);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,10 +9,10 @@ export function isInitializing(): boolean {
|
||||
}
|
||||
|
||||
function jsonToNodeTable(data: any, parent?: number): Map<number, TreeNode> {
|
||||
const FsTable: Map<number, TreeNode> = new Map<number, TreeNode>;
|
||||
const FsTable: Map<number, TreeNode> = new Map<number, TreeNode>();
|
||||
const entryList = Object.entries(data);
|
||||
|
||||
for(let i = 0; i < entryList.length; i++) {
|
||||
for (let i = 0; i < entryList.length; i++) {
|
||||
const object: any = entryList[i][1];
|
||||
const node: TreeNode = {
|
||||
inode: object.Inode,
|
||||
@@ -48,7 +48,7 @@ function jsonToNodeTable(data: any, parent?: number): Map<number, TreeNode> {
|
||||
cTime: new Date(object.TimeStamps.CTime),
|
||||
aTime: new Date(object.TimeStamps.ATime)
|
||||
},
|
||||
parent: object.parent
|
||||
parent: object.Parent
|
||||
};
|
||||
|
||||
FsTable.set(object.Inode, node);
|
||||
|
||||
@@ -85,7 +85,7 @@ export class Terminal {
|
||||
executeCommand(input: string): void {
|
||||
this.bash.updateHistory(input);
|
||||
const parsed: ParsedInput = this._parseInput(input);
|
||||
console.log(parsed);
|
||||
console.log(parsed, 'executeCommand output');
|
||||
this.bash.executeCommand(parsed.command, parsed.args);
|
||||
}
|
||||
|
||||
@@ -99,6 +99,7 @@ export class Terminal {
|
||||
|
||||
getCwd(): string {
|
||||
const fs: VirtualFS = this.bash.getFs();
|
||||
console.log(fs.getPathByInode(this.bash.getCwd()));
|
||||
return fs.formatPath(fs.getPathByInode(this.bash.getCwd()));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user