Ticket #13373: 13373_sage-i.patch

File 13373_sage-i.patch, 6.4 KB (added by jdemeyer, 9 years ago)
  • new file spkg/bin/sage-download-file

    # HG changeset patch
    # User Jeroen Demeyer <jdemeyer@cage.ugent.be>
    # Date 1345186797 -7200
    # Node ID ba2df99c4668754f3188aa2dcdc732fbf23952fc
    # Parent  d25550b6c646f1e2b82f549989f368940b18c732
    Use curl, wget, system Python for ./sage -i http://.../foo.spkg
    
    diff --git a/spkg/bin/sage-download-file b/spkg/bin/sage-download-file
    new file mode 100755
    - +  
     1#!/usr/bin/env bash
     2
     3# Usage: sage-download-file URL
     4# Download URL to standard output, using either wget, curl, Python's
     5# urllib or a custom program $URL_GRABBER.
     6#
     7# AUTHORS:
     8#
     9# - William Stein: original sage-download_package Python script
     10#
     11# - Leif Leonhardy, Jeroen Demeyer (Trac #13373): use wget, curl or Python
     12#
     13#*****************************************************************************
     14#  Distributed under the terms of the GNU General Public License (GPL)
     15#  as published by the Free Software Foundation; either version 2 of
     16#  the License, or (at your option) any later version.
     17#                  http://www.gnu.org/licenses/
     18#*****************************************************************************
     19
     20if [ $# -ne 1 ]; then
     21cat >&2 <<EOF
     22Usage: $0 URL
     23
     24Download URL to standard output, using either wget, curl, Python's
     25urllib or a custom program $URL_GRABBER.
     26EOF
     27exit 2
     28fi
     29
     30if [ -z "$URL_GRABBER" ]; then
     31    # Prefer Sage's Python because that's the same on all systems.
     32    # It should always work.
     33    if [ -n "$SAGE_LOCAL" ] && [ -x "$SAGE_LOCAL/bin/python" ]; then
     34        URL_GRABBER="$SAGE_LOCAL/bin/python"
     35    elif command -v curl &>/dev/null; then
     36        URL_GRABBER="curl"
     37    elif command -v wget &>/dev/null; then
     38        URL_GRABBER="wget --no-verbose -O-"
     39    # Pick Python last because we don't know which version it is,
     40    # so it's a bit risky.
     41    elif command -v python &>/dev/null; then
     42        URL_GRABBER="python"
     43    else
     44        echo >&2 "Error: $0: No program to fetch files from the web found."
     45        echo >&2 "       Either install Wget, curl or Python, or set the environment"
     46        echo >&2 "       variable URL_GRABBER to use some alternate, installed program."
     47        echo >&2 "       In the latter case, add options to download the contents of the"
     48        echo >&2 "       specified URL to the standard output. URL_GRABBER can also be"
     49        echo >&2 "       a Python interpreter."
     50        exit 3
     51    fi
     52fi
     53
     54
     55# Is $URL_GRABBER a Python interpreter?
     56if ! ( $URL_GRABBER --version </dev/null 2>&1 | grep '^Python ' ) &>/dev/null ; then
     57    # Not Python, simply execute it
     58    exec $URL_GRABBER "$1"
     59fi
     60
     61
     62# Use Python
     63exec $URL_GRABBER <<EOF
     64
     65##############################################
     66# Python script to download a file to stdout #
     67##############################################
     68
     69import sys, urllib
     70
     71# Change the URLopener to raise an exception on HTTP errors
     72def http_error_default(url, fp, errcode, errmsg, headers):
     73    fp.close()
     74    raise IOError(errcode, errmsg, url)
     75
     76opener = urllib.FancyURLopener()
     77opener.http_error_default = http_error_default
     78
     79# This reporthook is used below to print ...'s as the file downloads.
     80global cur
     81cur = 0
     82def reporthook(block, size, total):
     83    global cur
     84    n = 60*block*size
     85    # n ranges from 0 to 60*total, so we'll print at most 60 dots
     86    if n >= cur + total:
     87        sys.stderr.write('.')
     88        sys.stderr.flush()
     89        cur += total
     90sys.stderr.write('[')
     91sys.stderr.flush()
     92filename, info = opener.retrieve('''$1''', '/dev/stdout', reporthook)
     93sys.stderr.write(']\n')
     94EOF
  • spkg/bin/sage-spkg

    diff --git a/spkg/bin/sage-spkg b/spkg/bin/sage-spkg
    a b  
    243243    mkdir -p "$SAGE_PACKAGES/optional"
    244244    cd "$SAGE_PACKAGES/optional"
    245245   
    246     # Handle case 3 above, where the package name contains no version
    247     # number and no full path.  Reduce to case 2a.
    248     if [ "$PKG_BASE" = "$PKG_NAME" -a -z "$PKG_HAS_PATH" ]; then
    249         # No version number found
    250         echo "Searching for latest online version of $PKG_BASE"
    251         PKG_NAME=`sage-latest-online-package "$PKG_BASE"`
    252         if [ $? -ne 0 ]; then
     246    # Reduce everything to case 4: full URL.
     247    if [ -n "$PKG_HAS_PATH" ]; then
     248        PKG_URL="$PKG_SRC"
     249    else
     250        # Handle cases 2a and 3, where the package name is something
     251        # like "foo" or "foo-1.2.3".
     252        URL_BASE="${SAGE_SERVER}packages"
     253        for repo in optional experimental standard archive; do
     254            # Download the list of packages.
     255            echo ">>> Checking online list of $repo packages."
     256            repolist="${repo}.list"
     257            sage-download-file "$URL_BASE/$repo/list" >$repolist
     258            if [ $? -ne 0 ]; then
     259                echo >&2 "Error: failed to download $URL_BASE/$repo/list, aborting"
     260                rm -f $repolist
     261                exit 1
     262            fi
     263
     264            # The contrived sed commands print out either ${PKG_NAME} if
     265            # it appears as a complete line or some string starting with
     266            # ${PKG_NAME}- whichever occurs first.
     267            # Tested with GNU sed, BSD sed (on OS X) and Solaris sed.
     268            pkg=`sed -n -f <( echo "/^${PKG_NAME}\$/{p;q;}" && echo "/^${PKG_NAME}-/{p;q;}" ) $repolist`
     269            rm -f $repolist
     270            if [ -n "$pkg" ]; then
     271                PKG_NAME=$pkg
     272                PKG_URL="$URL_BASE/$repo/$pkg.spkg"
     273                break
     274            fi
     275        done
     276        if [ -z "$PKG_URL" ]; then
     277            echo >&2 "Error: could not find a package matching $PKG_NAME in $URL_BASE"
    253278            exit 1
    254279        fi
    255         echo "Found $PKG_NAME"
    256         PKG_SRC="$PKG_NAME"
     280        echo ">>> Found $PKG_NAME."
    257281    fi
    258282
    259     # This script can handle either full URLs (case 4) or a package
    260     # name with version (case 2a).
    261     sage-download_package "$PKG_SRC"
    262 
    263     if [ ! -f "$PKG_NAME.spkg" ]; then
    264         echo >&2 "Error: Failed to download package $PKG_NAME from $SAGE_SERVER"
     283    # Download to a temporary file (such that we don't end up with a
     284    # corrupted .spkg file).
     285    PKG_TMP="$PKG_NAME.tmp"
     286    echo ">>> Downloading $PKG_NAME.spkg."
     287    sage-download-file "$PKG_URL" >"$PKG_TMP"
     288    if [ $? -ne 0 ]; then
     289        # Delete failed download
     290        rm -f "$PKG_TMP"
     291        echo >&2 "Error: failed to download package $PKG_NAME"
    265292        exit 1
    266293    fi
     294
    267295    PKG_SRC="`pwd`/$PKG_NAME.spkg"
     296    mv -f "$PKG_TMP" "$PKG_SRC"
    268297fi
    269298
    270299# Do a final check that PKG_SRC is a file with an absolute path