Quelle download.gi
Sprache: unbekannt
|
|
Untersuchungsergebnis.gi Download desUnknown {[0] [0] [0]}zum Wurzelverzeichnis wechseln ##############################################################################
##
#W download.gi GAP4 package `Utils' Thomas Breuer
##
#Y Copyright (C) 2022, The GAP Group
#############################################################################
##
#V Download_Methods
##
## Use the following tools (in this order).
##
## - If the curlInterface package is available then call its
## 'DownloadURL' function.
## - If the URL starts with 'http://' and if the IO package is available
## then call the 'SingleHTTPRequest' function from this package.
## - If a 'wget' executable is available then call it.
## - If a 'curl' executable is available then call it.
##
## Note that currently the methods are *NOT* consistent in the case of
## failures:
##
## - The function 'SingleHTTPRequest' does not follow redirects as indicated
## by HTTP status codes 301 and 302.
## This happens for example if one asks for the file at
## 'http://www.gap-system.org/Packages/utils.html'.
##
BindGlobal( "Download_Methods", [] );
Add( Download_Methods, rec(
name:= "via DownloadURL (from the curlInterface package)",
isAvailable:= {} -> IsPackageLoaded( "curlInterface" ) and
CompareVersionNumbers(
InstalledPackageVersion( "curlInterface" ),
"2.3.0" ),
download:= function( url, opt )
local res;
opt:= ShallowCopy( opt );
if not IsBound( opt.failOnError ) then
opt.failOnError:= true;
fi;
# 'DownloadURL' handles the options 'verifyCert' and 'maxTime'.
res:= ValueGlobal( "DownloadURL" )( url, opt );
if res.success = true and
IsBound( opt.target ) and IsString( opt.target ) then
FileString( opt.target, res.result );
Unbind( res.result );
fi;
return res;
end ) );
Add( Download_Methods, rec(
name:= "via SingleHTTPRequest (from the IO package)",
isAvailable:= {} -> IsBoundGlobal( "SingleHTTPRequest" ),
download:= function( url, opt )
local rurl, pos, domain, uri, res;
if not StartsWith( url, "http://" ) then
return rec( success:= false, error:= "protocol is not http" );
elif IsBound( opt.maxTime ) and opt.maxTime <> 0 then
return rec( success:= false, error:= "no support for given timeout" );
fi;
rurl:= ReplacedString( url, "http://", "" );
pos:= Position( rurl, '/' );
domain:= rurl{ [ 1 .. pos-1 ] };
uri:= rurl{ [ pos .. Length( rurl ) ] };
if IsBound( opt.target ) and IsString( opt.target ) then
res:= ValueGlobal( "SingleHTTPRequest" )( domain, 80, "GET", uri,
rec(), false, opt.target );
else
res:= ValueGlobal( "SingleHTTPRequest" )( domain, 80, "GET", uri,
rec(), false, false );
fi;
if res.statuscode = 0 then
return rec( success:= false,
error:= res.status );
elif res.statuscode >= 400 then
return rec( success:= false,
error:= Concatenation( "HTTP error code ",
String( res.statuscode ) ) );
elif not ( IsBound( opt.target ) and IsString( opt.target ) ) then
return rec( success:= true, result:= res.body );
else
return rec( success:= true );
fi;
end ) );
Add( Download_Methods, rec(
name:= "via wget",
isAvailable:= function()
local exec;
exec:= Filename( DirectoriesSystemPrograms(), "wget" );
return exec <> fail and IsExecutableFile( exec );
end,
download:= function( url, opt )
local res, outstream, exec, args, code;
if IsBound( opt.maxTime ) and opt.maxTime <> 0 then
# wget 1.20.3 ignores a given timeout.
# (wget 1.21.3 would support timeout.)
return rec( success:= false, error:= "no support for given timeout" );
fi;
res:= "";
outstream:= OutputTextString( res, true );
exec:= Filename( DirectoriesSystemPrograms(), "wget" );
if IsBound( opt.target ) and IsString( opt.target ) then
args:= [ "--quiet", "-O", opt.target, url ];
else
args:= [ "--quiet", "-O", "-", url ];
fi;
if IsBound( opt.verifyCert ) and opt.verifyCert = false then
Add( args, "--no-check-certificate" );
fi;
if IsBound( opt.maxTime ) and IsPosInt( opt.maxTime ) then
Add( args, Concatenation( "--timeout=", String( opt.maxTime ) ) );
fi;
code:= Process( DirectoryCurrent(), exec, InputTextNone(), outstream, args );
CloseStream( outstream );
if code <> 0 then
# wget may have created the target file; try to remove it
if IsBound( opt.target ) and IsString( opt.target ) and
IsExistingFile( opt.target ) and RemoveFile( opt.target ) <> true then
Error( "Download cannot remove unwanted file ", opt.target );
fi;
return rec( success:= false,
error:= Concatenation( "Process returned ", String( code ) ) );
elif not ( IsBound( opt.target ) and IsString( opt.target ) ) then
return rec( success:= true, result:= res );
else
return rec( success:= true );
fi;
end ) );
Add( Download_Methods, rec(
name:= "via curl",
isAvailable:= function()
local exec;
exec:= Filename( DirectoriesSystemPrograms(), "curl" );
return exec <> fail and IsExecutableFile( exec );
end,
download:= function( url, opt )
local res, outstream, exec, args, code;
res:= "";
outstream:= OutputTextString( res, true );
exec:= Filename( DirectoriesSystemPrograms(), "curl" );
args:= [ "--silent", "-L", "--fail" ];
if IsBound( opt.verifyCert ) and opt.verifyCert = false then
Add( args, "-k" );
fi;
Add( args, "--output" );
if IsBound( opt.target ) and IsString( opt.target ) then
Add( args, opt.target );
else
Add( args, "-" );
fi;
if IsBound( opt.maxTime ) and IsPosInt( opt.maxTime ) then
Add( args, "--max-time" );
Add( args, opt.maxTime );
fi;
Add( args, url );
code:= Process( DirectoryCurrent(), exec, InputTextNone(), outstream, args );
CloseStream( outstream );
if code <> 0 then
return rec( success:= false,
error:= Concatenation( "Process returned ", String( code ) ) );
elif not ( IsBound( opt.target ) and IsString( opt.target ) ) then
return rec( success:= true, result:= res );
else
return rec( success:= true );
fi;
end ) );
#############################################################################
##
#M Download( <url>[, <opt>] )
##
## Try to download the file described by the string <url>,
## and return a record with the components 'success' ('true' or 'false'),
## and 'result' (a string, only if 'success' is 'true'),
## and 'error' (a string, only if 'success' is 'false').
##
InstallMethod( Download,
[ "IsString" ],
url -> Download( url, rec() ) );
InstallMethod( Download,
[ "IsString", "IsRecord" ],
function( url, opt )
local timeout, errors, r, res;
# Set the default for 'verifyCert' if necessary.
if not IsBound( opt.verifyCert ) and
UserPreference( "utils", "DownloadVerifyCertificate" ) = false then
opt.verifyCert:= false;
fi;
# Set the default for 'maxTime' if necessary.
if not IsBound( opt.maxTime ) then
timeout:= UserPreference( "utils", "DownloadMaxTime" );
if IsPosInt( timeout ) then
opt.maxTime:= timeout;
fi;
fi;
# Run over the methods.
errors:= [];
for r in Download_Methods do
if r.isAvailable() then
Info( InfoUtils, 2, "try Download method ", r.name );
res:= r.download( url, opt );
if res.success = true then
return res;
fi;
Info( InfoUtils, 2, "Download method ", r.name, " failed with\n",
"#I ", res.error );
Add( errors, Concatenation( r.name, ": ", res.error ) );
else
Info( InfoUtils, 2, "Download method ", r.name, " is not available" );
fi;
od;
# No method was successful.
if Length( errors ) = 0 then
# No method was available, inform the user
# that it is recommended to load or install some download tool.
Info( InfoWarning, 1,
"No 'Download' method is available.\n",
"#I Please consider to install one of the tools, ",
"see '?Download'" );
return rec( success:= false, error:= "no method was available" );
else
# At least one method was tried but without success.
if IsBound( opt.maxTime ) then
Add( errors,
Concatenation( "(maxTime option was set to ",
String( opt.maxTime ), ")" ) );
fi;
return rec( success:= false,
error:= JoinStringsWithSeparator( errors, "; " ) );
fi;
end );
[ zur Elbe Produktseite wechseln0.72Quellennavigators
]
|
2026-03-28
|