-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathnextcloud-duplicates-tagger.sh
More file actions
236 lines (154 loc) · 5.1 KB
/
nextcloud-duplicates-tagger.sh
File metadata and controls
236 lines (154 loc) · 5.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
#!/bin/bash
# By Georgiy Sitnikov.
#
# AS-IS without any warranty
# Will search and tag all Duplicated files by user.
tagName=duplicate
NextcloudURL="https://yourFQDN/nextcloud"
user="user"
password="xxxxx-xxxxx-xxxxxx"
ignoreCertificate="false"
# Log Level: none|Info
LogLvL=Info
# Path to nextcloud
NextCloudPath=/var/www/nextcloud
#####################
### End of Config ###
#####################
LOCKFILE=/tmp/nextcloud-duplicates-tagger.tmp
if [[ "$ignoreCertificate" == "false" ]]; then
curlOptions=(-s -m 10 -u $user:$password)
else
curlOptions=(-s -k -m 10 -u $user:$password)
fi
# Check if config.php exist
[[ -r "$NextCloudPath"/config/config.php ]] || {
echo >&2 "[ERROR] config.php could not be read under "$NextCloudPath"/config/config.php. Please check the path and permissions"
exit 1
}
# Fetch data directory place from the config file
DataDirectory=$(grep datadirectory "$NextCloudPath"/config/config.php | cut -d "'" -f4)
# Check if user Directory exist
[[ -d "$DataDirectory/$user" ]] || {
echo >&2 "[ERROR] User "$user" could not be found. Please check if case is correct"
exit 1
}
getFileID() {
fileid="$(curl $curlOptions ''$NextcloudURL'/remote.php/dav/files/'${user}'/'${fileToTag}'' \
-X PROPFIND --data '<?xml version="1.0" encoding="UTF-8"?>
<d:propfind xmlns:d="DAV:">
<d:prop xmlns:oc="http://owncloud.org/ns">
<oc:fileid/>
</d:prop>
</d:propfind>' | xml_pp | grep "fileid" | sed -n 's/^.*<\(oc:fileid\)>\([^<]*\)<\/.*$/\2/p')"
[[ "$LogLvL" == "Info" ]] && { echo "[INFO] Searching Nextcloud Internal FileID for $fileToTag"; }
if [[ -z "$fileid" ]]; then
echo "[WARNING] File ID could not be found for a "$fileToTag" will skip it."
#exit 1
else
[[ "$LogLvL" == "Info" ]] && { echo "[INFO] FileID is $fileid."; }
fi
}
getTag() {
getAllTags="$(curl $curlOptions ''$NextcloudURL'/remote.php/dav/systemtags/' \
-X PROPFIND --data '<?xml version="1.0" ?>
<d:propfind xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns">
<d:prop>
<oc:id />
<oc:display-name />
<oc:user-visible />
<oc:user-assignable />
<oc:can-assign />
</d:prop>
</d:propfind>' | xml_pp | grep -B 1 -w "$tagName" | head -n 1)"
if [[ ! -z "$getAllTags" ]]; then
tagID="$(echo $getAllTags | sed -n 's/^.*<\(oc:id\)>\([^<]*\)<\/.*$/\2/p')"
[[ "$LogLvL" == "Info" ]] && { echo "[INFO] Internal TagID for tag $tagName is $tagID."; }
else
echo "[ERROR] Could to find tagID for a tag $tagName. Please check spelling and if tag exist"
exit 1
fi
}
SetTag() {
curl $curlOptions ''$NextcloudURL'/remote.php/dav/systemtags-relations/files/'$fileid/$tagID \
-X PUT -H "Content-Type: application/json" \
--data '{"userVisible":true,\
"userAssignable":true,\
"canAssign":true,\
"id":"'$tag'",\
"name":"'$tagName'"}'
echo "[PROGRESS] Setting tag $tagName for $fileToTag."
}
checkIfTagIsSet() {
if [[ -z "$fileid" ]]; then
getAllTags="$(curl $curlOptions ''$NextcloudURL'/remote.php/dav/systemtags-relations/files/'$fileid'' \
-X PROPFIND --data '<?xml version="1.0" ?>
<d:propfind xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns">
<d:prop>
<oc:id />
<oc:display-name />
<oc:user-visible />
<oc:user-assignable />
<oc:can-assign />
</d:prop>
</d:propfind>' | xml_pp | grep -w "$tagName")"
if [[ ! -z "$getAllTags" ]]; then
[[ "$LogLvL" == "Info" ]] && { echo "[INFO] Tag $tagName is already set for $fileToTag, skipping."; }
else
#echo "[INFO] Tag $tagName is not set"
SetTag
fi
fi
}
findDuplicates() {
echo "[PROGRESS] Searching for duplicates, this can take a long time..."
cd $DataDirectory/$user/files/
find . ! -empty -type f -exec md5sum {} + | sort | uniq -w32 -dD >>$LOCKFILE
[[ "$LogLvL" == "Info" ]] && { echo "[INFO] Finally finished it is $(wc -l $LOCKFILE | awk '{print $1}') duplicates found"; }
}
checkLockFile() {
if [ -f "$LOCKFILE" ]; then
# Remove lock file if script fails last time and did not run more than 10 days due to lock file.
echo "[WARNING] - An older Duplicates report found in a $LOCKFILE,
will use it to tag files, it contains $(wc -l $LOCKFILE | awk '{print $1}') duplicates.
If you want to perform new search, please delete this file under: $LOCKFILE
e.g. execute: rm $LOCKFILE
File will be automatically deleted if older than 10 days.
"
find "$LOCKFILE" -mtime +10 -type f -delete
#exit 1
fi
touch $LOCKFILE
}
# From https://gist.github.com/cdown/1163649
urlencode() {
local LANG=C i c e=''
for ((i = 0; i < ${#1}; i++)); do
c=${1:$i:1}
[[ "$c" =~ [a-zA-Z0-9\.\~\_\-] ]] || printf -v c '%%%02X' "'$c"
e+="$c"
done
# sed here will return slashes back to the path
echo "$e" | sed 's/%2F/\//g'
}
# From https://gist.github.com/cdown/1163649
urldecode() {
# urldecode <string>
local url_encoded="${1//+/ }"
printf '%b' "${url_encoded//%/\\x}"
}
fileToTagPath() {
urlencode "$(echo $line | cut -c 36-)"
}
checkLockFile
getTag
# Will use existing Tag report
[[ -s "$LOCKFILE" ]] || { findDuplicates; }
while read line; do
# reading each line
fileToTag=$(fileToTagPath)
getFileID
checkIfTagIsSet
done <$LOCKFILE
#rm $LOCKFILE
exit 0