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 Archive prototype. 27 */ 28 29 Archive.PAGER = "page"; 30 Archive.COLLECTION = "collection"; 31 32 /** 33 * @name Archive 34 * @constructor 35 * @param {Object} name 36 * @param {Object} type 37 * @param {Object} parent 38 * @property {Story[]} _children 39 * @property {String} name 40 * @property {String} parent 41 * @property {String} type 42 * @extends HopObject 43 */ 44 Archive.prototype.constructor = function(name, type, parent) { 45 this.name = name; 46 this.type = type; 47 this.parent = parent; 48 return this; 49 } 50 51 /** 52 * 53 * @param {String} name 54 * @returns {HopObject} 55 */ 56 Archive.prototype.getChildElement = function(name) { 57 if (name.startsWith(Archive.PAGER)) { 58 return new Archive(name, Archive.PAGER, this); 59 } else if (!isNaN(name)) { 60 return new Archive(name, Archive.COLLECTION, this); 61 } 62 return this.get(name); 63 } 64 65 /** 66 * 67 * @param {String} action 68 * @returns {Boolean} 69 */ 70 Archive.prototype.getPermission = function(action) { 71 var site = res.handlers.site; 72 if (!site.getPermission("main") || site.archiveMode !== Site.PUBLIC) { 73 return false; 74 } 75 switch (action) { 76 case "main": 77 case "page1": 78 return true; 79 case "previous": 80 return this.getPage() > 1 81 case "next": 82 return this.getPage() < this.getSize() / this.getPageSize(); 83 } 84 return false; 85 } 86 87 Archive.prototype.main_action = function() { 88 res.data.title = gettext("Story Archive"); 89 res.data.body = this.renderSkinAsString("Archive#main"); 90 res.handlers.site.renderSkin("Site#page"); 91 res.handlers.site.log(); 92 return; 93 } 94 95 Archive.prototype.page1_action = function() { 96 return res.redirect(this.href()); 97 } 98 99 /** 100 * 101 * @param {String} action 102 * @returns {String} 103 */ 104 Archive.prototype.href = function(action) { 105 var buffer = []; 106 var archive = this; 107 while (archive.parent) { 108 buffer.push(archive.name); 109 archive = archive.parent; 110 } 111 buffer.push(res.handlers.site.href("archive")); 112 buffer.reverse(); 113 if (action) { 114 if (this.type === Archive.PAGER) { 115 buffer.pop(); 116 } 117 buffer.push(action); 118 } 119 return buffer.join("/"); 120 } 121 122 /** 123 * 124 * @param {Object} param 125 * @param {String} action 126 * @param {String} text 127 * @see renderLink 128 */ 129 Archive.prototype.link_macro = function(param, action, text) { 130 if (!this.getPermission(action)) { 131 return; 132 } 133 switch (action) { 134 case "previous": 135 var page = this.getPage() - 1; break; 136 case "next": 137 var page = this.getPage() + 1; break; 138 } 139 var action = "page" + page; 140 return renderLink.call(global, param, action, text, this); 141 } 142 143 /** 144 * 145 */ 146 Archive.prototype.stories_macro = function() { 147 var day, storyDay; 148 var page = this.getPage(); 149 var pageSize = this.getPageSize(); 150 151 var renderStory = function(story) { 152 storyDay = story.created.getDate(); 153 if (day !== storyDay) { 154 story.renderSkin("Story#date"); 155 day = storyDay; 156 } 157 story.renderSkin("Story#preview"); 158 return; 159 } 160 161 // FIXME: This is a little bit inconsistent and thus needs special care 162 var archive = this.type === Archive.PAGER ? this.parent : this; 163 if (!archive.parent) { 164 var site = res.handlers.site; 165 var offset = (page - 1) * pageSize; 166 var stories = site.stories.featured.list(offset, pageSize); 167 for each (var story in stories) { 168 renderStory(story); 169 }; 170 return; 171 } 172 173 var sql = new Sql; 174 sql.retrieve(Sql.ARCHIVE, res.handlers.site._id, this.getFilter(), 175 Sql.ARCHIVEORDER, pageSize, (page - 1) * pageSize); 176 sql.traverse(function() { 177 var story = Story.getById(this.id); 178 renderStory(story); 179 }); 180 return; 181 } 182 183 /** 184 * @returns {Number} 185 */ 186 Archive.prototype.getSize = function() { 187 // FIXME: This is a little bit inconsistent and thus needs special care 188 var archive = this.type === Archive.PAGER ? this.parent : this; 189 if (!archive.parent) { 190 return res.handlers.site.stories.featured.size(); 191 } 192 var size; 193 var sql = new Sql; 194 sql.retrieve(Sql.ARCHIVESIZE, res.handlers.site._id, this.getFilter()); 195 sql.traverse(function() { 196 size = this.count; 197 return; 198 }); 199 return size; 200 } 201 202 /** 203 * @param {boolean} 204 * @returns {String} 205 */ 206 Archive.prototype.getFilter = function() { 207 var buffer = []; 208 var archive = this; 209 do { 210 if (archive.type === Archive.COLLECTION) { 211 buffer.unshift(Number(archive.name)); 212 } 213 } while (archive = archive.parent); 214 215 if (buffer.length < 0) { 216 var now = new Date; 217 buffer.push(now.getDate()); 218 buffer.push(now.getMonth() + 1); 219 buffer.push(now.getFullYear()); 220 } 221 222 res.push(); 223 var sql = new Sql; 224 var keys = ["year", "month", "day"]; 225 for (var i in buffer) { 226 sql.retrieve(Sql.ARCHIVEPART, keys[i], buffer[i]); 227 res.write(sql); 228 } 229 return res.pop(); 230 } 231 232 /** 233 * @returns {Number} 234 */ 235 Archive.prototype.getPage = function() { 236 if (this.type === Archive.PAGER) { 237 return Number(this.name.substr(4)); 238 } 239 return 1; 240 } 241 242 /** 243 * @returns {Number} 244 */ 245 Archive.prototype.getPageSize = function() { 246 return res.handlers.site.pageSize; 247 } 248 249 /** 250 * @returns {Date} 251 */ 252 Archive.prototype.getDate = function() { 253 var date = new Date; 254 var offset = path.contains(res.handlers.site.archive) + 1; 255 if (offset > -1) { 256 var archive; 257 var buffer = []; 258 for (var i=offset; i<path.length; i+=1) { 259 archive = path[i]; 260 if (archive.type === Archive.COLLECTION) { 261 buffer.push(Number(archive.name)); 262 } 263 } 264 } 265 buffer[0] && date.setYear(buffer[0]); 266 buffer[1] && date.setMonth(buffer[1] - 1); 267 buffer[2] && date.setDate(buffer[2]); 268 return date; 269 } 270