반응형
반응형

요즘 플레이하는 게임마다 간단하게 매크로를 하나씩 만들어보고 있다.

기존에 잘 써먹던 Autohotkey 같은 경우, 워낙 많이 알려져있기 때문에 PC 클라가 뜨면서 보안프로그램이 같이 떠버리면 어뷰저 (악용 유저)로 분류가 되기 마련이다. (N사 게임들이 특히 그렇다)

 

하지만, 게임사도 win32 API인 SendMessage, PostMessage는 막을 수가 없기 때문에, 이것들을 활용해보았고, 그 결과 잘 되는 것을 확인하였다.

왜 못막냐고? 저것들을 막아버리면 PC 클라로 들어오는 모든 이벤트를 막는 것이기 때문에, 일반적인 키보드 / 마우스도 사용할 수가 없기 때문이다.

 

물론 C로 쌩짜로 짜면 좋겠지만, 간단하게 python으로 구현을 해보았고, win32gui, win32con 패키지 정도만 있으면 쉽게 구현가능하다.

 

요즘 하는 게임에서 필요한 기능은 자동 사냥은 일단 제공을 하고 있고, 자동 스킬까지 제공하는 훌륭한 게임이지만, 일정주기마다 특정 키를 눌러줘야 자동 사냥의 효율성이 더 올라가고, 물약도 적게 먹기 때문에, 난 30초마다 내가 숨겨둔 PC클라에 특정 키를 입력해주는 기능을 구현하려고 한다.

 

아래 소스는 내가 플레이하는 게임창을 찾아서, 특정 시간마다 Z 키를 누르는 기능을 수행한다.

import time
import win32gui
import win32con

class DiabloByebye:

    def __init__(self):        
        self.win_title_name = "찾고자 하는 창의 타이틀명 적어준다. (winspy로 찾을 수 있음)"
        self.handle = win32gui.FindWindow(None, self.win_title_name)
        print(self.handle) # 여기서 0 찍히면 타이틀명 잘못 찾은거임
        
    def start(self):
        while True:                        
            win32gui.SendMessage(self.handle, win32con.WM_KEYDOWN, ord('Z'), 0)
            time.sleep(0.1)
            win32gui.SendMessage(self.handle, win32con.WM_KEYUP, ord('Z'), 0)
            time.sleep(30)
 
if __name__== "__main__":  
    DiabloByebye().start()

 

클래스명은 최근 영정당한 Diablo에게 인사하는 이름으로 해보았다.

키보드 이벤트를 후킹해서, 시작 / 중지 / 종료 등도 다양하게 구현이 가능하다.

 

반응형
,
반응형

python 관련한 모듈 설치 시에 easy_install이나 pip를 사용하는데, 아무 설정없이 그냥 설치하면, nodejs나 maven같이 각 프로젝트에 해당 하는 모듈을 설치하는 것이 아니라, 시스템에 global하게 설치가 되버려서, 잘 됬던 기능도 호환성 이슈에 따라 문제가 생기는 경우가 발생하게 된다.


위와 같은 문제가 발생하는 것을 막기 위해, virtualenv 라는 모듈을 설치하여, 시스템에 global하게 설치되는 방식이 아닌, 해당 프로젝트에서만 종속되는 모듈을 설치할 수 있도록 가상 개발환경 구축이 가능하다.


[설치]

일단 아래와 같은 키워드로 virtualenv를 설치해보자. (사전에 pip가 설치되어 있어야 함.)

$ pip install virtualenv


가상 환경을 구축할 폴더를 하나 만들고, virtualenv를 이용하여 가상 환경을 구축해보자.

$ mkdir virtualenv_test
$ virtualenv venv

virtualenv 명령어 실행 시 첫번째 argument는 만들어질 가상환경의 이름(alias)이다. 보통 venv, .venv 등으로 만들며 이름만 다르다면 여러개도 만들 수 있다.


가상 환경 구축이 완료되면, 해당 디렉토리에 venv (alias) 디렉토리가 생기며, 가상 환경 컨트롤을 위한 몇 가지 폴더와 스크립트가 생긴다.


이제 기본 세팅은 끝났고, 가상 환경 활성화 / 비활성화에 대해 알아보겠다.


[활성화 / 비활성화]

만들어진 폴더들을 보면, Windows 환경인 경우에 Scripts 폴더가 있고, Linux 환경의 경우 bin 폴더가 있을 것이다.

* Windows

$ ls venv/
Include/  Lib/  pip-selfcheck.json  Scripts/  tcl/


* Linux

$ ls venv/
bin  lib  local


활성화는 아래와 같은 키워드로 한다.

* Windows

$ . venv/Scripts/activate


* Linux

$ . venv/bin/activate


활성화가 완료되면, git에서 브랜치를 변경했을 때처럼 쉘 앞에 (venv) 라는 문자열이 생기며, 앞으로 pip를 통해 설치하는 모듈은 해당 가상환경에만 종속되게 설치가 된다.


주의할 점은, 비활성화를 시키지 않은 채 다른 프로젝트로 이동해 작업을 하다가 필요한 모듈을 설치하면, 활성화 당시의 가상환경에 설치가 되기 때문에 혼선이 있을 수 있어, 하나의 프로젝트에서 필요한 작업을 완료하고 나면, 비활성화를 꼭 시켜주도록 한다.


비활성화는 아무 디렉토리에서나 아래 명령어를 통해 가능하다.

(venv)$ deactivate


이렇게 가상환경 구축을 이용해서 작업을 하다가, 최종적으로 원격 서버에 배포를 진행하기 위해서는 가상환경에서 설치했던 모듈들을 파일로 만들어줄 필요가 있다.


그럴땐 아래와 같은 키워드로 설치된 패키지 목록을 파일로 만들어준다.

(venv)$ pip freeze > requirements.txt


이렇게 해두면, 원격 서버에서 소스를 올린 후에 아래와 같은 커맨드로 한 번에 모듈을 설치할 수 있게 된다.

$ pip install -r requirements.txt


반응형
,
반응형

습관적으로 python 스크립트를 만들 때 한글 처리 등 귀찮은 일을 겪지 않기 위해, 가장 상단에 아래와 같은 구문을 넣어서 만들었었다.

#-*- coding: utf-8 -*-


그런데, 저것만으로는 format 함수 등 string을 세밀하게 다뤄야하는 로직들에서는 utf-8 인코딩 효과를 보질 못하는 것으로 보여, 아래와 같이 명시적으로 선언해주면, 모든 String 처리 시 UTF-8 인코딩으로 동작하게 된다.

#-*- coding: utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')


reload 함수 호출이 필요가 없어 보일 수 있는데, 호출 하지 않으면 동작하지 않는다.

반응형
,
반응형

리눅스 같은 경우는 pip3 install mysqlclient 키워드 하나로 종료되지만,

Windows의 경우 VisualStudio의 영향을 받는지, 이것저것 에러가 발생을 하기 때문에

mysqlclient을 직접 받아서 컴파일 하는 복잡한 과정을 거쳐야 한다.


하지만, 다행히도 누가 이미 컴파일을 해놓은 바이너리를 모아놓은 아래와 같은 사이트가 있다.

http://www.lfd.uci.edu/~gohlke/pythonlibs/#mysqlclient


python과 os bit에 맞게 파일을 다운 받은 후 아래와 같이 설치를 하면 된다.

$ pip install 다운받은파일.whl


반응형
,
반응형

매번 VisualStudio를 몇시간씩 깔고 하는게 귀찮아서, 간단한 걸 찾아보던 중

Python에서도 지원하는 Form기반의 GUI 툴이 있었다.


일단 설치는 공식홈에서도 가능하긴하지만, QT Designer가 Windows에서는 잘 안되는 모양인 것 같으니,

아래 링크에서 설치하였다. (Python 3.4, 64bit OS 기준)

https://sourceforge.net/projects/pyqt/files/PyQt5/PyQt-5.4.1/PyQt5-5.4.1-gpl-Py3.4-Qt5.4.1-x64.exe/download


설치하고 나면, 프로그램 목록에 아래와 같은 Qt Designer라는 GUI 구성을 편리하게 해주는 Tool이 덤으로 설치되어 나온다.


이것저것 편집을 하고나서 저장을 하려고 보면, .ui 파일만 하나 떨구게 되는데,

ui파일을 py파일로 변환을 해서 사용을 해야 한다.


변환방법은 아래와 같다.

Windows에서 기본 설치 기준으로 C:\Python34\Lib\site-packages\PyQt5 경로로 이동 후 아래 키워드 입력

$ python uic/pyuic.py -x ui파일명.ui -o 뽑아낼파일명.py


변환 과정에서 두 가지 예외 케이스가 있다.

1. PyQt5와 Python3.4의 OS bit 버전이 다르게 설치된 경우

  > 해결 : OS bit버전을 서로 맞춰서 재설치한다.


2. OS 자체에서 상대경로 참조를 못하는 경우

  > 해결 : pyuic.py 을 열어서 아래와 같이 절대경로로 바꿔준다. 

import sys
import optparse

from PyQt5 import QtCore
from PyQt5.uic.driver import Driver # 이 부분!

Version = "Python User Interface Compiler %s for Qt version %s" % (QtCore.PYQT_VERSION_STR, QtCore.QT_VERSION_STR)

if sys.hexversion >= 0x03000000:
    from PyQt5.uic.port_v3.invoke import invoke  # 이 부분!
else:
    from PyQt5.uic.port_v2.invoke import invoke  # 이 부분!


주석 달아놓은 세 군데 정도만 바꿔주면 정상적으로 .py 파일로 변환을 해준다.

본 포스팅에선 세팅이 목표이므로, 사용법은 다루지 않겠다.

반응형

'개발 > Python' 카테고리의 다른 글

[Python 2.x] UTF-8 인코딩 관련  (0) 2017.08.09
[Python] Python 3.x no module MysqlDB  (0) 2017.02.14
[Python] pyYaml을 이용한 yaml parsing  (0) 2017.02.10
[Python] asyncio  (0) 2017.02.10
[Python] paramiko for SSHClient  (0) 2017.02.10
,
반응형

Python으로 온갖 자동화를 하다보니, 이제 소스는 그대로 두고 설정파일만으로 뭔가를 해봐야겠다는 생각을 하던 중,

yaml이 Python과 호환성이 좋다는 얘기를 들었었기 때문에, parser가 있는지 찾아보던 중 pyYaml이라는 lib를 찾게 되었다.


설치 방법은 아래 링크로 대체하겠다.

http://pyyaml.org/wiki/PyYAMLDocumentation


사용방법은 아래 예제를 참고하면 된다.

# test.yaml
strs:
  - a
  - b
  - c


import yaml

doc = yaml.load(open('test.yaml', 'r'))
strs = doc['strs']

for s in strs:
    print(s)  # a, b, c
반응형

'개발 > Python' 카테고리의 다른 글

[Python] Python 3.x no module MysqlDB  (0) 2017.02.14
[PyQt5] GUI 개발을 위한 PyQt5 세팅  (0) 2017.02.14
[Python] asyncio  (0) 2017.02.10
[Python] paramiko for SSHClient  (0) 2017.02.10
[Python] requirements.txt  (0) 2017.01.31
,

[Python] asyncio

개발/Python 2017. 2. 10. 10:31
반응형

서버 한대에 SSH로 붙어서, 여러개의 원격 서버에 request를 해야 하는 일이 생겼는데,

SSH를 매번 붙여서 하기엔 SSH접속이 너무 느려서, async하게 처리하는 방법을 찾던 중,

coroutine이라는 비동기 처리를 할 수 있는 기능이 있다는 것을 알았다.


다만, python에서 제공하는 비동기 처리는 GIL (global interpreter lock)이라고 해서, lock이 존재하기 때문에 비동기 처리 같지 않은 비동기처리라고 많이 불리고 있었다. 


이런 문제점을 해결하기 위해 Python 3.4 버전이상부터 사용할 수 있는 asyncio(https://docs.python.org/3/library/asyncio.html)라는 lib가 있어서, 사용법에 대해 간단히 설명을 하고자 한다. (이 기능때문에 Python 2.7에서 3.4 이상 버전으로 갈아탈 준비를 하고 있다.)


일단 설치는 pip로 가능하다.

$ pip install asyncio


아래는 예제소스인데, 이 포스팅에서는 정말 간단한 기능만 다루기 때문에 (실제로도 간단한 기능만 사용했고;;),

상세한 정보 획득을 위해선 공식 홈을 참조하는 게 좋다. https://docs.python.org/3/library/asyncio.html

예제소스에서는 asyncio에서 사용하는 event_loop를 초기화해서, print찍는 부분을 async하게 동작하도록 해볼 생각이다.

import asyncio

@asyncio.coroutine
def print_string(str):
    print(str)

    # 아래와 같이 텀을 두지 않으면, 동시에 여러개의 Thread를 생성하면서 초기화하는 과정에서, 문제가 발생한다.
    yield from asyncio.sleep(0.1)

@asyncio.coroutine
def print_all():
    strs = ['a', 'b', 'c']

    # coroutine기반의 Task를 생성한다.
    fetches = [asyncio.Task(print_string(str)) for str in strs]  

    # asyncio에 Task들을 등록한다.
    yield from asyncio.gather(*fetches)

def main():
    # Event Loop를 초기화 한 후 coroutine으로 돌릴 메서드를 지정하여, 완료될때까지 loop한다.
    asyncio.get_event_loop().run_until_complete(print_all()) 

if __init__ == '__main__':
    main()


반응형
,
반응형

특정 서버에 SSH로 접속하여, 원격 커맨드를 날릴 일이 있어서 이것저것 찾아보던 중,

Python에서는 paramiko라는 lib를 많이 사용한다는 걸 알았다.


설치방법은 아래와 같이 pip로 원 커맨드로 가능함.

$ pip install paramiko


테스트했던 Python버전은 3.6이었지만, Python 2.x나 그 전 버전에서도 잘 동작하는 것으로 보인다.


아래는 예제소스다. 

ssh.connect부분은 각 Case에 맞춰서 하나만 사용하면 된다.

import paramiko

def main():
    ssh = paramiko.SSHClient()

    # HostKey 저장 여부를 결정하는 옵션인데, 왠만하면 그냥 넣어주자.
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())       

    # CASE 1: 인증 시 username과 password를 사용
    ssh.connect('서버 IP', username='인증 ID', password='패스워드')  

    # CASE 2: AWS의 EC2같은 경우 password를 key_filename로 바꾸어서 파일 명을 지정할 수 있다.
    ssh.connect('서버 IP', username='인증 ID', key_filename='Key파일 위치') 

    stdin, stdout, stderr = ssh.exec_command('커맨드 입력')    
    ssh.close()
    
if __name__ == '__main__':
    main()


반응형

'개발 > Python' 카테고리의 다른 글

[Python] pyYaml을 이용한 yaml parsing  (0) 2017.02.10
[Python] asyncio  (0) 2017.02.10
[Python] requirements.txt  (0) 2017.01.31
[SMTPlib] mail loops back to me (MX problem)  (0) 2016.12.27
[Python] file read / write  (0) 2016.11.09
,
반응형

python의 의존 라이브러리 관리를 위해 setup.py와 requirements.txt가 사용되는데,

여기서는 requirements.txt에 대해 포스팅한다.


python 프로젝트 내에 requirements.txt 파일이 들어 있다면,

아래 커맨드 하나 만으로 모든 의존성이 설치가 되게 된다.

$ pip install -r requirements.txt


requirements.txt를 일일히 수작업으로 구성해도 괜찮지만, pip freeze를 이용하면 현재 세팅된 시스템이 가지고 있는 의존성을 아래 키워드로 한 번에 뽑아낼 수가 있다.

$ pip freeze > requirements.txt


단, pip freeze의 경우, 현재 폴더 기준이 아닌 글로벌한 환경 기준으로 의존성을 뽑아내기 때문에,

여러개의 Python 프로젝트를 운용하는 경우 원치않는 결과가 나올수도 있다.


그런 경우, pigar(https://github.com/Damnever/pigar)를 이용하여, 특정 폴더 기준으로 의존성을 추출해 낼 수 있다.

pip 를 이용해서 pigar를 설치한 후, pigar 명령어 뒤에 argument로 폴더 경로를 입력해주면,

해당 폴더부터 의존성을 검색하여 requirements.txt 파일을 뽑아준다.

$ pip install pigar # install pigar
$ pigar



반응형

'개발 > Python' 카테고리의 다른 글

[Python] asyncio  (0) 2017.02.10
[Python] paramiko for SSHClient  (0) 2017.02.10
[SMTPlib] mail loops back to me (MX problem)  (0) 2016.12.27
[Python] file read / write  (0) 2016.11.09
[Python] multipart file upload  (0) 2016.11.09
,
반응형

python에 있는 SMTPLib을 이용해서 cronjob으로 sendmail을 호출하는데, 갑자기 메일이 안보내지길래,

syslog를 까보니, 아래와 같은 에러가 발생하였다. (아래 로그 중 회사관련 정보는 삭제하였음.)

Dec 26 09:02:09 sm-mta[23722]: uBQ929kP023720: SYSERR(root): 도메인 주소. config error: mail loops back to me (MX problem?)
Dec 26 09:02:09 sm-mta[23723]: uBQ929pM023723: 도메인 주소 [127.0.0.1] did not issue MAIL/EXPN/VRFY/ETRN during connection to MTA-v4
Dec 26 09:02:09 sm-mta[23722]: uBQ929kP023720: to=, delay=00:00:00, xdelay=00:00:00, mailer=esmtp, pri=121252, relay=hostname. [127.0.0.1], dsn=5.3.5, stat=Local configuration error
Dec 26 09:02:09 sm-mta[23722]: uBQ929kP023720: uBQ929kP023722: DSN: Local configuration error
Dec 26 09:02:09 sm-mta[23722]: uBQ929kP023722: to=root, delay=00:00:00, xdelay=00:00:00, mailer=local, pri=60000, dsn=2.0.0, stat=Sent
Dec 26 09:02:09 sm-mta[23722]: uBQ929kP023722: to=, delay=00:00:00, xdelay=00:00:00, mailer=esmtp, pri=60000, relay=도메인 주소, dsn=5.3.5, stat=Local configuration error


원인은 머신이 알고 있는 host정보가 유효하지 않아서 발생하는 문제였고,

hostname을 확인하여 /etc/hosts와 /etc/mail/local-host-names에 있는 내용을 각각 바꿔주면 된다.

왠만하면 동일하게 바꿔주는 게 좋다.


[/etc/hosts]

127.0.0.1 hostname


[/etc/mail/local-host-names]

127.0.0.1 hostname


우분투 14.04 기준이기 때문에, 다른 OS는 처리방법이 다를 수도 있다.

반응형

'개발 > Python' 카테고리의 다른 글

[Python] paramiko for SSHClient  (0) 2017.02.10
[Python] requirements.txt  (0) 2017.01.31
[Python] file read / write  (0) 2016.11.09
[Python] multipart file upload  (0) 2016.11.09
[Python] logging to file  (0) 2016.11.09
,
반응형