├── .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 | 
2 | 
3 | [](https://github.com/megous/megatools)
4 | [](https://github.com/alloy/terminal-notifier)
5 | [](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 |
--------------------------------------------------------------------------------