summaryrefslogtreecommitdiff
path: root/src/data_imports/DataImportJob.vala
blob: 4035ae68db8d8451a38a3d8ff90eb93399b7bb63 (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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/* 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.
 */

namespace Spit.DataImports  {

/**
 * A specialized import job implementation for alien databases.
 */
public class DataImportJob : BatchImportJob {
    private DataImportSource import_source;
    private File? src_file;
    private uint64 filesize;
    private time_t exposure_time;
    private DataImportJob? associated = null;
    private HierarchicalTagIndex? detected_htags = null;
    
    public DataImportJob(DataImportSource import_source) {
        this.import_source = import_source;
        
        // stash everything called in prepare(), as it may/will be called from a separate thread
        src_file = import_source.get_file();
        filesize = import_source.get_filesize();
        exposure_time = import_source.get_exposure_time();
    }
    
    private HierarchicalTagIndex? build_exclusion_index(ImportableTag[] src_tags) {
        Gee.Set<string> detected_htags = new Gee.HashSet<string>();
        
        foreach (ImportableTag src_tag in src_tags) {
            string? prepped = HierarchicalTagUtilities.join_path_components(
                Tag.prep_tag_names(
                    build_path_components(src_tag)
                )
            );
            
            if (prepped != null && prepped.has_prefix(Tag.PATH_SEPARATOR_STRING)) {
                detected_htags.add(prepped);

                Gee.List<string> parents = HierarchicalTagUtilities.enumerate_parent_paths(prepped);
                foreach (string parent in parents)
                    detected_htags.add(parent);
            }
        }
        
        return (detected_htags.size > 0) ? HierarchicalTagIndex.from_paths(detected_htags) : null;
    }
    
    public time_t get_exposure_time() {
        return exposure_time;
    }
    
    public override string get_dest_identifier() {
        return import_source.get_filename();
    }
    
    public override string get_source_identifier() {
        return import_source.get_filename();
    }
    
    public override bool is_directory() {
        return false;
    }
    
    public override string get_basename() {
        return src_file.get_basename();
    }
    
    public override string get_path() {
        return src_file.get_parent().get_path();
    }
    
    public override void set_associated(BatchImportJob associated) {
        this.associated = associated as DataImportJob;
    }
    
    public override bool determine_file_size(out uint64 filesize, out File file) {
        file = null;
        filesize = this.filesize;
        
        return true;
    }
    
    public override bool prepare(out File file_to_import, out bool copy_to_library) throws Error {
        file_to_import = src_file;
        copy_to_library = false;
        
        detected_htags = build_exclusion_index(import_source.get_photo().get_tags());
        
        return true;
    }
    
    public override bool complete(MediaSource source, BatchImportRoll import_roll) throws Error {
        LibraryPhoto? photo = source as LibraryPhoto;
        if (photo == null)
            return false;
        
        ImportableMediaItem src_photo = import_source.get_photo();
        
        // tags
        if (detected_htags != null) {
            Gee.Collection<string> paths = detected_htags.get_all_paths();

            foreach (string path in paths)
                Tag.for_path(path);
        }
        
        ImportableTag[] src_tags = src_photo.get_tags();
        foreach (ImportableTag src_tag in src_tags) {
            string? prepped = HierarchicalTagUtilities.join_path_components(
                Tag.prep_tag_names(
                    build_path_components(src_tag)
                )
            );
            if (prepped != null) {
                if (HierarchicalTagUtilities.enumerate_path_components(prepped).size == 1) {
                    if (prepped.has_prefix(Tag.PATH_SEPARATOR_STRING))
                        prepped = HierarchicalTagUtilities.hierarchical_to_flat(prepped);
                } else {
                    Gee.List<string> parents =
                        HierarchicalTagUtilities.enumerate_parent_paths(prepped);

                    assert(parents.size > 0);

                    string top_level_parent = parents.get(0);
                    string flat_top_level_parent =
                        HierarchicalTagUtilities.hierarchical_to_flat(top_level_parent);
                    
                    if (Tag.global.exists(flat_top_level_parent))
                        Tag.for_path(flat_top_level_parent).promote();
                }

                Tag.for_path(prepped).attach(photo);
            }
        }
        // event
        ImportableEvent? src_event = src_photo.get_event();
        if (src_event != null) {
            string? prepped = prepare_input_text(src_event.get_name(), 
                PrepareInputTextOptions.DEFAULT, -1);
            if (prepped != null)
                Event.generate_single_event(photo, import_roll.generated_events, prepped);
        }
        // rating
        Rating dst_rating;
        ImportableRating src_rating = src_photo.get_rating();
        if (src_rating.is_rejected())
            dst_rating = Rating.REJECTED;
        else if (src_rating.is_unrated())
            dst_rating = Rating.UNRATED;
        else
            dst_rating = Rating.unserialize(src_rating.get_value());
        photo.set_rating(dst_rating);
        // title
        string? title = src_photo.get_title();
        if (title != null)
            photo.set_title(title);
        // exposure time
        time_t? date_time = src_photo.get_exposure_time();
        if (date_time != null)
            photo.set_exposure_time(date_time);
        // import ID
        photo.set_import_id(import_roll.import_id);
        
        return true;
    }
    
    private string[] build_path_components(ImportableTag tag) {
        // use a linked list as we are always inserting in head position
        Gee.List<string> components = new Gee.LinkedList<string>();
        for (ImportableTag current_tag = tag; current_tag != null; current_tag = current_tag.get_parent()) {
            components.insert(0, HierarchicalTagUtilities.make_flat_tag_safe(current_tag.get_name()));
        }
        return components.to_array();
    }
}

}