Rockbox – audiobooks, podcasts and sorting

Since I moved to Rockbox, I’ve had two issues that have been bugging me:
1. Keeping my podcasts and audiobooks separate
2. Sorting my podcasts (reverse chronological order and separating the ones I’ve listened to already)

I finally got tired of ignoring the issue and decided to give it a serious shot today. And it goes on to prove to me that with sufficient motivation, you need not fear doing things you’re unfamiliar with. In this case it was editing some config files in Rockbox.

For those not interested in the story, but just the job, here’s the file:

#! rockbox/tagbrowser/2.0
# ^ Version header must be the first line of every file

# Tag Browser configuration file, do not edit as changes will be lost!
# Instead, you can modify “/.rockbox/tagnavi_custom.config” which will never
# get overwritten automatically.
# Basic format declarations
%format “fmt_podcast_album” “%s” album ? genre == “podcast”
%format “fmt_podcast_title” “%s %s – %02d:%02d” basename title Lm Ls %sort = “inverse” %strip = “15″ ? genre == “podcast”
%format “fmt_podcast_alphanum_title” “%s – %02d:%02d (%s)” basename Lm Ls filename ? title == “” & genre == “podcast”
%format “fmt_podcast_alphanum_title” “%s – %02d:%02d” title Lm Ls & genre == “podcast”

%menu_start “podcasts” “Podcasts”
“New podcasts” -> album ? genre == “podcast” -> title = “fmt_podcast_title” ? playcount == “0″ & genre == “podcast”
“Old podcasts” -> album ? genre == “podcast” -> title = “fmt_podcast_title” ? playcount != “0″ & genre == “podcast”

%menu_start “main2″ “Database”
“Artist” -> artist ? genre != “podcast” & genre != “audiobook” -> album -> title = “fmt_title” ? genre != “podcast”
“Album Artist” -> albumartist ? genre != “podcast” & genre != “audiobook” -> album -> title = “fmt_title” ? genre != “podcast”
“Album” -> album ? genre != “podcast” & genre != “audiobook” -> title = “fmt_title” ? genre != “podcast”
“Audiobooks” -> album ? genre == “audiobook” -> title = “fmt_title” ? genre == “audiobook”
“Podcasts” ==> “podcasts”
“Genre” -> genre -> artist -> album -> title = “fmt_title” ? genre != “podcast”
“Composer” -> composer -> album -> title = “fmt_title” ? genre != “podcast”
“Track” -> title = “fmt_alphanum_title” ? genre != “podcast”
“Year” -> year ? year > “0″ -> artist -> album -> title = “fmt_title” ? genre != “podcast”
“User Rating” -> rating -> title = “fmt_title” ? genre != “podcast”
“Recently Added” -> album ? entryage < “4″ & commitid > “0″ -> title = “fmt_title” ? genre != “podcast”
“A to Z…” ==> “a2z”
“History…” ==> “runtime”
“Same as current…” ==> “same”
“Search…” ==> “search”
“Custom view…” ==> “custom”

# And finally set main menu as our root menu
%root_menu “main2″

To solve this issue I had to approach the problem from two ends:
1. The files – correct tagging (podcast/audiobook) and in the case of podcasts, I had to ensure that the podcast filename was just the date the podcast was produced.
2. Rockbox – making the menus and the filtering

The files were relatively easy in terms of tagging. For podcasts, I use gPodder. I upgraded to the latest version on the debian repository (in Testing) and changed the config settings in gPodder to set the synchronized filename as just the “sortdate” as gPodder puts it.

In Rockbox, I had to pore over this page: http://www.rockbox.org/wiki/DataBase, and then experiment with the things listed until I finally got to the desired result. My key challenge was to understand how filters worked in the menus!

For example, initially, I had added the podcast menu as follows:
%menu_start “podcasts” “Podcasts”
“New podcasts” -> album -> title = “fmt_podcast_title” ? playcount == “0″ & genre == “podcast”

This resulted in me seeing all the albums on my player, not just the podcasts! So after poring over the Database wiki some more, I realized that I needed to add the conditional inside the menu!

“New podcasts” -> album? genre == “podcast”

Once I’d figured this out, the rest was a matter of tuning the gPodder output and figuring out what works!

Hope this helps.

Buttons and Stock Images in Python

Thanks to codecademy.com I’ve learnt the basics of Python, and now I’m trying to figure out pygtk. I looked up the tutorial on the pygtk website and even found a package python-gtk2-tutorial on the debian repository. Awesome. In Chapter 6 of the tutorial, there’s an exercise to add an image to a button. Now, the way the author does it is by using a pixmap, but gtk also has a ton of stock images, which you can use.

There is a catch – which is why this blog post’s here! In GTK, it appears that you cannot set a label and an image for a button at the same time, and have them both show by default. If you set the button as a stock.

button = gtk.Button(stock=gtk.STOCK_ADD) – for example, then you’ll see the text "Add".

To allow buttons to have both icons and labels, use the following bit of code before you type window.show()

settings = gtk.settings_get_default()
settings.props.gtk_button_images = True

However, you still can’t use a stock image with a custom label directly. So here’s the workaround:

 button = gtk.Button()
image = gtk.Image()
image.set_from_stock(gtk.STOCK_ADD,gtk.ICON_SIZE_BUTTON)
button.set_image(image)
button.set_label("button 1")
button.connect("clicked", self.callback, "button 1")
button.show()

(courtesy: https://stackoverflow.com/questions/2188659/stock-icons-not-shown-on-buttons)

Audiobooks on the iPod

Librivox is amazing. You can find some excellent books that you can listen to, when you just don’t have the energy to read. Now, like a podcast, when you’re listening to an audiobook, you may want to stop in the middle and resume your listening at a later time. If you’ve got an iPod and are ok with using iTunes, that’s pretty straightforward. You can download either the m4b or the mp3s and join them to make an audiobook. If you’re on linux you run into several issues.

First, what’s an m4b? It’s just like an m4a which has been renamed (one solution) or you can look at the wikipedia article here to find out more. The cool thing about it is that you can have chapters, just like those in your books, for audio, and all of those can be in one file. Additionally, when you listen to an audiobook on the ipod it saves your last position, so even if you ran out of juice or decided to take a break, you can always get back to where you were. So, a very useful format indeed.

Now, on linux, I know of no one who has a working version of iTunes on WINE. The only option is to install it in a virtual windows machine. Sucks. And I do want to get away from iTunes. So, the problems faced are:

  1. Convert your mp3s to a m4b audiobook
  2. Load those onto the iPod.

I researched the first for a long long while (2 weeks on and off) and then kicked myself when I stumbled across m4baker in the debian stable repository!! What could be easier? You can download it here if you’re on linux – in case it’s not in your repository. If you’re not on linux, well you can easily use iTunes, can’t you? :)

Loading it onto the iPod – I’ve got a gen5 classic (video iPod – see? All the stuff you learn when you use Linux. I wouldn’t have to think about this otherwise). Tried using Rhythmbox, and gtkpod (crashed repeatedly) to copy the file over. It copied fine. BUT – and that’s the killer – it did not have the bookmark function. At first I scratched my head and wondered if it was a format issue. That kept me busy for a few days, but then I figured I’d move it over with iTunes. I did and the file worked just fine… so after much fiddling, I figured it was Apple. They’re just messing around. I tried looking for software on linux that’d help. Nothing. So, I was stuck with two options – a) Change the genre to a podcast (which I know would work) or b) use iTunes to transfer the file over – which sucks!

I’m trying out option 3. Install Rockbox onto your iPod and get rid of Apple’s software. :) And the best part about Rockbox? Actually there are 2 good things:

  1. Installation is a breeze – I mean it. I couldn’t believe it was installed when it was!
  2. You can dualboot it. So you can have Rockbox and you can have the iOS, coexisting on your iPod. And switching betweem then couldn’t be easier.

And I realized something. The Apple iPod’s been hacked like mad and I think that works in Apple’s favor. The Zune was built way too securely, and look where it is now… anyone heard of it? Lessons to learn…

Converting numbers to text

After trying with Learn Python The Hard Way, I’m continuing with CodeAcademy. It’s fun to do some programming again. After mulling over something significantly challenging for my rusty gears, I decided to solve the problem of converting numbers to text.

The hardest bit was taking the time to think through the issue. I committed the error of coding without thinking. Perhaps the only intelligent thing I did in phase I was working out the mydict dictionary, which did not need to be changed throughout, except that I added trillion to it.

So here’s the code without much ado. When prompted to enter a number, enter just numbers.

E.g.:

Enter a number:832743242
Eight Hundred Thirty Two Million Seven Hundred Forty Three Thousand Two Hundred Forty Two

mydict = {0:"",
          1:"one", 
          2:"two", 
          3:"three",
          4:"four",
          5:"five",
          6:"six",
          7:"seven",
          8:"eight",
          9:"nine",
          10:"ten",
          11:"eleven",
          12:"twelve",
          13:"thirteen",
          14:"fourteen",
          15:"fifteen",
          16:"sixteen",
          17:"seventeen",
          18:"eighteen",
          19:"nineteen",
          20:"twenty",
          30:"thirty",
          40:"forty",
          50:"fifty",
          60:"sixty",
          70:"seventy",
          80:"eighty",
          90:"ninety",
          100:"hundred",
          1000:"thousand",
          1000000:"million",
          1000000000:"billion",
          1000000000000:"trillion"
          }

def to_text2(num,units=1):
    #have to split the number into thousands
    low = num % 1000
    high = int(num /1000)
    #evaluate the lower part
    low_str = ""
    if low!=0:
        hundred = int(low / 100)
        #print h
        if hundred!=0:
            low_str = mydict.get(hundred) +" "+ mydict.get(100) 
        tens = (low %100)
        if tens<=20:
            if tens!=0:
                low_str = low_str + " " + mydict.get(tens)
        else:
            low_str = low_str+ " " + mydict.get(int(tens/10)*10) + " " + mydict.get(tens%10)
        
        if units!=1:
            if low_str!="":
                low_str =low_str + " " + mydict.get(units)
    if high!=0:
        return to_text2(high,units*1000) + " " + low_str.strip()
    else:   
        return low_str.strip()

input_number = eval(raw_input("Enter a number:"))
print to_text2(input_number).title()

Does knowing VIM make you better at Linux?

Now that I’ve started playing with Vim (GVim to specific), I’ve discovered that lots of the GNU apps are linked up with Vim’s UI.

For example, when in Vim, you can search for text using the following command:

/mytextpattern

this takes you to the next match. Pressing ‘n’ will take you to the one after that and pressing ‘N’ will take you to the previous pattern.

The same applies when you’re using the man command, or aptitude too. Which suddenly makes using aptitude a lot easier for me. :)

I’m sure this has been documented somewhere, but it was a pleasant discovery for me.

Using Vim as an IDE

After trying out VIM, I think I may like it a bit more than EMACS already!

So, here’s something I’ve got to read soon:

https://wiki.python.org/moin/Vim
http://sontek.net/blog/detail/turning-vim-into-a-modern-python-ide

And to add to the excitement, VIM enthusiasts have published a whole lot of color-schemes online here:

http://code.google.com/p/vimcolorschemetest/

A looong read

Well, maybe it wasn’t so long, but it took me long enough to read it. That was “Sophie’s World”. And I’ve had the book for a while now. It started with a conversation in Cairo this summer while I was wading my way through Pirsig’s classic, “Zen and the Art of Motorcycle Maintenance”, rather slowly. At one point somewhere three quarters through the book, when Pirsig’s using the train analogy, I felt that my already fragile philosphic understanding was hampered by my ignorance of the history of philosophic thought.

I had two options then, Copleston’s excellent volumes on the history of philosophy or “Sophie’s World” and thanks to the intervention by a good friend, Yasser, I picked up the latter.

In Greece as I lay on the beach, I dived into the book, only to be hampered by my kindle’s breakdown when I was just about done with the Greeks. I had to wait a while for my kindle to be restored, lost again and finally be replaced by a Kobo – much satisfied with that now. And then the story resumes with me waffling about for a while longer and nibbling at the story every once in a while and backtracking a bit to recap on what I’d read and forgotten. It was a joyful journey most days, but I felt a bit bogged down in the last couple of chapters as Sophie’s World is invaded by other random thoughts. And I was happy to put it down, finally, today! Hip Horray! I can resume normal life again, secure in the knowledge that I know, or atleast I know where I can find bits and peices of what I need to resume reading Pirsig again. It can be a bit of a pain, really, the way I go about educating myself. But, atleast I can feel positive about checking off this book from my looooooooooong reading list.