Merge lp:~rainct/nautilus/nautilus-zg into lp:~rainct/nautilus/nautilus-orig
- nautilus-zg
- Merge into nautilus-orig
Status: | Needs review | ||||||||
---|---|---|---|---|---|---|---|---|---|
Proposed branch: | lp:~rainct/nautilus/nautilus-zg | ||||||||
Merge into: | lp:~rainct/nautilus/nautilus-orig | ||||||||
Diff against target: |
740 lines (+613/-1) 6 files modified
libnautilus-private/Makefile.am (+2/-0) libnautilus-private/nautilus-file-operations.c (+184/-0) libnautilus-private/nautilus-file.c (+28/-1) test/Makefile.am (+6/-0) test/run-zeitgeist-test.sh (+50/-0) test/test-nautilus-zeitgeist.c (+343/-0) |
||||||||
To merge this branch: | bzr merge lp:~rainct/nautilus/nautilus-zg | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Sebastien Bacher (community) | Needs Fixing | ||
Michal Hruby (community) | Approve | ||
Mikkel Kamstrup Erlandsen (community) | Needs Fixing | ||
Siegfried Gevatter | Pending | ||
Review via email:
|
Commit message
Description of the change
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Mikkel Kamstrup Erlandsen (kamstrup) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Mikkel Kamstrup Erlandsen (kamstrup) wrote : | # |
Oh - and can you attach it to a bug report against Nautilus please?
- 273. By Siegfried Gevatter
-
Update for new libzg.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Siegfried Gevatter (rainct) wrote : | # |
11:42 <RainCT> kamstrup: "g_path_get_dirname (uri)" I'm giving it an URI so it's supposed to work
11:42 <kamstrup> RainCT: ah, of course
11:43 <kamstrup> RainCT: should be fine as is
12:03 <RainCT> kamstrup: `done' is supposed to get the value of debuting_
12:03 <kamstrup> ah, that way
12:04 <kamstrup> so you're filtering out stuff that didn't complete properly
- 274. By Siegfried Gevatter
-
And let it compile even
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Mikkel Kamstrup Erlandsen (kamstrup) wrote : | # |
180 + gboolean *done;
181 + g_hash_
182 + while (g_hash_
Woopsiedaisy... This looks like a stackoverflow on 64 bit... A pointer to a pointer to a gboolean. I think you must declare 'done' without the asterisk ;-)
You have this error one other place as well.
- 275. By Siegfried Gevatter
-
change gboolean* -> gboolean
- 276. By Siegfried Gevatter
-
Start working on tests.
- 277. By Siegfried Gevatter
-
Tests are working! Now we just need to add some more.
- 278. By Siegfried Gevatter
-
Add more tests! \o/
- 279. By Siegfried Gevatter
-
remove thing
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Michal Hruby (mhr3) wrote : | # |
43 + zeitgeist_
Is this running in the main thread or some worker?
182 + while (g_hash_
Why the (void**) cast?
Nice job on the tests, but could we use the dbus-test-runner now that it works?
- 280. By Siegfried Gevatter
-
Minor changes (show debug, don't abort on warning, void**->gpointer*,
run Zeitgeist without FTS).
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Siegfried Gevatter (rainct) wrote : | # |
> Is this running in the main thread or some worker?
The Zeitgeist code is inside a g_io_scheduler_
> Why the (void**) cast?
Cause it's way more awesome than gpointer.
> Nice job on the tests, but could we use the dbus-test-runner now that it works?
Problem is someone eats the environment variables (to run Zeitgeist with temporary database). A way around this is launching zeitgeist-
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Michal Hruby (mhr3) wrote : | # |
All good then, approve from me.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Sebastien Bacher (seb128) wrote : | # |
the tests/Makefile.am first change needs a trailing '\' on its line or that breaks the makefile and fails to build
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Sebastien Bacher (seb128) wrote : | # |
I've uploaded nautilus with that patch (with the previous issue fixed) to https:/
- 281. By Siegfried Gevatter
-
patch by mhr3
- 282. By Siegfried Gevatter
-
Fix by Chris Coulson
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Sebastien Bacher (seb128) wrote : | # |
just for the record bug #944624 is a segfault on 64 bit archs created by it
Chris Coulson fixed it:
nautilus (1:3.3.90-0ubuntu6) precise; urgency=low
* Fix LP: #944624 - Don't stick a pointer to an int, as it causes stack
corruption on 64-bit architectures
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Sebastien Bacher (seb128) wrote : | # |
Siegfried, could you update the GNOME bug with the fixed version?
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Sebastien Bacher (seb128) wrote : | # |
bug #947489 (segfault in_log_
- 283. By Siegfried Gevatter
-
Make sure data->original_uri isn't NULL before freeing it.
- 284. By Siegfried Gevatter
-
Initialize GError to NULL.
From http://
developer. gnome.org/ glib/2. 31/glib- Error-Reporting .html:
"A GError* must be initialized to NULL before passing its address to a
function that can report errors."
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Sebastien Bacher (seb128) wrote : | # |
r284 is weird, it added diffs to quite some autogenerated files?
- 285. By Siegfried Gevatter
-
Revert accidentally committed changes
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Sebastien Bacher (seb128) wrote : | # |
r282 is weird
- while (g_hash_
+ while (g_hash_
did you really mean to change &done to done?
- 286. By Siegfried Gevatter
-
fix typo
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Siegfried Gevatter (rainct) wrote : | # |
Not really, 282 is supposed to be Chris' changes. Sorry.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Sebastien Bacher (seb128) wrote : | # |
thanks, r286 has that now:
-if (data->
+g_free (data->
seems to revert a null check fix from a previous revision? wanted?
- 287. By Siegfried Gevatter
-
Revert r283, dunno what I was doing there.
So, the only change since Chris' is initializing the GError.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Michal Hruby (mhr3) wrote : | # |
> thanks, r286 has that now:
>
> -if (data->
> +g_free (data->
>
> seems to revert a null check fix from a previous revision? wanted?
FWIW g_free is NULL-safe, so it doesn't matter.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Sebastien Bacher (seb128) wrote : | # |
could somebody set that one as merge or rejected? it got in but the vcs used is wrong
Unmerged revisions
- 287. By Siegfried Gevatter
-
Revert r283, dunno what I was doing there.
So, the only change since Chris' is initializing the GError.
- 286. By Siegfried Gevatter
-
fix typo
- 285. By Siegfried Gevatter
-
Revert accidentally committed changes
- 284. By Siegfried Gevatter
-
Initialize GError to NULL.
From http://
developer. gnome.org/ glib/2. 31/glib- Error-Reporting .html:
"A GError* must be initialized to NULL before passing its address to a
function that can report errors." - 283. By Siegfried Gevatter
-
Make sure data->original_uri isn't NULL before freeing it.
- 282. By Siegfried Gevatter
-
Fix by Chris Coulson
- 281. By Siegfried Gevatter
-
patch by mhr3
- 280. By Siegfried Gevatter
-
Minor changes (show debug, don't abort on warning, void**->gpointer*,
run Zeitgeist without FTS). - 279. By Siegfried Gevatter
-
remove thing
- 278. By Siegfried Gevatter
-
Add more tests! \o/
Preview Diff
1 | === modified file 'libnautilus-private/Makefile.am' |
2 | --- libnautilus-private/Makefile.am 2012-02-02 12:48:30 +0000 |
3 | +++ libnautilus-private/Makefile.am 2012-03-08 17:15:43 +0000 |
4 | @@ -12,6 +12,7 @@ |
5 | $(WARNING_CFLAGS) \ |
6 | $(DISABLE_DEPRECATED_CFLAGS) \ |
7 | $(TRACKER_CFLAGS) \ |
8 | + `pkg-config --cflags zeitgeist-1.0` \ |
9 | -DDATADIR=\""$(datadir)"\" \ |
10 | -DSYSCONFDIR=\""$(sysconfdir)"\" \ |
11 | -DNAUTILUS_DATADIR=\""$(datadir)/nautilus"\" \ |
12 | @@ -44,6 +45,7 @@ |
13 | |
14 | libnautilus_private_la_LDFLAGS = \ |
15 | -no-undefined \ |
16 | + `pkg-config --libs zeitgeist-1.0` \ |
17 | $(NULL) |
18 | |
19 | libnautilus_private_la_LIBADD = \ |
20 | |
21 | === modified file 'libnautilus-private/nautilus-file-operations.c' |
22 | --- libnautilus-private/nautilus-file-operations.c 2012-02-02 12:48:30 +0000 |
23 | +++ libnautilus-private/nautilus-file-operations.c 2012-03-08 17:15:43 +0000 |
24 | @@ -64,6 +64,8 @@ |
25 | #include "nautilus-file-utilities.h" |
26 | #include "nautilus-file-conflict-dialog.h" |
27 | |
28 | +#include <zeitgeist.h> |
29 | + |
30 | /* TODO: TESTING!!! */ |
31 | |
32 | typedef struct { |
33 | @@ -189,6 +191,104 @@ |
34 | #define MERGE_ALL _("Merge _All") |
35 | #define COPY_FORCE _("Copy _Anyway") |
36 | |
37 | +#define ZEITGEIST_NAUTILUS_ACTOR "application://nautilus.desktop" |
38 | + |
39 | +static void |
40 | +send_event_to_zeitgeist (ZeitgeistEvent *event) |
41 | +{ |
42 | + ZeitgeistLog *log = zeitgeist_log_get_default (); |
43 | + zeitgeist_log_insert_events_no_reply (log, event, NULL); |
44 | +} |
45 | + |
46 | +typedef struct { |
47 | + const char *event_interpretation; |
48 | + //char *event_origin; |
49 | + GFile *file; |
50 | + gchar *original_uri; // for MOVE_EVENT |
51 | +} _ZeitgeistFileEventData; |
52 | + |
53 | +static void |
54 | +_log_zeitgeist_event_for_file_cb (GObject *source_object, |
55 | + GAsyncResult *res, gpointer user_data) |
56 | +{ |
57 | + _ZeitgeistFileEventData *data; |
58 | + GError *error; |
59 | + GFileInfo *info; |
60 | + gchar *uri; |
61 | + gchar *origin; |
62 | + const gchar *display_name; |
63 | + const gchar *mimetype; |
64 | + |
65 | + data = user_data; |
66 | + |
67 | + error = NULL; |
68 | + info = g_file_query_info_finish (G_FILE (source_object), res, &error); |
69 | + |
70 | + if (info) { |
71 | + uri = g_file_get_uri (data->file); |
72 | + origin = g_path_get_dirname (uri); |
73 | + display_name = g_file_info_get_display_name (info); |
74 | + mimetype = g_file_info_get_content_type (info); |
75 | + } else { |
76 | + g_warning ("Error getting info: %s\n", error->message); |
77 | + g_error_free (error); |
78 | + g_object_unref (data->file); |
79 | + g_free (data->original_uri); |
80 | + g_free (data); |
81 | + return; // skip this event |
82 | + } |
83 | + |
84 | + ZeitgeistSubject *subject = zeitgeist_subject_new_full ( |
85 | + (data->original_uri) ? (data->original_uri) : uri, |
86 | + NULL, // subject interpretation - auto-guess |
87 | + NULL, // suject manifestation - auto-guess |
88 | + mimetype, |
89 | + origin, |
90 | + display_name, |
91 | + NULL // storage - auto-guess |
92 | + ); |
93 | + |
94 | + if (data->original_uri) |
95 | + zeitgeist_subject_set_current_uri (subject, uri); |
96 | + |
97 | + g_free (uri); |
98 | + g_free (origin); |
99 | + g_object_unref (info); |
100 | + |
101 | + if (subject) { |
102 | + ZeitgeistEvent *event = zeitgeist_event_new_full ( |
103 | + data->event_interpretation, |
104 | + ZEITGEIST_ZG_USER_ACTIVITY, |
105 | + ZEITGEIST_NAUTILUS_ACTOR, |
106 | + subject, NULL); |
107 | + send_event_to_zeitgeist (event); |
108 | + } |
109 | + |
110 | + g_object_unref (data->file); |
111 | + g_free (data->original_uri); |
112 | + g_free (data); |
113 | +} |
114 | + |
115 | +static void |
116 | +log_zeitgeist_event_for_file_no_reply (const char *event_interpretation, |
117 | + GFile *file, gchar *original_uri) |
118 | +{ |
119 | + _ZeitgeistFileEventData *data; |
120 | + data = g_new0 (_ZeitgeistFileEventData, 1); |
121 | + |
122 | + data->event_interpretation = event_interpretation; |
123 | + data->original_uri = original_uri; |
124 | + data->file = file; |
125 | + |
126 | + g_file_query_info_async (file, |
127 | + G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME "," |
128 | + G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, |
129 | + G_FILE_QUERY_INFO_NONE, |
130 | + G_PRIORITY_DEFAULT, |
131 | + NULL, |
132 | + _log_zeitgeist_event_for_file_cb, data); |
133 | +} |
134 | + |
135 | static void |
136 | mark_desktop_file_trusted (CommonJob *common, |
137 | GCancellable *cancellable, |
138 | @@ -1835,6 +1935,35 @@ |
139 | |
140 | job = user_data; |
141 | |
142 | + // Send event to Zeitgeist for deletions/trash |
143 | + GList *file_iter = job->files; |
144 | + while (file_iter != NULL) { |
145 | + gchar *uri = g_file_get_uri (file_iter->data); |
146 | + gchar *origin = g_path_get_dirname (uri); |
147 | + gchar *parse_name = g_file_get_parse_name (file_iter->data); |
148 | + gchar *display_name = g_path_get_basename (parse_name); |
149 | + ZeitgeistEvent *event = zeitgeist_event_new_full ( |
150 | + ZEITGEIST_ZG_DELETE_EVENT, |
151 | + ZEITGEIST_ZG_USER_ACTIVITY, |
152 | + ZEITGEIST_NAUTILUS_ACTOR, |
153 | + zeitgeist_subject_new_full ( |
154 | + uri, |
155 | + NULL, // subject interpretation - auto-guess |
156 | + NULL, // suject manifestation - auto-guess |
157 | + NULL, // mime-type |
158 | + origin, |
159 | + display_name, |
160 | + NULL // storage - auto-guess |
161 | + ), NULL); |
162 | + send_event_to_zeitgeist (event); |
163 | + g_free (uri); |
164 | + g_free (origin); |
165 | + g_free (parse_name); |
166 | + g_free (display_name); |
167 | + file_iter = g_list_next (file_iter); |
168 | + } |
169 | + // --- |
170 | + |
171 | g_list_free_full (job->files, g_object_unref); |
172 | |
173 | if (job->done_callback) { |
174 | @@ -4433,6 +4562,23 @@ |
175 | job->done_callback (job->debuting_files, job->done_callback_data); |
176 | } |
177 | |
178 | + // Send event to Zeitgeist |
179 | + GHashTableIter iter; |
180 | + GFile *file; |
181 | + gpointer done; |
182 | + g_hash_table_iter_init (&iter, job->debuting_files); |
183 | + while (g_hash_table_iter_next (&iter, (gpointer *) &file, &done)) { |
184 | + if (GPOINTER_TO_INT (done)) { |
185 | + // operation was completed successfully for this file |
186 | + g_object_ref (file); |
187 | + // FIXME: Set event origin to the original file URI, if we |
188 | + // can somehow figure out which one it is. |
189 | + log_zeitgeist_event_for_file_no_reply ( |
190 | + ZEITGEIST_ZG_CREATE_EVENT, file, NULL); |
191 | + } |
192 | + } |
193 | + // --- |
194 | + |
195 | g_list_free_full (job->files, g_object_unref); |
196 | if (job->destination) { |
197 | g_object_unref (job->destination); |
198 | @@ -4978,6 +5124,19 @@ |
199 | job->done_callback (job->debuting_files, job->done_callback_data); |
200 | } |
201 | |
202 | + // Send event to Zeitgeist for moved files (not renaming) |
203 | + GList *file_iter = job->files; |
204 | + while (file_iter != NULL) { |
205 | + char *basename = g_file_get_basename (file_iter->data); |
206 | + GFile *new_file = g_file_get_child (job->destination, basename); |
207 | + g_free (basename); |
208 | + |
209 | + log_zeitgeist_event_for_file_no_reply (ZEITGEIST_ZG_MOVE_EVENT, |
210 | + new_file, g_file_get_uri (file_iter->data)); |
211 | + file_iter = g_list_next (file_iter); |
212 | + } |
213 | + // --- |
214 | + |
215 | g_list_free_full (job->files, g_object_unref); |
216 | g_object_unref (job->destination); |
217 | g_hash_table_unref (job->debuting_files); |
218 | @@ -5295,6 +5454,23 @@ |
219 | job->done_callback (job->debuting_files, job->done_callback_data); |
220 | } |
221 | |
222 | + // Send event to Zeitgeist |
223 | + GHashTableIter iter; |
224 | + GFile *file; |
225 | + gpointer done; |
226 | + g_hash_table_iter_init (&iter, job->debuting_files); |
227 | + while (g_hash_table_iter_next (&iter, (gpointer *) &file, &done)) { |
228 | + if (GPOINTER_TO_INT (done)) { |
229 | + // operation was completed successfully for this file |
230 | + g_object_ref (file); |
231 | + // FIXME: Set event origin to the original file URI, if we |
232 | + // can somehow figure out which one it is. |
233 | + log_zeitgeist_event_for_file_no_reply ( |
234 | + ZEITGEIST_ZG_CREATE_EVENT, file, NULL); |
235 | + } |
236 | + } |
237 | + // --- |
238 | + |
239 | g_list_free_full (job->files, g_object_unref); |
240 | g_object_unref (job->destination); |
241 | g_hash_table_unref (job->debuting_files); |
242 | @@ -5726,6 +5902,14 @@ |
243 | job->done_callback (job->created_file, job->done_callback_data); |
244 | } |
245 | |
246 | + // Send event to Zeitgeist |
247 | + if (job->created_file) { |
248 | + g_object_ref (job->created_file); |
249 | + log_zeitgeist_event_for_file_no_reply ( |
250 | + ZEITGEIST_ZG_CREATE_EVENT, job->created_file, NULL); |
251 | + } |
252 | + // --- |
253 | + |
254 | g_object_unref (job->dest_dir); |
255 | if (job->src) { |
256 | g_object_unref (job->src); |
257 | |
258 | === modified file 'libnautilus-private/nautilus-file.c' |
259 | --- libnautilus-private/nautilus-file.c 2012-02-02 12:48:30 +0000 |
260 | +++ libnautilus-private/nautilus-file.c 2012-03-08 17:15:43 +0000 |
261 | @@ -88,6 +88,9 @@ |
262 | #define DEBUG_REF_PRINTF printf |
263 | #endif |
264 | |
265 | +#include <zeitgeist.h> |
266 | +#define ZEITGEIST_NAUTILUS_ACTOR "application://nautilus.desktop" |
267 | + |
268 | /* Files that start with these characters sort after files that don't. */ |
269 | #define SORT_LAST_CHAR1 '.' |
270 | #define SORT_LAST_CHAR2 '#' |
271 | @@ -1721,10 +1724,34 @@ |
272 | old_name = g_strdup (eel_ref_str_peek (op->file->details->name)); |
273 | |
274 | update_info_and_name (op->file, new_info); |
275 | - |
276 | + |
277 | g_free (old_name); |
278 | |
279 | new_uri = nautilus_file_get_uri (op->file); |
280 | + |
281 | + // Send event to Zeitgeist |
282 | + ZeitgeistLog *log = zeitgeist_log_get_default (); |
283 | + gchar *origin = g_path_get_dirname (new_uri); |
284 | + ZeitgeistSubject *subject = zeitgeist_subject_new_full ( |
285 | + old_uri, |
286 | + NULL, // subject interpretation - auto-guess |
287 | + NULL, // subject manifestation - auto-guess |
288 | + g_file_info_get_content_type (new_info), // const char* |
289 | + origin, |
290 | + new_name, |
291 | + NULL // storage - auto-guess |
292 | + ); |
293 | + zeitgeist_subject_set_current_uri (subject, new_uri); |
294 | + g_free (origin); |
295 | + // FIXME: zeitgeist_subject_set_current_uri (); |
296 | + ZeitgeistEvent *event = zeitgeist_event_new_full ( |
297 | + ZEITGEIST_ZG_MOVE_EVENT, |
298 | + ZEITGEIST_ZG_USER_ACTIVITY, |
299 | + ZEITGEIST_NAUTILUS_ACTOR, |
300 | + subject, NULL); |
301 | + zeitgeist_log_insert_events_no_reply (log, event, NULL); |
302 | + // --- |
303 | + |
304 | nautilus_directory_moved (old_uri, new_uri); |
305 | g_free (new_uri); |
306 | g_free (old_uri); |
307 | |
308 | === modified file 'test/Makefile.am' |
309 | --- test/Makefile.am 2011-05-16 18:53:51 +0000 |
310 | +++ test/Makefile.am 2012-03-08 17:15:43 +0000 |
311 | @@ -6,6 +6,7 @@ |
312 | $(COMMON_CFLAGS) \ |
313 | $(NAUTILUS_CFLAGS) \ |
314 | $(WARNING_CFLAGS) \ |
315 | + `pkg-config --cflags zeitgeist-1.0` \ |
316 | -DVERSION="\"$(VERSION)\"" \ |
317 | -DNAUTILUS_DATADIR=\""$(datadir)/nautilus"\" \ |
318 | -DGNOMELOCALEDIR=\""$(prefix)/${DATADIRNAME}/locale"\" \ |
319 | @@ -22,6 +23,7 @@ |
320 | test-nautilus-search-engine \ |
321 | test-nautilus-directory-async \ |
322 | test-nautilus-copy \ |
323 | + test-nautilus-zeitgeist \ |
324 | test-eel-editable-label \ |
325 | $(NULL) |
326 | |
327 | @@ -31,6 +33,10 @@ |
328 | |
329 | test_nautilus_directory_async_SOURCES = test-nautilus-directory-async.c |
330 | |
331 | +test_nautilus_zeitgeist_SOURCES = test-nautilus-zeitgeist.c |
332 | + |
333 | +test_nautilus_zeitgeist_LDCONFIG = `pkg-config --libs zeitgeist-1.0` |
334 | + |
335 | EXTRA_DIST = \ |
336 | test.h \ |
337 | $(NULL) |
338 | |
339 | === added file 'test/run-zeitgeist-test.sh' |
340 | --- test/run-zeitgeist-test.sh 1970-01-01 00:00:00 +0000 |
341 | +++ test/run-zeitgeist-test.sh 2012-03-08 17:15:43 +0000 |
342 | @@ -0,0 +1,50 @@ |
343 | +#! /bin/sh -e |
344 | + |
345 | +#echo "Building..." |
346 | +#gcc test-nautilus-zeitgeist.c -o test-nautilus-zeitgeist \ |
347 | +# ../libnautilus-private/nautilus-file-operations.c \ |
348 | +# `pkg-config --cflags --libs glib-2.0 gtk+-3.0 zeitgeist-1.0` -I.. \ |
349 | +[ "`basename $(pwd)`" = "test" ] || echo "Please cd into test/" |
350 | +[ "`basename $(pwd)`" = "test" ] || exit |
351 | +make |
352 | + |
353 | +echo "Configuring environment..." |
354 | + |
355 | +TMP_PATH="/tmp/nautilus-zg-test" |
356 | + |
357 | +rm -rf "${TMP_PATH}" |
358 | +mkdir -p "${TMP_PATH}/cache" |
359 | + |
360 | +# Launching Zeitgeist |
361 | +export ZEITGEIST_DATA_PATH="${TMP_PATH}" |
362 | +export ZEITGEIST_DATABASE_PATH=":memory:" |
363 | +export ZEITGEIST_DISABLED_EXTENSIONS="SearchEngine" |
364 | +export XDG_CACHE_HOME="${TMP_PATH}/cache" |
365 | +zeitgeist-daemon --replace --no-datahub >/dev/null 2>&1 & |
366 | + |
367 | +echo "Creating files to be used by the tests..." |
368 | + |
369 | +# test_copy_move |
370 | +mkdir "${TMP_PATH}/move_dest" |
371 | +touch "${TMP_PATH}/moveme.txt" |
372 | + |
373 | +# test_copy and test_new_file_from_template |
374 | +echo "#! /usr/bin/env python\nprint 'hi!'" > "${TMP_PATH}/a.py" |
375 | + |
376 | +# test_delete |
377 | +touch "${TMP_PATH}/del1.txt" "${TMP_PATH}/del2.txt" |
378 | + |
379 | +echo "Testing..." |
380 | +export G_MESSAGES_DEBUG=all |
381 | +#dbus-test-runner \ |
382 | +# --task zeitgeist-daemon \ |
383 | +# --parameter --no-datahub \ |
384 | +# --parameter --log-level=DEBUG \ |
385 | +# --task gtester \ |
386 | +# --parameter --verbose \ |
387 | +# --parameter ./test-nautilus-zeitgeist |
388 | +./test-nautilus-zeitgeist |
389 | + |
390 | +echo "Cleaning up..." |
391 | +zeitgeist-daemon --quit |
392 | +rm -r "${TMP_PATH}" |
393 | |
394 | === added file 'test/test-nautilus-zeitgeist.c' |
395 | --- test/test-nautilus-zeitgeist.c 1970-01-01 00:00:00 +0000 |
396 | +++ test/test-nautilus-zeitgeist.c 2012-03-08 17:15:43 +0000 |
397 | @@ -0,0 +1,343 @@ |
398 | +/* |
399 | + * Copyright © 2012 Canonical Ltd. |
400 | + * By Siegfried-A. Gevatter <siegfried.gevatter@collabora.co.uk> |
401 | + * |
402 | + * License: GPLv2+ |
403 | + * |
404 | + * The tests in this file require that certain directories and files exist |
405 | + * in order to operate on them. Please use ./run-zeitgeist-test.sh to launch |
406 | + * this test, since it'll create them for you (in a temporary directory). |
407 | + * |
408 | + * */ |
409 | + |
410 | +#include <glib.h> |
411 | +#include <glib-object.h> |
412 | +#include <zeitgeist.h> |
413 | +#include <string.h> |
414 | + |
415 | +#include <libnautilus-private/nautilus-file-operations.h> |
416 | + |
417 | +// After doing a file operation and before checking Zeitgeist for |
418 | +// events, we needed to give Nautilus some time to insert the events |
419 | +// (because of g_file_query_info, etc). |
420 | +#define SLEEP_TIME 400 |
421 | + |
422 | +// Test location |
423 | +#define TEST_PATH "/tmp/nautilus-zg-test" |
424 | +#define TEST_URI "file://" TEST_PATH |
425 | + |
426 | +typedef struct |
427 | +{ |
428 | + ZeitgeistLog *log; |
429 | + GMainLoop *mainloop; |
430 | + ZeitgeistTimeRange *query_time_range; |
431 | + GPtrArray *expected_events; |
432 | + guint num_expected_events; |
433 | +} Fixture; |
434 | + |
435 | +static void |
436 | +setup_test (Fixture *fix, gconstpointer data) |
437 | +{ |
438 | + fix->log = zeitgeist_log_new (); |
439 | + fix->mainloop = g_main_loop_new (NULL, FALSE); |
440 | + fix->query_time_range = zeitgeist_time_range_new_from_now (); |
441 | + fix->expected_events = g_ptr_array_new_with_free_func ( |
442 | + (GDestroyNotify) g_object_unref); |
443 | + fix->num_expected_events = 0; |
444 | +} |
445 | + |
446 | +static void teardown (Fixture *fix, gconstpointer data) |
447 | +{ |
448 | + g_object_unref (fix->log); |
449 | + g_object_unref (fix->query_time_range); |
450 | + g_ptr_array_free (fix->expected_events, TRUE); |
451 | + g_main_loop_unref (fix->mainloop); |
452 | + |
453 | + fix->log = NULL; |
454 | + fix->mainloop = NULL; |
455 | + fix->query_time_range = NULL; |
456 | + fix->expected_events = NULL; |
457 | +} |
458 | + |
459 | +static void |
460 | +test_add_event_assertion (Fixture *fix, |
461 | + const char *event_interpretation, const char *uri, const char *current_uri, |
462 | + const char *origin, const char *text, const char *mimetype) |
463 | +{ |
464 | + // Create subject template |
465 | + ZeitgeistSubject *subject_template = zeitgeist_subject_new_full ( |
466 | + uri, NULL, NULL, mimetype, origin, text, NULL); |
467 | + zeitgeist_subject_set_current_uri (subject_template, current_uri); |
468 | + |
469 | + // Create event template |
470 | + ZeitgeistEvent *event_template = zeitgeist_event_new_full ( |
471 | + event_interpretation, ZEITGEIST_ZG_USER_ACTIVITY, NULL, |
472 | + subject_template, NULL); |
473 | + |
474 | + // Add event template to the fixture for later verification |
475 | + g_ptr_array_add (fix->expected_events, (gpointer) event_template); |
476 | + fix->num_expected_events++; |
477 | +} |
478 | + |
479 | +static void |
480 | +assert_event_matches_template (ZeitgeistEvent *event, ZeitgeistEvent *tmpl) |
481 | +{ |
482 | + int i; |
483 | + int num_subjects = zeitgeist_event_num_subjects (tmpl); |
484 | + |
485 | + g_assert_cmpstr (zeitgeist_event_get_interpretation (event), ==, |
486 | + zeitgeist_event_get_interpretation (tmpl)); |
487 | + g_assert_cmpstr (zeitgeist_event_get_manifestation (event), ==, |
488 | + zeitgeist_event_get_manifestation (tmpl)); |
489 | + g_assert_cmpint (zeitgeist_event_num_subjects (event), ==, num_subjects); |
490 | + |
491 | + for (i = 0; i < num_subjects; ++i) |
492 | + { |
493 | + ZeitgeistSubject *subject = zeitgeist_event_get_subject (event, i); |
494 | + ZeitgeistSubject *subj_templ = zeitgeist_event_get_subject (tmpl, i); |
495 | + |
496 | + g_assert_cmpstr (zeitgeist_subject_get_uri (subject), ==, |
497 | + zeitgeist_subject_get_uri (subj_templ)); |
498 | + g_assert_cmpstr (zeitgeist_subject_get_current_uri (subject), ==, |
499 | + zeitgeist_subject_get_current_uri (subj_templ)); |
500 | + g_assert_cmpstr (zeitgeist_subject_get_origin (subject), ==, |
501 | + zeitgeist_subject_get_origin (subj_templ)); |
502 | + g_assert_cmpstr (zeitgeist_subject_get_text (subject), ==, |
503 | + zeitgeist_subject_get_text (subj_templ)); |
504 | + g_assert_cmpstr (zeitgeist_subject_get_mimetype (subject), ==, |
505 | + zeitgeist_subject_get_mimetype (subj_templ)); |
506 | + } |
507 | +} |
508 | + |
509 | +static void |
510 | +assert_results_as_expected (Fixture *fix, ZeitgeistResultSet *results) |
511 | +{ |
512 | + int i; |
513 | + |
514 | + g_assert_cmpint (zeitgeist_result_set_size (results), ==, |
515 | + fix->num_expected_events); |
516 | + |
517 | + for (i = 0; i < fix->num_expected_events; ++i) |
518 | + { |
519 | + ZeitgeistEvent *event = zeitgeist_result_set_next (results); |
520 | + ZeitgeistEvent *tmpl = g_ptr_array_index (fix->expected_events, i); |
521 | + assert_event_matches_template (event, tmpl); |
522 | + } |
523 | +} |
524 | + |
525 | +static void |
526 | +_zeitgeist_test_cb2 (ZeitgeistLog *log, GAsyncResult *res, Fixture *fix) |
527 | +{ |
528 | + GError *error = NULL; |
529 | + ZeitgeistResultSet *results = zeitgeist_log_find_events_finish ( |
530 | + log, res, &error); |
531 | + if (error) |
532 | + { |
533 | + g_warning ("Error with FindEventIds: %s", error->message); |
534 | + g_error_free (error); |
535 | + g_assert_not_reached (); |
536 | + } |
537 | + |
538 | + assert_results_as_expected (fix, results); |
539 | + g_object_unref (results); |
540 | + |
541 | + g_main_loop_quit (fix->mainloop); |
542 | +} |
543 | + |
544 | +static gboolean |
545 | +_zeitgeist_test_cb1 (Fixture *fix) |
546 | +{ |
547 | + zeitgeist_log_find_events (fix->log, |
548 | + fix->query_time_range, |
549 | + g_ptr_array_new (), |
550 | + ZEITGEIST_STORAGE_STATE_ANY, |
551 | + 50, |
552 | + ZEITGEIST_RESULT_TYPE_MOST_RECENT_EVENTS, |
553 | + NULL, |
554 | + (GAsyncReadyCallback) _zeitgeist_test_cb2, |
555 | + fix); |
556 | + |
557 | + return FALSE; |
558 | +} |
559 | + |
560 | +static void |
561 | +zeitgeist_test_start (GHashTable *debuting_uris, Fixture *fix) |
562 | +{ |
563 | + g_timeout_add (SLEEP_TIME, (GSourceFunc) _zeitgeist_test_cb1, (gpointer) fix); |
564 | +} |
565 | + |
566 | +static void |
567 | +zeitgeist_test_start_3 (GHashTable *debuting_uris, gboolean user_cancel, |
568 | + gpointer callback_data) |
569 | +{ |
570 | + zeitgeist_test_start (debuting_uris, callback_data); |
571 | +} |
572 | + |
573 | +static void |
574 | +test_copy_move (Fixture *fix, gconstpointer data) |
575 | +{ |
576 | + test_add_event_assertion (fix, ZEITGEIST_ZG_MOVE_EVENT, |
577 | + TEST_URI "/moveme.txt", |
578 | + TEST_URI "/move_dest/moveme.txt", |
579 | + TEST_URI "/move_dest", |
580 | + "moveme.txt", |
581 | + "text/plain"); |
582 | + |
583 | + GList *item_uris = NULL; |
584 | + item_uris = g_list_prepend (item_uris, |
585 | + TEST_URI "/moveme.txt"); |
586 | + |
587 | + nautilus_file_operations_copy_move ( |
588 | + item_uris, |
589 | + NULL, |
590 | + TEST_URI "/move_dest", |
591 | + GDK_ACTION_MOVE, |
592 | + NULL, |
593 | + (NautilusCopyCallback) zeitgeist_test_start, |
594 | + fix); |
595 | + |
596 | + g_main_loop_run (fix->mainloop); |
597 | +} |
598 | + |
599 | +static void |
600 | +test_copy (Fixture *fix, gconstpointer data) |
601 | +{ |
602 | + test_add_event_assertion (fix, ZEITGEIST_ZG_CREATE_EVENT, |
603 | + TEST_URI "/b.py", |
604 | + TEST_URI "/b.py", |
605 | + TEST_URI, |
606 | + "b.py", |
607 | + "text/x-python"); |
608 | + |
609 | + nautilus_file_operations_copy_file ( |
610 | + g_file_new_for_path (TEST_PATH "/a.py"), |
611 | + g_file_new_for_path (TEST_PATH), |
612 | + "a.py", "b.py", |
613 | + NULL, |
614 | + (NautilusCopyCallback) zeitgeist_test_start, |
615 | + fix); |
616 | + |
617 | + g_main_loop_run (fix->mainloop); |
618 | +} |
619 | + |
620 | +static void |
621 | +test_new_folder (Fixture *fix, gconstpointer data) |
622 | +{ |
623 | + test_add_event_assertion (fix, ZEITGEIST_ZG_CREATE_EVENT, |
624 | + TEST_URI "/Untitled%20Folder", |
625 | + TEST_URI "/Untitled%20Folder", |
626 | + TEST_URI, |
627 | + "Untitled Folder", |
628 | + "inode/directory"); |
629 | + |
630 | + nautilus_file_operations_new_folder ( |
631 | + NULL, NULL, |
632 | + TEST_URI, |
633 | + (NautilusCopyCallback) zeitgeist_test_start, |
634 | + fix); |
635 | + |
636 | + g_main_loop_run (fix->mainloop); |
637 | +} |
638 | + |
639 | +static void |
640 | +test_new_file (Fixture *fix, gconstpointer data) |
641 | +{ |
642 | + test_add_event_assertion (fix, ZEITGEIST_ZG_CREATE_EVENT, |
643 | + TEST_URI "/new_file_test.txt", |
644 | + TEST_URI "/new_file_test.txt", |
645 | + TEST_URI, |
646 | + "new_file_test.txt", |
647 | + "text/plain"); |
648 | + |
649 | + const char content[] = "this is the content of a text file...\n"; |
650 | + nautilus_file_operations_new_file ( |
651 | + NULL, NULL, |
652 | + TEST_URI, |
653 | + "new_file_test.txt", |
654 | + content, strlen (content), |
655 | + (NautilusCopyCallback) zeitgeist_test_start, |
656 | + fix); |
657 | + |
658 | + g_main_loop_run (fix->mainloop); |
659 | +} |
660 | + |
661 | +static void |
662 | +test_new_file_from_template (Fixture *fix, gconstpointer data) |
663 | +{ |
664 | + test_add_event_assertion (fix, ZEITGEIST_ZG_CREATE_EVENT, |
665 | + TEST_URI "/new_tpl_file_test.py", |
666 | + TEST_URI "/new_tpl_file_test.py", |
667 | + TEST_URI, |
668 | + "new_tpl_file_test.py", |
669 | + "text/x-python"); |
670 | + |
671 | + nautilus_file_operations_new_file_from_template ( |
672 | + NULL, NULL, |
673 | + TEST_URI, |
674 | + "new_tpl_file_test.py", |
675 | + TEST_URI "/a.py", |
676 | + (NautilusCopyCallback) zeitgeist_test_start, |
677 | + fix); |
678 | + |
679 | + g_main_loop_run (fix->mainloop); |
680 | +} |
681 | + |
682 | +static void |
683 | +test_delete (Fixture *fix, gconstpointer data) |
684 | +{ |
685 | + test_add_event_assertion (fix, ZEITGEIST_ZG_DELETE_EVENT, |
686 | + TEST_URI "/del1.txt", |
687 | + TEST_URI "/del1.txt", |
688 | + TEST_URI, |
689 | + "del1.txt", |
690 | + NULL); |
691 | + test_add_event_assertion (fix, ZEITGEIST_ZG_DELETE_EVENT, |
692 | + TEST_URI "/del2.txt", |
693 | + TEST_URI "/del2.txt", |
694 | + TEST_URI, |
695 | + "del2.txt", |
696 | + NULL); |
697 | + |
698 | + GList *file_list = NULL; |
699 | + file_list = g_list_prepend (file_list, |
700 | + g_file_new_for_path (TEST_PATH "/del1.txt")); |
701 | + file_list = g_list_prepend (file_list, |
702 | + g_file_new_for_path (TEST_PATH "/del2.txt")); |
703 | + |
704 | + // Nautilus_file_operations_trash_or_delete is exactly the same |
705 | + // NOTE: This operation will ask for manual confirmation of the delete. |
706 | + // There isn't really any nice way around this :(. |
707 | + nautilus_file_operations_delete ( |
708 | + file_list, |
709 | + NULL, |
710 | + (NautilusDeleteCallback) zeitgeist_test_start_3, |
711 | + fix); |
712 | + |
713 | + g_main_loop_run (fix->mainloop); |
714 | +} |
715 | + |
716 | +int |
717 | +main (int argc, char* argv[]) |
718 | +{ |
719 | + g_type_init (); |
720 | + |
721 | + g_test_init (&argc, &argv, NULL); |
722 | + gtk_init (&argc, &argv); |
723 | + |
724 | + g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL); |
725 | + |
726 | + g_test_add ("/Zeitgeist/CopyMove", Fixture, 0, |
727 | + setup_test, test_copy_move, teardown); |
728 | + g_test_add ("/Zeitgeist/Copy", Fixture, 0, |
729 | + setup_test, test_copy, teardown); |
730 | + g_test_add ("/Zeitgeist/NewFolder", Fixture, 0, |
731 | + setup_test, test_new_folder, teardown); |
732 | + g_test_add ("/Zeitgeist/NewFile", Fixture, 0, |
733 | + setup_test, test_new_file, teardown); |
734 | + g_test_add ("/Zeitgeist/NewFileFromTemplate", Fixture, 0, |
735 | + setup_test, test_new_file_from_template, teardown); |
736 | + g_test_add ("/Zeitgeist/Delete", Fixture, 0, |
737 | + setup_test, test_delete, teardown); |
738 | + |
739 | + return g_test_run (); |
740 | +} |
Really nice! :-)
95 + origin = g_path_get_dirname (uri);
This should be URI formatted I think.
200 + while (g_hash_ table_iter_ next (&iter, (void **) &file, (void **) &done)) {
201 + if (done) {
202 ...
It's not quite obvious what 'done' is or how it's used here..? Can you clarify?
I think you can just rely on the new libzg already and bump the configure check to 0.3.13 which is what trunk has to get rid of the fixmes.
I'll take it for a test spin monday.