Topic: edit chumby parameters from chumby website in my chumby account

Hello, i am pretty new, i received my chumby yesterday.
-> beautiful device


i added my own radio to the : my streams menu and i works

but to enter it is really painful, thanks god it stores it. Is there any way to enter it in the website and then synchronizing channels will load the parameters to the chumby so i don t have to enter it manually ?

also everytime i change channel widget the synchronization is manual, can't it be automatic ? using a web site function or button ?

thanks in advance, hope i am not flooding this topic with unwanted questions.

-------------------------------------
Christian LEBAUDY  :  SW Engineer (JAVA/C/++ and more)
MSN : clebaudy AT hotmail DOT com
Agility and open source are the key to achieve SW projects in our modern world.

Re: edit chumby parameters from chumby website in my chumby account

The information for "My Streams" is stored locally on your Chumby, so anything done has to be done locally on the Chumby. However, you can SSH into your Chumby and edit the file that has the stream information manually.

If you are in Windows, you will need to use an SSH client such as PuTTY. If you are on any other operating system, you should be able to pull up a terminal and just use the SSH command. Log in as Root (no password) and enter in vi /psp/url_streams . This will open the file in VI, text editor. To enter in text, merely hit a and you will be able to edit the file. When done, hit esc to stop editing, and type ZZ to save the file and exit.

Another option is to use the Mediafly service, although I find that to be more of a pain than manually editing things on my Chumby, mainly because the Mediafly site is, IMHO, not very well organized.

The Chumby does automatically synchronize widget changes in channels, it is just not immediate. Give it a bit and whatever changes you made will appear, with no intervention on your part.

Re: edit chumby parameters from chumby website in my chumby account

Another option is to add some CGI-scripts for the Chumby itself, and you browse to your Chumby.  If I get done with my current batch of widgets (it's taking longer than I thought) I'll tackle it.

wayn3w

Re: edit chumby parameters from chumby website in my chumby account

Thanks, i am familiar with SSH no problem. and also any kind of linux system

That's fine for me but for other users what you suggest as cgi script will enable it via web interface is better for common users. As i see the integrated webserver in the chumby is pretty empty, maybe with future releases it is planned to access full control panel via a web interface.

I am a Java developer and did webapps and a lot of client/server applications. I use to program in several lenguages so i can give a try to do the cgi you talk about, i have no time yet but on sunday maybe i try something, the chumby wiki is very useful for that.

I saw yesterday in the help website that chumby synchronizes every 5 to 10 min, i had a doubt because once it did synchronized alone and then i wanted it to be immediate (thats not logic to be immediate because chumby has to poll, it's logic).

I am incredibly surprised by the device and i can only say things like :
why hell did i haven't bought it before ?
how stupid was my life without this mini television ?
thanks god that s not steeve jobs that invented it orlse device would not have been open (open source code, linux, developer community etc...) ?

I am an employee of www.hortis.ch and for us agility and open source is a religion.

THANKS THANKS THAKS !!


other questions :
where do i post product hardware suggestions ?
if i destroy the file system do i have a way to restore the chumby linux if it does not boot anymore ? i am not going to modify any critical file before i am sure to be able to restore the full system back.

-------------------------------------
Christian LEBAUDY  :  SW Engineer (JAVA/C/++ and more)
MSN : clebaudy AT hotmail DOT com
Agility and open source are the key to achieve SW projects in our modern world.

Re: edit chumby parameters from chumby website in my chumby account

now i edit the file url_streams on my computer, save it in UNIX format for Line Feeds
and transfer it using winscp
that's it very simple (SSH server must be running on cumby)

see you thanks

-------------------------------------
Christian LEBAUDY  :  SW Engineer (JAVA/C/++ and more)
MSN : clebaudy AT hotmail DOT com
Agility and open source are the key to achieve SW projects in our modern world.

6 (edited by clebaudy 2009-04-16 23:15:22)

Re: edit chumby parameters from chumby website in my chumby account

Hello,

i coded a cgi-bin sh script to remotly edit the url_streams file

you can get the script from here : http://www.lebaudy.net/streams

just put this file streams on /psp/cgi-bin on the chumb with x attributes !

then access using : http://[your chumb ip]/cgi-bin/custom/streams

I am not familiar with perl yet but i think i recode it in perl in a few days cause sh really really s...cks, it is slow on complex awk functions, if anyone could recode one of my getHTTPparameter function in order to accelerate it it will be welcome.

admins : is there a section to post such files? it will be great to have a common place where we can find other users scripts (it helps us to write our owns and we can share our work). This script was done from scratch, save is still slow but it works fine.

consider using the full package (help and scripts inside) : http://sites.google.com/site/chumbyproject/Home

-------------------------------------
Christian LEBAUDY  :  SW Engineer (JAVA/C/++ and more)
MSN : clebaudy AT hotmail DOT com
Agility and open source are the key to achieve SW projects in our modern world.

Re: edit chumby parameters from chumby website in my chumby account

This is the part where I reveal just how much of a hacker I ain't...

PREAMBLE:  I took Turbo Pascal back in 1995.  I was lucky if I got a clean compile.  Then in 1996 I had to learn a little fortran.  Then I ran merrily away from all things programming.  That said:

-I can ssh into my Chumby.

-I can cd and mkdir so convincingly you'd almost think I know what I'm doing.

-I can type vi using Terminal in OS X and discover that copy, paste, and everything else I know and love doesn't work worth a hoot.

-I CAN'T "just put this file streams on /psp/cgi-bin on the chumb with x attributes" because I have no idea what that means.  When I copy the file off clebaudy's site and paste it at the command line, all sorts of beautiful things happen in Terminal that almost convinces me I've accomplished something.  Here's the last bit:

Printing radio named : iTunes Nicecast
its url is : http://10.0.1.200:8000/listen.m3u
name found :
chumby:/psp/cgi-bin# debug "${COUNT} radios printed"
chumby:/psp/cgi-bin# generate "<TR><TD><INPUT TYPE=\"text\" NAME=\"name_${INDEX}\" SIZE=\"30\" VALUE=\"\"></TD>"
chumby:/psp/cgi-bin# generate "<TD><INPUT TYPE=\"text\" NAME=\"url_${INDEX}\" SIZE=\"80\" VALUE=\"\"></TD><TD> </TD></TR>"
chumby:/psp/cgi-bin# generate "<INPUT TYPE=\"hidden\" NAME=\"id_${INDEX}\" VALUE=\"${id}\">"
chumby:/psp/cgi-bin# generate "</TABLE>"
chumby:/psp/cgi-bin# generate "<INPUT TYPE=\"hidden\" NAME=\"stream_count\" VALUE=\"${INDEX}\">"
chumby:/psp/cgi-bin# generate "<INPUT TYPE=\"BUTTON\" NAME=\"save_button\" VALUE=\"Save\" onclick=\"javascript:submitForm()\"></INPUT>"
chumby:/psp/cgi-bin# generate "</FORM>"
chumby:/psp/cgi-bin# generate "<HR>"
chumby:/psp/cgi-bin# generate "<BR>"
chumby:/psp/cgi-bin# generate "</BODY>"
chumby:/psp/cgi-bin# generate "</HTML>"

- I CAN'T "then access using: http://10.0.1.199/cgi-bin/custom/streams" because I get a 404.

I am sincerely eager to edit my streams in some way that doesn't involve removing them by hand and re-entering them by hand.  I promise that if I can accomplish this simple task I won't pretend to be a hacker or a programmer or anyone even vaguely computer literate.  But if someone wanted to fill in the obvious steps that I, Mr. Illiterate, am clearly missing, I would sincerely appreciate it.  The Wiki is clearly written FOR people who understand linux BY people who understand linux... and I have no bones with that.  Keeps the rest of us out of trouble.  But if someone could give me just a couple hints I promise I'll be good...

Slave to the Light, Inc.
Los Angeles & Seattle USA
www.slavetothelight.com

Re: edit chumby parameters from chumby website in my chumby account

very cool, clebaudy.  I hadn't considered doing something like this.  I wonder how much can be done via the browser interface.  For instance, could I force a swf file to run on the chumby (would make testing slightly easier).

slave2thelight - I recommend downloading a copy of WinSCP.  Then it is an easy drag and drop to put the streams file into /psp/cgi-bin.  Note that the filename is streams and it has no extension.  To set the X (execute permission), you can do a right click - properties in WinSCP.  You only need the first X (the owner one).  Oh - and don't click clebaudy's link, do a right click - save as.

Re: edit chumby parameters from chumby website in my chumby account

slave2thelight wrote:

-I CAN'T "just put this file streams on /psp/cgi-bin on the chumb with x attributes" because I have no idea what that means.  When I copy the file off clebaudy's site and paste it at the command line, all sorts of beautiful things happen in Terminal that almost convinces me I've accomplished something.  Here's the last bit:

If you're on Linux or Mac, try using 'scp' on the command line to copy clebaudy's file to /psp/cgi-bin.  If your on Windows, download and use WinSCP

Once you'bve copied it into that directory, you need to make it executable (this is what clebaudy meant by x attributes).  This is done by running the following command on the Chumby:
        chmod +x /psp/cgi-bin/streams

I hope this helps,

wayn3w

Re: edit chumby parameters from chumby website in my chumby account

Nice addon for the Chumby - perhaps there is space for a remote admin website (like a mini Webmin) to do tasks like this as well as offer a simple backup for alarms/My streams etc.

One minor comment - I had to make sure that there was a blank line on the end of the script before it worked - my knowlwedge of these scripts isn't good enough to know why sad

Re: edit chumby parameters from chumby website in my chumby account

clebaudy wrote:

What about a widget to read forum posts from the chumby ????

I have written one for the chumby forums but it is not very nice to look at.
The latest posts can be seen at : http://forum.chumby.com/extern.php?acti … p;type=rss
Or you can put a forum id on the string, like http://forum.chumby.com/extern.php?acti … amp;fid=13
The main problem is viewing the full post text, as I can only get it in html format.
Currently I am taking a creative guess to extract the last post, and then stripping out all of the <tags>

I posted it as a private widget and it didnt work.  I'm guessing that forum.chumby.com doesnt have the crossdomain.xml file set up, which does seem strange.

Still, the Google Blog widget is pretty good for keeping a rough eye on the forums.

12 (edited by clebaudy 2009-04-16 23:17:11)

Re: edit chumby parameters from chumby website in my chumby account

Hello,

i am proud to present the same script written in perl now.
It is much faster now.

Get it at from here : http://sites.google.com/site/chumbyproject/Home

instructions are the same than for the other script to install it (check previous post in this thread).

hope it will be useful for some one.

I am pretty familiar with perl now and ready to write some other scripts, just give me ideas and tell me where to post.
I was sprised how easy perl is to get in when you already know other lenguages. The interpreter is very tolerant when variables are not known and i had few syntax errors before having this script dunctional.

-------------------------------------
Christian LEBAUDY  :  SW Engineer (JAVA/C/++ and more)
MSN : clebaudy AT hotmail DOT com
Agility and open source are the key to achieve SW projects in our modern world.

Re: edit chumby parameters from chumby website in my chumby account

Right on.  I've been busy but I hope to try this out tonight.

Once again, I bow before the awesomeness that is the Chumby community!

Slave to the Light, Inc.
Los Angeles & Seattle USA
www.slavetothelight.com

14 (edited by clebaudy 2009-04-15 09:14:50)

Re: edit chumby parameters from chumby website in my chumby account

Hello,

it' me again but i have some good news. I added mime type support (needed to parameter chumby streams correctly.
And also the ability to choose ANY mp3 local file to the chumby /mnt filesystem and its subdirs.

get the full package that changes default welcome page adding elements to the menu of the chumby to access my script :
get full package here : http://sites.google.com/site/chumbyproject/Home/www.zip (right click and save as zip file)

to install just unzip the content of the www zip file to the root of your usb drive and plug it to the chumby, reboot chumby and that's it your chumby http default welcome page will be quite te same but with new elements (on your usb drive you should have the debugchumby and www directory, no need to set any special attributes to files, the guys at chumby did it well with the debugchumby, i set the attributes in the script for cgi elements)

For those wanted to wake up with a specific mp3 just put your mp3 on the usb drive, define a stream using the "choose mp3" button on My Streams configuration page and then set the clock to use the stream.

PLEASE admins, can you redirect me to chumby software developer ? they should consider integrating this package in the next firmware release (only a few bytes, there is only a perl script and few modifications on chumby index.html file)

Your feedback will be welcomed. Hope you enjoy.

-------------------------------------
Christian LEBAUDY  :  SW Engineer (JAVA/C/++ and more)
MSN : clebaudy AT hotmail DOT com
Agility and open source are the key to achieve SW projects in our modern world.

Re: edit chumby parameters from chumby website in my chumby account

clebaudy,

I am going to have to check this out. I have an idea that would make this even better. You may have already incorporated this, but I am away from my Chumby right now to see. If you could allow us to create a playlist off of multiple mp3 files we choose off of your interface that would be very cool. I currently create the playlist off of some other scripts that have been posted though ssh. Being able to do this through a web interface would be so much better. I have a couple playlists that I use to fall asleep to, but I always hear the same songs each night. It is too much of a pain to be shuffling the songs manually.

Thanks for all the work. I really enjoy all of the individual efforts that have gone into making Chumby great.

-HuckFinn

Re: edit chumby parameters from chumby website in my chumby account

no problem, now all this can be done easily so count on me for that.

Juste tell me how you manage a playlist and i offer you the ability to define it via the interface. Even a shuffle function can be added in perl to rearrange the playlist elements by a random order.
i put my MSN on my end signature.

-------------------------------------
Christian LEBAUDY  :  SW Engineer (JAVA/C/++ and more)
MSN : clebaudy AT hotmail DOT com
Agility and open source are the key to achieve SW projects in our modern world.

Re: edit chumby parameters from chumby website in my chumby account

Christian,

If you want to try something interesting, there is an executable on the chumbyh called 'mp3.x' which prints out in XML all the ID3 tag information on MP3 files.  You may want to get and display information based on its results...
... or not.  at least it's something to consider.

wayn3w

Re: edit chumby parameters from chumby website in my chumby account

I noticed this post : http://forum.chumby.com/viewtopic.php?id=249
The chap there added functionality to run local swf files.
It seems there are all sorts of things that are possible with the Chumby web server.

19 (edited by huckfinn 2008-04-29 16:54:18)

Re: edit chumby parameters from chumby website in my chumby account

Christian,

I tried this out with no luck. I have the modified Chumby screen, but when I click on "My Streams" I get an "Internet Explorer cannot display the webpage" message.  Please forgive my ignorance, but I then tried to download the streams.pl file from your link above separately and IE only wanted to save it as an htm file. So I then tried to load this in Firefox with similiar result, except when I go to "My Streams" i just get a blank page.

Please if you can offer some advice I would appreciate it.

UPDATE:

So I went home and tried this at on my Chumby at home. This time I moved all of the files over using WinSCP instead of copying the files directly on the USB drive from the PC - and it worked perfectly. I then rebooted the Chumby via PuTTY and got this working without even touching the Chumby - pretty cool. I have a question and then a request.

Question: Why can I remotely start MP3 streams but not M3U? I have created  a few M3U playlists and it would be nice to remotely start these as well. Not a huge deal, more curious than anything.

Request: In a previous post you mentioned being able to create a playlist by this method. What I would like to be able to do is select a folder of mp3's or even individual files to create a playlist/stream. It would be even better if once I select these files/folders I could then shuffle the files or even manually reorder the list.

Hopefully this is not asking too much.

Thanks for this!!!

-HuckFinn

Re: edit chumby parameters from chumby website in my chumby account

Ugh.  I'm *so* not a hacker.

Perhaps this would be easier if Chumby.com and the Chumby Wiki weren't down... perhaps not.  Christian - I have a jump drive.  It has debugchumby and the directory www on it, that's it.  And I plugged the jump drive into the back.  And I rebooted the Chumby.  And I got nothing on http://192.168.1.106/cgi-bin/custom/streams.  So I started SSHD and got nothing again.

I'm on a mac.  So using Putty and WinSCP and the like isn't happening.  Likewise, "using SCP on the Command line" assumes that I innately understand the following: 

scp [-pqrvBC46] [-F ssh_config] [-S program] [-P port] [-c cipher]
[-i identity_file] [-o ssh_option] [[user@]host1:]file1 [...]
[[user@]host2:]file2

...and I don't.  I can read it.  but that's about it.  I can tell I oughtta type scp (streams complete with the full path to get to it) (something on the chumby that tells it where to put streams) but beyond that it's greek.

I had not noticed that the secret page says "Do you believe in the users?" before.  That's *awesome.*

Slave to the Light, Inc.
Los Angeles & Seattle USA
www.slavetothelight.com

21 (edited by schmegs 2008-05-03 13:35:31)

Re: edit chumby parameters from chumby website in my chumby account

slave2thelight,

I haven't tried this yet (since my Chumby is still on its way to me...), but you could try these programs for the Mac:


Freeware (or donationware)

Fugu (although it hasn't been updated in years, and may not work anymore on 10.5)
CyberDuck

or

Shareware

Transmit
ForkLift
RBrowser

and probably others...

Re: edit chumby parameters from chumby website in my chumby account

can anyone post the script? It doesn't seem to be up anymore...

23

Re: edit chumby parameters from chumby website in my chumby account

@slave2thelight -

If you're on a Mac, the program you want for SCP is Interarchy. You can read about my experience with it on this thread:

http://forum.chumby.com/viewtopic.php?id=1859

Matt Drayton, the program's developer, fixed the current version to work with the Chumby so a patch is no longer needed. AFAIK, this is the only SSH program for Mac OS that works with Chumby. I'm very happy with it and think you'll find it useful.

Re: edit chumby parameters from chumby website in my chumby account

darundal wrote:

can anyone post the script? It doesn't seem to be up anymore...

Yep, lebaudy.net seems to be alive no more. I dig up the script in the google's cache, and you can find it here (hopefully the author will not protest):

#!/usr/bin/perl
package main;
#
# Hello, this is my first perl cgi script for chumby
# As you reading this code, i am new in perl lenguage.
# I hat magic things nobody understands so i try to write useful information as i write code.
# Feel free to use this file and modify it. I hope everybody will start writing cgi perl scripts easyly.
#
#
#       Author : Christian LEBAUDY
#       MSN    : clebaudy@hotmail.com
#
#
#
#
# You can find a lot of perl tutorials to learn the lenguage just use google : perl tutorial
#    for example : http://www.cs.cmu.edu/cgi-bin/perl-man
# I provide complementary information i needed to write cgi without the CGI.pm library (chumby does not come with it)
#
# CGI perl environment variable accessible via $ENV{'variable name'} when running from the webserver
#   GATEWAY_INTERFACE       The revision of the Common Gateway Interface that the server uses.
#   SERVER_NAME             The server's hostname or IP address.
#   SERVER_SOFTWARE         The name and version of the server software that is answering the client request.
#   SERVER_PROTOCOL         The name and revision of the information protocol the request came in with.
#   SERVER_PORT             The port number of the host on which the server is running.
#   REQUEST_METHOD          The method with which the information request was issued.
#   PATH_INFO               Extra path information passed to a CGI program.
#   PATH_TRANSLATED         The translated version of the path given by the variable PATH_INFO.
#   SCRIPT_NAME             The virtual path (e.g., /cgi-bin/program.pl) of the script being executed.
#   DOCUMENT_ROOT           The directory from which Web documents are served.
#   QUERY_STRING            The query information passed to the program. It is appended to the URL with a "?".
#   REMOTE_HOST             The remote hostname of the user making the request.
#   REMOTE_ADDR             The remote IP address of the user making the request.
#   AUTH_TYPE               The authentication method used to validate a user.
#   REMOTE_USER             The authenticated name of the user.
#   REMOTE_IDENT            The user making the request. This variable will only be set if NCSA IdentityCheck flag is enabled, and the client machine supports the RFC 931 identification scheme (ident daemon).
#   CONTENT_TYPE            The MIME type of the query data, such as "text/html".
#   CONTENT_LENGTH          The length of the data (in bytes or the number of characters) passed to the CGI program through standard input.
#   HTTP_FROM               The email address of the user making the request. Most browsers do not support this variable.
#   HTTP_ACCEPT             A list of the MIME types that the client can accept.
#   HTTP_USER_AGENT         The browser the client is using to issue the request.
#   HTTP_REFERER            The URL of the document that the client points to before accessing the CGI program.
#
#
# My script constants (it is better to use constants when naming HTTP parameters or other internal stuff, this avoids errors
# when accessing parameters.
#
$HTTP_PARAMETER_ACTION="action";
$HTTP_PARAMETER_STREAM_COUNT="stream_count";
$HTTP_PARAMETER_URL="url";
$HTTP_PARAMETER_NAME="name";
$HTTP_PARAMETER_MIME_TYPE="mime_type";
$HTTP_PARAMETER_ID="id";
$HTTP_PARAMETER_MP3_ID="mp3_id";
$HTTP_PARAMETER_MP3_PATH="mp3_path";
$HTTP_PARAMETER_MP3_NAME="mp3_name";
$ACTION_SAVE="save";
$ACTION_STOP_PLAYBACK="stop_playback";
$ACTION_START_PLAYBACK="start_playback";
$HTTP_STREAM_PLAYBACK="play_stream";
$ACTION_SET_MP3="setMp3Path";
$ACTION_CHOOSE_MP3="chooseMP3";
%MIME_TYPES=("MP3", "audio/mpeg", "PLS", "audio/x-scpls", "M3U", "audio/x-mpegurl", "OGG", "application/ogg");
#
#
# useful functions
package Stream;
sub new{
    my $class = shift;
    my $self = {
        name => shift,
        url  => shift,
        id   => shift,
        mime => shift,
    };
    bless $self, $class;
    return $self;
}
1;

package main;
sub urlDecode {
    my $theURL = $_[0];
    $theURL =~ tr/+/ /;
    $theURL =~ s/%([a-fA-F0-9]{2,2})/chr(hex($1))/eg;
    $theURL =~ s/<!--(.|\n)*-->//g;
    return $theURL;
}
sub urlEncode {
    my $theURL = $_[0];
    $theURL =~ s/([\W])/"%" . uc(sprintf("%2.2x",ord($1)))/eg;
    return $theURL;
}
sub readFile {
    my $file = $_[0];
    open(FILE, $file) || die("Could not open file ".$file);
    @streams_file=<FILE>;
    close(FILE);
    return "@streams_file";
}
sub writeFile {
    my $file = $_[0];
    my $text = $_[1];
    open(FILE, ">".$file) || die("Could not open file ".$file);
    print FILE $text;
    close(FILE);
}
sub getHTTPparameters {
    my $request = $_[0];
    %http_parameters;
    foreach $param (split(/&/, $request)){
        # reading each request parameter
        @parameter=split(/=/, $param);
        $name=$parameter[0];
        $value=$parameter[1];
        if( $value ){
            # adding parameter name/value pair to the associative array only if value is not null
            $http_parameters{urlDecode($name)} = urlDecode($value);
        }
    }
    return %http_parameters;
}
sub getXMLValue {
    my $xmlstring = $_[0];
    my $name = $_[1];
    $stringToFind=$name."=\"";
    $value=substr($xmlstring, index($xmlstring, $stringToFind)+length($stringToFind));
    $value=substr($value, 0, index($value, "\""));
    return $value;
}
sub parseStreams {
    my $xml = $_[0];
    @streams;
    foreach $stream (split(/<stream /, $xml)){
        if ( $stream =~ /url=/ && $stream =~ /id=/ && $stream =~ /name=/ ){
            $stream=~s/\n/ /g;
            $url=getXMLValue($stream, "url");
            $name=getXMLValue($stream, "name");
            $id=getXMLValue($stream, "id");
            $mime=getXMLValue($stream, "mimetype");
            $stream=new Stream($name, $url, $id, $mime);
            push(@streams, $stream);
        }
    }
    return @streams;
}
sub generateId {
    my $nb = $_[0];
    $id_prefix="xxxxxxxx-yyyy-zzzz-wwww-";
    $suffix=$nb."";
    while( length($suffix)<12 ){
        $suffix="0".$suffix;
    }
    return $id_prefix.$suffix;
}
sub listFiles {
    my $dir = $_[0];
    my $recurse = $_[1];
    if( !$recurse ){
        $recurse=false;
    }
    opendir(DIR, $dir);
    my @files = readdir(DIR);
    closedir(DIR);
    my @list;
    foreach $file (@files) {
        if( !($file eq "." || $file eq "..") ){
            if( recurse ){
                # listing sub dir, as if( -d $file ) test does not work i don t know if it is a directory, i try with all files
                my @sublist=listFiles($dir."/".$file, true);
                push(@list, @sublist);
            }
            push(@list, "$dir/".$file);
        }
    }
    return @list;
}
sub ascii_to_hex ($){
    ## Convert each ASCII character to a two-digit hex number.
    (my $str = shift) =~ s/(.|\n)/sprintf("%02lx", ord $1)/eg;
    return $str;
}
sub hex_to_ascii ($){
    ## Convert each two-digit hex number back to an ASCII character.
    (my $str = shift) =~ s/([a-fA-F0-9]{2})/chr(hex $1)/eg;
    return $str;
}
sub hashCode {
    my $string = $_[0];
    my $hash=0;
    foreach $char (split(//,$string)) {
        $hash = 31*$hash+ord($char);
    }
    return $hash."";
}
sub stopPlayback {
    system "/usr/bin/killall -9 btplayd>/dev/null 2>&1";
}
sub startPlayback {
    my $url = $_[0];
    # before playback testing in /tmp/stream_playback file it is not started to play with another thread
    # for stupid reasons web browser sometimes sends 2 HTTP requests simultaneously and thi smakes problems
    # playback starts and then stops, timestamp testing avoids that
    my $tempFile="/tmp/stream_playback";
    my $lastTimestamp=0;
    if( -e $tempFile && -R $tempFile ){
        $lastTimestamp=readFile($tempFile);
    }
    my $timestamp=time; # it is only one second resolution;
    if( $timestamp > ($lastTimestamp+10) ){
        # we do not allow multiple http requests between 10 s
        writeFile($tempFile, $timestamp);
        sleep(1);
        if( -e $tempFile && -R $tempFile ){
            $fileTimestamp=readFile($tempFile);
        }
        if( $fileTimestamp eq $timestamp || $timestamp > ($lastTimestamp+10) ){
            stopPlayback();
            system "/usr/bin/chumby_set_volume 75>/dev/null 2>&1";
            system "/usr/bin/btplay --start-daemon --output=alsa:plug:dmixer \"".$url."\" 1 >/dev/null 2>&1 ;";
        }
    }
}
#
# variable web will be tested to know wether we are running in the webserver or not
$web=$ENV{'REQUEST_METHOD'};
$request=$ENV{'QUERY_STRING'};
$uri=$ENV{'SCRIPT_NAME'};
# url_streams file
$url_streams_file="/psp/url_streams";

# getting HTTP POST data
if( $web eq "POST" ){
    # POST data is given as the standard input of the process
    @input=<STDIN>;
    $request="@input";
}

# only for tests purposes
if( !$web ){
    $request="name_1=Ibiza+Global+Radio&url_1=http%3A%2F%2Fs6.viastreaming.net%3A7010%2Flisten.pls&id_1=xxxxxxxx-yyyy-zzzz-wwww-1&name_2=ODS+Radio&url_2=http%3A%2F%2Fstatslive.infomaniak.ch%2F%7Eradios%2Fradios%2Ffiles%2Fods%2Fods-high.pls&id_2=xxxxxxxx-yyyy-zzzz-wwww-2&name_3=minichalet+radio&url_3=http%3A%2F%2F192.168.0.5%3A8000%2Flisten.pls&id_3=xxxxxxxx-yyyy-zzzz-wwww-3&name_4=&url_4=&id_4=xxxxxxxx-yyyy-zzzz-wwww-4";
    $url_streams_file="/psp/url_streams";
}

# associative array that will contain the HTTP request parameters name/value pairs
%http_parameters=getHTTPparameters($request);
$action=$http_parameters{$HTTP_PARAMETER_ACTION};

if( $action eq $ACTION_SAVE ){
    $nb=$http_parameters{$HTTP_PARAMETER_STREAM_COUNT};
    # generating new url_streams file xml content
    $xml_url_streams =  "<streams>\n";
    for ($i=1; $i<=$nb; ++$i){
        $name=$http_parameters{$HTTP_PARAMETER_NAME."_".$i};
        $url=$http_parameters{$HTTP_PARAMETER_URL."_".$i};
        $id=$http_parameters{$HTTP_PARAMETER_ID."_".$i};
        $mime=$http_parameters{$HTTP_PARAMETER_MIME_TYPE."_".$i};
        if( $url && $name ){
            $xml_url_streams.="     <stream url=\"".$url."\"\n";
            $xml_url_streams.="             id=\"".$id."\"\n";
            $xml_url_streams.="             mimetype=\"".$mime."\"\n";
            $xml_url_streams.="             name=\"".$name."\" />\n";
        }
    }
    $xml_url_streams.="</streams>\n";
    writeFile($url_streams_file, $xml_url_streams);
}

# reading url_streams file
$xml_content=readFile($url_streams_file);
# parsing streams XML
@streams=parseStreams($xml_content);

if( $web ){
    # Code running inside web server when script is invoked by cgi framework
    if( $action eq $ACTION_STOP_PLAYBACK ){
        stopPlayback();
    }
    if( $action eq $ACTION_START_PLAYBACK ){
        stopPlayback();
        $streamToPlay=$http_parameters{$HTTP_STREAM_PLAYBACK};
        startPlayback($streamToPlay);
    }
    if( $action eq $ACTION_CHOOSE_MP3 ){
        $mp3id=$http_parameters{$HTTP_PARAMETER_MP3_ID};
        @listing=listFiles("/mnt", true);
        @mp3s;
        foreach $file (@listing) {
            if( $file =~ /\.mp3$/ ){
                push(@mp3s, $file);
            }
        }
        @mp3s=sort(@mp3s);
        $mp3count=scalar(@mp3s);
        print   "HTTP/1.1 200 ok\n",
                "Content-type: text/html\n",
                "#\n",
                "\n",
                "<HTML>\n",
                "<HEAD><TITLE>My streams</TITLE>\n",
                "<script type=\"text/javascript\">\n",
                "function selectFile(file, name){\n",
                "    document.inputForm.", $HTTP_PARAMETER_MP3_PATH, ".value=file;\n",
                "    document.inputForm.", $HTTP_PARAMETER_MP3_NAME, ".value=name;\n",
                "    document.inputForm.submit();\n",
                "}\n",
                "</script>\n",
                "</HEAD>\n",
                "<BODY bgcolor=\"#cccccc\" text=\"#000000\">\n",
                "<CENTER><img src=\"/images/chumby_logo.png\"></CENTER><BR>",
                "<CENTER><H1>Choose an MP3 on the chumby filesystem to use as stream.</H1></CENTER>\n",
                "<BR><P>Back to <a href=\"", $uri, "\">My streams configuration page</a></P>\n",
                "<HR>\n";
        if( $mp3count > 0 ){
            print   "<TABLE BORDER=\"0\">\n";
            foreach $mp3 (@mp3s) {
                # computing file name alone without .mp3 extension and full path
                $name=substr($mp3, 0, length($mp3)-4);
                while( ($ix=index($name, "/"))>=0 ){
                    $name=substr($name, $ix+1);
                }
                print   "<TR>",
                        "<TD>  <INPUT TYPE=\"BUTTON\" NAME=\"select\" VALUE=\"", $mp3, "\"",
                        " onclick=\"javascript:selectFile('", $mp3, "', '", $name, "')\"></INPUT>\n</TD></TR>\n";
            }
            print   "</TABLE>";
        }else{
            print   "<H2>Sorry no mp3 found in all /mnt mount drives.</H2>\n",
                    "<BR>\n";
        }
        print   "<BR>\n",
                "<FORM NAME=\"inputForm\" METHOD=\"post\" ACTION=\"", $uri, "\">\n",
                "<INPUT TYPE=\"hidden\" NAME=\"", $HTTP_PARAMETER_ACTION, "\" VALUE=\"", $ACTION_SET_MP3, "\">\n",
                "<INPUT TYPE=\"hidden\" NAME=\"", $HTTP_PARAMETER_MP3_PATH, "\" VALUE=\"\">\n",
                "<INPUT TYPE=\"hidden\" NAME=\"", $HTTP_PARAMETER_MP3_NAME, "\" VALUE=\"\">\n",
                "<INPUT TYPE=\"hidden\" NAME=\"", $HTTP_PARAMETER_MP3_ID, "\" VALUE=\"", $mp3id, "\">\n",
                "</FORM>\n",
                "</BODY>\n",
                "</HTML>\n";
    }else{
        if( $action eq $ACTION_SET_MP3 ){
            $mp3Path=$http_parameters{$HTTP_PARAMETER_MP3_PATH};
            $mp3Name=$http_parameters{$HTTP_PARAMETER_MP3_NAME};
            $urlId=$http_parameters{$HTTP_PARAMETER_MP3_ID};
        }
        print   "HTTP/1.1 200 ok\n",
                "Content-type: text/html\n",
                "#\n",
                "\n",
                "<HTML>\n",
                "<HEAD><TITLE>My streams</TITLE>\n",
                "<script type=\"text/javascript\">\n",
                "function clearField(f_name,f_url){\n",
                "    f_name.value = '';\n",
                "    f_url.value = '';\n",
                "    submitForm();\n",
                "}\n",
                "function submitForm(){\n",
                "    document.inputForm.save_button.disabled = true;\n",
                "    i = 0;\n",
                "    for(i=0;i<document.inputForm.elements.length;i++){\n",
                "      if( document.inputForm.elements[i].type == 'button' ){\n",
                "          document.inputForm.elements[i].disabled = true;\n",
                "      }\n",
                "    }\n",
                "    document.inputForm.submit();\n",
                "}\n",
                "function stopPlay(){\n",
                "    document.inputForm.", $HTTP_PARAMETER_ACTION, ".value='", $ACTION_STOP_PLAYBACK, "';\n",
                "    document.inputForm.submit();\n",
                "}\n",
                "function startPlay(stream){\n",
                "    document.inputForm.", $HTTP_PARAMETER_ACTION, ".value='", $ACTION_START_PLAYBACK, "';\n",
                "    document.inputForm.", $HTTP_STREAM_PLAYBACK, ".value=stream;\n",
                "    document.inputForm.submit();\n",
                "}\n",
                "function selectMp3(id){\n",
                "    document.inputForm.", $HTTP_PARAMETER_ACTION, ".value='", $ACTION_CHOOSE_MP3, "';\n",
                "    document.inputForm.", $HTTP_PARAMETER_MP3_ID, ".value=id;\n",
                "    document.inputForm.submit();\n",
                "}\n",
                "</script>\n",
                "</HEAD>\n",
                "<BODY bgcolor=\"#cccccc\" text=\"#000000\">\n",
                "<CENTER><img src=\"/images/chumby_logo.png\"></CENTER>",
                "<CENTER><H1>My streams configuration page</H1></CENTER>\n",
                "<center><a href=\"/\">back</a></center><br>",
                "<BR>\n",
                "<FORM NAME=\"inputForm\" METHOD=\"post\" ACTION=\"", $uri, "\">\n",
                "<TABLE BORDER=\"0\">\n",
                "<TR><TD>Radio Name :</TD><TD>URL ( supports PLS, M3U, MP3, Ogg) :</TD><TD> </TD><TD> </TD><TD> </TD>",
                "<TD><INPUT TYPE=\"BUTTON\" VALUE=\"Stop playback\" onclick=\"javascript:stopPlay()\"></INPUT></TD>\n";
        $i=1;
        foreach $stream (@streams){
            $url=$stream->{url};
            $name=$stream->{name};
            $mime=$stream->{mime};
            if( $mp3Path && $i==$urlId ){
                $url=$mp3Path;
                $name=$mp3Name;
                $mime=$MIME_TYPES{"MP3"};
            }
            print   "<TR><TD><INPUT TYPE=\"text\" NAME=\"", $HTTP_PARAMETER_NAME."_".$i,"\" SIZE=\"30\" VALUE=\"", $name, "\"></TD>\n",
                    "<TD><INPUT TYPE=\"text\" NAME=\"", $HTTP_PARAMETER_URL."_".$i, "\" SIZE=\"80\" VALUE=\"", $url, "\"></TD>\n",
                    "<TD><select name=\"", $HTTP_PARAMETER_MIME_TYPE."_".$i, "\">\n";
            foreach $mimeName (keys(%MIME_TYPES)) {
                $selected="";
                if( $MIME_TYPES{$mimeName} eq $mime ){
                    $selected="selected";
                }
                print   "<option value=\"", $MIME_TYPES{$mimeName}, "\" ", $selected, ">", $mimeName, "</option>";
            }
            print   "</select></TD>\n",
                    "<TD><INPUT TYPE=\"BUTTON\" VALUE=\"choose mp3\" onclick=\"javascript:selectMp3(", $i, ")\"></INPUT></TD>\n",
                    "<TD><INPUT TYPE=\"BUTTON\" VALUE=\"remove\" onclick=\"javascript:clearField(this.form.name_", $i, ",this.form.url_", $i, ")\"></INPUT></TD>\n";
            if( $mime eq $MIME_TYPES{"MP3"} ){
                print   "<TD><INPUT TYPE=\"BUTTON\" VALUE=\"Start playback\" onclick=\"javascript:startPlay('", $url, "')\"></INPUT></TD>\n";
            }else{
                print   "<TD> </TD>\n";
            }
                    "</TR>\n",
                    "<INPUT TYPE=\"hidden\" NAME=\"", $HTTP_PARAMETER_ID."_".$i, "\" VALUE=\"", generateId($i), "\">\n";
            ++$i;
        }
        $url="";
        $name="";
        if( $mp3Path && $i==$urlId ){
            $url=$mp3Path;
            $name=$mp3Name;
        }
        print   "<TR><TD><INPUT TYPE=\"text\" NAME=\"", $HTTP_PARAMETER_NAME."_".$i,"\" SIZE=\"30\" VALUE=\"", $name, "\"></TD>\n",
                "<TD><INPUT TYPE=\"text\" NAME=\"", $HTTP_PARAMETER_URL."_".$i, "\" SIZE=\"80\" VALUE=\"", $url, "\"></TD>\n",
                "<TD><select name=\"", $HTTP_PARAMETER_MIME_TYPE."_".$i, "\">\n";
        foreach $mime (keys(%MIME_TYPES)) {
            print   "<option value=\"", $MIME_TYPES{$mime}, "\">", $mime, "</option>";
        }
        print   "</select></TD>\n",
                "<TD><INPUT TYPE=\"BUTTON\" VALUE=\"choose mp3\" onclick=\"javascript:selectMp3(", $i, ")\"></INPUT></TD>\n",
                "<TD> </TD></TR>\n",
                "<INPUT TYPE=\"hidden\" NAME=\"", $HTTP_PARAMETER_ID."_".$i, "\" VALUE=\"", generateId($i), "\">\n",
                "</TABLE>\n";
        if( $mp3Path ){
            print "<font color=\"red\"><p>Careful, this hasn't been saved yet. Please click on the button below to accept changes:<p></font>\n";
        }
        print   "<INPUT TYPE=\"BUTTON\" NAME=\"save_button\" VALUE=\"Save\" onclick=\"javascript:submitForm()\"></INPUT>\n",
                "<INPUT TYPE=\"hidden\" NAME=\"", $HTTP_PARAMETER_STREAM_COUNT, "\" VALUE=\"", $i, "\">\n",
                "<INPUT TYPE=\"hidden\" NAME=\"", $HTTP_PARAMETER_ACTION, "\" VALUE=\"", $ACTION_SAVE, "\">\n",
                "<INPUT TYPE=\"hidden\" NAME=\"", $HTTP_STREAM_PLAYBACK, "\" VALUE=\"\">\n",
                "<INPUT TYPE=\"hidden\" NAME=\"", $HTTP_PARAMETER_MP3_ID, "\" VALUE=\"\">\n",
                "</FORM>\n",
                "<HR>\n",
                "<BR>\n",
                #"<PRE>\n",
                #"REQUEST_METHOD=", $web, "\n",
                #"QUERY_STRING=", $request, "\n",
                #"action : ", $http_parameters{$HTTP_PARAMETER_ACTION}, "\n",
                #"</PRE>\n",
                "</BODY>\n",
                "</HTML>\n";
    }
}else{
    # Test code running outside web server when script is invoked directly from command line
    print "Running outside webserver\n";
    print urlDecode("%31+%32%0A%33+%34"), "\n";
    print "request=$request\n";
    print "name_1=", $http_parameters{"name_1"}, "\n";
    $n=2;
    print "name_2=", $http_parameters{"name_".$n}, "\n";
    print "Number of HTTP parameters : ", scalar(keys %http_parameters),"\n";
    print $xml_content, "\n";
    $s=new Stream("Radio", "listen.pls", "0");
    print $s->{name}, "\n";
    print scalar(@streams)," streams found.", "\n";
    foreach $stream (@streams){
        print "Stream ", $stream->{name}, " with url ", $stream->{url}, "\n";
    }
    print "id=", generateId(4), "\n";
    writeFile("testfile.txt", "Some text in the file.\nAnother line\n");
    $text=  "some text\n".
            "continuing here\n";
    $text.="\nmore text.";
    print $text."\n\n";

    print $text."\n\n";
    print "Listing files in /mnt\n";
    @listing=listFiles("/mnt", true);
    foreach $file (@listing) {
        if( $file =~ /.mp3$/ ){
            print "mp3 file : ", $file, "\n";
        }
    }
    print "\n\n";
    print keys(%MIME_TYPES);
    print "\n\n";
    $mp3path="/some/path/mp3";
    if( $mp3path =~ /\.mp3$/ ){
        print "file is an mp3\n";
    }
    $mp3path="/some/path/titi.mp3";
    if( $mp3path =~ /\.mp3$/ ){
        print "titi is an mp3\n";
    }
    $hash=hashCode("http://statslive.infomaniak.ch/~radios/radios/files/ods/ods-high.pls");
    print "hash=", ascii_to_hex($hash), "\n";
    #stopPlayback();
    #startPlayback("/mnt/usb/mp3/Celia Cruz - La vida es un carnaval.mp3");
    $time=time;
    print "time is : ", $time, "\n";
}

25

Re: edit chumby parameters from chumby website in my chumby account

Hi Christian,

Nice script, I've been wanting something like this for a while.

One feature request:
Right now, I only see a "Start Playback" button next to MP3 type streams. What I'd really like to be able to do is remotely start and stop PLS type streams type streams as well. Any chance of adding this capability? Thanks!