1
1
import html
2
2
import io
3
+ import json
3
4
import math
4
5
import os
5
6
import re
@@ -24,24 +25,32 @@ def element_attr(element, attr, default=None):
24
25
class QGSReader :
25
26
""" Read QGIS projects and extract data for QWC config """
26
27
27
- def __init__ (self , config , logger , assets_dir , use_cached_project_metadata , global_print_layouts ):
28
+ def __init__ (self , config , logger , assets_dir , translations_dir , use_cached_project_metadata , global_print_layouts ):
28
29
"""Constructor
29
30
30
31
:param obj config: Config generator config
31
32
:param Logger logger: Application logger
32
33
:param string assets_dir: Assets directory
34
+ :param str translations_dir: Viewer translations directory
33
35
:param bool use_cached_project_metadata: Whether to use cached project metadata
34
36
:param list global_print_layouts: Global print layouts
35
37
"""
36
38
self .config = config
37
39
self .logger = logger
38
40
self .assets_dir = assets_dir
41
+ self .translations_dir = translations_dir
39
42
self .use_cached_project_metadata = use_cached_project_metadata
40
43
self .global_print_layouts = global_print_layouts
41
44
42
45
self .qgs_resources_path = config .get ('qgis_projects_base_dir' , '/tmp/' )
43
46
self .qgs_ext = config .get ('qgis_project_extension' , '.qgs' )
44
47
self .nested_nrels = config .get ('generate_nested_nrel_forms' , False )
48
+ try :
49
+ with open (os .path .join (self .translations_dir , 'tsconfig.json' )) as fh :
50
+ self .viewer_languages = json .load (fh )['languages' ]
51
+ except :
52
+ self .logger .warning ("Failed to detect viewer languages from tsconfig.json" )
53
+ self .viewer_languages = ["en-US" ]
45
54
46
55
self .db_engine = DatabaseEngine ()
47
56
@@ -57,8 +66,9 @@ def read(self, map_prefix, theme_item, edit_datasets):
57
66
try :
58
67
if map_prefix .startswith ("pg/" ):
59
68
parts = map_prefix .split ("/" )
60
- qgs_path = self .qgs_resources_path
69
+ qgs_dir = self .qgs_resources_path
61
70
qgs_filename = 'postgresql:///?service=qgisprojects&schema=%s&project=%s' % (parts [1 ], parts [2 ])
71
+ projectname = parts [2 ]
62
72
63
73
qgis_projects_db = self .db_engine .db_engine ("postgresql:///?service=qgisprojects" )
64
74
@@ -84,6 +94,8 @@ def read(self, map_prefix, theme_item, edit_datasets):
84
94
else :
85
95
qgs_filename = map_prefix + self .qgs_ext
86
96
qgs_path = os .path .join (self .qgs_resources_path , qgs_filename )
97
+ qgs_dir = os .path .dirname (qgs_path )
98
+ projectname = os .path .basename (qgs_path ).removesuffix (self .qgs_ext )
87
99
if not os .path .exists (qgs_path ):
88
100
self .logger .error ("Could not find QGS project '%s'" % qgs_filename )
89
101
return None
@@ -131,9 +143,10 @@ def read(self, map_prefix, theme_item, edit_datasets):
131
143
132
144
return {
133
145
"project_crs" : self .__project_crs (root ),
146
+ "translations" : self .__theme_translations (qgs_dir , projectname ),
134
147
"print_templates" : self .__print_templates (root , shortname_map ),
135
148
"visibility_presets" : self .__visibility_presets (root ),
136
- "layer_metadata" : self .__layer_metadata (root , shortname_map , map_prefix , edit_datasets , theme_item , qgs_path )
149
+ "layer_metadata" : self .__layer_metadata (root , shortname_map , map_prefix , edit_datasets , theme_item , qgs_dir ),
137
150
}
138
151
139
152
@@ -142,6 +155,28 @@ def __project_crs(self, root):
142
155
authid = root .find ('./projectCrs/spatialrefsys/authid' )
143
156
return authid .text if authid is not None else None
144
157
158
+ def __theme_translations (self , qgs_dir , projectname ):
159
+ """ Read theme portion of translations from <projectname>_<lang>.json. """
160
+ all_translations = {}
161
+
162
+ for language in self .viewer_languages :
163
+ translations = {}
164
+
165
+ json_file = os .path .join (qgs_dir , f"{ projectname } _{ language } .json" )
166
+ if not os .path .exists (json_file ):
167
+ json_file = os .path .join (qgs_dir , f"{ projectname } _{ language [0 :2 ]} .json" )
168
+ if os .path .exists (json_file ):
169
+ self .logger .info ('Reading project translations %s' % json_file )
170
+ try :
171
+ with open (json_file ) as fh :
172
+ translations = json .load (fh )['theme' ]
173
+ except Exception as e :
174
+ self .logger .info ('Failed to read project translations %s: %s' % (json_file , str (e )))
175
+
176
+ if translations :
177
+ all_translations [language ] = translations
178
+
179
+ return all_translations
145
180
146
181
def __print_templates (self , root , shortname_map ):
147
182
""" Collect print templates from QGS and merge with global print layouts. """
@@ -248,7 +283,7 @@ def __visibility_presets(self, root):
248
283
return result
249
284
250
285
251
- def __layer_metadata (self , root , shortname_map , map_prefix , edit_datasets , theme_item , qgs_path ):
286
+ def __layer_metadata (self , root , shortname_map , map_prefix , edit_datasets , theme_item , qgs_dir ):
252
287
""" Read additional layer metadata from QGS. """
253
288
layers_metadata = {}
254
289
# Collect metadata for layers
@@ -276,7 +311,7 @@ def __layer_metadata(self, root, shortname_map, map_prefix, edit_datasets, theme
276
311
277
312
# Edit metadata
278
313
if editable :
279
- self .__layer_edit_metadata (root , layer_metadata , maplayer , layername , map_prefix , shortname_map , qgs_path , theme_item )
314
+ self .__layer_edit_metadata (root , layer_metadata , maplayer , layername , map_prefix , shortname_map , qgs_dir , theme_item )
280
315
281
316
layers_metadata [layername ] = layer_metadata
282
317
@@ -291,7 +326,7 @@ def __layer_metadata(self, root, shortname_map, map_prefix, edit_datasets, theme
291
326
return layers_metadata
292
327
293
328
294
- def __layer_edit_metadata (self , root , layer_metadata , maplayer , layername , map_prefix , shortnames , qgs_path , theme_item ):
329
+ def __layer_edit_metadata (self , root , layer_metadata , maplayer , layername , map_prefix , shortnames , qgs_dir , theme_item ):
295
330
""" Read layer metadata relevant for editing from QGS. """
296
331
297
332
provider = maplayer .find ('provider' ).text
@@ -384,7 +419,7 @@ def __layer_edit_metadata(self, root, layer_metadata, maplayer, layername, map_p
384
419
385
420
# Generate form
386
421
layer_metadata ["edit_form" ] = self .__generate_edit_form (
387
- root , qgs_path , map_prefix , shortnames , maplayer , layer_metadata , layername , theme_item
422
+ root , qgs_dir , map_prefix , shortnames , maplayer , layer_metadata , layername , theme_item
388
423
)
389
424
390
425
@@ -686,7 +721,7 @@ def __column_metadata(self, field_metadata, datasource, column, data_type_only =
686
721
constraints ['max' ] = ranges [data_type ]['max' ]
687
722
688
723
689
- def __generate_edit_form (self , project , qgs_path , map_prefix , shortnames , maplayer , layer_metadata , layername , theme_item ):
724
+ def __generate_edit_form (self , project , qgs_dir , map_prefix , shortnames , maplayer , layer_metadata , layername , theme_item ):
690
725
""" Copy / generate edit from from QGIS form settings. """
691
726
692
727
projectname = os .path .basename (map_prefix )
@@ -708,7 +743,7 @@ def __generate_edit_form(self, project, qgs_path, map_prefix, shortnames, maplay
708
743
if editform is not None :
709
744
formpath = editform .text
710
745
if not os .path .isabs (formpath ):
711
- formpath = os .path .join (os . path . dirname ( qgs_path ) , formpath )
746
+ formpath = os .path .join (qgs_dir , formpath )
712
747
try :
713
748
os .makedirs (outputdir , exist_ok = True )
714
749
shutil .copy (formpath , outputfile )
0 commit comments