w-ftp 1.0.0
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/.editorconfig +9 -0
- package/.eslintignore +3 -0
- package/.eslintrc.js +54 -0
- package/.jsdoc +25 -0
- package/LICENSE +21 -0
- package/README.md +163 -0
- package/SECURITY.md +5 -0
- package/babel.config.js +14 -0
- package/docs/WFtp.mjs.html +665 -0
- package/docs/fonts/Montserrat/Montserrat-Bold.eot +0 -0
- package/docs/fonts/Montserrat/Montserrat-Bold.ttf +0 -0
- package/docs/fonts/Montserrat/Montserrat-Bold.woff +0 -0
- package/docs/fonts/Montserrat/Montserrat-Bold.woff2 +0 -0
- package/docs/fonts/Montserrat/Montserrat-Regular.eot +0 -0
- package/docs/fonts/Montserrat/Montserrat-Regular.ttf +0 -0
- package/docs/fonts/Montserrat/Montserrat-Regular.woff +0 -0
- package/docs/fonts/Montserrat/Montserrat-Regular.woff2 +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +978 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +1049 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 +0 -0
- package/docs/global.html +439 -0
- package/docs/index.html +81 -0
- package/docs/jsftp.js.html +925 -0
- package/docs/scripts/collapse.js +20 -0
- package/docs/scripts/linenumber.js +25 -0
- package/docs/scripts/nav.js +12 -0
- package/docs/scripts/polyfill.js +4 -0
- package/docs/scripts/prettify/Apache-License-2.0.txt +202 -0
- package/docs/scripts/prettify/lang-css.js +2 -0
- package/docs/scripts/prettify/prettify.js +28 -0
- package/docs/scripts/search.js +83 -0
- package/docs/styles/jsdoc.css +765 -0
- package/docs/styles/prettify.css +79 -0
- package/g-download.mjs +84 -0
- package/g-upload.mjs +65 -0
- package/package.json +30 -0
- package/src/WFtp.mjs +596 -0
- package/src/jsftp.js +856 -0
- package/test/all.test.mjs +10 -0
- package/toolg/addVersion.mjs +4 -0
- package/toolg/cleanFolder.mjs +4 -0
- package/toolg/gDistRollup.mjs +27 -0
- package/toolg/modifyReadme.mjs +4 -0
|
@@ -0,0 +1,665 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
|
|
5
|
+
<meta charset="utf-8">
|
|
6
|
+
<title>WFtp.mjs - Documentation</title>
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
<script src="scripts/prettify/prettify.js"></script>
|
|
10
|
+
<script src="scripts/prettify/lang-css.js"></script>
|
|
11
|
+
<!--[if lt IE 9]>
|
|
12
|
+
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
|
13
|
+
<![endif]-->
|
|
14
|
+
<link type="text/css" rel="stylesheet" href="styles/prettify.css">
|
|
15
|
+
<link type="text/css" rel="stylesheet" href="styles/jsdoc.css">
|
|
16
|
+
<script src="scripts/nav.js" defer></script>
|
|
17
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
18
|
+
</head>
|
|
19
|
+
<body>
|
|
20
|
+
|
|
21
|
+
<input type="checkbox" id="nav-trigger" class="nav-trigger" />
|
|
22
|
+
<label for="nav-trigger" class="navicon-button x">
|
|
23
|
+
<div class="navicon"></div>
|
|
24
|
+
</label>
|
|
25
|
+
|
|
26
|
+
<label for="nav-trigger" class="overlay"></label>
|
|
27
|
+
|
|
28
|
+
<nav >
|
|
29
|
+
|
|
30
|
+
<h2><a href="index.html">Home</a></h2><h3>Global</h3><ul><li><a href="global.html#WFtp">WFtp</a></li></ul>
|
|
31
|
+
</nav>
|
|
32
|
+
|
|
33
|
+
<div id="main">
|
|
34
|
+
|
|
35
|
+
<h1 class="page-title">WFtp.mjs</h1>
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
<section>
|
|
44
|
+
<article>
|
|
45
|
+
<pre class="prettyprint source linenums"><code>import path from 'path'
|
|
46
|
+
import fs from 'fs'
|
|
47
|
+
import get from 'lodash/get'
|
|
48
|
+
import size from 'lodash/size'
|
|
49
|
+
import filter from 'lodash/filter'
|
|
50
|
+
import find from 'lodash/find'
|
|
51
|
+
import map from 'lodash/map'
|
|
52
|
+
import genPm from 'wsemi/src/genPm.mjs'
|
|
53
|
+
import cint from 'wsemi/src/cint.mjs'
|
|
54
|
+
import cstr from 'wsemi/src/cstr.mjs'
|
|
55
|
+
import ispint from 'wsemi/src/ispint.mjs'
|
|
56
|
+
import isestr from 'wsemi/src/isestr.mjs'
|
|
57
|
+
import iseobj from 'wsemi/src/iseobj.mjs'
|
|
58
|
+
import isfun from 'wsemi/src/isfun.mjs'
|
|
59
|
+
import isnum from 'wsemi/src/isnum.mjs'
|
|
60
|
+
import strleft from 'wsemi/src/strleft.mjs'
|
|
61
|
+
import pmSeries from 'wsemi/src/pmSeries.mjs'
|
|
62
|
+
import getFileName from 'wsemi/src/getFileName.mjs'
|
|
63
|
+
import fsTreeFolder from 'wsemi/src/fsTreeFolder.mjs'
|
|
64
|
+
import fsIsFolder from 'wsemi/src/fsIsFolder.mjs'
|
|
65
|
+
import fsIsFile from 'wsemi/src/fsIsFile.mjs'
|
|
66
|
+
import fsCreateFolder from 'wsemi/src/fsCreateFolder.mjs'
|
|
67
|
+
// import Jsftp from 'jsftp'
|
|
68
|
+
import Jsftp from './jsftp.js'
|
|
69
|
+
console.log('Jsftp', Jsftp)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* 指定FTP伺服器資料夾內檔案並自動同步至本機,只能用於Windows作業系統
|
|
74
|
+
*
|
|
75
|
+
* @param {String} fp 輸入檔案路徑字串
|
|
76
|
+
* @param {Object} [opt={}] 輸入設定物件,預設{}
|
|
77
|
+
* @param {String} [opt.ver='4.8'] 輸入調用windows程序之Net Framework版本字串,可有'4.5'、'4.6'、'4.7.2'與'4.8',預設'4.8'
|
|
78
|
+
* @returns {Promise} 回傳Promise,resolve回傳成功訊息,reject回傳錯誤訊息
|
|
79
|
+
* @example
|
|
80
|
+
* import WFtp from './src/WFtp.mjs'
|
|
81
|
+
*
|
|
82
|
+
* async function test() {
|
|
83
|
+
*
|
|
84
|
+
* //fp
|
|
85
|
+
* let fp = './g.mseed'
|
|
86
|
+
*
|
|
87
|
+
* //WFtp
|
|
88
|
+
* let r = await WFtp(fp)
|
|
89
|
+
* console.log(r)
|
|
90
|
+
* // [
|
|
91
|
+
* // {
|
|
92
|
+
* // name: 'SE.RST01.00.HNE.D.2020-09-17T013552.000000.csv',
|
|
93
|
+
* // path: null,
|
|
94
|
+
* // data: { heads: [Object], records: [Array] }
|
|
95
|
+
* // },
|
|
96
|
+
* // {
|
|
97
|
+
* // name: 'SE.RST01.00.HNN.D.2020-09-17T013552.000000.csv',
|
|
98
|
+
* // path: null,
|
|
99
|
+
* // data: { heads: [Object], records: [Array] }
|
|
100
|
+
* // },
|
|
101
|
+
* // {
|
|
102
|
+
* // name: 'SE.RST01.00.HNZ.D.2020-09-17T013552.000000.csv',
|
|
103
|
+
* // path: null,
|
|
104
|
+
* // data: { heads: [Object], records: [Array] }
|
|
105
|
+
* // }
|
|
106
|
+
* // ]
|
|
107
|
+
*
|
|
108
|
+
* }
|
|
109
|
+
* test()
|
|
110
|
+
* .catch((err) => {
|
|
111
|
+
* console.log('catch', err)
|
|
112
|
+
* })
|
|
113
|
+
*
|
|
114
|
+
*/
|
|
115
|
+
function WFtp() {
|
|
116
|
+
|
|
117
|
+
function WFtpCore() {
|
|
118
|
+
let Ftp = null
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
async function ftpConn(opt = {}) {
|
|
122
|
+
|
|
123
|
+
//pm
|
|
124
|
+
let pm = genPm()
|
|
125
|
+
|
|
126
|
+
//hostname
|
|
127
|
+
let hostname = get(opt, 'hostname')
|
|
128
|
+
if (!isestr(hostname)) {
|
|
129
|
+
pm.reject(`hostname[${hostname}] is not a effective string`)
|
|
130
|
+
return pm
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
//port
|
|
134
|
+
let port = get(opt, 'port')
|
|
135
|
+
if (!ispint(port)) {
|
|
136
|
+
pm.reject(`port[${port}] is not a positive integer`)
|
|
137
|
+
return pm
|
|
138
|
+
}
|
|
139
|
+
port = cint(port)
|
|
140
|
+
|
|
141
|
+
//username
|
|
142
|
+
let username = get(opt, 'username')
|
|
143
|
+
if (!isestr(username)) {
|
|
144
|
+
pm.reject(`username[${username}] is not a effective string`)
|
|
145
|
+
return pm
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
//password
|
|
149
|
+
let password = get(opt, 'password')
|
|
150
|
+
if (!isestr(password)) {
|
|
151
|
+
pm.reject(`password[${password}] is not a effective string`)
|
|
152
|
+
return pm
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
try {
|
|
156
|
+
Ftp = new Jsftp({
|
|
157
|
+
host: hostname,
|
|
158
|
+
port, // defaults to 21
|
|
159
|
+
user: username, // defaults to "anonymous"
|
|
160
|
+
pass: password, // defaults to "@anonymous"
|
|
161
|
+
})
|
|
162
|
+
pm.resolve('ok')
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
pm.reject(err)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return pm
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
async function ftpLs(remoteFd = '.') {
|
|
173
|
+
|
|
174
|
+
//pm
|
|
175
|
+
let pm = genPm()
|
|
176
|
+
|
|
177
|
+
//check
|
|
178
|
+
if (Ftp === null) {
|
|
179
|
+
pm.reject(`FTP has not been initialized. please use 'conn' to construct FTP`)
|
|
180
|
+
return pm
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
Ftp.ls(remoteFd, (err, res) => {
|
|
184
|
+
if (err) {
|
|
185
|
+
pm.reject(err)
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
pm.resolve(res)
|
|
189
|
+
}
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
return pm
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
async function ftpQuit() {
|
|
197
|
+
|
|
198
|
+
//pm
|
|
199
|
+
let pm = genPm()
|
|
200
|
+
|
|
201
|
+
//check
|
|
202
|
+
if (Ftp === null) {
|
|
203
|
+
pm.reject(`FTP has not been initialized. please use 'conn' to construct FTP`)
|
|
204
|
+
return pm
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
Ftp.raw('quit', (err, res) => {
|
|
208
|
+
if (err) {
|
|
209
|
+
pm.reject(err)
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
pm.resolve(res)
|
|
213
|
+
}
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
return pm
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
async function ftpStateFile(fpRemote) {
|
|
221
|
+
|
|
222
|
+
//ftpLs
|
|
223
|
+
let file = null
|
|
224
|
+
await ftpLs(fpRemote)
|
|
225
|
+
.then((res) => {
|
|
226
|
+
file = res
|
|
227
|
+
})
|
|
228
|
+
.catch(() => {
|
|
229
|
+
file = null
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
//get
|
|
233
|
+
file = get(file, 0, null)
|
|
234
|
+
// console.log('file', file)
|
|
235
|
+
|
|
236
|
+
return file
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
async function ftpCheckFile(fpRemote) {
|
|
241
|
+
|
|
242
|
+
//ftpStateFile
|
|
243
|
+
let file = await ftpStateFile(fpRemote)
|
|
244
|
+
|
|
245
|
+
//b
|
|
246
|
+
let b = iseobj(file)
|
|
247
|
+
|
|
248
|
+
return b
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
async function ftpDownload(fpRemote, fpLocal, cbProcess) {
|
|
253
|
+
|
|
254
|
+
//pm
|
|
255
|
+
let pm = genPm()
|
|
256
|
+
|
|
257
|
+
//check
|
|
258
|
+
if (Ftp === null) {
|
|
259
|
+
pm.reject(`FTP has not been initialized. please use 'conn' to construct FTP`)
|
|
260
|
+
return pm
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
//fpRemote
|
|
264
|
+
if (!isestr(fpRemote)) {
|
|
265
|
+
pm.reject(`fpRemote[${fpRemote}] is not a effective string`)
|
|
266
|
+
return pm
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
//fpLocal
|
|
270
|
+
if (!isestr(fpLocal)) {
|
|
271
|
+
pm.reject(`fpLocal[${fpLocal}] is not a effective string`)
|
|
272
|
+
return pm
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
//fdLocal
|
|
276
|
+
let fdLocal = path.basename(path.dirname(fpLocal))
|
|
277
|
+
|
|
278
|
+
//check fdLocal
|
|
279
|
+
if (!fsIsFolder(fdLocal)) {
|
|
280
|
+
fsCreateFolder(fdLocal)
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
//ftpStateFile
|
|
284
|
+
let file = await ftpStateFile(fpRemote)
|
|
285
|
+
// console.log('file', file)
|
|
286
|
+
|
|
287
|
+
//fileSize
|
|
288
|
+
let fileSize = get(file, 'size')
|
|
289
|
+
|
|
290
|
+
//check
|
|
291
|
+
if (!isnum(fileSize)) {
|
|
292
|
+
pm.reject(`can not get the size of file[${fpRemote}]`)
|
|
293
|
+
return pm
|
|
294
|
+
}
|
|
295
|
+
fileSize = cint(fileSize)
|
|
296
|
+
// console.log('fileSize', fileSize)
|
|
297
|
+
|
|
298
|
+
Ftp.get(fpRemote, (err, socket) => {
|
|
299
|
+
|
|
300
|
+
//check
|
|
301
|
+
if (err) {
|
|
302
|
+
pm.reject(err)
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
//check
|
|
306
|
+
if (fsIsFile(fpLocal)) {
|
|
307
|
+
fs.unlinkSync(fpLocal)
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
//createWriteStream
|
|
311
|
+
let writer = fs.createWriteStream(fpLocal)
|
|
312
|
+
|
|
313
|
+
//on data
|
|
314
|
+
let dss = 0
|
|
315
|
+
socket.on('data', (d) => {
|
|
316
|
+
// console.log('socket.on data', d)
|
|
317
|
+
|
|
318
|
+
//cbProcess
|
|
319
|
+
if (isfun(cbProcess)) {
|
|
320
|
+
let ds = size(d)
|
|
321
|
+
dss += ds
|
|
322
|
+
let r = dss / fileSize * 100
|
|
323
|
+
// console.log(`receving... ${dig((r), 1)}%`)
|
|
324
|
+
cbProcess({
|
|
325
|
+
progress: r,
|
|
326
|
+
name: getFileName(fpLocal),
|
|
327
|
+
fpRemote,
|
|
328
|
+
fpLocal,
|
|
329
|
+
})
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
//write
|
|
333
|
+
writer.write(d)
|
|
334
|
+
|
|
335
|
+
})
|
|
336
|
+
|
|
337
|
+
//on close
|
|
338
|
+
socket.on('close', (err) => {
|
|
339
|
+
if (err) {
|
|
340
|
+
pm.reject(err)
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
pm.resolve('ok')
|
|
344
|
+
}
|
|
345
|
+
})
|
|
346
|
+
|
|
347
|
+
//resume
|
|
348
|
+
socket.resume()
|
|
349
|
+
|
|
350
|
+
})
|
|
351
|
+
|
|
352
|
+
return pm
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
async function ftpUpload(fpLocal, fpRemote, cbProcess) {
|
|
357
|
+
|
|
358
|
+
//pm
|
|
359
|
+
let pm = genPm()
|
|
360
|
+
|
|
361
|
+
//check
|
|
362
|
+
if (Ftp === null) {
|
|
363
|
+
pm.reject(`FTP has not been initialized. please use 'conn' to construct FTP`)
|
|
364
|
+
return pm
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
//fpRemote
|
|
368
|
+
if (!isestr(fpRemote)) {
|
|
369
|
+
pm.reject(`fpRemote[${fpRemote}] is not a effective string`)
|
|
370
|
+
return pm
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
//fpLocal
|
|
374
|
+
if (!isestr(fpLocal)) {
|
|
375
|
+
pm.reject(`fpLocal[${fpLocal}] is not a effective string`)
|
|
376
|
+
return pm
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
//check
|
|
380
|
+
if (!fsIsFile(fpLocal)) {
|
|
381
|
+
pm.reject(`fpLocal[${fpLocal}] is not a file`)
|
|
382
|
+
return pm
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
//statSync
|
|
386
|
+
let stat = fs.statSync(fpLocal)
|
|
387
|
+
|
|
388
|
+
//fileSize
|
|
389
|
+
let fileSize = get(stat, 'size')
|
|
390
|
+
|
|
391
|
+
//check
|
|
392
|
+
if (!isnum(fileSize)) {
|
|
393
|
+
pm.reject(`can not get the size of file[${fpLocal}]`)
|
|
394
|
+
return pm
|
|
395
|
+
}
|
|
396
|
+
fileSize = cint(fileSize)
|
|
397
|
+
// console.log('fileSize', fileSize)
|
|
398
|
+
|
|
399
|
+
//bufferLocal
|
|
400
|
+
let bufferLocal = fs.readFileSync(fpLocal)
|
|
401
|
+
|
|
402
|
+
// //createReadStream
|
|
403
|
+
// let reader = fs.createReadStream(fpLocal)
|
|
404
|
+
|
|
405
|
+
let dss = 0
|
|
406
|
+
Ftp.put(bufferLocal, fpRemote, (err, buffer) => {
|
|
407
|
+
// console.log('Ftp.put', err, buffer)
|
|
408
|
+
|
|
409
|
+
//check
|
|
410
|
+
if (err) {
|
|
411
|
+
pm.reject(err)
|
|
412
|
+
return
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
//check
|
|
416
|
+
if (size(buffer) === 0) {
|
|
417
|
+
pm.resolve('ok')
|
|
418
|
+
return
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
//cbProcess
|
|
422
|
+
if (isfun(cbProcess)) {
|
|
423
|
+
let ds = size(buffer)
|
|
424
|
+
dss += ds
|
|
425
|
+
let r = dss / fileSize * 100
|
|
426
|
+
// console.log(`receving... ${dig((r), 1)}%`)
|
|
427
|
+
cbProcess({
|
|
428
|
+
progress: r,
|
|
429
|
+
name: getFileName(fpLocal),
|
|
430
|
+
fpRemote,
|
|
431
|
+
fpLocal,
|
|
432
|
+
})
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
})
|
|
436
|
+
|
|
437
|
+
return pm
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
async function ftpSyncToLocal(fdRemote, fdLocal, cbProcess) {
|
|
442
|
+
|
|
443
|
+
//check
|
|
444
|
+
if (Ftp === null) {
|
|
445
|
+
return Promise.reject(`FTP has not been initialized. please use 'conn' to construct FTP`)
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
//ftpLs
|
|
449
|
+
let fsRemote = await ftpLs(fdRemote)
|
|
450
|
+
// fsRemote = map(fsRemote, (v) => {
|
|
451
|
+
// let d = dayjs(v.time)
|
|
452
|
+
// v.stat = d.format('YYYY-MM-DDTHH:mm:ss')
|
|
453
|
+
// return v
|
|
454
|
+
// })
|
|
455
|
+
// console.log('fsRemote', fsRemote)
|
|
456
|
+
|
|
457
|
+
//check fdLocal
|
|
458
|
+
if (!fsIsFolder(fdLocal)) {
|
|
459
|
+
fsCreateFolder(fdLocal)
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
//fsTreeFolder
|
|
463
|
+
let fsLocal = fsTreeFolder(fdLocal)
|
|
464
|
+
fsLocal = filter(fsLocal, (v) => {
|
|
465
|
+
return !v.isFolder
|
|
466
|
+
})
|
|
467
|
+
fsLocal = map(fsLocal, (v) => {
|
|
468
|
+
let stat = fs.statSync(v.path)
|
|
469
|
+
v.size = cstr(get(stat, 'size', ''))
|
|
470
|
+
return v
|
|
471
|
+
})
|
|
472
|
+
// console.log('fsLocal', fsLocal)
|
|
473
|
+
|
|
474
|
+
//pmSeries
|
|
475
|
+
let n = 0
|
|
476
|
+
let ss = []
|
|
477
|
+
await pmSeries(fsRemote, async (fileRemote) => {
|
|
478
|
+
|
|
479
|
+
//fileLocal
|
|
480
|
+
let fileLocal = find(fsLocal, { name: fileRemote.name })
|
|
481
|
+
// console.log('fileLocal', fileLocal)
|
|
482
|
+
|
|
483
|
+
//fpRemote
|
|
484
|
+
// let fpRemote = path.resolve(fdRemote, v.name)
|
|
485
|
+
let fpRemote = fdRemote
|
|
486
|
+
if (!strleft(fpRemote, 1) !== '/') {
|
|
487
|
+
fpRemote += '/'
|
|
488
|
+
}
|
|
489
|
+
fpRemote += get(fileRemote, 'name', '')
|
|
490
|
+
// console.log('fpRemote', fpRemote)
|
|
491
|
+
|
|
492
|
+
//fpLocal
|
|
493
|
+
let fpLocal = path.resolve(fdLocal, get(fileRemote, 'name', ''))
|
|
494
|
+
// console.log('fpLocal', fpLocal)
|
|
495
|
+
|
|
496
|
+
//cb
|
|
497
|
+
let cb = (msg) => {
|
|
498
|
+
if (isfun(cbProcess)) {
|
|
499
|
+
cbProcess(msg)
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
//ftpDownload
|
|
504
|
+
if (!iseobj(fileLocal)) {
|
|
505
|
+
//本地檔案不存在
|
|
506
|
+
await ftpDownload(fpRemote, fpLocal, cb)
|
|
507
|
+
n++
|
|
508
|
+
ss.push({
|
|
509
|
+
name: fileRemote.name,
|
|
510
|
+
reason: 'no local file',
|
|
511
|
+
})
|
|
512
|
+
}
|
|
513
|
+
else if (fileRemote.size !== fileLocal.size) {
|
|
514
|
+
//本地檔案大小與遠端檔案大小不同
|
|
515
|
+
await ftpDownload(fpRemote, fpLocal, cb)
|
|
516
|
+
n++
|
|
517
|
+
ss.push({
|
|
518
|
+
name: fileRemote.name,
|
|
519
|
+
reason: `size[${fileLocal.size}] of local file != size[${fileRemote.size}] of remote file`,
|
|
520
|
+
})
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
})
|
|
524
|
+
|
|
525
|
+
return {
|
|
526
|
+
num: n,
|
|
527
|
+
files: ss,
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
|
|
532
|
+
async function ftpSyncToRemote(fdLocal, fdRemote, cbProcess) {
|
|
533
|
+
|
|
534
|
+
//check
|
|
535
|
+
if (Ftp === null) {
|
|
536
|
+
return Promise.reject(`FTP has not been initialized. please use 'conn' to construct FTP`)
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
//ftpLs
|
|
540
|
+
let fsRemote = await ftpLs(fdRemote)
|
|
541
|
+
// fsRemote = map(fsRemote, (v) => {
|
|
542
|
+
// let d = dayjs(v.time)
|
|
543
|
+
// v.stat = d.format('YYYY-MM-DDTHH:mm:ss')
|
|
544
|
+
// return v
|
|
545
|
+
// })
|
|
546
|
+
// console.log('fsRemote', fsRemote)
|
|
547
|
+
|
|
548
|
+
//check fdLocal
|
|
549
|
+
if (!fsIsFolder(fdLocal)) {
|
|
550
|
+
return Promise.reject(`fdLocal[${fdLocal}] is not a folder`)
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
//fsTreeFolder
|
|
554
|
+
let fsLocal = fsTreeFolder(fdLocal)
|
|
555
|
+
fsLocal = filter(fsLocal, (v) => {
|
|
556
|
+
return !v.isFolder
|
|
557
|
+
})
|
|
558
|
+
fsLocal = map(fsLocal, (v) => {
|
|
559
|
+
let stat = fs.statSync(v.path)
|
|
560
|
+
v.size = cstr(get(stat, 'size', ''))
|
|
561
|
+
return v
|
|
562
|
+
})
|
|
563
|
+
// console.log('fsLocal', fsLocal)
|
|
564
|
+
|
|
565
|
+
//pmSeries
|
|
566
|
+
let n = 0
|
|
567
|
+
let ss = []
|
|
568
|
+
await pmSeries(fsLocal, async (fileLocal) => {
|
|
569
|
+
|
|
570
|
+
//fileRemote
|
|
571
|
+
let fileRemote = find(fsRemote, { name: fileLocal.name })
|
|
572
|
+
// console.log('fileRemote', fileRemote)
|
|
573
|
+
|
|
574
|
+
//fpRemote
|
|
575
|
+
// let fpRemote = path.resolve(fdRemote, v.name)
|
|
576
|
+
let fpRemote = fdRemote
|
|
577
|
+
if (!strleft(fpRemote, 1) !== '/') {
|
|
578
|
+
fpRemote += '/'
|
|
579
|
+
}
|
|
580
|
+
fpRemote += get(fileLocal, 'name', '')
|
|
581
|
+
// console.log('fpRemote', fpRemote)
|
|
582
|
+
|
|
583
|
+
//fpLocal
|
|
584
|
+
let fpLocal = path.resolve(fdLocal, get(fileLocal, 'name', ''))
|
|
585
|
+
// console.log('fpLocal', fpLocal)
|
|
586
|
+
|
|
587
|
+
//cb
|
|
588
|
+
let cb = (msg) => {
|
|
589
|
+
if (isfun(cbProcess)) {
|
|
590
|
+
cbProcess(msg)
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
//ftpUpload
|
|
595
|
+
if (!iseobj(fileRemote)) {
|
|
596
|
+
//遠端檔案不存在
|
|
597
|
+
await ftpUpload(fpLocal, fpRemote, cb)
|
|
598
|
+
n++
|
|
599
|
+
ss.push({
|
|
600
|
+
name: fileLocal.name,
|
|
601
|
+
reason: 'no Remote file',
|
|
602
|
+
})
|
|
603
|
+
}
|
|
604
|
+
else if (fileLocal.size !== fileRemote.size) {
|
|
605
|
+
//遠端檔案大小與本機檔案大小不同
|
|
606
|
+
await ftpUpload(fpLocal, fpRemote, cb)
|
|
607
|
+
n++
|
|
608
|
+
ss.push({
|
|
609
|
+
name: fileLocal.name,
|
|
610
|
+
reason: `size[${fileRemote.size}] of remote file != size[${fileLocal.size}] of local file`,
|
|
611
|
+
})
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
})
|
|
615
|
+
|
|
616
|
+
return {
|
|
617
|
+
num: n,
|
|
618
|
+
files: ss,
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
|
|
623
|
+
return {
|
|
624
|
+
conn: ftpConn,
|
|
625
|
+
ls: ftpLs,
|
|
626
|
+
stateFile: ftpStateFile,
|
|
627
|
+
checkFile: ftpCheckFile,
|
|
628
|
+
download: ftpDownload,
|
|
629
|
+
syncToLocal: ftpSyncToLocal,
|
|
630
|
+
syncToRemote: ftpSyncToRemote,
|
|
631
|
+
upload: ftpUpload,
|
|
632
|
+
quit: ftpQuit,
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
return new WFtpCore()
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
|
|
640
|
+
export default WFtp
|
|
641
|
+
</code></pre>
|
|
642
|
+
</article>
|
|
643
|
+
</section>
|
|
644
|
+
|
|
645
|
+
|
|
646
|
+
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
|
|
650
|
+
</div>
|
|
651
|
+
|
|
652
|
+
<br class="clear">
|
|
653
|
+
|
|
654
|
+
<footer>
|
|
655
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.10</a> on Sat Jul 23 2022 13:03:06 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
656
|
+
</footer>
|
|
657
|
+
|
|
658
|
+
<script>prettyPrint();</script>
|
|
659
|
+
<script src="scripts/polyfill.js"></script>
|
|
660
|
+
<script src="scripts/linenumber.js"></script>
|
|
661
|
+
|
|
662
|
+
|
|
663
|
+
|
|
664
|
+
</body>
|
|
665
|
+
</html>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|