Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

A long dump of changes (had to develop behind a curtain for various r…

…easons, and failed to do the right thing re: small pushes). Things brings the source up to parity with the dropmocks.com web service.
  • Loading branch information...
commit b63c97a386c9cfcb2014cd6e48a629954db501b3 1 parent 56140b1
@glenmurphy authored
View
0  files/__init__.py
No changes.
View
BIN  files/delete.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
19 files/editor.css
@@ -24,7 +24,7 @@
}
.dm-editor .listname {
cursor:pointer;
- width:180px;
+ width:164px;
}
.title .delete {
position:absolute;
@@ -43,6 +43,23 @@
.title .delete:hover {
background-position:-16 -16;
}
+.title .minimize {
+ position:absolute;
+ right:24px;
+ top:50%;
+ margin-top:-8px;
+ display:inline;
+ background-image:url(/s/delete.png);
+ background-position:-32 0;
+ background-repeat:no-repeat;
+ overflow:hidden;
+ width:16px;
+ height:16px;
+ cursor:pointer;
+}
+.title .minimize:hover {
+ background-position:-32 -16;
+}
.dm-editor .listname:hover {
background-color:#fff9c2;
}
View
14 files/editor.js
@@ -11,12 +11,19 @@ function Editor(mocklist) {
var delete_button = createElement('div', 'delete', this.node_title_);
addEventListener(delete_button, 'click', this.titleDeleteClicked_.bind(this));
+ var minimize_button = createElement('div', 'minimize', this.node_title_);
+ addEventListener(minimize_button, 'click', this.titleClicked_.bind(this));
addEventListener(this.node_name_, 'click', this.nameClicked_.bind(this));
this.node_body_ = createElement('div', 'body', this.node_);
this.node_filelist_ = createElement('div', 'filelist', this.node_body_);
this.node_insert_ = createElement('div', 'insert-indicator', this.node_);
+
+ this.node_access_url_ = createElement('div', 'access-url', this.node_body_);
+ this.node_access_url_.style.display = 'none';
+ //this.node_hider_ = createElement('div', 'hider', this.node_body_);
+ //setText(this.node_hider_, "Hide editor");
// Sometimes we have to do things (such as get a mocklist id and key)
// before we can send the file.
@@ -40,7 +47,7 @@ function Editor(mocklist) {
}
this.node_status_ = createElement('div', 'dm-editor-status hidden', document.body);
-
+
addEventListener(document.body, 'dragover', this.dragOver_.bind(this));
addEventListener(document.body, 'dragenter', this.dragEnter_.bind(this));
addEventListener(document.body, 'dragleave', this.dragLeave_.bind(this));
@@ -340,9 +347,8 @@ Editor.prototype.fileDropped = function(e) {
}
Editor.prototype.showAccessURL_ = function(url) {
- if (!this.node_access_url_)
- this.node_access_url_ = createElement('div', 'access-url', this.node_body_);
-
+ this.node_access_url_.style.display = 'block';
+
//var full_url = window.location.protocol + '//' + window.location.host + url
var full_url = 'http://dropmocks.com' + url;
this.node_access_url_.innerHTML = 'Share this URL: <a href="' + full_url + '">' + full_url + '</a>';
View
10 files/functions.js
@@ -14,12 +14,20 @@ Function.prototype.bind = function(thisObj, var_args) {
function createElement(type, className, parent) {
var el = document.createElement(type);
- document.
el.className = className;
if (parent) parent.appendChild(el);
return el;
}
+function getPosition(obj) {
+ var pos = {x : 0, y : 0}
+ do {
+ pos.x += obj.offsetLeft;
+ pos.y += obj.offsetTop;
+ } while (obj = obj.offsetParent);
+ return pos;
+}
+
function min(a, b) { return (a < b) ? a : b; }
if (!('console' in window)) {
window.console = [];
View
83 files/menu.css
@@ -1,7 +1,6 @@
-
.home {
position:absolute;
- bottom:1px;
+ top:1px;
right:0px;
padding:5px;
z-index:10000;
@@ -10,8 +9,40 @@
.home .menuitem {
margin-left:12px;
}
+.home .menulink {
+ display:inline-block;
+ cursor:pointer;
+ margin-left:12px;
+ color:#999;
+}
+
+.leftbar {
+ position:absolute;
+ top:1px;
+ left:0px;
+ padding:5px;
+ z-index:10000;
+ -webkit-transition:all 0.2s;
+}
+.rightbar {
+ position:absolute;
+ top:1px;
+ right:0px;
+ padding:5px;
+ z-index:1;
+ -webkit-transition:all 0.2s;
+}
+.leftbar .menuitem {
+ margin-right:9px;
+}
+.leftbar .menulink {
+ display:inline-block;
+ cursor:pointer;
+ margin-right:12px;
+ color:#999;
+}
-.home .button {
+.button {
background: #75B5F4;
background: -moz-linear-gradient(top, #75B5F4 0%, #5BA3EA 44%, #3A89D8 100%); /* firefox */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#75B5F4), color-stop(44%,#5BA3EA), color-stop(100%,#3A89D8)); /* webkit */
@@ -35,9 +66,10 @@
cursor:pointer;
text-decoration:none;
display:inline-block;
+ color:white;
}
-.home .button:hover {
+.button:hover {
background: #7ABEFF; /* old browsers */
background: -moz-linear-gradient(top, #7ABEFF 0%, #5BA3EA 44%, #3884D1 100%); /* firefox */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#7ABEFF), color-stop(44%,#5BA3EA), color-stop(100%,#3884D1)); /* webkit */
@@ -49,7 +81,7 @@
-webkit-box-shadow: inset 0 1px 0 0 #7abdff, 0px 1px 2px rgba(0,0,0,0.3);;
}
-.home .button:active {
+.button:active {
background: #75B5F4;
background: -moz-linear-gradient(top, #75B5F4 0%, #5BA3EA 44%, #3A89D8 100%); /* firefox */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#75B5F4), color-stop(44%,#5BA3EA), color-stop(100%,#3A89D8)); /* webkit */
@@ -62,16 +94,39 @@
-webkit-box-shadow: inset 1px 1px 1px 1px rgba(0, 0, 0, 0.1);
}
-.sharebar {
+.list {
+ display:block;
position:absolute;
- bottom:1px;
- left:0px;
- padding:5px;
- z-index:10000;
- -webkit-transition:all 0.2s;
+ border:1px solid black;
+ z-index:2000;
+ background-color:white;
+ font-family:helvetica, arial, sans-serif;
+ font-size:12px;
+ border:1px solid rgba(0,0,0,0.5);
+ padding:3px 6px 3px 8px;
+ margin-top:2px;
+ margin-left:-9px;
+ -webkit-box-shadow:1px 1px 4px rgba(0, 0, 0, 0.3);
+ -webkit-transition:-webkit-transform 0.2s, opacity 0.2s;
+ line-height:23px;
+ min-width:160px;
+}
+.list.hidden {
+ -webkit-transform:translate(0px, -5px);
+ opacity:0;
+ pointer-events:none;
}
-.sharebar div {
- display:inline-block;
- margin-right:12px;
+.listitem {
+ display:block;
+ text-decoration:none;
+ color:#666;
+}
+.listitem.selected {
+ font-weight:bold;
+ color:black;
+}
+.listitem:hover {
+ color:black;
+ text-decoration:underline;
}
View
65 files/menu.js
@@ -1,6 +1,6 @@
function Menu(mocklist, user) {
this.page_mocklist_ = mocklist;
- this.page_mocklist_.addListener(this.mockListListener_.bind(this));
+ this.page_mocklist_.addListener(this.mockListListener_.bind(this), false);
this.signed_in_ = user.signed_in;
// Doesn't contain valid mocklist data, just id and name.
@@ -12,41 +12,50 @@ function Menu(mocklist, user) {
// Edit controls (right side).
this.node_ = createElement('div', 'home', document.body);
- this.node_new_ = createElement('a', 'menuitem', this.node_);
- this.node_new_.href = '/';
-
- this.node_menu_ = createElement('select', 'menuitem', this.node_);
+ /*
var opt = new Option("Your mocks:", "", false, false);
this.node_menu_.options[this.node_menu_.length] = opt;
addEventListener(this.node_menu_, 'change', this.menuChanged_.bind(this));
+ */
+
+ this.node_left_ = createElement('div', 'leftbar', document.body);
+ this.node_right_ = createElement('div', 'rightbar', document.body);
+
+ this.node_new_ = createElement('a', 'menuitem', this.node_left_);
+ this.node_new_.href = '/';
if (this.signed_in_) {
this.node_name_ = createElement('a', 'menuitem', this.node_);
setText(this.node_name_, this.username_);
- this.node_sign_ = createElement('a', 'menuitem', this.node_);
+ this.node_sign_ = createElement('a', 'menulink', this.node_left_);
this.node_sign_.href = this.sign_out_url_;
setText(this.node_sign_, "Sign out");
} else {
- this.node_sign_ = createElement('a', 'menuitem button', this.node_);
+ this.node_sign_ = createElement('a', 'menulink', this.node_left_);
this.node_sign_.href = this.sign_in_url_;
this.node_new_.className = 'menuitem button';
setText(this.node_sign_, "Sign in");
- }
+ }
+
+ this.node_menu_ = new MenuMocks('Your mocks', this.node_left_);
- // Sharing bar (left side).
- this.node_share_ = createElement('div', 'sharebar', document.body);
+ //this.node_about_ = createElement('a', 'menulink', this.node_left_);
+ //setText(this.node_about_, 'About');
+ // this.node_about_.href = '#';
+ //this.node_about_.addEventListener("click", this.handleAbout_.bind(this), false);
+
- this.node_tweet_ = createElement('div', '', this.node_share_);
+ this.node_tweet_ = createElement('div', 'menuitem', this.node_right_);
this.node_tweet_.innerHTML = '<a href="http://twitter.com/share" class="twitter-share-button" data-text="I liked this gallery on dropmocks:" data-count="none">Share on Twitter</a>';
var twitter_script = document.createElement('script');
twitter_script.async = true;
twitter_script.src = 'http://platform.twitter.com/widgets.js';
twitter_script.defer = true;
- this.node_share_.appendChild(twitter_script);
-
+ this.node_right_.appendChild(twitter_script);
+
this.update_();
}
@@ -68,6 +77,10 @@ Menu.prototype.mockListListener_ = function(e) {
}
}
+Menu.prototype.handleAbout_ = function(e) {
+ e.preventDefault();
+}
+
Menu.prototype.getMockListById = function(id) {
for (var i = 0, mocklist; mocklist = this.mocklists_[i]; i++) {
if (mocklist.id == id) {
@@ -78,10 +91,9 @@ Menu.prototype.getMockListById = function(id) {
}
Menu.prototype.update_ = function() {
- window.console.log("Menu updating");
-
this.node_new_.style.display = (this.page_mocklist_.id) ? 'inline-block' : 'none';
- this.node_share_.style.display = (this.page_mocklist_.id) ? 'block' : 'none';
+ //this.node_left_.style.display = (this.page_mocklist_.id) ? 'block' : 'none';
+ this.node_right_.style.display = (this.page_mocklist_.key || !this.page_mocklist_.id) ? 'none' : 'block';
if (this.signed_in_ || this.page_mocklist_.key) {
setText(this.node_new_, 'New');
@@ -91,20 +103,25 @@ Menu.prototype.update_ = function() {
// this.node_sign_.style.display = 'none';
}
- this.node_menu_.options.length = 1;
- for (var i = 0, mocklist; mocklist = this.mocklists_[i]; i++) {
- var selected = (mocklist.id == this.page_mocklist_.id);
- var name = mocklist.name ? mocklist.name : mocklist.id;
- var opt = new Option(name, mocklist.id, selected, selected);
- this.node_menu_.options[this.node_menu_.length] = opt;
+ this.node_menu_.clearItems();
+ if (this.mocklists_.length == 0) {
+ this.node_menu_.setVisible(false);
+ } else {
+ for (var i = 0, mocklist; mocklist = this.mocklists_[i]; i++) {
+ var selected = (mocklist.id == this.page_mocklist_.id);
+ var name = mocklist.name ? mocklist.name : mocklist.id;
+ this.node_menu_.addItem(name, '/m' + mocklist.id, selected);
+ }
+ this.node_menu_.setVisible(true);
}
// this.node_menu_.style.display = (this.mocklists_.length) ? 'inline-block' : 'none';
}
-
+/*
Menu.prototype.menuChanged_ = function() {
var v = this.node_menu_.value;
if (v) {
window.location.href = MockList.URL_VIEWER_BASE + v;
}
-}
+}
+*/
View
60 files/menumocks.js
@@ -0,0 +1,60 @@
+function MenuMocks(title, container) {
+ this.node_ = createElement('a', 'menulink');
+ //this.node_.href = '#';
+ this.node_.addEventListener('click', this.handleMenuClick_.bind(this), false);
+ window.addEventListener('resize', this.updatePosition.bind(this), false);
+ setText(this.node_, title);
+ container.appendChild(this.node_);
+
+ this.node_list_ = createElement('div', 'list hidden');
+ document.body.appendChild(this.node_list_);
+ document.body.addEventListener('click', this.handleBodyClick_.bind(this), false);
+ this.items_ = [];
+ this.updatePosition();
+}
+
+MenuMocks.prototype.updatePosition = function() {
+ var pos = getPosition(this.node_);
+ this.node_list_.style.top = pos.y + this.node_.offsetHeight - 4;
+ this.node_list_.style.left = pos.x;
+};
+
+MenuMocks.prototype.clearItems = function() {
+ this.node_list_.innerHTML = '';
+ this.items_ = [];
+};
+
+MenuMocks.prototype.setVisible = function(visible) {
+ this.node_.style.display = visible ? 'inline-block' : 'none';
+};
+
+MenuMocks.prototype.addItem = function(name, url, selected) {
+ var a = createElement('a', 'listitem' + (selected ? ' selected' : ''), this.node_list_);
+ a.href = url;
+ setText(a, name);
+ this.updatePosition();
+};
+
+// private:
+MenuMocks.prototype.handleMenuClick_ = function(e) {
+ if (this.node_list_.className == 'list hidden') {
+ this.showList_();
+ } else {
+ this.hideList_();
+ }
+ this.updatePosition();
+ e.preventDefault();
+};
+
+MenuMocks.prototype.showList_ = function() {
+ this.node_list_.className = 'list';
+};
+
+MenuMocks.prototype.hideList_ = function() {
+ this.node_list_.className = 'list hidden';
+};
+
+MenuMocks.prototype.handleBodyClick_ = function(e) {
+ if (e.target != this.node_)
+ this.hideList_();
+};
View
92 files/mock.js
@@ -19,6 +19,8 @@ function Mock(mocklist) {
Mock.EVENT_LOADED = 0;
Mock.EVENT_UPLOADED = 1;
Mock.EVENT_DELETED = 2;
+Mock.EVENT_UPLOAD_START = 3;
+Mock.EVENT_UPLOAD_PROGRESS = 4;
Mock.unknownFileCount = 1;
Mock.generateUnknownFileName = function() {
@@ -130,6 +132,7 @@ Mock.blurImage = function(image, amount, width, height) {
// Firefox 3 fails at putImageData - I suspect the blur
// algorithm may be to blame, however (clamping dstPixels
// causes all sorts of tomfoolery).
+
if (isValidBrowser() && BrowserDetect.version >= 4) {
// Create the canvas.
var canvas = document.createElement('canvas');
@@ -149,16 +152,21 @@ Mock.blurImage = function(image, amount, width, height) {
scaled_width, scaled_height);
// Blur the image.
+
+ // Blurring is horked by fast image serving.
var img = ctx.getImageData(0, 0, canvas.width, canvas.height);
img = Mock.blur(img, amount);
ctx.putImageData(img, 0, 0);
-
+ return canvas;
+ /*
// Export the image.
var new_image = new Image();
new_image.src = canvas.toDataURL();
canvas = null;
return new_image;
+ */
}
+
window.console.log("Blurring failed");
var img = new Image();
img.src = image.src;
@@ -210,6 +218,10 @@ Mock.prototype.setID = function(id) {
this.id = id;
}
+Mock.prototype.setServingURL = function(url) {
+ this.serving_url = url;
+}
+
Mock.prototype.setName = function(name) {
this.name = name;
}
@@ -245,61 +257,81 @@ Mock.prototype.loadLocalFileComplete_ = function(e) {
Mock.prototype.loadImageComplete_ = function(e) {
window.console.log("Load mock complete");
- this.generateThumb_();
+ setTimeout(this.generateThumb_.bind(this), 1);
}
Mock.prototype.generateThumb_ = function() {
this.thumb = Mock.blurImage(this.image, 7, 240, 240);
- // Similar to loadFileComplete, we need to give the image time to
- // do whatever it does before going off and using it, otherwise it
- // will give strange results for image.width etc.
- /*
- if (this.thumb.src.length < 600 && this.thumb_attempts_ < 3) {
- window.console.log("Failed thumbnailing attempt");
- this.thumb_attempts_++;
- setTimeout(this.generateThumb_.bind(this), 1);
- } else {
- */
this.loaded = true;
window.console.log("Thumbnail generation complete");
setTimeout(this.callListeners_.bind(this, {
type : Mock.EVENT_LOADED,
data : this
}), 1);
-}
-
+};
// SAVING
Mock.prototype.saveFile_ = function() {
if (!this.file_ || this.id) return;
window.console.log("Saving '" + this.name + "' ...");
+ // Modern browsers.
var req = new XMLHttpRequest();
- req.open("POST", MockList.URL_FILE_UPLOAD +
- '?id=' + this.mocklist_.id +
- '&key=' + this.mocklist_.key +
- '&filename=' + this.name
- , true);
- req.upload.addEventListener("progress", this.saveFileProgress_.bind(this), false);
- req.upload.addEventListener("load", this.saveFileComplete_.bind(this), false);
- req.upload.addEventListener("error", this.saveFileError_.bind(this), false);
- req.onreadystatechange = this.saveFileResult_.bind(this, req);
-
+
if (typeof FormData != 'undefined') {
- var form_data = new FormData();
- form_data.append('file', this.file_);
- req.send(form_data);
+ req.open("GET", MockList.URL_GET_UPLOAD_URL +
+ '?id=' + this.mocklist_.id +
+ '&key=' + this.mocklist_.key +
+ '&filename=' + this.name, true);
+ req.onreadystatechange = this.getUploadURLResult_.bind(this, req);
+ req.send();
} else {
// Firefox3
+ req.open("POST", MockList.URL_FILE_UPLOAD +
+ '?id=' + this.mocklist_.id +
+ '&key=' + this.mocklist_.key +
+ '&filename=' + this.name, true);
+ req.upload.addEventListener("progress", this.saveFileProgress_.bind(this), false);
+ req.upload.addEventListener("load", this.saveFileComplete_.bind(this), false);
+ req.upload.addEventListener("error", this.saveFileError_.bind(this), false);
+ req.onreadystatechange = this.saveFileResult_.bind(this, req);
+
var reader = new FileReader();
reader.onerror = function(e) {window.console.log("File read error");}
reader.onload = function(e) {
window.console.log("File data loaded, uploading...");
req.sendAsBinary(e.target.result);
}
- reader.readAsBinaryString(this.file_);
+ reader.readAsBinaryString(this.file_);
+ }
+ this.callListeners_({
+ type : Mock.EVENT_UPLOAD_START
+ });
+};
+
+
+Mock.prototype.getUploadURLResult_ = function(req) {
+ if (req.readyState == 4 && req.status == 200) {
+ var data = JSON.parse(req.responseText);
+ window.console.log("Got url:" + data.url);
+ this.uploadFile_(data.url);
}
+};
+
+Mock.prototype.uploadFile_ = function(url) {
+ window.console.log("Uploading to " + url);
+ url = url ? url : MockList.URL_FILE_UPLOAD;
+ var req = new XMLHttpRequest();
+ req.open("POST", url, true);
+ req.upload.addEventListener("progress", this.saveFileProgress_.bind(this), false);
+ req.upload.addEventListener("load", this.saveFileComplete_.bind(this), false);
+ req.upload.addEventListener("error", this.saveFileError_.bind(this), false);
+ req.onreadystatechange = this.saveFileResult_.bind(this, req);
+
+ var form_data = new FormData();
+ form_data.append('file', this.file_);
+ req.send(form_data);
}
Mock.prototype.saveFileProgress_ = function(e) {
@@ -309,7 +341,7 @@ Mock.prototype.saveFileProgress_ = function(e) {
window.console.log(percent);
this.callListeners_({
- type : Mock.EVENT_PROGRESS,
+ type : Mock.EVENT_UPLOAD_PROGRESS,
data : percent
});
}
@@ -318,7 +350,7 @@ Mock.prototype.saveFileComplete_ = function(e) {
window.console.log("File upload complete");
this.callListeners_({
- type : Mock.EVENT_PROGRESS,
+ type : Mock.EVENT_UPLOAD_PROGRESS,
data : 100
});
}
View
17 files/mocklist.js
@@ -49,7 +49,8 @@ MockList.REORDER_BEFORE = 21;
MockList.REORDER_AFTER = 22;
MockList.URL_GETID = '/api/getid/';
-MockList.URL_FILE_UPLOAD = '/api/savemock/';
+MockList.URL_FILE_UPLOAD = '/api/savemockff3/';
+MockList.URL_GET_UPLOAD_URL = '/api/getuploadurl/';
MockList.URL_FILE_DELETE = '/api/deletemock/';
MockList.URL_SAVE = '/api/savemocklist/';
MockList.URL_MOCK = '/i'; // no trailing slash
@@ -168,7 +169,11 @@ MockList.prototype.newLocalFiles = function(files, dropmock, order) {
// Verify that they're images and add the files.
for (var i = 0, file; file = files[i]; i++) {
- if (MockList.isImage(file) && file.size < 900000) {
+ var max_size = 950000;
+ if (typeof FormData != 'undefined') {
+ max_size = 3000000;
+ }
+ if (MockList.isImage(file) && file.size < max_size) {
var mock = new Mock(this);
mock.setFile(file);
new_mocks.push(mock);
@@ -177,8 +182,12 @@ MockList.prototype.newLocalFiles = function(files, dropmock, order) {
var error = '';
if (!MockList.isImage(file))
error = "not an image";
- else if (file.size >= 900000)
- error = "exceeds 900KB";
+ else if (file.size >= max_size) {
+ error = "xceeds "+(max_size/1000000)+" MB";
+ if (typeof FormData == 'undefined') {
+ error = "exceeds your browser's upload limit."
+ }
+ }
errors.push(file.name + ' (' + error + ')');
}
}
View
6 files/presenter.css
@@ -8,8 +8,8 @@
}
.presentation ::selection { background: transparent; }
.scene {
- position:absolute;
-webkit-transition:all 0.3s;
+ position:absolute;
-moz-transition:all 0.3s;
}
.mocknode {
@@ -42,12 +42,12 @@
position:absolute;
}
.mocknode .thumb {
+ -webkit-transition:all 0.3s;
+ -moz-transition:all 0.3s;
position:absolute;
opacity:0.5;
filter: alpha(opacity=50)
progid:DXImageTransform.Microsoft.Blur(pixelradius=7);
- -webkit-transition:all 0.3s;
- -moz-transition:all 0.3s;
border:1px solid transparent;
}
View
10 files/presenter.js
@@ -16,7 +16,7 @@ Presenter.SPACING = 250;
Presenter.SELECTED_OVERLAP = 50;
Presenter.SMALL_WIDTH = 240;
Presenter.SMALL_HEIGHT = 240;
-Presenter.MIN_EDGE_SPACING = 35;
+Presenter.MIN_EDGE_SPACING = 40;
Presenter.scale = function(node, scale) {
if (BrowserDetect.browser == "Explorer" && BrowserDetect.version <= 8) {
@@ -69,7 +69,7 @@ Presenter.prototype.mockListListener = function(e) {
Presenter.prototype.createNode_ = function(mock) {
// This probably causes layout.
var cx = this.node_.offsetWidth / 2;
- var cy = this.node_.offsetHeight / 2 - Presenter.MIN_EDGE_SPACING / 2;
+ var cy = this.node_.offsetHeight / 2;
var mock_node = createElement('div', 'mocknode');
addEventListener(mock_node, 'click', this.imageClicked_.bind(this, mock));
@@ -98,8 +98,8 @@ Presenter.prototype.createNode_ = function(mock) {
mock_node.thumb.natural_width = mock.thumb.width;
mock_node.thumb.natural_height = mock.thumb.height;
- mock_node.thumb.width = mock.thumb.width;
- mock_node.thumb.height = mock.thumb.height;
+ //mock_node.thumb.width = mock.thumb.width;
+ //mock_node.thumb.height = mock.thumb.height;
mock_node.thumb.style.top = -parseInt(mock.thumb.height / 2);
mock_node.thumb.style.left = -parseInt(mock.thumb.width / 2);
Presenter.scale(mock_node.thumb, 0.1);
@@ -158,7 +158,7 @@ Presenter.prototype.orderNodes_ = function() {
Presenter.prototype.layout = function() {
var selected = this.mocklist_.getSelected();
var cx = this.node_.offsetWidth / 2;
- var cy = this.node_.offsetHeight / 2 - Presenter.MIN_EDGE_SPACING / 2;
+ var cy = this.node_.offsetHeight / 2;
var max_width = this.node_.offsetWidth - Presenter.MIN_EDGE_SPACING * 2;
var max_height = this.node_.offsetHeight - Presenter.MIN_EDGE_SPACING * 2;
var x = 0;
View
5 index.html
@@ -14,6 +14,7 @@
<script src="/s/editor.js"></script>
<script src="/s/introduction.js"></script>
<script src="/s/menu.js"></script>
+<script src="/s/menumocks.js"></script>
<script>
// GLOBAL ---------------------------------------------------------------------
function load() {
@@ -25,7 +26,7 @@
}
</script>
<script type="text/javascript">
-
+/*
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-18063845-1']);
_gaq.push(['_setDomainName', '.dropmocks.com']);
@@ -36,7 +37,7 @@
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
-
+*/
</script>
</head>
<body onload="load();" style="width:100%; height:100%; margin:0;">
View
98 main.py
@@ -4,11 +4,15 @@
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext.webapp import template
from google.appengine.ext import db
+from google.appengine.api import images
from google.appengine.api import users
from google.appengine.api import memcache
+from google.appengine.ext import blobstore
+from google.appengine.ext.webapp import blobstore_handlers
from django.utils import simplejson
import random
import datetime
+import urllib
# FUNCTIONS -------------------------------------------------------------------
import string
@@ -79,6 +83,8 @@ class Mock(db.Model):
mimetype = db.StringProperty(multiline=False)
mocklist = db.ReferenceProperty(MockList)
date = db.DateTimeProperty(auto_now_add=True)
+ blob_key = blobstore.BlobReferenceProperty()
+ serving_url = db.StringProperty()
def get_id(self):
return id_encode(self.key().id())
@@ -215,31 +221,28 @@ class ViewMock(webapp.RequestHandler):
def get(self, id):
mock = dbMock(id)
- """
- referer = self.request.headers.get("Referer")
- if referer:
- referer = referer.split("/")
- if len(referer) >= 2:
- referer = referer[2]
-
- host = self.request.url.split("/")[2]
- if (referer != host):
- self.redirect('http://' + host + '/m' + mock.mocklist.get_id())
- return
- """
-
if mock.mimetype:
self.response.headers['Content-Type'] = mock.mimetype
else:
self.response.headers['Content-Type'] = 'image/png'
- self.response.out.write(mock.data)
-
-class SaveMock(webapp.RequestHandler):
+
+ if mock.data:
+ self.response.out.write(mock.data)
+ elif mock.blob_key:
+ blob_reader = blobstore.BlobReader(mock.blob_key)
+ self.response.out.write(str(blob_reader.read()))
+ # self.redirect(mock.serving_url)
+ # self.redirect(mock.serving_url = images.get_serving_url(str(blob_info.key()), 800))
+
+class UploadMock(blobstore_handlers.BlobstoreUploadHandler):
def post(self):
id = self.request.get('id')
edit_key = self.request.get('key')
filename = self.request.get('filename')
+ import logging
+ logging.info(filename)
+
mocklist = dbMockList(id)
if mocklist.edit_key != edit_key:
self.response.out.write('invalid edit key')
@@ -249,15 +252,57 @@ def post(self):
mock.name = filename
if self.request.POST:
# FormData
- image_file = self.request.POST['file']
- mock.mimetype = image_file.type
- mock.data = db.Blob(image_file.value)
+ upload_files = self.get_uploads('file') # 'file' is file upload field in the form
+ blob_info = upload_files[0]
+ mock.blob_key = blob_info.key()
+ image = images.Image(blob_key=str(blob_info.key()))
+ image.horizontal_flip()
+ image.execute_transforms()
+
+ if image.width > 1280:
+ mock.serving_url = images.get_serving_url(str(blob_info.key()), 1280)
+ else:
+ mock.serving_url = images.get_serving_url(str(blob_info.key()))
else:
# Firefox3
mock.data = self.request.body
mock.mocklist = mocklist
mock.put()
+ self.redirect("/api/uploaded/?id=%s" % mock.get_id())
+
+class UploadedResult(webapp.RequestHandler):
+ def get(self):
+ self.response.out.write(simplejson.dumps({
+ 'id' : str(self.request.get('id'))
+ }))
+
+class GetUploadURL(webapp.RequestHandler):
+ def get(self):
+ id = self.request.get('id')
+ edit_key = self.request.get('key')
+ filename = self.request.get('filename')
+
+ self.response.out.write(simplejson.dumps({
+ 'url' : blobstore.create_upload_url('/upload/?id=%s&key=%s&filename=%s' % (id, edit_key, urllib.quote(filename)))
+ }))
+
+class SaveMockFF3(webapp.RequestHandler):
+ def post(self):
+ id = self.request.get('id')
+ edit_key = self.request.get('key')
+ filename = self.request.get('filename')
+
+ mocklist = dbMockList(id)
+ if mocklist.edit_key != edit_key:
+ self.response.out.write('invalid edit key')
+ return
+
+ mock = Mock()
+ mock.name = filename
+ mock.data = self.request.body
+ mock.mocklist = mocklist
+ mock.put()
self.response.out.write(simplejson.dumps({
'id' : str(mock.get_id())
}))
@@ -338,6 +383,15 @@ def get(self):
mocklist.delete()
self.response.out.write('{"success":true}')
+class DeleteManual(webapp.RequestHandler):
+ def get(self, id):
+ mocklist = dbMockList(id)
+ q = Mock.gql("WHERE mocklist = :1", (mocklist)).fetch(1000)
+ for mock in q:
+ mock.delete()
+ mocklist.delete()
+ self.response.out.write('{"success":true}')
+
class ManualUpload(webapp.RequestHandler):
def post(self):
id = self.request.get('id')
@@ -465,8 +519,11 @@ def get(self):
application = webapp.WSGIApplication([
(r'/m(.*)', View),
(r'/i(.*)', ViewMock),
+ ('/upload/', UploadMock),
('/api/getid/', GetID),
- ('/api/savemock/', SaveMock),
+ ('/api/getuploadurl/', GetUploadURL),
+ ('/api/uploaded/', UploadedResult),
+ ('/api/savemockff3/', SaveMockFF3),
('/api/deletemock/', DeleteMock),
('/api/savemocklist/', SaveMockList),
('/api/getmocklists/', GetMockLists),
@@ -475,6 +532,7 @@ def get(self):
('/signin/', SignIn),
('/admin/updatemodel/', UpdateModel),
('/admin/processvisits/', ProcessVisits),
+ (r'/admin/delete/m(.*)', DeleteManual),
('/', MainPage),
], debug=False)
View
1  viewer.html
@@ -12,6 +12,7 @@
<script src="/s/mocklist.js"></script>
<script src="/s/mock.js"></script>
<script src="/s/menu.js"></script>
+<script src="/s/menumocks.js"></script>
<script src="/s/presenter.js"></script>
<script src="/s/editor.js"></script>
<script src="/s/introduction.js"></script>

0 comments on commit b63c97a

Please sign in to comment.
Something went wrong with that request. Please try again.