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