Get path of the Dropbox folder (cross-platform)

Share your advanced PureBasic knowledge/code with the community.
Little John
Addict
Addict
Posts: 4527
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Get path of the Dropbox folder (cross-platform)

Post 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
Last edited by Little John on Mon Dec 16, 2019 8:29 pm, edited 7 times in total.
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

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

Post by IdeasVacuum »

Well, it works on my PC and quickly. Just seems like a lot of code for such a simple requirement..........
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
Kiffi
Addict
Addict
Posts: 1357
Joined: Tue Mar 02, 2004 1:20 pm
Location: Amphibios 9

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

Post by Kiffi »

@Little John: Thanks for sharing! Image

Greetings ... Kiffi
Hygge
Little John
Addict
Addict
Posts: 4527
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

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

Post by Little John »

Hi Kiffi,

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

Regards, Little John
Little John
Addict
Addict
Posts: 4527
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

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

Post by Little John »

One bug fix and some minor changes, for details see first post.
User avatar
blueb
Addict
Addict
Posts: 1044
Joined: Sat Apr 26, 2003 2:15 pm
Location: Cuernavaca, Mexico

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

Post 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
- It was too lonely at the top.

System : PB 6.10 LTS (x64) and Win Pro 11 (x64)
Hardware: AMD Ryzen 9 5900X w/64 gigs Ram, AMD RX 6950 XT Graphics w/16gigs Mem
juror
Enthusiast
Enthusiast
Posts: 228
Joined: Mon Jul 09, 2007 4:47 pm
Location: Courthouse

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

Post by juror »

Yes, the new version does appear to have problems -
"ret$ = _Base64ToStr(_ReadLine(dbFile$, 2))" produces invalid memory access.
Little John
Addict
Addict
Posts: 4527
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

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

Post 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.
juror
Enthusiast
Enthusiast
Posts: 228
Joined: Mon Jul 09, 2007 4:47 pm
Location: Courthouse

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

Post by juror »

It runs. Apparently fine. Since I do not have a dropbox, it correctly returns "not found".
Little John
Addict
Addict
Posts: 4527
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

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

Post by Little John »

Thanks, juror.
User avatar
blueb
Addict
Addict
Posts: 1044
Joined: Sat Apr 26, 2003 2:15 pm
Location: Cuernavaca, Mexico

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

Post by blueb »

Thanks for the quick fix Little John 8)
- It was too lonely at the top.

System : PB 6.10 LTS (x64) and Win Pro 11 (x64)
Hardware: AMD Ryzen 9 5900X w/64 gigs Ram, AMD RX 6950 XT Graphics w/16gigs Mem
Little John
Addict
Addict
Posts: 4527
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

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

Post by Little John »

I'm glad that it works now for you.
And many thanks for reporting the bug!
Little John
Addict
Addict
Posts: 4527
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

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

Post by Little John »

2017-03-06
  • Adaptations in procedure _Base64ToStr() for compatibility with PB 5.60+
  • Some minor tweaks
User avatar
minimy
Enthusiast
Enthusiast
Posts: 349
Joined: Mon Jul 08, 2013 8:43 pm

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

Post by minimy »

Thanks!
+1
If translation=Error: reply="Sorry, Im Spanish": Endif
User avatar
Dreamland Fantasy
Enthusiast
Enthusiast
Posts: 335
Joined: Fri Jun 11, 2004 9:35 pm
Location: Glasgow, UK
Contact:

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

Post by Dreamland Fantasy »

Nice, just what I was looking for! :)

Kind regards,

Francis
Post Reply