Added repo tree to default virtual drive data
This commit is contained in:
parent
059c2e6835
commit
00b82c6548
7 changed files with 123 additions and 104 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -24,4 +24,5 @@ yarn-debug.log*
|
|||
yarn-error.log*
|
||||
*.ini
|
||||
|
||||
/tmp
|
||||
/tmp
|
||||
/public/config/tree.json
|
||||
|
|
@ -15,7 +15,7 @@ echo -e "Commit message: \e[0;36m$COMMIT_MESSAGE\e[0m"
|
|||
echo -e "Repository: \e[0;36m$REPO_URL\e[0m"
|
||||
echo ""
|
||||
|
||||
if gh-pages -x -d dist -m $COMMIT_MESSAGE -r $REPO_URL ; then
|
||||
if gh-pages -x -d dist -m "$COMMIT_MESSAGE" -r "$REPO_URL" ; then
|
||||
echo -e "\e[0;32m✓ Successfully deployed to \e[0;36mhttps://$domain/\e[0m"
|
||||
else
|
||||
echo -e "\e[0;31mFailed to deploy\e[0m"
|
||||
|
|
|
|||
|
|
@ -49,6 +49,12 @@ These are the scripts in logical order, that will be available when you have ins
|
|||
> [!NOTE]
|
||||
> After this deployment process, GitHub Pages will run its own build step to finalize the deployment, as seen in the `Actions` tab on GitHub. This usually takes less than a minute and once it's done, your deployment will be live.
|
||||
|
||||
### Other scripts
|
||||
|
||||
- `npm run fetch`
|
||||
|
||||
Fetch the repository tree using GitHub's API and store it as a JSON file that will be used to populate the virtual drive. More information can be found on the [virtual drive](./features/virtual-drive/README.md) page.
|
||||
|
||||
### Configuration
|
||||
|
||||
See [docs/configuration](configuration/README.md) for more information.
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ export function Example() {
|
|||
|
||||
The virtual root is a virtual folder that contains all other folders and files. It serves as the root directory for the virtual drive and is used as an access point in applications.
|
||||
|
||||
The default data for the virtual root is set in the `loadDefaultData()` function in the `VirtualRoot` class.
|
||||
The default data for the virtual root is set in the `loadDefaultData()` function in the `VirtualRoot` class. It uses the contents of the GitHub repository to populate the root folder, allowing the user to browse the source code of ProzillaOS using its file explorer. To create or update the fetched repository tree data, so it can be used by ProzillaOS, run `npm run fetch`. This will fetch and cache the paths of every file and folder inside the repository. You should only run this command whenever a file/folder has been added/removed from the repo, because there is a [rate limit of 60 requests per hour](https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api).
|
||||
|
||||
For more information about how the virtual root is stored and loaded, check the [Storage](../storage/README.md) docs.
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@
|
|||
"serve": "vite preview --port 8080 --host",
|
||||
"predeploy": "npm run build && npm run stage",
|
||||
"stage": "node --no-warnings --loader ts-node/esm ./src/tools/stage",
|
||||
"deploy": "sh deploy.sh"
|
||||
"deploy": "sh deploy.sh",
|
||||
"fetch": "node --no-warnings --loader ts-node/esm ./src/tools/fetchRepository"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "^6.4.0",
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { APPS } from "../../../config/apps.config";
|
||||
import { WALLPAPERS } from "../../../config/desktop.config";
|
||||
import AppsManager from "../../apps/appsManager";
|
||||
import { VirtualFileLink } from "../file";
|
||||
import { VirtualFolderLink } from "../folder";
|
||||
import { VirtualFile, VirtualFileLink } from "../file";
|
||||
import { VirtualFolder, VirtualFolderLink } from "../folder";
|
||||
import { VirtualRoot } from "./virtualRoot";
|
||||
|
||||
/**
|
||||
|
|
@ -22,7 +22,7 @@ export function loadDefaultData(virtualRoot: VirtualRoot) {
|
|||
}).createFile("apps", "xml", (file) => {
|
||||
file.setSource("/config/apps.xml");
|
||||
}).createFile("theme", "xml", (file) => {
|
||||
file.setSource("/config/apps.xml");
|
||||
file.setSource("/config/theme.xml");
|
||||
});
|
||||
})
|
||||
.createFolder("Pictures", (folder) => {
|
||||
|
|
@ -79,107 +79,53 @@ export function loadDefaultData(virtualRoot: VirtualRoot) {
|
|||
});
|
||||
});
|
||||
|
||||
virtualRoot.createFolder(".github", (folder) => {
|
||||
folder.createFile("FUNDING", "yml", (file) => {
|
||||
file.setSource("https://raw.githubusercontent.com/Prozilla/ProzillaOS/main/.github/FUNDING.yml");
|
||||
});
|
||||
});
|
||||
// Create files and folders based on repository tree
|
||||
void fetch("/config/tree.json").then((response) =>
|
||||
response.json()
|
||||
).then(({ files, folders }: { files: string[], folders: string[] }) => {
|
||||
|
||||
virtualRoot.createFolder(".vscode", (folder) => {
|
||||
folder.createFile("settings", "json", (file) => {
|
||||
file.setSource("https://raw.githubusercontent.com/Prozilla/ProzillaOS/main/.vscode/settings.json");
|
||||
});
|
||||
});
|
||||
folders.forEach((folderPath) => {
|
||||
const lastSlashIndex = folderPath.lastIndexOf("/");
|
||||
|
||||
virtualRoot.createFolder("docs", (folder) => {
|
||||
folder.createFile("README", "md", (file) => {
|
||||
file.setSource("https://raw.githubusercontent.com/Prozilla/ProzillaOS/main/docs/README.md");
|
||||
});
|
||||
});
|
||||
if (lastSlashIndex === -1) {
|
||||
virtualRoot.createFolder(folderPath);
|
||||
return;
|
||||
}
|
||||
|
||||
virtualRoot.createFolder("public", (folder) => {
|
||||
folder.createFolder("assets", (folder) => {
|
||||
folder.createFolder("apps", (folder) => {
|
||||
folder.createFolder("icons", (folder) => {
|
||||
AppsManager.APPS.forEach(({ id }) => {
|
||||
folder.createFile(id, "svg", (file) => {
|
||||
file.setSource(AppsManager.getAppIconUrl(id));
|
||||
});
|
||||
});
|
||||
});
|
||||
}).createFolder("fonts", (folder) => {
|
||||
folder.createFolders(["outfit", "roboto-mono"]);
|
||||
}).createFolder("screenshots", (folder) => {
|
||||
folder.createFile("screenshot", "png", (file) => {
|
||||
file.setSource("/assets/screenshots/screenshot-files-info-taskbar-desktop.png");
|
||||
});
|
||||
}).createFolder("wallpapers", (folder) => {
|
||||
folder.setProtected(true);
|
||||
for (let i = 0; i < WALLPAPERS.length; i++) {
|
||||
const source = WALLPAPERS[i];
|
||||
const name = source.split("/").pop().split(".")[0];
|
||||
folder.createFile(name, "png", (file) => {
|
||||
file.setSource(source);
|
||||
});
|
||||
const parentPath = folderPath.substring(0, lastSlashIndex);
|
||||
const folderName = folderPath.substring(lastSlashIndex + 1);
|
||||
|
||||
const parentFolder = virtualRoot.navigate(parentPath) as VirtualFolder;
|
||||
parentFolder.createFolder(folderName);
|
||||
});
|
||||
|
||||
files.forEach((filePath) => {
|
||||
const lastSlashIndex = filePath.lastIndexOf("/");
|
||||
|
||||
const callback = (virtualFile: VirtualFile) => {
|
||||
console.log(virtualFile.absolutePath);
|
||||
|
||||
const virtualPath = virtualFile.absolutePath;
|
||||
if (virtualPath.startsWith("/public/")) {
|
||||
virtualFile.setSource(virtualPath.replace(/^\/public\//, "/"));
|
||||
} else {
|
||||
virtualFile.setSource(`https://raw.githubusercontent.com/Prozilla/ProzillaOS/main${virtualPath}`);
|
||||
}
|
||||
}).createFile("banner", "png", (file) => {
|
||||
file.setSource("/assets/banner-logo-title.png");
|
||||
}).createFile("logo", "svg", (file) => {
|
||||
file.setSource("/icon.svg");
|
||||
});
|
||||
}).createFolder("config", (folder) => {
|
||||
folder.createFile("apps", "xml", (file) => {
|
||||
file.setSource("/config/apps.xml");
|
||||
}).createFile("desktop", "xml", (file) => {
|
||||
file.setSource("/config/desktop.xml");
|
||||
}).createFile("taskbar", "xml", (file) => {
|
||||
file.setSource("/config/taskbar.xml");
|
||||
}).createFile("theme", "xml", (file) => {
|
||||
file.setSource("/config/theme.xml");
|
||||
});
|
||||
}).createFolder("documents", (folder) => {
|
||||
folder.createFile("info", "md", (file) => {
|
||||
file.setSource("/documents/info.md");
|
||||
}).createFile("links", "md", (file) => {
|
||||
file.setSource("/documents/links.md");
|
||||
});
|
||||
}).createFile("favicon", "ico", (file) => {
|
||||
file.setSource("/favicon.ico");
|
||||
}).createFile("index", "html", (file) => {
|
||||
file.setSource("/index.html");
|
||||
}).createFile("robots", "txt", (file) => {
|
||||
file.setSource("/robots.txt");
|
||||
}).createFile("sitemap", "xml", (file) => {
|
||||
file.setSource("/sitemap.xml");
|
||||
};
|
||||
|
||||
if (lastSlashIndex === -1) {
|
||||
const { name, extension } = VirtualFile.convertId(filePath);
|
||||
virtualRoot.createFile(name, extension, callback);
|
||||
return;
|
||||
}
|
||||
|
||||
const parentPath = filePath.substring(0, lastSlashIndex);
|
||||
const { name, extension } = VirtualFile.convertId(filePath.substring(lastSlashIndex + 1));
|
||||
|
||||
const parentFolder = virtualRoot.navigate(parentPath) as VirtualFolder;
|
||||
parentFolder.createFile(name, extension, callback);
|
||||
});
|
||||
});
|
||||
|
||||
virtualRoot.createFolder("src", (folder) => {
|
||||
folder.createFolder("components")
|
||||
.createFolder("config")
|
||||
.createFolder("features")
|
||||
.createFolder("hooks")
|
||||
.createFolder("styles")
|
||||
.createFile("App", "tsx", (file) => {
|
||||
file.setSource("https://raw.githubusercontent.com/Prozilla/ProzillaOS/main/src/App.tsx");
|
||||
}).createFile("index", "tsx", (file) => {
|
||||
file.setSource("https://raw.githubusercontent.com/Prozilla/ProzillaOS/main/src/index");
|
||||
});
|
||||
});
|
||||
|
||||
virtualRoot.createFile("", "env", (file) => {
|
||||
file.setSource("https://raw.githubusercontent.com/Prozilla/ProzillaOS/main/.env");
|
||||
}).createFile("", "gitignore", (file) => {
|
||||
file.setSource("https://raw.githubusercontent.com/Prozilla/ProzillaOS/main/.gitignore");
|
||||
}).createFile("LICENSE", "md", (file) => {
|
||||
file.setSource("https://raw.githubusercontent.com/Prozilla/ProzillaOS/main/LICENSE.md");
|
||||
}).createFile("README", "md", (file) => {
|
||||
file.setSource("https://raw.githubusercontent.com/Prozilla/ProzillaOS/main/README.md");
|
||||
}).createFile("package", "json", (file) => {
|
||||
file.setSource("https://raw.githubusercontent.com/Prozilla/ProzillaOS/main/package.json");
|
||||
}).createFile("deploy", "sh", (file) => {
|
||||
file.setSource("https://raw.githubusercontent.com/Prozilla/ProzillaOS/main/deploy.sh");
|
||||
}).createFile("tsconfig", "json", (file) => {
|
||||
file.setSource("https://raw.githubusercontent.com/Prozilla/ProzillaOS/main/tsconfig.json");
|
||||
}).catch(() => {
|
||||
console.warn("Failed to fetch repository tree. Make sure the tree data is valid and up-to-date using 'npm run fetch'.");
|
||||
});
|
||||
}
|
||||
65
src/tools/fetchRepository.ts
Normal file
65
src/tools/fetchRepository.ts
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
import fs from "node:fs";
|
||||
import { ANSI } from "../config/apps/terminal.config";
|
||||
|
||||
const API_URL = "https://api.github.com/";
|
||||
const TREE_PATH = "public/config/tree.json";
|
||||
|
||||
// TO DO: split these two variables into their own file
|
||||
const OWNER = "Prozilla";
|
||||
const REPO = "ProzillaOS";
|
||||
|
||||
const BRANCH = "main";
|
||||
|
||||
interface ReponseType {
|
||||
sha: string;
|
||||
url: string;
|
||||
tree: {
|
||||
path: string;
|
||||
mode: string;
|
||||
type: string;
|
||||
sha: string;
|
||||
url: string;
|
||||
}[];
|
||||
truncated: boolean;
|
||||
}
|
||||
|
||||
function fetchRepositoryTree(callback: (tree: string) => void) {
|
||||
const treeUrl = `${API_URL}repos/${OWNER}/${REPO}/git/trees/${BRANCH}?recursive=true`;
|
||||
|
||||
console.log(`${ANSI.fg.yellow}Fetching: ${ANSI.fg.cyan + treeUrl + ANSI.reset}`);
|
||||
|
||||
void fetch(treeUrl).then((response) =>
|
||||
response.json()
|
||||
).then((response: ReponseType) => {
|
||||
const items = response.tree;
|
||||
|
||||
const files = [];
|
||||
const folders = [];
|
||||
|
||||
items.forEach(({ path, type }) => {
|
||||
if (type === "tree") {
|
||||
folders.push(path);
|
||||
} else {
|
||||
files.push(path);
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`Files found: ${ANSI.fg.cyan + files.length + ANSI.reset}`);
|
||||
console.log(`Folders found: ${ANSI.fg.cyan + folders.length + ANSI.reset}`);
|
||||
console.log(`Truncated: ${ANSI.fg.cyan + response.truncated.toString() + ANSI.reset}`);
|
||||
|
||||
const tree = JSON.stringify({ files, folders });
|
||||
callback(tree);
|
||||
}).catch((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
fetchRepositoryTree((tree) => {
|
||||
fs.writeFileSync(TREE_PATH, tree, { flag: "w+" });
|
||||
console.log(`\n${ANSI.fg.green}✓ Generated repository tree: ${ANSI.fg.cyan + TREE_PATH + ANSI.reset}`);
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
Loading…
Reference in a new issue