Minggu, November 16, 2008

Mengatasi firefox berjalan di modus offline di ubuntu terbaru

Pengguna Ubuntu sejak rilis Hardy Heron dan sekarang Intrepid Ibex, yang terkoneksi Internet menggunakan modem, atau tidak menggunakan Internet sama sekali, hampir dipastikan mengalami masalah Firefox berjalan pada modus Work Offline. Permasalahan ini bersumber dari NetworkManager yang tidak mendeteksi adanya koneksi melalui ethernet kabel, maupun wireless, sehingga mengirimkan status offline kepada Firefox. Firefox yang mendapatkan status offline ini akan otomatis mengaktifkan modus Work Offline.

Bagi web developer yang bekerja pada localhost, hal ini tentu sangat mengesalkan. Bagi yang terkoneksi lewat modem juga akan merasakan hal yang sama, karena NetworkManager tidak mendeteksi koneksi lewat modem. Saya mencoba mencari cara mengatasi hal ini. Di beberapa halaman yang saya temui menyarankan untuk menonaktifkan NetworkManager, atau mematikan pengiriman notifikasi dari NetworkManager ke aplikasi. Tentu hal ini kurang tepat untuk dilakukan, karena jika suatu saat kita membutuhkan koneksi melalui jaringan kabel ethernet maupun wireless, kita akan membutuhkan NetworkManager.

Saya akhirnya menemukan jawaban pada thread ini. Pada post nomer 34, saya mengetahui adanya opsi toolkit.networkmanager.disable pada firefox. Untuk mengetahui fungsi dari opsi ini, saya mencari informasinya di mozillazine dan mendapatkan halaman ini. Opsi ini sesuai dengan kebutuhan saya, yaitu membuat firefox tidak menggunakan NetworkManager untuk mengetahui status koneksi. Dengan mengeset opsi ini menjadi true, maka firefox tidak akan masuk ke modus Work Offline lagi. NetworkManager tetap berjalan, dan dapat digunakan untuk memilih koneksi kabel ethernet atau wireless saat dibutuhkan.

Semoga informasi ini membantu para pengguna Ubuntu maupun distro Linux lainnya mengatasi permasalahan Firefox Work Offline. Saya menggunakan juga varian Firefox yaitu Flock dan Mozilla Prism, dan opsi toolkit.networkmanager.disable juga bisa diterapkan.

Cara untuk mengeset toolkit.networkmanager.disable menjadi true:

  1. Pada Firefox, ketikkan about:config di kolom isian lokasi

  2. Klik tompol peringatan yang muncul

  3. Pada kolom isian filter, ketik toolkit.networkmanager.disable

  4. Sekarang tabel akan menampilkan opsi toolkit.networkmanager.disable saja. Nilai default adalah false. Klik dobel baris tersebut untuk mengubah nilai false menjadi true.

  5. Cara alternatif, terutama untuk mengeset opsi ini pada Mozilla Prism adalah dengan mengedit file prefs.js, lalu tambahkan baris ini di akhir file:
    user_pref("toolkit.networkmanager.disable", true);
    Lokasi file prefs.js untuk Mozilla Prism akan berada di dalam folder .prism di home direktory. Tiap aplikasi prism memiliki folder setting sendiri-sendiri, gunakan fitur search di nautilus untuk mencari semua file prefs.js yang ada.

Selamat mencoba.

Minggu, November 09, 2008

Publish tulisan ke blog menggunakan OpenOffice

Saya baru saja menemukan extension Sun Weblog Publisher di halaman ini. Extension ini akan membantu pengguna OpenOffice untuk mempublish tulisannya langsung ke blog. Blog yang didukung cukup banyak, diantaranya adalah Blogger dan Wordpress.


Extension ini tentu saja akan memudahkan blogger untuk menulis blognya, karena tidak perlu repot membuka control panel blognya untuk menulis tulisan. Cukup dengan menulis menggunakan OpenOffice, lalu mengklik File > Send > To Weblog... maka tulisannya akan langsung dipublish ke blog. Sangat mudah, cepat, dan nyaman.


Tulisan ini saya tulis menggunakan OpenOffice.org 3.0 yang berjalan pada OS GNU/Linux Ubuntu 8.10 Intrepid Ibex. Indahnya dunia ini dengan adanya software freeware yang menjamin kemerdekaan penggunanya untuk berkreasi.


Rabu, Oktober 15, 2008

Berbagi pengalaman apply kartu kredit BCA

Siang ini saya pergi ke kantor BCA Dago untuk apply kartu kredit BCA. Oleh satpam, saya dipersilahkan menuju lantai 2 untuk menemui Customer Service. Setelah bertemu dengan Customer Service, saya diberikan penjelasan tentang kartu kredit BCA.

Kartu kredit BCA yang akan diterima oleh pemegang kartu kredit ada 2 kartu. Yang pertama adalah kartu BCA Silver atau kartu Gold, dan yang kedua adalah kartu BCA VISA atau MasterCard. Saya bertanya apakah bisa hanya mendaftar untuk kartu VISA saja dan dijawab oleh mbak CS tidak bisa. Biaya tahunan kartu Silver adalah Rp 75.000,- dan biaya tahunan kartu VISA/MasterCard adalah Rp 125.000,- sehingga total biaya tahunan yang harus dibayar oleh pemegang kartu kredit BCA adalah sebesar Rp 200.000,-

BCA memiliki program tahun pertama gratis biaya tahunan kartu Silver/Gold, sehingga pemegang kartu yang baru setahun hanya membayar biaya tahunan untuk kartu VISA/MasterCard. Jika dalam setahun rata-rata penggunaan kartu kredit setiap bulannya mencapai 30% dari limit kartu kredit, maka biaya tahunan kartu Silver/Gold menjadi gratis.

Saya tadi mendaftar untuk kartu VISA, karena akan digunakan untuk aktivasi rekening PayPal yang selama ini masih inaktif. Mumpung saat ini masih berstatus karyawan. Mudah-mudahan saja permohonan aplikasi kartu kredit saya ini disetujui :)

Selasa, September 23, 2008

Mencoba Mozilla Prism

Pagi ini saya mencoba aplikasi Mozilla Prism (sebelumnya bernama WebRunner). Prism adalah aplikasi browser mini yang menjadi jembatan penghubung aplikasi web dengan desktop. Prism tidak menampilkan tampilan menu dan toolbar seperti browser lainnya, tetapi langsung menampilkan halaman aplikasi web secara penuh. Produk lain yang serupa dengan Prism ini adalah Adobe AIR.

Prism menyediakan aplikasi bantu untuk menciptakan file deskripsi dari halaman aplikasi web yang akan dijalankan dengan prism. Shortcut ke aplikasi web ini akan diciptakan di Desktop. Untuk menghapus aplikasi, cukup hapus shortcut ini. Saat ini saya sudah membuat webapp (istilah file deskripsi prism) untuk Plurk, RememberTheMilk, dan Blogger. Posting ini saya tulis dari halaman blogger yang dijalankan menggunakan Prism.

Untuk mendownload Prism, silakan mengunjungi halaman ini. Pengguna Ubuntu Hardy Heron dapat langsung menginstall prism melalui synaptic maupun apt-get, karena prism telah ada di repository standar ubuntu. Terdapat juga bundel webapp yang disertakan, diantaranya adalah google docs, google calendar, facebook, twitter, dan aplikasi google lainnya. Andapun dapat dengan mudah membuat webapp untuk aplikasi web favorit menggunakan aplikasi bantu bawaan dari Prism.

Minggu, Agustus 31, 2008

Menyimpan file ke dalam database dan menampilkannya di halaman web

Hari ini saya membaca artikel yang sangat menarik di asktom tentang keuntungan dan kerugian menyimpan file ke dalam database. Tom menjawab bahwa dia sampai saat ini tidak menemukan keuntungan menyimpan data dari file diluar database. Tom memaparkan keuntungan-keuntungan yang didapatkan kalau data file disimpan ke dalam database, diantaranya:

  1. data akan dikelola dengan profesional oleh DBMS
  2. data akan ikut di-backup
  3. dapat di-rollback / di-recover bersama data-data lainnya
  4. data ikut terlindungi / aman
  5. scalable
  6. locking
  7. konsistensi data
Membaca pembahasan-pembahasan yang ada disana, saya jadi tertarik untuk mencoba menyimpan file ke dalam database. Kebetulan proyek yang sedang saya kerjakan di kantor memilki permasalahan sinkronisasi file. Ada dua website, gambar diupload di salah satu website, dan ditampilkan di kedua website. Keduanya akan berada di mesin yang terpisah, sehingga saya perlu memikirkan cara sinkronisasi file hasil upload. Jika file yang diupload saya simpan ke database, saya tentu tidak akan memiliki masalah sinkronisasi, karena kedua website dapat mengambil data dari database yang sama.

Saya pun mencoba membuat halaman sederhana untuk upload file yang akan disimpan ke database, dan menampilkan file yang tersimpan di database. Saya menggunakan framework codeigniter dan untuk akses database saya menggunakan adodb. Untuk DBMS sendiri saya menggunakan OracleXE.

Berikut ini potongan struktur tabel, dan potongan kode yang saya buat. Silahkan dipelajari dan dikembangkan lebih lanjut.

Tabel

CREATE TABLE "T_BLOB"
("ID" NUMBER NOT NULL ENABLE,
 "TITLE" VARCHAR2(255 CHAR),
 "FILE_DATA" BLOB,
 "CONTENT_TYPE" VARCHAR2(100 CHAR),
 CONSTRAINT "T_BLOB_PK" PRIMARY KEY ("ID"));

Sequence

CREATE SEQUENCE "SEQ_BLOB" INCREMENT BY 1 START WITH 1;

Package

CREATE OR REPLACE PACKAGE "P_PUBLIC_TYPES" AS
  TYPE theCursor IS REF CURSOR;
END P_Public_Types;
/

CREATE OR REPLACE PACKAGE "PG_BLOB" as

  function get_single(v_id in INTEGER) return p_public_types.theCursor;

  function get_all(v_order in VARCHAR2) return p_public_types.theCursor;

  function add_blob(v_title in VARCHAR2
                    ,v_content_type in VARCHAR2) return INTEGER;

  function delete_blob(v_id in integer) return INTEGER;

end pg_blob;
/

CREATE OR REPLACE PACKAGE BODY "PG_BLOB" as

  function get_single(v_id in INTEGER) return p_public_types.theCursor as
    cc p_public_types.thecursor;
  begin

    open cc for '
    SELECT B.*
    FROM T_BLOB B
    WHERE B.ID = ' || v_id || '
    ';

    return cc;
  end get_single;

  function get_all(v_order in VARCHAR2) return p_public_types.theCursor as
    cc      p_public_types.thecursor;
    orderby VARCHAR2(255);
  begin
 
    if v_order is not null then
      orderby := ' ORDER BY ' || orderby;
    end if;

    open cc for '
    SELECT B.*
    FROM T_BLOB B
    ' || orderby || '
    ';

    return cc;
  end get_all;

  function add_blob(v_title in VARCHAR2
                    ,v_content_type in VARCHAR2) return INTEGER as
    new_id  INTEGER;
  BEGIN
    select SEQ_BLOB.nextval into new_id from dual;

    INSERT INTO T_BLOB (ID, TITLE, FILE_DATA, CONTENT_TYPE)
    VALUES (new_id, v_title, empty_blob(), v_content_type);

    if SQL%ROWCOUNT > 0 then
      return new_id;
    else
      return 0;
    end if;
  end add_blob;

  function delete_blob(v_id in integer) return INTEGER as
  begin

    DELETE FROM T_BLOB
    WHERE ID = v_id;

    return SQL%rowcount;
  end delete_blob;

end pg_blob;
/

Controller function index

function index()
{
  echo '<p><a href="'.site_url('/testblob/add').'">Add new data</a></p>';

  $rs =& $this->adodb->db->ExecuteCursor('begin'
                                        .' :result := pg_blob.get_all(:v_order);'
                                        .'end;'
                                        ,'result'
                                        ,array('v_order' => ''));
  if ($rs && $rs->RecordCount() > 0)
  {
    $this->load->library('table');
    $this->table->set_heading('No'
                            , 'Title'
                            , 'Content-Type'
                            , 'File');
    $i = 1;
    foreach ($rs as $row)
    {
      $this->table->add_row($i++
                          , $row['TITLE']
                          , $row['CONTENT_TYPE']
                          , $row['FILE_DATA'] ?
                              '<a href="'.site_url('/testblob/file/'.$row['ID']).'">Download File</a>'
                            : 'No File');
    }
    echo $this->table->generate();
  }
  else
  {
    echo '<p>No Data yet</p>';
  }
}

Controller function add

function add()
{
  if ($this->input->post('submit'))
  {
    $uploaded = false;
    if ($_FILES['file']['name'] != '')
    {
      //upload image
      $conf_upload['upload_path']    = realpath(BASEPATH.'../').'/tmp/';
      $conf_upload['allowed_types']  = 'gif|jpg|png';
      $conf_upload['encrypt_name']   = true;

      $this->upload->initialize($conf_upload);

      if ( ! $this->upload->do_upload('file'))
      {
        //echo '<p>'.$this->upload->display_errors().'</p>';
      }
      else
      {
        $data_upload = $this->upload->data();
        $uploaded = true;
      }
    }
    //insert data
    $sql = 'declare'
          .'  result integer;'
          .'begin'
          .'  :result := pg_blob.add_blob(:v_title'
                                      .', :v_content_type);'
        .'end;';
    $stmt =& $this->adodb->db->PrepareSP($sql);

    $this->adodb->db->InParameter($stmt, $this->input->post('title'), 'v_title', 255);
    $this->adodb->db->InParameter($stmt, $data_upload['file_type'], 'v_content_type', 255);
    $this->adodb->db->OutParameter($stmt, $result, 'result');

    $this->adodb->db->Execute($stmt);

    if ($result > 0)
    {
      if ($uploaded)
      {
        $this->adodb->db->UpdateBlobFile('T_BLOB', 'FILE_DATA', $data_upload['full_path'], 'ID='.$result, 'BLOB');
        unlink ($data_upload['full_path']);
      }
      redirect('/testblob/index');
    }
  }

  echo form_open_multipart('/testblob/add', array('name' => 'form_add', 'id' => 'form_add'));
  echo '<ol>';
  echo '<li>'.form_label('Title', 'title').form_input('title', $this->input->post('title'), 'id="title"').'</li>';
  echo '<li>'.form_label('File', 'file').form_upload('file', '', 'id="file"').'</li>';
  echo '<li>'.form_submit('submit', 'Add');
  echo '</ol>';
  echo form_close();
}

Controller function file

function file()
{
  $id = intval($this->uri->segment(3));
  if (! $id)
  {
    redirect('/testblob/index');
  }

  $rs =& $this->adodb->db->ExecuteCursor('begin'
                                        .' :result := pg_blob.get_single(:v_id);'
                                        .'end;'
                                        ,'result'
                                        ,array('v_id' => $id));
  if ($rs && $rs->RecordCount() > 0)
  {
    if ($rs->fields['FILE_DATA'])
    {
      header('Content-type: '.$rs->fields['CONTENT_TYPE']);
      echo $rs->fields['FILE_DATA'];
    }
    else
    {
      echo '<p>No File</p>';
    }
  }
  else
  {
    echo '<p>Data no longer exist</p>';
  }
}

Semoga tulisan singkat ini dapat memberikan gambaran kepada pembaca yang ingin menyimpan file ke dalam database dan menampilkan data file dari database.

Silahkan juga baca pembahasan dan contoh di link berikut ini:

  1. http://www.devarticles.com/c/a/MySQL/Blobbing-Data-With-PHP-and-MySQL/

  2. http://phplens.com/lens/adodb/docs-oracle.htm

  3. http://forums.oracle.com/forums/thread.jspa?threadID=205149

Penjumlahan jam dan menit di PHP

Beberapa jam yang lalu seorang teman bertanya tentang kode PHP untuk menjumlahkan dua string jam dan menit. Saya coba cari di google tapi tidak ada solusi yang saya temukan. Saya pun menyarankan untuk parsing manual stringnya, di-explode dan dijumlahkan secara terpisah menit dan jamnya. Cara dasar tapi memang bisa dipakai untuk menyelesaikan permasalahan.

Beberapa saat yang lalu tiba-tiba saja terlintas ide untuk menggali lagi kehebatan fungsi strtotime yang ada pada PHP. Hasilnya adalah potongan kode berikut ini

<?php

$time1 = '10:20';
$time2 = '12:40';

$time1_unix = strtotime(date('Y-m-d').' '.$time1.':00');
$time2_unix = strtotime(date('Y-m-d').' '.$time2.':00');

$begin_day_unix = strtotime(date('Y-m-d').' 00:00:00');

$jumlah_time = date('H:i', ($time1_unix + ($time2_unix - $begin_day_unix)));



Dengan kode diatas penjumlahan dua string jam:menit dapat dilakukan dengan mudah. Semoga bermanfaat.


Update: kesalahan ketik diatas sudah diperbaiki :) Maklum ditulisnya malem2 sih...

Kamis, Juli 31, 2008

Tri Duta Suci memang mengecewakan

Saat saya bertanya kepada teman saya ke bengkel mana dia mempercayakan servis motor yamaha miliknya, teman saya itu menyarankan bengkel Sentra Anugrah Motor di Jl. Dipati Ukur, depan STHB. Alasannya seserhana saja, "Pelayanannya lebih baik daripada Tri Duta Suci." Saat itu, saya masih berdomisili di Jl. Puyuh, sehingga bisa melakukan servis berkala I dan II motor saya di Sentra Anugrah.

Pelayanan di Sentra Anugrah memang memuaskan. Ketika saya datang, yang menjaga konter bengkel langsung mencatat motor saya dan menanyakan keluhan yang saya alami dengan motor ini. STNK diberikan kembali kepada saya sebagai bukti pengambilan motor setelah selesai diservis.

Sekarang saya sudah pindah rumah ke daerah Cibaduyut. Kemarin saya hendak menservis di bengkel resmi Yamaha, tetapi bengkel di Taman Kopo Indah ternyata ikut libur. Pagi ini sambil berangkat kerja, saya memutuskan untuk meninggalkan motor di bengkel untuk diservis, sehingga siang hari bisa langsung diambil. Saya memutuskan mencoba servis di Tri Duta Suci karena lokasinya yang dekat dengan kantor.

Pagi hari tadi saya datang ke Tri Duta Suci. Di konter bengkel, saya disambut oleh mbak penjaga konter. Saya menyerahkan buku servis, kunci dan STNK. Si mbak menyuruh saya menunggu. Saya bilang padanya bahwa motor akan saya tinggal disini saja, nanti siang diambil. Si mbak bertanya, "mau diambil jam berapa?" "Jam 12 siang," kata saya. Tidak ada pertanyaan tentang keluhan yang saya alami dengan motor, maupun pencatatan. Saya meminta STNK yang saya serahkan bersama kunci, tetapi kata si mbak, semua ditinggalkan disana saja. Dalam hati saya berpikir, mudah banget ya nanti kalo mau ngambil motor milik orang lain, kan STNK, buku, dan kunci disana semua. Sungguh suatu kelemahan yang sangat fatal.

Siang harinya setelah sholat dzuhur saya langsung ke Tri Duta Suci untuk mengambil motor. Saya berencana makan siang nanti setelah mengambil motor. Sesampainya di bengkel, saya kembali menjumpai mbak penjaga konter yang sama. Saya katakan ingin mengambil motor. Oleh si mbak, saya diminta menunggu karena kasirnya sedang keluar makan siang. "Duh, kenapa ga bilang tadi pagi kalo jam 12 pada istirahat," kata saya dalam hati.

Sayapun menunggu dengan sabar dan tak terasa 45 menit telah berlalu. Perut saya sudah protes dengan hebatnya. Si mbak penjaga itu kayaknya berusaha mencari keberadaan si kasir 'penting' itu. "Kayaknya kasirnya kekenyangan," begitu guraunya kepada saya. "Lucu banget mbak, pengen ketawa perut saya ini," kembali saya berujar dalam hati.

Sayapun menghampiri si mbak sambil bertanya, "Memangnya kasirnya cuma satu ya mbak?" "Iya, sekarang manajemennya digabung dengan showroom. Jadi menyulitkan konsumen sih. Saya sudah berkali-kali bilang agar kalau keluar jangan sampai lewat jam 1. " begitu jawaban si mbak. Si mbak pun memberikan kuitansi (2 lembar) dan KSG III dari buku servis kepada saya, dan menyarankan saya agar menunggu di showroom saja.

Di showroom, ada 2 orang mbak penjaga. Seorang dari mereka bertanya keperluan saya, dan saya jawab hendak bayar servis bengkel. Si mbak menerima kuitansi dan ksg dari saya. Ketika saya memberi uang Rp 50rb, si mbak minta uang pas saja, karena kasirnya lagi keluar. Saya pun bertanya padanya, "kasirnya hanya satu orang ya mbak?" "Iya, mas mau melamar jadi kasir disini?" begitu jawaban si mbak itu. Saya jawab saja, "nggak sih, cuman kalo ada yang sampai masukin ke surat pembaca, bisa sepi nih bengkel," begitu kaya saya. "Kenapa memangnya?" tanya si mbak. "Saya sudah menunggu dari jam 12 tadi. Setidaknya tolong diinformasikan kepada konsumen, " begitu jawaban saya padanya. Si mbak kemudian memberi cap di kuitansi dan KSG, lalu menyerahkan kembali pada saya. Lembar kuitansi hijau disimpan olehnya.

Saya kembali ke si mbak penjaga konter bengkel. Dia malah heran ketika saya sodorkan kembali kuitansi putih dan KSG. "Kok dikembalikan ke saya, " tanyanya kepada saya. "Di sana sudah bayar mbak," kata saya padanya. Si mbak pun akhirnya menyerahkan kunci+STNK dan buku servis pada saya.

Duh, coba kalo yang ambil motor ini bukan saya, apa Tri Duta Suci mau bertanggung jawab? Setidaknya kasi pertanyaan kek, atau coba tiru Sentra Anugrah yang menggunakan STNK sebagai bukti ketika hendak mengambil motor kembali.

Ini merupakan pengalaman saya yang pertama dan terakhir di Tri Duta Suci. Kepada manajemen Tri Duta, mohon lebih selektif dalam menerima dan membina pegawai-pegawai Anda. Kalau bengkel Anda sampai sepi dan bangkrut, kasihan para pekerja Anda yang lain yang telah bekerja dengan baik, tapi harus ikut menderita akibat ulah satu orang yang tidak becus bekerja.

Blogged with the Flock Browser