· 10 years ago · Nov 29, 2015, 09:54 PM
1#!/usr/bin/env bash
2#
3# Dropbox Uploader
4#
5# Copyright (C) 2010-2014 Andrea Fabrizi <andrea.fabrizi@gmail.com>
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20#
21
22#Default configuration file
23CONFIG_FILE=~/.dropbox_uploader
24
25#Default chunk size in Mb for the upload process
26#It is recommended to increase this value only if you have enough free space on your /tmp partition
27#Lower values may increase the number of http requests
28CHUNK_SIZE=4
29
30#Curl location
31#If not set, curl will be searched into the $PATH
32#CURL_BIN="/usr/bin/curl"
33
34#Default values
35TMP_DIR="/tmp"
36DEBUG=0
37QUIET=0
38SHOW_PROGRESSBAR=0
39SKIP_EXISTING_FILES=0
40ERROR_STATUS=0
41
42#Don't edit these...
43API_REQUEST_TOKEN_URL="https://api.dropbox.com/1/oauth/request_token"
44API_USER_AUTH_URL="https://www.dropbox.com/1/oauth/authorize"
45API_ACCESS_TOKEN_URL="https://api.dropbox.com/1/oauth/access_token"
46API_CHUNKED_UPLOAD_URL="https://api-content.dropbox.com/1/chunked_upload"
47API_CHUNKED_UPLOAD_COMMIT_URL="https://api-content.dropbox.com/1/commit_chunked_upload"
48API_UPLOAD_URL="https://api-content.dropbox.com/1/files_put"
49API_DOWNLOAD_URL="https://api-content.dropbox.com/1/files"
50API_DELETE_URL="https://api.dropbox.com/1/fileops/delete"
51API_MOVE_URL="https://api.dropbox.com/1/fileops/move"
52API_COPY_URL="https://api.dropbox.com/1/fileops/copy"
53API_METADATA_URL="https://api.dropbox.com/1/metadata"
54API_INFO_URL="https://api.dropbox.com/1/account/info"
55API_MKDIR_URL="https://api.dropbox.com/1/fileops/create_folder"
56API_SHARES_URL="https://api.dropbox.com/1/shares"
57API_SAVEURL_URL="https://api.dropbox.com/1/save_url/auto"
58API_SAVEURL_JOB_URL="https://api.dropbox.com/1/save_url_job"
59APP_CREATE_URL="https://www.dropbox.com/developers/apps"
60RESPONSE_FILE="$TMP_DIR/du_resp_$RANDOM"
61CHUNK_FILE="$TMP_DIR/du_chunk_$RANDOM"
62TEMP_FILE="$TMP_DIR/du_tmp_$RANDOM"
63BIN_DEPS="sed basename date grep stat dd mkdir"
64VERSION="0.16"
65
66umask 077
67
68#Check the shell
69if [ -z "$BASH_VERSION" ]; then
70 echo -e "Error: this script requires the BASH shell!"
71 exit 1
72fi
73
74shopt -s nullglob #Bash allows filename patterns which match no files to expand to a null string, rather than themselves
75shopt -s dotglob #Bash includes filenames beginning with a "." in the results of filename expansion
76
77#Look for optional config file parameter
78while getopts ":qpskdf:" opt; do
79 case $opt in
80
81 f)
82 CONFIG_FILE=$OPTARG
83 ;;
84
85 d)
86 DEBUG=1
87 ;;
88
89 q)
90 QUIET=1
91 ;;
92
93 p)
94 SHOW_PROGRESSBAR=1
95 ;;
96
97 k)
98 CURL_ACCEPT_CERTIFICATES="-k"
99 ;;
100
101 s)
102 SKIP_EXISTING_FILES=1
103 ;;
104
105 \?)
106 echo "Invalid option: -$OPTARG" >&2
107 exit 1
108 ;;
109
110 :)
111 echo "Option -$OPTARG requires an argument." >&2
112 exit 1
113 ;;
114
115 esac
116done
117
118if [[ $DEBUG != 0 ]]; then
119 echo $VERSION
120 uname -a 2> /dev/null
121 cat /etc/issue 2> /dev/null
122 set -x
123 RESPONSE_FILE="$TMP_DIR/du_resp_debug"
124fi
125
126if [[ $CURL_BIN == "" ]]; then
127 BIN_DEPS="$BIN_DEPS curl"
128 CURL_BIN="curl"
129fi
130
131#Dependencies check
132which $BIN_DEPS > /dev/null
133if [[ $? != 0 ]]; then
134 for i in $BIN_DEPS; do
135 which $i > /dev/null ||
136 NOT_FOUND="$i $NOT_FOUND"
137 done
138 echo -e "Error: Required program could not be found: $NOT_FOUND"
139 exit 1
140fi
141
142#Check if readlink is installed and supports the -m option
143#It's not necessary, so no problem if it's not installed
144which readlink > /dev/null
145if [[ $? == 0 && $(readlink -m "//test" 2> /dev/null) == "/test" ]]; then
146 HAVE_READLINK=1
147else
148 HAVE_READLINK=0
149fi
150
151#Forcing to use the builtin printf, if it's present, because it's better
152#otherwise the external printf program will be used
153#Note that the external printf command can cause character encoding issues!
154builtin printf "" 2> /dev/null
155if [[ $? == 0 ]]; then
156 PRINTF="builtin printf"
157 PRINTF_OPT="-v o"
158else
159 PRINTF=$(which printf)
160 if [[ $? != 0 ]]; then
161 echo -e "Error: Required program could not be found: printf"
162 fi
163 PRINTF_OPT=""
164fi
165
166#Print the message based on $QUIET variable
167function print
168{
169 if [[ $QUIET == 0 ]]; then
170 echo -ne "$1";
171 fi
172}
173
174#Returns unix timestamp
175function utime
176{
177 echo $(date +%s)
178}
179
180#Remove temporary files
181function remove_temp_files
182{
183 if [[ $DEBUG == 0 ]]; then
184 rm -fr "$RESPONSE_FILE"
185 rm -fr "$CHUNK_FILE"
186 rm -fr "$TEMP_FILE"
187 fi
188}
189
190#Returns the file size in bytes
191function file_size
192{
193 #Generic GNU
194 SIZE=$(stat --format="%s" "$1" 2> /dev/null)
195 if [ $? -eq 0 ]; then
196 echo $SIZE
197 return
198 fi
199
200 #Some embedded linux devices
201 SIZE=$(stat -c "%s" "$1" 2> /dev/null)
202 if [ $? -eq 0 ]; then
203 echo $SIZE
204 return
205 fi
206
207 #BSD, OSX and other OSs
208 SIZE=$(stat -f "%z" "$1" 2> /dev/null)
209 if [ $? -eq 0 ]; then
210 echo $SIZE
211 return
212 fi
213
214 echo "0"
215}
216
217
218#Usage
219function usage
220{
221 echo -e "Dropbox Uploader v$VERSION"
222 echo -e "Andrea Fabrizi - andrea.fabrizi@gmail.com\n"
223 echo -e "Usage: $0 COMMAND [PARAMETERS]..."
224 echo -e "\nCommands:"
225
226 echo -e "\t upload <LOCAL_FILE/DIR ...> <REMOTE_FILE/DIR>"
227 echo -e "\t download <REMOTE_FILE/DIR> [LOCAL_FILE/DIR]"
228 echo -e "\t delete <REMOTE_FILE/DIR>"
229 echo -e "\t move <REMOTE_FILE/DIR> <REMOTE_FILE/DIR>"
230 echo -e "\t copy <REMOTE_FILE/DIR> <REMOTE_FILE/DIR>"
231 echo -e "\t mkdir <REMOTE_DIR>"
232 echo -e "\t list [REMOTE_DIR]"
233 echo -e "\t share <REMOTE_FILE>"
234 echo -e "\t saveurl <URL> <REMOTE_DIR>"
235 echo -e "\t info"
236 echo -e "\t unlink"
237
238 echo -e "\nOptional parameters:"
239 echo -e "\t-f <FILENAME> Load the configuration file from a specific file"
240 echo -e "\t-s Skip already existing files when download/upload. Default: Overwrite"
241 echo -e "\t-d Enable DEBUG mode"
242 echo -e "\t-q Quiet mode. Don't show messages"
243 echo -e "\t-p Show cURL progress meter"
244 echo -e "\t-k Doesn't check for SSL certificates (insecure)"
245
246 echo -en "\nFor more info and examples, please see the README file.\n\n"
247 remove_temp_files
248 exit 1
249}
250
251#Check the curl exit code
252function check_http_response
253{
254 CODE=$?
255
256 #Checking curl exit code
257 case $CODE in
258
259 #OK
260 0)
261
262 ;;
263
264 #Proxy error
265 5)
266 print "\nError: Couldn't resolve proxy. The given proxy host could not be resolved.\n"
267
268 remove_temp_files
269 exit 1
270 ;;
271
272 #Missing CA certificates
273 60|58)
274 print "\nError: cURL is not able to performs peer SSL certificate verification.\n"
275 print "Please, install the default ca-certificates bundle.\n"
276 print "To do this in a Debian/Ubuntu based system, try:\n"
277 print " sudo apt-get install ca-certificates\n\n"
278 print "If the problem persists, try to use the -k option (insecure).\n"
279
280 remove_temp_files
281 exit 1
282 ;;
283
284 6)
285 print "\nError: Couldn't resolve host.\n"
286
287 remove_temp_files
288 exit 1
289 ;;
290
291 7)
292 print "\nError: Couldn't connect to host.\n"
293
294 remove_temp_files
295 exit 1
296 ;;
297
298 esac
299
300 #Checking response file for generic errors
301 if grep -q "HTTP/1.1 400" "$RESPONSE_FILE"; then
302 ERROR_MSG=$(sed -n -e 's/{"error": "\([^"]*\)"}/\1/p' "$RESPONSE_FILE")
303
304 case $ERROR_MSG in
305 *access?attempt?failed?because?this?app?is?not?configured?to?have*)
306 echo -e "\nError: The Permission type/Access level configured doesn't match the DropBox App settings!\nPlease run \"$0 unlink\" and try again."
307 exit 1
308 ;;
309 esac
310
311 fi
312
313}
314
315#Urlencode
316function urlencode
317{
318 #The printf is necessary to correctly decode unicode sequences
319 local string=$($PRINTF "${1}")
320 local strlen=${#string}
321 local encoded=""
322
323 for (( pos=0 ; pos<strlen ; pos++ )); do
324 c=${string:$pos:1}
325 case "$c" in
326 [-_.~a-zA-Z0-9] ) o="${c}" ;;
327 * ) $PRINTF $PRINTF_OPT '%%%02x' "'$c"
328 esac
329 encoded="${encoded}${o}"
330 done
331
332 echo "$encoded"
333}
334
335function normalize_path
336{
337 #The printf is necessary to correctly decode unicode sequences
338 path=$($PRINTF "${1//\/\///}")
339 if [[ $HAVE_READLINK == 1 ]]; then
340 new_path=$(readlink -m "$path")
341
342 #Adding back the final slash, if present in the source
343 if [[ ${path: -1} == "/" && ${#path} > 1 ]]; then
344 new_path="$new_path/"
345 fi
346
347 echo "$new_path"
348 else
349 echo "$path"
350 fi
351}
352
353#Check if it's a file or directory
354#Returns FILE/DIR/ERR
355function db_stat
356{
357 local FILE=$(normalize_path "$1")
358
359 #Checking if it's a file or a directory
360 $CURL_BIN $CURL_ACCEPT_CERTIFICATES -s --show-error --globoff -i -o "$RESPONSE_FILE" "$API_METADATA_URL/$ACCESS_LEVEL/$(urlencode "$FILE")?oauth_consumer_key=$APPKEY&oauth_token=$OAUTH_ACCESS_TOKEN&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26$OAUTH_ACCESS_TOKEN_SECRET&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM" 2> /dev/null
361 check_http_response
362
363 #Even if the file/dir has been deleted from DropBox we receive a 200 OK response
364 #So we must check if the file exists or if it has been deleted
365 if grep -q "\"is_deleted\":" "$RESPONSE_FILE"; then
366 local IS_DELETED=$(sed -n 's/.*"is_deleted":.\([^,]*\).*/\1/p' "$RESPONSE_FILE")
367 else
368 local IS_DELETED="false"
369 fi
370
371 #Exits...
372 grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"
373 if [[ $? == 0 && $IS_DELETED != "true" ]]; then
374
375 local IS_DIR=$(sed -n 's/^\(.*\)\"contents":.\[.*/\1/p' "$RESPONSE_FILE")
376
377 #It's a directory
378 if [[ $IS_DIR != "" ]]; then
379 echo "DIR"
380 #It's a file
381 else
382 echo "FILE"
383 fi
384
385 #Doesn't exists
386 else
387 echo "ERR"
388 fi
389}
390
391#Generic upload wrapper around db_upload_file and db_upload_dir functions
392#$1 = Local source file/dir
393#$2 = Remote destination file/dir
394function db_upload
395{
396 local SRC=$(normalize_path "$1")
397 local DST=$(normalize_path "$2")
398
399 #Checking if the file/dir exists
400 if [[ ! -e $SRC && ! -d $SRC ]]; then
401 print " > No such file or directory: $SRC\n"
402 ERROR_STATUS=1
403 return
404 fi
405
406 #Checking if the file/dir has read permissions
407 if [[ ! -r $SRC ]]; then
408 print " > Error reading file $SRC: permission denied\n"
409 ERROR_STATUS=1
410 return
411 fi
412
413 TYPE=$(db_stat "$DST")
414
415 #If DST it's a file, do nothing, it's the default behaviour
416 if [[ $TYPE == "FILE" ]]; then
417 DST="$DST"
418
419 #if DST doesn't exists and doesn't ends with a /, it will be the destination file name
420 elif [[ $TYPE == "ERR" && "${DST: -1}" != "/" ]]; then
421 DST="$DST"
422
423 #if DST doesn't exists and ends with a /, it will be the destination folder
424 elif [[ $TYPE == "ERR" && "${DST: -1}" == "/" ]]; then
425 local filename=$(basename "$SRC")
426 DST="$DST/$filename"
427
428 #If DST it'a directory, it will be the destination folder
429 elif [[ $TYPE == "DIR" ]]; then
430 local filename=$(basename "$SRC")
431 DST="$DST/$filename"
432 fi
433
434 #It's a directory
435 if [[ -d $SRC ]]; then
436 db_upload_dir "$SRC" "$DST"
437
438 #It's a file
439 elif [[ -e $SRC ]]; then
440 db_upload_file "$SRC" "$DST"
441
442 #Unsupported object...
443 else
444 print " > Skipping not regular file \"$SRC\"\n"
445 fi
446}
447
448#Generic upload wrapper around db_chunked_upload_file and db_simple_upload_file
449#The final upload function will be choosen based on the file size
450#$1 = Local source file
451#$2 = Remote destination file
452function db_upload_file
453{
454 local FILE_SRC=$(normalize_path "$1")
455 local FILE_DST=$(normalize_path "$2")
456
457 shopt -s nocasematch
458
459 #Checking not allowed file names
460 basefile_dst=$(basename "$FILE_DST")
461 if [[ $basefile_dst == "thumbs.db" || \
462 $basefile_dst == "desktop.ini" || \
463 $basefile_dst == ".ds_store" || \
464 $basefile_dst == "icon\r" || \
465 $basefile_dst == ".dropbox" || \
466 $basefile_dst == ".dropbox.attr" \
467 ]]; then
468 print " > Skipping not allowed file name \"$FILE_DST\"\n"
469 return
470 fi
471
472 shopt -u nocasematch
473
474 #Checking file size
475 FILE_SIZE=$(file_size "$FILE_SRC")
476
477 #Checking if the file already exists
478 TYPE=$(db_stat "$FILE_DST")
479 if [[ $TYPE != "ERR" && $SKIP_EXISTING_FILES == 1 ]]; then
480 print " > Skipping already existing file \"$FILE_DST\"\n"
481 return
482 fi
483
484 if [[ $FILE_SIZE -gt 157286000 ]]; then
485 #If the file is greater than 150Mb, the chunked_upload API will be used
486 db_chunked_upload_file "$FILE_SRC" "$FILE_DST"
487 else
488 db_simple_upload_file "$FILE_SRC" "$FILE_DST"
489 fi
490
491}
492
493#Simple file upload
494#$1 = Local source file
495#$2 = Remote destination file
496function db_simple_upload_file
497{
498 local FILE_SRC=$(normalize_path "$1")
499 local FILE_DST=$(normalize_path "$2")
500
501 if [[ $SHOW_PROGRESSBAR == 1 && $QUIET == 0 ]]; then
502 CURL_PARAMETERS="--progress-bar"
503 LINE_CR="\n"
504 else
505 CURL_PARAMETERS="-s"
506 LINE_CR=""
507 fi
508
509 print " > Uploading \"$FILE_SRC\" to \"$FILE_DST\"... $LINE_CR"
510 $CURL_BIN $CURL_ACCEPT_CERTIFICATES $CURL_PARAMETERS -i --globoff -o "$RESPONSE_FILE" --upload-file "$FILE_SRC" "$API_UPLOAD_URL/$ACCESS_LEVEL/$(urlencode "$FILE_DST")?oauth_consumer_key=$APPKEY&oauth_token=$OAUTH_ACCESS_TOKEN&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26$OAUTH_ACCESS_TOKEN_SECRET&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM"
511 check_http_response
512
513 #Check
514 if grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; then
515 print "DONE\n"
516 else
517 print "FAILED\n"
518 print "An error occurred requesting /upload\n"
519 ERROR_STATUS=1
520 fi
521}
522
523#Chunked file upload
524#$1 = Local source file
525#$2 = Remote destination file
526function db_chunked_upload_file
527{
528 local FILE_SRC=$(normalize_path "$1")
529 local FILE_DST=$(normalize_path "$2")
530
531 print " > Uploading \"$FILE_SRC\" to \"$FILE_DST\""
532
533 local FILE_SIZE=$(file_size "$FILE_SRC")
534 local OFFSET=0
535 local UPLOAD_ID=""
536 local UPLOAD_ERROR=0
537 local CHUNK_PARAMS=""
538
539 #Uploading chunks...
540 while ([[ $OFFSET != $FILE_SIZE ]]); do
541
542 let OFFSET_MB=$OFFSET/1024/1024
543
544 #Create the chunk
545 dd if="$FILE_SRC" of="$CHUNK_FILE" bs=1048576 skip=$OFFSET_MB count=$CHUNK_SIZE 2> /dev/null
546
547 #Only for the first request these parameters are not included
548 if [[ $OFFSET != 0 ]]; then
549 CHUNK_PARAMS="upload_id=$UPLOAD_ID&offset=$OFFSET"
550 fi
551
552 #Uploading the chunk...
553 echo > "$RESPONSE_FILE"
554 $CURL_BIN $CURL_ACCEPT_CERTIFICATES -s --show-error --globoff -i -o "$RESPONSE_FILE" --upload-file "$CHUNK_FILE" "$API_CHUNKED_UPLOAD_URL?$CHUNK_PARAMS&oauth_consumer_key=$APPKEY&oauth_token=$OAUTH_ACCESS_TOKEN&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26$OAUTH_ACCESS_TOKEN_SECRET&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM" 2> /dev/null
555 #check_http_response not needed, because we have to retry the request in case of error
556
557 #Check
558 if grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; then
559 print "."
560 UPLOAD_ERROR=0
561 UPLOAD_ID=$(sed -n 's/.*"upload_id": *"*\([^"]*\)"*.*/\1/p' "$RESPONSE_FILE")
562 OFFSET=$(sed -n 's/.*"offset": *\([^}]*\).*/\1/p' "$RESPONSE_FILE")
563 else
564 print "*"
565 let UPLOAD_ERROR=$UPLOAD_ERROR+1
566
567 #On error, the upload is retried for max 3 times
568 if [[ $UPLOAD_ERROR -gt 2 ]]; then
569 print " FAILED\n"
570 print "An error occurred requesting /chunked_upload\n"
571 ERROR_STATUS=1
572 return
573 fi
574 fi
575
576 done
577
578 UPLOAD_ERROR=0
579
580 #Commit the upload
581 while (true); do
582
583 echo > "$RESPONSE_FILE"
584 $CURL_BIN $CURL_ACCEPT_CERTIFICATES -s --show-error --globoff -i -o "$RESPONSE_FILE" --data "upload_id=$UPLOAD_ID&oauth_consumer_key=$APPKEY&oauth_token=$OAUTH_ACCESS_TOKEN&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26$OAUTH_ACCESS_TOKEN_SECRET&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM" "$API_CHUNKED_UPLOAD_COMMIT_URL/$ACCESS_LEVEL/$(urlencode "$FILE_DST")" 2> /dev/null
585 #check_http_response not needed, because we have to retry the request in case of error
586
587 #Check
588 if grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; then
589 print "."
590 UPLOAD_ERROR=0
591 break
592 else
593 print "*"
594 let UPLOAD_ERROR=$UPLOAD_ERROR+1
595
596 #On error, the commit is retried for max 3 times
597 if [[ $UPLOAD_ERROR -gt 2 ]]; then
598 print " FAILED\n"
599 print "An error occurred requesting /commit_chunked_upload\n"
600 ERROR_STATUS=1
601 return
602 fi
603 fi
604
605 done
606
607 print " DONE\n"
608}
609
610#Directory upload
611#$1 = Local source dir
612#$2 = Remote destination dir
613function db_upload_dir
614{
615 local DIR_SRC=$(normalize_path "$1")
616 local DIR_DST=$(normalize_path "$2")
617
618 #Creatig remote directory
619 db_mkdir "$DIR_DST"
620
621 for file in "$DIR_SRC/"*; do
622 db_upload "$file" "$DIR_DST"
623 done
624}
625
626#Generic download wrapper
627#$1 = Remote source file/dir
628#$2 = Local destination file/dir
629function db_download
630{
631 local SRC=$(normalize_path "$1")
632 local DST=$(normalize_path "$2")
633
634 TYPE=$(db_stat "$SRC")
635
636 #It's a directory
637 if [[ $TYPE == "DIR" ]]; then
638
639 #If the DST folder is not specified, I assume that is the current directory
640 if [[ $DST == "" ]]; then
641 DST="."
642 fi
643
644 #Checking if the destination directory exists
645 if [[ ! -d $DST ]]; then
646 local basedir=""
647 else
648 local basedir=$(basename "$SRC")
649 fi
650
651 local DEST_DIR=$(normalize_path "$DST/$basedir")
652 print " > Downloading \"$SRC\" to \"$DEST_DIR\"... \n"
653 print " > Creating local directory \"$DEST_DIR\"... "
654 mkdir -p "$DEST_DIR"
655
656 #Check
657 if [[ $? == 0 ]]; then
658 print "DONE\n"
659 else
660 print "FAILED\n"
661 ERROR_STATUS=1
662 return
663 fi
664
665 #Extracting directory content [...]
666 #and replacing "}, {" with "}\n{"
667 #I don't like this piece of code... but seems to be the only way to do this with SED, writing a portable code...
668 local DIR_CONTENT=$(sed -n 's/.*: \[{\(.*\)/\1/p' "$RESPONSE_FILE" | sed 's/}, *{/}\
669{/g')
670
671 #Extracting files and subfolders
672 TMP_DIR_CONTENT_FILE="${RESPONSE_FILE}_$RANDOM"
673 echo "$DIR_CONTENT" | sed -n 's/.*"path": *"\([^"]*\)",.*"is_dir": *\([^"]*\),.*/\1:\2/p' > $TMP_DIR_CONTENT_FILE
674
675 #For each entry...
676 while read -r line; do
677
678 local FILE=${line%:*}
679 local TYPE=${line#*:}
680
681 #Removing unneeded /
682 FILE=${FILE##*/}
683
684 if [[ $TYPE == "false" ]]; then
685 db_download_file "$SRC/$FILE" "$DEST_DIR/$FILE"
686 else
687 db_download "$SRC/$FILE" "$DEST_DIR"
688 fi
689
690 done < $TMP_DIR_CONTENT_FILE
691
692 rm -fr $TMP_DIR_CONTENT_FILE
693
694 #It's a file
695 elif [[ $TYPE == "FILE" ]]; then
696
697 #Checking DST
698 if [[ $DST == "" ]]; then
699 DST=$(basename "$SRC")
700 fi
701
702 #If the destination is a directory, the file will be download into
703 if [[ -d $DST ]]; then
704 DST="$DST/$SRC"
705 fi
706
707 db_download_file "$SRC" "$DST"
708
709 #Doesn't exists
710 else
711 print " > No such file or directory: $SRC\n"
712 ERROR_STATUS=1
713 return
714 fi
715}
716
717#Simple file download
718#$1 = Remote source file
719#$2 = Local destination file
720function db_download_file
721{
722 local FILE_SRC=$(normalize_path "$1")
723 local FILE_DST=$(normalize_path "$2")
724
725 if [[ $SHOW_PROGRESSBAR == 1 && $QUIET == 0 ]]; then
726 CURL_PARAMETERS="--progress-bar"
727 LINE_CR="\n"
728 else
729 CURL_PARAMETERS="-s"
730 LINE_CR=""
731 fi
732
733 #Checking if the file already exists
734 if [[ -e $FILE_DST && $SKIP_EXISTING_FILES == 1 ]]; then
735 print " > Skipping already existing file \"$FILE_DST\"\n"
736 return
737 fi
738
739 #Creating the empty file, that for two reasons:
740 #1) In this way I can check if the destination file is writable or not
741 #2) Curl doesn't automatically creates files with 0 bytes size
742 dd if=/dev/zero of="$FILE_DST" count=0 2> /dev/null
743 if [[ $? != 0 ]]; then
744 print " > Error writing file $FILE_DST: permission denied\n"
745 ERROR_STATUS=1
746 return
747 fi
748
749 print " > Downloading \"$FILE_SRC\" to \"$FILE_DST\"... $LINE_CR"
750 $CURL_BIN $CURL_ACCEPT_CERTIFICATES $CURL_PARAMETERS --globoff -D "$RESPONSE_FILE" -o "$FILE_DST" "$API_DOWNLOAD_URL/$ACCESS_LEVEL/$(urlencode "$FILE_SRC")?oauth_consumer_key=$APPKEY&oauth_token=$OAUTH_ACCESS_TOKEN&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26$OAUTH_ACCESS_TOKEN_SECRET&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM"
751 check_http_response
752
753 #Check
754 if grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; then
755 print "DONE\n"
756 else
757 print "FAILED\n"
758 rm -fr "$FILE_DST"
759 ERROR_STATUS=1
760 return
761 fi
762}
763
764#Saveurl
765#$1 = URL
766#$2 = Remote file destination
767function db_saveurl
768{
769 local URL="$1"
770 local FILE_DST=$(normalize_path "$2")
771 local FILE_NAME=$(basename "$URL")
772
773 print " > Downloading \"$URL\" to \"$FILE_DST\"..."
774 $CURL_BIN $CURL_ACCEPT_CERTIFICATES -s --show-error --globoff -i -o "$RESPONSE_FILE" --data "url=$(urlencode "$URL")&oauth_consumer_key=$APPKEY&oauth_token=$OAUTH_ACCESS_TOKEN&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26$OAUTH_ACCESS_TOKEN_SECRET&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM" "$API_SAVEURL_URL/$FILE_DST/$FILE_NAME" 2> /dev/null
775 check_http_response
776
777 JOB_ID=$(sed -n 's/.*"job": *"*\([^"]*\)"*.*/\1/p' "$RESPONSE_FILE")
778 if [[ $JOB_ID == "" ]]; then
779 print " > Error getting the job id\n"
780 return
781 fi
782
783 #Checking the status
784 while (true); do
785
786 $CURL_BIN $CURL_ACCEPT_CERTIFICATES -s --show-error --globoff -i -o "$RESPONSE_FILE" --data "oauth_consumer_key=$APPKEY&oauth_token=$OAUTH_ACCESS_TOKEN&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26$OAUTH_ACCESS_TOKEN_SECRET&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM" "$API_SAVEURL_JOB_URL/$JOB_ID" 2> /dev/null
787 check_http_response
788
789 STATUS=$(sed -n 's/.*"status": *"*\([^"]*\)"*.*/\1/p' "$RESPONSE_FILE")
790 case $STATUS in
791
792 PENDING)
793 print "."
794 ;;
795
796 DOWNLOADING)
797 print "+"
798 ;;
799
800 COMPLETE)
801 print " DONE\n"
802 break
803 ;;
804
805 FAILED)
806 print " ERROR\n"
807 MESSAGE=$(sed -n 's/.*"error": *"*\([^"]*\)"*.*/\1/p' "$RESPONSE_FILE")
808 print " > Error: $MESSAGE\n"
809 break
810 ;;
811
812 esac
813
814 sleep 2
815
816 done
817}
818
819#Prints account info
820function db_account_info
821{
822 print "Dropbox Uploader v$VERSION\n\n"
823 print " > Getting info... "
824 $CURL_BIN $CURL_ACCEPT_CERTIFICATES -s --show-error --globoff -i -o "$RESPONSE_FILE" --data "oauth_consumer_key=$APPKEY&oauth_token=$OAUTH_ACCESS_TOKEN&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26$OAUTH_ACCESS_TOKEN_SECRET&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM" "$API_INFO_URL" 2> /dev/null
825 check_http_response
826
827 #Check
828 if grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; then
829
830 name=$(sed -n 's/.*"display_name": "\([^"]*\).*/\1/p' "$RESPONSE_FILE")
831 echo -e "\n\nName:\t$name"
832
833 uid=$(sed -n 's/.*"uid": \([0-9]*\).*/\1/p' "$RESPONSE_FILE")
834 echo -e "UID:\t$uid"
835
836 email=$(sed -n 's/.*"email": "\([^"]*\).*/\1/p' "$RESPONSE_FILE")
837 echo -e "Email:\t$email"
838
839 quota=$(sed -n 's/.*"quota": \([0-9]*\).*/\1/p' "$RESPONSE_FILE")
840 let quota_mb=$quota/1024/1024
841 echo -e "Quota:\t$quota_mb Mb"
842
843 used=$(sed -n 's/.*"normal": \([0-9]*\).*/\1/p' "$RESPONSE_FILE")
844 let used_mb=$used/1024/1024
845 echo -e "Used:\t$used_mb Mb"
846
847 let free_mb=($quota-$used)/1024/1024
848 echo -e "Free:\t$free_mb Mb"
849
850 echo ""
851
852 else
853 print "FAILED\n"
854 ERROR_STATUS=1
855 fi
856}
857
858#Account unlink
859function db_unlink
860{
861 echo -ne "Are you sure you want unlink this script from your Dropbox account? [y/n]"
862 read answer
863 if [[ $answer == "y" ]]; then
864 rm -fr "$CONFIG_FILE"
865 echo -ne "DONE\n"
866 fi
867}
868
869#Delete a remote file
870#$1 = Remote file to delete
871function db_delete
872{
873 local FILE_DST=$(normalize_path "$1")
874
875 print " > Deleting \"$FILE_DST\"... "
876 $CURL_BIN $CURL_ACCEPT_CERTIFICATES -s --show-error --globoff -i -o "$RESPONSE_FILE" --data "oauth_consumer_key=$APPKEY&oauth_token=$OAUTH_ACCESS_TOKEN&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26$OAUTH_ACCESS_TOKEN_SECRET&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM&root=$ACCESS_LEVEL&path=$(urlencode "$FILE_DST")" "$API_DELETE_URL" 2> /dev/null
877 check_http_response
878
879 #Check
880 if grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; then
881 print "DONE\n"
882 else
883 print "FAILED\n"
884 ERROR_STATUS=1
885 fi
886}
887
888#Move/Rename a remote file
889#$1 = Remote file to rename or move
890#$2 = New file name or location
891function db_move
892{
893 local FILE_SRC=$(normalize_path "$1")
894 local FILE_DST=$(normalize_path "$2")
895
896 TYPE=$(db_stat "$FILE_DST")
897
898 #If the destination it's a directory, the source will be moved into it
899 if [[ $TYPE == "DIR" ]]; then
900 local filename=$(basename "$FILE_SRC")
901 FILE_DST=$(normalize_path "$FILE_DST/$filename")
902 fi
903
904 print " > Moving \"$FILE_SRC\" to \"$FILE_DST\" ... "
905 $CURL_BIN $CURL_ACCEPT_CERTIFICATES -s --show-error --globoff -i -o "$RESPONSE_FILE" --data "oauth_consumer_key=$APPKEY&oauth_token=$OAUTH_ACCESS_TOKEN&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26$OAUTH_ACCESS_TOKEN_SECRET&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM&root=$ACCESS_LEVEL&from_path=$(urlencode "$FILE_SRC")&to_path=$(urlencode "$FILE_DST")" "$API_MOVE_URL" 2> /dev/null
906 check_http_response
907
908 #Check
909 if grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; then
910 print "DONE\n"
911 else
912 print "FAILED\n"
913 ERROR_STATUS=1
914 fi
915}
916
917#Copy a remote file to a remote location
918#$1 = Remote file to rename or move
919#$2 = New file name or location
920function db_copy
921{
922 local FILE_SRC=$(normalize_path "$1")
923 local FILE_DST=$(normalize_path "$2")
924
925 TYPE=$(db_stat "$FILE_DST")
926
927 #If the destination it's a directory, the source will be copied into it
928 if [[ $TYPE == "DIR" ]]; then
929 local filename=$(basename "$FILE_SRC")
930 FILE_DST=$(normalize_path "$FILE_DST/$filename")
931 fi
932
933 print " > Copying \"$FILE_SRC\" to \"$FILE_DST\" ... "
934 $CURL_BIN $CURL_ACCEPT_CERTIFICATES -s --show-error --globoff -i -o "$RESPONSE_FILE" --data "oauth_consumer_key=$APPKEY&oauth_token=$OAUTH_ACCESS_TOKEN&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26$OAUTH_ACCESS_TOKEN_SECRET&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM&root=$ACCESS_LEVEL&from_path=$(urlencode "$FILE_SRC")&to_path=$(urlencode "$FILE_DST")" "$API_COPY_URL" 2> /dev/null
935 check_http_response
936
937 #Check
938 if grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; then
939 print "DONE\n"
940 else
941 print "FAILED\n"
942 ERROR_STATUS=1
943 fi
944}
945
946#Create a new directory
947#$1 = Remote directory to create
948function db_mkdir
949{
950 local DIR_DST=$(normalize_path "$1")
951
952 print " > Creating Directory \"$DIR_DST\"... "
953 $CURL_BIN $CURL_ACCEPT_CERTIFICATES -s --show-error --globoff -i -o "$RESPONSE_FILE" --data "oauth_consumer_key=$APPKEY&oauth_token=$OAUTH_ACCESS_TOKEN&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26$OAUTH_ACCESS_TOKEN_SECRET&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM&root=$ACCESS_LEVEL&path=$(urlencode "$DIR_DST")" "$API_MKDIR_URL" 2> /dev/null
954 check_http_response
955
956 #Check
957 if grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; then
958 print "DONE\n"
959 elif grep -q "^HTTP/1.1 403 Forbidden" "$RESPONSE_FILE"; then
960 print "ALREADY EXISTS\n"
961 else
962 print "FAILED\n"
963 ERROR_STATUS=1
964 fi
965}
966
967#List remote directory
968#$1 = Remote directory
969function db_list
970{
971 local DIR_DST=$(normalize_path "$1")
972
973 print " > Listing \"$DIR_DST\"... "
974 $CURL_BIN $CURL_ACCEPT_CERTIFICATES -s --show-error --globoff -i -o "$RESPONSE_FILE" "$API_METADATA_URL/$ACCESS_LEVEL/$(urlencode "$DIR_DST")?oauth_consumer_key=$APPKEY&oauth_token=$OAUTH_ACCESS_TOKEN&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26$OAUTH_ACCESS_TOKEN_SECRET&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM" 2> /dev/null
975 check_http_response
976
977 #Check
978 if grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; then
979
980 local IS_DIR=$(sed -n 's/^\(.*\)\"contents":.\[.*/\1/p' "$RESPONSE_FILE")
981
982 #It's a directory
983 if [[ $IS_DIR != "" ]]; then
984
985 print "DONE\n"
986
987 #Extracting directory content [...]
988 #and replacing "}, {" with "}\n{"
989 #I don't like this piece of code... but seems to be the only way to do this with SED, writing a portable code...
990 local DIR_CONTENT=$(sed -n 's/.*: \[{\(.*\)/\1/p' "$RESPONSE_FILE" | sed 's/}, *{/}\
991{/g')
992
993 #Converting escaped quotes to unicode format
994 echo "$DIR_CONTENT" | sed 's/\\"/\\u0022/' > "$TEMP_FILE"
995
996 #Extracting files and subfolders
997 rm -fr "$RESPONSE_FILE"
998 while read -r line; do
999
1000 local FILE=$(echo "$line" | sed -n 's/.*"path": *"\([^"]*\)".*/\1/p')
1001 local IS_DIR=$(echo "$line" | sed -n 's/.*"is_dir": *\([^,]*\).*/\1/p')
1002 local SIZE=$(echo "$line" | sed -n 's/.*"bytes": *\([0-9]*\).*/\1/p')
1003
1004 echo -e "$FILE:$IS_DIR;$SIZE" >> "$RESPONSE_FILE"
1005
1006 done < "$TEMP_FILE"
1007
1008 #Looking for the biggest file size
1009 #to calculate the padding to use
1010 local padding=0
1011 while read -r line; do
1012 local FILE=${line%:*}
1013 local META=${line##*:}
1014 local SIZE=${META#*;}
1015
1016 if [[ ${#SIZE} -gt $padding ]]; then
1017 padding=${#SIZE}
1018 fi
1019 done < "$RESPONSE_FILE"
1020
1021 #For each entry, printing directories...
1022 while read -r line; do
1023
1024 local FILE=${line%:*}
1025 local META=${line##*:}
1026 local TYPE=${META%;*}
1027 local SIZE=${META#*;}
1028
1029 #Removing unneeded /
1030 FILE=${FILE##*/}
1031
1032 if [[ $TYPE == "true" ]]; then
1033 FILE=$(echo -e "$FILE")
1034 $PRINTF " [D] %-${padding}s %s\n" "$SIZE" "$FILE"
1035 fi
1036
1037 done < "$RESPONSE_FILE"
1038
1039 #For each entry, printing files...
1040 while read -r line; do
1041
1042 local FILE=${line%:*}
1043 local META=${line##*:}
1044 local TYPE=${META%;*}
1045 local SIZE=${META#*;}
1046
1047 #Removing unneeded /
1048 FILE=${FILE##*/}
1049
1050 if [[ $TYPE == "false" ]]; then
1051 FILE=$(echo -e "$FILE")
1052 $PRINTF " [F] %-${padding}s %s\n" "$SIZE" "$FILE"
1053 fi
1054
1055 done < "$RESPONSE_FILE"
1056
1057 #It's a file
1058 else
1059 print "FAILED: $DIR_DST is not a directory!\n"
1060 ERROR_STATUS=1
1061 fi
1062
1063 else
1064 print "FAILED\n"
1065 ERROR_STATUS=1
1066 fi
1067}
1068
1069#Share remote file
1070#$1 = Remote file
1071function db_share
1072{
1073 local FILE_DST=$(normalize_path "$1")
1074
1075 $CURL_BIN $CURL_ACCEPT_CERTIFICATES -s --show-error --globoff -i -o "$RESPONSE_FILE" "$API_SHARES_URL/$ACCESS_LEVEL/$(urlencode "$FILE_DST")?oauth_consumer_key=$APPKEY&oauth_token=$OAUTH_ACCESS_TOKEN&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26$OAUTH_ACCESS_TOKEN_SECRET&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM&short_url=true" 2> /dev/null
1076 check_http_response
1077
1078 #Check
1079 if grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; then
1080 print " > Share link: "
1081 SHARE_LINK=$(sed -n 's/.*"url": "\([^"]*\).*/\1/p' "$RESPONSE_FILE")
1082 echo "$SHARE_LINK"
1083 else
1084 print "FAILED\n"
1085 ERROR_STATUS=1
1086 fi
1087}
1088
1089################
1090#### SETUP ####
1091################
1092
1093#CHECKING FOR AUTH FILE
1094if [[ -e $CONFIG_FILE ]]; then
1095
1096 #Loading data... and change old format config if necesary.
1097 source "$CONFIG_FILE" 2>/dev/null || {
1098 sed -i'' 's/:/=/' "$CONFIG_FILE" && source "$CONFIG_FILE" 2>/dev/null
1099 }
1100
1101 #Checking the loaded data
1102 if [[ $APPKEY == "" || $APPSECRET == "" || $OAUTH_ACCESS_TOKEN_SECRET == "" || $OAUTH_ACCESS_TOKEN == "" ]]; then
1103 echo -ne "Error loading data from $CONFIG_FILE...\n"
1104 echo -ne "It is recommended to run $0 unlink\n"
1105 remove_temp_files
1106 exit 1
1107 fi
1108
1109 #Back compatibility with previous Dropbox Uploader versions
1110 if [[ $ACCESS_LEVEL == "" ]]; then
1111 ACCESS_LEVEL="dropbox"
1112 fi
1113
1114#NEW SETUP...
1115else
1116
1117 echo -ne "\n This is the first time you run this script.\n\n"
1118 echo -ne " 1) Open the following URL in your Browser, and log in using your account: $APP_CREATE_URL\n"
1119 echo -ne " 2) Click on \"Create App\", then select \"Dropbox API app\"\n"
1120 echo -ne " 3) Now go on with the configuration, choosing the app permissions and access restrictions to your DropBox folder\n"
1121 echo -ne " 4) Enter the \"App Name\" that you prefer (e.g. MyUploader$RANDOM$RANDOM$RANDOM)\n\n"
1122
1123 echo -ne " Now, click on the \"Create App\" button.\n\n"
1124
1125 echo -ne " When your new App is successfully created, please type the\n"
1126 echo -ne " App Key, App Secret and the Permission type shown in the confirmation page:\n\n"
1127
1128 #Getting the app key and secret from the user
1129 while (true); do
1130
1131 echo -ne " # App key: "
1132 read APPKEY
1133
1134 echo -ne " # App secret: "
1135 read APPSECRET
1136
1137 echo -ne "\nPermission type:\n App folder [a]: If you choose that the app only needs access to files it creates\n Full Dropbox [f]: If you choose that the app needs access to files already on Dropbox\n\n # Permission type [a/f]: "
1138 read ACCESS_LEVEL
1139
1140 if [[ $ACCESS_LEVEL == "a" ]]; then
1141 ACCESS_LEVEL="sandbox"
1142 ACCESS_MSG="App Folder"
1143 else
1144 ACCESS_LEVEL="dropbox"
1145 ACCESS_MSG="Full Dropbox"
1146 fi
1147
1148 echo -ne "\n > App key is $APPKEY, App secret is $APPSECRET and Access level is $ACCESS_MSG. Looks ok? [y/n]: "
1149 read answer
1150 if [[ $answer == "y" ]]; then
1151 break;
1152 fi
1153
1154 done
1155
1156 #TOKEN REQUESTS
1157 echo -ne "\n > Token request... "
1158 $CURL_BIN $CURL_ACCEPT_CERTIFICATES -s --show-error --globoff -i -o "$RESPONSE_FILE" --data "oauth_consumer_key=$APPKEY&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM" "$API_REQUEST_TOKEN_URL" 2> /dev/null
1159 check_http_response
1160 OAUTH_TOKEN_SECRET=$(sed -n 's/oauth_token_secret=\([a-z A-Z 0-9]*\).*/\1/p' "$RESPONSE_FILE")
1161 OAUTH_TOKEN=$(sed -n 's/.*oauth_token=\([a-z A-Z 0-9]*\)/\1/p' "$RESPONSE_FILE")
1162
1163 if [[ $OAUTH_TOKEN != "" && $OAUTH_TOKEN_SECRET != "" ]]; then
1164 echo -ne "OK\n"
1165 else
1166 echo -ne " FAILED\n\n Please, check your App key and secret...\n\n"
1167 remove_temp_files
1168 exit 1
1169 fi
1170
1171 while (true); do
1172
1173 #USER AUTH
1174 echo -ne "\n Please open the following URL in your browser, and allow Dropbox Uploader\n"
1175 echo -ne " to access your DropBox folder:\n\n --> ${API_USER_AUTH_URL}?oauth_token=$OAUTH_TOKEN\n"
1176 echo -ne "\nPress enter when done...\n"
1177 read
1178
1179 #API_ACCESS_TOKEN_URL
1180 echo -ne " > Access Token request... "
1181 $CURL_BIN $CURL_ACCEPT_CERTIFICATES -s --show-error --globoff -i -o "$RESPONSE_FILE" --data "oauth_consumer_key=$APPKEY&oauth_token=$OAUTH_TOKEN&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26$OAUTH_TOKEN_SECRET&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM" "$API_ACCESS_TOKEN_URL" 2> /dev/null
1182 check_http_response
1183 OAUTH_ACCESS_TOKEN_SECRET=$(sed -n 's/oauth_token_secret=\([a-z A-Z 0-9]*\)&.*/\1/p' "$RESPONSE_FILE")
1184 OAUTH_ACCESS_TOKEN=$(sed -n 's/.*oauth_token=\([a-z A-Z 0-9]*\)&.*/\1/p' "$RESPONSE_FILE")
1185 OAUTH_ACCESS_UID=$(sed -n 's/.*uid=\([0-9]*\)/\1/p' "$RESPONSE_FILE")
1186
1187 if [[ $OAUTH_ACCESS_TOKEN != "" && $OAUTH_ACCESS_TOKEN_SECRET != "" && $OAUTH_ACCESS_UID != "" ]]; then
1188 echo -ne "OK\n"
1189
1190 #Saving data in new format, compatible with source command.
1191 echo "APPKEY=$APPKEY" > "$CONFIG_FILE"
1192 echo "APPSECRET=$APPSECRET" >> "$CONFIG_FILE"
1193 echo "ACCESS_LEVEL=$ACCESS_LEVEL" >> "$CONFIG_FILE"
1194 echo "OAUTH_ACCESS_TOKEN=$OAUTH_ACCESS_TOKEN" >> "$CONFIG_FILE"
1195 echo "OAUTH_ACCESS_TOKEN_SECRET=$OAUTH_ACCESS_TOKEN_SECRET" >> "$CONFIG_FILE"
1196
1197 echo -ne "\n Setup completed!\n"
1198 break
1199 else
1200 print " FAILED\n"
1201 ERROR_STATUS=1
1202 fi
1203
1204 done;
1205
1206 remove_temp_files
1207 exit $ERROR_STATUS
1208fi
1209
1210################
1211#### START ####
1212################
1213
1214COMMAND=${@:$OPTIND:1}
1215ARG1=${@:$OPTIND+1:1}
1216ARG2=${@:$OPTIND+2:1}
1217
1218let argnum=$#-$OPTIND
1219
1220#CHECKING PARAMS VALUES
1221case $COMMAND in
1222
1223 upload)
1224
1225 if [[ $argnum -lt 2 ]]; then
1226 usage
1227 fi
1228
1229 FILE_DST=${@:$#:1}
1230
1231 for (( i=$OPTIND+1; i<$#; i++ )); do
1232 FILE_SRC=${@:$i:1}
1233 db_upload "$FILE_SRC" "/$FILE_DST"
1234 done
1235
1236 ;;
1237
1238 download)
1239
1240 if [[ $argnum -lt 1 ]]; then
1241 usage
1242 fi
1243
1244 FILE_SRC=$ARG1
1245 FILE_DST=$ARG2
1246
1247 db_download "/$FILE_SRC" "$FILE_DST"
1248
1249 ;;
1250
1251 saveurl)
1252
1253 if [[ $argnum -lt 1 ]]; then
1254 usage
1255 fi
1256
1257 URL=$ARG1
1258 FILE_DST=$ARG2
1259
1260 db_saveurl "$URL" "/$FILE_DST"
1261
1262 ;;
1263
1264 share)
1265
1266 if [[ $argnum -lt 1 ]]; then
1267 usage
1268 fi
1269
1270 FILE_DST=$ARG1
1271
1272 db_share "/$FILE_DST"
1273
1274 ;;
1275
1276 info)
1277
1278 db_account_info
1279
1280 ;;
1281
1282 delete|remove)
1283
1284 if [[ $argnum -lt 1 ]]; then
1285 usage
1286 fi
1287
1288 FILE_DST=$ARG1
1289
1290 db_delete "/$FILE_DST"
1291
1292 ;;
1293
1294 move|rename)
1295
1296 if [[ $argnum -lt 2 ]]; then
1297 usage
1298 fi
1299
1300 FILE_SRC=$ARG1
1301 FILE_DST=$ARG2
1302
1303 db_move "/$FILE_SRC" "/$FILE_DST"
1304
1305 ;;
1306
1307 copy)
1308
1309 if [[ $argnum -lt 2 ]]; then
1310 usage
1311 fi
1312
1313 FILE_SRC=$ARG1
1314 FILE_DST=$ARG2
1315
1316 db_copy "/$FILE_SRC" "/$FILE_DST"
1317
1318 ;;
1319
1320 mkdir)
1321
1322 if [[ $argnum -lt 1 ]]; then
1323 usage
1324 fi
1325
1326 DIR_DST=$ARG1
1327
1328 db_mkdir "/$DIR_DST"
1329
1330 ;;
1331
1332 list)
1333
1334 DIR_DST=$ARG1
1335
1336 #Checking DIR_DST
1337 if [[ $DIR_DST == "" ]]; then
1338 DIR_DST="/"
1339 fi
1340
1341 db_list "/$DIR_DST"
1342
1343 ;;
1344
1345 unlink)
1346
1347 db_unlink
1348
1349 ;;
1350
1351 *)
1352
1353 if [[ $COMMAND != "" ]]; then
1354 print "Error: Unknown command: $COMMAND\n\n"
1355 ERROR_STATUS=1
1356 fi
1357 usage
1358
1359 ;;
1360
1361esac
1362
1363remove_temp_files
1364exit $ERROR_STATUS