def _get_user_perms(self, user, project, resource, language, team, checksum, is_maintainer): """ Get permissions for a user. Args: user: A User instance project: A Project instance resource: A Resource instance language: A Language instance team: A Team instance checksum: An md5 checksum representing a source entity is_maintiner: A boolean Returns: A dictionary containing various user permissions """ check = ProjectPermission(user) can_review = check.proofread(project, language) can_submit_translations = check.submit_translations( team or resource.project) accept_translations = resource.accept_translations return { 'can_review': can_review, 'can_submit_translations': can_submit_translations, 'accept_translations': accept_translations, 'is_maintainer': check.maintain(project), }
def stringset_handling(request, project_slug, lang_code, resource_slug=None, *args, **kwargs): """ Function to serve AJAX data to the datatable holding the translating stringset. """ project = get_object_or_404(Project, slug=project_slug) resources = [] if resource_slug: try: resources = [ Resource.objects.get(slug=resource_slug, project__slug = project_slug) ] except Resource.DoesNotExist: raise Http404 else: resources = Resource.objects.filter(project__slug = project_slug) try: language = Language.objects.by_code_or_alias(lang_code) except Language.DoesNotExist: raise Http404 # Check if user is a team reviewer so that we can # send the extra info. check = ProjectPermission(request.user) review = check.proofread(project, language) # FIXME Do we need to check for non-POST requests and return an error? return _get_stringset(request.POST, resources, language, review=review)
def _save_translation(source_string, translations, target_language, user): """Save a translation string to the database. This functions handle a signle source entity translation (could be pluralized). Currently, the function only returns warning strings. There is no message for success. Args: source_string: A Translation object of the string in the source language. translations: A (rule, string) tuple. target_language: The language the string is translated to. user: The translator. Returns: A list if strings to display to the user. Raises: An LotteBadRequestError exception in case of errors. """ source_id = source_string.pk resource = source_string.resource source_language = resource.source_language warnings = [] check = ProjectPermission(user) review_perm = check.proofread(resource.project, target_language) for rule, target_string in translations.items(): rule = target_language.get_rule_num_from_name(rule) if rule != 5: # fetch correct source string for plural rule try: source_string = Translation.objects.get( source_entity=source_string.source_entity, language=source_language, rule=rule) except Translation.DoesNotExist: # target language has extra plural forms pass # check for errors try: for ErrorValidator in create_error_validators( resource.i18n_method): v = ErrorValidator(source_language, target_language, rule) v(source_string.string, target_string) except ValidationError, e: raise LotteBadRequestError(e.message) # check for warnings for WarningValidator in create_warning_validators( resource.i18n_method): v = WarningValidator(source_language, target_language, rule) try: v(source_string.string, target_string) except ValidationError, e: warnings.append(e.message)
def _save_translation(source_string, translations, target_language, user): """Save a translation string to the database. This functions handle a signle source entity translation (could be pluralized). Currently, the function only returns warning strings. There is no message for success. Args: source_string: A Translation object of the string in the source language. translations: A (rule, string) tuple. target_language: The language the string is translated to. user: The translator. Returns: A list if strings to display to the user. Raises: An LotteBadRequestError exception in case of errors. """ source_id = source_string.pk resource = source_string.resource source_language = resource.source_language warnings = [] check = ProjectPermission(user) review_perm = check.proofread(resource.project, target_language) for rule, target_string in translations.items(): rule = target_language.get_rule_num_from_name(rule) if rule != 5: # fetch correct source string for plural rule try: source_string = Translation.objects.get( source_entity=source_string.source_entity, language=source_language, rule=rule ) except Translation.DoesNotExist: # target language has extra plural forms pass # check for errors try: for ErrorValidator in create_error_validators(resource.i18n_method): v = ErrorValidator(source_language, target_language, rule) v(source_string.string, target_string) except ValidationError, e: raise LotteBadRequestError(e.message) # check for warnings for WarningValidator in create_warning_validators(resource.i18n_method): v = WarningValidator(source_language, target_language, rule) try: v(source_string.string, target_string) except ValidationError, e: warnings.append(e.message)
def proofread(request, project_slug, lang_code, resource_slug=None, *args, **kwargs): """AJAX view that sets the reviewed flag on Translations to true or false. The request data is expected in JSON, with the following format: { 'true': [1,2,3] 'false': [4,5] } Note: The IDs are source entity IDs. """ if request.method != 'POST': return HttpResponse(status=405) project = get_object_or_404(Project, slug=project_slug) resource = get_object_or_404(Resource, slug=resource_slug, project=project) try: language = Language.objects.by_code_or_alias(lang_code) except Language.DoesNotExist: raise Http404 # Check if the user has the necessary permissions to review strings. check = ProjectPermission(request.user) if not check.proofread(project, language): return permission_denied(request) request_data = simplejson.loads(request.raw_post_data) if 'true' in request_data: source_entity_ids = request_data['true'] translations = Translation.objects.filter( source_entity__id__in=source_entity_ids, language__code=lang_code, ) translations.update(reviewed=True) ReviewHistory.add_many(translations, request.user, project.id, reviewed=True) if 'false' in request_data: source_entity_ids = request_data['false'] translations = Translation.objects.filter( source_entity__id__in=source_entity_ids, language__code=lang_code, ) translations.update(reviewed=False) ReviewHistory.add_many(translations, request.user, project.id, reviewed=False) invalidate_stats_cache(resource, language, user=request.user) return HttpResponse(status=200)
def update(self, request, project_slug, resource_slug, language_code, api_version=2): """ Update existing translations for multiple source entities of a resource at one go by permitted user(s). """ try: project, resource, language = \ self._requested_objects( project_slug, resource_slug, language_code) self._validate_language_is_not_source_language( project.source_language, language) translations = request.data self._validate_translations_json_data(translations) team = Team.objects.get_or_none(project, language.code) check = ProjectPermission(request.user) # User must be a member of the project is_maintainer = check.maintain(project) # Allow only project members to issue this update request if not is_maintainer and not (check.submit_translations( team or project) or check.proofread(project, language)): return FORBIDDEN_REQUEST( "You are not allowed to update translations.") trans_obj_dict = self._translations_as_dict( translations, resource, language) updated_translations = [] se_ids = [] for translation in translations: # All permission checks for a user is done here and # updated translations are collected in updated_tranlsations # and source_entity.id in se_ids self._process_translation_dict(translation, project, resource, language, team, check, is_maintainer, request.user, se_ids, updated_translations, trans_obj_dict) self._update_translations(updated_translations) keys = ['key', 'context', 'translation', 'reviewed', 'pluralized', 'wordcount', 'last_update', 'user', 'position', 'occurrences',] field_map, fields = self._get_update_fieldmap_and_fields(keys) return self._generate_translations_dict( Translation.objects.filter( source_entity__id__in=se_ids, language=language).values(*fields), field_map) except NotFoundError, e: return NOT_FOUND_REQUEST(unicode(e))
def update(self, request, project_slug, resource_slug, language_code, source_hash, api_version=2): """ Update existing translations for a source entity of a resource. """ try: project, resource, language = \ self._requested_objects(project_slug, resource_slug, language_code) # A translation in source language cannot be updated self._validate_language_is_not_source_language( project.source_language, language) try: source_entity = SourceEntity.objects.get( string_hash=source_hash, resource=resource) except SourceEntity.DoesNotExist, e: return rc.NOT_FOUND team = Team.objects.get_or_none(project, language.code) data = request.data # This is a hack to use the methods from TranslationObjectsHandler data['source_entity_hash'] = source_hash check = ProjectPermission(request.user) is_maintainer = check.maintain(project) # Allow only project members to issue this update request if not is_maintainer and not (check.submit_translations( team or project) or check.proofread(project, language)): return FORBIDDEN_REQUEST( "You are not allowed to update translations.") trans_obj_dict = self._translations_as_dict( [data], resource, language) if not trans_obj_dict: return rc.NOT_FOUND updated_translations = [] se_ids = [] # All permission checks for a user is done here and # updated translations are collected in updated_tranlsations # and source_entity.id in se_ids self._process_translation_dict(data, project, resource, language, team, check, is_maintainer, request.user, se_ids, updated_translations, trans_obj_dict) # Updated translations are saved to db self._update_translations(updated_translations) translations = Translation.objects.filter( source_entity=source_entity, language=language) field_map = self._get_fieldmap() fields = self._get_fields_for_translation_value_query_set(field_map) return self._generate_translations_dict( Translation.objects.filter( source_entity__id__in=se_ids, language=language).values(*fields), field_map, True)
def stringset_handling(request, project_slug, lang_code, resource_slug=None, *args, **kwargs): """ Function to serve AJAX data to the datatable holding the translating stringset. """ project = get_object_or_404(Project, slug=project_slug) resources = [] if resource_slug: try: resources = [ Resource.objects.get(slug=resource_slug, project__slug=project_slug) ] except Resource.DoesNotExist: raise Http404 else: resources = Resource.objects.filter(project__slug=project_slug) try: language = Language.objects.by_code_or_alias(lang_code) except Language.DoesNotExist: raise Http404 # Check if user is a team reviewer so that we can # send the extra info. check = ProjectPermission(request.user) review = check.proofread(project, language) # FIXME Do we need to check for non-POST requests and return an error? return _get_stringset(request.POST, resources, language, review=review, session=request.session)
def proofread(request, project_slug, lang_code, resource_slug=None, *args, **kwargs): """AJAX view that sets the reviewed flag on Translations to true or false. The request data is expected in JSON, with the following format: { 'true': [1,2,3] 'false': [4,5] } Note: The IDs are source entity IDs. """ if request.method != 'POST': return HttpResponse(status=405) project = get_object_or_404(Project, slug=project_slug) resource = get_object_or_404(Resource, slug=resource_slug, project=project) try: language = Language.objects.by_code_or_alias(lang_code) except Language.DoesNotExist: raise Http404 # Check if the user has the necessary permissions to review strings. check = ProjectPermission(request.user) if not check.proofread(project, language): return permission_denied(request) request_data = simplejson.loads(request.raw_post_data) if 'true' in request_data: source_entity_ids = request_data['true'] translations = Translation.objects.filter( source_entity__id__in=source_entity_ids, language__code=lang_code, ) translations.update(reviewed=True) ReviewHistory.add_many(translations, request.user, project.id, reviewed=True) if 'false' in request_data: source_entity_ids = request_data['false'] translations = Translation.objects.filter( source_entity__id__in=source_entity_ids, language__code=lang_code, ) translations.update(reviewed=False) ReviewHistory.add_many(translations, request.user, project.id, reviewed=False) invalidate_stats_cache(resource, language, user=request.user) return HttpResponse(status=200)