>From: Martin Andrews >To: wreq@math.duke.edu, jitterbug@samba.org >Subject: Converting jitterbug to wreq --------------FB736B273D0D6DCAEC7F8A68 I am in the process of converting my trouble reporting system from jitterbug ( http://samba.anu.edu.au/jitterbug/ ) to wreq ( http://www.math.duke.edu/~yu/wreq/ ). Anyone else considering such a move might be interested in this little perl script I wrote to convert the problem report database. Martin -- Martin Andrews mandrews@netgenics.com --------------FB736B273D0D6DCAEC7F8A68 #!/opt/ngapp/bin/perl # # Convert jitterbug data into wreq version 2.x format. # # Written by Martin Andrews (mandrews@netgenics.com) # #NOTE: YOU MUST CONFIGURE YOUR SERVER THROUGH THE WEB FIRST, THEN RUN THIS # TO CONVERT YOUR EXISTING REQ DATA BEFORE ADDING ANY NEW REQUESTS!!! # This script must be run from the dir where this file resides. #use strict; use File::stat; use Cwd; sub Convert; sub ReadFile; sub WriteFile; ########## local config: You might need to edit them before run ##### ### Data dir for the old jitterbug system. It contains the request dirs and ### files like systems.audit and users. my $jittertop="/export/home/mandrews/is-bugs"; # must be an absolute path name ### Your DNS domain name for email my $defaultemailaddress='netgenics.com'; ### Wreq support group# to convert into. Default to 1 for new install my $group=1; # Determine request status information from the name of the jitterbug # directory containing it sub InferFromDir { my ($dir) = @_; my $type; my $status; my $priority; $dir =~ s/^.*\///; if ( $subdir =~ /^[23]/ ) { $type = 'resolved'; $status = 'resolved'; } elsif ( $subdir =~ /^4/ ) { $type = 'deleted'; $status = 'deleted'; } else { $type = 'active'; if ( $subdir =~ /^1\.1 / ) { $priority = 100; } elsif ( $subdir =~ /^1\.2 / ) { $priority = 50; } elsif ( $subdir =~ /^1\.3 / ) { $priority = 30; } elsif ( $subdir =~ /^1\.4 / ) { $priority = 10; } elsif ( $subdir =~ /^1\.7 / ) { $priority = 5; $status = 'stalled'; } } return $type, $status, $priority; } ########## End local config ########################################## if(defined($ENV{'REQUEST_METHOD'})){# called from a browser, just quit print<<"EOF"; Content-type: text/html\n\r\n\r Please don't call this script directly from web. Thank you. EOF exit 0; } umask 022; my $now=time; my $field_sep ="\035"; require 'req-config'; require 'req-common'; $|=1; my $maxid = 0; # Create constants for request record's field offsets. my %offsets; my $i = 0; foreach my $fieldname (REQNUM, NAME, UID, EMAIL, LOCATION, DATE, DUEDATE, PRIORITY, OWNER, STATUS, BLINK, LASTACTDATE, OSTYPE, AREA, SUBJECT, DESCRIPTION, MAILHEADER, ACTIONLOGS, ALLVIEW, LASTEMAIL, LASTACT) { $offsets{$fieldname} = $i; $i++; } $offsets{'RHOST'} = 39; $offsets{'RADDR'} = 40; # Move to base wreq directory, and check that it is configured properly. chdir $top || die("Error, can't cd to $top."); if(!-d "req/$group/resolved" || !-f "req/config" || !-f "req/site.lock"){ die "The server is not properly configured yet. Please do that first!"; } if(!-d $jittertop){ die "Can't find $jittertop from current working dir $top."; } if(-s "req/$group/active" || -s "req/$group/all"){ print "Your wreq server already has data. OK to overwrite? [y] "; my $tmp=; chop $tmp; if($tmp && $tmp !~ /^y/i){exit(0);} } opendir(JDIR, $jittertop) or die $!; while ( $subdir = readdir(JDIR) ) { my $path = "$jittertop/$subdir"; # Skip if directory name does not begin with alpha-numeric or is not # a really a directory. next if ( $subdir !~ /^\w/ or !(-d "$jittertop/$subdir") ); opendir(JSUBDIR, $path) or die $!; while ( $filename = readdir(JSUBDIR) ) { Convert($filename, $path) if ($filename =~ /^\d+$/); } closedir(JSUBDIR); } closedir(JDIR); $maxid++; $f="req/$group/nextid"; WriteFile($f, $maxid); print ".done\n"; exit(0); sub Convert { my ($recnum, $dir) = @_; my %rec = (); my @arr = (); my $in_header = 1; my $st; my $rdt = $now; my ($type, $status, $priority) = InferFromDir($dir); print "Converting $dir/$recnum\n"; # huh? $rec{'REQNUM'} = $recnum; $rec{'RADDR'} = '1.2.3.4'; $rec{'OWNER'} = ReadFile("$dir/$recnum.assign"); $rec{'LOCATION'} = 'converted from jitterbug'; $rec{'STATUS'} = $status; $rec{'PRIORITY'} = $priority; $st = stat("$dir/$recnum"); $rec{'DATE'} = $st->mtime; if (-f "$dir/$recnum.audit") { $st = stat("$dir/$recnum.audit"); } $rec{'LASTACTDATE'} = $st->mtime; open(FILE, "$dir/$recnum") or die $!; foreach () { if ($in_header) { $rec{'MAILHEADER'} .= $_; if(/^$/){ $in_header = 0; $rec{'DESCRIPTION'} .= "\n"; }elsif(/^From:\s+(.*\S)/){ $rec{'DESCRIPTION'} .= ">$_"; # Huh? ($rec{'EMAIL'},$rec{'NAME'}) = &matchEmail($1); }elsif(/^From\s+(\S+)\s+(.*\S)/){ $rec{'EMAIL'}=$1 if(!$rec{'EMAIL'}); }elsif(/^Subject:\s+(.*)/i){ $rec{'DESCRIPTION'} .= ">$_"; $rec{'SUBJECT'}=$1; }elsif(/^To:/){ $rec{'DESCRIPTION'} .= ">$_"; } } else { # Body. $rec{'DESCRIPTION'} .= $_; } } close(FILE); $rec{'UID'} = $rec{'EMAIL'}; if ( $rec{'UID'} =~ /^(\S+)\@/ ) { $rec{'UID'}=$1; } # open all followups and replies... and notes ... and audit??? my $olddir = cwd; chdir $dir or die $!; my %bytimes; foreach my $path (glob($recnum . ".*")) { if ( $path =~ /\.(reply)|(followup)\.[0-9]+$/ ) { my $st = stat($path); my $mtime = $st->mtime; # In case two items have the same mtime - make one a little # later: while (defined($bytimes{$mtime})) { $mtime += 1; } $bytimes{$st->mtime} = $path; } } foreach my $mtime (sort({$a <=> $b} keys(%bytimes))) { $rec{'ACTIONLOGS'} .= "====================== did something " . localtime($mtime) . "\n"; $rec{'ACTIONLOGS'} .= ReadFile($bytimes{$mtime}) . "\n\n"; } if ( -f "$recnum.notes" ) { my $st = stat("$recnum.notes"); my $mtime = $st->mtime; $rec{'ACTIONLOGS'} .= "====================== SUMMARY " . localtime($mtime) . "\n"; $rec{'ACTIONLOGS'} .= ReadFile("$recnum.notes") . "\n\n"; } chdir $olddir || die("Error, can't cd to $olddir."); if ( $type ne 'active' ) { my @dt=localtime($rdt); $type .= "/" . ($dt[5]+1900) . "/$months{$dt[4]}"; } $dbfile="req/$group/$type"; &makeDir($dbfile); $maxid = $recnum if $recnum>$maxid; # Convert name-based hash to int-indexed array. foreach my $key (keys(%rec)) { die "bad field $key" if !defined $offsets{$key}; $arr[$offsets{$key}] = $rec{$key}; } &DBMopenwrite($dbfile); $DBM{$recnum}=join($field_sep, @arr); &DBMclosewrite($dbfile); &DBMopenwrite("req/$group/all"); $DBM{$recnum}=$type; &DBMclosewrite("req/$group/all"); } # Read contents of named file, and return contents with leading and trailing # spaces removed. If file does not exist, return nothing (undefined). sub ReadFile { my ($filename) = @_; open(FILE, "<$filename") or return; $contents = join('', ) ; close FILE; chomp($contents); return $contents; } # Create/replace $filename with data in $content - appends a newline. sub WriteFile { my ($filename, $content) = @_; open(FILE, ">$filename") or die "can't open $filename: $!"; print(FILE "$content\n"); close(FILE); } --------------FB736B273D0D6DCAEC7F8A68-- >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> To subscribe, mail wreq@math.duke.edu with the subject: wreq subscribe To unsubscribe, mail wreq@math.duke.edu with the subject: wreq unsubscribe