테스트 사이트 - 개발 중인 베타 버전입니다

[Python] PDF 파일을 이미지로 변환하여 그누보드에 자동 글 작성

안녕하세요?? ^-^

 

SIR 회원님들도 주말 잘 보내고 계시는가요??

 

 

PDF 파일의 각 페이지를 PNG 이미지 파일로 변환한 후,

 

이를 그누보드에 업로드하여 자동으로 글 작성을 하는 Python 스크립트를 작성해봤어요! :)

 

가끔은 PDF 뷰어 형식으로 보는 것보다 이미지로 스크롤해서 보는게 더 편한 경우도 있더군요~ ^^

 

 

보시다시피 PDF2image라는 모듈을 사용하여 PDF -> PNG 변환을 했구요~

 

만약 PDF2image 모듈의 설치에 어려움을 겪으신다면, 제가 작성한 아래 웹 문서를 참고하세요 :)

 

https://studyforus.com/tipnknowhow/826049

 

 

실행과정은 다음과 같이 진행됩니다!

 

1. 임시폴더 생성

2. 임시폴더에서 PDF -> PNG 변환

3. DB 연결 후 파일명으로 게시글 작성

4. FTP로 PNG 파일 업로드

5. DB에 파일 업로드 정보를 저장

6. 임시폴더 삭제

 

 

[code]

import pymysql, ftputil, hashlib, os, sys, shutil

from pdf2image import convert_from_path

from datetime import datetime

from PIL import Image


 

def pdf2png(file_name):

    temp = os.path.splitext(file_name)[0]

    pages = convert_from_path(file_name, poppler_path='poppler설치폴더를입력하세요')

    folder = '.\\temp_pdf2png\\'

    os.makedirs(folder)

    png_file_list = []

    for i, page in enumerate(pages, 1):

        png_file_name = f'{folder}{temp}{i}.png'

        page.save(f'{folder}{temp}{i}.png', 'PNG')

        png_file_list.append(png_file_name)

    return png_file_list


 

def file_upload(filename, bf_file): # FTP를 이용하여 파일을 업로드하는 함수입니다.

    with ftputil.FTPHost('URL을입력하세요', 'FTP계정ID를입력하세요', 'FTP계정비번을입력하세요') as fh:

        fh.chdir('/web/data/file/board') # 업로드할 디렉토리를 입력하세요

        fh.upload(filename, bf_file, callback = None)

    return


 

def get_filename(filename): # 파일명을 변환하는 함수입니다.

    ms = datetime.now().microsecond

    encoded_name = filename.encode('utf-8')

    result = f'{ms}_{hashlib.sha1(encoded_name).hexdigest()}'

    return result


 

def board_write(board, subject, content, mb_id, nickname, file_list = None):

    # MySQL connection 및 cursor 생성

    conn = pymysql.connect(host = 'URL을입력하세요', 

                           user = 'DB계정ID를입력하세요', 

                           password = 'DB계정비번을입력하세요',

                           db = 'DB명을입력하세요', 

                           charset = 'utf8')

    curs = conn.cursor()

 

    # 작성글 INSERT

    sql = f"select wr_num from g5_write_{board}"

    curs.execute(sql)

    wr_num = str(int(curs.fetchone()[0]) - 1)

    now = datetime.today().strftime('%Y-%m-%d %H:%M:%S') # 그누보드의 날짜 형식 준수 (ex: 2021-04-05 23:45:15)

    sql = f"insert into g5_write_{board} set wr_num = {wr_num}, \

          wr_reply = '', wr_comment = 0, ca_name = '', wr_option = 'html1', wr_subject = '{subject}', \

          wr_content = '{content}', wr_link1 = '', wr_link2 = '', \

          wr_link1_hit = 0, wr_link2_hit = 0, wr_hit = 1, wr_good = 0, wr_nogood = 0, \

          mb_id = '{mb_id}', wr_password = '', wr_name = '{nickname}', wr_email = '', wr_homepage = '', \

          wr_datetime = '{now}', wr_last = '{now}', wr_ip = '111.111.111.111', \

          wr_1 = '', wr_2 = '', wr_3 = '', wr_4 = '', wr_5 = '', \

          wr_6 = '', wr_7 = '', wr_8 = '', wr_9 = '', wr_10 = '', \

          wr_comment_reply = '', wr_facebook_user = '', wr_twitter_user = '', \

          as_re_name = '', as_tag = '', as_map = '', as_icon = '', as_thumb = '', as_video = ''"

    curs.execute(sql)

 

    # 부모 아이디에 UPDATE

    sql = f"select wr_id from g5_write_{board}"

    curs.execute(sql)

    wr_id = str(curs.fetchall()[-1][0])

    sql = f"update g5_write_{board} set wr_parent = {wr_id} where wr_id = {wr_id}"

    curs.execute(sql)

 

    # 새글 INSERT

    sql = f"insert into g5_board_new ( bo_table, wr_id, wr_parent, bn_datetime, mb_id ) values \

          ( '{board}', '{wr_id}', '{wr_id}', '{now}', '{mb_id}' )"

    curs.execute(sql)

 

    # 게시글 1 증가

    sql = f"select bo_count_write from g5_board where bo_table = '{board}'"

    curs.execute(sql)

    bo_count_write = str(int(curs.fetchone()[0]))

    sql = f"update g5_board set bo_count_write = {bo_count_write} + 1 where bo_table = '{board}'"

    curs.execute(sql)

 

    # 파일 업로드 및 관련 정보를 테이블에 저장

    if not file_list or file_list == [''] or file_list == []: # 첨부파일이 없는 경우에는 스크립트를 중단합니다.

        conn.close()

        sys.exit()

 

    file_count = len(file_list)

    for cnt, file in enumerate(file_list):

        ext = os.path.splitext(file)[1].lstrip('.')

        bf_file = f'{get_filename(file)}.{ext}'

        file_upload(file, bf_file)

        im = Image.open(file)

        width, height = im.size

        size = os.path.getsize(file)

        sql = f"insert into g5_board_file set bo_table = '{board}', wr_id = '{wr_id}', \

              bf_no = '{cnt}', bf_source = '{file}', bf_file = '{bf_file}', \

              bf_content = '', bf_download = 0, bf_filesize = '{size}', \

              bf_width = '{width}', bf_height = '{height}', bf_type = '3', bf_datetime = '{now}'" # PNG 파일은 type 3입니다.

        curs.execute(sql)

        

    # 파일의 개수를 게시물에 업데이트

    sql = f"update g5_write_board set wr_file = '{file_count}' where wr_id = '{wr_id}'"

    curs.execute(sql)

 

    # MySQL connection 닫기 및 로그 출력

    conn.close()

    print(f'총 {file_count}장의 이미지가 "{subject}"라는 제목으로 업로드되었습니다.')

    return


 

def main():

    filename = '업로드할PDF파일명을입력하세요'

    board = '게시판명을입력하세요'

    subject = os.path.splitext(filename)[0] # 글 제목을 파일명으로 합니다.

    content = ''

    mb_id = '아이디를입력하세요'

    nickname = '닉네임을입력하세요'

    file_list = pdf2png(filename) 

    board_write(board, subject, content, mb_id, nickname, file_list)

    shutil.rmtree('.\\temp_pdf2png\\') # 임시폴더를 삭제합니다.

    return


 

if __name__ == "__main__":

    main()

[/code]

 

 

 

위 스크립트를 실행하면 아래와 같이 파일명을 제목으로 한 글이 작성된 것을 확인할 수 있어요~ ^^

 

3696577391_1624770961.6711.png

 

 

 

해당 게시글을 클릭하면 아래와 같이 PDF 파일의 총 4페이지가 4개의 이미지로 변환되어 업로드되어 있습니다 :)

 

저작권에 저촉되지 않는 PDF 파일로 테스트했어요!

 

3696577391_1624771014.1646.png

 

 

 

여러모로 부족한 점이 많은 스크립트이지만, 아무쪼록 잘 사용하시면 좋겠네요 :)

 

다음에는 HWP 파일의 내용을 그누보드에 게시글로 올리는 스크립트를 작성해볼게요~

 

그럼 남은 주말 즐겁고 뜻깊게 보내시고, 날씨가 무더운데 항강 건강하세요!

 

SIR 회원님들께 항상 감사드립니다~ ^-^

댓글 작성

댓글을 작성하시려면 로그인이 필요합니다.

로그인하기

댓글 21개

와~ 참 편리한 스크립트네요. 멋지십니다! 설명글까지 자상하게 공유해주시니 더할 나위 없이 감사해요. ^^
@하나Yun 안녕하세요?? ^-^
우선 정성이 담긴 댓글과 추천 감사드립니다!
솔직히 여러모로 부족한 점이 많은 스크립트인데
편리하다고 말씀해주시니 제가 더 감사드려요~ :)
그럼 날씨가 무덥고 소나기가 자주 내리는데 항상 건강하세요!
이니스프리님 굿입니다.
@비타주리 안녕하세요?? ^-^
비타주리 님께서 올려주시는 여러 자료들에 비하면 새발의 피도 안 되는 허접한 자료인데
추천과 댓글 진심으로 감사드립니다!!
올려주신 "자바스크립트 전용 게시판"도 덕분에 잘 사용하겠습니다~
그럼 편안한 저녁 되세요 :)
잘 사용하겠습니다 수고하심에 감사드립니다
@ATOM1 잘 사용하겠다고 말씀하시니 제가 더 감사드립니다! ^-^
그럼 남은 6월 잘 마무리하시고, 가정에 건강이 늘 함께 하시길 기원합니다 :)
@ascii 안녕하세요?? ^-^
아직 부족한 점이 많지만 앞으로 더 열심히 Python을 공부하여 멋진 스크립트를 작성할 수 있도록 노력하겠습니다!!!
감사합니다 :)
적용하려면 파이썬을 알아야 하나요?
@김철용 안녕하세요? ^-^
말씀하신 질문의 취지를 제가 정확히 이해했는지 모르겠지만
일단 제 추측을 기반으로 답변을 드리겠습니다 :)

1.
위 스크립트는 PC 또는 VPS에서 실행을 하면 바로 게시글이 작성되기 때문에
별도의 적용이나 설치가 필요 없습니다.
굳이 서버에서 실행하시지 않으셔도 됩니다 ^^

2.
Python 스크립트이니 일단 Python을 설치하셔야 됩니다.
그누보드 서버 쪽에는 설치할 필요가 없습니다.
(저도 일반 PHP 웹 호스팅에서 테스트했습니다.)
VPS(Ubuntu 등)에는 Python이 기본으로 설치되어 있을겁니다.
윈도우에 Python을 설치하는 쉬운 방법은 Anaconda 홈페이지에서 다운을 받으시면 됩니다 ^^

3.
다만 이 스크립트의 경우에는 PDF2image 모듈을 별도로 설치해야 되는데,
본문에 적었듯이 poppler라는 프로그램에 dependent 합니다.
poppler를 다운받아서 PC에 압축을 해제한 후
위 스크립트의 9번째 행에 압축을 해제한 폴더를 입력하면 작동합니다 :)
아시다시피 윈도우와 리눅스의 경로 표시 방법이 살짝 달라서 혼동의 여지가 있는데(\ vs /),
제 생각에는 이걸 Python을 알아야 해결되는 내용이라고 말씀드리기는 어려울 것 같습니다 ^^;

4.
결론적으로 Python을 알아야 한다거나, 서버에 적용을 해야 한다기보다는
위 스크립트에 단순히 ID, PW 등을 입력하여 바로 실행하시면 됩니다 ^^

그럼 편안한 저녁 되세요! :)
수고하십니다.
@초코상자 저야말로 감사드립니다! ^-^
그럼 편안한 저녁 되시고, 이번 주도 화이팅입니다! :)
자료 공유 감사합니다
@구자철 부족한 점이 많은 자료인데 저야말로 감사합니다! ^-^
편안한 저녁 되시고 비 조심하세요~ :)
어디에 어떻게 적용해야할지 생각은 당장 나지 않지만..ㅋㅋ
일단 추천~ 꾸욱하고 갑니다.
@호텔천사 추천과 댓글 진심으로 감사드려요 ^-^
부디 적절한 곳에 잘 적용하셨으면 좋겠네요~
편안한 저녁 되시고, 7월도 홧팅입니다! :)
Innisfree 님 글을 꾸준히 읽고 잇어요
@더SUN 앗 여러모로 부족한 글인데 꾸준히 읽고 계시다니 부끄럽고 또 감사드려요! ^-^
그럼 남은 6월 잘 마무리하시고, 2021년 하반기도 홧팅입니다! :)
아주 멋진 기능이네요!!
아주 멋진 파이썬 기능이네요. 스크랩해 갑니다.
@shengwooshin 댓글과 추천, 스크랩 모두 감사드립니다! ^-^
다음에는 더 나은 스크립트를 작성해볼게요~
그럼 저녁식사 맛있게 드시고, 항상 건강하세요 :)

게시글 목록

번호 제목
24318
24317
24315
24309
24294
24293
24277
24262
24260
24253
24251
24236
24233
24228
24226
24221
24214
24203
24201
24199
24196
24195
24194
24192
24191
24187
24185
24183
24172
24168