回精華區
作者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
精華選讀←離開[主題上]主題下(k)上篇(j)下篇S/a搜尋 G串列 TAB精華 ↑↓捲 Pg/Space翻