-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.coffee
161 lines (144 loc) · 5.37 KB
/
index.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
mongoose = require('mongoose')
path = require('path')
fs = require('fs')
mkdirp = require('mkdirp')
Schema = mongoose.Schema
ObjectId = Schema.ObjectId
# ---------------------------------------------------------------------
# helper functions
# ---------------------------------------------------------------------
# Extend a source object with the properties of another object (shallow copy).
extend = (dst, src) ->
for key, val of src
dst[key] = val
dst
# Add missing properties from a `src` object.
defaults = (dst, src) ->
for key, val of src
if not (key of dst)
dst[key] = val
dst
# Add a new field by name to a mongoose schema
addSchemaField = (schema, pathname, fieldSpec) ->
fieldSchema = {}
fieldSchema[pathname] = fieldSpec
schema.add fieldSchema
addSchemaSubField = (schema, masterPathname, subName, fieldSpec) ->
addSchemaField schema, "#{masterPathname}.#{subName}", fieldSpec
is_callable = (f) ->
(typeof f is 'function')
# ---------------------------------------------------------------------
# M O N G O O S E P L U G I N S
# ---------------------------------------------------------------------
# http://mongoosejs.com/docs/plugins.html
filePlugin = (schema, options={}) ->
pathname = options.name or 'file'
onChangeCb = options.change_cb or null
upload_to = options.upload_to or null # if null, uploaded file is left in the temp upload dir
relative_to = options.relative_to or null # if null, .rel field is equal to .path
# fieldSchema = {}
# fieldSchema[pathname] = {} # mixed: { type: Schema.Types.Mixed }
# schema.add fieldSchema
# fieldSchema = {}
# fieldSchema["#{pathname}.name"] = String
# schema.add fieldSchema
# fieldSchema = {}
# fieldSchema["#{pathname}.path"] = String
# schema.add fieldSchema
# fieldSchema = {}
# fieldSchema["#{pathname}.type"] = {type: String}
# schema.add fieldSchema
# fieldSchema = {}
# fieldSchema["#{pathname}.size"] = Number
# schema.add fieldSchema
# fieldSchema = {}
# fieldSchema["#{pathname}.lastModified"] = Date
# schema.add fieldSchema
# fieldSchema = {}
# fieldSchema[pathname] =
# name: String
# path: String
# rel: String
# type: String
# size: Number
# lastModified: Date
# schema.add fieldSchema
# fieldSchema = {}
# fieldSchema[pathname] = {} # mixed: { type: Schema.Types.Mixed }
# schema.add fieldSchema
addSchemaField schema, pathname, {} # mixed: { type: Schema.Types.Mixed }
addSchemaSubField schema, pathname, 'name', { type: String, default: () -> null }
addSchemaSubField schema, pathname, 'path', { type: String, default: () -> null }
addSchemaSubField schema, pathname, 'rel', { type: String, default: () -> null }
addSchemaSubField schema, pathname, 'type', { type: String, default: () -> null }
addSchemaSubField schema, pathname, 'size', { type: Number, default: () -> null }
addSchemaSubField schema, pathname, 'lastModified', { type: Date, default: () -> null }
schema.virtual("#{pathname}.file").set (fileObj) ->
u_path = fileObj.path
if upload_to
# move from temp. upload directory to final destination
if is_callable(upload_to)
dst = upload_to.call(@, fileObj)
else
dst = path.join(upload_to, fileObj.name)
dst_dirname = path.dirname(dst)
mkdirp dst_dirname, (err) =>
throw err if err
fs.rename u_path, dst, (err) =>
if (err)
# delete the temporary file, so that the explicitly set temporary upload dir does not get filled with unwanted files
fs.unlink u_path, (err) =>
throw err if err
throw err
console.log("moved from #{u_path} to #{dst}")
rel = dst
if relative_to
if is_callable(relative_to)
rel = relative_to.call(@, fileObj)
else
rel = path.relative(relative_to, dst)
@set("#{pathname}.name", fileObj.name)
@set("#{pathname}.path", dst)
@set("#{pathname}.rel", rel)
@set("#{pathname}.type", fileObj.type)
@set("#{pathname}.size", fileObj.size)
@set("#{pathname}.lastModified", fileObj.lastModifiedDate)
@markModified(pathname)
else
dst = u_path
rel = dst
if relative_to
if is_callable(relative_to)
rel = relative_to.call(@, fileObj)
else
rel = path.relative(relative_to, dst)
@set("#{pathname}.name", fileObj.name)
@set("#{pathname}.path", dst)
@set("#{pathname}.rel", rel)
@set("#{pathname}.type", fileObj.type)
@set("#{pathname}.size", fileObj.size)
@set("#{pathname}.lastModified", fileObj.lastModifiedDate)
@markModified(pathname)
schema.pre 'set', (next, path, val, typel) ->
if path is "#{pathname}.path"
if onChangeCb
oldValue = @get("#{pathname}.path")
console.log("old: #{oldValue} new: #{val}")
onChangeCb.call(@, pathname, val, oldValue)
next()
make_upload_to_model = (basedir, subdir) ->
b_dir = basedir
s_dir = subdir
upload_to_model = (fileObj) ->
dstdir = b_dir
if s_dir
dstdir = path.join(dstdir, s_dir)
id = @get('id')
if id
dstdir = path.join(dstdir, "#{id}")
path.join(dstdir, fileObj.name)
upload_to_model
# -- exports ----------------------------------------------------------
module.exports =
filePlugin: filePlugin
make_upload_to_model: make_upload_to_model