Sunday, March 25, 2018

Install Tomcat 8 on RasberryPi

I wanted to play a little with my old RaspberryPi (2 Model B) and install Tomcat 8 on it. I went over several tedious blogs showing a pretty long process from checking Java version through creating tomcat user and downloading Tomcat from all sort of strange web sites.
If you are not picky on a specific Tomcat 8 version, then it is actually quite a simple task:

First make sure using the command line that your RaspberryPi is running at least Java 8:

java -version

The install Tomcat 8 using apt:

sudo apt-get install tomcat8

It will make sure to create tomcat8 user for you.

In order to make sure if Tomcat 8 is running properly, simply open your browser (probably Chromium) and type:


Saturday, December 27, 2014

Nikon 1 VR 70-300 f/4.5-5.6 Sample Photos

The Nikon 1 VR 70-300 f/4.5-5.6 is quite an expensive lens, but considering it gives you equivalent focal length of 189-810mm that you can very easily hold with one hand, it makes it quite an attractive lens.

I think Nikon made great job with this lens. It is relatively quite small and light, it has very good optical quality and a fast focus even on my old Nikon V1 camera.

If you consider buying this lens I brought you some field sample images so you can evaluate it. All photos are completely untouched and uploaded directly from the camera.

LEAF  |  download full image

Nikon 1 VR 70-300
Aprture: f/5.6
Focal Length: 300mm (810mm equivavlent)
ISO: 200
Exposure: 1/200 sec

SAVION  |  download full image

Nikon 1 VR 70-300
Aprture: f/5.6
Focal Length: 270mm (728mm equivavlent)
ISO: 100
Exposure: 1/800 sec
SNAIL  |  download full image

Nikon 1 VR 70-300
Aprture: f/5.6
Focal Length: 300mm (810mm equivavlent)
ISO: 400
Exposure: 1/400 sec
MIKA  |  download full image

Nikon 1 VR 70-300
Aprture: f/5.6
Focal Length: 114mm (307mm equivavlent)
ISO: 560
Exposure: 1/400 sec

Tuesday, December 16, 2014

List of mobile user-agents

Sometimes it is useful to have a list of different kinds of mobile user agents. It can be used in many ways for development purposes in wide areas.

For this reason I created quite a big list of user-agents. Each line in the list is a JSON object containing data of:
  • User agent
  • Device Brand
  • Device Model
Here are some examples from the file:

{"device":"SC-04E","brand":"DoCoMo","user_agent":"Mozilla\/5.0 (Linux; Android 4.4.2; en-us; SC-04E Build\/KOT49H) AppleWebKit\/537.36 (KHTML, like Gecko) Version\/1.5 Chrome\/28.0.1500.94 Mobile Safari\/537.36"}
{"device":"U3","brand":"Housin","user_agent":"Mozilla\/5.0 (Linux; U; Android 4.0.2; en-in; HONPhone V7 Build\/ITL41D) AppleWebKit\/534.30 (KHTML, like Gecko) Version\/4.0 Mobile Safari\/534.30"}
{"device":"XT926","brand":"Motorola","user_agent":"Mozilla\/5.0 (Linux; U; Android 4.0.1; th-th; DROID RAZR HD Build\/IMM76D) AppleWebKit\/534.30 (KHTML, like Gecko) Version\/4.0 Mobile Safari\/534.30"}
The list is compressed as RAR. It contains almost 1.5M different user agents.
I hope you will find this list useful.

Sunday, December 14, 2014

Nikon V1 Viewfinder/Display problem

I own a Nikon V1 camera. It is considered to be quite old and outdated these days, but still I find it useful from time to time.

Few days ago I had this strange problem: when I turned on the camera, things were shown properly on the display, but when I put my eye on the viewfinder and then removed it again the image stayed on the viewfinder and refused to go back to the display.

Took me quite some time to understand that the sensor on the left side of the viewfinder was simply covered with too much dust. It tricked the sensor to think that my eye is all the time on the viewfinder and therefore showed the image on the viewfinder instead of the display.

I though it might be useful to share this information in case one of you out there is still using Nikon V1 and experience the same problem. Of course that cleaning the sensor solved the problem.

Here is where the sensor is located:

Thursday, December 11, 2014

List of cities as SQL inserts

There are times you might need a list of cities as SQL inserts.
For this reason I extracted quite a large list of cities from MaxMind database.
The list is composed of 2 columns:
  • Country code as ISO-3166 alpha2 (2 letters for each country)
  • City name
There is also a script that creates the cities table (SQL Server syntax):

 CREATE TABLE [dbo].[city](  
      [country_code] [char](2) NOT NULL,  
      [city] [varchar](100) NOT NULL,  
      [country_code] ASC,  
      [city] ASC  

DOWNLOAD: You can download the list of cities HERE

Wednesday, December 3, 2014

Show Resultset as HTML table

There are times you simply want to show some result set as a table on the screen.
You do not need anything fancy, just show some tabular data on the screen.

In order to solve this issue I wrote a very small and lightweight Java class named: ResultSetToHtmlTable. Even through this class is doing a quite simple task it still have some nice qualities:

  • It is very fast. It doesn't construct any string. It simply writes the table directly to a writer.
  • It doesn't use any external libraries. All plain and simple Java.
  • It is only a single class.
  • It knows to format the data in each column. It supports the following formats:
    • Integer - Show 1000 as 1,000
    • Float - Show 0.5145235 as 0.51
    • Currency - Show 5.2 as $5.2
    • Percentage - Show 0.5 as 50%
    • Date - Show 12/5/2014 as 5 Dec 2014
    • Date and time - Show 12/5/2014 12:00:00 as 5 Dec 2014 12:00:00
    • Time - Show only the time part of a date. For example: 13:22:15
  • It allows to align the data to the left or right and add titles to columns.
  • If no strict column information is supplied is knows to auto detect:
    • Column types.
    • Column titles - titles are named as column names returned in query.
    • Column alignment - Numbers are aligned to the right.
The code of this class is quite simple and straightforward. Here is how it looks like:
package com.todacell.util.sql;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Types;
import java.text.DateFormat;
import java.text.Format;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;

 * @author Bashan
 *         Date: 18/11/2014 15:07
public class ResultSetToHtmlTable {

  public void writeTable(ResultSet rs, Writer writer, Column[] columns) throws IOException, SQLException {
    // Write titles
    for (Column column : columns) {
      writer.write("\t\t<th>" + column.title + "</th>");

    // Write data
    int cols = columns.length;
    while ( {
      for (int i = 0; i < cols; i++) {
        ColumnType columnType = columns[i].columnType;
        String columnAlign = columnAlignToColumnCss.get(columns[i].columnAlign);
        writer.write("\t\t<td" + columnAlign + ">" + format(columnType, rs.getObject(i + 1)) + "</td>");


  private static Map<Integer, ColumnType> sqlTypeToColumnType = new HashMap<Integer, ColumnType>();
  private static Map<ColumnType, ColumnAlign> columnTypeTpColumnAlign = new HashMap<ColumnType, ColumnAlign>();
  private static Map<ColumnAlign, String> columnAlignToColumnCss = new HashMap<ColumnAlign, String>();

  static {
    // Map SQL types to column types

    // integer
    sqlTypeToColumnType.put(Types.INTEGER, ColumnType.INTEGER);
    sqlTypeToColumnType.put(Types.BIGINT, ColumnType.INTEGER);
    sqlTypeToColumnType.put(Types.SMALLINT, ColumnType.INTEGER);
    sqlTypeToColumnType.put(Types.TINYINT, ColumnType.INTEGER);
    sqlTypeToColumnType.put(Types.NUMERIC, ColumnType.INTEGER);

    // float
    sqlTypeToColumnType.put(Types.FLOAT, ColumnType.INTEGER);
    sqlTypeToColumnType.put(Types.DOUBLE, ColumnType.INTEGER);
    sqlTypeToColumnType.put(Types.DECIMAL, ColumnType.INTEGER);

    // date
    sqlTypeToColumnType.put(Types.TIME, ColumnType.DATE);
    sqlTypeToColumnType.put(Types.TIMESTAMP, ColumnType.DATE);

    // Map column type to column alignment
    columnTypeTpColumnAlign.put(ColumnType.INTEGER, ColumnAlign.RIGHT);
    columnTypeTpColumnAlign.put(ColumnType.FLOAT, ColumnAlign.RIGHT);
    columnTypeTpColumnAlign.put(ColumnType.CURRENCY, ColumnAlign.RIGHT);
    columnTypeTpColumnAlign.put(ColumnType.DATE, ColumnAlign.LEFT);
    columnTypeTpColumnAlign.put(ColumnType.STRING, ColumnAlign.LEFT);

    // Map column alignment to css style
    columnAlignToColumnCss.put(ColumnAlign.LEFT, "");
    columnAlignToColumnCss.put(ColumnAlign.RIGHT, " style=\"text-align:right\"");
    columnAlignToColumnCss.put(ColumnAlign.CENTER, " style=\"text-align:center\"");

  public void writeTable(ResultSet rs, Writer writer) throws IOException, SQLException {
    ResultSetMetaData meta = rs.getMetaData();
    int cols = meta.getColumnCount();

    Column[] columns = new Column[meta.getColumnCount()];
    for (int i = 0; i < cols; i++) {
      ColumnType columnType = sqlTypeToColumnType.get(meta.getColumnType(i + 1));
      ColumnAlign columnAlign = columnTypeTpColumnAlign.get(columnType);
      columns[i] = new Column(
          columnType != null ? columnType : ColumnType.STRING,
          meta.getColumnName(i + 1),
          columnAlign != null ? columnAlign : ColumnAlign.LEFT);

    writeTable(rs, writer, columns);

  public enum ColumnType {

  public enum ColumnAlign {

  private static NumberFormat integerFormat = NumberFormat.getInstance();
  private static NumberFormat floatFormat = NumberFormat.getInstance();
  private static final NumberFormat percentFormat = NumberFormat.getPercentInstance();
  private static final NumberFormat currencyFormat = NumberFormat.getCurrencyInstance();
  private static final DateFormat dateFormat = new SimpleDateFormat("dd MMM yyyy");
  private static final DateFormat dateTimeFormat = new SimpleDateFormat("dd MMM yyyy hh:mm:ss");
  private static final DateFormat timeFormat = new SimpleDateFormat("hh:mm:ss");

  static {

  public String format(ColumnType columnType, Object value) {
    String result;
    if (value != null) {
      if (columnType == ColumnType.STRING) {
        result = value.toString();
      } else {
        Format format;
        if (columnType == ColumnType.FLOAT) {
          format = floatFormat;
        } else if (columnType == ColumnType.CURRENCY) {
          format = currencyFormat;
        } else if (columnType == ColumnType.PERCENTAGE) {
          format = percentFormat;
        } else if (columnType == ColumnType.DATE) {
          format = dateFormat;
        } else if (columnType == ColumnType.DATE_TIME) {
          format = dateTimeFormat;
        } else if (columnType == ColumnType.TIME) {
          format = timeFormat;
        }else {
          format = integerFormat;

        result = format.format(value);
    } else {
      result = "N/A";

    return result;

  public static class Column {
    ColumnType columnType;
    String title;
    ColumnAlign columnAlign;

    public Column(ColumnType columnType, String title, ColumnAlign columnAlign) {
      this.columnType = columnType;
      this.title = title;
      this.columnAlign = columnAlign;

And here is a simple example of how to use this code in a JSP file:
 <%@ page import="" %>  
 <%@ page import="com.todacell.util.sql.ResultSetToHtmlTable" %>  
 <%@ page import="org.hibernate.Session" %>  
 <%@ page import="java.sql.Connection" %>  
 <%@ page import="java.sql.ResultSet" %>  
 <%@ page import="java.sql.Statement" %>  
 <%@ page contentType="text/html;charset=UTF-8" language="java" %>  
   <title>Daily Deposits</title>  
   <style type="text/css">  
     table {  
       border-collapse: collapse;  
     table, th, td {  
       border: 1px solid black;  
     td, th {  
       padding: 5px;  
 <jsp:include page="k2_menu.jsp" />  
 <h1>Daily Deposits</h1>  
   Session hSession = SessionSingleton.instance();  
   Connection conn = hSession.connection();  
   try {  
     Statement stmt = conn.createStatement();  
     ResultSet rs = stmt.executeQuery("select * from k2_deposits(60)");  
     ResultSetToHtmlTable resultSetToHtmlTable = new com.todacell.util.sql.ResultSetToHtmlTable();  
     resultSetToHtmlTable.writeTable(rs, out,  
         new com.todacell.util.sql.ResultSetToHtmlTable.Column[] {  
             new ResultSetToHtmlTable.Column(ResultSetToHtmlTable.ColumnType.DATE, "Date", ResultSetToHtmlTable.ColumnAlign.LEFT),  
             new ResultSetToHtmlTable.Column(ResultSetToHtmlTable.ColumnType.CURRENCY, "Deposits", ResultSetToHtmlTable.ColumnAlign.RIGHT),  
             new ResultSetToHtmlTable.Column(ResultSetToHtmlTable.ColumnType.CURRENCY, "Allocated", ResultSetToHtmlTable.ColumnAlign.RIGHT),  
             new ResultSetToHtmlTable.Column(ResultSetToHtmlTable.ColumnType.CURRENCY, "Deallocated", ResultSetToHtmlTable.ColumnAlign.RIGHT),  
             new ResultSetToHtmlTable.Column(ResultSetToHtmlTable.ColumnType.CURRENCY, "Ad Spend", ResultSetToHtmlTable.ColumnAlign.RIGHT),  
             new ResultSetToHtmlTable.Column(ResultSetToHtmlTable.ColumnType.CURRENCY, "Potential Spend", ResultSetToHtmlTable.ColumnAlign.RIGHT),  
             new ResultSetToHtmlTable.Column(ResultSetToHtmlTable.ColumnType.INTEGER, "New Users", ResultSetToHtmlTable.ColumnAlign.RIGHT)  
   } finally {  
     if (hSession != null) {  
And here is how it looks on the browser:
DOWNLOAD: You can download the ResultSetToHtmlTable here

Tuesday, November 25, 2014

Instagram Photo Cycler JavaSscript widget

A while ago I built for the company I work for a nice Dashboard presenting business and operational data on a TV.

I wanted to add to the Dashboard something cool that will drive people to be more creative.

I had an idea of showing on the dashboard Instagram photos of the company by posting photos to a predefined hashtag. For example: #mycompany.

There was one problem: the real-estate on a dashboard TV screen is very expensive and you can not show more then a single photo.

I remembered that I once encountered a cool JavaScript widget that simply cycles photos with nice transition effects. I thought that it will be nice to connect this widget with Instagram and put it on the dashboard.

Back then I didn't know that I can also get the assistance of Instafeed.js in order to get Instagram data easily, so I had to write this part my self.

The result was pretty cool, so I decided to make a jQuery widget from it to allow others to use it as well. You can download the widget and use it for your own photos or for showing photos of some hashtag.

Here is how the widget looks like for the hashtag #love:
<script src="" type="text/javascript"></script>
<script src="" type="text/javascript"></script>
<script src="" type="text/javascript"></script>

<br />
<div id="instagramCyclerCoderEyeLove" style="width:320px; height:320px;">
<script language="JavaScript">

  $(document).ready(function() {
    'get':   'tagged',
    'tagName':  'love',
    'accessToken': '161840.f92bbd9.e0a09d9b00f746c8b2662a4e784e55b0'


And here is the result:

In order to show your own photos you can use the property "get" with the "user" value. Please note that in order to show you own photos, you can simply use for "userId" the word "self". In addition you can see how you can show more than just a photo and even control look of the widget very easily with the "template" property and simple usage of CSS:
<script src="" type="text/javascript"></script>
<script src="" type="text/javascript"></script>
<script src="" type="text/javascript"></script>

  #instagramCyclerCodeEyerUser {
   background-image: url(""); 
   background-size: cover; 

  #instagramCyclerCodeEyerUser img {

  #instagramCaption {
   font-family: ‘Lucida Sans Unicode’, ‘Lucida Grande’, sans-serif;
   width: 250px;
   white-space: nowrap;
   overflow: hidden;
   text-overflow: ellipsis;


<div id="instagramCyclerCodeEyerUser"></div>
<script language="JavaScript">

  $(document).ready(function() {
    'get':   'user',
    'userId':  'self',
    'tagName':  'todacellmon',
    'accessToken': '161840.f92bbd9.e0a09d9b00f746c8b2662a4e784e55b0',
    'template': '<div><a href="{{link}}"><img src="{{image}}" width="250" height="250" /></a><div id="instagramCaption">{{caption}}</div></div>'


Here is the result:

PLEASE NOTE: In order to use Instagram API, you should create an access token. You have nothing to worry that others can see your access token as long as you create an access token only for READING. Frankly, creating the access token on Instagram, at least at the time that I did it, was not a simple task. You can find more help on how to do it on Instagram developers section or on this url

DOWNLOAD: Here you can download the widget

Thursday, November 13, 2014

Working with SHA1 on SQL Server

There are times you might need to convert some information to MD5 on your SQL Server in HEX format. As it is for now there is no out of the box function to do it on SQL Server. But you can easily accomplish this task by using the following function:
create FUNCTION [dbo].[sha1]
        @value varchar(4000)
RETURNS varchar(40)
    case when @value is not null then
      SUBSTRING(master.dbo.fn_varbintohexstr(HashBytes('SHA1', @value)), 3, 40)
    else null end

Testing it is quite straight forward. For example:
select dbo.sha1('123') 

And here is the output:


Wednesday, November 12, 2014

Working with MD5 on SQL Server

There are times you might need to convert some information to MD5 on your SQL Server in HEX format. As it is for now there is no out of the box function to do it on SQL Server. But you can easily accomplish this task by using the following function:
create FUNCTION [dbo].[md5]
        @value varchar(4000)
RETURNS varchar(40)
    case when @value is not null then
      (SUBSTRING(master.dbo.fn_varbintohexstr(HashBytes('MD5', @value)), 3, 32))
    else null end

Testing it is quite straight forward. For example:
select dbo.md5('123') 

And here is the output:


Tuesday, April 9, 2013

PC speaker beeps with no apparent reason

I had this problem for about few months: from time to time with no warning, my PC started beeping from its speakers for no apparent reason.
Sometimes it started with several beeps, sometimes it started with a single long beep. When I restarted my computer the problem seemed to pass till the next time.
First, I suspected I had a virus. I made sure I updated my Kaspersky to the latest version and scanned for viruses with no luck.

I then went to Windows device drivers manager and stopped the speakers service - but still, the beep used to come whenever it wanted. Eventually, I came with the theory that my machine is getting too hot and therefore I get a warning beep. So I opened the case of the PC to make sure my ventilation is working properly - all seemed right.

So, I decided to download this small app named Core Temp. It can give detailed about the temperature of each core of your CPU. It uses information from the CPU itself and not sensors that measure temperature outside the CPU.

After loading the app I noticed the temperature was around 70 degrees. It seems to me a bit high, but nothing unreasonable. So I decided to wait for the next beep to come.
After few days the beep came again. I loaded the Core Temp and was amazed to see that the CPU temperature was on 95 degrees!
I quickly opened my PC case and noticed both ventilation are working properly. So I decided to give a closer look at the hit sink below the CPU ventilation. I noticed a huge amount of dust that filled the hit sink.

I started cleaning all the dust that accumulated there along the time. Then started my computer again and loaded the Core Temp. Then I noticed the temperature was around 35 degrees!
Eventually the mystery was solved: my PC was beeping like crazy, since the CPU was hitting too much and I couldn't tell there was a problem, because ventilation seemed to work properly.
So if your PC starts to beep with no apparent reason, do yourself a favor and give it attention. It might say that something is seriously wrong. Probably your CPU is over hitting and the blame might be more then a low performing ventilation: DUST.
I assume that the dust may have caused 2 major things:
  • Less effective hit dispensation.
  • Increases the drag of the ventilation and therefore cause it to rotate slower.
When my computer was not working too hard: temperature was around 70 degrees, which was not so good, but not so bad.

When my computer was working hard, CPU temperature started climbing higher and higher till  it reached around 95 degrees and the computer started beeping to warn about the hit.
The small difference of removing the excessive dust made the difference for more than 50 degrees! Worth the effort!