Page 1 of 1

Get path of the Dropbox folder (cross-platform)

Posted: Sun Apr 29, 2012 2:26 pm
by Little John
Hi,

for some programs it is useful to know the location of the Dropbox folder on a given system.
(see also my tip "Get path of the Google Drive folder")


Most recent changes
2017-03-06
  • Adaptations in procedure _Base64ToStr() for compatibility with PB 5.60+
  • Some minor tweaks

Code: Select all

; -- Get main Dropbox folder
; by Little John, 2017-03-06
; Original version after <http://stackoverflow.com/questions/12118162/how-can-i-get-the-dropbox-folder-location-programmatically-in-python>

; Previous versions of the code successfully tested in the course of time
; with various Dropbox and PB versions (ASCII mode and Unicode mode)
; on
; [v] Windows XP    (32 bit)
; [v] Windows 7     (64 bit)
; [v] Xubuntu 12.04 (32 bit)

; Current version of the code successfully tested with Dropbox 20.4.19
; and
; [v] PB 5.44 LTS (ASCII mode and Unicode mode)
; [v] PB 5.60     (only has Unicode mode)
; on
; [v] Windows 10      (64 bit)
; [v] Linux Mint 18.1 (64 bit)


DeclareModule Dropbox
   Declare.s Folder()
EndDeclareModule


Module Dropbox
   EnableExplicit
   
   CompilerSelect #PB_Compiler_OS
      CompilerCase #PB_OS_Windows
         #Slash$ = "\"
      CompilerDefault
         #Slash$ = "/"
   CompilerEndSelect
   
   
   Procedure.s _Base64ToStr (base64$, format.i=#PB_UTF8)
      ; -- decode a Base64 encoded string 
      ; in : base64$: Base64 encoded string
      ;      format : format of the string in memory (#PB_Ascii, #PB_UTF8, or #PB_Unicode),
      ;               before it had been encoded to Base64
      ; out: return value: decoded string
      Protected *base64, base64Size.i = StringByteLength(base64$, #PB_Ascii)
      Protected *buffer, bufferSize.i = 0.8 * base64Size + 64
      Protected plainSize.i = 0, ret$ = ""
      
      If base64Size > 0
         *buffer = AllocateMemory(bufferSize)
         If *buffer
            CompilerIf #PB_Compiler_Version < 560
               *base64 = AllocateMemory(base64Size, #PB_Memory_NoClear)
               If *base64
                  PokeS(*base64, base64$, -1, #PB_Ascii|#PB_String_NoZero)
                  plainSize = Base64Decoder(*base64, base64Size, *buffer, bufferSize)
                  FreeMemory(*base64)
               EndIf
            CompilerElse
               plainSize = Base64Decoder(base64$, *buffer, bufferSize)
            CompilerEndIf   
            
            ret$ = PeekS(*buffer, plainSize, format)
            FreeMemory(*buffer)
         EndIf
      EndIf
      
      ProcedureReturn ret$
   EndProcedure
   
   
   Procedure.s _ReadLine (file$, lineNo.i)
      ; -- read one line from a file
      ; in : file$ : text file to read
      ;      lineNo: number of line to read (1 based)
      ; out: return value: n-th line of 'file$',
      ;                    or "" if the file doesn't contain so many lines
      Protected line$, fn.i, count.i=0
      
      fn = ReadFile(#PB_Any, file$)
      If fn
         While Eof(fn) = #False
            line$ = ReadString(fn)
            count + 1
            If count = lineNo
               CloseFile(fn)
               ProcedureReturn line$
            EndIf
         Wend
         CloseFile(fn)
      EndIf
      
      ProcedureReturn ""
   EndProcedure
   
   
   Macro _ExistFile (_name_)
      Bool(FileSize(_name_) > -1)
   EndMacro
   
   Macro _ExistDir (_name_)
      Bool(FileSize(_name_) = -2)
   EndMacro
   
   
   Procedure.s Folder()
      ; -- return main folder of an installed Dropbox, with trailing (back)slash,
      ;    or "" if not found
      Protected dbFile$, ret$
      
      CompilerIf #PB_Compiler_OS = #PB_OS_Windows
         dbFile$ = GetEnvironmentVariable("appdata") + "\Dropbox\host.db"
         If _ExistFile(dbFile$) = #False
            dbFile$ = GetEnvironmentVariable("localappdata") + "\Dropbox\host.db"
         EndIf   
      CompilerElse
         dbFile$ = GetHomeDirectory() + ".dropbox/host.db"
      CompilerEndIf
      
      ret$ = _Base64ToStr(_ReadLine(dbFile$, 2))
      
      If _ExistDir(ret$) = #False
         ; make an educated guess
         CompilerIf #PB_Compiler_OS = #PB_OS_Windows
            ; This is after <https://www.dropbox.com/help/321>:
            ret$ = GetEnvironmentVariable("homedrive") + GetEnvironmentVariable("homepath") + "\Dropbox"
         CompilerElse
            ; This seems to be the standard e.g. on Xubuntu and Linux Mint:
            ret$ = GetHomeDirectory() + "Dropbox"
         CompilerEndIf
         If _ExistDir(ret$) = #False
            ret$ = ""
         EndIf   
      EndIf
      
      If ret$ <> "" And Right(ret$, 1) <> #Slash$
         ret$ + #Slash$
      EndIf
      ProcedureReturn ret$   
   EndProcedure
EndModule


CompilerIf #PB_Compiler_IsMainFile
   ; -- Module demo
   
   Dropbox$ = Dropbox::Folder()
   
   Debug "Location of Dropbox folder:"
   If Dropbox$ <> ""
      Debug "'" + Dropbox$ + "'"
   Else
      Debug "not found"
   EndIf
CompilerEndIf

Re: Get path of the dropbox folder (cross-platform)

Posted: Sun Apr 29, 2012 10:02 pm
by IdeasVacuum
Well, it works on my PC and quickly. Just seems like a lot of code for such a simple requirement..........

Re: Get path of the dropbox folder (cross-platform)

Posted: Mon May 14, 2012 12:50 pm
by Kiffi
@Little John: Thanks for sharing! Image

Greetings ... Kiffi

Re: Get path of the dropbox folder (cross-platform)

Posted: Mon May 14, 2012 2:16 pm
by Little John
Hi Kiffi,

you are welcome! I'm glad that the code is useful for you.

Regards, Little John

Re: Get path of the dropbox folder (cross-platform)

Posted: Fri Mar 25, 2016 8:57 pm
by Little John
One bug fix and some minor changes, for details see first post.

Re: Get path of the dropbox folder (cross-platform)

Posted: Sat Mar 26, 2016 2:19 pm
by blueb
Hmmm...
Only works if I comment out the two macros. _ExistFile and _ExistDir
Otherwise dbFile$ returns "non-ascii characters" (Ascii and Unicode flags - tried both)

(PS - When it works... the returned DropBox location is correct)

Note: Using Windows 10 64-bit... PureBasic 5.42 x86
Compiler Switches - Create Unicode and Modern Theme support

blueb

Re: Get path of the dropbox folder (cross-platform)

Posted: Sat Mar 26, 2016 4:17 pm
by juror
Yes, the new version does appear to have problems -
"ret$ = _Base64ToStr(_ReadLine(dbFile$, 2))" produces invalid memory access.

Re: Get path of the dropbox folder (cross-platform)

Posted: Sat Mar 26, 2016 6:08 pm
by Little John
I had only tested the code with the 64 bit compiler, which worked without any problem.
But now when using the 32 bit version, I was able to reproduce the bug.
In both macros, I had forgotten the word "Bool".

Could you please test the corrected code?
Thank you, and sorry for any inconveniences.

Re: Get path of the dropbox folder (cross-platform)

Posted: Sat Mar 26, 2016 6:59 pm
by juror
It runs. Apparently fine. Since I do not have a dropbox, it correctly returns "not found".

Re: Get path of the dropbox folder (cross-platform)

Posted: Sat Mar 26, 2016 11:54 pm
by Little John
Thanks, juror.

Re: Get path of the dropbox folder (cross-platform)

Posted: Sun Mar 27, 2016 11:32 am
by blueb
Thanks for the quick fix Little John 8)

Re: Get path of the dropbox folder (cross-platform)

Posted: Mon Mar 28, 2016 2:08 pm
by Little John
I'm glad that it works now for you.
And many thanks for reporting the bug!

Re: Get path of the dropbox folder (cross-platform)

Posted: Mon Mar 06, 2017 4:25 pm
by Little John
2017-03-06
  • Adaptations in procedure _Base64ToStr() for compatibility with PB 5.60+
  • Some minor tweaks

Re: Get path of the dropbox folder (cross-platform)

Posted: Tue Mar 07, 2017 9:28 pm
by minimy
Thanks!
+1

Re: Get path of the dropbox folder (cross-platform)

Posted: Sun Feb 25, 2018 7:35 pm
by Dreamland Fantasy
Nice, just what I was looking for! :)

Kind regards,

Francis