[Rt-commit] r2793 - in rtfm/branches/2.1-TESTING: . sbin

jesse at bestpractical.com jesse at bestpractical.com
Wed Apr 20 23:26:39 EDT 2005


Author: jesse
Date: Wed Apr 20 23:26:38 2005
New Revision: 2793

Added:
   rtfm/branches/2.1-TESTING/sbin/migrate-2.0-to-2.1
Modified:
   rtfm/branches/2.1-TESTING/   (props changed)
   rtfm/branches/2.1-TESTING/README
Log:
 r14000 at hualien:  jesse | 2005-04-20 23:19:54 -0400
 Added the 2.0 to 2.2 migration tool
 


Modified: rtfm/branches/2.1-TESTING/README
==============================================================================
--- rtfm/branches/2.1-TESTING/README	(original)
+++ rtfm/branches/2.1-TESTING/README	Wed Apr 20 23:26:38 2005
@@ -1,24 +1,8 @@
-# BEGIN LICENSE BLOCK
-# 
-#  Copyright (c) 2002-2003 Jesse Vincent <jesse at bestpractical.com>
-#  
-#  This program is free software; you can redistribute it and/or modify
-#  it under the terms of version 2 of the GNU General Public License 
-#  as published by the Free Software Foundation.
-# 
-#  A copy of that license should have arrived with this
-#  software, but in any event can be snarfed from www.gnu.org.
-# 
-#  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.
-# 
-# END LICENSE BLOCK
-
 RTFM (The RT FAQ Manager) is a tool for maintaining an organizational
-knowledgebase. Out of the box, it integrates with RT 3.0 (Also available 
-from bestpractical.com) Best Practical sells support and customization for RT
+knowledgebase. Out of the box, it integrates with RT 3.4 (Also available 
+from bestpractical.com) 
+
+Best Practical sells support and customization for RT
 and RTFM.  Feel free to contact us at sales at bestpractical.com if you have
 any questions about our service offerings.
 
@@ -34,14 +18,14 @@
     perl -MCPAN -e'install HTML::Format'
 
 
-Upgrade instructions (From an earlier 2.0.x release):
+Upgrade instructions (From any  2.0.x release):
 -----------------------------------------------------
 
-1) Edit RTFM's Makefile to point to your RT 3 instance
+1) perl Makefile.PL
 
-2) make sure that mysql or pgsql's commandline tool is in your path
+2) perl -I/path/to/your/rt/lib sbin/migrate-2.0-to-2.1
 
-3) Type "make upgrade"
+3) Type "make install"
 
 4) Type "ls etc/upgrade"; For each item in that directory whose name
    is greater than your previously installed RT version, run:
@@ -59,16 +43,16 @@
 Installation instructions:
 --------------------------
 
-1) Install RT 3.0.5 or newer
+1) Install RT 3.4.2 or newer
 
-2) Once RT 3.0 appears to be happily installed, cd into the directory you
+2) Once RT appears to be happily installed, cd into the directory you
    unpacked RTFM into.
 
-3) Edit RTFM's Makefile to point to your RT 3 instance
+3) perl Makefile.PL
 
-4) make sure that mysql or pgsql's commandline tool is in your path
+4) make install
 
-5) Type "make install"
+5) make initdb
 
 6) stop and start your web server
 
@@ -80,7 +64,7 @@
 some custom fields. You've got five choices. "SelectSingle" and
 "SelectMultiple" let you pick one or many choices from a list respectively.
 "FreeformSingle" and "FreeformMultiple" let you hand-enter one or many lines of
-text. "TextSingle" or "WikiTextSingle"  is what you want for the "Body" of articles. 
+text. "TextSingle" or "WikitextSingle"  is what you want for the "Body" of articles. 
 Once you've created your custom fields, go into your classes and click on "Custom Fields"
 and add the Custom Fields you want to each class.
 

Added: rtfm/branches/2.1-TESTING/sbin/migrate-2.0-to-2.1
==============================================================================
--- (empty file)
+++ rtfm/branches/2.1-TESTING/sbin/migrate-2.0-to-2.1	Wed Apr 20 23:26:38 2005
@@ -0,0 +1,237 @@
+#!/usr/bin/perl
+
+use RT;
+RT::LoadConfig;
+RT::Init;
+use RT::FM::CustomFieldCollection;
+use YAML;
+
+# find each rtfm custom field
+my $cfs = RT::FM::CustomFieldCollection->new($RT::SystemUser);
+$cfs->UnLimit();
+while ( my $cf = $cfs->Next ) {
+    print "Migrating custom field " . $cf->id . ": " . $cf->Name . "\n";
+
+    $cf_data->{ $cf->id } = {
+        id          => $cf->id,
+        Name        => $cf->Name,
+        Type        => $cf->Type,
+        Description => $cf->Description,
+        SortOrder   => $cf->SortOrder
+    };
+
+    # if it has values, find its values
+
+    my $values = $cf->ValuesObj;
+    my @values;
+    while ( my $value = $values->Next ) {
+        print "\t It has a value " . $value->Name . "\n";
+        push @values,
+          {
+            Name        => $value->Name,
+            Description => $value->Description,
+            SortOrder   => $value->SortOrder
+          };
+
+    }
+
+    $cf_data->{ $cf->id }->{values} = \@values;
+
+    # find its acls
+    my $acl = RT::ACL->new($RT::SystemUser);
+    $acl->Limit(
+        FIELD => 'ObjectType',
+        VALUE => 'RT::FM::CustomField',
+    );
+
+    $acl->Limit(
+        FIELD => 'ObjectId',
+        VALUE => $cf->id
+    );
+    my @acl;
+    print "  Migrating access control\n";
+    while ( my $ace = $acl->Next ) {
+        my $item = {
+            ObjectType    => $ace->ObjectType,
+            ObjectId      => $ace->ObjectId,
+            RightName     => $ace->RightName,
+            PrincipalType => $ace->PrincipalType,
+            PrincipalId   => $ace->PrincipalId,
+            DelegatedBy   => $ace->DelegatedBy,
+            DelegatedFrom => $ace->DelegatedFrom,
+            id            => $ace->id
+        };
+
+        push @acl, $item;
+    }
+    $cf_data->{ $cf->id }->{_acl} = \@acl;
+
+    #
+    # find out which classes its tied to
+
+    my $cf_classes = RT::FM::ClassCustomFieldCollection->new($RT::SystemUser);
+    $cf_classes->Limit( FIELD => 'CustomField', VALUE => $cf->id);
+    my @classes;
+    print " It's tied to these classes:\n";
+    while ( my $cfclass = $cf_classes->Next ) {
+        print "\t", $cfclass->ClassObj->Name, "\n";
+        push @classes,
+          { Class => $cfclass->Class, SortOrder => $cfclass->SortOrder };
+
+    }
+
+    $cf_data->{ $cf->id }->{_classes} = \@classes;
+
+    # clone it into core RT
+	my $type =  $cf_data->{$cf->id}{'Type'};
+	$type = 'WikitextSingle' if $type eq 'WikiTextSingle';
+    my $core_cf = RT::CustomField->new($RT::SystemUser);
+    my ( $id, $val ) = $core_cf->Create(
+        Name        => $cf_data->{$cf->id}{'Name'},
+        Type        => $type,
+        Description => $cf_data->{$cf->id}{'Description'},
+        SortOrder   => $cf_data->{$cf->id}{'SortOrder'},
+        LookupType  => 'RT::FM::Class-RT::FM::Article'
+
+    );
+    unless ($core_cf->id) { print "ERROR creating ".$cf->id.": $val ". YAML::Dump($cf_data->{$cf->id}); die;}
+    print " Migrated core custom field.\n";
+
+    # cache old id, new id
+    $cf_data->{$cf->id}->{'newid'} = $core_cf->id;
+
+
+    #
+    # add its values to core RT
+    print " Adding values\n";
+    foreach my $val (@{$cf_data->{ $cf->id }->{values}}) {
+        my ($valid,$valmsg) = $core_cf->AddValue (Name => $val->{'Name'},
+                            Description => $val->{'Description'},
+                            SortOrder => $val->{'SortOrder'}
+                        );
+
+        print "\t",$val->{'Name'},$valmsg , "\n";
+    }   
+    #
+    # add its tied classes to RT
+    print " adding classes\n";
+    foreach my $class (@{$cf_data->{ $cf->id }->{_classes}}) {
+        my   $object_cf = RT::ObjectCustomField->new($RT::SystemUser);
+        my ($ocfid, $ocfmsg) =  $object_cf->Create(CustomField => $cf->id, ObjectId => $class->{'Class'});
+        print "\tClass " . $class->{'Class'} ." ". $ocfmsg ."\n";
+     
+    } 
+        #
+    # add its acls to core RT
+    foreach my $ace (@{$cf_data->{ $cf->id }->{_acl}}) {
+
+
+        my $name = $ace->{'RightName'};
+        $name = 'SeeCustomField' if $name eq 'ShowCustomField';
+        $name = 'AdminCustomField' if $name eq 'ModifyACL';
+        $name = 'AdminCustomField' if $name eq 'ModifyValues';
+        
+            my $newace = RT::ACE->new($RT::SystemUser);
+            
+            my ($cfid, $cfmsg) = $newace->Create( Object => '',
+	    ObjectType    => 'RT::CustomField',
+            ObjectId      => $core_cf->id,
+            RightName     => $name,
+            PrincipalType => $ace->{'PrincipalType'},
+            PrincipalId   => $ace->{'PrincipalId'},
+            DelegatedBy   => $ace->{'DelegatedBy'},
+            DelegatedFrom => $ace->{'DelegatedFrom'},
+            );
+    
+            push (@aces_to_delete,  $ace->{'id'});
+            print " $cfmsg"; 
+        }
+}
+
+# Find all articles
+my $articles = RT::FM::ArticleCollection->new($RT::SystemUser);
+$articles->UnLimit();
+
+#
+#   For each article
+
+print "Importing articles";
+while ( my $article = $articles->Next ) {
+    print "\t Working with article " . $article->Id . "\n";
+
+    #       find its custom fields
+
+    my $cfvs = RT::FM::ArticleCFValueCollection->new($RT::SystemUser);
+    $cfvs->LimitToArticle( $article->id );
+
+    #       for each custom field
+    print "Importing article custom field values\n";
+    while ( my $value = $cfvs->Next ) {
+    #       Add the value to the new custom field (without a txn)
+        my $ocfv = RT::ObjectCustomFieldValue->new($RT::SystemUser);
+    my ($ocid,$ocmsg) =  $ocfv->Create( ObjectType => 'RT::FM::Article',
+                        ObjectId => $value->Article,
+
+            CustomField => $cf_data->{$value->CustomField}->{'newid'},
+            Content => $value->Content );
+
+
+        print " $ocmsg\n";
+    }
+
+    #
+
+}
+
+# record transactions
+#
+my $txns = RT::FM::TransactionCollection->new($RT::SystemUser);
+$txns->UnLimit();
+
+while ( my $txn = $txns->Next ) {
+
+    my $type = $txn->Type;
+    my $field = $txn->Field;
+    my $old_value = $txn->OldContent;
+    my $new_value = $txn->NewContent;
+    my $art = $txn->Article;
+
+
+    if ($type eq 'Link' && $new_value) {
+        $type = 'AddLink';
+    }
+    if ($type eq 'Link' && $old_value) {
+        $type = 'DeleteLink';
+    }
+
+    if ($type eq 'Custom') {
+        $type = 'CustomField';
+        $field = $cf_data->{$field}->{'newid'} || '0';
+    }
+
+    print "\tImporting transaction " . $txn->id . "\n";
+    my $new_txn = RT::Transaction->new($txn->CreatorObj);
+    my ($transid,$transmsg) = $new_txn->Create(
+        ObjectType => 'RT::FM::Article',
+        ObjectId   => $txn->Article,
+        Type => $type,
+        OldValue => $old_value,
+        NewValue => $new_value,
+	ActivateScrips => 0
+      );
+
+        print " $txn_msg\n";
+}
+
+#print YAML::Dump($cf_data);
+#
+#
+#
+# Delete outdated aces;
+#
+print "\nDeleting access control entries from old fields";
+foreach my $ace (@aces_to_delete) {
+    my $ACE = RT::ACE->new($RT::SystemUser);
+    $ACE->Load($ace);
+    $ACE->Delete();
+}


More information about the Rt-commit mailing list