~teejee2008/apt-toolkit/trunk

« back to all changes in this revision

Viewing changes to src/FileItem.vala

  • Committer: Tony George
  • Date: 2017-04-01 12:46:26 UTC
  • Revision ID: tony.george.kol@gmail.com-20170401124626-5sujdsdq06gjm6qu
Updated download manager backend; Fixed a random crash on downloading packages;

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * FileItem.vala
3
 
 *
4
 
 * Copyright 2016 Tony George <teejeetech@gmail.com>
5
 
 *
6
 
 * This program is free software; you can redistribute it and/or modify
7
 
 * it under the terms of the GNU General Public License as published by
8
 
 * the Free Software Foundation; either version 2 of the License, or
9
 
 * (at your option) any later version.
10
 
 *
11
 
 * This program is distributed in the hope that it will be useful,
12
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 * GNU General Public License for more details.
15
 
 *
16
 
 * You should have received a copy of the GNU General Public License
17
 
 * along with this program; if not, write to the Free Software
18
 
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 
 * MA 02110-1301, USA.
20
 
 *
21
 
 *
22
 
 */
23
 
 
24
 
using GLib;
25
 
using Gtk;
26
 
using Gee;
27
 
using Json;
28
 
 
29
 
using TeeJee.Logging;
30
 
using TeeJee.FileSystem;
31
 
using TeeJee.JSON;
32
 
using TeeJee.ProcessManagement;
33
 
using TeeJee.System;
34
 
using TeeJee.Misc;
35
 
using TeeJee.GtkHelper;
36
 
 
37
 
public class FileItem : GLib.Object {
38
 
        public string file_name = "";
39
 
        public string file_location = "";
40
 
        public string file_path = "";
41
 
        public FileType file_type = FileType.REGULAR;
42
 
        public DateTime modified;
43
 
 
44
 
        public bool is_selected = false;
45
 
        public bool is_symlink = false;
46
 
        public string symlink_target = "";
47
 
 
48
 
        public FileItem parent;
49
 
        public Gee.HashMap<string, FileItem> children;
50
 
        public Archive? task_ref;
51
 
        
52
 
        public long file_count = 0;
53
 
        public long dir_count = 0;
54
 
        private int64 _size = 0;
55
 
        private int64 _size_compressed = 0;
56
 
 
57
 
        public long file_count_total = 0;
58
 
        public long dir_count_total = 0;
59
 
 
60
 
        public string permissions = "";
61
 
        public string owner = "";
62
 
        public string group = "";
63
 
 
64
 
        public GLib.Icon icon;
65
 
 
66
 
        public bool is_dummy = false;
67
 
 
68
 
        public void init() {
69
 
                children = new Gee.HashMap<string, FileItem>();
70
 
        }
71
 
 
72
 
        public FileItem.base_archive(Archive? _task_ref, string name = "New Archive") {
73
 
                init();
74
 
                file_name = name;
75
 
                task_ref = _task_ref;
76
 
        }
77
 
 
78
 
        public FileItem.dummy(Archive? _task_ref, FileType _file_type) {
79
 
                init();
80
 
                is_dummy = true;
81
 
                file_type = _file_type;
82
 
                task_ref = _task_ref;
83
 
        }
84
 
 
85
 
        public FileItem.dummy_root() {
86
 
                init();
87
 
 
88
 
                file_name = "dummy";
89
 
                file_location = "";
90
 
        }
91
 
 
92
 
        //private
93
 
        private FileItem.from_path_and_type(Archive? _task_ref, string _file_path, FileType _file_type) {
94
 
                init();
95
 
 
96
 
                file_path = _file_path;
97
 
                file_name = file_basename(_file_path);
98
 
                file_location = file_parent(_file_path);
99
 
                file_type = _file_type;
100
 
                task_ref = _task_ref;
101
 
        }
102
 
 
103
 
        public int64 size {
104
 
                get{
105
 
                        return _size;
106
 
                }
107
 
        }
108
 
 
109
 
        public int64 size_compressed {
110
 
                get{
111
 
                        return _size_compressed;
112
 
                }
113
 
        }
114
 
 
115
 
        public FileItem add_child(string item_file_path, FileType item_file_type, int64 item_size, int64 item_size_compressed) {
116
 
                //create item
117
 
                var item = new FileItem.from_path_and_type(this.task_ref, item_file_path, item_file_type);
118
 
 
119
 
                //set parent and child
120
 
                item.parent = this;
121
 
 
122
 
                bool existing_file = false;
123
 
                if (!this.children.has_key(item.file_name)){
124
 
                        this.children[item.file_name] = item;
125
 
                }
126
 
                else{
127
 
                        existing_file = true;
128
 
                        item = this.children[item.file_name];
129
 
                }
130
 
 
131
 
                if (item_file_type == FileType.REGULAR) {
132
 
 
133
 
                        //set file sizes
134
 
                        if (item_size > 0) {
135
 
                                item._size = item_size;
136
 
                        }
137
 
                        if (item_size_compressed > 0) {
138
 
                                item._size_compressed = item_size_compressed;
139
 
                        }
140
 
 
141
 
                        //update file counts
142
 
                        if (!existing_file){
143
 
                                this.file_count++;
144
 
                                this.file_count_total++;
145
 
                                this._size += item_size;
146
 
                                this._size_compressed += item_size_compressed;
147
 
 
148
 
                                //update file count and size of parent dirs
149
 
                                var temp = this;
150
 
                                while (temp.parent != null) {
151
 
                                        temp.parent.file_count_total++;
152
 
                                        temp.parent._size += item_size;
153
 
                                        temp.parent._size_compressed += item_size_compressed;
154
 
                                        temp = temp.parent;
155
 
                                }
156
 
                        }
157
 
 
158
 
                        try {
159
 
                                item.icon = GLib.Icon.new_for_string("gtk-file");
160
 
                        }
161
 
                        catch (Error e) {
162
 
                                log_error (e.message);
163
 
                        }
164
 
                }
165
 
                else {
166
 
 
167
 
                        if (!existing_file){
168
 
                                
169
 
                                //update dir counts
170
 
                                this.dir_count++;
171
 
                                this.dir_count_total++;
172
 
                                //this.size += _size; //size will be updated when children are added
173
 
 
174
 
                                //update dir count of parent dirs
175
 
                                var temp = this;
176
 
                                while (temp.parent != null) {
177
 
                                        temp.parent.dir_count_total++;
178
 
                                        temp = temp.parent;
179
 
                                }
180
 
                        }
181
 
 
182
 
                        try {
183
 
                                item.icon = GLib.Icon.new_for_string("gtk-directory");
184
 
                        }
185
 
                        catch (Error e) {
186
 
                                log_error (e.message);
187
 
                        }
188
 
                }
189
 
 
190
 
                //log_debug("%3ld %3ld %s".printf(file_count, dir_count, file_path));
191
 
 
192
 
                return item;
193
 
        }
194
 
 
195
 
        public void clear_children() {
196
 
                this.children.clear();
197
 
        }
198
 
        
199
 
        public void query_children(int depth = -1) {
200
 
                FileEnumerator enumerator;
201
 
                FileInfo info;
202
 
                File file = File.parse_name (file_path);
203
 
 
204
 
                if (!file.query_exists()) {
205
 
                        return;
206
 
                }
207
 
                
208
 
                if ((file_type == FileType.DIRECTORY) && !is_symlink) {
209
 
                        if (depth == 0){
210
 
                                return;
211
 
                        }
212
 
                                
213
 
                        try{
214
 
                                //recurse children
215
 
                                enumerator = file.enumerate_children ("%s".printf(FileAttribute.STANDARD_NAME), 0);
216
 
                                while ((info = enumerator.next_file()) != null) {
217
 
                                        string child_name = info.get_name();
218
 
                                        string child_path = "%s/%s".printf(file_path, child_name);
219
 
                                        this.add_child_from_disk(child_path, depth - 1);
220
 
                                }
221
 
                        }
222
 
                        catch (Error e) {
223
 
                                log_error (e.message);
224
 
                        }
225
 
                }
226
 
        }
227
 
        
228
 
        public FileItem remove_child(string child_name) {
229
 
                FileItem child = null;
230
 
 
231
 
                if (this.children.has_key(child_name)) {
232
 
                        child = this.children[child_name];
233
 
                        this.children.unset(child_name);
234
 
 
235
 
                        if (child.file_type == FileType.REGULAR) {
236
 
                                //update file counts
237
 
                                this.file_count--;
238
 
                                this.file_count_total--;
239
 
 
240
 
                                //subtract child size
241
 
                                this._size -= child.size;
242
 
                                this._size_compressed -= child.size_compressed;
243
 
 
244
 
                                //update file count and size of parent dirs
245
 
                                var temp = this;
246
 
                                while (temp.parent != null) {
247
 
                                        temp.parent.file_count_total--;
248
 
 
249
 
                                        temp.parent._size -= child.size;
250
 
                                        temp.parent._size_compressed -= child.size_compressed;
251
 
 
252
 
                                        temp = temp.parent;
253
 
                                }
254
 
                        }
255
 
                        else {
256
 
                                //update dir counts
257
 
                                this.dir_count--;
258
 
                                this.dir_count_total--;
259
 
 
260
 
                                //subtract child counts
261
 
                                this.file_count_total -= child.file_count_total;
262
 
                                this.dir_count_total -= child.dir_count_total;
263
 
                                this._size -= child.size;
264
 
                                this._size_compressed -= child.size_compressed;
265
 
 
266
 
                                //update dir count of parent dirs
267
 
                                var temp = this;
268
 
                                while (temp.parent != null) {
269
 
                                        temp.parent.dir_count_total--;
270
 
 
271
 
                                        temp.parent.file_count_total -= child.file_count_total;
272
 
                                        temp.parent.dir_count_total -= child.dir_count_total;
273
 
                                        temp.parent._size -= child.size;
274
 
                                        temp.parent._size_compressed -= child.size_compressed;
275
 
 
276
 
                                        temp = temp.parent;
277
 
                                }
278
 
                        }
279
 
                }
280
 
 
281
 
                //log_debug("%3ld %3ld %s".printf(file_count, dir_count, file_path));
282
 
 
283
 
                return child;
284
 
        }
285
 
 
286
 
        public FileItem add_child_from_disk(string item_file_path, int depth = -1) {
287
 
                FileItem item = null;
288
 
 
289
 
                //log_debug("add_child_from_disk: %02d: %s".printf(depth, item_file_path));
290
 
                
291
 
                try {
292
 
                        FileEnumerator enumerator;
293
 
                        FileInfo info;
294
 
                        File file = File.parse_name (item_file_path);
295
 
 
296
 
                        GLib.Icon item_icon = null;
297
 
                        FileType item_file_type_actual = FileType.REGULAR;
298
 
                        FileType item_file_type_resolved = FileType.REGULAR;
299
 
                        bool item_is_symlink = false;
300
 
                        int64 item_size = 0;
301
 
                        DateTime item_modified = null;
302
 
                        string item_target = "";
303
 
                        
304
 
                        if (file.query_exists()) {
305
 
 
306
 
                                //get type without following symlinks
307
 
                                info = file.query_info("%s,%s,%s".printf(
308
 
                                                           FileAttribute.STANDARD_TYPE,
309
 
                                                           FileAttribute.STANDARD_ICON,
310
 
                                                           FileAttribute.STANDARD_SYMLINK_TARGET),
311
 
                                                       FileQueryInfoFlags.NOFOLLOW_SYMLINKS);
312
 
 
313
 
                                item_file_type_actual = info.get_file_type();
314
 
                                if (item_file_type_actual == FileType.SYMBOLIC_LINK) {
315
 
                                        item_icon = GLib.Icon.new_for_string("emblem-symbolic-link");
316
 
                                        item_is_symlink = true;
317
 
                                        item_target = info.get_symlink_target();
318
 
                                }
319
 
                                else {
320
 
                                        item_icon = info.get_icon();
321
 
                                        item_is_symlink = false;
322
 
                                }
323
 
 
324
 
                                //get file info - follow symlinks
325
 
                                info = file.query_info("%s,%s,%s".printf(
326
 
                                                           FileAttribute.STANDARD_TYPE,
327
 
                                                           FileAttribute.STANDARD_SIZE,
328
 
                                                           FileAttribute.TIME_MODIFIED), 0);
329
 
 
330
 
                                //get type
331
 
                                item_file_type_resolved = info.get_file_type();
332
 
 
333
 
                                //get size
334
 
                                if (!item_is_symlink && (item_file_type_resolved == FileType.REGULAR)) {
335
 
                                        item_size = info.get_size();
336
 
                                }
337
 
 
338
 
                                //get modified date
339
 
                                item_modified = (new DateTime.from_timeval_utc(info.get_modification_time())).to_local();
340
 
 
341
 
                                //add item
342
 
                                item = this.add_child(item_file_path, item_file_type_resolved, item_size, 0);
343
 
                                item.icon = item_icon;
344
 
                                item.is_symlink = item_is_symlink;
345
 
                                item.symlink_target = item_target;
346
 
                                item.modified = item_modified;
347
 
 
348
 
                                if ((item.file_type == FileType.DIRECTORY) && !item.is_symlink) {
349
 
                                        if (depth != 0){
350
 
                                                //recurse children
351
 
                                                enumerator = file.enumerate_children ("%s".printf(FileAttribute.STANDARD_NAME), 0);
352
 
                                                while ((info = enumerator.next_file()) != null) {
353
 
                                                        string child_path = "%s/%s".printf(item_file_path, info.get_name());
354
 
                                                        item.add_child_from_disk(child_path, depth - 1);
355
 
                                                }
356
 
                                        }
357
 
                                }
358
 
                        }
359
 
                }
360
 
                catch (Error e) {
361
 
                        log_error (e.message);
362
 
                }
363
 
 
364
 
                return item;
365
 
        }
366
 
 
367
 
        public FileItem add_descendant(string file_path, FileType ? _file_type, int64 item_size, int64 item_size_compressed) {
368
 
                string item_path = file_path.strip();
369
 
                FileType item_type = (_file_type == null) ? FileType.REGULAR : _file_type;
370
 
 
371
 
                if (item_path.has_suffix("/")) {
372
 
                        item_path = item_path[0:item_path.length - 1];
373
 
                        item_type = FileType.DIRECTORY;
374
 
                }
375
 
 
376
 
                string dir_name = "";
377
 
                string dir_path = "";
378
 
 
379
 
                //create dirs and find parent dir
380
 
                FileItem current_dir = this;
381
 
                string[] arr = item_path.split("/");
382
 
                for (int i = 0; i < arr.length - 1; i++) {
383
 
                        //get dir name
384
 
                        dir_name = arr[i];
385
 
 
386
 
                        //add dir
387
 
                        if (!current_dir.children.keys.contains(dir_name)) {
388
 
                                dir_path = (current_dir.parent == null) ? "" : current_dir.file_path + "/";
389
 
                                dir_path = "%s%s".printf(dir_path, dir_name);
390
 
                                current_dir.add_child(dir_path, FileType.DIRECTORY, 0, 0);
391
 
                        }
392
 
 
393
 
                        current_dir = current_dir.children[dir_name];
394
 
                }
395
 
 
396
 
                //get item name
397
 
                string item_name = arr[arr.length - 1];
398
 
 
399
 
                //add item
400
 
                if (!current_dir.children.keys.contains(item_name)) {
401
 
                        current_dir.add_child(item_path, item_type, item_size, item_size_compressed);
402
 
                }
403
 
 
404
 
                return current_dir.children[item_name];
405
 
        }
406
 
 
407
 
        public void print(int level) {
408
 
 
409
 
                if (level == 0) {
410
 
                        stdout.printf("\n");
411
 
                        stdout.flush();
412
 
                }
413
 
 
414
 
                stdout.printf("%s%s\n".printf(string.nfill(level * 2, ' '), file_name));
415
 
                stdout.flush();
416
 
 
417
 
                foreach (var key in this.children.keys) {
418
 
                        this.children[key].print(level + 1);
419
 
                }
420
 
        }
421
 
}
422
 
 
423
 
 
424