#!/usr/bin/perl -w 
#
# Copyright (C) 2001-2006 J.I. van Hemert
#
# index.cgi - connect to freedb's http server and collect an entry,
# then transform it into jewel covers using Disc-Cover.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# Author: J.I. van Hemert <jano	AT	vanhemert.co.uk>
#
# README
# 
# This index.cgi combined with Disc-Cover is what powers the on-line version of
# Disc-Cover. Basically when it receives a user's query for an artist and/or cd
# title, it will fetch all the cds that match the query from www.freedb.org.
# Then the user can select one of these and create a cover (using Disc-Cover)
# in any of the supported formats.
# 
# To get this script to work, put it in a subdirectory of your public_html
# together with a recent version of Disc-Cover. Make sure both scripts are
# publicly readable and executable.
# 
# This CGI script is licensed under the same license as Disc-Cover, which is
# the GNU General Public License. The script is part of the package of
# Disc-Cover and should always be included in the Disc-Cover package.
#
# Jano van Hemert
#
#
# $Id: index.cgi,v 1.5 2006/01/21 10:45:39 jvhemert Exp $
#

my $path_to_discover="./disc-cover";

my $version = "1.0";

use CGI qw/:standard :default_dtd/;
use strict;

$|++;

#DEBUG#print "Content-Type: text/plain\n\n";
default_dtd('-//W3C//DTD HTML 4.01//EN');

my $config_load_error_level = 4;

if (param("results"))
{
	my $format = param("format");
	my $address = param("results");
	my $sideflap = param("sideflap");
	my $casetype = param("casetype") || "jewel";
	my $variousartistsinfo = param("variousartistsinfo") || "";
	my $genreinfo = param("genreinfo") || "";
	my $extendedtrackinfo = param("extendedtrackinfo") || "";
	my $searchfrontpicture = param("searchfrontpicture") || "";
	my $uppercasefix = param("uppercasefix") || "";

	my $freedb_entry_filename = "/tmp/disc-cover-cgi-$$.cddb";

	my $result = safe_exec('wget', '-O', '-', '-o', '/dev/null', "$address");
	#open IN, "<result.html" or die $!; my $result; while (<IN>) { $result .= $_; } close IN;
	my ($freedb_address) = ($result =~ /(http:\/\/www\.freedb\.org\/freedb\/[a-z]+\/[0-9a-f]+)/mg);
	my $freedb_entry = safe_exec('wget', '-O', "$freedb_entry_filename", '-o', '/dev/null', "$freedb_address");
	#DEBUG print STDERR $freedb_entry;

	my @disc_cover_params = ("$path_to_discover", '-b', $sideflap, $searchfrontpicture, $extendedtrackinfo, $variousartistsinfo, $genreinfo, $uppercasefix, '-c', $casetype, '-f', '-', '-o', '-');

	if ($format eq "ps")
	{
		print header(-type=>'application/postscript');
		print safe_exec(@disc_cover_params, '-t', 'ps', '-f', $freedb_entry_filename);
	}
	elsif ($format eq "pdf")
	{
		print header(-type=>'application/pdf');
		print safe_exec(@disc_cover_params, '-t', 'pdf', '-f', $freedb_entry_filename);
	}
	elsif ($format eq "tex")
	{
		print header(-type=>'text/x-tex');
		print safe_exec(@disc_cover_params, '-t', 'tex', '-f', $freedb_entry_filename);
	}
	elsif ($format eq "dvi")
	{
		print header(-type=>'application/x-dvi');
		print safe_exec(@disc_cover_params, '-t', 'dvi', '-f', $freedb_entry_filename);
	}
	elsif ($format eq "html")
	{
		print header();
		print safe_exec(@disc_cover_params, '-t', 'html', '-f', $freedb_entry_filename);
	}
	elsif ($format eq "txt")
	{
		print header(-type=>'text/plain');
		print safe_exec(@disc_cover_params, '-t', 'txt', '-f', $freedb_entry_filename);
	}
	elsif ($format eq "cddb")
	{
		print header(-type=>'text/plain');
		print safe_exec(@disc_cover_params, '-t', 'cddb', '-f', $freedb_entry_filename);
	}
	elsif ($format eq "lbl")
	{
		print header(-type=>'text/plain');
		print safe_exec(@disc_cover_params, '-t', 'lbl', '-f', $freedb_entry_filename);
	}
	else
	{
		print
			header(),
			start_html(-title=>'Disc-Cover: FreeDB -> Jewel Cover', -meta=>{'copyright'=>'Copyright 2001-2003 by J.I. van Hemert', 'keywords' => 'jewel cddb cover disc-cover freedb cddbp postscript pdf tex html txt', description=>'Create jewel covers online', 'creator' => 'Jano I. van Hemert'}, -text=>'black', -bgcolor=>'white', -alink=>'red', -vlink=>'#AAAAAA', -link=>'#AAAAAA'
			#-meta=>{'HTTP-EQUIV' => "Pragma", 'CONTENT' => "no-cache"}
			),
			font({-color=>"red"}, "This format is not implemented"),
			end_html();
	}

	system ("rm $freedb_entry_filename");

	exit (0);
}





print
	header(),
	start_html(
		-title=>'Disc-Cover: From FreeDB to Cover',
		-meta=>{
			'copyright'=>'Copyright 2001-2006 by J.I. van Hemert',
			'keywords' => 'jewel slim case cddb cover disc-cover freedb cddbp postscript pdf tex html txt cdcover',
			description=>'Create covers online',
			'creator' => 'jano		vanhemert.co.uk'
		},
		-text=>'black',
		-bgcolor=>'white',
		-alink=>'red',
		-vlink=>'#333399',
		-link=>'blue',
		-head=>Link({-rel=>'SHORTCUT ICON', -href=>'http://jvhemert.cjb.net/favicon.ico'})
	#-meta=>{'HTTP-EQUIV' => "Pragma", 'CONTENT' => "no-cache"}
	),"\n";


open(LOAD, "/proc/loadavg");
my ($load) = split(' ',<LOAD>);
close (LOAD);
if ($load > $config_load_error_level)
{
	print	h1("Disc-Cover online"),"<font size=+1>The load of this server is too high to be able to serve you, please wait a while and try again. Apologies for the inconvenience.</font>",p(),"<font color=red>Disc-Cover is looking for new servers:</font> Due to the online version becoming increasingly more popular I am looking for volunteers that offer to run an online version on their server, drop me a line at jano 	# vanhemert.co.uk",end_html();
	exit 0;
}

print	h1("Disc-Cover online"),
	"This page enables you to testdrive ",a({-href=>"http://www.vanhemert.co.uk/disc-cover.html"}, "Disc-Cover")," before attempting installation on your own system. Just fill in an artist and/or title below. We will search the ",a({-href=>"http://www.freedb.org"}, "FreeDB")," database and show all the results. Then, select your desired cd, the output format you want together with the type of case and we will create a cover for it.",p(),"To make life even easier install Disc-Cover on your own UN*X/Linux system as it is able to detect which cd is in the drive automatically.",p(),"<font color=red>Disc-Cover is looking for new servers:</font> Due to the online version becoming increasingly more popular I am looking for volunteers that offer to run an online version on their server, drop me a line at <img src=\"http://www.vanhemert.co.uk/address.png\" /> .";


#if ( ! grep {-f "$_/disc-cover"} split ':', $ENV{PATH} ) 
if ( ! -f "$path_to_discover" ) 
#if ( ! -f "disc-cover") 
{
	print p.font({-color=>"red"}, "Error could not find executable for Disc-Cover as \"$path_to_discover\". Please notify the system administrator of this problem.");
	print end_html();
	exit 0;
}

my $test_disc_cover = `$path_to_discover -CVS`;
print p."This system is powered by Disc-Cover from CVS ($test_disc_cover)";

print p."Copyright &copy; 2001-2006 version $version by ".a({-href=>"http://www.vanhemert.co.uk/"}, "J.I. van Hemert");



if ($test_disc_cover eq "")
{
	print p.font({-color=>"red"}, "Error when testing for Disc-Cover. Please notify the system administrator of this problem.");
	print end_html();
	exit 0;
}

print	
	h2("Step 1: search cd"),
	"<fieldset><legend>search for artist / title</legend>",
        start_form(-action=>"", -method=>"post"),
	textfield(-name=>"q"),
	"&nbsp;",
	submit(),
	end_form(),
	"</fieldset>";


if (param("q"))
{
	print h2("Step 2: create cover");
	my $query = param_fetch('q')->[0];
	
	$query =~ s/ /\+/g;
	my $result = safe_exec('wget', '-O', '-', '-o', '/dev/null', "http://www.freedb.org/freedb_search.php?words=$query&allfields=NO&fields=artist&fields=title&allcats=YES&grouping=none");
	#DEBUG# open IN, "<result" or die $!; my $result; while (<IN>) { $result .= $_; } close IN;
	if ($result =~ /<b>Warning<\/b>:  OCI/)
	{
		print "Something appears to be wrong with the ",a({-href=>"http://freedb.music.sk/search/index.phtml?search=$query"}, "FreeDB search engine"),", please check it out and notify the maintainers.";
	}
	else
	{
		my @entries = ($result =~ /<a href=\"(http:\/\/www.freedb.org\/freedb_search_fmt.php\?cat=[a-z]+\&id=[a-f0-9]+)\">([^<]+)<\/a>/mg);
		my $matches = @entries;
		my ($specific) = ($result =~ /lot of matches found/mg);
		#DEBUG# print STDERR "Matches found: $matches\n";
		if (defined $matches and $matches > 0)
		{
			#DEBUG# print $result;
			CGI::delete("q");
			print
				start_form(-action=>"", -method=>"post");
				
			#print h3("2.1 choose the output format");
			print p."<fieldset><legend>2.1 choose the output format</legend>";
			print radio_group(	-name=>'format',
						-values=>['ps', 'pdf','dvi','tex','txt','html','lbl','cddb'],
						-default=>'',
						#-linebreak=>'true',
						-columns=>1,
						-labels=>{ 	'ps' => 'PostScript',
								'pdf' => 'PDF, Acrobat users, please make sure when printing you switch off the Fit to Page option',
								'tex' => 'LaTeX',
								'html' => 'HTML',
								'dvi' => 'Dvi',
								'txt' => 'Plain text',
								'lbl' => 'CDlabelgen',
								'cddb' => 'CDDB'
							}
			);

			print "</fieldset>";

			#print h3("2.2 choose the cover type");
			print p."<fieldset><legend>2.2 choose the cover type</legend>";
 			  my ($template_names, $template_desc);
 			  my @t_list = split(/\n/, safe_exec("$path_to_discover", "--template_list"));
 			  for (@t_list) {
 			      /^([-a-zA-Z0-9]+):.*$/;
 			      push(@$template_names, $1);
 			      $template_desc->{$1} = $_;
 			  }
 			  
 			  print radio_group(-name=>'casetype',
 					    -values=> $template_names,
 					    -default=>'jewel',
 					    -columns=>1,
 					    -labels=> $template_desc
 					    );

			print "</fieldset>";


			#print h3("2.3 set additional options");
			print p."<fieldset><legend>2.3 set additional options</legend>";

			print checkbox(-name=>"searchfrontpicture", -checked=>0, -value=>"-allmusic", -label=>"");
			print "search for a front cover on Allmusic (experimental: no success guarenteed)";
			print br;

			print checkbox(-name=>"extendedtrackinfo", -checked=>1, -value=>"-e", -label=>"");
			print "enable extended track info (sometimes contains garbage)";
			print br;

			print checkbox(-name=>"genreinfo", -checked=>0, -value=>"-g", -label=>"");
			print "enable genre info (often contains garbage)";
			print br;

			print checkbox(-name=>"variousartistsinfo", -checked=>0, -value=>"-va", -label=>"");
			print "enable various artist info (sometimes useful for collections cds)";
			print br;
			
			print checkbox(-name=>"uppercasefix", -checked=>0, -value=>"-uppercase", -label=>"");
			print "fix entries with all lowercase (sometimes useful)";
			print br;

			print textfield(-name=>"sideflap"),("text on sideflap")," (quite optional)",br;

			print p;

			my @values;
			my %labels;
			while (@entries)
			{
				my $address = shift @entries;
				my $name = shift @entries;
				
				push @values, $address;
				if ($name =~ /^[0-9]$/)
				{
					$name = "» alternative option $name";
				}
				$labels{$address} = " $name";
			}
			print "</fieldset>";

			#print h3("2.4 select which cd to use (".($matches/2)." found)");
			print p."<fieldset><legend>2.4 select which cd to use (".($matches/2)." found)</legend>";
			print radio_group(	-name=>'results',
						-values=>\@values,
						-default=>'',
						-linebreak=>'true',
						-labels=>\%labels
			);
			print "</fieldset>";
			
			#print h3("2.5 generate cover");
			print p."<fieldset><legend>2.5 generate cover</legend>";
			print submit(-name=>"submit", -value=>"download cover");
			print "</fieldset>";

			print
				end_form();
		}
		else
		{
			if (defined $specific)
			{
				print "Sorry, too many matches, be more specific";
			}
			else
			{
				print "Sorry, no matches found";
			}
		}
	}

	print p;
}

print end_html;



sub safe_exec
{
	my $program = shift;
	
	my $result;
	my $pid = undef;
	die "Error: cannot fork $!" unless defined ($pid = open(SAFE_KID, "-|"));
	if ($pid == 0)
	{
		#exec('wget', "-O-", "-o/dev/null", "http://www.allmusic.com/cg/amg.dll?P=amg&opt1=2&sql=$web_search") or die "Error: can not exec wget: $!";
		exec($program, @_) or die "Error: can not exec $program $!";
	}
	else
	{
		$/ = undef;
		$result = <SAFE_KID>;
		close SAFE_KID;
		
	}
	return $result;
}

