Example #1
0
    def get_last_content_change(self, silent=False):
        """Wrapper to get last content change metadata.

        Used when commiting pending changes, needs to handle and report inconsistencies
        from past releases.
        """
        from weblate.auth.models import get_anonymous

        try:
            change = self.recent_content_changes[0]
            return change.author or get_anonymous(), change.timestamp
        except IndexError:
            return get_anonymous(), timezone.now()
Example #2
0
    def get_last_content_change(self, request):
        """Wrapper to get last content change metadata

        Used when commiting pending changes, needs to handle and report
        inconsistencies from past releases.
        """
        from weblate.auth.models import get_anonymous
        try:
            change = self.change_set.content().order_by('-timestamp')[0]
            return change.author or get_anonymous(), change.timestamp
        except IndexError as error:
            report_error(error, request, level='error')
            return get_anonymous(), timezone.now()
Example #3
0
    def get_last_content_change(self, request, silent=False):
        """Wrapper to get last content change metadata

        Used when commiting pending changes, needs to handle and report
        inconsistencies from past releases.
        """
        from weblate.auth.models import get_anonymous
        try:
            change = self.change_set.content().order_by('-timestamp')[0]
            return change.author or get_anonymous(), change.timestamp
        except IndexError as error:
            if not silent:
                report_error(error, request, level='error')
            return get_anonymous(), timezone.now()
Example #4
0
    def get_last_content_change(self, silent=False):
        """Wrapper to get last content change metadata.

        Used when commiting pending changes, needs to handle and report inconsistencies
        from past releases.
        """
        from weblate.auth.models import get_anonymous

        try:
            change = self.change_set.content().order_by("-timestamp")[0]
            return change.author or get_anonymous(), change.timestamp
        except IndexError:
            if not silent:
                report_error(level="error")
            return get_anonymous(), timezone.now()
Example #5
0
    def add_units(
        self,
        request,
        batch: List[Tuple[str, Union[str, List[str]],
                          Optional[Union[str, List[str]]]]],
    ):
        from weblate.auth.models import get_anonymous

        user = request.user if request else get_anonymous()
        with self.component.repository.lock:
            self.component.commit_pending("new unit", user)
            previous_revision = (self.component.repository.last_revision, )
            for translation in self.get_store_change_translations():
                for context, source, target in batch:
                    translation.store.new_unit(context,
                                               source,
                                               target,
                                               skip_save=True)
                    Change.objects.create(
                        translation=translation,
                        action=Change.ACTION_NEW_UNIT,
                        target=source,
                        user=user,
                        author=user,
                    )
                translation.store.save()
                translation.drop_store_cache()
                translation.git_commit(user,
                                       user.get_author_name(),
                                       store_hash=False)
            self.handle_store_change(request, user, previous_revision)

        if self.is_source:
            self.component.sync_terminology()
Example #6
0
 def test_protect_project(self):
     middleware = RequireLoginMiddleware()
     request = HttpRequest()
     request.user = User()
     request.META['SERVER_NAME'] = 'testserver'
     request.META['SERVER_PORT'] = '80'
     # No protection for not protected path
     self.assertIsNone(
         middleware.process_view(request, self.view_method, (), {})
     )
     request.path = '/project/foo/'
     # No protection for protected path and logged in user
     self.assertIsNone(
         middleware.process_view(request, self.view_method, (), {})
     )
     # Protection for protected path and not logged in user
     request.user = get_anonymous()
     self.assertIsInstance(
         middleware.process_view(request, self.view_method, (), {}),
         HttpResponseRedirect
     )
     # No protection for login and not logged in user
     request.path = '/accounts/login/'
     self.assertIsNone(
         middleware.process_view(request, self.view_method, (), {})
     )
Example #7
0
def send_invitation(request: HttpRequest, project_name: str, user: User):
    """Send invitation to user to join project."""
    fake = HttpRequest()
    fake.user = get_anonymous()
    fake.method = "POST"
    fake.session = create_session()
    fake.session["invitation_context"] = {
        "from_user": request.user.full_name,
        "project_name": project_name,
    }
    fake.POST["email"] = user.email
    fake.META = request.META
    store_userid(fake, invite=True)

    # Make sure the email backend is there for the invitation
    email_auth = "social_core.backends.email.EmailAuth"
    has_email = email_auth in settings.AUTHENTICATION_BACKENDS
    backup_backends = settings.AUTHENTICATION_BACKENDS
    backup_cache = social_core.backends.utils.BACKENDSCACHE
    backup_social = social_django.utils.BACKENDS
    if not has_email:
        social_core.backends.utils.BACKENDSCACHE["email"] = EmailAuth
        settings.AUTHENTICATION_BACKENDS += (email_auth,)

    # Send invitation
    complete(fake, "email")

    # Revert temporary settings override
    if not has_email:
        social_core.backends.utils.BACKENDSCACHE = backup_cache
        settings.AUTHENTICATION_BACKENDS = backup_backends
        social_django.utils.BACKENDS = backup_social
Example #8
0
    def new_unit(
        self,
        request,
        key: Optional[str],
        value: Optional[str],
        batch: Optional[Dict[str, str]] = None,
    ):
        from weblate.auth.models import get_anonymous

        user = request.user if request else get_anonymous()
        with self.component.repository.lock:
            self.component.commit_pending("new unit", user)
            if batch:
                for batch_key, batch_value in batch.items():
                    self.store.new_unit(batch_key, batch_value)
                    Change.objects.create(
                        translation=self,
                        action=Change.ACTION_NEW_UNIT,
                        target=batch_value,
                        user=user,
                        author=user,
                    )
            else:
                self.store.new_unit(key, value)
                Change.objects.create(
                    translation=self,
                    action=Change.ACTION_NEW_UNIT,
                    target=value,
                    user=user,
                    author=user,
                )
            self.component.create_translations(request=request)
            self.git_commit(user, user.get_author_name())
Example #9
0
def cleanup_suggestions():
    # Process suggestions
    anonymous_user = get_anonymous()
    suggestions = Suggestion.objects.prefetch_related('project', 'language')
    for suggestion in suggestions.iterator():
        with transaction.atomic():
            # Remove suggestions with same text as real translation
            units = Unit.objects.filter(
                content_hash=suggestion.content_hash,
                translation__language=suggestion.language,
                translation__component__project=suggestion.project,
            )

            if not units.exclude(target=suggestion.target).exists():
                suggestion.delete_log(anonymous_user,
                                      change=Change.ACTION_SUGGESTION_CLEANUP)
                continue

            # Remove duplicate suggestions
            sugs = Suggestion.objects.filter(
                content_hash=suggestion.content_hash,
                language=suggestion.language,
                project=suggestion.project,
                target=suggestion.target).exclude(id=suggestion.id)
            if sugs.exists():
                suggestion.delete_log(anonymous_user,
                                      change=Change.ACTION_SUGGESTION_CLEANUP)
Example #10
0
def cleanup_suggestions():
    # Process suggestions
    anonymous_user = get_anonymous()
    suggestions = Suggestion.objects.prefetch_related('project', 'language')
    for suggestion in suggestions.iterator():
        with transaction.atomic():
            # Remove suggestions with same text as real translation
            units = Unit.objects.filter(
                content_hash=suggestion.content_hash,
                translation__language=suggestion.language,
                translation__component__project=suggestion.project,
            )

            if not units.exclude(target=suggestion.target).exists():
                suggestion.delete_log(
                    anonymous_user,
                    change=Change.ACTION_SUGGESTION_CLEANUP
                )
                continue

            # Remove duplicate suggestions
            sugs = Suggestion.objects.filter(
                content_hash=suggestion.content_hash,
                language=suggestion.language,
                project=suggestion.project,
                target=suggestion.target
            ).exclude(
                id=suggestion.id
            )
            if sugs.exists():
                suggestion.delete_log(
                    anonymous_user,
                    change=Change.ACTION_SUGGESTION_CLEANUP
                )
Example #11
0
def cleanup_suggestions():
    # Process suggestions
    anonymous_user = get_anonymous()
    suggestions = Suggestion.objects.prefetch_related("unit")
    for suggestion in suggestions:
        with transaction.atomic():
            # Remove suggestions with same text as real translation
            if (
                suggestion.unit.target == suggestion.target
                and suggestion.unit.translated
            ):
                suggestion.delete_log(
                    anonymous_user, change=Change.ACTION_SUGGESTION_CLEANUP
                )
                continue

            # Remove duplicate suggestions
            sugs = Suggestion.objects.filter(
                unit=suggestion.unit, target=suggestion.target
            ).exclude(id=suggestion.id)
            # Do not rely on the SQL as MySQL compares strings case insensitive
            for other in sugs:
                if other.target == suggestion.target:
                    suggestion.delete_log(
                        anonymous_user, change=Change.ACTION_SUGGESTION_CLEANUP
                    )
                    break
Example #12
0
def cleanup_suggestions():
    # Process suggestions
    anonymous_user = get_anonymous()
    suggestions = Suggestion.objects.prefetch_related('project', 'language')
    for suggestion in suggestions.iterator():
        with transaction.atomic():
            # Remove suggestions with same text as real translation
            is_different = False
            # Do not rely on the SQL as MySQL compares strings case insensitive
            for unit in suggestion.related_units:
                if unit.target != suggestion.target:
                    is_different = True
                    break

            if not is_different:
                suggestion.delete_log(
                    anonymous_user, change=Change.ACTION_SUGGESTION_CLEANUP
                )
                continue

            # Remove duplicate suggestions
            sugs = Suggestion.objects.filter(
                content_hash=suggestion.content_hash,
                language=suggestion.language,
                project=suggestion.project,
                target=suggestion.target,
            ).exclude(id=suggestion.id)
            # Do not rely on the SQL as MySQL compares strings case insensitive
            for other in sugs:
                if other.target == suggestion.target:
                    suggestion.delete_log(
                        anonymous_user, change=Change.ACTION_SUGGESTION_CLEANUP
                    )
                    break
Example #13
0
    def handle(self, *args, **options):
        try:
            addon_class = ADDONS[options["addon"]]
        except KeyError:
            raise CommandError("Addon not found: {}".format(options["addon"]))
        addon = addon_class()
        try:
            configuration = json.loads(options["configuration"])
        except ValueError as error:
            raise CommandError(f"Invalid addon configuration: {error}")
        try:
            user = User.objects.filter(is_superuser=True)[0]
        except IndexError:
            user = get_anonymous()
        for component in self.get_components(*args, **options):
            if addon.has_settings:
                form = addon.get_add_form(None, component, data=configuration)
                self.validate_form(form)
            addons = Addon.objects.filter_component(component).filter(
                name=addon.name)
            if addons:
                if options["update"]:
                    for addon_component in addons:
                        addon_component.addon.configure(configuration)
                    self.stdout.write(f"Successfully updated on {component}")
                else:
                    self.stderr.write(f"Already installed on {component}")
                continue

            if not addon.can_install(component, user):
                self.stderr.write(f"Can not install on {component}")
                continue

            addon.create(component, configuration=configuration)
            self.stdout.write(f"Successfully installed on {component}")
Example #14
0
    def add(self, unit, target, request, vote=False):
        """Create new suggestion for this unit."""
        from weblate.auth.models import get_anonymous
        user = request.user if request else get_anonymous()

        if unit.translated and unit.target == target:
            return False

        same_suggestions = self.filter(
            target=target,
            content_hash=unit.content_hash,
            language=unit.translation.language,
            project=unit.translation.component.project,
        )
        # Do not rely on the SQL as MySQL compares strings case insensitive
        for same in same_suggestions:
            if same.target == target:
                if same.user == user or not vote:
                    return False
                same.add_vote(unit.translation, request, Vote.POSITIVE)
                return False

        # Create the suggestion
        suggestion = self.create(
            target=target,
            content_hash=unit.content_hash,
            language=unit.translation.language,
            project=unit.translation.component.project,
            user=user,
            userdetails={
                'address':
                get_ip_address(request) if request else '',
                'agent':
                request.META.get('HTTP_USER_AGENT', '') if request else '',
            },
        )

        # Record in change
        for aunit in suggestion.related_units:
            Change.objects.create(
                unit=aunit,
                suggestion=suggestion,
                action=Change.ACTION_SUGGESTION,
                user=user,
                target=target,
                author=user,
            )

        # Add unit vote
        if vote:
            suggestion.add_vote(unit.translation, request, Vote.POSITIVE)

        # Update suggestion stats
        if user is not None:
            user.profile.suggested += 1
            user.profile.save()

        return True
Example #15
0
 def test_acl_disable(self):
     """Test disabling ACL."""
     response = self.client.get(self.access_url)
     self.assertEqual(response.status_code, 404)
     self.project.access_control = Project.ACCESS_PUBLIC
     self.project.save()
     self.assertTrue(get_anonymous().can_access_project(self.project))
     response = self.client.get(self.access_url)
     self.assertEqual(response.status_code, 403)
     response = self.client.get(self.translate_url)
     self.assertContains(response, 'type="submit" name="save"')
Example #16
0
def check_avatars(app_configs, **kwargs):
    from weblate.auth.models import get_anonymous
    from weblate.accounts.avatar import download_avatar_image

    if not settings.ENABLE_AVATARS:
        return []
    try:
        download_avatar_image(get_anonymous(), 32)
        return []
    except (IOError, CertificateError) as error:
        return [weblate_check("weblate.E018", f"Failed to download avatar: {error}")]
Example #17
0
 def test_acl_protected(self):
     """Test ACL protected project."""
     response = self.client.get(self.access_url)
     self.assertEqual(response.status_code, 404)
     self.project.access_control = Project.ACCESS_PROTECTED
     self.project.save()
     self.assertTrue(get_anonymous().can_access_project(self.project))
     response = self.client.get(self.access_url)
     self.assertEqual(response.status_code, 403)
     response = self.client.get(self.translate_url)
     self.assertContains(
         response, "Insufficient privileges for saving translations.")
Example #18
0
def send_invitation(request, project, user):
    fake = HttpRequest()
    fake.user = get_anonymous()
    fake.method = 'POST'
    fake.session = create_session()
    fake.session['invitation_context'] = {
        'from_user': request.user.full_name,
        'project_name': project.name,
    }
    fake.POST['email'] = user.email
    fake.META = request.META
    store_userid(fake, invite=True)
    complete(fake, 'email')
Example #19
0
def get_user(request):
    """Based on django.contrib.auth.middleware.get_user.

    Adds handling of anonymous user which is stored in database.
    """
    # pylint: disable=protected-access
    if not hasattr(request, "_cached_user"):
        user = auth.get_user(request)
        if isinstance(user, AnonymousUser):
            user = get_anonymous()

        request._cached_user = user
    return request._cached_user
Example #20
0
def get_user(request):
    """Based on django.contrib.auth.middleware.get_user

    Adds handling of anonymous user which is stored in database.
    """
    # pylint: disable=protected-access
    if not hasattr(request, '_cached_user'):
        user = auth.get_user(request)
        if isinstance(user, AnonymousUser):
            user = get_anonymous()

        request._cached_user = user
    return request._cached_user
Example #21
0
def send_invitation(request, project, user):
    fake = HttpRequest()
    fake.user = get_anonymous()
    fake.method = "POST"
    fake.session = create_session()
    fake.session["invitation_context"] = {
        "from_user": request.user.full_name,
        "project_name": project.name,
    }
    fake.POST["email"] = user.email
    fake.META = request.META
    store_userid(fake, invite=True)
    complete(fake, "email")
Example #22
0
    def handle(self, *args, **options):
        try:
            addon = ADDONS[options['addon']]
        except KeyError:
            raise CommandError('Addon not found: {}'.format(options['addon']))
        try:
            configuration = json.loads(options['configuration'])
        except ValueError as error:
            raise CommandError('Invalid addon configuration: {}'.format(error))
        if addon.has_settings:
            form = addon.get_add_form(None, data=configuration)
            if not form.is_valid():
                for error in form.non_field_errors():
                    self.stderr.write(error)
                for field in form:
                    for error in field.errors:
                        self.stderr.write(
                            'Error in {}: {}'.format(field.name, error)
                        )
                raise CommandError(
                    'Invalid addon configuration!'
                )
        try:
            user = User.objects.filter(is_superuser=True)[0]
        except IndexError:
            user = get_anonymous()
        for component in self.get_components(*args, **options):
            addons = Addon.objects.filter_component(component).filter(
                name=addon.name
            )
            if addons.exists():
                if options['update']:
                    addons.update(configuration=configuration)
                    self.stdout.write(
                        'Successfully updated on {}'.format(component)
                    )
                else:
                    self.stderr.write(
                        'Already installed on {}'.format(component)
                    )
                continue

            if not addon.can_install(component, user):
                self.stderr.write('Can not install on {}'.format(component))
                continue

            addon.create(component, configuration=configuration)
            self.stdout.write(
                'Successfully installed on {}'.format(component)
            )
Example #23
0
    def handle(self, *args, **options):
        try:
            addon = ADDONS[options['addon']]()
        except KeyError:
            raise CommandError('Addon not found: {}'.format(options['addon']))
        try:
            configuration = json.loads(options['configuration'])
        except ValueError as error:
            raise CommandError('Invalid addon configuration: {}'.format(error))
        if addon.has_settings:
            form = addon.get_add_form(None, data=configuration)
            if not form.is_valid():
                for error in form.non_field_errors():
                    self.stderr.write(error)
                for field in form:
                    for error in field.errors:
                        self.stderr.write(
                            'Error in {}: {}'.format(field.name, error)
                        )
                raise CommandError(
                    'Invalid addon configuration!'
                )
        try:
            user = User.objects.filter(is_superuser=True)[0]
        except IndexError:
            user = get_anonymous()
        for component in self.get_components(*args, **options):
            addons = Addon.objects.filter_component(component).filter(
                name=addon.name
            )
            if addons.exists():
                if options['update']:
                    addons.update(configuration=configuration)
                    self.stdout.write(
                        'Successfully updated on {}'.format(component)
                    )
                else:
                    self.stderr.write(
                        'Already installed on {}'.format(component)
                    )
                continue

            if not addon.can_install(component, user):
                self.stderr.write('Can not install on {}'.format(component))
                continue

            addon.create(component, configuration=configuration)
            self.stdout.write(
                'Successfully installed on {}'.format(component)
            )
Example #24
0
    def add(self, unit, target, request, vote=False):
        """Create new suggestion for this unit."""
        from weblate.auth.models import get_anonymous

        user = request.user if request else get_anonymous()

        if unit.translated and unit.target == target:
            return False

        same_suggestions = self.filter(target=target, unit=unit)
        # Do not rely on the SQL as MySQL compares strings case insensitive
        for same in same_suggestions:
            if same.target == target:
                if same.user == user or not vote:
                    return False
                same.add_vote(request, Vote.POSITIVE)
                return False

        # Create the suggestion
        suggestion = self.create(
            target=target,
            unit=unit,
            user=user,
            userdetails={
                "address": get_ip_address(request),
                "agent": get_user_agent_raw(request),
            },
        )

        # Record in change
        Change.objects.create(
            unit=unit,
            suggestion=suggestion,
            action=Change.ACTION_SUGGESTION,
            user=user,
            target=target,
            author=user,
        )

        # Add unit vote
        if vote:
            suggestion.add_vote(request, Vote.POSITIVE)

        # Update suggestion stats
        if user is not None:
            user.profile.suggested += 1
            user.profile.save()

        return suggestion
Example #25
0
def check_avatars(app_configs, **kwargs):
    from weblate.auth.models import get_anonymous
    from weblate.accounts.avatar import download_avatar_image
    if not settings.ENABLE_AVATARS:
        return []
    try:
        download_avatar_image(get_anonymous(), 32)
        return []
    except (IOError, CertificateError) as error:
        return [
            Critical(
                'Failed to download avatar: {}'.format(error),
                hint=get_doc_url('admin/optionals', 'avatars'),
                id='weblate.E018',
            )
        ]
Example #26
0
    def delete_unit(self, request, unit):
        from weblate.auth.models import get_anonymous

        component = self.component
        user = request.user if request else get_anonymous()
        with component.repository.lock:
            component.commit_pending("delete unit", user)
            try:
                pounit, add = self.store.find_unit(unit.context, unit.source)
            except UnitNotFound:
                return
            if add:
                return
            extra_files = self.store.remove_unit(pounit.unit)
            self.addon_commit_files.extend(extra_files)
            self.handle_store_change(request, user)
Example #27
0
def get_user(request):
    """Based on django.contrib.auth.middleware.get_user

    Adds handling of anonymous user which is stored in database.
    """
    # pylint: disable=protected-access
    if not hasattr(request, '_cached_user'):
        user = auth.get_user(request)
        if isinstance(user, AnonymousUser):
            user = get_anonymous()
            # Set short expiry for anonymous sessions
            request.session.set_expiry(2200)
        else:
            request.session.set_expiry(None)

        request._cached_user = user
    return request._cached_user
Example #28
0
    def delete_unit(self, request, unit):
        from weblate.auth.models import get_anonymous

        component = self.component
        user = request.user if request else get_anonymous()
        with component.repository.lock:
            component.commit_pending("delete unit", user)
            try:
                pounit, add = self.store.find_unit(unit.context, unit.source)
            except UnitNotFound:
                return
            if add:
                return
            extra_files = self.store.remove_unit(pounit.unit)
            self.addon_commit_files.extend(extra_files)
            self.git_commit(user, user.get_author_name())
        component.create_translations(request=request, force=True)
Example #29
0
    def add_units(self, request, batch: Dict[str, Union[str, List[str]]]):
        from weblate.auth.models import get_anonymous

        user = request.user if request else get_anonymous()
        with self.component.repository.lock:
            self.component.commit_pending("new unit", user)
            for key, value in batch.items():
                self.store.new_unit(key, value)
                Change.objects.create(
                    translation=self,
                    action=Change.ACTION_NEW_UNIT,
                    target=value,
                    user=user,
                    author=user,
                )
            self.git_commit(user, user.get_author_name())
        self.component.create_translations(request=request)
Example #30
0
def get_user(request):
    """Based on django.contrib.auth.middleware.get_user

    Adds handling of anonymous user which is stored in database.
    """
    # pylint: disable=protected-access
    if not hasattr(request, '_cached_user'):
        user = auth.get_user(request)
        if isinstance(user, AnonymousUser):
            user = get_anonymous()
            # Set short expiry for anonymous sessions
            request.session.set_expiry(1800)
        else:
            request.session.set_expiry(None)

        request._cached_user = user
    return request._cached_user
Example #31
0
    def delete_unit(self, request, unit):
        from weblate.auth.models import get_anonymous

        component = self.component
        user = request.user if request else get_anonymous()
        with component.repository.lock:
            component.commit_pending("delete unit", user)
            previous_revision = self.component.repository.last_revision
            for translation in self.get_store_change_translations():
                try:
                    pounit, add = translation.store.find_unit(unit.context, unit.source)
                except UnitNotFound:
                    return
                if add:
                    return
                extra_files = translation.store.remove_unit(pounit.unit)
                translation.addon_commit_files.extend(extra_files)
                translation.drop_store_cache()
                translation.git_commit(user, user.get_author_name(), store_hash=False)
            self.handle_store_change(request, user, previous_revision)
Example #32
0
 def test_protect_project(self):
     middleware = RequireLoginMiddleware()
     request = HttpRequest()
     request.user = User()
     request.META['SERVER_NAME'] = 'testserver'
     request.META['SERVER_PORT'] = '80'
     # No protection for not protected path
     self.assertIsNone(middleware.process_view(request, self.view_method, (), {}))
     request.path = '/project/foo/'
     # No protection for protected path and logged in user
     self.assertIsNone(middleware.process_view(request, self.view_method, (), {}))
     # Protection for protected path and not logged in user
     request.user = get_anonymous()
     self.assertIsInstance(
         middleware.process_view(request, self.view_method, (), {}),
         HttpResponseRedirect,
     )
     # No protection for login and not logged in user
     request.path = '/accounts/login/'
     self.assertIsNone(middleware.process_view(request, self.view_method, (), {}))
Example #33
0
 def test_protect_project(self):
     middleware = RequireLoginMiddleware()
     request = HttpRequest()
     request.user = User()
     request.META["SERVER_NAME"] = "testserver"
     request.META["SERVER_PORT"] = "80"
     # No protection for not protected path
     self.assertIsNone(middleware.process_view(request, self.view_method, (), {}))
     request.path = "/project/foo/"
     # No protection for protected path and signed in user
     self.assertIsNone(middleware.process_view(request, self.view_method, (), {}))
     # Protection for protected path and not signed in user
     request.user = get_anonymous()
     self.assertIsInstance(
         middleware.process_view(request, self.view_method, (), {}),
         HttpResponseRedirect,
     )
     # No protection for login and not signed in user
     request.path = "/accounts/login/"
     self.assertIsNone(middleware.process_view(request, self.view_method, (), {}))
Example #34
0
    def add_units(
        self,
        request,
        batch: List[Tuple[Union[str, List[str]], Union[str, List[str]],
                          Optional[str]]],
    ):
        from weblate.auth.models import get_anonymous

        user = request.user if request else get_anonymous()
        with self.component.repository.lock:
            self.component.commit_pending("new unit", user)
            for context, source, target in batch:
                self.store.new_unit(context, source, target)
                Change.objects.create(
                    translation=self,
                    action=Change.ACTION_NEW_UNIT,
                    target=source,
                    user=user,
                    author=user,
                )
            self.handle_store_change(request, user)
Example #35
0
def cleanup_suggestions():
    # Process suggestions
    anonymous_user = get_anonymous()
    suggestions = Suggestion.objects.prefetch_related('project', 'language')
    for suggestion in suggestions.iterator():
        with transaction.atomic():
            # Remove suggestions with same text as real translation
            is_different = False
            # Do not rely on the SQL as MySQL compares strings case insensitive
            for unit in suggestion.related_units:
                if unit.target != suggestion.target:
                    is_different = True
                    break

            if not is_different:
                suggestion.delete_log(
                    anonymous_user,
                    change=Change.ACTION_SUGGESTION_CLEANUP
                )
                continue

            # Remove duplicate suggestions
            sugs = Suggestion.objects.filter(
                content_hash=suggestion.content_hash,
                language=suggestion.language,
                project=suggestion.project,
                target=suggestion.target
            ).exclude(
                id=suggestion.id
            )
            # Do not rely on the SQL as MySQL compares strings case insensitive
            for other in sugs:
                if other.target == suggestion.target:
                    suggestion.delete_log(
                        anonymous_user,
                        change=Change.ACTION_SUGGESTION_CLEANUP
                    )
                    break
Example #36
0
def invite_user(request, project):
    """Invite user to a project."""
    obj, form = check_user_form(request,
                                project,
                                True,
                                form_class=InviteUserForm)

    if form is not None:
        try:
            user = form.save()
            obj.add_user(user)
            Change.objects.create(
                project=obj,
                action=Change.ACTION_INVITE_USER,
                user=request.user,
                details={'username': user.username},
            )
            fake = HttpRequest()
            fake.user = get_anonymous()
            fake.method = 'POST'
            fake.session = create_session()
            fake.session['invitation_context'] = {
                'from_user': request.user.full_name,
                'project_name': obj.name,
            }
            fake.POST['email'] = form.cleaned_data['email']
            fake.META = request.META
            store_userid(fake, invite=True)
            complete(fake, 'email')
            messages.success(request,
                             _('User has been invited to this project.'))
        except Group.DoesNotExist:
            messages.error(request, _('Failed to find group to add a user!'))

    return redirect(
        'manage-access',
        project=obj.slug,
    )
Example #37
0
def notify_connect(
    strategy,
    details,
    backend,
    user,
    social,
    new_association=False,
    is_new=False,
    **kwargs,
):
    """Notify about adding new link."""
    # Adjust possibly pending email confirmation audit logs
    AuditLog.objects.filter(
        user=get_anonymous(),
        activity="sent-email",
        params={
            "email": details["email"]
        },
    ).update(user=user)
    if user and not is_new:
        if new_association:
            action = "auth-connect"
        else:
            action = "login"
            adjust_session_expiry(strategy.request)
        AuditLog.objects.create(
            user,
            strategy.request,
            action,
            method=backend.name,
            name=social.uid,
        )
    # Remove partial pipeline
    session = strategy.request.session
    if PARTIAL_TOKEN_SESSION_NAME in session:
        strategy.really_clean_partial_pipeline(
            session[PARTIAL_TOKEN_SESSION_NAME])
Example #38
0
    def cleanup_database(self):
        """Cleanup the database"""
        anonymous_user = get_anonymous()
        with transaction.atomic():
            projects = list(Project.objects.values_list('id', flat=True))
        for pk in projects:
            with transaction.atomic():
                # List all current unit content_hashs
                units = Unit.objects.filter(
                    translation__component__project__pk=pk
                ).values('content_hash').distinct()

                # Remove source comments referring to deleted units
                Comment.objects.filter(
                    language=None,
                    project__pk=pk
                ).exclude(
                    content_hash__in=units
                ).delete()

                # Remove source checks referring to deleted units
                Check.objects.filter(
                    language=None,
                    project__pk=pk
                ).exclude(
                    content_hash__in=units
                ).delete()

            for lang in Language.objects.all():
                with transaction.atomic():
                    # Remove checks referring to deleted or not translated
                    # units
                    translatedunits = Unit.objects.filter(
                        translation__language=lang,
                        state__gte=STATE_TRANSLATED,
                        translation__component__project__pk=pk
                    ).values('content_hash').distinct()
                    Check.objects.filter(
                        language=lang, project__pk=pk
                    ).exclude(
                        content_hash__in=translatedunits
                    ).delete()

                    # List current unit content_hashs
                    units = Unit.objects.filter(
                        translation__language=lang,
                        translation__component__project__pk=pk
                    ).values('content_hash').distinct()

                    # Remove suggestions referring to deleted units
                    Suggestion.objects.filter(
                        language=lang,
                        project__pk=pk
                    ).exclude(
                        content_hash__in=units
                    ).delete()

                    # Remove translation comments referring to deleted units
                    Comment.objects.filter(
                        language=lang,
                        project__pk=pk
                    ).exclude(
                        content_hash__in=units
                    ).delete()

                    # Process suggestions
                    all_suggestions = Suggestion.objects.filter(
                        language=lang,
                        project__pk=pk
                    )
                    for sug in all_suggestions.iterator():
                        # Remove suggestions with same text as real translation
                        units = Unit.objects.filter(
                            content_hash=sug.content_hash,
                            translation__language=lang,
                            translation__component__project__pk=pk,
                        )

                        if not units.exclude(target=sug.target).exists():
                            sug.delete_log(
                                anonymous_user,
                                Change.ACTION_SUGGESTION_CLEANUP
                            )
                            continue

                        # Remove duplicate suggestions
                        sugs = Suggestion.objects.filter(
                            content_hash=sug.content_hash,
                            language=lang,
                            project__pk=pk,
                            target=sug.target
                        ).exclude(
                            id=sug.id
                        )
                        if sugs.exists():
                            sug.delete_log(
                                anonymous_user,
                                Change.ACTION_SUGGESTION_CLEANUP
                            )