[recipes/todoist-2: 2/3] Send ingredients to todoist



commit 292d006b9fce989d0f011af9a7061c923408b218
Author: Ekta Nandwani <mailnandwaniekta gmail com>
Date:   Wed Jul 19 07:52:58 2017 +0530

    Send ingredients to todoist

 meson.build                        |    2 +
 src/gr-ingredients-exporter.c      |  472 ++++++++++++++++++++++++++++++------
 src/gr-ingredients-exporter.h      |    1 +
 src/gr-shopping-page.c             |    6 +-
 src/gr-shopping-page.h             |    2 +
 src/ingredients-exporter-dialog.ui |    1 +
 6 files changed, 404 insertions(+), 80 deletions(-)
---
diff --git a/meson.build b/meson.build
index 1a7535f..432a672 100644
--- a/meson.build
+++ b/meson.build
@@ -83,6 +83,8 @@ deps = [ dependency('gtk+-3.0', version : '>=3.22'),
          dependency('gmodule-export-2.0'),
          dependency('libsoup-2.4'),
          dependency('goa-1.0'),
+         dependency('rest-0.7'),
+         dependency('json-glib-1.0'),
          autoar_dep,
          gspell_dep,
          canberra_dep,
diff --git a/src/gr-ingredients-exporter.c b/src/gr-ingredients-exporter.c
index 1cfbf7c..0e9bce7 100644
--- a/src/gr-ingredients-exporter.c
+++ b/src/gr-ingredients-exporter.c
@@ -25,14 +25,28 @@
 #include <glib/gstdio.h>
 #include <gtk/gtk.h>
 #include <goa/goa.h>
+#include <rest/oauth2-proxy.h>
+#include <json-glib/json-glib.h>
 
 #include "gr-ingredients-exporter.h"
+#include "gr-recipe-store.h"
+#include "gr-shopping-page.h"
+
+#define TODOIST_URL "https://todoist.com/API/v7/sync";
+
+static void
+get_project_id (GrIngredientsExporter *exporter);
 
  struct _GrIngredientsExporter
 {
         GObject parent_instance;
         GtkWindow *window;
 
+        gchar *access_token;
+        GoaObject *account_object;
+        gchar *sync_token;
+        glong project_id;
+
         GtkWidget *export_button;
         GtkWidget *cancel_button;
         GtkWidget *back_button;        
@@ -42,6 +56,11 @@
         GtkWidget *dialog_stack;
         GtkWidget *header_start_stack;
         GtkWidget *header;
+        GtkWidget *providers_list;
+        GtkWidget *accounts_list;
+        GtkWidget *account_row_selected;
+
+        GList *ingredients;
 };
 
 
@@ -82,33 +101,158 @@ gr_ingredients_exporter_new (GtkWindow *parent)
 }
 
 static void
+get_ingredients_list(GrIngredientsExporter *exporter)
+{
+        GtkWidget *shopping_page;
+
+        shopping_page = gr_shopping_page_new ();
+        gr_shopping_page_populate (GR_SHOPPING_PAGE(shopping_page));
+        exporter->ingredients = get_ingredients (GR_SHOPPING_PAGE(shopping_page));
+       g_print("inside get_ingredients_list\n");
+}
+
+static void
 switch_dialog_contents (GrIngredientsExporter *exporter)
 {
-       if (gtk_stack_get_visible_child (GTK_STACK (exporter->dialog_stack)) == exporter->accounts_box)
-       {
-               if (!exporter->providers_box)
-                       g_print("providers_box empty");
-               gtk_widget_set_visible (exporter->export_button, FALSE);
-               gtk_stack_set_visible_child_name (GTK_STACK (exporter->dialog_stack), "providers_box");
-               gtk_stack_set_visible_child_name (GTK_STACK (exporter->header_start_stack), "back");
-               gtk_header_bar_set_title (GTK_HEADER_BAR (exporter->header), "Add Account");
-       }
-       else
-       // if (gtk_stack_get_visible_child (GTK_STACK (exporter->dialog_stack)) == exporter->providers_box)
-       {
-               gtk_widget_set_visible (exporter->export_button, TRUE);
-               gtk_stack_set_visible_child (GTK_STACK (exporter->dialog_stack), exporter->accounts_box);
-               gtk_stack_set_visible_child_name (GTK_STACK (exporter->header_start_stack), "cancel_button");
-               gtk_header_bar_set_title (GTK_HEADER_BAR (exporter->header), "Export Ingredients");
-       }
-       //gtk_widget_set_visible (exporter->accounts_box, FALSE);
-       
+               if (gtk_stack_get_visible_child (GTK_STACK (exporter->dialog_stack)) == 
exporter->accounts_box)
+               {
+                       if (!exporter->providers_box)
+                               g_print("providers_box empty");
+                       gtk_widget_set_visible (exporter->export_button, FALSE);
+                       gtk_stack_set_visible_child_name (GTK_STACK (exporter->dialog_stack), 
"providers_box");
+                       gtk_stack_set_visible_child_name (GTK_STACK (exporter->header_start_stack), "back");
+                       gtk_header_bar_set_title (GTK_HEADER_BAR (exporter->header), "Add Account");
+               }
+               else
+               {
+                       gtk_widget_set_visible (exporter->export_button, TRUE);
+                       gtk_stack_set_visible_child (GTK_STACK (exporter->dialog_stack), 
exporter->accounts_box);
+                       gtk_stack_set_visible_child_name (GTK_STACK (exporter->header_start_stack), 
"cancel_button");
+                       gtk_header_bar_set_title (GTK_HEADER_BAR (exporter->header), "Export Ingredients");
+               }
+}
+static void
+export_shopping_list_callback (RestProxyCall *call, GError *error, GObject *obj, GrIngredientsExporter 
*exporter)
+{
+               JsonObject *object;
+               JsonParser *parser;
+               GError *parse_error;
+               const gchar *payload;
+               guint status_code;
+               gsize payload_length;
+               gchar *sync_token;
+               GList *lists;
+               GList *l;
+
+               g_print("reaches do_something_here\n");
+               parse_error = NULL;
+               status_code = rest_proxy_call_get_status_code (call);
+               parser = json_parser_new ();
+
+               if (status_code != 200)
+               {
+                       g_print("status code %d", status_code);
+                   goto out;
+               }
+
+               payload = rest_proxy_call_get_payload (call);
+               payload_length = rest_proxy_call_get_payload_length (call);
+
+               if (!json_parser_load_from_data (parser, payload, payload_length, &parse_error))
+               {
+                   g_clear_error (&parse_error);
+                   goto out;
+               }
+
+               object = json_node_dup_object (json_parser_get_root (parser));
+
+               if (!object)
+               {
+                       g_print("No Data found");
+               }
+               sync_token = json_object_get_string_member (object, "sync_token");
+               g_print("%s",sync_token);
+               exporter->sync_token;
+
+               json_object_unref (object);
+
+               out:
+                 g_object_unref (parser);
 }
 
+
+
 static void
-export_shopping_list (GtkLabel *label, const char *uri, GrIngredientsExporter *exporter)
+export_shopping_list (GrIngredientsExporter *exporter)
 {
-       g_print ("export_shopping_list\n");
+       
+               GError *error;
+           JsonObject *params;
+           JsonObject *project;
+           params = json_object_new ();
+           project = json_object_new ();
+           GList *l;
+           RestProxy *proxy;
+               RestProxyCall *call;
+               GString *commands;
+               commands = g_string_new ("");
+               error = NULL;
+               GString *commands_arg;
+
+
+           json_object_set_string_member (project, "type", "project_add");
+           json_object_set_string_member (project, "args", "{\"name\": \"Project4\"}");
+
+           get_ingredients_list(exporter);
+
+           for (l = exporter->ingredients; l != NULL; l = l->next)
+           {
+               GString *s;
+
+               ShoppingListItem *item = l->data;
+               s = g_string_new ("");
+               g_string_append_printf (s, "%s %s", item->amount, item->name);
+               g_print ("appending item");
+               g_print("%s\n",s->str);
+               gchar *uuid = g_uuid_string_random();
+               gchar *temp_id = g_uuid_string_random();
+
+               g_string_append_printf (commands, "{\"type\": \"item_add\", 
\"temp_id\":\"%s\",\"uuid\":\"%s\", "
+                                    "\"args\":{\"content\":\"%s\",\"project_id\":%ld}},",
+                                    temp_id, uuid,
+                                    s->str, exporter->project_id);
+               }
+               g_print("exits the loop");
+               g_print("%d",commands->len);
+               commands = g_string_truncate (commands, commands->len-1);
+               commands_arg = g_string_new("[");
+               g_string_append_printf (commands_arg, "%s]", commands->str);
+
+               
+               proxy = rest_proxy_new ("https://todoist.com/API/v7/sync";, FALSE);
+           call = rest_proxy_new_call (proxy);
+           rest_proxy_call_set_method (call, "POST");  
+           rest_proxy_call_add_header (call, "content-type", "application/x-www-form-urlencoded");
+           rest_proxy_call_add_param (call, "token", exporter->access_token);
+
+           if(!exporter->sync_token)
+               rest_proxy_call_add_param (call, "sync_token", "\'*\'");
+           else
+               rest_proxy_call_add_param (call, "sync_token", exporter->sync_token);
+
+           rest_proxy_call_add_param (call, "commands", commands_arg->str);
+
+               if (!rest_proxy_call_async (call, (RestProxyCallAsyncCallback) export_shopping_list_callback,
+                                                                       NULL,
+                                               exporter,
+                                               &error))
+               {
+                     g_print("calling async failed\n");
+           }
+
+           g_object_unref (proxy);
+           g_object_unref (call);
+
 }
 
 static void
@@ -117,6 +261,228 @@ cancel_export (GrIngredientsExporter *exporter)
        g_print ("cancel_export\n");
 }
 
+static GtkWidget *
+get_selected_account (GtkListBox *list, GrIngredientsExporter *exporter)
+{
+       g_print("get_selected_account\n");
+
+       exporter->account_row_selected = GTK_WIDGET (gtk_list_box_get_selected_row (list));
+}
+
+static gboolean
+get_todoist_account(GrIngredientsExporter *exporter)
+{
+
+                                   GoaClient *client;
+           GList *accounts, *l;
+           GoaAccount *account;
+           GError *error;
+
+                           client = goa_client_new_sync (NULL, &error);
+           
+           if (!client)
+           {
+               g_error ("Could not create GoaClient: %s", error->message);
+               return;
+               }
+
+               accounts = goa_client_get_accounts (client);
+               for (l = accounts; l != NULL; l = l->next)
+               {
+               const gchar *provider_type;
+
+               account = goa_object_get_account (GOA_OBJECT (l->data));
+                       provider_type = goa_account_get_provider_name (account);
+                       g_print("%s",provider_type);
+
+                       if (g_strcmp0 (provider_type, "Todoist") == 0)
+                   {   
+                       exporter->account_object = GOA_OBJECT(l->data);
+                       g_print("provider type %s \n", goa_account_get_provider_type(account));
+                           return TRUE;
+                       }
+                   else
+                       return FALSE;
+                       
+               }
+}
+
+static void get_access_token (GrIngredientsExporter *exporter)
+{
+
+
+           GoaObject *account_object;
+           gchar *access_token;
+           GoaOAuth2Based *oauth2 = NULL;
+           GError *error;
+
+
+
+               error = NULL;
+       oauth2 = goa_object_get_oauth2_based (GOA_OBJECT (exporter->account_object));
+
+       if (!goa_oauth2_based_call_get_access_token_sync (oauth2, &access_token, NULL, NULL, &error))
+    {
+       g_print("access token not found!");
+    }
+
+    if (exporter->todoist_row == exporter->account_row_selected)
+    {
+       g_print ("export the list here\n");
+    }
+    exporter->access_token = access_token;
+    g_print("%s",access_token);
+}
+
+static void
+get_project_id (GrIngredientsExporter *exporter)
+{
+               RestProxy *proxy;
+               RestProxyCall *call;
+               GError *error;
+           JsonObject *params;
+           JsonObject *project;
+           params = json_object_new ();
+           project = json_object_new ();
+
+
+           proxy = rest_proxy_new (TODOIST_URL, FALSE);
+           call = rest_proxy_new_call (proxy);
+           rest_proxy_call_set_method (call, "POST");  
+           rest_proxy_call_add_header (call, "content-type", "application/x-www-form-urlencoded");
+           rest_proxy_call_add_param (call, "token", exporter->access_token);
+           if(!exporter->sync_token)
+               rest_proxy_call_add_param (call, "sync_token", "\'*\'");
+           else
+               rest_proxy_call_add_param (call, "sync_token", exporter->sync_token);
+           rest_proxy_call_add_param (call, "resource_types", "[\"projects\"]");
+
+           if (!rest_proxy_call_sync (call,
+                                     &error))
+
+           {
+             g_clear_error (&error);
+
+           }
+
+           g_object_unref(proxy);
+           JsonObject *object;
+               JsonParser *parser;
+               GError *parse_error;
+               const gchar *payload;
+               guint status_code;
+               gsize payload_length;
+               gchar *sync_token;
+               GList *lists;
+               GList *l;
+               JsonArray *projects;
+               RestProxyCall *call2;
+
+               parse_error = NULL;
+               status_code = rest_proxy_call_get_status_code (call);
+               parser = json_parser_new ();
+
+               if (status_code != 200)
+               {
+                   g_print("status code %d", status_code);
+
+               }
+
+               payload = rest_proxy_call_get_payload (call);
+               payload_length = rest_proxy_call_get_payload_length (call);
+
+               if (!json_parser_load_from_data (parser, payload, payload_length, &parse_error))
+               {
+                   g_clear_error (&parse_error);
+               }
+
+               object = json_node_dup_object (json_parser_get_root (parser));
+               if (!object)
+                       g_print("No Data found");
+
+               projects = json_object_get_array_member (object, "projects");
+
+               lists = json_array_get_elements (projects);
+
+               for (l = lists; l != NULL; l = l->next)
+               {
+                   JsonObject *object;
+                    
+                   const gchar *name;
+                   double id;
+                   
+                   object = json_node_get_object (l->data);
+
+                   name = json_object_get_string_member (object, "name");
+                   g_print("%s" , name);
+                   if (strcmp (name, "Shopping List from Recipes") == 0)
+                   {
+                       id = json_object_get_double_member (object, "id");
+                       exporter->project_id  = (glong)malloc(sizeof(glong));
+                       g_print ("size of project_id %d" , sizeof(exporter->project_id));
+                       (exporter->project_id) = (glong) id;
+                       g_print("id : %ld\n",exporter->project_id);
+                       goto export;
+                   }
+               }
+               
+               if (exporter->project_id == NULL)
+               {
+                       gchar *uuid = g_uuid_string_random();
+                       gchar *temp_id = g_uuid_string_random();
+                       guint status_code2;
+                       GString *project_add_commands;
+                       project_add_commands = g_string_new ("");
+                       g_print("inside the loop to add project_id");
+                       proxy = rest_proxy_new (TODOIST_URL, FALSE);
+                   call2 = rest_proxy_new_call (proxy);
+                   rest_proxy_call_set_method (call2, "POST"); 
+                   rest_proxy_call_add_header (call2, "content-type", "application/x-www-form-urlencoded");
+                   rest_proxy_call_add_param (call2, "token", exporter->access_token);
+                   if(!exporter->sync_token)
+                       rest_proxy_call_add_param (call2, "sync_token", "\'*\'");
+                   else
+                       rest_proxy_call_add_param (call2, "sync_token", exporter->sync_token);
+
+                   g_string_append_printf (project_add_commands, "[{\"type\": \"project_add\", 
\"temp_id\":\"%s\",\"uuid\":\"%s\", "
+                             "\"args\":{\"name\":\"Shopping List from Recipes\"}}]",
+                             temp_id, uuid);
+
+
+                   rest_proxy_call_add_param (call2, "commands",project_add_commands->str);
+
+                   if (!rest_proxy_call_sync (call2,
+                                     &error))
+                   {
+                     g_clear_error (&error);
+
+                   }
+                   status_code2 = rest_proxy_call_get_status_code (call2);
+                               if (status_code2 != 200)
+                       {
+                       g_print("status code %d", status_code);
+                       }
+                       get_project_id(exporter);
+               }
+
+               export:
+               if (exporter->project_id)
+               {
+                       export_shopping_list (exporter);
+               }
+
+} 
+
+static void
+initialize_export (GrIngredientsExporter *exporter) {
+
+       get_access_token (exporter);
+       if (exporter->project_id == NULL)
+       {
+               get_project_id (exporter);
+       }
+}
+
 
 static void
 show_export_dialog (GrIngredientsExporter *exporter)
@@ -139,66 +505,19 @@ show_export_dialog (GrIngredientsExporter *exporter)
         exporter->dialog_stack = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_stack"));
         exporter->header_start_stack = GTK_WIDGET (gtk_builder_get_object (builder, "header_start_stack"));
         exporter->header =  GTK_WIDGET (gtk_builder_get_object (builder, "header"));
+        exporter->providers_list =  GTK_WIDGET (gtk_builder_get_object (builder, "providers_list"));
+        exporter->accounts_list =  GTK_WIDGET (gtk_builder_get_object (builder, "accounts_list"));
 
         g_signal_connect_swapped (add_service, "activate-link", G_CALLBACK (switch_dialog_contents), 
exporter);
         g_signal_connect_swapped (exporter->back_button, "clicked", G_CALLBACK (switch_dialog_contents), 
exporter);
-        g_signal_connect (exporter->export_button, "clicked", G_CALLBACK (export_shopping_list), exporter);
+        g_signal_connect_swapped (exporter->export_button, "clicked", G_CALLBACK (initialize_export), 
exporter);
         g_signal_connect (exporter->cancel_button, "clicked", G_CALLBACK (cancel_export), exporter);
+        g_signal_connect (exporter->accounts_list, "selected-rows-changed", G_CALLBACK 
(get_selected_account), exporter);
         
-
-
-        GoaClient *client;
-           GList *accounts, *l;
-           GoaAccount *account;
-           GError *error;
-
-           client = goa_client_new_sync (NULL, &error);
-           
-           if (!client)
-           {
-                       g_error ("Could not create GoaClient: %s", error->message);
-                       return;
-               }
-
-               accounts = goa_client_get_accounts (client);
-               for (l = accounts; l != NULL; l = l->next)
-               {
-                       GoaOAuth2Based *oauth2 = NULL;
-
-                       account = goa_object_get_account (GOA_OBJECT (l->data));
-                           if (strcmp (goa_account_get_provider_name (account), "Todoist"))
-                           {
-                               gtk_widget_set_visible (exporter->todoist_row, TRUE);
-                           }
-                           g_print ("%s at %s (%s)\n",
-                                    goa_account_get_presentation_identity (account),
-                                    goa_account_get_provider_name (account),
-                                    goa_account_get_provider_type (account));
-                           oauth2 = goa_object_get_oauth2_based (GOA_OBJECT (l->data));
-                       if (oauth2)
-                       {
-                                       gchar *access_token;
-                                       if (goa_oauth2_based_call_get_access_token_sync (oauth2,
-                                                                                      &access_token,
-                                                                                      NULL,
-                                                                                      NULL,
-                                                                                      NULL))
-                                       {
-                                       g_print ("\tAccessToken: %s\n", access_token);
-                                       g_free (access_token);
-                                       }
-                                       g_print ("\tClientId: %s\n\tClientSecret: %s\n",
-                               goa_oauth2_based_get_client_id (oauth2),
-                               goa_oauth2_based_get_client_secret (oauth2));
-                       }
-                       g_clear_object (&oauth2);
-               }
-
-        //GtkWidget *list;
-        //gtk_widget_set_visible (exporter->todoist_row, TRUE);
-
-        //gtk_builder_add_callback_symbol (GtkBuilder *builder, const gchar *callback_name,
-        //                         GCallback callback_symbol);
+        if (get_todoist_account (exporter))
+        {
+               gtk_widget_set_visible (exporter->todoist_row, TRUE);
+        }
 
         gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (exporter->window));
         gtk_widget_show (dialog);
@@ -207,6 +526,5 @@ show_export_dialog (GrIngredientsExporter *exporter)
 void
 gr_ingredients_exporter_export (GrIngredientsExporter *exporter)
 {
-        // check_todoist_present(exporter);
         show_export_dialog (exporter);
 }
diff --git a/src/gr-ingredients-exporter.h b/src/gr-ingredients-exporter.h
index 3de3ec6..6c83d54 100644
--- a/src/gr-ingredients-exporter.h
+++ b/src/gr-ingredients-exporter.h
@@ -22,6 +22,7 @@
 
 #include <gtk/gtk.h>
 #include "gr-recipe.h"
+#include "gr-shopping-list-printer.h"
 
 G_BEGIN_DECLS
 
diff --git a/src/gr-shopping-page.c b/src/gr-shopping-page.c
index e30888d..d536502 100644
--- a/src/gr-shopping-page.c
+++ b/src/gr-shopping-page.c
@@ -625,7 +625,7 @@ clear_list (GrShoppingPage *page)
         gr_window_go_back (GR_WINDOW (window));
 }
 
-static GList *
+GList *
 get_recipes (GrShoppingPage *page)
 {
         GList *children, *l, *recipes;
@@ -644,7 +644,7 @@ get_recipes (GrShoppingPage *page)
         return recipes;
 }
 
-static GList *
+GList *
 get_ingredients (GrShoppingPage *page)
 {
         GList *children, *l, *ingredients;
@@ -781,7 +781,7 @@ mail_done (GObject      *source,
 static void
 open_export_shopping_list_dialog (GrShoppingPage *page)
 {
-    g_print("inside share");
+    g_print("inside share\n");
      if (!page->exporter) {
                 GtkWidget *window;
 
diff --git a/src/gr-shopping-page.h b/src/gr-shopping-page.h
index 6992d63..987f0ec 100644
--- a/src/gr-shopping-page.h
+++ b/src/gr-shopping-page.h
@@ -32,6 +32,8 @@ G_DECLARE_FINAL_TYPE (GrShoppingPage, gr_shopping_page, GR, SHOPPING_PAGE, GtkBo
 
 GtkWidget      *gr_shopping_page_new      (void);
 
+GList * get_ingredients (GrShoppingPage *page);
+
 void            gr_shopping_page_populate (GrShoppingPage *self);
 
 G_END_DECLS
diff --git a/src/ingredients-exporter-dialog.ui b/src/ingredients-exporter-dialog.ui
index 775a2ad..cb50332 100644
--- a/src/ingredients-exporter-dialog.ui
+++ b/src/ingredients-exporter-dialog.ui
@@ -171,6 +171,7 @@
                     <object class="GtkListBox" id="providers_list">
                       <property name="selection_mode">single</property>
                       <property name="visible">1</property>
+                      <signal name="selected-rows-changed" handler="row_changed"/>
                       <style>
                             <class name="frame"/>
                       </style>


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