home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / ckscripts / ksitemap < prev    next >
Text File  |  2020-01-01  |  15KB  |  331 lines

  1. #!/net/u/1/f/fdc/kermit/wermit +
  2. #
  3. # ksitemap - sitemap.xml file constructor
  4. #
  5. .version = 1.03         # Version of this script
  6. .testingdest = ~/tmp/   # Result directory for testing - change if necessary
  7. #
  8. # Builds a sitemap.xml file for a website, with Google image extensions.
  9. # Requires: C-Kermit 9.0 Alpha.03 or later.
  10. # This file should be stored with execute permission.
  11. # Top line must give full pathname of C-Kermit 9.0 executable.
  12. #
  13. # Documentation: http://www.kermit.edu/ksitemap.html
  14. #
  15. # Optional command-line argument: path of filelist file.  If the argument is
  16. # given the web directory is assumed to be the same directory where the
  17. # filelist is.  If not given, a file named "filelist" in the current directory
  18. # is assumed if it exists.  For details see the documentation or read below.
  19. #
  20. # Data file summary... ON TOP:
  21. # enconding=value -- The character set in which the fileliest is encoded
  22. # home=value -- URL of website home directory (required)
  23. # geo=value  -- String: Default location for images (optional)
  24. # lic=value  -- Filename of page containing copyright/license info (optional)
  25. # .xxx=value -- Define a macro named xxx (optional)
  26. #
  27. # REST OF FILE: Information for each page to be included in sitemap:
  28. # url=value[=value]  -- Filename of web page (required, second value optional)
  29. # pri=value  -- Priority for indexing (0.0 to 1.0) (optional)
  30. #
  31. # AND FOR EACH IMAGE IN A URL THAT YOU WANT TO BE INDEXED:
  32. # img=value  -- Filename of an image used in this web page (optional)
  33. # cap=value  -- Caption for this image (optional)
  34. # title=value - Title for this image (optional)
  35. # (You can list as many images as you like for each URL, within reason)
  36. #
  37. # Version history:
  38. # 1.00 Wed Dec  8 10:51:32 2010: Initial version
  39. # 1.01 Sat Dec 11 19:02:20 2010: Fix bug in change frequency calculation
  40. # 1.02 Tue Dec 28 15:18:15 2010: Allow for redirects
  41. # 1.03 Thu Dec 30 09:51:46 2010: Add macro capability
  42. #
  43. # Author: Frank da Cruz, December 2010.
  44. #
  45. if llt \v(version) 900299 exit 1 "C-Kermit 9.0 or later required"
  46.  
  47. if def \$(DEBUG) set debug message on   # DEBUG env variable requests debugging
  48. .unix = 0                               # For "if unix ..."
  49. if equ "\v(system)" "UNIX" .unix = 1
  50. .usedenv = 0
  51.  
  52. def errexit {                           # Fatal error macro
  53.     echo \v(timestamp) \v(dir) sitemap.ksc:
  54.     echo Error: \%*
  55.     exit 1
  56. }
  57. if def \%1 {                            # Command-line argument if any
  58.     .webdirectory := \fdirname(\%1)     # is pathname of file list file.
  59.     if def webdirectory {               # If it includes a directory part
  60.         if not directory \m(webdirectory) { # Check it
  61.             errexit NOT A DIRECTORY: \m(webdirectory)
  62.         }
  63.         cd \m(webdirectory)             # and CD to it
  64.         if fail errexit CD FAILED: \m(webdirectory)
  65.     }
  66.     .filelist := \fbasename(\%1)        # And this is the name of the file
  67.     if not def filelist .filelist = filelist
  68. } else if def \$(KSITEMAPDIR) {         # Env variable KSITEMAPDIR exists
  69.     .webdirectory := \$(KSITEMAPDIR) 
  70.     if not directory \m(webdirectory) { # Check it
  71.         errexit "NOT A DIRECTORY: \m(webdirectory) [From $KSITEMAPDIR]"
  72.     }
  73.     cd \m(webdirectory)                 # and CD to it
  74.     if fail errexit "CD \m(webdirectory) [From $KSITEMAPDIR]"
  75.     .filelist = filelist                # And the file-list file is filelist
  76.     .usedenv = 1
  77. } else {                                # Otherwise
  78.     .webdirectory := \v(dir)            # assume the current directory
  79.     .filelist = filelist                # And default the filename to filelist
  80. }
  81. .resultdirectory := \m(webdirectory)    # Where to put sitemap.xml
  82.  
  83. if debug {                              # Debugging
  84.     .resultdirectory := \m(testingdest)
  85.     echo DEBUGGING...
  86.     echo \fbasename(\%0) V\m(version)
  87.     if usedenv echo Parameters obtained from $KSITEMAPDIR environment variable:
  88.     show mac webdirectory filelist
  89.     echo Writing result to \m(testingdest)\m(filelist)
  90.     echo current directory is \v(dir)
  91. }
  92. if not exist \m(filelist) {             # Check that the file list file exists
  93.     errexit FILE LIST NOT FOUND: \m(webdirectory)\m(filelist)
  94. }
  95. # Define some macros...
  96.  
  97. define FERREXIT {                       # Fatal error reading file list file
  98.     exit 1 [\flpad(\m(lineno),3,0)] \%1 [\m(line)]
  99. define FERRWARN {                       # Warning about a file list line
  100.     echo [\flpad(\m(lineno),3,0)] \%1 [\m(line)]
  101. }
  102. define FINISHIMAGE {                    # Macro to write Image epilog
  103.     if inimg {                          # If we were doing an image...
  104.         if def geo {                    # if location defined
  105.             .\%9 := <image:geo_location>\m(geo)</image:geo_location>
  106.             fwrite /line \%o "    \%9"  # add it.
  107.         }
  108.         if def lic {                    # If license URL defined
  109.             .\%9 := <image:license>\m(home)\m(lic)</image:license>
  110.             fwrite /line \%o "    \%9"  # Add it
  111.         }
  112.         fwrite /line \%o "  </image:image>" # Close image clause
  113.         .inimg = 0                      # No longer doing an image
  114.     }
  115. }
  116. def FINISHURL {                         # Macro to write URL epilog
  117.     if not inurl end 0
  118.     if > imginurl 0 {                   # Were there some images in this URL?
  119.         finishimage                     # Finish current image
  120.     } else {                            # No images - write priority now
  121.         fwrite /line \%o "  <priority>\m(priority)</priority>"
  122.     }
  123.     fwrite /line \%o </url>             # End of this URL
  124.     .inurl = 0                          # No longer doing a URL
  125. }
  126. # Begin execution...
  127.  
  128. fopen /read \%c \m(filelist)            # Open the file-list file
  129. if fail errexit "\v(lastcommand)"       # Make sure it is open
  130.  
  131. fopen /write \%o sitemap.tmp            # Open the temporary sitemap file.
  132. if fail errexit "OPEN /WRITE FAILED"    # Check
  133.  
  134. # Write XML prolog to sitemap file...
  135. fwrite /line \%o <?xml version="1.0" encoding="UTF-8"?> # First line
  136. if fail errexit "WRITE FAILED: sitemap.tmp" # Check that FWRITE succeeded
  137.  
  138. # If we get here all writes should succeed - continue the XML prolog...
  139. fwrite /line \%o <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
  140. fwrite /line \%o -
  141. { xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">}
  142.  
  143. .tags = |url|pri|img|cap|title|home|geo|lic|encoding|  # Valid tags
  144. .urls = 0                               # Initialize URL counter
  145. .imgs = 0                               # Image counter
  146. .imginurl = 0                           # Image within URL counter
  147. .inurl = 0                              # State flag: doing a URL
  148. .inimg = 0                              # State flag: doing an image (in a URL)
  149. .lineno = 0                             # File list file line number
  150. .doutf8 = 0                             # Convert encoding to UTF-8
  151. .mjd := \fmjd(today)                    # Today's date MJD format
  152. .encoding = UTF-8                       # Default encoding for file-list file
  153. .home =                                 # Web home directory (none yet)
  154. .globalgeo =                            # Global geographic location (ditto)
  155. .globallic =                            # Global license page (ditto)
  156.  
  157. while true {                            # Loop to read and process file list
  158.     fread /line /trim \%c line          # Read a line and trim trailing blanks
  159.     if fail break                       # Fail = end of file = all done
  160.     increment lineno                    # Count this line
  161.     if not defined line continue        # If empty line read the next one
  162.     .line := \fltrim(\m(line))          # Trim leading blanks
  163.     if equ "\s(line[1:1])" "#" continue # If it's a comment line keep reading
  164.     if equ "\v(version)" "900299" {    # If C-Kermit is 9.0.299
  165.     if not lgt "\v(test)" "Alpha.09" { # Alpha.09 or earlier...
  166.         # Work around "Quoting Hell" bug in CSV splitting
  167.         if \findex(\\,\m(line)) .line := \freplace(\m(line),\\,\\\\)
  168.     }
  169.     }
  170.     .\%9 := \fsplit(\m(line),&x,=,CSV)    # Split line on '='
  171.     if < \%9 2 { ferrwarn "TAG WITH NO VALUE", continue }
  172.     undef s1 s2 s3
  173.     .s1 := \&x[1]                       # Tag
  174.     .s2 := \fcontents(\&x[2])        # Value
  175.     if def \&x[3] .s3 := \fcontents(\&x[3]) # Optional second value (redirect)
  176.     if doutf8 {                # Converting character set?
  177.         if not equ "7BIT" "\fstringtype(\m(s2))" { # Need to convert this one?
  178.             .s2 := \fcvtcset(\m(s2),\m(encoding),utf-8)    # Convert to UTF-8
  179.         }
  180.     }
  181.     if ( > \flen(s1) 1 && equ "\s(s1[1:1])" "." ) { # Macro definition
  182.         _asg \s(s1[2]) \m(s2)        # See Using C-Kermit p.457
  183.         if debug {
  184.             message MACRO DEFINITION
  185.             show mac \s(s1[2])
  186.         }
  187.         continue
  188.     }
  189.     if not \findex(|\m(s1)|,\m(tags)) { # Preverify tag
  190.         ferrwarn "UNKNOWN TAG '\m(s1)'- SKIPPING"
  191.         continue
  192.     }
  193.     if match "\m(s2)" "*\\m(*)*" {    # Check for macro reference in s2
  194.         .s2 := \frecurse(\m(s2))    # Replace macro with its expansion
  195.         if debug { echo s2 MACRO EXPANSION, show mac s2 }
  196.     }
  197.     if match "\m(s3)" "*\\m(*)*" {    # Check for macro reference in s2
  198.         .s3 := \frecurse(\m(s3))
  199.          if debug { echo s3 MACRO EXPANSION, show mac s3 }
  200.     }
  201.     # Handle each kind of tag...
  202.  
  203.     if equ "\m(s1)" "encoding" {        # Encoding of filelist file
  204.         .encoding := \m(s2)             # Save it here
  205.         message Encoding=\m(encoding)
  206.         if not equ "\m(s2)" "UTF-8" .doutf8 = 1 # Must convert to UTF-8
  207.         continue
  208.     }
  209.     if equ "\m(s1)" "home" {            # Website home directory
  210.         # In Unix supply trailing slash if necessary
  211.         if unix if neq "\fright(\m(s2),1)" "/" .s2 := \m(s2)/
  212.         .home := \m(s2)                 # to be used in building URLs
  213.         continue
  214.     }
  215.     if equ "\m(s1)" "geo" {             # Image geographic location
  216.         if == 0 urls {                  # If geo given at the head of filelist
  217.             .globalgeo := \m(s2)        # make it the global default value
  218.         } else {
  219.             .geo := \m(s2)              # set the local value
  220.         }
  221.         continue
  222.     }
  223.     if equ "\m(s1)" "lic" {             # Website license page
  224.         if == 0 urls {                  # Same as for geo
  225.             .globallic := \m(s2)
  226.         } else {
  227.             .lic := \m(s2)
  228.         }
  229.         continue
  230.     }
  231.     if equ "\m(s1)" "url" {             # Web page URL
  232.         if not def home errexit "URL BEFORE HOME DEFINED"
  233.         if inurl do finishurl           # Finish previous URL if any
  234.         .imginurl = 0                   # How many images in this URL
  235.         .priority = 0.5                 # Default page priority (0.0-1.0)
  236.         .name := \m(s2)                 # Filename of this web page
  237.         .redirect := \m(s3)        # Name (if any) it is redirected to
  238.         if exist \m(s3) {        # If redirect is indicated
  239.             .redirect := \m(name)    # swap the names
  240.             .name := \m(s3)
  241.         }
  242.         if not exist \m(name) { ferrwarn "NOT EXIST \m(name)", continue }
  243.         if not readable \m(name) { ferrwarn "NOT READABLE \m(name)" }
  244.         .inurl = 1                      # We are doing a URL now
  245.  
  246.         message \m(name)...             # List the name if debugging
  247.         incr urls                       # Count the URL
  248.         fwrite /line \%o <url>          # Start the XML URL section
  249.         # Add URL of this file to sitemap...
  250.         if eq "\m(name)" "index.html" {    # Special for home page
  251.             fwrite /line \%o "  <loc>\m(home)</loc>"
  252.         } else if def redirect {    # Special for redirected names
  253.             fwrite /line \%o "  <loc>\m(home)\m(redirect)</loc>"
  254.         } else {            # Normal case
  255.             fwrite /line \%o "  <loc>\m(home)\m(name)</loc>"
  256.         }
  257.         .s := \fcvtd(\fdate(\m(name)),3) # Modification date of file
  258.         .s := \s(s[1:4])-\s(s[5:2])-\s(s[7:2]) # Just the date is enough
  259.         fwrite /line \%o "  <lastmod>\m(s)</lastmod>" # Add to sitemap
  260.         .\%x := \fmjd(\fdate(\m(name))) # Modification date as MJD
  261.         .\%y ::= \fmjd(\m(today)) - \%x    # How many days ago
  262.         .c = yearly                     # Default change frequency is yearly
  263.         if < \%y 8 .c =  daily          # If modified in last 7 days daily
  264.         else if < \%y 30 .c =  weekly   # or in last 30 days say weekly
  265.         else if < \%y 100 .c =  monthly # or in last 100 days say monthly
  266.         fwrite /line \%o "  <changefreq>\m(c)</changefreq>" # Add to sitemap
  267.         continue
  268.     }
  269.     if equ "\m(s1)" "pri" {             # Page priority
  270.         if not inurl ferrexit "PRIORITY NOT IN URL"
  271.         if not float \m(s2) ferrexit "PRIORITY NOT NUMERIC"
  272.         if ( > \m(s2) 1.0 || < \m(s2) 0.0 ) ferrexit "PRIORITY OUT OF RANGE"
  273.         .priority := \m(s2)             # Save it for epilog (see finishurl)
  274.         continue
  275.     }
  276.     if equ "\m(s1)" "img" {             # Image
  277.         finishimage                     # Finish previous image if any
  278.         if == 0 imginurl {              # First image for this URL?
  279.             # Add page priority before listing any images
  280.             fwrite /line \%o "  <priority>\m(priority)</priority>"
  281.         }
  282.         .geo := \m(globalgeo)           # If a global one defined use it
  283.         .lic := \m(globallic)           #  wherever a local one is not given.
  284.         if not inurl ferrexit "img not in url"
  285.         if not exist \m(s2) { ferrwarn "IMG NOT EXIST: \m(s2)", continue }
  286.         if not readabl \m(s2) { ferrwarn "IMG NOT READABLE: \m(s2)", continue }
  287.         increment imgs                  # Count this image
  288.         incr imginurl                   # Count image for this URL
  289.         fwrite /line \%o "  <image:image>" # Start image clause
  290.         fwrite /line \%o "    <image:loc>\m(home)\m(s2)</image:loc>" # Put URL
  291.         .inimg = 1                      # We are doing an image now
  292.         continue
  293.     }
  294.     if equ "\m(s1)" "cap" {             # Image caption
  295.         if not inimg ferrexit "CAP WITH NO IMG"
  296.         if def s2 {                     # If the caption is not empty add it
  297.             fwrite /line \%o "    <image:caption>\m(s2)</image:caption>"
  298.         }
  299.         continue
  300.     }
  301.     if equ "\m(s1)" "title" {           # Image title
  302.         if not inimg ferrexit "TITLE WITH NO IMG"
  303.         if def s2 {                     # If the title is not empty add it
  304.             fwrite /line \%o "    <image:title>\m(s2)</image:title>"
  305.         }
  306.     }
  307. }
  308. do finishurl                            # End of file list - finish last URL
  309. fwrite /line \%o </urlset>              # Finish the sitemap
  310. fclose \%o                              # Close the temporary sitemap file
  311. if exist sitemap.xml {                  # Rotate previous ones
  312.     if exist sitemap.ayer copy /preserve sitemap.ayer sitemap.ante
  313.     if fail message "FAILURE TO ROTATE OLD SITEMAP[1]"
  314.     copy /preserve sitemap.xml sitemap.ayer
  315.     if fail message "FAILURE TO ROTATE OLD SITEMAP[2]"
  316. }
  317. rename sitemap.tmp \m(resultdirectory)sitemap.xml # Install the new sitemap
  318. if fail errexit "FAILURE TO INSTALL NEW SITEMAP"
  319. if unix {                               # Unix...
  320.     chmod 644 \m(resultdirectory)sitemap.xml # Make it world readable
  321.     if fail errexit "CHMOD FAILURE - \m(resultdirectory)sitemap.xml"
  322. }
  323. # When run in a cron job this message arrives in email
  324. exit 0 "[\v(timestamp)] sitemap.ksc: OK - URLs: \m(urls); IMGs: \m(imgs)"
  325.  
  326. ; Local Variables:
  327. ; comment-column:40
  328. ; comment-start:"# "
  329. ; End:
  330.