Add DB2 to maven project

Unfortunately adding below dependencies to pom.xml is not enough for db2 since there is no public maven repository for it.
We need to add the jar files to our local maven repository. So if my directory structure looks like this:
├── MyMavenProject
│   ├── pom.xml
│   └── src
└── db2-connector
    ├── db2jcc4.jar
    └── db2jcc_license_cu.jar
Then I can do:
cd MyMavenProject

mvn install:install-file -Dfile=../db2-connector/db2jcc4.jar -DgroupId=com.ibm.db2.jcc -DartifactId=db2jcc4 -Dversion=10.1 -Dpackaging=jar -DgeneratePom=true -DcreateChecksum=true

mvn install:install-file -Dfile=db2jcc_license_cu.jar -DgroupId=com.ibm.db2 -DartifactId=db2jcc_license_cu -Dversion=10.5 -Dpackaging=jar -DgeneratePom=true -DcreateChecksum=true

Done! For Reference this is what I always have in my pom.xml so I remember what to do :)
<!-- Install previously: -->
<!-- mvn install:install-file -Dfile=../db2-connector/db2jcc4.jar -DgroupId=com.ibm.db2.jcc -DartifactId=db2jcc4 -Dversion=10.1 -Dpackaging=jar -DgeneratePom=true -DcreateChecksum=true -->
<!-- Install previously: -->
<!-- mvn install:install-file -Dfile=db2jcc_license_cu.jar -DgroupId=com.ibm.db2 -DartifactId=db2jcc_license_cu -Dversion=10.5 -Dpackaging=jar -DgeneratePom=true -DcreateChecksum=true -->


Some DB2 commands

Switch to db2inst1 user

su - db2inst1

Start and stop DB. All db2 commands should be between these two


db2 ...


List all databases in the instance


Connect to a certain database

db2 connect to MY_DATABASE_NAME

List all tables in all schemas

db2 list tables for all

List tables in a certain schema

db2 list tables for schema DB2INST1

Do a SQL Query

db2 "select * from MY_TABLE"


MapView for the busy

I has been a while since I don't do iOS. These are my notes, hopefully helpful for others.

Just show me code

Here you go. Full working example :)

Show a map

Very simple, create a view controller with a MapKit MapView object and you are done. A MapView without delegate is still usable however I set it (in interface builder) for future use.
import UIKit
import MapKit

class MapViewController: UIViewController, MKMapViewDelegate {
    @IBOutlet fileprivate weak var mapView: MKMapView!

Get and show current location

Get current location is a task of CoreLocation. We need to receive updates from CoreLocationManagerDelegate so render current location in our mapView. Location itself will be stored in fromLocation and fromLocationAnnotation will be used to represent a pin at such location.
import UIKit
import MapKit
import CoreLocation

class MapInfoDetailViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
    @IBOutlet fileprivate weak var mapView: MKMapView!
    fileprivate var locationManager: CLLocationManager?
    fileprivate var fromLocation: CLLocation?
    fileprivate var fromLocationAnnotation: MKPointAnnotation?
We start the location manager
override func viewDidLoad() {

    // Start location manager
    if CLLocationManager.locationServicesEnabled() {
        locationManager = CLLocationManager()
        locationManager?.delegate = self
        locationManager?.desiredAccuracy = kCLLocationAccuracyBest
Note that in recent versions of iOS we need to add the following to the Info.plist otherwise CoreLocation will not work
<string>🍌Short explanation of why you will require location services here🍌</string>
Here is the method that receives locations updates. This method is called several times in very short intervals
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    guard let location = locations.last else { return }

    fromLocation = location

    if fromLocationAnnotation == nil {
        // First time: Create and add annotation
        fromLocationAnnotation = MKPointAnnotation()
        fromLocationAnnotation!.coordinate = fromLocation!.coordinate
        fromLocationAnnotation!.title = "Current Location"
    } else {
        // Not first time: Update annotation
        fromLocationAnnotation!.coordinate = fromLocation!.coordinate
    mapView.showAnnotations(mapView.annotations, animated: true)

    if location.horizontalAccuracy < 30 {
        // IMO 30m is accurate enough to turn off location services to save battery :)
Previous method adds an MKPointAnnotation to the mapView. MKMapView will render the default annotation view for the given annotation. So far we our current location :)

Customize the pin

To customize the view we need to implement MKMapViewDelegate method. When we add MKAnnotation (usually a MKPointAnnotation) the map view will consult its delegate to see if there is a view for the given annotation. If we return nil or do not implement the delegate method is will draw the default view (a red pin). Usually you want to create a view with some extra information special to the location (For example number of likes for that place, an explanation of the place, etc) and a way to pass data from your model to the view is via a subclass of MKAnnotation. Each MKAnnotationView object will have a reference to an MKAnnotation so we have put data here.
import MapKit

class PlaceAnnotation: MKPointAnnotation {
    var label: String?
To use it instead of creating MKPointAnnotation we use our own:
// Instead of:
// fromLocationAnnotation = MKPointAnnotation()
// We can create our MKAnnotation and pass any data we might need later
let annotation = PlaceAnnotation()
annotation.label = "出発"
fromLocationAnnotation = annotation
The delegate method:
public func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    guard let annotation = annotation as? PlaceAnnotation else {
        // Other annotations will show the default pin
        return nil
    // Place annotation
    var annotationView: MKAnnotationView?
    let reuseId = String(describing: PlaceAnnotation.self)
    annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId)
    if annotationView == nil {
        // Create annotation view
        annotationView = MKAnnotationView(
            annotation: annotation,
            reuseIdentifier: reuseId)
        annotationView?.canShowCallout = true
        annotationView?.image = image(text: annotation.label)
    } else {
        // Update annotation view (update the least possible)
        annotationView?.annotation = annotation
        annotationView?.image = image(text: annotation.label)
    return annotationView
I am using a regular MKAnnotationView and simply customizing the image according the given data (I am creating an UIImage on the fly). In my small app I have just a few annotations so this does not cost me anything. If performance becomes a problem then we should create subclass MKAnnotationView and render things there rather than setting a different UIImage every time, to really reuse it. If you are curious about image(text: annotation.label) check code here.

Get and show location from an address

The act of find coordinates from a address text is called Geo Coding. Happily there is a geocoder class in CoreLocation so lets use it:

fileprivate var toLocation: CLLocation?


func getLocationAndShowRoute(address: String) {
    let geocoder = CLGeocoder()
    geocoder.geocodeAddressString(address) { (placemarks, error) in
        if let error = error {
            print("Geocoder error. " + error.localizedDescription)
        guard let placemark = placemarks?.last else {
            print("Geocoder error. No placemarks found")
        guard let location = placemark.location else {
            print("Geocoder error. No location in placemark")
        // Add location
        let annotation = MKPointAnnotation()
        annotation.coordinate = location.coordinate
        annotation.title = address
        self.toLocation = location

Draw route between two locations

By now we should have two locations:
  • fromLocation: current location found with help of CLLocationManager
  • toLocation: an arbitrary location found by geocoding an address

func showRoute(transportType: MKDirectionsTransportType) {
    guard let from = fromLocation else {
        print("showRoute: no fromLocation")
    guard let to = toLocation else {
        print("showRoute: no toLocation")
    // Search routes in MapKit (Japanese article)
    // http://qiita.com/oggata/items/18ce281d5818269c7281
    let fromPlacemark = MKPlacemark(coordinate: from.coordinate, addressDictionary: nil)
    let toPlacemark = MKPlacemark(coordinate: to.coordinate, addressDictionary: nil)
    let fromItem = MKMapItem(placemark:fromPlacemark)
    let toItem = MKMapItem(placemark:toPlacemark)
    let request = MKDirectionsRequest()
    request.source = fromItem
    request.destination = toItem
    request.requestsAlternateRoutes = false // only one route
    request.transportType = transportType
    let directions = MKDirections(request:request)
    directions.calculate { response, error in
        if let error = error {
            print("Route search error. " + error.localizedDescription)
        guard let route = response?.routes.last else {
            print("Route search error. No routes found")
Full code available here.


Generate PDF documentation from swagger annotations

TL DR;: Check this working example github.com/nacho4d/rest_to_pdf_example


I have a REST (JAX-RS) Java Web App and I use Maven (pom.xml) to build it.
  1. Annotate: Use swagger-annotations to annotate my endpoints.
  2. Generate swagger file: Use the swagger-maven-plugin to generate swagger file from sources
  3. Generate asciidoc file: Use the swagger2markup-maven-plugin to generate asciidoc from swagger file
  4. Generate pdf file: Use asciidoctor-maven-plugin to generate PDF from asciidoc file

0. Preparation

I use a couple of variables: swagger.directory and asciidoctor.directory.
One of the dependencies (markdown_to_asciidoc) of swagger2markup-maven-plugin need below repository:

1. Annotate

Add io.swagger dependency inside dependenciesand start annotating. Basically just add @ApiOperation(value = "Description of endpoint") to each endpoint (or swagger file will contain 0 endpoints). Near @POST, @GET, @DELETE, etc should be fine. See a more detailed example.

2. Generate swagger file

This looks a bit lengthy. but IMO should work for most people. Please adjust locations to have a list of all packages where your endpoints classes are (or swagger file will contain 0 endpoints). This should be inside build/plugins
                    <location>com.company.com.support.service</location>  <!-- Modify for your project -->
                    <title>Some System - API Reference</title>
                    <description>API Reference Description.</description>
                        <name>Apache 2.0</name>
            <?m2e execute onConfiguration?>
I have attached generate goal of this plugin to the compile phase. Hence we should be able to generate target/generated-docs/swagger/swagger.yaml file with:
mvn compile

2. Generate asciidoc file

I set the input to be the output of the previous plugin. Also set the output file (not output directory) so everything is concatenated in a single file. Place this inside build/plugins after swagger-maven-plugin.
I have attached convertSwagger2markup goal of this plugin to the prepare-package phase. Hence we should be able to generate target/generated-docs/asciidocs/ApiDocumentation.adoc file with:
mvn package

3. Generate pdf file

Again, I set the input to be the output of the previous plugin. Place this inside build/plugins after swagger2markup-maven-plugin.
Similarly process-asciidoc goal of this plugin to the prepare-package phase. Hence we should be able to generate target/generated-docs/ApiDocumentation.pdf file with:
mvn package
That is all folks :)




Recently I use flex-box a lot. Flex-box is kind of UIStackView in iOS (Flex-box spec was first than UIStackView). I wrote some samples so I don't forget specially about flex-grow, flex-shrink and flex-basis
JSBin - Flexbox examples - https://jsbin.com/kosajor
-- Sorry I don't have a PRO account so embedded code is not available :(


Compiling with Java 8 in Bluemix

The devops service of Bluemix is nice but at this moment it uses java 7 by default. In order to compile to Java 8 we should modify the pom.xml so maven will try to use java8 when compiling (sames as this post in Japanese):
<project >



We should also modify the configuration of the build stage in the pipeline. We need to set JAVA_HOME so maven can find it (At first I tried to do set JBP_CONFIG_IBMJDK as adviced via the manifest.yaml but it didn't work).
# Set Java8
export JAVA_HOME=~/java8
export PATH="$JAVA_HOME/bin:$PATH"
Now we are ready to go :)


"Password is not encoded" on WAS Liberty server.xml

There are some features in WAS Liberty Server (like apiDiscovery-1.0) that require stuff (like keyStore and basicRegistry) that will require passwords. If those passwords are note encoded we get warnings. It is was not clear to me how to encode a password. These are my notes :)

Encoding a password

We need the securityUtility command from bin directory of the server installation directory. And simply use encode subcommand. Since I am using the default key store defaultKeyStore everything is very simple:
# This is the location eclipse says my server is
cd /Users/ignacio/Documents/ibm/was16.0.0.2/usr
# Go to the bin directory
cd ../bin/

# encode all my passwords
./securityUtility encode keyStorePwd
./securityUtility encode admin
./securityUtility encode member

Update the server.xml

Now, instead of passwords in plain text we copy and paste above results. (See my full server.xml)


    <keyStore id="defaultKeyStore" password="{xor}NDomDCswLToPKDs=" /> <!-- password="keyStorePwd" -->

        <user name="admin" password="{xor}PjsyNjE"/>
        <user name="member" password="{xor}MjoyPTot"/>
        <group name="admins">
            <member name="admin"/>
        <group name="member">
            <member name="member"/>



voilà! no warnings -- So much better :)

PS: defaultKeyStore 's password must be "keyStorePwd" other password didn't work for me. I can't remember where exactly I got it but it was a site from IBM documentation somewhere in the past.

Hold on, I don't know where is my server installation directory!
In case you installed via eclipse and forgot where it was installed, go the server properties and check the location.

More references


Remove unnecessary files from java web application war file

I usually use Visual Code for coding in javascript and other client-side development. That means that I usually have .vscode/launch.json, .vscode/launch.json and jsconfig.json which are good for development but not needed in the final war file (created when doing mvn -B package)
├── .vscode/
│   ├── launch.json
│   └── settings.json
├── WEB-INF/
├── css/
│   └── ...
├── images/
│   └── ...
├── index.html
├── js/
│   └── ...
└── jsconfig.json
Below piece should be added in the pom.xml to tell maven to exclude certain files. When the start (*) is not enough we can use %regex[ ]. More details: Maven war plugin - including/excluding files from war.

          <!-- Exclude configuration files for Visual Code editor -->
          <!-- Exclude documentation and other unnecessary files from d3.js -->




I realized all code and stuff I write here does not have a license. I never really thought of such necessity since code I write here are usually just chunks of code, not finished products. But some people might mentioned recently.
So today I am releasing all this work under the BSD Zero Clause License (0BSD).

Basically, it allows unlimited freedom with the software without the requirements to include the copyright notice, license text, or disclaimer in either source or binary forms.
Copyright (C) 2016 by Guillermo Ignacio Enriquez Gutierrez <nacho4d@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.

More about the 0BSD: Fun read about 0BSD:


javax.json.Json めんどくさすぎる

var jsonObject = JSON.parse("{\"key\":\"value\"}");
var jsonArray = JSON.parse("[1,true,\"word\"]");
var jsonString = JSON.stringify({key:"value"});
のjavascriptみたいに一行でString ⇄ JsonObject変換したいけど javax.json.JsonのAPIがめんどくさすぎる。特にJsonWriterとか使わない使いたくない場合。

Lazy Man approach

使い方はjsに少し似ていて lazyなおれにとってはマシかと。。。
JsonObject jsonObject = JsonUtils.parse("{\"key\":\"value\"}");
JsonArray jsonArray = JsonUtils.parseArray("[1,true,\"word\"]");
String jsonString = JsonUtils.stringify(jsonObject);


使い方をいつもわすれるので ちょっとメモを


基本的に Json.createObjectBuilder().xyz.build()Json.createArrayBuilder().abc.build()でオブジェクトやアレーを入れっこ作っていく。xyzとabcとはadd(...)関数のこと
  keyString: "String",
  keyBoolean: true,
  keyArraySimple: [
  keyArrayObject: [{
      lang: "ja",
      where: "どこ"
      lang: "es",
      where: "donde"
  keyObject: {
    git: "svn",
    github: "sourceforge"
  keyNull: null
JsonObject json = Json.createObjectBuilder()
        .add("keyString", "string")
        .add("keyBoolean", true)
        .add("keyArraySimple", Json.createArrayBuilder()
        .add("keyArrayObject", Json.createArrayBuilder()
                        .add("lang", "ja")
                        .add("where", "どこ").build())
                        .add("lang", "es")
                        .add("where", "sourceforge").build()))
        .add("keyObject", Json.createObjectBuilder()
                .add("git", "svn")
                .add("github", "sourceforge").build())
注意 JsonObjectJsonArrayはinmutable。mutateできるのはJsonObjectBuilderJsonArrayBuilderの時点までだ。つまり.build()メソッドの直前まで。


例えば JsonArrayJsonObjectの中身が固定ではないとき getHogeHogeしてClassCastExceptionをキャッチするより get() してから getValueType() を行う方がよさそう.
JsonArray jsonArray = Json.createArrayBuilder()
         .add("some string")
for (int i = 0; i < jsonArray.size(); ++i) {
    JsonValue value = jsonArray.get(i);
    switch (value.getValueType()) {
    case STRING:
        String someString = jsonArray.getString(i);
    case ARRAY:
        boolean positive = jsonArray.getBoolean(i);
    case NULL:


リクエストのボディをStringにしてからまたJsonObjectにする方がめんどくさい。一発でreaderから直接JsonObjectしよう。書き出しのときは 一旦Stringにしてからじゃないやりかたを今のところ思いつかない。
public class MyServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

        // Only needed when client does not set it properly. 
        // IMO, Ideally this should not be needed

        // リクエストボディを読込
        JsonReader bodyJsonReader = Json.createReader(new BufferedReader(request.getReader()));
        JsonObject bodyJsonObject = bodyJsonReader.readObject();

        // リスポンスを返却
        String jsonString = JsonUtils.stringify(Json.createObjectBuilder.build());


Cookie config in servlet web app

I want to change session cookie name, make it secure and httpOnly. So, apparently this should be done via the web.xml file.
Based in Servlet Programming techniques - cookie-config (Japanese) I edited the src/main/webapp/WEB-INF/web.xml file:
<web-app version="3.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemalocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">


Now we have a customized session cookie:
curl -D - -o /dev/null http://localhost:9080/MyContext
X-Powered-By: Servlet/3.1
Set-Cookie: SASSESSION=0000GEg4qyTVnFKTdrdFjUC8eK0:5e81c98f-2566-49b3-9d72-b0efc4489ff8; Path=/; Secure; HttpOnly



Cloudant Analizers

The other day I rewrote CloudanDB (Which is in Japanese 日本語) and realized that some things were not working because of the analizer I was using. So this post is about them.

What are Cloudant Analizers?

From the official documentation:
Analyzers are settings which define how to recognize terms within text. This can be helpful if you need to index multiple languages.
I decided to try some of the analyzers and put my results here. Test text has two completely different languages (English and Japanese) and some other symbols which I think it is enough to find out how different analysers behave.

How to test Analizers

The _search_analyze API is for this purpose
echo '{"analyzer": "classic","text": "Evening of the seventh"}' > $FILE

# Use _search_analyze
curl -X POST ${CLOUDANT}/_search_analyze  -H 'Content-Type: application/json' --data @${FILE}


Today is a Japanese festival Tanabata so I will use a piece of this romantic song I like very much Suspicious Mind - Elvis Presley and a part of its japanese translation I found here
We're caught in a trap\n
I can't walk out\n
Because I love you too much baby♬.\n
Sent by nacho@email.com at 2016-07-07 18:00:29 +0900 ★\n
2016年7月7日18時0分29秒にnacho@email.jpより ★
I added new lines \n, ♬★ marks, an email and a timestamp to make it more interesting ;-]


AnalyzerResult tokensLength
classic["we're", "caught", "trap", "i", "can't", "walk", "out", "because", "i", "love", "you", "too", "much", "baby", "sent", "nacho@email.com", "2016-07-07", "18", "00", "29", "0900", "は", "ま", "っ", "た", "罠", "か", "ら", "出", "ら", "れ", "な", "い", "ん", "だ", "ほ", "ん", "と", "に", "君", "に", "首", "っ", "た", "け", "な", "ん", "だ", "2016", "年", "7", "月", "7", "日", "18", "時", "0", "分", "29", "秒", "に", "nacho@email.jp", "よ", "り"]64
email["we're", "caught", "trap", "i", "can't", "walk", "out", "because", "i", "love", "you", "too", "much", "baby", "sent", "nacho@email.com", "2016", "07", "07", "18", "00", "29", "0900", "は", "ま", "っ", "た", "罠", "か", "ら", "出", "ら", "れ", "な", "い", "ん", "だ", "ほ", "ん", "と", "に", "君", "に", "首", "っ", "た", "け", "な", "ん", "だ", "2016", "年", "7", "月", "7", "日", "18", "時", "0", "分", "29", "秒", "に", "nacho@email.jp", "よ", "り"]66
keyword["We're caught in a trap\nI can't walk out\nBecause I love you too much baby♬.\nSent by nacho@email.com at 2016-07-07 18:00:29 +0900 ★\nはまった罠から\n出られないんだ\nほんとに君に首ったけなんだ♬.\n2016年7月7日18時0分29秒にnacho@email.jpより ★"]1
simple["we", "re", "caught", "in", "a", "trap", "i", "can", "t", "walk", "out", "because", "i", "love", "you", "too", "much", "baby", "sent", "by", "nacho", "email", "com", "at", "はまった罠から", "出られないんだ", "ほんとに君に首ったけなんだ", "年", "月", "日", "時", "分", "秒にnacho", "email", "jpより"]35
standard["we're", "caught", "trap", "i", "can't", "walk", "out", "because", "i", "love", "you", "too", "much", "baby", "sent", "nacho", "email.com", "2016", "07", "07", "18", "00", "29", "0900", "は", "ま", "っ", "た", "罠", "か", "ら", "出", "ら", "れ", "な", "い", "ん", "だ", "ほ", "ん", "と", "に", "君", "に", "首", "っ", "た", "け", "な", "ん", "だ", "2016", "年", "7", "月", "7", "日", "18", "時", "0", "分", "29", "秒", "に", "nacho", "email.jp", "よ", "り"]68
whitespace["We're", "caught", "in", "a", "trap", "I", "can't", "walk", "out", "Because", "I", "love", "you", "too", "much", "baby♬.", "Sent", "by", "nacho@email.com", "at", "2016-07-07", "18:00:29", "+0900", "★", "はまった罠から", "出られないんだ", "ほんとに君に首ったけなんだ♬.", "2016年7月7日18時0分29秒にnacho@email.jpより", "★"]29
english["we'r", "caught", "trap", "i", "can't", "walk", "out", "becaus", "i", "love", "you", "too", "much", "babi", "sent", "nacho", "email.com", "2016", "07", "07", "18", "00", "29", "0900", "は", "ま", "っ", "た", "罠", "か", "ら", "出", "ら", "れ", "な", "い", "ん", "だ", "ほ", "ん", "と", "に", "君", "に", "首", "っ", "た", "け", "な", "ん", "だ", "2016", "年", "7", "月", "7", "日", "18", "時", "0", "分", "29", "秒", "に", "nacho", "email.jp", "よ", "り"]68
spanish["we'r", "caught", "in", "trap", "i", "can't", "walk", "out", "becaus", "i", "love", "you", "too", "much", "baby", "sent", "by", "nach", "email.com", "at", "2016", "07", "07", "18", "00", "29", "0900", "は", "ま", "っ", "た", "罠", "か", "ら", "出", "ら", "れ", "な", "い", "ん", "だ", "ほ", "ん", "と", "に", "君", "に", "首", "っ", "た", "け", "な", "ん", "だ", "2016", "年", "7", "月", "7", "日", "18", "時", "0", "分", "29", "秒", "に", "nach", "email.jp", "よ", "り"]71
japanese["we", "re", "caught", "in", "a", "trap", "i", "can", "t", "walk", "out", "because", "i", "love", "you", "too", "much", "baby", "sent", "by", "nacho", "email", "com", "at", "2016", "07", "07", "18", "00", "29", "0900", "はまる", "罠", "出る", "ほんとに", "君", "首ったけ", "2", "0", "1", "6", "年", "7月", "7", "日", "1", "8", "時", "0", "分", "2", "9", "秒", "nacho", "email", "jp"]56
cjk["we're", "caught", "trap", "i", "can't", "walk", "out", "because", "i", "love", "you", "too", "much", "baby", "sent", "nacho", "email.com", "2016", "07", "07", "18", "00", "29", "0900", "はま", "まっ", "った", "た罠", "罠か", "から", "出ら", "られ", "れな", "ない", "いん", "んだ", "ほん", "んと", "とに", "に君", "君に", "に首", "首っ", "った", "たけ", "けな", "なん", "んだ", "2016", "年", "7", "月", "7", "日", "18", "時", "0", "分", "29", "秒に", "nacho", "email.jp", "より"]63
arabic["we're", "caught", "in", "a", "trap", "i", "can't", "walk", "out", "because", "i", "love", "you", "too", "much", "baby", "sent", "by", "nacho", "email.com", "at", "2016", "07", "07", "18", "00", "29", "0900", "は", "ま", "っ", "た", "罠", "か", "ら", "出", "ら", "れ", "な", "い", "ん", "だ", "ほ", "ん", "と", "に", "君", "に", "首", "っ", "た", "け", "な", "ん", "だ", "2016", "年", "7", "月", "7", "日", "18", "時", "0", "分", "29", "秒", "に", "nacho", "email.jp", "よ", "り"]72


Some interesting things to note:
  • The only notorious difference between standard and classic is the treat of "2016-07-07" and emails. standard got the emails wrong.
  • email looks like standard but with the emails right
  • whitespace looks like a good option when text has symbols (ie.: ♬, ★). There are still there as tokens!
  • keyword just one token. I think it would be useful for exact match searches
  • None of the analyzers, not even keyword preserved the new line character \n.
  • Several occurrences of the same string are valid. (ie.: "i" and "★")
  • I find funny "we're" became "we'r" when english was used. Also "baby" became "babi".
  • Japanese words were tokenized as characters in english. Makes really hard (if possible) to do a useful search using Japanese
  • I am depressed that spanish didn't get my name "nacho" right. For some reason it became "nach". I guess it is trying to get the root of it, since there is also nacha, nachito, nachita, nachos, nachas, etc.
  • cjk (chinese/japanese/korean) complete broke the japanese words. I know it is hard to parse Japanese but cjk is not helping at all here.
  • I have no idea why I tried arabic I literally have 0 knowledge of the language to comment something about it.

More on "nacho"
curl -X POST ${CLOUDANT}/_search_analyze  -H 'Content-Type: application/json' -d '{"analyzer":"spanish", "text":"nacho"}'
curl -X POST ${CLOUDANT}/_search_analyze  -H 'Content-Type: application/json' -d '{"analyzer":"spanish", "text":"nachos"}'
curl -X POST ${CLOUDANT}/_search_analyze  -H 'Content-Type: application/json' -d '{"analyzer":"spanish", "text":"Nachos"}'
🇵🇪 Creo que voy a reclamar a los de Cloudant o Apache para que mi nombre salga bien! Ahorita mismo!!🇵🇪 (O sera que esta sacando la raiz de la palabra?)


Cordova application skeleton

Create application

Create it using the cordova command. We can get more help with: cordova create -help.

# cordova create <PATH> [ID [NAME [CONFIG]]] [options]
cordova create hello com.example.hello HelloWorld
cd hello

Next, we add platforms. Here I only add iOS and Android but there are a lot more.

cordova platform add ios --save
cordova platform add android --save

Working with git

I am not really into Cordova applications but as any other platforms I tend to have my repositories the smallest possible. There should be a command that downloads all dependencies so all users are able to have the same environment in the end. For such reason I ignore everything in platforms/ and plugins/ directories

My .gitignore:


The command that will make my environment ready will be:

cordova prepare

It copies files for specified platforms, or all platforms, so that the project is ready to build with each SDK.

So far our file structure will look like this:

├── config.xml
├── hooks/
│   └── README.md
├── platforms/
│   ├── android/
│   ├── ios/
│   └── platforms.json
├── plugins/
│   ├── android.json
│   ├── cordova-plugin-whitelist/
│   ├── fetch.json
│   └── ios.json
└── www/
    ├── css/
    ├── img/
    ├── index.html
    └── js/

Running the app

On iOS

Install ios-sim to be able to lunch the simulator. This is a one time task.

npm install -g ios-sim

Build and run

cordova build ios # build Xcode project
cordova emulate ios # launch simulator

Using Xcode

Command cordova build ios creates an Xcode project. This is quite useful specially for debbuging plugins.

 open -a Xcode platforms/ios/HelloWorld.xcodeproj/

On Android

Build and run

cordova build android
cordova run android # Run on connected device
cordova emulate android # Run on simulator

Using Android studio

Command cordova build android, creates an Android Studio project. Again, this is quite useful for debbuging plugins.

open -a "Android Studio" platforms/android/


Table of contents generator in javascript

There are a lot of approaches arround. Lets add one more to the pile:


No need of jquery or other stuff. Just plain and simple vanilla js ;]

function TableOfContents(tocId, containerId) {
    var toc = document.getElementById(tocId);
    toc.innerHTML = "";
    toc.className += " toc";
    var container = containerId ? document.getElementById(containerId) : toc.parentElement;
    var headings = [].slice.call(container.querySelectorAll('h1, h2, h3, h4, h5, h6'));
    var closeLevel = function(e, levels) {
        for (var i = 0; i < levels && e.parentElement && e.parentElement.parentElement; i++) {
            e = e.parentElement.parentElement;
        return e;
    var createLiWithAnchor = function(anchor, heading) {
        var li = document.createElement("li");
        var a = document.createElement("a");
        a.href = "#" + anchor;
        a.textContent = heading.textContent;
        heading.innerHTML = "<a name='" + anchor + "'>" + heading.textContent + "</a>";
        heading.className += " no-decoration";
        return li;
    var prevLevel = 0;
    var root, curr;
    headings.forEach(function (heading, index) {
        var tag = heading.tagName.toLowerCase();
        var curLevel = parseInt(tag.replace(/[^\d]/i, ""));// get number from h1, h2, h3,... tags
        var anchor = heading.textContent.replace(/\r?\n|\r/g, "").replace(/\s/, "_"); // remove all new lines and replace spaces with underscore
        var li = createLiWithAnchor(anchor, heading);
        if (curLevel > prevLevel) {
            // open 1 ul and add 1 li
            if (!curr) {
                root = document.createElement("ol");
            } else {
                var ul = document.createElement("ul");
        } else if (curLevel === prevLevel) {
            // add 1 new li next to current li
        } else if (curLevel < prevLevel) {
            // close n ul, add one 1 li as a sibling of the ancestor
            var ancestor = closeLevel(curr, prevLevel - curLevel);
        curr = li;
        prevLevel = curLevel;
If you are pasting this into blogger, the function must be XML escaped. This site helped a lot


So it looks a bit better.
/* ----- TOC ----- */
.toc {
background-color: #dadada;
border: gray solid 1px;
margin-bottom: 1em;
.toc .toc-title {
margin-left: 1em;
.post-body .no-decoration,
.post-body .no-decoration a {
text-decoration: none;
color: black;


Prepare a container

<div id="mytoc"></div>

Call the script

<script type="text/javascript">
TableOfContents("mytoc", "articleId");
If you using blogger just put the container div at the top of your post and omit the last parameter, the function will assume the article is the parent of the TOC container.



Gitlab merge request from terminal

This is not a fully automated command for making merge request, instead it is tiny helper command that will take you to the right place in the browser to complete your merge request with one click.

BTW, Why not to do everything with Gitlab API?
It is fully possible. Actually I was trying to do so but in the way I realized that is not what I need because in a merge request you want to set a description (writing a description in the terminal is not better than doing it in the browser), you also will want to assign somebody to review your code (searching for other gitlab users in the terminal is not easier than the browser pulldown menu), you probably want to have a milestone, and maybe other details...

If you still want to do it fully programatically I have some hints at the end of this post :p


#!/usr/bin/env bash -e

# Get host, group and repository names
REMOTE_LINE=`git remote get-url --push origin`
if [[ $REMOTE_LINE == "git@"* ]]; then
    # git: git@my.gitlab.host.com:my-group/project.git
    HOST=$(expr "$REMOTE_LINE" : 'git@\(.*\):.*')
    GROUP=$(expr "$REMOTE_LINE" : 'git@.*:\(.*\)\/.*')
    PROJECT_NAME=$(expr "$REMOTE_LINE" : 'git@.*:.*\/\(.*\)\.git')
elif [[ $REMOTE_LINE == "https://"* ]]; then
    # https: https://my.gitlab.host.com/my-group/project.git
    HOST=$(expr "$REMOTE_LINE" : 'https:\/\/\([^\/]*\)\/.*')
    GROUP=$(expr "$REMOTE_LINE" : 'https:\/\/[^\/]*\/\(.*\)\/.*')
    PROJECT_NAME=$(expr "$REMOTE_LINE" : 'https:\/\/.*\/\(.*\)\.git')
    echo Unknown protocol from $REMOTE_LINE
    exit 1

# Get current branch name
BRANCH=$(git rev-parse --abbrev-ref HEAD)

# Create new merge request from current branch to default branch
# (Add `-a /Applications/Firefox.app` to open it with a specific browser)
open https://${HOST}/${GROUP}/${PROJECT_NAME}/merge_requests/new?merge_request[source_branch]=${BRANCH}


Copy above script as git-mr and place it somewhere in the $PATH and make sure it has executable permissions using chmod
chmod +x ~/.bin/git-mr


git push origin -u feature/myfeature
git mr
(browsers opens and you are just one click away from completing your merge request)

If you still want to do it programatically with Gitlab API, we need a project id an authentication token to be able to call create merge request API.
POST /projects/:id/merge_requests

Get Authentication Token

We can request the user to enter his/her login and password once and store that in the keychain. Below code is how to retrieve a previously stored password from the keychain
# Get credentials
SECOUT=`security 2>&1 find-internet-password -gs ${HOST}`
LOGIN=`expr "$SECOUT" : '.*"acct"="\([^"]*\)"'`
PASSWORD=`expr "$SECOUT" : '.*password: "\([^"]*\)"'`
With such information we can call session API and get the token for the upcomming requests
#Initialize a session
SESSIONOUT=`curl -X POST "https://${HOST}/api/v3/session?login=${LOGIN}&password=${PASSWORD}"`
TOKEN=`expr "$SESSIONOUT" : '.*"private_token":"\([^"]*\)"'`
echo $TOKEN

Get Project ID

I have tried doing ${GROUP}/${PROJECT_NAME} and ${GROUP}%2F${PROJECT_NAME} without luck so I got the project by using project search API. Unfortunately gitlab search API is not very powerful yet so we need to search results and get the id of the project that exactly matches our project. Here I am using jq
PROJECT_ID=$(curl --header "PRIVATE-TOKEN: ${TOKEN}" 'https://${HOST}/api/v3/projects/?search=${PROJECT_NAME}' | jq '.[] | select( .path_with_namespace == '\"${GROUP}/${PROJECT_NAME}\"' ) | .id')
Now we are almost ready!

Call merge_request API

# Disabled code: Get tracking branch name
#BRANCH=$(git rev-parse --abbrev-ref --symbolic-full-name @{u})

# Get remote target branch

curl --header "PRIVATE-TOKEN: ${TOKEN}" -X POST "https://${HOST}/api/v3/projects/${PROJECT_ID}/merge_requests" --data "source_branch=${BRANCH}" --data "target_branch=${TARGET_BRANCH}" --data "title=Implementation of my feature"


Dictionary to JSON string and JSON string to dictionary

Because I always end up Googling NSJSONSerialization and its options...

Dictionary to JSON string

The dictionary is converted to NSData which contains an UTF8 encoded string inside.
let dictionary: [String: AnyObject] = ["nacho": ["1","2","3"] ]
let jsonData = try? NSJSONSerialization.dataWithJSONObject(dictionary, options: NSJSONWritingOptions())
let jsonString = NSString(data: jsonData!, encoding: NSUTF8StringEncoding)
Also it is possible to use .PrettyPrinted

JSON String to Dictionary

The JSON string should be converted to NSData (using UTF8 encoding), then we can create a dictionary from such data.
let jsonString = "{\"nacho\":[\"1\",\"2\",\"3\"]}"
let jsonData = jsonString.dataUsingEncoding(NSUTF8StringEncoding)
let dictionary = try? NSJSONSerialization.JSONObjectWithData(jsonData!, options: .MutableLeaves)
{\n    nacho =     (\n        1,\n        2,\n        3\n    );\n}
In NSJSONReadingOptions there is also .MutableLeaves and .AllowFragments but I barely use them


Registering client filters for JAX-RS ClientBuilder

I write this here so I don't forget some of the goodies in below packages :)
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientRequestFilter;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.Invocation.*;
Helpful Links


public class RequestFilter implements ClientRequestFilter {

    private static final Logger LOG = Logger.getLogger(RequestFilter.class.getName());

    public void filter(ClientRequestContext requestContext) throws IOException {
        LOG.log(Level.INFO, ">> " + requestContext.getMethod() + " " + requestContext.getUri());
        LOG.log(Level.INFO, ">> (body) " + requestContext.getEntity().toString());
        LOG.log(Level.INFO, ">> (headers) " + requestContext.getHeaders().toString());


public class ResponseFilter implements ClientResponseFilter {

    private static final Logger LOG = Logger.getLogger(ResponseFilter.class.getName());

    public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException {
        LOG.log(Level.INFO, "<< " + requestContext.getMethod() + " " + requestContext.getUri());
        LOG.log(Level.INFO, "<< (status) " + responseContext.getStatus());
        LOG.log(Level.INFO, "<< (headers) " + responseContext.getHeaders().toString());

        InputStream entityStream = responseContext.getEntityStream();
        if (entityStream != null) {
            LOG.log(Level.FINER, "<< (body)" + entityStream.toString());


JSONObject body = new JSONObject();
body.put("key", "value");

Client client = ClientBuilder.newClient();
client.register(ResponseFilter.class); // Response logging
client.register(new RequestFilter()); // Request logging

Response response = client.target("https://api.example.com")

if (response.getStatus() == 200) { ... } else { ... }


Setup Liberty Server on Eclipse

Instructions for setting up a Liberty Server in Eclipse Mars 4.5.2 (Eclipse IDE for Java EE Developers). The following instructions assume IBM WebSphere Application Server Liberty Developer Tools Beta has been installed from Eclipse Market Place.

Creating a new Liberty Server

  1. Create a server using the Wizard.
    Click File > New > Server
    Click Next
  2. Select WebSphere Application Server Liberty
    Click Next
  3. Select Install from an archive or repository
    Click Next
  4. Enter the Destination path (This will be the place where the server will live)
    Select Download and install a new runtime environment from ibm.com
    Select WAS Liberty V8.5.5.9 with Java EE 7 Full Support
    Click Next
  5. Click Install for the following bundles:
    • Base Bundle
    • Liberty Core Bundle
    • V9 Bundle for Java EE 7 Full Support
    • V9 Bundle for Java EE 7 Web Profile
    Click Next
  6. Accept the terms
    Click Next
  7. Select Stand-alone server
    Click Next
  8. Enter a name for your server. I usually leave it as defaultServer
    Click Finish
  9. Finally a confirmation alert will show. Now we have our Liberty server installed in Eclipse. Almost ready :)

Adding a simple keyStore

Since we have javaee-7.0 feature enabled we need to add a keystore, otherwise we will not get rid of the following error:

The enabled features require that a keyStore element and a user registry are defined in the server configuration. Use the server configuration editor to add these items.
We can do as the comments and create a properly encoded password but for development we can do just:
<keyStore id="defaultKeyStore" password="keyStorePwd"/>


JAX-RS Maven project for WAS Liberty

So the other day I wrote this, apparently not a good approach these days. This is probably the official (current) way of creating a web app project. The following instructions are specific for WebSphere Application Server Liberty Profile. Much of these information is based on the following sites/posts/answer:

Create a Maven project

This could be created manually, but Eclipse is good at this :)
  1. FileNewMaven Project
  2. Check Use default Workspace location
    Click next
  3. Select the http://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/wasdev/maven/repository Catalog
    Select the com.ibm.tools.archetype webapp-jee7-liberty
    Click next
  4. Enter a Group Id: com.ibm.jp.myproject
    Enter a Artifact Id: myproject
    Enter Package: com.ibm.jp.myproject
    Click Finish
At this point we have created the project but it seems it is a bit broken. At written here we can get rid of the following error by modifying the pom.xml
ArtifactDescriptorException: Failed to read artifact descriptor for com.ibm.tools.target:was-liberty:pom:LATEST: VersionResolutionException: Failed to resolve version for com.ibm.tools.target:was-liberty:pom:LATEST: Could not find metadata com.ibm.tools.target:was-liberty/maven-metadata.xml in local (/Users/paulbastide/.m2/repository)

Modify the pom.xml

  1. To get rid of above error add the following to pom.xml
            <id>maven online</id>
            <name>maven repository</name>
            <id>liberty maven online</id>
            <name>liberty maven repository</name>
  2. Setup to use Dynamic Web Module 3.1 Add the following to pom.xml
    Also we need to make sure 3.1 is setup properly in web.xml (For other versions check Katsumi Kokuzawa's Blog)
    <!DOCTYPE xml>
    <web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        <display-name>Servlet 3.1 Web Application</display-name>
  3. Setup to use Java 7 or 8 (needed for Dynamic Web Module 3.1)
    For Java 7
    For Java 8 we need to use the 3.5.1 version of the plugin

Update the project

After all the changes we just do right click in the project MavenUpdate Project ...
If we check the Project Facets we should have
  • Dynamic Web Module 3.1
  • Java 1.8
  • JAX-RS(Rest Web Services) 2.0

Here is a copy of the full pom.xml and web.xml files :)


Create a JAX-RS maven project and import it into Eclipse

See updated instructions here in this other post

The following instructions work but are Not Recommended since modifying the pom.xml would be useless since those modifications will not be reflected in Eclipse project :(
  1. Create the skeleton
    Instructions taken from Stackoverflow - Maven 3 failed to execute goal apache ...
    mvn archetype:generate \
        -DgroupId={project-packaging} \
        -DartifactId={project-name} \
        -DarchetypeArtifactId=maven-archetype-webapp \
    That will create a {project-name} directory with the contents:
    ├── pom.xml
    └── src
        └── main
            ├── java (This directory will contain all the source code, must be created manually)
            ├── resources
            └── webapp
                ├── WEB-INF
                │   └── web.xml
                └── index.jsp
  2. Import it into eclipse
    FileImportExisting Projects into Workspace and then select {project-name} directory. Once imported, go to project properties and do the following settings:
    1. Setup the facets
      Instructions taken from this article from OPENTONE and adapted for my needs
      • Java 1.8
      • Dynamic Web Project 3.1
      • JAX-RS 2.0
      • Javascript will be selected automatically later. It is not necessary to explicitly select it here
    2. Setup the target runtime
      Select "WebSphere Liberty Profile"


Convert flac to aac with ffmpeg

I write this so I don't forget (Original Superuser thread)
  • Install ffmpeg with libfaac support
    brew reinstall ffmpeg --with-faac;
  • Convert them
    cd flac_directory
    for f in *.flac; do ffmpeg -i "$f" -acodec libfaac -aq 400 "${f%flac}m4a"; done
Certain files will throw an error: [libx264 @ 0x2f08120] height not divisible by 2 (500x489) In such case adding the following option did the trick for me:
-vf "scale=640:-2"
Taken from Stackoverflow - Maintaining ffmpeg aspect ratio


Swift en el servidor con Kitura

Este post es 90% una traducción de esta pagina en Japonés que lo explica muy bien.

Recientemente IBM esta llevando Swift al servidor y para esto ha publicado varias herramientas. Kitura es uno de estas, es un framework para aplicaciones, es open-source y esta basado en Express.js, el popular framework de nodejs.


  1. Instalamos unas dependencias usando homebrew
    brew install http-parser pcre2 curl hiredis
  2. Instalamos el último compilador swift de la página official de Swift.org: Swift - Latest Development Snapshots. No se preocupen, ya esta compilado y viene en un archivo listo para instalar .pkg.
    Luego de la instalación agregamos la siguiente locación al PATH modificando el archivo ~/.bash_profile
    export PATH=/Library/Developer/Toolchains/swift-latest.xctoolchain/usr/bin:$PATH

Nuestro projecto

  1. Creamos un directorio para nuestro proyecto e iniciamos este con el comando swift build
    mkdir swift-sample && cd swift-sample
    swift build --init
  2. Modificamos el archivo Package.swift:
    import PackageDescription
    let package = Package(
        name: "myFirstProject",
        dependencies: [
            .Package(url: "https://github.com/IBM-Swift/Kitura-router.git", majorVersion: 0),
    Y con estos cambios instalamos de nuevo nuestras dependencias:
    swift build
    Algunos se habrán dado cuento que swift build es como un equivalente al npm install en nodejs or bundle install en ruby. Esta vez saldrán mas mensajes y al final terminará en error. Pero no preocuparse, es por que Kitura router depende un una librería en C y el package manager no soporta el linkage C/C++ todavia. Este error tambien esta descrito en el README de Kitura

    ld: library not found for -lcurlHelpers for architecture x86_64
    :0: error: link command failed with exit code 1 (use -v to see invocation)
    :0: error: build had 1 command failures
    error: exit(1): ...
  3. Copiamos el Makefile de Kitura-net. En mi caso es la version 0.3.2, usar la version que cada uno tenga :]
    cp Packages/Kitura-net-0.3.2/Makefile-client Makefile
  4. Ahora ya estamos listos para escribir nuestro codigo!. Modificamos el archivo Sources/main.swift
    import KituraRouter
    import KituraNet
    import KituraSys
    let router = Router()
    router.get("/") { request, response, next in
        response.status(HttpStatusCode.OK).send("Hello, World!")
    let server = HttpServer.listen(8090, delegate: router)
  5. Compilamos nuestro pequeño proyecto
  6. Ejecutamos el archivo ejecutable que acabamos de crear
  7. Ahora vayamos a nuestro explorador o con curl
    curl http://localhost:8090/
    Hello, World!
Por ahora son varios pasos, esperemos con el paso del tiempo todo es sea mas fácil. Yo ya estoy contento con esto!



このようなsvgを表示したい とすると 幾つかのアプローチが考えられる。


一番楽チンで IEでサポートされず無視されるからプロトタイプの時に便利。バックスラッシュで改行可能


.move {
    background-image: url('data:image/svg+xml;utf8,\
    <svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">\
    <g transform="translate(7, 7) rotate(135)">\
    <line x1="-0.5" y1="0" x2="0.5" y2="0" stroke="rgba(255,0,0,0.5)" stroke-width="1"/>\
    <line x1="-2.5" y1="2" x2="2.5" y2="2" stroke="rgba(255,0,0,0.5)" stroke-width="1"/>\
    <line x1="-4.5" y1="4" x2="4.5" y2="4" stroke="rgba(255,0,0,0.5)" stroke-width="1"/>\




<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">
    <g transform="translate(7, 7) rotate(135)">
        <line x1="-0.5" y1="0" x2="0.5" y2="0" stroke="rgba(255,0,0,0.5)" stroke-width="1"/>
        <line x1="-2.5" y1="2" x2="2.5" y2="2" stroke="rgba(255,0,0,0.5)" stroke-width="1"/>
        <line x1="-4.5" y1="4" x2="4.5" y2="4" stroke="rgba(255,0,0,0.5)" stroke-width="1"/>


.move {
    background-image: url("myfile.svg")


クローズブラウザー。リクエストは発生しない。普通の人間は多分読めないし、エンコードして短くなったわけではありません。 おそらくプログラムでコンテンツを作成してbtoaでバイナリに変換してbackground-imageとして表示したい時などに有効な方法でしょうかね

(最初間違って;base64,を書いていなかったから 何も表示されなかったですね。@rikuoさんご教授をありがとうございます!)


.move {
    background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4IiBoZWlnaHQ9IjgiIHZpZXdCb3g9IjAgMCA4IDgiPg0KICAgIDxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDcsIDcpIHJvdGF0ZSgxMzUpIj4NCiAgICAgICAgPGxpbmUgeDE9Ii0wLjUiIHkxPSIwIiB4Mj0iMC41IiB5Mj0iMCIgc3Ryb2tlPSJyZ2JhKDI1NSwwLDAsMC41KSIgc3Ryb2tlLXdpZHRoPSIxIi8+DQogICAgICAgIDxsaW5lIHgxPSItMi41IiB5MT0iMiIgeDI9IjIuNSIgeTI9IjIiIHN0cm9rZT0icmdiYSgyNTUsMCwwLDAuNSkiIHN0cm9rZS13aWR0aD0iMSIvPg0KICAgICAgICA8bGluZSB4MT0iLTQuNSIgeTE9IjQiIHgyPSI0LjUiIHkyPSI0IiBzdHJva2U9InJnYmEoMjU1LDAsMCwwLjUpIiBzdHJva2Utd2lkdGg9IjEiLz4NCiAgICA8L2c+DQo8L3N2Zz4=")


Setup Komodo with Go

Komodo IDE looks great but I needed to explicitly setup some stuff to make if work with Go. I believe these settings are necessary because Komodo cannot read my GOPATH definition which was done in ~/.bash_profile. Also because I didn't define GOBIN as it is not mandatory. Hence various tools are not found :(
  • Add GOPATH environment variable

    echo $GOPATH
  • Set godef and gocode

    # Install godef and gocode if needed
    go get -v github.com/rogpeppe/godef
    go get -u github.com/nsf/gocode
    • I realised that it has been a couple of months I didn't update anything. brew update; brew upgrade gave me go 1.5.1 so I had to re-compile godef again:
      cd $GOPATH/src/github.com/rogpeppe/godef
      go clean -r -i
      go install -v
    Now we can add their paths to Komodo. If go binary is not in the $PATH you can set up manually too but it should be. Their location are ${GOPATH}/bin/godef and ${GOPATH}/bin/gocode
Now restart Komodo :)




general coloriser can be installed via homebrew:
brew install grc


We need a general configuration file ~/.grc/grc.conf where we write a regex and a filename per kind of command we call with grc. For example to colorise:
tail -f messages.log
We will call
grc tail -f messages.log
grc will look for entries in ~/.grc/grc.conf that match tail -f messages.log and use the file of the same entry to color the output

Content of ~/.grc/grc.conf

# Colorise messages.log

Content of ~/.grc/messages.log.conf

# Informative logs
# More informative logs
# Error
# Stacktraces (start with tab)
colours=none, none, red




Ternjs is awesome tool for working with javascript. It provides autocompletion not only for current file but also for the entire project! Ternjs is made of a server (a daemon) that will read javascript files and will return completions/candidates upon client requests. Clients are usually plugins for editors like emacs, sublime text, etc. Here I show the emacs settings

Install server

Via npm is the easiest way:
npm install -g tern

Install the client

  • Install needed packages in emacs
    Install tern-mode and tern-auto-complete via package-list-packages
  • Test server communication
    This is optional. It is to check server and client can establish communication.
    Open a js file on emacs and activate tern mode M-x tern-mode. It will start the server automcatically and a message like the following will appear:
    Making url-show-status local to `http` while let-bound!
  • Make a .tern-project file
    This is optional but recommended. Ternjs uses a .tern-project file to understand the project. Ternjs can be used to do nodejs or the usual client web development. If no .tern-project is found then a fallback will be loaded. You can find more in the manual. This is mine:
        "libs": [
        "loadEagerly": [
  • Tell emacs to use tern always This is also optional. Since you can trigger tern-mode, etc manually. I just prefer to have it automatic:
    ;;; Tern for Javascript
    ;;; http://truongtx.me/2014/04/20/emacs-javascript-completion-and-refactoring/
    ;;; npm install -g tern-autocomplete
    ;;; Tern with Nodejs' Express
    ;;; https://github.com/angelozerr/tern-node-express
    ;;; npm install -g tern-node-express
    (add-hook 'js-mode-hook (lambda () (tern-mode t)))
    (eval-after-load 'tern
         (require 'tern-auto-complete)
    ;;; Start tern-mode automatically when starting js mode
    (add-hook 'js-mode-hook (lambda () (tern-mode t)))
Now we are ready!. Open a js file and you should get autocompletions right away yay!

Working with version control systems

Every time ternjs server starts it will create .tern-port file that contains the port number clients should access. This is a random number and it is recreated automatically. So, unlike .tern-project, .tern-port should NOT be committed.
If you are working with git, add this to .gitignore:
# Ignore ternjs port number



NoSQL系のDBが増えてきて最近 CloudantDB触る機会があって面白いと思ったのでここでメモを書くことにした。 まだまだわからないことだらけなのでこれをまたアップデートしていきたい。


  • SQL系:
    一つのDBの中に複数のテーブルがありえる。テーブルの中にデータがある。テーブルにはスキーマが必須なのでデータに型がある。 検索するにはSQL Queryで書く
  • CloudantDB:
    一つのDBの中に沢山のJSONドキュメントがある。スキーマがない。それぞれのドキュメントにはJSONである以外の制約がないからドキュメントごと全く異なる情報を持つことができる。 ドキュメントIDで検索することができるがsqlクエリみたいなものを実現するにはsearch indexを事前に作る必要がある。クエリーはCloudant Queryといい Lucene Queryベースだそうである。




  • 😵 curlの復習:
    curl <url> \
        -X <method> \
        -H <header> \
        -d <data>
    *メソッドを指定しない場合 通常はGETとなる。


curl ${CLOUDANT}/_all_dbs


car_answersというDBを用意する。 Cloudantのコンソルを使って5つのドキュメントを作ることができるが、ここでAPIで行う
curl ${CLOUDANT}/car_answers -X PUT


上記で作成したDBに次の5つのドキュメントをアップロードする。バルクというAPIを使うために一つのオブジェクトにdocsというキーにドキュメントの配列を定義する必要がある。ここでは_idを自分で指定しているけれども これは後で検索するから見やすさのためだけである。指定しなくてよい。Cloudantがユニークなものを生成してくれて それらをリスポンスに返ってくる。
    "docs": [
            "_id": "1",
            "created_at": "2015-05-15 00:00:00",
            "maker": "Mercedes Benz",
            "モデル": "A 180",
            "answers": {
                "評価": "★★★",
                "その他": "特になし"
          "_id": "2",
          "created_at": "2015-05-16 00:00:00",
          "maker": "Toyota",
          "モデル": "レクサス",
          "answers": {
          "_id": "3",
          "created_at": "2015-05-17 00:00:00",
          "maker": "Honda",
          "モデル": "フィット",
          "answers": {
          "_id": "4",
          "created_at": "2015-05-18 00:00:00",
          "maker": "Mercedes Benz",
          "モデル": "E 250 CABRIOLET",
          "answers": {
          "_id": "5",
          "other": "他とちがうもの"
curl ${CLOUDANT}/car_answers/_bulk_docs -X POST -H "Content-Type: application/json" -d "$json"


バルクではなく、単品でドキュメントをアップロードもちろん可能。バルクと同じくidrevを指定しなくてよくてCloudantはユニークなものを生成してくれて 生成されたidrev番号がリスポンスに返ってくる。
  "created_at": "2016-07-14 00:00:00",
  "maker": "Android",
  "モデル": "N",
  "answers": {
    "評価": "★★★★★",
    "その他": "特になし"
curl ${CLOUDANT}/car_answers/ -X POST -H "Content-Type: application/json" -d "$json"


curl ${CLOUDANT}/car_answers/_all_docs
curl ${CLOUDANT}/car_answers/_all_docs?include_docs=true
curl ${CLOUDANT}/car_answers/_all_docs?include_docs=true&limit=200


ドキュメントのidがわかれば そのドキュメントを簡単に取得できる。例えば、car_answersidが3のドキュメントを取る:
curl ${CLOUDANT}/car_answers/3
{"_id":"3","_rev":"1-fd7d17addf8149d0c522368e69bda27c","created_at":"2015-05-17 00:00:00","maker":"Honda","モデル":"フィット","answers":{"評価":"★★★★★","その他":"すぐ購入したいと思います"}}





条件を指定して検索を実現するのは検索インデックスである。DBに入っているドキュメントはどんなものかCloudantにはわからない、まして、全ドキュメントは同じフォーマットである保証もない。キーワードで検索したいときに ドキュメントのどのフィルドをどのように扱えばいいかを決めるのは検索インデックスである。検索インデックスは必ずデザインドキュメントの中にあり、デザインドキュメントに複数の検索インデックスが存在しえる。


他のドキュメントと同じくAPIで作成可能だが 今回はCloudantDBのコンソルで作成する。car_answersというDBを選択しAll Design Docsの➕ボタンを選択しNew Search Indexを選ぶ。そしてCreate Search Indexという画面が表示される。

Create Search Indexの入力フィルドの説明
  • Save to Design Document
  • Index name
  • Search index function
  • Analyzer
    例えばドキュメント1を処理した場合は"Mercedes Benz"というストリングがインデックスされる。"Mercedes Benz"を一つのストリングとして扱う("Keyword")か英語の文法を使って単語で分けるか日本語の文法で分けるかUnicode Text Segmentationアルゴリズム("Standard")で分けるかなど。アナライザーによって検索でドキュメントがヒットするかしないか変わる。より詳細は[Cloudant/For Developers/Search Indexes/Analyzers]を参照。


// インデックス名:car
function (doc) {
    index("brand", doc.maker);

curl ${CLOUDANT}/car_answers/_design/search/_search/car?q=brand:Honda

curl ${CLOUDANT}/car_answers/_design/search/_search/car?q=brand:Mercedes%20Benz
curl -v ${CLOUDANT}/car_answers/_design/search/_search/car?q=brand:Mercedes%20Benz\&limit=1\&include_docs=true
> GET /car_answers/_design/search/_search/car?q=brand:Mercedes%20Benz&limit=1&include_docs=true HTTP/1.1
{"total_rows":2,"bookmark":"g2wAAAABaANkAB5kYmNvcmVAZGI1LmlibTAwOS5jbG91ZGFudC5uZXRsAAAAAm4EAAAAAIBuBAD___-famgCRj-czh4AAAAAYQBq","rows":[{"id":"1","order":[0.028130024671554565,0],"fields":{},"doc":{"_id":"1","_rev":"1-a408ef0c09d5b0aaec96b87e04e049de","created_at":"2015-05-15 00:00:00","maker":"Mercedes Benz","モデル":"A 180","answers":{"評価":"★★★","その他":"特になし"}}}]}


// インデックス名:car2
function (doc) {
    if (typeof doc.maker === 'undefined') {
        // makerというフィルドをもっていないドキュメントを相手にしない. 
    if (doc.created_at) {
        // 日付で検索したい。例: q=created_at:2015-09-25 11:30:58 ただし日付の部分をエスケープが必要
        index("created_at", doc.created_at, {"store": true});

        // 日付で楽に検索したい。例: q=20150925113058
        index("created", parseInt(doc.created_at.replace(/[^0-9]/g, ''), 10), {"store": true});
    if (doc["モデル"]) {
        // 日本語キーで検索は可能だがエスケープが必要。これで楽にできる。「モデル」の代わりに「model」で検索可
        index("model", doc["モデル"], {"store": true});

    if (doc.answers && doc.answers["評価"]) {
        // 評価で検索したい。例:q=stars:★★★ ただし★をエスケープしなければならない
        var stars = doc.answers["評価"];
        index("stars", stars, {"store": true});

        // 評価で楽に検索したい。例:q=stars_num:3
        index("stars_num", (stars.match(/★/g) || []).length);

    if (doc.answers["その他"]) {
        // コメントなどで検索したい
        index("comment", doc.answers["その他"], {"store": true, "index": false});
Javascriptの標準の挙動だが、関数のどっかでExceptionが発生するとそれ以降は実行されなくて インデックス化されないので 検索でヒットしないことがある。関数のよくチェックすること。


詳細は[Cloudant/For Developers/Search Indexes/Options]に書かれてあるけど、まとめると次のようになる
キー 意味 デフォルト
store 検索結果に値を含むかどうか。 false
index 検索インデックスに入れるかどうか。 true
facet faceting機能をオンにするかどうか。今回は使わない false
boost 検索結果の中で優先度を上げる係数。今回は使わない 1.0


まずは({"store": true}を付けた)モデルで検索すると
curl -v ${CLOUDANT}/car_answers/_design/search/_search/car2?q=model:CABRIOLET
> GET /car_answers/_design/search/_search/car2?q=model:CABRIOLET HTTP/1.1
{"total_rows":1,"bookmark":"g2wAAAABaANkAB5kYmNvcmVAZGI4LmlibTAwOS5jbG91ZGFudC5uZXRsAAAAAm4EAAAAAOBuBAD_____amgCRj_Do3oAAAAAYQBq","rows":[{"id":"4","order":[0.1534264087677002,0],"fields":{"stars":"★★","model":"E 250 CABRIOLET","comment":"イメージしていたものと少し違った","created_at":"2015-05-18 00:00:00"}}]}
CloudantDBのコンソルで インデックスを簡単に試すことができる。URL全部書く必要がなくて Cloudant Queryの部分のみ、いろいろ試すには便利だね
curl ${CLOUDANT}/car_answers/_design/search/_search/car2?q=stars_num:2
{"total_rows":1,"bookmark":"g2wAAAABaANkAB5kYmNvcmVAZGI3LmlibTAwOS5jbG91ZGFudC5uZXRsAAAAAm4EAAAAAOBuBAD_____amgCRj_wAAAAAAAAYQBq","rows":[{"id":"4","order":[1.0,0],"fields":{"stars":"★★","model":"E 250 CABRIOLET","comment":"イメージしていたものと少し違った","created_at":"2015-05-18 00:00:00","created":20150518000000.0}}]}

Official docsメモ
The following characters require escaping if you want to search on them;
+ - && || ! ( ) { } [ ] ^ " ~ * ? : \ /
Escape these with a preceding backslash character. https://cloudant.com/for-developers/search/


ここからエスケープがかなりわけがわからなくなるのでcurlの--data-urlencodeオプションでクエリエンコーディングをする。そして-Gオプションで urlに付ける。さらに-vでverboseをオンにして実際に叩かれたURLの確認ができる。
curl -v -G ${CLOUDANT}/car_answers/_design/search/_search/car2 --data-urlencode 'q=model:"フィット"'
> GET /car_answers/_design/search/_search/car2?q=model%3A%22%E3%83%95%E3%82%A3%E3%83%83%E3%83%88%22 HTTP/1.1
{"total_rows":1,"bookmark":"g2wAAAABaANkAB5kYmNvcmVAZGI3LmlibTAwOS5jbG91ZGFudC5uZXRsAAAAAmJgAAAAYn____9qaAJGP9OjegAAAABhAGo","rows":[{"id":"3","order":[0.3068528175354004,0],"fields":{"stars":"★★★★★","model":"フィット","comment":"すぐ購入したいと思います","created_at2":"2015-05-1700:00:00","created_at":"2015-05-17 00:00:00","created":20150517000000.0}}]}
curl -v -G ${CLOUDANT}/car_answers/_design/search/_search/car2 --data-urlencode 'q=stars:"★★"'
> GET /car_answers/_design/search/_search/car2?q=stars%3A%22%E2%98%85%E2%98%85%22 HTTP/1.1

その理由はAnalyserのstandardにある。AnalyzerについてCloudant Analizersにの述べているように standardで"★★"というストリングをトークン化しようとするとトークンの数がゼロなのでstandardで記号を決してヒットしない。別のインデックスを作っておく必要がある。この場合はkeywordもしくはwhitespaceがいいかと思う。


curl -v -G ${CLOUDANT}/car_answers/_design/search/_search/car2 --data-urlencode 'q=created:[20150501000000 TO 20160705235959]'
> GET /car_answers/_design/search/_search/car2?q=created%3A%5B20150501000000%20TO%2020160705235959%5D HTTP/1.1

{"total_rows":4,"bookmark":"g1AAAAELeJzLYWBgYMlgTmGQS0lKzi9KdUhJMtHLTMo1MLDUS87JL01JzCvRy0styQGqY0pkSJL___9_VgaTm_0HBjBIZEDVbIZTc1ICkEyqJ6Aft-V5LCD1DUAKaMR88twAMeMBxAw0d2QBADHUTsY","rows":[{"id":"2","order":[1.0,0],"fields":{"stars":"★★★★","model":"レクサス","stars2":4.0,"comment":"よかった","created_at":"2015-05-16 00:00:00","created":20150516000000.0}},{"id":"3","order":[1.0,0],"fields":{"stars":"★★★★★","model":"フィット","stars2":5.0,"comment":"すぐ購入したいと思います","created_at":"2015-05-17 00:00:00","created":20150517000000.0}},{"id":"1","order":[1.0,0],"fields":{"stars":"★★★","model":"A 180","stars2":3.0,"comment":"特になし","created_at":"2015-05-15 00:00:00","created":20150515000000.0}},{"id":"4","order":[1.0,0],"fields":{"stars":"★★","model":"E 250 CABRIOLET","stars2":2.0,"comment":"イメージしていたものと少し違った","created_at":"2015-05-18 00:00:00","created":20150518000000.0}}]}


この辺になると またエスケープがややこしすぎてわけわからなすぎる。検索したいのは2015-05-01 00:00:00ストリングなので"で囲む。内容の:-をエスケープが必要。しかし 上記と同じレンジを指定しているのに結果が違う。なぜだろう。スペースが怪しいと思う。
この場合は完全マッチの検索に近いからkeywordwhitespaceがいいかもしれないね。AnalyzerについてCloudant Analizersに書いた。 とりあえず有効なqueryのようだが 期待しているものではない
curl -v -G ${CLOUDANT}/car_answers/_design/search/_search/car2 --data-urlencode 'q=created_at:["2015\-05\-01 00\:00\:00" TO "2016\-07\-05 23\:59\:59"]'
> GET /car_answers/_design/search/_search/car2?q=created_at%3A%5B%222015%5C-05%5C-01%2000%5C%3A00%5C%3A00%22%20TO%20%222016%5C-07%5C-05%2023%5C%3A59%5C%3A59%22%5D HTTP/1.1

{"total_rows":2,"bookmark":"g1AAAACPeJzLYWBgYMpgTmGQT0lKzi9KdUhJMjTRy0zKNTCw1EvOyS9NScwr0ctLLckBKcxjAZIMC4DU____92dlMLnZf2AAg0QGkCFycEPMCZjxAGLGfxQzGLMAarcpYw","rows":[{"id":"7fbfa0bbc27b8ab664d64cde5d00b421","order":[1.0,0],"fields":{"stars":"★★★★★","model":"N","stars2":5.0,"comment":"特になし","created_at":"2016-07-14 00:00:00","created":20160714000000.0}},{"id":"c4d9e99028d5b4016ef008768bfee9a6","order":[1.0,1],"fields":{"stars":"★★★★★","model":"N","stars2":5.0,"comment":"特になし","created_at":"2016-07-14 00:00:00","created":20160714000000.0}}]}


* Multiple Analizersを持つインデックスでの検索("★"などの記号で検索したい)
* 検索: index:falseなどについて(検索キーワードとして使いたくないけど(store:trueに合わせて使うと)と結果に出て欲しいとき)
* 検索: ranges, [], (), AND, OR, などについて


StackoverflowのEscaping Lucene Characters using Javascript Regexの回答で大抵カバーできるけど、下記では\と/とも対応している。
function luceneEscaped(input) {
    // http://stackoverflow.com/questions/26431958/ + own additions
    // + - && || ! ( ) { } [ ] ^ " ~ * ? : \ /
    input = input.replace(/([\!\*\+\&\|\(\)\[\]\{\}\^\~\?\:\"\-\\\\\/])/g, "\\$1")
    return '"' + input + '"';