]> git.plutz.net Git - shellwiki/blob - handlers/60_move_rename_delete.sh
Syntax help fro white space file names
[shellwiki] / handlers / 60_move_rename_delete.sh
1 #!/bin/sh
2
3 # Copyright 2022 - 2023 Paul Hänsch
4
5 # Permission to use, copy, modify, and/or distribute this software for any
6 # purpose with or without fee is hereby granted, provided that the above
7 # copyright notice and this permission notice appear in all copies.
8
9 # THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
12 # SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
15 # IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
17 l10n_immutablepage >/dev/null 2>&1 \
18 || l10n_immutablepage(){  #TRANSLATION
19   cat <<-EOF
20           <h1>Immutable Page</h1>
21           This is a core page of the wiki system. Its name and position cannot be changed.
22           You may however update this page and you can use ACLs to hide it from various listings.
23         EOF
24 }
25
26 case "${PATH_INFO}" in
27   */\[move\]|*/\[rename\]|*/\[delete\])
28     page="${PATH_INFO%\[*\]}"
29     if [ ! -d "$_DATA/pages/${page}" -a ! -d "$_EXEC/pages/${page}" ]; then
30       theme_error 404
31       return 0
32     elif ! acl_write "$page"; then
33       printf 'Refresh: %i, url=%s\r\n' 4 ./
34       theme_error 403
35       return 0
36     elif [ ! -d "$_DATA/pages/${page}" -a -d "$_EXEC/pages/${page}" ]; then
37       theme_page - <<-EOF
38         <article>
39           <p class=error>
40           $(l10n_immutablepage)
41           </p>
42         </article>
43         EOF
44       return 0
45     fi
46     ;;
47   *) return 1;;
48 esac
49
50 l10n_movepage >/dev/null 2>&1 \
51 || l10n_movepage(){  # TRANSLATION
52   cat <<-EOF
53           <h1>Move Page</h1>
54           <p class="pageid">$(HTML "${page}")</p>
55           <input name="newlocation" value="$(HTML "$location")" placeholder="New Location">
56           <ul>
57             <li>A page with the same name must not already exist at the new location.</li>
58             <li>You must have permission to create new pages at this location.</li>
59             <li>All subpages will become available under the new path name.</li>
60             <li>Subpages will become unavailable under their current name.</li>
61           </ul>
62           <button type=submit name=action value=move>Move</button>
63           <button type=submit name=action value=cancel>Cancel</button>
64         EOF
65 }
66 l10n_renamepage >/dev/null 2>&1 \
67 || l10n_renamepage(){  # TRANSLATION
68   cat <<-EOF
69           <h1>Rename Page</h1>
70           <p class="pageid">$(HTML "${page}")</p>
71           <input name="newname" value="$(HTML "$name")" placeholder="New Name">
72           <ul>
73             <li>A page with the new name must not already exist.</li>
74             <li>You must have permission to create new pages at this location.</li>
75             <li>All subpages will become available under the new path name.</li>
76             <li>Subpages will become unavailable under their current name.</li>
77           </ul>
78           <button type=submit name=action value=rename>Rename</button>
79           <button type=submit name=action value=cancel>Cancel</button>
80         EOF
81 }
82 l10n_deletepage >/dev/null 2>&1 \
83 || l10n_deletepage(){  # TRANSLATION
84   cat <<-EOF
85           <h1>Delete Page</h1>
86           <p class="pageid">$(HTML "${page}")</p>
87           <p>This page and its attachments will be deleted</p>
88           <input type=checkbox name=delete_subpages value=true id=delsub><label for=delsub>Delete subpages</label>
89           <ul>
90         EOF
91   [ "$REV_PAGES" = true ] \
92   && printf '    <li>Past revisions of the page text (including the current one) will remain accessible and can be restored.</li>'
93   [ "$REV_PAGES" = true -a "$REV_ATTACHMENTS" = true ] \
94   && printf '    <li>Attachments can be restored as well.</li>' \
95   || printf '    <li>Attachments will be deleted completely, and cannot be restored.</li>'
96   cat <<-EOF
97             <li class="delsub">Subpages will not be affected and can still be accessed normally.</li>
98           </ul>
99           <button type=submit name=action value=delete>Delete</button>
100           <button type=submit name=action value=cancel>Cancel</button>
101         EOF
102 }
103
104 list_writable() {
105   local PATH_INFO page="${1%/}/"
106
107   if acl_write "$page"; then
108     PATH_INFO="$page"
109     page_glob "*" 0 \
110     | while read page; do
111       list_writable "${PATH_INFO}${page}"
112     done
113     printf %s\\n "$page" |debug
114   fi
115 }
116
117 if [ "$REQUEST_METHOD" = POST ]; then
118   action="$(POST action)"
119   newname="$(POST newname |grep -m1 -xE '[^#/]*')"
120   newlocation="$(POST newlocation |grep -m1 -xE '/[^#]*')"
121   delsub="$(POST delete_subpages |grep -m1 -xE 'true|false')"
122 else case "${PATH_INFO}" in
123   */\[move\])
124       location="${page%/}" location="${location%/*}/"
125       theme_page - <<-EOF
126         <form method=POST id=movepage>
127           <input type=hidden name=session_id value="$SESSION_KEY">
128           $(l10n_movepage)
129         </form>
130         EOF
131       return 0
132     ;;
133   */\[rename\])
134       name="${page%/}" name="${name##*/}"
135       theme_page - <<-EOF
136         <form method=POST id=renamepage>
137           <input type=hidden name=session_id value="$SESSION_KEY">
138           $(l10n_renamepage)
139         </form>
140         EOF
141       return 0
142     ;;
143   */\[delete\])
144       theme_page - <<-EOF
145         <form method=POST id=deletepage>
146           <input type=hidden name=session_id value="$SESSION_KEY">
147           $(l10n_deletepage)
148         </form>
149         EOF
150       return 0
151     ;;
152   esac
153 fi
154
155 if [ "$action" = rename -a "$newname" ]; then
156   oldname="${PATH_INFO%\[*\]}"
157   newname="${oldname%/*/}$(PATH "${newname}/")"
158
159   if [ -d "$_DATA/pages/$newname" ]; then
160     printf 'Refresh: %i\r\n' 4
161     export ERROR_MSG="A location of that name already exists."
162     theme_error 400
163     return 0
164   elif ! acl_write "$oldname" || ! acl_write "$newname"; then
165     printf 'Refresh: %i\r\n' 4
166     theme_error 403
167     return 0
168   fi
169   if [ "$REV_PAGES" = true ]; then
170     git -C "$_DATA" mv "pages/$oldname" "pages/$newname"
171     git -C "$_DATA" commit -m 'Page # '"$oldname"' # renamed to # '"$newname"' # by user @ '"$USER_NAME"' @' \
172         -- "pages/$oldname" "pages/$newname"
173   else
174     mv -- "$_DATA/pages/$oldname" "$_DATA/pages/$newname"
175   fi
176   if [ "$SEARCH_INDEX" = true ]; then
177     find "$_DATA/pages/$newname" -name "#index.flag" -delete
178     ( "$_EXEC/searchindex.sh" index --location "$newname" & ) &
179   fi
180   REDIRECT "$_BASE${newname}"
181
182 elif [ "$action" = move -a "$newlocation" ]; then
183   oldname="${PATH_INFO%\[*\]}"
184   newlocation="$(PATH "$newlocation")"
185   newname="${oldname%/}"
186   newname="${newlocation%/}/${newname##*/}/"
187
188   if [ -d "$_DATA/pages/$newname" ]; then
189     printf 'Refresh: %i\r\n' 4
190     export ERROR_MSG="A page of that name already exists at the given location."
191     theme_error 400
192     return 0
193   elif [ ! -d "$_DATA/pages/$newlocation" ]; then
194     printf 'Refresh: %i\r\n' 4
195     export ERROR_MSG="The given location does not exist."
196     theme_error 400
197     return 0
198   elif ! acl_write "$oldname" || ! acl_write "$newname"; then
199     printf 'Refresh: %i\r\n' 4
200     theme_error 403
201     return 0
202   fi
203   if [ "$REV_PAGES" = true ]; then
204     git -C "$_DATA" mv "pages/${oldname}" "pages/${newname}"
205     git -C "$_DATA" commit -m 'Page # '"$oldname"' # moved to # '"$newname"' # by user @ '"$USER_NAME"' @' \
206         -- "pages/${oldname}" "pages/${newname}"
207   else
208     mv -- "$_DATA/pages/$oldname" "$_DATA/pages/$newname"
209   fi
210   if [ "$SEARCH_INDEX" = true ]; then
211     find "$_DATA/pages/$newname" -name "#index.flag" -delete
212     ( "$_EXEC/searchindex.sh" index --location "$newname" & ) &
213   fi
214   REDIRECT "$_BASE${newname}"
215
216 elif [ "$action" = delete ]; then
217   oldname="${PATH_INFO%\[*\]}"
218   if ! acl_write "$oldname"; then
219     printf 'Refresh: %i\r\n' 4
220     theme_error 403
221     return 0
222   fi
223
224   printf 'Status: 202 Accepted\r\n'
225   { [ "$delsub" = true ] \
226     && list_writable "$oldname" \
227     || printf %s\\n "$oldname"
228   } | while read oldname; do
229     if [ "$REV_PAGES" = true -a "$REV_ATTACHMENTS" = true ]; then
230       git -C "$_DATA" rm "pages/${oldname}/#page.md" >&2
231       git -C "$_DATA" rm -r "pages/${oldname}/#attachments/" >&2
232       git -C "$_DATA" commit -m 'Page # '"$oldname"' # deleted by user @ '"$USER_NAME"' @' \
233           -- "pages/${oldname}/#page.md" "pages/${oldname}/#attachments/" >&2
234       rm -r -- "$_DATA/pages/${oldname}"/\#*
235       rmdir -- "$_DATA/pages/${oldname}/" || true
236     elif [ "$REV_PAGES" = true ]; then
237       git -C "$_DATA" rm "pages/${oldname}/#page.md" >&2
238       git -C "$_DATA" commit -m 'Page # '"$oldname"' # deleted by user @ '"$USER_NAME"' @' \
239           -- "pages/${oldname}/#page.md" >&2
240       rm -r -- "$_DATA/pages/${oldname}"/\#*
241       rmdir -- "$_DATA/pages/${oldname}/" || true
242     else
243       rm -- "$_DATA/pages/${oldname}/#page.md"
244       rm -r -- "$_DATA/pages/${oldname}"/\#*
245       rmdir -- "$_DATA/pages/${oldname}/" || true
246     fi
247     printf '%s\n' "$oldname"
248   done | {
249     cat <<-EOF
250         <article id="deleteconfirm">
251           <h1>$(_ "Pages deleted:")</h1>
252           <ul>
253           $(while read page; do
254             printf '<li>%s</li>' "$(HTML $page)"
255           done)
256           </ul>
257           <a class="button" href="./">$(_ OK)</a>
258         </article>
259         EOF
260   } | theme_page -
261   return 0
262 elif [ "$action" = cancel ]; then
263   REDIRECT ./
264 elif [ "$action" ]; then
265   printf 'Refresh: %i\r\n' 4
266   export ERROR_MSG="Missing parameters."
267   theme_error 400
268   return 0
269 fi