Precisei criar um pacote Go para ao Dropbox e fazer algumas operações básicas, listar arquivos, upload e download. Para isso usei o dropbox-sdk-go-unofficial.
Conectando Dropbox
Para conectar o dropbox, precisamos das credenciais de acesso. A forma mais fácil é criar um token, e para isso, entre em Dropbox developers apps e crie uma aplicação. Em seguida, dentro do painel da aplicação, crie o token.
Configurando o sistema
Todas as funções precisam das configurações com as credenciais de acesso e outros parâmetros úteis como, por exemplo, o nível de log. Então criamos uma função para retornar uma instancia da struct config.
func NewConfig(token string) (config dropbox.Config) { config = dropbox.Config{ Token: token, LogLevel: dropbox.LogOff, // logging level. Default is off } return }
Exemplo
config := NewConfig("token aqui")
Listando arquivos
Para facilitar as coisas, criamos uma struct que chamamos de Node. Um node pode ser um arquivo ou um diretório; é uma forma mais comum de visualizar sistemas de arquivos do que a originalmente usada pelo pacote.
// Node contains metadata to files and folders type Node struct { IsFolder bool Name string Size uint64 Rev string ServerModified time.Time }
Para listar o diretório raiz, não envie uma “/” – como seria comum – no lugar, envie uma string vazia.
func List(config dropbox.Config, path string) (nodes []Node, err error) { f := files.New(config) lfa := files.NewListFolderArg(path) lfr, err := f.ListFolder(lfa) if err != nil { return } for _, v := range lfr.Entries { var n Node switch fm := v.(type) { case *files.FileMetadata: n = parseFileMetadata(fm) case *files.FolderMetadata: n = parseFolderMetadata(fm) } nodes = append(nodes, n) } return }
Exemplo
Listando arquivos e diretórios
nodes, err := dropbox.List(config, "") if err != nil { log.Fatal(err) } for k, v := range nodes { fmt.Printf("%v %v\n", k, v.Name) }
Fazendo upload de arquivos
Para fazer upload é necessário indicar o caminho completo de destino, incluindo a raiz e o nome do arquivo.
A nossa função já controla a sessão de upload de maneira a lidar com as limitações de envio em uma única sessão da API do Dropbox e também tenta manter o consumo de memória baixo. Aqui nos meus testes o melhor resultado foi enviando os arquivos em partes de 1Mb, mas isso pode variar dependendo das condições de rede. O tamanho máximo das partes dos arquivos enviadas que a API permite de uma vez é 150Mb.
Exemplo
err := dropbox.Upload(config, "origem", "/destino") if err != nil { log.Fatal(err) }
Fazendo download de arquivos
Assim como a função Upload, também precisamos tomar cuidado com o consumo de RAM durante o download, mas não é necessário fazer controle de sessão, não temos as mesmas limitações, então podemos usar a função copy para copiar o stream de dados vindo da API para o arquivo de destino.
err := dropbox.Download(config, "/origem", "destino") if err != nil { log.Fatal(err) }
O código fonte com exemplos e testes está em github.com/crgimenes/dropbox.
O grupo de estudos de Go se reúne todas as quintas-feiras, às 22h00. Para participar, entre no canal de Go no Slack e procure por #brazil.