Dropbox Upload Actor avatar
Dropbox Upload Actor
Try for free

No credit card required

View all Actors
Dropbox Upload Actor

Dropbox Upload Actor

aaron/dropbox-upload-actor
Try for free

No credit card required

Streams file from URL to a dropbox account.

Dockerfile

1# This is a template for a Dockerfile used to run acts in Actor system.
2# The base image name below is set during the act build, based on user settings.
3# IMPORTANT: The base image must set a correct working directory, such as /usr/src/app or /home/user
4FROM apify/actor-node-basic:v0.21.10
5
6# Second, copy just package.json and package-lock.json since it should be
7# the only file that affects "npm install" in the next step, to speed up the build
8COPY package*.json ./
9
10# Install NPM packages, skip optional and development dependencies to
11# keep the image small. Avoid logging too much and print the dependency
12# tree for debugging
13RUN npm --quiet set progress=false \
14 && npm install --only=prod --no-optional \
15 && echo "Installed NPM packages:" \
16 && (npm list --all || true) \
17 && echo "Node.js version:" \
18 && node --version \
19 && echo "NPM version:" \
20 && npm --version
21
22# Copy source code to container
23# Do this in the last step, to have fast build if only the source code changed
24COPY  . ./
25
26# NOTE: The CMD is already defined by the base image.
27# Uncomment this for local node inspector debugging:
28# CMD [ "node", "--inspect=0.0.0.0:9229", "main.js" ]

package.json

1{
2    "name": "apify-project",
3    "version": "0.0.1",
4    "description": "",
5    "author": "It's not you it's me",
6    "license": "ISC",
7    "dependencies": {
8        "node-fetch": "latest",
9        "dropbox": "latest",
10        "apify": "0.21.10"
11    },
12    "scripts": {
13        "start": "node main.js"
14    }
15}

main.js

1const fetch = require('node-fetch');
2var Dropbox = require('dropbox').Dropbox;
3const Apify = require('apify');
4
5Apify.main(async () => {
6    const input = await Apify.getValue('INPUT');
7    const accessToken = input.accessToken;
8    const filePath = input.filePath ? input.filePath : '';
9    const fileUrl = input.fileUrl;
10
11    await uploadFile(fileUrl, filePath);
12
13    async function uploadFile(fileUrl, filePath){ 
14        if(typeof fileUrl !== 'string'){
15          throw new TypeError('Parameter is not type of string.');
16        }
17        
18        // Open Dropbox instance.
19        var dbx = await new Dropbox({
20            fetch: fetch,
21            accessToken: accessToken
22        });
23  
24        const UPLOAD_FILE_SIZE_LIMIT = 150 * 1024 * 1024; // 150Mb - Dropbox file size threshold 
25        const maxBlob = 8 * 1000 * 1000; // 8Mb - Dropbox JavaScript API suggested max file / chunk size
26  
27        const buffer = await getFileBuffer(fileUrl);
28        console.log(`File size: ${(buffer.byteLength/1000000).toFixed(2)}Mb`);
29  
30        // Determine whether you should use filesUpload or filesUploadSession.
31        if(buffer.byteLength < UPLOAD_FILE_SIZE_LIMIT){
32            // Upload for files less than 150Mb don't have to be chunked.
33            console.log('Uploading file.');
34            await dbx.filesUpload({ path: filePath, contents:buffer })
35                .then(res => console.log('File successfully uploaded.'))
36                .catch(err => console.log(err));
37        } else {
38            var chunks = [];
39            var offset = 0;
40    
41            while(offset < buffer.byteLength){
42                var chunkSize = Math.min(maxBlob, buffer.byteLength - offset);
43                chunks.push(buffer.slice(offset, offset + chunkSize ));
44                offset += chunkSize;
45            }
46    
47            var index = 0;
48
49            for(chunk of chunks){
50                var percentToFinishUpload;
51
52                if (index == 0){
53                    // Begin upload session.
54                    var {session_id} = await dbx.filesUploadSessionStart({ close: false, contents: chunk });
55                    console.log(`Opening session: ${session_id}`);
56                    index++;
57
58                    percentToFinishUpload = ((index * chunk.byteLength)/buffer.byteLength * 100).toFixed(2);
59                    console.log(`Upload percentage: ${percentToFinishUpload}%`);
60                } else if (index < chunks.length - 1){
61                    // Append chunk to upload session.
62                    let cursor = { session_id: session_id, offset: index * chunk.byteLength };
63                    await dbx.filesUploadSessionAppendV2({ cursor: cursor, close: false, contents: chunk});
64                    index++;
65
66                    percentToFinishUpload = Math.floor(((index * chunk.byteLength)/buffer.byteLength) * 100).toFixed(2);
67                    console.log(`Upload percentage: ${percentToFinishUpload}%`);
68                } else {
69                    // Append final chunk and close session.
70                    let cursor = { session_id: session_id, offset: buffer.byteLength - chunk.byteLength };
71                    let commit = { path: input.filePath, mode: 'add', autorename: true, mute: false};
72                    await dbx.filesUploadSessionFinish({ cursor: cursor, commit: commit, contents: chunk })
73                        .then(res => console.log('Success!'));
74
75                    percentToFinishUpload = Math.floor(((index * chunk.byteLength)/buffer.byteLength) * 100).toFixed(2);
76                    console.log('File upload complete.');
77                }
78            }
79        }
80    }
81  
82      async function getFileBuffer(fileUrl){
83        console.log(`Fetching file from: ${fileUrl}`);
84  
85        const blob = await fetch(fileUrl)
86          .then(response => response.blob())
87          .catch(err => console.log(err));
88  
89        console.log('File successfully retrieved.');
90        console.log('Creating buffer from file.');
91        const buf = Buffer.from(blob[Object.getOwnPropertySymbols(blob)[1]]);
92        
93        console.log('Returning buffer.');
94        return buf;
95      }
96});
Developer
Maintained by Community
Actor metrics
  • 1 monthly users
  • days response time
  • Created in Jan 2019
  • Modified almost 2 years ago
Categories