Month: September 2017

  • เตาะแตะไปกับ Docker ตอนที่ 7 Manage data

    Docker ให้เราสามารถเลือกใช้วิธีการ mount data เข้าไปให้กับ container อยู่ 3 อย่างคือ
    1. Volumes
    2. Bind mounts
    3. tmpfs mounts

    Volumes จะถูกเก็บอยู่ในส่วนของ Host filesystem ที่จัดการโดย Docker เอง (อยู่ที่ /var/lib/docker/volumes)
    และนี่เป็นวิธีที่ดีที่สุดในการจัดเก็บข้อมูลที่เป็น persistent data (ตามคำบอกในเว็บเพจ docs.docker.com)

    Bind mounts จะถูกเก็บอยู่ในที่ไหนก็ได้ของ Host filesystem เป็นวิธีการที่มีมาตั้งแต่ Docker รุ่นแรก ๆ จึงมีข้อจำกัดเมื่อเทียบกับ Volumes

    tmpfs mounts จะถูกเก็บอยู่ในหน่วยความจำของ Host เท่านั้น

    อ่านรายละเอียดเพิ่มเติมได้จากที่นี่ https://docs.docker.com/engine/admin/volumes/ และ
    https://docs.docker.com/engine/admin/volumes/#more-details-about-mount-types

    ผมขอเล่าถึงตัวอย่างการใช้งาน Volumes ใน docker-compose.yml (version 2) ที่ผมได้ทำเสร็จแล้ว

    $ cat docker-compose.yml 
    version: '2'
    services:
     openldap:
     image: openldap
     container_name: openldap
     volumes:
      - ldapdatavol:/var/lib/ldap
      - ldapconfigvol:/etc/ldap/slapd.d
     ports:
      - "389:389"
      - "636:636"
    
    volumes:
     ldapdatavol:
      external: false
     ldapconfigvol:
      external: false

    อธิบายได้ดังนี้ ในไฟล์ docker-compose.yml นี้ เราจะรัน services ชื่อ openldap จาก image ที่สร้างไว้แล้วชื่อว่า openldap โดยรันเป็น container ที่ผมตั้งชื่อว่า openldap โดยจะเก็บข้อมูลไว้ถาวรที่ volume ชื่อ ldapdatavol ซึ่งจะ mapped กับ /var/lib/ldap ใน container และอีกบรรทัดคือ ldapconfigvol จะ mapped กับ /etc/ldap/slapd.d ใน container

    ถัดมาด้านล่างของไฟล์ เราจะต้องประกาศ volumes ไว้ด้วยว่า ldapdatavol ไม่ได้เป็น volume ที่สร้างไว้อยู่แล้วก่อนการัน docker-compose ด้วยการประกาศค่าว่า external: false เช่นเดียวกับ volume ชื่อ ldapconfigvol

    แต่ถ้าใช้ external: true จะหมายถึง docker-compose จะไม่สร้าง volume ให้ นั่นคือ เราได้สร้างไว้ก่อนแล้วด้วยคำสั่ง

    $ docker volume create --name ldapdatavol
    $ docker volume create --name ldapconfigvol

    เราสามารถดูรายการ volume ด้วยคำสั่งนี้

    $ docker volume ls

    และที่เก็บจริง ๆ จะอยู่ที่นี่ /var/lib/docker/volumes ใช้คำสั่งเปลี่ยนสิทธิเป็น root เข้าไปที่เก็บ volume แล้วเราจะสามารถสำรองข้อมูลนี้ได้โดยใช้คำสั่ง cp หรือ tar ได้เลย ดังนี้

    $ sudo su -
    # cd /var/lib/docker/volumes

    การใช้งาน volume แบบที่แนะนำนี้เรียกว่า named volume คือ เราตั้งเป็นชื่อตามที่เราคิดเอง ส่วนอีกแบบจะเรียกว่า anonymous นั่นคือ docker ตั้งชื่อให้เอง อันนี้ผมไม่ลงรายละเอียดครับ

    จบตอนนี้เราก็จะพอเข้าใจได้แล้วว่า หากจะเก็บข้อมูลของ app เช่นในตัวอย่างนี้คือ openldap ผมจะเลือกใช้ named volume ครับ ข้อมูลจะอยู่ถาวร เรียกว่าการทำ persistent data ในขณะที่ถ้าเราไม่เพิ่มการใช้ volume เข้ามากำหนดที่เก็บข้อมูล หากเราลบ container ก็จะเป็นการลบข้อมูลซึ่งอยู่ใน container ไปด้วย นอกจากว่าเราต้องการให้เป็นอย่างนั้นอาจเพราะว่าข้อมูลเป็นแค่ตัวอย่างไม่สำคัญอะไร ก็ไม่ต้องใช้ volume ครับ

  • ELK #6 วิธีการติดตั้ง ELK และ Geoserver แบบ Docker ให้ทำงานร่วมกัน

    จาก ELK #5 การประยุกต์ใช้ ELK ในงานด้าน GIS และ การสร้าง Web Map Service (WMS) บน Geoserver ก็จะเห็นถึงการนำไปใช้เบื้องต้น

    >> ขอบคุณ คุณนพัส กังวานตระกูล สถานวิจัยสารสนเทศภูมิศาสตร์ทรัพยากรธรรมชาติและสิ่งแวดล้อม ศูนย์ภูมิภาคเทคโนโลยีอวกาศและภูมิสารสนเทศ (ภาคใต้) สำหรับความรู้มากมายครับ <<

     

    ต่อไปนี้ จะเป็นขั้นตอนการติดตั้ง ELK และ Geoserver แบบ Docker โดยผมได้สร้าง Github Repository เอาไว้ ซึ่งได้แก้ไขให้ระบบสามารถเก็บข้อมูลไว้ภายนอก

    Prerequisite

    1. ถ้าเป็น Windows ก็ต้องติดตั้ง Docker Toolbox หรือ Docker for Windows ให้เรียบร้อย
    2. ถ้าเป็น Linux ก็ติดตั้ง docker-ce ให้เรียบร้อย (เรียนรู้เกี่ยวกับ Docker ได้จาก ติดตั้ง docker 17.06.0 CE บน Ubuntu)

    ขั้นตอนการติดตั้ง

    1. สร้าง Folder ชื่อ Docker เอาไว้ในเครื่อง เช่นใน Documents หรือ จะเป็น D:\ หรืออะไรก็แล้วแต่
    2. เปิด Terminal หรือ Docker Quickstart Terminal จากนั้นให้ cd เข้าไปมา Folder “Docker” ที่สร้างไว้
    3. ดึง ELK ลงมา ด้วยคำสั่ง
      git clone https://github.com/deviantony/docker-elk.git
    4. ดึง Geoserver ลงมา ด้วยคำสั่ง (อันนี้ผมทำต่อยอดเค้าอีกทีหนึ่ง ต้นฉบับคือ https://hub.docker.com/r/fiware/gisdataprovider/)
      git clone https://github.com/nagarindkx/geoserver.git
    5. เนื่องจาก ไม่อยากจะไปแก้ไข Git ของต้นฉบับ เราจึงต้องปรับแต่งนิดหน่อยเอง
      ให้แก้ไขไฟล์ docker-elk/docker-compose.yml
      โดยจะเพิ่ม Volume  “data” เพื่อไป mount ส่วนของ data directory ของ Elasticsearch ออกมาจาก Containerแก้ไขจาก

      elasticsearch:
       build: elasticsearch/
       volumes:
       - ./elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml

      เป็น

      elasticsearch:
       build: elasticsearch/
       volumes:
       - ./elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
       - ./elasticsearch/data:/usr/share/elasticsearch/data
    6. สร้าง docker-elk/elasticsearch/data
      mkdir docker-elk/elasticsearch/data
    7. แก้ไขไฟล์ docker-elk/logstash/pipeline/logstash.conf ตามต้องการ เช่น ใส่ filter
      filter {
       csv {
         separator => ","
         columns => [
      	"cid","name","lname","pid","house","road","diagcode","latitude","longitude","village","tambon","ampur","changwat"
         ]
       }
       if [cid] == "CID" {
         drop { }
       } else {
         # continue processing data
         mutate {
           remove_field => [ "message" ]
         }
         mutate {
           convert => { "longitude" => "float" }
           convert => { "latitude" => "float" }
         }
         mutate {
           rename => {
             "longitude" => "[geoip][location][lon]"
             "latitude" => "[geoip][location][lat]"
           }
         }
       }
      }
    8. จาก Terminal ให้เข้าไปใน docker-elk แล้ว start ด้วยคำสั่ง
      cd docker-elk
      docker-compose up -d
    9. จาก Terminal ให้เข้าไปใน geoserver แล้ว start ด้วยคำสั่ง
      cd ../geoserver
      docker-compose up -d

    ถึงขั้นตอนนี้ ก็จะได้ ELK และ Geoserver ทำงานขึ้นแล้ว

    ELK: http://localhost:5601

    Geoserver: http://localhost:9090/geoserver/web

     

    ขั้นตอนต่อไป จะเป็นการ นำข้อมูลเข้า และ เชื่อ Kibana กับ Geoserver

    วิธีการนำข้อมูลเข้า Elasticsearch

    เนื่องจาก pipeline ของ Logstash กำหนดว่า จะรับข้อมูลทาง TCP Port 5000 จึงใช้วิธี netcat ไฟล์เข้าไป ด้วยคำสั่ง (ตัวอย่างนี้ ใช้ข้อมูลจากไฟล์ sample.csv)

    cat sample.csv | nc localhost 5000

    วิธีการดึง Map จาก Geoserver มาใช้งานใน Kibana

    ทำตามขั้นตอนที่กล่าวไว้ใน การสร้าง Web Map Service (WMS) บน Geoserver ซึ่งจะได้ URL ของ Layer Preview มา ประมาณนี้
    http://localhost:9090/geoserver/test/wms?service=WMS&version=1.1.0&request=GetMap&layers=test:hadyai_vil&styles=&bbox=631866.963048935,748605.6609660918,677997.0295239205,791055.6681053439&width=768&height=706&srs=EPSG:32647&format=application/openlayers

    ทำตามขั้นตอนที่กล่าวไว้ใน ELK #5 การประยุกต์ใช้ ELK ในงานด้าน GIS ในส่วนของ วิธีใส่ Map Server อื่น แล้วเอา URL นี้ไปใส่ และรายละเอียดเกี่ยวกับ Layer, version, format ตามที่กำหนดไว้ ก็จะสามารถเอา Map ที่เราต้องการ พร้อม Shape File มาใช้งานได้

    หวังว่าจะเป็นประโยชน์ครับ

  • date นั้นสำคัญไฉน

    ที่ Shell prompt พิมพ์คำสั่ง man date

    ได้อะไรมาไม่รู้เยอะแยะ…

    man date
    man date

    จากคู่มือจะเอารูปแบบวันที่ 12-09-2017 ตัวเลือกที่เกี่ยวข้องได้แก่ %d %D %e %F %g %G %m %y %Y เป็นต้น ลองส่งคำสั่ง

    date +"%d-%m-%Y"

    ได้ผลลัพธ์

    12-09-2017

    ตรงตามที่ต้องการ มาเขียนสคริปต์กันหน่อย อยากได้เมื่อวานทำไง วันนี้เล่น tcsh shell สร้างแฟ้ม date.tcsh ด้วย editor ที่ชื่นชอบมีข้อความว่า

    #!/bin/tcsh -f
    set tday=`date +"%d"`
    set tmonth=`date +"%m"`
    set tyear=`date +"%Y"`
    echo "Today is ${tday}-${tmonth}-${tyear}."
    set yday=`expr ${tday} - 1`
    echo "Yesterday was ${yday}-${tmonth}-${tyear}."

    ทดสอบสคริปต์ด้วยคำสั่ง

    tcsh date.tcsh

    ไม่อยากพิมพ์ tcsh ทุกครั้งเพิ่ม execution bit ด้วยคำสั่ง

    chmod +x date.tcsh

    เรียกใช้ได้โดยพิมพ์

    ./date.tcsh (อ่านว่า จุด-ทับ-เดต-จุด-ที-ซี-เอส-เอช)

    ผลลัพธ์ที่ได้

    Today is 12-09-2017.
    Yesterday was 11-09-2017.

    อยากได้เมื่อวานทำไมมันยากอย่างนี้ ฮา… ซึ่งเมื่อกลับไปอ่านคู่มือ (man date) ให้ดี..อีกครั้งจะพบว่ามีตัวเลือก

    -d, –date=STRING
    display time described by STRING, not ‘now’

    และเมื่่อเลื่อนลงมาล่างสุดจะพบว่า

    DATE STRING
    The –date=STRING is a mostly free format human readable date string such as “Sun, 29 Feb 2004 16:21:42 -0800” or
    “2004-02-29 16:21:42” or even “next Thursday”. A date string may contain items indicating calendar date, time of day,
    time zone, day of week, relative time, relative date, and numbers. An empty string indicates the beginning of the day.
    The date string format is more complex than is easily documented here but is fully described in the info documentation.

    โอ้ววว มันเขียนไว้หมดแล้ว…

    เขียนใหม่ได้ว่า
    date -d yesterday

    ได้ผลลัพธ์

    Mon Sep 11 21:43:51 +07 2017

    เปลี่ยนให้ผลลัพธ์ออกมาในรูปแบบที่ต้องการได้ด้วยคำสั่ง

    date -d yesterday +"%d-%m-%Y"

    ก็จะได้ผลลัพธ์ว่า

    11-09-2017

    แก้สคริปต์ date.tcsh

    #!/bin/tcsh -f
    set tday=`date -d today +"%d-%m-%Y"`
    set yday=`date -d yesterday +"%d-%m-%Y"`
    echo "Today is ${tday}."
    echo "Yesterday was ${yday}."

    เจ็บมาเท่าไหร่แล้วกับคำว่าไม่อ่านเอกสาร….

    ยังใส่ข้อความอื่นๆ แทน string ได้เช่น
    date -d 'tomorrow'
    date -d '-1 days ago'
    date -d '200 days'
    date -d '1000 weeks'
    date -d '30 months'
    date -d '300 years'

    เรื่องนี้สอนให้รู้ว่า บางทีเอกสารก็มีให้หมดแล้ว ไม่ต้องทำเองก็ด้ายยยยย….

    จบขอให้สนุก

    man date
    ค้นเพิ่มเติม https://www.cyberciti.biz/tips/linux-unix-get-yesterdays-tomorrows-date.html

  • การสร้าง Web Map Service (WMS) บน Geoserver

    จากบทความ ELK #5 การประยุกต์ใช้ ELK ในงานด้าน GIS ของคุณคณกรณ์ ถือว่าเป็นอีกช่องทางหนึ่งในการจัดทำแผนที่ GIS ซึ่งอาศัย Web Map Service หรือเรียกย่อๆว่า WMS ก็เลยทำให้คันไม้คันมือ อยากนำเสนอวิธีการสร้าง WMS บน Geoserver เพื่อนำ shape file ที่เราได้จัดทำขึ้น(ไม่ว่าจะเป็น point , line, polygon) มาใช้งานบน GIS Web Application ซึ่งทั่วไปก็จะใช้ UI เป็น Openlayers, Leaflet ฯลฯ

    **ลองแวะเข้าไปอ่านบทความเก่าๆของผู้เขียน จะมีการนำเสนอวิธีการนำ WMS ไปใช้ อาทิเช่นกับ Google Earth, ArcGIS เป็นต้น

    ขั้นตอนการสร้าง WMS บน Geoserver

    1. สร้างและกำหนด style ของข้อมูลในโปรแกรม QGIS

    2. save style เป็น SLD file โดยจัดเก็บไว้ที่เดียวกับ shape file

    3. Copy file ทั้งหมด

    4. ไปวาง(past) ไว้ที่ root folder ของ Geoserver ซึ่งในที่นี้จะอยู่ที่ C:\Program Files\Apache Software Foundation\Tomcat 7.0\webapps\geoserver\data\shpfile\slb-gis

    *** ดาวน์โหลด shape file ตามตัวอย่างได้ที่นี่

    5. เปิด Geoserver manager โดยพิมพ์ url: localhost:8080/geoserver     *** port สามารถปรับเปลี่ยนได้

    6. ทำการสร้าง Workspaces

    7. กำหนดชื่อ Workspace และ URI

    8. กำหนด properties ของ Workspace ให้เปิดใช้งาน (Enabled) Services ต่างๆ

    9. จากนั้นทำการสร้าง Stores ในการเก็บข้อมูล shape file (จากขั้นตอนที่ 4)

    10. เลือกชนิดของ data sources ในที่นี้จะเลือก Directory of spatial files (Shapefiles)

    11. ทำตามขั้นตอนในรูป

    1) เลือก Work space ที่สร้างไว้ในข้อ 7

    2) กำหนดชื่อ data

    3) กำหนด directory ที่เก็บ shape file

    4) เลือกโฟลเดอร์ จากข้อ 4

    5) คลิกปุ่ม OK

    จากนั้นเลืื่อนไปด้านล่างสุดของหน้าจอ เพื่อคลิกปุ่ม Save

    12. จะปรากฏหน้าต่างข้อมูล shape file ที่ถูกจัดเก็บไว้ในข้อ 4 ซึ่งในที่นี้มีเพียง 1 shape file คือ slbtamb > จากนั้นคลิกที่ Publish เพื่อเปิดการใช้งานชั้นข้อมูล

    13. จะแสดงชั้นข้อมูล slbtamb จากข้อ 12

    14. คลิกปุ่ม Find เพื่อกำหนดระบบพิกัดให้กับชั้นข้อมูล ในที่นี้ shape file เป็นระบบ UTM ผู้เขียนจึงใช้รหัส 32647

    15. จากนั้น คลิก Compute from native bounds เพื่อให้ระบบ generate พิกัดให้

    16. คลิกปุ่ม Save

    17. ทำการเพิ่ม SLD file ที่ได้จัดทำไว้ในข้อที่ 2 เพื่อการแสดงผลของแผนที่ให้มีลักษณะเหมือนดังเช่นที่ได้ปรับแก้ในโปรแกรม QGIS

    18. เลือก Workspace > คลิกเลือกไฟล์ ที่ได้จัดเก็บไว้ในข้อ 4 > คลิก Upload…

    19. จะแสดงโค้ดของ sld file ซึ่งตรงนี้ สามารถปรับแก้/เพิ่มเติมได้ > จากนั้นคลิกปุ่ม Submit

    20. กลับไปที่เมนู Layers จากข้อ 12 ให้คลิกแถบ Publishing > เลือก Default Style > เลือก style ที่ได้สร้างในข้อ 19

    21. จะแสดงรูปแบบของ style

    22. ทำการพรีวิวดูชั้นข้อมูลที่ได้สร้างขึ้น > คลิกเมนู Layer Preview > เลือกชั้นข้อมูล จากนั้นคลิก OpenLayers

    23. จะแสดงแผนที่ชั้นข้อมูลที่ได้นำเข้า shape file โดยการนำไปใช้ จะใช้

    WMS url และ Layers name

    *** ดูตัวอย่างการนำไปใช้เพิ่มที่

     

    หวังว่าจะเป็นประโยชน์กับหลายๆท่านที่ต้องการจะสร้าง GIS Web App. หรือมีข้อมูล shape file แล้วต้องการจะนำไป publish ขึ้นเว็บในรูปแบบของ GIS Web นะคับ

    ** ข้อดีของ WMS คือ เราจะแชร์เฉพาะ Service โดยที่ข้อมูล shape file ยังคงอยู่กับเรา(private) 

     

    สำหรับท่านใดที่นึกหน้าตา GIS Web Application ไม่ออก ลองแวะเข้าไปเยี่ยมชมได้ที่ http://slb-gis.envi.psu.ac.th

    หรือ download shape file เพื่อลองนำไปใช้ได้ที่ http://slb-gis.envi.psu.ac.th/ เมนู ฐานข้อมูล GIS

     

    ===============================================
    สถานวิจัยสารสนเทศภูมิศาสตร์ ทรัพยากรธรรมชาติและสิ่งแวดล้อม
    ศูนย์ภูมิภาคเทคโนโลยีอวกาศและภูมิสารสนเทศ ภาคใต้
    คณะการจัดการสิ่งแวดล้อม มหาวิทยาลัยสงขลานครินทร์
    เว็บไซต์ http://www.rsgis.psu.ac.th
    แฟนเพจ https://www.facebook.com/southgist.thailand

  • วิธีการ Upload ไฟล์ไปบน Google Drive File Stream ด้วย Google Client Library for Python

    Google Drive File Stream จริงๆแล้วก็คือการเปิดให้ PC ทั้ง Windows และ Mac สามารถ Map Drive จาก Google Drive มาเป็น G:\ หรืออะไรทำนองนั้น แต่ปัจจุบัน (September 2017) บน Windows Server ซึ่งใช้ Secure Boot จะไม่สามารถติดตั้ง Client ได้ และ Ubuntu Server ก็ยังไม่มีตัวติดตั้ง ดังนั้น ในภาพของผู้ดูแลระบบ ไม่สามารถใช้ความสามารถนี้ได้ … โดยตรง

    ส่วนใน Windows Desktop ทั่วไปก็จะติดตั้งได้ แม้ว่า จากคำโฆษณา จะบอกว่าผู้ใช้สามารถใช้งานได้ แม้พื้นที่บน Local Drive ไม่เยอะ แต่เอาเข้าจริง ด้วยความสามารถที่จะใช้งาน Offline ได้บ้าง ทำให้ Client ต้อง Cache ไฟล์ที่ใช้งานด้วยเช่นกัน และหาก upload ไฟล์ขนาดใหญ่ จาก Local Drive ไปเก็บใน G:\ ข้างต้น ก็จะทำให้ต้องเสียพื้นที่ในขนาดเท่าๆกันไปด้วย เช่น ใน Local Drive มีไฟล์ที่จะ Backup ขึ้นไป ขนาด 1 GB บน C:\ เมื่อทำการ Copy ไปยัง G:\ ก็จะเสียพื้นที่อีก 1 GB ด้วยเช่นกัน

    ทางออกก็คือ ใช้ความสามารถของ Google Client Library ทำการ Upload ไฟล์ขึ้นไปโดยตรง เท่าที่ทดลองมา จะไม่ได้ Cache บน Local Drive ทำให้สามารถ Upload ไฟล์ขนาดใหญ่ได้ โดยไม่เสียพื้นที่เพิ่มแบบ Client ข้างต้น

    วิธีการใช้งาน Python เพื่อ Upload File ขึ้น Google Drive File Stream

    1. ผมเขียน Code เอาไว้ ชื่อ upload2gdrive.py ไว้บน GitHub (https://github.com/nagarindkx/google) สามารถดึงมาใช้งานได้โดยใช้คำสั่ง
      clone https://github.com/nagarindkx/google.git
      cd google
    2. สร้าง Project, Credential ตาม “ขั้นที่ 1” ในบทความ การใช้งาน Google Drive API ด้วย Google Client Library for Python ซึ่งจะได้ไฟล์ Client Secret File มา ให้แก้ไขชื่อเป็น “client_secret.json” แล้ว นำไปไว้ใน directory “google” ตามข้อ 1
    3. วิธีใช้คำสั่ง
      ดูวิธีใช้

      python upload2gdrive.py --help

      Upload ไฟล์ จาก /backup/bigfile.tar,gz

      python upload2gdrive.py --file /backup/bigfile.tar.gz

      บน Windows ก็สามารถใช้งานได้ ด้วยคำสั่ง

      python upload2gdrive.py --file D:\backup\bigfile.tar.gz

      หากต้องการระบุตำแหน่ง Folder บน Google Drive ที่ต้องการเอาไฟล์ไปไว้ ให้ระบุ Folder ID

      python upload2gdrive.py --file /backup/bigfile.tar.gz ----gdrive-id xxxxxxxbdXVu7icyyyyyy

      หากต้องการระบุ Chunk Size (ปริมาณข้อมูลที่จะแบ่ง Upload เช่น ไฟล์ 1 GB หากกำหนด Chunk Size เป็น 100MB โปรแกรมจะแบ่งข้อมูลเป็น 10 ส่วน — ขนาดที่เล็กที่สุดคือ 1 MB และค่า Default คือ 100 MB)

      python upload2gdrive.py --file /backup/bigfile.tar.gz ----gdrive-id xxxxxxxbdXVu7icyyyyyy --chunk-size 100
    4. ผลการทำงานจะประมาณนี้

      ใน Google Drive ที่กำหนด ก็จะมีไฟล์ปรากฏอยู่

    หวังว่าจะเป็นประโยชน์ครับ

    PS: ในบทความต่อไป จะมาอธิบายว่า เขียนขึ้นมาได้อย่างไร โปรดติดตามชม

  • การใช้งาน Google Drive API ด้วย Google Client Library for Python

    ในบทความนี้ จะแนะนำวิธีการเขียน Python เพื่อติดต่อกับ Google Drive API ทาง Google Client Library ซึ่ง จะใช้ REST v2 [1] เนื่องจาก ใน REST v3 ยังหาทางแสดง Progress ไม่ได้ (หากได้แล้วจะมา Update นะ)

    สิ่งต้องมี

    1. Python 2.6 ขึ้นไป
    2. PIP Package Management Tool
    3. เครื่องต้องต่อ Internet ได้
    4. แน่นอน มี Google Account

    ขั้นที่ 1: เปิดใช้ Drive API

    เปิด URL https://console.cloud.google.com แล้วคลิก Select a project

    จากนั้นคลิกปุ่ม + เพือสร้าง Project

    ตั้งชื่อ Project แล้วคลิก Save

    เลือก Project ที่สร้างขึ้น เลือก API Library ที่ต้องการ ในที่นี้คือ Google Drive API

    แล้วคลิก Enable

    จากนั้น Create Credentials

    เลือกชนิดเป็น OAuth Client ID แล้วกรอกข้อมูลดังนี้

    สร้าง Consent Screen

    เลือก Application Type เป็น Web Application, ระบุ Name (จะแสดงตอนขอ Permission) แล้วตั้งค่า URL ทั้ง 2 อันเป็น http://localhost:8080

     

    และ สุดท้าย คลิก Download

    ก็จะได้ไฟล์ JSON มา ส่งนี้จะเรียกว่า “Client Secret File”  ให้เก็บไฟล์ไว้ใน Directory เดียวกันกับที่ต้องการจะเขียน Python Code โดยสามารถแก้ไขเปลี่ยนชื่อ เช่น ตั้งเป็น client_secret.json

    ขั้นที่ 2: ติดตั้ง Google Client Library

    ติดตั้งด้วย pip ตามคำสั่งต่อไปนี้

    pip install --upgrade google-api-python-client

    ขั้นที่ 3: เขียน Code เพื่อติดต่อ Drive API

    จาก Python Quickstart [1] เป็นการเริ่มต้นที่ดีมาก เราสามารถนำ Code มาเป็นจุดเริ่มต้นได้ โดยตัวอย่างจะทำการติดต่อไปยัง Google Drive แล้ว List รายการของไฟล์ 10 อันดับแรกออกมา

    ตัวอย่างที่ Google ให้มา จะอ้างอิงไปยัง Credentials Path ไปยัง directory “.credentials” ใน “Home Directory” ของผู้ใช้ แต่ในตัวอย่างที่จะแสดงต่อไปนี้ ได้แก้ไขให้ “Client Secret File” อยู่ที่ directory เดียวกับ python file และเมื่อทำการ Authorization แล้วก็จะได้ “Credential File” มาเก็บไว้ที่เดียวกัน

    Code ต้นฉบับ สามารถดูได้จาก https://developers.google.com/drive/v2/web/quickstart/python ในที่นี้จะเปลี่ยนเฉพาะส่วนที่ต้องการข้างต้น และ เขียน Comment เพื่ออธิบายเพิ่มเติมเป็นภาษาไทย (ซึ่งไม่สามารถเขียนลงไปใน Python Code ได้) โดยตั้งชื่อไฟล์ว่า listfile.py

    from __future__ import print_function
    ...
    # การกำหนด SCOPES ต้องสอดคล้องกับบริการที่เราจะใช้งาน
    SCOPES = 'https://www.googleapis.com/auth/drive.metadata.readonly'
    
    # แก้ไข Client Secret File ให้สอดคล้องกับไฟล์ที่ได้จาก ขั้นตอนที่ 1
    CLIENT_SECRET_FILE = 'client_secret.json'
    # แก้ไข Application Name ตามต้องการ
    APPLICATION_NAME = 'Drive API Python Quickstart'
    
    ...
    def get_credentials():
    ...
     # ไม่ใช้
     # home_dir =os.path.expanduser('~')
     
     # เดิม อยู่ใน os.path.join(home_dir, '.credentials')
     # แก้ไขให้อยู่ที่ Current Working Directory เดียวกันเลย
     credential_dir = os.getcwd()
     ...
     # เดิม os.path.join(credential_dir,'drive-python-quickstart.json')
     # ตั้งชื่อ Credential ตามต้องการ 
     credential_path = os.path.join(credential_dir,'drive_credential.json')
    ...
    
    def main():
    ...
     credentials = get_credentials()
     http = credentials.authorize(httplib2.Http())
    
     # ตรงนี้สำคัญ จะต้องเลือกใช้ REST Version ที่ต้องการ
     # ในที่นี้ ใช้ REST v2
     service = discovery.build('drive', 'v2', http=http)
     
     # ส่วนของการเขียน Code
     # ตัวอย่างนี้ เรียกใช้ files().list()
     # โดยตั้งค่า maxResults เป็น 10 ก็คือ เรียกเฉพาะ 10 รายการแรก
     # อ้างอิงจาก https://developers.google.com/drive/v2/reference/files/list
     results = service.files().list(maxResults=10).execute()
    
     # จาก อ้างอิง จะเห็นได้ว่า files().list() นั้น Return หรือ Response
     # items[] ซึ่งมี element เป็น รายการของไฟล์
     items = results.get('items', [])
     
     # ตรวจสอบว่ามีไฟล์หรือไม่
     if not items:
       print('No files found.')
     else:
       # หากมีไฟล์อยู่
       print('Files:')
       # loop เพื่อแสดงไฟล์ที่มีอยู่ ในที่นี้ จะไม่เกิน maxResults ข้างต้น
       for item in items:
         # แสดงฟิลด์ title และ id
         # เพิ่มเติม .encode('utf-8') ด้วย
         print('{0} ({1})'.format(item['title'].encode('utf-8'), item['id']))
    
    if __name__ == '__main__':
     main()

    ขั้นที่ 4: Run

    ตอนนี้ใน Directory จะมีไฟล์

    • client_secrets.json
    • listfile.py

    ใช้คำสั่ง

    python listfile.py

    หากเป็นการ Run ครั้งแรก ซึ่งจะยังไม่มีไฟล์ drive_credential.json โปรแกรมก็จะทำตาม “flow” โดย ถ้า run command line บนเครื่องที่มี X Window ก็จะเปิด Web Page ไปยัง Google เพื่อ Authorization

    และเปิด Web นี้ ให้คลิกเลือก Account ที่จะติดต่อด้วย

    หน้า Consent Screen คืออย่างนี้ คลิกอนุญาต

    ผลที่ได้

    Reference:

    [1] https://developers.google.com/drive/v2/web/quickstart/python