본문 바로가기
공부공부/2023 쌓여가는 나의 지식~

(FastApi & Tree view)를 이용한 디렉토리 관리 웹 페이지 구축 (1) - GUI 관련

by Lee_story_.. 2023. 12. 8.
728x90


이번 프로젝트의 목표는 특정 디렉토리를 웹에서 관리할 수 있도록 하는것! 

그러기 위해서 다양한 파일 관리 기능들도 필요하지만,

 

웹에서 cmd창 마냥 파일 이름, 해야할 작업 등 을 커맨드로 작성하는것은 너무 비효율적이기에 

 

 

디렉토리를 표현할 GUI가 필요합니다!

그러다 찾은 템플릿이 "Tree view"입니다. 

 

 

 

Tree view


 

https://www.w3.org/WAI/ARIA/apg/patterns/treeview/

 

Tree View Pattern

Accessibility resources free online from the international standards organization: W3C Web Accessibility Initiative (WAI).

www.w3.org

 

w3c에서 제공해주는 기본적인 계층형 디렉토리 ui source로 아래와 같이 웹에서 디렉토리를 볼 수 있게 도와줍니다 .

 

 

이정도면 완벽한 GUI....

여기서 특정 디렉토리의 구조만 전달해 준다면 쉽게 구성할 수 있을것 같습니다.

 

 

source코드는 아래를 통해 확인 가능합니다.

 

 

Create a New Pen

Behavior Auto Save If active, Pens will autosave every 30 seconds after being saved once. Auto-Updating Preview If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update. Format on Save If enabled, your co

codepen.io

 

코드가 생각보다 길어서 이 글에서 전체를 파악하는것은 무리일 것 같습니다...

 

기본적인 구조는 이름 그대로 트리처럼 구성이 되니, 기능을 사용하는데에는 문제가 없을것입니다!

 

 

디렉토리 구성


 

그럼 이제 특정 디렉토리를 웹 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은 너무 길어졌네요 ㄷㄷ

 

 

전체코드는 파일로!

Share_Dir_Blog.html
0.02MB

 

 

만약 위 처럼 안나온다면 아마 css때문일거에요!

 

static폴더를 만들고 그 내부에 css를 추가해주시면 됩니다!

style.css
0.00MB

 

 

 

 

 

틀린 점이 있다면 댓 달아주세요!

댓글