Wednesday, November 7, 2012

RockMongo: MongoDB Client on Mac OSX Lion

On Mac OSX Lion, I use MongoHub as the client tool to view and display my mongodb. MongoHub has native UI for Mac, and provided functionalities for most of my operations. However MongoHub is a little bit buggy and sometimes crashes. On my apache server, I use RockMongo, an excellent Mongo administrator site to manage my mongodb. Here is some steps for me to lunch RockMongo on my Mac OSX Lion(10.7). It runs perfectly!


  1. Apache2 and PHP5 has already been installed on Mac OSX. You just need to enable it.
    • Enable Apache2:   
    install apache2 on mac osx
    • PHP is disabled on apache2 by default, you need to enable it manually: open apache2 config file with command "sudo vi /etc/apache2/httpd.conf", find the line "LoadModule php5_module libexec/apache2/libphp5.so" and remove the "#" at the beginning to enable php5 module.
  2. Install mongo php driver
    • You may need to firstly install the php tool "pecl"
      • cd /usr/lib/php
      • sudo php install-pear-nozlib.phar
      • Edit/etc/php.ini and find the line: ;include_path = ".:/php/includes" and change it to:
        include_path = ".:/usr/lib/php/pear"
      • sudo pear channel-update pear.php.net
      • sudo pecl channel-update pecl.php.net
      • sudo pear upgrade-all
    • Then run command "sudo pecl install mongo". Make sure you xcode has been installed correctly. pecl will download mongo php driver source code and build it. (The precompiled mongo.so may not work on your machine. So you have to use pecl to install the driver.)
    • run command sudo vi /etc/php.ini to open php.ini for editing, if you /etc/php.ini does not exist, copy /etc/php.ini.default to /etc/php.ini, add "extension=mongo.so"
  3. Download RockMongo source code, and copy to your "computer website folder"
  4. You need to run "sudo apachectl restart" to restart apache2 server.
  5. Login to http://localhost/rockmongo, with user/password as "admin/admin". Then you should see  RockMongo as follows:

Saturday, November 3, 2012

Grid to Excel export plugin for ExtJS 4

ExtJS has an excellent component Grid Panel to display well structured data. The Grid component may be able to fulfill customer's requirements in most of the cases, but once customer need to do customized calculation on the grid, the may need to export the grid data to their favorite tool, for example, Microsoft Excel, for further process.

With some investigation on internet, this requirement actually existed for a long time, there are 2 main thread on sencha forum:
The discussions have been there for 3 years, but neither of the works well so far, either because of compatibility issues on Ext.JS 4 or bugs in them. I'm not going to discuss more about details, but summarized the 3 ways:
  1. Leverage document data location: set document URL to BASE64 encoded data like: data:application/vnd.ms-excel;base64,... 
    • Pros: pure JavaScript side, no dependency on any 3rd party tools or objects.
    • Cons: the download file cannot be customized, and there are some limitations on encoding UTF-8 to BASE64
  2. Send request to server and generate data stream with specified file format on server.
    • Pros: still pure JavaScript on client side, and developer can choose the file name.
    • Cons: need some work on server side, the code here made it works on JSP.
  3. Use flash Downloadify to generate a file on the fly.
    • Pros: No server side work, user can choose the file name just like a normal download.
    • Cons: depends on flash object.
My version of Ext.ux.Exporter  actually forked the version who use Downloadify, and fixed some defects to make it works on ExtJS 4.1.1a. Here is the code to use it:

  • include script files in html file:
<script type="text/javascript" src="/extjs/src/ux/exporter/swfobject.js"></script>
<script type="text/javascript" src="/extjs/src/ux/exporter/downloadify.min.js"></script>
  • in docedItems list of grid panel, generally on a toolbar, add an item as follows::
{
    xtype: 'exporterbutton'
}
In my implementation, I didn't take time to resolve the excel format issue, instead I use CSV format as default format. What I need is not to keep the exact style when load. I need further processing on data, and a CSV file can fulfill my requirements perfectly.

Monday, April 2, 2012

LEAN2: What Happened in the First 75 Days

What Happened in the First 75 Days


There have been two and a half months since My last blog post The Lean Startup, My Real Practice. Here is the notes about what what has happened in the past 75 days.
  • Released a new version in February 7, 22 days after I released the first version. The majority change is the refinement of user interface for lists of to do today, task list, and interruptions. Here is the post I asked in stackoverflow.
  • Made a promotion on Giveaway of the Day in February 29, provided a one-day promotion for free of charge.
  • Made a promotion on bits dujour, provided a one-day promotion for 50% discount.
Here is the statistics for traffic:
  • 11,175 Visits, there are half of the visits are from the Giveaway of the Day promotion. Recently the traffic getting stable to about 790 visits per week.

  • 44.81% Bounce Rate, I hope I can improve this number, but in future when I made efforts on SEO, I think this number should be higher than current.

  • Traffic source within the past 75 days:
    • 17.34% Search Traffic
    • 63.90% Referral Traffic
    • 18.56% Direct Traffic

  • 48.96% Search Traffic within recent 2 weeks. The traffic number is impacted a lot by GOTD promotion.
[caption id="attachment_63" align="aligncenter" width="743" caption="PomodoroApp Visits (weekly) from 01/15/2012 to 03/31/2012"][/caption]

About the revenue:

  • January: US$0.00
  • February: US$0.00
  • March: The first order happens in March 3. 2 order for organic traffic, and 17 orders from the promotion on bits dujour. The total sales is: US$249.94, and profit is $127.82. In addition, some profit from promotion on GOTD.
  • I'm not sure how much will get in April, but the sure thing is that there is no promotions in April. If you have any suggestions to have promotion options, please be sure to let me know.
What's I'm working in progress:
  • Redesign the user interface, propose the concept of "dashboard", tasks will be categorized by dashboard.
  • Refactor the code and prepare to integrate with Jira.
Something that I didn't do well and should be improved:
  • I spent too much time to review traffic statistics from google analytics. However, my most important task is to complete the new version as soon as possible.
  • I didn't take time to follow up when PomodoroApp appears on social networks or blogs, news software. I can find those site by looking for the emergency traffic from a referrer.
  • I didn't have a tight schedule or plan for my new release since February 7. However, when I release the first 2 versions, I made a very aggressive deadline and did my best to follow the date.
  • My fulltime daily job made me exhausted and I didn't have energy to continue to work in after work hours.

Saturday, March 31, 2012

An overview of Qt Quick 1.1 Components

I'm recently redesign the UI of PomodoroApp, and testing Qt Quick. I read through the tutorials and resources below:

  • Qt Essentials - Qt Quick for C++ Developers: 8 excellent slides for you to getting started with Qt Quick, and understand most of the features

  • QML Elements: Detailed description for grouped lists of QML elements as part of Qt Quick.

  • Some samples from Qt demo/examples declarative folders. You can build and run those features and see what QML can do.

While my purpose is to have a smooth and beautiful UI for my app on *desktop*, both Windows, Mac and Ubuntu. I may need to spend more time to learn QML and create basic elements for desktop widgets. Then I found some existing QML components here. I played for a while. Here is the screenshot for colibri, beautiful and has covered most of frequently used components.

[caption id="attachment_60" align="aligncenter" width="300" caption="Qt Quick QML Component "colibri""]Qt Quick QML Component "colibri"[/caption]

How to make debian package (.deb) with scripts

When I port my qt projects to Ubuntu/Debian Linux systems, I provided the compiled debian package, a deb file for users. I use a GUI debian package creator to make a deb package. Today when I browser qt-components, I got this bash script that can create deb file easily:


#!/bin/sh
MAKE='make -j4'

cd `dirname $0`

rm -rf debian
mkdir debian
cd debian

mkdir -p "usr/share/applications"

desktop_file_meenotes="usr/share/applications/meenotes.desktop"
echo "[Desktop Entry]" > "$desktop_file_meenotes"
echo "Version=1.0" >> "$desktop_file_meenotes"
echo "Name=MeeNotes" >> "$desktop_file_meenotes"
echo "GenericName=MeeNotes" >> "$desktop_file_meenotes"
echo "Comment=MeeNotes" >> "$desktop_file_meenotes"
echo "Exec=/opt/meenotes/MeeNotes" >> "$desktop_file_meenotes"
echo "Terminal=false" >> "$desktop_file_meenotes"
echo "Type=Application" >> "$desktop_file_meenotes"
mkdir -p DEBIAN

control_file="DEBIAN/control"

echo "Package: meenotes" > "$control_file"
echo "Version: 1.0" >> "$control_file"
echo "Architecture: all" >> "$control_file"
echo "Maintainer: Qt developers" >> "$control_file"
echo "Description: Qt components MeeNotes" >> "$control_file"

[ ! -f "../Makefile" ] && (cd ..; qmake)
(export INSTALL_ROOT=`pwd`; $MAKE install)

mkdir -p opt/meenotes

cp -ar ../MeeNotes opt/meenotes/
cp -ar ../resource opt/meenotes/resource

cd ..
dpkg-deb --build debian
mv debian.deb meenotes.deb

Monday, March 12, 2012

Practice on C++11(2): tuple, rvalue, auto, lambda

Continue with my previous post about rvalue, auto, lambda, decltype, My second practice is to create a list of objects without knowing too much details. I'll give also 2 styles of code for comparing:

1. Traditional C++ style:

[cpp]
// definition of getTaskList:
// void getTaskLists( std::vector<int>& ids, std::vector<QString>& names );
std::vector<int> ids;
std::vector<QString> names;
PDatabaseManager::instance()->getTaskLists( ids, names );
Q_ASSERT( ids.size() == names.size() );

PLists lists;
for( size_t i = 0; i < ids.size(); ++i )
{
lists.push_back( PListPtr( new PListSqlite( ids[i], names[i] ) ) );
}
[/cpp]


2. C++11 style, also, leverage algorithms instead of write code by yourself:

[cpp]
// definition of getTaskList:
// std::vector< std::tuple<int, QString> > getTaskLists();
auto&& rawlists = PDatabaseManager::instance()->getTaskLists();

PLists lists;
std::for_each( rawlists.begin(), rawlists.end(), [&]( const std::tuple<int, QString>& i ) {
lists.push_back( PListPtr( new PListSqlite( std::get<0>( i ), std::get<1>( i ) ) ) );
} );
[/cpp]


The new style looks more elegant and clean.

Practice on C++11(1): rvalue, auto, lambda, decltype

I learned C++ programming language when I was a sophomore in the year 1998, and I started to use C++ on commercial software since 2001. I'm insist in using C++ for most of my projects just because I'm a skilled programmer. I have ever read books for C++98, and articles/presentations/papers for C++0x, but never really used it on my project. Recently I watched the keynotes of Bjarne Stroustrup and Herb Sutter on GoingNative 2012, I was motivated change my mind from traditional C++ mindset to C++11. The project of company still using Visual Studio 2008 as the compiler, I practiced C++11 on a side project in my spare time.

Here is my first practice which leveraged: rvalue, auto, lambda, decltype:

This function is in my unit test, the purpose is to check if there a line in the canvas with specified start and end point.

1. Traditional Style(not compiled, just write here for comparing with C++11 style)
[cpp]
bool hasLine( const QPointF& start, const QPointF& end )
{
std::vector<DGraphicsItem*> items = canvas.items();
for( std::vector<DGraphicsItem*>::const_iterator i = items.constBegin();
i != items.constEnd(); ++i )
{
DGraphicsItemLine* pLine = dynamic_cast<DGraphicsItemLine*>( p );
if ( !pLine ) continue;
if ( pLine-->startPoint() == start && pLine-->endPoint() == end ) return true;
}
return false;
}
[/cpp]

2. C++11 style
[cpp]
bool hasLine( const QPointF& start, const QPointF& end )
{
auto&& items = canvas.items();
return std::find_if( items.constBegin(), items.constEnd(),
[&]( DGraphicsItem* p ) -> bool
{
auto pLine = dynamic_cast<decltype(m_pLine)>( p );
return pLine && pLine->startPoint() == start && pLine->endPoint() == end;
} ) != items.constEnd();
}
[/cpp]

I like the new features in C++11 very much, and it's very impressive for me that my first C++11 style code works gracefully!
You may wonder why I use decltype here. The reason is, when I write other test cases, I may copy the code and make some modifications, if I have the type DGraphicsItemLine here, it's easy for me to miss changing the type. Furthermore, I hope I can get some templates or abstraction so that I can reuse the code in future.

Tuesday, February 14, 2012

Why Application Loader Unavailable

When I upload a package to Mac App Store today, I got the error message when using Application Loader:

Application loader is currently unavailable. Directory Services reported the following error: Your Apple ID or password was entered incorrectly. (-20101)

At the beginning I thought that it's because of the network error. But when I try it again after several hours, the error was still there. I then changed my network to use a proxy, still the same error. Then I logged to iTunes use my account, and authorized the computer, no lucky to resolve it. Finally I resolved the issue by several simple steps:

  1. Quit Application Loader

  2. Load Keychain Access, select "passwords" from category

  3. Search for "itunes", you'll see an application password item with the name starting with "iTunes Connect:..."

  4. Remove this item, and run Application Loader again, you'll get prompt to input your id and password.

This is the difference for applications on Mac and Windows. Windows does not have a centralized  place for internet and applications to save password, each browser or application has their own approach to manage passwords. But Mac has the Keychain Access to manage all your passwords. Once you are told that something is wrong with your id/password on Mac, then the first place to go is the Keychain Access, try to remove the stored password and login again.

Good luck:)

Sunday, January 15, 2012

LEAN1: Kick Off

Kick Off

Recently I read the book The Lean Startup. I really learned a lot from the book, new ideas and new concepts. I've been using Pomodoro Technique for several months, and use  focusbooster to track my time, log interruptions, completions and discarded pomodoros with pencil on my calender. But when I relied more on Pomodoro Technique. I really need to get statistics and want to learn from it. In addition, I hope I can get some simple GTD functionality into the timer instead of only counter down.

So 2 things motivated me: one is the book The Lean Startup,  another one is that I need a time management tool. I decided to practice the methods from the book with a minimum viable product. I do this in my spare time, and here is the timeline for my practice:

1. Purchased the domain "PomodoroApp.com" on Christmas Eve, 2011.

2. Spent 2 days(12/24, 12/25, 2011) to research the market,  investigation the necessary technology, including website, user experience, feature list, and so on.

3. Starting from the evening of 12/25/2011, I started building website.

4. Starting from 12/26/2011, I started coding.

5. My initial plan is really aggressive. I hope I can get a *minimum viable* software in 3 days, and get everything done, including the website. But late I found 3 days can just started the work with a very very rough version, not "viable".

6. In the coming 3 weeks, I spent my weekends and after work hours(0~2 hours/day) working on the product. The New Year Holiday I spent 2 days to travel with my wife, no work.

7. 1/14/2011, 2 days to work for release: final test, refine installation package, config website, grab screenshots, write web pages, set pricing plan, submit to download site/search engine and so on.

8. After released to web, I also spent some time to refine and optimize website, e.g. setup cache for website, schedule some resources to load from CDN for opening speed and so on.

After I completed all those work. I started to played web game for a while for a rest. Then started to write this blog post.

So as a summary:

To release a minimum viable product on time management area to improve personal productivity, here is the cost:

  • 2 days for marketing research and technique investment.

  • 5 days, and a number of after work hours in 3 weeks  for software design and programming.

  • 2 days for releasing: website, submission.