Load photo/video. Now works only with current DC.
This commit is contained in:
parent
78b5d205d7
commit
9565455d3f
5 changed files with 260 additions and 2 deletions
90
interface.c
90
interface.c
|
@ -68,6 +68,12 @@ char *commands[] = {
|
|||
"user_info",
|
||||
"fwd",
|
||||
"rename_chat",
|
||||
"load_photo",
|
||||
"view_photo",
|
||||
"load_video_thumb",
|
||||
"view_video_thumb",
|
||||
"load_video",
|
||||
"view_video",
|
||||
"show_license",
|
||||
0 };
|
||||
|
||||
|
@ -86,6 +92,12 @@ int commands_flags[] = {
|
|||
072,
|
||||
074,
|
||||
07,
|
||||
07,
|
||||
07,
|
||||
07,
|
||||
07,
|
||||
07,
|
||||
07,
|
||||
};
|
||||
|
||||
char *a = 0;
|
||||
|
@ -356,6 +368,84 @@ void interpreter (char *line UU) {
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if (!memcmp (line, "load_photo ", 10)) {
|
||||
char *q = line + 10;
|
||||
int len = 0;
|
||||
char *f = get_token (&q, &len);
|
||||
if (f) {
|
||||
int num = atoi (f);
|
||||
if (num > 0) {
|
||||
struct message *M = message_get (num);
|
||||
if (M && !M->service && M->media.type == (int)CODE_message_media_photo) {
|
||||
do_load_photo (&M->media.photo, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!memcmp (line, "view_photo ", 10)) {
|
||||
char *q = line + 10;
|
||||
int len = 0;
|
||||
char *f = get_token (&q, &len);
|
||||
if (f) {
|
||||
int num = atoi (f);
|
||||
if (num > 0) {
|
||||
struct message *M = message_get (num);
|
||||
if (M && !M->service && M->media.type == (int)CODE_message_media_photo) {
|
||||
do_load_photo (&M->media.photo, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!memcmp (line, "load_video_thumb ", 16)) {
|
||||
char *q = line + 16;
|
||||
int len = 0;
|
||||
char *f = get_token (&q, &len);
|
||||
if (f) {
|
||||
int num = atoi (f);
|
||||
if (num > 0) {
|
||||
struct message *M = message_get (num);
|
||||
if (M && !M->service && M->media.type == (int)CODE_message_media_video) {
|
||||
do_load_video_thumb (&M->media.video, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!memcmp (line, "view_video_thumb ", 16)) {
|
||||
char *q = line + 16;
|
||||
int len = 0;
|
||||
char *f = get_token (&q, &len);
|
||||
if (f) {
|
||||
int num = atoi (f);
|
||||
if (num > 0) {
|
||||
struct message *M = message_get (num);
|
||||
if (M && !M->service && M->media.type == (int)CODE_message_media_video) {
|
||||
do_load_video_thumb (&M->media.video, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!memcmp (line, "load_video ", 10)) {
|
||||
char *q = line + 10;
|
||||
int len = 0;
|
||||
char *f = get_token (&q, &len);
|
||||
if (f) {
|
||||
int num = atoi (f);
|
||||
if (num > 0) {
|
||||
struct message *M = message_get (num);
|
||||
if (M && !M->service && M->media.type == (int)CODE_message_media_video) {
|
||||
do_load_video (&M->media.video, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!memcmp (line, "view_video ", 10)) {
|
||||
char *q = line + 10;
|
||||
int len = 0;
|
||||
char *f = get_token (&q, &len);
|
||||
if (f) {
|
||||
int num = atoi (f);
|
||||
if (num > 0) {
|
||||
struct message *M = message_get (num);
|
||||
if (M && !M->service && M->media.type == (int)CODE_message_media_video) {
|
||||
do_load_video (&M->media.video, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!memcmp (line, "chat_info", 9)) {
|
||||
char *q = line + 10;
|
||||
int len;
|
||||
|
|
2
loop.c
2
loop.c
|
@ -244,7 +244,7 @@ int loop (void) {
|
|||
}
|
||||
|
||||
write_auth_file ();
|
||||
|
||||
|
||||
fflush (stdin);
|
||||
fflush (stdout);
|
||||
fflush (stderr);
|
||||
|
|
160
queries.c
160
queries.c
|
@ -36,6 +36,7 @@
|
|||
#include "structures.h"
|
||||
#include "interface.h"
|
||||
|
||||
char *get_downloads_directory (void);
|
||||
int verbosity;
|
||||
|
||||
#define QUERY_TIMEOUT 0.3
|
||||
|
@ -1059,3 +1060,162 @@ void do_get_user_list_info_silent (int num, int *list) {
|
|||
}
|
||||
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &user_list_info_silent_methods, 0);
|
||||
}
|
||||
|
||||
struct download {
|
||||
int offset;
|
||||
int size;
|
||||
long long volume;
|
||||
long long secret;
|
||||
long long access_hash;
|
||||
int local_id;
|
||||
int dc;
|
||||
int next;
|
||||
int fd;
|
||||
char *name;
|
||||
long long id;
|
||||
};
|
||||
|
||||
|
||||
void end_load (struct download *D) {
|
||||
close (D->fd);
|
||||
if (D->next == 1) {
|
||||
logprintf ("Done: %s\n", D->name);
|
||||
} else if (D->next == 2) {
|
||||
static char buf[1000];
|
||||
sprintf (buf, "xdg-open %s", D->name);
|
||||
int x = system (buf);
|
||||
if (x < 0) {
|
||||
logprintf ("Can not open image viewer: %m\n");
|
||||
logprintf ("Image is at %s\n", D->name);
|
||||
}
|
||||
}
|
||||
free (D->name);
|
||||
free (D);
|
||||
}
|
||||
|
||||
void load_next_part (struct download *D);
|
||||
int download_on_answer (struct query *q) {
|
||||
assert (fetch_int () == (int)CODE_upload_file);
|
||||
unsigned x = fetch_int ();
|
||||
struct download *D = q->extra;
|
||||
if (D->fd == -1) {
|
||||
static char buf[100];
|
||||
sprintf (buf, "%s/tmp_%ld_%ld", get_downloads_directory (), lrand48 (), lrand48 ());
|
||||
int l = strlen (buf);
|
||||
switch (x) {
|
||||
case CODE_storage_file_unknown:
|
||||
break;
|
||||
case CODE_storage_file_jpeg:
|
||||
sprintf (buf + l, "%s", ".jpg");
|
||||
break;
|
||||
case CODE_storage_file_gif:
|
||||
sprintf (buf + l, "%s", ".gif");
|
||||
break;
|
||||
case CODE_storage_file_png:
|
||||
sprintf (buf + l, "%s", ".png");
|
||||
break;
|
||||
case CODE_storage_file_mp3:
|
||||
sprintf (buf + l, "%s", ".mp3");
|
||||
break;
|
||||
case CODE_storage_file_mov:
|
||||
sprintf (buf + l, "%s", ".mov");
|
||||
break;
|
||||
case CODE_storage_file_partial:
|
||||
sprintf (buf + l, "%s", ".part");
|
||||
break;
|
||||
case CODE_storage_file_mp4:
|
||||
sprintf (buf + l, "%s", ".mp4");
|
||||
break;
|
||||
case CODE_storage_file_webp:
|
||||
sprintf (buf + l, "%s", ".webp");
|
||||
break;
|
||||
}
|
||||
D->name = strdup (buf);
|
||||
D->fd = open (D->name, O_CREAT | O_WRONLY, 0640);
|
||||
}
|
||||
fetch_int (); // mtime
|
||||
int len = prefetch_strlen ();
|
||||
assert (len >= 0);
|
||||
assert (write (D->fd, fetch_str (len), len) == len);
|
||||
D->offset += len;
|
||||
if (D->offset < D->size) {
|
||||
load_next_part (D);
|
||||
return 0;
|
||||
} else {
|
||||
end_load (D);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
struct query_methods download_methods = {
|
||||
.on_answer = download_on_answer
|
||||
};
|
||||
|
||||
void load_next_part (struct download *D) {
|
||||
clear_packet ();
|
||||
out_int (CODE_upload_get_file);
|
||||
if (!D->id) {
|
||||
out_int (CODE_input_file_location);
|
||||
out_long (D->volume);
|
||||
out_int (D->local_id);
|
||||
out_long (D->secret);
|
||||
} else {
|
||||
out_int (CODE_input_video_file_location);
|
||||
out_long (D->id);
|
||||
out_long (D->access_hash);
|
||||
}
|
||||
out_int (D->offset);
|
||||
out_int (1 << 14);
|
||||
send_query (DC_list[D->dc], packet_ptr - packet_buffer, packet_buffer, &download_methods, D);
|
||||
//send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &download_methods, D);
|
||||
}
|
||||
|
||||
void do_load_photo_size (struct photo_size *P, int next) {
|
||||
assert (P);
|
||||
assert (next);
|
||||
struct download *D = malloc (sizeof (*D));
|
||||
D->id = 0;
|
||||
D->offset = 0;
|
||||
D->size = P->size;
|
||||
D->volume = P->loc.volume;
|
||||
D->dc = P->loc.dc;
|
||||
D->local_id = P->loc.local_id;
|
||||
D->secret = P->loc.secret;
|
||||
D->next = next;
|
||||
D->name = 0;
|
||||
D->fd = -1;
|
||||
load_next_part (D);
|
||||
}
|
||||
|
||||
void do_load_photo (struct photo *photo, int next) {
|
||||
if (!photo->sizes_num) { return; }
|
||||
int max = -1;
|
||||
int maxi = 0;
|
||||
int i;
|
||||
for (i = 0; i < photo->sizes_num; i++) {
|
||||
if (photo->sizes[i].w + photo->sizes[i].h > max) {
|
||||
max = photo->sizes[i].w + photo->sizes[i].h;
|
||||
maxi = i;
|
||||
}
|
||||
}
|
||||
do_load_photo_size (&photo->sizes[maxi], next);
|
||||
}
|
||||
|
||||
void do_load_video_thumb (struct video *video, int next) {
|
||||
do_load_photo_size (&video->thumb, next);
|
||||
}
|
||||
|
||||
void do_load_video (struct video *V, int next) {
|
||||
assert (V);
|
||||
assert (next);
|
||||
struct download *D = malloc (sizeof (*D));
|
||||
D->offset = 0;
|
||||
D->size = V->size;
|
||||
D->id = V->id;
|
||||
D->access_hash = V->access_hash;
|
||||
D->dc = V->dc_id;
|
||||
D->next = next;
|
||||
D->name = 0;
|
||||
D->fd = -1;
|
||||
load_next_part (D);
|
||||
}
|
||||
|
|
|
@ -79,4 +79,10 @@ void do_get_user_info (union user_chat *user);
|
|||
void do_forward_message (union user_chat *U, int n);
|
||||
void do_rename_chat (union user_chat *U, char *name);
|
||||
|
||||
struct photo;
|
||||
struct video;
|
||||
void do_load_photo (struct photo *photo, int next);
|
||||
void do_load_video_thumb (struct video *video, int next);
|
||||
void do_load_video (struct video *V, int next);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -348,7 +348,9 @@ void fetch_photo_size (struct photo_size *S) {
|
|||
if (x == CODE_photo_size) {
|
||||
S->size = fetch_int ();
|
||||
} else {
|
||||
S->data = fetch_str_dup ();
|
||||
S->size = prefetch_strlen ();
|
||||
S->data = malloc (S->size);
|
||||
memcpy (S->data, fetch_str (S->size), S->size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue