Commit a5ef0adc authored by Seif Lotfy's avatar Seif Lotfy Committed by Seif Lotfy
Browse files

Added new properties to the Telepathy backends.



The Telepathy backend requires Zeitgeist to pull its info.
Signed-off-by: default avatarSeif Lotfy <seif.lotfy@collabora.co.uk>
parent f08ec1f0
......@@ -146,6 +146,13 @@ libfolks_telepathy_la_LIBADD = \
$(top_builddir)/folks/libfolks-internal.la \
$(NULL)
if ENABLE_ZEITGEIST
libfolks_telepathy_la_VALAFLAGS += --pkg zeitgeist-1.0
libfolks_telepathy_la_VALAFLAGS += --define=HAVE_ZEITGEIST
libfolks_telepathy_la_CFLAGS += $(ZEITGEIST_CFLAGS)
libfolks_telepathy_la_LIBADD += $(ZEITGEIST_LIBS)
endif
# The quoting here is unnecessary but harmless, and has the useful side-effect
# that vim quickfix mode (:make) doesn't interpret the libtool --mode=link
# command as an error message in a bizarrely named file
......
......@@ -24,7 +24,9 @@ using GLib;
using Gee;
using TelepathyGLib;
using Folks;
#if HAVE_ZEITGEIST
using Zeitgeist;
#endif
extern const string G_LOG_DOMAIN;
extern const string BACKEND_NAME;
......@@ -85,6 +87,11 @@ public class Tpf.PersonaStore : Folks.PersonaStore
private Account _account;
#if HAVE_ZEITGEIST
private Zeitgeist.Log? _log= null;
private Zeitgeist.Monitor? _monitor = null;
#endif
/**
* The Telepathy account this store is based upon.
*/
......@@ -1022,6 +1029,12 @@ public class Tpf.PersonaStore : Folks.PersonaStore
new GLib.GenericArray<TelepathyGLib.Contact> ());
this._got_initial_members = true;
#if HAVE_ZEITGEIST
if (this._monitor == null)
{
this._populate_counters ();
}
#endif
this._notify_if_is_quiescent ();
}
......@@ -1529,4 +1542,119 @@ public class Tpf.PersonaStore : Folks.PersonaStore
return store;
}
#if HAVE_ZEITGEIST
private string? _get_iid_from_event_metadata (string? uri)
{
/* Format a proper id represting a persona in the store.
* Zeitgeist uses x-telepathy-identifier as a prefix for telepathy, which
* is stored as the uri of a subject of an event. */
if (uri == null)
{
return null;
}
var new_uri = uri.replace ("x-telepathy-identifier:", "");
return this.account.protocol + ":" + new_uri;
}
private void _increase_persona_counter (string? id, string? interaction_type, Event event)
{
/* Check if the persona id and interaction is valid. If so increase the
* appropriate interacton counter, to signify that an
* interaction was successfully counted. */
if (id != null && this._personas.has_key (id) && interaction_type != null)
{
var persona = this._personas.get (id);
persona._increase_counter (id, interaction_type, event);
}
}
private void _handle_new_interaction (TimeRange timerange, ResultSet events)
{
foreach (var e in events)
{
for (var i = 1; i < e.num_subjects (); i++)
{
var id = this._get_iid_from_event_metadata (e.get_subject (i).get_uri ());
var interaction_type = e.get_subject (0).get_interpretation ();
this._increase_persona_counter (id, interaction_type, e);
}
}
}
private PtrArray _get_zeitgeist_event_templates ()
{
/* To fetch events from Zeitgeist about the interaction with contacts we
* create templates reflecting how the telepathy-logger stores events in
* Zeitgeist */
var origin = this.id.replace (TelepathyGLib.ACCOUNT_OBJECT_PATH_BASE,
"x-telepathy-account-path:");
Event ev1 = new Event.full ("", "", "dbus://org.freedesktop.Telepathy.Logger.service");
ev1.add_subject (new Subject.full ("", Zeitgeist.NMO_IMMESSAGE, "", "", "", "", ""));
ev1.set_origin (origin);
Event ev2 = new Event.full ("", "", "dbus://org.freedesktop.Telepathy.Logger.service");
ev2.add_subject (new Subject.full ("", "", Zeitgeist.NFO_MEDIA_STREAM, "", "", "", ""));
ev2.set_origin (origin);
var templates = new PtrArray ();
templates.add (ev1.ref ());
templates.add (ev2.ref ());
return templates;
}
private async void _populate_counters ()
{
this._log = new Zeitgeist.Log ();
/* Prepare a monitor for this account to populate the counters upon
* interaction changes */
if (this._monitor == null)
{
PtrArray monitor_events = this._get_zeitgeist_event_templates ();
this._monitor = new Zeitgeist.Monitor (new Zeitgeist.TimeRange.from_now (),
(owned) monitor_events);
this._monitor.events_inserted.connect (this._handle_new_interaction);
}
/* Get all events for this account from Zeitgeist and increase the
* the counters of the personas */
try
{
PtrArray events = this._get_zeitgeist_event_templates ();
var results = yield this._log.find_events (new TimeRange.anytime (),
(owned) events, StorageState.ANY, 0, ResultType.MOST_RECENT_EVENTS,
null);
foreach (var persona in this.personas.values)
{
persona.freeze_notify ();
}
foreach (var e in results)
{
var interaction_type = e.get_subject (0).get_interpretation ();
for (var i = 1; i < e.num_subjects (); i++)
{
var id = this._get_iid_from_event_metadata (e.get_subject (i).get_uri ());
this._increase_persona_counter (id, interaction_type, e);
}
}
foreach (var persona in this.personas.values)
{
persona.thaw_notify ();
}
}
catch
{
warning ("Failed to fetch events from Zeitgeist");
}
/* Install the monitor for this account to be notified when a persona has
* been interacted with */
this._log.install_monitor (this._monitor);
this._notify_if_is_quiescent ();
}
#endif
}
......@@ -22,6 +22,9 @@ using Gee;
using GLib;
using TelepathyGLib;
using Folks;
#if HAVE_ZEITGEIST
using Zeitgeist;
#endif
/**
* A persona subclass which represents a single instant messaging contact from
......@@ -34,6 +37,7 @@ public class Tpf.Persona : Folks.Persona,
EmailDetails,
FavouriteDetails,
GroupDetails,
InteractionDetails,
ImDetails,
NameDetails,
PhoneDetails,
......@@ -388,6 +392,64 @@ public class Tpf.Persona : Folks.Persona,
set { this.change_im_addresses.begin (value); }
}
private uint _im_interaction_count = 0;
/**
* A counter for IM interactions (send/receive message) with the persona.
*
* See {@link Folks.InteractionDetails.im_interaction_count}
*
* @since UNRELEASED
*/
public uint im_interaction_count
{
get { return this._im_interaction_count; }
}
internal DateTime? _last_im_interaction_datetime = null;
/**
* The latest datetime for IM interactions (send/receive message) with the
* persona.
*
* See {@link Folks.InteractionDetails.last_im_interaction_datetime}
*
* @since UNRELEASED
*/
public DateTime? last_im_interaction_datetime
{
get { return this._last_im_interaction_datetime; }
}
private uint _call_interaction_count = 0;
/**
* A counter for call interactions (only successful calls) with the persona.
*
* See {@link Folks.InteractionDetails.call_interaction_count}
*
* @since UNRELEASED
*/
public uint call_interaction_count
{
get { return this._call_interaction_count; }
}
internal DateTime? _last_call_interaction_datetime = null;
/**
* The latest datetime for call interactions (only successful calls) with the
* persona.
*
* See {@link Folks.InteractionDetails.last_call_interaction_datetime}
*
* @since UNRELEASED
*/
public DateTime? last_call_interaction_datetime
{
get { return this._last_call_interaction_datetime; }
}
private HashSet<string> _groups = new HashSet<string> ();
private Set<string> _groups_ro;
......@@ -1136,4 +1198,45 @@ public class Tpf.Persona : Folks.Persona,
var store = PersonaStore.dup_for_account (account);
return store._ensure_persona_for_contact (contact);
}
#if HAVE_ZEITGEIST
internal void _increase_counter (string id, string interaction_type, Event event)
{
var timestamp = (uint) (event.get_timestamp () / 1000);
var converted_datetime = new DateTime.from_unix_utc (timestamp);
var interpretation = event.get_interpretation ();
/* Only count send/receive for IM interactions */
if (interaction_type == Zeitgeist.NMO_IMMESSAGE &&
(interpretation == Zeitgeist.ZG_SEND_EVENT ||
interpretation == Zeitgeist.ZG_RECEIVE_EVENT))
{
this._im_interaction_count++;
this.notify_property ("im-interaction-count");
if (this._last_im_interaction_datetime == null ||
this._last_im_interaction_datetime.compare (converted_datetime) == -1)
{
this._last_im_interaction_datetime = converted_datetime;
this.notify_property ("last-im-interaction-datetime");
}
debug ("Persona %s IM interaction details changed:\n - count: %u \n - timestamp: %lld\n",
id, this._im_interaction_count, this._last_im_interaction_datetime.format ("%H %M %S - %d %m %y"));
}
/* Only count successful call for call interactions */
else if (interaction_type == Zeitgeist.NFO_AUDIO &&
interpretation == Zeitgeist.ZG_LEAVE_EVENT)
{
this._call_interaction_count++;
this.notify_property ("call-interaction-count");
if (this._last_call_interaction_datetime == null ||
this._last_call_interaction_datetime.compare (converted_datetime) == -1)
{
this._last_call_interaction_datetime = converted_datetime;
this.notify_property ("last-call-interaction-datetime");
}
debug ("Persona %s Call interaction details changed:\n - count: %u \n - timestamp: %lld\n",
id, this._call_interaction_count, this._last_call_interaction_datetime.format ("%H %M %S - %d %m %y"));
}
}
#endif
}
......@@ -101,6 +101,24 @@ fi
AM_CONDITIONAL([ENABLE_EDS], [test "x$enable_eds_backend" = "xyes"])
AC_ARG_ENABLE(zeitgeist,
AC_HELP_STRING([--enable-zeitgeist],
[ build the Zeitgeist]),
enable_zeitgeist=$enableval,
enable_zeitgeist=no )
AM_CONDITIONAL([ENABLE_ZEITGEIST], [test "x$enable_zeitgeist" = "xyes"])
if test "x$enable_zeitgeist" = "xyes"; then
AC_DEFINE(HAVE_ZEITGEIST, [1],
[Define as 1 if you have the Zeitgeist support])
else
AC_DEFINE(HAVE_ZEITGEIST, [0],
[Define as 1 if you have the Zeitgeist support])
fi
# Automatically check the dependencies for the libsocialweb backend
SW_CLIENT_REQUIRED=0.25.20
AC_ARG_ENABLE(libsocialweb-backend,
......@@ -152,6 +170,7 @@ TRACKER_SPARQL_MAJOR=0.14
TRACKER_SPARQL_REQUIRED=0.13.1
EBOOK_REQUIRED=3.1.5
EDATASERVER_REQUIRED=3.1.5
ZEITGEIST_REQUIRED=0.3.14
AC_SUBST([TRACKER_SPARQL_MAJOR])
......@@ -194,6 +213,10 @@ if test x$enable_eds_backend = xyes; then
PKG_CHECK_MODULES([EDATASERVER], [libedataserver-1.2 >= $EDATASERVER_REQUIRED])
fi
if test x$enable_zeitgeist = xyes; then
PKG_CHECK_MODULES([ZEITGEIST], [zeitgeist-1.0 >= $ZEITGEIST_REQUIRED])
fi
#
# Vala building options -- allows tarball builds without installing Vala
#
......@@ -276,6 +299,11 @@ if test "x$enable_vala" = "xyes" ; then
if test x$enable_eds_backend = xyes; then
VALA_CHECK_PACKAGES([libebook-1.2 libedataserver-1.2 libxml-2.0])
fi
if test x$enable_zeitgeist = xyes; then
VALA_CHECK_PACKAGES([zeitgeist-1.0])
fi
fi
# this will set HAVE_INTROSPECTION
......@@ -584,5 +612,6 @@ Configure summary:
Tracker backend.............: ${enable_tracker_backend}
Libsocialweb backend........: ${have_libsocialweb_backend}
E-D-S backend...............: ${enable_eds_backend}
Zeitgeist support...........: ${enable_zeitgeist}
"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment