Merge lp:~facundo/magicicada-protocol/publicfiles into lp:magicicada-protocol

Proposed by Facundo Batista
Status: Merged
Approved by: Natalia Bidart
Approved revision: 170
Merged at revision: 169
Proposed branch: lp:~facundo/magicicada-protocol/publicfiles
Merge into: lp:magicicada-protocol
Diff against target: 715 lines (+406/-59)
5 files modified
tests/test_client.py (+182/-49)
tests/test_public_file_info.py (+74/-0)
ubuntuone/storageprotocol/client.py (+71/-8)
ubuntuone/storageprotocol/protocol.proto (+24/-2)
ubuntuone/storageprotocol/public_file_info.py (+55/-0)
To merge this branch: bzr merge lp:~facundo/magicicada-protocol/publicfiles
Reviewer Review Type Date Requested Status
Natalia Bidart Approve
Review via email: mp+310154@code.launchpad.net

Commit message

Protocol infrastructure to support public files change and listing.

Description of the change

Protocol infrastructure to support public files change and listing.

To post a comment you must log in.
Revision history for this message
Natalia Bidart (nataliabidart) :
Revision history for this message
Facundo Batista (facundo) wrote :

Comments addressed

170. By Facundo Batista

Import order.

Revision history for this message
Natalia Bidart (nataliabidart) wrote :

LGTM Thanks!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'tests/test_client.py'
--- tests/test_client.py 2016-09-19 02:00:32 +0000
+++ tests/test_client.py 2016-11-15 23:38:26 +0000
@@ -1,6 +1,7 @@
1# -*- coding: utf-8 -*-1# -*- coding: utf-8 -*-
2#2
3# Copyright (C) 2009-2015 Canonical Ltd.3# Copyright 2009-2015 Canonical Ltd.
4# Copyright 2016 Chicharreros (https://launchpad.net/~chicharreros)
4#5#
5# This program is free software: you can redistribute it and/or modify it6# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU Affero General Public License version 3,7# under the terms of the GNU Affero General Public License version 3,
@@ -26,6 +27,7 @@
26# do not wish to do so, delete this exception statement from your27# do not wish to do so, delete this exception statement from your
27# version. If you delete this exception statement from all source28# version. If you delete this exception statement from all source
28# files in the program, then also delete it here.29# files in the program, then also delete it here.
30
29"""Tests for the protocol client."""31"""Tests for the protocol client."""
3032
31import StringIO33import StringIO
@@ -42,8 +44,20 @@
4244
43from ubuntuone.storageprotocol import protocol_pb2, sharersp, delta, request45from ubuntuone.storageprotocol import protocol_pb2, sharersp, delta, request
44from ubuntuone.storageprotocol.client import (46from ubuntuone.storageprotocol.client import (
45 StorageClient, CreateUDF, ListVolumes, DeleteVolume, GetDelta, Unlink,47 Authenticate,
46 Authenticate, MakeFile, MakeDir, PutContent, Move, BytesMessageProducer,48 BytesMessageProducer,
49 ChangePublicAccess,
50 CreateUDF,
51 DeleteVolume,
52 GetDelta,
53 ListPublicFiles,
54 ListVolumes,
55 MakeDir,
56 MakeFile,
57 Move,
58 PutContent,
59 StorageClient,
60 Unlink,
47)61)
4862
49from ubuntuone.storageprotocol import volumes63from ubuntuone.storageprotocol import volumes
@@ -61,6 +75,7 @@
61NODE = uuid.UUID('FEDCBA98-7654-3211-2345-6789ABCDEF12')75NODE = uuid.UUID('FEDCBA98-7654-3211-2345-6789ABCDEF12')
62USER = u'Dude'76USER = u'Dude'
63GENERATION = 99977GENERATION = 999
78PUBLIC_URL = "http://magicicada/someid"
6479
6580
66class FakedError(Exception):81class FakedError(Exception):
@@ -308,7 +323,7 @@
308 self.client.set_share_change_callback(a_callback)323 self.client.set_share_change_callback(a_callback)
309 self.assertTrue(self.client._share_change_callback is a_callback)324 self.assertTrue(self.client._share_change_callback is a_callback)
310 self.client.handle_NOTIFY_SHARE(proto_msg)325 self.client.handle_NOTIFY_SHARE(proto_msg)
311 self.assertEquals(self.share_notif.share_id, share_resp.share_id)326 self.assertEqual(self.share_notif.share_id, share_resp.share_id)
312327
313 def test_share_delete_callback(self):328 def test_share_delete_callback(self):
314 """Test share_delete callback usage."""329 """Test share_delete callback usage."""
@@ -329,7 +344,7 @@
329 self.client.set_share_delete_callback(a_callback)344 self.client.set_share_delete_callback(a_callback)
330 self.assertTrue(self.client._share_delete_callback is a_callback)345 self.assertTrue(self.client._share_delete_callback is a_callback)
331 self.client.handle_SHARE_DELETED(proto_msg)346 self.client.handle_SHARE_DELETED(proto_msg)
332 self.assertEquals(self.deleted_share_id, share_id)347 self.assertEqual(self.deleted_share_id, share_id)
333348
334 def test_share_answer_callback(self):349 def test_share_answer_callback(self):
335 """Test share_answer callback usage."""350 """Test share_answer callback usage."""
@@ -351,8 +366,8 @@
351 self.client.set_share_answer_callback(a_callback)366 self.client.set_share_answer_callback(a_callback)
352 self.assertTrue(self.client._share_answer_callback is a_callback)367 self.assertTrue(self.client._share_answer_callback is a_callback)
353 self.client.handle_SHARE_ACCEPTED(proto_msg)368 self.client.handle_SHARE_ACCEPTED(proto_msg)
354 self.assertEquals(self.answer[0], share_id)369 self.assertEqual(self.answer[0], share_id)
355 self.assertEquals(self.answer[1], "Yes")370 self.assertEqual(self.answer[1], "Yes")
356371
357 def test_handle_volume_new_generation_uuid(self):372 def test_handle_volume_new_generation_uuid(self):
358 """Test handle_VOLUME_NEW_GENERATION with an uuid id."""373 """Test handle_VOLUME_NEW_GENERATION with an uuid id."""
@@ -415,7 +430,7 @@
415 root = volumes.RootVolume.from_msg(message.volume_created.root)430 root = volumes.RootVolume.from_msg(message.volume_created.root)
416431
417 self.client.handle_VOLUME_CREATED(message)432 self.client.handle_VOLUME_CREATED(message)
418 self.assertEquals(root, self.volume)433 self.assertEqual(root, self.volume)
419434
420 def test_handle_udf_created_passes_a_udf(self):435 def test_handle_udf_created_passes_a_udf(self):
421 """Test handle_VOLUME_CREATED parameter passing."""436 """Test handle_VOLUME_CREATED parameter passing."""
@@ -431,7 +446,7 @@
431 udf = volumes.UDFVolume.from_msg(message.volume_created.udf)446 udf = volumes.UDFVolume.from_msg(message.volume_created.udf)
432447
433 self.client.handle_VOLUME_CREATED(message)448 self.client.handle_VOLUME_CREATED(message)
434 self.assertEquals(udf, self.volume)449 self.assertEqual(udf, self.volume)
435450
436 def test_handle_share_created_passes_a_share(self):451 def test_handle_share_created_passes_a_share(self):
437 """Test handle_VOLUME_CREATED parameter passing."""452 """Test handle_VOLUME_CREATED parameter passing."""
@@ -447,7 +462,7 @@
447 share = volumes.ShareVolume.from_msg(message.volume_created.share)462 share = volumes.ShareVolume.from_msg(message.volume_created.share)
448463
449 self.client.handle_VOLUME_CREATED(message)464 self.client.handle_VOLUME_CREATED(message)
450 self.assertEquals(share, self.volume)465 self.assertEqual(share, self.volume)
451466
452 def test_handle_volume_created_if_callback_is_none(self):467 def test_handle_volume_created_if_callback_is_none(self):
453 """Test handle_VOLUME_CREATED if callback is none."""468 """Test handle_VOLUME_CREATED if callback is none."""
@@ -478,7 +493,7 @@
478 message.volume_deleted.volume = str(VOLUME)493 message.volume_deleted.volume = str(VOLUME)
479 self.client.handle_VOLUME_DELETED(message)494 self.client.handle_VOLUME_DELETED(message)
480495
481 self.assertEquals(VOLUME, self.volume)496 self.assertEqual(VOLUME, self.volume)
482497
483 def test_handle_volume_deleted_if_none(self):498 def test_handle_volume_deleted_if_none(self):
484 """Test handle_VOLUME_DELETED if callback is none."""499 """Test handle_VOLUME_DELETED if callback is none."""
@@ -515,8 +530,8 @@
515530
516 def test_init(self):531 def test_init(self):
517 """Test request creation."""532 """Test request creation."""
518 self.assertEquals(PATH, self.request.path)533 self.assertEqual(PATH, self.request.path)
519 self.assertEquals(NAME, self.request.name)534 self.assertEqual(NAME, self.request.name)
520 self.assertTrue(self.request.volume_id is None)535 self.assertTrue(self.request.volume_id is None)
521 self.assertTrue(self.request.node_id is None)536 self.assertTrue(self.request.node_id is None)
522537
@@ -524,11 +539,11 @@
524 """Test request start."""539 """Test request start."""
525 self.request.start()540 self.request.start()
526541
527 self.assertEquals(1, len(self.request.protocol.messages))542 self.assertEqual(1, len(self.request.protocol.messages))
528 actual_msg, = self.request.protocol.messages543 actual_msg, = self.request.protocol.messages
529 self.assertEquals(protocol_pb2.Message.CREATE_UDF, actual_msg.type)544 self.assertEqual(protocol_pb2.Message.CREATE_UDF, actual_msg.type)
530 self.assertEquals(self.request.path, actual_msg.create_udf.path)545 self.assertEqual(self.request.path, actual_msg.create_udf.path)
531 self.assertEquals(self.request.name, actual_msg.create_udf.name)546 self.assertEqual(self.request.name, actual_msg.create_udf.name)
532547
533 def test_process_message_error(self):548 def test_process_message_error(self):
534 """Test request processMessage on error."""549 """Test request processMessage on error."""
@@ -544,8 +559,8 @@
544 message.volume_created.udf.node = str(NODE)559 message.volume_created.udf.node = str(NODE)
545 self.request.processMessage(message)560 self.request.processMessage(message)
546561
547 self.assertEquals(str(VOLUME), self.request.volume_id, 'volume set')562 self.assertEqual(str(VOLUME), self.request.volume_id, 'volume set')
548 self.assertEquals(str(NODE), self.request.node_id, 'node set')563 self.assertEqual(str(NODE), self.request.node_id, 'node set')
549 self.assertTrue(self.done_called, 'done() was called')564 self.assertTrue(self.done_called, 'done() was called')
550565
551566
@@ -566,15 +581,15 @@
566581
567 def test_init(self):582 def test_init(self):
568 """Test request creation."""583 """Test request creation."""
569 self.assertEquals([], self.request.volumes)584 self.assertEqual([], self.request.volumes)
570585
571 def test_start(self):586 def test_start(self):
572 """Test request start."""587 """Test request start."""
573 self.request.start()588 self.request.start()
574589
575 self.assertEquals(1, len(self.request.protocol.messages))590 self.assertEqual(1, len(self.request.protocol.messages))
576 actual_msg, = self.request.protocol.messages591 actual_msg, = self.request.protocol.messages
577 self.assertEquals(protocol_pb2.Message.LIST_VOLUMES, actual_msg.type)592 self.assertEqual(protocol_pb2.Message.LIST_VOLUMES, actual_msg.type)
578593
579 def test_process_message_error(self):594 def test_process_message_error(self):
580 """Test request processMessage on error."""595 """Test request processMessage on error."""
@@ -598,10 +613,9 @@
598 root = volumes.RootVolume.from_msg(message.list_volumes.root)613 root = volumes.RootVolume.from_msg(message.list_volumes.root)
599 self.request.processMessage(message)614 self.request.processMessage(message)
600615
601 self.assertEquals(3, len(self.request.volumes),616 self.assertEqual(3, len(self.request.volumes), '3 volumes stored')
602 '3 volumes stored')617 self.assertEqual([udf, share, root], self.request.volumes,
603 self.assertEquals([udf, share, root], self.request.volumes,618 'volumes stored')
604 'volumes stored')
605619
606 message = protocol_pb2.Message()620 message = protocol_pb2.Message()
607 message.type = protocol_pb2.Message.VOLUMES_END621 message.type = protocol_pb2.Message.VOLUMES_END
@@ -622,7 +636,7 @@
622 self.request.processMessage(message)636 self.request.processMessage(message)
623637
624 self.request.start()638 self.request.start()
625 self.assertEquals([], self.request.volumes)639 self.assertEqual([], self.request.volumes)
626640
627641
628class DeleteVolumeTestCase(RequestTestCase):642class DeleteVolumeTestCase(RequestTestCase):
@@ -642,17 +656,17 @@
642656
643 def test_init(self):657 def test_init(self):
644 """Test request creation."""658 """Test request creation."""
645 self.assertEquals(str(VOLUME), self.request.volume_id)659 self.assertEqual(str(VOLUME), self.request.volume_id)
646660
647 def test_start(self):661 def test_start(self):
648 """Test request start."""662 """Test request start."""
649 self.request.start()663 self.request.start()
650664
651 self.assertEquals(1, len(self.request.protocol.messages))665 self.assertEqual(1, len(self.request.protocol.messages))
652 actual_msg, = self.request.protocol.messages666 actual_msg, = self.request.protocol.messages
653 self.assertEquals(protocol_pb2.Message.DELETE_VOLUME, actual_msg.type)667 self.assertEqual(protocol_pb2.Message.DELETE_VOLUME, actual_msg.type)
654 self.assertEquals(self.request.volume_id,668 self.assertEqual(self.request.volume_id,
655 actual_msg.delete_volume.volume)669 actual_msg.delete_volume.volume)
656670
657 def test_process_message_error(self):671 def test_process_message_error(self):
658 """Test request processMessage on error."""672 """Test request processMessage on error."""
@@ -685,17 +699,17 @@
685699
686 def test_init(self):700 def test_init(self):
687 """Test request creation."""701 """Test request creation."""
688 self.assertEquals(str(SHARE), self.request.share_id)702 self.assertEqual(str(SHARE), self.request.share_id)
689703
690 def test_start(self):704 def test_start(self):
691 """Test request start."""705 """Test request start."""
692 self.request.start()706 self.request.start()
693707
694 self.assertEquals(1, len(self.request.protocol.messages))708 self.assertEqual(1, len(self.request.protocol.messages))
695 actual_msg, = self.request.protocol.messages709 actual_msg, = self.request.protocol.messages
696 self.assertEquals(protocol_pb2.Message.GET_DELTA, actual_msg.type)710 self.assertEqual(protocol_pb2.Message.GET_DELTA, actual_msg.type)
697 self.assertEquals(self.request.share_id,711 self.assertEqual(self.request.share_id,
698 actual_msg.get_delta.share)712 actual_msg.get_delta.share)
699713
700 def test_process_message_error(self):714 def test_process_message_error(self):
701 """Test request processMessage on error."""715 """Test request processMessage on error."""
@@ -712,11 +726,11 @@
712 self.request.processMessage(message)726 self.request.processMessage(message)
713727
714 self.assertTrue(self.done_called, 'done() was called')728 self.assertTrue(self.done_called, 'done() was called')
715 self.assertEquals(self.request.end_generation,729 self.assertEqual(self.request.end_generation,
716 message.delta_end.generation)730 message.delta_end.generation)
717 self.assertEquals(self.request.full, message.delta_end.full)731 self.assertEqual(self.request.full, message.delta_end.full)
718 self.assertEquals(self.request.free_bytes,732 self.assertEqual(self.request.free_bytes,
719 message.delta_end.free_bytes)733 message.delta_end.free_bytes)
720734
721 def test_process_message_content(self):735 def test_process_message_content(self):
722 """Test request processMessage for content."""736 """Test request processMessage for content."""
@@ -748,11 +762,11 @@
748 self.request.done = was_called(self, 'done_called')762 self.request.done = was_called(self, 'done_called')
749 self.request.start()763 self.request.start()
750764
751 self.assertEquals(1, len(self.request.protocol.messages))765 self.assertEqual(1, len(self.request.protocol.messages))
752 actual_msg, = self.request.protocol.messages766 actual_msg, = self.request.protocol.messages
753 self.assertEquals(protocol_pb2.Message.GET_DELTA, actual_msg.type)767 self.assertEqual(protocol_pb2.Message.GET_DELTA, actual_msg.type)
754 self.assertEquals(self.request.share_id,768 self.assertEqual(self.request.share_id,
755 actual_msg.get_delta.share)769 actual_msg.get_delta.share)
756770
757771
758class TestAuth(RequestTestCase):772class TestAuth(RequestTestCase):
@@ -958,5 +972,124 @@
958 return d972 return d
959973
960974
961if __name__ == '__main__':975class ChangePublicAccessTestCase(RequestTestCase):
962 unittest.main()976 """Test cases for ChangePublicAccess op."""
977
978 request_class = ChangePublicAccess
979
980 @defer.inlineCallbacks
981 def setUp(self):
982 """Initialize testing protocol."""
983 yield super(ChangePublicAccessTestCase, self).setUp()
984 self.protocol = FakedProtocol()
985 self.request = self.request_class(
986 self.protocol, share_id=SHARE, node_id=NODE, is_public=True)
987 self.request.error = faked_error
988 self.done_called = False
989 self.request.done = was_called(self, 'done_called')
990
991 def test_init(self):
992 """Test request creation."""
993 self.assertEqual(self.request.share_id, str(SHARE))
994 self.assertEqual(self.request.node_id, str(NODE))
995 self.assertTrue(self.request.is_public)
996
997 def test_start(self):
998 """Test request start."""
999 self.request.start()
1000
1001 self.assertEqual(1, len(self.request.protocol.messages))
1002 actual_msg, = self.request.protocol.messages
1003 self.assertEqual(actual_msg.type,
1004 protocol_pb2.Message.CHANGE_PUBLIC_ACCESS)
1005 self.assertEqual(actual_msg.change_public_access.share,
1006 self.request.share_id)
1007 self.assertEqual(actual_msg.change_public_access.node,
1008 self.request.node_id)
1009 self.assertTrue(actual_msg.change_public_access.is_public)
1010
1011 def test_process_message_error(self):
1012 """Test request processMessage on error."""
1013 message = protocol_pb2.Message()
1014 self.assertRaises(FakedError, self.request.processMessage, message)
1015 self.assertIsNone(self.request.public_url)
1016
1017 def test_process_message_ok(self):
1018 """Test request processMessage on sucess."""
1019 message = protocol_pb2.Message()
1020 message.type = protocol_pb2.Message.OK
1021 message.public_url = PUBLIC_URL
1022 self.request.processMessage(message)
1023
1024 self.assertTrue(self.done_called, 'done() was called')
1025 self.assertIsNotNone(self.request.public_url)
1026
1027
1028class ListPublicFilesTestCase(RequestTestCase):
1029 """Test cases for ListPublicFiles op."""
1030
1031 request_class = ListPublicFiles
1032
1033 @defer.inlineCallbacks
1034 def setUp(self):
1035 """Initialize testing protocol."""
1036 yield super(ListPublicFilesTestCase, self).setUp()
1037 self.protocol = FakedProtocol()
1038 self.request = self.request_class(self.protocol)
1039 self.request.error = faked_error
1040 self.done_called = False
1041 self.request.done = was_called(self, 'done_called')
1042
1043 def test_start(self):
1044 """Test request start."""
1045 self.request.start()
1046
1047 self.assertEqual(1, len(self.request.protocol.messages))
1048 actual_msg, = self.request.protocol.messages
1049 self.assertEqual(actual_msg.type,
1050 protocol_pb2.Message.LIST_PUBLIC_FILES)
1051
1052 def test_process_message_error(self):
1053 """Test request processMessage on error."""
1054 message = protocol_pb2.Message()
1055 self.assertRaises(FakedError, self.request.processMessage, message)
1056 self.assertEqual(self.request.public_files, [])
1057
1058 def test_process_message_ok(self):
1059 """Test request processMessage on sucess."""
1060 # send two nodes
1061 message = protocol_pb2.Message()
1062 message.type = protocol_pb2.Message.PUBLIC_FILE_INFO
1063 message.public_file_info.share = 'share_id'
1064 message.public_file_info.node = 'node_id_1'
1065 message.public_file_info.is_public = True
1066 message.public_file_info.public_url = "test url 123"
1067 self.request.processMessage(message)
1068
1069 message = protocol_pb2.Message()
1070 message.type = protocol_pb2.Message.PUBLIC_FILE_INFO
1071 message.public_file_info.share = 'share_id'
1072 message.public_file_info.node = 'node_id_2'
1073 message.public_file_info.is_public = True
1074 message.public_file_info.public_url = "test url 456"
1075 self.request.processMessage(message)
1076
1077 # finish
1078 message = protocol_pb2.Message()
1079 message.type = protocol_pb2.Message.PUBLIC_FILE_INFO_END
1080 self.request.processMessage(message)
1081
1082 # check
1083 self.assertTrue(self.done_called, 'done() was called')
1084 node1, node2 = self.request.public_files
1085 print("NNNNNNNNNNNNO 1", node1)
1086
1087 self.assertEqual(node1.share_id, 'share_id')
1088 self.assertEqual(node1.node_id, 'node_id_1')
1089 self.assertEqual(node1.is_public, True)
1090 self.assertEqual(node1.public_url, 'test url 123')
1091
1092 self.assertEqual(node2.share_id, 'share_id')
1093 self.assertEqual(node2.node_id, 'node_id_2')
1094 self.assertEqual(node2.is_public, True)
1095 self.assertEqual(node2.public_url, 'test url 456')
9631096
=== added file 'tests/test_public_file_info.py'
--- tests/test_public_file_info.py 1970-01-01 00:00:00 +0000
+++ tests/test_public_file_info.py 2016-11-15 23:38:26 +0000
@@ -0,0 +1,74 @@
1# -*- coding: utf-8 -*-
2
3# Copyright 2016 Chicharreros (https://launchpad.net/~chicharreros)
4#
5# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU Affero General Public License version 3,
7# as published by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranties of
11# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
12# PURPOSE. See the GNU Affero General Public License for more details.
13#
14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16#
17# In addition, as a special exception, the copyright holders give
18# permission to link the code of portions of this program with the
19# OpenSSL library under certain conditions as described in each
20# individual source file, and distribute linked combinations
21# including the two.
22# You must obey the GNU General Public License in all respects
23# for all of the code used other than OpenSSL. If you modify
24# file(s) with this exception, you may extend this exception to your
25# version of the file(s), but you are not obligated to do so. If you
26# do not wish to do so, delete this exception statement from your
27# version. If you delete this exception statement from all source
28# files in the program, then also delete it here.
29
30"""Tests for generation node data type."""
31
32import unittest
33
34from ubuntuone.storageprotocol import protocol_pb2, public_file_info, request
35
36SHARE = "share_id"
37NODE = "node_id"
38PUBLIC_URL = "test public url"
39
40
41def get_message():
42 """Returns a PUBLIC_FILE_INFO message with sample data in the fields."""
43 message = protocol_pb2.Message()
44 message.type = protocol_pb2.Message.PUBLIC_FILE_INFO
45 message.public_file_info.share = str(SHARE)
46 message.public_file_info.node = str(NODE)
47 message.public_file_info.is_public = True
48 message.public_file_info.public_url = PUBLIC_URL
49 return message
50
51
52class DeltaTestCase(unittest.TestCase):
53 """Check Delta data type."""
54
55 def test_correct_attributes(self):
56 """Assert over attribute correctness."""
57 m = public_file_info.PublicFileInfo.from_message(get_message())
58 self.assertEqual(m.share_id, SHARE)
59 self.assertEqual(m.node_id, NODE)
60 self.assertEqual(m.is_public, True)
61 self.assertEqual(m.public_url, PUBLIC_URL)
62
63 def test_is_equal(self):
64 """Test object equality."""
65 m = public_file_info.PublicFileInfo.from_message(get_message())
66 m2 = public_file_info.PublicFileInfo.from_message(get_message())
67 self.assertEqual(m, m2)
68
69 def test_root_share_id(self):
70 """Test that DeltaInfo.from_message works with request.ROOT."""
71 msg = get_message()
72 msg.public_file_info.share = request.ROOT
73 m = public_file_info.PublicFileInfo.from_message(msg)
74 self.assertEqual(m.share_id, request.ROOT)
075
=== modified file 'ubuntuone/storageprotocol/client.py'
--- ubuntuone/storageprotocol/client.py 2016-10-11 19:01:04 +0000
+++ ubuntuone/storageprotocol/client.py 2016-11-15 23:38:26 +0000
@@ -1,12 +1,5 @@
1# ubuntuone.storageprotocol.client - the storage protocol client
2#
3# Author: Lucio Torre <lucio.torre@canonical.com>
4# Author: Natalia B. Bidart <natalia.bidart@canonical.com>
5# Author: Guillermo Gonzalez <guillermo.gonzalez@canonical.com>
6# Author: Facundo Batista <facundo@canonical.com>
7# Author: Alejandro J. Cura <alecu@canonical.com>
8#
9# Copyright 2009-2015 Canonical Ltd.1# Copyright 2009-2015 Canonical Ltd.
2# Copyright 2016 Chicharreros (https://launchpad.net/~chicharreros)
10#3#
11# This program is free software: you can redistribute it and/or modify it4# This program is free software: you can redistribute it and/or modify it
12# under the terms of the GNU Affero General Public License version 3,5# under the terms of the GNU Affero General Public License version 3,
@@ -32,6 +25,7 @@
32# do not wish to do so, delete this exception statement from your25# do not wish to do so, delete this exception statement from your
33# version. If you delete this exception statement from all source26# version. If you delete this exception statement from all source
34# files in the program, then also delete it here.27# files in the program, then also delete it here.
28
35"""The storage protocol client."""29"""The storage protocol client."""
3630
37import logging31import logging
@@ -47,6 +41,7 @@
47from ubuntuone.storageprotocol import (41from ubuntuone.storageprotocol import (
48 delta,42 delta,
49 protocol_pb2,43 protocol_pb2,
44 public_file_info,
50 request,45 request,
51 sharersp,46 sharersp,
52 volumes,47 volumes,
@@ -538,6 +533,18 @@
538 p.start()533 p.start()
539 return p.deferred534 return p.deferred
540535
536 def change_public_access(self, share_id, node_id, is_public):
537 """Change the public access of a file."""
538 p = ChangePublicAccess(self, share_id, node_id, is_public)
539 p.start()
540 return p.deferred
541
542 def list_public_files(self):
543 """List the public files."""
544 p = ListPublicFiles(self)
545 p.start()
546 return p.deferred
547
541 def delete_volume(self, volume_id):548 def delete_volume(self, volume_id):
542 """Delete 'volume' on the server, removing the associated tree.549 """Delete 'volume' on the server, removing the associated tree.
543550
@@ -961,6 +968,62 @@
961 self._default_process_message(message)968 self._default_process_message(message)
962969
963970
971class ChangePublicAccess(request.Request):
972 """Change the public access of a file."""
973
974 __slots__ = ('share_id', 'node_id', 'is_public', 'public_url')
975
976 def __init__(self, protocol, share_id, node_id, is_public):
977 request.Request.__init__(self, protocol)
978 self.public_url = None
979
980 self.share_id = str(share_id)
981 self.node_id = str(node_id)
982 self.is_public = is_public
983
984 def _start(self):
985 message = protocol_pb2.Message()
986 message.type = protocol_pb2.Message.CHANGE_PUBLIC_ACCESS
987 message.change_public_access.share = self.share_id
988 message.change_public_access.node = self.node_id
989 message.change_public_access.is_public = self.is_public
990 self.sendMessage(message)
991
992 def processMessage(self, message):
993 if message.type == protocol_pb2.Message.OK:
994 self.public_url = message.public_url
995 self.done()
996 else:
997 self._default_process_message(message)
998
999
1000class ListPublicFiles(request.Request):
1001 """List all the public files for an user."""
1002
1003 __slots__ = ('public_files',)
1004
1005 def __init__(self, protocol):
1006 """List volumes."""
1007 request.Request.__init__(self, protocol)
1008 self.public_files = []
1009
1010 def _start(self):
1011 """Send the LIST_PUBLIC_FILES message to the server."""
1012 message = protocol_pb2.Message()
1013 message.type = protocol_pb2.Message.LIST_PUBLIC_FILES
1014 self.sendMessage(message)
1015
1016 def processMessage(self, message):
1017 """Process the answer from the server."""
1018 if message.type == protocol_pb2.Message.PUBLIC_FILE_INFO:
1019 info = public_file_info.PublicFileInfo.from_message(message)
1020 self.public_files.append(info)
1021 elif message.type == protocol_pb2.Message.PUBLIC_FILE_INFO_END:
1022 self.done()
1023 else:
1024 self._default_process_message(message)
1025
1026
964class Move(request.Request):1027class Move(request.Request):
965 """Move a node.1028 """Move a node.
9661029
9671030
=== modified file 'ubuntuone/storageprotocol/protocol.proto'
--- ubuntuone/storageprotocol/protocol.proto 2012-03-29 20:28:09 +0000
+++ ubuntuone/storageprotocol/protocol.proto 2016-11-15 23:38:26 +0000
@@ -1,7 +1,6 @@
1/*1/*
2 ubuntuone.storageprotocol.protocol_pb2 - storage protocol
3
4 Copyright 2009-2012 Canonical Ltd.2 Copyright 2009-2012 Canonical Ltd.
3 Copyright 2016 Chicharreros (https://launchpad.net/~chicharreros)
54
6 This program is free software: you can redistribute it and/or modify it5 This program is free software: you can redistribute it and/or modify it
7 under the terms of the GNU Affero General Public License version 3,6 under the terms of the GNU Affero General Public License version 3,
@@ -97,6 +96,11 @@
97 GET_DELTA = 51; // ask for a delta96 GET_DELTA = 51; // ask for a delta
98 DELTA_INFO = 52; // a row of the delta97 DELTA_INFO = 52; // a row of the delta
99 DELTA_END = 53; // marks the end of a delta98 DELTA_END = 53; // marks the end of a delta
99
100 CHANGE_PUBLIC_ACCESS = 55; // change the public access of a file
101 PUBLIC_FILE_INFO = 56; // information for a public file
102 PUBLIC_FILE_INFO_END = 57; // marks the end of a bunch of public file infos
103 LIST_PUBLIC_FILES = 58; // get the list of public files for the user
100 }104 }
101105
102 required MessageType type = 2; // The type of the message contained106 required MessageType type = 2; // The type of the message contained
@@ -159,6 +163,11 @@
159 optional GetDelta get_delta = 38;163 optional GetDelta get_delta = 38;
160 optional DeltaInfo delta_info = 39;164 optional DeltaInfo delta_info = 39;
161 optional DeltaEnd delta_end = 40;165 optional DeltaEnd delta_end = 40;
166
167 // public files
168 optional ChangePublicAccess change_public_access = 45;
169 optional bytes public_url = 46;
170 optional PublicFileInfo public_file_info = 47;
162}171}
163172
164message Error {173message Error {
@@ -481,6 +490,19 @@
481 optional uint64 free_bytes = 3; // this will be just a hint if full == False490 optional uint64 free_bytes = 3; // this will be just a hint if full == False
482}491}
483492
493message ChangePublicAccess {
494 optional bytes share = 1;
495 optional bytes node = 2;
496 optional bool is_public = 3;
497}
498
499message PublicFileInfo {
500 optional bytes share = 1;
501 optional bytes node = 2;
502 optional bool is_public = 3;
503 optional bytes public_url = 4;
504}
505
484/*506/*
485== changes ==507== changes ==
486508
487509
=== added file 'ubuntuone/storageprotocol/public_file_info.py'
--- ubuntuone/storageprotocol/public_file_info.py 1970-01-01 00:00:00 +0000
+++ ubuntuone/storageprotocol/public_file_info.py 2016-11-15 23:38:26 +0000
@@ -0,0 +1,55 @@
1# Copyright 2016 Chicharreros (https://launchpad.net/~chicharreros)
2#
3# This program is free software: you can redistribute it and/or modify it
4# under the terms of the GNU Affero General Public License version 3,
5# as published by the Free Software Foundation.
6#
7# This program is distributed in the hope that it will be useful, but
8# WITHOUT ANY WARRANTY; without even the implied warranties of
9# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
10# PURPOSE. See the GNU Affero General Public License for more details.
11#
12# You should have received a copy of the GNU Affero General Public License
13# along with this program. If not, see <http://www.gnu.org/licenses/>.
14#
15# In addition, as a special exception, the copyright holders give
16# permission to link the code of portions of this program with the
17# OpenSSL library under certain conditions as described in each
18# individual source file, and distribute linked combinations
19# including the two.
20# You must obey the GNU General Public License in all respects
21# for all of the code used other than OpenSSL. If you modify
22# file(s) with this exception, you may extend this exception to your
23# version of the file(s), but you are not obligated to do so. If you
24# do not wish to do so, delete this exception statement from your
25# version. If you delete this exception statement from all source
26# files in the program, then also delete it here.
27
28"""Wrapper class for public file information."""
29
30
31class PublicFileInfo(object):
32 """Hold the public file object information."""
33
34 def __init__(self, share_id, node_id, is_public, public_url):
35 self.share_id = share_id
36 self.node_id = node_id
37 self.is_public = is_public
38 self.public_url = public_url
39
40 @classmethod
41 def from_message(cls, message):
42 """Creates the object using the information from a message."""
43 info = message.public_file_info
44 result = cls(
45 share_id=info.share,
46 node_id=info.node,
47 is_public=info.is_public,
48 public_url=info.public_url)
49 return result
50
51 def __eq__(self, other):
52 if not isinstance(other, self.__class__):
53 return False
54
55 return self.__dict__ == other.__dict__

Subscribers

People subscribed via source and target branches

to all changes: