aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/cron/task.cron2
-rwxr-xr-xtools/csv/csv.2geojson46
-rwxr-xr-xtools/csv/csv.move_column18
-rwxr-xr-xtools/csv/csv.reorder17
-rwxr-xr-xtools/desktop/password-store.sh51
-rwxr-xr-xtools/desktop/takeshot78
-rwxr-xr-xtools/docker/dktags29
-rwxr-xr-xtools/gis/match-road.sh148
-rwxr-xr-xtools/git/check-repos.sh48
-rwxr-xr-xtools/git/swap-protocol.bash25
-rwxr-xr-xtools/github/github-release.sh154
-rw-r--r--tools/gpx/footer1
-rwxr-xr-xtools/gpx/gpx.check.py85
-rwxr-xr-xtools/gpx/gpx.merge_gpx.sh5
-rwxr-xr-xtools/gpx/gpx.merge_trk.sh4
-rwxr-xr-xtools/gpx/gpx2geojson.sh48
-rw-r--r--tools/gpx/header10
-rwxr-xr-xtools/init/check_upstream24
-rwxr-xr-xtools/init/exit.sh5
-rwxr-xr-xtools/init/load-settings.sh70
-rwxr-xr-xtools/init/sync.sh37
-rwxr-xr-xtools/install.sh30
-rwxr-xr-xtools/markdown/reveal45
-rwxr-xr-xtools/misc/brightness.sh10
-rwxr-xr-xtools/misc/diff-highlight213
-rwxr-xr-xtools/misc/flash.sh39
-rwxr-xr-xtools/misc/mvt_decode.py11
-rwxr-xr-xtools/misc/ocr16
-rwxr-xr-xtools/misc/refresh-todo.sh5
-rwxr-xr-xtools/misc/simple_cors_server.py18
-rwxr-xr-xtools/misc/sync-gist.sh21
-rwxr-xr-xtools/misc/transfer22
-rwxr-xr-xtools/osm/josm_install.sh8
-rw-r--r--tools/osm/note1
-rw-r--r--tools/osm/osm18
-rwxr-xr-xtools/osm/osm.api.changeset.add10
-rwxr-xr-xtools/osm/osm.api.changeset.close3
-rwxr-xr-xtools/osm/osm.api.changeset.commit80
-rwxr-xr-xtools/osm/osm.api.changeset.create25
-rwxr-xr-xtools/osm/osm.api.changeset.update9
-rwxr-xr-xtools/osm/osm.api.changeset.upload6
-rwxr-xr-xtools/osm/osm.api.fetch6
-rwxr-xr-xtools/osm/osm.api.fetch.full5
-rwxr-xr-xtools/osm/osm.api.fetch.history6
-rwxr-xr-xtools/osm/osm.api.member.relation4
-rwxr-xr-xtools/osm/osm.api.referenced.relation6
-rwxr-xr-xtools/osm/osm.api.referenced.way5
-rwxr-xr-xtools/osm/osm.api.upload.to12
-rwxr-xr-xtools/osm/osm.file.get4
-rwxr-xr-xtools/osm/osm.file.get.full4
-rwxr-xr-xtools/osm/osm.file.query4
-rwxr-xr-xtools/osm/osm.goto3
-rwxr-xr-xtools/osm/osm.help33
-rwxr-xr-xtools/osm/osm.list.ids3
-rwxr-xr-xtools/osm/osm.list.tag10
-rwxr-xr-xtools/osm/osm.list.tags15
-rwxr-xr-xtools/osm/osm.member.relation8
-rwxr-xr-xtools/osm/osm.osc.by_member31
-rwxr-xr-xtools/osm/osm.osc.by_tag45
-rwxr-xr-xtools/osm/osm.osm.remove9
-rwxr-xr-xtools/osm/osm.pbf.update41
-rwxr-xr-xtools/osm/osm.query3
-rwxr-xr-xtools/osm/sequence_number.sh22
-rwxr-xr-xtools/sns/mastodon.sh17
-rwxr-xr-xtools/task/tkk7
-rwxr-xr-xtools/unix/fdswap41
-rwxr-xr-xtools/wiki/diary49
-rwxr-xr-xtools/wiki/log.sh31
-rwxr-xr-xtools/wiki/notify7
69 files changed, 0 insertions, 1926 deletions
diff --git a/tools/cron/task.cron b/tools/cron/task.cron
deleted file mode 100644
index 7521cca..0000000
--- a/tools/cron/task.cron
+++ /dev/null
@@ -1,2 +0,0 @@
1# Push changes on ~/.task
2*/20 * * * * cd ~/.task && git add * && git commit -am update && git push origin 2>&1
diff --git a/tools/csv/csv.2geojson b/tools/csv/csv.2geojson
deleted file mode 100755
index e742be6..0000000
--- a/tools/csv/csv.2geojson
+++ /dev/null
@@ -1,46 +0,0 @@
1#! /bin/bash
2
3# -s to skip specify columns of longitude and latitude
4for i in "$@"
5do
6case $i in
7 -s)
8 lon_col=0; lat_col=1
9 shift;;
10
11 *)
12 csv=$i
13 shift;;
14esac
15done
16
17# if no -s option, just read from input
18if [ "$lon_col" != "0" ]; then
19 # show each field with index in csv
20 echo -------------- > /dev/tty
21 head -1 < $csv | tr ',' '\n' | nl > /dev/tty
22 echo -------------- > /dev/tty
23 echo > /dev/tty
24
25 # get index of lon/lat column
26 read -p "Number of longitude column: " lon_col
27 read -p "Number of latitude column: " lat_col
28fi
29
30(which dos2unix &>/dev/null && dos2unix <$csv || cat $csv) |\
31# move lon and lat to the first and second column
32awk -F',' -v lon_th=$lon_col -v lat_th=$lat_col '\
33 BEGIN{OFS=","}\
34 {printf $lon_th "," $lat_th; for (i=1; i<= NF; i++) if (i != lat_th && i != lon_th) printf "," $i; print ""}\
35 ' |\
36# change csv into array format, like [lon, lat, "field1", field2...]
37sed 's/[^,]*/"\0"/g; s/.*/[\0]/g' |\
38# wrap other fields as a json object, like [lon, lat, {...}]
39jq -s '.[0][2:] as $fields | .[1:][] | [.[0], .[1], ([$fields, .[2:]] | transpose | map({(.[0]): .[1]}) | add)]' |\
40# create array of geojson point features
41jq '{"type": "Feature", "properties": .[2], "geometry":{ "type": "Point", "coordinates": [(.[0] | tonumber), (.[1] | tonumber)] } }' |\
42# wrap features as geojson format
43jq -s '{"type": "FeatureCollection", "features": .}' |\
44tee /tmp/geojson
45
46echo stored into /tmp/geojson > /dev/tty
diff --git a/tools/csv/csv.move_column b/tools/csv/csv.move_column
deleted file mode 100755
index a62701f..0000000
--- a/tools/csv/csv.move_column
+++ /dev/null
@@ -1,18 +0,0 @@
1#! /bin/bash
2
3# show each field with index in csv
4echo -------------- > /dev/tty
5head -1 < $1 | sed 's/,/ /g' | awk '{for (i=1; i<=NF; i++) printf $i "_" i " "; print ""}' > /dev/tty
6echo -------------- > /dev/tty
7echo > /dev/tty
8
9# get index of lon/lat column
10read -p "Move which column? " origin_col
11read -p "To which index? " new_col
12
13cat $1 |
14# move lon and lat to the first and second column
15awk -F',' -v OFS="," -v origin_th=$origin_col -v new_th=$new_col '\
16 {for (i=1; i<= NF; i++) if (i == new_th) printf $origin_th OFS $i OFS; else if (i == origin_th); else printf $i OFS; print ""}\
17 ' |\
18sed 's/,$//g'
diff --git a/tools/csv/csv.reorder b/tools/csv/csv.reorder
deleted file mode 100755
index 8a64239..0000000
--- a/tools/csv/csv.reorder
+++ /dev/null
@@ -1,17 +0,0 @@
1#! /bin/bash
2
3# show each field with index in csv
4echo -------------- > /dev/tty
5head -1 < $1 | awk -F',' '{for (i=1; i<=NF; i++) printf $i "_" i " "; print ""}' > /dev/tty
6echo -------------- > /dev/tty
7echo > /dev/tty
8
9read -p "type column numbers by new order, like 3 2 1: " order
10
11arrange=$(echo $order | sed -r 's/([^ ]+)/$\1/g' | tr ' ' ',')
12
13cat $1 |\
14awk -F',' "BEGIN{OFS=\",\"}{print $arrange}" |\
15tee /tmp/csv
16
17echo "Also copied to /tmp/csv" > /dev/tty
diff --git a/tools/desktop/password-store.sh b/tools/desktop/password-store.sh
deleted file mode 100755
index 1de3148..0000000
--- a/tools/desktop/password-store.sh
+++ /dev/null
@@ -1,51 +0,0 @@
1#! /bin/bash
2
3# Use rofi to quickly access password by command 'pass'
4# xsel needed !!
5
6ROFI_ARGS=( "-font" "Hack 22" )
7
8find ~/.password-store -name '*gpg' -printf %P\\n | \
9sed 's/.gpg$//' | \
10rofi -dmenu "${ROFI_ARGS[@]}" | {
11 # Get arguments for command 'pass'
12 read ARG1 ARG2
13
14 if [[ -z $ARG1 ]]; then
15 exit 1
16 elif [[ $ARG1 == edit ]]; then
17 # Edit an existing password
18 alacritty --hold -e pass edit $ARG2 && \
19 rofi -e Password Edited: $ARG2
20 else
21 # If pass fails, then it means password doesn't exists
22 set pipefail
23
24 pass $ARG1 | {
25 # If command fails, just fail directly
26 read PASSWORD; [[ -z $PASSWORD ]] && exit 1
27
28 # Simply copy password into system clipboard
29 echo $PASSWORD | xsel -ib
30
31 # Show success message, and display extra contents
32 rofi "${ROFI_ARGS[@]}" \
33 -e "Copied: $ARG1 $(echo; echo; cat | sed '1{/^$/d}')"
34 } || {
35 # Make sure user want to create a new password
36 return_code=$(alacritty -e sh -c '
37 dialog --yesno "Password does not exist, Generate a new one?" 8 30;
38 echo "$?"
39 ')
40 [[ $return_code == 1 ]] && exit 1
41
42 # Generate a new password by ARG1
43 alacritty -e pass generate $ARG1 --clip && \
44
45 # Show success message
46 rofi "${ROFI_ARGS[@]}" -e "Password Created and Copied: $ARG1"
47 }
48
49 # TODO: if return code is 2, it means gpg password is not cached
50 fi
51}
diff --git a/tools/desktop/takeshot b/tools/desktop/takeshot
deleted file mode 100755
index 09252f3..0000000
--- a/tools/desktop/takeshot
+++ /dev/null
@@ -1,78 +0,0 @@
1#!/usr/bin/env bash
2
3## Copyright (C) 2020-2022 Aditya Shakya <adi1090x@gmail.com>
4## Everyone is permitted to copy and distribute copies of this file under GNU-GPL3
5
6## Script to take screenshots with maim
7
8time=`date +%Y-%m-%d-%H-%M-%S`
9geometry=`xrandr | head -n1 | cut -d',' -f2 | tr -d '[:blank:],current'`
10dir="`xdg-user-dir PICTURES`"
11file="Screenshot_${time}_${geometry}.png"
12
13# notify and view screenshot
14notify_view () {
15 dunstify -u low --replace=699 -i /usr/share/archcraft/icons/dunst/picture.png "Copied to clipboard."
16 viewnior ${dir}/"$file"
17 if [[ -e "$dir/$file" ]]; then
18 dunstify -u low --replace=699 -i /usr/share/archcraft/icons/dunst/picture.png "Screenshot Saved."
19 else
20 dunstify -u low --replace=699 -i /usr/share/archcraft/icons/dunst/picture.png "Screenshot Deleted."
21 fi
22}
23
24# countdown
25countdown () {
26 for sec in `seq $1 -1 1`; do
27 dunstify -t 1000 --replace=699 -i /usr/share/archcraft/icons/dunst/timer.png "Taking shot in : $sec"
28 sleep 1
29 done
30}
31
32# take shots
33shotnow () {
34 cd ${dir} && maim -u -f png | tee "$file" | xclip -selection clipboard -t image/png
35 notify_view
36}
37
38shot5 () {
39 countdown '5'
40 sleep 1 && cd ${dir} && maim -u -f png | tee "$file" | xclip -selection clipboard -t image/png
41 notify_view
42}
43
44shot10 () {
45 countdown '10'
46 sleep 1 && cd ${dir} && maim -u -f png | tee "$file" | xclip -selection clipboard -t image/png
47 notify_view
48}
49
50shotwin () {
51 cd ${dir} && maim -u -f png -i `xdotool getactivewindow` | tee "$file" | xclip -selection clipboard -t image/png
52 notify_view
53}
54
55shotarea () {
56 cd ${dir} && maim -u -f png -s -b 2 -c 0.35,0.55,0.855 | tee "$file" | xclip -selection clipboard -t image/png
57 notify_view
58}
59
60if [[ ! -d "$dir" ]]; then
61 mkdir -p "$dir"
62fi
63
64if [[ "$1" == "--now" ]]; then
65 shotnow
66elif [[ "$1" == "--in5" ]]; then
67 shot5
68elif [[ "$1" == "--in10" ]]; then
69 shot10
70elif [[ "$1" == "--win" ]]; then
71 shotwin
72elif [[ "$1" == "--area" ]]; then
73 shotarea
74else
75 echo -e "Available Options : --now --in5 --in10 --win --area"
76fi
77
78exit 0
diff --git a/tools/docker/dktags b/tools/docker/dktags
deleted file mode 100755
index 5a91434..0000000
--- a/tools/docker/dktags
+++ /dev/null
@@ -1,29 +0,0 @@
1#!/bin/bash
2
3# Orignally copied from https://stackoverflow.com/a/39454426/7051075
4
5if [ $# -lt 1 ]
6then
7cat << HELP
8
9dktags -- list all tags for a Docker image on a remote registry.
10
11EXAMPLE:
12 - list all tags for ubuntu:
13 dktags ubuntu
14
15 - list all php tags containing apache:
16 dktags php apache
17
18HELP
19fi
20
21image="$1"
22tags=`wget -q https://registry.hub.docker.com/v1/repositories/${image}/tags -O - | sed -e 's/[][]//g' -e 's/"//g' -e 's/ //g' | tr '}' '\n' | awk -F: '{print $3}'`
23
24if [ -n "$2" ]
25then
26 tags=` echo "${tags}" | grep "$2" `
27fi
28
29echo "${tags}"
diff --git a/tools/gis/match-road.sh b/tools/gis/match-road.sh
deleted file mode 100755
index d9beaae..0000000
--- a/tools/gis/match-road.sh
+++ /dev/null
@@ -1,148 +0,0 @@
1#!/usr/bin/env bash
2#
3# Author: Pham
4#
5# This script accepts a single GPX file as parameter and
6# output the processed GPX body to STDOUT, using Mapbox Map Matching API v4.
7# read doc at: https://docs.mapbox.com/api/legacy/map-matching-v4/
8#
9# Example:
10#
11# match-road.sh raw.gpx > new.gpx
12#
13# Hint:
14#
15# Remember to put Mapbox Access Token at the top!
16
17#set -x
18set -e
19
20# put yout Mapbox token here
21ACCESS_TOKEN=$(cat ~/settings/tokens/mapbox)
22# number of coordinates for each Mapbox Map Matching API request, Maximum value is 100
23LIMIT=100
24# define the lowest confidence of accepted matched points
25THRESHOLD=0.0001
26
27if [[ -z $1 ]]; then echo "You need to give a gpx file!"; exit 1; fi
28ORIGIN_DATA=/tmp/$(basename $1).origin
29RESPONSES=/tmp/$(basename $1).responses && true > $RESPONSES
30MATCHED=/tmp/$(basename $1).matched
31
32# extract data from the given gpx file
33# only keep first point and remove the rest which in the same "second"
34# input: [gpx format]
35# output: [121.0179739,14.5515336] 1984-01-01T08:00:46
36get_data() {
37 sed -nr '/<trkpt /, /<\/trkpt>/ {H; /<\/trkpt>/ {x; s/\n/ /g; p; s/.*//; x}}' $1 |
38 sed -nr 'h; s/.*lon="([^"]+).*/\1/; H; g
39 s/.*lat="([^"]+).*/\1/; H; g
40 # If trkpt has no time, leave it blank
41 /time/ {
42 s/.*<time>([^.]+).*<\/time>.*/\1/
43 H; g
44 }
45 s/^[^\n]+\n//; s/\n/ /g; p' |
46 sed -r 's/^([^ ]+) ([^ ]+)/[\1,\2]/' |
47 awk '!_[$2]++'
48}
49
50# Output GeoJSON object for Map Matching API
51# input: [121.0179739,14.5515336] 1984-01-01T08:00:46
52# output: {type: "Feature", properties: {coordTimes: [...]}, geometry: {type: "LineString", coordinates: [...]}}
53make_geojson() {
54 # change input to format like: [[lon, lat], time]
55 awk '{printf("[%s,\"%s\"]\n", $1, $2)}' |
56 jq '[inputs] | {type: "Feature", geometry: {type: "LineString", coordinates: map(.[0])}, properties: {coordTimes: (map(.[1]))}}'
57}
58
59# Read GeoJSON body from STDIN, and return result from Mapbox Map Matching API
60query_matched_points() {
61 curl -X POST -s --data @- \
62 --header "Content-Type:application/json" \
63 https://api.mapbox.com/matching/v4/mapbox.driving.json?access_token=$ACCESS_TOKEN
64}
65
66# Get valid data from Map Matching API response
67# output format is [coordinates] [index-of-original-data], like:
68# [121.0179739,14.5515336] 35
69# If the point is newly added, the index would be -1, like
70# [121.0189339,14.5525931] -1
71validate_matched_points() {
72 VALID_DATA=$(jq ".features[] | if(.properties.confidence < $THRESHOLD) then .geometry.coordinates=(.properties.indices|map(.+1)) else . end")
73
74 echo $VALID_DATA |
75 jq -cr '.properties | [.matchedPoints, (.indices | map(.+1))] | transpose[] | "\(.[0]) \(.[1])"' > $MATCHED
76
77 echo $VALID_DATA | jq -c '.geometry.coordinates[]' |
78 while read point; do
79 if [[ ${point:0:1} != '[' ]]; then
80 echo $(sed -n "$point p" $ORIGIN_DATA) | while read coor time; do echo $coor $(date -d $time +%s); done
81 sed -i 1d $MATCHED
82 elif head -1 $MATCHED | grep -F $point > /dev/null; then
83 index=$(head -1 $MATCHED | cut -d' ' -f2)
84 echo $point $(sed -n "$index p" $ORIGIN_DATA | cut -d' ' -f2 | date -f - +%s)
85 sed -i 1d $MATCHED
86 else
87 echo $point -1
88 fi
89 done
90}
91
92# Put existing timestamps to matched points, and interpolate new timestamps into new points
93complete_data() {
94 # interpolate timestamps to newly added points
95 awk '{COOR[NR][0]=$1; N++; COOR[NR][1]=$2} END{for (i=1; i<=N; i++) {printf COOR[i][0]; if (COOR[i][1] != -1) {print " "COOR[i][1]; LAST=i} else {while(COOR[i+n][1] == -1) n++; print " "COOR[LAST][1]+(COOR[i+n][1]-COOR[LAST][1])*(i-LAST)/(i+n-LAST)}}}' |
96 while read coor unix_time; do
97 # Transform unix timestamp into human readable time format, like following:
98 # Transform [121.018088,14.5516] 18.50
99 # Into [121.018088,14.5516] 1970-01-01T08:00:18.50Z
100 echo $coor $(date -d @$unix_time +'%Y-%m-%dT%H:%M:%S.%2NZ')
101 done
102}
103
104# Make GPX format for output
105# Take input with format: [lon,lat] [time]
106make_gpx() {
107 sed -E 's/\[([^,]+),([^,]+)\] (.*)/ <trkpt lon="\1" lat="\2"><time>\3<\/time><\/trkpt>/' |
108 sed "1i \
109<gpx version=\"1.1\" creator=\"Garmin Connect\"\n\
110 xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd\"\n\
111 xmlns=\"http://www.topografix.com/GPX/1/1\"\n\
112 xmlns:gpxtpx=\"http://www.garmin.com/xmlschemas/TrackPointExtension/v1\"\n\
113 xmlns:gpxx=\"http://www.garmin.com/xmlschemas/GpxExtensions/v3\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n\
114 <trk>\n <trkseg>" |
115 sed "\$a \ \ \ \ <\/trkseg>\n <\/trk>\n<\/gpx>"
116}
117
118get_data $1 > $ORIGIN_DATA
119
120#RAW_REQUEST=$(basename $1 | tr '.' '_')_request.geojson
121#cat $ORIGIN_DATA | make_geojson | jq '.properties.stroke="#ff0000"' > $RAW_REQUEST
122
123# Consume raw data with serveral request
124while [ -s $ORIGIN_DATA ]; do
125 # Take original data by limited points for each time: [121.0179739,14.5515336] 1984-01-01T08:00:46
126 # Make geojson body: {type: "Feature", properties: {coordTimes: [...]}, geometry: {type: "LineString", coordinates: [...]}}
127 # Call Mapbox Map Matching API: {geometry: {coordinates: [...]}, properties: {confidence: 0.9, matching: [...], indices: [...]}}
128 # Get valid point and index by confidence value: [121.0179739,14.5515336] 5
129 # complete_data
130 head -$LIMIT $ORIGIN_DATA |
131 make_geojson |
132 query_matched_points |
133 tee -a $RESPONSES |
134 validate_matched_points |
135 complete_data
136
137 # Remove processed raw data
138 sed -i "1,$LIMIT d" $ORIGIN_DATA
139done | make_gpx
140#make_geojson > test.geojson
141
142#RAW_RESPONSE=$(basename $1 | tr '.' '_')_response.geojson
143#MATCHED_POINTS=$(basename $1 | tr '.' '_')_matched.geojson
144#jq . $RESPONSES | jq -s '.[0].features=[.[]|.features[]] | .[0] | del(.code) | .features=(.features|map(.properties.stroke="#00ff00"))' > $RAW_RESPONSE
145#jq ".features=(.features|map(select(.properties.confidence>=$THRESHOLD).geometry.coordinates=.properties.matchedPoints)|map(.properties.stroke=\"#0000ff\"))" $RAW_RESPONSE > $MATCHED_POINTS
146#
147#DEBUG=$(basename $1 | tr '.' '_')_total.geojson
148#cat $RAW_REQUEST $RAW_RESPONSE $MATCHED_POINTS | jq -s '{type: "FeatureCollection", features: ([.[0]] + .[1].features + .[2].features)}' > $DEBUG
diff --git a/tools/git/check-repos.sh b/tools/git/check-repos.sh
deleted file mode 100755
index 5180fc9..0000000
--- a/tools/git/check-repos.sh
+++ /dev/null
@@ -1,48 +0,0 @@
1#! /bin/bash
2
3LIST=~/.repos
4[[ $1 == -n ]] && {
5 COUNT_ONLY=true
6 count=0
7}
8
9
10# Only works when file ~/.repos exists and readable
11if [ ! -r $LIST ]; then
12 echo File ~/.repos not found/readable
13 exit 1
14fi
15
16
17while read repo remote; do
18 [[ "$repo" =~ ^[[:space:]]*#.* ]] && continue
19
20 # In case repo is consists of variable like $HOME
21 # Use eval to get git information
22 eval cd $repo 2>/dev/null || {
23 echo Repo $repo is inaccessible
24 exit 1
25 }
26
27 # Changes in working dir, not yet to be a commit
28 changes="$(git -c color.status=always status --short)"
29
30 # Diff between from local repo and remote
31 cherry="$([ -n "`git remote`" ] && git cherry)"
32
33 if [[ $COUNT_ONLY == true ]]; then
34 # If '-n' is specified, only count repo with changes/local-diff
35 [[ -n "$changes" || -n "$cherry" ]] && (( count++ ))
36 else
37 # Or, just print their status
38 echo Check $repo
39 [[ -n "$changes" ]] && echo "$changes"
40 [[ -n "$cherry" ]] && echo -e "\e[31m[ahead]\e[0m"
41 fi
42done <$LIST
43
44
45# If '-n' is specified, print number of repos with changes/local-diff
46[[ $COUNT_ONLY == true ]] && echo $count
47
48exit 0
diff --git a/tools/git/swap-protocol.bash b/tools/git/swap-protocol.bash
deleted file mode 100755
index b7f4db2..0000000
--- a/tools/git/swap-protocol.bash
+++ /dev/null
@@ -1,25 +0,0 @@
1#! /usr/bin/env bash
2# Get the first remote URL within git/https protocol on github.com
3# Swap the protocol, and apply new protocol to every remaining remotes
4
5target=''
6extra=''
7
8# For each remote
9git remote -v \
10| while read remote url etc; do
11 # Set fetch/push URL seperately
12 [[ $etc =~ push ]] && extra='--push' || extra=''
13
14 if [[ $url =~ git@.*github.com ]]; then
15 target=${target:-https}
16 # git@ -> https://
17 [[ $target == https ]] && sed -E 's#^git@(.+):(.+)$#https://\1/\2#' <<<$url | xargs git remote set-url $extra $remote
18 elif [[ $url =~ https://.*github.com ]]; then
19 target=${target:-git}
20 # https:// -> git@
21 [[ $target == git ]] && sed -E 's#^https://([^/]+)/(.+)$#git@\1:\2#' <<<$url | xargs git remote set-url $extra $remote
22 fi
23done
24
25git remote -v
diff --git a/tools/github/github-release.sh b/tools/github/github-release.sh
deleted file mode 100755
index 70ba672..0000000
--- a/tools/github/github-release.sh
+++ /dev/null
@@ -1,154 +0,0 @@
1#!/usr/bin/env sh
2#
3# Author: Hsieh Chin Fan (typebrook) <typebrook@gmail.com>
4# License: MIT
5# https://gist.github.com/typebrook/4947769e266173303d8848f496e272c9
6#
7# Originally created by stefanbuck
8# fork from: https://gist.github.com/stefanbuck/ce788fee19ab6eb0b4447a85fc99f447
9#
10# --
11# This script manages a release note or its asset with GitHub API v3.
12# It accepts the following parameters:
13#
14# * repo
15# * tag
16# * type (asset or edit)
17# * filename
18# * github_api_token
19# * action (optional, could be upload, overwrite, rename, delete, default to be upload)
20# * extra (optional, new filename for action 'rename')
21# * create (optional, create a new release if it doesn't exist)
22#
23# Example:
24#
25# # Upload a file as asset. If there is a asset with the same filename, then overwrite it.
26# github-release.sh github_api_token=TOKEN repo=stefanbuck/playground tag=v0.1.0 type=asset filename=./build.zip overwrite=true
27#
28# # Edit a release note with file content
29# github-release.sh github_api_token=TOKEN repo=stefanbuck/playground tag=v0.1.0 type=edit filename=note
30
31# Check dependencies.
32set -e
33
34# Validate settings.
35[ "$TRACE" ] && set -x
36# Keep tty
37exec 3>&1
38
39CONFIG=$@
40
41for line in $CONFIG; do
42 eval "$line"
43done
44
45# Define variables.
46GH_API="https://api.github.com"
47GH_REPO="$GH_API/repos/$repo"
48GH_TAGS="$GH_REPO/releases/tags/$tag"
49AUTH="Authorization: token $github_api_token"
50
51if [ "$tag" = 'LATEST' ]; then
52 GH_TAGS="$GH_REPO/releases/latest"
53fi
54if [ "$type" = '' ]; then
55 sed -E -n -e ' /^$/ q; /# --/,$ s/^# *//p' "$0"
56 exit 0
57fi
58
59# Validate token.
60curl -o /dev/null -sH "$AUTH" $GH_REPO || { echo "Error: Invalid repo, token or network issue!"; exit 1; }
61
62# Read asset tags.
63response=$(curl -sH "$AUTH" $GH_TAGS)
64
65# Get ID of the release.
66release_id=$(echo "$response" | grep -m1 -w \"id\": | sed -E -e 's/[^0-9]//g')
67if [ -z "$release_id" ]; then
68 if [ "$create" = 'true' ]; then
69 body=$(cat <<EOF
70{
71 "tag_name": "$tag",
72 "target_commitish": "master",
73 "name": "$tag",
74 "body": "",
75 "draft": false,
76 "prerelease": false
77}
78EOF
79 )
80 response=$(curl -H "$AUTH" -H "Content-Type: application/json" -d "$body" "$GH_REPO/releases")
81 release_id=$(echo "$response" | grep -m1 -w \"id\": | sed -E -e 's/[^0-9]//g')
82 else
83 echo "Error: Failed to get release id for tag: $tag"; echo "$response" | awk 'length($0)<100' >&2
84 exit 1
85 fi
86fi
87
88post_asset() {
89 # Upload asset
90 echo "Uploading asset... " >&3
91 # Construct url
92 GH_ASSET="https://uploads.github.com/repos/$repo/releases/$release_id/assets?name=$1"
93
94 curl --data-binary @"$filename" -H "$AUTH" -H "Content-Type: application/octet-stream" $GH_ASSET
95}
96
97rename_asset() {
98 echo "Renaming asset($1) from $2 to $3" >&3
99 curl -X PATCH -H "$AUTH" -H "Content-Type: application/json" \
100 --data "{\"name\":\"$3\", \"label\":\"$3\"}" "$GH_REPO/releases/assets/$1"
101}
102
103delete_asset() {
104 echo "Deleting asset($1)... " >&3
105 curl -X "DELETE" -H "$AUTH" "$GH_REPO/releases/assets/$1"
106}
107
108upload_asset() {
109 # Get ID of the asset based on given filename.
110 # If exists, delete it.
111 eval $(echo "$response" | grep -C2 "\"name\": \"$(basename $filename)\"" | grep -m 1 "id.:" | grep -w id | tr : = | tr -cd '[[:alnum:]]=' | sed 's/id/asset_id/')
112 if [ "$asset_id" = "" ]; then
113 echo "No need to overwrite asset"
114 post_asset $(basename $filename)
115 else
116 if [ "$action" = "overwrite" ]; then
117 new_asset_id=$(post_asset "bak_$(basename $filename)" | sed -E 's/^\{[^{]+"id":([0-9]+).+$/\1/')
118 [ "$new_asset_id" = "" ] && exit 1 || delete_asset "$asset_id"
119
120 rename_asset "$new_asset_id" "bak_$(basename $filename)" "$(basename $filename)"
121 elif [ "$action" = "rename" ]; then
122 rename_asset "$asset_id" "$filename" "$extra"
123 elif [ "$action" = "delete" ]; then
124 delete_asset "$asset_id"
125 exit 0
126 else
127 echo "File already exists on tag $tag"
128 echo "If you want to overwrite it, set action=overwrite"
129 exit 1
130 fi
131 fi
132}
133
134edit_release() {
135 GH_RELEASE="$GH_REPO/releases/$release_id"
136 body=$(cat <<EOF
137{
138 "tag_name": "$tag",
139 "target_commitish": "master",
140 "name": "$tag",
141 "body": "$(cat $filename | sed 's/"/\\"/g; $! s/$/\\n/' | tr -d '\n')",
142 "draft": false,
143 "prerelease": false
144}
145EOF
146 )
147 curl -X PATCH -H "$AUTH" -H "Content-Type: application/json" -d "$body" $GH_RELEASE
148}
149
150case $type in
151 asset) upload_asset;;
152 edit) edit_release;;
153 *) echo "type should be 'asset' or 'edit'";;
154esac
diff --git a/tools/gpx/footer b/tools/gpx/footer
deleted file mode 100644
index d0759c0..0000000
--- a/tools/gpx/footer
+++ /dev/null
@@ -1 +0,0 @@
1</gpx>
diff --git a/tools/gpx/gpx.check.py b/tools/gpx/gpx.check.py
deleted file mode 100755
index 10be97c..0000000
--- a/tools/gpx/gpx.check.py
+++ /dev/null
@@ -1,85 +0,0 @@
1#!/usr/bin/env python3
2
3import sys
4import os
5import argparse
6import copy
7import fileinput
8from osgeo import ogr
9import osr
10import urllib.parse
11
12def rewrite_gpx(filename):
13 for line in fileinput.input(filename, inplace=True):
14 if fileinput.isfirstline() and "'" in line:
15 line = '<?xml version="1.0" encoding="UTF-8"?>'
16 if fileinput.filelineno() == 2 and "version" not in line:
17 line = line.replace('<gpx', '<gpx version="1.1"')
18 print(line.rstrip('\n'))
19
20def check_valid(filename, threshold, add_prefix):
21 rewrite_gpx(filename)
22
23 driver = ogr.GetDriverByName('GPX')
24 try:
25 dataSource = driver.Open(filename)
26 except Exception:
27 pass
28 if dataSource is None:
29 print("could not open")
30 sys.exit(1)
31
32 inSpatialRef = osr.SpatialReference()
33 inSpatialRef.ImportFromEPSG(4326)
34 outSpatialRef = osr.SpatialReference()
35 outSpatialRef.ImportFromEPSG(3857)
36 to3857 = osr.CoordinateTransformation(inSpatialRef, outSpatialRef)
37 to4326 = osr.CoordinateTransformation(outSpatialRef, inSpatialRef)
38
39 trkLayer = dataSource.GetLayer(4)
40 trkpt = trkLayer.GetNextFeature()
41 flag = False
42 while trkpt:
43 nextTrkpt = trkLayer.GetNextFeature()
44 if nextTrkpt:
45 geom1 = trkpt.GetGeometryRef()
46 geom1.Transform(to3857)
47 geom2 = nextTrkpt.GetGeometryRef()
48 geom2.Transform(to3857)
49 distance = geom1.Distance(geom2)
50
51 geom1.Transform(to4326)
52 geom2.Transform(to4326)
53 if distance >= threshold:
54 if not flag:
55 print(f'{filename} has problem, the following urls shows the points with distance far from {threshold}m:')
56 print()
57 flag = True
58 if add_prefix:
59 dir = os.path.dirname(filename)
60 if dir:
61 dir += '/'
62 os.rename(filename, f'{dir}invalid_{os.path.basename(filename)}')
63
64 geojson = '{{"type": "LineString", "coordinates": [[{}, {}], [{}, {}]]}}'.format(
65 geom1.GetX(), geom1.GetY(),
66 geom2.GetX(), geom2.GetY()
67 )
68 encoded = urllib.parse.quote(geojson)
69 print('http://geojson.io/#data=data:application/json,{}'.format(encoded))
70 print()
71 else:
72 break
73 trkpt = nextTrkpt
74
75def main(argv):
76 parser = argparse.ArgumentParser()
77 parser.add_argument('file', help="you can add multiple gpx files at the same time", nargs='+')
78 parser.add_argument("-i", help="add prefix to invalid files", action="store_true")
79 parser.add_argument("-d", help="distance of tolerance(m), 100 by default", dest="distance", default=100)
80 args = parser.parse_args()
81 for file in args.file:
82 check_valid(file, float(args.distance), args.i)
83
84if __name__ == '__main__':
85 main(sys.argv)
diff --git a/tools/gpx/gpx.merge_gpx.sh b/tools/gpx/gpx.merge_gpx.sh
deleted file mode 100755
index 4b024a7..0000000
--- a/tools/gpx/gpx.merge_gpx.sh
+++ /dev/null
@@ -1,5 +0,0 @@
1#!/bin/bash
2
3GPX_DIR=$(dirname $0)
4
5sed '/<trk/,/<\/trk>/ p' -nr | cat $GPX_DIR/header - $GPX_DIR/footer
diff --git a/tools/gpx/gpx.merge_trk.sh b/tools/gpx/gpx.merge_trk.sh
deleted file mode 100755
index c3a72d4..0000000
--- a/tools/gpx/gpx.merge_trk.sh
+++ /dev/null
@@ -1,4 +0,0 @@
1#!/bin/bash
2
3sed '/<trk>/,/<\/name>/ d; /<\/trk>/ d; /<\/gpx>/ i \ \ <\/trk>' |\
4awk '/<trkseg>/ && !x {print " <trk>\n <name>combined_trk</name>"; x=1} 1'
diff --git a/tools/gpx/gpx2geojson.sh b/tools/gpx/gpx2geojson.sh
deleted file mode 100755
index eefcf5e..0000000
--- a/tools/gpx/gpx2geojson.sh
+++ /dev/null
@@ -1,48 +0,0 @@
1#! /bin/bash
2
3<$1 xq '.gpx |
4 (
5 label $out |
6 if .wpt != null then [.wpt] else break $out end |
7 flatten[] |
8 {
9 type: "Feature",
10 properties: { name: .name },
11 geometry: {
12 type: "Point",
13 coordinates: [
14 (.["@lon"]|tonumber),
15 (.["@lat"]|tonumber),
16 (.ele | if . == null then null else tonumber end)
17 ]
18 }
19 }
20 ),
21 (
22 label $out |
23 if .trk != null then [.trk] else break $out end |
24 flatten[] |
25 {
26 type: "Feature",
27 properties: { name: .name },
28 geometry: {
29 type: "MultiLineString",
30 coordinates:
31 [.trkseg] | flatten | map(
32 .trkpt | map(
33 [
34 (.["@lon"]|tonumber),
35 (.["@lat"]|tonumber),
36 (.ele | if . == null then null else tonumber end)
37 ]
38 )
39 )
40 }
41 }
42 )
43' | jq -s '
44 {
45 type: "FeatureCollection",
46 features: .
47 }
48'
diff --git a/tools/gpx/header b/tools/gpx/header
deleted file mode 100644
index 1912e8b..0000000
--- a/tools/gpx/header
+++ /dev/null
@@ -1,10 +0,0 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
2<gpx xmlns="http://www.topografix.com/GPX/1/1" creator="MapSource 6.10.2" version="1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
3
4 <metadata>
5 <link href="http://www.garmin.com">
6 <text>Garmin International</text>
7 </link>
8 <time>2019-12-18T06:17:16Z</time>
9 <bounds maxlat="24.554773" maxlon="121.293261" minlat="24.534487" minlon="121.284309"/>
10 </metadata>
diff --git a/tools/init/check_upstream b/tools/init/check_upstream
deleted file mode 100755
index fa6d277..0000000
--- a/tools/init/check_upstream
+++ /dev/null
@@ -1,24 +0,0 @@
1#! /bin/bash
2
3# This script is for repo forked from others
4# check $1(repo) if upstream branch origin/master is
5# ahead of local branch $2(default to dev)
6
7if [ ! -d "$1" ]; then
8 return 0
9fi
10
11head='dev'
12if [ $# -eq 2 ]
13then
14 head=$2
15fi
16
17cd "$1" && \
18git fetch origin && \
19if ! git rev-list "$head" | grep "$(git rev-parse origin/master)" > /dev/null; then
20 [[ $(git pull my) == 'Alrady up to date.' ]] || \
21 echo "New commit at" "$1"
22fi
23
24echo "$(date)" check "$1" >> "$SETTING_DIR/log" || echo error happens when check upstream at $1
diff --git a/tools/init/exit.sh b/tools/init/exit.sh
deleted file mode 100755
index 3723670..0000000
--- a/tools/init/exit.sh
+++ /dev/null
@@ -1,5 +0,0 @@
1#! /usr/bin/env bash
2
3#if [[ `cat /etc/hostname` != 'vultr' ]]; then
4# rsync -a --delete ~/.thunderbird/ pham@topo.tw:~/.thunderbird &
5#fi
diff --git a/tools/init/load-settings.sh b/tools/init/load-settings.sh
deleted file mode 100755
index ff8ba3c..0000000
--- a/tools/init/load-settings.sh
+++ /dev/null
@@ -1,70 +0,0 @@
1trap 'exit.sh' EXIT
2
3export SETTING_DIR=${SETTING_DIR:=$HOME/helper}
4export EDITOR=vim
5export TERM=xterm-256color
6export XDG_CONFIG_HOME=~/.config
7
8# Get current shell
9export shell=$(</proc/$$/cmdline sed -E 's/(.)-.+$/\1/' | tr -d '[\0\-]')
10shell=${shell##*/}
11
12# load custom aliases
13source $SETTING_DIR/alias
14[[ -d $SETTING_DIR/private ]] && for f in $SETTING_DIR/private/*; do source $f; done
15
16# Add custom scripts into PATH
17BIN_DIR=$HOME/bin
18PATH=$BIN_DIR:$PATH
19mkdir -p $BIN_DIR
20find $BIN_DIR -xtype l -exec rm {} + 2>/dev/null
21find $SETTING_DIR/tools -type f -executable -exec realpath {} + | \
22xargs -I{} ln -sf {} $BIN_DIR
23
24# Mail
25MAIL=$HOME/Maildir
26
27# sync with important git repos
28setsid sync.sh
29
30# local
31PATH=$PATH:$HOME/.local/bin
32# go
33PATH=$PATH:$HOME/go/bin
34# android-studio
35PATH=$PATH:$HOME/android-studio/bin
36# cargo
37PATH=$PATH:$HOME/.cargo/bin
38# yarn
39PATH=$PATH:$HOME/.yarn/bin
40
41# fzf
42if which fzf &>/dev/null; then
43 fzf_preview() { fzf --preview 'cat {}'; }
44 source ~/.fzf.${shell} &>/dev/null
45fi
46
47# Set zsh or bash
48if [[ $- =~ i ]]; then
49 if [[ $shell == zsh ]]; then
50 setopt extended_glob
51 fpath=($SETTING_DIR/zsh $fpath)
52 alias history='history -i'
53 autoload compinit; compinit
54
55 #autoload -U deer
56 #zle -N deer
57 #bindkey '\ek' deer
58 bindkey -s '\ek' 'fzf_preview '
59 elif [[ $shell == bash ]]; then
60 shopt -s extglob
61 HISTTIMEFORMAT='%Y-%m-%d %T '
62
63 bind -m emacs-standard -x '"\ek": fzf_preview'
64 fi
65fi
66
67# Working DIR
68[[ `pwd` == $HOME ]] && cd ~/Downloads
69
70true
diff --git a/tools/init/sync.sh b/tools/init/sync.sh
deleted file mode 100755
index bcd7bed..0000000
--- a/tools/init/sync.sh
+++ /dev/null
@@ -1,37 +0,0 @@
1#!/bin/bash
2
3# If git is working in other process, then don't sync again
4pidof git >/dev/null && exit 0
5
6# my repo
7sync() {
8 {
9 cd $1 && [[ -n `git remote -v` ]] || return
10 } 2>/dev/null
11 GIT_SSH_COMMAND="ssh -o ControlMaster=no" git pull --quiet || echo Has trouble when syncing `pwd`
12}
13sync $SETTING_DIR &
14sync ~/log &
15sync ~/blog &
16sync ~/git/vps &
17sync ~/.task &
18sync ~/.password-store &
19sync ~/.vim/vim-init &
20sync ~/bean &
21
22while true; do
23 if test $(jobs -r | wc -l) -gt 0; then
24 sleep 1;
25 else
26 which notify-send &>/dev/null && notify-send 'Repos synced'
27 break
28 fi
29done &
30
31# others repo
32#check_upstream ~/git/tig || echo in `pwd` >/dev/tty &
33
34# thunderbird
35#if [[ `cat /etc/hostname` != 'vultr' ]]; then
36# rsync -a pham@topo.tw:~/.thunderbird/ ~/.thunderbird &
37#fi
diff --git a/tools/install.sh b/tools/install.sh
deleted file mode 100755
index 1f1dd86..0000000
--- a/tools/install.sh
+++ /dev/null
@@ -1,30 +0,0 @@
1#! /usr/bin/env bash
2
3set -e
4
5# Default settings
6SETTING_DIR=${SETTING_DIR:-~/helper}
7REPO=${REPO:-typebrook/helper}
8REMOTE=${REMOTE:-https://github.com/${REPO}.git}
9BRANCH=${BRANCH:-dev}
10RCFILE=${RCFILE:-~/.$(basename $SHELL)rc}
11
12if [ ! -d $SETTING_DIR ]; then
13 git clone --depth=1 --branch "$BRANCH" "$REMOTE" "$SETTING_DIR" || {
14 error "git clone of helper repo failed"
15 exit 1
16 }
17fi
18
19# Write initial commands into .bashrc or .zshrc
20sed -i'.bak' "\^# $REPO^, /^$/ d" $RCFILE
21cat >>$RCFILE <<EOF
22
23# $REPO
24export SETTING_DIR=$SETTING_DIR
25source \$SETTING_DIR/tools/init/load-settings.sh
26EOF
27
28cd "$SETTING_DIR" || exit 1
29git swapprotocol
30make
diff --git a/tools/markdown/reveal b/tools/markdown/reveal
deleted file mode 100755
index c6bf97b..0000000
--- a/tools/markdown/reveal
+++ /dev/null
@@ -1,45 +0,0 @@
1#! /bin/bash
2
3if [[ ! $1 =~ (.md|.slide)$ || ! -e $1 ]]; then
4 echo markdown file is not given >&2
5 exit 1
6fi
7
8# Available themes:
9# beige black blood league moon night serif simple sky solarized white
10THEME=${THEME:-serif}
11
12# Available highlight theme:
13# a11y-dark a11y-light agate androidstudio an-old-hope
14# arduino-light arta ascetic atom-one-dark atom-one-dark-reasonable
15# atom-one-light base16 brown-paper brown-papersq.png codepen-embed
16# color-brewer dark default devibeans docco
17# far felipec foundation github github-dark github-dark-dimmed
18# gml googlecode gradient-dark gradient-light grayscale hybrid
19# idea intellij-light ir-black isbl-editor-dark isbl-editor-light kimbie-dark
20# kimbie-light lightfair lioshi magula mono-blue monokai
21# monokai-sublime night-owl nnfx-dark nnfx-light nord obsidian
22# panda-syntax-dark panda-syntax-light paraiso-dark paraiso-light pojoaque
23# pojoaque.jpg purebasic qtcreator-dark qtcreator-light rainbow
24# routeros school-book shades-of-purple srcery stackoverflow-dark
25# stackoverflow-light sunburst tokyo-night-dark tokyo-night-light tomorrow-night-blue
26# tomorrow-night-bright vs2015 vs xcode xt256
27HIGHLIGHT_THEME=${HIGHLIGHT_THEME:-base16/zenburn}
28
29
30if [[ $1 =~ / ]]; then
31 DIR="`dirname $1`"
32else
33 DIR="`pwd`"
34fi
35
36set -x
37docker run --rm \
38 -u `id -u`:`id -g` \
39 -v "$DIR":/slides \
40 -p 1948:1948 \
41 webpronl/reveal-md:5.3.4 \
42 `basename $1` \
43 --static /slides \
44 #--theme ${THEME} \
45 #--highlight-theme ${HIGHLIGHT_THEME} \
diff --git a/tools/misc/brightness.sh b/tools/misc/brightness.sh
deleted file mode 100755
index 4f548f5..0000000
--- a/tools/misc/brightness.sh
+++ /dev/null
@@ -1,10 +0,0 @@
1#! /usr/bin/env bash
2
3BACKLIGHT_DIR=/sys/class/backlight/intel_backlight
4
5CURRENT=$(cat $BACKLIGHT_DIR/brightness)
6MAX=$(cat $BACKLIGHT_DIR/max_brightness)
7
8echo " $CURRENT + ( $MAX * ${1/+} )" | \
9bc | \
10cut -d'.' -f1 >$BACKLIGHT_DIR/brightness
diff --git a/tools/misc/diff-highlight b/tools/misc/diff-highlight
deleted file mode 100755
index 08c88bb..0000000
--- a/tools/misc/diff-highlight
+++ /dev/null
@@ -1,213 +0,0 @@
1#!/usr/bin/perl
2
3use warnings FATAL => 'all';
4use strict;
5
6# Highlight by reversing foreground and background. You could do
7# other things like bold or underline if you prefer.
8my @OLD_HIGHLIGHT = (
9 color_config('color.diff-highlight.oldnormal'),
10 color_config('color.diff-highlight.oldhighlight', "\x1b[7m"),
11 color_config('color.diff-highlight.oldreset', "\x1b[27m")
12);
13my @NEW_HIGHLIGHT = (
14 color_config('color.diff-highlight.newnormal', $OLD_HIGHLIGHT[0]),
15 color_config('color.diff-highlight.newhighlight', $OLD_HIGHLIGHT[1]),
16 color_config('color.diff-highlight.newreset', $OLD_HIGHLIGHT[2])
17);
18
19my $RESET = "\x1b[m";
20my $COLOR = qr/\x1b\[[0-9;]*m/;
21my $BORING = qr/$COLOR|\s/;
22
23my @removed;
24my @added;
25my $in_hunk;
26
27# Some scripts may not realize that SIGPIPE is being ignored when launching the
28# pager--for instance scripts written in Python.
29$SIG{PIPE} = 'DEFAULT';
30
31while (<>) {
32 if (!$in_hunk) {
33 print;
34 $in_hunk = /^$COLOR*\@/;
35 }
36 elsif (/^$COLOR*-/) {
37 push @removed, $_;
38 }
39 elsif (/^$COLOR*\+/) {
40 push @added, $_;
41 }
42 else {
43 show_hunk(\@removed, \@added);
44 @removed = ();
45 @added = ();
46
47 print;
48 $in_hunk = /^$COLOR*[\@ ]/;
49 }
50
51 # Most of the time there is enough output to keep things streaming,
52 # but for something like "git log -Sfoo", you can get one early
53 # commit and then many seconds of nothing. We want to show
54 # that one commit as soon as possible.
55 #
56 # Since we can receive arbitrary input, there's no optimal
57 # place to flush. Flushing on a blank line is a heuristic that
58 # happens to match git-log output.
59 if (!length) {
60 local $| = 1;
61 }
62}
63
64# Flush any queued hunk (this can happen when there is no trailing context in
65# the final diff of the input).
66show_hunk(\@removed, \@added);
67
68exit 0;
69
70# Ideally we would feed the default as a human-readable color to
71# git-config as the fallback value. But diff-highlight does
72# not otherwise depend on git at all, and there are reports
73# of it being used in other settings. Let's handle our own
74# fallback, which means we will work even if git can't be run.
75sub color_config {
76 my ($key, $default) = @_;
77 my $s = `git config --get-color $key 2>/dev/null`;
78 return length($s) ? $s : $default;
79}
80
81sub show_hunk {
82 my ($a, $b) = @_;
83
84 # If one side is empty, then there is nothing to compare or highlight.
85 if (!@$a || !@$b) {
86 print @$a, @$b;
87 return;
88 }
89
90 # If we have mismatched numbers of lines on each side, we could try to
91 # be clever and match up similar lines. But for now we are simple and
92 # stupid, and only handle multi-line hunks that remove and add the same
93 # number of lines.
94 if (@$a != @$b) {
95 print @$a, @$b;
96 return;
97 }
98
99 my @queue;
100 for (my $i = 0; $i < @$a; $i++) {
101 my ($rm, $add) = highlight_pair($a->[$i], $b->[$i]);
102 print $rm;
103 push @queue, $add;
104 }
105 print @queue;
106}
107
108sub highlight_pair {
109 my @a = split_line(shift);
110 my @b = split_line(shift);
111
112 # Find common prefix, taking care to skip any ansi
113 # color codes.
114 my $seen_plusminus;
115 my ($pa, $pb) = (0, 0);
116 while ($pa < @a && $pb < @b) {
117 if ($a[$pa] =~ /$COLOR/) {
118 $pa++;
119 }
120 elsif ($b[$pb] =~ /$COLOR/) {
121 $pb++;
122 }
123 elsif ($a[$pa] eq $b[$pb]) {
124 $pa++;
125 $pb++;
126 }
127 elsif (!$seen_plusminus && $a[$pa] eq '-' && $b[$pb] eq '+') {
128 $seen_plusminus = 1;
129 $pa++;
130 $pb++;
131 }
132 else {
133 last;
134 }
135 }
136
137 # Find common suffix, ignoring colors.
138 my ($sa, $sb) = ($#a, $#b);
139 while ($sa >= $pa && $sb >= $pb) {
140 if ($a[$sa] =~ /$COLOR/) {
141 $sa--;
142 }
143 elsif ($b[$sb] =~ /$COLOR/) {
144 $sb--;
145 }
146 elsif ($a[$sa] eq $b[$sb]) {
147 $sa--;
148 $sb--;
149 }
150 else {
151 last;
152 }
153 }
154
155 if (is_pair_interesting(\@a, $pa, $sa, \@b, $pb, $sb)) {
156 return highlight_line(\@a, $pa, $sa, \@OLD_HIGHLIGHT),
157 highlight_line(\@b, $pb, $sb, \@NEW_HIGHLIGHT);
158 }
159 else {
160 return join('', @a),
161 join('', @b);
162 }
163}
164
165sub split_line {
166 local $_ = shift;
167 return map { /$COLOR/ ? $_ : (split //) }
168 split /($COLOR*)/;
169}
170
171sub highlight_line {
172 my ($line, $prefix, $suffix, $theme) = @_;
173
174 my $start = join('', @{$line}[0..($prefix-1)]);
175 my $mid = join('', @{$line}[$prefix..$suffix]);
176 my $end = join('', @{$line}[($suffix+1)..$#$line]);
177
178 # If we have a "normal" color specified, then take over the whole line.
179 # Otherwise, we try to just manipulate the highlighted bits.
180 if (defined $theme->[0]) {
181 s/$COLOR//g for ($start, $mid, $end);
182 chomp $end;
183 return join('',
184 $theme->[0], $start, $RESET,
185 $theme->[1], $mid, $RESET,
186 $theme->[0], $end, $RESET,
187 "\n"
188 );
189 } else {
190 return join('',
191 $start,
192 $theme->[1], $mid, $theme->[2],
193 $end
194 );
195 }
196}
197
198# Pairs are interesting to highlight only if we are going to end up
199# highlighting a subset (i.e., not the whole line). Otherwise, the highlighting
200# is just useless noise. We can detect this by finding either a matching prefix
201# or suffix (disregarding boring bits like whitespace and colorization).
202sub is_pair_interesting {
203 my ($a, $pa, $sa, $b, $pb, $sb) = @_;
204 my $prefix_a = join('', @$a[0..($pa-1)]);
205 my $prefix_b = join('', @$b[0..($pb-1)]);
206 my $suffix_a = join('', @$a[($sa+1)..$#$a]);
207 my $suffix_b = join('', @$b[($sb+1)..$#$b]);
208
209 return $prefix_a !~ /^$COLOR*-$BORING*$/ ||
210 $prefix_b !~ /^$COLOR*\+$BORING*$/ ||
211 $suffix_a !~ /^$BORING*$/ ||
212 $suffix_b !~ /^$BORING*$/;
213}
diff --git a/tools/misc/flash.sh b/tools/misc/flash.sh
deleted file mode 100755
index 93ce8fd..0000000
--- a/tools/misc/flash.sh
+++ /dev/null
@@ -1,39 +0,0 @@
1#! /bin/bash
2
3while true; do
4 CARDS="$(cat ~/log/flashcards.md | shuf | head -5)"
5 CARD="$(<<<"$CARDS" sed -n 3p)"
6
7 # Print the Question
8 <<<"$CARD" tr -s '\t' | cut -f1
9 echo
10 tput bold; tput setaf 1
11 <<<"$CARDS" tr -s '\t' | cut -f2 | tr '\n' '\t'
12 tput sgr0
13 echo
14 echo
15 echo ----
16 echo
17
18 # Get the User Input
19 read -er INPUT
20
21 # Print the Answer
22 ANSER=$(<<<"$CARD" tr -s '\t' | cut -f2)
23 echo
24 echo ----
25 echo
26
27 # If answer correctly, print the checked box
28 if [[ "$INPUT" == "$ANSER" ]]; then
29 tput setaf 2
30 echo '☑'
31 tput setaf 7
32 else
33 echo $ANSER
34 fi
35
36 echo
37 read
38 tput clear
39done
diff --git a/tools/misc/mvt_decode.py b/tools/misc/mvt_decode.py
deleted file mode 100755
index 7c9ac89..0000000
--- a/tools/misc/mvt_decode.py
+++ /dev/null
@@ -1,11 +0,0 @@
1#! /bin/env python3
2
3import mapbox_vector_tile
4import sys
5
6mvt = sys.argv[1]
7
8with open(mvt, 'rb') as f:
9 data = f.read()
10 decoded_data = mapbox_vector_tile.decode(data)
11 print(decoded_data)
diff --git a/tools/misc/ocr b/tools/misc/ocr
deleted file mode 100755
index 26594fe..0000000
--- a/tools/misc/ocr
+++ /dev/null
@@ -1,16 +0,0 @@
1#!/bin/bash
2# Dependencies: tesseract-ocr imagemagick scrot xsel
3
4SCR_IMG=`mktemp`
5trap "rm $SCR_IMG*" EXIT
6
7scrot -s $SCR_IMG.png -q 100
8# increase image quality with option -q from default 75 to 100
9
10mogrify -modulate 100,0 -resize 400% $SCR_IMG.png
11#should increase detection rate
12
13tesseract $SCR_IMG.png $SCR_IMG &> /dev/null
14cat $SCR_IMG.txt | trans -t zh-TW --brief --engine bing | cat $SCR_IMG.txt - | tr '\n' ' ' | xargs -I{} notify-send --urgency=critical translation '{}'
15
16exit
diff --git a/tools/misc/refresh-todo.sh b/tools/misc/refresh-todo.sh
deleted file mode 100755
index 7931536..0000000
--- a/tools/misc/refresh-todo.sh
+++ /dev/null
@@ -1,5 +0,0 @@
1#!/bin/bash
2
3# $1 as file, $2 as topic (Daily, Weekly, Monthly)
4# change markdown check-list to empty
5sed -i "/^## $2/,/^$/ s/\[.\]/\[ \]/" $1
diff --git a/tools/misc/simple_cors_server.py b/tools/misc/simple_cors_server.py
deleted file mode 100755
index 9d2c898..0000000
--- a/tools/misc/simple_cors_server.py
+++ /dev/null
@@ -1,18 +0,0 @@
1#!/usr/bin/env python3
2# encoding: utf-8
3"""Use instead of `python3 -m http.server` when you need CORS"""
4
5from http.server import HTTPServer, SimpleHTTPRequestHandler
6
7
8class CORSRequestHandler(SimpleHTTPRequestHandler):
9 def end_headers(self):
10 self.send_header('Access-Control-Allow-Origin', '*')
11 self.send_header('Access-Control-Allow-Methods', 'GET')
12 self.send_header('Cache-Control', 'no-store, no-cache, must-revalidate')
13 return super(CORSRequestHandler, self).end_headers()
14
15
16httpd = HTTPServer(('localhost', 8003), CORSRequestHandler)
17print('check localhost:8003')
18httpd.serve_forever()
diff --git a/tools/misc/sync-gist.sh b/tools/misc/sync-gist.sh
deleted file mode 100755
index 86cca04..0000000
--- a/tools/misc/sync-gist.sh
+++ /dev/null
@@ -1,21 +0,0 @@
1#! /bin/bash
2
3set -o pipefail
4set -e
5
6repo=~/gist/b0d2e7e67aa50298fdf8111ae7466b56
7
8while read -r commit; do
9
10 cd $repo
11 git checkout $commit
12 message="$(git show $commit | sed -n '1,4 d; /^diff/ q; s/^ //p')"
13
14 cd ~/git/Bash-Snippets
15 cp $repo/gist gist/gist
16 git add gist/gist && git commit -m "$message" || true
17done
18
19cd $repo
20git checkout master
21
diff --git a/tools/misc/transfer b/tools/misc/transfer
deleted file mode 100755
index 1fc2117..0000000
--- a/tools/misc/transfer
+++ /dev/null
@@ -1,22 +0,0 @@
1#! /bin/env sh
2
3if [ $# -eq 0 ];then
4 echo "No arguments specified.\nUsage:\n transfer <file|directory>\n ... | transfer <file_name>">&2;
5 return 1;
6fi;
7if tty -s; then
8 file="$1"; file_name=$(basename "$file");
9 if [ ! -e "$file" ]; then
10 echo "$file: No such file or directory">&2;
11 return 1;
12 fi;
13 if [ -d "$file" ];then
14 file_name="$file_name.zip" ,;
15 (cd "$file" && zip -r -q - .) | curl -w '\n' --progress-bar --upload-file "-" "https://topo.tw/up/$file_name" | tee /dev/null;
16 else
17 cat "$file" | curl -w '\n' --progress-bar --upload-file "-" "https://topo.tw/up/$file_name" | tee /dev/null;
18 fi;
19else
20 file_name=$1;
21 curl -w '\n' --progress-bar --upload-file "-" "https://topo.tw/up/$file_name" | tee /dev/null;
22fi;
diff --git a/tools/osm/josm_install.sh b/tools/osm/josm_install.sh
deleted file mode 100755
index 520875a..0000000
--- a/tools/osm/josm_install.sh
+++ /dev/null
@@ -1,8 +0,0 @@
1#!/bin/bash
2
3# scripts from https://josm.openstreetmap.de/wiki/Download#Webstart
4echo deb https://josm.openstreetmap.de/apt $(lsb_release -sc) universe | sudo tee /etc/apt/sources.list.d/josm.list > /dev/null &&\
5wget -q https://josm.openstreetmap.de/josm-apt.key -O- | sudo apt-key add - &&\
6sudo apt-get update &&\
7sudo apt-get remove josm josm-plugins &&\
8sudo apt-get install josm
diff --git a/tools/osm/note b/tools/osm/note
deleted file mode 100644
index aa51031..0000000
--- a/tools/osm/note
+++ /dev/null
@@ -1 +0,0 @@
1diff -y <(ls|sort) <(osm.help | cut -d' ' -f3 | sort | uniq)
diff --git a/tools/osm/osm b/tools/osm/osm
deleted file mode 100644
index 344f906..0000000
--- a/tools/osm/osm
+++ /dev/null
@@ -1,18 +0,0 @@
1#! /bin/sh
2
3export OSM_TEST_SERVER=https://master.apis.dev.openstreetmap.org
4export OSM_SERVER=https://api.openstreetmap.org
5export OSM_TES_SERVER=https://api.openstreetmap.org
6
7export OSM_API=$OSM_SERVER/api/0.6
8export OSM_USER_PASSWD=$(cat $SETTING_DIR/tokens/osm 2>/dev/null)
9
10FILENAME=$0
11
12utils.osm() {
13 vim $FILENAME && source $FILENAME
14}
15
16osm.api() {
17 curl -X GET $OSM_API/$1/$2
18}
diff --git a/tools/osm/osm.api.changeset.add b/tools/osm/osm.api.changeset.add
deleted file mode 100755
index 3e4878e..0000000
--- a/tools/osm/osm.api.changeset.add
+++ /dev/null
@@ -1,10 +0,0 @@
1#!/bin/sh
2
3element=$(cat)
4header=$(echo $element | grep -E "<(node|way|relation)\s")
5ele_type=$(echo $header | sed -r 's/.*<(node|way|relation).*$/\1/')
6id=$(echo $header | sed -r 's/.* id=\"([^"]+)\".*$/\1/')
7
8echo $element | \
9sed -r "s/^( *<(node|way|relation).*version[^ ]+ )(.*)$/\1changeset=\"$1\">/" | \
10curl -X PUT -u $OSM_USER_PASSWD -i -T - $OSM_API/$ele_type/$id
diff --git a/tools/osm/osm.api.changeset.close b/tools/osm/osm.api.changeset.close
deleted file mode 100755
index 3b016c3..0000000
--- a/tools/osm/osm.api.changeset.close
+++ /dev/null
@@ -1,3 +0,0 @@
1#!/bin/sh
2
3curl -X PUT -u $OSM_USER_PASSWD -i $OSM_API/changeset/$1/close
diff --git a/tools/osm/osm.api.changeset.commit b/tools/osm/osm.api.changeset.commit
deleted file mode 100755
index 6b67833..0000000
--- a/tools/osm/osm.api.changeset.commit
+++ /dev/null
@@ -1,80 +0,0 @@
1#!/bin/bash
2
3set -e
4shopt -s lastpipe
5
6OSM_SERVER=https://api.openstreetmap.org
7OSM_TEST_SERVER=https://master.apis.dev.openstreetmap.org
8if [[ $@ =~ '--serious' ]]; then
9 SERVER=$OSM_SERVER
10else
11 SERVER=$OSM_TEST_SERVER
12fi
13
14OSM_API=${SERVER}/api/0.6
15FILE=${@//--serious/}
16
17# Prompt for comment and User:Password
18if [[ ! -t 0 ]]; then
19 comment=$(cat)
20else
21 read -e -p 'Type comment: ' -r comment </dev/tty
22fi
23if [ -z ${OSM_USER_PASSWD} ]; then
24 read -e -p 'Type USER:PASSWD: ' -r OSM_USER_PASSWD </dev/tty
25fi
26
27create_changeset() {
28 SOURCE_TAG="${SOURCE:+$(printf "<tag k='source' v='%s'/>" $SOURCE)}"
29
30 curl ${OSM_API}/changeset/create \
31 --user ${OSM_USER_PASSWD} \
32 --upload-file - \
33 --silent \
34 <<EOF | tail -1
35<osm>
36 <changeset>
37 ${SOURCE_TAG}
38 <tag k='comment' v='${comment}'/>
39 <tag k='created_by' v='bash script'/>
40 <tag k='bot' v='yes'/>
41 </changeset>
42</osm>
43EOF
44}
45
46# Return http code after uploading a file
47uploade_file_to_changeset() {
48 curl -X POST $OSM_API/changeset/${changeset_id}/upload \
49 --user ${OSM_USER_PASSWD} -i \
50 --upload-file - \
51 --silent -o /dev/null -w "%{http_code}"
52}
53
54close_changeset() {
55 curl -X PUT ${OSM_API}/changeset/${changeset_id}/close \
56 --user ${OSM_USER_PASSWD} -i \
57 --silent -o /dev/null -w "%{http_code}"
58}
59
60# Create changeset with given information
61changeset_id=$(create_changeset)
62
63# Print created changeset id
64echo "Changeset created, check ${SERVER}/changeset/${changeset_id}" >/dev/tty
65echo ${changeset_id}
66
67# Upload OSC file to Changeset
68sed -Ee "/<(node|way|relation)/ s/>/ changeset=\"${changeset_id}\">/" $FILE |\
69uploade_file_to_changeset | if [[ $(cat) == '200' ]]; then
70 echo Upload file $FILE to changeset ${changeset_id} >/dev/tty
71else
72 exit 1
73fi
74
75# Close Changeset
76close_changeset | if [[ $(cat) == '200' ]]; then
77 echo Changeset ${changeset_id} closed >/dev/tty
78else
79 exit 1
80fi
diff --git a/tools/osm/osm.api.changeset.create b/tools/osm/osm.api.changeset.create
deleted file mode 100755
index ab9fe85..0000000
--- a/tools/osm/osm.api.changeset.create
+++ /dev/null
@@ -1,25 +0,0 @@
1#!/bin/sh
2
3set -e
4
5read -e -p 'Type comment: ' -r comment </dev/tty
6if [ -z $OSM_USER_PASSWD ]; then
7 read -e -p 'Type USER:PASSWD: ' -r OSM_USER_PASSWD </dev/tty
8fi
9
10info="<osm>
11 <changeset>
12 <tag k='comment' v='$comment'/>
13 <tag k='created_by' v='bash script'/>
14 <tag k='bot' v='yes'/>
15 </changeset>
16 </osm>
17 "
18
19changeset_id=$(echo $info |\
20 curl -u $OSM_USER_PASSWD --upload-file - $OSM_API/changeset/create |\
21 tail -1)
22
23echo >/dev/tty
24echo "changeset created, check $OSM_SERVER/changeset/$changeset_id" >/dev/tty
25echo $changeset_id | tee /tmp/changeset && echo copied to /tmp/changeset
diff --git a/tools/osm/osm.api.changeset.update b/tools/osm/osm.api.changeset.update
deleted file mode 100755
index 7267449..0000000
--- a/tools/osm/osm.api.changeset.update
+++ /dev/null
@@ -1,9 +0,0 @@
1#!/bin/sh
2
3ID=${1:-$(cat /tmp/changeset 2>/dev/null)}
4[ -z $ID ] && echo Please specify Changeset ID && exit 1
5
6read -e -p 'Type comment: ' -r comment </dev/tty
7
8echo "<osm><changeset><tag k=\"comment\" v=\"$comment\"/></changeset></osm>" | \
9curl -X PUT -u $OSM_USER_PASSWD -i -T - $OSM_API/changeset/$1
diff --git a/tools/osm/osm.api.changeset.upload b/tools/osm/osm.api.changeset.upload
deleted file mode 100755
index 96bdff4..0000000
--- a/tools/osm/osm.api.changeset.upload
+++ /dev/null
@@ -1,6 +0,0 @@
1#!/bin/sh
2
3cat $2 |\
4sed -r "/<(node|way|relation)/ s/>/ changeset=\"$1\">/" |\
5tee /dev/tty |\
6curl -X POST -u $OSM_USER_PASSWD -i -T - $OSM_API/changeset/$1/upload
diff --git a/tools/osm/osm.api.fetch b/tools/osm/osm.api.fetch
deleted file mode 100755
index 8460c5f..0000000
--- a/tools/osm/osm.api.fetch
+++ /dev/null
@@ -1,6 +0,0 @@
1#! /bin/sh
2
3# get .osm format data
4curl -X GET $OSM_API/$1/$2 |\
5tee /tmp/osm &&\
6echo content of $1 $2 is copied into /tmp/osm > /dev/tty
diff --git a/tools/osm/osm.api.fetch.full b/tools/osm/osm.api.fetch.full
deleted file mode 100755
index 5ee78b8..0000000
--- a/tools/osm/osm.api.fetch.full
+++ /dev/null
@@ -1,5 +0,0 @@
1#! /bin/sh
2
3curl -X GET $OSM_API/$1/$2/full |\
4tee /tmp/osm &&\
5echo "\n" content of $1 $2 and its members are copied into /tmp/osm > /dev/tty
diff --git a/tools/osm/osm.api.fetch.history b/tools/osm/osm.api.fetch.history
deleted file mode 100755
index bc837bd..0000000
--- a/tools/osm/osm.api.fetch.history
+++ /dev/null
@@ -1,6 +0,0 @@
1#! /bin/sh
2
3curl -X GET $OSM_API/$1/$2/history |\
4tee /tmp/osm &&\
5echo &&\
6echo "\n" history of $1 $2 are copied into /tmp/osm > /dev/tty
diff --git a/tools/osm/osm.api.member.relation b/tools/osm/osm.api.member.relation
deleted file mode 100755
index 5addef7..0000000
--- a/tools/osm/osm.api.member.relation
+++ /dev/null
@@ -1,4 +0,0 @@
1#! /bin/sh
2
3osm.api.referenced.relation $1 $2 |\
4osm.member.relation $1 $2 $3
diff --git a/tools/osm/osm.api.referenced.relation b/tools/osm/osm.api.referenced.relation
deleted file mode 100755
index 2ce0631..0000000
--- a/tools/osm/osm.api.referenced.relation
+++ /dev/null
@@ -1,6 +0,0 @@
1#! /bin/sh
2
3curl -X GET $OSM_API/$1/$2/relations |\
4tee /tmp/osm &&\
5echo &&\
6echo "\n" relations contain $1 $2 are copied into /tmp/osm > /dev/tty
diff --git a/tools/osm/osm.api.referenced.way b/tools/osm/osm.api.referenced.way
deleted file mode 100755
index 1d84238..0000000
--- a/tools/osm/osm.api.referenced.way
+++ /dev/null
@@ -1,5 +0,0 @@
1#!/bin/bash
2
3curl -X GET $OSM_API/node/$1/ways |\
4tee /tmp/osm &&\
5echo ways contain node $1 are copied into /tmp/osm > /dev/tty
diff --git a/tools/osm/osm.api.upload.to b/tools/osm/osm.api.upload.to
deleted file mode 100755
index 3979220..0000000
--- a/tools/osm/osm.api.upload.to
+++ /dev/null
@@ -1,12 +0,0 @@
1#! /bin/sh
2
3# allows multiple elements in osm body
4tee /tmp/osm |\
5osm.list.ids |\
6sed 's#.*#osm.extract \0 < /tmp/osm#g' |\
7sed "s/.*/\0 \| osm.api.changeset.add $1/g" |\
8while read -r command
9do
10 echo $command
11 source<(echo "($command &)")
12done
diff --git a/tools/osm/osm.file.get b/tools/osm/osm.file.get
deleted file mode 100755
index e2b67b4..0000000
--- a/tools/osm/osm.file.get
+++ /dev/null
@@ -1,4 +0,0 @@
1#! /bin/sh
2
3file=$1; shift
4osmium getid $file $@ --output-format=osm
diff --git a/tools/osm/osm.file.get.full b/tools/osm/osm.file.get.full
deleted file mode 100755
index 50ee2f1..0000000
--- a/tools/osm/osm.file.get.full
+++ /dev/null
@@ -1,4 +0,0 @@
1#! /bin/sh
2
3file=$1; shift
4osmium getid $file $@ --output-format=osm --add-referenced
diff --git a/tools/osm/osm.file.query b/tools/osm/osm.file.query
deleted file mode 100755
index 4a01b5b..0000000
--- a/tools/osm/osm.file.query
+++ /dev/null
@@ -1,4 +0,0 @@
1#! /bin/sh
2
3file=$1; shift
4osmium tags-filter $file $@ --output-format=osm --omit-referenced
diff --git a/tools/osm/osm.goto b/tools/osm/osm.goto
deleted file mode 100755
index 25bceaa..0000000
--- a/tools/osm/osm.goto
+++ /dev/null
@@ -1,3 +0,0 @@
1#!/bin/sh
2
3xdg-open https://www.openstreetmap.org/$1/$2
diff --git a/tools/osm/osm.help b/tools/osm/osm.help
deleted file mode 100755
index f4c20d2..0000000
--- a/tools/osm/osm.help
+++ /dev/null
@@ -1,33 +0,0 @@
1#! /bin/sh
2
3cat <<EOF
4COMMANDS:
5 osm.help
6 util.osm.edit
7 osm.api.changeset.create create a new changeset and return its ID
8 osm.api.changeset.update <changeset ID> update changeset with new comment
9 osm.api.changeset.upload <changeset ID> <osc file> upload osc file to the given changeset
10 osm.api.changeset.add <changeset ID> STDIN=osm element, add it into changeset
11 osm.api.changeset.close <changeset ID> close the given changeset
12 osm.api.fetch <element type> <element ID>
13 osm.api.fetch.full like .fetch, but return with all referenced elements
14 osm.api.fetch.history <element type> <element ID>
15 osm.api.member.relation <element type> <element ID> <member type> get first relations reference it as member type
16 osm.api.referenced.relation <element type> <element ID> get all relations reference this element
17 osm.api.referenced.way <element type> <element ID> get all ways reference this element
18 osm.api.upload.to
19
20 osm.file.cat
21 osm.file.get
22 osm.file.get.full
23 osm.file.query
24 osm.list.ids
25 osm.list.tag
26 osm.list.tags
27
28 osm.get.id
29 osm.query
30 osm.member.relation
31 osm.pbf.update
32 osm.osm.update
33EOF
diff --git a/tools/osm/osm.list.ids b/tools/osm/osm.list.ids
deleted file mode 100755
index 8e5d870..0000000
--- a/tools/osm/osm.list.ids
+++ /dev/null
@@ -1,3 +0,0 @@
1#! /bin/sh
2
3sed -nr 's/.*<(node|way|relation) id=\"([^"]+)\".*/\1 \2/p'
diff --git a/tools/osm/osm.list.tag b/tools/osm/osm.list.tag
deleted file mode 100755
index 76649a0..0000000
--- a/tools/osm/osm.list.tag
+++ /dev/null
@@ -1,10 +0,0 @@
1#!/bin/bash
2
3ele_pattern="(node|way|relation)"
4sed -nr "/<$ele_pattern/,/<\/$ele_pattern/ {
5 /<tag k=\"$1\"/ {
6 s/.*v=\"([^\"]+)\".*/\1/
7 h
8 }
9 /<\/$ele_pattern/ {x;p;s/.*//;x}
10}"
diff --git a/tools/osm/osm.list.tags b/tools/osm/osm.list.tags
deleted file mode 100755
index 767d32a..0000000
--- a/tools/osm/osm.list.tags
+++ /dev/null
@@ -1,15 +0,0 @@
1#!/bin/bash
2
3content=$(cat)
4echo $content | osm.list.ids | tr ' ' ',' > /tmp/osm
5
6for tag in $@
7do
8 echo $content |\
9 osm.list.tag $tag |\
10 paste -d',' /tmp/osm - > /tmp/osm.new &&\
11 mv /tmp/osm.new /tmp/osm
12done
13
14cat /tmp/osm
15echo "\ntag list is also copied into /tmp/osm" > /dev/tty
diff --git a/tools/osm/osm.member.relation b/tools/osm/osm.member.relation
deleted file mode 100755
index f8d4598..0000000
--- a/tools/osm/osm.member.relation
+++ /dev/null
@@ -1,8 +0,0 @@
1#! /bin/sh
2
3sed -nr "/<relation/,/<\/relation/ {
4 /<relation/ {s/.* id=\"([^\"]+)\".*/\1/;h}
5 /<member type=\"$1\" ref=\"$2\" role=\"$3\"/ {g;p;q}
6}
7$ {s/.*//;P}
8" | head -1
diff --git a/tools/osm/osm.osc.by_member b/tools/osm/osm.osc.by_member
deleted file mode 100755
index 5f9d9be..0000000
--- a/tools/osm/osm.osc.by_member
+++ /dev/null
@@ -1,31 +0,0 @@
1#!/bin/bash
2
3while read -r line
4do
5
6 TYPE=$(echo $line | cut -d ' ' -f1) # field1 is type
7 ID=$(echo $line | cut -d ' ' -f2) # field2 is ID
8
9 NEW_MEMBERS=$(echo $line |\
10 cut -d' ' -f3- |\
11 sed -r 's/([0-9]+)/<member type=\"relation\" ref=\"\1\" role=\"subarea\"\/>/g')
12
13 echo $NEW_MEMBERS
14
15 # print matched element with new tags to .osc file
16 cat $1 |\
17 sed -nr "/<$TYPE id=\"$ID\"/,/<\/$TYPE/ {
18 /<$TYPE id=\"$ID\"/ {
19 s/(version=\"[0-9]+\")(.*)/\1>/
20 a \ \ \ \ $NEW_MEMBERS
21 }
22 p
23 /<\/$TYPE/ q
24 }" >> $1.osc
25done
26
27# Add .osc structure for output
28sed -ir '1 i <osmChange version="0.6" generator="bash script">
29 1 i <modify>
30 $ a </modify>
31 $ a </osmChange>' $1.osc
diff --git a/tools/osm/osm.osc.by_tag b/tools/osm/osm.osc.by_tag
deleted file mode 100755
index cc92c1d..0000000
--- a/tools/osm/osm.osc.by_tag
+++ /dev/null
@@ -1,45 +0,0 @@
1#!/bin/bash
2
3# create new tags from input line, for example:
4# field1 field2 field3 field4 field5 field6 field7 field8...
5# [element type] [element ID] key1_added "value1" key2_added "value2" key3_removed key4_removed...
6
7# key should not quoted, value must be quoted
8# And keys which need to be removed must be placed at the end
9while read -r line
10do
11 TYPE=$(echo $line | cut -d ' ' -f1) # field1 is type
12 ID=$(echo $line | cut -d ' ' -f2) # field2 is ID
13
14 # transform key-value pair into tag format:
15 # <tag k="[key]" v="[value]"/>
16 # keys without values are omitted
17 NEW_TAGS=$(echo $line |\
18 cut -d' ' -f3- |\
19 sed -r 's/([^ "]+) (\"[^"]+\")/<tag k=\"\1\" v=\2\/>/g; s/>[^"]*$/>/')
20
21 # get regex pattern need to removed from original osm element:
22 # key1|key2|key3|key4
23 TAG_PATTERN=$(echo $line |\
24 cut -d' ' -f3- | xargs -n2 echo |\
25 cut -d' ' -f1 | paste -s -d'|')
26
27 echo $NEW_TAGS > /dev/tty
28
29 # print matched element with new tags to .osc file
30 cat $1 |\
31 sed -nr "/<$TYPE id=\"$ID\"/,/<\/$TYPE/ {
32 /<$TYPE id=\"$ID\"/ {
33 s/(version=\"[0-9]+\")(.*)/\1>/
34 a \ \ \ \ $NEW_TAGS
35 }
36 /<tag k=\"($TAG_PATTERN)\"/ !p
37 /<\/$TYPE/ q
38 }" >> $1.osc
39done
40
41# Add .osc structure for output
42sed -ir '1 i <osmChange version="0.6" generator="bash script">
43 1 i <modify>
44 $ a </modify>
45 $ a </osmChange>' $1.osc
diff --git a/tools/osm/osm.osm.remove b/tools/osm/osm.osm.remove
deleted file mode 100755
index 83d6ea8..0000000
--- a/tools/osm/osm.osm.remove
+++ /dev/null
@@ -1,9 +0,0 @@
1#!/bin/bash
2
3while read -r line
4do
5 # put element type and element ID into array
6 array=( $(echo $line) )
7 cat $1 |\
8 sed -i "/<$array[1] id=\"$array[2]\"/,/<\/$array[1]>/ d"
9done
diff --git a/tools/osm/osm.pbf.update b/tools/osm/osm.pbf.update
deleted file mode 100755
index 6c6f445..0000000
--- a/tools/osm/osm.pbf.update
+++ /dev/null
@@ -1,41 +0,0 @@
1#!/bin/bash
2
3set -e
4
5GEOFABRIK_SERVER=http://download.geofabrik.de/asia/taiwan-updates
6PBF_FILE=$1
7
8# get latest sequence number
9echo Fetching the latest sequence number
10LATEST_SEQ=$(curl --silent http://download.geofabrik.de/asia/taiwan-updates/state.txt |\
11 tail -1 | cut -d'=' -f2)
12echo Latest sequence number is $LATEST_SEQ
13
14# get current sequence number
15SEQ=$(osmium fileinfo $PBF_FILE |\
16 grep osmosis_replication_sequence_number |\
17 cut -d'=' -f2)
18echo File sequence number is $SEQ
19
20# while server has osc file with given sequence number,
21# get it and do file update
22while
23 (( SEQ++ ))
24 [ $SEQ -le $LATEST_SEQ ]
25do
26 mkdir -p changes
27 SEQ_PATH=$(echo $SEQ | sed -r 's/(.{1})(.{3})/00\1\/\2/')
28 CHANGE_URL=$GEOFABRIK_SERVER/000/$SEQ_PATH.osc.gz
29 echo $CHANGE_URL
30 curl -o changes/$SEQ.osc.gz $CHANGE_URL && \
31 osmium apply-changes $PBF_FILE changes/$SEQ.osc.gz \
32 --output-header=osmosis_replication_sequence_number=$SEQ \
33 --overwrite \
34 --output $SEQ.osm.pbf
35
36 mv $PBF_FILE $((SEQ-1)).osm.pbf
37 mv $SEQ.osm.pbf $PBF_FILE
38done
39
40echo
41echo File sequence number is $((SEQ-1)), already the latest one on Geofrbrik
diff --git a/tools/osm/osm.query b/tools/osm/osm.query
deleted file mode 100755
index 8d0b9f7..0000000
--- a/tools/osm/osm.query
+++ /dev/null
@@ -1,3 +0,0 @@
1#!/bin/bash
2
3osmium tags-filter - $@ --input-format=osm --output-format=osm --omit-referenced
diff --git a/tools/osm/sequence_number.sh b/tools/osm/sequence_number.sh
deleted file mode 100755
index eb365d0..0000000
--- a/tools/osm/sequence_number.sh
+++ /dev/null
@@ -1,22 +0,0 @@
1#!/bin/bash
2
3# $1 as --hour or --minute, $2 as timestamp
4# return the latest sequence number
5
6case $1 in
7 # hour difference with Tue Jun 4 03:00:00 UTC 2019
8 # sequence number=58940
9 --hour)
10 echo $[($2 - 1559617200)/3600 + 58940]
11 ;;
12
13 # minute difference with latest planet state file
14 --minute)
15 benchmark=benchmark
16 curl https://planet.openstreetmap.org/replication/minute/state > $benchmark
17 timeString=$(tail -1 $benchmark | tr -d 'timestamp=\\')
18 timestamp=$(date -d "$timeString" +%s)
19 seq=$(sed -n 2p $benchmark | tr -d "sequenceNumber=")
20 rm $benchmark
21 echo $[$seq - ($timestamp - $2)/60 - 1 ]
22esac
diff --git a/tools/sns/mastodon.sh b/tools/sns/mastodon.sh
deleted file mode 100755
index fb93bcd..0000000
--- a/tools/sns/mastodon.sh
+++ /dev/null
@@ -1,17 +0,0 @@
1#! /bin/bash
2
3# Restore mail in variable
4MAIL="$(cat)"
5
6# Only execute the following script when mail receiver is mastodon@topo.tw
7grep -qE "^X-Original-To: .*mastodon@topo.tw[>]?$" <<<"$MAIL" || exit 0
8# A little hacky way to check if mail is sent from me
9sed -nE '/^Received: /p;/^$/q' <<<"$(MAIL)" | wc -l | xargs -i test {} -lt 2 || exit 0
10
11# Leave log
12date >>~/Downloads/mastodon.log
13echo $$ >>~/Downloads/mastodon.log
14awk -v RS= 'NR>1' <<<"$MAIL" >>~/Downloads/mastodon.log
15
16# Use toot to send message on g0v.social
17awk -v RS= 'NR>1' <<<"$MAIL" | toot post >>/tmp/mastodon.log
diff --git a/tools/task/tkk b/tools/task/tkk
deleted file mode 100755
index 148d3f6..0000000
--- a/tools/task/tkk
+++ /dev/null
@@ -1,7 +0,0 @@
1#! /bin/bash
2
3PS1='task '
4while true; do
5 read -r -p 'task ' line </dev/tty;
6 task $line
7done
diff --git a/tools/unix/fdswap b/tools/unix/fdswap
deleted file mode 100755
index 251cdea..0000000
--- a/tools/unix/fdswap
+++ /dev/null
@@ -1,41 +0,0 @@
1#!/bin/bash
2#
3# fdswap
4#
5# Orignal author: ingvarha
6# ref: https://ingvarha.wordpress.com/2010/07/10/changing-a-process-file-descriptor-on-the-fly/
7
8if [ "$2" = "" ]; then
9<<HELP cat
10Usage: ${0##*/} /path/to/oldfile /path/to/newfile [pids]
11Example: ${0##*/} /var/log/daemon.log /var/log/newvolume/daemon.log 1234
12Example: ${0##*/} /dev/pts/53 /dev/null 2345
13HELP
14 exit 0
15fi
16
17if ! gdb --version &>/dev/null; then
18 echo "Unable to find gdb."
19 exit 1
20fi
21
22src="$1"; dst="$2"; shift; shift
23pids=$*
24
25for pid in ${pids:=$( /sbin/fuser $src | cut -d ':' -f 2 )};
26do
27 echo "src=$src, dst=$dst"
28 echo "$src has $pid using it"
29 cmd=$(mktemp)
30 {
31 echo "attach $pid"
32 echo 'call (int)open("'$dst'", 66, 0666)'
33 for ufd in $(LANG=C ls -l /proc/$pid/fd | \
34 grep "$src"\$ | awk ' { print $9; } ');
35 do echo 'call (int)dup2($1,'"$ufd"')'; done
36 echo 'call (int)close($1)'
37 echo 'detach'; echo 'quit'
38 sleep 5
39 } | tee /dev/tty >$cmd
40 gdb -x $cmd
41done
diff --git a/tools/wiki/diary b/tools/wiki/diary
deleted file mode 100755
index 3995ecf..0000000
--- a/tools/wiki/diary
+++ /dev/null
@@ -1,49 +0,0 @@
1#! /bin/bash
2
3today=~/log/`date +%y.w%W.md`
4
5specify_date() {
6 YEAR=${YEAR:-22}
7
8 while read -e -p 'Month? ' -r MONTH </dev/tty; do
9 [ -z $MONTH ] && MONTH=$(date +%m)
10 MONTH=$(printf "%02d" $MONTH)
11 date -d $YEAR-$MONTH-01 &>/dev/null && break
12 done
13
14 while read -e -p 'Day? ' -r DAY </dev/tty; do
15 [ -z $DAY ] && DAY=$(date +%d)
16 DAY=$(printf "%02d" $DAY)
17 date -d $YEAR-$MONTH-$DAY &>/dev/null && break
18 done
19
20 FILE=~/log/diary/20$YEAR-$MONTH-$DAY.md
21 vim -c 'Goyo' $FILE
22}
23
24print_today() {
25 [[ ! -e $today ]] && touch $today
26 cat $today
27}
28
29edit_today() {
30 vim -c Goyo $today
31}
32
33add_entry() {
34 [[ $# -ne 0 ]] && echo - "$@" >>$today
35 while read -e -r entry; do
36 echo $entry | sed -E 's/\t/ /g; s/(^[[:space:]]*)/\1- /' >>$today
37 done
38}
39
40case "$1" in
41 specify)
42 specify_date ;;
43 print)
44 print_today ;;
45 today)
46 edit_today ;;
47 *)
48 add_entry "$@" ;;
49esac
diff --git a/tools/wiki/log.sh b/tools/wiki/log.sh
deleted file mode 100755
index 4ef2c27..0000000
--- a/tools/wiki/log.sh
+++ /dev/null
@@ -1,31 +0,0 @@
1#! /bin/bash
2
3# Restore mail in variable
4MAIL="$(cat)"
5
6# Only execute the following script when mail receiver is log@topo.tw
7grep -qE "^X-Original-To: .*log@topo.tw[>]?$" <<<"$MAIL" || exit 0
8# A little hacky way to check if mail is sent from me
9sed -nE '/^Received: /p;/^$/q' <<<"$(MAIL)" | wc -l | xargs -i test {} -lt 2 || exit 0
10
11# Leave log
12date >>~/Downloads/log.log
13echo $$ >>~/Downloads/log.log
14awk -v RS= 'NR>1' <<<"$MAIL" >>~/Downloads/log.log
15
16LOG=~/log/`date +%y.w%W.md`
17TODAY="`date '+%a %b.%d'`"
18
19grep -Eq "^## ${TODAY}$" ${LOG} || \
20cat <<EOF >>${LOG}
21
22
23## $TODAY
24EOF
25
26
27# Save content to log file of current week
28echo >>${LOG}
29awk -v RS= 'NR>1' <<<"$MAIL" >>${LOG}
30
31{ cd ~/log && git add `basename ${LOG}` && git commit -m "Update by mail"; } >>~/Downloads/log.log
diff --git a/tools/wiki/notify b/tools/wiki/notify
deleted file mode 100755
index 6e510d8..0000000
--- a/tools/wiki/notify
+++ /dev/null
@@ -1,7 +0,0 @@
1#! /bin/sh
2
3exec >/dev/pts/$(ls /dev/pts -t | head -1)
4
5echo
6echo
7cat