이번 프로젝트의 목표는 특정 디렉토리를 웹에서 관리할 수 있도록 하는것!
그러기 위해서 다양한 파일 관리 기능들도 필요하지만,
웹에서 cmd창 마냥 파일 이름, 해야할 작업 등 을 커맨드로 작성하는것은 너무 비효율적이기에
디렉토리를 표현할 GUI가 필요합니다!
그러다 찾은 템플릿이 "Tree view"입니다.
Tree view
https://www.w3.org/WAI/ARIA/apg/patterns/treeview/
w3c에서 제공해주는 기본적인 계층형 디렉토리 ui source로 아래와 같이 웹에서 디렉토리를 볼 수 있게 도와줍니다 .
이정도면 완벽한 GUI....
여기서 특정 디렉토리의 구조만 전달해 준다면 쉽게 구성할 수 있을것 같습니다.
source코드는 아래를 통해 확인 가능합니다.
코드가 생각보다 길어서 이 글에서 전체를 파악하는것은 무리일 것 같습니다...
기본적인 구조는 이름 그대로 트리처럼 구성이 되니, 기능을 사용하는데에는 문제가 없을것입니다!
디렉토리 구성
그럼 이제 특정 디렉토리를 웹 GUI에 만들어 줍시다.
가장 먼저 디렉토리가 어떻게 구성되어있는지를 받아와야합니다.
디렉토리 내부구성은 Python의 os라이브러리를 이용하여 저장해주었습니다.
<Share_Dir.py>
....
dirList=[]
fileList=[]
....
@router.post("/dir/Check")
async def CheckDir():
global dirList
global fileList
dirList.clear()
fileList.clear()
path='./static/ShareFolder' ## 특정 디렉토리!
for root, dirs, files in os.walk(path):
for dir in dirs:## 디렉토리
user_part = os.path.join(root, dir).split('static')[1]
dirList.append(user_part)
for file in files: ## 파일
user_part = os.path.join(root, file).split('static')[1]
fileList.append(user_part)
dirList = sorted(dirList)
fileList = sorted(fileList)
return dirList,fileList
디렉토리와 파일들의 주소를 아래와 같이 만들어 각각의 List에 보관해 주었습니다.
/ShareFolder/Make_folder
/ShareFolder/Flo.jpg
이렇게 파일과 디렉토리 List를 만들었으니, Tree UI에 적용시켜줍시다.
다른 방법도 있겠지만 저는 웹이 로드될때 html을 재구성하는 방식을 사용하기로 하였습니다.
먼저 base Tree부분을 구성해줍시다.
<Share_Dir.html>
...
<ul role="tree" aria-labelledby="tree_label">
<li id="rootLi" role="treeitem" aria-expanded="false" aria-selected="false" aria-label="root,Dir">
<span id="ShareFolder"> ShareFolder </span>
<!-- 여기 추가됨 -->
</li>
</ul>
...
<span id="ShareFolder" ... 아랫줄부터 디렉토리/파일들을 추가해줄 것입니다 .
html에서의 구조는 <span>을 통해 특정 디렉토리를 표현하면 그 밑에 <ul>요소를 통해 내부 파일들을 묶어 관리하는 방식
그리고 내부 파일들은 각각 <li role="treeitem".. 으로 표현!
이제 웹 로드시 재구성하는 부분!
window.addEventListener('load', ... 부분을 찾고 아래부분을 상단에 추가해줍시다.
아래처럼 로드하면서 rooLi를 찾고 그 아래 새로운 ul을 추가해줍시다.
<script>
...
window.addEventListener('load', async () => {/*로드시 현재 사용자 공유폴더 디렉토리 생성!*/
const ShareFolder=document.getElementById('ShareFolder');
ShareFolder.textContent="ShareFolder"
const rootLiElement = document.getElementById('rootLi');
const ulElement = document.createElement('ul');
ulElement.setAttribute('role', 'group');
ulElement.setAttribute('id', '/ShareFolder');
rootLiElement.appendChild(ulElement);
...
여기서 실행하면 아래처럼!
여기서 이전에 만들어뒀던 /dir/Check 함수를 실행해서 디렉토리/파일 리스트를 받아와 줍시다.
...
const refreshResponse = await fetch(`/dir/Check`, {
method: 'POST',
}).then(function(response) {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
}).then(function(data) {
let dirs=data[0]
const Filelists=data[1]
....
그다음 디렉토리추가 부분
for (const dir of dirs) { // 디렉토리 추가부분 ----------------------------------------------------------
let tempdir=""
let baseroot = document.getElementById('root'); // 맨 위 루트
for (const dirname of dir.split('/').slice(1)){
tempdir=String(tempdir)+'/'+String(dirname)
let finddir = document.getElementById(tempdir);
if(finddir==null){ // 요소 추가
const newLi = document.createElement('li');
newLi.setAttribute('role', 'treeitem');
newLi.setAttribute('aria-expanded', 'false');
newLi.setAttribute('aria-selected', 'false');
newLi.setAttribute('tabindex', '-1');
newLi.setAttribute('aria-label', tempdir +",Dir");
// 새로운 <span> 요소 생성
const newSpan = document.createElement('span');
newSpan.textContent = dirname;
// 새로운 <ul> 요소 생성
const newUl = document.createElement('ul');
newUl.setAttribute('role', 'group');
newUl.id=tempdir;
newLi.addEventListener('click', handleTreeItemClick);
// <span>과 <ul>을 <li> 아래에 추가
newLi.appendChild(newSpan);
newLi.appendChild(newUl);
// 기존 요소를 새로운 <li> 요소로 대체
baseroot.appendChild(newLi);
}
else{
baseroot = finddir;
}
}
}
디렉토리를 추가하면 아래처럼 구성됩니다.
다음은 파일 추가부분을 추가해줍시다.
for (const file of Filelists) {// 파일 추가부분 ----------------------------------------------------------
const alldir = file.split('/');
const fileName = alldir.pop(); // 이름
const directory = alldir.join('/'); // 경로
const sort=fileName.split('.').reverse()[0];
let findDir = document.getElementById(directory);
const newLi = document.createElement('li');
newLi.setAttribute('role', 'treeitem');
newLi.setAttribute('aria-selected', 'false');
if(image_format_List.includes(sort)){
newLi.setAttribute('class', 'img');
}
else if(video_format_List.includes(sort)){
newLi.setAttribute('class', 'vid');
}
else if(zip_format_List.includes(sort)){
newLi.setAttribute('class', 'zip');
}
else{
newLi.setAttribute('class', 'doc');
}
newLi.setAttribute('tabindex', '-1');
newLi.textContent=fileName
newLi.setAttribute('aria-label', file+",File");
newLi.addEventListener('click', handleTreeItemClick);
findDir.appendChild(newLi);
}
});
파일을 추가하면 아래처럼 구성됩니다.
이제 재구성된 html을 기준으로 GUI를 구성해주면 끝입니다.
var trees = document.querySelectorAll('[role="tree"]');
for (var i = 0; i < trees.length; i++) {
var t = new Tree(trees[i]);
t.init();
}
});
최종적으로는 아래와 같은 html을 통해
아래와 같은 ui를 얻을 수 있습니다.
python파일은 간단한데 html은 너무 길어졌네요 ㄷㄷ
전체코드는 파일로!
만약 위 처럼 안나온다면 아마 css때문일거에요!
static폴더를 만들고 그 내부에 css를 추가해주시면 됩니다!
틀린 점이 있다면 댓 달아주세요!
'공부공부 > 2023 쌓여가는 나의 지식~' 카테고리의 다른 글
MediaPipe와 Yolo모델을 이용한 사람 관절 오토 라벨링 [Labelme Tool 사용 및 수정(3)] (2) | 2023.12.21 |
---|---|
블렌더를 이용해 간단한 3D 모델 만들기 (0) | 2023.12.09 |
Fastapi를 이용한 웹페이지 구성 (2) - 웹 페이지 연결 및 구성 & Get/Post (1) | 2023.12.07 |
Fastapi를 이용한 웹페이지 구성 (1) - 설치 및 사용 (1) | 2023.12.06 |
Mediapipe를 이용한 손 인식 (1) | 2023.11.01 |
댓글