티스토리 뷰

보는 사람도 없는 것 같고..해서 계속 해야하나 고민을 좀 했는데
횽들의 말을 듣고 깨달았어

달릴 때 바람은 필요 없는거다!
뭐..이정도?
(그래도 관심 1g만...; )

그리고 라따뚜이 봤는데, 정말 재미있더라.
Anyone can cook!

오늘의 목표
  • 쿠키 사용해 중복 방문 걸러내기!
세부사항
  • cookie모듈의 사용법을 알자.
  • 누구나 프로그래밍 할 수 있다.


어제의 완성 코드.
#! /usr/bin/python

import os
import time

fileName = 'count.dat'
def loadCount():
    if os.path.exists(fileName):
        L = file(fileName, 'r').read().split('\n')
        today, total = map(int, L)
        return today, total
    return 0, 0

def incrCount():
    today, total = loadCount()
    if os.path.exists(fileName) and time.localtime()[2] != time.localtime(os.path.getmtime(fileName))[2]:
        today = 0

    today = today + 1
    total = total + 1
    file(fileName, 'w').write('%s\n%s' % (today, total))
    return today, total

today, total = incrCount()
print 'Content-Type: text/plain\n'
print 'Today : %s' % today
print 'Total : %s' % total


파이썬에는 기본적으로 쿠키를 관리할 수 있는 Cookie 모듈이 있어.
>>> import Cookie

이 쿠키 모듈에는 쿠키 클래스가 있는데 알아야 하는게 SimpleCookie랑, SmartCookie이 두개야.
쿠키에 그냥 문자들만 저장하려면 SimpleCookie를 사용하면 되고, 객체를 저장하려면 SmartCookie를 사용하면 돼,
우리는 그냥 30분 이내에 방문 했었나만 확인하면 되니까, SimpleCookie를 사용하기로 하자구.
>>> c = Cookie.SimpleCookie()    이 c가 우리가 저장할 쿠키야.

뭐..어차피 우리한테 필요한건 그냥 아무 값이나 만들고 그게 30분간 유지되도록 하면 되니까.
아무 이름에 아무 값이나 써버렸어; (이름 짓기 귀찮아효 ;ㅁ; )
>>> c['auth'] = 'Hello'     

그리고 만료 시간 정해줘야지. 만료는 초단위로 지정해 주면 돼. 몇초 후에 만료될 지.
>>> c['auth']['expires'] = 60*30    

그리고 마지막으로 헤더 뿌릴때 쿠키도 뿌려줘야지.
>>> print c  이리하면
Set-Cookie: auth=Hello; expires= 날짜 이런식으로 나오는데, 쿠키 모듈 쓰기 싫음 직접 프린트를 해버려도 되는데...아무튼 그냥 저리 알고 사용하자., 자세한 내용이 알고싶다면 관련 http 헤더에 관한 문서를 찾아봐. 웹 프로그래밍을 한다면 그정도는 꼭 봐야된다고 봐.

여기까지 쿠키를 굽는걸 알아봤는데...이건 뭐 설명도 아니고 코드도 아니고..이론도 아니고 실전도 아니고..
쓸모가 없구만 쓰기가 싫어지는데...그래도 완주는 해야겠지!

일단 읽어노는 것도 쿠키 객체를 생성하는 것 까진 똑같아!
>>> c = Cookie.SimpleCookie()  

그 다음에 쿠키 불러오기!
os.environ에 환경 변수들이 들어있어. 우리는 쿠키가 필요하니까 기거서 쿠키를 가져와서! 쿠키 객체를 셋팅해주자구!
>>> c.load(os.environ["HTTP_COOKIE"])
이리 하면 생길 수 있는 문제는? os.environ에 쿠키값이 없으면!!!? 에러가 나겠지. 고로....없으면 로드를 하지 말아야지.
>>> if os.environ.get("HTTP_COOKIE"):
get은 사전형에 있는 메소든데 넘겨준 키가 사전에 있으면 그 값을 넘겨주고 없으면 None을 넘겨주거든?
사전에서 어떤 값을 불러와야 하는 다른 방법은 os.environ['HTTP_COOKIE']인데 이 경우는 없는 키를 달라고하면 에러가나. 그래서 여기선 get을 사용했어.

아무튼 위에서 얘기한 두개를 합치면 우리가 원하는 결과를 얻을 수 있지.
>>> if os.environ.get("HTTP_COOKIE"):
>>>     c.load(os.environ["HTTP_COOKIE"])

자, 이제 쿠키를 불러오는 것 까지 됐고, 먼저 페이지에서 쿠키에 구웠던 auth가 잘 있는지 확인을 해보자구!

불러오는건 c['auth'].value 라고 쓰면 되는데 c에 'auth'가 없으면 에러가 나거든?
그러니까 먼저 c에 auth가 있나를 봐야겠지.
쿠키 객체는 사전이랑 비슷하거든? (이런 문제는 사전을 사용할때도 똑같아. )
쿠키 객체 안에 키:값 요렇게 묶여있어. 거기서 쿠키 객체에 키가 뭐가 있나~~보려면
c.keys() 요래 하면 되는거지. (사전이랑 같아)

자 여기서 in 연산자를 설명해야겠네.
파이썬을 슈두코드처럼 보이게 하는 훌륭한 몇가지중에 하나가 바로 이 in인데,

>>> '1' in '12345'   =>  True
>>> 'python' in 'happy python' => True
>>> 'python' in ['python', 'C++']   => True
>>> 'python' in {'python':'language'}   => True
>>> 'python' in ('python')   => True

이렇게만 써놔도 알겠지? A in B   A가 B에 들어있으면 참! 없으면 거짓!

>>> if 'auth' in c.keys():   요래하면?  c.keys()가 ['auth']니까 'auth'가 ['auth']에 있나? 라는게 되는거!
그래서, c에 'auth'에 값이 있으면 어쩌까?
있으면....좋은거지 뭐~
아까 우리가 cookie를 선언할 때 시간도 정해줬잖아?
그러니까..그 시간 내에 다시 접속했으면 auth가 있을거고 없으면 뭐..시간 내에 안온거니까 카운트를 올려줘야겠지?

코드로 작성해보자고..
>>> if 'auth' in c.keys(): 이렇게 쓰면 'auth'가 있는 경우인데 우린 없는 경우에 카운트를 올려줘야 하니까!
>>> if 'auth' not in c.keys(): 이래 써야겠네. not in
그럼..없는 경우에는 어째? 카운트를 올려줘야지.
>>> if 'auth' not in c.keys():
>>>     incrCount()
그럼 된건가?

정리를 해봅세!

완성코드
#! /usr/bin/python

import os
import time
import Cookie

fileName = 'count.dat'
def loadCount():
    if os.path.exists(fileName):
        L = file(fileName, 'r').read().split('\n')
        today, total = map(int, L)
        return today, total
    return 0, 0

def incrCount():
    today, total = loadCount()
    if os.path.exists(fileName) and time.localtime()[2] != time.localtime(os.path.getmtime(fileName))[2]:
        today = 0

    today = today + 1
    total = total + 1
    file(fileName, 'w').write('%s\n%s' % (today, total))
    return today, total

def burnCookie():
    c = Cookie.SimpleCookie()  
    c['auth'] = 'Hello'
    c['auth']['expires'] = 60*30
    print c

def loadCookie():
    c = Cookie.SimpleCookie()
    if os.environ.get("HTTP_COOKIE"):
        c.load(os.environ["HTTP_COOKIE"])
    return c

c = loadCookie()

if 'auth' not in c.keys():
    today, total = incrCount()
    burnCookie()
else:
    today, total = loadCount()

print 'Content-Type: text/plain\n'
print 'Today : %s' % today
print 'Total : %s' % total

정리하면서 기능별로 함수로 묶고 사용하는 부분도 막 설명 없이 고치고, 했는데....전에 이미 설명했던 것들이라 그냥 빼버렸어. (귀찮아서.......)
이야~ 코드가 꽤나 길어졌네.

아무튼 카운터는 이제 끝났네. 사실....중간 코드들은 안돌려봐서 돌아가나 모르겠어 ㅎㅎ
보는 횽들이 하다가 안되는 거 있음 지적해줘~, 모르겠다 싶은 부분 질문도 환영!

이제 다음 시간에 TDD를 사용하면서 숫자를 한글로 변환하는 코드를 만들면 카운터 만들기가 마무리!!!
댓글
댓글쓰기 폼