Extra Form
라이선스 MIT

안녕하세요? 


한동안 정신이 없이 지냈는데 오래간만에 짬을 내서 파이썬을 만지작 거렸네요 ^^


제가 작년에 오토핫키를 이용하여 구글드라이브의 링크를 이미지 호스팅 용도로 변환하는 스크립트를 올렸는데,


이번에는 파이썬과 Dropbox API를 이용하여 윈도우에서 파일을 선택해서 업로드하고 


그 파일의 공유링크를 받아서 이미지 호스팅 용도로 문자열 처리를 하는 스크립트를 만들어봤네요.


GUI는 PyQt5를 이용해서 아주 간단하게조잡하게 만들었습니다.



저는 개발자도 아니고 유사한 영역에서 근무하지도 않으며, 솔직히 객체 지향 프로그래밍에 대해 전혀 모릅니다.


하지만 주먹구구식으로 절차 지향적으로 스크립트를 작성하는 것보다는


정착된 업계의 표준을 따르는 것이 학습에 있어서 바람직하다고 생각되기 때문에


이 스크립트를 작성하면서 객체 지향 프로그래밍을 흉내라도 내보려고


제가 아는 한도에서 클래스 등을 사용했는데 역시 전문 개발자 분들이 작성한 것과는 이질감이 있네요 ^^


이 부분에 대해서는 앞으로 공부를 더 해야할 것 같아요.



import dropbox, sys
from PyQt5.QtWidgets import * # 아직 GUI가 완성단계가 아니라서 일단 라이브러리 전체를 불러왔습니다.


class UploadFile:
    def __init__(self, access_token):
        self.access_token = access_token

    def check_file(self, file_to):
        # 드롭박스 API의 메타데이터 함수를 이용하여 같은 이름의 파일이 이미 존재하는지 확인하는 함수입니다.
        dbx = dropbox.Dropbox(self.access_token)            
        number = 1
        file_to_original = file_to
        while number :
            try:
                dbx.files_get_metadata(file_to)
                if number < 10 :
                    count = '0' + str(number)
                else :
                    count = str(number)
                file_to = '/'.join(file_to_original.split('/')[:-1]) + '/' + file_to_original.split('/')[-1].split('.')[-2] + '_' + count + '.' + file_to_original.split('/')[-1].split('.')[-1]
                # 파일명을 XX.jpg -> XX_01.jpg -> XX_02.jpg 이런 식으로 처리하는 부분인데 보다 간결한 방법을 찾지 못했네요 ㅠㅠ
                number += 1
            except:
                break
        return file_to

    def upload_file(self, file_from, file_to):
        # 파일을 업로드하는 함수입니다.
        dbx = dropbox.Dropbox(self.access_token)            
        with open(file_from, 'rb') as f:
            dbx.files_upload(f.read(), file_to)

    def get_link(self, file_to):
        # 업로드한 파일을 공유한 후에 해당 공유링크를 받아와서 이미지호스팅 용도로 변환하는 함수입니다.
        dbx = dropbox.Dropbox(self.access_token)
        shared_URL = dbx.sharing_create_shared_link_with_settings(file_to).url
        modified_URL = shared_URL[:-1] + '1'
        return modified_URL


def up_and_get(file_name):
    # 드롭박스 API를 이용한 업로드 및 공유 처리에 있어 메인이 되는 함수입니다.
    access_token = 'API의 토큰을 입력하세요!!!'
    transfer = UploadFile(access_token)

    file_from = file_name
    file_to = '/image_hosting/' + file_from.split('/')[-1]

    file_to = transfer.check_file(file_to)
    transfer.upload_file(file_from, file_to)
    image_URL = transfer.get_link(file_to)
    return (file_to, image_URL)


class MyWindow(QWidget):
    # PyQt5를 이용하여 간단히 GUI를 만들었습니다.
    def __init__(self):
        super().__init__()
        self.initialUI()

    def initialUI(self):
        self.setGeometry(800, 300, 350, 350)
        self.setWindowTitle('Easy Dropbox Image Hosting')

        button = QPushButton('File Open', self)
        button.clicked.connect(self.buttonClicked)
        self.file_inPC = QLabel()
        self.file_inCloud = QLabel()
        self.browser = QTextBrowser()

        layout = QVBoxLayout()
        layout.addWidget(button)
        layout.addWidget(self.file_inPC)
        layout.addWidget(self.file_inCloud)
        layout.addWidget(self.browser)
        self.setLayout(layout)        

    def buttonClicked(self):
        # 파일을 업로드한 후에 어떤 파일이 드롭박스의 어떤 폴더에 업로드 되었고, 공유링크는 무엇인지 출력하는 함수입니다.
        file_name = QFileDialog.getOpenFileName(self)[0]
        path_and_URL = up_and_get(file_name)
        self.file_inPC.setText('Selected file : ' + file_name)
        self.file_inCloud.setText('Uploaded to your Dropbox : ' + path_and_URL[0])
        self.browser.append(path_and_URL[1])


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MyWindow()
    window.show()
    app.exec_()



위 스크립트를 윈도우에서 실행하시면 다음 사진과 같은 창을 띄웁니다.


기존에 KI.jpg를 3회 업로드하여 KI.jpg, KI_01.jpg, KI_02.jpg가 업로드된 상태에서 


KI.jpg를 8번 추가로 업로드한 화면입니다.


처음에는 업로드할 파일 갯수를 미리 지정하는 방향으로 만들어보려고 했는데


GUI 크기를 변환하는 것이 귀찮아서 원래 업로드한 결과를 삭제하지 않는 방향으로 간단히 처리했습니다.


변환되어 최종 출력된 공유 URL을 img 태그 안에 넣으면 이미지 호스팅이 잘 되는 것을 확인할 수 있습니다.


(참고로 아래 이미지의 공유 URL은 모두 삭제되었습니다.)




제가 이 스크립트를 작성하면서 느낀 점을 몇 가지 적어봅니다.



1. 전역변수


예전에 C 언어를 학교에서 배울 때의 기억으로는 


변수 선언을 할 때 global로 선언하면 함수에서도 그 변수를 사용할 수 있었던 반면에, 


파이썬은 함수 안에서 global로 전역변수를 읽고 사용하는 것이 굉장히 큰 차이인 것 같네요.


처음에는 전역변수를 2개 정도 사용해서 작성하다가 


결국 전역변수를 사용하지 않고 모두 return으로 처리를 했는데요.


up_and_get() 부분은 반환할 값이 두 개가 되어서 부득이 리스트를 리턴하게 되었네요 ㅠㅠ


리스트를 리턴하는 것은 바람직하지 않다는 글을 언뜻 본 것 같은데 말이죠.



2. 문자열 처리


역시 문자열 처리는 모든 프로그래밍에서 번거로운 부분이네요.


항상 팔부능선을 넘었다고 생각하는 순간에 문자열 처리가 "어서와~ 문자열 처리는 처음이지"라고 반기는 것 같네요 ㄷㄷ


이 스크립트에서는 파일명을 XX.jpg -> XX_01.jpg -> XX_02.jpg 이런 식으로 처리하는 부분에서 


경로명에서 '/'로 split한 가장 마지막 부분을 다시 '.'로 split해서 


정수를 스트링으로 변환한 것을 합치는 방식을 이용했는데요.


제 머리로는 보다 간결하게 처리하는 방법을 찾지 못하겠네요 ㅠㅠ



3. 드롭박스의 파일 업로드 및 이미지 출력 속도 등


아무래도 드롭박스의 서버가 국내에 소재한 것이 아니다보니 


KT망에서 파일 업로드 및 이미지 출력 속도는 그다지 빠르지는 않네요.


체감상 imgur와 비슷하거나 살짝 더 느린 것 같은 느낌이네요.


다만 기존에 동일한 파일명이 있는지 metadata를 확인하는 부분을 삭제하면


업로드 속도가 절반 가량으로 줄어들기는 하더군요.


드롭박스가 몇 년 전에 자체적인 이미지 공유 기능을 막아버렸지만


다행히 URL을 조작하는 방법으로 아직까지는 이미지 호스팅이 가능하네요.

(아무래도 기존에 업로드된 파일에 대한 기득권을 당분간은 보호하려는 의미이겠죠.)


참고로 트래픽은 무료 유저의 경우에는 20GB/day, 비지니스 유저의 경우에는 200GB/day라고 알고 있네요.


제가 사용한 방법으로 HTML 등 정적 웹페이지가 드롭박스에서 돌아가는지는 아직 확인하지 못했습니다.



나중에 시간적인 여유가 있으면 PHP로 imgur 플러그인과 유사한 방법으로 작동하도록 만들어보고 싶네요 ^^


마지막으로 별 것 아닌 허접한 스크립트인데 긴 글을 읽어주셔서 감사합니다.


이렇게 좌충우돌하며 스크립트를 작성하다보면 우리가 늘상 사용하는 앱의 개발자 분들이 존경스럽고 


그 분들 덕분에 저같은 'Hello, world!"를 간신히 출력하는 수준인 사람이 편안한 생활을 하고 있다는 생각에 정말 감사하네요.


그럼 날씨가 무덥고 습한데 항상 건강하세요!


감사합니다 ^-^


  • profile
    이니스프리 2019.08.03 00:21
    만약 사파리나 IE 등 일부 브라우저에서 이미지 깨짐 현상이 발생한다면
    https://studyforus.com/help/593359
    이 글에 humit 님께서 답변해주신 내용으로 소스를 수정하는 것이 좋을 것 같네요 ^^

List of Articles
번호 분류 제목 글쓴이 날짜 조회 수
23 코드 [JS] http를 https로 리디렉션! 3 Hanam09 2018.12.30 885
22 코드 [JS]클라이언트에서 Ip를 얻어보자 2 Hanam09 2019.01.21 807
» 코드 [Python] 선택한 파일을 Dropbox API를 이용하여 업로드하고 공유링크를 받아서 이미지 호스팅 용도로 URL을 변환하기 1 file 이니스프리 2019.07.02 1192
20 코드 [Python] Selenium을 이용하여 특정 element를 캡처하는 스크립트 2 file 이니스프리 2019.07.03 6170
19 코드 [PHP/Javascript] 아미나에 자동으로 게시글을 생성하고 Ajax로 전송하여 결과를 표시하기 2 file 이니스프리 2019.07.09 963
18 코드 [Python] 네이버 모바일 이미지 검색에서의 이미지 파일을 멀티스레드로 다운받고 1개의 파일로 병합 11 file 이니스프리 2019.07.12 1557
17 코드 [아미나] Dropbox API를 이용한 이미지 호스팅 보드스킨 12 file 이니스프리 2019.07.13 1619
16 코드 [PyQt] sir.kr에서 스크랩한 게시글을 보여주는 윈도우앱 (검색 및 정렬 가능) 7 file 이니스프리 2019.08.09 1146
15 코드 [Python] PIL을 이용한 Animated GIF의 리사이징 file 이니스프리 2019.11.03 1356
14 코드 [Python] 싸이월드 미니홈피 백업 스크립트 1 이니스프리 2019.11.07 2456
13 코드 [JS] 클라이언트단 GET Parameter Hanam09 2019.11.16 714
12 코드 [파이썬] Requests를 사용한 네이버 카페 크롤링 - 일정수 이상의 리플이 달린 게시글만 텔레그램 알림 3 file 이니스프리 2019.11.17 4376
11 코드 [Python] Google Image Search 결과를 받아오기 file 이니스프리 2019.12.09 1209
10 코드 JavaScript에서 파이썬 문자열 처리 함수 중 하나 (바인딩)를 구현 7 Seia 2020.01.20 578
9 코드 Koa에서 자동으로 라우팅 채워주기 Seia 2020.01.22 739
8 코드 [Python] 네이버 실시간 검색어 3 title: 황금 서버 (30일)humit 2020.01.23 1347
7 코드 [Python] url 주소로부터 IP 주소 알아내기 title: 황금 서버 (30일)humit 2020.02.20 2259
6 코드 [Python/Telegram] Studyforus 알림봇 (댓글, 스티커 파싱) 7 file 이니스프리 2020.05.15 869
5 코드 [Python] 유튜브 영상을 다운받아 일정 간격으로 캡쳐하여 10장씩 merge하기 3 file 이니스프리 2020.05.27 1291
4 코드 도박 중독자를 위한 광고 차단 규칙 file 제르엘 2020.08.21 471
Board Pagination Prev 1 2 3 4 Next
/ 4