File Coverage

lib/Serge/Sync/Plugin/TranslationService/Smartcat.pm
Criterion Covered Total %
statement 18 97 18.5
branch 0 54 0.0
condition 0 9 0.0
subroutine 6 13 46.1
pod 0 7 0.0
total 24 180 13.3


line stmt bran cond sub pod time code
1             package Serge::Sync::Plugin::TranslationService::Smartcat;
2 1         5 use parent Serge::Sync::Plugin::Base::TranslationService,
3 1     1   1187 Serge::Interface::SysCmdRunner;
  1         292  
4              
5 1     1   22575 use strict;
  1         2  
  1         22  
6 1     1   5 use warnings;
  1         2  
  1         32  
7              
8 1     1   5 use File::Basename;
  1         2  
  1         59  
9 1     1   5 use File::Spec::Functions qw(rel2abs);
  1         2  
  1         38  
10 1     1   508 use Serge::Util qw(subst_macros);
  1         24316  
  1         1215  
11              
12             our $VERSION = "0.0.3";
13              
14             sub name {
15             return
16 0     0 0   'Smartcat translation server (http://smartcat.io/) .po synchronization plugin';
17             }
18              
19             sub init {
20 0     0 0   my $self = shift;
21              
22 0           $self->SUPER::init(@_);
23              
24 0           $self->merge_schema(
25             {
26             project_id => 'STRING',
27             token_id => 'STRING',
28             token => 'STRING',
29             project_translation_files_path => 'STRING',
30             push => {
31             disassemble_algorithm_name => 'STRING',
32             },
33             pull => {
34             complete_projects => 'BOOLEAN',
35             complete_documents => 'BOOLEAN',
36             },
37             filetype => 'STRING',
38             language_file_tree => 'BOOLEAN',
39              
40             log_file => 'STRING',
41             debug => 'BOOLEAN',
42             }
43             );
44             }
45              
46             sub validate_data {
47 0     0 0   my ($self) = @_;
48              
49 0           $self->SUPER::validate_data;
50              
51 0           $self->{data}->{filetype} = subst_macros( $self->{data}->{filetype} );
52 0           $self->{data}->{project_translation_files_path} = subst_macros( $self->{data}->{project_translation_files_path} );
53              
54 0 0         unless ( $self->{data}->{project_translation_files_path} ) {
55 0           my %job_ts_file_paths;
56             $job_ts_file_paths{ $_->{ts_file_path} }++
57 0           for @{ $self->{parent}{config}{data}{jobs} };
  0            
58 0           my @job_ts_file_paths = keys %job_ts_file_paths;
59             die sprintf( "Set 'project_translation_files_path' parameter, more than one 'ts_file_path' found in the config file: %s",
60 0 0         join( ', ', map { "'$_'" } @job_ts_file_paths ) )
  0            
61             if @job_ts_file_paths > 1;
62 0           my $ts_file_path = shift @job_ts_file_paths;
63              
64 0 0         die sprintf(
65             "'ts_file_path' which is set to '%s', doesn't match '%%LANG%%' pattern.",
66             $ts_file_path )
67             unless $ts_file_path =~
68             m/(%LOCALE%|%LANG%).*$self->{data}->{filetype}/;
69              
70             $self->{data}->{project_translation_files_path} =
71 0           dirname( dirname($ts_file_path) );
72              
73             die sprintf(
74             "'ts_file_path' parent directory, which is set to '%s', does not point to a valid directory. Run 'localize' to generate translation files.",
75             $self->{data}->{project_translation_files_path} )
76 0 0         unless -d $self->{data}->{project_translation_files_path};
77             } else {
78             die sprintf(
79             "'project_translation_files_path', which is set to '%s', does not point to a valid directory. Run 'localize' to generate translation files.",
80             $self->{data}->{project_translation_files_path} )
81 0 0         unless -d $self->{data}->{project_translation_files_path};
82             }
83              
84              
85 0           $self->{data}->{project_id} = subst_macros( $self->{data}->{project_id} );
86 0           $self->{data}->{token_id} = subst_macros( $self->{data}->{token_id} );
87 0           $self->{data}->{token} = subst_macros( $self->{data}->{token} );
88              
89 0 0         if ( exists $self->{data}->{push} ) {
90             $self->{data}->{push}->{disassemble_algorithm_name} =
91 0           subst_macros( $self->{data}->{push}->{disassemble_algorithm_name} );
92             }
93 0 0         if ( exists $self->{data}->{pull} ) {
94             $self->{data}->{pull_complete_documents} =
95 0           subst_macros( $self->{data}->{pull}->{complete_documents} );
96             $self->{data}->{pull}->{complete_projects} =
97 0           subst_macros( $self->{data}->{pull}->{complete_projects} );
98             }
99 0           $self->{data}->{log_file} = subst_macros( $self->{data}->{log_file} );
100             $self->{data}->{language_file_tree} =
101 0           subst_macros( $self->{data}->{language_file_tree} );
102              
103 0           $self->{data}->{debug} = subst_macros( $self->{data}->{debug} );
104              
105 0 0         die "'project_id' not defined" unless defined $self->{data}->{project_id};
106              
107 0 0         if ( $self->{data}->{log_file} ) {
108 0           my $log_dir = rel2abs( dirname( $self->{data}->{log_file} ) );
109 0 0         die
110             "'log_file' parent directory which is set to '$log_dir', does not point to a valid directory.\n"
111             unless -d $log_dir;
112             }
113              
114 0 0         $self->{data}->{push} = {} unless defined $self->{data}->{push};
115             $self->{data}->{push}->{disassemble_algorithm_name} = 'Serge.io PO'
116 0 0         unless defined $self->{data}->{push}->{disassemble_algorithm_name};
117 0 0         $self->{data}->{filetype} = '.po' unless defined $self->{data}->{filetype};
118 0 0         $self->{data}->{pull} = {} unless defined $self->{data}->{pull};
119             $self->{data}->{pull}->{complete_projects} = 0
120 0 0         unless $self->{data}->{pull}->{complete_projects};
121             $self->{data}->{pull}->{complete_documents} = 0
122 0 0         unless $self->{data}->{pull}->{complete_documents};
123             }
124              
125             sub run_smartcat_cli {
126 0     0 0   my ( $self, $action, $langs ) = @_;
127              
128 0           my $command = $action . ' --project-id=' . $self->{data}->{project_id};
129              
130             $command .= " --token-id=" . $self->{data}->{token_id}
131 0 0         if defined $self->{data}->{token_id};
132             $command .= " --token=" . $self->{data}->{token}
133 0 0         if defined $self->{data}->{token};
134             $command .=
135 0           " --project-workdir=" . $self->{data}->{project_translation_files_path};
136 0           $command .= " --log=" . $self->{data}->{log_file};
137              
138 0 0         if ( $self->{data}->{language_file_tree} ) {
139 0           $command .= " --language-file-tree";
140             }
141              
142 0 0         $command .= " --debug" if $self->{data}->{debug};
143              
144 0           $command = 'smartcat-cli ' . $command;
145 0           my $result = $self->run_cmd($command);
146              
147 0           return $result;
148             }
149              
150             sub run_cmd {
151 0     0 0   my ( $self, $command, $ignore_codes ) = @_;
152              
153 0           my $line = $command;
154 0           $line =~ s/(\-\-token=\").+?(\")/$1******$2/;
155 0 0         $line =~ s/(\-\-token=).+?(\s)/$1******$2/ unless $1;
156 0           print "Running '$line'...\n";
157              
158 0           my $result = "";
159 0           print "\n--------------------\n";
160 0           system($command); # output will be echoed but not captured
161 0           print "\n--------------------\n";
162              
163 0           my $error_code = unpack 'c', pack 'C', $? >> 8; # error code
164              
165 0 0 0       if (
      0        
      0        
166             ( $error_code > 0 )
167             && $ignore_codes
168             && ( ref( \$ignore_codes ) eq 'SCALAR'
169             || ( grep( $_ eq $error_code, @$ignore_codes ) > 0 ) )
170             )
171             {
172 0 0         print "Exit code: $error_code (ignored)\n" if $self->{debug};
173 0           $error_code = 0;
174             }
175              
176 0 0         die $result . "\nExit code: $error_code; last error: $!\n"
177             if $error_code != 0;
178              
179 0           return $result;
180             }
181              
182             sub pull_ts {
183 0     0 0   my ( $self, $langs ) = @_;
184              
185 0           my $options = '';
186 0           my $pull_settings = $self->{data}->{pull};
187 0 0         $options .= ' --complete-documents' if $pull_settings->{complete_documents};
188 0 0         $options .= ' --complete-projects' if $pull_settings->{complete_projects};
189              
190 0           return $self->run_smartcat_cli( 'pull' . $options, $langs );
191             }
192              
193             sub push_ts {
194 0     0 0   my ( $self, $langs ) = @_;
195              
196 0           my $options = '';
197 0           my $push_settings = $self->{data}->{push};
198             $options .=
199             ' --disassemble-algorithm-name="'
200             . $push_settings->{disassemble_algorithm_name} . '"'
201 0 0         if $push_settings->{disassemble_algorithm_name};
202              
203 0           return $self->run_smartcat_cli( 'push' . $options, $langs );
204             }
205              
206             1;
207              
208             __END__