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

[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 댓글과 추천, 스크랩 모두 감사드립니다! ^-^
다음에는 더 나은 스크립트를 작성해볼게요~
그럼 저녁식사 맛있게 드시고, 항상 건강하세요 :)

게시판 목록

그누보드5 팁자료실

글쓰기
🐛 버그신고