Show More
@@ -30,6 +30,21 b' from IPython.utils.py3compat import string_types' | |||||
30 | copy_pat = re.compile(r'\-Copy\d*\.') |
|
30 | copy_pat = re.compile(r'\-Copy\d*\.') | |
31 |
|
31 | |||
32 |
|
32 | |||
|
33 | def _separate_dirs_files(models): | |||
|
34 | """ | |||
|
35 | Split an iterable of models into a list of file paths and a list of | |||
|
36 | directory paths. | |||
|
37 | """ | |||
|
38 | dirs = [] | |||
|
39 | files = [] | |||
|
40 | for model in models: | |||
|
41 | if model['type'] == 'directory': | |||
|
42 | dirs.append(model['path']) | |||
|
43 | else: | |||
|
44 | files.append(model['path']) | |||
|
45 | return dirs, files | |||
|
46 | ||||
|
47 | ||||
33 | class CheckpointManager(LoggingConfigurable): |
|
48 | class CheckpointManager(LoggingConfigurable): | |
34 | """ |
|
49 | """ | |
35 | Base class for managing checkpoints for a ContentsManager. |
|
50 | Base class for managing checkpoints for a ContentsManager. | |
@@ -499,6 +514,31 b' class ContentsManager(LoggingConfigurable):' | |||||
499 | """Should this file/directory name be displayed in a listing?""" |
|
514 | """Should this file/directory name be displayed in a listing?""" | |
500 | return not any(fnmatch(name, glob) for glob in self.hide_globs) |
|
515 | return not any(fnmatch(name, glob) for glob in self.hide_globs) | |
501 |
|
516 | |||
|
517 | def walk(self): | |||
|
518 | """ | |||
|
519 | Like os.walk, but written in terms of the ContentsAPI. | |||
|
520 | ||||
|
521 | Returns a generator of tuples of the form: | |||
|
522 | (directory name, [subdirectories], [files in directory]) | |||
|
523 | """ | |||
|
524 | return self._walk(['']) | |||
|
525 | ||||
|
526 | def _walk(self, dirs): | |||
|
527 | """ | |||
|
528 | Recursive helper for walk. | |||
|
529 | """ | |||
|
530 | for directory in dirs: | |||
|
531 | children = self.get( | |||
|
532 | directory, | |||
|
533 | content=True, | |||
|
534 | type='directory', | |||
|
535 | )['content'] | |||
|
536 | dirs, files = map(sorted, _separate_dirs_files(children)) | |||
|
537 | yield (directory, dirs, files) | |||
|
538 | if dirs: | |||
|
539 | for entry in self._walk(dirs): | |||
|
540 | yield(entry) | |||
|
541 | ||||
502 | # Part 3: Checkpoints API |
|
542 | # Part 3: Checkpoints API | |
503 | def create_checkpoint(self, path): |
|
543 | def create_checkpoint(self, path): | |
504 | """Create a checkpoint.""" |
|
544 | """Create a checkpoint.""" |
@@ -614,3 +614,82 b' class APITest(NotebookTestBase):' | |||||
614 | with TemporaryDirectory() as td: |
|
614 | with TemporaryDirectory() as td: | |
615 | with self.patch_cp_root(td): |
|
615 | with self.patch_cp_root(td): | |
616 | self.test_file_checkpoints() |
|
616 | self.test_file_checkpoints() | |
|
617 | ||||
|
618 | def test_walk(self): | |||
|
619 | """ | |||
|
620 | Test ContentsManager.walk. | |||
|
621 | """ | |||
|
622 | results = list(self.notebook.contents_manager.walk()) | |||
|
623 | expected = [ | |||
|
624 | ( | |||
|
625 | '', | |||
|
626 | [ | |||
|
627 | 'Directory with spaces in', | |||
|
628 | 'foo', | |||
|
629 | 'ordering', | |||
|
630 | u'unicodé', | |||
|
631 | u'å b', | |||
|
632 | ], | |||
|
633 | ['inroot.blob', 'inroot.ipynb', 'inroot.txt'], | |||
|
634 | ), | |||
|
635 | ( | |||
|
636 | 'Directory with spaces in', | |||
|
637 | [], | |||
|
638 | ['inspace.blob', 'inspace.ipynb', 'inspace.txt'], | |||
|
639 | ), | |||
|
640 | ( | |||
|
641 | 'foo', | |||
|
642 | ['bar'], | |||
|
643 | [ | |||
|
644 | 'a.blob', 'a.ipynb', 'a.txt', | |||
|
645 | 'b.blob', 'b.ipynb', 'b.txt', | |||
|
646 | 'name with spaces.blob', | |||
|
647 | 'name with spaces.ipynb', | |||
|
648 | 'name with spaces.txt', | |||
|
649 | u'unicodé.blob', u'unicodé.ipynb', u'unicodé.txt' | |||
|
650 | ] | |||
|
651 | ), | |||
|
652 | ( | |||
|
653 | 'foo/bar', | |||
|
654 | [], | |||
|
655 | ['baz.blob', 'baz.ipynb', 'baz.txt'], | |||
|
656 | ), | |||
|
657 | ( | |||
|
658 | 'ordering', | |||
|
659 | [], | |||
|
660 | [ | |||
|
661 | 'A.blob', 'A.ipynb', 'A.txt', | |||
|
662 | 'C.blob', 'C.ipynb', 'C.txt', | |||
|
663 | 'b.blob', 'b.ipynb', 'b.txt', | |||
|
664 | ], | |||
|
665 | ), | |||
|
666 | ( | |||
|
667 | u'unicodé', | |||
|
668 | [], | |||
|
669 | ['innonascii.blob', 'innonascii.ipynb', 'innonascii.txt'], | |||
|
670 | ), | |||
|
671 | ( | |||
|
672 | u'å b', | |||
|
673 | [], | |||
|
674 | [u'ç d.blob', u'ç d.ipynb', u'ç d.txt'], | |||
|
675 | ), | |||
|
676 | ] | |||
|
677 | ||||
|
678 | for idx, (dname, subdirs, files) in enumerate(expected): | |||
|
679 | result_dname, result_subdirs, result_files = results[idx] | |||
|
680 | if dname == '': | |||
|
681 | sep = '' | |||
|
682 | else: | |||
|
683 | sep = '/' | |||
|
684 | self.assertEqual( | |||
|
685 | dname, | |||
|
686 | result_dname, | |||
|
687 | ) | |||
|
688 | self.assertEqual( | |||
|
689 | [sep.join([dname, sub]) for sub in subdirs], | |||
|
690 | result_subdirs, | |||
|
691 | ) | |||
|
692 | self.assertEqual( | |||
|
693 | [sep.join([dname, fname]) for fname in files], | |||
|
694 | result_files, | |||
|
695 | ) |
General Comments 0
You need to be logged in to leave comments.
Login now