beet 0.4.2 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +1 -1
- data/VERSION +1 -1
- data/beet.gemspec +8 -2
- data/lib/beet/files/swfupload/images/cancelbutton.gif +0 -0
- data/lib/beet/files/swfupload/images/header-bg.jpg +0 -0
- data/lib/beet/files/swfupload/images/logo.gif +0 -0
- data/lib/beet/files/swfupload/js/handlers.js +290 -0
- data/lib/beet/recipes/rails/auth/devise.rb +3 -4
- data/lib/beet/recipes/rails/db/mongo.rb +57 -0
- data/lib/beet/recipes/rails/swfupload.rb +305 -0
- metadata +8 -2
    
        data/README.rdoc
    CHANGED
    
    
    
        data/VERSION
    CHANGED
    
    | @@ -1 +1 @@ | |
| 1 | 
            -
            0.4. | 
| 1 | 
            +
            0.4.3
         | 
    
        data/beet.gemspec
    CHANGED
    
    | @@ -5,11 +5,11 @@ | |
| 5 5 |  | 
| 6 6 | 
             
            Gem::Specification.new do |s|
         | 
| 7 7 | 
             
              s.name = %q{beet}
         | 
| 8 | 
            -
              s.version = "0.4. | 
| 8 | 
            +
              s.version = "0.4.3"
         | 
| 9 9 |  | 
| 10 10 | 
             
              s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
         | 
| 11 11 | 
             
              s.authors = ["Jack Dempsey"]
         | 
| 12 | 
            -
              s.date = %q{ | 
| 12 | 
            +
              s.date = %q{2010-01-09}
         | 
| 13 13 | 
             
              s.default_executable = %q{beet}
         | 
| 14 14 | 
             
              s.email = %q{jack.dempsey@gmail.com}
         | 
| 15 15 | 
             
              s.executables = ["beet"]
         | 
| @@ -37,6 +37,10 @@ Gem::Specification.new do |s| | |
| 37 37 | 
             
                 "lib/beet/execution.rb",
         | 
| 38 38 | 
             
                 "lib/beet/executor.rb",
         | 
| 39 39 | 
             
                 "lib/beet/file_system.rb",
         | 
| 40 | 
            +
                 "lib/beet/files/swfupload/images/cancelbutton.gif",
         | 
| 41 | 
            +
                 "lib/beet/files/swfupload/images/header-bg.jpg",
         | 
| 42 | 
            +
                 "lib/beet/files/swfupload/images/logo.gif",
         | 
| 43 | 
            +
                 "lib/beet/files/swfupload/js/handlers.js",
         | 
| 40 44 | 
             
                 "lib/beet/gem_location_map.rb",
         | 
| 41 45 | 
             
                 "lib/beet/interaction.rb",
         | 
| 42 46 | 
             
                 "lib/beet/logger.rb",
         | 
| @@ -52,10 +56,12 @@ Gem::Specification.new do |s| | |
| 52 56 | 
             
                 "lib/beet/recipes/rails/css/blueprint.rb",
         | 
| 53 57 | 
             
                 "lib/beet/recipes/rails/css/nifty_layout.rb",
         | 
| 54 58 | 
             
                 "lib/beet/recipes/rails/css/reset.rb",
         | 
| 59 | 
            +
                 "lib/beet/recipes/rails/db/mongo.rb",
         | 
| 55 60 | 
             
                 "lib/beet/recipes/rails/db/mysql.rb",
         | 
| 56 61 | 
             
                 "lib/beet/recipes/rails/db/postgres.rb",
         | 
| 57 62 | 
             
                 "lib/beet/recipes/rails/git.rb",
         | 
| 58 63 | 
             
                 "lib/beet/recipes/rails/jquery.rb",
         | 
| 64 | 
            +
                 "lib/beet/recipes/rails/swfupload.rb",
         | 
| 59 65 | 
             
                 "lib/beet/recipes/rails/testing/rspec.rb",
         | 
| 60 66 | 
             
                 "lib/beet/recipes/rails/testing/shoulda.rb",
         | 
| 61 67 | 
             
                 "lib/beet/scm.rb",
         | 
| Binary file | 
| Binary file | 
| Binary file | 
| @@ -0,0 +1,290 @@ | |
| 1 | 
            +
            function fileQueueError(file, errorCode, message) {
         | 
| 2 | 
            +
            	try {
         | 
| 3 | 
            +
            		var imageName = "error.gif";
         | 
| 4 | 
            +
            		var errorName = "";
         | 
| 5 | 
            +
            		if (errorCode === SWFUpload.errorCode_QUEUE_LIMIT_EXCEEDED) {
         | 
| 6 | 
            +
            			errorName = "You have attempted to queue too many files.";
         | 
| 7 | 
            +
            		}
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            		if (errorName !== "") {
         | 
| 10 | 
            +
            			alert(errorName);
         | 
| 11 | 
            +
            			return;
         | 
| 12 | 
            +
            		}
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            		switch (errorCode) {
         | 
| 15 | 
            +
            		case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
         | 
| 16 | 
            +
            			imageName = "zerobyte.gif";
         | 
| 17 | 
            +
            			break;
         | 
| 18 | 
            +
            		case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:
         | 
| 19 | 
            +
            			imageName = "toobig.gif";
         | 
| 20 | 
            +
            			break;
         | 
| 21 | 
            +
            		case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
         | 
| 22 | 
            +
            		case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE:
         | 
| 23 | 
            +
            		default:
         | 
| 24 | 
            +
            			alert(message);
         | 
| 25 | 
            +
            			break;
         | 
| 26 | 
            +
            		}
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            		addImage("images/swfupload/" + imageName);
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            	} catch (ex) {
         | 
| 31 | 
            +
            		this.debug(ex);
         | 
| 32 | 
            +
            	}
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            }
         | 
| 35 | 
            +
             | 
| 36 | 
            +
            function fileDialogComplete(numFilesSelected, numFilesQueued) {
         | 
| 37 | 
            +
            	try {
         | 
| 38 | 
            +
            		if (numFilesQueued > 0) {
         | 
| 39 | 
            +
            			this.startUpload();
         | 
| 40 | 
            +
            		}
         | 
| 41 | 
            +
            	} catch (ex) {
         | 
| 42 | 
            +
            		this.debug(ex);
         | 
| 43 | 
            +
            	}
         | 
| 44 | 
            +
            }
         | 
| 45 | 
            +
             | 
| 46 | 
            +
            function uploadProgress(file, bytesLoaded) {
         | 
| 47 | 
            +
             | 
| 48 | 
            +
            	try {
         | 
| 49 | 
            +
            		var percent = Math.ceil((bytesLoaded / file.size) * 100);
         | 
| 50 | 
            +
             | 
| 51 | 
            +
            		var progress = new FileProgress(file,  this.customSettings.upload_target);
         | 
| 52 | 
            +
            		progress.setProgress(percent);
         | 
| 53 | 
            +
            		if (percent === 100) {
         | 
| 54 | 
            +
            			progress.setStatus("Processing file...");
         | 
| 55 | 
            +
            			progress.toggleCancel(false, this);
         | 
| 56 | 
            +
            		} else {
         | 
| 57 | 
            +
            			progress.setStatus("Uploading...");
         | 
| 58 | 
            +
            			progress.toggleCancel(true, this);
         | 
| 59 | 
            +
            		}
         | 
| 60 | 
            +
            	} catch (ex) {
         | 
| 61 | 
            +
            		this.debug(ex);
         | 
| 62 | 
            +
            	}
         | 
| 63 | 
            +
            }
         | 
| 64 | 
            +
             | 
| 65 | 
            +
            function uploadSuccess(file, serverData) {
         | 
| 66 | 
            +
            	try {
         | 
| 67 | 
            +
            	  $('#mp3info').append("<p>"+serverData+"</p>");
         | 
| 68 | 
            +
            		var progress = new FileProgress(file,  this.customSettings.upload_target);
         | 
| 69 | 
            +
             | 
| 70 | 
            +
            		if (serverData.substring(0, 2) === "OK") {
         | 
| 71 | 
            +
            			//addImage("thumbnail.php?id=" + serverData.substring(7));
         | 
| 72 | 
            +
             | 
| 73 | 
            +
            			progress.setStatus("Upload Successfull.");
         | 
| 74 | 
            +
            			progress.toggleCancel(false);
         | 
| 75 | 
            +
            		} else {
         | 
| 76 | 
            +
            			addImage("/images/swfupload/error.gif");
         | 
| 77 | 
            +
            			progress.setStatus("Error.");
         | 
| 78 | 
            +
            			progress.toggleCancel(false);
         | 
| 79 | 
            +
            			alert(serverData);
         | 
| 80 | 
            +
             | 
| 81 | 
            +
            		}
         | 
| 82 | 
            +
             | 
| 83 | 
            +
             | 
| 84 | 
            +
            	} catch (ex) {
         | 
| 85 | 
            +
            		this.debug(ex);
         | 
| 86 | 
            +
            	}
         | 
| 87 | 
            +
            }
         | 
| 88 | 
            +
             | 
| 89 | 
            +
            function uploadComplete(file) {
         | 
| 90 | 
            +
            	try {
         | 
| 91 | 
            +
            		/*  I want the next upload to continue automatically so I'll call startUpload here */
         | 
| 92 | 
            +
            		if (this.getStats().files_queued > 0) {
         | 
| 93 | 
            +
            			this.startUpload();
         | 
| 94 | 
            +
            		} else {
         | 
| 95 | 
            +
            			var progress = new FileProgress(file,  this.customSettings.upload_target);
         | 
| 96 | 
            +
            			progress.setComplete();
         | 
| 97 | 
            +
            			progress.setStatus("All files received.");
         | 
| 98 | 
            +
            			progress.toggleCancel(false);
         | 
| 99 | 
            +
            		}
         | 
| 100 | 
            +
            	} catch (ex) {
         | 
| 101 | 
            +
            		this.debug(ex);
         | 
| 102 | 
            +
            	}
         | 
| 103 | 
            +
            }
         | 
| 104 | 
            +
             | 
| 105 | 
            +
            function uploadError(file, errorCode, message) {
         | 
| 106 | 
            +
            	var imageName =  "error.gif";
         | 
| 107 | 
            +
            	var progress;
         | 
| 108 | 
            +
            	try {
         | 
| 109 | 
            +
            		switch (errorCode) {
         | 
| 110 | 
            +
            		case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED:
         | 
| 111 | 
            +
            			try {
         | 
| 112 | 
            +
            				progress = new FileProgress(file,  this.customSettings.upload_target);
         | 
| 113 | 
            +
            				progress.setCancelled();
         | 
| 114 | 
            +
            				progress.setStatus("Cancelled");
         | 
| 115 | 
            +
            				progress.toggleCancel(false);
         | 
| 116 | 
            +
            			}
         | 
| 117 | 
            +
            			catch (ex1) {
         | 
| 118 | 
            +
            				this.debug(ex1);
         | 
| 119 | 
            +
            			}
         | 
| 120 | 
            +
            			break;
         | 
| 121 | 
            +
            		case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED:
         | 
| 122 | 
            +
            			try {
         | 
| 123 | 
            +
            				progress = new FileProgress(file,  this.customSettings.upload_target);
         | 
| 124 | 
            +
            				progress.setCancelled();
         | 
| 125 | 
            +
            				progress.setStatus("Stopped");
         | 
| 126 | 
            +
            				progress.toggleCancel(true);
         | 
| 127 | 
            +
            			}
         | 
| 128 | 
            +
            			catch (ex2) {
         | 
| 129 | 
            +
            				this.debug(ex2);
         | 
| 130 | 
            +
            			}
         | 
| 131 | 
            +
            		case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED:
         | 
| 132 | 
            +
            			imageName = "uploadlimit.gif";
         | 
| 133 | 
            +
            			break;
         | 
| 134 | 
            +
            		default:
         | 
| 135 | 
            +
            			alert(message);
         | 
| 136 | 
            +
            			break;
         | 
| 137 | 
            +
            		}
         | 
| 138 | 
            +
             | 
| 139 | 
            +
            		addImage("/images/swfupload/" + imageName);
         | 
| 140 | 
            +
             | 
| 141 | 
            +
            	} catch (ex3) {
         | 
| 142 | 
            +
            		this.debug(ex3);
         | 
| 143 | 
            +
            	}
         | 
| 144 | 
            +
             | 
| 145 | 
            +
            }
         | 
| 146 | 
            +
             | 
| 147 | 
            +
             | 
| 148 | 
            +
            function addImage(src) {
         | 
| 149 | 
            +
            	var newImg = document.createElement("img");
         | 
| 150 | 
            +
            	newImg.style.margin = "5px";
         | 
| 151 | 
            +
             | 
| 152 | 
            +
            	document.getElementById("thumbnails").appendChild(newImg);
         | 
| 153 | 
            +
            	if (newImg.filters) {
         | 
| 154 | 
            +
            		try {
         | 
| 155 | 
            +
            			newImg.filters.item("DXImageTransform.Microsoft.Alpha").opacity = 0;
         | 
| 156 | 
            +
            		} catch (e) {
         | 
| 157 | 
            +
            			// If it is not set initially, the browser will throw an error.  This will set it if it is not set yet.
         | 
| 158 | 
            +
            			newImg.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + 0 + ')';
         | 
| 159 | 
            +
            		}
         | 
| 160 | 
            +
            	} else {
         | 
| 161 | 
            +
            		newImg.style.opacity = 0;
         | 
| 162 | 
            +
            	}
         | 
| 163 | 
            +
             | 
| 164 | 
            +
            	newImg.onload = function () {
         | 
| 165 | 
            +
            		fadeIn(newImg, 0);
         | 
| 166 | 
            +
            	};
         | 
| 167 | 
            +
            	newImg.src = src;
         | 
| 168 | 
            +
            }
         | 
| 169 | 
            +
             | 
| 170 | 
            +
            function fadeIn(element, opacity) {
         | 
| 171 | 
            +
            	var reduceOpacityBy = 5;
         | 
| 172 | 
            +
            	var rate = 30;	// 15 fps
         | 
| 173 | 
            +
             | 
| 174 | 
            +
             | 
| 175 | 
            +
            	if (opacity < 100) {
         | 
| 176 | 
            +
            		opacity += reduceOpacityBy;
         | 
| 177 | 
            +
            		if (opacity > 100) {
         | 
| 178 | 
            +
            			opacity = 100;
         | 
| 179 | 
            +
            		}
         | 
| 180 | 
            +
             | 
| 181 | 
            +
            		if (element.filters) {
         | 
| 182 | 
            +
            			try {
         | 
| 183 | 
            +
            				element.filters.item("DXImageTransform.Microsoft.Alpha").opacity = opacity;
         | 
| 184 | 
            +
            			} catch (e) {
         | 
| 185 | 
            +
            				// If it is not set initially, the browser will throw an error.  This will set it if it is not set yet.
         | 
| 186 | 
            +
            				element.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + opacity + ')';
         | 
| 187 | 
            +
            			}
         | 
| 188 | 
            +
            		} else {
         | 
| 189 | 
            +
            			element.style.opacity = opacity / 100;
         | 
| 190 | 
            +
            		}
         | 
| 191 | 
            +
            	}
         | 
| 192 | 
            +
             | 
| 193 | 
            +
            	if (opacity < 100) {
         | 
| 194 | 
            +
            		setTimeout(function () {
         | 
| 195 | 
            +
            			fadeIn(element, opacity);
         | 
| 196 | 
            +
            		}, rate);
         | 
| 197 | 
            +
            	}
         | 
| 198 | 
            +
            }
         | 
| 199 | 
            +
             | 
| 200 | 
            +
             | 
| 201 | 
            +
             | 
| 202 | 
            +
            /* ******************************************
         | 
| 203 | 
            +
             *	FileProgress Object
         | 
| 204 | 
            +
             *	Control object for displaying file info
         | 
| 205 | 
            +
             * ****************************************** */
         | 
| 206 | 
            +
             | 
| 207 | 
            +
            function FileProgress(file, targetID) {
         | 
| 208 | 
            +
            	this.fileProgressID = "divFileProgress";
         | 
| 209 | 
            +
             | 
| 210 | 
            +
            	this.fileProgressWrapper = document.getElementById(this.fileProgressID);
         | 
| 211 | 
            +
            	if (!this.fileProgressWrapper) {
         | 
| 212 | 
            +
            		this.fileProgressWrapper = document.createElement("div");
         | 
| 213 | 
            +
            		this.fileProgressWrapper.className = "progressWrapper";
         | 
| 214 | 
            +
            		this.fileProgressWrapper.id = this.fileProgressID;
         | 
| 215 | 
            +
             | 
| 216 | 
            +
            		this.fileProgressElement = document.createElement("div");
         | 
| 217 | 
            +
            		this.fileProgressElement.className = "progressContainer";
         | 
| 218 | 
            +
             | 
| 219 | 
            +
            		var progressCancel = document.createElement("a");
         | 
| 220 | 
            +
            		progressCancel.className = "progressCancel";
         | 
| 221 | 
            +
            		progressCancel.href = "#";
         | 
| 222 | 
            +
            		progressCancel.style.visibility = "hidden";
         | 
| 223 | 
            +
            		progressCancel.appendChild(document.createTextNode(" "));
         | 
| 224 | 
            +
             | 
| 225 | 
            +
            		var progressText = document.createElement("div");
         | 
| 226 | 
            +
            		progressText.className = "progressName";
         | 
| 227 | 
            +
            		progressText.appendChild(document.createTextNode(file.name));
         | 
| 228 | 
            +
             | 
| 229 | 
            +
            		var progressBar = document.createElement("div");
         | 
| 230 | 
            +
            		progressBar.className = "progressBarInProgress";
         | 
| 231 | 
            +
             | 
| 232 | 
            +
            		var progressStatus = document.createElement("div");
         | 
| 233 | 
            +
            		progressStatus.className = "progressBarStatus";
         | 
| 234 | 
            +
            		progressStatus.innerHTML = " ";
         | 
| 235 | 
            +
             | 
| 236 | 
            +
            		this.fileProgressElement.appendChild(progressCancel);
         | 
| 237 | 
            +
            		this.fileProgressElement.appendChild(progressText);
         | 
| 238 | 
            +
            		this.fileProgressElement.appendChild(progressStatus);
         | 
| 239 | 
            +
            		this.fileProgressElement.appendChild(progressBar);
         | 
| 240 | 
            +
             | 
| 241 | 
            +
            		this.fileProgressWrapper.appendChild(this.fileProgressElement);
         | 
| 242 | 
            +
             | 
| 243 | 
            +
            		document.getElementById(targetID).appendChild(this.fileProgressWrapper);
         | 
| 244 | 
            +
            		fadeIn(this.fileProgressWrapper, 0);
         | 
| 245 | 
            +
             | 
| 246 | 
            +
            	} else {
         | 
| 247 | 
            +
            		this.fileProgressElement = this.fileProgressWrapper.firstChild;
         | 
| 248 | 
            +
            		this.fileProgressElement.childNodes[1].firstChild.nodeValue = file.name;
         | 
| 249 | 
            +
            	}
         | 
| 250 | 
            +
             | 
| 251 | 
            +
            	this.height = this.fileProgressWrapper.offsetHeight;
         | 
| 252 | 
            +
             | 
| 253 | 
            +
            }
         | 
| 254 | 
            +
            FileProgress.prototype.setProgress = function (percentage) {
         | 
| 255 | 
            +
            	this.fileProgressElement.className = "progressContainer green";
         | 
| 256 | 
            +
            	this.fileProgressElement.childNodes[3].className = "progressBarInProgress";
         | 
| 257 | 
            +
            	this.fileProgressElement.childNodes[3].style.width = percentage + "%";
         | 
| 258 | 
            +
            };
         | 
| 259 | 
            +
            FileProgress.prototype.setComplete = function () {
         | 
| 260 | 
            +
            	this.fileProgressElement.className = "progressContainer blue";
         | 
| 261 | 
            +
            	this.fileProgressElement.childNodes[3].className = "progressBarComplete";
         | 
| 262 | 
            +
            	this.fileProgressElement.childNodes[3].style.width = "";
         | 
| 263 | 
            +
             | 
| 264 | 
            +
            };
         | 
| 265 | 
            +
            FileProgress.prototype.setError = function () {
         | 
| 266 | 
            +
            	this.fileProgressElement.className = "progressContainer red";
         | 
| 267 | 
            +
            	this.fileProgressElement.childNodes[3].className = "progressBarError";
         | 
| 268 | 
            +
            	this.fileProgressElement.childNodes[3].style.width = "";
         | 
| 269 | 
            +
             | 
| 270 | 
            +
            };
         | 
| 271 | 
            +
            FileProgress.prototype.setCancelled = function () {
         | 
| 272 | 
            +
            	this.fileProgressElement.className = "progressContainer";
         | 
| 273 | 
            +
            	this.fileProgressElement.childNodes[3].className = "progressBarError";
         | 
| 274 | 
            +
            	this.fileProgressElement.childNodes[3].style.width = "";
         | 
| 275 | 
            +
             | 
| 276 | 
            +
            };
         | 
| 277 | 
            +
            FileProgress.prototype.setStatus = function (status) {
         | 
| 278 | 
            +
            	this.fileProgressElement.childNodes[2].innerHTML = status;
         | 
| 279 | 
            +
            };
         | 
| 280 | 
            +
             | 
| 281 | 
            +
            FileProgress.prototype.toggleCancel = function (show, swfuploadInstance) {
         | 
| 282 | 
            +
            	this.fileProgressElement.childNodes[0].style.visibility = show ? "visible" : "hidden";
         | 
| 283 | 
            +
            	if (swfuploadInstance) {
         | 
| 284 | 
            +
            		var fileID = this.fileProgressID;
         | 
| 285 | 
            +
            		this.fileProgressElement.childNodes[0].onclick = function () {
         | 
| 286 | 
            +
            			swfuploadInstance.cancelUpload(fileID);
         | 
| 287 | 
            +
            			return false;
         | 
| 288 | 
            +
            		};
         | 
| 289 | 
            +
            	}
         | 
| 290 | 
            +
            };
         | 
| @@ -1,5 +1,5 @@ | |
| 1 | 
            -
            gem 'warden', :version => '~> 0.5 | 
| 2 | 
            -
            gem 'devise', :version => '~> 0. | 
| 1 | 
            +
            gem 'warden', :version => '~> 0.6.5'
         | 
| 2 | 
            +
            gem 'devise', :version => '~> 0.7.1'
         | 
| 3 3 |  | 
| 4 4 | 
             
            rake 'gems:install'
         | 
| 5 5 | 
             
            generate "devise_install"
         | 
| @@ -13,8 +13,7 @@ add_after 'config/routes.rb', '# map.root :controller => "welcome"', "\n  map.ro | |
| 13 13 | 
             
            rake "db:migrate"
         | 
| 14 14 |  | 
| 15 15 | 
             
            file 'app/controllers/home_controller.rb' do
         | 
| 16 | 
            -
              %{
         | 
| 17 | 
            -
            class HomeController < ApplicationController
         | 
| 16 | 
            +
              %{class HomeController < ApplicationController
         | 
| 18 17 | 
             
              def index 
         | 
| 19 18 | 
             
                render :text => "Welcome!"
         | 
| 20 19 | 
             
              end
         | 
| @@ -0,0 +1,57 @@ | |
| 1 | 
            +
            # based on jnunemaker's gist at http://gist.github.com/232953
         | 
| 2 | 
            +
            file 'config/database.yml' do
         | 
| 3 | 
            +
              %{
         | 
| 4 | 
            +
            development: &global_settings
         | 
| 5 | 
            +
                database: #{project_name}_development
         | 
| 6 | 
            +
                host: 127.0.0.1
         | 
| 7 | 
            +
                port: 27017
         | 
| 8 | 
            +
               
         | 
| 9 | 
            +
            test:
         | 
| 10 | 
            +
              database: #{project_name}_test
         | 
| 11 | 
            +
              <<: *global_settings
         | 
| 12 | 
            +
             
         | 
| 13 | 
            +
            production:
         | 
| 14 | 
            +
              host: hostname
         | 
| 15 | 
            +
              database: databasename
         | 
| 16 | 
            +
              username: username
         | 
| 17 | 
            +
              password: password
         | 
| 18 | 
            +
              <<: *global_settings
         | 
| 19 | 
            +
            }
         | 
| 20 | 
            +
            end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            file 'config/initializers/mongo.rb' do
         | 
| 23 | 
            +
            %{
         | 
| 24 | 
            +
            config = YAML.load_file(Rails.root + 'config' + 'database.yml')[Rails.env]
         | 
| 25 | 
            +
             
         | 
| 26 | 
            +
            MongoMapper.connection = Mongo::Connection.new(config['host'], config['port'], {
         | 
| 27 | 
            +
              :logger => Rails.logger
         | 
| 28 | 
            +
            })
         | 
| 29 | 
            +
             
         | 
| 30 | 
            +
            MongoMapper.database = config['database']
         | 
| 31 | 
            +
            if config['username'].present?
         | 
| 32 | 
            +
              MongoMapper.database.authenticate(config['username'], config['password'])
         | 
| 33 | 
            +
            end
         | 
| 34 | 
            +
             
         | 
| 35 | 
            +
            Dir[Rails.root + 'app/models/**/*.rb'].each do |model_path|
         | 
| 36 | 
            +
              File.basename(model_path, '.rb').classify.constantize
         | 
| 37 | 
            +
            end
         | 
| 38 | 
            +
            MongoMapper.ensure_indexes!
         | 
| 39 | 
            +
             
         | 
| 40 | 
            +
            if defined?(PhusionPassenger)
         | 
| 41 | 
            +
              PhusionPassenger.on_event(:starting_worker_process) do |forked|
         | 
| 42 | 
            +
                # if using older than 0.6.5 of MM then you want database instead of connection
         | 
| 43 | 
            +
                # MongoMapper.database.connect_to_master if forked
         | 
| 44 | 
            +
                MongoMapper.connection.connect_to_master if forked
         | 
| 45 | 
            +
              end
         | 
| 46 | 
            +
            end
         | 
| 47 | 
            +
            }
         | 
| 48 | 
            +
            end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
            # for those who don't like keeping database.yml in version control
         | 
| 51 | 
            +
            # we slot in an example file to serve as reference
         | 
| 52 | 
            +
             | 
| 53 | 
            +
            FileUtils.copy "config/database.yml", "config/database.yml.example"
         | 
| 54 | 
            +
             | 
| 55 | 
            +
            environment 'config.frameworks -= [:active_record]'
         | 
| 56 | 
            +
             | 
| 57 | 
            +
            gem 'mongo_mapper'
         | 
| @@ -0,0 +1,305 @@ | |
| 1 | 
            +
            # lots of code and ideas borrowed from http://jetpackweb.com/blog/2009/10/21/rails-2-3-4-and-swfupload-rack-middleware-for-flash-uploads-that-degrade-gracefully/
         | 
| 2 | 
            +
            # setup directories to hold files
         | 
| 3 | 
            +
            FileUtils.mkdir_p 'public/javascripts/swfupload'
         | 
| 4 | 
            +
            FileUtils.mkdir_p 'public/flash/swfupload'
         | 
| 5 | 
            +
            FileUtils.mkdir_p 'public/images/swfupload'
         | 
| 6 | 
            +
            FileUtils.mkdir_p 'app/views/swfupload'
         | 
| 7 | 
            +
            FileUtils.mkdir_p 'app/stylesheets'
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            # download plugin files
         | 
| 10 | 
            +
            base_url = 'http://swfupload.googlecode.com/svn/swfupload/trunk/core/plugins'
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            js_files = %w(swfupload.cookies swfupload.queue swfupload.speed swfupload.swfobject handlers swfupload)
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            js_files.each do |js_file|
         | 
| 15 | 
            +
              run "curl -L #{base_url}/#{js_file}.js > public/javascripts/swfupload/#{js_file}.js"
         | 
| 16 | 
            +
            end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            run "curl -L http://github.com/jackdempsey/beet/raw/master/lib/beet/files/swfupload/js/handlers.js > public/javascripts/swfupload/handlers.js"
         | 
| 19 | 
            +
            run "curl -L http://swfupload.googlecode.com/svn/swfupload/trunk/core/swfupload.js > public/javascripts/swfupload/swfupload.js"
         | 
| 20 | 
            +
            run "curl -L http://swfupload.googlecode.com/svn/swfupload/trunk/core/Flash/swfupload.swf > public/flash/swfupload/swfupload.swf"
         | 
| 21 | 
            +
            run "chmod +x public/flash/swfupload/swfupload.swf"
         | 
| 22 | 
            +
            run "curl -L http://github.com/jackdempsey/beet/raw/master/lib/beet/files/swfupload/images/cancelbutton.gif > public/images/swfupload/cancelbutton.gif"
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            file 'app/stylesheets/swfupload.sass', <<-FILE
         | 
| 25 | 
            +
            divFileProgressContainer
         | 
| 26 | 
            +
              height: 75px
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            #divFileProgress
         | 
| 29 | 
            +
             | 
| 30 | 
            +
              .progressWrapper
         | 
| 31 | 
            +
                width: 100%
         | 
| 32 | 
            +
                overflow: hidden
         | 
| 33 | 
            +
             | 
| 34 | 
            +
              .progressContainer
         | 
| 35 | 
            +
                margin: 5px
         | 
| 36 | 
            +
                padding: 4px
         | 
| 37 | 
            +
                border: solid 1px #E8E8E8
         | 
| 38 | 
            +
                background-color: #F7F7F7
         | 
| 39 | 
            +
                overflow: hidden
         | 
| 40 | 
            +
                
         | 
| 41 | 
            +
              .progressName
         | 
| 42 | 
            +
                font-size: 8pt
         | 
| 43 | 
            +
                font-weight: 700
         | 
| 44 | 
            +
                color: #555
         | 
| 45 | 
            +
                width: 100%
         | 
| 46 | 
            +
                height: 14px
         | 
| 47 | 
            +
                text-align: left
         | 
| 48 | 
            +
                white-space: nowrap
         | 
| 49 | 
            +
                overflow: hidden
         | 
| 50 | 
            +
             | 
| 51 | 
            +
              .progressBarInProgress, .progressBarComplete, .progressBarError
         | 
| 52 | 
            +
                font-size: 0
         | 
| 53 | 
            +
                width: 0%
         | 
| 54 | 
            +
                height: 2px
         | 
| 55 | 
            +
                background-color: blue
         | 
| 56 | 
            +
                margin-top: 2px
         | 
| 57 | 
            +
                
         | 
| 58 | 
            +
              .progressBarComplete
         | 
| 59 | 
            +
                width: 100%
         | 
| 60 | 
            +
                background-color: green
         | 
| 61 | 
            +
                visibility: hidden
         | 
| 62 | 
            +
                
         | 
| 63 | 
            +
              .progressBarError
         | 
| 64 | 
            +
                width: 100%
         | 
| 65 | 
            +
                background-color: red
         | 
| 66 | 
            +
                visibility: hidden
         | 
| 67 | 
            +
             | 
| 68 | 
            +
              .progressBarStatus
         | 
| 69 | 
            +
                margin-top: 2px
         | 
| 70 | 
            +
                width: 337px
         | 
| 71 | 
            +
                font-size: 7pt
         | 
| 72 | 
            +
                font-family: Arial
         | 
| 73 | 
            +
                text-align: left
         | 
| 74 | 
            +
                white-space: nowrap
         | 
| 75 | 
            +
                  
         | 
| 76 | 
            +
              a.progressCancel
         | 
| 77 | 
            +
                font-size: 0
         | 
| 78 | 
            +
                display: block
         | 
| 79 | 
            +
                height: 14px
         | 
| 80 | 
            +
                width: 14px
         | 
| 81 | 
            +
                background-image: url(/images/swfupload/cancelbutton.gif)
         | 
| 82 | 
            +
                background-repeat: no-repeat
         | 
| 83 | 
            +
                background-position: -14px 0px
         | 
| 84 | 
            +
                float: right
         | 
| 85 | 
            +
             | 
| 86 | 
            +
              a.progressCancel:hover
         | 
| 87 | 
            +
                background-position: 0px 0px
         | 
| 88 | 
            +
            FILE
         | 
| 89 | 
            +
             | 
| 90 | 
            +
            # create upload partial
         | 
| 91 | 
            +
            file 'app/views/swfupload/_upload.html.haml', %q{
         | 
| 92 | 
            +
            - content_for :head do
         | 
| 93 | 
            +
              = javascript_include_tag 'swfupload/swfupload', 'swfupload/swfupload.swfobject', 'swfupload/handlers'
         | 
| 94 | 
            +
              = stylesheet_link_tag %w(compiled/swfupload)
         | 
| 95 | 
            +
            - session_key_name = ActionController::Base.session_options[:key]
         | 
| 96 | 
            +
             | 
| 97 | 
            +
            - upload_url = songs_path
         | 
| 98 | 
            +
            - form_tag upload_url, :multipart => true do
         | 
| 99 | 
            +
              #swfupload_degraded_container
         | 
| 100 | 
            +
                %noscript= "You should have Javascript enabled for a nicer upload experience"
         | 
| 101 | 
            +
                = file_field_tag :Filedata
         | 
| 102 | 
            +
                = submit_tag "Add a File"
         | 
| 103 | 
            +
              #swfupload_container{ :style => "display: none" }
         | 
| 104 | 
            +
                %span#spanButtonPlaceholder
         | 
| 105 | 
            +
              #divFileProgressContainer
         | 
| 106 | 
            +
             | 
| 107 | 
            +
             | 
| 108 | 
            +
            :javascript
         | 
| 109 | 
            +
              SWFUpload.onload = function() {
         | 
| 110 | 
            +
                var swf_settings = {
         | 
| 111 | 
            +
             | 
| 112 | 
            +
                  // SWFObject settings
         | 
| 113 | 
            +
                  minimum_flash_version: "9.0.28",
         | 
| 114 | 
            +
                  swfupload_pre_load_handler: function() {
         | 
| 115 | 
            +
                    $('#swfupload_degraded_container').hide();
         | 
| 116 | 
            +
                    $('#swfupload_container').show();
         | 
| 117 | 
            +
                  },
         | 
| 118 | 
            +
                  swfupload_load_failed_handler: function() {
         | 
| 119 | 
            +
                  },
         | 
| 120 | 
            +
             | 
| 121 | 
            +
                  post_params: {
         | 
| 122 | 
            +
                    "#{session_key_name}": "#{cookies[session_key_name]}",
         | 
| 123 | 
            +
                    "authenticity_token": "#{form_authenticity_token}",
         | 
| 124 | 
            +
                  },
         | 
| 125 | 
            +
             | 
| 126 | 
            +
                  //upload_url: "#{upload_url}?#{session_key_name}="+encodeURIComponent("#{cookies[session_key_name]}")+"&authenticity_token="+encodeURIComponent("#{form_authenticity_token}"),
         | 
| 127 | 
            +
                  upload_url: "#{upload_url}",
         | 
| 128 | 
            +
                  flash_url: '/flash/swfupload/swfupload.swf',
         | 
| 129 | 
            +
             | 
| 130 | 
            +
                  //example below lets you scope to only allowing image uploads
         | 
| 131 | 
            +
                  //file_types: "*.jpg;*.jpeg;*.gif;*.png;",
         | 
| 132 | 
            +
                  file_types: "*",
         | 
| 133 | 
            +
                  file_types_description: "pictures",
         | 
| 134 | 
            +
                  file_size_limit: "20 MB",
         | 
| 135 | 
            +
             | 
| 136 | 
            +
                  button_placeholder_id: "spanButtonPlaceholder",
         | 
| 137 | 
            +
                  button_width: 380,
         | 
| 138 | 
            +
                  button_height: 32,
         | 
| 139 | 
            +
                  button_text : '<span class="button">Select Files <span class="buttonSmall">(10 MB Max)</span></span>',
         | 
| 140 | 
            +
                  button_text_style : '.button { font-family: Helvetica, Arial, sans-serif; font-size: 24pt; } .buttonSmall { font-size: 18pt; }',
         | 
| 141 | 
            +
                  button_text_top_padding: 0,
         | 
| 142 | 
            +
                  button_text_left_padding: 18,
         | 
| 143 | 
            +
                  button_window_mode: SWFUpload.WINDOW_MODE.TRANSPARENT,
         | 
| 144 | 
            +
                  button_cursor: SWFUpload.CURSOR.HAND,
         | 
| 145 | 
            +
                  file_queue_error_handler : fileQueueError,
         | 
| 146 | 
            +
                  file_dialog_complete_handler : fileDialogComplete,
         | 
| 147 | 
            +
                  upload_progress_handler : uploadProgress,
         | 
| 148 | 
            +
                  upload_error_handler : uploadError,
         | 
| 149 | 
            +
                  upload_success_handler : uploadSuccess,
         | 
| 150 | 
            +
                  upload_complete_handler : uploadComplete,
         | 
| 151 | 
            +
             | 
| 152 | 
            +
                  custom_settings : {
         | 
| 153 | 
            +
                    upload_target: "divFileProgressContainer"
         | 
| 154 | 
            +
                  }
         | 
| 155 | 
            +
                }
         | 
| 156 | 
            +
                var swf_upload = new SWFUpload(swf_settings);
         | 
| 157 | 
            +
              };
         | 
| 158 | 
            +
            }
         | 
| 159 | 
            +
             | 
| 160 | 
            +
            append_file 'config/initializers/session_store.rb', <<-FILE
         | 
| 161 | 
            +
            require 'rack/utils'
         | 
| 162 | 
            +
             
         | 
| 163 | 
            +
            class FlashSessionCookieMiddleware
         | 
| 164 | 
            +
              def initialize(app, session_key = '_session_id')
         | 
| 165 | 
            +
                @app = app
         | 
| 166 | 
            +
                @session_key = session_key
         | 
| 167 | 
            +
              end
         | 
| 168 | 
            +
                 
         | 
| 169 | 
            +
              def call(env)
         | 
| 170 | 
            +
                if env['HTTP_USER_AGENT'] =~ /^(Adobe|Shockwave) Flash/
         | 
| 171 | 
            +
                  params = ::Rack::Request.new(env).params
         | 
| 172 | 
            +
                  env['HTTP_COOKIE'] = [ @session_key, params[@session_key] ].join('=').freeze unless params[@session_key].nil?
         | 
| 173 | 
            +
                end
         | 
| 174 | 
            +
                @app.call(env)
         | 
| 175 | 
            +
              end
         | 
| 176 | 
            +
            end
         | 
| 177 | 
            +
             | 
| 178 | 
            +
            ActionController::Dispatcher.middleware.insert_before(ActionController::Base.session_store, FlashSessionCookieMiddleware, ActionController::Base.session_options[:key])
         | 
| 179 | 
            +
            FILE
         | 
| 180 | 
            +
             | 
| 181 | 
            +
            # example Song resource for those who want it
         | 
| 182 | 
            +
            controller_file = <<-FILE
         | 
| 183 | 
            +
            class SongsController < ApplicationController
         | 
| 184 | 
            +
              layout 'swfupload'
         | 
| 185 | 
            +
             | 
| 186 | 
            +
              def index
         | 
| 187 | 
            +
                @songs = Song.all
         | 
| 188 | 
            +
              end
         | 
| 189 | 
            +
             | 
| 190 | 
            +
              def create
         | 
| 191 | 
            +
                require 'mime/types'
         | 
| 192 | 
            +
                mp3_info = Mp3Info.new(params[:Filedata].path)
         | 
| 193 | 
            +
             | 
| 194 | 
            +
                song = Song.new
         | 
| 195 | 
            +
                song.artist = mp3_info.tag.artist
         | 
| 196 | 
            +
                song.title = mp3_info.tag.title
         | 
| 197 | 
            +
                song.length_in_seconds = mp3_info.length.to_i
         | 
| 198 | 
            +
             | 
| 199 | 
            +
                params[:Filedata].content_type = MIME::Types.type_for(params[:Filedata].original_filename).to_s
         | 
| 200 | 
            +
                song.track = params[:Filedata]
         | 
| 201 | 
            +
                song.save
         | 
| 202 | 
            +
             | 
| 203 | 
            +
                render :text => [song.artist, song.title, song.convert_seconds_to_time].join(" - ")
         | 
| 204 | 
            +
              rescue Mp3InfoError => e
         | 
| 205 | 
            +
                render :text => "File error"
         | 
| 206 | 
            +
              rescue Exception => e
         | 
| 207 | 
            +
                render :text => e.message
         | 
| 208 | 
            +
              end
         | 
| 209 | 
            +
            end
         | 
| 210 | 
            +
            FILE
         | 
| 211 | 
            +
             | 
| 212 | 
            +
             | 
| 213 | 
            +
            model_file = <<-FILE
         | 
| 214 | 
            +
            class Song < ActiveRecord::Base
         | 
| 215 | 
            +
             
         | 
| 216 | 
            +
              has_attached_file :track
         | 
| 217 | 
            +
             
         | 
| 218 | 
            +
            #  validates_presence_of :title, :artist, :length_in_seconds
         | 
| 219 | 
            +
              validates_attachment_presence :track
         | 
| 220 | 
            +
              validates_attachment_content_type :track, :content_type => [ 'application/mp3', 'application/x-mp3', 'audio/mpeg', 'audio/mp3' ]
         | 
| 221 | 
            +
              validates_attachment_size :track, :less_than => 20.megabytes
         | 
| 222 | 
            +
             
         | 
| 223 | 
            +
              attr_accessible :title, :artist, :length_in_seconds
         | 
| 224 | 
            +
             | 
| 225 | 
            +
              def convert_seconds_to_time
         | 
| 226 | 
            +
                total_minutes = length_in_seconds / 1.minutes
         | 
| 227 | 
            +
                seconds_in_last_minute = length_in_seconds - total_minutes.minutes.seconds
         | 
| 228 | 
            +
                "\#{total_minutes}m \#{seconds_in_last_minute}s"
         | 
| 229 | 
            +
              end
         | 
| 230 | 
            +
             | 
| 231 | 
            +
             
         | 
| 232 | 
            +
            end
         | 
| 233 | 
            +
            FILE
         | 
| 234 | 
            +
             | 
| 235 | 
            +
            view_file = <<-FILE
         | 
| 236 | 
            +
            %h1 Songs
         | 
| 237 | 
            +
             | 
| 238 | 
            +
            - @songs.each do |song|
         | 
| 239 | 
            +
              %p= song.title
         | 
| 240 | 
            +
             | 
| 241 | 
            +
            = render 'swfupload/upload'
         | 
| 242 | 
            +
            FILE
         | 
| 243 | 
            +
             | 
| 244 | 
            +
            migration_file = <<-FILE
         | 
| 245 | 
            +
            class CreateSongs < ActiveRecord::Migration
         | 
| 246 | 
            +
              def self.up
         | 
| 247 | 
            +
                create_table :songs do |t|
         | 
| 248 | 
            +
                  t.string :artist
         | 
| 249 | 
            +
                  t.string :title
         | 
| 250 | 
            +
                  t.integer :length_in_seconds
         | 
| 251 | 
            +
                  t.string :track_file_name
         | 
| 252 | 
            +
                  t.string :track_content_type
         | 
| 253 | 
            +
                  t.integer :track_file_size
         | 
| 254 | 
            +
                  t.timestamps
         | 
| 255 | 
            +
                end
         | 
| 256 | 
            +
              end
         | 
| 257 | 
            +
             | 
| 258 | 
            +
              def self.down
         | 
| 259 | 
            +
                drop_table :songs
         | 
| 260 | 
            +
              end
         | 
| 261 | 
            +
            end
         | 
| 262 | 
            +
            FILE
         | 
| 263 | 
            +
             | 
| 264 | 
            +
            layout_file = <<-FILE
         | 
| 265 | 
            +
            !!! Strict
         | 
| 266 | 
            +
            %html
         | 
| 267 | 
            +
              %head
         | 
| 268 | 
            +
                %title
         | 
| 269 | 
            +
                  = h(yield(:title) || "Untitled")
         | 
| 270 | 
            +
                = '<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"></script>'
         | 
| 271 | 
            +
                = '<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery-ui.min.js"></script>'
         | 
| 272 | 
            +
                = yield(:head)
         | 
| 273 | 
            +
              %body
         | 
| 274 | 
            +
                #container
         | 
| 275 | 
            +
                  = yield
         | 
| 276 | 
            +
            FILE
         | 
| 277 | 
            +
             | 
| 278 | 
            +
            puts '=' * 80
         | 
| 279 | 
            +
            if yes? "Create an example resource using Paperclip? (y/n)"
         | 
| 280 | 
            +
              FileUtils.mkdir_p 'app/views/songs'
         | 
| 281 | 
            +
              FileUtils.mkdir_p 'public/stylesheets/compiled'
         | 
| 282 | 
            +
             | 
| 283 | 
            +
              file 'app/views/layouts/swfupload.html.haml', layout_file
         | 
| 284 | 
            +
              file 'app/controllers/songs_controller.rb', controller_file
         | 
| 285 | 
            +
              file 'app/models/song.rb', model_file
         | 
| 286 | 
            +
              file 'app/views/songs/index.html.haml', view_file
         | 
| 287 | 
            +
             | 
| 288 | 
            +
              generate "migration", "create_songs"
         | 
| 289 | 
            +
              filename = Dir['db/migrate/*create_songs.rb'].first
         | 
| 290 | 
            +
              file filename, migration_file
         | 
| 291 | 
            +
              rake "db:migrate"
         | 
| 292 | 
            +
             | 
| 293 | 
            +
              gem 'paperclip'
         | 
| 294 | 
            +
              gem 'haml'
         | 
| 295 | 
            +
              gem 'ruby-mp3info', :lib => 'mp3info'
         | 
| 296 | 
            +
             | 
| 297 | 
            +
              run "sass app/stylesheets/swfupload.sass > public/stylesheets/compiled/swfupload.css"
         | 
| 298 | 
            +
             | 
| 299 | 
            +
              route 'map.resources :songs'
         | 
| 300 | 
            +
             | 
| 301 | 
            +
              puts "Now fire up the app and go to /songs to test it out!"
         | 
| 302 | 
            +
            else
         | 
| 303 | 
            +
              puts "\nYour controller should have a create action that looks something like this:\n#{controller_file}"
         | 
| 304 | 
            +
              puts "\nYou can create a model that looks like this:\n#{model_file}"
         | 
| 305 | 
            +
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification 
         | 
| 2 2 | 
             
            name: beet
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            -
              version: 0.4. | 
| 4 | 
            +
              version: 0.4.3
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors: 
         | 
| 7 7 | 
             
            - Jack Dempsey
         | 
| @@ -9,7 +9,7 @@ autorequire: | |
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 11 |  | 
| 12 | 
            -
            date:  | 
| 12 | 
            +
            date: 2010-01-09 00:00:00 -05:00
         | 
| 13 13 | 
             
            default_executable: beet
         | 
| 14 14 | 
             
            dependencies: 
         | 
| 15 15 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| @@ -51,6 +51,10 @@ files: | |
| 51 51 | 
             
            - lib/beet/execution.rb
         | 
| 52 52 | 
             
            - lib/beet/executor.rb
         | 
| 53 53 | 
             
            - lib/beet/file_system.rb
         | 
| 54 | 
            +
            - lib/beet/files/swfupload/images/cancelbutton.gif
         | 
| 55 | 
            +
            - lib/beet/files/swfupload/images/header-bg.jpg
         | 
| 56 | 
            +
            - lib/beet/files/swfupload/images/logo.gif
         | 
| 57 | 
            +
            - lib/beet/files/swfupload/js/handlers.js
         | 
| 54 58 | 
             
            - lib/beet/gem_location_map.rb
         | 
| 55 59 | 
             
            - lib/beet/interaction.rb
         | 
| 56 60 | 
             
            - lib/beet/logger.rb
         | 
| @@ -66,10 +70,12 @@ files: | |
| 66 70 | 
             
            - lib/beet/recipes/rails/css/blueprint.rb
         | 
| 67 71 | 
             
            - lib/beet/recipes/rails/css/nifty_layout.rb
         | 
| 68 72 | 
             
            - lib/beet/recipes/rails/css/reset.rb
         | 
| 73 | 
            +
            - lib/beet/recipes/rails/db/mongo.rb
         | 
| 69 74 | 
             
            - lib/beet/recipes/rails/db/mysql.rb
         | 
| 70 75 | 
             
            - lib/beet/recipes/rails/db/postgres.rb
         | 
| 71 76 | 
             
            - lib/beet/recipes/rails/git.rb
         | 
| 72 77 | 
             
            - lib/beet/recipes/rails/jquery.rb
         | 
| 78 | 
            +
            - lib/beet/recipes/rails/swfupload.rb
         | 
| 73 79 | 
             
            - lib/beet/recipes/rails/testing/rspec.rb
         | 
| 74 80 | 
             
            - lib/beet/recipes/rails/testing/shoulda.rb
         | 
| 75 81 | 
             
            - lib/beet/scm.rb
         |