Beispiel #1
0
/**
 * cinnamon_contact_system_get_email_for_display:
 * @self: A #CinnamonContactSystem
 * @individual A #FolksIndividual
 *
 * Get an email address (either from IM addresses or email), which can be
 * used to represent @individual.
 *
 * Return: (transfer full): a newly allocated string or %NULL if no address
 *                          was found
 */
char *
cinnamon_contact_system_get_email_for_display (CinnamonContactSystem *self,
                                            FolksIndividual    *individual)
{
  GeeMultiMap *im_addr_map = folks_im_details_get_im_addresses (FOLKS_IM_DETAILS (individual));
  GeeCollection *im_addrs = gee_multi_map_get_values (im_addr_map);
  GeeSet *email_addrs = folks_email_details_get_email_addresses (FOLKS_EMAIL_DETAILS (individual));
  GeeIterator *addrs_iter;
  char *email = NULL;

  addrs_iter = gee_iterable_iterator (GEE_ITERABLE (im_addrs));
  if (gee_iterator_first (addrs_iter))
    {
      FolksImFieldDetails *field = gee_iterator_get (addrs_iter);
      email = g_strdup (folks_abstract_field_details_get_value ((FolksAbstractFieldDetails*)field));

      g_object_unref (field);
    }

  g_object_unref (addrs_iter);
  g_object_unref (im_addrs);

  if (email != NULL)
    return email;

  addrs_iter = gee_iterable_iterator (GEE_ITERABLE (email_addrs));

  if (gee_iterator_first (addrs_iter))
    {
      FolksEmailFieldDetails *field = gee_iterator_get (addrs_iter);
      email = g_strdup (folks_abstract_field_details_get_value ((FolksAbstractFieldDetails*)field));

      g_object_unref (field);
    }

  g_object_unref (addrs_iter);

  return email;
}
Beispiel #2
0
static guint
do_match (CinnamonContactSystem  *self,
          FolksIndividual     *individual,
          GSList              *terms)
{
  GSList *term_iter;
  guint weight = 0;

  char *alias = cinnamon_util_normalize_and_casefold (folks_alias_details_get_alias (FOLKS_ALIAS_DETAILS (individual)));
  char *name = cinnamon_util_normalize_and_casefold (folks_name_details_get_full_name (FOLKS_NAME_DETAILS (individual)));
  char *nick = cinnamon_util_normalize_and_casefold (folks_name_details_get_nickname (FOLKS_NAME_DETAILS (individual)));

  GeeMultiMap *im_addr_map = folks_im_details_get_im_addresses (FOLKS_IM_DETAILS (individual));
  GeeCollection *im_addrs = gee_multi_map_get_values (im_addr_map);
  GeeSet *email_addrs = folks_email_details_get_email_addresses (FOLKS_EMAIL_DETAILS (individual));
  GeeIterator *addrs_iter;

  gboolean have_name_prefix = FALSE;
  gboolean have_name_substring = FALSE;
  
  gboolean have_addr_prefix = FALSE;
  gboolean have_addr_substring = FALSE;

  for (term_iter = terms; term_iter; term_iter = term_iter->next)
    {
      const char *term = term_iter->data;
      const char *p;
      gboolean matched;

      matched = FALSE;

      /* Match on alias, name, nickname */
      if (alias != NULL)
	{
	  p = strstr (alias, term);
	  if (p == alias)
            {
	      have_name_prefix = TRUE;
              matched = TRUE;
            }
	  else if (p != NULL)
            {
	      have_name_substring = TRUE;
              matched = TRUE;
            }
	}
      if (name != NULL)
	{
	  p = strstr (name, term);
	  if (p == name)
            {
	      have_name_prefix = TRUE;
              matched = TRUE;
            }
	  else if (p != NULL)
            {
	      have_name_substring = TRUE;
              matched = TRUE;
            }
	}
      if (nick != NULL)
	{
	  p = strstr (nick, term);
	  if (p == nick)
            {
	      have_name_prefix = TRUE;
              matched = TRUE;
            }
	  else if (p != NULL)
            {
	      have_name_substring = TRUE;
              matched = TRUE;
            }
	}

      /* Match on one or more IM or email addresses */
      addrs_iter = gee_iterable_iterator (GEE_ITERABLE (im_addrs));

      while (gee_iterator_next (addrs_iter))
        {
          FolksImFieldDetails *field = gee_iterator_get (addrs_iter);
          const gchar *addr = folks_abstract_field_details_get_value ((FolksAbstractFieldDetails*)field);

          p = strstr (addr, term);
          if (p == addr)
            {
              have_addr_prefix = TRUE;
              matched = TRUE;
            }
          else if (p != NULL)
            {
              have_addr_substring = TRUE;
              matched = TRUE;
            }

          g_object_unref (field);
        }

      g_object_unref (addrs_iter);
      addrs_iter = gee_iterable_iterator (GEE_ITERABLE (email_addrs));
      while (gee_iterator_next (addrs_iter))
        {
          FolksEmailFieldDetails *field = gee_iterator_get (addrs_iter);
          const gchar *addr = folks_abstract_field_details_get_value ((FolksAbstractFieldDetails*)field);

          p = strstr (addr, term);
          if (p == addr)
            {
              have_addr_prefix = TRUE;
              matched = TRUE;
            }
          else if (p != NULL)
            {
              have_addr_substring = TRUE;
              matched = TRUE;
            }

          g_object_unref (field);
        }

      g_object_unref (addrs_iter);

      if (!matched)
        {
          have_name_prefix = FALSE;
          have_name_substring = FALSE;
          have_addr_prefix = FALSE;
          have_addr_substring = FALSE;
          break;
        }
    }

    if (have_name_prefix)
      weight += NAME_PREFIX_MATCH_WEIGHT;
    else if (have_name_substring)
      weight += NAME_SUBSTRING_MATCH_WEIGHT;

    if (have_addr_prefix)
      weight += ADDR_PREFIX_MATCH_WEIGHT;
    else if (have_addr_substring)
      weight += ADDR_SUBSTRING_MATCH_WEIGHT;

  g_free (alias);
  g_free (name);
  g_free (nick);
  g_object_unref (im_addrs);

  return weight;
}
static void
aggregator_individuals_changed_cb (FolksIndividualAggregator *aggregator,
    GeeMultiMap *changes,
    EmpathyIndividualManager *self)
{
  EmpathyIndividualManagerPriv *priv = GET_PRIV (self);
  GeeIterator *iter;
  GeeSet *removed;
  GeeCollection *added;
  GList *added_set = NULL, *added_filtered = NULL, *removed_list = NULL;

  /* We're not interested in the relationships between the added and removed
   * individuals, so just extract collections of them. Note that the added
   * collection may contain duplicates, while the removed set won't. */
  removed = gee_multi_map_get_keys (changes);
  added = gee_multi_map_get_values (changes);

  /* Handle the removals first, as one of the added Individuals might have the
   * same ID as one of the removed Individuals (due to linking). */
  iter = gee_iterable_iterator (GEE_ITERABLE (removed));
  while (gee_iterator_next (iter))
    {
      FolksIndividual *ind = gee_iterator_get (iter);

      if (ind == NULL)
        continue;

      g_signal_handlers_disconnect_by_func (ind,
          individual_notify_personas_cb, self);

      if (g_hash_table_lookup (priv->individuals,
          folks_individual_get_id (ind)) != NULL)
        {
          remove_individual (self, ind);
          removed_list = g_list_prepend (removed_list, ind);
        }

      g_clear_object (&ind);
    }
  g_clear_object (&iter);

  /* Filter the individuals for ones which contain EmpathyContacts */
  iter = gee_iterable_iterator (GEE_ITERABLE (added));
  while (gee_iterator_next (iter))
    {
      FolksIndividual *ind = gee_iterator_get (iter);

      /* Make sure we handle each added individual only once. */
      if (ind == NULL || g_list_find (added_set, ind) != NULL)
        continue;
      added_set = g_list_prepend (added_set, ind);

      g_signal_connect (ind, "notify::personas",
          G_CALLBACK (individual_notify_personas_cb), self);

      if (empathy_folks_individual_contains_contact (ind) == TRUE)
        {
          add_individual (self, ind);
          added_filtered = g_list_prepend (added_filtered, ind);
        }

      g_clear_object (&ind);
    }
  g_clear_object (&iter);

  g_list_free (added_set);

  g_object_unref (added);
  g_object_unref (removed);

  /* Bail if we have no individuals left */
  if (added_filtered == NULL && removed == NULL)
    return;

  added_filtered = g_list_reverse (added_filtered);

  g_signal_emit (self, signals[MEMBERS_CHANGED], 0, NULL,
      added_filtered, removed_list,
      TP_CHANNEL_GROUP_CHANGE_REASON_NONE,
      TRUE);

  g_list_free (added_filtered);
  g_list_free (removed_list);
}