aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/usr/bin/drive-menu
blob: fc62faa6daf3c285b4ac4a76595794f0fa1a2d6b (about) (plain)
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
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
#!/bin/bash
###################################################################################################
# drive-menu
###################################################################################################
# Copyright 2017-2022 Jean-Christophe Manciot <jcmanciot@sdxlive.com>
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 
# in compliance with the License. You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# This script is using a project hosted at https://github.com/odeke-em/drive, originally developed 
# by Burcu Dogan while working on the Google Drive team and now maintained by Emmanuel T Odeke.
#
# Attribution — You must give appropriate credit, provide a link to the license, and indicate if 
#               changes were made. You may do so in any reasonable manner, but not in any way that 
#               suggests the licensor endorses you or your use.
###################################################################################################

###################################################################################################
#
# Listing all drive-<command>s in a GUI window to choose from:
#       + About Drive:                                          drive-about
#       + Check selected remote duplicated objects:             drive-check-duplicates (clashes)
#       + Change working directory
#       + Delete selected remote objects:                       drive-delete
#       + Disable local Google Drive:                           drive-disable
#       + Empty remote trash:                                   drive-empty-trash
#       + Help:                                                 drive-<command> --help
#       + List selected remote objects:                         drive-list
#       + List selected shared remote objects:                  drive-list-shared
#       + List selected starred remote objects:                 drive-list-starred
#       + Log selected scripts
#       + Publish selected remote objects:                      drive-publish
#       + Pull selected remote objects:                         drive-pull
#       + Push selected local objects:                          drive-push
#       + Query statistics about selected remote objects:       drive-stats (stat)
#       + Select objects & configure general settings
#       + Share with link selected remote objects:              drive-share-link
#       + Sync selected local/remote objects:                   drive-sync
#       + Touch selected remote objects:                        drive-touch
#       + Trash selected remote objects:                        drive-trash
#       + Unpublish selected remote objects:                    drive-unpublish
#       + Unshare selected remote objects:                      drive-unshare
#       + Untrash selected remote objects:                      drive-untrash
#       + Versions                                              drive-version
#
# Once a command has been selected, it is executed in the same folder as the one where 
# 'drive-menu' has been called, selecting files/folders (objects) using configuration found in all 
# following files:
#       - <google_drive_folder>/.driverc
#       - <google_drive_folder>/.driveignore
#       - ./.driveselect.
#
# By default, all your objects recursively found below the current working directory are affected by the
# chosen drive command. 
#
# You may modify the default scale of each command using depth setting(s) in your 
# <google_drive_folder>/.driverc, **except** for the following commands:
#       - delete
#       - (un)trash
#       - (un)publish
#       - (un)share
#
# The list of objects affected by the chosen command can be optionnaly also filtered by:
#       - <google_drive_folder>/.driveignore
#       - ./.driveselect
#
###################################################################################################
#
# Requirements:
# ------------
#
# - We assume that:
#       + drive-google package is already installed, including all drive-* scripts.
#       + leap-year, convert-date-time-to-utc & zenity-cancel utilities are available.
#       + coreutils, sed, trash-cli & zenity packages are already installed.
#
# - This command must be called from within your local Google Drive folder(s).
#
# - <google_drive_folder>/.driverc:it must be properly setup, either manually or with drive-setup,
#                                  with the following settings:
#       * depth=
#               + -1: an infinite traversal depth, i.e recursive traversal from the current working  
#                     directory until there is no more child folder
#               + non-zero number: a fixed traversal depth
#       * ignore-checksum=
#               + true: objects checksum is not verified 
#               + false: objects checksum is verified 
#       * encryption-password="<your_secret>": drive optionally encrypts all pushed objects at rest
#                                              on your Google Drive
#       * decryption-password="<your_secret>": drive optionally decrypts all pulled objects which 
#                                              are encrypted at rest on your Google Drive online.
#       * ...: cf. https://github.com/odeke-em/drive for a complete list of available  
#              options. They can only be set manually through .driverc or through drive-setup for
#              the sake of simplicity.
#              Cf. /etc/drive-google/.driverc for some examples.
#
# - <google_drive_folder>/.driveignore: it may be used to exclude/include some objects from the 
#                                       scope of the current drive-<command> by using regular
#                                       expressions.
#                                       Cf. /etc/drive-google/.driveignore for its format & some 
#                                       examples.
#
# - ./.driveselect: it may be used to include/exclude the objects from the scope of the current 
#                   drive-<command>. 
#                   Cf. /etc/drive-google/.driveselect for its format & some examples.
#
###################################################################################################
#
# Parameters:
# ----------
#
# - <anything> will display this help message
#
###################################################################################################
#
# Notes:
# -----
#
# - One must be **cautious** with some commands: a list of potentially affected objects will be
#   printed before each actual command.
#   I recommend to perform a backup of your local Google Drive folder before running this command.
#
# - The performance of some commands is proportional to part or all of: 
#       + the chosen command
#       + the number of all the objects recursively found locally and on your remote Google Drive
#       + the size of all the objects that need to be synced (pulled and/or pushed)
#       + the end-to-end bandwidth, latency & quality of your current Internet connection to your 
#         Google Drive online.
#
# - In order to **drastically** improve their performances, you can:
#       + restrict the number of objects affected by the chosen command by setting:
#               * <google_drive_folder>/.driverc: depth
#               * <google_drive_folder>/.driveignore: filter
#               * ./.driveselect: list of objects under the right [<command>] section.
#       + and/or move to the deepest folder which recursively contains the affected objects
#         before calling drive-menu.
#       + **remove, i.e comment** in <google_drive_folder>/.driverc some settings:
#               * checksum verification: # ignore-checksum=false
#               * any sorting: # --sort=name,version,modt,size_r...
#
###################################################################################################
#
# Usage example:
# -------------
#
# cd ~/<google_drive_folder>/any/sub/folder
# drive-menu
#
###################################################################################################
# Preventing globbing (pathname expansion)
set -o noglob
# Allowing extended globbing
shopt -s extglob
# Expanding aliases
shopt -s expand_aliases

# Including alias definitions to sed/grep/awk/perl commands for readability sake
. /usr/include/drive-google/aliases

# Checking for no parameter
if [[ $# -eq 0 ]]; then
        local_folder="$(pwd)"

        # Removing all occurrences of '&' in $object as a workaround to a markup ampersand issue with zenity
        noamp_local_folder="$(echo "${local_folder}" | rm_ampersand)"

        # Finding local root Google Drive folder
        gd_root_folder="$(.drive-find-gd)"
        return_code=$?

        # Removing all occurrences of '&' in $gd_root_folder as a workaround to a markup ampersand issue with zenity
        noamp_gd_root_folder="$(echo "${gd_root_folder}" | rm_ampersand)"

        case $return_code in
                0)
                        # Everything is fine - we continue
                        ;;
                7)
                        zenity --warning --title "Drive context found in $noamp_gd_root_folder" --text="We have moved to $noamp_gd_root_folder\n\nIf you prefer to select another Google Drive folder:\n\t--> 'Change working directory'" --width 1400

                        cd "$gd_root_folder"

                        local_folder="$(pwd)"

                        # Removing all occurrences of '&' in $object as a workaround to a markup ampersand issue with zenity
                        noamp_local_folder="$(echo "${local_folder}" | rm_ampersand)"
                        ;;
                8)
                        zenity --error --title "No drive context found below and above $noamp_local_folder" --text="- either drive has not been initialized properly (at least one hop away from '/') with:\n\t--> '# drive init google_drive_folder' within a terminal\n- or we are not located below your google_drive_folder top level branch:\n\t--> 'Change working directory'" --width 1400
                        ;;
                *)
                        # Something is fatally wrong
                        zenity --error --title "Fatal error in drive-menu" --text="\tUnknown return code from .drive-find-gd: $return_code\n\nPlease report that issue to: https://gitlab.com/jean-christophe-manciot/Drive/issues" --width 1200
                        exit 99
                        ;;
        esac

        local_folder_path_from_gd_root=${local_folder#$gd_root_folder}
        drive_menu_pid=$(ps -C drive-menu -o pid=)

        while :
        do
                command=$(zenity --list  \
                                 --radiolist \
                                 --height=860 \
                                 --width=1000 \
                                 --title "Selecting Google Drive Command for ${noamp_local_folder}" \
                                 --column "Pick" \
                                 --column "Google Drive Command" TRUE "About Drive" FALSE "Check selected remote duplicated objects" FALSE "Change working directory" FALSE "Delete selected remote objects" FALSE "Disable local Google Drive" FALSE "Empty remote trash" FALSE Help FALSE "List selected remote objects" FALSE "List selected shared remote objects" FALSE "List selected starred remote objects" FALSE "Log selected scripts" FALSE "Publish selected remote objects" FALSE "Pull selected remote objects" FALSE "Push selected local objects" FALSE "Query statistics about selected remote objects" FALSE "Select objects & configure general settings" FALSE "Share with link selected remote objects" FALSE "Sync selected local/remote objects" FALSE "Touch selected remote objects" FALSE "Trash selected remote objects" FALSE "Unpublish selected remote objects" FALSE "Unshare selected remote objects" FALSE "Untrash selected remote objects" FALSE "Versions" FALSE Exit)
                case $command in
                        "About Drive")
                                drive-about | zenity --progress --pulsate --auto-close --width=700 --text="Running on ${noamp_local_folder}" --title="About Drive" &

                                # Passing zenity process ID & drive-menu process ID to manage zenity cancel action
                                zenity_pid=${!}
                                zenity-cancel $drive_menu_pid $zenity_pid
                                # Making sure the process has been killed in case of cancelled operation
                                drive_about_pid=$(ps -C drive-about -o pid=)
                                kill $drive_about_pid 2>/dev/null
                                ;;
                        "Change working directory")
                                local_folder=$(zenity --file-selection --directory --height=1000 --title="Changing folder")

                                # Checking if Cancel has not been chosen
                                if [[ ! -z "${local_folder}" ]]; then
                                        cd "$local_folder"

                                        # Removing all occurrences of '&' in $object as a workaround to a markup ampersand issue with zenity
                                        noamp_local_folder=$(echo "${local_folder}" | rm_ampersand)

                                        # Finding local root Google Drive folder
                                        gd_root_folder="$(.drive-find-gd)"
                                        return_code=$?

                                        # Removing all occurrences of '&' in $gd_root_folder as a workaround to a markup ampersand issue with zenity
                                        noamp_gd_root_folder=$(echo "${gd_root_folder}" | rm_ampersand)

                                        case $return_code in
                                                0)
                                                        # Everything is fine - we continue
                                                        ;;
                                                7)
                                                        zenity --warning --title "Drive context found in $noamp_gd_root_folder" --text="We have moved to $noamp_gd_root_folder\n\nIf you prefer to select another Google Drive folder:\n\t--> 'Change working directory'" --width 1400

                                                        cd "$gd_root_folder"
                                                        ;;
                                                8)
                                                        zenity --error --title "No drive context found below and above $noamp_local_folder" --text="- either drive has not been initialized properly (at least one hop away from '/') with:\n\t--> '# drive init google_drive_folder' within a terminal\n- or we are not located below your google_drive_folder top level branch:\n\t--> 'Change working directory'" --width 1400
                                                        ;;
                                                *)
                                                        # Something is fatally wrong
                                                        zenity --error --title "Fatal error in drive-menu" --text="\tUnknown return code from .drive-find-gd: $return_code\n\nPlease report that issue to: https://gitlab.com/jean-christophe-manciot/Drive/issues" --width 1200
                                                        exit 99
                                                        ;;
                                        esac

                                        local_folder="$(pwd)"

                                        # Removing all occurrences of '&' in $object as a workaround to a markup ampersand issue with zenity
                                        noamp_local_folder="$(echo "${local_folder}" | rm_ampersand)"
                
                                        local_folder_path_from_gd_root=${local_folder#$gd_root_folder}
                                fi
                                ;;
                        "Check selected remote duplicated objects")
                                drive-check-duplicates | zenity --progress --pulsate --auto-close --width=700 --text="Running on ${noamp_local_folder}" --title="Checking for duplicates among selected remote objects" &

                                # Passing zenity process ID & drive-menu process ID to manage zenity cancel action
                                zenity_pid=${!}
                                zenity-cancel $drive_menu_pid $zenity_pid
                                # Making sure the process has been killed in case of cancelled operation
                                drive_check_duplicates_pid=$(ps -C drive-check-duplicates -o pid=)
                                kill $drive_check_duplicates_pid 2>/dev/null
                                ;;
                        "Delete selected remote objects")
                                drive-delete | zenity --progress --pulsate --auto-close --width=700 --text="Running on ${noamp_local_folder}" --title="Deleting selected remote objects" &

                                # Passing zenity process ID & drive-menu process ID to manage zenity cancel action
                                zenity_pid=${!}
                                zenity-cancel $drive_menu_pid $zenity_pid
                                # Making sure the process has been killed in case of cancelled operation
                                drive_delete_pid=$(ps -C drive-delete -o pid=)
                                kill $drive_delete_pid 2>/dev/null
                                ;;
                        "Disable local Google Drive")
                                drive-disable | zenity --progress --pulsate --auto-close --width=700 --text="Running on ${noamp_local_folder}" --title="Disabling local Google Drive" &

                                # Passing zenity process ID & drive-menu process ID to manage zenity cancel action
                                zenity_pid=${!}
                                zenity-cancel $drive_menu_pid $zenity_pid
                                # Making sure the process has been killed in case of cancelled operation
                                drive_disable_pid=$(ps -C drive-disable -o pid=)
                                kill $drive_disable_pid 2>/dev/null
                                ;;
                        "Empty remote trash")
                                drive-empty-trash | zenity --progress --pulsate --auto-close --width=700 --text="Running on ${noamp_local_folder}" --title="Emptying remote trash" &

                                # Passing zenity process ID & drive-menu process ID to manage zenity cancel action
                                zenity_pid=${!}
                                zenity-cancel $drive_menu_pid $zenity_pid
                                # Making sure the process has been killed in case of cancelled operation
                                drive_empty_trash_pid=$(ps -C drive-empty-trash -o pid=)
                                kill $drive_empty_trash_pid 2>/dev/null
                                ;;
                        Help)
                                while :
                                do
                                        help_command=$(zenity --list  \
                                                              --radiolist \
                                                              --height=780 \
                                                              --width=700 \
                                                              --title "Selecting type of help" \
                                                              --column "Pick" \
                                                              --column "Google Drive Help" TRUE "About Drive" FALSE "Check selected remote duplicated objects" FALSE "Delete selected remote objects" FALSE "Disable local Google Drive" FALSE "Empty remote trash" FALSE "List selected remote objects" FALSE "List selected shared remote objects" FALSE "List selected starred remote objects" FALSE "Menu & objects selection" FALSE "Publish selected remote objects" FALSE "Pull selected remote objects" FALSE "Push selected local objects" FALSE "Query statistics about selected remote objects" FALSE "Share with link selected remote objects" FALSE "Sync selected local/remote objects" FALSE "Touch selected remote objects" FALSE "Trash selected remote objects" FALSE "Unpublish selected remote objects" FALSE "Unshare selected remote objects" FALSE "Untrash selected remote objects" FALSE "Versions" FALSE Exit)
                                        case $help_command in
                                                "About Drive")
                                                        drive-about --help
                                                        ;;
                                                "Check selected remote duplicated objects")
                                                        drive-check-duplicates --help
                                                        ;;
                                                "Delete selected remote objects")
                                                        drive-delete --help
                                                        ;;
                                                "Disable local Google Drive")
                                                        drive-disable --help
                                                        ;;
                                                "Empty remote trash")
                                                        drive-empty-trash --help
                                                        ;;
                                                "List selected remote objects")
                                                        drive-list --help
                                                        ;;
                                                "List selected shared remote objects")
                                                        drive-list-shared --help
                                                        ;;
                                                "List selected starred remote objects")
                                                        drive-list-starred --help
                                                        ;;
                                                "Menu & objects selection")
                                                        drive-menu --help
                                                        ;;
                                                "Publish selected remote objects")
                                                        drive-publish --help
                                                        ;;
                                                "Pull selected remote objects")
                                                        drive-pull --help
                                                        ;;
                                                "Push selected local objects")
                                                        drive-push --help
                                                        ;;
                                                "Query statistics about selected remote objects")
                                                        drive-stats --help
                                                        ;;
                                                "Share with link selected remote objects")
                                                        drive-share-link --help
                                                        ;;
                                                "Sync selected local/remote objects")
                                                        drive-sync --help
                                                        ;;
                                                "Touch selected remote objects")
                                                        drive-touch --help
                                                        ;;
                                                "Trash selected remote objects")
                                                        drive-trash --help
                                                        ;;
                                                "Unpublish selected remote objects")
                                                        drive-unpublish --help
                                                        ;;
                                                "Unshare selected remote objects")
                                                        drive-unshare --help
                                                        ;;
                                                "Untrash selected remote objects")
                                                        drive-untrash --help
                                                        ;;
                                                "Versions")
                                                        drive-version --help
                                                        ;;
                                                *)
                                                        break
                                                        ;;
                                        esac
                                done
                                ;;
                        "List selected remote objects")
                                drive-list | zenity --progress --pulsate --auto-close --width=700 --text="Running on ${noamp_local_folder}" --title="Listing selected remote objects" &

                                # Passing zenity process ID & drive-menu process ID to manage zenity cancel action
                                zenity_pid=${!}
                                zenity-cancel $drive_menu_pid $zenity_pid
                                # Making sure the process has been killed in case of cancelled operation
                                drive_list_pid=$(ps -C drive-list -o pid=)
                                kill $drive_list_pid 2>/dev/null
                                ;;
                        "List selected shared remote objects")
                                drive-list-shared | zenity --progress --pulsate --auto-close --width=700 --text="Running on ${noamp_local_folder}" --title="Listing selected shared remote objects" &

                                # Passing zenity process ID & drive-menu process ID to manage zenity cancel action
                                zenity_pid=${!}
                                zenity-cancel $drive_menu_pid $zenity_pid
                                # Making sure the process has been killed in case of cancelled operation
                                drive_list_shared_pid=$(ps -C drive-list-shared -o pid=)
                                kill $drive_list_shared_pid 2>/dev/null
                                ;;
                        "List selected starred remote objects")
                                drive-list-starred | zenity --progress --pulsate --auto-close --width=700 --text="Running on ${noamp_local_folder}" --title="Listing selected starred remote objects" &

                                # Passing zenity process ID & drive-menu process ID to manage zenity cancel action
                                zenity_pid=${!}
                                zenity-cancel $drive_menu_pid $zenity_pid
                                # Making sure the process has been killed in case of cancelled operation
                                drive_list_starred_pid=$(ps -C drive-list-starred -o pid=)
                                kill $drive_list_starred_pid 2>/dev/null
                                ;;
                        "Log selected scripts")
                                # Resetting all log variables
                                for variable in LOG_CHECK_INTERNET_CONNECTIVITY LOG_CONVERT_DATE_TIME_TO_UTC LOG_DRIVE_ABOUT LOG_DRIVE_CHECK_DUPLICATES LOG_DRIVE_COMPUTE_OBJECT_SIZE LOG_DRIVE_COMPUTE_SPEED_ETA LOG_DRIVE_DELETE LOG_DRIVE_DELETE_UNSYNCED_LOCAL LOG_DRIVE_DELETE_UNSYNCED_REMOTE LOG_DRIVE_DISABLE LOG_DRIVE_EMPTY_TRASH LOG_DRIVE_FIND_GD LOG_DRIVE_LIST LOG_DRIVE_LIST_SHARED LOG_DRIVE_LIST_STARRED LOG_DRIVE_MENU LOG_DRIVE_PREPEND_OBJECT_TYPE_SIZE LOG_DRIVE_PUBLISH LOG_DRIVE_PULL LOG_DRIVE_PULL_UNSYNCED LOG_DRIVE_PUSH LOG_DRIVE_PUSH_UNSYNCED LOG_DRIVE_READ_DRIVERC LOG_DRIVE_SELECT_OBJECTS LOG_DRIVE_SETUP LOG_DRIVE_SHARE_LINK LOG_DRIVE_STATS LOG_DRIVE_SYNC LOG_DRIVE_TOUCH LOG_DRIVE_TRASH LOG_DRIVE_TRASH_UNSYNCED_LOCAL LOG_DRIVE_TRASH_UNSYNCED_REMOTE LOG_DRIVE_UNPUBLISH LOG_DRIVE_UNSHARE LOG_DRIVE_UNTRASH LOG_DRIVE_VERSION LOG_DRIVE_WRITE_DRIVESELECT LOG_LEAP_YEAR LOG_ZENITY_CANCEL
                                do
                                        export $variable=OFF
                                done

                                while :
                                do
                                        scripts=$(zenity --list  \
                                                         --checklist \
                                                         --separator=":" \
                                                         --height=1000 \
                                                         --width=450 \
                                                         --title "Selecting Scripts" \
                                                         --column "Pick" \
                                                         --column "Scripts" FALSE check-internet-connectivity FALSE convert-date-time-to-utc FALSE drive-about FALSE drive-check-duplicates FALSE drive-delete FALSE drive-disable FALSE drive-empty-trash FALSE drive-list FALSE drive-list-shared FALSE drive-list-starred TRUE drive-menu FALSE drive-publish FALSE drive-pull FALSE drive-push FALSE drive-setup FALSE drive-share-link FALSE drive-stats FALSE drive-sync FALSE drive-touch FALSE drive-trash FALSE drive-unpublish FALSE drive-unshare FALSE drive-untrash FALSE drive-version FALSE leap-year FALSE zenity-cancel FALSE .drive-compute-object-size FALSE .drive-compute-speed-eta FALSE .drive-delete-unsynced-local FALSE .drive-delete-unsynced-remote FALSE .drive-find-gd FALSE .drive-prepend-object-type-size FALSE .drive-pull-unsynced FALSE .drive-push-unsynced FALSE .drive-read-driverc FALSE .drive-select-objects FALSE .drive-trash-unsynced-local FALSE .drive-trash-unsynced-remote FALSE .drive-write-driveselect FALSE Exit)
                                        case $scripts in
                                                *-*)
                                                        # Getting the last existing file descriptor of ~/.drive-google/logs/drive-google.log
                                                        fd=$(ls -al /proc/$$/fd | grep ~/.drive-google/logs/drive-google.log | sed -E 's|^.* ([0-9]+) -> .*$|\1|g' | sort -V | tail -n 1)

                                                        # Case where fd is unset, 
                                                        # i.e the file ~/.drive-google/logs/drive-google.log has not yet been opened
                                                        if [[ -z $fd ]]; then
                                                                lowest_unused_fd () 
                                                                {
                                                                        local fd=0
                                                                        while [[ -e /proc/$$/fd/${fd} ]]; do
                                                                                fd=$((fd+1))
                                                                        done
                                                                        echo $fd
                                                                }
                                                                fd=$(lowest_unused_fd)

                                                                # All selected scripts will be logged into ~/.drive-google/logs
                                                                if [[ ! -d ~/.drive-google/logs ]]; then
                                                                        mkdir -p ~/.drive-google/logs
                                                                fi

                                                                # Renaming log file by appending its modify date/time if it already exists
                                                                if [[ -f ~/.drive-google/logs/drive-google.log ]]; then
                                                                        last_modify_date_time=$(stat -c %y ~/.drive-google/logs/drive-google.log  | cut -d '.' -f 1)
                                                                        # - Changing all ' ' by '-'
                                                                        last_modify_date_time=$(echo "${last_modify_date_time// /-}")
                                                                        # - Changing all ':' by '-'
                                                                        last_modify_date_time=$(echo "${last_modify_date_time//:/-}")

                                                                        mv ~/.drive-google/logs/drive-google.log ~/.drive-google/logs/drive-google-${last_modify_date_time}.log
                                                                fi

                                                                # Opening ~/.drive-google/logs/drive-google.log as $fd for writing
                                                                eval "exec $fd> ~/.drive-google/logs/drive-google.log"
                                                        fi

                                                        # Writing the trace output generated when set -x is enabled to $fd 
                                                        eval "BASH_XTRACEFD=$fd"
                                                        # Logging line numbers - We could also use ${0} for ${BASH_SOURCE}
                                                        export PS4='$(basename ${BASH_SOURCE}).${LINENO}+ '

                                                        # It is necessary to always set this here 
                                                        # since at least one script needs to be logged,
                                                        # otherwise the "set -x" in the subscripts won't be effective
                                                        # Expanding all variables and prints the full commands before output of the command
                                                        set -x

                                                        while :
                                                        do
                                                                # Processing each script one by one in order
                                                                # $scripts is formatted with "scripts:scripts:scripts:..."
                                                                if [[ "$scripts" =~ : ]]; then
                                                                        # There are at least 2 scripts
                                                                        script="$(echo $scripts | cut -d ':' -f 1)"
                                                                else
                                                                        script="$scripts"
                                                                fi

                                                                case $script in
                                                                        *-*)
                                                                                # - Changing all letters of $script to uppercase
                                                                                log_variable=$(echo "${script^^}")
                                                                                # - Changing all '-' by '_'
                                                                                log_variable=$(echo "${log_variable//-/_}")
                                                                                # - Removing potential leading '.'
                                                                                log_variable=$(echo "${log_variable//./}")

                                                                                # Setting the log variable cooresponding to the script 
                                                                                export LOG_${log_variable}=ON
                                                                                ;;
                                                                        *)
                                                                                break
                                                                                ;;
                                                                esac

                                                                # Removing $script from $scripts
                                                                if [[ "$scripts" =~ : ]]; then
                                                                        # There are at least 2 repositories
                                                                        scripts="${scripts#${script}:}"
                                                                else
                                                                        scripts="${scripts#${script}}"
                                                                fi
                                                        done

                                                        zenity --warning --title "Logging selected scripts" --text="\nAll selected scripts will be logged into ~/.drive-google/logs/drive-google.log" --width 900
                                                        break
                                                        ;;
                                                *)
                                                        # Nothing will be logged, including in the subscripts
                                                        set +x

                                                        break
                                                        ;;
                                        esac
                                done
                                ;;
                        "Publish selected remote objects")
                                drive-publish | zenity --progress --pulsate --auto-close --width=700 --text="Running on ${noamp_local_folder}" --title="Publishing selected remote objects" &

                                # Passing zenity process ID & drive-menu process ID to manage zenity cancel action
                                zenity_pid=${!}
                                zenity-cancel $drive_menu_pid $zenity_pid
                                # Making sure the process has been killed in case of cancelled operation
                                drive_publish_pid=$(ps -C drive-publish -o pid=)
                                kill $drive_publish_pid 2>/dev/null
                                ;;
                        "Pull selected remote objects")
                                drive-pull | zenity --progress --pulsate --auto-close --width=700 --text="Running on ${noamp_local_folder}" --title="Pulling selected remote objects" &

                                # Passing zenity process ID & drive-menu process ID to manage zenity cancel action
                                zenity_pid=${!}
                                zenity-cancel $drive_menu_pid $zenity_pid
                                # Making sure the process has been killed in case of cancelled operation
                                drive_pull_pid=$(ps -C drive-pull -o pid=)
                                kill $drive_pull_pid 2>/dev/null
                                ;;
                        "Push selected local objects")
                                drive-push | zenity --progress --pulsate --auto-close --width=700 --text="Running on ${noamp_local_folder}" --title="Pushing selected local objects" &

                                # Passing zenity process ID & drive-menu process ID to manage zenity cancel action
                                zenity_pid=${!}
                                zenity-cancel $drive_menu_pid $zenity_pid
                                # Making sure the process has been killed in case of cancelled operation
                                drive_push_pid=$(ps -C drive-push -o pid=)
                                kill $drive_push_pid 2>/dev/null
                                ;;
                        "Query statistics about selected remote objects")
                                drive-stats | zenity --progress --pulsate --auto-close --width=700 --text="Running on ${noamp_local_folder}" --title="Querying statistics about selected remote objects" &

                                # Passing zenity process ID & drive-menu process ID to manage zenity cancel action
                                zenity_pid=${!}
                                zenity-cancel $drive_menu_pid $zenity_pid
                                # Making sure the process has been killed in case of cancelled operation
                                drive_stats_pid=$(ps -C drive-stats -o pid=)
                                kill $drive_stats_pid 2>/dev/null
                                ;;
                        "Select objects & configure general settings")
                                drive-setup | zenity --progress --pulsate --auto-close --width=700 --text="Running on ${noamp_local_folder}" --title="Configuring general settings & selecting objects" &

                                # Passing zenity process ID & drive-menu process ID to manage zenity cancel action
                                zenity_pid=${!}
                                zenity-cancel $drive_menu_pid $zenity_pid
                                # Making sure the process has been killed in case of cancelled operation
                                drive_setup_pid=$(ps -C drive-setup -o pid=)
                                kill $drive_setup_pid 2>/dev/null
                                ;;
                        "Share with link selected remote objects")
                                drive-share-link | zenity --progress --pulsate --auto-close --width=700 --text="Running on ${noamp_local_folder}" --title="Sharing with link selected remote objects" &

                                # Passing zenity process ID & drive-menu process ID to manage zenity cancel action
                                zenity_pid=${!}
                                zenity-cancel $drive_menu_pid $zenity_pid
                                # Making sure the process has been killed in case of cancelled operation
                                drive_share_link_pid=$(ps -C drive-share-link -o pid=)
                                kill $drive_share_link_pid 2>/dev/null
                                ;;
                        "Sync selected local/remote objects")
                                drive-sync | zenity --progress --pulsate --auto-close --width=700 --text="Running on ${noamp_local_folder}" --title="Syncing selected local/remote objects" &

                                # Passing zenity process ID & drive-menu process ID to manage zenity cancel action
                                # Last backgrounded process
                                zenity_pid=${!}
                                zenity-cancel $drive_menu_pid $zenity_pid
                                # Making sure the process has been killed in case of cancelled operation
                                drive_sync_pid=$(ps -C drive-sync -o pid=)
                                kill $drive_sync_pid 2>/dev/null
                                ;;
                        "Touch selected remote objects")
                                drive-touch | zenity --progress --pulsate --auto-close --width=700 --text="Running on ${noamp_local_folder}" --title="Touching selected remote objects" &

                                # Passing zenity process ID & drive-menu process ID to manage zenity cancel action
                                zenity_pid=${!}
                                zenity-cancel $drive_menu_pid $zenity_pid
                                # Making sure the process has been killed in case of cancelled operation
                                drive_touch_pid=$(ps -C drive-touch -o pid=)
                                kill $drive_touch_pid 2>/dev/null
                                ;;
                        "Trash selected remote objects")
                                drive-trash | zenity --progress --pulsate --auto-close --width=700 --text="Running on ${noamp_local_folder}" --title="Trashing selected remote objects" &

                                # Passing zenity process ID & drive-menu process ID to manage zenity cancel action
                                zenity_pid=${!}
                                zenity-cancel $drive_menu_pid $zenity_pid
                                # Making sure the process has been killed in case of cancelled operation
                                drive_trash_pid=$(ps -C drive-trash -o pid=)
                                kill $drive_trash_pid 2>/dev/null
                                ;;
                        "Unpublish selected remote objects")
                                drive-unpublish | zenity --progress --pulsate --auto-close --width=700 --text="Running on ${noamp_local_folder}" --title="Unpublishing selected remote objects" &

                                # Passing zenity process ID & drive-menu process ID to manage zenity cancel action
                                zenity_pid=${!}
                                zenity-cancel $drive_menu_pid $zenity_pid
                                # Making sure the process has been killed in case of cancelled operation
                                drive_unpublish_pid=$(ps -C drive-unpublish -o pid=)
                                kill $drive_unpublish_pid 2>/dev/null
                                ;;
                        "Unshare selected remote objects")
                                drive-unshare | zenity --progress --pulsate --auto-close --width=700 --text="Running on ${noamp_local_folder}" --title="Unsharing selected remote objects" &

                                # Passing zenity process ID & drive-menu process ID to manage zenity cancel action
                                zenity_pid=${!}
                                zenity-cancel $drive_menu_pid $zenity_pid
                                # Making sure the process has been killed in case of cancelled operation
                                drive_unshare_pid=$(ps -C drive-unshare -o pid=)
                                kill $drive_unshare_pid 2>/dev/null
                                ;;
                        "Untrash selected remote objects")
                                drive-untrash | zenity --progress --pulsate --auto-close --width=700 --text="Running on ${noamp_local_folder}" --title="Untrashing selected remote objects" &

                                # Passing zenity process ID & drive-menu process ID to manage zenity cancel action
                                zenity_pid=${!}
                                zenity-cancel $drive_menu_pid $zenity_pid
                                # Making sure the process has been killed in case of cancelled operation
                                drive_untrash_pid=$(ps -C drive-untrash -o pid=)
                                kill $drive_untrash_pid 2>/dev/null
                                ;;
                        "Versions")
                                drive-version | zenity --progress --pulsate --auto-close --width=700 --text="Running on ${noamp_local_folder}" --title="Listing drive & drive-google versions" &

                                # Passing zenity process ID & drive-menu process ID to manage zenity cancel action
                                zenity_pid=${!}
                                zenity-cancel $drive_menu_pid $zenity_pid
                                # Making sure the process has been killed in case of cancelled operation
                                drive_version_pid=$(ps -C drive-version -o pid=)
                                kill $drive_version_pid 2>/dev/null
                                ;;
                        *)
                                break
                                ;;
                esac
        done

        exit 0
else
        # Any parameter
        end_of_help_message_line_number=$(awk '/^# Preventing globbing /{ print NR; exit }' $(which drive-menu))
        ((end_of_help_message_line_number--))
        awk -v var=$end_of_help_message_line_number 'NR >= 20 && NR <= var' $(which drive-menu) | zenity --text-info --title "drive-menu help" --width 1150 --height 1000
        exit 1
fi