def collect_translatables(manager, obj): """ Return translatables from ``obj``. Mutates ``obj`` to replace translations with placeholders. Expects translator.save_translation or translator.delete_translations to be called for each collected translatable. """ if isinstance(obj, PersistableType): # object is a type; nothing to do return [] translatables = [] descriptor = manager.type_registry.get_descriptor(type(obj)) message_id = get_message_id(manager, obj) for attr_name in iter_translatables(descriptor): attr = getattr(obj, attr_name) if is_translatable_value(attr): setattr(obj, attr_name, PLACEHOLDER) context = get_context(manager, obj, attr_name) translatable = TaalTranslatableString( context, message_id, attr) translatables.append(translatable) return translatables
def collect_translatables(manager, obj): """ Return translatables from ``obj``. Mutates ``obj`` to replace translations with placeholders. Expects translator.save_translation or translator.delete_translations to be called for each collected translatable. """ if isinstance(obj, PersistableType): # object is a type; nothing to do return [] translatables = [] descriptor = manager.type_registry.get_descriptor(type(obj)) message_id = get_message_id(manager, obj) for attr_name in iter_translatables(descriptor): attr = getattr(obj, attr_name) if is_translatable_value(attr): setattr(obj, attr_name, PLACEHOLDER) if isinstance(attr, TaalTranslatableString): # not changed since value was loaded, so don't collect for # updating the translations table continue context = get_context(manager, obj, attr_name) translatable = TaalTranslatableString(context, message_id, attr) translatables.append(translatable) return translatables
def serialize(self, obj, for_db=False): if for_db or type(obj) is PersistableType: return super(Manager, self).serialize(obj) message_id = get_message_id(self, obj) data = super(Manager, self).serialize(obj) descriptor = self.type_registry.get_descriptor(type(obj)) for attr_name, attr_type in descriptor.attributes.items(): if isinstance(attr_type, TranslatableString): value = data[attr_name] if is_translatable_value(value): context = get_context(self, obj, attr_name) data[attr_name] = TaalTranslatableString( context, message_id) return data
def test_get_translation(session, manager): manager.save(CustomFieldsEntity) item = CustomFieldsEntity() manager.save(item) create_translation_for_entity(session, manager, 'english', item, 'name', 'English name') context = get_context(manager, item, 'name') message_id = get_message_id(manager, item) translatable = TranslatableString(context=context, message_id=message_id) translator = Translator(Translation, session, 'english') translated_data = translator.translate(translatable) assert translated_data == 'English name'
def test_get_translation(session, manager): manager.save(CustomFieldsEntity) item = CustomFieldsEntity() manager.save(item) create_translation_for_entity( session, manager, 'english', item, 'name', 'English name') context = get_context(manager, item, 'name') message_id = get_message_id(manager, item) translatable = TranslatableString( context=context, message_id=message_id) translator = Translator(Translation, session, 'english') translated_data = translator.translate(translatable) assert translated_data == 'English name'
def test_collect_translatables(bound_manager): manager = bound_manager obj = CustomFieldsEntity(id=1, name="value", extra1="", extra2=None) manager.save(CustomFieldsEntity) manager.save(obj) translatables = collect_translatables(manager, obj) expected_values = { "name": PLACEHOLDER, "extra1": PLACEHOLDER, "extra2": None } for translatable in translatables: attr_name = translatable.context.split(":")[-1] expected_value = expected_values.pop(attr_name) assert translatable.context == get_context(manager, obj, attr_name) assert translatable.message_id == get_message_id(manager, obj) assert translatable.pending_value == expected_value assert expected_values == {}
def create_translation_for_entity( session, manager, language, obj, field, translation_str): context = taal_kaiso_types.get_context(manager, obj, field) message_id = taal_kaiso_types.get_message_id(manager, obj) return _create_translation( session, language, context, message_id, translation_str)
def check_value(obj, attr_name, expected_value): context = get_context(manager, obj, attr_name) assert session_cls().query(Translation).filter_by( context=context).one().value == expected_value
def change_instance_type(self, obj, type_id, updated_values=None): if updated_values is None: updated_values = {} updated_values = updated_values.copy() old_descriptor = self.type_registry.get_descriptor(type(obj)) new_descriptor = self.type_registry.get_descriptor_by_id(type_id) old_message_id = get_message_id(self, obj) old_translatables = {} # collect any translatable fields on the original object # also, replace any values with placeholders for the super() call for attr_name in iter_translatables(old_descriptor): attr = getattr(obj, attr_name) if is_translatable_value(attr): setattr(obj, attr_name, PLACEHOLDER) context = get_context(self, obj, attr_name) translatable = TaalTranslatableString( context, old_message_id, attr) old_translatables[attr_name] = translatable new_translatables = {} # collect any translatable fields from the new type # also, replace any values in updated_values with placeholders # for the super() call # note that we can't collect the context/message_id until after # we call super(), since they may be about to change # (context will definitely change, and message_id might, if we add or # remove unique attributes) for attr_name in iter_translatables(new_descriptor): attr = updated_values.get(attr_name) if is_translatable_value(attr): updated_values[attr_name] = PLACEHOLDER translatable = TaalTranslatableString( None, None, attr) new_translatables[attr_name] = translatable new_obj = super(Manager, self).change_instance_type( obj, type_id, updated_values) # we are now able to fill in context/message_id for the new object new_message_id = get_message_id(self, new_obj) for attr_name, translatable in new_translatables.items(): translatable.message_id = new_message_id translatable.context = get_context(self, new_obj, attr_name) to_delete = set(old_translatables) - set(new_translatables) to_rename = set(old_translatables) & set(new_translatables) to_add = set(new_translatables) - set(old_translatables) translator = get_translator(self) for key in to_delete: translatable = old_translatables[key] translator.delete_translations(translatable) for key in to_rename: old_translatable = old_translatables[key] new_translatable = new_translatables[key] translator.move_translations(old_translatable, new_translatable) if new_translatable.pending_value is not None: # updated_values contained a key for a field already existing # on the old type. save the updated translation translator.save_translation(new_translatable) for key in to_add: translatable = new_translatables[key] if translatable.pending_value is not None: translator.save_translation(translatable) return new_obj
def change_instance_type(self, obj, type_id, updated_values=None): if updated_values is None: updated_values = {} updated_values = updated_values.copy() old_descriptor = self.type_registry.get_descriptor(type(obj)) new_descriptor = self.type_registry.get_descriptor_by_id(type_id) old_message_id = get_message_id(self, obj) old_translatables = {} # collect any translatable fields on the original object # also, replace any values with placeholders for the super() call for attr_name in iter_translatables(old_descriptor): attr = getattr(obj, attr_name) if is_translatable_value(attr): setattr(obj, attr_name, PLACEHOLDER) context = get_context(self, obj, attr_name) translatable = TaalTranslatableString(context, old_message_id, attr) old_translatables[attr_name] = translatable new_translatables = {} # collect any translatable fields from the new type # also, replace any values in updated_values with placeholders # for the super() call # note that we can't collect the context/message_id until after # we call super(), since they may be about to change # (context will definitely change, and message_id might, if we add or # remove unique attributes) for attr_name in iter_translatables(new_descriptor): attr = updated_values.get(attr_name, MISSING) if attr is None: continue if attr is MISSING: attr = None if is_translatable_value(attr): updated_values[attr_name] = PLACEHOLDER translatable = TaalTranslatableString(None, None, attr) new_translatables[attr_name] = translatable new_obj = super(Manager, self).change_instance_type(obj, type_id, updated_values) # we are now able to fill in context/message_id for the new object new_message_id = get_message_id(self, new_obj) for attr_name, translatable in new_translatables.items(): translatable.message_id = new_message_id translatable.context = get_context(self, new_obj, attr_name) to_delete = set(old_translatables) - set(new_translatables) to_rename = set(old_translatables) & set(new_translatables) to_add = set(new_translatables) - set(old_translatables) translator = get_translator(self) for key in to_delete: translatable = old_translatables[key] translator.delete_translations(translatable) for key in to_rename: old_translatable = old_translatables[key] new_translatable = new_translatables[key] translator.move_translations(old_translatable, new_translatable) if new_translatable.pending_value is not None: # updated_values contained a key for a field already existing # on the old type. save the updated translation translator.save_translation(new_translatable) for key in to_add: translatable = new_translatables[key] if translatable.pending_value is not None: translator.save_translation(translatable) return new_obj