Python/2.7 for fun.

py2exe, (편의) 티스토리에 맞는 파이썬 소스코드 변환기

qkqhxla1 2015. 2. 23. 13:01

파이썬 파일을 실행파일(.exe)로 만들어줌. 

다운로드 : http://sourceforge.net/projects/py2exe/files/py2exe/0.6.9/


튜토리얼 : http://www.py2exe.org/index.cgi/Tutorial


옵션 : http://www.py2exe.org/index.cgi/ListOfOptions


방법.

1. setup.py를 만든다.

#setup.py
from distutils.core import setup
import py2exe

setup(console=['hello.py']) #hello.py는 우리가 exe로 변환시킬 .py파일. 
#hello.py는 지금 만든 setup.py와 같은 콘솔상에 있어야 하는것 같다.


2. exe로 변환시킬 hello.py를 만든다.

#hello.py
print 'hello world'


3. 위의 두 파일이 있는 해당 경로로 들어가서 python setup.py py2exe로 실행한다.

그러면 주르륵 뭔가 만들어지면서 dist와 build라는 폴더가 만들어진다.


dist폴더에 들어가면 hello.exe와 w9xpopen.exe가 있는데 w9xpopen.exe는 하위 os에서 실행시킬 경우를 대비하는 것으로 없애도 된다고 함. hello.exe는 실행이 잘 되고, hello.exe만 빼고 나머지 .pyd등을 다 지웠을시 에러가 뜨면서 안됨. 결국 이게 최소조건이라는 말.


http://wonderfuldream.tistory.com/186유용한 정보가 있다.

옵션으로 bundle file옵션을 줄 수 있다고 함.

3 (default) don't bundle

2 bundle everything but the Python interpreter

1 bundle everything, including the Python interpreter

라고 설명이 되있음. 옵션 변경해서 해봤다.


setup.py 변경. (파이썬 인터프리터까지 모든 것을 포함하는 1번 옵션을 줘봤다.)

#setup.py
from distutils.core import setup
import py2exe

setup(
     console=['hello.py'],
     options = {'py2exe': {'bundle_files': 1}}
     )

만든경우 dist폴더에는 hello.exe와 library.zip만 남아있다. 


setup.py에 zip파일까지 보기싫어서 옵션을 더줘본 결과 

#-*- coding: cp949 -*-
from distutils.core import setup
import py2exe
 
setup(
     windows=['hello.py'],
     options = {'py2exe': {'bundle_files':1,'dist_dir':'python exe','dist_dir':'C:\\Users\\Ko\\Desktop\\python exe',}},
     zipfile = None
     )


아까 바로 위의 zipfile옵션을 주지 않았을때의 library.zip에는 7m정도가 들어있었는데, 그 용량이 hello.exe에 추가됬고, hello.exe의 용량이 커졌다. 앞으로는 그냥 맨 마지막 옵션으로 사용해야겠다. (별로 용량도 커지지 않고..) 또 실험결과 마지막 옵션으로 만들었을시 build폴더 자체를 지워버려도 dist에 있는 .exe는 영향없이 잘 실행된다


그냥 설치만 해놓으면 재미없으니까 나름 나에게 유용한걸 하나 만들었다.

매번 티스토리로 소스를 올릴시 syntax highter가 잘 작동하지 않는 경우가 있다. <또는 >가 껴서 티스토리가 태그로 인식해서 마음대로 이상하게 바꿔버리는데, 내가 일일히 찾아서 수작업으로 <를 &lt;로 바꿔 줘야 했다. 그리고 위 아래로 <pre class="brush:py"></pre>를 써야 했는데..... 수작업이 많이 불편해서 이번에 유용한 모듈을 찾은 만큼 한번 만들어 보기로 했다.


소스

# -*- encoding: cp949 -*-
import sys
while 1:
    filename = raw_input('input filename : ')
    try:
        f = open(filename,'r')
        coding = f.read()
        try:
            print 'changing source...'
            if coding.find('<'):
                coding = coding.replace('<','&lt;')
            if coding.find('>'):
                coding = coding.replace('>','&gt;')
            f.close()
            f = open(filename,'w')
            f.write('<pre class="brush:py">\n'+coding+'\n</pre>')
            f.close()
            print 'source change success!\n'
        except:
            print 'file error!\n'
    except:
        print 'don\'t find file : '+filename+'\n'

이다. 파이썬만을 대상으로 만들었기 때문에 &lt;문자 자체를 넣을때나 다른 버그가 있을수 있다.

나중을 위한 참고 사이트 : http://demun.tistory.com/2452



15년 3월 23일 추가. 나만을 위한 소스 편집기로 새로 수정.


원래는 source.txt를 열고 소스를 source.txt에 복붙 후 닫고, exe를 실행시키고, 다시 source.txt를 누르면 완성된 복붙용 소스가 나타남. 근데 이게 귀찮음.


개선점

0. 이제 내가 작업하던 파이썬 소스를 올리고 싶으면... 비쥬얼스튜디오 내부의 소스파일에서 ctrl+s로 저장 후 exe를 실행시키면 알아서 정리된 소스가 메모장에 나타남. 정리된 source.txt는 끄면 알아서 지워지기 때문에(임시파일) 계속 재실행해도 문제는 없음. 


1. 단순히 coding.find('<') 처럼 하면 < 의 위치가 0일시 if문으로 안들어가는걸 발견함. !=-1로 고침.


2. <나 &lt;관련 소스를 올릴시 &amplt;로의 변환의 필요성을 느껴서 추가. 


3. 메모장이 실행되면서 뒤에 보이던 콘솔창 보기 싫어서 없애버림. setup.py의 console을 windows로 변경.


tistory_upload.exe


# -*- encoding: cp949 -*-
import sys, os, webbrowser, time
filename = 'C:\\Users\\Ko\\documents\\visual studio 2012\\Projects\\PythonApplication37\\PythonApplication37.py' #os.path.abspath(__file__)
try:
    f = open(filename,'r')
    coding = f.read()
    try:
        print 'changing source...'
        if coding.find('&') != -1:
            coding = coding.replace('&','&amp')
        if coding.find('<') != -1:
            coding = coding.replace('<','&lt;')
        if coding.find('>') != -1:
            coding = coding.replace('>','&gt;')
        f.close()
        copy = open('source.txt','w')
        copy.write('<pre class="brush:py">\n'+coding+'\n</pre>')
        copy.close()
    except:
        print 'file error!\n'
        os.system('pause')
        exit(1)
except:
    print 'don\'t find file : '+filename+'\n'
    os.system('pause')
    exit(1)
 
webbrowser.open("source.txt")
time.sleep(1)
os.remove('source.txt')




15년 4월 11일 추가.

py2exe로 이것저것 만들다 보면 python setup.py py2exe로 실행했을시 종종 엑세스 거부 에러를 볼 수 있다.



그런데 계속 해보다보면 될때도 있고 이렇게 에러가 발생할 때도 있다. 이것은 실행되고 있는 exe에 접근해서 변경 시 백신 프로그램이 접근을 막아서 이러한 에러가 뜬다고 한다.


출처 : http://stackoverflow.com/questions/21848033/access-denied-using-py2exe


15.10.03

index.php도 되게 추가.

1. py파일과 php파일의 수정 날짜를 비교해서 더 최근에 수정한 것의 소스를 티스토리에 적합하게 만든다.


16.09.25

2. c++도 되게 추가.

# -*- encoding: cp949 -*-
import sys, os, webbrowser, time
filename = r'C:\Users\Ko\documents\visual studio 2012\Projects\PythonApplication37\PythonApplication37.py' #os.path.abspath(__file__)
file_web = r'C:\APM_Setup\htdocs\index.php'
file_clang = r'C:\Users\Ko\Documents\Visual Studio 2012\Projects\ConsoleApplication17\ConsoleApplication17.cpp'
py  = os.path.getmtime(filename)
web = os.path.getmtime(file_web)
clang=os.path.getmtime(file_clang)

d={filename:py,file_web:web,file_clang:clang}
recent_file = sorted(d.iteritems(),key=lambda x:x[1],reverse=True)[0][0]
print sorted(d.iteritems(),key=lambda x:x[1],reverse=True)
#recent_file = filename if py > web else file_web
for_brush = {'.py':'py','php':'php','cpp':'c++'}
 
f = open(recent_file,'r')
coding = f.read()
try:
    print 'changing source...'
    if coding.find('&') != -1:
        coding = coding.replace('&','&amp')
    if coding.find('<') != -1:
        coding = coding.replace('<','&lt;')
    if coding.find('>') != -1:
        coding = coding.replace('>','&gt;')
    f.close()
    copy = open('source.txt','w')
    copy.write('<pre class="brush:'+for_brush[recent_file[-3:]]+'">\n'+coding+'\n</pre>')
    #if py > web: copy.write('<pre class="brush:py">\n'+coding+'\n</pre>')
    #else: copy.write('<pre class="brush:php">\n'+coding+'\n</pre>')

    copy.close()
except:
    print 'file error!\n'
    os.system('pause')
    exit(1)
 
webbrowser.open("source.txt")
time.sleep(1)
os.remove('source.txt')

setup.py

#-*- coding: cp949 -*-
from distutils.core import setup
import py2exe
  
setup(
     windows=[{'script':'hello.py','icon_resources':[(1, 'tistory.ico')]}],
     options = {'py2exe': {'bundle_files':1,'dist_dir':'python exe','dist_dir':'C:\\Users\\Ko\\Desktop\\python exe',}},
     zipfile = None
     )