feat: Editor + read pdf/docx...

This commit is contained in:
莘权 马 2024-08-07 20:13:11 +08:00
parent fa06a67a64
commit dc578d8b0b
15 changed files with 447 additions and 30 deletions

View file

@ -12,6 +12,7 @@
from __future__ import annotations
import ast
import asyncio
import base64
import contextlib
import csv
@ -852,7 +853,10 @@ async def get_mime_type(filename: str | Path, force_read: bool = False) -> str:
}
try:
stdout, _, _ = await shell_execute(f"file --mime-type {str(filename)}")
stdout, stderr, _ = await shell_execute(f"file --mime-type {str(filename)}")
if stderr:
logger.debug(f"file:{filename}, error:{stderr}")
return guess_mime_type
ix = stdout.rfind(" ")
mime_type = stdout[ix:].strip()
if mime_type == "text/plain" and guess_mime_type in text_set:
@ -1050,6 +1054,32 @@ def tool2name(cls, methods: List[str], entry) -> Dict[str, Any]:
return mappings
def run_coroutine_sync(coroutine, *args, **kwargs):
"""
Runs a coroutine function synchronously by encapsulating its invocation as a non-coroutine function call.
Args:
coroutine: The coroutine function to be encapsulated.
*args: Positional arguments to be passed to the coroutine.
**kwargs: Keyword arguments to be passed to the coroutine.
Returns:
The return value of the coroutine.
"""
try:
loop = asyncio.get_running_loop()
except RuntimeError: # No running event loop
loop = None
if loop and loop.is_running():
# The event loop is already running
future = asyncio.run_coroutine_threadsafe(coroutine(*args, **kwargs), loop)
return future.result()
else:
# The event loop is not running
return asyncio.run(coroutine(*args, **kwargs))
def log_time(method):
"""A time-consuming decorator for printing execution duration."""

View file

@ -7,7 +7,7 @@ from __future__ import annotations
import re
from pathlib import Path
from typing import Tuple
from typing import Tuple, Union
from gitignore_parser import parse_gitignore
@ -82,7 +82,7 @@ async def _write_files(repo_path, gitignore_rules=None) -> str:
async def _write_file(filename: Path, repo_path: Path) -> str:
is_text, mime_type = await _is_text_file(filename)
is_text, mime_type = await is_text_file(filename)
if not is_text:
logger.info(f"Ignore content: {filename}")
return ""
@ -100,7 +100,17 @@ async def _write_file(filename: Path, repo_path: Path) -> str:
return ""
async def _is_text_file(filename: Path) -> Tuple[bool, str]:
async def is_text_file(filename: Union[str, Path]) -> Tuple[bool, str]:
"""
Determines if the specified file is a text file based on its MIME type.
Args:
filename (Union[str, Path]): The path to the file.
Returns:
Tuple[bool, str]: A tuple where the first element indicates if the file is a text file
(True for text file, False otherwise), and the second element is the MIME type of the file.
"""
pass_set = {
"application/json",
"application/vnd.chipnuts.karaoke-mmd",
@ -129,7 +139,7 @@ async def _is_text_file(filename: Path) -> Tuple[bool, str]:
"image/vnd.microsoft.icon",
"video/mp4",
}
mime_type = await get_mime_type(filename, force_read=True)
mime_type = await get_mime_type(Path(filename), force_read=True)
v = "text/" in mime_type or mime_type in pass_set
if v:
return True, mime_type