Jump to content

I made a pandora program for linux.


dirty D

Recommended Posts

just copy the code into a .c text-file and compile it, change the #defines for the paths if you need to change them. You need xwininfo and xprops for it to work, they probably came with the distrobution but if not it should be easy enough to get them. if you dont know how to compile its "gcc -o programname sourcefile.c". Just open up pandora in its own window, start the program and click on the browser after the first song has been playing for a little bit to make sure its completly cached.

Edit: uploading the code somewhere it wont let me post with it in here

Edit: here, http://www.freewebs.com/jakhole/main.c

Link to comment
Share on other sites

Interesting way of doing it, though I wonder why you're not using a shell script instead. You're already doing most of the work by spawning sub-processes anyways.

*NOTE*! Completely untested script. It'll probably need a little tweaking before it'll do anything:

#!/bin/bash

# Quick script that will allow time-shifting of Pandora songs.

# Use of this script may be illegal in your country. Use at your own risk.



XWININFO_BIN=/usr/bin/X11/xwininfo

XPROP_BIN=/usr/bin/X11/xprop

PANDORA_DIR=/tmp/plugtmp-1

DEST_DIR=/home/pandora/MP3



# Make sure the settings are sane.

initialize() {

    if [ ! -x "$XWININFO_BIN ]

    then echo "Unable to execute XWININFO program ($XWININFO)"

          exit 1

    fi

    if [ ! -x "$XPROP_BIN ]

    then echo "Unable to execute XPROP program ($XPROP)"

          exit 2

    fi

    if [ ! -d "$PANDORA_DIR" ]

    then echo "Unable to find Pandora directory ($PANDORA_DIR)"

          exit 3

    fi

    if [ ! -d "$DEST_DIR" ]

    then echo "Unable to find Pandora directory ($DEST_DIR)"

          exit 4

    fi

}



# Get the window ID of the Pandora browser window

getPandoraWindowID() {

    echo "Click the Window that's running Pandora."

    echo "Note: Must be a separate window. Tabs DO NOT work with this script."

    WINDOW_ID=`XWININFO_BIN | grep "xwininfo: Window id: " | sed -e 's/ ".*//' -e 's/.* //'`

    if [ ! $? -eq 0 ]

    then echo "Error isolating WindowID. Exiting."

         exit 1;

    fi

    return $WINDOW_ID;

}



# Grab the title text of a window with a given ID.

getWindowTitleText() {

    TITLE_TEXT = `"$XPROP_BIN" -id "$1" | grep "WM_NAME(STRING)" | sed -e 's/^[^"]*"//' -e 's/"[^"]*$//'`

    if [ ! $? -eq 0 ]

    then echo "Error getting title text from window. Exiting."

         exit 1

    fi

    return $TITLE_TEXT

}



# Copy the file over from the pandora plugin dir to a specified directory

# giving it a more descriptive name in the process.

copyMP3() {

    # The title passed to us as a parameter is formatted like this:

    # "<song>  by  <artist> - Pandora - "

    SONG=`echo $1 | sed 's/  by  .*//'`

    ARTIST=`echo $1 | sed -e 's/.*  by  //` -e s/ - Pandora - .*//'`

    # wait a few seconds for the file to finish downloading.

    sleep 5

    # Copy!

    SRC_FILE=`ls -rt "$PANDORA_DIR" | tail -1`

    cp -v "$SRC_FILE" "$DEST_DIR"/"$ARTIST"-"$TITLE".mp3

}



# Main program section.

initialize

WINDOW_ID=getPandoraWindowID;

while (true)

do  sleep 5    # Check once every 5 seconds.

    WINTITLE_NEW=getWindowTitleText $WINDOW_ID

    if [ -z "`echo "$WINTITLE_NEW" | grep -i pause`" ]

    then # Not paused.

        if [ ! "$WINTITLE_NEW" = "$WINTITLE_OLD" ]

        then copyMP3 $WINTITLE_NEW

             WINTITLE_OLD = $WINTITLE_NEW

        fi

    fi

done

Link to comment
Share on other sites

As for your own code, some thoughts:

- COMMENTS! Please!

- You're checking every second to see if the title has changed, but the file might not have finished downloading by the time you start copying it.

- You're assuming copying will succeed no matter what.

- The fetching of the Window ID should be done in its own function.

- usleep should be used when you need the extra precision. Use sleep(3) instead.

- In a number of places I get the impression that you're trying to keep things too compact. Examples:

strstr(p, " ")[0] = 0; - Look for the first space in p, and end the string there.

I would consider assigning the result of strstr to a pointer and setting the value it points to to '0' cleaner.

strncpy(song, p, strstr(p, SEP) -p); - Copy the amount of bytes in the string up to SEP into song.

If you first compute the length, again using a temporary variable, readability would improve.

In both instances the compiler is smart enough to figure out you're not (re-)using that variable, and just optimize it out.

- Use access(2) instead of fopen to test for the existance of a file.

- POSIX C states that you aren't allowed to declare new variables inside the body of a function. The count variable declared at the top of the for-loop should be declared at the top of main().

- I personally prefer 'while(1)' over 'for(;; )', again for readability.

- What happens when the Pandora window is closed while the program is still running?

Other than that, pretty decent.

Link to comment
Share on other sites

The general way of doing it is:

Wait until the next song starts playing before copying the previous file. The way you know the song has changed is to keep checking the titlrbar at a regular interval and keep checking it for changes. I have my version checking for pausing, but skipping isn't something I am going to implement.

This is how I currently do it for my version and it works. I am currently in the process of rewriting mine and I am probably going to code a Linux version as well as my Windows version. I am collaberating with another person to look at Mac OS X version as well.

Link to comment
Share on other sites

Thanks for pointing all of that out, I know its messy i just slapped it together real quick and know it will crash if you close the window or some other things happen. I didnt know there was a POSIX C standard i thought the current standard was ANSI C and it says you can declare variables only at the beginning of a block so the variable in the for loop would be ok, i think it makes it a lot neater that way too and limits the scope of the variable.

Link to comment
Share on other sites

  • 1 month later...

gcc -o prip main.c

main.c: In function ‘main’:

main.c:42: warning: incompatible implicit declaration of built-in function ‘strstr’

main.c:53: warning: incompatible implicit declaration of built-in function ‘strcpy’

main.c:65: warning: incompatible implicit declaration of built-in function ‘memset’

main.c: In function ‘get_title’:

main.c:102: warning: incompatible implicit declaration of built-in function ‘memset’

main.c:106: warning: incompatible implicit declaration of built-in function ‘strlen’

main.c:107: warning: incompatible implicit declaration of built-in function ‘strstr’

main.c:108: warning: incompatible implicit declaration of built-in function ‘strcpy’

main.c: In function ‘make_mp3_name’:

main.c:120: warning: incompatible implicit declaration of built-in function ‘strcpy’

main.c:124: warning: incompatible implicit declaration of built-in function ‘strstr’

main.c:126: warning: incompatible implicit declaration of built-in function ‘strlen’

main.c:129: warning: incompatible implicit declaration of built-in function ‘strncpy’

main.c:131: warning: incompatible implicit declaration of built-in function ‘strlen’

main.c: In function ‘cur_tmp_mp3’:

main.c:176: warning: incompatible implicit declaration of built-in function ‘strcpy’

When I try to compile it.

-m13

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...