#!/usr/bin/perl -w use strict; use Getopt::Std; use URI::Escape; if ($#ARGV==-1) { displayUsage(); exit -1; } getopts('ndc:o:s:'); my $csvDir; if ($::opt_c) { if (-d $::opt_c) { $csvDir = $::opt_c; } else { print STDERR "FATAL: Specified CSV directory nof found: ".$::opt_c."\n"; displayUsage(); exit -1; } } else { print STDERR "FATAL: A CSV directory needed. (-c)\n"; displayUsage(); exit -1; } my $outputDir; if ($::opt_o) { if (-d $::opt_o) { $outputDir = $::opt_o; } else { print STDERR "FATAL: Specified output not found: ".$::opt_o."\n"; displayUsage(); exit -1; } } else { print STDERR "FATAL: An output directory needed. (-o)\n"; displayUsage(); exit -1; } ## my $addSuffix; $addSuffix = $::opt_s if ($::opt_s); my $suppressFileTag; $suppressFileTag++ if ($::opt_n); my $deleteCSVs; $deleteCSVs++ if ($::opt_d); # Sanitize slashes if ($outputDir !~ /[\\\/]/) { $outputDir .= "\\"; } else { my $outputDirSlash = ($outputDir =~ /\\/ ? "\\" : "\/"); $outputDir .= $outputDirSlash unless($outputDir =~ /$outputDirSlash$/); } if ($csvDir !~ /[\\\/]/) { $csvDir .= "\\"; } else { my $csvDirSlash = ($csvDir =~ /\\/ ? "\\" : "\/"); $csvDir .= $csvDirSlash unless($csvDir =~ /$csvDirSlash$/); } # Check directories unless(-d $csvDir) { print STDERR "FATAL: Could not find specified CSV directory: ".$csvDir."\n"; exit -1; } unless(-d $outputDir) { print STDERR "FATAL: Could not find specified output directory: ".$outputDir."\n"; exit -1; } # Read all CSVs unless(opendir(CSV, $csvDir)) { print STDERR "FATAL: Unable to open CSV directory [".$csvDir."]: ".$!."\n"; exit -1; } while(my $entry = readdir(CSV)) { next if ($entry =~ /^\.\.*$/); print STDERR "INFO: Processing CSV: ".$entry."\n"; my %metaData; readCSV($csvDir.$entry, \%metaData); if ($::opt_d) { unless(unlink($csvDir.$entry)) { print STDERR "ERROR: Unable to remove CSV file [".$csvDir.$entry."]: ".$!."\n"; } } # Create metadata directories foreach my $metaEntry (sort keys %metaData) { my $entryDir = $outputDir.$metaEntry.".card"; if (!-d $entryDir) { unless(mkdir($entryDir)) { print STDERR "FATAL: Unable to create directory [".$entryDir."]: ".$!."\n"; exit -1; } } } ## # Generate XML foreach my $metaEntry (sort keys %metaData) { my $eventDataFile = $outputDir.$metaEntry.".card".($outputDir =~ /\\/ ? "\\" : "\/")."eventDetail.xml"; my %fileHash = %{$metaData{$metaEntry}}; my $XML = generateXML(\%fileHash, $addSuffix, $suppressFileTag); print STDERR "INFO: Writing [".$eventDataFile."]...\n"; unless(open(OUT, ">", $eventDataFile)) { print STDERR "FATAL: Unable to open file [".$eventDataFile."] for write: ".$!."\n"; exit -1; } print OUT $XML."\n"; close(OUT); print STDERR "INFO: Done!\n"; } print STDERR "INFO: Done Processing CSV: ".$entry."\n"; } closedir(CSV); exit 0; sub readCSV { return undef unless($#_==1); my $mKfile = shift(@_); my $mKHHRef = shift(@_); unless(open(CSV, "<", $mKfile)) { print STDERR "FATAL: Unable to open CSV file [".$mKfile."]: ".$!."\n"; exit -1; } my $mKlineCnt = 0; # Fields Setup my @mKHDFields = parseCSVLine(scalar()); my %mKHH; for(my $i=0;$i!=($#mKHDFields+1);$i++) { # Adjust Fields to Lower Case $mKHDFields[$i] =~ tr/A-Z/a-z/; # Clean out tags like , etc. $mKHDFields[$i] =~ s/\<([^>]+)\>//g; # Clean leading and trailing spaces $mKHDFields[$i] =~ s/^\s+//g; $mKHDFields[$i] =~ s/\s+$//g; } # Load Data while(my $mKline = ) { $mKline =~ s/(\n|\r)//g; $mKlineCnt++; my $advance=5; if (((() = $mKline =~ /\"/g) % 2)!=0) { while(($advance)&&(((() = $mKline =~ /\"/g) % 2)!=0)) { my $temp = ; $temp =~ s/(\n|\r)//g; $advance--; $mKline .= $temp; } } my @mKrowFields = parseCSVLine($mKline); my %tempHash; my $mKfieldCnt = 0; foreach my $mKrowField (@mKrowFields) { my $key = $mKHDFields[$mKfieldCnt]; $mKfieldCnt++; next if ($mKrowField =~ /^(\s+)*None(\s+)*$/i); # Patch to avoid 'None' values $tempHash{$key} = $mKrowField; } if ((!exists($tempHash{'filename'}))&& (exists($tempHash{'file name'}))) { $tempHash{'filename'} = $tempHash{'file name'}; } if ($tempHash{'filename'}) { ${$mKHHRef}{${tempHash{'filename'}}} = \%tempHash; } } close(CSV); return 1; } sub parseCSVLine { return undef unless($#_>=0); my $zzzline = shift(@_); my $zzzfieldCnt = shift(@_); # Must have an even number of quotes return undef if (((() = $zzzline =~ /\"/g) % 2)!=0); my @zzzarray = split(/\,/,$zzzline); my @zzzreturn; while($#zzzarray!=-1) { my $zzzentry = shift(@zzzarray); if ($zzzentry =~ /\"/) { while (((() = $zzzentry =~ /\"/g) % 2)!=0) { $zzzentry .= ",".shift(@zzzarray); } } # Strip leading quotes $zzzentry =~ s/^\"//g; # Strip trailing quotes $zzzentry =~ s/\"$//g; # Strip leading spaces $zzzentry =~ s/^\s+//g; # Strip trailing spaces $zzzentry =~ s/\s+$//g; # Convert double quotes to single. $zzzentry =~ s/\"\"/\"/g; push(@zzzreturn,$zzzentry); } return (@zzzreturn) if ($#zzzreturn!=-1); } ## trim down the sub xml etc sub generateXML { return undef unless(ref($_[0]) eq 'HASH'); my $gXHHRef = shift(@_); my $gXfileSuffix; # optional if ($#_>=0) { my $suffix = shift(@_); $gXfileSuffix = ".".$suffix if ($suffix); } my $gXsuppressFileTag; if ($#_>=0) { $gXsuppressFileTag = shift(@_); } my $gXpthe = ${$gXHHRef}{'picnic theme'}; my $gXorgname = ${$gXHHRef}{'organizer name'}; my $gXvaddr = ${$gXHHRef}{'venue address'}; my $gXeLoc = ${$gXHHRef}{'event location'}; my $gXpFull = html_escape(${$gXHHRef}{'event detail'}); my $gXtot = html_escape(${$gXHHRef}{'total allowed heads'}); my $gXgpar = html_escape(${$gXHHRef}{'maximum game participants'}); my $gXecont = ${$gXHHRef}{'star attraction'}; my $gXpdate = reformatDate(${$gXHHRef}{'picnic date'}); my $gXtext = <<"GXEOF"; $gXpthe