Support for sending photos. Some fixed bugs. Slightly changed interface
This commit is contained in:
parent
dd6c67008d
commit
1c0ba265f0
46
interface.c
46
interface.c
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
143
queries.c
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user