2009-09-05

Fixing graphical glitches using Spotify&Wine in Fedora 11

To reduce dual-booting to windows to a minimum, I recently setup Spotify under Wine in Fedora 11 (64-bit).
Initially, the audio went silent shortly after starting the application - this was fixed by changing the sound driver in winecfg to ALSA instead of PulseAudio.
A second problem was graphical glitches:

Googling found a nice blog post about what was missing:
yum install cups-libs.i586 fontconfig.i586 gnutls.i586 hal-libs.i586 libXcomposite.i586 libpng.i586 sane-backends-libs.i586 libXcursor.i586 libXinerama.i586 libXrandr.i586 libXrender.i586
After installing the above packages the graphical glitches disappeared and victory was declared:

2009-08-05

Worth repeating: How to easily add certificates to your keystore in java

Today I (yet again) had the below tiresome problem:
sun.security.validator.ValidatorException:
PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target
The problem occurred when accessing WSDL files on a test server. I cursed life...

Then, a helpful post how to easily add certificates at http://blogs.sun.com/andreas/entry/no_more_unable_to_find saved the day. Yay!


2009-05-20

New work-related blog (på svenska!)

Finally got inspired to setup a work-related blog at blogger: http://fredrik-at-pingpong.blogspot.com/

2009-05-18

Indentation problem when pasting into vim and the nopaste option

When pasting content into vim, such as a code snippet, it may mess up the indentation in a nested kind of way, with indentation increasing the further down you go.

The vim paste option fixes this - just issue :vim paste before pasting, and :vim nopaste when done.

As noted by the vim documentation, the underlying problem is that a terminal program, in contrast to a GUI one, may not recognize the difference between pasted and typed text.

2009-05-03

Java app to send geocaching data to your Nokia phone

I have documented a small java app that's useful for me that allows me to send geocaching information from geocaching.com to Nokia phones. See http://fornwall.net/landmarksender/ for more information.

2009-04-29

Session variables in postgresql

Consider a trigger that would like to prevent certain operations when executed by a web application, while allowing the operations when performed by a nightly batch job.

One way to solve this is to use a kind of session variables. The trigger lets the operation execute normally only if a session variable is set, which the batch job sets at the start of the execution. Below is an example illustrating one implementation for this in PostgreSQL.

First, we define a kind of namespace for our session variable (a customized option or variable class in postgres lingo) in postgresql.conf:

# comma-separated list of class names:
custom_variable_classes = 'myvariableclass'

Now, consider the following table:

CREATE TABLE my_table (ID INTEGER);
INSERT INTO my_table VALUES (1);

A trigger is to prevent DELETE:s from that table unless the session variable myvariableclass.idontcare is set:

CREATE OR REPLACE FUNCTION prevent_delete_unless_idontcare() RETURNS TRIGGER AS $$
DECLARE
idontcare TEXT;
BEGIN
SELECT INTO idontcare CURRENT_SETTING('myvariableclass.idontcare');
IF (idontcare != 'true') THEN
RAISE EXCEPTION 'Not allowed to delete unless myvariableclass.idontcare is true';
END IF;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER prevent_delete_unless_idontcare_trigger
AFTER DELETE ON my_table
FOR EACH ROW EXECUTE PROCEDURE prevent_delete_unless_idontcare();

Now let's see it in action:

fornwall=> DELETE FROM my_table;
ERROR: Not allowed to delete unless myvariableclass.idontcare is true
fornwall=> SELECT SET_CONFIG('myvariableclass.idontcare', 'true', FALSE);
set_config
------------
true
(1 row)

fornwall=> DELETE FROM my_table;
DELETE 1

See postgres documentation for the current_setting and set_config functions.

2009-02-23

PyS60 script to summarize top persons in SMS inbox and outbox

This requires the latest version of PyS60 (1.9.x):
# -*- coding:utf-8 -*-
import appuifw, collections, e32, inbox

def summarize_box(box, box_name):
counter = collections.defaultdict(int)
for message_id in box.sms_messages():
counter[box.address(message_id)] += 1

content = "Persons in " + box_name + ":\n"
for (name, count) in sorted(counter.iteritems(), key=lambda (x,y):(y,x), reverse=True):
content += u"%-3d: %s\n" % (count, name)

return content

content = summarize_box(inbox.Inbox(), 'Inbox')
content += "\n"
content += summarize_box(inbox.Inbox(inbox.ESent), 'Sent')

lock = e32.Ao_lock()
appuifw.app.body = appuifw.Text(content)
appuifw.app.exit_key_handler = lock.signal
lock.wait()