Example #1
0
def get_translation_context(request):
    """Returns a common context for translation views.

    :param request: a :cls:`django.http.HttpRequest` object.
    """
    resource_path = getattr(request, 'resource_path', '')
    vfolder_pk = getattr(request, 'current_vfolder', '')

    return {
        'page': 'translate',

        'cantranslate': check_permission("translate", request),
        'cansuggest': check_permission("suggest", request),
        'canreview': check_permission("review", request),
        'is_admin': check_permission('administrate', request),
        'profile': request.profile,

        'pootle_path': request.pootle_path,
        'ctx_path': request.ctx_path,
        'current_vfolder_pk': vfolder_pk,
        'display_priority': display_vfolder_priority(request),
        'resource_path': resource_path,
        'resource_path_parts': get_path_parts(resource_path),

        'check_categories': get_qualitycheck_schema(),

        'search_form': make_search_form(request=request),

        'previous_url': get_previous_url(request),

        'POOTLE_MT_BACKENDS': settings.POOTLE_MT_BACKENDS,
        'AMAGAMA_URL': settings.AMAGAMA_URL,
    }
Example #2
0
def _test_translate_view(language, request, response, kwargs, settings):
    ctx = response.context
    view_context_test(
        ctx,
        **dict(
            project=None,
            language=language,
            page="translate",
            ctx_path=language.directory.pootle_path,
            pootle_path=language.directory.pootle_path,
            resource_path="",
            resource_path_parts=[],
            profile=request.profile,
            editor_extends="languages/base.html",
            check_categories=get_qualitycheck_schema(),
            previous_url=get_previous_url(request),
            display_priority=False,
            is_admin=check_permission('administrate', request),
            cantranslate=check_permission("translate", request),
            cansuggest=check_permission("suggest", request),
            canreview=check_permission("review", request),
            search_form=make_search_form(request=request),
            current_vfolder_pk="",
            POOTLE_MT_BACKENDS=settings.POOTLE_MT_BACKENDS,
            AMAGAMA_URL=settings.AMAGAMA_URL))
Example #3
0
File: tp.py Project: haf/pootle
def _test_translate_view(tp, request, response, kwargs, settings):
    ctx = response.context
    kwargs["project_code"] = tp.project.code
    kwargs["language_code"] = tp.language.code
    resource_path = "%(dir_path)s%(filename)s" % kwargs
    request_path = "%s%s" % (tp.pootle_path, resource_path)
    vfolder, pootle_path = extract_vfolder_from_path(request_path)
    current_vfolder_pk = vfolder.pk if vfolder else ""
    display_priority = not current_vfolder_pk and (
        VirtualFolderTreeItem.objects.filter(pootle_path__startswith=pootle_path).exists()
    )
    assertions = dict(
        page="translate",
        translation_project=tp,
        language=tp.language,
        project=tp.project,
        is_admin=False,
        profile=request.profile,
        ctx_path=tp.pootle_path,
        pootle_path=request_path,
        resource_path=resource_path,
        resource_path_parts=get_path_parts(resource_path),
        editor_extends="translation_projects/base.html",
        check_categories=get_qualitycheck_schema(),
        previous_url=get_previous_url(request),
        current_vfolder_pk=current_vfolder_pk,
        display_priority=display_priority,
        cantranslate=check_permission("translate", request),
        cansuggest=check_permission("suggest", request),
        canreview=check_permission("review", request),
        search_form=make_search_form(request=request),
        POOTLE_MT_BACKENDS=settings.POOTLE_MT_BACKENDS,
        AMAGAMA_URL=settings.AMAGAMA_URL,
    )
    view_context_test(ctx, **assertions)
Example #4
0
def language_index(request, language_code):
    language = get_object_or_404(Language, code=language_code)
    request.permissions = get_matching_permissions(get_profile(request.user), language.directory)

    if not check_permission("view", request):
        raise PermissionDenied

    projects = language.translationproject_set.order_by('project__fullname')
    projectcount = len(projects)
    items = (make_project_item(translate_project) for translate_project in projects.iterator())

    totals = language.getquickstats()
    average = nice_percentage(totals['translatedsourcewords'] * 100.0 / max(totals['totalsourcewords'], 1))
    topstats = gentopstats_language(language)

    templatevars = {
        'language': {
          'code': language.code,
          'name': tr_lang(language.fullname),
          'description': language.description,
          'stats': ungettext('%(projects)d project, %(average)d%% translated',
                             '%(projects)d projects, %(average)d%% translated',
                             projectcount, {"projects": projectcount, "average": average}),
        },
        'feed_path': '%s/' % language.code,
        'description': language.description,
        'projects': items,
        'statsheadings': get_stats_headings(),
        'topstats': topstats,
        }
    if check_permission('administrate', request):
        from pootle_language.forms import DescriptionForm
        templatevars['form'] = DescriptionForm(instance=language)

    return render_to_response("language/language_index.html", templatevars, context_instance=RequestContext(request))
Example #5
0
def test_view_projects_translate(site_permissions, site_matrix_with_vfolders, client, nobody, default, settings):
    response = client.get(reverse("pootle-projects-translate"))
    ctx = response.context
    request = response.wsgi_request
    assertions = dict(
        page="translate",
        is_admin=False,
        language=None,
        project=None,
        profile=request.profile,
        pootle_path="/projects/",
        ctx_path="/projects/",
        resource_path="",
        resource_path_parts=[],
        editor_extends="projects/all/base.html",
        check_categories=get_qualitycheck_schema(),
        previous_url=get_previous_url(request),
        display_priority=False,
        cantranslate=check_permission("translate", request),
        cansuggest=check_permission("suggest", request),
        canreview=check_permission("review", request),
        search_form=make_search_form(request=request),
        current_vfolder_pk="",
        POOTLE_MT_BACKENDS=settings.POOTLE_MT_BACKENDS,
        AMAGAMA_URL=settings.AMAGAMA_URL,
    )
    view_context_test(ctx, **assertions)
Example #6
0
def get_translation_context(request, is_terminology=False):
    """Return a common context for translation views.

    :param request: a :cls:`django.http.HttpRequest` object.
    :param is_terminology: boolean indicating if the translation context
        is relevant to a terminology project.
    """
    return {
        'cantranslate': check_permission("translate", request),
        'cansuggest': check_permission("suggest", request),
        'canreview': check_permission("review", request),
        'is_admin': check_permission('administrate', request),
        'profile': request.profile,

        'pootle_path': request.pootle_path,
        'ctx_path': request.ctx_path,
        'resource_path': (request.resource_path
                          if hasattr(request, 'resource_path') else ''),

        'check_categories': get_qualitycheck_schema(),

        'search_form': make_search_form(request=request,
                                        terminology=is_terminology),

        'MT_BACKENDS': settings.MT_BACKENDS,
        'LOOKUP_BACKENDS': settings.LOOKUP_BACKENDS,
        'AMAGAMA_URL': settings.AMAGAMA_URL,
    }
Example #7
0
def test_view_projects_translate(client, settings, request_users):
    user = request_users["user"]
    client.login(
        username=user.username,
        password=request_users["password"])
    response = client.get(reverse("pootle-projects-translate"))

    if not user.is_superuser:
        assert response.status_code == 403
        return

    ctx = response.context
    request = response.wsgi_request
    assertions = dict(
        page="translate",
        has_admin_access=user.is_superuser,
        language=None,
        project=None,
        pootle_path="/projects/",
        ctx_path="/projects/",
        resource_path="",
        resource_path_parts=[],
        editor_extends="projects/all/base.html",
        check_categories=get_qualitycheck_schema(),
        previous_url=get_previous_url(request),
        display_priority=False,
        cantranslate=check_permission("translate", request),
        cansuggest=check_permission("suggest", request),
        canreview=check_permission("review", request),
        search_form=make_search_form(request=request),
        current_vfolder_pk="",
        POOTLE_MT_BACKENDS=settings.POOTLE_MT_BACKENDS,
        AMAGAMA_URL=settings.AMAGAMA_URL)
    view_context_test(ctx, **assertions)
Example #8
0
def view(request, path):
    # FIXME: why do we have leading and trailing slashes in pootle_path?
    pootle_path = "/%s" % path

    directory = get_object_or_404(Directory, pootle_path=pootle_path)

    request.permissions = get_matching_permissions(get_profile(request.user), directory)

    if not check_permission("view", request):
        raise PermissionDenied

    template_vars = {"path": path, "directory": directory}

    if check_permission("administrate", request):
        template_vars["form"] = handle_form(request, directory)
        template_vars["title"] = directory_to_title(directory)
    if request.GET.get("all", False):
        template_vars["notices"] = Notice.objects.filter(
            directory__pootle_path__startswith=directory.pootle_path
        ).select_related("directory")[:30]
    else:
        template_vars["notices"] = Notice.objects.filter(directory=directory).select_related("directory")[:30]

    if not directory.is_language() and not directory.is_project():
        try:
            request.translation_project = directory.get_translationproject()
            template_vars["navitems"] = [navbar_dict.make_directory_navbar_dict(request, directory)]
            template_vars["translation_project"] = request.translation_project
            template_vars["language"] = request.translation_project.language
            template_vars["project"] = request.translation_project.project
        except:
            pass

    return render_to_response("notices.html", template_vars, context_instance=RequestContext(request))
Example #9
0
    def __init__(self, request, data=None, files=None):
        choices = [('merge', _("Merge the file with the current file and turn conflicts into suggestions")),
                   ('suggest', _("Add all new translations as suggestions"))]
        if check_permission('overwrite', request):
            choices.insert(0, ('overwrite',  _("Overwrite the current file if it exists")))

        translation_project = request.translation_project

        class StoreFormField(forms.ModelChoiceField):
            def label_from_instance(self, instance):
                return _(instance.pootle_path[len(translation_project.pootle_path):])

        class DirectoryFormField(forms.ModelChoiceField):
            def label_from_instance(self, instance):
                return _(instance.pootle_path[len(translation_project.pootle_path):])

        class UploadForm(forms.Form):
            file = forms.FileField(required=True, label=_('File'))
            overwrite = forms.ChoiceField(required=True, widget=forms.RadioSelect,
                                          label='', choices=choices, initial='merge')
            upload_to = StoreFormField(required=False, label=_('Upload to'),
                                       queryset=translation_project.stores.all(),
                                       help_text=_("Optionally select the file you want to merge with. If not specified, the uploaded file's name is used."))
            upload_to_dir = DirectoryFormField(required=False, label=_('Upload to'),
                              queryset=Directory.objects.filter(pootle_path__startswith=translation_project.pootle_path).exclude(pk=translation_project.directory.pk),
                              help_text=_("Optionally select the file you want to merge with. If not specified, the uploaded file's name is used."))


        self.Form = UploadForm
        super(UploadHandler, self).__init__(request, data, files)
        self.form.allow_overwrite = check_permission('overwrite', request)
        self.form.title = _("Upload File")
Example #10
0
def view(request, path):
    #FIXME: why do we have leading and trailing slashes in pootle_path?
    pootle_path = '/%s' % path

    directory = get_object_or_404(Directory, pootle_path=pootle_path)

    request.permissions = get_matching_permissions(get_profile(request.user), directory)

    if not check_permission('view', request):
        raise PermissionDenied

    template_vars = {'path': path,
                     'directory': directory}

    if check_permission('administrate', request):
        template_vars['form'] = handle_form(request, directory)
        template_vars['title'] = directory_to_title(request, directory)
    if request.GET.get('all', False):
        template_vars['notices'] = Notice.objects.filter(directory__pootle_path__startswith=directory.pootle_path).select_related('directory')[:30]
    else:
        template_vars['notices'] = Notice.objects.filter(directory=directory).select_related('directory')[:30]

    if not directory.is_language() and not directory.is_project():
        try:
            request.translation_project = directory.get_translationproject()
            template_vars['navitems'] = [navbar_dict.make_directory_navbar_dict(request, directory)]
            template_vars['translation_project'] = request.translation_project
            template_vars['language'] = request.translation_project.language
            template_vars['project'] = request.translation_project.project
        except:
            pass

    return render_to_response('notices.html', template_vars, context_instance=RequestContext(request))
Example #11
0
def translate_page(request):
    cantranslate = check_permission("translate", request)
    cansuggest = check_permission("suggest", request)
    canreview = check_permission("review", request)
    translation_project = request.translation_project
    language = translation_project.language
    profile = request.profile

    store = getattr(request, "store", None)
    is_terminology = translation_project.project.is_terminology or store and store.is_terminology
    search_form = make_search_form(terminology=is_terminology)
    context = {
        'cantranslate': cantranslate,
        'cansuggest': cansuggest,
        'canreview': canreview,
        'search_form': search_form,
        'store': store,
        'store_id': store and store.id,
        'language': language,
        'translation_project': translation_project,
        'profile': profile,
        'source_language': translation_project.project.source_language,
        'directory': getattr(request, "directory", None),
        'MT_BACKENDS': settings.MT_BACKENDS,
        'AMAGAMA_URL': settings.AMAGAMA_URL,
        'advanced_search_title': _('Advanced search'),
        }
    return render_to_response('store/translate.html', context, context_instance=RequestContext(request))
Example #12
0
def _test_translate_view(project, request, response, kwargs, settings):
    ctx = response.context
    user = request.profile
    kwargs["project_code"] = project.code
    ctx_path = "/projects/%(project_code)s/" % kwargs
    resource_path = "%(dir_path)s%(filename)s" % kwargs
    pootle_path = "%s%s" % (ctx_path, resource_path)
    view_context_test(
        ctx,
        **dict(
            page="translate",
            is_admin=False,
            language=None,
            project=project,
            profile=user,
            pootle_path="%s%s" % (ctx_path, resource_path),
            ctx_path=ctx_path,
            resource_path=resource_path,
            resource_path_parts=get_path_parts(resource_path),
            editor_extends="projects/base.html",
            check_categories=get_qualitycheck_schema(),
            previous_url=get_previous_url(request),
            display_priority=(VirtualFolderTreeItem.objects.filter(pootle_path__startswith=pootle_path).exists()),
            cantranslate=check_permission("translate", request),
            cansuggest=check_permission("suggest", request),
            canreview=check_permission("review", request),
            search_form=make_search_form(request=request),
            current_vfolder_pk="",
            POOTLE_MT_BACKENDS=settings.POOTLE_MT_BACKENDS,
            AMAGAMA_URL=settings.AMAGAMA_URL,
        )
    )
Example #13
0
def translate_page(request):
    cantranslate = check_permission("translate", request)
    cansuggest = check_permission("suggest", request)
    canreview = check_permission("review", request)
    translation_project = request.translation_project
    language = translation_project.language
    profile = request.profile

    store = getattr(request, "store", None)
    is_terminology = translation_project.project.is_terminology or store and store.is_terminology
    search_form = make_search_form(terminology=is_terminology)
    context = {
        "cantranslate": cantranslate,
        "cansuggest": cansuggest,
        "canreview": canreview,
        "search_form": search_form,
        "store": store,
        "store_id": store and store.id,
        "language": language,
        "translation_project": translation_project,
        "profile": profile,
        "source_language": translation_project.project.source_language,
        "directory": getattr(request, "directory", None),
        "MT_BACKENDS": settings.MT_BACKENDS,
        "LOOKUP_BACKENDS": settings.LOOKUP_BACKENDS,
        "AMAGAMA_URL": settings.AMAGAMA_URL,
        "advanced_search_title": _("Advanced search"),
    }
    if is_terminology:
        return render_to_response("store/terms.html", context, context_instance=RequestContext(request))
    else:
        return render_to_response("store/translate.html", context, context_instance=RequestContext(request))
Example #14
0
def upload_file(request, directory, django_file, overwrite):
    translation_project = request.translation_project
    relative_root_dir = directory.pootle_path[len(translation_project.directory.pootle_path):]
    # for some reason factory checks explicitly for file existance and
    # if file is open, which makes it difficult to work with Django's
    # in memory uploads.
    #
    # setting _closed to False should work around this
    #FIXME: hackish, does this have any undesirable side effect?
    if getattr(django_file, '_closed', None) is None:
        try:
            django_file._closed = False
        except AttributeError:
            pass
    # factory also checks for _mode
    if getattr(django_file, '_mode', None) is None:
        try:
            django_file._mode = 1
        except AttributeError:
            pass
    # mode is an attribute not a property in Django 1.1
    if getattr(django_file, 'mode', None) is None:
        django_file.mode = 1

    local_filename = get_local_filename(translation_project, django_file.name)
    pootle_path = directory.pootle_path + local_filename
    # The full filesystem path to 'local_filename'
    upload_path    = get_upload_path(translation_project, relative_root_dir, local_filename)

    try:
        store = translation_project.stores.get(pootle_path=pootle_path)
    except Store.DoesNotExist:
        store = None

    file_exists = os.path.exists(absolute_real_path(upload_path))
    if store is not None and overwrite == 'overwrite' and not check_permission('overwrite', request):
        raise PermissionDenied(_("You do not have rights to overwrite files here."))
    if store is None and not check_permission('administrate', request):
        raise PermissionDenied(_("You do not have rights to upload new files here."))
    if overwrite == 'merge' and not check_permission('translate', request):
        raise PermissionDenied(_("You do not have rights to upload files here."))
    if overwrite == 'suggest' and not check_permission('suggest', request):
        raise PermissionDenied(_("You do not have rights to upload files here."))

    if store is None or (overwrite == 'overwrite' and store.file != ""):
        overwrite_file(request, relative_root_dir, django_file, upload_path)
        return

    newstore = factory.getobject(django_file, classes=factory_classes)

    #FIXME: are we sure this is what we want to do? shouldn't we
    # diffrentiate between structure changing uploads and mere
    # pretranslate uploads?
    suggestions = overwrite == 'merge'
    notranslate = overwrite == 'suggest'
    #allownewstrings = check_permission('overwrite', request) or check_permission('administrate', request) or check_permission('commit', request)
    #obsoletemissing = allownewstrings and overwrite == 'merge'
    store.mergefile(newstore, request.user.username, suggestions=suggestions, notranslate=notranslate,
                    allownewstrings=False, obsoletemissing=False)
Example #15
0
def test_submit_fuzzy_unit(client, store0, request_users, settings, system):
    """Test un/fuzzying units."""
    settings.POOTLE_CAPTCHA_ENABLED = False
    user = request_users["user"]
    unit = store0.units.filter(state=UNTRANSLATED).first()
    if user.username != "nobody":
        client.login(
            username=user.username,
            password=request_users["password"])
    url = '/xhr/units/%d/' % unit.id
    old_target = unit.target
    new_target = "%s changed" % unit.target
    response = client.post(
        url,
        dict(target_f_0=(new_target),
             is_fuzzy="1",
             sfn="PTL.editor.processSubmission"),
        HTTP_X_REQUESTED_WITH='XMLHttpRequest')
    unit.refresh_from_db()
    if check_permission('translate', response.wsgi_request):
        assert response.status_code == 200
        assert unit.state == FUZZY
        assert unit.target == new_target
    else:
        assert response.status_code == 403
        assert unit.state == UNTRANSLATED
        assert unit.target == old_target
    response = client.post(
        url,
        dict(target_f_0=(new_target),
             is_fuzzy="0",
             sfn="PTL.editor.processSubmission"),
        HTTP_X_REQUESTED_WITH='XMLHttpRequest')
    unit.refresh_from_db()
    if check_permission('translate', response.wsgi_request):
        assert response.status_code == 200
        assert unit.state == TRANSLATED
        assert unit.target == new_target
    else:
        assert response.status_code == 403
        assert unit.state == UNTRANSLATED
        assert unit.target == old_target
    # state is always untranslated if target is empty
    response = client.post(
        url,
        dict(target_f_0="",
             is_fuzzy="1",
             sfn="PTL.editor.processSubmission"),
        HTTP_X_REQUESTED_WITH='XMLHttpRequest')
    unit.refresh_from_db()
    if check_permission('translate', response.wsgi_request):
        assert response.status_code == 200
        assert unit.target == ""
    else:
        assert response.status_code == 403
        assert unit.target == old_target
    assert unit.state == UNTRANSLATED
Example #16
0
def test_view_projects_translate(client, settings, request_users):
    user = request_users["user"]
    client.login(
        username=user.username,
        password=request_users["password"])
    response = client.get(reverse("pootle-projects-translate"))

    if not user.is_superuser:
        assert response.status_code == 403
        return
    ctx = response.context
    request = response.wsgi_request
    user_projects = Project.accessible_by_user(request.user)
    user_projects = (
        Project.objects.for_user(request.user)
                       .filter(code__in=user_projects))
    obj = ProjectSet(user_projects)
    checks = get_qualitychecks()
    schema = {sc["code"]: sc for sc in get_qualitycheck_schema()}
    check_data = obj.data_tool.get_checks()
    _checks = {}
    for check, checkid in checks.items():
        if check not in check_data:
            continue
        _checkid = schema[checkid]["name"]
        _checks[_checkid] = _checks.get(
            _checkid, dict(checks=[], title=schema[checkid]["title"]))
        _checks[_checkid]["checks"].append(
            dict(
                code=check,
                title=check_names[check],
                count=check_data[check]))
    _checks = OrderedDict(
        (k, _checks[k])
        for k in CATEGORY_IDS.keys()
        if _checks.get(k))
    assertions = dict(
        page="translate",
        has_admin_access=user.is_superuser,
        language=None,
        project=None,
        pootle_path="/projects/",
        ctx_path="/projects/",
        resource_path="",
        resource_path_parts=[],
        editor_extends="projects/all/base.html",
        checks=_checks,
        previous_url=get_previous_url(request),
        display_priority=False,
        cantranslate=check_permission("translate", request),
        cansuggest=check_permission("suggest", request),
        canreview=check_permission("review", request),
        search_form=make_search_form(request=request),
        current_vfolder_pk="",
        POOTLE_MT_BACKENDS=settings.POOTLE_MT_BACKENDS,
        AMAGAMA_URL=settings.AMAGAMA_URL)
    view_context_test(ctx, **assertions)
Example #17
0
def process_submit(request, unit, type):
    """
    Processes submissions and suggestions and stores them in the database.

    @return: An object in JSON notation that contains the previous
    and last units for the unit next to unit C{uid}.
    """
    json = {}
    cantranslate = check_permission("translate", request)
    cansuggest = check_permission("suggest", request)
    if type == "submission" and not cantranslate or type == "suggestion" and not cansuggest:
        raise PermissionDenied(_("You do not have rights to access translation mode."))

    translation_project = request.translation_project
    language = translation_project.language

    if unit.hasplural():
        snplurals = len(unit.source.strings)
    else:
        snplurals = None

    form_class = unit_form_factory(language, snplurals, request)
    form = form_class(request.POST, instance=unit)

    if form.is_valid():
        if type == "submission":
            if (
                form.instance._target_updated
                or form.instance._translator_comment_updated
                or form.instance._state_updated
            ):
                form.save()
                translation_submitted.send(sender=translation_project, unit=form.instance, profile=request.profile)

                sub = Submission(translation_project=translation_project, submitter=request.profile)
                sub.save()
        elif type == "suggestion":
            if form.instance._target_updated:
                # HACKISH: django 1.2 stupidly modifies instance on
                # model form validation, reload unit from db
                unit = Unit.objects.get(id=unit.id)
                sugg = unit.add_suggestion(form.cleaned_data["target_f"], request.profile)
                if sugg:
                    SuggestionStat.objects.get_or_create(
                        translation_project=translation_project,
                        suggester=request.profile,
                        state="pending",
                        unit=unit.id,
                    )
        rcode = 200
    else:
        # Form failed
        # FIXME: we should display validation errors here
        rcode = 400
        json["msg"] = _("Failed to process submit.")
    response = jsonify(json)
    return HttpResponse(response, status=rcode, mimetype="application/json")
Example #18
0
def _test_translate_view(project, request, response, kwargs, settings):

    if not request.user.is_superuser:
        assert response.status_code == 403
        return

    ctx = response.context
    kwargs["project_code"] = project.code
    ctx_path = (
        "/projects/%(project_code)s/" % kwargs)
    resource_path = (
        "%(dir_path)s%(filename)s" % kwargs)
    pootle_path = "%s%s" % (ctx_path, resource_path)
    display_priority = False

    checks = get_qualitychecks()
    schema = {sc["code"]: sc for sc in get_qualitycheck_schema()}
    check_data = ctx["object"].data_tool.get_checks()
    _checks = {}
    for check, checkid in checks.items():
        if check not in check_data:
            continue
        _checkid = schema[checkid]["name"]
        _checks[_checkid] = _checks.get(
            _checkid, dict(checks=[], title=schema[checkid]["title"]))
        _checks[_checkid]["checks"].append(
            dict(
                code=check,
                title=check_names[check],
                count=check_data[check]))
    _checks = OrderedDict(
        (k, _checks[k])
        for k in CATEGORY_IDS.keys()
        if _checks.get(k))
    view_context_test(
        ctx,
        **dict(
            page="translate",
            has_admin_access=request.user.is_superuser,
            language=None,
            project=project,
            pootle_path=pootle_path,
            ctx_path=ctx_path,
            resource_path=resource_path,
            resource_path_parts=get_path_parts(resource_path),
            editor_extends="projects/base.html",
            checks=_checks,
            previous_url=get_previous_url(request),
            display_priority=display_priority,
            cantranslate=check_permission("translate", request),
            cansuggest=check_permission("suggest", request),
            canreview=check_permission("review", request),
            search_form=make_search_form(request=request),
            current_vfolder_pk="",
            POOTLE_MT_BACKENDS=settings.POOTLE_MT_BACKENDS,
            AMAGAMA_URL=settings.AMAGAMA_URL))
Example #19
0
File: tp.py Project: arky/pootle
def _test_translate_view(tp, request, response, kwargs, settings):
    ctx = response.context
    obj = ctx["object"]
    kwargs["project_code"] = tp.project.code
    kwargs["language_code"] = tp.language.code
    resource_path = "%(dir_path)s%(filename)s" % kwargs
    request_path = "%s%s" % (tp.pootle_path, resource_path)

    checks = get_qualitychecks()
    schema = {sc["code"]: sc for sc in get_qualitycheck_schema()}
    check_data = obj.data_tool.get_checks()
    _checks = {}
    for check, checkid in checks.items():
        if check not in check_data:
            continue
        _checkid = schema[checkid]["name"]
        _checks[_checkid] = _checks.get(
            _checkid, dict(checks=[], title=schema[checkid]["title"]))
        _checks[_checkid]["checks"].append(
            dict(
                code=check,
                title=CHECK_NAMES[check],
                count=check_data[check]))
    _checks = OrderedDict(
        (k, _checks[k])
        for k in CATEGORY_IDS.keys()
        if _checks.get(k))
    current_vfolder_pk = ""
    display_priority = False
    if not kwargs["filename"]:
        vf_view = vfolders_data_view.get(obj.__class__)(obj, request.user)
        display_priority = vf_view.has_data
    unit_api_root = "/xhr/units/"
    assertions = dict(
        page="translate",
        translation_project=tp,
        language=tp.language,
        project=tp.project,
        has_admin_access=check_permission('administrate', request),
        ctx_path=tp.pootle_path,
        pootle_path=request_path,
        resource_path=resource_path,
        resource_path_parts=get_path_parts(resource_path),
        editor_extends="translation_projects/base.html",
        checks=_checks,
        previous_url=get_previous_url(request),
        current_vfolder_pk=current_vfolder_pk,
        display_priority=display_priority,
        cantranslate=check_permission("translate", request),
        cansuggest=check_permission("suggest", request),
        canreview=check_permission("review", request),
        search_form=make_search_form(request=request),
        unit_api_root=unit_api_root,
        POOTLE_MT_BACKENDS=settings.POOTLE_MT_BACKENDS,
        AMAGAMA_URL=settings.AMAGAMA_URL)
    view_context_test(ctx, **assertions)
Example #20
0
def upload_form_factory(request):
    translation_project = request.translation_project
    choices = []

    if check_permission('overwrite', request):
        choices.append(('overwrite', _("Overwrite the current file if it "
                                       "exists")))
    if check_permission('translate', request):
        choices.append(('merge', _("Merge the file with the current file and "
                                   "turn conflicts into suggestions")))
    if check_permission('suggest', request):
        choices.append(('suggest', _("Add all new translations as "
                                     "suggestions")))

    if check_permission('translate', request):
        initial = 'merge'
    else:
        initial = 'suggest'

    class StoreFormField(forms.ModelChoiceField):
        def label_from_instance(self, instance):
            return instance.pootle_path[len(request.pootle_path):]

    class DirectoryFormField(forms.ModelChoiceField):
        def label_from_instance(self, instance):
            return instance.pootle_path[len(translation_project.pootle_path):]

    class UploadForm(forms.Form):
        file = forms.FileField(required=True, label=_('File'))
        overwrite = forms.ChoiceField(
            required=True,
            widget=forms.RadioSelect,
            label='',
            choices=choices,
            initial=initial
        )
        upload_to = StoreFormField(
            required=False,
            label=_('Upload to'),
            queryset=translation_project.stores.filter(
                pootle_path__startswith=request.pootle_path),
            help_text=_("Optionally select the file you want to merge with. "
                        "If not specified, the uploaded file's name is used.")
        )
        upload_to_dir = DirectoryFormField(
            required=False,
            label=_('Upload to'),
            queryset=Directory.objects.filter(
                pootle_path__startswith=translation_project.pootle_path). \
                exclude(pk=translation_project.directory.pk),
            help_text=_("Optionally select the file you want to merge with. "
                        "If not specified, the uploaded file's name is used.")
        )

    return UploadForm
Example #21
0
def project_language_index(request, project_code):
    """page listing all languages added to project"""
    project = get_object_or_404(Project, code=project_code)
    request.permissions = get_matching_permissions(
            get_profile(request.user), project.directory
    )

    if not check_permission('view', request):
        raise PermissionDenied

    can_edit = check_permission('administrate', request)

    translation_projects = project.translationproject_set.all()

    items = [make_language_item(request, translation_project) \
            for translation_project in translation_projects.iterator()]
    items.sort(lambda x, y: locale.strcoll(x['title'], y['title']))

    languagecount = len(translation_projects)
    project_stats = get_raw_stats(project)
    average = project_stats['translated']['percentage']

    topstats = gentopstats_project(project)

    table_fields = ['name', 'progress', 'total', 'need-translation', 'activity']
    table = {
        'id': 'project',
        'proportional': False,
        'fields': table_fields,
        'headings': get_table_headings(table_fields),
        'items': items,
    }

    templatevars = {
        'project': {
          'code': project.code,
          'name': project.fullname,
          'description': project.description,
          'summary': ungettext('%(languages)d language, %(average)d%% translated',
                               '%(languages)d languages, %(average)d%% translated',
                               languagecount, {"languages": languagecount,
                                               "average": average}),
        },
        'topstats': topstats,
        'can_edit': can_edit,
        'table': table,
    }

    if can_edit:
        from pootle_project.forms import DescriptionForm
        templatevars['form'] = DescriptionForm(instance=project)

    return render_to_response('project/project.html', templatevars,
                              context_instance=RequestContext(request))
Example #22
0
def view(request, path):
    #FIXME: why do we have leading and trailing slashes in pootle_path?
    pootle_path = '/%s' % path

    directory = get_object_or_404(Directory, pootle_path=pootle_path)

    request.permissions = get_matching_permissions(get_profile(request.user),
                                                   directory)

    if not check_permission('view', request):
        raise PermissionDenied

    template_vars = {'path': path,
                     'directory': directory}

    # Find language and project defaults, passed to handle_form
    proj = None
    lang = None
    if not directory.is_language() and not directory.is_project():
        translation_project = directory.translation_project
        lang = translation_project.language
        proj = translation_project.project
    else:
        if directory.is_language():
            lang = directory.language
            proj = None
        if directory.is_project():
            lang = None
            proj = directory.project


    if check_permission('administrate', request):
        # Thus, form is only set for the template if the user has
        # 'administrate' permission
        template_vars['form'] = handle_form(request, directory, proj, lang,
                                            template_vars)
        template_vars['title'] = directory_to_title(directory)
    else:
        template_vars['form'] = None

    if request.GET.get('all', False):
        template_vars['notices'] = Notice.objects.filter(directory__pootle_path__startswith=directory.pootle_path).select_related('directory')[:30]
    else:
        template_vars['notices'] = Notice.objects.filter(directory=directory).select_related('directory')[:30]

    if not directory.is_language() and not directory.is_project():
        request.translation_project = directory.translation_project
        template_vars['translation_project'] = request.translation_project
        template_vars['language'] = request.translation_project.language
        template_vars['project'] = request.translation_project.project

    return render_to_response('notices.html', template_vars,
                              context_instance=RequestContext(request))
Example #23
0
def upload_zip(request, path_obj):
    if (check_permission('translate', request) or
        check_permission('suggest', request) or
        check_permission('overwrite', request)):
        text = _('Upload (.zip)')
        link = '#'

        return {
            'icon': 'icon-upload',
            'class': 'js-overview-actions-upload',
            'href': link,
            'text': text,
        }
Example #24
0
File: tp.py Project: phlax/pootle
def _test_translate_view(tp, request, response, kwargs, settings):
    ctx = response.context
    obj = ctx["object"]
    kwargs["project_code"] = tp.project.code
    kwargs["language_code"] = tp.language.code
    resource_path = "%(dir_path)s%(filename)s" % kwargs
    request_path = "%s%s" % (tp.pootle_path, resource_path)
    if request.path.startswith("/++vfolder"):
        vfolder = VirtualFolder.objects.get(
            name=request.resolver_match.kwargs["vfolder_name"])
        current_vfolder_pk = vfolder.pk
        display_priority = False
        unit_api_root = reverse(
            "vfolder-pootle-xhr-units",
            kwargs=dict(vfolder_name=vfolder.name))
        resource_path = (
            "/".join(
                ["++vfolder",
                 vfolder.name,
                 ctx['object'].pootle_path.replace(tp.pootle_path, "")]))
    else:
        vfolder = None
        current_vfolder_pk = ""
        display_priority = False
        if not kwargs["filename"]:
            vf_view = vfolders_data_view.get(obj.__class__)(obj, request.user)
            display_priority = vf_view.has_data
        unit_api_root = "/xhr/units/"
    assertions = dict(
        page="translate",
        translation_project=tp,
        language=tp.language,
        project=tp.project,
        has_admin_access=check_permission('administrate', request),
        ctx_path=tp.pootle_path,
        pootle_path=request_path,
        resource_path=resource_path,
        resource_path_parts=get_path_parts(resource_path),
        editor_extends="translation_projects/base.html",
        check_categories=get_qualitycheck_schema(),
        previous_url=get_previous_url(request),
        current_vfolder_pk=current_vfolder_pk,
        display_priority=display_priority,
        cantranslate=check_permission("translate", request),
        cansuggest=check_permission("suggest", request),
        canreview=check_permission("review", request),
        search_form=make_search_form(request=request),
        unit_api_root=unit_api_root,
        POOTLE_MT_BACKENDS=settings.POOTLE_MT_BACKENDS,
        AMAGAMA_URL=settings.AMAGAMA_URL)
    view_context_test(ctx, **assertions)
Example #25
0
def translate_page(request):
    cantranslate = check_permission("translate", request)
    cansuggest = check_permission("suggest", request)
    canreview = check_permission("review", request)

    translation_project = request.translation_project
    language = translation_project.language
    project = translation_project.project
    profile = request.profile

    store = getattr(request, "store", None)
    directory = getattr(request, "directory", None)

    is_single_file = store and True or False
    path = is_single_file and store.path or directory.path
    pootle_path = (is_single_file and store.pootle_path or
                                      directory.pootle_path)

    is_terminology = (project.is_terminology or store and
                                                store.is_terminology)
    search_form = make_search_form(request=request,
                                   terminology=is_terminology)

    previous_overview_url = previous_view_url(request, ['overview'])

    context = {
        'cantranslate': cantranslate,
        'cansuggest': cansuggest,
        'canreview': canreview,
        'search_form': search_form,
        'store': store,
        'store_id': store and store.id,
        'directory': directory,
        'directory_id': directory and directory.id,
        'path': path,
        'pootle_path': pootle_path,
        'is_single_file': is_single_file,
        'language': language,
        'project': project,
        'translation_project': translation_project,
        'profile': profile,
        'source_language': translation_project.project.source_language,
        'previous_overview_url': previous_overview_url,
        'MT_BACKENDS': settings.MT_BACKENDS,
        'LOOKUP_BACKENDS': settings.LOOKUP_BACKENDS,
        'AMAGAMA_URL': settings.AMAGAMA_URL,
    }

    return render_to_response('store/translate.html', context,
                              context_instance=RequestContext(request))
Example #26
0
    def __init__(self, request, data=None, files=None):
        choices = [('merge', _("Merge the file with the current file and turn conflicts into suggestions")),
                   ('suggest', _("Add all new translations as suggestions"))]
        if check_permission('overwrite', request):
            choices.insert(0, ('overwrite',  _("Overwrite the current file if it exists")))

        class UploadForm(forms.Form):
            file = forms.FileField(required=True, label=_('File'))
            overwrite = forms.ChoiceField(required=True, widget=forms.RadioSelect,
                                          label='', choices=choices, initial='merge')

        self.Form = UploadForm
        super(UploadHandler, self).__init__(request, data, files)
        self.form.allow_overwrite = check_permission('overwrite', request)
        self.form.title = _("Upload File")
Example #27
0
def upload_zip(request, path_obj, **kwargs):
    if (check_permission('translate', request) or
        check_permission('suggest', request) or
        check_permission('overwrite', request)):
        text = _('Upload')
        tooltip = _('Upload translation files or archives in .zip format')
        link = '#upload'

        return {
            'icon': 'icon-upload',
            'class': 'js-popup-inline',
            'href': link,
            'text': text,
            'tooltip': tooltip,
        }
Example #28
0
def get_items(request, model, get_last_action, name_func):

    items = []
    if not check_permission('view', request):
        return items

    for item in model.iterator():
        stats = item.getquickstats()
        stats = add_percentages(stats)

        lastact = get_last_action(item)
        items.append({
            'code': item.code,
            'name': name_func(item.fullname),
            'lastactivity': lastact,
            'trans': stats["translatedsourcewords"],
            'fuzzy': stats["fuzzysourcewords"],
            'untrans': stats["untranslatedsourcewords"],
            'total': stats["totalsourcewords"],
            'transper': stats["translatedpercentage"],
            'fuzzyper': stats["fuzzypercentage"],
            'untransper': stats["untranslatedpercentage"],
            'completed_title': _("%(percentage)d%% complete",
                                 {'percentage': stats['translatedpercentage']}),
            })
    items.sort(lambda x, y: locale.strcoll(x['name'], y['name']))
    return items
Example #29
0
File: views.py Project: kant/pootle
def overview(request, translation_project, dir_path, filename=None):
    if not check_permission("view", request):
        raise PermissionDenied(_("You do not have rights to access this "
                                 "translation project."))

    current_path = translation_project.directory.pootle_path + dir_path

    if filename:
        current_path = current_path + filename
        store = get_object_or_404(Store, pootle_path=current_path)
        directory = store.parent
    else:
        directory = get_object_or_404(Directory, pootle_path=current_path)
        store = None

    request.current_path = current_path

    view_obj = ProjectIndexView(forms=dict(upload=UploadHandler,
                                          )
                               )

    return render_to_response("translation_project/overview.html",
                              view_obj(request, translation_project,
                                       directory, store),
                              context_instance=RequestContext(request))
Example #30
0
def reject_suggestion(request, unit, suggid):
    json = {
        'udbid': unit.id,
        'sugid': suggid,
    }

    try:
        sugg = unit.suggestion_set.get(id=suggid)
    except ObjectDoesNotExist:
        raise Http404

    # In order to be able to reject a suggestion, users have to either:
    # 1. Have `review` rights, or
    # 2. Be the author of the suggestion being rejected
    if (not check_permission('review', request) and
        (request.user.is_anonymous() or request.user != sugg.user)):
        raise PermissionDenied(_('Insufficient rights to access review mode.'))

    unit.reject_suggestion(sugg, request.translation_project, request.user)
    r_data = QueryDict(request.body)
    if "comment" in r_data and r_data["comment"]:
        kwargs = dict(
            comment=r_data["comment"],
            user=request.user,
        )
        comment_form = UnsecuredCommentForm(sugg, kwargs)
        if comment_form.is_valid():
            comment_form.save()

    json['user_score'] = request.user.public_score

    return JsonResponse(json)
Example #31
0
def unit_form_factory(language, snplurals=None, request=None):

    if snplurals is not None:
        tnplurals = language.nplurals
    else:
        tnplurals = 1

    action_disabled = False
    if request is not None:
        cantranslate = check_permission("translate", request)
        cansuggest = check_permission("suggest", request)

        if not (cansuggest or cantranslate):
            action_disabled = True

    target_attrs = {
        'lang': language.code,
        'dir': language.direction,
        'class': 'translation expanding focusthis js-translation-area',
        'rows': 2,
        'tabindex': 10,
    }

    fuzzy_attrs = {
        'accesskey': 'f',
        'class': 'fuzzycheck',
        'tabindex': 13,
    }

    if action_disabled:
        target_attrs['disabled'] = 'disabled'
        fuzzy_attrs['disabled'] = 'disabled'

    class UnitForm(forms.ModelForm):
        class Meta:
            model = Unit
            fields = (
                'id',
                'index',
                'target_f',
                'state',
            )

        id = forms.IntegerField(required=False)
        target_f = MultiStringFormField(
            nplurals=tnplurals,
            required=False,
            attrs=target_attrs,
        )
        state = UnitStateField(
            required=False,
            label=_('Needs work'),
            widget=forms.CheckboxInput(
                attrs=fuzzy_attrs,
                check_test=lambda x: x == FUZZY,
            ),
        )
        similarity = forms.FloatField(required=False)
        mt_similarity = forms.FloatField(required=False)

        def __init__(self, *args, **kwargs):
            self.request = kwargs.pop('request', None)
            super(UnitForm, self).__init__(*args, **kwargs)
            self.updated_fields = []

            self.fields['target_f'].widget.attrs['data-translation-aid'] = \
                self['target_f'].value()

        def clean_target_f(self):
            value = self.cleaned_data['target_f']

            if self.instance.target.strings != multistring(value or [u'']):
                self.instance._target_updated = True
                self.updated_fields.append(
                    (SubmissionFields.TARGET, to_db(self.instance.target),
                     to_db(value)))

            return value

        def clean_state(self):
            old_state = self.instance.state  # Integer
            is_fuzzy = self.cleaned_data['state']  # Boolean
            new_target = self.cleaned_data['target_f']

            if (self.request is not None
                    and not check_permission('administrate', self.request)
                    and is_fuzzy):
                raise forms.ValidationError(_('Fuzzy flag must be cleared'))

            if new_target:
                if old_state == UNTRANSLATED:
                    self.instance._save_action = TRANSLATION_ADDED
                    self.instance.store.mark_dirty(
                        CachedMethods.WORDCOUNT_STATS)
                else:
                    self.instance._save_action = TRANSLATION_CHANGED

                if is_fuzzy:
                    new_state = FUZZY
                else:
                    new_state = TRANSLATED
            else:
                new_state = UNTRANSLATED
                if old_state > FUZZY:
                    self.instance._save_action = TRANSLATION_DELETED
                    self.instance.store.mark_dirty(
                        CachedMethods.WORDCOUNT_STATS)

            if is_fuzzy != (old_state == FUZZY):
                # when Unit toggles its FUZZY state the number of translated words
                # also changes
                self.instance.store.mark_dirty(CachedMethods.WORDCOUNT_STATS,
                                               CachedMethods.LAST_ACTION)

            if old_state != new_state and old_state != OBSOLETE:
                self.instance._state_updated = True
                self.updated_fields.append(
                    (SubmissionFields.STATE, old_state, new_state))

                return new_state

            self.instance._state_updated = False

            return old_state

        def clean_similarity(self):
            value = self.cleaned_data['similarity']

            if 0 <= value <= 1 or value is None:
                return value

            raise forms.ValidationError(
                _('Value of `similarity` should be in in the [0..1] range'))

        def clean_mt_similarity(self):
            value = self.cleaned_data['mt_similarity']

            if 0 <= value <= 1 or value is None:
                return value

            raise forms.ValidationError(
                _('Value of `mt_similarity` should be in in the [0..1] range'))

    return UnitForm
Example #32
0
 def is_admin(self):
     return check_permission('administrate', self.request)
Example #33
0
def unit_form_factory(language, snplurals=None, request=None):

    if snplurals is not None:
        tnplurals = language.nplurals
    else:
        tnplurals = 1

    action_disabled = False
    if request is not None:
        cantranslate = check_permission("translate", request)
        cansuggest = check_permission("suggest", request)

        if not (cansuggest or cantranslate):
            action_disabled = True

    target_attrs = {
        'lang': language.code,
        'dir': language.direction,
        'class': 'translation expanding focusthis js-translation-area',
        'rows': 2,
        'tabindex': 10,
    }

    fuzzy_attrs = {
        'accesskey': 'f',
        'class': 'fuzzycheck',
        'tabindex': 13,
    }

    if action_disabled:
        target_attrs['disabled'] = 'disabled'
        fuzzy_attrs['disabled'] = 'disabled'

    class UnitForm(forms.ModelForm):
        class Meta(object):
            model = Unit
            fields = ('target_f', )

        target_f = MultiStringFormField(
            nplurals=tnplurals,
            required=False,
            attrs=target_attrs,
        )
        is_fuzzy = forms.BooleanField(
            required=False,
            label=_("Needs work"),
            widget=forms.CheckboxInput(attrs=fuzzy_attrs))
        suggestion = forms.ModelChoiceField(queryset=Suggestion.objects.all(),
                                            required=False)
        comment = forms.CharField(required=False)

        def __init__(self, *args, **kwargs):
            self.request = kwargs.pop('request', None)
            self.user = self.request.user
            super(UnitForm, self).__init__(*args, **kwargs)
            self._updated_fields = []
            self.fields['target_f'].widget.attrs['data-translation-aid'] = \
                self['target_f'].value()
            self.initial.update(dict(is_fuzzy=(self.instance.state == FUZZY)))

        @property
        def updated_fields(self):
            order_dict = {
                SubmissionFields.STATE: 0,
                SubmissionFields.TARGET: 1,
            }
            return sorted(self._updated_fields, key=lambda x: order_dict[x[0]])

        def clean_target_f(self):
            value = self.cleaned_data['target_f']

            if self.instance.target != multistring(value or [u'']):
                self._updated_fields.append(
                    (SubmissionFields.TARGET, to_db(self.instance.target),
                     to_db(value)))

            return value

        def clean_is_fuzzy(self):
            return self.data.get("is_fuzzy", None) and True or False

        def clean(self):
            old_state = self.instance.state  # Integer
            is_fuzzy = self.cleaned_data['is_fuzzy']  # Boolean
            new_target = self.cleaned_data['target_f']

            # If suggestion is provided set `old_state` should be `TRANSLATED`.
            if self.cleaned_data['suggestion']:
                old_state = TRANSLATED

                # Skip `TARGET` field submission if suggestion value is equal
                # to submitted translation
                if new_target == self.cleaned_data['suggestion'].target_f:
                    self._updated_fields = []
            not_cleared = (self.request is not None and
                           not check_permission('administrate', self.request)
                           and is_fuzzy)
            if not_cleared:
                self.add_error(
                    'is_fuzzy',
                    forms.ValidationError(
                        _('Needs work flag must be cleared')))

            if new_target:
                if is_fuzzy:
                    new_state = FUZZY
                else:
                    new_state = TRANSLATED
            else:
                new_state = UNTRANSLATED
            if old_state not in [new_state, OBSOLETE]:
                self._updated_fields.append(
                    (SubmissionFields.STATE, old_state, new_state))

                self.cleaned_data['state'] = new_state
            else:
                self.cleaned_data['state'] = old_state

            return super(UnitForm, self).clean()

        def save(self, *args, **kwargs):
            if not self.updated_fields:
                return
            changed_with = kwargs.pop("changed_with", None)
            suggestion = self.cleaned_data["suggestion"]
            with update_store_after(self.instance.store):
                user = (suggestion.user if suggestion else self.user)
                self.instance.save(user=user, changed_with=changed_with)
            return self.instance

    return UnitForm
Example #34
0
File: tp.py Project: lawlor/pootle
def _test_browse_view(tp, request, response, kwargs):
    cookie_data = json.loads(
        unquote(response.cookies[SIDEBAR_COOKIE_NAME].value))
    assert cookie_data["foo"] == "bar"
    assert "announcements_projects_%s" % tp.project.code in cookie_data
    assert "announcements_%s" % tp.language.code in cookie_data
    assert ("announcements_%s_%s" % (tp.language.code, tp.project.code)
            in cookie_data)
    ctx = response.context
    kwargs["project_code"] = tp.project.code
    kwargs["language_code"] = tp.language.code
    resource_path = "%(dir_path)s%(filename)s" % kwargs
    pootle_path = "%s%s" % (tp.pootle_path, resource_path)

    if not (kwargs["dir_path"] or kwargs.get("filename")):
        obj = tp.directory
    elif not kwargs.get("filename"):
        obj = Directory.objects.get(pootle_path=pootle_path)
    else:
        obj = Store.objects.get(pootle_path=pootle_path)
    if obj.tp_path == "/":
        data_obj = obj.tp
    else:
        data_obj = obj
    if not kwargs.get("filename"):
        vf_view = vfolders_data_view.get(obj.__class__)(obj, request.user)
        vf_stats = ({} if not vf_view else StatsDisplay(
            data_obj, stats=vf_view.stats).stats)
        stats = (dict(vfolders=vf_stats["children"]) if vf_stats else {})
        stats.update(
            StatsDisplay(
                data_obj,
                stats=data_obj.data_tool.get_stats(user=request.user)).stats)
        vfolders = True
    else:
        stats = StatsDisplay(
            data_obj, data_obj.data_tool.get_stats(user=request.user)).stats
        vfolders = None
    filters = {}
    if vfolders:
        filters['sort'] = 'priority'
    dirs_with_vfolders = set(
        split_pootle_path(path)[2].split("/")[0] for path in tp.stores.filter(
            vfolders__isnull=False).values_list("pootle_path", flat=True))
    directories = [
        make_directory_item(
            child,
            **(dict(
                sort="priority") if child.name in dirs_with_vfolders else {}))
        for child in obj.get_children() if isinstance(child, Directory)
    ]
    stores = [
        make_store_item(child) for child in obj.get_children()
        if isinstance(child, Store)
    ]
    items = directories + stores
    for item in items:
        if item["code"] in stats["children"]:
            item["stats"] = stats["children"][item["code"]]
        elif item["title"] in stats["children"]:
            item["stats"] = stats["children"][item["title"]]
    if not kwargs.get("filename"):
        table_fields = [
            'name', 'progress', 'total', 'need-translation', 'suggestions',
            'critical', 'last-updated', 'activity'
        ]
        table = {
            'id': 'tp',
            'fields': table_fields,
            'headings': get_table_headings(table_fields),
            'items': items
        }
    else:
        table = None
    checks = ChecksDisplay(obj).checks_by_category
    del stats["children"]
    User = get_user_model()
    top_scorers = User.top_scorers(language=tp.language.code,
                                   project=tp.project.code,
                                   limit=11)
    assertions = dict(
        page="browse",
        object=obj,
        translation_project=tp,
        language=tp.language,
        project=tp.project,
        has_admin_access=check_permission('administrate', request),
        is_store=(kwargs.get("filename") and True or False),
        browser_extends="translation_projects/base.html",
        pootle_path=pootle_path,
        resource_path=resource_path,
        resource_path_parts=get_path_parts(resource_path),
        translation_states=get_translation_states(obj),
        checks=checks,
        top_scorers=top_scorers,
        top_scorers_data=get_top_scorers_data(top_scorers, 10),
        url_action_continue=obj.get_translate_url(state='incomplete',
                                                  **filters),
        url_action_fixcritical=obj.get_critical_url(**filters),
        url_action_review=obj.get_translate_url(state='suggestions',
                                                **filters),
        url_action_view_all=obj.get_translate_url(state='all'),
        stats=stats,
        parent=get_parent(obj))
    if table:
        assertions["table"] = table
    sidebar = get_sidebar_announcements_context(request,
                                                (tp.project, tp.language, tp))
    for k in ["has_sidebar", "is_sidebar_open", "announcements"]:
        assertions[k] = sidebar[0][k]
    view_context_test(ctx, **assertions)
    if vfolders:
        for vfolder in ctx["vfolders"]["items"]:
            assert (vfolder["is_grayed"]
                    and not ctx["has_admin_access"]) is False
        assert ctx["vfolders"]["items"] == vf_view.table_items

    assert (('display_download' in ctx
             and ctx['display_download']) == (request.user.is_authenticated()
                                              and check_permission(
                                                  'translate', request)))
Example #35
0
def handle_upload_form(request, tp):
    """Process the upload form."""
    valid_extensions = tp.project.filetype_tool.valid_extensions
    if "po" not in valid_extensions:
        return {}
    language = tp.language
    team = language_team.get(tp.language.__class__)(language)

    uploader_list = [
        (request.user.id, request.user.display_name),
    ]
    if check_permission('administrate', request):
        User = get_user_model()
        uploader_list = [(user.id, user.display_name)
                         for user in (team.submitters | team.reviewers
                                      | team.admins | team.superusers)]

    if request.method == "POST" and "file" in request.FILES:
        upload_form = UploadForm(request.POST,
                                 request.FILES,
                                 uploader_list=uploader_list)

        if upload_form.is_valid():
            uploader_id = upload_form.cleaned_data["user_id"]
            django_file = request.FILES["file"]
            uploader = request.user
            if uploader_id and uploader_id != uploader.id:
                User = get_user_model()
                uploader = User.objects.get(
                    id=upload_form.cleaned_data["user_id"])

            try:
                if is_zipfile(django_file):
                    with ZipFile(django_file, "r") as zf:
                        for path in zf.namelist():
                            if path.endswith("/"):
                                # is a directory
                                continue
                            ext = os.path.splitext(path)[1].strip(".")
                            if ext not in valid_extensions:
                                continue
                            with zf.open(path, "r") as f:
                                import_file(f, user=uploader)
                else:
                    # It is necessary to seek to the beginning because
                    # is_zipfile f***s the file, and thus cannot be read.
                    django_file.seek(0)
                    import_file(django_file, user=uploader)
            except Exception as e:
                upload_form.add_error("file", e)
                return {
                    "upload_form": upload_form,
                }
        else:
            return {
                "upload_form": upload_form,
            }

    # Always return a blank upload form unless the upload form is not valid.
    return {
        "upload_form":
        UploadForm(uploader_list=uploader_list,
                   initial=dict(user_id=request.user.id)),
    }
Example #36
0
def project_admin(request, project_code):
    """adding and deleting project languages"""
    current_project = Project.objects.get(code=project_code)
    request.permissions = get_matching_permissions(get_profile(request.user),
                                                   current_project.directory)

    if not check_permission('administrate', request):
        raise PermissionDenied(
            _("You do not have rights to administer "
              "this project."))

    template_translation_project = current_project \
                                        .get_template_translationproject()

    class TranslationProjectForm(forms.ModelForm):

        if template_translation_project is not None:
            update = forms.BooleanField(required=False,
                                        label=_("Update against templates"))

        #FIXME: maybe we can detect if initialize is needed to avoid
        # displaying it when not relevant
        #initialize = forms.BooleanField(required=False, label=_("Initialize"))

        project = forms.ModelChoiceField(
            queryset=Project.objects.filter(pk=current_project.pk),
            initial=current_project.pk,
            widget=forms.HiddenInput)
        language = LiberalModelChoiceField(
            label=_("Language"),
            queryset=Language.objects.exclude(
                translationproject__project=current_project),
            widget=forms.Select(attrs={
                'class': 'js-select2 select2-language',
            }),
        )

        class Meta:
            prefix = "existing_language"
            model = TranslationProject

        def process_extra_fields(self):
            if self.instance.pk is not None:
                if self.cleaned_data.get('initialize', None):
                    self.instance.initialize()

                if (self.cleaned_data.get('update', None)
                        or not self.instance.stores.count()):
                    self.instance.update_against_templates()

    queryset = TranslationProject.objects.filter(
        project=current_project).order_by('pootle_path')

    model_args = {
        'project': {
            'code': current_project.code,
            'name': current_project.fullname,
        }
    }

    link = lambda instance: '<a href="%s">%s</a>' % (
        l(instance.pootle_path + 'admin_permissions.html'),
        instance.language,
    )

    return util.edit(request,
                     'project/project_admin.html',
                     TranslationProject,
                     model_args,
                     link,
                     linkfield="language",
                     queryset=queryset,
                     can_delete=True,
                     form=TranslationProjectForm,
                     formset=TranslationProjectFormSet,
                     exclude=('description', ))
Example #37
0
 def must_display(cls, request, *args, **kwargs):
     return check_permission('translate', request) or \
            check_permission('suggest', request) or \
            check_permission('overwrite', request)
Example #38
0
def browse(request, translation_project, dir_path, filename=None):
    project = translation_project.project
    language = translation_project.language

    directory = request.directory
    store = request.store
    is_admin = check_permission('administrate', request)

    ctx, cookie_data = get_sidebar_announcements_context(
        request, project.code, language.code)

    ctx.update(get_browser_context(request))

    # TODO improve plugin logic
    if "import_export" in settings.INSTALLED_APPS and request.user.is_authenticated(
    ):
        from import_export.views import handle_upload_form

        ctx.update(handle_upload_form(request))

        has_download = (not translation_project.is_terminology_project
                        and (check_permission('translate', request)
                             or check_permission('suggest', request)))
        ctx.update({
            'display_download': has_download,
            'has_sidebar': True,
        })

    stats = request.resource_obj.get_stats()

    if store is None:
        table_fields = [
            'name', 'progress', 'total', 'need-translation', 'suggestions',
            'critical', 'last-updated', 'activity'
        ]
        ctx.update({
            'table': {
                'id': 'tp',
                'fields': table_fields,
                'headings': get_table_headings(table_fields),
                'items': get_children(directory),
            }
        })

        if 'virtualfolder' in settings.INSTALLED_APPS:
            vfolders = get_vfolders(directory, all_vfolders=is_admin)
            if len(vfolders) > 0:
                table_fields = [
                    'name', 'priority', 'progress', 'total',
                    'need-translation', 'suggestions', 'critical',
                    'last-updated', 'activity'
                ]
                ctx.update({
                    'vfolders': {
                        'id': 'vfolders',
                        'fields': table_fields,
                        'headings': get_table_headings(table_fields),
                        'items': vfolders,
                    },
                })

                #FIXME: set vfolders stats in the resource, don't inject them here.
                stats['vfolders'] = {}

                for vfolder_treeitem in directory.vf_treeitems.iterator():
                    if request.user.is_superuser or vfolder_treeitem.is_visible:
                        stats['vfolders'][vfolder_treeitem.code] = \
                            vfolder_treeitem.get_stats(include_children=False)

    ctx.update({
        'parent': get_parent(directory if store is None else store),
        'translation_project': translation_project,
        'project': project,
        'language': language,
        'stats': jsonify(stats),
        'is_admin': is_admin,
        'is_store': store is not None,
        'browser_extends': 'translation_projects/base.html',
    })

    response = render(request, 'browser/index.html', ctx)

    if cookie_data:
        response.set_cookie(SIDEBAR_COOKIE_NAME, cookie_data)

    return response
Example #39
0
 def is_active(self, request):
     """Check if the action is active."""
     return check_permission(self.permission, request)
Example #40
0
    def __init__(self, request, data=None, files=None):
        choices = []

        if check_permission('overwrite', request):
            choices.append(
                ('overwrite', _("Overwrite the current file if it exists")))

        if check_permission('translate', request):
            choices.append(('merge',
                            _("Merge the file with the current file and turn "
                              "conflicts into suggestions")))

        if check_permission('suggest', request):
            choices.append(
                ('suggest', _("Add all new translations as suggestions")))

        translation_project = request.translation_project

        class StoreFormField(forms.ModelChoiceField):
            def label_from_instance(self, instance):
                return instance.pootle_path[len(request.current_path):]

        class DirectoryFormField(forms.ModelChoiceField):
            def label_from_instance(self, instance):
                return instance.pootle_path[len(translation_project.pootle_path
                                                ):]

        class UploadForm(forms.Form):

            file = forms.FileField(required=True, label=_('File'))

            if check_permission('translate', request):
                initial = 'merge'
            else:
                initial = 'suggest'

            overwrite = forms.ChoiceField(required=True,
                                          widget=forms.RadioSelect,
                                          label='',
                                          choices=choices,
                                          initial=initial)
            upload_to = StoreFormField(
                required=False,
                label=_('Upload to'),
                queryset=translation_project.stores.filter(
                    pootle_path__startswith=request.current_path),
                help_text=_("Optionally select the file you want to "
                            "merge with. If not specified, the uploaded "
                            "file's name is used."))

            upload_to_dir = DirectoryFormField(
                    required=False, label=_('Upload to'),
                    queryset=Directory.objects.filter(
                        pootle_path__startswith=translation_project.pootle_path).\
                        exclude(pk=translation_project.directory.pk),
                    help_text=_("Optionally select the file you want to "
                                "merge with. If not specified, the uploaded "
                                "file's name is used."))

        self.Form = UploadForm

        super(UploadHandler, self).__init__(request, data, files)

        self.form.allow_overwrite = check_permission('overwrite', request)
        self.form.title = _("Upload File")
Example #41
0
def overview(request, translation_project, dir_path, filename=None):
    project = translation_project.project
    language = translation_project.language

    directory = request.directory
    store = request.store

    # TODO: cleanup and refactor, retrieve from cache
    try:
        ann_virtual_path = 'announcements/projects/' + project.code
        announcement = StaticPage.objects.live(request.user).get(
            virtual_path=ann_virtual_path, )
    except StaticPage.DoesNotExist:
        announcement = None

    has_announcement = announcement is not None
    has_sidebar = has_announcement
    is_sidebar_open = True
    stored_mtime = None
    new_mtime = None
    cookie_data = {}

    if ANN_COOKIE_NAME in request.COOKIES:
        json_str = unquote(request.COOKIES[ANN_COOKIE_NAME])
        cookie_data = json.loads(json_str)

        if 'isOpen' in cookie_data:
            is_sidebar_open = cookie_data['isOpen']

        if project.code in cookie_data:
            stored_mtime = cookie_data[project.code]

    if announcement is not None:
        ann_mtime = dateformat.format(announcement.modified_on, 'U')
        if ann_mtime != stored_mtime:
            is_sidebar_open = True
            new_mtime = ann_mtime

    ctx = get_overview_context(request)

    # TODO improve plugin logic
    if "import_export" in settings.INSTALLED_APPS and request.user.is_authenticated(
    ):
        from import_export.views import handle_upload_form
        from pootle_app.models.permissions import check_permission

        ctx.update(handle_upload_form(request))

        has_download = (check_permission('translate', request)
                        or check_permission('suggest', request))
        ctx.update({
            'display_download': has_download,
        })
        has_sidebar = True

    ctx.update({
        'translation_project': translation_project,
        'project': project,
        'language': language,
        'stats': jsonify(request.resource_obj.get_stats()),
        'browser_extends': 'translation_projects/base.html',
        'announcement': announcement,
        'is_sidebar_open': is_sidebar_open,
        'has_sidebar': has_sidebar,
    })

    if store is None:
        table_fields = [
            'name', 'progress', 'total', 'need-translation', 'suggestions',
            'critical', 'last-updated', 'activity'
        ]
        ctx.update({
            'table': {
                'id': 'tp',
                'fields': table_fields,
                'headings': get_table_headings(table_fields),
                'parent': get_parent(directory),
                'items': get_children(directory),
            }
        })

    response = render(request, 'browser/overview.html', ctx)

    if new_mtime is not None:
        cookie_data[project.code] = new_mtime
        cookie_data = quote(json.dumps(cookie_data))
        response.set_cookie(ANN_COOKIE_NAME, cookie_data)

    return response
Example #42
0
 def decorated_f(request, path_obj, *args, **kwargs):
     request.permissions = get_matching_permissions(get_profile(request.user), path_obj.directory)
     if check_permission(permission_code, request):
         return f(request, path_obj, *args, **kwargs)
     else:
         raise PermissionDenied(_("You do not have rights to administer %s.", path_obj.fullname))
Example #43
0
 def has_admin_access(self):
     return check_permission('administrate', self.request)
Example #44
0
def test_submit_with_suggestion_and_comment(client, request_users, settings,
                                            system):
    """Tests translation can be applied after suggestion is accepted."""
    settings.POOTLE_CAPTCHA_ENABLED = False
    Comment = get_comment_model()
    unit = Unit.objects.filter(suggestion__state__name='pending',
                               state=UNTRANSLATED)[0]
    last_sub_pk = unit.submission_set.order_by("id").values_list(
        "id", flat=True).last() or 0
    sugg = Suggestion.objects.filter(unit=unit, state__name='pending')[0]
    user = request_users["user"]

    if user.username != "nobody":
        client.login(username=user.username,
                     password=request_users["password"])

    url = '/xhr/units/%d/' % unit.id
    edited_target = "Edited %s" % sugg.target_f
    comment = 'This is a comment!'
    qdict = QueryDict(mutable=True)
    qdict.update({
        'state': False,
        'target_f_0': edited_target,
        'suggestion': sugg.id,
        'comment': comment
    })
    qdict._mutable = False
    response = client.post(url, qdict, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
    suggestion = Suggestion.objects.get(id=sugg.id)
    unit = Unit.objects.get(id=unit.id)
    new_subs = unit.submission_set.filter(id__gt=last_sub_pk).order_by("id")
    if check_permission('translate', response.wsgi_request):
        assert response.status_code == 200
        content = json.loads(response.content)
        assert content['newtargets'] == [edited_target]
        assert content['user_score'] == response.wsgi_request.user.public_score
        assert content['checks'] is None
        unit_source = unit.unit_source
        assert unit_source.created_by == system
        assert unit_source.created_with == SubmissionTypes.SYSTEM
        assert unit.change.submitted_by == suggestion.user
        if user == suggestion.user:
            assert unit.change.reviewed_by is None
            assert unit.change.reviewed_on is None
        else:
            assert unit.change.reviewed_by == user
            assert unit.change.reviewed_on == unit.mtime
        assert unit.change.changed_with == SubmissionTypes.WEB

        assert suggestion.state.name == 'accepted'
        assert suggestion.is_accepted
        assert str(unit.target) == edited_target
        assert (Comment.objects.for_model(suggestion).get().comment == comment)
        assert new_subs.count() == 2
        target_sub = new_subs[0]
        assert target_sub.old_value == ""
        assert target_sub.new_value == unit.target
        assert target_sub.field == SubmissionFields.TARGET
        assert target_sub.type == SubmissionTypes.WEB
        assert target_sub.submitter == unit.change.submitted_by
        assert target_sub.suggestion == suggestion
        assert target_sub.revision == unit.revision
        assert target_sub.creation_time == unit.mtime

        state_sub = new_subs[1]
        assert state_sub.old_value == str(UNTRANSLATED)
        assert state_sub.new_value == str(unit.state)
        assert state_sub.suggestion == suggestion

        assert state_sub.field == SubmissionFields.STATE
        assert state_sub.type == SubmissionTypes.WEB

        assert state_sub.submitter == unit.change.submitted_by
        assert state_sub.revision == unit.revision
        assert state_sub.creation_time == unit.mtime
    else:
        assert response.status_code == 403
        assert suggestion.state.name == "pending"
        assert suggestion.is_pending
        assert unit.target == ""
        assert new_subs.count() == 0
        with pytest.raises(UnitChange.DoesNotExist):
            unit.change
Example #45
0
def upload_file(request, directory, django_file, overwrite, store=None):
    translation_project = request.translation_project
    relative_root_dir = directory.pootle_path[len(translation_project.
                                                  pootle_path):]
    # for some reason factory checks explicitly for file existance and
    # if file is open, which makes it difficult to work with Django's
    # in memory uploads.
    #
    # setting _closed to False should work around this
    #FIXME: hackish, does this have any undesirable side effect?
    if getattr(django_file, '_closed', None) is None:
        try:
            django_file._closed = False
        except AttributeError:
            pass
    # factory also checks for _mode
    if getattr(django_file, '_mode', None) is None:
        try:
            django_file._mode = 1
        except AttributeError:
            pass
    # mode is an attribute not a property in Django 1.1
    if getattr(django_file, 'mode', None) is None:
        django_file.mode = 1

    if store and store.file:
        # uploading to an existing file
        pootle_path = store.pootle_path
        upload_path = store.real_path
    elif store:
        # uploading to a virtual store
        pootle_path = store.pootle_path
        upload_path = get_upload_path(translation_project, relative_root_dir,
                                      store.name)
    else:
        local_filename = get_local_filename(translation_project,
                                            django_file.name)
        pootle_path = directory.pootle_path + local_filename
        # The full filesystem path to 'local_filename'
        upload_path = get_upload_path(translation_project, relative_root_dir,
                                      local_filename)
        try:
            store = translation_project.stores.get(pootle_path=pootle_path)
        except Store.DoesNotExist:
            store = None

    if (store is not None and overwrite == 'overwrite'
            and not check_permission('overwrite', request)):
        raise PermissionDenied(
            _("You do not have rights to overwrite "
              "files here."))

    if store is None and not check_permission('administrate', request):
        raise PermissionDenied(
            _("You do not have rights to upload new "
              "files here."))

    if overwrite == 'merge' and not check_permission('translate', request):
        raise PermissionDenied(
            _("You do not have rights to upload "
              "files here."))

    if overwrite == 'suggest' and not check_permission('suggest', request):
        raise PermissionDenied(
            _("You do not have rights to upload "
              "files here."))

    if store is None or (overwrite == 'overwrite' and store.file != ""):
        overwrite_file(request, relative_root_dir, django_file, upload_path)
        return

    if store.file and store.file.read() == django_file.read():
        logging.debug(u"identical file uploaded to %s, not merging",
                      store.pootle_path)
        return

    django_file.seek(0)
    from translate.storage import factory
    newstore = factory.getobject(django_file, classes=factory_classes)

    #FIXME: are we sure this is what we want to do? shouldn't we
    # diffrentiate between structure changing uploads and mere
    # pretranslate uploads?
    suggestions = overwrite == 'merge'
    notranslate = overwrite == 'suggest'
    allownewstrings = overwrite == 'overwrite' and store.file == ''

    store.mergefile(newstore,
                    get_profile(request.user),
                    suggestions=suggestions,
                    notranslate=notranslate,
                    allownewstrings=allownewstrings,
                    obsoletemissing=allownewstrings)
Example #46
0
def submit(request, unit):
    """Processes translation submissions and stores them in the database.

    :return: An object in JSON notation that contains the previous and last
             units for the unit next to unit ``uid``.
    """
    json = {}

    cantranslate = check_permission("translate", request)
    if not cantranslate:
        raise PermissionDenied(
            _("You do not have rights to access "
              "translation mode."))

    translation_project = request.translation_project
    language = translation_project.language

    if unit.hasplural():
        snplurals = len(unit.source.strings)
    else:
        snplurals = None

    # Store current time so that it is the same for all submissions
    current_time = timezone.now()

    # Update current unit instance's attributes
    unit.submitted_by = request.profile
    unit.submitted_on = current_time

    form_class = unit_form_factory(language, snplurals, request)
    form = form_class(request.POST, instance=unit)

    if form.is_valid():
        if form.updated_fields:
            for field, old_value, new_value in form.updated_fields:
                sub = Submission(
                    creation_time=current_time,
                    translation_project=translation_project,
                    submitter=request.profile,
                    unit=unit,
                    field=field,
                    type=SubmissionTypes.NORMAL,
                    old_value=old_value,
                    new_value=new_value,
                )
                sub.save()

            form.save()
            translation_submitted.send(
                sender=translation_project,
                unit=form.instance,
                profile=request.profile,
            )

        rcode = 200
    else:
        # Form failed
        #FIXME: we should display validation errors here
        rcode = 400
        json["msg"] = _("Failed to process submission.")
    response = jsonify(json)
    return HttpResponse(response, status=rcode, mimetype="application/json")
Example #47
0
    def GET(self,
            template_vars,
            request,
            translation_project,
            directory,
            store=None):
        can_edit = check_permission('administrate', request)

        project = translation_project.project
        language = translation_project.language

        path_obj = store or directory

        path_stats = get_raw_stats(path_obj, include_suggestions=True)
        path_summary = get_path_summary(path_obj, path_stats)
        actions = action_groups(request, path_obj, path_stats=path_stats)

        template_vars.update({
            'translation_project':
            translation_project,
            'project':
            project,
            'language':
            language,
            'directory':
            directory,
            'path_summary':
            path_summary,
            'stats':
            path_stats,
            'topstats':
            gentopstats_translation_project(translation_project),
            'feed_path':
            directory.pootle_path[1:],
            'action_groups':
            actions,
            'can_edit':
            can_edit,
        })

        if store is not None:
            template_vars.update({'store': store})
        else:
            table_fields = [
                'name', 'progress', 'total', 'need-translation', 'suggestions'
            ]
            template_vars.update({
                'table': {
                    'id': 'tp',
                    'proportional': True,
                    'fields': table_fields,
                    'headings': get_table_headings(table_fields),
                    'items': get_children(translation_project, directory),
                }
            })

        if can_edit:
            from pootle_translationproject.forms import DescriptionForm
            template_vars['form'] = DescriptionForm(
                instance=translation_project)

        return template_vars
Example #48
0
def unit_form_factory(language, snplurals=None, request=None):

    if snplurals is not None:
        tnplurals = language.nplurals
    else:
        tnplurals = 1

    action_disabled = False
    if request is not None:
        cantranslate = check_permission("translate", request)
        cansuggest = check_permission("suggest", request)

        if not (cansuggest or cantranslate):
            action_disabled = True

    target_attrs = {
        'lang': language.code,
        'dir': language.direction,
        'class': 'translation expanding focusthis js-translation-area',
        'rows': 2,
        'tabindex': 10,
    }

    fuzzy_attrs = {
        'accesskey': 'f',
        'class': 'fuzzycheck',
        'tabindex': 13,
    }

    if action_disabled:
        target_attrs['disabled'] = 'disabled'
        fuzzy_attrs['disabled'] = 'disabled'

    class UnitForm(forms.ModelForm):
        class Meta(object):
            model = Unit
            fields = ('target_f', 'state',)

        target_f = MultiStringFormField(
            nplurals=tnplurals,
            required=False,
            attrs=target_attrs,
        )
        state = UnitStateField(
            required=False,
            label=_('Needs work'),
            widget=forms.CheckboxInput(
                attrs=fuzzy_attrs,
                check_test=lambda x: x == FUZZY,
            ),
        )
        similarity = forms.FloatField(required=False)
        mt_similarity = forms.FloatField(required=False)
        suggestion = forms.ModelChoiceField(
            queryset=Suggestion.objects.all(),
            required=False)
        comment = forms.CharField(required=False)

        def __init__(self, *args, **kwargs):
            self.request = kwargs.pop('request', None)
            super(UnitForm, self).__init__(*args, **kwargs)
            self._updated_fields = []

            self.fields['target_f'].widget.attrs['data-translation-aid'] = \
                self['target_f'].value()

        @property
        def updated_fields(self):
            order_dict = {
                SubmissionFields.STATE: 0,
                SubmissionFields.TARGET: 1,
            }
            return sorted(self._updated_fields, key=lambda x: order_dict[x[0]])

        def clean_target_f(self):
            value = self.cleaned_data['target_f']

            if self.instance.target != multistring(value or [u'']):
                self.instance._target_updated = True
                self._updated_fields.append((SubmissionFields.TARGET,
                                            to_db(self.instance.target),
                                            to_db(value)))

            return value

        def clean_similarity(self):
            value = self.cleaned_data['similarity']

            if 0 <= value <= 1 or value is None:
                return value

            raise forms.ValidationError(
                _('Value of `similarity` should be in in the [0..1] range')
            )

        def clean_mt_similarity(self):
            value = self.cleaned_data['mt_similarity']

            if 0 <= value <= 1 or value is None:
                return value

            raise forms.ValidationError(
                _('Value of `mt_similarity` should be in in the [0..1] range')
            )

        def clean(self):
            old_state = self.instance.state  # Integer
            is_fuzzy = self.cleaned_data['state']  # Boolean
            new_target = self.cleaned_data['target_f']

            # If suggestion is provided set `old_state` should be `TRANSLATED`.
            if self.cleaned_data['suggestion']:
                old_state = TRANSLATED

                # Skip `TARGET` field submission if suggestion value is equal
                # to submitted translation
                if new_target == self.cleaned_data['suggestion'].target_f:
                    self._updated_fields = []

            if (self.request is not None and
                not check_permission('administrate', self.request) and
                is_fuzzy):
                self.add_error('state',
                               forms.ValidationError(
                                   _('Needs work flag must be '
                                     'cleared')))

            if new_target:
                if old_state == UNTRANSLATED:
                    self.instance._save_action = TRANSLATION_ADDED
                    self.instance.store.mark_dirty(
                        CachedMethods.WORDCOUNT_STATS)
                else:
                    self.instance._save_action = TRANSLATION_CHANGED

                if is_fuzzy:
                    new_state = FUZZY
                else:
                    new_state = TRANSLATED
            else:
                new_state = UNTRANSLATED
                if old_state > FUZZY:
                    self.instance._save_action = TRANSLATION_DELETED
                    self.instance.store.mark_dirty(
                        CachedMethods.WORDCOUNT_STATS)

            if is_fuzzy != (old_state == FUZZY):
                # when Unit toggles its FUZZY state the number of translated
                # words also changes
                self.instance.store.mark_dirty(CachedMethods.WORDCOUNT_STATS,
                                               CachedMethods.LAST_ACTION)

            if old_state not in [new_state, OBSOLETE]:
                self.instance._state_updated = True
                self._updated_fields.append((SubmissionFields.STATE,
                                            old_state, new_state))

                self.cleaned_data['state'] = new_state
            else:
                self.instance._state_updated = False
                self.cleaned_data['state'] = old_state

            return super(UnitForm, self).clean()

    return UnitForm
Example #49
0
 def must_display(cls, request, *args, **kwargs):
     return check_permission('commit', request) and \
         hasversioning(request.translation_project.abs_real_path)
Example #50
0
def project_language_index(request, project_code):
    """page listing all languages added to project"""
    project = get_object_or_404(Project, code=project_code)
    request.permissions = get_matching_permissions(get_profile(request.user),
                                                   project.directory)

    if not check_permission('view', request):
        raise PermissionDenied

    can_edit = check_permission('administrate', request)

    translation_projects = project.translationproject_set.all()

    items = [make_language_item(request, translation_project) \
            for translation_project in translation_projects.iterator()]
    items.sort(lambda x, y: locale.strcoll(x['title'], y['title']))

    languagecount = len(translation_projects)
    project_stats = get_raw_stats(project)
    average = project_stats['translated']['percentage']

    topstats = gentopstats_project(project)

    table_fields = [
        'name', 'progress', 'total', 'need-translation', 'activity'
    ]
    table = {
        'id': 'project',
        'proportional': False,
        'fields': table_fields,
        'headings': get_table_headings(table_fields),
        'items': items,
    }

    templatevars = {
        'project': {
            'code':
            project.code,
            'name':
            project.fullname,
            'description':
            project.description,
            'summary':
            ungettext('%(languages)d language, %(average)d%% translated',
                      '%(languages)d languages, %(average)d%% translated',
                      languagecount, {
                          "languages": languagecount,
                          "average": average
                      }),
        },
        'topstats': topstats,
        'can_edit': can_edit,
        'table': table,
    }

    if can_edit:
        from pootle_project.forms import DescriptionForm
        templatevars['form'] = DescriptionForm(instance=project)

    return render_to_response('project/project.html',
                              templatevars,
                              context_instance=RequestContext(request))
Example #51
0
def overview(request, translation_project, dir_path, filename=None):
    current_path = translation_project.directory.pootle_path + dir_path

    if filename:
        current_path = current_path + filename
        store = get_object_or_404(Store, pootle_path=current_path)
        directory = store.parent
        template_vars = {
            'store_tags': store.tags.all().order_by('name'),
        }
        template = "translation_project/store_overview.html"
    else:
        store = None
        directory = get_object_or_404(Directory, pootle_path=current_path)
        template_vars = {
            'tp_tags': translation_project.tags.all().order_by('name'),
        }
        template = "translation_project/overview.html"

    if (check_permission('translate', request)
            or check_permission('suggest', request)
            or check_permission('overwrite', request)):

        template_vars.update({
            'upload_form':
            _handle_upload_form(request, current_path, translation_project,
                                directory),
        })

    can_edit = check_permission('administrate', request)

    project = translation_project.project
    language = translation_project.language

    path_obj = store or directory

    latest_action = ''
    # If current directory is the TP root directory.
    if not directory.path:
        latest_action = translation_project.get_latest_submission()
    elif store is None:  # If this is not a file.
        latest_action = Submission.get_latest_for_dir(path_obj)

    path_stats = get_raw_stats(path_obj, include_suggestions=True)
    path_summary = get_path_summary(path_obj, path_stats, latest_action)
    actions = action_groups(request, path_obj, path_stats=path_stats)
    action_output = ''
    running = request.GET.get(EXTDIR, '')
    if running:
        if store:
            act = StoreAction
        else:
            act = TranslationProjectAction
        try:
            action = act.lookup(running)
        except KeyError:
            messages.error(request, _("Unable to find %s %s") % (act, running))
        else:
            if not getattr(action, 'nosync', False):
                (store or translation_project).sync()
            if action.is_active(request):
                vcs_dir = settings.VCS_DIRECTORY
                po_dir = settings.PODIRECTORY
                tp_dir = directory.get_real_path()
                store_fn = '*'
                if store:
                    tp_dir_slash = add_trailing_slash(tp_dir)
                    if store.file.name.startswith(tp_dir_slash):
                        # Note: store_f used below in reverse() call.
                        store_f = store.file.name[len(tp_dir_slash):]
                        store_fn = store_f.replace('/', os.sep)

                # Clear possibly stale output/error (even from other path_obj).
                action.set_output('')
                action.set_error('')
                try:
                    action.run(path=path_obj,
                               root=po_dir,
                               tpdir=tp_dir,
                               project=project.code,
                               language=language.code,
                               store=store_fn,
                               style=translation_project.file_style,
                               vc_root=vcs_dir)
                except StandardError:
                    err = (_("Exception while running '%s' extension action") %
                           action.title)
                    logging.exception(err)
                    if (action.error):
                        messages.error(request, action.error)
                    else:
                        messages.error(request, err)
                else:
                    if (action.error):
                        messages.warning(request, action.error)

                action_output = action.output
                if getattr(action, 'get_download', None):
                    export_path = action.get_download(path_obj)
                    if export_path:
                        response = HttpResponse('/export/' + export_path)
                        response['Content-Disposition'] = (
                            'attachment; filename="%s"' %
                            os.path.basename(export_path))
                        return response

                if not action_output:
                    if not store:
                        rev_args = [language.code, project.code, '']
                        overview_url = reverse('tp.overview', args=rev_args)
                    else:
                        slash = store_f.rfind('/')
                        store_d = ''
                        if slash > 0:
                            store_d = store_f[:slash]
                            store_f = store_f[slash + 1:]
                        elif slash == 0:
                            store_f = store_f[1:]
                        rev_args = [
                            language.code, project.code, store_d, store_f
                        ]
                        overview_url = reverse('tp.overview', args=rev_args)
                    return HttpResponseRedirect(overview_url)

    template_vars.update({
        'translation_project':
        translation_project,
        'project':
        project,
        'language':
        language,
        'path_obj':
        path_obj,
        'resource_path':
        request.resource_path,
        'path_summary':
        path_summary,
        'stats':
        path_stats,
        'topstats':
        gentopstats_translation_project(translation_project),
        'feed_path':
        directory.pootle_path[1:],
        'action_groups':
        actions,
        'action_output':
        action_output,
        'can_edit':
        can_edit,
    })

    if store is None:
        table_fields = [
            'name', 'progress', 'total', 'need-translation', 'suggestions'
        ]
        template_vars.update({
            'table': {
                'id': 'tp',
                'proportional': True,
                'fields': table_fields,
                'headings': get_table_headings(table_fields),
                'items': get_children(translation_project, directory),
            }
        })

    if can_edit:
        if store is None:
            url_kwargs = {
                'language_code': language.code,
                'project_code': project.code,
            }
            add_tag_action_url = reverse('tp.ajax_add_tag', kwargs=url_kwargs)
        else:
            add_tag_action_url = reverse('pootle-store-ajax-add-tag',
                                         args=[path_obj.pk])

        template_vars.update({
            'form':
            DescriptionForm(instance=translation_project),
            'add_tag_form':
            TagForm(),
            'add_tag_action_url':
            add_tag_action_url,
        })

    return render_to_response(template,
                              template_vars,
                              context_instance=RequestContext(request))
Example #52
0
def _test_browse_view(tp, request, response, kwargs):
    cookie_data = json.loads(
        unquote(response.cookies[SIDEBAR_COOKIE_NAME].value))
    assert cookie_data["foo"] == "bar"
    assert "announcements_projects_%s" % tp.project.code in cookie_data
    assert "announcements_%s" % tp.language.code in cookie_data
    assert (
        "announcements_%s_%s"
        % (tp.language.code, tp.project.code)
        in cookie_data)
    ctx = response.context
    kwargs["project_code"] = tp.project.code
    kwargs["language_code"] = tp.language.code
    resource_path = "%(dir_path)s%(filename)s" % kwargs
    pootle_path = "%s%s" % (tp.pootle_path, resource_path)

    if not (kwargs["dir_path"] or kwargs.get("filename")):
        ob = tp.directory
    elif not kwargs.get("filename"):
        ob = Directory.objects.get(
            pootle_path=pootle_path)
    else:
        ob = Store.objects.get(
            pootle_path=pootle_path)
    if not kwargs.get("filename"):
        vftis = ob.vf_treeitems.select_related("vfolder")
        if not ctx["has_admin_access"]:
            vftis = vftis.filter(vfolder__is_public=True)
        vfolders = [
            make_vfolder_treeitem_dict(vfolder_treeitem)
            for vfolder_treeitem
            in vftis.order_by('-vfolder__priority')
            if (ctx["has_admin_access"]
                or vfolder_treeitem.is_visible)]
        stats = {"vfolders": {}}
        for vfolder_treeitem in vfolders or []:
            stats['vfolders'][
                vfolder_treeitem['code']] = vfolder_treeitem["stats"]
            del vfolder_treeitem["stats"]
        if stats["vfolders"]:
            stats.update(ob.get_stats())
        else:
            stats = ob.get_stats()
    else:
        stats = ob.get_stats()
        vfolders = None

    filters = {}
    if vfolders:
        filters['sort'] = 'priority'

    dirs_with_vfolders = vftis_for_child_dirs(ob).values_list(
        "directory__pk", flat=True)
    directories = [
        make_directory_item(
            child,
            **(dict(sort="priority")
               if child.pk in dirs_with_vfolders
               else {}))
        for child in ob.get_children()
        if isinstance(child, Directory)]
    stores = [
        make_store_item(child)
        for child in ob.get_children()
        if isinstance(child, Store)]

    if not kwargs.get("filename"):
        table_fields = [
            'name', 'progress', 'total', 'need-translation',
            'suggestions', 'critical', 'last-updated', 'activity']
        table = {
            'id': 'tp',
            'fields': table_fields,
            'headings': get_table_headings(table_fields),
            'items': directories + stores}
    else:
        table = None

    User = get_user_model()
    assertions = dict(
        page="browse",
        object=ob,
        translation_project=tp,
        language=tp.language,
        project=tp.project,
        has_admin_access=check_permission('administrate', request),
        is_store=(kwargs.get("filename") and True or False),
        browser_extends="translation_projects/base.html",
        pootle_path=pootle_path,
        resource_path=resource_path,
        resource_path_parts=get_path_parts(resource_path),
        translation_states=get_translation_states(ob),
        checks=get_qualitycheck_list(ob),
        top_scorers=User.top_scorers(language=tp.language.code,
                                     project=tp.project.code, limit=10),
        url_action_continue=ob.get_translate_url(
            state='incomplete', **filters),
        url_action_fixcritical=ob.get_critical_url(**filters),
        url_action_review=ob.get_translate_url(
            state='suggestions', **filters),
        url_action_view_all=ob.get_translate_url(state='all'),
        stats=stats,
        parent=get_parent(ob))
    if table:
        assertions["table"] = table
    sidebar = get_sidebar_announcements_context(
        request, (tp.project, tp.language, tp))
    for k in ["has_sidebar", "is_sidebar_open", "announcements"]:
        assertions[k] = sidebar[0][k]
    view_context_test(ctx, **assertions)
    if vfolders:
        for vfolder in ctx["vfolders"]["items"]:
            assert (vfolder["is_grayed"] and not ctx["has_admin_access"]) is False
        assert (
            ctx["vfolders"]["items"]
            == vfolders)

    assert (('display_download' in ctx and ctx['display_download']) ==
            (request.user.is_authenticated()
             and check_permission('translate', request)))
Example #53
0
def translate_page(request, units_queryset, store=None):
    if not check_permission("view", request):
        raise PermissionDenied(
            _("You do not have rights to access this translation project."))

    cantranslate = check_permission("translate", request)
    cansuggest = check_permission("suggest", request)
    canreview = check_permission("review", request)
    translation_project = request.translation_project
    language = translation_project.language
    # shouldn't we globalize profile context
    profile = get_profile(request.user)

    step_queryset = None

    # Process search first
    search_form = None
    if 'search' in request.GET and 'sfields' in request.GET:
        search_form = SearchForm(request.GET)
        if search_form.is_valid():
            step_queryset = get_search_step_query(request.translation_project,
                                                  search_form, units_queryset)
    else:
        search_form = SearchForm()

    # which units are we interested in?
    if step_queryset is None:
        step_queryset = get_step_query(request, units_queryset)

    prev_unit, edit_unit, pager = get_current_units(request, step_queryset,
                                                    units_queryset)

    # time to process POST submission
    form = None
    if prev_unit is not None and ('submit' in request.POST
                                  or 'suggest' in request.POST):
        # check permissions
        if 'submit'  in request.POST and not cantranslate or \
           'suggest' in request.POST and not cansuggest:
            raise PermissionDenied

        form_class = unit_form_factory(language, len(prev_unit.source.strings))
        form = form_class(request.POST, instance=prev_unit)
        if form.is_valid():
            if cantranslate and 'submit' in request.POST:
                if form.instance._target_updated or form.instance._translator_comment_updated or \
                       form.instance._state_updated:
                    form.save()
                    sub = Submission(translation_project=translation_project,
                                     submitter=get_profile(request.user))
                    sub.save()

            elif cansuggest and 'suggest' in request.POST:
                if form.instance._target_updated:
                    #HACKISH: django 1.2 stupidly modifies instance on
                    # model form validation, reload unit from db
                    prev_unit = Unit.objects.get(id=prev_unit.id)
                    sugg = prev_unit.add_suggestion(
                        form.cleaned_data['target_f'],
                        get_profile(request.user))
                    if sugg:
                        SuggestionStat.objects.get_or_create(
                            translation_project=translation_project,
                            suggester=get_profile(request.user),
                            state='pending',
                            unit=prev_unit.id)
        else:
            # form failed, don't skip to next unit
            edit_unit = prev_unit

    if edit_unit is None:
        # no more units to step through, display end of translation message
        return translate_end(request, translation_project)

    # only create form for edit_unit if prev_unit was processed successfully
    if form is None or form.is_valid():
        form_class = unit_form_factory(language, len(edit_unit.source.strings))
        form = form_class(instance=edit_unit)

    if store is None:
        store = edit_unit.store
        pager_query = units_queryset
        preceding = (pager_query.filter(store=store, index__lt=edit_unit.index) | \
                     pager_query.filter(store__pootle_path__lt=store.pootle_path)).count()
        store_preceding = store.units.filter(index__lt=edit_unit.index).count()
    else:
        pager_query = store.units
        preceding = pager_query.filter(index__lt=edit_unit.index).count()
        store_preceding = preceding

    unit_rows = profile.get_unit_rows()

    # regardless of the query used to step through units, we will
    # display units in their original context, and display a pager for
    # the store not for the unit_step query
    if pager is None:
        page = preceding / unit_rows + 1
        pager = paginate(request, pager_query, items=unit_rows, page=page)

    # we always display the active unit in the middle of the page to
    # provide context for translators
    context_rows = (unit_rows - 1) / 2
    if store_preceding > context_rows:
        unit_position = store_preceding % unit_rows
        if unit_position < context_rows:
            # units too close to the top of the batch
            offset = unit_rows - (context_rows - unit_position)
            units_query = store.units[offset:]
            page = store_preceding / unit_rows
            units = paginate(request, units_query, items=unit_rows,
                             page=page).object_list
        elif unit_position >= unit_rows - context_rows:
            # units too close to the bottom of the batch
            offset = context_rows - (unit_rows - unit_position - 1)
            units_query = store.units[offset:]
            page = store_preceding / unit_rows + 1
            units = paginate(request, units_query, items=unit_rows,
                             page=page).object_list
        else:
            units = pager.object_list
    else:
        units = store.units[:unit_rows]

    # caluclate url querystring so state is retained on POST
    # we can't just use request URL cause unit and page GET vars cancel state
    GET_vars = []
    for key, values in request.GET.lists():
        if key not in ('page', 'unit'):
            for value in values:
                GET_vars.append('%s=%s' % (key, value))

    # links for quality check documentation
    checks = []
    for check in request.GET.get('matchnames', '').split(','):
        if not check:
            continue
        safe_check = escape(check)
        link = '<a href="http://translate.sourceforge.net/wiki/toolkit/pofilter_tests#%s" target="_blank">%s</a>' % (
            safe_check, safe_check)
        checks.append(_('checking %s', link))

    # precalculate alternative source languages
    alt_src_langs = get_alt_src_langs(request, profile, translation_project)
    alt_src_codes = alt_src_langs.values_list('code', flat=True)

    context = {
        'unit_rows': unit_rows,
        'alt_src_langs': alt_src_langs,
        'alt_src_codes': alt_src_codes,
        'cantranslate': cantranslate,
        'cansuggest': cansuggest,
        'canreview': canreview,
        'form': form,
        'search_form': search_form,
        'edit_unit': edit_unit,
        'store': store,
        'pager': pager,
        'units': units,
        'language': language,
        'translation_project': translation_project,
        'project': translation_project.project,
        'profile': profile,
        'source_language': translation_project.project.source_language,
        'directory': store.parent,
        'GET_state': '&'.join(GET_vars),
        'checks': checks,
        'MT_BACKENDS': settings.MT_BACKENDS,
    }
    return render_to_response('store/translate.html',
                              context,
                              context_instance=RequestContext(request))
Example #54
0
File: forms.py Project: notz/pootle
def unit_form_factory(language, snplurals=None, request=None):

    if snplurals is not None:
        tnplurals = language.nplurals
    else:
        tnplurals = 1

    action_disabled = False
    if request is not None:
        cantranslate = check_permission("translate", request)
        cansuggest = check_permission("suggest", request)

        if not (cansuggest or cantranslate):
            action_disabled = True

    target_attrs = {
        'lang': language.code,
        'dir': language.get_direction(),
        'class': 'translation expanding focusthis',
        'rows': 5,
        'tabindex': 10,
        }

    fuzzy_attrs = {
        'accesskey': 'f',
        'class': 'fuzzycheck',
        'tabindex': 13,
        }

    if action_disabled:
        target_attrs['disabled'] = 'disabled'
        fuzzy_attrs['disabled'] = 'disabled'

    class UnitForm(forms.ModelForm):
        class Meta:
            model = Unit
            exclude = ['store', 'developer_comment', 'translator_comment',
                       'submitted_by', 'commented_by']

        id = forms.IntegerField(required=False)
        source_f = MultiStringFormField(nplurals=snplurals or 1,
                                        required=False, textarea=False)
        target_f = MultiStringFormField(nplurals=tnplurals, required=False,
                                        attrs=target_attrs)
        state = forms.BooleanField(required=False, label=_('Fuzzy'),
                                   widget=forms.CheckboxInput(attrs=fuzzy_attrs,
                                       check_test=lambda x: x == FUZZY))

        def __init__(self, *args, **argv):
            super(UnitForm, self).__init__(*args, **argv)
            self.updated_fields = []

        def clean_source_f(self):
            value = self.cleaned_data['source_f']

            if self.instance.source.strings != value:
                self.instance._source_updated = True
                self.updated_fields.append((SubmissionFields.SOURCE,
                                            to_db(self.instance.source),
                                            to_db(value)))
            if snplurals == 1:
                # plural with single form, insert placeholder
                value.append(PLURAL_PLACEHOLDER)

            return value

        def clean_target_f(self):
            value = self.cleaned_data['target_f']

            if self.instance.target.strings != multistring(value or [u'']):
                self.instance._target_updated = True
                self.updated_fields.append((SubmissionFields.TARGET,
                                            to_db(self.instance.target),
                                            to_db(value)))

            return value

        def clean_state(self):
            old_state = self.instance.state    #integer
            value = self.cleaned_data['state'] #boolean
            new_target = self.cleaned_data['target_f']

            new_state = None
            if new_target:
                if value:
                    new_state = FUZZY
                else:
                    new_state = TRANSLATED
            else:
                new_state = UNTRANSLATED


            if old_state != new_state:
                self.instance._state_updated = True
                self.updated_fields.append((SubmissionFields.STATE,
                                            old_state, new_state))
            else:
                self.instance._state_updated = False

            return new_state


    return UnitForm
Example #55
0
def overview(request, translation_project, dir_path, filename=None, goal=None):
    from django.utils import dateformat
    from staticpages.models import StaticPage
    from pootle.scripts.actions import EXTDIR, StoreAction, TranslationProjectAction
    from .actions import action_groups

    if filename:
        ctx = {
            'store_tags': request.store.tag_like_objects,
        }
        template_name = "translation_projects/store_overview.html"
    else:
        ctx = {
            'tp_tags': translation_project.tag_like_objects,
        }
        template_name = "browser/overview.html"

    if (check_permission('translate', request) or
        check_permission('suggest', request) or
        check_permission('overwrite', request)):

        ctx.update({
            'upload_form': _handle_upload_form(request, translation_project),
        })

    can_edit = check_permission('administrate', request)

    project = translation_project.project
    language = translation_project.language

    resource_obj = request.store or request.directory

    #TODO enable again some actions when drilling down a goal.
    if goal is None:
        actions = action_groups(request, resource_obj)
    else:
        actions = []

    action_output = ''
    running = request.GET.get(EXTDIR, '')

    #TODO enable the following again when drilling down a goal.
    if running and goal is None:
        if request.store:
            act = StoreAction
        else:
            act = TranslationProjectAction
        try:
            action = act.lookup(running)
        except KeyError:
            messages.error(request, _("Unable to find '%(action)s' in '%(extdir)s'") %
                                      {'action': act, 'extdir': running})
        else:
            if not getattr(action, 'nosync', False):
                (request.store or translation_project).sync()
            if action.is_active(request):
                vcs_dir = settings.VCS_DIRECTORY
                po_dir = settings.PODIRECTORY
                tp_dir = request.directory.get_real_path()
                store_fn = '*'
                if request.store:
                    tp_dir_slash = add_trailing_slash(tp_dir)
                    if request.store.file.name.startswith(tp_dir_slash):
                        # Note: store_f used below in reverse() call.
                        store_f = request.store.file.name[len(tp_dir_slash):]
                        store_fn = store_f.replace('/', os.sep)

                # Clear possibly stale output/error (even from other
                # resource_obj).
                action.set_output('')
                action.set_error('')
                try:
                    action.run(path=resource_obj, root=po_dir, tpdir=tp_dir,
                               project=project.code, language=language.code,
                               store=store_fn,
                               style=translation_project.file_style,
                               vc_root=vcs_dir)
                except StandardError:
                    err = (_("Error while running '%s' extension action") %
                           action.title)
                    logging.exception(err)
                    if (action.error):
                        messages.error(request, action.error)
                    else:
                        messages.error(request, err)
                else:
                    if (action.error):
                        messages.warning(request, action.error)

                action_output = action.output
                if getattr(action, 'get_download', None):
                    export_path = action.get_download(resource_obj)
                    if export_path:
                        import mimetypes
                        abs_path = absolute_real_path(export_path)
                        filename = os.path.basename(export_path)
                        mimetype, encoding = mimetypes.guess_type(filename)
                        mimetype = mimetype or 'application/octet-stream'
                        with open(abs_path, 'rb') as f:
                            response = HttpResponse(f.read(),
                                                    mimetype=mimetype)
                        response['Content-Disposition'] = (
                                'attachment; filename="%s"' % filename)
                        return response

                if not action_output:
                    if not request.store:
                        rev_args = [language.code, project.code, '']
                        overview_url = reverse('pootle-tp-overview',
                                               args=rev_args)
                    else:
                        slash = store_f.rfind('/')
                        store_d = ''
                        if slash > 0:
                            store_d = store_f[:slash]
                            store_f = store_f[slash + 1:]
                        elif slash == 0:
                            store_f = store_f[1:]
                        rev_args = [language.code, project.code, store_d,
                                    store_f]
                        overview_url = reverse('pootle-tp-overview',
                                               args=rev_args)
                    return redirect(overview_url)

    # TODO: cleanup and refactor, retrieve from cache
    try:
        ann_virtual_path = 'announcements/' + project.code
        announcement = StaticPage.objects.live(request.user).get(
            virtual_path=ann_virtual_path,
        )
    except StaticPage.DoesNotExist:
        announcement = None

    display_announcement = True
    stored_mtime = None
    new_mtime = None
    cookie_data = {}

    if ANN_COOKIE_NAME in request.COOKIES:
        json_str = unquote(request.COOKIES[ANN_COOKIE_NAME])
        cookie_data = json.loads(json_str)

        if 'isOpen' in cookie_data:
            display_announcement = cookie_data['isOpen']

        if project.code in cookie_data:
            stored_mtime = cookie_data[project.code]

    if announcement is not None:
        ann_mtime = dateformat.format(announcement.modified_on, 'U')
        if ann_mtime != stored_mtime:
            display_announcement = True
            new_mtime = ann_mtime

    tp_goals = translation_project.all_goals

    ctx.update(get_overview_context(request))
    ctx.update({
        'resource_obj': request.store or request.directory,  # Dirty hack.
        'translation_project': translation_project,
        'description': translation_project.description,
        'project': project,
        'language': language,
        'tp_goals': tp_goals,
        'goal': goal,
        'feed_path': request.directory.pootle_path[1:],
        'action_groups': actions,
        'action_output': action_output,
        'can_edit': can_edit,

        'browser_extends': 'translation_projects/base.html',

        'announcement': announcement,
        'announcement_displayed': display_announcement,
    })

    tp_pootle_path = translation_project.pootle_path

    if request.store is None:
        table_fields = ['name', 'progress', 'total', 'need-translation',
                        'suggestions', 'critical', 'last-updated', 'activity']

        if goal is not None:
            # Then show the drill down view for the specified goal.
            continue_url = goal.get_translate_url_for_path(request.pootle_path,
                                                           state='incomplete')
            critical_url = goal.get_critical_url_for_path(request.pootle_path)
            review_url = goal.get_translate_url_for_path(request.pootle_path,
                                                         state='suggestions')
            all_url = goal.get_translate_url_for_path(request.pootle_path)

            ctx.update({
                'table': {
                    'id': 'tp-goals',
                    'fields': table_fields,
                    'headings': get_table_headings(table_fields),
                    'parent': get_goal_parent(request.directory, goal),
                    'items': get_goal_children(request.directory, goal),
                },
                'url_action_continue': continue_url,
                'url_action_fixcritical': critical_url,
                'url_action_review': review_url,
                'url_action_view_all': all_url,
            })
        else:
            # Then show the files tab.
            ctx.update({
                'table': {
                    'id': 'tp-files',
                    'fields': table_fields,
                    'headings': get_table_headings(table_fields),
                    'parent': get_parent(request.directory),
                    'items': get_children(request.directory),
                },
            })

    if can_edit:
        if request.store is None:
            add_tag_action_url = reverse('pootle-xhr-tag-tp',
                                         args=[language.code, project.code])
        else:
            add_tag_action_url = reverse('pootle-xhr-tag-store',
                                         args=[resource_obj.pk])

        ctx.update({
            'form': DescriptionForm(instance=translation_project),
            'form_action': reverse('pootle-tp-admin-settings',
                                   args=[language.code, project.code]),
            'add_tag_form': TagForm(),
            'add_tag_action_url': add_tag_action_url,
        })

        if goal is not None:
            ctx.update({
                'goal_form': GoalForm(instance=goal),
                'goal_form_action': reverse('pootle-xhr-edit-goal',
                                            args=[goal.slug]),
            })

    response = render(request, template_name, ctx)

    if new_mtime is not None:
        cookie_data[project.code] = new_mtime
        cookie_data = quote(json.dumps(cookie_data))
        response.set_cookie(ANN_COOKIE_NAME, cookie_data)

    return response
Example #56
0
def _test_browse_view(tp, request, response, kwargs):
    assert (request.user.is_anonymous or
            "announcements/projects/%s" % tp.project.code in request.session)
    assert (request.user.is_anonymous
            or "announcements/%s" % tp.language.code in request.session)
    assert (request.user.is_anonymous or "announcements/%s/%s" %
            (tp.language.code, tp.project.code) in request.session)
    ctx = response.context
    kwargs["project_code"] = tp.project.code
    kwargs["language_code"] = tp.language.code
    resource_path = "%(dir_path)s%(filename)s" % kwargs
    pootle_path = "%s%s" % (tp.pootle_path, resource_path)

    if not (kwargs["dir_path"] or kwargs.get("filename")):
        obj = tp.directory
    elif not kwargs.get("filename"):
        obj = Directory.objects.get(pootle_path=pootle_path)
    else:
        obj = Store.objects.get(pootle_path=pootle_path)
    if obj.tp_path == "/":
        data_obj = obj.tp
    else:
        data_obj = obj
    stats = StatsDisplay(
        data_obj, stats=data_obj.data_tool.get_stats(user=request.user)).stats
    if not kwargs.get("filename"):
        vfolders = True
    else:
        vfolders = None
    filters = {}
    if vfolders:
        filters['sort'] = 'priority'
    checks = ChecksDisplay(obj).checks_by_category
    del stats["children"]

    score_data = scores.get(tp.__class__)(tp)
    chunk_size = TOP_CONTRIBUTORS_CHUNK_SIZE
    top_scorers = score_data.top_scorers

    def scores_to_json(score):
        score["user"] = score["user"].to_dict()
        return score

    top_scorers = score_data.display(limit=chunk_size,
                                     formatter=scores_to_json)
    top_scorer_data = dict(
        items=list(top_scorers),
        has_more_items=len(score_data.top_scorers) > chunk_size)
    assertions = dict(
        page="browse",
        object=obj,
        translation_project=tp,
        language=tp.language,
        project=tp.project,
        has_admin_access=check_permission('administrate', request),
        is_store=(kwargs.get("filename") and True or False),
        browser_extends="translation_projects/base.html",
        pootle_path=pootle_path,
        resource_path=resource_path,
        resource_path_parts=get_path_parts(resource_path),
        translation_states=get_translation_states(obj),
        checks=checks,
        top_scorers=top_scorer_data,
        url_action_continue=obj.get_translate_url(state='incomplete',
                                                  **filters),
        url_action_fixcritical=obj.get_critical_url(**filters),
        url_action_review=obj.get_translate_url(state='suggestions',
                                                **filters),
        url_action_view_all=obj.get_translate_url(state='all'),
        stats=stats,
        parent=get_parent(obj))
    sidebar = get_sidebar_announcements_context(request,
                                                (tp.project, tp.language, tp))
    for k in ["has_sidebar", "is_sidebar_open", "announcements"]:
        assertions[k] = sidebar[k]
    view_context_test(ctx, **assertions)
    assert (('display_download' in ctx
             and ctx['display_download']) == (request.user.is_authenticated
                                              and check_permission(
                                                  'translate', request)))
Example #57
0
File: tp.py Project: lawlor/pootle
def _test_translate_view(tp, request, response, kwargs, settings):
    ctx = response.context
    obj = ctx["object"]
    kwargs["project_code"] = tp.project.code
    kwargs["language_code"] = tp.language.code
    resource_path = "%(dir_path)s%(filename)s" % kwargs
    request_path = "%s%s" % (tp.pootle_path, resource_path)

    checks = get_qualitychecks()
    schema = {sc["code"]: sc for sc in get_qualitycheck_schema()}
    check_data = obj.data_tool.get_checks()
    _checks = {}
    for check, checkid in checks.items():
        if check not in check_data:
            continue
        _checkid = schema[checkid]["name"]
        _checks[_checkid] = _checks.get(
            _checkid, dict(checks=[], title=schema[checkid]["title"]))
        _checks[_checkid]["checks"].append(
            dict(code=check, title=check_names[check],
                 count=check_data[check]))
    _checks = OrderedDict(
        (k, _checks[k]) for k in CATEGORY_IDS.keys() if _checks.get(k))
    if request.path.startswith("/++vfolder"):
        vfolder = VirtualFolder.objects.get(
            name=request.resolver_match.kwargs["vfolder_name"])
        current_vfolder_pk = vfolder.pk
        display_priority = False
        unit_api_root = reverse("vfolder-pootle-xhr-units",
                                kwargs=dict(vfolder_name=vfolder.name))
        resource_path = ("/".join([
            "++vfolder", vfolder.name,
            ctx['object'].pootle_path.replace(tp.pootle_path, "")
        ]))
    else:
        vfolder = None
        current_vfolder_pk = ""
        display_priority = False
        if not kwargs["filename"]:
            vf_view = vfolders_data_view.get(obj.__class__)(obj, request.user)
            display_priority = vf_view.has_data
        unit_api_root = "/xhr/units/"
    assertions = dict(page="translate",
                      translation_project=tp,
                      language=tp.language,
                      project=tp.project,
                      has_admin_access=check_permission(
                          'administrate', request),
                      ctx_path=tp.pootle_path,
                      pootle_path=request_path,
                      resource_path=resource_path,
                      resource_path_parts=get_path_parts(resource_path),
                      editor_extends="translation_projects/base.html",
                      checks=_checks,
                      previous_url=get_previous_url(request),
                      current_vfolder_pk=current_vfolder_pk,
                      display_priority=display_priority,
                      cantranslate=check_permission("translate", request),
                      cansuggest=check_permission("suggest", request),
                      canreview=check_permission("review", request),
                      search_form=make_search_form(request=request),
                      unit_api_root=unit_api_root,
                      POOTLE_MT_BACKENDS=settings.POOTLE_MT_BACKENDS,
                      AMAGAMA_URL=settings.AMAGAMA_URL)
    view_context_test(ctx, **assertions)
Example #58
0
def unit_form_factory(language, snplurals=None, request=None):

    if snplurals is not None:
        tnplurals = language.nplurals
    else:
        tnplurals = 1

    action_disabled = False
    if request is not None:
        cantranslate = check_permission("translate", request)
        cansuggest = check_permission("suggest", request)

        if not (cansuggest or cantranslate):
            action_disabled = True

    target_attrs = {
        'lang': language.code,
        'dir': language.direction,
        'class': 'translation expanding focusthis js-translation-area',
        'rows': 5,
        'tabindex': 10,
    }

    fuzzy_attrs = {
        'accesskey': 'f',
        'class': 'fuzzycheck',
        'tabindex': 13,
    }

    if action_disabled:
        target_attrs['disabled'] = 'disabled'
        fuzzy_attrs['disabled'] = 'disabled'

    class UnitForm(forms.ModelForm):
        class Meta:
            model = Unit
            exclude = ['store', 'developer_comment', 'translator_comment',
                       'submitted_by', 'commented_by']

        id = forms.IntegerField(required=False)
        source_f = MultiStringFormField(
            nplurals=snplurals or 1,
            required=False,
            textarea=False,
        )
        target_f = MultiStringFormField(
            nplurals=tnplurals,
            required=False,
            attrs=target_attrs,
        )
        state = UnitStateField(
            required=False,
            label=_('Needs work'),
            widget=forms.CheckboxInput(
                attrs=fuzzy_attrs,
                check_test=lambda x: x == FUZZY,
            ),
        )

        def __init__(self, *args, **argv):
            super(UnitForm, self).__init__(*args, **argv)
            self.updated_fields = []

        def clean_source_f(self):
            value = self.cleaned_data['source_f']

            if self.instance.source.strings != value:
                self.instance._source_updated = True
                self.updated_fields.append((SubmissionFields.SOURCE,
                                            to_db(self.instance.source),
                                            to_db(value)))
            if snplurals == 1:
                # Plural with single form, insert placeholder.
                value.append(PLURAL_PLACEHOLDER)

            return value

        def clean_target_f(self):
            value = self.cleaned_data['target_f']

            if self.instance.target.strings != multistring(value or [u'']):
                self.instance._target_updated = True
                self.updated_fields.append((SubmissionFields.TARGET,
                                            to_db(self.instance.target),
                                            to_db(value)))

            return value

        def clean_state(self):
            old_state = self.instance.state  # Integer
            is_fuzzy = self.cleaned_data['state']  # Boolean
            new_target = self.cleaned_data['target_f']

            if new_target:
                if old_state == UNTRANSLATED:
                    self.instance.store \
                                 .flag_for_deletion(CachedMethods.TRANSLATED)

                if is_fuzzy:
                    new_state = FUZZY
                else:
                    new_state = TRANSLATED
            else:
                new_state = UNTRANSLATED

            if is_fuzzy != (old_state == FUZZY):
                # when Unit toggles its FUZZY state the number of translated words
                # also changes
                self.instance.store.flag_for_deletion(CachedMethods.FUZZY,
                                                      CachedMethods.TRANSLATED,
                                                      CachedMethods.LAST_ACTION,
                                                      CachedMethods.PATH_SUMMARY)

            if old_state != new_state:
                self.instance._state_updated = True
                self.updated_fields.append((SubmissionFields.STATE,
                                            old_state, new_state))
            else:
                self.instance._state_updated = False

            return new_state


    return UnitForm
Example #59
0
def unit_form_factory(language, snplurals=None, request=None):

    if snplurals is not None:
        tnplurals = language.nplurals
    else:
        tnplurals = 1

    action_disabled = False
    if request is not None:
        cantranslate = check_permission("translate", request)
        cansuggest = check_permission("suggest", request)

        if not (cansuggest or cantranslate):
            action_disabled = True

    target_attrs = {
        'lang': language.code,
        'dir': language.direction,
        'class': 'translation expanding focusthis js-translation-area',
        'rows': 2,
        'tabindex': 10,
    }

    fuzzy_attrs = {
        'accesskey': 'f',
        'class': 'fuzzycheck',
        'tabindex': 13,
    }

    if action_disabled:
        target_attrs['disabled'] = 'disabled'
        fuzzy_attrs['disabled'] = 'disabled'

    class UnitForm(forms.ModelForm):
        class Meta(object):
            model = Unit
            fields = (
                'target_f',
                'state',
            )

        target_f = MultiStringFormField(
            nplurals=tnplurals,
            required=False,
            attrs=target_attrs,
        )
        state = UnitStateField(
            required=False,
            label=_('Needs work'),
            widget=forms.CheckboxInput(
                attrs=fuzzy_attrs,
                check_test=lambda x: x == FUZZY,
            ),
        )
        suggestion = forms.ModelChoiceField(queryset=Suggestion.objects.all(),
                                            required=False)
        comment = forms.CharField(required=False)

        def __init__(self, *args, **kwargs):
            self.request = kwargs.pop('request', None)
            self.user = self.request.user
            super(UnitForm, self).__init__(*args, **kwargs)
            self._updated_fields = []
            self.fields['target_f'].widget.attrs['data-translation-aid'] = \
                self['target_f'].value()

        @property
        def updated_fields(self):
            order_dict = {
                SubmissionFields.STATE: 0,
                SubmissionFields.TARGET: 1,
            }
            return sorted(self._updated_fields, key=lambda x: order_dict[x[0]])

        def clean_target_f(self):
            value = self.cleaned_data['target_f']

            if self.instance.target != multistring(value or [u'']):
                self._updated_fields.append(
                    (SubmissionFields.TARGET, to_db(self.instance.target),
                     to_db(value)))

            return value

        def clean(self):
            old_state = self.instance.state  # Integer
            is_fuzzy = self.cleaned_data['state']  # Boolean
            new_target = self.cleaned_data['target_f']

            # If suggestion is provided set `old_state` should be `TRANSLATED`.
            if self.cleaned_data['suggestion']:
                old_state = TRANSLATED

                # Skip `TARGET` field submission if suggestion value is equal
                # to submitted translation
                if new_target == self.cleaned_data['suggestion'].target_f:
                    self._updated_fields = []

            if (self.request is not None
                    and not check_permission('administrate', self.request)
                    and is_fuzzy):
                self.add_error(
                    'state',
                    forms.ValidationError(
                        _('Needs work flag must be '
                          'cleared')))

            if new_target:
                if is_fuzzy:
                    new_state = FUZZY
                else:
                    new_state = TRANSLATED
            else:
                new_state = UNTRANSLATED
            if old_state not in [new_state, OBSOLETE]:
                self._updated_fields.append(
                    (SubmissionFields.STATE, old_state, new_state))

                self.cleaned_data['state'] = new_state
            else:
                self.cleaned_data['state'] = old_state

            return super(UnitForm, self).clean()

        def save(self, *args, **kwargs):
            changed_with = kwargs.pop("changed_with", None)
            kwargs["commit"] = False
            unit = super(UnitForm, self).save(*args, **kwargs)
            with update_data_after(unit.store):
                current_time = timezone.now()
                if SubmissionFields.TARGET in (f[0]
                                               for f in self.updated_fields):
                    unit.submitted_by = self.user
                    unit.submitted_on = current_time
                    unit.reviewed_by = None
                    unit.reviewed_on = None
                suggestion = self.cleaned_data["suggestion"]
                user = (suggestion.user if suggestion else self.user)
                unit.save(submitted_on=current_time,
                          submitted_by=user,
                          changed_with=changed_with)
                translation_project = unit.store.translation_project
                for field, old_value, new_value in self.updated_fields:
                    if field == SubmissionFields.TARGET and suggestion:
                        old_value = str(suggestion.target_f)
                    sub = Submission(creation_time=current_time,
                                     translation_project=translation_project,
                                     submitter=self.user,
                                     unit=unit,
                                     store=unit.store,
                                     field=field,
                                     type=SubmissionTypes.NORMAL,
                                     old_value=old_value,
                                     new_value=new_value)
                    sub.save()
            return unit

    return UnitForm