feat(server/web): Initial support for RAF and SRW RAW formats (#1414)

* feat(server/web): Initial support for RAF and SRW RAW formats.

* It should return the promise.

* Better comment

* feat(server/web): file-uploader needed changes.

* Remove un-used imports

* The failing test.. is no longer failing.

* Run prettier

* Original implementation with just a catch block added.

* feat(server): Some tests and specific handling for the two raw formats

* feat(web): Helper for raw image type.

* Handling of mimetype on server

* Handling of mimetypes on web with a map

* Bring back the acceptedfile filter

* Fix the asset-upload tests after changes

* acceptedFile is not usable due to type being empty from browser.

* Switch needs to use lowercase variants.

* Address Discord comments

* feat(mobile): Library page rework (album sorting, favorites) (#1501)

* Add album sorting

* Change AppBar to match photos page behaviour

* Add buttons

* First crude implementation of the favorites page

* Clean up

* Add favorite button

* i18n

* Add star indicator to thumbnail

* Add favorite logic to separate provider and fix favorite behavior in album

* Review feedback (Add isFavorite variable)

* dev: style buttons

* dev: styled drop down button

---------

Co-authored-by: Alex Tran <alex.tran1502@gmail.com>

* feat(mobile): Tap to enter immersive mode on gallery viewer (#1546)

* feat(mobile): Removed stay logged in checkbox and made it enabled by default (#1550)

* removed stay logged in checkbox and made it enabled by default

* adds padding to login button

* removed all isSaveLogin

* fix: logout would re-login with previous credential upon app restart

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>

* chore(server): remove token when logged out (#1560)

* chore(mobile): invoke logout() on mobile app

* feat: add mechanism to delete token from logging out endpoint

* fix: set state after login sequence success

* fix: not removing token when logging out from OAuth

* fix: prettier

* refactor: using accessTokenId to delete

* chore: pr comments

* fix: test

* fix: test threshold

* feat(deployment): support docker secrets (#1254)

* Support secrets

* Rewrite to support sh

* Remove JWT_SECRET

* fix(mobile): Added flutter native splash and splash screens (#1520)

* rebasing

* added launch background image to repository

---------

Co-authored-by: Marty Fuhry <marty@fuhry.farm>

* refactor(mobile): introduce Album & User classes (#1561)

replace usages of AlbumResponseDto with Album
replace usages of UserResponseDto with User

* feat(mobile): Multiselect add to favorite from the timeline (#1558)

* multiselect add to favorites

* feat(server): add updatedAt to Asset, Album and User (#1566)

* feat: add updatedAt info to DTO and generate api

* chore: remove unsued file

* chore: Add update statement to add/remove asset/user to album

* fix: test

* chore(server): update package-lock.json to match package.json (#1573)

* chore(server) Add user FK to album entity (#1569)

* chore(deps): bump docker/setup-buildx-action from 2.4.0 to 2.4.1 (#1575)

Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 2.4.0 to 2.4.1.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/v2.4.0...v2.4.1)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(server): make owner as required response for AlbumResponseDto (#1579)

* feat(GitHub): update bug and feature request template (#1584)

* dev: Reusing template from Home Assistant

* dev: add bug report template

* fix: template

* dev: change type

* dev:

* dev: add default labels

* dev: Add default title

* dev: add feature request template

* remove feature request from markdown

* dev: frontmatter

* fix(GitHub): feature request template

* fix(GitHub): feature request form has wrong type for textarea

* feat(mobile): Responsive layout improvements with a navigation rail and album grid (#1583)

* feat(proxy): Initial IPv6 support (#1577)

* fix(server): Create album response doesn't have owner property as required (#1704)

* feat(web): allow uploading more file types (#1570)

* feat(web): allow uploading more file types

* fix(web): make filename extension lowercase

* refactor(mobile): add Isar DB & Store class (#1574)

* refactor(mobile): add Isar DB & Store class

new Store: globally accessible key-value store like Hive (but based on Isar)

replace first few places of Hive usage with the new Store

* reduce max. DB size to prevent errors on older iOS devices

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>

* feat(mobile): Home screen customization options (#1563)

* Try staggered layout for home page

* Introduce setting for dynamic layout

* Fix some provider related bugs

* Make asset grouping configurable

* Add translation keys, refactor group title

* Rename enum values

* Fix enum names

* Reformat long if statement

* Fix timezone related bug

* Minor clean up

* Fix unit test

* Add second assets check back to home screen

* [Localizely] Translations update (#1707)

* fix(server): get shared link album info doesn't contain owner property (#1708)

* Version v1.46.0

* feat(server/web): file-uploader needed changes.

* Add raf and srw to the file names.

* Remember to add the extensions to fileSelector.

* Removed the getMimeType function on server as shouldn't be needed anymore.

* Revert "Removed the getMimeType function on server as shouldn't be needed anymore."

It is required still.

This reverts commit fc766dd0be.

* Should use proper mimetypes.

* fix linter

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Matthias Rupp <matthias.rupp@posteo.de>
Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
Co-authored-by: martyfuhry <martyfuhry@gmail.com>
Co-authored-by: James <jdm12989@gmail.com>
Co-authored-by: Marty Fuhry <marty@fuhry.farm>
Co-authored-by: Fynn Petersen-Frey <zoodyy@users.noreply.github.com>
Co-authored-by: Zack Pollard <zackpollard@ymail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com>
Co-authored-by: Immich Release Bot <bot@immich.app>
This commit is contained in:
Skyler Mäntysaari 2023-02-14 21:54:28 +02:00 committed by GitHub
parent 86b3bdb90b
commit 0d543bbb0a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 33 additions and 7 deletions

View File

@ -55,7 +55,7 @@ describe('assetUploadOption', () => {
});
it('should allow videos', async () => {
const file = { mimetype: 'image/mp4', originalname: 'test.mp4' } as any;
const file = { mimetype: 'video/mp4', originalname: 'test.mp4' } as any;
fileFilter(mock.userRequest, file, callback);
expect(callback).toHaveBeenCalledWith(null, true);
});
@ -66,6 +66,18 @@ describe('assetUploadOption', () => {
expect(callback).toHaveBeenCalledWith(null, true);
});
it('should allow .raf recognized', () => {
const file = { mimetype: 'image/x-fuji-raf', originalname: 'test.raf' } as any;
fileFilter(mock.userRequest, file, callback);
expect(callback).toHaveBeenCalledWith(null, true);
});
it('should allow .srw recognized', () => {
const file = { mimetype: 'image/x-samsung-srw', originalname: 'test.srw' } as any;
fileFilter(mock.userRequest, file, callback);
expect(callback).toHaveBeenCalledWith(null, true);
});
it('should not allow unknown types', async () => {
const file = { mimetype: 'application/html', originalname: 'test.html' } as any;
const callback = jest.fn();

View File

@ -10,8 +10,6 @@ import sanitize from 'sanitize-filename';
import { AuthUserDto } from '../decorators/auth-user.decorator';
import { patchFormData } from '../utils/path-form-data.util';
const logger = new Logger('AssetUploadConfig');
export interface ImmichFile extends Express.Multer.File {
/** sha1 hash of file */
checksum: Buffer;
@ -48,13 +46,15 @@ export function customStorage(): StorageEngine {
export const multerUtils = { fileFilter, filename, destination };
const logger = new Logger('AssetUploadConfig');
function fileFilter(req: Request, file: any, cb: any) {
if (!req.user || (req.user.isPublicUser && !req.user.isAllowUpload)) {
return cb(new UnauthorizedException());
}
if (
file.mimetype.match(
/\/(jpg|jpeg|png|gif|mp4|webm|x-msvideo|quicktime|heic|heif|dng|x-adobe-dng|webp|tiff|3gpp|nef|x-nikon-nef)$/,
/\/(jpg|jpeg|png|gif|mp4|webm|x-msvideo|quicktime|heic|heif|dng|x-adobe-dng|webp|tiff|3gpp|nef|x-nikon-nef|x-fuji-raf|x-samsung-srw)$/,
)
) {
cb(null, true);

View File

@ -14,6 +14,7 @@ import { Repository } from 'typeorm/repository/Repository';
import { join } from 'path';
import { CommunicationGateway } from 'apps/immich/src/api-v1/communication/communication.gateway';
import { IMachineLearningJob } from '@app/domain';
import { exiftool } from 'exiftool-vendored';
@Processor(QueueName.THUMBNAIL_GENERATION)
export class ThumbnailGeneratorProcessor {
@ -53,7 +54,15 @@ export class ThumbnailGeneratorProcessor {
.resize(1440, 1440, { fit: 'outside', withoutEnlargement: true })
.jpeg()
.rotate()
.toFile(jpegThumbnailPath);
.toFile(jpegThumbnailPath)
.catch(() => {
this.logger.warn(
'Failed to generate jpeg thumbnail for asset: ' +
asset.id +
' using sharp, failing over to exiftool-vendored',
);
return exiftool.extractThumbnail(asset.originalPath, jpegThumbnailPath);
});
await this.assetRepository.update({ id: asset.id }, { resizePath: jpegThumbnailPath });
} catch (error: any) {
this.logger.error('Failed to generate jpeg thumbnail for asset: ' + asset.id, error.stack);

View File

@ -141,7 +141,11 @@ export function getFileMimeType(file: File): string {
case '3gp':
return 'video/3gpp';
case 'nef':
return 'image/nef';
return 'image/x-nikon-nef';
case 'raf':
return 'image/x-fuji-raf';
case 'srw':
return 'image/x-samsung-srw';
default:
return '';
}

View File

@ -21,7 +21,7 @@ export const openFileUploadDialog = (
// When adding a content type that is unsupported by browsers, make sure
// to also add it to getFileMimeType() otherwise the upload will fail.
fileSelector.accept = 'image/*,video/*,.heic,.heif,.dng,.3gp,.nef';
fileSelector.accept = 'image/*,video/*,.heic,.heif,.dng,.3gp,.nef,.srw,.raf';
fileSelector.onchange = async (e: Event) => {
const target = e.target as HTMLInputElement;
@ -53,6 +53,7 @@ export const fileUploadHandler = async (
}, 2)
)
.subscribe();
const acceptedFile = files.filter((file) => {
const assetType = getFileMimeType(file).split('/')[0];
return assetType === 'video' || assetType === 'image';