|
18 | 18 | from django.db.models.expressions import RawSQL
|
19 | 19 | from django.db.models.functions import Left, Length
|
20 | 20 | from django.http import Http404, StreamingHttpResponse
|
| 21 | +from django.shortcuts import redirect |
21 | 22 | from django.urls import reverse
|
22 | 23 | from django.utils.functional import cached_property
|
23 | 24 | from django.utils.text import capfirst, slugify
|
|
37 | 38 | from core import authentication, choices, enums, models
|
38 | 39 | from core.services.ai_services import AIService
|
39 | 40 | from core.services.collaboration_services import CollaborationService
|
| 41 | +from core.services.converter_services import YdocConverter |
| 42 | +from core.services.notion_import import import_notion |
40 | 43 | from core.tasks.mail import send_ask_for_access_mail
|
41 | 44 | from core.utils import extract_attachments, filter_descendants
|
42 | 45 |
|
@@ -2072,3 +2075,95 @@ def _load_theme_customization(self):
|
2072 | 2075 | )
|
2073 | 2076 |
|
2074 | 2077 | return theme_customization
|
| 2078 | + |
| 2079 | + |
| 2080 | +@drf.decorators.api_view() |
| 2081 | +def notion_import_redirect(request): |
| 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 | + ) |
| 2090 | + return redirect("https://api.notion.com/v1/oauth/authorize?" + query) |
| 2091 | + |
| 2092 | + |
| 2093 | +@drf.decorators.api_view() |
| 2094 | +def notion_import_callback(request): |
| 2095 | + code = request.GET.get("code") |
| 2096 | + resp = requests.post( |
| 2097 | + "https://api.notion.com/v1/oauth/token", |
| 2098 | + auth=requests.auth.HTTPBasicAuth( |
| 2099 | + settings.NOTION_CLIENT_ID, settings.NOTION_CLIENT_SECRET |
| 2100 | + ), |
| 2101 | + headers={"Accept": "application/json"}, |
| 2102 | + data={ |
| 2103 | + "grant_type": "authorization_code", |
| 2104 | + "code": code, |
| 2105 | + "redirect_uri": settings.NOTION_REDIRECT_URI, |
| 2106 | + }, |
| 2107 | + ) |
| 2108 | + resp.raise_for_status() |
| 2109 | + data = resp.json() |
| 2110 | + request.session["notion_token"] = data["access_token"] |
| 2111 | + return redirect(f"{settings.FRONTEND_URL}/import-notion/") |
| 2112 | + |
| 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 "Child page", |
| 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 "Imported Notion page", |
| 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"]) |
| 2159 | +def notion_import_run(request): |
| 2160 | + if "notion_token" not in request.session: |
| 2161 | + raise drf.exceptions.PermissionDenied() |
| 2162 | + |
| 2163 | + imported_docs = import_notion(request.session["notion_token"]) |
| 2164 | + |
| 2165 | + imported_docs_by_page_id = {} |
| 2166 | + for imported_doc in imported_docs: |
| 2167 | + _import_notion_root_page(imported_doc, request.user, imported_docs_by_page_id) |
| 2168 | + |
| 2169 | + return drf.response.Response({}) |
0 commit comments