新聞閱讀工具 V1.1 (newspaper.c)

看板Maple (BBS架站)作者時間22年前 (2002/05/11 02:17), 編輯推噓1(100)
留言1則, 1人參與, 最新討論串1/2 (看更多)
/* 新增了許多的熱鍵,如 F轉寄 ^X轉錄 ^Z 還有閱讀時將與一般閱讀文章時所預設按鍵 相符合。 也稍微把一些地方做了美化(如標題過長會出現"未完"的字樣等),此外於 takenews.c 中抓新聞時由於沒有判定要抓多長,所以有些標題過長新聞可能會導至 head 的 title 部份變二行,本來想要在 newspaper.c 中做判定的,但後來還是覺得 在 takenews.c 中做判定比較治本,至於判定方法目前還沒寫,以後有空再加了 :p */ /*-------------------------------------------------------*/ /* newspaper.c */ /*-------------------------------------------------------*/ /* author : kenshieh.bbs@bbs.ntit.edu.tw */ /* target : 新聞閱讀工具 */ /* create : 2002/01/19 */ /*-------------------------------------------------------*/ #include "bbs.h" #define NEWS_PAGE 12 /* 一頁新聞筆數 */ #define mouts(y, x, s) { move(y, x); outs(s); } static int x, y, z; static int class_name; /* 記錄 news_class 的第幾筆 */ static int news_class[10] = {NEWS_UDN, NEWS_CTNEWS, NEWS_TWDAILY, NEWS_REUTERS, NEWS_CNA, NEWS_FTV, NEWS_PNN, NEWS_CNYES, NEWS_ZDNET, NEWS_GREAT }; static char *newsname[4][3] = { {"聯合新聞網","中時電子報","台灣 日報"}, {"路 透 社","中央 新聞","民視 新聞"}, {"勁 報","鉅 亨 網","資 傳 網"}, {"大成報影報","離 開",""} }; static char newsname2[][10] = {"udn", "ctnews", "twdaily", "reuters", "cna", "ftv","pnn", "cnyes", "2dnet", "great"}; static char newsclass2[][15] = {"polity", "realtime", "society", "international","twoshore", "finance", "entertain", "sports", "leisure", "health", "technology"}; static char *newsclass[] = {"政治","即時","社會","國際","兩岸","財經","影視", "體育","生活","健康","科技"}; static int news_neck() { clear(); mouts(0, 9, "\033[37m◢\033[44m \ \033[m"); mouts(1, 9, "\033[1;36;44m 碧海藍天新聞閱\讀工具 v1.1 資料來源:雅虎奇\ 摩新聞 \033[m"); mouts(2, 9, "\033[1;36;44m http://tw.news.yahoo.com/ \ \033[m"); mouts(3, 9, "\033[1;36;44m Designed By kenshieh.bbs@bbs.ntit.edu.tw\ \033[m"); mouts(4, 0, "\033[45m \ [類別選擇] \033[m"); } static void news_mainmenu_title(n_y, o_y, n_x) int n_y; int o_y; int n_x; { int i; if (o_y != n_y) { for (i = 0; i < 3; i++) { move(8 + o_y, 6 + 36 * i); prints("\033[0;37;00m %s \033[m", newsname[o_y][i]); move(8 + n_y, 6 + 36 * i); if (n_x == i) prints("\033[1;37;43m %s \033[m", newsname[n_y][i]); else prints("\033[0;37;00m %s \033[m", newsname[n_y][i]); } } else { for (i = 0; i < 3; i++) { move(8 + n_y, 6 + 36 * i); if (n_x == i) prints("\033[1;37;43m %s \033[m", newsname[n_y][i]); else prints("\033[0;37;00m %s \033[m", newsname[n_y][i]); } } } static int news_mainmenu(maxy, sum) int maxy; int sum; { int cmd; int n_x, n_y, o_x, o_y; o_x = o_y = 0; n_x = x; n_y = y; for (;;) { news_mainmenu_title(n_y, o_y, n_x); o_x = n_x; o_y = n_y; cmd = vkey(); switch (cmd) { case KEY_DOWN: if (n_y < maxy - 1) { n_y++; if (newsname[n_y][n_x] == "") n_y = 0; } else n_y = 0; break; case KEY_UP: if (n_y > 0) n_y--; else { n_y = maxy - 1; while (newsname[n_y][n_x] == "") n_y--; } break; case '\n': x = n_x; y = n_y; class_name = news_class[y * 3 + x]; break; case KEY_RIGHT: if (n_x < 2) { n_x++; if (newsname[n_y][n_x] == "") n_x = 0; } else n_x = 0; break; case KEY_LEFT: if (n_x > 0) n_x--; else { n_x = 2; while (newsname[n_y][n_x] == "") n_x--; } break; case 'q': case 'Q': y = maxy; break; default: break; } if (cmd == '\n' || cmd == 'q' || cmd == 'Q') return ((y * 3 + x) < sum) ? 1 : 2; } } static void news_mainmsg() { move(6, 0); clrtobot(); refresh(); mouts(b_lines, 0, "\033[46m 操作說明 \033[31;47m (↑↓←→) \033[30m選擇\ \033[31m(Enter)\033[30m確定 \033[31m(Q) \033[30m離開 \ \033[m"); } static int news_showmenu() { int i, p; int maxy, sum; news_mainmsg(); i = maxy = sum = 0; /* 計算有幾筆 */ sum = maxy = sizeof(newsname2) / (sizeof(char) * 10); if (maxy % 3) maxy = (maxy / 3) + 1; else maxy = maxy / 3; for (p = 0; p < maxy; p++) for (i = 0; i < 3; i++) { move (8 + p, 6 + 36 * i); prints("\033[0;37;00m %s \033[m", newsname[p][i]); } return news_mainmenu(maxy, sum); } static int news_classmenu_title(pos) int pos; { int i, j; int max, sum; char a; struct tm *btime; time_t now; a = 65; time(&now); btime = localtime(&now); move (6, 18); clrtobot(); prints("\033[1;37m今天為 \033[32m%d \033[37m月 \033[32m%d\ \033[37m日 您目前正閱\讀\033[1;32m%s\033[37m新聞", btime -> tm_mon + 1, btime -> tm_mday, newsname[y][x]); move(8, 2); /* 算有幾筆 */ sum = sizeof(newsclass2) / (sizeof(char) * 15); for (i = 0, j = 1, max = 0; i < sum; i++) { if (class_name & j) { if (pos == max) { prints("\033[1;37;44m%c)%s\033[m ", a, newsclass[i]); z = i; } else prints("\033[m%c)%s\033[m ", a, newsclass[i]); max++; a++; } j <<= 1; } return max; } static int news_article(file, pos) char *file; int pos; { char fpath[64]; takeALL takeall; rec_get(file, &takeall, sizeof(takeALL), pos); sprintf(fpath, ""NEWSHOME"/%s/%s/%s", newsname2[y * 3 + x], newsclass2[z], takeall.file); if (more(fpath, NULL) < 0) { vmsg("此文正在抓取中或者讀取錯誤"); return 0; } return 1; } static void news_mainnews_msg() { outz("\033[46m 操作說明 \033[31;47m (↑↓) \033[30m選擇 \033[31m(Enter )\ \033[30m確定 \033[31m(Q ←) \033[30m離開 (1~n) \033[31m(F)\033[30m轉寄 \033[31m\ (^X)\033[30m轉錄\033[m"); } static void news_mainnews_titleprint(take, pos, mode) takeALL *take; int pos; int mode; /* 0: 印光棒 1: No 光棒 */ { move(10 + ((pos - 1) % NEWS_PAGE), 10); if (!mode) prints("\033[1;37;44m%3d %-50.50s\033[1;33m%8.8s\033[m", pos, take->title, (strlen(take -> title) < 50) ? "" : "[..未完]"); else prints("\033[0;00;00m%3d %-50.50s\033[1;33m%8.8s\033[m", pos, take->title, (strlen(take -> title) < 50) ? "" : "[..未完]"); } static int news_mainnews_title(file, max, n_pos, o_pos, n_y, o_y, mode) char *file; int max; int n_pos; int o_pos; int n_y; int o_y; int mode; /* 1:翻頁 0:不翻*/ { takeALL takeall, ntakeall; if (mode) { int top, i; i = 0; move (10, 0); clrtobot(); top = (n_pos / NEWS_PAGE) * NEWS_PAGE; while (rec_get(file, &takeall, sizeof(takeALL), top) != -1 && i < NEWS_PAGE) { if (i == n_y) news_mainnews_titleprint(&takeall, top + 1, 0); else news_mainnews_titleprint(&takeall, top + 1, 1); top++; i++; } news_mainnews_msg(); } else { rec_get(file, &takeall, sizeof(takeALL), o_pos); news_mainnews_titleprint(&takeall, o_pos + 1, 1); rec_get(file, &ntakeall, sizeof(takeALL), n_pos); news_mainnews_titleprint(&ntakeall, n_pos + 1, 0); } } static int news_forward(file, pos) char *file; int pos; { static char rcpt[64]; char fpath[64], folder[80], *userid, *title; int cc, userno; usint method; takeALL takeall; if (cuser.userlevel & PERM_DENYMAIL) return 0; if (!rcpt[0]) strcpy(rcpt, cuser.email); if (!vget(b_lines, 0, "目的地:", rcpt, sizeof(rcpt), GCARRY)) return 0; userid = cuser.userid; /* 參考 struct.h 之 MQ_UUENCODE / MQ_JUSTIFY */ #define MF_SELF 0x04 #define MF_USER 0x08 userno = 0; if (!mail_external(rcpt)) /* 中途攔截 */ { if (!str_cmp(rcpt, userid)) { method = MF_SELF; } else { if ((userno = acct_userno(rcpt)) <= 0) { sprintf(fpath, "查無此人:%s", rcpt); zmsg(fpath); return 0; } method = MF_USER; } usr_fpath(folder, rcpt, fn_dir); } else { if (not_addr(rcpt)) return 0; method = 0; } rec_get(file, &takeall, sizeof(takeALL), pos); sprintf(fpath, ""NEWSHOME"/%s/%s/%s", newsname2[y * 3 + x], newsclass2[z], takeall.file); title = takeall.title; if (method >= MF_SELF) { HDR mhdr; if ((cc = hdr_stamp(folder, HDR_LINK, &mhdr, fpath)) < 0) return 0; if (method == MF_SELF) { strcpy(mhdr.owner, "[新 聞]"); mhdr.xmode = MAIL_READ | MAIL_NOREPLY; } else { strcpy(mhdr.owner, userid); } strcpy(mhdr.nick, cuser.username); memcpy(mhdr.title, title, sizeof(mhdr.title)); if ((cc = rec_add(folder, &mhdr, sizeof(HDR))) < 0) { zmsg("部份信件無法寄達"); return 0; } } else { if ((cc = bsmtp(fpath, title, rcpt, method)) < 0) zmsg("部份信件無法寄達"); return 0; } if (userno > 0) m_biff(userno); zmsg("寄信完畢"); return 1; } static int news_cross(file, pos) char *file; int pos; { int rc; char xboard[20], fpath[128], xfolder[80], buf[80], buf2[80], title[73]; HDR xpost; takeALL takeall; FILE *fp; if(!HAS_PERM(PERM_POST)) return 0; if (ask_board(xboard, BRD_W_BIT, "\n\n\033[1;33m請挑選適當的看板,切勿轉貼超過三板。\033[m\n\n") && *xboard) { rc = vget(2, 0, "(S)存檔 (Q)取消?[Q] ", buf, 3, LCECHO); if (rc != 's' && rc != 'S') return 0; rec_get(file, &takeall, sizeof(takeALL), pos); sprintf(fpath, ""NEWSHOME"/%s/%s/%s", newsname2[y * 3 + x], newsclass2[z], takeall.file); brd_fpath(xfolder, xboard, fn_dir); if(!(fp = fdopen(hdr_stamp(xfolder, 'A', &xpost, buf), "w"))) return 0; strcpy(buf2,ve_title); strcpy(ve_title, takeall.title); strcpy(buf, currboard); strcpy(currboard, xboard); ve_header(fp); strcpy(currboard, buf); strcpy(ve_title, buf2); fprintf(fp, "※ 本文轉錄自碧海藍天新聞閱\讀系統 ※\n\n"); fprintf(fp, "轉自 Yahoo!Kimo 之 %s 報\n\n", newsname[y][x]); f_suck(fp, fpath); fclose(fp); strcpy(xpost.owner, cuser.userid); strcpy(xpost.nick, cuser.username); memcpy(title, takeall.title, sizeof(title)); sprintf(xpost.title,"[轉貼]%-54.54s", title); rec_add(xfolder, &xpost, sizeof(xpost)); vmsg("轉錄完成"); } return 1; } static int news_mainnews(file, max, z_pos) char *file; int max; int z_pos; { int n_y, o_y, max_y; int pos, o_pos; int cmd, mode, page; n_y = o_y = pos = o_pos = page = mode = 0; for (;;) { /* 判斷是否有翻頁 */ if (o_y == 0 && (pos == max - 1 || pos == ((page + 1) * NEWS_PAGE) - 1)) { mode = 1; n_y = max_y = (pos == max - 1) ? (max <= NEWS_PAGE) ? max - 1 : max % NEWS_PAGE == 0 ? NEWS_PAGE - 1 : max % NEWS_PAGE - 1 : NEWS_PAGE - 1; } else if ((o_y == max_y && n_y == 0) || (pos == 0 && o_pos != pos + 1)) { mode = 1; max_y = (max - pos > NEWS_PAGE) ? NEWS_PAGE - 1 : max - pos - 1; n_y = o_y = 0; } news_mainnews_title(file, max_y, pos, o_pos, n_y, o_y, mode); o_y = n_y; o_pos = pos; cmd = vkey(); if (cmd >= '1' && cmd <= '9') { int opage, num; char buf[6]; buf[0] = cmd; buf[1] = '\0'; vget(b_lines, 0, "跳至第幾項:", buf, sizeof(buf), GCARRY); num = atoi(buf); if (num > max) num = max; opage = page; pos = num - 1; n_y = pos - (pos / NEWS_PAGE * NEWS_PAGE); page = pos / NEWS_PAGE; if (page > opage || page < opage) mode = 1; continue; } switch (cmd) { case KEY_DOWN: if (n_y < max_y) n_y++; else { n_y = 0; if (page < max / NEWS_PAGE) page++; else page = 0; } if (pos < max - 1) pos++; else pos = 0; break; case KEY_UP: if (n_y > 0) n_y--; else { n_y = max_y - 1; if (page > 0) page--; else page = max / NEWS_PAGE; } if (pos > 0) pos--; else pos = max - 1; case KEY_LEFT: case 'q': case 'Q': break; case KEY_RIGHT: case '\n': mode = 1; break; case KEY_PGDN: case ' ': pos += NEWS_PAGE; if (pos > max - 1) { pos = max - 1; n_y = max % NEWS_PAGE == 0 ? NEWS_PAGE - 1 : max % NEWS_PAGE - 1; page = max / NEWS_PAGE; } else page++; mode = 1; break; case KEY_PGUP: pos -= NEWS_PAGE; if (pos < 0) pos = n_y = page = 0; else page--; mode = 1; break; case KEY_HOME: case '0': pos = n_y = page = 0; mode = 1; break; case KEY_END: case '$': pos = max - 1; n_y = max % NEWS_PAGE == 0 ? NEWS_PAGE - 1 : max % NEWS_PAGE - 1; page = max / NEWS_PAGE; mode = 1; break; case 'F': news_forward(file, pos); cmd = '\n'; /* 配合下面 */ mode = 0; break; case Ctrl('X'): news_cross(file, pos); cmd = '\n'; /* 配合下面 */ mode = 0; break; case Ctrl('Z'): every_Z(); break; default: continue; } if (cmd == KEY_LEFT || cmd == 'q' || cmd == 'Q') return 0; else if (cmd == '\n' || cmd == KEY_RIGHT) { if (mode) { if (!news_article(file, pos)) break; } /* 重印一次 */ news_neck(); news_classmenu_title(z_pos); mode = 1; } else if (cmd == KEY_PGDN || cmd == KEY_PGUP || cmd == KEY_END || cmd == '$' || cmd == KEY_HOME || cmd == '0' || cmd == ' ') continue; else mode = 0; } } static void news_class_msg() { mouts(b_lines, 0, "\033[46m 操作說明 \033[31;47m (←→) \033[30m選擇 \ \033[31m(Enter↓)\033[30m確定 \033[31m(Q) \033[30m離開 \ \033[m"); } static void news_printbody(take, pos, num) takeALL *take; int pos; int num; /* 0: 印 title 1: Empty */ { if (!num) { move(10 + pos, 10); prints("\033[m%3d %-50.50s\033[1;33m%8.8s\033[m", pos + 1, take -> title, (strlen(take -> title) < 50) ? "" : "[..未完]"); } else { move(14, 29); prints("\033[1;37;41m 目前尚無新聞 \033[m"); } } static int news_printnews(file) char *file; { int i, max; takeALL takeall; i = max = 0; move(10, 0); clrtobot(); while (rec_get(file, &takeall, sizeof(takeall), i) != -1) { max++; if (i < NEWS_PAGE) news_printbody(&takeall, i, 0); i++; } news_class_msg(); if (i <= 0) { news_printbody(&takeall, i, 1); return 0; } return max; } static void news_fpath(fpath, x, z) char *fpath; int x; int z; { sprintf(fpath, "/home/bbs/news/%s/%s/@class", newsname2[x], newsclass2[z]); } static int news_classmenu() { int n_x, max_x; int max, cmd, a; char fpath[64]; max_x = n_x = max = 0; for (;;) { max_x = news_classmenu_title(n_x); max_x--; news_fpath(fpath, (y * 3 + x), z); max = news_printnews(fpath); cmd = vkey(); switch (cmd) { case KEY_RIGHT: if (n_x < max_x) n_x++; else n_x = 0; break; case KEY_LEFT: if (n_x > 0) n_x--; else n_x = max_x; break; case '\n': case KEY_DOWN: break; case 'Q': case 'q': break; default: /* 鍵入 a(A) ~ z(Z) 直接跳 */ if (cmd >= 65 && cmd <= 65 + max_x) { a = cmd - 65; n_x = a; } else if (cmd >= 97 && cmd <= 97 + max_x) { a = cmd - 97; n_x = a; } break; } if ((cmd == '\n' || cmd == KEY_DOWN) && max > 0) news_mainnews(fpath, max, n_x); else if (cmd == 'q' || cmd == 'Q') return 0; } } int main_news() { int i; x = y = z = 0; i = 0; news_neck(); while (1) { if (!i) i = news_showmenu(); else if(i == 1) i = news_classmenu(); else break; } return 0; } -- / ╭┬╮╭╮ ╭┐╭─╯ ╰┼─┼╯ ╭─┬─╮ | ◤◤╰┼╮├┤ └╯╭─╮ ╭┬╮╭╮ ◢█◣◢◥◣◢◥◣◢◥◣ | d ; ; ╰┴╯╰╯ ╭┐│●╭ ├● ┼╮ ╰─◥◢▉▋◢▉▋◢▉▋◢█ _ ╰┬──╮ └╯│╭╯ ╰┴╯╰┘ ╭◢█◤█▊◤█▊◤█▋◤ ╯──┐ ╭┐│ ╭┬─┬╮ │ │▔ 163.17.132.1─╮ ◥◤\\// ╰───╯ └╯╰└╯ ┴┴─┴┴ ╰╯ ╰╯ bbs.ntit.edu.tw -- ※ Origin: 碧海藍天 <bbs.ntit.edu.tw> ◆ From: 61-216-129-25.hinet-ip.hinet.net

09/09 11:51, , 1F
09/09 11:51, 1F
文章代碼(AID): #yt0wU00 (Maple)
文章代碼(AID): #yt0wU00 (Maple)