Skip to content

Commit 07353ae

Browse files
committed
Expose file.get_shared_link_download_url method.
Fixes #110
1 parent 2d2a585 commit 07353ae

File tree

5 files changed

+188
-32
lines changed

5 files changed

+188
-32
lines changed

boxsdk/object/file.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,3 +237,53 @@ def metadata(self, scope='global', template='properties'):
237237
:class:`Metadata`
238238
"""
239239
return Metadata(self._session, self, scope, template)
240+
241+
def get_shared_link_download_url(
242+
self,
243+
access=None,
244+
etag=None,
245+
unshared_at=None,
246+
allow_preview=None,
247+
password=None,
248+
):
249+
"""
250+
Get a shared link download url for the file with the given access permissions.
251+
252+
:param access:
253+
Determines who can access the shared link. May be open, company, or collaborators. If no access is
254+
specified, the default access will be used.
255+
:type access:
256+
`unicode` or None
257+
:param etag:
258+
If specified, instruct the Box API to create the link only if the current version's etag matches.
259+
:type etag:
260+
`unicode` or None
261+
:param unshared_at:
262+
The date on which this link should be disabled. May only be set if the current user is not a free user
263+
and has permission to set expiration dates.
264+
:type unshared_at:
265+
:class:`datetime.date` or None
266+
:param allow_preview:
267+
Whether or not the item being shared can be previewed when accessed via the shared link.
268+
If this parameter is None, the default setting will be used.
269+
:type allow_preview:
270+
`bool` or None
271+
:param password:
272+
The password required to view this link. If no password is specified then no password will be set.
273+
Please notice that this is a premium feature, which might not be available to your app.
274+
:type password:
275+
`unicode` or None
276+
:returns:
277+
The URL of the shared link that allows direct download.
278+
:rtype:
279+
`unicode`
280+
:raises: :class:`BoxAPIException` if the specified etag doesn't match the latest version of the item.
281+
"""
282+
item = self.create_shared_link(
283+
access=access,
284+
etag=etag,
285+
unshared_at=unshared_at,
286+
allow_preview=allow_preview,
287+
password=password,
288+
)
289+
return item.shared_link['download_url']

boxsdk/object/item.py

Lines changed: 72 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,17 @@ def move(self, parent_folder):
159159
}
160160
return self.update_info(data)
161161

162-
def get_shared_link(self, access=None, etag=None, unshared_at=None, allow_download=None, allow_preview=None, password=None):
163-
"""Get a shared link for the item with the given access permissions.
162+
def create_shared_link(
163+
self,
164+
access=None,
165+
etag=None,
166+
unshared_at=None,
167+
allow_download=None,
168+
allow_preview=None,
169+
password=None,
170+
):
171+
"""
172+
Create a shared link for the item with the given access permissions.
164173
165174
:param access:
166175
Determines who can access the shared link. May be open, company, or collaborators. If no access is
@@ -191,10 +200,11 @@ def get_shared_link(self, access=None, etag=None, unshared_at=None, allow_downlo
191200
Please notice that this is a premium feature, which might not be available to your app.
192201
:type password:
193202
`unicode` or None
194-
:returns:
195-
The URL of the shared link.
203+
:return:
204+
The updated object with s shared link.
205+
Returns a new object of the same type, without modifying the original object passed as self.
196206
:rtype:
197-
`unicode`
207+
:class:`Item`
198208
:raises: :class:`BoxAPIException` if the specified etag doesn't match the latest version of the item.
199209
"""
200210
data = {
@@ -216,7 +226,63 @@ def get_shared_link(self, access=None, etag=None, unshared_at=None, allow_downlo
216226
if password is not None:
217227
data['shared_link']['password'] = password
218228

219-
item = self.update_info(data, etag=etag)
229+
return self.update_info(data, etag=etag)
230+
231+
def get_shared_link(
232+
self,
233+
access=None,
234+
etag=None,
235+
unshared_at=None,
236+
allow_download=None,
237+
allow_preview=None,
238+
password=None,
239+
):
240+
"""
241+
Get a shared link for the item with the given access permissions.
242+
243+
:param access:
244+
Determines who can access the shared link. May be open, company, or collaborators. If no access is
245+
specified, the default access will be used.
246+
:type access:
247+
`unicode` or None
248+
:param etag:
249+
If specified, instruct the Box API to create the link only if the current version's etag matches.
250+
:type etag:
251+
`unicode` or None
252+
:param unshared_at:
253+
The date on which this link should be disabled. May only be set if the current user is not a free user
254+
and has permission to set expiration dates.
255+
:type unshared_at:
256+
:class:`datetime.date` or None
257+
:param allow_download:
258+
Whether or not the item being shared can be downloaded when accessed via the shared link.
259+
If this parameter is None, the default setting will be used.
260+
:type allow_download:
261+
`bool` or None
262+
:param allow_preview:
263+
Whether or not the item being shared can be previewed when accessed via the shared link.
264+
If this parameter is None, the default setting will be used.
265+
:type allow_preview:
266+
`bool` or None
267+
:param password:
268+
The password required to view this link. If no password is specified then no password will be set.
269+
Please notice that this is a premium feature, which might not be available to your app.
270+
:type password:
271+
`unicode` or None
272+
:returns:
273+
The URL of the shared link.
274+
:rtype:
275+
`unicode`
276+
:raises: :class:`BoxAPIException` if the specified etag doesn't match the latest version of the item.
277+
"""
278+
item = self.create_shared_link(
279+
access=access,
280+
etag=etag,
281+
unshared_at=unshared_at,
282+
allow_download=allow_download,
283+
allow_preview=allow_preview,
284+
password=password,
285+
)
220286
return item.shared_link['url']
221287

222288
def remove_shared_link(self, etag=None):

test/unit/object/conftest.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# coding: utf-8
22

33
from __future__ import unicode_literals
4+
from datetime import date
45
import os
56
from mock import Mock
67
import pytest
@@ -162,3 +163,28 @@ def file_size(request):
162163
def mock_group(mock_box_session, mock_group_id):
163164
group = Group(mock_box_session, mock_group_id)
164165
return group
166+
167+
168+
@pytest.fixture(params=(True, False, None))
169+
def shared_link_can_download(request):
170+
return request.param
171+
172+
173+
@pytest.fixture(params=(True, False, None))
174+
def shared_link_can_preview(request):
175+
return request.param
176+
177+
178+
@pytest.fixture(params=('open', None))
179+
def shared_link_access(request):
180+
return request.param
181+
182+
183+
@pytest.fixture(params=('hunter2', None))
184+
def shared_link_password(request):
185+
return request.param
186+
187+
188+
@pytest.fixture(params=(date(2015, 5, 5), None))
189+
def shared_link_unshared_at(request):
190+
return request.param

test/unit/object/test_file.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,3 +234,43 @@ def test_preflight_check(
234234
expect_json_response=False,
235235
data=expected_data,
236236
)
237+
238+
239+
def test_get_shared_link_download_url(
240+
test_file,
241+
mock_box_session,
242+
shared_link_access,
243+
shared_link_unshared_at,
244+
shared_link_password,
245+
shared_link_can_preview,
246+
test_url,
247+
etag,
248+
if_match_header,
249+
):
250+
# pylint:disable=redefined-outer-name, protected-access
251+
expected_url = test_file.get_url()
252+
mock_box_session.put.return_value.json.return_value = {'shared_link': {'url': None, 'download_url': test_url}}
253+
expected_data = {'shared_link': {}}
254+
if shared_link_access is not None:
255+
expected_data['shared_link']['access'] = shared_link_access
256+
if shared_link_unshared_at is not None:
257+
expected_data['shared_link']['unshared_at'] = shared_link_unshared_at.isoformat()
258+
if shared_link_can_preview is not None:
259+
expected_data['shared_link']['permissions'] = permissions = {}
260+
permissions['can_preview'] = shared_link_can_preview
261+
if shared_link_password is not None:
262+
expected_data['shared_link']['password'] = shared_link_password
263+
url = test_file.get_shared_link_download_url(
264+
etag=etag,
265+
access=shared_link_access,
266+
unshared_at=shared_link_unshared_at,
267+
password=shared_link_password,
268+
allow_preview=shared_link_can_preview,
269+
)
270+
mock_box_session.put.assert_called_once_with(
271+
expected_url,
272+
data=json.dumps(expected_data),
273+
headers=if_match_header,
274+
params=None,
275+
)
276+
assert url == test_url

test/unit/object/test_item.py

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# coding: utf-8
22

33
from __future__ import unicode_literals
4-
from datetime import date
54
import json
65
import pytest
76

@@ -56,31 +55,6 @@ def test_move_item(test_item_and_response, mock_box_session, test_folder, mock_o
5655
assert isinstance(move_response, test_item.__class__)
5756

5857

59-
@pytest.fixture(params=(True, False, None))
60-
def shared_link_can_download(request):
61-
return request.param
62-
63-
64-
@pytest.fixture(params=(True, False, None))
65-
def shared_link_can_preview(request):
66-
return request.param
67-
68-
69-
@pytest.fixture(params=('open', None))
70-
def shared_link_access(request):
71-
return request.param
72-
73-
74-
@pytest.fixture(params=('hunter2', None))
75-
def shared_link_password(request):
76-
return request.param
77-
78-
79-
@pytest.fixture(params=(date(2015, 5, 5), None))
80-
def shared_link_unshared_at(request):
81-
return request.param
82-
83-
8458
def test_get_shared_link(
8559
test_item_and_response,
8660
mock_box_session,

0 commit comments

Comments
 (0)