Remove .env

This commit is contained in:
mbaharip
2023-04-21 21:07:19 +07:00
commit b6fc85151a
72 changed files with 9502 additions and 0 deletions
+33
View File
@@ -0,0 +1,33 @@
import apiConfig from "@config/api.config";
import { google, drive_v3 } from "googleapis";
class DriveClient {
private instance: drive_v3.Drive;
constructor() {
const oauth2Client = new google.auth.OAuth2(
apiConfig.client_id,
process.env.CLIENT_SECRET,
apiConfig.redirect_uri,
);
oauth2Client.setCredentials({ refresh_token: process.env.REFRESH_TOKEN });
this.instance = google.drive({ version: "v3", auth: oauth2Client });
}
getInstance() {
if (!this.instance) {
const oauth2Client = new google.auth.OAuth2(
apiConfig.client_id,
process.env.CLIENT_SECRET,
apiConfig.redirect_uri,
);
oauth2Client.setCredentials({ refresh_token: process.env.REFRESH_TOKEN });
this.instance = google.drive({ version: "v3", auth: oauth2Client });
}
return this.instance;
}
}
const drive = new DriveClient();
export default drive.getInstance();
+70
View File
@@ -0,0 +1,70 @@
import drive from "@utils/driveClient";
import config from "@config/site.config";
export function buildQuery({
id,
extraQuery,
globalSearch = false,
}: {
id?: string;
extraQuery?: string[];
globalSearch?: boolean;
}) {
const query = [
"name != '.password'",
"'me' in owners",
"trashed = false",
// "mimeType != 'application/vnd.google-apps.shortcut'",
];
if (id && !globalSearch) {
query.unshift(`'${id}' in parents`);
}
if (!id && !globalSearch) {
query.unshift(`'${config.files.rootFolder}' in parents`);
}
if (extraQuery) {
query.unshift(...extraQuery);
}
return query.join(" and ");
}
export async function checkProtected(id: string) {
try {
const files = await drive.files.list({
q: id ? buildQuery({ id }) : buildQuery({}),
fields: "files(id)",
});
return {
protected: files.data.files?.length,
id: files.data.files?.[0].id || null,
};
} catch (error: any) {
return {
protected: false,
id: null,
};
}
}
export async function validateFolderPassword(
passwordFileId: string,
password: string,
) {
try {
const folderPassword = await drive.files.get(
{
fileId: passwordFileId,
alt: "media",
},
{ responseType: "text" },
);
return folderPassword.data === password;
} catch (error: any) {
return false;
}
}
+12
View File
@@ -0,0 +1,12 @@
import crypto from "crypto";
export function generateRandomEncryptionKey(): Promise<string> {
return new Promise((resolve, reject) => {
crypto.randomBytes(32, (err, buffer) => {
if (err) {
reject(err);
}
resolve(buffer.toString("hex"));
});
});
}
+78
View File
@@ -0,0 +1,78 @@
// Get locale from browser
export function getLocale() {
if (typeof window === "undefined") return "en-US";
if (window.navigator.languages) return window.navigator.languages[0];
return window.navigator.language;
}
export function formatDuration(milliseconds: string | number) {
let ms: number = milliseconds as number;
if (typeof milliseconds === "string") {
ms = parseInt(milliseconds);
}
const totalSeconds = Math.floor(ms / 1000);
const hours = Math.floor(totalSeconds / 3600);
const minutes = Math.floor((totalSeconds % 3600) / 60);
const seconds = totalSeconds % 60;
const hourString = hours > 0 ? `${hours}:` : "";
const minuteString =
minutes > 0 ? `${String(minutes).padStart(2, "0")}:` : "00:";
const secondString = seconds > 0 ? String(seconds).padStart(2, "0") : "00";
return `${hourString}${minuteString}${secondString}`;
}
export function formatBytes(bytes: number | string) {
let b: number = typeof bytes === "string" ? parseInt(bytes) : bytes;
if (b === 0) return "0 Bytes";
const k = 1024;
const dm = 2;
const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
const i = Math.floor(Math.log(b) / Math.log(k));
return parseFloat((b / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
}
export function formatDate(date: Date, locale = getLocale()) {
return new Intl.DateTimeFormat(locale, {
year: "numeric",
month: "long",
day: "numeric",
hour: "numeric",
minute: "numeric",
hour12: false,
}).format(date);
}
type RelativeTimeFormatUnit =
| "year"
| "quarter"
| "month"
| "week"
| "day"
| "hour"
| "minute"
| "second";
export function formatRelativeDate(
date: Date,
unit: RelativeTimeFormatUnit = "day",
locale = getLocale(),
) {
const currentDate = Date.now();
let diff = (date.getTime() - currentDate) / (1000 * 60 * 60 * 24);
// if negative, round up, else round down
if (diff < 0) {
diff = Math.ceil(diff);
} else {
diff = Math.floor(diff);
}
return new Intl.RelativeTimeFormat(locale, {
localeMatcher: "best fit",
numeric: "auto",
style: "long",
}).format(diff, unit);
}
+239
View File
@@ -0,0 +1,239 @@
import mime from "mime-types";
import { IconType } from "react-icons";
import {
BsBoxFill,
BsDatabaseFill,
BsFileEarmarkBinaryFill,
BsFileEarmarkBreakFill,
BsFileEarmarkCodeFill,
BsFileEarmarkFill,
BsFileEarmarkFontFill,
BsFileEarmarkImageFill,
BsFileEarmarkMusicFill,
BsFileEarmarkPdfFill,
BsFileEarmarkPlayFill,
BsFileEarmarkRichtextFill,
BsFileEarmarkRuledFill,
BsFileEarmarkSlidesFill,
BsFileEarmarkSpreadsheetFill,
BsFileEarmarkTextFill,
BsFileEarmarkWordFill,
BsFileEarmarkZipFill,
BsFillDatabaseFill,
BsFolderFill,
} from "react-icons/bs";
import ModelPreview from "@components/FilePreview/ModelPreview";
import AudioPreview from "@components/FilePreview/AudioPreview";
import DefaultPreview from "@components/FilePreview/DefaultPreview";
import MarkdownPreview from "@components/FilePreview/MarkdownPreview";
import OfficePreview from "@components/FilePreview/OfficePreview";
import PDFPreview from "@components/FilePreview/PDFPreview";
import ImagePreview from "@components/FilePreview/ImagePreview";
import CodePreview from "@components/FilePreview/CodePreview";
import TextPreview from "@components/FilePreview/TextPreview";
import VideoPreview from "@components/FilePreview/VideoPreview";
export default function findMimeType(extension: string): string {
return mime.lookup(extension) || "application/octet-stream";
}
const type = {
"3d": "3d", // model preview
"audio": "audio", // audio preview
"archive": "archive", // default preview
"rich_text": "markdown", // markdown preview
"officeWord": "officeWord", // office preview
"officeExcel": "officeExcel", // office preview
"officePowerPoint": "officePowerPoint", // office preview
"pdf": "pdf", // pdf preview
"database": "database", // default preview
"image": "image", // image preview
"code": "code", // code preview
"text": "text", // text preview
"video": "video", // video preview
"font": "font", // default preview
"default": "default", // default preview
"binary": "binary", // default preview
};
const iconsForType: { [key: string]: IconType } = {
"3d": BsBoxFill,
"archive": BsFileEarmarkZipFill,
"audio": BsFileEarmarkMusicFill,
"rich_text": BsFileEarmarkRichtextFill,
"officeWord": BsFileEarmarkWordFill,
"officeExcel": BsFileEarmarkSpreadsheetFill,
"officePowerPoint": BsFileEarmarkSlidesFill,
"pdf": BsFileEarmarkPdfFill,
"database": BsDatabaseFill,
"image": BsFileEarmarkImageFill,
"code": BsFileEarmarkCodeFill,
"text": BsFileEarmarkTextFill,
"video": BsFileEarmarkPlayFill,
"font": BsFileEarmarkFontFill,
"default": BsFileEarmarkFill,
"binary": BsFileEarmarkBinaryFill,
};
const overlapVideo = ["ts", "ogg"];
const extToTypeMap: { [key: string]: string } = {
// 3D models
"fbx": type["3d"],
"obj": type["3d"],
"stl": type["3d"],
"gltf": type["3d"],
"glb": type["3d"],
// Audio
"aac": type.audio,
"flac": type.audio,
"m4a": type.audio,
"mp3": type.audio,
"ogg": type.audio, // Check for audio or video
"opus": type.audio,
"wav": type.audio,
// Archives
"7z": type.default,
"bz2": type.default,
"gz": type.default,
"rar": type.default,
"tar": type.default,
"zip": type.default,
// Rich text
"md": type.rich_text,
// Office
"doc": type.officeWord,
"docx": type.officeWord,
"odt": type.officeWord,
"xls": type.officeExcel,
"xlsx": type.officeExcel,
"ods": type.officeExcel,
"ppt": type.officePowerPoint,
"pptx": type.officePowerPoint,
"odp": type.officePowerPoint,
// PDF
"pdf": type.pdf,
// Database
"db": type.database,
"dbf": type.database,
"mdb": type.database,
"pdb": type.database,
"sql": type.database,
"csv": type.database,
"tsv": type.database,
// Images
"bmp": type.image,
"gif": type.image,
"jpg": type.image,
"jpeg": type.image,
"png": type.image,
"svg": type.image,
"webp": type.image,
"apng": type.image, //Should be able to preview according to MDN
"avif": type.image,
"ico": type.image,
// Code
"c": type.code,
"cpp": type.code,
"cs": type.code,
"css": type.code,
"go": type.code,
"h": type.code,
"html": type.code,
"ini": type.code,
"java": type.code,
"js": type.code,
"json": type.code,
"jsx": type.code,
"php": type.code,
"py": type.code,
"rb": type.code,
"rs": type.code,
"rust": type.code,
"sass": type.code,
"scss": type.code,
"sh": type.code,
"swift": type.code,
"ts": type.code, // Check for video also
"tsx": type.code,
"xml": type.code,
"yaml": type.code,
// Text
"txt": type.text,
// Video
"mp4": type.video,
"webm": type.video,
"3gp": type.video,
"mpeg": type.video,
"mov": type.video,
"mkv": type.video,
// Fonts
"woff": type.font,
"woff2": type.font,
"ttf": type.font,
"otf": type.font,
// Binary
"dat": type.binary,
"bin": type.binary,
"exe": type.binary,
"dll": type.binary,
"msi": type.binary,
};
export function getFilePreview(extension: string) {
if (overlapVideo.includes(extension)) {
const isVideo = findMimeType(extension).startsWith("video");
if (isVideo) {
return VideoPreview;
}
}
const category = extToTypeMap[extension] || type.default;
switch (category) {
case type["3d"]:
return ModelPreview;
case type.audio:
return AudioPreview;
case type.rich_text:
return MarkdownPreview;
case type.officeWord:
case type.officeExcel:
case type.officePowerPoint:
return OfficePreview;
case type.pdf:
return PDFPreview;
case type.image:
return ImagePreview;
case type.code:
return CodePreview;
case type.text:
return TextPreview;
case type.video:
return VideoPreview;
default:
return DefaultPreview;
}
}
export function getFileIcon(extension: string): IconType {
if (overlapVideo.includes(extension)) {
const isVideo = findMimeType(extension).startsWith("video");
if (isVideo) {
return iconsForType["video"];
}
}
const category = extToTypeMap[extension] || type.default;
return iconsForType[category];
}
+28
View File
@@ -0,0 +1,28 @@
import axios from "axios";
import {FilesResponse} from "@/types/googleapis";
const fetcher = async <T>(url: string) =>
axios.get<T>(url).then((res) => res.data);
function getNextKey(
pageIndex: number,
previousPageData: FilesResponse,
): string | null {
if (previousPageData && !previousPageData.nextPageToken) {
return null;
}
const pageToken = previousPageData ? previousPageData.nextPageToken : "";
return `/api/files?pageToken=${pageToken}`;
}
export function buildNextKey(apiURL:string) {
return (pageIndex: number, previousPageData: FilesResponse) => {
if (previousPageData && !previousPageData.nextPageToken) {
return null;
}
const pageToken = previousPageData ? previousPageData.nextPageToken : "";
return `${apiURL}?pageToken=${pageToken}`;
}
}
export default fetcher;