add pad2txt tools

This commit is contained in:
Wenjie Zhang 2024-09-29 16:13:35 +08:00
parent e968a3d9f8
commit 9744b738ba
3 changed files with 202 additions and 0 deletions

View File

@ -20,6 +20,13 @@ def route_index():
"description": "将文本分块以更好地理解。可以输入文本或者上传文件。",
"url": "/tools/text_chunking",
"method": "POST",
},
{
"name": "pdf2txt",
"title": "PDF转文本",
"description": "将PDF文件转换为文本文件。",
"url": "/tools/pdf2txt",
"method": "POST",
}
]
@ -32,3 +39,10 @@ def text_chunking():
text = request.json.get("text")
nodes = chunk(text, params=request.json)
return jsonify({"nodes": [node.to_dict() for node in nodes]})
@tools.route("/pdf2txt", methods=["POST"])
def handle_pdf2txt():
from src.plugins import pdf2txt
file = request.json.get("file")
text = pdf2txt(file, return_text=True)
return jsonify({"text": text})

View File

@ -0,0 +1,183 @@
<template>
<div class="pdf2txt-container">
<div class="sidebar">
<div class="additional-params">
<h4>相关参数</h4>
<!-- Add any PDF-specific parameters here if needed -->
</div>
</div>
<div class="result-container">
<div class="input-container">
<div class="upload">
<a-upload-dragger
class="upload-dragger"
v-model:fileList="fileList"
name="file"
:max-count="1"
:disabled="state.uploading"
action="/api/database/upload"
@change="handleFileUpload"
@drop="handleDrop"
>
<p class="ant-upload-text">点击或者把PDF文件拖拽到这里上传</p>
<p class="ant-upload-hint">
仅支持上传PDF文件同名文件无法重复添加
</p>
</a-upload-dragger>
</div>
<a-button type="primary" @click="convertPdfToText" :loading="state.loading">Convert PDF to Text</a-button>
</div>
<div class="output-container">
<textarea v-model="convertedText" placeholder="Converted text will appear here" readonly></textarea>
<div class="infos">
<span>字符数: {{ charCount }}</span>
<span>Token {{ estimatedTokenCount }}</span>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { reactive, ref, computed } from 'vue';
import { message } from 'ant-design-vue';
const state = reactive({
loading: false,
uploading: false,
});
const fileList = ref([]);
const convertedText = ref('');
const charCount = computed(() => convertedText.value.length);
const estimatedTokenCount = computed(() => {
const chars = convertedText.value.split('');
let tokenCount = 0;
for (let char of chars) {
if (/[\u4e00-\u9fff]/.test(char)) {
tokenCount += 1;
} else if (/[a-zA-Z]/.test(char)) {
tokenCount += 0.25;
} else {
tokenCount += 0.5;
}
}
return Math.ceil(tokenCount);
});
const handleFileUpload = (info) => {
const { status } = info.file;
if (status !== 'uploading') {
console.log(info.file, info.fileList);
}
if (status === 'done') {
message.success(`${info.file.name} file uploaded successfully.`);
} else if (status === 'error') {
message.error(`${info.file.name} file upload failed.`);
}
};
const handleDrop = (e) => {
console.log(e);
};
const convertPdfToText = async () => {
if (fileList.value.length === 0) {
message.error("请上传PDF文件");
return;
}
const file = fileList.value[0].response.file_path;
try {
state.loading = true;
const response = await fetch('/api/tools/pdf2txt', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ file: file })
});
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json();
convertedText.value = data.text;
state.loading = false;
} catch (error) {
console.error('Error converting PDF to text:', error);
message.error('PDF转换失败请重试');
state.loading = false;
}
};
</script>
<style lang="less" scoped>
.pdf2txt-container {
display: flex;
border-radius: 8px;
font-family: 'Arial', sans-serif;
.sidebar {
position: sticky;
top: 0;
width: 350px;
background-color: var(--bg-sider);
border-right: 1px solid var(--main-light-3);
padding: 20px;
min-width: 250px;
flex: 1;
.additional-params {
h4 {
font-size: 1.2em;
margin-bottom: 10px;
}
}
}
.result-container {
flex: 3;
padding: 20px;
.input-container {
display: flex;
flex-direction: column;
margin-bottom: 15px;
.upload {
margin-bottom: 15px;
}
}
.output-container {
textarea {
width: 100%;
height: 300px;
resize: vertical;
padding: 1rem;
border: 1px solid var(--gray-300);
border-radius: 8px;
font-size: 1rem;
transition: border-color 0.3s;
background-color: var(--gray-100);
&:focus {
border-color: var(--main-color);
outline: none;
}
}
.infos {
padding: 10px;
margin-top: 10px;
font-size: 1em;
color: var(--gray-800);
display: flex;
gap: 16px;
}
}
}
}
</style>

View File

@ -91,6 +91,11 @@ const router = createRouter({
name: 'TextChunking',
component: () => import('../components/TextChunkingComponent.vue'),
},
{
path: 'pdf2txt',
name: 'PDF_to_TXT',
component: () => import('../components/ConvertToTxtComponent.vue'),
},
]
},
{