Skip to content

Commit

Permalink
node data add snippet; add link quick post
Browse files Browse the repository at this point in the history
  • Loading branch information
MorvanZhou committed Nov 15, 2023
1 parent 3ca6f2c commit 63b9751
Show file tree
Hide file tree
Showing 9 changed files with 182 additions and 14 deletions.
23 changes: 23 additions & 0 deletions src/rethink/controllers/node/node_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ def __get_node_data(n: models.tps.Node) -> schemas.node.NodeData:
id=n["id"],
md=n["md"],
title=n["title"],
snippet=n["snippet"],
type=n["type"],
disabled=n["disabled"],
createdAt=datetime2str(n["_id"].generation_time),
Expand Down Expand Up @@ -71,6 +72,28 @@ def put_node(
)


async def put_quick_node(
td: TokenDecode,
req: schemas.node.PutRequest,
) -> schemas.node.PutResponse:
if td.code != const.Code.OK:
return schemas.node.PutResponse(
code=td.code.value,
message=const.get_msg_by_code(td.code, td.language),
requestId=req.requestId,
node=None
)

if models.utils.contain_only_http_link(req.md) != "":
title, description = await models.utils.get_title_description_from_link(req.md)
req.md = f"{title}\n\n{description}\n\n[{req.md}]({req.md})"

return put_node(
td=td,
req=req,
)


def get_node(
td: TokenDecode,
req_id: str,
Expand Down
1 change: 1 addition & 0 deletions src/rethink/controllers/schemas/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class LinkedNode(BaseModel):
id: str
md: str
title: str
snippet: str
type: NonNegativeInt
disabled: bool
createdAt: str
Expand Down
9 changes: 0 additions & 9 deletions src/rethink/dist-local/css/app.8fc24017.css
Original file line number Diff line number Diff line change
Expand Up @@ -4183,32 +4183,27 @@ tr.tr-sm .node-more-ops {
width: 1px;
height: 1px;
}

.file-label[data-v-a421d7c6] {
font-size: 1.3em;
font-weight: 300;
display: block;
text-align: center;
cursor: pointer;
}

.file-label img[data-v-a421d7c6] {
width: 50px;
height: 50px;
margin-bottom: 1rem;
}

.center[data-v-a421d7c6] {
display: flex;
justify-content: center;
align-items: center;
}

.click-upload[data-v-a421d7c6] {
text-underline-offset: 0.1em;
text-decoration: underline;
}

.preview-container[data-v-a421d7c6] {
display: flex;
margin-top: 2rem;
Expand Down Expand Up @@ -4413,23 +4408,19 @@ h2[data-v-05a72108] {
font-size: 1.2em;
font-weight: bold;
}

.start-at[data-v-05a72108] {
font-size: 1em;
color: #666;
}

.stopped[data-v-05a72108] {
font-size: 1em;
color: #f44336;
}

.error-msg[data-v-05a72108] {
font-size: 1em;
color: #f44336;
padding-left: 20px;
}

.process[data-v-05a72108] {
width: 100%;
height: 20px;
Expand Down
20 changes: 16 additions & 4 deletions src/rethink/dist-local/js/app.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/rethink/models/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ def add(
md = md.strip()
if len(md) > const.MD_MAX_LENGTH:
return None, const.Code.NOTE_EXCEED_MAX_LENGTH

u, code = user.get(uid=uid)
if code != const.Code.OK:
return None, code
Expand Down
59 changes: 59 additions & 0 deletions src/rethink/models/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
import uuid
from typing import Tuple

import httpx
import jwt
import pypinyin
from markdown import Markdown

from rethink import config
from rethink.logger import logger

HEADERS = {
'typ': 'jwt',
Expand Down Expand Up @@ -128,3 +130,60 @@ def change_link_title(md: str, nid: str, new_title: str) -> str:
md,
)
return new_md


ONLY_HTTP_LINK_PTN = re.compile(r"^https?://\S*$")


def contain_only_http_link(md: str) -> str:
content = md.strip()
if ONLY_HTTP_LINK_PTN.match(content) is None:
return ""
return content


ASYNC_CLIENT_HEADERS = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36",
}


async def get_title_description_from_link(url: str) -> Tuple[str, str]:
async with httpx.AsyncClient() as client:
try:
response = await client.get(
url=url,
headers=ASYNC_CLIENT_HEADERS,
timeout=3.
)
except (
httpx.ConnectTimeout,
RuntimeError,
httpx.ConnectError,
httpx.ReadTimeout,
httpx.HTTPError
) as e:
logger.info(f"failed to get {url}: {e}")
return "", ""
if response.status_code in [302, 301]:
url = response.headers["Location"]
return await get_title_description_from_link(url)
if response.status_code != 200:
return "", ""
html = response.text[:10000]

title, description = "", ""
found = re.search(r'<meta[^>]*name="title"[^>]*content="([^"]*)"[^>]*>', html, re.DOTALL)
if found is None:
found = re.search(r'<meta[^>]*content="([^"]*)"[^>]*name="title"[^>]*>', html, re.DOTALL)
if found is None:
found = re.search(r"<title>(.*?)</title>", html, re.DOTALL)
if found:
title = found.group(1).strip()

found = re.search(r'<meta[^>]*name="description"[^>]*content="([^"]*)"[^>]*>', html, re.DOTALL)
if found is None:
found = re.search(r'<meta[^>]*content="([^"]*)"[^>]*name="description"[^>]*>', html, re.DOTALL)
if found:
description = found.group(1).strip()[:400]
return title, description
15 changes: 15 additions & 0 deletions src/rethink/routes/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,21 @@ async def put_node(
)


@router.put(
path="/node/quick",
response_model=schemas.node.PutResponse,
)
@measure_time_spend
async def put_node(
req: schemas.node.PutRequest,
token_decode: Annotated[TokenDecode, Depends(token2uid)]
) -> schemas.node.PutResponse:
return await node_ops.put_quick_node(
td=token_decode,
req=req,
)


@router.get(
path="/node",
response_model=schemas.node.GetResponse,
Expand Down
36 changes: 35 additions & 1 deletion tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ def test_update_obsidian(self):
rj = resp.json()
self.assertEqual(0, rj["code"], msg=rj)

for _ in range(8):
for _ in range(10):
time.sleep(0.1)
resp = self.client.get(
"/api/files/uploadProcess",
Expand Down Expand Up @@ -511,3 +511,37 @@ def test_upload_image(self):
f1.close()
os.remove("temp/test.png")
os.rmdir("temp")

def test_put_quick_node(self):
resp = self.client.put(
"/api/node/quick",
json={
"requestId": "xxx",
"md": "node1\ntext",
"type": const.NodeType.MARKDOWN.value,
},
headers={"token": self.token}
)
rj = resp.json()
self.assertEqual(0, rj["code"])
self.assertEqual("xxx", rj["requestId"])
node = rj["node"]
self.assertEqual("node1", node["title"])
self.assertEqual("node1\ntext", node["md"])
self.assertEqual(const.NodeType.MARKDOWN.value, node["type"])

resp = self.client.put(
"/api/node/quick",
json={
"requestId": "xxx",
"md": "https://baidu.com",
"type": const.NodeType.MARKDOWN.value,
},
headers={"token": self.token}
)
rj = resp.json()
self.assertEqual(0, rj["code"])
self.assertEqual("xxx", rj["requestId"])
node = rj["node"]
self.assertIn("https://baidu.com", node["md"])
self.assertIn("百度", node["md"])
32 changes: 32 additions & 0 deletions tests/test_models_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,35 @@ def test_change_link_title(self):
[@我](/n/1) [@哇塞](/n/2)
"""), new_md)

def test_contain_only_link(self):
for md, res in [
("http://rethink.run", "http://rethink.run"),
("[123](/n/123)", ""),
("few", ""),
("c https://rethink.run", ""),
(" https://rethink.run ", "https://rethink.run"),
("https://rethink.run ", "https://rethink.run"),
("https://rethink.run", "https://rethink.run"),
("https://rethink.run wwq", ""),

]:
self.assertEqual(res, utils.contain_only_http_link(md))


class TestAsync(unittest.IsolatedAsyncioTestCase):
async def test_get_title_description_from_link(self):
for url, res in [
("https://waa.fffffffff", False),
("https://baidu.com", True),
("https://rethink.run", True),
("https://rethink.run/about", True),
("https://baidu.com/wqwqqqqq", False),
("https://mp.weixin.qq.com/s/fHrDf4XQ00a8IG-VF8-VwQ", False),
]:
title, desc = await utils.get_title_description_from_link(url)
if res:
self.assertNotEqual(title, "", msg=f"{url} {title}")
self.assertNotEqual(desc, "", msg=f"{url} {desc}")
else:
self.assertEqual(title, "")
self.assertEqual(desc, "")

0 comments on commit 63b9751

Please sign in to comment.