Wednesday, February 8, 2012

Scripting in Haskell and reading current playing song

If you use Xmonad as your prefered window manager you have to script some information for yourself. So I wanted to put my current playing song into the bottom bar.


On the image above you can see my bottom bar with the information of the current playing song. For this I use xmobar for putting this information into the bottom bar and mocp for getting the information which song is currently playing.

The nice thing is if you want to script with Haskell just put the following line to the first line of your script and you can run it after you give the appropriate permissions (chmod +x).
#!/usr/bin/env runhaskell
The following code will show you how to get a information from an external program and parse some important information and put it to stdout.
#!/usr/bin/env runhaskell

module Main where

import System.Process (readProcess)
import Data.List (isPrefixOf)

sizeOfString :: Int
sizeOfString = 47

split :: Eq a => a -> [a] -> [[a]]
split d = foldr f [[]]
  where f c l@(x:xs) | c == d = []:l
                     | otherwise = (c:x):xs

-- | my head function doesn't crash if there is an empty list                                                                                          
head' :: [String] -> String
head' [] = ""
head' (x:xs) = x

-- | my tail function doesn't chrash if there is an empty list                                                                                         
tail' :: [a] -> [a]
tail' [] = []
tail' (x:xs) = xs

line :: String -> IO [String]
line start = do
  s <- readProcess "mocp" ["-i"] []
  let t = split '\n' s
  let l = filter (isPrefixOf start) t
  return $ words $ head' l

reduceLine :: String -> String
reduceLine s
  | length s <= sizeOfString + 3 = s
  | otherwise = take sizeOfString s ++ "... "

main :: IO ()
main = do
  s <- line "SongTitle"
  a <- line "Artist"
  let song = foldr (++) "" $ map (++" ") $ tail' s
  let artist = foldr (++) "" $ map (++" ") $ tail' a
  if (length artist == 0)
    then if (length song == 0)
         then putStrLn $ "stop "
         else putStrLn $ reduceLine song
    else putStrLn $ reduceLine $ artist ++ ":: " ++ song
I know the code could be much shorter but its nice for learning Haskell and learn how to script with Haskell.

No comments:

Post a Comment