作者itoc.bbs@processor.tfcis.org (核心動力) 看板: plan
標題Re: 請問關於雅虎!奇摩的新聞功能
時間動力核心 (2004/02/12 Thu 12:45:28) Updated: 2006/03/17
要先做精華區這篇
[功能] enews-open.c 奇摩新聞轉至看板
: menu.c 適當選單加入
+ "bin/enews.so:main_enews", 0, - M_GAME,
+ "Enews 奇摩新聞",
: theme.h
#define FOOTER_VEDIT \
COLOR1 " %s " COLOR2 " (^Z)說明 (^W)符號 (^L)重繪 (^X)檔案處理 ... \033[m"
+ #define FOOTER_ENEWS \
+ COLOR1 " 奇摩新聞 " COLOR2 " (kj)上下篇 (↑↓←)上下離開 "
+ " "
...
...
#define FEETER_INNBBS \
COLOR1 " 轉信設定 " COLOR2 " (↑/↓)上下 (PgUp/PgDn)上下頁 ... "
+ #define FEETER_ENEWS \
+ COLOR1 " 奇摩新聞 " COLOR2 " (方向)移動 (字母/數字)項目/篇數 " \
+ "(ENTER)瀏覽 (F/x) 轉寄/轉錄 (q)離開 "
: game/Makefile
SO = ..... enews.so
: game/enews.c 新增此程式
/*-------------------------------------------------------*/
/* enews.c ( NTHU CS MapleBBS Ver 3.10 ) */
/*-------------------------------------------------------*/
/* target : Yahoo! 奇摩新聞 */
/* create : 02/01/27 */
/* update : / / */
/* author : itoc.bbs@bbs.tnfsh.tn.edu.tw */
/*-------------------------------------------------------*/
#if 0
本奇摩新聞程式需要配合 enews-open 去抓資料,crontab 如下:
# 每天 10:30AM 4:30PM 抓奇摩新聞
30 10,16 * * * bin/enews-open
要使用 enews-open.c 必須裝有 lynx。
文章檔案放在 run/kimo/
資料來源:Yahoo! 奇摩新聞 http://tw.news.yahoo.com/
#endif
#include "bbs.h"
/*-------------------------------------------------------*/
/* variable */
/*-------------------------------------------------------*/
/* itoc.020129: 目前不支援翻頁,所以每種分類新聞最多也是 16 條而已 */
#define MAX_ENEWS 16 /* 一頁最多有 16 項 */
static char title[MAX_ENEWS][TTLEN + 1]; /* 本分類新聞的所有標題 */
static char xname[MAX_ENEWS][10]; /* 本分類新聞的所有檔案路徑 */
static int maxitem; /* 本分類的共有幾篇 */
extern BCACHE *bshm;
extern void outgo_post(HDR *hdr, char *board);
#define mouts(x,y,s) { move(x, y); outs(s); }
static void
enews_fpath(fpath, kind, fname)
char *fpath;
char kind;
char *fname;
{
sprintf(fpath, "run/kimo/%c/%s", kind, fname);
}
/*-------------------------------------------------------*/
/* E-News 選單 */
/*-------------------------------------------------------*/
static void
enews_item(num, cc)
int num;
int cc;
{
move(6 + num, 0);
clrtoeol();
move(6 + num, 15);
prints(cc == num ? "%2d " COLOR4 " %.*s \033[m" : "%2d %.*s",
num + 1, d_cols + 54, title[num]); /* 太長的截掉 */
}
static void
enews_body(kind, cc)
char kind;
int cc;
{
int num;
if (!maxitem)
return;
for (num = 0; num < maxitem; num++)
enews_item(num, cc);
for (; num < MAX_ENEWS; num++)
{
move(6 + num, 0);
clrtoeol();
}
/* 游標移去所選項的最後 */
num = 20 + strlen(title[cc]);
if (num > 74) /* 太長的截掉 */
num = 74;
move(6 + cc, num);
}
static void
enews_neck(kind, cc)
char kind;
int cc;
{
int i;
char class[12][5] =
{
"政治", "社會", "國際", "兩岸", "財經", "影視",
"體育", "生活", "休閒", "健康", "科技", "新奇"
};
move(4, 0);
clrtoeol();
move(4, 4);
for (i = 'A'; i <= 'L'; i++)
prints(i == kind ? "\033[1;36m%c\033[37;41m%s\033[m " :
"\033[1;36m%c\033[m%s ", i, class[i - 'A']);
enews_body(kind, cc);
}
static void
enews_head(kind, cc)
char kind;
int cc;
{
clear();
mouts(0, 8, "\033[1;37;42m ╔═╮╗ ═══════════════"
"═════════╮ \033[m");
mouts(1, 8, "\033[1;37;42m ║ ║║╭═╮╭ ╮╭═╮ \033[33m"
"雅虎!奇摩新聞\033[37m ║ \033[m");
mouts(2, 8, "\033[1;37;42m ║ ║║╠═╝║║║╰═╮ \033[33m"
"http://tw.news.yahoo.com/\033[37m ║ \033[m");
mouts(3, 8, "\033[1;37;42m ╚═╰╩╩═╩╩╩╩══╯ ══════"
"═════════╯ \033[m");
outf(FEETER_ENEWS);
enews_neck(kind, cc);
}
static void
enews_load(kind)
char kind;
{
char fpath[64];
FILE *fp;
ENEWS enews;
maxitem = 0;
enews_fpath(fpath, kind, ".ENEWS");
if (!(fp = fopen(fpath, "r")))
return;
while (fread(&enews, sizeof(ENEWS), 1, fp) == 1 && maxitem < MAX_ENEWS)
{
strcpy(title[maxitem], enews.title);
strcpy(xname[maxitem], enews.xname);
maxitem++;
}
fclose(fp);
}
/*-------------------------------------------------------*/
/* 其他功能 */
/*-------------------------------------------------------*/
static int /* 回傳最後讀到哪一篇 */
enews_browse(kind, cc)
char kind;
int cc;
{
int key;
char fpath[64];
for (;;)
{
if (cc >= maxitem)
break;
enews_fpath(fpath, kind, xname[cc]);
/* Thor.990204: 為考慮more 傳回值 */
if ((key = more(fpath, FOOTER_ENEWS)) < 0)
break;
if (!key) /* 已讀完 */
key = vkey();
switch (key)
{
case KEY_RIGHT:
case KEY_PGDN:
case KEY_DOWN:
case ' ':
case 'j':
if (cc < maxitem - 1)
{
cc++;
continue;
}
break;
case KEY_UP:
case KEY_PGUP:
case 'k':
if (cc > 0)
{
cc--;
continue;
}
break;
}
break;
}
return cc;
}
static void
enews_cross(kind, cc) /* 提供單篇轉錄到看板 */
char kind;
int cc;
{
int rc, battr, xbno;
char xboard[IDLEN + 1], xfolder[64], fpath[64];
HDR xpost;
if (!cuser.userlevel)
return;
if (ask_board(xboard, BRD_W_BIT, "\n\n\033[1;33m請挑選適當的看板,"
"切勿轉錄超過三板。\033[m\n\n"))
{
rc = vget(2, 0, "(S)存檔 (L)站內 (Q)取消?[Q] ", fpath, 3, LCECHO);
if (rc == 'l' || rc == 's')
{
enews_fpath(fpath, kind, xname[cc]);
brd_fpath(xfolder, xboard, fn_dir);
/* 轉錄新聞就直接原文轉載,但是作者換為自己 */
hdr_stamp(xfolder, HDR_COPY | 'A', &xpost, fpath);
strcpy(xpost.owner, cuser.userid);
strcpy(xpost.nick, cuser.username);
strcpy(xpost.title, title[cc]);
xbno = brd_bno(xboard);
battr = (bshm->bcache + xbno)->battr;
/* Thor.990111: 在可以轉出前, 要check user有沒有轉出的權力? */
if (!HAS_PERM(PERM_INTERNET) || (battr & BRD_NOTRAN))
rc = 'l';
if (rc == 's' && (!(battr & BRD_NOTRAN)))
xpost.xmode = POST_OUTGO;
rec_bot(xfolder, &xpost, sizeof(HDR));
if (rc == 's' && (!(battr & BRD_NOTRAN)))
outgo_post(&xpost, xboard);
btime_update(xbno);
/* Thor.981205: check 被轉的板有沒有列入紀錄? */
if (battr & BRD_NOCOUNT)
{
vmsg("轉錄完成,文章不列入紀錄,敬請包涵。");
}
else
{
cuser.numposts++;
vmsg("轉錄完成");
}
}
}
enews_head(kind, cc);
}
static int
enews_forward(kind, cc) /* 提供單篇轉寄 */
char kind;
int cc;
{
char rcpt[64];
char fpath[64], folder[64], *userid;
int userno, rc;
int method; /* 轉寄到 0:站外 >0:自己 <0:其他站內使用者 */
if (!HAS_PERM(PERM_INTERNET) || HAS_STATUS(STATUS_MAILOVER))
return XO_NONE;
strcpy(rcpt, cuser.email);
if (!vget(b_lines, 0, "目的地:", rcpt, sizeof(rcpt), GCARRY))
return XO_FOOT;
userid = cuser.userid;
userno = 0;
if (!mail_external(rcpt)) /* 中途攔截 */
{
if (!str_cmp(rcpt, userid))
{
/* userno = cuser.userno; */ /* Thor.981027: 寄精選集給自己不通知自己 */
method = 1;
}
else
{
if ((userno = acct_userno(rcpt)) <= 0)
{
zmsg(err_uid);
return XO_FOOT;
}
method = -1;
}
usr_fpath(folder, rcpt, fn_dir);
}
else
{
if (not_addr(rcpt))
{
zmsg(err_email);
return XO_FOOT;
}
method = 0;
}
enews_fpath(fpath, kind, xname[cc]);
if (method) /* 轉寄站內 */
{
HDR mhdr;
hdr_stamp(folder, HDR_COPY, &mhdr, fpath);
if (method > 0) /* 轉寄自己 */
{
strcpy(mhdr.owner, "[精 選 集]");
mhdr.xmode = MAIL_READ | MAIL_NOREPLY;
}
else /* 轉寄其他使用者 */
{
strcpy(mhdr.owner, userid);
}
strcpy(mhdr.nick, cuser.username);
strcpy(mhdr.title, title[cc]);
rc = rec_add(folder, &mhdr, sizeof(HDR));
}
else /* 轉寄站外 */
{
rc = bsmtp(fpath, title[cc], rcpt, 0);
}
if (userno > 0 && rc >= 0)
m_biff(userno);
zmsg(rc < 0 ? "部份信件無法寄達" : "寄信完畢");
enews_head(kind, cc);
return XO_NONE;
}
/*-------------------------------------------------------*/
/* 主程式 */
/*-------------------------------------------------------*/
int
main_enews()
{
int cc, ch;
char kind;
kind = 'A'; /* 分類 */
cc = 0; /* 第幾篇 */
enews_load(kind);
enews_head(kind, cc);
while (ch = vkey())
{
if (ch >= 'a' && ch <= 'l')
{
kind = ch - 32; /* 變大寫 */
cc = 0;
enews_load(kind);
enews_neck(kind, cc);
continue;
}
if (ch >= '1' && ch <= '9')
{
char ans[5];
ans[0] = ch;
ans[1] = '\0';
vget(b_lines, 0, "跳至第幾項:", ans, 4, GCARRY);
outf(FEETER_ENEWS); /* 重繪 feet */
ch = atoi(ans);
if (ch > 0 && ch <= maxitem)
{
enews_item(cc, 12345); /* 重繪原來那行 */
cc = ch - 1;
enews_item(cc, cc);
}
continue;
}
switch (ch)
{
case 'q':
case 'e':
return 0;
case KEY_RIGHT:
kind = kind < 'L' ? kind + 1 : 'A';
cc = 0;
enews_load(kind);
enews_neck(kind, cc);
break;
case KEY_LEFT:
kind = kind > 'A' ? kind - 1 : 'L';
cc = 0;
enews_load(kind);
enews_neck(kind, cc);
break;
case KEY_DOWN:
enews_item(cc, 12345); /* 重繪原來那行 */
cc = cc < maxitem - 1 ? cc + 1 : 0;
enews_item(cc, cc);
break;
case KEY_UP:
enews_item(cc, 12345); /* 重繪原來那行 */
cc = cc > 0 ? cc - 1 : maxitem - 1;
enews_item(cc, cc);
break;
case '\n':
cc = enews_browse(kind, cc);
enews_head(kind, cc);
break;
case '0':
case KEY_HOME:
if (cc != 0)
{
enews_item(cc, 12345); /* 重繪原來那行 */
cc = 0;
enews_item(cc, cc);
}
break;
case KEY_END:
if (cc != maxitem - 1)
{
enews_item(cc, 12345); /* 重繪原來那行 */
cc = maxitem - 1;
enews_item(cc, cc);
}
break;
case 'x':
enews_cross(kind, cc);
break;
case 'F':
if (enews_forward(kind, cc) == XO_FOOT)
outf(FEETER_ENEWS);
break;
}
}
}
--
╭┼ Origin: Maple-itoc˙動力核心 processor.tfcis.org
┼╯ Author: itoc 從 pc512-2.ee.nctu.edu.tw 發表