aboutsummaryrefslogtreecommitdiffstats
path: root/libempathy/empathy-ft-handler.c
diff options
context:
space:
mode:
Diffstat (limited to 'libempathy/empathy-ft-handler.c')
-rw-r--r--libempathy/empathy-ft-handler.c194
1 files changed, 149 insertions, 45 deletions
diff --git a/libempathy/empathy-ft-handler.c b/libempathy/empathy-ft-handler.c
index dfaeceabf..c1365fb86 100644
--- a/libempathy/empathy-ft-handler.c
+++ b/libempathy/empathy-ft-handler.c
@@ -74,6 +74,12 @@ typedef struct {
gssize total_read;
} HashingData;
+typedef struct {
+ EmpathyFTHandlerReadyCallback callback;
+ gpointer user_data;
+ EmpathyFTHandler *handler;
+} CallbacksData;
+
/* private data */
typedef struct {
gboolean dispose_run;
@@ -81,6 +87,15 @@ typedef struct {
GFile *gfile;
EmpathyTpFile *tpfile;
GCancellable *cancellable;
+
+ /* transfer properties */
+ gchar *content_type;
+ gchar *filename;
+ gchar *description;
+ guint64 total_bytes;
+ guint64 transferred_bytes;
+ gchar *content_hash;
+ EmpFileHashType content_hash_type;
} EmpathyFTHandlerPriv;
static guint signals[LAST_SIGNAL] = { 0 };
@@ -639,9 +654,47 @@ ft_handler_read_async_cb (GObject *source,
}
static void
+ft_handler_complete_request (EmpathyFTHandler *handler)
+{
+ EmpathyFTHandlerPriv *priv = GET_PRIV (handler);
+ GError *myerr = NULL;
+
+ g_cancellable_set_error_if_cancelled (priv->cancellable, &myerr);
+
+ if (myerr == NULL)
+ {
+ if (error != NULL)
+ {
+ myerr = g_error_copy (error);
+ }
+ else
+ {
+ /* check if FT is allowed before firing up the I/O machinery */
+ if (!ft_handler_check_if_allowed (req_data->handler))
+ {
+ g_set_error_literal (&myerr, EMPATHY_FT_ERROR_QUARK,
+ EMPATHY_FT_ERROR_NOT_SUPPORTED,
+ _("File transfer not supported by remote contact"));
+ }
+ }
+ }
+
+ if (myerr != NULL)
+ {
+ g_signal_emit (req_data->handler, signals[TRANSFER_ERROR], 0, myerr);
+
+ request_data_free (req_data);
+ g_clear_error (&myerr);
+
+ return;
+ }
+
+}
+
+static void
ft_handler_gfile_ready_cb (GObject *source,
GAsyncResult *res,
- RequestData *req_data)
+ CallbacksData *cb_data)
{
GFileInfo *info;
GError *error = NULL;
@@ -652,9 +705,7 @@ ft_handler_gfile_ready_cb (GObject *source,
info = g_file_query_info_finish (req_data->gfile, res, &error);
if (error != NULL)
{
- g_signal_emit (req_data->handler, signals[TRANSFER_ERROR], 0, error);
-
- request_data_free (req_data);
+ /* TODO: error handling */
g_clear_error (&error);
return;
@@ -675,78 +726,131 @@ ft_handler_contact_ready_cb (EmpathyContact *contact,
gpointer user_data,
GObject *weak_object)
{
- RequestData *req_data = user_data;
- EmpathyFTHandlerPriv *priv = GET_PRIV (req_data->handler);
- GError *myerr = NULL;
+ CallbacksData *cb_data = user_data;
+ EmpathyFTHandlerPriv *priv = GET_PRIV (weak_object);
g_assert (priv->contact != NULL);
g_assert (priv->gfile != NULL);
DEBUG ("FT: contact is ready.");
- g_cancellable_set_error_if_cancelled (priv->cancellable, &myerr);
+ /* start collecting info about the file */
+ g_file_query_info_async (priv->gfile,
+ G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME ","
+ G_FILE_ATTRIBUTE_STANDARD_SIZE ","
+ G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE ","
+ G_FILE_ATTRIBUTE_TIME_MODIFIED,
+ G_FILE_QUERY_INFO_NONE, G_PRIORITY_DEFAULT,
+ NULL, (GAsyncReadyCallback) ft_handler_gfile_ready_cb,
+ cb_data);
+}
- if (myerr == NULL)
- {
- if (error != NULL)
- {
- myerr = g_error_copy (error);
- }
- else
- {
- /* check if FT is allowed before firing up the I/O machinery */
- if (!ft_handler_check_if_allowed (req_data->handler))
- {
- g_set_error_literal (&myerr, EMPATHY_FT_ERROR_QUARK,
- EMPATHY_FT_ERROR_NOT_SUPPORTED,
- _("File transfer not supported by remote contact"));
- }
- }
- }
+static void
+callbacks_data_free (gpointer user_data)
+{
+ CallbacksData *data = user_data;
- if (myerr != NULL)
- {
- g_signal_emit (req_data->handler, signals[TRANSFER_ERROR], 0, myerr);
+ g_object_unref (data->handler);
- request_data_free (req_data);
- g_clear_error (&myerr);
+ g_slice_free (CallbacksData, data);
+}
+
+static void
+channel_get_all_properties_cb (TpProxy *proxy,
+ GHashTable *properties,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ CallbacksData *cb_data = user_data;
+ EmpathyFTHandler *handler = EMPATHY_FT_HANDLER (weak_object);
+ EmpathyFTHandlerPriv *priv = GET_PRIV (handler);
+ if (error != NULL)
+ {
+ cb_data->callback (handler, error, cb_data->user_data);
return;
}
- /* start collecting info about the file */
- g_file_query_info_async (req_data->gfile,
- G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME ","
- G_FILE_ATTRIBUTE_STANDARD_SIZE ","
- G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE ","
- G_FILE_ATTRIBUTE_TIME_MODIFIED,
- G_FILE_QUERY_INFO_NONE, G_PRIORITY_DEFAULT,
- priv->cancellable, (GAsyncReadyCallback) ft_handler_gfile_ready_cb,
- req_data);
+ priv->total_bytes = g_value_get_uint64 (
+ g_hash_table_lookup (properties, "Size"));
+
+ priv->transferred_bytes = g_value_get_uint64 (
+ g_hash_table_lookup (properties, "TransferredBytes"));
+
+ priv->filename = g_value_dup_string (
+ g_hash_table_lookup (properties, "Filename"));
+
+ priv->content_hash = g_value_dup_string (
+ g_hash_table_lookup (properties, "ContentHash"));
+
+ priv->content_hash_type = g_value_get_uint (
+ g_hash_table_lookup (properties, "ContentHashType"));
+
+ priv->content_type = g_value_dup_string (
+ g_hash_table_lookup (properties, "ContentType"));
+
+ priv->description = g_value_dup_string (
+ g_hash_table_lookup (properties, "Description"));
+
+ g_hash_table_destroy (properties);
+
+ cb_data->callback (handler, NULL, cb_data->user_data);
}
/* public methods */
-EmpathyFTHandler*
+void
empathy_ft_handler_new_outgoing (EmpathyContact *contact,
- GFile *source)
+ GFile *source,
+ EmpathyFTHandlerReadyCallback callback,
+ gpointer user_data)
{
+ EmpathyFTHandler *handler;
+ CallbacksData *data;
+
g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
g_return_val_if_fail (G_IS_FILE (source), NULL);
- return g_object_new (EMPATHY_TYPE_FT_HANDLER,
+ handler = g_object_new (EMPATHY_TYPE_FT_HANDLER,
"contact", contact, "gfile", source, NULL);
+
+ data = g_slice_new0 (CallbacksData);
+ data->callback = callback;
+ data->user_data = user_data;
+ data->handler = g_object_ref (handler);
+
+ empathy_contact_call_when_ready (priv->contact,
+ EMPATHY_CONTACT_READY_HANDLE,
+ ft_handler_contact_ready_cb, data, NULL, G_OBJECT (handler));
}
-EmpathyFTHandler *
+void
empathy_ft_handler_new_incoming (EmpathyTpFile *tp_file,
- GFile *destination)
+ GFile *destination,
+ EmpathyFTHandlerReadyCallback callback,
+ gpointer user_data)
{
+ EmpathyFTHandler *handler;
+ TpChannel *channel;
+ CallbacksData *data;
+
g_return_val_if_fail (EMPATHY_IS_TP_FILE (tp_file), NULL);
g_return_val_if_fail (G_IS_FILE (destination), NULL);
- return g_object_new (EMPATHY_TYPE_FT_HANDLER,
+ handler = g_object_new (EMPATHY_TYPE_FT_HANDLER,
"tp-file", tp_file, "gfile", destination, NULL);
+
+ g_object_get (tp_file, "channel", &channel, NULL);
+
+ data = g_slice_new0 (CallbacksData);
+ data->callback = callback;
+ data->user_data = user_data;
+ data->handler = g_object_ref (handler);
+
+ tp_cli_dbus_properties_call_get_all (channel,
+ -1, EMP_IFACE_CHANNEL_TYPE_FILE_TRANSFER,
+ channel_get_all_properties_cb, data, callbacks_data_free, G_OBJECT (handler));
}
void