Skip to content

Commit

Permalink
Merge pull request #1 from chanwit-y/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
chanwit-y authored Nov 26, 2024
2 parents ac1cd51 + ee5ea96 commit 626cc7e
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 72 deletions.
2 changes: 1 addition & 1 deletion libs/api/openai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export class OpenAIAPI {
role: "user",
content: [
{
text: `ตอบกลับเป็น json\n{\n "word": "${word}",\n "thai": "...", //แปลคำว่า ${word} เป็นภาษาไทยของคำว่า \n "english": "...", //คำอ่านและการออกเสียง obse${word}ssion เป็นภาษาไทย\n "type": "...", //ประเภทของคำของคำว่า ${word}\n "examples": [...], //ตัวอย่างการใช้คำว่า ${word} ในประเภทคำต่างๆ\n}`,
text: `ตอบกลับเป็น json\n{\n "word": "${word}",\n "thai": "...", //แปลคำว่า ${word} เป็นภาษาไทยของคำว่า \n "english": "...", //คำอ่านและการออกเสียง ${word} เป็นภาษาไทย\n "types": [...], //ประเภทของคำของคำว่า ${word}\n "examples": [...], //ตัวอย่างการใช้คำว่า ${word} ในประเภทคำต่างๆ\n}`,
type: "text",
},
],
Expand Down
16 changes: 16 additions & 0 deletions libs/mod/vocabulary/@types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export type TVocabulary = {
word: string;
content: string;
remark: string;
thai: string;
english: string;
types: string[];
examples: string[];
speech_url: string;
};

export type TUpload = {
id: string;
path: string;
fullPath: string;
};
94 changes: 61 additions & 33 deletions libs/mod/vocabulary/repository.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,16 @@
import { SupabaseDB } from './../../utils/db/index.ts';
import { Buffer } from "node:buffer";
import { SupabaseDB } from "./../../utils/db/index.ts";
import type { SupabaseClient } from "@supabase/supabase-js";
import { inject, injectable } from "inversify";

import "reflect-metadata";
import { Env } from "../../utils/config/index.ts";
import { Instances } from "../../utils/config/container.ts";

type TVocabulary = {
word: string;
content: string;
remark: string;
thai: string;
english: string;
type: string;
example: string;
};
import type { TUpload, TVocabulary } from "./@types/index.ts";

export interface IVocabularyRepository {
findAll(): Promise<unknown>;
findByWord(word: string): Promise<any[]>;
insert(v: TVocabulary): Promise<unknown>;

findByWord(word: string): Promise<TVocabulary[]>;
insert(v: TVocabulary): Promise<TVocabulary[]>;
upload(n: string, b: Buffer): Promise<TUpload>;
}

const TableName = "vocabulary";
Expand All @@ -32,32 +22,70 @@ export class VocabularyRepository implements IVocabularyRepository {
this._db = db.instance();
}

public async upload(name: string, buff: Buffer): Promise<TUpload> {
try {
const { data, error } = await this._db.storage
.from("speech")
.upload(`${name}`, buff, {
cacheControl: "3600",
});
if (error) {
console.error(error);
throw new Error(`Failed to upload file: ${error.message}`);
}
return data;
} catch (error) {
console.error(error);
throw new Error(`Failed to upload file: ${error}`);
}
}

public async findAll() {
const { data, error } = await this._db.from(TableName).select("*");
if (error) {
console.log(error);
return error;
try {
const { data, error } = await this._db.from(TableName).select("*");
if (error) {
console.log(error);
return error;
}
return data;
} catch (error) {
console.error(error);
throw new Error(`Failed to find all words: ${error}`);
}
return data;
}

public async findByWord(word: string) {
const { data, error } = await this._db
.from(TableName)
.select("*")
.eq("word", word);
if (error) {
console.log(error);
throw new Error(`Failed to find word: ${error.message}`);
try {
const { data, error } = await this._db
.from(TableName)
.select("*")
.eq("word", word);
if (error) {
console.log(error);
throw new Error(`Failed to find word: ${error.message}`);
}
return data;
} catch (error) {
console.error(error);
throw new Error(`Failed to find word: ${error}`);
}
return data;
}

public async insert(v: TVocabulary) {
const { data, error } = await this._db.from(TableName).insert([{ ...v }]).select();
if (error) {
try {
await this._db.auth.reauthenticate();
const { data, error } = await this._db
.from(TableName)
.insert([{ ...v, type: "", remark: "" }])
.select();
if (error) {
console.error(error);
throw new Error(`Failed to insert word: ${error.message}`);
}
return data;
} catch (error) {
console.error(error);
throw new Error(`Failed to insert word: ${error.message}`);
throw new Error(`Failed to insert word: ${error}`);
}
return data;
}
}
16 changes: 8 additions & 8 deletions libs/mod/vocabulary/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ const vocabularyRoutes = new Hono()
.post("/create", async (c) => {
const body = await c.req.json<{ word: string }>();
const srv = container.get<IVocabularyService>(Instances.VocabularyService);
const res = await srv.insert(body.word);
const res = await srv.newWord(body.word);
return c.json(res);
})
.get("/speech", async (c) => {
const text = await c.req.query("text");
if(!text) return c.json({ error: "text is required" }, 400);
// .post("/speech", async (c) => {
// const text = await c.req.query("text");
// if(!text) return c.json({ error: "text is required" }, 400);

const srv = container.get<IVocabularyService>(Instances.VocabularyService);
const res = await srv.speech(text);
return c.json(res);
});
// const srv = container.get<IVocabularyService>(Instances.VocabularyService);
// const res = await srv.speech(text);
// return c.json(res);
// });

export default vocabularyRoutes;
77 changes: 47 additions & 30 deletions libs/mod/vocabulary/service.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
import { transform } from "./../../utils/common/transform.ts";
import { injectable, inject } from "inversify";
import type { IVocabularyRepository } from "./repository.ts";

import "reflect-metadata";
import type { OpenAIAPI } from "../../api/openai.ts";

import fs from "node:fs";
import path from "node:path";
import { Buffer } from "node:buffer";
import type { TUpload, TVocabulary } from "./@types/index.ts";

export interface IVocabularyService {
insert(word: string): Promise<any>;
speech(text: string): Promise<any>;
// insert(word: string): Promise<TVocabulary[]>;
// speech(text: string): Promise<TUpload>;
newWord(word: string): Promise<TVocabulary[]>;
}

@injectable()
export class VocabularyService implements IVocabularyService {
// constructor(private _repo: VocabularyRepository, private _openai: OpenAIAPI) {}
private _repo: IVocabularyRepository;
private _openai: OpenAIAPI;

Expand All @@ -27,39 +25,58 @@ export class VocabularyService implements IVocabularyService {
this._repo = repo;
this._openai = openai;
}
public async speech(text: string): Promise<any> {
private async _askAiForSpeech(text: string): Promise<TUpload> {
const res = await this._openai.speech(text);

const speechFile = path.resolve(`./sound/${text}.mp3`);
// console.log(res)
const buffer = Buffer.from(await res.arrayBuffer());
await fs.promises.writeFile(speechFile, buffer);
return await this._repo.upload(`${text}.mp3`, buffer);
}

// public async auth() {
// const res = await this._repo.auth();
// return res;
// }

// public async getUser(token: string) {
// const res = await this._repo.getUser(token);
// return res;
// }

public async insert(word: string) {
let vocabulary;
vocabulary = await this._repo.findByWord(word);
if (vocabulary.length === 0) {
console.log(`call openai: ${word}`);
private async _askAiForMeening(word: string): Promise<string> {
try {
const res = await this._openai.translate(word);
const content = res.choices[0].message.content ?? "";
console.log(content);
return content;
} catch (error) {
console.error(error);
throw new Error(`Failed to ask AI: ${error}`);
}
}

vocabulary = await this._repo.insert({
...JSON.parse(content),
content,
private async _insert(data: TVocabulary): Promise<TVocabulary[]> {
try {
return await this._repo.insert({
...data,
remark: "-",
});
} catch (error) {
console.error(error);
throw new Error(`Failed to insert word: ${error}`);
}
}

public async findByWord(word: string): Promise<TVocabulary[]> {
try {
const v = await this._repo.findByWord(word);
return v;
} catch (error) {
console.error(error);
throw new Error(`Failed to check word: ${error}`);
}
}

public async newWord(word: string): Promise<TVocabulary[]> {
try {
const v = await this.findByWord(word);
if (v.length > 0) return v;
const content = await this._askAiForMeening(word);
const data: TVocabulary = JSON.parse(content);
const speech = await this._askAiForSpeech(word);
const res = await this._insert({ ...data, speech_url: speech.fullPath });
return res;
} catch (error) {
console.error(error);
throw new Error(`Failed to insert word: ${error}`);
}
return vocabulary;
}
}

0 comments on commit 626cc7e

Please sign in to comment.