ソースを参照

add copy method into tracim contentAPI and COPY support for webdav

Guénaël Muller 6 年 前
コミット
f538c75794
共有3 個のファイルを変更した320 個の追加0 個の削除を含む
  1. 41 0
      tracim/tracim/lib/content.py
  2. 34 0
      tracim/tracim/lib/webdav/sql_resources.py
  3. 245 0
      tracim/tracim/tests/library/test_content_api.py

+ 41 - 0
tracim/tracim/lib/content.py ファイルの表示

@@ -860,6 +860,47 @@ class ContentApi(object):
860 860
 
861 861
         item.revision_type = ActionDescription.MOVE
862 862
 
863
+    def copy(
864
+        self,
865
+        item: Content,
866
+        new_parent: Content=None,
867
+        new_label: str=None,
868
+        do_save: bool=True,
869
+    ) -> None:
870
+        if not new_parent and not new_label:
871
+            # TODO - G.M - 08-03-2018 - Use something else than value error
872
+            raise ValueError("You can't copy file into itself")
873
+        if new_parent:
874
+            workspace = new_parent.workspace
875
+            parent = new_parent
876
+        else:
877
+            workspace = item.workspace
878
+            parent = item.parent
879
+
880
+        if new_label:
881
+            label = new_label
882
+        else:
883
+            label = item.label
884
+
885
+        with DBSession.no_autoflush:
886
+            file = self.create(
887
+                content_type=item.type,
888
+                workspace=workspace,
889
+                parent=parent,
890
+                label=label,
891
+                do_save=False,
892
+            )
893
+            file.description = item.description
894
+            if item.depot_file:
895
+                self.update_file_data(
896
+                    file,
897
+                    item.file_name,
898
+                    item.file_mimetype,
899
+                    item.depot_file.file
900
+                )
901
+        if do_save:
902
+            self.save(file, ActionDescription.CREATION, do_notify=True)
903
+
863 904
     def move_recursively(self, item: Content,
864 905
                          new_parent: Content, new_workspace: Workspace):
865 906
         self.move(item, new_parent, False, new_workspace)

+ 34 - 0
tracim/tracim/lib/webdav/sql_resources.py ファイルの表示

@@ -1005,6 +1005,40 @@ class File(DAVNonCollection):
1005 1005
 
1006 1006
         transaction.commit()
1007 1007
 
1008
+    def copyMoveSingle(self, destpath, isMove):
1009
+        if isMove:
1010
+            raise NotImplemented
1011
+
1012
+        new_file_name = None
1013
+        new_file_extension = None
1014
+
1015
+        # Inspect destpath
1016
+        if basename(destpath) != self.getDisplayName():
1017
+            new_given_file_name = transform_to_bdd(basename(destpath))
1018
+            new_file_name, new_file_extension = \
1019
+                os.path.splitext(new_given_file_name)
1020
+
1021
+        workspace_api = WorkspaceApi(self.user)
1022
+        content_api = ContentApi(self.user)
1023
+        destination_workspace = self.provider.get_workspace_from_path(
1024
+            destpath,
1025
+            workspace_api,
1026
+        )
1027
+        destination_parent = self.provider.get_parent_from_path(
1028
+            destpath,
1029
+            content_api,
1030
+            destination_workspace,
1031
+        )
1032
+        workspace = self.content.workspace
1033
+        parent = self.content.parent
1034
+        self.content_api.copy(
1035
+            item=self.content,
1036
+            new_label=new_file_name,
1037
+            new_parent=destination_parent,
1038
+        )
1039
+
1040
+        transaction.commit()
1041
+
1008 1042
     def supportRecursiveMove(self, destPath):
1009 1043
         return True
1010 1044
 

+ 245 - 0
tracim/tracim/tests/library/test_content_api.py ファイルの表示

@@ -4,6 +4,7 @@ import datetime
4 4
 from nose.tools import eq_, ok_
5 5
 from nose.tools import raises
6 6
 
7
+from depot.io.utils import FileIntent
7 8
 import transaction
8 9
 
9 10
 from tracim.lib.content import compare_content_for_sorting_by_type_and_name
@@ -347,6 +348,250 @@ class TestContentApi(BaseTest, TestStandard):
347 348
         eq_('', c.label)
348 349
         eq_(ActionDescription.COMMENT, c.revision_type)
349 350
 
351
+    def test_unit_copy_file_different_label_different_parent_ok(self):
352
+        uapi = UserApi(None)
353
+        groups = [
354
+            GroupApi(None).get_one(Group.TIM_USER),
355
+            GroupApi(None).get_one(Group.TIM_MANAGER),
356
+            GroupApi(None).get_one(Group.TIM_ADMIN)
357
+        ]
358
+
359
+        user = uapi.create_user(
360
+            email='user1@user',
361
+            groups=groups,
362
+            save_now=True
363
+        )
364
+        user2 = uapi.create_user(
365
+            email='user2@user',
366
+            groups=groups,
367
+            save_now=True
368
+        )
369
+        workspace = WorkspaceApi(user).create_workspace(
370
+            'test workspace',
371
+            save_now=True
372
+        )
373
+        RoleApi(user).create_one(
374
+            user2,
375
+            workspace,
376
+            UserRoleInWorkspace.WORKSPACE_MANAGER,
377
+            with_notif=False
378
+        )
379
+        api = ContentApi(user)
380
+        foldera = api.create(
381
+            ContentType.Folder,
382
+            workspace,
383
+            None,
384
+            'folder a',
385
+            True
386
+        )
387
+        with DBSession.no_autoflush:
388
+            text_file = api.create(
389
+                content_type=ContentType.File,
390
+                workspace=workspace,
391
+                parent=foldera,
392
+                label='test_file',
393
+                do_save=False,
394
+            )
395
+            api.update_file_data(
396
+                text_file,
397
+                'test_file',
398
+                'text/plain',
399
+                b'test_content'
400
+            )
401
+
402
+        api.save(text_file, ActionDescription.CREATION)
403
+        api2 = ContentApi(user2)
404
+        workspace2 = WorkspaceApi(user2).create_workspace(
405
+            'test workspace2',
406
+            save_now=True
407
+        )
408
+        folderb = api2.create(
409
+            ContentType.Folder,
410
+            workspace2,
411
+            None,
412
+            'folder b',
413
+            True
414
+        )
415
+
416
+        api2.copy(
417
+            item=text_file,
418
+            new_parent=folderb,
419
+            new_label='test_file_copy'
420
+        )
421
+
422
+        text_file_copy = api2.get_one_by_label_and_parent(
423
+            'test_file_copy',
424
+            folderb
425
+        )
426
+        assert text_file != text_file_copy
427
+        assert text_file_copy.content_id != text_file.content_id
428
+        assert text_file_copy.workspace == workspace2
429
+        assert text_file_copy.depot_file != text_file.depot_file
430
+        assert text_file_copy.label == 'test_file_copy'
431
+        assert text_file_copy.type == text_file.type
432
+        assert text_file_copy.parent == folderb
433
+        assert text_file_copy.owner == user2
434
+        assert text_file_copy.description == text_file.description
435
+        assert text_file_copy.file_extension == text_file.file_extension
436
+        assert text_file_copy.file_mimetype == text_file.file_mimetype
437
+
438
+    def test_unit_copy_file__same_label_different_parent_ok(self):
439
+        uapi = UserApi(None)
440
+        groups = [GroupApi(None).get_one(Group.TIM_USER),
441
+                  GroupApi(None).get_one(Group.TIM_MANAGER),
442
+                  GroupApi(None).get_one(Group.TIM_ADMIN)]
443
+
444
+        user = uapi.create_user(
445
+            email='user1@user',
446
+            groups=groups,
447
+            save_now=True
448
+        )
449
+        user2 = uapi.create_user(
450
+            email='user2@user',
451
+            groups=groups,
452
+            save_now=True
453
+        )
454
+        workspace = WorkspaceApi(user).create_workspace(
455
+            'test workspace',
456
+            save_now=True
457
+        )
458
+        RoleApi(user).create_one(
459
+            user2,
460
+            workspace,
461
+            UserRoleInWorkspace.WORKSPACE_MANAGER,
462
+            with_notif=False
463
+        )
464
+        api = ContentApi(user)
465
+        foldera = api.create(
466
+            ContentType.Folder,
467
+            workspace,
468
+            None,
469
+            'folder a',
470
+            True
471
+        )
472
+        with DBSession.no_autoflush:
473
+            text_file = api.create(
474
+                content_type=ContentType.File,
475
+                workspace=workspace,
476
+                parent=foldera,
477
+                label='test_file',
478
+                do_save=False,
479
+            )
480
+            api.update_file_data(
481
+                text_file,
482
+                'test_file',
483
+                'text/plain',
484
+                b'test_content'
485
+            )
486
+
487
+        api.save(text_file, ActionDescription.CREATION)
488
+        api2 = ContentApi(user2)
489
+        workspace2 = WorkspaceApi(user2).create_workspace(
490
+            'test workspace2',
491
+            save_now=True
492
+        )
493
+        folderb = api2.create(
494
+            ContentType.Folder,
495
+            workspace2,
496
+            None,
497
+            'folder b',
498
+            True
499
+        )
500
+
501
+        api2.copy(
502
+            item=text_file,
503
+            new_parent=folderb,
504
+        )
505
+
506
+        text_file_copy = api2.get_one_by_label_and_parent('test_file', folderb)
507
+        assert text_file != text_file_copy
508
+        assert text_file_copy.content_id != text_file.content_id
509
+        assert text_file_copy.workspace == workspace2
510
+        assert text_file_copy.depot_file != text_file.depot_file
511
+        assert text_file_copy.label == text_file.label
512
+        assert text_file_copy.type == text_file.type
513
+        assert text_file_copy.parent == folderb
514
+        assert text_file_copy.owner == user2
515
+        assert text_file_copy.description == text_file.description
516
+        assert text_file_copy.file_extension == text_file.file_extension
517
+        assert text_file_copy.file_mimetype == text_file.file_mimetype
518
+
519
+    def test_unit_copy_file_different_label_same_parent_ok(self):
520
+        uapi = UserApi(None)
521
+        groups = [
522
+            GroupApi(None).get_one(Group.TIM_USER),
523
+            GroupApi(None).get_one(Group.TIM_MANAGER),
524
+            GroupApi(None).get_one(Group.TIM_ADMIN),
525
+        ]
526
+
527
+        user = uapi.create_user(
528
+            email='user1@user',
529
+            groups=groups,
530
+            save_now=True,
531
+        )
532
+        user2 = uapi.create_user(
533
+            email='user2@user',
534
+            groups=groups,
535
+            save_now=True
536
+        )
537
+        workspace = WorkspaceApi(user).create_workspace(
538
+            'test workspace',
539
+            save_now=True
540
+        )
541
+        RoleApi(user).create_one(
542
+            user2, workspace,
543
+            UserRoleInWorkspace.WORKSPACE_MANAGER,
544
+            with_notif=False
545
+        )
546
+        api = ContentApi(user)
547
+        foldera = api.create(
548
+            ContentType.Folder,
549
+            workspace,
550
+            None,
551
+            'folder a',
552
+            True
553
+        )
554
+        with DBSession.no_autoflush:
555
+            text_file = api.create(
556
+                content_type=ContentType.File,
557
+                workspace=workspace,
558
+                parent=foldera,
559
+                label='test_file',
560
+                do_save=False,
561
+            )
562
+            api.update_file_data(
563
+                text_file,
564
+                'test_file',
565
+                'text/plain',
566
+                b'test_content'
567
+            )
568
+
569
+        api.save(
570
+            text_file,
571
+            ActionDescription.CREATION
572
+        )
573
+        api2 = ContentApi(user2)
574
+
575
+        api2.copy(
576
+            item=text_file,
577
+            new_label='test_file_copy'
578
+        )
579
+
580
+        text_file_copy = api2.get_one_by_label_and_parent(
581
+            'test_file_copy',
582
+            foldera
583
+        )
584
+        assert text_file != text_file_copy
585
+        assert text_file_copy.content_id != text_file.content_id
586
+        assert text_file_copy.workspace == workspace
587
+        assert text_file_copy.depot_file != text_file.depot_file
588
+        assert text_file_copy.label == 'test_file_copy'
589
+        assert text_file_copy.type == text_file.type
590
+        assert text_file_copy.parent == foldera
591
+        assert text_file_copy.owner == user2
592
+        assert text_file_copy.description == text_file.description
593
+        assert text_file_copy.file_extension == text_file.file_extension
594
+        assert text_file_copy.file_mimetype == text_file.file_mimetype
350 595
 
351 596
     def test_mark_read__workspace(self):
352 597
         uapi = UserApi(None)