def search():
    t = request.args.get('type', 'all')
    s = request.args.get('term', '').lower()
    c = request.args.get('custom', '') == 'true';
    #l = request.args.get('label', '%(uri)s')

    if (s == ''):
        return "{}"

    ontologies=['']
    ontologies.extend(os.listdir(ONTOLOGY_DIR))
    results = []
    if t == 'all' or t == 'subjects':
        for subj in maingraph.subjects():
            subj = str(subj)
            try:
                subjlabel = str(get_label(subj))
            except:
                subjlabel = subj
            try:
                subjqname =  str(get_qname(subj))
            except:
                subjqname =  subj
            if s in subj.lower() or s in subjlabel.lower() or s in subjqname.lower():
                item = {'uri':subj, 'qname': subjqname, 'label': subjlabel}
                if item not in results:
                    results.append(item)
    if t == 'predicates':
        for pred,_,_ in maingraph.triples((None, RDF.type, RDF.Property)):
            pred = str(pred)
            try:
                predlabel = str(get_label(pred))
            except:
                predlabel = pred
            try:
                predqname =  str(get_qname(pred))
            except:
                predqname =  pred
            if s in pred.lower() or s in predlabel.lower() or s in predqname.lower():
                item = {'uri':pred, 'qname': predqname, 'label': predlabel}
                if item not in results:
                    results.append(item)
    if c:
        results.append({'uri':s})
    return json.dumps(results)
def prepare_nquads_for_template(nquads):
    changes = {}
    for q in nquads:
        ctx = changes.get(q['context'], {'prefix': get_prefix_from_uri(q['context'])})
        sub = ctx.get(q['subject'], {'qname': get_qname(q['subject']), 
                                     'label': get_label(q['subject'])})
        pred = sub.get(q['predicate'], {'qname': get_qname(q['predicate']), 
                                        'label': get_label(q['predicate']),
                                        'values': []})
        vals = pred.get('values')
        v = rdfstring2dict(q['object'])
        v['class'] = q['type']
        v['id'] = q['id']
        vals.append(v)
        sub[q['predicate']] = pred
        ctx[q['subject']] = sub
        changes[q['context']] = ctx
    return changes
def ontology(ontology_):
    ont = query_db('select * from ontologies where prefix = ?', [ontology_], one=True)
    # get the graph for the relevant ontology
    graph = get_graph(ontology_)
    if graph is None:
        # TODO: 404
        return redirect(url_for('index'))
    resource_ = request.args.get('resource_', None)
    errors = []
    # for recreating a page if there are errors
    changes = {'addition':[], 'removal':[]}

    # if ?resource_=xxx is present and xxx is not None then go into "resource viewing mode"
    if resource_ is not None:
        properties = {}
        # get the label of the resource
        res_name = get_label(resource_)

        # force the resource to a URIRef
        uri2res = lambda uri: uri if isinstance(uri, rdflib.URIRef) else rdflib.URIRef(uri)
        r = uri2res(resource_)

        # build list of (type,predicate,object)s, using an empty string for the type of original triples
        tpos = [('', p, o) for p, o in graph.predicate_objects(subject=r)]
        # include additions/removals from uncommited proposal
        if session.get('logged_in', False):
            tpos.extend([(s['type'], uri2res(s['predicate']), parse_string_rdfobject(s['object'])) for s in get_uncommited_quads(g.userid, resource_)])

        # TODO: these 2 lines may be redundant now as most form validation is done in the UI, remove them  completely when this is confirmed
        # include additions from changes (only present if errors in form submission)
        tpos.extend([('addition', uri2res(stmt['pred']), parse_string_rdfobject(stmt['val'])) for stmt in changes['addition']])
        # include removals from changes (only present if errors in form submission)
        tpos.extend([('removal', uri2res(stmt['pred']), parse_string_rdfobject(stmt['val'])) for stmt in changes['removal']])
        # TODO: add "modified" type (maybe)
        for t,p,o in tpos:
            # get existing values for this predicate
            item = properties.get(p,
                                  {'value': [],
                                   'qname': get_qname(p), 
                                   'label': get_label(p)})
            # convert rdf object to a dict
            v = rdfobject2dict(o)
            # add 'deleted' or 'added' 'class' value (used by templates)
            if t == 'removal':
                try:
                    # if it's a removal, it should already exist in the values list
                    # find it and add the class to the existing entry
                    idx = item['value'].index(v)
                    v['class'] = 'deleted'
                    item['value'][idx] = v
                except ValueError:
                    pass # caused when .index fails
            else:
                if t == 'addition':
                    v['class'] = 'added'
                item['value'].append(v)

            # update the changes
            properties[p] = item

            # TODO: this may be redundant with the get_label call above
            # simply sets the resource name variable to the value of the RDFS.label predicate
            if res_name is '' and p == RDFS.label:
                res_name = v['value']

        # if there were no predicates, consider this a "new resource" and present the "create resource" view
        # with the URI already filled in
        # TODO: a lot of this is duplicate code from the create_resource function
        is_new = False
        if len(properties) == 0:
            # create new resource
            properties = {}
            properties[RDF.type] = {'value': [{'type':"URI", 'value':"", 'class':'added'}],
                                    'qname': 'rdf:type',
                                    'label': 'type'}
            properties[RDFS.label] = {'value': [{'type':"Literal", 'value':"", 'class':'added'}],
                                      'qname': 'rdfs:label', 
                                      'label': 'label'}
            res_name='Create New Resource'
            is_new=True

        # TODO: proposal/history stuff
        proposals = []
        history = []
        return render_template('resource.html',
                               ontology_=ont,
                               uri=resource_,
                               name=res_name,
                               properties_=properties,
                               proposals=proposals,
                               history=history,
                               is_new=is_new,
                               auto_save=False)

    # if no resource is requested, go to the ontology view, retrieving a list of all the subjects in the ontology
    resources = [{'uri':s[0], 'qname':get_qname(s[0]), 'label':get_label(s[0])} for s in graph.triples((None, RDF.type, None))]
    proposals = None #[s for s,_ in groupby(pgraph.subjects()) if isinstance(s, rdflib.URIRef)] # TODO and not s.startswith(changeset_base_uri)
    return render_template('ontology.html', ontology_=ont, resources=resources, proposals=proposals)