mirror of
https://github.com/tdurieux/anonymous_github.git
synced 2026-02-12 18:32:44 +00:00
fix: improve error message for folders
This commit is contained in:
@@ -2,7 +2,7 @@ import { join, basename } from "path";
|
||||
import { Response } from "express";
|
||||
import { Readable } from "stream";
|
||||
import Repository from "./Repository";
|
||||
import { Tree, TreeElement, TreeFile } from "./types";
|
||||
import { FILE_TYPE, Tree, TreeElement, TreeFile } from "./types";
|
||||
import storage from "./storage";
|
||||
import config from "../config";
|
||||
import {
|
||||
@@ -175,8 +175,14 @@ export default class AnonymizedFile {
|
||||
httpStatus: 403,
|
||||
});
|
||||
}
|
||||
if (await storage.exists(this.originalCachePath)) {
|
||||
const exist = await storage.exists(this.originalCachePath);
|
||||
if (exist == FILE_TYPE.FILE) {
|
||||
return storage.read(this.originalCachePath);
|
||||
} else if (exist == FILE_TYPE.FOLDER) {
|
||||
throw new AnonymousError("folder_not_supported", {
|
||||
object: this,
|
||||
httpStatus: 400,
|
||||
});
|
||||
}
|
||||
return await this.repository.source?.getFileContent(this);
|
||||
}
|
||||
@@ -223,7 +229,7 @@ export default class AnonymizedFile {
|
||||
// unable to get file size
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
|
||||
const anonymizer = new AnonymizeTransformer(this);
|
||||
|
||||
anonymizer.once("transform", (data) => {
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
import { join } from "path";
|
||||
import storage from "./storage";
|
||||
import { RepositoryStatus, Source, Tree, TreeElement, TreeFile } from "./types";
|
||||
import {
|
||||
FILE_TYPE,
|
||||
RepositoryStatus,
|
||||
Source,
|
||||
Tree,
|
||||
TreeElement,
|
||||
TreeFile,
|
||||
} from "./types";
|
||||
import { Readable } from "stream";
|
||||
import User from "./User";
|
||||
import GitHubStream from "./source/GitHubStream";
|
||||
@@ -333,7 +340,9 @@ export default class Repository {
|
||||
async removeCache() {
|
||||
this.model.isReseted = true;
|
||||
await this.model.save();
|
||||
if (await storage.exists(this._model.repoId + "/")) {
|
||||
if (
|
||||
(await storage.exists(this._model.repoId + "/")) !== FILE_TYPE.NOT_FOUND
|
||||
) {
|
||||
return storage.rm(this._model.repoId + "/");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import storage from "../storage";
|
||||
import Repository from "../Repository";
|
||||
import GitHubBase from "./GitHubBase";
|
||||
import AnonymizedFile from "../AnonymizedFile";
|
||||
import { RepositoryStatus, SourceBase } from "../types";
|
||||
import { FILE_TYPE, RepositoryStatus, SourceBase } from "../types";
|
||||
import AnonymousError from "../AnonymousError";
|
||||
import { tryCatch } from "bullmq";
|
||||
|
||||
@@ -132,8 +132,14 @@ export default class GitHubDownload extends GitHubBase implements SourceBase {
|
||||
}
|
||||
|
||||
async getFileContent(file: AnonymizedFile): Promise<Readable> {
|
||||
if (await storage.exists(file.originalCachePath)) {
|
||||
const exists = await storage.exists(file.originalCachePath);
|
||||
if (exists === FILE_TYPE.FILE) {
|
||||
return storage.read(file.originalCachePath);
|
||||
} else if (exists === FILE_TYPE.FOLDER) {
|
||||
throw new AnonymousError("folder_not_supported", {
|
||||
httpStatus: 400,
|
||||
object: file,
|
||||
});
|
||||
}
|
||||
// will throw an error if the file is not in the repository
|
||||
await file.originalPath();
|
||||
@@ -145,7 +151,7 @@ export default class GitHubDownload extends GitHubBase implements SourceBase {
|
||||
|
||||
async getFiles() {
|
||||
const folder = this.repository.originalCachePath;
|
||||
if (!(await storage.exists(folder))) {
|
||||
if ((await storage.exists(folder)) === FILE_TYPE.NOT_FOUND) {
|
||||
await this.download();
|
||||
}
|
||||
return storage.listFiles(folder);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { SourceBase, StorageBase, Tree } from "../types";
|
||||
import { FILE_TYPE, SourceBase, StorageBase, Tree } from "../types";
|
||||
import config from "../../config";
|
||||
|
||||
import * as fs from "fs";
|
||||
@@ -17,8 +17,15 @@ export default class FileSystem implements StorageBase {
|
||||
constructor() {}
|
||||
|
||||
/** @override */
|
||||
async exists(p: string): Promise<boolean> {
|
||||
return fs.existsSync(join(config.FOLDER, p));
|
||||
async exists(p: string): Promise<FILE_TYPE> {
|
||||
try {
|
||||
const stat = await fs.promises.stat(join(config.FOLDER, p));
|
||||
if (stat.isDirectory()) return FILE_TYPE.FOLDER;
|
||||
if (stat.isFile()) return FILE_TYPE.FILE;
|
||||
} catch (_) {
|
||||
// ignore file not found or not downloaded
|
||||
}
|
||||
return FILE_TYPE.NOT_FOUND;
|
||||
}
|
||||
|
||||
/** @override */
|
||||
@@ -49,11 +56,7 @@ export default class FileSystem implements StorageBase {
|
||||
file?: AnonymizedFile,
|
||||
source?: SourceBase
|
||||
): Promise<void> {
|
||||
if (!(await this.exists(dirname(p)))) {
|
||||
await fs.promises.mkdir(dirname(join(config.FOLDER, p)), {
|
||||
recursive: true,
|
||||
});
|
||||
}
|
||||
await this.mk(dirname(p));
|
||||
return fs.promises.writeFile(join(config.FOLDER, p), data);
|
||||
}
|
||||
|
||||
@@ -67,7 +70,7 @@ export default class FileSystem implements StorageBase {
|
||||
|
||||
/** @override */
|
||||
async mk(dir: string): Promise<void> {
|
||||
if (!(await this.exists(dir)))
|
||||
if ((await this.exists(dir)) === FILE_TYPE.NOT_FOUND)
|
||||
fs.promises.mkdir(join(config.FOLDER, dir), { recursive: true });
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { SourceBase, StorageBase, Tree, TreeFile } from "../types";
|
||||
import { FILE_TYPE, SourceBase, StorageBase, Tree, TreeFile } from "../types";
|
||||
import {
|
||||
GetObjectCommand,
|
||||
ListObjectsV2CommandOutput,
|
||||
@@ -44,14 +44,12 @@ export default class S3Storage implements StorageBase {
|
||||
}
|
||||
|
||||
/** @override */
|
||||
async exists(path: string): Promise<boolean> {
|
||||
async exists(path: string): Promise<FILE_TYPE> {
|
||||
if (!config.S3_BUCKET) throw new Error("S3_BUCKET not set");
|
||||
try {
|
||||
await this.client().headObject({
|
||||
Bucket: config.S3_BUCKET,
|
||||
Key: path,
|
||||
});
|
||||
return true;
|
||||
// if we can get the file info, it is a file
|
||||
await this.fileInfo(path);
|
||||
return FILE_TYPE.FILE;
|
||||
} catch (err) {
|
||||
// check if it is a directory
|
||||
const data = await this.client().listObjectsV2({
|
||||
@@ -59,7 +57,9 @@ export default class S3Storage implements StorageBase {
|
||||
Prefix: path,
|
||||
MaxKeys: 1,
|
||||
});
|
||||
return (data.Contents?.length || 0) > 0;
|
||||
return (data.Contents?.length || 0) > 0
|
||||
? FILE_TYPE.FOLDER
|
||||
: FILE_TYPE.NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,12 @@ export interface SourceBase {
|
||||
|
||||
export type Source = GitHubDownload | GitHubStream | Zip;
|
||||
|
||||
export enum FILE_TYPE {
|
||||
FILE = "file",
|
||||
FOLDER = "folder",
|
||||
NOT_FOUND = "not_found",
|
||||
}
|
||||
|
||||
export interface StorageBase {
|
||||
/**
|
||||
* The type of storage
|
||||
@@ -42,7 +48,7 @@ export interface StorageBase {
|
||||
* check if the path exists
|
||||
* @param path the path to check
|
||||
*/
|
||||
exists(path: string): Promise<boolean>;
|
||||
exists(path: string): Promise<FILE_TYPE>;
|
||||
|
||||
send(p: string, res: Response): Promise<void>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user