Coverage for gws-app/gws/base/exporter/worker.py: 81%
78 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-24 12:46 +0200
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-24 12:46 +0200
1from typing import Optional, cast
3import gws
4import gws.base.job
7class Object(gws.base.job.worker.Object):
8 project: gws.Project
9 request: gws.ExportRequest
10 result: gws.ExportResult
11 progressTotal: int = 1
12 progressStep: int = 0
13 progressPercent: int = 0
15 @classmethod
16 def run(cls, root: gws.Root, job: gws.Job):
17 request = gws.u.unserialize_from_path(job.payload.get('requestPath'))
18 w = cls(root, job.user, job, request)
19 w.work()
21 def __init__(self, root: gws.Root, user: gws.User, job: Optional[gws.Job], request: gws.ExportRequest):
22 super().__init__(root, user, job)
23 self.request = request
24 self.result = gws.ExportResult(
25 path='',
26 mime='',
27 numFiles=0,
28 numFeaturesTotal=0,
29 numFeaturesExported=0,
30 errors=[],
31 )
33 def work(self):
34 self.project = cast(gws.Project, self.user.require(self.request.projectUid, gws.ext.object.project))
36 exporter = self.root.app.exporterMgr.get_exporter(
37 [self.project, self.root.app],
38 self.request.exporterUid,
39 self.user,
40 )
41 if not exporter:
42 raise gws.NotFoundError('exporter not found')
44 # load + features + write
45 self.progressTotal = 1 + len(self.request.features or []) + 1
46 self.update_job(numSteps=100)
48 features = self.load_features()
49 self.notify('load')
51 ea = gws.ExportArgs(
52 exporter=exporter,
53 features=features,
54 shape=self.request.shape,
55 project=self.project,
56 user=self.user,
57 notify=self.notify,
58 )
60 exporter.run(ea, self.result)
61 self.update_job(state=gws.JobState.complete, result=self.result)
63 def load_features(self):
64 if not self.request.features:
65 return []
67 self.result.numFeaturesTotal = len(self.request.features)
69 models: dict[str, gws.Model] = {}
70 uid_map: dict[str, set[str]] = {}
71 fs_map: dict[str, gws.Feature] = {}
73 mc = gws.ModelContext(op=gws.ModelOperation.export, user=self.user, project=self.project)
75 for fp in self.request.features:
76 model_uid = fp.modelUid
77 feature_uid = fp.uid
79 model = models.get(model_uid)
80 if not model:
81 model = self.root.app.modelMgr.get_model(model_uid, self.user)
82 if not model:
83 gws.log.warning(f'model not found: {model_uid}')
84 continue
85 models[model_uid] = model
87 guid = gws.u.join_uid(model_uid, feature_uid)
88 es = model.exportStrategy or gws.FeatureExportStrategy.load
89 if es == gws.FeatureExportStrategy.client:
90 fs_map[guid] = model.feature_from_props(fp, mc)
91 else:
92 uid_map.setdefault(model_uid, set()).add(feature_uid)
94 for model_uid, feature_uids in uid_map.items():
95 model = models[model_uid]
96 fs = model.get_features(feature_uids, mc)
97 for f in fs:
98 guid = gws.u.join_uid(model_uid, f.uid())
99 fs_map[guid] = f
101 fs = []
103 for fp in self.request.features:
104 guid = gws.u.join_uid(fp.modelUid, fp.uid)
105 f = fs_map.get(guid)
106 if not f:
107 gws.log.warning(f'feature not found: {guid}')
108 continue
109 fs.append(f)
111 return fs
113 def notify(self, event, details=None):
114 job = self.get_job()
115 if not job:
116 return
117 self.progressStep += 1
118 p = int(self.progressStep / self.progressTotal * 100)
119 if p > self.progressPercent:
120 self.progressPercent = p
121 self.update_job(numSteps=100, step=self.progressPercent)