~rye/ubuntuone-client/trash-support

« back to all changes in this revision

Viewing changes to ubuntuone/syncdaemon/event_logging.py

  • Committer: Tarmac
  • Author(s): Alejandro J. Cura
  • Date: 2010-12-14 18:05:35 UTC
  • mfrom: (748.4.18 ziggy-for-filesync)
  • Revision ID: tarmac-20101214180535-0fmlie4syn3dd33x
Remaining SyncDaemon events to be logged into Zeitgeist.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
# with this program.  If not, see <http://www.gnu.org/licenses/>.
18
18
"""Event logging from SyncDaemon into Zeitgeist."""
19
19
 
 
20
import mimetypes
 
21
 
20
22
from zeitgeist.datamodel import Event, Interpretation, Manifestation, Subject
 
23
from zeitgeist.mimetypes import get_interpretation_for_mimetype
21
24
 
22
25
from ubuntuone.eventlog import zglog
23
 
from ubuntuone.syncdaemon.volume_manager import Share
 
26
from ubuntuone.syncdaemon.volume_manager import Share, UDF
24
27
 
25
28
ACTOR_UBUNTUONE = "dbus://com.ubuntuone.SyncDaemon.service"
26
29
DIRECTORY_MIMETYPE = "inode/directory"
 
30
DEFAULT_MIME = "application/octet-stream"
 
31
DEFAULT_INTERPRETATION = Interpretation.DOCUMENT
27
32
EVENT_INTERPRETATION_U1_FOLDER_SHARED = "u1://FolderShared"
28
33
EVENT_INTERPRETATION_U1_FOLDER_UNSHARED = "u1://FolderUnshared"
29
34
EVENT_INTERPRETATION_U1_SHARE_ACCEPTED = "u1://ShareAccepted"
30
35
EVENT_INTERPRETATION_U1_SHARE_UNACCEPTED = "u1://ShareUnaccepted"
 
36
EVENT_INTERPRETATION_U1_CONFLICT_RENAME = "u1://ConflictRename"
 
37
EVENT_INTERPRETATION_U1_UDF_CREATED = "u1://UserFolderCreated"
 
38
EVENT_INTERPRETATION_U1_UDF_DELETED = "u1://UserFolderDeleted"
 
39
EVENT_INTERPRETATION_U1_UDF_SUBSCRIBED = "u1://UserFolderSubscribed"
 
40
EVENT_INTERPRETATION_U1_UDF_UNSUBSCRIBED = "u1://UserFolderUnsubscribed"
31
41
MANIFESTATION_U1_CONTACT_DATA_OBJECT = "u1://ContactDataObject"
32
42
INTERPRETATION_U1_CONTACT = "u1://Contact"
33
43
URI_PROTOCOL_U1 = "ubuntuone:"
 
44
STORAGE_LOCAL = ""
34
45
STORAGE_NETWORK = "net"
 
46
STORAGE_DELETED = "deleted"
35
47
 
36
48
class ZeitgeistListener(object):
37
49
    """An Event Queue listener that logs into ZG."""
41
53
        self.fsm = fsm
42
54
        self.vm = vm
43
55
        self.zg = zglog.ZeitgeistLogger()
 
56
        self.newly_created_server_files = set()
 
57
        self.newly_created_local_files = set()
44
58
 
45
59
    def handle_AQ_CREATE_SHARE_OK(self, share_id=None, marker=None):
46
60
        """Log the 'directory shared thru the server' event."""
153
167
 
154
168
        self.zg.log(event)
155
169
 
 
170
    def log_udf_deleted(self, volume):
 
171
        """Log the udf deleted event."""
 
172
        folder = Subject.new_for_values(
 
173
            uri=URI_PROTOCOL_U1 + str(volume.node_id),
 
174
            interpretation=Interpretation.FOLDER,
 
175
            manifestation=Manifestation.DELETED_RESOURCE,
 
176
            origin="file:///" + volume.path,
 
177
            mimetype=DIRECTORY_MIMETYPE,
 
178
            storage=STORAGE_DELETED)
 
179
 
 
180
        event = Event.new_for_values(
 
181
            interpretation=EVENT_INTERPRETATION_U1_UDF_DELETED,
 
182
            manifestation=Manifestation.USER_ACTIVITY,
 
183
            actor=ACTOR_UBUNTUONE,
 
184
            subjects=[folder])
 
185
 
 
186
        self.zg.log(event)
 
187
 
156
188
    def handle_VM_VOLUME_DELETED(self, volume):
157
189
        """Log the share/UDF unaccepted event."""
158
190
        if isinstance(volume, Share):
159
191
            self.log_share_unaccepted(volume)
 
192
        if isinstance(volume, UDF):
 
193
            self.log_udf_deleted(volume)
 
194
 
 
195
    def handle_VM_UDF_CREATED(self, udf):
 
196
        """An udf was created. Log it into Zeitgeist."""
 
197
        folder = Subject.new_for_values(
 
198
            uri=URI_PROTOCOL_U1 + str(udf.node_id),
 
199
            interpretation=Interpretation.FOLDER,
 
200
            manifestation=Manifestation.REMOTE_DATA_OBJECT,
 
201
            origin="file:///" + udf.path,
 
202
            mimetype=DIRECTORY_MIMETYPE,
 
203
            storage=STORAGE_NETWORK)
 
204
 
 
205
        event = Event.new_for_values(
 
206
            interpretation=EVENT_INTERPRETATION_U1_UDF_CREATED,
 
207
            manifestation=Manifestation.USER_ACTIVITY,
 
208
            actor=ACTOR_UBUNTUONE,
 
209
            subjects=[folder])
 
210
 
 
211
        self.zg.log(event)
 
212
 
 
213
    def handle_VM_UDF_SUBSCRIBED(self, udf):
 
214
        """An udf was subscribed."""
 
215
 
 
216
        folder = Subject.new_for_values(
 
217
            uri="file:///" + udf.path,
 
218
            interpretation=Interpretation.FOLDER,
 
219
            manifestation=Manifestation.FILE_DATA_OBJECT,
 
220
            origin=URI_PROTOCOL_U1 + str(udf.node_id),
 
221
            mimetype=DIRECTORY_MIMETYPE,
 
222
            storage=STORAGE_LOCAL)
 
223
 
 
224
        event = Event.new_for_values(
 
225
            interpretation=EVENT_INTERPRETATION_U1_UDF_SUBSCRIBED,
 
226
            manifestation=Manifestation.USER_ACTIVITY,
 
227
            actor=ACTOR_UBUNTUONE,
 
228
            subjects=[folder])
 
229
 
 
230
        self.zg.log(event)
 
231
 
 
232
    def handle_VM_UDF_UNSUBSCRIBED(self, udf):
 
233
        """An udf was unsubscribed."""
 
234
 
 
235
        folder = Subject.new_for_values(
 
236
            uri="file:///" + udf.path,
 
237
            interpretation=Interpretation.FOLDER,
 
238
            manifestation=Manifestation.DELETED_RESOURCE,
 
239
            origin=URI_PROTOCOL_U1 + str(udf.node_id),
 
240
            mimetype=DIRECTORY_MIMETYPE,
 
241
            storage=STORAGE_DELETED)
 
242
 
 
243
        event = Event.new_for_values(
 
244
            interpretation=EVENT_INTERPRETATION_U1_UDF_UNSUBSCRIBED,
 
245
            manifestation=Manifestation.USER_ACTIVITY,
 
246
            actor=ACTOR_UBUNTUONE,
 
247
            subjects=[folder])
 
248
 
 
249
        self.zg.log(event)
 
250
 
 
251
    def handle_AQ_FILE_NEW_OK(self, volume_id, marker, new_id, new_generation):
 
252
        """A new file was created on server. Store and wait till it uploads."""
 
253
        self.newly_created_server_files.add((volume_id, new_id))
 
254
 
 
255
    def get_mime_and_interpretation_for_filepath(self, filepath):
 
256
        """Try to guess the mime and the interpretation from the path."""
 
257
        mime, encoding = mimetypes.guess_type(filepath)
 
258
        if mime is None:
 
259
            return DEFAULT_MIME, DEFAULT_INTERPRETATION
 
260
        interpret = get_interpretation_for_mimetype(mime)
 
261
        if interpret is None:
 
262
            return DEFAULT_MIME, Interpretation.DOCUMENT
 
263
        return mime, interpret
 
264
 
 
265
    def handle_AQ_UPLOAD_FINISHED(self, share_id, node_id, hash,
 
266
                                  new_generation):
 
267
        """A file finished uploading to the server."""
 
268
 
 
269
        mdo = self.fsm.get_by_node_id(share_id, node_id)
 
270
        path = self.fsm.get_abspath(share_id, mdo.path)
 
271
 
 
272
        if (share_id, node_id) in self.newly_created_server_files:
 
273
            self.newly_created_server_files.remove((share_id, node_id))
 
274
            event_interpretation = Interpretation.CREATE_EVENT
 
275
        else:
 
276
            event_interpretation = Interpretation.MODIFY_EVENT
 
277
 
 
278
        mime, interp = self.get_mime_and_interpretation_for_filepath(path)
 
279
 
 
280
        file_subject = Subject.new_for_values(
 
281
            uri=URI_PROTOCOL_U1 + str(node_id),
 
282
            interpretation=interp,
 
283
            manifestation=Manifestation.REMOTE_DATA_OBJECT,
 
284
            origin="file:///" + path,
 
285
            mimetype=mime,
 
286
            storage=STORAGE_NETWORK)
 
287
 
 
288
        event = Event.new_for_values(
 
289
            interpretation=event_interpretation,
 
290
            manifestation=Manifestation.SCHEDULED_ACTIVITY,
 
291
            actor=ACTOR_UBUNTUONE,
 
292
            subjects=[file_subject])
 
293
 
 
294
        self.zg.log(event)
 
295
 
 
296
    def handle_AQ_DIR_NEW_OK(self, volume_id, marker, new_id, new_generation):
 
297
        """A dir was created on the server."""
 
298
 
 
299
        mdo = self.fsm.get_by_node_id(volume_id, new_id)
 
300
        path = self.fsm.get_abspath(volume_id, mdo.path)
 
301
 
 
302
        file_subject = Subject.new_for_values(
 
303
            uri=URI_PROTOCOL_U1 + str(new_id),
 
304
            interpretation=Interpretation.FOLDER,
 
305
            manifestation=Manifestation.REMOTE_DATA_OBJECT,
 
306
            origin="file:///" + path,
 
307
            mimetype=DIRECTORY_MIMETYPE,
 
308
            storage=STORAGE_NETWORK)
 
309
 
 
310
        event = Event.new_for_values(
 
311
            interpretation=Interpretation.CREATE_EVENT,
 
312
            manifestation=Manifestation.SCHEDULED_ACTIVITY,
 
313
            actor=ACTOR_UBUNTUONE,
 
314
            subjects=[file_subject])
 
315
 
 
316
        self.zg.log(event)
 
317
 
 
318
    def handle_SV_FILE_NEW(self, volume_id, node_id, parent_id, name):
 
319
        """A file was created locally by Syncdaemon."""
 
320
        self.newly_created_local_files.add((volume_id, node_id))
 
321
 
 
322
    def handle_AQ_DOWNLOAD_FINISHED(self, share_id, node_id, server_hash):
 
323
        """A file finished downloading from the server."""
 
324
 
 
325
        mdo = self.fsm.get_by_node_id(share_id, node_id)
 
326
        path = self.fsm.get_abspath(share_id, mdo.path)
 
327
 
 
328
        if (share_id, node_id) in self.newly_created_local_files:
 
329
            self.newly_created_local_files.remove((share_id, node_id))
 
330
            event_interpretation = Interpretation.CREATE_EVENT
 
331
        else:
 
332
            event_interpretation = Interpretation.MODIFY_EVENT
 
333
 
 
334
        mime, interp = self.get_mime_and_interpretation_for_filepath(path)
 
335
 
 
336
        file_subject = Subject.new_for_values(
 
337
            uri="file:///" + path,
 
338
            interpretation=interp,
 
339
            manifestation=Manifestation.FILE_DATA_OBJECT,
 
340
            origin=URI_PROTOCOL_U1 + str(node_id),
 
341
            mimetype=mime,
 
342
            storage=STORAGE_LOCAL)
 
343
 
 
344
        event = Event.new_for_values(
 
345
            interpretation=event_interpretation,
 
346
            manifestation=Manifestation.WORLD_ACTIVITY,
 
347
            actor=ACTOR_UBUNTUONE,
 
348
            subjects=[file_subject])
 
349
 
 
350
        self.zg.log(event)
 
351
 
 
352
    def handle_SV_DIR_NEW(self, volume_id, node_id, parent_id, name):
 
353
        """A file finished downloading from the server."""
 
354
 
 
355
        mdo = self.fsm.get_by_node_id(volume_id, node_id)
 
356
        path = self.fsm.get_abspath(volume_id, mdo.path)
 
357
 
 
358
        file_subject = Subject.new_for_values(
 
359
            uri="file:///" + path,
 
360
            interpretation=Interpretation.FOLDER,
 
361
            manifestation=Manifestation.FILE_DATA_OBJECT,
 
362
            origin=URI_PROTOCOL_U1 + str(node_id),
 
363
            mimetype=DIRECTORY_MIMETYPE,
 
364
            storage=STORAGE_LOCAL)
 
365
 
 
366
        event = Event.new_for_values(
 
367
            interpretation=Interpretation.CREATE_EVENT,
 
368
            manifestation=Manifestation.WORLD_ACTIVITY,
 
369
            actor=ACTOR_UBUNTUONE,
 
370
            subjects=[file_subject])
 
371
 
 
372
        self.zg.log(event)
 
373
 
 
374
    def handle_SV_FILE_DELETED(self, volume_id, node_id, is_dir):
 
375
        """A file or folder was deleted locally by Syncdaemon."""
 
376
        mdo = self.fsm.get_by_node_id(volume_id, node_id)
 
377
        path = self.fsm.get_abspath(volume_id, mdo.path)
 
378
 
 
379
        if is_dir:
 
380
            mime, interp = DIRECTORY_MIMETYPE, Interpretation.FOLDER
 
381
        else:
 
382
            mime, interp = self.get_mime_and_interpretation_for_filepath(path)
 
383
 
 
384
        file_subject = Subject.new_for_values(
 
385
            uri="file:///" + path,
 
386
            interpretation=interp,
 
387
            manifestation=Manifestation.DELETED_RESOURCE,
 
388
            origin=URI_PROTOCOL_U1 + str(node_id),
 
389
            mimetype=mime,
 
390
            storage=STORAGE_DELETED)
 
391
 
 
392
        event = Event.new_for_values(
 
393
            interpretation=Interpretation.DELETE_EVENT,
 
394
            manifestation=Manifestation.WORLD_ACTIVITY,
 
395
            actor=ACTOR_UBUNTUONE,
 
396
            subjects=[file_subject])
 
397
 
 
398
        self.zg.log(event)
 
399
 
 
400
    def handle_AQ_UNLINK_OK(self, share_id, parent_id, node_id,
 
401
                            new_generation):
 
402
        """A file or folder was deleted on the server by Syncdaemon,"""
 
403
        mdo = self.fsm.get_by_node_id(share_id, node_id)
 
404
        path = self.fsm.get_abspath(share_id, mdo.path)
 
405
 
 
406
        if mdo.is_dir:
 
407
            mime, interp = DIRECTORY_MIMETYPE, Interpretation.FOLDER
 
408
        else:
 
409
            mime, interp = self.get_mime_and_interpretation_for_filepath(path)
 
410
 
 
411
        file_subject = Subject.new_for_values(
 
412
            uri=URI_PROTOCOL_U1 + str(node_id),
 
413
            interpretation=interp,
 
414
            manifestation=Manifestation.DELETED_RESOURCE,
 
415
            origin="file:///" + path,
 
416
            mimetype=mime,
 
417
            storage=STORAGE_DELETED)
 
418
 
 
419
        event = Event.new_for_values(
 
420
            interpretation=Interpretation.DELETE_EVENT,
 
421
            manifestation=Manifestation.SCHEDULED_ACTIVITY,
 
422
            actor=ACTOR_UBUNTUONE,
 
423
            subjects=[file_subject])
 
424
 
 
425
        self.zg.log(event)
 
426
 
 
427
    def handle_FSM_FILE_CONFLICT(self, old_name, new_name):
 
428
        """A file was renamed because of conflict."""
 
429
        mime, interp = self.get_mime_and_interpretation_for_filepath(old_name)
 
430
 
 
431
        file_subject = Subject.new_for_values(
 
432
            uri="file:///" + new_name,
 
433
            interpretation=interp,
 
434
            manifestation=Manifestation.FILE_DATA_OBJECT,
 
435
            origin="file:///" + old_name,
 
436
            mimetype=mime,
 
437
            storage=STORAGE_LOCAL)
 
438
 
 
439
        event = Event.new_for_values(
 
440
            interpretation=EVENT_INTERPRETATION_U1_CONFLICT_RENAME,
 
441
            manifestation=Manifestation.WORLD_ACTIVITY,
 
442
            actor=ACTOR_UBUNTUONE,
 
443
            subjects=[file_subject])
 
444
 
 
445
        self.zg.log(event)
 
446
 
 
447
    def handle_FSM_DIR_CONFLICT(self, old_name, new_name):
 
448
        """A dir was renamed because of conflict."""
 
449
        folder_subject = Subject.new_for_values(
 
450
            uri="file:///" + new_name,
 
451
            interpretation=Interpretation.FOLDER,
 
452
            manifestation=Manifestation.FILE_DATA_OBJECT,
 
453
            origin="file:///" + old_name,
 
454
            mimetype=DIRECTORY_MIMETYPE,
 
455
            storage=STORAGE_LOCAL)
 
456
 
 
457
        event = Event.new_for_values(
 
458
            interpretation=EVENT_INTERPRETATION_U1_CONFLICT_RENAME,
 
459
            manifestation=Manifestation.WORLD_ACTIVITY,
 
460
            actor=ACTOR_UBUNTUONE,
 
461
            subjects=[folder_subject])
 
462
 
 
463
        self.zg.log(event)
 
464
 
 
465
    def handle_AQ_CHANGE_PUBLIC_ACCESS_OK(self, share_id, node_id, is_public,
 
466
                                          public_url):
 
467
        """The status of a published resource changed. Log it!"""
 
468
        if is_public:
 
469
            self.log_publishing(share_id, node_id, is_public, public_url)
 
470
        else:
 
471
            self.log_unpublishing(share_id, node_id, is_public, public_url)
 
472
 
 
473
    def log_publishing(self, share_id, node_id, is_public, public_url):
 
474
        """Log the publishing of a resource."""
 
475
        mime, interp = self.get_mime_and_interpretation_for_filepath(
 
476
                                                                    public_url)
 
477
 
 
478
        origin = "" if node_id is None else URI_PROTOCOL_U1 + str(node_id)
 
479
 
 
480
        public_file = Subject.new_for_values(
 
481
            uri=public_url,
 
482
            interpretation=interp,
 
483
            manifestation=Manifestation.REMOTE_DATA_OBJECT,
 
484
            origin=origin,
 
485
            mimetype=mime,
 
486
            storage=STORAGE_NETWORK)
 
487
 
 
488
        event = Event.new_for_values(
 
489
            interpretation=Interpretation.CREATE_EVENT,
 
490
            manifestation=Manifestation.USER_ACTIVITY,
 
491
            actor=ACTOR_UBUNTUONE,
 
492
            subjects=[public_file])
 
493
 
 
494
        self.zg.log(event)
 
495
 
 
496
    def log_unpublishing(self, share_id, node_id, is_public, public_url):
 
497
        """Log the unpublishing of a resource."""
 
498
        mime, interp = self.get_mime_and_interpretation_for_filepath(
 
499
                                                                    public_url)
 
500
 
 
501
        origin = "" if node_id is None else URI_PROTOCOL_U1 + str(node_id)
 
502
 
 
503
        public_file = Subject.new_for_values(
 
504
            uri=public_url,
 
505
            interpretation=interp,
 
506
            manifestation=Manifestation.DELETED_RESOURCE,
 
507
            origin=origin,
 
508
            mimetype=mime,
 
509
            storage=STORAGE_DELETED)
 
510
 
 
511
        event = Event.new_for_values(
 
512
            interpretation=Interpretation.DELETE_EVENT,
 
513
            manifestation=Manifestation.USER_ACTIVITY,
 
514
            actor=ACTOR_UBUNTUONE,
 
515
            subjects=[public_file])
 
516
 
 
517
        self.zg.log(event)