Calibre Leaving Old News on My Sony Reader — Delete It!

I haven’t had much use for book readers, but I saw a Sony PRS-300 in the Sony Outlet Store for only $40 so I bought it. No Linux software, but it does work well with Calibre, so I’ve been very happy with it. It is tiny and has amazing battery life and it is a great alternative to lugging my tablet around all the time.

Calibre has a great feature where it can grab things off the Web, make them into eBooks and put them on your device. They have lots of precreated feeds like the BBC, CNN, etc. There is an option to tell Calibre to remove the news after it is a certain number of days old.

I thought this wasn’t working because stuff was accumulating on my device. However, a little research showed that it is a quirk of Calibre. It removes the news from your library but not the Reader! Oops.

I decided I can run a little script to trim old news from the reader. I may change the Calibre shortcut to do this automatically before it runs Calibre in the future. Here’s the script in case you find it useful:

NOTE: DO NOT USE THIS CODE, use the code below!

#!/bin/bash
# Detele old news files from Sony Reader
# Usage: trimsony [days]
# Default is 5 days (delete things older than 5 days)
echo NO DON'T USE THIS!!!
exit 0

# Check this file to see that reader is connected
READERPRESENTFILE=/media/READER/metadata.calibre
# Directory that holds news
MEDIADIR=/media/READER/database/media/books/News

if [ ! -f $READERPRESENTFILE ]
then
echo Error: Reader not connected! 2>&1
exit 1
fi
DAYS=5
if [ "$1" != "" ]
then
DAYS=$1
fi
# All subscriptions are in /media/READER/database/media/books/News
find $MEDIADIR -type f -mtime +$DAYS -exec rm {} \;
exit 0

You can change the directories and the number of days used by default pretty easily if you like.

Enjoy!

UPDATE: I’m not so sure this is a good idea anymore. I have to run more tests. It does work, but I think deleting files off the Sony makes its media.xml database get out of sync and I can’t figure out what syncs it. Sometimes Calibre gets the dreaded media.xml is corrupt message and then getting it to stop doing that is a massive inconvenience. I’m still looking into it, but be warned!

Update 2: Ok I’m back to try again. I found Calibre has a poorly-documented ebook-device command that lets you do command line operations. I also used kdialog to give a progress bar because it is slow. That means you need kdialog, qdbus, and other stuff that you already have if you are running KDE. However, you could remove that or replace it with other things if you aren’t.


#!/bin/bash
# Detele old news files from Sony Reader
# Usage: trimsony [days]
# Default is 5 days (delete things older than 5 days)

# Mount directory (no trailing slash please)
MOUNT=/media/READER
# Check this file to see that reader is connected
READERPRESENTFILE=$MOUNT/metadata.calibre
# Directory that holds news
MEDIADIR=$MOUNT/database/media/books/News

if [ "$1" == '-' ]
then
dbusRef=$2
CT=`qdbus $dbusRef Get "" value`
CT=`expr $CT + 1`
qdbus $dbusRef Set "" value $CT
BASE=`basename "$3"`
qdbus $dbusRef setLabelText "Removing $BASE"
FILE="${3##$MOUNT}"
echo -n $FILE
ebook-device rm "$FILE"
exit 0
fi

if [ ! -f $READERPRESENTFILE ]
then
echo Error: Reader not connected! 2>&1
exit 1
fi
DAYS=5
if [ "$1" != "" ]
then
DAYS=$1
fi
# All subscriptions are in /media/READER/database/media/books/News
COUNT=`find $MEDIADIR -type f -mtime +$DAYS | wc -l`
if [ "$COUNT" != 0 ]
then
# this desyncs the database!
#find $MEDIADIR -type f -mtime +$DAYS -exec rm {} \;
dbusRef=`kdialog --progressbar "Deleting old news" $COUNT`
qdbus $dbusRef Set "" value 0
find $MEDIADIR -type f -mtime +$DAYS -exec $0 - "$dbusRef" "{}" \;
qdbus $dbusRef close
fi
exit 0

Linux Multimonitor Madness

I’m addicted to having two monitors. It drives me crazy to go back to just one. Well yesterday one of my 19″ panels went white and stayed that way. Luckily with black Friday sales going on I was able to replace it on the cheap. However, most monitors these days are widescreen, so it takes a little getting used to. I replaced both monitors so they’d match (they were cheap) so my X screen is effectively 3200×900 now.

With all that real estate, I wanted some way to manage windows so they could be tiled effectively on one monitor (which is basically how I use two monitors; one app on one screen and another on the other screen). I’ve talked before about using wmctrl to script windows so I dusted off my shell programming skills and wrote “place”.It assumes your monitors are sitting next to each other (not stacked).

Place chops your screen up into 8 zones:

ABCD
EFGH

So your left screen is ABEF and your right screen is CDGH. You can also use 1 for the left screen and 2 for the right screen

How to use it: Run the script (hint: assign it a global shortcut key). It will prompt you to press OK and then click on a window. Click on the window you want to adjust, and the script  will prompt you to enter the grid letters. Enter them in order.

So you might enter A to get it at the top left or GH to get a double wide window at the bottom right. Or DH to get a double high window (the acronym is coincidental).If you enter CDGH or 2 the app will jump to the 2nd screen

What you need:

Stuff you can get out of the repos:  Bash (duh), zenity, xwininfo, gawk, and wmctrl. You also need to use a window manager that works with wmctrl (most do). The script picks up the reported size of your screens automatically. This could be a problem if you have two mismatched screens since I know at least TwinView (NVidia) reports a bigger size (so if your screens are 1600×900 and 1600×1024, TwinView reports 3200×1024.

Options (all optional):

-w 10 – Set width trim to 10 (adjusts the width down to account for decor)

-t 40 – Set height trim to 40

-i 0x4942 – Use window ID instead of prompting for window

-n ‘mywin’ – Identify window by title instead of prompting

Note: -n doesn’t work well when 2 windows have same title! Also, use -i -n or nothing but do not use -i and -n together

-x 1600 – Override screen width to 1600

-y 900 – Override screen height to 900

-s ABEF – Use placer string and don’t prompt

-r – Do not raise window

-q – Quiet (do not show intro dialog)

Here’s the script (or download it from .

#!/bin/bash
# Dual Monitor Window placement script -- Williams alw@al-williams.com
# Version Beta 1, November 28 2009 - http://www.hotsolder.com

## This little script chops your screen up into 8 zones:
#  ABCD
#  EFGH
# (Obviously I'm assuming you have two monitors horizontally)
# So your left screen is ABEF and your right screen is CDGH
# You can also use 1 for the left screen and 2 for the right screen
#
# How to use it: Run this script (hint: assign it a global shortcut key)
# It will prompt you to press OK and then click on a window
# Then it will prompt you to enter the grid letters. Enter them in order.
# So you might enter A to get it at the top left or GH to get a double
# wide window at the bottom right. Or DH to get a double high window.
# if you enter CDGH or 2 the app will jump to the 2nd screen
#
# What you need:
# Stuff you can get out of the repos:
# Bash (duh), zenity, xwininfo, gawk, wmctrl
# You also need to use a window manager that works with wmctrl (most do)
#
# The script picks up the reported size of your screens automatically
# This could be a problem if you have two mismatched screens since
#  know at least TwinView (NVidia) reports a bigger size (so if your
#  screens are 1600x900 and 1600x1024, TwinView reports 3200x1024
# So you may want to override
# Also, you will want to trim down the exact values so the window edges
# and all fit. You can adjust WTRIM and HTRIM below or use the options

# Options (all optional)
# -w 10 - Set width trim to 10
# -t 40 - Set height trim to 40
# -i 0x4942 - Use window ID instead of prompting for window
# -n 'mywin' - Identify window by title instead of prompting
# Note: -n doesn't work well when 2 windows have same title!
# Note: Use -i -n or nothing but do not use -i and -n together
# -x 1600 - Override screen width to 1600
# -y 900 - Override screen height to 900
# -s ABEF - Use placer string and don't prompt
# -r - Do not raise window
# -q - Quiet (do not show intro dialog)

# TODO: Custom grid dialog to pick on a 4x2 grid
# I may do this with kdialog and/or pick zenity or kdialog depending on
# which is available

# max width and height trim down (adjust to suit)
WTRIM=40
HTRIM=40
PROMPTCMD=zenity
XWIOPT=
XWIARG=
CELLS=
NORAISE=0

# Max Width and Height
MW=`xwininfo -root | awk ' /^[ \\t]*Width:/ { print $2 }' `
MH=`xwininfo -root | awk ' /^[ \\t]*Height:/ { print $2 }' `

# process options
while getopts hw:t:i:n:qx:y:s:r o
do
	case "$o" in
	r) NORAISE=1 ;;
	w) WTRIM="$OPTARG" ;;
	t) HTRIM="$OPTARG" ;;
	i) XWIOPT="-i" ; XWIARG="$OPTARG"  ;;
	n) XWIOPT="-name" ; XWIARG="$OPTARG" ;;
	x) MW="$OPTARG" ;;
	y) MH="$OPTARG" ;;
	s) CELLS="$OPTARG" ;;
	q) PROMPTCMD=false ;;
	[?]|h) echo "Usage $0 [-x screen_width] [-y screen_height] [-w width_trim] [-h height_trim] [-i window_id] [-n window_name] -q" 1>&2
	exit 1 ;;
    esac
done

# Calculate Trimmed sizes
MWT=`expr $MW - $WTRIM`
MHT=`expr $MH - $HTRIM`

# Calculate 1 cell width and height and their trimmed versions
W1=`expr $MW / 4`
H1=`expr $MH / 2`
W1T=`expr $MWT / 4`
H1T=`expr $MHT / 2`

# prompt user so as not to confuse
if [ "$XWIOPT" == "" ]
then $PROMPTCMD --info --text 'Press OK and then select a window' --title 'Window Placer'
fi

# find out ID of window selected
if [ "$XWIOPT" != "" ]
then WID=`xwininfo $XWIOPT "$XWIARG" | awk '/xwininfo: Window id:/ { print $4 } ' `
else WID=`xwininfo | awk '/xwininfo: Window id:/ { print $4 } ' `
fi
if [ "$WID" == "" ]
then
	echo  "Unknown window" 1>&2
	exit 2
fi

# get position requested
if [ "$CELLS" == "" ]
then CELLS=`zenity --title 'Window Placer' --entry --text 'Your screens are divided into a 4x2 grid.
The top 4 cells are ABCD and the
bottom cells are EFGH. Or pick a screen (1 or 2).
Pick which cells you wouldd like for this window to occupy.

ABCD    -or-   12
EFGH' `
  if [ $? -ne 0 ]
  then
    echo Cancelled
    exit 3
  fi
fi

# Do the processing
case $CELLS in
[aA])
	X=0
	Y=0
	W=$W1T
	H=$H1T
;;
[bB])
	X=$W1
	Y=0
	W=$W1T
	H=$H1T
;;

[cC])
	X=`expr 2 \* $W1`
	Y=0
	W=$W1T
	H=$H1T

;;
[dD])
	X=`expr 3 \* $W1`
	Y=0
	W=$W1T
	H=$H1T

;;
[eE])
	X=0
	Y=$H1
	W=$W1T
	H=$H1T
;;
[fF])
	X=$W1
	Y=$H1
	W=$W1T
	H=$H1T
;;

[gG])
	X=`expr 2 \* $W1`
	Y=$H1
	W=$W1T
	H=$H1T

;;
[hH])
	X=`expr 3 \* $W1`
	Y=$H1
	W=$W1T
	H=$H1T

;;

[aA][bB])
	X=0
	Y=0
	W=`expr 2 \* $W1T`
	H=$H1T
;;

[bB][cC])
	X=$W1
	Y=0
	W=`expr 2 \* $W1T`
	H=$H1T
;;
[cC][dD])
	X=`expr 2 \* $W1`
	Y=0
	W=`expr 2 \* $W1T`
	H=$H1T
;;
[eE][fF])
	X=0
	Y=$H1
	W=`expr 2 \* $W1T`
	H=$H1T
;;

[fF][gG])
	X=$W1
	Y=$H1
	W=`expr 2 \* $W1T`
	H=$H1T
;;
[gG][hH])
	X=`expr 2 \* $W1`
	Y=$H1
	W=`expr 2 \* $W1T`
	H=$H1T
;;
[aA][bB][cC])
	X=0
	Y=0
	W=`expr 3 \* $W1T`
	H=$H1T
;;

[bB][cC][dD])
	X=$W1
	Y=0
	W=`expr 3 \* $W1T`
	H=$H1T
;;
[eE][fF][gG])
	X=0
	Y=$H1
	W=`expr 3 \* $W1T`
	H=$H1T

;;

[fF][gG][hH])
	X=$W1
	Y=$H1
	W=`expr 3 \* $W1T`
	H=$H1T
;;
[aA][bB][cC][dD])
	X=0
	Y=0
	W=$MWT
	H=$H1T
;;
[eE][fF][gG][hH])
	X=0
	Y=$H1
	W=$MWT
	H=$H1T
;;

[aA][eE])
	X=0
	Y=0
	W=$W1T
	H=$MHT
;;
[bB][fF])
	X=$W1
	Y=0
	W=$W1T
	H=$MHT
;;
[cC][gG])
	X=`expr 2 \* $W1`
	Y=0
	W=$W1T
	H=$MHT
;;
[dD][hH])
	X=`expr 3 \* $W1`
	Y=0
	W=$W1T
	H=$MHT
;;

[aA][bB][eE][fF]|1)
	X=0
	Y=0
	W=`expr 2 \* $W1T`
	H=$MHT
;;
[bB][cC][fF][gG])
	X=$W1
	Y=0
	W=`expr 2 \* $W1T`
	H=$MHT
;;
[cC][dD][gG][hH]|2)

	X=`expr 2 \* $W1`
	Y=0
	W=`expr 2 \* $W1T`
	H=$MHT
;;

*)
	zenity  --title 'Window Placer' --error --text 'Unknown position command'
	exit 5
;;  

esac

if [ $NORAISE -eq 0 ]
then wmctrl -i -R $WID
fi
wmctrl -i -r $WID -e 0,$X,$Y,$W,$H
exit $?

I/O Scheduling Eleveator and Gambas

Gambas Program

I recently had to work with some very large files under Kubuntu 8.10 and found that when I was decompressing or copying these large files the system would become sluggish. Keep in mind this is with dual 3Ghz AMD cores and 4GB of RAM. The CPU load was almost nothing, but for some reason the disks were blocking the whole system.

Looking around, I wasn’t the only one to have this problem. It turns out Linux can use several I/O schedulers or “elevators”. The idea is to try to service disk requests as the heads go by instead of moving the heads back and forth for each request. There are 4 schedulers:

  • noop – Don’t schedule
  • anticipatory – Try to anticipate disk usage patterns
  • deadline – Service requests if they haven’t been serviced by a deadline already
  • cfq – Completely fair; this is the default in recent kernels

Turns out the cfq scheduler is what was doing it — not sure if it is a bug per se or just some interaction with my hardware. Anticipatory worked best for me. There are two ways you might change the schedule policy. At run time you can send the right string to /sys/block/XXX/queue/scheduler (where XXX is the device name). So if your main disk is /dev/sda you might say:

echo deadline>/sys/block/sda/queue/scheduler

You can cat the same file to find out which one is current (it will be in square brackets). You can also edit your bootloader line to include the option elevator=XXX to set the system-wide default (XXX can be noop, as, deadline, or cfq — as is anticipatory).

I wrote a simple Gambas program using Gambas 2.9 to view and set the scheduler. It uses either kdesudo or gksudo to give you root privleges to write to the system file. I haven’t tried to distribute a Gambas program before — I know it depends on having Gambas in the system repositories and of the same version, so I’m not sure how useful it will be to others unless they are Gambas developers. None the less, I have a

and a available.

Man Pages for X

If you use the Linux command line a lot you know the value of man (that’s man as in manual, not as in a guy). But I do find it annoying that when I quit paging through man’s output, the output disappears. Of course, you could fix this by changing the pager, but what I really wanted was a way to just have a “help window” show up that I could refer to while I was typing. Of course, there is the venerable xman, but it is a clunky old X application with a poor interface.

I noticed manview the other day in the repositories (part of manedit). I installed it (on Hardy it shows up under Development, but your milage may vary). Of course, then you have to remember to type manview instead of man — and I’ve been typing man for nearly 30 years.

So here’s the latest two entries in my ~/.bashrc:

  alias man=xman



 xman ()
{
    if [ -z "$DISPLAY" ]; then
        'man' $@;
    else
        manview $@ &
    fi
}

This way when you type “man” from an X-Window shell you get the GUI but over a non-X shell you get good old fashioned man (be sure your shell function quotes man or you’ll get an endless loop thanks to the alias). Of course, you need to make sure manview is installed (for example, sudo apt-get install manedit).

Autohotkey for Linux — Sort Of…

I’ve enjoyed using AutoHotKey on Windows. If you haven’t used it, it is kind of hard to explain exactly what it is. Its sort of a scripting language, but it can manipulate windows, send key strokes, mouse events, and so forth.

Its surprising that there isn’t really a good analog to this program in Linux. Sure you have all sorts of scripting languages including the shell. But I haven’t really seen any that do a good job manipulating windows.

However, in true Unix fashion, there are a few tools you can use to make your favorite scripting language work with your desktop — assuming you have a compatible window manager (which you probably do).

The two main weapons in the macro arsenal are xmacro and wmctrl (chances are you can download them right from your package repository). You might also want a utility that lets you make simple dialog boxes for scripts. I like Kommander, but that’s not as lightweight as, say, Zenity, but that’s purely optional.

The wmctrl package allows you to list the current windows. You can raise a window and do other basic operations like set the window title or switch desktops. Here’s a great page about wmctrl: http://jrandomhacker.info/Wmctrl_examples [broken link]. Note that the desktop stuff doesn’t seem to work with KDE4.1 (my testing) and blackbox (from that page).

The xmacro package lets you send keystrokes and mouse events to the X terminal. It can also record actions, but I rarely use that feature. If you need it though, you might need to add:

Load “Record”

In the Modules section of your xorg.conf. You can use the recorder to “start” a script by running:

xmacrorec2 >temp.macro

The program will ask you to pick a “stop” key — something you won’t use in the recording like the Escape key, for example. Then you do your actions — try not to make any mistakes — and press the “stop” key. The temp.macro file will have the actions recorded. You can edit them (cut out any mistakes, delay between them, activate windows, etc.).

The only real problem with xmacro is that the mouse positions are absolute. So you are better off if you can stick to keystroke commands. However, if your scripting skills are good enough, the wmctrl -l -G command gives you enough info to compute relative mouse coordinates for any window.

I used AutoHotKey to correct a missing feature in ThunderBird for Windows. I wanted to just print a PDF attachment in an e-mail message (something Outlook does easily). With the Linux version of ThunderBird I wrote the following quick and dirty script:


   # Simple script to print the first PDF attachment from an e-mail# in thunderbird
# assumes you are already on the message with the attachment
# and also assumes the attachment is a PDF and that the
# PDF reader is from Adobe
# but for debugging try this
#wmctrl -R thunderbird
sleep 2  # wait for user to let go of keyboard

xmacroplay -d 10 $DISPLAY << ~~~
KeyStrPress Alt_L
KeyStrPress f
KeyStrRelease f
KeyStrRelease Alt_L
KeyStrPress a
KeyStrRelease a
KeyStrPress 1
KeyStrRelease 1
KeyStrPress o
KeyStrRelease o
~~~
sleep 1
# adobe should be active but just in case
# either comment this out or change it if you want to
# use kpdf or ockular or whatever
wmctrl -R adobe
xmacroplay -d 10 $DISPLAY << ~~~
KeyStrPress Alt_L
KeyStrPress f
KeyStrRelease f
KeyStrRelease Alt_L
KeyStrPress p
KeyStrRelease p
KeyStrPress Alt_L
KeyStrPress o
KeyStrRelease o
Delay 2
KeyStrRelease Alt_L
KeyStrPress Alt_L
KeyStrPress f
KeyStrRelease f
KeyStrRelease Alt_L
KeyStrPress x
KeyStrRelease x
~~~
# change the x above to c if you don't want to quit Acrobat

I used the Window manager to bind the script to a key and its all done. If you don’t want to go that far, you can uncomment the wmctrl line that activates Thunderbird and start the program from a shell prompt or an icon. Naturally, you could use wmctrl -l to verify that the attachment opened, etc. But this will get you started.

Of course, this doesn’t approach some of the power of Autohotkey. But it is still pretty usable.

Extra note: If you do want to experiment with using the mouse, you might consider using xev to look at mouse coordinates. You can use wmctrl -l to get window IDs and then use xev’s -id option to attach it to a particular window and watch events. A grep is handy to filter out events you don’t care about, or catch it all in a file and examine it later.

Update: There is another tool I have found that seems to work well and integrates window control and keyboard control. Check out xdotool.

Jericho Morse Code

It seems like I get more hits about Morse code on Jericho than just about anything else, so…. The series finale was necessarily disappointing. But you can see they are setting up for a new “Civil War” show on SciFi, I bet. Perhaps with a mostly new cast at that. Maybe they’ll call the show “Republic” and it’d be about the Texans kicking everyone else’s… um, well.

Episode 1.01: The Pilot
Jericho Pilot

Episode 1.02: Fallout
Jericho Fallout

Episode 1.03: Four Horsemen

Jericho Three

Episode 1.04: Walls of Jericho
He knows Rob

Episode 1.05: Federal Response
There is a fire

Episode 1.06: “9.02”
The EMP hits

Episode 1.07: Long Live the Mayor
Pray for NYC

Episode 1.08: Rogue River
Rob not FBI

Episode 1.09: Crossroads
AOV Surprise

Episode 1.10: Red Flag
It begins with

Episode 1.11: Vox Populi
6 and ends with


Special Episode: Return To Jericho
back next week. 36 hours before bombs

Episode 1.12: The Day Before
Bloodshed

Episode 1.13: Black Jack
Bleeding KS

Episode 1.14: Heart of Winter
4 Down 4 to Go

Episode 1.15: Semper Fidelis
They will need it

Episode 1.16: Winter’s End
A costly deal

Episode 1.17: One Man’s Terrorist
Rob Exposed

Episode 1.18: A.K.A.


Who Ran Red Bell

Episode 1.19: Casus-Belli
ONE GOT AWAY

Episode 1.20: One If By Land
We Pledge

Episode 1.21: Coalition of the Willing
Allegiance

Episode 1.22: Why We Fight
To the Flag

Episode 2.01: Reconstruction


WE’RE BAAACK

Episode 2.02: Condor

J&R RAN BOXCAR  (man… have you ever heard an & sent using Morse code before? I hadn’t)

Episode 2.03: Jennings & Rall
CALLER KNOWS ALL

 Episode 2.04:  Oversight
A Costly Death

Episode 2.05: Termination for Cause
THO IT IS DARK

Episode 2.06: Sedition

Know our Flag

Episode 2.07: Patriots and Tyrants
Is still there

The code was sloppy at the start of the series. In addition, I always thought “AOV Surprise” was a mistake, although some say it means “Area of Vulnerability.” Right.  It got better, but also got faster and covered up more with music. The sloppy nature and the use of the & symbol makes me think that whoever was responsible for this was not a ham, but just someone who thought it was a cool idea and looked up the Morse code.

Too bad about a great show. They really dumbed it down for the 2nd season, which I guess was necessary. I wonder if they’ll release the alternate ending on the Internet?

73 de WD5GNR