summary refs log tree commit diff stats
path: root/handlers.go
blob: 01049b0ab67ebac4adebf80805f66e6d3556f634 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package main

import (
	"crypto/sha256"
	"fmt"
	"log"
	"net/http"
	"time"

	"github.com/gorilla/mux"
)

// handles "/"
func indexHandler(w http.ResponseWriter, _ *http.Request) {
	w.Header().Set("Content-Type", htmlutf8)
	n, err := w.Write([]byte("getwtxt v" + getwtxt))
	if err != nil || n == 0 {
		log.Printf("Error writing to HTTP stream: %v\n", err)
	}

}

// handles "/api"
func apiBaseHandler(w http.ResponseWriter, r *http.Request) {
	timerfc3339, err := time.Now().MarshalText()
	if err != nil {
		log.Printf("Couldn't format time as RFC3339: %v\n", err)
	}
	etag := fmt.Sprintf("%x", sha256.Sum256(timerfc3339))
	w.Header().Set("ETag", etag)
	w.Header().Set("Content-Type", txtutf8)
	pathdata := []byte("\n\n" + r.URL.Path)
	timerfc3339 = append(timerfc3339, pathdata...)
	n, err := w.Write(timerfc3339)
	if err != nil || n == 0 {
		log.Printf("Error writing to HTTP stream: %v\n", err)
	}
}

// handles "/api/plain"
// maybe add json/xml support later
func apiFormatHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	format := vars["format"]

	w.Header().Set("Content-Type", txtutf8)
	n, err := w.Write([]byte(format + "\n"))
	if err != nil || n == 0 {
		log.Printf("Error writing to HTTP stream: %v\n", err)
	}
}

// handles "/api/plain/(users|mentions|tweets)"
func apiEndpointHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	format := vars["format"]
	endpoint := vars["endpoint"]

	w.Header().Set("Content-Type", htmlutf8)
	n, err := w.Write([]byte(format + "/" + endpoint))
	if err != nil || n == 0 {
		log.Printf("Error writing to HTTP stream: %v\n", err)
	}

}

// handles POST for "/api/plain/users"
func apiEndpointPOSTHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	format := vars["format"]
	endpoint := vars["endpoint"]

	w.Header().Set("Content-Type", htmlutf8)
	n, err := w.Write([]byte(format + "/" + endpoint))
	if err != nil || n == 0 {
		log.Printf("Error writing to HTTP stream: %v\n", err)
	}

}

// handles "/api/plain/tags"
func apiTagsBaseHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	format := vars["format"]

	w.Header().Set("Content-Type", htmlutf8)
	n, err := w.Write([]byte("api/" + format + "/tags"))
	if err != nil || n == 0 {
		log.Printf("Error writing to HTTP stream: %v\n", err)
	}

}

// handles "/api/plain/tags/[a-zA-Z0-9]+"
func apiTagsHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	format := vars["format"]
	tags := vars["tags"]

	w.Header().Set("Content-Type", htmlutf8)
	n, err := w.Write([]byte("api/" + format + "/tags/" + tags))
	if err != nil || n == 0 {
		log.Printf("Error writing to HTTP stream: %v\n", err)
	}

}
="p">; static char *inp_line = NULL; static gboolean get_password = FALSE; static void _inp_win_update_virtual(void); static int _inp_printable(const wint_t ch); static void _inp_win_handle_scroll(void); static int _inp_offset_to_col(char *str, int offset); static void _inp_write(char *line, int offset); static int _inp_rl_getc(FILE *stream); static void _inp_rl_linehandler(char *line); static int _inp_rl_tab_handler(int count, int key); static int _inp_rl_clear_handler(int count, int key); static int _inp_rl_win1_handler(int count, int key); static int _inp_rl_win2_handler(int count, int key); static int _inp_rl_win3_handler(int count, int key); static int _inp_rl_win4_handler(int count, int key); static int _inp_rl_win5_handler(int count, int key); static int _inp_rl_win6_handler(int count, int key); static int _inp_rl_win7_handler(int count, int key); static int _inp_rl_win8_handler(int count, int key); static int _inp_rl_win9_handler(int count, int key); static int _inp_rl_win0_handler(int count, int key); static int _inp_rl_altleft_handler(int count, int key); static int _inp_rl_altright_handler(int count, int key); static int _inp_rl_pageup_handler(int count, int key); static int _inp_rl_pagedown_handler(int count, int key); static int _inp_rl_altpageup_handler(int count, int key); static int _inp_rl_altpagedown_handler(int count, int key); static int _inp_rl_startup_hook(void); void create_input_window(void) { #ifdef NCURSES_REENTRANT set_escdelay(25); #else ESCDELAY = 25; #endif rl_readline_name = "profanity"; rl_getc_function = _inp_rl_getc; rl_startup_hook = _inp_rl_startup_hook; rl_callback_handler_install(NULL, _inp_rl_linehandler); inp_win = newpad(1, INP_WIN_MAX); wbkgd(inp_win, theme_attrs(THEME_INPUT_TEXT));; keypad(inp_win, TRUE); wmove(inp_win, 0, 0); _inp_win_update_virtual(); } char* inp_readline(void) { free(inp_line); inp_line = NULL; p_rl_timeout.tv_sec = inp_timeout / 1000; p_rl_timeout.tv_usec = inp_timeout % 1000 * 1000; FD_ZERO(&fds); FD_SET(fileno(rl_instream), &fds); errno = 0; r = select(FD_SETSIZE, &fds, NULL, NULL, &p_rl_timeout); if (r < 0) { if (errno != EINTR) { char *err_msg = strerror(errno); log_error("Readline failed: %s", err_msg); } return NULL; } if (FD_ISSET(fileno(rl_instream), &fds)) { rl_callback_read_char(); if (rl_line_buffer && rl_line_buffer[0] != '/' && rl_line_buffer[0] != '\0' && rl_line_buffer[0] != '\n') { prof_handle_activity(); } ui_reset_idle_time(); if (!get_password) { _inp_write(rl_line_buffer, rl_point); } inp_nonblocking(TRUE); } else { inp_nonblocking(FALSE); prof_handle_idle(); } if (inp_line) { return strdup(inp_line); } else { return NULL; } } void inp_win_resize(void) { int col = getcurx(inp_win); int wcols = getmaxx(stdscr); // if lost cursor off screen, move contents to show it if (col >= pad_start + wcols) { pad_start = col - (wcols / 2); if (pad_start < 0) { pad_start = 0; } } wbkgd(inp_win, theme_attrs(THEME_INPUT_TEXT));; _inp_win_update_virtual(); } void inp_nonblocking(gboolean reset) { if (! prefs_get_boolean(PREF_INPBLOCK_DYNAMIC)) { inp_timeout = prefs_get_inpblock(); return; } if (reset) { inp_timeout = 0; no_input_count = 0; } if (inp_timeout < prefs_get_inpblock()) { no_input_count++; if (no_input_count % 10 == 0) { inp_timeout += no_input_count; if (inp_timeout > prefs_get_inpblock()) { inp_timeout = prefs_get_inpblock(); } } } } void inp_close(void) { rl_callback_handler_remove(); } char* inp_get_line(void) { werase(inp_win); wmove(inp_win, 0, 0); _inp_win_update_virtual(); doupdate(); char *line = NULL; while (!line) { line = inp_readline(); ui_update(); } status_bar_clear(); return line; } char* inp_get_password(void) { werase(inp_win); wmove(inp_win, 0, 0); _inp_win_update_virtual(); doupdate(); char *password = NULL; get_password = TRUE; while (!password) { password = inp_readline(); ui_update(); } get_password = FALSE; status_bar_clear(); return password; } void inp_put_back(void) { _inp_win_update_virtual(); } static void _inp_win_update_virtual(void) { int wrows, wcols; getmaxyx(stdscr, wrows, wcols); pnoutrefresh(inp_win, 0, pad_start, wrows-1, 0, wrows-1, wcols-2); } static void _inp_write(char *line, int offset) { int col = _inp_offset_to_col(line, offset); werase(inp_win); waddstr(inp_win, line); wmove(inp_win, 0, col); _inp_win_handle_scroll(); _inp_win_update_virtual(); doupdate(); } static int _inp_printable(const wint_t ch) { char bytes[MB_CUR_MAX+1]; size_t utf_len = wcrtomb(bytes, ch, (mbstate_t*)NULL); bytes[utf_len] = '\0'; gunichar unichar = g_utf8_get_char(bytes); return g_unichar_isprint(unichar); } static int _inp_offset_to_col(char *str, int offset) { int i = 0; int col = 0; while (i < offset && str[i] != '\0') { gunichar uni = g_utf8_get_char(&str[i]); size_t ch_len = mbrlen(&str[i], 4, NULL); i += ch_len; col++; if (g_unichar_iswide(uni)) { col++; } } return col; } static void _inp_win_handle_scroll(void) { int col = getcurx(inp_win); int wcols = getmaxx(stdscr); if (col == 0) { pad_start = 0; } else if (col >= pad_start + (wcols -2)) { pad_start = col - (wcols / 2); if (pad_start < 0) { pad_start = 0; } } else if (col <= pad_start) { pad_start = pad_start - (wcols / 2); if (pad_start < 0) { pad_start = 0; } } } // Readline callbacks static int _inp_rl_startup_hook(void) { rl_bind_keyseq("\\e1", _inp_rl_win1_handler); rl_bind_keyseq("\\e2", _inp_rl_win2_handler); rl_bind_keyseq("\\e3", _inp_rl_win3_handler); rl_bind_keyseq("\\e4", _inp_rl_win4_handler); rl_bind_keyseq("\\e5", _inp_rl_win5_handler); rl_bind_keyseq("\\e6", _inp_rl_win6_handler); rl_bind_keyseq("\\e7", _inp_rl_win7_handler); rl_bind_keyseq("\\e8", _inp_rl_win8_handler); rl_bind_keyseq("\\e9", _inp_rl_win9_handler); rl_bind_keyseq("\\e0", _inp_rl_win0_handler); rl_bind_keyseq("\\eOP", _inp_rl_win1_handler); rl_bind_keyseq("\\eOQ", _inp_rl_win2_handler); rl_bind_keyseq("\\eOR", _inp_rl_win3_handler); rl_bind_keyseq("\\eOS", _inp_rl_win4_handler); rl_bind_keyseq("\\e[15~", _inp_rl_win5_handler); rl_bind_keyseq("\\e[17~", _inp_rl_win6_handler); rl_bind_keyseq("\\e[18~", _inp_rl_win7_handler); rl_bind_keyseq("\\e[19~", _inp_rl_win8_handler); rl_bind_keyseq("\\e[20~", _inp_rl_win9_handler); rl_bind_keyseq("\\e[21~", _inp_rl_win0_handler); rl_bind_keyseq("\\e[1;9D", _inp_rl_altleft_handler); rl_bind_keyseq("\\e[1;3D", _inp_rl_altleft_handler); rl_bind_keyseq("\\e\\e[D", _inp_rl_altleft_handler); rl_bind_keyseq("\\e[1;9C", _inp_rl_altright_handler); rl_bind_keyseq("\\e[1;3C", _inp_rl_altright_handler); rl_bind_keyseq("\\e\\e[C", _inp_rl_altright_handler); rl_bind_keyseq("\\e\\e[5~", _inp_rl_altpageup_handler); rl_bind_keyseq("\\e[5;3~", _inp_rl_altpageup_handler); rl_bind_keyseq("\\e\\eOy", _inp_rl_altpageup_handler); rl_bind_keyseq("\\e\\e[6~", _inp_rl_altpagedown_handler); rl_bind_keyseq("\\e[6;3~", _inp_rl_altpagedown_handler); rl_bind_keyseq("\\e\\eOs", _inp_rl_altpagedown_handler); rl_bind_keyseq("\\e[5~", _inp_rl_pageup_handler); rl_bind_keyseq("\\eOy", _inp_rl_pageup_handler); rl_bind_keyseq("\\e[6~", _inp_rl_pagedown_handler); rl_bind_keyseq("\\eOs", _inp_rl_pagedown_handler); rl_bind_key('\t', _inp_rl_tab_handler); rl_bind_key(CTRL('L'), _inp_rl_clear_handler); // unbind unwanted mappings rl_bind_keyseq("\\e=", NULL); return 0; } static void _inp_rl_linehandler(char *line) { if (line && *line) { if (!get_password) { add_history(line); } } inp_line = line; } static int _inp_rl_getc(FILE *stream) { int ch = rl_getc(stream); if (_inp_printable(ch)) { ProfWin *window = wins_get_current(); cmd_reset_autocomplete(window); } return ch; } static int _inp_rl_clear_handler(int count, int key) { ProfWin *win = wins_get_current(); win_clear(win); return 0; } static int _inp_rl_tab_handler(int count, int key) { if (rl_point != rl_end || !rl_line_buffer) { return 0; } ProfWin *current = wins_get_current(); if ((strncmp(rl_line_buffer, "/", 1) != 0) && (current->type == WIN_MUC)) { char *result = muc_autocomplete(current, rl_line_buffer); if (result) { rl_replace_line(result, 0); rl_point = rl_end; free(result); } } else if (strncmp(rl_line_buffer, "/", 1) == 0) { ProfWin *window = wins_get_current(); char *result = cmd_autocomplete(window, rl_line_buffer); if (result) { rl_replace_line(result, 0); rl_point = rl_end; free(result); } } return 0; } static void _go_to_win(int i) { ProfWin *window = wins_get_by_num(i); if (window) { ui_focus_win(window); } } static int _inp_rl_win1_handler(int count, int key) { _go_to_win(1); return 0; } static int _inp_rl_win2_handler(int count, int key) { _go_to_win(2); return 0; } static int _inp_rl_win3_handler(int count, int key) { _go_to_win(3); return 0; } static int _inp_rl_win4_handler(int count, int key) { _go_to_win(4); return 0; } static int _inp_rl_win5_handler(int count, int key) { _go_to_win(5); return 0; } static int _inp_rl_win6_handler(int count, int key) { _go_to_win(6); return 0; } static int _inp_rl_win7_handler(int count, int key) { _go_to_win(7); return 0; } static int _inp_rl_win8_handler(int count, int key) { _go_to_win(8); return 0; } static int _inp_rl_win9_handler(int count, int key) { _go_to_win(9); return 0; } static int _inp_rl_win0_handler(int count, int key) { _go_to_win(0); return 0; } static int _inp_rl_altleft_handler(int count, int key) { ProfWin *window = wins_get_previous(); if (window) { ui_focus_win(window); } return 0; } static int _inp_rl_altright_handler(int count, int key) { ProfWin *window = wins_get_next(); if (window) { ui_focus_win(window); } return 0; } static int _inp_rl_pageup_handler(int count, int key) { ProfWin *current = wins_get_current(); win_page_up(current); return 0; } static int _inp_rl_pagedown_handler(int count, int key) { ProfWin *current = wins_get_current(); win_page_down(current); return 0; } static int _inp_rl_altpageup_handler(int count, int key) { ProfWin *current = wins_get_current(); win_sub_page_up(current); return 0; } static int _inp_rl_altpagedown_handler(int count, int key) { ProfWin *current = wins_get_current(); win_sub_page_down(current); return 0; }