Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use thumbnails for big images #23

Merged
merged 2 commits into from
Jan 3, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions matrix-api.c
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,48 @@ MatrixApiRequestData *matrix_api_download_file(MatrixConnectionData *conn,
return fetch_data;
}

/**
* Download a thumbnail for a file
* @param uri URI string in the form mxc://example.com/unique
*/
MatrixApiRequestData *matrix_api_download_thumb(MatrixConnectionData *conn,
const gchar *uri,
gsize max_size,
unsigned int width, unsigned int height, gboolean scale,
MatrixApiCallback callback,
MatrixApiErrorCallback error_callback,
MatrixApiBadResponseCallback bad_response_callback,
gpointer user_data)
{
GString *url;
MatrixApiRequestData *fetch_data;
char tmp[64];

/* Sanity check the uri - TODO: Add more sanity */
if (strncmp(uri, "mxc://", 6)) {
error_callback(conn, user_data, "bad media uri");
return NULL;
}
url = g_string_new(conn->homeserver);
g_string_append(url, "_matrix/media/r0/thumbnail/");
g_string_append(url, uri + 6); /* i.e. after the mxc:// */
sprintf(tmp, "?width=%u", width);
g_string_append(url, tmp);
sprintf(tmp, "&height=%u", height);
g_string_append(url, tmp);
g_string_append(url, scale ? "&method=scale": "&method=crop");

/* I'd like to validate the headers etc a bit before downloading the
* data (maybe using _handle_header_completed), also I'm not convinced
* purple always does sane things on over-size.
*/
fetch_data = matrix_api_start(url->str, "GET", NULL, conn, callback,
error_callback, bad_response_callback, user_data, max_size);
g_string_free(url, TRUE);

return fetch_data;
}

#if 0
MatrixApiRequestData *matrix_api_get_room_state(MatrixConnectionData *conn,
const gchar *room_id,
Expand Down
28 changes: 28 additions & 0 deletions matrix-api.h
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,34 @@ MatrixApiRequestData *matrix_api_download_file(MatrixConnectionData *conn,
MatrixApiBadResponseCallback bad_response_callback,
gpointer user_data);

/**
* Download a thumbnail for a file
*
* @param conn The connection with which to make the request
* @param uri The Matrix uri to fetch starting mxc://
* @param max_size A maximum size of file to receive.
* @param width Desired width; the server might not obey
* @param height Desired height; the server might not obey
* @param scale True to scale, false to crop
* @param callback Function to be called when the request completes
* @param error_callback Function to be called if there is an error making
* the request. If NULL, matrix_api_error will be
* used.
* @param bad_response_callback Function to be called if the API gives a non-200
* response. If NULL, matrix_api_bad_response will be
* used.
* @param user_data Opaque data to be passed to the callbacks
*
*/
MatrixApiRequestData *matrix_api_download_thumb(MatrixConnectionData *conn,
const gchar *uri,
gsize max_size,
unsigned int width, unsigned int height, gboolean scale,
MatrixApiCallback callback,
MatrixApiErrorCallback error_callback,
MatrixApiBadResponseCallback bad_response_callback,
gpointer user_data);

#if 0
/**
* Get the current state of a room
Expand Down
29 changes: 22 additions & 7 deletions matrix-room.c
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,7 @@ static gboolean _handle_incoming_image(PurpleConversation *conv,
MatrixConnectionData *conn = _get_connection_data_from_conversation(conv);
MatrixApiRequestData *fetch_data = NULL;
struct ReceiveImageData *rid;
gboolean use_thumb = FALSE;

const gchar *url;
JsonObject *json_info_object;
Expand All @@ -625,9 +626,7 @@ static gboolean _handle_incoming_image(PurpleConversation *conv,
/* OK, we've got some (optional) info on the image */
size = matrix_json_object_get_int_member(json_info_object, "size");
if (size > purple_max_image_size) {
purple_debug_info("matrixprpl", "image too large %" PRId64 "\n", size);
/* TODO: Switch to a thumbnail */
return FALSE;
use_thumb = TRUE;
}
mime_type = matrix_json_object_get_string_member(json_info_object,
"mimetype");
Expand All @@ -649,10 +648,26 @@ static gboolean _handle_incoming_image(PurpleConversation *conv,
rid->room_id = room_id;
rid->original_body = g_strdup(msg_body);

fetch_data = matrix_api_download_file(conn, url, purple_max_image_size,
_image_download_complete,
_image_download_error,
_image_download_bad_response, rid);
if (!use_thumb) {
fetch_data = matrix_api_download_file(conn, url,
purple_max_image_size,
_image_download_complete,
_image_download_error,
_image_download_bad_response, rid);
} else {
/* TODO: Configure the size of thumbnails, and provide
* a way for the user to get the full image if they want.
* 640x480 is a good a width as any and reasonably likely to
* fit in the byte size limit unless someone has a big long
* tall png.
*/
fetch_data = matrix_api_download_thumb(conn, url,
purple_max_image_size,
640, 480, TRUE, /* Scaled */
_image_download_complete,
_image_download_error,
_image_download_bad_response, rid);
}

purple_conversation_set_data(conv, PURPLE_CONV_DATA_ACTIVE_SEND,
fetch_data);
Expand Down