Using ImageMagick for batch image processing in Picasa

07/27/2011
tags: , ,
Olexandr Savchuk

Our office is using Google Picasa to process a lot of images. We’ve used Picasa for years now, and it’s a very convenient instrument for our needs. However, while it has many built-in functions to process and modify images, there are some missing, or only available through complicated multi-stage user interaction, which is unacceptable for the amount of work our employees have to get done. My solution to this is a combination of two ingredients: the command-line ImageMagick toolkit for image processing, and Picasa’s Button API.

The example application I’ll explain here is a utility to combine multiple images into one in one click directly from a Picasa folder view. However, it is very easy to modify this to perform various other batch image processing tasks directly from Picasa.

Read the rest of this entry »

Android: scroll a ListView with volume keys

02/24/2011
Olexandr Savchuk

Scrolling a list view in an Android app using the volume buttons on the side of the phone is actually quite easy. Not knowing this, yesterday I spent some time looking for a nice easy tutorial to do this, and found nothing. Having it coded and released in version 1.0 of Quoter, I thought it’d be a good thing to write one myself.

Basically, what you need to do is to override the dispatchKeyEvent() method in your Activity, and intercept key presses for the volume keys, leaving the other keys untouched. This is how I did it, fairly straightforward:

@Override
public boolean dispatchKeyEvent(KeyEvent event) {
	if (event.getAction() == KeyEvent.ACTION_DOWN) {
		switch (event.getKeyCode()) {
		case KeyEvent.KEYCODE_VOLUME_UP:
			scrollToPrevious();
			return true;
		case KeyEvent.KEYCODE_VOLUME_DOWN:
			scrollToNext();
			return true;
		}
	}
	if (event.getAction() == KeyEvent.ACTION_UP
		&& (event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP
			|| event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_DOWN)) {
		return true;
	}
	return super.dispatchKeyEvent(event);
}

Note that we only execute our code on the ACTION_DOWN event – the ACTION_UP event is only caught in order to mute the keypress sound. Then event.getKeyCode() is checked, and if the key pressed is volume up or volume down, my scrolling functions are called and the function returns. In any other case (another event or different keys) the execution is passed on to the standard key press handler.

Next are the scrolling functions to scroll the ListView. The problem with these is, you can scroll to any x/y coordinates using the scrollTo method. But what I needed is to scroll to the next visible item, since Quoter is a reading app and one wants to scroll to the next qoute in the list and read it. So this is what I did:

private void scrollToNext() {
	int currentPosition = getListView().getFirstVisiblePosition();
	if (currentPosition == getListView().getCount() - 1)
		return;
	getListView().setSelection(currentPosition + 1);
	getListView().clearFocus();
}

private void scrollToPrevious() {
	int currentPosition = getListView().getFirstVisiblePosition();
	if (currentPosition == 0)
		return;
	getListView().setSelection(currentPosition - 1);
	getListView().clearFocus();
}

First we get the list position of the first element visible on screen. If it’s already the last position in scroll direction, we do nothing. If it isn’t, we set the selection in the list to the next item; this automatically scrolls the list (same thing happens if you use the D-pad keys to navigate a list). The only problem now is, the list item becomes selected and highlighted, which we don’t want since we’re reading text from it. By clearing the focus from the list, we remove the selection. All done.

OpenTTD WebConfig

10/10/2010
Olexandr Savchuk

A tool to configure an OpenTTD server via web interface.

Tested with OpenTTD 1.0.4, Apache2 and PHP 5.2.4 on Windows and Ubuntu Linux. No reason it shouldn’t work on any other platform, given PHP.

Project hosted at the OpenTTDCoop DevZone:
http://dev.openttdcoop.org/projects/ottd-webconfig

OpenTTD – Junctions and stations

10/7/2010
tags: ,
Olexandr Savchuk

OpenTTD is an open source remake and expansion of the 1995 Chris Sawyer game Transport Tycoon Deluxe. It is an “Urban planning and simulation game”.

Wikipedia

I’ve once again started playing OpenTTD – it’s been years now. OpenTTD, as stated above, is an open source remake of a strategy game called Transport Tycoon Deluxe from the MS-DOS times. The goal is to create a transportation network for passengers and cargo using trains, trucks, ships and planes, and to make more money than your opponents. A couple of screenshots to illustrate:

Efficient rail networks in the game can become very complex, with hundreds of trains rolling on them. Such networks cannot be built without large intersections, and the traffic flow is strongly influenced by the junction design efficiency. In this post, I’ll collect a few junction and station designs I made, that could become helpful for some OpenTTD players out there.

A day in the life of a Programmer

03/16/2010
Olexandr Savchuk

DIY CCFL display backlight

03/12/2010
tags: ,
Olexandr Savchuk

I often work at my PC in the dark, and I know it’s not very good for the eyes to look at the bright screen in the dark surroundings. I checked multiple ideas concerning the problem, including a LED backlight from an IKEA lamp on a friend’s TV, but I never came to building something like that myself. One time I even had my desk lamp turned behind the screen to act as a backlight of sorts, but it was obvious that was not a solution to last.

A solution came suddenly, when I saw some CCFLs on sale in an online hardware store for €4,99. One trip to the shops and 7€ spent later I’m sitting here in the dark, typing this text and having my eyes not stressed at all :)
Read the rest of this entry »

Android App – Quoter

03/10/2010
tags: , ,
Olexandr Savchuk

Android Market: Quoter Quoter QR Code
Read fun internet quotes from a variety of websites. Perfect entertaining while waiting in queues, public transport and similar.

Features include:
- Choosing which sites to read from
- Reading latest quotes
- Saving quotes for offline reading
- Sharing quotes via SMS, email, Facebook etc.

If you like my app, please buy the donate version – it’s ad-free!

Any comments and suggestions are welcome here in the Market or per eMail.

Quote sources in English:
- bash.org: latest, random, random >0, top100
- qdb.us
- quotebucket.org
- fmylife.com

Quote sources in German:
- german-bash.org: latest, random
- ibash.de
- swissbash.ch
- abash.at
- SMSvonGesternNacht
- school-bash.org

Quote sources in Russian and Ukrainian:
- bash.org.ru: latest, random, abyss, abyssbest, all with pagination support!
- ibash.org.ru
- ithappens.ru
- zadolba.li
- bash.bynets.org (bash.org.by)
- ukrbash.org
- killmepls.ru
- nefart.ru

§ 162. Writer’s block

02/21/2010
Olexandr Savchuk

Let’s have a simple experiment. Without stopping, let’s say all the words we know (or ask a friend to do this). The first ten words will come at once. Then we will look for and name objects in the room – maybe ten of those. Then we remember a few unusual words from the far distant end of our vocabulary. Abd then we stop, because we run out of words.

If we try to describe anything known to us with our words, there will be no word deficiency. One description will be good, another one not so – that will tell the difference in the describer’s skill. But noone will stop looking for the next needed word in a simple story.

An “idea crisis” can only happen, if the designer sets out aiming to think of something new and unusual.

Something new and unusual cannot be thought up – it can only be discovered while working on a specific, defined goal. It’s the same difference as there is between recitation of words and a story.

A writer’s block is a dead end of a senseless way.

© art.lebedev, my translation from Russian

SVN for website deployment – watch it

02/17/2010
tags: ,
Olexandr Savchuk

Many webmasters use SVN not only as a version control system during website development, but also as a deployment tool for easily synchronising the development environment with the production server. A serious flaw has been uncovered in the system that many are unaware about, and that poses a significant security threat, allowing a potential attacker to gain access to source codes and configuration files. To understand that flaw, we must understand a little about how the SVN system works.

In every folder that is managed with SVN, it creates a hidden .svn subdirectory. In it, a list of all files and subdirectories in that folder are stored, together with technical information about their history as well as every file itself. The file .svn/entries contains a list of all files and directories in the folder where .svn is located, and the directory .svn/text-base contains the recent revisions of all files, with .svn-base added as an additional extension.

project
  |- index.php
  |- config.php
  |- dir
  |    |- .svn
  |    |    |- entries
  |    |    '- text-base
  |    |         '- file.ext.svn-base
  |    '- file.ext
  |- .svn
  |    |- entries
  |    |- text-base
  |    |    |- index.php.svn-base
  |    |    '- config.php.svn-base
  |    '- ...
  '- ...

Now, normally the .svn is hidden, and doesn’t bother anyone much. However, with default settings, the webserver will treat the files inside it just like any other file – if requested directly, those files will be served. Using the entries file, a list of accessible files can be obtained – among which there might be configuration files or others containing confidential information. And since the files in the text-base directory have their extension changed they will not be processed by, for example, PHP – the sourcecode will be shown as it is.

This vulnerability was discovered some time ago by a group of Russian programmers. They did a scan of a large amount of websites, including some fairly big names in the .com, .de and .ru zones, and the results were staggering. Owners of hundreds of websites were notified of the vulnerability, and after it was closed, some details were disclosed on a large Russian IT blog Habrahabr.

There are multiple ways of securing against the vulnerability. Among the most simple and efficient are:

  • Blocking web access to the .svn directory altogether using, for example, the .htaccess file for Apache.
  • Using the svn export command instead of the usual svn checkout does not produce the .svn directory in the first place.

While those solutions might seem obvious (and they really are), I was very surprised when I did a simple check among a few websites from my bookmarks list. So webmasters – if you haven’t yet known about this, beware.

How Fanboys See Operating Systems

12/19/2009
tags:
Olexandr Savchuk