# ================================================================== # Gossamer Forum - Advanced web community # # Website : http://gossamer-threads.com/ # Support : http://gossamer-threads.com/scripts/support/ # Revision : $Id: UBB5.pm,v 1.7 2002/01/15 06:06:03 adrian Exp $ # # Copyright (c) 2001 Gossamer Threads Inc. All Rights Reserved. # Redistribution in part or in whole strictly prohibited. Please # see LICENSE file for full details. # ================================================================== package GForum::Import::UBB5; BEGIN { local $@; eval { require Time::HiRes; import Time::HiRes qw/time/; }; } use strict; use GForum qw/:user $DB $CFG/; use vars qw/@ISA $MembersPath $VariablesPath $NonCGIPath $CGIPath $BBName $EditOption/; use GForum::Import::UBB; use GForum::ContentType; use GT::Dumper; use GT::Date; @ISA = qw/GForum::Import::UBB/; sub new { my $class = shift; my $self = GForum::Import::UBB->new(@_); return bless($self, $class); } sub read_conf { my $start_time = time; my $self = shift; my $conf; if (-f $self->{source} . '/UltBB.setup') { $conf = $self->{source} . '/UltBB.setup'; } elsif (-f $self->{source} . '/cgi-bin/UltBB.setup') { $conf = $self->{source} . '/cgi-bin/UltBB.setup'; } else { $self->{error} = 'Cannot locate UBB configuration file (UltBB.setup).'; return 0; } $self->debug("Reading UBB configuration from: $conf", 1); local ($!, $@); if (!do "$conf") { $self->{error} = "Unable to load UBB configuration file $conf: " . ("$!" || $@); return 0; } $self->{member_path} = $MembersPath; $self->{vars_path} = $VariablesPath; $self->{noncgi_path} = $NonCGIPath; $self->{cgi_path} = $CGIPath; $self->{site_title} = $BBName; $self->debug("UBB User data path: $self->{member_path}\n", 1); $self->debug("UBB configuration path: $self->{vars_path}\n", 1); $self->debug("UBB non-cgi path: $self->{noncgi_path}\n", 1); $self->debug("UBB cgi path: $self->{cgi_path}\n", 1); if ((!defined $self->{member_path}) || (!defined $self->{vars_path}) || (!defined $self->{noncgi_path}) || (!defined $self->{cgi_path})) { $self->{error} = "Your UBB configuration file, vars_config.cgi, is missing data."; return 0; } # Read UBB version info. # see ubb_lib.cgi ($version) # Probably should do a check for version 5.x # No User Title info to import. $self->{post_allow_user_edit} = (lc($EditOption) eq 'off') ? '0' : '1'; my $run_time = time - $start_time; printf ("(%.2fs) ", $run_time) if ($run_time >= 1); return 1; } sub close_forums { my $start_time = time; my $self = shift; # Close GForum. $CFG->{disabled} = 1; $CFG->{disabled_message} = 'Import in progress. The forum is unavailable until the import is completed successfully.'; $CFG->save(); # Close UBB. my $conf; if (-f $self->{source} . '/UltBB.setup') { $conf = $self->{source} . '/UltBB.setup'; } elsif (-f $self->{source} . '/cgi-bin/UltBB.setup') { $conf = $self->{source} . '/cgi-bin/UltBB.setup'; } else { $self->{error} = 'Cannot locate UBB configuration file (UltBB.setup).'; return 0; } open (CONF, "+< $conf") or $self->{error} = "Unable to load UBB configuration file $conf: " . ("$!" || $@), return 0; my $out = ''; while () { s/^(\$BBStatus\s*=\s*).*;^/${1}qq(OFF);/gi; s/^(\$BBClosedMessage\s*=\s*).*;^/${1}qq(Import in progress. The forum is unavailable until the import is completed successfully.");/gi; $out .= $_; } seek (CONF, 0, 0) or $self->{error} = "Unable to seek to start of $conf: " . ("$!" || $@), return 0; print CONF $out or $self->{error} = "Unable to print to $conf: " . ("$!" || $@), return 0; truncate (CONF, tell (CONF)) or $self->{error} = "Unable to truncate $conf: " . ("$!" || $@), return 0; close (CONF); my $run_time = time - $start_time; printf ("(%.2fs) ", $run_time) if ($run_time >= 1); return 1; } sub open_forums { my $start_time = time; my $self = shift; # Open GForum. $CFG->{disabled} = 0; $CFG->save(); # Open UBB. my $conf; if (-f $self->{source} . '/UltBB.setup') { $conf = $self->{source} . '/UltBB.setup'; } elsif (-f $self->{source} . '/cgi-bin/UltBB.setup') { $conf = $self->{source} . '/cgi-bin/UltBB.setup'; } else { $self->{error} = 'Cannot locate UBB configuration file (UltBB.setup).'; return 0; } open (CONF, "+< $conf") or $self->{error} = "Unable to load UBB configuration file $conf: " . ("$!" || $@), return 0; my $out = ''; while () { s/^(\$BBStatus\s*=\s*).*;^/${1}qq(ON);/gi; $out .= $_; } seek (CONF, 0, 0) or $self->{error} = "Unable to seek to start of $conf: " . ("$!" || $@), return 0; print CONF $out or $self->{error} = "Unable to print to $conf: " . ("$!" || $@), return 0; truncate (CONF, tell (CONF)) or $self->{error} = "Unable to truncate $conf: " . ("$!" || $@), return 0; close (CONF); my $run_time = time - $start_time; printf ("(%.2fs) ", $run_time) if ($run_time >= 1); return 1; } sub import_users { my $self = shift; my $return = $self->SUPER::import_users(); # UBB5 uses Username's in the relation fields instead of ID's like in UBB6. # Convert the $self->{users} to reflect this. my $users = delete $self->{users}; $self->{users} = {}; foreach my $uid (keys %{$users}) { $self->{users}{lc($users->{$uid}{username})} = $users->{$uid}; } foreach my $key (keys %{$self->{users}}) { if (!exists $self->{users}{$key}{username}) { delete $self->{users}{$key}; } } my $users_not_added = delete $self->{users_not_added}; $self->{users_not_added} = {}; foreach my $uid (keys %{$users_not_added}) { $self->{users_not_added}{lc($users_not_added->{$uid}{username})} = $users_not_added->{$uid}; } my $administrators = delete $self->{administrators}; $self->{administrators} = {}; foreach my $uid (keys %{$administrators}) { $self->{administrators}{lc($users->{$uid}{username})} = $administrators->{$uid}; } my $registered = delete $self->{registered}; $self->{registered} = {}; foreach my $uid (keys %{$registered}) { $self->{registered}{lc($self->{users}{$uid}{username})} = $registered->{$uid}; } $self->debug('UBB Username => { id => GForum user_id, permissions => Forum Permissions, username => username }:', 2); $self->debug(Dumper($self->{users}), 2); $self->debug('Imported UBB Administrators:', 2); $self->debug(Dumper($self->{administrators}), 2); $self->debug('Imported UBB Registered Users (Currently includes Moderators):', 2); $self->debug(Dumper($self->{registered}), 2); $self->debug('Duplicate/Invalid users that have NOT been added:', 2); $self->debug(Dumper($self->{users_not_added}), 2); return $return; } sub import_forums { my $start_time = time; my $self = shift; my $forum_table = $DB->table('Forum'); # This stuff is for showing progress of import. my $total = 0; # Total number of records. my $curr_rec = 1; # Current record #. my $dots = -1; # 'Dot' count :) my $forum_file = $self->{cgi_path} . "/forums.cgi"; open (FORUMS, "< $forum_file") or $self->{error} = "Unable to load UBB forums $forum_file: " . ("$!" || $@), return 0; my @forums = ; close FORUMS; $total = scalar(@forums); foreach (@forums) { # This stuff is for showing progress of import. $dots = $self->show_progress($total, $curr_rec, $dots); $curr_rec++; chomp; my ($cat_id, $forum_title, $forum_desc, $forum_status, $html_allowed, $ubb_code_allowed, $permissions, $dir_pass, $forum_id, $_unknown_, $images_allowed, $mod_notify, $forum_password, $private_forum, $forum_sort_order, $sort_topics_by, $announcement) = split(/\|/); next if (!$forum_title or !$forum_id); my $gf_row = {}; $gf_row->{forum_sort_rank} = int($forum_sort_order); $gf_row->{forum_name} = $forum_title; $gf_row->{forum_desc} = $forum_desc; if ((lc($html_allowed) eq 'is') && (lc($ubb_code_allowed) eq 'is')) { $gf_row->{forum_style} = 3; # Forum Markup and HTML allowed. } elsif (lc($html_allowed) eq 'is') { $gf_row->{forum_style} = 2; # HTML and plain text only. } elsif (lc($ubb_code_allowed) eq 'is') { $gf_row->{forum_style} = 1; # Forum Markup and plain text only. } else { $gf_row->{forum_style} = 0; # Plain text only. } # Convert UBB category ID to GForum's ID. if (!$cat_id) { $cat_id = 0; } $gf_row->{cat_id_fk} = $self->{categories}{$cat_id}; # Turn off attachments by default. $gf_row->{forum_allow_attachments} = 0; $gf_row->{forum_allow_guest_attachments} = 0; $gf_row->{forum_allow_user_edit} = $self->{post_allow_user_edit}; $gf_row->{forum_edit_timeout} = 0; # Check to see if there is already a forum that's in the same category. if ($forum_table->count({ forum_name => $gf_row->{forum_name}, cat_id_fk => $gf_row->{cat_id_fk} }) > 0) { my $forum_data = $forum_table->select('forum_id', 'forum_style', { forum_name => $gf_row->{forum_name}, cat_id_fk => $gf_row->{cat_id_fk} })->fetchrow_arrayref(); $self->{forums}{$forum_id}{id} = $forum_data->[0]; $self->{forums}{$forum_id}{style} = $forum_data->[1]; $self->{forums}{$forum_id}{dir_pass} = $dir_pass; $self->{forums}{$forum_id}{permissions} = $permissions; $self->{forums}{$forum_id}{title} = $forum_title; next; } # Grab forum_last from file. my $forum_last; if (length($dir_pass)) { $forum_last = $self->{noncgi_path} . "/Forum" . int($forum_id) . "/private-$dir_pass/lasttime.file"; } else { $forum_last = $self->{noncgi_path} . "/Forum" . int($forum_id) . "/lasttime.file"; } if (-f $forum_last and -r _) { open (FORUM_LAST, "< $forum_last") or $self->{error} = "Unable to load UBB forum last file $forum_last: " . ("$!" || $@), return 0; my @last = ; close FORUM_LAST; chomp (@last); $gf_row->{forum_last} = GT::Date::timelocal(GT::Date::_parse_format("$last[0] $last[1]", '%mm%-%dd%-%yyyy% %hh%:%MM% %tt%')); } $self->debug('Imported Forum data:', 3); $self->debug(Dumper($gf_row), 3); my $sth = $forum_table->insert($gf_row) or $self->{error} = "Fatal Error: ($GT::SQL::errcode) $GT::SQL::error", return 0; $self->{forums}{$forum_id}{id} = $sth->insert_id(); $self->{forums}{$forum_id}{style} = $gf_row->{forum_style}; $self->{forums}{$forum_id}{permissions} = $permissions; $self->{forums}{$forum_id}{dir_pass} = $dir_pass; $self->{forums}{$forum_id}{title} = $forum_title; } $self->debug('UBB Forum ID => { id => GForum forum_id, style => GForum forum_style, permissions => UBB Permissions }:', 2); $self->debug(Dumper($self->{forums}), 2); # Check to see if the special category was used. If not, delete it. if ($forum_table->count({ cat_id_fk => $self->{categories}{0} }) == 0) { $DB->table('Category')->delete({ cat_id => $self->{categories}{0} }); } my $run_time = time - $start_time; printf ("(%.2fs) ", $run_time) if ($run_time >= 1); return 1; } sub import_moderators { my $start_time = time; my $self = shift; my $moderator_table = $DB->table('ForumModerator'); my $conf; if (-f $self->{cgi_path} . '/mods.file') { $conf = $self->{cgi_path} . '/mods.file'; } else { $self->{error} = 'Cannot locate UBB moderator file (mods.file).'; return 0; } local ($!, $@); if (!do "$conf") { $self->{error} = "Unable to load UBB moderator file $conf: " . ("$!" || $@); return 0; } # Loop through all the forums. foreach my $forum_id (keys %{$self->{forums}}) { # Let us use variable variables. no strict "refs"; my $var = "Forum${forum_id}Moderator"; # See if we have any moderators for this forum. if (defined(${$var})) { my $forum_mods = ${$var}; foreach my $username (split(/\|\|\^\|\|/, $forum_mods)) { # Don't add a Moderator entry if they are a duplicate/deleted user. # Don't make administrators moderators in GForum since administrators already have moderator privilleges. if ((exists $self->{users_not_added}{lc($username)}) || (exists $self->{administrators}{lc($username)})) { next; } my $gf_row = {}; $gf_row->{forum_id_fk} = $self->{forums}{$forum_id}{id}; $gf_row->{user_id_fk} = $self->{users}{lc($username)}{id}; # If somehow the user or forum does not exist... if ((!defined $gf_row->{forum_id_fk}) || (!defined $gf_row->{user_id_fk})) { next; } $gf_row->{mod_time} = int(time); # Check to see if they're already a moderator for this forum. if ($moderator_table->count({ forum_id_fk => $gf_row->{forum_id_fk}, user_id_fk => $gf_row->{user_id_fk} }) < 1) { $self->debug('Imported ForumModerator data:', 3); $self->debug(Dumper($gf_row), 3); $moderator_table->insert($gf_row) or $self->{error} = "Fatal Error: ($GT::SQL::errcode) $GT::SQL::error", return 0; } # We added moderators as registered users before, now we'll remove them from that list. $self->{moderators}{lc($username)} = delete $self->{registered}{lc($username)} unless exists $self->{moderators}{lc($username)}; } } } $self->debug('Imported UBB Moderators:', 2); $self->debug(Dumper($self->{moderators}), 2); my $run_time = time - $start_time; printf ("(%.2fs) ", $run_time) if ($run_time >= 1); return 1; } sub import_posts { my $start_time = time; my $self = shift; # To keep track of which post we have imported last (in case we resume a failed import), we just use a field of a user (user_rows) to store this ID. my ($last_forum_id, $last_thread_id, $last_post_id); local $CFG->{username_max_length} = 50; if ($DB->table('User')->count({ user_username => 'gossamer_forum_import_temp_user' }) < 1) { # No posts have been imported yet. $DB->table('User')->insert({ user_username => 'gossamer_forum_import_temp_user', user_password => '', user_enabled => '0', user_status => ANONYMOUS, user_title => '0', user_icon => '000000', user_template => '000000'}) or $self->{error} = "Fatal Error: ($GT::SQL::errcode) $GT::SQL::error", return 0; $last_forum_id = 0; $last_thread_id = "000000"; $last_post_id = "000000"; } else { # Resume an import. ($last_forum_id, $last_thread_id, $last_post_id) = $DB->table('User')->select('user_title', 'user_icon', 'user_template', { user_username => 'gossamer_forum_import_temp_user' })->fetchrow_array(); } my $post_table = $DB->table('Post'); # This stuff is for showing progress of import. my $total = 0; # Total number of records. my $curr_rec = 1; # Current record #. my $dots = -1; # 'Dot' count :) my $total_added_posts = 0; # Get the total number of posts. foreach my $forum_id (keys %{$self->{forums}}) { my $forum_path; if (length($self->{forums}{$forum_id}{dir_pass}) and -f "$self->{noncgi_path}/Forum$forum_id/private-$self->{forums}{$forum_id}{dir_pass}/lastnumber.file") { $forum_path = $self->{noncgi_path} . "/Forum" . $forum_id . "/private-$self->{forums}{$forum_id}{dir_pass}"; } else { $forum_path = $self->{noncgi_path} . "/Forum" . $forum_id; } # Get the total number of posts in the forum. if (-f "$forum_path/lastnumber.file" and -r _) { open (TOTAL, "< $forum_path/lastnumber.file"); my @total = ; close TOTAL; $total += int($total[2]); } } FORUM: foreach my $forum_id (sort {$a <=> $b} keys %{$self->{forums}}) { # Skip the forum if it's not in the forum list. next FORUM if !exists $self->{forums}{$forum_id}; next FORUM if $forum_id < $last_forum_id; # Update the last thread which was imported. $DB->table('User')->update({ user_title => $forum_id, user_icon => "000000", user_template => "000000" }, { user_username => 'gossamer_forum_import_temp_user' }) or $self->{error} = "Fatal Error: ($GT::SQL::errcode) $GT::SQL::error", return 0; $last_forum_id = 0; my $forum_path; if (length($self->{forums}{$forum_id}{dir_pass}) and -f "$self->{noncgi_path}/Forum$forum_id/private-$self->{forums}{$forum_id}{dir_pass}/forum_$forum_id.threads") { $forum_path = $self->{noncgi_path} . "/Forum" . $forum_id . "/private-$self->{forums}{$forum_id}{dir_pass}"; } else { $forum_path = $self->{noncgi_path} . "/Forum" . $forum_id; } # Get the list of threads. my $file = "$forum_path/forum$forum_id.threads"; open (THREADS, "< $file") or $self->{error} = "Unable to load UBB threads file $file: " . ("$!" || $@), return 0; my @thread_ids; while () { my @thread = split(/\|\^\|/); if ($thread[1]) { push (@thread_ids, $thread[1]); } } close THREADS; # Go through the threads. THREAD: foreach my $thread_id (@thread_ids) { next THREAD if int $thread_id < int $last_thread_id; # Update the last thread which was imported. $DB->table('User')->update({ user_icon => $thread_id, user_template => "000000" }, { user_username => 'gossamer_forum_import_temp_user' }) or $self->{error} = "Fatal Error: ($GT::SQL::errcode) $GT::SQL::error", return 0; $last_thread_id = "000000"; my $thread_file = "$forum_path/$thread_id.cgi"; open (THREAD, "< $thread_file") or $self->{error} = "Unable to load UBB thread $thread_file: " . ("$!" || $@), return 0; my @thread = ; close THREAD; my $thread_locked = 0; my $subject = ""; POST: for my $i (0 .. $#thread) { my $line = $thread[$i]; if ($i == 0) { my @info = split(/\|\|/, $line); if (lc $info[1] eq 'x') { $thread_locked = 1; } $subject = $info[4]; # Don't add threads which have no subject; if (!length($subject)) { $self->{posts_not_added}{"${forum_id}-${thread_id}"} = 'Thread has no subject'; next THREAD; } next POST; } my ($nothing, $post_id, $username, $date, $time, $email, $body, $ip, $status, $icon_id, $disp_name, $user_id, $signature) = split(/\|\|/, $line); next POST if (!defined $post_id || !length($post_id)); # Don't do anything with this post if it's already been imported. next POST if (($post_id ne "000000") && (int $post_id <= int $last_post_id)); $last_post_id = "000000"; # This stuff is for showing progress of import. $dots = $self->show_progress($total, $curr_rec, $dots); $curr_rec++; # Don't add deleted posts or posts which have no root or fathers. if (!length($body)) { $self->{posts_not_added}{"${forum_id}-${thread_id}-${post_id}"} = 'Post has no body'; next POST; } if ($post_id ne "000000" && exists $self->{posts_not_added}{"${forum_id}-${thread_id}-000000"}) { $self->{posts_not_added}{"${forum_id}-${thread_id}-${post_id}"} = 'Root post has not been added'; next POST; } my $gf_row = {}; $gf_row->{user_id_fk} = defined $self->{users}{lc($username)} ? $self->{users}{lc($username)}{id} : 0; $gf_row->{forum_id_fk} = $self->{forums}{$forum_id}{id}; $gf_row->{post_root_id} = $self->{posts}{"${forum_id}-${thread_id}-000000"} || 0; $gf_row->{post_father_id} = $self->{posts}{"${forum_id}-${thread_id}-000000"} || 0; $gf_row->{post_username} = $username; # Older UBB used a 2 digit year. if (length($date) == 10) { $gf_row->{post_time} = GT::Date::timelocal(GT::Date::_parse_format("$date $time", '%mm%-%dd%-%yyyy% %hh%:%MM% %tt%')); } else { $gf_row->{post_time} = GT::Date::timelocal(GT::Date::_parse_format("$date $time", '%mm%-%dd%-%yy% %hh%:%MM% %tt%')); } $gf_row->{post_subject} = html_unescape($subject); $gf_row->{post_message} = html_unescape($body); # UBB includes last edited info in the post itself. while ($gf_row->{post_message} =~ s|

\[This message has been edited by (.*?) \(edited (.*)\)\.\]||gis) { $gf_row->{post_last_edit_username} = $1; $gf_row->{post_last_edit_time} = GT::Date::timelocal(GT::Date::_parse_format($2, '%mm%-%dd%-%yyyy%')); } # Append signature if needed. if (lc $signature eq 'yes') { $gf_row->{post_message} .= "\n[signature]"; } $gf_row->{post_ip} = $ip; if ($post_id eq '000000') { $gf_row->{post_locked} = (lc $thread_locked eq 'x') ? 1 : 0; $gf_row->{post_thread_views} = 0; $gf_row->{post_depth} = 0; } else { $gf_row->{post_locked} = 0; $gf_row->{post_thread_views} = undef; $gf_row->{post_depth} = 1; } # Anonymous post. if (lc $status eq 'unreg') { # Check to see if we already know of an anonymous user we can use. if (!$self->{anonymous}{id}) { if ($DB->table('User')->count({ user_status => ANONYMOUS, user_enabled => '1' }) < 1) { # No anonymous users exist. Create one. # Just in case there's already users with a username of Anonymous... my $anon_username = 'Anonymous'; my $anon_count = 2; while ($DB->table('User')->count({ user_username => $anon_username }) > 0) { $anon_username = "Anonymous$anon_count"; $anon_count++; } # Found a suitable username, create this user. my $sth = $DB->table('User')->insert({ user_username => $anon_username, user_password => '', user_enabled => '1', user_status => ANONYMOUS, user_title => 'Anonymous' }) or $self->{error} = "Fatal Error: ($GT::SQL::errcode) $GT::SQL::error", return 0; $self->{anonymous}{id} = $sth->insert_id(); $self->{anonymous}{username} = $anon_username; } else { my $row = $DB->table('User')->select('user_id', 'user_username', { user_status => ANONYMOUS, user_enabled => '1' })->fetchrow_arrayref(); $self->{anonymous}{id} = $row->[0]; $self->{anonymous}{username} = $row->[1]; } } # UBB allows anonymous users to choose their own usernames to be displayed. Don't need that. $gf_row->{post_username} = $self->{anonymous}{username}; $gf_row->{user_id_fk} = $self->{anonymous}{id}; } # Since duplicate users are not added, we'll count them as deleted. if (exists $self->{users_not_added}{lc($username)}) { $gf_row->{post_signature_deleted} = $self->{users_not_added}{lc($username)}{signature}; } elsif (not defined $gf_row->{user_id_fk}) { # These users have no user record, but have been deleted with their posts still remaining (ie. deleted before import). $gf_row->{post_signature_deleted} = ''; # Check to see if for some reason the username field is not set... if ((not defined $gf_row->{post_username}) or ($gf_row->{post_username} eq '')) { $self->{posts_not_added}{"${forum_id}-${thread_id}-${post_id}"} = 'Username could not be found for deleted user'; next POST; } } # UBB does not store # of views. $gf_row->{post_views} = 0; chomp $gf_row->{post_subject}; chomp $gf_row->{post_message}; # UBB stores all the messages as HTML, GForum on the other hand stores the messages as they were input (Markup or HTML or plain text). # So if the forum only allows Markup (style = 1), then convert the HTML back to markup. my $forum_style = $self->{forums}{$forum_id}{style}; if ($forum_style) { if ($forum_style == 0) { # Only plain text allowed. $gf_row->{post_message} = html_to_text($gf_row->{post_message}); $gf_row->{post_style} = 0; } elsif ($forum_style == 1) { # Only Markup and plain text allowed. $gf_row->{post_message} = html_to_markup($gf_row->{post_message}); $gf_row->{post_style} = 1; } elsif ($forum_style == 2) { # Only HTML allowed. No need to convert anything. $gf_row->{post_style} = 2; } elsif ($forum_style == 3) { # Forum Markup and HTML are allowed, so we'll convert any markup tags that may have been used. $gf_row->{post_message} = html_to_html_markup($gf_row->{post_message}); $gf_row->{post_style} = 3; } } # Set post_ip to 0.0.0.0 if no ip has been saved. $gf_row->{post_ip} = '0.0.0.0' if not $gf_row->{post_ip}; # Special column to make GForum not update the forum_last column in the Forum table. $gf_row->{no_update_forum_last} = 1; $gf_row->{post_latest_poster} = $gf_row->{post_username}; # For some reason, some posts/subjects have a null character in them, which can screw things up. Remove them. $gf_row->{post_subject} =~ s/\0//g; $gf_row->{post_message} =~ s/\0//g; $self->debug('Imported Post data:', 3); $self->debug(Dumper($gf_row), 3); my $sth = $post_table->insert($gf_row) or $self->{error} = "Fatal Error: ($GT::SQL::errcode) $GT::SQL::error", return 0; $self->{posts}{"${forum_id}-${thread_id}-${post_id}"} = $sth->insert_id(); # Update the last post which was imported. $DB->table('User')->update({ user_template => $post_id }, { user_username => 'gossamer_forum_import_temp_user' }) or $self->{error} = "Fatal Error: ($GT::SQL::errcode) $GT::SQL::error", return 0; } } } # Get a list of all the forum id's, and update the forum_latest_poster, etc entries for the forums. my @forum_ids = $DB->table('Forum')->select('forum_id')->fetchall_list(); $DB->table('Forum')->rebuild_latest(@forum_ids); # Done with the temp user, delete the user. $DB->table('User')->delete({ user_username => 'gossamer_forum_import_temp_user' }); my $run_time = time - $start_time; printf ("(%.2fs) ", $run_time) if ($run_time >= 1); return 1; } sub import_messages { # UBB does not support messages. Nothing to do here... return 1; } sub import_message_attachments { # UBB does not support attachments. Nothing to do here... return 1; } sub post_import { return 1; } sub html_to_markup { my $message = shift; return if not defined $message; # Bold, Italic, and Underline (although WWWThreads doesn't have underline). $message =~ s#<(/?)(b|i|u)>#[$1$2]#gi; $message =~ s#<(/?)strong>#[$1b]#gi; # Convert smiley's. $message =~ s#]*>#[$1]#gis; # Convert colour codes. # $message =~ s#<(/?)font color=(red|green|blue|orange|purple|black|white|yellow)>#[$1$2]#gis; # Convert quote. $message =~ s#

]*>quote:
(.*?)
#[quote]$1\[/quote]#gis; # Convert code. $message =~ s#
]*>code:
(.*?)

#[code]$1\[/code]#gis; # Convert pre. $message =~ s#
(.*?)

#[pre]$1\[/pre]#gis; # Convert URL's. $message =~ s#]*>(?:http|https|ftp)://.*?#[url]$1\[/url]#gis; $message =~ s#]*>(.*?)#[url "$1"]$2\[/url]#gis; # Convert mailto. $message =~ s#(.*?)#[email]$1\[/email]#gis; # Convert image. $message =~ s##[image]$1\[/image]#gis; # Convert
's and

's. $message =~ s#]*>#\n#gi; $message =~ s#]*>#\n\n#gi; $message =~ s#

##gi; # Convert lists. $message =~ s#]*>(.*?)#[ul]$1\[/ul]#gis; $message =~ s#]*>(.*?)#[ol]$1\[/ol]#gis; $message =~ s#]*>#[li]#gis; # HTML unescape. $message = html_unescape($message); return $message; } sub html_to_text { my $message = shift; return if not defined $message; my $hr = ('-' x 60); $message =~ s# # #ig; $message =~ s#\s+# #g; $message =~ s###gs; $message =~ s#
  • \s*(.*?)\s*
  • #\n* $1\n#gis; $message =~ s#
  • \s*([^<]*)#\n* $1#gis; $message =~ s#]*>#\n\n#gi; $message =~ s#]*>#\n#gi; $message =~ s##\n#gi; $message =~ s#([^<]*)#*$1*#gi; $message =~ s#([^<]*)#_$1_#gi; $message =~ s#([^<]*)#/$1/#gi; $message =~ s#]*>#\n\n#gi; $message =~ s#]*>#\n$hr\n#gi; my @tokens = split /(<[^>"']*(?:(?:(?:"[^"]*"[^>"]*)|(?:'[^']*'[^>']*)))*>)/, $message; $message = join '' => map { $tokens[$_] } grep { not $_ % 2 } 0 .. $#tokens; $message =~ s#^[ \t]+##gm; $message =~ s#[ \t]+$##gm; $message = html_unescape($message); return $message; } sub html_to_html_markup { my $message = shift; return if not defined $message; # Convert smiley's. $message =~ s#]*>#[$1]#gis; return $message; } sub html_unescape { my $message = shift; return if not defined $message; $message =~ s/<//g; $message =~ s/"/"/g; $message =~ s/ / /g; $message =~ s/Ѐ/|/g; $message =~ s/&/&/g; return $message; } 1;