char *api_key;
char *shared_secret;
char *frob;
+ MilkAuthState state;
};
enum {
PROP_API_KEY = 1,
PROP_SHARED_SECRET,
+ PROP_STATE,
};
static MilkAuth *default_auth = NULL;
+MilkAuthState
+milk_auth_get_state (MilkAuth *auth)
+{
+ g_return_val_if_fail (auth, MILK_AUTH_STATE_DISCONNECTED);
+ g_return_val_if_fail (MILK_IS_AUTH (auth),
+ MILK_AUTH_STATE_DISCONNECTED);
+
+ return MILK_AUTH_PRIVATE (auth)->state;
+}
+
static void
milk_auth_get_property (GObject *object,
guint property_id,
g_value_set_string (value, priv->shared_secret);
break;
+ case PROP_STATE:
+ g_value_set_int (value, priv->state);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id,
pspec);
priv->shared_secret = g_value_dup_string (value);
break;
+ case PROP_STATE:
+ priv->state = g_value_get_int (value);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id,
pspec);
{
MilkAuthPrivate *priv;
-
GError *error = NULL;
gchar *auth_token;
gchar *username;
+ MilkAuthState previous_state;
priv = MILK_AUTH_PRIVATE (auth);
+ previous_state = priv->state;
auth_token = rtm_glib_auth_get_token (priv->rtm_glib, priv->frob,
&error);
if (error != NULL) {
- g_error ("%s", rtm_error_get_message (error));
- goto auth_response_cb_OUT;
+ g_warning ("%s", rtm_error_get_message (error));
+ goto auth_response_cb_error_OUT;
}
if (!rtm_glib_auth_check_token (priv->rtm_glib, auth_token, NULL)) {
- g_error ("auth_token not valid!\n");
+ g_warning ("auth_token not valid!\n");
goto auth_response_cb_error_OUT;
}
if (error != NULL) {
- g_error ("%s", rtm_error_get_message (error));
- goto auth_response_cb_OUT;
+ g_warning ("%s", rtm_error_get_message (error));
+ goto auth_response_cb_error_OUT;
}
username = rtm_glib_test_login (priv->rtm_glib, auth_token, &error);
g_free (auth_token);
if (error != NULL) {
- g_error ("%s", rtm_error_get_message (error));
- goto auth_response_cb_OUT;
+ g_warning ("%s", rtm_error_get_message (error));
+ goto auth_response_cb_error_OUT;
}
- /* FIXME: work this in where appropriate */
-#if 0
- glist = rtm_glib_tasks_get_list (priv->rtm_glib, NULL, NULL, NULL, &error);
- if (error != NULL) {
- g_error ("%s", rtm_error_get_message (error));
- }
- for (item = glist; item; item = g_list_next (item)) {
- task = (RtmTask *) item->data;
- g_print ("%s", rtm_task_to_string (task));
- }
- g_list_free (glist);
+ priv->state = MILK_AUTH_STATE_CONNECTED;
+ goto auth_response_cb_OUT;
- glist = rtm_glib_lists_get_list (priv->rtm_glib, &error);
- if (error != NULL) {
- g_error ("%s", rtm_error_get_message (error));
- goto auth_response_cb_OUT;
- }
- for (item = glist; item; item = g_list_next (item)) {
- rtm_list = (RtmList *) item->data;
- if (g_strcmp0 (rtm_list_get_name (rtm_list), "Sent") == 0) {
- list_id_sent = rtm_list_get_id (rtm_list);
+auth_response_cb_error_OUT:
+ priv->state = MILK_AUTH_STATE_DISCONNECTED;
+ /* FIXME: make it possible to re-try, etc. */
+ gtk_main_quit ();
+
+auth_response_cb_OUT:
+ if (priv->state != previous_state)
+ g_object_notify (G_OBJECT (auth), "state");
+
+ gtk_widget_destroy (dialog);
+}
+
+GList *
+milk_auth_get_tasks (MilkAuth *auth,
+ const char *last_sync,
+ GError **error)
+{
+ MilkAuthPrivate *priv;
+ GList *rtm_tasks;
+
+ g_return_val_if_fail (auth, NULL);
+ g_return_val_if_fail (MILK_IS_AUTH (auth), NULL);
+ g_return_val_if_fail (
+ milk_auth_get_state (auth) == MILK_AUTH_STATE_CONNECTED,
+ NULL);
+
+ priv = MILK_AUTH_PRIVATE (auth);
+
+ /* FIXME: cache this */
+ rtm_tasks = rtm_glib_tasks_get_list (priv->rtm_glib, NULL, NULL,
+ (char*) last_sync, error);
+
+ return rtm_tasks;
+}
+
+char*
+milk_auth_timeline_create (MilkAuth *auth,
+ GError **error)
+{
+ MilkAuthPrivate *priv;
+
+ g_return_val_if_fail (MILK_IS_AUTH (auth), NULL);
+
+ priv = MILK_AUTH_PRIVATE (auth);
+
+ return rtm_glib_timelines_create (priv->rtm_glib, error);
+}
+
+/* FIXME: we probably really want this to be async (but sequencable) */
+GList*
+milk_auth_tasks_add (MilkAuth *auth,
+ char *timeline,
+ GList *names)
+{
+ gboolean success = TRUE;
+ MilkAuthPrivate *priv;
+ GList *l;
+ GList *tasks = NULL;
+ GError *error = NULL;
+
+ g_return_val_if_fail (MILK_IS_AUTH (auth), NULL);
+ g_return_val_if_fail (names, NULL);
+
+ priv = MILK_AUTH_PRIVATE (auth);
+
+ for (l = names; l; l = l->next) {
+ RtmTask *task;
+
+ /* FIXME: cut this */
+ g_debug ("trying to send task with name '%s'", l->data);
+
+ /* XXX: this uses Smart Add parsing; make this user-settable? */
+ /* XXX: the cast to char* is actually a bug in the rtm-glib API
+ */
+ task = rtm_glib_tasks_add (priv->rtm_glib, timeline,
+ l->data, NULL, TRUE, &error);
+ if (task) {
+ /* FIXME: cut this */
+ g_debug (G_STRLOC ": added task with ID '%s'",
+ rtm_task_get_id (task));
+
+ tasks = g_list_prepend (tasks, task);
+ } else {
+ g_warning ("failed to add some tasks: %s",
+ error->message);
+ g_clear_error (&error);
}
- g_print ("%s", rtm_list_to_string (rtm_list));
}
- g_list_free (glist);
- timeline = rtm_glib_timelines_create (priv->rtm_glib, &error);
- if (error != NULL) {
- g_error ("%s", rtm_error_get_message (error));
- }
- g_print ("timeline: %s", timeline);
+ return tasks;
+}
- task = rtm_glib_tasks_add (priv->rtm_glib, timeline, "test-rtm-glib", NULL, FALSE, &error);
- if (error != NULL) {
- g_error ("%s", rtm_error_get_message (error));
- goto auth_response_cb_OUT;
- }
- if (task != NULL) {
- g_print ("First task added! task_id: %s\n", rtm_task_get_id (task));
- } else {
- g_print ("First task NOT added!\n");
- goto auth_response_cb_OUT;
+RtmTask*
+milk_auth_task_add (MilkAuth *auth,
+ char *timeline,
+ const char *name,
+ GError **error)
+{
+ MilkAuthPrivate *priv;
+
+ g_return_val_if_fail (MILK_IS_AUTH (auth), NULL);
+
+ priv = MILK_AUTH_PRIVATE (auth);
+
+ /* XXX: this uses Smart Add parsing; make this user-settable? */
+ /* XXX: the cast to char* is actually a bug in the rtm-glib API */
+ return rtm_glib_tasks_add (priv->rtm_glib, timeline, (char*) name, NULL,
+ TRUE, error);
+}
+
+/* FIXME: we probably really want this to be async (but sequencable) */
+GList*
+milk_auth_tasks_send_changes (MilkAuth *auth,
+ char *timeline,
+ GList *tasks)
+{
+ gboolean success = TRUE;
+ MilkAuthPrivate *priv;
+ GList *l;
+ GList *tasks_sent = NULL;
+ GError *error = NULL;
+
+ g_return_val_if_fail (MILK_IS_AUTH (auth), NULL);
+ g_return_val_if_fail (tasks, NULL);
+
+ priv = MILK_AUTH_PRIVATE (auth);
+
+ for (l = tasks; l; l = l->next) {
+ RtmTask *task = l->data;
+
+ GTimeVal *tv;
+
+ /* If any of these conditions fail, libsoup ends up exploding
+ * in a segfault (blindly de-reffing NULL); better to be safe
+ * than sorry */
+ if (!rtm_task_get_list_id (task)) {
+ g_warning (G_STRLOC ": task doesn't have a list ID; "
+ "skipping...");
+ continue;
+ }
+
+ if (!rtm_task_get_taskseries_id (task)) {
+ g_warning (G_STRLOC ": task doesn't have a taskseries "
+ "ID; skipping...");
+ continue;
+ }
+
+ if (!rtm_task_get_id (task)) {
+ g_warning (G_STRLOC ": task doesn't have an ID; "
+ "skipping...");
+ continue;
+ }
+
+ tv = rtm_task_get_due_date (task);
+ if (tv) {
+ char *due_str;
+ char *tid;
+
+ due_str = g_time_val_to_iso8601 (tv);
+
+ /* FIXME: cut this */
+ g_debug ("going to set due string: '%s'", due_str);
+
+ /* XXX: this uses Smart Add parsing; make this
+ * user-settable? */
+ /* XXX: the cast to char* is actually a bug in the
+ * rtm-glib API */
+ tid = rtm_glib_tasks_set_due_date (priv->rtm_glib, timeline,
+ task, due_str,
+ /* FIXME: set this appropriately */
+ FALSE,
+ FALSE, &error);
+
+ if (tid) {
+ /* FIXME: this should be a set, not a list --
+ * we'll add each task to the set if it's been
+ * changed since the last send */
+ tasks_sent = g_list_prepend (tasks_sent, task);
+ } else {
+ g_warning ("failed to add some tasks: %s",
+ error->message);
+ g_clear_error (&error);
+ }
+
+ g_free (tid);
+ }
+
+ /* FIXME: handle all the other attributes, not just the date */
}
-#endif
+ return tasks_sent;
+}
-auth_response_cb_OUT:
- gtk_widget_destroy (dialog);
+char*
+milk_auth_task_complete (MilkAuth *auth,
+ char *timeline,
+ RtmTask *task,
+ GError **error)
+{
+ MilkAuthPrivate *priv;
+
+ g_return_val_if_fail (MILK_IS_AUTH (auth), NULL);
+
+ priv = MILK_AUTH_PRIVATE (auth);
+
+ return rtm_glib_tasks_complete (priv->rtm_glib, timeline, task, error);
}
-void
-milk_auth_run_demo (MilkAuth *auth)
+char*
+milk_auth_task_delete (MilkAuth *auth,
+ char *timeline,
+ RtmTask *task,
+ GError **error)
{
MilkAuthPrivate *priv;
+ g_return_val_if_fail (MILK_IS_AUTH (auth), NULL);
+
+ priv = MILK_AUTH_PRIVATE (auth);
+
+ return rtm_glib_tasks_delete (priv->rtm_glib, timeline, task, error);
+}
+
+/* FIXME: why does this (or something above it) totally fail if we don't have a
+ * working Internet connection / resolv.conf is mangled? */
+/* FIXME: instead of this manual call, listen to the connection manager
+ * transitions -- see this:
+ * http://wiki.maemo.org/Documentation/Maemo_5_Developer_Guide/Using_Connectivity_Components/Maemo_Connectivity#Libconic_Usage
+ */
+void
+milk_auth_log_in (MilkAuth *auth)
+{
+ MilkAuthPrivate *priv;
GError *error = NULL;
gchar *url;
GtkDialog *dialog;
+ g_return_if_fail (auth);
+ g_return_if_fail (MILK_IS_AUTH (auth));
+
priv = MILK_AUTH_PRIVATE (auth);
if (rtm_glib_test_echo (priv->rtm_glib, &error)) {
auth);
}
-
static void
milk_auth_constructed (GObject *object)
{
RTM_SHARED_SECRET,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (object_class,
+ PROP_STATE,
+ g_param_spec_int
+ ("state",
+ "Authentication state",
+ "Authentication/connection state with the server.",
+ 0, (NUM_MILK_AUTH_STATES-1),
+ MILK_AUTH_STATE_DISCONNECTED,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
}
static void