CAD-Firemen

 view release on metacpan or  search on metacpan

bin/fm_create_help  view on Meta::CPAN

#!/usr/bin/perl
######################
#
#    Copyright (C) 2011 - 2015 TU Clausthal, Institut fuer Maschinenwesen, Joachim Langenbach
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    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.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
######################

# Pod::Weaver infos
# PODNAME: fm_create_help
# ABSTRACT: Walks through an installation and tries to extract all options with informations into a database

use strict;
use POSIX;
use warnings;
use Getopt::Long;
use Pod::Usage;
use Archive::Zip qw/ :ERROR_CODES :CONSTANTS/;
use HTML::TreeBuilder;
use IO::HTML;
use XML::LibXML;
use Tie::File;
use Term::ProgressBar;
use DBI;
#use utf8;
use File::Find;
use File::Basename;
use File::Spec;
use CAD::Firemen;
use CAD::Firemen::Common qw(
  getInstallationPath
  getInstallationConfigCdb
  :PRINTING
  strip
  sharedDir
  dbConnect
  buildStatistic
);
use CAD::Firemen::Load qw(loadCDB);
use CAD::Firemen::ParseHelp::Wildfire5 qw(extractHelpWildfire5);
use CAD::Firemen::ParseHelp::Creo3 qw(extractHelpCreo3);


sub localeToLang {
  my $locale = shift;
  if(!defined($locale) || $locale eq ""){
    return "";
  }
  my %languages = ("en_US" => "usascii", "de_DE" => "german");
  if(exists($languages{$locale})){
    return $languages{$locale};
  }
  return "";
}

our $locale = "en_US";
our $zipUrl = "";
our $tocUrl = "";
sub findHelpUrls{
  my $file = $File::Find::name;
  my $regex = "(?:\|/)(?:pma|proe)_help_". substr($locale, 0, 2) .".zip\$";
  if(($zipUrl eq "") && ($file =~ m/$regex/i)){
    $zipUrl = $file;
    testPassed("Found help archive (". $zipUrl .")");
  }
  elsif($tocUrl eq ""){
    $regex = "toc/". $locale .".xml\$";
    if($file =~ m/$regex/i){
      $tocUrl = $file;
      testPassed("Found help toc (". $tocUrl .")");
    }
    else{
      my $language = localeToLang($locale);
      if($language ne ""){
        $regex = "(?:\|/)". $language ."/pma_sx.js\$";
        if(($tocUrl eq "") && ($file =~ m/$regex/i)){
          my ($name, $path, $suffix) = fileparse($file);
          $tocUrl = File::Spec->canonpath( $path ."/../../");
          testPassed("Found help in creo 3 format (". $tocUrl .")");
          $zipUrl = "";
        }
      }
    }
  }
}

my $showVersion = 0;
my $verbose = 0;
my $outputFile = "";
my $crossfire = 0;
my $notepad = 0;
my $dbh = undef;

Getopt::Long::Configure ("bundling", "auto_help");
if(!GetOptions(
  'version' => \$showVersion,
  'verbose|v:i' => \$verbose,
  'output|o:s' => \$outputFile,
  'locale|l:s' => \$locale,
  'crossfire|c' => \$crossfire,
  'notepad|n' => \$notepad
)){
  pod2usage(2);
}

if($showVersion){
  CAD::Firemen::printVersion();
}

my $structUrl = shift;

if(!defined($structUrl)){
  $structUrl = getInstallationPath();
}

if(!defined($structUrl) || $structUrl eq ""){
  pod2usage(2);
}

if($locale !~ m/[a-z]{2}_[A-Z]{2}/){
  print "Please specify a valid locale like en_US\n";
  help();
  exit 1;
}

if($crossfire && $outputFile eq ""){
  print "Please specify an output file with help of --output\n";
  pod2usage(2);
}

if($notepad && !-d $outputFile){
  print "Please specify an existend output directory with help of --output\n";
  pod2usage(2);
}

# get most upper folder (root folder) of creo or proe
my $rootUrl = $structUrl;
$rootUrl =~ s/^(.+(?:creo|proe)[^(?:\\|\/)]+).{0,}/$1/gi;
if(!-d $rootUrl){
  print $rootUrl ."\n";
  testFailed("Extract root Url");
  exit 1;
}

my $cdbUrl = getInstallationConfigCdb($structUrl);
my ($refOptions, $refErrors) = loadCDB($cdbUrl);
my %cdbOptions = %{$refOptions};
my %cdbErrors = %{$refErrors};
if(scalar(keys(%cdbErrors))){
  if($verbose > 0){
    testFailed("Load CDB");
  }
  if($verbose > 1){
    print "Errors while parsing ". $cdbUrl .":\n";
    my @lines = sort { $a <=> $b } keys(%cdbErrors);
    my $max = length($lines[scalar(@lines) - 1]);
    foreach my $line (@lines){
      printColored(sprintf("%". $max ."s", $line) .": ". $cdbErrors{$line} ."\n", "red");
    }
  }
  exit 1;
}

# find files
find(\&findHelpUrls, $rootUrl);
if(!-e $tocUrl){
  testFailed("Found help archive");
  exit 1;
}
if(!-e $zipUrl && $verbose > 1){
  print "Found help in extracted format\n";
}

# extract info for every option
my %optionsInfo = ();
my %optionsValue = ();
my %optionsDefault = ();
my %errors = ();
if($zipUrl ne ""){
    my ($optionsInfoRef, $optionsValueRef, $optionsDefaultRef, $errorsRef) = extractHelpWildfire5($tocUrl, "", \%cdbOptions, $verbose, $zipUrl);
    %optionsInfo = %{$optionsInfoRef};
    %optionsValue = %{$optionsValueRef};
    %optionsDefault = %{$optionsDefaultRef};
    %errors = %{$errorsRef};
}
else{
    my ($optionsInfoRef, $optionsValueRef, $optionsDefaultRef, $errorsRef) = extractHelpCreo3($tocUrl, localeToLang($locale), \%cdbOptions, $verbose);
    %optionsInfo = %{$optionsInfoRef};
    %optionsValue = %{$optionsValueRef};
    %optionsDefault = %{$optionsDefaultRef};
    %errors = %{$errorsRef};
}
my $foundOptionsInHelp = scalar(keys(%optionsInfo));

if(scalar(keys(%errors)) > 0){
  print2ColsRightAligned("Collecting infos ", scalar(keys(%errors)) ." errors", "yellow");
  if($verbose > 0){
    my $max = maxLength(keys(%errors)) + 2;
    foreach my $opt (sort(keys(%errors))){
      print sprintf("%-". $max ."s", $opt .": ") . $errors{$opt} ."\n";
    }
  }
}

if($crossfire){
  # create the output in format of crossfire
  my $CROSS;
  if(!open($CROSS, ">", $outputFile)){
    testFailed("Creating crossfire help");
    exit 1;
  }

  # insert header
  if($structUrl =~ m/^.+((?:creo|proe)[^(?:\\|\/)]+).{0,}/i){
    print $CROSS "#####################################\n";
    print $CROSS "#\n";
    print $CROSS "# For ". $1 ."; Created with CAD::Firemen-". $CAD::Firemen::VERSION ." on ". strftime("%Y-%m-%d", localtime()) ."\n";
    print $CROSS "#\n";
    print $CROSS "#####################################\n";
  }

  # insert all found options into the file
  # we use cdbOptions here as base, to catch also those options, which we have not found at the documentation
  my $max = scalar(keys(%cdbOptions));
  my $progress = Term::ProgressBar->new({name => "Inserting data", count => $max});
  $progress->minor(0);
  my $i = 0;
  foreach my $opt (sort(keys(%cdbOptions))){
    # insert option
    print $CROSS lc($opt) ."\n";

    # insert values
    my @keys = keys(%{$cdbOptions{$opt}});
    if(scalar(@keys) < 1 || !$keys[0]){
        next;
    }
    my $ref = $cdbOptions{$opt}->{$keys[0]};
    if(!defined($ref)){
      next;
    }
    my @values = ();
    foreach my $value (keys(%{$ref})){
      # insert default value hint
      if(exists($optionsDefault{$opt}) && ($value eq $optionsDefault{$opt})){
        $value .= " (default)";
      }
      push(@values, $value);

bin/fm_create_help  view on Meta::CPAN

    my @keys = keys(%{$cdbOptions{$opt}});
    if(scalar(@keys) > 0){
        foreach my $value (keys(%{$cdbOptions{$opt}->{$keys[0]}})){
          if($value eq "( -Fs )"){
            $ignoredFs++;
            last;
          }
        }
    }
  }
  my $countOptionsDefaultValues = $countOptions - $ignoredFs;

  print "\n\n";
  print "Statistics:\n";

  my %statistics = ();
  $statistics{"Options in cdb"} = buildStatistic("Options in cdb", $countOptions, $countOptions);
  $statistics{"Options in Help"} = buildStatistic("Options in Help", $foundOptionsInHelp, $countOptions);
  $statistics{"Default values"} = buildStatistic("Default values", scalar(keys(%optionsDefault)), $countOptionsDefaultValues);
  $statistics{"Descriptions"} = buildStatistic("Descriptions", scalar(keys(%optionsInfo)), $countOptions);

  my $maxLen = maxLength(keys(%statistics)) + 2;
  foreach my $stat (keys(%statistics)){
    print sprintf("%-". $maxLen ."s", $stat) . $statistics{$stat} ."\n";
  }
  print "Ignored ". $ignoredFs ." Options with value -Fs to calculate percentage of Default values\n";
}

END {
  if(defined($dbh) && ($dbh != 0) && !$dbh->disconnect){
    print "Could not disconnect from database!\n";
    print "Error: ". $DBI::errstr;
    exit 1;
  }
}

exit 0;

__END__

=pod

=head1 NAME

fm_create_help - Walks through an installation and tries to extract all options with informations into a database

=head1 VERSION

version 0.7.2

=head1 SYNOPSIS

fm_create_help [options] [PATH_TO_INSTALLATION]

Options:

  --help             -?   Prints this help.
  --version               Prints current version.
  --verbose          -v   The verbose level. 0 - least output, 2 most output (Default: 0).
  --output           -o   Optional filepath to store the created data.
  --locale           -l   The locale which should be used (Default en_US).
  --crossfire        -c   Store the output in the format of Crossfire. Set file with --output.
  --notepad          -n   Create some Notepad++ help files. Set directory with --output.

If no PATH_TO_INSTALLATION is given, it tries to figure out the correct path with help of $ENV{PATH}.

Example:

  fm_create_help

=head1 DESCRIPTION

This script parses a option database (cdb file) and afterwards, it tries
to collect more information with help of the delivered html help. The collected
data is stored in an SQLite Database afterwards. The structure is as shown below.

                                                    |==========================|
                                                    | options_has_values       |
                                                    |==========================|
  |==========================|                      | id INTEGER, PRIMARY KEY  |
  | options                  |                      |--------------------------|
  |==========================|          |---------->| optionsId INTEGER        |
  | id INTEGER, PRIMARY KEY  | ---------|           |--------------------------|
  |--------------------------|                |---->| valuesId INTEGER         |
  | name VARCHAR(250)        |                |     |==========================|
  |--------------------------|                |
  | defaultValueId INTEGER   |<---------------|
  |--------------------------|                |     |==========================|
  | description TEXT         |                |     | options_values           |
  |==========================|                |     |==========================|
                                              ------| id INTEGER, PRIMARY KEY  |
                                                    |--------------------------|
                                                    | name VARCHAR(250)        |
                                                    |==========================|

It can also create help files for Crossfire (see option --crossfire) or a user
defined language (udl) with auto completion for use with Notepad++ (--notepad).
The last command creates to files. One file is the auto completion file, which
should be copied into the plugins\APIs folder within your Notepad++ directory.
The other file, with a name ending with -udl, is the definition of the udl. To
import this file, start Notepad++ and choose Import in the udl dialog,
which can be found within the View menu. After next restart of Notepad++, you can
use the auto completion and syntax highlighting for your configuration files after
choosing the new udl at the language menu.

=head1 AUTHOR

Joachim Langenbach <langenbach@imw.tu-clausthal.de>

=head1 COPYRIGHT AND LICENSE

This software is Copyright (c) 2015 by TU Clausthal, Institut fuer Maschinenwesen.

This is free software, licensed under:

  The GNU General Public License, Version 2, June 1991

=cut



( run in 0.917 second using v1.01-cache-2.11-cpan-ceb78f64989 )