Procházet zdrojové kódy

readable wip commit

Ben Hsieh před 8 roky
rodič
revize
fabc08f1b3

+ 4
- 9
src/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java Zobrazit soubor

@@ -558,6 +558,7 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
558 558
                 DownloadManager dm = (DownloadManager) appCtx.getSystemService(Context.DOWNLOAD_SERVICE);
559 559
                 dm.query(query);
560 560
                 Cursor c = dm.query(query);
561
+                String error = null;
561 562
                 String filePath = null;
562 563
                 // the file exists in media content database
563 564
                 if (c.moveToFirst()) {
@@ -568,11 +569,6 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
568 569
                     if (cursor != null) {
569 570
                         cursor.moveToFirst();
570 571
                         filePath = cursor.getString(0);
571
-                        cursor.close();
572
-                        if(filePath != null) {
573
-                            this.callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_PATH, filePath);
574
-                            return;
575
-                        }
576 572
                     }
577 573
                 }
578 574
                 // When the file is not found in media content database, check if custom path exists
@@ -582,14 +578,13 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
582 578
                         boolean exists = new File(customDest).exists();
583 579
                         if(!exists)
584 580
                             throw new Exception("Download manager download failed, the file does not downloaded to destination.");
585
-                        callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_PATH, customDest);
586 581
 
587 582
                     } catch(Exception ex) {
588
-                        this.callback.invoke(ex.getLocalizedMessage(), null, null);
583
+                        error = ex.getLocalizedMessage();
589 584
                     }
590 585
                 }
591
-                else
592
-                    this.callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_PATH, filePath);
586
+                this.callback.invoke(error, RNFetchBlobConst.RNFB_RESPONSE_PATH, filePath);
587
+                c.close();
593 588
             }
594 589
         }
595 590
     }

+ 80
- 0
src/polyfill/Readable.js Zobrazit soubor

@@ -0,0 +1,80 @@
1
+// Copyright 2016 wkh237@github. All rights reserved.
2
+// Use of this source code is governed by a MIT-style license that can be
3
+// found in the LICENSE file.
4
+
5
+import RNFetchBlob from '../index.js'
6
+import fs from '../fs.js'
7
+import getUUID from '../utils/uuid'
8
+import Log from '../utils/log.js'
9
+import Stream from './Stream.js'
10
+import EventEmitter from 'EventEmitter'
11
+
12
+const log = new Log('Readable')
13
+
14
+// log.disable()
15
+log.level(3)
16
+
17
+/**
18
+ * A RNFetchBlob style nodejs ReadableStream polyfill class
19
+ */
20
+export default class Readable {
21
+
22
+  constructor() {
23
+
24
+    this._emitter = new EventEmitter()
25
+    this._encoding = 'utf8'
26
+    this._readableState = null
27
+    this._isPaused = true
28
+
29
+  }
30
+
31
+  pipe(stream:Readable):Readable {
32
+    this._emitter.addListener('data', (chunk) => {
33
+      stream.emit('data', chunk)
34
+    })
35
+  }
36
+
37
+  unpipe(stream:Readable, options:any):Readable {
38
+
39
+  }
40
+
41
+  setEncoding(encoding:'utf8' | 'base64' | 'ascii'):Readable {
42
+    this._encoding = encoding
43
+  }
44
+
45
+  resume():Readable {
46
+    this._readableState = true
47
+  }
48
+
49
+  read(size:number) {
50
+
51
+  }
52
+
53
+  isPaused():boolean {
54
+    return this._isPaused
55
+  }
56
+
57
+  pause():Readable {
58
+    this._readableState = false
59
+    return this
60
+  }
61
+
62
+  emit(event:string, data:any):Readable {
63
+    this._emitter.emit(event, data)
64
+    return this
65
+  }
66
+
67
+  on(event:string, fn:() => void):Readable {
68
+    this._emitter.addListener(event, fn)
69
+    return this
70
+  }
71
+
72
+  unshift(chunk:any):Readable {
73
+
74
+  }
75
+
76
+  wrap(stream:Stream) {
77
+
78
+  }
79
+
80
+}

+ 19
- 0
src/polyfill/Stream.js Zobrazit soubor

@@ -0,0 +1,19 @@
1
+// Copyright 2016 wkh237@github. All rights reserved.
2
+// Use of this source code is governed by a MIT-style license that can be
3
+// found in the LICENSE file.
4
+
5
+import RNFetchBlob from '../index.js'
6
+import fs from '../fs.js'
7
+import getUUID from '../utils/uuid'
8
+import Log from '../utils/log.js'
9
+
10
+const log = new Log('Stream')
11
+
12
+log.disable()
13
+// log.level(3)
14
+
15
+/**
16
+ * A RNFetchBlob style nodejs Stream polyfill class
17
+ */
18
+export default class Stream {
19
+}

+ 142
- 142
test/test-android.js Zobrazit soubor

@@ -28,126 +28,126 @@ let prefix = ((Platform.OS === 'android') ? 'file://' : '')
28 28
 let tmpFilePath = null
29 29
 const dirs = RNFetchBlob.fs.dirs
30 30
 
31
-describe('Download with notification', (report, done) => {
32
-  let filePath = null
33
-  let filename = `test-${Date.now()}.png`
34
-
35
-  filePath = `${dirs.DownloadDir}/${filename}`
36
-  RNFetchBlob.config({
37
-    path : filePath,
38
-    addAndroidDownloads : {
39
-      title : 'RNFetchBlob test download success',
40
-      description : `File description added by RNFetchblob`,
41
-      mediaScannable : true,
42
-      mime : "image/png",
43
-      notification : true
44
-    }
45
-  })
46
-  .fetch('GET', `${TEST_SERVER_URL}/public/github2.jpg`)
47
-  .then((resp) => {
48
-    tmpFilePath = resp.path()
49
-    report(<Info key={`image from ${tmpFilePath}`}>
50
-      <Image
51
-        source={{ uri : prefix + tmpFilePath}}
52
-        style={styles.image}/>
53
-    </Info>)
54
-    done()
55
-  })
56
-
57
-})
58
-
59
-describe('MediaScanner tests ', (report, done) => {
60
-  let filename = `scannable-test-${Date.now()}.png`
61
-  let filePath = `${dirs.DownloadDir}/${filename}`
62
-  RNFetchBlob.config({
63
-    path : filePath,
64
-  })
65
-  .fetch('GET', `${TEST_SERVER_URL}/public/github2.jpg`)
66
-  .then((resp) => {
67
-    tmpFilePath = resp.path()
68
-    return RNFetchBlob.fs.scanFile([
69
-      { path:resp.path() }
70
-    ])
71
-  })
72
-  .then(() => {
73
-    report(<Assert key={`scan image success, there should be a new file in Picture app named "${filename}"`} expect={true} actual={true}/>)
74
-    return RNFetchBlob
75
-            .config({
76
-              path : dirs.DCIMDir + '/beethoven-'+ Date.now() +'.mp3'
77
-            })
78
-            .fetch('GET', `${TEST_SERVER_URL}/public/beethoven.mp3`)
79
-  })
80
-  .then((resp) => {
81
-    fs.scanFile([{
82
-      path : resp.path()
83
-    }])
84
-    .then(() => {
85
-      report(<Assert
86
-        key={`scan mp3 file success, there exist a new file named "beethoven-${Date.now()}.mp3" in Music app`}
87
-        expect={true}
88
-        actual={true}/>)
89
-      done()
90
-    })
91
-  })
92
-
93
-})
94
-
95
-describe('android download manager', (report, done) => {
96
-  RNFetchBlob.config({
97
-    addAndroidDownloads : {
98
-      useDownloadManager : true,
99
-      title : 'RNFetchBlob test download manager test',
100
-      description : `File description added by RNFetchblob`,
101
-      mediaScannable : true,
102
-      notification : true
103
-    }
104
-  })
105
-  .fetch('GET', `${TEST_SERVER_URL}/public/beethoven.mp3`).then((resp) => {
106
-    report(
107
-      <Assert key="download manager complete handler" expect={true} actual={true}/>
108
-    )
109
-    return resp.readStream('ascii')
110
-  })
111
-  .then((stream) => {
112
-    stream.open();
113
-    let len = 0
114
-    stream.onData((chunk) => {
115
-      len += chunk.length
116
-    })
117
-    stream.onEnd(() => {
118
-      report(
119
-        <Assert key="download manager URI is readable"
120
-          expect={len}
121
-          comparer={Comparer.greater}
122
-          actual={0}/>
123
-      )
124
-      done()
125
-    })
126
-  })
127
-})
128
-
129
-describe('open a file from intent', (report, done) => {
130
-  let url  = null
131
-  RNFetchBlob.config({
132
-    addAndroidDownloads : {
133
-      useDownloadManager : true,
134
-      title : 'test-image',
135
-      description : 'open it from intent !',
136
-      mime : 'image/png',
137
-      mediaScannable : true,
138
-      notification : true,
139
-    }
140
-  })
141
-  .fetch('GET', `${TEST_SERVER_URL}/public/github.png`)
142
-  .then((res) => {
143
-    let sendIntent = RNFetchBlob.android.actionViewIntent
144
-    return sendIntent(res.path(), 'image/png')
145
-  })
146
-  .then(() => {
147
-    done()
148
-  })
149
-})
150
-
31
+// describe('Download with notification', (report, done) => {
32
+//   let filePath = null
33
+//   let filename = `test-${Date.now()}.png`
34
+//
35
+//   filePath = `${dirs.DownloadDir}/${filename}`
36
+//   RNFetchBlob.config({
37
+//     path : filePath,
38
+//     addAndroidDownloads : {
39
+//       title : 'RNFetchBlob test download success',
40
+//       description : `File description added by RNFetchblob`,
41
+//       mediaScannable : true,
42
+//       mime : "image/png",
43
+//       notification : true
44
+//     }
45
+//   })
46
+//   .fetch('GET', `${TEST_SERVER_URL}/public/github2.jpg`)
47
+//   .then((resp) => {
48
+//     tmpFilePath = resp.path()
49
+//     report(<Info key={`image from ${tmpFilePath}`}>
50
+//       <Image
51
+//         source={{ uri : prefix + tmpFilePath}}
52
+//         style={styles.image}/>
53
+//     </Info>)
54
+//     done()
55
+//   })
56
+//
57
+// })
58
+//
59
+// describe('MediaScanner tests ', (report, done) => {
60
+//   let filename = `scannable-test-${Date.now()}.png`
61
+//   let filePath = `${dirs.DownloadDir}/${filename}`
62
+//   RNFetchBlob.config({
63
+//     path : filePath,
64
+//   })
65
+//   .fetch('GET', `${TEST_SERVER_URL}/public/github2.jpg`)
66
+//   .then((resp) => {
67
+//     tmpFilePath = resp.path()
68
+//     return RNFetchBlob.fs.scanFile([
69
+//       { path:resp.path() }
70
+//     ])
71
+//   })
72
+//   .then(() => {
73
+//     report(<Assert key={`scan image success, there should be a new file in Picture app named "${filename}"`} expect={true} actual={true}/>)
74
+//     return RNFetchBlob
75
+//             .config({
76
+//               path : dirs.DCIMDir + '/beethoven-'+ Date.now() +'.mp3'
77
+//             })
78
+//             .fetch('GET', `${TEST_SERVER_URL}/public/beethoven.mp3`)
79
+//   })
80
+//   .then((resp) => {
81
+//     fs.scanFile([{
82
+//       path : resp.path()
83
+//     }])
84
+//     .then(() => {
85
+//       report(<Assert
86
+//         key={`scan mp3 file success, there exist a new file named "beethoven-${Date.now()}.mp3" in Music app`}
87
+//         expect={true}
88
+//         actual={true}/>)
89
+//       done()
90
+//     })
91
+//   })
92
+//
93
+// })
94
+//
95
+// describe('android download manager', (report, done) => {
96
+//   RNFetchBlob.config({
97
+//     addAndroidDownloads : {
98
+//       useDownloadManager : true,
99
+//       title : 'RNFetchBlob test download manager test',
100
+//       description : `File description added by RNFetchblob`,
101
+//       mediaScannable : true,
102
+//       notification : true
103
+//     }
104
+//   })
105
+//   .fetch('GET', `${TEST_SERVER_URL}/public/beethoven.mp3`).then((resp) => {
106
+//     report(
107
+//       <Assert key="download manager complete handler" expect={true} actual={true}/>
108
+//     )
109
+//     return resp.readStream('ascii')
110
+//   })
111
+//   .then((stream) => {
112
+//     stream.open();
113
+//     let len = 0
114
+//     stream.onData((chunk) => {
115
+//       len += chunk.length
116
+//     })
117
+//     stream.onEnd(() => {
118
+//       report(
119
+//         <Assert key="download manager URI is readable"
120
+//           expect={len}
121
+//           comparer={Comparer.greater}
122
+//           actual={0}/>
123
+//       )
124
+//       done()
125
+//     })
126
+//   })
127
+// })
128
+//
129
+// describe('open a file from intent', (report, done) => {
130
+//   let url  = null
131
+//   RNFetchBlob.config({
132
+//     addAndroidDownloads : {
133
+//       useDownloadManager : true,
134
+//       title : 'test-image',
135
+//       description : 'open it from intent !',
136
+//       mime : 'image/png',
137
+//       mediaScannable : true,
138
+//       notification : true,
139
+//     }
140
+//   })
141
+//   .fetch('GET', `${TEST_SERVER_URL}/public/github.png`)
142
+//   .then((res) => {
143
+//     let sendIntent = RNFetchBlob.android.actionViewIntent
144
+//     return sendIntent(res.path(), 'image/png')
145
+//   })
146
+//   .then(() => {
147
+//     done()
148
+//   })
149
+// })
150
+//
151 151
 // #75
152 152
 describe('APK downloaded from Download Manager should correct', (report, done) => {
153 153
 
@@ -175,25 +175,25 @@ describe('APK downloaded from Download Manager should correct', (report, done) =
175 175
 })
176 176
 
177 177
 // issue #74
178
-describe('download file to specific location using DownloadManager', (report, done) => {
179
-  let dest = dirs.DCIMDir + '/android-download-test-' +Date.now() + '.png'
180
-  RNFetchBlob.config({
181
-    addAndroidDownloads : {
182
-      useDownloadManager : true,
183
-      path : dest,
184
-      mime : 'image/png',
185
-      title : 'android-download-path-test.png',
186
-      description : 'download to specific path #74'
187
-    }
188
-  })
189
-  .fetch('GET', `${TEST_SERVER_URL}/public/github.png`)
190
-  .then((res) => fs.stat(res.path()))
191
-  .then((stat) => {
192
-    report(
193
-      <Assert key="file exists at the path"
194
-        expect={true} actual={true}/>,
195
-      <Assert key="file size correct"
196
-        expect="23975" actual={stat.size}/>)
197
-    done()
198
-  })
199
-})
178
+// describe('download file to specific location using DownloadManager', (report, done) => {
179
+//   let dest = dirs.DCIMDir + '/android-download-test-' +Date.now() + '.png'
180
+//   RNFetchBlob.config({
181
+//     addAndroidDownloads : {
182
+//       useDownloadManager : true,
183
+//       path : dest,
184
+//       mime : 'image/png',
185
+//       title : 'android-download-path-test.png',
186
+//       description : 'download to specific path #74'
187
+//     }
188
+//   })
189
+//   .fetch('GET', `${TEST_SERVER_URL}/public/github.png`)
190
+//   .then((res) => fs.stat(res.path()))
191
+//   .then((stat) => {
192
+//     report(
193
+//       <Assert key="file exists at the path"
194
+//         expect={true} actual={true}/>,
195
+//       <Assert key="file size correct"
196
+//         expect="23975" actual={stat.size}/>)
197
+//     done()
198
+//   })
199
+// })

+ 78
- 16
test/test-init.js Zobrazit soubor

@@ -18,8 +18,8 @@ const { Assert, Comparer, Info, prop } = RNTest
18 18
 // test environment variables
19 19
 
20 20
 prop('FILENAME', `${Platform.OS}-0.8.0-${Date.now()}.png`)
21
-prop('TEST_SERVER_URL', 'http://192.168.16.70:8123')
22
-prop('TEST_SERVER_URL_SSL', 'https://192.168.16.70:8124')
21
+prop('TEST_SERVER_URL', 'http://192.168.0.11:8123')
22
+prop('TEST_SERVER_URL_SSL', 'https://192.168.0.11:8124')
23 23
 prop('DROPBOX_TOKEN', 'fsXcpmKPrHgAAAAAAAAAoXZhcXYWdgLpQMan6Tb_bzJ237DXhgQSev12hA-gUXt4')
24 24
 prop('styles', {
25 25
   image : {
@@ -59,19 +59,81 @@ describe('GET image from server', (report, done) => {
59 59
 })
60 60
 
61 61
 
62
-require('./test-0.1.x-0.4.x')
63
-require('./test-0.5.1')
64
-require('./test-0.5.2')
65
-require('./test-0.6.0')
66
-require('./test-0.6.2')
62
+describe('Upload octet-stream image to Dropbox', (report, done) => {
63
+  let image = prop('image')
64
+  let tmp = null
65
+  let etag = ''
66
+  // upload a file to dropbox
67
+  RNFetchBlob.fetch('POST', 'https://content.dropboxapi.com/2/files/upload', {
68
+    Authorization : `Bearer ${DROPBOX_TOKEN}`,
69
+    'Dropbox-API-Arg': '{\"path\": \"/rn-upload/'+FILENAME+'\",\"mode\": \"add\",\"autorename\": true,\"mute\": false}',
70
+    'Content-Type' : 'application/octet-stream',
71
+  }, image)
72
+  .then((resp) => {
73
+    resp = resp.json()
74
+    report(
75
+      <Assert key="confirm the file has been uploaded" expect={FILENAME} actual={resp.name}/>
76
+    )
77
+    // detect range request support
78
+    return RNFetchBlob
79
+    .config({
80
+      path : RNFetchBlob.fs.dirs.DocumentDir + '/part1.png'
81
+    })
82
+    .fetch('GET', 'https://content.dropboxapi.com/1/files/auto'+'/rn-upload/'+FILENAME, {
83
+      Authorization : `Bearer ${DROPBOX_TOKEN}`,
84
+      'Cache-Control' : 'no-store',
85
+      'Range' : 'bytes=0-22975'
86
+    })
87
+  })
88
+  .then((res) => {
89
+
90
+    console.log('first chunk', res.info().headers,res.info().headers['Content-Length'])
91
+    // get first range
92
+    return RNFetchBlob
93
+    .config({
94
+      path : RNFetchBlob.fs.dirs.DocumentDir + '/part2.png'
95
+    })
96
+    .fetch('GET', 'https://content.dropboxapi.com/1/files/auto/rn-upload/'+FILENAME, {
97
+      Authorization : `Bearer ${DROPBOX_TOKEN}`,
98
+      'Cache-Control' : 'no-store',
99
+      'Range' : 'bytes=22976-'
100
+    })
101
+  })
102
+  .then((res) => {
103
+    tmp = res
104
+    console.log('second chunk', res.info().headers, res.info().headers['Content-Length'])
105
+    // get second range
106
+    return RNFetchBlob.fs.appendFile(RNFetchBlob.fs.dirs.DocumentDir + '/part1.png', RNFetchBlob.fs.dirs.DocumentDir + '/part2.png', 'uri')
107
+  })
108
+  .then(() => {
109
+    return RNFetchBlob.fs.stat(RNFetchBlob.fs.dirs.DocumentDir + '/part1.png')
110
+  })
111
+  .then((stat) => {
112
+    tmp.flush()
113
+    console.log('combined', stat)
114
+    report(<Info key="combined image">
115
+      <Text>{stat.size}</Text>
116
+      <Image key="combined image" style={styles.image} source={{uri :RNFetchBlob.fs.dirs.DocumentDir + '/part1.png' }}/>
117
+    </Info>)
118
+    done()
119
+  })
120
+
121
+})
122
+
123
+// require('./test-0.1.x-0.4.x')
124
+// require('./test-0.5.1')
125
+// require('./test-0.5.2')
126
+// require('./test-0.6.0')
127
+// require('./test-0.6.2')
67 128
 // require('./test-0.6.3')
68
-require('./test-0.7.0')
69
-require('./test-0.8.0')
70
-require('./test-0.9.0')
71
-require('./test-fetch')
72
-require('./test-fs')
73
-require('./test-xmlhttp')
74
-require('./test-blob')
75
-require('./test-firebase')
76
-require('./test-android')
129
+// require('./test-0.7.0')
130
+// require('./test-0.8.0')
131
+// require('./test-0.9.0')
132
+// require('./test-fetch')
133
+// require('./test-fs')
134
+// require('./test-xmlhttp')
135
+// require('./test-blob')
136
+// require('./test-firebase')
137
+// require('./test-android')
138
+// require('./test-readable')
77 139
 // require('./benchmark')

+ 40
- 0
test/test-readable.js Zobrazit soubor

@@ -0,0 +1,40 @@
1
+import RNTest from './react-native-testkit/'
2
+import React from 'react'
3
+import RNFetchBlob from 'react-native-fetch-blob'
4
+import Timer from 'react-timer-mixin'
5
+
6
+import {
7
+  StyleSheet,
8
+  Text,
9
+  View,
10
+  ScrollView,
11
+  CameraRoll,
12
+  Platform,
13
+  Dimensions,
14
+  Image,
15
+} from 'react-native';
16
+
17
+import EventEmitter from 'EventEmitter'
18
+
19
+const fs = RNFetchBlob.fs
20
+
21
+const Readable = RNFetchBlob.polyfill.Readable
22
+const { Assert, Comparer, Info, prop } = RNTest
23
+const describe = RNTest.config({
24
+  group : 'Blob',
25
+  run : true,
26
+  expand : false,
27
+  timeout : 20000,
28
+})
29
+const { TEST_SERVER_URL, TEST_SERVER_URL_SSL, DROPBOX_TOKEN, styles } = prop()
30
+const  dirs = RNFetchBlob.fs.dirs
31
+
32
+let prefix = ((Platform.OS === 'android') ? 'file://' : '')
33
+let file = RNTest.prop('image')
34
+
35
+describe('first test', (report, done) => {
36
+  let e = new EventEmitter()
37
+  console.log(e)
38
+  e.addListener('aaa', (data) => { console.log(data) })
39
+  e.emit('aaa', 123)
40
+})