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