You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
266 lines
8.1 KiB
266 lines
8.1 KiB
package AN::Tools::Words; |
|
# |
|
# This module contains methods used to handle storage related tasks |
|
# |
|
|
|
use strict; |
|
use warnings; |
|
use Data::Dumper; |
|
use XML::Simple qw(:strict); |
|
|
|
our $VERSION = "3.0.0"; |
|
my $THIS_FILE = "Words.pm"; |
|
|
|
# Setup for UTF-8 mode. |
|
# use utf8; |
|
# $ENV{'PERL_UNICODE'} = 1; |
|
|
|
### Methods; |
|
# key |
|
# read |
|
|
|
=pod |
|
|
|
=encoding utf8 |
|
|
|
=head1 NAME |
|
|
|
AN::Tools::Words |
|
|
|
Provides all methods related to generating translated strings for users. |
|
|
|
=head1 SYNOPSIS |
|
|
|
use AN::Tools::Words; |
|
|
|
# Get a common object handle on all AN::Tools modules. |
|
my $an = AN::Tools->new(); |
|
|
|
# Access to methods using '$an->Words->X'. |
|
# |
|
# Example using 'read()'; |
|
my $foo_path = $an->Words->read({file => $an->data->{path}{words}{'an-tools.xml'}}); |
|
|
|
=head1 METHODS |
|
|
|
Methods in this module; |
|
|
|
=cut |
|
sub new |
|
{ |
|
my $class = shift; |
|
my $self = {}; |
|
|
|
bless $self, $class; |
|
|
|
return ($self); |
|
} |
|
|
|
# Get a handle on the AN::Tools object. I know that technically that is a sibling module, but it makes more |
|
# sense in this case to think of it as a parent. |
|
sub parent |
|
{ |
|
my $self = shift; |
|
my $parent = shift; |
|
|
|
$self->{HANDLE}{TOOLS} = $parent if $parent; |
|
|
|
return ($self->{HANDLE}{TOOLS}); |
|
} |
|
|
|
|
|
############################################################################################################# |
|
# Public methods # |
|
############################################################################################################# |
|
|
|
=head2 key |
|
|
|
NOTE: This is likely not the method you want. This method does no parsing at all. It returns the raw string from the 'words' file. You probably want C<< $an->Words->string() >> if you want to inject variables and get a string back ready to display to the user. |
|
|
|
This returns a string by its key name. Optionally, a language and/or a source file can be specified. When no file is specified, loaded files will be search in alphabetical order (including path) and the first match is returned. |
|
|
|
If the requested string is not found, 'C<< #!not_found!# >>' is returned. |
|
|
|
Example to retrieve 'C<< t_0001 >>'; |
|
|
|
my $string = $an->Words->key({key => 't_0001'}); |
|
|
|
Same, but specifying the key from Canadian english; |
|
|
|
my $string = $an->Words->key({ |
|
key => 't_0001', |
|
language => 'en_CA', |
|
}) |
|
|
|
Same, but specifying a source file. |
|
|
|
my $string = $an->Words->key({ |
|
key => 't_0001', |
|
language => 'en_CA', |
|
file => 'an-tools.xml', |
|
}) |
|
|
|
Parameters; |
|
|
|
=head3 key (required) |
|
|
|
This is the key to return the string for. |
|
|
|
=head3 language (optional) |
|
|
|
This is the ISO code for the language you wish to read. For example, 'en_CA' to get the Canadian English string, or 'jp' for the Japanese string. |
|
|
|
When no language is passed, 'C<< $an->data->{defaults}{languages}{output} >>' is used. |
|
|
|
=head3 file (optional) |
|
|
|
This is the specific file to read the string from. It should generally not be needed as string keys should not be reused. However, if it happens, this is a way to specify which file's version you want. |
|
|
|
The file can be the file name, or a path. The specified file is search for by matching the the passed in string against the end of the file path. For example, 'C<< file => 'AN/an-tools.xml' >> will match the file 'c<< /usr/share/perl5/AN/an-tools.xml >>'. |
|
|
|
=cut |
|
sub key |
|
{ |
|
my $self = shift; |
|
my $parameter = shift; |
|
my $an = $self->parent; |
|
|
|
# Setup default values |
|
my $key = defined $parameter->{key} ? $parameter->{key} : ""; |
|
my $language = defined $parameter->{language} ? $parameter->{language} : $an->data->{defaults}{languages}{output}; |
|
my $file = defined $parameter->{file} ? $parameter->{file} : ""; |
|
my $string = "#!not_found!#"; |
|
my $error = 0; |
|
#print $THIS_FILE." ".__LINE__."; [ Debug ] - key: [$key], language: [$language], file: [$file]\n"; |
|
|
|
if (not $key) |
|
{ |
|
#print $THIS_FILE." ".__LINE__."; AN::Tools::Words->key()' called without a key name to read.\n"; |
|
$error = 1; |
|
} |
|
if (not $language) |
|
{ |
|
#print $THIS_FILE." ".__LINE__."; AN::Tools::Words->key()' called without a language, and 'defaults::languages::output' is not set.\n"; |
|
$error = 2; |
|
} |
|
|
|
if (not $error) |
|
{ |
|
foreach my $this_file (sort {$a cmp $b} keys %{$an->data->{words}}) |
|
{ |
|
#print $THIS_FILE." ".__LINE__."; [ Debug ] - this_file: [$this_file], file: [$file]\n"; |
|
# If they've specified a file and this doesn't match, skip it. |
|
next if (($file) && ($this_file !~ /$file$/)); |
|
if (exists $an->data->{words}{$this_file}{language}{$language}{key}{$key}{content}) |
|
{ |
|
$string = $an->data->{words}{$this_file}{language}{$language}{key}{$key}{content}; |
|
#print $THIS_FILE." ".__LINE__."; [ Debug ] - string: [$string]\n"; |
|
last; |
|
} |
|
} |
|
} |
|
|
|
#print $THIS_FILE." ".__LINE__."; [ Debug ] - string: [$string]\n"; |
|
return($string); |
|
} |
|
|
|
=head2 read |
|
|
|
This reads in a words file containing translated strings used to generated output for the user. |
|
|
|
Example to read 'C<< an-tools.xml >>'; |
|
|
|
my $words_file = $an->data->{path}{words}{'an-words.xml'}; |
|
my $an->Words->read({file => $words_file}) or die "Failed to read: [$words_file]. Does the file exist?\n"; |
|
|
|
Successful read will return '0'. Non-0 is an error; |
|
0 = OK |
|
1 = Invalid file name or path |
|
2 = File not found |
|
3 = File not readable |
|
4 = File found, failed to read for another reason. The error details will be printed. |
|
|
|
NOTE: Read works are stored in 'C<< $an->data->{words}{<file_name>}{language}{<language>}{string}{content} >>'. Metadata, like what languages are provided, are stored under 'C<< $an->data->{words}{<file_name>}{meta}{...} >>'. |
|
|
|
Parameters; |
|
|
|
=head3 file (required) |
|
|
|
This is the file to read. |
|
|
|
=cut |
|
sub read |
|
{ |
|
my $self = shift; |
|
my $parameter = shift; |
|
my $an = $self->parent; |
|
|
|
# Setup default values |
|
my $file = defined $parameter->{file} ? $parameter->{file} : 0; |
|
my $return_code = 0; |
|
|
|
if (not $file) |
|
{ |
|
# TODO: Log the problem, do not translate. |
|
print $THIS_FILE." ".__LINE__."; [ Warning ] - AN::Tools::Words->read()' called without a file name to read.\n"; |
|
$return_code = 1; |
|
} |
|
elsif (not -e $file) |
|
{ |
|
# TODO: Log the problem, do not translate. |
|
print $THIS_FILE." ".__LINE__."; [ Warning ] - AN::Tools::Words->read()' asked to read: [$file] which was not found.\n"; |
|
$return_code = 2; |
|
} |
|
elsif (not -r $file) |
|
{ |
|
# TODO: Log the problem, do not translate. |
|
print $THIS_FILE." ".__LINE__."; [ Warning ] - AN::Tools::Words->read()' asked to read: [$file] which was not readable by: [".getpwuid($<)."/".getpwuid($>)."] (uid/euid: [".$<."/".$>."]).\n"; |
|
$return_code = 3; |
|
} |
|
else |
|
{ |
|
# Read the file with XML::Simple |
|
my $xml = XML::Simple->new(); |
|
eval { $an->data->{words}{$file} = $xml->XMLin($file, KeyAttr => { language => 'name', key => 'name' }, ForceArray => [ 'language', 'key' ]) }; |
|
if ($@) |
|
{ |
|
chomp $@; |
|
print $THIS_FILE." ".__LINE__."; [ Error ] - The was a problem reading: [$file]. The error was:\n"; |
|
print "===========================================================\n"; |
|
print $@."\n"; |
|
print "===========================================================\n"; |
|
$return_code = 4; |
|
} |
|
else |
|
{ |
|
# Successfully read. |
|
|
|
### Some debug stuff |
|
# Read the meta data |
|
#my $version = $an->data->{words}{$file}{meta}{version}; |
|
#my $languages = $an->data->{words}{$file}{meta}{languages}; |
|
#print $THIS_FILE." ".__LINE__."; [ Debug ] - Version: [$version], languages: [$languages]\n"; |
|
|
|
#foreach my $this_language (sort {$a cmp $b} keys %{$an->data->{words}{$file}{language}}) |
|
#{ |
|
# my $long_name = $an->data->{words}{$file}{language}{$this_language}{long_name}; |
|
# print $THIS_FILE." ".__LINE__."; [ Debug ] - this_language: [$this_language], long_name: [$long_name]\n"; |
|
# print $THIS_FILE." ".__LINE__."; [ Debug ] - "$this_language:t_0001: [".$an->data->{words}{$file}{language}{$this_language}{key}{t_0001}{content}."]\n"; |
|
#} |
|
} |
|
} |
|
|
|
return($return_code); |
|
} |
|
|
|
# =head3 |
|
# |
|
# Private Functions; |
|
# |
|
# =cut |
|
|
|
############################################################################################################# |
|
# Private functions # |
|
############################################################################################################# |
|
|
|
1;
|
|
|