Skip to content

Commit 5c292c0

Browse files
claraniemersionCastavoNicolasRitouetTguisnet
committed
Add import_notion service
Co-authored-by: Simon Ser <[email protected]> Co-authored-by: Baptiste Prevot <[email protected]> Co-authored-by: Nicolas Ritouet <[email protected]> Co-authored-by: Thibault Guisnet <[email protected]>
1 parent 101714e commit 5c292c0

File tree

4 files changed

+497
-13
lines changed

4 files changed

+497
-13
lines changed

src/backend/core/api/viewsets.py

Lines changed: 69 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818
from django.db.models.expressions import RawSQL
1919
from django.db.models.functions import Left, Length
2020
from django.http import Http404, StreamingHttpResponse
21+
from django.shortcuts import redirect
2122
from django.urls import reverse
2223
from django.utils.functional import cached_property
23-
from django.shortcuts import redirect
2424
from django.utils.text import capfirst, slugify
2525
from django.utils.translation import gettext_lazy as _
2626

@@ -38,6 +38,8 @@
3838
from core import authentication, choices, enums, models
3939
from core.services.ai_services import AIService
4040
from core.services.collaboration_services import CollaborationService
41+
from core.services.converter_services import YdocConverter
42+
from core.services.notion_import import import_notion
4143
from core.tasks.mail import send_ask_for_access_mail
4244
from core.utils import extract_attachments, filter_descendants
4345

@@ -2074,41 +2076,95 @@ def _load_theme_customization(self):
20742076

20752077
return theme_customization
20762078

2077-
notion_client_id = "206d872b-594c-80de-94ff-003760c352e4"
2078-
notion_client_secret = "XXX"
2079-
notion_redirect_uri = "https://emersion.fr/notion-redirect"
20802079

20812080
@drf.decorators.api_view()
20822081
def notion_import_redirect(request):
2083-
query = urlencode({
2084-
"client_id": notion_client_id,
2085-
"response_type": "code",
2086-
"owner": "user",
2087-
"redirect_uri": notion_redirect_uri,
2088-
})
2082+
query = urlencode(
2083+
{
2084+
"client_id": settings.NOTION_CLIENT_ID,
2085+
"response_type": "code",
2086+
"owner": "user",
2087+
"redirect_uri": settings.NOTION_REDIRECT_URI,
2088+
}
2089+
)
20892090
return redirect("https://api.notion.com/v1/oauth/authorize?" + query)
20902091

2092+
20912093
@drf.decorators.api_view()
20922094
def notion_import_callback(request):
20932095
code = request.GET.get("code")
20942096
resp = requests.post(
20952097
"https://api.notion.com/v1/oauth/token",
2096-
auth=requests.auth.HTTPBasicAuth(notion_client_id, notion_client_secret),
2098+
auth=requests.auth.HTTPBasicAuth(
2099+
settings.NOTION_CLIENT_ID, settings.NOTION_CLIENT_SECRET
2100+
),
20972101
headers={"Accept": "application/json"},
20982102
data={
20992103
"grant_type": "authorization_code",
21002104
"code": code,
2101-
"redirect_uri": notion_redirect_uri,
2105+
"redirect_uri": settings.NOTION_REDIRECT_URI,
21022106
},
21032107
)
21042108
resp.raise_for_status()
21052109
data = resp.json()
21062110
request.session["notion_token"] = data["access_token"]
21072111
return redirect("/api/v1.0/notion_import/run")
21082112

2109-
#@drf.decorators.api_view(["POST"])
2113+
2114+
def _import_notion_child_page(imported_doc, parent_doc, user, imported_docs_by_page_id):
2115+
document_content = YdocConverter().convert_blocks(imported_doc.blocks)
2116+
2117+
obj = parent_doc.add_child(
2118+
creator=user,
2119+
title=imported_doc.page.get_title() or "J'aime les carottes",
2120+
content=document_content,
2121+
)
2122+
2123+
models.DocumentAccess.objects.create(
2124+
document=obj,
2125+
user=user,
2126+
role=models.RoleChoices.OWNER,
2127+
)
2128+
2129+
imported_docs_by_page_id[imported_doc.page.id] = obj
2130+
2131+
for child in imported_doc.children:
2132+
_import_notion_child_page(child, obj, user, imported_docs_by_page_id)
2133+
2134+
2135+
def _import_notion_root_page(imported_doc, user, imported_docs_by_page_id):
2136+
document_content = YdocConverter().convert_blocks(imported_doc.blocks)
2137+
2138+
obj = models.Document.add_root(
2139+
depth=1,
2140+
creator=user,
2141+
title=imported_doc.page.get_title() or "J'aime les courgettes",
2142+
link_reach=models.LinkReachChoices.RESTRICTED,
2143+
content=document_content,
2144+
)
2145+
2146+
models.DocumentAccess.objects.create(
2147+
document=obj,
2148+
user=user,
2149+
role=models.RoleChoices.OWNER,
2150+
)
2151+
2152+
imported_docs_by_page_id[imported_doc.page.id] = obj
2153+
2154+
for child in imported_doc.children:
2155+
_import_notion_child_page(child, obj, user, imported_docs_by_page_id)
2156+
2157+
2158+
# @drf.decorators.api_view(["POST"])
21102159
@drf.decorators.api_view()
21112160
def notion_import_run(request):
21122161
if "notion_token" not in request.session:
21132162
raise drf.exceptions.PermissionDenied()
2163+
2164+
imported_docs = import_notion(request.session["notion_token"])
2165+
2166+
imported_docs_by_page_id = {}
2167+
for imported_doc in imported_docs:
2168+
_import_notion_root_page(imported_doc, request.user, imported_docs_by_page_id)
2169+
21142170
return drf.response.Response({"sava": "oui et toi ?"})

src/backend/core/notion_schemas/notion_block.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class NotionBlock(BaseModel):
1919
specific: "NotionBlockSpecifics"
2020
has_children: bool
2121
children: list["NotionBlock"] = Field(init=False, default_factory=list)
22+
# This is not part of the API response, but is used to store children blocks
2223

2324
@model_validator(mode="before")
2425
@classmethod

0 commit comments

Comments
 (0)