वीर

25 เมษายน 2008

CakePHP 1.2 + ภาษาไทย + UTF-8 + MySQL

default encoding ของ MySQL เท่าที่ผมใช้ไม่ได้เป็น UTF-8. เวลาใช้ CakePHP ก็เลยต้องแก้ configuration นิดหน่อยเพื่อทำให้ ใช้ UTF-8 และ MySQL ได้เนียนๆ. ใน CakePHP รุ่นก่อนๆ หน้านี้บางทีก็ต้องไปแก้ AppModel ที่ไม่ค่อยเท่เท่าไหร่ เพราะน่าจะต้องมาแก้อีกเวลา port ไปใช้ database ตัวอื่นที่ไม่ใช่ MySQL.

ใน Cake 1.2.x สามารถตั้งค่า encoding/charset แบบรวมศูนย์ได้ใน app/config/database.php เลย. ตามตัวอย่างแบบด้านล่าง

class DATABASE_CONFIG {

    var $default = array(
        'driver' => 'mysql',
        'persistent' => false,
        'host' => 'localhost',
        'login' => 'your_username',
        'password' => 'your_password',
        'database' => 'my2',
        'prefix' => '',
        'encoding' => 'UTF8' #ดูบรรทัดนี้เป็นสำคัญ
    );

    var $test = array(
        'driver' => 'mysql',
        'persistent' => false,
        'host' => 'localhost',
        'login' => 'user',
        'password' => 'password',
        'database' => 'test_database_name',
        'prefix' => '',
    );
}
?>

เพื่อม ‘encoding’ => ‘UTF8′ เข้าไปก็ทำให้ใช้ภาษาไทยและ UTF-8 ได้เนียนๆ แล้ว.

พอมาเปิดใน phpmyadmin ที่ตั้งค่าให้ใช้ UTF-8 และภาษาไทย

ก็แสดงผลออกมาได้ถูกต้อง.

สรุปว่าถ้าอยากใช้ UTF-8 กับ MySQL ใน CakePHP 1.2.x ก็เข้าไปตั้งค่าได้ใน app/config/database.php

อ้างอิง

24 เมษายน 2008

CakePHP 1.2.0.6311b: Group + ACL + AuthComponent

หลังจากที่ใช้ ACL กับ AuthComponent ได้แล้ว … ก็จะลองเปลี่ยนตัวอย่างเก่าให้ใช้ Group ได้ดู ก็แก้เยอะเหมือน :-P.

ผมเริ่มจากการแก้ database schema ก่อน. หลังจากที่ลองใช้ migration อยู่พักใหญ่แล้วผมก็งงๆ เลยตัดสินใจสละ table: aros และ users ไป.

เริ่มจากลบของใน table: aros และ aros_acos ก่อน ด้วยคำสั่ง:

mysql -u<your_username> -p<your_password> my_project -e 'delete from aros;'
mysql -u<your_username> -p<your_password> my_project -e 'delete from aros_acos;'

แล้วก็แก้ CakeSchema ของ user ใน folder: app/config/sql, ไฟล์: users.php แก้เป็นแบบนี้:

class UsersSchema extends CakeSchema {

    var $name = 'users';

    function before($event = array()) {
        return true;
    }

    function after($event = array()) {
    }

    var $users =
        array('id' => array('type'=>'integer',
                            'null' => false,
                            'key' => 'primary',
                            'extra' => 'auto_increment'),
              'username' =>  array('type'=>'string',
                                   'null' => false,
                                   'length' => 255),
              'password' =>  array('type'=>'string',
                                   'null' => false,
                                   'length' => 255),
              'group_id' => array('type' => 'integer',
                                  'null' => false),
              'indexes' => array('PRIMARY' => array('column' => 'id',
                                                    'unique' => 1)));
    var $groups =
        array('id' => array('type' => 'integer',
                            'null' => false,
                            'key' => 'primary',
                            'extra' => 'auto_increment'),
              'name' => array('type' => 'string',
                              'null' => 'false',
                              'length' => 255,
                              'unique' => true),
              'parent_id' => array('type' => 'integer'),
              'indexes' => array('PRIMARY' => array('column' => 'id',
                                                    'unique' => true),
                                 'GRP_NAME_KEY' => array('column' => 'name',
                                                         'unique' => true)));

ของใหม่อีกอย่างหนึ่งในตัวอย่างนี้คือ AclBehavior ที่จะช่วย sync ระหว่าง users, groups และ acl. แต่เท่าที่ใช้มา AclBehavior ไม่แก้ค่า alias ใน Aro ก็เลยสร้าง AclaBehavior จากการดัดแปลง AclBehavior นิดๆ หน่อยๆ โดยเพิ่มไฟล์ acla.php ลงใน folder: app/model/behaviors แบบข้างล่าง (จริงแล้วต้องเปิด <?php และปิดด้วย ?> ด้วย … แต่ว่าใส่ใน wordpress แล้วเหมือนเพี้ยนๆ ผมก็แก้ไม่เป็นด้วย.)

/* SVN FILE: $Id: acl.php 6311 2008-01-02 06:33:52Z phpnut $ */
/**
 * ACL behavior class.
 *
 * Enables objects to easily tie into an ACL system
 *
 * PHP versions 4 and 5
 *
 * CakePHP :  Rapid Development Framework <http ://www.cakephp.org/>
 * Copyright 2006-2008, Cake Software Foundation, Inc.
 *                                1785 E. Sahara Avenue, Suite 490-204
 *                                Las Vegas, Nevada 89104
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * @filesource
 * @copyright        Copyright 2006-2008, Cake Software Foundation, Inc.
 * @link                http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
 * @package            cake
 * @subpackage        cake.cake.libs.model.behaviors
 * @since            CakePHP v 1.2.0.4487
 * @version            $Revision: 6311 $
 * @modifiedby        $LastChangedBy: phpnut $
 * @lastmodified    $Date: 2008-01-02 00:33:52 -0600 (Wed, 02 Jan 2008) $
 * @license            http://www.opensource.org/licenses/mit-license.php The MIT License
 */
/**
 * Short description for file
 *
 * Long description for file
 *
 * @package        cake
 * @subpackage    cake.cake.libs.model.behaviors
 */
class AclaBehavior extends ModelBehavior {

/**
 * Maps ACL type options to ACL models
 *
 * @var array
 * @access protected
 */
    var $__typeMaps = array('requester' => 'Aro', 'controlled' => 'Aco');
/**
 * Sets up the configuation for the model, and loads ACL models if they haven't been already
 *
 * @param mixed $config
 */
    function setup(&$model, $config = array()) {
        if (is_string($config)) {
            $config = array('type' => $config);
        }
        $this->settings[$model->alias] = array_merge(array('type' => 'requester'), (array)$config);
        $type = $this->__typeMaps[$this->settings[$model->alias]['type']];

        if (!ClassRegistry::isKeySet($type)) {
            uses('model' . DS . 'db_acl');
            $object =& new $type();
        } else {
            $object =& ClassRegistry::getObject($type);
        }
        $model->{$type} =& $object;
        if (!method_exists($model, 'parentNode')) {
            trigger_error("Callback parentNode() not defined in {$model->alias}", E_USER_WARNING);
        }
    }
/**
 * Retrieves the Aro/Aco node for this model
 *
 * @param mixed $ref
 * @return array
 */
    function node(&$model, $ref = null) {
        $type = $this->__typeMaps[strtolower($this->settings[$model->alias]['type'])];
        if (empty($ref)) {
            $ref = array('model' => $model->alias, 'foreign_key' => $model->id);
        }

        return $model->{$type}->node($ref);
    }
/**
 * Creates a new ARO/ACO node bound to this record
 *
 * @param boolean $created True if this is a new record
 */
    function afterSave(&$model, $created) {
        if ($created) {
            $type = $this->__typeMaps[strtolower($this->settings[$model->alias]['type'])];
            $parent = $model->parentNode();

            if (!empty($parent)) {
                $parent = $this->node($model, $parent);
            } else {
                $parent = null;
            }

            $acl_node_alias = null;

            if(method_exists($model, "aclNodeAlias"))
                $acl_node_alias = $model->aclNodeAlias();

            $model->{$type}->create();
            $model->{$type}->save(array(
                'parent_id'        => Set::extract($parent, "0.{$type}.id"),
                'model'            => $model->alias,
                'foreign_key'    => $model->id,
                'alias'         => $acl_node_alias
            ));
        }
    }
/**
 * Destroys the ARO/ACO node bound to the deleted record
 *
 */
    function afterDelete(&$model) {
        $type = $this->__typeMaps[strtolower($this->settings[$model->alias]['type'])];
        $node = Set::extract($this->node($model), "0.{$type}.id");
        if (!empty($node)) {
            $model->{$type}->delete($node);
        }
    }
}

ไม่พอก็ยังต้องแก้ CakeShell ต่อใน folder: app/vendors/shells

แก้ user.php:

uses ('controller'.DS.'components'.DS.'auth');

class UserShell extends Shell {
    var $uses = array("User", "Group");
    function add() {
        $auth = new AuthComponent();
        $username = $this->args[0];
        $password = $auth->password($this->args[1]);
        $grp_name = $this->args[2];
        $grp = $this->get_group($grp_name);
        $data = array("User" =>
                      array("username" => $username,
                            "password" => $password,
                            "group_id" => $grp["id"]));
        if($this->User->save($data))
            print "Success: $username was added\n";
        else
            print "Fail\n";
    }

    function get_group($name) {
        $data = $this->Group->findByName($name);
        if(!$data)
            return null;
        else
            return $data["Group"];

    }
}

สร้าง group.php ขึ้นมาใหม่:

class GroupShell extends Shell {

    var $uses = array("Group", "Aro");

    function add() {
        $name = $this->args[1];
        $parent_name = $this->args[0];
        if($parent_name == '/')
            $parent_id = null;
        else
            $parent_id = $this->get_parent($parent_name);
        $data = array("Group" =>
                      array("parent_id" => $parent_id,
                            "name" => $name));
        if($this->Group->save($data))
            print "Success: group: $name has been added\n";
        else
            print "Fail\n";
    }

    function get_parent($name) {
        $data = $this->Group->findByName($name, null, null, False);
        if(!$data['Group']['id'])
            return null;
        else
            return $data['Group']['id'];
    }
}

ยังไม่หมดต้องมาแก้ model ต่อใน folder: app/model

แก้ user.php:

class User extends AppModel {
    var $actsAs = array('Acla');
    var $belongsTo = array('Group');

    function parentNode() {
        if(!$this->id)
            return null;

        $data = $this->read();
        if(!$data['Group']['id'])
            return null;
        else
            return array('model' => 'Group',
                         'foreign_key' => $data['Group']['id']); 
    }
}

ตามด้วยเขียน group.php ขึ้นมาใหม่:

class Group extends AppModel {
    var $actsAs = array('Acla');
    var $hasMany = array('User');
    function parentNode() {
        if(!$this->id)
            return null;
        $data = $this->read();
        if(!$data['Group']['parent_id'])
            return null;
        else
            return array('model' => 'Group',
                         'foreign_key' => $data['Group']['parent_id']);
    }

    function aclNodeAlias() {
        if(!$this->id)
            return null;
        $data = $this->read();
        if(!$data['Group']['name'])
            return null;
        else
            return $data['Group']['name'];
    }

}

จาก code ที่แก้มามากมายก็จะเริ่มเรียกใช้แล้ว. โดย cd เข้าไปใน cake/console สั่ง: ./cake schema run create users แล้วก็กด y ไปเรื่อยๆ. เพื่อที่จะ drop table: users เก่าทิ้งไป แล้วสร้าง table: users และ groups ขึ้นมาใหม่.

ตามด้วยสร้าง group ขึ้นมาใหม่แบ่งเป็น admins กับ users ตามนี้:

./cake group add ‘/’ users

./cake group add ‘/’ admins

แล้วก็ add user ไว้ทดลอง group ละ 1 user:

./cake user add myadmin mypassword admins
./cake user add myuser mypassword users

grant ให้ admins ดูได้ทั้ง site (ทุกหน้า, ทุก action):

./cake acl grant admins site ‘*’

grant ให้ users ดู Pages/display (เอาไว้ redirect มาเวลาดูหน้าอื่นไม่ได้). และ ดู Books/display1:

./cake acl grant users ‘Pages/display’ ‘*’

./cake acl grant users ‘Books/display1′ ‘*’

ถ้าลอง login ด้วย myadmin ก็จะดูได้ทุกหน้า. แต่ถ้า login ด้วย myuser ก็จะดู http://localhost/my_project/books/display2 ไม่ได้.

ก็เป็นอันว่า users แต่ละกลุ่ม ก็ดูหน้าเว็บได้ต่างๆ กันตามที่กำหมดไว้ :-).

อ้างอิง:

http://lemoncake.wordpress.com/2007/07/19/acl-with-groups/

23 เมษายน 2008

CakePHP 1.2.x: Action-based ACL

หลังจากที่ลองใช้ AuthComponent อย่างง่ายไปแล้ว. ผมก็อยากจะลอง ACL (Access control list) บ้าง ไม่รู้ว่าทำถูกวิธีหรือเปล่าด้วย. ผมก็เริ่มจากแก้ app_controller.php ใน cake/libs/controller เลย

class AppController extends Controller {
    var $components = array('Auth', 'Acl');

    function beforeFilter() {
        if(isset($this->Auth)) {
            $this->Auth->authorize = "actions";
            $this->Auth->userModel = 'User';
        }
   }
}

ACL ใน CakePHP ระบุความสัมพันธ์ระหว่าง ARO และ ACO. ARO ใน blog entry นี้ก็คือ user ของเว็บ. ส่วน ACO ของ CakePHP เป็นได้หลายอย่าง ได้แก่ controller, model และ action. ในที่นี้ผมระบุว่าใช้ action $this->Auth->authorize = “actions”; โดย action ก็คงประมาณว่าระบุเลยว่า user เข้าไปใช้หน้าไหนได้บ้างเช่น ระบุว่า user1 เข้าไปใช้ http://localhost/books/display1 ได้หรือเปล่า ระบุเป็นรายหน้าเลย.

หลังจากระบุไปแบบนี้แล้วผมก็ลอง login เพื่อที่จะไปเปิดดูหน้า http://localhost/books/display1 ผมก็คือเจ๊งตอบรูปข้างล่าง:

ที่ยังใช้ไม่ได้เพราะยังไม่ได้ใส่ข้อมูลใน ACL. ดูๆ แล้วการใช้ action-based acl เหมือนจะออกแรงเยอะชอบกล :-P. เหมือนกัน. เราเพิ่ม acl ด้วย command line interface เริ่มจาก cd เข้าไปใน folder: cake/console แล้วใช้คำสั่งต่อไปนี้


./cake acl create aro ‘/’ ‘users’
./cake acl create aco ‘/’ ’site’
./cake acl create aco ’site’ ‘Pages’
./cake acl create aco ‘Pages’ ‘display’
./cake acl create aco ’site’ ‘Books’
./cake acl create aco ‘Books’ ‘display1′
./cake acl create aco ‘Books’ ‘display2′
./cake acl create aco ’site’ ‘Users’
./cake acl create aco ‘Users’ ‘login’
./cake acl create aco ‘Users’ ‘logout’
./cake acl grant ‘users’ ‘Pages/display’ ‘*’
./cake acl grant ‘users’ ‘Books/display1′ ‘*’

แล้วก็ยังไม่พอต้องเข้าไปแก้ database ตรงๆ อีกนิดหน่อย (ผมใช้ MySQL ในตัวอย่างนี้)

mysql -u<your_username> -p<your_password> my_project -e ’set @userid = (select id from users where username = “myusername”); update aros set foreign_key = @userid, model = “User” where alias=”users”;’

เท่านี้ก็ลองเข้าไปในเว็บได้แล้ว หลังจาก login ที่หน้า http://localhost/my_project/users/login แล้ว. ก็ลองดูเว็บ page ใน http://localhost/my_project/books/display1 ก็ควรจะเข้าไปดูได้ แต่ถ้าเข้าไปใน http://localhost/my_project/books/display2 ก็จะถูก redirect กลับมาที่ http://localhost/my_project/

การใช้ acl แบบนี้ก็ยังมีปัญหาอยู่บ้าง ที่ว่าต้องมา grant สิทธิให้ user แต่ละคน กับหน้าแทบทุกหน้า เพราะ aco นึง map กับ user 1 คน … ถ้ามี user มากๆ ก็คงไม่เคยเหมาะ. ดังนั้นจึงน่าจะใช้ group เข้ามาช่วยได้ คือให้ aco เชื่อมกับ group แทน และระบุว่า group ไหน มี user คนไหนบ้าง.

อ้างอิง

http://aranworld.com/article/162/cakephp-acl-tutorial-initial-setup

ใช้ AuthComponent ของ CakePHP 1.2.x อย่างง่าย

หลังจากติดตั้ง CakePHP เรียบร้อยแล้ว. นอกจากนั้นเพื่อให้การทดลองเป็นได้โดยสะดวกผมคิดว่าควรจะสร้าง view กับ controller ง่ายๆ ไว้ใช้ในทดลองก่อน. จากนั้นก็สร้าง user table ผ่านทาง CakeSchema. แล้วก็เตรียม model ของ users table พร้อมด้วย add user เข้าไปลองก่อนสัก user. ขั้นตอนต่อไปก็แก้ AppController ที่อยู่ใน  cake/libs/controller/app_controller.php นิดหน่อย พอแก้แล้วหน้าตาก็จะเป็นแบบด้านล่าง:

< ?php

/* มี comment ต่างๆ นานา */

class AppController extends Controller {
    var $components = array('Auth', 'Acl');
}
?>

ทีนี้ก็ลองเข้าเปิดเว็บดูหน้า http://localhost/my_project/books/display1 ถ้า app ของเราทำงานถูกต้องหน้าเว็บจะถูก redirect ไปที่ http://localhost/my_project/users/login แบบข้างล่าง

แล้วก็กรอก username: myusername และ password: mypassword (ตามที่ add ไปก่อนหน้านี้ในการเตรียม model ของ users table พร้อมด้วย add user เข้าไปลองก่อนสัก user. ) แล้วก็กด “submit” ถ้าเข้าได้ปกติมันก็ redirect มาที่ books/display1 ตามที่เข้าไว้ตอนแรก.

ถ้ามี warning ว่าเขียน app/tmp ไม่ได้ขึ้นมาแบบในตัวอย่างผมก็แก้ permission เอา โดยใช้คำสั่ง chmod -R 777 app/tmp ทำให้ทุก user เขียนได้ … อาจจะมีใช่วิธีแก้ปัญหาที่ดีแต่มันก็ทำ warning หายไป :-P.

เวลาจะ logout ก็แค่เข้าไปที่ http://localhost/my_project/users/logout

ก็เป็นอันว่าเว็บที่สร้างขึ้นมามีระบบ login แล้ว แต่ก็แยกได้แค่ว่า login หรือไม่ login. ใคร login ก็ดูได้ทุกหน้า ไม่ login ก็ดูอะไรไม่ได้. การจะทำอะไรซับซ้อนกว่านี้ใช้ Access control list (ACL) ช่วยได้.

23 มีนาคม 2008

ละครของ อเล็กซานดร้า บุญช่วย จะออกอากาศแล้ว?

ละครของอเล็กซานดร้าจะออกอากาศอีกแล้ว ช่วงนี้ดูช่องเจ็ดเริ่มเห็นตัวอย่างออกมาบ้างแล้ว. เรื่อง “เรไร ลูกสาวป่า” ดูตัวอย่างแล้วเนื้อเรื่อง หรืออะไรต่างๆ ไม่ได้ทำให้อยากดูเลย. ไม่ใช่ว่าไม่ดีนะ แค่ไม่ทำให้ผมอยากดู. แต่จะดูเพราะอยากดูอเล็กซานดร้า เล่นละคร. รอฟังเพลงประกอบละครด้วย. เรืองก่อนของ “อเล็กซานดร้า” อะไรสองฝั่งโขงสักอย่างอดดู เพราะไม่มีทีวีดู. … เลยได้แต่ฟังเพลงประกอบละคร แอบคิดว่าน่าจะดีถ้ามีเพลงเดี่ยวของอเล็กซานดร้ามากกว่านี้หน่อย และขอแบบที่ไม่ใช่ลูกทุ่งบ้างก็ดี.

http://www.ch7.com/Entertain/News_Detail.aspx?NwType=06&SbType=00&SeqNo=164

update: จะออกอากาศวันที่ 4 เมษาฯ http://blog.vee-u.com/2008/03/28/alexandra/ 

23 กุมภาพันธ์ 2008

รัฐบาลห้ามข้าราชการใช้ Hotmail/Yahoo/Gmail และอื่นๆ … MSN และ Ubuntu

Filed under: Uncategorized — वीर @ 1:22 pm
Tags: , , , , ,

รัฐบาลห้ามข้าราชการใช้ e-mail เอกชน ข่าวมาจาก INN News นะครับ เช่น Yahoo/Hot/G mail เป็นต้น. จากข่าวบอกว่ารัฐบาลห้ามตั้งแต่ข้าราชการซี 8 ขึ้นไป เพราะว่ากลัวว่าจะถูกล้วงความลับ. เรื่องนี้ส่วนตัวผมคิดว่า ฟังดูก็สมเหตุสมผลอยู่.

แต่ก็น่าจะพอจะคาดเดาได้ว่าสิ่งที่ตามมาอาจจะเป็นความไม่สะดวกสบาย และผู้ได้ประโยชน์. สมัยเมื่อนานมาแล้ว ผมเคยใช้เมล์ของต้นสังกัด ปัญหาใหญ่ๆ เลยคือให้พื้นที่น้อย ต้องมาลบบ่อย. ล่มบ่อย. ชื่อเมล์ไม่ค่อยสื่อความหมาย จริงๆ แล้วคล้ายเบอร์โทรศัพท์มากกว่า. เนื่องจากว่าโดน spam mail เข้าไปเยอะ ทำให้ server ช้าเข้าไปใหญ่. คนอ่านเมล์ก็เจอแต่ spam มากมาย. นอกจากนั้นยังอ่านเมล์ผ่านทาง IMAP และ POP ได้แต่ในที่ทำงาน ถ้าเป็นทางอื่นก็ต้องอ่านผ่านเว็บสถานเดียว. ซึ่งเห็นได้ชัดเจนว่าด้อยกว่าเมล์ที่ให้บริการฟรีๆ มากมาย และนี่ก็คงเป็นสาเหตุว่าทำไมคนถึงไม่ใช้เมล์ของต้นสังกัด …. แต่ว่าเดี๋ยวนี้คงเปลี่ยนไปแล้ว?

อาจจะเป็นไปได้ว่าเหตุการณ์ที่ผมเคยเจออาจจะไปเกิดกับข้าราชการด้วย. ทางออกก็อาจจะเป็นต้องซื้อ solution ของเอกชน มีกรอง spam mail. ซื้อโปรแกรมทำโน่นทำนี่ ดีไม่ดีอาจจะต้อง outsource งานทำ server ออกไปให้เอกชนทำ เพื่อให้ได้คุณภาพที่ดี? (หรือเปล่า?) . ซึ่งก็น่าจะให้รัฐบาลของประเทศอื่นล้วงความลับได้ยากขึ้นนมั้ง เพราะว่าอย่างน้อยก็ควบคุมได้มากขึ้น. อย่างไรก็ตาม ก็คงจะต้องไม่ลืมระวังซอฟต์แวร์ หรือระบบทั้งระบบที่ซื้อมาใช้ คนที่จ้างมาว่าจะไว้วางใจได้แค่ไหน. ทำตัวเป็น spyware หรือเปล่า. มากไปกว่านั้นหากมัวแต่ระวังที่ server ก็อาจจะโดนโจมตีที่เครื่องส่วนตัวแทนก็ได้? เครื่องที่ลงโปรแกรมที่ไม่ชอบมาพากล รวมถึงซอฟต์แวร์เถื่อนทั้งหลาย ก็อาจจะน่ากลัวเป็นพิเศษ. นี่อาจจะลามไปถึงว่าต่อไปรัฐบาลต้องซื้อ Windows และ MS Office ให้ข้าราชการ ทั้งประเทศใช้กันด้วย? ทว่าเท่านั้นอาจจะยังไม่ปลอดภัยพอ. ทางออกที่แกร่งกว่าอาจจะเป็นการใช้เครื่องศูนย์รวม และใช้ Terminal server เอา?

ดีไม่ดีป้องกันเมล์กันดิบดี ข้าราชการก็ส่งข้อมูลกันทาง Windows Live Messenger ซะนี่ก็คงจบกัน :-P.

ผมก็ได้แต่จิตนาการไป ไม่รู้ว่าระบบของรัฐตอนนี้จริงๆเป็นอย่างไร? ทำไปทำมา จะมี Ubuntu มาเป็น server บ้างหรือเปล่า. หรือจะมี Ubuntu เข้าไปแทรกเป็น client หรือ server  ได้สักเครื่องไหม ถ้าหากว่าต้องการระบบที่รัฐบาลไทยดูแลได้ ขนาดที่ว่าเข้าไป review code และแก้ไขเองได้.   Jabber server บ้างเปล่านะ? ไม่ใช้ Jabber แล้วซื้อ M server มาก็ไม่ผิดหรอกมั้ง. … แต่ผมตามประสาแฟน Ubuntu และ Jabber ก็อยากให้ใช้ Ubuntu กับ Jabber อะ.

20 กุมภาพันธ์ 2008

KUCut - โปรแกรมตัดคำ ที่เขียนด้วย Python

Filed under: Uncategorized — वीर @ 10:49 am
Tags: , , , ,

หลายคนแม้แต่ในหน่วยวิจัยเดียวกันมักจะถามผมว่าใช้โปรแกรมตัดคำตัวไหนอยู่. โปรแกรมตัดคำตัวที่ผมใช้เป็นหลักชื่อว่า KUCut จาก NAiST @KUมี license แบบ GPL และ download ได้จาก http://naist.cpe.ku.ac.th/pkg/kucut-1.2.2_python25_fix.zip. โปรแกรมตัดคำตัวนี้เขียนด้วยภาษา Python. หลักการที่แปลกจากตัวอื่นคือใช้เทคนิค unsupervised machine learning ด้วย อ่านเพิ่มได้จาก “การตัดคําภาษาไทยดวยเทคนิคการเรียนรูแบบไมใชตัวอยาง”.

ส่วน Python sdk และ runtime (ภาษาเรียกแบบ Java :-P) สามารถ download ได้จาก http://www.python.org/download/

ฟังลูกทุ่งมหานครบน Ubuntu 7.10

เรียก terminal ขึ้นมาแล้วพิมพ์ตามข้างล่างเลย หรือถ้าไม่ได้ก็ลง vlc ก่อน.

vlc http://radio.mcot.net/popup/fm_95.asx

17 กุมภาพันธ์ 2008

ซบ Epiphany

Filed under: Uncategorized — वीर @ 5:02 am
Tags: , , , , ,

ช่วงนี้มีปัญหาว่า Firefox 3 beta ทั้งหลาย บางทีก็เปิดนั่นโน่นนี่ไม่ได้. ก็เลยต้องเปิด Firefox 2 สลับไปมา แต่เหมือนมันเปิดพร้อมกันไม่ได้. เลยลองมาใช้ Epiphany ดูก็เปิดพร้อมกับ Firefox 3 beta x. แถมยังแสดงตัวอักษร ออกมาดูดี + หน้าตาของ preference ไม่ซับซ้อนด้วย. เลยต้องใช้ซะแล้ว :-).

15 กุมภาพันธ์ 2008

เครื่องจักรแปลภาษางุงิกับภาษาไทย

ภาษางุงิเป็นภาษาที่เด็กๆ และวัยรุ่นไทยนิยมใช้สื่อสารกัน. ภาษางุงิพูดเขียนคล้ายๆภาษาไทย และยืมอักษรภาษาไทยไปใช้ อย่างไรก็ตามการใช้คำแบบคำแตกต่างกันอย่างมาก. มากไปกว่านั้นการสะกดคำยังแตกต่างกันอีกด้วย. ยกตัวอย่างเช่น “งับๆ” ในภาษางุงิแปลเป็นภาษาไทยได้ว่า “ครับๆ”.

อย่างไรก็ตามภาษางุงิไม่ได้ใช้เป็นภาษาราชการของประเทศใดๆ มากไปกว่านั้นยังใช้เฉพาะในกลุ่มเด็กและเยาวชน จึงทำให้เยาวชนจำเป็นต้องเรียนภาษาอื่นๆ เช่น ภาษาไทย เพิ่มเติมขึ้นจากภาษางุงิ ฯลฯ. มากไปกว่านั้นคนไทยทั่วไปก็อาจจะอยากทราบว่าข้อความภาษางุงิเขียนว่าอะไร.

ดังนั้นเราจึงข้อเสนอโครงการสร้างเครื่องจักรแปลภาษางุงิเป็นภาษาไทยและภาษาไทยเป็นภาษางุง. ซึ่งในช่วงแรกจะเริ่มจากการสร้างพจนานุกรมไทย - งุงิ กันก่อน. … จะสร้างอย่างไรดี?

หน้าต่อไป »

บลอกที่ WordPress.com .