mesodiar

Having me on those pictures are the prove that I was there

Month: December 2016

[Cron] เขียน slackbot ส่ง notification เตือน standup meeting

โจทย์คือ เราต้องการสร้าง Slackbot เพื่อแจ้งเตือนใน channels ที่เรา subscribe ไว้ ตอนเวลา 9.59 น.ตอนเช้า เพื่อในเวลา 10.00 น.จะมี standup meeting ที่ Pronto Tools

Set up environment

$ virtualenv venv

$ source venv/bin/activate

โหลด slackclient API library เพื่อที่จะให้เราส่งและรับข้อความจาก Slack ให้ได้ก่อน

(venv) $ pip install slackclient

  1. ก่อนอื่น ไปสร้าง Slack team ให้เรียบร้อย หรือจะใช้ที่มีอยู่ก็ได้

2. เข้าไปสร้าง bot

note : แต่ชื่อจะซ้ำกับ Slackbot ซึ่งเป็น bot จริงๆของ Slack ไม่ได้นะ

Read More

[Cron] มาเล่น cron กันเถอะ

เคยไหมที่เราจะต้องทำ task แบบเดิมๆในช่วงเวลาเดิมๆของทุกวัน ในการพัฒนาระบบ web application

แทนที่เราจะมานั่งรันคำสั่งแบบเดิมๆทุกวัน Cron ได้ตอบโจทย์ของเรา

Cron คืออะไร

Cron มีไว้เพื่อ schedule tasks ที่เราต้องการเช่น กำหนด ณ เวลาเท่านี้ จะต้องทำ task นี้ มันก็จะไปทำ task ตาม script ที่เราเขียนเพื่อไปรัน server

หรือเรียกอีกอย่างว่าเป็น Job scheduler ซึ่งใช้สำหรับ Unix-like operating systems นั่นเอง

และแต่ละ task หรือ job จะถูกเรียกง่ายๆว่า Cron Jobs

ถ้ายังนึกภาพกันไม่ออก ยกตัวอย่างเช่น

  • บริษัท A มีระบบ membership ซึ่งมีจำนวนสมาชิกเยอะมาก เมื่อถึงวันหมดอายุของสมาชิกลูกค้า ก็ไม่จำเป็นมานั่งกด deactivate หรือลบ  account เอง
  • บริษัท B อยากส่ง newsletter email ในรอบวัน หรือประจำเดือน  เพื่อโปรโมตสินค้า
  • บริษัท C มีระบบที่เช็คว่าใน website มีอะไรพังบ้าง จึงอยากให้มีระบบแจ้งเตือนเข้า email ทันที

 

Syntax

ตัวอย่างเช่น

Read More

[Python] Django project: 03 Make it dynamic

2016-12-27-180347-801168

สิ่งที่เราต้องการคืออยากให้ข้อมูลเก็บลงใน database และนำมาแสดงบนหน้า html

 อย่างแรกที่ต้องทำ หนีไม่พ้นสร้าง Model แน่นอน

Django Model

สร้าง model ใน kitten/models.py

from __future__ import unicode_literals

from django.db import models

class Kitten_image(models.Model):

   image_name = models.CharField(max_length=100)

    width = models.CharField(max_length=10)

    height = models.CharField(max_length=10)

เมื่อเราสร้าง model ของตัวเองแล้ว สิ่งที่เราต้องทำคือ add model ไปยัง database

Read More

[Python] Django Project: 02 Get image via API

kittens

สืบเนื่องจาก โพสนี้ 

เราต้องการที่สร้างโปรแกรมใส่ width และ height ที่ต้องการเพื่อให้แสดงรูปภาพแมวเหมียวขึ้นมา

จากคราวที่แล้ว เมื่อเซตอัพเสร็จ ก็ถึงเวลาที่จะสร้างโปรแกรมจริงๆจังๆสักที

Create own application inside project

(venv)   django_project$ python manage.py startapp kitten

แต่เราต้องบอก Django ว่าสร้าง application อะไรไป

เข้าไปใน mysite/settings.py

INSTALLED_APPS = [

    ‘django.contrib.admin’,

    ‘django.contrib.auth’,

    ‘django.contrib.contenttypes’,

    ‘django.contrib.sessions’,

    ‘django.contrib.messages’,

    ‘django.contrib.staticfiles’,

    ‘kitten’,

]

——

Manage URL

การที่ Django จะรู้ว่ามีหน้าไหนบ้างนั้น เราต้องระบุใน mysite/urls.py

from django.conf.urls import include, url

from django.contrib import admin

urlpatterns = [

    url(r’^admin/’, admin.site.urls),

    url(r”, include(‘kitten.urls’)),

]

Django ตามหา url ยังไง? คำตอบคือใช้สิ่งที่เรียกว่า Regex หรือ Regular Expression ซึ่งมันคือ search pattern

ตัวสำคัญๆ เช่น

  • ^  ตอนเริ่ม text
  • $  ตอนจบ text
  • \d  สำหรับ digit
  • + to indicate that the previous item should be repeated at least once
  • () to capture part of the pattern

เราเพิ่ม  url(r”, include(‘kitten.urls’)) มาเพื่อให้เวลาเรียก url ก็จะไปตามหา url ใน application kitten ก่อน เพื่อการจัดการที่เป็นระบบที่ง่ายขึ้น

ดังนั้นเราต้องสร้าง urls ของ application ของเรา

from django.conf.urls  import url

from . import views

urlpatterns = [

    url(r’^$’, views.kitten_home, name=’kitten_home’),

]

เพื่อให้หน้า http://127.0.0.1:8000/ จะแสดงหน้า homepage ของ application

โดยเราให้ views ไปเรียก kitten_home ไปยัง url ^$

kitten/views.py

from django.shortcuts import render

import requests

def kitten_home(request):

       return render(request, ‘kitten_home.html’, {})

แต่สิ่งที่เกิดขึ้นคือ

screen-shot-2559-12-26-at-10-12-35-am

ไม่มีไฟล์ kitten_home.html นั่นเพราะเรายังไม่มี template มาให้แสดงนี่เอง

——

Create Template

เราสร้าง directory ขึ้นมาใหม่ภายใน kitten ของเราเพื่อแยกพวกไฟล์ template ต่างหาก

โดยสิ่งที่เราสร้างคือ form รับขนาด width และ  height และเมื่อกดปุ่ม Get Image จะต้องได้รูปแมวเหมียวออกมา

template/kitten_home.html

[code language=”html”]

{% load static %}

<html>
<head> <title> Kitten </title>
</head>
<!– Latest compiled and minified CSS –>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!– Optional theme –>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<!– Latest compiled and minified JavaScript –>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<body>
<div class="row">
<div class="col-md-4"></div>
<div class="col-md-4">
<form class="form-inline" method="post">
{% csrf_token %}
<div class="form-group">
<label for="input_width">Width</label>
<input name="input_width" type="text" class="form-control" id="input_width" placeholder="insert width"></div>
<div class="form-group">
<label for="input_height">Height</label>
<input name= "input_height" type="text" class="form-control" id="input_height" placeholder="insert height"></div>
<button type="submit" class="btn btn-default" value="OK">Get Image</button>
</form>

<img src="{% static ” %}{{ kitten_image }}"></div>
<div class="col-md-4"></div>
</div>
</body>
</html>

[/code]

โดยการรับ input นั้น จะต้องตรวจสอบผ่าน forms.py ว่าต้องรับเป็น field type อะไร

kitten/forms.py

from django import forms

class KittenForm(forms.Form):

    input_width = forms.CharField(label=’input_width’, max_length=10)

    input_height = forms.CharField(label=’input_height’, max_length=10)

(https://docs.djangoproject.com/en/1.10/topics/forms/#forms-in-django)

kitten/views.py

[code language=”python”]

from django.shortcuts import render
from .forms import KittenForm
import requests
def kitten_home(request):
if request.method == ‘POST’:
form = KittenForm(request.POST)

if form.is_valid():
url = "http://placekitten.com/g/" + form.cleaned_data[‘input_width’] + "/" + form.cleaned_data[‘input_height’]
kitten = requests.get(url)
f = open("kittens.png", "w")
f.write(kitten.content)
f.close
else:
form = KittenForm()
return render(request, ‘kitten_home.html’, {‘kitten_image’: "kittens.png"})

[/code]

ครั้งแรกที่เข้า url นี้จะเป็น GET request จะเป็นการสร้าง form instance เปล่าๆ และในครั้งถัดไป เมื่อ submit ก็จะเป็นการ Post Request เข้าสู่ form instance

return render(request, ‘kitten_home.html’, {‘kitten_image’: “kittens.png”})

นั้นจะส่ง path ของรูปภาพที่เราสร้างไว้ กลับไป render ที่ template ใน ด้วยวิธี การจัดการกับ static files

ใน settings file จะมี STATICFILES_DIRS บอกถึง path ที่ให้ไปหา static files ที่ได้เก็บไว้

STATICFILES_DIRS = [
    os.path.join(BASE_DIR),
]

ทำให้เมื่อเราใส่ {% static ” %}{{ kitten_image }} เท่ากับการใส่  path ปัจจุบัน + ภาพไฟล์

ทำให้ template แสดงรูปภาพออกมาได้ตามนี้

{% load static %}
 <img src="{% static '' %}{{ kitten_image }}">

(https://docs.djangoproject.com/en/1.10/howto/static-files/)

Screen Shot 2559-12-27 at 9.13.25 AM.png

[Python] Django Project : 01 Setting up

Django คืออะไร ?

Django คือ open source web framework ตัวหนึ่งที่

1. ฟรี

2. เขียนด้วย Python

framework คืออะไร?

framework คือตัวช่วยในการสร้าง websites ที่ทำให้งานเราง่ายขึ้นและสะดวกขึ้น ตัวอย่างเข่น ระบบ authentication ( sign up, sign in, บลาๆ ), การจัดการ form บน website หรือแม้การโหลดไฟล์ก็ตาม

ทำให้ปัญหาเดิมๆที่เราต้องเผชิญเวลาสร้าง websites ใหม่ๆมีน้อยลงด้วยการใช้ของสำเร็จที่ django เขาสร้างมาเรียบร้อยแล้ว

Installation

  1. install python

install Homebrew  ลง package manager ก่อนเลย เพื่อลง Setuptools และ pip ให้เรา

$ /usr/bin/ruby -e “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)

และลง python3

$ brew install python3

2. install virtualenv

สร้าง virtual environment สำหรับ project เรา

$ mkdir django_project

$ cd django_project

$ virtualenv venv 

(http://docs.python-guide.org/en/latest/dev/virtualenvs/)

คำสั่งนี้ virtualenv venv จะ สร้าง folder ใน current directory

และเราจะเลือกใช้ Python3 ในนี้  ด้วยคำสั่ง

virtualenv -p python3 venv

3. install Django

คราวนี้เมื่อเราได้ virtualenv สร้าง environment เรียบร้อยแล้ว เราก็มาลง Djangoกันได้เลย

แต่แน่นอน ก่อนอื่นต้องมั่นใจว่าเราได้ pip เวอร์ชั่นล่าสุดก่อน

$pip install –upgrade pip

$ pip install django

ถ้า django ถูกลงแล้ว จะต้องเห็น version

$ python -m django –version

เริ่มโปรเจคกัน

อย่าลืมว่าเราต้องรันทุกอย่างของโปรเจคนี้ใน virtualenv จึงต้อง activate กันก่อน

เข้าไปใน directory ที่แล้วต้องการแล้ว

source myvenv/bin/activate

ต่อด้วย

(venv)   django_project$  django-admin startproject mysite .

คำสั่งนี้จะ auto-generate โค้ดเพื่อสร้าง Django Project ให้แก่เรา

mysite/
    manage.py
    mysite/
        __init__.py
        settings.py
        urls.py
        wsgi.py

# ต้องใช้ . ด้วย เพื่อบอก script ว่า install django ใน current directory นะ และทำให้ไฟล์ manage.py ก็จะมาอยู่ใน directory นี้ ซึ่งเป็นตัวสำคัญที่ต่อไปจะเป็นตัว start server ให้

# django-admin.py คือสคริปต์ที่จะสร้าง directory แล้ว file ให้เรา

# settings.py คือ configuration ของ website

แก้ Configuration เรื่อง Time zone กันก่อน

# เข้า mysite/settings.py ไป set เวลา timezone เซตที่ TIME_ZONE = ‘Asia/Bangkok

# ตรง debug = True

ALLOW_HOSTED = [’127.0.0.1’]

ตัว allowed_hosts เหมือนเป็นการระบุ whitelist ของ domain ว่า site ไหนปลอดภัยแก่การ respond ซึ่งตัว Django นั้นเองเป็นคนสร้าง security ตัวนี้เพื่อป้องกันปัญหาเรื่อง Phishing attack นั่นเอง

Phishing ออกเสียงเหมือน Fishing เป็นการตกเบ็ด นั่งรอเฉยๆเพื่อให้เหยื่อเข้ามาหาเอง อย่างเช่น การที่สร้าง websites ปลอม หน้าตาดูเชื่อถือ เพื่อให้เราเชื่อแล้วกรอกข้อมูลส่วนตัว คนรอเบ็ดก็วินไปได้ข้อมูลเราไปใช้ทำมิดีมิร้ายด้าย

(https://www.djangoproject.com/weblog/2013/feb/19/security/)

เซต database 

เข้ามาใน mysite/settings.py

เราเลือกใช้ SQLite เพราะเป็น default ของ python อยู่แล้ว ไม่ต้องทำอะไรเพิ่ม แต่ถ้าอยากได้ database ที่ scalable กว่าก็เลือก PostgreSQL ไปนะแจ๊ะ

DATABASES = {

    ‘default’: {

        ‘ENGINE’: ‘django.db.backends.sqlite3’,  // ไม่ก็ ‘django.db.backends.postgresql’

        ‘NAME’: os.path.join(BASE_DIR, ‘db.sqlite3’), // ถ้าใช้ sqlite3 ตัว database จะสร้างไฟล์ลงในเครื่องของเราให้เลย

    }

}

ถ้าใช้นอกเหนือ SQLite ล่ะก็ ต้องรันคำสั่ง “CREATE DATABASE database_name;” ด้วยนะ

Migrate 

ในส่วนต้นๆของไฟล์ ที่ INSTALLED_APPS จะมีชื่อของ Django Applications ต่างๆมาเป็น default ให้อยู่ละ

พวก apps เหล่านี้จะต้องใช้ database เราจึงต้อง create database ขึ้นมาถึงจะใช้ apps เหล่านี้ได้

$ python manage.py migrate

( ต้องอยู่ที่ๆมี manage.py นะแจ๊ะ)

คำสั่งนี้จะ create และ update database ไปในตัว

Start web server

มาดูหน่อยซิว่า work ไหม

(venv)   django_project$ python manage.py runserver

เปิดเข้าไปใน http://127.0.0.1:8000/ แล้วก็จะพบกับ

screen-shot-2559-12-23-at-4-30-24-pm

happy-crying-face-meme-11

เย้

[Python] เขียน API ดึงรูปแมวเหมียวมาเซฟด้วย Requests Library !

[เขียนโค้ด] เขียน API เซฟรูปแมวเหมียวด้วย Requests Library!

เราจะมาเข้าใจการใช้ Requests ด้วยวิธีง่ายๆ ด้วยการทำเรื่องง่ายๆ อย่างเช่นตัวอย่างที่จะอธิบายต่อไปนี้ คือการดึงรูปมาเซฟ นั่นเอง

เริ่มต้นเลย! เรามีเว็บไซต์ง่ายๆ http://placekitten.com/ ที่เพียงแค่ใส่ image size ใน URL ก็สามารถได้รูปแมวเหมียวขึ้นมา

เช่น http://placekitten.com/g/300/200

kittens

นั่นคือ กว้าง 300 px, สูง 200 px

สิ่งต่อไปคือ เราจะเซฟรูปยังไงนะ?

คีย์ลัดของเราคือ Requests Library

Requests คืออะไร?

Requests คือ HTTP Library ตัวหนึ่งที่เขียนด้วยภาษา Python (for human beings เป็นมิตรกับสุขภาพจิต)  ให้เราส่ง HTTP/1.1 request ไปได้ (https://github.com/kennethreitz/requests)

ตัวอย่างการใช้ requests เช่น

>>> import requests

>>> r = requests.get(‘https://api.github.com/user’, auth=(‘user’, ‘pass’))

>>> r.status_code

200

>>> r.headers[‘content-type’]

‘application/json; charset=utf8’

>>> r.encoding

‘utf-8’

>>> r.text

u'{“type”:”User”…’

>>> r.json()

{u’private_gists’: 419, u’total_private_repos’: 77, …}

เริ่มต้นด้วยการ install package นี้เข้าเครื่อง

ด้วยคำสั่ง

$ pip install requests

หรือจะ clone มาโดยตรงจากผู้สร้างก็ได้

$ git clone git://github.com/kennethreitz/requests.git

จากนั้นเราก็เริ่มโค้ดกันได้เลย!

เริ่มต้น ทำกรอบง่ายๆด้วยการสร้าง class และแบ่งเป็นคอนเซปง่ายๆดังนี้

import requests

class Kitten():

   // 1. ทำ url ให้สมบูรณ์ : การที่เราจะดึงข้อมูลจาก placekitten ได้ เราจะต้องรู้ที่อยู่ (url) ของไฟล์ที่เราต้องการจะเซฟก่อน โดยการป้อนwidth และ height เข้าไป

   // 2. เขียน request เพื่อที่จะดึงข้อมูลนั้น

   // 3. นำข้อมูลที่ดึงมา เขียนลงไฟล์ที่เราสร้างขึ้นมาในเครื่อง (เซฟรูป)

  1. เราต้องการจะทำให้ได้รูปตามที่ความยาวและความกว้างที่เรากำหนด custom เอง ดังนั้นจึงสร้างตัวแปรรับค่า

width = raw_input(“How wide do you want image to be?”)

height = raw_input(“How tall do you want image to be?”)

ค่า url ที่ได้จึงควรจะเป็น

url = “http://placekitten.com/g/” + width + “/” + height

เท่านั้นเราก็ได้ url แล้ว!

  1. สิ่งถัดไปคือ เมื่อเราได้ที่อยู่ของข้อมูลแล้ว เราก็เขียน API เรียก request เพื่อเอาค่านั้นมา โดยวิธี requests.get()

kitten = requests.get(url)

และค่าที่เราได้จะนำไปเก็บที่ตัวแปร kitten

3. นำข้อมูลที่ดึงมาเรียบร้อยแล้วลงไฟล์ที่เราสร้าง !

f = open(“kittens.png”, “w”)  // open() เป็นฟังก์ชั่น built-in ของ python เพื่อบอกว่าต้องการจะเขียนไฟล์ png ขึ้นมาใหม่ ชื่อว่า kittens แต่แค่เปิดไว้เฉยๆ ยังไม่ได้ทำอะไร

f.write(kitten.content)  // นำข้อมูลที่เราได้ดึงมาก่อนหน้า นำมาเขียนลง kittens.png ที่เปิดคาไว้ให้แล้ว

f.close // ปิดไฟล์

สังเกตว่าข้อมูลที่ดึงมานั้น( kitten) จะใช้เฉยๆไม่ได้ เพราะเราได้ kitten เป็น object ที่เป็น dictionary

ถ้าเราลอง kitten.__dict__ ดู จะเจอ

{‘cookies’: <RequestsCookieJar[Cookie(version=0, name=’__cfduid’, value=’df2b7c0cd57b968b95249e432bca8a3b91482412416′, port=None, port_specified=False, domain=’.placekitten.com’, domain_specified=True, domain_initial_dot=True, path=’/’, path_specified=True, secure=False, expires=1513948416, discard=False, comment=None, comment_url=None, rest={‘HttpOnly’: None}, rfc2109=False)]>, ‘_content’: ‘\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00\xff\xfe\x00;CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), quality = 65\n\xff\xdb\x00C\x00\x0b\x08\x08\n\x08\x0…. บลาๆเยอะมาก ‘ }

ใน content นั่นเองที่เก็บข้อมูลรูปภาพอยู่ นั่นคือต้องใช้ kitten.content เขียนลงไปในไฟล์ใหม่

จบคอนเซปหลักๆ เราก็ fill in โค้ดได้เลย

import requests

class Kitten():

    def get_width_and_height(self, width, height):       /// ฟังก์ชั่น เพื่อรับค่า input ของ weight และ height

        self.width = width

        self.height = height

        return (self.width, self.height)

    def get_image(self): /// ฟังก์ชั่น เพื่อสร้างรูปภาพขึ้นมา

        url = “http://placekitten.com/g/” + self.width + “/” + self.height   

        kitten = requests.get(url)

        f = open(“kittens.png”, “w”)

        f.write(kitten.content)

        f.close

        return url

width = raw_input(“How wide do you want image to be”)             

height = raw_input(“How tall do you want image to be”)

x = Kitten()

x.get_width_and_height(width, height) /// instantiate เพื่อนำค่า width และ height เข้าฟังก์ชั่นแรก

x.get_image()

จากนั้นเมื่อเรารันไฟล์ ก็จะมีคำสั่ง How wide/tall do you want image to be ?  ให้เราป้อนขนาดรูปภาพที่ต้องการลงไป

คราวนี้ใน path เราก็มีรูปแมวเหมียวขึ้นมาแล้ว เย้

400

Powered by WordPress & Theme by Anders Norén