荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: jjk (你看了帮助没?), 信区: InstallBBS
标  题: SMTH-012 将版面文章转成 HTML 格式?     Lg
发信站: 荔园晨风BBS站 (Wed Dec  5 11:28:51 2001), 站内信件

发信人: Lg (创造人生的传奇), 信区: Linux
标  题: [转载] SMTH-012 将版面文章转成 HTML 格式并压缩打包(转寄)
发信站: BBS 荔园晨风站 (Mon Jun 14 13:10:09 1999), 站内信件

【 以下文字转载自 Lg 的信箱 】
发信人: Leeward (Initializing 92%), 信区: BBSMan_Dev
标  题: SMTH-012 将版面文章转成 HTML 格式并压缩打包
发信站: BBS 水木清华站 (Sun May 23 10:37:08 1999)

本文描述的代码在 FireBird 2.5 和 2.6 上均可使用.

代码由 Leeward 于 1998.01.05 在 BBS 水木清华站 开发并运行.
其后在 1998.08.28 进行了改进.

=========================================================================

代码运行需要调用系统中已经正确安装的 tar 和 gzip 命令.
转换后的文章中, 对 URL 能自动生成 HyperLink.

以下假定 Bhtml.c 是本程序的源文件名, 执行代码是 Bhtml:

编译指令: make Bhtml

运行指令: 首先进入要处理的版面的磁盘目录内,
          然后调用 Bhtml (假定 Bhtml 位于/home/bbs/bin):
          /home/bbs/bin/Bhtml [-aAuthor] [-tTitle] [-dDay] [-sStart] [-eEnd]

运行参数: -a 指定只处理某一作者的文章; -t 指定只处理某一主题的文章;
          -d 指定只处理最近若干天内的文章, -s 指定从第几篇文章开始处理;
          -e 指定只处理到第几篇文章.

          以上参数可以复合使用; 如果什么参数也不跟, 则处理全部文章.

运行举例:
1. 将所有的文章转成 HTML 格式并压缩打包:
                 /home/bbs/bin/Bhtml
2. 将所有最近 7 天的文章转成 HTML 格式并压缩打包:
                 /home/bbs/bin/Bhtml -d7
3. 将所有 Leeward 的最近 7 天的文章转成 HTML 格式并压缩打包:
                 /home/bbs/bin/Bhtml -aLeeward -d7
4. 将从第1000到2000篇文章中所有标题是 test 的文章转成 HTML 格式并压缩打包:
                 /home/bbs/bin/Bhtml -s1000 -e2000 -ttest

可以使用 cron 来完成很多版面的文章的定期自动处理,
并且放置到 WWW 页面中以便下载.

可以直接在 http://bbs.net.tsinghua.edu.cn/BBSMan_Dev/Bhtml.c 下载本文中的代码.

否则, 建议将本文转寄到电子邮件信箱, 再保存并编译.
如果用 telnet 方式直接 Copy/Paste 文中的代码, 可能导致因行长超过 80 字符
而折行从而出现编译错误:-P

=========================================================================

/* Making articles in a board into HTML format and then compress them.       */
/*                                                                           */
/* Leeward 1998.01.05 (Modified 1998.08.28)                                  */
/*                                                                           */
/* This little program scans a board's directory for its articles            */
/* and converts all of them into HTML format new files                       */
/* and finally compress the new into a UNIX tgz format package.              */
/*                                                                           */
/* Also this program duplicates all source files and renames all of them     */
/* into digital MS-DOS 8.3 format file names (avoiding easily re-produce).   */
/*                                                                           */
/* Build:                                                                    */
/*        make Bhtml                                                         */
/* Syntax:                                                                   */
/*        Bhtml [-aAuthor] [-tTitle] [-dDay] [-sStart] [-eEnd]               */
/*                                                                           */
/* Known shortcomings: do not check if disk space is enough                  */
/*                                                                           */


#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <sys/stat.h>


#define MAXSTRLEN 8192
#define STRLEN 80

#define DOTDIR ".DIR"
#define ROOTHTML "index.htm"
#define INDEXHTML "AIXindex.htm"
#define FRAMENAME "SMTHBAIX"

#define HEADER "BBS水木清华站∶讨论区"
#define FOOTER "BBS水木清华站∶讨论区"


struct fileheader { /* This structure is used to hold data in */
        char filename[STRLEN];          /* the DIR files */
        char owner[STRLEN];
        char title[STRLEN];
        unsigned level;
        unsigned char accessed[12];   /* struct size = 256 bytes */
} ;
typedef struct fileheader fileheader;

/* Leeward 98.08.28: Do not process those boards not public */
#define XBOARDNUM 6
char Xboard[XBOARDNUM][24] = { "deleted", "junk", "syssecurity", "Registry",
                               "sys_discuss", "Filter"};

int
main(int argc, char **argv)
{
  FILE *fpDOTDIR, *fpIn, *fpOut, *fpIndex;
  char szBuf[MAXSTRLEN], szBufX[MAXSTRLEN], *ptr, szBoard[48], szAuthor[48] =
"", szTitle[128] = "";
  int nArticle, i, j, k, nStart = 0, nEnd = 20480, nDay = -1, nTotal = 0;
  fileheader FH;


  printf("This application creates compressed HTML package for BBS.\n");


  printf("Initializing...\n");
  getcwd(szBuf, MAXSTRLEN);
  for (i = 0; i < XBOARDNUM; i ++)
  {
    ptr = strrchr(szBuf, '/');
    ptr = ptr ? ptr + 1 : szBuf;
    if (!strcmp(ptr, Xboard[i]))
    {
      printf("Board \"%s\" forbidden\n", ptr);
      exit(-4);
    }
  }
  for (i = 1; i < argc; i ++)
  {
    if (!strncasecmp(argv[i], "-d", 2))
    {
      sscanf(argv[i], "-d%d", &nDay);
    }
    else if (!strncasecmp(argv[i], "-s", 2))
    {
      sscanf(argv[i], "-s%d", &nStart);
    }
    else if (!strncasecmp(argv[i], "-e", 2))
    {
      sscanf(argv[i], "-e%d", &nEnd);
    }
    else if (!strncasecmp(argv[i], "-a", 2))
    {
      sscanf(argv[i], "-a%24s", szAuthor);
    }
    else if (!strncasecmp(argv[i], "-t", 2))
    {
      sscanf(argv[i], "-t%96s", szTitle);
    }
    else
    {
      printf("Syntax: Bhtml [-aAuthor] [-tTitle] [-dDay] [-sStart] [-eEnd]\n");
      exit(1998);
    }
  }

  if (nDay < 0)
    nDay = - 1;
  if (nStart < 0)
    nStart = 0;
  if (nEnd < nStart)
    nEnd = nStart;

  printf("Executing: %s -a%s -t%s -d%d -s%d -e%d...\n", argv[0], szAuthor,
szTitle, nDay, nStart, nEnd);


  getcwd(szBuf, MAXSTRLEN);
  ptr = strrchr(szBuf, '/');
  if (NULL == ptr)
  {
    printf("Directory error?\n");
    exit(-1);
  }
  else
    strcpy(szBoard, ptr + 1);


  sprintf(szBuf, "rm -fr %s.AIX", szBoard);
  system(szBuf);
  sprintf(szBuf, "%s.AIX", szBoard);
  if (0 == chdir(szBuf))
  {
    printf("Can not erase %s\n", szBuf);
    exit(-3);
  }

  if (mkdir(szBuf, 0000755)) /* drwxr-xr-x */
  {
    printf("Can not create %s\n", szBuf);
    exit(-2);
  }


  fpDOTDIR = fopen(DOTDIR, "rb");
  if (NULL == fpDOTDIR)
  {
    printf("%s not found\n", DOTDIR);
    exit(1);
  }

  sprintf(szBuf, "%s.AIX/%s", szBoard, INDEXHTML);
  fpIndex = fopen(szBuf, "wt");
  if (NULL == fpIndex)
  {
    printf("Cannot create %s\n", szBuf);
    exit(2);
  }

  fseek(fpDOTDIR, 0L, 2);
  nArticle = ftell(fpDOTDIR) / sizeof(fileheader);
  printf("Currently total %d articles found\n", nArticle);
  rewind(fpDOTDIR);

  fprintf(fpIndex, "<HTML>\n<HEAD>\n  <TITLE>%s</TITLE>\n</HEAD>\n\n<BODY>
\n<CENTER>\n\n<H2>%s - %s</H2>\n</CENTER>\n\n", HEADER, HEADER, szBoard);

  for (i = 0; i < nArticle; i ++)
  {
    fread(&FH, sizeof(fileheader), 1, fpDOTDIR);

    if (i + 1 < nStart)
      continue;
    if (i + 1 > nEnd)
      break;
    if (nDay >= 0)
    {
      struct stat st;
      time_t      timeCurrent;
      struct tm   *ptm;

      timeCurrent = time(NULL);
      ptm = localtime(&timeCurrent);
      ptm->tm_hour = 23;
      ptm->tm_min = ptm->tm_sec = 59;
      timeCurrent = mktime(ptm);

      stat(FH.filename, &st);
      if (difftime(timeCurrent, st.st_mtime) > (double)(nDay + 1) * 3600 * 24)
        continue;
    }
    if (szAuthor[0])
    {
      if (strcmp(szAuthor, FH.owner))
        continue;
    }
    if (szTitle[0])
    {
      if ( !(  (   !strncasecmp(FH.title, "Re: ", 4)
                && !strcmp( 4 + FH.title, szTitle  )
               )
            || (   !strcmp(     FH.title, szTitle  )
               )
            )
         )
        continue;
    }

    printf("Processing article No.%08d: %s...\n", i + 1, FH.filename);

    fpIn = fopen(FH.filename, "rt");
    if (NULL == fpIn)
    {
      printf("%s not found!!!\n", FH.filename);
      continue;
      /*fclose(fpIndex);
      fclose(fpDOTDIR);
      exit(3);*/
    }

    sprintf(szBuf, "%s.AIX/%08d.htm", szBoard, i);
    fpOut = fopen(szBuf, "wt");
    if (NULL == fpOut)
    {
      printf("Cannot create %s\n", szBuf);
      fclose(fpIndex);
      fclose(fpDOTDIR);
      exit(4);
    }

    nTotal ++;
    fprintf(fpOut, "<HTML>\n<HEAD>\n  <TITLE>%s - %s</TITLE>\n</HEAD>\n<BODY>
\n\n", HEADER, szBoard);

    while (!feof(fpIn))
    {
      fgets(szBuf, MAXSTRLEN, fpIn);
      if (feof(fpIn))
        break;

      if ('\n' == szBuf[strlen(szBuf) - 1])
        szBuf[strlen(szBuf) - 1] = ' ';
      if (!strncmp(szBuf, "标  题:", 7))
        szBuf[2] = szBuf[3] = 161;
      else if (!strncmp(szBuf, "来  源:", 7))
        szBuf[2] = szBuf[3] = 161;

      for (j = 0; szBuf[j]; j ++)
      {
        if (ptr = strchr(szBuf + j, '@'))
        {
          j = ptr - szBuf;
          if (strchr(ptr, '.'))
          {
            if (strchr(ptr, ' ') - strchr(ptr, '.') > 0)
            {
              for (k = j - 1; k >= 0; k --)
                if (!(  (szBuf[k] >= '0' && szBuf[k] <= '9')
                      ||(szBuf[k] >= 'A' && szBuf[k] <= 'Z')
                      ||(szBuf[k] >= 'a' && szBuf[k] <= 'z')
                      || '.' == szBuf[k])  )
                  break;

              strcpy(szBufX, szBuf + k + 1);
              sprintf(szBuf + k + 1, "mailto:%s", szBufX);
              ptr += 7; /* strlen("mailto:") */
              j = strchr(ptr, ' ') - szBuf - 1;
            } /* End if (strchr(ptr, ' ') - strchr(ptr, '.') > 0) */
          } /* End if (strchr(ptr, '.')) */
        } /* End if (ptr = strchr(szBuf + j, '@')) */
      } /* for (j = 0; szBuf[j]; j ++) */


      for (j = szBufX[0] = 0; szBuf[j]; j ++)
      {
        switch (szBuf[j])
        {
          case '>':
            strcat(szBufX, "&gt;");
          break;

          case '<':
            strcat(szBufX, "&lt;");
          break;

          case '&':
            strcat(szBufX, "&amp;");
          break;

          case '"':
            strcat(szBufX, "&quot;");
          break;

          case ' ':
            strcat(szBufX, "&nbsp;");
          break;

          case 27:
            ptr = strchr(szBuf + j, 'm');
            if (ptr)
              j = ptr - szBuf;
          break;

          case 'h':
          case 'H':
          case 'f':
          case 'F':
          case 'n':
          case 'N':
          case 'm':
          case 'M':
            if (!strncasecmp(szBuf + j, "http://", 7)
            ||  !strncasecmp(szBuf + j, "ftp://",  6)
            ||  !strncasecmp(szBuf + j, "news://", 7)
            ||  !strncasecmp(szBuf + j, "mailto:", 7))
            {
              ptr = strchr(szBuf + j, ' ');

              if (ptr)
              {
                *ptr = 0;
                k = strlen(szBufX);
                sprintf(szBufX + k, "<A HREF=\"%s\">%s</A>", szBuf + j, szBuf +
j + 7 * (!strncasecmp(szBuf + j, "mailto:", 7)));
                *ptr = ' ';
                j += ptr - (szBuf + j) - 1;
                break;
              }
            }
            /* no break here ! */

          default:
            szBufX[k = strlen(szBufX)] = szBuf[j];
            szBufX[k + 1] = 0;
        }
      }

      if (':' == szBuf[0])
        sprintf(szBuf, "∶<I>%s</I><BR>\n", szBufX + 1);
      else if ('>' == szBuf[0])
        sprintf(szBuf, "><I>%s</I><BR>\n", szBufX + 4);
      else
        sprintf(szBuf, "%s<BR>\n", szBufX);

      fputs(szBuf, fpOut);
    }

    fprintf(fpOut, "\n</BODY>\n</HTML>\n");
    fclose(fpIn);
    fclose(fpOut);

    fprintf(fpIndex, "No.%d&nbsp;&nbsp;<A HREF=\"%08d.htm\" TARGET=\"%s\">%s
</A>&nbsp;&nbsp;&nbsp;&nbsp;&lt;%s&gt;<BR>\n", i + 1, i, FRAMENAME, FH.title,
FH.owner); /* Do NOT erase the appended ' ' after the 2nd %s ! (for IE 4) */
  }

  fprintf(fpIndex, "\n<CENTER>\n<HR>\n<H2>%s - %s</H2>\n</CENTER>\n\n</BODY>
\n</HTML>\n", FOOTER, szBoard);

  fclose(fpIndex);
  fclose(fpDOTDIR);


  sprintf(szBuf, "%s.AIX/%s", szBoard, ROOTHTML);
  fpIndex = fopen(szBuf, "wt");
  if (NULL == fpIndex)
  {
    printf("Cannot create %s\n", szBuf);
    exit(5);
  }

  fprintf(fpIndex, "<HTML>\n  <TITLE>%s - %s</TITLE>\n\n<FRAMESET ROWS=25%,75%>
\n  <FRAME SRC=\"%s\" FRAMEBORDER=1>\n  <FRAME SRC=\"null.htm\" NAME=\"%s\"
FRAMEBORDER=0>\n</FRAMESET>\n\n</HTML>\n", HEADER, szBoard, INDEXHTML,
FRAMENAME);

  fclose(fpIndex);


  sprintf(szBuf, "%s.AIX/null.htm", szBoard);
  fpIndex = fopen(szBuf, "wt");
  if (NULL == fpIndex)
  {
    printf("Cannot create %s\n", szBuf);
    exit(5);
  }

  fprintf(fpIndex, "<HTML>\n<BODY>\n<CENTER><BR>\n<H2>阅读本版文章</H2><BR>
\n<H2>请点击上面窗口内的文章标题</H2></CENTER>\n</BODY>\n</HTML>\n");

  fclose(fpIndex);


  printf("Compressing HTML files...\n");
  printf("Calling tar...\n");
  sprintf(szBuf, "%s.board.html.tar", szBoard);
  unlink(szBuf);
  sprintf(szBuf, "tar cf %s.board.html.tar %s.AIX", szBoard, szBoard);
  system(szBuf);
  printf("Calling gzip...\n");
  sprintf(szBuf, "%s.board.html.tar.gz", szBoard);
  unlink(szBuf);
  sprintf(szBuf, "gzip %s.board.html.tar", szBoard);
  system(szBuf);

  sprintf(szBuf, "rm -fr %s.AIX", szBoard);
  system(szBuf);
  sprintf(szBuf, "%s.AIX", szBoard);
  if (0 == chdir(szBuf))
  {
    printf("Can not erase %s\n", szBuf);
    exit(-3);
  }

  sprintf(szBuf, "mv -f %s.board.html.tar.gz %s.board.html.tgz", szBoard,
          szBoard);
  system(szBuf);


  printf("Finished Bhtml: %s.board.html.tgz (Total %d articles, %d files)\n",
          szBoard, nTotal, nTotal + 3);
  return 0;
}

--
※ 修改:·Leeward 於 May 23 10:56:58 修改本文·[FROM:  202.112.58.200]
※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 202.112.58.200]


※ 修改:·jjk 於 Dec  5 11:32:54 修改本文·[FROM: 192.168.0.146]
※ 转载:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.0.146]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店