Skip to content

Commit

Permalink
add an explicit manage_main view target, point to the manage main vie…
Browse files Browse the repository at this point in the history
…w target from the contents view, get explicit tab ordering more right
  • Loading branch information
mcdonc committed Apr 22, 2012
1 parent 47a3d64 commit dcbf8a4
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 42 deletions.
3 changes: 2 additions & 1 deletion demos/simple/development.ini
Expand Up @@ -10,7 +10,8 @@ pyramid.includes =
# pyramid_debugtoolbar
pyramid_tm

zodbconn.uri = file://%(here)s/Data.fs
zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000&blobstorage_dir=%(here)s/blobs&blobstorage_layout=bushy
pyramid_deform.tempdir = %(here)s/tmp
substanced.secret = seekri1
substanced.initial_login = admin
substanced.initial_password = admin
Expand Down
161 changes: 139 additions & 22 deletions demos/simple/simple/resources.py
@@ -1,10 +1,14 @@
from persistent import Persistent

from pyramid.httpexceptions import HTTPFound
import mimetypes

import colander
import deform.widget

from persistent import Persistent
from ZODB.blob import Blob

from pyramid.httpexceptions import HTTPFound
from pyramid.response import FileResponse

from substanced.interfaces import (
IFolder,
IPropertied,
Expand All @@ -15,28 +19,38 @@
from substanced.sdi import mgmt_view
from substanced.form import FormView

@colander.deferred
def name_validator(node, kw):
context = kw['request'].context
def exists(node, value):
if DocumentType.providedBy(context):
if value != context.__name__:
from .form import (
SessionTempStore,
chunks,
)

def make_name_validator(content_type):
@colander.deferred
def name_validator(node, kw):
context = kw['request'].context
def exists(node, value):
if content_type.providedBy(context):
if value != context.__name__:
try:
context.__parent__.check_name(value)
except Exception as e:
raise colander.Invalid(node, e.message, value)
else:
try:
context.__parent__.check_name(value)
context.check_name(value)
except Exception as e:
raise colander.Invalid(node, e.message, value)
else:
try:
context.check_name(value)
except Exception as e:
raise colander.Invalid(node, e.message, value)

return exists

return exists
return name_validator

class DocumentType(IPropertied, ICatalogable):
pass

class DocumentSchema(Schema):
name = colander.SchemaNode(
colander.String(),
validator = name_validator,
validator = make_name_validator(DocumentType),
)
title = colander.SchemaNode(
colander.String(),
Expand All @@ -46,10 +60,7 @@ class DocumentSchema(Schema):
widget=deform.widget.RichTextWidget()
)

class DocumentType(IPropertied, ICatalogable):
pass

@content(DocumentType, icon='icon-file', add_view='add_document',
@content(DocumentType, icon='icon-align-left', add_view='add_document',
name='Document')
class Document(Persistent):

Expand Down Expand Up @@ -90,3 +101,109 @@ def add_success(self, appstruct):
self.request.context[name] = document
return HTTPFound(self.request.mgmt_path(document, '@@properties'))


class FileType(IPropertied, ICatalogable):
pass

@colander.deferred
def upload_widget(node, kw):
request = kw['request']
tmpstore = SessionTempStore(request)
return deform.widget.FileUploadWidget(tmpstore)

class FileSchema(Schema):
name = colander.SchemaNode(
colander.String(),
validator = make_name_validator(FileType),
)
stream = colander.SchemaNode(
deform.schema.FileData(),
widget = upload_widget,
title = 'File',
)
mimetype = colander.SchemaNode(
colander.String(),
missing=colander.null,
)

@content(FileType, name='File', icon='icon-file', add_view='add_file')
class File(Persistent):

# prevent download tab from sorting first (it would show the file
# when manage_main clicked)
__tab_order__ = ('properties', 'acl_edit', 'download')

__propschema__ = FileSchema()

def __init__(self, stream, mimetype='application/octet-stream'):
self.mimetype = mimetype
self.blob = Blob()
self.upload(stream)

def get_properties(self):
filedata = dict(
fp=None,
uid=str(self.__objectid__),
filename=self.__name__,
)
return dict(name=self.__name__, file=filedata, mimetype=self.mimetype)

def set_properties(self, struct):
newname = struct['name']
oldname = self.__name__
if newname != oldname:
parent = self.__parent__
parent.rename(oldname, newname)
if struct['fp']:
self.upload(struct['fp'])
self.mimetype = mimetypes.guess_type(
struct['filename'], strict=False)[0]

def upload(self, stream):
fp = self.blob.open('w')
size = 0
for chunk in chunks(stream):
size += len(chunk)
fp.write(chunk)
fp.close()
self.size = size

@mgmt_view(context=IFolder,
name='add_file',
tab_title='Add File',
permission='sdi.add-content',
renderer='substanced.sdi:templates/form.pt',
tab_condition=False)
class AddFileView(FormView):
title = 'Add Document'
schema = FileSchema()
buttons = ('add',)

def add_success(self, appstruct):
registry = self.request.registry
name = appstruct.pop('name')
filedata = appstruct.pop('stream')
stream = filedata['fp']
mimetype = appstruct['mimetype']
if not mimetype:
mimetype = mimetypes.guess_type(
filedata['filename'], strict=False)[0]
fileob = registry.content.create(FileType, stream, mimetype)
self.request.context[name] = fileob
return HTTPFound(self.request.mgmt_path(fileob, '@@properties'))

@mgmt_view(context=FileType,
name='download',
tab_title='Download',
permission='sdi.view')
def download_tab(context, request):
return HTTPFound(location=request.mgmt_path(context))

@mgmt_view(context=FileType,
name='',
permission='sdi.view',
tab_condition=False)
def download_file(context, request):
return FileResponse(context.blob.committed(), request=request,
content_type=context.mimetype)

2 changes: 1 addition & 1 deletion substanced/folder/views.py
Expand Up @@ -74,7 +74,7 @@ def show(self):
L = []
for k, v in context.items():
viewable = False
url = request.mgmt_path(v)
url = request.mgmt_path(v, '@@manage_main')
if has_permission('sdi.view', v, request):
viewable = True
icon = request.registry.content.metadata(v, 'icon')
Expand Down
25 changes: 10 additions & 15 deletions substanced/sdi/__init__.py
Expand Up @@ -192,8 +192,6 @@ def get_mgmt_views(request, context=None, names=None):
continue
for intr in related:
view_name = intr['name']
if view_name == '' and tab_title == 'manage_main':
continue # manage_main view
if names is not None and not view_name in names:
continue
if intr.category_name == 'views' and not view_name in L:
Expand All @@ -218,22 +216,19 @@ def get_mgmt_views(request, context=None, names=None):
{'view_name':view_name,
'tab_title':tab_title or view_name.capitalize()}
)
selected = []
extra = []
ordered = []

if hasattr(context, '__tab_order__'):
tab_order = context.__tab_order__
for view_data in L:
for view_name in tab_order:
if view_name == view_data['view_name']:
selected.append(view_data)
break
else:
extra.append(view_data)
else:
extra = L

return selected + sorted(extra, key=operator.itemgetter('tab_title'))
ordered_names_available = [ y for y in tab_order if y in
[ x['view_name'] for x in L ] ]
for ordered_name in ordered_names_available:
for view_data in L:
if view_data['view_name'] == ordered_name:
L.remove(view_data)
ordered.append(view_data)

return ordered + sorted(L, key=operator.itemgetter('tab_title'))

def get_add_views(request, context=None):
registry = request.registry
Expand Down
8 changes: 5 additions & 3 deletions substanced/sdi/views.py
Expand Up @@ -62,15 +62,17 @@ def logout(request):
return HTTPFound(location = request.mgmt_path(request.context),
headers = headers)

@mgmt_view(tab_title='manage_main')
@mgmt_view(tab_condition=False)
@mgmt_view(name='manage_main', tab_condition=False)
def manage_main(request):
view_data = get_mgmt_views(request)
if not view_data:
request.session['came_from'] = request.url
return HTTPFound(location=request.mgmt_path(request.root, '@@login'))
view_name = view_data[0]['view_name']
return HTTPFound(request.mgmt_path(request.context, '@@%s' % view_name))

return HTTPFound(
location=request.mgmt_path(request.context, '@@%s' % view_name)
)

@mgmt_view(context=IFolder, name='add', tab_title='Add',
permission='sdi.manage-contents', renderer='templates/add.pt',
Expand Down

0 comments on commit dcbf8a4

Please sign in to comment.