File Coverage

lib/Serge/Sync/Plugin/TranslationService/Smartcat.pm
Criterion Covered Total %
statement 18 101 17.8
branch 0 58 0.0
condition 0 9 0.0
subroutine 6 13 46.1
pod 0 7 0.0
total 24 188 12.7


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