#go
90 catatan
Wed, 22 Jan 2020 4:17 pm
Sempat gagal Create Tulisan gara-gara mengubah struct Blog, solusinya insert tidak lagi menggunakan Blog tapi langsung ke Bson.M{} object saja.

#webkoe #go #mgo
Thu, 24 May 2018 3:51 pm
Fitur web framework iris sepertinya lebih lengkap dibandingkan gorilla. Dari segi performa? klaimnya iris sih "The fastest backend web framework for Go". #project #go #iris-framework #gorilla-toolkit
Mon, 5 Sep 2016 12:29 pm
Bersiap mengawinkan webkoe.net dan webkoe.id, kini dengan #go sebagai webserver, mengingat #go sudah bisa SSL dan secara performa tidak beda jauh dengan #nginx... Websocket server wss sejauh ini berjalan lancar, semoga demikian seterusnya. Aamien... #webkoe
Sun, 4 Sep 2016 6:58 am
Back to standalone #go, without #nginx @webkoe.id #webkoe
Sun, 4 Sep 2016 5:57 am
Ternyata #go bisa melayani SSL sendiri, tanpa #nginx. Percobaan ini bermula saat protokol ws yang ditolak oleh https://webkoe.id, setelah wss berhasil dicreate, tinggal masalahnya sekarang "origin not allowed", wss tidak akan memproses request dari origin/alamat yang berbeda. Dalam hal ini originnya adalah webkoe.id, dan server wss ada di webkoe.net:99, solusinya adalah memasukkan layanan wss ke webkoe.id. Masalah berikutnya timbul, karena webkoe.id bukan murni, dia sebenarnya hanya proxy pass nginx ke localhost. Rumit? memang ... #webkoe
Sun, 26 Jun 2016 11:17 pm
Webkoe.net dan webkansaja.com sudah bisa dihandle SSL, juga routingnya lewat #go. Sekarang tinggal menyembunyikan port beckend-nya (88). #webkoe
Sat, 28 May 2016 9:06 pm
Kemudahan #gvm nya #go ternyata ada juga di #python. Dengan #conda ... untuk switch ke environment yang berbeda tinggal :
1. Create Environment
    conda create --name snakes python=3
2. Aktifkan dengan
    activate snakes
#nice
Fri, 22 Apr 2016 11:03 am
Instalasi di #windows :
- Windows 10
- Go versi 1.5
- Git

Pastikan Go berjalan lancar, terutama untuk menjalankan perintah "go get" ... :)

1. Install gomobile dengan perintah
    go get golang.org/x/mobile/cmd/gomobile
    Keterangan :
    - proses ini akan menghasilkan gomobile.exe yang akan tersimpan di $GOPATH\bin
    - di windows, file exe ini tidak bisa langsung dijalankan secara global
    - jadi, harus diregister dulu ke environment variable-nya windows
    - kalo ngga mau capek ya copy aja ke folder project, hehe.

3. Pastikan command "gomobile" berjalan lancar jaya
2. Masuk ke folder yang ditentukan (bebas)
3. Lalu jalankan perintah "gomobile init", it might take a few minutes ... or hours ? T_T
#go #golang #gomobile #android #go_andoid_tutor1_firstlook
Tue, 23 Feb 2016 1:42 pm
Alhamdulillah berhasil meng-konek-kan golang ke oracle, pake driver "github.com/mattn/go-oci8". Lika liku instalasi di Ubuntu 14 lumayan berkelok. Tapi dengan mengikuti step by stepnya di README.md sebenarnya cukup. Memang benar, yang tricky ada dibagian setting oci8.pc nya .... tapi dengan mengikuti setiap error yang ada, akhirnya bisa juga. :) #go #oracle #alhamdulillah #nice
Sat, 13 Feb 2016 11:16 pm
Post from #go desktop app ... :) #nice
Mon, 11 Jan 2016 6:43 pm
Hari ini mulai nyoba workernya #go ... digunakan untuk word dan sentence count, pekerja lepas ini.
Sat, 2 Jan 2016 7:33 am
Iterate interface{} #golang yang menjadi momok selama ini akhirnya terpecahkan. T_T #alhamdulillah yah ... ternyata solusinya simple, jika ada error seperti ini
script .go
for k2, v2 := range v1 {
    fmt.Println(k2)
    fmt.Println(v2)
}
error :
.\retrieve_mongo.go:92: cannot range over v1 (type interface {})
Maka tinggal diubah seperti ini saja (type assertion) :
script .go
for k2, v2 := range v1.(bson.M) {
    fmt.Println(k2)
    fmt.Println(v2)
}
Works like a charm .... #enlightenment #go
Sat, 14 Nov 2015 10:00 pm
#taganomali #go #golang
Sat, 14 Nov 2015 9:59 pm
http://marcio.io/2015/07/handling-1-million-requests-per-minute-with-golang/ #go
Thu, 8 Oct 2015 12:20 am
Go versi 1.5 secara default memakai max processor sebanyak yang dimiliki system, sedangkan versi sebelumnya default max processornya 1 saja. Jadi dengan versi baru ini ga perlu repot menset var, sudah otomatis. Instalasi dan switch dari satu versi ke versi lainnya sangat dimudahkan dengan GVM. Jadi serahkan semuanya ke GVM saja. Semuanga tentang instalasi dan versioning go lah, kalo semuanya yang sebenarnya serahkan pada Yang Maha Kuasa dong. #nice #go
Thu, 8 Oct 2015 12:10 am
Install go1.5 di #webkoe dengan #gvm.
- gvm use go1.4 
- export GOROOT_BOOTSTRAP=$GOROOT 
- gvm install go1.5
#go
Sun, 27 Sep 2015 1:03 pm
Impian ane berikutnya, menerjemahkan struktur DNA dengan #go. #hahaha #nice
Sun, 27 Sep 2015 12:46 pm
GO dominate next decade #go
Fri, 25 Sep 2015 7:25 pm
Surat masuk di server 222 ane kembalikan ke laptop lagi developnya, untuk kemudahan. Disamping juga uji coba portabilitasnya, lumayan portable, tinggal sesuaikan file config dan hardedit di file config.go, develop terbaru sudah mengeliminir hardedit dengan memindahkan ke args[0]. Jadi perintah untuk menjalankannya "server.exe fileconfig.json". Query like dengan bson.regex juga running smoothly, #alhamdulillah, padahal bagian inilah yang sebelumnya membuat ane lumayan stuck. Berikutnya sort() diputuskan untuk descending berdasarkan waktu created saja, tidak perlu memperhitungkan tag, untuk meningkatkan performa search. Mungkin dengan menaikkan waktu create ke level 0 bisa menaikkan performa juga. Selama ini created time hanya ada di level 1, tag dan history. #project #go #mongodb
Wed, 23 Sep 2015 4:30 pm
Mau nyoba #flask #python, tapi ga jadi ... performanya ga lebih bagus dibandingkan #go
Thu, 16 Jul 2015 4:35 am
Dari kemaren sore, sampe dini hari ini dipusingkan
sama arraynya #go. Bentuk seperti ini : 

[
   [ {"title":"OK"} , {"title":"WELL"} ]
] 

tidak bisa langsung dikonsumsi sama contoh script 
di #ebook nya #addyosmani. 

Yang diinginkan adalah bentuk 2 objectnya 
langsung (up 1 level) yaitu :

[ {"title":"OK"} , {"title":"WELL"} ]

#problemsolve nya sementara ini di #go adalah,
mengubah type struct ke type string
#project
Sun, 5 Jul 2015 2:14 pm
Ganti aki,ban luar belakang, service dan ganti kampas rem belakang shogun tadi pagi sampe jam 12 siang tadi di bengkel sebelah ponsel teluk dalam (seberang ayam panggang langganan, samping lp3i). Habis dari situ kujuk-kujuk nyari penjilidan spiral; mau njilid print2an #ebook #go hasil ngeprint di kantor, berturut-turut : fotokopi rekomendasi #ayang di seberang suzuki s.parman tutup, trus yang di kayutangi juga tutup, fotokopi samping uniska hanya menjilid dengan lakban, fotokopi uniskanya tutup, trus fotokopi depan gang stikes hanya terima lakban juga. #alhamdulillah akhirnya dapat fotokopian yang bisa njilid spiral, berlokasi sebelum lampu merah s.parman kalo arah kayu tangi mau ke sabilal, hasilnya bagus, 275 lembar cuman 20 ribu. #sabtuminggu
Wed, 6 May 2015 12:31 am
Sudah nyoba masang di windows 7 32 ,... #go #project running smoothly ... berarti memang komputer 123 yang bermasalah #fyuuh
Mon, 4 May 2015 5:31 pm
Nyoba compile ke windows 32 bit, semua berjalan lancar, kecuali CSS external yang tidak terload ... #error #go #project

Padahal di 64 lancar jaya ...

Issue yang mirip di stackoverflow
Mon, 4 May 2015 4:22 pm
Prepare to surat keluar #project #go
Mon, 4 May 2015 3:24 pm
#fyuuh ribet sekali mau compile #go lintas platform, compile di mesin mawon wes ... xD
Mon, 4 May 2015 10:03 am
Ternyata go compiler bisa mengcompile lintas OS dan ARCH (arsitektur prosessor, 32 atau 64 bit). GO di komputer ane bermasalah saat akan melakukan kompilasi lintas OS dan ARCH, ini nyoba install ulang GO, dari sourcenya langsung, untuk itu perlu compiler gcc Petunjuknya
#go #project
Fri, 1 May 2015 3:15 pm
Ternyata #go bisa dibikin dengan multiple package main, tanpa harus import ... tapi saat compile harus dengan perintah build.
Misal saat ini saya sedang ada di folder Chat.
Isi foldernya :
/Chat :
- main.go    = package main
- client.go  = package main
- room.go    = package main

dengan command berikut :
go build -o chat.exe

akan menghasilkan file chat.exe yang ready, hasilnya :

/Chat :
- main.go
- client.go
- room.go
- chat.exe   = Hasilnya

catatan :
"chat.exe" boleh diisi dengan nama apapun.
Hasilnya nanti akan menjadi binary/executable


Wed, 29 Apr 2015 6:27 pm
Pindah semua variable di config.go ke file .json , sementara ini path dipakem ke c:\DWConf\config.json, berikutnya mungkin bisa dimasukkan ke argument command line saja #project #go
package config

import(
	"encoding/json"
	"os"
	"fmt"
)

var (

    // Path
    // TemplatePath      = "D:\\PROJECTS\\GO-APP\\sms.0.01\\templates\\"
    // PublicPath		  = "D:\\PROJECTS\\GO-APP\\sms.0.01\\public\\"
    UploadPath		  = "D:\\PROJECTS\\GO-APP\\sms.0.01\\public\\files\\"
    PDFPath			  = "D:\\PROJECTS\\GO-APP\\sms.0.01\\public\\pdf\\"
    ImagesLogoPath 	  = "D:\\PROJECTS\\GO-APP\\sms.0.01\\public\\images\\depkeu.png" // PDF Generator | logo depkeu disposisi suratmasuk
    
    // Tahun Nomor Agenda
    TahunAgendaSMS	  = "2015"

)

type Configuration struct {
    Port string
    TemplatePath string
    PublicPath string
}


func Port() string {
	file, _ := os.Open("C:\\DWConf\\config.json")
	decoder := json.NewDecoder(file)
	configuration := Configuration{}
	err := decoder.Decode(&configuration)
	if err != nil {
	  fmt.Println("error:", err)
	}
	// fmt.Println() // output: [UserA, UserB]
	return configuration.Port
}

func TemplatePath() string {
	file, _ := os.Open("C:\\DWConf\\config.json")
	decoder := json.NewDecoder(file)
	configuration := Configuration{}
	err := decoder.Decode(&configuration)
	if err != nil {
	  fmt.Println("error:", err)
	}
	return configuration.TemplatePath
}

func PublicPath() string {
	file, _ := os.Open("C:\\DWConf\\config.json")
	decoder := json.NewDecoder(file)
	configuration := Configuration{}
	err := decoder.Decode(&configuration)
	if err != nil {
	  fmt.Println("error:", err)
	}
	return configuration.PublicPath
}

Wed, 29 Apr 2015 10:35 am
Redesign tag #go #project ... Bentuk list diubah ke bentuk array saja

Sebelum 
"tag" : [
          {
            "created_by" : "auto",
            "created_from" : "::1",
            "nama" : "ARIEF YANUAR",
            "kode_jabatan" : "01",
            "nama_jabatan" : "Kepala Kantor Wilayah DJP Kalimantan Selatan dan Tengah",
            "nomor_agenda" : 2,
            "tanggal_disposisi" : "2015-04-29 10:03:21.7417571 +0800 SGT",
            "tanggal_terima" : "2015-04-29 10:03:21.7417571 +0800 SGT"
          }
        ],

Planningnya 
"tag" : {
        "01" : {
            "created_by" : "auto",
            "created_from" : "::1",
            "nama" : "ARIEF YANUAR",
            "kode_jabatan" : "01",
            "nama_jabatan" : "Kepala Kantor Wilayah DJP Kalimantan Selatan dan Tengah",
            "nomor_agenda" : 2,
            "tanggal_disposisi" : "2015-04-29 10:03:21.7417571 +0800 SGT",
            "tanggal_terima" : "2015-04-29 10:03:21.7417571 +0800 SGT"
        }
    },
Wed, 29 Apr 2015 4:45 am
Beli "go programming blueprints" di #googleplay #go #book
Wed, 29 Apr 2015 4:43 am
Resource #go yang mangstabb ... golang-book.com
Wed, 29 Apr 2015 4:42 am
Resource #go yang mangstabb ... golang-book.com
Wed, 22 Apr 2015 8:48 pm
Hasil pencarian google sebenarnya mengarahkan ke library code.google.com/p/gofpdf, tapi setelah saya coba pasang dengan "go get" muncul error terkait versioning, blablabla ... #alhamdulillah diakhir-akhir pencarian kitab suci, saya dituntun ke sebuah library yang wow punya ... library sebenarnya dari library yang error ini yaitu "github.com/jung-kurt/gofpdf", meski library ini tidak semagic html2pdfnya php, saya pikir sudah cukup ... jadi kembali ke masa masa membuat pdf dengan koordinat #hahaha #go #project
Wed, 22 Apr 2015 8:42 pm
Golang pdf works like a charm, pake library github.com/jung-kurt/gofpdf #go #project
Wed, 22 Apr 2015 4:55 pm
Sedang berjibaku (oeeh) dengan golang pdf ... kesana kemari mencari kitab suci #go #project
Fri, 10 Apr 2015 10:25 am
Javascript sangat mudah mengolah data ini ...
JAVASCRIPT
{
	"kodejabatan":"01",
	"listsurat":[
			{
				"Tanggal":"08/04/2015",
				"Asal":"KPP Pratama Banjarmasin",
				"Hal":"Laporan",
				"Nomor":"S-123/WPJ.29/KP.01/2015",
				"Tag":
					[{
						"created_by":"auto",
						"kode_jabatan":"01",
						"nama":"MEKAR SATRIA UTAMA",
						"nama_jabatan":"Kepala Kantor Wilayah DJP Kalimantan Selatan dan Tengah",
						"nomor_agenda":1,
						"tanggal_disposisi":"2015-04-10 09:16:38.0569814 +0800 SGT",
						"tanggal_terima":"2015-04-10 09:16:38.0569814 +0800 SGT"
					},
					{
						"created_by":"01",
						"kode_jabatan":"01.02",
						"nama":"MUH. ARIEF ZUSNIANTO",
						"nama_jabatan":"Kepala Bidang Dukungan Teknis dan Konsultasi",
						"nomor_agenda":1,
						"tanggal_disposisi":"2015-04-10 09:16:53.9328976 +0800 SGT"
					},
					{
						"created_by":"01",
						"kode_jabatan":"01.04",
						"nama":"HENNY SUATRI SUARDI",
						"nama_jabatan":"Kepala Bidang Kerjasama dan Ekstensifikasi Perpajakan",
						"nomor_agenda":1,
						"tanggal_disposisi":"2015-04-10 09:35:56.3725057 +0800 SGT"
					},
					{
						"created_by":"01",
						"kode_jabatan":"99",
						"nama":"%!s(\u003cnil\u003e)",
						"nama_jabatan":"Fungsional",
						"nomor_agenda":1,
						"tanggal_disposisi":"2015-04-10 09:41:45.4615867 +0800 SGT"
					},
					{
						"created_by":"01",
						"kode_jabatan":"01.06",
						"nama":"\u003cnil\u003e",
						"nama_jabatan":"Kepala Bidang Pengurangan Keberatan dan Banding",
						"nomor_agenda":1,
						"tanggal_disposisi":"2015-04-10 09:43:13.1716407 +0800 SGT"
					}]
				,"Doc_series":"BLw2DLPAM"
			}
		],
	"username":"kakanwil"
}

INTERFACE{} GO

{"kodejabatan":"01","listsurat":[{"Tanggal":"08/04/2015","Asal":"KPP Pratama Ban
	jarmasin","Hal":"Laporan","Nomor":"S-123/WPJ.29/KP.01/2015","Tag":[{"created_by"
	:"auto","kode_jabatan":"01","nama":"MEKAR SATRIA UTAMA","nama_jabatan":"Kepala K
	antor Wilayah DJP Kalimantan Selatan dan Tengah","nomor_agenda":1,"tanggal_dispo
	sisi":"2015-04-10 09:16:38.0569814 +0800 SGT","tanggal_terima":"2015-04-10 09:16
	:38.0569814 +0800 SGT"},{"created_by":"01","kode_jabatan":"01.02","nama":"MUH. A
	RIEF ZUSNIANTO","nama_jabatan":"Kepala Bidang Dukungan Teknis dan Konsultasi","n
	omor_agenda":1,"tanggal_disposisi":"2015-04-10 09:16:53.9328976 +0800 SGT"},{"cr
	eated_by":"01","kode_jabatan":"01.04","nama":"HENNY SUATRI SUARDI","nama_jabatan
	":"Kepala Bidang Kerjasama dan Ekstensifikasi Perpajakan","nomor_agenda":1,"tang
	gal_disposisi":"2015-04-10 09:35:56.3725057 +0800 SGT"},{"created_by":"01","kode
	_jabatan":"99","nama":"%!s(\u003cnil\u003e)","nama_jabatan":"Fungsional","nomor_
	agenda":1,"tanggal_disposisi":"2015-04-10 09:41:45.4615867 +0800 SGT"},{"created
	_by":"01","kode_jabatan":"01.06","nama":"\u003cnil\u003e","nama_jabatan":"Kepala
	 Bidang Pengurangan Keberatan dan Banding","nomor_agenda":1,"tanggal_disposisi":
	"2015-04-10 09:43:13.1716407 +0800 SGT"}],"Doc_series":"BLw2DLPAM"}],"username":
	"kakanwil"}

	Type ==> suratmasuk.Response aka interface{}

dan masih menjadi mimpi buruk di #go, dengan type interface{} -nya #fyuuh #go
Fri, 10 Apr 2015 10:05 am
Mungkin inilah sebabnya Go lebih powerful untuk API development ketimbang Web Development ... GO sangat pelik retrieve data interfacenya, sedangkan serving JSON nya work like a magic #fyuuh #go
Fri, 10 Apr 2015 10:02 am
JSON Output
        /*
        // JSON
        w.Header().Set("Content-Type", "application/json")
        fmt.Fprint(w, finalResult)
        return
        */
#go
Thu, 9 Apr 2015 9:12 pm
Hooaaaheemm i am really really love #go
Thu, 9 Apr 2015 9:10 pm
Satu pertanyaan besar, kenapa ga pake sambel ? wex... kenala ga pake fungsi saja untuk mengolah data di template #go, daripada harus capek2 dengan programmable html/template yang sangat terbatas ... ckckck, ga kepikiran ... tinggal masalahnya sekarang lempar melempar variable dari dan ke template ... mungkin context-nya #gorilla bisa dicoba ...
Thu, 9 Apr 2015 3:47 pm
Wuuh, benar-benar hari-hari yang runyam. Kemaren belepotan di iterate interface{} ke map[string]interface{}, maksud hati supaya gampang di json-kan, dan ane lebih paham apa yang sebenarnya terjadi, daripada harus menerima magic-nya #go. Ane nyerah, coz untuk output json sudah di magic-kan juga sama #go ... ane tetap saja kurang puas coz data yang diparsing ke template adalah semua, tidak bisa dipilah-pilah dahulu sebelum di pass. Untung lah template bisa meng-compare data, jadi tidak perlu semua data ditampilkan
{{define "title"}}
		Home
	{{end}}

	{{define "username"}}
		{{.username}}
	{{end}}

	{{define "body"}}
		
		{{ $kodejabatan := .kodejabatan }}
		
		Input 
<table border="1"> <thead> <th>Mode</th> <th colspan="2">Agenda</th> <th>Asal</th> <th>Nomor</th> <th>Tanggal</th> <th>Hal</th> </thead> {{ range .listsurat}} <tr> <td>Detail</td> {{ range .Tag}} {{ if eq .kode_jabatan $kodejabatan}} <td>{{.nomor_agenda}}</td> <td>{{.tanggal_disposisi | formatwaktu}}</td> {{ end }} {{ end }} <td>{{ .Asal}}</td> <td>{{ .Nomor}}</td> <td>{{ .Tanggal}}</td> <td>{{ .Hal}}</td> </tr> {{ end }} </table> {{end}}
#project
Tue, 7 Apr 2015 4:27 pm
Merapikan Model sms #go, nama model sesuai nama collection saja ... biar ga pusing #project
Mon, 6 Apr 2015 9:35 am
Ajax-ing sms #project, mulai berkutat dengan JSON-nya #go. Selama ini masih seputar Form ... semoga lancar jaya aamieen
Thu, 2 Apr 2015 11:38 am
sms-go #done at
- Admin Login
- Admin Logout
- Admin User
- Admin Jabatan
#project #go
Fri, 27 Mar 2015 6:09 pm
Package Checklist
Session : OK
MongoDB : OK
#todo
- Pecah sms-server ke package-package
- Rapikan Folder Templates
#project #go
Fri, 27 Mar 2015 5:47 pm
Belajar #go mulai masuk package, hari ini runtime sms sudah berhasil dipecah ke beberapa package #enlightenment
Fri, 27 Mar 2015 10:29 am
To handle different methods differently: Many of my HTTP handlers contain nothing but a switch statement like this:
switch r.Method {
   case "GET":
       // Serve the resource.
   case "POST":
       // Create a new record.
   case "PUT":
       // Update an existing record.
   case "DELETE":
       // Remove the record.
   default:
       // Give an error message.
}
#go #stackoverflow #reminder
Thu, 26 Mar 2015 12:48 am
sms-server.go
package main

  import (
      "fmt"
      "github.com/gorilla/mux"
      "github.com/gorilla/sessions"
      // "github.com/fzzy/radix/redis"
      // "github.com/fatih/structs"
      "net"
      "net/http"
      "html/template"
      "gopkg.in/mgo.v2"         
      "gopkg.in/mgo.v2/bson"
      "regexp"
      "strings"
      "crypto/rand"
      "time"
      "strconv"
      // "encoding/json"
      // "reflect"
  )

  var (
      // MongoDB
      mongoConfig       = "mongodb://localhost:27017/admin"
      MongoSession, err = mgo.Dial(mongoConfig)
      MDB               = MongoSession.DB("admin")
      BlogCol           = MDB.C("blog")
      UserCol           = MDB.C("user")

      // Session
      store             = sessions.NewCookieStore([]byte("something-very-secret"))

      // Blog
      skipHome          = 0
      limit             = 10
      rowsNum           = 10

      // Tag Factory
      tagPattern        = "#([a-z]|[A-Z]|[_])+"

      // Path
      templatePath      = "D:\\PROJECTS\\GO-APP\\webkoe\\templates\\"
      publicPath        = "D:\\PROJECTS\\GO-APP\\webkoe\\public\\"
  )

  func cekKodeJabatan(r *http.Request) string {
      session,_       := store.Get(r, "session-name")
      kode_jabatan    := fmt.Sprintf("%s", session.Values["kode_jabatan"])
      return kode_jabatan  
  }

  func SmsHomeHandler(w http.ResponseWriter, r *http.Request) {

      if cekKodeJabatan(r) == "" {
          http.Redirect(w, r, "/login", 301)
          fmt.Println(cekKodeJabatan(r))
          fmt.Println("*** @home -> No Data ")
      }else{
          templates := template.Must(template.New("").ParseFiles(templatePath + "sms-base.html", templatePath + "sms-home.html"))
          err := templates.ExecuteTemplate(w, "base", cekKodeJabatan(r))
          if err != nil {
              http.Error(w, err.Error(), http.StatusInternalServerError)
          }        
      }
  }

  func SmsLoginFormHandler(w http.ResponseWriter, r *http.Request) {

      if cekKodeJabatan(r) == "" {
          templates := template.Must(template.New("").ParseFiles(templatePath + "sms-base.html", templatePath + "sms-loginform.html"))
          err := templates.ExecuteTemplate(w, "base", nil)
          if err != nil {
              http.Error(w, err.Error(), http.StatusInternalServerError)
          }
      }else{
          http.Redirect(w, r, "/", 301)
      }
  }  

  func SmsPostLoginHandler(w http.ResponseWriter, r *http.Request) {
      
      if cekKodeJabatan(r) == "" {
          username          := r.FormValue("username")
          password          := r.FormValue("password")

          var results map[string]interface{}
          err = UserCol.Find(bson.M{"username": username, "password" : password}).One(&results)
          if err != nil {
              http.Redirect(w, r, "/#error", 301)
          }else{
              kode_jabatan, _ := results["kode_jabatan"]
              session, _                     := store.Get(r, "session-name")
              session.Values["kode_jabatan"]  = kode_jabatan
              session.Save(r, w)
              http.Redirect(w, r, "/", 301)
          }
      }else{
          http.Redirect(w, r, "/", 301)
      }
  }

  func SmsLogoutHandler(w http.ResponseWriter, r *http.Request) {
      
      session, _                     := store.Get(r, "session-name")
      session.Values["kode_jabatan"]  = ""
      session.Save(r, w)

      http.Redirect(w, r, "/", 301)
  }

  func safehtml(text string) template.HTML { 

      text = text + " "
      text = strings.Replace(text, "<", "<", -1)   
      text = strings.Replace(text, ">", ">", -1) 
        
      text = strings.Replace(text, "", "
", -1) text = strings.Replace(text, "", "", -1) text = strings.Replace(text, "", "", -1) text = strings.Replace(text, "", "", -1) text = strings.Replace(text, "", "", -1) text = strings.Replace(text, "", "", -1) text = strings.Replace(text, "", "", -1) text = strings.Replace(text, "=", "=", -1) text = strings.Replace(text, "<a href=", "", "", -1) text = strings.Replace(text, "<img src=", "", ">", -1) regexPagar, _ := regexp.Compile(tagPattern) tags := regexPagar.FindAllString(text, -1) for _ , value := range tags { tagAscii := strings.Replace(value, "#", "#", 1) tagOnly := strings.Replace(value, "#", "", 1) text = strings.Replace(text, value, "" + tagAscii + "", 1) } return template.HTML(text) } func timeFormatter(text string) template.HTML { text = strings.Replace(text, " ", "-", -1) text = strings.Replace(text, ":", "-", -1) split := strings.Split(text, "-") tahun, _ := strconv.Atoi(split[0]) bulan, _ := strconv.Atoi(split[1]) tanggal, _ := strconv.Atoi(split[2]) jam, _ := strconv.Atoi(split[3]) menit, _ := strconv.Atoi(split[4]) detik, _ := strconv.Atoi(split[5]) var _bulan time.Month if bulan == 1 { _bulan = time.January }else if bulan == 2 { _bulan = time.February }else if bulan == 3{ _bulan = time.March }else if bulan == 4{ _bulan = time.April }else if bulan == 5{ _bulan = time.May }else if bulan == 6{ _bulan = time.June }else if bulan == 7{ _bulan = time.July }else if bulan == 8{ _bulan = time.August }else if bulan == 9{ _bulan = time.September }else if bulan == 10{ _bulan = time.October }else if bulan == 11{ _bulan = time.November }else if bulan == 12{ _bulan = time.December } // const layout = "Mon Jan 2, 2006 at 3:04pm (MST)" (MST) --> WITA const layout = "Mon, 2 Jan 2006 3:04 pm" t := time.Date(tahun, _bulan, tanggal, jam, menit, detik, 0, time.Local) return template.HTML(t.Format(layout)) } func randStr(strSize int, randType string) string { var dictionary string if randType == "alphanum" { dictionary = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" } if randType == "alpha" { dictionary = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" } if randType == "number" { dictionary = "0123456789" } var bytes = make([]byte, strSize) rand.Read(bytes) for k, v := range bytes { bytes[k] = dictionary[v%byte(len(dictionary))] } return string(bytes) } func GetIP(r *http.Request) string { if ipProxy := r.Header.Get("X-FORWARDED-FOR"); len(ipProxy) > 0 { return ipProxy } ip, _, _ := net.SplitHostPort(r.RemoteAddr) return ip } func main() { mx := mux.NewRouter() // *** home *** mx.HandleFunc("/", SmsHomeHandler) // *** login *** mx.HandleFunc("/login", SmsLoginFormHandler).Methods("GET") mx.HandleFunc("/login", SmsPostLoginHandler).Methods("POST") // *** logout *** mx.HandleFunc("/logout", SmsLogoutHandler).Methods("GET") // *** static server *** mx.PathPrefix("/").Handler(http.FileServer(http.Dir( publicPath ))) http.ListenAndServe(":80", mx) } #go #script
Wed, 25 Mar 2015 8:30 pm
Go Pros
Was it worth it?

Yes, a million times, yes. The speed boost is just too good to pass up. Also, and this counts for something I think, Go is a trendy language right now, so when it comes to recruiting, I think having Go as a critical part of Repustate’s tech stack will help.
#go
Wed, 25 Mar 2015 6:07 pm
add /page/{page} #webkoe #go
Mon, 23 Mar 2015 3:46 pm
func safehtml di List dan TagView di sederhanakan jadi satu fungsi tersendiri #webkoe #go
      func safehtml(text string) template.HTML { 

          text = text + " "
          text = strings.Replace(text, "<", "<", -1)   
          text = strings.Replace(text, ">", ">", -1) 
            
          text = strings.Replace(text, "
", "
", -1) 
          text = strings.Replace(text, "
", "
", -1) regexPagar, _ := regexp.Compile(tagPattern) tags := regexPagar.FindAllString(text, -1) for _ , value := range tags { tagAscii := strings.Replace(value, "#", "#", 1) tagOnly := strings.Replace(value, "#", "", 1) text = strings.Replace(text, value, "" + tagAscii + "", 1) } return template.HTML(text) }
dan ini yang memanggil
      func WkListHandler(w http.ResponseWriter, r *http.Request) {
          funcMap := template.FuncMap{
              "safehtml": safehtml ,
          }
          templates := template.Must(template.New("").Funcs(funcMap).ParseFiles(templatePath + "webkoe-base.html", templatePath + "webkoe-list.html"))
          
          var results []Blog
          err = MCol.Find(bson.M{}).Sort("-date").Limit(1000000000000).All(&results)
          if err != nil {
              panic(err)
          }

          // var finalResult []tagView
          // fmt.Println(reflect.TypeOf(results))
          err := templates.ExecuteTemplate(w, "base", results)
          if err != nil {
              http.Error(w, err.Error(), http.StatusInternalServerError)
          }
      }
#script #webkoe #go #enlightenment #nice
Mon, 23 Mar 2015 6:08 am
Semangat pagi, rencana hari ini adalah update rencana 2014 di #portalkanwil #kantor, rencana masih make rencana sebelum revisi PBB (turun 70M) dan sebelum adjusment 100% per kpp. Untuk #go nya #webkoe mungkin akan nyoba get dayname from date dulu, lumayan mengganggu kalo tanggal ga ada harinya #todo
Sun, 22 Mar 2015 1:58 am
Menambah Environment Variable di Ubuntu dan Windows
- Ubuntu :
  Awal    PATH="/root/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"
  
  root@webkoe:~# export PATH=$PATH:/root/go/bin
  
  Menjadi PATH="/root/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/root/go/bin"

- Windows :
  Awal Path=C:\Python27\;C:\Python27\Scripts;D:\oracle\product\11.1.0\db_1\bin;C:\ProgramData\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;
  C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;D:\PROJECTS\NODEAPP\Nodejs\;D:\PROJECTS\WEB\xampp\php;
  C:\Program Files\MongoDB 2.6 Standard\bin;C:\ProgramData\ComposerSetup\bin;C:\dart\dart-sdk\bin;D:\PROJECTS\GO\bin;
  C:\Program Files (x86)\Git\cmd;C:\Ruby21-x64\bin;C:\Users\lou\AppData\Roaming\npm
  
  C:\Users\lou>set PATH=%PATH%;D:\PROJECTS\GO\bin

  Menjadi Path=C:\Python27\;C:\Python27\Scripts;D:\oracle\product\11.1.0\db_1\bin;C:\ProgramData\Oracle\Java\javapath;C:\Windows\system32;
  C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;D:\PROJECTS\NODEAPP\Nodejs\;D:\PROJECTS\WEB\xampp\php;
  C:\Program Files\MongoDB 2.6 Standard\bin;C:\ProgramData\ComposerSetup\bin;C:\dart\dart-sdk\bin;D:\PROJECTS\GO\bin;
  C:\Program Files (x86)\Git\cmd;C:\Ruby21-x64\bin;C:\Users\lou\AppData\Roaming\npm;D:\PROJECTS\GO\bin

#script #setting #go
Sun, 22 Mar 2015 12:19 am
Saatnya kompilasi ... server-gorilla :) #webkoe #go
Sun, 22 Mar 2015 12:17 am
Ane awalnya rumit sekali mikirnya ... syukurlah ketemu link ini 
http://stackoverflow.com/questions/17306358/golang-removing-fields-from-struct-or-hiding-them-in-json-response

Ternyata cukup serahkan pada map[string]interface{}, sudah bisa kirim variable apapun, sepuasnya ke templates

  func WkTagViewHandler(w http.ResponseWriter, r *http.Request) {
          
          tagName := mux.Vars(r)["tag"]
          
          funcMap := template.FuncMap{
              "safehtml": func(text string) template.HTML { 

                  text = text + " "
                  text = strings.Replace(text, "<", "<", -1)   
                  text = strings.Replace(text, ">", ">", -1) 
                    
                  text = strings.Replace(text, "
", "
", -1) 
                  text = strings.Replace(text, "
", "
", -1) regexPagar, _ := regexp.Compile(tagPattern) tags := regexPagar.FindAllString(text, -1) for _ , value := range tags { tagAscii := strings.Replace(value, "#", "#", 1) tagOnly := strings.Replace(value, "#", "", 1) text = strings.Replace(text, value, "" + tagAscii + "", 1) } return template.HTML(text) }, } templates := template.Must(template.New("").Funcs(funcMap).ParseFiles(templatePath + "webkoe-base.html", templatePath + "webkoe-tagview.html")) var results []Blog err = MCol.Find(bson.M{"tag": tagName}).Sort("-date").Limit(1000000000000).All(&results) if err != nil { panic(err) } finalResult := map[string]interface{}{ "tagName" : tagName, "tagList" : results, } err := templates.ExecuteTemplate(w, "base", finalResult) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } }
#webkoe #go #script
Sun, 22 Mar 2015 12:14 am
Passing multiple variable to templates #done #alhamdulillah #go #webkoe
Sat, 21 Mar 2015 8:10 pm
Tinggal satu masalah lagi, variable #go yang masih belum clear. Passing tagName dan result dalam satu var, yang satunya "string", dan satunya lagi "[]Blog"
#todo #webkoe
Sat, 21 Mar 2015 6:19 am
server-gorilla.go
package main

    import (
        "fmt"
        "github.com/gorilla/mux"
        "github.com/gorilla/sessions"
        "github.com/fzzy/radix/redis"
        "net"
        "net/http"
        "html/template"
        "gopkg.in/mgo.v2"         
        "gopkg.in/mgo.v2/bson"
        "regexp"
        "strings"
        "crypto/rand"
        "time"
        // "reflect"
    )
    
    var (
        // MongoDB
        mongoConfig       = "mongodb://***usermongo***:***passmongo***@localhost:***portmongo***/***dbmongo***"
        MongoSession, err = mgo.Dial(mongoConfig)
        MDB               = MongoSession.DB("admin")
        MCol              = MDB.C("blog")

        // Session
        store             = sessions.NewCookieStore([]byte("something-very-secret"))

        // Tag Factory
        tagPattern        = "#([a-z]|[A-Z])+"
    )

    type Blog struct {
      Id string
      Things string
      Date string
      Ip string
      Agent string
      Tag []string
    }

    // type tagView struct {
    //   tagName string
    //   tagList []main.Blog
    // }

    func WkHomeHandler(w http.ResponseWriter, r *http.Request) {
        err := template.Must(template.ParseFiles("templates/webkoe-home.html")).Execute(w, nil) 
        if err != nil { 
           http.Error(w, err.Error(), http.StatusInternalServerError) 
        } 
    }

    func WkTagViewHandler(w http.ResponseWriter, r *http.Request) {
        
        tagName := mux.Vars(r)["tag"]
        
        funcMap := template.FuncMap{
            "safehtml": func(text string) template.HTML { 

                text = text + " "
                text = strings.Replace(text, "<", "<", -1)   
                text = strings.Replace(text, ">", ">", -1) 
                  
                text = strings.Replace(text, "
", "
", -1) 
                text = strings.Replace(text, "
", "
", -1) regexPagar, _ := regexp.Compile(tagPattern) tags := regexPagar.FindAllString(text, -1) for _ , value := range tags { tagAscii := strings.Replace(value, "#", "#", 1) tagOnly := strings.Replace(value, "#", "", 1) text = strings.Replace(text, value, "" + tagAscii + "", 1) } return template.HTML(text) }, } templates := template.Must(template.New("").Funcs(funcMap).ParseFiles("templates/webkoe-base.html", "templates/webkoe-tagview.html")) var results []Blog err = MCol.Find(bson.M{"tag": tagName}).Sort("-date").Limit(1000000000000).All(&results) if err != nil { panic(err) } err := templates.ExecuteTemplate(w, "base", results) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } func WkCreateHandler(w http.ResponseWriter, r *http.Request) { blog_id := randStr(7, "alphanum") session, _ := store.Get(r, "session-name") session.Values["blog_id"] = blog_id session.Save(r, w) templates := template.Must(template.New("").ParseFiles("templates/webkoe-base.html", "templates/webkoe-create.html")) err := templates.ExecuteTemplate(w, "base", blog_id) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } func WkPostCreateHandler(w http.ResponseWriter, r *http.Request) { things := r.FormValue("things") thingsWithSpace := things + " " captcha := r.FormValue("captcha") session,_ := store.Get(r, "session-name") blog_id := fmt.Sprintf("%s", session.Values["blog_id"]) if things != "" { if captcha == blog_id { // Factory cariTag,_ := regexp.Compile(tagPattern) tagFound := cariTag.FindAllString(thingsWithSpace, -1) var tempTags []string for _, value := range tagFound { cleanRegex,_ := regexp.Compile("(#| )") cleanTag := cleanRegex.ReplaceAllString(value, "") tempTags = append(tempTags, cleanTag) } waktu := strings.Split(fmt.Sprint(time.Now()), ".")[0] ip := GetIP(r) agent := fmt.Sprint(r.Header["User-Agent"]) jsonBlog := &Blog{Id: blog_id, Things: things, Date: waktu, Ip: ip, Agent: agent, Tag: tempTags} err = MCol.Insert(jsonBlog) fmt.Println("Welcome, " + things + " " + thingsWithSpace) http.Redirect(w, r, "/#thanks", 301) }else{ fmt.Println("Robot ?") http.Redirect(w, r, "/#you_r_a_bots", 301) } }else{ http.Redirect(w, r, "/#empty", 301) } // fmt.Println("Someone POST " + things + " blog_id " + blog_id) // fmt.Println(blog_id) /* templates := template.Must(template.New("").ParseFiles("templates/webkoe-base.html", "templates/webkoe-create.html")) err := templates.ExecuteTemplate(w, "base", nil) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } */ } func WkListHandler(w http.ResponseWriter, r *http.Request) { funcMap := template.FuncMap{ "safehtml": func(text string) template.HTML { text = text + " " text = strings.Replace(text, "<", "<", -1) text = strings.Replace(text, ">", ">", -1) text = strings.Replace(text, "
", "
", -1) 
                text = strings.Replace(text, "
", "
", -1) regexPagar, _ := regexp.Compile(tagPattern) tags := regexPagar.FindAllString(text, -1) for _ , value := range tags { tagAscii := strings.Replace(value, "#", "#", 1) tagOnly := strings.Replace(value, "#", "", 1) text = strings.Replace(text, value, "" + tagAscii + "", 1) } return template.HTML(text) }, } templates := template.Must(template.New("").Funcs(funcMap).ParseFiles("templates/webkoe-base.html", "templates/webkoe-list.html")) var results []Blog err = MCol.Find(bson.M{}).Sort("-date").Limit(1000000000000).All(&results) if err != nil { panic(err) } // var finalResult []tagView // fmt.Println(reflect.TypeOf(results)) err := templates.ExecuteTemplate(w, "base", results) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } func CatatanHomeHandler(w http.ResponseWriter, r *http.Request) { var results []Blog err = MCol.Find(bson.M{}).Sort("-date").Limit(100).All(&results) if err != nil { panic(err) } err := template.Must(template.ParseFiles("templates/gorilla-catatanhome.html")).Execute(w, results) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } func HomeWKSHandler(w http.ResponseWriter, r *http.Request) { err := template.Must(template.ParseFiles("templates/gorilla-home_wks.html")).Execute(w, nil) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } func WkBlogHandler(w http.ResponseWriter, r *http.Request) { page := mux.Vars(r)["page"] err := template.Must(template.ParseFiles("templates/gorilla-blog.html")).Execute(w, map[string]string{"halaman": page}) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } func WkRedisHandler(w http.ResponseWriter, r *http.Request) { // redis redisClient, _ := redis.Dial("tcp", "localhost:6379") news, _ := redisClient.Cmd("zrevrangebyscore", "news:republika:posttime", "+inf", "-inf", "limit", "0", "3").List() var bundleNews []string for _, elemStr := range news { bundleNews = append(bundleNews, elemStr) fmt.Println(bundleNews) } // render err := template.Must(template.ParseFiles("templates/gorilla-redis.html")).Execute(w, bundleNews) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } func WkTestPassVarHandler(w http.ResponseWriter, r *http.Request) { err := template.Must(template.ParseFiles("templates/gorilla-blog.html")).Execute(w, map[string]string{"halaman": "2"}) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } func randStr(strSize int, randType string) string { var dictionary string if randType == "alphanum" { dictionary = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" } if randType == "alpha" { dictionary = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" } if randType == "number" { dictionary = "0123456789" } var bytes = make([]byte, strSize) rand.Read(bytes) for k, v := range bytes { bytes[k] = dictionary[v%byte(len(dictionary))] } return string(bytes) } func GetIP(r *http.Request) string { if ipProxy := r.Header.Get("X-FORWARDED-FOR"); len(ipProxy) > 0 { return ipProxy } ip, _, _ := net.SplitHostPort(r.RemoteAddr) return ip } func main() { // MUX ROUTER mx := mux.NewRouter() // WEBKOE.NET // *** home *** mx.HandleFunc("/", WkListHandler).Host("webkoe.net") // *** tag *** mx.HandleFunc("/tag/{tag}", WkTagViewHandler).Host("webkoe.net").Methods("GET") // *** create *** mx.HandleFunc("/create", WkCreateHandler).Host("webkoe.net").Methods("GET") mx.HandleFunc("/create", WkPostCreateHandler).Host("webkoe.net").Methods("POST") // *** misc *** mx.HandleFunc("/test/pass_var", WkTestPassVarHandler).Host("webkoe.net") mx.HandleFunc("/redis", WkRedisHandler).Host("webkoe.net") mx.HandleFunc("/page/{page}", WkBlogHandler).Host("webkoe.net") mx.PathPrefix("/").Handler(http.FileServer(http.Dir("./public/"))).Host("webkoe.net") // CATATAN.WEBKOE.NET mx.HandleFunc("/", CatatanHomeHandler).Host("catatan.webkoe.net") // WEBKANSAJA.COM mx.HandleFunc("/", HomeWKSHandler).Host("webkansaja.com") http.ListenAndServe(":80", mx) }
#script #go #webkoe
Sat, 21 Mar 2015 6:12 am
Semua pattern tagsearch di List, tagView, dan POSTcreate juga dimasukkan ke var() #go #webkoe
Sat, 21 Mar 2015 6:07 am
Semua var #go masuk ke var() #webkoe
Fri, 20 Mar 2015 6:17 pm
- How to start executable file with forever
- How to Pass result and tagName to template
#todo #go #webkoe
Fri, 20 Mar 2015 4:54 pm
Wuhuuuu ... #go running smooothlyyy
Wed, 11 Mar 2015 9:11 pm
Tinggal 1 PR lagi untuk mereplace nodejs ... REDIS ... kalo perlu crawler yang selama ini dilakukan python dan curl, juga diambil alih #go #webkoe
Wed, 11 Mar 2015 9:10 pm
#go dengan #gorilla support #mongodb juga .... #nice
Wed, 11 Mar 2015 9:09 pm
#go dengan #gorilla sudah support static file juga ... #nice #alhamdulillah
Wed, 11 Mar 2015 6:16 pm
#go dengan #gorilla, bisa meroute sepuasnya ... :)
Mon, 9 Mar 2015 12:40 am
#go tetap menunjukkan progress, satu persatu mulai bisa ditasi #webkoe
Mon, 9 Mar 2015 12:38 am
Berikutnya tinggal mengubah pagar tag (#) menjadi link, ...
1. Disisi server
   ** bisa dilakukan, tapi belum tau caranya mempassing HTML Tag ke template martini
2. Sisi Client
   ** tinggal copas script di express ke client
#webkoe #go
Mon, 9 Mar 2015 12:32 am
Single file #webkoe server written in #go :)

package main

  import (
    "github.com/go-martini/martini"
    "github.com/martini-contrib/render"
    "gopkg.in/mgo.v2"
    "gopkg.in/mgo.v2/bson"
    "net"
    "net/http"
    "fmt"
    "time"
    "crypto/rand"
    "strings"
    "regexp"
  )

  // local 
  var mongoConfig = "127.0.0.1:27017"
  var blogCollection = "webkoe_blog"
  var hostHome = "localhost:8080"
  var hostCatatan = "catatan"


  // webkoe
  // var mongoConfig = "mongodb://usermongo:passmongo@localhost:portmongo/dbmongo"
  // var blogCollection = "blog"
  // var hostHome = "webkoe.net:8080"
  // var hostCatatan = "catatan.webkoe.net"


  type Blog struct {
    Id string
    Things string
    Date string
    Ip string
    Agent string
    Tag []string
  }

  func GetIP(r *http.Request) string {
      if ipProxy := r.Header.Get("X-FORWARDED-FOR"); len(ipProxy) > 0 {
          return ipProxy
      }
      ip, _, _ := net.SplitHostPort(r.RemoteAddr)
      return ip
  }

  func randStr(strSize int, randType string) string {
     var dictionary string
     if randType == "alphanum" {
        dictionary = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
     }
     if randType == "alpha" {
        dictionary = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
     }
     if randType == "number" {
        dictionary = "0123456789"
     }
     var bytes = make([]byte, strSize)
     rand.Read(bytes)
     for k, v := range bytes {
        bytes[k] = dictionary[v%byte(len(dictionary))]
     }
     return string(bytes)
   }

  func main() {

      // MARTINI
      m := martini.Classic()
      m.Use(render.Renderer(render.Options{
            Layout: "layout",
      }))

      // MONGODB
      session, err := mgo.Dial(mongoConfig)
      if err != nil {
        panic(err)
      }
      defer session.Close()
      session.SetMode(mgo.Monotonic, true)
      webkoe_blog := session.DB("admin").C(blogCollection)

      // ROUTER
      m.Get("/", func(r render.Render, req *http.Request) {
        if req.Host == hostHome {
          r.HTML(200, "home", req.Host)
        }else if req.Host == hostCatatan {
          r.HTML(200, "home-catatan", req.Host)
        }
      })

      m.Get("/blog", func(r render.Render) {
        var results []Blog
        err = webkoe_blog.Find(bson.M{}).Sort("-date").Limit(100).All(&results)
        if err != nil {
          panic(err)
        }
        // fmt.Println(results)
        r.HTML(200, "blog", results)
      })
      m.Post("/blog", func(req *http.Request, r render.Render){
        
        things := req.FormValue("things") + " "
        
        // tag
        regex, err := regexp.Compile("#([a-z])+ ")
        remove, err := regexp.Compile("(#| )")
        tags := regex.FindAllString(things, -1)
        // fmt.Println(tags)

        // modify semua listA
        var modTags []string
        for _, value := range tags {
            final := remove.ReplaceAllString(value, "")
            modTags = append(modTags, final)
        }
        // fmt.Println(modTags)


        waktu := strings.Split(fmt.Sprint(time.Now()), ".")[0]
        blog_id := randStr(7, "alphanum")
        ip := GetIP(req)
        agent := fmt.Sprint(req.Header["User-Agent"])

        jsonBlog := &Blog{Id: blog_id, Things: things, Date: waktu, Ip: ip, Agent: agent, Tag: modTags}
        err = webkoe_blog.Insert(jsonBlog)
        if err != nil {
          panic(err)
        }
        // fmt.Println(agent)
        r.Redirect("/blog")
      })
      m.Get("/blog/write", func(r render.Render) {
        r.HTML(200, "blog-form", nil)
      })

      m.RunOnAddr(":8080")
  }

Mon, 9 Mar 2015 12:30 am
Menempel ke tag#webkoe from #go
Mon, 9 Mar 2015 12:29 am
Tags behavior added to #go again ...
Sun, 8 Mar 2015 11:46 pm
Script #go khusus modifikasi list http://play.golang.org/p/dpuX0ORbYJ
Sun, 8 Mar 2015 11:41 pm
Kesimpulan array #go sampai dengan hari ini

package main

    import "fmt"
    import "encoding/json"

    type Blog struct {
        id string
        things string
        tag []string
    }

    func main() {
        
        fmt.Println("\nMari mulai belajar list dan map Golang ...")

        // list
        listA   := []string{"ikan","sayur","buah", "1", "2", "3"}
        listB, _ := json.Marshal(listA)
        fmt.Println("\nlistA adalah " + string(listB))

        listA2   := []int{1,2,3}
        listB2, _ := json.Marshal(listA2)
        fmt.Println("\nlistA2 adalah " + string(listB2))   

        // dict
        mapA    := map[string]int {"apple": 5, "lettuce": 7}
        mapB, _ := json.Marshal(mapA)
        fmt.Println("\nmapA adalah " + string(mapB))

        fmt.Println("\nlist A")
        for _, value := range listA {
            fmt.Println(value)
        }

        fmt.Println("\nlist A2")
        for _, value := range listA2 {
            fmt.Println(value)
        }      

        fmt.Println("\nmapA")
        for key , value := range mapA {
            fmt.Println(key + " " + fmt.Sprint(value))
        }

        // manipulate list
        fmt.Println("\nAppend listA")
        x := append(listA, "77")
        fmt.Println(x)

        // modify semua listA
        fmt.Println("\nModify listA")
        var modListA []string
        for _, value := range listA {
            modListA = append(modListA, "mod:" + value)
        }
        fmt.Println(modListA)
    }

script diatas menghasilkan output

D:\PROJECTS\GO-APP>go run coba_json_sendiri.go

Mari mulai belajar list dan map Golang ...

listA adalah ["ikan","sayur","buah","1","2","3"]

listA2 adalah [1,2,3]

mapA adalah {"apple":5,"lettuce":7}

list A
ikan
sayur
buah
1
2
3

list A2
1
2
3

mapA
lettuce 7
apple 5

Append listA
[ikan sayur buah 1 2 3 77]

Modify listA
[mod:ikan mod:sayur mod:buah mod:1 mod:2 mod:3]

Sat, 7 Mar 2015 2:36 pm
belajar list/array di $go

Yang saya tahu pada awalnya, pada #javascript dan #python
    
    a = ['ikan', 'sayur', 'buah', 1, 2, 3]

selesai, list sudah langsung terbentuk
bahkan dengan #php pun mudah

    a = array('ikan', 'sayur', 'buah', 1, 2, 3)

Buum, jadi ....

di GO lumayan runyam, namun JELAS dan RAPI

    listA   := []string{"ikan","sayur","buah", "1", "2", "3"}
    listB, _ := json.Marshal(listA)
    fmt.Println(string(listB)) // output ["ikan","sayur","buah","1","2","3"]

    listA2   := []int{1,2,3}
    listB2, _ := json.Marshal(listA2)
    fmt.Println(string(listB2)) // output [1,2,3]

listA adalah list dengan type data STRING, angka bisa masuk, tapi dia tidak diperlakukan sebagai INT (dengan petik dua "")
sedangankan listA2 adalah list dengan type data INT, anggotanya benar-benar angka (tanpa petik dua ""),
ikan sayur buah ERROR pada saat di-compile jika dipaksakan masuk

kode lengkapnya #go-nya :

    package main

    import "fmt"
    import "encoding/json"

    type Blog struct {
        id string
        things string
        tag []string
    }

    func main() {
        
        fmt.Println("Mari mulai ...")

        // list
        listA   := []string{"ikan","sayur","buah", "1", "2", "3"}
        listB, _ := json.Marshal(listA)
        fmt.Println(string(listB))

        listA2   := []int{1,2,3}
        listB2, _ := json.Marshal(listA2)
        fmt.Println(string(listB2))   

        // dict
        mapA    := map[string]int {"apple": 5, "lettuce": 7}
        mapB, _ := json.Marshal(mapA)
        fmt.Println(string(mapB))    
    }

Sat, 7 Mar 2015 9:02 am
tidak mudah migrasi ke #go ... kembalikan lagi ke express, sementara ini #go masih dapat porsi di port 8080, http://webkoe.net:8080 #webkoe
Fri, 6 Mar 2015 9:59 pm
Mmmm ... dari #go waktunya beda #bug
Fri, 6 Mar 2015 9:04 pm
#go Sudah bisa POST and GET dari mongodb ... :)
Fri, 6 Mar 2015 7:42 pm
Untuk menghindari pulsa terbuang percuma, develop martini #go nya di laptop mawon
Thu, 5 Mar 2015 10:22 pm
Coba pake Martini, salah satu web frameworknya #go
Fri, 27 Feb 2015 10:03 am
Mbikin crawler Intranet #kantor dengan #go, ternyata lumayan menyita waktu, ada banyak contoh scriptnya, tp kebanyakan belum mensupport POST, SESSION, COOKIES ... akhirnya ane balik ke duet #python dan #curl mawon .... Xixixi #project
Wed, 25 Feb 2015 2:34 pm
#go sudah bisa konek ke #mysql ... belajarGO #project
Sat, 21 Feb 2015 3:03 am
http://webkoe.net:8080 resmi dihandle #go ... ada wikinyaa ... alamAaAakk #veryawesome #webkoe #alhamdulillah
Sat, 21 Feb 2015 2:14 am
#go and #node both are fast ... tapi untuk komputasi yg tdk melibatkan database, go jauh lebih unggul karena diconvert ke native mesin dulu (compile) sedangkan node menggunakan virtual machine (V8 engine)
Sat, 21 Feb 2015 1:11 am
Amazing #go ... dengan script ini sdh bisa listen client ... #nice
package main 

import (
    "fmt"
    "net/http" ) 

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hi :) ... I love %s!", r.URL.Path[1:])
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}
http://webkoe.net:8080
Sat, 21 Feb 2015 12:35 am
mau nyoba #go untuk web development #project #webkoe
Sat, 21 Feb 2015 12:34 am
#go is in #webkoe server
Thu, 12 Feb 2015 6:55 am
Baca baca e-book #go , penasaran kenapa tjholowaychuk (maatermind yg misterius) beralih ke #go begitu saja ... statementnya yg paling ane ingat ttg #javascript aka. #nodejs "callback hell". Dan memang ane sudah merasakannya ... #fyuuh #project