iradio script and WJBQ

This post was imported from my old blog “Tux Wears Fedora” on 2010-09-28. Some stuff in this post may be broken, please leave a comment if you see any, then I will try to fix it.
I updated my iradio script for a Internet radio station, WJBQ.

iradio: WJBQ

A portion of code is copied from MPDisp, I think I am totally crazy for cli and FIGlet right now. In this modification, it retrieves current playing song and the program host's name from website, then show them using FIGlet.

The radio station, WJBQ (Portland, Maine), I have been listening to it (The Q Morning Show) every morning on weekdays for about a half year. I seemed to firstly "watch" it (the studio webcam) on ustream.tv.

The data contains start time of playing and song duration, but that will need to do time conversion between timezones, with just Bash, I have no idea how to do that. I wonder if there is a very simple and straight program to do that.

This script depends on mplayer and wget (currently, only listening to WJBQ needs). If you have your favorites, and you want have similar info in your terminal window, free feel to post a link to radio station, I will see if I can do something for you.

Gentoo Forums feed

This post was imported from my old blog “Tux Wears Fedora” on 2010-09-28. Some stuff in this post may be broken, please leave a comment if you see any, then I will try to fix it.
A quick post. I wrote a script for GAE, it generates Gentoo Forums' latest topic/post feed.
Hope this is useful for you.

Open URL or google from terminal

This post was imported from my old blog “Tux Wears Fedora” on 2010-09-28. Some stuff in this post may be broken, please leave a comment if you see any, then I will try to fix it.
I made two small Bash scripts. They are very short and simple, so I just paste them here:
chk-url-browser.sh
#!/bin/bash
# A script to check if select a url, if so, then open it in browser

# Or http://search.yahoo.com/search?p=
# Or http://search.live.com/results.aspx?q=
SEARCH_ENGINE="http://www.google.com/search?q="
# Or use firefox, opear, etc
LAUNCHER=xdg-open

url=$(xsel -o)
[[ $(egrep "(ht|f)tps?://" <<< $url) ]] || exit 1
$LAUNCHER "$url"

terminal-search.sh
#!/bin/bash
# A script to search text from X clipboard

# Or http://search.yahoo.com/search?p=
# Or http://search.live.com/results.aspx?q=
SEARCH_ENGINE="http://www.google.com/search?q="
# Or use firefox, opear, etc
LAUNCHER=xdg-open

text=$(xsel -o)
text=$(python -c """import urllib ; print urllib.quote('$text')""")
$LAUNCHER "$SEARCH_ENGINE$text"

If you are using VTE-based terminal, then you don't need the first one. If you may also not need it, check out this post.

The second one also relies on Python to do url encoding. I don't know if there is a common program for that, but Python is quite common too.

I bind Win+R to chk-url-browser.sh and Win+G to terminal-search.sh in Fluxbox, using the following in ~/.fluxbox/keys:
# Open url
Mod4 R :Exec ~/bin/chk-url-browser.sh
# Search from terminal
Mod4 G :Exec ~/bin/terminal-search.sh

MPDisp: a simple Bash MPD client

This post was imported from my old blog “Tux Wears Fedora” on 2010-09-28. Some stuff in this post may be broken, please leave a comment if you see any, then I will try to fix it.
Just finished this hours-project. I happened to read this thread and know the FIGlet and TOIlet, hours later, I am showing you MPDisp. I used FIGlet not TOIlet because TOIlet doesn't support center aligning. Here is a screenshot:

MPDisp

You can read and download the code. The only dependency should be FIGlet (do I really need to say you need MPD?). It doesn't rely on (nc)mpc(pp), it contacts MPD directly. All it does is show the song information and give you a little bit of control, see the key list:

  • p - Pause/Resume
  • Enter - Play
  • s - Stop
  • n - Next song
  • p - Previous song
  • r - Repeat mode on/off
  • S - Single mode on/off
  • R - Random mode on/off
  • q - Quit
  • Q - Quit with MPD
I was thinking to use TOIlet, it has a feature called filter, which can render with colors. But it can't align text center. I might try to see what I can do to next.

The only problem I have seen is if you have too small window, text will be messed up, and I am not intended to solve it right now.

Terminals width(columns) and Non-blocking stdin without echoing

This post was imported from my old blog “make YJL” on 2010-09-28. Some stuff in this post may be broken, please leave a comment if you see any, then I will try to fix it.
I spent few hours trying to find the solution for them, I did find one, but it's not portable and not good for me.

Photo: Anechoic chamber by lovestruck

The final code is

#!/usr/bin/env python


import os
import select
import signal
import sys
import termios
import time
import tty


def ttywidth():

#f = os.popen('stty size', 'r')
# Should return 'HHH WWW'
#width = int(f.read().split(' ')[1])
f = os.popen('tput cols', 'r')
width = int(f.read())
f.close()
return width


def getch():

return sys.stdin.read(1)


def update_width(signum, frame):

global width

width = ttywidth()
sys.stdout.write(str(width) + '\r\n')

width = ttywidth()

# Use signal to be ackknowledged of window change event
signal.signal(signal.SIGWINCH, update_width)

# Get stdin file descriptor
fd = sys.stdin.fileno()
# Backup, important!
old_settings = termios.tcgetattr(fd)
tty.setraw(sys.stdin.fileno())

p = select.poll()
# Register for data-in
p.register(sys.stdin, select.POLLIN)

while True:
# If do not need the width of terminal, then this catch might not be
# necessary.
try:
# Wait for 1ms, if still not char in, then return.
if p.poll(1):
ch = getch()
if ch == "\x03":
# Ctrl+C
break
if ch == "\x0d":
# Entry key
sys.stdout.write("\033[97;101m" + " " * width + "\r\n\033[39;49m\r\n")
break
except select.error:
# Conflict with signal
# select.error: (4, 'Interrupted system call') on p.poll(1)
pass
# Must restore the setting, or stdin still not echo after exit this program.
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)

For first part of problem, terminal's width (columns), it calls external program, which is what I don't like. There also is a way to use environment variable COLUMNS, but it's not a good way because most of people would not export COLUMNS.

The second part of problem, non-blocking stdin without echoing, it uses select.poll to do non-blocking and tty to do no echoing. In addition, it uses termios to backup and to restore terminal attributes, which is very important. If it doesn't do, then the stdin of shell will be still not echoing after program exits.

Unless you are in console, or you would change terminal's geometry sometimes, therefore signal comes to catch the event SIGWINCH. That will slightly affect select.poll, but should be no harm, you can see the try except for that.

One more thing to note, after setraw(), it needs to use "\r\n"("\x0d\x0a") not just "\n" for a newline (this I don't know the reason).

All I want from the code is when user hits enter, then it prints out a horizontal bar with same width of terminal as seperator.

This code is put in Public Domain. If you know of a portable code, and it does rely on additional library, please share with me. Please also comment on the code, explain some things that I didn't mention above, those must be the things that I didn't know. It should be able to merge the code inside main loop into getch(), make it return None when no data available, I leave you that to finish.

Updated on 5/26: If you don't want to show cursor, you can do:
# Hide cursor
sys.stdout.write('\033[?25l')
# Show cursor
sys.stdout.write('\033[?25h')
If you don't like change original code for "\r\n", you can do
class STDOUT_R:

@staticmethod
def write(s):

s = s.replace('\n', '\r\n')
sys.__stdout__.write(s.encode('utf-8'))

@staticmethod
def flush():

return sys.__stdout__.flush()


class STDERR_R:

@staticmethod
def write(s):

s = s.replace('\n', '\r\n')
sys.__stderr__.write(s.encode('utf-8'))

@staticmethod
def flush():

return sys.__stderr__.flush()

nephilim, a new Python/QT MPD client

This post was imported from my old blog “Tux Wears Fedora” on 2010-09-28. Some stuff in this post may be broken, please leave a comment if you see any, then I will try to fix it.
I knew of this new player, nephilim, few days ago via Arch's forum. So far, I can't find any official web page for it, I have no idea how to get information or to ask for help, but I got no problem at running it. You may need MPD 0.15 Beta, I have tried 0.14 and got an error. As you may know I like CLI as much as possible, but I think this is worth to introduce, make people know of it.

Nephilim, Image Hosted by ImageShack.us

The layout is very flexible, you can drag any panel and drop at any place you like. I can't edit the playlist, it doesn't seem to be implemented yet, but I can double-click on a track in the Playlist panel to play. The playlist you see in screenshot is I edited in the other client. Therefore, the Library panel and the Filebrowser panel do not have actual function at this moment. Album cover can be fetched, but error happens on saving. I haven't seen the Lyrics panel showing any lyrics. It also has the tray icon, just for showing/hiding the window.

I probably wouldn't use it anymore, not because it's not yet fully functional at all but it's a GUI program. However, I just want to spread it for whom may be interested and hope someone can support this player.

Shell.FM

This post was imported from my old blog “Tux Wears Fedora” on 2010-09-28. Some stuff in this post may be broken, please leave a comment if you see any, then I will try to fix it.
Before I subscribed to Last.fm, I thought I should find a TUI Last.fm player, I am a CLI addict. I tried LastBash first, but it didn't play and I don't know the reason. Then I found Shell.FM, and I love it. Here is a screenshot:
Image Hosted by ImageShack.us

Here is my ~/.shell-fm/shell-fm.rc:
username = [username]
password = secret
default-radio = lastfm://user/[username]/recommended
np-file = /home/[username]/.shell-fm/nowplaying
np-file-format = %t by %a
title-format = Now playing %t from %l by %a (%T)
screen-format = %t by %a
term-format = %t by %a
delay-change = true
# COLORS!!!
# Track title
t-color = 1;31
# Album name
l-color = 1;32
# Artist name
a-color = 1;34
# Track page
T-color = 0;36

I also use conky to cat nowplaying file. If you don't know what those mean, man shell-fm to find out.

I got a snazzy black icon on Last.fm!

This post was imported from my old blog “Blogarbage” on 2010-09-28. Some stuff in this post may be broken, please leave a comment if you see any, then I will try to fix it.
Today I paid first monthly subscription fee to Last.fm. You may probably be aware that Last.fm is not free for all. People who live outside of US, UK, and German would need to subscribe for listening to streams. I noticed this change two weeks ago, at the moment, I had no intention and no idea that I would subscribe. Earlier, I read a forum thread, which mentions few things:
  • Music is not all free
  • $3 is just enough buy you a cup of coffee
Because of this coffee comparison, I decided to subscribe. And I totally agreed with the first one. Some music are free like on Jamendo. I was hoping Jamendo can be the alternative. Unfortunately, it doesn't have same concept. All I want is the radio-like playing. Jamendo has radio stations, too, but the songs in list are fixed. No random or based on your taste of music. I used to like Pandora, but it doesn't provide service outside of US since two years ago, both paid or free. So Last.fm is my only choice.

And this is me on Last.fm.

looping, positioning, ontop, transparency, and mplayer

This post was imported from my old blog “Tux Wears Fedora” on 2010-09-28. Some stuff in this post may be broken, please leave a comment if you see any, then I will try to fix it.
Sometimes, when you are working, you need some background noise or music. I have been using mplayer to play music videos. I already knew -loop 0 option can loop the video. However, mplayer recreates window every restart, which is quite annoying. But that does how it works.

Luckily, mplayer is a mature software, it has lots of options to fit your needs. So, the following came out to rescue me a bit:
mplayer -vo x11 -loop 0 -geometry 360x201+1320+826 -ontop -zoom video.file

Now, it's positioned and always ontop every replay. Nonetheless, desires grow while your needs being fed. I started to want to have window with transparency. So, I firstly installed xcompmgr to my Gentoo with Fluxbox.

Here is a quick sidenote if you also use conky, conky can not work with xcompmgr nicely when settings are not right. You may need to use the following settings in your ~/.conkyrc:
own_window yes
own_window_transparent yes
own_window_type desktop

Another sidenote for video output driver of mplayer, when xcompmgr enables, the valid options seem to be xv, x11, xshm, gl, gl2. I can only get x11 to fully worked. xshm totally can't work, gl has audio sparkling, gl2 won't render image anymore after the window lost focus. xv is actually still working, but you will see scanning line (not sure if that is the term).

Now, back to transparency, this should be window manager setting. In Fluxbox, you can use ~/.fluxbox/apps to configure applications' settings.
[app] (name=x11) (class=MPlayer)
[Deco] {NONE}
[Alpha] {192}
[Layer] {2}
[Hidden] {yes}
[end]

Note that Hidden option is for not letting window show up in window list and not being selected by Alt+Tab.

I have tried to get window id and use transset-df to set the transparency by window id. However, the only way I know to get the window id is by using xlsclient, unfortunately, the mplayer's video window doesn't show up in the list (using gmplayer to play will do). Because of that, I have to use Fluxbox's apps configuration to make all mplayer windows have same setting, this is a drawback which I don't like. I have thought about setting window's name, but mplayer doesn't support that.

Things are not always be good or can be resolved, there is a major problem with mplayer, and I couldn't resolve it yet: every time the window recreates, it also gets the focus, that is default action for WM. If you know how to get rid of that, please tell me.

Some of you might wonder why not just use GUI player, such as totem or VLC, the reason is quite simple: I don't like them. I like being drowned in man pages and numerous options, sometimes. Options provide precise and fast actions after properly configuring. Pay your time once, enjoy the rest of your life.

BashPad, the best program launcher

This post was imported from my old blog “Tux Wears Fedora” on 2010-09-28. Some stuff in this post may be broken, please leave a comment if you see any, then I will try to fix it.
Cuber shares his great creation, BashPad (forum thread). It uses a terminal and a bash processes.

Image Hosted by ImageShack.us

I use it on FluxBox. So far, it works well and replaces gmrun. You can read me asking about memory usage and few things in that thread. Now, I am using daemonized urxvt, I didn't know urxvt does that. The daemonized urxvt is really memory efficient. If you are a terminal window nuts, then you definitely need to try it out. Run urxvtd -q -o -f to start the daemon, then urxvtc to start the client.

Because BashPad natively is a Bash, so you can do what you already do with Bash. Such as specify environment varibles, you can't do that with gmrun; or full Bash-completion, gmrun can only do the program name completion. Also it has own history, won't mess up original bash history, and history search (Ctrl+R) works as well.

XZ compression

This post was imported from my old blog “Tux Wears Fedora” on 2010-09-28. Some stuff in this post may be broken, please leave a comment if you see any, then I will try to fix it.
Knew this new format (LZMA-based) via Slackware, Slackware will be starting using XZ to package. I tried to emerge (install) it on Gentoo, but it's masked and blocking with lzma-utils. So, I downloaded and compiled it. The version I used is 4.999.8beta.

Here is a quick result, I used Linux kernel source 2.6.29.3:
              gzip  bzip2     xz
compression 22.1s 78.1s 322.9s
72.6M 56.5M 48.2M
decomprssion 4.0s 19.3s 7.4s

Original tar size is 336MB.

XZ compression time is about 4 times slower than bzip2 (1.0.5), 3 times faster than bzip2 in decompression, twice slower than gzip(1.3.12) in decompression. If consider as a file distributer, the numbers are great. We can ignore the compression time because compression only does once, but transmission and decompression do once per request. It save lots of bandwidth and time. Though it's almost twice slower than gzip, but not many connections can transfer 24.4MB in 3.4 seconds.

Twitter tells the day

This post was imported from my old blog “make YJL” on 2010-09-28. Some stuff in this post may be broken, please leave a comment if you see any, then I will try to fix it.
I just wrote a quick code:
#!/usr/bin/python
# Using Twitter to find out how special today is
#
# This code is in Public Domain.
#
# Author:
# 2009 Yu-Jie Lin


from sys import exit
from urllib import urlopen
import simplejson as json


TREND_API = 'http://search.twitter.com/trends/current.json'


f = urlopen(TREND_API)
if f.info()['status'] == '200 OK':
_, trends = json.loads(f.read())['trends'].popitem()
for t in trends:
if 'day' in t['name'] or 'Day' in t['name']:
print t['name'].replace('Happy', '').replace('happy', '').replace('#', '').strip()
else:
print 'Unable to retrieve, status code: %s' % f.info()['status']
exit(1)

It shouldn't be hard to guess what this script does.

If you ever read the trending topics at side of your Twitter homepage, you must have learnt some things you wouldn't have heard before. Sometimes, they bring you interesting things. Well, not always, but still fun to read them.

One thing I have noticed is everyday seems to be a very special day. You can read #fooday or Happy Bar Day, or something like that in trending topics. I guess that also prompts you or reminds us: Don't give upon this special day. (I don't know why I said that, it's just popping up out of my head)

A quick example for this moment of writing this posting, this code prints out or Twitter tells about this day is:
$ ./TwitterTellsTheDay.py 
Mothers Day
bouvierb-day

So, how are you today?

get-volume.c

This post was imported from my old blog “make YJL” on 2010-09-28. Some stuff in this post may be broken, please leave a comment if you see any, then I will try to fix it.
Photo: Volume Blue by SimonWhitaker

I just wrote a simple C program. It's been quite a long time, at least years, my skill has become very rusty. Any tips or tricks are welcome!

Here is the code, you can also get it on Google Code:
// get-volume is a small utility for ALSA mixer volume, written for being used
// in Conky.
//
// This code is in Public Domain
//
// Reference:
// http://www.alsa-project.org/alsa-doc/alsa-lib/index.html
//
// Author:
// 2009 Yu-Jie Lin
//
// Compile using:
// gcc -lasound -o get-volume get-volume.c

#include <stdio.h>
#include "alsa/asoundlib.h"

const char *ATTACH = "default";
const snd_mixer_selem_channel_id_t CHANNEL = SND_MIXER_SCHN_FRONT_LEFT;
const char *SELEM_NAME = "Master";

void error_close_exit(char *errmsg, int err, snd_mixer_t *h_mixer) {
if (err == 0)
fprintf(stderr, errmsg);
else
fprintf(stderr, errmsg, snd_strerror(err));
if (h_mixer != NULL)
snd_mixer_close(h_mixer);
exit(EXIT_FAILURE);
}

int main(int argc, char** argv) {
int err;
long vol;
long vol_min, vol_max;
int switch_value;
snd_mixer_t *h_mixer;
snd_mixer_selem_id_t *sid;
snd_mixer_elem_t *elem ;

if ((err = snd_mixer_open(&h_mixer, 1)) < 0)
error_close_exit("Mixer open error: %s\n", err, NULL);

if ((err = snd_mixer_attach(h_mixer, ATTACH)) < 0)
error_close_exit("Mixer attach error: %s\n", err, h_mixer);

if ((err = snd_mixer_selem_register(h_mixer, NULL, NULL)) < 0)
error_close_exit("Mixer simple element register error: %s\n", err, h_mixer);

if ((err = snd_mixer_load(h_mixer)) < 0)
error_close_exit("Mixer load error: %s\n", err, h_mixer);

snd_mixer_selem_id_alloca(&sid);
snd_mixer_selem_id_set_index(sid, 0);
snd_mixer_selem_id_set_name(sid, SELEM_NAME);

if ((elem = snd_mixer_find_selem(h_mixer, sid)) == NULL)
error_close_exit("Cannot find simple element\n", 0, h_mixer);

if (argc != 2)
error_close_exit("Missing (switch|volume) as argument\n", 0, NULL);

if (strcmp(argv[1], "volume") == 0) {
snd_mixer_selem_get_playback_volume(elem, CHANNEL, &vol);
snd_mixer_selem_get_playback_volume_range(elem, &vol_min, &vol_max);
printf("%3.0f%%", 100.0 * vol / vol_max);
}
else if (strcmp(argv[1], "switch") == 0) {
snd_mixer_selem_get_playback_switch(elem, CHANNEL, &switch_value);
printf("%s", (switch_value == 1) ? "ON" : "OFF");
}
else if (strcmp(argv[1], "on") == 0) {
snd_mixer_selem_get_playback_switch(elem, CHANNEL, &switch_value);
printf("%s", (switch_value == 1) ? "ON" : "");
}
else if (strcmp(argv[1], "off") == 0) {
snd_mixer_selem_get_playback_switch(elem, CHANNEL, &switch_value);
printf("%s", (switch_value == 1) ? "" : "OFF");
}
else
error_close_exit("Invalid argument. Using (switch|volume)\n", 0, NULL);

snd_mixer_close(h_mixer);
return 0;
}

This code is written for being used with Conky. Before this, I had the following in my .conkyrc:
${color lightblue}Volume:$color ${exec amixer get Master | egrep -o "[0-9]+%" | head -1 | egrep -o "[0-9]*"} % $alignr${color blue}${exec amixer get Master | grep -o "\[on\]" | head -1}$color${color red}${exec amixer get Master | grep -o "\[off\]" | head -1}$color

amixer, (e)grep, and head may not consume too much resource and I have never been aware of them running background. But, one simple C program, definitely run faster and efficient than those, because it's just written for that purpose.

I also thought of Python. I love Python, but I personally prefer compiled program if I need to make a choice. So, I decided to use C. Python is really (usually) easy to code and (almost) fun to program, but it really consumes much more memory.

With this small program, then that part become
${color lightblue}Volume:$color ${exec ~/bin/get-volume volume}$alignr${color blue}${exec ~/bin/get-volume on}$color${color red}${exec ~/bin/get-volume off}$color

PDepGraph.py Generating dependency graph on Gentoo

This post was imported from my old blog “Tux Wears Fedora” on 2010-09-28. Some stuff in this post may be broken, please leave a comment if you see any, then I will try to fix it.
(Also posted to Gentoo forum)

Photo: Branches Against the Sky by Chris Campbell

Seeing a visualized dependency graph of a package should be always interesting. I read a post on Arch Linux Forums, which generates very beautiful images of your Arch Linux. I was thinking to add a support for Gentoo, but after reading the code, I decided to write my own completely.

Actually, I only did a half of work. My code doesn't not render the image but using Graphviz to the job. It requires packages gentoolkit and graphviz. There are few usage examples written at top of the script.

Here are two quick examples: First one is the Dependency of portage
dep graph of package portage on Twitpic

Second one is big, whole world highlighting python.

You can read the code and download it.

The result should be reflecting installed packages and used USE flags on packages at the time of installing. I didn't take a look at the results very deep, so I am not sure if they are 100% correct since I don't know if I interpreted the data from gentoolkit correctly or not.

I think it's fun to see the visualized dependency data. The code needs Graphviz to render the image, and I think I didn't configure it well. So if you generate whole world, the result is hard to read.

Hope you would like it and give me some feedback.