示例#1
0
def fsMetadataView(fsPathString=''):
    """Edit-file-metadata view, a web-form."""
    user = g.user
    db = dbGetDatabase()
    form = FileDataForm()
    lsPath = splitPathString(fsPathString)
    boxPath, prevFileName = lsPath[:-1], lsPath[-1]
    parentBox = getBoxFromPath(db, boxPath, user)
    request._onErrorUrl = url_for(
        'lsView',
        lsPathString='/'.join(boxPath[1:]),
    )
    file = getFileFromParent(db, parentBox, prevFileName, user)
    if form.validate_on_submit():
        newFile = File(**recursivelyMergeDictionaries(
            {
                'name': form.filename.data,
                'description': form.filedescription.data,
                'metadata_username': user.username,
            },
            defaultMap=file.asDict(),
        ))
        updateFile(db, boxPath, prevFileName, newFile, user)
        return redirect(url_for('lsView', lsPathString='/'.join(boxPath[1:])))
    else:
        form.filename.data = applyDefault(form.filename.data, file.name)
        form.filedescription.data = applyDefault(form.filedescription.data,
                                                 file.description)
        #
        pageFeatures = {
            'breadCrumbs':
            makeBreadCrumbs(
                boxPath,
                g,
                appendedItems=[{
                    'kind': 'file',
                    'target': file,
                }, {
                    'kind': 'link',
                    'target': None,
                    'name': 'Metadata',
                }],
            ),
            'pageTitle':
            'Edit file metadata (%s)' % file.name,
            'pageSubtitle':
            'Name is mandatory',
            'iconUrl':
            url_for(
                'fileThumbnailView',
                dummyId=file.icon_file_id + '_',
                fsPathString='/'.join(lsPath[1:]),
            ),
        }
        return render_template(
            'filedataedit.html',
            form=form,
            user=user,
            **pageFeatures,
        )
示例#2
0
def makeLinkView(fsPathString=''):
    """Generate-new-link route."""
    user = g.user
    form = EditLinkForm()
    db = dbGetDatabase()
    boxPath = splitPathString(fsPathString)
    request._onErrorUrl = url_for(
        'lsView',
        lsPathString='/'.join(boxPath[1:]),
    )
    parentBoxPath = boxPath
    parentBox = getBoxFromPath(db, parentBoxPath, user)
    if form.validate_on_submit():
        linkName = secure_filename(form.linkname.data)
        linkTitle = form.linktitle.data
        linkDescription = form.linkdescription.data
        linkTarget = form.linktarget.data
        openInNewWindow = form.openinnewwindow.data
        savingResult = makeLinkInParent(
            db=db,
            user=user,
            parentBox=parentBox,
            date=datetime.now(),
            linkName=linkName,
            linkTitle=linkTitle,
            linkDescription=linkDescription,
            linkTarget=linkTarget,
            linkOptions={
                'open_in_new_window': openInNewWindow,
            },
        )
        return redirect(url_for(
            'lsView',
            lsPathString=fsPathString,
        ))
    else:
        pathBCrumbs = makeBreadCrumbs(
            parentBoxPath,
            g,
            appendedItems=[{
                'kind': 'link',
                'target': None,
                'name': 'New link',
            }],
        )
        form.openinnewwindow.data = True
        return render_template(
            'editlink.html',
            form=form,
            user=user,
            breadCrumbs=pathBCrumbs,
            iconUrl=makeSettingImageUrl(g, 'app_images', 'external_link'),
            pageTitle='New link',
            pageSubtitle='Create a new link in "%s"' %
            (describeBoxTitle(parentBox)),
        )
示例#3
0
def fsMakeTicketView(fsPathString=''):
    """Create-file-ticket (file-read) view."""
    user = g.user
    lsPath = splitPathString(fsPathString)
    boxPath, fileName = lsPath[:-1], lsPath[-1]
    db = dbGetDatabase()
    parentBox = getBoxFromPath(db, boxPath, user)
    request._onErrorUrl = url_for(
        'lsView',
        lsPathString='/'.join(boxPath[1:]),
    )
    if parentBox is not None:
        file = getFileFromParent(db, parentBox, fileName, user)
        if file is not None:
            pathBCrumbs = makeBreadCrumbs(
                boxPath,
                g,
                appendedItems=[
                    {
                        'kind': 'file',
                        'target': file,
                    },
                    {
                        'name':
                        '(create ticket)',
                        'kind':
                        'link',
                        'target':
                        url_for(
                            'fsMakeTicketView',
                            fsPathString=fsPathString,
                        ),
                        'link':
                        False,
                    },
                ],
            )
            # if this succeeded, user has read permission on 'file'
            form = generateFsTicketForm(
                fileModePresent=True,
                settings=g.settings,
            )
            if form.validate_on_submit():
                magicLink = dbMakeFileTicket(
                    db=db,
                    ticketName=form.name.data,
                    validityHours=transformIfNotEmpty(
                        form.validityhours.data,
                        int,
                    ),
                    multiplicity=transformIfNotEmpty(
                        form.multiplicity.data,
                        int,
                    ),
                    ticketMessage=transformIfNotEmpty(
                        form.ticketmessage.data, ),
                    file=file,
                    fileMode=form.filemode.data,
                    lsPath=lsPath,
                    user=user,
                    urlRoot=request.url_root,
                    settings=g.settings,
                )
                flashMessage(
                    'Success',
                    'Done',
                    ('File ticket generated. Give the recipient '
                     'the following magic link:'),
                    pillText=magicLink,
                )
                return redirect(
                    url_for(
                        'lsView',
                        lsPathString='/'.join(boxPath[1:]),
                    ))
            else:
                form.name.data = applyDefault(form.name.data, file.name)
                form.ticketmessage.data = applyDefault(
                    form.ticketmessage.data,
                    'Please access this file',
                )
                form.filemode.data = applyDefault(
                    form.filemode.data,
                    'direct',
                    additionalNulls=['None'],
                )
                maxValidityHours = g.settings['behaviour'][
                    'behaviour_tickets']['max_ticket_validityhours']['value']
                form.validityhours.data = applyDefault(
                    form.validityhours.data,
                    (str(maxValidityHours)
                     if maxValidityHours is not None else ''),
                )
                maxMultiplicity = g.settings['behaviour']['behaviour_tickets'][
                    'max_ticket_multiplicity']['value']
                form.multiplicity.data = applyDefault(
                    form.multiplicity.data,
                    (str(maxMultiplicity)
                     if maxMultiplicity is not None else ''),
                )
                return render_template(
                    'fsticket.html',
                    pageTitle='Create public file ticket',
                    pageSubtitle=('Recipient(s) of the ticket will be able '
                                  'to access "%s" without an account.') %
                    (fsPathString, ),
                    baseMultiplicityCaption=('Number of granted accesses (bo'
                                             'th views and downloads count)'),
                    user=user,
                    form=form,
                    iconUrl=makeSettingImageUrl(
                        g,
                        'app_images',
                        'file_ticket',
                    ),
                    showFileMode=True,
                    breadCrumbs=pathBCrumbs,
                )
        else:
            return abort(404)
    else:
        return abort(404)
示例#4
0
def fsView(fsPathString=''):
    """View file route. If not viewable, display an error message."""
    user = g.user
    lsPath = splitPathString(fsPathString)
    boxPath, fileName = lsPath[:-1], lsPath[-1]
    db = dbGetDatabase()
    fileStorageDirectory = g.settings['system']['system_directories'][
        'fs_directory']['value']
    parentBox = getBoxFromPath(db, boxPath, user)
    request._onErrorUrl = url_for(
        'lsView',
        lsPathString='/'.join(boxPath[1:]),
    )
    file = getFileFromParent(db, parentBox, fileName, user)
    if file is not None:
        fileInfo = prepareFileInfo(db, file)
        fileActions = prepareFileActions(
            db,
            file,
            boxPath[1:] + [file.name],
            parentBox,
            user,
            discardedActions={'view'},
        )
        fileContents = produceFileViewContents(
            db,
            file,
            mode='fsview',
            viewParameters={
                'boxPath': boxPath,
                'fileName': fileName,
            },
            fileStorageDirectory=fileStorageDirectory,
        )
        #
        pathBCrumbs = makeBreadCrumbs(
            boxPath,
            g,
            appendedItems=[{
                'kind': 'file',
                'target': file,
            }],
        )
        #
        return render_template(
            'fileview.html',
            fileActions=fileActions,
            fileInfo=fileInfo,
            filecontents=fileContents,
            breadCrumbs=pathBCrumbs,
            user=user,
            pageTitle='"%s" file view' % file.name,
            pageSubtitle='%s (%s; %s)' % (
                file.description,
                file.type,
                formatBytesSize(file.size),
            ),
            downloadUrl=None,
        )
    else:
        return abort(404)
示例#5
0
def fsMoveBoxView(quotedSrcBox):
    """
        Move-box-phase-1 route: where the source box is selected
        (and then in offering the choose-dest-box it is put in the URL
        for calling phase two).
    """
    user = g.user
    db = dbGetDatabase()
    # first we find the box
    bxPathString = urllib.parse.unquote_plus(quotedSrcBox)
    boxPath = splitPathString(bxPathString)
    parentBox = getBoxFromPath(db, boxPath[:-1], user)
    request._onErrorUrl = url_for(
        'lsView',
        lsPathString='/'.join(boxPath[1:-1]),
    )
    box = getBoxFromPath(db, boxPath, user)
    if not canDeleteBox(db, box, parentBox, user):
        raise OstracionWarning('Cannot act on this object')
    # next we prepare the selectable destinations
    rootBox = getRootBox(db)

    def rbPredicate(richBox, _box=box, _srcBox=parentBox):
        _dstBox = richBox['box']
        if _box.parent_id != _dstBox.box_id:
            if all(userHasPermission(db, user, _dstBox.permissions, prm)
                    for prm in {'w', 'c'}):
                if not isNameUnderParentBox(db, _dstBox, _box.box_name):
                    if not isAncestorBoxOf(db, _box, _dstBox):
                        return True
        return False

    dstBoxTree = collectTreeFromBox(
        db,
        rootBox,
        user,
        admitFiles=False,
        fileOrBoxEnricher=lambda richBox: {
            'obj_path': urllib.parse.quote_plus('/'.join(richBox['path'])),
        },
        predicate=rbPredicate,
    )
    #
    maxDepth = getMaxTreeDepth(dstBoxTree)
    colorShadeMap = prepareColorShadeMap(
        g.settings['color']['navigation_colors']['box']['value'],
        g.settings['color']['tree_shade_colors'][
            'shade_treeview_pickbox']['value'],
        numShades=1 + maxDepth,
    )
    destinationsExist = treeAny(
        dstBoxTree,
        property=lambda node: node['predicate'],
    )
    #
    return render_template(
        'dirtreeview.html',
        tree=dstBoxTree if destinationsExist else None,
        mode='box_move',
        object_quoted_path=quotedSrcBox,
        colorShadeMap=colorShadeMap,
        user=user,
        iconUrl=makeSettingImageUrl(g, 'app_images', 'move'),
        pageTitle='Select box destination',
        pageSubtitle=('Choose the box to which box "%s" '
                      'shall be moved from "%s"') % (
                            describeBoxTitle(box),
                            describeBoxTitle(parentBox),
                     ),
        actions=None,
        backToUrl=(None
                   if destinationsExist
                   else url_for(
                        'lsView',
                        lsPathString='/'.join(boxPath[1:]))),
        breadCrumbs=makeBreadCrumbs(
            boxPath,
            g,
            appendedItems=[
                {
                    'kind': 'link',
                    'target': None,
                    'name': 'Move box',
                }
            ],
        ),
    )
示例#6
0
def makeTicketBoxUploadView(boxPathString=''):
    """Make-upload-ticket (to a box) route."""
    user = g.user
    db = dbGetDatabase()
    boxPath = splitPathString(boxPathString)
    box = getBoxFromPath(db, boxPath, user)
    request._onErrorUrl = url_for(
        'lsView',
        lsPathString='/'.join(boxPath[1:]),
    )
    #
    if userHasPermission(db, user, box.permissions, 'w'):
        #
        pathBCrumbs = makeBreadCrumbs(
            boxPath,
            g,
            appendedItems=[
                {
                    'name': '(create upload ticket)',
                    'kind': 'link',
                    'target': url_for(
                        'makeTicketBoxUploadView',
                        boxPathString=boxPathString,
                    ),
                    'link': False,
                },
            ],
        )
        form = generateFsTicketForm(
            fileModePresent=False,
            settings=g.settings,
        )
        if form.validate_on_submit():
            magicLink = dbMakeUploadTicket(
                db=db,
                ticketName=form.name.data,
                validityHours=transformIfNotEmpty(
                    form.validityhours.data,
                    int,
                ),
                multiplicity=transformIfNotEmpty(
                    form.multiplicity.data,
                    int,
                ),
                ticketMessage=transformIfNotEmpty(
                    form.ticketmessage.data,
                ),
                box=box,
                boxPath=boxPath,
                user=user,
                urlRoot=request.url_root,
                settings=g.settings,
            )
            flashMessage(
                'Success',
                'Done',
                ('Upload ticket generated. Give the recipient '
                 'the following magic link:'),
                pillText=magicLink,
            )
            return redirect(url_for(
                'lsView',
                lsPathString='/'.join(boxPath[1:]),
            ))
        else:
            defaultName = 'Upload-To-%s' % (
                describeBoxName(box)
            )
            form.name.data = applyDefault(form.name.data, defaultName)
            form.ticketmessage.data = applyDefault(
                form.ticketmessage.data,
                'Please, upload files to this box',
            )
            maxValidityHours = g.settings['behaviour']['behaviour_tickets'][
                'max_ticket_validityhours']['value']
            form.validityhours.data = applyDefault(
                form.validityhours.data,
                str(maxValidityHours) if maxValidityHours is not None else '',
            )
            maxMultiplicity = g.settings['behaviour']['behaviour_tickets'][
                'max_ticket_multiplicity']['value']
            form.multiplicity.data = applyDefault(
                form.multiplicity.data,
                str(maxMultiplicity) if maxMultiplicity is not None else '',
            )
            return render_template(
                'fsticket.html',
                pageTitle='Create public upload ticket',
                pageSubtitle=('Recipient(s) of the ticket will be able to '
                              'upload to "%s", without an account, on '
                              'your behalf.') % (
                                    describeBoxTitle(box)
                               ),
                baseMultiplicityCaption='Number of granted file uploads',
                user=user,
                form=form,
                iconUrl=makeSettingImageUrl(g, 'app_images', 'upload_ticket'),
                showFileMode=False,
                breadCrumbs=pathBCrumbs,
            )
        #
    else:
        raise OstracionError('Insufficient permissions')
示例#7
0
def makeTicketBoxGalleryView(boxPathString=''):
    """Make-gallery-ticket-of-box route."""
    user = g.user
    db = dbGetDatabase()
    boxPath = splitPathString(boxPathString)
    box = getBoxFromPath(db, boxPath, user)
    request._onErrorUrl = url_for('lsView', lsPathString='/'.join(boxPath[1:]))
    #
    pathBCrumbs = makeBreadCrumbs(
        boxPath,
        g,
        appendedItems=[
            {
                'name': '(create gallery ticket)',
                'kind': 'link',
                'target': url_for(
                    'makeTicketBoxGalleryView',
                    boxPathString=boxPathString,
                ),
                'link': False,
            },
        ],
    )
    form = generateFsTicketForm(
        fileModePresent=False,
        settings=g.settings,
    )
    if form.validate_on_submit():
        magicLink = dbMakeGalleryTicket(
            db=db,
            ticketName=form.name.data,
            validityHours=transformIfNotEmpty(
                form.validityhours.data,
                int
            ),
            multiplicity=transformIfNotEmpty(
                form.multiplicity.data,
                int
            ),
            ticketMessage=transformIfNotEmpty(
                form.ticketmessage.data
            ),
            box=box,
            boxPath=boxPath,
            user=user,
            urlRoot=request.url_root,
            settings=g.settings,
        )
        flashMessage(
            'Success',
            'Done',
            ('Gallery ticket generated. Give the recipient '
             'the following magic link:'),
            pillText=magicLink,
        )
        return redirect(url_for(
            'lsView',
            lsPathString='/'.join(boxPath[1:]),
        ))
    else:
        defaultName = 'Gallery-View-%s' % describeBoxName(box)
        form.name.data = applyDefault(form.name.data, defaultName)
        form.ticketmessage.data = applyDefault(
            form.ticketmessage.data,
            'Please, look at this gallery',
        )
        maxValidityHours = g.settings['behaviour']['behaviour_tickets'][
            'max_ticket_validityhours']['value']
        form.validityhours.data = applyDefault(
            form.validityhours.data,
            str(maxValidityHours) if maxValidityHours is not None else '',
        )
        maxMultiplicity = g.settings['behaviour']['behaviour_tickets'][
            'max_ticket_multiplicity']['value']
        form.multiplicity.data = applyDefault(
            form.multiplicity.data,
            str(maxMultiplicity) if maxMultiplicity is not None else '',
        )
        return render_template(
            'fsticket.html',
            pageTitle='Create public gallery-view ticket',
            pageSubtitle=('Recipient(s) of the ticket will be able to view '
                          'files (and not contained boxes) in "%s", without '
                          'an account, as a gallery. If setting a number of '
                          'accesses, keep in mind that every single-file view'
                          ' counts toward the total accesses.') % (
                describeBoxTitle(box)
            ),
            baseMultiplicityCaption='Number of granted accesses',
            user=user,
            form=form,
            iconUrl=makeSettingImageUrl(g, 'app_images', 'gallery_ticket'),
            showFileMode=False,
            breadCrumbs=pathBCrumbs,
        )
示例#8
0
def editTextFileView(fsPathString=''):
    """Edit-text-file route."""
    user = g.user
    db = dbGetDatabase()
    lsPath = splitPathString(fsPathString)
    boxPath, fileName = lsPath[:-1], lsPath[-1]
    request._onErrorUrl = url_for(
        'lsView',
        lsPathString='/'.join(boxPath[1:]),
    )
    fileStorageDirectory = g.settings['system']['system_directories'][
        'fs_directory']['value']
    parentBox = getBoxFromPath(db, boxPath, user)
    file = getFileFromParent(db, parentBox, fileName, user)
    if file is None:
        raise OstracionError('File not found.')
    else:
        fileActions = prepareFileActions(
            db,
            file,
            boxPath[1:] + [file.name],
            parentBox,
            user,
            discardedActions={'text_edit'},
        )
        fileInfo = prepareFileInfo(db, file)
        form = EditTextFileForm()
        form.textformat.choices = [
            (mId, mDesc['title'])
            for mId, mDesc in sorted(
                textFileViewingModes.items(),
                key=lambda kv: kv[1]['index'],
            )
        ]
        ##
        if form.validate_on_submit():
            newcontents = form.filecontents.data
            filePath = fileIdToPath(
                file.file_id,
                fileStorageDirectory=fileStorageDirectory,
            )
            with open(filePath, 'w') as openFile:
                openFile.write('%s' % newcontents)
            # file properties
            fileProperties = determineFileProperties(filePath)
            newFile = File(**file.asDict())
            newFile.mime_type = fileProperties['file_mime_type']
            newFile.type = fileProperties['file_type']
            newFile.size = fileProperties['file_size']
            newFile.textual_mode = form.textformat.data
            newFile.editor_username = user.username
            updateFile(db, boxPath, file.name, newFile, user)
            #
            flashMessage('Info', 'Info', 'File "%s" saved.' % file.name)
            return redirect(
                url_for(
                    'lsView',
                    lsPathString='/'.join(boxPath[1:]),
                )
            )
        else:
            form.filecontents.data = applyDefault(
                form.filecontents.data,
                open(
                    fileIdToPath(
                        file.file_id,
                        fileStorageDirectory=fileStorageDirectory,
                    )
                ).read(),
            )
            form.textformat.data = applyDefault(
                form.textformat.data,
                file.textual_mode,
                additionalNulls=['None'],
            )
            pathBCrumbs = makeBreadCrumbs(
                boxPath,
                g,
                appendedItems=[
                    {
                        'kind': 'file',
                        'target': file,
                    },
                    {
                        'kind': 'link',
                        'target': None,
                        'name': 'Edit text',
                    }
                ],
            )
            return render_template(
                'edittextfile.html',
                user=user,
                form=form,
                fileActions=fileActions,
                fileInfo=fileInfo,
                pageTitle='"%s" file edit' % file.name,
                pageSubtitle='Click "Save" to commit the changes',
                breadCrumbs=pathBCrumbs,
            )
示例#9
0
def makeBoxView(parentBoxPathString=''):
    """MKBOX-in-a-box- route."""
    user = g.user
    form = makeMakeBoxForm('Create')()
    db = dbGetDatabase()
    parentBoxPath = splitPathString(parentBoxPathString)
    parentBox = getBoxFromPath(db, parentBoxPath, user)
    boxNiceName = describeBoxTitle(parentBox)
    request._onErrorUrl = url_for(
        'lsView',
        lsPathString='/'.join(parentBoxPath),
    )
    if form.validate_on_submit():
        #
        boxName = form.boxname.data
        boxDescription = form.boxdescription.data
        boxTitle = form.boxtitle.data
        #
        newBox = Box(
            box_name=boxName,
            title=boxTitle,
            description=boxDescription,
            icon_file_id='',
            nature='box',
            parent_id=parentBox.box_id,
            date=datetime.now(),
            creator_username=user.username,
            icon_file_id_username=user.username,
            metadata_username=user.username,
        )
        makeBoxInParent(db, parentBox, newBox, user, skipCommit=True)
        if parentBox.box_id == '':
            # the new box is a direct child of root:
            # act according to the localhost-mode policy setting
            rootChildAnonPerms = g.settings['behaviour'][
                'behaviour_permissions'][
                'rootchild_box_anonymous_permissions']['value']
            rcPermSet = {
                k: 1 if rootChildAnonPerms[i] != '_' else 0
                for i, k in enumerate('rwc')
            }
            # the above is a bit of a hack which parses the char
            # of the setting 'r__', 'rwc', ...
            rootChildBRP = BoxRolePermission(
                box_id=newBox.box_id,
                role_class='system',
                role_id='anonymous',
                **rcPermSet,
            )
            dbInsertBoxRolePermission(
                db,
                rootChildBRP,
                user,
                skipCommit=True,
            )
        #
        db.commit()
        additionalLsItems = [boxName]
        #
        return redirect(url_for(
            'lsView',
            lsPathString='/'.join(parentBoxPath[1:] + additionalLsItems),
        ))
    else:
        pathBCrumbs = makeBreadCrumbs(
            parentBoxPath,
            g,
            appendedItems=[{
                'kind': 'link',
                'target': None,
                'name': 'Make box',
            }],
        )
        return render_template(
            'makebox.html',
            form=form,
            user=user,
            breadCrumbs=pathBCrumbs,
            iconUrl=makeSettingImageUrl(g, 'app_images', 'standard_box'),
            pageTitle='Create box in "%s"' % boxNiceName,
            pageSubtitle='Name and title are mandatory',
        )
示例#10
0
def lsView(lsPathString=''):
    """LS-of-a-box route, additionally with 'tasks' if viewing root."""
    user = g.user
    lsPath = splitPathString(lsPathString)
    db = dbGetDatabase()
    thisBox = getBoxFromPath(db, lsPath, user)
    boxPath = lsPath[1:]
    #
    showBoxPermissionToAll = g.settings['behaviour']['behaviour_permissions'][
        'show_permission']['value']
    #
    if thisBox is not None:
        request._onErrorUrl = url_for('lsView')
        if thisBox.box_id == '':
            tasks = prepareRootTasks(db, g, user)
        else:
            tasks = []
        boxes = [
            {
                'box': box,
                'path': boxPath + [box.box_name],
                'info': prepareBoxInfo(db, box),
                'actions': prepareBoxActions(
                    db,
                    box,
                    boxPath + [box.box_name],
                    thisBox,
                    user
                ),
            }
            for box in sorted(
                (
                    b
                    for b in getBoxesFromParent(db, thisBox, user)
                    if b is not None
                ),
                key=lambda b: (b.box_name.lower(), b.box_name),
            )
            if box.box_id != ''
        ]
        files = [
            {
                'file': file,
                'path': boxPath + [file.name],
                'nice_size': formatBytesSize(file.size),
                'info': prepareFileInfo(db, file),
                'actions': prepareFileActions(
                    db,
                    file,
                    boxPath + [file.name],
                    thisBox,
                    user
                ),
            }
            for file in sorted(
                getFilesFromBox(db, thisBox),
                key=lambda f: (f.name.lower(), f.name),
            )
        ]
        links = [
            {
                'link': link,
                'path': boxPath + [link.name],
                'info': prepareLinkInfo(db, link),
                'actions': prepareLinkActions(
                    db,
                    link,
                    boxPath + [link.name],
                    thisBox,
                    user
                ),
            }
            for link in sorted(
                getLinksFromBox(db, thisBox),
                key=lambda l: (l.name.lower(), l.name),
            )
        ]
        #
        pathBCrumbs = makeBreadCrumbs(lsPath, g)
        boxNiceName = transformIfNotEmpty(thisBox.box_name)
        if thisBox.box_id == '':
            boxTitle, boxDescription = describeRootBoxCaptions(g)
        else:
            boxTitle = describeBoxTitle(thisBox)
            boxDescription = thisBox.description
        #
        boxActions = prepareBoxHeaderActions(
            db,
            thisBox,
            boxPath,
            user,
            g.settings,
            discardedActions=(
                set()
                if len(files) > 0
                else {'gallery_view', 'issue_gallery_ticket'}
            ),
        )
        showAdminToolsLink = userIsAdmin(db, user)
        if showBoxPermissionToAll or userIsAdmin(db, user):
            thisBoxPermissionAlgebra = calculateBoxPermissionAlgebra(
                thisBox.permissionHistory,
                thisBox.permissions,
            )
            #
            roleKeyToRoleMap = {
                r.roleKey(): r
                for r in dbGetAllRoles(db, user)
                if r.can_box != 0
            }
            structuredPermissionInfo = reformatBoxPermissionAlgebraIntoLists(
                thisBoxPermissionAlgebra,
                roleKeyToRoleMap,
            )
            #
            permissionInfo = {
                'powers': structuredPermissionInfo,
                'assignments': {
                    'edit_url': (
                        url_for(
                            'adminLsPermissionsView',
                            lsPathString='/'.join(boxPath),
                        )
                        if showAdminToolsLink
                        else None
                    ),
                    'native': [
                        {
                            'role_class': brp.role_class,
                            'role_id': brp.role_id,
                            'r': brp.r,
                            'w': brp.w,
                            'c': brp.c,
                            'role': roleKeyToRoleMap[(
                                brp.role_class,
                                brp.role_id,
                            )],
                        }
                        for brp in sorted(thisBox.listPermissions('native'))
                    ],
                    'inherited': [
                        {
                            'role_class': brp.role_class,
                            'role_id': brp.role_id,
                            'r': brp.r,
                            'w': brp.w,
                            'c': brp.c,
                            'role': roleKeyToRoleMap[(
                                brp.role_class,
                                brp.role_id,
                            )],
                        }
                        for brp in sorted(thisBox.listPermissions('inherited'))
                    ],
                },
            }
        else:
            permissionInfo = None
        #
        if len(boxes) + len(files) + len(links) > 0:
            foundCounts = [
                (len(boxes), 'box', 'boxes'),
                (len(files), 'file', 'files'),
                (len(links), 'link', 'links'),
            ]
            foundParts = pickSingularPluralSentences(
                foundCounts,
                keepZeroes=False,
            )
            boxChildrenCounter = colloquialJoinClauses(foundParts)
        else:
            boxChildrenCounter = 'no contents'
        #
        return render_template(
            'ls.html',
            user=user,
            thisBox=thisBox,
            boxTitle=boxTitle,
            boxNiceName=boxNiceName,
            boxDescription=boxDescription,
            pageTitle=boxNiceName,
            boxChildrenCounter=boxChildrenCounter,
            boxActions=boxActions,
            boxPath=boxPath,
            permissionInfo=permissionInfo,
            breadCrumbs=pathBCrumbs,
            tasks=tasks,
            boxes=boxes,
            files=files,
            links=links,
        )
    else:
        request._onErrorUrl = url_for(
            'lsView',
            lsPathString='/'.join(lsPath[1:-1]),
        )
        raise OstracionWarning(
            'Cannot access the specified box "%s"' % lsPath[-1]
        )
示例#11
0
def fsLinkMetadataView(fsPathString=''):
    """Edit-link-metadata view, a web-form."""

    user = g.user
    db = dbGetDatabase()
    form = EditLinkForm()
    lsPath = splitPathString(fsPathString)
    boxPath, prevLinkName = lsPath[:-1], lsPath[-1]
    parentBox = getBoxFromPath(db, boxPath, user)
    request._onErrorUrl = url_for(
        'lsView',
        lsPathString='/'.join(boxPath[1:]),
    )
    link = getLinkFromParent(db, parentBox, prevLinkName, user)
    if form.validate_on_submit():
        newLink = Link(**recursivelyMergeDictionaries(
            {
                'name': form.linkname.data,
                'description': form.linkdescription.data,
                'title': form.linktitle.data,
                'target': form.linktarget.data,
                'metadata_username': user.username,
                'metadata_dict': {
                    'open_in_new_window': form.openinnewwindow.data,
                },
            },
            defaultMap={
                k: v
                for k, v in link.asDict().items() if k not in {
                    'metadata', 'dvector_description', 'dvector_name',
                    'dvector_title'
                }
            },
        ))
        updateLink(db, boxPath, prevLinkName, newLink, user)
        return redirect(url_for('lsView', lsPathString='/'.join(boxPath[1:])))
    else:
        form.linkname.data = applyDefault(form.linkname.data, link.name)
        form.linkdescription.data = applyDefault(form.linkdescription.data,
                                                 link.description)
        form.linktitle.data = applyDefault(form.linktitle.data, link.title)
        form.linktarget.data = applyDefault(form.linktarget.data, link.target)
        form.openinnewwindow.data = link.getMetadata(
            'open_in_new_window',
            True,
        )
        #
        pageFeatures = {
            'breadCrumbs':
            makeBreadCrumbs(
                boxPath,
                g,
                appendedItems=[{
                    'kind': 'external_link',
                    'target': link,
                }, {
                    'kind': 'link',
                    'target': None,
                    'name': 'Metadata',
                }],
            ),
            'pageTitle':
            'Edit link metadata (%s)' % link.name,
            'pageSubtitle':
            'Name and target are mandatory',
            'iconUrl':
            url_for(
                'linkThumbnailView',
                dummyId=link.icon_file_id + '_',
                fsPathString='/'.join(lsPath[1:]),
            ),
        }
        return render_template(
            'editlink.html',
            form=form,
            user=user,
            **pageFeatures,
        )
示例#12
0
def makeTextFileView(fsPathString=''):
    """Generate-new-text-file route."""
    user = g.user
    form = MakeTextFileForm()
    db = dbGetDatabase()
    boxPath = splitPathString(fsPathString)
    request._onErrorUrl = url_for(
        'lsView',
        lsPathString='/'.join(boxPath[1:]),
    )
    fileStorageDirectory = g.settings['system']['system_directories'][
        'fs_directory']['value']
    parentBoxPath = boxPath
    parentBox = getBoxFromPath(db, parentBoxPath, user)
    if form.validate_on_submit():
        fileName = secure_filename(form.filename.data)
        savableFile = SavableTextFile('')
        filesToUpload = [
            {
                'box_id': parentBox.box_id,
                'name': fileName,
                'description': form.filedescription.data,
                'date': datetime.datetime.now(),
                'fileObject': savableFile,
            }
        ]
        makeThumbnails = g.settings['behaviour']['behaviour_appearance'][
            'extract_thumbnails']['value']
        savingResult = saveAndAnalyseFilesInBox(
            db=db,
            files=filesToUpload,
            parentBox=parentBox,
            user=user,
            fileStorageDirectory=fileStorageDirectory,
            thumbnailFormat='thumbnail' if makeThumbnails else None,
            pastActionVerbForm='created',
        )
        flashMessage('Success', 'Info', savingResult)
        return redirect(url_for(
            'editTextFileView',
            fsPathString='/'.join(parentBoxPath[1:] + [fileName]),
        ))
    else:
        pathBCrumbs = makeBreadCrumbs(
            parentBoxPath,
            g,
            appendedItems=[{
                'kind': 'link',
                'target': None,
                'name': 'New text',
            }],
        )
        return render_template(
            'maketextfile.html',
            form=form,
            user=user,
            breadCrumbs=pathBCrumbs,
            iconUrl=pickFileThumbnail('text/plain'),
            pageTitle='New text',
            pageSubtitle='Create a new text file in "%s"' % (
                describeBoxTitle(parentBox)
            ),
        )
示例#13
0
def uploadMultipleFilesView(fsPathString=''):
    """Upload-several-files (to a box) route."""
    user = g.user
    form = UploadMultipleFilesForm()
    db = dbGetDatabase()
    boxPath = splitPathString(fsPathString)
    request._onErrorUrl = url_for(
        'lsView',
        lsPathString='/'.join(boxPath[1:]),
    )
    fileStorageDirectory = g.settings['system']['system_directories'][
        'fs_directory']['value']
    parentBoxPath = boxPath
    parentBox = getBoxFromPath(db, parentBoxPath, user)
    #
    if form.validate_on_submit():
        uploadedFiles = [
            uf
            for uf in request.files.getlist('files')
            if uf.filename != ''
        ]
        #
        filesToUpload = [
            {
                'box_id': parentBox.box_id,
                'name': secure_filename(uploadedFile.filename),
                'description': form.filesdescription.data,
                'date': datetime.datetime.now(),
                'fileObject': uploadedFile,
            }
            for uploadedFile in uploadedFiles
        ]
        makeThumbnails = g.settings['behaviour']['behaviour_appearance'][
            'extract_thumbnails']['value']
        savingResult = saveAndAnalyseFilesInBox(
            db=db,
            files=filesToUpload,
            parentBox=parentBox,
            user=user,
            fileStorageDirectory=fileStorageDirectory,
            thumbnailFormat='thumbnail' if makeThumbnails else None,
        )
        flashMessage('Success', 'Info', savingResult)
        return redirect(url_for(
            'lsView',
            lsPathString='/'.join(parentBoxPath[1:]),
        ))
    else:
        pathBCrumbs = makeBreadCrumbs(
            parentBoxPath,
            g,
            appendedItems=[{
                'kind': 'link',
                'target': None,
                'name': 'Multiple upload',
            }],
        )
        return render_template(
            'uploadmultiplefiles.html',
            form=form,
            user=user,
            breadCrumbs=pathBCrumbs,
            pageTitle='Upload new files',
            pageSubtitle='Upload new files to box "%s"' % (
                describeBoxTitle(parentBox)
            ),
            iconUrl=makeSettingImageUrl(g, 'app_images', 'multiple_upload')
        )
示例#14
0
def fsMoveFileView(quotedFilePath):
    """Move-file, view 1/2: select destination box."""
    user = g.user
    db = dbGetDatabase()
    # first we find the file
    fsPathString = urllib.parse.unquote_plus(quotedFilePath)
    lsPath = splitPathString(fsPathString)
    boxPath, fileName = lsPath[:-1], lsPath[-1]
    parentBox = getBoxFromPath(db, boxPath, user)
    file = getFileFromParent(db, parentBox, fileName, user)
    # next we prepare the selectable destinations
    rootBox = getRootBox(db)

    def rbPredicate(richBox, idToAvoid=parentBox.box_id):
        return all((richBox['box'].box_id != idToAvoid,
                    userHasPermission(db, user, richBox['box'].permissions,
                                      'w')))

    dstBoxTree = collectTreeFromBox(
        db,
        rootBox,
        user,
        admitFiles=False,
        fileOrBoxEnricher=lambda richBox: {
            'obj_path': urllib.parse.quote_plus('/'.join(richBox['path'])),
        },
        predicate=rbPredicate,
    )
    #
    maxDepth = getMaxTreeDepth(dstBoxTree)
    colorShadeMap = prepareColorShadeMap(
        g.settings['color']['navigation_colors']['file']['value'],
        g.settings['color']['tree_shade_colors']['shade_treeview_pickbox']
        ['value'],
        numShades=1 + maxDepth,
    )
    destinationsExist = treeAny(
        dstBoxTree,
        property=lambda node: node['predicate'],
    )
    #
    return render_template(
        'dirtreeview.html',
        tree=dstBoxTree if destinationsExist else None,
        mode='file_move',
        object_quoted_path=quotedFilePath,
        colorShadeMap=colorShadeMap,
        user=user,
        iconUrl=makeSettingImageUrl(g, 'app_images', 'move'),
        pageTitle='Select file destination',
        pageSubtitle=(('Choose the box to which file "%s" shall '
                       'be moved from "%s"') % (
                           file.name,
                           describeBoxTitle(parentBox),
                       )),
        actions=None,
        backToUrl=None if destinationsExist else url_for(
            'lsView',
            lsPathString='/'.join(boxPath[1:]),
        ),
        breadCrumbs=makeBreadCrumbs(
            boxPath,
            g,
            appendedItems=[{
                'kind': 'file',
                'target': file,
            }, {
                'kind': 'link',
                'target': None,
                'name': 'Move file',
            }],
        ),
    )
示例#15
0
def metadataBoxView(boxPathString=''):
    """edit-metadata-of-box route."""
    user = g.user
    db = dbGetDatabase()
    boxPath = splitPathString(boxPathString)
    box = getBoxFromPath(db, boxPath, user)
    parentBox = getBoxFromPath(db, boxPath[:-1], user)
    request._onErrorUrl = url_for(
        'lsView',
        lsPathString='/'.join(boxPath[1:-1]),
    )
    #
    form = makeMakeBoxForm('Save')()
    if parentBox is None:
        # target box was root
        raise OstracionError('Cannot act on this object')
    else:
        if box is not None:
            #
            if form.validate_on_submit():
                newBox = Box(
                    **recursivelyMergeDictionaries(
                        {
                            'box_name': form.boxname.data,
                            'title': form.boxtitle.data,
                            'description': form.boxdescription.data,
                            'metadata_username': user.username,
                        },
                        defaultMap=box.asDict(),
                    )
                )
                updateBox(db, boxPath, newBox, user)
                return redirect(url_for(
                    'lsView',
                    lsPathString='/'.join(boxPath[1:-1]),
                ))
            else:
                form.boxname.data = applyDefault(
                    form.boxname.data,
                    box.box_name,
                )
                form.boxdescription.data = applyDefault(
                    form.boxdescription.data,
                    box.description,
                )
                form.boxtitle.data = applyDefault(
                    form.boxtitle.data,
                    box.title,
                )
                pathBCrumbs = makeBreadCrumbs(
                    boxPath,
                    g,
                    appendedItems=[{
                        'kind': 'link',
                        'target': None,
                        'name': 'Metadata',
                    }],
                )
                return render_template(
                    'makebox.html',
                    form=form,
                    user=user,
                    breadCrumbs=pathBCrumbs,
                    pageTitle='Edit box metadata',
                    pageSubtitle='Name and title are mandatory',
                    iconUrl=url_for(
                        'boxThumbnailView',
                        dummyId=box.icon_file_id + '_',
                        boxPathString='/'.join(boxPath[1:]),
                    ),
                )
            #
        else:
            raise OstracionWarning('Box not accessible')
    return redirect(url_for(
        'lsView',
        lsPathString='/'.join(boxPath[1:-1]),
    ))
示例#16
0
def fsGalleryView(fsPathString=''):
    """ Gallery view route on a box.
        If just box, redirect to first file.
        If a file, use the ls of files to prepare prev/next links.

        That is to say, if user has read permission on box, gallery URLs are
        not index-based, rather filename-based and recalculated on actual 'ls'.
    """
    isTopAccess = 1 if safeInt(request.args.get('top'), 0) != 0 else 0
    user = g.user
    fileStorageDirectory = g.settings['system']['system_directories'][
        'fs_directory']['value']
    db = dbGetDatabase()
    lsPath = splitPathString(fsPathString)
    # is it a box or a file?
    targetBox = getBoxFromPath(db, lsPath, user)
    if targetBox is not None:
        # if there are files, we redirect to the first one
        # otherwise, a message and falling back to ls view of the box
        files = sorted(
            getFilesFromBox(db, targetBox),
            key=lambda f: (f.name.lower(), f.name),
        )
        if len(files) > 0:
            return redirect(
                url_for(
                    'fsGalleryView',
                    fsPathString='/'.join(lsPath[1:] + [files[0].name]),
                    top=str(isTopAccess),
                ))
        else:
            flashMessage(
                'Info',
                'Empty box',
                'Cannot view as gallery a box without files',
            )
            return redirect(
                url_for(
                    'lsView',
                    lsPathString='/'.join(lsPath[1:]),
                ))
    else:
        # is it a file?
        boxPath, fileName = lsPath[:-1], lsPath[-1]
        parentBox = getBoxFromPath(db, boxPath, user)
        file = getFileFromParent(db, parentBox, fileName, user)
        if file is not None:
            if isTopAccess:
                # gallery navigation calculations
                files = sorted(
                    getFilesFromBox(db, parentBox),
                    key=lambda f: (f.name.lower(), f.name),
                )
                thisFileIndex = [
                    idx for idx, fil in enumerate(files)
                    if fil.name == fileName
                ][0]
                numGalleryFiles = len(files)
                nextFileIndex = (thisFileIndex + 1) % numGalleryFiles
                prevFileIndex = (thisFileIndex - 1 +
                                 numGalleryFiles) % numGalleryFiles
                #
                pathBCrumbs = makeBreadCrumbs(
                    boxPath,
                    g,
                    appendedItems=[{
                        'kind':
                        'link',
                        'name':
                        'Gallery view %i/%i' % (
                            thisFileIndex + 1,
                            numGalleryFiles,
                        ),
                        'target':
                        None,
                    }],
                )
                fileContents = produceFileViewContents(
                    db,
                    file,
                    mode='fsview',
                    viewParameters={
                        'boxPath': boxPath,
                        'fileName': fileName,
                    },
                    fileStorageDirectory=fileStorageDirectory,
                )
                fileActions = {
                    'gallery_prev':
                    url_for(
                        'fsGalleryView',
                        fsPathString='/'.join(boxPath[1:] +
                                              [files[prevFileIndex].name]),
                        top=str(isTopAccess),
                    ),
                    'gallery_next':
                    url_for(
                        'fsGalleryView',
                        fsPathString='/'.join(boxPath[1:] +
                                              [files[nextFileIndex].name]),
                        top=str(isTopAccess),
                    ),
                    'gallery_up':
                    url_for(
                        'lsView',
                        lsPathString='/'.join(boxPath[1:]),
                    ),
                    'download':
                    url_for(
                        'fsDownloadView',
                        fsPathString=fsPathString,
                    ),
                }
                return render_template(
                    'fileview.html',
                    fileActions=fileActions,
                    fileInfo=None,
                    filecontents=fileContents,
                    breadCrumbs=pathBCrumbs,
                    user=user,
                    pageTitle='"%s" gallery, file "%s" (%i/%i)' % (
                        parentBox.title,
                        file.name,
                        thisFileIndex + 1,
                        numGalleryFiles,
                    ),
                    pageSubtitle=file.description,
                    downloadUrl=None,
                    hideBreadCrumbs=True,
                    hideNavbar=True,
                )
            else:
                return fsDownloadView(fsPathString=fsPathString)
        else:
            # extreme fallback to ls, which will hiearchically
            # deal with the retrieval
            return redirect(url_for('lsView', lsPathString=fsPathString))
示例#17
0
def setIconView(mode, itemPathString=''):
    """ Route to set/replace the thumbnail of various items."""
    if (mode == 'au' and not g.settings['behaviour']['behaviour_admin_powers']
        ['admin_is_god']['value']):
        request._onErrorUrl = url_for('adminHomeUsersView')
        raise OstracionError('This feature is turned off in the configuration')
    else:
        user = g.user
        form = UploadIconForm()
        db = dbGetDatabase()
        tempFileDirectory = g.settings['system']['system_directories'][
            'temp_directory']['value']
        fileStorageDirectory = g.settings['system']['system_directories'][
            'fs_directory']['value']
        if mode == 'b':
            boxPath = splitPathString(itemPathString)
            request._onErrorUrl = url_for(
                'lsView',
                lsPathString='/'.join(boxPath[1:]),
            )
            parentBox = None
            thisItem = getBoxFromPath(db, boxPath, user)
            itemName = thisItem.getName()
            pageFeatures = {
                'breadCrumbs':
                makeBreadCrumbs(
                    splitPathString(itemPathString),
                    g,
                    appendedItems=[{
                        'kind': 'link',
                        'target': None,
                        'name': 'Icon',
                    }],
                ),
            }
        elif mode == 'f':
            fullPath = splitPathString(itemPathString)
            boxPath, fileName = fullPath[:-1], fullPath[-1]
            request._onErrorUrl = url_for(
                'lsView',
                lsPathString='/'.join(boxPath[1:]),
            )
            parentBox = getBoxFromPath(db, boxPath, user)
            thisItem = getFileFromParent(db, parentBox, fileName, user)
            itemName = thisItem.getName()
            pageFeatures = {
                'breadCrumbs':
                makeBreadCrumbs(
                    splitPathString(itemPathString)[:-1],
                    g,
                    appendedItems=[{
                        'kind': 'file',
                        'target': thisItem,
                    }, {
                        'kind': 'link',
                        'target': None,
                        'name': 'Icon',
                    }],
                ),
            }
        elif mode == 'l':
            fullPath = splitPathString(itemPathString)
            boxPath, linkName = fullPath[:-1], fullPath[-1]
            request._onErrorUrl = url_for(
                'lsView',
                lsPathString='/'.join(boxPath[1:]),
            )
            parentBox = getBoxFromPath(db, boxPath, user)
            thisItem = getLinkFromParent(db, parentBox, linkName, user)
            itemName = thisItem.getName()
            pageFeatures = {
                'breadCrumbs':
                makeBreadCrumbs(
                    splitPathString(itemPathString)[:-1],
                    g,
                    appendedItems=[{
                        'kind': 'external_link',
                        'target': thisItem,
                    }, {
                        'kind': 'link',
                        'target': None,
                        'name': 'Icon',
                    }],
                ),
            }
        elif mode == 'u':
            pageFeatures = prepareTaskPageFeatures(
                userProfilePageDescriptor,
                ['root', 'icon'],
                g,
                overrides={
                    'pageTitle': None,
                    'pageSubtitle': None,
                    'iconUrl': None,
                },
            )
            thisItem = user
            itemName = thisItem.getName()
            parentBox = None
        elif mode == 'au':
            pageFeatures = prepareTaskPageFeatures(
                adminPageDescriptor,
                ['root', 'users'],
                g,
                appendedItems=[{
                    'kind': 'link',
                    'link': False,
                    'target': None,
                    'name': 'Icon',
                }],
                overrides={
                    'pageTitle': None,
                    'pageSubtitle': None,
                    'iconUrl': None,
                },
            )
            if userIsAdmin(db, user):
                thisItem = dbGetUser(db, itemPathString)
                itemName = thisItem.getName()
                parentBox = None
            else:
                raise OstracionError('Insufficient permissions')
        elif mode == 's':
            pageFeatures = prepareTaskPageFeatures(
                adminPageDescriptor,
                ['root', 'settings', 'images'],
                g,
                appendedItems=[{
                    'kind': 'link',
                    'link': False,
                    'target': None,
                    'name': 'Set image',
                }],
                overrides={
                    'pageTitle': None,
                    'pageSubtitle': None,
                    'iconUrl': None,
                },
            )
            if userIsAdmin(db, user):
                settingGroupId, settingId = itemPathString.split('/')
                thisItem = g.settings['image'][settingGroupId][settingId]
                itemName = thisItem['setting'].getName()
                parentBox = None
            else:
                raise OstracionError('Insufficient permissions')
        else:
            raise RuntimeError('Unknown mode encountered')
        #
        if form.validate_on_submit():
            #
            storageSuccess = storeFileAsThumbnail(
                db,
                fileToSave=form.file.data,
                mode=mode,
                thumbnailFormat=determineThumbnailFormatByModeAndTarget(
                    db,
                    mode,
                    thisItem,
                ),
                targetItem=thisItem,
                parentBox=parentBox,
                user=user,
                tempFileDirectory=tempFileDirectory,
                fileStorageDirectory=fileStorageDirectory,
            )
            if not storageSuccess:
                raise OstracionError('Could not set the icon')
            #
            if mode in {'f', 'b', 'l'}:
                return redirect(
                    url_for(
                        'lsView',
                        lsPathString='/'.join(boxPath[1:-1] if mode ==
                                              'b' else boxPath[1:]),
                    ))
            elif mode == 'u':
                return redirect(url_for('userProfileView', ))
            elif mode == 'au':
                return redirect(url_for('adminHomeUsersView', ))
            elif mode == 's':
                return redirect(url_for('adminHomeSettingsImagesView', ))
            else:
                raise RuntimeError('Unknown mode encountered')
        else:
            #
            titleMap = {
                'f': 'Set File Icon',
                'l': 'Set Link Icon',
                'b': 'Set Box Icon',
                'u': 'Set User Icon',
                'au': 'Set User Icon (as admin)',
                's': 'Set Application Image',
            }
            modeNameMap = {
                'f': 'for file',
                'l': 'for link',
                'b': 'for box',
                'u': 'for user',
                'au': '(as admin) for user',
                's': 'for setting',
            }
            finalPageFeatures = recursivelyMergeDictionaries(
                {
                    'pageTitle':
                    titleMap[mode],
                    'pageSubtitle':
                    'Upload an image file %s "%s"' % (
                        modeNameMap[mode],
                        itemName,
                    ),
                },
                defaultMap=pageFeatures,
            )
            if mode == 'u':
                finalPageFeatures['iconUrl'] = url_for(
                    'userThumbnailView',
                    dummyId='%s_' % thisItem.icon_file_id,
                    username=thisItem.username,
                )
            elif mode == 'au':
                finalPageFeatures['iconUrl'] = url_for(
                    'userThumbnailView',
                    dummyId='%s_' % thisItem.icon_file_id,
                    username=thisItem.username,
                )
            elif mode == 's':
                finalPageFeatures['iconUrl'] = makeSettingImageUrl(
                    g,
                    settingGroupId,
                    settingId,
                )
            elif mode == 'b':
                finalPageFeatures['iconUrl'] = url_for(
                    'boxThumbnailView',
                    dummyId=thisItem.icon_file_id + '_',
                    boxPathString='/'.join(boxPath[1:]),
                )
            elif mode == 'f':
                finalPageFeatures['iconUrl'] = url_for(
                    'fileThumbnailView',
                    dummyId=thisItem.icon_file_id + '_',
                    fsPathString='/'.join(boxPath[1:] + [thisItem.name]),
                )
            elif mode == 'l':
                finalPageFeatures['iconUrl'] = url_for(
                    'linkThumbnailView',
                    dummyId=thisItem.icon_file_id + '_',
                    fsPathString='/'.join(boxPath[1:] + [thisItem.name]),
                )
            #
            return render_template(
                'uploadicon.html',
                form=form,
                user=user,
                mode=mode,
                itemPathString=itemPathString,
                **finalPageFeatures,
            )