Пример #1
0
def check_tree(request, NICK):
    if not slug_re.match(NICK):
        return HttpResponse("Invalid ColDoc %r." % (NICK, ),
                            status=http.HTTPStatus.BAD_REQUEST)
    c = DColDoc.objects.filter(nickname=NICK).get()
    try:
        from helper import check_tree
        problems = check_tree(logger.warning, settings.COLDOC_SITE_ROOT, NICK)
        if problems:
            s = '<h3>Problems in tree of blobs</h3><ul>'
            for code, uuid, desc in problems:
                url = django.urls.reverse('UUID:index',
                                          kwargs={
                                              'NICK': NICK,
                                              'UUID': uuid
                                          })
                s += ('<li><a href="%s">' %
                      (url, )) + uuid + '</a> →' + desc + '</li>'
            s += '</ul>'
        else:
            s = 'Tree is fine.'
        return HttpResponse(s)
    except Exception as e:
        logger.exception(repr(e))
        return HttpResponse("Internal error",
                            status=http.HTTPStatus.SERVICE_UNAVAILABLE)
Пример #2
0
def reparse(request, NICK):
    assert slug_re.match(NICK)
    coldoc = DColDoc.objects.filter(nickname=NICK).get()
    #
    request.user.associate_coldoc_blob_for_has_perm(coldoc, None)
    if not request.user.is_editor:
        raise SuspiciousOperation("Permission denied")
    #
    coldoc_dir = osjoin(settings.COLDOC_SITE_ROOT, 'coldocs', NICK)
    blobs_dir = osjoin(coldoc_dir, 'blobs')
    if not os.path.isdir(blobs_dir):
        raise SuspiciousOperation("No blobs for this ColDoc %r.\n" % (NICK, ))
    #
    if settings.USE_BACKGROUND_TASKS:
        from .tasks import reparse_all_sched
        reparse_all_sched(request.user.email, NICK, verbose_name='reparse')
        messages.add_message(request, messages.INFO, 'Reparsing scheduled')
        if request.user.email:
            messages.add_message(
                request, messages.INFO,
                'Reparsing results will be sent to ' + str(request.user.email))
    else:
        from helper import reparse_all

        def writelog(s):
            messages.add_message(request, messages.INFO, s)

        reparse_all(writelog, settings.COLDOC_SITE_ROOT, NICK)
        messages.add_message(request, messages.INFO, 'Reparsing done')
    return redirect(
        django.urls.reverse('ColDoc:index', kwargs={
            'NICK': NICK,
        }))
Пример #3
0
def reparse_all(writelog, COLDOC_SITE_ROOT, coldoc_nick, lang=None, act=True):
    " returns (success, message, new_uuid)"
    #
    from ColDoc.utils import slug_re, get_blobinator_args
    assert isinstance(coldoc_nick,
                      str) and slug_re.match(coldoc_nick), coldoc_nick
    assert ((isinstance(lang, str) and slug_re.match(lang))
            or lang is None), lang
    #
    if lang is None:
        lang_ = ''
    else:
        lang_ = '_' + lang
    #
    coldoc_dir = osjoin(COLDOC_SITE_ROOT, 'coldocs', coldoc_nick)
    assert os.path.exists(coldoc_dir), ('Does not exist coldoc_dir=%r\n' %
                                        (coldoc_dir))
    #
    blobs_dir = osjoin(coldoc_dir, 'blobs')
    #
    blobinator_args = get_blobinator_args(blobs_dir)
    #
    from ColDocApp.models import DColDoc
    coldoc = list(DColDoc.objects.filter(nickname=coldoc_nick))
    coldoc = coldoc[0]
    #if not coldoc:
    #    return HttpResponse("No such ColDoc %r." % (NICK,), status=http.HTTPStatus.NOT_FOUND)
    from ColDoc.utils import reparse_blob, choose_blob
    from UUID.models import DMetadata
    for metadata in DMetadata.objects.filter(coldoc=coldoc,
                                             extension='.tex\n'):
        for avail_lang in metadata.get('lang'):
            try:
                filename, uuid, metadata, lang, ext = choose_blob(
                    blobs_dir=blobs_dir,
                    ext='.tex',
                    lang=avail_lang,
                    metadata=metadata)
            except ColDocException:
                pass
            else:

                def warn(msg):
                    writelog('Parsing uuid %r lang %r : %s' %
                             (uuid, lang, msg))

                reparse_blob(filename, metadata, blobs_dir, warn, act=act)
Пример #4
0
def pdf(request, NICK, subpath=None):
    if not slug_re.match(NICK):
        return HttpResponse("Invalid ColDoc %r." % (NICK, ),
                            status=http.HTTPStatus.BAD_REQUEST)
    c = DColDoc.objects.filter(nickname=NICK).get()
    return UUIDviews.view_(request,
                           c,
                           c.root_uuid,
                           '.pdf',
                           None,
                           subpath,
                           prefix='main')
Пример #5
0
def list_authors(warn, COLDOC_SITE_ROOT, coldoc_nick, as_django_user=True):
    " if as_django_user is true, authors will be returned as django user whenever possible"
    #
    from ColDoc.utils import slug_re
    assert isinstance(coldoc_nick,
                      str) and slug_re.match(coldoc_nick), coldoc_nick
    #
    coldoc_dir = osjoin(COLDOC_SITE_ROOT, 'coldocs', coldoc_nick)
    assert os.path.exists(coldoc_dir), ('Does not exist coldoc_dir=%r\n' %
                                        (coldoc_dir))
    #
    blobs_dir = osjoin(coldoc_dir, 'blobs')
    #
    from ColDocApp.models import DColDoc
    coldoc = list(DColDoc.objects.filter(nickname=coldoc_nick))
    coldoc = coldoc[0]
    #
    from UUID.models import DMetadata
    #
    authors = {}

    #
    def smartappend(user_, uuid_):
        if user_ not in authors:
            authors[user_] = [uuid_]
        else:
            authors[user_].append(uuid_)

    #
    from itertools import chain
    for metadata in DMetadata.objects.filter(coldoc=coldoc):
        uuid = metadata.uuid
        m1 = metadata.get('M_author')
        if as_django_user:
            m2 = metadata.author.all()
        else:
            m2 = metadata.get(
                'author')  #[a.username for a in metadata.get('author')]
        for u in chain(m1, m2):
            smartappend(u, uuid)
        if not m1 and not m2:
            smartappend(None, uuid)
    return authors
Пример #6
0
def post_coldoc_edit(request, NICK):
    assert slug_re.match(NICK)
    if request.method != 'POST':
        return redirect(
            django.urls.reverse('ColDoc:index', kwargs={
                'NICK': NICK,
            }))
    #
    coldoc = DColDoc.objects.filter(nickname=NICK).get()
    #
    request.user.associate_coldoc_blob_for_has_perm(coldoc, None)
    if not request.user.has_perm('ColDocApp.change_dcoldoc'):
        logger.error('Hacking attempt %r', request.META)
        raise SuspiciousOperation("Permission denied")
    #
    form = ColDocForm(request.POST, instance=coldoc)
    #
    if not form.is_valid():
        return HttpResponse("Invalid form: " + repr(form.errors),
                            status=http.HTTPStatus.BAD_REQUEST)
    form.save()
    messages.add_message(request, messages.INFO, 'Changes saved')
    return index(request, NICK)
Пример #7
0
def check_tree(warn, COLDOC_SITE_ROOT, coldoc_nick, lang=None):
    " returns `problems`, a list of problems found in tree"
    # TODO implement some tree check regarding `lang`
    #
    from functools import partial
    from ColDoc.utils import recurse_tree
    from UUID.models import DMetadata
    #
    from ColDoc.utils import slug_re
    assert isinstance(coldoc_nick,
                      str) and slug_re.match(coldoc_nick), coldoc_nick
    assert ((isinstance(lang, str) and slug_re.match(lang))
            or lang is None), lang
    #
    coldoc_dir = osjoin(COLDOC_SITE_ROOT, 'coldocs', coldoc_nick)
    assert os.path.exists(coldoc_dir), ('Does not exist coldoc_dir=%r\n' %
                                        (coldoc_dir))
    #
    blobs_dir = osjoin(coldoc_dir, 'blobs')
    #
    from ColDoc.utils import tree_environ_helper
    teh = tree_environ_helper(blobs_dir=blobs_dir)
    #
    from ColDocApp.models import DColDoc
    coldoc = DColDoc.objects.get(nickname=coldoc_nick)
    #
    from ColDoc.latex import prepare_options_for_latex
    options = prepare_options_for_latex(coldoc_dir, blobs_dir, DMetadata,
                                        coldoc)
    #
    from UUID.models import DMetadata
    #
    seen = set()
    available = set()
    all_metadata = {}
    problems = []
    #
    for metadata in DMetadata.objects.filter(coldoc=coldoc):
        available.add(metadata.uuid)
        all_metadata[metadata.uuid] = metadata
    # each one of those is equivalent
    load_by_uuid = partial(DMetadata.load_by_uuid, coldoc=coldoc)
    load_by_uuid = lambda uuid: all_metadata[uuid]

    #
    def actor(teh, seen, available, warn, problems, uuid, branch, *v, **k):
        if uuid in branch:
            a = "loop detected along branch %r" % (branch + [uuid], )
            warn(a)
            problems.append(("LOOP", uuid, a))
        ret = True
        if uuid in seen:
            ret = False
            a = "duplicate node %r in tree" % (uuid, )
            warn(a)
            problems.append(("DUPLICATE", uuid, a))
        if uuid in available:
            available.discard(uuid)
        else:
            ret = False
            warn("already deleted from queue %r" % uuid)
        seen.add(uuid)
        if len(branch) > 1:
            c = load_by_uuid(branch[-1])
            p = load_by_uuid(branch[-2])
            if not teh.child_is_allowed(c.environ, p.environ,
                                        c.get('extension')):
                a = "The node %r %r cannot be a child of %r %r" % (
                    c.uuid, c.environ, p.uuid, p.environ)
                problems.append(("WRONG_LINK", uuid, a))
                warn(a)
                ret = False
            #else:
            #    warn("The node %r %r can be a child of %r %r" %(c.uuid,c.environ,p.uuid,p.environ))
        return ret

    #
    action = partial(actor,
                     teh=teh,
                     seen=seen,
                     available=available,
                     warn=warn,
                     problems=problems)
    ret = recurse_tree(load_by_uuid, action)
    # self check
    assert bool(problems) ^ (bool(ret)), (ret, problems, bool(ret),
                                          bool(problems))
    #
    if available:
        a = ("Disconnected nodes %r" % available)
        warn(a)
        for j in available:
            problems.append(('DISCONNECTED', j, a))
    # load back_maps
    from ColDoc.utils import uuid_to_dir, parent_cmd_env_child
    back_maps = {}
    for uuid in all_metadata:
        a = osjoin(blobs_dir, uuid_to_dir(uuid), '.back_map.pickle')
        if os.path.exists(a):
            back_maps[uuid] = pickle.load(open(a, 'rb'))
        else:
            M = all_metadata[uuid]
            if M.get('extension') == ['.tex']:
                logger.warning('UUID %r does not have back_map', uuid)
    # check environ
    environments = {}
    for uuid in all_metadata:
        M = all_metadata[uuid]
        env = M.get('environ')
        if len(env) != 1:
            a = 'UUID %r environ %r' % (uuid, env)
            logger.error(a)
            problems.append(("WRONG environ", uuid, a))
            continue
        environments[uuid] = env[0]
    # check protection
    private_environment = options.get("private_environment", [])
    if private_environment:
        for uuid in all_metadata:
            env = environments.get(uuid)
            M = all_metadata[uuid]
            if (env[:2] == 'E_') and (bool(env[2:] in private_environment) !=
                                      bool(M.access == 'private')):
                a = 'UUID %r environ %r access %r' % (uuid, env, M.access)
                logger.warning(a)
                problems.append(('WRONG access', uuid, a))
    # check that the environment of the child corresponds to the LaTex \begin/\end used in the parent
    split_graphic = options.get("split_graphic", [])
    allowed_parenthood = options.get("allowed_parenthood", {})
    for uuid in all_metadata:
        M = all_metadata[uuid]
        parents = M.get('parent_uuid')
        child_env = environments.get(uuid)
        if child_env is None:
            continue
        for parent_uuid in parents:
            back_map = back_maps.get(parent_uuid)
            if back_map is None:
                logger.error('Parent %r of %r does not have back_map',
                             parent_uuid, uuid)
                continue
            cmd, file, parent_uses_env = back_map[uuid]
            wrong = parent_cmd_env_child(parent_uses_env, cmd, child_env,
                                         split_graphic, allowed_parenthood)
            if wrong:
                #a = 'child env %r parent_env %r parent_cmd %r' %(child_env,parent_uses_env,cmd))
                a = 'Parent %r includes child %r using cmd %r environ %r but child %r thinks it is environ %r' %\
                    (parent_uuid, uuid, cmd, parent_uses_env, uuid , child_env)
                logger.warning(a)
                problems.append(('CMD_PARENT_CHILD', uuid, a))
    # check that header is consistent
    from ColDoc.config import ColDoc_environments_sectioning
    for uuid in all_metadata:
        M = all_metadata[uuid]
        env = environments.get(uuid)
        if env and env in ColDoc_environments_sectioning:
            D = osjoin(blobs_dir, uuid_to_dir(uuid, blobs_dir))
            try:
                for j in os.listdir(D):
                    if j.startswith('blob') and j.endswith('.tex'):
                        l = open(osjoin(D, j)).readline(32)
                        if not l.startswith('\\' + env):
                            a = 'UUID %r file %r environ %r first line %r' % (
                                uuid, j, env, l)
                            logger.warning(a)
                            problems.append(('WRONG_HEADER', uuid, a))
            except:
                logger.exception('while checking headers in %r', uuid)
    return problems
Пример #8
0
def add_blob(logger,
             user,
             COLDOC_SITE_ROOT,
             coldoc_nick,
             parent_uuid,
             environ,
             lang,
             selection_start=None,
             selection_end=None,
             add_beginend=True):
    " returns (success, message, new_uuid)"
    #
    from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
    #
    from ColDoc.utils import slug_re
    assert isinstance(coldoc_nick,
                      str) and slug_re.match(coldoc_nick), coldoc_nick
    assert ((isinstance(lang, str) and slug_re.match(lang))
            or lang is None), lang
    assert isinstance(parent_uuid,
                      str) and slug_re.match(parent_uuid), parent_uuid
    assert isinstance(environ, str), environ
    if isinstance(selection_end, int) and selection_end < 0:
        selection_end = None
    if isinstance(selection_start, int) and selection_start < 0:
        selection_start = None
    #
    import ColDoc.config as CC
    #
    if lang is None:
        lang_ = ''
    else:
        lang_ = '_' + lang
    #
    if environ.startswith('E_'):
        extension = '.tex'
    elif environ == 'graphic_file':
        extension = '.png'
    else:
        extension = None
        for k in CC.ColDoc_latex_mime:
            if environ in CC.ColDoc_latex_mime[k]:
                extension = k
    #
    coldoc_dir = osjoin(COLDOC_SITE_ROOT, 'coldocs', coldoc_nick)
    assert os.path.exists(coldoc_dir), ('Does not exist coldoc_dir=%r\n' %
                                        (coldoc_dir))
    #
    blobs_dir = osjoin(coldoc_dir, 'blobs')
    #
    blobinator_args = get_blobinator_args(blobs_dir)
    #
    if environ[:2] == 'E_':
        if environ[2:] not in (blobinator_args['split_environment'] +
                               blobinator_args['split_list']):
            a = 'The environ %r was never splitted when the document was first created ' % environ
            logger.error(a)
            return False, a, None
    else:
        if environ not in CC.ColDoc_environments:
            a = "Cannot add a child with unknown environ %r" % environ
            logger.error(a)
            return False, a, None
    #
    if selection_start is not None and selection_end != selection_start:
        if extension is None or environ == 'graphic_file':
            a = ("cannot select region when adding a non-TeX file")
            logger.error(a)
            return False, a, None
    #
    if isinstance(user, str):
        import django.contrib.auth as A
        M = A.get_user_model()
        try:
            user_ = M.objects.get(username=user)
        except ObjectDoesNotExist:
            logger.error('No such user %r', user)
            return False, 'No such user', None
        user = user_
        logger.debug("Resolved user as %r", user)
    #
    from ColDoc import utils
    import ColDocApp.models as coldocapp_models
    import UUID.models as blob_models
    metadata_class = blob_models.DMetadata
    #
    #try:
    parent_uuid_, parent_uuid_dir, parent_metadata = utils.resolve_uuid(
        uuid=parent_uuid,
        uuid_dir=None,
        blobs_dir=blobs_dir,
        coldoc=coldoc_nick,
        metadata_class=metadata_class)
    logger.debug('Resolved parent as %r', parent_uuid_dir)
    #
    if '.tex' not in parent_metadata.get('extension'):
        a = "Only '.tex' blobs can have children"
        logger.error(a)
        return False, a, None
    #
    from ColDoc.utils import tree_environ_helper
    parent_environ = parent_metadata.environ
    teh = tree_environ_helper(parent=parent_environ, blobs_dir=blobs_dir)
    if not teh.child_is_allowed(environ, extension=extension):
        if environ[:2] == 'E_':
            a = "Cannot add a \\begin{%s}..\\end{%s} to a blob that has environ=%r " % (
                environ[2:], environ[2:], parent_environ)
        else:
            a = "Cannot add a child with environ %r extension %r to a parent with environ %r" % (
                parent_environ, extension, environ)
        logger.error(a)
        return False, a, None
    #
    #from ColDocDjango.users import user_has_perm
    user.associate_coldoc_blob_for_has_perm(parent_metadata.coldoc,
                                            parent_metadata)
    if not user.has_perm('UUID.view_blob', parent_metadata):
        logger.error("Permission denied (view_blob)")
        return False, "Permission denied (view_blob)", None
    try:
        parent_metadata.author.get(id=user.id)
    except ObjectDoesNotExist:
        logger.debug("User %r is not an author of %r", user, parent_uuid)
        if not user.has_perm('ColDocApp.add_blob'):
            a = (
                "Permission denied (add_blob) and %s is not an author of %s " %
                (user, parent_uuid))
            logger.error(a)
            return False, a, None
    else:
        logger.debug("User %r is an author of %r", user, parent_uuid)
    #
    # FIXME TODO maybe we should insert the "input" for all languages available?
    parent_abs_filename = os.path.join(blobs_dir, parent_uuid_dir,
                                       'blob' + lang_ + '.tex')
    if not os.path.exists(parent_abs_filename):
        a = "Parent does not exists %r" % parent_abs_filename
        logger.error(a)
        return False, a, None
    #
    filename = None
    while not filename:
        new_uuid = utils.new_uuid(blobs_dir=blobs_dir)
        new_dir = utils.uuid_to_dir(new_uuid, blobs_dir=blobs_dir, create=True)
        filename = osjoin(new_dir, 'blob' + lang_ + extension)
        if os.path.exists(osjoin(blobs_dir, filename)):
            logger.error(' output exists %r, trying next UUID' % filename)
            filename = None
    #
    child_metadata = metadata_class(coldoc=parent_metadata.coldoc,
                                    uuid=new_uuid)
    #child_metadata.add('uuid', new_uuid)
    if extension is not None:
        child_metadata.add('extension', extension)
    child_metadata.add('environ', environ)
    if lang is not None:
        child_metadata.add('lang', lang)
    if environ[:2] == 'E_' and environ[2:] in blobinator_args[
            'private_environment']:
        child_metadata.add('access', 'private')
    child_metadata.save()
    child_metadata.add('author', user)
    parent_metadata.add('child_uuid', new_uuid)
    child_metadata.save()
    #
    placeholder = 'placeholder'
    parent_file = open(parent_abs_filename).read()
    if selection_start is not None and selection_end != selection_start:
        placeholder = parent_file[selection_start:selection_end]
    if environ in CC.ColDoc_environments_sectioning:
        from ColDoc.blob_inator import _rewrite_section
        sources = ['', '', '{placeholder}']
        _, src = _rewrite_section(sources, new_uuid, environ)
        placeholder = src + '\n' + placeholder
        child_metadata.add('optarg', json.dumps(sources))
        child_metadata.save()
    else:
        placeholder = ("\\uuid{%s}%%\n" % (new_uuid, )) + placeholder
    with open(parent_abs_filename, 'w') as f:
        if selection_start is None:
            f.write(parent_file)
        else:
            f.write(parent_file[:selection_start])
        f.write("%\n")
        #utils.environ_stub(environ)
        if environ[:2] == 'E_':
            if add_beginend: f.write("\\begin{" + environ[2:] + "}")
            if environ[2:] in blobinator_args['split_list']:
                f.write("\\item")
        if environ == 'graphic_file':
            f.write("\\includegraphics{" + filename + "}")
        else:
            f.write("\\input{" + filename + "}")
        if environ[:2] == 'E_' and add_beginend:
            f.write("\\end{" + environ[2:] + "}")
        f.write("\n")
        if selection_start is not None:
            f.write(parent_file[selection_end:])
    #
    if environ == 'graphic_file':
        import shutil
        child_metadata.original_filename = child_metadata.uuid + '.png'
        child_metadata.save()
        shutil.copy(
            osjoin(os.environ['COLDOC_SRC_ROOT'],
                   'ColDocDjango/assets/placeholder.png'),
            osjoin(blobs_dir, filename))
    else:
        with open(osjoin(blobs_dir, filename), 'w') as f:
            f.write(placeholder + '\n')
    #
    # write  the metadata (including, a a text copy in filesytem)
    parent_metadata.save()
    return True, (
        "Created blob with UUID %r, please edit %r to properly input it (a stub \\input was inserted for your convenience)"
        % (new_uuid, parent_uuid)), new_uuid
Пример #9
0
def index(request, NICK):
    if not slug_re.match(NICK):
        return HttpResponse("Invalid ColDoc %r." % (NICK, ),
                            status=http.HTTPStatus.BAD_REQUEST)
    #coldoc_dir = osjoin(settings.COLDOC_SITE_ROOT,NICK)
    try:
        c = DColDoc.objects.filter(nickname=NICK).get()
    except DColDoc.DoesNotExist:
        return HttpResponse("No such ColDoc %r.\n" % (NICK, ),
                            status=http.HTTPStatus.NOT_FOUND)
    #
    request.user.associate_coldoc_blob_for_has_perm(c, None)
    #
    if request.user.has_perm('UUID.view_view'):
        whole_button_class = 'btn-outline-success'
    else:
        whole_button_class = 'btn-outline-primary'
    #
    coldocform = None
    if request.user.has_perm('ColDocApp.view_dcoldoc'):
        coldocform = ColDocForm(instance=c)
        coldocform.htmlid = 'id_coldocform'
        for a in 'nickname', 'root_uuid':
            coldocform.fields[a].widget.attrs['readonly'] = True
    #
    latex_error_logs = []
    failed_blobs = []
    tasks = []
    completed_tasks = []
    if request.user.is_editor:
        from ColDocDjango.utils import convert_latex_return_codes
        latex_error_logs = convert_latex_return_codes(c.latex_return_codes,
                                                      c.nickname, c.root_uuid)
        #
        failed_blobs = map(
            lambda x: (x,
                       django.urls.reverse('UUID:index',
                                           kwargs={
                                               'NICK': NICK,
                                               'UUID': x
                                           })),
            DMetadata.objects.exclude(
                latex_return_codes__exact='').values_list('uuid', flat=True))
        #
        if Task is not None:
            tasks = [TaskForm(instance=j) for j in Task.objects.all()]
            completed_tasks = [
                CompletedTaskForm(instance=j)
                for j in CompletedTask.objects.all()
            ]
        #
    check_tree_url = django.urls.reverse('ColDoc:check_tree',
                                         kwargs={
                                             'NICK': NICK,
                                         })
    return render(
        request, 'coldoc.html', {
            'coldoc': c,
            'NICK': c.nickname,
            'coldocform': coldocform,
            'failedblobs': failed_blobs,
            'check_tree_url': check_tree_url,
            'whole_button_class': whole_button_class,
            'tasks': tasks,
            'completed_tasks': completed_tasks,
            'latex_error_logs': latex_error_logs
        })
Пример #10
0
def search(request, NICK):
    if not slug_re.match(NICK):
        return HttpResponse("Invalid ColDoc %r." % (NICK, ),
                            status=http.HTTPStatus.BAD_REQUEST)
    if request.method == 'POST':
        searchtoken = request.POST.get('searchtoken')
        if searchtoken is None:
            logger.error(
                'Search POST with not "searchtoken" : hacking attemp?')
            return HttpResponse("Bad ... bad ..." % (request.method, ),
                                status=http.HTTPStatus.BAD_REQUEST)
    else:
        assert request.method == 'GET'
        searchtoken = request.GET.get('searchtoken')
        if searchtoken is None:
            # this happens when the user logs in or logs out while on the search page
            return redirect(
                django.urls.reverse('ColDoc:index', kwargs={
                    'NICK': NICK,
                }))
        #return HttpResponse("Method %r not allowed"%(request.method,),status=http.HTTPStatus.BAD_REQUEST)
    #
    if len(searchtoken) <= 1:
        messages.add_message(request, messages.WARNING,
                             "Search key is too short.")
        return index(request, NICK)
    #
    coldoc = DColDoc.objects.filter(nickname=NICK).get()
    #
    request.user.associate_coldoc_blob_for_has_perm(coldoc, None)
    # UUID
    if len(searchtoken) <= 8 and len(searchtoken) >= 3:
        maybe_uuid = True
        try:
            uuid_ = ColDoc.utils.uuid_check_normalize(searchtoken)
        except ValueError:
            uuid_list = []
            maybe_uuid = False
        else:
            uuid_list = DMetadata.objects.filter(coldoc=coldoc, uuid=uuid_)
    else:
        maybe_uuid = False
        uuid_list = []
    #
    if request.user.is_authenticated and coldoc.anonymous_can_view:
        # FIXME , would like to use `has_perm('UUID.view_view')`
        # but this currently works only on a per-blob basis:
        # so we should filter this list accordingly
        index_list = ExtraMetadata.objects.filter(
            Q(key__contains='M_index') & Q(blob__coldoc=coldoc)
            & Q(value__contains=searchtoken))
    else:
        index_list = []
    if request.user.has_perm('UUID.view_blob'):
        label_list = ExtraMetadata.objects.filter(
            Q(key__endswith='M_label') & Q(blob__coldoc=coldoc)
            & Q(value__contains=searchtoken))
        ref_list = ExtraMetadata.objects.filter(
            (Q(key__endswith='M_ref') | Q(key__endswith='M_eqref')
             | Q(key__endswith='M_pageref')) & Q(blob__coldoc=coldoc)
            & Q(value__contains=searchtoken))
    else:
        label_list = ref_list = []
    #
    meta_list = []
    if request.user.is_authenticated and coldoc.anonymous_can_view:
        # FIXME , would like to use `has_perm('UUID.view_view')`
        # but this currently works only on a per-blob basis:
        # so we should filter this list accordingly
        blobs_dir = osjoin(settings.COLDOC_SITE_ROOT, 'coldocs', NICK, 'blobs')
        blobinator_args = get_blobinator_args(blobs_dir)
        for j in blobinator_args["metadata_command"]:
            if j not in ('label', 'ref', 'eqref', 'pageref', 'index'):
                meta_list += list(
                    ExtraMetadata.objects.filter(
                        Q(key__endswith=('M_' + j)) & Q(blob__coldoc=coldoc)
                        & Q(value__contains=searchtoken)))
    # TODO search in text
    # shortcut
    if len(
            uuid_list
    ) == 1 and not label_list and not index_list and not ref_list and not meta_list:
        return redirect(
            django.urls.reverse('UUID:index',
                                kwargs={
                                    'NICK': NICK,
                                    'UUID': uuid_list[0].uuid
                                }))

    return render(
        request, 'search.html', {
            'coldoc': coldoc,
            'NICK': coldoc.nickname,
            'maybe_uuid': maybe_uuid,
            'uuid_list': uuid_list,
            'label_list': label_list,
            'ref_list': ref_list,
            'index_list': index_list,
            'meta_list': meta_list,
        })
Пример #11
0
def latex(request, NICK):
    assert slug_re.match(NICK)
    coldoc = DColDoc.objects.filter(nickname=NICK).get()
    #
    request.user.associate_coldoc_blob_for_has_perm(coldoc, None)
    if not request.user.is_editor:
        raise SuspiciousOperation("Permission denied")
    #
    coldoc_dir = osjoin(settings.COLDOC_SITE_ROOT, 'coldocs', NICK)
    blobs_dir = osjoin(coldoc_dir, 'blobs')
    if not os.path.isdir(blobs_dir):
        raise SuspiciousOperation("No blobs for this ColDoc %r.\n" % (NICK, ))
    #
    q = request.GET
    typ_ = q.get('type')
    if typ_ not in ('main', 'anon', 'tree'):
        messages.add_message(request, messages.WARNING, 'Wrong request')
        return index(request, NICK)
    #
    assert slug_re.match(typ_)
    #
    from ColDoc.latex import prepare_options_for_latex
    options = {}  # prepare_options_for_latex() will be called by latex_main
    #
    url = django.urls.reverse('UUID:index',
                              kwargs={
                                  'NICK': coldoc.nickname,
                                  'UUID': '000'
                              })[:-4]
    url = request.build_absolute_uri(url)
    # used for PDF
    options['url_UUID'] = url
    options['coldoc'] = coldoc
    options['metadata_class'] = DMetadata
    # used to dedup plastex stuff
    options['coldoc_site_root'] = settings.COLDOC_SITE_ROOT
    options['dedup_root'] = settings.DEDUP_ROOT
    options['dedup_url'] = settings.DEDUP_URL
    # needed by `latex_tree`
    if typ_ == 'tree':
        import functools
        from ColDocDjango.transform import squash_helper_ref
        options["squash_helper"] = functools.partial(squash_helper_ref, coldoc)
    # this signals `latex_main` to run `prepare_options_for_latex()`
    options['coldoc_dir'] = coldoc_dir
    options = base64.b64encode(pickle.dumps(options)).decode()
    #
    ret = False
    if typ_ == 'tree':
        ret = latex_tree_sched(blobs_dir,
                               uuid=coldoc.root_uuid,
                               options=options,
                               verbose_name="latex_tree",
                               email_to=request.user.email)
    elif typ_ == 'main':
        ret = latex_main_sched(blobs_dir,
                               uuid=coldoc.root_uuid,
                               options=options,
                               access='private',
                               verbose_name="latex_main:private",
                               email_to=request.user.email)
    else:
        ret = latex_anon_sched(coldoc_dir,
                               uuid=coldoc.root_uuid,
                               options=options,
                               access='public',
                               verbose_name="latex_main:public",
                               email_to=request.user.email)
    if settings.USE_BACKGROUND_TASKS:
        messages.add_message(request, messages.INFO,
                             'Compilation scheduled for ' + typ_)
    elif ret:
        messages.add_message(request, messages.INFO,
                             'Compilation finished for ' + typ_)
    else:
        messages.add_message(request, messages.WARNING,
                             'Compilation failed for ' + typ_)
    return redirect(
        django.urls.reverse('ColDoc:index', kwargs={
            'NICK': NICK,
        }))