1 /* Copyright 2013,2014 Akira Ohta (akohta001@gmail.com)
2 This file is part of ntch.
4 The ntch is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 The ntch is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with ntch. If not, see <http://www.gnu.org/licenses/>.
18 #include <sys/types.h>
19 #include <sys/socket.h>
26 #include <netinet/in.h>
31 #include "nt_string.h"
32 #include "utils/nt_std_t.h"
33 #include "net/nt_http.h"
34 #include "net/nt_socket.h"
35 #include "net/nt_cookie.h"
36 #include "utils/file.h"
37 #include "usr/usr_db_t.h"
38 #include "utils/nt_mutex.h"
39 #include "utils/nt_pthread.h"
40 #include "utils/nt_timer.h"
41 #include "utils/base64.h"
42 #include "utils/crypt.h"
43 #include "usr/favorite_t.h"
44 #include "_2ch/_2ch.h"
45 #include "_2ch/maru_2ch.h"
46 #include "_2ch/search_2ch.h"
48 #include "ui/disp_win.h"
49 #include "ui/disp_string.h"
50 #include "cloud/nt_cloud.h"
51 #include "usr/ng_word_t.h"
55 extern int server_main();
57 static int draw_title(WINDOW *wp, const wchar_t *title, attr_t attr);
58 static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle,
59 nt_cloud_handle h_cloud,
60 nt_favorite_handle h_favorite,
61 nt_favorite_grp_handle h_favorite_grp,
62 nt_ng_word_handle h_ng_word);
63 static void print_error(WINDOW *wp, const wchar_t *msg);
65 static void _2ch_selected_item_free(void *ptr)
67 nt_2ch_selected_item_release_ref(
68 (nt_2ch_selected_item_handle)ptr);
72 int main(int argc, char *argv[])
76 nt_usr_db_handle usr_db_handle;
77 nt_favorite_handle h_favorite;
78 nt_favorite_grp_handle h_favorite_grp;
79 nt_link_tp text_linkp, text2_linkp;
81 nt_ng_word_handle h_ng_word;
82 nt_cloud_handle h_cloud;
86 setlocale(LC_ALL, "ja_JP.UTF-8");
88 if(0 != set_option(argc, argv)){
92 if(APP_MODE == NT_APP_MODE_SERVER){
99 usr_db_handle = nt_usr_db_init_lib(USR_LOG_DB_PATH);
101 fputs("Couldn't initialize usr database.\n", stderr);
108 fputs("Couldn't initialize Curses libraly.\n", stderr);
117 if(!nt_pthread_lib_init(
118 NT_PTHREAD_POOL_SIZE,
119 NT_PTHREAD_POOL_QUEUE_SIZE,
122 fputs(err_msg, stderr);
126 if(nt_crypt_lib_init(RFC2898_SALT, RFC2898_ITERATION,
127 AES256_PASS, &err_msg)){
128 if(NCE_AUTH_URL && NCE_ID && NCE_PASS){
129 h_cloud = nt_cloud_init(NCE_AUTH_URL, NCE_ID, NCE_PASS);
133 fputs(err_msg, stderr);
138 if(!nt_2ch_model_init()){
139 fputs("Failed to read board menu data.\n", stderr);
143 if(!nt_init_board_menu()){
144 fputs("Failed to initialize board menu data.\n", stderr);
149 h_favorite = nt_favorite_alloc(L"favorite");
153 h_favorite_grp = nt_favorite_grp_alloc(h_favorite,
155 NT_FAVORITE_GRP_FLAG_FOLDER_OPEN);
157 nt_favorite_release_ref(h_favorite);
163 text_linkp = nt_cloud_download_file(h_cloud, "fb.txt");
166 text_linkp = nt_read_text_file(USR_FAVORITE_BOARD_FILE_PATH);
168 nt_favorite_load_boards(h_favorite, text_linkp);
169 nt_all_link_free(text_linkp, free);
173 text_linkp = nt_cloud_download_file(h_cloud, "ft.txt");
174 nt_cloud_query_favorite_attributes_async(h_cloud, usr_db_handle);
175 //nt_cloud_query_attributes(h_cloud, usr_db_handle, 0);
178 text_linkp = nt_read_text_file(USR_FAVORITE_THREAD_FILE_PATH);
180 nt_favorite_load_threads(h_favorite, h_favorite_grp, text_linkp);
181 nt_all_link_free(text_linkp, free);
184 h_ng_word = nt_ng_word_load(h_cloud,
185 USR_NG_WORD_FILE_PATH,
186 USR_NG_NAME_FILE_PATH,
187 USR_NG_ID_FILE_PATH);
192 if(DoLoop(scrp, usr_db_handle, h_cloud, h_favorite, h_favorite_grp, h_ng_word))
199 nt_ng_word_save(h_ng_word,
200 USR_NG_WORD_FILE_PATH,
201 USR_NG_NAME_FILE_PATH,
202 USR_NG_ID_FILE_PATH);
203 nt_ng_word_release_ref(h_ng_word);
206 text_linkp = nt_favorite_retrieve_boards(h_favorite);
208 nt_write_text_file(USR_FAVORITE_BOARD_FILE_PATH, text_linkp);
209 nt_all_link_free(text_linkp, free);
211 unlink(USR_FAVORITE_BOARD_FILE_PATH);
213 if(nt_favorite_retrieve_threads(h_favorite,
214 &text_linkp, &text2_linkp)){
216 nt_all_link_free(text_linkp, free);
218 nt_write_text_file(USR_FAVORITE_THREAD_FILE_PATH, text2_linkp);
219 nt_all_link_free(text2_linkp, free);
221 unlink(USR_FAVORITE_THREAD_FILE_PATH);
225 nt_favorite_grp_release_ref(h_favorite_grp);
226 nt_favorite_release_ref(h_favorite);
232 nt_2ch_model_release_ref(app_2ch_model);
236 nt_usr_db_finish_lib(usr_db_handle);
238 nt_pthread_lib_finish();
240 nt_mutex_lib_finish();
242 nt_timer_lib_finish();
244 nt_crypt_lib_finish();
246 nt_cloud_release_ref(h_cloud);
251 #define TIMER_ID_AUTO_UPDATE_NONE 0
252 #define TIMER_ID_AUTO_UPDATE 1
253 #define TIMER_ID_AUTO_SCROLL 2
254 static int auto_update_timer_func(int id)
257 case TIMER_ID_AUTO_UPDATE:
258 return TIMER_ID_AUTO_UPDATE;
259 case TIMER_ID_AUTO_SCROLL:
260 return TIMER_ID_AUTO_SCROLL;
262 return TIMER_ID_AUTO_UPDATE_NONE;
265 static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle,
266 nt_cloud_handle h_cloud,
267 nt_favorite_handle h_favorite,
268 nt_favorite_grp_handle h_favorite_grp,
269 nt_ng_word_handle h_ng_word)
272 int disp_state, nresult;
273 nt_window_tp bwinp = NULL;
274 nt_window_tp twinp = NULL;
275 nt_window_tp rwinp = NULL;
276 nt_window_tp search_winp = NULL;
277 nt_window_tp favorite_winp = NULL;
278 nt_window_tp history_winp = NULL;
280 wchar_t title_buf[128];
282 const wchar_t *title, *board_name;
283 const wchar_t *status_msg;
285 nt_write_data_handle h_write_data;
286 nt_maru_2ch_tp marup;
287 nt_cookie_tp cookiep;
289 nt_searched_thread_handle h_searched_thread;
290 nt_2ch_selected_item_handle h_sel_items;
291 nt_2ch_selected_item_handle h_sel_items_tmp;
292 nt_favorite_board_handle h_favorite_board;
293 nt_favorite_thread_handle h_favorite_thread;
295 nt_pthread_result_t async_data;
296 nt_link_tp linkp, linkp2;
298 nt_timer_handle h_timer_auto_update;
299 nt_timer_handle h_timer_auto_scroll;
300 nt_timer_handle h_timer;
302 state = DISP_STATE_BOARDMENU;
303 if(INIT_DISP_STATE == NT_INTI_DISP_FAVORITE){
304 disp_state = DISP_STATE_FAVORITE;
305 }else if(INIT_DISP_STATE == NT_INTI_DISP_HISTORY){
306 disp_state = DISP_STATE_HISTORY;
308 disp_state = DISP_STATE_BOARDMENU;
310 cookiep = nt_load_cookies(USR_COOKIE_PATH);
312 if(MARU_ID && MARU_PW)
313 marup = nt_maru_2ch_alloc(MARU_ID, MARU_PW);
314 h_timer_auto_scroll = nt_timer_alloc(
315 TIMER_ID_AUTO_SCROLL, -1, auto_update_timer_func);
316 h_timer_auto_update = nt_timer_alloc(
317 TIMER_ID_AUTO_UPDATE, NT_AUTO_UPDATE_INTERVAL, auto_update_timer_func);
322 h_searched_thread = NULL;
323 h_sel_items_tmp = NULL;
324 h_sel_items = nt_2ch_selected_item_alloc();
329 bwinp = nt_disp_win_alloc(scrp, LINES-1, COLS, 1, 0, buf);
332 twinp = nt_disp_win_alloc(scrp, LINES-1, COLS, 1, 0, buf);
335 rwinp = nt_disp_win_alloc(scrp, LINES-1, COLS, 1, 0, buf);
340 keypad(stdscr, true);
349 case DISP_STATE_BOARDMENU:
352 draw_title(scrp, L"板一覧", WA_REVERSE);
353 if(!nt_disp_win_move(scrp, bwinp, LINES-1, COLS, 1, 0))
355 state = disp_board_menu(bwinp, app_2ch_model, h_sel_items);
357 if(DISP_CMD(state) == DISP_CMD_ADD_FAVORITE){
358 board_name = nt_2ch_selected_item_get_board_name(h_sel_items);
359 h_favorite_board = nt_favorite_board_alloc(
360 h_favorite, board_name);
361 if(h_favorite_board){
362 linkp = nt_link_add_data(NULL, (void*)board_name);
365 nt_cloud_insert_lines_into_file(h_cloud, "fb.txt", linkp);
368 nt_favorite_board_release_ref(h_favorite_board);
369 //favorite_dump(h_favorite);
372 state = DISP_STATE_BOARDMENU;
375 if(DISP_STATE_ERROR == state){
377 }else if(DISP_STATE_THREADTITLE == state){
378 if(nt_read_board(h_sel_items)){
380 state = DISP_STATE_BOARDMENU;
382 free_threadlist_ctx(twinp->data);
388 print_error(scrp, NT_ERR_MSG_COUDLNOT_READ_BOARD);
390 }else if(state != DISP_STATE_BOARDMENU){
392 state = DISP_STATE_BOARDMENU;
397 case DISP_STATE_THREADTITLE:
400 twinp->status_msg = NULL;
401 title = nt_2ch_selected_item_get_board_name(h_sel_items);
402 draw_title(scrp, title, WA_REVERSE);
403 if(!nt_disp_win_move(scrp, twinp, LINES-1, COLS, 1, 0))
405 state = disp_threadlist(twinp, state, h_sel_items, db_handle);
407 if(DISP_CMD(state) == DISP_CMD_ADD_FAVORITE){
408 h_favorite_thread = nt_favorite_thread_alloc(
410 nt_2ch_selected_item_get_thread_dat_name(h_sel_items),
411 nt_2ch_selected_item_get_board_name(h_sel_items),
412 nt_2ch_selected_item_get_thread_title(h_sel_items));
413 if(h_favorite_thread){
415 if(nt_favorite_retrieve_thread(h_favorite_thread, &linkp)){
417 nt_cloud_insert_lines_into_file(h_cloud, "ft.txt", linkp);
418 nt_all_link_free(linkp, free);
420 nt_favorite_thread_release_ref(h_favorite_thread);
421 //favorite_dump(h_favorite);
422 status_msg = NT_INFO_ADD_FAVORITE_SUCCEEDED;
424 status_msg = NT_ERR_MSG_ADD_FAVORITE_FAILED;
426 }else if(DISP_CMD(state) == DISP_CMD_REFRESH){
427 if(nt_read_board(h_sel_items)){
429 free_threadlist_ctx(twinp->data);
433 status_msg = NT_INFO_REFRESH_BOARD_SUCCESS;
434 state = DISP_STATE_THREADTITLE;
438 status_msg = NT_ERR_MSG_COUDLNOT_READ_BOARD;
441 state = DISP_STATE_THREADTITLE;
443 }else if(DISP_STATE_ERROR == state){
445 }else if(DISP_STATE_BOARDMENU == state){
449 }else if(DISP_STATE_RESLIST == state){
451 if(!nt_read_thread(h_sel_items)){
453 state = DISP_STATE_THREADTITLE;
461 init_threadlist_ctx(twinp->data);
464 free_reslist_ctx(rwinp->data);
467 state = DISP_STATE_THREADTITLE;
470 }else if(DISP_STATE_THREADTITLE != state){
472 state = DISP_STATE_THREADTITLE;
476 status_msg = twinp->status_msg;
479 case DISP_STATE_RESLIST:
481 title = nt_2ch_selected_item_get_thread_title(h_sel_items);
483 num = draw_title(scrp, L"Title not found.", WA_REVERSE);
484 }else if(-1 == swprintf(title_buf, sizeof(title_buf)/sizeof(wchar_t),
486 nt_2ch_selected_item_get_board_name(h_sel_items),
488 num = draw_title(scrp, title, WA_REVERSE);
490 num = draw_title(scrp, title_buf, WA_REVERSE);
492 if(!nt_disp_win_move(scrp, rwinp,
493 LINES - num, COLS, num, 0))
496 state = disp_reslist(rwinp, state, h_sel_items, db_handle, h_ng_word, h_cloud);
497 auto_scrolling = FALSE;
499 if(DISP_CMD(state) == DISP_CMD_AUTO_SCROLL){
500 if(0 >= nt_timer_get_interval(h_timer_auto_scroll)){
501 nt_timer_set_interval(
502 h_timer_auto_scroll, NT_AUTO_SCROLL_INTERVAL);
504 auto_scrolling = TRUE;
505 state = DISP_STATE_RESLIST;
506 }else if(DISP_CMD(state) == DISP_CMD_REFRESH){
507 state = DISP_STATE_RESLIST;
509 if(!nt_read_thread(h_sel_items)){
510 status_msg = NT_ERR_MSG_REFRESH_THREAD_FAILED;
515 free_reslist_ctx(rwinp->data);
518 status_msg = NT_INFO_REFRESH_THREAD_SUCCESS;
521 }else if(DISP_CMD(state) == DISP_CMD_REENTER){
525 }else if(DISP_CMD(state) == DISP_CMD_EDIT_NGWORD){
529 linkp = nt_ng_word_get_words(h_ng_word);
530 linkp = disp_editor3(linkp);
531 if(linkp && nt_ng_word_set_words(h_ng_word, linkp, h_cloud)){
532 ch = NT_KEY_CMD_NGWORD_UPDATE;
535 keypad(stdscr, true);
538 }else if(DISP_CMD(state) == DISP_CMD_EDIT_NGNAME){
542 linkp = nt_ng_word_get_names(h_ng_word);
543 linkp = disp_editor3(linkp);
544 if(linkp && nt_ng_word_set_names(h_ng_word, linkp, h_cloud)){
545 ch = NT_KEY_CMD_NGWORD_UPDATE;
548 keypad(stdscr, true);
551 }else if(DISP_CMD(state) == DISP_CMD_EDIT_NGID){
555 linkp = nt_ng_word_get_ids(h_ng_word);
556 linkp = disp_editor3(linkp);
557 if(linkp && nt_ng_word_set_ids(h_ng_word, linkp, h_cloud)){
558 ch = NT_KEY_CMD_NGWORD_UPDATE;
561 keypad(stdscr, true);
567 nt_timer_set_interval(h_timer_auto_scroll, -1);
569 if(DISP_STATE_ERROR == state){
571 }else if(state != DISP_STATE_RESLIST){
573 state = DISP_STATE_RESLIST;
578 case DISP_STATE_EDITOR:
579 disp_state = DISP_STATE_RESLIST;
580 state = DISP_STATE_RESLIST;
583 nt_write_data_release_ref(h_write_data);
584 h_write_data = nt_write_data_alloc();
587 if(disp_editor(h_write_data)){
588 if(marup && !marup->sid)
589 get_session_id(marup);
590 if(nt_write_msg(h_sel_items,
591 h_write_data, cookiep, marup)){
592 disp_state = DISP_STATE_HTML_RESULT;
596 keypad(stdscr, true);
597 status_msg = nt_write_data_get_status_msg(h_write_data);
600 case DISP_STATE_HTML_RESULT:
601 nresult = disp_html_result(h_write_data);
603 if(!nt_read_thread(h_sel_items))
606 free_reslist_ctx(rwinp->data);
609 }else if(1 == nresult){
610 if(nt_write_msg(h_sel_items,
611 h_write_data, cookiep, marup)){
612 if(0 == disp_html_result(h_write_data)){
613 if(!nt_read_thread(h_sel_items))
616 free_reslist_ctx(rwinp->data);
622 keypad(stdscr, true);
623 disp_state = DISP_STATE_RESLIST;
624 state = DISP_STATE_RESLIST;
626 status_msg = nt_write_data_get_status_msg(h_write_data);
629 case DISP_STATE_SEARCH_THREAD:
630 draw_title(scrp, L"全板検索", WA_REVERSE);
632 search_winp = nt_disp_win_alloc(
633 scrp, LINES-1, COLS, 1, 0, buf);
636 search_winp->key = ch;
638 if(nt_get_search_text(buf, &search)){
640 linkp = nt_search_all_board(
641 app_2ch_model, search, &status_msg);
646 h_searched_thread = NULL;
647 disp_state = disp_thread_search(search_winp,
648 state, linkp, &h_searched_thread);
650 if(h_searched_thread){
651 if(nt_set_sel_item(app_2ch_model,
652 &h_sel_items_tmp, h_searched_thread, &status_msg)){
653 disp_state = DISP_STATE_RESLIST;
654 nt_2ch_selected_item_release_ref(h_sel_items);
655 h_sel_items = h_sel_items_tmp;
657 free_reslist_ctx(rwinp->data);
661 free_threadlist_ctx(twinp->data);
664 nt_searched_thread_release_ref(h_searched_thread);
665 h_searched_thread = NULL;
668 nt_searched_thread_release_ref(h_searched_thread);
669 h_searched_thread = NULL;
671 if(disp_state != DISP_STATE_SEARCH_THREAD){
675 case DISP_STATE_HISTORY:
676 draw_title(scrp, L"履歴", WA_REVERSE);
678 history_winp = nt_disp_win_alloc(
679 scrp, LINES-1, COLS, 1, 0, buf);
682 history_winp->key = ch;
683 h_searched_thread = NULL;
684 state = disp_history(history_winp, state, app_2ch_model,
685 db_handle, &h_searched_thread, &linkp);
687 nt_read_board_list(linkp);
688 nt_all_link_free(linkp, _2ch_selected_item_free);
692 if(DISP_CMD(state) == DISP_CMD_SEL_THREAD){
693 assert(h_searched_thread);
694 if(nt_set_sel_item(app_2ch_model,
695 &h_sel_items_tmp, h_searched_thread, &status_msg)){
696 nt_2ch_selected_item_release_ref(h_sel_items);
697 h_sel_items = h_sel_items_tmp;
699 free_reslist_ctx(rwinp->data);
703 free_threadlist_ctx(twinp->data);
707 nt_searched_thread_release_ref(h_searched_thread);
708 h_searched_thread = NULL;
709 disp_state = DISP_STATE_RESLIST;
710 state = DISP_STATE_HISTORY;
713 }else if(DISP_CMD(state) == DISP_CMD_REENTER){
716 }else if(DISP_CMD(state) == DISP_CMD_REFRESH){
718 if(history_winp->data){
719 free_history_ctx(history_winp->data);
720 history_winp->data = NULL;
725 if(state != DISP_STATE_HISTORY){
731 case DISP_STATE_FAVORITE:
732 draw_title(scrp, L"お気に入り", WA_REVERSE);
734 favorite_winp = nt_disp_win_alloc(
735 scrp, LINES-1, COLS, 1, 0, buf);
738 favorite_winp->key = ch;
739 h_searched_thread = NULL;
740 if(!favorite_winp->data){
741 linkp = nt_favorite_get_update_board_list(app_2ch_model, h_favorite);
743 nt_read_board_list(linkp);
744 nt_all_link_free(linkp, _2ch_selected_item_free);
747 state = disp_favorite(favorite_winp, state, app_2ch_model,
748 h_favorite, db_handle,
749 &handle, &h_searched_thread);
752 if(DISP_CMD(state) == DISP_CMD_DEL_FAVORITE_BOARD){
753 if(nt_favorite_board_remove(handle)){
754 h_favorite_board = (nt_favorite_board_handle)handle;
756 linkp = nt_link_add_data(NULL,
757 (void*)nt_favorite_board_get_name(h_favorite_board));
759 nt_cloud_delete_lines_from_file(h_cloud, "fb.txt", linkp);
763 nt_favorite_board_release_ref(h_favorite_board);
764 status_msg = NT_INFO_DEL_FAVORITE_SUCCEEDED;
766 status_msg = NT_ERR_MSG_DEL_FAVORITE_FAILED;
768 }else if(DISP_CMD(state) == DISP_CMD_DEL_FAVORITE_THREAD){
769 if(nt_favorite_thread_remove(handle)){
770 h_favorite_thread = (nt_favorite_thread_handle)handle;
773 if(nt_favorite_retrieve_thread(h_favorite_thread, &linkp)){
774 nt_cloud_delete_lines_from_file(h_cloud, "ft.txt", linkp);
775 nt_all_link_free(linkp, free);
778 nt_favorite_thread_release_ref(h_favorite_thread);
779 status_msg = NT_INFO_DEL_FAVORITE_SUCCEEDED;
781 status_msg = NT_ERR_MSG_DEL_FAVORITE_FAILED;
783 }else if(DISP_CMD(state) == DISP_CMD_SEL_BOARD ||
784 DISP_CMD(state) == DISP_CMD_SEL_THREAD){
785 assert(h_searched_thread);
786 if(nt_set_sel_item(app_2ch_model,
787 &h_sel_items_tmp, h_searched_thread, &status_msg)){
788 disp_state = (DISP_CMD(state) == DISP_CMD_SEL_BOARD)
789 ? DISP_STATE_THREADTITLE : DISP_STATE_RESLIST;
790 state = DISP_STATE_FAVORITE;
791 nt_2ch_selected_item_release_ref(h_sel_items);
792 h_sel_items = h_sel_items_tmp;
794 free_reslist_ctx(rwinp->data);
798 free_threadlist_ctx(twinp->data);
802 nt_searched_thread_release_ref(h_searched_thread);
803 h_searched_thread = NULL;
804 }else if(DISP_CMD(state) == DISP_CMD_REFRESH){
805 state = DISP_STATE_FAVORITE;
807 if(favorite_winp->data){
808 free_favorite_ctx(favorite_winp->data);
809 favorite_winp->data = NULL;
811 status_msg = NT_INFO_REFRESH_FAVORITE_SUCCESS;
815 if(DISP_CMD(state) == DISP_CMD_UPLOAD_ALL ||
816 DISP_CMD(state) == DISP_CMD_UPLOAD_BOARDS){
817 status_msg = NT_ERR_MSG_UPLOAD_FAVORITE_FAILED;
818 linkp = nt_favorite_retrieve_boards(h_favorite);
820 if(nt_cloud_upload_file(h_cloud, "fb.txt", linkp)){
821 status_msg = NT_INFO_UPLOAD_FAVORITE_SUCCEEDED;
823 nt_all_link_free(linkp, free);
826 if(DISP_CMD(state) == DISP_CMD_UPLOAD_ALL ||
827 DISP_CMD(state) == DISP_CMD_UPLOAD_THREADS){
828 if(nt_favorite_retrieve_threads(h_favorite,
831 nt_all_link_free(linkp, free);
833 if(nt_cloud_upload_file(h_cloud, "ft.txt", linkp2)){
834 status_msg = NT_INFO_UPLOAD_FAVORITE_SUCCEEDED;
836 nt_all_link_free(linkp2, free);
840 if(DISP_CMD(state) == DISP_CMD_UPLOAD_ALL ||
841 DISP_CMD(state) == DISP_CMD_UPLOAD_NG_FILES){
842 if(nt_ng_word_upload_cloud(h_cloud, h_ng_word)){
843 status_msg = NT_INFO_UPLOAD_FAVORITE_SUCCEEDED;
846 disp_state = state = DISP_STATE_FAVORITE;
848 disp_state = state = DISP_STATE_FAVORITE;
851 }else if(state != DISP_STATE_FAVORITE){
854 state = DISP_STATE_FAVORITE;
857 disp_state = DISP_STATE_FAVORITE;
865 print_error(scrp, status_msg);
869 move(LINES-1,COLS-1);
873 timeout(NT_MAINLOOP_POLLING_INTERVAL);
877 async_data = nt_pthread_get_result_from_que();
878 if(async_data.code == NT_PTHREAD_RESULT_UPDATE_BOARD){
879 ch = NT_KEY_CMD_BOARD_UPDATE;
880 //fprintf(stderr, "Async result recieved.!\n");
881 }else if(async_data.code == NT_PTHREAD_RESULT_UPDATE_FAVORITE){
882 ch = NT_KEY_CMD_FAVORITE_UPDATE;
883 //fprintf(stderr, "Async result recieved.!\n");
885 h_timer = nt_timer_ring_a_bell();
887 switch(nt_timer_get_id(h_timer)){
888 case TIMER_ID_AUTO_SCROLL:
889 ch = NT_KEY_CMD_AUTO_SCROLL;
891 case TIMER_ID_AUTO_UPDATE:
892 linkp = nt_favorite_get_update_board_list(
893 app_2ch_model, h_favorite);
895 nt_read_board_list(linkp);
896 nt_all_link_free(linkp, _2ch_selected_item_free);
897 //fprintf(stderr, "Update request calling.!\n");
901 nt_timer_release_ref(h_timer);
905 }while(ch == '\n' || ch == '\r' || ch == ERR);
918 case NT_KEY_PAGEDOWN:
932 ch = NT_KEY_COMMAND1;
933 nt_add_wch(scrp,ch,0);
936 case NT_KEY_COMMAND1:
937 case NT_KEY_COMMAND2:
938 case NT_KEY_COMMAND3:
943 nt_add_wch(scrp,wch,0);
957 if(h_timer_auto_update)
958 nt_timer_release_ref(h_timer_auto_update);
959 if(h_timer_auto_scroll)
960 nt_timer_release_ref(h_timer_auto_scroll);
962 nt_unload_cookie(cookiep);
964 nt_maru_2ch_free(marup);
966 nt_write_data_release_ref(h_write_data);
967 if(h_searched_thread)
968 nt_searched_thread_release_ref(h_searched_thread);
969 nt_2ch_selected_item_release_ref(h_sel_items);
970 free_board_menu_ctx(bwinp->data);
971 free_threadlist_ctx(twinp->data);
972 free_reslist_ctx(rwinp->data);
974 if(history_winp->data)
975 free_history_ctx(history_winp->data);
976 nt_disp_win_free(history_winp);
979 if(search_winp->data)
980 free_search_thread_ctx(search_winp->data);
981 nt_disp_win_free(search_winp);
984 if(favorite_winp->data)
985 free_favorite_ctx(favorite_winp->data);
986 nt_disp_win_free(favorite_winp);
988 nt_disp_win_free(bwinp);
989 nt_disp_win_free(twinp);
990 nt_disp_win_free(rwinp);
997 static int draw_title(WINDOW *wp, const wchar_t *title, attr_t attr)
1001 num = nt_get_wc_count_within_colmns(title, COLS-1);
1005 nt_add_wnch(wp, L' ', attr, COLS);
1007 nt_add_wnstr(wp, title, WA_REVERSE, COLS - 1);
1013 static void print_error(WINDOW *wp, const wchar_t *msg)
1016 nt_add_wstr(wp, msg, 0);