~yacinechaouche/+junk/BZR

« back to all changes in this revision

Viewing changes to PROG/MERGOU/.svn/text-base/code-browser.py.svn-base

  • Committer: yacinechaouche at yahoo
  • Date: 2015-01-14 22:23:03 UTC
  • Revision ID: yacinechaouche@yahoo.com-20150114222303-6gbtqqxii717vyka
Ajout de CODE et PROD. Il faudra ensuite ajouter ce qu'il y avait dan TMP

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""
 
2
r5 : make the arguments  in the Cmd completable to children keys when user inserts a >
 
3
     for ex. :
 
4
     > #modules>[tab]
 
5
     will complete to the keys of the #modules node.
 
6
r6 : implement shell functionalities :
 
7
r6.1    o ls (with completion) : replace ">" with "/" to simulate directories
 
8
r6.2    o ls -l                : each function,module,classe etc. with its lines of code.
 
9
                                 Permissions are replaced with the type of the node
 
10
r6.3    o cd                   : descend one node
 
11
r6.4    o cat                  : display node's code
 
12
r6.5    o find                 : search for a node's name
 
13
r6.6    o grep                 : look for a string in the code
 
14
     
 
15
"""
 
16
 
 
17
import tahar
 
18
import sys
 
19
import cmd
 
20
import pprint
 
21
import traceback
 
22
 
 
23
def raise_problem(function):
 
24
    def wrapper(*args,**kw): 
 
25
        try:
 
26
            return function(*args,**kw)
 
27
        except:
 
28
            print traceback.print_exc()
 
29
    return wrapper
 
30
 
 
31
class CodeBrowser(cmd.Cmd):
 
32
    def __init__(self,stat):
 
33
        cmd.Cmd.__init__(self)
 
34
        self.prompt = "root > "
 
35
        self.stat = stat.stats
 
36
        self.current_node = self.stat["#modules"]
 
37
 
 
38
    def path(self,node=None):
 
39
        if not node:
 
40
            node = self.current_node
 
41
        parent = node.get("#parent")
 
42
        if not parent:
 
43
            return node.get("#name","root")
 
44
        parents_path = self.path(parent)
 
45
        parents_type = parent.get("#type")
 
46
        nodes_type   = node.get("#type","?")
 
47
        nodes_name   = node.get("#name","?")
 
48
        chunk        = ""
 
49
        if nodes_type == "class" :
 
50
            chunk = "classes"
 
51
        elif nodes_type == "function":
 
52
            if parents_type == "class":
 
53
                chunk = "methods"
 
54
            else : 
 
55
                chunk = "functions"
 
56
        elif nodes_type == "module":
 
57
            chunk = "modules"
 
58
        elif nodes_type in ("modules","classes","functions","class_code","module_code","methods"):
 
59
            chunk = nodes_type
 
60
        return "/".join([parents_path,chunk,nodes_name])
 
61
 
 
62
    def change_node(self,dst,error_msg="",node=None):
 
63
        next_node = self.current_node.get(dst)
 
64
        if next_node :
 
65
            self.current_node = next_node
 
66
        else:
 
67
            if error_msg :
 
68
                print error_msg
 
69
            else : 
 
70
                print "this node has no attribute named",dst
 
71
        self.prompt = self.path()+"> "
 
72
        #self.do_show()
 
73
        #self.do_keys()
 
74
        
 
75
    def do_name(self,line="",node=None):
 
76
        if not node:
 
77
            node = self.current_node
 
78
        print node.get("#name")
 
79
 
 
80
    ## do_n = do_name
 
81
 
 
82
    def do_path(self,line="",node=None):
 
83
        if not node:
 
84
            node = self.current_node
 
85
        print self.path(node=node)
 
86
 
 
87
    do_pwd = do_path
 
88
 
 
89
    def do_show(self,line="",node=None):
 
90
        if not node:
 
91
            node = self.current_node
 
92
        print "node name",
 
93
        self.do_name(node=node)
 
94
        print "node path",
 
95
        self.do_path(node=node)
 
96
        print "node ",
 
97
        self.do_keys(node=node)
 
98
            
 
99
    do_w = do_s = do_show
 
100
 
 
101
    def do_keys(self,line="",node=None):
 
102
        if not node:
 
103
            node = self.current_node
 
104
        print node.keys()
 
105
 
 
106
    do_k = do_down = do_keys
 
107
    
 
108
    def do_parent(self,line="",node=None):
 
109
        if not node :
 
110
            node = self.current_node
 
111
        self.change_node("#parent","this node has no parent",node=node)
 
112
 
 
113
    do_up = do_u = do_parent
 
114
 
 
115
    ## def do_functions(self,line=""):
 
116
    ##     self.change_node("#functions","this node has no functions")
 
117
 
 
118
    ## def do_methods(self,line=""):
 
119
    ##     self.change_node("#methods","this node has no methods")
 
120
 
 
121
    ## def do_modules(self,line=""):
 
122
    ##     self.change_node("#modules","this node has no modules")
 
123
 
 
124
    ## def do_loc(self,line=""):        
 
125
    ##     loc = self.current_node.get("#loc")
 
126
    ##     if loc != None : 
 
127
    ##         print loc
 
128
    ##     else:
 
129
    ##         print "This node has no #loc key. This is a bug. Please report it"
 
130
 
 
131
    ## def do_type(self,line=""):
 
132
    ##     print self.current_node.get("#type")
 
133
    
 
134
    # def do_select(self,line=""):
 
135
    #     node = line.split(":")[0]
 
136
    #     self.change_node(node)
 
137
 
 
138
    def default(self,line=""):
 
139
        x = self._get_element(line)
 
140
        if type(x)!= dict:
 
141
            print x
 
142
        else:
 
143
            self.do_show(node=x)
 
144
 
 
145
    @raise_problem
 
146
    def completenames(self,*args):
 
147
        user_input = args[1]
 
148
        keys       = self.current_node.keys()
 
149
        ## if user_input.startswith("#"):
 
150
        ##     user_input = user_input[1:]
 
151
        return [key for key in self.current_node.keys() if key.startswith(user_input)]        
 
152
 
 
153
    @raise_problem
 
154
    def completedefault_old(self,*args):
 
155
        #print "completedefault",args
 
156
        user_input = args[1].split(">")
 
157
        node       = self.current_node
 
158
        for element in user_input:
 
159
            x = node.get(element)
 
160
            if type(x) == dict:
 
161
                node = x
 
162
            else:
 
163
                break
 
164
        keys = node.keys()
 
165
        if element.startswith("#"):
 
166
            L = [key[1:] or key for key in keys if key.startswith(element)]
 
167
        else :
 
168
            L = [key for key in keys if key.startswith(element)]            
 
169
        #print "keys are", keys
 
170
        # L = [key.startswith("#") and key[1:] or key for key in keys if key.startswith(element)]
 
171
        #print "L is",L
 
172
        return L 
 
173
 
 
174
    def _get_element(self,path):
 
175
        """
 
176
        Returns a node or a content, depending on what node.get(element) returns.
 
177
        """
 
178
        elements = path.split(">")
 
179
        node =  self.current_node
 
180
        for element in elements :
 
181
            x = node.get(element)
 
182
            if type(x) != dict:
 
183
                return x
 
184
            else:
 
185
                node = x
 
186
        return x
 
187
 
 
188
    def do_ls(self,line=""):
 
189
        current_type = self.current_node.get("#type")
 
190
        current_name = self.current_node.get("#name")
 
191
        if current_type == "module":
 
192
            self._list_module(self.current_node)
 
193
 
 
194
        elif current_type == "modules":
 
195
            self._list_modules(self.current_node)
 
196
 
 
197
        elif current_type == "class":
 
198
            self._list_class(self.current_node)
 
199
        
 
200
 
 
201
    def _list_class(self,klass=None):
 
202
        if not klass:
 
203
            # XXX dangerous assumption
 
204
            klass = self.current_node
 
205
 
 
206
        subclasses_names = [sub for sub in klass.get("#classes",{}).keys() if not sub.startswith("#")]
 
207
        methods_names    = [sub for sub in klass.get("#methods",{}).keys() if not sub.startswith("#")]
 
208
        max_length       = max(map(lambda x:len(x),subclasses_names+methods_names))
 
209
        
 
210
        for subclass_name in subclasses_names : 
 
211
            print "\t".join(("class",subclass_name.ljust(max_length),str(klass["classes"].get(subclass_name).get("#loc")).rjust(6)))
 
212
            
 
213
        for method_name in methods_names :
 
214
            print "\t".join(("method",method_name.ljust(max_length),str(klass["#methods"].get(method_name).get("#loc")).rjust(6)))
 
215
 
 
216
    def _list_modules(self,module=None):
 
217
        if not module:
 
218
            module = self.current_node
 
219
        modules_names = [module_name for module_name in module.keys() if not module_name.startswith("#")]
 
220
        max_length    = max(map(lambda x:len(x),modules_names+["#modules"]))
 
221
        
 
222
        for module_name in modules_names:
 
223
            print "\t".join(("m",module_name.ljust(max_length),str(module.get(module_name).get("#loc"))))
 
224
 
 
225
    def _list_module(self,module=None):
 
226
        if not module :
 
227
            module = self.current_node
 
228
 
 
229
        module_info     = module.get("#name"),str(module.get("#loc"))
 
230
        classes         = [klass_name    for klass_name    in module.get("#classes").keys()   if not klass_name.startswith("#")]
 
231
        functions       = [function_name for function_name in module.get("#functions").keys() if not function_name.startswith("#")]
 
232
        classes_info    = []
 
233
        functions_info  = []        
 
234
        max_name_length = max(map(lambda x:len(x),functions+classes))
 
235
        if classes:
 
236
            classes_info   = [(klass_name.ljust(max_name_length),
 
237
                               str(module.get("#classes").get(klass_name).get("#loc")).rjust(6))
 
238
                              for klass_name in classes]
 
239
        if functions:
 
240
            functions_info = [(function_name.ljust(max_name_length),
 
241
                               str(module.get("#functions").get(function_name).get("#loc")).rjust(6))
 
242
                              for function_name in functions]
 
243
        
 
244
        print "Total : "+"\t".join(module_info)
 
245
        for class_info in classes_info:
 
246
            print "class".ljust(8)+"\t"+"\t".join(class_info)
 
247
        for function_info in functions_info:
 
248
            print "function".ljust(8)+"\t"+"\t".join(function_info)
 
249
 
 
250
    def do_cd(self,line=""):
 
251
        if line == "..":
 
252
            self.do_parent()
 
253
            self.prompt = self.path()+"> "            
 
254
            return
 
255
        
 
256
        node = self.get_node(line)
 
257
        if node :
 
258
            self.current_node = node
 
259
        self.prompt = self.path()+"> "
 
260
 
 
261
    @raise_problem
 
262
    def do_cat(self,line):
 
263
        node = self.get_node(line)
 
264
        print node["#code"]
 
265
        
 
266
    def get_node(self,path):
 
267
        elements = path.split("/")
 
268
        node     = self.current_node
 
269
        for i,element in enumerate(elements):
 
270
            x = self.fetch(element,node)
 
271
            if not x:
 
272
                return node
 
273
            if type(x) != dict:
 
274
                return x            
 
275
            else:
 
276
                node = x
 
277
        return node
 
278
 
 
279
    def fetch(self,element,node):
 
280
        if element in node:
 
281
            return node.get(element)
 
282
        else:
 
283
            for branch in "#modules","#methods","#functions","#classes" :
 
284
                branch_node = node.get(branch,{})
 
285
                if element in branch_node.keys():
 
286
                    return branch_node.get(element)
 
287
        
 
288
    @raise_problem    
 
289
    def completedefault(self,*args):
 
290
        user_input = args[1]
 
291
        # print "user_input",user_input
 
292
        arg = user_input.split(" ")[1]
 
293
        last_arg = arg.split("/")[-1]
 
294
        node = self.get_node(arg)
 
295
        if not node: # de-fense !
 
296
            node = self.current_node
 
297
        keys = node.keys()
 
298
        for branch in "#modules","#methods","#functions","#classes" :
 
299
            keys += node.get(branch,{}).keys()
 
300
        completions = [key for key in keys if key.startswith(last_arg) and not "#" in key]
 
301
        if "#" in last_arg:
 
302
            completions = [completion[1:] for completion in completions]
 
303
        # print "last_arg",last_arg
 
304
        if len(completions) == 1:
 
305
            completions[0] = completions[0] + "/"
 
306
        return completions
 
307
    
 
308
def main():
 
309
    if len(sys.argv) < 2 :
 
310
        usage()
 
311
        exit(1)
 
312
    file_path = sys.argv[1]
 
313
    st = tahar.SourceStats(file_path)
 
314
    st.process()
 
315
    CodeBrowser(st).cmdloop()
 
316
    
 
317
 
 
318
def usage():
 
319
    print sys.argv[0],"file_path"
 
320
 
 
321
 
 
322
 
 
323
if __name__ == "__main__":
 
324
    main()