This is all Pav’s fault. The conversation went something like this (other conversations trimmed):
[15:32] <Pav> dvl: around?
[15:39] <dvl> Pav: here!
[15:41] <dvl> .ping Pav
[15:41] <dvl> ping Pav
[15:41] *** ¢ PING sent to Pav
[15:41] *** ¢ PING reply of 3.25 s from Pav
[15:41] <dvl> third time works
[15:42] <laemodost> Ping timeout.
[15:43] <dvl> yueah
[15:49] <Pav> dvl: hey hey.. been afk
[15:49] <dvl> me too
[15:49] <Pav> dvl: I noticed freshports don’t have descriptions for virtual categories.
[15:49] <Pav> dvl: you can parse them easily from www/en/ports/categories, if you want
[15:49] <dvl> Pav: Yes, I recall writing about it, but never working on it.
[15:49] <Pav> take it as a little improvement idea from me :)
[15:49] <dvl> let’s check the phorum
[15:49] <Pav> oh! okay then
[15:51] <dvl> Pav: http://news.freshports.org/2006/07/19/virtual-categories-have-no-descriptions/
[15:54] <Pav> dvl: great… so, when is it arriving to production?
[15:54] <dvl> NFI
[15:56] <dvl> well, that script works!
Nearly two hours later, I figured out how to use what Anton Berezin sent me many months ago;. The resulting script appears below, along with the output.
This leaves just five categories without descriptions:
freshports.org=# select name, description from categories where description like 'This%' order by name; name | description ----------+---------------------------------------------------------- offix | This is a virtual category. No description is available. paralell | This is a virtual category. No description is available. perl | This is a virtual category. No description is available. php | This is a virtual category. No description is available. tk42 | This is a virtual category. No description is available. (5 rows) freshports.org=#
The code appears below, along with the output. Hopefully I’ll be able to run this on production soon, and automate it.
#! /usr/bin/perl
#use 5.006;
use warnings;
use strict;
use category;
use DBI;
use database;
use utilities;
use constants;
my $dbh;
my $sql;
my $sth;
my @row;
use Text::CSV_XS;  # textproc/p5-Text-CSV_XS
# = for testing
use Data::Dumper;
FreshPorts::Utilities::InitSyslog();
$dbh = FreshPorts::Database::GetDBHandle();
my @Categories = parse_categories(shift);
#print Dumper [@Categories];
# = end of test
update_each_category($dbh, @Categories);
$dbh->commit();
$dbh->disconnect();
sub update_each_category
{
  my $dbh        = shift;
  my @Categories = @_;
  my $category = FreshPorts::Category->new($dbh);
  foreach my $value (@Categories) {
#    print $value->{category} . "\n";
    $category->{name} = $value->{category};
    $category->{id}   = 0;
    if ($category->FetchByName()) {
#      print $category->{name} . ": old: " . $category->{description} . " new: ".
#      $value->{description}. "\n";
      $category->{description} = $value->{description};
      $category->save();
    } else {
      FreshPorts::Utilities::ReportError('err', "Could not find category " . $value->{category}, 1);
    }
  }
}
# Input:  filename
# Output: an array of hashes representing categories,
#         each hash having fields named "category",
#         "description", and "class"
sub parse_categories
{
   my ($fn) = @_;
   open my $fh, "<", $fn or die "cannot open $fn: $!n";
   my $csv = Text::CSV_XS->new();
   my @r;
   while (<$fh>)
   {
      chomp;
      next if /^s*#/;
      next if /^s*$/;
      if ($csv->parse($_)) {
         my @c = $csv->fields;
         if (@c != 3) {
            warn "oops, got " . scalar(@c) . " fields at line $. while expecting 3n";
            next;
         }
         push @r, {
            category    => $c[0],
            description => $c[1],
            class       => $c[2],
         };
      } else {
         warn "oops, cannot parse line $.n";
      }
   }
   close $fh;
   return @r;
}











