mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
core: file rename api
This commit is contained in:
1 parent
46d7f4518e
commit
e5bfb78f94
9 files changed
+134
-8
No files matched your search
@@ -4,13 +4,13 @@ import { Dictionary, escapeRegExp, pick } from 'lodash';
|
||||
import { streamToBuffer } from '@hydrooj/utils/lib/utils';
|
||||
import * as document from './document';
|
||||
import { STATUS } from './builtin';
|
||||
import storage from './storage';
|
||||
import { buildProjection } from '../utils';
|
||||
import type { ProblemStatusDoc, ProblemDict, Document } from '../interface';
|
||||
import {
|
||||
ArrayKeys, MaybeArray, NumberKeys, Projection,
|
||||
} from '../typeutils';
|
||||
import { ProblemNotFoundError, ValidationError } from '../error';
|
||||
import storage from '../service/storage';
|
||||
import * as bus from '../service/bus';
|
||||
|
||||
export interface ProblemDoc extends Document { }
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
import type { Readable } from 'stream';
|
||||
import { escapeRegExp } from 'lodash';
|
||||
import { ItemBucketMetadata } from 'minio';
|
||||
import moment from 'moment';
|
||||
import storage from '../service/storage';
|
||||
import * as bus from '../service/bus';
|
||||
import db from '../service/db';
|
||||
|
||||
export class StorageModel {
|
||||
static coll = db.collection('storage');
|
||||
|
||||
static async put(path: string, file: string | Buffer | Readable, meta: ItemBucketMetadata = {}) {
|
||||
const [current, place] = await Promise.all([
|
||||
StorageModel.coll.findOne({ path }),
|
||||
StorageModel.coll.findOne({ _id: path }),
|
||||
]);
|
||||
if (current) {
|
||||
await storage.put(current._id, file, meta);
|
||||
const { metaData, size, etag } = await storage.getMeta(current._id);
|
||||
await StorageModel.coll.updateOne({ path }, {
|
||||
$set: {
|
||||
meta: metaData, size, etag, lastModified: new Date(),
|
||||
},
|
||||
});
|
||||
return path;
|
||||
}
|
||||
const target = place ? path + Math.random().toString(16) : path;
|
||||
await storage.put(target, file, meta);
|
||||
const { metaData, size, etag } = await storage.getMeta(target);
|
||||
await StorageModel.coll.insertOne({
|
||||
_id: target, meta: metaData, path, size, etag, lastModified: new Date(),
|
||||
});
|
||||
return path;
|
||||
}
|
||||
|
||||
static async get(path: string, savePath?: string) {
|
||||
const { value } = await StorageModel.coll.findOneAndUpdate({ path }, { $set: { lastUsage: new Date() } }, { returnOriginal: false });
|
||||
if (value) return await storage.get(value._id, savePath);
|
||||
return await storage.get(path, savePath);
|
||||
}
|
||||
|
||||
static async rename(path: string, newPath: string) {
|
||||
return await StorageModel.coll.updateOne({ path }, { $set: { path: newPath } });
|
||||
}
|
||||
|
||||
static async del(path: string[]) {
|
||||
const autoDelete = moment().add(7, 'day').toDate();
|
||||
await StorageModel.coll.updateMany({ path: { $in: path } }, { $set: { autoDelete } });
|
||||
}
|
||||
|
||||
static async list(target: string, recursive = true) {
|
||||
if (target.includes('..') || target.includes('//')) throw new Error('Invalid path');
|
||||
if (target?.length && !target.endsWith('/')) target += '/';
|
||||
const results = recursive
|
||||
? await StorageModel.coll.find({ path: { $regex: new RegExp(`^${escapeRegExp(target)}`, 'i') } }).toArray()
|
||||
: await StorageModel.coll.find({ path: { $regex: new RegExp(`^${escapeRegExp(target)}[^/]+$`) } }).toArray();
|
||||
return results.map((i) => ({
|
||||
...i, name: i.path, prefix: i.path.split(target)[1],
|
||||
}));
|
||||
}
|
||||
|
||||
static async getMeta(path: string) {
|
||||
const { value } = await StorageModel.coll.findOneAndUpdate({ path }, { $set: { lastUsage: new Date() } }, { returnOriginal: false });
|
||||
if (!value) return null;
|
||||
return {
|
||||
...value.meta,
|
||||
size: value.size,
|
||||
lastModified: value.lastModified,
|
||||
etag: value.etag,
|
||||
};
|
||||
}
|
||||
|
||||
static async signDownloadLink(target: string, filename?: string, noExpire = false, useAlternativeEndpointFor?: 'user' | 'judge') {
|
||||
await StorageModel.coll.updateOne({ path: target }, { $set: { lastUsage: new Date() } });
|
||||
return await storage.signDownloadLink(target, filename, noExpire, useAlternativeEndpointFor);
|
||||
}
|
||||
}
|
||||
|
||||
bus.on('app/started', () => StorageModel.coll.createIndex({ path: 1 }, { unique: true }));
|
||||
|
||||
global.Hydro.model.storage = StorageModel;
|
||||
export default StorageModel;
|
||||
Reference in new issue
Block a user