gcgetics.sh - Extract cids and ics links from google embedded calendars
This commit is contained in:
6
.editorconfig
Normal file
6
.editorconfig
Normal file
@@ -0,0 +1,6 @@
|
||||
root = true
|
||||
|
||||
[*.sh]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
@@ -1,3 +1,5 @@
|
||||
# icsutils
|
||||
|
||||
Tools to work with ics files in bash.
|
||||
Tools to work with ics files in bash.
|
||||
|
||||
* `gcgetics.sh` : Extract google calender IDs and ICS links from given embedded google calendar
|
||||
|
165
gcgetics.sh
Executable file
165
gcgetics.sh
Executable file
@@ -0,0 +1,165 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Author: Martin Winkler
|
||||
# License: Please refer to the repository
|
||||
# Origin: https://winklerfamilie.eu/git/SmallThings/icsutils.git
|
||||
|
||||
# Exit on error. Append "|| true" if you expect an error.
|
||||
set -o errexit
|
||||
# Exit on error inside any functions or subshells.
|
||||
set -o errtrace
|
||||
# Do not allow use of undefined vars. Use ${VAR:-} to use an undefined VAR
|
||||
set -o nounset
|
||||
# Catch the error in case mysqldump fails (but gzip succeeds) in `mysqldump |gzip`
|
||||
set -o pipefail
|
||||
|
||||
# gc = google calendar
|
||||
gc::getIcsUsage() {
|
||||
cat <<USAGE_END
|
||||
Usage: ${0##*/} [OPTIONS] [URL/FILE]
|
||||
|
||||
Parses a google calendar embbeded URL content for any number
|
||||
of containted google calendar id (cid).
|
||||
|
||||
[OPTIONS]
|
||||
--file, -f : Input is a file containing a previous curl
|
||||
of a google calendar embbeded link.
|
||||
--help, -h : Show this help.
|
||||
-- : End of Options.
|
||||
|
||||
[URL/FILE]
|
||||
Such a URL usually starts with:
|
||||
"https://calendar.google.com/calendar/../embed?"
|
||||
Where ".." may be empty or a more specific reference.
|
||||
|
||||
If [URL/FILE] is empty or "-", standard input is used.
|
||||
|
||||
USAGE_END
|
||||
}
|
||||
|
||||
gc::makeIcsUrl() {
|
||||
# Exclude public holiday calendar
|
||||
local rexHoliday='group\.v\.calendar'
|
||||
[[ "${1:?}" =~ $rexHoliday ]] && return 1
|
||||
echo "https://calendar.google.com/calendar/ical/${1}/public/basic.ics"
|
||||
}
|
||||
|
||||
gc::findcid() {
|
||||
local arg=""
|
||||
local content=""
|
||||
local file=0
|
||||
local cids=()
|
||||
local title=()
|
||||
|
||||
local color_green= ; [ -t 1 ] && color_green='\033[1;32m'
|
||||
local color_blue= ; [ -t 1 ] && color_blue='\033[1;34m'
|
||||
local color_red= ; [ -t 1 ] && color_red='\033[2;31m'
|
||||
local color_less= ; [ -t 1 ] && color_less='\033[0m'
|
||||
|
||||
for arg in "${@}" ; do
|
||||
case "$1" in
|
||||
--file|-f)
|
||||
file=1
|
||||
shift 1 ;;
|
||||
--)
|
||||
shift && break ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ "${1}" = "-" ]] || [ -z "${1}" ] ; then
|
||||
file=1
|
||||
shift
|
||||
fi
|
||||
if (( file )) ; then
|
||||
content=$(<"${1:-"/dev/stdin"}")
|
||||
else
|
||||
# could grep for "cids", but unsure if result is always on one line
|
||||
content="$(curl --silent -L "${1:-}")"
|
||||
fi
|
||||
|
||||
while IFS= read -r line || [[ "${line}" ]] ; do
|
||||
cids+=("${line}")
|
||||
done < <(grep -oP '(?<=")[^"]*@(group|group\.v)\.calendar\.google\.com(?=")' <<<"${content}")
|
||||
|
||||
while IFS= read -r line || [[ "${line}" ]] ; do
|
||||
title+=("${line}")
|
||||
done < <(grep -oP '(?<="title":")[^"]*(?=")' <<<"${content}")
|
||||
|
||||
for i in "${!cids[@]}" ; do
|
||||
printf '%12s: %b%s%b\n' "Title" "${color_green}" "${title[$i]}" "${color_less}"
|
||||
printf '%12s: %s\n' "Calendar ID" "${cids[$i]}"
|
||||
printf '%12s: %b' "ICS Url" "${color_blue}"
|
||||
gc::makeIcsUrl "${cids[$i]}" || printf '%b\n' "${color_red}No ics file for this calendar${color_less}"
|
||||
printf '%b' "${color_less}"
|
||||
echo
|
||||
done
|
||||
}
|
||||
|
||||
gc::getIcs() {
|
||||
local arg=
|
||||
local element=
|
||||
local opt=""
|
||||
|
||||
readonly shortMax=80
|
||||
local shortEnd=0
|
||||
|
||||
local color_yellow= ; [ -t 1 ] && color_yellow='\033[1;33m'
|
||||
local color_less= ; [ -t 1 ] && color_less='\033[0m'
|
||||
|
||||
# shellcheck disable=SC2034 # arg not used
|
||||
for arg in "${@}" ; do
|
||||
case "$1" in
|
||||
--help|-h)
|
||||
gc::getIcsUsage
|
||||
return 0 ;;
|
||||
--file|-f)
|
||||
opt="-f"
|
||||
shift ;;
|
||||
--)
|
||||
shift && break ;;
|
||||
esac
|
||||
done
|
||||
|
||||
local args=("${@}")
|
||||
|
||||
# Use standard input if no files are present
|
||||
[ $# -eq 0 ] && args[0]="-"
|
||||
|
||||
for element in "${args[@]}" ; do
|
||||
if [[ $# -gt 1 ]] ; then
|
||||
printf "%b## CID information from: " "${color_yellow}"
|
||||
# Shorten the URL of PATH if it is greater than $shortMax
|
||||
if [[ ${#element} -gt ${shortMax} ]] ; then
|
||||
shortEnd=$((${#element} - shortMax/2))
|
||||
printf '%s[...]%s' \
|
||||
"${element:0:$((shortMax/2))}" \
|
||||
"${element:${shortEnd}:${#element}}"
|
||||
else
|
||||
printf '%s' "${element}"
|
||||
fi
|
||||
printf '%b\n\n' "${color_less}"
|
||||
fi
|
||||
gc::findcid ${opt} "${element}"
|
||||
done
|
||||
}
|
||||
|
||||
### Check if script is _sourced
|
||||
### https://stackoverflow.com/a/28776166
|
||||
_sourced=0
|
||||
if [ -n "${ZSH_EVAL_CONTEXT:-}" ]; then
|
||||
case ${ZSH_EVAL_CONTEXT:-} in *:file) _sourced=1;; esac
|
||||
elif [ -n "${KSH_VERSION:-}" ]; then
|
||||
[ "$(cd "$(dirname -- "$0")" && pwd -P)/$(basename -- "$0")" \
|
||||
!= "$(cd "$(dirname -- "${.sh.file}")" && pwd -P)/$(basename -- "${.sh.file}")" ] && _sourced=1
|
||||
elif [ -n "${BASH_VERSION:-}" ]; then
|
||||
(return 0 2>/dev/null) && _sourced=1
|
||||
else # All other shells: examine $0 for known shell binary filenames
|
||||
# Detects `sh` and `dash`; add additional shell filenames as needed.
|
||||
case ${0##*/} in sh|dash) _sourced=1;; esac
|
||||
fi
|
||||
###
|
||||
|
||||
if (( ! _sourced )); then
|
||||
gc::getIcs "${@}"
|
||||
fi
|
||||
|
Reference in New Issue
Block a user