1/* Copyright 2016 Software Freedom Conservancy Inc.
2 *
3 * This software is licensed under the GNU LGPL (version 2.1 or later).
4 * See the COPYING file in this distribution.
5 */
6
7// Class for aggregating one-off "upgrade" tasks that occur at startup, such as
8// moving or deleting files. This occurs after the UI is shown, so it's not appropriate
9// for database updates and such.
10public class Upgrades {
11    private static Upgrades? instance = null;
12    private uint64 total_steps = 0;
13    private Gee.LinkedList<UpgradeTask> task_list = new Gee.LinkedList<UpgradeTask>();
14
15    private Upgrades() {
16        // Add all upgrade tasks here.
17        add(new MimicsRemovalTask());
18
19        if (Application.get_instance().get_raw_thumbs_fix_required())
20            add(new FixupRawThumbnailsTask());
21    }
22
23    // Call this to initialize the subsystem.
24    public static void init() {
25        assert(instance == null);
26        instance = new Upgrades();
27    }
28
29    public static Upgrades get_instance() {
30        return instance;
31    }
32
33    // Gets the total number of steps for the progress monitor.
34    public uint64 get_step_count() {
35        return total_steps;
36    }
37
38    // Performs all upgrade tasks.
39    public void execute(ProgressMonitor? monitor = null) {
40        foreach (UpgradeTask task in task_list)
41            task.execute(monitor);
42    }
43
44    private void add(UpgradeTask task) {
45        total_steps += task.get_step_count();
46        task_list.add(task);
47    }
48}
49
50// Interface for upgrades that happen on startup.
51// When creating a new upgrade task, you MUST add it to the constructor
52// supplied in Upgrades (see above.)
53private interface UpgradeTask : Object{
54    // Returns the number of steps involved in the upgrade.
55    public abstract uint64 get_step_count();
56
57    // Performs the upgrade.  Note that when using the progress
58    // monitor, the total number of steps must be equal to the
59    // step count above.
60    public abstract void execute(ProgressMonitor? monitor = null);
61}
62
63// Deletes the mimics folder, if it still exists.
64// Note: for the step count to be consistent, files cannot be written
65// to the mimcs folder for the duration of this task.
66private class MimicsRemovalTask : Object, UpgradeTask {
67    // Mimics folder (to be deleted, if present)
68    private File mimic_dir = AppDirs.get_data_dir().get_child("mimics");
69    private uint64 num_mimics = 0;
70
71    public uint64 get_step_count() {
72        try {
73            num_mimics = count_files_in_directory(mimic_dir);
74        } catch (Error e) {
75            debug("Error on deleting mimics: %s", e.message);
76        }
77        return num_mimics;
78    }
79
80    public void execute(ProgressMonitor? monitor = null) {
81        try {
82            delete_all_files(mimic_dir, null, monitor, num_mimics, null);
83            mimic_dir.delete();
84        } catch (Error e) {
85            debug("Could not delete mimics: %s", e.message);
86        }
87    }
88}
89
90// Deletes 'stale' thumbnails from camera raw files whose default developer was
91// CAMERA and who may have been incorrectly generated from the embedded preview by
92// previous versions of the application that had bug 4692.
93private class FixupRawThumbnailsTask : Object, UpgradeTask {
94    public uint64 get_step_count() {
95        int num_raw_files = 0;
96
97        foreach (PhotoRow phr in PhotoTable.get_instance().get_all()) {
98            if (phr.master.file_format == PhotoFileFormat.RAW)
99                num_raw_files++;
100        }
101        return num_raw_files;
102    }
103
104    public void execute(ProgressMonitor? monitor = null) {
105        debug("Executing thumbnail deletion and fixup");
106
107        foreach (PhotoRow phr in PhotoTable.get_instance().get_all()) {
108            if ((phr.master.file_format == PhotoFileFormat.RAW) &&
109                (phr.developer == RawDeveloper.CAMERA)) {
110                ThumbnailCache.remove(LibraryPhoto.global.fetch(phr.photo_id));
111            }
112        }
113    }
114}
115
116