This commit is contained in:
Manav Rathi 2024-03-22 20:45:25 +05:30
parent 0fdb2fb357
commit d297465ea6
No known key found for this signature in database
9 changed files with 32 additions and 274 deletions

View file

@ -1,11 +1,11 @@
import { CustomError } from "@ente/shared/error";
import { addLogLine } from "@ente/shared/logging";
import { retryAsyncFunction } from "@ente/shared/promise";
import { logError } from "@ente/shared/sentry";
import { convertBytesToHumanReadable } from "@ente/shared/utils/size";
import QueueProcessor from "services/queueProcessor";
import { getDedicatedConvertWorker } from "utils/comlink/ComlinkConvertWorker";
import { ComlinkWorker } from "utils/comlink/comlinkWorker";
import { retryAsyncFunction } from "utils/network";
import { DedicatedConvertWorker } from "worker/convert.worker";
const WORKER_POOL_SIZE = 2;

View file

@ -1,28 +0,0 @@
import { sleep } from "@ente/shared/sleep";
const waitTimeBeforeNextAttemptInMilliSeconds = [2000, 5000, 10000];
export async function retryAsyncFunction<T>(
request: (abort?: () => void) => Promise<T>,
waitTimeBeforeNextTry?: number[],
): Promise<T> {
if (!waitTimeBeforeNextTry) {
waitTimeBeforeNextTry = waitTimeBeforeNextAttemptInMilliSeconds;
}
for (
let attemptNumber = 0;
attemptNumber <= waitTimeBeforeNextTry.length;
attemptNumber++
) {
try {
const resp = await request();
return resp;
} catch (e) {
if (attemptNumber === waitTimeBeforeNextTry.length) {
throw e;
}
await sleep(waitTimeBeforeNextTry[attemptNumber]);
}
}
}

View file

@ -1,78 +0,0 @@
import i18n, { t } from "i18next";
const dateTimeFullFormatter1 = new Intl.DateTimeFormat(i18n.language, {
weekday: "short",
month: "short",
day: "numeric",
});
const dateTimeFullFormatter2 = new Intl.DateTimeFormat(i18n.language, {
year: "numeric",
});
const dateTimeShortFormatter = new Intl.DateTimeFormat(i18n.language, {
month: "short",
day: "numeric",
year: "numeric",
hour: "2-digit",
minute: "2-digit",
});
const timeFormatter = new Intl.DateTimeFormat(i18n.language, {
timeStyle: "short",
});
export function formatDateFull(date: number | Date) {
return [dateTimeFullFormatter1, dateTimeFullFormatter2]
.map((f) => f.format(date))
.join(" ");
}
export function formatDate(date: number | Date) {
const withinYear =
new Date().getFullYear() === new Date(date).getFullYear();
const dateTimeFormat2 = !withinYear ? dateTimeFullFormatter2 : null;
return [dateTimeFullFormatter1, dateTimeFormat2]
.filter((f) => !!f)
.map((f) => f.format(date))
.join(" ");
}
export function formatDateTimeShort(date: number | Date) {
return dateTimeShortFormatter.format(date);
}
export function formatTime(date: number | Date) {
return timeFormatter.format(date).toUpperCase();
}
export function formatDateTimeFull(dateTime: number | Date): string {
return [formatDateFull(dateTime), t("at"), formatTime(dateTime)].join(" ");
}
export function formatDateTime(dateTime: number | Date): string {
return [formatDate(dateTime), t("at"), formatTime(dateTime)].join(" ");
}
export function formatDateRelative(date: number) {
const units = {
year: 24 * 60 * 60 * 1000 * 365,
month: (24 * 60 * 60 * 1000 * 365) / 12,
day: 24 * 60 * 60 * 1000,
hour: 60 * 60 * 1000,
minute: 60 * 1000,
second: 1000,
};
const relativeDateFormat = new Intl.RelativeTimeFormat(i18n.language, {
localeMatcher: "best fit",
numeric: "always",
style: "long",
});
const elapsed = date - Date.now(); // "Math.abs" accounts for both "past" & "future" scenarios
for (const u in units)
if (Math.abs(elapsed) > units[u] || u === "second")
return relativeDateFormat.format(
Math.round(elapsed / units[u]),
u as Intl.RelativeTimeFormatUnit,
);
}

View file

@ -1,136 +0,0 @@
export interface TimeDelta {
hours?: number;
days?: number;
months?: number;
years?: number;
}
interface DateComponent<T = number> {
year: T;
month: T;
day: T;
hour: T;
minute: T;
second: T;
}
export function validateAndGetCreationUnixTimeInMicroSeconds(dateTime: Date) {
if (!dateTime || isNaN(dateTime.getTime())) {
return null;
}
const unixTime = dateTime.getTime() * 1000;
//ignoring dateTimeString = "0000:00:00 00:00:00"
if (unixTime === Date.UTC(0, 0, 0, 0, 0, 0, 0) || unixTime === 0) {
return null;
} else if (unixTime > Date.now() * 1000) {
return null;
} else {
return unixTime;
}
}
/*
generates data component for date in format YYYYMMDD-HHMMSS
*/
export function parseDateFromFusedDateString(dateTime: string) {
const dateComponent: DateComponent<number> = convertDateComponentToNumber({
year: dateTime.slice(0, 4),
month: dateTime.slice(4, 6),
day: dateTime.slice(6, 8),
hour: dateTime.slice(9, 11),
minute: dateTime.slice(11, 13),
second: dateTime.slice(13, 15),
});
return validateAndGetDateFromComponents(dateComponent);
}
/* sample date format = 2018-08-19 12:34:45
the date has six symbol separated number values
which we would extract and use to form the date
*/
export function tryToParseDateTime(dateTime: string): Date {
const dateComponent = getDateComponentsFromSymbolJoinedString(dateTime);
if (dateComponent.year?.length === 8 && dateComponent.month?.length === 6) {
// the filename has size 8 consecutive and then 6 consecutive digits
// high possibility that the it is a date in format YYYYMMDD-HHMMSS
const possibleDateTime = dateComponent.year + "-" + dateComponent.month;
return parseDateFromFusedDateString(possibleDateTime);
}
return validateAndGetDateFromComponents(
convertDateComponentToNumber(dateComponent),
);
}
function getDateComponentsFromSymbolJoinedString(
dateTime: string,
): DateComponent<string> {
const [year, month, day, hour, minute, second] =
dateTime.match(/\d+/g) ?? [];
return { year, month, day, hour, minute, second };
}
function validateAndGetDateFromComponents(
dateComponent: DateComponent<number>,
) {
let date = getDateFromComponents(dateComponent);
if (hasTimeValues(dateComponent) && !isTimePartValid(date, dateComponent)) {
// if the date has time values but they are not valid
// then we remove the time values and try to validate the date
date = getDateFromComponents(removeTimeValues(dateComponent));
}
if (!isDatePartValid(date, dateComponent)) {
return null;
}
return date;
}
function isTimePartValid(date: Date, dateComponent: DateComponent<number>) {
return (
date.getHours() === dateComponent.hour &&
date.getMinutes() === dateComponent.minute &&
date.getSeconds() === dateComponent.second
);
}
function isDatePartValid(date: Date, dateComponent: DateComponent<number>) {
return (
date.getFullYear() === dateComponent.year &&
date.getMonth() === dateComponent.month &&
date.getDate() === dateComponent.day
);
}
function convertDateComponentToNumber(
dateComponent: DateComponent<string>,
): DateComponent<number> {
return {
year: Number(dateComponent.year),
// https://stackoverflow.com/questions/2552483/why-does-the-month-argument-range-from-0-to-11-in-javascripts-date-constructor
month: Number(dateComponent.month) - 1,
day: Number(dateComponent.day),
hour: Number(dateComponent.hour),
minute: Number(dateComponent.minute),
second: Number(dateComponent.second),
};
}
function getDateFromComponents(dateComponent: DateComponent<number>) {
const { year, month, day, hour, minute, second } = dateComponent;
if (hasTimeValues(dateComponent)) {
return new Date(year, month, day, hour, minute, second);
} else {
return new Date(year, month, day);
}
}
function hasTimeValues(dateComponent: DateComponent<number>) {
const { hour, minute, second } = dateComponent;
return !isNaN(hour) && !isNaN(minute) && !isNaN(second);
}
function removeTimeValues(
dateComponent: DateComponent<number>,
): DateComponent<number> {
return { ...dateComponent, hour: 0, minute: 0, second: 0 };
}

View file

@ -1,9 +1,9 @@
import { CustomError } from "@ente/shared/error";
import HTTPService from "@ente/shared/network/HTTPService";
import { getFileURL, getThumbnailURL } from "@ente/shared/network/api";
import { retryAsyncFunction } from "@ente/shared/promise";
import { DownloadClient } from "services/download";
import { EnteFile } from "types/file";
import { retryAsyncFunction } from "utils/network";
export class PhotosDownloadClient implements DownloadClient {
constructor(

View file

@ -4,9 +4,9 @@ import {
getPublicCollectionFileURL,
getPublicCollectionThumbnailURL,
} from "@ente/shared/network/api";
import { retryAsyncFunction } from "@ente/shared/promise";
import { DownloadClient } from "services/download";
import { EnteFile } from "types/file";
import { retryAsyncFunction } from "utils/network";
export class PublicAlbumsDownloadClient implements DownloadClient {
constructor(

View file

@ -1,11 +1,11 @@
import { CustomError } from "@ente/shared/error";
import { addLogLine } from "@ente/shared/logging";
import { retryAsyncFunction } from "@ente/shared/promise";
import { logError } from "@ente/shared/sentry";
import { convertBytesToHumanReadable } from "@ente/shared/utils/size";
import { ComlinkWorker } from "@ente/shared/worker/comlinkWorker";
import QueueProcessor from "services/queueProcessor";
import { getDedicatedConvertWorker } from "utils/comlink/ComlinkConvertWorker";
import { retryAsyncFunction } from "utils/network";
import { DedicatedConvertWorker } from "worker/convert.worker";
const WORKER_POOL_SIZE = 2;

View file

@ -1,28 +0,0 @@
import { sleep } from "utils/common";
const waitTimeBeforeNextAttemptInMilliSeconds = [2000, 5000, 10000];
export async function retryAsyncFunction<T>(
request: (abort?: () => void) => Promise<T>,
waitTimeBeforeNextTry?: number[],
): Promise<T> {
if (!waitTimeBeforeNextTry) {
waitTimeBeforeNextTry = waitTimeBeforeNextAttemptInMilliSeconds;
}
for (
let attemptNumber = 0;
attemptNumber <= waitTimeBeforeNextTry.length;
attemptNumber++
) {
try {
const resp = await request();
return resp;
} catch (e) {
if (attemptNumber === waitTimeBeforeNextTry.length) {
throw e;
}
await sleep(waitTimeBeforeNextTry[attemptNumber]);
}
}
}

View file

@ -1,5 +1,33 @@
import { sleep } from "@ente/shared/sleep";
import { CustomError } from "../error";
const waitTimeBeforeNextAttemptInMilliSeconds = [2000, 5000, 10000];
export async function retryAsyncFunction<T>(
request: (abort?: () => void) => Promise<T>,
waitTimeBeforeNextTry?: number[],
): Promise<T> {
if (!waitTimeBeforeNextTry) {
waitTimeBeforeNextTry = waitTimeBeforeNextAttemptInMilliSeconds;
}
for (
let attemptNumber = 0;
attemptNumber <= waitTimeBeforeNextTry.length;
attemptNumber++
) {
try {
const resp = await request();
return resp;
} catch (e) {
if (attemptNumber === waitTimeBeforeNextTry.length) {
throw e;
}
await sleep(waitTimeBeforeNextTry[attemptNumber]);
}
}
}
export const promiseWithTimeout = async <T>(
request: Promise<T>,
timeout: number,