From 4c4f287c9179ca5e192114a6036b6a3e01e15aab Mon Sep 17 00:00:00 2001 From: sm4640 Date: Mon, 29 Dec 2025 12:04:15 +0900 Subject: [PATCH] =?UTF-8?q?=E2=9C=8F=EF=B8=8F=20Fix:=20[#95]=20=EC=BB=A4?= =?UTF-8?q?=EB=B0=8B=20=ED=8C=8C=EC=9D=BC=20=EB=AA=A9=EB=A1=9D=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=EB=84=A4=EC=9D=B4=EC=85=98,=20=EC=BB=A4?= =?UTF-8?q?=EB=B0=8B=20=ED=8C=8C=EC=9D=BC=20=ED=99=95=EC=9E=A5=EC=9E=90?= =?UTF-8?q?=EC=99=80=20=EC=BD=94=EB=93=9C=20=EC=96=B8=EC=96=B4=20=EB=A7=A4?= =?UTF-8?q?=ED=95=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/utils/mapManager.py | 69 ++++++++++++++++++++++++++++++++++++++ users/views.py | 57 +++++++++++++++++++++++++++++-- 2 files changed, 123 insertions(+), 3 deletions(-) create mode 100644 common/utils/mapManager.py diff --git a/common/utils/mapManager.py b/common/utils/mapManager.py new file mode 100644 index 0000000..ce9c721 --- /dev/null +++ b/common/utils/mapManager.py @@ -0,0 +1,69 @@ +import os + + +def guess_language_from_path(path: str) -> str: + _, ext = os.path.splitext(path or "") + ext = ext.lower() + + ext_to_lang = { + # Web + ".js": "javascript", + ".mjs": "javascript", + ".cjs": "javascript", + ".ts": "typescript", + ".tsx": "typescript", + ".jsx": "javascript", + ".html": "html", + ".htm": "html", + ".css": "css", + ".scss": "scss", + ".sass": "sass", + ".less": "less", + + # Backend / General + ".py": "python", + ".java": "java", + ".kt": "kotlin", + ".kts": "kotlin", + ".go": "go", + ".rb": "ruby", + ".php": "php", + ".cs": "csharp", + ".rs": "rust", + ".c": "c", + ".h": "c", # 프로젝트에 따라 c/cpp 헤더지만 일단 c로 + ".cpp": "cpp", + ".cc": "cpp", + ".cxx": "cpp", + ".hpp": "cpp", + ".hh": "cpp", + ".swift": "swift", + + # Shell / Infra + ".sh": "bash", + ".bash": "bash", + ".zsh": "zsh", + ".ps1": "powershell", + ".dockerfile": "dockerfile", # 보통 안 걸림. 아래 별도 처리도 참고. + ".yml": "yaml", + ".yaml": "yaml", + ".json": "json", + ".toml": "toml", + ".ini": "ini", + + # Data / Docs + ".md": "markdown", + ".txt": "text", + ".sql": "sql", + ".xml": "xml", + ".csv": "csv", + } + + # 확장자 없는 케이스들 (대표적으로 Dockerfile 등) + base = os.path.basename(path or "").lower() + if base == "dockerfile": + return "dockerfile" + if base in {"makefile"}: + return "makefile" + + return ext_to_lang.get(ext, "text") \ No newline at end of file diff --git a/users/views.py b/users/views.py index bacb7ec..47e2eea 100644 --- a/users/views.py +++ b/users/views.py @@ -26,6 +26,7 @@ from .services import * from .permissions import * from common.utils.fileManager import file_delete +from common.utils.mapManager import guess_language_from_path from projects.serializers import * from portfolios.serializers import * @@ -212,9 +213,51 @@ class GithubAPIViewSet(viewsets.ViewSet): if not (repo_full and sha): return Response({"is_query_param": False}, status=status.HTTP_400_BAD_REQUEST) + + try: + page = int(request.query_params.get("page", 1)) + except ValueError: + return Response({"is_page_int": False,"detail": "page and page_size must be integers"}, status=status.HTTP_400_BAD_REQUEST) - commit = self.github.get_repo(repo_full).get_commit(sha) - return Response([{"filename": f.filename, "status": f.status} for f in commit.files]) + if page < 1: + return Response({"is_page_gte_1": False, "detail": "page and page_size must be >= 1"}, status=status.HTTP_400_BAD_REQUEST) + + try: + repo = self.github.get_repo(repo_full) + commit = repo.get_commit(sha) + files = list(commit.files) + total_count = len(files) + + total_page = GithubTokenService.cal_github_total_page(total_count, PAGE_SIZE) + + if total_page != 0 and page > total_page: + return Response( + { + "is_page_le_total_page": False, + "detail": "page is out of range", + "page": page, + "total_page": total_page, + }, + status=status.HTTP_400_BAD_REQUEST, + ) + + start = (page - 1) * PAGE_SIZE + end = start + PAGE_SIZE + paged_files = files[start:end] + + except Exception as e: + return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST) + + results = [{"filename": f.filename, "status": f.status} for f in paged_files] + + return Response( + { + "page": page, + "page_size": PAGE_SIZE, + "total_page": total_page, + "results": results + }, status=status.HTTP_200_OK + ) @action(detail=False, methods=["get"], url_path="file-content") def file_content(self, request): @@ -229,7 +272,15 @@ class GithubAPIViewSet(viewsets.ViewSet): content = file.decoded_content.decode("utf-8", errors="replace") else: content = file.content - return Response({"path": file.path, "ref": sha, "content": content}) + + language = guess_language_from_path(file.path) + + return Response({ + "path": file.path, + "ref": sha, + "language": language, + "content": content, + }) except GithubException as e: return Response({"detail": str(e)}, status=e.status)