Re: [PATCH obexd 1/5] Change EDS backend to support multiple ebooks

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Bartosz,

On Tue, Jul 5, 2011 at 12:51 AM, Bartosz Szatkowski <bulislaw@xxxxxxxxx> wrote:
> Until now only default ebook was used, this patch change this behaviour
> so each function is run on all available (active) ebooks and merging
> results from each of them.
> ---
>  plugins/phonebook-ebook.c |  281 +++++++++++++++++++++++++++++----------------
>  1 files changed, 182 insertions(+), 99 deletions(-)
>
> diff --git a/plugins/phonebook-ebook.c b/plugins/phonebook-ebook.c
> index 82019da..f223965 100644
> --- a/plugins/phonebook-ebook.c
> +++ b/plugins/phonebook-ebook.c
> @@ -45,17 +45,20 @@
>  #define QUERY_NAME "(contains \"given_name\" \"%s\")"
>  #define QUERY_PHONE "(contains \"phone\" \"%s\")"
>
> -
>  struct query_context {
> -       gboolean completed;
>        const struct apparam_field *params;
>        phonebook_cb contacts_cb;
>        phonebook_entry_cb entry_cb;
>        phonebook_cache_ready_cb ready_cb;
> +       EBookQuery *query;
> +       int count;
> +       GString *buf;
> +       char *id;
> +       unsigned queued_calls;
>        void *user_data;
>  };
>
> -static EBook *ebook = NULL;
> +static GSList *ebooks = NULL;
>
>  static char *attribute_mask[] = {
>  /* 0 */                "VERSION",
> @@ -91,6 +94,19 @@ static char *attribute_mask[] = {
>
>  };
>
> +static void free_query_context(struct query_context *data)
> +{
> +       g_free(data->id);
> +
> +       if (data->buf != NULL)
> +               g_string_free(data->buf, TRUE);
> +
> +       if (data->query != NULL)
> +               e_book_query_unref(data->query);
> +
> +       g_free(data);
> +}
> +
>  static char *evcard_to_string(EVCard *evcard, unsigned int format,
>                                                        uint64_t filter)
>  {
> @@ -99,7 +115,8 @@ static char *evcard_to_string(EVCard *evcard, unsigned int format,
>        char *vcard;
>
>        if (!filter)
> -               return e_vcard_to_string(evcard, format);
> +               return e_vcard_to_string(evcard, EVC_FORMAT_VCARD_30);
> +               /* XXX There is no support for VCARD 2.1 at this time */
>
>        /*
>         * Mandatory attributes for vCard 2.1 are VERSION ,N and TEL.
> @@ -136,24 +153,20 @@ static char *evcard_to_string(EVCard *evcard, unsigned int format,
>        return vcard;
>  }
>
> -static void ebookpull_cb(EBook *book, EBookStatus estatus, GList *contacts,
> +static void ebookpull_cb(EBook *book, const GError *gerr, GList *contacts,
>                                                        void *user_data)
>  {
>        struct query_context *data = user_data;
> -       GString *string = g_string_new("");
> -       unsigned int count = 0, maxcount;
>        GList *l;
> +       unsigned int count = data->count, maxcount;
>
> -       if (estatus == E_BOOK_ERROR_CANCELLED) {
> -               error("E-Book operation was cancelled: status %d", estatus);
> -               goto fail;
> -       }
> -
> -       if (estatus != E_BOOK_ERROR_OK) {
> -               error("E-Book query failed: status %d", estatus);
> +       if (gerr != NULL) {
> +               error("E-Book query failed: %s", gerr->message);
>                goto done;
>        }
>
> +       DBG("");
> +
>        /*
>         * When MaxListCount is zero, PCE wants to know the number of used
>         * indexes in the phonebook of interest. All other parameters that
> @@ -161,7 +174,7 @@ static void ebookpull_cb(EBook *book, EBookStatus estatus, GList *contacts,
>         */
>        maxcount = data->params->maxlistcount;
>        if (maxcount == 0) {
> -               count = g_list_length(contacts);
> +               count += g_list_length(contacts);
>                goto done;
>        }
>
> @@ -177,45 +190,36 @@ static void ebookpull_cb(EBook *book, EBookStatus estatus, GList *contacts,
>                vcard = evcard_to_string(evcard, data->params->format,
>                                                data->params->filter);
>
> -               string = g_string_append(string, vcard);
> -               string = g_string_append(string, "\r\n");
> +               data->buf = g_string_append(data->buf, vcard);
> +               data->buf = g_string_append(data->buf, "\r\n");
>                g_free(vcard);
>        }
> -       DBG("collected %d vcards", count);
> -
>
>  done:
> -       data->completed = TRUE;
> -       data->contacts_cb(string->str, string->len, count, 0, TRUE,
> -                                                       data->user_data);
> +       g_list_free_full(contacts, g_object_unref);
>
> -fail:
> -       g_string_free(string, TRUE);
> +       DBG("collected %d vcards", count);
>
> -       if (data->completed)
> -               g_free(data);
> +       data->queued_calls--;
> +       if (data->queued_calls == 0)
> +               data->contacts_cb(data->buf->str, data->buf->len, count, 0,
> +                                                       TRUE, data->user_data);
>  }
>
> -static void ebook_entry_cb(EBook *book, EBookStatus estatus,
> -                       EContact *contact, void *user_data)
> +static void ebook_entry_cb(EBook *book, const GError *gerr,
> +                               EContact *contact, void *user_data)
>  {
>        struct query_context *data = user_data;
>        EVCard *evcard;
>        char *vcard;
>        size_t len;
>
> -       if (estatus == E_BOOK_ERROR_CANCELLED) {
> -               error("E-Book operation was cancelled: status %d", estatus);
> -               goto fail;
> +       if (gerr != NULL) {
> +               error("E-Book query failed: %s", gerr->message);
> +               goto done;
>        }
>
> -       data->completed = TRUE;
> -
> -       if (estatus != E_BOOK_ERROR_OK) {
> -               error("E-Book query failed: status %d", estatus);
> -               data->contacts_cb(NULL, 0, 1, 0, TRUE, data->user_data);
> -               goto fail;
> -       }
> +       DBG("");
>
>        evcard = E_VCARD(contact);
>
> @@ -224,13 +228,21 @@ static void ebook_entry_cb(EBook *book, EBookStatus estatus,
>
>        len = vcard ? strlen(vcard) : 0;
>
> +       data->count++;
>        data->contacts_cb(vcard, len, 1, 0, TRUE, data->user_data);
>
>        g_free(vcard);
> +       g_object_unref(contact);
>
> -fail:
> -       if (data->completed)
> -               g_free(data);
> +done:
> +       data->queued_calls--;
> +       if (data->queued_calls == 0) {
> +               if (data->count == 0)
> +                       data->contacts_cb(NULL, 0, 1, 0, TRUE,
> +                                               data->user_data);
> +
> +               free_query_context(data);
> +       }
>  }
>
>  static char *evcard_name_attribute_to_string(EVCard *evcard)
> @@ -263,24 +275,19 @@ static char *evcard_name_attribute_to_string(EVCard *evcard)
>        return g_string_free(name, FALSE);
>  }
>
> -static void cache_cb(EBook *book, EBookStatus estatus, GList *contacts,
> +static void cache_cb(EBook *book, const GError *gerr, GList *contacts,
>                                                        void *user_data)
>  {
>        struct query_context *data = user_data;
>        GList *l;
>
> -       if (estatus == E_BOOK_ERROR_CANCELLED) {
> -               error("E-Book operation was cancelled: status %d", estatus);
> -               goto fail;
> -       }
> -
> -       data->completed = TRUE;
> -
> -       if (estatus != E_BOOK_ERROR_OK) {
> -               error("E-Book query failed: status %d", estatus);
> +       if (gerr != NULL) {
> +               error("E-Book operation failed: %s", gerr->message);
>                goto done;
>        }
>
> +       DBG("");
> +
>        for (l = contacts; l; l = g_list_next(l)) {
>                EContact *contact = E_CONTACT(l->data);
>                EVCard *evcard = E_VCARD(contact);
> @@ -295,61 +302,116 @@ static void cache_cb(EBook *book, EBookStatus estatus, GList *contacts,
>                if (!attrib)
>                        continue;
>
> -               uid =  e_vcard_attribute_get_value(attrib);
> +               uid = e_vcard_attribute_get_value(attrib);
>                if (!uid)
>                        continue;
>
>                attrib = e_vcard_get_attribute(evcard, EVC_TEL);
>                if (!attrib)
> -                       continue;
> -
> -               tel =  e_vcard_attribute_get_value(attrib);
> +                       tel = e_vcard_attribute_get_value(attrib);
> +               else
> +                       tel = g_strdup("");
>
>                data->entry_cb(uid, PHONEBOOK_INVALID_HANDLE, name, NULL,
>                                                        tel, data->user_data);
> +
>                g_free(name);
>                g_free(uid);
>                g_free(tel);
>        }
> +
>  done:
> -       data->ready_cb(data->user_data);
> +       g_list_free_full(contacts, g_object_unref);
>
> -fail:
> -       if (data->completed)
> -               g_free(data);
> +       data->queued_calls--;
> +       if (data->queued_calls == 0)
> +               data->ready_cb(data->user_data);
>  }
>
>  int phonebook_init(void)
>  {
> -       GError *gerr = NULL;
> +       GError *gerr;
> +       ESourceList *src_list;
> +       GSList *list;
> +       gchar *default_src = NULL;
> +       int status = 0;
>
> -       if (ebook)
> +       if (ebooks)
>                return 0;
>
>        g_type_init();
>
> -       ebook = e_book_new_default_addressbook(&gerr);
> -       if (!ebook) {
> -               error("Can't create user's default address book: %s",
> -                               gerr->message);
> -               g_error_free(gerr);
> -               return -EIO;
> +       if (e_book_get_addressbooks(&src_list, &gerr) == FALSE) {
> +               error("Can't list user's address books: %s", gerr->message);
> +
> +               status = -EIO;
> +               goto fail;
>        }
>
> -       if (!e_book_open(ebook, FALSE, &gerr)) {
> -               error("Can't open e-book address book: %s", gerr->message);
> -               g_error_free(gerr);
> -               return -EIO;

Please consider splitting this function since it is becoming too big.

> +       list = e_source_list_peek_groups(src_list);
> +       while (list) {
> +               ESourceGroup *group = E_SOURCE_GROUP(list->data);
> +
> +               GSList *sources = e_source_group_peek_sources(group);
> +               while (sources != NULL) {
> +                       EBook *ebook = e_book_new(E_SOURCE(sources->data),
> +                                                                       &gerr);
> +                       if (ebook == NULL) {
> +                               error("Can't create user's address book: %s",
> +                                                               gerr->message);
> +
> +                               status = -EIO;
> +                               goto fail;
> +                       }
> +
> +                       if (g_strcmp0(default_src, e_source_get_uri(
> +                                       E_SOURCE(sources->data))) == 0) {
> +                               sources = sources->next;
> +
> +                               continue;
> +                       }
> +
> +                       if (e_book_open(ebook, FALSE, &gerr) == FALSE) {
> +                               error("Can't open e-book address book: %s",
> +                                                               gerr->message);
> +
> +                               status = -EIO;
> +                               goto fail;
> +                       }
> +
> +                       if (default_src == NULL)
> +                               default_src = e_source_get_uri(
> +                                               E_SOURCE(sources->data));
> +
> +                       DBG("%s address book opened",
> +                                       e_source_peek_name(sources->data));
> +
> +                       ebooks = g_slist_append(ebooks, ebook);
> +
> +                       sources = sources->next;
> +               }
> +
> +               list = list->next;
>        }
>
> -       return 0;
> +       return status;
> +
> +fail:
> +       g_error_free(gerr);
> +       g_slist_free_full(ebooks, g_object_unref);
> +       g_object_unref(src_list);
> +
> +       return status;
>  }
>
>  void phonebook_exit(void)
>  {
> -       if (ebook)
> -               g_object_unref(ebook);
> -       ebook = NULL;
> +       DBG("");
> +
> +       if (ebooks == NULL)
> +               return;
> +
> +       g_slist_free_full(ebooks, g_object_unref);
>  }
>
>  char *phonebook_set_folder(const char *current_folder,
> @@ -440,13 +502,10 @@ void phonebook_req_finalize(void *request)
>  {
>        struct query_context *data = request;
>
> -       if (!data)
> -               return;
> +       DBG("");
>
> -       if (!data->completed) {
> -               data->completed = TRUE;
> -               e_book_cancel_async_op(ebook, NULL);
> -       }
> +       if (data != NULL && data->queued_calls == 0)
> +               free_query_context(data);
>  }
>
>  void *phonebook_pull(const char *name, const struct apparam_field *params,
> @@ -458,6 +517,7 @@ void *phonebook_pull(const char *name, const struct apparam_field *params,
>        data->contacts_cb = cb;
>        data->params = params;
>        data->user_data = user_data;
> +       data->buf = g_string_new("");
>
>        if (err)
>                *err = 0;
> @@ -468,15 +528,26 @@ void *phonebook_pull(const char *name, const struct apparam_field *params,
>  int phonebook_pull_read(void *request)
>  {
>        struct query_context *data = request;
> -       EBookQuery *query;
> +       gboolean ret;
> +       GSList *ebook;
>
>        if (!data)
>                return -ENOENT;
>
> -       query = e_book_query_any_field_contains("");
> -       e_book_async_get_contacts(ebook, query, ebookpull_cb, data);
> +       data->query = e_book_query_any_field_contains("");
> +
> +       ebook = ebooks;
> +       while (ebook != NULL) {
> +               ret = e_book_get_contacts_async(ebook->data, data->query,
> +                                                       ebookpull_cb, data);
> +               if (ret == TRUE)
> +                       data->queued_calls++;
>
> -       e_book_query_unref(query);
> +               ebook = ebook->next;
> +       }
> +
> +       if (data->queued_calls == 0)
> +               return -ENOENT;
>
>        return 0;
>  }
> @@ -485,22 +556,28 @@ void *phonebook_get_entry(const char *folder, const char *id,
>                                const struct apparam_field *params,
>                                phonebook_cb cb, void *user_data, int *err)
>  {
> +       gboolean ret;
>        struct query_context *data;
> +       GSList *ebook;
>
>        data = g_new0(struct query_context, 1);
>        data->contacts_cb = cb;
>        data->params = params;
>        data->user_data = user_data;
> +       data->id = g_strdup(id);
>
> -       if (e_book_async_get_contact(ebook, id, ebook_entry_cb, data)) {
> -               g_free(data);
> -               if (err)
> -                       *err = -ENOENT;
> -               return NULL;
> +       ebook = ebooks;
> +       while (ebook != NULL) {
> +               ret = e_book_get_contact_async(ebook->data, data->id,
> +                                                       ebook_entry_cb, data);
> +               if (ret == TRUE)
> +                       data->queued_calls++;
> +
> +               ebook = ebook->next;
>        }
>
>        if (err)
> -               *err = 0;
> +               *err = (data->queued_calls == 0 ? -ENOENT : 0);
>
>        return data;
>  }
> @@ -511,31 +588,37 @@ void *phonebook_create_cache(const char *name, phonebook_entry_cb entry_cb,
>        struct query_context *data;
>        EBookQuery *query;
>        gboolean ret;
> +       GSList *ebook;
>
>        if (g_strcmp0("/telecom/pb", name) != 0) {
>                if (err)
>                        *err = -ENOENT;
> +
>                return NULL;
>        }
>
> +       DBG("");
> +
>        query = e_book_query_any_field_contains("");
>
>        data = g_new0(struct query_context, 1);
>        data->entry_cb = entry_cb;
>        data->ready_cb = ready_cb;
>        data->user_data = user_data;
> +       data->query = query;
>
> -       ret = e_book_async_get_contacts(ebook, query, cache_cb, data);
> -       e_book_query_unref(query);
> -       if (ret != FALSE) {
> -               g_free(data);
> -               if (err)
> -                       *err = -EFAULT;
> -               return NULL;
> +       ebook = ebooks;
> +       while (ebook != NULL) {
> +               ret = e_book_get_contacts_async(ebook->data, query,
> +                                                       cache_cb, data);
> +               if (ret == TRUE)
> +                       data->queued_calls++;
> +
> +               ebook = ebook->next;
>        }
>
>        if (err)
> -               *err = 0;
> +               *err = (data->queued_calls == 0 ? -ENOENT : 0);
>
>        return data;
>  }
> --
> 1.7.5.3
>
> --

Btw, are we still using libebook? I though this breaks the integration
with gdbus, doesn't it?



-- 
Luiz Augusto von Dentz
--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux