1
0
mirror of https://github.com/bpatrik/pigallery2.git synced 2024-12-21 01:22:08 +02:00

Merge pull request #902 from grasdk/bugfix/offset-or-ignore

Bugfix/offset or ignore
This commit is contained in:
Patrik J. Braun 2024-05-28 23:23:38 +02:00 committed by GitHub
commit 072f65a3d9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 160 additions and 71 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

View File

@ -364,7 +364,11 @@ export class SearchManager {
for (const sort of sortings) {
switch (sort.method) {
case SortByTypes.Date:
query.addOrderBy('media.metadata.creationDate', sort.ascending ? 'ASC' : 'DESC'); //If media.metadata.creationDateOffset is defined, it is an offset of minutes (+/-). If taken into account, it will alter the sort order. Probably should not be done.
if (Config.Gallery.ignoreTimestampOffset === true) {
query.addOrderBy('media.metadata.creationDate + (media.metadata.creationDateOffset * 60000)', sort.ascending ? 'ASC' : 'DESC');
} else {
query.addOrderBy('media.metadata.creationDate', sort.ascending ? 'ASC' : 'DESC');
}
break;
case SortByTypes.Rating:
query.addOrderBy('media.metadata.rating', sort.ascending ? 'ASC' : 'DESC');
@ -562,15 +566,17 @@ export class SearchManager {
const textParam: { [key: string]: unknown } = {};
textParam['from' + queryId] = (query as FromDateSearch).value;
q.where(
`media.metadata.creationDate ${relation} :from${queryId}`, //TODO: If media.metadata.creationDateOffset is defined, it is an offset of minutes (+/-).
//Example: -600 means in the database UTC-10:00. The time 20:00 in the evening in the UTC-10 timezone, is actually 06:00 the next morning
//in UTC+00:00. To make search take that into account, one can subtract the offset from the creationDate to "pretend" the photo is taken
//in UTC time. Subtracting -600 minutes (because it's the -10:00 timezone), corresponds to adding 10 hours to the photo's timestamp, thus
//bringing it into the next day as if it was taken at UTC+00:00. Similarly subtracting a positive timezone from a timestamp will "pretend"
//the photo is taken earlier in time (e.g. subtracting 300 from the UTC+05:00 timezone).
textParam
);
if (Config.Gallery.ignoreTimestampOffset === true) {
q.where(
`(media.metadata.creationDate + (media.metadata.creationDateOffset * 60000)) ${relation} :from${queryId}`,
textParam
);
} else {
q.where(
`media.metadata.creationDate ${relation} :from${queryId}`,
textParam
);
}
return q;
});
@ -589,10 +595,18 @@ export class SearchManager {
const textParam: { [key: string]: unknown } = {};
textParam['to' + queryId] = (query as ToDateSearch).value;
q.where(
`media.metadata.creationDate ${relation} :to${queryId}`, //TODO: If media.metadata.creationDateOffset is defined, it is an offset of minutes (+/-). See explanation above.
textParam
);
if (Config.Gallery.ignoreTimestampOffset === true) {
q.where(
`(media.metadata.creationDate + (media.metadata.creationDateOffset * 60000)) ${relation} :to${queryId}`,
textParam
);
} else {
q.where(
`media.metadata.creationDate ${relation} :to${queryId}`,
textParam
);
}
return q;
});
@ -793,18 +807,34 @@ export class SearchManager {
textParam['to' + queryId] = to.getTime();
textParam['from' + queryId] = from.getTime();
if (tq.negate) {
if (Config.Gallery.ignoreTimestampOffset === true) {
q.where(
`(media.metadata.creationDate + (media.metadata.creationDateOffset * 60000)) >= :to${queryId}`,
textParam
).orWhere(`(media.metadata.creationDate + (media.metadata.creationDateOffset * 60000)) < :from${queryId}`,
textParam);
} else {
q.where(
`media.metadata.creationDate >= :to${queryId}`,
textParam
).orWhere(`media.metadata.creationDate < :from${queryId}`,
textParam);
q.where(
`media.metadata.creationDate >= :to${queryId}`, //TODO: If media.metadata.creationDateOffset is defined, it is an offset of minutes (+/-). See explanation above.
textParam
).orWhere(`media.metadata.creationDate < :from${queryId}`, //TODO: If media.metadata.creationDateOffset is defined, it is an offset of minutes (+/-). See explanation above.
textParam);
}
} else {
q.where(
`media.metadata.creationDate < :to${queryId}`, //TODO: If media.metadata.creationDateOffset is defined, it is an offset of minutes (+/-). See explanation above.
textParam
).andWhere(`media.metadata.creationDate >= :from${queryId}`, //TODO: If media.metadata.creationDateOffset is defined, it is an offset of minutes (+/-). See explanation above.
textParam);
if (Config.Gallery.ignoreTimestampOffset === true) {
q.where(
`(media.metadata.creationDate + (media.metadata.creationDateOffset * 60000)) < :to${queryId}`,
textParam
).andWhere(`(media.metadata.creationDate + (media.metadata.creationDateOffset * 60000)) >= :from${queryId}`,
textParam);
} else {
q.where(
`media.metadata.creationDate < :to${queryId}`,
textParam
).andWhere(`media.metadata.creationDate >= :from${queryId}`,
textParam);
}
}
} else {
@ -825,29 +855,51 @@ export class SearchManager {
if (Config.Database.type === DatabaseType.sqlite) {
if (tq.daysLength == 0) {
q.where(
//TODO: If media.metadata.creationDateOffset is defined, it is an offset of minutes (+/-). See explanation above.
`CAST(strftime('${duration}',media.metadataCreationDate/1000, 'unixepoch') AS INTEGER) ${relationEql} CAST(strftime('${duration}','now') AS INTEGER)`
);
if (Config.Gallery.ignoreTimestampOffset === true) {
q.where(
`CAST(strftime('${duration}',(media.metadataCreationDate + (media.metadataCreationDateOffset * 60000))/1000, 'unixepoch') AS INTEGER) ${relationEql} CAST(strftime('${duration}','now') AS INTEGER)`
);
} else {
q.where(
`CAST(strftime('${duration}',media.metadataCreationDate/1000, 'unixepoch') AS INTEGER) ${relationEql} CAST(strftime('${duration}','now') AS INTEGER)`
);
}
} else {
q.where(
//TODO: If media.metadata.creationDateOffset is defined, it is an offset of minutes (+/-). See explanation above.
`CAST(strftime('${duration}',media.metadataCreationDate/1000, 'unixepoch') AS INTEGER) ${relationTop} CAST(strftime('${duration}','now') AS INTEGER)`
)[whereFN](`CAST(strftime('${duration}',media.metadataCreationDate/1000, 'unixepoch') AS INTEGER) ${relationBottom} CAST(strftime('${duration}','now','-:diff${queryId} day') AS INTEGER)`,
textParam);
if (Config.Gallery.ignoreTimestampOffset === true) {
q.where(
`CAST(strftime('${duration}',(media.metadataCreationDate + (media.metadataCreationDateOffset * 60000))/1000, 'unixepoch') AS INTEGER) ${relationTop} CAST(strftime('${duration}','now') AS INTEGER)`
)[whereFN](`CAST(strftime('${duration}',(media.metadataCreationDate + (media.metadataCreationDateOffset * 60000))/1000, 'unixepoch') AS INTEGER) ${relationBottom} CAST(strftime('${duration}','now','-:diff${queryId} day') AS INTEGER)`,
textParam);
} else {
q.where(
`CAST(strftime('${duration}',media.metadataCreationDate/1000, 'unixepoch') AS INTEGER) ${relationTop} CAST(strftime('${duration}','now') AS INTEGER)`
)[whereFN](`CAST(strftime('${duration}',media.metadataCreationDate/1000, 'unixepoch') AS INTEGER) ${relationBottom} CAST(strftime('${duration}','now','-:diff${queryId} day') AS INTEGER)`,
textParam);
}
}
} else {
if (tq.daysLength == 0) {
q.where(
//TODO: If media.metadata.creationDateOffset is defined, it is an offset of minutes (+/-). See explanation above.
`CAST(FROM_UNIXTIME(media.metadataCreationDate/1000, '${duration}') AS SIGNED) ${relationEql} CAST(DATE_FORMAT(CURDATE(),'${duration}') AS SIGNED)`
);
if (Config.Gallery.ignoreTimestampOffset === true) {
q.where(
`CAST(FROM_UNIXTIME((media.metadataCreationDate + (media.metadataCreationDateOffset * 60000))/1000, '${duration}') AS SIGNED) ${relationEql} CAST(DATE_FORMAT(CURDATE(),'${duration}') AS SIGNED)`
);
} else {
q.where(
`CAST(FROM_UNIXTIME(media.metadataCreationDate/1000, '${duration}') AS SIGNED) ${relationEql} CAST(DATE_FORMAT(CURDATE(),'${duration}') AS SIGNED)`
);
}
} else {
q.where(
//TODO: If media.metadata.creationDateOffset is defined, it is an offset of minutes (+/-). See explanation above.
`CAST(FROM_UNIXTIME(media.metadataCreationDate/1000, '${duration}') AS SIGNED) ${relationTop} CAST(DATE_FORMAT(CURDATE(),'${duration}') AS SIGNED)`
)[whereFN](`CAST(FROM_UNIXTIME(media.metadataCreationDate/1000, '${duration}') AS SIGNED) ${relationBottom} CAST(DATE_FORMAT((DATE_ADD(curdate(), INTERVAL -:diff${queryId} DAY)),'${duration}') AS SIGNED)`,
textParam);
if (Config.Gallery.ignoreTimestampOffset === true) {
q.where(
`CAST(FROM_UNIXTIME((media.metadataCreationDate + (media.metadataCreationDateOffset * 60000))/1000, '${duration}') AS SIGNED) ${relationTop} CAST(DATE_FORMAT(CURDATE(),'${duration}') AS SIGNED)`
)[whereFN](`CAST(FROM_UNIXTIME((media.metadataCreationDate + (media.metadataCreationDateOffset * 60000))/1000, '${duration}') AS SIGNED) ${relationBottom} CAST(DATE_FORMAT((DATE_ADD(curdate(), INTERVAL -:diff${queryId} DAY)),'${duration}') AS SIGNED)`,
textParam);
} else {
q.where(
`CAST(FROM_UNIXTIME(media.metadataCreationDate/1000, '${duration}') AS SIGNED) ${relationTop} CAST(DATE_FORMAT(CURDATE(),'${duration}') AS SIGNED)`
)[whereFN](`CAST(FROM_UNIXTIME(media.metadataCreationDate/1000, '${duration}') AS SIGNED) ${relationBottom} CAST(DATE_FORMAT((DATE_ADD(curdate(), INTERVAL -:diff${queryId} DAY)),'${duration}') AS SIGNED)`,
textParam);
}
}
}
};

View File

@ -277,8 +277,8 @@ export class DiskManager {
directory.oldestMedia = Number.MIN_SAFE_INTEGER;
directory.media.forEach((m) => {
directory.youngestMedia = Math.min(m.metadata.creationDate, directory.youngestMedia);
directory.oldestMedia = Math.max(m.metadata.creationDate, directory.oldestMedia);
directory.youngestMedia = Math.min(Utils.getTimeMS(m.metadata.creationDate, m.metadata.creationDateOffset, Config.Gallery.ignoreTimestampOffset), directory.youngestMedia);
directory.oldestMedia = Math.max(Utils.getTimeMS(m.metadata.creationDate, m.metadata.creationDateOffset, Config.Gallery.ignoreTimestampOffset), directory.oldestMedia);
}
);

View File

@ -70,7 +70,7 @@ export class EmailMessenger extends Messenger<{
(media[i].metadata as PhotoMetadata).positionData?.country :
((media[i].metadata as PhotoMetadata).positionData?.city ?
(media[i].metadata as PhotoMetadata).positionData?.city : '');
const caption = Utils.getFullYear(media[i].metadata.creationDate, media[i].metadata.creationDateOffset) + (location ? ', ' + location : '');
const caption = Utils.getFullYear(Utils.getTimeMS(media[i].metadata.creationDate, media[i].metadata.creationDateOffset, Config.Gallery.ignoreTimestampOffset), undefined) + (location ? ', ' + location : '');
attachments.push({
filename: media[i].name,
path: media[i].thumbnailPath,

View File

@ -123,10 +123,11 @@ export class Utils {
}
}
static makeUTCMidnight(d: number | Date) {
static makeUTCMidnight(d: number | Date, offset: string) {
if (!(d instanceof Date)) {
d = new Date(d);
}
d = new Date(new Date(d).toISOString().substring(0,19) + (offset ? offset : '+00:00'))
d.setUTCHours(0);
d.setUTCMinutes(0);
d.setUTCSeconds(0);
@ -139,7 +140,7 @@ export class Utils {
if (!(d instanceof Date)) {
d = new Date(d);
}
return new Date(new Date(d).toISOString().substring(0,19) + (offset ? offset : '')).getUTCFullYear();
return new Date(new Date(d).toISOString().substring(0,19) + (offset ? offset : '+00:00')).getUTCFullYear();
}
static getFullYear(d: number | Date, offset: string) {
@ -225,10 +226,21 @@ export class Utils {
}
}
static getLocalTimeMS(creationDate: number, creationDateOffset: string) {
//Get the MS of the creationDate, adjusted for the offset. Effectively getting the MS value as if the photo did not contain an offset.
//One can consider this "Local" time of the photo. Starting point is UTC, as MetadataLoader loads timestamps with unknown timestamps as UTC.
static getLocalTimeMS(creationDate: number, creationDateOffset: string) {
const offsetMinutes = Utils.getOffsetMinutes(creationDateOffset);
return creationDate + (offsetMinutes ? (offsetMinutes * 60000) : 0);
}
//Like getLocalTimeMS, but only if localTime is true, otherwise just returns creationDate (global time)
static getTimeMS(creationDate: number, creationDateOffset: string, localTime: boolean) {
if (localTime) {
return Utils.getLocalTimeMS(creationDate, creationDateOffset);
} else {
return creationDate;
}
}
static isLeapYear(year: number) {
return (0 == year % 4) && (0 != year % 100) || (0 == year % 400)

View File

@ -1082,6 +1082,18 @@ export class ClientGalleryConfig {
})
enableDirectorySortingByDate: boolean = false;
@ConfigProperty({
tags: {
name: $localize`Ignore timestamp offsets`,
priority: ConfigPriority.advanced,
},
description: $localize`If enabled, timestamp offsets are ignored, meaning that the local times of pictures are used for searching, sorting and grouping. If disabled, global time is used and pictures with no timestamp are assumed to be in UTC (offset +00:00).`
})
//DEVELOPER NOTE: The Database model stores the timestamp (creationDate) as milliseconds since 1970-01-01 UTC (global time). And stores and offset (creationDateOffset) as minutes.
//Ignoring timestamp for the user is the opposite for the database. If the user wants to ignore the offset, we have to add the offset to the creationDate to give the user the right experience.
ignoreTimestampOffset: boolean = true;
@ConfigProperty({
tags: {
name: $localize`On scroll thumbnail prioritising`,

View File

@ -6,6 +6,7 @@ import {ContentService} from '../content.service';
import {mergeMap, Observable, shareReplay} from 'rxjs';
import {MDFilesFilterPipe} from '../../../pipes/MDFilesFilterPipe';
import {MDFileDTO} from '../../../../../common/entities/MDFileDTO';
import {Config} from '../../../../../common/config/public/Config';
@Injectable()
export class BlogService {
@ -28,7 +29,7 @@ export class BlogService {
let firstMedia = Number.MAX_SAFE_INTEGER;
if (content.mediaGroups.length > 0) {
firstMedia = content.mediaGroups[0].media.reduce((p, m) =>
Math.min(m.metadata.creationDate, p), Number.MAX_SAFE_INTEGER);
Math.min(Utils.getTimeMS(m.metadata.creationDate, m.metadata.creationDateOffset, Config.Gallery.ignoreTimestampOffset), p), Number.MAX_SAFE_INTEGER);
}
const files = this.mdFilesFilterPipe.transform(content.metaFile)
@ -65,7 +66,7 @@ export class BlogService {
const getDateGroup = (date: Date) => {
// get UTC midnight date
const dateNum = Utils.makeUTCMidnight(date).getTime();
const dateNum = Utils.makeUTCMidnight(date, undefined).getTime();
let groupDate = dates.find((d, i) => i > dates.length - 1 ? false : dates[i + 1] > dateNum); //dates are sorted
// cant find the date. put to the last group (as it was later)

View File

@ -3,6 +3,8 @@ import {BehaviorSubject, Observable} from 'rxjs';
import {PhotoDTO} from '../../../../../common/entities/PhotoDTO';
import {DirectoryContent} from '../contentLoader.service';
import {map, switchMap} from 'rxjs/operators';
import {Config} from '../../../../../common/config/public/Config';
import {Utils} from '../../../../../common/Utils';
export enum FilterRenderType {
enum = 1,
@ -159,11 +161,11 @@ export class FilterService {
}
const ret: { date: Date, endDate: Date, dateStr: string, count: number, max: number }[] = [];
const minDate = prefiltered.media.reduce(
(p, curr) => Math.min(p, curr.metadata.creationDate),
(p, curr) => Math.min(p, Utils.getTimeMS(curr.metadata.creationDate, curr.metadata.creationDateOffset, Config.Gallery.ignoreTimestampOffset)),
Number.MAX_VALUE - 1
);
const maxDate = prefiltered.media.reduce(
(p, curr) => Math.max(p, curr.metadata.creationDate),
(p, curr) => Math.max(p, Utils.getTimeMS(curr.metadata.creationDate, curr.metadata.creationDateOffset, Config.Gallery.ignoreTimestampOffset)),
Number.MIN_VALUE + 1
);
const diff = (maxDate - minDate) / 1000;
@ -205,7 +207,7 @@ export class FilterService {
const startMediaDate = new Date(floorDate(minDate));
prefiltered.media.forEach(m => {
const key = Math.floor((floorDate(m.metadata.creationDate) - startMediaDate.getTime()) / 1000 / usedDiv); //TODO
const key = Math.floor((floorDate(Utils.getTimeMS(m.metadata.creationDate, m.metadata.creationDateOffset, Config.Gallery.ignoreTimestampOffset)) - startMediaDate.getTime()) / 1000 / usedDiv);
const getDate = (index: number) => {
let d: Date;
@ -273,16 +275,16 @@ export class FilterService {
if (c.media.length > 0) {
// Update date filter range
afilters.dateFilter.minDate = c.media.reduce(
(p, curr) => Math.min(p, curr.metadata.creationDate),
(p, curr) => Math.min(p, Utils.getTimeMS(curr.metadata.creationDate, curr.metadata.creationDateOffset, Config.Gallery.ignoreTimestampOffset)),
Number.MAX_VALUE - 1
);
afilters.dateFilter.maxDate = c.media.reduce(
(p, curr) => Math.max(p, curr.metadata.creationDate),
(p, curr) => Math.max(p, Utils.getTimeMS(curr.metadata.creationDate, curr.metadata.creationDateOffset, Config.Gallery.ignoreTimestampOffset)),
Number.MIN_VALUE + 1
);
// Add a few sec padding
afilters.dateFilter.minDate -= (afilters.dateFilter.minDate % 1000) + 1000;
afilters.dateFilter.maxDate += (afilters.dateFilter.maxDate % 1000) + 1000;
afilters.dateFilter.minDate -= ((afilters.dateFilter.minDate % 1000) + 1000);
afilters.dateFilter.maxDate += ((1000 - (afilters.dateFilter.maxDate % 1000)) + 1000);
if (afilters.dateFilter.minFilter === Number.MIN_VALUE) {
afilters.dateFilter.minFilter = afilters.dateFilter.minDate;
@ -294,8 +296,8 @@ export class FilterService {
// Apply Date filter
c.media = c.media.filter(
(m) =>
m.metadata.creationDate >= afilters.dateFilter.minFilter &&
m.metadata.creationDate <= afilters.dateFilter.maxFilter
Utils.getTimeMS(m.metadata.creationDate, m.metadata.creationDateOffset, Config.Gallery.ignoreTimestampOffset) >= afilters.dateFilter.minFilter &&
Utils.getTimeMS(m.metadata.creationDate, m.metadata.creationDateOffset, Config.Gallery.ignoreTimestampOffset) <= afilters.dateFilter.maxFilter
);
} else {
afilters.dateFilter.minDate = Number.MIN_VALUE;
@ -398,5 +400,3 @@ export class FilterService {
}
}
}

View File

@ -508,7 +508,7 @@ export class ControlsLightboxComponent implements OnDestroy, OnInit, OnChanges {
case LightBoxTitleTexts.persons:
return m.metadata.faces?.map(f => f.name)?.join(', ');
case LightBoxTitleTexts.date:
return this.datePipe.transform(m.metadata.creationDate, 'longDate', m.metadata.creationDateOffset);
return this.datePipe.transform(Utils.getTimeMS(m.metadata.creationDate, m.metadata.creationDateOffset, Config.Gallery.ignoreTimestampOffset) , 'longDate', 'UTC');
case LightBoxTitleTexts.location:
if (!m.metadata.positionData) {
return '';

View File

@ -148,7 +148,7 @@ export class InfoPanelLightboxComponent implements OnInit, OnChanges {
isThisYear(): boolean {
return (
new Date().getFullYear() ===
Utils.getUTCFullYear(this.media.metadata.creationDate, this.media.metadata.creationDateOffset)
Utils.getUTCFullYear(this.media.metadata.creationDate, this.media.metadata.creationDateOffset)
);
}
@ -202,4 +202,3 @@ export class InfoPanelLightboxComponent implements OnInit, OnChanges {
} as TextSearch);
}
}

View File

@ -150,7 +150,7 @@ export class GallerySortingService {
break;
case SortByTypes.Date:
media.sort((a: PhotoDTO, b: PhotoDTO): number => {
return a.metadata.creationDate - b.metadata.creationDate;
return Utils.getTimeMS(a.metadata.creationDate, a.metadata.creationDateOffset, Config.Gallery.ignoreTimestampOffset) - Utils.getTimeMS(b.metadata.creationDate, b.metadata.creationDateOffset, Config.Gallery.ignoreTimestampOffset);
});
break;
case SortByTypes.Rating:
@ -196,7 +196,13 @@ export class GallerySortingService {
private getGroupByNameFn(grouping: GroupingMethod) {
switch (grouping.method) {
case SortByTypes.Date:
return (m: MediaDTO) => this.datePipe.transform(m.metadata.creationDate, 'longDate', m.metadata.creationDateOffset ? m.metadata.creationDateOffset : 'UTC');
if (Config.Gallery.ignoreTimestampOffset === true) {
//Datepipe used this way, converts creationDate to date in local time.
return (m: MediaDTO) => this.datePipe.transform(m.metadata.creationDate, 'longDate', m.metadata.creationDateOffset ? m.metadata.creationDateOffset : 'UTC');
} else {
//Grouping with global time, requires a common timeframe.
return (m: MediaDTO) => this.datePipe.transform(m.metadata.creationDate, 'longDate', 'UTC');
}
case SortByTypes.Name:
return (m: MediaDTO) => m.name.at(0).toUpperCase();
@ -308,7 +314,7 @@ export class GallerySortingService {
if (grouping.method === GroupByTypes.Date) {
// We do not need the youngest as we group by day. All photos are from the same day
c.mediaGroups.forEach(g => {
g.date = Utils.makeUTCMidnight(new Date(g.media?.[0]?.metadata?.creationDate));
g.date = Utils.makeUTCMidnight(new Date(g.media?.[0]?.metadata?.creationDate), g.media?.[0]?.metadata?.creationDateOffset);
});
}
@ -338,5 +344,3 @@ export interface GroupedDirectoryContent {
mediaGroups: MediaGroup[];
metaFile: FileDTO[];
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

View File

@ -0,0 +1,8 @@
{
"creationDate": 1713040680000,
"fileSize": 71525,
"size": {
"height": 1080,
"width": 1920
}
}

View File

@ -173,7 +173,7 @@ describe('Typeorm integration', () => {
const photos = await pr
.createQueryBuilder('media')
.orderBy('media.metadata.creationDate', 'ASC')
.orderBy('media.metadata.creationDate', 'ASC') //TODO: Offset: Create a test where it is ".orderBy('media.metadata.creationDate + (media.metadata.creationDateOffset * 60000)', 'ASC')" instead
.where('media.metadata.positionData.city LIKE :text COLLATE utf8_general_ci', {text: '%' + photo.metadata.positionData.city + '%'})
.innerJoinAndSelect('media.directory', 'directory')
.limit(10)
@ -195,7 +195,7 @@ describe('Typeorm integration', () => {
await pr.save(photo);
const photos = await pr
.createQueryBuilder('media')
.orderBy('media.metadata.creationDate', 'ASC')
.orderBy('media.metadata.creationDate', 'ASC') //TODO: Offset: Create a test where it is ".orderBy('media.metadata.creationDate + (media.metadata.creationDateOffset * 60000)', 'ASC')" instead
.where('media.metadata.positionData.city LIKE :text COLLATE utf8_general_ci', {text: '%' + city + '%'})
.innerJoinAndSelect('media.directory', 'directory')
.limit(10)

View File

@ -128,6 +128,7 @@ describe('CoverManager', (sqlHelper: DBTestHelper) => {
before(async () => {
await setUpSqlDB();
Config.Gallery.ignoreTimestampOffset = false;
});