Coverage for gws-app/gws/base/application/core.py: 93%
150 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-16 22:59 +0200
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-16 22:59 +0200
1"""Core application object"""
3from typing import Optional
5import gws
6import gws.base.action
7import gws.base.application.middleware
8import gws.base.auth
9import gws.base.client
10import gws.base.database
11import gws.base.job
12import gws.base.model
13import gws.base.printer
14import gws.base.project
15import gws.base.search
16import gws.base.storage
17import gws.base.template
18import gws.base.web
19import gws.config
20import gws.gis.cache
21import gws.gis.mpx.config
22import gws.lib.font
23import gws.lib.importer
24import gws.base.metadata
25import gws.lib.osx
26import gws.server.manager
27import gws.server.monitor
28import gws.spec
30_DEFAULT_LOCALE = ['en_CA']
32_DEFAULT_TEMPLATES = [
33 gws.Config(
34 type='html',
35 path=gws.u.dirname(__file__) + '/templates/project_description.cx.html',
36 subject='project.description',
37 access=gws.c.PUBLIC,
38 uid='default_template.project_description',
39 ),
40 gws.Config(
41 type='html',
42 path=gws.u.dirname(__file__) + '/templates/layer_description.cx.html',
43 subject='layer.description',
44 access=gws.c.PUBLIC,
45 uid='default_template.layer_description',
46 ),
47 gws.Config(
48 type='html',
49 path=gws.u.dirname(__file__) + '/templates/feature_description.cx.html',
50 subject='feature.description',
51 access=gws.c.PUBLIC,
52 uid='default_template.feature_description',
53 ),
54 gws.Config(
55 type='html',
56 path=gws.u.dirname(__file__) + '/templates/feature_title.cx.html',
57 subject='feature.title',
58 access=gws.c.PUBLIC,
59 uid='default_template.feature_title',
60 ),
61 gws.Config(
62 type='html',
63 path=gws.u.dirname(__file__) + '/templates/feature_label.cx.html',
64 subject='feature.label',
65 access=gws.c.PUBLIC,
66 uid='default_template.feature_label',
67 ),
68]
70_DEFAULT_PRINTER = gws.Config(
71 uid='gws.base.application.default_printer',
72 access=gws.c.PUBLIC,
73 template=gws.Config(
74 type='html',
75 path=gws.u.dirname(__file__) + '/templates/project_print.cx.html',
76 mapSize=(200, 180, gws.Uom.mm),
77 ),
78 qualityLevels=[{'dpi': 72}],
79)
82class Config(gws.ConfigWithAccess):
83 """Main application configuration"""
85 actions: Optional[list[gws.ext.config.action]]
86 """System-wide server actions."""
87 auth: Optional[gws.base.auth.manager.Config]
88 """Authorization methods and options."""
89 cache: Optional[gws.gis.cache.Config]
90 """Global cache configuration."""
91 client: Optional[gws.base.client.Config]
92 """Gws client configuration."""
93 database: Optional[gws.base.database.manager.Config]
94 """Database configuration."""
95 developer: Optional[dict]
96 """Developer options."""
97 finders: Optional[list[gws.ext.config.finder]]
98 """Global search providers."""
99 fonts: Optional[gws.lib.font.Config]
100 """Fonts configuration."""
101 helpers: Optional[list[gws.ext.config.helper]]
102 """Helpers configurations."""
103 locales: Optional[list[gws.LocaleUid]]
104 """Default locales for all projects."""
105 metadata: Optional[gws.base.metadata.Config]
106 """Application metadata."""
107 models: Optional[list[gws.ext.config.model]]
108 """Global data models."""
109 owsServices: Optional[list[gws.ext.config.owsService]]
110 """OWS services configuration."""
111 projectDirs: Optional[list[gws.DirPath]]
112 """Directories with additional projects."""
113 projectPaths: Optional[list[gws.FilePath]]
114 """Additional project paths."""
115 printers: Optional[list[gws.ext.config.printer]]
116 """Print configurations."""
117 projects: Optional[list[gws.ext.config.project]]
118 """Project configurations."""
119 server: Optional[gws.server.Config]
120 """Server engine options."""
121 storage: Optional[gws.base.storage.manager.Config]
122 """Database configuration."""
123 templates: Optional[list[gws.ext.config.template]]
124 """Default templates."""
125 vars: Optional[dict]
126 """Custom variables."""
127 web: Optional[gws.base.web.manager.Config]
128 """Web server options."""
131class Object(gws.Application):
132 """Main Application object"""
134 _helperMap: dict[str, gws.Node]
136 _developerOptions: dict
138 mpxUrl = ''
139 mpxConfig = ''
141 def configure(self):
142 self.vars = self.cfg('vars') or {}
144 self.serverMgr = self.create_child(gws.server.manager.Object, self.cfg('server'))
145 # NB need defaults from the server
146 self.config.server = self.serverMgr.config
148 gws.log.set_level(self.cfg('server.log.level'))
150 self.version = self.root.specs.version
151 self.versionString = f'GWS version {self.version}'
153 if gws.u.is_file('/GWS_REVISION'):
154 self.versionString += ' (rev. ' + gws.u.read_file('/GWS_REVISION') + ')'
156 if not gws.env.GWS_IN_TEST:
157 gws.log.info('*' * 80)
158 gws.log.info(self.versionString)
159 gws.log.info('*' * 80)
161 self._developerOptions = self.cfg('developer') or {}
162 if self._developerOptions:
163 gws.log.warning(f'developer mode enabled: {self._developerOptions}')
165 self.monitor = self.create_child(gws.server.monitor.Object, self.serverMgr.cfg('monitor'))
167 self.localeUids = self.cfg('locales') or _DEFAULT_LOCALE
168 self.metadata = gws.base.metadata.from_config(self.cfg('metadata'))
170 self.middlewareMgr = self.create_child(gws.base.application.middleware.Object)
172 p = self.cfg('fonts')
173 if p:
174 gws.lib.font.configure(p)
176 # NB the order of initialization is important
177 # - db
178 # - helpers
179 # - auth providers
180 # - actions, client, web
181 # - finally, projects
183 self.databaseMgr = self.create_child(gws.base.database.manager.Object, self.cfg('database'))
185 helpers = self.create_children(gws.ext.object.helper, self.cfg('helpers'))
186 self._helperMap = {p.extType: p for p in helpers}
188 self.storageMgr = self.create_child(gws.base.storage.manager.Object, self.cfg('storage'))
189 self.authMgr = self.create_child(gws.base.auth.manager.Object, self.cfg('auth'))
191 # @TODO default API
192 self.actionMgr = self.create_child(gws.base.action.manager.Object)
193 self.actions = self.create_children(gws.ext.object.action, self.cfg('actions'))
195 self.webMgr = self.create_child(gws.base.web.manager.Object, self.cfg('web'))
197 self.searchMgr = self.create_child(gws.base.search.manager.Object)
198 self.finders = self.create_children(gws.ext.object.finder, self.cfg('finders'))
200 self.modelMgr = self.create_child(gws.base.model.manager.Object)
201 self.models = self.create_children(gws.ext.object.model, self.cfg('models'))
203 self.templateMgr = self.create_child(gws.base.template.manager.Object)
204 self.templates = self.create_children(gws.ext.object.template, self.cfg('templates'))
205 for cfg in _DEFAULT_TEMPLATES:
206 self.templates.append(self.root.create_shared(gws.ext.object.template, cfg))
208 self.jobMgr = self.create_child(gws.base.job.manager.Object)
210 self.printerMgr = self.create_child(gws.base.printer.manager.Object)
211 self.printers = self.create_children(gws.ext.object.printer, self.cfg('printers'))
212 self.defaultPrinter = self.root.create_shared(gws.ext.object.printer, _DEFAULT_PRINTER)
214 self.owsServices = self.create_children(gws.ext.object.owsService, self.cfg('owsServices'))
216 self.client = self.create_child(gws.base.client.Object, self.cfg('client'))
218 self.projects = self.create_children(gws.ext.object.project, self.cfg('projects'))
220 def post_configure(self):
221 if not self.cfg('server.mapproxy.disabled'):
222 self.mpxUrl = f"http://{self.cfg('server.mapproxy.host')}:{self.cfg('server.mapproxy.port')}"
223 self.mpxConfig = gws.gis.mpx.config.create_and_save(self.root)
225 def activate(self):
226 gws.log.set_level(self.cfg('server.log.level'))
228 for p in self.root.configPaths:
229 if p.startswith(gws.c.CONFIG_DIR):
230 # do not watch derived config paths
231 continue
232 self.monitor.watch_file(p)
233 for d in self.config.get('projectDirs') or []:
234 self.monitor.watch_directory(d, gws.config.CONFIG_PATH_PATTERN)
236 def project(self, uid):
237 for p in self.projects:
238 if p.uid == uid:
239 return p
241 def helper(self, ext_type):
242 if ext_type not in self._helperMap:
243 p = self.create_child(gws.ext.object.helper, type=ext_type)
244 if not p:
245 raise gws.Error(f'helper {ext_type!r} not found')
246 gws.log.info(f'created helper {ext_type!r}')
247 self._helperMap[ext_type] = p
248 return self._helperMap.get(ext_type)
250 def developer_option(self, key):
251 return self._developerOptions.get(key)