tools_eget 5.28 KB
Newer Older
Vitaly Lipatov's avatar
Vitaly Lipatov committed
1
#!/bin/sh
2
# eget - simply shell on wget for loading directories over http (wget does not support wildcard for http)
Vitaly Lipatov's avatar
Vitaly Lipatov committed
3
# Example use:
4
# eget http://ftp.altlinux.ru/pub/security/ssl/*
Vitaly Lipatov's avatar
Vitaly Lipatov committed
5
#
6
# Copyright (C) 2014-2014, 2016, 2020  Etersoft
7
# Copyright (C) 2014 Daniil Mikhailov <danil@etersoft.ru>
8
# Copyright (C) 2016-2017, 2020 Vitaly Lipatov <lav@etersoft.ru>
Vitaly Lipatov's avatar
Vitaly Lipatov committed
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#

24 25 26 27 28 29 30 31 32 33 34 35 36 37
fatal()
{
    echo "FATAL: $*" >&2
    exit 1
}

WGETQ='' #-q
CURLQ='' #-s

set_quiet()
{
    WGETQ='-q'
    CURLQ='-s'
}
Vitaly Lipatov's avatar
Vitaly Lipatov committed
38

39
# TODO: passthrou all wget options
Vitaly Lipatov's avatar
Vitaly Lipatov committed
40
if [ "$1" = "-q" ] ; then
41
    set_quiet
Vitaly Lipatov's avatar
Vitaly Lipatov committed
42 43 44
    shift
fi

45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82

WGET="$(which wget 2>/dev/null)"

if [ -n "$WGET" ] ; then
# put remote content to stdout
scat()
{
    $WGET $WGETQ -O- "$1"
}
# download to default name of to $2
sget()
{
    if [ -n "$2" ] ; then
       $WGET $WGETQ -O "$2" "$1"
    else
       $WGET $WGETQ "$1"
    fi
}

else
CURL="$(which curl 2>/dev/null)"
[ -n "$CURL" ] || fatal "There are no wget nor curl in the system. Install it with $ epm install curl"
# put remote content to stdout
scat()
{
    $CURL -L $CURLQ "$1"
}
# download to default name of to $2
sget()
{
    if [ -n "$2" ] ; then
       $CURL -L $CURLQ --output "$2" "$1"
    else
       $CURL -L $CURLQ -O "$1"
    fi
}
fi

83
LISTONLY=''
84 85
if [ "$1" = "--list" ] ; then
    LISTONLY="$1"
86
    set_quiet
87 88 89
    shift
fi

90 91 92 93 94 95
LATEST=''
if [ "$1" = "--latest" ] ; then
    LATEST="$1"
    shift
fi

96 97 98 99 100 101
fatal()
{
    echo "$*" >&2
    exit 1
}

102 103 104
# check man glob
filter_glob()
{
105
	[ -z "$1" ] && cat && return
106
	# translate glob to regexp
107
	grep "$(echo "$1" | sed -e "s|\*|.*|g" -e "s|?|.|g")$"
108 109
}

110 111 112 113 114
filter_order()
{
    [ -z "$LATEST" ] && cat && return
    sort | tail -n1
}
115

116
# download to this file
117
TARGETFILE=''
118 119 120 121 122
if [ "$1" = "-O" ] ; then
    TARGETFILE="$2"
    shift 2
fi

Vitaly Lipatov's avatar
Vitaly Lipatov committed
123 124
# TODO:
# -P support
Vitaly Lipatov's avatar
Vitaly Lipatov committed
125

126
if [ -z "$1" ] ; then
127 128
    echo "eget - wget like downloader" >&2
    fatal "Run $0 --help to get help"
129 130
fi

131
if [ "$1" = "-h" ] || [ "$1" = "--help" ] ; then
132 133
    echo "eget - wget like downloader with wildcard support in filename part of URL"
    echo "Usage: eget [-q] [-O target file] [--list] http://somesite.ru/dir/na*.log"
134
    echo
135
    echo "Options:"
136 137 138
    echo "    -q       - quiet mode"
    echo "    -O file  - download to this file (use filename from server if missed)"
    echo "    --list   - print files from url with mask"
139
    echo "    --latest - print only latest version of file"
140
    echo
141 142
    echo "eget supports --list and download for https://github.com/owner/project urls"
    echo
143
#    echo "See $ wget --help for wget options you can use here"
144 145 146
    exit
fi

147 148 149 150 151 152 153
get_github_urls()
{
    # https://github.com/OWNER/PROJECT
    local owner="$(echo "$1" | sed -e "s|^https://github.com/||" -e "s|/.*||")" #"
    local project="$(echo "$1" | sed -e "s|^https://github.com/$owner/||" -e "s|/.*||")" #"
    [ -n "$owner" ] || fatal "Can't get owner from $1"
    [ -n "$project" ] || fatal "Can't get project from $1"
154
    local URL="https://api.github.com/repos/$owner/$project/releases"
155
    scat $URL | \
156 157 158
        grep -i -o -E '"browser_download_url": "https://.*"' | cut -d'"' -f4
}

159 160
if echo "$1" | grep -q "^https://github.com/" && \
   echo "$1" | grep -q -v "/download/" && [ -n "$2" ] ; then
161 162 163
    MASK="$2"

    if [ -n "$LISTONLY" ] ; then
164
        get_github_urls "$1" | filter_glob "$MASK" | filter_order
165 166 167 168
        exit
    fi

    for fn in $(get_github_urls "$1" | filter_glob "$MASK" | filter_order) ; do
169
        sget "$fn" || ERROR=1
170
    done
171
    exit
172 173 174
fi


175 176 177
# do not support /
if echo "$1" | grep -q "/$" ; then
    fatal "Use http://example.com/e/* to download all files in dir"
178 179 180 181
fi

# If ftp protocol, just download
if echo "$1" | grep -q "^ftp://" ; then
182 183
    [ -n "$LISTONLY" ] && fatal "TODO: list files for ftp:// do not supported yet"
    sget "$1" "$TARGETFILE"
184 185 186
    exit
fi

187 188 189 190 191 192 193 194 195 196 197
# mask allowed only in the last part of path
MASK=$(basename "$1")

# if mask are second arg
if [ -n "$2" ] ; then
    URL="$1"
    MASK="$2"
else
    # drop mask part
    URL="$(dirname "$1")"
fi
198

199 200
if echo "$URL" | grep -q "[*?]" ; then
    fatal "Error: there are globbing symbols (*?) in $URL"
Vitaly Lipatov's avatar
Vitaly Lipatov committed
201 202
fi

203
# If have no wildcard symbol like asterisk, just download
204
if echo "$MASK" | grep -qv "[*?]" || echo "$MASK" | grep -q "[?].*="; then
205
    sget "$1" "$TARGETFILE"
206 207 208
    exit
fi

209 210 211 212 213
is_url()
{
    echo "$1" | grep -q "://"
}

214
get_urls()
Vitaly Lipatov's avatar
Vitaly Lipatov committed
215
{
216
    scat $URL/ | \
217
         grep -i -o -E 'href="(.+)"' | cut -d'"' -f2
Vitaly Lipatov's avatar
Vitaly Lipatov committed
218 219
}

220
if [ -n "$LISTONLY" ] ; then
221
    for fn in $(get_urls | filter_glob "$MASK" | filter_order) ; do
222 223 224
        is_url "$fn" && echo $fn && continue
        fn="$(echo "$fn" | sed -e 's|^./||' -e 's|^/+||')"
        echo "$URL/$fn"
Vitaly Lipatov's avatar
Vitaly Lipatov committed
225
    done
226 227
    exit
fi
Vitaly Lipatov's avatar
Vitaly Lipatov committed
228

229
ERROR=0
230
for fn in $(get_urls | filter_glob "$MASK" | filter_order) ; do
231
    sget "$URL/$(basename "$fn")" || ERROR=1
232 233
done
exit $ERROR
Vitaly Lipatov's avatar
Vitaly Lipatov committed
234