Monday, February 4, 2013

Announcing... Plasma wallpaper plugin

ExternalCommand 1.0.0

This is a plasma wallpaper that plugs into the standard Desktop Settings configuration widget and allows you to choose a command that will be periodically called to provide the name of the next wallpaper to display.

This enables you to get virtually any dynamic or static content as a wallpaper, even if you don't know programming, you can for instance, use the curl or wget commands to retrieve Wikipedia or Flickr's image of the day.

My first C++ and Qt project, hope you enjoy it.

The project is hosted on Sourceforge: http://externalcommand.sourceforge.net 

Screen shots:




Wednesday, August 1, 2012

My journey to value brand groceries

To boldly shop what I have never shopped shopped before

Everybody that ever walks into a super market is sooner or later confronted with value brand products. They usually have white packaging with a monochromatic colour scheme. The product name is usually the product itself, such as 'Lemonade', or 'Shampoo', or 'Spring roll'

There is also quite a bit of stigma to buying brand products, many a time have I observed people being shifty when putting value brand products in their trolley or at the checkout.

In today's society, you have got to be seen buying brand products. Brands are the new cool, and if you don't buy them, you may be regarded as backward.

It is easy to understand where this image comes from, after all, a massive amount of money is being spent in research and advertising to sell not just a product, but a feeling.

In this article I hope to convince you to overcome the taboo of value brand products, and show you that it really makes sense to consider generic when doing your groceries.

As to the stigma associated with the value brand foods, you may point out to your peers that they are content to use generic medicines, are they not, so if they trust their health to generic medicines, why not trust generic products for other things.

Before we proceed, a word of caution. I do not advice to blindly replace everything in your life with generic alternatives. My aim, however, is to underline their existence, and their quality.

On the Wikipedia article on generic brand, you may find such statements as “quality is equal to, if not better than established brands.”, and “may be a healthier alternative” Of course these are generalizations, and should be treated as such.

My journey into generic products began in May of this year. I was struggling with my new car finance and insurance premium, and on top of it I was heavily addicted to take away food.

After being completely broke the day after payday that month, I decided there and then that something would have to give. The first thing that went out the door were the pizza's and other take away. And so on and so forth until I sat down and calculated my monthly expenditure on food. It was a big shocker. 38% of my monthly income is spent on things that go in my mouth! After a full week of denying this figure I finally came to grips with it.

I set forth to bring balance to my diet as well as my budget. I explored my options, what about store brand products? I have no qualms over those. However, whilst they are cheaper they are often only a couple miserable pennies cheaper than their brand brethren.

I considered bulk buying but without a freezer, it is very impractical.

As I stood in the super market isle I noticed at one point that a generic packet of noodles costs 11 pence! Eleven pence. A super noodle packet costs 68 pence, six times as much!

I tentatively bought one packet of generic noodles thinking at worst I'd be out 11 pence.

Imagine my surprise when I actually liked the noodles. Better still, they have become my favorites. I now consider super noodles to be inferior to these ones.

My next gamble came with cheese. For a full 50 pence less than the main brand, I absolutely enjoyed a wedge of brie, which I couldn't fault on anything; Smell, taste, texture, packaging, all excellent.

On and on my experiments went. Each time I remember thinking: surely generic ones wont' be suitable for this, or I don't think I would trust generic for that, etc.

Until I come across cola, which for many of us, may be the most iconic of all products past, present, and future.

I must admit that the taste of the generic cola is significantly different than the brand taste.

To me it tasted like a cola flavored grenadine with carbonated water. However, taste is largely acquired, and we have been brainwashed for years how cola is supposed to taste.

If you are willing to give your body a couple days to get used to the taste difference, you may actually start to like it. What's more, you have the happy experience of only paying 17 pence per two liter bottle!

At times it will become apparent as to why a product is generic; for instance you may have a pack of assorted or only small sizes, whereas the brand has big, equal sizes, or, you may find yourself struggling with the generic packaging, whilst the brand has a packaging that opens easily. Other times there may be differences in preparation: oven cook only for generic, versus microwave cook, and oven cook for the brand, etc.

Another word of caution: the quality of the product can change in any direction without warning, according to the Wikipedia article, but so far, I have not come across any generic product I did not like, nor any of which I thought to be of questionable quality.

Things I have tried as generic

Product

Average saving

Notes

Noodles

0.57 £

Seasoning packet sometimes hard to open

White chocolate bar

1.79 £

(compared to organic)

Bree

0.51 £


Camenbert

0.48 £


Spring rolls

1.07 £


Lemonade / Cola

1.81 £


Oranges

1.31 £


Nectarine

1.05 £


Chips

1.35 £

A lot of small chips

Kitchen towel

1.10 £

A bit thin, use 1 extra sheet

Shampoo

4.23 £

A tiny bit too liquid

Conditioner

4.19 £

Excellent

Hand soap

1.61 £


Washing up liquid

1.40 £

A tiny bit too liquid



In conclusion, I will continue to embrace generic medicines, as well as generic grocery products, and I hope you will too.

PS: what is the I.T. angle, why is this posted on a Linux blog? In addition to my wanting to share my experiences with you, there is a clear analogy to the stigma of using Open Source products in corporate or SMB environments. The people in charge (of purchasing software) often consider a product more on its apparent value (higher cost equals higher value), rather than on potential merit.

Monday, July 30, 2012

On MySQL Merge tables

The MySQL Merge storage engine is nothing more than a means to link together identical MyISAM tables into one big one that you can query at your leisure. To create one, first create a table with a structure identical to one of the tables you want to link, for instance by doing a create like statement. The next, and final step, is to alter the new table's engine to merge and define the union. Simple as pie. It won't be long, however, before MySQL throws an error at you:

ERROR 1168 (HY000): Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist

The four causes outlined below should cover 98% of all the situations where you encounter this error.

  1. The tables really are different
    This may be because the schema of one of the tables is different, or was created with another MySQL version (and you copied the raw tables across at one point)
  2. Some, or all of the tables are not MyISAM tables
    Merge only works with MyISAM tables so the solution in this case is to change the storage engine type on all the tables to MyISAM
  3. Some, or all of the tables in your union do not exist
    MySQL does not check if the tables exist when you create the UNION, so it is perfectly possible to create a UNION on tables that don't exist, and MySQL will only tell you when you try to use the merged table.
  4. You created your union in a different database, and did not specify what database the tables are in
    This particular situation caused me much grief. Consider that you are using a MySQL interactive client, and that you have selected the test2 database, and your source tables are in the test database. Now when you write your merge, you may do:
    ALTER TABLE test.my_merged_table ENGINE=MERGE UNION=(
    	table1,table2,table3
    );
    

    You would expect MySQL to be smart enough to figure out that table1,table2,table3 are in the test database, since that is where the merged table is being saved.

    Except, it doesn't. It assumes table1,table2,table3 refer to the current database, and will create the merged table like that.

When you encounter that error, there is nothing else that you can do with that table, except to delete it.

If you are not sure why you are getting this error, you may want to look at exactly how MySQL defined your merge. Since describe and show create table and the likes do not work on a busted merge table, your only other option is to look at the physical merge definition file on the disk.

The file you are looking for, is in the MySQL data directory, in the sub directory of your database, and is called my_merged_table.MRG (replace my_merged_table with your own table name).

The format of the file is plain ASCII and it just lists, one entry per line, the tables, in order, that are part of the union for that table

Tuesday, February 8, 2011

MySQL Tricks

I've got two tips for you today.

First on the use of pagers


When using MySQL from the commandline through its mysql client, one enjoys usage speeds many phpMyAdmin users are extremely jealous of. On the downside, though, comes that your queries sometimes generate so much information that it becomes unmanageable, a veritable landslide of information, untamed, pouring down your terminal like an unending avalanche. Page after page after page runs down your screen. You sent a CTRL+C ages ago but your terminal still hasn't processed it... why oh why didn't I put a LIMIT on that query....

Luckily, there are ways with which to stem the tide of information.

I am, of course, talking about the pager command.

\P pagercmd

or

pager pagercmd;

The venerable less or more are obvious candidates for pagination.

However

It also works with grep. Say you want to find all records around a particular value but don't know precisely where it appears in the table(s) / output

pager fgrep -i -C 10 --color=yes searchstring

SELECT * FROM mytable;


This will run the query and pipe it through fgrep, doing a case-insensitive match, colourising the output, and showing 10 lines before and after the match.

Of course, for advanced matching you can use egrep or grep -E

Secondly, on the use of the information_schema database


The information_schema database is a very welcome ANSI addition to MySQL and I'm sure you can find heaps of information about it elsewhere. However, I invite you to explore it for yourself. Almost every SHOW command, which output often cannot be filtered directly, fetches (or exposes) its information through the information_schema database.

Say you want to list all processes from a particular user. You could of course use the pager trick mentioned above, or, you could use the information_schema database:

SELECT * FROM information_schema.processes WHERE user='username';

There is no need to include the @hostname part because the hostname is stored in a different column.

Just like the /proc filesystem on Linux, so does the information_schema database provide an easy to use insight into its core.

Speaking of the /proc I just this morning came across a rather nice little article about it, see here on Ksplice blog.

Saturday, January 22, 2011

dasKeyboard

After a few days of waiting, which seemed to pass so slowely, they seemed like weeks, my new keyboard finally arrived. It is a dasKeyboard Ultimate, with utterly blank keylabels. Many of my colleagues where impressed by this, but even more so by the price. Having to explain to my colleagues just why I chose to spend 130 pounds on a keyboard, I came to realise that I had actually bought the keyboard without exactly knowing why. Sure, I do have a habbit of buying new keyboards every other month or so, but never this expensive. So instead, I said, give me a couple of days, and I'll tell you why. A couple days later, I definitely knew why I had bought it.

First of all, unlike other keyboards that come with blank keys, this one actually has a slightly raised surface on the two home keys, and on the 5 key on the keypad. Now I can touch-type withouth those, but I find it takes longer to have to reposition your fingers by going all the way to the edge of the keyboard, then sliding over the left shift just to get back to the start position. No, having these reliefs on the home keys helps immensely.

The other thing I do like a lot is the black look. Anybody that has seen a white keyboard go yellow/brown-ish from sigarette smoke, and white keys go blackish from unwashed hands can agree. White should be outlawed on keyboards; black is the way to go.

Now the clicking sounds. I do not know if I will still like the clicking noises in a month's time, or a year's time, but for now, I enjoy the sounds and just hearing them makes me want to type faster and faster. Having full n-key roll-over also means that many more of my keystrokes are correctly interpreted. Other keyboards have difficulties keeping up sometimes.

That's all I can think of at the moment, I will, of course, be posting more about dasKeyboard after a month or so.

Saturday, December 25, 2010

Touch typing

Learning touch-typing


One of the most important skills as an IT practitioner, is touch typing. Anybody can touch type providing they want to spend time to practice.

You don't need anything except a computer or typewriter, to learn to touch-type, but in this day and age, learning to touch type on the computer is much more fun.

A plethora of touch-type-tutors exist out there, both free, and commercial, but the best one by far is the ktouch program, for the KDE desktop. It can also run under gnome, and under cygwin. What I like about it is that it has just the right amount of eye-candy, and functionality, and adding new lessons is very easy.

It comes packed with most common keyboard layouts, and many lessons in many languages, even, with a series of lessons designed for English-speaking dvorak users.

I switched to dvorak a couple years ago, and have often regretted not switching sooner. I find they layout to be the most effective one so far, and with the help of ktouch, and lots of practice, I now get to 300+ characters a minute when typing English text.

As a programmer, however, English text isn't the main thing I am typing. I still have difficulties with typing numbers, and symbols, and for that reason, I have created a ktouch lessons specifically designed for teaching numbers and symbols to dvorak users.

This is the first part in a series of two, and covers almost all the numbers and symbols on the top row.

kTouch Lecture on Numbers & Symbols in dvorak

Tuesday, January 26, 2010

Simple iptables port forwarding

Preface


I always enjoy learning new things, specially when it is about iptables. This beauty has been in my toolbox for so long, it's hard to even remember what life was like without it...

Today, I ran into some issues. I needed to capture all inbound traffic on a specific port and redirect it to another because of a change in server software.

Preparation


Before you even think about changing your firewall rules, there's 2 very important things to do first:

  1. Enable packet forwarding
  2. Load the iptables NAT module
You can either do those two things manually, but better is to write a script that does it, which you can put in your init.d or rc.d directory to load before loading iptables

Put whatever logic you need in that script, but always make sure that it successfully executes these commands:

# turn on support for packet forwarding

echo 1 > /proc/sys/net/ipv4/ip_forward

# load the iptables nat module

modprobe iptable_nat


I'm not going to show you what command lines to use with iptables to accomplish the port forwarding. I disagree with people always saying you shouldn't edit the iptable rules file directly.

The iptable rules


If you know a bit about generic iptables filtering, you probably already know that the layout commonly employed is this:

INPUT filtering
OUTPUT filtering

COMMIT


If you already have that kind of filtering in your rules, then that is fine, you needn't change any of those.

Instead, we are going to work on what happens before it reaches the INPUT, and OUTPUT filters, what happens during the PREROUTING stage; the stage that packets are in before they go to the INPUT/OUTPUT filters.

In our example, we are going to route all inbound packets on port 8080 to port 80, without the daemon listening on port 80 being any the wiser. Users can then use either port 8080 or port 80 and they will always go to the same service.

In your iptable rules file, above any existing rules or preface, place the following rules:

# Redirect traffic on port 8080 to port 80

*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]

-A PREROUTING -d 222.222.222.2 -p tcp -m tcp --dport 8080 -j DNAT --to-destination :80

COMMIT



# `normal' filtering goes here


Remember to test if you rules pass a cursory test by running

iptables-restore -v --test < rules_file

Although you should know that iptables-restore mostly checks syntax so when you deploy your new rules for the first time, either make sure you are on a physical console, or have set up a cron job to run every two minutes and stop the iptables service

Notes


In the above example, the things to note most, are the parts colored in red.

To begin, there's the -d 222.222.222.2 part; it basically says, look for packets sent to the private address 222.222.222.2. You should adapt this to match the private ip address of your server.

Next, there's the --dport 8080 part; change this to the port you want to forward

Last, the --to-destination :80 means that all the packets that match the rule should be forwarded to port 80 on the same interface as they were received.

See the manual page for some more information:

http://www.netadmintools.com/html/8iptables.man.html#lbBI

Now, remember a bit back I said you didn't have to change your `normal' iptable rules? I might have mislead you a bit there...

If you haven't already got rules that will allow access to the port you are forwarding to, then you will need to add filter rules for those.

Here's a simple iptable rules file that will do the port forwarding from above, plus some `normal' traffic filtering to allow access to that port.



# REMEMBER TO ENABLE PACKET FORWARDING
# AND REMEMBER TO LOAD THE iptable_nat MODULE

# Reroute inbound traffic from port 8080 to port 80
*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]

-A PREROUTING -d 222.222.222.2 -p tcp -m tcp --dport 8080 -j DNAT --to-destination :80

COMMIT

# `Normal' traffic filter

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]


#** FILTER INBOUND TRAFFIC

# Accept packets from localhost

-A INPUT -i lo -j ACCEPT

# Accept data relating to an existing or related connection

-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

# Allow access to port 80

-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT

# Allow access to ssh (remove as needed)

-A INPUT -p tcp -m tcp --dport ssh -j ACCEPT

# Everything else is rubbish

-A INPUT -j DROP

COMMIT



That about sums it up. Let me know should you need some clarification.