Support for sending photos. Some fixed bugs. Slightly changed interface

This commit is contained in:
Vysheng 2013-10-21 22:24:31 +04:00
parent dd6c67008d
commit 1c0ba265f0
5 changed files with 241 additions and 15 deletions

View File

@ -33,6 +33,8 @@ char *commands[] = {
"stats",
"history",
"dialog_list",
"send_photo",
"send_video",
0 };
int commands_flags[] = {
@ -42,6 +44,8 @@ int commands_flags[] = {
07,
072,
07,
0732,
0732,
};
char *a = 0;
@ -219,6 +223,22 @@ void interpreter (char *line UU) {
if (*q && index < user_num + chat_num) {
do_send_message (Peers[index], q);
}
} else if (!memcmp (line, "send_photo", 10)) {
char *q = line + 10;
int len;
char *text = get_token (&q, &len);
int index = 0;
while (index < user_num + chat_num && (!Peers[index]->print_name || strncmp (Peers[index]->print_name, text, len))) {
index ++;
}
if (index < user_num + chat_num) {
int len = 0;
char *f = get_token (&q, &len);
if (len > 0) {
do_send_photo (CODE_input_media_uploaded_photo,
Peers[index]->id, strndup (f, len));
}
}
} else if (!memcmp (line, "history", 7)) {
char *q = line + 7;
int len;
@ -380,7 +400,7 @@ void pop_color (void) {
assert (color_stack_pos > 0);
color_stack_pos --;
if (color_stack_pos >= 1) {
printf ("%s", color_stack[color_stack_pos] - 1);
printf ("%s", color_stack[color_stack_pos - 1]);
} else {
printf ("%s", COLOR_NORMAL);
}
@ -391,7 +411,11 @@ void print_media (struct message_media *M) {
case CODE_message_media_empty:
return;
case CODE_message_media_photo:
printf ("[photo]");
if (M->photo.caption && strlen (M->photo.caption)) {
printf ("[photo %s]", M->photo.caption);
} else {
printf ("[photo]");
}
return;
case CODE_message_media_video:
printf ("[video]");
@ -466,7 +490,11 @@ void print_message (struct message *M) {
printf (" ");
print_user_name (M->to_id, user_chat_get (M->to_id));
push_color (COLOR_GREEN);
printf (" <<< ");
if (M->unread) {
printf (" <<< ");
} else {
printf (" ««« ");
}
} else {
push_color (COLOR_BLUE);
print_date (M->date);
@ -474,7 +502,11 @@ void print_message (struct message *M) {
printf (" ");
print_user_name (M->from_id, user_chat_get (M->from_id));
push_color (COLOR_BLUE);
printf (" >>> ");
if (M->unread) {
printf (" >>> ");
} else {
printf (" »»» ");
}
}
} else {
push_color (COLOR_MAGENTA);
@ -489,7 +521,11 @@ void print_message (struct message *M) {
} else {
push_color (COLOR_BLUE);
}
printf (" >>> ");
if (M->unread) {
printf (" >>> ");
} else {
printf (" »»» ");
}
}
if (M->message && strlen (M->message)) {
printf ("%s", M->message);

View File

@ -22,4 +22,11 @@ void hexdump (int *in_ptr, int *in_end);
struct message;
void print_message (struct message *M);
void print_chat_name (int id, union user_chat *C);
void print_user_name (int id, union user_chat *U);
//void print_media (struct message_media *M);
void pop_color (void);
void push_color (const char *color);
void print_start (void);
void print_end (void);
#endif

View File

@ -645,15 +645,24 @@ void work_update (struct connection *c UU, long long msg_id UU) {
}
}
fetch_int (); //pts
print_start ();
push_color (COLOR_YELLOW);
printf ("%d messages marked as read\n", n);
pop_color ();
print_end ();
}
break;
case CODE_update_user_typing:
{
int id = fetch_int ();
union user_chat *U = user_chat_get (id);
if (U) {
rprintf (COLOR_YELLOW "User " COLOR_RED "%s %s" COLOR_YELLOW " is typing....\n" COLOR_NORMAL, U->user.first_name, U->user.last_name);
}
print_start ();
push_color (COLOR_YELLOW);
printf ("User ");
print_user_name (id, U);
printf (" is typing....\n");
pop_color ();
print_end ();
}
break;
case CODE_update_chat_user_typing:
@ -662,9 +671,15 @@ void work_update (struct connection *c UU, long long msg_id UU) {
int id = fetch_int ();
union user_chat *C = user_chat_get (-chat_id);
union user_chat *U = user_chat_get (id);
if (U && C) {
rprintf (COLOR_YELLOW "User " COLOR_RED "%s %s" COLOR_YELLOW " is typing in chat %s....\n" COLOR_NORMAL, U->user.first_name, U->user.last_name, C->chat.title);
}
print_start ();
push_color (COLOR_YELLOW);
printf ("User ");
print_user_name (id, U);
printf (" is typing in chat ");
print_chat_name (-chat_id, C);
printf ("....\n");
pop_color ();
print_end ();
}
break;
case CODE_update_user_status:
@ -673,7 +688,14 @@ void work_update (struct connection *c UU, long long msg_id UU) {
union user_chat *U = user_chat_get (user_id);
if (U) {
fetch_user_status (&U->user.status);
rprintf (COLOR_YELLOW "User " COLOR_RED "%s %s" COLOR_YELLOW " is now %s\n" COLOR_NORMAL, U->user.first_name, U->user.last_name, (U->user.status.online > 0) ? "online" : "offline");
print_start ();
push_color (COLOR_YELLOW);
printf ("User ");
print_user_name (user_id, U);
printf (" is now ");
printf ("%s\n", (U->user.status.online > 0) ? "online" : "offline");
pop_color ();
print_end ();
} else {
struct user_status t;
fetch_user_status (&t);
@ -686,11 +708,20 @@ void work_update (struct connection *c UU, long long msg_id UU) {
union user_chat *UC = user_chat_get (user_id);
if (UC) {
struct user *U = &UC->user;
print_start ();
push_color (COLOR_YELLOW);
printf ("User ");
print_user_name (user_id, UC);
if (U->first_name) { free (U->first_name); }
if (U->last_name) { free (U->first_name); }
if (U->print_name) { free (U->first_name); }
if (U->last_name) { free (U->last_name); }
if (U->print_name) { free (U->print_name); }
U->first_name = fetch_str_dup ();
U->last_name = fetch_str_dup ();
printf (" changed name to ");
print_user_name (user_id, UC);
printf ("\n");
pop_color ();
print_end ();
if (!strlen (U->first_name)) {
if (!strlen (U->last_name)) {
U->print_name = strdup ("none");
@ -722,6 +753,14 @@ void work_update (struct connection *c UU, long long msg_id UU) {
union user_chat *UC = user_chat_get (user_id);
if (UC) {
struct user *U = &UC->user;
print_start ();
push_color (COLOR_YELLOW);
printf ("User ");
print_user_name (user_id, UC);
printf (" updated profile photo\n");
pop_color ();
print_end ();
unsigned y = fetch_int ();
if (y == CODE_user_profile_photo_empty) {
U->photo_big.dc = -2;

143
queries.c
View File

@ -1,7 +1,12 @@
#define _FILE_OFFSET_BITS 64
#include <string.h>
#include <memory.h>
#include <stdlib.h>
#include <zlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "include.h"
#include "mtproto-client.h"
@ -57,8 +62,11 @@ struct query *send_query (struct dc *DC, int ints, void *data, struct query_meth
logprintf ( "Msg_id is %lld\n", q->msg_id);
}
q->methods = methods;
q->DC = DC;
if (queries_tree) {
logprintf ( "%lld %lld\n", q->msg_id, queries_tree->x->msg_id);
if (verbosity >= 2) {
logprintf ( "%lld %lld\n", q->msg_id, queries_tree->x->msg_id);
}
}
queries_tree = tree_insert_query (queries_tree, q, lrand48 ());
@ -581,3 +589,136 @@ void do_get_dialog_list (void) {
out_int (1000);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &get_dialogs_methods, 0);
}
struct send_file {
int fd;
long long size;
long long offset;
int part_num;
int part_size;
long long id;
int to_id;
int media_type;
char *file_name;
};
void out_peer_id (int id) {
union user_chat *U = user_chat_get (id);
if (id < 0) {
out_int (CODE_input_peer_chat);
out_int (-id);
} else {
if (U && U->user.access_hash) {
out_int (CODE_input_peer_foreign);
out_int (id);
out_long (U->user.access_hash);
} else {
out_int (CODE_input_peer_contact);
out_int (id);
}
}
}
void send_part (struct send_file *f);
int send_file_part_on_answer (struct query *q) {
assert (fetch_int () == (int)CODE_bool_true);
send_part (q->extra);
return 0;
}
int send_file_on_answer (struct query *q UU) {
assert (fetch_int () == (int)CODE_messages_stated_message);
struct message *M = fetch_alloc_message ();
assert (fetch_int () == CODE_vector);
int n, i;
n = fetch_int ();
for (i = 0; i < n; i++) {
fetch_alloc_chat ();
}
assert (fetch_int () == CODE_vector);
n = fetch_int ();
for (i = 0; i < n; i++) {
fetch_alloc_user ();
}
fetch_int (); // pts
fetch_int (); // seq
print_message (M);
return 0;
}
struct query_methods send_file_part_methods = {
.on_answer = send_file_part_on_answer
};
struct query_methods send_file_methods = {
.on_answer = send_file_on_answer
};
void send_part (struct send_file *f) {
if (f->fd >= 0) {
clear_packet ();
out_int (CODE_upload_save_file_part);
out_long (f->id);
out_int (f->part_num ++);
static char buf[512 << 10];
int x = read (f->fd, buf, f->part_size);
assert (x > 0);
out_cstring (buf, x);
f->offset += x;
logprintf ("offset=%lld size=%lld\n", f->offset, f->size);
if (f->offset == f->size) {
close (f->fd);
f->fd = -1;
}
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &send_file_part_methods, f);
} else {
clear_packet ();
out_int (CODE_messages_send_media);
out_peer_id (f->to_id);
assert (f->media_type == CODE_input_media_uploaded_photo);
out_int (f->media_type);
out_int (CODE_input_file);
out_long (f->id);
out_int (f->part_num);
char *s = f->file_name + strlen (f->file_name);
while (s >= f->file_name && *s != '/') { s --;}
out_string (s + 1);
out_string ("");
out_long (-lrand48 () * (1ll << 32) - lrand48 ());
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &send_file_methods, 0);
free (f->file_name);
free (f);
}
}
void do_send_photo (int type, int to_id, char *file_name) {
int fd = open (file_name, O_RDONLY);
if (fd < 0) {
rprintf ("No such file '%s'\n", file_name);
return;
}
struct stat buf;
fstat (fd, &buf);
long long size = buf.st_size;
if (size <= 0) {
rprintf ("File has zero length\n");
close (fd);
return;
}
struct send_file *f = malloc (sizeof (*f));
f->fd = fd;
f->size = size;
f->offset = 0;
f->part_num = 0;
f->part_size = (size / 1000 + 0x3ff) & ~0x3ff;
f->id = lrand48 () * (1ll << 32) + lrand48 ();
f->to_id = to_id;
f->media_type = type;
f->file_name = file_name;
if (f->part_size > (512 << 10)) {
close (fd);
rprintf ("Too big file. Maximal supported size is %d", (512 << 10) * 1000);
return;
}
send_part (f);
}

View File

@ -24,6 +24,7 @@ struct query {
void *data;
struct query_methods *methods;
struct event_timer ev;
struct dc *DC;
void *extra;
};
@ -49,4 +50,6 @@ union user_chat;
void do_send_message (union user_chat *U, const char *msg);
void do_get_history (union user_chat *U, int limit);
void do_get_dialog_list (void);
void do_send_photo (int type, int to_id, char *file_name);
#endif