read files

This commit is contained in:
Manav Rathi
2024-06-26 13:28:26 +05:30
parent 1d0cbc527a
commit 2c3bd39ab6
69 changed files with 229 additions and 206 deletions

View File

@@ -9,6 +9,12 @@ import { FILE_TYPE } from "@/media/file-type";
import { isHEICExtension, isNonWebImageFileExtension } from "@/media/formats";
import { heicToJPEG } from "@/media/heic-convert";
import { decodeLivePhoto } from "@/media/live-photo";
import type {
EncryptedEnteFile,
EnteFile,
FileMagicMetadata,
FilePublicMagicMetadata,
} from "@/new/photos/types/file";
import { nameAndExtension } from "@/next/file";
import log from "@/next/log";
import { apiOrigin, customAPIOrigin } from "@/next/origins";
@@ -21,12 +27,6 @@ import HTTPService from "@ente/shared/network/HTTPService";
import type { AxiosResponse } from "axios";
import type { CastData } from "services/cast-data";
import { detectMediaMIMEType } from "services/detect-type";
import type {
EncryptedEnteFile,
EnteFile,
FileMagicMetadata,
FilePublicMagicMetadata,
} from "types/file";
import { isChromecast } from "./chromecast";
/**

View File

@@ -3,7 +3,7 @@ import type {
EncryptedMagicMetadata,
MagicMetadataCore,
VISIBILITY_STATE,
} from "types/magicMetadata";
} from "@/new/photos/types/magicMetadata";
export interface MetadataFileAttributes {
encryptedData: string;

View File

@@ -1,10 +1,10 @@
import { EnteFile } from "@/new/photos/types/file";
import {
LoadingThumbnail,
StaticThumbnail,
} from "components/PlaceholderThumbnails";
import { useEffect, useState } from "react";
import downloadManager from "services/download";
import { EnteFile } from "types/file";
export default function CollectionCard(props: {
children?: any;

View File

@@ -1,3 +1,4 @@
import { VISIBILITY_STATE } from "@/new/photos/types/magicMetadata";
import log from "@/next/log";
import { HorizontalFlex } from "@ente/shared/components/Container";
import OverflowMenu from "@ente/shared/components/OverflowMenu/menu";
@@ -18,7 +19,6 @@ import * as CollectionAPI from "services/collectionService";
import * as TrashService from "services/trashService";
import { Collection } from "types/collection";
import { SetFilesDownloadProgressAttributesCreator } from "types/gallery";
import { VISIBILITY_STATE } from "types/magicMetadata";
import {
changeCollectionOrder,
changeCollectionSortOrder,

View File

@@ -1,3 +1,4 @@
import { EnteFile } from "@/new/photos/types/file";
import { SpaceBetweenFlex } from "@ente/shared/components/Container";
import { formatDateTime } from "@ente/shared/time/format";
import {
@@ -9,7 +10,6 @@ import {
} from "@mui/material";
import { t } from "i18next";
import { useState } from "react";
import { EnteFile } from "types/file";
import { formatNumber } from "utils/number/format";
import ExportPendingList from "./ExportPendingList";
import LinkButton from "./pages/gallery/LinkButton";

View File

@@ -1,3 +1,4 @@
import { EnteFile } from "@/new/photos/types/file";
import log from "@/next/log";
import ChangeDirectoryOption from "@ente/shared/components/ChangeDirectoryOption";
import {
@@ -24,7 +25,6 @@ import exportService, {
selectAndPrepareExportDirectory,
} from "services/export";
import { ExportProgress, ExportSettings } from "types/export";
import { EnteFile } from "types/file";
import { getExportDirectoryDoesNotExistMessage } from "utils/ui";
import { DirectoryPath } from "./Directory";
import ExportFinished from "./ExportFinished";

View File

@@ -1,9 +1,9 @@
import { EnteFile } from "@/new/photos/types/file";
import { FlexWrapper } from "@ente/shared/components/Container";
import DialogBoxV2 from "@ente/shared/components/DialogBoxV2";
import { Box, styled } from "@mui/material";
import ItemList from "components/ItemList";
import { t } from "i18next";
import { EnteFile } from "types/file";
import CollectionCard from "./Collections/CollectionCard";
import { ResultPreviewTile } from "./Collections/styledComponents";

View File

@@ -1,3 +1,4 @@
import { EnteFile } from "@/new/photos/types/file";
import DialogBox from "@ente/shared/components/DialogBox/";
import {
Button,
@@ -14,7 +15,6 @@ import { t } from "i18next";
import { GalleryContext } from "pages/gallery";
import React, { useContext, useEffect, useState } from "react";
import { updateCreationTimeWithExif } from "services/fix-exif";
import { EnteFile } from "types/file";
import EnteDateTimePicker from "./EnteDateTimePicker";
export interface FixCreationTimeAttributes {

View File

@@ -1,4 +1,6 @@
import { FILE_TYPE } from "@/media/file-type";
import type { LivePhotoSourceURL, SourceURLs } from "@/new/photos/types/file";
import { EnteFile } from "@/new/photos/types/file";
import log from "@/next/log";
import { PHOTOS_PAGES } from "@ente/shared/constants/pages";
import { CustomError } from "@ente/shared/error";
@@ -12,11 +14,7 @@ import PhotoSwipe from "photoswipe";
import { useContext, useEffect, useState } from "react";
import AutoSizer from "react-virtualized-auto-sizer";
import { Duplicate } from "services/deduplicationService";
import DownloadManager, {
LivePhotoSourceURL,
SourceURLs,
} from "services/download";
import { EnteFile } from "types/file";
import DownloadManager from "services/download";
import {
SelectedState,
SetFilesDownloadProgressAttributesCreator,

View File

@@ -1,3 +1,4 @@
import { EnteFile } from "@/new/photos/types/file";
import { FlexWrapper } from "@ente/shared/components/Container";
import { Box, styled } from "@mui/material";
import {
@@ -18,7 +19,6 @@ import {
areEqual,
} from "react-window";
import { Duplicate } from "services/deduplicationService";
import { EnteFile } from "types/file";
import { formattedByteSize } from "utils/units";
export enum ITEM_TYPE {

View File

@@ -1,3 +1,4 @@
import { EnteFile } from "@/new/photos/types/file";
import { FlexWrapper } from "@ente/shared/components/Container";
import { formatDate } from "@ente/shared/time/format";
import { Box, Checkbox, Link, Typography, styled } from "@mui/material";
@@ -21,7 +22,6 @@ import {
ListChildComponentProps,
areEqual,
} from "react-window";
import { EnteFile } from "types/file";
import { handleSelectCreator } from "utils/photoFrame";
import { PublicCollectionGalleryContext } from "utils/publicCollectionGallery";
import { formattedByteSize } from "utils/units";

View File

@@ -1,3 +1,4 @@
import { EnteFile } from "@/new/photos/types/file";
import log from "@/next/log";
import { FlexWrapper } from "@ente/shared/components/Container";
import Close from "@mui/icons-material/Close";
@@ -6,7 +7,6 @@ import { Box, IconButton, TextField } from "@mui/material";
import { Formik } from "formik";
import { t } from "i18next";
import { useState } from "react";
import { EnteFile } from "types/file";
import { changeCaption, updateExistingFilePubMetadata } from "utils/file";
import * as Yup from "yup";
import { SmallLoadingSpinner } from "../styledComponents/SmallLoadingSpinner";

View File

@@ -1,10 +1,10 @@
import { EnteFile } from "@/new/photos/types/file";
import log from "@/next/log";
import { FlexWrapper } from "@ente/shared/components/Container";
import { formatDate, formatTime } from "@ente/shared/time/format";
import CalendarTodayIcon from "@mui/icons-material/CalendarToday";
import EnteDateTimePicker from "components/EnteDateTimePicker";
import { useState } from "react";
import { EnteFile } from "types/file";
import {
changeFileCreationTime,
updateExistingFilePubMetadata,

View File

@@ -1,4 +1,5 @@
import { FILE_TYPE } from "@/media/file-type";
import { EnteFile } from "@/new/photos/types/file";
import { nameAndExtension } from "@/next/file";
import log from "@/next/log";
import { FlexWrapper } from "@ente/shared/components/Container";
@@ -6,7 +7,6 @@ import PhotoOutlined from "@mui/icons-material/PhotoOutlined";
import VideocamOutlined from "@mui/icons-material/VideocamOutlined";
import Box from "@mui/material/Box";
import { useEffect, useState } from "react";
import { EnteFile } from "types/file";
import { changeFileName, updateExistingFilePubMetadata } from "utils/file";
import { formattedByteSize } from "utils/units";
import { FileNameEditDialog } from "./FileNameEditDialog";

View File

@@ -1,3 +1,4 @@
import { EnteFile } from "@/new/photos/types/file";
import CopyButton from "@ente/shared/components/CodeBlock/CopyButton";
import { FlexWrapper } from "@ente/shared/components/Container";
import EnteSpinner from "@ente/shared/components/EnteSpinner";
@@ -18,7 +19,6 @@ import { AppContext } from "pages/_app";
import { GalleryContext } from "pages/gallery";
import { useContext, useEffect, useMemo, useState } from "react";
import { getEXIFLocation } from "services/exif";
import { EnteFile } from "types/file";
import { PublicCollectionGalleryContext } from "utils/publicCollectionGallery";
import {
getMapDisableConfirmationDialog,

View File

@@ -1,3 +1,4 @@
import { EnteFile } from "@/new/photos/types/file";
import { nameAndExtension } from "@/next/file";
import log from "@/next/log";
import { ensure } from "@/utils/ensure";
@@ -36,7 +37,6 @@ import { createContext, useContext, useEffect, useRef, useState } from "react";
import { getLocalCollections } from "services/collectionService";
import downloadManager from "services/download";
import uploadManager from "services/upload/uploadManager";
import { EnteFile } from "types/file";
import { getEditorCloseConfirmationMessage } from "utils/ui";
import ColoursMenu from "./ColoursMenu";
import CropMenu, { cropRegionOfCanvas, getCropRegionArgs } from "./CropMenu";

View File

@@ -1,3 +1,4 @@
import { EnteFile } from "@/new/photos/types/file";
import log from "@/next/log";
import Photoswipe from "photoswipe";
import PhotoswipeUIDefault from "photoswipe/dist/photoswipe-ui-default";
@@ -6,7 +7,6 @@ import {
addToFavorites,
removeFromFavorites,
} from "services/collectionService";
import { EnteFile } from "types/file";
import {
copyFileToClipboard,
downloadSingleFile,
@@ -16,6 +16,7 @@ import {
import { FILE_TYPE } from "@/media/file-type";
import { isNonWebImageFileExtension } from "@/media/formats";
import type { LoadedLivePhotoSourceURL } from "@/new/photos/types/file";
import { lowercaseExtension } from "@/next/file";
import { FlexWrapper } from "@ente/shared/components/Container";
import EnteSpinner from "@ente/shared/components/EnteSpinner";
@@ -44,7 +45,7 @@ import isElectron from "is-electron";
import { AppContext } from "pages/_app";
import { GalleryContext } from "pages/gallery";
import { detectFileTypeInfo } from "services/detect-type";
import downloadManager, { LoadedLivePhotoSourceURL } from "services/download";
import downloadManager from "services/download";
import { getParsedExifData } from "services/exif";
import { trashFiles } from "services/fileService";
import { SetFilesDownloadProgressAttributesCreator } from "types/gallery";

View File

@@ -1,7 +1,7 @@
import { Collection } from "types/collection";
import { SearchBarMobile } from "./searchBarMobile";
import { EnteFile } from "types/file";
import { EnteFile } from "@/new/photos/types/file";
import { UpdateSearch } from "types/search";
import SearchInput from "./searchInput";
import { SearchBarWrapper } from "./styledComponents";

View File

@@ -1,4 +1,5 @@
import { FILE_TYPE } from "@/media/file-type";
import { EnteFile } from "@/new/photos/types/file";
import CloseIcon from "@mui/icons-material/Close";
import { IconButton } from "@mui/material";
import { t } from "i18next";
@@ -17,7 +18,6 @@ import {
} from "services/searchService";
import { Collection } from "types/collection";
import { LocationTagData } from "types/entity";
import { EnteFile } from "types/file";
import {
ClipSearchScores,
DateValue,

View File

@@ -1,3 +1,4 @@
import { EnteFile } from "@/new/photos/types/file";
import { blobCache } from "@/next/blob-cache";
import { Skeleton, styled } from "@mui/material";
import { Legend } from "components/PhotoViewer/styledComponents/Legend";
@@ -5,7 +6,6 @@ import { t } from "i18next";
import React, { useEffect, useState } from "react";
import { unidentifiedFaceIDs } from "services/face/indexer";
import type { Person } from "services/face/people";
import { EnteFile } from "types/file";
const FaceChipContainer = styled("div")`
display: flex;

View File

@@ -1,9 +1,9 @@
import { EnteFile } from "@/new/photos/types/file";
import log from "@/next/log";
import { styled } from "@mui/material";
import { useTheme } from "@mui/material/styles";
import { GalleryContext } from "pages/gallery";
import React, { useContext, useLayoutEffect, useState } from "react";
import { EnteFile } from "types/file";
interface AvatarProps {
file?: EnteFile;

View File

@@ -1,3 +1,4 @@
import { EnteFile } from "@/new/photos/types/file";
import { FlexWrapper, HorizontalFlex } from "@ente/shared/components/Container";
import SidebarToggler from "@ente/shared/components/Navbar/SidebarToggler";
import NavbarBase from "@ente/shared/components/Navbar/base";
@@ -9,7 +10,6 @@ import { t } from "i18next";
import { AppContext } from "pages/_app";
import React from "react";
import { Collection } from "types/collection";
import { EnteFile } from "types/file";
import { UpdateSearch } from "types/search";
interface Iprops {

View File

@@ -1,4 +1,5 @@
import { FILE_TYPE } from "@/media/file-type";
import { EnteFile } from "@/new/photos/types/file";
import log from "@/next/log";
import { Overlay } from "@ente/shared/components/Container";
import { CustomError } from "@ente/shared/error";
@@ -17,7 +18,6 @@ import { DeduplicateContext } from "pages/deduplicate";
import { GalleryContext } from "pages/gallery";
import React, { useContext, useEffect, useRef, useState } from "react";
import DownloadManager from "services/download";
import { EnteFile } from "types/file";
import { shouldShowAvatar } from "utils/file";
import Avatar from "./Avatar";

View File

@@ -1,11 +1,11 @@
import { t } from "i18next";
import { getLocalFiles } from "@/new/photos/services/files";
import PhotoFrame from "components/PhotoFrame";
import { ALL_SECTION } from "constants/collection";
import { t } from "i18next";
import { AppContext } from "pages/_app";
import { createContext, useContext, useEffect, useState } from "react";
import { Duplicate, getDuplicates } from "services/deduplicationService";
import { getLocalFiles, syncFiles, trashFiles } from "services/fileService";
import { syncFiles, trashFiles } from "services/fileService";
import { SelectedState } from "types/gallery";
import { VerticallyCentered } from "@ente/shared/components/Container";

View File

@@ -1,6 +1,8 @@
import { WhatsNew } from "@/new/photos/components/WhatsNew";
import { shouldShowWhatsNew } from "@/new/photos/services/changelog";
import { fetchAndSaveFeatureFlagsIfNeeded } from "@/new/photos/services/feature-flags";
import { getLocalFiles } from "@/new/photos/services/files";
import { EnteFile } from "@/new/photos/types/file";
import log from "@/next/log";
import { CenteredFlex } from "@ente/shared/components/Container";
import EnteSpinner from "@ente/shared/components/EnteSpinner";
@@ -90,13 +92,12 @@ import {
import downloadManager from "services/download";
import { syncCLIPEmbeddings } from "services/embeddingService";
import { syncEntities } from "services/entityService";
import { getLocalFiles, syncFiles } from "services/fileService";
import { syncFiles } from "services/fileService";
import locationSearchService from "services/locationSearchService";
import { getLocalTrashedFiles, syncTrash } from "services/trashService";
import uploadManager from "services/upload/uploadManager";
import { isTokenValid, syncMapEnabled } from "services/userService";
import { Collection, CollectionSummaries } from "types/collection";
import { EnteFile } from "types/file";
import {
GalleryContextType,
SelectedState,

View File

@@ -1,3 +1,4 @@
import { EnteFile } from "@/new/photos/types/file";
import log from "@/next/log";
import {
CenteredFlex,
@@ -58,7 +59,6 @@ import {
verifyPublicCollectionPassword,
} from "services/publicCollectionService";
import { Collection } from "types/collection";
import { EnteFile } from "types/file";
import {
SelectedState,
SetFilesDownloadProgressAttributes,

View File

@@ -1,4 +1,6 @@
import { FILE_TYPE } from "@/media/file-type";
import { getAllLocalFiles, getLocalFiles } from "@/new/photos/services/files";
import { EnteFile } from "@/new/photos/types/file";
import { ensureElectron } from "@/next/electron";
import log from "@/next/log";
import ComlinkCryptoWorker from "@ente/shared/crypto";
@@ -8,11 +10,9 @@ import { LS_KEYS, getData } from "@ente/shared/storage/localStorage";
import isElectron from "is-electron";
import PQueue from "p-queue";
import { Embedding } from "types/embedding";
import { EnteFile } from "types/file";
import { getPersonalFiles } from "utils/file";
import downloadManager from "./download";
import { localCLIPEmbeddings, putEmbedding } from "./embeddingService";
import { getAllLocalFiles, getLocalFiles } from "./fileService";
/** Status of CLIP indexing on the images in the user's local library. */
export interface CLIPIndexingStatus {

View File

@@ -1,10 +1,18 @@
import { getLocalFiles } from "@/new/photos/services/files";
import { EnteFile } from "@/new/photos/types/file";
import {
EncryptedMagicMetadata,
SUB_TYPE,
UpdateMagicMetadataRequest,
VISIBILITY_STATE,
} from "@/new/photos/types/magicMetadata";
import log from "@/next/log";
import { apiOrigin } from "@/next/origins";
import ComlinkCryptoWorker from "@ente/shared/crypto";
import { CustomError } from "@ente/shared/error";
import HTTPService from "@ente/shared/network/HTTPService";
import localForage from "@ente/shared/storage/localForage";
import { getData, LS_KEYS } from "@ente/shared/storage/localStorage";
import { LS_KEYS, getData } from "@ente/shared/storage/localStorage";
import { getToken } from "@ente/shared/storage/localStorage/helpers";
import { getActualKey } from "@ente/shared/user";
import type { User } from "@ente/shared/user/types";
@@ -40,13 +48,6 @@ import {
RemoveFromCollectionRequest,
UpdatePublicURL,
} from "types/collection";
import { EnteFile } from "types/file";
import {
EncryptedMagicMetadata,
SUB_TYPE,
UpdateMagicMetadataRequest,
VISIBILITY_STATE,
} from "types/magicMetadata";
import { FamilyData } from "types/user";
import {
changeCollectionSubType,
@@ -73,7 +74,6 @@ import {
isPinnedCollection,
updateMagicMetadata,
} from "utils/magicMetadata";
import { getLocalFiles } from "./fileService";
import { getPublicKey } from "./userService";
const COLLECTION_TABLE = "collections";

View File

@@ -1,11 +1,11 @@
import { hasFileHash } from "@/media/file";
import { FILE_TYPE } from "@/media/file-type";
import type { Metadata } from "@/media/types/file";
import { EnteFile } from "@/new/photos/types/file";
import log from "@/next/log";
import { apiOrigin } from "@/next/origins";
import HTTPService from "@ente/shared/network/HTTPService";
import { getToken } from "@ente/shared/storage/localStorage/helpers";
import { EnteFile } from "types/file";
interface DuplicatesResponse {
duplicates: Array<{

View File

@@ -1,9 +1,9 @@
import { EnteFile } from "@/new/photos/types/file";
import { customAPIOrigin } from "@/next/origins";
import { CustomError } from "@ente/shared/error";
import HTTPService from "@ente/shared/network/HTTPService";
import { retryAsyncFunction } from "@ente/shared/utils";
import { DownloadClient } from "services/download";
import { EnteFile } from "types/file";
export class PhotosDownloadClient implements DownloadClient {
constructor(

View File

@@ -1,9 +1,9 @@
import { EnteFile } from "@/new/photos/types/file";
import { customAPIOrigin } from "@/next/origins";
import { CustomError } from "@ente/shared/error";
import HTTPService from "@ente/shared/network/HTTPService";
import { retryAsyncFunction } from "@ente/shared/utils";
import { DownloadClient } from "services/download";
import { EnteFile } from "types/file";
export class PublicAlbumsDownloadClient implements DownloadClient {
private token: string;

View File

@@ -1,5 +1,10 @@
import { FILE_TYPE } from "@/media/file-type";
import { decodeLivePhoto } from "@/media/live-photo";
import {
EnteFile,
type LivePhotoSourceURL,
type SourceURLs,
} from "@/new/photos/types/file";
import { blobCache, type BlobCache } from "@/next/blob-cache";
import log from "@/next/log";
import ComlinkCryptoWorker from "@ente/shared/crypto";
@@ -9,38 +14,10 @@ import { isPlaybackPossible } from "@ente/shared/media/video-playback";
import type { Remote } from "comlink";
import isElectron from "is-electron";
import * as ffmpeg from "services/ffmpeg";
import { EnteFile } from "types/file";
import { getRenderableImage } from "utils/file";
import { PhotosDownloadClient } from "./clients/photos";
import { PublicAlbumsDownloadClient } from "./clients/publicAlbums";
export type LivePhotoSourceURL = {
image: () => Promise<string>;
video: () => Promise<string>;
};
export type LoadedLivePhotoSourceURL = {
image: string;
video: string;
};
export type SourceURLs = {
url: string | LivePhotoSourceURL | LoadedLivePhotoSourceURL;
isOriginal: boolean;
isRenderable: boolean;
type: "normal" | "livePhoto";
/**
* Best effort attempt at obtaining the MIME type.
*
* Known cases where it is missing:
*
* - Live photos (these have a different code path for obtaining the URL).
* - A video that is passes the isPlayable test in the browser.
*
*/
mimeType?: string;
};
export type OnDownloadProgress = (event: {
loaded: number;
total: number;

View File

@@ -1,4 +1,6 @@
import type { EmbeddingModel } from "@/new/photos/services/embedding";
import { getAllLocalFiles } from "@/new/photos/services/files";
import { EnteFile } from "@/new/photos/types/file";
import { inWorker } from "@/next/env";
import log from "@/next/log";
import { apiOrigin } from "@/next/origins";
@@ -14,10 +16,8 @@ import type {
GetEmbeddingDiffResponse,
PutEmbeddingRequest,
} from "types/embedding";
import { EnteFile } from "types/file";
import { getLocalCollections } from "./collectionService";
import type { FaceIndex } from "./face/types";
import { getAllLocalFiles } from "./fileService";
import { getLocalTrashedFiles } from "./trashService";
type FileML = FaceIndex & {

View File

@@ -1,6 +1,8 @@
import { FILE_TYPE } from "@/media/file-type";
import { decodeLivePhoto } from "@/media/live-photo";
import type { Metadata } from "@/media/types/file";
import { getAllLocalFiles } from "@/new/photos/services/files";
import { EnteFile } from "@/new/photos/types/file";
import { ensureElectron } from "@/next/electron";
import log from "@/next/log";
import { wait } from "@/utils/promise";
@@ -22,7 +24,6 @@ import {
ExportUIUpdaters,
FileExportNames,
} from "types/export";
import { EnteFile } from "types/file";
import {
constructCollectionNameMap,
getCollectionUserFacingName,
@@ -37,7 +38,6 @@ import { safeDirectoryName, safeFileName } from "utils/native-fs";
import { writeStream } from "utils/native-stream";
import { getAllLocalCollections } from "../collectionService";
import downloadManager from "../download";
import { getAllLocalFiles } from "../fileService";
import { migrateExport } from "./migration";
/** Name of the JSON file in which we keep the state of the export. */

View File

@@ -1,5 +1,7 @@
import { FILE_TYPE } from "@/media/file-type";
import { decodeLivePhoto } from "@/media/live-photo";
import { getAllLocalFiles } from "@/new/photos/services/files";
import { EnteFile } from "@/new/photos/types/file";
import { ensureElectron } from "@/next/electron";
import { nameAndExtension } from "@/next/file";
import log from "@/next/log";
@@ -8,7 +10,6 @@ import { LS_KEYS, getData } from "@ente/shared/storage/localStorage";
import type { User } from "@ente/shared/user/types";
import { getLocalCollections } from "services/collectionService";
import downloadManager from "services/download";
import { getAllLocalFiles } from "services/fileService";
import { Collection } from "types/collection";
import {
CollectionExportNames,
@@ -20,7 +21,6 @@ import {
ExportedCollectionPaths,
FileExportNames,
} from "types/export";
import { EnteFile } from "types/file";
import { getNonEmptyPersonalCollections } from "utils/collection";
import {
getIDBasedSortedFiles,

View File

@@ -1,5 +1,6 @@
import { FILE_TYPE } from "@/media/file-type";
import { decodeLivePhoto } from "@/media/live-photo";
import type { EnteFile } from "@/new/photos/types/file";
import log from "@/next/log";
import { workerBridge } from "@/next/worker/worker-bridge";
import { Matrix } from "ml-matrix";
@@ -12,7 +13,6 @@ import {
scale,
translate,
} from "transformation-matrix";
import type { EnteFile } from "types/file";
import { getRenderableImage } from "utils/file";
import { saveFaceCrop } from "./crop";
import {

View File

@@ -1,7 +1,7 @@
import { EnteFile } from "@/new/photos/types/file";
import { expose } from "comlink";
import downloadManager from "services/download";
import mlService from "services/machineLearning/machineLearningService";
import { EnteFile } from "types/file";
export class DedicatedMLWorker {
public async closeLocalSyncContext() {

View File

@@ -2,11 +2,11 @@ import {
isBetaUser,
isInternalUser,
} from "@/new/photos/services/feature-flags";
import { getAllLocalFiles } from "@/new/photos/services/files";
import type { EnteFile } from "@/new/photos/types/file";
import { ComlinkWorker } from "@/next/worker/comlink-worker";
import { ensure } from "@/utils/ensure";
import type { Remote } from "comlink";
import { getAllLocalFiles } from "services/fileService";
import type { EnteFile } from "types/file";
import {
faceIndex,
indexableFileIDs,

View File

@@ -1,5 +1,5 @@
import type { EnteFile } from "@/new/photos/types/file";
import log from "@/next/log";
import type { EnteFile } from "types/file";
import { fileLogID } from "utils/file";
import {
closeFaceDBConnectionsIfNeeded,

View File

@@ -1,4 +1,5 @@
import { FILE_TYPE } from "@/media/file-type";
import { EnteFile } from "@/new/photos/types/file";
import { ensureElectron } from "@/next/electron";
import log from "@/next/log";
import { clientPackageNamePhotosDesktop } from "@/next/types/app";
@@ -8,7 +9,6 @@ import { getToken, getUserID } from "@ente/shared/storage/localStorage/helpers";
import debounce from "debounce";
import PQueue from "p-queue";
import type { DedicatedMLWorker } from "services/face/face.worker";
import { EnteFile } from "types/file";
export type JobState = "Scheduled" | "Running" | "NotScheduled";

View File

@@ -1,7 +1,7 @@
import type { EnteFile } from "@/new/photos/types/file";
import log from "@/next/log";
import ComlinkCryptoWorker from "@ente/shared/crypto";
import { putEmbedding } from "services/embeddingService";
import type { EnteFile } from "types/file";
import type { FaceIndex } from "./types";
export const putFaceIndex = async (

View File

@@ -1,21 +1,20 @@
import log from "@/next/log";
import { apiOrigin } from "@/next/origins";
import ComlinkCryptoWorker from "@ente/shared/crypto";
import { Events, eventBus } from "@ente/shared/events";
import HTTPService from "@ente/shared/network/HTTPService";
import localForage from "@ente/shared/storage/localForage";
import { getToken } from "@ente/shared/storage/localStorage/helpers";
import { REQUEST_BATCH_SIZE } from "constants/api";
import { Collection } from "types/collection";
import { getLocalFiles, setLocalFiles } from "@/new/photos/services/files";
import {
EncryptedEnteFile,
EnteFile,
FileWithUpdatedMagicMetadata,
FileWithUpdatedPublicMagicMetadata,
TrashRequest,
} from "types/file";
} from "@/new/photos/types/file";
import { BulkUpdateMagicMetadataRequest } from "@/new/photos/types/magicMetadata";
import log from "@/next/log";
import { apiOrigin } from "@/next/origins";
import ComlinkCryptoWorker from "@ente/shared/crypto";
import HTTPService from "@ente/shared/network/HTTPService";
import { getToken } from "@ente/shared/storage/localStorage/helpers";
import { REQUEST_BATCH_SIZE } from "constants/api";
import { Collection } from "types/collection";
import { SetFiles } from "types/gallery";
import { BulkUpdateMagicMetadataRequest } from "types/magicMetadata";
import { batch } from "utils/common";
import {
decryptFile,
@@ -28,52 +27,6 @@ import {
setCollectionLastSyncTime,
} from "./collectionService";
const FILES_TABLE = "files";
const HIDDEN_FILES_TABLE = "hidden-files";
/**
* Return all files that we know about locally, both "normal" and "hidden".
*/
export const getAllLocalFiles = async () =>
[].concat(await getLocalFiles("normal"), await getLocalFiles("hidden"));
/**
* Return all files that we know about locally. By default it returns only
* "normal" (i.e. non-"hidden") files, but it can be passed the {@link type}
* "hidden" to get it to instead return hidden files that we know about locally.
*/
export const getLocalFiles = async (type: "normal" | "hidden" = "normal") => {
const tableName = type === "normal" ? FILES_TABLE : HIDDEN_FILES_TABLE;
const files: Array<EnteFile> =
(await localForage.getItem<EnteFile[]>(tableName)) || [];
return files;
};
const setLocalFiles = async (type: "normal" | "hidden", files: EnteFile[]) => {
try {
const tableName = type === "normal" ? FILES_TABLE : HIDDEN_FILES_TABLE;
await localForage.setItem(tableName, files);
try {
eventBus.emit(Events.LOCAL_FILES_UPDATED);
} catch (e) {
log.error("Error in localFileUpdated handlers", e);
}
} catch (e1) {
try {
const storageEstimate = await navigator.storage.estimate();
log.error(
`failed to save files to indexedDB (storageEstimate was ${storageEstimate}`,
e1,
);
log.info(`storage estimate ${JSON.stringify(storageEstimate)}`);
} catch (e2) {
log.error("failed to save files to indexedDB", e1);
log.error("failed to get storage stats", e2);
}
throw e1;
}
};
export const syncFiles = async (
type: "normal" | "hidden",
collections: Collection[],

View File

@@ -1,9 +1,9 @@
import { FILE_TYPE } from "@/media/file-type";
import { EnteFile } from "@/new/photos/types/file";
import log from "@/next/log";
import { validateAndGetCreationUnixTimeInMicroSeconds } from "@ente/shared/time";
import type { FixOption } from "components/FixCreationTime";
import { detectFileTypeInfo } from "services/detect-type";
import { EnteFile } from "types/file";
import {
changeFileCreationTime,
updateExistingFilePubMetadata,

View File

@@ -1,9 +1,9 @@
import { EnteFile } from "@/new/photos/types/file";
import log from "@/next/log";
import { CustomError, parseUploadErrorCodes } from "@ente/shared/error";
import PQueue from "p-queue";
import { syncAndGetFilesToIndex } from "services/face/indexer";
import { FaceIndexerWorker } from "services/face/indexer.worker";
import { EnteFile } from "types/file";
const batchSize = 200;

View File

@@ -1,3 +1,4 @@
import { EncryptedEnteFile, EnteFile } from "@/new/photos/types/file";
import log from "@/next/log";
import { apiOrigin } from "@/next/origins";
import ComlinkCryptoWorker from "@ente/shared/crypto";
@@ -5,7 +6,6 @@ import { CustomError, parseSharingErrorCodes } from "@ente/shared/error";
import HTTPService from "@ente/shared/network/HTTPService";
import localForage from "@ente/shared/storage/localForage";
import { Collection, CollectionPublicMagicMetadata } from "types/collection";
import { EncryptedEnteFile, EnteFile } from "types/file";
import { LocalSavedPublicCollectionFiles } from "types/publicCollection";
import { decryptFile, mergeMetadata, sortFiles } from "utils/file";

View File

@@ -1,11 +1,11 @@
import { FILE_TYPE } from "@/media/file-type";
import { EnteFile } from "@/new/photos/types/file";
import log from "@/next/log";
import * as chrono from "chrono-node";
import { t } from "i18next";
import type { Person } from "services/face/people";
import { Collection } from "types/collection";
import { EntityType, LocationTag, LocationTagData } from "types/entity";
import { EnteFile } from "types/file";
import {
ClipSearchScores,
DateValue,

View File

@@ -1,10 +1,10 @@
import { EnteFile } from "@/new/photos/types/file";
import log from "@/next/log";
import { apiOrigin } from "@/next/origins";
import HTTPService from "@ente/shared/network/HTTPService";
import localForage from "@ente/shared/storage/localForage";
import { getToken } from "@ente/shared/storage/localStorage/helpers";
import { Collection } from "types/collection";
import { EnteFile } from "types/file";
import { SetFiles } from "types/gallery";
import { EncryptedTrashItem, Trash } from "types/trash";
import { decryptFile, mergeMetadata, sortTrashFiles } from "utils/file";

View File

@@ -1,8 +1,8 @@
import { EnteFile } from "@/new/photos/types/file";
import log from "@/next/log";
import { apiOrigin } from "@/next/origins";
import { CustomError, handleUploadError } from "@ente/shared/error";
import HTTPService from "@ente/shared/network/HTTPService";
import { EnteFile } from "types/file";
import { retryHTTPCall } from "./uploadHttpClient";
import { MultipartUploadURLs, UploadFile, UploadURL } from "./uploadService";

View File

@@ -1,10 +1,10 @@
import { EnteFile } from "@/new/photos/types/file";
import log from "@/next/log";
import { apiOrigin, uploaderOrigin } from "@/next/origins";
import { wait } from "@/utils/promise";
import { CustomError, handleUploadError } from "@ente/shared/error";
import HTTPService from "@ente/shared/network/HTTPService";
import { getToken } from "@ente/shared/storage/localStorage/helpers";
import { EnteFile } from "types/file";
import { MultipartUploadURLs, UploadFile, UploadURL } from "./uploadService";
const MAX_URL_REQUESTS = 50;

View File

@@ -1,5 +1,7 @@
import { FILE_TYPE } from "@/media/file-type";
import { potentialFileTypeFromExtension } from "@/media/live-photo";
import { getLocalFiles } from "@/new/photos/services/files";
import { EncryptedEnteFile, EnteFile } from "@/new/photos/types/file";
import { ensureElectron } from "@/next/electron";
import { lowercaseExtension, nameAndExtension } from "@/next/file";
import log from "@/next/log";
@@ -26,10 +28,8 @@ import {
import { getDisableCFUploadProxyFlag } from "services/userService";
import watcher from "services/watch";
import { Collection } from "types/collection";
import { EncryptedEnteFile, EnteFile } from "types/file";
import { SetFiles } from "types/gallery";
import { decryptFile, getUserOwnedFiles, sortFiles } from "utils/file";
import { getLocalFiles } from "../fileService";
import {
getMetadataJSONMapKeyForJSON,
tryParseTakeoutMetadataJSON,

View File

@@ -2,6 +2,15 @@ import { hasFileHash } from "@/media/file";
import { FILE_TYPE, type FileTypeInfo } from "@/media/file-type";
import { encodeLivePhoto } from "@/media/live-photo";
import type { Metadata } from "@/media/types/file";
import {
EnteFile,
MetadataFileAttributes,
S3FileAttributes,
type EncryptedEnteFile,
type FilePublicMagicMetadata,
type FilePublicMagicMetadataProps,
} from "@/new/photos/types/file";
import { EncryptedMagicMetadata } from "@/new/photos/types/magicMetadata";
import { ensureElectron } from "@/next/electron";
import { basename } from "@/next/file";
import log from "@/next/log";
@@ -24,15 +33,6 @@ import {
PublicUploadProps,
type LivePhotoAssets,
} from "services/upload/uploadManager";
import {
EnteFile,
MetadataFileAttributes,
S3FileAttributes,
type EncryptedEnteFile,
type FilePublicMagicMetadata,
type FilePublicMagicMetadataProps,
} from "types/file";
import { EncryptedMagicMetadata } from "types/magicMetadata";
import type { ParsedExtractedMetadata } from "types/metadata";
import {
getNonEmptyMagicMetadataProps,

View File

@@ -3,6 +3,8 @@
* watch folders functionality.
*/
import { getLocalFiles } from "@/new/photos/services/files";
import { EncryptedEnteFile } from "@/new/photos/types/file";
import { ensureElectron } from "@/next/electron";
import { basename, dirname } from "@/next/file";
import log from "@/next/log";
@@ -18,10 +20,8 @@ import uploadManager, {
type UploadItemWithCollection,
} from "services/upload/uploadManager";
import { Collection } from "types/collection";
import { EncryptedEnteFile } from "types/file";
import { groupFilesBasedOnCollectionID } from "utils/file";
import { removeFromCollection } from "./collectionService";
import { getLocalFiles } from "./fileService";
/**
* Watch for file system folders and automatically update the corresponding Ente

View File

@@ -1,11 +1,11 @@
import { CollectionSummaryType, CollectionType } from "constants/collection";
import { EnteFile } from "types/file";
import { EnteFile } from "@/new/photos/types/file";
import {
EncryptedMagicMetadata,
MagicMetadataCore,
SUB_TYPE,
VISIBILITY_STATE,
} from "types/magicMetadata";
} from "@/new/photos/types/magicMetadata";
import { CollectionSummaryType, CollectionType } from "constants/collection";
export enum COLLECTION_ROLE {
VIEWER = "VIEWER",

View File

@@ -1,5 +1,5 @@
import { EnteFile } from "@/new/photos/types/file";
import type { ExportStage } from "services/export";
import { EnteFile } from "types/file";
export interface ExportProgress {
success: number;

View File

@@ -1,9 +1,9 @@
import { EnteFile } from "@/new/photos/types/file";
import type { User } from "@ente/shared/user/types";
import { CollectionSelectorAttributes } from "components/Collections/CollectionSelector";
import { FilesDownloadProgressAttributes } from "components/FilesDownloadProgress";
import { TimeStampListItem } from "components/PhotoList";
import { Collection } from "types/collection";
import { EnteFile } from "types/file";
export type SelectedState = {
[k: number]: boolean;

View File

@@ -1,6 +1,6 @@
import { EnteFile } from "@/new/photos/types/file";
import { TimeStampListItem } from "components/PhotoList";
import { PublicURL } from "types/collection";
import { EnteFile } from "types/file";
export interface PublicCollectionGalleryContextType {
token: string;

View File

@@ -1,9 +1,9 @@
import { FILE_TYPE } from "@/media/file-type";
import { EnteFile } from "@/new/photos/types/file";
import type { FaceIndexingStatus } from "services/face/indexer";
import type { Person } from "services/face/people";
import { City } from "services/locationSearchService";
import { LocationTagData } from "types/entity";
import { EnteFile } from "types/file";
export enum SuggestionType {
DATE = "DATE",

View File

@@ -1,4 +1,4 @@
import { EncryptedEnteFile, EnteFile } from "types/file";
import { EncryptedEnteFile, EnteFile } from "@/new/photos/types/file";
export interface TrashItem extends Omit<EncryptedTrashItem, "file"> {
file: EnteFile;

View File

@@ -1,3 +1,6 @@
import { getAllLocalFiles, getLocalFiles } from "@/new/photos/services/files";
import { EnteFile } from "@/new/photos/types/file";
import { SUB_TYPE, VISIBILITY_STATE } from "@/new/photos/types/magicMetadata";
import { ensureElectron } from "@/next/electron";
import log from "@/next/log";
import { CustomError } from "@ente/shared/error";
@@ -30,7 +33,6 @@ import {
updatePublicCollectionMagicMetadata,
updateSharedCollectionMagicMetadata,
} from "services/collectionService";
import { getAllLocalFiles, getLocalFiles } from "services/fileService";
import {
COLLECTION_ROLE,
Collection,
@@ -38,9 +40,7 @@ import {
CollectionPublicMagicMetadataProps,
CollectionSummaries,
} from "types/collection";
import { EnteFile } from "types/file";
import { SetFilesDownloadProgressAttributes } from "types/gallery";
import { SUB_TYPE, VISIBILITY_STATE } from "types/magicMetadata";
import { downloadFilesWithProgress } from "utils/file";
import { isArchivedCollection, updateMagicMetadata } from "utils/magicMetadata";
import { safeDirectoryName } from "utils/native-fs";

View File

@@ -2,6 +2,16 @@ import { FILE_TYPE } from "@/media/file-type";
import { isNonWebImageFileExtension } from "@/media/formats";
import { heicToJPEG } from "@/media/heic-convert";
import { decodeLivePhoto } from "@/media/live-photo";
import {
EncryptedEnteFile,
EnteFile,
FileMagicMetadata,
FileMagicMetadataProps,
FilePublicMagicMetadata,
FilePublicMagicMetadataProps,
FileWithUpdatedMagicMetadata,
} from "@/new/photos/types/file";
import { VISIBILITY_STATE } from "@/new/photos/types/magicMetadata";
import { lowercaseExtension } from "@/next/file";
import log from "@/next/log";
import { CustomErrorMessage, type Electron } from "@/next/types/ipc";
@@ -23,21 +33,11 @@ import {
updateFileMagicMetadata,
updateFilePublicMagicMetadata,
} from "services/fileService";
import {
EncryptedEnteFile,
EnteFile,
FileMagicMetadata,
FileMagicMetadataProps,
FilePublicMagicMetadata,
FilePublicMagicMetadataProps,
FileWithUpdatedMagicMetadata,
} from "types/file";
import {
SelectedState,
SetFilesDownloadProgressAttributes,
SetFilesDownloadProgressAttributesCreator,
} from "types/gallery";
import { VISIBILITY_STATE } from "types/magicMetadata";
import { isArchivedFile, updateMagicMetadata } from "utils/magicMetadata";
import { safeFileName } from "utils/native-fs";
import { writeStream } from "utils/native-stream";

View File

@@ -1,7 +1,10 @@
import { EnteFile } from "@/new/photos/types/file";
import {
MagicMetadataCore,
VISIBILITY_STATE,
} from "@/new/photos/types/magicMetadata";
import ComlinkCryptoWorker from "@ente/shared/crypto";
import { Collection } from "types/collection";
import { EnteFile } from "types/file";
import { MagicMetadataCore, VISIBILITY_STATE } from "types/magicMetadata";
export function isArchivedFile(item: EnteFile): boolean {
if (!item || !item.magicMetadata || !item.magicMetadata.data) {

View File

@@ -1,7 +1,7 @@
import { FILE_TYPE } from "@/media/file-type";
import type { LivePhotoSourceURL, SourceURLs } from "@/new/photos/types/file";
import { EnteFile } from "@/new/photos/types/file";
import log from "@/next/log";
import { LivePhotoSourceURL, SourceURLs } from "services/download";
import { EnteFile } from "types/file";
import { SetSelectedState } from "types/gallery";
export async function playVideo(livePhotoVideo, livePhotoImage) {

View File

@@ -1,9 +1,9 @@
import { EnteFile } from "@/new/photos/types/file";
import * as Comlink from "comlink";
import {
isInsideCity,
isInsideLocationTag,
} from "services/locationSearchService";
import { EnteFile } from "types/file";
import { Search } from "types/search";
import { isSameDayAnyYear } from "utils/search";

View File

@@ -1,6 +1,6 @@
import { FILE_TYPE } from "@/media/file-type";
import { getLocalFiles } from "@/new/photos/services/files";
import { getLocalCollections } from "services/collectionService";
import { getLocalFiles } from "services/fileService";
import { tryToParseDateTime } from "services/upload/date";
import {
MAX_FILE_NAME_LENGTH_GOOGLE_EXPORT,

View File

@@ -22,7 +22,9 @@
"**/*.tsx",
"**/*.js",
"../../packages/shared/themes/mui-theme.d.ts",
"../../packages/next/global-electron.d.ts"
"../../packages/next/global-electron.d.ts",
"../../packages/new/photos/types/file.ts",
"../../packages/new/photos/types/magicMetadata.ts"
],
"exclude": ["node_modules", "out", ".next", "thirdparty"]
}

View File

@@ -1,7 +1,9 @@
import { authenticatedRequestHeaders } from "@/next/http";
import { apiOrigin } from "@/next/origins";
import { nullToUndefined } from "@/utils/transform";
// import ComlinkCryptoWorker from "@ente/shared/crypto";
import { z } from "zod";
// import { getAllLocalFiles } from "./files";
/**
* The embeddings that we (the current client) knows how to handle.
@@ -79,18 +81,24 @@ type RemoteEmbedding = z.infer<typeof RemoteEmbedding>;
*/
export const syncRemoteFaceEmbeddings = async () => {
let sinceTime = faceEmbeddingSyncTime();
// const cryptoWorker = await ComlinkCryptoWorker.getInstance();
// const files = await getAllLocalFiles();
// TODO: eslint has fixed this spurious warning, but we're not on the latest
// version yet, so add a disable.
// https://github.com/eslint/eslint/pull/18286
/* eslint-disable no-constant-condition */
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
while (true) {
const embeddings = await getEmbeddingsDiff(
const remoteEmbeddings = await getEmbeddingsDiff(
"file-ml-clip-face",
sinceTime,
);
if (embeddings.length == 0) break;
sinceTime = embeddings.reduce(
if (remoteEmbeddings.length == 0) break;
// const _embeddings = Promise.all(
// remoteEmbeddings.map(decryptFaceEmbedding),
// );
sinceTime = remoteEmbeddings.reduce(
(max, { updatedAt }) => Math.max(max, updatedAt),
sinceTime,
);
@@ -98,6 +106,22 @@ export const syncRemoteFaceEmbeddings = async () => {
}
};
// const decryptFaceEmbedding = async (remoteEmbedding: RemoteEmbedding) => {
// const fileKey = fileIdToKeyMap.get(embedding.fileID);
// if (!fileKey) {
// throw Error(CustomError.FILE_NOT_FOUND);
// }
// const decryptedData = await worker.decryptMetadata(
// embedding.encryptedEmbedding,
// embedding.decryptionHeader,
// fileIdToKeyMap.get(embedding.fileID),
// );
// return {
// ...decryptedData,
// updatedAt: embedding.updatedAt,
// } as unknown as FileML;
// };
/**
* The updatedAt of the most recent face {@link RemoteEmbedding} we've retrieved
* and saved from remote, or 0.

View File

@@ -0,0 +1,38 @@
import { type EnteFile } from "@/new/photos/types/file";
import log from "@/next/log";
import { Events, eventBus } from "@ente/shared/events";
import localForage from "@ente/shared/storage/localForage";
const FILES_TABLE = "files";
const HIDDEN_FILES_TABLE = "hidden-files";
/**
* Return all files that we know about locally, both "normal" and "hidden".
*/
export const getAllLocalFiles = async () =>
(await getLocalFiles("normal")).concat(await getLocalFiles("hidden"));
/**
* Return all files that we know about locally. By default it returns only
* "normal" (i.e. non-"hidden") files, but it can be passed the {@link type}
* "hidden" to get it to instead return hidden files that we know about locally.
*/
export const getLocalFiles = async (type: "normal" | "hidden" = "normal") => {
const tableName = type === "normal" ? FILES_TABLE : HIDDEN_FILES_TABLE;
const files: EnteFile[] =
(await localForage.getItem<EnteFile[]>(tableName)) ?? [];
return files;
};
export const setLocalFiles = async (
type: "normal" | "hidden",
files: EnteFile[],
) => {
const tableName = type === "normal" ? FILES_TABLE : HIDDEN_FILES_TABLE;
await localForage.setItem(tableName, files);
try {
eventBus.emit(Events.LOCAL_FILES_UPDATED);
} catch (e) {
log.error("Failed to save files", e);
}
};

View File

@@ -1,10 +1,9 @@
import type { Metadata } from "@/media/types/file";
import { SourceURLs } from "services/download";
import {
EncryptedMagicMetadata,
MagicMetadataCore,
VISIBILITY_STATE,
} from "types/magicMetadata";
type EncryptedMagicMetadata,
type MagicMetadataCore,
} from "./magicMetadata";
export interface MetadataFileAttributes {
encryptedData: string;
@@ -63,6 +62,33 @@ export interface EnteFile
isConverted?: boolean;
}
export interface LivePhotoSourceURL {
image: () => Promise<string>;
video: () => Promise<string>;
}
export interface LoadedLivePhotoSourceURL {
image: string;
video: string;
}
export interface SourceURLs {
url: string | LivePhotoSourceURL | LoadedLivePhotoSourceURL;
isOriginal: boolean;
isRenderable: boolean;
type: "normal" | "livePhoto";
/**
* Best effort attempt at obtaining the MIME type.
*
* Known cases where it is missing:
*
* - Live photos (these have a different code path for obtaining the URL).
* - A video that is passes the isPlayable test in the browser.
*
*/
mimeType?: string;
}
export interface TrashRequest {
items: TrashRequestItems[];
}