Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def _get_set_item_elems(self, item_model, field, value):
from ..fields import FieldPath, IndexedField
from ..indexed_properties import MultiFieldIndexedElement
if isinstance(field, IndexedField):
# TODO: Maybe the set/delete logic should extend into subfields, not just overwrite the whole item.
for v in value:
# TODO: We should also delete the labels that no longer exist in the list
if issubclass(field.value_cls, MultiFieldIndexedElement):
# We have subfields. Generate SetItem XML for each subfield. SetItem only accepts items that
# have the one value set that we want to change. Create a new IndexedField object that has
# only that value set.
for subfield in field.value_cls.supported_fields(version=self.account.version):
yield self._set_item_elem(
item_model=item_model,
field_path=FieldPath(field=field, label=v.label, subfield=subfield),
value=field.value_cls(**{'label': v.label, subfield.name: getattr(v, subfield.name)}),
)
else:
# The simpler IndexedFields with only one subfield
subfield = field.value_cls.value_field(version=self.account.version)
yield self._set_item_elem(
item_model=item_model,
field_path=FieldPath(field=field, label=v.label, subfield=subfield),
value=v,
)
else:
yield self._set_item_elem(item_model=item_model, field_path=FieldPath(field=field), value=value)
for subfield in field.value_cls.supported_fields(version=self.account.version):
yield self._set_item_elem(
item_model=item_model,
field_path=FieldPath(field=field, label=v.label, subfield=subfield),
value=field.value_cls(**{'label': v.label, subfield.name: getattr(v, subfield.name)}),
)
else:
# The simpler IndexedFields with only one subfield
subfield = field.value_cls.value_field(version=self.account.version)
yield self._set_item_elem(
item_model=item_model,
field_path=FieldPath(field=field, label=v.label, subfield=subfield),
value=v,
)
else:
yield self._set_item_elem(item_model=item_model, field_path=FieldPath(field=field), value=value)
if issubclass(field.value_cls, MultiFieldIndexedElement):
# We have subfields. Generate SetItem XML for each subfield. SetItem only accepts items that
# have the one value set that we want to change. Create a new IndexedField object that has
# only that value set.
for subfield in field.value_cls.supported_fields(version=self.account.version):
yield self._set_item_elem(
item_model=item_model,
field_path=FieldPath(field=field, label=v.label, subfield=subfield),
value=field.value_cls(**{'label': v.label, subfield.name: getattr(v, subfield.name)}),
)
else:
# The simpler IndexedFields with only one subfield
subfield = field.value_cls.value_field(version=self.account.version)
yield self._set_item_elem(
item_model=item_model,
field_path=FieldPath(field=field, label=v.label, subfield=subfield),
value=v,
)
else:
yield self._set_item_elem(item_model=item_model, field_path=FieldPath(field=field), value=value)
def get_folder_fields(self, is_complex=None):
additional_fields = set()
for folder in self.folders:
if isinstance(folder, Folder):
additional_fields.update(
FieldPath(field=f) for f in folder.supported_fields(version=self.account.version)
if is_complex is None or f.is_complex is is_complex
)
else:
additional_fields.update(
FieldPath(field=f) for f in Folder.supported_fields(version=self.account.version)
if is_complex is None or f.is_complex is is_complex
)
return additional_fields
def _query(self):
from .folders import SHALLOW
from .items import Persona
if self.only_fields is None:
# We didn't restrict list of field paths. Get all fields from the server, including extended properties.
if self.request_type == self.PERSONA:
additional_fields = {FieldPath(field=f) for f in Persona.supported_fields(
version=self.folder_collection.account.version
) if not f.is_complex}
complex_fields_requested = False
else:
additional_fields = {FieldPath(field=f) for f in self.folder_collection.allowed_item_fields()}
complex_fields_requested = True
else:
additional_fields = self._additional_fields()
complex_fields_requested = any(f.field.is_complex for f in additional_fields)
# EWS can do server-side sorting on multiple fields. A caveat is that server-side sorting is not supported
# for calendar views. In this case, we do all the sorting client-side.
if self.calendar_view:
must_sort_clientside = bool(self.order_fields)
order_fields = None
else:
def get_folder_fields(self, target_cls, is_complex=None):
return {
FieldPath(field=f) for f in target_cls.supported_fields(version=self.account.version)
if is_complex is None or f.is_complex is is_complex
}
def _get_field_order(self, field_path):
from .items import Persona
if self.request_type == self.PERSONA:
return FieldOrder(
field_path=FieldPath(field=Persona.get_field_by_fieldname(field_path.lstrip('-'))),
reverse=field_path.startswith('-'),
)
for folder in self.folder_collection:
try:
return FieldOrder.from_string(field_path=field_path, folder=folder)
except InvalidField:
pass
raise InvalidField("Unknown field path %r on folders %s" % (field_path, self.folder_collection.folders))
def _get_field_path(self, folders, applies_to, version):
# Convert the string field path to a real FieldPath object. The path is validated using the given folders.
from .fields import FieldPath
for folder in folders:
try:
if applies_to == Restriction.FOLDERS:
# This is a restriction on Folder fields
field = folder.get_field_by_fieldname(fieldname=self.field_path)
field_path = FieldPath(field=field)
else:
field_path = FieldPath.from_string(field_path=self.field_path, folder=folder)
except ValueError:
continue
self._validate_field_path(field_path=field_path, folder=folder, applies_to=applies_to, version=version)
break
else:
raise InvalidField("Unknown field path %r on folders %s" % (self.field_path, folders))
return field_path
for fieldname in self._sort_fieldnames(folder_model=folder_model, fieldnames=fieldnames_set):
field = folder_model.get_field_by_fieldname(fieldname)
if field.is_read_only:
raise ValueError('%s is a read-only field' % field.name)
value = field.clean(getattr(folder, field.name), version=self.account.version) # Make sure the value is OK
if value is None or (field.is_list and not value):
# A value of None or [] means we want to remove this field from the item
if field.is_required or field.is_required_after_save:
raise ValueError('%s is a required field and may not be deleted' % field.name)
for field_path in FieldPath(field=field).expand(version=self.account.version):
yield self._delete_folder_elem(field_path=field_path)
continue
yield self._set_folder_elem(folder_model=folder_model, field_path=FieldPath(field=field), value=value)
def _get_delete_item_elems(self, field):
from .fields import FieldPath
if field.is_required or field.is_required_after_save:
raise ValueError('%s is a required field and may not be deleted' % field.name)
for field_path in FieldPath(field=field).expand(version=self.account.version):
yield self._delete_item_elem(field_path=field_path)