Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Devin Torres committed Apr 8, 2010
0 parents commit 02e7065
Show file tree
Hide file tree
Showing 66 changed files with 2,823 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.DS_Store
tmp/
11 changes: 11 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[submodule "sproutcore"]
path = frameworks/sproutcore
url = git://github.com/sproutit/sproutcore.git

[submodule "scui"]
path = frameworks/scui
url = git://github.com/etgryphon/sproutcore-ui.git

[submodule "node-router"]
path = server/deps/node-router
url = git://github.com/creationix/node-router.git
10 changes: 10 additions & 0 deletions Buildfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# ===========================================================================
# Project: Fotofoo
# Copyright: ©2010 Devin Torres
# ===========================================================================

# Add initial buildfile information here
config :all, :required => :sproutcore
config :fotofoo, :theme => :'sproutcore/sc_ace'

proxy '/_media/', :to => 'localhost:8080', :url => '/'
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
Fotofoo - SproutCore foto foolery
=================================

## Installing
$ git clone git://github.com/devinus/fotofoo.git
$ cd fotofoo
$ git submodule init
$ git submodule update

## Running
$ sudo port install GraphicsMagick # or apt-get
$ git clone git://github.com/ry/node.git
$ cd node
$ ./configure
$ make
$ sudo make install
$ cd /path/to/fotofoo
# cd server
$ node fotofoo.js

Then, in a new console:
$ cd /path/to/fotofoo
$ sc-server

## Viewing
Now navigate your web browser to `http://127.0.0.1:4020/fotofoo`

## TODO
- Dragging and dropping of folders (commented out for now)
- Deleting folders/files (already have this in an older internal revision)
- Warn when file by the same name already exists in destination folder
- More image manipulation features, such as cropping
4 changes: 4 additions & 0 deletions apps/fotofoo/Buildfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
config :fotofoo, :required => [
:sproutcore,
:'scui/foundation'
]
18 changes: 18 additions & 0 deletions apps/fotofoo/controllers/file.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// ==========================================================================
// Project: Fotofoo.fileController
// Copyright: ©2010 Devin Torres
// ==========================================================================
/*globals Fotofoo */

/** @class
(Document Your Controller Here)
@extends SC.Object
*/
Fotofoo.fileController = SC.ObjectController.create(
/** @scope Fotofoo.fileController.prototype */ {

contentBinding: SC.Binding.from('Fotofoo.filesController.selection').single()

}) ;
20 changes: 20 additions & 0 deletions apps/fotofoo/controllers/files.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// ==========================================================================
// Project: Fotofoo.filesController
// Copyright: ©2010 Devin Torres
// ==========================================================================
/*globals Fotofoo */

Fotofoo.MAX_THUMBNAIL_SIZE = 250;

/** @class
(Document Your Controller Here)
@extends SC.Object
*/
Fotofoo.filesController = SC.ArrayController.create(
/** @scope Fotofoo.filesController.prototype */ {

contentBinding: 'Fotofoo.folderController.files'

}) ;
18 changes: 18 additions & 0 deletions apps/fotofoo/controllers/folder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// ==========================================================================
// Project: Fotofoo.folderController
// Copyright: ©2010 Devin Torres
// ==========================================================================
/*globals Fotofoo */

/** @class
(Document Your Controller Here)
@extends SC.Object
*/
Fotofoo.folderController = SC.ObjectController.create(
/** @scope Fotofoo.folderController.prototype */ {

contentBinding: SC.Binding.from('Fotofoo.foldersController.selection').single()

}) ;
60 changes: 60 additions & 0 deletions apps/fotofoo/controllers/folders.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// ==========================================================================
// Project: Fotofoo.foldersController
// Copyright: ©2010 Devin Torres
// ==========================================================================
/*globals Fotofoo */

/** @class
(Document Your Controller Here)
@extends SC.Object
*/
Fotofoo.foldersController = SC.TreeController.create(
/** @scope Fotofoo.foldersController.prototype */ {

treeItemIsGrouped: YES,

newFolder: function() {
var sel = this.getPath('selection.firstObject'),
useSelectionAsParent = sel ? !sel.get('isTrash') : NO,
root = this.getPath('content.treeItemChildren.firstObject'),
parentFolder = useSelectionAsParent ? sel.get('guid') || '/' : '/',
newFolder = Fotofoo.store.createRecord(Fotofoo.Folder, {
type: 'Folder',
guid: (parentFolder === '/' ? '' : parentFolder + '/') + SC.generateGuid(),
parentFolder: parentFolder
});

var $this = this;
newFolder.addObserver('status', newFolder, function() {
var status = this.get('status');
if (status && status & SC.Record.READY_CLEAN) {
this.removeObserver('status', this, arguments.callee);

try {
if (useSelectionAsParent) sel.get('childFolders').pushObject(this);
else Fotofoo.getPath('rootFolder.childFolders').pushObject(this);
} catch (e) {}

if (useSelectionAsParent) {
var folderView = Fotofoo.foldersView.itemViewForContentObject(sel),
idx = folderView.get('contentIndex'),
set = (!SC.none(idx)) ? SC.IndexSet.create(idx) : null,
del = folderView.get('displayDelegate');

if (set && del && del.expand) del.expand(set);
else folderView.set('disclosureState', SC.BRANCH_OPEN);
folderView.displayDidChange();
}

$this.selectObject(this);
Fotofoo.foldersView.itemViewForContentObject(this).beginEditing();
}
});

newFolder.commitRecord();
return YES;
}

}) ;
65 changes: 65 additions & 0 deletions apps/fotofoo/core.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// ==========================================================================
// Project: Fotofoo
// Copyright: ©2010 Devin Torres
// ==========================================================================
/*globals Fotofoo */

/** @namespace
My cool new app. Describe your application.
@extends SC.Object
*/
Fotofoo = SC.Application.create(
/** @scope Fotofoo.prototype */ {

NAMESPACE: 'Fotofoo',
VERSION: '0.1.0',

// This is your application store. You will use this store to access all
// of your model data. You can also set a data source on this store to
// connect to a backend server. The default setup below connects the store
// to any fixtures you define.
// store: SC.Store.create().from(SC.Record.fixtures),
store: SC.Store.create().from('Fotofoo.MediaDataSource'),

// TODO: Add global constants or singleton objects needed by your app here.
ROOT_MEDIA_URL: '/_media/',
nowShowing: 'master',
rootFolder: null,
state: null,

_SLASH_RE: /\//g,
_ENCODED_PIPE_RE: /%7C/g,
_MULTIPLE_SLASHES_RE: /\/+/g,
_SURROUNDING_WHITESPACE_RE: /^\s+|\s+$/g,

encodeGuid: function(guid) {
var encoded = encodeURIComponent(guid.replace(this._SLASH_RE, '|'));
return encoded.replace(this._ENCODED_PIPE_RE, '/');
},

urlJoin: function() {
var joined = Array.prototype.join.call(arguments, '/');
return joined.replace(this._MULTIPLE_SLASHES_RE, '/');
},

trim: function (str) {
return String.prototype.trim ? String.prototype.trim.apply(str)
: str.replace(this._SURROUNDING_WHITESPACE_RE, '');
},

_lastStateObserved: null,

_stateDidChange: function() {
var state = this.get('state');
if (SC.typeOf(state) === SC.T_STRING) state = this.get(state);

if (state !== this._lastStateObserved) {
this._lastStateObserved = state;
state.set('responderContext', this);
this.makeFirstResponder(state);
}
}.observes('state')

}) ;
128 changes: 128 additions & 0 deletions apps/fotofoo/data_sources/media.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// ==========================================================================
// Project: Fotofoo.MediaDataSource
// Copyright: ©2010 Devin Torres
// ==========================================================================
/*globals Fotofoo */

/** @class
(Document Your Data Source Here)
@extends SC.DataSource
*/
Fotofoo.MediaDataSource = SC.DataSource.extend(
/** @scope Fotofoo.MediaDataSource.prototype */ {

// ..........................................................
// QUERY SUPPORT
//

fetch: function(store, query) {
if (query.get('isLocal')) return NO;

SC.Request.getUrl(Fotofoo.ROOT_MEDIA_URL)
.set('isJSON', YES)
.notify(this, this._didFetch, { query: query, store: store })
.send();

return YES;
},

_didFetch: function(request, params) {
var store = params.store,
query = params.query,
response = request.get('response');

if (SC.$ok(response)) {
var storeKey = store.loadRecord(Fotofoo.Folder, response);
store.loadQueryResults(query, [storeKey]);
store.dataSourceDidFetchQuery(query);
} else store.dataSourceDidErrorQuery(query, response);
},

// ..........................................................
// RECORD SUPPORT
//

retrieveRecord: function(store, storeKey) {
var id = store.idFor(storeKey),
params = { store: store, storeKey: storeKey },
safeId = Fotofoo.encodeGuid(id),
url = Fotofoo.urlJoin(Fotofoo.ROOT_MEDIA_URL, safeId);

SC.Request.getUrl(url)
.set('isJSON', YES)
.notify(this, this._didRetrieveRecord, params)
.send();

return YES;
},

_didRetrieveRecord: function(request, params) {
var store = params.store,
storeKey = params.storeKey,
response = request.get('response');

if (SC.$ok(response)) {
store.dataSourceDidComplete(storeKey, response);
} else store.dataSourceDidError(storeKey, response);
},

createRecord: function(store, storeKey) {
var id = store.idFor(storeKey),
recordType = store.recordTypeFor(storeKey),
data = store.readDataHash(storeKey),
params = { store: store, storeKey: storeKey },
safeId = Fotofoo.encodeGuid(id),
url = Fotofoo.urlJoin(Fotofoo.ROOT_MEDIA_URL, safeId);

if (recordType === Fotofoo.File) return NO;

SC.Request.postUrl(url)
.set('isJSON', YES)
.notify(this, this._didCreateRecord, params)
.send(data);

return YES;
},

_didCreateRecord: function(request, params) {
var store = params.store,
storeKey = params.storeKey,
response = request.get('response');

if (SC.$ok(response)) {
store.dataSourceDidComplete(storeKey, response, response.guid);
} else store.dataSourceDidError(storeKey, response);
},

updateRecord: function(store, storeKey) {
var id = store.idFor(storeKey),
data = store.readDataHash(storeKey),
params = { store: store, storeKey: storeKey },
safeId = Fotofoo.encodeGuid(id),
url = Fotofoo.urlJoin(Fotofoo.ROOT_MEDIA_URL, safeId);

SC.Request.putUrl(url)
.set('isJSON', YES)
.notify(this, this._didUpdateRecord, params)
.send(data);

return YES;
},

_didUpdateRecord: function(request, params) {
var store = params.store,
storeKey = params.storeKey,
response = request.get('response');

if (SC.$ok(response)) {
store.dataSourceDidComplete(storeKey, response, response.guid);
} else store.dataSourceDidError(storeKey, response);
},

destroyRecord: function(store, storeKey) {
return NO;
}

}) ;
Loading

0 comments on commit 02e7065

Please sign in to comment.