Ejemplo n.º 1
0
 def get_rows(self, folder=''):
     rows = []
     attribs = collections.defaultdict(dict)
     field_groups, lookup_count = [[]], 0
     for field in self.fields.values():
         if isinstance(field, (UserField, LookupField)):
             lookup_count += 1
         if lookup_count >= 8:
             lookup_count = 0
             field_groups.append([])
         field_groups[-1].append(field)
     for field_group in field_groups:
         # Request all fields, not just the ones in the default view
         view_fields = E.ViewFields(*(E.FieldRef(Name=field.name) for field in field_group))
         #query_options = E.QueryOptions(E.ViewAttributes(Scope="Recursive"))
         query_options = E.QueryOptions(E.Folder(folder))
         xml = SP.GetListItems(SP.listName(self.id),
                               SP.rowLimit("100000"),
                               SP.viewFields(view_fields),
                               SP.queryOptions(query_options))
         response = self.opener.post_soap(LIST_WEBSERVICE, xml)
         for row in list(response[0][0][0]):
             attrib = attribs[row.attrib['ows_ID']]
             attrib.update(row.attrib)
         for attrib in attribs.values():
             rows.append(self.Row(attrib=attrib))
     return list(rows)
Ejemplo n.º 2
0
 def get_rows(self, folder=''):
     rows = []
     attribs = collections.defaultdict(dict)
     field_groups, lookup_count = [[]], 0
     for field in self.fields.values():
         if isinstance(field, (UserField, LookupField)):
             lookup_count += 1
         if lookup_count >= 8:
             lookup_count = 0
             field_groups.append([])
         field_groups[-1].append(field)
     for field_group in field_groups:
         # Request all fields, not just the ones in the default view
         view_fields = E.ViewFields(*(E.FieldRef(Name=field.name)
                                      for field in field_group))
         #query_options = E.QueryOptions(E.ViewAttributes(Scope="Recursive"))
         query_options = E.QueryOptions(E.Folder(folder))
         xml = SP.GetListItems(SP.listName(self.id), SP.rowLimit("100000"),
                               SP.viewFields(view_fields),
                               SP.queryOptions(query_options))
         response = self.opener.post_soap(LIST_WEBSERVICE, xml)
         for row in list(response[0][0][0]):
             attrib = attribs[row.attrib['ows_ID']]
             attrib.update(row.attrib)
     for attrib in attribs.values():
         rows.append(self.Row(attrib=attrib))
     return list(rows)
Ejemplo n.º 3
0
    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"] = unicode(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(unicode(row.id), Name="ID"), ID=unicode(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)
Ejemplo n.º 4
0
 def remove(self, list):
     """
     Removes a list from the site.
     """
     xml = SP.DeleteList(SP.listName(list.id))
     self.opener.post_soap(
         LIST_WEBSERVICE,
         xml,
         soapaction='http://schemas.microsoft.com/sharepoint/soap/DeleteList'
     )
     self.all_lists.remove(list)
Ejemplo n.º 5
0
    def __iter__(self):
        """
        Returns an iterator over attachments for a list item.

        Implements http://msdn.microsoft.com/en-us/library/websvclists.lists.getattachmentcollection.aspx
        """
        xml = SP.GetAttachmentCollection(SP.listName(self.list_id),
                                         SP.listItemID(str(self.row_id)))
        response = self.opener.post_soap(LIST_WEBSERVICE, xml,
                                         soapaction='http://schemas.microsoft.com/sharepoint/soap/GetAttachmentCollection')
        for url in response.xpath('//sp:Attachment', namespaces=namespaces):
            yield SharePointAttachment(self, url.text)
Ejemplo n.º 6
0
    def __iter__(self):
        """
        Returns an iterator over attachments for a list item.

        Implements http://msdn.microsoft.com/en-us/library/websvclists.lists.getattachmentcollection.aspx
        """
        xml = SP.GetAttachmentCollection(SP.listName(self.list_id),
                                         SP.listItemID(str(self.row_id)))
        response = self.opener.post_soap(
            LIST_WEBSERVICE, xml,
            soapaction='http://schemas.microsoft.com/sharepoint/soap/GetAttachmentCollection')
        for url in response.xpath('//sp:Attachment', namespaces=namespaces):
            yield SharePointAttachment(self, url.text)
Ejemplo n.º 7
0
 def remove(self, list):
     """
     Removes a list from the site.
     """
     xml = SP.DeleteList(SP.listName(list.id))
     result = self.opener.post_soap(LIST_WEBSERVICE, xml,
                                    soapaction='http://schemas.microsoft.com/sharepoint/soap/DeleteList')
     self.all_lists.remove(list)
Ejemplo n.º 8
0
    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)
Ejemplo n.º 9
0
 def create(self, name, description="", template=100):
     """
     Creates a new list in the site.
     """
     try:
         template = int(template)
     except ValueError:
         template = LIST_TEMPLATES[template]
     if name in self:
         raise ValueError("List already exists: '{0}".format(name))
     if uuid_re.match(name):
         raise ValueError("Cannot create a list with a UUID as a name")
     xml = SP.AddList(SP.listName(name), SP.description(description), SP.templateID(unicode(template)))
     result = self.opener.post_soap(
         LIST_WEBSERVICE, xml, soapaction="http://schemas.microsoft.com/sharepoint/soap/AddList"
     )
     list_element = result.xpath("sp:AddListResult/sp:List", namespaces=namespaces)[0]
     self._all_lists.append(SharePointList(self.opener, self, list_element))
Ejemplo n.º 10
0
    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)
Ejemplo n.º 11
0
    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(unicode(comment), Name="_ModerationComment")

        for row in rows:
            batch = E.Method(
                E.Field(unicode(row.id), Name="ID"),
                E.Field(unicode(status.value), Name="_ModerationStatus"),
                ID=unicode(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)
Ejemplo n.º 12
0
 def create(self, name, description='', template=100):
     """
     Creates a new list in the site.
     """
     try:
         template = int(template)
     except ValueError:
         template = LIST_TEMPLATES[template]
     if name in self:
         raise ValueError("List already exists: '{0}".format(name))
     if uuid_re.match(name):
         raise ValueError("Cannot create a list with a UUID as a name")
     xml = SP.AddList(SP.listName(name), SP.description(description),
                      SP.templateID(text_type(template)))
     result = self.opener.post_soap(
         LIST_WEBSERVICE,
         xml,
         soapaction='http://schemas.microsoft.com/sharepoint/soap/AddList')
     list_element = result.xpath('sp:AddListResult/sp:List',
                                 namespaces=namespaces)[0]
     self._all_lists.append(SharePointList(self.opener, self, list_element))
Ejemplo n.º 13
0
    def all_lists(self):
        if not hasattr(self, '_all_lists'):
            xml = SP.GetListCollection()
            result = self.opener.post_soap(LIST_WEBSERVICE, xml)

            self._all_lists = []
            for list_element in result.xpath(
                    'sp:GetListCollectionResult/sp:Lists/sp:List',
                    namespaces=namespaces):
                self._all_lists.append(
                    SharePointList(self.opener, self, list_element))

            # Explicitly request information about the UserInfo list.
            # This can be accessed with the name "User Information List"
            result = self.opener.post_soap(LIST_WEBSERVICE,
                                           SP.GetList(SP.listName("UserInfo")))
            list_element = result.xpath('.//sp:List', namespaces=namespaces)[0]
            self._all_lists.append(
                SharePointList(self.opener, self, list_element))

        return self._all_lists
Ejemplo n.º 14
0
    def rows(self):
        if not hasattr(self, "_rows"):
            attribs = collections.defaultdict(dict)
            field_groups, lookup_count = [[]], 0
            for field in self.fields.values():
                if isinstance(field, (UserField, LookupField)):
                    lookup_count += 1
                if lookup_count >= 8:
                    lookup_count = 0
                    field_groups.append([])
                field_groups[-1].append(field)
            for field_group in field_groups:
                # Request all fields, not just the ones in the default view
                view_fields = E.ViewFields(*(E.FieldRef(Name=field.name) for field in field_group))
                xml = SP.GetListItems(SP.listName(self.id), SP.rowLimit("100000"), SP.viewFields(view_fields))
                response = self.opener.post_soap(LIST_WEBSERVICE, xml)
                for row in list(response[0][0][0]):
                    attrib = attribs[row.attrib["ows_ID"]]
                    attrib.update(row.attrib)

            self._rows = []
            for attrib in attribs.values():
                self._rows.append(self.Row(attrib=attrib))
        return list(self._rows)
Ejemplo n.º 15
0
    def all_lists(self):
        if not hasattr(self, '_all_lists'):
            xml = SP.GetListCollection()
            result = self.opener.post_soap(LIST_WEBSERVICE, xml)
    
            self._all_lists = []
            for list_element in result.xpath('sp:GetListCollectionResult/sp:Lists/sp:List', namespaces=namespaces):
                self._all_lists.append(SharePointList(self.opener, self, list_element))
            
            # Explicitly request information about the UserInfo list.
            # This can be accessed with the name "User Information List"
            result = self.opener.post_soap(LIST_WEBSERVICE, SP.GetList(SP.listName("UserInfo")))
            list_element = result.xpath('.//sp:List', namespaces=namespaces)[0]
            self._all_lists.append(SharePointList(self.opener, self, list_element))

        return self._all_lists
Ejemplo n.º 16
0
 def settings(self):
     if self._settings is None or not len(self._settings):
         xml = SP.GetList(SP.listName(self.id))
         response = self.opener.post_soap(LIST_WEBSERVICE, xml)
         self._settings = response[0][0]
     return self._settings
Ejemplo n.º 17
0
 def delete(self, url):
     xml = SP.DeleteAttachment(SP.listName(self.list_id), SP.listItemID(str(self.row_id)), SP.url(url))
     response = self.opener.post_soap(LIST_WEBSERVICE, xml, 
                                      soapaction='http://schemas.microsoft.com/sharepoint/soap/DeleteAttachment')
Ejemplo n.º 18
0
 def settings(self):
     if self._settings is None or not len(self._settings):
         xml = SP.GetList(SP.listName(self.id))
         response = self.opener.post_soap(LIST_WEBSERVICE, xml)
         self._settings = response[0][0]
     return self._settings
Ejemplo n.º 19
0
 def add(self, filename, content):
     xml = SP.AddAttachment(SP.listName(self.list_id), SP.listItemID(str(self.row_id)), SP.fileName(filename), SP.attachment(content))
     response = self.opener.post_soap(LIST_WEBSERVICE, xml,
                                      soapaction='http://schemas.microsoft.com/sharepoint/soap/AddAttachment')
Ejemplo n.º 20
0
    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)