mirror of
				https://gitlab.crans.org/bde/nk20
				synced 2025-11-04 09:12:11 +01:00 
			
		
		
		
	Compare commits
	
		
			30 Commits
		
	
	
		
			c49af0b83a
			...
			faster_ci
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					3eed93e346 | ||
| 
						 | 
					4da523a1ba | ||
| 
						 | 
					e74ff54468 | ||
| 
						 | 
					2e49c9ffbd | ||
| 
						 | 
					d20a1038a8 | ||
| 
						 | 
					f6b711bb1b | ||
| 
						 | 
					893d87a9e1 | ||
| 
						 | 
					9f3323c73e | ||
| 
						 | 
					c57f81b920 | ||
| 
						 | 
					0636d84286 | ||
| 
						 | 
					ed06901fae | ||
| 
						 | 
					28932f316b | ||
| 
						 | 
					9b50ba722c | ||
| 
						 | 
					3e3e61d23f | ||
| 
						 | 
					1129815ca3 | ||
| 
						 | 
					c13172d3ff | ||
| 
						 | 
					fcc4121225 | ||
| 
						 | 
					a06f355559 | ||
| 
						 | 
					08df5fcccd | ||
| 
						 | 
					b6c0f9758d | ||
| 
						 | 
					a23093851f | ||
| 
						
						
							
						
						d5a9bf175f
	
				 | 
					
					
						|||
| 
						 | 
					d803ab5ec2 | ||
| 
						 | 
					d7a537b6b5 | ||
| 
						 | 
					0941ee954d | ||
| 
						 | 
					fd11d96d95 | ||
| 
						 | 
					4bfc057454 | ||
| 
						
						
							
						
						b597a6ac5b
	
				 | 
					
					
						|||
| 
						 | 
					a704b92c3d | ||
| 53090b1a21 | 
							
								
								
									
										3
									
								
								.ansible-lint
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.ansible-lint
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					skip_list:
 | 
				
			||||||
 | 
					  - command-instead-of-shell  # Use shell only when shell functionality is required
 | 
				
			||||||
 | 
					  - experimental  # all rules tagged as experimental
 | 
				
			||||||
@@ -10,50 +10,22 @@ variables:
 | 
				
			|||||||
# Debian Buster
 | 
					# Debian Buster
 | 
				
			||||||
py37-django22:
 | 
					py37-django22:
 | 
				
			||||||
  stage: test
 | 
					  stage: test
 | 
				
			||||||
  image: debian:buster-backports
 | 
					  image: otthorn/nk20_ci_37
 | 
				
			||||||
  before_script:
 | 
					 | 
				
			||||||
    - >
 | 
					 | 
				
			||||||
        apt-get update &&
 | 
					 | 
				
			||||||
        apt-get install --no-install-recommends -t buster-backports -y
 | 
					 | 
				
			||||||
        python3-django python3-django-crispy-forms
 | 
					 | 
				
			||||||
        python3-django-extensions python3-django-filters python3-django-polymorphic
 | 
					 | 
				
			||||||
        python3-djangorestframework python3-django-oauth-toolkit python3-psycopg2 python3-pil
 | 
					 | 
				
			||||||
        python3-babel python3-lockfile python3-pip python3-phonenumbers python3-memcache
 | 
					 | 
				
			||||||
        python3-bs4 python3-setuptools tox texlive-xetex
 | 
					 | 
				
			||||||
  script: tox -e py37-django22
 | 
					  script: tox -e py37-django22
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Ubuntu 20.04
 | 
					# Ubuntu 20.04
 | 
				
			||||||
py38-django22:
 | 
					py38-django22:
 | 
				
			||||||
  stage: test
 | 
					  stage: test
 | 
				
			||||||
  image: ubuntu:20.04
 | 
					  image: otthorn/nk20_ci_38
 | 
				
			||||||
  before_script:
 | 
					 | 
				
			||||||
    # Fix tzdata prompt
 | 
					 | 
				
			||||||
    - ln -sf /usr/share/zoneinfo/Europe/Paris /etc/localtime && echo Europe/Paris > /etc/timezone
 | 
					 | 
				
			||||||
    - >
 | 
					 | 
				
			||||||
        apt-get update &&
 | 
					 | 
				
			||||||
        apt-get install --no-install-recommends -y
 | 
					 | 
				
			||||||
        python3-django python3-django-crispy-forms
 | 
					 | 
				
			||||||
        python3-django-extensions python3-django-filters python3-django-polymorphic
 | 
					 | 
				
			||||||
        python3-djangorestframework python3-django-oauth-toolkit python3-psycopg2 python3-pil
 | 
					 | 
				
			||||||
        python3-babel python3-lockfile python3-pip python3-phonenumbers python3-memcache
 | 
					 | 
				
			||||||
        python3-bs4 python3-setuptools tox texlive-xetex
 | 
					 | 
				
			||||||
  script: tox -e py38-django22
 | 
					  script: tox -e py38-django22
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Debian Bullseye
 | 
					# Debian Bullseye
 | 
				
			||||||
py39-django22:
 | 
					py39-django22:
 | 
				
			||||||
  stage: test
 | 
					  stage: test
 | 
				
			||||||
  image: debian:bullseye
 | 
					  image: otthorn/nk20_ci_39
 | 
				
			||||||
  before_script:
 | 
					 | 
				
			||||||
    - >
 | 
					 | 
				
			||||||
        apt-get update &&
 | 
					 | 
				
			||||||
        apt-get install --no-install-recommends -y
 | 
					 | 
				
			||||||
        python3-django python3-django-crispy-forms
 | 
					 | 
				
			||||||
        python3-django-extensions python3-django-filters python3-django-polymorphic
 | 
					 | 
				
			||||||
        python3-djangorestframework python3-django-oauth-toolkit python3-psycopg2 python3-pil
 | 
					 | 
				
			||||||
        python3-babel python3-lockfile python3-pip python3-phonenumbers python3-memcache
 | 
					 | 
				
			||||||
        python3-bs4 python3-setuptools tox texlive-xetex
 | 
					 | 
				
			||||||
  script: tox -e py39-django22
 | 
					  script: tox -e py39-django22
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Tox linter
 | 
				
			||||||
linters:
 | 
					linters:
 | 
				
			||||||
  stage: quality-assurance
 | 
					  stage: quality-assurance
 | 
				
			||||||
  image: debian:buster-backports
 | 
					  image: debian:buster-backports
 | 
				
			||||||
@@ -64,6 +36,20 @@ linters:
 | 
				
			|||||||
  # Be nice to new contributors, but please use `tox`
 | 
					  # Be nice to new contributors, but please use `tox`
 | 
				
			||||||
  allow_failure: true
 | 
					  allow_failure: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Ansible linter
 | 
				
			||||||
 | 
					ansible-linter:
 | 
				
			||||||
 | 
					  stage: quality-assurance
 | 
				
			||||||
 | 
					  image: otthorn/nk20_ci_ansiblelint
 | 
				
			||||||
 | 
					  script: ansible-lint ansible/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Docker linter
 | 
				
			||||||
 | 
					docker-linter:
 | 
				
			||||||
 | 
					  stage: quality-assurance
 | 
				
			||||||
 | 
					  image: hadolint/hadolint
 | 
				
			||||||
 | 
					  script:
 | 
				
			||||||
 | 
					    - hadolint -c .hadolint Dockerfile
 | 
				
			||||||
 | 
					    - hadolint -c .hadolint docker_ci/Dockerfile.*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Compile documentation
 | 
					# Compile documentation
 | 
				
			||||||
documentation:
 | 
					documentation:
 | 
				
			||||||
  stage: docs
 | 
					  stage: docs
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								.hadolint
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								.hadolint
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					ignored:
 | 
				
			||||||
 | 
					  - DL3008  # Do not force to pin version in apt (Debian)
 | 
				
			||||||
 | 
					  - DL3013  # Do not force to pin version in pip (PyPI)
 | 
				
			||||||
 | 
					  - DL3018  # Do not force to pin version in apk (Alpine)
 | 
				
			||||||
@@ -223,7 +223,8 @@ class Transaction(PolymorphicModel):
 | 
				
			|||||||
        # Check that the amounts stay between big integer bounds
 | 
					        # Check that the amounts stay between big integer bounds
 | 
				
			||||||
        diff_source, diff_dest = self.validate()
 | 
					        diff_source, diff_dest = self.validate()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not self.source.is_active or not self.destination.is_active:
 | 
					        if not (hasattr(self, '_force_save') and self._force_save) \
 | 
				
			||||||
 | 
					                and (not self.source.is_active or not self.destination.is_active):
 | 
				
			||||||
            raise ValidationError(_("The transaction can't be saved since the source note "
 | 
					            raise ValidationError(_("The transaction can't be saved since the source note "
 | 
				
			||||||
                                    "or the destination note is not active."))
 | 
					                                    "or the destination note is not active."))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -271,7 +272,7 @@ class RecurrentTransaction(Transaction):
 | 
				
			|||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def clean(self):
 | 
					    def clean(self):
 | 
				
			||||||
        if self.template.destination != self.destination:
 | 
					        if self.template.destination != self.destination and not (hasattr(self, '_force_save') and self._force_save):
 | 
				
			||||||
            raise ValidationError(
 | 
					            raise ValidationError(
 | 
				
			||||||
                _("The destination of this transaction must equal to the destination of the template."))
 | 
					                _("The destination of this transaction must equal to the destination of the template."))
 | 
				
			||||||
        return super().clean()
 | 
					        return super().clean()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,4 +43,5 @@ def delete_transaction(instance, **_kwargs):
 | 
				
			|||||||
    """
 | 
					    """
 | 
				
			||||||
    if not hasattr(instance, "_no_signal"):
 | 
					    if not hasattr(instance, "_no_signal"):
 | 
				
			||||||
        instance.valid = False
 | 
					        instance.valid = False
 | 
				
			||||||
 | 
					        instance._force_save = True
 | 
				
			||||||
        instance.save()
 | 
					        instance.save()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -223,13 +223,14 @@ function consume (source, source_alias, dest, quantity, amount, reason, type, ca
 | 
				
			|||||||
        const newBalance = source.balance - quantity * amount
 | 
					        const newBalance = source.balance - quantity * amount
 | 
				
			||||||
        if (newBalance <= -5000) {
 | 
					        if (newBalance <= -5000) {
 | 
				
			||||||
          addMsg(interpolate(gettext('Warning, the transaction from the note %s succeed, ' +
 | 
					          addMsg(interpolate(gettext('Warning, the transaction from the note %s succeed, ' +
 | 
				
			||||||
              'but the emitter note %s is very negative.', [source_alias, source_alias])), 'danger', 30000)
 | 
					              'but the emitter note %s is very negative.'), [source_alias, source_alias]), 'danger', 30000)
 | 
				
			||||||
        } else if (newBalance < 0) {
 | 
					        } else if (newBalance < 0) {
 | 
				
			||||||
          addMsg(interpolate(gettext('Warning, the transaction from the note %s succeed, ' +
 | 
					          addMsg(interpolate(gettext('Warning, the transaction from the note %s succeed, ' +
 | 
				
			||||||
              'but the emitter note %s is negative.', [source_alias, source_alias])), 'warning', 30000)
 | 
					              'but the emitter note %s is negative.'), [source_alias, source_alias]), 'warning', 30000)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (source.membership && source.membership.date_end < new Date().toISOString()) {
 | 
					        if (source.membership && source.membership.date_end < new Date().toISOString()) {
 | 
				
			||||||
          addMsg(interpolate(gettext('Warning, the emitter note %s is no more a BDE member.', [source_alias])), 'danger', 30000)
 | 
					          addMsg(interpolate(gettext('Warning, the emitter note %s is no more a BDE member.'), [source_alias]),
 | 
				
			||||||
 | 
					              'danger', 30000)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      reset()
 | 
					      reset()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3024,7 +3024,9 @@
 | 
				
			|||||||
				24,
 | 
									24,
 | 
				
			||||||
				25,
 | 
									25,
 | 
				
			||||||
				26,
 | 
									26,
 | 
				
			||||||
				27
 | 
									27,
 | 
				
			||||||
 | 
									30,
 | 
				
			||||||
 | 
									33
 | 
				
			||||||
			]
 | 
								]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 
 | 
				
			|||||||
 Submodule apps/scripts updated: dbe7bf6591...8ec7d68a16
									
								
							@@ -381,9 +381,14 @@ class SogeCredit(models.Model):
 | 
				
			|||||||
            tr.valid = True
 | 
					            tr.valid = True
 | 
				
			||||||
            tr.created_at = timezone.now()
 | 
					            tr.created_at = timezone.now()
 | 
				
			||||||
            tr.save()
 | 
					            tr.save()
 | 
				
			||||||
        self.credit_transaction.valid = False
 | 
					        if self.credit_transaction:
 | 
				
			||||||
        self.credit_transaction.reason += " (invalide)"
 | 
					            # If the soge credit is deleted while the user is not validated yet,
 | 
				
			||||||
        self.credit_transaction.save()
 | 
					            # there is not credit transaction.
 | 
				
			||||||
 | 
					            # There is a credit transaction iff the user declares that no bank account
 | 
				
			||||||
 | 
					            # was opened after the validation of the account.
 | 
				
			||||||
 | 
					            self.credit_transaction.valid = False
 | 
				
			||||||
 | 
					            self.credit_transaction.reason += " (invalide)"
 | 
				
			||||||
 | 
					            self.credit_transaction.save()
 | 
				
			||||||
        super().delete(**kwargs)
 | 
					        super().delete(**kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										18
									
								
								docker_ci/Dockerfile.37
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								docker_ci/Dockerfile.37
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					FROM debian:buster-backports
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LABEL maintainer="otthorn@crans.org"
 | 
				
			||||||
 | 
					LABEL description="Debian Buster backports image with django and tox \
 | 
				
			||||||
 | 
					installed for testing purposes"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN apt-get update \
 | 
				
			||||||
 | 
					        && apt-get install --no-install-recommends -t buster-backports -y \
 | 
				
			||||||
 | 
					        python3-django python3-django-crispy-forms \
 | 
				
			||||||
 | 
					        python3-django-extensions python3-django-filters \
 | 
				
			||||||
 | 
							python3-django-polymorphic \
 | 
				
			||||||
 | 
					        python3-djangorestframework python3-django-oauth-toolkit \
 | 
				
			||||||
 | 
							python3-psycopg2 python3-pil \
 | 
				
			||||||
 | 
					        python3-babel python3-lockfile python3-pip python3-phonenumbers \
 | 
				
			||||||
 | 
							python3-memcache \
 | 
				
			||||||
 | 
					        python3-bs4 python3-setuptools tox texlive-xetex \
 | 
				
			||||||
 | 
							&&  apt-get clean \
 | 
				
			||||||
 | 
							&& rm -rf /var/lib/apt/lists/*
 | 
				
			||||||
							
								
								
									
										22
									
								
								docker_ci/Dockerfile.38
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								docker_ci/Dockerfile.38
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					FROM ubuntu:20.04
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LABEL maintainer="otthorn@crans.org"
 | 
				
			||||||
 | 
					LABEL description="Ubuntu 20.04 image with django and tox \
 | 
				
			||||||
 | 
					installed for testing purposes"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# fix tzdata prompt
 | 
				
			||||||
 | 
					RUN ln -sf /usr/share/zoneinfo/Europe/Paris /etc/localtime && echo Europe/Paris > /etc/timezone
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN apt-get update \
 | 
				
			||||||
 | 
					        && apt-get install --no-install-recommends -y \
 | 
				
			||||||
 | 
					        python3-django python3-django-crispy-forms \
 | 
				
			||||||
 | 
					        python3-django-extensions python3-django-filters \
 | 
				
			||||||
 | 
							python3-django-polymorphic \
 | 
				
			||||||
 | 
					        python3-djangorestframework python3-django-oauth-toolkit \
 | 
				
			||||||
 | 
							python3-psycopg2 python3-pil \
 | 
				
			||||||
 | 
					        python3-babel python3-lockfile python3-pip python3-phonenumbers \
 | 
				
			||||||
 | 
							python3-memcache \
 | 
				
			||||||
 | 
					        python3-bs4 python3-setuptools tox texlive-xetex \
 | 
				
			||||||
 | 
							&&  apt-get clean \
 | 
				
			||||||
 | 
							&& rm -rf /var/lib/apt/lists/*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										18
									
								
								docker_ci/Dockerfile.39
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								docker_ci/Dockerfile.39
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					FROM debian:bullseye
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LABEL maintainer="otthorn@crans.org"
 | 
				
			||||||
 | 
					LABEL description="Debian Bulleye image with django and tox \
 | 
				
			||||||
 | 
					installed for testing purposes"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN apt-get update \
 | 
				
			||||||
 | 
					        && apt-get install --no-install-recommends -y \
 | 
				
			||||||
 | 
					        python3-django python3-django-crispy-forms \
 | 
				
			||||||
 | 
					        python3-django-extensions python3-django-filters \
 | 
				
			||||||
 | 
							python3-django-polymorphic \
 | 
				
			||||||
 | 
					        python3-djangorestframework python3-django-oauth-toolkit \
 | 
				
			||||||
 | 
							python3-psycopg2 python3-pil \
 | 
				
			||||||
 | 
					        python3-babel python3-lockfile python3-pip python3-phonenumbers \
 | 
				
			||||||
 | 
							python3-memcache \
 | 
				
			||||||
 | 
					        python3-bs4 python3-setuptools tox texlive-xetex \
 | 
				
			||||||
 | 
							&&  apt-get clean \
 | 
				
			||||||
 | 
							&& rm -rf /var/lib/apt/lists/*
 | 
				
			||||||
							
								
								
									
										10
									
								
								docker_ci/Dockerfile.ansiblelint
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								docker_ci/Dockerfile.ansiblelint
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					FROM python:3.9-alpine
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LABEL maintainer="otthorn@crans.org"
 | 
				
			||||||
 | 
					LABEL description="Alpine image with ansible-lint and yamllint \
 | 
				
			||||||
 | 
					installed for linting purposes"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN apk add --no-cache gcc musl-dev python3-dev libffi-dev openssl-dev cargo
 | 
				
			||||||
 | 
					RUN pip install --no-cache-dir "yamllint>=1.26.0,<2.0"
 | 
				
			||||||
 | 
					RUN pip install --no-cache-dir "ansible-lint==5.0.0"
 | 
				
			||||||
 | 
					RUN pip install --no-cache-dir "ansible>=2.10,<2.11"
 | 
				
			||||||
							
								
								
									
										8
									
								
								docker_ci/Dockerfile.tox
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								docker_ci/Dockerfile.tox
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					FROM alpine:3.13
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LABEL maintainer="otthorn@crans.org"
 | 
				
			||||||
 | 
					LABEL description="Alpine image with tox \
 | 
				
			||||||
 | 
					installed for linting purposes"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN apk --no-cache add py3-pip=20.3.4-r0
 | 
				
			||||||
 | 
					RUN pip install --no-cache-dir tox==3.22.0
 | 
				
			||||||
							
								
								
									
										21
									
								
								docker_ci/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								docker_ci/README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					# Docker CI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Ce dossier contient les images docker à construire pour la CI.  L'idée est
 | 
				
			||||||
 | 
					d'avoir une image pré-construire, au dessus laquel il y a besoin de faire
 | 
				
			||||||
 | 
					tourner uniquement les commandes qui nous intéresse. Cela permet notamment de
 | 
				
			||||||
 | 
					réduire drastiquement le temps que nécessite chaque test car seul la dernière
 | 
				
			||||||
 | 
					couche (layer) de l'image a besoin d'etre éxécuter.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Build les images
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Pour build les images il suffit de lancer les commandes suivantes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					cd docker_ci/
 | 
				
			||||||
 | 
					docker build -t nk20_ci_37 -f Dockerfile.37 .
 | 
				
			||||||
 | 
					docker build -t nk20_ci_38 -f Dockerfile.38 .
 | 
				
			||||||
 | 
					docker build -t nk20_ci_39 -f Dockerfile.39 .
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Elles sont acutellement build et disponible sur dockerhub
 | 
				
			||||||
 | 
					https://hub.docker.com/otthorn/nk20_ci_37
 | 
				
			||||||
		Reference in New Issue
	
	Block a user