I believe the Dropbox public folder method has been removed from the Dropbox API. You have to use the API to generate the proper url. Therefore, only the second method you have above will currently work.
Thanks, Peter. Neither of those articles showed up in my seaches.
Thanks for your feedback.
Let me ask you guys: Is there a way to use a completely different approach?
What about using AppleScript to have the Finder execute the "Copy Public Link" context menu item? Is this possible? If so, how?
Many thanks for all of your ideas.
Its possible if you can get your mouse over the icon. It's possible the Finder has enough AppleScript support to allow this, but it is well beyond what I would try to do with AppleScript.
Plus it would be a lot of UI interaction. The script solution, while tedious to set up, will produce a much better end result I suspect.
Hey JM,
Well.. It's possible but a PIA.
Scripting the contextual-menu with System Events is broken in list-view but seems to work in icon-view. Nevertheless if you want to install the Dropbox toolbar-button it's pretty easy.
This won't be quite right, because the parameters depend upon where you put the Dropbox button in the toolbar. (This is tested on 10.10.4 — different versions of OSX can have subtle or not so subtle variations.)
tell application "System Events"
tell application process "Finder"
set frontWin to (first window whose role is "AXWindow")
tell frontWin
tell menu button 1 of group 6 of toolbar 1
click
tell menu 1
click menu item "Copy Public Link"
end tell
end tell
end tell
end tell
end tell
However it's pretty pointless to use Dropbox's UI for this, because the result can be easily duplicated.
[EDIT: DropBox broke the ability to create a public link this way in late 2017 — ccs]
Here's what a public link copied from the Finder using Copy-Public-Link looks like (I've changed the user-number):
https://dl.dropboxusercontent.com/u/00000000/Developers/Stairways_Software/Keyboard%20Maestro%20ScreenShot%20Issue.mp4
Here's what a link from the Dropbox site looks like:
https://www.dropbox.com/sc/7x9xe87mjhedxwd/AAAHb_1v_IfHSUYcOyfph19va
So, if you're giving the link to someone else the scripted method is going to be better, because it anonymizes the link just like the latter example.
If you don't care who sees your static user number the job is simple to do with basic AppleScript.
You replace dbBaseURL
with your address by getting copying a public link once with the Dropbox UI, and you're ready to go to town.
------------------------------------------------------------
# Auth: Christopher Stone
# dCre: 2013/04/29 23:22
# dMod: 2015/08/05 23:58
# Appl: Finder & Script-Runner
# Task: Copy Public Dropbox URLs from selected files to the Clipboard.
# Libs: None
# Tags: @Applescript, @Dropbox, @Public, @URL, @Clipboard
# Test: Mavericks, Yosemite.
------------------------------------------------------------
try
set dbBaseURL to "https://dl.dropboxusercontent.com/u/00000000/" # User must supply.
set dbPubStr to ((path to home folder as text) & "Dropbox:Public:")
set AppleScript's text item delimiters to "/Dropbox/Public/"
tell application "Finder"
set _sel to selection as alias list
if _sel ≠ {} then
set hfsPath to item 1 of _sel as text
if (hfsPath does not contain dbPubStr) or (hfsPath = dbPubStr) then
error "Selection not in Public Dropbox folder."
end if
repeat with i in _sel
set contents of i to (dbBaseURL & (text item 2 of (get i's URL)))
end repeat
set _sel to joinList(_sel, linefeed) of me & linefeed
set the clipboard to _sel
end if
end tell
on error e number n
stdErr(e, n, true, true) of me
end try
------------------------------------------------------------
on joinList(_list, _delimiter)
set {oldTIDS, AppleScript's text item delimiters} to {AppleScript's text item delimiters, _delimiter}
set joinedList to _list as string
set AppleScript's text item delimiters to oldTIDS
return joinedList
end joinList
------------------------------------------------------------
on stdErr(e, n, beepFlag, ddFlag)
set e to e & return & return & "Num: " & n
if beepFlag = true then
beep
end if
if ddFlag = true then
tell me
set dDlg to display dialog e with title "ERROR!" buttons {"Cancel", "Copy", "OK"} default button "OK"
end tell
if button returned of dDlg = "Copy" then set the clipboard to e
else
return e
end if
end stdErr
------------------------------------------------------------
-Chris
Chris, you are the champion of champions!
Once again, you saved the day!
Your last script worked perfect! Well, almost perfect. My DropBox folder is setup in /Users/Shared/, not in Home. So the error msg threw me for a loop at first.
I made a couple of small changes, mostly for my benefit, the most important of which is changing the error msg (last line in the below code). My changes are noted by "##JM##".
You should publish your code at MacScripters so other AppleScript coders can easily find it.
set strDropBoxAcctNum to "1234567" -- Your DropBox Acct# ##JM##
set dbBaseURL to "https://dl.dropboxusercontent.com/u/" & strDropBoxAcctNum & "/" ##JM##
--set dbPubStr to ((path to home folder as text) & "Dropbox:Public:")
set dbPubStr to ((path to users folder as text) & "Shared:Dropbox:Public:") ##JM##
set AppleScript's text item delimiters to "/Dropbox/Public/"
tell application "Finder"
set _sel to selection as alias list
if _sel ≠ {} then
set hfsPath to item 1 of _sel as text
if (hfsPath does not contain dbPubStr) or (hfsPath = dbPubStr) then
error "Selected file is not in the designated Public Folder:" & return & dbPubStr ##JM##
end if
If you want to do this and do not want to use your Dropbox “Public” folder, the best way to be able to script it reliably is to set up https://github.com/andreafabrizi/Dropbox-Uploader on your system.
It is a bash script which requires about 10 minutes of initial setup, but once you have done that, it gives you a lot of functionality to interact with your Dropbox account via scripting (it does more than its name implies).
For example, if I had a file “foo” in a folder “txt” inside my Dropbox folder, I would do this to get to the share link:
dropbox_uploader.sh share txt/foo.txt | awk '{print $NF}'
No GUI scripting required. The Dropbox.app doesn’t even have to be running!
Thanks for posting another solution.
The AppleScript solution posted by @ccstone just above is working really well for me, and also doesn't require GUI scripting nor the DB app.
That’s a much easier solution, assuming that you are OK using your
regular “Public” folder on Dropbox.
I think that this the best approach in most cases.
It is easy to see and understand that EVERYTHING I put in my DB Public folder is, well, public.
While it may be convenient to have individual files that are public buried within your folder hierarchy, I think it can also be dangerous because it is hard to monitor.
I'm trying for a simple, non-script approach. I always put my shared documents in the same public folder and I'm ok with people seeing my static address.
The workflow I want is:
- Select file
- Copy file name and extension i.e. xxxxxxx.pdf
- append file name to **https://dl.dropboxusercontent.com/u/716207/share/**xxxxxxx.pdf to the clipboard
- Paste where needed
My attempted solution
How can I get the name and extension of the selected file on to the clipboard? I'm trying this with out luck:
Any tips on how to get the selected file name on to the clipboard?
I then need to figure out how to append it to my path, "https://dl.dropboxusercontent.com/u/716207/share/append-here"
Thanks for any help.
Still in my novitiate, I recently had to push my sled through this bog. This should both solve your problem, and indicate some things worth learning:
Add specified path to file name and save to system clipboard.kmmacros (3.8 KB)
A few things I didn't know that muddied my progress:
- "path", in KM, is the entire path including what I thought of as the filename.
- "parent path" in KM is the path not including what I thought of as the file name.
- "base name" in KM is what I thought of as the file name not including what I thought of as the file name extension.
- "extension" in KM is what I thought of as the file name extension.
- All of the above can be easily saved to variables
- Variable can be easily concatenated.
- Variables can be easily searched and replaced.
- RegEx is very helpful.
- For good reasons, don't use the literal text "variable" in your KM variable's names.
HTH.
—Kirby.
@Kirby_Krieger Thanks not only helping create a working copy for me, but for helping me understand how things work. Seeing how you put it together and your notes sped up my learning. I think you are ready to move out of the novitiate.
==UPDATED==: 2019-06-20 20:08 GMT-5
- Cleanup thread
- Upload revised Script, Ver 2.5.3
- Add file path verification
- Revise to with with PF8
- Now works with both Finder & PathFinder (PF8).
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Chris, unfortunately that is no longer true, ==as of 2017-09-01, Dropbox has eliminated use of the Public Folder==. And now, the "Copy Dropbox Link" does not seem to be able to be automated without UI scripting, because the root URL changes for every file. OTOH, if you know a better way -- I'm all for it.
So, based on your UI script, ==I've written a new one that uses the Dropbox button/menu item in the Finder.== Things seem to have changed since your script two years ago, and the Dropbox group is no longer in the same location. My script does not depend on group location.
AppleScript To Get New Dropbox Public Link (post 2017-09-01)
(this is NOT the same as the old Dropbox Public Folder link).
• Since 2017-09-01 public links have been disabled for all DropBox users
• So the prior methods of getting a Public Link not longer work.
• This is based on the DropBox UI in the Finder Toolbar.
property ptyScriptName : "Get Dropbox Public Link of Selected Finder Item"
property ptyScriptVer : "2.5.3" -- CHG revealInFinder Handler for PF8
property ptyScriptDate : "2019-06-20"
property ptyScriptAuthor : "JMichaelTX" -- based on script by @ccstone
(*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PURPOSE:
• Get the Public Link for any DropBox item currently selected in the Finder
• Since 2017-09-01 public links have been disabled for all DropBox users
• So the prior methods of getting a Public Link not longer work.
• This is based on the DropBox UI in the Finder Toolbar.
RETURNS:
• URL of Public Dropbox item to the Clipboard
• URL is set with "dl=1" to auto-download
UNLESS the file kind contains a keyword in the property viewKWList;
THEN it is set to "dl=0"
• Script returns Markdown link of same
REQUIRED:
1. macOS 10.11.6+
2. Mac Applications
• Dropbox
REF: The following were used in some way in the writing of this script.
1. https://www.dropbox.com/help/files-folders/public-folder
2. Based on script by Chris Stone (@ccstone)
https://forum.keyboardmaestro.com/t/how-do-i-execute-dropbox-copy-public-link/1772/7
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*)
use framework "Foundation"
use scripting additions
property LF : linefeed
try
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
set testPF to false
set frontApp to path to frontmost application as text -- use for dialogs
if ((frontApp contains "Path Finder") or testPF) then
--- Reveal Item Selected in PF in the Finder ---
-- (DropBox Menu works only in Finder)
set fileAlias to revealPFItemInFinder()
end if
set maxWait to 2.0 -- sec
set delayInt to 1.0E-3
set elapsedTime to 0.0
set cbTest to "WAITING"
set the clipboard to cbTest
tell application "Finder" to set finderSelectionList to selection as alias list
if length of finderSelectionList = 0 then error "No files were selected in the Finder!"
set fileAlias to item 1 of finderSelectionList
set filePath to POSIX path of fileAlias
if (filePath does not contain "/Dropbox/") then
error "fItem MUST in the the Dropbox folders. Invalid path:" & linefeed & filePath
end if
set oFile to info for fileAlias
tell oFile
set fileName to name
set fileSize to size
set fileKind to kind
end tell
set fileSize to (current application's NSByteCountFormatter's stringFromByteCount:fileSize countStyle:(current application's NSByteCountFormatterCountStyleDecimal)) as text
tell application "System Events"
tell application process "Finder"
set frontWin to (first window whose role is "AXWindow")
tell frontWin
set dbGrp to first group of first toolbar whose help contains "Dropbox"
# Alternate Method #
(*
IF you prefer speed over reliability, then use next statement instead of prior.
Position of the Dropbox Group/Menu may vary by macOS and how you have configured the Finder.
(uses < 0.01 sec less time in my testing, but YMMV)
set dbGrp to group 5 of toolbar 1
*)
tell dbGrp
tell menu button 1
perform action "AXPress"
tell menu 1
--- Delay Until Menu Item Shows ---
repeat until (exists menu item "Copy Dropbox Link")
delay delayInt -- short delay needed to show menu
set elapsedTime to elapsedTime + delayInt
if (elapsedTime > maxWait) then error ("Max Time Exceeded Waiting for Dropbox Menu to show: " & elapsedTime)
end repeat
click menu item "Copy Dropbox Link" -- to the Clipboard
end tell
end tell -- menu button 1
end tell -- dbGrp
end tell -- frontWin
end tell
end tell
--- Delay Until Link is on Clipboard ---
(*
NOTE: You wouldn't think this is necessary, but in my testing
I found it could take almost 1 sec for the Dropbox Mac
service to put the link on the clipboard.
*)
set elapsedTime to 0.0
set dbLink to "TBD"
repeat until (dbLink starts with "http")
delay delayInt -- short delay needed for DropBox Service
try
set dbLink to the clipboard as text
on error
set dbLink to "TBD"
end try
set elapsedTime to elapsedTime + delayInt
if (elapsedTime > maxWait) then error ("Max Time Exceeded Waiting for Dropbox Link to be put on Clipboard: " & elapsedTime)
end repeat
if (my isFileTypeAVI(fileAlias) is false) then
--- Change the DropBox Link to Auto-Download ---
set dbLink to «event SATIRPLl» "dl=0" given «class by »:"dl=1", «class $in »:dbLink
set mdTextPrefix to "Download: "
else --- File Type is either Audio, Video, or Image ---
set mdTextPrefix to "View/Download: "
end if
set the clipboard to dbLink as text
--- Build & Return Markdown Link ---
set mdLink to "[" & mdTextPrefix & fileName & " (" & fileSize & ")](" & dbLink & ")"
set scriptResults to mdLink
--~~~~~~~~~~~~~ END TRY ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
on error errMsg number errNum
if errNum = -128 then ## User Canceled
set errMsg to "[USER_CANCELED]"
end if
set scriptResults to "[ERROR]" & return & errMsg & return & return ¬
& "SCRIPT: " & ptyScriptName & " Ver: " & ptyScriptVer & return ¬
& "Error Number: " & errNum
end try
--~~~~~~~~~~~~~~~~END ON ERROR ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return scriptResults
--~~~~~~~~~~~~~~~~~~ END OF MAIN SCRIPT ~~~~~~~~~~~~~~~~~
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
on isFileTypeAVI(pFileAlias)
--–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
(* VER: 1.0 2017-12-25
PURPOSE: Determine if file is any of these top level types:
Audio, Video (Movie), Image, PDF
PARAMETERS:
• pFileAlias | alias | File to be evaluated for file type
RETURNS: true/false
AUTHOR: JMichaelTX (refactor of script by Shane Stanley)
## REQUIRES: use framework "Foundation"
REF: @ShaneStanley, Late Night Software Forum, script
http://forum.latenightsw.com/t/handler-to-determine-if-text-contains-item-in-list/893/2
--–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
*)
tell current application's NSWorkspace's sharedWorkspace()
set theUTI to its typeOfFile:(POSIX path of pFileAlias) |error|:(missing value)
return (its |type|:theUTI conformsToType:"public.movie") ¬
or (its |type|:theUTI conformsToType:"public.audio") ¬
or (its |type|:theUTI conformsToType:"public.image") ¬
or (its |type|:theUTI conformsToType:"com.adobe.pdf")
end tell
end isFileTypeAVI
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
on doesTextContainAnyListItem(pText, pList)
--–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
(* VER: 1.0 2017-12-23
PURPOSE: Determine if string (text) contains any item in the List
PARAMETERS:
• pText | text | Text to search
• pList | list | List of text items to search for
RETURNS: true IF any item in the list was found in the text
false IF NOT
AUTHOR: JMichaelTX
--–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
*)
set foundItemBool to false
repeat with aItem in pList
if pText contains (contents of aItem) then
set foundItemBool to true
exit repeat
end if
end repeat
return foundItemBool
end doesTextContainAnyListItem
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
on revealPFItemInFinder()
--–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
(* VER: 2.1 2018-03-19
PURPOSE: Reveal Item in Finder that is Selected in Path Finder
RETURNS: alias of item selected in both Finder and Path Finder
AUTHOR: JMichaelTX
--–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
*)
local finWinName, pfWinName, fileList, itemPath, oItem
--- GET THE ITEM SELECTED IN PATH FINDER ---
tell application "Path Finder"
set fileList to (get selection)
if ((fileList is missing value) or ((count of fileList) ≠ 1)) then error ("You must select only ONE file in Path Finder.")
set oItem to item 1 of fileList
set itemPath to POSIX path of oItem
set pfWinName to name of container of oItem
end tell
set itemAlias to alias POSIX file itemPath
--- REVEAL SAME ITEM IN FINDER ---
tell application "Finder"
activate -- to make sure reveal will be in frontmost window
reveal itemAlias
--- Now Wait for New Finder Window with Same Name as Path Finder ---
tell application "System Events" to set currentAppName to name of first application process whose frontmost is true
set maxWaitTime to 3.0
set delayTime to 0.1
set waitTime to 0
repeat while currentAppName ≠ "Finder"
delay delayTime
tell application "System Events" to set currentAppName to name of first application process whose frontmost is true
set waitTime to waitTime + delayTime
if (waitTime > maxWaitTime) then error "Max wait time of " & maxWaitTime & " exceeded waiting for Finder Window of " & pfWinName
end repeat
end tell
return itemAlias
end revealPFItemInFinder
Hey JM,
The only other way I know of offhand is the Dropbox-Uploader shell script TJ posted above.
As far as I can see that project on GitHub is still active and working.
Unfortunately that critter is complex enough that I think mere mortals will walk on by...
I haven't bothered with it myself. However — since my old method has been dusted by Dropbox I may just give it a try.
-Chris
I think I fall into that category.
For my purposes, the new UI script seems to be working very well, very reliable. Of course, like all UI scripts, it is subject to breaking if changes are made to the Finder UI and/or the Dropbox UI. I tried to build in some future-proofing by searching for a UI group that contains "Dropbox" rather than hard-coding the group position.
For scripts/macros posted in this forum, I prefer to not use external software that requires download/install (Satimage.osax is an exception to this).
Your script works great @JMichaelTX ! Just put it in a KM Macro to email a dropbox link. Thanks!
Just an FYI to anyone who has used dropbox_uploder.sh:
After a long time idle, the developer apparently made some updates a few months ago… but didn't increment the version number.
So… I just deleted my old version and installed the new version, and it fixed a few things that had broken. If you tried it and it didn't work for you, you might want to make sure you're using the most up-to-date version, and don't rely solely on the version number for that!
Just updated above post/script.
Hey JMichaelTX thanks so much for this! It works great, just had to update the dropbox folder name to match ours.
Hi JM,
I downloaded your script and it's working fine.
But it does no change the dl=0 to dl=1
I downloaded smile from Satimage, because you mention that in the thread and I saw some events in the script.
But should I do something else?