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
번호 분류 제목 글쓴이 날짜 조회 수
58 코드 [Python] Selenium을 이용하여 특정 element를 캡처하는 스크립트 2 file 이니스프리 2019.07.03 6110
» 코드 [Python] 선택한 파일을 Dropbox API를 이용하여 업로드하고 공유링크를 받아서 이미지 호스팅 용도로 URL을 변환하기 1 file 이니스프리 2019.07.02 1167
56 코드 [JS]클라이언트에서 Ip를 얻어보자 2 Hanam09 2019.01.21 779
55 코드 [JS] http를 https로 리디렉션! 3 Hanam09 2018.12.30 841
54 코드 [PHP] 이미지를 원하는 크기(원본비율 유지)로 리사이즈 하여 출력 (원본 이미지는 수정하지 않습니다) 6 이니스프리 2018.12.20 7994
53 코드 [아미나] 네이트 실시간 검색어 순위 위젯 (아미나 캐시 적용) 3 file 이니스프리 2018.12.18 1125
52 코드 [아미나] 출석 여부를 나타내는 메인화면 위젯 4 file 이니스프리 2018.12.15 780
51 코드 [PHP] 간단한 캐싱 클래스 3 title: 황금 서버 (30일)humit 2018.12.06 865
50 코드 [Python] 텔레그램을 이용한 게시판 새 글 알림봇 7 이니스프리 2018.12.02 3987
49 코드 [아미나] 게시글을 작성하면 ID와 IP로 필터링하여 자동으로 랜덤 댓글을 남기기 (+랜덤 포인트) 7 file 이니스프리 2018.11.18 805
48 코드 [PHP] 그누보드 자동 게시글 작성 - 일본기상협회의 우리나라 날씨를 크롤링한 후 파파고로 번역하여 글 작성 4 file 이니스프리 2018.11.15 822
47 코드 [PHP] 기상청 RSS 시간별 예보 위젯 - cache 적용(?) 9 file 이니스프리 2018.10.28 993
46 코드 [오토핫키] 브라우저를 열어 지난번과 동일한 폴더에 MZK를 다운받고 압축을 네이티브로 해제하는 스크립트 file 이니스프리 2018.10.20 920
45 코드 [PHP] 기상청 중기예보를 캐러셀로 보여주는 위젯 (매우 허접합니다 ㅠㅠ) 10 file 이니스프리 2018.09.28 733
44 코드 [오토핫키] 구글 드라이브의 공유링크를 이미지 호스팅을 위한 다이렉트 링크로 바꿔주는 스크립트 10 file 이니스프리 2018.09.25 1756
43 코드 [오토핫키] 특정 사이트에 대한 ping 테스트 결과를 실행시간과 함께 로그 파일로 저장하는 스크립트 2 이니스프리 2018.09.22 2055
42 코드 [Python] 모 정부기관 사이트 파싱 후 PC 통신처럼 열람하고 싶은 게시글 번호를 입력하면 내용을 보여주는 소스 (허접) 4 이니스프리 2018.09.14 746
41 코드 파이선 셸에서 실행하면...? 3 제르엘 2018.07.22 546
40 코드 C언어 삼중자를 이용한 코드 title: 황금 서버 (30일)humit 2018.07.22 484
39 코드 폰트를 자동 설치하는 코드 1 네모 2018.07.16 982
Board Pagination Prev 1 2 3 4 Next
/ 4