Archive | Bahasa Indonesia RSS for this section

Ijin Kabid Informasi dan Publikasi KemDikNas terkait Aplikasi KBBI Reference

Terkait informasi release Aplikasi KBBI Reference Android App yang diposting awal November lalu, penulis sempat mengirim email kepada Kementrian Pendidikan Nasional Indonesia (badan.bahasa[at]kemdiknas.go.id) terkait ijin penggunaan API Aplikasi KBBI Daring (Dalam Jaring) mereka.

Pada dasarnya, email ini dikirim penulis dengan maksud untuk mendapatkan ijin formal mengenai penggunaan logic KBBI pada situs Kemdiknas. Sebagai developer aplikasi yang baik, tentu tidak etis jika kita menggunakan fasilitas buatan pihak lain tanpa ijin. Mereka tentu sudah mengeluarkan effort¬†yang cukup besar (dana, SDM, dkk) untuk menghadirkan KBBI daring tersebut. Pastinya mereka akan senang jika hasil usaha tersebut dapat berguna dan dimaksimalkan kegunaannya oleh banyak pihak. Disini penulis berusaha untuk menghadirkan aplikasi KBBI kepada audiens yang lebih luas, pengguna layanan Mobile Android. Selain itu, tentu penulis “sedikit berharap” agar dapat menjalin kerjasama yang lebih membangun dengan pihak Kementrian Pendidikan Nasional Republik Indonesia ūüôā

nb: aplikasi dapat diunduh pada https://market.android.com/details?id=net.antonrifco.kbbi . Penulis membuka peluang bagi semua pihak untuk bekerja sama dalam mengembangkan fitur-fitur aplikasi. Mohon kontak via email.

Berikut isi pembicaraan dengan  Kabid Informasi dan Publikasi Dra. Wahyu Trihartati, M.Pd.

—–

—– Original Message —–
From: “Anton Rifco” <email>
To: “badan bahasa” <badan.bahasa@kemdiknas.go.id>
Sent: Wednesday, November 9, 2011 10:43:14 PM
Subject: Informasi Publishing Aplikasi Gratis Android KBBI dalam jaringan (daring)

Dengan hormat,

Melalui email ini saya ingin memberitahu dan meminta ijin resmi dari Kemdiknas mengenai dirilisnya aplikasi Android KBBI online atau dalam jaringan (daring).
Aplikasi tersebut dapat diunduh melalui pranala https://market.android.com/details?id=net.antonrifco.kbbi

Sebagai informasi, saya mendevelop aplikasi Android ini dengan tujuan agar pengguna layanan mobile Indonesia dan Asing dapat dengan mudah mengakses Kamus KBBI Daring ciptaan Kemdiknas Indonesia. Aplikasi tersebut dirilis secara gratis, dan terbuka bagi masyarakat umum yang ingin berkontribusi untuk melalui pengayaan fitur.

Sekian pemberitahuan dari saya. Harap maklum.

Terima kasih.

—————————————————————–

Balasan:

On Nov 24, 2011 10:02 PM, “Badan Bahasa” <badan.bahasa@kemdiknas.go.id> wrote:

Yth. Saudara Anton R Susilo

Surat Saudara telah kami terima. Berikut jawaban kami atas pertanyaan Saudara.

Pada dasarnya, semua konten yang kami tampilkan dalam Laman Badan Pengembangan dan Pembinaan Bahasa (Badan Bahasa) bertujuan memberi layanan kepada masyarakat. Untuk itu, kami tidak berkeberatan bahwa Saudara telah membuat aplikasi KBBI android untuk kepentingan yang bersifat nonkomersial. Namun, apabila Saudara memperdagangkannya untuk memperoleh keuntungan, penentuan harga harus seizin Badan Bahasa.

Atas perhatian Saudara, kami ucapkan terima kasih.

Kabid Informasi dan Publikasi,

Dra. Wahyu Trihartati, M.Pd.

————————————————————

Balasan:

2011/11/24 Anton Rifco
Dengan hormat,

Terima kasih atas perhatian dan ijin Kemdiknas.

Saat ini aplikasi tersebut bisa didownload secara gratis, melalui Android Market http://market.android.com/details?id=net.antonrifco.kbbi
dan bersifat Open Source.

Sebagai informasi, saat ini aplikasi masih diusahakan untuk terus dikembangkan, agar bisa diintegrasikan dengan fungsi lainnya (translate, synonim, dkk).

Saran, kritik dan informasi dari Kemdiknas terkait ide pengembangan aplikasi akan sangat berharga bagi evolusi fungsi aplikasi.

Terima kasih

releaseV0.9 KBBI Reference, Android application

Untuk kebutuhan referensi terhadap kata/istilah dalam bahasa Indonesia, aplikasi Android KBBI Reference ini dapat diberdayakan. Aplikasi bisa didownload melalui Android Market.

Saat ini aplikasi sudah bisa melakukan lookup istilah dalam bahasa Indonesia untuk dicari definisinya pada database Kamus Besar Bahasa Indonesia, oleh Departemen Pendidikan Republik Indonesia. Kemudian, aplikasi juga akan mentranslate defisini tersebut ke dalam bahasa Inggris (untuk keperluan referensi silang). Saat ini, translasi ke bahasa Inggris tersebut menggunakan API Microsoft Bing Translate.

Ke depannya, banyak fitur tambahan yang ingin diimplementasi, diantaranya:
1. Saving historical lookup to persistence.
2. Personalisasi translasi ke dalam bahasa pilihan terkonfigurasi.
3. UI enhancement: pilihan default Activity ketika aplikasi startup (Dashboard atau halaman lookup), gesture input, dll.
4. Text to Speech dan Voice Input
5. Reverse lookup, dari bahasa pilihan ditranslate ke bahasa Indonesia, kemudian dicari definisinya pada database KBBI.

Bagi teman-teman yang tertarik untuk berkontribusi / untuk enhancement aplikasi, bisa menghubungi melalui email antonDOTrifcoATgmailDOTcom

yang tersisa dari segelas kopi pahit

Ada yang tersisa dari segelas kopi pahit yang dengan nikmatnya kuseruput malam tadi.

sebuah kesempatan untuk belajar menjadi yang lebih baik. pelajaran bahwa hidup itu sekali-kalinya haruslah mengecewakan.

kopi itu aku minta agar dibuat sangat pekat. saking pekatnya sampai-sampai hitamnya meluruhkan warna putih keramik dari cangkir dan nampannya. aku ingin selalu mengingat bahwa hidup bisa sekalinya terlalu pekat hingga kau tidak menyadari bahwa selalu ada makna di baliknya. sebuah kafein yang tanpa kita sadari selalu membantu kita menjernihkan pikiran dari penatnya siang tadi.

juga kopi itu dibuat sangat panas sampai aku gemetar memegang sendok kecil yang seolah-olah tertanam pada kepekatan kopi. hingga aku bisa terus yakin bahwa akan selalu ada zat yang meluruskan kita pada jalan setapak yang tidak berbelok.

malam itu sangat gelap, dan kopi ini sangat pekat. apa yang bisa lebih buruk daripada itu.

dari semua sahabat, hanya ada dia yang bersedia menemaniku untuk menghabiskan kopi ini malam tadi di kedai itu. secangkir kopi yang kupesan sejak tahun lalu. aku memesannya sejak lama, dengan harapan agar aku mempunyai waktu yang cukup untuk membuat kebodohan baru yang perlu diceritakan kepadanya.

rupanya banyak hal yang telah aku lakukan setahun ini. tidak semuanya kuceritakan. bahkan dari semua cerita yang kusampaikan, semuanya belum pernah benar-benar kualami. kami hanya sepakat untuk menceritakan hal-hal bodoh yang mungkin kita jalani di masa nanti. tindakan nekat sempurna yang hanya akan kita lakukan dengan pertimbangan satu atau dua detik. sesuatu yang benar-benar menarik untuk diceritakan pada anak-anak kecil yang kelak memanggilku dengan sebutan kakek. bukan cerita picisan mengenai bagaimana seseorang berjuang untuk sekedar mencari kehidupan hari esok. karena pada dasarnya semua orang telah berjuang.

tidak terasa panjangnya cerita kita telah memberikan energi pada sang mentari untuk membebani semua orang dengan satu cerita lagi yang harus dijalani. kisah menyebalkan yang menuntut kita untuk menjalani proses menjadi individu yang lebih baik dari seseorang yang menyeruput kopi pahit tadi malam.

dari semuanya, ada satu hal yang pasti, ketika waktu berjalan tidak sesuai dengan harapan, akan selalu ada segelas kopi pahit yang menyimpan kehangatannya untuk menemani kita mengalir sejalan dengan kenyataan.

How to send MMS using SOAP MM7

Here’s an article describing how to implement MM7 connection to your service provider’s MMS center.

Perhaps for the start, I would like to tell the history of MM7 implementation. At first most vendors implement MM7 connection to send MMS content using their own proprietary library. E.g. One of biggest vendor uses PAP (Push Application Protocol) to send standard MMS content from VAS App to the subscriber. Basically it’s built on standard MIME Message class.

Good news, nowadays many vendor has dealt to implement their MM7 connection from VAS App using standard SOAP connection. Moreover, under this SOAP implementation, they can support SMIL class message. It’s a standard Markup Language to implement layouting in MMS content delivery. Also, using this SMIL implementation, we can present multi pages MMS that showed one after another with predefined duration.

Here’s the example of SMIL tag:

<smil xmlns=”http://www.w3.org/2001/SMIL20/Language”&gt;

<head>

<layout>¬†¬† ¬† ¬†<root-layout width=”160″ height=”120″/>

<region id=”upper” top=”0″ left=”0″ />¬†¬† ¬† ¬†<region id=”lower” top=”100″ left=”0″ />

</layout>

</head>

<body>

<par dur=”3s”>¬†¬† ¬† ¬†<text region=”lower” src=”text0.txt” />¬†¬† ¬† ¬†<img region=”upper” src=”zzz.JPG” />¬†¬† ¬† ¬†<audio src=”01000000478.mid” />¬†¬† ¬†</par>

<par dur=”5s”>¬†¬† ¬† ¬†<text region=”lower” src=”text3.txt” />¬†¬† ¬† ¬†<img region=”upper” src=”zzz.JPG” />¬†¬† ¬† ¬†<audio src=”01000000478.mid” />¬†¬† ¬†</par>

</body></smil>

For the art of software programming, I will put my example code here in Java from scratch. Actually you can code SOAP Message in Java using SAAJ standard library.

At first you need to make sure that you have variables that define the connection to the MMSC. They are MMSC IP, Port, VASID, VASPID, and Password. It can be defined from file configuration.

String mmsc_ip = Utility.getConfiguration(“MmscSoap.ip”); int mmsc_port = Integer.parseInt(Utility.getConfiguration(“MmscSoap.port”)); String mmsc_pwd = Utility.getConfiguration(“MmscSoap.pwd”); String mmsc_vaspid = Utility.getConfiguration(“MmscSoap.vaspid”); String mmsc_vasid = Utility.getConfiguration(“MmscSoap.vasid”);

Basically, SOAP connection is a like a HTTP socket connection using POST method. So, we need to define the HTTP header:

String header = “POST /vas_soap HTTP/1.1\n” +

“Host: “+mmsc_ip+”:”+mmsc_port+”\n” +

“Authorization: Basic “+toBASE64(mmsc_pwd,0)+”\n” +

“User-Agent: mm7submit/0.1\n” + ¬† “Content-Type: multipart/related; boundary=\”–_=_NextPart_21B2_1EE0_E97.2593\”; type=\”text/xml\”; start=\”<mm7submit@localhost>\”\n” +

“Content-Length: “+data.length()+”\n” +

“Accept: */*\n” +

“SOAPAction: \”\”\n\n”;

You can specify either the connection is using HTTP/1.1 or HTTP/1.0. Also you can add more HTTP header there, depends on the server’s need.

MMS contents are simply the texts, multimedia contents (audio, video, and picture), and SMIL tags that defined how the contents presented. Multimedia contents are supposed to be sent as format Base64 Encoding. So, we’re going to put

import sun.misc.BASE64Encoder;

in top of the file.

For the contents’ location, this tutorial will search the contents based on the URL specified in the SMIL tags. Normally, SMIL tag should not be filled with URL. But, to simplify the solution, this code will accept SMIL with URL. Then it will string-process the SMIL to extracts the URL of the contents. Then, will put the content name based on the hashcode of the URL specified.

<img region=”upper” src=”http://www.google.com/images/logos/ps_logo2.png” />

will be replaced with:

<img region=”upper” src=”c63893e3754e335896165ed94d6ce67e” />

The code will differs multimedia into three different types (audio, video, and image). Then it will assume the Content-Type based on the suffix of the URL path.

The code will string-process the smil to get contents’ URL:

smil = URLDecoder.decode(smil);

Vector<String> gambars = new Vector<String>();

Pattern p = Pattern.compile( “<img[ *]region=.[^<>’\”]*.[ *]src=[‘\”]([^’\”<>]*)[‘\”][ *]/>”, ¬†Pattern.DOTALL);
Matcher matcher = p.matcher(smil);

while (matcher.find()) {

String temp = matcher.group(1);

if(!gambars.contains(temp))

gambars.add(temp);

}

Vector<String> suaras = new Vector<String>();

p = Pattern.compile(“<audio[ *]src=[‘\”]([^’\”<>]*)[‘\”][ *]/>”, Pattern.DOTALL);
matcher = p.matcher(smil);

while (matcher.find()) {

String temp = matcher.group(1);

if(!suaras.contains(temp))

suaras.add(temp);

}

Vector<String> videos = new Vector<String>();

p = Pattern.compile(“<video[ *]src=[‘\”]([^’\”<>]*)[‘\”][ *]/>”, Pattern.DOTALL);
matcher = p.matcher(smil);

while (matcher.find()) {

String temp = matcher.group(1);

if(!videos.contains(temp))

videos.add(temp);

}

And here’s how we build the main HTTP body:

String data = “”+ “—-_=_NextPart_21B2_1EE0_E97.2593\n” +

“Content-Type: application/xml\n” +

“Content-ID: <mm7submit@localhost>\n” + “\n” +

“<?xml version=\”1.0\” encoding=\”UTF-8\”?>\n” +

“<SOAP-ENV:Envelope xmlns:SOAP-ENV=\”http://schemas.xmlsoap.org/soap/envelope/\” xmlns=\”http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-2\”>\n” +

“<SOAP-ENV:Header>\n” +

” <TransactionID SOAP-ENV:mustUnderstand=\”1\”>vas00001</TransactionID>\n” +

“</SOAP-ENV:Header>\n” +

“<SOAP-ENV:Body>\n” +

“<SubmitReq>\n” +

“<MM7Version>5.3.0</MM7Version>\n” +

“<SenderIdentification>\n” +

” <VASPID>”+mmsc_vaspid+”</VASPID>\n” +

” <VASID>”+mmsc_vasid+”</VASID>\n” +

” <SenderAddress><Number>”+ sender +”</Number></SenderAddress>\n” +

” </SenderIdentification>\n” +

” <Recipients>\n” +

” <To><Number>”+to+”</Number></To>\n” +

” </Recipients>\n” + ” <MessageClass>Informational</MessageClass>\n” +

” <DeliveryReport>false</DeliveryReport>\n” +

” <ReadReply>false</ReadReply>\n” +

” <Priority>Normal</Priority>\n” +

” <Subject>”+subject+”</Subject>\n” +

” <ChargedParty>Sender</ChargedParty>\n” +

” <Content href=\”cid:content@localhost\” allowAdaptations=\”true\”/>\n” +

“</SubmitReq>\n” + “</SOAP-ENV:Body>\n” +

“</SOAP-ENV:Envelope>\n\n” + “—-_=_NextPart_21B2_1EE0_E97.2593\n” +

“Content-Type: multipart/mixed; boundary=\”—-_=_NextPart_220A_232_2517.E38\”\n” +

“Content-ID: <content@localhost>\n” + “\n”;

String texts[] = text.split(“<next/>”);

for(int g = 0; g < texts.length; g++){

data+=”——_=_NextPart_220A_232_2517.E38\n” +

“Content-Type: text/plain; charset=\”us-ascii\”; Name=text”+g+”.txt\n” +

“Content-ID: <text”+g+”.txt>\n” +

“Content-Location: text”+g+”.txt\n\n” +

texts[g]+”\n” + “\n”;

}
String gambar_name[] = null;

int max_depth = 0;

if(gambars != null){

Log.getLogger().debug(“Parse image…”);

gambar_name = new String[gambars.size()];

for(int g = 0; g < gambars.size(); g++){

if(max_depth == g) max_depth++;

URL sourceURL1 = null;

try {

String url = gambars.get(g).replaceAll(” ” , “+”);

sourceURL1 = new URL(url);

byte[] byteArray = null;

HttpClient http = new HttpClient();

http.getParams().setSoTimeout(timeout);

if (proxyHost != null && proxyPort != null) {

Log.getLogger().info(“Using proxy = ” + proxyHost + “:” + proxyPort);

http.getHostConfiguration().setProxy(proxyHost, Integer.parseInt(proxyPort));

}

HttpMethod method = new GetMethod(url);

http.getParams().setParameter(“http.socket.timeout”, timeout);

http.getParams().setParameter(“http.connection.timeout”, timeout);

method.getParams().setParameter(“http.socket.timeout”, timeout);

method.getParams().setParameter(“http.connection.timeout”, timeout);

try {

int statusCode = http.executeMethod(method);

if (statusCode != HttpStatus.SC_OK && statusCode != 202) {

byteArray = null; Log.getLogger().debug(“Status HTTP:”+ statusCode);

} else { byteArray = method.getResponseBody(); }

} catch (Exception e) { Log.getLogger().error(“Error in httpGet”, e); byteArray = null; }

finally { method.releaseConnection(); }

String filename = sourceURL1.getFile();

BASE64Encoder encoder = new BASE64Encoder();

if(filename.contains(“/”)) filename = filename.substring(filename.lastIndexOf(“/”)+1);

gambar_name[g] = Integer.toString(filename.hashCode());

smil = replace(smil, url, gambar_name[g]);

String format = filename.substring(filename.lastIndexOf(“.”)).toLowerCase();

String type = “image/png”;

if(format.equals(“.gif”)) type = “image/gif”;

else if(format.equals(“.jpg”) || format.equals(“.jpeg”)) type = “image/jpeg”;

else if(format.equals(“.png”)) type = “image/png”;

else if(format.equals(“.tiff”)) type = “image/tiff”;

data+=”——_=_NextPart_220A_232_2517.E38\n” +

“Content-Type: “+type+”;

Name=”+gambar_name[g]+”\n” +

“Content-Transfer-Encoding: base64\n” +

“Content-ID: <“+gambar_name[g]+”>\n” +

“Content-Location: “+gambar_name[g]+”\n\n” +

encoder.encode(byteArray)+”\n” + “\n”;

} catch (Exception e) {// TODO Auto-generated catch block e.printStackTrace(); }

}

}

String suara_name[] = null;

if(suaras != null){

suara_name = new String[suaras.size()];

for(int g = 0; g < suaras.size(); g++){

if(max_depth == g) max_depth++;

URL sourceURL1 = null;

try {

String url = suaras.get(g).replaceAll(” ” , “+”);

sourceURL1 = new URL(url);

byte[] byteArray = null;

HttpClient http = new HttpClient();

http.getParams().setSoTimeout(timeout);

if (proxyHost != null && proxyPort != null) {

Log.getLogger().info(“Using proxy = ” + proxyHost + “:” + proxyPort);

http.getHostConfiguration().setProxy(proxyHost, Integer.parseInt(proxyPort));

}

HttpMethod method = new GetMethod(url);

http.getParams().setParameter(“http.socket.timeout”, timeout);

http.getParams().setParameter(“http.connection.timeout”, timeout);

method.getParams().setParameter(“http.socket.timeout”, timeout);

method.getParams().setParameter(“http.connection.timeout”, timeout);

try {

int statusCode = http.executeMethod(method);

if (statusCode != HttpStatus.SC_OK && statusCode != 202) {

byteArray = null;

Log.getLogger().debug(“Status HTTP:”+ statusCode);

} else { byteArray = method.getResponseBody(); }

} catch (Exception e) { Log.getLogger().error(“Error in httpGet”, e); byteArray = null; }

finally { method.releaseConnection(); }

String filename = sourceURL1.getFile();

BASE64Encoder encoder = new BASE64Encoder();

if(filename.contains(“/”)) filename = filename.substring(filename.lastIndexOf(“/”)+1);

suara_name[g] = Integer.toString(filename.hashCode());

smil = replace(smil, suaras.get(g), suara_name[g]);

String format = filename.substring(filename.lastIndexOf(“.”)).toLowerCase();

String type = “audio/wav”;

if(format.equals(“.wav”)) type = “audio/wav”;

else if(format.equals(“.mid”) || format.equals(“.midi”)) type = “audio/midi”;

else if(format.equals(“.mp3”)) type = “audio/mp3”;

else if(format.equals(“.3gp”)) type = “audio/3gpp”;

else if(format.equals(“.aac”)) type = “audio/aac”;

else if(format.equals(“.amr”)) type = “audio/amr”;

else if(format.equals(“.amr-wb”)) type = “audio/amr-wb”;

else if(format.equals(“.mpeg”) || format.equals(“.mpg”)) type = “audio/mpeg”;

else if(format.equals(“.mp4”)) type = “audio/mp4”;

else if(format.equals(“.rmv”) || format.equals(“.rmvb”)) type = “audio/rmv”;

else continue;

data+=”——_=_NextPart_220A_232_2517.E38\n” +

“Content-Type: “+type+”; Name=”+filename+”\n” +

“Content-Transfer-Encoding: base64\n” +

“Content-ID: <“+filename+”>\n” +

“Content-Location: “+filename+”\n\n” +

encoder.encode(byteArray)+”\n” + “\n”;

} catch (MalformedURLException e) {// TODO Auto-generated catch block e.printStackTrace(); }

catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }

String video_name[] = null;

if(videos != null) {

video_name = new String[videos.size()];

for(int g = 0; g < videos.size(); g++) {

if(max_depth == g) max_depth++;

URL sourceURL1 = null;

try {

String url = videos.get(g).replaceAll(” ” , “+”);

sourceURL1 = new URL(url);

byte[] byteArray = null;

HttpClient http = new HttpClient();

http.getParams().setSoTimeout(timeout);

if (proxyHost != null && proxyPort != null) {

Log.getLogger().info(“Using proxy = ” + proxyHost + “:” + proxyPort);

http.getHostConfiguration().setProxy(proxyHost, Integer.parseInt(proxyPort));

}

HttpMethod method = new GetMethod(url);

http.getParams().setParameter(“http.socket.timeout”, timeout);

http.getParams().setParameter(“http.connection.timeout”, timeout);

method.getParams().setParameter(“http.socket.timeout”, timeout);

method.getParams().setParameter(“http.connection.timeout”, timeout);

try {

int statusCode = http.executeMethod(method);

if (statusCode != HttpStatus.SC_OK && statusCode != 202) {

byteArray = null;

Log.getLogger().debug(“Status HTTP:”+ statusCode);

} else { byteArray = method.getResponseBody(); }

}

catch (Exception e) { Log.getLogger().error(“Error in httpGet”, e); byteArray = null; }

finally { method.releaseConnection(); }

String filename = sourceURL1.getFile();

BASE64Encoder encoder = new BASE64Encoder();

if(filename.contains(“/”)) filename = filename.substring(filename.lastIndexOf(“/”)+1);

video_name[g] = Integer.toString(filename.hashCode());

smil = replace(smil, videos.get(g), video_name[g]);

String format = filename.substring(filename.lastIndexOf(“.”)).toLowerCase();

String type = “video/mpeg”;

if(format.equals(“mpeg”) || format.equals(“mpg”)) type = “video/mpeg”;

else if(format.equals(“.3gp”) || format.equals(“.3gpp”)) type = “video/3gpp”;

else if(format.equals(“.mp4”)) type = “video/mp4”;

else if(format.equals(“.rmv”) || format.equals(“.rmvb”)) type = “video/rmv”;

else continue;

data+=”——_=_NextPart_220A_232_2517.E38\n” +

“Content-Type: “+type+”; Name=”+filename+”\n” +

“Content-Transfer-Encoding: base64\n” +

“Content-ID: <“+filename+”>\n” +

“Content-Location: “+filename+”\n\n” +

encoder.encode(byteArray)+”\n” + “\n”;

} catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); }

catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }

}

}

if(use_smil != null && !use_smil.equals(“”) && !use_smil.equals(“false”)) {

if(use_smil.toLowerCase().equals(“default”)){

smil = “<smil><head><layout><root-layout/><region id=\”upper\” top=\”0\” left=\”0\” /><region id=\”lower\” top=\”100\” left=\”0\” /><region id=\”lowest\” top=\”200\” left=\”0\” /></layout></head><body>”;

for(int g = 0; g < max_depth; g++) {

smil += “<par dur=\”3s\”>”;

if(g < texts.length) smil += “<text region=\”lower\” src=\”text”+g+”.txt\” />”;

if(gambar_name != null && g < gambar_name.length) smil += “<img region=\”upper\” src=\””+gambar_name[g]+”\” />”;

if(video_name != null && g < video_name.length) smil += “<video region=\”lowest\” src=”+video_name[g]+” />”;

if(suara_name != null && g < suara_name.length) smil += “<audio src=”+suara_name[g]+” />”;

smil += “</par>”;

}

smil += “</body></smil>”;

}

data += “——_=_NextPart_220A_232_2517.E38\n” +

“Content-Type: application/smil; charset=\”us-ascii\”; Name=smil4.smil\n” +

“Content-ID: <smil4.smil>\n” +

“Content-Location: smil4.smil\n” + “\n” +

“<?xml version=\”1.0\” encoding=\”utf-8\”?>” +

“<!DOCTYPE smil PUBLIC \”-//3GPP//DTD SMIL rel5//EN\” \”http://www.3gpp.org/SMIL20/PSS5\”>” + smil + “\n”;

}

data += “——_=_NextPart_220A_232_2517.E38–\n” + “—-_=_NextPart_21B2_1EE0_E97.2593–\n\n”;

Finally, here’s the code to submit the header + contents (data) to the MMSC using HTTP Socket SOAP:

String dat;

try {

Socket so = new Socket(mmsc_ip, mmsc_port);

BufferedOutputStream bos = new BufferedOutputStream(so.getOutputStream());

String msg = header + data;

BufferedReader br2 = new BufferedReader(new InputStreamReader(so.getInputStream()));

bos.write(msg.getBytes());

bos.flush();

dat = “”;

Log.getLogger().debug(“MmsSOAP request :”+msg);

String temp;

while((temp = br2.readLine()) != null){

dat += temp;

}

so.close();

try {

String a = dat.substring(dat.indexOf(“<StatusCode>”) + 12, dat.indexOf(“</StatusCode>”));

Log.getLogger().info(“MmsSOAP response :”+a);

ret = Integer.parseInt(a);

} catch (Exception e) {  // TODO Auto-generated catch block  ret = -9;  e.printStackTrace();  } }

catch (UnknownHostException e1) { // TODO Auto-generated catch block e1.printStackTrace(); }

catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); }

For the response, normally MMSC will reply response String 1000 as Success.

Difference between MySQL’s InnoDB and MyISAM

MySQL has two primary storange engines: MyISAM and InnoDB. Each has its own performance characteristics and considerations. In the broadest sense MyISAM is good for read-heavy data and InnoDB is good for write-heavy data, though there are cases where the opposite is true. The biggest gotcha is how the two differ with respect to the COUNT function.

ISAM = Indexed Sequential Access Method, while InnoDB is named after the engine’s creator Innobase Oy

MyISAM keeps an internal cache of table meta-data like the number of rows. This means that, generally, COUNT(*) incurs no additional cost for a well-structured query. InnoDB, however, has no such cache. For a concrete example, let’s say we’re trying to paginate a query. If you have a query SELECT * FROM users LIMIT 5,10, let’s say, running SELECT COUNT(*) FROM users LIMIT 5,10 is essentially free with MyISAM but takes the same amount of time as the first query with InnoDB. MySQL has a SQL_CALC_FOUND_ROWS option which tells InnoDB to calculate the number of rows as it runs the query, which can then be retreived by executing SELECT FOUND_ROWS(). This is very MySQL-specific, but can be necessary in certain situations, particularly if you use InnoDB for its other features (e.g., row-level locking, stored procedures, etc.).

======= BAHASA INDONESIA ========

MySQL memiliki dua mesin storange utama: MyISAM dan InnoDB. Masing-masing memiliki karakteristik performa dan pertimbangan. Dalam arti yang luas MyISAM baik untuk membaca-data (red) dan InnoDB baik untuk menulis data (write), meskipun ada kasus dimana kebalikannya yang benar. Perbedaan utama adalah bagaimana keduanya berbeda dalam penanganan fungsi COUNT.

ISAM = Indexed Sequential Metode akses, sedangkan InnoDB ini dinamakan berdasarkan penciptanya : Innobase Oy

MyISAM menyimpan cache internal tabel meta-data seperti jumlah baris. Ini berarti bahwa, pada umumnya, COUNT (*) berlangsung tanpa biaya tambahan untuk query yang terstruktur dengan baik. InnoDB, bagaimanapun, tidak memiliki cache tersebut. Untuk contoh konkret, mari kita mengatakan bahwa kita mencoba untuk penomoran pd halaman table (pagination). Jika Anda memiliki pertanyaan SELECT * FROM users LIMIT 5,10, katakanlah, menjalankan SELECT COUNT (*) FROM users LIMIT 5,10 pada dasarnya gratis dengan MyISAM tapi mengambil jumlah waktu yang sama sebagai permintaan pertama dengan InnoDB. MySQL memiliki opsi  SQL_CALC_FOUND_ROWS pada InnoDB untuk menghitung jumlah baris seperti menjalankan permintaan, yang kemudian dapat retreived dengan mengeksekusi SELECT FOUND_ROWS (). Hal ini sangat MySQL-spesifik, tetapi dapat diperlukan dalam situasi tertentu, terutama jika Anda menggunakan InnoDB untuk fitur lainnya (misalnya, tingkat baris penguncian, stored procedure, dll).

Twitter status update via curl

Sometimes,,you just need to waste your time just to sending status update to your twitter.

Here’s my suggestion to make your wasting time more wasted :),, by sending twitter status update via curl in bash scripting environment.

vi some-file.sh, and write this bunch of code :

#!/bin/bash
/usr/local/bin/curl --basic --proxy 10.2.249.250:8080 --user $1:$2 --data status="$3" twitter.com/statuses/update.xml

Then save the file using (:wq!)
give chmod +x some-file.sh to your script
Here you can call your script using :
./some-file.sh username passwd "your status"

I recommend to use (“) in your status,,,so that the script can detect that everything in between ” is your status..

have fun !

Front End Logging (tail -f stuff)

Entering a new coding environment (working in a national company), I’ve got several things learned.

One of the important is that I have to take care of every logging activities. It means that people needs me to write any transaction (success, fail, or error) to a flat file.

After my application’s been launching live, the “operation people” can check the log file for any transaction activities using unix command :

tail -f <log_file>

hmmmm…

Rather than supply them with backend checking, I’d prefer to make it (checking log file) into frontend using php.

Here’s the code I scratch to “tail” the log file in FrontEnd :

<html>
<head>
<script language="javascript">
setInterval ( "window.scrollBy(0,100)", 5 );
</script>
</head>
<body>
<a href="http://localhost/tesapps">Click</a>
<?
if(!empty($_GET))
{
$page = $_GET[log]; //supply this GET variable with path to log file
system("tail -f $page");
}
else
echo "<h1>Please provide log file to read !</h1>";
?>
</body>
</html>

With this code, I can simulate tail activities in web browser

nice, huh? ūüôā