作者itoc, 信區: itoc
標題[功能] topscore.c 文章評分排行榜
時間04/09/07
作者: itoc (test) 看板: plan
標題: [功能] 文章評分功能
時間: Sun Aug 18 14:45:05 2002 Updated: 2005/05/19
評分排行榜
: crontab -e
# 每天做一次排行榜統計
28 3 * * * bin/topgem > /dev/null 2>&1
30 3 * * * bin/topsong > /dev/null 2>&1
+ 32 3 * * * bin/topscore > /dev/null 2>&1
34 3 * * * bin/topusr > /dev/null 2>&1
: BBS 站上 (A)nnounce 裡面的 {排行} 統計資料
Ctrl+P 新增 (D)資料
標題:評分次數統計
檔名:-topscore
: src/util/Makefile 加入 topscore
TOOL = ... \
... \
... topgem topscore topsong ...
: src/util/topscore.c 新增這程式,內容如下
/*-------------------------------------------------------*/
/* util/topscore.c ( NTHU CS MapleBBS Ver 3.10 ) */
/*-------------------------------------------------------*/
/* target : 文章評分排名 */
/* create : 03/04/26 */
/* update : / / */
/* author : itoc.bbs@bbs.tnfsh.tn.edu.tw */
/*-------------------------------------------------------*/
/* syntax : topscore */
/*-------------------------------------------------------*/
#include "bbs.h"
#define FN_RUN_SCOREUSIES "run/score_usies" /* 評分記錄 */
#define OUTFILE_TOPSCORE "gem/@/@-topscore"
typedef struct
{
char brdname[BNLEN + 1];
char owner[IDLEN + 1];
char title[TTLEN + 1];
char score;
} SCOREDATA;
/*-------------------------------------------------------*/
/* 把所有被評分的文章找出來 */
/*-------------------------------------------------------*/
static void
do_find(brdname)
char *brdname;
{
int i, size, fd;
char fpath[64];
struct stat st;
HDR *hdr;
SCOREDATA score;
time_t due;
brd_fpath(fpath, brdname, FN_DIR);
if ((fd = open(fpath, O_RDONLY)) >= 0)
{
fstat(fd, &st);
size = st.st_size;
hdr = (HDR *) malloc(size);
read(fd, hdr, size);
close(fd);
due = time(NULL) - 86400 * 10; /* 最多統計到十天前的文章 */
size /= sizeof(HDR);
for (i = 0; i < size; i++)
{
if (hdr[i].score > 0 && hdr[i].chrono >= due)
{
strcpy(score.brdname, brdname);
strcpy(score.owner, hdr[i].owner);
strcpy(score.title, hdr[i].title);
score.score = hdr[i].score;
rec_add(FN_RUN_SCOREUSIES, &score, sizeof(SCOREDATA));
}
}
free(hdr);
}
}
/*-------------------------------------------------------*/
/* 製作排名 */
/*-------------------------------------------------------*/
static void
write_data(score, num)
SCOREDATA *score;
int num;
{
int n;
FILE *fp;
if (!(fp = fopen(OUTFILE_TOPSCORE, "w")))
return;
fprintf(fp, "\033[37m名次\033[36m─\033[37m看板\033[36m────"
"\033[37m作者\033[36m─────\033[37m標 題\033[36m────"
"─────────────\033[37m分數\033[36m─\033[m\n");
for (n = 0; n < 50 && n < num; n++) /* 只取前 50 名 */
{
fprintf(fp, "%3d. %-13.13s%-13.13s%-38.38s %4d 次\033[m\n",
n + 1, score[n].brdname, score[n].owner, score[n].title, score[n].score);
}
fclose(fp);
}
static int
count_cmp(b, a)
SCOREDATA *a, *b;
{
return (a->score - b->score);
}
int
main()
{
int fd, size;
struct stat st;
SCOREDATA *score;
BRD brd;
chdir(BBSHOME);
unlink(FN_RUN_SCOREUSIES);
size = 0;
while (!rec_get(FN_BRD, &brd, sizeof(BRD), size))
{
if ((brd.readlevel | brd.postlevel) < (PERM_VALID << 1)) /* 隱藏板不統計 */
do_find(brd.brdname);
size++;
}
if ((fd = open(FN_RUN_SCOREUSIES, O_RDWR)) < 0)
return 0;
if (!fstat(fd, &st) && (size = st.st_size) >= sizeof(SCOREDATA))
{
score = (SCOREDATA *) malloc(size);
size = read(fd, score, size);
qsort(score, size / sizeof(SCOREDATA), sizeof(SCOREDATA), count_cmp);
lseek(fd, 0, SEEK_SET);
write(fd, score, size);
ftruncate(fd, size);
write_data(score, size / sizeof(SCOREDATA));
free(score);
}
close(fd);
return 0;
}
--
□ Origin: 動力核心 xeon.tfcis.org □ From: itoc.Dorm-GD2.NCTU.edu.tw