home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 28 / amigaformatcd28.iso / -seriously_amiga- / comms / www / wgetrexx / wget.rexx < prev   
Encoding:
OS/2 REXX Batch file  |  1998-05-09  |  13.1 KB  |  453 lines

  1. /*
  2.  * wget.rexx -- Invoke Wget from WWW browser
  3.  *
  4.  * $VER: wget.rexx 2.0 (8.5.1998)
  5.  *
  6.  * This program is copyrighted freeware. All rights reserved.
  7.  * Copyright (C) 1998 by Thomas Aglassinger <agi@sbox.tu-graz.ac.at>
  8.  *
  9.  * See http://www.giga.or.at/~agi/wgetrexx/ for more information.
  10.  */
  11.  
  12. /* Version information */
  13. version = "2.0 (8.5.1998)"
  14.  
  15. /* Install signal handlers */
  16. SIGNAL ON Break_C                      /* Catch Control-C */
  17. SIGNAL ON NoValue                      /* Catch unitinialized variables */
  18.  
  19. /* Directory to where the directory structure of the server
  20.  * should be copied */
  21. download_directory = 'Web:'
  22.  
  23. PARSE ARG arguments
  24. OPTIONS RESULTS
  25.  
  26. /* Check, if wget is in search path */
  27. ADDRESS COMMAND 'which >nil: wget'
  28. IF RC ~= 0 THEN DO
  29.     CALL view_error_message("Could not find wget.*NMake sure it is in the Workbench search path.")
  30.     EXIT 10
  31. END
  32.  
  33. /* Open rexxdossupport.library */
  34. IF ~SHOW('L', 'rexxdossupport.library') THEN DO
  35.     IF ~ADDLIB('rexxdossupport.library', 0, -30, 2) THEN DO
  36.         CALL view_error_message("Library 'rexxdossupport.library' not found.*NRefer to the manual where to obtain it from.")
  37.     END
  38. END
  39.  
  40. /* Set default values for CLI arguments */
  41. to       = download_directory
  42. ask      = 0
  43. further  = 0
  44. continue = 0
  45. verbose  = 0
  46. clip     = 'wget'
  47. port     = ''
  48. options  = ''
  49.  
  50. /* Parse CLI options using ReadArgs() */
  51. template = "Verbose/S,To/K,Ask/S,Further/S,Port/K,Continue/S,Clip/K,Options/F"
  52. IF ~ReadArgs(arguments, template) THEN DO
  53.    CALL view_error_message("Error in CLI options: " || Fault(RC) || "*NRefer to the manual about possible arguments.")
  54.    EXIT 10
  55. END
  56.  
  57. /* Show program header */
  58. IF verbose THEN DO
  59.     SAY 'wget.rexx -- Invoke Wget from WWW browser. Version ' || version
  60.     SAY 'Copyright © 1998 Thomas Aglassinger. Freeware.'
  61.     SAY
  62. END
  63.  
  64. /* Check, if download directory is available */
  65. download_directory = to
  66. IF ~Exists(download_directory) THEN DO
  67.     CALL view_error_message("Download directory '" || download_directory || "' not found.*NMake sure it exists and that it is accessible.")
  68.     EXIT 10
  69. END
  70.  
  71. /* If no browser port has been specified, find out which port to use */
  72. IF (port = "") THEN DO
  73.     /* Assume that current host is a browser */
  74.     port = ADDRESS()
  75.  
  76.     IF ((LEFT(port, 4) ~= 'AWEB') ,
  77.          | (LEFT(port, 7) ~= 'IBROWSE')) ,
  78.     THEN DO
  79.         /* Current host has turned out to be useless (e.g. 'REXX' if started
  80.          * from a plain CLI), therefore try to find the default port of any
  81.          * of the supported browsers */
  82.         IF SHOW('P', 'AWEB.1') THEN DO
  83.             port = 'AWEB.1'
  84.         END
  85.         ELSE IF SHOW('P', 'IBROWSE') THEN DO
  86.             port = 'IBROWSE'
  87.         END
  88.         ELSE DO
  89.             /* No supported browser found. Abort with error message. */
  90.             CALL view_error_message("Could not find ARexx port of any supported browser.*NMake sure your browser is supported and running at*Nits default ARexx port or start script from browser.")
  91.             EXIT 10
  92.         END
  93.     END
  94. END
  95.  
  96. /* Assign browser port */
  97. browser.port = port
  98.  
  99. IF verbose THEN DO
  100.     /* Tell the user which browser we are using */
  101.     SAY "Using browser in port '" || browser.port || "'"
  102.     SAY
  103. END
  104.  
  105. /* Assign browser ARexx commands */
  106. IF LEFT(browser.port,4) = 'AWEB' THEN DO
  107.     /* AWeb */
  108.     browser.open = 'Open Reload'
  109.     browser.query_uri = 'Get URL'
  110.     browser.activate.count = 2
  111.     browser.activate.1 = 'ActivateWindow'
  112.     browser.activate.2 = 'WindowToFront'
  113. END
  114. ELSE IF LEFT(browser.port,7) = 'IBROWSE' THEN DO
  115.     /* iBrowse */
  116.     browser.open = 'GotoURL'
  117.     browser.query_uri = 'Query URL'
  118.     browser.activate.count = 2
  119.     browser.activate.1 = 'Show'
  120.     browser.activate.2 = 'ScreenToFront'
  121. END
  122.  
  123. ELSE DO
  124.     /* Unknown browser */
  125.     CALL view_error_message("Browser at port '" || browser.port || "' is not supported*NRefer to the manual to learn which browsers are.")
  126.     EXIT 10
  127. END
  128.  
  129. /* Check, if browser is available */
  130. IF ~SHOW('P', browser.port) THEN DO
  131.     /* No; abort with error message */
  132.     CALL view_error_message("Could not find WWW browser in port '" || browser.port || "'.*NStart browser before using this script.")
  133.     EXIT 10
  134. END
  135.  
  136. /*
  137.  * Ask for additional options
  138.  */
  139. IF (ask) THEN DO
  140.     /* Open rexxreqtools.library */
  141.     IF ~SHOW('L', 'rexxreqtools.library') THEN DO
  142.         IF ~ADDLIB('rexxreqtools.library', 0, -30, 0) THEN DO
  143.             CALL view_error_message("Library 'rexxreqtools.library' not found.*NRefer to the manual where to obtain it from.")
  144.         END
  145.     END
  146.  
  147.     IF further THEN DO
  148.         /* Only further options are asked and the options passed in the
  149.          * command line are not displayed in the requester */
  150.         ask_options = ''
  151.         options = options || ' '
  152.         further_text = ' further '
  153.     END
  154.     ELSE DO
  155.         /* Display options passed in the command line in the requester
  156.          * so that the user can edit all of them */
  157.         ask_options = options
  158.         options = ''
  159.         further_text = ' '
  160.     END
  161.  
  162.     IF continue THEN DO
  163.         /* Obtain options used to be displayed as default in requester
  164.          * from the clip.
  165.          *
  166.          * Note that this can discard all options passed in the CLI if
  167.          * <further> was not specified.*/
  168.         ask_options = GetClip(clip)
  169.     END
  170.     ELSE DO
  171.         /* Reset the Clip and use the options already in <ask_options>
  172.          * as default requester content */
  173.         SetClip(clip, "")
  174.     END
  175.  
  176.     /* Ask for additional options. If the user cancels the requester,
  177.      * abort the whole process. */
  178.     ok = 1
  179.     ask_options = rtGetString(ask_options, "     Enter" || further_text || "options for Wget     ", "Wget Request",,,ok)
  180.     IF (ok = 0) THEN DO
  181.         EXIT 5
  182.     END
  183.  
  184.     /* Update the clip with the options asked */
  185.     SetClip(clip, ask_options)
  186.  
  187.     /* Append options just asked to overall options */
  188.     options = options || ask_options
  189. END /* ask */
  190.  
  191. /* From now on talk with the browser */
  192. ADDRESS VALUE browser.port
  193.  
  194. /* Figure out URI to download from */
  195. IF (POS('http://', options) = 0) THEN DO
  196.     /* There is no URI specified in the command line, therefore use the one
  197.      * from page currently viewed in browser */
  198.     browser.query_uri
  199.     uri = RESULT
  200.  
  201. END
  202. ELSE DO
  203.     /* Extract URI from options */
  204.     PARSE VAR options options1 'http://' uri ' ' options2
  205.  
  206.     uri = 'http://' || uri
  207.     options = options1 || ' ' || options2
  208. END
  209.  
  210. /* Check, if there is another URI within the options.
  211.  * In case, abort with error message. */
  212. IF (POS('http://', options) > 0) THEN DO
  213.     CALL view_error_message("Only one URI at a time allowed in options.*NRemove all other URIs from your request.")
  214.     EXIT 10
  215. END
  216.  
  217. /* Extract the name of the WWW-server to be downloaded from */
  218. PARSE VAR uri 'http://' server '/' external_file
  219.  
  220. /* Validate URI */
  221. IF server = '' THEN DO
  222.     /* If the server name could not be extracted,
  223.      * view error message and abort */
  224.     CALL view_error_message(" Server name is missing in URI*Nor does not start with 'http://'")
  225.     EXIT 10
  226. END
  227.  
  228. /* Make sure that download_directory ends in ':' or '/' */
  229. IF (POS(RIGHT(download_directory, 1), ':/') = 0) THEN DO
  230.     download_directory = download_directory || '/'
  231. END
  232.  
  233. /* Compute target directory and filename in URI-style */
  234. target_directory = convert_amiga_path_to_uri(download_directory)
  235. target_file = 'file://localhost/' || download_directory || server
  236. target_file = target_file || '/' || convert_uri_to_amiga_path(external_file)
  237.  
  238. /*
  239.  * Compute command call for wget
  240.  */
  241. wget = 'wget -x --directory-prefix=' || target_directory
  242. wget = wget || ' ' || options || ' ' || uri
  243.  
  244. /*
  245.  * Invoke Wget and lauch error requester or view downloaded page in browser
  246.  */
  247.  
  248. /* View source and target file for users information */
  249. IF verbose THEN DO
  250.     SAY 'Downloading "' || uri || '"'
  251.     SAY 'to          "' || target_file || '"'
  252.     SAY
  253. END
  254.  
  255. /* View the command so the user knows what is going to happen */
  256. IF verbose THEN DO
  257.     SAY 'Downloading "' || uri || '"'
  258.     SAY 'to          "' || target_file || '"'
  259.     SAY
  260. END
  261. SAY wget
  262. SAY
  263.  
  264. /* Invoke the command viewed before
  265.  * and remember its returncode */
  266. ADDRESS COMMAND wget
  267. wgetRC = RC
  268.  
  269. /* If wget was successful, view the copied page in browser */
  270. IF (wgetRC = 0) THEN DO
  271.     SAY
  272.     SAY 'Successfully downloaded data to local web.'
  273.  
  274.     IF SHOW('P', browser.port) THEN DO
  275.         SAY 'Viewing page in Browser'
  276.  
  277.         /* In case browser has been iconified meanwhile, pop it up again */
  278.         DO command_index=1 FOR browser.activate.count
  279.             browser.activate.command_index
  280.         END
  281.  
  282.         /* View page from local web */
  283.         browser.open target_file
  284.     END
  285. END
  286. ELSE DO
  287.     /* Inform user that something has gone wrong */
  288.     SAY
  289.     SAY 'Error during download. Nothing to display in Browser.'
  290.     CALL view_error_message("Wget did return an error")
  291. END
  292.  
  293. /* Exit with code returned by wget, multiplied by 10
  294.  * (wget returns 1 in case of error) */
  295. EXIT 10*wgetRC
  296.  
  297. /*
  298.  * Signal handlers
  299.  */
  300.  
  301. /* Handler for Control-C */
  302. Break_C:
  303.     SIGNAL OFF Break_C
  304.     SAY
  305.     SAY '*** Interrupted.'
  306.     EXIT 5
  307.  
  308. /* Handler for unitinialized variables */
  309. NoValue:
  310.     SIGNAL OFF NoValue
  311.     SAY
  312.     SAY SIGL SourceLine(SIGL)
  313.     SAY '*** Error: uninitialized value.'
  314.     EXIT 20
  315.  
  316. /*
  317.  * Subroutines
  318.  */
  319.  
  320. /***** ugly/convert_amiga_path_to_uri **************************************
  321.  * NAME
  322.  *   convert_amiga_path_to_uri - Convert path from Amiga to URI style
  323.  * FUNCTION
  324.  *   Convert path from Amiga to URI style. The following conversion rules
  325.  *   are applied:
  326.  *
  327.  *   - Device names are transformed from e.g. "ram:" to "/ram/"
  328.  *   - Leading "/"'s replaced by "../"
  329.  *   - All "//"'s are replaced by "/../"
  330.  * INPUTS
  331.  *   amiga_path - Amiga style path
  332.  * RESULT
  333.  *   Path in URI style
  334.  * BUGS
  335.  *   The input path is not validated for correctness. In such a case the
  336.  *   result will also be invalid.
  337.  * EXAMPLES
  338.  *   "ram:"           -> "/ram/"
  339.  *   "ram:sepp"       -> "/ram/sepp"
  340.  *   "sepp//resi"     -> "sepp/../resi"
  341.  *   "ram:sepp//resi" -> "/ram/sepp/../resi"
  342.  *   "//resi/hugo"    -> "../../resi/hugo"
  343.  *   "//resi//hugo"   -> "../../resi/../hugo
  344.  **************************************************************************/
  345. convert_amiga_path_to_uri : PROCEDURE
  346.     PARSE ARG amiga_path
  347.  
  348.     uri = ''
  349.  
  350.     /* Extract device name from Amigapath (if there is any) */
  351.     device = ''
  352.     IF (POS(':', amiga_path) > 0) THEN DO
  353.         PARSE VAR amiga_path device ':' path_part
  354.         amiga_path = path_part
  355.     END
  356.  
  357.     /* Convert leading "/" to "../" */
  358.     DO WHILE (LEFT(amiga_path, 1) = '/')
  359.         amiga_path = DELSTR(amiga_path, 1, 1)
  360.         uri = uri || '../'
  361.     END
  362.  
  363.     uri = uri || amiga_path
  364.  
  365.     /* Convert '//' inside string to '/../' */
  366.     DO WHILE (POS('//', uri) > 0)
  367.         PARSE VAR uri before '//' after
  368.         uri = before || '/../' || after
  369.     END
  370.  
  371.     /* Add device name in Unix-style;
  372.      * 'ram:' becomes '/ram/' */
  373.     IF (device ~= '') THEN DO
  374.         uri = '/' || device || '/' || uri
  375.     END
  376.  
  377.     RETURN uri
  378.  
  379. /***** ugly/convert_uri_to_amiga_path **************************************
  380.  * NAME
  381.  *   convert_uri_to_amiga_path - Convert path from URI to Amiga style
  382.  * SYNOPSIS
  383.  *   amiga_path = convert_uri_to_amiga_path( uri )
  384.  * FUNCTION
  385.  *   Convert path from URI to Amiga style. The following conversion rules
  386.  *   are applied:
  387.  *
  388.  *   - Replace every leading '../' by '/'
  389.  *   - Replace every '/../' by '//'
  390.  *   - Replace every '~' by '%7E'
  391.  * INPUTS
  392.  *   uri - URI style path
  393.  * RESULT
  394.  *   amiga_path - Amiga style path
  395.  * BUGS
  396.  *   The input path is not validated for correctness. In such a case the
  397.  *   result will also be invalid.
  398.  *
  399.  *   Devices in URI style are not handled.
  400.  **************************************************************************/
  401. convert_uri_to_amiga_path : PROCEDURE
  402.     PARSE ARG uri
  403.  
  404.     amiga_path = ''
  405.  
  406.     /* Replace leading "../" by "/" */
  407.     DO WHILE (LEFT(uri, 3) = '../')
  408.         uri = DELSTR(uri, 1, 3)
  409.         amiga_path = amiga_path || '/'
  410.     END
  411.  
  412.     amiga_path = amiga_path || uri
  413.  
  414.     /* Replace '/../' inside string by '//' */
  415.     DO WHILE (POS('//', uri) > 0)
  416.         PARSE VAR uri before '/../' after
  417.         amiga_path = before || '//' || after
  418.     END
  419.  
  420.     /* Replace '~' by '%7E' */
  421.     DO WHILE (POS('~', uri) > 0)
  422.         PARSE VAR uri before '~' after
  423.         amiga_path = before || '%7E' || after
  424.     END
  425.  
  426.     RETURN amiga_path
  427.  
  428. /***************************************************************************
  429.  * NAME
  430.  *   view_error_message -- Pop-up error requester.
  431.  * FUNCTION
  432.  *   Pop-up error requester and wait for user to confirm it.
  433.  *
  434.  *   The title of the requester is "Wget Error", and the conformation button
  435.  *   will have an "Ok".
  436.  *
  437.  *   This procedure simply invokes c:RequestChoice with the proper
  438.  *   arguments.
  439.  * INPUTS
  440.  *   message - Message text to be in body of requester.  This text must not
  441.  *       contain any double quotes ("), but single quotes (') are allowed.
  442.  * RESULT
  443.  *   The return value is the same as sent by the RequestChoice command.
  444.  *   Normally, this is 0, as there is only one button. Other values indicate
  445.  *   an error while invoking RequestChoice.
  446.  **************************************************************************/
  447. view_error_message : PROCEDURE
  448.     PARSE ARG message
  449.     ADDRESS COMMAND 'RequestChoice >nil: "Wget Error" "' || message || '" Ok'
  450.  
  451.     RETURN RC
  452.  
  453.