Skip to content

Commit

Permalink
ankilot形式のcsvからのインポート準備完了
Browse files Browse the repository at this point in the history
  • Loading branch information
chakkun1121 authored Jan 18, 2024
1 parent 1a12647 commit 10d5d33
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"cSpell.words": ["vocabphrase"]
"cSpell.words": ["anikilot", "vocabphrase"]
}
29 changes: 28 additions & 1 deletion app/(app)/app/ImportForm.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
"use client";
import { fileType } from "@/@types/fileType";
import { uuidv7 as createUUID } from "uuidv7";
import React, { useState } from "react";
import React, { MouseEventHandler, useState } from "react";
import { wayakuFile2file } from "./_library/wayaku";
import { uploadFile } from "./_library/uploadFile";
import { csvToFileContent } from "./_library/csvToFileContent";

export default function ImportForm({
close,
Expand Down Expand Up @@ -30,6 +32,27 @@ export default function ImportForm({
setTitle(title);
close();
}
async function importFromCsv(mode?: "en-ja" | "ja-en") {
/**
* ファイル形式(ヘッダー行は基本的になしだが、含まれている場合はユーザーによって除去してもらう)
* 1. |表|裏|
* 2. |index|表|裏|
* 3. |表|(表ヒント(最後にカッコの中に入れる))|裏|(裏ヒント)|
* 4. |index|表|(表ヒント)|裏|(裏ヒント)|
*/
const { content, fileName } = await uploadFile([
{
description: "csvファイル(anikilot形式)",
accept: { "text/csv": [".csv"] },
},
]);
if (!content) return;
const csv = content.split("\n").map((line) => line.split(","));
const fileContent = csvToFileContent(csv, mode);
const title = fileName.split(".").slice(0, -1).join(".");
setFileContent({ content: fileContent, mode: null });
setTitle(title);
}
return (
<div className="w-full p-4 rounded bg-gray-200">
<p>Excel,Googleスプレッドシートなどからコピペできます</p>
Expand All @@ -56,6 +79,10 @@ export default function ImportForm({
name: "和訳ファイル(.wayaku)",
onClick: uploadWayakuFile,
},
{
name: "csvファイル(ankilot形式のもの)",
onClick: () => importFromCsv(),
},
].map(({ name, onClick }, i) => (
<li className="list-none text-center relative " key={i}>
<button
Expand Down
53 changes: 53 additions & 0 deletions app/(app)/app/_library/csvToFileContent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { fileType } from "@/@types/fileType";
import { uuidv7 as createUUID } from "uuidv7";

export function csvToFileContent(
csv: string[][],
mode?: "en-ja" | "ja-en"
): fileType["content"] {
const lines = csv[1].length;
if (!mode) mode = isEnglish(csv[1][lines % 2]) ? "en-ja" : "ja-en";
let fileContent: fileType["content"];
if (lines === 2) {
fileContent = csv.map((line) => ({
id: createUUID(),
en: line[mode === "en-ja" ? 0 : 1],
ja: line[mode === "ja-en" ? 0 : 1],
}));
} else if (lines === 3) {
fileContent = csv.map((line) => ({
id: createUUID(),
en: line[mode === "en-ja" ? 0 : 1],
ja: line[mode === "ja-en" ? 0 : 1],
hint: line[2],
}));
} else if (lines === 4) {
fileContent = csv.map((line) => ({
id: createUUID(),
en: `${line[mode === "en-ja" ? 0 : 1]} ${
line[mode === "en-ja" ? 2 : 3] ? `(${[mode === "en-ja" ? 2 : 3]})` : ``
}`,
ja: `${line[mode === "ja-en" ? 0 : 1]}${
line[mode === "ja-en" ? 2 : 3] ? `(${[mode === "ja-en" ? 2 : 3]})` : ``
}`,
}));
} else if (lines === 5) {
fileContent = csv.map((line) => ({
id: createUUID(),
en: `${line[mode === "en-ja" ? 1 : 2]} ${
line[mode === "en-ja" ? 3 : 4] ? `(${[mode === "en-ja" ? 3 : 4]})` : ``
}`,
ja: `${line[mode === "ja-en" ? 1 : 2]}${
line[mode === "ja-en" ? 3 : 4] ? `(${[mode === "ja-en" ? 3 : 4]})` : ``
}`,
}));
} else throw new Error("ファイル形式が不正です");
return fileContent;
}
export function isEnglish(text: string) {
/**
* 英語の判定(unicode上で225以上の数が入っていないか)
* @param text 判定する文字列
*/
return !text.split("").some((char) => char.charCodeAt(0) >= 225);
}
22 changes: 14 additions & 8 deletions app/(app)/app/_library/uploadFile.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
export async function uploadFile(): Promise<{
export async function uploadFile(
acceptType: {
description: string;
accept: Record<string, string[]>;
}[] = [
{
description: "和訳ファイル",
accept: { "application/wayaku": [".wayaku"] },
},
]
): Promise<{
content: string;
fileName: string;
fileHandle?: FileSystemFileHandle;
Expand All @@ -8,12 +18,8 @@ export async function uploadFile(): Promise<{
throw new Error("showOpenFilePicker is not defined");
const FileSystemFileHandles: FileSystemFileHandle[] =
await window.showOpenFilePicker({
types: [
{
description: "和訳ファイル",
accept: { "application/wayaku": ".wayaku" },
},
],
types: acceptType,
excludeAcceptAllOption: false,
});
const FileSystemFileHandle: FileSystemFileHandle = FileSystemFileHandles[0];
return FileSystemFileHandle;
Expand All @@ -28,7 +34,7 @@ export async function uploadFile(): Promise<{
}
const fileInput = document.createElement("input");
fileInput.type = "file";
fileInput.accept = "application/wayaku";
fileInput.accept = Object.keys(acceptType[0].accept)[0];
fileInput.click();
const file = await new Promise<File>((resolve) => {
fileInput.addEventListener("change", () => {
Expand Down

0 comments on commit 10d5d33

Please sign in to comment.