├── gdrive ├── curl ├── libusr │ ├── libz.so │ ├── libz.so.1 │ └── libz.so.1.2.8 ├── JSON.sh ├── GDriveConf ├── GDriveAutoremover └── GDriveUploader ├── test └── equip_test.sh ├── donate.md ├── LICENSE └── README.md /gdrive/curl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porunov/xiaomi_gdrive/HEAD/gdrive/curl -------------------------------------------------------------------------------- /gdrive/libusr/libz.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porunov/xiaomi_gdrive/HEAD/gdrive/libusr/libz.so -------------------------------------------------------------------------------- /gdrive/libusr/libz.so.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porunov/xiaomi_gdrive/HEAD/gdrive/libusr/libz.so.1 -------------------------------------------------------------------------------- /gdrive/libusr/libz.so.1.2.8: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porunov/xiaomi_gdrive/HEAD/gdrive/libusr/libz.so.1.2.8 -------------------------------------------------------------------------------- /test/equip_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Open Telnet 4 | 5 | if [ ! -f "/etc/init.d/S88telnet" ]; then 6 | echo "#!/bin/sh" > /etc/init.d/S88telnet 7 | echo "telnetd &" >> /etc/init.d/S88telnet 8 | chmod 755 /etc/init.d/S88telnet 9 | /etc/init.d/S88telnet 10 | fi 11 | 12 | /bin/rm -R /home/hd1/test 13 | reboot -------------------------------------------------------------------------------- /donate.md: -------------------------------------------------------------------------------- 1 | You can help me by donating any amount of money: 2 | 3 | Patreon: https://www.patreon.com/porunov 4 | 5 | Bountysource: https://salt.bountysource.com/checkout/amount?team=porunov 6 | 7 | Bitcoin address: 15PrkYhv9EZLiQbjQMJDRZsqdheE574XPe 8 | 9 | Ethereum address: 0x65a92111d599aa0f6695b011c1c01390d4f29a2a 10 | 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Alexandr Porunov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /gdrive/JSON.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | throw() { 4 | echo "$*" >&2 5 | exit 1 6 | } 7 | 8 | BRIEF=0 9 | LEAFONLY=0 10 | PRUNE=0 11 | NO_HEAD=0 12 | NORMALIZE_SOLIDUS=0 13 | 14 | usage() { 15 | echo 16 | echo "Usage: JSON.sh [-b] [-l] [-p] [-s] [-h]" 17 | echo 18 | echo "-p - Prune empty. Exclude fields with empty values." 19 | echo "-l - Leaf only. Only show leaf nodes, which stops data duplication." 20 | echo "-b - Brief. Combines 'Leaf only' and 'Prune empty' options." 21 | echo "-n - No-head. Do not show nodes that have no path (lines that start with [])." 22 | echo "-s - Remove escaping of the solidus symbol (stright slash)." 23 | echo "-h - This help text." 24 | echo 25 | } 26 | 27 | parse_options() { 28 | set -- "$@" 29 | local ARGN=$# 30 | while [ "$ARGN" -ne 0 ] 31 | do 32 | case $1 in 33 | -h) usage 34 | exit 0 35 | ;; 36 | -b) BRIEF=1 37 | LEAFONLY=1 38 | PRUNE=1 39 | ;; 40 | -l) LEAFONLY=1 41 | ;; 42 | -p) PRUNE=1 43 | ;; 44 | -n) NO_HEAD=1 45 | ;; 46 | -s) NORMALIZE_SOLIDUS=1 47 | ;; 48 | ?*) echo "ERROR: Unknown option." 49 | usage 50 | exit 0 51 | ;; 52 | esac 53 | shift 1 54 | ARGN=$((ARGN-1)) 55 | done 56 | } 57 | 58 | awk_egrep () { 59 | local pattern_string=$1 60 | 61 | gawk '{ 62 | while ($0) { 63 | start=match($0, pattern); 64 | token=substr($0, start, RLENGTH); 65 | print token; 66 | $0=substr($0, start+RLENGTH); 67 | } 68 | }' pattern="$pattern_string" 69 | } 70 | 71 | tokenize () { 72 | local GREP 73 | local ESCAPE 74 | local CHAR 75 | 76 | if echo "test string" | egrep -ao --color=never "test" >/dev/null 2>&1 77 | then 78 | GREP='egrep -ao --color=never' 79 | else 80 | GREP='egrep -ao' 81 | fi 82 | 83 | if echo "test string" | egrep -o "test" >/dev/null 2>&1 84 | then 85 | ESCAPE='(\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})' 86 | CHAR='[^[:cntrl:]"\\]' 87 | else 88 | GREP=awk_egrep 89 | ESCAPE='(\\\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})' 90 | CHAR='[^[:cntrl:]"\\\\]' 91 | fi 92 | 93 | local STRING="\"$CHAR*($ESCAPE$CHAR*)*\"" 94 | local NUMBER='-?(0|[1-9][0-9]*)([.][0-9]*)?([eE][+-]?[0-9]*)?' 95 | local KEYWORD='null|false|true' 96 | local SPACE='[[:space:]]+' 97 | 98 | # Force zsh to expand $A into multiple words 99 | local is_wordsplit_disabled=$(unsetopt 2>/dev/null | grep -c '^shwordsplit$') 100 | if [ $is_wordsplit_disabled != 0 ]; then setopt shwordsplit; fi 101 | $GREP "$STRING|$NUMBER|$KEYWORD|$SPACE|." | egrep -v "^$SPACE$" 102 | if [ $is_wordsplit_disabled != 0 ]; then unsetopt shwordsplit; fi 103 | } 104 | 105 | parse_array () { 106 | local index=0 107 | local ary='' 108 | read -r token 109 | case "$token" in 110 | ']') ;; 111 | *) 112 | while : 113 | do 114 | parse_value "$1" "$index" 115 | index=$((index+1)) 116 | ary="$ary""$value" 117 | read -r token 118 | case "$token" in 119 | ']') break ;; 120 | ',') ary="$ary," ;; 121 | *) throw "EXPECTED , or ] GOT ${token:-EOF}" ;; 122 | esac 123 | read -r token 124 | done 125 | ;; 126 | esac 127 | [ "$BRIEF" -eq 0 ] && value=$(printf '[%s]' "$ary") || value= 128 | : 129 | } 130 | 131 | parse_object () { 132 | local key 133 | local obj='' 134 | read -r token 135 | case "$token" in 136 | '}') ;; 137 | *) 138 | while : 139 | do 140 | case "$token" in 141 | '"'*'"') key=$token ;; 142 | *) throw "EXPECTED string GOT ${token:-EOF}" ;; 143 | esac 144 | read -r token 145 | case "$token" in 146 | ':') ;; 147 | *) throw "EXPECTED : GOT ${token:-EOF}" ;; 148 | esac 149 | read -r token 150 | parse_value "$1" "$key" 151 | obj="$obj$key:$value" 152 | read -r token 153 | case "$token" in 154 | '}') break ;; 155 | ',') obj="$obj," ;; 156 | *) throw "EXPECTED , or } GOT ${token:-EOF}" ;; 157 | esac 158 | read -r token 159 | done 160 | ;; 161 | esac 162 | [ "$BRIEF" -eq 0 ] && value=$(printf '{%s}' "$obj") || value= 163 | : 164 | } 165 | 166 | parse_value () { 167 | local jpath="${1:+$1,}$2" isleaf=0 isempty=0 print=0 168 | case "$token" in 169 | '{') parse_object "$jpath" ;; 170 | '[') parse_array "$jpath" ;; 171 | # At this point, the only valid single-character tokens are digits. 172 | ''|[!0-9]) throw "EXPECTED value GOT ${token:-EOF}" ;; 173 | *) value=$token 174 | # if asked, replace solidus ("\/") in json strings with normalized value: "/" 175 | [ "$NORMALIZE_SOLIDUS" -eq 1 ] && value=$(echo "$value" | sed 's#\\/#/#g') 176 | isleaf=1 177 | [ "$value" = '""' ] && isempty=1 178 | ;; 179 | esac 180 | [ "$value" = '' ] && return 181 | [ "$NO_HEAD" -eq 1 ] && [ -z "$jpath" ] && return 182 | 183 | [ "$LEAFONLY" -eq 0 ] && [ "$PRUNE" -eq 0 ] && print=1 184 | [ "$LEAFONLY" -eq 1 ] && [ "$isleaf" -eq 1 ] && [ $PRUNE -eq 0 ] && print=1 185 | [ "$LEAFONLY" -eq 0 ] && [ "$PRUNE" -eq 1 ] && [ "$isempty" -eq 0 ] && print=1 186 | [ "$LEAFONLY" -eq 1 ] && [ "$isleaf" -eq 1 ] && \ 187 | [ $PRUNE -eq 1 ] && [ $isempty -eq 0 ] && print=1 188 | [ "$print" -eq 1 ] && printf "[%s]\t%s\n" "$jpath" "$value" 189 | : 190 | } 191 | 192 | parse () { 193 | read -r token 194 | parse_value 195 | read -r token 196 | case "$token" in 197 | '') ;; 198 | *) throw "EXPECTED EOF GOT $token" ;; 199 | esac 200 | } 201 | 202 | if ([ "$0" = "$BASH_SOURCE" ] || ! [ -n "$BASH_SOURCE" ]); 203 | then 204 | parse_options "$@" 205 | tokenize | parse 206 | fi 207 | 208 | # vi: expandtab sw=2 ts=2 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Google drive loader for xiaomi smart ip camera 2 | Google drive loader for xiaomi smart ip camera (12CN). xiaomi_gdrive let you automatically upload your videos from xiaomi smart ip camera to your google drive account. Also it can automatically remove old files from your google drive account to prevent space exhaustion. 3 | 4 | ![ants_smart_webcam_ xiaomi](https://cloud.githubusercontent.com/assets/17673243/17768152/76d2a56a-653b-11e6-81db-522a29f9f1f2.png) 5 | 6 | ### Step-by-step instruction for installing xiaomi_gdrive 7 | 8 | 1. Turn off your camera and get microSD 9 | 2. Download xiaomi_gdrive and unzip it (https://github.com/porunov/xiaomi_gdrive/releases/download/0.0.5/xiaomi_gdrive.zip) 10 | 3. Copy next folders into your microSD: 11 | 12 | ``` 13 | test 14 | gdrive 15 | ``` 16 | 17 | 4. If you want to set the time when your GDrive can interact with the Internet (i.e. send or remove files to Google Drive) you can change change the time in GDriveAutoremover and GDriveUploader files. If you want to let the camera interact with the Internet 24 hour/day (immediately send a video after it is recorded) then skip this step. If you still want to change the time then open your GDriveUploader script and change start_time and finish_time variables to whatever you want in the next format: HH:MM:SS. To do it find the next line: 18 | 19 | ``` 20 | start_time="00:00:00" 21 | ``` 22 | 23 | and change the time in this line to whatever you want. Example 7:35:00 pm will be: 24 | 25 | ``` 26 | start_time="19:35:00" 27 | ``` 28 | 29 | Then find the next line: 30 | 31 | ``` 32 | finish_time="23:59:59" 33 | ``` 34 | 35 | and change it to whatever you want. Example 01:00:05 am will be: 36 | 37 | ``` 38 | finish_time="01:00:05" 39 | ``` 40 | 41 | Your camera will be able to interact with the Internet from start_time to finish_time. 42 | 43 | 5. Put microSD into your camera 44 | 6. Turn on camera 45 | 7. After turnung on a camera use telnet to connect to your camera (login: root, password: 1234qwer): 46 | 47 | ``` 48 | telnet {YOUR_CAMERA_IP_ADDRESS} 49 | Example: telnet 192.168.0.70 50 | ``` 51 | 52 | 8. Go to the browser 53 | 9. Create your Google Drive application and OAuth keys for Google Drive API (example tutorial: http://www.iperiusbackup.net/en/how-to-enable-google-drive-api-and-get-client-credentials/) 54 | 55 | Example: 56 | 1. Go to Google Api Console (https://console.developers.google.com/?hl=RU) 57 | 2. Click "Drive API" 58 | 3. Clieck "Create project" and create it (if don't have one) 59 | 4. Click "Enable" 60 | 5. Go to Credentials and add credentials to your project 61 | 1. Where will you be calling the API from? : Other UI (e.g. Windows, CLI tool) 62 | 2. What data will you be accessing? : User data 63 | 3. Click "What credentials do I need?" 64 | 4. Name your credentials as you want 65 | 5. Product name shown to users - use any name 66 | 6. Click "Done" 67 | 6. Click on your credentials 68 | 7. Save your client id and client secret 69 | 70 | 10. Go to your console back 71 | 11. Run GDriveConf to configure your Google Drive access: 72 | 73 | ``` 74 | sh /home/hd1/gdrive/GDriveConf 75 | ``` 76 | 77 | 12. Paste your client id and press enter 78 | 13. Paste your client secret and press enter 79 | 14. Copy link which you see and paste into your browser 80 | 15. Click "Accept" 81 | 16. Copy code which you see 82 | 17. Go to your console back 83 | 18. Paste your code and press enter 84 | 19. You will be suggested to see the folders. Press Enter if you want to see all folders. If you want to see only root folders type `root` and press Enter. 85 | //Folders showing isn't fast. Wait for 5-10 seconds to see your directories. 86 | 20. You will see your folders (number of folder is on the left side) 87 | 21. Type the number of a folder and press Enter. (If you want to save videos in the root dir then just press Enter) 88 | 22. You will be asked if you want to turn on automatic remove. Press `1` and type Enter if you want. Press `0` and type Enter if you do not want. GDriveAutoremover itself will delete old files in case if your disk space overflows. 89 | 23. Reboot your camera: 90 | 91 | ``` 92 | reboot 93 | ``` 94 | 95 | 23. Done 96 | 97 | How it works: 98 | The script in the loop will create the same folders as in the record folder and upload videos into Google Drive. After the reboot, or failure of the Internet script continues normally send files. If you have enabled automatic remove, GDriveAutoremover will check your free space every 45 minutes. In case when disk space is not enough, the script will erase old videos (IMPORTANT: do not put anything extra in the folder which is designed for video because GDriveAutoremover can remove it if it considers that the disk space is not enough). 99 | 100 | This scripts were tested under 1.8.5.1L firmware 101 | 102 | Troubleshooting: 103 | 104 | 1. Your camera starts reboot from time to time. Your RAM is likely not enough. Turn off additional features which you have installed. 105 | 1. Turn off ftp server: 106 | 107 | ``` 108 | rm /etc/init.d/S89ftp 109 | ``` 110 | 111 | 2. Turn off HTTP server 112 | ``` 113 | rm /home/web/server 114 | rm /home/web/record 115 | ``` 116 | 117 | 3. Turn off RTSP server 118 | 119 | ``` 120 | rm /home/rtspsvr 121 | mv /home/recv_X.726 /home/recv.726 122 | ``` 123 | 124 | 4. Reboot your camera 125 | 126 | ``` 127 | reboot 128 | ``` 129 | 130 | 2. Check if camera can send requests to the Internet. 131 | 132 | ``` 133 | ping -q -c2 8.8.8.8 134 | ping -q -c2 google.com 135 | ``` 136 | 137 | if it isn't pingable then check your route table: 138 | 139 | ``` 140 | route -n 141 | ``` 142 | 143 | 1. If your gateway isn't correct then add your gateway (Where 192.168.0.1 is your router IP address): 144 | 145 | ``` 146 | my_router_ip="192.168.0.1" 147 | route add default gw ${my_router_ip} ra0 148 | ``` 149 | 150 | 2. To have normal gateway after reboot run all next commands: 151 | 152 | ``` 153 | echo "#!/bin/sh" > /etc/init.d/S65route 154 | echo "change_def_route(){" >> /etc/init.d/S65route 155 | echo "route add default gw ${my_router_ip} ra0" >> /etc/init.d/S65route 156 | echo "}" >> /etc/init.d/S65route 157 | echo "change_def_route &" >> /etc/init.d/S65route 158 | echo "exit 0" >> /etc/init.d/S65route 159 | chmod +x vi /etc/init.d/S65route 160 | echo "${my_router_ip}" > /tmp/gw1 161 | ``` 162 | 163 | 3. Add public DNS 164 | 165 | ``` 166 | echo "nameserver 8.8.8.8" > /var/run/dhcpcd/resolv.conf/resolv.conf 167 | echo "nameserver 8.8.8.8" > /etc/resolv.conf 168 | ``` 169 | 170 | 4. Reboot your camera 171 | 172 | ``` 173 | reboot 174 | ``` 175 | 176 | -------------------------------------------------------------------------------- /gdrive/GDriveConf: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # GDriveConf version 0.5 by Alexandr Porunov https://github.com/porunov/xiaomi_gdrive 3 | # Google drive configuration script 4 | 5 | gdrive_dir="/home/hd1/gdrive/" 6 | 7 | renew_token(){ 8 | while [ 1 ] ; do 9 | ${gdrive_dir}./curl --insecure -H "Host: www.googleapis.com" -H "Content-Type: application/x-www-form-urlencoded" --request POST -o ${gdrive_dir}conf/refreshed_token --data "client_id=${client_id}&client_secret=${client_secret}&refresh_token=${refresh_token}&grant_type=refresh_token" 'https://www.googleapis.com/oauth2/v4/token' 10 | if [ -f "${gdrive_dir}conf/refreshed_token" ]; then 11 | if grep -q "access_token" ${gdrive_dir}conf/refreshed_token; then 12 | break 13 | else 14 | echo "ERROR: $(date) : Your refresh_token might has reached the limit. Please configure your google drive access again. Please use configuration scipt." 15 | echo "ERROR: $(date) : Check ${gdrive_dir}conf/refreshed_token for detailed information" 16 | fi 17 | else 18 | echo "WARNING: $(date) : Can not refresh token. Please check internet conectivity" 19 | fi 20 | check_log_file 21 | sleep 15 22 | done 23 | access_token=$(cat "${gdrive_dir}conf/refreshed_token" | ${gdrive_dir}./JSON.sh -b | egrep '\["access_token"\]' | sed 's/\[.*\][^\"0-9tf]*//g' | sed 's/\"//g') 24 | if grep -q "refresh_token" ${gdrive_dir}conf/refreshed_token; then 25 | refresh_token=$(cat "${gdrive_dir}conf/refreshed_token" | ${gdrive_dir}./JSON.sh -b | egrep '\["refresh_token"\]' | sed 's/\[.*\][^\"0-9tf]*//g' | sed 's/\"//g') 26 | fi 27 | echo "access_token='${access_token}'" > ${gdrive_dir}conf/gdrive_token.conf 28 | echo "refresh_token='${refresh_token}'" >> ${gdrive_dir}conf/gdrive_token.conf 29 | 30 | if grep -q "expires_in" ${gdrive_dir}conf/refreshed_token; then 31 | expiretion_time=$(cat "${gdrive_dir}conf/refreshed_token" | ${gdrive_dir}./JSON.sh -b | egrep '\["expires_in"\]' | sed 's/\[.*\][^\"0-9tf]*//g' | sed 's/\"//g') 32 | expires_in=`expr $expiretion_time + $(date +%s)`; 33 | echo "expires_in=${expires_in}" >> ${gdrive_dir}conf/gdrive_token.conf 34 | fi 35 | rm ${gdrive_dir}conf/refreshed_token 36 | } 37 | 38 | check_token(){ 39 | if [ ! -z ${expires_in+x} ]; then 40 | if [ $(date +%s) -ge ${expires_in} ]; then 41 | renew_token 42 | fi 43 | fi 44 | } 45 | 46 | configure(){ 47 | echo 'Enter your Client ID: ' 48 | read client_id 49 | echo 'Enter your Client secret: ' 50 | read client_secret 51 | echo "" 52 | echo 'Put this link into your browser:' 53 | echo 'https://accounts.google.com/o/oauth2/v2/auth?scope=https://www.googleapis.com/auth/drive&state=state&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code&client_id='$client_id'&access_type=offline' 54 | echo "" 55 | echo 'Copy and paste your code here: ' 56 | 57 | while [ 1 ] ; do 58 | read code 59 | ${gdrive_dir}./curl --insecure -H "Host: www.googleapis.com" -H "Content-Type: application/x-www-form-urlencoded" -d "code=${code}&client_id=${client_id}&client_secret=${client_secret}&redirect_uri=urn:ietf:wg:oauth:2.0:oob&grant_type=authorization_code" -o ${gdrive_dir}conf/response https://www.googleapis.com/oauth2/v4/token 60 | if grep -q "access_token" ${gdrive_dir}conf/response & grep -q "refresh_token" ${gdrive_dir}conf/response; then 61 | break 62 | else 63 | echo "Your code was expired or it is not correct. Please refresh a link in your browser and enter a new valid code: " 64 | fi 65 | done 66 | 67 | echo "client_id='${client_id}'" > ${gdrive_dir}conf/gdrive.conf 68 | echo "client_secret='${client_secret}'" >> ${gdrive_dir}conf/gdrive.conf 69 | 70 | access_token=$(cat "${gdrive_dir}conf/response" | ${gdrive_dir}./JSON.sh -b | egrep '\["access_token"\]' | sed 's/\[.*\][^\"0-9tf]*//g' | sed 's/\"//g') 71 | if grep -q "refresh_token" ${gdrive_dir}conf/response; then 72 | refresh_token=$(cat "${gdrive_dir}conf/response" | ${gdrive_dir}./JSON.sh -b | egrep '\["refresh_token"\]' | sed 's/\[.*\][^\"0-9tf]*//g' | sed 's/\"//g') 73 | fi 74 | echo "access_token='${access_token}'" > ${gdrive_dir}conf/gdrive_token.conf 75 | echo "refresh_token='${refresh_token}'" >> ${gdrive_dir}conf/gdrive_token.conf 76 | 77 | if grep -q "expires_in" ${gdrive_dir}conf/response; then 78 | expiretion_time=$(cat "${gdrive_dir}conf/response" | ${gdrive_dir}./JSON.sh -b | egrep '\["expires_in"\]' | sed 's/\[.*\][^\"0-9tf]*//g' | sed 's/\"//g') 79 | expires_in=`expr $expiretion_time + $(date +%s)`; 80 | echo "expires_in=${expires_in}" >> ${gdrive_dir}conf/gdrive_token.conf 81 | fi 82 | rm ${gdrive_dir}conf/response 83 | 84 | echo "" 85 | echo "Next step is the folder selection for your data. Do you want to be shown all folders or only root folders?" 86 | echo "Press Enter to show all folders. To show only root folders type 'root' without quotes and press Enter: " 87 | read rootFolder 88 | 89 | if [ "$rootFolder" = "root" ]; then 90 | rootFolder='%20and%20"root"%20in%20parents' 91 | else 92 | rootFolder='' 93 | fi; 94 | 95 | while [ 1 ] ; do 96 | ${gdrive_dir}./curl --insecure -H "Host: www.googleapis.com" -H "Authorization: Bearer ${access_token}" --request GET -o ${gdrive_dir}conf/gDriveFolders 'https://www.googleapis.com/drive/v2/files?q=mimeType="application/vnd.google-apps.folder"%20and%20trashed=false'$rootFolder'&fields=items(id,title)' 97 | if grep -q "items" ${gdrive_dir}conf/gDriveFolders ; then 98 | break 99 | else 100 | renew_token 101 | fi 102 | done 103 | 104 | echo "Select folder where you want to save your files:" 105 | echo "(If you want to choose root folder do not write anything and press Enter)" 106 | echo "" 107 | 108 | if [ -f ${gdrive_dir}conf/gDriveFolersIds ]; then 109 | rm ${gdrive_dir}conf/gDriveFolersIds 110 | fi 111 | 112 | if [ -f ${gdrive_dir}conf/gDriveFolersTitles ]; then 113 | rm ${gdrive_dir}conf/gDriveFolersTitles 114 | fi 115 | 116 | cat ${gdrive_dir}conf/gDriveFolders | ${gdrive_dir}./JSON.sh -b | egrep '\["items",[0-9]+,"id"\]' | sed 's/\[.*\][^\"]*//g' | sed 's/\"//g' >> ${gdrive_dir}conf/gDriveFolersIds 117 | cat ${gdrive_dir}conf/gDriveFolders | ${gdrive_dir}./JSON.sh -b | egrep '\["items",[0-9]+,"title"\]' | sed 's/\[.*\][^\"]*//g' | sed 's/\"//g' >> ${gdrive_dir}conf/gDriveFolersTitles 118 | 119 | rm ${gdrive_dir}conf/gDriveFolders 120 | 121 | i=1 122 | 123 | while read line; do 124 | echo "${i} - ${line}" 125 | i=`expr $i + 1` 126 | done < ${gdrive_dir}conf/gDriveFolersTitles 127 | 128 | rm ${gdrive_dir}conf/gDriveFolersTitles 129 | 130 | echo "Enter a number of a folder (Default folder: root)" 131 | echo "" 132 | read folder_number 133 | 134 | folder_id='root' 135 | 136 | if LC_ALL=C awk 'BEGIN{exit(!(ARGV[1] ~ /^[0-9]+$/))}' "$folder_number" 137 | then 138 | if [ $folder_number -lt $i ]; then 139 | if [ $folder_number -gt 0 ]; then 140 | folder_id=$(sed -n "${folder_number}p" ${gdrive_dir}conf/gDriveFolersIds) 141 | fi 142 | fi 143 | fi 144 | 145 | rm ${gdrive_dir}conf/gDriveFolersIds 146 | 147 | echo "folder_id='${folder_id}'" > ${gdrive_dir}conf/gdrive_folder.conf 148 | 149 | echo "Do you want to enable autoremove?" 150 | echo "If you enable autoremove then when your google drive free space is less then 600 MB GDriveAutoremove script will try to remove old videos (it will remove only old videos from your folder to get about 1200 MB of free space)" 151 | echo "WARNING: Do not put your personal data in the same folder where your videos are stored. GDrive autoremove script will delete all old data from that folder." 152 | echo "If you want to enable autoremove feature type '1' and press Enter. If you do not want to enable autoremove feature then just type Enter. (Default: off): " 153 | 154 | read autoremove 155 | 156 | if [ "${autoremove}" = "1" ]; then 157 | autoremove='on' 158 | else 159 | autoremove='off' 160 | fi 161 | 162 | echo "autoremove='${autoremove}'" >> ${gdrive_dir}conf/gdrive.conf 163 | echo "" 164 | echo "Your configuration files were successfully created" 165 | echo "" 166 | } 167 | 168 | echo "Configuration is started. Wait for several seconds." 169 | 170 | if [ ! -d ${gdrive_dir}conf ]; then 171 | mkdir ${gdrive_dir}conf 172 | fi 173 | if [ ! -d ${gdrive_dir}log ]; then 174 | mkdir ${gdrive_dir}log 175 | fi 176 | if [ ! -d ${gdrive_dir}tmp ]; then 177 | mkdir ${gdrive_dir}tmp 178 | fi 179 | 180 | cp ${gdrive_dir}libusr/* /home/libusr/ 181 | 182 | sed -e 's/sh \/home\/hd1\/gdrive\/GDrive\(Uploader\|Autoremover\)//g' -i /home/init.sh 183 | echo "sh ${gdrive_dir}GDriveUploader" >> /home/init.sh 184 | echo "sh ${gdrive_dir}GDriveAutoremover" >> /home/init.sh 185 | 186 | chmod +x /home/libusr/libz.so* ${gdrive_dir}GDriveUploader ${gdrive_dir}GDriveAutoremover ${gdrive_dir}JSON.sh ${gdrive_dir}curl 187 | 188 | if [ -f ${gdrive_dir}gdrive_folder.index ]; then 189 | rm ${gdrive_dir}gdrive_folder.index 190 | fi 191 | 192 | if [ -f ${gdrive_dir}gdrive_file.index ]; then 193 | rm ${gdrive_dir}gdrive_file.index 194 | fi 195 | 196 | configure 197 | -------------------------------------------------------------------------------- /gdrive/GDriveAutoremover: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # GDriveAutoremover version 0.5 by Alexandr Porunov https://github.com/porunov/xiaomi_gdrive 3 | # Google drive autoremover 4 | 5 | gdrive_dir="/home/hd1/gdrive/" 6 | total_space=0 7 | used_space=0 8 | sleep_time=0 9 | log=${gdrive_dir}log/GDriveAutoremover.log 10 | #min_free_space - 600 MB * 1048576 = 629145600 byte 11 | min_free_space=629145600 12 | #prefer_free_space - 1200 MB * 1048576 = 1258291200 byte 13 | prefer_free_space=1258291200 14 | # hours: 00 minutes: 00 seconds: 00 15 | start_time="00:00:00" 16 | # hours: 23 minutes: 59 seconds: 59 17 | finish_time="23:59:59" 18 | 19 | wait_until_proper_hours(){ 20 | while [ 1 ] ; do 21 | current_time=`date +"%H:%M:%S" | awk -F':' '{print $1 * 60 * 60 + $2 * 60 + $3}'` 22 | if [ ${current_time} -le ${finish_time} ] && [ ${current_time} -ge ${start_time} ]; then 23 | break 24 | else 25 | if [ ${current_time} -le ${start_time} ]; then 26 | sleep_time=`expr ${start_time} - ${current_time}` 27 | else 28 | sleep_time=`expr 86400 - ${current_time} + ${start_time}` 29 | fi 30 | fi 31 | sleep ${sleep_time} 32 | done 33 | } 34 | 35 | check_log_file(){ 36 | if [ $(stat -c %s ${log}) -gt 524288 ]; then 37 | tail -100 ${log} > ${log}.new 38 | mv ${log}.new ${log} 39 | rm ${log}.new 40 | fi 41 | } 42 | 43 | renew_token(){ 44 | while [ 1 ] ; do 45 | wait_until_proper_hours 46 | ${gdrive_dir}./curl --insecure -s --max-time 100 -H "Host: www.googleapis.com" -H "Content-Type: application/x-www-form-urlencoded" --request POST -o ${gdrive_dir}conf/refreshed_token --data "client_id=${client_id}&client_secret=${client_secret}&refresh_token=${refresh_token}&grant_type=refresh_token" 'https://www.googleapis.com/oauth2/v4/token' > /dev/null 47 | if [ -f "${gdrive_dir}conf/refreshed_token" ]; then 48 | if grep -q "access_token" ${gdrive_dir}conf/refreshed_token; then 49 | break 50 | else 51 | echo "ERROR: $(date) : Your refresh_token might has reached the limit. Please configure your google drive access again. Please use configuration scipt." 52 | echo "ERROR: $(date) : Check ${gdrive_dir}conf/refreshed_token for detailed information" 53 | fi 54 | else 55 | echo "WARNING: $(date) : Can not refresh token. Please check internet conectivity" 56 | fi 57 | check_log_file 58 | sleep 15 59 | done 60 | export access_token=$(cat "${gdrive_dir}conf/refreshed_token" | ${gdrive_dir}./JSON.sh -b | egrep '\["access_token"\]' | sed 's/\[.*\][^\"0-9tf]*//g' | sed 's/\"//g') 61 | if grep -q "refresh_token" ${gdrive_dir}conf/refreshed_token; then 62 | export refresh_token=$(cat "${gdrive_dir}conf/refreshed_token" | ${gdrive_dir}./JSON.sh -b | egrep '\["refresh_token"\]' | sed 's/\[.*\][^\"0-9tf]*//g' | sed 's/\"//g') 63 | fi 64 | echo "access_token='${access_token}'" > ${gdrive_dir}conf/gdrive_token.conf 65 | echo "refresh_token='${refresh_token}'" >> ${gdrive_dir}conf/gdrive_token.conf 66 | 67 | if grep -q "expires_in" ${gdrive_dir}conf/refreshed_token; then 68 | expiretion_time=$(cat "${gdrive_dir}conf/refreshed_token" | ${gdrive_dir}./JSON.sh -b | egrep '\["expires_in"\]' | sed 's/\[.*\][^\"0-9tf]*//g' | sed 's/\"//g') 69 | export expires_in=`expr $expiretion_time + $(date +%s)`; 70 | echo "expires_in=${expires_in}" >> ${gdrive_dir}conf/gdrive_token.conf 71 | fi 72 | rm ${gdrive_dir}conf/refreshed_token 73 | } 74 | 75 | check_token(){ 76 | if [ ! -z ${expires_in+x} ]; then 77 | if [ $(date +%s) -ge ${expires_in} ]; then 78 | renew_token 79 | fi 80 | fi 81 | } 82 | 83 | read_conf_files(){ 84 | check_log_file 85 | 86 | if [ -f ${gdrive_dir}conf/gdrive_token.conf ]; then 87 | . ${gdrive_dir}conf/gdrive_token.conf 88 | if [ -z ${access_token+x} ] || [ -z ${refresh_token+x} ]; then 89 | echo "ERROR: $(date) : Your token configuretion file has not been configured properly. Please use configuration scipt again" 90 | echo "ERROR: $(date) : Your token configuretion file has not access_token and refresh_token." 91 | exit 1 92 | fi 93 | else 94 | echo "ERROR: $(date) : You have to configure you access first. Please use configuration scipt" 95 | echo "ERROR: $(date) : Your token configuretion file has to be places in this location: ${gdrive_dir}conf/gdrive_token.conf" 96 | exit 1 97 | fi 98 | 99 | if [ -f ${gdrive_dir}conf/gdrive_folder.conf ]; then 100 | . ${gdrive_dir}conf/gdrive_folder.conf 101 | if [ -z ${folder_id+x} ]; then 102 | echo "ERROR: $(date) : Your folder configuretion file has not been configured properly. Please use configuration scipt again" 103 | echo "ERROR: $(date) : Your folder configuretion file has not folder_id." 104 | exit 1 105 | fi 106 | else 107 | echo "ERROR: $(date) : You have to configure you folder id first. Please use configuration scipt" 108 | echo "ERROR: $(date) : Your configuretion file has to be places in this location: ${gdrive_dir}conf/gdrive_folder.conf" 109 | exit 1 110 | fi 111 | 112 | if [ -f ${gdrive_dir}conf/gdrive.conf ]; then 113 | . ${gdrive_dir}conf/gdrive.conf 114 | if [ -z ${client_id+x} ] || [ -z ${client_secret+x} ]; then 115 | echo "ERROR: $(date) : Your configuretion file has not been configured properly. Please use configuration scipt again" 116 | echo "ERROR: $(date) : Your configuretion file has not client_id and client_secret." 117 | exit 1 118 | fi 119 | else 120 | echo "ERROR: $(date) : You have to configure you client_id and client_secret first. Please use configuration scipt" 121 | echo "ERROR: $(date) : Your configuretion file has to be places in this location: ${gdrive_dir}conf/gdrive.conf" 122 | exit 1 123 | fi 124 | 125 | if [ -f ${gdrive_dir}gdrive_folder.index ]; then 126 | . ${gdrive_dir}gdrive_folder.index 127 | if [ -z ${current_dir+x} ]; then 128 | current_dir="" 129 | fi 130 | else 131 | current_dir="" 132 | fi 133 | 134 | if [ -z ${autoremove+x} ]; then 135 | exit 0 136 | fi 137 | 138 | if [ "${autoremove}" = "off" ]; then 139 | exit 0 140 | fi 141 | echo "-----STARTING GDriveAutoremover $(date)" 142 | } 143 | 144 | get_space_info(){ 145 | check_token 146 | while [ 1 ] ; do 147 | wait_until_proper_hours 148 | ${gdrive_dir}./curl --insecure -s --max-time 100 -H "Host: www.googleapis.com" -H "Authorization: Bearer ${access_token}" --request GET -o ${gdrive_dir}tmp/spaceInfo "https://www.googleapis.com/drive/v2/about?fields=quotaBytesTotal,quotaBytesUsedAggregate" > /dev/null 149 | if [ -f "${gdrive_dir}tmp/spaceInfo" ]; then 150 | total_space=$(cat "${gdrive_dir}tmp/spaceInfo" | ${gdrive_dir}./JSON.sh -b | egrep '\["quotaBytesTotal"\]' | sed 's/\[.*\][^\"0-9tf]*//g' | sed 's/\"//g') 151 | used_space=$(cat "${gdrive_dir}tmp/spaceInfo" | ${gdrive_dir}./JSON.sh -b | egrep '\["quotaBytesUsedAggregate"\]' | sed 's/\[.*\][^\"0-9tf]*//g' | sed 's/\"//g') 152 | if [ "${total_space}" = "" ] || [ "${used_space}" = "" ]; then 153 | response_code=$(cat "${gdrive_dir}tmp/spaceInfo" | ${gdrive_dir}./JSON.sh -b | egrep '\["error","code"\]' | sed 's/\[.*\][^\"0-9tf]*//g' | sed 's/\"//g') 154 | if [ "${response_code}" = "401" ]; then 155 | echo "WARNING: $(date) : Can not get quota info. Token was expired. Trying to refresh token and get quota info again" 156 | renew_token 157 | else 158 | echo "WARNING: $(date) : Can not get quota info. Something happen. Trying to get quota info again" 159 | sleep 5 160 | fi 161 | else 162 | rm ${gdrive_dir}tmp/spaceInfo 163 | break 164 | fi 165 | else 166 | echo "WARNING: $(date) : Can not get quota info. Please check internet conectivity" 167 | sleep 15 168 | fi 169 | check_log_file 170 | done 171 | } 172 | 173 | get_folder_list(){ 174 | check_token 175 | while [ 1 ] ; do 176 | wait_until_proper_hours 177 | ${gdrive_dir}./curl --insecure -s --max-time 100 -H "Host: www.googleapis.com" -H "Authorization: Bearer ${access_token}" --request GET -o ${gdrive_dir}tmp/folderListToRemove "https://www.googleapis.com/drive/v2/files?q='${folder_id}'%20in%20parents%20and%20mimeType='application/vnd.google-apps.folder'%20and%20trashed=false&orderBy=createdDate&maxResults=${1}&fields=items(id,title)" > /dev/null 178 | if [ -f "${gdrive_dir}tmp/folderListToRemove" ]; then 179 | if ! grep -q "items" ${gdrive_dir}tmp/folderListToRemove; then 180 | response_code=$(cat "${gdrive_dir}tmp/folderListToRemove" | ${gdrive_dir}./JSON.sh -b | egrep '\["error","code"\]' | sed 's/\[.*\][^\"0-9tf]*//g' | sed 's/\"//g') 181 | if [ "${response_code}" = "401" ]; then 182 | echo "WARNING: $(date) : Can not get folders. Token was expired. Trying to refresh token and get folders again" 183 | renew_token 184 | else 185 | echo "WARNING: $(date) : Can not get folders. Something happen. Trying to get folders. again" 186 | sleep 5 187 | fi 188 | else 189 | cat ${gdrive_dir}tmp/folderListToRemove | ${gdrive_dir}./JSON.sh -b | egrep '\["items",[0-9]+,"id"\]' | sed 's/\[.*\][^\"]*//g' | sed 's/\"//g' >> ${gdrive_dir}/tmp/foldersIdsToRemove 190 | cat ${gdrive_dir}tmp/folderListToRemove | ${gdrive_dir}./JSON.sh -b | egrep '\["items",[0-9]+,"title"\]' | sed 's/\[.*\][^\"]*//g' | sed 's/\"//g' >> ${gdrive_dir}/tmp/foldersTitlesToRemove 191 | rm ${gdrive_dir}tmp/folderListToRemove 192 | break 193 | fi 194 | else 195 | echo "WARNING: $(date) : Can not get folders. Please check internet conectivity" 196 | sleep 15 197 | fi 198 | check_log_file 199 | done 200 | } 201 | 202 | remove_folder(){ 203 | check_token 204 | while [ 1 ] ; do 205 | wait_until_proper_hours 206 | ${gdrive_dir}./curl --insecure -s --max-time 100 -H "Host: www.googleapis.com" -H "Authorization: Bearer ${access_token}" --request DELETE -o ${gdrive_dir}tmp/removedFolder "https://www.googleapis.com/drive/v2/files/${1}" > /dev/null 207 | if [ -f "${gdrive_dir}tmp/removedFolder" ]; then 208 | response_code=$(cat "${gdrive_dir}tmp/removedFolder" | ${gdrive_dir}./JSON.sh -b | egrep '\["error","code"\]' | sed 's/\[.*\][^\"0-9tf]*//g' | sed 's/\"//g') 209 | if [ "${response_code}" = "401" ]; then 210 | rm ${gdrive_dir}tmp/removedFolder 211 | echo "WARNING: $(date) : Can not get folders. Token was expired. Trying to refresh token and get folders again" 212 | renew_token 213 | else 214 | rm ${gdrive_dir}tmp/removedFolder 215 | break 216 | fi 217 | else 218 | break 219 | fi 220 | check_log_file 221 | done 222 | } 223 | 224 | start_autoremover(){ 225 | while [ 1 ] ; do 226 | get_space_info 227 | let_space=`expr ${total_space} - ${min_free_space}` 228 | if [ ${used_space} -gt ${let_space} ]; then 229 | let_space=`expr ${total_space} - ${prefer_free_space}` 230 | while [ ${used_space} -gt ${let_space} ]; do 231 | folders_count=$(echo ${used_space} ${let_space} | awk '{ printf "%.0f", ($1 - $2) / 251658240 + 1}') 232 | get_folder_list ${folders_count} 233 | i=0 234 | while read folder_title_to_remove; do 235 | if [ "${folder_title_to_remove}" = "${current_dir}" ]; then 236 | break 237 | fi 238 | i=`expr $i + 1` 239 | folder_id_to_remove=$(sed -n "${i}p" ${gdrive_dir}/tmp/foldersIdsToRemove) 240 | remove_folder ${folder_id_to_remove} 241 | done < ${gdrive_dir}/tmp/foldersTitlesToRemove 242 | rm ${gdrive_dir}/tmp/foldersIdsToRemove 243 | rm ${gdrive_dir}/tmp/foldersTitlesToRemove 244 | get_space_info 245 | sleep 25 246 | done 247 | fi 248 | sleep 1200 249 | done 250 | } 251 | 252 | start_time=`echo ${start_time} | awk -F':' '{print $1 * 60 * 60 + $2 * 60 + $3}'` 253 | finish_time=`echo ${finish_time} | awk -F':' '{print $1 * 60 * 60 + $2 * 60 + $3}'` 254 | 255 | read_conf_files >> ${log} 256 | start_autoremover >> ${log} 2>&1 & 257 | exit 0 258 | -------------------------------------------------------------------------------- /gdrive/GDriveUploader: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # GDriveUploader version 0.5 by Alexandr Porunov https://github.com/porunov/xiaomi_gdrive 3 | # Google drive uploader 4 | 5 | gdrive_dir="/home/hd1/gdrive/" 6 | record_dir="/home/hd1/record/" 7 | next_dir="" 8 | next_time=0 9 | sleep_time=0 10 | current_file="" 11 | log=${gdrive_dir}log/GDriveUploader.log 12 | max_connect_tries=3 13 | # hours: 00 minutes: 00 seconds: 00 14 | start_time="00:00:00" 15 | # hours: 23 minutes: 59 seconds: 59 16 | finish_time="23:59:59" 17 | 18 | wait_until_proper_hours(){ 19 | while [ 1 ] ; do 20 | current_time=`date +"%H:%M:%S" | awk -F':' '{print $1 * 60 * 60 + $2 * 60 + $3}'` 21 | if [ ${current_time} -le ${finish_time} ] && [ ${current_time} -ge ${start_time} ]; then 22 | break 23 | else 24 | if [ ${current_time} -le ${start_time} ]; then 25 | sleep_time=`expr ${start_time} - ${current_time}` 26 | else 27 | sleep_time=`expr 86400 - ${current_time} + ${start_time}` 28 | fi 29 | fi 30 | sleep ${sleep_time} 31 | done 32 | } 33 | 34 | check_log_file(){ 35 | if [ $(stat -c %s ${log}) -gt 524288 ]; then 36 | tail -100 ${log} > ${log}.new 37 | mv ${log}.new ${log} 38 | rm ${log}.new 39 | fi 40 | } 41 | 42 | renew_token(){ 43 | while [ 1 ] ; do 44 | wait_until_proper_hours 45 | ${gdrive_dir}./curl --insecure -s --max-time 100 -H "Host: www.googleapis.com" -H "Content-Type: application/x-www-form-urlencoded" --request POST -o ${gdrive_dir}conf/refreshed_token --data "client_id=${client_id}&client_secret=${client_secret}&refresh_token=${refresh_token}&grant_type=refresh_token" 'https://www.googleapis.com/oauth2/v4/token' > /dev/null 46 | if [ -f "${gdrive_dir}conf/refreshed_token" ]; then 47 | if grep -q "access_token" ${gdrive_dir}conf/refreshed_token; then 48 | break 49 | else 50 | echo "ERROR: $(date) : Your refresh_token might has reached the limit. Please configure your google drive access again. Please use configuration scipt." 51 | echo "ERROR: $(date) : Check ${gdrive_dir}conf/refreshed_token for detailed information" 52 | fi 53 | else 54 | echo "WARNING: $(date) : Can not refresh token. Please check internet conectivity" 55 | fi 56 | check_log_file 57 | sleep 15 58 | done 59 | export access_token=$(cat "${gdrive_dir}conf/refreshed_token" | ${gdrive_dir}./JSON.sh -b | egrep '\["access_token"\]' | sed 's/\[.*\][^\"0-9tf]*//g' | sed 's/\"//g') 60 | if grep -q "refresh_token" ${gdrive_dir}conf/refreshed_token; then 61 | export refresh_token=$(cat "${gdrive_dir}conf/refreshed_token" | ${gdrive_dir}./JSON.sh -b | egrep '\["refresh_token"\]' | sed 's/\[.*\][^\"0-9tf]*//g' | sed 's/\"//g') 62 | fi 63 | echo "access_token='${access_token}'" > ${gdrive_dir}conf/gdrive_token.conf 64 | echo "refresh_token='${refresh_token}'" >> ${gdrive_dir}conf/gdrive_token.conf 65 | 66 | if grep -q "expires_in" ${gdrive_dir}conf/refreshed_token; then 67 | expiretion_time=$(cat "${gdrive_dir}conf/refreshed_token" | ${gdrive_dir}./JSON.sh -b | egrep '\["expires_in"\]' | sed 's/\[.*\][^\"0-9tf]*//g' | sed 's/\"//g') 68 | export expires_in=`expr $expiretion_time + $(date +%s)`; 69 | echo "expires_in=${expires_in}" >> ${gdrive_dir}conf/gdrive_token.conf 70 | fi 71 | rm ${gdrive_dir}conf/refreshed_token 72 | } 73 | 74 | check_token(){ 75 | if [ ! -z ${expires_in+x} ]; then 76 | if [ $(date +%s) -ge ${expires_in} ]; then 77 | renew_token 78 | fi 79 | fi 80 | } 81 | 82 | str_to_time(){ 83 | rfc_form=$(echo $1 | cut -c 1-4)$(echo $1 | cut -c 6-7)$(echo $1 | cut -c 9-10)$(echo $1 | cut -c 12-13)$(echo $1 | cut -c 15-16).$(echo $1 | cut -c 18-19) 84 | echo $(date -d ${rfc_form} +%s) 85 | } 86 | 87 | get_next_dir(){ 88 | newDir="" 89 | for n in $(ls -1 ${record_dir}); do 90 | if [ "$(expr ${current_dir} \< ${n})" = "1" ]; then 91 | newDir=$(echo ${n}) 92 | break 93 | fi 94 | done 95 | echo ${newDir} 96 | } 97 | 98 | get_next_file(){ 99 | result="" 100 | for n in $(ls -1 ${record_dir}${current_dir}); do 101 | if [ "$(expr ${current_file} \< ${n})" = "1" ] && [ "$(echo -n $n | tail -c 4)" = ".mp4" ]; then 102 | result=$(echo ${n}) 103 | break 104 | fi 105 | done 106 | echo ${result} 107 | } 108 | 109 | newest_dir(){ 110 | result="" 111 | for n in $(ls -1r ${record_dir}); do 112 | result=$(echo ${n}) 113 | break 114 | done 115 | echo "${result}" 116 | } 117 | 118 | oldest_dir(){ 119 | result="" 120 | for n in $(ls -1 ${record_dir}); do 121 | result=$(echo ${n}) 122 | break 123 | done 124 | echo "${result}" 125 | } 126 | 127 | get_oldest_file(){ 128 | result="" 129 | for n in $(ls -1 ${record_dir}${current_dir}); do 130 | if [ "$(echo -n $n | tail -c 4)" = ".mp4" ]; then 131 | result=$(echo ${n}) 132 | break 133 | fi 134 | done 135 | echo "${result}" 136 | } 137 | 138 | create_dir(){ 139 | check_token 140 | while [ 1 ] ; do 141 | wait_until_proper_hours 142 | ${gdrive_dir}./curl --insecure -s --max-time 100 -H "Host: www.googleapis.com" -H "Authorization: Bearer ${access_token}" -H "Content-Type: application/json" --data "{'title': '${1}', 'parents': [{'id': '${folder_id}'}], 'mimeType': 'application/vnd.google-apps.folder'}" --request POST -o ${gdrive_dir}tmp/lastDirInfo 'https://www.googleapis.com/drive/v2/files?fields=id' > /dev/null 143 | if [ -f "${gdrive_dir}tmp/lastDirInfo" ]; then 144 | google_dir_id=$(cat "${gdrive_dir}tmp/lastDirInfo" | ${gdrive_dir}./JSON.sh -b | egrep '\["id"\]' | sed 's/\[.*\][^\"]*//g' | sed 's/\"//g') 145 | if [ "${google_dir_id}" = "" ]; then 146 | response_code=$(cat "${gdrive_dir}tmp/lastDirInfo" | ${gdrive_dir}./JSON.sh -b | egrep '\["error","code"\]' | sed 's/\[.*\][^\"0-9tf]*//g' | sed 's/\"//g') 147 | if [ "${response_code}" = "401" ]; then 148 | echo "WARNING: $(date) : Can not create dir. Token was expired. Trying to refresh token and create new dir again" 149 | renew_token 150 | else 151 | echo "WARNING: $(date) : Can not create dir. Something happen. Trying to create new dir again" 152 | sleep 5 153 | fi 154 | else 155 | rm ${gdrive_dir}tmp/lastDirInfo 156 | break 157 | fi 158 | else 159 | echo "WARNING: $(date) : Can not create dir. Please check internet conectivity" 160 | sleep 15 161 | fi 162 | check_log_file 163 | done 164 | } 165 | 166 | generate_empty_current_file(){ 167 | current_dir_file="" 168 | current_file="" 169 | echo "current_dir_file=''" > ${gdrive_dir}gdrive_file.index 170 | } 171 | 172 | generate_oldest_dir(){ 173 | export current_dir=$(oldest_dir) 174 | if [ "${current_dir}" != "" ]; then 175 | create_dir ${current_dir} 176 | echo "current_dir='${current_dir}'" > ${gdrive_dir}gdrive_folder.index 177 | echo "google_dir_id='${google_dir_id}'" >> ${gdrive_dir}gdrive_folder.index 178 | next_time=`expr $(str_to_time "${current_dir}00M00S") + 3600` 179 | else 180 | google_dir_id="" 181 | fi 182 | } 183 | 184 | read_conf_files(){ 185 | echo "-----STARTING GDriveUploader $(date)" 186 | check_log_file 187 | 188 | if [ -f ${gdrive_dir}conf/gdrive_token.conf ]; then 189 | . ${gdrive_dir}conf/gdrive_token.conf 190 | if [ -z ${access_token+x} ] || [ -z ${refresh_token+x} ]; then 191 | echo "ERROR: $(date) : Your token configuretion file has not been configured properly. Please use configuration scipt again" 192 | echo "ERROR: $(date) : Your token configuretion file has not access_token and refresh_token." 193 | exit 1 194 | fi 195 | else 196 | echo "ERROR: $(date) : You have to configure you access first. Please use configuration scipt" 197 | echo "ERROR: $(date) : Your token configuretion file has to be places in this location: ${gdrive_dir}conf/gdrive_token.conf" 198 | exit 1 199 | fi 200 | 201 | if [ -f ${gdrive_dir}conf/gdrive_folder.conf ]; then 202 | . ${gdrive_dir}conf/gdrive_folder.conf 203 | if [ -z ${folder_id+x} ]; then 204 | echo "ERROR: $(date) : Your folder configuretion file has not been configured properly. Please use configuration scipt again" 205 | echo "ERROR: $(date) : Your folder configuretion file has not folder_id." 206 | exit 1 207 | fi 208 | else 209 | echo "ERROR: $(date) : You have to configure you folder id first. Please use configuration scipt" 210 | echo "ERROR: $(date) : Your configuretion file has to be places in this location: ${gdrive_dir}conf/gdrive_folder.conf" 211 | exit 1 212 | fi 213 | 214 | if [ -f ${gdrive_dir}conf/gdrive.conf ]; then 215 | . ${gdrive_dir}conf/gdrive.conf 216 | if [ -z ${client_id+x} ] || [ -z ${client_secret+x} ]; then 217 | echo "ERROR: $(date) : Your configuretion file has not been configured properly. Please use configuration scipt again" 218 | echo "ERROR: $(date) : Your configuretion file has not client_id and client_secret." 219 | exit 1 220 | fi 221 | else 222 | echo "ERROR: $(date) : You have to configure you client_id and client_secret first. Please use configuration scipt" 223 | echo "ERROR: $(date) : Your configuretion file has to be places in this location: ${gdrive_dir}conf/gdrive.conf" 224 | exit 1 225 | fi 226 | 227 | if [ -f ${gdrive_dir}gdrive_folder.index ]; then 228 | . ${gdrive_dir}gdrive_folder.index 229 | if [ -z ${current_dir+x} ] || [ -z ${google_dir_id+x} ]; then 230 | generate_oldest_dir 231 | else 232 | if [ ! -d "${record_dir}${current_dir}" ]; then 233 | generate_oldest_dir 234 | fi 235 | fi 236 | else 237 | generate_oldest_dir 238 | fi 239 | 240 | 241 | if [ -f ${gdrive_dir}gdrive_file.index ]; then 242 | . ${gdrive_dir}gdrive_file.index 243 | if [ -z ${current_dir_file+x} ]; then 244 | generate_empty_current_file 245 | else 246 | if [ ! -f ${record_dir}${current_dir}/$(echo ${current_dir_file} | cut -c 15-24) ]; then 247 | generate_empty_current_file 248 | fi 249 | fi 250 | else 251 | generate_empty_current_file 252 | fi 253 | 254 | if [ "${current_dir}" != "$(echo ${current_dir_file} | cut -c 1-14)" ]; then 255 | generate_empty_current_file 256 | fi 257 | } 258 | 259 | sendFile(){ 260 | check_token 261 | tries=0 262 | while [ 1 ] ; do 263 | wait_until_proper_hours 264 | ${gdrive_dir}./curl --insecure -s --max-time 1200 -H "Host: www.googleapis.com" -H "Authorization: Bearer ${access_token}" -H "Content-Length: $(stat -c %s ${record_dir}${current_dir}/${1})" -H "Content-Type: video/mp4" --request PUT -T ${record_dir}${current_dir}/${1} -o ${gdrive_dir}tmp/lastFileInfo "https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable&upload_id=${2}" 265 | if [ -f "${gdrive_dir}tmp/lastFileInfo" ]; then 266 | file_id=$(cat "${gdrive_dir}tmp/lastFileInfo" | ${gdrive_dir}./JSON.sh -b | egrep '\["id"\]' | sed 's/\[.*\][^\"]*//g' | sed 's/\"//g') 267 | if [ "${file_id}" = "" ]; then 268 | response_code=$(cat "${gdrive_dir}tmp/lastFileInfo" | ${gdrive_dir}./JSON.sh -b | egrep '\["error","code"\]' | sed 's/\[.*\][^\"0-9tf]*//g' | sed 's/\"//g') 269 | if [ "${response_code}" = "401" ]; then 270 | echo "WARNING: $(date) : Can not send the file ${record_dir}${current_dir}/${1}. Token was expired. Trying to refresh token and send file again" 271 | renew_token 272 | else 273 | echo "WARNING: $(date) : Can not send the file ${record_dir}${current_dir}/${1}. Something happen. Trying to send the file again" 274 | sleep 5 275 | fi 276 | else 277 | break 278 | fi 279 | else 280 | echo "WARNING: $(date) : Can not send file. Please check internet conectivity" 281 | sleep 15 282 | fi 283 | check_log_file 284 | if [ ! -f "${record_dir}${current_dir}/${1}" ]; then 285 | break 286 | fi 287 | ping -q -c2 8.8.8.8 > /dev/null 288 | if [ $? -eq 0 ]; then 289 | tries=`expr $tries + 1` 290 | fi 291 | if [ $tries -gt $max_connect_tries ]; then 292 | echo "WARNING: $(date) : Can not send the file ${record_dir}${current_dir}/${1}. May be it is too big. File was skipped" 293 | break 294 | fi 295 | done 296 | rm ${gdrive_dir}tmp/lastFileInfo 297 | current_file="${1}" 298 | current_dir_file="${current_dir}${current_file}" 299 | echo "current_dir_file=${current_dir_file}" > ${gdrive_dir}gdrive_file.index 300 | } 301 | 302 | sendMatadata(){ 303 | check_token 304 | jsonData="{'name': '${1}', parents: ['${google_dir_id}']}" 305 | while [ 1 ] ; do 306 | wait_until_proper_hours 307 | ${gdrive_dir}./curl --insecure -s --max-time 100 -H "Host: www.googleapis.com" -H "Authorization: Bearer ${access_token}" -H "Content-Length: $(expr length "${jsonData}")" -H "Content-Type: application/json; charset=UTF-8" -H "X-Upload-Content-Type: video/mp4" -H "X-Upload-Content-Length: $(stat -c %s ${record_dir}${current_dir}/${1})" --request POST --data "${jsonData}" -D ${gdrive_dir}tmp/lastFileMetadataInfo "https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable" > /dev/null 308 | if [ -f "${gdrive_dir}tmp/lastFileMetadataInfo" ]; then 309 | if grep -q "200 OK" ${gdrive_dir}tmp/lastFileMetadataInfo && ( grep -q "Location" ${gdrive_dir}tmp/lastFileMetadataInfo || grep -q "X-GUploader-UploadID" ${gdrive_dir}tmp/lastFileMetadataInfo; ); then 310 | upload_file_id=$(cat ${gdrive_dir}tmp/lastFileMetadataInfo | egrep 'X-GUploader-UploadID:' | sed 's/.*\ //g' | tr -d '\n' | tr -d '\r') 311 | if [ "${upload_file_id}" = "" ]; then 312 | upload_file_id=$(cat ${gdrive_dir}tmp/lastFileMetadataInfo | egrep 'Location:' | sed 's/.*upload_id=//g' | sed 's/&.*//g' | tr -d '\n' | tr -d '\r') 313 | fi 314 | if [ "${upload_file_id}" = "" ]; then 315 | echo "WARNING: $(date) : Something wrong happen when metadata of the file was sending. Trying to send metadata of the file again" 316 | sleep 5 317 | else 318 | sendFile "${1}" "${upload_file_id}" 319 | break 320 | fi 321 | else 322 | if grep -q "401 Unauthorized" ${gdrive_dir}tmp/lastFileMetadataInfo; then 323 | echo "WARNING: $(date) : Can not send metadata of the file. Token was expired. Trying to refresh token and send metadata again" 324 | renew_token 325 | else 326 | echo "WARNING: $(date) : Can not send metadata of the file. Something happen. Trying to send metadata of the file again" 327 | sleep 5 328 | fi 329 | fi 330 | 331 | else 332 | echo "WARNING: $(date) : Can not send metadata of the file. Please check internet conectivity" 333 | sleep 15 334 | fi 335 | check_log_file 336 | done 337 | rm ${gdrive_dir}tmp/lastFileMetadataInfo 338 | } 339 | 340 | finish_current_dir_uploads(){ 341 | while [ 1 ] ; do 342 | if [ "${current_file}" = "" ]; then 343 | next_file=$(get_oldest_file) 344 | else 345 | next_file=$(get_next_file) 346 | fi 347 | if [ "${next_file}" = "" ]; then 348 | break 349 | else 350 | sendMatadata "${next_file}" 351 | fi 352 | done 353 | } 354 | 355 | wait_for_new_file(){ 356 | wait_finish_time=`expr $(date +%s) + 60` 357 | while [ ${wait_finish_time} -gt $(date +%s) ] ; do 358 | new_files_count=$(ls ${record_dir}${next_dir} | wc -l) 359 | if [ ${new_files_count} -gt 0 ]; then 360 | break 361 | else 362 | sleep 5 363 | fi 364 | done 365 | } 366 | 367 | uploadFiles(){ 368 | if [ "${current_dir}" != "" ] && [ ${next_time} -eq 0 ]; then 369 | next_time=`expr $(str_to_time "${current_dir}00M00S") + 3600` 370 | fi 371 | if [ "${current_dir_file}" != "" ]; then 372 | current_file=$(echo ${current_dir_file} | cut -c 15-24) 373 | fi 374 | while [ 1 ] ; do 375 | if [ "${current_dir}" = "" ]; then 376 | generate_oldest_dir 377 | if [ "${current_dir}" = "" ]; then 378 | sleep 30 379 | continue 380 | fi 381 | fi 382 | 383 | while [ $(date +%s) -gt ${next_time} ]; do 384 | next_dir=$(get_next_dir) 385 | if [ "${next_dir}" != "" ]; then 386 | wait_for_new_file 387 | finish_current_dir_uploads 388 | export current_dir="${next_dir}" 389 | create_dir ${current_dir} 390 | echo "current_dir='${current_dir}'" > ${gdrive_dir}gdrive_folder.index 391 | echo "google_dir_id='${google_dir_id}'" >> ${gdrive_dir}gdrive_folder.index 392 | next_time=`expr $(str_to_time "${current_dir}00M00S") + 3600` 393 | generate_empty_current_file 394 | else 395 | break 396 | fi 397 | done 398 | finish_current_dir_uploads 399 | sleep 30 400 | done 401 | } 402 | 403 | start_time=`echo ${start_time} | awk -F':' '{print $1 * 60 * 60 + $2 * 60 + $3}'` 404 | finish_time=`echo ${finish_time} | awk -F':' '{print $1 * 60 * 60 + $2 * 60 + $3}'` 405 | 406 | read_conf_files >> ${log} 407 | uploadFiles >> ${log} 2>&1 & 408 | exit 0 --------------------------------------------------------------------------------