HEX
Server: nginx/1.24.0
System: Linux nowruzgan 6.8.0-57-generic #59-Ubuntu SMP PREEMPT_DYNAMIC Sat Mar 15 17:40:59 UTC 2025 x86_64
User: babak (1000)
PHP: 8.3.6
Disabled: NONE
Upload Files
File: //var/dev/shahnamag/back-end/src/verse/verse.controller.ts
import { Controller, Get, Post, Body, Patch, Param, Delete, Query, HttpException, HttpStatus, Put } from '@nestjs/common';
import { VerseService } from './verse.service';
import { CreateVerseDto } from './dto/create-verse.dto';
import { UpdateVerseDto } from './dto/update-verse.dto';
import { Public } from '../user/auth.guard';
import { UpdateVerseKeywordDto } from './dto/update-verse-keyword.dto';
import { VerseKeywordService } from './verse-keyword.service';
import { VersePersonService } from './verse-person.service';
import { KeywordService } from '../keyword/keyword.service';
import { Between, LessThanOrEqual, MoreThanOrEqual } from 'typeorm';
import { PersonService } from '../person/person.service';
import { CreateVersePersonDto } from './dto/create-verse-person.dto';

@Controller('verse')
export class VerseController {
  constructor(
    private readonly keywordService: KeywordService,
    private readonly verseService: VerseService,
    private readonly personService: PersonService,
    private readonly verseKeywordService: VerseKeywordService,
    private readonly versePersonService: VersePersonService
  ) {}

  @Post()
  create(@Body() createVerseDto: CreateVerseDto) {
    return this.verseService.create(createVerseDto);
  }

  @Get()
  @Public()
  async findAll(
    @Query('page') page: number,
    @Query('size') size: number,
    @Query('fromVerse') fromVerse: number,
    @Query('toVerse') toVerse: number,
    @Query('keyword') keywordId: number,
    @Query('person') personId: number,
    @Query('onlyPublished') onlyPublished: number,
    ) {

    if(keywordId) return this.findAllByKeyword(page, size, fromVerse, toVerse, keywordId, !!onlyPublished)
    if(personId) return this.findAllByPerson(page, size, fromVerse, toVerse, personId, !!onlyPublished)

    let where: any = {};
    if(fromVerse!==undefined)
      where.id = MoreThanOrEqual(fromVerse);
    if(toVerse!==undefined) {
      if(where.id)
        where.id = Between(fromVerse, toVerse);
      else
        where.id = LessThanOrEqual(toVerse);
    }
    let result = await this.verseService.findAll(size, page*size, where).catch(error => error);
    if(result instanceof Error)
      throw new HttpException({error: 500, message: result.message}, HttpStatus.INTERNAL_SERVER_ERROR);

    let [list, sum] = result;

    for(let verse of list)
      for(let triplet of verse.triplets)
        if(triplet.predicate) {
          triplet.predicate.label = {fa: triplet.predicate.label, en: triplet.predicate.translation};
          delete triplet.predicate.translation;
        }

    for(let i=0; i<list.length; i++) {
      if(!i || list[i-1].id<list[i].id-1)
        list[i].prevs = await this.verseService.findNeighbours(list[i].id, -3).catch(error => false);

      if(i==list.length-1 || list[i+1].id>list[i].id+1)
        list[i].nexts = await this.verseService.findNeighbours(list[i].id, 3).catch(error => false);
    }

    return {
      error: 0,
      data: { list, sum }
    };
  }

  async findAllByPerson(page: number, size: number, fromVerse: number|undefined, toVerse: number|undefined, personId: number, onlyPublished: boolean) {
    let person = await this.personService.findOne(personId, false).catch(error => error);
    if(!person)
      throw new HttpException({error: 404, message: 'person not found'}, HttpStatus.NOT_FOUND);
    if(person instanceof Error)
      throw new HttpException({error: 500, message: person.message}, HttpStatus.INTERNAL_SERVER_ERROR);
   
    let where: any = {person};
    if(onlyPublished)
      where.state = 'accepted';
    if(fromVerse!==undefined)
      where.verseId = MoreThanOrEqual(fromVerse);
    if(toVerse!==undefined)
      where.verseId = LessThanOrEqual(toVerse);

    let [versePersons, sum] = await this.versePersonService.findAll(size, page*size, true, where).catch(error => error);
    let verseIds = versePersons.map(record => record.verse.id);
    let list = await this.verseService.findById(verseIds).catch(error => error);
    if(list instanceof Error)
      throw new HttpException({error: 500, message: list.message}, HttpStatus.INTERNAL_SERVER_ERROR);


    for(let i=0; i<list.length; i++) {
      if(!i || list[i-1].id<list[i].id-1)
        list[i].prevs = await this.verseService.findNeighbours(list[i].id, -3).catch(error => false);

      if(i==list.length-1 || list[i+1].id>list[i].id+1)
        list[i].nexts = await this.verseService.findNeighbours(list[i].id, 3).catch(error => false);
    }

    return {
      error: 0,
      data: { list, sum }
    };
  }

  async findAllByKeyword(page: number, size: number, fromVerse: number|undefined, toVerse: number|undefined, keywordId: number, onlyPublished: boolean) {
    let keyword = await this.keywordService.findOne(keywordId, false).catch(error => error);
    if(!keyword)
      throw new HttpException({error: 404, message: 'keyword not found'}, HttpStatus.NOT_FOUND);
    if(keyword instanceof Error)
      throw new HttpException({error: 500, message: keyword.message}, HttpStatus.INTERNAL_SERVER_ERROR);
   
    let where: any = {keyword};
    if(onlyPublished)
      where.state = 'accepted';
    if(fromVerse!==undefined)
      where.verseId = MoreThanOrEqual(fromVerse);
    if(toVerse!==undefined)
      where.verseId = LessThanOrEqual(toVerse);

    let [verseKeywords, sum] = await this.verseKeywordService.findAll(size, page*size, true, where).catch(error => error);
    let verseIds = verseKeywords.map(record => record.verse.id);
    let list = await this.verseService.findById(verseIds).catch(error => error);
    if(list instanceof Error)
      throw new HttpException({error: 500, message: list.message}, HttpStatus.INTERNAL_SERVER_ERROR);


    for(let i=0; i<list.length; i++) {
      if(!i || list[i-1].id<list[i].id-1)
        list[i].prevs = await this.verseService.findNeighbours(list[i].id, -3).catch(error => false);

      if(i==list.length-1 || list[i+1].id>list[i].id+1)
        list[i].nexts = await this.verseService.findNeighbours(list[i].id, 3).catch(error => false);
    }

    return {
      error: 0,
      data: { list, sum }
    };
  }

  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.verseService.findOne(+id);
  }

  @Patch(':id')
  update(@Param('id') id: string, @Body() updateVerseDto: UpdateVerseDto) {
    return this.verseService.update(+id, updateVerseDto);
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    return this.verseService.remove(+id);
  }

  @Patch('keyword/:id')
  async updateVerseKeyword(@Param('id') id: number, @Body() updateVerseKeywordDto: UpdateVerseKeywordDto) {
    let record = await this.verseKeywordService.findOne(id).catch(error => error);
    if(!record)
      throw new HttpException({error: 'not found'}, HttpStatus.NOT_FOUND);
    if(record instanceof Error)
      throw new HttpException({error: record}, HttpStatus.INTERNAL_SERVER_ERROR);
    if(updateVerseKeywordDto.state != 'accepted' && updateVerseKeywordDto.state != 'rejected')
      throw new HttpException({error: 'invalid state field'}, HttpStatus.BAD_REQUEST);

    let result = await this.verseKeywordService.update(id, {state: updateVerseKeywordDto.state}).catch(error => error);
    if(result instanceof Error)
      throw new HttpException({error: result}, HttpStatus.INTERNAL_SERVER_ERROR);
    return {error: 0, data: true};
  }

  /*@Patch('person/:id')
  async updateVersePerson(@Param('id') id: number, @Body() updateVersePersonDto: UpdateVersePersonDto) {
    let record = await this.versePersonService.findOne(id).catch(error => error);
    if(!record)
      throw new HttpException({error: 'not found'}, HttpStatus.NOT_FOUND);
    if(record instanceof Error)
      throw new HttpException({error: record}, HttpStatus.INTERNAL_SERVER_ERROR);
    if(updateVersePersonDto.state != 'accepted' && updateVersePersonDto.state != 'rejected')
      throw new HttpException({error: 'invalid state field'}, HttpStatus.BAD_REQUEST);

    let result = await this.versePersonService.update(id, {state: updateVersePersonDto.state}).catch(error => error);
    if(result instanceof Error)
      throw new HttpException({error: result}, HttpStatus.INTERNAL_SERVER_ERROR);
    return {error: 0, data: true};
  }*/

  @Post('person')
  async addVersePerson(@Body() record: any) {
    record.verse = await this.verseService.findOne(record.verse).catch(error => error);
    if(!record.verse)
      throw new HttpException({}, HttpStatus.NOT_FOUND);
    if(record.verse instanceof Error)
      throw new HttpException({}, HttpStatus.INTERNAL_SERVER_ERROR);
    record.person = await this.personService.findOne(record.person).catch(error => error);
    if(!record.person)
      throw new HttpException({}, HttpStatus.NOT_FOUND);
    if(record.person instanceof Error)
      throw new HttpException({}, HttpStatus.INTERNAL_SERVER_ERROR);

    let result = await this.versePersonService.create(record as CreateVersePersonDto).catch(error => error);
    if(result instanceof Error)
      throw new HttpException({}, HttpStatus.INTERNAL_SERVER_ERROR);
    return result;
  }

  @Delete('person/:id')
  async removeVersePerson(@Param('id') id: number) {
    let record = await this.versePersonService.findOne(id).catch(error => error);
    if(!record)
      throw new HttpException({}, HttpStatus.NOT_FOUND);
    if(record instanceof Error)
      throw new HttpException({}, HttpStatus.INTERNAL_SERVER_ERROR);

    let result = await this.versePersonService.remove(record).catch(error => error);
    if(result instanceof Error)
      throw new HttpException({error: result}, HttpStatus.INTERNAL_SERVER_ERROR);
    return true;
  }
}