1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 import os
22 import shutil
23
24 from translate.convert import factory as convert_factory
25
26 from projstore import ProjectStore
27
28 __all__ = ['Project']
29
30
31
32
33
34
36 """Split the given filename into a name and extensions part.
37 The extensions part is defined by any sequence of extensions, where an
38 extension is a 3-letter, .-separated string or one of "po" or
39 "properties". If the file name consists entirely out of extensions, the
40 first part is assumed to be the file name and the rest extensions."""
41 filename_parts = filename.split(os.extsep)
42 extensions = []
43 for part in reversed(filename_parts):
44 if len(part) != 3 and part not in ('po', 'properties'):
45 break
46 extensions.append(part)
47 if not extensions:
48 return filename, ''
49 extensions = [x for x in reversed(extensions)]
50
51 if len(extensions) == len(filename_parts):
52 extensions = extensions[1:]
53 return os.extsep.join(filename_parts[:-len(extensions)]), os.extsep.join(extensions)
54
55
57 """Manages a project store as well as the processes involved in a project
58 workflow."""
59
60
65
67 if self.store:
68 del self.store
69
70
72 """Proxy for C{self.store.append_sourcefile()}."""
73 return self.store.append_sourcefile(srcfile, src_fname)
74
75 - def add_source_convert(self, srcfile, src_fname=None, convert_options=None, extension=None):
76 """Convenience method that calls L{add_source} and L{convert_forward}
77 and returns the results from both."""
78 srcfile, srcfname = self.add_source(srcfile, src_fname)
79 transfile, transfname = self.convert_forward(srcfname, convert_options=convert_options)
80 return srcfile, srcfname, transfile, transfname
81
83 """Proxy for C{self.store.close()}."""
84 self.store.close()
85
86 - def convert_forward(self, input_fname, template=None, output_fname=None, **options):
87 """Convert the given input file to the next type in the process:
88 Source document (eg. ODT) -> Translation file (eg. XLIFF) ->
89 Translated document (eg. ODT).
90
91 @type input_fname: basestring
92 @param input_fname: The project name of the file to convert
93 @type convert_options: dict (optional)
94 @param convert_options: Passed as-is to
95 C{translate.convert.factory.convert()}.
96 @returns 2-tuple: the converted file object and it's project name."""
97 inputfile = self.get_file(input_fname)
98 input_type = self.store.get_filename_type(input_fname)
99
100 if input_type == 'tgt':
101 raise ValueError('Cannot convert a target document further: %s' % (input_fname))
102
103 templ_fname = None
104 if isinstance(template, basestring):
105 template, templ_fname = self.get_file(template)
106
107 if template and not templ_fname:
108 templ_fname = template.name
109
110
111 if template is None:
112 convert_map = self.store.convert_map
113 if input_fname in convert_map:
114 templ_fname = convert_map[input_fname][1]
115 template = self.get_file(templ_fname)
116 elif input_type == 'trans':
117
118
119
120 for in_name, (out_name, tmpl_name) in self.store.convert_map.items():
121 if input_fname == out_name:
122 template, templ_fname = self.get_file(in_name), in_name
123 break
124
125
126 conv_options = dict(in_fname=input_fname)
127
128 if input_fname in self.store.convert_map:
129 out_name, tmpl_name = self.store.convert_map[input_fname]
130 if out_name in self.store._files and options.get('overwrite_output', True):
131 self.remove_file(out_name)
132
133 converted_file, converted_ext = convert_factory.convert(
134 inputfile,
135 template=template,
136 options=conv_options,
137 convert_options=options.get('convert_options', None)
138 )
139
140
141 if not output_fname:
142 _dir, fname = os.path.split(input_fname)
143 directory = ''
144 if hasattr(inputfile, 'name'):
145
146 directory, _fn = os.path.split(inputfile.name)
147 else:
148
149 directory = os.getcwd()
150 output_fname = os.path.join(directory, fname)
151 output_fname, output_ext = split_extensions(output_fname)
152 output_ext_parts = output_ext.split(os.extsep)
153
154
155 if 'output_suffix' in options:
156 output_fname += options['output_suffix']
157
158
159
160
161 if len(output_ext_parts) >= 2 and output_ext_parts[-2] == converted_ext:
162 output_ext_parts = output_ext_parts[:-1]
163 else:
164 output_ext_parts.append(converted_ext)
165 output_fname += os.extsep.join([''] + output_ext_parts)
166
167 if os.path.isfile(output_fname):
168
169
170 os.unlink(converted_file.name)
171 raise IOError("Output file already exists: %s" % (output_fname))
172
173 os.rename(converted_file.name, output_fname)
174
175 output_type = self.store.TYPE_INFO['next_type'][input_type]
176 outputfile, output_fname = self.store.append_file(
177 output_fname, None, ftype=output_type, delete_orig=True
178 )
179 self.store.convert_map[input_fname] = (output_fname, templ_fname)
180
181 return outputfile, output_fname
182
184 """Export the file with the specified filename to the given destination.
185 This method will raise L{FileNotInProjectError} via the call to
186 L{ProjectStore.get_file()} if C{fname} is not found in the project."""
187 open(destfname, 'w').write(self.store.get_file(fname).read())
188
190 """Proxy for C{self.store.get_file()}."""
191 return self.store.get_file(fname)
192
194 """Proxy for C{self.store.get_proj_filename()}."""
195 return self.store.get_proj_filename(realfname)
196
198 """Try and find a real file name for the given project file name."""
199 projfile = self.get_file(projfname)
200 rfname = getattr(projfile, 'name', getattr(projfile, 'filename', None))
201 if rfname is None:
202 raise ValueError('Project file has no real file: %s' % (projfname))
203 return rfname
204
206 """Proxy for C{self.store.remove_file()}."""
207 self.store.remove_file(projfname, ftype)
208
209 - def save(self, filename=None):
210 """Proxy for C{self.store.save()}."""
211 self.store.save(filename)
212
214 """Proxy for C{self.store.update_file()}."""
215 self.store.update_file(proj_fname, infile)
216