Merge branch 'release/v0.10'

This commit is contained in:
Roberto Rosario
2011-11-22 18:04:39 -04:00
189 changed files with 5335 additions and 3918 deletions

View File

@@ -120,12 +120,12 @@ trans.es = apps/project_tools/locale/es/LC_MESSAGES/django.po
trans.pt = apps/project_tools/locale/pt/LC_MESSAGES/django.po
trans.ru = apps/project_tools/locale/ru/LC_MESSAGES/django.po
[mayan-edms.apps-grouping]
source_file = apps/grouping/locale/en/LC_MESSAGES/django.po
[mayan-edms.apps-linking]
source_file = apps/linking/locale/en/LC_MESSAGES/django.po
source_lang = en
trans.es = apps/grouping/locale/es/LC_MESSAGES/django.po
trans.pt = apps/grouping/locale/pt/LC_MESSAGES/django.po
trans.ru = apps/grouping/locale/ru/LC_MESSAGES/django.po
trans.es = apps/linking/locale/es/LC_MESSAGES/django.po
trans.pt = apps/linking/locale/pt/LC_MESSAGES/django.po
trans.ru = apps/linking/locale/ru/LC_MESSAGES/django.po
[mayan-edms.apps-document_comments]
source_file = apps/document_comments/locale/en/LC_MESSAGES/django.po

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-09-30 00:54-0400\n"
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -99,67 +99,67 @@ msgstr ""
msgid "Landscape"
msgstr ""
#: utils.py:289
#: utils.py:291
msgid "function found"
msgstr ""
#: utils.py:291 utils.py:293
#: utils.py:293 utils.py:295
#, python-format
msgid "class found: %s"
msgstr ""
#: views.py:23 templates/password_change_done.html:5
#: views.py:24 templates/password_change_done.html:5
msgid "Your password has been successfully changed."
msgstr ""
#: views.py:39
#: views.py:41
msgid "No action selected."
msgstr ""
#: views.py:43
#: views.py:45
msgid "Must select at least one item."
msgstr ""
#: views.py:76
#: views.py:86
#, python-format
msgid "%(selection)s added successfully added to %(right_list_title)s."
msgstr ""
#: views.py:79 views.py:96
#: views.py:89 views.py:106
#, python-format
msgid "Unable to add %(selection)s to %(right_list_title)s."
msgstr ""
#: views.py:93
#: views.py:103
#, python-format
msgid "%(selection)s added successfully removed from %(right_list_title)s."
msgstr ""
#: views.py:111
#: views.py:121
msgid "Add"
msgstr ""
#: views.py:122
#: views.py:132
msgid "Remove"
msgstr ""
#: views.py:145
#: views.py:155
msgid "current user details"
msgstr ""
#: views.py:162
#: views.py:172
msgid "Current user's details updated."
msgstr ""
#: views.py:171
#: views.py:181
msgid "edit current user details"
msgstr ""
#: views.py:197
#: views.py:207
msgid "Changelog"
msgstr ""
#: views.py:210
#: views.py:220
msgid "License"
msgstr ""
@@ -237,25 +237,25 @@ msgstr ""
msgid "Confirm delete"
msgstr ""
#: templates/generic_confirm.html:28
#: templates/generic_confirm.html:32
msgid "form icon"
msgstr ""
#: templates/generic_confirm.html:36
#: templates/generic_confirm.html:40
#, python-format
msgid "Are you sure you wish to delete %(object_name)s: %(object)s?"
msgstr ""
#: templates/generic_confirm.html:38
#: templates/generic_confirm.html:42
#, python-format
msgid "Are you sure you wish to delete: %(object)s?"
msgstr ""
#: templates/generic_confirm.html:46
#: templates/generic_confirm.html:50
msgid "Yes"
msgstr ""
#: templates/generic_confirm.html:50
#: templates/generic_confirm.html:54
msgid "No"
msgstr ""
@@ -268,8 +268,8 @@ msgstr ""
#: templates/generic_form_subtemplate.html:78
#: templates/generic_list_horizontal_subtemplate.html:51
#: templates/generic_list_horizontal_subtemplate.html:178
#: templates/generic_list_subtemplate.html:51
#: templates/generic_list_subtemplate.html:171
#: templates/generic_list_subtemplate.html:52
#: templates/generic_list_subtemplate.html:178
msgid "Save"
msgstr ""
@@ -277,22 +277,18 @@ msgstr ""
#: templates/generic_form_subtemplate.html:78
#: templates/generic_list_horizontal_subtemplate.html:51
#: templates/generic_list_horizontal_subtemplate.html:178
#: templates/generic_list_subtemplate.html:51
#: templates/generic_list_subtemplate.html:171
#: templates/generic_list_subtemplate.html:52
#: templates/generic_list_subtemplate.html:178
msgid "Submit"
msgstr ""
#: templates/generic_form_subtemplate.html:82
msgid "Cancel"
msgstr ""
#: templates/generic_list.html:6 templates/generic_list_horizontal.html:6
#, python-format
msgid "List of %(stripped_title)s"
msgstr ""
#: templates/generic_list_horizontal_subtemplate.html:23
#: templates/generic_list_subtemplate.html:23
#: templates/generic_list_subtemplate.html:24
#, python-format
msgid ""
"List of %(title)s (%(start)s - %(end)s out of %(total)s) (Page "
@@ -300,18 +296,16 @@ msgid ""
msgstr ""
#: templates/generic_list_horizontal_subtemplate.html:25
#: templates/generic_list_subtemplate.html:25
#: templates/generic_list_subtemplate.html:26
#, python-format
msgid "List of %(title)s (%(total)s)"
msgstr ""
#: templates/generic_list_horizontal_subtemplate.html:72
#: templates/generic_list_subtemplate.html:71
#: templates/generic_list_subtemplate.html:72
msgid "Identifier"
msgstr ""
#: templates/generic_list_horizontal_subtemplate.html:146
#: templates/generic_list_subtemplate.html:145
#: templates/generic_list_subtemplate.html:152
#, python-format
msgid "There are no %(stripped_title)s"
msgstr ""

View File

@@ -1,21 +1,22 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
#
# Translators:
# Roberto Rosario <roberto.rosario.gonzalez@gmail.com>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
"POT-Creation-Date: 2011-09-30 00:54-0400\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
"PO-Revision-Date: 2011-11-04 00:58+0000\n"
"Last-Translator: rosarior <roberto.rosario.gonzalez@gmail.com>\n"
"Language-Team: Spanish (Castilian) (http://www.transifex.net/projects/p/mayan-edms/team/es/)\n"
"Language-Team: Spanish (Castilian) (http://www.transifex.net/projects/p/"
"mayan-edms/team/es/)\n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: es\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
#: __init__.py:17
@@ -103,67 +104,67 @@ msgstr "Retrato"
msgid "Landscape"
msgstr "Paisaje"
#: utils.py:289
#: utils.py:291
msgid "function found"
msgstr "función encontrada"
#: utils.py:291 utils.py:293
#: utils.py:293 utils.py:295
#, python-format
msgid "class found: %s"
msgstr "clase encontrada: %s"
#: views.py:23 templates/password_change_done.html:5
#: views.py:24 templates/password_change_done.html:5
msgid "Your password has been successfully changed."
msgstr "Su contraseña se ha modificado correctamente."
#: views.py:39
#: views.py:41
msgid "No action selected."
msgstr "Ninguna acción seleccionada."
#: views.py:43
#: views.py:45
msgid "Must select at least one item."
msgstr "Debe seleccionar al menos un artículo."
#: views.py:76
#: views.py:86
#, python-format
msgid "%(selection)s added successfully added to %(right_list_title)s."
msgstr "Se agrego exitosamente %(selection)s a %(right_list_title)s."
#: views.py:79 views.py:96
#: views.py:89 views.py:106
#, python-format
msgid "Unable to add %(selection)s to %(right_list_title)s."
msgstr "No se puede agregar %(selection)s a %(right_list_title)s."
#: views.py:93
#: views.py:103
#, python-format
msgid "%(selection)s added successfully removed from %(right_list_title)s."
msgstr "Se removió exitosamente %(selection)s de %(right_list_title)s."
#: views.py:111
#: views.py:121
msgid "Add"
msgstr "Agregar"
#: views.py:122
#: views.py:132
msgid "Remove"
msgstr "Remover"
#: views.py:145
#: views.py:155
msgid "current user details"
msgstr "detalles del usuario corriente"
#: views.py:162
#: views.py:172
msgid "Current user's details updated."
msgstr "Datos del usuario corriente actualizados."
#: views.py:171
#: views.py:181
msgid "edit current user details"
msgstr "editar detalles del usuario corriente"
#: views.py:197
#: views.py:207
msgid "Changelog"
msgstr "Cambios"
#: views.py:210
#: views.py:220
msgid "License"
msgstr "Licencia"
@@ -174,8 +175,8 @@ msgstr "Ninguno"
#: conf/settings.py:15
msgid ""
"Temporary directory used site wide to store thumbnails, previews and "
"temporary files. If none is specified, one will be created using "
"tempfile.mkdtemp()"
"temporary files. If none is specified, one will be created using tempfile."
"mkdtemp()"
msgstr ""
"Directorio temporal utilizado por todo el sitio para almacenar imágenes en "
"miniatura, vistas previas y los archivos temporales. Si no se especifica "
@@ -246,25 +247,25 @@ msgstr "Confirmar"
msgid "Confirm delete"
msgstr "Confirmar eliminación"
#: templates/generic_confirm.html:28
#: templates/generic_confirm.html:32
msgid "form icon"
msgstr "emblema de la forma"
#: templates/generic_confirm.html:36
#: templates/generic_confirm.html:40
#, python-format
msgid "Are you sure you wish to delete %(object_name)s: %(object)s?"
msgstr "¿Está seguro que desea eliminar %(object_name)s: %(object)s?"
#: templates/generic_confirm.html:38
#: templates/generic_confirm.html:42
#, python-format
msgid "Are you sure you wish to delete: %(object)s?"
msgstr "¿Está seguro que desea eliminar: %(object)s?"
#: templates/generic_confirm.html:46
#: templates/generic_confirm.html:50
msgid "Yes"
msgstr "Sí"
#: templates/generic_confirm.html:50
#: templates/generic_confirm.html:54
msgid "No"
msgstr "No"
@@ -277,8 +278,8 @@ msgstr "requerido"
#: templates/generic_form_subtemplate.html:78
#: templates/generic_list_horizontal_subtemplate.html:51
#: templates/generic_list_horizontal_subtemplate.html:178
#: templates/generic_list_subtemplate.html:51
#: templates/generic_list_subtemplate.html:171
#: templates/generic_list_subtemplate.html:52
#: templates/generic_list_subtemplate.html:178
msgid "Save"
msgstr "Guardar"
@@ -286,22 +287,18 @@ msgstr "Guardar"
#: templates/generic_form_subtemplate.html:78
#: templates/generic_list_horizontal_subtemplate.html:51
#: templates/generic_list_horizontal_subtemplate.html:178
#: templates/generic_list_subtemplate.html:51
#: templates/generic_list_subtemplate.html:171
#: templates/generic_list_subtemplate.html:52
#: templates/generic_list_subtemplate.html:178
msgid "Submit"
msgstr "Enviar"
#: templates/generic_form_subtemplate.html:82
msgid "Cancel"
msgstr "Cancelar"
#: templates/generic_list.html:6 templates/generic_list_horizontal.html:6
#, python-format
msgid "List of %(stripped_title)s"
msgstr "Lista de %(stripped_title)s "
#: templates/generic_list_horizontal_subtemplate.html:23
#: templates/generic_list_subtemplate.html:23
#: templates/generic_list_subtemplate.html:24
#, python-format
msgid ""
"List of %(title)s (%(start)s - %(end)s out of %(total)s) (Page "
@@ -311,18 +308,16 @@ msgstr ""
"%(page_number)s de %(total_pages)s)"
#: templates/generic_list_horizontal_subtemplate.html:25
#: templates/generic_list_subtemplate.html:25
#: templates/generic_list_subtemplate.html:26
#, python-format
msgid "List of %(title)s (%(total)s)"
msgstr "Lista de %(title)s (%(total)s)"
#: templates/generic_list_horizontal_subtemplate.html:72
#: templates/generic_list_subtemplate.html:71
#: templates/generic_list_subtemplate.html:72
msgid "Identifier"
msgstr "Identificador"
#: templates/generic_list_horizontal_subtemplate.html:146
#: templates/generic_list_subtemplate.html:145
#: templates/generic_list_subtemplate.html:152
#, python-format
msgid "There are no %(stripped_title)s"
msgstr "No hay %(stripped_title)s "
@@ -336,4 +331,5 @@ msgstr "Iniciar sesión"
msgid "Password change"
msgstr "Cambio de contraseña"
#~ msgid "Cancel"
#~ msgstr "Cancelar"

View File

@@ -1,21 +1,22 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
#
# Translators:
# <dev.emerson@gmail.com>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
"POT-Creation-Date: 2011-09-30 00:54-0400\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
"PO-Revision-Date: 2011-11-02 02:18+0000\n"
"Last-Translator: emersonsoares <dev.emerson@gmail.com>\n"
"Language-Team: Portuguese (http://www.transifex.net/projects/p/mayan-edms/team/pt/)\n"
"Language-Team: Portuguese (http://www.transifex.net/projects/p/mayan-edms/"
"team/pt/)\n"
"Language: pt\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: pt\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
#: __init__.py:17
@@ -102,68 +103,67 @@ msgstr "Retrato"
msgid "Landscape"
msgstr "Paisagem"
#: utils.py:289
#: utils.py:291
msgid "function found"
msgstr "função encontrada"
#: utils.py:291 utils.py:293
#: utils.py:293 utils.py:295
#, python-format
msgid "class found: %s"
msgstr "classe encontrada: %s"
#: views.py:23 templates/password_change_done.html:5
#: views.py:24 templates/password_change_done.html:5
msgid "Your password has been successfully changed."
msgstr "Sua senha foi alterada com êxito."
#: views.py:39
#: views.py:41
msgid "No action selected."
msgstr "Nenhuma ação selecionada."
#: views.py:43
#: views.py:45
msgid "Must select at least one item."
msgstr "Deve selecionar pelo menos um item."
#: views.py:76
#: views.py:86
#, python-format
msgid "%(selection)s added successfully added to %(right_list_title)s."
msgstr "%(selection)s adicionadas com sucesso a %(right_list_title)s ."
#: views.py:79 views.py:96
#: views.py:89 views.py:106
#, python-format
msgid "Unable to add %(selection)s to %(right_list_title)s."
msgstr "Não foi possível adicionar %(selection)s para %(right_list_title)s ."
#: views.py:93
#: views.py:103
#, python-format
msgid "%(selection)s added successfully removed from %(right_list_title)s."
msgstr ""
" %(selection)s adicionado com sucesso removidos %(right_list_title)s."
msgstr " %(selection)s adicionado com sucesso removidos %(right_list_title)s."
#: views.py:111
#: views.py:121
msgid "Add"
msgstr "Adicionar"
#: views.py:122
#: views.py:132
msgid "Remove"
msgstr "Remover"
#: views.py:145
#: views.py:155
msgid "current user details"
msgstr "detalhes atuais do usuário"
#: views.py:162
#: views.py:172
msgid "Current user's details updated."
msgstr "Detalhes do usuário atual atualizados."
#: views.py:171
#: views.py:181
msgid "edit current user details"
msgstr "editar os detalhes do usuário atual"
#: views.py:197
#: views.py:207
msgid "Changelog"
msgstr "Log de alterações"
#: views.py:210
#: views.py:220
msgid "License"
msgstr "Licença"
@@ -174,12 +174,12 @@ msgstr "Nenhum"
#: conf/settings.py:15
msgid ""
"Temporary directory used site wide to store thumbnails, previews and "
"temporary files. If none is specified, one will be created using "
"tempfile.mkdtemp()"
"temporary files. If none is specified, one will be created using tempfile."
"mkdtemp()"
msgstr ""
"Diretório temporário usado para armazenar miniaturas, previews e arquivos "
"temporários. Se nenhum for especificado, um será criado usando "
"tempfile.mkdtemp()"
"temporários. Se nenhum for especificado, um será criado usando tempfile."
"mkdtemp()"
#: conf/settings.py:65
msgid ""
@@ -246,25 +246,25 @@ msgstr "Confirmar"
msgid "Confirm delete"
msgstr "Confirmar exclusão"
#: templates/generic_confirm.html:28
#: templates/generic_confirm.html:32
msgid "form icon"
msgstr "ícone de formulário"
#: templates/generic_confirm.html:36
#: templates/generic_confirm.html:40
#, python-format
msgid "Are you sure you wish to delete %(object_name)s: %(object)s?"
msgstr "Tem certeza de que deseja excluir %(object_name)s: %(object)s ?"
#: templates/generic_confirm.html:38
#: templates/generic_confirm.html:42
#, python-format
msgid "Are you sure you wish to delete: %(object)s?"
msgstr "Tem certeza de que deseja excluir: %(object)s ?"
#: templates/generic_confirm.html:46
#: templates/generic_confirm.html:50
msgid "Yes"
msgstr "Sim"
#: templates/generic_confirm.html:50
#: templates/generic_confirm.html:54
msgid "No"
msgstr "Não"
@@ -277,8 +277,8 @@ msgstr "exigido"
#: templates/generic_form_subtemplate.html:78
#: templates/generic_list_horizontal_subtemplate.html:51
#: templates/generic_list_horizontal_subtemplate.html:178
#: templates/generic_list_subtemplate.html:51
#: templates/generic_list_subtemplate.html:171
#: templates/generic_list_subtemplate.html:52
#: templates/generic_list_subtemplate.html:178
msgid "Save"
msgstr "Salvar"
@@ -286,22 +286,18 @@ msgstr "Salvar"
#: templates/generic_form_subtemplate.html:78
#: templates/generic_list_horizontal_subtemplate.html:51
#: templates/generic_list_horizontal_subtemplate.html:178
#: templates/generic_list_subtemplate.html:51
#: templates/generic_list_subtemplate.html:171
#: templates/generic_list_subtemplate.html:52
#: templates/generic_list_subtemplate.html:178
msgid "Submit"
msgstr "Submeter"
#: templates/generic_form_subtemplate.html:82
msgid "Cancel"
msgstr "Cancelar"
#: templates/generic_list.html:6 templates/generic_list_horizontal.html:6
#, python-format
msgid "List of %(stripped_title)s"
msgstr "Lista de %(stripped_title)s "
#: templates/generic_list_horizontal_subtemplate.html:23
#: templates/generic_list_subtemplate.html:23
#: templates/generic_list_subtemplate.html:24
#, python-format
msgid ""
"List of %(title)s (%(start)s - %(end)s out of %(total)s) (Page "
@@ -311,18 +307,16 @@ msgstr ""
"of %(total_pages)s)"
#: templates/generic_list_horizontal_subtemplate.html:25
#: templates/generic_list_subtemplate.html:25
#: templates/generic_list_subtemplate.html:26
#, python-format
msgid "List of %(title)s (%(total)s)"
msgstr "Lista de %(title)s (%(total)s)"
#: templates/generic_list_horizontal_subtemplate.html:72
#: templates/generic_list_subtemplate.html:71
#: templates/generic_list_subtemplate.html:72
msgid "Identifier"
msgstr "Identificador"
#: templates/generic_list_horizontal_subtemplate.html:146
#: templates/generic_list_subtemplate.html:145
#: templates/generic_list_subtemplate.html:152
#, python-format
msgid "There are no %(stripped_title)s"
msgstr "Não há %(stripped_title)s "
@@ -336,4 +330,5 @@ msgstr "Login"
msgid "Password change"
msgstr "Alterar a senha"
#~ msgid "Cancel"
#~ msgstr "Cancelar"

View File

@@ -8,8 +8,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
"POT-Creation-Date: 2011-09-30 00:54-0400\n"
"PO-Revision-Date: 2011-11-04 10:27+0000\n"
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
"PO-Revision-Date: 2011-11-22 19:21+0000\n"
"Last-Translator: gsv70 <gsv70@mail.ru>\n"
"Language-Team: Russian (http://www.transifex.net/projects/p/mayan-edms/team/ru/)\n"
"MIME-Version: 1.0\n"
@@ -32,7 +32,7 @@ msgstr "изменение сведений"
#: __init__.py:23 __init__.py:29
msgid "about"
msgstr "о"
msgstr "инфо"
#: __init__.py:24
msgid "changelog"
@@ -102,67 +102,67 @@ msgstr "Портрет"
msgid "Landscape"
msgstr "Пейзаж"
#: utils.py:289
#: utils.py:291
msgid "function found"
msgstr "Функция найдены"
msgstr "функция найдена"
#: utils.py:291 utils.py:293
#: utils.py:293 utils.py:295
#, python-format
msgid "class found: %s"
msgstr "Класс найден: %s."
msgstr "класс найден: %s."
#: views.py:23 templates/password_change_done.html:5
#: views.py:24 templates/password_change_done.html:5
msgid "Your password has been successfully changed."
msgstr "Ваш пароль был успешно изменен."
msgstr "Ваш пароль был изменен."
#: views.py:39
#: views.py:41
msgid "No action selected."
msgstr "Никаких действий не выбрано."
#: views.py:43
#: views.py:45
msgid "Must select at least one item."
msgstr "Необходимо выбрать хотя бы один элемент."
#: views.py:76
#: views.py:86
#, python-format
msgid "%(selection)s added successfully added to %(right_list_title)s."
msgstr "%(selection)s успешно добавлен в %(right_list_title)s ."
#: views.py:79 views.py:96
#: views.py:89 views.py:106
#, python-format
msgid "Unable to add %(selection)s to %(right_list_title)s."
msgstr "Не удалось добавить %(selection)s до %(right_list_title)s ."
#: views.py:93
#: views.py:103
#, python-format
msgid "%(selection)s added successfully removed from %(right_list_title)s."
msgstr "%(selection)s успешно удален из %(right_list_title)s ."
#: views.py:111
#: views.py:121
msgid "Add"
msgstr "Добавить"
#: views.py:122
#: views.py:132
msgid "Remove"
msgstr "Удалить"
#: views.py:145
#: views.py:155
msgid "current user details"
msgstr "данные пользователя"
#: views.py:162
#: views.py:172
msgid "Current user's details updated."
msgstr "Данные пользователя обновлены."
#: views.py:171
#: views.py:181
msgid "edit current user details"
msgstr "редактировать данные пользователя"
#: views.py:197
#: views.py:207
msgid "Changelog"
msgstr "Изменения"
#: views.py:210
#: views.py:220
msgid "License"
msgstr "Лицензия"
@@ -194,7 +194,7 @@ msgstr "Недостаточно прав"
#: templates/403.html:9
msgid "You don't have enough permissions for this operation."
msgstr "У вас нет достаточно прав для этой операции."
msgstr "У вас недостаточно прав для этой операции."
#: templates/404.html:3 templates/404.html.py:7
msgid "Page not found"
@@ -230,7 +230,7 @@ msgstr "Создать %(object_name)s"
#: templates/calculate_form_title.html:26
msgid "Create"
msgstr "Создавать"
msgstr "Создать"
#: templates/generic_assign_remove.html:3
#, python-format
@@ -245,25 +245,25 @@ msgstr "Подтверждать"
msgid "Confirm delete"
msgstr "Подтвердить удаление"
#: templates/generic_confirm.html:28
#: templates/generic_confirm.html:32
msgid "form icon"
msgstr "значок формы"
#: templates/generic_confirm.html:36
#: templates/generic_confirm.html:40
#, python-format
msgid "Are you sure you wish to delete %(object_name)s: %(object)s?"
msgstr "Вы действительно хотите удалить %(object_name)s: %(object)s?"
#: templates/generic_confirm.html:38
#: templates/generic_confirm.html:42
#, python-format
msgid "Are you sure you wish to delete: %(object)s?"
msgstr "Вы действительно хотите удалить: %(object)s?"
#: templates/generic_confirm.html:46
#: templates/generic_confirm.html:50
msgid "Yes"
msgstr "Да"
#: templates/generic_confirm.html:50
#: templates/generic_confirm.html:54
msgid "No"
msgstr "Нет"
@@ -276,8 +276,8 @@ msgstr "требуется"
#: templates/generic_form_subtemplate.html:78
#: templates/generic_list_horizontal_subtemplate.html:51
#: templates/generic_list_horizontal_subtemplate.html:178
#: templates/generic_list_subtemplate.html:51
#: templates/generic_list_subtemplate.html:171
#: templates/generic_list_subtemplate.html:52
#: templates/generic_list_subtemplate.html:178
msgid "Save"
msgstr "Сохранить"
@@ -285,22 +285,18 @@ msgstr "Сохранить"
#: templates/generic_form_subtemplate.html:78
#: templates/generic_list_horizontal_subtemplate.html:51
#: templates/generic_list_horizontal_subtemplate.html:178
#: templates/generic_list_subtemplate.html:51
#: templates/generic_list_subtemplate.html:171
#: templates/generic_list_subtemplate.html:52
#: templates/generic_list_subtemplate.html:178
msgid "Submit"
msgstr "Выполнить"
#: templates/generic_form_subtemplate.html:82
msgid "Cancel"
msgstr "Отменить"
#: templates/generic_list.html:6 templates/generic_list_horizontal.html:6
#, python-format
msgid "List of %(stripped_title)s"
msgstr "Список %(stripped_title)s"
msgstr "Список \"%(stripped_title)s\""
#: templates/generic_list_horizontal_subtemplate.html:23
#: templates/generic_list_subtemplate.html:23
#: templates/generic_list_subtemplate.html:24
#, python-format
msgid ""
"List of %(title)s (%(start)s - %(end)s out of %(total)s) (Page "
@@ -310,18 +306,16 @@ msgstr ""
" %(total_pages)s)"
#: templates/generic_list_horizontal_subtemplate.html:25
#: templates/generic_list_subtemplate.html:25
#: templates/generic_list_subtemplate.html:26
#, python-format
msgid "List of %(title)s (%(total)s)"
msgstr "Список %(title)s (%(total)s)"
#: templates/generic_list_horizontal_subtemplate.html:72
#: templates/generic_list_subtemplate.html:71
#: templates/generic_list_subtemplate.html:72
msgid "Identifier"
msgstr "Идентификатор"
#: templates/generic_list_horizontal_subtemplate.html:146
#: templates/generic_list_subtemplate.html:145
#: templates/generic_list_subtemplate.html:152
#, python-format
msgid "There are no %(stripped_title)s"
msgstr "Нет %(stripped_title)s"

View File

@@ -22,7 +22,11 @@
<form action="" method="post" class="form login">{% csrf_token %}
{% if next %}
<input name="next" type="hidden" value="{{ next }}" />
{% endif %}
{% endif %}
{% if previous %}
<input name="previous" type="hidden" value="{{ previous }}" />
{% endif %}
<div style="float: left; margin-right: 10px;">
<img style="margin-top: 12px;" src="{{ STATIC_URL }}images/icons/{{ form_icon|default:'question.png' }}" alt="{% trans 'form icon' %}" />

View File

@@ -3,6 +3,8 @@ import os
import re
import types
import tempfile
import string
import random
from django.utils.http import urlquote as django_urlquote
from django.utils.http import urlencode as django_urlencode
@@ -358,8 +360,13 @@ def validate_path(path):
return True
def encapsulate(function):
# Workaround Django ticket 15791
# Changeset 16045
# http://stackoverflow.com/questions/6861601/cannot-resolve-callable-context-variable/6955045#6955045
return lambda: function
def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
return ''.join(random.choice(chars) for x in range(size))

View File

@@ -4,8 +4,6 @@ import hashlib
from common.conf.settings import TEMPORARY_DIRECTORY
from converter.conf.settings import UNOCONV_PATH
from converter.exceptions import OfficeConversionError
from converter.literals import DEFAULT_PAGE_NUMBER, \
DEFAULT_ZOOM_LEVEL, DEFAULT_ROTATION, DEFAULT_FILE_FORMAT
@@ -16,28 +14,12 @@ from converter.literals import TRANSFORMATION_RESIZE, \
from converter.literals import DIMENSION_SEPARATOR
from converter.literals import FILE_FORMATS
from converter.utils import cleanup
from converter.runtime import office_converter
from converter.exceptions import OfficeConversionError
HASH_FUNCTION = lambda x: hashlib.sha256(x).hexdigest()
CONVERTER_OFFICE_FILE_EXTENSIONS = [
u'ods', u'docx', u'doc'
]
def execute_unoconv(input_filepath, arguments=''):
"""
Executes the program unoconv using subprocess's Popen
"""
command = []
command.append(UNOCONV_PATH)
command.extend(unicode(arguments).split())
command.append(input_filepath)
proc = subprocess.Popen(command, close_fds=True, stderr=subprocess.PIPE)
return_code = proc.wait()
if return_code != 0:
raise OfficeConversionError(proc.stderr.readline())
def cache_cleanup(input_filepath, *args, **kwargs):
try:
os.remove(create_image_cache_filename(input_filepath, *args, **kwargs))
@@ -53,37 +35,35 @@ def create_image_cache_filename(input_filepath, *args, **kwargs):
return None
def convert_office_document(input_filepath):
if os.path.exists(UNOCONV_PATH):
execute_unoconv(input_filepath, arguments='-f pdf')
return input_filepath + u'.pdf'
return None
def convert(input_filepath, output_filepath=None, cleanup_files=False, *args, **kwargs):
def convert(input_filepath, output_filepath=None, cleanup_files=False, mimetype=None, *args, **kwargs):
size = kwargs.get('size')
file_format = kwargs.get('file_format', DEFAULT_FILE_FORMAT)
zoom = kwargs.get('zoom', DEFAULT_ZOOM_LEVEL)
rotation = kwargs.get('rotation', DEFAULT_ROTATION)
page = kwargs.get('page', DEFAULT_PAGE_NUMBER)
transformations = kwargs.get('transformations', [])
if transformations is None:
transformations = []
unoconv_output = None
if output_filepath is None:
output_filepath = create_image_cache_filename(input_filepath, *args, **kwargs)
if os.path.exists(output_filepath):
return output_filepath
path, extension = os.path.splitext(input_filepath)
if extension[1:].lower() in CONVERTER_OFFICE_FILE_EXTENSIONS:
result = convert_office_document(input_filepath)
if result:
unoconv_output = result
input_filepath = result
if office_converter:
try:
office_converter.convert(input_filepath, mimetype=mimetype)
if office_converter.exists:
input_filepath = office_converter.output_filepath
mimetype = 'application/pdf'
else:
# Recycle the already detected mimetype
mimetype = office_converter.mimetype
except OfficeConversionError:
raise UnknownFileFormat('office converter exception')
if size:
transformations.append(
@@ -110,17 +90,24 @@ def convert(input_filepath, output_filepath=None, cleanup_files=False, *args, **
)
try:
backend.convert_file(input_filepath=input_filepath, output_filepath=output_filepath, transformations=transformations, page=page, file_format=file_format)
backend.convert_file(input_filepath=input_filepath, output_filepath=output_filepath, transformations=transformations, page=page, file_format=file_format, mimetype=mimetype)
finally:
if cleanup_files:
cleanup(input_filepath)
if unoconv_output:
cleanup(unoconv_output)
return output_filepath
def get_page_count(input_filepath):
if office_converter:
try:
office_converter.convert(input_filepath)
if office_converter.exists:
input_filepath = office_converter.output_filepath
except OfficeConversionError:
raise UnknownFileFormat('office converter exception')
return backend.get_page_count(input_filepath)

View File

@@ -29,7 +29,7 @@ class ConverterClass(ConverterBase):
raise IdentifyError(proc.stderr.readline())
return proc.stdout.read()
def convert_file(self, input_filepath, output_filepath, transformations=None, page=DEFAULT_PAGE_NUMBER, file_format=DEFAULT_FILE_FORMAT):
def convert_file(self, input_filepath, output_filepath, transformations=None, page=DEFAULT_PAGE_NUMBER, file_format=DEFAULT_FILE_FORMAT, **kwargs):
arguments = []
try:

View File

@@ -29,7 +29,7 @@ class ConverterClass(ConverterBase):
raise IdentifyError(proc.stderr.readline())
return proc.stdout.read()
def convert_file(self, input_filepath, output_filepath, transformations=None, page=DEFAULT_PAGE_NUMBER, file_format=DEFAULT_FILE_FORMAT):
def convert_file(self, input_filepath, output_filepath, transformations=None, page=DEFAULT_PAGE_NUMBER, file_format=DEFAULT_FILE_FORMAT, **kwargs):
arguments = []
try:
if transformations:

View File

@@ -25,7 +25,7 @@ class ConverterClass(ConverterBase):
def get_page_count(self, input_filepath):
page_count = 1
mimetype, encoding = get_mimetype(open(input_filepath, 'rb'), input_filepath)
mimetype, encoding = get_mimetype(open(input_filepath, 'rb'), input_filepath, mimetype_only=True)
if mimetype == 'application/pdf':
# If file is a PDF open it with slate to determine the page
# count
@@ -48,9 +48,12 @@ class ConverterClass(ConverterBase):
return page_count
def convert_file(self, input_filepath, output_filepath, transformations=None, page=DEFAULT_PAGE_NUMBER, file_format=DEFAULT_FILE_FORMAT):
def convert_file(self, input_filepath, output_filepath, transformations=None, page=DEFAULT_PAGE_NUMBER, file_format=DEFAULT_FILE_FORMAT, **kwargs):
tmpfile = None
mimetype, encoding = get_mimetype(open(input_filepath, 'rb'), input_filepath)
mimetype = kwargs.get('mimetype', None)
if not mimetype:
mimetype, encoding = get_mimetype(open(input_filepath, 'rb'), input_filepath, mimetype_only=True)
if mimetype == 'application/pdf' and USE_GHOSTSCRIPT:
# If file is a PDF open it with ghostscript and convert it to
# TIFF
@@ -64,7 +67,7 @@ class ConverterClass(ConverterBase):
'gs', '-q', '-dQUIET', '-dSAFER', '-dBATCH',
'-dNOPAUSE', '-dNOPROMPT',
first_page_tmpl, last_page_tmpl,
'-sDEVICE=jpeg', '-dJPEGQ=75',
'-sDEVICE=jpeg', '-dJPEGQ=95',
'-r150', output_file_tmpl,
input_file_tmpl,
'-c "60000000 setvmthreshold"', # use 30MB

View File

@@ -1,4 +1,5 @@
"""Configuration options for the converter app"""
'''Configuration options for the converter app'''
from django.utils.translation import ugettext_lazy as _
from smart_settings.api import register_settings
@@ -12,7 +13,9 @@ register_settings(
{'name': u'GM_PATH', 'global_name': u'CONVERTER_GM_PATH', 'default': u'/usr/bin/gm', 'description': _(u'File path to graphicsmagick\'s program.'), 'exists': True},
{'name': u'GM_SETTINGS', 'global_name': u'CONVERTER_GM_SETTINGS', 'default': u''},
{'name': u'GRAPHICS_BACKEND', 'global_name': u'CONVERTER_GRAPHICS_BACKEND', 'default': u'converter.backends.python', 'description': _(u'Graphics conversion backend to use. Options are: converter.backends.imagemagick, converter.backends.graphicsmagick and converter.backends.python.')},
{'name': u'UNOCONV_PATH', 'global_name': u'CONVERTER_UNOCONV_PATH', 'default': u'/usr/bin/unoconv', 'exists': True},
{'name': u'UNOCONV_PATH', 'global_name': u'CONVERTER_UNOCONV_PATH', 'default': u'/usr/bin/unoconv', 'exists': True, 'description': _(u'Path to the unoconv program.')},
{'name': u'UNOCONV_USE_PIPE', 'global_name': u'CONVERTER_UNOCONV_USE_PIPE', 'default': True, 'description': _(u'Use alternate method of connection to LibreOffice using a pipe, it is slower but less prone to segmentation faults.')},
#{'name': u'OCR_OPTIONS', 'global_name': u'CONVERTER_OCR_OPTIONS', 'default': u'-colorspace Gray -depth 8 -resample 200x200'},
#{'name': u'HIGH_QUALITY_OPTIONS', 'global_name': u'CONVERTER_HIGH_QUALITY_OPTIONS', 'default': u'-density 400'},
#{'name': u'PRINT_QUALITY_OPTIONS', 'global_name': u'CONVERTER_PRINT_QUALITY_OPTIONS', 'default': u'-density 500'},

View File

@@ -29,3 +29,7 @@ class UnkownConvertError(ConvertError):
class OfficeConversionError(ConvertError):
pass
class OfficeBackendError(OfficeConversionError):
pass

View File

@@ -5,6 +5,7 @@ DEFAULT_ZOOM_LEVEL = 100
DEFAULT_ROTATION = 0
DEFAULT_PAGE_NUMBER = 1
DEFAULT_FILE_FORMAT = u'jpeg'
DEFAULT_FILE_FORMAT_MIMETYPE = u'image/jpeg'
DIMENSION_SEPARATOR = u'x'

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,113 @@
import os
import subprocess
import logging
from mimetype.api import get_mimetype
from common.conf.settings import TEMPORARY_DIRECTORY
from common.utils import id_generator
from converter.conf.settings import UNOCONV_PATH, UNOCONV_USE_PIPE
from converter.exceptions import (OfficeConversionError,
OfficeBackendError, UnknownFileFormat)
CACHED_FILE_SUFFIX = u'_office_converter'
CONVERTER_OFFICE_FILE_MIMETYPES = [
'application/msword',
'application/mswrite',
'application/mspowerpoint',
'application/msexcel',
'application/vnd.ms-excel',
'application/vnd.ms-powerpoint',
'text/plain',
'application/vnd.oasis.opendocument.presentation',
'application/vnd.oasis.opendocument.text',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/vnd.oasis.opendocument.spreadsheet',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'application/vnd.oasis.opendocument.graphics',
]
logger = logging.getLogger(__name__)
class OfficeConverter(object):
def __init__(self):
self.backend_class = OfficeConverterBackendUnoconv
self.backend = self.backend_class()
self.exists = False
self.mimetype = None
self.encoding = None
def mimetypes(self):
return CONVERTER_OFFICE_FILE_MIMETYPES
def convert(self, input_filepath, mimetype=None):
self.exists = False
self.mimetype = None
self.encoding = None
self.input_filepath = input_filepath
# Make sure file is of a known office format
if mimetype:
self.mimetype = mimetype
else:
self.mimetype, self.encoding = get_mimetype(open(self.input_filepath), self.input_filepath, mimetype_only=True)
if self.mimetype in CONVERTER_OFFICE_FILE_MIMETYPES:
# Cache results of conversion
self.output_filepath = os.path.join(TEMPORARY_DIRECTORY, u''.join([self.input_filepath, CACHED_FILE_SUFFIX]))
self.exists = os.path.exists(self.output_filepath)
if not self.exists:
try:
self.backend.convert(self.input_filepath, self.output_filepath)
self.exists = True
except OfficeBackendError, msg:
# convert exception so that at least the mime type icon is displayed
raise UnknownFileFormat(msg)
def __unicode__(self):
return getattr(self, 'output_filepath', None)
def __str__(self):
return str(self.__unicode__())
class OfficeConverterBackendUnoconv(object):
def __init__(self):
self.unoconv_path = UNOCONV_PATH if UNOCONV_PATH else u'/usr/bin/unoconv'
if not os.path.exists(self.unoconv_path):
raise OfficeBackendError('cannot find unoconv executable')
def convert(self, input_filepath, output_filepath):
'''
Executes the program unoconv using subprocess's Popen
'''
self.input_filepath = input_filepath
self.output_filepath = output_filepath
command = []
command.append(self.unoconv_path)
if UNOCONV_USE_PIPE:
command.append(u'--pipe')
command.append(u'mayan-%s' % id_generator())
command.append(u'--format=pdf')
command.append(u'--output=%s' % self.output_filepath)
command.append(self.input_filepath)
try:
logger.debug('prev environment: %s' % os.environ)
proc = subprocess.Popen(command, close_fds=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
return_code = proc.wait()
logger.debug('post environment: %s' % os.environ)
readline = proc.stderr.readline()
if return_code != 0:
raise OfficeBackendError(proc.stderr.readline())
except OSError, msg:
raise OfficeBackendError(msg)
except Exception, msg:
logger.error('Unhandled exception: %s' % msg)

View File

@@ -0,0 +1,8 @@
from converter.office_converter import OfficeConverter
from converter.exceptions import OfficeBackendError
try:
office_converter = OfficeConverter()
except OfficeBackendError:
office_converter = None

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-09-29 18:44-0400\n"
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"

View File

@@ -1,20 +1,21 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
"POT-Creation-Date: 2011-09-29 18:44-0400\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
"PO-Revision-Date: 2011-09-30 04:34+0000\n"
"Last-Translator: rosarior <roberto.rosario.gonzalez@gmail.com>\n"
"Language-Team: Spanish (Castilian) (http://www.transifex.net/projects/p/mayan-edms/team/es/)\n"
"Language-Team: Spanish (Castilian) (http://www.transifex.net/projects/p/"
"mayan-edms/team/es/)\n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: es\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
#: __init__.py:15
@@ -98,5 +99,3 @@ msgstr "Añadir comentario al documento: %s"
#, python-format
msgid "comments: %s"
msgstr "comentarios: %s"

View File

@@ -1,21 +1,22 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
#
# Translators:
# <dev.emerson@gmail.com>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
"POT-Creation-Date: 2011-09-29 18:44-0400\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
"PO-Revision-Date: 2011-09-30 21:14+0000\n"
"Last-Translator: emersonsoares <dev.emerson@gmail.com>\n"
"Language-Team: Portuguese (http://www.transifex.net/projects/p/mayan-edms/team/pt/)\n"
"Language-Team: Portuguese (http://www.transifex.net/projects/p/mayan-edms/"
"team/pt/)\n"
"Language: pt\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: pt\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
#: __init__.py:15
@@ -99,5 +100,3 @@ msgstr "Adicionar comentário ao documento: %s"
#, python-format
msgid "comments: %s"
msgstr "comentários: %s"

View File

@@ -1,102 +1,103 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
# Translators:
# Sergey Glita <gsv70@mail.ru>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-11-03 16:38-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
"PO-Revision-Date: 2011-11-19 20:58+0000\n"
"Last-Translator: gsv70 <gsv70@mail.ru>\n"
"Language-Team: Russian (http://www.transifex.net/projects/p/mayan-edms/team/"
"ru/)\n"
"Language: ru\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\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"
"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"
#: __init__.py:15
msgid "Create new comments"
msgstr ""
msgstr "Создать новые комментарии"
#: __init__.py:16
msgid "Delete comments"
msgstr ""
msgstr "Удалить комментарии"
#: __init__.py:17
msgid "Edit comments"
msgstr ""
msgstr "Редактировать комментарии"
#: __init__.py:18
msgid "View comments"
msgstr ""
msgstr "Просмотр комментариев"
#: __init__.py:20
msgid "Comments"
msgstr ""
msgstr "Комментарии"
#: __init__.py:26 __init__.py:27
msgid "delete"
msgstr ""
msgstr "удалить"
#: __init__.py:28
msgid "add comment"
msgstr ""
msgstr "добавить комментарий"
#: __init__.py:29 utils.py:14
msgid "comments"
msgstr ""
msgstr "комментарии"
#: __init__.py:33
msgid "date"
msgstr ""
msgstr "дата"
#: __init__.py:37
msgid "user"
msgstr ""
msgstr "пользователь"
#: __init__.py:41
msgid "comment"
msgstr ""
msgstr "комментарий"
#: views.py:27
msgid "Must provide at least one comment."
msgstr ""
msgstr "Должен быть хотя бы один комментарий."
#: views.py:37
#, python-format
msgid "Comment \"%s\" deleted successfully."
msgstr ""
msgstr "Комментарий \"%s\" удален."
#: views.py:39
#, python-format
msgid "Error deleting comment \"%(comment)s\": %(error)s"
msgstr ""
msgstr "Ошибка при удалении комментариев \"%(comment)s\": %(error)s"
#: views.py:54
#, python-format
msgid "Are you sure you wish to delete the comment: %s?"
msgstr ""
msgstr "Вы действительно хотите удалить комментарий %s?"
#: views.py:56
#, python-format
msgid "Are you sure you wish to delete the comments: %s?"
msgstr ""
msgstr "Вы действительно хотите удалить комментарии %s?"
#: views.py:86
msgid "Comment added successfully."
msgstr ""
msgstr "Комментарий добавлен."
#: views.py:93
#, python-format
msgid "Add comment to document: %s"
msgstr ""
msgstr "Добавить комментарий на документ: %s"
#: views.py:109
#, python-format
msgid "comments: %s"
msgstr ""
msgstr "комментарии: %s"

View File

@@ -3,7 +3,7 @@ from django.utils.translation import ugettext_lazy as _
from navigation.api import register_top_menu, register_sidebar_template, \
register_links
from permissions.api import register_permission, set_namespace_title
from main.api import register_maintenance
from main.api import register_maintenance_links
from documents.literals import PERMISSION_DOCUMENT_VIEW
from documents.models import Document
@@ -24,7 +24,7 @@ register_top_menu('indexes', link={'text': _('indexes'), 'famfam': 'folder_page'
rebuild_index_instances = {'text': _('rebuild indexes'), 'view': 'rebuild_index_instances', 'famfam': 'folder_page', 'permissions': [PERMISSION_DOCUMENT_INDEXING_REBUILD_INDEXES], 'description': _(u'Deletes and creates from scratch all the document indexes.')}
register_maintenance(rebuild_index_instances, namespace='document_indexing', title=_(u'Indexes'))
register_maintenance_links([rebuild_index_instances], namespace='document_indexing', title=_(u'Indexes'))
register_sidebar_template(['index_instance_list'], 'indexing_help.html')

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-09-29 18:45-0400\n"
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"

View File

@@ -1,21 +1,22 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
#
# Translators:
# Roberto Rosario <roberto.rosario.gonzalez@gmail.com>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
"POT-Creation-Date: 2011-09-29 18:45-0400\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
"PO-Revision-Date: 2011-11-04 17:05+0000\n"
"Last-Translator: rosarior <roberto.rosario.gonzalez@gmail.com>\n"
"Language-Team: Spanish (Castilian) (http://www.transifex.net/projects/p/mayan-edms/team/es/)\n"
"Language-Team: Spanish (Castilian) (http://www.transifex.net/projects/p/"
"mayan-edms/team/es/)\n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: es\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
#: __init__.py:12
@@ -186,8 +187,8 @@ msgstr "¿Está seguro que desea reconstruir todos los índices?"
#: views.py:83
msgid "On large databases this operation may take some time to execute."
msgstr ""
"En bases de datos de gran tamaño esta operación puede tardar algún tiempo en"
" ejecutarse."
"En bases de datos de gran tamaño esta operación puede tardar algún tiempo en "
"ejecutarse."
#: views.py:89
msgid "Index rebuild completed successfully."
@@ -211,5 +212,3 @@ msgstr "¿Que son los índices?"
msgid "Indexes group documents into a tree like hierarchical structure."
msgstr ""
"Los índices agrupan documentos en una estructura jerárquica tipo árbol. "

View File

@@ -1,21 +1,22 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
#
# Translators:
# Renata Oliveira <renatabels@gmail.com>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
"POT-Creation-Date: 2011-09-29 18:45-0400\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
"PO-Revision-Date: 2011-11-03 02:59+0000\n"
"Last-Translator: renataoliveira <renatabels@gmail.com>\n"
"Language-Team: Portuguese (http://www.transifex.net/projects/p/mayan-edms/team/pt/)\n"
"Language-Team: Portuguese (http://www.transifex.net/projects/p/mayan-edms/"
"team/pt/)\n"
"Language: pt\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: pt\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
#: __init__.py:12
@@ -186,8 +187,7 @@ msgstr "Tem certeza de que deseja reconstruir todos os índices?"
#: views.py:83
msgid "On large databases this operation may take some time to execute."
msgstr ""
"Em grandes bases de dados esta operação pode levar algum tempo para "
"executar."
"Em grandes bases de dados esta operação pode levar algum tempo para executar."
#: views.py:89
msgid "Index rebuild completed successfully."
@@ -211,5 +211,3 @@ msgstr "Quais são os índices?"
msgid "Indexes group documents into a tree like hierarchical structure."
msgstr ""
"Indexar documentos agrupados em uma árvore como uma estrutura hierárquica."

View File

@@ -1,21 +1,23 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
"POT-Creation-Date: 2011-09-29 18:45-0400\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
"PO-Revision-Date: 2011-11-03 22:42+0000\n"
"Last-Translator: gsv70 <gsv70@mail.ru>\n"
"Language-Team: Russian (http://www.transifex.net/projects/p/mayan-edms/team/ru/)\n"
"Language-Team: Russian (http://www.transifex.net/projects/p/mayan-edms/team/"
"ru/)\n"
"Language: ru\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ru\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"
"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"
#: __init__.py:12
msgid "View document indexes"
@@ -209,5 +211,3 @@ msgstr "что за индексы?"
#: templates/indexing_help.html:4
msgid "Indexes group documents into a tree like hierarchical structure."
msgstr "Индексы группы документов в древовидной иерархической структуре."

View File

@@ -6,7 +6,7 @@ from common.utils import validate_path, encapsulate
from navigation.api import register_links, register_top_menu, \
register_model_list_columns, register_multi_item_links, \
register_sidebar_template
from main.api import register_diagnostic, register_maintenance
from main.api import register_diagnostic, register_maintenance_links
from permissions.api import register_permission, set_namespace_title
from tags.widgets import get_tags_inline_widget_simple
from history.api import register_history_type
@@ -29,7 +29,6 @@ from documents.conf.settings import ZOOM_MIN_LEVEL
from documents.conf import settings as document_settings
from documents.widgets import document_thumbnail
# Document page links expressions
def is_first_page(context):
return context['page'].page_number <= 1
@@ -81,6 +80,7 @@ document_preview = {'text': _(u'preview'), 'class': 'fancybox', 'view': 'documen
document_download = {'text': _(u'download'), 'view': 'document_download', 'args': 'object.id', 'famfam': 'page_save', 'permissions': [PERMISSION_DOCUMENT_DOWNLOAD]}
document_find_duplicates = {'text': _(u'find duplicates'), 'view': 'document_find_duplicates', 'args': 'object.id', 'famfam': 'page_refresh', 'permissions': [PERMISSION_DOCUMENT_VIEW]}
document_find_all_duplicates = {'text': _(u'find all duplicates'), 'view': 'document_find_all_duplicates', 'famfam': 'page_refresh', 'permissions': [PERMISSION_DOCUMENT_VIEW], 'description': _(u'Search all the documents\' checksums and return a list of the exact matches.')}
document_update_page_count = {'text': _(u'update office documents\' page count'), 'view': 'document_update_page_count', 'famfam': 'page_white_csharp', 'permissions': [PERMISSION_DOCUMENT_TOOLS], 'description': _(u'Update the page count of the office type documents. This is useful when enabling office document support after there were already office type documents in the database.')}
document_clear_transformations = {'text': _(u'clear transformations'), 'view': 'document_clear_transformations', 'args': 'object.id', 'famfam': 'page_paintbrush', 'permissions': [PERMISSION_DOCUMENT_TRANSFORM]}
document_multiple_clear_transformations = {'text': _(u'clear transformations'), 'view': 'document_multiple_clear_transformations', 'famfam': 'page_paintbrush', 'permissions': [PERMISSION_DOCUMENT_TRANSFORM]}
document_print = {'text': _(u'print'), 'view': 'document_print', 'args': 'object.id', 'famfam': 'printer', 'permissions': [PERMISSION_DOCUMENT_VIEW]}
@@ -158,17 +158,16 @@ register_links(['document_page_transformation_edit', 'document_page_transformati
register_diagnostic('documents', _(u'Documents'), document_missing_list)
register_maintenance(document_find_all_duplicates, namespace='documents', title=_(u'documents'))
register_maintenance_links([document_find_all_duplicates, document_update_page_count], namespace='documents', title=_(u'documents'))
def document_exists(document):
try:
if document.exists():
return u'<span class="famfam active famfam-tick"></span>'
else:
return u'<span class="famfam active famfam-cross"></span>'
except Exception, exc:
return exc
#def document_exists(document):
# try:
# if document.exists():
# return u'<span class="famfam active famfam-tick"></span>'
# else:
# return u'<span class="famfam active famfam-cross"></span>'
# except Exception, exc:
# return exc
register_model_list_columns(Document, [
{'name':_(u'thumbnail'), 'attribute':

View File

@@ -9,11 +9,11 @@ from common.forms import DetailForm
from common.literals import PAGE_SIZE_CHOICES, PAGE_ORIENTATION_CHOICES
from common.conf.settings import DEFAULT_PAPER_SIZE
from common.conf.settings import DEFAULT_PAGE_ORIENTATION
from common.widgets import TextAreaDiv
from common.widgets import TextAreaDiv
from documents.models import Document, DocumentType, \
DocumentPage, DocumentPageTransformation, DocumentTypeFilename
from documents.widgets import document_html_widget
# Document page forms
class DocumentPageTransformationForm(forms.ModelForm):
@@ -32,22 +32,10 @@ class DocumentPageImageWidget(forms.widgets.Widget):
rotation = final_attrs.get('rotation', 0)
if value:
output = []
output.append('''
<div class="full-height scrollable" style="overflow: auto;">
<div class="tc">
<img class="lazy-load" data-href="%(img)s?page=%(page)d&zoom=%(zoom)d&rotation=%(rotation)d" src="%(static_url)s/images/ajax-loader.gif" alt="%(string)s" />
<noscript>
<img src="%(img)s?page=%(page)d&zoom=%(zoom)d&rotation=%(rotation)d" alt="%(string)s" />
</noscript>
</div>
</div>''' % {
'img': reverse('document_display', args=[value.document.id]),
'page': value.page_number,
'zoom': zoom,
'rotation': rotation,
'static_url': settings.STATIC_URL,
'string': ugettext(u'page image')
})
output.append('<div class="full-height scrollable" style="overflow: auto;">')
output.append(document_html_widget(value.document, view='document_display', page=value.page_number, zoom=zoom, rotation=rotation))
output.append('</div>')
return mark_safe(u''.join(output))
else:
return u''
@@ -113,52 +101,24 @@ class DocumentPagesCarouselWidget(forms.widgets.Widget):
output.append(u'<div style="white-space:nowrap; overflow: auto;">')
for page in value.documentpage_set.all():
try:
page.document.get_valid_image()
template = u'''<div style="display: inline-block; margin: 5px 10px 10px 10px;">
<div class="tc">%(page_string)s %(page)s</div>
<div class="tc" style="border: 1px solid black; margin: 5px 0px 5px 0px;">
<a rel="page_gallery" class="fancybox-noscaling" href="%(view_url)s?page=%(page)d">
<img class="lazy-load" data-href="%(img)s?page=%(page)d" src="%(static_url)s/images/ajax-loader.gif" alt="%(string)s" />
<noscript>
<img src="%(img)s?page=%(page)d" alt="%(string)s" />
</noscript>
</a>
</div>
<div class="tc">
<a class="fancybox-iframe" href="%(url)s"><span class="famfam active famfam-page_white_go"></span>%(details_string)s</a>
</div>
</div>'''
except:
template = u'''<div style="display: inline-block; margin: 5px 10px 10px 10px;">
<div class="tc">%(page_string)s %(page)s</div>
<div class="tc" style="border: 1px solid black; margin: 5px 0px 5px 0px;">
<img class="lazy-load" data-href="%(img)s?page=%(page)d" src="%(static_url)s/images/ajax-loader.gif" alt="%(string)s" />
<noscript>
<img src="%(img)s?page=%(page)d" alt="%(string)s" />
</noscript>
</div>
<div class="tc">
<a class="fancybox-iframe" href="%(url)s"><span class="famfam active famfam-page_white_go"></span>%(details_string)s</a>
</div>
</div>'''
output.append(template % {
'url': reverse('document_page_view', args=[page.pk]),
'img': reverse('document_preview_multipage', args=[value.pk]),
'page': page.page_number,
'view_url': reverse('document_display', args=[page.document.pk]),
'page_string': ugettext(u'Page'),
'details_string': ugettext(u'Details'),
'static_url': settings.STATIC_URL,
'string': _(u'document page')
})
output.append(u'<div style="display: inline-block; margin: 5px 10px 10px 10px;">')
output.append(
document_html_widget(
page.document,
view='document_preview_multipage',
click_view='document_display',
page=page.page_number,
gallery_name='document_pages',
fancybox_class='fancybox-noscaling',
)
)
output.append(u'<div class="tc">')
output.append(u'<a class="fancybox-iframe" href="%s"><span class="famfam active famfam-page_white_go"></span>%s</a>' % (reverse('document_page_view', args=[page.pk]), ugettext(u'Details')))
output.append(u'</div>')
output.append(u'</div>')
output.append(u'</div>')
output.append(
u'<br /><span class="famfam active famfam-magnifier"></span>%s' %
ugettext(u'Click on the image for full size preview'))
output.append(u'<br /><span class="famfam active famfam-magnifier"></span>%s' % ugettext(u'Click on the image for full size preview'))
return mark_safe(u''.join(output))

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,9 @@ import os
import tempfile
import hashlib
from ast import literal_eval
import base64
from StringIO import StringIO
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext
@@ -26,6 +28,8 @@ from documents.conf.settings import STORAGE_BACKEND
from documents.conf.settings import PREVIEW_SIZE
from documents.conf.settings import DISPLAY_SIZE
from documents.conf.settings import CACHE_PATH
from documents.conf.settings import ZOOM_MAX_LEVEL
from documents.conf.settings import ZOOM_MIN_LEVEL
from documents.managers import RecentDocumentManager, \
DocumentPageTransformationManager
@@ -194,6 +198,10 @@ class Document(models.Model):
self.save()
return detected_pages
@property
def page_count(self):
return self.documentpage_set.count()
def save_to_file(self, filepath, buffer_size=1024 * 1024):
"""
@@ -246,21 +254,37 @@ class Document(models.Model):
return cache_file_path
else:
document_file = document_save_to_temp_dir(self, self.checksum)
return convert(document_file, output_filepath=cache_file_path, page=page, transformations=transformations)
return convert(document_file, output_filepath=cache_file_path, page=page, transformations=transformations, mimetype=self.file_mimetype)
def get_valid_image(self, size=DISPLAY_SIZE, page=DEFAULT_PAGE_NUMBER, zoom=DEFAULT_ZOOM_LEVEL, rotation=DEFAULT_ROTATION):
image_cache_name = self.get_image_cache_name(page=page)
return convert(image_cache_name, cleanup_files=False, size=size, zoom=zoom, rotation=rotation)
def get_image(self, size=DISPLAY_SIZE, page=DEFAULT_PAGE_NUMBER, zoom=DEFAULT_ZOOM_LEVEL, rotation=DEFAULT_ROTATION):
def get_image(self, size=DISPLAY_SIZE, page=DEFAULT_PAGE_NUMBER, zoom=DEFAULT_ZOOM_LEVEL, rotation=DEFAULT_ROTATION, as_base64=False):
if zoom < ZOOM_MIN_LEVEL:
zoom = ZOOM_MIN_LEVEL
if zoom > ZOOM_MAX_LEVEL:
zoom = ZOOM_MAX_LEVEL
rotation = rotation % 360
try:
return self.get_valid_image(size=size, page=page, zoom=zoom, rotation=rotation)
file_path = self.get_valid_image(size=size, page=page, zoom=zoom, rotation=rotation)
except UnknownFileFormat:
return get_icon_file_path(self.file_mimetype)
file_path = get_icon_file_path(self.file_mimetype)
except UnkownConvertError:
return get_error_icon_file_path()
file_path = get_error_icon_file_path()
except:
return get_error_icon_file_path()
file_path = get_error_icon_file_path()
if as_base64:
image = open(file_path, 'r')
out = StringIO()
base64.encode(image, out)
return u'data:%s;base64,%s' % (get_mimetype(open(file_path, 'r'), file_path, mimetype_only=True)[0], out.getvalue().replace('\n', ''))
else:
return file_path
def invalidate_cached_image(self, page):
try:
@@ -274,6 +298,13 @@ class Document(models.Model):
def delete(self, *args, **kwargs):
super(Document, self).delete(*args, **kwargs)
return self.file.storage.delete(self.file.path)
@property
def size(self):
if self.exists():
return self.file.storage.size(self.file.path)
else:
return None
class DocumentTypeFilename(models.Model):

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -25,6 +25,10 @@ urlpatterns = patterns('documents.views',
url(r'^(?P<document_id>\d+)/display/$', 'get_document_image', {'size': DISPLAY_SIZE}, 'document_display'),
url(r'^(?P<document_id>\d+)/display/print/$', 'get_document_image', {'size': PRINT_SIZE}, 'document_display_print'),
url(r'^(?P<document_id>\d+)/display/preview/base64/$', 'get_document_image', {'size': PREVIEW_SIZE, 'base64_version': True}, 'document_preview_base64'),
url(r'^(?P<document_id>\d+)/display/preview/multipage/base64/$', 'get_document_image', {'size': MULTIPAGE_PREVIEW_SIZE, 'base64_version': True}, 'document_preview_multipage_base64'),
url(r'^(?P<document_id>\d+)/display/thumbnail/base64/$', 'get_document_image', {'size': THUMBNAIL_SIZE, 'base64_version': True}, 'document_thumbnail_base64'),
url(r'^(?P<document_id>\d+)/download/$', 'document_download', (), 'document_download'),
url(r'^(?P<document_id>\d+)/create/siblings/$', 'document_create_siblings', (), 'document_create_siblings'),
url(r'^(?P<document_id>\d+)/find_duplicates/$', 'document_find_duplicates', (), 'document_find_duplicates'),
@@ -32,6 +36,7 @@ urlpatterns = patterns('documents.views',
url(r'^multiple/clear_transformations/$', 'document_multiple_clear_transformations', (), 'document_multiple_clear_transformations'),
url(r'^duplicates/list/$', 'document_find_all_duplicates', (), 'document_find_all_duplicates'),
url(r'^maintenance/update_page_count/$', 'document_update_page_count', (), 'document_update_page_count'),
url(r'^page/(?P<document_page_id>\d+)/$', 'document_page_view', (), 'document_page_view'),
url(r'^page/(?P<document_page_id>\d+)/text/$', 'document_page_text', (), 'document_page_text'),

View File

@@ -2,7 +2,7 @@ import urlparse
import copy
from django.utils.translation import ugettext_lazy as _
from django.http import HttpResponseRedirect
from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import render_to_response, get_object_or_404
from django.template import RequestContext
from django.contrib import messages
@@ -18,7 +18,8 @@ from common.literals import PAGE_SIZE_DIMENSIONS, \
PAGE_ORIENTATION_PORTRAIT, PAGE_ORIENTATION_LANDSCAPE
from common.conf.settings import DEFAULT_PAPER_SIZE
from converter.literals import DEFAULT_ZOOM_LEVEL, DEFAULT_ROTATION, \
DEFAULT_PAGE_NUMBER
DEFAULT_PAGE_NUMBER, DEFAULT_FILE_FORMAT_MIMETYPE
from converter.office_converter import OfficeConverter
from filetransfers.api import serve_file
from metadata.forms import MetadataFormSet, MetadataSelectionForm
from navigation.utils import resolve_to_name
@@ -40,7 +41,7 @@ from documents.literals import PERMISSION_DOCUMENT_CREATE, \
PERMISSION_DOCUMENT_VIEW, \
PERMISSION_DOCUMENT_DELETE, PERMISSION_DOCUMENT_DOWNLOAD, \
PERMISSION_DOCUMENT_TRANSFORM, \
PERMISSION_DOCUMENT_EDIT
PERMISSION_DOCUMENT_EDIT, PERMISSION_DOCUMENT_TOOLS
from documents.literals import HISTORY_DOCUMENT_CREATED, \
HISTORY_DOCUMENT_EDITED, HISTORY_DOCUMENT_DELETED
@@ -117,14 +118,14 @@ def document_view(request, document_id, advanced=False):
{'label': _(u'File extension'), 'field': 'file_extension'},
{'label': _(u'File mimetype'), 'field': 'file_mimetype'},
{'label': _(u'File mime encoding'), 'field': 'file_mime_encoding'},
{'label': _(u'File size'), 'field':lambda x: pretty_size(x.file.storage.size(x.file.path)) if x.exists() else '-'},
{'label': _(u'File size'), 'field':lambda x: pretty_size(x.size) if x.size else '-'},
{'label': _(u'Exists in storage'), 'field': 'exists'},
{'label': _(u'File path in storage'), 'field': 'file'},
{'label': _(u'Date added'), 'field':lambda x: x.date_added.date()},
{'label': _(u'Time added'), 'field':lambda x: unicode(x.date_added.time()).split('.')[0]},
{'label': _(u'Checksum'), 'field': 'checksum'},
{'label': _(u'UUID'), 'field': 'uuid'},
{'label': _(u'Pages'), 'field': lambda x: x.documentpage_set.count()},
{'label': _(u'Pages'), 'field': 'page_count'},
])
subtemplates_list.append(
@@ -270,7 +271,7 @@ def document_edit(request, document_id):
}, context_instance=RequestContext(request))
def get_document_image(request, document_id, size=PREVIEW_SIZE):
def get_document_image(request, document_id, size=PREVIEW_SIZE, base64_version=False):
check_permissions(request.user, [PERMISSION_DOCUMENT_VIEW])
document = get_object_or_404(Document, pk=document_id)
@@ -287,7 +288,12 @@ def get_document_image(request, document_id, size=PREVIEW_SIZE):
rotation = int(request.GET.get('rotation', DEFAULT_ROTATION)) % 360
return sendfile.sendfile(request, document.get_image(size=size, page=page, zoom=zoom, rotation=rotation))
if base64_version:
return HttpResponse(u'<html><body><img src="%s" /></body></html>' % document.get_image(size=size, page=page, zoom=zoom, rotation=rotation, as_base64=True))
else:
# TODO: hardcoded MIMETYPE
return sendfile.sendfile(request, document.get_image(size=size, page=page, zoom=zoom, rotation=rotation), mimetype=DEFAULT_FILE_FORMAT_MIMETYPE)
def document_download(request, document_id):
@@ -471,6 +477,37 @@ def document_find_all_duplicates(request):
return _find_duplicate_list(request, include_source=True)
def document_update_page_count(request):
check_permissions(request.user, [PERMISSION_DOCUMENT_TOOLS])
previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', '/')))
office_converter = OfficeConverter()
qs = Document.objects.exclude(file_extension__iendswith='dxf').filter(file_mimetype__in=office_converter.mimetypes())
if request.method == 'POST':
updated = 0
processed = 0
for document in qs:
old_page_count = document.page_count
document.update_page_count()
processed += 1
if old_page_count != document.page_count:
updated += 1
messages.success(request, _(u'Page count update complete. Documents processed: %(total)d, documents with changed page count: %(change)d') % {
'total': processed,
'change': updated
})
return HttpResponseRedirect(previous)
return render_to_response('generic_confirm.html', {
'previous': previous,
'title': _(u'Are you sure you wish to update the page count for the office documents (%d)?') % qs.count(),
'message': _(u'On large databases this operation may take some time to execute.'),
'form_icon': u'page_white_csharp.png',
}, context_instance=RequestContext(request))
def document_clear_transformations(request, document_id=None, document_id_list=None):
check_permissions(request.user, [PERMISSION_DOCUMENT_TRANSFORM])

View File

@@ -2,25 +2,77 @@ from django.utils.safestring import mark_safe
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from django.core.urlresolvers import reverse
from django.utils.http import urlencode
from converter.literals import DEFAULT_ZOOM_LEVEL, DEFAULT_ROTATION, \
DEFAULT_PAGE_NUMBER
from converter.exceptions import UnknownFileFormat, UnkownConvertError
from mimetype.api import get_error_icon_url
from documents.conf.settings import DISPLAY_SIZE
def document_thumbnail(document):
try:
document.get_valid_image()
template = u'<a class="fancybox" href="%(url)s"><img class="lazy-load" data-href="%(thumbnail)s" src="%(static_url)s/images/ajax-loader.gif" alt="%(string)s" /><noscript><img src="%(thumbnail)s" alt="%(string)s" /></noscript></a>'
except:
template = u'<img class="lazy-load" data-href="%(thumbnail)s" src="%(static_url)s/images/ajax-loader.gif" alt="%(string)s" /><noscript><img src="%(thumbnail)s" alt="%(string)s" /></noscript>'
try:
return mark_safe(template % {
'url': reverse('document_preview', args=[document.pk]),
'thumbnail': reverse('document_thumbnail', args=[document.pk]),
'static_url': settings.STATIC_URL,
'string': _(u'thumbnail')
})
except:
return u''
return document_html_widget(document, click_view='document_preview')
def document_link(document):
return mark_safe(u'<a href="%s">%s</a>' % (reverse('document_view_simple', args=[document.pk]), document))
def document_html_widget(document, view='document_thumbnail', click_view=None, page=DEFAULT_PAGE_NUMBER, zoom=DEFAULT_ZOOM_LEVEL, rotation=DEFAULT_ROTATION, gallery_name=None, fancybox_class='fancybox'):
result = []
alt_text = _(u'document page image')
query_dict = {
'page': page,
'zoom': zoom,
'rotation': rotation,
}
if gallery_name:
gallery_template = u'rel="%s"' % gallery_name
else:
gallery_template = u''
query_string = urlencode(query_dict)
preview_view = u'%s?%s' % (reverse(view, args=[document.pk]), query_string)
plain_template = []
plain_template.append(u'<img src="%s" alt="%s" />' % (preview_view, alt_text))
result.append(u'<div class="tc" id="document-%d-%d">' % (document.pk, page if page else 1))
if click_view:
result.append(u'<a %s class="%s" href="%s">' % (gallery_template, fancybox_class, u'%s?%s' % (reverse(click_view, args=[document.pk]), query_string)))
result.append(u'<img class="thin_border lazy-load" data-href="%s" src="%simages/ajax-loader.gif" alt="%s" />' % (preview_view, settings.STATIC_URL, alt_text))
result.append(u'<noscript><img style="border: 1px solid black;" src="%s" alt="%s" /></noscript>' % (preview_view, alt_text))
if click_view:
result.append(u'</a>')
result.append(u'</div>')
result.append(u'''
<script type="text/javascript">
$(document).ready(function() {
$.get('%(url)s', function(data) {})
.success(function(data) {
if (!data.result) {
$('#document-%(pk)d-%(page)d').html('%(plain_template)s');
}
})
.error(function(data) {
$('#document-%(pk)d-%(page)d').html('<img src="%(error_image)s" />');
});
});
</script>
''' % {
'url': reverse('documents-expensive-is_zoomable', args=[document.pk, page]),
'pk': document.pk,
'page': page if page else 1,
'plain_template': mark_safe(u''.join(plain_template)),
'error_image': u''.join([settings.STATIC_URL, get_error_icon_url()]),
}
)
return mark_safe(u''.join(result))

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-09-29 18:45-0400\n"
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -33,27 +33,27 @@ msgstr ""
msgid "Search terms"
msgstr ""
#: models.py:18
#: models.py:20
msgid "user"
msgstr ""
#: models.py:19
#: models.py:21
msgid "query"
msgstr ""
#: models.py:20
#: models.py:22
msgid "datetime created"
msgstr ""
#: models.py:21
#: models.py:23
msgid "hits"
msgstr ""
#: models.py:59
#: models.py:61
msgid "recent search"
msgstr ""
#: models.py:60
#: models.py:62
msgid "recent searches"
msgstr ""

View File

@@ -1,21 +1,22 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
#
# Translators:
# Roberto Rosario <roberto.rosario.gonzalez@gmail.com>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
"POT-Creation-Date: 2011-09-29 18:45-0400\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
"PO-Revision-Date: 2011-11-04 17:06+0000\n"
"Last-Translator: rosarior <roberto.rosario.gonzalez@gmail.com>\n"
"Language-Team: Spanish (Castilian) (http://www.transifex.net/projects/p/mayan-edms/team/es/)\n"
"Language-Team: Spanish (Castilian) (http://www.transifex.net/projects/p/"
"mayan-edms/team/es/)\n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: es\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
#: __init__.py:5
@@ -34,27 +35,27 @@ msgstr "buscar de nuevo"
msgid "Search terms"
msgstr "Términos de búsqueda"
#: models.py:18
#: models.py:20
msgid "user"
msgstr "usuario"
#: models.py:19
#: models.py:21
msgid "query"
msgstr "pregunta"
#: models.py:20
#: models.py:22
msgid "datetime created"
msgstr "fecha y hora creados"
#: models.py:21
#: models.py:23
msgid "hits"
msgstr "accesos"
#: models.py:59
#: models.py:61
msgid "recent search"
msgstr "búsqueda reciente"
#: models.py:60
#: models.py:62
msgid "recent searches"
msgstr "búsquedas recientes"
@@ -117,5 +118,3 @@ msgstr "Tiempo transcurrido: %(time_delta)s segundos"
#, python-format
msgid "recent searches (maximum of %d)"
msgstr "búsquedas recientes (máximo de %d)"

View File

@@ -1,21 +1,22 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
#
# Translators:
# <dev.emerson@gmail.com>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
"POT-Creation-Date: 2011-09-29 18:45-0400\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
"PO-Revision-Date: 2011-11-03 02:32+0000\n"
"Last-Translator: emersonsoares <dev.emerson@gmail.com>\n"
"Language-Team: Portuguese (http://www.transifex.net/projects/p/mayan-edms/team/pt/)\n"
"Language-Team: Portuguese (http://www.transifex.net/projects/p/mayan-edms/"
"team/pt/)\n"
"Language: pt\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: pt\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
#: __init__.py:5
@@ -34,27 +35,27 @@ msgstr "pesquisar novamente"
msgid "Search terms"
msgstr "Termos de pesquisa"
#: models.py:18
#: models.py:20
msgid "user"
msgstr "usuário"
#: models.py:19
#: models.py:21
msgid "query"
msgstr "pergunta"
#: models.py:20
#: models.py:22
msgid "datetime created"
msgstr "Data e hora da criação"
#: models.py:21
#: models.py:23
msgid "hits"
msgstr "visitas"
#: models.py:59
#: models.py:61
msgid "recent search"
msgstr "pesquisa recente"
#: models.py:60
#: models.py:62
msgid "recent searches"
msgstr "pesquisas recentes"
@@ -116,5 +117,3 @@ msgstr "Tempo decorrido: %(time_delta)s segundos"
#, python-format
msgid "recent searches (maximum of %d)"
msgstr "pesquisas recentes (maximum of %d)"

View File

@@ -1,21 +1,23 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
"POT-Creation-Date: 2011-09-29 18:45-0400\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
"PO-Revision-Date: 2011-11-03 22:40+0000\n"
"Last-Translator: gsv70 <gsv70@mail.ru>\n"
"Language-Team: Russian (http://www.transifex.net/projects/p/mayan-edms/team/ru/)\n"
"Language-Team: Russian (http://www.transifex.net/projects/p/mayan-edms/team/"
"ru/)\n"
"Language: ru\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ru\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"
"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"
#: __init__.py:5
msgid "search"
@@ -33,27 +35,27 @@ msgstr "искать ещё раз"
msgid "Search terms"
msgstr "Слова для поиска"
#: models.py:18
#: models.py:20
msgid "user"
msgstr "пользователь"
#: models.py:19
#: models.py:21
msgid "query"
msgstr "запрос"
#: models.py:20
#: models.py:22
msgid "datetime created"
msgstr "даты и время создания"
#: models.py:21
#: models.py:23
msgid "hits"
msgstr "хитов"
#: models.py:59
#: models.py:61
msgid "recent search"
msgstr "недавний поиск"
#: models.py:60
#: models.py:62
msgid "recent searches"
msgstr "последние запросы"
@@ -83,8 +85,7 @@ msgstr "Поиск"
#: conf/settings.py:12
msgid "Maximum amount search hits to fetch and display."
msgstr ""
"Максимальное количество отображаемых документов из результатов поиска."
msgstr "Максимальное количество отображаемых документов из результатов поиска."
#: conf/settings.py:13
msgid "Maximum number of search queries to remember per user."
@@ -118,5 +119,3 @@ msgstr "Прошедшее время в секундах: %(time_delta)s"
#, python-format
msgid "recent searches (maximum of %d)"
msgstr "Последние запросы (максимум %d)"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-09-29 18:45-0400\n"
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"

View File

@@ -1,20 +1,21 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
"POT-Creation-Date: 2011-09-29 18:45-0400\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
"PO-Revision-Date: 2011-09-30 05:10+0000\n"
"Last-Translator: rosarior <roberto.rosario.gonzalez@gmail.com>\n"
"Language-Team: Spanish (Castilian) (http://www.transifex.net/projects/p/mayan-edms/team/es/)\n"
"Language-Team: Spanish (Castilian) (http://www.transifex.net/projects/p/"
"mayan-edms/team/es/)\n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: es\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
#: __init__.py:10
@@ -192,8 +193,8 @@ msgstr ""
#: views.py:268
#, python-format
msgid ""
"Are you sure you wish to remove the documents: %(documents)s from the folder"
" \"%(folder)s\"?"
"Are you sure you wish to remove the documents: %(documents)s from the folder "
"\"%(folder)s\"?"
msgstr ""
"¿Está seguro que desea eliminar los documentos: %(documents)s de la carpeta "
"\"%(folder)s\"?"
@@ -218,5 +219,3 @@ msgstr ""
#: templatetags/folder_tags.py:17
msgid "Add document to a folder"
msgstr "Agregar documento a una carpeta"

View File

@@ -1,21 +1,22 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
#
# Translators:
# Renata Oliveira <renatabels@gmail.com>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
"POT-Creation-Date: 2011-09-29 18:45-0400\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
"PO-Revision-Date: 2011-11-03 03:33+0000\n"
"Last-Translator: renataoliveira <renatabels@gmail.com>\n"
"Language-Team: Portuguese (http://www.transifex.net/projects/p/mayan-edms/team/pt/)\n"
"Language-Team: Portuguese (http://www.transifex.net/projects/p/mayan-edms/"
"team/pt/)\n"
"Language: pt\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: pt\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
#: __init__.py:10
@@ -192,8 +193,8 @@ msgstr ""
#: views.py:268
#, python-format
msgid ""
"Are you sure you wish to remove the documents: %(documents)s from the folder"
" \"%(folder)s\"?"
"Are you sure you wish to remove the documents: %(documents)s from the folder "
"\"%(folder)s\"?"
msgstr ""
"Tem certeza de que deseja remover os documentos: %(documents)s da pasta "
"\"%(folder)s\"?"
@@ -209,8 +210,8 @@ msgid ""
"created by one user and the documents contained by them don't affect any "
"other user folders or documents."
msgstr ""
"Estas pastas também podem ser descritas como pastas de usuário. Elas são uma"
" maneira de permitir que os usuários individuais criem os seus próprios "
"Estas pastas também podem ser descritas como pastas de usuário. Elas são uma "
"maneira de permitir que os usuários individuais criem os seus próprios "
"métodos de organização do documento. Pastas criadas por um usuário e os "
"documentos contidos nelas não afetam todas as pastas de outros usuários ou "
"documentos."
@@ -218,5 +219,3 @@ msgstr ""
#: templatetags/folder_tags.py:17
msgid "Add document to a folder"
msgstr "Adicionar documento à uma pasta"

View File

@@ -1,21 +1,23 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
"POT-Creation-Date: 2011-09-29 18:45-0400\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
"PO-Revision-Date: 2011-11-03 16:56+0000\n"
"Last-Translator: gsv70 <gsv70@mail.ru>\n"
"Language-Team: Russian (http://www.transifex.net/projects/p/mayan-edms/team/ru/)\n"
"Language-Team: Russian (http://www.transifex.net/projects/p/mayan-edms/team/"
"ru/)\n"
"Language: ru\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ru\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"
"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"
#: __init__.py:10
msgid "folder list"
@@ -185,14 +187,14 @@ msgid ""
"Are you sure you wish to remove the document: %(document)s from the folder "
"\"%(folder)s\"?"
msgstr ""
"Вы действительно хотите удалить документ: %(document)s из папки \"%(folder)s"
" \"?"
"Вы действительно хотите удалить документ: %(document)s из папки \"%(folder)s "
"\"?"
#: views.py:268
#, python-format
msgid ""
"Are you sure you wish to remove the documents: %(documents)s from the folder"
" \"%(folder)s\"?"
"Are you sure you wish to remove the documents: %(documents)s from the folder "
"\"%(folder)s\"?"
msgstr ""
"Вы действительно хотите удалить документы: %(documents)s из папки "
"\"%(folder)s\"?"
@@ -215,5 +217,3 @@ msgstr ""
#: templatetags/folder_tags.py:17
msgid "Add document to a folder"
msgstr "Добавить документ в папку"

View File

@@ -1,11 +0,0 @@
from django.utils.translation import ugettext_lazy as _
from navigation.api import register_links
from documents.literals import PERMISSION_DOCUMENT_VIEW
from documents.models import Document
document_group_link = {'text': _(u'group actions'), 'view': 'document_group_view', 'famfam': 'page_go', 'permissions': [PERMISSION_DOCUMENT_VIEW]}
groups_for_document = {'text': _(u'groups'), 'view': 'groups_for_document', 'args': 'object.pk', 'famfam': 'page_go', 'permissions': [PERMISSION_DOCUMENT_VIEW]}
register_links(Document, [groups_for_document], menu_name='form_header')

View File

@@ -1,16 +0,0 @@
from django.contrib import admin
from grouping.models import DocumentGroup, DocumentGroupItem
class DocumentGroupItemInline(admin.StackedInline):
model = DocumentGroupItem
extra = 1
classes = ('collapse-open',)
allow_add = True
class DocumentGroupAdmin(admin.ModelAdmin):
inlines = [DocumentGroupItemInline]
admin.site.register(DocumentGroup, DocumentGroupAdmin)

View File

@@ -1,11 +0,0 @@
"""Configuration options for the grouping app"""
from smart_settings.api import register_settings
register_settings(
namespace=u'grouping',
module=u'grouping.conf.settings',
settings=[
{'name': u'SHOW_EMPTY_GROUPS', 'global_name': u'GROUPING_SHOW_EMPTY_GROUPS', 'default': True},
]
)

View File

@@ -1,106 +0,0 @@
from django import forms
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext
from django.core.urlresolvers import reverse
from django.utils.safestring import mark_safe
from django.template.defaultfilters import capfirst
from django.conf import settings
from tags.widgets import get_tags_inline_widget
class DocumentGroupImageWidget(forms.widgets.Widget):
def render(self, name, value, attrs=None):
output = []
if value['links']:
output.append(u'<div class="group navform wat-cf">')
for link in value['links']:
output.append(u'''
<button class="button" type="submit" name="action" value="%(action)s">
<span class="famfam active famfam-%(famfam)s"></span>%(text)s
</button>
''' % {
'famfam': link.get('famfam', u'link'),
'text': capfirst(link['text']),
'action': reverse('document_group_view', args=[value['current_document'].pk, value['group'].pk])
})
output.append(u'</div>')
output.append(u'<div style="white-space:nowrap; overflow: auto;">')
for document in value['group_data']:
tags_template = get_tags_inline_widget(document)
try:
document.get_valid_image()
template = u'''<div style="display: inline-block; margin: 0px 10px 10px 10px; %(current)s">
<div class="tc">%(document_name)s</div>
<div class="tc">%(page_string)s: %(document_pages)d</div>
%(tags_template)s
<div class="tc">
<a rel="group_%(group_id)d_documents_gallery" class="fancybox-noscaling" href="%(view_url)s">
<img class="lazy-load" style="border: 1px solid black; margin: 10px;" src="%(static_url)s/images/ajax-loader.gif" data-href="%(img)s" alt="%(string)s" />
<noscript>
<img style="border: 1px solid black; margin: 10px;" src="%(img)s" alt="%(string)s" />
</noscript>
</a>
</div>
<div class="tc">
<a href="%(url)s"><span class="famfam active famfam-page_go"></span>%(details_string)s</a>
</div>
</div>'''
except:
template = u'''<div style="display: inline-block; margin: 0px 10px 10px 10px; %(current)s">
<div class="tc">%(document_name)s</div>
<div class="tc">%(page_string)s: %(document_pages)d</div>
%(tags_template)s
<div class="tc">
<img class="lazy-load" style="border: 1px solid black; margin: 10px;" src="%(static_url)s/images/ajax-loader.gif" data-href="%(img)s" alt="%(string)s" />
<noscript>
<img style="border: 1px solid black; margin: 10px;" src="%(img)s" alt="%(string)s" />
</noscript>
</div>
<div class="tc">
<a href="%(url)s"><span class="famfam active famfam-page_go"></span>%(details_string)s</a>
</div>
</div>'''
output.append(template % {
'url': reverse('document_view_simple', args=[document.pk]),
'img': reverse('document_preview_multipage', args=[document.pk]),
'current': u'border: 5px solid black; padding: 3px;' if value['current_document'] == document else u'',
'view_url': reverse('document_display', args=[document.pk]),
'document_pages': document.documentpage_set.count(),
'page_string': ugettext(u'Pages'),
'details_string': ugettext(u'Select'),
'group_id': value['group'].pk,
'document_name': document,
'static_url': settings.STATIC_URL,
'tags_template': tags_template if tags_template else u'',
'string': _(u'group document'),
})
output.append(u'</div>')
output.append(
u'<br /><span class="famfam active famfam-magnifier"></span>%s' %
ugettext(u'Click on the image for full size view of the first page.'))
return mark_safe(u''.join(output))
class DocumentDataGroupForm(forms.Form):
def __init__(self, *args, **kwargs):
groups = kwargs.pop('groups', None)
links = kwargs.pop('links', None)
current_document = kwargs.pop('current_document', None)
super(DocumentDataGroupForm, self).__init__(*args, **kwargs)
for group, data in groups.items():
self.fields['preview-%s' % group] = forms.CharField(
widget=DocumentGroupImageWidget(),
label=u'%s (%d)' % (unicode(data['title']), len(data['documents'])),
required=False,
initial={
'group': group,
'group_data': data['documents'],
'current_document': current_document,
'links': links
}
)

View File

@@ -1,198 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-09-29 18:45-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: __init__.py:8
msgid "group actions"
msgstr ""
#: __init__.py:9
msgid "groups"
msgstr ""
#: forms.py:55
msgid "Pages"
msgstr ""
#: forms.py:56
msgid "Select"
msgstr ""
#: forms.py:61
msgid "group document"
msgstr ""
#: forms.py:66
msgid "Click on the image for full size view of the first page."
msgstr ""
#: literals.py:7
msgid "and"
msgstr ""
#: literals.py:8
msgid "or"
msgstr ""
#: literals.py:12
msgid "is equal to"
msgstr ""
#: literals.py:13
msgid "is equal to (case insensitive)"
msgstr ""
#: literals.py:14
msgid "contains"
msgstr ""
#: literals.py:15
msgid "contains (case insensitive)"
msgstr ""
#: literals.py:16
msgid "is in"
msgstr ""
#: literals.py:17
msgid "is greater than"
msgstr ""
#: literals.py:18
msgid "is greater than or equal to"
msgstr ""
#: literals.py:19
msgid "is less than"
msgstr ""
#: literals.py:20
msgid "is less than or equal to"
msgstr ""
#: literals.py:21
msgid "starts with"
msgstr ""
#: literals.py:22
msgid "starts with (case insensitive)"
msgstr ""
#: literals.py:23
msgid "ends with"
msgstr ""
#: literals.py:24
msgid "ends with (case insensitive)"
msgstr ""
#: literals.py:25
msgid "is in regular expression"
msgstr ""
#: literals.py:26
msgid "is in regular expression (case insensitive)"
msgstr ""
#: models.py:10
msgid "title"
msgstr ""
#: models.py:11
msgid "dynamic title"
msgstr ""
#: models.py:12 models.py:33
msgid "enabled"
msgstr ""
#: models.py:20 models.py:25
msgid "document group"
msgstr ""
#: models.py:21
msgid "document groups"
msgstr ""
#: models.py:26
msgid "The inclusion is ignored for the first item."
msgstr ""
#: models.py:27
msgid "foreign document data"
msgstr ""
#: models.py:27
msgid ""
"This represents the metadata of all other documents. Available objects: "
"`document.<attribute>` and `metadata.<metadata_type_name>`."
msgstr ""
#: models.py:31
msgid "expression"
msgstr ""
#: models.py:31
msgid ""
"This expression will be evaluated against the current selected document. "
"The document metadata is available as variables `metadata` and document "
"properties under the variable `document`."
msgstr ""
#: models.py:32
msgid "negated"
msgstr ""
#: models.py:32
msgid "Inverts the logic of the operator."
msgstr ""
#: models.py:36
msgid "not"
msgstr ""
#: models.py:39
msgid "group item"
msgstr ""
#: models.py:40
msgid "group items"
msgstr ""
#: views.py:21
msgid "No action selected."
msgstr ""
#: views.py:34
#, python-format
msgid "documents in group: %(group)s"
msgstr ""
#: views.py:50
#, python-format
msgid "Document group query error: %s"
msgstr ""
#: views.py:61
#, python-format
msgid "document groups (%s)"
msgstr ""
#: views.py:75
msgid "There no defined groups for the current document."
msgstr ""

View File

@@ -1,208 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# Roberto Rosario <roberto.rosario.gonzalez@gmail.com>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
"POT-Creation-Date: 2011-09-29 18:45-0400\n"
"PO-Revision-Date: 2011-11-04 00:55+0000\n"
"Last-Translator: rosarior <roberto.rosario.gonzalez@gmail.com>\n"
"Language-Team: Spanish (Castilian) (http://www.transifex.net/projects/p/mayan-edms/team/es/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: es\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
#: __init__.py:8
msgid "group actions"
msgstr "acciones de grupo"
#: __init__.py:9
msgid "groups"
msgstr "grupos"
#: forms.py:55
msgid "Pages"
msgstr "Páginas"
#: forms.py:56
msgid "Select"
msgstr "Seleccionar"
#: forms.py:61
msgid "group document"
msgstr "documento del grupo"
#: forms.py:66
msgid "Click on the image for full size view of the first page."
msgstr ""
"Haga clic en la imagen para ver el tamaño completo de la primera página."
#: literals.py:7
msgid "and"
msgstr "y"
#: literals.py:8
msgid "or"
msgstr "o"
#: literals.py:12
msgid "is equal to"
msgstr "es igual a"
#: literals.py:13
msgid "is equal to (case insensitive)"
msgstr "es igual a (mayúsculas y minúsculas)"
#: literals.py:14
msgid "contains"
msgstr "contiene"
#: literals.py:15
msgid "contains (case insensitive)"
msgstr "contiene (mayúsculas y minúsculas)"
#: literals.py:16
msgid "is in"
msgstr "está en"
#: literals.py:17
msgid "is greater than"
msgstr "es mayor que"
#: literals.py:18
msgid "is greater than or equal to"
msgstr "es mayor o igual a"
#: literals.py:19
msgid "is less than"
msgstr "es menor que"
#: literals.py:20
msgid "is less than or equal to"
msgstr "es menor o igual a"
#: literals.py:21
msgid "starts with"
msgstr "comienza con"
#: literals.py:22
msgid "starts with (case insensitive)"
msgstr "comienza con (mayúsculas y minúsculas)"
#: literals.py:23
msgid "ends with"
msgstr "termina con"
#: literals.py:24
msgid "ends with (case insensitive)"
msgstr "termina con (mayúsculas y minúsculas)"
#: literals.py:25
msgid "is in regular expression"
msgstr "está en la expresión regular"
#: literals.py:26
msgid "is in regular expression (case insensitive)"
msgstr "está en la expresión regular (mayúsculas y minúsculas)"
#: models.py:10
msgid "title"
msgstr "título"
#: models.py:11
msgid "dynamic title"
msgstr "título dinámico"
#: models.py:12 models.py:33
msgid "enabled"
msgstr "habilitado"
#: models.py:20 models.py:25
msgid "document group"
msgstr "grupo de documento"
#: models.py:21
msgid "document groups"
msgstr "grupos de documentos"
#: models.py:26
msgid "The inclusion is ignored for the first item."
msgstr "La inclusión es ignorada para el primer artículo."
#: models.py:27
msgid "foreign document data"
msgstr "datos de documento foráneo"
#: models.py:27
msgid ""
"This represents the metadata of all other documents. Available objects: "
"`document.<attribute>` and `metadata.<metadata_type_name>`."
msgstr ""
"Esto representa los metadatos de todos los demás documentos. Objetos "
"disponibles: `document.<attributo>` y `metadata.<nombre de tipo de "
"metadata>`."
#: models.py:31
msgid "expression"
msgstr "expresión"
#: models.py:31
msgid ""
"This expression will be evaluated against the current selected document. "
"The document metadata is available as variables `metadata` and document "
"properties under the variable `document`."
msgstr ""
"Esta expresión sera evaluada con respecto al documento seleccionado actual."
" Los metadatos del documento están disponible como variables `metadata` y "
"las propiedades del documento en la variable `document`."
#: models.py:32
msgid "negated"
msgstr "negado"
#: models.py:32
msgid "Inverts the logic of the operator."
msgstr "Invierte la lógica del operador."
#: models.py:36
msgid "not"
msgstr "no"
#: models.py:39
msgid "group item"
msgstr "artículo del grupo"
#: models.py:40
msgid "group items"
msgstr "artículo del grupo"
#: views.py:21
msgid "No action selected."
msgstr "Ninguna acción seleccionada."
#: views.py:34
#, python-format
msgid "documents in group: %(group)s"
msgstr "documentos en el grupo: %(group)s "
#: views.py:50
#, python-format
msgid "Document group query error: %s"
msgstr "Error en consulta de grupo de documentos: %s"
#: views.py:61
#, python-format
msgid "document groups (%s)"
msgstr "grupos de documentos (%s)"
#: views.py:75
msgid "There no defined groups for the current document."
msgstr "No hay grupos definidos para el documento actual."

View File

@@ -1,206 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# <dev.emerson@gmail.com>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
"POT-Creation-Date: 2011-09-29 18:45-0400\n"
"PO-Revision-Date: 2011-11-02 05:05+0000\n"
"Last-Translator: emersonsoares <dev.emerson@gmail.com>\n"
"Language-Team: Portuguese (http://www.transifex.net/projects/p/mayan-edms/team/pt/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: pt\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
#: __init__.py:8
msgid "group actions"
msgstr "ações do grupo"
#: __init__.py:9
msgid "groups"
msgstr "grupos"
#: forms.py:55
msgid "Pages"
msgstr "Páginas"
#: forms.py:56
msgid "Select"
msgstr "Selecionar"
#: forms.py:61
msgid "group document"
msgstr "agrupar documento"
#: forms.py:66
msgid "Click on the image for full size view of the first page."
msgstr "Clique na imagem para ver em tamanho grande a primeira página."
#: literals.py:7
msgid "and"
msgstr "e"
#: literals.py:8
msgid "or"
msgstr "ou"
#: literals.py:12
msgid "is equal to"
msgstr "é igual a"
#: literals.py:13
msgid "is equal to (case insensitive)"
msgstr "é igual a (case insensitive)"
#: literals.py:14
msgid "contains"
msgstr "contém"
#: literals.py:15
msgid "contains (case insensitive)"
msgstr "contém (case insensitive)"
#: literals.py:16
msgid "is in"
msgstr "está em"
#: literals.py:17
msgid "is greater than"
msgstr "é maior do que"
#: literals.py:18
msgid "is greater than or equal to"
msgstr "é maior ou igual a"
#: literals.py:19
msgid "is less than"
msgstr "é inferior a"
#: literals.py:20
msgid "is less than or equal to"
msgstr "é menor ou igual a"
#: literals.py:21
msgid "starts with"
msgstr "começa com"
#: literals.py:22
msgid "starts with (case insensitive)"
msgstr "começa com (case insensitive)"
#: literals.py:23
msgid "ends with"
msgstr "termina com"
#: literals.py:24
msgid "ends with (case insensitive)"
msgstr "termina com (case insensitive)"
#: literals.py:25
msgid "is in regular expression"
msgstr "está em expressão regular"
#: literals.py:26
msgid "is in regular expression (case insensitive)"
msgstr "está em expressão regular (case insensitive)"
#: models.py:10
msgid "title"
msgstr "título"
#: models.py:11
msgid "dynamic title"
msgstr "título dinâmico"
#: models.py:12 models.py:33
msgid "enabled"
msgstr "habilitado"
#: models.py:20 models.py:25
msgid "document group"
msgstr "grupo de documentos"
#: models.py:21
msgid "document groups"
msgstr "grupos de documentos"
#: models.py:26
msgid "The inclusion is ignored for the first item."
msgstr "A inclusão é ignorada para o primeiro item."
#: models.py:27
msgid "foreign document data"
msgstr "dados de documentos estrangeiros"
#: models.py:27
msgid ""
"This represents the metadata of all other documents. Available objects: "
"`document.<attribute>` and `metadata.<metadata_type_name>`."
msgstr ""
"Isto representa os metadados de todos os outros documentos. Objetos "
"disponíveis: `document. <attribute> ` e ` metadata. <metadata_type_name> `."
#: models.py:31
msgid "expression"
msgstr "expressão"
#: models.py:31
msgid ""
"This expression will be evaluated against the current selected document. "
"The document metadata is available as variables `metadata` and document "
"properties under the variable `document`."
msgstr ""
"Esta expressão será avaliada em relação ao documento atual selecionado. Os "
"metadados do documento estão disponíveis como variáveis \"metadados \" e "
"propriedades do documento em variáveis `documento`."
#: models.py:32
msgid "negated"
msgstr "negada"
#: models.py:32
msgid "Inverts the logic of the operator."
msgstr "Inverte a lógica do operador."
#: models.py:36
msgid "not"
msgstr "não"
#: models.py:39
msgid "group item"
msgstr "item do grupo"
#: models.py:40
msgid "group items"
msgstr "itens do grupo"
#: views.py:21
msgid "No action selected."
msgstr "Nenhuma ação selecionada."
#: views.py:34
#, python-format
msgid "documents in group: %(group)s"
msgstr "documentos no grupo: %(group)s "
#: views.py:50
#, python-format
msgid "Document group query error: %s"
msgstr "Erro na consulta de grupo do documento: %s"
#: views.py:61
#, python-format
msgid "document groups (%s)"
msgstr "grupos do documento (%s)"
#: views.py:75
msgid "There no defined groups for the current document."
msgstr "Não há grupos definidos para o documento atual."

View File

@@ -1,207 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# Sergey Glita <gsv70@mail.ru>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
"POT-Creation-Date: 2011-09-29 18:45-0400\n"
"PO-Revision-Date: 2011-11-04 10:53+0000\n"
"Last-Translator: gsv70 <gsv70@mail.ru>\n"
"Language-Team: Russian (http://www.transifex.net/projects/p/mayan-edms/team/ru/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ru\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"
#: __init__.py:8
msgid "group actions"
msgstr "групповые действия"
#: __init__.py:9
msgid "groups"
msgstr "группы"
#: forms.py:55
msgid "Pages"
msgstr "Страницы"
#: forms.py:56
msgid "Select"
msgstr "Выбрать"
#: forms.py:61
msgid "group document"
msgstr "group document"
#: forms.py:66
msgid "Click on the image for full size view of the first page."
msgstr ""
"Нажмите на изображение для просмотра первой страницы в полном размере."
#: literals.py:7
msgid "and"
msgstr "и"
#: literals.py:8
msgid "or"
msgstr "или"
#: literals.py:12
msgid "is equal to"
msgstr "равно"
#: literals.py:13
msgid "is equal to (case insensitive)"
msgstr "равно (без учета регистра)"
#: literals.py:14
msgid "contains"
msgstr "содержит"
#: literals.py:15
msgid "contains (case insensitive)"
msgstr "содержит (без учета регистра)"
#: literals.py:16
msgid "is in"
msgstr "находится в"
#: literals.py:17
msgid "is greater than"
msgstr "больше"
#: literals.py:18
msgid "is greater than or equal to"
msgstr "больше или равно"
#: literals.py:19
msgid "is less than"
msgstr "меньше"
#: literals.py:20
msgid "is less than or equal to"
msgstr "меньше или равно"
#: literals.py:21
msgid "starts with"
msgstr "начинается с"
#: literals.py:22
msgid "starts with (case insensitive)"
msgstr "начинается с (без учета регистра)"
#: literals.py:23
msgid "ends with"
msgstr "заканчивается на"
#: literals.py:24
msgid "ends with (case insensitive)"
msgstr "заканчивается на (без учета регистра)"
#: literals.py:25
msgid "is in regular expression"
msgstr "В регулярном выражении"
#: literals.py:26
msgid "is in regular expression (case insensitive)"
msgstr "В регулярном выражении (без учета регистра)"
#: models.py:10
msgid "title"
msgstr "название"
#: models.py:11
msgid "dynamic title"
msgstr "динамический заголовок"
#: models.py:12 models.py:33
msgid "enabled"
msgstr "разрешено"
#: models.py:20 models.py:25
msgid "document group"
msgstr "document group"
#: models.py:21
msgid "document groups"
msgstr "document groups"
#: models.py:26
msgid "The inclusion is ignored for the first item."
msgstr "Включение игнорируется для первого элемента."
#: models.py:27
msgid "foreign document data"
msgstr "foreign document data"
#: models.py:27
msgid ""
"This represents the metadata of all other documents. Available objects: "
"`document.<attribute>` and `metadata.<metadata_type_name>`."
msgstr ""
"Это представляет метаданные всех других документов. Доступные объекты: "
"`document. <attribute> ` и `metadata. <metadata_type_name> `."
#: models.py:31
msgid "expression"
msgstr "выражение"
#: models.py:31
msgid ""
"This expression will be evaluated against the current selected document. "
"The document metadata is available as variables `metadata` and document "
"properties under the variable `document`."
msgstr ""
"Это выражение будет вычислено вмето выбранного документа. Метаданные "
"документа доступны как переменные `metadata` и свойства документа в "
"переменной `document`."
#: models.py:32
msgid "negated"
msgstr "отрицание"
#: models.py:32
msgid "Inverts the logic of the operator."
msgstr "Инвертирует логику оператора."
#: models.py:36
msgid "not"
msgstr "не"
#: models.py:39
msgid "group item"
msgstr "член группы"
#: models.py:40
msgid "group items"
msgstr "члены группы"
#: views.py:21
msgid "No action selected."
msgstr "Никаких действий не выбрано."
#: views.py:34
#, python-format
msgid "documents in group: %(group)s"
msgstr "Документы в группе: %(group)s"
#: views.py:50
#, python-format
msgid "Document group query error: %s"
msgstr "Документ группы запросов ошибка: %s"
#: views.py:61
#, python-format
msgid "document groups (%s)"
msgstr "группы документов (%s)"
#: views.py:75
msgid "There no defined groups for the current document."
msgstr "Для текущего документа не выбрана группа"

View File

@@ -1,7 +0,0 @@
from django.conf.urls.defaults import patterns, url
urlpatterns = patterns('grouping.views',
url(r'^action/$', 'document_group_action', (), 'document_group_action'),
url(r'^document/(?P<document_id>\d+)/group/(?P<document_group_id>\d+)/$', 'document_group_view', (), 'document_group_view'),
url(r'^groups/for_document/(?P<document_id>\d+)/$', 'groups_for_document', (), 'groups_for_document'),
)

View File

@@ -1,83 +0,0 @@
from django.utils.translation import ugettext_lazy as _
from django.contrib import messages
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render_to_response
from django.core.urlresolvers import reverse
from django.template import RequestContext
from documents.models import Document
from documents.views import document_list
from grouping.models import DocumentGroup
from grouping.conf.settings import SHOW_EMPTY_GROUPS
from grouping.forms import DocumentDataGroupForm
from grouping import document_group_link
def document_group_action(request):
action = request.GET.get('action', None)
if not action:
messages.error(request, _(u'No action selected.'))
return HttpResponseRedirect(request.META.get('HTTP_REFERER', u'/'))
return HttpResponseRedirect(action)
def document_group_view(request, document_id, document_group_id):
document = get_object_or_404(Document, pk=document_id)
document_group = get_object_or_404(DocumentGroup, pk=document_group_id)
object_list, errors = DocumentGroup.objects.get_groups_for(document, document_group)
return document_list(
request,
title=_(u'documents in group: %(group)s') % {
'group': object_list['title']
},
object_list=object_list['documents'],
extra_context={
'object': document
}
)
def groups_for_document(request, document_id):
subtemplates_list = []
document = get_object_or_404(Document, pk=document_id)
document_groups, errors = DocumentGroup.objects.get_groups_for(document)
if (request.user.is_staff or request.user.is_superuser) and errors:
for error in errors:
messages.warning(request, _(u'Document group query error: %s' % error))
if not SHOW_EMPTY_GROUPS:
#If GROUP_SHOW_EMPTY is False, remove empty groups from
#dictionary
document_groups = dict([(group, data) for group, data in document_groups.items() if data['documents']])
if document_groups:
subtemplates_list = [{
'name': 'generic_form_subtemplate.html',
'context': {
'title': _(u'document groups (%s)') % len(document_groups.keys()),
'form': DocumentDataGroupForm(
groups=document_groups, current_document=document,
links=[document_group_link]
),
'form_action': reverse('document_group_action'),
'submit_method': 'GET',
}
}]
else:
# If there are not group display a placeholder messages saying so
subtemplates_list = [{
'name': 'generic_subtemplate.html',
'context': {
'content': _(u'There no defined groups for the current document.'),
}
}]
return render_to_response('generic_detail.html', {
'object': document,
'document': document,
'subtemplates_list': subtemplates_list,
}, context_instance=RequestContext(request))

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-09-29 18:46-0400\n"
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"

View File

@@ -1,20 +1,21 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
"POT-Creation-Date: 2011-09-29 18:46-0400\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
"PO-Revision-Date: 2011-09-30 05:10+0000\n"
"Last-Translator: rosarior <roberto.rosario.gonzalez@gmail.com>\n"
"Language-Team: Spanish (Castilian) (http://www.transifex.net/projects/p/mayan-edms/team/es/)\n"
"Language-Team: Spanish (Castilian) (http://www.transifex.net/projects/p/"
"mayan-edms/team/es/)\n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: es\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
#: __init__.py:6
@@ -102,5 +103,3 @@ msgstr "Detalles del evento"
#, python-format
msgid "details for: %s"
msgstr "Detalles para: %s"

View File

@@ -1,21 +1,22 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
#
# Translators:
# <dev.emerson@gmail.com>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
"POT-Creation-Date: 2011-09-29 18:46-0400\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
"PO-Revision-Date: 2011-11-03 03:22+0000\n"
"Last-Translator: emersonsoares <dev.emerson@gmail.com>\n"
"Language-Team: Portuguese (http://www.transifex.net/projects/p/mayan-edms/team/pt/)\n"
"Language-Team: Portuguese (http://www.transifex.net/projects/p/mayan-edms/"
"team/pt/)\n"
"Language: pt\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: pt\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
#: __init__.py:6
@@ -103,5 +104,3 @@ msgstr "Detalhes do evento"
#, python-format
msgid "details for: %s"
msgstr "detalhes para: %s"

View File

@@ -1,21 +1,23 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
"POT-Creation-Date: 2011-09-29 18:46-0400\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
"PO-Revision-Date: 2011-11-03 23:30+0000\n"
"Last-Translator: gsv70 <gsv70@mail.ru>\n"
"Language-Team: Russian (http://www.transifex.net/projects/p/mayan-edms/team/ru/)\n"
"Language-Team: Russian (http://www.transifex.net/projects/p/mayan-edms/team/"
"ru/)\n"
"Language: ru\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ru\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"
"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"
#: __init__.py:6
msgid "Access the history app"
@@ -102,5 +104,3 @@ msgstr "Подробности события"
#, python-format
msgid "details for: %s"
msgstr "подробности: %s"

44
apps/linking/__init__.py Normal file
View File

@@ -0,0 +1,44 @@
from django.utils.translation import ugettext_lazy as _
from navigation.api import register_links, register_sidebar_template
from permissions.api import register_permission, set_namespace_title
from project_setup.api import register_setup
from documents.literals import PERMISSION_DOCUMENT_VIEW
from documents.models import Document
from linking.models import SmartLink, SmartLinkCondition
PERMISSION_SMART_LINK_VIEW = {'namespace': 'linking', 'name': 'smart_link_view', 'label': _(u'View existing smart links')}
PERMISSION_SMART_LINK_CREATE = {'namespace': 'linking', 'name': 'smart_link_create', 'label': _(u'Create new smart links')}
PERMISSION_SMART_LINK_DELETE = {'namespace': 'linking', 'name': 'smart_link_delete', 'label': _(u'Delete smart links')}
PERMISSION_SMART_LINK_EDIT = {'namespace': 'linking', 'name': 'smart_link_edit', 'label': _(u'Edit smart links')}
set_namespace_title('linking', _(u'Smart links'))
register_permission(PERMISSION_SMART_LINK_VIEW)
register_permission(PERMISSION_SMART_LINK_CREATE)
register_permission(PERMISSION_SMART_LINK_DELETE)
register_permission(PERMISSION_SMART_LINK_EDIT)
smart_link_instance_view_link = {'text': _(u'smart links actions'), 'view': 'smart_link_instance_view', 'famfam': 'page_link', 'permissions': [PERMISSION_DOCUMENT_VIEW]}
smart_link_instances_for_document = {'text': _(u'smart links'), 'view': 'smart_link_instances_for_document', 'args': 'object.pk', 'famfam': 'page_link', 'permissions': [PERMISSION_DOCUMENT_VIEW]}
smart_link_setup = {'text': _(u'smart links'), 'view': 'smart_link_list', 'icon': 'link.png', 'permissions': [PERMISSION_SMART_LINK_CREATE]}
smart_link_list = {'text': _(u'smart links list'), 'view': 'smart_link_list', 'famfam': 'link', 'permissions': [PERMISSION_SMART_LINK_CREATE]}
smart_link_create = {'text': _(u'create new smart link'), 'view': 'smart_link_create', 'famfam': 'link_add', 'permissions': [PERMISSION_SMART_LINK_CREATE]}
smart_link_edit = {'text': _(u'edit'), 'view': 'smart_link_edit', 'args': 'smart_link.pk', 'famfam': 'link_edit', 'permissions': [PERMISSION_SMART_LINK_EDIT]}
smart_link_delete = {'text': _(u'delete'), 'view': 'smart_link_delete', 'args': 'smart_link.pk', 'famfam': 'link_delete', 'permissions': [PERMISSION_SMART_LINK_DELETE]}
smart_link_condition_list = {'text': _(u'conditions'), 'view': 'smart_link_condition_list', 'args': 'smart_link.pk', 'famfam': 'cog', 'permissions': [PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_CREATE]}
smart_link_condition_create = {'text': _(u'create condition'), 'view': 'smart_link_condition_create', 'args': 'smart_link.pk', 'famfam': 'cog_add', 'permissions': [PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT]}
smart_link_condition_edit = {'text': _(u'edit'), 'view': 'smart_link_condition_edit', 'args': 'condition.pk', 'famfam': 'cog_edit', 'permissions': [PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT]}
smart_link_condition_delete = {'text': _(u'delete'), 'view': 'smart_link_condition_delete', 'args': 'condition.pk', 'famfam': 'cog_delete', 'permissions': [PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT]}
register_links(Document, [smart_link_instances_for_document], menu_name='form_header')
register_links(SmartLink, [smart_link_edit, smart_link_delete, smart_link_condition_list])
register_links(SmartLinkCondition, [smart_link_condition_edit, smart_link_condition_delete])
register_links(['smart_link_list', 'smart_link_create', 'smart_link_edit', 'smart_link_delete', 'smart_link_condition_list', 'smart_link_condition_create', 'smart_link_condition_edit', 'smart_link_condition_delete'], [smart_link_list, smart_link_create], menu_name='sidebar')
register_links(['smart_link_condition_list', 'smart_link_condition_create', 'smart_link_condition_edit', 'smart_link_condition_delete'], [smart_link_condition_create], menu_name='sidebar')
register_setup(smart_link_setup)
register_sidebar_template(['smart_link_list'], 'smart_links_help.html')

16
apps/linking/admin.py Normal file
View File

@@ -0,0 +1,16 @@
from django.contrib import admin
from linking.models import SmartLink, SmartLinkCondition
class SmartLinkConditionInline(admin.StackedInline):
model = SmartLinkCondition
extra = 1
classes = ('collapse-open',)
allow_add = True
class SmartLinkAdmin(admin.ModelAdmin):
inlines = [SmartLinkConditionInline]
admin.site.register(SmartLink, SmartLinkAdmin)

View File

@@ -0,0 +1,13 @@
'''Configuration options for the linking app'''
from django.utils.translation import ugettext_lazy as _
from smart_settings.api import register_settings
register_settings(
namespace=u'linking',
module=u'linking.conf.settings',
settings=[
{'name': u'SHOW_EMPTY_SMART_LINKS', 'global_name': u'LINKING_SHOW_EMPTY_SMART_LINKS', 'default': True, 'description': _(u'Show smart link that don\'t return any documents.')},
]
)

85
apps/linking/forms.py Normal file
View File

@@ -0,0 +1,85 @@
from django import forms
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext
from django.core.urlresolvers import reverse
from django.utils.safestring import mark_safe
from django.template.defaultfilters import capfirst
from django.conf import settings
from documents.widgets import document_html_widget
from tags.widgets import get_tags_inline_widget
from linking.models import SmartLink, SmartLinkCondition
class SmartLinkForm(forms.ModelForm):
class Meta:
model = SmartLink
class SmartLinkConditionForm(forms.ModelForm):
class Meta:
model = SmartLinkCondition
exclude = ('smart_link',)
class SmartLinkImageWidget(forms.widgets.Widget):
def render(self, name, value, attrs=None):
output = []
# TODO: convert to navigation app
if value['links']:
output.append(u'<div class="group navform wat-cf">')
for link in value['links']:
output.append(u'''
<button class="button" type="submit" name="action" value="%(action)s">
<span class="famfam active famfam-%(famfam)s"></span>%(text)s
</button>
''' % {
'famfam': link.get('famfam', u'link'),
'text': capfirst(link['text']),
'action': reverse(link.get('view'), args=[value['current_document'].pk, value['smart_link_instance'].pk])
})
output.append(u'</div>')
output.append(u'<div style="white-space:nowrap; overflow: auto;">')
for document in value['documents']:
output.append(u'<div style="display: inline-block; margin: 0px 10px 10px 10px; %s">' % (u'border: 5px solid black; padding: 3px;' if value['current_document'] == document else u''))
output.append(u'<div class="tc">%s</div>' % document)
output.append(u'<div class="tc">%s: %d</div>' % (ugettext(u'Pages'), document.documentpage_set.count()))
output.append(get_tags_inline_widget(document))
output.append(u'<div style="padding: 5px;">' % document)
output.append(document_html_widget(document, click_view='document_display', view='document_preview_multipage', fancybox_class='fancybox-noscaling', gallery_name=u'smart_link_%d_documents_gallery' % value['smart_link_instance'].pk))
output.append(u'</div>')
output.append(u'<div class="tc">')
output.append(u'<a href="%s"><span class="famfam active famfam-page_go"></span>%s</a>' % (reverse('document_view_simple', args=[document.pk]), ugettext(u'Select')))
output.append(u'</div>')
output.append(u'</div>')
output.append(u'</div>')
output.append(
u'<br /><span class="famfam active famfam-magnifier"></span>%s' %
ugettext(u'Click on the image for full size view of the first page.'))
return mark_safe(u''.join(output))
class SmartLinkInstanceForm(forms.Form):
def __init__(self, *args, **kwargs):
smart_link_instances = kwargs.pop('smart_link_instances', None)
links = kwargs.pop('links', None)
current_document = kwargs.pop('current_document', None)
super(SmartLinkInstanceForm, self).__init__(*args, **kwargs)
for smart_link_instance, data in smart_link_instances.items():
self.fields['preview-%s' % smart_link_instance] = forms.CharField(
widget=SmartLinkImageWidget(),
label=u'%s (%d)' % (unicode(data['title']), len(data['documents'])),
required=False,
initial={
'smart_link_instance': smart_link_instance,
'documents': data['documents'],
'current_document': current_document,
'links': links
}
)

View File

@@ -0,0 +1,329 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: __init__.py:11
msgid "View existing smart links"
msgstr ""
#: __init__.py:12
msgid "Create new smart links"
msgstr ""
#: __init__.py:13
msgid "Delete smart links"
msgstr ""
#: __init__.py:14
msgid "Edit smart links"
msgstr ""
#: __init__.py:16
msgid "Smart links"
msgstr ""
#: __init__.py:22
msgid "smart links actions"
msgstr ""
#: __init__.py:23 __init__.py:25 models.py:21 views.py:105
msgid "smart links"
msgstr ""
#: __init__.py:26
msgid "smart links list"
msgstr ""
#: __init__.py:27
msgid "create new smart link"
msgstr ""
#: __init__.py:28 __init__.py:33
msgid "edit"
msgstr ""
#: __init__.py:29 __init__.py:34
msgid "delete"
msgstr ""
#: __init__.py:31
msgid "conditions"
msgstr ""
#: __init__.py:32
msgid "create condition"
msgstr ""
#: forms.py:48
msgid "Pages"
msgstr ""
#: forms.py:54
msgid "Select"
msgstr ""
#: forms.py:61
msgid "Click on the image for full size view of the first page."
msgstr ""
#: literals.py:7
msgid "and"
msgstr ""
#: literals.py:8
msgid "or"
msgstr ""
#: literals.py:12
msgid "is equal to"
msgstr ""
#: literals.py:13
msgid "is equal to (case insensitive)"
msgstr ""
#: literals.py:14
msgid "contains"
msgstr ""
#: literals.py:15
msgid "contains (case insensitive)"
msgstr ""
#: literals.py:16
msgid "is in"
msgstr ""
#: literals.py:17
msgid "is greater than"
msgstr ""
#: literals.py:18
msgid "is greater than or equal to"
msgstr ""
#: literals.py:19
msgid "is less than"
msgstr ""
#: literals.py:20
msgid "is less than or equal to"
msgstr ""
#: literals.py:21
msgid "starts with"
msgstr ""
#: literals.py:22
msgid "starts with (case insensitive)"
msgstr ""
#: literals.py:23
msgid "ends with"
msgstr ""
#: literals.py:24
msgid "ends with (case insensitive)"
msgstr ""
#: literals.py:25
msgid "is in regular expression"
msgstr ""
#: literals.py:26
msgid "is in regular expression (case insensitive)"
msgstr ""
#: models.py:10
msgid "title"
msgstr ""
#: models.py:11 views.py:108
msgid "dynamic title"
msgstr ""
#: models.py:11 models.py:29
msgid ""
"This expression will be evaluated against the current selected document. "
"The document metadata is available as variables `metadata` and document "
"properties under the variable `document`."
msgstr ""
#: models.py:12 models.py:31 views.py:109 views.py:196
msgid "enabled"
msgstr ""
#: models.py:20 models.py:25 views.py:256 views.py:287
msgid "smart link"
msgstr ""
#: models.py:26
msgid "The inclusion is ignored for the first item."
msgstr ""
#: models.py:27
msgid "foreign document data"
msgstr ""
#: models.py:27
msgid ""
"This represents the metadata of all other documents. Available objects: "
"`document.<attribute>` and `metadata.<metadata_type_name>`."
msgstr ""
#: models.py:29
msgid "expression"
msgstr ""
#: models.py:30
msgid "negated"
msgstr ""
#: models.py:30
msgid "Inverts the logic of the operator."
msgstr ""
#: models.py:34
msgid "not"
msgstr ""
#: models.py:37
msgid "link condition"
msgstr ""
#: models.py:38
msgid "link conditions"
msgstr ""
#: views.py:32
msgid "No action selected."
msgstr ""
#: views.py:47
#, python-format
msgid "documents in smart link: %(group)s"
msgstr ""
#: views.py:65
#, python-format
msgid "Smart link query error: %s"
msgstr ""
#: views.py:76
#, python-format
msgid "smart links (%s)"
msgstr ""
#: views.py:90
msgid "There no defined smart links for the current document."
msgstr ""
#: views.py:124
#, python-format
msgid "Smart link: %s created successfully."
msgstr ""
#: views.py:131
msgid "Create new smart link"
msgstr ""
#: views.py:144
#, python-format
msgid "Smart link: %s edited successfully."
msgstr ""
#: views.py:153
#, python-format
msgid "Edit smart link: %s"
msgstr ""
#: views.py:168
#, python-format
msgid "Smart link: %s deleted successfully."
msgstr ""
#: views.py:170
#, python-format
msgid "Error deleting smart link: %(smart_link)s; %(error)s."
msgstr ""
#: views.py:180
#, python-format
msgid "Are you sure you wish to delete smart link: %s?"
msgstr ""
#: views.py:193
#, python-format
msgid "conditions for smart link: %s"
msgstr ""
#: views.py:216
#, python-format
msgid "Smart link condition: \"%s\" created successfully."
msgstr ""
#: views.py:223
#, python-format
msgid "Add new conditions to smart link: \"%s\""
msgstr ""
#: views.py:243
#, python-format
msgid "Smart link condition: \"%s\" edited successfully."
msgstr ""
#: views.py:250
msgid "Edit smart link condition"
msgstr ""
#: views.py:257 views.py:288
msgid "condition"
msgstr ""
#: views.py:274
#, python-format
msgid "Smart link condition: \"%s\" deleted successfully."
msgstr ""
#: views.py:276
#, python-format
msgid ""
"Error deleting smart link condition: %(smart_link_condition)s; %(error)s."
msgstr ""
#: views.py:290
#, python-format
msgid "Are you sure you wish to delete smart link condition: \"%s\"?"
msgstr ""
#: conf/settings.py:11
msgid "Show smart link that don't return any documents."
msgstr ""
#: templates/smart_links_help.html:3
msgid "What are smart links?"
msgstr ""
#: templates/smart_links_help.html:4
msgid ""
"Smart links are a set of conditional statements that are used to query the "
"database using the current document the user is accessing as the data "
"source, the results of these queries are a list of documents that relate in "
"some manner to the document being displayed and allow users the ability to "
"jump to and from linked documents very easily."
msgstr ""

Binary file not shown.

View File

@@ -0,0 +1,351 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# Roberto Rosario <roberto.rosario.gonzalez@gmail.com>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
"PO-Revision-Date: 2011-11-22 20:56+0000\n"
"Last-Translator: rosarior <roberto.rosario.gonzalez@gmail.com>\n"
"Language-Team: Spanish (Castilian) (http://www.transifex.net/projects/p/mayan-edms/team/es/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: es\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
#: __init__.py:11
msgid "View existing smart links"
msgstr "Ver enlaces inteligentes existentes"
#: __init__.py:12
msgid "Create new smart links"
msgstr "Crear nuevos enlaces inteligentes"
#: __init__.py:13
msgid "Delete smart links"
msgstr "Eliminar enlaces inteligentes"
#: __init__.py:14
msgid "Edit smart links"
msgstr "Editar enlaces inteligentes"
#: __init__.py:16
msgid "Smart links"
msgstr "Enlaces inteligentes"
#: __init__.py:22
msgid "smart links actions"
msgstr "acciones de enlaces inteligentes"
#: __init__.py:23 __init__.py:25 models.py:21 views.py:105
msgid "smart links"
msgstr "enlaces inteligentes"
#: __init__.py:26
msgid "smart links list"
msgstr "lista de enlaces inteligentes"
#: __init__.py:27
msgid "create new smart link"
msgstr "crear un enlace inteligente nuevo"
#: __init__.py:28 __init__.py:33
msgid "edit"
msgstr "editar"
#: __init__.py:29 __init__.py:34
msgid "delete"
msgstr "borrar"
#: __init__.py:31
msgid "conditions"
msgstr "condiciones"
#: __init__.py:32
msgid "create condition"
msgstr "crear condicion"
#: forms.py:48
msgid "Pages"
msgstr "Páginas"
#: forms.py:54
msgid "Select"
msgstr "Seleccionar"
#: forms.py:61
msgid "Click on the image for full size view of the first page."
msgstr ""
"Haga clic en la imagen para ver el tamaño completo de la primera página."
#: literals.py:7
msgid "and"
msgstr "y"
#: literals.py:8
msgid "or"
msgstr "o"
#: literals.py:12
msgid "is equal to"
msgstr "es igual a"
#: literals.py:13
msgid "is equal to (case insensitive)"
msgstr "es igual a (mayúsculas y minúsculas)"
#: literals.py:14
msgid "contains"
msgstr "contiene"
#: literals.py:15
msgid "contains (case insensitive)"
msgstr "contiene (mayúsculas y minúsculas)"
#: literals.py:16
msgid "is in"
msgstr "está en"
#: literals.py:17
msgid "is greater than"
msgstr "es mayor que"
#: literals.py:18
msgid "is greater than or equal to"
msgstr "es mayor o igual a"
#: literals.py:19
msgid "is less than"
msgstr "es menor que"
#: literals.py:20
msgid "is less than or equal to"
msgstr "es menor o igual a"
#: literals.py:21
msgid "starts with"
msgstr "comienza con"
#: literals.py:22
msgid "starts with (case insensitive)"
msgstr "comienza con (mayúsculas y minúsculas)"
#: literals.py:23
msgid "ends with"
msgstr "termina con"
#: literals.py:24
msgid "ends with (case insensitive)"
msgstr "termina con (mayúsculas y minúsculas)"
#: literals.py:25
msgid "is in regular expression"
msgstr "está en la expresión regular"
#: literals.py:26
msgid "is in regular expression (case insensitive)"
msgstr "está en la expresión regular (mayúsculas y minúsculas)"
#: models.py:10
msgid "title"
msgstr "título"
#: models.py:11 views.py:108
msgid "dynamic title"
msgstr "título dinámico"
#: models.py:11 models.py:29
msgid ""
"This expression will be evaluated against the current selected document. "
"The document metadata is available as variables `metadata` and document "
"properties under the variable `document`."
msgstr ""
"Esta expresión sera evaluada con respecto al documento seleccionado actual."
" Los metadatos del documento están disponible como variables `metadata` y "
"las propiedades del documento en la variable `document`."
#: models.py:12 models.py:31 views.py:109 views.py:196
msgid "enabled"
msgstr "habilitado"
#: models.py:20 models.py:25 views.py:256 views.py:287
msgid "smart link"
msgstr "enlace inteligente"
#: models.py:26
msgid "The inclusion is ignored for the first item."
msgstr "La inclusión es ignorada para el primer artículo."
#: models.py:27
msgid "foreign document data"
msgstr "datos de documento foráneo"
#: models.py:27
msgid ""
"This represents the metadata of all other documents. Available objects: "
"`document.<attribute>` and `metadata.<metadata_type_name>`."
msgstr ""
"Esto representa los metadatos de todos los demás documentos. Objetos "
"disponibles: `document.<attributo>` y `metadata.<nombre de tipo de "
"metadata>`."
#: models.py:29
msgid "expression"
msgstr "expresión"
#: models.py:30
msgid "negated"
msgstr "negado"
#: models.py:30
msgid "Inverts the logic of the operator."
msgstr "Invierte la lógica del operador."
#: models.py:34
msgid "not"
msgstr "no"
#: models.py:37
msgid "link condition"
msgstr "condición de enlace"
#: models.py:38
msgid "link conditions"
msgstr "condiciones de enlace"
#: views.py:32
msgid "No action selected."
msgstr "Ninguna acción seleccionada."
#: views.py:47
#, python-format
msgid "documents in smart link: %(group)s"
msgstr "documentos en el enlace inteligente: %(group)s"
#: views.py:65
#, python-format
msgid "Smart link query error: %s"
msgstr "Error en consulta de enlace inteligente: %s"
#: views.py:76
#, python-format
msgid "smart links (%s)"
msgstr "enlaces inteligentes (%s)"
#: views.py:90
msgid "There no defined smart links for the current document."
msgstr "No hay enlaces inteligentes definidos para el documento actual."
#: views.py:124
#, python-format
msgid "Smart link: %s created successfully."
msgstr "Enlace inteligente: %s creado exitosamente."
#: views.py:131
msgid "Create new smart link"
msgstr "Crear un enlace inteligente nuevo"
#: views.py:144
#, python-format
msgid "Smart link: %s edited successfully."
msgstr "Enlace inteligente: %s editado exitosamente."
#: views.py:153
#, python-format
msgid "Edit smart link: %s"
msgstr "Editar enlace inteligente: %s"
#: views.py:168
#, python-format
msgid "Smart link: %s deleted successfully."
msgstr "Enlace inteligente: %s eliminado exitosamente."
#: views.py:170
#, python-format
msgid "Error deleting smart link: %(smart_link)s; %(error)s."
msgstr ""
"Error al tratar de eliminar enlace inteligente: %(smart_link)s; %(error)s."
#: views.py:180
#, python-format
msgid "Are you sure you wish to delete smart link: %s?"
msgstr "¿Está seguro que desea eliminar el enlace inteligente: %s?"
#: views.py:193
#, python-format
msgid "conditions for smart link: %s"
msgstr "condiciones de enlace inteligente: %s"
#: views.py:216
#, python-format
msgid "Smart link condition: \"%s\" created successfully."
msgstr "Condición de enlace inteligente: \"%s\" creada exitosamente."
#: views.py:223
#, python-format
msgid "Add new conditions to smart link: \"%s\""
msgstr "Añadir nuevas condiciones de enlace inteligente: \"%s\""
#: views.py:243
#, python-format
msgid "Smart link condition: \"%s\" edited successfully."
msgstr "Condición de enlace inteligente: \"%s\", editada exitosamente."
#: views.py:250
msgid "Edit smart link condition"
msgstr "Editar condición de enlace inteligente"
#: views.py:257 views.py:288
msgid "condition"
msgstr "condición"
#: views.py:274
#, python-format
msgid "Smart link condition: \"%s\" deleted successfully."
msgstr "Condición de enlace inteligente: \"%s\" ha eliminada exitosamente."
#: views.py:276
#, python-format
msgid ""
"Error deleting smart link condition: %(smart_link_condition)s; %(error)s."
msgstr ""
"Error al tratar de eliminar la condición de enlace inteligente: "
"%(smart_link_condition)s; %(error)s."
#: views.py:290
#, python-format
msgid "Are you sure you wish to delete smart link condition: \"%s\"?"
msgstr ""
"¿Está seguro que desea eliminar la condición de enlace inteligente: \"%s\"?"
#: conf/settings.py:11
msgid "Show smart link that don't return any documents."
msgstr ""
"Mostrar enlace inteligente que no devuelven ningun documentos como "
"resultado."
#: templates/smart_links_help.html:3
msgid "What are smart links?"
msgstr "¿Qué son los enlaces inteligentes?"
#: templates/smart_links_help.html:4
msgid ""
"Smart links are a set of conditional statements that are used to query the "
"database using the current document the user is accessing as the data "
"source, the results of these queries are a list of documents that relate in "
"some manner to the document being displayed and allow users the ability to "
"jump to and from linked documents very easily."
msgstr ""
"Enlaces inteligentes son un conjunto de condiciones que se utilizan para "
"consultar la base de datos en relacion al documento actual que el usuario "
"está accediendo, los resultados de estas consultas son una lista de "
"documentos que se relacionan de alguna manera al documento que se muestra y "
"permite a los usuarios la capacidad de navegar entre los documentos "
"vinculados con mucha facilidad."

View File

@@ -0,0 +1,361 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# <dev.emerson@gmail.com>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
"PO-Revision-Date: 2011-11-02 05:05+0000\n"
"Last-Translator: emersonsoares <dev.emerson@gmail.com>\n"
"Language-Team: Portuguese (http://www.transifex.net/projects/p/mayan-edms/"
"team/pt/)\n"
"Language: pt\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
#: __init__.py:11
msgid "View existing smart links"
msgstr ""
#: __init__.py:12
msgid "Create new smart links"
msgstr ""
#: __init__.py:13
msgid "Delete smart links"
msgstr ""
#: __init__.py:14
msgid "Edit smart links"
msgstr ""
#: __init__.py:16
msgid "Smart links"
msgstr ""
#: __init__.py:22
msgid "smart links actions"
msgstr ""
#: __init__.py:23 __init__.py:25 models.py:21 views.py:105
msgid "smart links"
msgstr ""
#: __init__.py:26
msgid "smart links list"
msgstr ""
#: __init__.py:27
msgid "create new smart link"
msgstr ""
#: __init__.py:28 __init__.py:33
msgid "edit"
msgstr ""
#: __init__.py:29 __init__.py:34
msgid "delete"
msgstr ""
#: __init__.py:31
msgid "conditions"
msgstr ""
#: __init__.py:32
msgid "create condition"
msgstr ""
#: forms.py:48
msgid "Pages"
msgstr "Páginas"
#: forms.py:54
msgid "Select"
msgstr "Selecionar"
#: forms.py:61
msgid "Click on the image for full size view of the first page."
msgstr "Clique na imagem para ver em tamanho grande a primeira página."
#: literals.py:7
msgid "and"
msgstr "e"
#: literals.py:8
msgid "or"
msgstr "ou"
#: literals.py:12
msgid "is equal to"
msgstr "é igual a"
#: literals.py:13
msgid "is equal to (case insensitive)"
msgstr "é igual a (case insensitive)"
#: literals.py:14
msgid "contains"
msgstr "contém"
#: literals.py:15
msgid "contains (case insensitive)"
msgstr "contém (case insensitive)"
#: literals.py:16
msgid "is in"
msgstr "está em"
#: literals.py:17
msgid "is greater than"
msgstr "é maior do que"
#: literals.py:18
msgid "is greater than or equal to"
msgstr "é maior ou igual a"
#: literals.py:19
msgid "is less than"
msgstr "é inferior a"
#: literals.py:20
msgid "is less than or equal to"
msgstr "é menor ou igual a"
#: literals.py:21
msgid "starts with"
msgstr "começa com"
#: literals.py:22
msgid "starts with (case insensitive)"
msgstr "começa com (case insensitive)"
#: literals.py:23
msgid "ends with"
msgstr "termina com"
#: literals.py:24
msgid "ends with (case insensitive)"
msgstr "termina com (case insensitive)"
#: literals.py:25
msgid "is in regular expression"
msgstr "está em expressão regular"
#: literals.py:26
msgid "is in regular expression (case insensitive)"
msgstr "está em expressão regular (case insensitive)"
#: models.py:10
msgid "title"
msgstr "título"
#: models.py:11 views.py:108
msgid "dynamic title"
msgstr "título dinâmico"
#: models.py:11 models.py:29
msgid ""
"This expression will be evaluated against the current selected document. "
"The document metadata is available as variables `metadata` and document "
"properties under the variable `document`."
msgstr ""
"Esta expressão será avaliada em relação ao documento atual selecionado. Os "
"metadados do documento estão disponíveis como variáveis \"metadados \" e "
"propriedades do documento em variáveis `documento`."
#: models.py:12 models.py:31 views.py:109 views.py:196
msgid "enabled"
msgstr "habilitado"
#: models.py:20 models.py:25 views.py:256 views.py:287
msgid "smart link"
msgstr ""
#: models.py:26
msgid "The inclusion is ignored for the first item."
msgstr "A inclusão é ignorada para o primeiro item."
#: models.py:27
msgid "foreign document data"
msgstr "dados de documentos estrangeiros"
#: models.py:27
msgid ""
"This represents the metadata of all other documents. Available objects: "
"`document.<attribute>` and `metadata.<metadata_type_name>`."
msgstr ""
"Isto representa os metadados de todos os outros documentos. Objetos "
"disponíveis: `document. <attribute> ` e ` metadata. <metadata_type_name> `."
#: models.py:29
msgid "expression"
msgstr "expressão"
#: models.py:30
msgid "negated"
msgstr "negada"
#: models.py:30
msgid "Inverts the logic of the operator."
msgstr "Inverte a lógica do operador."
#: models.py:34
msgid "not"
msgstr "não"
#: models.py:37
msgid "link condition"
msgstr ""
#: models.py:38
msgid "link conditions"
msgstr ""
#: views.py:32
msgid "No action selected."
msgstr "Nenhuma ação selecionada."
#: views.py:47
#, fuzzy, python-format
msgid "documents in smart link: %(group)s"
msgstr "documentos no grupo: %(group)s "
#: views.py:65
#, fuzzy, python-format
msgid "Smart link query error: %s"
msgstr "Erro na consulta de grupo do documento: %s"
#: views.py:76
#, python-format
msgid "smart links (%s)"
msgstr ""
#: views.py:90
#, fuzzy
msgid "There no defined smart links for the current document."
msgstr "Não há grupos definidos para o documento atual."
#: views.py:124
#, python-format
msgid "Smart link: %s created successfully."
msgstr ""
#: views.py:131
msgid "Create new smart link"
msgstr ""
#: views.py:144
#, python-format
msgid "Smart link: %s edited successfully."
msgstr ""
#: views.py:153
#, python-format
msgid "Edit smart link: %s"
msgstr ""
#: views.py:168
#, python-format
msgid "Smart link: %s deleted successfully."
msgstr ""
#: views.py:170
#, python-format
msgid "Error deleting smart link: %(smart_link)s; %(error)s."
msgstr ""
#: views.py:180
#, python-format
msgid "Are you sure you wish to delete smart link: %s?"
msgstr ""
#: views.py:193
#, python-format
msgid "conditions for smart link: %s"
msgstr ""
#: views.py:216
#, python-format
msgid "Smart link condition: \"%s\" created successfully."
msgstr ""
#: views.py:223
#, python-format
msgid "Add new conditions to smart link: \"%s\""
msgstr ""
#: views.py:243
#, python-format
msgid "Smart link condition: \"%s\" edited successfully."
msgstr ""
#: views.py:250
msgid "Edit smart link condition"
msgstr ""
#: views.py:257 views.py:288
msgid "condition"
msgstr ""
#: views.py:274
#, python-format
msgid "Smart link condition: \"%s\" deleted successfully."
msgstr ""
#: views.py:276
#, python-format
msgid ""
"Error deleting smart link condition: %(smart_link_condition)s; %(error)s."
msgstr ""
#: views.py:290
#, python-format
msgid "Are you sure you wish to delete smart link condition: \"%s\"?"
msgstr ""
#: conf/settings.py:11
msgid "Show smart link that don't return any documents."
msgstr ""
#: templates/smart_links_help.html:3
msgid "What are smart links?"
msgstr ""
#: templates/smart_links_help.html:4
msgid ""
"Smart links are a set of conditional statements that are used to query the "
"database using the current document the user is accessing as the data "
"source, the results of these queries are a list of documents that relate in "
"some manner to the document being displayed and allow users the ability to "
"jump to and from linked documents very easily."
msgstr ""
#~ msgid "group actions"
#~ msgstr "ações do grupo"
#~ msgid "groups"
#~ msgstr "grupos"
#~ msgid "group document"
#~ msgstr "agrupar documento"
#~ msgid "document group"
#~ msgstr "grupo de documentos"
#~ msgid "document groups"
#~ msgstr "grupos de documentos"
#~ msgid "group item"
#~ msgstr "item do grupo"
#~ msgid "group items"
#~ msgstr "itens do grupo"
#~ msgid "document groups (%s)"
#~ msgstr "grupos do documento (%s)"

Binary file not shown.

View File

@@ -0,0 +1,343 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# Sergey Glita <gsv70@mail.ru>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Mayan EDMS\n"
"Report-Msgid-Bugs-To: http://github.com/rosarior/mayan/issues\n"
"POT-Creation-Date: 2011-11-22 11:26-0400\n"
"PO-Revision-Date: 2011-11-22 18:47+0000\n"
"Last-Translator: gsv70 <gsv70@mail.ru>\n"
"Language-Team: Russian (http://www.transifex.net/projects/p/mayan-edms/team/ru/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ru\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"
#: __init__.py:11
msgid "View existing smart links"
msgstr "Просмотр отношений"
#: __init__.py:12
msgid "Create new smart links"
msgstr "Создать отношение"
#: __init__.py:13
msgid "Delete smart links"
msgstr "Удалить отношения"
#: __init__.py:14
msgid "Edit smart links"
msgstr "Редактировать отношения"
#: __init__.py:16
msgid "Smart links"
msgstr "Отношения"
#: __init__.py:22
msgid "smart links actions"
msgstr "действия отношений"
#: __init__.py:23 __init__.py:25 models.py:21 views.py:105
msgid "smart links"
msgstr "отношения"
#: __init__.py:26
msgid "smart links list"
msgstr "список отношений"
#: __init__.py:27
msgid "create new smart link"
msgstr "создать отношение"
#: __init__.py:28 __init__.py:33
msgid "edit"
msgstr "редактировать"
#: __init__.py:29 __init__.py:34
msgid "delete"
msgstr "удалить"
#: __init__.py:31
msgid "conditions"
msgstr "условия"
#: __init__.py:32
msgid "create condition"
msgstr "создать условие"
#: forms.py:48
msgid "Pages"
msgstr "Страницы"
#: forms.py:54
msgid "Select"
msgstr "Выбрать"
#: forms.py:61
msgid "Click on the image for full size view of the first page."
msgstr ""
"Нажмите на изображение для просмотра первой страницы в полном размере."
#: literals.py:7
msgid "and"
msgstr "и"
#: literals.py:8
msgid "or"
msgstr "или"
#: literals.py:12
msgid "is equal to"
msgstr "равно"
#: literals.py:13
msgid "is equal to (case insensitive)"
msgstr "равно (без учета регистра)"
#: literals.py:14
msgid "contains"
msgstr "содержит"
#: literals.py:15
msgid "contains (case insensitive)"
msgstr "содержит (без учета регистра)"
#: literals.py:16
msgid "is in"
msgstr "находится в"
#: literals.py:17
msgid "is greater than"
msgstr "больше"
#: literals.py:18
msgid "is greater than or equal to"
msgstr "больше или равно"
#: literals.py:19
msgid "is less than"
msgstr "меньше"
#: literals.py:20
msgid "is less than or equal to"
msgstr "меньше или равно"
#: literals.py:21
msgid "starts with"
msgstr "начинается с"
#: literals.py:22
msgid "starts with (case insensitive)"
msgstr "начинается с (без учета регистра)"
#: literals.py:23
msgid "ends with"
msgstr "заканчивается на"
#: literals.py:24
msgid "ends with (case insensitive)"
msgstr "заканчивается на (без учета регистра)"
#: literals.py:25
msgid "is in regular expression"
msgstr "В регулярном выражении"
#: literals.py:26
msgid "is in regular expression (case insensitive)"
msgstr "В регулярном выражении (без учета регистра)"
#: models.py:10
msgid "title"
msgstr "название"
#: models.py:11 views.py:108
msgid "dynamic title"
msgstr "динамический заголовок"
#: models.py:11 models.py:29
msgid ""
"This expression will be evaluated against the current selected document. "
"The document metadata is available as variables `metadata` and document "
"properties under the variable `document`."
msgstr ""
"Это выражение будет вычислено вмето выбранного документа. Метаданные "
"документа доступны как переменные `metadata` и свойства документа в "
"переменной `document`."
#: models.py:12 models.py:31 views.py:109 views.py:196
msgid "enabled"
msgstr "разрешено"
#: models.py:20 models.py:25 views.py:256 views.py:287
msgid "smart link"
msgstr "отношение"
#: models.py:26
msgid "The inclusion is ignored for the first item."
msgstr "Включение игнорируется для первого элемента."
#: models.py:27
msgid "foreign document data"
msgstr "foreign document data"
#: models.py:27
msgid ""
"This represents the metadata of all other documents. Available objects: "
"`document.<attribute>` and `metadata.<metadata_type_name>`."
msgstr ""
"Это представляет метаданные всех других документов. Доступные объекты: "
"`document. <attribute> ` и `metadata. <metadata_type_name> `."
#: models.py:29
msgid "expression"
msgstr "выражение"
#: models.py:30
msgid "negated"
msgstr "отрицание"
#: models.py:30
msgid "Inverts the logic of the operator."
msgstr "Инвертирует логику оператора."
#: models.py:34
msgid "not"
msgstr "не"
#: models.py:37
msgid "link condition"
msgstr "условие ссылки"
#: models.py:38
msgid "link conditions"
msgstr "условия ссылки"
#: views.py:32
msgid "No action selected."
msgstr "Никаких действий не выбрано."
#: views.py:47
#, python-format
msgid "documents in smart link: %(group)s"
msgstr "документы в отношении %(group)s"
#: views.py:65
#, python-format
msgid "Smart link query error: %s"
msgstr "Ошибка запроса в отношении %s"
#: views.py:76
#, python-format
msgid "smart links (%s)"
msgstr "отношения (%s)"
#: views.py:90
msgid "There no defined smart links for the current document."
msgstr "Для этого документа отношения не определены."
#: views.py:124
#, python-format
msgid "Smart link: %s created successfully."
msgstr "Отношение %s создано."
#: views.py:131
msgid "Create new smart link"
msgstr "Создать новое отношение"
#: views.py:144
#, python-format
msgid "Smart link: %s edited successfully."
msgstr "Отношение %s изменено."
#: views.py:153
#, python-format
msgid "Edit smart link: %s"
msgstr "Редактировать отношение %s"
#: views.py:168
#, python-format
msgid "Smart link: %s deleted successfully."
msgstr "Отношение %s удалено."
#: views.py:170
#, python-format
msgid "Error deleting smart link: %(smart_link)s; %(error)s."
msgstr "Ошибка при удалении отношения %(smart_link)s; %(error)s."
#: views.py:180
#, python-format
msgid "Are you sure you wish to delete smart link: %s?"
msgstr "Вы действительно хотите удалить отношение %s?"
#: views.py:193
#, python-format
msgid "conditions for smart link: %s"
msgstr "условия для отношения %s"
#: views.py:216
#, python-format
msgid "Smart link condition: \"%s\" created successfully."
msgstr "Условие для отношения \"%s\" успешно создано."
#: views.py:223
#, python-format
msgid "Add new conditions to smart link: \"%s\""
msgstr "Добавить новые условия отношения \"%s\""
#: views.py:243
#, python-format
msgid "Smart link condition: \"%s\" edited successfully."
msgstr "Условие отношения \"%s\" изменено."
#: views.py:250
msgid "Edit smart link condition"
msgstr "Изменить условие отношения"
#: views.py:257 views.py:288
msgid "condition"
msgstr "состояние"
#: views.py:274
#, python-format
msgid "Smart link condition: \"%s\" deleted successfully."
msgstr "Условие отношения \"%s\" удалено."
#: views.py:276
#, python-format
msgid ""
"Error deleting smart link condition: %(smart_link_condition)s; %(error)s."
msgstr "Ошибка при удалении условия %(smart_link_condition)s; %(error)s."
#: views.py:290
#, python-format
msgid "Are you sure you wish to delete smart link condition: \"%s\"?"
msgstr "Вы действительно хотите удалить условие отношения \"%s\"?"
#: conf/settings.py:11
msgid "Show smart link that don't return any documents."
msgstr "Показать отношения без документов."
#: templates/smart_links_help.html:3
msgid "What are smart links?"
msgstr "Что такое отношение?"
#: templates/smart_links_help.html:4
msgid ""
"Smart links are a set of conditional statements that are used to query the "
"database using the current document the user is accessing as the data "
"source, the results of these queries are a list of documents that relate in "
"some manner to the document being displayed and allow users the ability to "
"jump to and from linked documents very easily."
msgstr ""
"Отношение, в оригинале smart-link, представляет собой набор условий, которые"
" используются для поиска документов отвечающих им . Результатом такого "
"поискового запроса является список документов, относящихся к текущему, и "
"позволяющих быстро переходить от одного к другому. Условия строятся исходя "
"из содержимого документа и метаданных."

View File

@@ -4,13 +4,13 @@ from django.db.models import Q
from metadata.classes import MetadataObject
from documents.models import Document
from grouping.literals import INCLUSION_AND, INCLUSION_OR
from linking.literals import INCLUSION_AND, INCLUSION_OR
class DocumentGroupManager(models.Manager):
def get_groups_for(self, document, group_obj=None):
class SmartLinkManager(models.Manager):
def get_smart_link_instances_for(self, document, smart_link_obj=None):
errors = []
document_groups = {}
result = {}
metadata_dict = {}
for document_metadata in document.documentmetadata_set.all():
metadata_dict[document_metadata.metadata_type.name] = document_metadata.value
@@ -18,38 +18,38 @@ class DocumentGroupManager(models.Manager):
eval_dict['document'] = document
eval_dict['metadata'] = MetadataObject(metadata_dict)
if group_obj:
groups_qs = self.model.objects.filter(Q(enabled=True) & Q(pk=group_obj.pk))
if smart_link_obj:
smart_link_qs = self.model.objects.filter(Q(enabled=True) & Q(pk=smart_link_obj.pk))
else:
groups_qs = self.model.objects.filter(enabled=True)
smart_link_qs = self.model.objects.filter(enabled=True)
for group in groups_qs:
for smart_link in smart_link_qs:
total_query = Q()
for item in group.documentgroupitem_set.filter(enabled=True):
cls, attribute = item.foreign_document_data.lower().split(u'.')
for condition in smart_link.smartlinkcondition_set.filter(enabled=True):
cls, attribute = condition.foreign_document_data.lower().split(u'.')
try:
if cls == u'metadata':
value_query = Q(**{'documentmetadata__value__%s' % item.operator: eval(item.expression, eval_dict)})
if item.negated:
value_query = Q(**{'documentmetadata__value__%s' % condition.operator: eval(condition.expression, eval_dict)})
if condition.negated:
query = (Q(documentmetadata__metadata_type__name=attribute) & ~value_query)
else:
query = (Q(documentmetadata__metadata_type__name=attribute) & value_query)
if item.inclusion == INCLUSION_AND:
if condition.inclusion == INCLUSION_AND:
total_query &= query
elif item.inclusion == INCLUSION_OR:
elif condition.inclusion == INCLUSION_OR:
total_query |= query
elif cls == u'document':
value_query = Q(**{
'%s__%s' % (attribute, item.operator): eval(item.expression, eval_dict)
'%s__%s' % (attribute, condition.operator): eval(condition.expression, eval_dict)
})
if item.negated:
if condition.negated:
query = ~value_query
else:
query = value_query
if item.inclusion == INCLUSION_AND:
if condition.inclusion == INCLUSION_AND:
total_query &= query
elif item.inclusion == INCLUSION_OR:
elif condition.inclusion == INCLUSION_OR:
total_query |= query
except Exception, e:
@@ -59,24 +59,24 @@ class DocumentGroupManager(models.Manager):
if total_query:
try:
document_qs = Document.objects.filter(total_query)
document_groups[group] = {'documents': document_qs.order_by('file_filename') or []}
result[smart_link] = {'documents': document_qs.order_by('file_filename') or []}
except Exception, e:
document_groups[group] = {'documents': []}
result[smart_link] = {'documents': []}
errors.append(e)
else:
document_groups[group] = {'documents': []}
result[smart_link] = {'documents': []}
if group.dynamic_title:
if smart_link.dynamic_title:
try:
document_groups[group]['title'] = eval(group.dynamic_title, eval_dict)
result[smart_link]['title'] = eval(smart_link.dynamic_title, eval_dict)
except Exception, e:
document_groups[group]['title'] = 'Error; %s' % e
result[smart_link]['title'] = 'Error; %s' % e
else:
document_groups[group]['title'] = group.title
result[smart_link]['title'] = smart_link.title
if group_obj:
if smart_link_obj:
# Return a single group if documents even if there were
# many matches
return document_groups[group_obj], errors
return result[smart_link_obj], errors
return document_groups, errors
return result, errors

View File

@@ -1,40 +1,38 @@
from django.db import models
from django.utils.translation import ugettext_lazy as _
from grouping.managers import DocumentGroupManager
from grouping.literals import OPERATOR_CHOICES, INCLUSION_AND, \
from linking.managers import SmartLinkManager
from linking.literals import OPERATOR_CHOICES, INCLUSION_AND, \
INCLUSION_CHOICES
class DocumentGroup(models.Model):
class SmartLink(models.Model):
title = models.CharField(max_length=96, verbose_name=_(u'title'))
dynamic_title = models.CharField(blank=True, max_length=96, verbose_name=_(u'dynamic title'))
dynamic_title = models.CharField(blank=True, max_length=96, verbose_name=_(u'dynamic title'), help_text=_(u'This expression will be evaluated against the current selected document. The document metadata is available as variables `metadata` and document properties under the variable `document`.'))
enabled = models.BooleanField(default=True, verbose_name=_(u'enabled'))
objects = DocumentGroupManager()
objects = SmartLinkManager()
def __unicode__(self):
return self.title
class Meta:
verbose_name = _(u'document group')
verbose_name_plural = _(u'document groups')
verbose_name = _(u'smart link')
verbose_name_plural = _(u'smart links')
class DocumentGroupItem(models.Model):
document_group = models.ForeignKey(DocumentGroup, verbose_name=_(u'document group'))
class SmartLinkCondition(models.Model):
smart_link = models.ForeignKey(SmartLink, verbose_name=_(u'smart link'))
inclusion = models.CharField(default=INCLUSION_AND, max_length=16, choices=INCLUSION_CHOICES, help_text=_(u'The inclusion is ignored for the first item.'))
foreign_document_data = models.CharField(max_length=32, verbose_name=_(u'foreign document data'), help_text=_(u'This represents the metadata of all other documents. Available objects: `document.<attribute>` and `metadata.<metadata_type_name>`.'))
operator = models.CharField(max_length=16, choices=OPERATOR_CHOICES)
#local_document_data = models.ForeignKey(MetadataType, related_name='metadata_type_local', verbose_name=_(u'local metadata'), help_text=_(u'This represents the metadata of the current document.'))
expression = models.TextField(verbose_name=_(u'expression'), help_text=_(u'This expression will be evaluated against the current selected document. The document metadata is available as variables `metadata` and document properties under the variable `document`.'))
negated = models.BooleanField(default=False, verbose_name=_(u'negated'), help_text=_(u'Inverts the logic of the operator.'))
enabled = models.BooleanField(default=True, verbose_name=_(u'enabled'))
def __unicode__(self):
return u'[%s] %s foreign %s %s %s %s' % (u'x' if self.enabled else u' ', self.get_inclusion_display(), self.foreign_document_data, _(u'not') if self.negated else u'', self.get_operator_display(), self.expression)
return u'%s foreign %s %s %s %s' % (self.get_inclusion_display(), self.foreign_document_data, _(u'not') if self.negated else u'', self.get_operator_display(), self.expression)
class Meta:
verbose_name = _(u'group item')
verbose_name_plural = _(u'group items')
verbose_name = _(u'link condition')
verbose_name_plural = _(u'link conditions')

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1,5 @@
{% load i18n %}
<div class="block notice">
<h4>{% trans "What are smart links?" %}</h4>
<p>{% blocktrans %}Smart links are a set of conditional statements that are used to query the database using the current document the user is accessing as the data source, the results of these queries are a list of documents that relate in some manner to the document being displayed and allow users the ability to jump to and from linked documents very easily.{% endblocktrans %}</p>
</div>

17
apps/linking/urls.py Normal file
View File

@@ -0,0 +1,17 @@
from django.conf.urls.defaults import patterns, url
urlpatterns = patterns('linking.views',
url(r'^action/$', 'smart_link_action', (), 'smart_link_action'),
url(r'^document/(?P<document_id>\d+)/smart_link/(?P<smart_link_pk>\d+)/$', 'smart_link_instance_view', (), 'smart_link_instance_view'),
url(r'^smart/for_document/(?P<document_id>\d+)/$', 'smart_link_instances_for_document', (), 'smart_link_instances_for_document'),
url(r'^setup/list/$', 'smart_link_list', (), 'smart_link_list'),
url(r'^setup/create/$', 'smart_link_create', (), 'smart_link_create'),
url(r'^setup/(?P<smart_link_pk>\d+)/delete/$', 'smart_link_delete', (), 'smart_link_delete'),
url(r'^setup/(?P<smart_link_pk>\d+)/edit/$', 'smart_link_edit', (), 'smart_link_edit'),
url(r'^setup/(?P<smart_link_pk>\d+)/condition/list/$', 'smart_link_condition_list', (), 'smart_link_condition_list'),
url(r'^setup/(?P<smart_link_pk>\d+)/condition/create/$', 'smart_link_condition_create', (), 'smart_link_condition_create'),
url(r'^setup/smart_link/condition/(?P<smart_link_condition_pk>\d+)/edit/$', 'smart_link_condition_edit', (), 'smart_link_condition_edit'),
url(r'^setup/smart_link/condition/(?P<smart_link_condition_pk>\d+)/delete/$', 'smart_link_condition_delete', (), 'smart_link_condition_delete'),
)

294
apps/linking/views.py Normal file
View File

@@ -0,0 +1,294 @@
from django.utils.translation import ugettext_lazy as _
from django.contrib import messages
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render_to_response
from django.core.urlresolvers import reverse
from django.template import RequestContext
from common.utils import generate_choices_w_labels, encapsulate
from common.widgets import two_state_template
from documents.models import Document
from documents.views import document_list
from permissions.api import check_permissions
from linking.models import SmartLink, SmartLinkCondition
from linking.conf.settings import SHOW_EMPTY_SMART_LINKS
from linking.forms import (SmartLinkInstanceForm, SmartLinkForm,
SmartLinkConditionForm)
from linking import smart_link_instance_view_link
from linking import (PERMISSION_SMART_LINK_VIEW,
PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_DELETE,
PERMISSION_SMART_LINK_EDIT)
def smart_link_action(request):
check_permissions(request.user, [PERMISSION_SMART_LINK_VIEW])
action = request.GET.get('action', None)
if not action:
messages.error(request, _(u'No action selected.'))
return HttpResponseRedirect(request.META.get('HTTP_REFERER', u'/'))
return HttpResponseRedirect(action)
def smart_link_instance_view(request, document_id, smart_link_pk):
check_permissions(request.user, [PERMISSION_SMART_LINK_VIEW])
document = get_object_or_404(Document, pk=document_id)
smart_link = get_object_or_404(SmartLink, pk=smart_link_pk)
object_list, errors = SmartLink.objects.get_smart_link_instances_for(document, smart_link)
return document_list(
request,
title=_(u'documents in smart link: %(group)s') % {
'group': object_list['title']
},
object_list=object_list['documents'],
extra_context={
'object': document
}
)
def smart_link_instances_for_document(request, document_id):
check_permissions(request.user, [PERMISSION_SMART_LINK_VIEW])
subtemplates_list = []
document = get_object_or_404(Document, pk=document_id)
smart_link_instances, errors = SmartLink.objects.get_smart_link_instances_for(document)
if (request.user.is_staff or request.user.is_superuser) and errors:
for error in errors:
messages.warning(request, _(u'Smart link query error: %s' % error))
if not SHOW_EMPTY_SMART_LINKS:
#If SHOW_EMPTY_SMART_LINKS is False, remove empty groups from
#dictionary
smart_link_instances = dict([(group, data) for group, data in smart_link_instances.items() if data['documents']])
if smart_link_instances:
subtemplates_list = [{
'name': 'generic_form_subtemplate.html',
'context': {
'title': _(u'smart links (%s)') % len(smart_link_instances.keys()),
'form': SmartLinkInstanceForm(
smart_link_instances=smart_link_instances, current_document=document,
links=[smart_link_instance_view_link]
),
'form_action': reverse('smart_link_action'),
'submit_method': 'GET',
}
}]
else:
# If there are not group display a placeholder messages saying so
subtemplates_list = [{
'name': 'generic_subtemplate.html',
'context': {
'content': _(u'There no defined smart links for the current document.'),
}
}]
return render_to_response('generic_detail.html', {
'object': document,
'document': document,
'subtemplates_list': subtemplates_list,
}, context_instance=RequestContext(request))
def smart_link_list(request):
check_permissions(request.user, [PERMISSION_SMART_LINK_CREATE])
return render_to_response('generic_list.html', {
'title': _(u'smart links'),
'object_list': SmartLink.objects.all(),
'extra_columns': [
{'name': _(u'dynamic title'), 'attribute': 'dynamic_title'},
{'name': _(u'enabled'), 'attribute': encapsulate(lambda x: two_state_template(x.enabled))},
],
'hide_link': True,
'list_object_variable_name': 'smart_link',
}, context_instance=RequestContext(request))
def smart_link_create(request):
check_permissions(request.user, [PERMISSION_SMART_LINK_CREATE])
if request.method == 'POST':
form = SmartLinkForm(request.POST)
if form.is_valid():
document_group = form.save()
messages.success(request, _(u'Smart link: %s created successfully.') % document_group)
return HttpResponseRedirect(reverse('document_group_list'))
else:
form = SmartLinkForm()
return render_to_response('generic_form.html', {
'form': form,
'title': _(u'Create new smart link')
}, context_instance=RequestContext(request))
def smart_link_edit(request, smart_link_pk):
check_permissions(request.user, [PERMISSION_SMART_LINK_EDIT])
smart_link = get_object_or_404(SmartLink, pk=smart_link_pk)
if request.method == 'POST':
form = SmartLinkForm(request.POST, instance=smart_link)
if form.is_valid():
smart_link = form.save()
messages.success(request, _(u'Smart link: %s edited successfully.') % smart_link)
return HttpResponseRedirect(reverse('document_group_list'))
else:
form = SmartLinkForm(instance=smart_link)
return render_to_response('generic_form.html', {
'navigation_object_name': 'smart_link',
'smart_link': smart_link,
'form': form,
'title': _(u'Edit smart link: %s') % smart_link
}, context_instance=RequestContext(request))
def smart_link_delete(request, smart_link_pk):
check_permissions(request.user, [PERMISSION_SMART_LINK_DELETE])
smart_link = get_object_or_404(SmartLink, pk=smart_link_pk)
next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', '/')))
previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', '/')))
if request.method == 'POST':
try:
smart_link.delete()
messages.success(request, _(u'Smart link: %s deleted successfully.') % smart_link)
except Exception, error:
messages.error(request, _(u'Error deleting smart link: %(smart_link)s; %(error)s.') % {
'smart_link': smart_link,
'error': error
})
return HttpResponseRedirect(next)
return render_to_response('generic_confirm.html', {
'delete_view': True,
'navigation_object_name': 'smart_link',
'smart_link': smart_link,
'title': _(u'Are you sure you wish to delete smart link: %s?') % smart_link,
'next': next,
'previous': previous,
'form_icon': u'link_delete.png',
}, context_instance=RequestContext(request))
def smart_link_condition_list(request, smart_link_pk):
check_permissions(request.user, [PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT])
smart_link = get_object_or_404(SmartLink, pk=smart_link_pk)
return render_to_response('generic_list.html', {
'title': _(u'conditions for smart link: %s') % smart_link,
'object_list': smart_link.smartlinkcondition_set.all(),
'extra_columns': [
{'name': _(u'enabled'), 'attribute': encapsulate(lambda x: two_state_template(x.enabled))},
],
'hide_link': True,
'smart_link': smart_link,
'navigation_object_name': 'smart_link',
'list_object_variable_name': 'condition',
}, context_instance=RequestContext(request))
def smart_link_condition_create(request, smart_link_pk):
check_permissions(request.user, [PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT])
smart_link = get_object_or_404(SmartLink, pk=smart_link_pk)
if request.method == 'POST':
form = SmartLinkConditionForm(request.POST)
if form.is_valid():
new_smart_link_condition = form.save(commit=False)
new_smart_link_condition.smart_link = smart_link
new_smart_link_condition.save()
messages.success(request, _(u'Smart link condition: "%s" created successfully.') % new_smart_link_condition)
return HttpResponseRedirect(reverse('smart_link_condition_list', args=[smart_link.pk]))
else:
form = SmartLinkConditionForm(initial={'smart_link': smart_link})
return render_to_response('generic_form.html', {
'form': form,
'title': _(u'Add new conditions to smart link: "%s"') % smart_link,
'navigation_object_name': 'smart_link',
'smart_link': smart_link,
}, context_instance=RequestContext(request))
def smart_link_condition_edit(request, smart_link_condition_pk):
check_permissions(request.user, [PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT])
smart_link_condition = get_object_or_404(SmartLinkCondition, pk=smart_link_condition_pk)
next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', '/')))
previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', '/')))
if request.method == 'POST':
form = SmartLinkConditionForm(request.POST, instance=smart_link_condition)
if form.is_valid():
new_smart_link_condition = form.save(commit=False)
new_smart_link_condition.smart_link = smart_link_condition.smart_link
new_smart_link_condition.save()
messages.success(request, _(u'Smart link condition: "%s" edited successfully.') % new_smart_link_condition)
return HttpResponseRedirect(next)
else:
form = SmartLinkConditionForm(instance=smart_link_condition)
return render_to_response('generic_form.html', {
'form': form,
'title': _(u'Edit smart link condition'),
'next': next,
'previous': previous,
'condition': smart_link_condition,
'smart_link': smart_link_condition.smart_link,
'navigation_object_list': [
{'object': 'smart_link', 'name': _(u'smart link')},
{'object': 'condition', 'name': _(u'condition')}
],
}, context_instance=RequestContext(request))
def smart_link_condition_delete(request, smart_link_condition_pk):
check_permissions(request.user, [PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT])
smart_link_condition = get_object_or_404(SmartLinkCondition, pk=smart_link_condition_pk)
next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', '/')))
previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', '/')))
if request.method == 'POST':
try:
smart_link_condition.delete()
messages.success(request, _(u'Smart link condition: "%s" deleted successfully.') % smart_link_condition)
except Exception, error:
messages.error(request, _(u'Error deleting smart link condition: %(smart_link_condition)s; %(error)s.') % {
'smart_link_condition': smart_link_condition,
'error': error
})
return HttpResponseRedirect(next)
return render_to_response('generic_confirm.html', {
'delete_view': True,
'condition': smart_link_condition,
'smart_link': smart_link_condition.smart_link,
'navigation_object_list': [
{'object': 'smart_link', 'name': _(u'smart link')},
{'object': 'condition', 'name': _(u'condition')}
],
'title': _(u'Are you sure you wish to delete smart link condition: "%s"?') % smart_link_condition,
'next': next,
'previous': previous,
'form_icon': u'cog_delete.png',
}, context_instance=RequestContext(request))

View File

@@ -0,0 +1,4 @@
from lock_manager.exceptions import LockError
from lock_manager.models import Lock as LockModel
Lock = LockModel.objects

View File

@@ -0,0 +1,10 @@
from django.contrib import admin
from lock_manager.models import Lock
class LockAdmin(admin.ModelAdmin):
model = Lock
admin.site.register(Lock, LockAdmin)

View File

@@ -0,0 +1,16 @@
from django.core.cache import get_cache
if CACHE_URI:
try:
cache_backend = get_cache(CACHE_URI)
except ImportError:
# TODO: display or log error
cache_backend = None
else:
cache_backend = None
if cache_backend:
acquire_lock = lambda lock_id: cache_backend.add(lock_id, u'true', LOCK_EXPIRE)
release_lock = lambda lock_id: cache_backend.delete(lock_id)
else:
acquire_lock = lambda lock_id: True
release_lock = lambda lock_id: True

View File

@@ -1,5 +1,5 @@
from django.conf import settings
DEFAULT_LOCK_TIMEOUT_VALUE = 10
DEFAULT_LOCK_TIMEOUT_VALUE = 30
DEFAULT_LOCK_TIMEOUT = getattr(settings, 'LOCK_MANAGER_DEFAULT_LOCK_TIMEOUT', DEFAULT_LOCK_TIMEOUT_VALUE)

View File

@@ -1,9 +1,4 @@
try:
from psycopg2 import OperationalError
except ImportError:
class OperationalError(Exception):
pass
import logging
import datetime
from django.db.utils import DatabaseError
@@ -13,40 +8,34 @@ from django.db import models
from lock_manager.exceptions import LockError
logger = logging.getLogger(__name__)
class LockManager(models.Manager):
@transaction.commit_manually
@transaction.commit_on_success
def acquire_lock(self, name, timeout=None):
logger.debug('trying to acquire lock: %s' % name)
lock = self.model(name=name, timeout=timeout)
try:
lock.save(force_insert=True)
logger.debug('acquired lock: %s' % name)
return lock
except IntegrityError:
transaction.rollback()
# There is already an existing lock
# Check it's expiration date and if expired, delete it and
# create it again
lock = self.model.objects.get(name=name)
transaction.rollback()
# Check it's expiration date and if expired, reset it
try:
lock = self.model.objects.get(name=name)
except self.model.DoesNotExist:
# Table based locking
logger.debug('lock: %s does not exist' % name)
raise LockError('Unable to acquire lock')
if datetime.datetime.now() > lock.creation_datetime + datetime.timedelta(seconds=lock.timeout):
self.release_lock(name)
logger.debug('reseting deleting stale lock: %s' % name)
lock.timeout=timeout
logger.debug('try to reacquire stale lock: %s' % name)
lock.save()
transaction.commit()
return lock
else:
logger.debug('unable to acquire lock: %s' % name)
raise LockError('Unable to acquire lock')
except DatabaseError:
transaction.rollback()
# Special case for ./manage.py syncdb
except (OperationalError, ImproperlyConfigured):
transaction.rollback()
# Special for DjangoZoom, which executes collectstatic media
# doing syncdb and creating the database tables
else:
transaction.commit()
@transaction.commit_manually
def release_lock(self, name):
lock = self.model.objects.get(name=name)
lock.delete()
transaction.commit()

View File

@@ -10,17 +10,28 @@ from lock_manager.conf.settings import DEFAULT_LOCK_TIMEOUT
class Lock(models.Model):
creation_datetime = models.DateTimeField(verbose_name=_(u'creation datetime'))
timeout = models.IntegerField(default=DEFAULT_LOCK_TIMEOUT, verbose_name=_(u'timeout'))
name = models.CharField(max_length=32, verbose_name=_(u'name'), unique=True)
name = models.CharField(max_length=48, verbose_name=_(u'name'), unique=True)
objects = LockManager()
def __unicode__(self):
return self.name
def save(self, *args, **kwargs):
self.creation_datetime = datetime.datetime.now()
if not self.timeout and not kwarget.get('timeout'):
self.timeout = DEFAULT_LOCK_TIMEOUT
super(Lock, self).save(*args, **kwargs)
def release(self):
try:
lock = Lock.objects.get(name=self.name, creation_datetime=self.creation_datetime)
lock.delete()
except Lock.DoesNotExist:
# Out lock expired and was reassigned
pass
class Meta:
verbose_name = _(u'lock')
verbose_name_plural = _(u'locks')

View File

@@ -1,10 +1,3 @@
"""
This file demonstrates writing tests using the unittest module. These will pass
when you run "manage.py test".
Replace this with more appropriate tests for your application.
"""
from django.test import TestCase

View File

@@ -20,8 +20,8 @@ admin_site = {'text': _(u'admin site'), 'view': 'admin:index', 'famfam': 'keyboa
__version_info__ = {
'major': 0,
'minor': 9,
'micro': 1,
'minor': 10,
'micro': 0,
'releaselevel': 'final',
'serial': 0
}

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