diff --git a/pandora/templates/site.json b/pandora/templates/site.json index be1b3076..df15c98f 100644 --- a/pandora/templates/site.json +++ b/pandora/templates/site.json @@ -72,7 +72,7 @@ {"id": "news", "title": "News"}, {"id": "tour", "title": "Take a Tour"}, {"id": "faq", "title": "Frequently Asked Questions"}, - {"id": "tos", "title": "Terms of Service"} + {"id": "terms", "title": "Terms of Service"} ], "sortKeys": [ {"id": "title", "title": "Title", "width": 180, "removable": false, "type": "title"}, @@ -127,7 +127,7 @@ {"id": "pixels"} ], "user": { - "group": "guest", + "level": "guest", "lists": { "history": [ {"id": "all_movies", "title": "All Movies", "query": {}} diff --git a/pandora/urls.py b/pandora/urls.py index 9500abef..95c043be 100644 --- a/pandora/urls.py +++ b/pandora/urls.py @@ -42,6 +42,7 @@ if settings.DEBUG: urlpatterns += patterns('', (r'^.*?embed$', 'app.views.embed'), (r'^[A-Z0-9].*$', 'app.views.index'), + (r'^[a-z0-9].+$', 'app.views.index'), (r'^$', 'app.views.index'), ) diff --git a/pandora/user/models.py b/pandora/user/models.py index 6f1fd24c..09550eed 100644 --- a/pandora/user/models.py +++ b/pandora/user/models.py @@ -92,7 +92,10 @@ def get_user_json(user): result = {} for key in ('username', ): result[key] = getattr(user, key) - result['admin'] = user.is_staff + if user.is_staff: + result['level'] = 'admin' + else: + result['level'] = 'user' result['groups'] = [g.name for g in user.groups.all()] result['preferences'] = profile.get_preferences() result['ui'] = profile.get_ui() diff --git a/static/js/pandora.js b/static/js/pandora.js index a64525b1..105cddef 100755 --- a/static/js/pandora.js +++ b/static/js/pandora.js @@ -21,15 +21,26 @@ var pandora = new Ox.App({ ui: { sectionFolders: { site: $.merge([ - {id: "site", title: "Site"}, - {id: "user", title: "User"} - ], data.user.group == 'admin' ? [ - {id: "admin", title: "Admin"} + {id: 'site', title: 'Site', items: $.merge([ + {id: 'home', title: 'Home'} + ], $.merge(data.config.sitePages, [ + {id: 'software', title: 'Software'}, + {id: 'help', title: 'Help'} + ]))}, + {id: 'user', title: 'User', items: [ + {id: 'preferences', title: 'Preferences'}, + {id: 'archives', title: 'Archives'} + ]} + ], data.user.level == 'admin' ? [ + {id: 'admin', title: 'Admin', items: [ + {id: 'statistics', title: 'Statistics'}, + {id: 'users', title: 'Users'} + ]} ] : []), items: [ - {id: "personal", title: "Personal Lists"}, - {id: "favorite", title: "Favorite Lists", showBrowser: false}, - {id: "featured", title: "Featured Lists", showBrowser: false} + {id: 'personal', title: 'Personal Lists'}, + {id: 'favorite', title: 'Favorite Lists', showBrowser: false}, + {id: 'featured', title: 'Featured Lists', showBrowser: false} ], }, infoRatio: 16 / 9, @@ -46,7 +57,7 @@ var pandora = new Ox.App({ app.config.user.ui.theme = 'classic' } - if (app.user.group == 'guest') { + if (app.user.level == 'guest') { app.user = $.extend({}, app.config.user); } @@ -948,241 +959,288 @@ var pandora = new Ox.App({ }, folderList: function(id) { var i = Ox.getPositionById(app.ui.sectionFolders[app.user.ui.section], id), + that; + if (app.user.ui.section == 'site') { that = new Ox.TextList({ - columns: [ - { - format: function() { - return $('').attr({ - src: 'static/oxjs/build/png/ox.ui/icon16.png' - }); - }, - id: 'user', - operator: '+', - visible: true, - width: 16 - }, - { - format: function(value) { - return value.split('/').join(': '); - }, - id: 'id', - operator: '+', - unique: true, - visible: id == 'favorite', - width: app.user.ui.sidebarWidth - 88 - }, - { - editable: function(data) { - return data.user == app.user.username; - }, - id: 'name', - input: { - autovalidate: autovalidateListname - }, - operator: '+', - visible: id != 'favorite', - width: app.user.ui.sidebarWidth - 88 - }, - { - align: 'right', - id: 'items', - operator: '-', - visible: true, - width: 40 - }, - { - clickable: function(data) { - return data.type == 'smart'; - }, - format: function(value) { - return $('') - .attr({ - src: 'static/oxjs/build/png/ox.ui.' + Ox.theme() + - '/symbolFind.png' - }) - .css({ - opacity: value == 'static' ? 0.1 : 1 + columns: [ + { + format: function() { + return $('').attr({ + src: 'static/oxjs/build/png/ox.ui/icon16.png' }); + }, + id: 'id', + operator: '+', + unique: true, + visible: true, + width: 16 }, - id: 'type', - operator: '+', - visible: true, - width: 16 - }, - { - clickable: id == 'personal', - format: function(value) { - //var symbols = {private: 'Publish', public: 'Publish', featured: 'Star'}; - return $('') - .attr({ - src: 'static/oxjs/build/png/ox.ui.' + Ox.theme() + '/symbol' - + (value == 'featured' ? 'Star' : 'Publish') + '.png' - }) - .css({ - opacity: value == 'private' ? 0.1 : 1 - }) - }, - id: 'status', - operator: '+', - visible: true, - width: 16 - } - ], - max: 1, - min: 0, - pageLength: 1000, - request: function(data, callback) { - var query; - if (id == 'personal') { - query = {conditions: [ - {key: 'user', value: app.user.username, operator: '='}, - {key: 'status', value: 'featured', operator: '!'} - ], operator: '&'}; - } else if (id == 'favorite') { - query = {conditions: [ - {key: 'subscribed', value: true, operator: '='}, - {key: 'status', value: 'featured', operator: '!'}, - ], operator: '&'}; - } else if (id == 'featured') { - query = {conditions: [{key: 'status', value: 'featured', operator: '='}], operator: '&'}; - } - return pandora.api.findLists($.extend(data, { - query: query - }), callback); - }, - sort: [ - {key: 'position', operator: '+'} - ], - sortable: id == 'personal' || id == 'favorite' || app.user.group == 'admin' - }) - .css({ - left: 0, - top: 0, - width: app.user.ui.sidebarWidth + 'px', - }) - .bind({ - dragenter: function(e) { - //Ox.print('DRAGENTER', e) - } - }) - .bindEvent({ - click: function(event, data) { - var $list = app.$ui.folderList[id]; - if (data.key == 'type') { - var $dialog = new Ox.Dialog({ - buttons: [ - new Ox.Button({ - id: 'cancel', - title: 'Cancel' - }).bindEvent('click', function() { - $dialog.close(); - }), - new Ox.Button({ - id: 'save', - title: 'Save' - }).bindEvent('click', function() { - $dialog.close(); - }) - ], - content: new Ox.Element('div').html('...'), - height: 200, - keys: {enter: 'save', escape: 'cancel'}, - title: 'Advanced Find', - width: 640 - }).open(); - } else if (data.key == 'status') { - pandora.api.editList({ - id: data.id, - status: $list.value(data.id, data.key) == 'private' ? 'public' : 'private' - }, function(result) { - $list.value(result.data.id, 'status', result.data.status); - }); - } - }, - 'delete': function(event, data) { - var $list = app.$ui.folderList[id]; - app.user.ui.listQuery.conditions = []; - URL.set(Query.toString()); - $list.options({selected: []}); - if (id == 'personal') { - pandora.api.removeList({ - id: data.ids[0] - }, function(result) { - // fixme: is this the best way to delete a ui preference? - delete app.user.ui.lists[data.ids[0]]; - UI.set({lists: app.user.ui.lists}); - Ox.Request.emptyCache(); // fixme: remove - $list.reloadList(); - }); - } else if (id == 'favorite') { - pandora.api.unsubscribeFromList({ - id: data.ids[0] - }, function(result) { - Ox.Request.emptyCache(); // fixme: remove - $list.reloadList(); - }); - } else if (id == 'featured' && app.user.group == 'admin') { - pandora.api.editList({ - id: data.ids[0], - status: 'public' - }, function(result) { - // fixme: duplicated - if (result.data.user == app.user.username || result.data.subscribed) { - Ox.Request.emptyCache(); // fixme: remove - app.$ui.folderList[ - result.data.user == app.user.username ? 'personal' : 'favorite' - ].reloadList(); - } - $list.reloadList(); - }); - } - }, - init: function(event, data) { - app.ui.sectionFolders[app.user.ui.section][i].items = data.items; - app.$ui.folder[i].$content.css({ - height: data.items * 16 + 'px' - }); - app.$ui.folderList[id].css({ - height: data.items * 16 + 'px' - }); - resizeFolders(); - }, - move: function(event, data) { - /* - data.ids.forEach(function(id, pos) { - app.user.ui.lists[id].position = pos; - }); - */ - pandora.api.sortLists({ - section: id, - ids: data.ids - }); - }, - paste: function(event, data) { - app.$ui.list.triggerEvent('paste', data); - }, - select: function(event, data) { - if (data.ids.length) { + { + id: 'title', + operator: '+', + visible: true, + width: app.user.ui.sidebarSize - 16 + } + ], + max: 1, + min: 1, + request: function(data, callback) { + var result = {data: {}}; + if (!data.range) { + result.data.items = Ox.getObjectById(app.ui.sectionFolders.site, id).items.length; + } else { + result.data.items = Ox.getObjectById(app.ui.sectionFolders.site, id).items; + } + callback(result); + }, + sort: [{key: '', operator: ''}] + }) + .bindEvent({ + select: function(event, data) { + // fixme: duplicated $.each(app.$ui.folderList, function(id_, $list) { id != id_ && $list.options('selected', []); }) - URL.set('?find=list:' + data.ids[0]); - } else { - URL.set(''); - } - }, - submit: function(event, data) { - data_ = {id: data.id}; - data_[data.key] = data.value; - pandora.api.editList(data_, function(result) { - if (result.data.id != data.id) { - app.$ui.folderList[id].value(data.id, 'name', result.data.name); - app.$ui.folderList[id].value(data.id, 'id', result.data.id); - URL.set('?find=list:' + result.data.id); + URL.set((id == 'admin' ? 'admin/' : '' ) + data.ids[0]); + }, + }); + } else if (app.user.ui.section == 'items') { + that = new Ox.TextList({ + columns: [ + { + format: function() { + return $('').attr({ + src: 'static/oxjs/build/png/ox.ui/icon16.png' + }); + }, + id: 'user', + operator: '+', + visible: true, + width: 16 + }, + { + format: function(value) { + return value.split('/').join(': '); + }, + id: 'id', + operator: '+', + unique: true, + visible: id == 'favorite', + width: app.user.ui.sidebarWidth - 88 + }, + { + editable: function(data) { + return data.user == app.user.username; + }, + id: 'name', + input: { + autovalidate: autovalidateListname + }, + operator: '+', + visible: id != 'favorite', + width: app.user.ui.sidebarWidth - 88 + }, + { + align: 'right', + id: 'items', + operator: '-', + visible: true, + width: 40 + }, + { + clickable: function(data) { + return data.type == 'smart'; + }, + format: function(value) { + return $('') + .attr({ + src: 'static/oxjs/build/png/ox.ui.' + Ox.theme() + + '/symbolFind.png' + }) + .css({ + opacity: value == 'static' ? 0.1 : 1 + }); + }, + id: 'type', + operator: '+', + visible: true, + width: 16 + }, + { + clickable: id == 'personal', + format: function(value) { + //var symbols = {private: 'Publish', public: 'Publish', featured: 'Star'}; + return $('') + .attr({ + src: 'static/oxjs/build/png/ox.ui.' + Ox.theme() + '/symbol' + + (value == 'featured' ? 'Star' : 'Publish') + '.png' + }) + .css({ + opacity: value == 'private' ? 0.1 : 1 + }) + }, + id: 'status', + operator: '+', + visible: true, + width: 16 } - }); - } - }); + ], + max: 1, + min: 0, + pageLength: 1000, + request: function(data, callback) { + var query; + if (id == 'personal') { + query = {conditions: [ + {key: 'user', value: app.user.username, operator: '='}, + {key: 'status', value: 'featured', operator: '!'} + ], operator: '&'}; + } else if (id == 'favorite') { + query = {conditions: [ + {key: 'subscribed', value: true, operator: '='}, + {key: 'status', value: 'featured', operator: '!'}, + ], operator: '&'}; + } else if (id == 'featured') { + query = {conditions: [{key: 'status', value: 'featured', operator: '='}], operator: '&'}; + } + return pandora.api.findLists($.extend(data, { + query: query + }), callback); + }, + sort: [ + {key: 'position', operator: '+'} + ], + sortable: id == 'personal' || id == 'favorite' || app.user.level == 'admin' + }) + .css({ + left: 0, + top: 0, + width: app.user.ui.sidebarWidth + 'px', + }) + .bind({ + dragenter: function(e) { + //Ox.print('DRAGENTER', e) + } + }) + .bindEvent({ + click: function(event, data) { + var $list = app.$ui.folderList[id]; + if (data.key == 'type') { + var $dialog = new Ox.Dialog({ + buttons: [ + new Ox.Button({ + id: 'cancel', + title: 'Cancel' + }).bindEvent('click', function() { + $dialog.close(); + }), + new Ox.Button({ + id: 'save', + title: 'Save' + }).bindEvent('click', function() { + $dialog.close(); + }) + ], + content: new Ox.Element('div').html('...'), + height: 200, + keys: {enter: 'save', escape: 'cancel'}, + title: 'Advanced Find', + width: 640 + }).open(); + } else if (data.key == 'status') { + pandora.api.editList({ + id: data.id, + status: $list.value(data.id, data.key) == 'private' ? 'public' : 'private' + }, function(result) { + $list.value(result.data.id, 'status', result.data.status); + }); + } + }, + 'delete': function(event, data) { + var $list = app.$ui.folderList[id]; + app.user.ui.listQuery.conditions = []; + URL.set(Query.toString()); + $list.options({selected: []}); + if (id == 'personal') { + pandora.api.removeList({ + id: data.ids[0] + }, function(result) { + // fixme: is this the best way to delete a ui preference? + delete app.user.ui.lists[data.ids[0]]; + UI.set({lists: app.user.ui.lists}); + Ox.Request.emptyCache(); // fixme: remove + $list.reloadList(); + }); + } else if (id == 'favorite') { + pandora.api.unsubscribeFromList({ + id: data.ids[0] + }, function(result) { + Ox.Request.emptyCache(); // fixme: remove + $list.reloadList(); + }); + } else if (id == 'featured' && app.user.level == 'admin') { + pandora.api.editList({ + id: data.ids[0], + status: 'public' + }, function(result) { + // fixme: duplicated + if (result.data.user == app.user.username || result.data.subscribed) { + Ox.Request.emptyCache(); // fixme: remove + app.$ui.folderList[ + result.data.user == app.user.username ? 'personal' : 'favorite' + ].reloadList(); + } + $list.reloadList(); + }); + } + }, + init: function(event, data) { + app.ui.sectionFolders[app.user.ui.section][i].items = data.items; + app.$ui.folder[i].$content.css({ + height: data.items * 16 + 'px' + }); + app.$ui.folderList[id].css({ + height: data.items * 16 + 'px' + }); + resizeFolders(); + }, + move: function(event, data) { + /* + data.ids.forEach(function(id, pos) { + app.user.ui.lists[id].position = pos; + }); + */ + pandora.api.sortLists({ + section: id, + ids: data.ids + }); + }, + paste: function(event, data) { + app.$ui.list.triggerEvent('paste', data); + }, + select: function(event, data) { + if (data.ids.length) { + $.each(app.$ui.folderList, function(id_, $list) { + id != id_ && $list.options('selected', []); + }) + URL.set('?find=list:' + data.ids[0]); + } else { + URL.set('?find='); + } + }, + submit: function(event, data) { + data_ = {id: data.id}; + data_[data.key] = data.value; + pandora.api.editList(data_, function(result) { + if (result.data.id != data.id) { + app.$ui.folderList[id].value(data.id, 'name', result.data.name); + app.$ui.folderList[id].value(data.id, 'id', result.data.id); + URL.set('?find=list:' + result.data.id); + } + }); + } + }); + } return that; }, folders: function() { @@ -1199,22 +1257,38 @@ var pandora = new Ox.App({ app.$ui.folderBrowser = {}; app.$ui.folderList = {}; if (app.user.ui.section == 'site') { - /* $.each(app.ui.sectionFolders.site, function(i, folder) { - var extras = []; + var height = (Ox.getObjectById(app.ui.sectionFolders.site, folder.id).items.length * 16); app.$ui.folder[i] = new Ox.CollapsePanel({ - id: id, - collapsed: !app.user.ui.showSection[id], - extras: extras, + id: folder.id, + collapsed: !app.user.ui.showFolder.site[folder.id], size: 16, - title: Ox.getObjectById(app.config.sections, id).title + title: folder.title }) + .bindEvent({ + toggle: function(event, data) { + + } + }); + //alert(JSON.stringify(Ox.getObjectById(app.ui.sectionFolders.site, folder.id))) + app.$ui.folder[i].$content.css({ + height: height + 'px' + }) + //.appendTo(that); + app.$ui.folderList[folder.id] = ui.folderList(folder.id) + .css({ + height: height + 'px' + }) + .appendTo(app.$ui.folder[i].$content); + app.$ui.folder.forEach(function($folder) { + that.append($folder); + }); }); - */ + //resizeFolders(); } else if (app.user.ui.section == 'items') { $.each(app.ui.sectionFolders.items, function(i, folder) { var extras; - if (folder.id == 'personal' && app.user.group != 'guest') { + if (folder.id == 'personal' && app.user.level != 'guest') { extras = [new Ox.Select({ items: [ { id: 'new', title: 'New List...' }, @@ -1254,7 +1328,7 @@ var pandora = new Ox.App({ } } })]; - } else if (folder.id == 'favorite' && app.user.group != 'guest') { + } else if (folder.id == 'favorite' && app.user.level != 'guest') { extras = [new Ox.Button({ selectable: true, style: 'symbol', @@ -1278,7 +1352,7 @@ var pandora = new Ox.App({ resizeFolders(); } })]; - } else if (folder.id == 'featured' && app.user.group == 'admin') { + } else if (folder.id == 'featured' && app.user.level == 'admin') { extras = [new Ox.Button({ selectable: true, style: 'symbol', @@ -1351,7 +1425,7 @@ var pandora = new Ox.App({ function init(event, data) { Ox.print('init', i, counter) if (++counter == 3) { - $.each(app.$ui.folder, function(i, $folder) { + app.$ui.folder.forEach(function($folder) { that.append($folder); }); resizeFolders(); @@ -2141,7 +2215,7 @@ var pandora = new Ox.App({ height = imageHeight * width / imageWidth; app.ui.infoRatio = width / height; !app.user.ui.showInfo && app.$ui.leftPanel.css({bottom: -height - 16}); - app.$ui.leftPanel.size('infoPanel', height + 16); + app.$ui.leftPanel.size(2, height + 16); $still.css({ position: 'absolute', left: 0, @@ -2227,7 +2301,7 @@ var pandora = new Ox.App({ return that; }, mainMenu: function() { - var isGuest = app.user.group == 'guest', + var isGuest = app.user.level == 'guest', that = new Ox.MainMenu({ extras: [ $('