-
-
Notifications
You must be signed in to change notification settings - Fork 318
/
attachment.py
118 lines (96 loc) · 4.21 KB
/
attachment.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
from typing import AnyStr, Optional
from office365.runtime.client_result import ClientResult
from office365.runtime.queries.service_operation import ServiceOperationQuery
from office365.sharepoint.entity import Entity
from office365.sharepoint.internal.queries.upload_file import create_upload_file_query
from office365.sharepoint.types.resource_path import ResourcePath as SPResPath
class Attachment(Entity):
"""Represents an attachment file in a SharePoint List Item."""
def download(self, file_object, use_path=True):
"""Download attachment file
:type file_object: typing.IO
:param bool use_path: Use Path instead of Url for addressing attachments
"""
def _save_content(return_type):
# type: (ClientResult[AnyStr]) -> None
file_object.write(return_type.value)
def _download_file_by_path():
file = self.context.web.get_file_by_server_relative_path(
str(self.server_relative_path)
)
file.get_content().after_execute(_save_content)
def _download_file_by_url():
file = self.context.web.get_file_by_server_relative_url(
self.server_relative_url
)
file.get_content().after_execute(_save_content)
if use_path:
self.ensure_property("ServerRelativePath", _download_file_by_path)
else:
self.ensure_property("ServerRelativeUrl", _download_file_by_url)
return self
def recycle_object(self):
"""Move this attachment to site recycle bin."""
qry = ServiceOperationQuery(self, "RecycleObject")
self.context.add_query(qry)
return self
def upload(self, file_object, use_path=True):
"""
Upload attachment into list item
:type file_object: typing.IO
:param bool use_path: Use Path instead of Url for addressing attachments
"""
def _upload_file_by_url():
target_file = self.context.web.get_file_by_server_relative_url(
self.server_relative_url
)
qry = create_upload_file_query(target_file, file_object)
self.context.add_query(qry)
def _upload_file_by_path():
target_file = self.context.web.get_file_by_server_relative_path(
str(self.server_relative_path)
)
qry = create_upload_file_query(target_file, file_object)
self.context.add_query(qry)
if use_path:
self.ensure_property("ServerRelativePath", _upload_file_by_path)
else:
self.ensure_property("ServerRelativeUrl", _upload_file_by_url)
return self
@property
def file_name(self):
# type: () -> Optional[str]
"""Specifies the file name of the list item attachment."""
return self.properties.get("FileName", None)
@property
def file_name_as_path(self):
"""The file name of the attachment as a SP.ResourcePath."""
return self.properties.get("FileNameAsPath", SPResPath())
@property
def server_relative_url(self):
# type: () -> Optional[str]
""" """
return self.properties.get("ServerRelativeUrl", None)
@property
def server_relative_path(self):
"""The server-relative-path of the attachment."""
return self.properties.get("ServerRelativePath", SPResPath())
@property
def property_ref_name(self):
return "FileName"
def set_property(self, name, value, persist_changes=True):
super(Attachment, self).set_property(name, value, persist_changes)
# fallback: create a new resource path
if self._resource_path is None:
if name == "ServerRelativeUrl":
self._resource_path = self.context.web.get_file_by_server_relative_url(
value
).resource_path
def get_property(self, name, default_value=None):
if default_value is None:
property_mapping = {
"FileNameAsPath": self.file_name_as_path,
"ServerRelativePath": self.server_relative_path,
}
default_value = property_mapping.get(name, None)
return super(Attachment, self).get_property(name, default_value)