def save_doc(docdef, baseform, data, user, eid=None):
    """
    Saves doc to given eid, using doc from index as a base.
    If eid is not given, lets elastic search create one.
    """

    doctype = docdef['meta']['document_type']
    original_meta_field = None

    if eid:
        basedata = get_doc_from_index(
            settings.INDEX_NAME, doctype, eid)

        if eid:
            authorization = authorize(user, basedata['_source'])
            if not authorization:
                raise PermissionDenied("ei oikeuksia")

        if basedata:
            orig = basedata['_source']
            original_meta_field = orig.get('meta')
            form = baseform(data)
    else:
        form = baseform(data)

    # This data is used by kir.form_elements.validators.test_cyclic_hierarchy
    form.document_id = eid

    if data and form.validate():
        form_data = form.data

        if doctype == 'organisation':
            form_data['default_attachment'] = get_default_attachment(form_data.get('attachments'))
            #print(form_data['default_attachment'])

        # validation destroys fields not present in the
        # form, so metadata has to be passed separately
        msg = save(form_data, docdef['meta'], user, eid,
                   GlobalForm(data).data, preserved_metadata = original_meta_field)
        if msg['ok']:
            eid = msg['_id']
            saved = True
        else:
            saved = False
    else:
        saved = False

    if form.errors:
        errors = print_form_errors(parse_form(form))
    else:
        errors = None

    return {"errors" : errors, "saved" : saved, "doc_id" : eid,
            "form" : form, 'formdata' : data}
def restore_view(request, doctype, eid):
    """
    Restore document from versioning index
    """
    basedoc = get_basedoc(doctype)
    reid = request.GET.get("reid") or request.POST.get("reid")
    if not reid:
        versions = es_tools.get_versions(doctype, eid)
        if not versions:
            raise Http404
        resdoc = None
    else:
        versions = None
        res = get_doc_from_index(settings.VERSION_INDEX_NAME, doctype, reid)
        if res:
            resdoc = htmltree_conversion(es_tools.get_source(res), basedoc)
        else:
            raise Http404
    cur = get_doc_from_index(settings.INDEX_NAME, doctype, eid)
    if cur:
        curdoc = es_tools.get_source(cur)
    else:
        raise Http404

    if request.POST.get("restore"):
        es_tools.restore(doctype, curdoc, resdoc, request.user)
        restore = True
    else:
        restore = False
    t = env.get_template('restore.html')
    context = {"restore" : restore,
                  "data" : htmltree_conversion(curdoc, basedoc),
                  "curdoc" : curdoc,
                  "resdoc" : resdoc,
                  "versions" : versions,
                  "doctype" : doctype}
    context.update(csrf(request))
    s = template_render(t, context)
    return HttpResponse(s)
def open_doc(docdef, baseform, user, eid):
    """
    Creates form for given doc id from database, form being otherwise empty.
    """
    basedata = get_doc_from_index(
        settings.INDEX_NAME, docdef['meta']['document_type'], eid)
    if eid:
        authorization = authorize(user, basedata['_source'])
        if not authorization:
            raise PermissionDenied("ei oikeuksia")
    if basedata:
        form = baseform(**basedata['_source'])
        return {"form" : form, "doc_id" : eid, 'objdata' : basedata['_source']}
    else:
        return None
def delete_view(request, doctype, eid):
    """
    Deletes document from index with given doctype and elastic id.
    Copies document to version index with meta.deleted being the deleted doc's
    id.

    Thus one can search for deleted docs and its versions
    (since meta.deleted and versioned docs meta.original are set same id).
    """
    doc = get_doc_from_index(settings.INDEX_NAME, doctype, eid)
    if not doc:
        raise Http404
    add_metadata(doc["_source"], request.user)
    doc["_source"]["meta"]["deleted"] = eid
    conn.index(doc["_source"], settings.VERSION_INDEX_NAME, doctype)
    conn.delete(settings.INDEX_NAME, doctype, eid)
    t = env.get_template('delete.html')
    s = template_render(t, {"msg" : _("The document with the id %s was removed.") %
                  (eid, ),
                  "doctype" : doctype})
    return HttpResponse(s)
def index(request, entity_id=None):
    current_step = 1
    docs = []
    only_one = False

    if not request.user.is_authenticated():
        login_required = True
    else:
        login_required = False
        current_step = 2

    doc_id = entity_id
    selected_id = None
    selected_library = None

    if doc_id:
        selected_doc = get_doc_from_index(
                settings.INDEX_NAME, 'organisation', doc_id)
        if selected_doc:
            selected_library = get_source(selected_doc)
            selected_id=doc_id
            current_step = 3

            if selected_library['organisation_type'] != 'library':
                family_tree = searcher.search_family_tree(user=request.user)
                member = family_tree.get(doc_id)
                if member:
                    selected_library['children'] = [
                        (cid, cname) for cid, cname in
                        zip(member['children'], member['children_names'])]

                    parents = member['parent_names']
                    parents.reverse()
                    selected_library['parents'] = ' → '.join(parents)
    else:
        if not login_required:
            request.session.set_expiry(12*60*60)
            current_step = 2

        required_fields = ['organisation_type',
                           'contact.street_address.municipality_fi',
                           'name_fi',
                           'parent_organisation',
                           'meta.modified']

        if request.user.is_authenticated():
            if request.user.is_superuser:
                results = searcher.search(
                    # todo: remove size
                    searcher.ALL_LIBS, size = 10000, fields = required_fields)
            else:
                results = searcher.front_page_search(
                    request.user, size = 500, fields = required_fields)

            family_tree = searcher.search_family_tree(user=request.user)

            for doc in results[0]:
                if 'organisation_type' not in doc:
                    print(doc)

                if (doc['organisation_type'] in
                    ['branchlibrary', 'unit', 'library']):
                    family_member = family_tree.get(doc['_id'])

                    if family_member:
                        parents = family_member['parent_names']
                        children = family_member['children_names']
                        children_ids = family_member['children']

                        if len(parents):
                            parents.reverse()
                            doc['parents'] = ' → '.join(parents)

                        if len(children):
                            doc['children'] = [(cid, cname) for cid, cname in
                                               zip(children_ids, children)]

                if (doc['organisation_type'] not in ['department',
                                                     'mobile_stop']):
                    docs.append(doc)


            if not login_required and len(docs) == 1:
                current_step = 3
                selected_library = docs[0]
                selected_id = selected_library['_id']
                only_one = True

    t = env.get_template('index.html')

    note_filter_date = dt.datetime.now() - dt.timedelta(days=7)
    notifications = models.Notification.objects.unread(request.user, note_filter_date)

    context = {
        'login_required'      : login_required,
        'docs'                : docs,
        'library_count'       : len(docs),
        'username'            : request.user.username,
        'access_to_templates' : (
            not login_required and
            request.user.has_perm('sites.access_to_templates')),

        'summary'             : teaser('organisation'),
        'selected_library'    : selected_library,
        'selected_id'         : selected_id ,
        'frontpage_url'       : frontpage_url,
        'editpage_url'        : editpage_url,
        'current_step'        : current_step,
        'only_one'            : only_one,
        'library_limit'       : 5,
        'username_string'     : _("Username"),
        'password_string'     : _("Password"),
        'login_string'        : _("Log in"),
        'notifications'       : notifications,
        'can_export'          : user_has_group(request.user, 'export')
        }

    context.update(csrf(request)) # todo: better way?

    s = template_render(t, context)

    return HttpResponse(s)