Friday, July 31, 2009

Rip from WAV to MP3 and add ID3 tags -- All with Perl

Ok - so I know I have said before that I am not much of a perl fan. ( yes it's safe, I am wearing my flame proof suit. )

I will, however, say now; I am coming around. It would seem that I am starting to see the light. I needed to extract some files from a CD I have and convert them to MP3. The CD was not made with extracting to mp3 in mind if you get my drift. It's ok, because the CD is my copy and I want to listen to it on my iPod. Regular extracting on iTunes was not working out for me. So I rolled my chair over to my trusty Linux Box and perl, id3, cdparanoia and lame.

First thing I did was use cdparanoia to extract all the tracks. This went swimmingly leaving me with a folder full of files called 01.cdparanoia.wav or something just as useless. The files played ok but I needed to name them all. This particular CD was not listed on Music Brainz so I couldn't do anything fancy with FreeCDDB or whatever they call that now days.

* shudder * - I had to manually edit 17 filenames. I left the .wav extensions of course. I thought that I might need to get the tags later so I decided to choose a naming scheme for my file names.

01-My Song Title_My Artist Name.wav

and so on.

Then I wrote a little script that:
  • Loops through each file in a folder with the .wav extension
  • Saves a variable with the file name but with .mp3 instead of .wav
  • Regexes ( new word ) out the various parts of the file name into $track, $title, $artist ( thanks to the nice naming scheme this was easy. )
  • Uses Lame to convert the file. Lame now days is pretty cool.
  • Uses id3v2 to add the tags extracted from the file name. I can use amarok to add the album titles etc once it is imported into Amarok.
Here is the script:
#!/usr/bin/env perl

@files = <*.wav>;

foreach $file (@files) {

$newfile = $file;
$newfile =~ s/\.wav/\.mp3/;

$file =~ m/^(.*)-(.*)_(.*).wav/;

$track = $1;
$title = $2;
$artist = $3;

system("lame", "--preset", "cd" ,"$file" ,"$newfile");
system("id3v2", "--artist", "$artist", "$newfile");
system("id3v2", "--song", "$title", "$newfile");
system("id3v2", "--track", "$track", "$newfile");


Thursday, July 30, 2009

Real simple to connect to MSSQL from Perl

Again, this took me a little while but here I am. Connecting to a database ( SQL SERVER 2008 ) from a Windows Server 2008 VM I own ( thanks TECH ED 2008 ) and Active State Perl.

Install Scite cos it's a nice editor and you are away laughing...


use DBI;

my $DSN = 'driver={SQL Server};Server=localhost; database=AdventureWorks;TrustedConnection=Yes';
my $dbh = DBI->connect("dbi:ODBC:$DSN") or die "$DBI::errstr\n";

my $sth = $dbh->prepare('select top 10 * from Sales.vSalesPerson')
or die "Couldn't prepare statement: " . $dbh->errstr;


while( @data = $sth->fetchrow_array())
foreach(@data) {
print "[$_]";
print "\n\n";



[268][][Stephen][Y][Jiang][][North American Sales Manager][238-555-0197][stephen][0][2427 Notre Dame Ave.][][Redmond][Washington][98052][Un
ited States][][][][677558.4653][.0000]

[275][][Michael][G][Blythe][][Sales Representative][257-555-0154][michael9@adven][1][8154 Via Mexico][][Detroit][Michigan][48226][United States][N
ortheast][North America][300000.0000][4557045.0459][1750406.4785]

[276][][Linda][C][Mitchell][][Sales Representative][883-555-0116][linda3@adventu][0][2487 Riverside Drive][][Nevada][Utah][84407][United States][Sou
thwest][North America][250000.0000][5200475.2313][1439156.0291]

[277][][Jillian][][Carson][][Sales Representative][517-555-0117][jillian0@advent][1][80 Sunview Terrace][][Duluth][Minnesota][55802][United States]
[Central][North America][250000.0000][3857163.6332][1997186.2037]

[278][][Garrett][R][Vargas][][Sales Representative][922-555-0165][garrett1@adven][0][10203 Acorn Avenue][][Calgary][Alberta][T2P 2G8][Canada][Cana
da][North America][250000.0000][1764938.9859][1620276.8966]

[279][][Tsvi][Michael][Reiter][][Sales Representative][664-555-0112][tsvi0@adven][1][8291 Crossbow Way][][Memphis][Tennessee][38103][United States
][Southeast][North America][300000.0000][2811012.7151][1849640.9418]

[280][][Pamela][O][Ansman-Wolfe][][Sales Representative][340-555-0193][pamela0@a][1][636 Vine Hill Way][][Portland][Oregon][97205][United Stat
es][Northwest][North America][250000.0000][.0000][1927059.1780]

[281][][Shu][K][Ito][][Sales Representative][330-555-0120][shu0@adventure-works.
com][2][5725 Glaze Drive][][San Francisco][California][94109][United States][Sou
thwest][North America][250000.0000][3018725.4858][2073505.9999]

[282][][JosΘ][Edvaldo][Saraiva][][Sales Representative][185-555-0169][josΘ1@adve][0][9100 Sheppard Avenue North][][Ottawa][Ontario][K4B 1T7][Cana
da][Canada][North America][250000.0000][3189356.2465][2038234.6549]

[283][][David][R][Campbell][][Sales Representative][740-555-0182][david8@adventu][0][2284 Azalea Avenue][][Bellevue][Washington][98004][United State
s][Northwest][North America][250000.0000][3587378.4257][1371635.3158]


Sunday, July 26, 2009

Basic Perl file parser - useful for working with logs

Really I just need to remember how to do this:

#!/usr/bin/env perl
#yum log file
use warnings;
use strict;

open FILE, "/var/log/yum.log" or die $!;
while (<FILE>) {
my ($month,$day,$time,$action,$package) = ($1,$2,$3,$4,$5);
if( $action =~ /Installed/ ) {
my $suffix = 'th';
if( $day == 1 ){ $suffix = 'st'; }
if( $day == 21 ){ $suffix = 'st'; }
if( $day == 31 ){ $suffix = 'st'; }
if( $day == 2 ){ $suffix = 'nd'; }
if( $day == 22 ){ $suffix = 'nd'; }
if( $day == 3 ){ $suffix = 'rd'; }
if( $day == 23 ){ $suffix = 'rd'; }

print "$day$suffix of $month at $time\n"
close FILE

Joining multiple PDF documents with Gostscript.

This really works.

I downloaded all the chapters of beginning perl as published here:

To do it in a painless way I first used curl to grab the html.
curl -o bp.txt

Then I used grep to grab the hyperlinks to pdf files and piped that into another file.
cat bp.txt | grep -o "<a.*pdf"> bp2.txt

Then I used sed to clean up a little bit.
cat bp2.txt | sed "s/^<a href=\"//g"> bp3.txt

Then I used wget to download each pdf.
for line in `cat bp3.txt`; do wget $line; done

So now I had a whole bunch of pdf files that together make up one book. A quick hunt on google produced this guy.

And I was away laughing.

gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=beginning-perl.pdf 3145_Intro.pdf 3145_Chap*.pdf 3145_App*.pdf 3145_Index.pdf

Sunday, July 5, 2009

Samba File Sharing to Windows ( Includes Vista )

I found this:

Here are the main points:

Install Samba

yum install samba samba-client

Configure Samba ( as root )

# vim /etc/smb.conf

Add a workgroup name under the [globals] section.

Add your fileshares at the end of the file.

path = /media/TerraByte
public = yes
writable = yes

This will create a writable share. File permissions in linux must match. Ie: (dwrx-dwr-dwr ).

If your drive is an NTFS formatted drive, these permissions can not be applied. It doesn't matter though because it still works.

Set up samba users. Users must already exist as users on your linux system. They must be valid users. The password does not need to match. There are a bunch of warnings that can be ignored.

# smbpasswd -a username
New SMB password:
Retype new SMB password:
account_policy_get: (warnings ignored)
Added user username.

Start the samba service and enable it in chkconfig levels 3 and 5.

Enable samba in the firewall of the linux box.

SELINUX - I don't use it at home so I have quoted direct from the webpage for reference.

SELinux has significant control over restricting different parts of Samba. Run system-config-selinux. Please read lines #23 - #51 in /etc/samba/smb.conf for a better explanation. Alternatively, you can run:

[mirandam@charon ~]$ system-config-selinux

Go to Boolean and type 'samba' in the Filter (without quotes).

Alternatively, you can ignore SELinux at this point and try to access your shares in Windows and SELinux TroubleShooter should give an automatic pop-up in GNOME explaining what is wrong. If you follow those recommendations you most likely will be more secure.

For any changes made above to the SELinux settings or smb.conf, it is recommended to restart Samba.