回精華區
作者amaki.bbs@luna.twbbs.org (招喚阿某的羊) 看板: plan
標題Re: [功能]全球搜尋
時間月下夜想 (Fri, 19 Sep 2003 04:19:51 +0800 (CST)) Updated: 2003/09/19
  超適合水球王的功能,如果你為了在一堆水球裡找電話苦惱、如果你為了在一堆水球裡

  找某個關鍵字苦惱,在水球列表下,按 f 鍵,將會自動找出

  含有該特定關鍵字的所有水球,連id也一併找。

  完整版的水球搜尋功能,bmw_item()部分是頗吃資源的東西,不一定要換,如果站夠小

  機器夠Power,那就換吧!


: bmw.c

  bmw_item()換成下面那隻,要讓水球裡的關鍵字變色的bmw_item()就是這樣。

  如果怕日後維護困難(指標飛來飛去的三天後我一定會忘記我自己在寫什麼,所以這點

  站長自己要有備案以防萬一),就把舊的bmw_item()用#if 0包起來,留著日後用。


+ static char out_hunt[32], out_lunt[32];

static void
bmw_item(num, bmw)    /* amaki.030915: 具備變色功能的bmw_item */
  int num;
  BMW *bmw;
{
  char *str, *ptr;
  int hunt_len, msg_len, leftover = 0;

  struct tm *ptime = localtime(&bmw->btime);

  msg_len = strlen(bmw->msg);
  hunt_len = strlen(out_hunt);

  if (bmw->sender == cuser.userno)      /* 送出的水球 */
  {
    if (*out_hunt == '\0')
      prints("%6d %-13s%-53.53s\033[33m%02d:%02d\033[m\n",
        num, bmw->userid, bmw->msg, ptime->tm_hour, ptime->tm_min);
    else
    {
      /* amaki.030915: 先印id */
      prints("%6d %-13s", num, bmw->userid);

      /* amaki.030915: 再印水球內容 */
      if (str = str_str(bmw->msg, out_lunt))
      {
        prints("%.*s\033[7m%.*s\033[m",
          str - bmw->msg, bmw->msg, hunt_len, str);

        if (str + hunt_len < bmw->msg + msg_len)
        {
          str += hunt_len;
          while (1)
          {
            if (ptr = str_str(str, out_lunt))
              prints("%.*s\033[7m%.*s\033[m", ptr - str, str, hunt_len, ptr);
            else
            {
              leftover = 53 - (str - bmw->msg);
              prints("%-*.*s\033[33m%02d:%02d\033[m\n",
                leftover, leftover, str, ptime->tm_hour, ptime->tm_min);
              break;
            }

            if (ptr + hunt_len < bmw->msg + msg_len)
              str = ptr + hunt_len;
            else if (ptr + hunt_len >= bmw->msg + msg_len)
            {
              leftover = 53 - (str - bmw->msg);
              if (ptr + hunt_len != bmw->msg + msg_len)
                prints("%-*.*s\033[33m%02d:%02d\033[m\n",
                  leftover, leftover, str, ptime->tm_hour, ptime->tm_min);
              break;
            }
          }
        }
        else
        {
          leftover = 53 - (str - bmw->msg) - hunt_len;
          prints("%-*.*s\033[33m%02d:%02d\033[m\n",
            leftover, leftover, " ", ptime->tm_hour, ptime->tm_min);
        }
      }
      else
        prints("%-53.53s\033[33m%02d:%02d\033[m\n",
          bmw->msg, ptime->tm_hour, ptime->tm_min);
    }
  }
  else                                  /* 收到的水球 */
  {
    if (*out_hunt == '\0')
    {
      prints("%6d \033[1;33m%-13s\033[37;46m%-53.53s\033[33m%02d:%02d\033[m\n",
        num, bmw->userid, bmw->msg, ptime->tm_hour, ptime->tm_min);
    }
    else
    {
      /* amaki.030915: 先印id */
      prints("%6d \033[1;33m%-13s\033[37;46m", num, bmw->userid);

      /* amaki.030915: 再印水球內容 */
      if (str = str_str(bmw->msg, out_lunt))
      {
        prints("%.*s\033[7m%.*s\033[7m",
          str - bmw->msg, bmw->msg, hunt_len, str);

        if (str + hunt_len < bmw->msg + msg_len)
        {
          str += hunt_len;
          while (1)
          {
            if (ptr = str_str(str, out_lunt))
              prints("%.*s\033[7m%.*s\033[7m", ptr - str, str, hunt_len, ptr);
            else
            {
              leftover = 53 - (str - bmw->msg);
              prints("%-*.*s\033[33m%02d:%02d\033[m\n",
                leftover, leftover, str, ptime->tm_hour, ptime->tm_min);
              break;
            }

            if (ptr + hunt_len < bmw->msg + msg_len)
              str = ptr + hunt_len;
            else if (ptr + hunt_len >= bmw->msg + msg_len)
            {
              leftover = 53 - (str - bmw->msg);
              if (ptr + hunt_len != bmw->msg + msg_len)
                prints("%-*.*s\033[33m%02d:%02d\033[m\n",
                  leftover, leftover, str, ptime->tm_hour, ptime->tm_min);
              break;
            }
          }
        }
        else
        {
          leftover = 53 - (str - bmw->msg) - hunt_len;
          prints("%-*.*s\033[33m%02d:%02d\033[m\n",
            leftover, leftover, " ", ptime->tm_hour, ptime->tm_min);
        }
      }
      else
        prints("%-53.53s\033[33m%02d:%02d\033[m\n",
          bmw->msg, ptime->tm_hour, ptime->tm_min);
    }
  }
}


  在bmw_load()後新增下這一隻函式。


extern KeyFunc bmw_cb[];

/* amaki.030915: 提供全"球"搜尋:p */

+ static int bmw_time;


static int
bmw_hunt(xo)
  XO *xo;
{
  char fpath[64], fn_tmp[64], *ptr;
  int fd, fb, i = 0, j = 0;
  BMW bmw;

  usr_fpath(fpath, cuser.userid, "bmw_n");
  strcpy(fn_tmp, xo->dir);

  if ((fd = open(xo->dir, O_RDONLY, 0600)) < 0)
  {
    zmsg("無法開啟水球檔案");
    return XO_FOOT;
  }

  if (dashf(fpath)) /* amaki.030915: 刪除舊的 */
    unlink(fpath);

  if ((fb = open(fpath, O_RDWR | O_CREAT, 0600)) < 0)
  {
    zmsg("無法開啟水球檔案");
    return XO_FOOT;
  }

  if (!vget(b_lines, 0, "水球關鍵字搜尋:", out_hunt, sizeof(out_hunt), DOECHO))
    return XO_FOOT;

  str_lower(out_lunt, out_hunt);

  lseek(fd, (off_t) (sizeof(BMW) * i), SEEK_SET);
  lseek(fb, (off_t) (sizeof(BMW) * j), SEEK_SET);
  while (read(fd, &bmw, sizeof(BMW)))
  {
    if ((ptr = str_str(bmw.msg, out_lunt)) ||
      (ptr = str_str(bmw.userid, out_lunt)))
    {
      write(fb, &bmw, sizeof(BMW));
      j++;
      lseek(fb, (off_t) (sizeof(BMW) * j), SEEK_SET);
    }
    i++;
    lseek(fd, (off_t) (sizeof(BMW) * i), SEEK_SET);
  }
  close(fd);
  close(fb);

  xz[XZ_BMW - XO_ZONE].xo = xo_new(fpath);
  xz[XZ_BMW - XO_ZONE].cb = bmw_cb;
  xover(XZ_BMW);
  xz[XZ_BMW - XO_ZONE].xo = xo_new(fn_tmp);
  xz[XZ_BMW - XO_ZONE].cb = bmw_cb;


 /* amaki.030915: 再開一次檔,別愚蠢到把上一個fd留到這裡用,使用這功能的user */
 /* 一多會讓硬碟等待處理的堆疊很快爆掉 */
  if ((fd = open(xo->dir, O_RDONLY, 0600)) < 0)
  {
    zmsg("無法開啟水球檔案");
    return XO_FOOT;
  }
  i = 0;
  lseek(fd, (off_t) (sizeof(BMW) * i), SEEK_SET);
  while (read(fd, &bmw, sizeof(BMW)))
  {
    if (bmw.btime == bmw_time)
    {
      xo->pos = i;
      break;
    }
  /* amaki.030915: 這有可能發生嗎?難道水球跑到另一個宇宙去了?非也,萬一分 */
  /* 身砍水球,就有可能找不到,為節省效率早早跳出來 */
    else if (bmw.btime > bmw_time)
      break;

    i++;
    lseek(fd, (off_t) (sizeof(BMW) * i), SEEK_SET);
  }
  close(fd);

  unlink(fpath);
  memset(out_hunt, 0, sizeof(out_hunt));
  memset(out_lunt, 0, sizeof(out_lunt));

  return XO_INIT;
}


  改bmw_query()

  bmw = (BMW *) xo_pool + (xo->pos - xo->top);
  /* amaki.030915: 紀錄下水球的時間,整數,跟hdr->xid有相同功用,就算有兩 */
  /* 顆同時出現的水球也無妨,跳出來時雖不中亦不遠矣 */
+ bmw_time = bmw->btime;
  move(1, 0);


  改bmw_cb[]

  'D', bmw_rangedel,
+ 'f', bmw_hunt,
  'm', bmw_mail,

: bbsd.c : u_exit()


#ifdef MODE_STAT
  log_modes();
#endif

+ usr_fpath(fpath, cuser.userid, "bmw_n");
+ if (dashf(fpath))
+   unlink(fpath);

  /* 寫回 .ACCT */

--
  Origin: luna.twbbs.org
精華選讀←離開[主題上]主題下(k)上篇(j)下篇S/a搜尋 G串列 TAB精華 ↑↓捲 Pg/Space翻