Monday, January 27, 2014

BASH History Suggest Box

A command line utility that brings improved BASH command completion from the history. It aims to make completion easier and more efficient than Ctrl-r. Find it on GitHub and YouTube.

Labels: , , ,

Wednesday, January 01, 2014

Ubuntu @ Acer Aspire S7-191

Thursday, June 28, 2012

Concept2 Indoor Rower

After years of running I was facing crisis of motivation, limits of my body and injuries. I cross train more and more and looking for new challenges and personal bests to beat. I have been rowing since I was 10 for 8 years and both on water rowing and erging is the activity I enjoy. Therefore I decided to return back to the roots and get Concept2 indoor rower.

Concept2 is a company with perfect profile and cool history. I have been riding models B, C, D and E of their basically indestructible machines.

Prior Velvet revolution I was even erging on bad copies of model B from the Eastern bloc :-Z

The most interesting alternatives I found are WaterRower (check James Stroud comparison) and RowPerfect. Both are not (that) bad, but I decided to bet on Concept2 as I know it for a very long time; because of the community (log, ranking, challenges, BIRC/CRASH B, ...), old models support (Concept2 supports even oldest models up today) and use of Concept2 by majority of elite rowers.

General consensus is that model D/PM3 is perfect fit for home use, while model E is kind of "Rolls-Royce" meant rather for fitness centers and hotels. Model E is bigger, higher, nicer and ultimately durable. So, after not much deliberation, I decided to invest in my health and became happy owner of Model E/PM4.

You may want to check model D/E comparison and PM3/PM4 monitors comparison.

There is a lot of accessories and gadgets - log card allowing you to track all your workouts (I had it in the past while erging in fitness centers around Prague), CBreeze (the perfect accessory with the best 'value for price' ratio), RowPro (for social rowers), ErgLog (Android phones), KinoMap (to row your favorite river/trail), slides, ShoxBox ... and much more.

Before you start erging check the technique and common errors videos. Set the damper (which has the similar function like bike gearing) to 5 (not to 10 - which is the most common beginner error) and experiment from there. Learn about drag factor (allows you to set different machines to the same resistance e.g. older machines have typically lower resistance with the same damper settings). Join a forum and find a training plan like C2 Interactive, Pete's plan or Wolverine plan. I also found very useful French Rowing Federation 2k Strategy and pace calculator.

I follow Concept 2 2k interactive plan 4 days a week with 2 extra sessions of rowing or running and aiming to get to 300km/month+ (again ;-).
Happy erging!

Labels: , , ,

Tuesday, December 06, 2011

MindRaider meets MindForger

Announcing new release of MindForger that brings integration with MindRaider. MindRaider is a desktop outliner that enables off-line and sharing of your outlines. MindForger is an online companion of MindRaider. With MindForger you can upload your outlines on the web and easily access them from any device. Check MindForger - your Outlines on the Web for more details.

Labels: , , ,

Saturday, December 03, 2011

Google App Engine SDK: HttpClient authentication on localhost

public class AppEngineLocalhostClient {

 public String authenticateAtLocalhost(
     String username, 
     boolean asAdmin, 
     String redirectUrl) throws Exception {
  HttpClient httpClient = new DefaultHttpClient();
  httpClient.getParams().setBooleanParameter(
    ClientPNames.HANDLE_REDIRECTS, false);
  
  HttpPost httpPost = new HttpPost("http://localhost:8888/_ah/login");
  httpPost.setHeader("Content-Type","application/x-www-form-urlencoded");
  String email = URLEncoder.encode(username, "UTF-8");
  httpPost.setEntity(
    new StringEntity(
      "email=" + email + 
      "&continue=" + redirectUrl + 
      (asAdmin?"&isAdmin=on":"")));
  HttpResponse response = httpClient.execute(httpPost);
  
  String authenticationCookie 
   = response.getFirstHeader("Set-Cookie").getValue();
  httpClient.getConnectionManager().shutdown();
  
  return authenticationCookie;
 }

 public static void main(String[] args) throws Exception {
  AppEngineLocalhostClient client = new AppEngineLocalhostClient();
  
  String username="test@example.com";
  boolean iWantToBeAdmin = true;
  String afterLoginGetMeToThisUrl 
   = URLEncoder.encode("http://localhost:8888", "UTF-8");
  String authenticationCookie = client.authenticateAtLocalhost(
    username,
    iWantToBeAdmin, 
    afterLoginGetMeToThisUrl);
  
  // ... access the REST interface authenticated
  
  HttpGet httpget = new HttpGet("http://localhost:8888/rest");
  httpget.addHeader("Cookie", authenticationCookie);
  
  // ...  
 }
}
When developing a Google App Engine application using SDK on localhost you sometimes need to authenticate programatically. For example in case that your application has a REST-style interface like MindForger. It took me a bit of time to determine how exactly to do that - lets save it for you.

Labels: , , , , ,

Monday, May 30, 2011

Google App Engine: Deployment Ensuring Sustainable Evolution


I use Google App Engine for Java since it was relased. I did a few smaller projects like Facebook application for behej.com backed by AppEngine in the past. Recently I started to use AppEngine more seriously. Therefore I had to define environments and procedures that are closer to these that are commonly used in the enterprise environment.

I defined 3 environments:
  • Development
    • This is where I do actual development of the application apart to localhost. There are no restrictions on changing the code and data. Data might be screwed (even intentionally) and/or deleted. The purpose of this environment is to enjoy the freedom of development and testing AppEngine features and APIs online.
    • It is separate AppEngine application deployed at the URL like http://foo-development.appspot.com
  • Pre-production
    • I use pre-production instance to verify that new version of the application (that I plan to release) works with the production data and that the upgrade will be smooth and easy. The data are replicated from production to pre-production only from time to time. Therefore there is always a slight difference which is perfectly OK, because this instances is not supposed to be backup. For the replication of the data I use REST interface of my application. 
    • Alternatively you may consider for example incremental pull-style (replica is pulling data from the master) replication of the data using TX backed Tasks (copy only if TX succeeds).
    • This is also separate AppEngine application deployed at the URL like http://projectname-preproduction.appspot.com
  • Production
    • This is where the production version of the application runs and where real users are working with the real data. 
    • This is obviously separate AppEngine application deployed at the URL like http://projectname.appspot.com
There are a couple of AppEngine features that could be used to define these environments. For example namespaces. After I compared different pros and cons I decided to go with the option described above. It gives me the highest level of isolation and data separation. Therefore it seems to be the most robust and safe solution. I also defined upgrade procedures that differ based on the type of the change and its impact:
  • Presumption
    • AppEngine supports multiple versions of the applications to be deployed. Note that these applications share the same storage. Let me presume that the production application is deployed as version 1 and this version is made default.
  • New version upload
    • Upload new version of the application - version 2.
  • Test upload
    • Make the final check that the application works as expected by accessing and testing it at http://2.foo.appspot.com
  • Release
    • Make the version 2 the default.
This is zero downtime upgrade. You don't have to define new version each time you deploy a new application version - I rotate just 3 versions as shown in the diagram above.

In case of a major release, that includes data model change (find the definition of the major release in the best practices paragraph below), there might have to be a scheduled maintenance window:
  • Presumptions 
    • The same as above.
  • Disable the access 
    • Disable the access to the application and display maintenance info page to users.
    • AppEngine storage can be also switched to read-only mode from the administration console. 
  • Backup
    • AppEngine provides no backup. Fortunately there are a couple of doable options:
      • Copy data using Datastore Admin (experimental)
        • With Datastore Admin tool You can safely copy data between different applications. This tool can be used to migrate from Master/Slave to HRD datastore, but also for a backup.
      • Export the repository using:
        • Bulk loader tool (yes, it works with Java).
        • Alternatively with your own backup service (for example REST-based) and tool - as I do.
      • Snapshots
        • Although AppEngine doesn't support snapshots (yet ;-) you can easily implement them yourself. For example by creating set of "snapshot" variants of your persistence beans. By adding 'snapshot' field to these beans you can even maintain multiple snapshots. Again you can use namespaces in this case.
        • This is in place (scope of single application) backup and/or transformation. 
    • The backup can include only entities (and entity instances) impacted by data model changes. Typically there is no need to dump whole storage. 
  • Transform (if needed)
    • Based on the size of the repository transformation to the new data model schema can be performed:
      • Offline on the exported image which requires subsequent drop of the all affected datastore tables and import of the new image. 
      • In-place transformation that is realized by running a set of statements (export/drop/import not required).
  • Deploy new application code
    • The same steps as above - new version upload, test and release.
  • Enable the access
    • Switch off the maintenance info page and enable the access to application again.
The procedure described above is pretty expensive as the amount of the data grows. You have to basically pay for re-imaging the application (requests, bandwidth, read and write operations). Such approach obviously becomes unusable once your storage size is bigger than small.

Zero downtime could be achieved for example using 2 isolated applications, data replication and DNS reconfiguration. I'm not that far yet. 

Let me also mention data model change best practices. They enable in place upgrades and work with any size of the storage. It might be obvious, but it is worth to remind. The motivation is to minimize the impact of changes you do (e.g. avoid maintenance windows):
  • Do not change field names
    • If there is really need for such a change, rather create a field with new name, deprecate the old one and define an administrative task that will copy the data from the old field to new field and/or default value. 
  • Do not change fields data types
    • Use deprecation in the same way as above.
  • Do not delete fields 
    • Simply deprecate them.
  • Make the fields optional (if possible)
    • This guideline might be translated to - allow null values on the persistence tier, because it can make your upgrades doable on top of AppEngine repository. For example consider that you want to introduce a new field and compare boolean vs. Boolean. The datastore upgrade will fail in the first case.
  • Use major releases to purge your data model
    • Major application release is opportunity to remove all deprecated fields, polish your data model and do the transformation of the data.
My application is opened to users for several months and I'm still in learning new tricks and improving the procedures described above. The obvious motivation is to  make sure that the application will run without any problems and outages .

Labels: , , ,

Sunday, May 29, 2011

MindForger: Problem Solver & Coaching Notebook


MindForger is a free problem solver and coaching notebook. Learn more about G.R.O.W. model, S.M.A.R.T. goals, action plans, S.W.O.T. analysis and Eisenhower matrix at mindfoger.com!

Labels: , ,

Thursday, January 20, 2011

pipni.cz: konfigurace DNS pro App Engine via Google Apps


V tomto česky psaném příspěvku bych rád popsal konfiguraci DNS na hostingu pipni.cz pro uživatele Google App Engine, kteří chtějí zpřístupnit svou aplikaci na vlastní doméně. Pokud tedy máte Google App Engine aplikaci moje-aplikace-123.appspot.com a vlastníte doménu moje-domena.cz, kterou vám společně s webem hostuje pipni.cz, tak postup je následující:
  •  Prvním krokem je vytvoření Google Apps pro vaši doménu moje-domena.cz, bez něhož to bohužel nejde.
  • Po založení účtu je s ním nejdříve nutné doménu svázat - v menu Domain settings, záložce Domain names je akce Add a domain or a domain alias. Vše je detailně a srozumitelně popsáno v dokumentaci Google Apps.
  • Součástí svázání domény je i konfigurace DNS - viz obrázek v záhlaví příspěvku (CNAME a MX záznamy).
  • Záhy přijdete na to, že některé vaše emaily jsou filtrovány jako spam resp. phishing, proto je nutné navíc přidat SPF záznam, což se v dokumentaci nikde nezdůrazňuje. Jak SPF nastavit ale popsáno je a na obrázku výše je opět vidět, jak a co přesně je třeba přidat (TXT záznam).
  • Konečně je možné přejít ke konfiguraci applikace hostované na Google App Engine. Jak na to je opět dobře zdokumentováno
Nyní je vaše aplikace dostupná např. na app.moje-doména.cz, nebo na jiné doméně třetího řádu.

Labels: , , , ,

Wednesday, December 08, 2010

MindRaider: GPL > Apache 2.0

Today is an important day for MindRaider project. In the hope that it makes MR more open and usable I decided to change its license from GPL to Apache 2.0. New distributions were not released yet, but all the formal steps and source code changes has been already made. As a consequence of this decision sketches were removed, because their rendering was based on the library that is released under GPL. However existing sketches are still accessible in your document repository and you can edit them with Jarnal.

It is also indication that I'm going to invest most of my spare time from now on to the new project. But don't be affraid - I still use MindRaider on daily basis. I also don't foreclose possibility that they will exist the upgrade path from MindRaider to that new project.

Feel free to drop me an email in case that you would be interested in maintaining MR ;-)

Labels:

Thursday, September 17, 2009

HTC Blackstone Flaws


Nah·det Masr asked me to explain why I was not satisfied with HTC Blackstone. Before I will answer, let me share with you a suggestion for HTC
  • If you want to test your product, find somebody who has never had Pocket PC before. 
Why? When you see a "feature" for the first time, you cannot believe it. But after some time you think that flaws I will be describing are normal (at least you can live with them) and after some time you even think that these are normal features (this is where I'm).

There are flaws related to HW/drivers, to Windows and to TF3D:
  • One of the reasons why I decided to buy Blackstone and not iPhone was Bluetooth A2DP. I do several hours of confcalls every week. The most comfortable setup for me is cell phone + Bluetooth heaphones. My handsfree/heaphones work perfectly for example with Nokia phones, but there are several problems with Blackstone. It might be that there is a way how to reconfigure the whole thing, but I was not able to do that. Also I believe that the behavior described below is the default:
    • After you pair phone and handsfree, phone should discover and connect to handsfree automatically whenever I switch them on. With Blackstone I have to do that manually (Nokia does that for you).
    • Presume that I'm expecting a call, both phone and handsfree are on and linked. It takes several seconds before sound/mic functionality is routed to handsfree. With Blackstone it works like this: you pick up the call, you use the phone normally (as without handsfree), after several seconds the sound is finally redirected from phones's speaker to the handsfree.
    • After you pick up the call/call to somebody, display is sometimes automatically turned off for a couple of seconds and this "feature" can not fixed. Obviously there is a light sensor that should take care of this, but the display is turned off even if the phone lies on the table in front of you. What I typically do is that I call to the conference and than want to go on mute - but you the display is black and you can not use Mute button to do that.
  • Screen rotation is switched off for all the applications except photos album and Opera. There is now way how to mark an application that it is capable of handling that. This problem can be partially fixed by Gyrator (rotation is allowed for all the applications).
  • The official name of Blackstone is HTC Touch HD, therefore you would expect that you can use your fingers to use it, but you get a hybrid instead (this is why this "touch" phone has stylus).
    • Keyboard (phone/compact/full) shows keys you press under your finger, therefore you don't know which key was actually pressed (compare with iPhone).
    • Transition from TF3D to Windows and back is unbelievable. It is schizophrenia. From finger friendly environment to stylus environment and back. You may try to use nails :) in Windows, but sometimes you simply have to use stylus (the best test of your skills is alarm setup using fingers). 
  • Applications/task switching use also pretty unusable. The suggested way how to do that is to use the Programs panel (because at most one instance of the application can be run). Of course this doesn't work - for example Opera opens new tab. Therefore what you must do is to click Home hardware button, move to the Programs panel and click the target application icon. Fortunately there is a fix for this - TaskFacade (pattern that used for example by HTC Hero/Android).
  • No battery status indication. To determine the status of battery go to Start, Settings menu item, System tab, Power icon. I fixed this using dciBattery.
  • I also don't like Windows alarm system. There is no list of missed/snoozed alarms as you know it from Outlook or SonyEricsson. To find a missed alarm, you have to start with a balloon next to the Start menu, you click the ballon, then you get to the status screen, click alarms icon, and finally you can see alarms one by one (no list). Pretty complicated.
  • If you download an (opensource) application, that is just extracted to the card, it cannot be added programs in the Start menu or Programs panel. Shortcut must be created first (otherwise it is impossible). But there is no way how to create a shortcut in Windows. You have to download an opensource tool that is capable of doing that. In my opinion this should be one of the basic utilities shipped with Windows.
  • Order of favorite contacts in TF3D's People tab cannot be changed. It also disappear whenever you need to resync with the contacts with Outlook.
  • ... and more ;)
This is what I still remember. I fixed several problems already and some of the flaws became features ;) Hopefully somebody will find this list useful.

Labels:

Tuesday, August 11, 2009

HTC Blackstone: PocketCM Keyboard


Blackstone has finger unfriendly keyboard - it was designed for stylus and thus it is almost unusable with touch display. As usually there is a fix - PocketCM keyboard ;)

Labels: ,

Thursday, July 30, 2009

GoogleWave Sandbox Account


I'm there ;) martin.dvorak at wavesandbox.com

HTC Blackstone


HTC Touch HD is my first pocket PC. I never had smartphone or pocket PC before. Obviously I had to decide what to buy, the selection was - iPhone 3G (3GS was not released yet at that time), G1, Nokia 5800 and HTC Touch HD. Obviously the final choice was subjective :)
  • Day 1: I understood what is the difference between ergonomicity of iPhone and WM6.1+TouchFLO3D shizophrenia.
  • Day 2: I decided to sell that damn thing!
  • Day 3: I discovered XDA Developers, did a couple of customizations and decided to give Blackstone a chance.
A couple of links and applications you may find useful:
Stay tuned ;)

Labels: