~ubuntu-branches/ubuntu/quantal/shotwell/quantal

« back to all changes in this revision

Viewing changes to src/alien_db/f_spot/FSpotDatabase.vala

  • Committer: Package Import Robot
  • Author(s): Robert Ancell
  • Date: 2012-02-21 13:52:58 UTC
  • mto: This revision was merged to the branch mainline in revision 47.
  • Revision ID: package-import@ubuntu.com-20120221135258-ao9jiib5qicomq7q
Tags: upstream-0.11.92
ImportĀ upstreamĀ versionĀ 0.11.92

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright 2011 Yorba Foundation
2
 
 *
3
 
 * This software is licensed under the GNU Lesser General Public License
4
 
 * (version 2.1 or later).  See the COPYING file in this distribution. 
5
 
 */
6
 
 
7
 
namespace AlienDb.FSpot {
8
 
 
9
 
internal class FSpotTagsCache : Object {
10
 
    private FSpotTagsTable tags_table;
11
 
    private Gee.HashMap<FSpotTagID, FSpotDatabaseTag> tags_map;
12
 
    
13
 
    public FSpotTagsCache(FSpotTagsTable tags_table) throws DatabaseError {
14
 
        this.tags_table = tags_table;
15
 
        tags_map = new Gee.HashMap<FSpotTagID, FSpotDatabaseTag> ();
16
 
    }
17
 
    
18
 
    public FSpotDatabaseTag get_tag(FSpotTagRow tag_row) throws DatabaseError {
19
 
        FSpotDatabaseTag? tag = tags_map.get(tag_row.tag_id);
20
 
        if (tag != null) {
21
 
            return tag;
22
 
        } else {
23
 
            FSpotDatabaseTag? parent_tag = get_tag_from_id(tag_row.category_id);
24
 
            FSpotDatabaseTag new_tag = new FSpotDatabaseTag(tag_row, parent_tag);
25
 
            tags_map[tag_row.tag_id] = new_tag;
26
 
            return new_tag;
27
 
        }
28
 
    }
29
 
    
30
 
    private FSpotDatabaseTag? get_tag_from_id(FSpotTagID tag_id) throws DatabaseError {
31
 
        if (tag_id.is_null() || tag_id.is_invalid())
32
 
            return null;
33
 
        FSpotDatabaseTag? tag = tags_map.get(tag_id);
34
 
        if (tag != null)
35
 
            return tag;
36
 
        FSpotTagRow? tag_row = tags_table.get_by_id(tag_id);
37
 
        if (tag_row != null) {
38
 
            FSpotDatabaseTag? parent_tag = get_tag_from_id(tag_row.category_id);
39
 
            FSpotDatabaseTag new_tag = new FSpotDatabaseTag(tag_row, parent_tag);
40
 
            tags_map[tag_id] = new_tag;
41
 
            return new_tag;
42
 
        }
43
 
        return null;
44
 
    }
45
 
}
46
 
 
47
 
/**
48
 
 * An implementation of AlienDatabase that is able to read from the F-Spot
49
 
 * database and extract the relevant objects.
50
 
 */
51
 
public class FSpotDatabase : Object, AlienDatabase {
52
 
    private AlienDatabaseID id;
53
 
    private Sqlite.Database fspot_db;
54
 
    private FSpotMetaTable meta_table;
55
 
    private FSpotPhotosTable photos_table;
56
 
    private FSpotPhotoVersionsTable photo_versions_table;
57
 
    private FSpotTagsTable tags_table;
58
 
    private FSpotTagsCache tags_cache;
59
 
    private FSpotRollsTable rolls_table;
60
 
    private int64 hidden_tag_id;
61
 
    
62
 
    public FSpotDatabase(FSpotDatabaseDriver driver, AlienDatabaseID id) throws DatabaseError, AlienDatabaseError {
63
 
        this.id = id;
64
 
        initialize(driver, id.driver_specific_uri);
65
 
    }
66
 
    
67
 
    public FSpotDatabase.from_file(FSpotDatabaseDriver driver, File db_file) throws DatabaseError, AlienDatabaseError {
68
 
        this.id = new AlienDatabaseID(driver.get_id(), db_file.get_path());
69
 
        initialize(driver, db_file.get_path());
70
 
    }
71
 
    
72
 
    private void initialize(FSpotDatabaseDriver driver, string filename) throws DatabaseError, AlienDatabaseError {
73
 
        int res = Sqlite.Database.open_v2(filename, out fspot_db,
74
 
            Sqlite.OPEN_READONLY, null);
75
 
        if (res != Sqlite.OK)
76
 
            throw new DatabaseError.ERROR("Unable to open F-Spot database %s: %d", filename, res);
77
 
        meta_table = new FSpotMetaTable(fspot_db);
78
 
        hidden_tag_id = meta_table.get_hidden_tag_id();
79
 
        
80
 
        FSpotDatabaseBehavior db_behavior = new FSpotDatabaseBehavior(driver, get_version());
81
 
        
82
 
        photos_table = new FSpotPhotosTable(fspot_db, db_behavior);
83
 
        photo_versions_table = new FSpotPhotoVersionsTable(fspot_db, db_behavior);
84
 
        tags_table = new FSpotTagsTable(fspot_db, db_behavior);
85
 
        tags_cache = new FSpotTagsCache(tags_table);
86
 
        rolls_table = new FSpotRollsTable(fspot_db, db_behavior);
87
 
    }
88
 
    
89
 
    ~FSpotDatabase() {
90
 
    }
91
 
    
92
 
    public string get_uri() {
93
 
        return id.to_uri();
94
 
    }
95
 
    
96
 
    public string get_display_name() {
97
 
        return _("F-Spot");
98
 
    }
99
 
    
100
 
    private AlienDatabaseVersion get_version() throws DatabaseError {
101
 
        return new AlienDatabaseVersion.from_string(meta_table.get_db_version());
102
 
    }
103
 
    
104
 
    public Gee.Collection<AlienDatabasePhoto> get_photos() throws DatabaseError {
105
 
        Gee.List<AlienDatabasePhoto> photos = new Gee.ArrayList<AlienDatabasePhoto>();
106
 
 
107
 
        foreach (FSpotPhotoRow photo_row in photos_table.get_all()) {
108
 
            bool hidden = false;
109
 
            bool favorite = false;
110
 
            Gee.ArrayList<AlienDatabaseTag> tags = new Gee.ArrayList<AlienDatabaseTag>();
111
 
            AlienDatabaseEvent? event = null;
112
 
            FSpotRollRow? roll_row = null;
113
 
            
114
 
            // TODO: We do not convert F-Spot events to Shotwell events because F-Spot's events
115
 
            // are essentially tags.  We would need to detect if the tag is an event (use
116
 
            // is_tag_event) and then assign the event to the photo ... since a photo can be
117
 
            // in multiple F-Spot events, we would need to pick one, and since their tags
118
 
            // are heirarchical, we would need to pick a name (probably the leaf)
119
 
            try {
120
 
                foreach (FSpotTagRow tag_row in tags_table.get_by_photo_id(photo_row.photo_id)) {
121
 
                    FSpotDatabaseTag tag = tags_cache.get_tag(tag_row);
122
 
                    if (is_tag_hidden(tag))
123
 
                        hidden = true;
124
 
                    else if (is_tag_favorite(tag))
125
 
                        favorite = true;
126
 
                    else
127
 
                        tags.add(tag);
128
 
                }
129
 
            } catch(DatabaseError e) {
130
 
                // log the error and leave the tag list empty
131
 
                message("Failed to retrieve tags for photo ID %ld: %s", (long) photo_row.photo_id.id,
132
 
                    e.message);
133
 
            }
134
 
            
135
 
            try {
136
 
                roll_row = rolls_table.get_by_id(photo_row.roll_id);
137
 
            } catch (DatabaseError e) {
138
 
                // log the error and leave the roll row null
139
 
                message("Failed to retrieve roll for photo ID %ld: %s", (long) photo_row.photo_id.id,
140
 
                    e.message);
141
 
            }
142
 
            
143
 
            try {
144
 
                bool photo_versions_added = false;
145
 
                foreach (FSpotPhotoVersionRow photo_version_row in photo_versions_table.get_by_photo_id(photo_row.photo_id)) {
146
 
                    photos.add(new FSpotDatabasePhoto(
147
 
                        photo_row, photo_version_row, roll_row, tags, event, hidden, favorite
148
 
                    ));
149
 
                    photo_versions_added = true;
150
 
                }
151
 
                
152
 
                // older versions of F-Spot (0.4.3.1 at least, perhaps later) did not maintain photo_versions,
153
 
                // this handles that case
154
 
                if (!photo_versions_added)
155
 
                    photos.add(new FSpotDatabasePhoto(
156
 
                        photo_row, null, roll_row, tags, event, hidden, favorite
157
 
                    ));
158
 
            } catch (DatabaseError e) {
159
 
                // if we can't load the different versions, do the best we can
160
 
                // and create one photo from the photo row that was found earlier
161
 
                message("Failed to retrieve versions for photo ID %ld: %s", (long) photo_row.photo_id.id,
162
 
                    e.message);
163
 
                photos.add(new FSpotDatabasePhoto(
164
 
                    photo_row, null, roll_row, tags, event, hidden, favorite
165
 
                ));
166
 
            }
167
 
        }
168
 
        
169
 
        return photos;
170
 
    }
171
 
    
172
 
    public bool is_tag_event(FSpotDatabaseTag tag) {
173
 
        bool result = (FSpotTagsTable.STOCK_ICON_EVENTS == tag.get_row().stock_icon);
174
 
        if (!result) {
175
 
            FSpotDatabaseTag? parent = tag.get_fspot_parent();
176
 
            if (parent == null)
177
 
                result = false;
178
 
            else
179
 
                result = is_tag_event(parent);
180
 
        }
181
 
        return result;
182
 
    }
183
 
    
184
 
    public bool is_tag_hidden(FSpotDatabaseTag tag) {
185
 
        bool result = (hidden_tag_id == tag.get_row().tag_id.id);
186
 
        if (!result) {
187
 
            FSpotDatabaseTag? parent = tag.get_fspot_parent();
188
 
            if (parent == null)
189
 
                result = false;
190
 
            else
191
 
                result = is_tag_hidden(parent);
192
 
        }
193
 
        return result;
194
 
    }
195
 
    
196
 
    public bool is_tag_favorite(FSpotDatabaseTag tag) {
197
 
        bool result = (FSpotTagsTable.STOCK_ICON_FAV == tag.get_row().stock_icon);
198
 
        if (!result) {
199
 
            FSpotDatabaseTag? parent = tag.get_fspot_parent();
200
 
            if (parent == null)
201
 
                result = false;
202
 
            else
203
 
                result = is_tag_favorite(parent);
204
 
        }
205
 
        return result;
206
 
    }
207
 
}
208
 
 
209
 
}
210