terabox-upload-tool 1.2.1 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -138
- package/lib/helpers/download/download.js +16 -33
- package/lib/helpers/download/downloadHelper.js +40 -120
- package/lib/helpers/fileDelete.js +32 -0
- package/lib/helpers/fileMove.js +33 -0
- package/lib/helpers/getShortUrl.js +30 -44
- package/lib/helpers/utils.js +9 -29
- package/lib/index.js +124 -80
- package/package.json +27 -27
- package/test_all.js +79 -0
- package/examples/dl-test.js +0 -118
- package/examples/example.js +0 -57
package/README.md
CHANGED
|
@@ -1,165 +1,75 @@
|
|
|
1
1
|
# Terabox Upload Tool
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
A robust Node.js library for seamless integration with TeraBox. Effortlessly upload, download, manage files and directories, and retrieve file lists.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
* Get direct file download link
|
|
12
|
-
|
|
13
|
-
## Coming Soon (Open for Collaboration)
|
|
14
|
-
|
|
15
|
-
* Fetch Files: Retrieve the resources download URL and add URL Path in JSON object returned by existing [fetchFileList() ](./lib/index.js)method . ✅
|
|
16
|
-
* Delete Files: Remove files from your Terabox storage directly using this library.
|
|
17
|
-
* Video Streaming: Support for streaming videos.
|
|
18
|
-
* Fetch Upload History
|
|
19
|
-
* Fetch Download History
|
|
20
|
-
* Restructure code and files
|
|
6
|
+
- **Automated Upload Flow**: Handles `precreate`, MD5 calculation, and finalization automatically.
|
|
7
|
+
- **File Management**: Create directories, move, rename, and delete files.
|
|
8
|
+
- **Downloads**: Generate direct download links (`dlink`).
|
|
9
|
+
- **Sharing**: Generate short URLs for file sharing.
|
|
10
|
+
- **Latest API Support**: Includes `jsToken`, `dp-logid`, and `appId` support to bypass modern restrictions.
|
|
21
11
|
|
|
22
12
|
## Installation
|
|
23
|
-
|
|
24
|
-
Install the package using npm:
|
|
25
|
-
|
|
26
13
|
```bash
|
|
27
14
|
npm install terabox-upload-tool
|
|
28
15
|
```
|
|
29
16
|
|
|
30
|
-
##
|
|
17
|
+
## Setup & Credentials
|
|
18
|
+
|
|
19
|
+
To use this library, you need to extract three key parameters from your browser while logged into TeraBox:
|
|
31
20
|
|
|
32
|
-
|
|
21
|
+
1. **ndus**: Found in your Browser Cookies (`Application` -> `Cookies` -> `https://www.terabox.com`).
|
|
22
|
+
2. **jsToken**: Found in the response or query parameters of API calls (e.g., `api/list` or `api/home/info`) in the `Network` tab.
|
|
23
|
+
3. **appId**: Usually `250528`, but verify by looking at the `app_id` parameter in any API request in the `Network` tab.
|
|
33
24
|
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
### Initialization
|
|
34
28
|
```javascript
|
|
35
29
|
const TeraboxUploader = require('terabox-upload-tool');
|
|
36
30
|
|
|
37
|
-
const
|
|
38
|
-
ndus:
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
31
|
+
const uploader = new TeraboxUploader({
|
|
32
|
+
ndus: "YOUR_NDUS",
|
|
33
|
+
jsToken: "YOUR_JS_TOKEN",
|
|
34
|
+
appId: "250528",
|
|
35
|
+
bdstoken: "OPTIONAL",
|
|
36
|
+
browserId: "OPTIONAL"
|
|
37
|
+
});
|
|
43
38
|
```
|
|
44
39
|
|
|
45
|
-
###
|
|
46
|
-
|
|
47
|
-
To upload a file, create an instance of TeraboxUploader and specify the file path.
|
|
48
|
-
|
|
49
|
-
#### Example: Save File to a Specific Directory
|
|
40
|
+
### API Methods
|
|
50
41
|
|
|
42
|
+
#### Upload File
|
|
51
43
|
```javascript
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
try {
|
|
56
|
-
const result = await uploader.uploadFile(filePath, showProgress, '/myUploads');
|
|
57
|
-
if (result.success) {
|
|
58
|
-
console.log('File uploaded successfully!');
|
|
59
|
-
console.log('File details:', result.fileDetails);
|
|
60
|
-
} else {
|
|
61
|
-
console.log('Upload failed:', result.message);
|
|
62
|
-
}
|
|
63
|
-
} catch (error) {
|
|
64
|
-
console.log('An error occurred during the upload:', error.message);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
44
|
+
const result = await uploader.uploadFile('./myfile.txt', (loaded, total) => {
|
|
45
|
+
console.log(`Progress: ${Math.round((loaded / total) * 100)}%`);
|
|
46
|
+
}, '/remote/dir');
|
|
68
47
|
```
|
|
69
48
|
|
|
70
|
-
####
|
|
71
|
-
|
|
49
|
+
#### Download File
|
|
72
50
|
```javascript
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const fileList=await uploader.fetchFileList('/myUploads');
|
|
76
|
-
console.log('Files in your directory:', fileList);
|
|
77
|
-
} catch (error) {
|
|
78
|
-
console.log('Error fetching file list:', error.message);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
51
|
+
const result = await uploader.downloadFile(fs_id);
|
|
52
|
+
console.log('Download Link:', result.downloadLink);
|
|
81
53
|
```
|
|
82
54
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
* Enable users to delete specific files or directories from their Terabox storage.
|
|
90
|
-
* Include safeguards like confirmation prompts before deletion.
|
|
91
|
-
2. Error Handling Enhancements:
|
|
92
|
-
|
|
93
|
-
* Improve error messages for easier debugging and user guidance.
|
|
94
|
-
3. Automated Tests:
|
|
95
|
-
|
|
96
|
-
* Add test cases to ensure reliability and robustness.
|
|
97
|
-
4. Documentation Updates:
|
|
98
|
-
|
|
99
|
-
* Expand guides with screenshots and example workflows.
|
|
100
|
-
|
|
101
|
-
## Contribution Guidelines
|
|
102
|
-
|
|
103
|
-
We welcome contributions from the community! Here’s how you can get started:
|
|
104
|
-
|
|
105
|
-
1. Fork the repository and create a new branch for your feature or bugfix.
|
|
106
|
-
2. Make your changes and ensure the code adheres to the project's style guide.
|
|
107
|
-
3. Submit a pull request detailing your changes and their purpose.
|
|
108
|
-
4. Feel free to open issues for feature requests or bug reports.
|
|
109
|
-
|
|
110
|
-
## Resources for Developers
|
|
111
|
-
|
|
112
|
-
* [Node.js File System Documentation](https://nodejs.org/api/fs.html)
|
|
113
|
-
* [Chrome Dev-Tools (Networks)](https://developer.chrome.com/docs/devtools/network)
|
|
114
|
-
|
|
115
|
-
<br>
|
|
116
|
-
|
|
117
|
-
Terabox Node.js Library
|
|
118
|
-
|
|
119
|
-
Upload Files to Terabox
|
|
120
|
-
|
|
121
|
-
Terabox API Integration
|
|
122
|
-
|
|
123
|
-
Terabox File Management
|
|
124
|
-
|
|
125
|
-
Node.js Terabox SDK
|
|
126
|
-
|
|
127
|
-
## Screenshots
|
|
128
|
-
|
|
129
|
-
For getting your credentials, go to the terabox, create an account and follow the steps:
|
|
130
|
-
|
|
131
|
-

|
|
132
|
-
Login you account and open the developer tools
|
|
133
|
-
<br>
|
|
134
|
-
<br>
|
|
135
|
-
<br>
|
|
136
|
-
|
|
137
|
-

|
|
138
|
-
Go to network tab
|
|
139
|
-
<br>
|
|
140
|
-
<br>
|
|
141
|
-
<br>
|
|
142
|
-
|
|
143
|
-

|
|
144
|
-
Upload an image from left of your screen
|
|
145
|
-
<br>
|
|
146
|
-
<br>
|
|
147
|
-
<br>
|
|
148
|
-
|
|
149
|
-

|
|
150
|
-
Look for 'appId' and 'uploadId' from following request
|
|
151
|
-
<br>
|
|
152
|
-
<br>
|
|
153
|
-
<br>
|
|
154
|
-
|
|
155
|
-

|
|
156
|
-
Get the 'ndus' from cookies in the header section
|
|
157
|
-
<br>
|
|
158
|
-
<br>
|
|
159
|
-
<br>
|
|
55
|
+
#### File List
|
|
56
|
+
```javascript
|
|
57
|
+
const result = await uploader.fetchFileList('/remote/dir');
|
|
58
|
+
console.log(result.data.list);
|
|
59
|
+
```
|
|
160
60
|
|
|
161
|
-
|
|
61
|
+
#### Directory Operations
|
|
62
|
+
```javascript
|
|
63
|
+
await uploader.createDirectory('/new_folder');
|
|
64
|
+
await uploader.moveFiles('/old/path.txt', '/new/dir', 'newname.txt');
|
|
65
|
+
await uploader.deleteFiles(['/file_to_delete.txt', '/folder_to_delete']);
|
|
66
|
+
```
|
|
162
67
|
|
|
163
|
-
|
|
68
|
+
#### Sharing
|
|
69
|
+
```javascript
|
|
70
|
+
const result = await uploader.generateShortUrl('/path/file.txt', fs_id);
|
|
71
|
+
console.log('Short URL:', result.shortUrl);
|
|
72
|
+
```
|
|
164
73
|
|
|
165
|
-
|
|
74
|
+
## License
|
|
75
|
+
MIT
|
|
@@ -1,41 +1,24 @@
|
|
|
1
1
|
const { generateSign, fetchHomeInfo, generateDownload } = require('./downloadHelper');
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
async function getDownloadLink(ndus, fid) {
|
|
10
|
-
try {
|
|
11
|
-
// Fetch home information to retrieve necessary parameters for signing
|
|
12
|
-
const homeInfo = await fetchHomeInfo(ndus);
|
|
13
|
-
|
|
14
|
-
if (!homeInfo || !homeInfo.data.sign3 || !homeInfo.data.sign1 || !homeInfo.data.timestamp) {
|
|
15
|
-
return { success: false, message: "Invalid home information received." };
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const sign1 = homeInfo.data.sign3;
|
|
19
|
-
const sign2 = homeInfo.data.sign1;
|
|
20
|
-
const timestamp = homeInfo.data.timestamp;
|
|
21
|
-
|
|
22
|
-
// Generate the required sign using sign1 and sign2
|
|
23
|
-
const sign = generateSign(sign1, sign2);
|
|
24
|
-
if (!sign) {
|
|
25
|
-
return { success: false, message: "Failed to generate sign." };
|
|
26
|
-
}
|
|
3
|
+
async function getDownloadLink(ndus, fid, appId, jsToken, dpLogId) {
|
|
4
|
+
try {
|
|
5
|
+
const homeInfo = await fetchHomeInfo(ndus);
|
|
6
|
+
if (!homeInfo || !homeInfo.data.sign3 || !homeInfo.data.sign1 || !homeInfo.data.timestamp) {
|
|
7
|
+
return { success: false, message: "Invalid home information received." };
|
|
8
|
+
}
|
|
27
9
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
if (!responseDownload || !responseDownload.downloadLink[0]?.dlink) {
|
|
31
|
-
return { success: false, message: "Failed to retrieve download link." };
|
|
32
|
-
}
|
|
10
|
+
const sign = generateSign(homeInfo.data.sign3, homeInfo.data.sign1);
|
|
11
|
+
if (!sign) return { success: false, message: "Failed to generate sign." };
|
|
33
12
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return { success: false, message: error.message || "Unknown error occurred while fetching download link." };
|
|
13
|
+
const res = await generateDownload(sign, fid, homeInfo.data.timestamp, ndus, appId, jsToken, dpLogId);
|
|
14
|
+
if (!res || !res.downloadLink[0]?.dlink) {
|
|
15
|
+
return { success: false, message: res.message || "Failed to retrieve download link." };
|
|
38
16
|
}
|
|
17
|
+
|
|
18
|
+
return { success: true, message: "Download link retrieved successfully.", downloadLink: res.downloadLink[0].dlink };
|
|
19
|
+
} catch (error) {
|
|
20
|
+
return { success: false, message: error.message || "Unknown error occurred." };
|
|
21
|
+
}
|
|
39
22
|
}
|
|
40
23
|
|
|
41
24
|
module.exports = getDownloadLink;
|
|
@@ -1,131 +1,51 @@
|
|
|
1
1
|
const axios = require('axios');
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* Generates a cryptographic sign using RC4-like encryption.
|
|
5
|
-
* @param {string} s1 - First input string (key).
|
|
6
|
-
* @param {string} s2 - Second input string (data).
|
|
7
|
-
* @returns {string} - Base64 encoded signed string.
|
|
8
|
-
*/
|
|
9
3
|
function generateSign(s1, s2) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
[p[i], p[j]] = [p[j], p[i]];
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
let i = 0;
|
|
31
|
-
j = 0;
|
|
32
|
-
for (let q = 0; q < s2.length; q++) {
|
|
33
|
-
i = (i + 1) % 256;
|
|
34
|
-
j = (j + p[i]) % 256;
|
|
35
|
-
[p[i], p[j]] = [p[j], p[i]];
|
|
36
|
-
const k = p[(p[i] + p[j]) % 256];
|
|
37
|
-
result.push(s2.charCodeAt(q) ^ k);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return Buffer.from(result).toString('base64');
|
|
41
|
-
} catch (error) {
|
|
42
|
-
console.error("Error generating sign:", error.message);
|
|
43
|
-
return null;
|
|
4
|
+
try {
|
|
5
|
+
const p = new Uint8Array(256), a = new Uint8Array(256), result = [];
|
|
6
|
+
for (let i = 0; i < 256; i++) {
|
|
7
|
+
a[i] = s1.charCodeAt(i % s1.length);
|
|
8
|
+
p[i] = i;
|
|
9
|
+
}
|
|
10
|
+
let j = 0;
|
|
11
|
+
for (let i = 0; i < 256; i++) {
|
|
12
|
+
j = (j + p[i] + a[i]) % 256;
|
|
13
|
+
[p[i], p[j]] = [p[j], p[i]];
|
|
14
|
+
}
|
|
15
|
+
let i = 0; j = 0;
|
|
16
|
+
for (let q = 0; q < s2.length; q++) {
|
|
17
|
+
i = (i + 1) % 256;
|
|
18
|
+
j = (j + p[i]) % 256;
|
|
19
|
+
[p[i], p[j]] = [p[j], p[i]];
|
|
20
|
+
result.push(s2.charCodeAt(q) ^ p[(p[i] + p[j]) % 256]);
|
|
44
21
|
}
|
|
22
|
+
return Buffer.from(result).toString('base64');
|
|
23
|
+
} catch (e) { return null; }
|
|
45
24
|
}
|
|
46
25
|
|
|
47
|
-
/**
|
|
48
|
-
* Fetches home information from Terabox API.
|
|
49
|
-
* @param {string} ndus - User authentication token.
|
|
50
|
-
* @returns {Promise<{success: boolean, message: string, data?: object}>} - The response data from the API.
|
|
51
|
-
*/
|
|
52
26
|
async function fetchHomeInfo(ndus) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const response = await axios.get(url, {
|
|
61
|
-
params: {
|
|
62
|
-
app_id: "250528",
|
|
63
|
-
web: "1",
|
|
64
|
-
channel: "dubox",
|
|
65
|
-
clienttype: "0",
|
|
66
|
-
},
|
|
67
|
-
headers: {
|
|
68
|
-
"User-Agent": "Mozilla/5.0",
|
|
69
|
-
"Accept": "application/json",
|
|
70
|
-
"Cookie": `ndus=${ndus}`,
|
|
71
|
-
},
|
|
72
|
-
});
|
|
73
|
-
return { success: true, message: "Home info retrieved successfully.", data: response.data.data };
|
|
74
|
-
} catch (error) {
|
|
75
|
-
console.error("Error fetching home info:", error.response?.data || error.message);
|
|
76
|
-
return { success: false, message: error.message || "Failed to fetch home info." };
|
|
77
|
-
}
|
|
27
|
+
try {
|
|
28
|
+
const res = await axios.get("https://www.1024terabox.com/api/home/info", {
|
|
29
|
+
params: { app_id: "250528", web: "1", channel: "dubox", clienttype: "0" },
|
|
30
|
+
headers: { "Cookie": `ndus=${ndus}` }
|
|
31
|
+
});
|
|
32
|
+
return { success: true, data: res.data.data };
|
|
33
|
+
} catch (e) { return { success: false, message: e.message }; }
|
|
78
34
|
}
|
|
79
35
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
return { success: false, message: "Missing required parameters for generating download link." };
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const response = await axios.get(url, {
|
|
97
|
-
params: {
|
|
98
|
-
app_id: "250528",
|
|
99
|
-
web: "1",
|
|
100
|
-
channel: "dubox",
|
|
101
|
-
clienttype: "0",
|
|
102
|
-
fidlist: `[${fid}]`,
|
|
103
|
-
type: "dlink",
|
|
104
|
-
vip: "2",
|
|
105
|
-
sign,
|
|
106
|
-
timestamp,
|
|
107
|
-
need_speed: "0",
|
|
108
|
-
},
|
|
109
|
-
headers: {
|
|
110
|
-
"User-Agent": "Mozilla/5.0",
|
|
111
|
-
"Accept": "application/json",
|
|
112
|
-
"Cookie": `ndus=${ndus}`,
|
|
113
|
-
},
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
if (!response.data.dlink) {
|
|
117
|
-
return { success: false, message: "No download link received." };
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
return { success: true, message: "Download link generated successfully.", downloadLink: response.data.dlink };
|
|
121
|
-
} catch (error) {
|
|
122
|
-
console.error("Error generating download link:", error.response?.data || error.message);
|
|
123
|
-
return { success: false, message: error.message || "Failed to generate download link." };
|
|
124
|
-
}
|
|
36
|
+
async function generateDownload(sign, fid, timestamp, ndus, appId, jsToken, dpLogId) {
|
|
37
|
+
try {
|
|
38
|
+
const res = await axios.get("https://www.1024terabox.com/api/download", {
|
|
39
|
+
params: {
|
|
40
|
+
app_id: appId || "250528", web: "1", channel: "dubox", clienttype: "0",
|
|
41
|
+
jsToken, "dp-logid": dpLogId, fidlist: `[${fid}]`, type: "dlink",
|
|
42
|
+
vip: "2", sign, timestamp, need_speed: "0"
|
|
43
|
+
},
|
|
44
|
+
headers: { "Cookie": `ndus=${ndus}` }
|
|
45
|
+
});
|
|
46
|
+
if (!res.data.dlink) return { success: false, message: res.data.errmsg };
|
|
47
|
+
return { success: true, downloadLink: res.data.dlink };
|
|
48
|
+
} catch (e) { return { success: false, message: e.message }; }
|
|
125
49
|
}
|
|
126
50
|
|
|
127
|
-
module.exports = {
|
|
128
|
-
generateSign,
|
|
129
|
-
fetchHomeInfo,
|
|
130
|
-
generateDownload,
|
|
131
|
-
};
|
|
51
|
+
module.exports = { generateSign, fetchHomeInfo, generateDownload };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
const axios = require("axios");
|
|
2
|
+
|
|
3
|
+
const deleteFile = async (filelist, config) => {
|
|
4
|
+
const { appId, jsToken, browserId, ndus, dpLogId } = config.credentials || config;
|
|
5
|
+
const url = "https://www.1024terabox.com/api/filemanager";
|
|
6
|
+
|
|
7
|
+
const params = {
|
|
8
|
+
opera: "delete",
|
|
9
|
+
app_id: appId,
|
|
10
|
+
jsToken: jsToken,
|
|
11
|
+
"dp-logid": dpLogId,
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const data = new URLSearchParams();
|
|
15
|
+
data.append("filelist", JSON.stringify(filelist));
|
|
16
|
+
|
|
17
|
+
const headers = {
|
|
18
|
+
"Cookie": `browserid=${browserId}; ndus=${ndus};`,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
const response = await axios.post(url, data.toString(), {
|
|
23
|
+
headers,
|
|
24
|
+
params,
|
|
25
|
+
});
|
|
26
|
+
return response.data;
|
|
27
|
+
} catch (error) {
|
|
28
|
+
throw error.response ? error.response.data : error.message;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
module.exports = { deleteFile };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const axios = require("axios");
|
|
2
|
+
|
|
3
|
+
const moveFile = async (filelist, config) => {
|
|
4
|
+
const { appId, jsToken, browserId, ndus, dpLogId } = config.credentials || config;
|
|
5
|
+
const url = "https://www.1024terabox.com/api/filemanager";
|
|
6
|
+
|
|
7
|
+
const params = {
|
|
8
|
+
opera: "move",
|
|
9
|
+
app_id: appId,
|
|
10
|
+
jsToken: jsToken,
|
|
11
|
+
"dp-logid": dpLogId,
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const data = new URLSearchParams();
|
|
15
|
+
data.append("filelist", JSON.stringify(filelist));
|
|
16
|
+
|
|
17
|
+
const headers = {
|
|
18
|
+
"Cookie": `browserid=${browserId}; ndus=${ndus};`,
|
|
19
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
const response = await axios.post(url, data.toString(), {
|
|
24
|
+
headers,
|
|
25
|
+
params,
|
|
26
|
+
});
|
|
27
|
+
return response.data;
|
|
28
|
+
} catch (error) {
|
|
29
|
+
throw error.response ? error.response.data : error.message;
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
module.exports = { moveFile };
|
|
@@ -1,52 +1,38 @@
|
|
|
1
1
|
const axios = require('axios');
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
* @param {string} fid - The file ID.
|
|
8
|
-
* @returns {Promise<object|null>} - A promise that resolves to the API response containing the short URL or null if an error occurs.
|
|
9
|
-
*/
|
|
10
|
-
const getShortUrl = async (ndus, path, fid) => {
|
|
11
|
-
try {
|
|
12
|
-
// API Endpoint
|
|
13
|
-
const url = 'https://www.1024terabox.com/share/pset';
|
|
14
|
-
const cookies = `ndus=${ndus}`;
|
|
3
|
+
const getShortUrl = async (ndus, path, fid, appId, jsToken, dpLogId) => {
|
|
4
|
+
try {
|
|
5
|
+
const url = `https://www.1024terabox.com/share/pset?app_id=${appId}&jsToken=${jsToken}&dp-logid=${dpLogId}`;
|
|
6
|
+
const cookies = `ndus=${ndus}`;
|
|
15
7
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
});
|
|
8
|
+
const formData = new URLSearchParams({
|
|
9
|
+
app_id: appId,
|
|
10
|
+
web: '1',
|
|
11
|
+
channel: 'dubox',
|
|
12
|
+
clienttype: '0',
|
|
13
|
+
app: 'universe',
|
|
14
|
+
schannel: '0',
|
|
15
|
+
channel_list: '[0]',
|
|
16
|
+
period: '0',
|
|
17
|
+
path_list: `["${path}"]`,
|
|
18
|
+
fid_list: `[${fid}]`,
|
|
19
|
+
pwd: '',
|
|
20
|
+
public: '1',
|
|
21
|
+
scene: ''
|
|
22
|
+
});
|
|
32
23
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
};
|
|
24
|
+
const headers = {
|
|
25
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
26
|
+
'Cookie': cookies,
|
|
27
|
+
'Referer': 'https://www.1024terabox.com/',
|
|
28
|
+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
|
|
29
|
+
};
|
|
40
30
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
} catch (error) {
|
|
47
|
-
console.error('Error generating short link:', error);
|
|
48
|
-
return null;
|
|
49
|
-
}
|
|
31
|
+
const response = await axios.post(url, formData.toString(), { headers });
|
|
32
|
+
return response.data;
|
|
33
|
+
} catch (error) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
50
36
|
};
|
|
51
37
|
|
|
52
38
|
module.exports = getShortUrl;
|
package/lib/helpers/utils.js
CHANGED
|
@@ -1,41 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
* @param {string} appId - The application ID (required)
|
|
6
|
-
* @returns {string} - The upload URL
|
|
7
|
-
*/
|
|
1
|
+
function buildPrecreateUrl(appId, jsToken, dpLogId) {
|
|
2
|
+
return `https://www.1024terabox.com/api/precreate?app_id=${appId}&web=1&channel=dubox&clienttype=0&jsToken=${jsToken}&dp-logid=${dpLogId}`;
|
|
3
|
+
}
|
|
4
|
+
|
|
8
5
|
function buildUploadUrl(fileName, uploadId, appId) {
|
|
9
6
|
return `https://c-jp.1024terabox.com/rest/2.0/pcs/superfile2?method=upload&app_id=${appId}&channel=dubox&clienttype=0&web=1&path=%2F${encodeURIComponent(fileName)}&uploadid=${uploadId}&uploadsign=0&partseq=0`;
|
|
10
7
|
}
|
|
11
8
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
* @returns {string} - The create URL
|
|
15
|
-
*/
|
|
16
|
-
function buildCreateUrl() {
|
|
17
|
-
return 'https://www.1024terabox.com/api/create';
|
|
9
|
+
function buildCreateUrl(appId, jsToken, dpLogId) {
|
|
10
|
+
return `https://www.1024terabox.com/api/create?app_id=${appId}&web=1&channel=dubox&clienttype=0&jsToken=${jsToken}&dp-logid=${dpLogId}`;
|
|
18
11
|
}
|
|
19
12
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
* @param {string} appId - The application ID
|
|
23
|
-
* @param {string} directory - The directory path to fetch the file list from
|
|
24
|
-
* @returns {string} - The file list URL
|
|
25
|
-
*/
|
|
26
|
-
function buildListUrl(appId, directory) {
|
|
27
|
-
return `https://www.1024terabox.com/api/list?app_id=${appId}&web=1&channel=dubox&clienttype=0&order=time&desc=1&dir=${encodeURIComponent(directory)}&num=100&page=1&showempty=0`;
|
|
13
|
+
function buildListUrl(appId, directory, jsToken, dpLogId) {
|
|
14
|
+
return `https://www.1024terabox.com/api/list?app_id=${appId}&web=1&channel=dubox&clienttype=0&jsToken=${jsToken}&dp-logid=${dpLogId}&order=time&desc=1&dir=${encodeURIComponent(directory)}&num=100&page=1&showempty=0`;
|
|
28
15
|
}
|
|
29
16
|
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Builds the downloadable link for videos.
|
|
33
|
-
* @param {string} appId - The application ID
|
|
34
|
-
* @param {string} videoPath - The directory path to fetch the file list from
|
|
35
|
-
* @returns {string} - The file list URL
|
|
36
|
-
*/
|
|
37
17
|
function buildVideoDownloadUrl(appId, videoPath) {
|
|
38
18
|
return `https://www.1024terabox.com/api/streaming?path=${encodeURIComponent(videoPath)}&app_id=${appId}&clienttype=0&type=M3U8_FLV_264_480&vip=1`;
|
|
39
19
|
}
|
|
40
20
|
|
|
41
|
-
module.exports = { buildUploadUrl, buildCreateUrl, buildListUrl, buildVideoDownloadUrl };
|
|
21
|
+
module.exports = { buildPrecreateUrl, buildUploadUrl, buildCreateUrl, buildListUrl, buildVideoDownloadUrl };
|
package/lib/index.js
CHANGED
|
@@ -1,124 +1,168 @@
|
|
|
1
1
|
const axios = require('axios');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const fs = require('fs');
|
|
4
|
+
const crypto = require('crypto');
|
|
4
5
|
const FormData = require('form-data');
|
|
5
|
-
const {
|
|
6
|
-
|
|
6
|
+
const {
|
|
7
|
+
buildPrecreateUrl,
|
|
8
|
+
buildUploadUrl,
|
|
9
|
+
buildCreateUrl,
|
|
10
|
+
buildListUrl,
|
|
11
|
+
} = require('./helpers/utils');
|
|
12
|
+
const getDownloadLink = require('./helpers/download/download');
|
|
13
|
+
const { deleteFile } = require('./helpers/fileDelete');
|
|
14
|
+
const { moveFile } = require('./helpers/fileMove');
|
|
15
|
+
const getShortUrl = require('./helpers/getShortUrl');
|
|
7
16
|
|
|
8
|
-
/**
|
|
9
|
-
* Class to handle Terabox file operations
|
|
10
|
-
*/
|
|
11
17
|
class TeraboxUploader {
|
|
12
18
|
constructor(credentials) {
|
|
13
|
-
if (!credentials || !credentials.ndus || !credentials.appId || !credentials.
|
|
14
|
-
throw new Error(
|
|
19
|
+
if (!credentials || !credentials.ndus || !credentials.appId || !credentials.jsToken) {
|
|
20
|
+
throw new Error('Credentials are required (ndus, appId, jsToken).');
|
|
15
21
|
}
|
|
16
22
|
|
|
17
23
|
this.credentials = {
|
|
18
24
|
ndus: credentials.ndus,
|
|
19
|
-
cookies: `
|
|
25
|
+
cookies: `lang=en; ndus=${credentials.ndus};`,
|
|
20
26
|
appId: credentials.appId,
|
|
21
|
-
|
|
27
|
+
jsToken: credentials.jsToken,
|
|
28
|
+
bdstoken: credentials.bdstoken || '',
|
|
29
|
+
browserId: credentials.browserId || '',
|
|
30
|
+
dpLogId: credentials.dpLogId || this._generateDpLogId(),
|
|
22
31
|
};
|
|
23
32
|
}
|
|
24
33
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
* @param {string} [directory='/'] - Optional directory where the file will be saved on Terabox
|
|
30
|
-
* @returns {Promise<{success: boolean, message: string, fileDetails?: object}>} - A promise that resolves to an object indicating the result of the upload:
|
|
31
|
-
* - `success` (boolean): `true` if the upload was successful, `false` otherwise.
|
|
32
|
-
* - `message` (string): A message with the upload status (success or error).
|
|
33
|
-
* - `fileDetails` (optional object): The details of the file uploaded, returned only if the upload was successful.
|
|
34
|
-
*/
|
|
34
|
+
_generateDpLogId() {
|
|
35
|
+
return crypto.randomBytes(10).toString('hex').toUpperCase();
|
|
36
|
+
}
|
|
37
|
+
|
|
35
38
|
async uploadFile(filePath, progressCallback, directory = '/') {
|
|
36
39
|
try {
|
|
37
40
|
const fileName = path.basename(filePath);
|
|
38
|
-
const
|
|
39
|
-
const
|
|
41
|
+
const stats = fs.statSync(filePath);
|
|
42
|
+
const fileSize = stats.size;
|
|
43
|
+
const fileMd5 = crypto.createHash('md5').update(fs.readFileSync(filePath)).digest('hex');
|
|
40
44
|
|
|
41
|
-
|
|
42
|
-
await axios.
|
|
45
|
+
const precreateUrl = buildPrecreateUrl(this.credentials.appId, this.credentials.jsToken, this.credentials.dpLogId);
|
|
46
|
+
const precreateResponse = await axios.post(
|
|
47
|
+
precreateUrl,
|
|
48
|
+
new URLSearchParams({
|
|
49
|
+
path: `${directory}/${fileName}`,
|
|
50
|
+
autoinit: '1',
|
|
51
|
+
target_path: directory,
|
|
52
|
+
block_list: JSON.stringify([fileMd5]),
|
|
53
|
+
size: fileSize,
|
|
54
|
+
local_mtime: Math.floor(stats.mtimeMs / 1000),
|
|
55
|
+
}).toString(),
|
|
56
|
+
{ headers: { 'Content-Type': 'application/x-www-form-urlencoded', Cookie: this.credentials.cookies } }
|
|
57
|
+
);
|
|
43
58
|
|
|
44
|
-
|
|
59
|
+
if (precreateResponse.data.errno !== 0) {
|
|
60
|
+
throw new Error(`Precreate failed: ${precreateResponse.data.errmsg || 'Unknown error'}`);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const uploadId = precreateResponse.data.uploadid;
|
|
64
|
+
const uploadUrl = buildUploadUrl(fileName, uploadId, this.credentials.appId);
|
|
45
65
|
const formData = new FormData();
|
|
46
66
|
formData.append('file', fs.createReadStream(filePath));
|
|
47
67
|
|
|
48
|
-
|
|
49
|
-
headers: {
|
|
50
|
-
|
|
51
|
-
Origin: 'https://www.1024terabox.com',
|
|
52
|
-
Cookie: this.credentials.cookies,
|
|
53
|
-
},
|
|
54
|
-
onUploadProgress: (progressEvent) => {
|
|
55
|
-
if (progressCallback) {
|
|
56
|
-
progressCallback(progressEvent.loaded, progressEvent.total);
|
|
57
|
-
}
|
|
58
|
-
},
|
|
68
|
+
await axios.post(uploadUrl, formData, {
|
|
69
|
+
headers: { ...formData.getHeaders(), Cookie: this.credentials.cookies },
|
|
70
|
+
onUploadProgress: (e) => progressCallback && progressCallback(e.loaded, e.total),
|
|
59
71
|
});
|
|
60
72
|
|
|
61
|
-
|
|
62
|
-
const
|
|
63
|
-
const createResponse = await axios.post(createUrl, new URLSearchParams({
|
|
73
|
+
const createUrl = buildCreateUrl(this.credentials.appId, this.credentials.jsToken, this.credentials.dpLogId);
|
|
74
|
+
const createParams = new URLSearchParams({
|
|
64
75
|
path: `${directory}/${fileName}`,
|
|
65
76
|
size: fileSize,
|
|
66
|
-
uploadid:
|
|
77
|
+
uploadid: uploadId,
|
|
67
78
|
target_path: directory,
|
|
68
|
-
block_list: JSON.stringify([
|
|
79
|
+
block_list: JSON.stringify([fileMd5]),
|
|
80
|
+
local_mtime: Math.floor(stats.mtimeMs / 1000),
|
|
81
|
+
isdir: '0',
|
|
82
|
+
rtype: '1',
|
|
83
|
+
});
|
|
84
|
+
if (this.credentials.bdstoken) createParams.append('bdstoken', this.credentials.bdstoken);
|
|
85
|
+
|
|
86
|
+
const createResponse = await axios.post(createUrl, createParams.toString(), {
|
|
87
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded', Cookie: this.credentials.cookies },
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
return { success: true, message: 'File uploaded successfully.', fileDetails: createResponse.data };
|
|
91
|
+
} catch (error) {
|
|
92
|
+
return { success: false, message: error.response?.data || error.message };
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async createDirectory(directoryPath) {
|
|
97
|
+
try {
|
|
98
|
+
const createUrl = buildCreateUrl(this.credentials.appId, this.credentials.jsToken, this.credentials.dpLogId);
|
|
99
|
+
const createParams = new URLSearchParams({
|
|
100
|
+
path: directoryPath,
|
|
101
|
+
isdir: '1',
|
|
102
|
+
size: '0',
|
|
103
|
+
block_list: '[]',
|
|
69
104
|
local_mtime: Math.floor(Date.now() / 1000),
|
|
70
|
-
}).toString(), {
|
|
71
|
-
headers: {
|
|
72
|
-
'Content-Type': 'application/x-www-form-urlencoded',
|
|
73
|
-
Cookie: this.credentials.cookies,
|
|
74
|
-
},
|
|
75
105
|
});
|
|
106
|
+
if (this.credentials.bdstoken) createParams.append('bdstoken', this.credentials.bdstoken);
|
|
107
|
+
|
|
108
|
+
const response = await axios.post(createUrl, createParams.toString(), {
|
|
109
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded', Cookie: this.credentials.cookies },
|
|
110
|
+
});
|
|
111
|
+
return { success: true, message: 'Directory created successfully.', data: response.data };
|
|
112
|
+
} catch (error) {
|
|
113
|
+
return { success: false, message: error.response?.data || error.message };
|
|
114
|
+
}
|
|
115
|
+
}
|
|
76
116
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
};
|
|
117
|
+
async fetchFileList(directory = '/') {
|
|
118
|
+
try {
|
|
119
|
+
const listUrl = buildListUrl(this.credentials.appId, directory, this.credentials.jsToken, this.credentials.dpLogId);
|
|
120
|
+
const response = await axios.get(listUrl, { headers: { Cookie: this.credentials.cookies } });
|
|
121
|
+
return { success: true, message: 'File list retrieved successfully.', data: response.data };
|
|
83
122
|
} catch (error) {
|
|
84
|
-
|
|
123
|
+
return { success: false, message: error.response?.data?.error || error.message };
|
|
124
|
+
}
|
|
125
|
+
}
|
|
85
126
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
127
|
+
async downloadFile(fileId) {
|
|
128
|
+
try {
|
|
129
|
+
const { ndus, appId, jsToken, dpLogId } = this.credentials;
|
|
130
|
+
return await getDownloadLink(ndus, fileId, appId, jsToken, dpLogId);
|
|
131
|
+
} catch (error) {
|
|
132
|
+
return { success: false, message: error.response?.data?.error || error.message };
|
|
91
133
|
}
|
|
92
134
|
}
|
|
93
135
|
|
|
136
|
+
async deleteFiles(fileList) {
|
|
137
|
+
try {
|
|
138
|
+
const config = { ...this.credentials };
|
|
139
|
+
const result = await deleteFile(fileList, config);
|
|
140
|
+
return { success: true, message: 'Files deleted successfully.', result };
|
|
141
|
+
} catch (error) {
|
|
142
|
+
return { success: false, message: error.response?.data?.error || error.message };
|
|
143
|
+
}
|
|
144
|
+
}
|
|
94
145
|
|
|
95
|
-
|
|
96
|
-
* Fetches the file list from Terabox
|
|
97
|
-
* @param {string} directory - Directory to fetch the file list from (e.g., "/")
|
|
98
|
-
* @returns {Promise<object>} - JSON response with file details along with download link
|
|
99
|
-
*/
|
|
100
|
-
async fetchFileList(directory = '/') {
|
|
146
|
+
async moveFiles(sourcePath, destinationPath, newName) {
|
|
101
147
|
try {
|
|
102
|
-
const
|
|
148
|
+
const config = { ...this.credentials };
|
|
149
|
+
const fileList = [{ path: sourcePath, dest: destinationPath, newname: newName }];
|
|
150
|
+
return await moveFile(fileList, config);
|
|
151
|
+
} catch (error) {
|
|
152
|
+
throw error;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
103
155
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
for (const file of finalDataArray) {
|
|
111
|
-
const fid = file.fs_id;
|
|
112
|
-
file.downloadLink = await getDownloadLink(this.credentials.ndus, fid);
|
|
156
|
+
async generateShortUrl(filePath, fileId) {
|
|
157
|
+
try {
|
|
158
|
+
const { ndus, appId, jsToken, dpLogId } = this.credentials;
|
|
159
|
+
const res = await getShortUrl(ndus, filePath, fileId, appId, jsToken, dpLogId);
|
|
160
|
+
if (res && res.errno === 0) {
|
|
161
|
+
return { success: true, message: 'Short URL generated successfully.', shortUrl: res.shorturl };
|
|
113
162
|
}
|
|
114
|
-
|
|
115
|
-
return { success: true, message: 'File list retrieved successfully.', data: finalDataArray };
|
|
163
|
+
return { success: false, message: res?.errmsg || 'Failed to generate short URL.' };
|
|
116
164
|
} catch (error) {
|
|
117
|
-
|
|
118
|
-
return {
|
|
119
|
-
success: false,
|
|
120
|
-
message: error.response?.data?.error || error.message || 'Failed to fetch file list.',
|
|
121
|
-
};
|
|
165
|
+
return { success: false, message: error.message };
|
|
122
166
|
}
|
|
123
167
|
}
|
|
124
168
|
}
|
package/package.json
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "terabox-upload-tool",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "A
|
|
5
|
-
"repository": {
|
|
6
|
-
"type": "git",
|
|
7
|
-
"url": "git+https://github.com/Pahadi10/terabox-upload-tool"
|
|
8
|
-
},
|
|
9
|
-
"main": "lib/index.js",
|
|
10
|
-
"scripts": {
|
|
11
|
-
"test": "echo \"Error: no test specified\" && exit 1"
|
|
12
|
-
},
|
|
13
|
-
"keywords": [
|
|
14
|
-
"terabox",
|
|
15
|
-
"upload",
|
|
16
|
-
"file",
|
|
17
|
-
"storage",
|
|
18
|
-
"node"
|
|
19
|
-
],
|
|
20
|
-
"homepage": "https://github.com/Pahadi10/terabox-upload-tool#readme",
|
|
21
|
-
"author": "Nitesh Singh Bhandari",
|
|
22
|
-
"license": "MIT",
|
|
23
|
-
"dependencies": {
|
|
24
|
-
"axios": "^1.7.9",
|
|
25
|
-
"form-data": "^4.0.1"
|
|
26
|
-
}
|
|
27
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "terabox-upload-tool",
|
|
3
|
+
"version": "1.4.1",
|
|
4
|
+
"description": "A robust library designed for seamless integration with TeraBox, the leading cloud storage service offering 1 TB of free space. Effortlessly upload files, download files, delete files, manage directories, and retrieve file lists. Ideal for developers seeking efficient cloud storage solutions within their Node.js projects.",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/Pahadi10/terabox-upload-tool"
|
|
8
|
+
},
|
|
9
|
+
"main": "lib/index.js",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"terabox",
|
|
15
|
+
"upload",
|
|
16
|
+
"file",
|
|
17
|
+
"storage",
|
|
18
|
+
"node"
|
|
19
|
+
],
|
|
20
|
+
"homepage": "https://github.com/Pahadi10/terabox-upload-tool#readme",
|
|
21
|
+
"author": "Nitesh Singh Bhandari",
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"axios": "^1.7.9",
|
|
25
|
+
"form-data": "^4.0.1"
|
|
26
|
+
}
|
|
27
|
+
}
|
package/test_all.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
const TeraboxUploader = require('./lib/index');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
if (fs.existsSync('.env')) {
|
|
6
|
+
const envFile = fs.readFileSync('.env', 'utf8');
|
|
7
|
+
envFile.split('\n').forEach(line => {
|
|
8
|
+
const [key, ...valueParts] = line.split('=');
|
|
9
|
+
if (key && valueParts.length > 0) {
|
|
10
|
+
const value = valueParts.join('=').trim();
|
|
11
|
+
process.env[key.trim()] = value;
|
|
12
|
+
if (value.includes('ndus=')) {
|
|
13
|
+
const match = value.match(/ndus=([^;]+)/);
|
|
14
|
+
if (match && match[1]) process.env.ndus = match[1];
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const credentials = {
|
|
21
|
+
ndus: process.env.TERABOX_NDUS || process.env.ndus || 'YOUR_NDUS',
|
|
22
|
+
appId: process.env.TERABOX_APPID || process.env.appId || '250528',
|
|
23
|
+
jsToken: process.env.TERABOX_JSTOKEN || process.env.jsToken || 'YOUR_JS_TOKEN',
|
|
24
|
+
bdstoken: process.env.TERABOX_BDSTOKEN || process.env.bdstoken || '',
|
|
25
|
+
browserId: process.env.TERABOX_BROWSERID || process.env.browserId || ''
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
async function runTest() {
|
|
29
|
+
if (credentials.ndus === 'YOUR_NDUS' || credentials.jsToken === 'YOUR_JS_TOKEN') {
|
|
30
|
+
console.log('Skipping real API tests: Credentials not provided.');
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const uploader = new TeraboxUploader(credentials);
|
|
35
|
+
const testFileName = 'test_file.txt';
|
|
36
|
+
const testFilePath = path.join(__dirname, testFileName);
|
|
37
|
+
const testDirPath = '/test_dir_' + Date.now();
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
fs.writeFileSync(testFilePath, 'Hello Terabox! This is a test file.');
|
|
41
|
+
|
|
42
|
+
console.log('--- Testing createDirectory ---');
|
|
43
|
+
const createDirRes = await uploader.createDirectory(testDirPath);
|
|
44
|
+
console.log('Result:', createDirRes.success ? 'Success' : 'Failed');
|
|
45
|
+
|
|
46
|
+
console.log('--- Testing uploadFile ---');
|
|
47
|
+
const uploadRes = await uploader.uploadFile(testFilePath, null, testDirPath);
|
|
48
|
+
console.log('Result:', uploadRes.success ? 'Success' : 'Failed');
|
|
49
|
+
|
|
50
|
+
if (uploadRes.success) {
|
|
51
|
+
const fsId = uploadRes.fileDetails.fs_id;
|
|
52
|
+
const remotePath = uploadRes.fileDetails.path || `${testDirPath}/${testFileName}`;
|
|
53
|
+
|
|
54
|
+
console.log('--- Testing fetchFileList ---');
|
|
55
|
+
const listRes = await uploader.fetchFileList(testDirPath);
|
|
56
|
+
console.log('Result:', listRes.success ? 'Success' : 'Failed');
|
|
57
|
+
|
|
58
|
+
console.log('--- Testing downloadFile ---');
|
|
59
|
+
const downloadRes = await uploader.downloadFile(fsId);
|
|
60
|
+
console.log('Result:', downloadRes.success ? 'Success' : 'Failed');
|
|
61
|
+
|
|
62
|
+
console.log('--- Testing generateShortUrl ---');
|
|
63
|
+
const shortUrlRes = await uploader.generateShortUrl(remotePath, fsId);
|
|
64
|
+
console.log('Result:', shortUrlRes.success ? 'Success' : 'Failed');
|
|
65
|
+
|
|
66
|
+
console.log('--- Testing moveFiles ---');
|
|
67
|
+
const moveRes = await uploader.moveFiles(remotePath, testDirPath, 'moved_test_file.txt');
|
|
68
|
+
console.log('Result:', moveRes.errno === 0 ? 'Success' : 'Failed');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
console.log('--- Final Cleanup skipped. Files remain in:', testDirPath);
|
|
72
|
+
} catch (error) {
|
|
73
|
+
console.error('Test failed:', error.message);
|
|
74
|
+
} finally {
|
|
75
|
+
if (fs.existsSync(testFilePath)) fs.unlinkSync(testFilePath);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
runTest();
|
package/examples/dl-test.js
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
// syscfg APIへのリクエスト
|
|
2
|
-
async function getSysCfg() {
|
|
3
|
-
const url = 'https://www.terabox.com/api/getsyscfg';
|
|
4
|
-
const params = {
|
|
5
|
-
app_id: '250528',
|
|
6
|
-
web: '1',
|
|
7
|
-
channel: 'dubox',
|
|
8
|
-
clienttype: '0',
|
|
9
|
-
jsToken: 'BDFC7E99221F980D72CA17B19C98F23E35D1C43EBD1B76F2CE493F27A1C2E7C71D7F637156999EF9A71106D82A4836DE040DA96397B95B7F95DDE4836EA0766B',
|
|
10
|
-
'dp-logid': '18397400250736220038',
|
|
11
|
-
cfg_category_keys: '[{"cfg_category_key":"web_download_to_pc_exp_flow_new","cfg_version":1},{"cfg_category_key":"web_download_to_pc","cfg_version":1}]',
|
|
12
|
-
version: '0',
|
|
13
|
-
language_type: 'ja'
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
const response = await fetch(`${url}?${new URLSearchParams(params)}`, {
|
|
17
|
-
method: 'GET',
|
|
18
|
-
headers: {
|
|
19
|
-
'Content-Type': 'application/json'
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
const data = await response.json();
|
|
24
|
-
return data;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// home info APIへのリクエスト
|
|
28
|
-
async function getHomeInfo() {
|
|
29
|
-
const url = 'https://www.terabox.com/api/home/info';
|
|
30
|
-
const params = {
|
|
31
|
-
app_id: '250528',
|
|
32
|
-
web: '1',
|
|
33
|
-
channel: 'dubox',
|
|
34
|
-
clienttype: '0',
|
|
35
|
-
jsToken: 'BDFC7E99221F980D72CA17B19C98F23E35D1C43EBD1B76F2CE493F27A1C2E7C71D7F637156999EF9A71106D82A4836DE040DA96397B95B7F95DDE4836EA0766B',
|
|
36
|
-
'dp-logid': '18397400250736220039'
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
const response = await fetch(`${url}?${new URLSearchParams(params)}`, {
|
|
40
|
-
method: 'GET',
|
|
41
|
-
headers: {
|
|
42
|
-
'Content-Type': 'application/json'
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
const data = await response.json();
|
|
47
|
-
return data;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// ダウンロードURL取得のための関数
|
|
51
|
-
async function getDownloadUrl(fidlist) {
|
|
52
|
-
const sysCfg = await getSysCfg();
|
|
53
|
-
const homeInfo = await getHomeInfo();
|
|
54
|
-
|
|
55
|
-
console.log('System Configuration:', sysCfg);
|
|
56
|
-
console.log('Home Info:', homeInfo);
|
|
57
|
-
|
|
58
|
-
const downloadUrl = 'https://www.terabox.com/api/download';
|
|
59
|
-
|
|
60
|
-
// ダウンロードパラメータの設定
|
|
61
|
-
const params = {
|
|
62
|
-
app_id: '250528',
|
|
63
|
-
web: '1',
|
|
64
|
-
channel: 'dubox',
|
|
65
|
-
clienttype: '0',
|
|
66
|
-
jsToken: 'BDFC7E99221F980D72CA17B19C98F23E35D1C43EBD1B76F2CE493F27A1C2E7C71D7F637156999EF9A71106D82A4836DE040DA96397B95B7F95DDE4836EA0766B',
|
|
67
|
-
'dp-logid': '18397400250736220040',
|
|
68
|
-
fidlist: JSON.stringify(fidlist), // fidlistを渡す
|
|
69
|
-
type: 'dlink',
|
|
70
|
-
vip: '2',
|
|
71
|
-
sign: 'VeJPxoh1ryXIWRvdcBXzMXJvl9iJMry0sUyKk7FrD5ohO4wghBmZ7w==',
|
|
72
|
-
timestamp: '1737845700',
|
|
73
|
-
need_speed: '0',
|
|
74
|
-
bdstoken: 'bbc878665ecd53f583ce583d16deddd9'
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
// ダウンロードリクエスト送信
|
|
78
|
-
const response = await fetch(`${downloadUrl}?${new URLSearchParams(params)}`, {
|
|
79
|
-
method: 'GET',
|
|
80
|
-
headers: {
|
|
81
|
-
'Content-Type': 'application/json'
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
const data = await response.json();
|
|
86
|
-
|
|
87
|
-
// ダウンロードリンクが存在する場合、リンクを返す
|
|
88
|
-
if (data.dlink && data.dlink.length > 0) {
|
|
89
|
-
return data.dlink[0].dlink;
|
|
90
|
-
} else {
|
|
91
|
-
throw new Error('Download link not found.');
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// `dlFiles` 関数: ダウンロードリンクを返す
|
|
96
|
-
async function dlFiles(fidlist) {
|
|
97
|
-
try {
|
|
98
|
-
const downloadLink = await getDownloadUrl(fidlist);
|
|
99
|
-
return downloadLink;
|
|
100
|
-
} catch (error) {
|
|
101
|
-
console.error('Error:', error);
|
|
102
|
-
throw error; // エラーがあった場合は再度投げる
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// 使用例
|
|
107
|
-
(async () => {
|
|
108
|
-
try {
|
|
109
|
-
const fidlist = [546136331131393]; // ダウンロード対象のファイルIDリスト
|
|
110
|
-
const downloadLink = await dlFiles(fidlist);
|
|
111
|
-
console.log('Download Link:', downloadLink);
|
|
112
|
-
|
|
113
|
-
// ダウンロードリンクが取得できたら、URLを返す
|
|
114
|
-
return downloadLink;
|
|
115
|
-
} catch (error) {
|
|
116
|
-
console.error('Error:', error);
|
|
117
|
-
}
|
|
118
|
-
})();
|
package/examples/example.js
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
// Import the TeraboxUploader class from your library
|
|
2
|
-
const TeraboxUploader = require('./index'); // Make sure to use the correct path to your module
|
|
3
|
-
|
|
4
|
-
// Step 1: Set up your Terabox credentials
|
|
5
|
-
const credentials = {
|
|
6
|
-
ndus: 'your-ndus-token', // Replace with your actual ndus token
|
|
7
|
-
appId: 'your-app-id', // Replace with your actual appId
|
|
8
|
-
uploadId: 'your-upload-id', // Replace with your actual uploadId
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
// Step 2: Create a new instance of the TeraboxUploader with your credentials
|
|
12
|
-
const uploader = new TeraboxUploader(credentials);
|
|
13
|
-
|
|
14
|
-
// Step 3: Define the file you want to upload (replace with the path to your file)
|
|
15
|
-
const filePath = './path/to/your/file.txt'; // Example: './myDocuments/photo.jpg'
|
|
16
|
-
|
|
17
|
-
// Step 4: (Optional) Track upload progress with a simple callback function
|
|
18
|
-
// This will show how much of the file has been uploaded
|
|
19
|
-
const showProgress = (loaded, total) => {
|
|
20
|
-
const percentage = ((loaded / total) * 100).toFixed(2);
|
|
21
|
-
console.log(`Uploading... ${percentage}% complete`);
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
// Step 5: Upload the file
|
|
25
|
-
async function uploadFile() {
|
|
26
|
-
try {
|
|
27
|
-
// Upload the file to Terabox, specify a directory (optional)
|
|
28
|
-
const result = await uploader.uploadFile(filePath, showProgress, '/myUploads'); // Change '/myUploads' to your desired directory
|
|
29
|
-
|
|
30
|
-
// Check if the upload was successful
|
|
31
|
-
if (result.success) {
|
|
32
|
-
console.log('File uploaded successfully!');
|
|
33
|
-
console.log('File details:', result.fileDetails); // Show details of the uploaded file
|
|
34
|
-
} else {
|
|
35
|
-
console.log('Upload failed:', result.message); // Show error message
|
|
36
|
-
}
|
|
37
|
-
} catch (error) {
|
|
38
|
-
console.log('An error occurred during the upload:', error.message); // Handle any errors
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Step 6: Fetch a list of files from Terabox (optional)
|
|
43
|
-
async function fetchFileList() {
|
|
44
|
-
try {
|
|
45
|
-
// Get a list of files from your Terabox account
|
|
46
|
-
const fileList = await uploader.fetchFileList('/myUploads'); // Specify the directory to list files
|
|
47
|
-
console.log('Files in your directory:', fileList); // Show the list of files
|
|
48
|
-
} catch (error) {
|
|
49
|
-
console.log('Error fetching file list:', error.message); // Handle any errors
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// Step 7: Call the functions to upload the file and/or fetch the file list
|
|
54
|
-
|
|
55
|
-
// uploadFile(); // Upload the file
|
|
56
|
-
|
|
57
|
-
fetchFileList(); //Fetch files
|