Compare commits

..

8 Commits

Author SHA1 Message Date
Roberto Rosario
2de95b57d3 Fix translation file formatting
GitLab issue #579.

Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
2019-04-09 02:53:24 -04:00
Roberto Rosario
cd74f6f461 Merge remote-tracking branch 'origin/hotfix' into hotfix 2019-04-09 02:51:55 -04:00
Roberto Rosario
9e1b77c5fc Revert "Language and translation file updates"
This reverts commit fbf03788a2.
2019-04-09 02:51:30 -04:00
Roberto Rosario
fbf03788a2 Language and translation file updates
Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
2019-04-09 02:41:39 -04:00
Roberto Rosario
4ee11cd067 Language and translation file updates
Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
2019-04-09 01:46:59 -04:00
Roberto Rosario
ad84cf8cdb Make mimetype app translatable
Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
2019-04-09 00:53:17 -04:00
Roberto Rosario
d627e9713c Fix source text typo
Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
2019-04-09 00:51:41 -04:00
Roberto Rosario
80e5fd89e4 Update translation sources
Also update the translatable text template in document states
views module.

Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
2019-04-09 00:32:04 -04:00
6224 changed files with 254410 additions and 149471 deletions

View File

@@ -4,7 +4,8 @@ HISTORY.md
mayan/media mayan/media
db.sqlite* db.sqlite*
docker docker
!docker/rootfs !docker/etc
!docker/entrypoint.sh
!docker/version
./.* ./.*
docs docs

View File

@@ -1,3 +1,2 @@
[flake8] [flake8]
exclude = node_modules,static,templates ignore = E501
ignore = E501, N801, N802, N804, N805, N806

3
.gitignore vendored
View File

@@ -7,7 +7,6 @@
.coverage .coverage
.coverage.tox* .coverage.tox*
.idea/ .idea/
*.swp
.tox/ .tox/
.vagrant .vagrant
_build/ _build/
@@ -30,6 +29,4 @@ static_collected/
/venv/ /venv/
/venv3/ /venv3/
/whoosh_index/ /whoosh_index/
google_fonts/
node_modules/ node_modules/
docs/build/

View File

@@ -17,7 +17,7 @@ job_docker_build:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
script: script:
- docker build --pull -t "$CI_REGISTRY_IMAGE" -f docker/Dockerfile . - docker build --pull -t "$CI_REGISTRY_IMAGE" -f docker/Dockerfile .
- VERSION=`cat docker/rootfs/version` - VERSION=`cat docker/version`
- docker tag "$CI_REGISTRY_IMAGE" "$CI_REGISTRY_IMAGE:$VERSION" - docker tag "$CI_REGISTRY_IMAGE" "$CI_REGISTRY_IMAGE:$VERSION"
- docker run --rm "$CI_REGISTRY_IMAGE:$VERSION" run-tests - docker run --rm "$CI_REGISTRY_IMAGE:$VERSION" run-tests
- docker push "$CI_REGISTRY_IMAGE:$VERSION" - docker push "$CI_REGISTRY_IMAGE:$VERSION"
@@ -37,7 +37,7 @@ job_docker_push:
before_script: before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
script: script:
- VERSION=`cat docker/rootfs/version` - VERSION=`cat docker/version`
- docker pull "$CI_REGISTRY_IMAGE:$VERSION" - docker pull "$CI_REGISTRY_IMAGE:$VERSION"
- docker tag "$CI_REGISTRY_IMAGE:$VERSION" registry-1.docker.io/mayanedms/mayanedms:"$VERSION" - docker tag "$CI_REGISTRY_IMAGE:$VERSION" registry-1.docker.io/mayanedms/mayanedms:"$VERSION"
- docker tag "$CI_REGISTRY_IMAGE:$VERSION" registry-1.docker.io/mayanedms/mayanedms:latest - docker tag "$CI_REGISTRY_IMAGE:$VERSION" registry-1.docker.io/mayanedms/mayanedms:latest
@@ -63,7 +63,6 @@ job_docker_nightly:
only: only:
- nightly - nightly
- staging - staging
- /^clients\/.+$/
job_documentation_build: job_documentation_build:
stage: build_documentation stage: build_documentation
@@ -120,7 +119,7 @@ job_build_python:
- update-locale LANG=en_US.UTF-8 - update-locale LANG=en_US.UTF-8
- export LC_ALL=en_US.UTF-8 - export LC_ALL=en_US.UTF-8
- pip install -r requirements/build.txt - pip install -r requirements/build.txt
- make python-wheel - make wheel
only: only:
- releases/all - releases/all
- releases/python - releases/python
@@ -141,7 +140,7 @@ job_push_python:
.test_base: &test_base .test_base: &test_base
stage: test stage: test
image: ubuntu:18.04 image: ubuntu:16.04
cache: cache:
paths: paths:
- ~/.cache/pip/ - ~/.cache/pip/
@@ -153,15 +152,15 @@ job_push_python:
- locale-gen en_US.UTF-8 - locale-gen en_US.UTF-8
- update-locale LANG=en_US.UTF-8 - update-locale LANG=en_US.UTF-8
- export LC_ALL=en_US.UTF-8 - export LC_ALL=en_US.UTF-8
- apt-get install -qq curl exiftool gcc ghostscript gnupg1 graphviz libfuse2 libjpeg-dev libmagic1 libpng-dev libtiff-dev poppler-utils libreoffice poppler-utils python-dev python-pip tesseract-ocr tesseract-ocr-deu - apt-get install -qq curl gcc ghostscript gpgv gnupg graphviz libfuse2 libjpeg-dev libmagic1 libpng-dev libtiff-dev poppler-utils libreoffice poppler-utils python-dev python-pip tesseract-ocr tesseract-ocr-deu
- pip install -r requirements.txt -r requirements/testing-base.txt - pip install -r requirements/testing.txt
only: only:
- releases/all - releases/all
- releases/docker - releases/docker
- releases/python - releases/python
- master
- staging - staging
- nightly - nightly
- /^clients\/.+$/
test-mysql: test-mysql:
<<: *test_base <<: *test_base
@@ -172,7 +171,7 @@ test-mysql:
- mysql:8.0.3 - mysql:8.0.3
script: script:
- apt-get install -qq libmysqlclient-dev mysql-client - apt-get install -qq libmysqlclient-dev mysql-client
- pip install mysqlclient - pip install mysql-python
- mysql -h"$MYSQL_PORT_3306_TCP_ADDR" -P"$MYSQL_PORT_3306_TCP_PORT" -uroot -p"$MYSQL_ENV_MYSQL_ROOT_PASSWORD" -e "set global character_set_server=utf8mb4;" - mysql -h"$MYSQL_PORT_3306_TCP_ADDR" -P"$MYSQL_PORT_3306_TCP_PORT" -uroot -p"$MYSQL_ENV_MYSQL_ROOT_PASSWORD" -e "set global character_set_server=utf8mb4;"
- python manage.py test --mayan-apps --settings=mayan.settings.testing.gitlab-ci.db_mysql --nomigrations - python manage.py test --mayan-apps --settings=mayan.settings.testing.gitlab-ci.db_mysql --nomigrations
tags: tags:

View File

@@ -19,12 +19,6 @@ source_lang = en
source_file = mayan/apps/authentication/locale/en/LC_MESSAGES/django.po source_file = mayan/apps/authentication/locale/en/LC_MESSAGES/django.po
type = PO type = PO
[mayan-edms.autoadmin-2-0]
file_filter = mayan/apps/autoadmin/locale/<lang>/LC_MESSAGES/django.po
source_lang = en
source_file = mayan/apps/autoadmin/locale/en/LC_MESSAGES/django.po
type = PO
[mayan-edms.cabinets-2-0] [mayan-edms.cabinets-2-0]
file_filter = mayan/apps/cabinets/locale/<lang>/LC_MESSAGES/django.po file_filter = mayan/apps/cabinets/locale/<lang>/LC_MESSAGES/django.po
source_lang = en source_lang = en
@@ -49,24 +43,18 @@ source_lang = en
source_file = mayan/apps/converter/locale/en/LC_MESSAGES/django.po source_file = mayan/apps/converter/locale/en/LC_MESSAGES/django.po
type = PO type = PO
[mayan-edms.dashboards-2-0]
file_filter = mayan/apps/dashboards/locale/<lang>/LC_MESSAGES/django.po
source_lang = en
source_file = mayan/apps/dashboards/locale/en/LC_MESSAGES/django.po
type = PO
[mayan-edms.dependencies-3-0]
file_filter = mayan/apps/dependencies/locale/<lang>/LC_MESSAGES/django.po
source_lang = en
source_file = mayan/apps/dependencies/locale/en/LC_MESSAGES/django.po
type = PO
[mayan-edms.django_gpg-2-0] [mayan-edms.django_gpg-2-0]
file_filter = mayan/apps/django_gpg/locale/<lang>/LC_MESSAGES/django.po file_filter = mayan/apps/django_gpg/locale/<lang>/LC_MESSAGES/django.po
source_lang = en source_lang = en
source_file = mayan/apps/django_gpg/locale/en/LC_MESSAGES/django.po source_file = mayan/apps/django_gpg/locale/en/LC_MESSAGES/django.po
type = PO type = PO
[mayan-edms.documents-2-0]
file_filter = mayan/apps/documents/locale/<lang>/LC_MESSAGES/django.po
source_lang = en
source_file = mayan/apps/documents/locale/en/LC_MESSAGES/django.po
type = PO
[mayan-edms.document_comments-2-0] [mayan-edms.document_comments-2-0]
file_filter = mayan/apps/document_comments/locale/<lang>/LC_MESSAGES/django.po file_filter = mayan/apps/document_comments/locale/<lang>/LC_MESSAGES/django.po
source_lang = en source_lang = en
@@ -97,12 +85,6 @@ source_lang = en
source_file = mayan/apps/document_states/locale/en/LC_MESSAGES/django.po source_file = mayan/apps/document_states/locale/en/LC_MESSAGES/django.po
type = PO type = PO
[mayan-edms.documents-2-0]
file_filter = mayan/apps/documents/locale/<lang>/LC_MESSAGES/django.po
source_lang = en
source_file = mayan/apps/documents/locale/en/LC_MESSAGES/django.po
type = PO
[mayan-edms.dynamic_search-2-0] [mayan-edms.dynamic_search-2-0]
file_filter = mayan/apps/dynamic_search/locale/<lang>/LC_MESSAGES/django.po file_filter = mayan/apps/dynamic_search/locale/<lang>/LC_MESSAGES/django.po
source_lang = en source_lang = en
@@ -115,12 +97,6 @@ source_lang = en
source_file = mayan/apps/events/locale/en/LC_MESSAGES/django.po source_file = mayan/apps/events/locale/en/LC_MESSAGES/django.po
type = PO type = PO
[mayan-edms.file_metadata-3-0]
file_filter = mayan/apps/file_metadata/locale/<lang>/LC_MESSAGES/django.po
source_lang = en
source_file = mayan/apps/file_metadata/locale/en/LC_MESSAGES/django.po
type = PO
[mayan-edms.linking-2-0] [mayan-edms.linking-2-0]
file_filter = mayan/apps/linking/locale/<lang>/LC_MESSAGES/django.po file_filter = mayan/apps/linking/locale/<lang>/LC_MESSAGES/django.po
source_lang = en source_lang = en
@@ -151,6 +127,12 @@ source_lang = en
source_file = mayan/apps/mirroring/locale/en/LC_MESSAGES/django.po source_file = mayan/apps/mirroring/locale/en/LC_MESSAGES/django.po
type = PO type = PO
[mayan-edms.mimetype-2-0]
file_filter = mayan/apps/mimetype/locale/<lang>/LC_MESSAGES/django.po
source_lang = en
source_file = mayan/apps/mimetype/locale/en/LC_MESSAGES/django.po
type = PO
[mayan-edms.motd-2-0] [mayan-edms.motd-2-0]
file_filter = mayan/apps/motd/locale/<lang>/LC_MESSAGES/django.po file_filter = mayan/apps/motd/locale/<lang>/LC_MESSAGES/django.po
source_lang = en source_lang = en
@@ -169,12 +151,6 @@ source_lang = en
source_file = mayan/apps/permissions/locale/en/LC_MESSAGES/django.po source_file = mayan/apps/permissions/locale/en/LC_MESSAGES/django.po
type = PO type = PO
[mayan-edms.platform-2-0]
file_filter = mayan/apps/platform/locale/<lang>/LC_MESSAGES/django.po
source_lang = en
source_file = mayan/apps/platform/locale/en/LC_MESSAGES/django.po
type = PO
[mayan-edms.rest_api-2-0] [mayan-edms.rest_api-2-0]
file_filter = mayan/apps/rest_api/locale/<lang>/LC_MESSAGES/django.po file_filter = mayan/apps/rest_api/locale/<lang>/LC_MESSAGES/django.po
source_lang = en source_lang = en

View File

@@ -1,14 +0,0 @@
- Use Select2 widget for the document type selection form.
- Update source column matching to be additive and not exclusive.
- Add two columns to show the number of documents per workflow and
workflow state.
- Sort module.
- Add link to sort individual indexes.
- Support exclusions from source columns.
- Improve source column exclusion. Improve for model subclasses in partial querysets.
- Add sortable index instance label column.
- Add rectangle drawing transformation.
- Redactions app.
- Remove duplicated trashed document preview.
- Add label to trashed date and time document source column.
- Tag created event fix.

View File

@@ -23,7 +23,7 @@ with deployments, webservers, cloud providers, etc.
Code Code
---- ----
1. Complete and mail, or scan and email the corresponding Contributor Assignment Agreement: [Mayan EDMS Individual Contributor Assignment Agreement](https://gitlab.com/mayan-edms/mayan-edms/blob/master/docs/chapters/caa_individual.rst) or [Mayan EDMS Entity Contributor Assignment Agreement](https://gitlab.com/mayan-edms/mayan-edms/blob/master/docs/chapters/caa_entity.rst). 1. Complete and mail, or scan and email the corresponding Contributor Assignment Agreement: [Mayan EDMS Individual Contributor Assignment Agreement](https://docs.mayan-edms.com/topics/caa_individual.rst) or [Mayan EDMS Entity Contributor Assignment Agreement](https://docs.mayan-edms.com/topics/topics/caa_entity.rst).
1. Fork [the repository](http://gitlab.com/mayan-edms/mayan-edms). 1. Fork [the repository](http://gitlab.com/mayan-edms/mayan-edms).
1. Choose the version for which you want to develop. The code is divided in the 1. Choose the version for which you want to develop. The code is divided in the
following branches: following branches:

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
Copyright 2011 Roberto Rosario Copyright 2011-2018 Roberto Rosario
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

View File

@@ -1,6 +1,3 @@
include README.md LICENSE HISTORY.rst mayan/LICENSE include README.md LICENSE HISTORY.rst mayan/LICENSE
recursive-include mayan/apps *.txt *.html *.css *.ico *.png *.jpg *.js *.mo *.ttf *.woff *.woff2 *.gif *.eot *.svg *.doc *.pdf *.tiff *.sig *.asc *.gpg *.zip *.tar *.gz *.bz2 *.tmpl recursive-include mayan/apps *.txt *.html *.css *.ico *.png *.jpg *.js *.po *.mo *.ttf *.woff *.woff2 *.gif *.eot *.svg *.doc *.pdf *.tiff *.sig *.asc *.gpg *.zip *.tar *.gz *.bz2 package.json
global-exclude mayan/settings/local.py *.po global-exclude mayan/settings/local.py mayan/settings/travis/* mayan/media/*
prune mayan/apps/*/static/*/node_modules/*
prune mayan/settings/travis/*
prune mayan/media/*

169
Makefile
View File

@@ -1,20 +1,64 @@
.PHONY: clean-pyc clean-build .PHONY: clean-pyc clean-build
help: help: docker-help
@echo "Usage: make <target>\n" @echo
@awk 'BEGIN {FS = ":.*##"} /^[a-zA-Z_-]+:.*?## / { printf " * %-40s -%s\n", $$1, $$2 }' $(MAKEFILE_LIST)|sort @echo "**** Main makefile ****"
@echo "clean-build - Remove build artifacts."
@echo "clean-pyc - Remove Python artifacts."
@echo "clean - Remove Python and build artifacts."
@echo "generate-setup - Create and updated setup.py"
@echo "check-readme - Checks validity of the README.rst file for PyPI publication."
@echo "check-missing_migrations - Make sure all models have proper migrations."
@echo "test-all - Run all tests."
@echo "test MODULE=<python module name> - Run tests for a single app, module or test class."
@echo "test-with-postgres-all - Run all tests against a Postgres database container."
@echo "test-postgres MODULE=<python module name> - Run tests for a single app, module or test class against a Postgres database container."
@echo "test-with-mysql-all - Run all tests against a MySQL database container."
@echo "test-mysql MODULE=<python module name> - Run tests for a single app, module or test class against a MySQL database container."
@echo "test-with-oracle-all - Run all tests against a Oracle database container."
@echo "test-oracle MODULE=<python module name> - Run tests for a single app, module or test class against a Oracle database container."
@echo "docs-serve - Run the livehtml documentation generator."
@echo "translations-make - Refresh all translation files."
@echo "translations-compile - Compile all translation files."
@echo "translations-push - Upload all translation files to Transifex."
@echo "translations-pull - Download all translation files from Transifex."
@echo "sdist - Build the source distribution package."
@echo "wheel - Build the wheel distribution package."
@echo "release - Package (sdist and wheel) and upload a release."
@echo "test-release - Package (sdist and wheel) and upload to the PyPI test server."
@echo "release-test-via-docker-ubuntu - Package (sdist and wheel) and upload to the PyPI test server using an Ubuntu Docker builder."
@echo "release-via-docker-ubuntu - Package (sdist and wheel) and upload to PyPI using an Ubuntu Docker builder."
@echo "test-sdist-via-docker-ubuntu - Make an sdist packange and test it using an Ubuntu Docker container."
@echo "test-wheel-via-docker-ubuntu - Make a wheel package and test it using an Ubuntu Docker container."
@echo "runserver - Run the development server."
@echo "runserver_plus - Run the Django extension's development server."
@echo "shell_plus - Run the shell_plus command."
@echo "test-with-docker-services-on - Launch and initialize production-like services using Docker (Postgres and Redis)."
@echo "test-with-docker-services-off - Stop and delete the Docker production-like services."
@echo "test-with-docker-frontend - Launch a front end instance that uses the production-like services."
@echo "test-with-docker-worker - Launch a worker instance that uses the production-like services."
@echo "docker-mysql-on - Launch and initialize a MySQL Docker container."
@echo "docker-mysql-off - Stop and delete the MySQL Docker container."
@echo "docker-postgres-on - Launch and initialize a PostgreSQL Docker container."
@echo "docker-postgres-off - Stop and delete the PostgreSQL Docker container."
@echo "safety-check - Run a package safety check."
# Cleaning # Cleaning
clean: ## Remove Python and build artifacts.
clean: clean-build clean-pyc clean: clean-build clean-pyc
clean-build: ## Remove build artifacts. clean-build:
rm -fr build/ rm -fr build/
rm -fr dist/ rm -fr dist/
rm -fr *.egg-info rm -fr *.egg-info
clean-pyc: ## Remove Python artifacts. clean-pyc:
find . -name '*.pyc' -exec rm -f {} + find . -name '*.pyc' -exec rm -f {} +
find . -name '*.pyo' -exec rm -f {} + find . -name '*.pyo' -exec rm -f {} +
find . -name '*~' -exec rm -f {} + find . -name '*~' -exec rm -f {} +
@@ -22,29 +66,25 @@ clean-pyc: ## Remove Python artifacts.
# Testing # Testing
test: clean-pyc test:
test: ## MODULE=<python module name> - Run tests for a single app, module or test class.
./manage.py test $(MODULE) --settings=mayan.settings.testing.development --nomigrations $(ARGUMENTS) ./manage.py test $(MODULE) --settings=mayan.settings.testing.development --nomigrations $(ARGUMENTS)
test-all: ## Run all tests. test-all:
test-all: clean-pyc
./manage.py test --mayan-apps --settings=mayan.settings.testing.development --nomigrations $(ARGUMENTS) ./manage.py test --mayan-apps --settings=mayan.settings.testing.development --nomigrations $(ARGUMENTS)
test-launch-postgres: test-launch-postgres:
@docker rm -f test-postgres || true @docker rm -f test-postgres || true
@docker volume rm test-postgres || true @docker volume rm test-postgres || true
docker run -d --name test-postgres -p 5432:5432 -v test-postgres:/var/lib/postgresql/data healthcheck/postgres docker run -d --name test-postgres -p 5432:5432 -v test-postgres:/var/lib/postgresql/data healthcheck/postgres
sudo apt-get install -q libpq-dev sudo apt-get install -qq libpq-dev
pip install psycopg2 pip install psycopg2
while ! docker inspect --format='{{json .State.Health}}' test-postgres|grep 'Status":"healthy"'; do sleep 1; done while ! docker inspect --format='{{json .State.Health}}' test-postgres|grep 'Status":"healthy"'; do sleep 1; done
test-with-postgres: ## MODULE=<python module name> - Run tests for a single app, module or test class against a Postgres database container.
test-with-postgres: test-launch-postgres test-with-postgres: test-launch-postgres
./manage.py test $(MODULE) --settings=mayan.settings.testing.docker.db_postgres --nomigrations ./manage.py test $(MODULE) --settings=mayan.settings.testing.docker.db_postgres --nomigrations
@docker rm -f test-postgres || true @docker rm -f test-postgres || true
@docker volume rm test-postgres || true @docker volume rm test-postgres || true
test-with-postgres-all: ## Run all tests against a Postgres database container.
test-with-postgres-all: test-launch-postgres test-with-postgres-all: test-launch-postgres
./manage.py test --mayan-apps --settings=mayan.settings.testing.docker.db_postgres --nomigrations ./manage.py test --mayan-apps --settings=mayan.settings.testing.docker.db_postgres --nomigrations
@docker rm -f test-postgres || true @docker rm -f test-postgres || true
@@ -54,19 +94,16 @@ test-launch-mysql:
@docker rm -f test-mysql || true @docker rm -f test-mysql || true
@docker volume rm test-mysql || true @docker volume rm test-mysql || true
docker run -d --name test-mysql -p 3306:3306 -e MYSQL_ALLOW_EMPTY_PASSWORD=True -e MYSQL_DATABASE=mayan -v test-mysql:/var/lib/mysql healthcheck/mysql docker run -d --name test-mysql -p 3306:3306 -e MYSQL_ALLOW_EMPTY_PASSWORD=True -e MYSQL_DATABASE=mayan -v test-mysql:/var/lib/mysql healthcheck/mysql
sudo apt-get install -q libmysqlclient-dev mysql-client sudo apt-get install -qq libmysqlclient-dev mysql-client
pip install mysqlclient pip install mysql-python
while ! docker inspect --format='{{json .State.Health}}' test-mysql|grep 'Status":"healthy"'; do sleep 1; done while ! docker inspect --format='{{json .State.Health}}' test-mysql|grep 'Status":"healthy"'; do sleep 1; done
mysql -h 127.0.0.1 -P 3306 -uroot -e "set global character_set_server=utf8mb4;" mysql -h 127.0.0.1 -P 3306 -uroot -e "set global character_set_server=utf8mb4;"
test-with-mysql: ## MODULE=<python module name> - Run tests for a single app, module or test class against a MySQL database container.
test-with-mysql: test-launch-mysql test-with-mysql: test-launch-mysql
./manage.py test $(MODULE) --settings=mayan.settings.testing.docker.db_mysql --nomigrations ./manage.py test $(MODULE) --settings=mayan.settings.testing.docker.db_mysql --nomigrations
@docker rm -f test-mysql || true @docker rm -f test-mysql || true
@docker volume rm test-mysql || true @docker volume rm test-mysql || true
test-with-mysql-all: ## Run all tests against a MySQL database container.
test-with-mysql-all: test-launch-mysql test-with-mysql-all: test-launch-mysql
./manage.py test --mayan-apps --settings=mayan.settings.testing.docker.db_mysql --nomigrations ./manage.py test --mayan-apps --settings=mayan.settings.testing.docker.db_mysql --nomigrations
@docker rm -f test-mysql || true @docker rm -f test-mysql || true
@@ -81,13 +118,11 @@ test-launch-oracle:
while ! nc -z 127.0.0.1 49161; do sleep 1; done while ! nc -z 127.0.0.1 49161; do sleep 1; done
sleep 10 sleep 10
test-with-oracle: ## MODULE=<python module name> - Run tests for a single app, module or test class against a Oracle database container.
test-with-oracle: test-launch-oracle test-with-oracle: test-launch-oracle
./manage.py test $(MODULE) --settings=mayan.settings.testing.docker.db_oracle --nomigrations ./manage.py test $(MODULE) --settings=mayan.settings.testing.docker.db_oracle --nomigrations
@docker rm -f test-oracle || true @docker rm -f test-oracle || true
@docker volume rm test-oracle || true @docker volume rm test-oracle || true
test-with-oracle-all: ## Run all tests against a Oracle database container.
test-with-oracle-all: test-launch-oracle test-with-oracle-all: test-launch-oracle
./manage.py test --mayan-apps --settings=mayan.settings.testing.docker.db_oracle --nomigrations ./manage.py test --mayan-apps --settings=mayan.settings.testing.docker.db_oracle --nomigrations
@docker rm -f test-oracle || true @docker rm -f test-oracle || true
@@ -95,56 +130,58 @@ test-with-oracle-all: test-launch-oracle
# Documentation # Documentation
docs-serve: ## Run the livehtml documentation generator. docs-serve:
cd docs;make livehtml cd docs;make livehtml
docs-spellcheck: ## Spellcheck the documentation. docs-spellcheck:
sphinx-build -b spelling -d docs/_build/ docs docs/_build/spelling sphinx-build -b spelling -d docs/_build/ docs docs/_build/spelling
# Translations # Translations
translations-make: ## Refresh all translation files. translations-make:
contrib/scripts/process_messages.py -m contrib/scripts/process_messages.py -m
translations-compile: ## Compile all translation files. translations-compile:
contrib/scripts/process_messages.py -c contrib/scripts/process_messages.py -c
translations-push: ## Upload all translation files to Transifex. translations-push:
tx push -s tx push -s
translations-pull: ## Download all translation files from Transifex. translations-pull:
tx pull -f tx pull -f
generate-setup:
@./generate_setup.py
@echo "Complete."
# Releases # Releases
increase-version: ## Increase the version number of the entire project's files. increase-version:
@VERSION=`grep "__version__ =" mayan/__init__.py| cut -d\' -f 2|./increase_version.py - $(PART)`; \ @VERSION=`grep "__version__ =" mayan/__init__.py| cut -d\' -f 2|./increase_version.py - $(PART)`; \
BUILD=`echo $$VERSION|awk '{split($$VERSION,a,"."); printf("0x%02d%02d%02d\n", a[1],a[2], a[3])}'`; \ BUILD=`echo $$VERSION|awk '{split($$VERSION,a,"."); printf("0x%02d%02d%02d\n", a[1],a[2], a[3])}'`; \
sed -i -e "s/__build__ = 0x[0-9]*/__build__ = $${BUILD}/g" mayan/__init__.py; \ sed -i -e "s/__build__ = 0x[0-9]*/__build__ = $${BUILD}/g" mayan/__init__.py; \
sed -i -e "s/__version__ = '[0-9\.]*'/__version__ = '$${VERSION}'/g" mayan/__init__.py; \ sed -i -e "s/__version__ = '[0-9\.]*'/__version__ = '$${VERSION}'/g" mayan/__init__.py; \
echo $$VERSION > docker/rootfs/version echo $$VERSION > docker/version
make generate-setup make generate-setup
python-test-release: ## Package (sdist and wheel) and upload to the PyPI test server. test-release: clean wheel
python-test-release: clean wheel
twine upload dist/* -r testpypi twine upload dist/* -r testpypi
@echo "Test with: pip install -i https://testpypi.python.org/pypi mayan-edms" @echo "Test with: pip install -i https://testpypi.python.org/pypi mayan-edms"
python-release: ## Package (sdist and wheel) and upload a release. release: clean wheel
python-release: clean python-wheel
twine upload dist/* -r pypi twine upload dist/* -r pypi
python-sdist: ## Build the source distribution package. sdist: clean
python-sdist: clean
python setup.py sdist python setup.py sdist
ls -l dist ls -l dist
python-wheel: ## Build the wheel distribution package. wheel: clean sdist
python-wheel: clean python-sdist
pip wheel --no-index --no-deps --wheel-dir dist dist/*.tar.gz pip wheel --no-index --no-deps --wheel-dir dist dist/*.tar.gz
ls -l dist ls -l dist
python-release-test-via-docker-ubuntu: ## Package (sdist and wheel) and upload to the PyPI test server using an Ubuntu Docker builder. release-test-via-docker-ubuntu:
docker run --rm --name mayan_release -v $(HOME):/host_home:ro -v `pwd`:/host_source -w /source ubuntu:16.04 /bin/bash -c "\ docker run --rm --name mayan_release -v $(HOME):/host_home:ro -v `pwd`:/host_source -w /source ubuntu:16.04 /bin/bash -c "\
echo "LC_ALL=\"en_US.UTF-8\"" >> /etc/default/locale && \ echo "LC_ALL=\"en_US.UTF-8\"" >> /etc/default/locale && \
locale-gen en_US.UTF-8 && \ locale-gen en_US.UTF-8 && \
@@ -157,7 +194,7 @@ python-release-test-via-docker-ubuntu: ## Package (sdist and wheel) and upload t
cp -r /host_home/.pypirc ~/.pypirc && \ cp -r /host_home/.pypirc ~/.pypirc && \
make test-release" make test-release"
python-release-via-docker-ubuntu: ## Package (sdist and wheel) and upload to PyPI using an Ubuntu Docker builder. release-via-docker-ubuntu:
docker run --rm --name mayan_release -v $(HOME):/host_home:ro -v `pwd`:/host_source -w /source ubuntu:16.04 /bin/bash -c "\ docker run --rm --name mayan_release -v $(HOME):/host_home:ro -v `pwd`:/host_source -w /source ubuntu:16.04 /bin/bash -c "\
apt-get update && \ apt-get update && \
apt-get -y install locales && \ apt-get -y install locales && \
@@ -171,7 +208,7 @@ python-release-via-docker-ubuntu: ## Package (sdist and wheel) and upload to PyP
cp -r /host_home/.pypirc ~/.pypirc && \ cp -r /host_home/.pypirc ~/.pypirc && \
make release" make release"
test-sdist-via-docker-ubuntu: ## Make an sdist package and test it using an Ubuntu Docker container. test-sdist-via-docker-ubuntu:
docker run --rm --name mayan_sdist_test -v $(HOME):/host_home:ro -v `pwd`:/host_source -w /source ubuntu:16.04 /bin/bash -c "\ docker run --rm --name mayan_sdist_test -v $(HOME):/host_home:ro -v `pwd`:/host_source -w /source ubuntu:16.04 /bin/bash -c "\
cp -r /host_source/* . && \ cp -r /host_source/* . && \
echo "LC_ALL=\"en_US.UTF-8\"" >> /etc/default/locale && \ echo "LC_ALL=\"en_US.UTF-8\"" >> /etc/default/locale && \
@@ -184,7 +221,7 @@ test-sdist-via-docker-ubuntu: ## Make an sdist package and test it using an Ubun
make sdist-test-suit \ make sdist-test-suit \
" "
test-wheel-via-docker-ubuntu: ## Make a wheel package and test it using an Ubuntu Docker container. test-wheel-via-docker-ubuntu:
docker run --rm --name mayan_wheel_test -v $(HOME):/host_home:ro -v `pwd`:/host_source -w /source ubuntu:16.04 /bin/bash -c "\ docker run --rm --name mayan_wheel_test -v $(HOME):/host_home:ro -v `pwd`:/host_source -w /source ubuntu:16.04 /bin/bash -c "\
cp -r /host_source/* . && \ cp -r /host_source/* . && \
echo "LC_ALL=\"en_US.UTF-8\"" >> /etc/default/locale && \ echo "LC_ALL=\"en_US.UTF-8\"" >> /etc/default/locale && \
@@ -197,7 +234,7 @@ test-wheel-via-docker-ubuntu: ## Make a wheel package and test it using an Ubunt
make wheel-test-suit \ make wheel-test-suit \
" "
python-sdist-test-suit: sdist sdist-test-suit: sdist
rm -f -R _virtualenv rm -f -R _virtualenv
virtualenv _virtualenv virtualenv _virtualenv
sh -c '\ sh -c '\
@@ -208,7 +245,7 @@ python-sdist-test-suit: sdist
_virtualenv/bin/mayan-edms.py test --mayan-apps \ _virtualenv/bin/mayan-edms.py test --mayan-apps \
' '
python-wheel-test-suit: wheel wheel-test-suit: wheel
rm -f -R _virtualenv rm -f -R _virtualenv
virtualenv _virtualenv virtualenv _virtualenv
sh -c '\ sh -c '\
@@ -219,30 +256,18 @@ python-wheel-test-suit: wheel
_virtualenv/bin/mayan-edms.py test --mayan-apps \ _virtualenv/bin/mayan-edms.py test --mayan-apps \
' '
generate-setup: ## Create and update the setup.py file.
generate-setup: generate-requirements
@./generate_setup.py
@echo "Complete."
generate-requirements: ## Generate all requirements files from the project depedency declarations.
@./manage.py generaterequirements build > requirements/build.txt
@./manage.py generaterequirements development > requirements/development.txt
@./manage.py generaterequirements testing > requirements/testing-base.txt
@./manage.py generaterequirements production --exclude=django > requirements/base.txt
@./manage.py generaterequirements production --only=django > requirements/common.txt
# Dev server # Dev server
runserver: ## Run the development server. runserver:
./manage.py runserver --settings=mayan.settings.development $(ADDRPORT) ./manage.py runserver --settings=mayan.settings.development $(ADDRPORT)
runserver_plus: ## Run the Django extension's development server. runserver_plus:
./manage.py runserver_plus --settings=mayan.settings.development $(ADDRPORT) ./manage.py runserver_plus --settings=mayan.settings.development $(ADDRPORT)
shell_plus: ## Run the shell_plus command. shell_plus:
./manage.py shell_plus --settings=mayan.settings.development ./manage.py shell_plus --settings=mayan.settings.development
test-with-docker-services-on: ## Launch and initialize production-like services using Docker (Postgres and Redis). test-with-docker-services-on:
docker run -d --name redis -p 6379:6379 redis docker run -d --name redis -p 6379:6379 redis
docker run -d --name postgres -p 5432:5432 postgres docker run -d --name postgres -p 5432:5432 postgres
while ! nc -z 127.0.0.1 6379; do sleep 1; done while ! nc -z 127.0.0.1 6379; do sleep 1; done
@@ -250,45 +275,45 @@ test-with-docker-services-on: ## Launch and initialize production-like services
sleep 4 sleep 4
./manage.py initialsetup --settings=mayan.settings.staging.docker ./manage.py initialsetup --settings=mayan.settings.staging.docker
test-with-docker-services-off: ## Stop and delete the Docker production-like services. test-with-docker-services-off:
docker stop postgres redis docker stop postgres redis
docker rm postgres redis docker rm postgres redis
test-with-docker-frontend: ## Launch a front end instance that uses the production-like services. test-with-docker-frontend:
./manage.py runserver --settings=mayan.settings.staging.docker ./manage.py runserver --settings=mayan.settings.staging.docker
test-with-docker-worker: ## Launch a worker instance that uses the production-like services. test-with-docker-worker:
./manage.py celery worker --settings=mayan.settings.staging.docker -B -l INFO -O fair ./manage.py celery worker --settings=mayan.settings.staging.docker -B -l INFO -O fair
docker-mysql-on: ## Launch and initialize a MySQL Docker container. docker-mysql-on:
docker run -d --name mysql -p 3306:3306 -e MYSQL_ALLOW_EMPTY_PASSWORD=True -e MYSQL_DATABASE=mayan_edms mysql docker run -d --name mysql -p 3306:3306 -e MYSQL_ALLOW_EMPTY_PASSWORD=True -e MYSQL_DATABASE=mayan_edms mysql
while ! nc -z 127.0.0.1 3306; do sleep 1; done while ! nc -z 127.0.0.1 3306; do sleep 1; done
docker-mysql-off: ## Stop and delete the MySQL Docker container. docker-mysql-off:
docker stop mysql docker stop mysql
docker rm mysql docker rm mysql
docker-postgres-on: ## Launch and initialize a PostgreSQL Docker container. docker-postgres-on:
docker run -d --name postgres -p 5432:5432 postgres docker run -d --name postgres -p 5432:5432 postgres
while ! nc -z 127.0.0.1 5432; do sleep 1; done while ! nc -z 127.0.0.1 5432; do sleep 1; done
docker-postgres-off: ## Stop and delete the PostgreSQL Docker container. docker-postgres-off:
docker stop postgres docker stop postgres
docker rm postgres docker rm postgres
# Security # Security
safety-check: ## Run a package safety check. safety-check:
safety check safety check
# Other # Other
find-gitignores: ## Find stray .gitignore files. find-gitignores:
@export FIND_GITIGNORES=`find -name '.gitignore'| wc -l`; \ @export FIND_GITIGNORES=`find -name '.gitignore'| wc -l`; \
if [ $${FIND_GITIGNORES} -gt 1 ] ;then echo "More than one .gitignore found."; fi if [ $${FIND_GITIGNORES} -gt 1 ] ;then echo "More than one .gitignore found."; fi
python-build: build:
docker rm -f mayan-edms-build || true && \ docker rm -f mayan-edms-build || true && \
docker run --rm --name mayan-edms-build -v $(HOME):/host_home:ro -v `pwd`:/host_source -w /source python:2-slim sh -c "\ docker run --rm --name mayan-edms-build -v $(HOME):/host_home:ro -v `pwd`:/host_source -w /source python:2-slim sh -c "\
rm /host_source/dist -R || true && \ rm /host_source/dist -R || true && \
@@ -301,13 +326,11 @@ python-build:
make wheel && \ make wheel && \
cp dist/* /host_source/dist/" cp dist/* /host_source/dist/"
check-readme: ## Checks validity of the README.rst file for PyPI publication. check-readme:
python setup.py check -r -s python setup.py check -r -s
check-missing-migrations: ## Make sure all models have proper migrations. check-missing-migrations:
./manage.py makemigrations --dry-run --noinput --check ./manage.py makemigrations --dry-run --noinput --check
setup-dev-environment: ## Bootstrap a virtualenv by install all dependencies to start developing.
pip install -r requirements.txt -r requirements/development.txt -r requirements/testing-base.txt -r requirements/documentation.txt -r requirements/build.txt
-include docker/Makefile include docker/Makefile

View File

@@ -9,6 +9,6 @@ __author__ = 'Roberto Rosario'
__author_email__ = 'roberto.rosario@mayan-edms.com' __author_email__ = 'roberto.rosario@mayan-edms.com'
__description__ = 'Free Open Source Electronic Document Management System' __description__ = 'Free Open Source Electronic Document Management System'
__license__ = 'Apache 2.0' __license__ = 'Apache 2.0'
__copyright_short__ = '2011 Roberto Rosario' __copyright_short__ = '2011-2018 Roberto Rosario'
__copyright__ = '{} {}'.format('Copyright', __copyright_short__) __copyright__ = '{} {}'.format('Copyright', __copyright_short__)
__website__ = 'https://www.mayan-edms.com' __website__ = 'https://www.mayan-edms.com'

View File

@@ -1,10 +1,8 @@
#!/bin/sh #!/bin/sh
export DEBIAN_FRONTEND=noninteractive
apt-get update apt-get update
apt-get install -y --no-install-recommends tesseract-ocr-deu apt-get install -y --no-install-recommends tesseract-ocr-deu
$MAYAN_PIP_BIN install -r ${MAYAN_INSTALL_DIR}/requirements-testing.txt $MAYAN_PIP_BIN install -r $DOCKER_ROOT/requirements-testing.txt
$MAYAN_BIN test --mayan-apps --settings=mayan.settings.testing $MAYAN_BIN test --mayan-apps --settings=mayan.settings.testing

View File

@@ -0,0 +1,72 @@
#!/usr/bin/env bash
INSTALLATION_DIRECTORY=/home/vagrant/mayan-edms/
DB_NAME=mayan_edms
DB_PASSWORD=test123
cat << EOF | sudo tee -a /etc/motd.tail
**********************************sudo apt
Mayan EDMS Vagrant Development Box
**********************************
EOF
# Update sources
echo -e "\n -> Running apt-get update & upgrade \n"
sudo apt-get -qq update
sudo apt-get -y upgrade
echo -e "\n -> Installing core binaries \n"
sudo apt-get -y install git-core python-virtualenv gcc python-dev libjpeg-dev libpng-dev libtiff-dev tesseract-ocr poppler-utils libreoffice
echo -e "\n -> Cloning development branch of repository \n"
git clone /mayan-edms-repository/ $INSTALLATION_DIRECTORY
cd $INSTALLATION_DIRECTORY
git checkout development
git reset HEAD --hard
echo -e "\n -> Setting up virtual env \n"
virtualenv venv
source venv/bin/activate
echo -e "\n -> Installing python dependencies \n"
pip install -r requirements.txt
echo -e "\n -> Running Mayan EDMS initial setup \n"
./manage.py initialsetup
echo -e "\n -> Installing Redis server \n"
sudo apt-get install -y redis-server
pip install redis
echo -e "\n -> Installing testing software \n"
pip install coverage
echo -e "\n -> Installing MySQL \n"
sudo debconf-set-selections <<< 'mysql-server mysql-server/root_password password '$DB_PASSWORD
sudo debconf-set-selections <<< 'mysql-server mysql-server/root_password_again password '$DB_PASSWORD
sudo apt-get install -y mysql-server libmysqlclient-dev
# Create a passwordless root and travis users
mysql -u root -p$DB_PASSWORD -e "SET PASSWORD = PASSWORD('');"
mysql -u root -e "CREATE USER 'travis'@'localhost' IDENTIFIED BY '';GRANT ALL PRIVILEGES ON * . * TO 'travis'@'localhost';FLUSH PRIVILEGES;"
mysql -u travis -e "CREATE DATABASE $DB_NAME;"
pip install mysql-python
echo -e "\n -> Installing PostgreSQL \n"
sudo apt-get install -y postgresql postgresql-server-dev-all
sudo -u postgres psql -c 'create database mayan_edms;' -U postgres
sudo cat > /etc/postgresql/9.3/main/pg_hba.conf << EOF
local all postgres trust
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all peer
# IPv4 local connections:
host all all 127.0.0.1/32 md5
# IPv6 local connections:
host all all ::1/128 md5
EOF
pip install -q psycopg2

File diff suppressed because it is too large Load Diff

View File

@@ -16,7 +16,7 @@ set -e
: ${DATABASE_USER:=mayan} : ${DATABASE_USER:=mayan}
: ${DATABASE_NAME:=mayan} : ${DATABASE_NAME:=mayan}
: ${DATABASE_PASSWORD:=mayanuserpass} : ${DATABASE_PASSWORD:=mayanuserpass}
: ${DOCKER_POSTGRES_IMAGE:=postgres:9.6} : ${DOCKER_POSTGRES_IMAGE:=postgres:9.5}
: ${DOCKER_POSTGRES_CONTAINER:=mayan-edms-postgres} : ${DOCKER_POSTGRES_CONTAINER:=mayan-edms-postgres}
: ${DOCKER_POSTGRES_VOLUME:=/docker-volumes/mayan-edms/postgres} : ${DOCKER_POSTGRES_VOLUME:=/docker-volumes/mayan-edms/postgres}
: ${DOCKER_POSTGRES_PORT:=5432} : ${DOCKER_POSTGRES_PORT:=5432}
@@ -121,7 +121,7 @@ docker run -d \
-e MAYAN_DATABASE_PASSWORD=$DATABASE_PASSWORD \ -e MAYAN_DATABASE_PASSWORD=$DATABASE_PASSWORD \
-e MAYAN_DATABASE_USER=$DATABASE_USER \ -e MAYAN_DATABASE_USER=$DATABASE_USER \
-e MAYAN_DATABASE_PORT=$DOCKER_POSTGRES_PORT \ -e MAYAN_DATABASE_PORT=$DOCKER_POSTGRES_PORT \
-e MAYAN_DATABASE_CONN_MAX_AGE=0 \ -e MAYAN_DATABASE_CONN_MAX_AGE=60 \
-v $DOCKER_MAYAN_VOLUME:/var/lib/mayan \ -v $DOCKER_MAYAN_VOLUME:/var/lib/mayan \
$DOCKER_MAYAN_IMAGE >/dev/null $DOCKER_MAYAN_IMAGE >/dev/null
echo "Done" echo "Done"

View File

@@ -0,0 +1,171 @@
#!/usr/bin/env bash
# ====== CONFIG ======
INSTALLATION_DIRECTORY=/usr/share/mayan-edms/
DB_NAME=mayan_edms
DB_USERNAME=mayan
DB_PASSWORD=test123
# ==== END CONFIG ====
cat << EOF | tee -a /etc/motd.tail
**********************************
Mayan EDMS Vagrant Production Box
**********************************
EOF
echo -e "\n -> Running apt-get update & upgrade \n"
apt-get -qq update
apt-get -y upgrade
echo -e "\n -> Installing core binaries \n"
apt-get install nginx supervisor redis-server postgresql libpq-dev libjpeg-dev libmagic1 libpng-dev libreoffice libtiff-dev gcc ghostscript gpgv python-dev python-virtualenv tesseract-ocr poppler-utils -y
echo -e "\n -> Setting up virtualenv \n"
rm -f ${INSTALLATION_DIRECTORY}
virtualenv ${INSTALLATION_DIRECTORY}
source ${INSTALLATION_DIRECTORY}bin/activate
echo -e "\n -> Installing Mayan EDMS from PyPI \n"
pip install mayan-edms
echo -e "\n -> Installing Python client for PostgreSQL, Redis, and uWSGI \n"
pip install psycopg2 redis uwsgi
echo -e "\n -> Creating the database for the installation \n"
echo "CREATE USER mayan WITH PASSWORD '$DB_PASSWORD';" | sudo -u postgres psql
sudo -u postgres createdb -O $DB_USERNAME $DB_NAME
echo -e "\n -> Creating the directories for the logs \n"
mkdir /var/log/mayan
echo -e "\n -> Making a convenience symlink \n"
cd ${INSTALLATION_DIRECTORY}
ln -s lib/python2.7/site-packages/mayan .
echo -e "\n -> Creating an initial settings file \n"
mayan-edms.py createsettings
echo -e "\n -> Updating the mayan/settings/local.py file \n"
cat >> mayan/settings/local.py << EOF
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': '$DB_NAME',
'USER': '$DB_USERNAME',
'PASSWORD': '$DB_PASSWORD',
'HOST': 'localhost',
'PORT': '5432',
}
}
BROKER_URL = 'redis://127.0.0.1:6379/0'
CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6379/0'
EOF
echo -e "\n -> Migrating the database or initialize the project \n"
mayan-edms.py initialsetup
echo -e "\n -> Disabling the default NGINX site \n"
rm -f /etc/nginx/sites-enabled/default
echo -e "\n -> Creating a uwsgi.ini file \n"
cat > uwsgi.ini << EOF
[uwsgi]
chdir = ${INSTALLATION_DIRECTORY}lib/python2.7/site-packages/mayan
chmod-socket = 664
chown-socket = www-data:www-data
env = DJANGO_SETTINGS_MODULE=mayan.settings.production
gid = www-data
logto = /var/log/uwsgi/%n.log
pythonpath = ${INSTALLATION_DIRECTORY}lib/python2.7/site-packages
master = True
max-requests = 5000
socket = ${INSTALLATION_DIRECTORY}uwsgi.sock
uid = www-data
vacuum = True
wsgi-file = ${INSTALLATION_DIRECTORY}lib/python2.7/site-packages/mayan/wsgi.py
EOF
echo -e "\n -> Creating the directory for the uWSGI log files \n"
mkdir -p /var/log/uwsgi
echo -e "\n -> Creating the NGINX site file for Mayan EDMS, /etc/nginx/sites-available/mayan \n"
cat > /etc/nginx/sites-available/mayan << EOF
server {
listen 80;
server_name localhost;
location / {
include uwsgi_params;
uwsgi_pass unix:${INSTALLATION_DIRECTORY}uwsgi.sock;
client_max_body_size 30M; # Increse if your plan to upload bigger documents
proxy_read_timeout 30s; # Increase if your document uploads take more than 30 seconds
}
location /static {
alias ${INSTALLATION_DIRECTORY}mayan/media/static;
expires 1h;
}
location /favicon.ico {
alias ${INSTALLATION_DIRECTORY}mayan/media/static/appearance/images/favicon.ico;
expires 1h;
}
}
EOF
echo -e "\n -> Enabling the NGINX site for Mayan EDMS \n"
ln -s /etc/nginx/sites-available/mayan /etc/nginx/sites-enabled/
echo -e "\n -> Creating the supervisor file for the uWSGI process, /etc/supervisor/conf.d/mayan-uwsgi.conf \n"
cat > /etc/supervisor/conf.d/mayan-uwsgi.conf << EOF
[program:mayan-uwsgi]
command = ${INSTALLATION_DIRECTORY}bin/uwsgi --ini ${INSTALLATION_DIRECTORY}uwsgi.ini
user = root
autostart = true
autorestart = true
redirect_stderr = true
EOF
echo -e "\n -> Creating the supervisor file for the Celery worker, /etc/supervisor/conf.d/mayan-celery.conf \n"
cat > /etc/supervisor/conf.d/mayan-celery.conf << EOF
[program:mayan-worker]
command = ${INSTALLATION_DIRECTORY}bin/python ${INSTALLATION_DIRECTORY}bin/mayan-edms.py celery --settings=mayan.settings.production worker -Ofair -l ERROR
directory = ${INSTALLATION_DIRECTORY}
user = www-data
stdout_logfile = /var/log/mayan/worker-stdout.log
stderr_logfile = /var/log/mayan/worker-stderr.log
autostart = true
autorestart = true
startsecs = 10
stopwaitsecs = 10
killasgroup = true
priority = 998
[program:mayan-beat]
command = ${INSTALLATION_DIRECTORY}bin/python ${INSTALLATION_DIRECTORY}bin/mayan-edms.py celery --settings=mayan.settings.production beat -l ERROR
directory = ${INSTALLATION_DIRECTORY}
user = www-data
numprocs = 1
stdout_logfile = /var/log/mayan/beat-stdout.log
stderr_logfile = /var/log/mayan/beat-stderr.log
autostart = true
autorestart = true
startsecs = 10
stopwaitsecs = 1
killasgroup = true
priority = 998
EOF
echo -e "\n -> Collecting the static files \n"
mayan-edms.py collectstatic --noinput
echo -e "\n -> Making the installation directory readable and writable by the webserver user \n"
chown www-data:www-data ${INSTALLATION_DIRECTORY} -R
echo -e "\n -> Restarting the services \n"
/etc/init.d/nginx restart
/etc/init.d/supervisor restart

View File

@@ -9,20 +9,18 @@ import sh
APP_LIST = ( APP_LIST = (
'acls', 'appearance', 'authentication', 'autoadmin', 'cabinets', 'acls', 'appearance', 'authentication', 'cabinets', 'checkouts', 'common',
'checkouts', 'common', 'converter', 'dashboards', 'dependencies', 'converter', 'django_gpg', 'document_comments', 'document_indexing',
'django_gpg', 'document_comments', 'document_indexing', 'document_parsing', 'document_signatures', 'document_states', 'documents',
'document_parsing', 'document_signatures', 'document_states', 'dynamic_search', 'events', 'linking', 'lock_manager', 'mayan_statistics',
'documents', 'dynamic_search', 'events', 'file_metadata', 'linking', 'mailer', 'metadata', 'mimetype', 'mirroring', 'motd', 'navigation', 'ocr',
'lock_manager', 'mailer', 'mayan_statistics', 'metadata', 'mirroring', 'permissions','rest_api', 'smart_settings', 'sources', 'storage', 'tags',
'motd', 'navigation', 'ocr', 'permissions', 'platform', 'rest_api', 'task_manager', 'user_management'
'smart_settings', 'sources', 'storage', 'tags', 'task_manager',
'user_management'
) )
LANGUAGE_LIST = ( LANGUAGE_LIST = (
'ar', 'bg', 'bs_BA', 'cs', 'da_DK', 'de_DE', 'en', 'es', 'el', 'fa', 'fr', 'ar', 'bg', 'bs_BA', 'cs', 'da_DK', 'de_DE', 'en', 'es', 'el', 'fa', 'fr',
'hu', 'id', 'it', 'lv', 'nl_NL', 'pl', 'pt', 'pt_BR', 'ro_RO', 'ru', 'sl_SI', 'hu', 'id', 'it', 'nl_NL', 'pl', 'pt', 'pt_BR', 'ro_RO', 'ru', 'sl_SI',
'tr_TR', 'vi_VN', 'zh', 'tr_TR', 'vi_VN', 'zh',
) )

View File

@@ -0,0 +1,35 @@
#!/bin/bash
NAME="mayan-edms"
DJANGODIR=/usr/share/mayan-edms
SOCKFILE=/var/tmp/filesystem.sock
USER=www-data
GROUP=www-data
NUM_WORKERS=3
DJANGO_SETTINGS_MODULE=mayan.settings.production
DJANGO_WSGI_MODULE=mayan.wsgi
TIMEOUT=600
echo "Starting $NAME as `whoami`"
# Activate the virtual environment
cd $DJANGODIR
source bin/activate
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
export PYTHONPATH=$DJANGODIR:$PYTHONPATH
# Create the run directory if it doesn't exist
RUNDIR=$(dirname $SOCKFILE)
test -d $RUNDIR || mkdir -p $RUNDIR
# Start your Django Unicorn
# Programs meant to be run under supervisor should not daemonize themselves (do not use --daemon)
exec bin/gunicorn ${DJANGO_WSGI_MODULE}:application \
--name $NAME \
--workers $NUM_WORKERS \
--user=$USER --group=$GROUP \
--log-level=debug \
--bind=unix:$SOCKFILE \
--timeout=$TIMEOUT

View File

@@ -1,157 +1,164 @@
# vim:set ft=dockerfile: # vim:set ft=dockerfile:
#### ####################
# BASE_IMAGE - Bare bones image with the base packages needed to run Mayan EDMS # Base image start #
#### ####################
FROM debian:9.8-slim as BASE_IMAGE FROM debian:9.4-slim as BASE_IMAGE
LABEL maintainer="Roberto Rosario roberto.rosario@mayan-edms.com" MAINTAINER Roberto Rosario "roberto.rosario@mayan-edms.com"
ENV PYTHONUNBUFFERED=1 \ ENV DEBIAN_FRONTEND noninteractive
LC_ALL=C.UTF-8 \ ENV PYTHONUNBUFFERED 1
PROJECT_INSTALL_DIR=/opt/mayan-edms ENV LC_ALL C.UTF-8
ENV PROJECT_INSTALL_DIR=/opt/mayan-edms
ENV PYTHON_PIP=${PROJECT_INSTALL_DIR}/bin/pip
# Debian package caching
ARG APT_PROXY ARG APT_PROXY
RUN set -x \ # Package caching
&& if [ "${APT_PROXY}" ]; \ RUN if [ "${APT_PROXY}" ]; then echo "Acquire::http { Proxy \"http://${APT_PROXY}\"; };" > /etc/apt/apt.conf.d/01proxy; fi
then echo "Acquire::http { Proxy \"http://${APT_PROXY}\"; };" > /etc/apt/apt.conf.d/01proxy \
; fi \
# Install base OS packages to run Mayan EDMS
&& DEBIAN_FRONTEND=noninteractive \
apt-get update \
&& apt-get install -y --no-install-recommends \
exiftool \
ghostscript \
gpgv \
gnupg1 \
graphviz \
libfuse2 \
libmagic1 \
libmariadbclient18 \
libreoffice \
libpq5 \
poppler-utils \
redis-server \
sane-utils \
sudo \
supervisor \
tesseract-ocr \
# Remove make and build dependencies
&& apt-get remove make libproxy-tools libreoffice-avmedia-backend-vlc libvlc-bin libvlc5 libvlccore9 adwaita-icon-theme gsettings-desktop-schemas libgstreamer-plugins-base1.0-0 -y \
&& apt-get autoremove -y --purge \
# Add mayan user
&& adduser mayan --disabled-password --disabled-login --no-create-home --gecos "" \
# Pillow can't find zlib or libjpeg on aarch64 (ODROID C2)
&& if [ "$(uname -m)" = "aarch64" ]; then \
ln -s /usr/lib/aarch64-linux-gnu/libz.so /usr/lib/ \
&& ln -s /usr/lib/aarch64-linux-gnu/libjpeg.so /usr/lib/ \
; fi \
# Pillow can't find zlib or libjpeg on armv7l (ODROID HC1)
&& if [ "$(uname -m)" = "armv7l" ]; then \
ln -s /usr/lib/arm-linux-gnueabihf/libz.so /usr/lib/ \
&& ln -s /usr/lib/arm-linux-gnueabihf/libjpeg.so /usr/lib/ \
; fi \
# Discard data when Redis runs out of memory
&& echo "maxmemory-policy allkeys-lru" >> /etc/redis/redis.conf \
# Disable saving the Redis database
echo "save \"\"" >> /etc/redis/redis.conf \
# Only provision 1 database
&& echo "databases 1" >> /etc/redis/redis.conf
# Install base Ubuntu libraries
#### RUN apt-get update && \
# BUILDER_IMAGE - This image buildS the Python package and is discarded afterwards
####
# Reuse image
FROM BASE_IMAGE as BUILDER_IMAGE
WORKDIR /src
# Copy the source files needed to build the Python package
COPY --chown=mayan:mayan requirements /src/requirements
COPY --chown=mayan:mayan \
HISTORY.rst \
LICENSE \
MANIFEST.in \
README.md \
README.rst \
setup.py \
/src/
COPY --chown=mayan:mayan mayan /src/mayan
# Install development packages needed to build the Python packages
RUN DEBIAN_FRONTEND=noninteractive \
apt-get install -y --no-install-recommends \ apt-get install -y --no-install-recommends \
default-libmysqlclient-dev \ g++ \
libffi-dev \ gcc \
libjpeg-dev \ ghostscript \
libpng-dev \ gpgv \
libpq-dev \ gnupg1 \
libtiff-dev \ graphviz \
zlib1g-dev \ libffi-dev \
libssl-dev \ libfuse2 \
g++ \ libjpeg-dev \
gcc \ libmagic1 \
python-dev \ default-libmysqlclient-dev \
python-virtualenv \ libpng-dev \
&& mkdir -p "${PROJECT_INSTALL_DIR}" \ libpq-dev \
&& chown -R mayan:mayan "${PROJECT_INSTALL_DIR}" \ libreoffice \
&& chown -R mayan:mayan /src libtiff-dev \
poppler-utils \
python-dev \
python-setuptools \
python-virtualenv \
python-wheel \
redis-server \
sane-utils \
sudo \
supervisor \
tesseract-ocr \
zlib1g-dev \
libssl-dev \
&& \
apt-get clean autoclean && \
apt-get autoremove --purge -y && \
rm -rf /var/lib/apt/lists/* && \
rm -f /var/cache/apt/archives/*.deb
USER mayan # Install apt-get-install
RUN python -m virtualenv "${PROJECT_INSTALL_DIR}" \ ADD https://raw.githubusercontent.com/guilhem/apt-get-install/master/apt-get-install /usr/bin/
&& . "${PROJECT_INSTALL_DIR}/bin/activate" \ RUN chmod +x /usr/bin/apt-get-install
&& pip install --no-cache-dir --no-use-pep517 \
librabbitmq==1.6.1 \
mysql-python==1.2.5 \
psycopg2==2.7.3.2 \
redis==2.10.6 \
# psutil is needed by ARM builds otherwise gevent and gunicorn fail to start
&& UNAME=`uname -m` && if [ "${UNAME#*arm}" != $UNAME ]; then \
pip install --no-cache-dir --no-use-pep517 \
psutil==5.6.2 \
; fi \
# Install the Python packages needed to build Mayan EDMS
&& pip install --no-cache-dir --no-use-pep517 -r /src/requirements/build.txt \
# Build Mayan EDMS
&& python setup.py sdist \
# Install the built Mayan EDMS package
&& pip install --no-cache-dir --no-use-pep517 dist/mayan* \
# Install the static content
&& mayan-edms.py installdependencies \
&& MAYAN_STATIC_ROOT=${PROJECT_INSTALL_DIR}/static mayan-edms.py preparestatic --link --noinput
COPY --chown=mayan:mayan requirements/testing-base.txt "${PROJECT_INSTALL_DIR}" RUN adduser mayan --disabled-password --disabled-login --no-create-home --gecos ""
#### # Pillow can't find zlib or libjpeg on aarch64 (ODROID C2)
# Final image - BASE_IMAGE + Mayan install directory from the builder image RUN if [ "$(uname -m)" = "aarch64" ]; then \
#### ln -s /usr/lib/aarch64-linux-gnu/libz.so /usr/lib/ && \
ln -s /usr/lib/aarch64-linux-gnu/libjpeg.so /usr/lib/ \
; fi
# Pillow can't find zlib or libjpeg on armv7l (ODROID HC1)
RUN if [ "$(uname -m)" = "armv7l" ]; then \
ln -s /usr/lib/arm-linux-gnueabihf/libz.so /usr/lib/ && \
ln -s /usr/lib/arm-linux-gnueabihf/libjpeg.so /usr/lib/ \
; fi
# Discard data when Redis runs out of memory
RUN echo "maxmemory-policy allkeys-lru" >> /etc/redis/redis.conf
# Disable saving the Redis database
RUN echo "save \"\"" >> /etc/redis/redis.conf
# Only provision 1 database
RUN echo "databases 1" >> /etc/redis/redis.conf
#####################
# Build image start #
#####################
FROM debian:9.4-slim as BUILDER_IMAGE
ARG APT_PROXY
# Package caching
RUN if [ "${APT_PROXY}" ]; then echo "Acquire::http { Proxy \"http://${APT_PROXY}\"; };" > /etc/apt/apt.conf.d/01proxy; fi
WORKDIR /code
COPY . /code
RUN apt-get update && apt-get install make python-dev python-pip -y
RUN pip install -r requirements/build.txt
ENV LC_ALL C.UTF-8
RUN touch docker/Makefile
RUN make wheel
RUN chmod 777 dist -R
#####################
# Final image start #
#####################
FROM BASE_IMAGE FROM BASE_IMAGE
COPY --from=BUILDER_IMAGE --chown=mayan:mayan "${PROJECT_INSTALL_DIR}/" "${PROJECT_INSTALL_DIR}/" RUN mkdir -p /opt
USER root RUN python /usr/lib/python2.7/dist-packages/virtualenv.py $PROJECT_INSTALL_DIR
COPY docker/rootfs / WORKDIR $PROJECT_INSTALL_DIR
COPY --from=BUILDER_IMAGE /code/dist/*.whl .
COPY --from=BUILDER_IMAGE /code/contrib/scripts/docker/run-tests.sh .
COPY --from=BUILDER_IMAGE /code/requirements/testing-base.txt requirements-testing.txt
COPY --from=BUILDER_IMAGE /code/docker/version .
# Fix ownership
RUN chown -R mayan:mayan $PROJECT_INSTALL_DIR
# Install build Mayan EDMS
RUN sudo -u mayan $PYTHON_PIP install --no-cache-dir --no-use-pep517 *.whl && \
rm *.whl
# Install Python clients for librabbitmq, MySQL, PostgreSQL, REDIS
RUN sudo -u mayan $PYTHON_PIP install --no-cache-dir --no-use-pep517 librabbitmq==1.6.1 mysql-python==1.2.5 psycopg2==2.7.3.2 redis==2.10.6
# Setup supervisor
COPY docker/etc/supervisor/mayan.conf /etc/supervisor/conf.d
RUN mkdir /var/lib/mayan
VOLUME ["/var/lib/mayan"] VOLUME ["/var/lib/mayan"]
COPY docker/entrypoint.sh /usr/local/bin/
RUN ln -s usr/local/bin/entrypoint.sh / # backwards compat
ENTRYPOINT ["entrypoint.sh"] ENTRYPOINT ["entrypoint.sh"]
EXPOSE 8000 EXPOSE 8000
CMD ["mayan"] CMD ["mayan"]
RUN ${PROJECT_INSTALL_DIR}/bin/mayan-edms.py platformtemplate supervisord_docker > /etc/supervisor/conf.d/mayan.conf \ RUN rm /root/.cache -R
&& apt-get clean autoclean \ RUN rm -rf /tmp/*
&& apt-get autoremove --purge -y \
&& rm -rf /var/lib/apt/lists/* \ RUN apt-get -y autoremove --purge && apt-get -y autoclean && apt-get -y clean
&& rm -f /var/cache/apt/archives/*.deb \
# Remove temporary files owned by root from the platformtemplate step RUN rm -rf /usr/share/man/*
&& rm /tmp/* \ RUN rm -rf /usr/share/doc/*
# Keep displaying log messages to stdout
&& find /var/log -type f | while read f; do echo -ne '' > $f; done; RUN find /var/lib/apt -type f | xargs rm -f
RUN find /var/cache -type f -exec rm -rf {} \;
RUN find /var/log -type f | while read f; do echo -ne '' > $f; done;

150
docker/Dockerfile.ubuntu Executable file
View File

@@ -0,0 +1,150 @@
# vim:set ft=dockerfile:
####################
# Base image start #
####################
FROM ubuntu:16.04 as BASE_IMAGE
MAINTAINER Roberto Rosario "roberto.rosario@mayan-edms.com"
ENV DEBIAN_FRONTEND noninteractive
ENV PYTHONUNBUFFERED 1
ENV LANG en_US.UTF-8
ENV PROJECT_INSTALL_DIR=/usr/local/lib/python2.7/dist-packages/mayan
ARG APT_PROXY
# Package caching
RUN if [ "${APT_PROXY}" ]; then echo "Acquire::http { Proxy \"http://${APT_PROXY}\"; };" > /etc/apt/apt.conf.d/01proxy; fi
# Install base Ubuntu libraries
RUN apt-get update && \
apt-get install -y --no-install-recommends \
curl \
g++ \
gcc \
gettext-base \
ghostscript \
gpgv \
graphviz \
libffi-dev \
libjpeg-dev \
libmagic1 \
libmysqlclient-dev \
libpng-dev \
libpq-dev \
libreoffice \
libtiff-dev \
locales \
netcat-openbsd \
poppler-utils \
python-dev \
python-pip \
python-setuptools \
python-wheel \
redis-server \
supervisor \
tesseract-ocr \
zlib1g-dev \
&& \
apt-get clean autoclean && \
apt-get autoremove --purge -y && \
rm -rf /var/lib/apt/lists/* && \
rm -f /var/cache/apt/archives/*.deb
# Switch to UTF locale
RUN echo "LC_ALL=\"en_US.UTF-8\"" >> /etc/default/locale && \
locale-gen en_US.UTF-8 && \
update-locale LANG=en_US.UTF-8 && \
export LC_ALL=en_US.UTF-8
# Install apt-get-install
ADD https://raw.githubusercontent.com/guilhem/apt-get-install/master/apt-get-install /usr/bin/
RUN chmod +x /usr/bin/apt-get-install
# Install Python clients for PostgreSQL, REDIS, librabbitmq
RUN pip install psycopg2==2.7.3.2 redis==2.10.6 mysql-python==1.2.5 librabbitmq==1.6.1
RUN adduser mayan --disabled-password --disabled-login --no-create-home --gecos ""
# Pillow can't find zlib or libjpeg on aarch64
RUN if [ "$(uname -m)" = "aarch64" ]; then \
ln -s /usr/lib/aarch64-linux-gnu/libz.so /usr/lib/ && \
ln -s /usr/lib/aarch64-linux-gnu/libjpeg.so /usr/lib/ \
; fi
#####################
# Build image start #
#####################
FROM python:2-alpine3.7 as BUILDER_IMAGE
WORKDIR /code
COPY . /code
RUN apk update && \
apk add make
RUN pip install -r requirements/build.txt
RUN make wheel
RUN chmod 777 dist -R
#####################
# Final image start #
#####################
FROM BASE_IMAGE
WORKDIR /root/
COPY --from=BUILDER_IMAGE /code/dist/*.whl .
# Install build Mayan EDMS
RUN pip install *.whl && \
rm *.whl
# Setup supervisor
#RUN mkdir /etc/supervisor.d/
COPY docker/etc/supervisor/beat.conf /etc/supervisor/conf.d
COPY docker/etc/supervisor/gunicorn.conf /etc/supervisor/conf.d
COPY docker/etc/supervisor/redis.conf /etc/supervisor/conf.d
COPY docker/etc/supervisor/workers.conf /etc/supervisor/conf.d
# Create the directory for the logs
RUN mkdir /var/log/mayan
# Fix ownership
RUN chown -R mayan:mayan $PROJECT_INSTALL_DIR
# Allow flanker to autogenerate its PLY files
RUN chown -R mayan:mayan /usr/local/lib/python2.7/dist-packages/flanker/
RUN mkdir /var/lib/mayan
VOLUME ["/var/lib/mayan"]
COPY docker/entrypoint.sh /usr/local/bin/
RUN ln -s usr/local/bin/entrypoint.sh / # backwards compat
ENTRYPOINT ["entrypoint.sh"]
# Healthcheck setup
HEALTHCHECK --interval=15s --timeout=1s --retries=20 \
CMD curl -s -f http://localhost/authentication/login/ | grep 'form' > /dev/null || exit 1
EXPOSE 8000
CMD ["mayan"]
RUN rm /root/.cache -R
RUN rm -rf /tmp/*
RUN apt-get -y autoremove --purge && apt-get -y autoclean && apt-get -y clean
RUN rm -rf /usr/share/man/*
RUN rm -rf /usr/share/doc/*
RUN find /var/lib/apt -type f | xargs rm -f
RUN find /var/cache -type f -exec rm -rf {} \;
RUN find /var/log -type f | while read f; do echo -ne '' > $f; done;

View File

@@ -1,25 +1,33 @@
APT_PROXY ?= `/sbin/ip route|awk '/docker0/ { print $$9 }'`:3142 APT_PROXY ?= `/sbin/ip route|awk '/docker0/ { print $$9 }'`:3142
IMAGE_VERSION ?= `cat docker/rootfs/version` IMAGE_VERSION ?= `cat docker/version`
CONSOLE_COLUMNS ?= `echo $$(tput cols)` CONSOLE_COLUMNS ?= `echo $$(tput cols)`
CONSOLE_LINES ?= `echo $$(tput lines)` CONSOLE_LINES ?= `echo $$(tput lines)`
docker-build: ## Build a new image locally. docker-help:
@echo
@echo "**** Docker makefile ****"
@echo "docker-build - Build a new image locally."
@echo "docker-build-with-proxy - Build a new image locally using an APT proxy."
@echo "docker-test-container - Build and run a test container."
@echo "docker-test-cleanup - Delete the test container and the test volume."
@echo "docker-test-all - Build and executed the test suite in a test container."
@echo "docker-shell - Launch a bash instance inside a running container. Pass the container name via DOCKER_CONTAINER."
docker-build:
docker build -t mayanedms/mayanedms:$(IMAGE_VERSION) -f docker/Dockerfile . docker build -t mayanedms/mayanedms:$(IMAGE_VERSION) -f docker/Dockerfile .
docker-build-with-proxy: ## Build a new image locally using an APT proxy as APT_PROXY. docker-build-with-proxy:
docker build -t mayanedms/mayanedms:$(IMAGE_VERSION) -f docker/Dockerfile --build-arg APT_PROXY=$(APT_PROXY) . docker build -t mayanedms/mayanedms:$(IMAGE_VERSION) -f docker/Dockerfile --build-arg APT_PROXY=$(APT_PROXY) .
docker-shell: ## Launch a bash instance inside a running container. Pass the container name via DOCKER_CONTAINER. docker-shell:
docker exec -e TERM=$(TERM) -e "COLUMNS=$(CONSOLE_COLUMNS)" -e "LINES=$(CONSOLE_LINES)" -it $(DOCKER_CONTAINER) /bin/bash docker exec -e TERM=$(TERM) -e "COLUMNS=$(CONSOLE_COLUMNS)" -e "LINES=$(CONSOLE_LINES)" -it $(DOCKER_CONTAINER) /bin/bash
docker-test-container: ## Build and run a test container.
docker-test-container: docker-build-with-proxy docker-test-cleanup docker-test-container: docker-build-with-proxy docker-test-cleanup
docker run -d --name test-mayan-edms -p 80:8000 -v test-mayan_data:/var/lib/mayan mayanedms/mayanedms:$(DOCKER_VERSION) docker run -d --name test-mayan-edms -p 80:8000 -v test-mayan_data:/var/lib/mayan mayanedms/mayanedms:$(DOCKER_VERSION)
docker-test-cleanup: ## Delete the test container and the test volume. docker-test-cleanup:
@docker rm -f test-mayan-edms || true @docker rm -f test-mayan-edms || true
@docker volume rm test-mayan_data || true @docker volume rm test-mayan_data || true
docker-test-all: ## Build and executed the test suite in a test container.
docker-test-all: docker-build-with-proxy docker-test-all: docker-build-with-proxy
docker run --rm run-tests docker run --rm run-tests

1
docker/README-short.txt Executable file
View File

@@ -0,0 +1 @@
Mayan EDMS is a free open source electronic document management system.

554
docker/README.md Executable file

File diff suppressed because it is too large Load Diff

549
docker/README.md.tmpl Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -4,9 +4,7 @@ set -e
echo "mayan: starting entrypoint.sh" echo "mayan: starting entrypoint.sh"
INSTALL_FLAG=/var/lib/mayan/system/SECRET_KEY INSTALL_FLAG=/var/lib/mayan/system/SECRET_KEY
CONCURRENCY_ARGUMENT=--concurrency= CONCURRENCY_ARGUMENT=--concurrency=
export DOCKER_ROOT=/opt/mayan-edms
DEFAULT_USER_UID=1000
DEFAULT_USER_GUID=1000
export MAYAN_DEFAULT_BROKER_URL=redis://127.0.0.1:6379/0 export MAYAN_DEFAULT_BROKER_URL=redis://127.0.0.1:6379/0
export MAYAN_DEFAULT_CELERY_RESULT_BACKEND=redis://127.0.0.1:6379/0 export MAYAN_DEFAULT_CELERY_RESULT_BACKEND=redis://127.0.0.1:6379/0
@@ -22,18 +20,12 @@ export MAYAN_SETTINGS_MODULE=${MAYAN_SETTINGS_MODULE:-mayan.settings.production}
export MAYAN_GUNICORN_BIN=${MAYAN_PYTHON_BIN_DIR}gunicorn export MAYAN_GUNICORN_BIN=${MAYAN_PYTHON_BIN_DIR}gunicorn
export MAYAN_GUNICORN_WORKERS=${MAYAN_GUNICORN_WORKERS:-2} export MAYAN_GUNICORN_WORKERS=${MAYAN_GUNICORN_WORKERS:-2}
export MAYAN_GUNICORN_TIMEOUT=${MAYAN_GUNICORN_TIMEOUT:-120}
export MAYAN_PIP_BIN=${MAYAN_PYTHON_BIN_DIR}pip export MAYAN_PIP_BIN=${MAYAN_PYTHON_BIN_DIR}pip
export MAYAN_STATIC_ROOT=${MAYAN_INSTALL_DIR}/static
MAYAN_WORKER_FAST_CONCURRENCY=${MAYAN_WORKER_FAST_CONCURRENCY:-1} MAYAN_WORKER_FAST_CONCURRENCY=${MAYAN_WORKER_FAST_CONCURRENCY:-1}
MAYAN_WORKER_MEDIUM_CONCURRENCY=${MAYAN_WORKER_MEDIUM_CONCURRENCY:-1} MAYAN_WORKER_MEDIUM_CONCURRENCY=${MAYAN_WORKER_MEDIUM_CONCURRENCY:-1}
MAYAN_WORKER_SLOW_CONCURRENCY=${MAYAN_WORKER_SLOW_CONCURRENCY:-1} MAYAN_WORKER_SLOW_CONCURRENCY=${MAYAN_WORKER_SLOW_CONCURRENCY:-1}
echo "mayan: changing uid/guid"
usermod mayan -u ${MAYAN_USER_UID:-${DEFAULT_USER_UID}}
groupmod mayan -g ${MAYAN_USER_GUID:-${DEFAULT_USER_GUID}}
if [ "$MAYAN_WORKER_FAST_CONCURRENCY" -eq 0 ]; then if [ "$MAYAN_WORKER_FAST_CONCURRENCY" -eq 0 ]; then
MAYAN_WORKER_FAST_CONCURRENCY= MAYAN_WORKER_FAST_CONCURRENCY=
else else
@@ -60,30 +52,16 @@ export PYTHONPATH=$PYTHONPATH:$MAYAN_MEDIA_ROOT
chown mayan:mayan /var/lib/mayan -R chown mayan:mayan /var/lib/mayan -R
apt_get_install() {
apt-get -q update
apt-get install -y --force-yes --no-install-recommends --auto-remove "$@"
apt-get -q clean
rm -rf /var/lib/apt/lists/*
}
initialize() { initialize() {
echo "mayan: initialize()" echo "mayan: initialize()"
su mayan -c "${MAYAN_BIN} initialsetup --force --no-javascript" su mayan -c "${MAYAN_BIN} initialsetup --force"
su mayan -c "${MAYAN_BIN} collectstatic --noinput --clear"
} }
os_package_installs() { upgrade() {
echo "mayan: os_package_installs()" echo "mayan: upgrade()"
if [ "${MAYAN_APT_INSTALLS}" ]; then su mayan -c "${MAYAN_BIN} performupgrade"
DEBIAN_FRONTEND=noninteractive apt_get_install $MAYAN_APT_INSTALLS su mayan -c "${MAYAN_BIN} collectstatic --noinput --clear"
fi
}
pip_installs() {
echo "mayan: pip_installs()"
if [ "${MAYAN_PIP_INSTALLS}" ]; then
su mayan -c "${MAYAN_PIP_BIN} install $MAYAN_PIP_INSTALLS"
fi
} }
start() { start() {
@@ -92,9 +70,18 @@ start() {
exec /usr/bin/supervisord -nc /etc/supervisor/supervisord.conf exec /usr/bin/supervisord -nc /etc/supervisor/supervisord.conf
} }
upgrade() { os_package_installs() {
echo "mayan: upgrade()" echo "mayan: os_package_installs()"
su mayan -c "${MAYAN_BIN} performupgrade --no-javascript" if [ "${MAYAN_APT_INSTALLS}" ]; then
apt-get-install $MAYAN_APT_INSTALLS
fi
}
pip_installs() {
echo "mayan: pip_installs()"
if [ "${MAYAN_PIP_INSTALLS}" ]; then
$MAYAN_PIP_BIN install $MAYAN_PIP_INSTALLS
fi
} }
os_package_installs || true os_package_installs || true
@@ -119,7 +106,7 @@ run-tests) # Check if this is a new install, otherwise try to upgrade the existi
else else
upgrade upgrade
fi fi
run-tests.sh $DOCKER_ROOT/run-tests.sh
;; ;;
*) su mayan -c "$@"; *) su mayan -c "$@";

View File

@@ -0,0 +1,80 @@
[program:mayan-gunicorn]
autorestart = false
autostart = true
command = /bin/bash -c "${MAYAN_GUNICORN_BIN} -w ${MAYAN_GUNICORN_WORKERS} mayan.wsgi --max-requests 500 --max-requests-jitter 50 --worker-class gevent --bind 0.0.0.0:8000 --env DJANGO_SETTINGS_MODULE=${MAYAN_SETTINGS_MODULE}" --timeout 120
redirect_stderr = true
stderr_logfile = /dev/fd/2
stderr_logfile_maxbytes = 0
stdout_logfile = /dev/fd/1
stdout_logfile_maxbytes = 0
user = mayan
[program:redis]
autorestart = false
autostart = true
command = /bin/bash -c "if [ ${MAYAN_BROKER_URL} == ${MAYAN_DEFAULT_BROKER_URL} ] && [ ${MAYAN_CELERY_RESULT_BACKEND} == ${MAYAN_DEFAULT_CELERY_RESULT_BACKEND} ];then /usr/bin/redis-server /etc/redis/;fi"
stderr_logfile = /dev/fd/2
stderr_logfile_maxbytes = 0
stdout_logfile = /dev/fd/1
stdout_logfile_maxbytes = 0
user = root
[program:mayan-worker-fast]
autorestart = false
autostart = true
command = nice -n 1 /bin/bash -c "${MAYAN_BIN} celery --settings=${MAYAN_SETTINGS_MODULE} worker -Ofair -l ERROR -Q converter,sources_fast -n mayan-worker-fast.%%h ${MAYAN_WORKER_FAST_CONCURRENCY}"
killasgroup = true
numprocs = 1
priority = 998
startsecs = 10
stderr_logfile = /dev/fd/2
stderr_logfile_maxbytes = 0
stdout_logfile = /dev/fd/1
stdout_logfile_maxbytes = 0
stopwaitsecs = 1
user = mayan
[program:mayan-worker-medium]
autorestart = false
autostart = true
command = nice -n 18 /bin/bash -c "${MAYAN_BIN} celery --settings=${MAYAN_SETTINGS_MODULE} worker -Ofair -l ERROR -Q checkouts_periodic,documents_periodic,indexing,metadata,sources,sources_periodic,uploads,documents -n mayan-worker-medium.%%h ${MAYAN_WORKER_MEDIUM_CONCURRENCY}"
killasgroup = true
numprocs = 1
priority = 998
startsecs = 10
stderr_logfile = /dev/fd/2
stderr_logfile_maxbytes = 0
stdout_logfile = /dev/fd/1
stdout_logfile_maxbytes = 0
stopwaitsecs = 1
user = mayan
[program:mayan-worker-slow]
autorestart = false
autostart = true
command = nice -n 19 /bin/bash -c "${MAYAN_BIN} celery --settings=${MAYAN_SETTINGS_MODULE} worker -Ofair -l ERROR -Q mailing,tools,statistics,parsing,ocr -n mayan-worker-slow.%%h ${MAYAN_WORKER_SLOW_CONCURRENCY}"
killasgroup = true
numprocs = 1
priority = 998
startsecs = 10
stderr_logfile = /dev/fd/2
stderr_logfile_maxbytes = 0
stdout_logfile = /dev/fd/1
stdout_logfile_maxbytes = 0
stopwaitsecs = 1
user = mayan
[program:mayan-celery-beat]
autorestart = false
autostart = true
command = nice -n 1 /bin/bash -c "${MAYAN_BIN} celery --settings=${MAYAN_SETTINGS_MODULE} beat --pidfile= -l ERROR"
killasgroup = true
numprocs = 1
priority = 998
stderr_logfile = /dev/fd/2
stderr_logfile_maxbytes = 0
stdout_logfile = /dev/fd/1
stdout_logfile_maxbytes = 0
startsecs = 10
stopwaitsecs = 1
user = mayan

View File

@@ -1,10 +0,0 @@
#!/bin/sh
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y --no-install-recommends gcc python-dev tesseract-ocr-deu
su mayan -c "$MAYAN_PIP_BIN install -r ${MAYAN_INSTALL_DIR}/testing-base.txt"
su mayan -c "$MAYAN_BIN test --mayan-apps --settings=mayan.settings.testing"

View File

@@ -1 +0,0 @@
3.2.6

View File

@@ -27,6 +27,6 @@ services:
MAYAN_DATABASE_NAME: mayan MAYAN_DATABASE_NAME: mayan
MAYAN_DATABASE_PASSWORD: mayan-password MAYAN_DATABASE_PASSWORD: mayan-password
MAYAN_DATABASE_USER: mayan MAYAN_DATABASE_USER: mayan
MAYAN_DATABASE_CONN_MAX_AGE: 0 MAYAN_DATABASE_CONN_MAX_AGE: 60
volumes: volumes:
- app:/var/lib/mayan - app:/var/lib/mayan

1
docker/version Executable file
View File

@@ -0,0 +1 @@
3.1.10

View File

@@ -1,5 +0,0 @@
.menuselection {
color: white;
background: #2c3e50;
padding: 3px;
}

View File

@@ -59,17 +59,6 @@ App modules
corresponding signal in the ready() method of the MayanAppConfig subclass in corresponding signal in the ready() method of the MayanAppConfig subclass in
apps.py apps.py
- html_widgets.py
Classes to render an HTML widget. HTML widget are not the same as Django's
native form widgets. Form widgets only work as part of a form field.
HTML widgets are for use outside of forms, such as in a table cell.
- licenses.py
This module outlines the license text of the third party content used in
the app. It could be other Python libraries, JavaScript libraries, etc.
- links.py - links.py
Defines the links to be used by the app. Import only from the navigation app Defines the links to be used by the app. Import only from the navigation app
@@ -103,11 +92,6 @@ App modules
This module acts as a shared memory space for the other modules of the app or This module acts as a shared memory space for the other modules of the app or
other apps. other apps.
- search.py
Search model definitions. Define which field of the app's models are
searchable.
- serializers.py - serializers.py
Hold Django REST Framework serializers used by the api_views.py module. Hold Django REST Framework serializers used by the api_views.py module.
@@ -143,7 +127,7 @@ App modules
- widgets.py - widgets.py
Custom form widgets go here. This should be the only place with presentation HTML widgets go here. This should be the only place with presentation
directives in the app (aside the templates). directives in the app (aside the templates).

View File

@@ -59,7 +59,7 @@ Example::
-e POSTGRES_DB=mayan \ -e POSTGRES_DB=mayan \
-e POSTGRES_PASSWORD=mayanuserpass \ -e POSTGRES_PASSWORD=mayanuserpass \
-v /docker-volumes/mayan-edms/postgres-new:/var/lib/postgresql/data \ -v /docker-volumes/mayan-edms/postgres-new:/var/lib/postgresql/data \
-d postgres:9.6 -d postgres:9.5
docker exec -i mayan-edms-pg-new pg_restore -U mayan -d mayan < 2018-06-07_17-09-34.dump docker exec -i mayan-edms-pg-new pg_restore -U mayan -d mayan < 2018-06-07_17-09-34.dump

View File

@@ -99,5 +99,5 @@ Direct install
MAYAN_DATABASE_NAME=mayan, MAYAN_DATABASE_NAME=mayan,
MAYAN_DATABASE_PASSWORD=mayanuserpass, MAYAN_DATABASE_PASSWORD=mayanuserpass,
MAYAN_DATABASE_USER=mayan, MAYAN_DATABASE_USER=mayan,
MAYAN_DATABASE_CONN_MAX_AGE=0, MAYAN_DATABASE_CONN_MAX_AGE=360,
<...> <...>

File diff suppressed because it is too large Load Diff

View File

@@ -248,6 +248,9 @@ Special branches:
``releases/python`` ``releases/python``
Used by the continuous delivery system to trigger the build and release Used by the continuous delivery system to trigger the build and release
of a new Python package to PyPI. of a new Python package to PyPI.
``releases/python``
Used by the continuous delivery system to trigger the build and release
of a new Python package to PyPI.
``nightly`` ``nightly``
Used by the continuous delivery system to trigger the build and release Used by the continuous delivery system to trigger the build and release
of a new Docker image based on development code to the GitLab image of a new Docker image based on development code to the GitLab image
@@ -479,7 +482,7 @@ Release checklist
make check-readme make check-readme
#. Bump version in ``mayan/__init__.py`` and ``docker/rootfs/version``:: #. Bump version in ``mayan/__init__.py`` and ``docker/version``::
make increase-version PART=<major, minor or micro> make increase-version PART=<major, minor or micro>

View File

@@ -7,23 +7,16 @@ How to use this image
.. _docker_install: .. _docker_install:
Start a Mayan EDMS Docker image Start a Mayan EDMS image
------------------------------- ------------------------
With Docker properly installed, proceed to download the Mayan EDMS image using With Docker properly installed, proceed to download the Mayan EDMS image using the command::
the command::
docker pull mayanedms/mayanedms:<version> docker pull mayanedms/mayanedms:<version>
Instead of a specific version tag you may use then generic ``:latest`` tag Then download version 9.5 of the Docker PostgreSQL image::
to the get latest version available automatically. If you use the ``:latest``
tag here, remember to do so in the next steps also.::
docker pull mayanedms/mayanedms:latest docker pull postgres:9.5
Then download version 9.6 of the Docker PostgreSQL image::
docker pull postgres:9.6
Create and run a PostgreSQL container:: Create and run a PostgreSQL container::
@@ -35,7 +28,7 @@ Create and run a PostgreSQL container::
-e POSTGRES_DB=mayan \ -e POSTGRES_DB=mayan \
-e POSTGRES_PASSWORD=mayanuserpass \ -e POSTGRES_PASSWORD=mayanuserpass \
-v /docker-volumes/mayan-edms/postgres:/var/lib/postgresql/data \ -v /docker-volumes/mayan-edms/postgres:/var/lib/postgresql/data \
-d postgres:9.6 -d postgres:9.5
The PostgreSQL container will have one database named ``mayan``, with an user The PostgreSQL container will have one database named ``mayan``, with an user
named ``mayan`` too, with a password of ``mayanuserpass``. The container will named ``mayan`` too, with a password of ``mayanuserpass``. The container will
@@ -43,7 +36,9 @@ expose its internal 5432 port (PostgreSQL's default port) via the host's
5432 port. The data of this container will reside on the host's 5432 port. The data of this container will reside on the host's
``/docker-volumes/mayan-edms/postgres`` folder. ``/docker-volumes/mayan-edms/postgres`` folder.
Finally create and run a Mayan EDMS container:: Finally create and run a Mayan EDMS container. Change <version> with the
latest version in numeric form (example: 2.7.3) or use the ``latest``
identifier::
docker run -d \ docker run -d \
--name mayan-edms \ --name mayan-edms \
@@ -54,7 +49,7 @@ Finally create and run a Mayan EDMS container::
-e MAYAN_DATABASE_NAME=mayan \ -e MAYAN_DATABASE_NAME=mayan \
-e MAYAN_DATABASE_PASSWORD=mayanuserpass \ -e MAYAN_DATABASE_PASSWORD=mayanuserpass \
-e MAYAN_DATABASE_USER=mayan \ -e MAYAN_DATABASE_USER=mayan \
-e MAYAN_DATABASE_CONN_MAX_AGE=0 \ -e MAYAN_DATABASE_CONN_MAX_AGE=60 \
-v /docker-volumes/mayan-edms/media:/var/lib/mayan \ -v /docker-volumes/mayan-edms/media:/var/lib/mayan \
mayanedms/mayanedms:<version> mayanedms/mayanedms:<version>
@@ -77,7 +72,6 @@ If another web server is running on port 80 use a different port in the
Using a dedicated Docker network Using a dedicated Docker network
-------------------------------- --------------------------------
Use this method to avoid having to expose PostreSQL port to the host's network Use this method to avoid having to expose PostreSQL port to the host's network
or if you have other PostgreSQL instances but still want to use the default or if you have other PostgreSQL instances but still want to use the default
port of 5432 for this installation. port of 5432 for this installation.
@@ -97,7 +91,7 @@ binding (``-p 5432:5432``)::
-e POSTGRES_DB=mayan \ -e POSTGRES_DB=mayan \
-e POSTGRES_PASSWORD=mayanuserpass \ -e POSTGRES_PASSWORD=mayanuserpass \
-v /docker-volumes/mayan-edms/postgres:/var/lib/postgresql/data \ -v /docker-volumes/mayan-edms/postgres:/var/lib/postgresql/data \
-d postgres:9.6 -d postgres:9.5
Launch the Mayan EDMS container with the network option and change the Launch the Mayan EDMS container with the network option and change the
database hostname to the PostgreSQL container name (``mayan-edms-postgres``) database hostname to the PostgreSQL container name (``mayan-edms-postgres``)
@@ -113,11 +107,10 @@ instead of the IP address of the Docker host (``172.17.0.1``)::
-e MAYAN_DATABASE_NAME=mayan \ -e MAYAN_DATABASE_NAME=mayan \
-e MAYAN_DATABASE_PASSWORD=mayanuserpass \ -e MAYAN_DATABASE_PASSWORD=mayanuserpass \
-e MAYAN_DATABASE_USER=mayan \ -e MAYAN_DATABASE_USER=mayan \
-e MAYAN_DATABASE_CONN_MAX_AGE=0 \ -e MAYAN_DATABASE_CONN_MAX_AGE=60 \
-v /docker-volumes/mayan-edms/media:/var/lib/mayan \ -v /docker-volumes/mayan-edms/media:/var/lib/mayan \
mayanedms/mayanedms:<version> mayanedms/mayanedms:<version>
Stopping and starting the container Stopping and starting the container
----------------------------------- -----------------------------------
@@ -133,7 +126,6 @@ To start the container again::
.. _docker_environment_variables: .. _docker_environment_variables:
Environment Variables Environment Variables
--------------------- ---------------------
@@ -228,10 +220,6 @@ Optional. Allows loading an alternate settings file.
Amount in seconds to keep a database connection alive. Allow reuse of database Amount in seconds to keep a database connection alive. Allow reuse of database
connections. For more information read the pertinent Django documentation connections. For more information read the pertinent Django documentation
page: :django-docs:`Settings, CONN_MAX_AGE <ref/settings/#conn-max-age>` page: :django-docs:`Settings, CONN_MAX_AGE <ref/settings/#conn-max-age>`
According to new information Gunicorn's microthreads don't share connections
and will exhaust the available Postgres connections available if a number
other than 0 is used. Reference: https://serverfault.com/questions/635100/django-conn-max-age-persists-connections-but-doesnt-reuse-them-with-postgresq
and https://github.com/benoitc/gunicorn/issues/996
``MAYAN_GUNICORN_WORKERS`` ``MAYAN_GUNICORN_WORKERS``
@@ -264,19 +252,6 @@ category. Default is 1. Use 0 to disable hardcoded concurrency and allow the
Celery worker to launch its default number of child processes (equal to the Celery worker to launch its default number of child processes (equal to the
number of CPUs detected). number of CPUs detected).
``MAYAN_USER_UID``
Optional. Changes the UID of the ``mayan`` user internal to the Docker
container. Defaults to 1000.
``MAYAN_USER_GUID``
Optional. Changes the GUID of the ``mayan`` user internal to the Docker
container. Defaults to 1000.
.. _docker-accessing-outside-data:
Accessing outside data Accessing outside data
====================== ======================
@@ -288,21 +263,18 @@ on purpose. For example, to make a folder in the host accessible as a watch
folder, add the following to the Docker command line when starting the folder, add the following to the Docker command line when starting the
container:: container::
-v /opt/scanned_files:/scanned_files -v /opt/scanned_files:/srv/watch_folder
The command line would look like this:: The command line would look like this::
docker run ... -v /opt/scanned_files:/scanned_files mayanedms/mayanedms:latest docker run ... -v /opt/scanned_files:/srv/watch_folder mayanedms/mayanedms:latest
Now create a watch folder in Mayan EDMS using the path ``/scanned_files`` Now create a watch folder in Mayan EDMS using the path ``/srv/watch_folder``
and the documents from the host folder ``/opt/scanned_files`` will be and the documents from the host folder ``/opt/scanned_files`` will be
automatically available. Use the same procedure to mount host folders to be automatically available. Use the same procedure to mount host folders to be
used as staging folders. In this example ``/scanned_files`` was used as the used as staging folderes. In this example ``/srv/watch_folder`` was as the
container directory, but any path can be used as long as: container directory, but any path can be used as long as it is not an
already existing path or a path used by any other program.
- the path not an already existing path
- the path is not used by any other program
- the path is a single level path
Performing backups Performing backups
@@ -313,7 +285,7 @@ For the example::
docker run -d --name mayan-edms --restart=always -p 80:8000 \ docker run -d --name mayan-edms --restart=always -p 80:8000 \
-v /docker-volumes/mayan:/var/lib/mayan \ -v /docker-volumes/mayan:/var/lib/mayan \
-v /opt/scanned_files:/scanned_files mayanedms/mayanedms:latest -v /opt/scanned_files:/srv/watch_folder mayanedms/mayanedms:latest
That would be the ``/docker-volumes/mayan folder``:: That would be the ``/docker-volumes/mayan folder``::
@@ -325,7 +297,6 @@ too need to be backed up using their respective procedures. A simple solution
is to copy the entire database container volume after the container has is to copy the entire database container volume after the container has
been stopped. been stopped.
Restoring from a backup Restoring from a backup
======================= =======================
@@ -333,7 +304,6 @@ Uncompress the backup archive in the original docker volume using::
sudo tar -xvzf backup.tar.gz -C / sudo tar -xvzf backup.tar.gz -C /
Upgrading Upgrading
========= =========
@@ -363,7 +333,6 @@ Start the container again with the new image version::
docker run -d --name mayan-edms --restart=always -p 80:8000 -v /docker-volumes/mayan:/var/lib/mayan mayanedms/mayanedms:latest docker run -d --name mayan-edms --restart=always -p 80:8000 -v /docker-volumes/mayan:/var/lib/mayan mayanedms/mayanedms:latest
Building the image Building the image
================== ==================
@@ -379,14 +348,13 @@ Execute Docker's build command using the provided makefile::
make docker-build make docker-build
Or using an APT cache to speed up the build:: Or using an apt cacher to speed up the build::
make docker-build-with-proxy APT_PROXY=172.17.0.1:3142 make docker-build-with-proxy APT_PROXY=172.17.0.1:3142
Replace the IP address `172.17.0.1` with the IP address of the computer Replace the IP address `172.17.0.1` with the IP address of the computer
running the APT proxy and caching service. running the APT proxy and caching service.
Customizing the image Customizing the image
===================== =====================
@@ -411,7 +379,6 @@ Specifies a list of Python packages to be installed via ``pip``. Packages will
be downloaded from the Python Package Index (https://pypi.python.org) by be downloaded from the Python Package Index (https://pypi.python.org) by
default. default.
Using Docker compose Using Docker compose
==================== ====================

View File

@@ -68,21 +68,5 @@ type at a given moment, but if needed, the type of a document can be changed.
Upon changing its type, the document will lose its previous settings and Upon changing its type, the document will lose its previous settings and
attributes, and will inherit the settings and attributes of its new type. attributes, and will inherit the settings and attributes of its new type.
Document types are create in the
Creating document types :menuselection:`System --> Setup --> Document types` menu.
=======================
.. admonition:: Permissions required
:class: warning
The "Create document types" permission is required for this action.
#. Go to the :menuselection:`System --> Setup --> Document types` menu.
#. From the :guilabel:`Actions` dropdown select :guilabel:`Create document type`.
#. Enter a label to be shown to users when using this document type.
#. Optional: Enter a period of time after which documents of this type will be moved to the trash.
#. Optional: Select the unit of time for the period after which the document will be moved to the trash.
#. Optional: Enter a period of time after which documents moved to the trash will be permanently deleted.
#. Optional: Select the unit of time for the period of time after which the documents moved to the trash will be permanently deleted
#. Press :guilabel:`Submit`.

View File

@@ -5,32 +5,22 @@ Index examples
Index of document types Index of document types
^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^
.. admonition:: Permissions required
:class: warning
- The "Create new document indexes" permission is required for this action.
- The "Edit document indexes" permission is required for this action, globally
of via an ACL for a document index.
- The "Edit document types" permission is required for this action, globally
of via an ACL for a document type.
This index will create one level for each document type in the system and place This index will create one level for each document type in the system and place
links to the document of each respective type. links to the document of each respective type.
#. Go to the :menuselection:`System --> Setup --> Indexes` menu. #. Go to the :menuselection:`System --> Setup --> Indexes` menu.
#. Create a new index using :guilabel:`Actions` > :guilabel:`Create new`. #. Create a new index using :menuselection:`Actions --> Create new`.
#. Give it a label to describe it, and an internal name. The internal name is #. Give it a label to describe it, and an internal name. The internal name is
used when referencing this index in other parts of the system. used when referencing this index in other parts of the system.
#. Press the :guilabel:`Template` link of the newly created index. #. Press the :menuselection:`Template` link of the newly created index.
#. Select :guilabel:`New child node` to create a new level in which the #. Select :menuselection:`New child node` to create a new level in which the
following template code will be entered. following template code will be entered.
:: ::
{{ document.document_type }} {{ document.document_type }}
#. Save the template. #. Save the template.
#. Click on :guilabel:`Document types` and associate this index with #. Go to :menuselection:`Document types` and associate this index with
existing document types in the system. existing document types in the system.
#. Finally go to :menuselection:`Tools --> Rebuild indexes` to execute the #. Finally go to :menuselection:`Tools --> Rebuild indexes` to execute the
index template. The rebuild process is only necessary when changes are index template. The rebuild process is only necessary when changes are
@@ -111,8 +101,8 @@ Index documents not found in any cabinet
{% if document.cabinets.count == 0 %}No Cabinets{% endif %} {% if document.cabinets.count == 0 %}No Cabinets{% endif %}
Index documents not tagged Index untagged documents
^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
:: ::
{% if document.tags.count == 0 %}No Tags{% endif %} {% if document.tags.count == 0 %}No Tags{% endif %}

View File

@@ -6,7 +6,7 @@ The list of languages choices in the language dropdown used for documents is
based on the current ISO 639 list. This list can be quite extensive. To reduce based on the current ISO 639 list. This list can be quite extensive. To reduce
the number of languages available use the setting ``DOCUMENTS_LANGUAGE_CODES``, the number of languages available use the setting ``DOCUMENTS_LANGUAGE_CODES``,
and set it to a nested list of abbreviations. This setting can be found in the and set it to a nested list of abbreviations. This setting can be found in the
:menuselection:`System --> Setup --> Settings --> Common` menu. :menuselection:`System --> Setup -> Settings -> Common` menu.
For example, to reduce the list to just English and Spanish use For example, to reduce the list to just English and Spanish use
:: ::

View File

@@ -26,74 +26,3 @@ interpret and modify the value provided by the user to a conform to a specific
format. An example of a provided parser is the date parser which will interpret format. An example of a provided parser is the date parser which will interpret
and correct dates provided by users regardless of the format in which they are and correct dates provided by users regardless of the format in which they are
entered. entered.
Creating metadata types
=======================
.. admonition:: Permissions required
:class: warning
The "Create new metadata types" permission is required for this action.
#. Go to the :menuselection:`System --> Setup --> Metadata types` menu.
#. From the :guilabel:`Actions` dropdown select :guilabel:`Create new`.
#. Provide a name to reference this metadata type in other parts of the system.
#. Enter a label to be shown to users when using this metadata type.
#. Optional: Enter a default value for the metadata type.
#. Optional: Provide a comma separated list of options to restrict the data entry
when using this metadata type.
#. Optional: Select a validator and a parser to validate and cleanup the data
entry when not using a predetermined list of values.
#. Press :guilabel:`Submit`.
Assigning a metadata type to a document type
============================================
.. admonition:: Permissions required
:class: warning
- The "Edit metadata types" permission is required for this action, globally or
via an ACL for a metadata type.
- Also the "Edit document type" permission
is required, globally or via an ACL for a document type.
This action can be performed in two ways.
Option 1: Via the metadata type view
------------------------------------
#. Go to the :menuselection:`System --> Setup --> Metadata types` menu.
#. Click on the button :guilabel:`Document types` of the metadata type you which
to associate.
#. From the list of existing document types press either:
- :guilabel:`None` if this metadata type will not be available for documents
of the type.
- :guilabel:`Optional` if this metadata type will be available and is
optional to provide a value for documents of the type.
- :guilabel:`Required` if this metadata type will be available and is
required to provide a value for documents of the type.
#. Press :guilabel:`Save`.
Option 2: Via the document type view
------------------------------------
#. Go to the :menuselection:`System --> Setup --> Document types` menu.
#. Click on the button :guilabel:`Metadata types` of the metadata type you which
to associate.
#. From the list of existing metadata types press either:
- :guilabel:`None` if this metadata type will not be available for documents
of the type.
- :guilabel:`Optional` if this metadata type will be available and is
optional to provide a value for documents of the type.
- :guilabel:`Required` if this metadata type will be available and is
required to provide a value for documents of the type.
#. Press :guilabel:`Save`.

View File

@@ -1,70 +0,0 @@
************
Quick labels
************
Quick labels are predetermined filenames that allow the quick renaming of
documents as they are uploaded or after they have been uploaded.
Quick labels are added and associated to a document type.
Example of quick label: Invoice, Receipt from X store, Purchase order.
It is possible to preserve the file extension when using quick labels.
Extensions are required for some operating system to be able to detect the
correct file type to access the content.
For example if a document file is named "file0001.pdf" and the quick label
"Receipt from X store" is applied, the resulting document label will be
"Receipt from X store.pdf".
Creating quick labels
=====================
.. admonition:: Permissions required
:class: warning
The "Edit document types" permission is required for this action, either
globally or via an ACL for a document type.
Since quick labels are associated with document types, creating quick labels
must be done from the document type view.
#. Go to the :menuselection:`System --> Setup --> Document types` menu.
#. In the document type list, click on the :guilabel:`Quick labels` button of
the document type for which you wish to create a quick label.
#. In the view titled "Quick labels for document type: <your document type>",
from the :guilabel:`Actions` dropdown select :guilabel:`Add quick label to document type`.
#. At the quick label creation form enter the desired label and press :guilabel:`Save`.
Using quick labels during upload
================================
#. Use the new document upload wizard from :menuselection:`Documents --> New document`.
#. Select a document type and navigate to the penultimate step, where you have
the option to drag and drop files to upload.
#. Select a an option from the :guilabel:`Quick document rename` dropdown.
#. Optionally select the :guilabel:`Preserve extension` checkbox to keep the file
extension.
#. Upload your documents.
Using quick labels for existing documents
=========================================
.. admonition:: Permissions required
:class: warning
The "Edit document properties" permission is required for this action, either
globally or via an ACL for a document or document type.
#. Navigate to the document preview view of the document to rename. Make sure
quick labels for the document type of the document select have been created.
#. From the :guilabel:`Actions` dropdown select :guilabel:`Edit Properties`.
#. Select a an option from the :guilabel:`Quick document rename` dropdown.
#. Optionally select the :guilabel:`Preserve extension` checkbox to keep the file
extension.
#. Press :guilabel:`Save` to rename the document.

View File

@@ -6,19 +6,15 @@ The default installation method fits most use cases. If you use case requires
more speed or capacity here are some suggestion that can help you improve the more speed or capacity here are some suggestion that can help you improve the
performance of your installation. performance of your installation.
Change the database manager Change the database manager
=========================== ===========================
Use PostgreSQL or MySQL as the database manager. Use PostgreSQL or MySQL as the database manager.
Tweak the memory setting of the database manager to increase memory allocation. Tweak the memory setting of the database manager to increase memory allocation.
More PostgreSQL specific examples are available in their wiki page: More PostgreSQL specific examples are available in their wiki page:
https://wiki.postgresql.org/wiki/Performance_Optimization https://wiki.postgresql.org/wiki/Performance_Optimization
Increase the number of Gunicorn workers Increase the number of Gunicorn workers
======================================= =======================================
The Gunicorn workers process HTTP requests and affect the speed at which the The Gunicorn workers process HTTP requests and affect the speed at which the
website responds. website responds.
@@ -37,7 +33,6 @@ And increase the value of the ``-w 2`` argument. This line is found in the
Background task processing Background task processing
========================== ==========================
The Celery workers are system processes that take care of the background The Celery workers are system processes that take care of the background
tasks requested by the frontend interactions like document image rendering tasks requested by the frontend interactions like document image rendering
and periodic tasks like OCR. There are several dozen tasks defined in the code. and periodic tasks like OCR. There are several dozen tasks defined in the code.
@@ -50,9 +45,37 @@ low volume, medium duration tasks. It is not advisable to have the same
worker processing OCR to process image rendering too. If the worker is worker processing OCR to process image rendering too. If the worker is
processing several OCR tasks it will not be able to provide fast images processing several OCR tasks it will not be able to provide fast images
when an user is browsing the user interface. This is why by default the when an user is browsing the user interface. This is why by default the
queues are split into 3 workers: fast, medium, and slow. Each worker will handle queues are split into 3 workers: fast, medium, and slow.
queues based on the latency required by each queue group.
The fast worker handles the queues:
* converter: Handles document page rendering
* sources_fast: Does staging file image rendering
The medium worker handles the queues:
* checkouts_periodic: Scheduled tasks that check if a document's checkout
period has expired
* documents_periodic:
* indexing: Does reindexing of documents in the background when their
properties change
* metadata:
* sources:
* sources_periodic: Checking email accounts and watch folders for new
documents.
* uploads: Processes files to turn the into Mayan documents. Processing
encompasses MIME type detection, page count detection.
* documents:
The slow worker handles the queues:
* mailing: Does the actual sending of documents via email as requested by
users via the mailing profiles
* tools: Executes in the background maintenance requests from the options
in the tools menu
* statistics: Recalculates statistics and charts
* parsing: Parses documents to extract actual text content
* ocr: Performs OCR to transcribe page images to text
Optimizations Optimizations
------------- -------------
@@ -65,16 +88,15 @@ Optimizations
* By default each worker process uses 1 thread. You can increase the thread * By default each worker process uses 1 thread. You can increase the thread
count of each worker process with the Docker environment options: count of each worker process with the Docker environment options:
* ``MAYAN_WORKER_FAST_CONCURRENCY`` * MAYAN_WORKER_FAST_CONCURRENCY
* ``MAYAN_WORKER_MEDIUM_CONCURRENCY`` * MAYAN_WORKER_MEDIUM_CONCURRENCY
* ``MAYAN_WORKER_SLOW_CONCURRENCY`` * MAYAN_WORKER_SLOW_CONCURRENCY
* If using direct deployment, increase the value of the ``--concurrency=1`` * If using direct deployment, increase the value of the --concurrency=1
argument of each worker in the supervisor file. You can also remove this argument of each worker in the supervisor file. You can also remove this
argument and let the Celery algorithm choose the number of threads to argument and let the Celery algorithm choose the number of threads to
launch. Usually this defaults to the number of CPU cores + 1. launch. Usually this defaults to the number of CPU cores + 1.
Change the message broker Change the message broker
========================= =========================
Messages are the method of communication between front end interactive code Messages are the method of communication between front end interactive code
@@ -105,13 +127,11 @@ calculation, these are stored for a while so that whoever requested the
background task, is able retrieve the result. These results are stored in the background task, is able retrieve the result. These results are stored in the
result storage. By default a Redis server is launched inside the Mayan EDMS result storage. By default a Redis server is launched inside the Mayan EDMS
container. You can launch a separate Docker Redis container and tell the Mayan container. You can launch a separate Docker Redis container and tell the Mayan
EDMS container to use this via the ``MAYAN_CELERY_RESULT_BACKEND`` environment EDMS container to use this via the MAYAN_CELERY_RESULT_BACKEND environment
variable. The format of this variable is explained here: http://docs.celeryproject.org/en/3.1/configuration.html#celery-result-backend variable. The format of this variable is explained here: http://docs.celeryproject.org/en/3.1/configuration.html#celery-result-backend
Deployment type Deployment type
=============== ===============
Docker provides a faster deployment and the overhead is not high on modern Docker provides a faster deployment and the overhead is not high on modern
systems. It is however memory and CPU limited by default and you need to systems. It is however memory and CPU limited by default and you need to
increase this limits. The settings to change the container resource limits increase this limits. The settings to change the container resource limits
@@ -120,10 +140,8 @@ are here: https://docs.docker.com/config/containers/resource_constraints/#limit-
For the best performance possible use the advanced deployment method on a For the best performance possible use the advanced deployment method on a
host dedicated to serving only Mayan EDMS. host dedicated to serving only Mayan EDMS.
Storage Storage
======= =======
For best input and output speed use a block based local filesystem on an For best input and output speed use a block based local filesystem on an
SSD drive for the ``/media`` sub folder. The location of the ``/media`` folder SSD drive for the ``/media`` sub folder. The location of the ``/media`` folder
will be specified by the ``MEDIA_ROOT`` setting. will be specified by the ``MEDIA_ROOT`` setting.
@@ -131,10 +149,8 @@ will be specified by the ``MEDIA_ROOT`` setting.
If capacity is your bottom line, switch to an If capacity is your bottom line, switch to an
:doc:`object storage <../chapters/object_storage>` system. :doc:`object storage <../chapters/object_storage>` system.
Use additional hosts Use additional hosts
==================== ====================
When one host is not enough you can use multiple hosts and share the load. When one host is not enough you can use multiple hosts and share the load.
Make sure that all hosts share the ``/media`` folder as specified by the Make sure that all hosts share the ``/media`` folder as specified by the
``MEDIA_ROOT`` setting, also the database, the broker, and the result storage. ``MEDIA_ROOT`` setting, also the database, the broker, and the result storage.

View File

@@ -11,7 +11,6 @@ signatures sections of a document.
.. blockdiag:: .. blockdiag::
blockdiag { blockdiag {
orientation = portrait orientation = portrait
span_width = 240; span_width = 240;

View File

@@ -51,29 +51,7 @@ The current document sources supported are:
web -> manual; web -> manual;
} }
Document sources can be configure to allow document bundles to uploaded as Document source can be configure to allow document bundles to uploaded as
compressed files which are decompressed and their content uploaded as separate compressed files which are decompressed and their content uploaded as separate
documents. This feature is useful when migrating from another document documents. This feature is useful when migrating from another document
manager system. manager system.
.. note::
If you deployed a Mayan EDMS Docker container and want to use watched folders
or staging folder, refer to the Docker chapter :ref:`docker-accessing-outside-data`.
Creating new sources
====================
.. admonition:: Permissions required
:class: warning
The "Create new document sources" permission is required for this action.
#. Go to the :menuselection:`System --> Setup --> Sources` menu.
#. From the :guilabel:`Actions` dropdown select the new type of source to create.
#. Each source type will have different fields to customize its behavior. Enter
the required information in each field based on the help text provided.
#. Press :guilabel:`Save`.

View File

@@ -5,6 +5,10 @@ Tags are color coded properties that can be attached or removed from documents.
Tags allow giving documents a binary property. Documents can also be tagged Tags allow giving documents a binary property. Documents can also be tagged
with more than one tag. with more than one tag.
Tags are created from the :menuselection:`Tags --> Create` menu.
To view all created tags use the :menuselection:`Tags --> All` menu.
Once tagged, documents can be searched by their tags. It is also possible to Once tagged, documents can be searched by their tags. It is also possible to
show all the documents tagged with a particular show all the documents tagged with a particular
tag via the **Documents** link of each tag. tag via the **Documents** link of each tag.
@@ -17,30 +21,3 @@ more tags to the document and another to remove tags from the document.
It is also possible to tag documents in bulk by selecting several documents It is also possible to tag documents in bulk by selecting several documents
from any view that displays a list documents and selecting the **Attach tag** from any view that displays a list documents and selecting the **Attach tag**
or **Remove tags** from the dropdown menu. or **Remove tags** from the dropdown menu.
Creating tags
=============
.. admonition:: Permissions required
:class: warning
The "Create new tags" permission is required for this action.
#. Go to the :menuselection:`Tags --> Create` menu.
#. Enter a label to identify the tag.
#. Select a color for the tag.
#. Press :guilabel:`Submit`.
View all tags
=============
.. admonition:: Permissions required
:class: warning
The "View tags" permission is required for this action, globally or via an
ACL for a tag.
#. Go to the :menuselection:`Tags --> All` menu.

View File

@@ -46,35 +46,3 @@ There is no limit to the number of versions a document can have.
By default, the last version will be showed when working with the document By default, the last version will be showed when working with the document
but any of the versions can be inspected and viewed. but any of the versions can be inspected and viewed.
View a document version list
============================
.. admonition:: Permissions required
:class: warning
The "View documents' versions list" permission is required for this action,
either globally or via an ACL for a document or document type.
#. Navigate to the select document's preview view.
#. Click on the sibebar's :guilabel:`Versions` button.
Uploading a new document version
================================
.. admonition:: Permissions required
:class: warning
The "Create new document versions" permission is required for this action,
either globally or via an ACL for a document or document type.
#. Navigate to the select document's versions list view.
#. From the :guilabel:`Actions` dropdown select :guilabel:`Upload new version`.
#. Optionally type a comment explaining the changes in the new version.
#. Press the :guilabel:`Browse` button and select a new file.
#. Press :guilabel:`Save` upload the new version.

View File

@@ -5,7 +5,7 @@ Workflows
Introduction Introduction
============ ============
Workflows provide a structured method for storing a sequence of states over Workflows provide a structure method for storing a sequence of states over
which the a document will progress. Workflows keep track how a document has which the a document will progress. Workflows keep track how a document has
been processed so far. been processed so far.
@@ -20,36 +20,6 @@ provide and order for the sequence of possible states changes.
Transitions can be executed manually by users if they have the required access Transitions can be executed manually by users if they have the required access
level as configure by the system administrator. level as configure by the system administrator.
.. blockdiag::
:caption: Example workflow. Circles represent states, rectangles represent transitions.
span_width = 30;
submitted [shape = circle, width = 60, height = 60];
approved [shape = circle, width = 60, height = 60];
rejected [shape = circle, width = 60, height = 60];
archived [shape = circle, width = 60, height = 60];
approve [label = approve];
reject [label = reject];
reopen [label = "re-open"];
submitted -> approve -> approved;
approved -> archived;
submitted -> reject -> rejected;
rejected -> archived;
archived -> reopen -> submitted;
Workflows in Mayan EDMS are implemented as finite state machines
(https://en.wikipedia.org/wiki/Finite-state_machine).
Workflows are mainly used to represent business processes. But they can also be
used an automation system to customized Mayan EDMS and have it perform some
tasks automatically.
Automation Automation
========== ==========
@@ -96,18 +66,26 @@ Implementation
============== ==============
Internally, workflows are implemented as a finite state machines Internally, workflows are implemented as a finite state machines
(https://en.wikipedia.org/wiki/Finite-state_machine). To make them simpler to (https://en.wikipedia.org/wiki/Finite-state_machine). And have the limitation
use, workflow have been designed so that only one state can be the current that only one state can be the current active state for a workflow being
active state for a workflow being executed. Another design decision is that executed. The other limitation of the current implementation is that every
every workflow needs at least one state marked as the initial state. workflow needs at least one state marked as the initial state. These limitations
are the result of a compromised in the design between flexibility and ease of
use.
Visualizations Visualizations
============== ==============
The graphical representation of a workflow is similar to a flowchart. The The graphical representation of a workflow (or a finite state machine style
states are represented with circles. The transitions are represented with in Mayan EDMS's case) is similar to a flowchart. The states are represented
arrows. Circle with a double border represent the initial state of the workflow. with circles. The transitions are represented with arrows. Circle with a
double border represent the initial state of the workflow.
To view the graphical representations of workflow use **Preview** button of To view the graphical representations of workflow use **Preview** button of
the workflow in the setup view. the workflow in the setup view.
We are working now on workflow transition trigger filters to have
the trigger move the state of the workflow on certain conditions. For example: Attach a tag if there is a specific word found in the OCR text.

View File

@@ -249,6 +249,3 @@ extlinks = {
'https://gitlab.com/mayan-edms/mayan-edms/issues/%s', 'GitLab issue #' 'https://gitlab.com/mayan-edms/mayan-edms/issues/%s', 'GitLab issue #'
) )
} }
def setup(app):
app.add_stylesheet('css/custom.css')

View File

@@ -21,14 +21,12 @@ repository for electronic documents.
topics/installation topics/installation
releases/index releases/index
topics/getting_started topics/getting_started
topics/adding_documents
topics/access_control topics/access_control
topics/categorization topics/categorization
topics/collaboration topics/collaboration
topics/settings topics/settings
topics/storage topics/storage
topics/integration topics/integration
topics/docker
topics/advanced topics/advanced
topics/administration topics/administration
topics/troubleshooting topics/troubleshooting

View File

@@ -31,9 +31,9 @@ for Mayan EDMS. Most MERCs will be Feature MERCs.
2. An **Informational** MERC describes a Mayan EDMS design issue, or 2. An **Informational** MERC describes a Mayan EDMS design issue, or
provides general guidelines or information to the Mayan EDMS community, provides general guidelines or information to the Mayan EDMS community,
but does not propose a new feature. Informational MERCs do not but does not propose a new feature. Informational MERCs do not
necessarily represent a community consensus or recommendation, so users necessarily represent a community consensus or
and implementers are free to ignore Informational MERCs or follow their recommendation, so users and implementers are free to ignore
advice. Informational MERCs or follow their advice.
3. A **Process** MERC describes a process surrounding Mayan EDMS, or 3. A **Process** MERC describes a process surrounding Mayan EDMS, or
proposes a change to (or an event in) a process. Process MERCs are proposes a change to (or an event in) a process. Process MERCs are

View File

@@ -1,6 +1,6 @@
==================== =====================
MERC 2: Test writing MERC 2: Test writing
==================== =====================
:MERC: 2 :MERC: 2
:Author: Michael Price :Author: Michael Price

View File

@@ -1,149 +0,0 @@
==========================
MERC 5: Explicit arguments
==========================
:MERC: 5
:Author: Roberto Rosario
:Status: Accepted
:Type: Feature
:Created: 2018-12-30
:Last-Modified: 2018-12-31
.. contents:: Table of Contents
:depth: 3
:local:
Abstract
========
This MERC proposes the adoption of a new methodology when performing calls.
It seeks to reduce the use of positional arguments in favor of keyword
arguments in as many places as possible.
Motivation
==========
As the project grows, legibility of code becomes more important. Keyword
argument help document the use of services, classes and functions. Refactors
that affect the interface of services are also easier to find and update and
fix. Positional argument can cause a call to continue working as long as the
datatype of the argument remains the same. Usage of keyword arguments will
automatically raise and error that will prevent such situations. Keyword
argument further eliminate the relevance of position or the arguments, and
the arguments can be sorted alphabetically for easier visual scanning or by
semantic significance improving code readability.
Specification
=============
Adoption of this MERC will require an audit of existing calls and the use
of the method proposed for new calls. Every call regardless of the type or
origin of the source callable will name each argument used. By type it is
meant: classes, functions, methods. Origin means: local from the project,
from the framework, third party libraries or the standard library.
Backwards Compatibility
=======================
No backwards compatibility issues are expected. New errors arising from the use
if keyword arguments could be interpreted as existing latent issues that
have not been uncovered.
Reference Implementation
========================
Example:
Before:
.. code-block:: python
from mayan.apps.common.classes import Template
Template(
'menu_main', 'appearance/menu_main.html'
)
After:
.. code-block:: python
from mayan.apps.common.classes import Template
Template(
name='menu_main', template_name='appearance/menu_main.html'
)
When calls use a mixture or positional and keyword arguments, the keywords
arguments can only be found after the positional arguments. Complete use
of keyword arguments allow the reposition of arguments for semantic
purposes.
Example:
Before:
.. code-block:: python
from django.conf.urls import url
from .views import AboutView, HomeView, RootView
urlpatterns = [
url(r'^$', RootView.as_view(), name='root'),
url(r'^home/$', HomeView.as_view(), name='home'),
url(r'^about/$', AboutView.as_view(), name='about_view'),
]
After:
.. code-block:: python
from django.conf.urls import url
from .views import AboutView, HomeView, RootView
urlpatterns = [
url(regex=r'^$', name='root', view=RootView.as_view()),
url(regex=r'^home/$', name='home', view=HomeView.as_view()),
url(regex=r'^about/$', name='about_view', view=AboutView.as_view()),
]
Keyword arguments should also be used for callables that pass those to others
down the line like Django's ``reverse`` function. Any change to the name of
the ``pk`` URL parameter will raise an exception in this code alerting to
any possible incompatible use.
Example:
.. code-block:: python
def get_absolute_url(self):
return reverse(
viewname='documents:document_preview', kwargs={'pk': self.pk}
)
This becomes even more important when multiple URL parameters are used. Since
the API documentation is auto generated from the code itself, it would make
sense to rename the first URL parameter from ``pk`` to ``document_pk``. Such
change will cause all address to view resolutions to break forcing their
update and allowing all consumers' interface usage to remain synchronized to the
callable's interface.
.. code-block:: python
url(
regex=r'^documents/(?P<pk>[0-9]+)/versions/(?P<document_version_pk>[0-9]+)/pages/(?P<document_page_pk>[0-9]+)/image/$',
name='documentpage-image', view=APIDocumentPageImageView.as_view()
),

View File

@@ -1,81 +0,0 @@
==================================
MERC 6: Lower information disclose
==================================
:MERC: 6
:Author: Michael Price
:Status: Accepted
:Type: Feature
:Created: 2018-12-30
:Last-Modified: 2018-12-31
.. contents:: Table of Contents
:depth: 3
:local:
Abstract
========
This MERC proposes the use of errors that don't disclose the existence of a
resource in the event that the requester doesn't have the required credentials.
Motivation
==========
When an user tries to perform an action like opening a view to a document for
which the required permission is missing, a permission required or access
denied error is presented. This is semantically correct, but from the stand
point of security it is still failing because it is letting the user know
that such document exists in the first place. This MERC proposes changing the
error message for existing resource to one that doesn't divulge any information
to unauthorized parties, like "Not Found".
Specification
=============
Out of the 4 basic CRUD operations, Read, Update and Delete should return an
HTTP 404 error instead of an HTTP 403 error. Only the Create operation will
continue returning the current HTTP 403 error, unless it is creating a
new resource that is related to an existing resource.
Since most view use the internal custom CRUD classes making a change to the
``ObjectPermissionCheckMixin`` class to raise an HTTP 404 on object access
failure will fulfill the proposal of this MERC.
Adding the ``object_permission_raise_404`` class attribute and setting it
to default to False will allow fulfilling the goal of this MERC while
keeping the existing functionality intact.
Example:
.. code-block:: python
class ObjectPermissionCheckMixin(object):
"""
If object_permission_raise_404 is True an HTTP 404 error will be raised
instead of the normal 403.
"""
object_permission = None
object_permission_raise_404 = False
def get_permission_object(self):
return self.get_object()
def dispatch(self, request, *args, **kwargs):
if self.object_permission:
try:
AccessControlList.objects.check_access(
permissions=self.object_permission, user=request.user,
obj=self.get_permission_object(),
related=getattr(self, 'object_permission_related', None)
)
except PermissionDenied:
if self.object_permission_raise_404:
raise Http404
else:
raise
return super(
ObjectPermissionCheckMixin, self
).dispatch(request, *args, **kwargs)

View File

@@ -20,8 +20,6 @@ Accepted
../mercs/0001-merc-process ../mercs/0001-merc-process
../mercs/0002-test-writing ../mercs/0002-test-writing
../mercs/0003-using-javascript-libraries ../mercs/0003-using-javascript-libraries
../mercs/0005-explicit-arguments
../mercs/0006-lower-information-disclose
Draft Draft
----- -----
@@ -51,5 +49,3 @@ Feature
../mercs/0002-test-writing ../mercs/0002-test-writing
../mercs/0003-using-javascript-libraries ../mercs/0003-using-javascript-libraries
../mercs/0005-explicit-arguments
../mercs/0006-lower-information-disclose

View File

@@ -63,5 +63,5 @@ Changes needed:
the Role model's permissions many to many field. the Role model's permissions many to many field.
4. Update the ``AccessControlList`` models roles field to point to the group 4. Update the ``AccessControlList`` models roles field to point to the group
models. models.
5. Update the role checks in the ``check_access`` and ``restrict_queryset`` 5. Update the role checks in the ``check_access`` and ``filter_by_access``
``AccessControlList`` model manager methods. ``AccessControlList`` model manager methods.

View File

@@ -17,11 +17,11 @@ Version 0.11
* Added a view to delete the document image cache, useful when switching * Added a view to delete the document image cache, useful when switching
converter backends or doing diagnostics. converter backends or doing diagnostics.
* Added South to the requirements. * Added South to the requirements.
* Merged documents' filename and extension database fields into a single * Merged documents' filename and extension database fiels into a single
filename field, filename are store as uploaded not manipulation is done filename field, filename are store as uploaded not manipulation is done
Users with existing data must install South and run the appropriate Users with existing data must install South and run the appropiate
migrate commands:: migrate commands::
$ pip install -r requirements/production.txt $ pip install -r requirements/production.txt
$ ./manager syncdb $ ./manager syncdb
$ ./manage.py migrate documents 0001 --fake $ ./manage.py migrate documents 0001 --fake
@@ -30,5 +30,5 @@ Version 0.11
* Added new office document mimetype * Added new office document mimetype
* application/vnd.ms-office * application/vnd.ms-office
* Fixed documents not saving the file encoding * Fixed documents not saving the file encoding
* Removed extra slash in ajax-loader.gif URL fixes #15, thanks to * Removed extra slash in ajax-loader.gif URL fixes #15, thanks to
IHLeanne for finding this one IHLeanne for finding this one

View File

@@ -1,119 +0,0 @@
Version 3.2.1
=============
Released: June 14, 2019
Changes
-------
- Fix sub cabinet creation view. Thanks to Frédéric Sheedy
(@fsheedy) for the report.
- Add PostgreSQL troubleshooting entry. Closes GitLab
issues #523 and #602
- Use YAML SafeDumper to avoid adding YAML datatype tags.
Closes GitLab issue #599. Thanks to Frédéric Sheedy
(@fsheedy) for the report and debug information.
- Add check for app references and point users to release notes for details.
GitLab issue #603. Thanks to Vikas Kedia (@vikaskedia) for the report.
- Remove sidebar floar right.
Fixed GitLab issue #600. Thanks to Frédéric Sheedy
(@fsheedy) for the report and debug information.
- Collapse sidebar on small screen
Display sidebar at the bottom of the screen on small displays.
Removals
--------
- None
Upgrading from a previous version
---------------------------------
If installed via Python's PIP
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Remove deprecated requirements::
$ curl https://gitlab.com/mayan-edms/mayan-edms/raw/master/removals.txt | pip uninstall -r /dev/stdin
Type in the console::
$ pip install mayan-edms==3.2.1
the requirements will also be updated automatically.
Using Git
^^^^^^^^^
If you installed Mayan EDMS by cloning the Git repository issue the commands::
$ git reset --hard HEAD
$ git pull
otherwise download the compressed archived and uncompress it overriding the
existing installation.
Remove deprecated requirements::
$ pip uninstall -y -r removals.txt
Next upgrade/add the new requirements::
$ pip install --upgrade -r requirements.txt
Common steps
^^^^^^^^^^^^
Perform these steps after updating the code from either step above.
Make a backup of your supervisord file::
sudo cp /etc/supervisor/conf.d/mayan.conf /etc/supervisor/conf.d/mayan.conf.bck
Update the supervisord configuration file. Replace the environment
variables values show here with your respective settings. This step will refresh
the supervisord configuration file with the new queues and the latest
recommended layout::
MAYAN_DATABASE_ENGINE=django.db.backends.postgresql MAYAN_DATABASE_NAME=mayan \
MAYAN_DATABASE_PASSWORD=mayanuserpass MAYAN_DATABASE_USER=mayan \
MAYAN_DATABASE_HOST=127.0.0.1 MAYAN_MEDIA_ROOT=/opt/mayan-edms/media \
/opt/mayan-edms/bin/mayan-edms.py platformtemplate supervisord > /etc/supervisor/conf.d/mayan.conf
Edit the supervisord configuration file and update any setting the template
generator missed::
vi /etc/supervisor/conf.d/mayan.conf
Migrate existing database schema with::
$ mayan-edms.py performupgrade
Add new static media::
$ mayan-edms.py preparestatic --noinput
The upgrade procedure is now complete.
Backward incompatible changes
-----------------------------
- None
Bugs fixed or issues closed
---------------------------
- :gitlab-issue:`523` PostgreSQL error about insufficient connections
- :gitlab-issue:`599` Settings display !!python/unicode with values since 3.2
- :gitlab-issue:`600` Layout broken if we change locale, since 3.2
- :gitlab-issue:`601` Error when creating new cabinet level
- :gitlab-issue:`602` System stops responding for a minute every 10 minutes or so
- :gitlab-issue:`603` ImportError: No module named appearance
.. _PyPI: https://pypi.python.org/pypi/mayan-edms/

View File

@@ -1,109 +0,0 @@
Version 3.2.2
=============
Released: June 19, 2019
Changes
-------
- Fix document type change view. Closes GitLab issue #614.
Thanks to Christoph Roeder (@brightdroid) for the report.
- Fix document parsing tool view typo. Closes GitLab issue #615.
Thanks to Tyler Page (@iamtpage) for the report.
- Update the task_check_interval_source reference
GitLab issue #617. Thanks to Lukas Gill (@lukkigi) for
the report and debug information.
Removals
--------
- None
Upgrading from a previous version
---------------------------------
If installed via Python's PIP
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Remove deprecated requirements::
$ curl https://gitlab.com/mayan-edms/mayan-edms/raw/master/removals.txt | pip uninstall -r /dev/stdin
Type in the console::
$ pip install mayan-edms==3.2.2
the requirements will also be updated automatically.
Using Git
^^^^^^^^^
If you installed Mayan EDMS by cloning the Git repository issue the commands::
$ git reset --hard HEAD
$ git pull
otherwise download the compressed archived and uncompress it overriding the
existing installation.
Remove deprecated requirements::
$ pip uninstall -y -r removals.txt
Next upgrade/add the new requirements::
$ pip install --upgrade -r requirements.txt
Common steps
^^^^^^^^^^^^
Perform these steps after updating the code from either step above.
Make a backup of your supervisord file::
sudo cp /etc/supervisor/conf.d/mayan.conf /etc/supervisor/conf.d/mayan.conf.bck
Update the supervisord configuration file. Replace the environment
variables values show here with your respective settings. This step will refresh
the supervisord configuration file with the new queues and the latest
recommended layout::
MAYAN_DATABASE_ENGINE=django.db.backends.postgresql MAYAN_DATABASE_NAME=mayan \
MAYAN_DATABASE_PASSWORD=mayanuserpass MAYAN_DATABASE_USER=mayan \
MAYAN_DATABASE_HOST=127.0.0.1 MAYAN_MEDIA_ROOT=/opt/mayan-edms/media \
/opt/mayan-edms/bin/mayan-edms.py platformtemplate supervisord > /etc/supervisor/conf.d/mayan.conf
Edit the supervisord configuration file and update any setting the template
generator missed::
vi /etc/supervisor/conf.d/mayan.conf
Migrate existing database schema with::
$ mayan-edms.py performupgrade
Add new static media::
$ mayan-edms.py preparestatic --noinput
The upgrade procedure is now complete.
Backward incompatible changes
-----------------------------
- None
Bugs fixed or issues closed
---------------------------
- :gitlab-issue:`614` change type exception
- :gitlab-issue:`615` TypeError: success() got an unexpected keyword argument 'requrest'
- :gitlab-issue:`617` Watcher Task not running
.. _PyPI: https://pypi.python.org/pypi/mayan-edms/

View File

@@ -1,113 +0,0 @@
Version 3.2.3
=============
Released: June 21, 2019
Changes
-------
- Add support for disabling the random primary key
test mixin.
- Fix mailing profile log columns mappings.
GitLab issue #626. Thanks to Jesaja Everling (@jeverling)
for the report.
- Fix the Django SMTP backend username field name.
GitLab issue #625. Thanks to Jesaja Everling (@jeverling)
for the report and the research.
- Increase the Django STMP username.
GitLab issue #625. Thanks to Jesaja Everling (@jeverling)
for the report and the research.
Removals
--------
- None
Upgrading from a previous version
---------------------------------
If installed via Python's PIP
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Remove deprecated requirements::
$ curl https://gitlab.com/mayan-edms/mayan-edms/raw/master/removals.txt | pip uninstall -r /dev/stdin
Type in the console::
$ pip install mayan-edms==3.2.1
the requirements will also be updated automatically.
Using Git
^^^^^^^^^
If you installed Mayan EDMS by cloning the Git repository issue the commands::
$ git reset --hard HEAD
$ git pull
otherwise download the compressed archived and uncompress it overriding the
existing installation.
Remove deprecated requirements::
$ pip uninstall -y -r removals.txt
Next upgrade/add the new requirements::
$ pip install --upgrade -r requirements.txt
Common steps
^^^^^^^^^^^^
Perform these steps after updating the code from either step above.
Make a backup of your supervisord file::
sudo cp /etc/supervisor/conf.d/mayan.conf /etc/supervisor/conf.d/mayan.conf.bck
Update the supervisord configuration file. Replace the environment
variables values show here with your respective settings. This step will refresh
the supervisord configuration file with the new queues and the latest
recommended layout::
MAYAN_DATABASE_ENGINE=django.db.backends.postgresql MAYAN_DATABASE_NAME=mayan \
MAYAN_DATABASE_PASSWORD=mayanuserpass MAYAN_DATABASE_USER=mayan \
MAYAN_DATABASE_HOST=127.0.0.1 MAYAN_MEDIA_ROOT=/opt/mayan-edms/media \
/opt/mayan-edms/bin/mayan-edms.py platformtemplate supervisord > /etc/supervisor/conf.d/mayan.conf
Edit the supervisord configuration file and update any setting the template
generator missed::
vi /etc/supervisor/conf.d/mayan.conf
Migrate existing database schema with::
$ mayan-edms.py performupgrade
Add new static media::
$ mayan-edms.py preparestatic --noinput
The upgrade procedure is now complete.
Backward incompatible changes
-----------------------------
- None
Bugs fixed or issues closed
---------------------------
- :gitlab-issue:`619` poplib.POP3_SSL and poplib.POP3 initialized with wrong kwarg
- :gitlab-issue:`625` mayan.apps.mailer.mailers.DjangoSMTP uses "user", but django.core.mail.backends.smtp.EmailBackend expects "username"
- :gitlab-issue:`626` Mailing profile error log is empty, despite errors
.. _PyPI: https://pypi.python.org/pypi/mayan-edms/

View File

@@ -1,131 +0,0 @@
Version 3.2.4
=============
Released: June 29, 2019
Changes
-------
- Support configurable GUnicorn timeouts. Defaults to
current value of 120 seconds.
- Fix help text of the platformtemplate command.
- Fix IMAP4 mailbox.store flags argument. Python's documentation
incorrectly state it is named flag_list. Closes GitLab issue
#606. Thanks to Samuel Aebi (@samuelaebi) for the report and
debug information.
- Support configurable GUnicorn timeouts. Defaults to
current value of 120 seconds.
- Fix help text of the platformtemplate command.
- Fix IMAP4 mailbox.store flags argument. Python's documentation
incorrectly state it is named flag_list. Closes GitLab issue
#606.
- Improve the workflow preview generation. Use polylines
instead of splines. Add state actions to the preview.
Highlight the initial state.
- Add help text to the workflow transition form comment field.
- Fix direct deployment instructions.
- Add user, group, and role dashboard widgets.
- Add test mixin detect database connection leaks.
- Remove tag create event registration from the tag
instances. The tag create event is not applicable to
existing tags.
- Add proper redirection after moving a document to the
trash.
- Remove the INSTALLED_APPS setting. Replace it with
the new COMMON_EXTRA_APPS and COMMON_DISABLED_APPS.
- Improve email metadata support. Can now work on
email with nested parts. Also the metadata.yaml
attachment no longer needs to be the first attachment.
Removals
--------
- None
Upgrading from a previous version
---------------------------------
If installed via Python's PIP
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Remove deprecated requirements::
$ curl https://gitlab.com/mayan-edms/mayan-edms/raw/master/removals.txt | pip uninstall -r /dev/stdin
Type in the console::
$ pip install mayan-edms==3.2.4
the requirements will also be updated automatically.
Using Git
^^^^^^^^^
If you installed Mayan EDMS by cloning the Git repository issue the commands::
$ git reset --hard HEAD
$ git pull
otherwise download the compressed archived and uncompress it overriding the
existing installation.
Remove deprecated requirements::
$ pip uninstall -y -r removals.txt
Next upgrade/add the new requirements::
$ pip install --upgrade -r requirements.txt
Common steps
^^^^^^^^^^^^
Perform these steps after updating the code from either step above.
Make a backup of your supervisord file::
sudo cp /etc/supervisor/conf.d/mayan.conf /etc/supervisor/conf.d/mayan.conf.bck
Update the supervisord configuration file. Replace the environment
variables values show here with your respective settings. This step will refresh
the supervisord configuration file with the new queues and the latest
recommended layout::
sudo MAYAN_DATABASE_ENGINE=django.db.backends.postgresql MAYAN_DATABASE_NAME=mayan \
MAYAN_DATABASE_PASSWORD=mayanuserpass MAYAN_DATABASE_USER=mayan \
MAYAN_DATABASE_HOST=127.0.0.1 MAYAN_MEDIA_ROOT=/opt/mayan-edms/media \
/opt/mayan-edms/bin/mayan-edms.py platformtemplate supervisord > /etc/supervisor/conf.d/mayan.conf
Edit the supervisord configuration file and update any setting the template
generator missed::
sudo vi /etc/supervisor/conf.d/mayan.conf
Migrate existing database schema with::
$ mayan-edms.py performupgrade
Add new static media::
$ mayan-edms.py preparestatic --noinput
The upgrade procedure is now complete.
Backward incompatible changes
-----------------------------
- None
Bugs fixed or issues closed
---------------------------
- :gitlab-issue:`606` Delete after IMAP Processing
- :gitlab-issue:`628` mailbox.user in POP3Email gets passed keyword argument, but only accepts "user" or positional argument
.. _PyPI: https://pypi.python.org/pypi/mayan-edms/

View File

@@ -1,117 +0,0 @@
Version 3.2.5
=============
Released: July 05, 2019
Changes
-------
- Don't error out if the EXTRA_APPS or the DISABLED_APPS settings
are set to blank.
- Update troubleshooting documentation topic.
- Add data migration to the file metadata app. Synchronizes the
document type settings model of existing document types.
- Fix cabinet and tags upload wizard steps missing some entries.
GitLab issue #632. Thanks to Matthias Urhahn (@d4rken) for the
report.
- Add alert when settings are changed and util the installation
is restarted. GitLab issue #605. Thanks to
Vikas Kedia (@vikaskedia) to the report.
- Update Django to version 1.11.22, PyYAML to version 5.1.1,
django-widget-tweaks to version 1.4.5, pathlib2 to version 2.3.4,
Werkzeug to version 0.15.4, django-extensions to version 2.1.9,
django-rosetta to version 0.9.3, psutil to version 5.6.3.
Removals
--------
- None
Upgrading from a previous version
---------------------------------
If installed via Python's PIP
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Remove deprecated requirements::
$ curl https://gitlab.com/mayan-edms/mayan-edms/raw/master/removals.txt | pip uninstall -r /dev/stdin
Type in the console::
$ pip install mayan-edms==3.2.5
the requirements will also be updated automatically.
Using Git
^^^^^^^^^
If you installed Mayan EDMS by cloning the Git repository issue the commands::
$ git reset --hard HEAD
$ git pull
otherwise download the compressed archived and uncompress it overriding the
existing installation.
Remove deprecated requirements::
$ pip uninstall -y -r removals.txt
Next upgrade/add the new requirements::
$ pip install --upgrade -r requirements.txt
Common steps
^^^^^^^^^^^^
Perform these steps after updating the code from either step above.
Make a backup of your supervisord file::
sudo cp /etc/supervisor/conf.d/mayan.conf /etc/supervisor/conf.d/mayan.conf.bck
Update the supervisord configuration file. Replace the environment
variables values show here with your respective settings. This step will refresh
the supervisord configuration file with the new queues and the latest
recommended layout::
sudo MAYAN_DATABASE_ENGINE=django.db.backends.postgresql MAYAN_DATABASE_NAME=mayan \
MAYAN_DATABASE_PASSWORD=mayanuserpass MAYAN_DATABASE_USER=mayan \
MAYAN_DATABASE_HOST=127.0.0.1 MAYAN_MEDIA_ROOT=/opt/mayan-edms/media \
/opt/mayan-edms/bin/mayan-edms.py platformtemplate supervisord > /etc/supervisor/conf.d/mayan.conf
Edit the supervisord configuration file and update any setting the template
generator missed::
sudo vi /etc/supervisor/conf.d/mayan.conf
Migrate existing database schema with::
$ mayan-edms.py performupgrade
Add new static media::
$ mayan-edms.py preparestatic --noinput
The upgrade procedure is now complete.
Backward incompatible changes
-----------------------------
- None
Bugs fixed or issues closed
---------------------------
- :gitlab-issue:`605` Project title fluctuates between default value and new value [Video]
- :gitlab-issue:`629` Cannot Upgrade to 3.2.X Docker Image
- :gitlab-issue:`632` Tags get lost when uploading through the webui
.. _PyPI: https://pypi.python.org/pypi/mayan-edms/

View File

@@ -1,111 +0,0 @@
Version 3.2.6
=============
Released: July 10, 2019
Changes
-------
- Remove the smart settings app * import. Following MERC 0005.
- Encode settings YAML before hashing. Avoids unicode issues with Python 3.
- Fix document icon used in the workflow runtime links.
- Add trashed date time label.
- Fix thumbnail generation issue. GitLab issue #637.
Thanks to Giacomo Cariello (@giacomocariello) for the report
and the merge request fixing the issue.
Removals
--------
- None
Upgrading from a previous version
---------------------------------
If installed via Python's PIP
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Remove deprecated requirements::
sudo -u mayan curl https://gitlab.com/mayan-edms/mayan-edms/raw/master/removals.txt -o /tmp/removals.txt && sudo -u mayan /opt/mayan-edms/bin/pip uninstall -y -r /tmp/removals.txt
Type in the console::
sudo -u mayan /opt/mayan-edms/bin/pip install mayan-edms==3.2.6
the requirements will also be updated automatically.
Using Git
^^^^^^^^^
If you installed Mayan EDMS by cloning the Git repository issue the commands::
$ git reset --hard HEAD
$ git pull
otherwise download the compressed archived and uncompress it overriding the
existing installation.
Remove deprecated requirements::
$ pip uninstall -y -r removals.txt
Next upgrade/add the new requirements::
$ pip install --upgrade -r requirements.txt
Common steps
^^^^^^^^^^^^
Perform these steps after updating the code from either step above.
Make a backup of your supervisord file::
sudo cp /etc/supervisor/conf.d/mayan.conf /etc/supervisor/conf.d/mayan.conf.bck
Update the supervisord configuration file. Replace the environment
variables values show here with your respective settings. This step will refresh
the supervisord configuration file with the new queues and the latest
recommended layout::
sudo MAYAN_DATABASE_ENGINE=django.db.backends.postgresql MAYAN_DATABASE_NAME=mayan \
MAYAN_DATABASE_PASSWORD=mayanuserpass MAYAN_DATABASE_USER=mayan \
MAYAN_DATABASE_HOST=127.0.0.1 MAYAN_MEDIA_ROOT=/opt/mayan-edms/media \
/opt/mayan-edms/bin/mayan-edms.py platformtemplate supervisord > /etc/supervisor/conf.d/mayan.conf
Edit the supervisord configuration file and update any setting the template
generator missed::
sudo vi /etc/supervisor/conf.d/mayan.conf
Migrate existing database schema with::
sudo -u mayan MAYAN_DATABASE_ENGINE=django.db.backends.postgresql MAYAN_DATABASE_NAME=mayan \
MAYAN_DATABASE_PASSWORD=mayanuserpass MAYAN_DATABASE_USER=mayan \
MAYAN_DATABASE_HOST=127.0.0.1 MAYAN_MEDIA_ROOT=/opt/mayan-edms/media \
/opt/mayan-edms/bin/mayan-edms.py performupgrade
Add new static media::
sudo -u mayan MAYAN_MEDIA_ROOT=/opt/mayan-edms/media \
/opt/mayan-edms/bin/mayan-edms.py preparestatic --noinput
The upgrade procedure is now complete.
Backward incompatible changes
-----------------------------
- None
Bugs fixed or issues closed
---------------------------
- :gitlab-issue:`637` Thumbnail generation bug
.. _PyPI: https://pypi.python.org/pypi/mayan-edms/

File diff suppressed because it is too large Load Diff

View File

@@ -1,166 +0,0 @@
Version 3.3
===========
Released: XX XX, 2019
Changes
-------
- Add support for icon shadows.
- Add icons and no-result template to the object error log view and
links.
- Use Select2 widget for the document type selection form.
- Backport the vertical main menu update. This update splits the previous
main menu into a new menu in the same location as the previous one
now called the top bar, and a new vertical main menu on the left side.
The vertical menu remain open even when clicking on items and upon
a browser refresh will also restore its state to match the selected
view.
- Backport workflow preview refactor. GitLab issue #532.
- Add support for source column inheritance.
- Add support for source column exclusion.
- Backport workflow context support.
- Backport workflow transitions field support.
- Backport workflow email action.
- Backport individual index rebuild support.
- Rename the installjavascript command to installdependencies.
- Remove database conversion command.
- Remove support for quoted configuration entries. Support unquoted,
nested dictionaries in the configuration. Requires manual
update of existing config.yml files.
- Support user specified locations for the configuration file with the
CONFIGURATION_FILEPATH (MAYAN_CONFIGURATION_FILEPATH environment variable), and
CONFIGURATION_LAST_GOOD_FILEPATH
(MAYAN_CONFIGURATION_LAST_GOOD_FILEPATH environment variable) settings.
- Move bootstrapped settings code to their own module in the smart_settings apps.
- Remove individual database configuration options. All database configuration
is now done using MAYAN_DATABASES to mirror Django way of doing database setup.
- Added support for YAML encoded environment variables to the platform
templates apps.
- Move YAML code to its own module. Code now resides in common.serialization
in the form of two new functions: yaml_load and yaml_dump.
- Move Django and Celery settings. Django settings now reside in the smart
settings app. Celery settings now reside in the task manager app.
- Backport FakeStorageSubclass from versions/next. Placeholder class to allow
serializing the real storage subclass to support migrations.
Used by all configurable storages.
- Support checking in and out multiple documents.
- Remove encapsulate helper.
- Add support for menu inheritance.
- Emphasize source column labels.
Removals
--------
- Database conversion. Reason for removal. The database conversions support
provided by this feature (SQLite to PostgreSQL) was being confused with
database migrations and upgrades.
Database upgrades are the responsibility of the app and the framework.
Database conversions however are not the responsibility of the app (Mayan),
they are the responsibility of the framework.
Database conversion is outside the scope of what Mayan does but we added
the code, management command, instructions and testing setup to provide
this to our users until the framework (Django) decided to add this
themselves (like they did with migrations).
Continued confusion about the purpose of the feature and confusion about
how errors with this feature were a reflexion of the code quality of
Mayannecessitated the removal of the database conversion feature.
- Django environ
Upgrading from a previous version
---------------------------------
If installed via Python's PIP
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Remove deprecated requirements::
sudo -u mayan curl https://gitlab.com/mayan-edms/mayan-edms/raw/master/removals.txt -o /tmp/removals.txt && sudo -u mayan /opt/mayan-edms/bin/pip uninstall -y -r /tmp/removals.txt
Type in the console::
/opt/mayan-edms/bin/pip install mayan-edms==3.3
the requirements will also be updated automatically.
Using Git
^^^^^^^^^
If you installed Mayan EDMS by cloning the Git repository issue the commands::
git reset --hard HEAD
git pull
otherwise download the compressed archived and uncompress it overriding the
existing installation.
Remove deprecated requirements::
pip uninstall -y -r removals.txt
Next upgrade/add the new requirements::
pip install --upgrade -r requirements.txt
Common steps
^^^^^^^^^^^^
Perform these steps after updating the code from either step above.
Make a backup of your supervisord file::
sudo cp /etc/supervisor/conf.d/mayan.conf /etc/supervisor/conf.d/mayan.conf.bck
Update the supervisord configuration file. Replace the environment
variables values show here with your respective settings. This step will refresh
the supervisord configuration file with the new queues and the latest
recommended layout::
sudo MAYAN_DATABASES="{'default':{'ENGINE':'django.db.backends.postgresql','NAME':'mayan','PASSWORD':'mayanuserpass','USER':'mayan','HOST':'127.0.0.1'}}" \
MAYAN_MEDIA_ROOT=/opt/mayan-edms/media \
/opt/mayan-edms/bin/mayan-edms.py platformtemplate supervisord > /etc/supervisor/conf.d/mayan.conf
Edit the supervisord configuration file and update any setting the template
generator missed::
sudo vi /etc/supervisor/conf.d/mayan.conf
Migrate existing database schema with::
sudo -u mayan MAYAN_MEDIA_ROOT=/opt/mayan-edms/media /opt/mayan-edms/bin/mayan-edms.py performupgrade
Add new static media::
sudo -u mayan MAYAN_MEDIA_ROOT=/opt/mayan-edms/media /opt/mayan-edms/bin/mayan-edms.py preparestatic --noinput
The upgrade procedure is now complete.
Backward incompatible changes
-----------------------------
- Update quoted settings to be unquoted:
- COMMON_SHARED_STORAGE_ARGUMENTS
- CONVERTER_GRAPHICS_BACKEND_ARGUMENTS
- DOCUMENTS_CACHE_STORAGE_BACKEND_ARGUMENTS
- DOCUMENTS_STORAGE_BACKEND_ARGUMENTS
- FILE_METADATA_DRIVERS_ARGUMENTS
- SIGNATURES_STORAGE_BACKEND_ARGUMENTS
Bugs fixed or issues closed
---------------------------
- :gitlab-issue:`532` Workflow preview isn't updated right after transitions are modified
- :gitlab-issue:`634` Failing docker entrypoint when using secret config
.. _PyPI: https://pypi.python.org/pypi/mayan-edms/

View File

@@ -20,14 +20,6 @@ versions of the documentation contain the release notes for any later releases.
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1
3.3
3.2.6
3.2.5
3.2.4
3.2.3
3.2.2
3.2.1
3.2
3.1.11 3.1.11
3.1.10 3.1.10
3.1.9 3.1.9

View File

@@ -1,5 +1,3 @@
Archlinux
archlinux
adf adf
ajax ajax
ajaxForm ajaxForm
@@ -143,7 +141,6 @@ storages
Storages Storages
subclasses subclasses
subclassing subclassing
subfolder
sublicense sublicense
sublicensees sublicensees
swedish swedish
@@ -176,15 +173,3 @@ YaN
yasg yasg
YbN YbN
YrcN YrcN
metacopy
overlayfs
sys
supervisord
Monkeypatch
Bootswatch
sortable
Odroid
callables
ModelPermission
mixins
kwargs

View File

@@ -1,5 +0,0 @@
################
Adding documents
################
.. include:: ../chapters/sources.rst

View File

@@ -8,4 +8,3 @@ Advanced topics
.. include:: ../chapters/metadata.rst .. include:: ../chapters/metadata.rst
.. include:: ../chapters/transformations.rst .. include:: ../chapters/transformations.rst
.. include:: ../chapters/versioning.rst .. include:: ../chapters/versioning.rst
.. include:: ../chapters/quick_labels.rst

View File

@@ -7,12 +7,10 @@ allows showing users different views of document groups. These are divided
into ones requiring manual maintenance and others that are updated into ones requiring manual maintenance and others that are updated
automatically. automatically.
************** **************
Manual methods Manual methods
************** **************
.. include:: ../chapters/document_types.rst
.. include:: ../chapters/cabinets.rst .. include:: ../chapters/cabinets.rst
.. include:: ../chapters/tags.rst .. include:: ../chapters/tags.rst

View File

@@ -1,8 +0,0 @@
######
Docker
######
Docker is a container technology. Containers are a standard unit of software
that packages up code and all its dependencies.
.. include:: ../chapters/docker.rst

View File

@@ -6,88 +6,6 @@ FAQ
Non technical Non technical
************* *************
Contact
=======
Can I contact members of the development team?
----------------------------------------------
Direct access to members of the development team is reserved for clients
of a support or consultation contract.
I can't pay for support/consultation
------------------------------------
A community forum is available at https://forum.mayan-edms.com. Members of
the development team visit the forum on occasions and might answer some
questions on a voluntary basis.
I found a bug
-------------
For bugs, open an issue at https://gitlab.com/mayan-edms/mayan-edms/issues.
I found a security issue
------------------------
Open an issue at https://gitlab.com/mayan-edms/mayan-edms/issues and mark it as
Confidential. Allow us at least 48 hours to find and release a fix
for the issue before submitting it to the CVE database.
I want to join the development team
-----------------------------------
Perfect! We need all the help we can get. Tell us where we can see what you've
done using Mayan EDMS. It could be a fork, a new UI, an API client, a custom app,
or anything else that you think will be able to evidence your dominion over the
codebase.
I submitted an issue and it has not been fixed
----------------------------------------------
There are many reason an issue might not get resolved and remain open for an
extended period of time. We document on the issue itself the progress and when
resolved will reference what commit fixed it and the version or approximate time
for the code to make it into a production release. Some reason why issues remain
open with no resolution are:
- It was not an issue with the code. It happens that sometimes the problem lies
with the operating system, the filesystem being used, the platform or packaging
method.
- It was not an issue but a question or a comment. The issue system is for reporting
problems with the code. That said, we sometimes answer questions submitted as
issues. For questions or discussions use the community forum.
- We are not able to reproduce the issue. We need to be able to recreate the
conditions that trigger the issue so that we can pinpoint the cause. After that
we create a test to make sure the issue is really fixed. Some issues can
be triggered manually easily but are hard to trigger programatically.
- The issue is not clearly explained. Issue descriptions like: "It doesn't work",
or "It showed an error but I forgot to write it down" are almost impossible to
resolve.
- We understand the cause of the problem but don't yet a solution to implement.
We have studied the issue and have been able to reproduce it, but have not
reached a consensus on how it should be fixed. Could be that the solution is
beyond the collective expertise of the development team or that a design
decision of big impact is needed before code changes can be implemented.
- The issue is no real. The issue might be for an obsolete version. It could be
for a fork or a program that is not developed by us. Sometimes they are just
fake issues.
I submitted a merge request and has not been merged
---------------------------------------------------
Merge requests must follow the development standards of the code as close a
possible. They must also be atomic and as small as possible. The code must also
not change the behavior of the project. We can't accept merge request that
customize it in some way based on your own preferences or needs.
Distribution Distribution
============ ============
@@ -126,7 +44,6 @@ Restricting distribution or sale would conflict with the license terms. This
would possible for a commercial version of Mayan EDMS with separate licensing would possible for a commercial version of Mayan EDMS with separate licensing
terms. terms.
Is there a commercial partnership program? Is there a commercial partnership program?
------------------------------------------ ------------------------------------------
@@ -167,6 +84,17 @@ upgrades, if a migration fails the database structure is left in a transitory
state and has to be reverted manually before trying again. state and has to be reverted manually before trying again.
Document versions
=================
How do you upload a new version of an existing file?
----------------------------------------------------
Choose a document, and go to the versions tab, on the right menu at the bottom
under Other available action there is Upload new version. Clicking it will
take you to a very similar view as the Upload new document but you will be
able to specify version number and comments for the new version being uploaded.
LDAP LDAP
==== ====
@@ -177,7 +105,6 @@ A sample settings file called ldap_connection_settings.py is included in the
contrib/settings/ folder of the repository showing how to setup LDAP contrib/settings/ folder of the repository showing how to setup LDAP
authentication. authentication.
Operating systems Operating systems
================= =================
@@ -221,24 +148,20 @@ Django's development server doesn't serve static files unless the DEBUG option
is set to True, this mode of operation should only be used for development or is set to True, this mode of operation should only be used for development or
testing. For production deployments the management command:: testing. For production deployments the management command::
$ mayan-edms.py preparestatic $ mayan-edms.py collectstatic
should be used and the resulting static folder served from a webserver. should be used and the resulting static folder served from a webserver.
For more information check the For more information check the
:django-docs:`howto/static-files/` :django-docs:`howto/static-files/`
Watchfolders
Watch folders ============
=============
The watched folder feature is not working The watched folder feature is not working
----------------------------------------- -----------------------------------------
Make sure that the Celery BEAT scheduler is running correctly as it is the Make sure that the Celery BEAT scheduler is running correctly as it is the
element that triggers the periodic tasks. Check that the user running the Mayan element that triggers the periodics tasks.
EDMS services has read and write permissions for the watch folder.
Other Other
===== =====
@@ -265,3 +188,8 @@ Example::
Reference: Reference:
* http://www.samba.org/samba/docs/man/manpages-3/smb.conf.5.html * http://www.samba.org/samba/docs/man/manpages-3/smb.conf.5.html
Can you change the display order of documents…i.e can they be in alphabetical order?
------------------------------------------------------------------------------------
A the moment no, but it is something being worked on.

View File

@@ -4,19 +4,6 @@ Getting started
These are the basic concepts you need to understand to start using Mayan EDMS. These are the basic concepts you need to understand to start using Mayan EDMS.
The absolute minimum setup to start using Mayan EDMS is:
#. A document type
#. A document source to add new documents
that's it!
To make things even easier, a default document type (named "Default") and a
default document source (also named "Default") were created for you during the
installation. So you don't need to do anything more to start adding documents
right now, however take your time reading the information below to get a deeper
understanding about how these concepts work.
.. include:: ../chapters/document_types.rst .. include:: ../chapters/document_types.rst
.. include:: ../chapters/sources.rst .. include:: ../chapters/sources.rst

View File

@@ -12,7 +12,7 @@ Minimum hardware requirements
- 2 Gigabytes of RAM (1 Gigabyte if OCR is turned off). - 2 Gigabytes of RAM (1 Gigabyte if OCR is turned off).
- Multiple core CPU (64 bit, faster than 1 GHz recommended). - Multiple core CPU (64 bit, faster than 1 GHz recommended).
- Unix-like operating system like GNU/Linux. For other operating systems - Unix-like operating system like Linux and OpenBSD. For other operating systems
user container technologies like Docker or virtual machines. user container technologies like Docker or virtual machines.
**************** ****************

View File

@@ -7,8 +7,8 @@ Troubleshooting
Database Database
******** ********
MySQL error: ``OperationalError: (1267, "Illegal mix of collations (latin1_swedish_ci, IMPLICIT) and (utf8_general_ci, COERCIBLE) for operation '='”)`` _mysql_exceptions. OperationalError: (1267, "Illegal mix of collations (latin1_swedish_ci, IMPLICIT) and (utf8_general_ci, COERCIBLE) for operation ='”)
======================================================================================================================================================= =========================================================================================================================================================
:: ::
@@ -25,8 +25,8 @@ References:
* http://stackoverflow.com/questions/1073295/django-character-set-with-mysql-weirdness * http://stackoverflow.com/questions/1073295/django-character-set-with-mysql-weirdness
MySQL error: ``Incorrect string value: `'xE2x80x95rs6…'` for column `'content'` at row 1`` Incorrect string value: ``'xE2x80x95rs6…'`` for column ``'content'`` at row 1
========================================================================================== =============================================================================
When using MySQL and doing OCR on languages other than English When using MySQL and doing OCR on languages other than English
@@ -39,31 +39,13 @@ References:
* http://markmail.org/message/bqajx2utvmtriixi * http://markmail.org/message/bqajx2utvmtriixi
MySQL error: ``Error "django.db.utils.IntegrityError IntegrityError: (1452, 'Cannot add or update a child row: a foreign key constraint fails (`…`.`…`, CONSTRAINT `…_refs_id_b0252274` FOREIGN KEY (`…`) REFERENCES `…` (`…`))')`` Error "django.db.utils.IntegrityError IntegrityError: (1452, Cannot add or update a child row: a foreign key constraint fails (`…`.`…`, CONSTRAINT `…_refs_id_b0252274` FOREIGN KEY (`…`) REFERENCES `…` (`…`))')
=================================================================================================================================================================================================================================== ==================================================================================================================================================================================================================
Solution: Solution:
Convert all MySQL tables to the same type, either all MyISAM or InnoDB Convert all MySQL tables to the same type, either all MyISAM or InnoDB
PostgreSQL error: ``OperationalError: FATAL: sorry, too many clients already``
===============================================================================
Set ``MAYAN_DATABASE_CONN_MAX_AGE`` to 0
This setting keeps a database connection alive. It allows reuse of database
connections. When Mayan EDMS is deployed with Gunicorn a microthreads backend,
the database connections are not shared and this setting has the reverse effect
of exhausting the available PostgreSQL connections available. To avoid this,
Setting ``MAYAN_DATABASE_CONN_MAX_AGE`` to 0 will cause all microthreads to
release their connections, by closing them when finished.
References:
- https://serverfault.com/questions/635100/django-conn-max-age-persists-connections-but-doesnt-reuse-them-with-postgresq
- https://github.com/benoitc/gunicorn/issues/996
****** ******
Docker Docker
****** ******
@@ -90,94 +72,15 @@ References:
Passwords Passwords
********* *********
.. _troubleshooting-admin-password: Missing initial credentials or admin password reset
===================================================
Admin password reset First you need to know the name of the Docker container running Mayan EDMS
==================== on your setup with::
To reset the password of the admin account use the following command::
MAYAN_MEDIA_ROOT=<your Mayan media root setting> <installation directory>/bin/mayan-edms.py changepassword admin
If you followed the deploying instructions from the documentation your
``MAYAN_MEDIA_ROOT`` will be ``/opt/mayan-edms/media``.
If using a Docker image, execute the command inside the container. First you
need to know the name of the Docker container running Mayan EDMS on your setup
with::
docker ps docker ps
Then execute the password reset command inside the Docker container:: Then execute the password reset command inside the Docker container::
docker exec -ti <your docker container name> /opt/mayan-edms/bin/mayan-edms.py changepassword admin
Another way to do this is to execute a shell inside the container to get a
command prompt::
docker exec -ti <your docker container name> /bin/bash docker exec -ti <your docker container name> /bin/bash
And then execute the command::
/opt/mayan-edms/bin/mayan-edms.py changepassword admin /opt/mayan-edms/bin/mayan-edms.py changepassword admin
.. _troubleshooting-autoadmin-account:
Missing automatic admin account after installation
==================================================
This is caused when the ``initialsetup`` command is interrupted as the admin
user is created outside of the database migrations.
To create an admin super user account manually use the command::
MAYAN_MEDIA_ROOT=<your Mayan media root setting> <installation directory>/bin/mayan-edms.py createsuperuser
If you followed the deploying instructions from the documentation your
``MAYAN_MEDIA_ROOT`` will be ``/opt/mayan-edms/media``.
If using a Docker image, execute the command inside the container. First
find you container name with::
docker ps
Then execute the command inside the container::
docker exec -ti <your docker container name> /opt/mayan-edms/bin/mayan-edms.py createsuperuser
Another way to do this is to execute a shell inside the container to get a
command prompt::
docker exec -ti <your docker container name> /bin/bash
And then execute the command::
/opt/mayan-edms/bin/mayan-edms.py createsuperuser
************
Watchfolders
************
Incomplete files uploaded
=========================
To avoid uploading files are they are being copied to the watchfolder, copy the
files to a temporary directory on the same partition as the watchfolder first.
Then move the files to the watchfolder. The move will be executed as an atomic
operation and will prevent the files to be uploaded in the middle of the
copying process.
************
Dependencies
************
Error: ``unable to execute 'x86_64-linux-gnu-gcc': No such file or directory``
==============================================================================
This happens when using the ``MAYAN_APT_INSTALLS`` feature. It means that the
``GCC`` package is required to compile the packages specified with
``MAYAN_APT_INSTALLS``.
Solution: Include ``gcc`` in the list of packages specified with ``MAYAN_APT_INSTALLS``.

View File

@@ -1,4 +1,4 @@
Copyright 2011 Roberto Rosario Copyright 2011-2018 Roberto Rosario
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

View File

@@ -1,14 +1,14 @@
from __future__ import unicode_literals from __future__ import unicode_literals
__title__ = 'Mayan EDMS' __title__ = 'Mayan EDMS'
__version__ = '3.2.6' __version__ = '3.1.10'
__build__ = 0x030206 __build__ = 0x030110
__build_string__ = 'v3.2.6_Wed Jul 10 03:18:15 2019 -0400' __build_string__ = 'v3.1.10-1-g51ea493a26_Thu Apr 4 22:03:19 2019 -0400'
__django_version__ = '1.11' __django_version__ = '1.11'
__author__ = 'Roberto Rosario' __author__ = 'Roberto Rosario'
__author_email__ = 'roberto.rosario@mayan-edms.com' __author_email__ = 'roberto.rosario@mayan-edms.com'
__description__ = 'Free Open Source Electronic Document Management System' __description__ = 'Free Open Source Electronic Document Management System'
__license__ = 'Apache 2.0' __license__ = 'Apache 2.0'
__copyright_short__ = '2011 Roberto Rosario' __copyright_short__ = '2011-2018 Roberto Rosario'
__copyright__ = '{} {}'.format('Copyright', __copyright_short__) __copyright__ = '{} {}'.format('Copyright', __copyright_short__)
__website__ = 'https://www.mayan-edms.com' __website__ = 'https://www.mayan-edms.com'

View File

@@ -1,3 +1,5 @@
from __future__ import unicode_literals from __future__ import unicode_literals
default_app_config = 'mayan.apps.acls.apps.ACLsApp' from .classes import ModelPermission # NOQA
default_app_config = 'acls.apps.ACLsApp'

View File

@@ -21,12 +21,12 @@ class APIObjectACLListView(generics.ListCreateAPIView):
""" """
def get_content_object(self): def get_content_object(self):
content_type = get_object_or_404( content_type = get_object_or_404(
klass=ContentType, app_label=self.kwargs['app_label'], ContentType, app_label=self.kwargs['app_label'],
model=self.kwargs['model'] model=self.kwargs['model']
) )
content_object = get_object_or_404( content_object = get_object_or_404(
klass=content_type.model_class(), pk=self.kwargs['object_id'] content_type.model_class(), pk=self.kwargs['object_pk']
) )
if self.request.method == 'GET': if self.request.method == 'GET':
@@ -35,8 +35,8 @@ class APIObjectACLListView(generics.ListCreateAPIView):
permission_required = permission_acl_edit permission_required = permission_acl_edit
AccessControlList.objects.check_access( AccessControlList.objects.check_access(
obj=content_object, permissions=(permission_required,), permissions=permission_required, user=self.request.user,
user=self.request.user obj=content_object
) )
return content_object return content_object
@@ -62,9 +62,7 @@ class APIObjectACLListView(generics.ListCreateAPIView):
if not self.request: if not self.request:
return None return None
return super(APIObjectACLListView, self).get_serializer( return super(APIObjectACLListView, self).get_serializer(*args, **kwargs)
*args, **kwargs
)
def get_serializer_class(self): def get_serializer_class(self):
if self.request.method == 'GET': if self.request.method == 'GET':
@@ -87,17 +85,17 @@ class APIObjectACLView(generics.RetrieveDestroyAPIView):
permission_required = permission_acl_edit permission_required = permission_acl_edit
content_type = get_object_or_404( content_type = get_object_or_404(
klass=ContentType, app_label=self.kwargs['app_label'], ContentType, app_label=self.kwargs['app_label'],
model=self.kwargs['model'] model=self.kwargs['model']
) )
content_object = get_object_or_404( content_object = get_object_or_404(
klass=content_type.model_class(), pk=self.kwargs['object_id'] content_type.model_class(), pk=self.kwargs['object_pk']
) )
AccessControlList.objects.check_access( AccessControlList.objects.check_access(
obj=content_object, permissions=(permission_required,), permissions=permission_required, user=self.request.user,
user=self.request.user obj=content_object
) )
return content_object return content_object
@@ -113,27 +111,22 @@ class APIObjectACLPermissionListView(generics.ListCreateAPIView):
""" """
def get_acl(self): def get_acl(self):
return get_object_or_404( return get_object_or_404(
klass=self.get_content_object().acls, pk=self.kwargs['pk'] self.get_content_object().acls, pk=self.kwargs['pk']
) )
def get_content_object(self): def get_content_object(self):
content_type = get_object_or_404( content_type = get_object_or_404(
klass=ContentType, app_label=self.kwargs['app_label'], ContentType, app_label=self.kwargs['app_label'],
model=self.kwargs['model'] model=self.kwargs['model']
) )
content_object = get_object_or_404( content_object = get_object_or_404(
klass=content_type.model_class(), pk=self.kwargs['object_id'] content_type.model_class(), pk=self.kwargs['object_pk']
) )
if self.request.method == 'GET':
permission = permission_acl_view
else:
permission = permission_acl_edit
AccessControlList.objects.check_access( AccessControlList.objects.check_access(
obj=content_object, permissions=(permission,), permissions=permission_acl_view, user=self.request.user,
user=self.request.user obj=content_object
) )
return content_object return content_object
@@ -154,9 +147,7 @@ class APIObjectACLPermissionListView(generics.ListCreateAPIView):
return WritableAccessControlListPermissionSerializer return WritableAccessControlListPermissionSerializer
def get_serializer_context(self): def get_serializer_context(self):
context = super( context = super(APIObjectACLPermissionListView, self).get_serializer_context()
APIObjectACLPermissionListView, self
).get_serializer_context()
if self.kwargs: if self.kwargs:
context.update( context.update(
{ {
@@ -177,27 +168,22 @@ class APIObjectACLPermissionView(generics.RetrieveDestroyAPIView):
def get_acl(self): def get_acl(self):
return get_object_or_404( return get_object_or_404(
klass=self.get_content_object().acls, pk=self.kwargs['pk'] self.get_content_object().acls, pk=self.kwargs['pk']
) )
def get_content_object(self): def get_content_object(self):
content_type = get_object_or_404( content_type = get_object_or_404(
klass=ContentType, app_label=self.kwargs['app_label'], ContentType, app_label=self.kwargs['app_label'],
model=self.kwargs['model'] model=self.kwargs['model']
) )
content_object = get_object_or_404( content_object = get_object_or_404(
klass=content_type.model_class(), pk=self.kwargs['object_id'] content_type.model_class(), pk=self.kwargs['object_pk']
) )
if self.request.method == 'GET':
permission = permission_acl_view
else:
permission = permission_acl_edit
AccessControlList.objects.check_access( AccessControlList.objects.check_access(
obj=content_object, permissions=(permission,), permissions=permission_acl_view, user=self.request.user,
user=self.request.user obj=content_object
) )
return content_object return content_object
@@ -206,9 +192,7 @@ class APIObjectACLPermissionView(generics.RetrieveDestroyAPIView):
return self.get_acl().permissions.all() return self.get_acl().permissions.all()
def get_serializer_context(self): def get_serializer_context(self):
context = super( context = super(APIObjectACLPermissionView, self).get_serializer_context()
APIObjectACLPermissionView, self
).get_serializer_context()
if self.kwargs: if self.kwargs:
context.update( context.update(
{ {

View File

@@ -2,56 +2,35 @@ from __future__ import unicode_literals
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from mayan.apps.common.apps import MayanAppConfig from common import MayanAppConfig, menu_object, menu_sidebar
from mayan.apps.common.menus import menu_object, menu_secondary from navigation import SourceColumn
from mayan.apps.events.classes import ModelEventType
from mayan.apps.events.links import (
link_events_for_object, link_object_event_types_user_subcriptions_list
)
from mayan.apps.navigation.classes import SourceColumn
from .classes import ModelPermission
from .events import event_acl_created, event_acl_edited
from .links import link_acl_create, link_acl_delete, link_acl_permissions from .links import link_acl_create, link_acl_delete, link_acl_permissions
class ACLsApp(MayanAppConfig): class ACLsApp(MayanAppConfig):
app_namespace = 'acls'
app_url = 'acls'
has_rest_api = True has_rest_api = True
has_tests = True has_tests = True
name = 'mayan.apps.acls' name = 'acls'
verbose_name = _('ACLs') verbose_name = _('ACLs')
def ready(self): def ready(self):
super(ACLsApp, self).ready() super(ACLsApp, self).ready()
from actstream import registry
AccessControlList = self.get_model(model_name='AccessControlList') AccessControlList = self.get_model('AccessControlList')
ModelEventType.register(
event_types=(event_acl_created, event_acl_edited),
model=AccessControlList
)
ModelPermission.register_inheritance(
model=AccessControlList, related='content_object',
)
SourceColumn( SourceColumn(
attribute='role', is_sortable=True, source=AccessControlList, source=AccessControlList, label=_('Role'), attribute='role'
)
SourceColumn(
source=AccessControlList, label=_('Permissions'),
attribute='get_permission_titles'
) )
menu_object.bind_links( menu_object.bind_links(
links=( links=(link_acl_permissions, link_acl_delete),
link_acl_permissions, link_acl_delete,
link_events_for_object,
link_object_event_types_user_subcriptions_list
),
sources=(AccessControlList,) sources=(AccessControlList,)
) )
menu_secondary.bind_links( menu_sidebar.bind_links(
links=(link_acl_create,), sources=('acls:acl_list',) links=(link_acl_create,), sources=('acls:acl_list',)
) )
registry.register(AccessControlList)

View File

@@ -1,24 +1,16 @@
from __future__ import unicode_literals, absolute_import from __future__ import unicode_literals, absolute_import
import itertools
import logging import logging
from django.apps import apps from django.apps import apps
from django.utils.encoding import force_text
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class ModelPermission(object): class ModelPermission(object):
_functions = {}
_inheritances = {}
_registry = {} _registry = {}
_proxies = {}
@classmethod _inheritances = {}
def deregister(cls, model):
cls._registry.pop(model, None)
# TODO: Find method to revert the add_to_class('acls'...)
# delattr doesn't work.
@classmethod @classmethod
def register(cls, model, permissions): def register(cls, model, permissions):
@@ -32,9 +24,7 @@ class ModelPermission(object):
app_label='acls', model_name='AccessControlList' app_label='acls', model_name='AccessControlList'
) )
model.add_to_class( model.add_to_class('acls', GenericRelation(AccessControlList))
name='acls', value=GenericRelation(AccessControlList)
)
@classmethod @classmethod
def get_classes(cls, as_content_type=False): def get_classes(cls, as_content_type=False):
@@ -55,21 +45,8 @@ class ModelPermission(object):
return cls._registry.keys() return cls._registry.keys()
@classmethod @classmethod
def get_for_class(cls, klass, as_choices=False): def get_for_class(cls, klass):
if as_choices: return cls._registry.get(klass, ())
results = []
for namespace, permissions in itertools.groupby(cls.get_for_class(klass=klass, as_choices=False), lambda entry: entry.namespace):
permission_options = [
(force_text(permission.pk), permission) for permission in permissions
]
results.append(
(namespace, permission_options)
)
return results
else:
return cls._registry.get(klass, ())
@classmethod @classmethod
def get_for_instance(cls, instance): def get_for_instance(cls, instance):
@@ -84,23 +61,24 @@ class ModelPermission(object):
if class_permissions: if class_permissions:
permissions.extend(class_permissions) permissions.extend(class_permissions)
proxy = cls._proxies.get(type(instance))
if proxy:
permissions.extend(cls._registry.get(proxy))
pks = [ pks = [
permission.stored_permission.pk for permission in set(permissions) permission.stored_permission.pk for permission in set(permissions)
] ]
return StoredPermission.objects.filter(pk__in=pks) return StoredPermission.objects.filter(pk__in=pks)
@classmethod @classmethod
def get_function(cls, model): def register_proxy(cls, source, model):
return cls._functions[model] cls._proxies[model] = source
@classmethod
def get_inheritance(cls, model):
return cls._inheritances[model]
@classmethod
def register_function(cls, model, function):
cls._functions[model] = function
@classmethod @classmethod
def register_inheritance(cls, model, related): def register_inheritance(cls, model, related):
cls._inheritances[model] = related cls._inheritances[model] = related
@classmethod
def get_inheritance(cls, model):
return cls._inheritances[model]

View File

@@ -1,16 +0,0 @@
from __future__ import absolute_import, unicode_literals
from django.utils.translation import ugettext_lazy as _
from mayan.apps.events.classes import EventTypeNamespace
namespace = EventTypeNamespace(
label=_('Access control lists'), name='acls'
)
event_acl_created = namespace.add_event_type(
label=_('ACL created'), name='acl_created'
)
event_acl_edited = namespace.add_event_type(
label=_('ACL edited'), name='acl_edited'
)

View File

@@ -1,17 +0,0 @@
from __future__ import unicode_literals
from django import forms
from django.utils.translation import ugettext_lazy as _
from mayan.apps.common.forms import FilteredSelectionForm
from .models import AccessControlList
class ACLCreateForm(FilteredSelectionForm, forms.ModelForm):
class Meta:
field_name = 'role'
fields = ('role',)
label = _('Role')
model = AccessControlList
widget_attributes = {'class': 'select2'}

View File

@@ -1,12 +1,6 @@
from __future__ import absolute_import, unicode_literals from __future__ import absolute_import, unicode_literals
from mayan.apps.appearance.classes import Icon from appearance.classes import Icon
from mayan.apps.permissions.icons import icon_permission
icon_acl_delete = Icon(driver_name='fontawesome', symbol='times')
icon_acl_list = Icon(driver_name='fontawesome', symbol='lock') icon_acl_list = Icon(driver_name='fontawesome', symbol='lock')
icon_acl_new = Icon( icon_acl_new = Icon(driver_name='fontawesome', symbol='plus')
driver_name='fontawesome-dual', primary_symbol='lock',
secondary_symbol='plus'
)
icon_acl_permissions = icon_permission

View File

@@ -3,11 +3,9 @@ from __future__ import unicode_literals
from django.apps import apps from django.apps import apps
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from mayan.apps.navigation.classes import Link from navigation import Link
from .icons import ( from .icons import icon_acl_list, icon_acl_new
icon_acl_delete, icon_acl_list, icon_acl_new, icon_acl_permissions
)
from .permissions import permission_acl_view, permission_acl_edit from .permissions import permission_acl_view, permission_acl_edit
@@ -29,22 +27,22 @@ def get_kwargs_factory(variable_name):
return get_kwargs return get_kwargs
link_acl_create = Link(
icon_class=icon_acl_new, kwargs=get_kwargs_factory('resolved_object'),
permissions=(permission_acl_edit,), text=_('New ACL'),
view='acls:acl_create'
)
link_acl_delete = Link( link_acl_delete = Link(
args='resolved_object.pk', icon_class=icon_acl_delete, args='resolved_object.pk', permissions=(permission_acl_edit,),
permissions=(permission_acl_edit,), tags='dangerous', text=_('Delete'), permissions_related='content_object', tags='dangerous', text=_('Delete'),
view='acls:acl_delete' view='acls:acl_delete',
) )
link_acl_list = Link( link_acl_list = Link(
icon_class=icon_acl_list, kwargs=get_kwargs_factory('resolved_object'), icon_class=icon_acl_list, kwargs=get_kwargs_factory('resolved_object'),
permissions=(permission_acl_view,), text=_('ACLs'), view='acls:acl_list' permissions=(permission_acl_view,), text=_('ACLs'), view='acls:acl_list'
) )
link_acl_permissions = Link( link_acl_create = Link(
args='resolved_object.pk', icon_class=icon_acl_permissions, icon_class=icon_acl_new, kwargs=get_kwargs_factory('resolved_object'),
permissions=(permission_acl_edit,), permissions=(permission_acl_edit,), text=_('New ACL'),
text=_('Permissions'), view='acls:acl_permissions' view='acls:acl_create'
)
link_acl_permissions = Link(
args='resolved_object.pk', permissions=(permission_acl_edit,),
permissions_related='content_object', text=_('Permissions'),
view='acls:acl_permissions',
) )

View File

@@ -1,77 +1,70 @@
# SOME DESCRIPTIVE TITLE. # SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package. # This file is distributed under the same license as the PACKAGE package.
# #
# Translators: # Translators:
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Mayan EDMS\n" "Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-07-05 01:27-0400\n" "POT-Creation-Date: 2019-04-09 02:06-0400\n"
"PO-Revision-Date: 2019-06-15 07:48+0000\n" "PO-Revision-Date: 2019-03-16 22:48+0000\n"
"Last-Translator: Roberto Rosario\n" "Last-Translator: Yaman Sanobar <yman.snober@gmail.com>\n"
"Language-Team: Arabic (http://www.transifex.com/rosarior/mayan-edms/language/ar/)\n" "Language-Team: Arabic (http://www.transifex.com/rosarior/mayan-edms/language/"
"ar/)\n"
"Language: ar\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Language: ar\n" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" "&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
#: apps.py:24 links.py:44 #: apps.py:15 links.py:37
msgid "ACLs" msgid "ACLs"
msgstr "ACLs" msgstr "ACLs"
#: events.py:8 permissions.py:7 #: apps.py:23 models.py:47
msgid "Access control lists"
msgstr "Access control lists"
#: events.py:12
msgid "ACL created"
msgstr ""
#: events.py:15
msgid "ACL edited"
msgstr ""
#: forms.py:15 models.py:49
msgid "Role" msgid "Role"
msgstr "" msgstr ""
#: links.py:34 #: apps.py:26 links.py:46 models.py:43 workflow_actions.py:48
msgid "New ACL"
msgstr ""
#: links.py:39
msgid "Delete"
msgstr "حذف"
#: links.py:49 models.py:45 workflow_actions.py:49 workflow_actions.py:164
msgid "Permissions" msgid "Permissions"
msgstr "الصلاحيات" msgstr "الصلاحيات"
#: managers.py:216 #: links.py:32
#, python-format msgid "Delete"
msgid "Object \"%s\" is not a model and cannot be checked for access." msgstr "حذف"
#: links.py:41
msgid "New ACL"
msgstr "" msgstr ""
#: managers.py:236 #: managers.py:61 managers.py:102
#, python-format #, python-format
msgid "Insufficient access for: %s" msgid "Insufficient access for: %s"
msgstr "" msgstr ""
#: models.py:57 #: models.py:55
msgid "Access entry" msgid "Access entry"
msgstr "" msgstr ""
#: models.py:58 #: models.py:56
msgid "Access entries" msgid "Access entries"
msgstr "" msgstr ""
#: models.py:62 #: models.py:60
#, python-format #, python-format
msgid "Role \"%(role)s\" permission's for \"%(object)s\"" msgid "Permissions \"%(permissions)s\" to role \"%(role)s\" for \"%(object)s\""
msgstr "" msgstr ""
#: models.py:77
msgid "None"
msgstr "لا شيء"
#: permissions.py:7
msgid "Access control lists"
msgstr "Access control lists"
#: permissions.py:10 #: permissions.py:10
msgid "Edit ACLs" msgid "Edit ACLs"
msgstr "Edit ACLs" msgstr "Edit ACLs"
@@ -80,124 +73,111 @@ msgstr "Edit ACLs"
msgid "View ACLs" msgid "View ACLs"
msgstr "View ACLs" msgstr "View ACLs"
#: serializers.py:26 serializers.py:136 #: serializers.py:24 serializers.py:132
msgid "" msgid ""
"API URL pointing to the list of permissions for this access control list." "API URL pointing to the list of permissions for this access control list."
msgstr "" msgstr ""
#: serializers.py:59 #: serializers.py:57
msgid "" msgid ""
"API URL pointing to a permission in relation to the access control list to " "API URL pointing to a permission in relation to the access control list to "
"which it is attached. This URL is different than the canonical workflow URL." "which it is attached. This URL is different than the canonical workflow URL."
msgstr "" msgstr ""
#: serializers.py:91 #: serializers.py:87
msgid "Primary key of the new permission to grant to the access control list." msgid "Primary key of the new permission to grant to the access control list."
msgstr "" msgstr ""
#: serializers.py:115 serializers.py:191 #: serializers.py:111 serializers.py:187
#, python-format #, python-format
msgid "No such permission: %s" msgid "No such permission: %s"
msgstr "" msgstr ""
#: serializers.py:130 #: serializers.py:126
msgid "" msgid ""
"Comma separated list of permission primary keys to grant to this access " "Comma separated list of permission primary keys to grant to this access "
"control list." "control list."
msgstr "" msgstr ""
#: serializers.py:142 #: serializers.py:138
msgid "Primary keys of the role to which this access control list binds to." msgid "Primary keys of the role to which this access control list binds to."
msgstr "" msgstr ""
#: views.py:62 #: views.py:77
#, python-format #, python-format
msgid "New access control lists for: %s" msgid "New access control lists for: %s"
msgstr "" msgstr ""
#: views.py:100 #: views.py:104
#, python-format #, python-format
msgid "Delete ACL: %s" msgid "Delete ACL: %s"
msgstr "" msgstr ""
#: views.py:147 #: views.py:148
msgid "There are no ACLs for this object" msgid "There are no ACLs for this object"
msgstr "" msgstr ""
#: views.py:150 #: views.py:151
msgid "" msgid ""
"ACL stands for Access Control List and is a precise method to control user " "ACL stands for Access Control List and is a precise method to control user "
"access to objects in the system." "access to objects in the system."
msgstr "" msgstr ""
#: views.py:154 #: views.py:155
#, python-format #, python-format
msgid "Access control lists for: %s" msgid "Access control lists for: %s"
msgstr "" msgstr ""
#: views.py:170 #: views.py:167
msgid "Granted permissions"
msgstr ""
#: views.py:171
msgid "Available permissions" msgid "Available permissions"
msgstr "" msgstr ""
#: views.py:215 #: views.py:168
msgid "Granted permissions"
msgstr ""
#: views.py:230
#, python-format #, python-format
msgid "Role \"%(role)s\" permission's for \"%(object)s\"." msgid "Role \"%(role)s\" permission's for \"%(object)s\""
msgstr "" msgstr ""
#: views.py:224 #: views.py:250
msgid "" msgid "Disabled permissions are inherited from a parent object."
"Disabled permissions are inherited from a parent object or directly granted "
"to the role and can't be removed from this view. Inherited permissions need "
"to be removed from the parent object's ACL or from them role via the Setup "
"menu."
msgstr "" msgstr ""
#: workflow_actions.py:26 #: workflow_actions.py:25
msgid "Object type" msgid "Object type"
msgstr "" msgstr ""
#: workflow_actions.py:29 #: workflow_actions.py:28
msgid "Type of the object for which the access will be modified." msgid "Type of the object for which the access will be modified."
msgstr "" msgstr ""
#: workflow_actions.py:35 #: workflow_actions.py:34
msgid "Object ID" msgid "Object ID"
msgstr "" msgstr ""
#: workflow_actions.py:38 #: workflow_actions.py:37
msgid "" msgid "Numeric identifier of the object for which the access will be modified."
"Numeric identifier of the object for which the access will be modified."
msgstr "" msgstr ""
#: workflow_actions.py:43 workflow_actions.py:158 #: workflow_actions.py:42
msgid "Roles" msgid "Roles"
msgstr "Roles" msgstr "Roles"
#: workflow_actions.py:45 workflow_actions.py:160 #: workflow_actions.py:44
msgid "Roles whose access will be modified." msgid "Roles whose access will be modified."
msgstr "" msgstr ""
#: workflow_actions.py:52 workflow_actions.py:167 #: workflow_actions.py:51
msgid "" msgid ""
"Permissions to grant/revoke to/from the role for the object selected above." "Permissions to grant/revoke to/from the role for the object selected above."
msgstr "" msgstr ""
#: workflow_actions.py:60 #: workflow_actions.py:59
msgid "Grant access" msgid "Grant access"
msgstr "" msgstr ""
#: workflow_actions.py:143 #: workflow_actions.py:129
msgid "Revoke access" msgid "Revoke access"
msgstr "" msgstr ""
#: workflow_actions.py:175
msgid "Grant document access"
msgstr ""
#: workflow_actions.py:214
msgid "Revoke document access"
msgstr ""

View File

@@ -1,77 +1,69 @@
# SOME DESCRIPTIVE TITLE. # SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package. # This file is distributed under the same license as the PACKAGE package.
# #
# Translators: # Translators:
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Mayan EDMS\n" "Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-07-05 01:27-0400\n" "POT-Creation-Date: 2019-04-09 02:06-0400\n"
"PO-Revision-Date: 2019-06-15 07:48+0000\n" "PO-Revision-Date: 2018-09-08 08:06+0000\n"
"Last-Translator: Roberto Rosario\n" "Last-Translator: Roberto Rosario\n"
"Language-Team: Bulgarian (http://www.transifex.com/rosarior/mayan-edms/language/bg/)\n" "Language-Team: Bulgarian (http://www.transifex.com/rosarior/mayan-edms/"
"language/bg/)\n"
"Language: bg\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Language: bg\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: apps.py:24 links.py:44 #: apps.py:15 links.py:37
msgid "ACLs" msgid "ACLs"
msgstr "ACLs" msgstr "ACLs"
#: events.py:8 permissions.py:7 #: apps.py:23 models.py:47
msgid "Access control lists"
msgstr "Контролни списъци за достъп"
#: events.py:12
msgid "ACL created"
msgstr ""
#: events.py:15
msgid "ACL edited"
msgstr ""
#: forms.py:15 models.py:49
msgid "Role" msgid "Role"
msgstr "" msgstr ""
#: links.py:34 #: apps.py:26 links.py:46 models.py:43 workflow_actions.py:48
msgid "New ACL"
msgstr ""
#: links.py:39
msgid "Delete"
msgstr ""
#: links.py:49 models.py:45 workflow_actions.py:49 workflow_actions.py:164
msgid "Permissions" msgid "Permissions"
msgstr "Разрешения" msgstr "Разрешения"
#: managers.py:216 #: links.py:32
#, python-format msgid "Delete"
msgid "Object \"%s\" is not a model and cannot be checked for access."
msgstr "" msgstr ""
#: managers.py:236 #: links.py:41
msgid "New ACL"
msgstr ""
#: managers.py:61 managers.py:102
#, python-format #, python-format
msgid "Insufficient access for: %s" msgid "Insufficient access for: %s"
msgstr "" msgstr ""
#: models.py:57 #: models.py:55
msgid "Access entry" msgid "Access entry"
msgstr "достъп вписване" msgstr "достъп вписване"
#: models.py:58 #: models.py:56
msgid "Access entries" msgid "Access entries"
msgstr "достъп вписвания" msgstr "достъп вписвания"
#: models.py:62 #: models.py:60
#, python-format #, python-format
msgid "Role \"%(role)s\" permission's for \"%(object)s\"" msgid "Permissions \"%(permissions)s\" to role \"%(role)s\" for \"%(object)s\""
msgstr "" msgstr ""
#: models.py:77
msgid "None"
msgstr "Няма"
#: permissions.py:7
msgid "Access control lists"
msgstr "Контролни списъци за достъп"
#: permissions.py:10 #: permissions.py:10
msgid "Edit ACLs" msgid "Edit ACLs"
msgstr "Редактиране на контролни списъци за достъп" msgstr "Редактиране на контролни списъци за достъп"
@@ -80,124 +72,111 @@ msgstr "Редактиране на контролни списъци за до
msgid "View ACLs" msgid "View ACLs"
msgstr "Преглед на контролни списъци за достъп" msgstr "Преглед на контролни списъци за достъп"
#: serializers.py:26 serializers.py:136 #: serializers.py:24 serializers.py:132
msgid "" msgid ""
"API URL pointing to the list of permissions for this access control list." "API URL pointing to the list of permissions for this access control list."
msgstr "" msgstr ""
#: serializers.py:59 #: serializers.py:57
msgid "" msgid ""
"API URL pointing to a permission in relation to the access control list to " "API URL pointing to a permission in relation to the access control list to "
"which it is attached. This URL is different than the canonical workflow URL." "which it is attached. This URL is different than the canonical workflow URL."
msgstr "" msgstr ""
#: serializers.py:91 #: serializers.py:87
msgid "Primary key of the new permission to grant to the access control list." msgid "Primary key of the new permission to grant to the access control list."
msgstr "" msgstr ""
#: serializers.py:115 serializers.py:191 #: serializers.py:111 serializers.py:187
#, python-format #, python-format
msgid "No such permission: %s" msgid "No such permission: %s"
msgstr "" msgstr ""
#: serializers.py:130 #: serializers.py:126
msgid "" msgid ""
"Comma separated list of permission primary keys to grant to this access " "Comma separated list of permission primary keys to grant to this access "
"control list." "control list."
msgstr "" msgstr ""
#: serializers.py:142 #: serializers.py:138
msgid "Primary keys of the role to which this access control list binds to." msgid "Primary keys of the role to which this access control list binds to."
msgstr "" msgstr ""
#: views.py:62 #: views.py:77
#, python-format #, python-format
msgid "New access control lists for: %s" msgid "New access control lists for: %s"
msgstr "" msgstr ""
#: views.py:100 #: views.py:104
#, python-format #, python-format
msgid "Delete ACL: %s" msgid "Delete ACL: %s"
msgstr "" msgstr ""
#: views.py:147 #: views.py:148
msgid "There are no ACLs for this object" msgid "There are no ACLs for this object"
msgstr "" msgstr ""
#: views.py:150 #: views.py:151
msgid "" msgid ""
"ACL stands for Access Control List and is a precise method to control user " "ACL stands for Access Control List and is a precise method to control user "
"access to objects in the system." "access to objects in the system."
msgstr "" msgstr ""
#: views.py:154 #: views.py:155
#, python-format #, python-format
msgid "Access control lists for: %s" msgid "Access control lists for: %s"
msgstr "" msgstr ""
#: views.py:170 #: views.py:167
msgid "Granted permissions"
msgstr ""
#: views.py:171
msgid "Available permissions" msgid "Available permissions"
msgstr "" msgstr ""
#: views.py:215 #: views.py:168
msgid "Granted permissions"
msgstr ""
#: views.py:230
#, python-format #, python-format
msgid "Role \"%(role)s\" permission's for \"%(object)s\"." msgid "Role \"%(role)s\" permission's for \"%(object)s\""
msgstr "" msgstr ""
#: views.py:224 #: views.py:250
msgid "" msgid "Disabled permissions are inherited from a parent object."
"Disabled permissions are inherited from a parent object or directly granted "
"to the role and can't be removed from this view. Inherited permissions need "
"to be removed from the parent object's ACL or from them role via the Setup "
"menu."
msgstr "" msgstr ""
#: workflow_actions.py:26 #: workflow_actions.py:25
msgid "Object type" msgid "Object type"
msgstr "" msgstr ""
#: workflow_actions.py:29 #: workflow_actions.py:28
msgid "Type of the object for which the access will be modified." msgid "Type of the object for which the access will be modified."
msgstr "" msgstr ""
#: workflow_actions.py:35 #: workflow_actions.py:34
msgid "Object ID" msgid "Object ID"
msgstr "" msgstr ""
#: workflow_actions.py:38 #: workflow_actions.py:37
msgid "" msgid "Numeric identifier of the object for which the access will be modified."
"Numeric identifier of the object for which the access will be modified."
msgstr "" msgstr ""
#: workflow_actions.py:43 workflow_actions.py:158 #: workflow_actions.py:42
msgid "Roles" msgid "Roles"
msgstr "Роли" msgstr "Роли"
#: workflow_actions.py:45 workflow_actions.py:160 #: workflow_actions.py:44
msgid "Roles whose access will be modified." msgid "Roles whose access will be modified."
msgstr "" msgstr ""
#: workflow_actions.py:52 workflow_actions.py:167 #: workflow_actions.py:51
msgid "" msgid ""
"Permissions to grant/revoke to/from the role for the object selected above." "Permissions to grant/revoke to/from the role for the object selected above."
msgstr "" msgstr ""
#: workflow_actions.py:60 #: workflow_actions.py:59
msgid "Grant access" msgid "Grant access"
msgstr "" msgstr ""
#: workflow_actions.py:143 #: workflow_actions.py:129
msgid "Revoke access" msgid "Revoke access"
msgstr "" msgstr ""
#: workflow_actions.py:175
msgid "Grant document access"
msgstr ""
#: workflow_actions.py:214
msgid "Revoke document access"
msgstr ""

View File

@@ -1,77 +1,70 @@
# SOME DESCRIPTIVE TITLE. # SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package. # This file is distributed under the same license as the PACKAGE package.
# #
# Translators: # Translators:
# Atdhe Tabaku <Atdhe617@gmail.com>, 2018 # Atdhe Tabaku <Atdhe617@gmail.com>, 2018
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Mayan EDMS\n" "Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-07-05 01:27-0400\n" "POT-Creation-Date: 2019-04-09 02:06-0400\n"
"PO-Revision-Date: 2019-06-15 07:48+0000\n" "PO-Revision-Date: 2018-09-08 08:06+0000\n"
"Last-Translator: Roberto Rosario\n" "Last-Translator: Roberto Rosario\n"
"Language-Team: Bosnian (Bosnia and Herzegovina) (http://www.transifex.com/rosarior/mayan-edms/language/bs_BA/)\n" "Language-Team: Bosnian (Bosnia and Herzegovina) (http://www.transifex.com/"
"rosarior/mayan-edms/language/bs_BA/)\n"
"Language: bs_BA\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Language: bs_BA\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
#: apps.py:24 links.py:44 #: apps.py:15 links.py:37
msgid "ACLs" msgid "ACLs"
msgstr "ACLs" msgstr "ACLs"
#: events.py:8 permissions.py:7 #: apps.py:23 models.py:47
msgid "Access control lists"
msgstr "Liste kontrole pristupa (ACLs)"
#: events.py:12
msgid "ACL created"
msgstr ""
#: events.py:15
msgid "ACL edited"
msgstr ""
#: forms.py:15 models.py:49
msgid "Role" msgid "Role"
msgstr "Uloga" msgstr "Uloga"
#: links.py:34 #: apps.py:26 links.py:46 models.py:43 workflow_actions.py:48
msgid "New ACL"
msgstr "Novi ACL"
#: links.py:39
msgid "Delete"
msgstr "Obriši"
#: links.py:49 models.py:45 workflow_actions.py:49 workflow_actions.py:164
msgid "Permissions" msgid "Permissions"
msgstr "Dozvole" msgstr "Dozvole"
#: managers.py:216 #: links.py:32
#, python-format msgid "Delete"
msgid "Object \"%s\" is not a model and cannot be checked for access." msgstr "Obriši"
msgstr ""
#: managers.py:236 #: links.py:41
msgid "New ACL"
msgstr "Novi ACL"
#: managers.py:61 managers.py:102
#, python-format #, python-format
msgid "Insufficient access for: %s" msgid "Insufficient access for: %s"
msgstr "Nedovoljan pristup za:%s" msgstr "Nedovoljan pristup za:%s"
#: models.py:57 #: models.py:55
msgid "Access entry" msgid "Access entry"
msgstr "Pristupni unos" msgstr "Pristupni unos"
#: models.py:58 #: models.py:56
msgid "Access entries" msgid "Access entries"
msgstr "Pristupni unosi" msgstr "Pristupni unosi"
#: models.py:62 #: models.py:60
#, python-format #, python-format
msgid "Role \"%(role)s\" permission's for \"%(object)s\"" msgid "Permissions \"%(permissions)s\" to role \"%(role)s\" for \"%(object)s\""
msgstr "Uloga \"%(role)s\" dozvole za \"%(object)s\"" msgstr "Pristup \"%(permissions)s\" za ulogu \"%(role)s\" za \"%(object)s\""
#: models.py:77
msgid "None"
msgstr "Nijedno"
#: permissions.py:7
msgid "Access control lists"
msgstr "Liste kontrole pristupa (ACLs)"
#: permissions.py:10 #: permissions.py:10
msgid "Edit ACLs" msgid "Edit ACLs"
@@ -81,124 +74,116 @@ msgstr "Izmjeniti ACLs"
msgid "View ACLs" msgid "View ACLs"
msgstr "Pregledati ACLs" msgstr "Pregledati ACLs"
#: serializers.py:26 serializers.py:136 #: serializers.py:24 serializers.py:132
msgid "" msgid ""
"API URL pointing to the list of permissions for this access control list." "API URL pointing to the list of permissions for this access control list."
msgstr "API URL ukazujući na listu dozvola za ovu listu kontrole pristupa." msgstr "API URL ukazujući na listu dozvola za ovu listu kontrole pristupa."
#: serializers.py:59 #: serializers.py:57
msgid "" msgid ""
"API URL pointing to a permission in relation to the access control list to " "API URL pointing to a permission in relation to the access control list to "
"which it is attached. This URL is different than the canonical workflow URL." "which it is attached. This URL is different than the canonical workflow URL."
msgstr "URL API koji ukazuje na dozvolu u vezi sa listom kontrole pristupa kojoj je priložena. Ova URL adresa se razlikuje od kanonskog URL-a za radni tok." msgstr ""
"URL API koji ukazuje na dozvolu u vezi sa listom kontrole pristupa kojoj je "
"priložena. Ova URL adresa se razlikuje od kanonskog URL-a za radni tok."
#: serializers.py:91 #: serializers.py:87
msgid "Primary key of the new permission to grant to the access control list." msgid "Primary key of the new permission to grant to the access control list."
msgstr "Primarni ključ za novu dozvolu za dodjelu listi kontrole pristupa." msgstr "Primarni ključ za novu dozvolu za dodjelu listi kontrole pristupa."
#: serializers.py:115 serializers.py:191 #: serializers.py:111 serializers.py:187
#, python-format #, python-format
msgid "No such permission: %s" msgid "No such permission: %s"
msgstr "Nema takve dozvole: %s" msgstr "Nema takve dozvole: %s"
#: serializers.py:130 #: serializers.py:126
msgid "" msgid ""
"Comma separated list of permission primary keys to grant to this access " "Comma separated list of permission primary keys to grant to this access "
"control list." "control list."
msgstr "Lista odvojenih primarnih ključeva za razdvajanje sa komandom dodeljuje se ovoj listi kontrola pristupa." msgstr ""
"Lista odvojenih primarnih ključeva za razdvajanje sa komandom dodeljuje se "
"ovoj listi kontrola pristupa."
#: serializers.py:142 #: serializers.py:138
msgid "Primary keys of the role to which this access control list binds to." msgid "Primary keys of the role to which this access control list binds to."
msgstr "Primarni ključevi uloge na koje se ova lista kontrole pristupa vezuje." msgstr "Primarni ključevi uloge na koje se ova lista kontrole pristupa vezuje."
#: views.py:62 #: views.py:77
#, python-format #, python-format
msgid "New access control lists for: %s" msgid "New access control lists for: %s"
msgstr "Nove kontrole pristupa za:%s" msgstr "Nove kontrole pristupa za:%s"
#: views.py:100 #: views.py:104
#, python-format #, python-format
msgid "Delete ACL: %s" msgid "Delete ACL: %s"
msgstr "Obriši ACL:%s" msgstr "Obriši ACL:%s"
#: views.py:147 #: views.py:148
msgid "There are no ACLs for this object" msgid "There are no ACLs for this object"
msgstr "" msgstr ""
#: views.py:150 #: views.py:151
msgid "" msgid ""
"ACL stands for Access Control List and is a precise method to control user " "ACL stands for Access Control List and is a precise method to control user "
"access to objects in the system." "access to objects in the system."
msgstr "" msgstr ""
#: views.py:154 #: views.py:155
#, python-format #, python-format
msgid "Access control lists for: %s" msgid "Access control lists for: %s"
msgstr "Liste kontrole pristupa (ACL) za: %s" msgstr "Liste kontrole pristupa (ACL) za: %s"
#: views.py:170 #: views.py:167
msgid "Granted permissions"
msgstr "Dodjeljene dozvole"
#: views.py:171
msgid "Available permissions" msgid "Available permissions"
msgstr "Dostupne dozvole" msgstr "Dostupne dozvole"
#: views.py:215 #: views.py:168
msgid "Granted permissions"
msgstr "Dodjeljene dozvole"
#: views.py:230
#, python-format #, python-format
msgid "Role \"%(role)s\" permission's for \"%(object)s\"." msgid "Role \"%(role)s\" permission's for \"%(object)s\""
msgstr "" msgstr "Uloga \"%(role)s\" dozvole za \"%(object)s\""
#: views.py:224 #: views.py:250
msgid "" msgid "Disabled permissions are inherited from a parent object."
"Disabled permissions are inherited from a parent object or directly granted " msgstr "Dozvole za onesposobljavanje su nasledjene od roditeljskog objekta."
"to the role and can't be removed from this view. Inherited permissions need "
"to be removed from the parent object's ACL or from them role via the Setup "
"menu."
msgstr ""
#: workflow_actions.py:26 #: workflow_actions.py:25
msgid "Object type" msgid "Object type"
msgstr "Tip objekta" msgstr "Tip objekta"
#: workflow_actions.py:29 #: workflow_actions.py:28
msgid "Type of the object for which the access will be modified." msgid "Type of the object for which the access will be modified."
msgstr "Tip objekta za koji će se pristup mijenjati." msgstr "Tip objekta za koji će se pristup mijenjati."
#: workflow_actions.py:35 #: workflow_actions.py:34
msgid "Object ID" msgid "Object ID"
msgstr "ID objekta" msgstr "ID objekta"
#: workflow_actions.py:38 #: workflow_actions.py:37
msgid "" msgid "Numeric identifier of the object for which the access will be modified."
"Numeric identifier of the object for which the access will be modified."
msgstr "Numerički identifikator objekta za koji će se pristup mijenjati." msgstr "Numerički identifikator objekta za koji će se pristup mijenjati."
#: workflow_actions.py:43 workflow_actions.py:158 #: workflow_actions.py:42
msgid "Roles" msgid "Roles"
msgstr "Role" msgstr "Role"
#: workflow_actions.py:45 workflow_actions.py:160 #: workflow_actions.py:44
msgid "Roles whose access will be modified." msgid "Roles whose access will be modified."
msgstr "Uloge čiji će pristup biti modifikovan." msgstr "Uloge čiji će pristup biti modifikovan."
#: workflow_actions.py:52 workflow_actions.py:167 #: workflow_actions.py:51
msgid "" msgid ""
"Permissions to grant/revoke to/from the role for the object selected above." "Permissions to grant/revoke to/from the role for the object selected above."
msgstr "Dozvole za dodeljivanje / poništavanje / od uloge za gore izabrani objekat." msgstr ""
"Dozvole za dodeljivanje / poništavanje / od uloge za gore izabrani objekat."
#: workflow_actions.py:60 #: workflow_actions.py:59
msgid "Grant access" msgid "Grant access"
msgstr "Dodjeljen pristup" msgstr "Dodjeljen pristup"
#: workflow_actions.py:143 #: workflow_actions.py:129
msgid "Revoke access" msgid "Revoke access"
msgstr "Opozvati pristup" msgstr "Opozvati pristup"
#: workflow_actions.py:175
msgid "Grant document access"
msgstr ""
#: workflow_actions.py:214
msgid "Revoke document access"
msgstr ""

View File

@@ -1,76 +1,68 @@
# SOME DESCRIPTIVE TITLE. # SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package. # This file is distributed under the same license as the PACKAGE package.
# #
# Translators: # Translators:
# Jiri Fait <fait@orkasolutions.cz>, 2019
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Mayan EDMS\n" "Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-07-05 01:27-0400\n" "POT-Creation-Date: 2019-04-09 02:06-0400\n"
"PO-Revision-Date: 2019-06-15 07:48+0000\n" "PO-Revision-Date: 2019-01-17 19:28+0000\n"
"Last-Translator: Roberto Rosario\n" "Last-Translator: Jiri Fait <fait@orkasolutions.cz>\n"
"Language-Team: Czech (http://www.transifex.com/rosarior/mayan-edms/language/cs/)\n" "Language-Team: Czech (http://www.transifex.com/rosarior/mayan-edms/language/"
"cs/)\n"
"Language: cs\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Language: cs\n" "Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n "
"Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;\n" "<= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;\n"
#: apps.py:24 links.py:44 #: apps.py:15 links.py:37
msgid "ACLs" msgid "ACLs"
msgstr "" msgstr ""
#: events.py:8 permissions.py:7 #: apps.py:23 models.py:47
msgid "Access control lists"
msgstr ""
#: events.py:12
msgid "ACL created"
msgstr ""
#: events.py:15
msgid "ACL edited"
msgstr ""
#: forms.py:15 models.py:49
msgid "Role" msgid "Role"
msgstr "" msgstr ""
#: links.py:34 #: apps.py:26 links.py:46 models.py:43 workflow_actions.py:48
msgid "New ACL" msgid "Permissions"
msgstr "" msgstr ""
#: links.py:39 #: links.py:32
msgid "Delete" msgid "Delete"
msgstr "Odstranit" msgstr "Odstranit"
#: links.py:49 models.py:45 workflow_actions.py:49 workflow_actions.py:164 #: links.py:41
msgid "Permissions" msgid "New ACL"
msgstr "Práva"
#: managers.py:216
#, python-format
msgid "Object \"%s\" is not a model and cannot be checked for access."
msgstr "" msgstr ""
#: managers.py:236 #: managers.py:61 managers.py:102
#, python-format #, python-format
msgid "Insufficient access for: %s" msgid "Insufficient access for: %s"
msgstr "" msgstr ""
#: models.py:57 #: models.py:55
msgid "Access entry" msgid "Access entry"
msgstr "" msgstr ""
#: models.py:58 #: models.py:56
msgid "Access entries" msgid "Access entries"
msgstr "" msgstr ""
#: models.py:62 #: models.py:60
#, python-format #, python-format
msgid "Role \"%(role)s\" permission's for \"%(object)s\"" msgid "Permissions \"%(permissions)s\" to role \"%(role)s\" for \"%(object)s\""
msgstr ""
#: models.py:77
msgid "None"
msgstr ""
#: permissions.py:7
msgid "Access control lists"
msgstr "" msgstr ""
#: permissions.py:10 #: permissions.py:10
@@ -81,124 +73,111 @@ msgstr ""
msgid "View ACLs" msgid "View ACLs"
msgstr "" msgstr ""
#: serializers.py:26 serializers.py:136 #: serializers.py:24 serializers.py:132
msgid "" msgid ""
"API URL pointing to the list of permissions for this access control list." "API URL pointing to the list of permissions for this access control list."
msgstr "" msgstr ""
#: serializers.py:59 #: serializers.py:57
msgid "" msgid ""
"API URL pointing to a permission in relation to the access control list to " "API URL pointing to a permission in relation to the access control list to "
"which it is attached. This URL is different than the canonical workflow URL." "which it is attached. This URL is different than the canonical workflow URL."
msgstr "" msgstr ""
#: serializers.py:91 #: serializers.py:87
msgid "Primary key of the new permission to grant to the access control list." msgid "Primary key of the new permission to grant to the access control list."
msgstr "" msgstr ""
#: serializers.py:115 serializers.py:191 #: serializers.py:111 serializers.py:187
#, python-format #, python-format
msgid "No such permission: %s" msgid "No such permission: %s"
msgstr "" msgstr ""
#: serializers.py:130 #: serializers.py:126
msgid "" msgid ""
"Comma separated list of permission primary keys to grant to this access " "Comma separated list of permission primary keys to grant to this access "
"control list." "control list."
msgstr "" msgstr ""
#: serializers.py:142 #: serializers.py:138
msgid "Primary keys of the role to which this access control list binds to." msgid "Primary keys of the role to which this access control list binds to."
msgstr "" msgstr ""
#: views.py:62 #: views.py:77
#, python-format #, python-format
msgid "New access control lists for: %s" msgid "New access control lists for: %s"
msgstr "" msgstr ""
#: views.py:100 #: views.py:104
#, python-format #, python-format
msgid "Delete ACL: %s" msgid "Delete ACL: %s"
msgstr "" msgstr ""
#: views.py:147 #: views.py:148
msgid "There are no ACLs for this object" msgid "There are no ACLs for this object"
msgstr "" msgstr ""
#: views.py:150 #: views.py:151
msgid "" msgid ""
"ACL stands for Access Control List and is a precise method to control user " "ACL stands for Access Control List and is a precise method to control user "
"access to objects in the system." "access to objects in the system."
msgstr "" msgstr ""
#: views.py:154 #: views.py:155
#, python-format #, python-format
msgid "Access control lists for: %s" msgid "Access control lists for: %s"
msgstr "" msgstr ""
#: views.py:170 #: views.py:167
msgid "Granted permissions"
msgstr ""
#: views.py:171
msgid "Available permissions" msgid "Available permissions"
msgstr "" msgstr ""
#: views.py:215 #: views.py:168
msgid "Granted permissions"
msgstr ""
#: views.py:230
#, python-format #, python-format
msgid "Role \"%(role)s\" permission's for \"%(object)s\"." msgid "Role \"%(role)s\" permission's for \"%(object)s\""
msgstr "" msgstr ""
#: views.py:224 #: views.py:250
msgid "" msgid "Disabled permissions are inherited from a parent object."
"Disabled permissions are inherited from a parent object or directly granted "
"to the role and can't be removed from this view. Inherited permissions need "
"to be removed from the parent object's ACL or from them role via the Setup "
"menu."
msgstr "" msgstr ""
#: workflow_actions.py:26 #: workflow_actions.py:25
msgid "Object type" msgid "Object type"
msgstr "" msgstr ""
#: workflow_actions.py:29 #: workflow_actions.py:28
msgid "Type of the object for which the access will be modified." msgid "Type of the object for which the access will be modified."
msgstr "" msgstr ""
#: workflow_actions.py:35 #: workflow_actions.py:34
msgid "Object ID" msgid "Object ID"
msgstr "" msgstr ""
#: workflow_actions.py:38 #: workflow_actions.py:37
msgid "" msgid "Numeric identifier of the object for which the access will be modified."
"Numeric identifier of the object for which the access will be modified."
msgstr "" msgstr ""
#: workflow_actions.py:43 workflow_actions.py:158 #: workflow_actions.py:42
msgid "Roles" msgid "Roles"
msgstr "" msgstr ""
#: workflow_actions.py:45 workflow_actions.py:160 #: workflow_actions.py:44
msgid "Roles whose access will be modified." msgid "Roles whose access will be modified."
msgstr "" msgstr ""
#: workflow_actions.py:52 workflow_actions.py:167 #: workflow_actions.py:51
msgid "" msgid ""
"Permissions to grant/revoke to/from the role for the object selected above." "Permissions to grant/revoke to/from the role for the object selected above."
msgstr "" msgstr ""
#: workflow_actions.py:60 #: workflow_actions.py:59
msgid "Grant access" msgid "Grant access"
msgstr "" msgstr ""
#: workflow_actions.py:143 #: workflow_actions.py:129
msgid "Revoke access" msgid "Revoke access"
msgstr "" msgstr ""
#: workflow_actions.py:175
msgid "Grant document access"
msgstr ""
#: workflow_actions.py:214
msgid "Revoke document access"
msgstr ""

View File

@@ -1,76 +1,69 @@
# SOME DESCRIPTIVE TITLE. # SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package. # This file is distributed under the same license as the PACKAGE package.
# #
# Translators: # Translators:
# Rasmus Kierudsen <tebrasso@gmail.com>, 2018 # Rasmus Kierudsen <tebrasso@gmail.com>, 2018
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Mayan EDMS\n" "Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-07-05 01:27-0400\n" "POT-Creation-Date: 2019-04-09 02:06-0400\n"
"PO-Revision-Date: 2019-06-15 07:48+0000\n" "PO-Revision-Date: 2018-11-12 14:13+0000\n"
"Last-Translator: Roberto Rosario\n" "Last-Translator: Rasmus Kierudsen <tebrasso@gmail.com>\n"
"Language-Team: Danish (Denmark) (http://www.transifex.com/rosarior/mayan-edms/language/da_DK/)\n" "Language-Team: Danish (Denmark) (http://www.transifex.com/rosarior/mayan-"
"edms/language/da_DK/)\n"
"Language: da_DK\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Language: da_DK\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: apps.py:24 links.py:44 #: apps.py:15 links.py:37
msgid "ACLs" msgid "ACLs"
msgstr "ACL'er" msgstr "ACL'er"
#: events.py:8 permissions.py:7 #: apps.py:23 models.py:47
msgid "Access control lists"
msgstr ""
#: events.py:12
msgid "ACL created"
msgstr ""
#: events.py:15
msgid "ACL edited"
msgstr ""
#: forms.py:15 models.py:49
msgid "Role" msgid "Role"
msgstr "Rolle" msgstr "Rolle"
#: links.py:34 #: apps.py:26 links.py:46 models.py:43 workflow_actions.py:48
msgid "New ACL"
msgstr "Ny ACL"
#: links.py:39
msgid "Delete"
msgstr "Slet"
#: links.py:49 models.py:45 workflow_actions.py:49 workflow_actions.py:164
msgid "Permissions" msgid "Permissions"
msgstr "Tilladelser" msgstr "Tilladelser"
#: managers.py:216 #: links.py:32
#, python-format msgid "Delete"
msgid "Object \"%s\" is not a model and cannot be checked for access." msgstr "Slet"
msgstr ""
#: managers.py:236 #: links.py:41
msgid "New ACL"
msgstr "Ny ACL"
#: managers.py:61 managers.py:102
#, python-format #, python-format
msgid "Insufficient access for: %s" msgid "Insufficient access for: %s"
msgstr "Utilstækkelig adgang for: %s" msgstr "Utilstækkelig adgang for: %s"
#: models.py:57 #: models.py:55
msgid "Access entry" msgid "Access entry"
msgstr "" msgstr ""
#: models.py:58 #: models.py:56
msgid "Access entries" msgid "Access entries"
msgstr "" msgstr ""
#: models.py:62 #: models.py:60
#, python-format #, python-format
msgid "Role \"%(role)s\" permission's for \"%(object)s\"" msgid "Permissions \"%(permissions)s\" to role \"%(role)s\" for \"%(object)s\""
msgstr ""
"Tilladelse \"%(permissions)s\" til rolle \"%(role)s\" for \"%(object)s\""
#: models.py:77
msgid "None"
msgstr "Ingen"
#: permissions.py:7
msgid "Access control lists"
msgstr "" msgstr ""
#: permissions.py:10 #: permissions.py:10
@@ -81,124 +74,111 @@ msgstr "Editér ACL"
msgid "View ACLs" msgid "View ACLs"
msgstr "Se ACL" msgstr "Se ACL"
#: serializers.py:26 serializers.py:136 #: serializers.py:24 serializers.py:132
msgid "" msgid ""
"API URL pointing to the list of permissions for this access control list." "API URL pointing to the list of permissions for this access control list."
msgstr "" msgstr ""
#: serializers.py:59 #: serializers.py:57
msgid "" msgid ""
"API URL pointing to a permission in relation to the access control list to " "API URL pointing to a permission in relation to the access control list to "
"which it is attached. This URL is different than the canonical workflow URL." "which it is attached. This URL is different than the canonical workflow URL."
msgstr "" msgstr ""
#: serializers.py:91 #: serializers.py:87
msgid "Primary key of the new permission to grant to the access control list." msgid "Primary key of the new permission to grant to the access control list."
msgstr "" msgstr ""
#: serializers.py:115 serializers.py:191 #: serializers.py:111 serializers.py:187
#, python-format #, python-format
msgid "No such permission: %s" msgid "No such permission: %s"
msgstr "" msgstr ""
#: serializers.py:130 #: serializers.py:126
msgid "" msgid ""
"Comma separated list of permission primary keys to grant to this access " "Comma separated list of permission primary keys to grant to this access "
"control list." "control list."
msgstr "" msgstr ""
#: serializers.py:142 #: serializers.py:138
msgid "Primary keys of the role to which this access control list binds to." msgid "Primary keys of the role to which this access control list binds to."
msgstr "" msgstr ""
#: views.py:62 #: views.py:77
#, python-format #, python-format
msgid "New access control lists for: %s" msgid "New access control lists for: %s"
msgstr "" msgstr ""
#: views.py:100 #: views.py:104
#, python-format #, python-format
msgid "Delete ACL: %s" msgid "Delete ACL: %s"
msgstr "Slet ACL: %s" msgstr "Slet ACL: %s"
#: views.py:147 #: views.py:148
msgid "There are no ACLs for this object" msgid "There are no ACLs for this object"
msgstr "" msgstr ""
#: views.py:150 #: views.py:151
msgid "" msgid ""
"ACL stands for Access Control List and is a precise method to control user " "ACL stands for Access Control List and is a precise method to control user "
"access to objects in the system." "access to objects in the system."
msgstr "" msgstr ""
#: views.py:154 #: views.py:155
#, python-format #, python-format
msgid "Access control lists for: %s" msgid "Access control lists for: %s"
msgstr "" msgstr ""
#: views.py:170 #: views.py:167
msgid "Granted permissions"
msgstr ""
#: views.py:171
msgid "Available permissions" msgid "Available permissions"
msgstr "" msgstr ""
#: views.py:215 #: views.py:168
msgid "Granted permissions"
msgstr ""
#: views.py:230
#, python-format #, python-format
msgid "Role \"%(role)s\" permission's for \"%(object)s\"." msgid "Role \"%(role)s\" permission's for \"%(object)s\""
msgstr "" msgstr ""
#: views.py:224 #: views.py:250
msgid "" msgid "Disabled permissions are inherited from a parent object."
"Disabled permissions are inherited from a parent object or directly granted "
"to the role and can't be removed from this view. Inherited permissions need "
"to be removed from the parent object's ACL or from them role via the Setup "
"menu."
msgstr "" msgstr ""
#: workflow_actions.py:26 #: workflow_actions.py:25
msgid "Object type" msgid "Object type"
msgstr "Objekttype" msgstr "Objekttype"
#: workflow_actions.py:29 #: workflow_actions.py:28
msgid "Type of the object for which the access will be modified." msgid "Type of the object for which the access will be modified."
msgstr "" msgstr ""
#: workflow_actions.py:35 #: workflow_actions.py:34
msgid "Object ID" msgid "Object ID"
msgstr "Objekt ID" msgstr "Objekt ID"
#: workflow_actions.py:38 #: workflow_actions.py:37
msgid "" msgid "Numeric identifier of the object for which the access will be modified."
"Numeric identifier of the object for which the access will be modified."
msgstr "" msgstr ""
#: workflow_actions.py:43 workflow_actions.py:158 #: workflow_actions.py:42
msgid "Roles" msgid "Roles"
msgstr "Roller" msgstr "Roller"
#: workflow_actions.py:45 workflow_actions.py:160 #: workflow_actions.py:44
msgid "Roles whose access will be modified." msgid "Roles whose access will be modified."
msgstr "" msgstr ""
#: workflow_actions.py:52 workflow_actions.py:167 #: workflow_actions.py:51
msgid "" msgid ""
"Permissions to grant/revoke to/from the role for the object selected above." "Permissions to grant/revoke to/from the role for the object selected above."
msgstr "" msgstr ""
#: workflow_actions.py:60 #: workflow_actions.py:59
msgid "Grant access" msgid "Grant access"
msgstr "Giv tilladelse" msgstr "Giv tilladelse"
#: workflow_actions.py:143 #: workflow_actions.py:129
msgid "Revoke access" msgid "Revoke access"
msgstr "Tilbagekald tilladelse" msgstr "Tilbagekald tilladelse"
#: workflow_actions.py:175
msgid "Grant document access"
msgstr ""
#: workflow_actions.py:214
msgid "Revoke document access"
msgstr ""

View File

@@ -1,7 +1,7 @@
# SOME DESCRIPTIVE TITLE. # SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package. # This file is distributed under the same license as the PACKAGE package.
# #
# Translators: # Translators:
# Berny <berny@bernhard-marx.de>, 2015 # Berny <berny@bernhard-marx.de>, 2015
# Jesaja Everling <jeverling@gmail.com>, 2017 # Jesaja Everling <jeverling@gmail.com>, 2017
@@ -11,70 +11,63 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Mayan EDMS\n" "Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-07-05 01:27-0400\n" "POT-Creation-Date: 2019-04-09 02:06-0400\n"
"PO-Revision-Date: 2019-06-15 07:48+0000\n" "PO-Revision-Date: 2019-03-31 21:36+0000\n"
"Last-Translator: Roberto Rosario\n" "Last-Translator: Mathias Behrle <mathiasb@m9s.biz>\n"
"Language-Team: German (Germany) (http://www.transifex.com/rosarior/mayan-edms/language/de_DE/)\n" "Language-Team: German (Germany) (http://www.transifex.com/rosarior/mayan-"
"edms/language/de_DE/)\n"
"Language: de_DE\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Language: de_DE\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: apps.py:24 links.py:44 #: apps.py:15 links.py:37
msgid "ACLs" msgid "ACLs"
msgstr "Zugriffsberechtigungen" msgstr "Zugriffsberechtigungen"
#: events.py:8 permissions.py:7 #: apps.py:23 models.py:47
msgid "Access control lists"
msgstr "Zugriffsberechtigungen"
#: events.py:12
msgid "ACL created"
msgstr "Zugriffsberechtigung erstellt"
#: events.py:15
msgid "ACL edited"
msgstr "Zugriffsberechtigung bearbeitet"
#: forms.py:15 models.py:49
msgid "Role" msgid "Role"
msgstr "Rolle" msgstr "Rolle"
#: links.py:34 #: apps.py:26 links.py:46 models.py:43 workflow_actions.py:48
msgid "New ACL"
msgstr "Neue Berechtigung"
#: links.py:39
msgid "Delete"
msgstr "Löschen"
#: links.py:49 models.py:45 workflow_actions.py:49 workflow_actions.py:164
msgid "Permissions" msgid "Permissions"
msgstr "Berechtigungen" msgstr "Berechtigungen"
#: managers.py:216 #: links.py:32
#, python-format msgid "Delete"
msgid "Object \"%s\" is not a model and cannot be checked for access." msgstr "Löschen"
msgstr "Objekt \"%s\" ist kein Modell und kann nicht auf Zugriffsberechtigungen überprüft werden."
#: managers.py:236 #: links.py:41
msgid "New ACL"
msgstr "Neue Berechtigung"
#: managers.py:61 managers.py:102
#, python-format #, python-format
msgid "Insufficient access for: %s" msgid "Insufficient access for: %s"
msgstr "Unzureichende Berechtigung für: %s" msgstr "Unzureichende Berechtigung für: %s"
#: models.py:57 #: models.py:55
msgid "Access entry" msgid "Access entry"
msgstr "Berechtigungseintrag" msgstr "Berechtigungseintrag"
#: models.py:58 #: models.py:56
msgid "Access entries" msgid "Access entries"
msgstr "Berechtigungseinträge" msgstr "Berechtigungseinträge"
#: models.py:62 #: models.py:60
#, python-format #, python-format
msgid "Role \"%(role)s\" permission's for \"%(object)s\"" msgid "Permissions \"%(permissions)s\" to role \"%(role)s\" for \"%(object)s\""
msgstr "Berechtigungen von Rolle \"%(role)s\" für \"%(object)s\"" msgstr ""
"Berechtigungen \"%(permissions)s\" von Rolle \"%(role)s\" für \"%(object)s\""
#: models.py:77
msgid "None"
msgstr "Keine"
#: permissions.py:7
msgid "Access control lists"
msgstr "Zugriffsberechtigungen"
#: permissions.py:10 #: permissions.py:10
msgid "Edit ACLs" msgid "Edit ACLs"
@@ -84,124 +77,123 @@ msgstr "Zugriffsberechtigungen bearbeiten"
msgid "View ACLs" msgid "View ACLs"
msgstr "Zugriffsberechtigungen anzeigen" msgstr "Zugriffsberechtigungen anzeigen"
#: serializers.py:26 serializers.py:136 #: serializers.py:24 serializers.py:132
msgid "" msgid ""
"API URL pointing to the list of permissions for this access control list." "API URL pointing to the list of permissions for this access control list."
msgstr "API URL für die Liste der Berechtigungen dieser ACL" msgstr "API URL für die Liste der Berechtigungen dieser ACL"
#: serializers.py:59 #: serializers.py:57
msgid "" msgid ""
"API URL pointing to a permission in relation to the access control list to " "API URL pointing to a permission in relation to the access control list to "
"which it is attached. This URL is different than the canonical workflow URL." "which it is attached. This URL is different than the canonical workflow URL."
msgstr "API URL für die Berechtigung in Beziehung zur Zugriffsberechtigungsliste der sie zugeordnet ist. Diese URL unterscheidet sich von der normalen Workflow URL." msgstr ""
"API URL für die Berechtigung in Beziehung zur Zugriffsberechtigungsliste der "
"sie zugeordnet ist. Diese URL unterscheidet sich von der normalen Workflow "
"URL."
#: serializers.py:91 #: serializers.py:87
msgid "Primary key of the new permission to grant to the access control list." msgid "Primary key of the new permission to grant to the access control list."
msgstr "Primärschlüssel der neuen Berechtigung für die Zugriffsberechtigungsliste." msgstr ""
"Primärschlüssel der neuen Berechtigung für die Zugriffsberechtigungsliste."
#: serializers.py:115 serializers.py:191 #: serializers.py:111 serializers.py:187
#, python-format #, python-format
msgid "No such permission: %s" msgid "No such permission: %s"
msgstr "Keine solche Berechtigung: %s" msgstr "Keine solche Berechtigung: %s"
#: serializers.py:130 #: serializers.py:126
msgid "" msgid ""
"Comma separated list of permission primary keys to grant to this access " "Comma separated list of permission primary keys to grant to this access "
"control list." "control list."
msgstr "Durch Komma getrennte Liste von Primärschlüsseln der zu dieser Zugriffsberechtigungsliste hinzuzufügenden Berechtigungen." msgstr ""
"Durch Komma getrennte Liste von Primärschlüsseln der zu dieser "
"Zugriffsberechtigungsliste hinzuzufügenden Berechtigungen."
#: serializers.py:142 #: serializers.py:138
msgid "Primary keys of the role to which this access control list binds to." msgid "Primary keys of the role to which this access control list binds to."
msgstr "Primärschlüssel der Rolle die dieser Zugriffsberechtigung zugeordnet ist." msgstr ""
"Primärschlüssel der Rolle die dieser Zugriffsberechtigung zugeordnet ist."
#: views.py:62 #: views.py:77
#, python-format #, python-format
msgid "New access control lists for: %s" msgid "New access control lists for: %s"
msgstr "Neue Zugriffsberechtigunglisten für %s" msgstr "Neue Zugriffsberechtigunglisten für %s"
#: views.py:100 #: views.py:104
#, python-format #, python-format
msgid "Delete ACL: %s" msgid "Delete ACL: %s"
msgstr "Zugriffsberechtigung \"%s\" löschen" msgstr "Zugriffsberechtigung \"%s\" löschen"
#: views.py:147 #: views.py:148
msgid "There are no ACLs for this object" msgid "There are no ACLs for this object"
msgstr "Keine Zugriffsberechtigungen für dieses Objekt verfügbar" msgstr "Keine Zugriffsberechtigungen für dieses Objekt verfügbar"
#: views.py:150 #: views.py:151
msgid "" msgid ""
"ACL stands for Access Control List and is a precise method to control user " "ACL stands for Access Control List and is a precise method to control user "
"access to objects in the system." "access to objects in the system."
msgstr "Über Zugriffsberechtigungen wird der Zugriff von Benutzern zu Systemobjekten kontrolliert." msgstr ""
"Über Zugriffsberechtigungen wird der Zugriff von Benutzern zu Systemobjekten "
"kontrolliert."
#: views.py:154 #: views.py:155
#, python-format #, python-format
msgid "Access control lists for: %s" msgid "Access control lists for: %s"
msgstr "Zugriffsberechtigungen für %s" msgstr "Zugriffsberechtigungen für %s"
#: views.py:170 #: views.py:167
msgid "Granted permissions"
msgstr "Erteilte Berechtigungen"
#: views.py:171
msgid "Available permissions" msgid "Available permissions"
msgstr "Verfügbare Berechtigungen" msgstr "Verfügbare Berechtigungen"
#: views.py:215 #: views.py:168
msgid "Granted permissions"
msgstr "Erteilte Berechtigungen"
#: views.py:230
#, python-format #, python-format
msgid "Role \"%(role)s\" permission's for \"%(object)s\"." msgid "Role \"%(role)s\" permission's for \"%(object)s\""
msgstr "Berechtigungen von Rolle \"%(role)s\" für \"%(object)s\"." msgstr "Berechtigungen von Rolle \"%(role)s\" für \"%(object)s\""
#: views.py:224 #: views.py:250
msgid "" msgid "Disabled permissions are inherited from a parent object."
"Disabled permissions are inherited from a parent object or directly granted " msgstr ""
"to the role and can't be removed from this view. Inherited permissions need " "Deaktivierte Berechtigungen sind von einem übergeordneten Objekt vererbt."
"to be removed from the parent object's ACL or from them role via the Setup "
"menu."
msgstr "Unzureichende Berechtigungen werden durch ein übergeordnetes Objekt vererbt oder direkt an die Rolle erteilt. Sie können nicht direkt auf diesem Formular bearbeitet werden. Vererbte Berechtigungen müssen auf dem übergeordneten Objekt oder für die Rolle über das Einrichtungsmenü eingestellt werden."
#: workflow_actions.py:26 #: workflow_actions.py:25
msgid "Object type" msgid "Object type"
msgstr "Objekttyp" msgstr "Objekttyp"
#: workflow_actions.py:29 #: workflow_actions.py:28
msgid "Type of the object for which the access will be modified." msgid "Type of the object for which the access will be modified."
msgstr "Objekttyp für den der Zugang bearbeitet wird." msgstr "Objekttyp für den der Zugang bearbeitet wird."
#: workflow_actions.py:35 #: workflow_actions.py:34
msgid "Object ID" msgid "Object ID"
msgstr "Objekt ID" msgstr "Objekt ID"
#: workflow_actions.py:38 #: workflow_actions.py:37
msgid "" msgid "Numeric identifier of the object for which the access will be modified."
"Numeric identifier of the object for which the access will be modified."
msgstr "Numerischer Identifikator des Objekts" msgstr "Numerischer Identifikator des Objekts"
#: workflow_actions.py:43 workflow_actions.py:158 #: workflow_actions.py:42
msgid "Roles" msgid "Roles"
msgstr "Rollen" msgstr "Rollen"
#: workflow_actions.py:45 workflow_actions.py:160 #: workflow_actions.py:44
msgid "Roles whose access will be modified." msgid "Roles whose access will be modified."
msgstr "Rollen deren Zugang bearbeitet wird." msgstr "Rollen deren Zugang bearbeitet wird."
#: workflow_actions.py:52 workflow_actions.py:167 #: workflow_actions.py:51
msgid "" msgid ""
"Permissions to grant/revoke to/from the role for the object selected above." "Permissions to grant/revoke to/from the role for the object selected above."
msgstr "Berechtigungen, die der Rolle für das ausgewählte Objekt erteilt oder entzogen werden." msgstr ""
"Berechtigungen, die der Rolle für das ausgewählte Objekt erteilt oder "
"entzogen werden."
#: workflow_actions.py:60 #: workflow_actions.py:59
msgid "Grant access" msgid "Grant access"
msgstr "Zugriffsberechtigung erteilen" msgstr "Zugriffsberechtigung erteilen"
#: workflow_actions.py:143 #: workflow_actions.py:129
msgid "Revoke access" msgid "Revoke access"
msgstr "Zugriffsberechtigung entziehen" msgstr "Zugriffsberechtigung entziehen"
#: workflow_actions.py:175
msgid "Grant document access"
msgstr ""
#: workflow_actions.py:214
msgid "Revoke document access"
msgstr ""

View File

@@ -1,76 +1,69 @@
# SOME DESCRIPTIVE TITLE. # SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package. # This file is distributed under the same license as the PACKAGE package.
# #
# Translators: # Translators:
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Mayan EDMS\n" "Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-07-05 01:27-0400\n" "POT-Creation-Date: 2019-04-09 02:06-0400\n"
"PO-Revision-Date: 2019-06-15 07:48+0000\n" "PO-Revision-Date: 2018-09-08 08:06+0000\n"
"Last-Translator: Roberto Rosario\n" "Last-Translator: Roberto Rosario\n"
"Language-Team: Greek (http://www.transifex.com/rosarior/mayan-edms/language/el/)\n" "Language-Team: Greek (http://www.transifex.com/rosarior/mayan-edms/language/"
"el/)\n"
"Language: el\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Language: el\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: apps.py:24 links.py:44 #: apps.py:15 links.py:37
msgid "ACLs" msgid "ACLs"
msgstr "ΛΕΠ" msgstr "ΛΕΠ"
#: events.py:8 permissions.py:7 #: apps.py:23 models.py:47
msgid "Access control lists"
msgstr "Λίστες Ελέγχου Πρόσβασης (ΛΕΠ)"
#: events.py:12
msgid "ACL created"
msgstr ""
#: events.py:15
msgid "ACL edited"
msgstr ""
#: forms.py:15 models.py:49
msgid "Role" msgid "Role"
msgstr "Ρόλος" msgstr "Ρόλος"
#: links.py:34 #: apps.py:26 links.py:46 models.py:43 workflow_actions.py:48
msgid "New ACL"
msgstr "Νέα ΛΕΠ"
#: links.py:39
msgid "Delete"
msgstr "Διαγραφή"
#: links.py:49 models.py:45 workflow_actions.py:49 workflow_actions.py:164
msgid "Permissions" msgid "Permissions"
msgstr "Ανεπαρκή δικαιώματα" msgstr "Ανεπαρκή δικαιώματα"
#: managers.py:216 #: links.py:32
#, python-format msgid "Delete"
msgid "Object \"%s\" is not a model and cannot be checked for access." msgstr "Διαγραφή"
msgstr ""
#: managers.py:236 #: links.py:41
msgid "New ACL"
msgstr "Νέα ΛΕΠ"
#: managers.py:61 managers.py:102
#, python-format #, python-format
msgid "Insufficient access for: %s" msgid "Insufficient access for: %s"
msgstr "Μη επαρκή δικαιώματα πρόσβασης για το: %s" msgstr "Μη επαρκή δικαιώματα πρόσβασης για το: %s"
#: models.py:57 #: models.py:55
msgid "Access entry" msgid "Access entry"
msgstr "" msgstr ""
#: models.py:58 #: models.py:56
msgid "Access entries" msgid "Access entries"
msgstr "" msgstr ""
#: models.py:62 #: models.py:60
#, python-format #, python-format
msgid "Role \"%(role)s\" permission's for \"%(object)s\"" msgid "Permissions \"%(permissions)s\" to role \"%(role)s\" for \"%(object)s\""
msgstr "Δικαιώματα του Ρόλου \"%(role)s\" για \"%(object)s\"" msgstr ""
"Δικαιώματα \"%(permissions)s\" στον ρόλο \"%(role)s\" για \"%(object)s\""
#: models.py:77
msgid "None"
msgstr "Κανένα"
#: permissions.py:7
msgid "Access control lists"
msgstr "Λίστες Ελέγχου Πρόσβασης (ΛΕΠ)"
#: permissions.py:10 #: permissions.py:10
msgid "Edit ACLs" msgid "Edit ACLs"
@@ -80,124 +73,116 @@ msgstr "Τροποποιηση ΛΕΠ"
msgid "View ACLs" msgid "View ACLs"
msgstr "Εμφάνιση ΛΕΠ" msgstr "Εμφάνιση ΛΕΠ"
#: serializers.py:26 serializers.py:136 #: serializers.py:24 serializers.py:132
msgid "" msgid ""
"API URL pointing to the list of permissions for this access control list." "API URL pointing to the list of permissions for this access control list."
msgstr "" msgstr ""
#: serializers.py:59 #: serializers.py:57
msgid "" msgid ""
"API URL pointing to a permission in relation to the access control list to " "API URL pointing to a permission in relation to the access control list to "
"which it is attached. This URL is different than the canonical workflow URL." "which it is attached. This URL is different than the canonical workflow URL."
msgstr "" msgstr ""
#: serializers.py:91 #: serializers.py:87
msgid "Primary key of the new permission to grant to the access control list." msgid "Primary key of the new permission to grant to the access control list."
msgstr "" msgstr ""
#: serializers.py:115 serializers.py:191 #: serializers.py:111 serializers.py:187
#, python-format #, python-format
msgid "No such permission: %s" msgid "No such permission: %s"
msgstr "Άγνωστο δικαίωμα: %s" msgstr "Άγνωστο δικαίωμα: %s"
#: serializers.py:130 #: serializers.py:126
msgid "" msgid ""
"Comma separated list of permission primary keys to grant to this access " "Comma separated list of permission primary keys to grant to this access "
"control list." "control list."
msgstr "" msgstr ""
#: serializers.py:142 #: serializers.py:138
msgid "Primary keys of the role to which this access control list binds to." msgid "Primary keys of the role to which this access control list binds to."
msgstr "" msgstr ""
#: views.py:62 #: views.py:77
#, python-format #, python-format
msgid "New access control lists for: %s" msgid "New access control lists for: %s"
msgstr "Νέα λίστα ελέγχου για: %s" msgstr "Νέα λίστα ελέγχου για: %s"
#: views.py:100 #: views.py:104
#, python-format #, python-format
msgid "Delete ACL: %s" msgid "Delete ACL: %s"
msgstr "Διαγραφή ΛΕΠ: %s" msgstr "Διαγραφή ΛΕΠ: %s"
#: views.py:147 #: views.py:148
msgid "There are no ACLs for this object" msgid "There are no ACLs for this object"
msgstr "" msgstr ""
#: views.py:150 #: views.py:151
msgid "" msgid ""
"ACL stands for Access Control List and is a precise method to control user " "ACL stands for Access Control List and is a precise method to control user "
"access to objects in the system." "access to objects in the system."
msgstr "" msgstr ""
#: views.py:154 #: views.py:155
#, python-format #, python-format
msgid "Access control lists for: %s" msgid "Access control lists for: %s"
msgstr "Λίστα ελέγχου πρόσβασης για: %s" msgstr "Λίστα ελέγχου πρόσβασης για: %s"
#: views.py:170 #: views.py:167
msgid "Granted permissions"
msgstr "Χωρηγημένα δικαιώματα"
#: views.py:171
msgid "Available permissions" msgid "Available permissions"
msgstr "Διαθέσιμα δικαιώματα" msgstr "Διαθέσιμα δικαιώματα"
#: views.py:215 #: views.py:168
msgid "Granted permissions"
msgstr "Χωρηγημένα δικαιώματα"
#: views.py:230
#, python-format #, python-format
msgid "Role \"%(role)s\" permission's for \"%(object)s\"." msgid "Role \"%(role)s\" permission's for \"%(object)s\""
msgstr "" msgstr "Δικαιώματα του Ρόλου \"%(role)s\" για \"%(object)s\""
#: views.py:224 #: views.py:250
msgid "" msgid "Disabled permissions are inherited from a parent object."
"Disabled permissions are inherited from a parent object or directly granted "
"to the role and can't be removed from this view. Inherited permissions need "
"to be removed from the parent object's ACL or from them role via the Setup "
"menu."
msgstr "" msgstr ""
"Απενεργοποιημένα δικαιώματα κληρονομούνται από το \"γοννικό\" αντικείμενο"
#: workflow_actions.py:26 #: workflow_actions.py:25
msgid "Object type" msgid "Object type"
msgstr "Τύπος αντικειμένου" msgstr "Τύπος αντικειμένου"
#: workflow_actions.py:29 #: workflow_actions.py:28
msgid "Type of the object for which the access will be modified." msgid "Type of the object for which the access will be modified."
msgstr "Τύπος του αντικειμένου για το οποίο η πρόσβαση θα τροποποιηθεί." msgstr "Τύπος του αντικειμένου για το οποίο η πρόσβαση θα τροποποιηθεί."
#: workflow_actions.py:35 #: workflow_actions.py:34
msgid "Object ID" msgid "Object ID"
msgstr "Αναγνωριστικό αντικειμένου" msgstr "Αναγνωριστικό αντικειμένου"
#: workflow_actions.py:38 #: workflow_actions.py:37
msgid "" msgid "Numeric identifier of the object for which the access will be modified."
"Numeric identifier of the object for which the access will be modified." msgstr ""
msgstr "Αριθμητικό αναγνωριστικό του αντικειμένου για το οποίο η πρόσβαση θα τροποποιηθεί." "Αριθμητικό αναγνωριστικό του αντικειμένου για το οποίο η πρόσβαση θα "
"τροποποιηθεί."
#: workflow_actions.py:43 workflow_actions.py:158 #: workflow_actions.py:42
msgid "Roles" msgid "Roles"
msgstr "Ρόλοι" msgstr "Ρόλοι"
#: workflow_actions.py:45 workflow_actions.py:160 #: workflow_actions.py:44
msgid "Roles whose access will be modified." msgid "Roles whose access will be modified."
msgstr "Ρόλοι των οποιων η πρόσβαση θα τροποποιηθει." msgstr "Ρόλοι των οποιων η πρόσβαση θα τροποποιηθει."
#: workflow_actions.py:52 workflow_actions.py:167 #: workflow_actions.py:51
msgid "" msgid ""
"Permissions to grant/revoke to/from the role for the object selected above." "Permissions to grant/revoke to/from the role for the object selected above."
msgstr "Δικαιώματα προς χορήγηση/ανάληση προς/από τον ρόλο για το ανωτέρω επιλεγμένο αντικείμενο." msgstr ""
"Δικαιώματα προς χορήγηση/ανάληση προς/από τον ρόλο για το ανωτέρω επιλεγμένο "
"αντικείμενο."
#: workflow_actions.py:60 #: workflow_actions.py:59
msgid "Grant access" msgid "Grant access"
msgstr "Χορήγηση πρόσβασης" msgstr "Χορήγηση πρόσβασης"
#: workflow_actions.py:143 #: workflow_actions.py:129
msgid "Revoke access" msgid "Revoke access"
msgstr "Ανάκληση πρόσβασης" msgstr "Ανάκληση πρόσβασης"
#: workflow_actions.py:175
msgid "Grant document access"
msgstr ""
#: workflow_actions.py:214
msgid "Revoke document access"
msgstr ""

Some files were not shown because too many files have changed in this diff Show More