Skip to content

Commit

Permalink
v.1.0.4
Browse files Browse the repository at this point in the history
 - Add streaming option, just append `?play=true` query to download link
 - Better download link, now with file extension
 - Better docs
  • Loading branch information
dr-dimitru committed Apr 17, 2015
1 parent eb1cf85 commit 81a98c6
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 15 deletions.
2 changes: 1 addition & 1 deletion .versions
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ [email protected]
[email protected]
[email protected]
[email protected]
ostrio:[email protected].3
ostrio:[email protected].4
ostrio:[email protected]
[email protected]
[email protected]
Expand Down
32 changes: 26 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ This package allows to:
- Write file in file system
* Automatically writes uploaded files on FS and special Collection
* You able to specify `path`, collection name, schema, chunk size and naming function
- File streaming from server via HTTP
* Correct `mime-type` and `Content-Range` headers
* Correct `206` and `416` responses
- Download uploaded files from server via HTTP
* You able to specify `route`
* Download huge files via stream `pipe`, tested on 100GB
Expand Down Expand Up @@ -78,19 +81,36 @@ myFiles.findOne(fileRef._id).link() # Get download link
myFiles.findOne(fileRef._id).remove() # Remove file
```

##### File streaming:
To stream file add `?play=true` query to download link.
```coffeescript
audio = new Meteor.Files()

if Meteor.isClient
Template.my.helpers
audiofiles: ->
audio.find({'meta.post': postId}).cursor
```

In template:
```jade
template(name="my")
ul
each audiofiles
li
audio(preload="auto" controls="true")
source(src="{{fileURL this}}?play=true" type="{{type}}")
```

##### File download:
To download file simply return result of `link()` method to template. Data will be transfered via pipe, add `?download=true` query to link, to send file directly.
Use `?download=true` query for smaller files, for big files, video and audio files (including streaming) - just use plain link without query.
To download file use `fileURL` template helper. Data will be transfered via pipe, - just add `?download=true` query to link, so server will send file directly. Use `?download=true` query for smaller files, for big files - just use plain link without query.
```coffeescript
uploads = new Meteor.Files()

if Meteor.isClient
Template.my.helpers
files: ->
uploads.find({'meta.post': postId}).cursor

link: ->
uploads.findOne(@_id).link()
```

In template:
Expand All @@ -99,7 +119,7 @@ template(name="my")
ul
each files
li
a(href="{{link}}?download=true") name
a(href="{{fileURL this}}?download=true") name
```


Expand Down
43 changes: 36 additions & 7 deletions files.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ cp = (to, from) ->
@property {Object} schema - Collection Schema
@property {Number} chunkSize - Upload chunk size
@property {Function} namingFunction - Function which returns `String`
@property {Boolean} debug - Turn on/of debugging and extra logging
@property {Boolean} debug - Turn on/of debugging and extra logging
@description Create new instance of Meteor.Files
###
class Meteor.Files
Expand Down Expand Up @@ -126,7 +126,7 @@ class Meteor.Files
remove: ->
true

Router.route "#{@downloadRoute}/:_id/#{@collectionName}", ->
Router.route "#{@downloadRoute}/#{@collectionName}/:_id/:name", ->
self.findOne(this.params._id).download.call @, self
, {where: 'server'}

Expand Down Expand Up @@ -270,7 +270,6 @@ class Meteor.Files
###
insert: (file, meta, onUploaded, onProgress, onBeforeUpload) ->
console.info "Meteor.Files Debugger: [insert()]" if @debug
check file, Match.OneOf File, Object
check meta, Match.Optional Object
check onUploaded, Match.Optional Function
check onProgress, Match.Optional Function
Expand All @@ -292,7 +291,6 @@ class Meteor.Files

file = _.extend file, fileData

startTime = performance.now() if @debug
console.time('insert') if @debug

randFileName = @namingFunction.call null, true
Expand All @@ -302,9 +300,7 @@ class Meteor.Files
self = @

end = (error, data) ->
endTime = performance.now() if self.debug
console.timeEnd('insert') if self.debug
console.info "Meteor.Files Debugger: [EXECUTION TIME]: " + (endTime - startTime) if self.debug
window.onbeforeunload = null
onUploaded and onUploaded.call self, error, data

Expand Down Expand Up @@ -391,6 +387,39 @@ class Meteor.Files
'Content-Length': self.currentFile.size
resp.write file
resp.end()
else if @params.query.play and @params.query.play == 'true'
if @request.headers.range
array = @request.headers.range.split /bytes=([0-9]*)-([0-9]*)/
start = parseInt array[1]
end = parseInt array[2]
result =
Start: if isNaN(start) then 0 else start
End: if isNaN(end) then (self.currentFile.size - 1) else end

if not isNaN(start) and isNaN(end)
result.Start = start
result.End = self.currentFile.size - 1

if isNaN(start) and not isNaN(end)
result.Start = self.currentFile.size - end
result.End = self.currentFile.size - 1

if not @request.headers.range or (result.Start >= self.currentFile.size or result.End >= self.currentFile.size)
resp.writeHead 416,
'Content-Range': "bytes */#{self.currentFile.size}"
resp.end()
return null

stream = fs.createReadStream self.currentFile.path, {start: result.Start, end: result.End}
resp.writeHead 206,
'Content-Range': "bytes #{result.Start}-#{result.End}/#{self.currentFile.size}"
'Cache-Control': 'no-cache'
'Content-Type': self.currentFile.type
'Content-Encoding': 'binary'
'Content-Disposition': 'attachment; filename=' + encodeURI self.currentFile.name + ';'
'Content-Length': if result.Start == result.End then 0 else (result.End - result.Start + 1);
'Accept-Ranges': 'bytes'
stream.pipe resp
else
stream = fs.createReadStream self.currentFile.path
resp.writeHead 200,
Expand Down Expand Up @@ -428,6 +457,6 @@ if Meteor.isClient
###
Template.registerHelper 'fileURL', (fileRef) ->
if fileRef._id
return "#{fileRef._downloadRoute}/#{fileRef._id}/#{fileRef._collectionName}"
return "#{fileRef._downloadRoute}/#{fileRef._collectionName}/#{fileRef._id}/#{fileRef._id}.#{fileRef.extension}"
else
null
2 changes: 1 addition & 1 deletion package.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package.describe({
name: 'ostrio:files',
version: '1.0.3',
version: '1.0.4',
summary: 'Upload, Store and Download small and huge files to/from file system (FS) via DDP and HTTP',
git: 'https://github.com/VeliovGroup/Meteor-Files',
documentation: 'README.md'
Expand Down

0 comments on commit 81a98c6

Please sign in to comment.