리셋 되지 말자

service 외에 필요한 파일들 본문

졸업작품

service 외에 필요한 파일들

kyeongjun-dev 2020. 8. 24. 19:43

/opt/sdob 경로에 설치되는 파일들

rpm으로 패키지 설치시에, /opt/sdob 경로가 생성되고 그 안에 아래 그림에 표시된 파일들이 설치된다.

  • directory.png

그냥 폴더 그림

  • file.png

그냥 파일 그림

  • index.html

파이썬 서버로 접속하면 client에게 보여지는 페이지. 파일 및 디렉토리 제어 기능 가능 (websocket 사용)

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title></title>
    <style>
        div {
            float: left;
        }

        .contextmenu {
            display: none;
            position: absolute;
            width: 200px;
            margin: 0;
            padding: 0;
            background: #FFFFFF;
            border-radius: 5px;
            list-style: none;
            box-shadow: 0 15px 35px rgba(50,50,90,0.1), 0 5px 15px rgba(0,0,0,0.07);
            overflow: hidden;
            z-index: 999999;
        }

            .contextmenu li {
                border-left: 3px solid transparent;
                transition: ease .2s;
            }

                .contextmenu li a {
                    display: block;
                    padding: 10px;
                    color: #B0BEC5;
                    text-decoration: none;
                    transition: ease .2s;
                }

                .contextmenu li:hover {
                    background: #CE93D8;
                    border-left: 3px solid #9C27B0;
                }

                    .contextmenu li:hover a {
                        color: #FFFFFF;
                    }

        div:hover {
            background: #CE93D8;
        }
    </style>
    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
    <script>


                var targetId="";
                <!-- 클릭시 드롭다운 메뉴 출력 -->
                $(document).ready(function(){
                  //Show contextmenu:
                  $(document).contextmenu(function(e){
                        //Get window size:
                        var winWidth = $(document).width();
                        var winHeight = $(document).height();
                        //Get pointer position:
                        var posX = e.pageX;
                        var posY = e.pageY;
                        //Get contextmenu size:
                        var menuWidth = $(".contextmenu").width();
                        var menuHeight = $(".contextmenu").height();
                        //Security margin:
                        var secMargin = 10;
                        //Prevent page overflow:
                        if(posX + menuWidth + secMargin >= winWidth
                        && posY + menuHeight + secMargin >= winHeight){
                          //Case 1: right-bottom overflow:
                          posLeft = posX - menuWidth - secMargin + "px";
                          posTop = posY - menuHeight - secMargin + "px";
                        }
                        else if(posX + menuWidth + secMargin >= winWidth){
                          //Case 2: right overflow:
                          posLeft = posX - menuWidth - secMargin + "px";
                          posTop = posY + secMargin + "px";
                        }
                        else if(posY + menuHeight + secMargin >= winHeight){
                          //Case 3: bottom overflow:
                          posLeft = posX + secMargin + "px";
                          posTop = posY - menuHeight - secMargin + "px";
                        }
                        else {
                          //Case 4: default values:
                          posLeft = posX + secMargin + "px";
                          posTop = posY + secMargin + "px";
                        };
                        //Display contextmenu:
                        $(".contextmenu").css({
                          "left": posLeft,
                          "top": posTop
                        }).show();
                        //Prevent browser default contextmenu.
                        return false;
                  });
                  //Hide contextmenu:
                  $(document).click(function(){
                        $(".contextmenu").hide();
                  });
                  $("#remove").click(function(){
                        sendMessage("remove",targetId);
                        alert(targetId+" deleted");
                  });

                  $("#namemodify").click(function(){
                        var inputString = prompt("바꿀 이름을 입력하세요");
                        sendMessageChangeName("namemodify",targetId,inputString);
                  });

                  $("#copy").click(function(){
                        sendMessage("copy",targetId);
                        alert(targetId+" copied");
                  });
                  //입력창 -> 입력한 값 받아서 서버로 전송 -> 처리 후 컴컴
                  $("#modify").click(function(){
                        sendMessage("modify",targetId);
                  });

                  //우클릭 메뉴에서 MakeTextFile 클릭
                  $("#maketextfile").click(function(){
                        //textArea 보이게 하기
                        textAreaOpen("");

                        // makefilenamearea 창 보이게 하기
                        var makefilenamearea = document.getElementById("makefilenamearea");
                        makefilenamearea.style.display='';

                        //Make 버튼 보이게하기
                        var makebtn = document.getElementById("makebtn");
                        makebtn.style.display='';

                        //cancel 버튼 보이게 하기
                        document.getElementById("cancel").style.display='';
                        //sendMessage("maketextfile", targetId);
                  });
                });
                function textAreaOpen(text){
                        var background = document.getElementById("ta");
                        background.style.display='';
                        background.innerHTML=text;
                }
                <!-- function modalOpen(text){ -->
                        <!-- var background = document.getElementById("background"); -->
                        <!-- var popup = document.getElementById("popup"); -->
                        <!-- background.style.display=''; -->
                        <!-- popup.style.display=''; -->
                        <!-- document.getElementById("EMP_NM").innerHTML=text; -->
                <!-- } -->
                <!-- function modalclose(){ -->
                        <!-- document.getElementById("popup").style.display='none'; -->
                        <!-- document.getElementById("background").style.display='none'; -->
                        <!-- document.getElementById("EMP_NM").style.display=''; -->
                <!-- } -->
                var ws=0;
                var ws_text=0;
                var ip="";
                var port="";
                var dirList = new Array();
                var fileList = new Array();
                function ws_connect(){
                        //text_port 는 입력된 port보다 1이 크다
                        ip = document.getElementById('ipArea').value;
                        port = document.getElementById('portArea').value;
                        text_port = port*1;
                        text_port += 1;
                        text_port+="";
                        ws_text = new WebSocket("ws://"+ip+":"+text_port);

                        //text용 웹소켓이 접속되면 접속되는 함수
                        ws_text.onopen = function(message){
                                alert('connected');
                        };

                        //text용 웹소켓이 끝나면 호출되는 함수
                        ws_text.onclose=function(message){
                                alert('disconnected');

                        };

                        //text용 웹소켓이 통신중 에러가 발생되면 호출되는 함수
                        ws_text.onerror = function(message){
                                alert('error occured...');

                        };

                        //text용 웹소켓 서버로부터 메시지가 오면 호출되는 함수
                        ws_text.onmessage = function(message){


                                //서버로 부터의 JSON 데이터를 parsing해서 저장
                                // ex) {"kinds": "directory", "list": ["All Users", "Default", "Default User", "Public", "rudwn"]}

                                var parsed_data = JSON.parse(message.data);
                                //alert(parsed_data.kinds, parsed_data.text);
                                //JSON 데이터의 kinds가 디렉토리이면
                                if(parsed_data.kinds==="directory"){
                                        make_div(parsed_data.list, "directory");
                                }
                                else if(parsed_data.kinds==="filelist"){
                                        make_div(parsed_data.list, "file");
                                }
                                else if(parsed_data.kinds==="modify"){
                                        textAreaOpen(parsed_data.text);
                                        //alert(parsed_data.text);
                                        <!-- modalOpen(parsed_data.text); -->
                                }
                        };

                        function disconnect(){
                                ws_text.close();
                        }
                }

                function upload(){
                        var file = document.getElementById('file').files[0];// 파일을 받아옴
                        var buffersize=102400;// 파일을 전송할 단위인 버퍼사이즈 설정(1024:1byte)
                        filename = file.name;// 파일의 이름
                        filesize = file.size;// 파일의 크기
                        var reader = new FileReader();
                        reader.readAsArrayBuffer(file);// file을 ArrayBuffer로 읽어옴
                        var rawData = new ArrayBuffer();// 버퍼사이즈 만큼 데이터를 저장할 rawData 설정

                        // 파일을 읽으면 요청되는 이벤트
                        reader.onload = function(e){
                                console.log(e.target.result);
                                rawData = e.target.result;
                        }

                        var pos=0;//파일의 시작위치

                        //웹소켓 생성(ip주소 및 포트 설정)
                        //파일 보내는 전용
                        //var ws = new WebSocket("ws://192.168.0.82:8080");
                        console.log("ws://"+ip+":"+port);
                        var ws = new WebSocket("ws://"+ip+":"+port);

                        //웹소켓에 접속이 되면, START를 전송
                        ws.onopen = function(){
                                ws.send("START");
                        };

                        // START -> FILENAME -> FILESIZE -> DATA -> DATA -> ...
                        ws.onmessage = function(message){
                                // 메시지 echo
                                console.log(message.data);
                                ws.send(message.data);

                                if(message.data === 'FILENAME'){
                                        //파일 이름 전송
                                        ws.send(filename);
                                }else if(message.data === 'FILESIZE'){
                                        //파일 사이즈 전송
                                        ws.send(filesize);
                                }else if(message.data ==='DATA'){
                                        //buffersize만큼 파일을 나누어 전송
                                        ws.send(file.slice(pos, pos+buffersize));
                                        pos = pos + buffersize;
                                        if(pos > filesize){
                                                pos = filesize;
                                        }
                                }
                        }

                        ws.onclose=function(){
                                console.log("disconnected");
                        }
                };


                //text용 웹소켓이 끝나면 호출되는 함수
                ws_text.onclose=function(message){
                        alert('disconnected');
                };

                //text용 웹소켓이 통신중 에러가 발생되면 호출되는 함수
                ws_text.onerror = function(message){
                        alert('error occured...');
                };


                //text용 웹소켓 서버로 메시지를 전송하는 함수
                //kind가 'chdir'이면, 위치를 변경한다는 뜻(kind:chdir, message:이동할 파일 이름)
                function sendMessage(kind, message){
                        var msg ={
                                kinds : kind,
                                text : message
                        };

                        json_msg = JSON.stringify(msg);

                        //message 전송
                        ws_text.send(json_msg);
                };
                function sendMessageChangeName(kind, src, dst){
                        var msg ={
                                kinds : kind,
                                text : src,
                                text2 : dst
                        };
                        json_msg = JSON.stringify(msg);
                        ws_text.send(json_msg);
                }
                function disconnect(){
                        ws_text.close();
                }
                function makefile(text){
                        var msg = {
                                kinds : "modify2",
                                text : text.value
                        };
                        ws_text.send(JSON.stringify(msg));
                        text.value='';
                        ta.style.display='none';
                        alert("Modified Successfully");
                }
                //파일과 딕렉토리 div를 동적 생성
                //list에는 파일 배열 또는 디렉토리 배열
                //kinds에는 file 또는 directory
                //kinds가 file이면 그림은 file.png 이고, directory이면 그림이 direcrory.png
                function make_div(list, kinds){
                        for(var i=0; i<list.length; i++){
                                var img = document.createElement('img');
                                if(kinds==="directory"){
                                        img.src = '/directory.png';
                                }
                                else if(kinds==="file"){
                                        img.src = '/file.png';
                                }

                                var par = document.getElementById("list");
                                var newDiv = document.createElement("div");

                                var childDiv = document.createElement("div");

                                childDiv.style.fontSize = "20px";
                                childDiv.style.width = "240px";
                                childDiv.style.overflow = "hidden";
                                childDiv.innerHTML = list[i].substr(0, 20);

                                newDiv.appendChild(img);

                                newDiv.appendChild(childDiv);
                                newDiv.id = list[i]+"";
                                newDiv.oncon
                                //newDiv.style.backgroundColor = "yellow";
                                newDiv.style.height = "250px";
                                newDiv.style.width = "250px";

                                newDiv.onclick= function(){
                                        sendMessage("chdir", this.id);

                                        //파일, 디렉토리가 나타나는 div id 가 list인데,
                                        //이 list의 Child(파일, 디렉토리)를 모두 제거
                                        //하는 반복문
                                        var p = document.getElementById('list');
                                        while(p.firstChild){
                                                p.removeChild(p.firstChild);
                                        }
                                };
                                newDiv.addEventListener("auxclick",function(){
                                        targetId=this.id;
                                });
                                par.appendChild(newDiv);
                        }
                }
                <!-- function remove(){ -->
                        <!-- $('.div').click(function(){ -->
                                <!-- var id_check=$(this).attr("id"); -->
                                <!-- sendMessage("remove",id_check); -->
                        <!-- } -->
                        <!-- sendMessage("remove",this.id); -->
                <!-- } -->

                function sendmakefile(){
                        if(document.getElementById("makefilenamearea").value==''){
                                alert('file name is null');
                                return;
                        }
                        alert(document.getElementById("ta").value);
                        alert(document.getElementById("makefilenamearea").value);
                        sendMessage("makename", document.getElementById("makefilenamearea").value);
                        sendMessage("maketext", document.getElementById("ta").value)
                        document.getElementById("makefilenamearea").value = "";
                        document.getElementById("makefilenamearea").style.display='none';
                        document.getElementById("makebtn").style.display='none';
                        document.getElementById("ta").value="";
                        document.getElementById("ta").style.display='none';
                }

                function makingfilecancel(){
                        document.getElementById("makefilenamearea").value = "";
                        document.getElementById("makefilenamearea").style.display='none';
                        document.getElementById("makebtn").style.display='none';
                        document.getElementById("ta").value="";
                        document.getElementById("ta").style.display='none';
                        document.getElementById("cancel").style.display='none';
                }
    </script>
</head>
<body>
    <!--안내 text 박스. 나중에 이걸로 해야함
    <input id="ipArea" type="text" placeholder="ip address"></input>
    <input id="portArea" type="text" placeholder="port number"></input>
    -->
    <input id="ipArea" type="text" value="192.168.252.1"></input>
    <input id="portArea" type="text" value="8080"></input>
    <button id="connect_btn" onclick="ws_connect()">Connect</button>
    <br />
    <input id="file" type="file">
    <button id="uploadbtn" onclick="upload()">파일 업로드</button>
    <br />
    <form>
        <!-- 접속 종료 버튼 -->
        <input onclick="disconnect()" value="Disconnect" type="button">
        <input onclick="makefile(ta)" value="Submit" type="button"></input>
    </form>

    <textarea id="ta" rows="20" cols="30" style="display:none;" onkeydown="if(event.keyCode==9){var v=this.value,s=this.selectionStart,e=this.selectionEnd;this.value=v.substring(0, s)+'\t'+v.substring(e);this.selectionStart=this.selectionEnd=s+1;return false;}"></textarea>
    <form>
        <!-- 우클릭 메뉴 중 MakeTextFile을 선택하면 나타나는 파일 이름 입력하는 txt 박스-->
        <input id="makefilenamearea" type="text" placeholder="File name" style="display:none;"></input>
        <!-- 우클릭 메뉴 중 MakeTextFile을 선택하면 나타나는 make 버튼-->
        <input id="makebtn" onclick="sendmakefile()" value="Make" style="display:none;" type="button"></input>
        <input id="cancel" onclick="makingfilecancel()" value="Cancel" style="display:none;" type="button"></input>
    </form>
    <!-- 우클릭 시 나오는 드롭다운 메뉴 -->
    <ul class="contextmenu">
        <li><a id="remove" href="#">Remove</a></li>
        <li><a id="copy" href="#">Copy</a></li>
        <li><a id="modify" href="#">Modify</a></li>
        <li><a id="namemodify" href="#">NameModify</a></li>
        <li><a id="maketextfile" href="#">MakeTextFile</a></li>
    </ul>
    <!-- 파일 div들이 생성될 list div -->
    <div id="list" style="background-color: ivory">
    </div>
</body>
</html>
  • server.py

웹소켓 서버를 담당하는 파이썬 스크립트 파일 (ip와 port를 지정할 수 있도록 수정 필요)

import asyncio;
# 웹 소켓 모듈을 선언한다.
import websockets;
import socket;

#아래서부터 파일 관련 패키지
import os;
import sys;
import json;
import shutil
import string
#기본 경로
#os.chdir('D:')
os.chdir('/')
ndir=nfile=0

# 업로드 할 때 데이터 정보에 관한 클래스
class Node():
    #생성자
    def __init__(self):
        self.__filename=''; # 받는 파일의 이름
        self.__filesize =0; # 받는 파일의 크기
        self.__data='';     # 받는 파일의 내용(클라이언트에서 정한 버퍼 사이즈 만큼씩 받는다)
        self.__datasize=0;  # 받은 파일의 사이즈

    # filename getter
    @property
    def filename(self):
        return self.__filename;

    # filename setter
    @filename.setter
    def filename(self, filename):
        self.__filename=filename;

    # filesize getter
    @property
    def filesize(self):
        return self.__filesize;

    # filesize setter
    @filesize.setter
    def filesize(self, filesize):
        self.__filesize=int(filesize);

    # data getter
    @property
    def data(self):
        return self.__data;

    # data setter
    @data.setter
    def data(self, data):
        self.__data = data;

    @property
    def datasize(self):
        return self.__datasize;

    @datasize.setter
    def datasize(self, length):
        self.__datasize += length;

    # add data to self.__data
    def add_data(self, data):
        self.__data += data;

    # 파일전송이 끝났는지 확인하는 함수
    def is_completed(self):
        if self.__filesize == self.__datasize:
            print('transfering finished')
            return True;
        else:
            return False;
    def save(self, data):
        # 파일을 binary형식, 이어붙이는 모드로 연뒤에 파일을 계속 이어쓴다
        with open("C:/Users/rudwn/OneDrive/문서/WS/"+self.__filename, "ab+") as handle:
            handle.write(data);
        # 받은 datasize를 받은 데이터 size를 더해가며 저장한다(전송 종료 조건에 사용)
        self.__datasize += len(data)


# 클라이언트가 '파일 업로드'버튼을 클릭하면 호출된다.
async def file_accept(websocket, path):
    node = Node(); # node에 Node() 클래스 할당
    while True:
        # 클라이언트로부터 메시지를 대기한다.
        message = await websocket.recv();
        if message == 'START': #클라이언트로부터 'START' 메시지가 날라오면
            await websocket.send("FILENAME"); #파일 이름을 요청
        elif message == 'FILENAME': #파일 이름을 받는다
            node.filename = await websocket.recv();
            await websocket.send("FILESIZE")
        elif message == 'FILESIZE': #파일 사이즈를 받는다
            node.filesize = await websocket.recv();
            await websocket.send("DATA");#데이터를 요청한다
        elif message == 'DATA':#데이터가 오면 저장한다
            node.save(await websocket.recv());
            if node.is_completed() == False:#전송이 끝나지 않았으면 계속 전송
                await websocket.send("DATA");
            else:
                await websocket.close();#전송이 끝났으면 웹소켓을 닫고 종료
                break;

async def text_accept(websocket, path):
    available_drives = ['/']
    #print(available_drives)
    #print(os.listdir())
    #allList=os.listdir(os.getcwd())
    #print(allList)
    #dirList=['..']
    #fileList=[]
    #for i in os.listdir():
    #    if os.path.isfile(i):
    #        fileList.append(i)
    #    else:
    #        dirList.append(i)
    json_dirList = json.dumps({"kinds": "directory", "list": available_drives})
    #json_fileList = json.dumps({"kinds": "directory", "list": fileList})

    #드라이블 경로로 가기 위해서는 C: 이 아닌 C:\ 이렇게 필요해서 끝에 \를 붙여줌
    #for i in range(len(available_drives)):
    #    available_drives[i] = available_drives[i] + '\\'
    #    print(available_drives[i])


    #json_fileList = json.dumps({"kinds": "filelist", "list": fileList})
    #await websocket.send("{}".format(dirList))
    await websocket.send("{}".format(json_dirList))
    #await websocket.send("{}".format(json_fileList))
    while True:
        #클라이언트가 'send'버튼으로 text를 전송할 때까지 대기
        data = await websocket.recv();#받는 데이터는 json형태(kinds, text)
        json_data = json.loads(data)#받은 데이터를 json으로 변환

        if json_data['kinds']=='chdir' and json_data['text']=='..' and os.getcwd() in available_drives :
            json_dirList = json.dumps({"kinds": "directory", "list": available_drives})
            await websocket.send("{}".format(json_dirList))
        elif json_data['kinds']=='chdir':
            #print(type(json_data['text']))
            #print(os.getcwd())
            os.chdir(json_data['text'])
            dirList=['..']
            fileList=[]
            for i in os.listdir():
                if os.path.isfile(i):
                    fileList.append(i)
                else:
                    dirList.append(i)

            json_dirList = json.dumps({"kinds": "directory", "list": dirList})
            json_fileList = json.dumps({"kinds": "filelist", "list": fileList})
            await websocket.send("{}".format(json_dirList));
            await websocket.send("{}".format(json_fileList));

        #print("received : " + data);


def network_info():
    host = socket.gethostname()
    ip_addr = socket.gethostbyname(host)
    print('HOST:' + host)
    print("ip Address:" + ip_addr)
    return ip_addr


ip = network_info()

# 파일 전송용 웹 소켓 서버 생성.호스트는 localhost에 port는 8080으로 생성한다.
start_server = websockets.serve(file_accept, '192.168.252.29', 9998);

# 파일 전송용이 아닌 웹 소켓 서버 성생. 호스트는 localhost에 port는 80801로 생성
start_server_text = websockets.serve(text_accept,  '192.168.252.29', 9999);

# 비동기로 서버를 대기한다.
asyncio.get_event_loop().run_until_complete(start_server);
asyncio.get_event_loop().run_until_complete(start_server_text);
asyncio.get_event_loop().run_forever();

보완사항

conf파일을 추가해서 패키지 설치 후에 conf파일에서 service파일들과 파이썬 스크립트, 파이썬 웹서버 명령어에 Dependency Injection 할 수 있도록 파일입출력 기능이나 .sh 파일을 추가해야함.

'졸업작품' 카테고리의 다른 글

rpm 패키징 다시 하기  (0) 2020.08.25
파일들 내용 수정  (0) 2020.08.25
서비스 설명  (0) 2020.08.25
서비스 묶기 (dependence)  (0) 2020.08.24
가시화 패키지 개발-참고 문헌 저장  (0) 2020.08.21
Comments