File: Synopsis/FileTree.py
 1#
 2# Copyright (C) 2000 Stefan Seefeld
 3# Copyright (C) 2000 Stephen Davies
 4# All rights reserved.
 5# Licensed to the public under the terms of the GNU LGPL (>= 2),
 6# see the file COPYING for details.
 7#
 8
 9import os.path
10
11class Node:
12    """Base class for directories and files in the tree.
13    @attr path the path of this node as a string.
14    @attr filename the name of the node, i.e. the last element of the
15    path string
16    """
17    def __init__(self, path, filename):
18        self.path = path
19        self.filename = filename
20
21class Directory(Node):
22    """FileTree node for directories.
23    @attr path the path of this node as a string.
24    @attr filename the name of the directory, i.e. the last element of the
25    path string
26    @attr children the children of this directory, each Directory or File
27    objects.
28    """
29    def __init__(self, path, filename):
30        Node.__init__(self, path, filename)
31        self.children = []
32
33class File(Node):
34    """FileTree node for files.
35    @attr path the path of this node as a string.
36    @attr filename the name of the file, i.e. the last element of the
37    path string
38    @attr decls the list of declarations in this file.
39    """
40    def __init__(self, path, filename, declarations):
41        Node.__init__(self, path, filename)
42        self.declarations = declarations
43
44def make_file_tree(files):
45
46    tmp_dirs = {}
47    root = Directory('', '')
48
49    def insert_dir(path):
50        """Recursively add a directory to the tree"""
51        parent_dir, filename = os.path.split(path)
52        if parent_dir == path:
53            # The root directory is added below the root node
54            # This is in case absolute filenames are mixed with relative ones
55            parent = root
56            filename = '/'
57        else:
58            parent_dir, filename = os.path.split(path)
59            if parent_dir:
60                if tmp_dirs.has_key(parent_dir):
61                    parent = tmp_dirs[parent_dir]
62                else:
63                    parent = insert_dir(parent_dir)
64            else:
65             # No parent means a relative name like 'home/foo/bar'
66             parent = root
67        new_dir = Directory(path, filename)
68        tmp_dirs[path] = new_dir
69        parent.children.append(new_dir)
70        return new_dir
71
72    def insert_file(file, declarations):
73        parent_dir, filename = os.path.split(file)
74        if parent_dir:
75            if tmp_dirs.has_key(parent_dir):
76                parent = tmp_dirs[parent_dir]
77            else:
78                parent = insert_dir(parent_dir)
79        else:
80            # No parent means an relative name like 'home/foo/bar'
81            parent = root
82        new_file = File(file, filename, declarations)
83        parent.children.append(new_file)
84
85
86    for f in files:
87        if f.annotations['primary']:
88            insert_file(f.name, f.declarations)
89
90    return root
91