remove main/web-api

This commit is contained in:
an-lee
2024-01-11 17:44:43 +08:00
parent 267eee37b9
commit eda547aca1
7 changed files with 42 additions and 490 deletions

View File

@@ -25,13 +25,20 @@ import mainWindow from "@main/window";
import log from "electron-log/main";
import storage from "@main/storage";
import Ffmpeg from "@main/ffmpeg";
import webApi from "@main/web-api";
import { Client } from "@/api";
import { WEB_API_URL } from "@/constants";
import { startCase } from "lodash";
import { v5 as uuidv5 } from "uuid";
const SIZE_LIMIT = 1024 * 1024 * 50; // 50MB
const logger = log.scope("db/models/audio");
const webApi = new Client({
baseUrl: process.env.WEB_API_URL || WEB_API_URL,
accessToken: settings.getSync("user.accessToken") as string,
});
@Table({
modelName: "Audio",
tableName: "audios",

View File

@@ -14,7 +14,15 @@ import {
} from "sequelize-typescript";
import mainWindow from "@main/window";
import { Recording } from "@main/db/models";
import webApi from "@main/web-api";
import { Client } from "@/api";
import { WEB_API_URL } from "@/constants";
import settings from "@main/settings";
const webApi = new Client({
baseUrl: process.env.WEB_API_URL || WEB_API_URL,
accessToken: settings.getSync("user.accessToken") as string,
});
@Table({
modelName: "PronunciationAssessment",

View File

@@ -23,12 +23,18 @@ import { hashFile } from "@/utils";
import log from "electron-log/main";
import storage from "@main/storage";
import Ffmpeg from "@main/ffmpeg";
import webApi from "@main/web-api";
import { Client } from "@/api";
import { WEB_API_URL } from "@/constants";
import { AzureSpeechSdk } from "@main/azure-speech-sdk";
import camelcaseKeys from "camelcase-keys";
const logger = log.scope("db/models/recording");
const webApi = new Client({
baseUrl: process.env.WEB_API_URL || WEB_API_URL,
accessToken: settings.getSync("user.accessToken") as string,
});
@Table({
modelName: "Recording",
tableName: "recordings",
@@ -36,7 +42,7 @@ const logger = log.scope("db/models/recording");
timestamps: true,
})
export class Recording extends Model<Recording> {
@IsUUID('all')
@IsUUID("all")
@Default(DataType.UUIDV4)
@Column({ primaryKey: true, type: DataType.UUID })
id: string;

View File

@@ -15,9 +15,16 @@ import { Audio, Video } from "@main/db/models";
import whisper from "@main/whisper";
import mainWindow from "@main/window";
import log from "electron-log/main";
import webApi from "@main/web-api";
import { Client } from "@/api";
import { WEB_API_URL } from "@/constants";
import settings from "@main/settings";
const logger = log.scope("db/models/transcription");
const webApi = new Client({
baseUrl: process.env.WEB_API_URL || WEB_API_URL,
accessToken: settings.getSync("user.accessToken") as string,
});
@Table({
modelName: "Transcription",
tableName: "transcriptions",
@@ -25,7 +32,7 @@ const logger = log.scope("db/models/transcription");
timestamps: true,
})
export class Transcription extends Model<Transcription> {
@IsUUID('all')
@IsUUID("all")
@Default(DataType.UUIDV4)
@Column({ primaryKey: true, type: DataType.UUID })
id: string;

View File

@@ -25,13 +25,20 @@ import mainWindow from "@main/window";
import log from "electron-log/main";
import storage from "@main/storage";
import Ffmpeg from "@main/ffmpeg";
import webApi from "@main/web-api";
import { Client } from "@/api";
import { WEB_API_URL } from "@/constants";
import { startCase } from "lodash";
import { v5 as uuidv5 } from "uuid";
const SIZE_LIMIT = 1024 * 1024 * 100; // 100MB
const logger = log.scope("db/models/video");
const webApi = new Client({
baseUrl: process.env.WEB_API_URL || WEB_API_URL,
accessToken: settings.getSync("user.accessToken") as string,
});
@Table({
modelName: "Video",
tableName: "videos",

View File

@@ -1,480 +0,0 @@
import { ipcMain } from "electron";
import axios, { AxiosInstance } from "axios";
import { WEB_API_URL } from "@/constants";
import settings from "@main/settings";
import log from "electron-log/main";
import decamelizeKeys from "decamelize-keys";
import camelcaseKeys from "camelcase-keys";
const logger = log.scope("web-api");
const ONE_MINUTE = 1000 * 60; // 1 minute
class WebApi {
public api: AxiosInstance;
constructor() {
this.api = axios.create({
baseURL: process.env.WEB_API_URL || WEB_API_URL,
timeout: ONE_MINUTE,
headers: {
"Content-Type": "application/json",
},
});
this.api.interceptors.request.use((config) => {
config.headers.Authorization = `Bearer ${settings.getSync(
"user.accessToken"
)}`;
logger.info(
config.method.toUpperCase(),
config.baseURL + config.url,
config.data,
config.params
);
return config;
});
this.api.interceptors.response.use(
(response) => {
logger.info(
response.status,
response.config.method.toUpperCase(),
response.config.baseURL + response.config.url
);
return camelcaseKeys(response.data, { deep: true });
},
(err) => {
if (err.response) {
logger.error(
err.response.status,
err.response.config.method.toUpperCase(),
err.response.config.baseURL + err.response.config.url
);
logger.error(err.response.data);
return Promise.reject(err.response.data);
}
if (err.request) {
logger.error(err.request);
} else {
logger.error(err.message);
}
return Promise.reject(err);
}
);
}
auth(params: { provider: string; code: string }): Promise<UserType> {
return this.api.post("/api/sessions", decamelizeKeys(params));
}
me() {
return this.api.get("/api/me");
}
rankings(range: "day" | "week" | "month" | "year" | "all" = "day"): Promise<{
rankings: UserType[];
range: string;
}> {
return this.api.get("/api/users/rankings", { params: { range } });
}
posts(params?: { page?: number; items?: number }): Promise<
{
posts: PostType[];
} & PagyResponseType
> {
return this.api.get("/api/posts", { params: decamelizeKeys(params) });
}
post(id: string): Promise<PostType> {
return this.api.get(`/api/posts/${id}`);
}
createPost(params: { content: string }): Promise<PostType> {
return this.api.post("/api/posts", decamelizeKeys(params));
}
updatePost(id: string, params: { content: string }): Promise<PostType> {
return this.api.put(`/api/posts/${id}`, decamelizeKeys(params));
}
deletePost(id: string): Promise<void> {
return this.api.delete(`/api/posts/${id}`);
}
syncAudio(audio: Partial<AudioType>) {
return this.api.post("/api/mine/audios", decamelizeKeys(audio));
}
syncVideo(video: Partial<VideoType>) {
return this.api.post("/api/mine/videos", decamelizeKeys(video));
}
syncTranscription(transcription: Partial<TranscriptionType>) {
return this.api.post("/api/transcriptions", decamelizeKeys(transcription));
}
syncRecording(recording: Partial<RecordingType>) {
if (!recording) return;
return this.api.post("/api/mine/recordings", decamelizeKeys(recording));
}
generateSpeechToken(): Promise<{ token: string; region: string }> {
return this.api.post("/api/speech/tokens");
}
syncPronunciationAssessment(
pronunciationAssessment: Partial<PronunciationAssessmentType>
) {
if (!pronunciationAssessment) return;
return this.api.post(
"/api/mine/pronunciation_assessments",
decamelizeKeys(pronunciationAssessment)
);
}
recordingAssessment(id: string) {
return this.api.get(`/api/mine/recordings/${id}/assessment`);
}
lookup(params: {
word: string;
context: string;
sourceId?: string;
sourceType?: string;
}): Promise<LookupType> {
return this.api.post("/api/lookups", decamelizeKeys(params));
}
lookupInBatch(
lookups: {
word: string;
context: string;
sourceId?: string;
sourceType?: string;
}[]
): Promise<{ successCount: number; total: number }> {
return this.api.post("/api/lookups/batch", {
lookups: decamelizeKeys(lookups, { deep: true }),
});
}
extractVocabularyFromStory(storyId: string): Promise<string[]> {
return this.api.post(`/api/stories/${storyId}/extract_vocabulary`);
}
storyMeanings(
storyId: string,
params?: {
page?: number;
items?: number;
storyId?: string;
}
): Promise<
{
meanings: MeaningType[];
} & PagyResponseType
> {
return this.api.get(`/api/stories/${storyId}/meanings`, {
params: decamelizeKeys(params),
});
}
mineMeanings(params?: {
page?: number;
items?: number;
sourceId?: string;
sourceType?: string;
status?: string;
}): Promise<
{
meanings: MeaningType[];
} & PagyResponseType
> {
return this.api.get("/api/mine/meanings", {
params: decamelizeKeys(params),
});
}
createStory(params: CreateStoryParamsType): Promise<StoryType> {
return this.api.post("/api/stories", decamelizeKeys(params));
}
story(id: string): Promise<StoryType> {
return this.api.get(`/api/stories/${id}`);
}
stories(params?: { page: number }): Promise<
{
stories: StoryType[];
} & PagyResponseType
> {
return this.api.get("/api/stories", { params: decamelizeKeys(params) });
}
mineStories(params?: { page: number }): Promise<
{
stories: StoryType[];
} & PagyResponseType
> {
return this.api.get("/api/mine/stories", {
params: decamelizeKeys(params),
});
}
starStory(storyId: string) {
return this.api.post(`/api/mine/stories`, decamelizeKeys({ storyId }));
}
unstarStory(storyId: string) {
return this.api.delete(`/api/mine/stories/${storyId}`);
}
registerIpcHandlers() {
ipcMain.handle("web-api-auth", async (event, params) => {
return this.auth(params)
.then((user) => {
return user;
})
.catch((error) => {
event.sender.send("on-notification", {
type: "error",
message: error.message,
});
});
});
ipcMain.handle("web-api-me", async (event) => {
return this.me()
.then((user) => {
return user;
})
.catch((error) => {
event.sender.send("on-notification", {
type: "error",
message: error.message,
});
});
});
ipcMain.handle("web-api-rankings", async (event, range) => {
return this.rankings(range)
.then((response) => {
return response;
})
.catch((error) => {
logger.error(error);
event.sender.send("on-notification", {
type: "error",
message: error.message,
});
});
});
ipcMain.handle("web-api-posts", async (event, params) => {
return this.posts(params)
.then((response) => {
return response;
})
.catch((error) => {
logger.error(error);
event.sender.send("on-notification", {
type: "error",
message: error.message,
});
});
});
ipcMain.handle("web-api-post", async (event, id) => {
return this.post(id)
.then((response) => {
return response;
})
.catch((error) => {
logger.error(error);
event.sender.send("on-notification", {
type: "error",
message: error.message,
});
});
});
ipcMain.handle("web-api-create-post", async (event, params) => {
return this.createPost(params)
.then((response) => {
return response;
})
.catch((error) => {
logger.error(error);
event.sender.send("on-notification", {
type: "error",
message: error.message,
});
});
});
ipcMain.handle("web-api-delete-post", async (event, id) => {
return this.deletePost(id)
.then((response) => {
return response;
})
.catch((error) => {
logger.error(error);
event.sender.send("on-notification", {
type: "error",
message: error.message,
});
});
});
ipcMain.handle("web-api-lookup", async (event, params) => {
return this.lookup(params)
.then((response) => {
return response;
})
.catch((error) => {
event.sender.send("on-notification", {
type: "error",
message: error.message,
});
});
});
ipcMain.handle("web-api-lookup-in-batch", async (event, params) => {
return this.lookupInBatch(params)
.then((response) => {
return response;
})
.catch((error) => {
event.sender.send("on-notification", {
type: "error",
message: error.message,
});
});
});
ipcMain.handle("web-api-mine-meanings", async (event, params) => {
return this.mineMeanings(params)
.then((response) => {
return response;
})
.catch((error) => {
event.sender.send("on-notification", {
type: "error",
message: error.message,
});
});
});
ipcMain.handle("web-api-create-story", async (event, params) => {
return this.createStory(params)
.then((response) => {
return response;
})
.catch((error) => {
event.sender.send("on-notification", {
type: "error",
message: error.message,
});
});
});
ipcMain.handle(
"web-api-extract-vocabulary-from-story",
async (event, storyId) => {
return this.extractVocabularyFromStory(storyId)
.then((response) => {
return response;
})
.catch((error) => {
event.sender.send("on-notification", {
type: "error",
message: error.message,
});
});
}
);
ipcMain.handle("web-api-story-meanings", async (event, storyId, params) => {
return this.storyMeanings(storyId, params)
.then((response) => {
return response;
})
.catch((error) => {
event.sender.send("on-notification", {
type: "error",
message: error.message,
});
});
});
ipcMain.handle("web-api-stories", async (event, params) => {
return this.stories(params)
.then((response) => {
return response;
})
.catch((error) => {
event.sender.send("on-notification", {
type: "error",
message: error.message,
});
});
});
ipcMain.handle("web-api-story", async (event, id) => {
return this.story(id)
.then((response) => {
return response;
})
.catch((error) => {
event.sender.send("on-notification", {
type: "error",
message: error.message,
});
});
});
ipcMain.handle("web-api-mine-stories", async (event, params) => {
return this.mineStories(params)
.then((response) => {
return response;
})
.catch((error) => {
event.sender.send("on-notification", {
type: "error",
message: error.message,
});
});
});
ipcMain.handle("web-api-star-story", async (event, id) => {
return this.starStory(id)
.then((response) => {
return response;
})
.catch((error) => {
event.sender.send("on-notification", {
type: "error",
message: error.message,
});
});
});
ipcMain.handle("web-api-unstar-story", async (event, id) => {
return this.unstarStory(id)
.then((response) => {
return response;
})
.catch((error) => {
event.sender.send("on-notification", {
type: "error",
message: error.message,
});
});
});
}
}
export default new WebApi();

View File

@@ -14,7 +14,6 @@ import downloader from "@main/downloader";
import whisper from "@main/whisper";
import fs from "fs-extra";
import "@main/i18n";
import webApi from "@main/web-api";
import log from "electron-log/main";
import { WEB_API_URL } from "@/constants";
import { AudibleProvider, TedProvider } from "@main/providers";
@@ -38,8 +37,6 @@ main.init = () => {
return;
}
webApi.registerIpcHandlers();
// Prepare local database
db.registerIpcHandlers();