1 // 2 // The Antville Project 3 // http://code.google.com/p/antville 4 // 5 // Copyright 2001-2007 by The Antville People 6 // 7 // Licensed under the Apache License, Version 2.0 (the ``License''); 8 // you may not use this file except in compliance with the License. 9 // You may obtain a copy of the License at 10 // 11 // http://www.apache.org/licenses/LICENSE-2.0 12 // 13 // Unless required by applicable law or agreed to in writing, software 14 // distributed under the License is distributed on an ``AS IS'' BASIS, 15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 // See the License for the specific language governing permissions and 17 // limitations under the License. 18 // 19 // $Revision$ 20 // $LastChangedBy$ 21 // $LastChangedDate$ 22 // $URL$ 23 // 24 25 /** 26 * @fileOverview Defines the Comment prototype. 27 */ 28 29 this.handleMetadata("url"); 30 this.handleMetadata("description"); 31 this.handleMetadata("contentType"); 32 this.handleMetadata("contentLength"); 33 this.handleMetadata("fileName"); 34 35 /** 36 * 37 */ 38 File.remove = function() { 39 if (this.constructor === File) { 40 this.getFile().remove(); 41 this.remove(); 42 } 43 return; 44 } 45 46 /** 47 * 48 * @param {String} name 49 */ 50 File.getName = function(name) { 51 if (name) { 52 //return name.replace(/[^\w\d\s._-]/g, String.EMPTY); 53 return String(name).trim().replace(/[\/\\:;?+\[\]{}|#"`<>^]/g, String.EMPTY); 54 } 55 return null; 56 } 57 58 /** 59 * @name File 60 * @constructor 61 * @property {Date} created 62 * @property {User} creator 63 * @property {Metadata} metadata 64 * @property {Date} modified 65 * @property {User} modifier 66 * @property {String} name 67 * @property {Number} parent_id 68 * @property {String} parent_type 69 * @property {String} prototype 70 * @property {Number} requests 71 * @property {Site} site 72 * @extends HopObject 73 */ 74 File.prototype.constructor = function() { 75 this.creator = this.modifier = session.user; 76 this.created = this.modified = new Date; 77 this.requests = 0; 78 return this; 79 } 80 81 /** 82 * 83 * @param {String} action 84 * @return {Boolean} 85 */ 86 File.prototype.getPermission = function(action) { 87 switch (action) { 88 case ".": 89 case "main": 90 return true; 91 case "delete": 92 case "edit": 93 return this._parent.getPermission("main") && 94 this.creator === session.user || 95 Membership.require(Membership.MANAGER) || 96 User.require(User.PRIVILEGED); 97 } 98 return false; 99 } 100 101 File.prototype.main_action = function() { 102 if (Membership.require(Membership.SUBSCRIBER) && 103 User.require(User.REGULAR)) { 104 this.requests += 1; 105 } 106 return res.redirect(this.getUrl()); 107 } 108 109 File.prototype.edit_action = function() { 110 if (req.postParams.save) { 111 try { 112 this.update(req.postParams); 113 res.message = gettext("The changes were saved successfully."); 114 res.redirect(this._parent.href()); 115 } catch (ex) { 116 res.message = ex; 117 app.log(ex); 118 } 119 } 120 121 res.data.action = this.href(req.action); 122 res.data.title = gettext("Edit file {0}", this.name); 123 res.data.body = this.renderSkinAsString("$File#edit"); 124 return this.site.renderSkin("Site#page"); 125 } 126 127 /** 128 * 129 * @param {String} name 130 * @returns {Object} 131 */ 132 File.prototype.getFormValue = function(name) { 133 var self = this; 134 135 var getOrigin = function(str) { 136 var origin = req.postParams.file_origin || self.origin; 137 if (origin && origin.contains("://")) { 138 return origin; 139 } 140 return null; 141 } 142 143 if (req.isPost()) { 144 if (name === "file") { 145 return getOrigin(); 146 } 147 return req.postParams[name]; 148 } 149 switch (name) { 150 case "file": 151 return getOrigin(); 152 } 153 return this[name]; 154 } 155 156 /** 157 * 158 * @param {Object} data 159 */ 160 File.prototype.update = function(data) { 161 if (data.uploadError) { 162 app.log(data.uploadError); 163 // Looks like the file uploaded has exceeded the upload limit ... 164 throw Error(gettext("File size is exceeding the upload limit.")); 165 } 166 167 if (!data.file_origin) { 168 if (this.isTransient()) { 169 throw Error(gettext("There was nothing to upload. Please be sure to choose a file.")); 170 } 171 } else if (data.file_origin !== this.origin) { 172 var mime = data.file; 173 if (mime.contentLength < 1) { 174 mime = getURL(data.file_origin); 175 if (!mime) { 176 throw Error(gettext("Could not fetch the file from the given URL.")); 177 } 178 } 179 180 this.origin = data.file_origin; 181 var mimeName = mime.normalizeFilename(mime.name); 182 this.contentLength = mime.contentLength; 183 this.contentType = mime.contentType; 184 185 if (!this.name) { 186 var name = File.getName(data.name) || mimeName.split(".")[0]; 187 this.name = this.site.files.getAccessName(name); 188 } 189 190 // Make the file persistent before proceeding with writing 191 // it to disk (also see Helma bug #607) 192 this.isTransient() && this.persist(); 193 194 var extension = mimeName.substr(mimeName.lastIndexOf(".")) || String.EMPTY; 195 var fileName = this.name + extension; 196 if (fileName !== this.fileName) { 197 // Remove existing file if the file name has changed 198 this.getFile().remove(); 199 } 200 this.fileName = fileName; 201 var file = this.getFile(); 202 mime.writeToFile(file.getParent(), file.getName()); 203 } 204 205 // FIXME: one day? 206 //this.setTags(data.tags || data.tag_array); 207 this.description = data.description; 208 this.touch(); 209 return; 210 } 211 212 /** 213 * 214 */ 215 File.prototype.url_macro = function() { 216 return res.write(this.url || this.getUrl()); 217 } 218 219 /** 220 * 221 * @param {Object} param 222 */ 223 File.prototype.contentLength_macro = function(param) { 224 return res.write((this.contentLength / 1024).format("###,###") + " KB"); 225 } 226 227 /** 228 * 229 */ 230 File.prototype.getFile = function() { 231 var site = this.site || res.handlers.site; 232 return site.getStaticFile("files/" + this.fileName); 233 } 234 235 /** 236 * 237 */ 238 File.prototype.getUrl = function() { 239 var site = this.site || res.handlers.site; 240 return site.getStaticUrl("files/" + this.fileName); 241 } 242