Skip to content

Instantly share code, notes, and snippets.

@tangb
Created June 17, 2022 13:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tangb/f749af0f95a1db03cc1c0abf5a8ed03d to your computer and use it in GitHub Desktop.
Save tangb/f749af0f95a1db03cc1c0abf5a8ed03d to your computer and use it in GitHub Desktop.
My dropbox backend service (nestjs)
import { Dropbox, DropboxResponse, files as DropboxFiles, sharing } from 'dropbox';
import { IFilesProvider, ProviderFileLink, FILE_MIME_DIRECTORY, ProviderFileUpload } from './files-providers.types';
import mime from 'mime-types';
import { AppLoggerService } from '../logger/app-logger.service';
import 'isomorphic-fetch'; // fetch stuff for Dropbox
import { DropboxFile } from './dropbox-file.entity';
import { Readable } from 'stream';
import * as path from 'path';
// eslint-disable-next-line @typescript-eslint/no-var-requires
const DropboxStream = require('dropbox-stream');
interface IFilesListFolderResult {
files: DropboxFile[];
cursor: string;
more: boolean;
}
export enum DROPBOX_CREATE_SHARED_LINK_ERRORS {
UNKNOWN = 0,
LINK_ALREADY_EXISTS,
ACCESS_DENIED,
EMAIL_NOT_VERIFIED,
SETTINGS_ERROR,
FILE_NOT_FOUND,
}
export enum DROPBOX_GET_SHARED_LINK_ERRORS {
UNKNOWN = 10,
CURSOR_RESET,
INVALID_FILE_PATH,
OTHER,
INVALID_TYPE,
NOT_FOUND,
TOO_MANY,
}
export enum DROPBOX_FILES_LIST_FOLDER_ERRORS {
UNKNOWN = 20,
CURSOR_RESET,
INVALID_FILE_PATH,
OTHER,
}
export enum DROPBOX_REVOKE_SHARED_LINK {
OK = 30,
UNKNOWN,
OTHER,
ACCESS_DENIED,
MALFORMED_URL,
NOT_FOUND,
UNSUPPORTED,
}
export enum DROPBOX_FILES_GET_METADATA {
UNKNOWN = 50,
NOT_FOUND,
ACCESS_DENIED,
INVALID,
CANT_ACCESS,
}
export class DropboxProvider extends IFilesProvider {
/**
* API documentation https://www.dropbox.com/developers/documentation/http/documentation
*/
private dbx: Dropbox;
constructor(
public logger: AppLoggerService,
private readonly token: string,
private readonly baseDir: string,
private readonly linkVisibility: 'public' | 'team_only' | 'password',
) {
super();
this.logger.debug(`Init Dropbox API with token "${token}"`);
this.dbx = new Dropbox({
accessToken: token,
fetch,
});
}
public async getFiles(processBatch: (files: DropboxFile[], batchNumber: number) => Promise<void>): Promise<void> {
try {
// let output: DropboxFile[] = [];
let filesCount = 0;
let batchNumber = 1;
// first batch
this.logger.debug('First batch');
let result = await this.filesListFolder();
this.logger.trace(` -> ${result.files.length} results`);
filesCount += result.files.length;
try {
await processBatch(result.files, batchNumber);
} catch (err) {
this.logger.error(' -> process batch failed: ', err);
}
this.logger.debug(` -> ${filesCount} files found`);
// more batch
while (result.more) {
batchNumber++;
this.logger.debug('Next batch');
result = await this.filesListFolderContinue(result.cursor);
this.logger.trace(` -> ${result.files.length} results`);
try {
await processBatch(result.files, batchNumber);
} catch (err) {
this.logger.error(' -> process batch failed: ', err);
}
filesCount += result.files.length;
this.logger.debug(` -> ${filesCount} files found`);
}
} catch (error) {
this.logger.error('Unable to get Dropbox files', { error });
throw error;
}
}
public async createFileLink(internalId: string): Promise<ProviderFileLink> {
const dropboxFilePath = await this.filesGetMetadata(internalId);
this.logger.debug('File metadata:', { dropboxFilePath });
this.logger.debug(`Create file link for file "${internalId}" with path "${dropboxFilePath}"`);
return this.createSharedLinkWithSettings(dropboxFilePath, internalId);
}
public async getFileLink(internalId: string): Promise<ProviderFileLink> {
const dropboxFilePath = await this.filesGetMetadata(internalId);
this.logger.debug('File metadata:', { dropboxFilePath });
this.logger.debug(`Get file link for file "${internalId}" with path "${dropboxFilePath}"`);
try {
const sharedLink = await this.listSharedLink(dropboxFilePath, internalId);
return sharedLink;
} catch(error) {
this.logger.warn('File seems not to have existing link', {internalId, error});
}
return
}
public deleteFileLink(link: ProviderFileLink): Promise<boolean> {
this.logger.info(`Delete file link from Dropbox for url: ${link.url}`);
return this.revokeSharedLink(link.url);
}
...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment