Exemple #1
0
    def reorder(self, id, **params):
        if getparam('cancel') == '1':
            redirect(url("coll-view", id=id))
        coll = get_or_404(Collection, id)

        context = {}
        if cherrypy.request.method == "POST":
            # FIXME - check csrf token

            order, ordering = coll_order_from_request()

            if getparam('submit') == '1':
                # save order
                coll.autoorder.ordering = ordering
                Collection.objects.set(coll)
                Collection.objects.flush()
                redirect(url("coll-view", id=id))
        else:
            order = []
            for field, dir in coll.autoorder.ordering:
                order.append((len(order), field, dir))

        if not order:
            order.append((0, '', ''))

        context['coll'] = coll
        context['collorder'] = order
        return render("coll-reorder.html", context)
Exemple #2
0
def coll_parents_from_request():
    parents = []

    for num in getorderparam('order'):
        parent = getparam('parent%d' % num)
        if parent is None or parent == '':
            continue
        if getparam('del%d' % num) == '1':
            continue
        parents.append(unicode(parent))
    if getparam('add') == '1':
        parents.append(u'')

    return parents
Exemple #3
0
 def handle_post(self, params, context):
     context.update(self.build_form_context(params))
     do_import = getparam('import', None, None, params)
     if do_import:
         self.set_next(BuildExploratourRecordsTask(self.handler, self.importer))
         redirect(url("import", id=self.importer.id))
     return render("import/choose-fields.html", context)
Exemple #4
0
    def create(self, **params):
        context = {}

        if cherrypy.request.method == "POST":
            # FIXME - check csrf token
            title = params.get('newcoll_title', u'').strip()
            parents = coll_parents_from_request()
            if getparam('create'):
                if title:
                    id = create_collection(title, parents)
                    gonext()
                    redirect(url("colls-list", id=id))
                else:
                    context['error'] = "You must set a title for the collection"
        else:
            parents = []

        allowable_parents = set(
            c.id for c in Collection.objects
        )

        context.update(dict(
            parents = tuple(enumerate(parents)),
            allowable_parents = sorted(allowable_parents),
            collections = Collection.objects,
        ))

        return render("coll-new.html", context)
Exemple #5
0
 def handle_post(self, params, context):
     context.update(self.build_form_context(params))
     do_import = getparam('import', None, None, params)
     if do_import:
         self.set_next(ImportPerformTask(self.handler, self.importer))
         redirect(url("import", id=self.importer.id))
     return render("import/choose-mappings.html", context)
Exemple #6
0
    def imp(self, **params):
        stash = {}

        # Get any existing Importer
        imp = None
        imp_id = getintparam("id", None, stash, params)
        if imp_id is not None:
            imp = self.imports.get(imp_id, None)
            if imp is None:
                context = {}
                context['error'] = 'Unknown import ID'
                return render("import/choose-file.html", context)

        if imp is None:
            # No import in progress
            if cherrypy.request.method == "POST":
                return self.handle_import_start(params)
            elif cherrypy.request.method == "GET":
                return render("import/choose-file.html", {})
        else:
            # Import in progress; let it handle the request.
            if cherrypy.request.method == "POST":
                if getparam("import_cancel", None):
                    imp.cancel()
                    redirect(url("home"))
                return imp.handle_post(params)
            elif cherrypy.request.method == "GET":
                return imp.handle_get(params)

        raise cherrypy.NotFound
def record_from_simple_request(params):
    # Iterate through the parameters in order, getting the values and adding
    # them to the record.  The stack is used for groups.
    result = Record()
    ordering = map(int, filter(lambda x: x != '', getparam('ordering', '', params=params).split(',')))
    stack = [dict(item=result.root, repeat=False, remove=False, num=None)]
    for num in ordering:
        item = RecordItem_from_form(num, params=params)

        repeat = (getparam('repeat_%d' % num, '', params=params) != '')
        remove = (getparam('remove_%d' % num, '', params=params) != '')

        if item.tag == u'field':
            if remove:
                continue
            indent_previous(stack)
            elt = item.get_elt()
            stack[-1]['item'].append(elt)
            if repeat:
                # Special case for the "display" attribute - preserve it, for
                # file fields.
                newelt = copy_elt_without_values(elt, keep=('display',))
                indent_previous(stack)
                stack[-1]['item'].append(newelt)

        elif item.tag == u'group':
            if num == stack[-1]['num']:
                if len(stack) <= 1:
                    raise ValidationError("More groups closed than opened")
                indent_previous(stack, -1)
                if stack[-1]['remove']:
                    del stack[-2]['item'][-1]
                elif stack[-1]['repeat']:
                    # Repeat this element.
                    newgroup = copy_elt_without_values(stack[-1]['item'])
                    indent_previous(stack[:-1])
                    stack[-2]['item'].append(newgroup)
                del stack[-1]
            else:
                indent_previous(stack)
                elt = item.get_elt()
                stack[-1]['item'].append(elt)
                stack.append(dict(item=elt, repeat=repeat, remove=remove,
                                  num=num))

    return result
Exemple #8
0
    def reparent(self, id, **params):
        if getparam('cancel') == '1':
            redirect(url("coll-view", id=id))
        coll = get_or_404(Collection, id)

        if cherrypy.request.method == "POST":
            # FIXME - check csrf token

            title = getparam('title')
            parents = coll_parents_from_request()

            if getparam('submit') == '1':
                # Save parents
                changed = coll.set_parents(filter(lambda x: x != '', parents))
                if coll.title != title:
                    coll.title = title
                Collection.objects.set(coll)
                Collection.objects.flush()
                Record.objects.flush()
                redirect(url("coll-view", id=id))
        else:
            title = coll.title
            parents = []
            for parent in coll.parents:
                parents.append(parent)
        if not parents:
            parents.append('')

        not_allowed = set(coll.ancestors) - set(coll.parents)
        not_allowed.add(id)

        allowable_parents = set(
            c.id for c in Collection.objects
            if c.id != id and id not in c.ancestors
        )

        context = dict(
            title = title,
            coll = coll,
            parents = tuple(enumerate(parents)),
            allowable_parents = sorted(allowable_parents),
            collections = Collection.objects,
        )

        return render("coll-reparent.html", context)
Exemple #9
0
def coll_order_from_request():
    order = []
    ordering = []

    # Read collection order from request.
    for num in getorderparam('order'):
        field = getparam('field%d' % num)
        dir = getparam('dir%d' % num)
        if field is None or '_' not in field or dir is None:
            continue
        if getparam('del%d' % num) == '1':
            continue
        order.append((len(order), field, dir))
        ordering.append((field, dir))
    if getparam('add') == '1':
        order.append((len(order), '', ''))

    return order, ordering
    def read_params(self, stash, params):
        self.collid = getparam('coll', None, stash, params)
        self.incmedia = getparam('incmedia', 'include', stash, params)
        self.mediabase = getparam('mediabase', '', stash, params)

        self.frontpage = None
        if self.collid:
            types_available, dates_available = self.types_in_collection(self.collid)
            coll = Collection.objects.get(self.collid)
            if coll is not None:
                allowed_ancestors = self.allowed_ancestors(coll)
                maintab = self.coll_maintab(coll, types_available, dates_available,
                                            allowed_ancestors)
                if not coll.has_children:
                    subs = 'coll'
                else:
                    subs = 'all'
                self.frontpage = 'coll/%s/%s/detail/%s/index.html' % \
                    (self.collid, maintab, subs)
Exemple #11
0
    def export_backup(self, export_id=None, download=False, **params):
        # Read parameters first, to ensure they all get stashed.
        stash = {}

        # Make a new exporter, and get any parameters it needs into the stash.
        exp = Exporter.get('xml')()
        exp.read_params(stash, params)

        # Handle exports which are in progress, or have finished
        if export_id is not None:
            try:
                export_id = int(export_id)
            except ValueError:
                export_id = None
        if export_id is not None:
            try:
                running_exp = exports[export_id]
            except KeyError:
                # Invalid export id (most probably due to a server restart)
                running_exp = None
            if running_exp is not None:
                # Export in progress
                progress = pool.get_progress(export_id)
                context = dict(export_id=export_id, fmt='xml', progress=progress,
                               stash=stash)
                if not progress.complete:
                    return render('export/in_progress.html', context)
                if progress.failed:
                    return render('export/failed.html', context)
                # Export complete
                if not download:
                    # Display a "Export prepared"
                    return render('export/complete.html', context)
                return running_exp.respond()

        # Read the set of things to export.
        search, desc, topcoll = self._get_export_records(stash, None, None, None, True)

        if not getparam('export', False, stash, params):
            # Not ready to start the export yet.
            context = dict(
                           export_desc = desc,
                           stash = stash,
                          )

            exp.add_to_context(context, search, stash, params)
            return render('backup/pick.html', context)

        # Start the exporter
        task = ExportRecords(exp, search)
        export_id = pool.add_task(task)
        exports[export_id] = task

        redirect(url("records-export-inprogress", export_id=export_id, fmt='xml', **stash))
Exemple #12
0
 def handle_import_start(self, params):
     """Handle a POST request that starts an import."""
     if getparam("import_cancel", None):
         redirect(url("home"))
     imp = download.Importer()
     imp.start(params)
     if imp.error:
         context = {}
         context['error'] = imp.error
         return render("import/choose-file.html", context)
     self.imports[imp.id] = imp
     redirect(url("import", id=imp.id))
 def write_search(self, params):
     params = dict(params)
     stash = {}
     context = dict(stash=stash)
     searchparams = SearchParams(stash, params)
     search = Search(searchparams, url_fn=self.url)
     if self.collid is not None:
         search.restrict_to_collection(self.collid)
     search.add_to_context(context)
     context['showfull'] = int(getparam('showfull', '1', stash, params))
     self.render('search', (), params,
                 "export/html/search.html", context)
Exemple #14
0
    def view(self, id, **params):
        context = {}

        stash = {}
        showfull = int(getparam('showfull', '0', stash))
        search = build_search(stash)

        # FIXME - hack
        q = search['q']
        q.startrank = 0
        q.endrank = 20000
        items = q.results

        ids = set()
        for item in items:
            if item.data['type'][0] != 'r': continue
            ids.add(item.data['id'][0])
        points = []
        for id in sorted(ids):
            rec = Record.objects.get(unicode(id))
            date = rec.root.find("field[@type='date']")
            if date is None:
                continue
            date = date.text
            if date is None:
                continue
            mo = single_full_bamboostyle_date_re.match(date) 
            if not mo:
                continue
            day, month, year = map(lambda x: int(x), (mo.group(1), mo.group(2), mo.group(3)))
            date = datetime.date(year, month, day)

            locs = rec.root.findall(".//field[@type='location']")
            for loc in locs:
                ll = latlongparse(loc.get('latlong'))
                if ll is None:
                    continue
                points.append([ll.lat, ll.long, rec.id, date])

        points.sort(key=lambda x: x[3])
        startdate = points[0][3]
        for i in xrange(len(points)):
            days = (points[i][3] - startdate).days
            points[i][3] = points[i][3].isoformat()
            points[i].append(days)

        context['points'] = points
        context['center_point'] = [points[0][0], points[0][1], 7]

        return render("dataview.html", context)
Exemple #15
0
 def list(self, **params):
     coll = get_lockto_coll()
     if coll is not None:
         redirect(url("coll-view", id=coll.id))
     groups = [CollGroup(coll.id, coll.title, [coll.id])
               for coll in Collection.objects if not coll.parents]
     groupid = getparam('groupid', '')
     filtered_groups = filter(lambda group: group.id == groupid, groups)
     if len(filtered_groups) > 0:
         currgroup = filtered_groups[0]
     elif len(groups) > 0:
         currgroup = groups[0]
     else:
         currgroup = None
     context = dict(groups=groups, currgroup=currgroup)
     return render("colls-list.html", context)
Exemple #16
0
    def build_form_context(self, params):
        context = {}
        class Info(object):
            def __init__(self, **kwargs):
                for k, v in kwargs.items():
                    setattr(self, k, v)

        # Determine how conflicts should be resolved
        self.handler.record_conflict_resolution = self.get_conflict_option('record_conflict', params)
        context['record_conflict'] = self.handler.record_conflict_resolution

        self.handler.coll_conflict_resolution = self.get_conflict_option('coll_conflict', params)
        context['coll_conflict'] = self.handler.coll_conflict_resolution

        # Get the media root mappings supplied by the client.
        media_root_mappings = {}
        for num, (root, rootinfo) in enumerate(sorted(self.handler.media_roots.items())):
            newroot = getparam('r%d' % num, root, None, params)
            rootinfo['newroot'] = newroot
            if newroot != root:
                media_root_mappings[root] = newroot
        self.handler.update_media_root_mappings(media_root_mappings)

        # Calculate the info, after the mappings have been applied.
        info = Info(filename = self.importer.filename,
                    records_count = len(self.handler.records),
                    record_identical = self.handler.record_identical,
                    record_conflicts = self.handler.record_conflicts,
                    record_new = self.handler.record_new,
                    collections = self.handler.collections,
                    coll_identical = self.handler.coll_identical,
                    coll_conflicts = self.handler.coll_conflicts,
                    coll_new = self.handler.coll_new,
                    media_files_count = len(self.handler.media_paths),
                    media_roots = enumerate(sorted(self.handler.media_roots.items())),
                   )
        context['info'] = info
        context['import_id'] = getintparam("id", None, None, params)
        return context
Exemple #17
0
 def read_params(self, stash, params):
     self.fields = getparamlist("f", None, stash, params)
     self.forder = getparam("forder", "record", stash, params)
Exemple #18
0
    def export_records(self, export_id=None, fmt='rtf', download=False,
                       **params):
        """Export a set of records.

        """
        # Read parameters first, to ensure they all get stashed.
        stash = {}
        record_id = getparam('record_id', None, stash, params)
        issearch = getparam('issearch', None, stash, params)
        coll = getparam('coll', None, stash, params)
        incsubs = getintparam('incsubs', 1, stash, params)

        # Make a new exporter, and get any parameters it needs into the stash.
        try:
            exp = Exporter.get(fmt)()
        except KeyError:
            raise cherrypy.NotFound
        exp.read_params(stash, params)

        # Handle exports which are in progress, or have finished
        if export_id is not None:
            try:
                export_id = int(export_id)
            except ValueError:
                export_id = None
        if export_id is not None:
            try:
                running_exp = exports[export_id]
            except KeyError:
                # Invalid export id (most probably due to a server restart)
                running_exp = None
            if running_exp is not None:
                # Export in progress
                progress = pool.get_progress(export_id)
                context = dict(export_id=export_id, fmt=fmt, progress=progress,
                               stash=stash)
                if not progress.complete:
                    return render('export/in_progress.html', context)
                if progress.failed:
                    return render('export/failed.html', context)
                # Export complete
                if not download:
                    # Display a "Export prepared"
                    return render('export/complete.html', context)
                return running_exp.respond()

        # Read the set of things to export.
        search, desc, topcoll = self._get_export_records(stash, record_id, issearch,
                                                coll, incsubs)

        if not getparam('export', False, stash, params):
            # Not ready to start the export yet.
            context = dict(
                           fmts = Exporter.fmts(params),
                           fmt = fmt,
                           export_desc = desc,
                           stash = stash,
                          )

            exp.add_to_context(context, search, stash, params)
            return render('export/pickfmt.html', context)

        # Start the exporter
        task = ExportRecords(exp, search)
        export_id = pool.add_task(task)
        exports[export_id] = task

        redirect(url("records-export-inprogress", export_id=export_id, fmt=fmt, **stash))
Exemple #19
0
    def search(self, **params):
        stash = {}
        context = dict(stash=stash)
        params = SearchParams(stash)
        search = Search(params)
        if not search.validate():
            # If the search doesn't validate, always go to the search entry
            # page.
            params.action = 'entry'
        search.add_to_context(context)
        context['showfull'] = int(getparam('showfull', '0', stash))

        if params.action == 'search':
            return render("search.html", context)
        elif params.action == 'select':
            return render("search_select.html", context)

        elif params.action.startswith('createcoll'):
            if cherrypy.request.method != "POST":
                return render("search_createcoll.html", context)
            subact = params.action[11:]

            parents = []
            for num in getorderparam('parent_order'):
                parent = getparam('parent%d' % num)
                if parent is None or parent == '':
                    continue
                if subact == ('del_parent_%d' % num):
                    continue
                parents.append(unicode(parent))
            if subact == 'add_parent':
                parents.append(u'')
            context['parents'] = tuple(enumerate(parents))
            context['allowable_parents'] = set(
                c.id for c in Collection.objects
            )
            context['collections'] = Collection.objects

            if subact == 'do':
                newtitle = getparam('create_colltitle', '')
                if len(newtitle) == 0:
                    context['error'] = "Cannot create collection with no title"
                    return render("search_createcoll.html", context)

                coll = Collection.find_by_title(newtitle)
                if len(coll) != 0:
                    context['error'] = "Collection with title %s already exists" % newtitle
                    return render("search_createcoll.html", context)

                coll = Collection(None, None, newtitle)
                Collection.objects.set(coll)
                # Have to set the collection before setting the parents, to get
                # an ID for the parents to refer back to.
                coll.set_parents(filter(lambda x: x != '', parents))
                Collection.objects.set(coll)
                Record.objects.flush()
                Collection.objects.flush()

                for record in search.query:
                    record = record.object
                    record.collections = record.collections + [coll.id]
                    Record.objects.set(record)
                Record.objects.flush()
                Collection.objects.flush()

                redirect(url("coll-view", id=coll.id))
            else:
                return render("search_createcoll.html", context)

        elif params.action == 'addtocoll':
            context['all_collections'] = Collection.objects
            if cherrypy.request.method != "POST":
                return render("search_addtocoll.html", context)

            newid = getparam('addto_collid', '')
            if len(newid) == 0:
                context['error'] = "Pick a collection to add to"
                return render("search_addtocoll.html", context)

            coll = Collection.objects.get(newid)
            for record in search.query:
                record = record.object
                record.collections = record.collections + [coll.id]
                Record.objects.set(record)
            Record.objects.flush()
            Collection.objects.flush()

            redirect(url("coll-view", id=coll.id))

            return render("search_addtocoll.html", context)

        elif params.action == 'removefromcoll':
            context['all_collections'] = Collection.objects
            if cherrypy.request.method != "POST":
                return render("search_removefromcoll.html", context)

            newid = getparam('removefrom_collid', '')
            if len(newid) == 0:
                context['error'] = "Pick a collection to remove from"
                return render("search_removefromcoll.html", context)

            coll = Collection.objects.get(newid)
            for record in search.query:
                record = record.object
                record.collections = tuple(filter(lambda x: x != coll.id,
                                                  record.collections))
                Record.objects.set(record)
            Record.objects.flush()
            Collection.objects.flush()

            redirect(url("coll-view", id=coll.id))

            return render("search_removefromcoll.html", context)

        else:
            context['all_collections'] = Collection.objects
            return render("search_entry.html", context)
 def is_valid(cls, params):
     """Check if the exporter is valid for the given parameters."""
     collid = getparam('coll', None, None, params)
     if collid is None:
         return False
     return True
    def write_collection(self, params):
        params = dict(params)
        id = unicode(params['id'][0])
        del params['id']

        coll = Collection.objects.get(id)
        if coll is None:
            return
        if self.collid != id and self.collid not in coll.ancestors:
            return

        # Massive cut and paste follows
        def items_of_type(type, cons, order, incsubs, reverse, hpp):
            q = coll.items_from_search(type=type, incsubs=incsubs)

            if order != 'collection':
                q = q.order_by_multiple([])
                order_key = order
                if order.startswith('+'):
                    order_key, asc = order[1:], True
                elif order.startswith('-'):
                    order_key, asc = order[1:], False
                else:
                    order_key, asc = order, False
                q = q.order_by(order_key, asc)

            max_hpp = int(math.ceil(hpp * 1.25))
            items = q[startrank:startrank + max_hpp]
            if len(items) >= max_hpp:
                items = items[:hpp]
            return dict(coll_size=q.matches_estimated, items=items)

        stash = {}
        order = getparam('order', 'collection', stash, params)
        incsubs = int(getparam('incsubs', '1', stash, params))
        reverse = int(getparam('reverse', '0', stash, params))
        startrank = int(getparam('startrank', '0', stash, params))
        hpp = int(getparam('hpp', '100', stash, params))
        tab = getparam('tab', 'records', stash, params)

        # FIXME - do a faceted search to check which type tabs to show.
        types_available, dates_available = self.types_in_collection(id)
        allowed_ancestors = self.allowed_ancestors(coll)

        tabs = self.tabs_for_collection(coll, types_available, dates_available,
                                        allowed_ancestors)

        context = dict(
            stash = stash,
            tab = tab,
            tabs = tabs,
            startrank = startrank,
            coll = coll,
            incsubs = incsubs,
        )

        pagination_params = dict(
            hpp = hpp,
            order = order,
            reverse = reverse,
            showfull = int(getparam('showfull', '1', stash, params)),
        )

        if tab == 'parents':
            context['ancestor_objs'] = allowed_ancestors

        if tab == 'records':
            context.update(pagination_params)
            context.update(items_of_type('record', lambda x: x, order, incsubs, reverse, hpp))
        if tab == 'images':
            context.update(pagination_params)
            context.update(items_of_type('image', lambda x: x, order, incsubs, reverse, hpp))
        if tab == 'video':
            context.update(pagination_params)
            context.update(items_of_type('video', lambda x: x, order, incsubs, reverse, hpp))
        if tab == 'audio':
            context.update(pagination_params)
            context.update(items_of_type('audio', lambda x: x, order, incsubs, reverse, hpp))
        if tab == 'media':
            context.update(pagination_params)
            context.update(items_of_type('media', lambda x: x, order, incsubs, reverse, hpp))
        if tab == 'calendar':
            calstyle = getparam('calstyle', 'year', stash, params)
            if calstyle not in ('year', 'month', 'day'):
                calstyle = 'year'
            datefield = getparam('datefield', 'date', stash, params)

            startdate = getparam('startdate', '', stash, params)
            year = getparam('year', None, None, params)
            month = getparam('month', None, None, params)
            day = getparam('day', None, None, params)

            incsubs = True # FIXME - no UI to set at present
            context.update(calendar_items(id, incsubs, calstyle, startdate,
                                          year, month, day,
                                          datefield))
            stash['startdate'] = [context['startdate']]

        if tab == 'children':
            context['direct_records'] = items_of_type('record', lambda x: x, 'collection', 0, False, 10)

        if tab.startswith('x'):
            context['currpage'] = coll.page(tab[1:])

        params['id'] = id
        self.render('coll-view', (), params,
                    "export/html/coll-view.html", context)
    def lookup_path_internal(self, name, args, kwargs):
        #print name, args, kwargs
        kwargs = get_args(kwargs)
        if name == 'static':
            static = u'/'.join(args)
            if '..' in static.split('/') or static.startswith('/'):
                print "error: invalid static %r" % static
                return u'404.html'
            self.gen_static.add(static)
            return u'static/' + static
        if name == 'record-view':
            return u'record/%s.html' % kwargs['id']
        if name == 'media':
            path = kwargs['path']
            self.gen_media.add(path)
            return u'media%s' % path
        if name == 'mediapreview':
            path = kwargs['path']
            self.gen_media.add(path)
            htmlpath = path + '.html'
            return u'mediaview%s' % htmlpath
        if name == 'thumbnail':
            path = kwargs['path']
            width = kwargs['width']
            width = kwargs.get('width')
            height = kwargs.get('height')
            self.gen_thumbnails.add((path, width, height))
            fmt = get_format(path)
            if path.endswith(fmt):
                thumbpath = path
            else:
                thumbpath = path.rsplit('.', 1)[0] + '.' + fmt
            if width is None:
                return u'thumbnail/full/%s' % (thumbpath, )
            else:
                return u'thumbnail/%d/%d%s' % (width, height, thumbpath)
        if name == 'record-gallery':
            id = kwargs['id']
            offset = kwargs.get('offset', None)
            if offset is None:
                show = kwargs['show']
                offset = self.gallery_offset(id, show)
            self.gen_gallery.add((id, offset))
            return u'record/%s/gallery/%s.html' % (id, offset)
        if name == 'coll-view':
            collid = getparam('id', '', None, kwargs)
            tab = getparam('tab', None, None, kwargs)
            if tab is None:
                types_available, dates_available = self.types_in_collection(collid)
                coll = Collection.objects.get(collid)
                if coll is not None:
                    allowed_ancestors = self.allowed_ancestors(coll)
                    tab = self.coll_maintab(coll, types_available, dates_available,
                                            allowed_ancestors)
            if tab is None:
                tab = 'records'
            startrank = int(getparam('startrank', '0', None, kwargs))
            showfull = int(getparam('showfull', '0', None, kwargs))
            incsubs = int(getparam('incsubs', '0', None, kwargs))

            if tab not in ('records', 'images', 'video', 'audio', 'media'):
                startrank = 0
                showfull = 1
                incsubs = 1

            params = dict(id=collid, tab=tab, startrank=startrank,
                          incsubs=incsubs, showfull=showfull)
            key = tuple(sorted((k, tupleify(v)) for (k, v) in params.iteritems()))
            if key not in self.gen_colls:
                #print "ADDING", key
                #print '\n'.join(map(str, self.gen_colls))
                self.gen_colls.add(key)
                self.ungenerated_colls.add(key)
            if showfull:
                showfull = 'detail'
            else:
                showfull = 'list'
            if incsubs:
                incsubs = 'all'
            else:
                incsubs = 'coll'
            if startrank:
                startrank = 'from_%s' % startrank
            else:
                startrank = 'index'
            return u'coll/%s/%s/%s/%s/%s.html' % (collid, tab, showfull, incsubs, startrank)

        if name == 'search':
            try:
                del kwargs['act']
            except KeyError: pass

            if '*' in kwargs.get('collid', ()):
                del kwargs['collid']

            showfull = kwargs.get('showfull', ())
            if isinstance(showfull, int):
                pass
            elif len(showfull) > 0 and int(showfull[0]) == 0:
                showfull = 0
            else:
                showfull = 1
            kwargs['showfull'] = [showfull]

            startrank = kwargs.get('startrank', ())
            if isinstance(startrank, int):
                pass
            elif len(startrank) > 0:
                startrank = int(startrank[0])
            else:
                startrank = 0
            kwargs['startrank'] = [startrank]

            qs = kwargs.get('qs', ())
            newqs = []
            for qnum in qs:
                # If there aren't corresponding q%df items skip this one.
                qnum = int(qnum)
                qf = kwargs.get('q%df' % qnum)
                if qf is not None:
                    newqs.append(str(qnum))
            kwargs['qs'] = tuple(newqs)

            if not kwargs.get('ttypes'):
                kwargs['ttypes'] = ('record', )
            key = tuple(sorted((k, tupleify(v)) for (k, v) in kwargs.iteritems()))
            searchid = self.gen_searches.get(key, None)
            if searchid is None:
                searchid = self.gen_search_id(key)
                self.gen_searches[key] = searchid
                self.search_ids[searchid] = key
                self.ungenerated_searches.add(key)
            return u'search/%s.html' % (searchid, )

        if name == 'export-toppage':
            return u'index.html'

        print 'unhandled URL: ', repr(name), repr(args), repr(kwargs)
        return u'404.html'
Exemple #23
0
    def view(self, id, **params):
        coll = get_or_404(Collection, id)

        def types_in_collection(collid):
            q = SearchCollection.field.coll.is_or_is_descendant(collid)
            q = q.calc_occur('!', '').check_at_least(-1)
            q = q.calc_facet_count('date', result_limit=2)
            q = q[:0]
            return dict(q.info[0]['counts']), q.info[1]

        def items_of_type(type, cons, order, incsubs, reverse, hpp):
            q = coll.items_from_search(type=type, incsubs=incsubs)

            if order != 'collection':
                q = q.order_by_multiple([])
                order_key = order
                if order.startswith('+'):
                    order_key, asc = order[1:], True
                elif order.startswith('-'):
                    order_key, asc = order[1:], False
                else:
                    order_key, asc = order, False
                q = q.order_by(order_key, asc)

            max_hpp = int(math.ceil(hpp * 1.25))
            items = q[startrank:startrank + max_hpp]
            if len(items) >= max_hpp:
                items = items[:hpp]
            return dict(coll_size=q.matches_estimated, items=items)

        stash = {}
        order = getparam('order', 'collection', stash, params)
        incsubs = int(getparam('incsubs', '1', stash, params))
        reverse = int(getparam('reverse', '0', stash, params))
        startrank = int(getparam('startrank', '0', stash, params))
        hpp = int(getparam('hpp', '100', stash, params))
        tab = getparam('tab', 'records', stash, params)

        tabs = []

        # FIXME - do a faceted search to check which type tabs to show.
        types_available, dates_available = types_in_collection(id)

        for page in coll.leading_tabs():
            tabs.append("x" + page.id)

        if coll.parents:
            tabs.append('parents')
        #if 'r' in types_available:
        tabs.append("records")
        if coll.children:
            tabs.append('children')
        if 'image' in types_available:
            tabs.append("images")
        if 'video' in types_available:
            tabs.append("video")
        if 'audio' in types_available:
            tabs.append("audio")
        if 'media' in types_available:
            tabs.append("media")
        if dates_available['values_seen'] >= 1:
            tabs.append("calendar")

        context = dict(
            stash = stash,
            tab = tab,
            tabs = tabs,
            startrank = startrank,
            hpp = hpp,
            coll = coll,
            order = order,
            incsubs = incsubs,
            reverse = reverse,
            showfull = int(getparam('showfull', '1', stash, params)),
        )

        if tab == 'records':
            context.update(items_of_type('record', lambda x: x, order, incsubs, reverse, hpp))
        if tab == 'images':
            context.update(items_of_type('image', lambda x: x, order, incsubs, reverse, hpp))
        if tab == 'video':
            context.update(items_of_type('video', lambda x: x, order, incsubs, reverse, hpp))
        if tab == 'audio':
            context.update(items_of_type('audio', lambda x: x, order, incsubs, reverse, hpp))
        if tab == 'media':
            context.update(items_of_type('media', lambda x: x, order, incsubs, reverse, hpp))
        if tab == 'calendar':
            calstyle = getparam('calstyle', 'year', stash, params)
            if calstyle not in ('year', 'month', 'day'):
                calstyle = 'year'
            datefield = getparam('datefield', 'date', stash, params)

            startdate = getparam('startdate', '', stash, params)
            year = getparam('year', None, None, params)
            month = getparam('month', None, None, params)
            day = getparam('day', None, None, params)

            incsubs = True # FIXME - no UI to set at present
            context.update(calendar_items(id, incsubs, calstyle, startdate,
                                          year, month, day,
                                          datefield))
            stash['startdate'] = [context['startdate']]

        if tab == 'children':
            context['direct_records'] = items_of_type('record', lambda x: x, 'collection', 0, False, 10)

        if tab.startswith('x'):
            context['currpage'] = coll.page(tab[1:])

        if params.get('lockto', None) == 'set':
            set_lockto_collid(id)

        elif params.get('lockto', None) == 'unset':
            unset_lockto_collid()

        return render("coll-view.html", context)
Exemple #24
0
def param_from_form(key, required=True, params=None):
    val = getparam(key, params=params)
    if required and val is None:
        raise ValidationError("Missing parameter %s" % key)
    return val
Exemple #25
0
 def get_conflict_option(self, paramname, params):
     value = getparam(paramname, 'newid', None, params)
     if value not in ('overwrite', 'skip', 'newid', 'allnewid'):
         value = 'newid'
     return value