UPDATE: Please check out latest version from my git repo: http://git.vpetkov.net/projects – project name: “pandora”
It seems that Pandora is not putting too much time or thought into how they provide and access music online through their website. I really hope they fix this since it’s irresponsible as far as the the DMCA is concerned. Each song is simply an encoded token, and it’s pulled down directly from, presumably, one of their proxy server. If you look at the stream while playing songs on pandora.com, you will notice something like this (ex: not real):
access/197185343492159781?
version=4&lid=######&token=Rqcw8pKLwxByRVLM6SynyT%2Fw0yGw2F3WW8efWPzuBSsaQTUKz
obvQ3A8Q0Z0uDm1FiUpSiWMqH5CUwW%2B51WJs7IhT9O%85DLlKtVZuYO55LpLuaeooiYTIFvdeCyHaM
i%2Fq8%2FClLJuDEipmt6%2FMR8QvwebIF8rt2Hlcqwj70Stc7E2TeB8021eG60OV%2B%2FCbVMhL3Sh
0qdGSLnHK55xabtdZSoES7HYGPPG7wLjNurP%2FTGjqx%2Bz9%afdsjx2jdhg%2FMZX3A7zx8DlNEPy5
ahaM8z3VjjfDGhWTElBIzveYigBdLq7j9t7mUHjtwEJZ3yHKhHNapEtmb8ZSOIwbAUfqjMiJtk7WXVDq
qBZZ7
Some assumptions: the “version=4″ is high quality or what used to be CD quality (192 kbps). The “lid=#####” is the “login id”, or your unique user number. The “token=…” is the actual song, encoded. By finding the host of these requests, and putting it all together, where the lid is completely optional, you will have a full request URL to a song.
Imagine putting it together like this: (example as a POC, like this)
#!/bin/bash
tshark -i en0 -l -T fields -E separator="," -e http.host -e http.request.uri -R
"http.request.uri contains token and http.host contains pandora" | ./worker.pl
Then having something that parses this “buffer”:
#!/usr/bin/perl
use Tie::File;
use WWW::Mechanize;
my $tokensdb = '.tokens.db'; my $songsdb = '.songs';
unless(-e $tokensdb) { `touch $tokensdb`; }
unless(-d $songsdb){ mkdir $songsdb or die; }
tie our @tokens, 'Tie::File', $tokensdb;
my $mech = WWW::Mechanize->new();
$mech->timeout(5);
$mech->quiet(1);
$mech->agent_alias( 'Mac Safari' );
while (<STDIN>) {
my ($host, $token) = split(/,/, $_);
$token =~ s/&lid=(\d*)//g; chomp($token);
my $url = "http://$host"."$token";
if ( grep { "$_" eq "$token"} @tokens ) {
print "Token Already Seen...\n";
}
else {
push(@tokens, $token);
print ">> New Token Added!\n";
$file = time;
# Code removed in order to prevent Abuse!
}
}
One way for them to fix this would be to session encode the requests. You should not be able to make requests that originate from outside of pandora.com directly to the servers. Also, the requests should be authenticated. As an addition, they could potentially be checked against what is “played” and controlled for streaming mechanisms. I really hope this fix this as soon as possible.
UPDATE: Please check out latest version from my git repo: http://git.vpetkov.net/projects – project name: “wordpress”
I already created a script to upgrade wordpress installations automatically. You can find it here: http://blog.vpetkov.net/2011/06/01/script-to-upgrade-wordpress-to-the-latest-version-fully-automatically Recently, the same general problem came about when it came to plugins. The biggest problem I had is that I had to log-into wordpress, see a number of plugins that were outdated, and then go hunt each one down by generally just copying the name and pasting it into google . Even thought most of the time, the plugin was the first hit, I then had to download the latest version, extract it, and clean it up. Imagine doing this for 10+ plugins for 5+ blogs — constantly. It was just time consuming and frustrating.
Here is my solution in the form of a perl script:
#!/usr/bin/perl
# Usage:
# ./update-wp-plugins.pl
# or
# ./update-wp-plugins.pl registered-name-of-plugin
# (and this works to update an exiting plugin or download+install a new one)
chdir("/var/www/domain/blog/wp-content/plugins");
use WWW::Mechanize;
my $mech = WWW::Mechanize->new();
$mech->agent_alias( 'Mac Safari' );
my $wp_base_url = "http://wordpress.org/extend/plugins";
################################################
# Add New Plugins Here:
# Format:
# 'registered-name-of-plugin',
#
my @plugins = (
'google-sitemap-generator',
'wptouch',
);
################################################
if(defined($ARGV[0])) {
my $name = $ARGV[0];
&update_plugin($name);
}
else {
for my $name (@plugins) {
&update_plugin($name);
}
}
sub update_plugin {
my $name = shift;
my $url = "$wp_base_url/$name";
$mech->get( $url );
my $page = $mech->content;
my ($url,$version,$file) = "";
if($page =~ /.*<p class="button"><a href='(.*)'>Download Version (.*)<\/a><\/p>.*/) {
$url = $1;
$version = $2;
if($url =~ /http:\/\/downloads\.wordpress\.org\/plugin\/(.*)/) {
$file = $1;
}
}
print "\nPLUGIN: $name | Version $version\n";
`/bin/rm -f $file`; print "Downloading: \t$url\n";
`/usr/bin/wget -q $url`; print "Unzipping: \t$file\n";
`/usr/bin/unzip -o $file`; print "Installed: \t$name\n";
`/bin/rm -f $file`;
}
This script can be used in one of two ways:
1.) You can simply run it, and it will update everything that you have listed in the @plugins array.
2.) You can give it a parameter of a registered plugin name. This does 2 jobs — upgrades an existing plugin, AND installs new ones.
You can definitely add an extension to this. For #1, you can go a step further by making it scan your plugin directory and populating the list from there. If you want to be even fancier, you can relatively easily keep version tracks of what you have installed and what’s currently available, so that you don’t just blindly download new plugins. For me this is sufficient. If anyone is interested in getting help implementing any of these extra additions, feel free to ask and I’ll help as much as I can.
Recent Comments