├── .gitignore ├── img └── jb-img.png ├── license.md ├── README.md └── megadl.sh /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /img/jb-img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayBrown/MEGA-D-l/HEAD/img/jb-img.png -------------------------------------------------------------------------------- /license.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 Joss Brown (pseud.) -- German laws apply -- Place of jurisdiction: Berlin, Germany 2 | 3 | --- 4 | 5 | MIT License 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![MEGAdl-platform-macos](https://img.shields.io/badge/platform-macOS-lightgrey.svg) 2 | ![MEGAdl-code-shell](https://img.shields.io/badge/code-shell-yellow.svg) 3 | [![MEGAdl-depend-megatools](https://img.shields.io/badge/dependency-megatools%201.9.98-green.svg)](https://github.com/megous/megatools) 4 | [![MEGAdl-depend-tnote](https://img.shields.io/badge/dependency-terminal--notifier%201.7.1-green.svg)](https://github.com/alloy/terminal-notifier) 5 | [![MEGAdl-license](http://img.shields.io/badge/license-MIT+-blue.svg)](https://github.com/JayBrown/MEGA-D-l/blob/master/license.md) 6 | 7 | # MEGA D/l 8 | **macOS workflow and shell script to download files from public mega.nz shares using the megatools** 9 | 10 | Minimum OS: **OS X 10.8** 11 | 12 | * click on a MEGA URL (or select a bunch of MEGA URLs), and select **Download from MEGA** from **Services** in the contextual menu 13 | * on first run, **MEGA D/l** will ask you to select the location of your MEGA download folder 14 | 15 | You can reset your download folder choice by running the following command: 16 | 17 | `rm -rf $HOME/Library/Preferences/local.lcars.MEGAdl.plist` 18 | 19 | After that **MEGA D/l** will let you select a different MEGA download folder. 20 | 21 | ## Installations 22 | ### megatools [prerequisite] 23 | More information: [megatools](https://github.com/megous/megatools) 24 | 25 | * install using [Homebrew](http://brew.sh) with `brew install megatools` (or with a similar manager) 26 | 27 | ### Main installation 28 | * [Download the latest DMG](https://github.com/JayBrown/MEGA-D-l/releases) and open 29 | 30 | #### Workflow 31 | * Double-click on the workflow file to install 32 | * If you encounter problems, open it with Automator and save/install from there 33 | 34 | #### Main shell script [optional] 35 | Only necessary if for some reason you want to run this from the shell or another shell script. For normal use the workflow will be sufficient. 36 | 37 | * Move the script `megadl.sh` to e.g. `/usr/local/bin` 38 | * In your shell enter `chmod +x /usr/local/bin/megadl.sh` 39 | * Run the script with `megadl.sh ''` (it has to be in your $PATH) 40 | 41 | ### terminal-notifier [optional, recommended] 42 | More information: [terminal-notifier](https://github.com/alloy/terminal-notifier) 43 | 44 | You need to have Spotlight enabled for `mdfind` to locate the terminal-notifier.app on your volume; if you don't install terminal-notifier, or if you have deactivated Spotlight, the MEGA D/l scripts will call notifications via AppleScript instead 45 | 46 | * install using [Homebrew](http://brew.sh) with `brew install terminal-notifier` (or with a similar manager) 47 | * move or copy `terminal-notifier.app` from the Homebrew Cellar to a suitable location, e.g. to `/Applications`, `/Applications/Utilities`, or `$HOME/Applications` 48 | 49 | ## Uninstall 50 | Remove the following files or folders: 51 | 52 | ``` 53 | /path/to/your/MEGADownloadFolder/MEGAdupes 54 | $HOME/Library/Caches/local.lcars.MEGAdl 55 | $HOME/Library/Preferences/local.lcars.MEGAdl.plist 56 | $HOME/Library/Services/Download\ from\ MEGA.workflow 57 | /usr/local/bin/megadl.sh 58 | ``` 59 | -------------------------------------------------------------------------------- /megadl.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # MEGA D/l v1.1.1 4 | # MEGA D/l (shell script version) 5 | 6 | # download public mega.nz shares 7 | # prerequisite: megatools, terminal-notifier (install with Homebrew) 8 | # optional: terminal-notifier (install with Homebrew) 9 | 10 | # to reset the MEGA download folder, run the following command: 11 | # rm -rf $HOME/Library/Preferences/local.lcars.MEGAdl.plist 12 | 13 | LANG=en_US.UTF-8 14 | export PATH=/usr/local/bin:$PATH 15 | ACCOUNT=$(/usr/bin/id -un) 16 | CURRENT_VERSION="1.11" 17 | 18 | # notify function 19 | notify () { 20 | if [[ "$NOTESTATUS" == "osa" ]] ; then 21 | /usr/bin/osascript &>/dev/null << EOT 22 | tell application "System Events" 23 | display notification "$2" with title "MEGA D/l [" & "$ACCOUNT" & "]" subtitle "$1" 24 | end tell 25 | EOT 26 | elif [[ "$NOTESTATUS" == "tn" ]] ; then 27 | "$TERMNOTE_LOC/Contents/MacOS/terminal-notifier" \ 28 | -title "MEGA D/l [$ACCOUNT]" \ 29 | -subtitle "$1" \ 30 | -message "$2" \ 31 | -appIcon "$ICON_LOC" \ 32 | >/dev/null 33 | fi 34 | } 35 | 36 | # check for update 37 | updater () { 38 | echo "Checking for update..." 39 | NEWEST_VERSION=$(/usr/bin/curl --silent https://api.github.com/repos/JayBrown/MEGA-D-l/releases/latest | /usr/bin/awk '/tag_name/ {print $2}' | xargs) 40 | if [[ "$NEWEST_VERSION" == "" ]] ; then 41 | NEWEST_VERSION="0" 42 | fi 43 | NEWEST_VERSION=${NEWEST_VERSION//,} 44 | if (( $(echo "$NEWEST_VERSION > $CURRENT_VERSION" | /usr/bin/bc -l) )) ; then 45 | notify "⚠️ Update available" "MEGA D/l v$NEWEST_VERSION" 46 | /usr/bin/open "https://github.com/JayBrown/MEGA-D-l/releases/latest" 47 | fi 48 | } 49 | 50 | # check compatibility 51 | MACOS2NO=$(/usr/bin/sw_vers -productVersion | /usr/bin/awk -F. '{print $2}') 52 | if [[ "$MACOS2NO" -le 7 ]] ; then 53 | echo "Error! Exiting…" 54 | echo "MEGA D/l needs at least OS X 10.8 (Mountain Lion)" 55 | INFO=$(/usr/bin/osascript << EOT 56 | tell application "System Events" 57 | activate 58 | set userChoice to button returned of (display alert "Error! Minimum OS requirement:" & return & "OS X 10.8 (Mountain Lion)" ¬ 59 | as critical ¬ 60 | buttons {"Quit"} ¬ 61 | default button 1 ¬ 62 | giving up after 60) 63 | end tell 64 | EOT) 65 | exit 66 | fi 67 | 68 | # icon & cache dir 69 | ICON64="iVBORw0KGgoAAAANSUhEUgAAAIwAAACMEAYAAAD+UJ19AAACYElEQVR4nOzUsW1T 70 | URxH4fcQSyBGSPWQrDRZIGUq2IAmJWyRMgWRWCCuDAWrGDwAkjsk3F/MBm6OYlnf 71 | 19zqSj/9i/N6jKenaRpjunhXV/f30zTPNzePj/N86q9fHx4evi9j/P202/3+WO47 72 | D2++3N4uyzS9/Xp3d319+p3W6+fncfTnqNx3Lpbl3bf/72q1+jHPp99pu91sfr4f 73 | 43DY7w+fu33n4tVLDwAul8AAGYEBMgIDZAQGyAgMkBEYICMwQEZggIzAABmBATIC 74 | A2QEBsgIDJARGCAjMEBGYICMwAAZgQEyAgNkBAbICAyQERggIzBARmCAjMAAGYEB 75 | MgIDZAQGyAgMkBEYICMwQEZggIzAABmBATICA2QEBsgIDJARGCAjMEBGYICMwAAZ 76 | gQEyAgNkBAbICAyQERggIzBARmCAjMAAGYEBMgIDZAQGyAgMkBEYICMwQEZggIzA 77 | ABmBATICA2QEBsgIDJARGCAjMEBGYICMwAAZgQEyAgNkBAbICAyQERggIzBARmCA 78 | jMAAGYEBMgIDZAQGyAgMkBEYICMwQEZggIzAABmBATICA2QEBsgIDJARGCAjMEBG 79 | YICMwAAZgQEyAgNkBAbICAyQERggIzBARmCAjMAAGYEBMgIDZAQGyAgMkBEYICMw 80 | QEZggIzAABmBATICA2QEBsgIDJARGCAjMEBGYICMwAAZgQEyAgNkBAbICAyQERgg 81 | IzBARmCAjMAAGYEBMgIDZAQGyAgMkBEYICMwQEZggIzAABmBATICA2QEBsgIDJAR 82 | GCAjMEBGYICMwAAZgQEy/wIAAP//nmUueblZmDIAAAAASUVORK5CYII=" 83 | CACHE_DIR="$HOME/Library/Caches/local.lcars.MEGAdl" 84 | mkdir -p "$CACHE_DIR" 85 | ICON_LOC="$CACHE_DIR/lcars.png" 86 | if [[ ! -e "$ICON_LOC" ]] ; then 87 | echo "$ICON64" > "$CACHE_DIR/lcars.base64" 88 | /usr/bin/base64 -D -i "$CACHE_DIR/lcars.base64" -o "$ICON_LOC" && rm -rf "$CACHE_DIR/lcars.base64" 89 | fi 90 | if [[ -e "$CACHE_DIR/lcars.base64" ]] ; then 91 | rm -rf "$CACHE_DIR/lcars.base64" 92 | fi 93 | 94 | # look for terminal-notifier 95 | TERMNOTE_LOC=$(/usr/bin/mdfind "kMDItemCFBundleIdentifier == 'nl.superalloy.oss.terminal-notifier'" 2>/dev/null | /usr/bin/awk 'NR==1') 96 | if [[ "$TERMNOTE_LOC" == "" ]] ; then 97 | NOTESTATUS="osa" 98 | else 99 | NOTESTATUS="tn" 100 | fi 101 | 102 | # check if megadl binary is present 103 | MEGADOWN=$(which megadl 2>/dev/null) 104 | if [[ "$MEGADOWN" != "/"*"/megadl" ]] ; then 105 | notify "✖️ Aborted!" "Please install megatools!" 106 | open https://github.com/megous/megatools 107 | exit 108 | fi 109 | 110 | # check for preferences file 111 | PREFS="local.lcars.MEGAdl" 112 | if [[ ! -f "$HOME/Library/Preferences/$PREFS.plist" ]] ; then 113 | touch "$HOME/Library/Preferences/$PREFS.plist" 114 | /usr/bin/defaults write $PREFS dlDir "" 115 | fi 116 | 117 | # set download directory 118 | DL_DIR=$(/usr/bin/defaults read $PREFS dlDir 2>/dev/null) 119 | if [[ "$DL_DIR" == "" ]] ; then 120 | DL_DIR=$(/usr/bin/osascript << EOT 121 | tell application "System Events" 122 | activate 123 | set theStartDirectory to ((path to downloads folder from user domain) as text) as alias 124 | set theMegaFolder to choose folder with prompt "Please select your MEGA download folder…" default location theStartDirectory 125 | set theMegaFolderPath to (POSIX path of theMegaFolder) 126 | end tell 127 | theMegaFolderPath 128 | EOT) 129 | if [[ "$DL_DIR" == "" ]] || [[ "$DL_DIR" == "false" ]] ; then 130 | exit 131 | fi 132 | /usr/bin/defaults write $PREFS dlDir "$DL_DIR" 133 | notify "☑️ Download folder set" "${DL_DIR/$HOME/~}" 134 | fi 135 | 136 | for URL in "$@" 137 | do 138 | 139 | # check & convert URL 140 | if [[ $URL == "http://www.nullrefer.com"* ]] ; then 141 | URL=$(echo $URL | /usr/bin/awk -F? '{print $2}') 142 | fi 143 | if [[ $URL != *"mega.nz/"* ]] && [[ $URL != *"mega.co.nz/"* ]] ; then 144 | notify "❌ Error!" "Not a MEGA URL!" 145 | continue 146 | elif [[ $URL == *" ... "* ]] ; then 147 | notify "☠️ Error!" "Poor URL formatting" 148 | continue 149 | else 150 | if [[ $URL == *"mega.co.nz/"* ]] ; then 151 | URL=$(echo $URL | /usr/bin/awk '{gsub("mega.co.nz","mega.nz"); print}') 152 | fi 153 | MEGA_URL=$(echo $URL | /usr/bin/awk '{gsub("\#","_"); gsub("\!","+"); print}') 154 | CODE=$(echo "$MEGA_URL" | /usr/bin/awk -F+ '{print $2}') 155 | SECRET=$(echo "$MEGA_URL" | /usr/bin/awk -F+ '{print $3}') 156 | SEC_COUNT=$(echo "$SECRET" | /usr/bin/wc -c | /usr/bin/xargs) 157 | if [[ "$SEC_COUNT" -lt 44 ]] ; then 158 | notify "☠️ Error!" "Poor URL formatting" 159 | continue 160 | fi 161 | fi 162 | 163 | # check if file online or offline 164 | STATUS=$(/usr/bin/curl --silent --data-ascii '[{"a":"g", "g":1, "ssl":0, "p":"'$CODE'"}]' https://eu.api.mega.co.nz/cs) 165 | if [[ "$STATUS" == "[-9]" ]] ; then 166 | notify "❌ File offline $STATUS" "mega.nz: $CODE" 167 | continue 168 | elif [[ "$STATUS" == "[-"?"]" ]] ; then 169 | notify "❓ File status unknown $STATUS" "mega.nz: $CODE" 170 | /usr/bin/open $URL 171 | continue 172 | fi 173 | 174 | # download 175 | notify "⚠️ Please wait…" "Downloading file with ID $CODE" 176 | DUPED="" 177 | DOWN=$("$MEGADOWN" "$URL" --no-progress --print-names --path "$DL_DIR" 2>&1) 178 | if [[ $(echo "$DOWN" | /usr/bin/grep "File exists") != "" ]] ; then 179 | # if file exists, move it to dupes 180 | PREVIOUS=$(echo "$DOWN" | /usr/bin/awk -F"Error opening file '" '{print $2}' | rev | /usr/bin/awk -F":'" '{print $2}' | rev) 181 | echo "$PREVIOUS" 182 | PREV_NAME=$(/usr/bin/basename "$PREVIOUS") 183 | mkdir -p "$DL_DIR/MEGAdupes" && mv "$PREVIOUS" "$DL_DIR/MEGAdupes/$PREV_NAME" && DUPED="true" 184 | # download for real this time 185 | DOWN=$("$MEGADOWN" "$URL" --no-progress --print-names --path "$DL_DIR" 2>&1) 186 | fi 187 | 188 | if [[ $(echo "$DOWN" | /usr/bin/grep "WARNING: ") != "" ]] || [[ $(echo "$DOWN" | /usr/bin/grep "ERROR: ") != "" ]] ; then 189 | WARN_INFO=$(echo "$DOWN" | rev | /usr/bin/awk -F" :" '{print $1}' | rev) 190 | notify "❌ Download error!" "$WARN_INFO [$CODE]" 191 | continue 192 | elif [[ "$DOWN" == "" ]] ; then 193 | notify "✖️ Possible error!" "No d/l confirmation [$CODE]" 194 | continue 195 | fi 196 | 197 | # compare checksums 198 | if [[ "$DUPED" == "true" ]] ; then 199 | OLDSUM=$(/sbin/md5 -q "$DL_DIR/MEGAdupes/$PREV_NAME") 200 | NEWSUM=$(/sbin/md5 -q "$DL_DIR/$DOWN") 201 | if [[ "$OLDSUM" == "$NEWSUM" ]] ; then 202 | # remove old file, then check if dupes dir is empty & delete if it is 203 | rm -rf "$DL_DIR/MEGAdupes/$PREV_NAME" 204 | ALL_DUPES=$(find "$DL_DIR/MEGAdupes" -type f -not -path '*/\.*' | /usr/bin/wc -l | /usr/bin/xargs) 205 | if [[ "$ALL_DUPES" == "0" ]] ; then 206 | rm -rf "$DL_DIR/MEGAdupes" 207 | fi 208 | fi 209 | fi 210 | 211 | # calculate file size 212 | BYTES=$(/usr/bin/stat -f%z "$DL_DIR/$DOWN") 213 | MEGABYTES=$(bc -l <<< "scale=2; $BYTES/1000000") 214 | if [[ ($MEGABYTES<1) ]] ; then 215 | SIZE="0$MEGABYTES" 216 | else 217 | SIZE="$MEGABYTES" 218 | fi 219 | 220 | notify "✅ Finished d/l: $SIZE MB" "$DOWN [$CODE]" 221 | 222 | done 223 | 224 | updater 225 | --------------------------------------------------------------------------------