[gnome-control-center] printers: get printer job attributes async



commit dc7b78ca423b710bda1109c278e863235a86f2e7
Author: Felipe Borges <felipeborges gnome org>
Date:   Wed Feb 17 15:25:14 2016 +0100

    printers: get printer job attributes async
    
    https://bugzilla.gnome.org/show_bug.cgi?id=748336

 panels/printers/cc-printers-panel.c |  107 +++++++++++++++-----------
 panels/printers/pp-job.c            |  144 +++++++++++++++++++++++++++++++++++
 panels/printers/pp-job.h            |   18 ++++-
 3 files changed, 219 insertions(+), 50 deletions(-)
---
diff --git a/panels/printers/cc-printers-panel.c b/panels/printers/cc-printers-panel.c
index e4ec22b..1159495 100644
--- a/panels/printers/cc-printers-panel.c
+++ b/panels/printers/cc-printers-panel.c
@@ -39,6 +39,7 @@
 #include "pp-utils.h"
 #include "pp-maintenance-command.h"
 #include "pp-cups.h"
+#include "pp-job.h"
 
 CC_PANEL_REGISTER (CcPrintersPanel, cc_printers_panel)
 
@@ -271,6 +272,56 @@ cc_printers_panel_class_init (CcPrintersPanelClass *klass)
 }
 
 static void
+on_get_job_attributes_cb (GObject      *source_object,
+                          GAsyncResult *res,
+                          gpointer      user_data)
+{
+  CcPrintersPanel        *self = (CcPrintersPanel*) user_data;
+  CcPrintersPanelPrivate *priv;
+  const gchar            *job_originating_user_name;
+  const gchar            *job_printer_uri;
+  GVariant               *attributes;
+  GVariant               *username;
+  GVariant               *printer_uri;
+  GError                 *error = NULL;
+
+  priv = PRINTERS_PANEL_PRIVATE (self);
+
+  attributes = pp_job_get_attributes_finish (PP_JOB (source_object), res, &error);
+  g_object_unref (source_object);
+
+  if (attributes != NULL)
+    {
+      if ((username = g_variant_lookup_value (attributes, "job-originating-user-name", G_VARIANT_TYPE 
("as"))) != NULL)
+       {
+         if ((printer_uri = g_variant_lookup_value (attributes, "job-printer-uri", G_VARIANT_TYPE ("as"))) 
!= NULL)
+            {
+              job_originating_user_name = g_variant_get_string (g_variant_get_child_value (username, 0), 
NULL);
+              job_printer_uri = g_variant_get_string (g_variant_get_child_value (printer_uri, 0), NULL);
+
+              if (job_originating_user_name != NULL && job_printer_uri != NULL &&
+                  g_strcmp0 (job_originating_user_name, cupsUser ()) == 0 &&
+                  g_strrstr (job_printer_uri, "/") != 0 &&
+                  priv->current_dest >= 0 &&
+                  priv->current_dest < priv->num_dests &&
+                  priv->dests != NULL &&
+                  g_strcmp0 (g_strrstr (job_printer_uri, "/") + 1,
+                                        priv->dests[priv->current_dest].name) == 0)
+                {
+                  update_jobs_count (self);
+                }
+
+             g_variant_unref (printer_uri);
+            }
+
+         g_variant_unref (username);
+       }
+
+      g_variant_unref (attributes);
+    }
+}
+
+static void
 on_cups_notification (GDBusConnection *connection,
                       const char      *sender_name,
                       const char      *object_path,
@@ -280,23 +331,22 @@ on_cups_notification (GDBusConnection *connection,
                       gpointer         user_data)
 {
   CcPrintersPanel        *self = (CcPrintersPanel*) user_data;
-  CcPrintersPanelPrivate *priv;
   gboolean                printer_is_accepting_jobs;
   gchar                  *printer_name = NULL;
   gchar                  *text = NULL;
   gchar                  *printer_uri = NULL;
   gchar                  *printer_state_reasons = NULL;
+  PpJob                  *job;
   gchar                  *job_state_reasons = NULL;
   gchar                  *job_name = NULL;
   guint                   job_id;
   gint                    printer_state;
   gint                    job_state;
   gint                    job_impressions_completed;
-  static const char * const requested_attrs[] = {
+  static gchar *requested_attrs[] = {
     "job-printer-uri",
-    "job-originating-user-name"};
-
-  priv = PRINTERS_PANEL_PRIVATE (self);
+    "job-originating-user-name",
+    NULL };
 
   if (g_strcmp0 (signal_name, "PrinterAdded") != 0 &&
       g_strcmp0 (signal_name, "PrinterDeleted") != 0 &&
@@ -342,47 +392,12 @@ on_cups_notification (GDBusConnection *connection,
   else if (g_strcmp0 (signal_name, "JobCreated") == 0 ||
            g_strcmp0 (signal_name, "JobCompleted") == 0)
     {
-      http_t *http;
-      gchar  *job_uri;
-      ipp_t  *request, *response;
-
-      job_uri = g_strdup_printf ("ipp://localhost/jobs/%d", job_id);
-      if ((http = httpConnectEncrypt (cupsServer (), ippPort (),
-                                     cupsEncryption ())) != NULL)
-        {
-          request = ippNewRequest (IPP_GET_JOB_ATTRIBUTES);
-          ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI,
-                       "job-uri", NULL, job_uri);
-          ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_NAME,
-                        "requesting-user-name", NULL, cupsUser ());
-          ippAddStrings (request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
-                         "requested-attributes", G_N_ELEMENTS (requested_attrs), NULL, requested_attrs);
-          response = cupsDoRequest (http, request, "/");
-
-          if (response)
-            {
-              if (ippGetStatusCode (response) <= IPP_OK_CONFLICT)
-                {
-                  ipp_attribute_t *attr_username = NULL;
-                  ipp_attribute_t *attr_printer_uri = NULL;
-
-                  attr_username = ippFindAttribute(response, "job-originating-user-name", IPP_TAG_NAME);
-                  attr_printer_uri = ippFindAttribute(response, "job-printer-uri", IPP_TAG_URI);
-                  if (attr_username && attr_printer_uri &&
-                      g_strcmp0 (ippGetString (attr_username, 0, NULL), cupsUser ()) == 0 &&
-                      g_strrstr (ippGetString (attr_printer_uri, 0, NULL), "/") != 0 &&
-                      priv->current_dest >= 0 &&
-                      priv->current_dest < priv->num_dests &&
-                      priv->dests != NULL &&
-                      g_strcmp0 (g_strrstr (ippGetString (attr_printer_uri, 0, NULL), "/") + 1,
-                                 priv->dests[priv->current_dest].name) == 0)
-                    update_jobs_count (self);
-                }
-              ippDelete(response);
-            }
-          httpClose (http);
-        }
-      g_free (job_uri);
+      job = g_object_new (PP_TYPE_JOB, "id", job_id, NULL);
+      pp_job_get_attributes_async (job,
+                                   requested_attrs,
+                                   NULL,
+                                   on_get_job_attributes_cb,
+                                   self);
     }
 }
 
diff --git a/panels/printers/pp-job.c b/panels/printers/pp-job.c
index 42200a7..0c7c267 100644
--- a/panels/printers/pp-job.c
+++ b/panels/printers/pp-job.c
@@ -20,6 +20,9 @@
 
 #include "pp-job.h"
 
+#include <gio/gio.h>
+#include <cups/cups.h>
+
 typedef struct
 {
   GObject parent;
@@ -249,3 +252,144 @@ pp_job_class_init (PpJobClass *class)
 
   g_object_class_install_properties (object_class, LAST_PROPERTY, properties);
 }
+
+static void
+_pp_job_get_attributes_thread (GTask        *task,
+                               gpointer      source_object,
+                               gpointer      task_data,
+                               GCancellable *cancellable)
+{
+  ipp_attribute_t *attr = NULL;
+  GVariantBuilder  builder;
+  GVariant        *attributes = NULL;
+  gchar          **attributes_names = task_data;
+  PpJobPrivate    *priv;
+  ipp_t           *request;
+  ipp_t           *response = NULL;
+  gchar           *job_uri;
+  gint             i, j, length = 0, n_attrs = 0;
+
+  priv = pp_job_get_instance_private (source_object);
+
+  job_uri = g_strdup_printf ("ipp://localhost/jobs/%d", priv->id);
+
+  if (attributes_names != NULL)
+    {
+      length = g_strv_length (attributes_names);
+
+      request = ippNewRequest (IPP_GET_JOB_ATTRIBUTES);
+      ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI,
+                    "job-uri", NULL, job_uri);
+      ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+                    "requesting-user-name", NULL, cupsUser ());
+      ippAddStrings (request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+                     "requested-attributes", length, NULL, (const char **) attributes_names);
+      response = cupsDoRequest (CUPS_HTTP_DEFAULT, request, "/");
+    }
+
+  if (response != NULL)
+    {
+      g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
+
+      for (j = 0; j < length; j++)
+        {
+          attr = ippFindAttribute (response, attributes_names[j], IPP_TAG_ZERO);
+          n_attrs = ippGetCount (attr);
+          if (attr != NULL && n_attrs > 0 && ippGetValueTag (attr) != IPP_TAG_NOVALUE)
+            {
+              const GVariantType  *type = NULL;
+              GVariant           **values;
+              GVariant            *range[2];
+              gint                 range_uppervalue;
+
+              values = g_new (GVariant*, n_attrs);
+
+              switch (ippGetValueTag (attr))
+                {
+                  case IPP_TAG_INTEGER:
+                  case IPP_TAG_ENUM:
+                    type = G_VARIANT_TYPE_INT32;
+
+                    for (i = 0; i < n_attrs; i++)
+                      values[i] = g_variant_new_int32 (ippGetInteger (attr, i));
+                    break;
+
+                  case IPP_TAG_NAME:
+                  case IPP_TAG_STRING:
+                  case IPP_TAG_TEXT:
+                  case IPP_TAG_URI:
+                  case IPP_TAG_KEYWORD:
+                  case IPP_TAG_URISCHEME:
+                    type = G_VARIANT_TYPE_STRING;
+
+                    for (i = 0; i < n_attrs; i++)
+                      values[i] = g_variant_new_string (ippGetString (attr, i, NULL));
+                    break;
+
+                  case IPP_TAG_RANGE:
+                    type = G_VARIANT_TYPE_TUPLE;
+
+                    for (i = 0; i < n_attrs; i++)
+                      {
+                        range[0] = g_variant_new_int32 (ippGetRange (attr, i, &(range_uppervalue)));
+                        range[1] = g_variant_new_int32 (range_uppervalue);
+
+                        values[i] = g_variant_new_tuple (range, 2);
+                      }
+                    break;
+
+                  case IPP_TAG_BOOLEAN:
+                    type = G_VARIANT_TYPE_BOOLEAN;
+
+                    for (i = 0; i < n_attrs; i++)
+                      values[i] = g_variant_new_boolean (ippGetBoolean (attr, i));
+                    break;
+
+                  default:
+                    /* do nothing (switch w/ enumeration type) */
+                    break;
+                }
+
+              if (type != NULL)
+                {
+                  g_variant_builder_add (&builder, "{sv}",
+                                         attributes_names[j],
+                                         g_variant_new_array (type, values, n_attrs));
+                }
+
+              g_free (values);
+            }
+        }
+
+      attributes = g_variant_builder_end (&builder);
+    }
+  g_free (job_uri);
+
+  g_task_return_pointer (task, attributes, (GDestroyNotify) g_variant_unref);
+}
+
+void
+pp_job_get_attributes_async (PpJob                *job,
+                             gchar               **attributes_names,
+                             GCancellable         *cancellable,
+                             GAsyncReadyCallback   callback,
+                             gpointer              user_data)
+{
+  GTask *task;
+
+  task = g_task_new (job, cancellable, callback, user_data);
+  g_task_set_task_data (task, g_strdupv (attributes_names), (GDestroyNotify) g_strfreev);
+  g_task_run_in_thread (task, _pp_job_get_attributes_thread);
+
+  g_object_unref (task);
+}
+
+GVariant *
+pp_job_get_attributes_finish (PpJob         *job,
+                              GAsyncResult  *result,
+                              GError       **error)
+{
+  g_return_val_if_fail (g_task_is_valid (result, job), NULL);
+
+  return g_task_propagate_pointer (G_TASK (result), error);
+}
diff --git a/panels/printers/pp-job.h b/panels/printers/pp-job.h
index 35e16e9..ba6f461 100644
--- a/panels/printers/pp-job.h
+++ b/panels/printers/pp-job.h
@@ -36,11 +36,21 @@ struct _PpJob
   GObject parent_instance;
 };
 
-void pp_job_set_hold_until_async (PpJob        *job,
-                                  const gchar  *job_hold_until);
+void           pp_job_set_hold_until_async       (PpJob                *job,
+                                                  const gchar          *job_hold_until);
 
-void pp_job_cancel_purge_async (PpJob        *job,
-                                gboolean      job_purge);
+void           pp_job_cancel_purge_async         (PpJob                *job,
+                                                  gboolean              job_purge);
+
+void           pp_job_get_attributes_async       (PpJob                *job,
+                                                  gchar               **attributes_names,
+                                                  GCancellable         *cancellable,
+                                                  GAsyncReadyCallback   callback,
+                                                  gpointer              user_data);
+
+GVariant      *pp_job_get_attributes_finish      (PpJob                *job,
+                                                  GAsyncResult         *result,
+                                                  GError              **error);
 
 G_END_DECLS
 


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