요 근래 말이 많은 텔레그램입니다. 원격지 컴퓨터에 명령 실행할 방법을 찾다가, 메신저를 통해서 실행해 보자는 아이디어 차원에서 한번 챗봇을 보게 되었는데, 파이썬 + 텔레그램 봇 구성이 생각보다 쉬워 공유를 해봅니다.

telepot 모듈 설치

pip install telepot --upgrade

소스 샘플

import telepot

from telepot.loop import MessageLoop
import time

TOKEN_MAIN = 'BOT_TOKEN'
StartMsg = """
BOT 기본 명령어
1. /help : 도움말
2. 안녕
"""

# 특정 명령어가 입력할 때 반응
def execcommand(message, chat_id):
    args = message.split(' ')
    command = args[0]
    del args[0]

    if command == '/help':
        send(chat_id, StartMsg)

# 메시지를 그대로 전송
def echoserver(message, chat_id, target):
    args = message.split(' ')
    command = args[0]

    if command == '안녕':
        send(chat_id, '안녕하세요~ %s 님!' % target['username'])

# 메시지 텔레그램으로 전송
def send(chat_id, message):
    bot.sendMessage(chat_id, message)

def handler(msg):
    content_type, chat_type, chat_id, msg_date, msg_id = telepot.glance(msg, long=True)

    print(msg)
    if content_type == 'text':
        _message = msg['text']
        if _message[0:1] == '/': # 명령어
            execcommand(_message, chat_id)
        else:
            echoserver(_message, chat_id, msg['from'])

bot = telepot.Bot(TOKEN_MAIN)
bot.message_loop(handler, run_forever=True)

버그 리포트

#1. ssl 접속 오류

urllib3 버전 이슈로 보입니다. 1.25 이상 버전에서 자체 서명된 인증서(self signed cert) 인 경우, SSL 인증서를 무시하는 부분을 거절하네요. 그래서 urllib3 버전을 강제로 다운그레이드 합니다.

# urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='api.telegram.org', port=443): 
pip install urllib3==1.24.3

참조 URL

https://telepot.readthedocs.io/en/latest/

 


WRITTEN BY
비트센스
뷰파인더로 보는 프로그래머의 세상 페이스북 @bitsense 트위터 @picory 스카이프 picory MSN drawhalf@dreamwiz.com

트랙백  0 , 댓글  0개가 달렸습니다.
secret

맥 팩키지 통합 관리 및 버전 변경을 쉽게 하기 위해서 홈브루(homebrew)를 사용합니다.

// 파이썬 설치
brew install python

// 버전 확인. 2020-05-15 현재 최신버전 3.8.22
python3
Python 3.8.2 (v3.8.2:7b3ab5921f, Feb 24 2020, 17:52:18) 
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.

// python3 > python 명령으로 대체 방법
vi ~/.zprofile (macOS 카탈리나)

// 추가 내용
alias python='python3'

// 소스 적용
source ~/.zprofile

// python 실행
python

WRITTEN BY
비트센스
뷰파인더로 보는 프로그래머의 세상 페이스북 @bitsense 트위터 @picory 스카이프 picory MSN drawhalf@dreamwiz.com

트랙백  0 , 댓글  0개가 달렸습니다.
secret
import psycopg2 as pg2
from psycopg2.extras import DictCursor

conn = pg2.connect()
cursor = conn.cursor(cursor_factory=DictCursor)
cursor.execute('select %s, %s', ('test', 2))
cursor.query
"select E'test', 2"

WRITTEN BY
비트센스
뷰파인더로 보는 프로그래머의 세상 페이스북 @bitsense 트위터 @picory 스카이프 picory MSN drawhalf@dreamwiz.com

트랙백  0 , 댓글  0개가 달렸습니다.
secret
pip install openpyxl

디렉토리 내의 엑셀 파일 목록 전체를 읽어서 분석하기 코드 일부

import openpyxl
import os
 
dirList = [
    'D:\\admin',
    'D:\\front'
]

currentNo = 0

def analsysEcxcel(filename, currentNo):
    # 엑셀파일 열기
    wb = openpyxl.load_workbook(filename)
    
    # 현재 Active Sheet 얻기
    ws = wb.active
    
    # Active Sheet 지정하기
    # ws = wb.get_sheet_by_name("Sheet1")
    
    # 국영수 점수를 읽기
    for r in ws.rows:
        row_index = r[0].row  # 행 인덱스
        if row_index < 2: # 첫번째 행은 칼럼 정보가 있으니 그대로 패쓰
            continue

        kor_score = r[7].value
        eng_score = r[8].value
        math_score = r[9].value
        
        if int(kor_score) > 50: # 국어 점수가 50점 초과 인원만 확인
            currentNo += 1
            print("%d > %d: %s %s %s" % (currentNo, row_index, kor_score, eng_score, math_score))

    # 엑셀 파일 종료
    wb.close()

    return currentNo

currentFileNo = 0
for dir in dirList:
    currentDir = dir

    # 현재 디렉토리 위치가 존재하는 지 확인
    if os.path.exists(currentDir) == False:
        print('no directory: %s' % currentDir)
    else:
        # 현재 디렉토리 출력
        print(currentDir + ' >>>>>>')
        fileList = os.listdir(currentDir)

        for filename in fileList:
            if filename[:1] == '~': # ~로 시작되는 임시 파일이 존재하면 패쓰
                print('except file .... <<<<<<< %s' % filename)
                continue

            currentFileNo += 1
            # 현재 파일 디렉토리 + 파일명 정리
            currentFile = '%s\\%s' % (currentDir, filename)
            currentNo = analsysEcxcel(currentFile, currentNo)

# 현재 파일 갯수를 출력. 심심하니깐.
print('File Count : %d' % currentFileNo)

 


WRITTEN BY
비트센스
뷰파인더로 보는 프로그래머의 세상 페이스북 @bitsense 트위터 @picory 스카이프 picory MSN drawhalf@dreamwiz.com

트랙백  0 , 댓글  0개가 달렸습니다.
secret

Google App Engine(이하 gae) 사용시 local mysql 연동에 문제가 좀 있더군요. 이리 저리 자료를 찾아서 정리를 했습니다.

파일다운로드 URL :
http://www.lfd.uci.edu/~gohlke/pythonlibs/#mysql-python

app.yaml 추가

libraries:

- name: MySQLdb
  version: "latest"

샘플 소스

import MySQLdb

CLOUDSQL_INSTANCE = '127.0.0.1' #localhost라고 하면 연결이 안되네요
DATABASE_NAME = 'database'
USER_NAME = 'root'
PASSWORD = '비밀번호'

def get_connection():
    kwargs = {
              'db': DATABASE_NAME,
              'user': USER_NAME,
              'passwd': PASSWORD,
              'port': 3306,
              'charset': 'utf8' #없으면 한글이 깨집니다.
              }

    return MySQLdb.connect(CLOUDSQL_INSTANCE, **kwargs)

class DbHandler(BaseHandler):
    def get(self):
        # Viewing guestbook
        conn = get_connection()
        cursor = conn.cursor()
        cursor.execute('SELECT idx, code, level FROM user_group '
                       'ORDER BY created_at DESC limit 20')
        rows = cursor.fetchall()
        conn.close()
        template_values = {"rows": rows}
        self.templates('test/test.html', **template_values);


app = webapp2.WSGIApplication([
    ('/db', DbHandler),
], debug=True)



WRITTEN BY
비트센스
뷰파인더로 보는 프로그래머의 세상 페이스북 @bitsense 트위터 @picory 스카이프 picory MSN drawhalf@dreamwiz.com

트랙백  0 , 댓글  0개가 달렸습니다.
secret

공식사이트 :
http://celestialteapot.com/exedore/




WRITTEN BY
비트센스
뷰파인더로 보는 프로그래머의 세상 페이스북 @bitsense 트위터 @picory 스카이프 picory MSN drawhalf@dreamwiz.com

트랙백  1 , 댓글  0개가 달렸습니다.
secret

카카오톡 연동 API :
https://github.com/HallaZzang/pykakao


WRITTEN BY
비트센스
뷰파인더로 보는 프로그래머의 세상 페이스북 @bitsense 트위터 @picory 스카이프 picory MSN drawhalf@dreamwiz.com

트랙백  0 , 댓글  0개가 달렸습니다.
secret