Skip to content

Commit

Permalink
feat(app):
Browse files Browse the repository at this point in the history
- extension upload image
  • Loading branch information
MorvanZhou committed Aug 16, 2024
1 parent a87a026 commit 811fc72
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 20 deletions.
29 changes: 17 additions & 12 deletions src/retk/controllers/browser_extension.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
from typing import List

from fastapi import UploadFile

from retk import config, core, const
from retk.controllers import schemas
from retk.controllers.account import __login
Expand Down Expand Up @@ -43,20 +47,21 @@ async def get_access_token(

async def post_node(
au: AuthedUser,
req: schemas.browser_extension.CreateNodeRequest,
url: str,
title: str,
content: str,
referer: str,
user_agent: str,
images: List[UploadFile],
) -> schemas.node.NodeResponse:
if au.language == const.LanguageEnum.ZH.value:
source_prefix = "原文来自:"
elif au.language == const.LanguageEnum.EN.value:
source_prefix = "Source from:"
else:
source_prefix = "Source from:"
md = f"{req.title}\n\n{source_prefix} [{req.url}]({req.url})\n\n{req.content}"
n, code = await core.node.post(
n, code = await core.browser_extension.post_node(
au=au,
md=md,
type_=const.NodeTypeEnum.MARKDOWN.value,
from_nid="",
url=url,
title=title,
content=content,
referer=referer,
user_agent=user_agent,
images=images,
)
maybe_raise_json_exception(au=au, code=code)
await core.statistic.add_user_behavior(
Expand Down
1 change: 1 addition & 0 deletions src/retk/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@
notice,
analysis,
ai,
browser_extension,
)
55 changes: 55 additions & 0 deletions src/retk/core/browser_extension.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
from typing import List, Tuple, Optional

from fastapi import UploadFile

from retk import const
from retk.core import node, user
from retk.core.files.importing import sync_tasks
from retk.core.files.upload import fetch_image_vditor
from retk.models.tps import AuthedUser, Node


async def post_node(
au: AuthedUser,
url: str,
title: str,
content: str,
referer: str,
user_agent: str,
images: List[UploadFile],
) -> Tuple[Optional[Node], const.CodeEnum]:
if len(images):
if await user.user_space_not_enough(au=au):
return None, const.CodeEnum.USER_SPACE_NOT_ENOUGH

filtered_images = []
for file in images:
if file.size == 0:
new_url, code = await fetch_image_vditor(au=au, url=file.filename, referer=referer, user_agent=user_agent)
if code == const.CodeEnum.OK:
content = content.replace(file.filename, new_url)
continue
if not file.content_type.startswith(const.app.ValidUploadedFilePrefixEnum.IMAGE.value):
continue
filtered_images.append(file)
res = await sync_tasks.save_editor_upload_files(
uid=au.u.id,
files=filtered_images,
)

for original_url, new_url in res["succMap"].items():
content = content.replace(original_url, new_url)
if au.language == const.LanguageEnum.ZH.value:
source_prefix = "原文来自:"
elif au.language == const.LanguageEnum.EN.value:
source_prefix = "Source from:"
else:
source_prefix = "Source from:"
md = f"{title}\n\n{source_prefix} [{url}]({url})\n\n{content}"
n, code = await node.post(
au=au,
md=md,
type_=const.NodeTypeEnum.MARKDOWN.value,
from_nid="",
)
return n, code
23 changes: 18 additions & 5 deletions src/retk/core/files/upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,9 @@ async def vditor_upload(au: AuthedUser, files: List[UploadFile]) -> dict:
)


async def fetch_image_vditor(au: AuthedUser, url: str, count=0) -> Tuple[str, const.CodeEnum]:
# pylint: disable=line-too-long
async def fetch_image_vditor(au: AuthedUser, url: str, count=0, referer: str = "", user_agent: str = "") -> Tuple[
str, const.CodeEnum]:
if count > 2:
logger.debug(f"too many 30X code, failed to get {url}")
return "", const.CodeEnum.FILE_OPEN_ERROR
Expand All @@ -149,11 +151,16 @@ async def fetch_image_vditor(au: AuthedUser, url: str, count=0) -> Tuple[str, co
return "", const.CodeEnum.FILE_OPEN_ERROR
if await core.user.user_space_not_enough(au=au):
return "", const.CodeEnum.USER_SPACE_NOT_ENOUGH
headers = ASYNC_CLIENT_HEADERS.copy()
if referer != "":
headers["Referer"] = referer
if user_agent != "":
headers["User-Agent"] = user_agent
try:
async with httpx.AsyncClient() as client:
response = await client.get(
async with httpx.AsyncClient() as c:
response = await c.get(
url=url,
headers=ASYNC_CLIENT_HEADERS,
headers=headers,
follow_redirects=False,
timeout=5.
)
Expand All @@ -167,7 +174,13 @@ async def fetch_image_vditor(au: AuthedUser, url: str, count=0) -> Tuple[str, co
logger.debug(f"failed to get {url}: {e}")
return "", const.CodeEnum.FILE_OPEN_ERROR
if response.status_code in [301, 302]:
return await fetch_image_vditor(au=au, url=response.headers["Location"], count=count + 1)
return await fetch_image_vditor(
au=au,
url=response.headers["Location"],
count=count + 1,
referer=referer,
user_agent=user_agent
)
elif response.status_code != 200:
return "", const.CodeEnum.FILE_OPEN_ERROR

Expand Down
2 changes: 2 additions & 0 deletions src/retk/core/scheduler/tasks/extend_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ async def async_deliver_unscheduled_extend_nodes() -> str:

for item in batch:
node = await db[CollNameEnum.nodes.value].find_one({"id": item["nid"]})
if node is None:
continue
cases.append(
knowledge.ExtendCase(
_id=item["_id"],
Expand Down
18 changes: 15 additions & 3 deletions src/retk/routes/browser_extension.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from fastapi import APIRouter
from typing import Annotated, List

from fastapi import APIRouter, Form, UploadFile

from retk.controllers import schemas, browser_extension
from retk.routes import utils
Expand Down Expand Up @@ -43,9 +45,19 @@ async def browser_extension_refresh_token(
@utils.measure_time_spend
async def post_node_from_browser_extension(
au: utils.ANNOTATED_AUTHED_USER_BROWSER_EXTENSION,
req: schemas.browser_extension.CreateNodeRequest,
url: Annotated[str, Form(...)],
title: Annotated[str, Form(...)],
content: Annotated[str, Form(...)],
referer: Annotated[str, Form(...)],
user_agent: Annotated[str, Form(alias="userAgent")],
images: List[Annotated[UploadFile, Form(...)]],
) -> schemas.node.NodeResponse:
return await browser_extension.post_node(
au=au,
req=req,
url=url,
title=title,
content=content,
referer=referer,
user_agent=user_agent,
images=images,
)

0 comments on commit 811fc72

Please sign in to comment.