Internship, Day 21 (18 May 2012)

Posted on May 19th, 2012 in cloud, computer, in English, in Thai, personal, PHP, programming | No Comments »


(Photo: We have SCB. Your argument is invalid. << Wait what?!)

วันนี้ผมเริ่มจากการทำระบบตรวจสอบและปรับไฟล์ก่อนเลย โดยคราวนี้มามาดใหม่ แทนที่จะเอาไฟล์มาไล่ทีละชื่อ (โคตรเชยเลย) ผมใช้คำสั่ง array_diff($a, $b) เพื่อหา A-B (เมื่อ A และ B เป็นเซตที่แทนด้วยอาร์เรย์ $a และ $b ตามลำดับ) แล้วลบหรือโหลดไฟล์ทีเดียวหมดเลย ง่ายดี ทำไมตอนนั้นคิดไม่ได้แบบนี้ก็ไม่รู้ จากนั้นผมก็เขียนคู่มือการใช้งานต่อจนจบ โดยเปลี่ยนจาก text เป็น HTML จะได้อ่านง่ายๆ หน่อย แล้วก็ใส่ spinner (ไอ้ตัวหมุนๆ เวลารอ ajax ทำงาน) ขณะมีการดาวน์โหลดไฟล์ที่ใช้เวลาค่อนข้างนานโดยใช้ spin.js ซึ่งใช้งานได้ง่ายและเป็น MIT License ด้วย จึงนำมาใช้กับชิ้นงานของบริษัทได้ทันที

สุดท้ายผมก็เลยได้ทำงานชิ้นต่อไปคือการศึกษาเกี่ยวกับ vCloud Director อธิบายกันสั้นๆ จากผู้เริ่มต้น vCloud Director เป็นตัวที่มาครอบบน vCenter อีกที ก็หลักๆ ก็รู้แค่นี้แหละครับ (ยอมรับว่ารู้แค่นี้ เพราะตรงนี้เป็นรายงานประจำวัน ไม่ใช่บทความ) สำหรับลิงค์ที่อ่านไปจะไว้ท้ายเอนทรีนะครับ

Today I started from file consistency restorer, which I revised to use array_diff($a, $b) to find missing or extra files and take appropriate actions. Then, I finished the manual, which I converted into HTML format from plain text. Finally, I added spinner (that spinning thing when there are ajax calls) using spin.js , which uses MIT License and thereby is compatible with this work.

At the end of the day I started reading about vCloud Director. From a newbie, it’s something that runs on top of vCenter. That’s all I know. (And I’m going to admit my limits here because this is a daily report not an article).

References

http://www.yellow-bricks.com/2010/08/31/vmware-vcloud-director-vcd/
http://frankdenneman.nl/2010/09/provider-vdc-cluster-or-resource-pool/

Internship, Day 20 (17 May 2012)

Posted on May 17th, 2012 in computer, CPE, in English, in Thai, personal, programming | No Comments »

null
(Photo: Getting from second floor to first, duh. I don’t know the subject.)

เหนื่อยๆๆ อะไรก็ไม่รู้แต่เช้า รู้แต่ว่าต้องรีบปั่นงานต่อเพราะตอนนี้มีสองงาน พอทำไปทำมามาติดบั๊กตรงคำสั่ง JavaScript จึงทำให้ได้บทเรียนที่สำคัญว่า

อย่าลืมว่าการใส่ $.each ให้ ajax (หรือ get หรือ getJSON หรือ post) ไม่ใช่การทำ ajax ทีละอัน แต่เป็นการสร้าง ajax หลายๆ อันทำขนานกัน

อย่า “โยง” ajax เข้าด้วยกันถ้าไม่รู้ว่ากำลังทำอะไรอยู่

เพราะ…

“a” ใน “a”-jax ย่อมาจาก “asynchronous”

วันนี้ผมเขียนระบบเล่นไฟล์สองรูปแบบ (double-format) โดยจะเป็น MP4 (ด้วย <video> tag) กับ YouTube (ด้วย YouTube API) ก็เล่นได้ เพื่อบรรเทาปัญหาที่ว่า Aruba บล็อกการส่งคำขอไปยังเครืองอื่นที่ไม่ใช่ตัวมันเอง แต่ข้อเสียที่สะท้อนกลับมาคือมันใช้พื้นที่มหาศาล และบริหารจัดการได้ยากมาก โดยเฉพาะเวลาสภาพความสอดคล้อง (consistency) เสียไปเนื่องจากเพิ่มวิดีโอใหม่เข้าไปใน playlist ที่เป็นแบบ MP4 แล้ว (อย่าลืมว่า ระบบไฟล์ใหม่ของผมจะกำหนด format ในระดับ playlist ไม่ใช่ระดับไฟล์) จึงใช้วิธีแก้ง่ายๆ ที่อาจฟังดูโหด คือ หากมีการเซฟ playlist ไม่ว่าจะไปแก้ไขมันหรือไม่ ผมจะตีความว่าเป็นการ downgrade playlist จากแบบ MP4 กลับไปเป็น YouTube อัตโนมัติ แต่สามารถ upgrade กลับมาเป็น MP4 ได้ทุกเมื่อเช่นกัน

งานต่อไปสำหรับพรุ่งนี้ของผมคือการทำระบบตรวจสอบและกำจัดไฟล์ที่ไม่ใช้แล้ว เพื่อลดการใช้พื้นที่บนเซิร์ฟเวอร์ อีกอันคือทำคู่มือให้อ่านง่าย เนื่องจากโปรแกรมของผมใช้การรายงานสถานะด้วยสีเป็นส่วนใหญ่ (แต่ส่วนใหญ่ถ้าไม่ใช่สีส้มหรือแดงก็แปลว่าไม่มีปัญหา) รวมไปถึงทดสอบการติดตั้งบนเครื่องใหม่ด้วย เพื่อดูว่าการติดตั้งทำได้อย่าราบรื่นหรือไม่ จากนั้นจะได้ไปอ่านเรื่อง vCloud ต่อซะที

และแน่นอน ปัญหา Aruba จะไม่จบ ถ้าไม่สามารถอัพโหลดงานของผมขึ้นไปไว้ในที่ๆ มัน whitelist ได้

Tiring morning. I had to do everything quickly because I have two jobs to do now. While working on a JavaScript bug I realized that …

$.each over ajax calls don’t do each one after another, but AT THE SAME TIME

Don’t chain ajax calls if you don’t know what you’re doing

because …

The first “a” in “a”-jax means “asynchronous”

Today I finish building the double-format (MP4 using <video> tag & YouTube using YouTube API) player in order to mitigate the Aruba problem, which prevented requests to other servers (i.e. my own media server) from working. The downside of this approach is the immense disk space requirement, and difficult management especially when the playlist is not consistent with the files after new files are added to the playlist. A bit harsh, but I fixed by forcing a “downgrade” (from MP4 to YouTube) upon saving for every playlist, however an “upgrade” is sill one click away so that’s not much of a problem.

Tomorrow, I will rebuild the file cleanup system to reduce space waste. Another thing I will do is to make an easy-to-read manual because my program uses lots of coloring (you only need to watch out for red or orange however, for they represent “error occurred”) and the final one is to test installation on a new machine. Then I can read vCloud. In. Peace.

Certainly, the Aruba problem will not end if I cannot get my work into its “whitelisted zone”. I don’t know how to do that or any kind of help is possible.

Internship, Day 19 (16 May 2012)

Posted on May 17th, 2012 in computer, CPE, in English, in Thai, personal, PHP, programming | No Comments »

วันนี้ผมไปทำงานก็เจอดีแต่เช้าเลย เพราะหัวหน้าฝ่ายเรียกให้ไปคุยงานนิดหน่อย สรุปได้ใจความว่าผมต้องอ่านเรื่อง vCloud Director แล้วทำสไลด์ไปอธิบายให้ฟัง

ต่อมา ผมก็ทำงานต่อ แต่ไม่ทันไรพี่เลี้ยงก็มาคุยเรื่องการอัพโหลดไฟล์ขึ้น Aruba Captive Portal ซึ่งอัพไปแล้วมันใช้งานไม่ได้ด้วยเหตุผลบางประการ คือ พออัพไปแล้ว (หน้า video player ของผมเป็น iframe) มันพยายามที่จะเรียก iframe ขึ้นมาแต่ทำไม่ได้ โดยไม่ว่าจะ request ไปกี่ครั้งก็ได้ HTTP 302 กลับมาตลอด (ควรเป็น 200) และติดลูปอยู่อย่างนั้นจนเบราเซอร์หยุดการทำงานให้เอง อาการนี้ไม่รู้จะแก้ยังไง แถมไฟล์ที่จะเล่นอยู่บน YouTube ยิ่งยากเข้าไปใหญ่ เลยตัดสินใจเอาระบบโหลดไฟล์กลับมาอีกครั้ง แต่มาในร่างใหม่ที่บริหารในระดับ playlist แทน นั่นคือ ทั้ง playlist จะต้องเป็น YouTube หรือเป็น MP4 อย่างใดอย่างหนึ่ง (แต่ต้นกำเนิดมาจาก YouTube เหมือนกัน คือ สร้าง YouTube playlist ก่อน แล้วค่อยโหลดไฟล์มาลงเครื่องอีกทีด้วย youtube-dl)

เวลาที่เหลือทั้งวันของผมก็หมดไปกับการทำให้ตรงนี้มันใช้งานได้ครับ แต่ทำได้ไม่เท่าไหร่ เพราะผมต้องแก้โค้ดเก่าอยู่พอสมควร ตอนนี้มันกลับมาโหลดไฟล์ได้แล้ว แต่โหลดมาแล้วยังไม่เกิดประโยชน์อะไรเพราะไม่มีตัว player ที่จะเอาไว้เล่นไฟล์ที่โหลดมาครับ

Today I was summoned to the Department and he assigned me to read vCloud Director, then make a presentation to explain to him.

Then I continued my work for a bit before supervisor discussed uploading the file to Aruba Captive Portal, which failed. For some reasons after uploading (the video player which uses an iframe), the iframe (stored on “media server” separate from Aruba) cannot be loaded and the browser always gets HTTP 302, instead of 200, over and over until browser killed the tab. I don’t know how to fix it yet, but the fact that the files are on YouTube will make it all worse so we decided to bring back the file download system, in a new form that it is managed at playlist level instead, downloading entire playlists at a time. All or nothing. First, the user would create a YouTube playlist, then “convert” it to MP4.

I spent the rest of the day implementing all that, but did not progress much due to wrestling with the old code. It can now load files, but cannot play them yet.

[jQuery] … for MySQL Data Manipulation in PHP

Posted on May 16th, 2012 in computer, dedicated entry, in Thai, PHP, programming | No Comments »

<< อ่านบทที่แล้ว (jQuery for Beginners)

ก็กลับมาอีกครั้งกับหัวข้อ jQuery นะครับ วันนี้ผมจะมาเสนอเรื่องการใช้ jQuery ติดต่อกับฐานข้อมูลผ่าน PHP แบบง่ายๆ (ง่ายมากๆ) กัน

ก่อนที่เราจะทำอะไร เราต้องโหลด starter code กันก่อนครับ ถ้าโหลดแล้วก็ทำตามคำแนะนำที่ให้ไป จากนั้นก็เริ่มกันเลย

การอ่านค่าจากฟอร์ม

การอ่านค่าจาก form field ต่างๆ สามารถทำได้โดยใช้ .val() ยกตัวอย่างเช่น จากไฟล์ HTML ต่อไปนี้

 <form>
  <input type="text" id="name" name="name">
  <input type="button" id="btname" name="btname">
</form> 

เราสามารถเอาค่าออกมาจาก field “name” ได้โดยใช้คำสั่ง jQuery (บรรทัดบน) หรือ JS ธรรมดา (บรรทัดล่าง) ได้ดังนี้

 $("#name").val()
document.getElementById("name").value 

โจทย์: จาก starter code ที่ให้ไป ให้เปิดไฟล์ user.html ขึ้นมา ลองพิมพ์อะไรก็ได้ลงไปในช่องทั้งสอง ยังไม่ต้องทำอะไร จากนั้นให้ใช้คำสั่ง val ในการดึงค่าออกมา

การเรียกหน้า PHP จาก jQuery

เรามีไฟล์สองไฟล์ คือ signup.php กับ login.php ซึ่งเป็นไฟล์ที่สร้างผู้ใช้ใหม่กับทำการ login (แบบปลอมๆ) โดยไฟล์ทั้งสองนี้เป็นตัวแทนการ insert และการ select ตามลำดับ ให้ศึกษาไฟล์ให้เข้าใจก่อนที่จะอ่านต่อ …………………… หากอ่านจนพอเข้าใจ จะเห็นว่า ไฟล์ทั้งสองรับตัวแปรชื่อ user กับ pass แล้วเอาไปทำอะไรบางอย่างกับฐานข้อมูล จากนั้นมันจะ print ค่าออกมาหนึ่งในสองค่าคือ “OK” หรือ “FAILED” ขึ้นกับผลการทำงานที่ได้

เมื่อคราวที่แล้วผมสอนให้ผู้อ่านใช้คำสั่ง $.get ไป คราวนี้จะเปลี่ยนมาใช้คำสั่ง $.post บ้าง สำหรับ $.post ไม่ต่างอะไรจาก $.get เลยในแง่ของการใช้งาน ต่างกันแค่ความหมายนิดหน่อยเท่านั้น (สั้นๆ: GET ใช้ในการดึงข้อมูลออกมา โดยใส่ตัวแปรต่อจาก URL ในขณะที่ POST ใช้ในการส่งข้อมูลขึ้นระบบ โดยส่งตัวแปรด้วย HTTP Protocol ในส่วนที่ไม่ใช่ URL)

เช่น หากผมต้องการให้ส่งตัวแปร ‘ticket’ มีค่าเท่ากับ 814418 ไปยังหน้า ‘lottery.php’ โดยเมื่อ PHP ตอบกลับมาแล้วให้แสดงว่าได้รางวัลอะไร ก็จะมีโค้ดสองส่วน คือส่วนของ PHP ก่อน

 //LOTTERY PRIZE LOOKUP
function prize($ticket){
  if($ticket==814418){
    return "First Prize!!"
  } else if (in_array($ticket%1000,Array(504,309,902,101)){
    return "..."
  } // ... (whatever)
}

print prize($_POST ['ticket'] ); 

สังเกตว่าเมื่อเราเรียกไฟล์จริงๆ ไฟล์ lottery จะ print ไม่ใช่ return ซึ่งถูกต้องแล้ว เพราะการเรียก jQuery หรือ ajax มันจะไม่รู้ว่า return อะไรออกมา มันจะเอาแต่สิ่งที่ print ออกมาเท่านั้น

จากนั้นเราไปดู jQuery กันต่อ

 //LOTTERY CHECKER
function checkPrize(ticket){
  $.post(
         'lottery.php',
         {'ticket': ticket},
         function(output){alert(output);}
        );
}

checkPrize(814418); 

อธิบาย: โค้ดนี้จะเรียก lottery.php โดยใช้วิธี POST ส่งตัวแปร ticket ไปหนึ่งตัวมีค่า 814418 ส่วนฟังก์ชันที่รับ output เราเรียกว่า “ฟังก์ชันนิรนาม” (anonymous function) ซึ่งถูกกำหนดขึ้นมาเฉพาะกิจ ใช้งานแค่ใน scope เท่านั้น เช่น ในกรณีนี้ ฟังก์ชันจะเอา output แสดงออกมาผ่าน alert เป็นต้น หากอธิบายคร่าวๆ (มากๆ) ก็จะได้อะไรที่คล้ายๆ กับรูปข้างล่าง

เอาเป็นว่าเราเอาไว้เท่านี้ก่อน สำหรับโจทย์ในวันนี้คือ “พยายาม hack ตัว login ของผมด้วย SQL Injection ให้ได้” สำหรับคราวหน้าหากผมมีแรงเหลือจะมาอธิบายว่าทำไม SQL Injection จะใช้ได้หรือไม่ได้กับชุดคำสั่ง JQ2 ของผมนะครับ :)

Internship …. NOT! TG Exam!

Posted on May 15th, 2012 in in English, in Thai, personal | No Comments »


(Photo: Exam hall prior to examination)

วันนี้ผมไม่ได้เข้างานครับ เพราะไปสอบเป็นนักเรียนการบินของการบินไทยแทน

การสอบสอบที่ธรรมศาสตร์ ศูนย์รังสิต โดยเข้าห้องสอบเวลา 0830 ห้ามนำสิ่งอื่นใดนอกเหนือจากที่ใช้สอบเข้าห้องสอบ (ถ้าเป็นกระเป๋าให้วางนอกห้อง ถ้าเป็นมือถือมีโต๊ะให้วาง รับผิดชอบกันเอง) และเริ่มสอบเวลา 0900 การสอบก็เป็นแบบฝนทั้งหมดเลย (เหมือนกับข้อสอบทุกๆ ที่แหละ) มีน้ำให้กินขวดนึง วิชาแรกคือวิชาภาษาอังกฤษ (English Test) ก็มีสอบไวยากรณ์ คำศัพท์ และการอ่าน รวมกัน 100 ข้อ ลักษณะการสอบส่วนใหญ่จะให้เลือกคำเติมในช่องว่าง และการตอบคำถามจาก passage ที่ได้มาในแต่ละข้อ อันนี้ก็ไม่ค่อยยากเท่าไหร่ เพราะปกติเป็นคนอ่านภาษาอังกฤษมากอยู่แล้ว (แต่ยอมรับว่าถ้ามีสอบฟังด้วยคงตายเหมือนกัน) อันนี้ทำทัน แอบมั่วไปข้อนึง เทคนิคที่ใช้ก็เอาตามที่เรียนมา เช่น กฎการกำหนด part of speech และการใช้ parallelism เป็นต้น

สำหรับข้อสอบวิชาต่อมาคือความรู้ (Knowledge Test) โดยประกอบไปด้วยการทดสอบย่อยห้าวิชา คือคณิตศาสตร์ วิทยาศาสตร์ ความรู้เกี่ยวกับการบินไทย ความรู้ด้านการบินโดยทั่วไป และความรู้ทั่วไป โดยด้านวิชาการทั้งหมดจะไม่ยากเกินมัธยม เช่น…

  • คณิตศาสตร์: 2x+y = 5; x+2y = 3; x = ? (พีชคณิต เรื่องอื่นๆ เช่น ทฤษฎีบทพิทากอรัส การคิดอัตราส่วน)
  • วิทยาศาสตร์: วัตถุเคลื่อนที่ด้วยอัตราเร็ว 2 เมตรต่อวินาที ตกจากโต๊ะสูง 0.8 เมตร จะตกไกลตากขอบโต๊ะในแนวระดับเท่าใด (กลศาสตร์ เรื่องอื่นๆ เช่น ไฟฟ้า พลังงาน)
  • ความรู้เกี่ยวกับการบินไทย: ตราสัญลักษณ์แรกของบริษัทคืออะไร (ตอบ: The Dancing Man)
  • ความรู้ทั่วไปด้านการบิน: เครื่อง Airbus A380 มีกี่ล้อ (ไม่เคยไปนอนนับเหมือนกัน)
  • ความรู้ทั่วไป: โดม เดอะสตาร์ 8 เป็นคนจังหวัดอะไร (ภูเก็ต!! บร๊ะเจ้า ไม่ได้ดู The Star มาหลายปี ไม่นึกว่าจะถามกันแบบนี้ เฮือก)

คณิตวิทย์ก็พอทำได้ครับ Dancing Man ก็รู้จัก ความรู้การบินนี่เริ่มงง อะไรหว่า rudder elevator aileron เอ๊ะ แล้วเครื่องบินมันใช้เครื่องยนต์อะไร เคยดูใน หว้ากอ มีคำว่า Rolls Royce ตอบอันนี้ละกัน เฮือกกกกก ส่วนโดมเป็นคนจังหวัดอะไรนี่ผ่านครับ (ไม่รู้ห้ามเดา! คะแนนจะเอาอัตราส่วนข้อที่ถูกเทียบกับข้อที่ทำด้วย ไม่ใช่แค่คะแนนที่ได้)

สำหรับส่วนสุดท้ายที่ทำคือ Aptitude Test ประกอบไปด้วย 5 part เช่น ความถนัดเชิงตัวเลข (ให้เลือกเลขที่สัมพันธ์กับที่กำหนดให้) ภาพสามมิติ (ให้แผ่นคลี่ของลูกบาศก์มา ถามว่าประกอบเป็นแบบใดได้บ้าง) ความจำระยะสั้น (ให้ตารางใส่ตัวเลขกับตัวอักษรมา จำให้ได้มากที่สุดในเวลาที่กำหนด) เป็นต้น

ส่วนที่ทำได้มากที่สุดคือภาษาอังกฤษ รองลงมาก็คณิตศาสตร์ วิทยาศาสตร์ ส่วนที่ไม่แน่ใจมากๆ คือ Aptitude ส่วนความจำ กับความรู้ทั่วไปครับ ไม่รู้จะผ่านมั้ยเหมือนกัน

I skipped work today to take Thai Airways (TG) student pilot exam.

Exam took place at Thammasat University (Rangsit Campus), starting 0900. First course is English Test, consisting of 100 reading multiple-choice questions about grammar, vocabulary and comprehension. This is not very hard on me because I read a lot (not the case if the exam includes listening). Normal school techniques should do well.

The next test is the Knowledge Test, including Mathematics, Science, Thai Airways Knowledge, Aviation Knowledge, and General Knowledge. Most “academic” questions are not hard. Examples:

  • Maths: 2x+y = 5; x+2y = 3; x = ? (Algebra. There are also Pythagorean Theorem, ratios, etc.)
  • Science: Object moving horizontally at 2 m/s and fell off a 0.8 meters table. How far will it land from the edge of table. (Mechanics. Others: Simple electronics, energy, etc.)
  • TG Knowledge: The First Logo of Thai Airways (The Dancing Man)
  • Aviation Knowledge: How many wheels are there on the Airbus A380? (Never actually counted it…)
  • General Knowledge: Hometown of “Dome The Star 8″? (Phuket. I don’t know. Honest.)

I did fine in Maths and Sci, got a bit stirred during Aviation … rudder … elevator … aileron … what are these … what’s that engine again … Rolls Royce? As for Dome The Star I don’t know. (No Guessing: Penalties for wrong answers!)

The last part is Aptitude Test, consisting of five parts such as numerical aptitude (given a number, find related numbers), 3-D aptitude (given an unfolded cube, what is the correct folded form?), and short-term memory.

I did well at English, followed by Maths and Science. I’m really unsure about Aptitude and Knowledge. Not sure if I will pass.

Just hope I will.

DISCLAIMER: “Thai Airways”, the “THAI” typeset, branding, and related names and marks are properties of Thai Airways International, or otherwise legally owned. We mention these names for reference only, and are NOT endorsed by the trademark owner(s).

Internship, Day 17 (14 May 2012)

Posted on May 15th, 2012 in computer, CPE, in English, in Thai, programming | No Comments »


(Photo: Can I leave work on 17? DAT ANNOYING ALARM!)
(Sorry for late upload)

วันนี้เช้าผมเข้าไปทำงาน กำลังทดสอบงานเตรียมส่ง ปรากฏว่าพี่เอางานมาเพิ่ม โดยให้

  • เลือก default playlist จากเมนูได้เลย
  • ปรับ interface ให้ใช้ง่ายขึ้น
  • ทำให้ embed ได้ง่ายๆ
  • ทำให้เรียกไฟล์จากที่อื่นได้

ถึงกับอึ้งรับประทานไปเลยทีเดียว แถมทำแทบตายกว่าจะได้ เพราะต้องเพิ่มฟังก์ชันให้เก็บ default playlist ได้ ต้องทำ iframe interface มาครอบ ไม่งั้นก็ embed ยาก (การทำ iframe ครอบจะทำให้ออกมาคล้ายๆ YouTube iframe API อีกที) สรุปว่าวันนี้ทำงานแบบรีบๆ มึนๆ ก็เลยจบแบบงงๆ ว่าทำอะไรลงไปบ้าง กลับมาก็น็อกอีก เลยเขียนได้แค่นี้ครับ :(

I was testing my work when the senior got more tasks for the job.

  • “Select Default Playlist” menu which affects all player instances without further configuration
  • Easier-to-use UI, and optimize for mobile use
  • Easier embedding
  • Call the player from foreign domain

Yeah, I got stunned, and it was a hell a lot of work in one day just to store default playlist. There’s also iframe interface (not unlike YouTube iframe API) so all in all it was pretty confusing and ended up very confusing. I got sick after work so this is all I remembered.

NOTE: There will NOT be an Internship Day 18. It’s skipped.

Internship, Day 16 (11 May 2012)

Posted on May 12th, 2012 in computer, CPE, in English, in Thai, personal, programming | No Comments »


(Photo: This is Madness! Madness? THIS. IS. ALAINAAAAAA!!!!)

ผมติดบั๊กค้างมาแต่เมื่อวาน ปรากฏว่าเป็นปัญหาการเปิดวิดีโออะไรบางอย่างของ Chrome 18 (ตั้งแต่เมื่อไหร่เนี่ย!) เอง ไม่เกี่ยวกับสคริปต์แต่อย่างใด จึงได้แต่ภาวนาขอให้ Google แก้ไวๆ (แต่เล่นบน IE และ Firefox ได้ตามปกติ)

อีกอย่างที่ทำในวันนี้คือลอง optimize ในรูปแบบต่างๆ แต่เนื่องจาก JavaScript มันเป็นภาษาระดับสูงที่ใช้คำสั่งจำนวนน้อยๆ เลยไม่รู้จะไปลดตรงไหน ก็เลยได้แค่เปลี่ยนกระบวนการเปลี่ยนวิดีโอ จากการแก้ tag โดยตรงเปลี่ยนมาใช้ API เปลี่ยนไฟล์แทน (จริงๆ API สามารถโหลด playlist เป็นสตริง เช่น “vid1,vid2,vid3″ มาเลยก็ได้ แต่มันมึนๆ เลยใช้เปลี่ยนไฟล์เองดีกว่า) คิดว่าน่าจะเสถียรมากขึ้น ไม่รู้เหมือนกัน

ต่อจากนี้ก็ไม่มีอะไรแล้วครับ เหลือแต่เก็บรายละเอียดเล็กๆ น้อยๆ เวลาที่เหลือก็หยิบความรู้ CSS มาปัดฝุ่นบ้าง นั่งทบทวนนิดๆ หน่อยๆ

The bug that persisted from yesterday turned out to be some kind of video problem in Chrome 18 (since when?!) and not the script error. The only thing I can do right now is to pray that Google fixes it. (No problem in IE and Firefox)

Another thing I did was optimizing the code, but there wasn’t much to do because JavaScript is already high-level and there’s nothing to optimize “code-wise” so I changed the video change method from tag editing to using API. (Actually, the API can load comma-separated strings like “vid1,vid2,vid3″ as playlist but it seemed problematic so I ditched that idea) It might be more stable now, I don’t know.

There’s not much other than fine details. I spent some time revising my CSS knowledge and techniques.

Internship, Day 15 (10 May 2012)

Posted on May 11th, 2012 in computer, CPE, in English, in Thai, personal, programming | No Comments »


(Photo: From skywalk in front of Cyber World Tower, looking at Robinson Dept. Store)

วันนี้ไม่ค่อยมีงานแล้ว เนื่องจากทุกอย่างเกี่ยวกับโปรแกรมวิดีโอใกล้เสร็จ จึงใช้เวลาส่วนใหญ่เขียนรายงานมากกว่า แต่เมื่อตอนบ่ายมาเจอปัญหาว่า เมื่อกำลังจะเล่นวิดีโอบางตัว ระบบจะไม่สามารถโหลดไฟล์ได้ โดยตัดเป็นจอดำๆ ที่ไม่สามารถทำอะไรได้อีกเลย อาการนี้เป็นเฉพาะใน Chrome เท่านั้น (ใน IE และ Firefox ปกติดี) จึงไม่แน่ใจว่าเป็นที่ Chrome หรือไม่ เพราะไม่ได้แก้ไขโค้ดใดๆ จากเมื่อวาน

I had almost no work today because the video player is almost done, so I spent more time writing reports. In the afternoon however I found out that some videos cannot be played and causes the YouTube screen to black out. This happens only in Chrome (and not in IE or Firefox) so I’m not sure if it’s the browser’s fault, because the code wasn’t changed.

Follow-up: It’s problem with only one instance of Chrome, too. I’m trying to isolate that to extensions.

Internship, Day 14 (9 May 2012)

Posted on May 10th, 2012 in computer, CPE, in English, in Thai, personal, programming | No Comments »


(Photo: That awkward moment when it took one photo and five minutes to realize there’s a … YAKINIKU!)

วันนี้งานเริ่มหมด หนักไปทางเก็บรายละเอียดและทำ installer ให้เสร็จ จะได้ปิดงานได้ซักที งานที่ทำจึงไม่ค่อยมีอะไรโดดเด่นเป็นสาระเท่าไหร่เช่นกัน โดยเริ่มจากการล็อกปุ่ม Load ตอนที่เพิ่งกดไปใหม่ๆ เพื่อไม่ให้เกิดภาระงานมากจนเกินไป ทำ embed code ให้ update ทุกอักขระที่พิมพ์ (โดยไม่มีการ ช้าไปหนึ่งจังหวะ ) รวมไปถึงการปรับโค้ดของการโหลดวิดีโอจากฐานข้อมูลเพื่อให้ระบบตอบสนองได้ไวขึ้น

ที่เหลือก็ไม่ค่อยมีอะไรมากแล้ว อาจมีการปรับ CSS บ้างอะไรบ้างไปตามเรื่อง รวมไปถึงการอธิบายโค้ดให้เรียบร้อย (กว่าเดิมนิดนึง) เพื่อให้กลับมาพัฒนาต่อในภายหลังได้ง่ายขึ้น

There’s not many things to do left. I spent most time creating installer and polishing old code, such as locking the Load button while loading data from database, as well as updating embed code more rapidly (without ” falling one character behind “), and making the database loading process more responsive.

Then I adjusted some of the CSS, and documented the entire job for easier development in the future.

Internship, Day 13 (8 May 2012)

Posted on May 9th, 2012 in computer, CPE, in English, in Thai, personal, PHP, programming | No Comments »


(Photo: A report to be submitted to the company)

วันนี้ผมลืมบัตรพนักงานไว้ที่บ้าน ซึ่งแน่นอนว่าต้องกลับไปเอา ไม่เช่นนั้นจะเกิดความลำบากหลายอย่างมากตลอดทั้งวัน แต่กว่าจะกลับไปเอาบัตรแล้วกลับมาทำงานได้ก็เกือบสายเช่นกัน (ก็ยังดีที่ไม่สาย แต่ท่อนบนเปียกเหงื่อเต็มๆ ฮ่าๆ)

เข้าเรื่องกันดีกว่า ผมต้องการให้ระบบจัด playlist ของผมเรียงลำดับได้ด้วย (เช่น อยากสลับให้ไฟล์ 2 เล่นก่อนไฟล์ 1) แต่ไม่รู้ว่าจะสลับข้อมูลในฐานข้อมูลยังไงให้เหมาะสม ผมเลยใช้วิธีลบทั้งหมดแล้วสร้างใหม่เอาดื้อๆ เลย โดยใช้ความรู้เกี่ยวกับ transaction ในการรักษาสภาพฐานข้อมูล เพราะการลบสร้างใหม่จะมีหลายขั้นตอนมาก และหากมีปัญหาจะทำให้ข้อมูลที่เก็บไว้เสียหายได้ สำหรับการใช้ transaction ใน mysqli นั้นไม่ยาก แต่ขอเก็บไว้ทีหลังเหมือนเดิมครับ นอกจากนี้ เพื่อให้ได้ความเร็วในการทำงานมากขึ้น ผมจึงทดลองนำ prepared statements ออกมาใช้ด้วย

ต่อมา ผมก็ทำระบบดึง playlist กลับออกมา อันนี้ไม่ค่อยยากแล้ว แค่ใช้ SELECT ด้วย SQL จากนั้นจึง print ผ่าน json_encode เพื่อให้เรียกผ่าน jQuery ได้ง่ายๆ

พี่มาบอกว่า iPad ใช้งานตัวนี้ไม่ได้ ผมก็ไม่ค่อยแน่ใจว่าเกิดอะไรขึ้น (ยกเว้นว่าผมจะมี iPad ใช้ซักตัว 555+) แต่ก็ลง jQuery UI Touch Punch ไปแล้ว น่าจะใช้ได้ดีขึ้นเพราะผมทดลองใช้งานดูก็ไม่มีปัญหาแล้ว แต่ถ้าจะทำใช้บนมือถือคงต้องลดขนาดภาพลงอีก (ลองดูแล้วเต็มจอมากๆ)

จากนั้น ผมไม่อยากให้ต้องมากดดูรายชื่อ playlist ผมก็เลยลง AutoComplete เพิ่มอีกตัว ตรงนี้ยากเล็กน้อย แต่ผมจะพยายามอธิบายให้ง่ายตอนท้ายเช่นกัน สุดท้ายผมก็ไม่ต้องแสดงรายชื่อ playlist ทั้งหมด แค่พิมพ์ลงไปก็ได้ ซึ่งตรงนี้ผมเขียน PHP ดักไว้แล้วว่าถ้าเป็น playlist ที่มีอยู่แล้วก็ทำงานได้เลย แต่ถ้ายังไม่มีก็ต้องสร้างใหม่ก่อน เป็นต้น

I forgot the staff ID at home, so I had to go back and get it to avert further complications. As a result, I was almost late for work, sweating all over.

On point. I wanted the playlist manager to support “sorting” playing order, but I don’t know the optimal method so I just wiped the playlist and create it anew, using what I learned about transactions. I used transactions because it needed many steps to complete and I can’t risk any problem. Using transactions in mysqli is not very hard, so is “prepared statements” feature.

Then, I created the playlist loader that pulls data back from the database. I already got the hang of it, and a simple SELECT + json_encode did it all very well.

Senior staff came and told me it’s not working on iPad. I’m not sure how it looked like (unless I had, of course, an iPad!) but I installed jQuery UI Touch Punch and it partially works now. (Partial because there’s no screen real estate on my phone!!)

Finally, I don’t want to list every single playlist when user wants to find one so I used AutoComplete. It’s a bit tricky, but I’ll try to keep it easy. The end product is a text field with, of course, AutoComplete. If user enters something not already in the list, it will be added after the playlist is saved.

mysqli transactions with prepared statements

(I’m using procedural style here, and I assume that you’ve already created a connection.)

 // Disable autocommit (we're doing it manually here)
mysqli_autocommit($db, false);

// Your query here
// Replace potential variables with question marks
$q = "INSERT INTO files (fileName, fileAuthor) VALUES (?, ?)";

$stmt = mysqli_prepare($db, $q) or die('Prepare Failed');

// If we have an array, we can foreach over it
foreach ($newData as $row){
  $bind = mysqli_stmt_bind_param($stmt,'ss',$row ['Name'] ,$row ['Author'] );
  if (!$bind){
    mysqli_rollback($db);
    die('Bind Failed');
  }

  $result = mysqli_stmt_execute($stmt);
  if (!$result) {
    mysqli_rollback($db);
    die('Insert Failed');
  }
}

// All done, we can now commit and re-enable autocommit
mysqli_commit($db);
print('OK! All done!');

mysqli_autocommit($db, true); 

jQuery UI AutoComplete

HTML Part: Interface

 <div id="menu-container" style="position:absolute; width: 20px;"></div>
<input type="text" name="searchq" id="searchq"> 

JS Part: Just one function

 $(function(){
  $("#searchq").autocomplete({
    source:'get_data.php',
    minLength: 1,
    delay: 100,
    appendTo: '#menu-container'
  });
}); 

PHP Part is the trickiest. You will need to accept a GET variable, $_GET ['term'] , which are supplied as the user types into the text box. Yes, you will need to perform filtering here. The following is the easiest method, displaying every candidate alphabetically without limit.

 function filter_result($term){
  $r = mysqli_query("SELECT fileName FROM files WHERE fileName LIKE '%$term%'");
  $result = Array();
  while($row = mysqli_fetch_assoc($r)){
    $result []  = $row ['fileName'] ;
  }
  return $result;
}
print json_encode(playlist_list($_GET ['term'] )); 

Reference: [StackOverflow]