ui_definition.py (14523B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\campaigns\client\v2\data_model\ui_definition.py 2 from __future__ import absolute_import, division, print_function 3 import calendar 4 import campaigns.client.v2.data_model.flatbuffer.event_matcher_definitions_generated as definitions_fb 5 from datetime import datetime 6 from datetime import timedelta 7 from flatbuffers.vector_utils import write_vector_of_offsets 8 from google.protobuf.internal.well_known_types import Timestamp 9 from localization.client.cerberus_formatted_message import CerberusFormattedMessage 10 from eveProto.generated.eve_public.campaign.ui.ui_pb2 import Definition 11 try: 12 from typing import Dict, List 13 except ImportError: 14 pass 15 16 _NANOS_PER_MICROSECOND = 1000 17 _EPOCH_DATETIME = datetime.utcfromtimestamp(0) 18 19 class UIDefinition(object): 20 21 def __init__(self, texts, resources, annotations, tags): 22 self._texts = texts 23 self._resources = resources 24 self._annotations = annotations 25 self._tags = tags 26 27 @property 28 def texts(self): 29 return self._texts 30 31 @property 32 def resources(self): 33 return self._resources 34 35 @property 36 def annotations(self): 37 return self._annotations 38 39 @property 40 def tags(self): 41 return self._tags 42 43 def __repr__(self): 44 return '<%s %r>' % (self.__class__.__name__, self.__dict__) 45 46 @classmethod 47 def from_proto(cls, definition): 48 texts = [ Text.from_proto(text) for text in definition.texts ] 49 resources = [ Resource.from_proto(resource) for resource in definition.resources ] 50 annotations = {annotation.key:annotation.value for annotation in definition.annotations} 51 tags = [ tag.name for tag in definition.content_tags ] 52 return UIDefinition(texts, resources, annotations, tags) 53 54 def __eq__(self, other): 55 if not isinstance(other, UIDefinition): 56 raise NotImplementedError 57 return self.texts == other.texts and self.resources == other.resources and self.annotations == other.annotations and self.tags == other.tags 58 59 def __ne__(self, other): 60 return not self.__eq__(other) 61 62 def _annotation_to_flatbuffer(self, builder, key, value): 63 key_offset = builder.CreateString(key) 64 value_ofset = builder.CreateString(value) 65 definitions_fb.AnnotationStart(builder) 66 definitions_fb.AnnotationAddKey(builder, key_offset) 67 definitions_fb.AnnotationAddValue(builder, value_ofset) 68 return definitions_fb.AnnotationEnd(builder) 69 70 def to_flatbuffer(self, builder): 71 text_offsets = [ text.to_flatbuffer(builder) for text in self.texts ] 72 resources_offsets = [ resource.to_flatbuffer(builder) for resource in self.resources ] 73 annotations_offsets = [ self._annotation_to_flatbuffer(builder, key, value) for key, value in self.annotations.items() ] 74 tags_offsets = [ builder.CreateString(tag) for tag in self.tags ] 75 text_offset = write_vector_of_offsets(builder, definitions_fb.UIDefinitionStartTextsVector, text_offsets) 76 resources_offset = write_vector_of_offsets(builder, definitions_fb.UIDefinitionStartResourcesVector, resources_offsets) 77 annotations_offset = write_vector_of_offsets(builder, definitions_fb.UIDefinitionStartAnnotationsVector, annotations_offsets) 78 tags_offset = write_vector_of_offsets(builder, definitions_fb.UIDefinitionStartTagsVector, tags_offsets) 79 definitions_fb.UIDefinitionStart(builder) 80 definitions_fb.UIDefinitionAddTexts(builder, text_offset) 81 definitions_fb.UIDefinitionAddResources(builder, resources_offset) 82 definitions_fb.UIDefinitionAddAnnotations(builder, annotations_offset) 83 definitions_fb.UIDefinitionAddTags(builder, tags_offset) 84 return definitions_fb.UIDefinitionEnd(builder) 85 86 @classmethod 87 def from_flatbuffer(cls, ui_definition_fb): 88 texts = [] 89 for index in range(ui_definition_fb.TextsLength()): 90 text = ui_definition_fb.Texts(index) 91 texts.append(Text.from_flatbuffer(text)) 92 93 resources = [] 94 for index in range(ui_definition_fb.ResourcesLength()): 95 resource = ui_definition_fb.Resources(index) 96 resources.append(Resource.from_flatbuffer(resource)) 97 98 annotations = {} 99 for index in range(ui_definition_fb.AnnotationsLength()): 100 annotation = ui_definition_fb.Annotations(index) 101 annotations[annotation.Key()] = annotation.Value() 102 103 tags = [] 104 for index in range(ui_definition_fb.TagsLength()): 105 tag = ui_definition_fb.Tags(index) 106 tags.append(tag.decode('utf-8')) 107 108 return UIDefinition(texts, resources, annotations, tags) 109 110 111 def _RoundTowardZero(value, divider): 112 result = value // divider 113 remainder = value % divider 114 if result < 0 and remainder > 0: 115 return result + 1 116 else: 117 return result 118 119 120 def _message_from_flatbuffer(formatted_message_fb): 121 id = formatted_message_fb.Id() 122 parameters = {} 123 for index in range(formatted_message_fb.ParametersLength()): 124 parameter = formatted_message_fb.Parameters(index) 125 key, value = _parameter_from_flatbuffer(parameter) 126 parameters[key] = value 127 128 return CerberusFormattedMessage(id, parameters) 129 130 131 def _parameter_from_flatbuffer(formatted_message_parameter_fb): 132 key = formatted_message_parameter_fb.Key().decode('utf-8') 133 value_type = formatted_message_parameter_fb.ValueType() 134 if value_type == definitions_fb.FormattedMessageParameterValue.String: 135 generic_value = formatted_message_parameter_fb.Value() 136 string_value = definitions_fb.StringParameterValue() 137 string_value.Init(generic_value.Bytes, generic_value.Pos) 138 value = string_value.Value().decode('utf-8') 139 elif value_type == definitions_fb.FormattedMessageParameterValue.Double: 140 generic_value = formatted_message_parameter_fb.Value() 141 double_value = definitions_fb.DoubleParameterValue() 142 double_value.Init(generic_value.Bytes, generic_value.Pos) 143 value = double_value.Value() 144 elif value_type == definitions_fb.FormattedMessageParameterValue.Int: 145 generic_value = formatted_message_parameter_fb.Value() 146 int_value = definitions_fb.IntParameterValue() 147 int_value.Init(generic_value.Bytes, generic_value.Pos) 148 value = int_value.Value() 149 elif value_type == definitions_fb.FormattedMessageParameterValue.UInt: 150 generic_value = formatted_message_parameter_fb.Value() 151 uint_value = definitions_fb.UIntParameterValue() 152 uint_value.Init(generic_value.Bytes, generic_value.Pos) 153 value = uint_value.Value() 154 elif value_type == definitions_fb.FormattedMessageParameterValue.Timestamp: 155 generic_value = formatted_message_parameter_fb.Value() 156 timestamp_value = definitions_fb.TimestampParameterValue() 157 timestamp_value.Init(generic_value.Bytes, generic_value.Pos) 158 timestamp_seconds = timestamp_value.Seconds() 159 timestamp_nanos = timestamp_value.Nanos() 160 value = _convert_seconds_and_nanos_to_datetime(timestamp_seconds, timestamp_nanos) 161 elif value_type == definitions_fb.FormattedMessageParameterValue.Duration: 162 generic_value = formatted_message_parameter_fb.Value() 163 duration_value = definitions_fb.DurationParameterValue() 164 duration_value.Init(generic_value.Bytes, generic_value.Pos) 165 timestamp_seconds = duration_value.Seconds() 166 timestamp_nanos = duration_value.Nanos() 167 value = _convert_seconds_and_nanos_to_timedelta(timestamp_seconds, timestamp_nanos) 168 else: 169 raise ValueError('Unsupported FormattedMessageParameterValue') 170 return (key, value) 171 172 173 def _convert_seconds_and_nanos_to_datetime(seconds, nanos): 174 return _EPOCH_DATETIME + timedelta(seconds=seconds, microseconds=_RoundTowardZero(nanos, _NANOS_PER_MICROSECOND)) 175 176 177 def _convert_seconds_and_nanos_to_timedelta(seconds, nanos): 178 return timedelta(seconds=seconds, microseconds=_RoundTowardZero(nanos, _NANOS_PER_MICROSECOND)) 179 180 181 class Text(object): 182 183 def __init__(self, key, message): 184 self._key = key 185 self._message = message 186 187 @property 188 def key(self): 189 return self._key 190 191 @property 192 def message(self): 193 return self._message 194 195 def __repr__(self): 196 return '<%s %r>' % (self.__class__.__name__, self.__dict__) 197 198 @classmethod 199 def from_proto(cls, definition): 200 key = definition.key 201 message = CerberusFormattedMessage.from_proto(definition.message) 202 return Text(key, message) 203 204 def to_flatbuffer(self, builder): 205 key_offset = builder.CreateString(self.key) 206 message_offset = self._message_to_flatbuffer(builder) 207 definitions_fb.TextStart(builder) 208 definitions_fb.TextAddKey(builder, key_offset) 209 definitions_fb.TextAddMessage(builder, message_offset) 210 return definitions_fb.TextEnd(builder) 211 212 @classmethod 213 def from_flatbuffer(cls, text_fb): 214 key = text_fb.Key().decode('utf-8') 215 message = _message_from_flatbuffer(text_fb.Message()) 216 return Text(key, message) 217 218 def _message_to_flatbuffer(self, builder): 219 message = self.message 220 parameter_offsets = [ self._parameter_to_flatbuffer(builder, key, parameter) for key, parameter in message.parameters.items() ] 221 parameters_offset = write_vector_of_offsets(builder, definitions_fb.FormattedMessageStartParametersVector, parameter_offsets) 222 definitions_fb.FormattedMessageStart(builder) 223 definitions_fb.FormattedMessageAddId(builder, message.identifier) 224 definitions_fb.FormattedMessageAddParameters(builder, parameters_offset) 225 return definitions_fb.FormattedMessageEnd(builder) 226 227 def _parameter_to_flatbuffer(self, builder, key, parameter): 228 if isinstance(parameter, str): 229 string_offset = builder.CreateString(parameter) 230 definitions_fb.StringParameterValueStart(builder) 231 definitions_fb.StringParameterValueAddValue(builder, string_offset) 232 parameter_offset = definitions_fb.StringParameterValueEnd(builder) 233 parameter_type = definitions_fb.FormattedMessageParameterValue.String 234 elif isinstance(parameter, int): 235 if parameter < 0: 236 definitions_fb.IntParameterValueStart(builder) 237 definitions_fb.IntParameterValueAddValue(builder, parameter) 238 parameter_offset = definitions_fb.IntParameterValueEnd(builder) 239 parameter_type = definitions_fb.FormattedMessageParameterValue.Int 240 else: 241 definitions_fb.UIntParameterValueStart(builder) 242 definitions_fb.UIntParameterValueAddValue(builder, parameter) 243 parameter_offset = definitions_fb.UIntParameterValueEnd(builder) 244 parameter_type = definitions_fb.FormattedMessageParameterValue.UInt 245 elif isinstance(parameter, float): 246 definitions_fb.DoubleParameterValueStart(builder) 247 definitions_fb.DoubleParameterValueAddValue(builder, parameter) 248 parameter_offset = definitions_fb.DoubleParameterValueEnd(builder) 249 parameter_type = definitions_fb.FormattedMessageParameterValue.Double 250 elif isinstance(parameter, datetime): 251 seconds, nanos = self._convert_datetime_to_seconds_and_nanos(parameter) 252 definitions_fb.TimestampParameterValueStart(builder) 253 definitions_fb.TimestampParameterValueAddSeconds(builder, seconds) 254 definitions_fb.TimestampParameterValueAddNanos(builder, nanos) 255 parameter_offset = definitions_fb.TimestampParameterValueEnd(builder) 256 parameter_type = definitions_fb.FormattedMessageParameterValue.Timestamp 257 elif isinstance(parameter, timedelta): 258 second = int(parameter.total_seconds()) 259 nanos = 0 260 definitions_fb.DurationParameterValueStart(builder) 261 definitions_fb.DurationParameterValueAddSeconds(builder, second) 262 definitions_fb.DurationParameterValueAddNanos(builder, nanos) 263 parameter_offset = definitions_fb.DurationParameterValueEnd(builder) 264 parameter_type = definitions_fb.FormattedMessageParameterValue.Duration 265 else: 266 raise NotImplementedError 267 key_offset = builder.CreateString(key) 268 definitions_fb.FormattedMessageParameterStart(builder) 269 definitions_fb.FormattedMessageParameterAddKey(builder, key_offset) 270 definitions_fb.FormattedMessageParameterAddValue(builder, parameter_offset) 271 definitions_fb.FormattedMessageParameterAddValueType(builder, parameter_type) 272 return definitions_fb.FormattedMessageParameterEnd(builder) 273 274 def _convert_datetime_to_seconds_and_nanos(self, dt): 275 seconds = calendar.timegm(dt.utctimetuple()) 276 nanos = dt.microsecond * _NANOS_PER_MICROSECOND 277 return (seconds, nanos) 278 279 def __eq__(self, other): 280 if not isinstance(other, Text): 281 raise NotImplementedError 282 return self.key == other.key and self.message == other.message 283 284 def __ne__(self, other): 285 return not self.__eq__(other) 286 287 288 class Resource(object): 289 290 def __init__(self, key, path): 291 self._key = key 292 self._path = path 293 294 @property 295 def key(self): 296 return self._key 297 298 @property 299 def path(self): 300 return self._path 301 302 def __repr__(self): 303 return '<%s %r>' % (self.__class__.__name__, self.__dict__) 304 305 @classmethod 306 def from_proto(cls, definition): 307 key = definition.key 308 path = definition.client_resource_path 309 return Resource(key, path) 310 311 def to_flatbuffer(self, builder): 312 key_offset = builder.CreateString(self.key) 313 path_offset = builder.CreateString(self.path) 314 definitions_fb.ResourceStart(builder) 315 definitions_fb.ResourceAddKey(builder, key_offset) 316 definitions_fb.ResourceAddPath(builder, path_offset) 317 return definitions_fb.ResourceEnd(builder) 318 319 @classmethod 320 def from_flatbuffer(cls, resource_fb): 321 key = resource_fb.Key() 322 path = resource_fb.Path() 323 return Resource(key, path) 324 325 def __eq__(self, other): 326 if not isinstance(other, Resource): 327 raise NotImplementedError 328 return self.key == other.key and self.path == other.path 329 330 def __ne__(self, other): 331 return not self.__eq__(other)