def set_status(self, rows, status, comment=None): rows_by_batch_id, batch_id = {}, 1 if isinstance(status, int): status = moderation_statuses[status] batches = E.Batch(ListVersion='1', OnError='Return') # Here's the root element of our SOAP request. xml = SP.UpdateListItems(SP.listName(self._list.id), SP.updates(batches)) if comment: comment = E.Field(text_type(comment), Name='_ModerationComment') for row in rows: batch = E.Method(E.Field(text_type(row.id), Name='ID'), E.Field(text_type(status.value), Name='_ModerationStatus'), ID=text_type(batch_id), Cmd='Moderate') if comment: batch.append(comment) rows_by_batch_id[batch_id] = row batches.append(batch) batch_id += 1 response = self._list.opener.post_soap( LIST_WEBSERVICE, xml, soapaction= 'http://schemas.microsoft.com/sharepoint/soap/UpdateListItems') for result in response.xpath('.//sp:Result', namespaces=namespaces): batch_id, batch_result = result.attrib['ID'].split(',') row = rows_by_batch_id[int(batch_id)] error_code = result.find('sp:ErrorCode', namespaces=namespaces) error_text = result.find('sp:ErrorText', namespaces=namespaces) if error_code is not None and error_code.text != '0x00000000': raise UpdateFailedError(row, batch_result, error_code.text, error_text.text) if batch_result == 'Moderate': row._update(result.xpath('z:row', namespaces=namespaces)[0], clear=True)
def save(self): """ Updates the list with changes. """ # Based on the documentation at # http://msdn.microsoft.com/en-us/library/lists.lists.updatelistitems%28v=office.12%29.aspx # Note, this ends up un-namespaced. SharePoint doesn't care about # namespaces on this XML node, and will bork if any of these elements # have a namespace prefix. Likewise Method and Field in # SharePointRow.get_batch_method(). batches = E.Batch(ListVersion='1', OnError='Return') # Here's the root element of our SOAP request. xml = SP.UpdateListItems(SP.listName(self.id), SP.updates(batches)) # rows_by_batch_id contains a mapping from new rows to their batch # IDs, so we can set their IDs when they are returned by SharePoint. rows_by_batch_id, batch_id = {}, 1 for row in self._rows: batch = row.get_batch_method() if batch is None: continue # Add the batch ID batch.attrib['ID'] = text_type(batch_id) rows_by_batch_id[batch_id] = row batches.append(batch) batch_id += 1 for row in self._deleted_rows: batch = E.Method(E.Field(text_type(row.id), Name='ID'), ID=text_type(batch_id), Cmd='Delete') rows_by_batch_id[batch_id] = row batches.append(batch) batch_id += 1 if len(batches) == 0: return response = self.opener.post_soap( LIST_WEBSERVICE, xml, soapaction= 'http://schemas.microsoft.com/sharepoint/soap/UpdateListItems') for result in response.xpath('.//sp:Result', namespaces=namespaces): batch_id, batch_result = result.attrib['ID'].split(',') row = rows_by_batch_id[int(batch_id)] error_code = result.find('sp:ErrorCode', namespaces=namespaces) error_text = result.find('sp:ErrorText', namespaces=namespaces) if error_code is not None and error_code.text != '0x00000000': raise UpdateFailedError(row, batch_result, error_code.text, error_text.text) if batch_result in ('Update', 'New'): row._update(result.xpath('z:row', namespaces=namespaces)[0], clear=True) else: self._deleted_rows.remove(row) assert not self._deleted_rows assert not any(row._changed for row in self.rows)