Google Apps Script for Fun and Profit

Saya suka membaca, buku, artikel, blog, notes dll, untuk blog saya biasa menggunakan google reader dan setelah di shutdown, saya berpindah menggunakan feedly, ada lebih dari seratus sumber berita saya subscribe (meskipun tidak selalu saya baca semua artikelnya). Saya juga senang sekali kalau ada yang mengirimkan artikel-artikel menarik melalui email karena tentu saja pengirim info tersebut telah memilihkan berita atau informasi yang menarik bagi saya. Hal tersebut yang dilakukan oleh salah seorang manager senior di kantor.

Karena beliau relatif sering mengirimkan artikel tersebut, saya berfikir untuk menyimpan artikel-artikel tersebut di google site saya, sehingga saya bisa mengaksesnya sewaktu-waktu dengan mudah. Oleh karena itu saya membuat script sederhana untuk mengambil artikel tersebut dan menyimpannya di google site dengan menggunakan google apps script. Menggunakan google apps script ternyata sangat mudah, berikut script yang saya buat:

/**
 * Retrieves all inbox and post body email from pak Soegi with subject: "fyi" to google sites
 * https://sites.google.com/a/kaskusnetworks.com/hakim/home/articles
 * For more information on using the GMail API, see
 * https://developers.google.com/apps-script/class_gmailapp
 */
function processInbox() {
  Logger.log("start reading inbox");
  // get top 50 inbox (assuming no more than 50 threads within a day)
  // sort it based on first message date, since sometimes old thread goes up because of new message/reply
  // it make sure that only latest message read and posted to google site
  var threads = GmailApp.getInboxThreads(0, 50).sort(function(thread1, thread2){
    return thread2.getMessages()[0].getDate().getTime() - thread1.getMessages()[0].getDate().getTime();
  });
  
  var day_in_miliseconds = 86400000; // 24*60*60*1000
  if (threads.length > 0){
    for (var i = 0; ; i++) {
      // get all messages in a given thread
      var thread = threads[i];
      var firstmessage = thread.getMessages()[0];
      var firstmessagedate = firstmessage.getDate()
      var now = new Date();
      // only check for past 24 hour email
      if ((now.getTime() - firstmessagedate.getTime()) <= day_in_miliseconds){
        var messages = thread.getMessages();
        // log message subject
        var message = messages[0]; // we only care for the first message
        Logger.log(message.getFrom() + " subject: "+ message.getSubject())
        if (message.getSubject().trim() == "fyi" && message.getFrom().indexOf("soegi") > 0){
          var date = message.getDate()
          // post to google sites
          var fyi = "<strong>" + date.toLocaleDateString() + "</strong><br/>"+message.getBody();
          addArticlesToPage(fyi);
        }
      }else{ // outdated message
        break;
      }
    }  
  }
  
};

function addArticlesToPage(fyi){
  var domain = 'kaskusnetworks.com';
  var sitenya = 'hakim';
  var site = SitesApp.getSite(domain, sitenya);
  var page = SitesApp.getPageByUrl("https://sites.google.com/a/kaskusnetworks.com/hakim/home/articles");
  var content = page.getHtmlContent();
  // append content
  content = content.replace("</div></td>","<br/>"+fyi+"</div></td>");
  page.setHtmlContent(content);
}

selanjutnya saya tinggal menentukan trigger yang akan mengeksekusi fungsi tersebut (semcam membuat cron jobs). akhirnya halaman google sites saya akan selalu terupdate dengan link-link informasi menarik yang dikirimkan kepada saya. Dan di akhir pekan, saya bisa membaca semua link-link tersebut dengan santai.

happy scripting :)

Memoization

Memoization

Terinspirasi dari salah seorang kolega di kantor yang berhasil meningkatkan performansi satu bagian di server. Saya ingin menulis tentang memoization. Dalam programming, saat satu fungsi yang kita gunakan membutuhkan proses yang mahal dan dipanggil berulang-ulang, kita bisa menyimpan data hasil perhitungan tersebut untuk kemudian digunakan saat fungsi tersebut dipanggil kembali. Dengan teknik ini, kita bisa menghemat “biaya” operasi fungsi (degnan kata lain performansi program kita meningkat) dengan “ganti rugi” space memory (untuk menyimpan hasil operasi fungsi tersebut). Teknik seperti ini disebut memoization.

Lebih jelasnya, mari kita lihat contoh berikut:

public class Lingkaran{
	private static final int PI = 3.14f;
	private float luas = -1;
	private int radius;

	public void setRadius(float r){
		luas = -1;
		radius = r;
	}
	public float Luas(){
		if (luas < 0){  // kita korbanin biaya buat branching, karena operasi di dalam sini bakal banyak makan resources
			luas = PI*radius*radius; // ini hanya contoh saja
		}
		return luas;
	}
}

tentu saja contoh di atas hanyalah contoh yang sangat sederhana sekali :)

Lookup Table
Salah satu teknik memoization adalah dengan menggunakan lookup table. Saat SMA tentu kita pernah melihat buku table logaritma, yang bisa kita gunakan untuk membantu menghitung nilai logaritma bilangan tertentu dengan cara melihat table logaritma tersebut yang sudah mencatat berbagai perhitungan logaritma bilangan tertentu. Dalam programming, kita juga dapat memanfaatkan table lookup, yang menyimpan data.

misalnya fungsi javascript sederhana ini:

function isPrime(value){
	if (!isPrime.answers) isPrime.answers = {};
	if (isPrime.answers[value] != null){
		return isPrime.answers[value];
	}

	var prime = value != 1;
	for (var i = 2; i < value; i++){
		if (value % i == 0){
			prime = false;
			break;
		}
	}

	return isPrime.answers[value] = prime;
}

tentu saja fungsi pengujian bilangan prima di atas sangat tidak efisien (cek cara lebih efisien di wiki, misalnya dengan metode Sieve of Eratosthenes), tapi bisa kita lihat di contoh kode di atas, setiap kali kita menguji satu bilangan, kita mencatat status bilangan tersebut apakah prima atau tidak dalam satu object. Dan ketika kita menguji kembali bilangan yang sama, kita tidak perlu melakukan pengujian ulang, tapi langsung mengembalikan status yang ada dalam “memo”.

lebih jauh tentang memoization bisa diawali dengan membaca wikipedia berikut: https://en.wikipedia.org/wiki/Memoization

happy coding :)

Indonesia Photo Gallery Gadget

image Alhamdulillah, gadget keduaku akhirnya diupload di google desktop gallery. jadi ceritanya sebagai penduduk indonesia yang baik, saya beberapa waktu yang lalu membuat sebauh gadget / widget sederhana untuk menampilkan foto – foto daerah wisata dan kebudayaan indonesia yang ada di situs my-indonesia.com, tentu saja maksudnya ikutan berpartisipasi dalam proyek pemerintah visit indonesia 2008; mengenai google gadget sendiri, google gadget adalah salah satu bagian dari google desktop, gadget merupakan sebuah plagin dari google desktop.

ok, rasanya saya tidak perlu panjang lebar untuk menjelaskan ini semua, jika ingin mencoba hasil karya saya, anda perlu mendownload google desktop selanjutnya mendownload gadget saya (Indonesia Photo Gallery), dan akhirnya jalankan gadget tersebut; wohoo! anda akan dapat melihat slideshow dari foto – foto beberapa obyek wisata di Indonesia.