[easytag/wip/musicbrainz-support] Implemented Error showing during Manual Search



commit 2d8b4837df68645c08dabeeb3753000daf3e6527
Author: Abhinav <abhijangda hotmail com>
Date:   Sat May 17 19:45:02 2014 +0530

    Implemented Error showing during Manual Search

 data/musicbrainz_dialog.ui |   16 +++---
 src/mb_search.c            |  127 ++++++++++++++++++++++++++++++++++++++------
 src/mb_search.h            |   44 ++++++++++++++--
 src/mbentityview.c         |   40 ++++++++++----
 src/musicbrainz_dialog.c   |   56 +++++++++++++++----
 src/musicbrainz_dialog.h   |   12 ++++-
 6 files changed, 244 insertions(+), 51 deletions(-)
---
diff --git a/data/musicbrainz_dialog.ui b/data/musicbrainz_dialog.ui
index bcc49cd..ade53f4 100755
--- a/data/musicbrainz_dialog.ui
+++ b/data/musicbrainz_dialog.ui
@@ -6,11 +6,6 @@
     <property name="can_focus">False</property>
     <property name="stock">gtk-find</property>
   </object>
-  <object class="GtkImage" id="image13">
-    <property name="visible">True</property>
-    <property name="can_focus">False</property>
-    <property name="stock">gtk-stop</property>
-  </object>
   <object class="GtkImage" id="image10">
     <property name="visible">True</property>
     <property name="can_focus">False</property>
@@ -26,6 +21,11 @@
     <property name="can_focus">False</property>
     <property name="stock">gtk-find</property>
   </object>
+  <object class="GtkImage" id="image13">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="stock">gtk-stop</property>
+  </object>
   <object class="GtkImage" id="image14">
     <property name="visible">True</property>
     <property name="can_focus">False</property>
@@ -66,11 +66,13 @@
       <object class="GtkBox" id="dialog-vbox1">
         <property name="can_focus">False</property>
         <property name="orientation">vertical</property>
-        <property name="spacing">2</property>
         <child internal-child="action_area">
           <object class="GtkButtonBox" id="dialog-action_area1">
             <property name="can_focus">False</property>
             <property name="layout_style">end</property>
+            <child>
+              <placeholder/>
+            </child>
           </object>
           <packing>
             <property name="expand">False</property>
@@ -737,7 +739,7 @@
               </packing>
             </child>
             <child>
-              <object class="GtkStatusbar" id="statusbar1">
+              <object class="GtkStatusbar" id="statusbar">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
                 <property name="spacing">2</property>
diff --git a/src/mb_search.c b/src/mb_search.c
index 5f3cfb3..16dc086 100644
--- a/src/mb_search.c
+++ b/src/mb_search.c
@@ -21,6 +21,19 @@
 #include "mb_search.h"
 
 /*
+ * et_mb5_search_error_quark:
+ *
+ * To get EtMB5SearchError domain.
+ *
+ * Returns: GQuark for EtMB5SearchError domain
+ */
+GQuark
+et_mb5_search_error_quark (void)
+{
+    return g_quark_from_static_string ("et-mb5-search-error-quark");
+}
+
+/*
  * et_musicbrainz_search_in_entity:
  * @string:
  * @child_type:
@@ -30,16 +43,16 @@
  *
  *
  */
-void
+gboolean
 et_musicbrainz_search_in_entity (enum MB_ENTITY_TYPE child_type,
                                  enum MB_ENTITY_TYPE parent_type,
-                                 gchar *parent_mbid, GNode *root)
+                                 gchar *parent_mbid, GNode *root,
+                                 GError **error)
 {
     Mb5Query query;
     Mb5Metadata metadata;
     char error_message[256];
     tQueryResult result;
-    //int httpcode;
     char *param_values[1];
     char *param_names[1];
 
@@ -53,7 +66,7 @@ et_musicbrainz_search_in_entity (enum MB_ENTITY_TYPE child_type,
         metadata = mb5_query_query (query, "artist", parent_mbid, "", 1, param_names,
                                     param_values);
         result = mb5_query_get_lastresult (query);
-        //httpcode = mb5_query_get_lasthttpcode (query);
+
         if (result == eQuery_Success)
         {
             if (metadata)
@@ -77,7 +90,6 @@ et_musicbrainz_search_in_entity (enum MB_ENTITY_TYPE child_type,
                         entity->type = MB_ENTITY_TYPE_ALBUM;
                         node = g_node_new (entity);
                         g_node_append (root, node);
-                        printf ("releases\n");
                     }
                 }
             }
@@ -93,12 +105,53 @@ et_musicbrainz_search_in_entity (enum MB_ENTITY_TYPE child_type,
         
     }
 
-    return;
+    mb5_query_delete (query);
+
+    return TRUE;
+
     err:
     mb5_query_get_lasterrormessage (query, error_message,
                                     sizeof(error_message));
-    printf ("Error searching MusicBrainz Database: '%s'\n", error_message);
-    mb5_query_delete (query);
+
+    switch (result)
+    {
+        case eQuery_ConnectionError:
+            g_set_error (error, ET_MB5_SEARCH_ERROR,
+                         ET_MB5_SEARCH_ERROR_CONNECTION, error_message);
+            break;
+
+        case eQuery_Timeout:
+            g_set_error (error, ET_MB5_SEARCH_ERROR,
+                         ET_MB5_SEARCH_ERROR_TIMEOUT, error_message);
+            break;
+
+        case eQuery_AuthenticationError:
+            g_set_error (error, ET_MB5_SEARCH_ERROR,
+                         ET_MB5_SEARCH_ERROR_AUTHENTICATION, error_message);
+            break;
+
+        case eQuery_FetchError:
+            g_set_error (error, ET_MB5_SEARCH_ERROR,
+                         ET_MB5_SEARCH_ERROR_FETCH, error_message);
+            break;
+ 
+        case eQuery_RequestError:
+            g_set_error (error, ET_MB5_SEARCH_ERROR,
+                         ET_MB5_SEARCH_ERROR_REQUEST, error_message);
+            break;
+ 
+        case eQuery_ResourceNotFound:
+            g_set_error (error, ET_MB5_SEARCH_ERROR, 
+                         ET_MB5_SEARCH_ERROR_RESOURCE_NOT_FOUND,
+                         error_message);
+            break;
+
+        default:
+            break;
+    }
+
+    g_assert (error == NULL || *error != NULL);
+    return FALSE;
 }
 
 /*
@@ -109,18 +162,19 @@ et_musicbrainz_search_in_entity (enum MB_ENTITY_TYPE child_type,
  *
  *
  */
-void
-et_musicbrainz_search (gchar *string, enum MB_ENTITY_TYPE type, GNode *root)
+gboolean
+et_musicbrainz_search (gchar *string, enum MB_ENTITY_TYPE type, GNode *root,
+                       GError **error)
 {
-    /* TODO: to free metadata, first use mb5_<entity>_copy to copy that entity */
     Mb5Query query;
     Mb5Metadata metadata;
     char error_message[256];
     tQueryResult result;
-    //int HTTPCode;
     char *param_values[2];
     char *param_names[2];
 
+    g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
     param_names [0] = "query";
     param_names [1] = "limit";
     param_values [1] = SEARCH_LIMIT_STR;
@@ -132,7 +186,6 @@ et_musicbrainz_search (gchar *string, enum MB_ENTITY_TYPE type, GNode *root)
         metadata = mb5_query_query (query, "artist", "", "", 2, param_names,
                                     param_values);
         result = mb5_query_get_lastresult (query);
-        //HTTPCode = mb5_query_get_lasthttpcode (Query);
         if (result == eQuery_Success)
         {
             if (metadata)
@@ -173,7 +226,7 @@ et_musicbrainz_search (gchar *string, enum MB_ENTITY_TYPE type, GNode *root)
         metadata = mb5_query_query (query, "release", "", "", 2, param_names,
                                     param_values);
         result = mb5_query_get_lastresult (query);
-        //HTTPCode = mb5_query_get_lasthttpcode (Query);
+
         if (result == eQuery_Success)
         {
             if (metadata)
@@ -185,7 +238,7 @@ et_musicbrainz_search (gchar *string, enum MB_ENTITY_TYPE type, GNode *root)
                 for (i = 0; i < mb5_release_list_size (list); i++)
                 {
                     Mb5Release release;
-                    release = mb5_artist_list_item (list, i);
+                    release = mb5_release_list_item (list, i);
                     if (release)
                     {
                         GNode *node;
@@ -213,12 +266,52 @@ et_musicbrainz_search (gchar *string, enum MB_ENTITY_TYPE type, GNode *root)
     }
 
     mb5_query_delete (query);
-    return;
+
+    return TRUE;
 
     err:
     mb5_query_get_lasterrormessage (query, error_message,
                                     sizeof(error_message));
-    printf ("Error searching MusicBrainz Database: '%s'\n", error_message);
+
+    switch (result)
+    {
+        case eQuery_ConnectionError:
+            g_set_error (error, ET_MB5_SEARCH_ERROR,
+                         ET_MB5_SEARCH_ERROR_CONNECTION, error_message);
+            break;
+
+        case eQuery_Timeout:
+            g_set_error (error, ET_MB5_SEARCH_ERROR,
+                         ET_MB5_SEARCH_ERROR_TIMEOUT, error_message);
+            break;
+
+        case eQuery_AuthenticationError:
+            g_set_error (error, ET_MB5_SEARCH_ERROR,
+                         ET_MB5_SEARCH_ERROR_AUTHENTICATION, error_message);
+            break;
+
+        case eQuery_FetchError:
+            g_set_error (error, ET_MB5_SEARCH_ERROR,
+                         ET_MB5_SEARCH_ERROR_FETCH, error_message);
+            break;
+ 
+        case eQuery_RequestError:
+            g_set_error (error, ET_MB5_SEARCH_ERROR,
+                         ET_MB5_SEARCH_ERROR_REQUEST, error_message);
+            break;
+ 
+        case eQuery_ResourceNotFound:
+            g_set_error (error, ET_MB5_SEARCH_ERROR, 
+                         ET_MB5_SEARCH_ERROR_RESOURCE_NOT_FOUND,
+                         error_message);
+            break;
+
+        default:
+            break;
+    }
+
+    g_assert (error == NULL || *error != NULL);
+    return FALSE;
 }
 
 /*
diff --git a/src/mb_search.h b/src/mb_search.h
index 1d46b56..17b8dfc 100644
--- a/src/mb_search.h
+++ b/src/mb_search.h
@@ -27,6 +27,40 @@
 #define SEARCH_LIMIT_STR "5"
 #define SEARCH_LIMIT_INT 5
 
+/****************
+ * Declarations *
+ ****************/
+
+GCancellable *cancellable;
+
+/*
+ * Error domain and codes for errors while reading/writing Opus files
+ */
+GQuark et_mb5_search_error_quark (void);
+
+#define ET_MB5_SEARCH_ERROR et_mb5_search_error_quark ()
+
+/*
+ * EtMB5SearchError:
+ * @ET_MB5_SEARCH_ERROR_CONNECTION: Connection Error
+ * @ET_MB5_SEARCH_ERROR_TIMEOUT: Timeout reached while communicating
+ * @ET_MB5_SEARCH_ERROR_AUTHENTICATION: Server Authentication not matched
+ * @ET_MB5_SEARCH_ERROR_FETCH: Cannot Fetch Data
+ * @ET_MB5_SEARCH_ERROR_REQUEST: Request to MusicBrainz Server cannot be made
+ * @ET_MB5_SEARCH_ERROR_RESOURCE_NOT_FOUND: Resource user is trying to search is not found
+ *
+ * Errors while searching MusicBrainz Server.
+ */
+typedef enum
+{
+    ET_MB5_SEARCH_ERROR_CONNECTION,
+    ET_MB5_SEARCH_ERROR_TIMEOUT,
+    ET_MB5_SEARCH_ERROR_AUTHENTICATION,
+    ET_MB5_SEARCH_ERROR_FETCH,
+    ET_MB5_SEARCH_ERROR_REQUEST,
+    ET_MB5_SEARCH_ERROR_RESOURCE_NOT_FOUND,
+} EtMB5SearchError;
+
 enum MB_ENTITY_TYPE
 {
     MB_ENTITY_TYPE_ARTIST = 0,
@@ -45,12 +79,14 @@ typedef struct
  * Prototypes *
  **************/
 
-void
+gboolean
 et_musicbrainz_search_in_entity (enum MB_ENTITY_TYPE child_type,
                                  enum MB_ENTITY_TYPE parent_type,
-                                 gchar *parent_mbid, GNode *root);
-void
-et_musicbrainz_search (gchar *string, enum MB_ENTITY_TYPE type, GNode *root);
+                                 gchar *parent_mbid, GNode *root,
+                                 GError **error);
+gboolean
+et_musicbrainz_search (gchar *string, enum MB_ENTITY_TYPE type, GNode *root,
+                       GError **error);
 void
 free_mb_tree (GNode *node);
 #endif /* __MB_SEARCH_H__ */
\ No newline at end of file
diff --git a/src/mbentityview.c b/src/mbentityview.c
index 3bcbd4d..2f7fbb7 100644
--- a/src/mbentityview.c
+++ b/src/mbentityview.c
@@ -18,7 +18,14 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
+#include <gdk/gdkkeysyms.h>
+#include <glib/gi18n.h>
+
+#include "gtk2_compat.h"
+#include "easytag.h"
 #include "mbentityview.h"
+#include "log.h"
+#include "musicbrainz_dialog.h"
 
 #define NAME_MAX_SIZE 256
 #define ET_MB_ENTITY_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
@@ -94,8 +101,9 @@ tree_view_row_activated (GtkTreeView *tree_view, GtkTreePath *path,
 GType
 et_mb_entity_view_get_type (void)
 {
+    /* TODO: Use G_DEFINE_TYPE */
     static GType et_mb_entity_view_type = 0;
-    
+
     if (!et_mb_entity_view_type)
     {
         static const GTypeInfo et_mb_entity_view_type_info = 
@@ -349,15 +357,15 @@ toggle_button_clicked (GtkWidget *btn, gpointer user_data)
         return;
     }
 
-    if (!gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (btn)))
+    if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (btn)))
     {
         return;
     }
 
     if (priv->active_toggle_button)
     {
-        gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (priv->active_toggle_button),
-                                           FALSE);
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->active_toggle_button),
+                                      FALSE);
     }
 
     children = gtk_container_get_children (GTK_CONTAINER (priv->bread_crumb_box));
@@ -425,11 +433,12 @@ search_in_levels_callback (GObject *source, GAsyncResult *res,
     show_data_in_entity_view (entity_view);
     g_object_unref (res);
 }
-                            
+
 static void
 search_in_levels_thread_func (GSimpleAsyncResult *res, GObject *obj,
                               GCancellable *cancellable)
 {
+    /* TODO: Call GTK+ functions from main thread */
     EtMbEntityView *entity_view;
     EtMbEntityViewPrivate *priv;
     GtkTreeSelection *selection;
@@ -438,6 +447,7 @@ search_in_levels_thread_func (GSimpleAsyncResult *res, GObject *obj,
     GNode *child;
     gchar mbid [NAME_MAX_SIZE];
     int depth;
+    GError *error;
 
     entity_view = ET_MB_ENTITY_VIEW (g_async_result_get_user_data (G_ASYNC_RESULT (res)));
     priv = ET_MB_ENTITY_VIEW_GET_PRIVATE (entity_view);
@@ -460,10 +470,17 @@ search_in_levels_thread_func (GSimpleAsyncResult *res, GObject *obj,
     {
         mb5_release_get_id (((EtMbEntity *)child->data)->entity, mbid, sizeof (mbid));
     }
-    
-    et_musicbrainz_search_in_entity (((EtMbEntity *)child->data)->type + 1,
-                                     ((EtMbEntity *)child->data)->type, mbid,
-                                     child);
+
+    error = NULL;
+
+    if (!et_musicbrainz_search_in_entity (((EtMbEntity *)child->data)->type + 1,
+                                          ((EtMbEntity *)child->data)->type, mbid,
+                                          child, &error))
+    {
+        g_simple_async_report_gerror_in_idle (NULL,
+                                              mb5_search_error_callback,
+                                              NULL, error);
+    }
 }
 
 /*
@@ -482,7 +499,8 @@ tree_view_row_activated (GtkTreeView *tree_view, GtkTreePath *path,
     /* TODO: Add Cancellable object */
     /* TODO: Use GSimpleAsyncResult with GError */
     /* TODO: Display Status Bar messages */
-    async_result = g_simple_async_result_new (NULL, search_in_levels_callback, 
+    async_result = g_simple_async_result_new (NULL,
+                                              search_in_levels_callback,
                                               user_data,
                                               tree_view_row_activated);
     g_simple_async_result_run_in_thread (async_result,
@@ -565,6 +583,8 @@ et_mb_entity_view_set_tree_root (EtMbEntityView *entity_view, GNode *treeRoot)
         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (btn), TRUE);
         gtk_widget_show_all (priv->bread_crumb_box);
         show_data_in_entity_view (entity_view);
+        g_signal_connect (G_OBJECT (btn), "clicked",
+                          G_CALLBACK (toggle_button_clicked), entity_view);
     }
 }
 
diff --git a/src/musicbrainz_dialog.c b/src/musicbrainz_dialog.c
index 4db418b..51b31d8 100644
--- a/src/musicbrainz_dialog.c
+++ b/src/musicbrainz_dialog.c
@@ -34,9 +34,6 @@
  * Declaration *
  ***************/
 
-static GtkBuilder *builder;
-static GtkWidget *mbDialog;
-static GtkWidget *entityView;
 static GNode *mb_tree_root;
 static GSimpleAsyncResult *async_result;
 
@@ -61,6 +58,21 @@ manual_search_callback (GObject *source, GAsyncResult *res,
     g_object_unref (res);
 }
 
+void
+mb5_search_error_callback (GObject *source, GAsyncResult *res,
+                              gpointer user_data)
+{
+    GError *dest;
+    dest = NULL;
+    g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res),
+                                           &dest);
+    Log_Print (LOG_ERROR,
+               _("Error searching MusicBrainz Database '%s'"), dest->message);
+    gtk_statusbar_push (GTK_STATUSBAR (gtk_builder_get_object (builder, "statusbar")),
+                        0, dest->message);
+    g_error_free (dest);
+}
+
 /*
  * manual_search_thread_func:
  * @res: GSimpleAsyncResult
@@ -73,17 +85,26 @@ static void
 manual_search_thread_func (GSimpleAsyncResult *res, GObject *obj,
                            GCancellable *cancellable)
 {
+    /* TODO: Call GTK+ functions from main thread */
     GtkWidget *cb_manual_search;
     GtkWidget *cb_manual_search_in;
     int type;
-
+    GError *error;
+    error = NULL;
+   
     cb_manual_search = GTK_WIDGET (gtk_builder_get_object (builder,
                                                            "cbManualSearch"));
     cb_manual_search_in = GTK_WIDGET (gtk_builder_get_object (builder,
                                                               "cbManualSearchIn"));
     type = gtk_combo_box_get_active (GTK_COMBO_BOX (cb_manual_search_in));
-    et_musicbrainz_search (gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (cb_manual_search)),
-                           type, mb_tree_root);
+
+    if (!et_musicbrainz_search (gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (cb_manual_search)),
+                                type, mb_tree_root, &error))
+    {
+        g_simple_async_report_gerror_in_idle (NULL,
+                                              mb5_search_error_callback,
+                                              NULL, error);
+    }
 }
 
 /*
@@ -102,6 +123,7 @@ btn_manual_find_clicked (GtkWidget *btn, gpointer user_data)
         mb_tree_root = g_node_new (NULL);
     }
 
+    cancellable = g_cancellable_new ();
     /* TODO: Add Cancellable object */
     /* TODO: Use GSimpleAsyncResult with GError */
     /* TODO: Display Status Bar messages */
@@ -120,15 +142,25 @@ void
 et_open_musicbrainz_dialog ()
 {
     GtkWidget *cb_manual_search_in;
+    GError *error;
 
-    mb_tree_root = g_node_new (NULL);
-    entityView = et_mb_entity_view_new ();
     builder = gtk_builder_new ();
-    /* TODO: Check the error. */
-    gtk_builder_add_from_resource (builder,
-                                   "/org/gnome/EasyTAG/musicbrainz_dialog.ui",
-                                   NULL);
+    error = NULL;
 
+    if (!gtk_builder_add_from_resource (builder,
+                                        "/org/gnome/EasyTAG/musicbrainz_dialog.ui",
+                                        &error))
+    {
+        Log_Print (LOG_ERROR,
+                   _("Error loading MusicBrainz Search Dialog '%s'"),
+                   error->message);
+        g_error_free (error);
+        g_object_unref (G_OBJECT (builder));
+        return;
+    }
+
+    mb_tree_root = g_node_new (NULL);
+    entityView = et_mb_entity_view_new ();
     mbDialog = GTK_WIDGET (gtk_builder_get_object (builder, "mbDialog"));
     gtk_box_pack_start (GTK_BOX (gtk_builder_get_object (builder, "centralBox")),
                         entityView, TRUE, TRUE, 2);
diff --git a/src/musicbrainz_dialog.h b/src/musicbrainz_dialog.h
index 32e5cad..653680e 100644
--- a/src/musicbrainz_dialog.h
+++ b/src/musicbrainz_dialog.h
@@ -21,11 +21,21 @@
 #ifndef __MUSICBRAINZ_DIALOG_H__
 #define __MUSICBRAINZ_DIALOG_H__
 
+/****************
+ * Declarations *
+ ****************/
+
+GtkBuilder *builder;
+GtkWidget *mbDialog;
+GtkWidget *entityView;
+
 /**************
  * Prototypes *
  **************/
 
 void
 et_open_musicbrainz_dialog (void);
-
+void
+mb5_search_error_callback (GObject *source, GAsyncResult *res,
+                           gpointer user_data);
 #endif /* __MUSICBRAINZ_DIALOG_H__ */


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