580 lines
22 KiB
Plaintext
580 lines
22 KiB
Plaintext
Version 2.0
|
|
===========
|
|
|
|
Released: December 2015
|
|
|
|
Changes
|
|
-------
|
|
|
|
Update to Django 1.7
|
|
^^^^^^^^^^^^^^^^^^^^
|
|
|
|
The biggest change of this release comes in the form of support for Django 1.7.
|
|
Mayan EDMS makes use of several new features of Django 1.7 like: migrations,
|
|
app config and transaction handling. The version of Django supported in this
|
|
version is 1.7.10. With the move to Django 1.7, support for South migrations
|
|
and Python 2.6 is removed. The switch to Django 1.7's app config means that
|
|
the startup order of app should not longer have any relevance, cause any import
|
|
or startup problems.
|
|
|
|
|
|
Frontend UI
|
|
^^^^^^^^^^^
|
|
|
|
The frontend UI HTML has been re-factored to use Bootstrap. Along with this
|
|
update a lot of legacy HTML and CSS was removed, greatly simplifying the
|
|
existing template and allowing the removal of some.
|
|
|
|
|
|
Theming and re-branding
|
|
^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
All the presentation logic and markup has been moved into it's own app, the
|
|
'appearance' app. All modifications required to customize the entire look of
|
|
the Mayan EDMS can now be done in a single app. Very little markup remains
|
|
in the other apps, and it's usually because of necessity, namely the widgets.py
|
|
modules.
|
|
|
|
|
|
Improved page navigation interface
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Previously the document page interface used a fancybox windows leaving the
|
|
current document in the background. This UI workflow as been improved and the
|
|
document page navigation behaves like the rest of the document views.
|
|
|
|
|
|
Menu reorganization
|
|
^^^^^^^^^^^^^^^^^^^
|
|
|
|
To improve user experience, the main menu has been restructured based on
|
|
function usage, moving seldom used buttons inside other views.
|
|
|
|
|
|
Removal of famfam icon set
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
The previously used icon set and icon display code was removed and a new
|
|
system that favor font icon was added.
|
|
|
|
|
|
Document preview generation
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
The image conversion system was re-factored from the ground up and uses a much
|
|
smarted caching system. The document image cache has it's own Django file
|
|
storage driver and no longer default to the system /tmp directory. By moving
|
|
the document image cache to a Django file storage, the cache doesn't need to
|
|
reside in the same filesystem or even computer serving the document images.
|
|
This change also allows nodes in a clustered install to share the document
|
|
image cache.
|
|
|
|
|
|
Document submission for OCR changed to POST
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Previously submitting a document for OCR could be done with a GET request to
|
|
the corresponding URL. This design decision allowed for fast user experience
|
|
but caused massive document submissions when sites were scanned by web spiders.
|
|
The new workflow is to submit documents to the OCR queue only on POST request.
|
|
|
|
|
|
New YAML based settings system
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
The first phase of the new distributed settings system has landed in this
|
|
version. This first change causes settings to be serialized to YAML. This also
|
|
means that it is not possible to pass functions or custom classes as values to
|
|
settings. Setting that related to a class or function, now specify the path to
|
|
those classes or functions and they are imported dynamically at runtime.
|
|
Example::
|
|
|
|
DOCUMENTS_STORAGE_BACKEND = 'storage.backends.filebasedstorage.FileBasedStorage'
|
|
|
|
|
|
Removal of auto admin creation
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
The auto admin user creation code used during new installs has been removed and
|
|
it is its own reusable Django app. The app is available at
|
|
https://pypi.python.org/pypi/django-autoadmin
|
|
|
|
|
|
Removal of dependencies
|
|
^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Through optimizations and code reduction several Python libraries and Django
|
|
app are no longer required. These are:
|
|
|
|
* South
|
|
* GitPython
|
|
* django-pagination
|
|
* psutil
|
|
* python-hkp
|
|
* sendfile
|
|
* slate
|
|
|
|
|
|
ACL system re-factor
|
|
^^^^^^^^^^^^^^^^^^^^
|
|
|
|
The Access Control System has been greatly simplified and optimized. The
|
|
logistics to grant and revoke permissions are now as follows: Only Roles can
|
|
hold permissions, groups and user can no longer on their own be granted a
|
|
permission. Groups are now only organizational units that hold users and Roles
|
|
are collections of groups. User are just a profile and authentication
|
|
information object. So to grant a permission or access to a document to a user,
|
|
grant those permissions to a new or existing role, add the desired user to a
|
|
group and add that group to the role to which you granted the permission. When
|
|
thinking about granting permissions think of it this way:
|
|
|
|
**Permissions -> Roles -> Groups -> User**
|
|
|
|
**Permissions for a document -> Roles -> Groups -> User**
|
|
|
|
**Permissions for a type of document -> Roles -> Groups -> User**
|
|
|
|
|
|
Object access control inheritance
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
A frequently asked feature is the ability to change the access control of a
|
|
group of documents. This feature has been implemented in the form of object
|
|
access control inheritance. This means that if you grant a permission to a role
|
|
for a document type, that role will inherit that permission for all document
|
|
that are later created of that type. If you revoke a permission from a role for
|
|
a document type, that role loses that permission for all documents of that type.
|
|
With this new system changing the access control of individual documents
|
|
should be an edge case. This new ability of modifying the access control of
|
|
document types is the new recommended method.
|
|
|
|
|
|
Removal of anonymous user support
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Allowing anonymous users access to your document repository is no longer
|
|
support. Administrators wanting to make a group of documents public are
|
|
encouraged to create an user, group and role for that purpose.
|
|
|
|
|
|
Metadata validators re-factor
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
The metadata validators have been split into: Validators and Parsers.
|
|
Validators will just check that the input value conforms to certain
|
|
specification, raising a validation error is not and blocking the user from
|
|
submitting data. The Parsers will transform user input and store the result as
|
|
the metadata value.
|
|
|
|
|
|
Trash can support
|
|
^^^^^^^^^^^^^^^^^
|
|
|
|
To avoid accidental data loss, documents are not deleted but moved to a virtual
|
|
trash can. From that trash can documents can them be deleted permanently. The
|
|
deletion document documents and the moving of documents to the trash can are
|
|
governed by two different permissions.
|
|
|
|
|
|
Retention policies
|
|
^^^^^^^^^^^^^^^^^^
|
|
|
|
Support for retention policies was added and is control on a document type basis.
|
|
Two aspects can be controlled: the time at which documents will be
|
|
automatically moved to the trash can and the time after which documents in the
|
|
trash can will be automatically deleted. By default all new document types
|
|
created will have a retention policy that doesn't move documents to the trash
|
|
can and that permanently deletes documents in the trash can after 30 days.
|
|
|
|
|
|
Support to share an index as a FUSE filesystem
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Index mirror has been added after being removed several version ago. This time
|
|
mirroring works by creating a FUSE filesystem that is then mounted anywhere in
|
|
the filesystem. The previous implementation used symbolic links that while
|
|
fast, required constant modification to keep in sync with the indexes structure
|
|
and only worked when the document storage and the index mirror resided in the
|
|
same physical computer or node. This new implementation allowing mirroring of
|
|
indexes even across a network or if the document storage is not a traditional
|
|
filesystem but a remote object store. Since this new FUSE mirroring uses direct
|
|
read access to the database caching is provided and is controlled by the
|
|
``MIRRORING_DOCUMENT_CACHE_LOOKUP_TIMEOUT`` and ``MIRRORING_NODE_CACHE_LOOKUP_TIMEOUT``
|
|
setting options. Both setting have a default of 10 seconds.
|
|
|
|
|
|
Clickable preview images titles
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
To reduce the amount of clicks required to access a document, document previews
|
|
titles are now clickable and will take the user straight to the document view.
|
|
|
|
|
|
Removal of eval
|
|
^^^^^^^^^^^^^^^
|
|
|
|
Use of Python's eval statement has been completely removed. Metadata type
|
|
defaults, lookup fields, smart links and indexes templates now use Django's
|
|
own template language.
|
|
|
|
|
|
Smarter OCR
|
|
^^^^^^^^^^^
|
|
|
|
Document OCR workflow has been improved to try to parse text for each document
|
|
page and in failing to parse text will only perform OCR on that specific page,
|
|
returning to the parsing behavior for the next page. This allowing proper text
|
|
extraction of documents containing both, embedded text and images.
|
|
|
|
|
|
Failure tolerance
|
|
^^^^^^^^^^^^^^^^^
|
|
|
|
Previous versions made use of transactions to prevent data loss in the event of
|
|
an unexpected error. This release improves on that approach by also reacting
|
|
to infrastructure failures. Mayan EDMS can now recover without any or
|
|
minimal data loss from critical events such as loss of connectivity to the
|
|
database manager. This changes allow installation of using database managers
|
|
that do not provide guaranteed concurrency such as SQLite, to scale to thousand
|
|
of documents. While this configuration is still not recommended, Mayan EDMS
|
|
will now work and scale much better in environments where parts of the
|
|
infrastructure cannot be changed (such as the database manager).
|
|
|
|
For more information about this change read the blog post:
|
|
http://blog.robertorosario.com/testing-django-project-infrastructure-failure-tolerance/
|
|
|
|
As a result of this work a new Django app called Django-sabot was created that
|
|
gives Django projects the ability to create unit tests for infrastructure
|
|
failure tolerance: https://pypi.python.org/pypi/django-sabot
|
|
|
|
|
|
RGB tags
|
|
^^^^^^^^
|
|
|
|
Previously tags could only choose from a predetermined number of color. This
|
|
release changes that and tags be of any color. Tags now store the color
|
|
selected in HTML RGB format. Existing tags are automatically converted to this
|
|
new scheme.
|
|
|
|
|
|
Default document type and default document source
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
After installation a default document type and document source are created,
|
|
this means that users can start uploading documents as soon as Mayan EDMS
|
|
is installed without having to do any configuration setting changes. The
|
|
default document type and default document source are both called 'Default'.
|
|
|
|
|
|
Link unbinding
|
|
^^^^^^^^^^^^^^
|
|
|
|
Support for allowing 3rd party apps to unbind links binded by the core apps
|
|
was added to further improve re-branding and customization.
|
|
|
|
|
|
Statistics re-factor
|
|
^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Statistics gathering and generation has been overhauled to allow for the
|
|
creation of scheduled statistics. This allows statistics computation to be
|
|
scheduled during low load times. A new management command was added to
|
|
purge stale or orphan schedules left behind by the editing of statistics
|
|
scheduled. The command is `purgestatistics` and has no parameters.
|
|
|
|
|
|
Apps merge
|
|
^^^^^^^^^^
|
|
|
|
Several app were merge to reduce complexity of the code based on function.
|
|
These are: the `home`, `common`, `project_tools` and `project_setup` apps,
|
|
as well as the `documents` and `document_acls` apps.
|
|
|
|
|
|
New signals
|
|
^^^^^^^^^^^
|
|
|
|
Two new signals are provided to better trigger processing documents at the
|
|
correct moment, these are:
|
|
|
|
* common/perform_upgrade - Launched on the `performupgrade` management command
|
|
to allow 3rd party apps to execute custom upgrade procedures in an unified
|
|
manner.
|
|
* common/post_initial_setup - Launched on the `initialsetup` management command
|
|
to allow for post install initialization or setup.
|
|
* common/post_upgrade - Launched after the `performupgrade` management command
|
|
finishes.
|
|
* documents/post_version_upload = Launched after a new document version is
|
|
uploaded.
|
|
* document/post_document_type_change = Launched after the document type of a
|
|
document is changed.
|
|
* documents/post_document_created = Launched after a document is finally ready
|
|
to be accessed, not when it is created.
|
|
* ocr/post_document_version_ocr - Launched when the OCR of a document version
|
|
has finished.
|
|
|
|
|
|
Test improvements
|
|
^^^^^^^^^^^^^^^^^
|
|
|
|
Instead of a flat tests.py file, each app now has a tests/ directory containing
|
|
tests modules for each particular aspect of an apps, ie: test_models.py,
|
|
test_views.py, test_classes.py. The total number and coverage of tests has been
|
|
greatly increased.
|
|
|
|
|
|
Indexes recalculation
|
|
^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Indexes are now recalculated on when a new document is ready as well as the
|
|
when the metadata of a document changes. This allows indexing documents not
|
|
only based on their metadata but also based on their properties.
|
|
|
|
|
|
Upgrade command
|
|
^^^^^^^^^^^^^^^
|
|
|
|
To reduce the steps and complexity of upgrades, the new ``performupgrade``
|
|
management command was been added. All the upgrade steps will be performed
|
|
by this command.
|
|
|
|
|
|
Admin changes
|
|
^^^^^^^^^^^^^
|
|
|
|
Installation admins are no longer required to have the ``superusers`` or ``staff``
|
|
Django account flags. All setup tasks are now governed by a permission which
|
|
can be assigned to a role.
|
|
|
|
|
|
OCR functions split
|
|
^^^^^^^^^^^^^^^^^^^
|
|
|
|
The textual content of a document as interpreted by the OCR now resides as data
|
|
in the OCR app and not in the Documents app as before. OCR content might
|
|
not be available for all documents after the upgrade and might need to be
|
|
queued again. To help with this situation there is new tool called "OCR all
|
|
documents" for this exact situation.
|
|
|
|
|
|
New internal document creation workflow
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
The new document upload code now returns a document stub while content is
|
|
processing. This allows API users to have the document id of the document
|
|
just uploaded and perform other actions on it while it becomes ready
|
|
for access.
|
|
|
|
|
|
Auto logging
|
|
^^^^^^^^^^^^
|
|
|
|
App logging to the console is now automatically enabled. If Django's ``DEBUG``
|
|
flag is ``True`` the default level for auto logging is ``DEBUG``. If Django's
|
|
``DEBUG`` flag is ``False`` (as in production), the default level changes to
|
|
``INFO``. This should make it easier to add relevant messages to issue tickets
|
|
as well as a adecuate logging during production.
|
|
|
|
|
|
Other changes
|
|
^^^^^^^^^^^^^
|
|
|
|
* Merge of document_print and document_hard_copy views.
|
|
* New class based and menu based navigation system.
|
|
* Re-purpose the installation app.
|
|
* New class based transformations.
|
|
* Usage of Font Awesome icons set.
|
|
* Move document text content display code to the OCR app.
|
|
* Add new permissions ``PERMISSION_OCR_CONTENT_VIEW``.
|
|
* Document type OCR settings move to the OCR app.
|
|
* New dependencies:
|
|
|
|
* PyYAML
|
|
* django-autoadmin
|
|
* django-pure-pagination
|
|
* djangorestframework-recursive
|
|
|
|
* Management command to remove obsolete permissions: ``purgepermissions``.
|
|
* Normalization of 'title' and 'name' fields to 'label'.
|
|
* Improved API, now at version 1.
|
|
* Invert page title/project name order in browser title.
|
|
* Use Django's class based views pagination.
|
|
* Reduction of text strings.
|
|
* OCR all documents.
|
|
* Add tool to OCR all documents of a type.
|
|
* Fix rendering of text files with Unicode characters.
|
|
* Capture body of emails as a text document.
|
|
* All app APIs are top level URLs.
|
|
* CI using gitlab-ci.
|
|
* Coverage report with codecov.io.
|
|
* Thumbnails for documents in trash.
|
|
* Production deployment documentation chapter.
|
|
* Command line to create an initial settings file: ``createsettings``.
|
|
* Initialsetup now continues even is a settings/local.py exists.
|
|
* default_app_config for each app.
|
|
* Natural key support for many models allowing database migrations using dumped data.
|
|
* Separate documentation requirements file to allow for contributor who only want to work on documentation.
|
|
* Centralized testing with a new management command, ``runtests``.
|
|
* Addition of a tox testing configuration.
|
|
* Email test body capture.
|
|
* Email subject and from values storage.
|
|
* Gitlab CI support.
|
|
* Codecov support.
|
|
* Improve text file rendering.
|
|
* Show other packages licenses.
|
|
* Task delay to allow DB replication.
|
|
* Automatic debug logging and info logging during production.
|
|
|
|
|
|
Removals
|
|
--------
|
|
|
|
* Removal of the ``CombinedSource`` class.
|
|
* Removal of default class ACLs.
|
|
* Removal of the ImageMagick and GraphicsMagick converter backends.
|
|
* Remove support for applying roles to new users automatically.
|
|
* Removal of the ``DOCUMENT_RESTRICTIONS_OVERRIDE`` permission.
|
|
* Removed the page_label field.
|
|
* Removal of custom HTTP 505 error view.
|
|
|
|
|
|
Upgrading from a previous version
|
|
---------------------------------
|
|
|
|
Using PIP
|
|
^^^^^^^^^
|
|
|
|
Type in the console::
|
|
|
|
$ pip install -U mayan-edms
|
|
|
|
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.
|
|
|
|
Next upgrade/add the new requirements::
|
|
|
|
$ pip install --upgrade -r requirements.txt
|
|
|
|
|
|
Common steps
|
|
^^^^^^^^^^^^
|
|
|
|
Migrate existing database schema with::
|
|
|
|
$ mayan-edms.py performupgrade
|
|
|
|
During the migration several messages of stale content types can occur:
|
|
|
|
::
|
|
|
|
The following content types are stale and need to be deleted:
|
|
|
|
XX | XX
|
|
|
|
Any objects related to these content types by a foreign key will also
|
|
be deleted. Are you sure you want to delete these content types?
|
|
If you're unsure, answer 'no'.
|
|
|
|
Type 'yes' to continue, or 'no' to cancel:
|
|
|
|
|
|
You can safely answer "yes" to all.
|
|
|
|
Add new static media::
|
|
|
|
$ mayan-edms.py collectstatic --noinput
|
|
|
|
Remove unused dependencies::
|
|
|
|
$ pip uninstall South
|
|
$ pip uninstall GitPython
|
|
$ pip uninstall psutil
|
|
$ pip uninstall python-hkp
|
|
$ pip uninstall django-sendfile
|
|
$ pip uninstall django-pagination
|
|
$ pip uninstall slate
|
|
|
|
The upgrade procedure is now complete.
|
|
|
|
|
|
Backward incompatible changes
|
|
-----------------------------
|
|
|
|
* Current document and document sources transformations will be lost during upgrade.
|
|
* Permissions and Access Controls granted to users and/or groups will be lost during upgrade.
|
|
|
|
|
|
Bugs fixed or issues closed
|
|
---------------------------
|
|
|
|
* :gitlab-issue:`33` Update to Django 1.7
|
|
* :gitlab-issue:`59` New bootstrap based UI
|
|
* :gitlab-issue:`60` Backport class based navigation code from the unstable branch
|
|
* :gitlab-issue:`62` Simplify and reduce code in templates
|
|
* :gitlab-issue:`67` Python 3 compatibility: Update models __unicode__ methdo to __str__ methods (using Django's six library)
|
|
* :gitlab-issue:`121` Twitter Bootstrap theme for Mayan EDMS
|
|
* :gitlab-issue:`155` Header does not fit list on documents/list on small screens (laptop)
|
|
* :gitlab-issue:`170` Remove use of python-hkp
|
|
* :gitlab-issue:`182` Reorganize signal processors
|
|
* :gitlab-issue:`131` error on initialsetup: GPG initialization error
|
|
* :gitlab-issue:`135` Add document indexing filesystem mirroring
|
|
* :gitlab-issue:`141` Merge common and main app
|
|
* :gitlab-issue:`142` New authentication app
|
|
* :gitlab-issue:`145` Convert document tags to user RGB value for code instead of predetermined choices
|
|
* :gitlab-issue:`150` Add 'trash can' support
|
|
* :gitlab-issue:`151` Add support for data retention policies
|
|
* :gitlab-issue:`152` JSON API 500 error
|
|
* :gitlab-issue:`154` /documents API endpoint should return document pk
|
|
* :gitlab-issue:`155` Remove unused document page label field
|
|
* :gitlab-issue:`156` Remove post OCR language cleanup
|
|
* :gitlab-issue:`158` Django REST Swagger not working
|
|
* :gitlab-issue:`159` Error during template rendering on /document/folder/add with non-admin user
|
|
* :gitlab-issue:`160` Add audit logging
|
|
* :gitlab-issue:`163` Removal of the compressed file support
|
|
* :gitlab-issue:`164` Keep fancybox prev & next buttons enabled all the time
|
|
* :gitlab-issue:`167` Add workflow completion number to states
|
|
* :gitlab-issue:`168` Add field to store last error of source during execution
|
|
* :gitlab-issue:`171` tesseract fails with german language (wrong abbreviation)
|
|
* :gitlab-issue:`173` Add post_document_upload signal
|
|
* :gitlab-issue:`174` Bootstrap UI with master branch
|
|
* :gitlab-issue:`176` Replace default email domain
|
|
* :gitlab-issue:`177` Multi page tiff preview is not working
|
|
* :gitlab-issue:`178` Add separate missing optional metadata and missing required metadata tools
|
|
* :gitlab-issue:`181` Move task <-> queue assignment to apps.py
|
|
* :gitlab-issue:`182` Document tags widget is not permissions aware
|
|
* :gitlab-issue:`183` Separate metadata validators into: validators and parsers
|
|
* :gitlab-issue:`184` Move literals in checkouts apps.py and tasks.py to literals.py
|
|
* :gitlab-issue:`186` Scheduled task to delete all document stubs of more than X age.
|
|
* :gitlab-issue:`187` Add tests for multi page tiff files
|
|
* :gitlab-issue:`189` Use transient queues
|
|
* :gitlab-issue:`190` Bump API version number
|
|
* :gitlab-issue:`192` Use local model for document comments
|
|
* :gitlab-issue:`197` Add continuous integration that is compatible with Gitlab
|
|
* :gitlab-issue:`201` Untranslated items
|
|
* :gitlab-issue:`202` AutoAdminSingleton matching query does not exist.
|
|
* :gitlab-issue:`203` KeyError at /sources/upload/document/new/interactive/
|
|
* :gitlab-issue:`204` Problems to add required metadata after changin the document type
|
|
* :gitlab-issue:`216` Add default_app_config value to each app
|
|
* :gitlab-issue:`223` [Documents] Trigger event_document_type_change on the model not on the view
|
|
* :gitlab-issue:`227` decoder zip not available
|
|
* :gitlab-issue:`228` Attribute error when trying to attach a tag for a user with inadequate permissions
|
|
* :gitlab-issue:`229` Attribute error when a user tries to download a document - version 2.0.0b2
|
|
* :gitlab-issue:`230` No option to create new document version even though user given permission in document ACL
|
|
* :gitlab-issue:`231` User shown option to upload new version of a document even though it is blocked by checkout - v2.0.0b2
|
|
* :gitlab-issue:`233` Available users instead of available groups
|
|
* :gitlab-issue:`237` Forcefully checking in a document by a user without adequate permissions throws out an error
|
|
|
|
|
|
.. _PyPI: https://pypi.python.org/pypi/mayan-edms/
|