some fixes. updated tgl
This commit is contained in:
parent
44286cd15e
commit
0faf9f80b7
@ -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
|
||||
|
154
interface.c
154
interface.c
@ -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++) {
|
||||
|
@ -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
10
loop.c
@ -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
8
main.c
@ -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;
|
||||
|
@ -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
2
tgl
@ -1 +1 @@
|
||||
Subproject commit 41121e9908fc5ddebe3ec6eca9f55172b630f21a
|
||||
Subproject commit 73482c7a461ff4341ea098dd258b6373f530ab70
|
Loading…
Reference in New Issue
Block a user