1 module filenode;
2 import std.array;
3 import std.file;
4 import std.stdio;
5 import std.algorithm;
6 
7 struct FileNode {
8   string name;
9   ulong weight;
10   FileNode[] children;
11   bool invalid;
12   this(string name) {
13     this.name = name;
14     this.invalid = true;
15   }
16   this(string name, ulong weight) {
17     this(name, weight, null);
18   }
19   this(string name, ulong weight, FileNode[] childs) {
20     this.name = name;
21     this.weight = weight;
22     this.children = childs;
23   }
24   FileNode[] childs() {
25     return children;
26   }
27   ulong getWeight() {
28     return weight;
29   }
30   string getName() {
31     return name;
32   }
33   string toString() {
34     import std.conv;
35     return "{ name: \"" ~getName() ~ "\" , weight: " ~ getWeight().to!string ~ " }";
36   }
37 }
38 
39 FileNode calcFileNode(DirEntry entry) {
40   if (entry.isDir) {
41     auto childs = dirEntries(entry.name, SpanMode.shallow, false)
42       .map!(v => calcFileNode(v))
43       .filter!(v => !v.invalid).array()
44       .sort!((a, b) => a.getWeight() > b.getWeight()).array();
45     auto childSize = 0L.reduce!((sum, v) => sum + v.getWeight)(childs);
46     return FileNode(entry, childSize, childs);
47   } else {
48     try {
49       size_t s = DirEntry(entry).size;
50       return FileNode(entry, s);
51     } catch (Exception e) {
52       writeln("problems with file", entry);
53       return FileNode(entry);
54     }
55   }
56 }
57 
58 size_t calcSize(DirEntry entry) {
59   if (entry.isDir) {
60     size_t res = 0;
61     foreach (DirEntry e; dirEntries(entry.name, SpanMode.shallow, false)) {
62       res += calcSize(e);
63     }
64     return res;
65   } else {
66     size_t res = 0;
67     try {
68       res = entry.size;
69     } catch (Exception e) {
70     }
71     return res;
72   }
73 }
74 
75 size_t calcSize(string file) {
76   return calcSize(DirEntry(file));
77 }