Skip to content

Commit

Permalink
feat: Add endpoint to retrieve random audio based on limit and recite…
Browse files Browse the repository at this point in the history
…r ID #31
  • Loading branch information
the-sabra committed Feb 4, 2025
1 parent f448e71 commit 4c03900
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/audio/audio.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { AudioService } from './audio.service';
import { CreateAudioDto } from './dto/create-audio.dto';
import { FilterAudioDto } from './dto/filter-audio.dto';
import { FilterAudioLrcDto } from './dto/filter-lrc.dto';
import { RandomDto } from './dto/random.dto';

@Controller('audio')
export class AudioController {
Expand All @@ -22,4 +23,12 @@ export class AudioController {
getLrc(@Query() filterAudioLrcDto: FilterAudioLrcDto) {
return this.audioService.getAudioLrc(filterAudioLrcDto);
}

@Get('/random')
getRandom(@Query() randomDto: RandomDto) {
return this.audioService.getRandomAudio(
randomDto.limit,
randomDto.reciter_id,
);
}
}
41 changes: 41 additions & 0 deletions src/audio/audio.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,45 @@ export class AudioService {
},
});
}

async getRandomAudio(limit: number, reciter_id: number) {
if (limit < 1) {
throw new Error('Limit must be greater than 0');
}

const tilawat = await this.reciterService.getReciterTilawa(reciter_id);

if (!tilawat?.length) {
throw new Error('No tilawat found for this reciter');
}

// Use more efficient random selection for tilawa
const randomTilawaIndex = Math.floor(Math.random() * tilawat.length);
const randomTilawa = tilawat[randomTilawaIndex];

const audioRecords = await this.tilawaSurahRepo.find({
select: ['tilawa_id', 'url'],
where: {
tilawa_id: randomTilawa.id,
},
relations: {
surah: true,
tilawa: {
reciter: true,
},
},
});

if (!audioRecords?.length) {
return [];
}

// Use Fisher-Yates shuffle algorithm for randomization
for (let i = audioRecords.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[audioRecords[i], audioRecords[j]] = [audioRecords[j], audioRecords[i]];
}

return audioRecords.slice(0, Math.min(limit, audioRecords.length));
}
}
14 changes: 14 additions & 0 deletions src/audio/dto/random.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Transform } from 'class-transformer';
import { IsNumber, IsPositive } from 'class-validator';

export class RandomDto {
@IsNumber()
@IsPositive()
@Transform(({ value }) => parseInt(value))
limit: number;

@IsNumber()
@IsPositive()
@Transform(({ value }) => parseInt(value))
reciter_id: number;
}

0 comments on commit 4c03900

Please sign in to comment.