Last active
August 29, 2015 14:15
-
-
Save snapcase/8a0f0f86c8bb24ef9c6a to your computer and use it in GitHub Desktop.
subscribe to maps
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# subscribe to files from reflexfiles.com | |
# snapcase 2015 | |
# | |
# variables | |
BASE_URL="http://reflexfiles.com" | |
maps_path="${HOME}/reflex/base/internal/maps" | |
verbose=true | |
update=false | |
list=false | |
message() { | |
cat << EOF | |
Usage: $0 [-p path] [-l | -u] [-a id] [-r id] | |
Options: | |
-p, --path <directory> | |
maps are located in <directory> | |
-l, --list display subscribed maps | |
-a, --add <id> add map | |
-r, --remove <id> remove map | |
-u, --update update all subscribed maps | |
-q, --quiet do not write messages on standard output | |
-h, --help display this | |
EOF | |
} | |
parse_options() { | |
while [[ $1 ]]; do | |
case $1 in | |
-p | --path ) shift; maps_path=$1 ;; | |
-u | --update ) update=true ;; | |
-a | --add ) shift; add=${1//[^0-9]/} ;; | |
-r | --remove ) shift; remove=${1//[^0-9]/} ;; | |
-l | --list ) list=true; ;; | |
-q | --quiet ) verbose=false ;; | |
-h | --help ) message; exit ;; | |
* ) message; exit 1 ;; | |
esac | |
shift | |
done | |
} | |
die() { error "$*"; exit 1; } | |
error() { printf "error: $*\n" >&2; } | |
info() { printf ":: $*\n"; } | |
validate_path() { | |
# make sure path exists | |
if [[ -d $maps_path ]]; then | |
cd "$maps_path" | |
else | |
die "Path not found" | |
fi | |
} | |
unixtime() { | |
# seconds since the Unix epoch | |
date -d "$1" +%s | |
} | |
timestamp() { | |
# return timestamp | |
local released="$1" updated="$2" | |
if [[ $updated = "---" ]]; then | |
printf "%d\n" "$(unixtime $released)" | |
else | |
printf "%d\n" "$(unixtime $updated)" | |
fi | |
} | |
dlmap() { | |
# download map and create symlink | |
local id="$1" file ts uid | |
typeset -a arr | |
# 0=released, 1=uid, 2=updated (optional) | |
IFS=$'\n' read -d '' -r -a arr < \ | |
<(wget -qO- "${BASE_URL}/file/${id}" | \ | |
sed -n 's|hrs|hours|g | |
/<b>Released:/s|.*</b>\([^<]*\).*|\1|p | |
/<b>Last Revised:/h | |
/piwik_download/s|.*/download/\([^/]*\).*|\1|p | |
${x;s|.*Revised: </b>\([^<]*\).*|\1|p}') | |
[[ ! ${#arr[@]} -ge 2 ]] && die "Map (id:${id}) not found" | |
uid="${arr[1]}" | |
# update requested | |
[[ $# -eq 2 && -f ".sub_${id}_${lfiles[$id]%-*}-${uid}" ]] && return 2 | |
ts="$(timestamp "${arr[0]}" "${arr[2]:----}")" | |
file=$(wget -qO- "${BASE_URL}/download/${uid}/latest" | \ | |
bsdtar -s ',.*/,,' -xvf - \*.map 2>&1 | awk '{print $2}') | |
if [[ $? -eq 0 ]]; then | |
ln -s "$file" ".sub_${id}_${ts}-${uid}" | |
$verbose && info "Downloaded $file (id:${id})" | |
fi | |
} | |
add() { | |
# add new file | |
local id=$1 | |
if [[ ${lfiles[$id]} ]]; then | |
die "File already exists" | |
else | |
dlmap $id | |
fi | |
} | |
remove() { | |
# remove file | |
local id=$1 symlink file | |
if [[ ${lfiles[$id]} ]]; then | |
symlink=".sub_${id}_${lfiles[$id]}" | |
file="$(readlink $symlink)" | |
rm -- "$symlink" | |
rm -- "$file" | |
$verbose && info "Removed ${file} (id:${id})" | |
else | |
die "File to be removed does not exist" | |
fi | |
} | |
update() { | |
local i=0 ts | |
[[ ${#lfiles[@]} -eq 0 ]] && die "No files to update" | |
parse_files | |
for id in "${!lfiles[@]}"; do | |
ts="${lfiles[$id]%-*}" | |
uid="${lfiles[$id]##*-}" | |
if (( ${files[$id]} - $ts > 120 )); then | |
if dlmap "$id" "$uid"; then | |
rm ".sub_${id}_${ts}-${uid}" | |
(( ++i )) | |
fi | |
fi | |
done | |
if [[ i -eq 0 ]] && $verbose; then | |
info "Nothing to do" | |
fi | |
} | |
list() { | |
# list local files | |
[[ ${#lfiles[@]} -eq 0 ]] && die "There's no files" | |
for id in "${!lfiles[@]}"; do | |
printf "%5d -> %s\n" $id "$(readlink .sub_${id}_*)" | |
done | |
exit 0 | |
} | |
local_files() { | |
# construct an array of local files | |
typeset -a arr | |
while IFS=_ read -r -a arr; do | |
lfiles[${arr[1]}]=${arr[2]} | |
done < <(find . -maxdepth 1 -name '.sub_[0-9]*_[0-9]*-S*') | |
} | |
parse_files() { | |
# "parse" /files using sed and populate the $files array | |
typeset -a arr | |
while IFS=$'\t' read -r -a arr; do | |
# 0=id, 1=released, 2=updated | |
ts="$(timestamp "${arr[1]}" "${arr[2]}")" | |
files[${arr[0]}]=$ts | |
done < \ | |
<(wget -qO- "${BASE_URL}/files" | \ | |
sed -n \ | |
'/filetablerow1/{ | |
s|^[ ]*|| | |
s|</td>|&\n|g | |
s|</tr>|&\t|g | |
s|hrs|hours|g | |
s|[^/]*/file/\([0-9]\+\)">\([^<]*\)\([^\n]*\n\)\{3\}<td>\([^<]*\)</td>\n<td>\([^<]*\)[^\t]*\t|\1\t\4\t\5\n|g | |
s|</table>\r|| | |
s|\n$|| | |
p | |
}') | |
} | |
declare -A files # id->timestamp | |
declare -A lfiles # id->timestamp | |
parse_options "$@" | |
validate_path | |
local_files | |
$list && list | |
[[ $add ]] && add $add | |
[[ $remove ]] && remove $remove | |
$update && update |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment