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 # Update current unit instance's attributes unit.submitted_by = request.profile unit.submitted_on = datetime.utcnow() form_class = unit_form_factory(language, snplurals, request) form = form_class(request.POST, instance=unit) if form.is_valid(): if form.updated_fields: # Store creation time so that it is the same for all submissions creation_time=datetime.utcnow() for field, old_value, new_value in form.updated_fields: sub = Submission( creation_time=creation_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")
def get_edit_unit(request, unit): """ Given a store path C{pootle_path} and unit id C{uid}, gathers all the necessary information to build the editing widget. @return: A templatised editing widget is returned within the C{editor} variable and paging information is also returned if the page number has changed. """ json = {} 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) form = form_class(instance=unit) store = unit.store directory = store.parent profile = request.profile alt_src_langs = get_alt_src_langs(request, profile, translation_project) project = translation_project.project suggestions, suggestion_details = get_sugg_list(unit) template_vars = {'unit': unit, 'form': form, 'store': store, 'directory': directory, 'profile': profile, 'user': request.user, 'language': language, 'source_language': translation_project.project.source_language, 'cantranslate': check_profile_permission(profile, "translate", directory), 'cansuggest': check_profile_permission(profile, "suggest", directory), 'canreview': check_profile_permission(profile, "review", directory), 'altsrcs': find_altsrcs(unit, alt_src_langs, store=store, project=project), 'suggestions': suggestions, 'suggestion_detail': suggestion_details, } if translation_project.project.is_terminology or store.is_terminology: t = loader.get_template('unit/term_edit.html') else: t = loader.get_template('unit/edit.html') c = RequestContext(request, template_vars) json['editor'] = t.render(c) t = loader.get_template('store/dircrumbs.html') json['dircrumbs'] = t.render(c) t = loader.get_template('store/storecrumbs.html') json['storecrumbs'] = t.render(c) rcode = 200 # Return context rows if filtering is applied if _is_filtered(request) or request.GET.get('filter', 'all') != 'all': json['ctxt'] = _filter_ctxt_units(store.units, unit, 2) response = jsonify(json) return HttpResponse(response, status=rcode, mimetype="application/json")
def get_edit_unit(request, pootle_path, uid): """ Given a store path C{pootle_path} and unit id C{uid}, gathers all the necessary information to build the editing widget. @return: A templatised editing widget is returned within the C{editor} variable and paging information is also returned if the page number has changed. """ if pootle_path[0] != '/': pootle_path = '/' + pootle_path unit = get_object_or_404(Unit, id=uid, store__pootle_path=pootle_path) translation_project = unit.store.translation_project language = translation_project.language form_class = unit_form_factory(language, len(unit.source.strings)) form = form_class(instance=unit) store = unit.store directory = store.parent profile = get_profile(request.user) alt_src_langs = get_alt_src_langs(request, profile, translation_project) project = translation_project.project template_vars = {'unit': unit, 'form': form, 'store': store, 'profile': profile, 'user': request.user, 'language': language, 'source_language': translation_project.project.source_language, 'cantranslate': check_profile_permission(profile, "translate", directory), 'cansuggest': check_profile_permission(profile, "suggest", directory), 'canreview': check_profile_permission(profile, "review", directory), 'altsrcs': find_altsrcs(unit, alt_src_langs, store=store, project=project), 'suggestions': get_sugg_list(unit)} t = loader.get_template('unit/edit.html') c = RequestContext(request, template_vars) json = {'success': True, 'editor': t.render(c)} current_page = int(request.GET.get('page', 1)) all_units = unit.store.units units_qs = _filter_queryset(request.GET, all_units) unit_rows = profile.get_unit_rows() current_unit = unit if current_unit is not None: current_index = _get_index_in_qs(units_qs, current_unit) preceding = units_qs[:current_index].count() page = preceding / unit_rows + 1 if page != current_page: pager = paginate(request, units_qs, items=unit_rows, page=page) json["pager"] = _build_pager_dict(pager) # Return context rows if filtering is applied if 'filter' in request.GET and request.GET.get('filter', 'all') != 'all': edit_index = _get_index_in_qs(all_units, current_unit) json["ctxt"] = _filter_ctxt_units(all_units, edit_index, 2) response = simplejson.dumps(json) return HttpResponse(response, mimetype="application/json")
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")
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")
def manage_store(request, template_vars, language, term_store): from django import forms from pootle_store.forms import unit_form_factory unit_form_class = unit_form_factory(language) # XXX: Review this # HACKISH: Django won't allow excluding form fields already defined in # the parent class, manually extra fields. del (unit_form_class.base_fields['target_f']) del (unit_form_class.base_fields['id']) del (unit_form_class.base_fields['state']) del (unit_form_class.declared_fields['target_f']) del (unit_form_class.declared_fields['id']) del (unit_form_class.declared_fields['state']) class TermUnitForm(unit_form_class): # Set store for new terms qs = Store.objects.filter(pk=term_store.pk) store = forms.ModelChoiceField(queryset=qs, initial=term_store.pk, widget=forms.HiddenInput) index = forms.IntegerField(required=False, widget=forms.HiddenInput) def clean_index(self): # Assign new terms an index value value = self.cleaned_data['index'] if self.instance.id is None: value = term_store.max_index() + 1 return value def clean_source_f(self): value = super(TermUnitForm, self).clean_source_f() if value: existing = term_store.findid(value[0]) if existing and existing.id != self.instance.id: raise forms.ValidationError( _('This term already exists ' 'in this file.')) self.instance.setid(value[0]) return value return util.edit(request, 'terminology/manage.html', Unit, template_vars, None, None, queryset=term_store.units, can_delete=True, form=TermUnitForm, exclude=['state', 'target_f', 'id', 'translator_comment'])
def manage(request, translation_project): template_vars = { "translation_project": translation_project, "language": translation_project.language, "project": translation_project.project, "source_language": translation_project.project.source_language, "directory": translation_project.directory, 'formid': 'terminology-manage', 'submitname': 'changeterminology', } try: terminology_filename = get_terminology_filename(translation_project) term_store = Store.objects.get(pootle_path=translation_project.pootle_path + terminology_filename) template_vars['store'] = term_store #HACKISH: Django won't allow excluding form fields already defined in parent class, manually extra fields. unit_form_class = unit_form_factory(translation_project.language, 1) del(unit_form_class.base_fields['target_f']) del(unit_form_class.base_fields['id']) del(unit_form_class.base_fields['translator_comment']) del(unit_form_class.base_fields['state']) del(unit_form_class.declared_fields['target_f']) del(unit_form_class.declared_fields['id']) del(unit_form_class.declared_fields['translator_comment']) del(unit_form_class.declared_fields['state']) class TermUnitForm(unit_form_class): # set store for new terms store = forms.ModelChoiceField(queryset=Store.objects.filter(pk=term_store.pk), initial=term_store.pk, widget=forms.HiddenInput) index = forms.IntegerField(required=False, widget=forms.HiddenInput) def clean_index(self): # assign new terms an index value value = self.cleaned_data['index'] if self.instance.id is None: value = term_store.max_index() + 1 return value def clean_source_f(self): value = super(TermUnitForm, self).clean_source_f() if value: existing = term_store.findid(value[0]) if existing and existing.id != self.instance.id: raise forms.ValidationError(_('Please correct the error below.')) self.instance.setid(value[0]) return value return util.edit(request, 'terminology/manage.html', Unit, template_vars, None, None, queryset=term_store.units, can_delete=True, form=TermUnitForm, exclude=['state', 'target_f', 'id', 'translator_comment']) except Store.DoesNotExist: return render_to_response("terminology/manage.html", template_vars, context_instance=RequestContext(request))
def manage_store(request, ctx, language, term_store): from django import forms from pootle_store.forms import unit_form_factory unit_form_class = unit_form_factory(language) # XXX: Review this # HACKISH: Django won't allow excluding form fields already defined in # the parent class, manually extra fields. del(unit_form_class.base_fields['target_f']) del(unit_form_class.base_fields['id']) del(unit_form_class.base_fields['state']) del(unit_form_class.declared_fields['target_f']) del(unit_form_class.declared_fields['id']) del(unit_form_class.declared_fields['state']) class TermUnitForm(unit_form_class): # Set store for new terms. qs = Store.objects.filter(pk=term_store.pk) store = forms.ModelChoiceField(queryset=qs, initial=term_store.pk, widget=forms.HiddenInput) index = forms.IntegerField(required=False, widget=forms.HiddenInput) def clean_index(self): # Assign new terms an index value. value = self.cleaned_data['index'] if self.instance.id is None: value = term_store.max_index() + 1 return value def clean_source_f(self): value = super(TermUnitForm, self).clean_source_f() if value: existing = term_store.findid(value[0]) if existing and existing.id != self.instance.id: raise forms.ValidationError(_('This term already exists ' 'in this file.')) self.instance.setid(value[0]) return value #TODO 'submitted_by' and 'commented_by' had to be excluded in order to get # terminology editing working. When the schema can be changed again this # exclusion should be removed and change the schema accordingly. excluded_fields = ['state', 'target_f', 'id', 'translator_comment', 'submitted_by', 'commented_by'] template_name = 'translation_projects/terminology/manage.html' return util.edit(request, template_name, Unit, ctx, None, None, queryset=term_store.units, can_delete=True, form=TermUnitForm, exclude=excluded_fields)
def manage(request, translation_project): template_vars = { "translation_project": translation_project, "language": translation_project.language, "project": translation_project.project, "source_language": translation_project.project.source_language, "directory": translation_project.directory, 'formid': 'terminology-manage', 'submitname': 'changeterminology' } try: term_store = Store.objects.get(pootle_path=translation_project.pootle_path + 'pootle-terminology.po') template_vars['store'] = term_store #HACKISH: Django won't allow excluding form fields already defined in parent class, manually extra fields. unit_form_class = unit_form_factory(translation_project.language, 1) del(unit_form_class.base_fields['target_f']) del(unit_form_class.base_fields['id']) del(unit_form_class.base_fields['translator_comment']) del(unit_form_class.base_fields['state']) del(unit_form_class.declared_fields['target_f']) del(unit_form_class.declared_fields['id']) del(unit_form_class.declared_fields['translator_comment']) del(unit_form_class.declared_fields['state']) class TermUnitForm(unit_form_class): # set store for new terms store = forms.ModelChoiceField(queryset=Store.objects.filter(pk=term_store.pk), initial=term_store.pk, widget=forms.HiddenInput) index = forms.IntegerField(required=False, widget=forms.HiddenInput) def clean_index(self): # assign new terms an index value value = self.cleaned_data['index'] if self.instance.id is None: value = term_store.max_index() + 1 return value def clean_source_f(self): value = super(TermUnitForm, self).clean_source_f() if value: existing = term_store.findid(value[0]) if existing and existing.id != self.instance.id: raise forms.ValidationError(_('Please correct the error below.')) self.instance.setid(value[0]) return value return util.edit(request, 'terminology/manage.html', Unit, template_vars, None, None, queryset=term_store.units, can_delete=True, form=TermUnitForm, exclude=['state', 'target_f', 'id', 'translator_comment']) except Store.DoesNotExist: return render_to_response("terminology/manage.html", template_vars, context_instance=RequestContext(request))
def manage_store(request, template_vars, language, term_store): from django import forms from pootle_store.forms import unit_form_factory unit_form_class = unit_form_factory(language) # XXX: Review this # HACKISH: Django won't allow excluding form fields already defined in # the parent class, manually extra fields. del(unit_form_class.base_fields['target_f']) del(unit_form_class.base_fields['id']) del(unit_form_class.base_fields['state']) del(unit_form_class.declared_fields['target_f']) del(unit_form_class.declared_fields['id']) del(unit_form_class.declared_fields['state']) class TermUnitForm(unit_form_class): # Set store for new terms qs = Store.objects.filter(pk=term_store.pk) store = forms.ModelChoiceField(queryset=qs, initial=term_store.pk, widget=forms.HiddenInput) index = forms.IntegerField(required=False, widget=forms.HiddenInput) def clean_index(self): # Assign new terms an index value value = self.cleaned_data['index'] if self.instance.id is None: value = term_store.max_index() + 1 return value def clean_source_f(self): value = super(TermUnitForm, self).clean_source_f() if value: existing = term_store.findid(value[0]) if existing and existing.id != self.instance.id: raise forms.ValidationError(_('This term already exists ' 'in this file.')) self.instance.setid(value[0]) return value return util.edit(request, 'terminology/manage.html', Unit, template_vars, None, None, queryset=term_store.units, can_delete=True, form=TermUnitForm, exclude=['state', 'target_f', 'id', 'translator_comment'])
def suggest(request, unit): """Processes translation 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 ``uid``. """ json = {} cansuggest = check_permission("suggest", request) if 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 form.instance._target_updated: # TODO: Review if this hackish method is still necessary #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 suggestion.") response = jsonify(json) return HttpResponse(response, status=rcode, mimetype="application/json")
def get_edit_unit(request, unit): """Given a store path ``pootle_path`` and unit id ``uid``, gathers all the necessary information to build the editing widget. :return: A templatised editing widget is returned within the ``editor`` variable and paging information is also returned if the page number has changed. """ json = {} 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(instance=unit) comment_form_class = unit_comment_form_factory(language) comment_form = comment_form_class({}, instance=unit) store = unit.store directory = store.parent profile = request.profile alt_src_langs = get_alt_src_langs(request, profile, translation_project) project = translation_project.project report_target = ensure_uri(project.report_target) suggestions = get_sugg_list(unit) template_vars = { 'unit': unit, 'form': form, 'comment_form': comment_form, 'store': store, 'directory': directory, 'profile': profile, 'user': request.user, 'language': language, 'source_language': translation_project.project.source_language, 'cantranslate': check_profile_permission(profile, "translate", directory), 'cansuggest': check_profile_permission(profile, "suggest", directory), 'canreview': check_profile_permission(profile, "review", directory), 'altsrcs': find_altsrcs(unit, alt_src_langs, store=store, project=project), 'report_target': report_target, 'suggestions': suggestions, } if translation_project.project.is_terminology or store.is_terminology: t = loader.get_template('unit/term_edit.html') else: t = loader.get_template('unit/edit.html') c = RequestContext(request, template_vars) json['editor'] = t.render(c) rcode = 200 # Return context rows if filtering is applied but # don't return any if the user has asked not to have it current_filter = request.GET.get('filter', 'all') show_ctx = request.COOKIES.get('ctxShow', 'true') if ((_is_filtered(request) or current_filter not in ('all', )) and show_ctx == 'true'): # TODO: review if this first 'if' branch makes sense if translation_project.project.is_terminology or store.is_terminology: json['ctx'] = _filter_ctx_units(store.units, unit, 0) else: ctx_qty = int(request.COOKIES.get('ctxQty', 1)) json['ctx'] = _filter_ctx_units(store.units, unit, ctx_qty) response = jsonify(json) return HttpResponse(response, status=rcode, mimetype="application/json")
def get_edit_unit(request, unit): """ Given a store path C{pootle_path} and unit id C{uid}, gathers all the necessary information to build the editing widget. @return: A templatised editing widget is returned within the C{editor} variable and paging information is also returned if the page number has changed. """ json = {} 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(instance=unit) store = unit.store directory = store.parent profile = request.profile alt_src_langs = get_alt_src_langs(request, profile, translation_project) project = translation_project.project report_target = ensure_uri(project.report_target) suggestions, suggestion_details = get_sugg_list(unit) template_vars = { 'unit': unit, 'form': form, 'store': store, 'directory': directory, 'profile': profile, 'user': request.user, 'language': language, 'source_language': translation_project.project.source_language, 'cantranslate': check_profile_permission(profile, "translate", directory), 'cansuggest': check_profile_permission(profile, "suggest", directory), 'canreview': check_profile_permission(profile, "review", directory), 'altsrcs': find_altsrcs(unit, alt_src_langs, store=store, project=project), 'report_target': report_target, 'suggestions': suggestions, 'suggestion_detail': suggestion_details, } if translation_project.project.is_terminology or store.is_terminology: t = loader.get_template('unit/term_edit.html') else: t = loader.get_template('unit/edit.html') c = RequestContext(request, template_vars) json['editor'] = t.render(c) t = loader.get_template('store/dircrumbs.html') json['dircrumbs'] = t.render(c) t = loader.get_template('store/storecrumbs.html') json['storecrumbs'] = t.render(c) rcode = 200 # Return context rows if filtering is applied if _is_filtered(request) or request.GET.get('filter', 'all') != 'all': if translation_project.project.is_terminology or store.is_terminology: json['ctxt'] = _filter_ctxt_units(store.units, unit, 0) else: json['ctxt'] = _filter_ctxt_units(store.units, unit, 2) response = jsonify(json) return HttpResponse(response, status=rcode, mimetype="application/json")
def _create_unit_form(request, language, unit): """Convenience function to create unit forms.""" form_class = unit_form_factory(language, request=request) return form_class(request.POST, instance=unit, request=request)
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 ``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 import copy old_unit = copy.copy(unit) form_class = unit_form_factory(language, snplurals, request) form = form_class(request.POST, instance=unit) if form.is_valid(): if type == 'submission' and form.updated_fields: # Store creation time so that it is the same for all submissions: creation_time=datetime.utcnow() for field, old_value, new_value in form.updated_fields: sub = Submission( creation_time=creation_time, translation_project=translation_project, submitter=request.profile, unit=unit, field=field, type=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, ) 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")
def process_submit(request, pootle_path, uid, type): """ @return: An object in JSON notation that contains the previous and last units for the unit next to unit C{uid}. This object also contains success status that indicates if the submission has been succesfully saved or not. """ json = {} if pootle_path[0] != '/': pootle_path = '/' + pootle_path try: unit = Unit.objects.get(id=uid, store__pootle_path=pootle_path) directory = unit.store.parent profile = get_profile(request.user) cantranslate = check_profile_permission(profile, "translate", directory) cansuggest = check_profile_permission(profile, "suggest", directory) if type == 'submission' and not cantranslate or \ type == 'suggestion' and not cansuggest: json["success"] = False json["msg"] = _( "You do not have rights to access translation mode.") else: translation_project = unit.store.translation_project language = translation_project.language form_class = unit_form_factory(language, len(unit.source.strings)) 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() sub = Submission( translation_project=translation_project, submitter=get_profile(request.user)) 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'], get_profile(request.user)) if sugg: SuggestionStat.objects.get_or_create( translation_project=translation_project, suggester=get_profile(request.user), state='pending', unit=unit.id) current_page = int(request.POST.get('page', 1)) all_units = unit.store.units units_qs = _filter_queryset(request.POST, all_units) unit_rows = profile.get_unit_rows() current_unit = unit if current_unit is not None: current_index = _get_index_in_qs(units_qs, current_unit) preceding = units_qs[:current_index].count() page = preceding / unit_rows + 1 if page != current_page: pager = paginate(request, units_qs, items=unit_rows, page=page) json["pager"] = _build_pager_dict(pager) try: new_index = current_index + 1 json["new_uid"] = units_qs[new_index].id except IndexError: # End of set: let's assume the new unit is the last we had new_unit = unit json["new_uid"] = None json["success"] = True else: # Form failed json["success"] = False json["msg"] = _("Failed to process submit.") except Store.DoesNotExist: json["success"] = False json["msg"] = _("Store %(path)s does not exist." % {'path': pootle_path}) except Unit.DoesNotExist: json["success"] = False json["msg"] = _("Unit %(uid)s does not exist on %(path)s." % { 'uid': uid, 'path': pootle_path }) response = simplejson.dumps(json) return HttpResponse(response, mimetype="application/json")
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 # Update current unit instance's attributes unit.submitted_by = request.profile unit.submitted_on = timezone.now() form_class = unit_form_factory(language, snplurals, request) form = form_class(request.POST, instance=unit) if form.is_valid(): if form.updated_fields: # Store creation time so that it is the same for all submissions creation_time = timezone.now() for field, old_value, new_value in form.updated_fields: sub = Submission( creation_time=creation_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")
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 if prev_unit.hasplural(): snplurals = len(prev_unit.source.strings) else: snplurals = None form_class = unit_form_factory(language, snplurals) 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() translation_submitted.send(sender=translation_project, unit=form.instance, profile=profile) 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(): if edit_unit.hasplural(): snplurals = len(edit_unit.source.strings) else: snplurals = None form_class = unit_form_factory(language, snplurals) 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, orphans=0) # 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 page_length = pager.end_index() - pager.start_index() + 1 if page_length < unit_rows: if pager.has_other_pages(): units_query = store.units[page_length:] else: units_query = store.units page = store_preceding / unit_rows units = paginate(request, units_query, items=unit_rows, page=page, orphans=0).object_list elif 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, orphans=0).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, orphans=0).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))
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: # (jgonzale|2014-09-05|INTL-591): log unsolicited modification to the source field if field == SubmissionFields.SOURCE: logging.warning( u'Corrupted submission for (unit_id, {0}) - ' \ u'(submitter, {1}) ' \ u'(source_old_value, {2}) ' \ u'(request info - {3})'.format(unit.id, request.profile, old_value, repr(request)) ) 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")
def get_edit_unit(request, pootle_path, uid): """ Given a store path C{pootle_path} and unit id C{uid}, gathers all the necessary information to build the editing widget. @return: A templatised editing widget is returned within the C{editor} variable and paging information is also returned if the page number has changed. """ if pootle_path[0] != '/': pootle_path = '/' + pootle_path unit = get_object_or_404(Unit, id=uid, store__pootle_path=pootle_path) translation_project = unit.store.translation_project language = translation_project.language form_class = unit_form_factory(language, len(unit.source.strings)) form = form_class(instance=unit) store = unit.store directory = store.parent profile = get_profile(request.user) alt_src_langs = get_alt_src_langs(request, profile, translation_project) project = translation_project.project template_vars = { 'unit': unit, 'form': form, 'store': store, 'profile': profile, 'user': request.user, 'language': language, 'source_language': translation_project.project.source_language, 'cantranslate': check_profile_permission(profile, "translate", directory), 'cansuggest': check_profile_permission(profile, "suggest", directory), 'canreview': check_profile_permission(profile, "review", directory), 'altsrcs': find_altsrcs(unit, alt_src_langs, store=store, project=project), 'suggestions': get_sugg_list(unit) } t = loader.get_template('unit/edit.html') c = RequestContext(request, template_vars) json = {'success': True, 'editor': t.render(c)} current_page = int(request.GET.get('page', 1)) all_units = unit.store.units units_qs = _filter_queryset(request.GET, all_units) unit_rows = profile.get_unit_rows() current_unit = unit if current_unit is not None: current_index = _get_index_in_qs(units_qs, current_unit) preceding = units_qs[:current_index].count() page = preceding / unit_rows + 1 if page != current_page: pager = paginate(request, units_qs, items=unit_rows, page=page) json["pager"] = _build_pager_dict(pager) # Return context rows if filtering is applied if 'filter' in request.GET and request.GET.get('filter', 'all') != 'all': edit_index = _get_index_in_qs(all_units, current_unit) json["ctxt"] = _filter_ctxt_units(all_units, edit_index, 2) response = simplejson.dumps(json) return HttpResponse(response, mimetype="application/json")
def process_submit(request, pootle_path, uid, type): """ @return: An object in JSON notation that contains the previous and last units for the unit next to unit C{uid}. This object also contains success status that indicates if the submission has been succesfully saved or not. """ json = {} if pootle_path[0] != '/': pootle_path = '/' + pootle_path try: unit = Unit.objects.get(id=uid, store__pootle_path=pootle_path) directory = unit.store.parent profile = get_profile(request.user) cantranslate = check_profile_permission(profile, "translate", directory) cansuggest = check_profile_permission(profile, "suggest", directory) if type == 'submission' and not cantranslate or \ type == 'suggestion' and not cansuggest: json["success"] = False json["msg"] = _("You do not have rights to access translation mode.") else: translation_project = unit.store.translation_project language = translation_project.language form_class = unit_form_factory(language, len(unit.source.strings)) 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() sub = Submission(translation_project=translation_project, submitter=get_profile(request.user)) 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'], get_profile(request.user)) if sugg: SuggestionStat.objects.get_or_create(translation_project=translation_project, suggester=get_profile(request.user), state='pending', unit=unit.id) current_page = int(request.POST.get('page', 1)) all_units = unit.store.units units_qs = _filter_queryset(request.POST, all_units) unit_rows = profile.get_unit_rows() current_unit = unit if current_unit is not None: current_index = _get_index_in_qs(units_qs, current_unit) preceding = units_qs[:current_index].count() page = preceding / unit_rows + 1 if page != current_page: pager = paginate(request, units_qs, items=unit_rows, page=page) json["pager"] = _build_pager_dict(pager) try: new_index = current_index + 1 json["new_uid"] = units_qs[new_index].id except IndexError: # End of set: let's assume the new unit is the last we had new_unit = unit json["new_uid"] = None json["success"] = True else: # Form failed json["success"] = False json["msg"] = _("Failed to process submit.") except Store.DoesNotExist: json["success"] = False json["msg"] = _("Store %(path)s does not exist." % {'path': pootle_path}) except Unit.DoesNotExist: json["success"] = False json["msg"] = _("Unit %(uid)s does not exist on %(path)s." % {'uid': uid, 'path': pootle_path}) response = simplejson.dumps(json) return HttpResponse(response, mimetype="application/json")
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 if prev_unit.hasplural(): snplurals = len(prev_unit.source.strings) else: snplurals = None form_class = unit_form_factory(language, snplurals) 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() translation_submitted.send(sender=translation_project, unit=form.instance, profile=profile) 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(): if edit_unit.hasplural(): snplurals = len(edit_unit.source.strings) else: snplurals = None form_class = unit_form_factory(language, snplurals) 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, orphans=0) # 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 page_length = pager.end_index() - pager.start_index() + 1 if page_length < unit_rows: if pager.has_other_pages(): units_query = store.units[page_length:] else: units_query = store.units page = store_preceding / unit_rows units = paginate(request, units_query, items=unit_rows, page=page, orphans=0).object_list elif 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, orphans=0).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, orphans=0).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))
def get_edit_unit(request, unit): """Given a store path ``pootle_path`` and unit id ``uid``, gathers all the necessary information to build the editing widget. :return: A templatised editing widget is returned within the ``editor`` variable and paging information is also returned if the page number has changed. """ json = {} 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(instance=unit) comment_form_class = unit_comment_form_factory(language) comment_form = comment_form_class({}, instance=unit) store = unit.store directory = store.parent profile = request.profile alt_src_langs = get_alt_src_langs(request, profile, translation_project) project = translation_project.project report_target = ensure_uri(project.report_target) suggestions = get_sugg_list(unit) template_vars = { 'unit': unit, 'form': form, 'comment_form': comment_form, 'store': store, 'directory': directory, 'profile': profile, 'user': request.user, 'language': language, 'source_language': translation_project.project.source_language, 'cantranslate': check_profile_permission(profile, "translate", directory), 'cansuggest': check_profile_permission(profile, "suggest", directory), 'canreview': check_profile_permission(profile, "review", directory), 'altsrcs': find_altsrcs(unit, alt_src_langs, store=store, project=project), 'report_target': report_target, 'suggestions': suggestions, } if translation_project.project.is_terminology or store.is_terminology: t = loader.get_template('unit/term_edit.html') else: t = loader.get_template('unit/edit.html') c = RequestContext(request, template_vars) json['editor'] = t.render(c) rcode = 200 # Return context rows if filtering is applied but # don't return any if the user has asked not to have it current_filter = request.GET.get('filter', 'all') show_ctx = request.COOKIES.get('ctxShow', 'true') if ((_is_filtered(request) or current_filter not in ('all',)) and show_ctx == 'true'): # TODO: review if this first 'if' branch makes sense if translation_project.project.is_terminology or store.is_terminology: json['ctx'] = _filter_ctx_units(store.units, unit, 0) else: ctx_qty = int(request.COOKIES.get('ctxQty', 1)) json['ctx'] = _filter_ctx_units(store.units, unit, ctx_qty) response = jsonify(json) return HttpResponse(response, status=rcode, mimetype="application/json")
def get_edit_unit(request, unit): """ Given a store path C{pootle_path} and unit id C{uid}, gathers all the necessary information to build the editing widget. @return: A templatised editing widget is returned within the C{editor} variable and paging information is also returned if the page number has changed. """ json = {} 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(instance=unit) store = unit.store directory = store.parent profile = request.profile alt_src_langs = get_alt_src_langs(request, profile, translation_project) project = translation_project.project report_target = ensure_uri(project.report_target) suggestions, suggestion_details = get_sugg_list(unit) template_vars = { "unit": unit, "form": form, "store": store, "directory": directory, "profile": profile, "user": request.user, "language": language, "source_language": translation_project.project.source_language, "cantranslate": check_profile_permission(profile, "translate", directory), "cansuggest": check_profile_permission(profile, "suggest", directory), "canreview": check_profile_permission(profile, "review", directory), "altsrcs": find_altsrcs(unit, alt_src_langs, store=store, project=project), "report_target": report_target, "suggestions": suggestions, "suggestion_detail": suggestion_details, } if translation_project.project.is_terminology or store.is_terminology: t = loader.get_template("unit/term_edit.html") else: t = loader.get_template("unit/edit.html") c = RequestContext(request, template_vars) json["editor"] = t.render(c) t = loader.get_template("store/dircrumbs.html") json["dircrumbs"] = t.render(c) t = loader.get_template("store/storecrumbs.html") json["storecrumbs"] = t.render(c) rcode = 200 # Return context rows if filtering is applied if _is_filtered(request) or request.GET.get("filter", "all") != "all": if translation_project.project.is_terminology or store.is_terminology: json["ctxt"] = _filter_ctxt_units(store.units, unit, 0) else: json["ctxt"] = _filter_ctxt_units(store.units, unit, 2) response = jsonify(json) return HttpResponse(response, status=rcode, mimetype="application/json")