วันศุกร์, มิถุนายน 26, 2558

บันทึก การ build และแก้ปัญหา เพื่อลง GitHub's friends บน Mac OSX

จะลองติดตั้ง GitHub friends, P2P chat powered

friends เป็น chat application ที่ใช้ technology ของ P2P (แบบเดียวกับ bittorrent)
GUI ใช้ electron หรือ atom-shell ที่ github ใช้สร้าง Atom editor และปล่อย open source ด้วย ไปอ่านความเจ๋งของมันได้ที่ site ของเค้าได้เลย ที่นี่

วันนี้มาทดลอง build เล่นดีกว่า เพราะหา binary release ไม่เจอ -_-

ก่อนจะเริ่ม build ต้องมีบัญชีกับ github ก่อน (เค้าบอกว่าในช่วงแรกใช้แบบนี้ไปก่อน)

ติดตั้ง module ที่ต้องใช้ในการตรวจสอบก่อน

$ npm i github-current-user -g

ทดสอบว่า github เชื่อมต่อกับ account เราได้หรือยัง

$ DEBUG=* github-current-user

  ghsign SSH_AUTH_SOCK +0ms /private/tmp/com.apple.launchd.G4BHMbX15X/Listeners
  github-current-user username from .gitconfig: dahoba +47ms
  github-current-user signing with "dahoba" +3ms
  ghsign ssh-agent public keys ...

ถ้ามีปํญหาที่ขั้นตอนนี้ให้ลองตรวจสอบว่า git config username ของเราตรงกับ github account ของเราหรือยัง

$ git config --global user.username
dahoba

อย่างตัวอย่างนี้ก็ต้องได้ account ผมใน github ออกมา ถ้ายังไม่ตรงต้องแก้ซะก่อน

เมื่อ clone ลงมาแล้ว ก่อนจะเริ่ม คำสั่งแรก ถ้ายังไม่มี leveldb ในเครื่องให้ลงก่อน วิธีติดตั้งที่สะดวกสำหรับผมคือใช้ Homebrew

$ brew install leveldb

พอจะสั่ง build step ที่ 2 npm run rebuild-leveldb เจอ error ก็เพราะว่า npm ในเครื่องเก่าไป เค้าต้องการ npm version ที่สูงกว่าหรือเท่ากับ 2.8.3

เราต้องติดตั้ง npm iojs node เป็น version อย่างน้อยตามที่เอกสารระบุ
io.js >= 1.8.1 และ npm >= 2.8.3 เมื่อเราติดตั้ง homebrew อยู่แล้วก็สั่งติดตั้งได้เลย

$ brew update
$ brew install node

เราจะได้ nodejs และ npm binary ติดตั้งในเครื่อง

ต่อไปติดตั้ง iojs สั่ง

$ brew install dahoba/iojs/iojs
$ brew link iojs

Formula homebrew-js ตัวข้างบนนี้ผม fork มาจากของ smockle/iojs/iojs เนื่องจากตอนทำครั้งแรก
ผมใช้ของ smockle แล้วพบว่าเป็น iojs v1.0.4 (เก่าไปอีก) เลยจัดการ fork เอา formula มาแก้ไขเป็น version ที่ต้องการ (เอา version ล่าสุดเลย v2.3.1)

ข้อสังเกต:
ถึงคุณจะไม่ใช้ formula พิเศษ ก็จะลง iojs ได้เหมือนกัน แต่มันจะมี message แบบว่า

This formula is keg-only.
iojs conflicts with node (which is currently more established)

ไม่ค่อยเข้าใจ แต่ googling ดูแล้วเห็นว่ามันต้องทำอะไรยุ่งยาก และได้ iojs version ที่เก่ากว่าที่ต้องการด้วย

เราต้องเลือกใช้ node หรือ iojs (ทำไมใช้ไปด้วยกันไม่ได้?)

  • เวลาจะใช้ node brew unlink iojs && brew link node
  • เวลาจะใช้ iojs brew unlink node && brew link --force iojs

หรือถ้าใช้บ่อยทำเป็น alias เลยก็ได้ จับใส่ใน ~/.bashrc หรือ ~/.zshrc

alias usenode="brew unlink iojs && brew link node && echo Updating NPM && npm install -g npm@latest && echo Using Node.js"
alias useio="brew unlink node && brew link --force iojs && echo Updating NPM && npm install -g npm@latest && echo Using io.js"

กราบส์ขอบคุณ gist อันนี้ :thumpup:

กลับมา rebuild-levelb กันต่อ ต้องกลับมาใช้ node ก่อน

$ usenode
$ npm run rebuild-leveldb

มันดูแปลกๆใช่มั้ย ที่เราไปเสียเวลาลง iojs แต่มาพิมพ์ usenode ก่อน compile แต่เหมือนว่าข้างใน script build มันมีการเรียกใช้ iojs นะ

คราวนี้ไม่มี error message อะไรแล้ว สั่ง npm start เพื่อเรียก friends ขึ้นมาเลย

friends on my machine

LOL จาก screenshot ไม่เจอใครเลย เพราะยังไม่มีใครมาเปิด friends ใน network เดียวกับผมน่ะสิ่ -_- เดี๋ยวรอเพื่อนโต๊ะทำงานๆใกล้ว่างก่อน จะส่ง friends แบบที่ build แล้วไปให้มาลองเล่นกัน

วันพุธ, มิถุนายน 24, 2558

สร้าง Technical Document แบบ minimal ด้วย markdown และ gulp.js

TL;DR

มี project java web application ตัวหนึ่ง ที่กำลังจะเอาออกไปใช้งาน มันยังขาดงานเอกสารอยู่ โดยเฉพาะ Technical document ซึ่งจะต้องให้ implementor
ใช้เวลาเค้าเอา software ไป build หรือไปติดตั้ง

ทีแรกก็เขียนเป็น README ธรรมดาๆ แต่หลังจากถูกเอาไป implement มาครั้งหนึ่งแล้ว
ก็พบว่าเอกสาร README มันไม่สมบูณณ์เอาซะเลย

โจทย์ของ Technical document ของตัวผมเองก็คือ

  1. ต้อง minimal ดูเรียบง่าย
  2. ไม่ต้องเสียเวลาทำมาก
  3. มีสารบัญด้วย (Table Of Contents)
  4. ถ้าได้ใช้ markdown ด้วยยิ่งดี

ลอง google ดูก็เจอ

  • mkDocs แต่มันใช้ python ซึ่งทำให้คนที่เอาไปใช้ต้องไปติดตั้ง python อีก ถ้าเป็น Window ก็งานงอก

project นี้ใช้ javascript อยู่แล้วเลยมองๆตัวที่ใช้ javascript ได้เลยมาเจอ

  • Hexojs เป็น static site generator ลองเอามาเล่นแล้ว ก็ติดขัดที่ว่า theme ที่มีมันไม่ถูกใจ และมันออกแบบมาให้ทำเป็น blogging framework มากกว่า
  • ยังมีตัวอื่นๆ ที่น่าสนใจอีกเยอะเลยพวก site generator เช่น

แต่ว่ามันขัดกับโจทย์ที่ตั้งเอาไว้ เสียเวลา วันนี้คงไม่จบ

มาลงตัวที่ solution นี้ project นี้ใช้ javascript อย่างที่บอก และมีการใช้ npm อยู่แล้ว อย่ากระนั้นเลย ลองหา node module มาช่วยแปลง markdown file ให้เป็น html ซึ่งจะเป็นเอกสารที่เปิดอ่านผ่าน browser ได้

ขั้นตอนที่ใช้/Solution

ผมสร้างไฟล์ README.md เอาไว้ที่ root folder ของ project (ก็เหมือน open sources ที่เห็นได้ตาม github นี่แหละ)

เปิด markdown reference ไปด้วย เพราะยังไม่คล่องเท่าไหร่
- ต้นตำรับ Darling fireball
- ยอดนิยม github flavored markdown (GFM)

ใช้ editor เป็น Sublime text ลง plugin 2 ตัวนี้
- Markdown Editing
- Markdown Preview

วิธีทำสารบัญ ก็คือใช้ anchor link เช่น

...  
### Table of contents

- [Overview](#overview)
- [Pre-requesite](#what-well-need)
- [How to Build](#how-to-build)  
...  
### Overview
...  

ตัว #overview จะทำให้ Overview กลายเป็น tag <a> ที่ link ไปหา anchor tag ที่อยู่ในเอกสารเดียวกัน ซึ่งก็คือ Overview ที่อยู่ด้านล่าง

header ทั้งหลายในเอกสารที่เรากำหนดเอาไว้ เมื่อ preview แปลง markdown เป็น html แล้วมันจะทำให้มี anchor tag ควบคู่ไปด้วยได้ เช่น จาก markdown ด้านบนเมื่อ generate แล้วจะได้แบบนี้

...  
<h3 id="table-of-contents">Table of contents</h3>
<ul>
<li><a href="#overview">Overview</a></li>
<li><a href="#what-well-need">Pre-requesite</a></li>
<li><a href="#how-to-build">How to Build</a>
...  
<h3 id="overview">Overview</h3>
... 

ผมเขียนๆไป ก็ทดสอบโดยใช้ Markdown Preview ใน Sublime Text ดูว่า link แล้วไปถูกหัวข้อหรือเปล่า หรือว่า เมื่อ generate เป็น html แล้วจะได้ anchor ชื่ออะไร สังเกตได้ว่ามันจะเอา - มาแทน space symbol อื่นๆ หรือภาษาไทยตัดทิ้งหมด

เมื่อเขียน Technical Document ครบตามหัวข้อที่ตั้งใจแล้ว ก็มานึกต่อว่าจะ generate เป็น html อย่างไรดี จะให้มาเปิด Sublime Text หรือเปิด website ที่รับ convert markdown online ก็ยุ่งยาก เสียเวลา

เมื่อเราใช้ javascript อยู่แล้ว และก็ใช้ node กับ gulp.js ช่วยทำงาน automate หลายอย่างอยู่แล้ว จึงมาหาวิธีแปลง markdown text ให้เป็น html ด้วยซะเลย

นั่งไล่ลองอยู่นานมาถูกใจตัวนี้ markdown-it เค้ารองรับ commonmarkdown ด้วย ทันสมัยมาก แต่เมื่อเราจะเอามาใช้กับ gulp จึงต้องใช้ module gulp-markdown-it

เราใช้ตอน build เท่านั้น อย่าลืมใส่ --save-dev ด้วย

$ npm install --save-dev gulp-markdown-it

วิธีใช้ตาม github ก็คือ ใส่ code แบบนี้ลงใน gulpfile.js. ไฟล์ README.md ผมอยู่ข้างๆ gulpfile.js อยู่แล้วจึงใส่แบบนี้

var gulp = require('gulp');
var md = require('gulp-markdown-it');

gulp.task('gen-docs', function () {
    gulp.src('README.md')
        .pipe(md())
        .pipe(gulp.dest("."));
});

เค้าจะสร้างไฟล์ readme.html ออกมาให้เลย

แต่มันยังไม่ใช่ ไม่ถูกใจ! syntax มันไม่ highlight, code block ก็ดูไม่แตกต่างจากเนื้อหาเลย เอ๊ นี่เราทำอะไรผิด พอเปิด source code ถึงได้รู้ว่า เค้า generate html ที่ไม่ใช่ไฟล์สมบูรณ์ เนื้อหาได้ประมาณนี้

<h1>Technical Documentation</h1>
<p>If you're open the README.md you can execute <code>$ mvn generate-resource -N</code> to view this document in HTML (readme.htm).</p>
<h3>Table of contents</h3>
<ul>
<li><a href="#overview">Overview</a></li>
<li><a href="#what-well-need">Pre-requesite</a></li>
<li><a href="#how-to-build">How to Build</a>
...  
<h3>Overview</h3>
...    

  • ไม่มี tag <html> <body>
  • ไม่มี stylesheet ที่ทำให้ดูสวยแบบใน github (ไม่เหมือนเวลา preview จาก Sublime เลย)
  • ไม่มี anchor tag
  • อ่าว.. :-(

งั้นเราจะต้องสร้าง html ส่วนที่เหลือเอง แล้วเอา content ส่วนนี้มาใส่เข้าไปสิ่นะ
อยากให้มี syntax highlight เพราะมีคำสั่ง และตัวอย่าง code ในเอกสารด้วย เราจะต้องใช้

เมื่อ download ไฟล์จาก link ข้างบนมาแล้ว extract zip ผมจับมันใส่ folder site จะมีหน้าตาแบบนี้ ส่วน github-markdown.css ที่โหลดมาได้ก็เอาไปไว้ใน styles ของ highlight ด้วย

+-- README.md
+-- gulpfile.js
|
+-- site 
    +-- readme.htm 
    +-- highlight
       +-- highlight.pack.js
       +-- styles
           +-- github-markdown.css
           +-- default.css 


ไฟล์ css อื่นๆ ใน styles ลบทิ้งหมด เหลือเอาไว้แต่ตัวที่ชอบ ซึ่งคือ default.css

มาลงเอยด้วย gulpfile.js แบบนี้

var gulp = require('gulp');
var mdit = require('gulp-markdown-it');
var inject = require('gulp-inject');

gulp.task('gen-docs', function() {
    var content = gulp.src('README.md')
        .pipe(mdit({
            preset: 'commonmark',
            options: {
                html: false,
                xhtmlOut: true,
                breaks: true,
                typographer: true,
                langPrefix: 'hljs-'
            },
            plugins: ['markdown-it-highlightjs', 'markdown-it-anchor']
        }));
    return gulp.src('site/readme.htm')
        .pipe(inject(content, {
            transform: function(filePath, file) {
                return file.contents.toString('utf8')
            }
        }))
        .pipe(gulp.dest('.'));
});

อธิบาย code ข้างบน

gulp-markdown-it ระบุ option ให้

  • generate html ตาม standard xhtml
  • ให้ใส่ tag <br/> เป็นตัวขึ้นบรรทัดแทน \n
  • หากมี markdown code block ที่ระบุภาษาให้ใส่ prefix hljs-

gulp-markdown-it ใช้ plugin markdown-it-highlightjs เพื่อให้มัน generate html ที่พร้อมให้ hilightjs เรียกใช้ ใส่ class ที่ tag code เพื่อพร้อมแสดงผลด้วย highlightjs

gulp-markdown-it ใช้ plugin markdown-it-anchor เพื่อให้มัน generate html พร้อม anchor ที่ tag <h?> ออกมาด้วย

gulp-inject เป็นตัวช่วยเอา content จากไฟล์หนึ่งไปใส่ยังไฟล์ที่เราทำเป็น template (site/readmd.htm) รอเอาไว้ได้ ในที่นี้คือเอา content ที่ markdown-it แปลงออกมาเป็น html เอาไปใส่ใน placeholder ที่ กำหนดไว้ด้วย inject:html

ตัวอย่างไฟล์ site/readme.htm

<html>
<head>
<link rel="stylesheet" href="site/highlight/styles/default.css">
<link rel="stylesheet" href="site/highlight/styles/github-markdown.css">
<style>
.markdown-body {min-width:200px;max-width:790px;
    margin:0 auto;padding: 30px;overflow: visible}
</style>
</head>
<body class="markdown-body">
<!-- inject:html -->
<!-- endinject -->
</body>
<script src="site/highlight/highlight.pack.js"></script>
<script>
  hljs.initHighlightingOnLoad();
</script>
</html>

style .markdown-body ผมแก้ไขไม่เหมือนกับที่บอกไว้ใน github ของคนทำนิดหน่อย คือผมใส่ overflow: visible เข้าไปด้วย

เมื่อรัน gulp gen-docs task แล้ว html ผลลัทธ์จะออกมาแบบนี้

<html>
<head>
<link rel="stylesheet" href="site/highlight/styles/default.css">
<link rel="stylesheet" href="site/highlight/styles/github-markdown.css">
<style>
.markdown-body {min-width:200px;max-width:790px;
    margin:0 auto;padding: 30px;overflow: visible}
</style>
</head>
<body class="markdown-body">
<!-- inject:html -->
<h1 id="technical-documentation">Technical Documentation</h1>
<p>If you're open the README.md you can execute <code>$ mvn generate-resource -N</code> to view this document in HTML (readme.htm).</p>
<h3 id="table-of-contents">Table of contents</h3>
<ul>
<li><a href="#overview">Overview</a></li>
<li><a href="#what-well-need">Pre-requesite</a></li>
<li><a href="#how-to-build">How to Build</a>
...
<h3 id="what-well-need">What we'll need</h3>
<ul>
<li>JDK 1.7 หรือใหม่กว่านั้น</li>
<li>Maven 3.1 หรือใหม่กว่านั้น</li>
</ul>
<h3 id="how-to-build">How to build</h3>
... 

เมื่อเปิด readme.htm ที่ถูก generate ขึ้น มาดูใน browser ก็สวยงามถูกใจแล้ว ตอนแก้ปัญหาก็ใช้เวลานานหน่อย เกือบวันนึง ตอนนี้ก็มีสูตรสำเร็จแล้ว ครั้งต่อไปก็จะเร็วขึ้นมากแล้วล่ะครับ

Happy Coding ^^

วันพฤหัสบดี, มิถุนายน 11, 2558

ทำ Spring Boot ให้สร้าง PID file ตอนรัน executable jar/war (Another way to config ApplicationPidFileWriter in Spring Boot)

เมื่อเราทำ executable jar หรือ executable war เวลารันไฟล์เหล่านี้ มันก็จะไม่ได้เปิดหรือแสดง console การที่จะหยุดการทำงานมัน เราจะต้องรู้ process id ของมัน
วิธีหา process id ของ executable jar/war ก็มีหลายวิธี
  • ใช้ command line `ps -ef|grep {ชื่อ file ของเรา}
  • เปิด log file ดู (ถ้า config พวก log4j เอาไว้) เวลา SpringApplication เริ่มทำงานมันก็จะบอกว่า process id ที่มันได้คือเลขอะไร i.e.: ...Starting FooApplication v0.1.0 on dahoba-laptop with PID 15840 ...
  • ใช้ Spring Boot Actuator ให้มันสร้าง pid ไฟล์ให้เรา
อ้างอิงตาม Spring Boot 1.2.3.RELEASE หัวข้อ Process monitoring เค้าบอกว่า ApplicationPidFileWriter สามารถจะเขียน application.pid ซึ่งมีเลข PID (process id) ของ application ที่รันอยู่ให้เราได้
วิธีการทำ
  • ใส่ dependency Spring Boot Actuator ก่อน
    reference #39
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
</dependencies>
Note: วิธี extend META-INF/spring.factories ยังทำให้ผมสับสน หรือใช้ SpringApplication.addListeners(…​) มันไม่ work แฮะ (ผมยังใช้ไม่เป็น :-( )
ผมทำแบบนี้ ใช้ได้เหมือนกัน
  • สร้างไฟล์ application.properties ขึ้นมาใน classpath i.e.: src/main/resources/application.properties
  • เพิ่ม line context.listener.classes นี้เข้าไป
  • ทางขวา value เป็น comma separate ใส่ class อื่นๆ ได้อีก
... 
context.listener.classes = org.springframework.boot.actuate.system.ApplicationPidFileWriter
... 
ที่นี้พอ execute jar/war ที่ package ใหม่หลังจาก ใส่ properties กับ dependency เข้าไปแล้ว มันก็จะสร้าง application.pid ให้เราแล้ว
มันจะถูกสร้างข้างๆไฟล์ jar/war ของเราเลย
$ cat applicaion.pid
19489%
ถ้าใช้ OS เป็น OSX หรือ linux ก็สามารถใช้คำสั่งแบบนี้เพื่อหยุด app ของเราได้เลย
$ kill `cat application.pid| awk '{print;}'`
หรือ
$ kill $(cat application.pid| awk '{print;}')

Happy Coding ^^
Written with StackEdit.

วันพุธ, มิถุนายน 10, 2558

เปลี่ยนภาพ wallpaper ใหม่ๆ อัตโนมัติ บน macbook ทุกวัน ด้วยภาพจาก Bing search

post poster
รู้สึกเบื่อภาพ wallpaper เดิมๆที่ Apple ให้มากับ OSX แล้ว การจะมานั่งหาภาพใหม่ๆทุกๆวัน มันก็เสียเวลา สมัยใช้ Window จะมีโปรแกรมที่คอยเปลี่ยน wallpaper ให้เราตามช่วงเวลาที่กำหนดไว้ เลยมาลองค้นดูว่าสำหรับ OSX หรือ linux OS เนี่ยมันน่าจะมีเหมือนกัน (ที่หา linux ด้วยเพราะว่าถ้าเป็น script มันก็จะรันใน OSX ได้เหมือนกัน)
วิธีตามนี้เลย
  1. โหลดไฟล์จาก github นี้ https://github.com/thejandroman/bing-Wallpaper. หาดูปุ่มที่เขียนว่า Download in ZIP หรือว่าถ้าเป็น developer อยู่แล้วจะใช้ git clone เลยก็ได้
  2. ผมสร้าง folder script ที่ home folder ของผมเอง แตก zip ที่ดาวโหลดมาไปที่นั่น
    directory
    จากภาพ โปรแกรมที่โหลดมาจะอยู่ที่ siritas_s/script/bing-Wallpaper
  3. ภาพที่โหลดมาได้จะเก็บไว้ที่ {user’s home}/Pictures/bing-wallpapers/
    ซึ่งเราสามารถใช้ text editor เปลี่ยนปลายทางได้เอง
ขั้นต่อไปเราจะมาทำให้มันเรียกโปรแกรมนี้ให้เราทุกวัน
  1. เปิดโปรแกรม Calendar
  2. สร้าง event ใหม่ (คลิกขวาบนปฎิทิน, วันที่ทำก็ได้)
    สร้าง event ใหม่
  3. ตั้งชื่อว่า bing-download
    config event
    เลือก repeat เป็น every day
    เลือก alert เป็น Custom…
    ถ้าอยากให้มันหยุดเรียก event นี้เมื่อไหร่ก็กำหนด end repeat ให้มันด้วย
  4. เมื่อเลือก Custom แล้ว เลือก Open file
    open file
  5. เลือกให้มันเปิด Bing wallpaper.app ที่อยู่ใน folder Tools
    select app
  6. ต่อมาเลือกให้มันรันตอนเวลาที่เรากำหนด (At time of event) ก่อนกดปุ่ม OK ดูว่าเซตแบบนี้แล้ว
    pre-ok
  7. เมื่อกด OK ออกมาแล้วจะได้ปฎิทินเป็นคล้ายภาพนี้ มี event bing-download เต็มไปหมด
    final calendar
  8. จากตัวอย่าง ทุกๆ 9 โมงเช้ามันก็จะดาวโหลดภาพ wallpaper จาก bing search มาให้
หลังจากนั้นก็ไปกำหนดให้ OSX แสดงภาพจาก folder ที่เก็บภาพ เปิด System Preferences > Desktop & Screen Saver กดปุ่ม + แล้วเลือก folder bing-wallpapers
*วิธีนี้ใช้ได้กับ Mac OSX และ Ubuntu
Written with StackEdit.

วันอังคาร, มิถุนายน 09, 2558

แก้ปัญหา SQLDeveloper ฟ้อง Low Memory Warning dialog

แก้ปัญหา sqldeveloper ฟ้อง Low Memory Warning

1.  เปิดไฟล์ {path ที่ติดตั้ง sqldeveloper}/sqldeveloper/bin/ide.conf

2.  มองหาข้อความเหล่านี้
...
# If you are getting the 'Low Memory Warning' Message Dialog while running
# JDeveloper, please increase the -Xmx value below from the default 800M to
# something greater, like 1024M or 1250M.  If after increasing the value,
# JDeveloper is no longer starting up because it fails to create a virtual
# machine, then please reduce the modified -Xmx value, or use a 64bit JDK
# which allows for very very large value for -Xmx.
#
AddVMOption  -Xmx800M
...

ลองแก้ไขจาก 800M เป็น 1024M (1 กิ๊ก)

AddVMOption  -Xmx1024M

3. Save แล้ว restart SQLDeveloper.

---
ปล. ใช้ SQLDeveloper บน Mac OSX สำหรับ window หรือ linux ก็น่าจะแก้ไขได้ด้วยเช่นกัน.