feat(api): filter recent listens by timespan

This commit is contained in:
Julian Tölle 2020-05-09 16:28:57 +02:00
parent c545699f22
commit c9030937e2
5 changed files with 48 additions and 6 deletions

5
package-lock.json generated
View file

@ -3722,6 +3722,11 @@
"whatwg-url": "^7.0.0" "whatwg-url": "^7.0.0"
} }
}, },
"date-fns": {
"version": "2.13.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.13.0.tgz",
"integrity": "sha512-xm0c61mevGF7f0XpCGtDTGpzEFC/1fpLXHbmFpxZZQJuvByIK2ozm6cSYuU+nxFYOPh2EuCfzUwlTEFwKG+h5w=="
},
"debug": { "debug": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",

View file

@ -37,6 +37,7 @@
"@nestjs/typeorm": "^7.0.0", "@nestjs/typeorm": "^7.0.0",
"class-transformer": "^0.2.3", "class-transformer": "^0.2.3",
"class-validator": "^0.12.2", "class-validator": "^0.12.2",
"date-fns": "^2.13.0",
"nestjs-typeorm-paginate": "^2.0.3", "nestjs-typeorm-paginate": "^2.0.3",
"passport": "^0.4.1", "passport": "^0.4.1",
"passport-jwt": "^4.0.0", "passport-jwt": "^4.0.0",

View file

@ -1,5 +1,26 @@
import { IsOptional, ValidateNested, IsISO8601 } from "class-validator";
import { User } from "src/users/user.entity"; import { User } from "src/users/user.entity";
export interface GetListensDto { // tslint:disable-next-line: max-classes-per-file
user: User; export class GetListensFilterTimeDto {
@IsISO8601()
start: string;
@IsISO8601()
end: string;
}
// tslint:disable-next-line: max-classes-per-file
export class GetListensFilterDto {
@IsOptional()
@ValidateNested()
time?: GetListensFilterTimeDto;
}
// tslint:disable-next-line: max-classes-per-file
export class GetListensDto {
user: User;
@IsOptional()
@ValidateNested()
filter?: GetListensFilterDto;
} }

View file

@ -3,6 +3,7 @@ import { Pagination } from "nestjs-typeorm-paginate";
import { Auth } from "../auth/decorators/auth.decorator"; import { Auth } from "../auth/decorators/auth.decorator";
import { ReqUser } from "../auth/decorators/req-user.decorator"; import { ReqUser } from "../auth/decorators/req-user.decorator";
import { User } from "../users/user.entity"; import { User } from "../users/user.entity";
import { GetListensFilterDto } from "./dto/get-listens.dto";
import { Listen } from "./listen.entity"; import { Listen } from "./listen.entity";
import { ListensService } from "./listens.service"; import { ListensService } from "./listens.service";
@ -15,10 +16,11 @@ export class ListensController {
async getRecentlyPlayed( async getRecentlyPlayed(
@Query("page") page: number = 1, @Query("page") page: number = 1,
@Query("limit") limit: number = 10, @Query("limit") limit: number = 10,
@Query("filter") filter: GetListensFilterDto,
@ReqUser() user: User @ReqUser() user: User
): Promise<Pagination<Listen>> { ): Promise<Pagination<Listen>> {
limit = limit > 100 ? 100 : limit; limit = limit > 100 ? 100 : limit;
return this.listensService.getListens({ page, limit, user }); return this.listensService.getListens({ page, limit, user, filter });
} }
} }

View file

@ -1,13 +1,14 @@
import { Injectable } from "@nestjs/common"; import { Injectable } from "@nestjs/common";
import { getTime, parseISO, getUnixTime } from "date-fns";
import { import {
IPaginationOptions, IPaginationOptions,
paginate, paginate,
Pagination, Pagination,
} from "nestjs-typeorm-paginate"; } from "nestjs-typeorm-paginate";
import { CreateListenDto } from "./dto/create-listen.dto"; import { CreateListenDto } from "./dto/create-listen.dto";
import { GetListensDto } from "./dto/get-listens.dto";
import { Listen } from "./listen.entity"; import { Listen } from "./listen.entity";
import { ListenRepository } from "./listen.repository"; import { ListenRepository } from "./listen.repository";
import { GetListensDto } from "./dto/get-listens.dto";
@Injectable() @Injectable()
export class ListensService { export class ListensService {
@ -42,9 +43,9 @@ export class ListensService {
async getListens( async getListens(
options: GetListensDto & IPaginationOptions options: GetListensDto & IPaginationOptions
): Promise<Pagination<Listen>> { ): Promise<Pagination<Listen>> {
const { page, limit, user } = options; const { page, limit, user, filter } = options;
const queryBuilder = this.listenRepository let queryBuilder = this.listenRepository
.createQueryBuilder("l") .createQueryBuilder("l")
.leftJoin("l.user", "user") .leftJoin("l.user", "user")
.where("user.id = :userID", { userID: user.id }) .where("user.id = :userID", { userID: user.id })
@ -54,6 +55,18 @@ export class ListensService {
.leftJoinAndSelect("album.artists", "albumArtists") .leftJoinAndSelect("album.artists", "albumArtists")
.orderBy("l.playedAt", "DESC"); .orderBy("l.playedAt", "DESC");
if (filter) {
if (filter.time) {
queryBuilder = queryBuilder.andWhere(
"l.playedAt BETWEEN :timeStart AND :timeEnd",
{
timeStart: parseISO(filter.time.start),
timeEnd: parseISO(filter.time.end),
}
);
}
}
return paginate<Listen>(queryBuilder, { return paginate<Listen>(queryBuilder, {
page, page,
limit, limit,