some fixes. updated tgl

This commit is contained in:
vvaltman 2015-06-17 12:05:57 +03:00
parent 44286cd15e
commit 0faf9f80b7
7 changed files with 164 additions and 15 deletions

View File

@ -1,6 +1,7 @@
1.3.2
* use TGL-2.0.2
* add block/unblock user methods
* support for autocomplete for bot's commands
1.3.1
* added error codes
1.3.0

View File

@ -299,6 +299,30 @@ void next_token_end (void) {
}
}
void next_token_end_ac (void) {
skip_wspc ();
if (*line_ptr && *line_ptr != '"' && *line_ptr != '\'') {
cur_token_quoted = 0;
cur_token = line_ptr;
while (*line_ptr) { line_ptr ++; }
cur_token_len = line_ptr - cur_token;
assert (cur_token_len > 0);
cur_token_end_str = !force_end_mode;
return;
} else {
if (*line_ptr) {
next_token ();
skip_wspc ();
if (*line_ptr) {
cur_token_len = -1;
}
} else {
next_token ();
}
}
}
#define NOT_FOUND (int)0x80000000
tgl_peer_id_t TGL_PEER_NOT_FOUND = {.id = NOT_FOUND};
@ -569,6 +593,7 @@ enum command_argument {
ca_number,
ca_double,
ca_string_end,
ca_msg_string_end,
ca_string,
ca_modifier,
ca_command,
@ -1360,11 +1385,11 @@ struct command commands[MAX_COMMANDS_SIZE] = {
{"load_video_thumb", {ca_number, ca_none}, do_load_video_thumb, "load_video_thumb <msg-id>\tDownloads file to downloads dirs. Prints file name after download end", NULL},
{"main_session", {ca_none}, do_main_session, "main_session\tSends updates to this connection (or terminal). Useful only with listening socket", NULL},
{"mark_read", {ca_peer, ca_none}, do_mark_read, "mark_read <peer>\tMarks messages with peer as read", NULL},
{"msg", {ca_peer, ca_string_end, ca_none}, do_msg, "msg <peer> <text>\tSends text message to peer", NULL},
{"msg", {ca_peer, ca_msg_string_end, ca_none}, do_msg, "msg <peer> <text>\tSends text message to peer", NULL},
{"quit", {ca_none}, do_quit, "quit\tQuits immediately", NULL},
{"rename_chat", {ca_chat, ca_string_end, ca_none}, do_rename_chat, "rename_chat <chat> <new name>\tRenames chat", NULL},
{"rename_contact", {ca_user, ca_string, ca_string, ca_none}, do_rename_contact, "rename_contact <user> <first name> <last name>\tRenames contact", NULL},
{"reply", {ca_number, ca_string_end, ca_none}, do_reply, "reply <msg-id> <text>\tSends text reply to message", NULL},
{"reply", {ca_number, ca_msg_string_end, ca_none}, do_reply, "reply <msg-id> <text>\tSends text reply to message", NULL},
{"reply_audio", {ca_number, ca_file_name, ca_none}, do_send_audio, "reply_audio <msg-id> <file>\tSends audio to peer", NULL},
{"reply_contact", {ca_number, ca_string, ca_string, ca_string, ca_none}, do_reply_contact, "reply_contact <msg-id> <phone> <first-name> <last-name>\tSends contact (not necessary telegram user)", NULL},
{"reply_document", {ca_number, ca_file_name, ca_none}, do_reply_document, "reply_document <msg-id> <file>\tSends document to peer", NULL},
@ -1422,9 +1447,14 @@ void register_new_command (struct command *cmd) {
commands[i] = *cmd;
}
tgl_peer_t *autocomplete_peer;
int autocomplete_id;
enum command_argument get_complete_mode (void) {
force_end_mode = 0;
line_ptr = rl_line_buffer;
autocomplete_peer = NULL;
autocomplete_id = 0;
while (1) {
next_token ();
@ -1471,8 +1501,9 @@ enum command_argument get_complete_mode (void) {
int opt = (*flags) & ca_optional;
if (op == ca_none) { return ca_none; }
if (op == ca_string_end || op == ca_file_name_end) {
next_token_end ();
if (op == ca_string_end || op == ca_file_name_end || op == ca_msg_string_end) {
next_token_end_ac ();
if (cur_token_len < 0 || !cur_token_end_str) {
return ca_none;
} else {
@ -1510,10 +1541,18 @@ enum command_argument get_complete_mode (void) {
ok = (tgl_get_peer_type (cur_token_encr_chat ()) != NOT_FOUND);
break;
case ca_peer:
ok = (tgl_get_peer_type (cur_token_user ()) != NOT_FOUND);
ok = (tgl_get_peer_type (cur_token_peer ()) != NOT_FOUND);
if (ok) {
autocomplete_peer = tgl_peer_get (TLS, cur_token_peer ());
autocomplete_id = 0;
}
break;
case ca_number:
ok = (cur_token_int () != NOT_FOUND);
if (ok) {
autocomplete_peer = NULL;
autocomplete_id = cur_token_int ();
}
break;
case ca_double:
ok = (cur_token_double () != NOT_FOUND);
@ -1585,6 +1624,70 @@ int complete_command_list (int index, const char *text, int len, char **R) {
}
}
int complete_spec_message_answer (struct tgl_message *M, int index, const char *text, int len, char **R) {
if (!M || !M->reply_markup || !M->reply_markup->rows) {
*R = NULL;
return -1;
}
index ++;
int total = M->reply_markup->row_start[M->reply_markup->rows];
while (index < total && strncmp (M->reply_markup->buttons[index], text, len)) {
index ++;
}
if (index < total) {
*R = strdup (M->reply_markup->buttons[index]);
assert (*R);
return index;
} else {
*R = NULL;
return -1;
}
}
int complete_message_answer (tgl_peer_t *P, int index, const char *text, int len, char **R) {
struct tgl_message *M = P->last;
while (M && (M->flags & TGLMF_OUT)) {
M = M->next;
}
return complete_spec_message_answer (M, index, text, len, R);
}
int complete_user_command (tgl_peer_t *P, int index, const char *text, int len, char **R) {
if (len <= 0 || *text != '/') {
return complete_message_answer (P, index, text, len, R);
}
text ++;
len --;
struct tgl_user *U = (void *)P;
index ++;
if (!U->bot_info) {
*R = NULL;
return -1;
}
while (index < U->bot_info->commands_num && strncmp (U->bot_info->commands[index].command, text, len)) {
index ++;
}
if (index < U->bot_info->commands_num) {
*R = NULL;
assert (asprintf (R, "/%s", U->bot_info->commands[index].command) >= 0);
assert (*R);
return index;
} else {
*R = NULL;
return -1;
}
}
int complete_chat_command (tgl_peer_t *P, int index, const char *text, int len, char **R) {
*R = NULL;
return -1;
}
char *command_generator (const char *text, int state) {
#ifndef DISABLE_EXTF
static int len;
@ -1616,7 +1719,7 @@ char *command_generator (const char *text, int state) {
if (mode != ca_file_name && mode != ca_file_name_end && index == -1) { return 0; }
}
if (mode == ca_none || mode == ca_string || mode == ca_string_end || mode == ca_number || mode == ca_double) {
if (mode == ca_none || mode == ca_string || mode == ca_string_end || mode == ca_number || mode == ca_double) {
if (c) { rl_line_buffer[rl_point] = c; }
return 0;
}
@ -1653,6 +1756,30 @@ char *command_generator (const char *text, int state) {
index = complete_string_list (modifiers, index, command_pos, command_len, &R);
if (c) { rl_line_buffer[rl_point] = c; }
return R;
case ca_msg_string_end:
if (autocomplete_peer) {
if (tgl_get_peer_type (autocomplete_peer->id) == TGL_PEER_USER) {
index = complete_user_command (autocomplete_peer, index, command_pos, command_len, &R);
}
if (tgl_get_peer_type (autocomplete_peer->id) == TGL_PEER_CHAT) {
index = complete_chat_command (autocomplete_peer, index, command_pos, command_len, &R);
}
}
if (autocomplete_id) {
struct tgl_message *M = tgl_message_get (TLS, autocomplete_id);
if (M) {
if (command_len > 0 && *command_pos == '/') {
tgl_peer_t *P = tgl_peer_get (TLS, M->from_id);
if (P) {
index = complete_user_command (autocomplete_peer, index, command_pos, command_len, &R);
}
} else {
index = complete_spec_message_answer (M, index, command_pos, command_len, &R);
}
}
}
if (c) { rl_line_buffer[rl_point] = c; }
return R;
#ifndef DISABLE_EXTF
case ca_extf:
index = tglf_extf_autocomplete (TLS, text, len, index, &R, rl_line_buffer, rl_point);
@ -2049,6 +2176,17 @@ void print_user_info_gw (struct tgl_state *TLSR, void *extra, int success, struc
mprintf (ev, "\t");
print_user_status (&U->status, ev);
mprintf (ev, "\n");
if (U->bot_info) {
mprintf (ev, "\tshare_text: %s\n", U->bot_info->share_text);
mprintf (ev, "\tdescription: %s\n", U->bot_info->description);
mprintf (ev, "\tcommands:\n");
int i;
for (i = 0; i < U->bot_info->commands_num; i++) {
mprintf (ev, "\t\t/%s <%s>: %s\n", U->bot_info->commands[i].command, U->bot_info->commands[i].params, U->bot_info->commands[i].description);
}
}
mpop_color (ev);
} else {
#ifdef USE_JSON
@ -2782,7 +2920,7 @@ void interpreter_ex (char *line, void *ex) {
break;
}
if (op == ca_string_end || op == ca_file_name_end) {
if (op == ca_string_end || op == ca_file_name_end || op == ca_msg_string_end) {
next_token_end ();
if (cur_token_len < 0) {
fail_interface (TLS, ex, ENOSYS, "can not parse string_end arg #%d", args_num);
@ -2915,7 +3053,7 @@ void interpreter_ex (char *line, void *ex) {
continue;
}
}
assert (0);
//assert (0);
}
int i;
for (i = 0; i < args_num; i++) {

View File

@ -84,7 +84,7 @@ void json_pack_encr_chat (json_t *res, tgl_peer_t *P) {
json_t *json_pack_peer (tgl_peer_id_t id) {
tgl_peer_t *P = tgl_peer_get (TLS, id);
assert (P);
//assert (P);
json_t *res = json_object ();
assert (json_object_set (res, "id", json_integer (tgl_get_peer_id (id))) >= 0);

10
loop.c
View File

@ -76,6 +76,7 @@
int verbosity;
extern int readline_disabled;
extern int bot_mode;
int binlog_read;
extern char *default_username;
extern char *auth_token;
@ -360,10 +361,10 @@ void write_dc (struct tgl_dc *DC, void *extra) {
assert (DC->flags & TGLDCF_LOGGED_IN);
assert (write (auth_file_fd, &DC->port, 4) == 4);
int l = strlen (DC->ip);
assert (write (auth_file_fd, &DC->options[0]->port, 4) == 4);
int l = strlen (DC->options[0]->ip);
assert (write (auth_file_fd, &l, 4) == 4);
assert (write (auth_file_fd, DC->ip, l) == l);
assert (write (auth_file_fd, DC->options[0]->ip, l) == l);
assert (write (auth_file_fd, &DC->auth_key_id, 8) == 8);
assert (write (auth_file_fd, DC->auth_key, 256) == 256);
}
@ -701,6 +702,9 @@ int loop (void) {
if (ipv6_enabled) {
tgl_enable_ipv6 (TLS);
}
if (bot_mode) {
tgl_enable_bot (TLS);
}
if (disable_link_preview) {
tgl_disable_link_preview (TLS);
}

8
main.c
View File

@ -100,6 +100,7 @@
"# This is an empty config file\n" \
"# Feel free to put something here\n"
int bot_mode;
int verbosity;
int msg_num_mode;
char *default_username;
@ -492,6 +493,7 @@ void usage (void) {
printf (" --help/-h prints this help\n");
printf (" --accept-any-tcp accepts tcp connections from any src (only loopback by default)\n");
printf (" --disable-link-preview disables server-side previews to links\n");
printf (" --bot/-b bot mode\n");
#ifdef USE_JSON
printf (" --json prints answers and values in json format\n");
#endif
@ -640,6 +642,7 @@ void args_parse (int argc, char **argv) {
{"exec", required_argument, 0, 'e'},
{"disable-names", no_argument, 0, 'I'},
{"enable-ipv6", no_argument, 0, '6'},
{"bot", no_argument, 0, 'b'},
{"help", no_argument, 0, 'h'},
{"accept-any-tcp", no_argument, 0, 1001},
{"disable-link-preview", no_argument, 0, 1002},
@ -651,7 +654,7 @@ void args_parse (int argc, char **argv) {
int opt = 0;
while ((opt = getopt_long (argc, argv, "u:hk:vNl:fEwWCRdL:DU:G:qP:S:e:I6"
while ((opt = getopt_long (argc, argv, "u:hk:vNl:fEwWCRdL:DU:G:qP:S:e:I6b"
#ifdef HAVE_LIBCONFIG
"c:p:"
#else
@ -667,6 +670,9 @@ void args_parse (int argc, char **argv) {
)) != -1) {
switch (opt) {
case 'b':
bot_mode ++;
break;
case 1000:
tgl_allocator = &tgl_allocator_debug;
break;

View File

@ -21,4 +21,4 @@
#define PROG_NAME "telegram-cli"
#endif
#define TELEGRAM_CLI_VERSION "1.3.1"
#define TELEGRAM_CLI_VERSION "1.3.2"

2
tgl

@ -1 +1 @@
Subproject commit 41121e9908fc5ddebe3ec6eca9f55172b630f21a
Subproject commit 73482c7a461ff4341ea098dd258b6373f530ab70