summaryrefslogtreecommitdiff
path: root/src/Upgrades.vala
blob: d60d1951ed783e508a2c3cda33ac4709324e8e19 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/* Copyright 2016 Software Freedom Conservancy Inc.
 *
 * This software is licensed under the GNU LGPL (version 2.1 or later).
 * See the COPYING file in this distribution.
 */

// Class for aggregating one-off "upgrade" tasks that occur at startup, such as
// moving or deleting files. This occurs after the UI is shown, so it's not appropriate
// for database updates and such.
public class Upgrades {
    private static Upgrades? instance = null;
    private uint64 total_steps = 0;
    private Gee.LinkedList<UpgradeTask> task_list = new Gee.LinkedList<UpgradeTask>();
    
    private Upgrades() {
        // Add all upgrade tasks here.
        add(new MimicsRemovalTask());
        
        if (Application.get_instance().get_raw_thumbs_fix_required())
            add(new FixupRawThumbnailsTask());
    }
    
    // Call this to initialize the subsystem.
    public static void init() {
        assert(instance == null);
        instance = new Upgrades();
    }

    public static Upgrades get_instance() {
        return instance;
    }
    
    // Gets the total number of steps for the progress monitor.
    public uint64 get_step_count() {
        return total_steps;
    }
    
    // Performs all upgrade tasks.
    public void execute(ProgressMonitor? monitor = null) {
        foreach (UpgradeTask task in task_list)
            task.execute(monitor);
    }
    
    private void add(UpgradeTask task) {
        total_steps += task.get_step_count();
        task_list.add(task);
    }
}

// Interface for upgrades that happen on startup.
// When creating a new upgrade task, you MUST add it to the constructor
// supplied in Upgrades (see above.)
private interface UpgradeTask : Object{
    // Returns the number of steps involved in the ugprade.
    public abstract uint64 get_step_count();
    
    // Performs the upgrade.  Note that when using the progress
    // monitor, the total number of steps must be equal to the
    // step count above.
    public abstract void execute(ProgressMonitor? monitor = null);
}

// Deletes the mimics folder, if it still exists.
// Note: for the step count to be consistent, files cannot be written
// to the mimcs folder for the durration of this task.
private class MimicsRemovalTask : Object, UpgradeTask {
    // Mimics folder (to be deleted, if present)
    private File mimic_dir = AppDirs.get_data_dir().get_child("mimics");
    private uint64 num_mimics = 0;
    
    public uint64 get_step_count() {
        try {
            num_mimics = count_files_in_directory(mimic_dir);
        } catch (Error e) {
            debug("Error on deleting mimics: %s", e.message);
        }
        return num_mimics;
    }
    
    public void execute(ProgressMonitor? monitor = null) {
        try {
            delete_all_files(mimic_dir, null, monitor, num_mimics, null);
            mimic_dir.delete();
        } catch (Error e) {
            debug("Could not delete mimics: %s", e.message);
        }
    }
}

// Deletes 'stale' thumbnails from camera raw files whose default developer was
// CAMERA and who may have been incorrectly generated from the embedded preview by
// previous versions of the application that had bug 4692.
private class FixupRawThumbnailsTask : Object, UpgradeTask {
    public uint64 get_step_count() {
        int num_raw_files = 0;
        
        foreach (PhotoRow phr in PhotoTable.get_instance().get_all()) {
            if (phr.master.file_format == PhotoFileFormat.RAW)
                num_raw_files++;
        }
        return num_raw_files;
    }
    
    public void execute(ProgressMonitor? monitor = null) {
        debug("Executing thumbnail deletion and fixup");
        
        foreach (PhotoRow phr in PhotoTable.get_instance().get_all()) {
            if ((phr.master.file_format == PhotoFileFormat.RAW) &&
                (phr.developer == RawDeveloper.CAMERA)) {
                ThumbnailCache.remove(LibraryPhoto.global.fetch(phr.photo_id));
            }
        }
    }
}