Gery Debongnie 2014-04-10 15:32:51 +02:00
commit c6f41caf99
97 changed files with 452 additions and 342 deletions

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:26+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:50+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:26+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:50+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:27+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:51+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:27+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:51+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:28+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:52+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:27+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:51+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:28+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:52+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:28+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:52+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:28+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:53+0000\n"
"X-Generator: Launchpad (build 16976)\n"
"X-Poedit-Language: Czech\n"
#. module: base

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:28+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:53+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:30+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:55+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -12,8 +12,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:30+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:55+0000\n"
"X-Generator: Launchpad (build 16976)\n"
"X-Poedit-Country: GREECE\n"
"X-Poedit-Language: Greek\n"
"X-Poedit-SourceCharset: utf-8\n"

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:39+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:08+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:36+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:04+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:38+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:08+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:39+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:10+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:39+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:09+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:40+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:10+0000\n"
"X-Generator: Launchpad (build 16976)\n"
"Language: \n"
#. module: base

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:39+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:08+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:41+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:12+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:40+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:11+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:41+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:12+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:38+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:07+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:29+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:53+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:27+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:51+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -9,8 +9,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:34+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:00+0000\n"
"X-Generator: Launchpad (build 16976)\n"
"X-Poedit-Country: IRAN, ISLAMIC REPUBLIC OF\n"
"X-Poedit-Language: Persian\n"

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:41+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:12+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:29+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:54+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:29+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:54+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:39+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:09+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:30+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:55+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:30+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:56+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:31+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:56+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:31+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:56+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:35+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:03+0000\n"
"X-Generator: Launchpad (build 16976)\n"
"Language: hr\n"
#. module: base

View File

@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:31+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:56+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -9,8 +9,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:27+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:51+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:31+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:57+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:31+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:57+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:32+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:57+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:32+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:58+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:29+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:54+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:32+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:58+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:33+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:58+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:33+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:59+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:33+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:58+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:33+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:59+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:34+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:59+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:34+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:00+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:28+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:53+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:39+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:09+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:34+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:00+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:34+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:01+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:38+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:07+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:35+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:01+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:35+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:02+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:36+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:03+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:36+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:04+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:27+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 05:50+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:35+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:02+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:41+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:12+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:36+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:04+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:37+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:05+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:37+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:05+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:37+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:05+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:37+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:06+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:37+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:06+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:37+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:07+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:40+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:11+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:38+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:07+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-28 05:40+0000\n"
"X-Generator: Launchpad (build 16967)\n"
"X-Launchpad-Export-Date: 2014-04-09 06:10+0000\n"
"X-Generator: Launchpad (build 16976)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing

View File

@ -104,7 +104,9 @@ class ir_actions_report_xml(osv.osv):
cr.execute("SELECT * FROM ir_act_report_xml WHERE report_name=%s", (name,))
r = cr.dictfetchone()
if r:
if r['report_rml'] or r['report_rml_content_data']:
if r['report_type'] in ['qweb-pdf', 'qweb-html']:
return r['report_name']
elif r['report_rml'] or r['report_rml_content_data']:
if r['parser']:
kwargs = { 'parser': operator.attrgetter(r['parser'])(openerp.addons) }
else:
@ -127,7 +129,11 @@ class ir_actions_report_xml(osv.osv):
Look up a report definition and render the report for the provided IDs.
"""
new_report = self._lookup_report(cr, name)
return new_report.create(cr, uid, res_ids, data, context)
# in order to use current yml test files with qweb reports
if isinstance(new_report, (str, unicode)):
return self.pool['report'].get_pdf(cr, uid, res_ids, new_report, data=data, context=context), 'pdf'
else:
return new_report.create(cr, uid, res_ids, data, context)
_name = 'ir.actions.report.xml'
_inherit = 'ir.actions.actions'

View File

@ -241,7 +241,7 @@ class QWeb(orm.AbstractModel):
if attribute_name == "groups":
cr = qwebcontext.get('request') and qwebcontext['request'].cr or None
uid = qwebcontext.get('request') and qwebcontext['request'].uid or None
can_see = self.user_has_groups(cr, uid, groups=attribute_value)
can_see = self.user_has_groups(cr, uid, groups=attribute_value) if cr and uid else False
if not can_see:
return ''
continue
@ -332,7 +332,9 @@ class QWeb(orm.AbstractModel):
return self.render_element(element, template_attributes, generated_attributes, qwebcontext, inner)
def render_tag_esc(self, element, template_attributes, generated_attributes, qwebcontext):
inner = werkzeug.utils.escape(self.eval_str(template_attributes["esc"], qwebcontext))
options = json.loads(template_attributes.get('esc-options') or '{}')
widget = self.get_widget_for(options.get('widget', ''))
inner = widget.format(template_attributes['esc'], options, qwebcontext)
return self.render_element(element, template_attributes, generated_attributes, qwebcontext, inner)
def render_tag_foreach(self, element, template_attributes, generated_attributes, qwebcontext):
@ -419,6 +421,9 @@ class QWeb(orm.AbstractModel):
return self.pool.get('ir.qweb.field.' + field_type,
self.pool['ir.qweb.field'])
def get_widget_for(self, widget):
return self.pool.get('ir.qweb.widget.' + widget, self.pool['ir.qweb.widget'])
#--------------------------------------------------------------------
# QWeb Fields converters
#--------------------------------------------------------------------
@ -840,6 +845,38 @@ class Contact(orm.AbstractModel):
return HTMLSafe(html)
class QwebWidget(osv.AbstractModel):
_name = 'ir.qweb.widget'
def _format(self, inner, options, qwebcontext):
return self.pool['ir.qweb'].eval_str(inner, qwebcontext)
def format(self, inner, options, qwebcontext):
return werkzeug.utils.escape(self._format(inner, options, qwebcontext))
class QwebWidgetMonetary(osv.AbstractModel):
_name = 'ir.qweb.widget.monetary'
_inherit = 'ir.qweb.widget'
def _format(self, inner, options, qwebcontext):
inner = self.pool['ir.qweb'].eval(inner, qwebcontext)
display = self.pool['ir.qweb'].eval_object(options['display_currency'], qwebcontext)
precision = int(round(math.log10(display.rounding)))
fmt = "%.{0}f".format(-precision if precision < 0 else 0)
lang_code = qwebcontext.context.get('lang') or 'en_US'
formatted_amount = self.pool['res.lang'].format(
qwebcontext.cr, qwebcontext.uid, [lang_code], fmt, inner, grouping=True, monetary=True
)
pre = post = u''
if display.position == 'before':
pre = u'{symbol} '
else:
post = u' {symbol}'
return u'{pre}{0}{post}'.format(
formatted_amount, pre=pre, post=post
).format(symbol=display.symbol,)
class HTMLSafe(object):
""" HTMLSafe string wrapper, Werkzeug's escape() has special handling for
objects with a ``__html__`` methods but AFAIK does not provide any such

View File

@ -31,6 +31,7 @@ import shutil
import tempfile
import urllib
import urllib2
import urlparse
import zipfile
import zipimport
import lxml.html
@ -41,6 +42,7 @@ except ImportError:
from StringIO import StringIO # NOQA
import openerp
import openerp.exceptions
from openerp import modules, tools
from openerp.modules.db import create_categories
from openerp.modules import get_module_resource
@ -621,40 +623,14 @@ class module(osv.osv):
return res
def download(self, cr, uid, ids, download=True, context=None):
res = []
default_version = modules.adapt_version('1.0')
for mod in self.browse(cr, uid, ids, context=context):
if not mod.url:
continue
match = re.search('-([a-zA-Z0-9\._-]+)(\.zip)', mod.url, re.I)
version = default_version
if match:
version = match.group(1)
if parse_version(mod.installed_version) >= parse_version(version):
continue
res.append(mod.url)
if not download:
continue
zip_content = urllib.urlopen(mod.url).read()
fname = modules.get_module_path(str(mod.name) + '.zip', downloaded=True)
try:
with open(fname, 'wb') as fp:
fp.write(zip_content)
except Exception:
_logger.exception('Error when trying to create module '
'file %s', fname)
raise orm.except_orm(_('Error'), _('Can not create the module file:\n %s') % (fname,))
terp = self.get_module_info(mod.name)
self.write(cr, uid, mod.id, self.get_values_from_terp(terp))
cr.execute('DELETE FROM ir_module_module_dependency WHERE module_id = %s', (mod.id,))
self._update_dependencies(cr, uid, mod, terp.get('depends', []))
self._update_category(cr, uid, mod, terp.get('category', 'Uncategorized'))
# Import module
zimp = zipimport.zipimporter(fname)
zimp.load_module(mod.name)
return res
return []
def install_from_urls(self, cr, uid, urls, context=None):
if not self.pool['res.users'].has_group(cr, uid, 'base.group_system'):
raise openerp.exceptions.AccessDenied()
apps_server = urlparse.urlparse(self.get_apps_server(cr, uid, context=context))
OPENERP = 'openerp'
tmp = tempfile.mkdtemp()
_logger.debug('Install from url: %r', urls)
@ -663,6 +639,11 @@ class module(osv.osv):
for module_name, url in urls.items():
if not url:
continue # nothing to download, local version is already the last one
up = urlparse.urlparse(url)
if up.scheme != apps_server.scheme or up.netloc != apps_server.netloc:
raise openerp.exceptions.AccessDenied()
try:
_logger.info('Downloading module `%s` from OpenERP Apps', module_name)
content = urllib2.urlopen(url).read()
@ -727,8 +708,8 @@ class module(osv.osv):
finally:
shutil.rmtree(tmp)
def install_by_names(self, cr, uid, names, context=None):
raise NotImplementedError('# TODO')
def get_apps_server(self, cr, uid, context=None):
return tools.config.get('apps_server', 'https://apps.openerp.com/apps')
def _update_dependencies(self, cr, uid, mod_browse, depends=None):
if depends is None:

View File

@ -388,14 +388,13 @@ class res_users(osv.osv):
if not password:
return False
user_id = False
cr = self.pool.db.cursor()
cr = self.pool.cursor()
try:
# autocommit: our single update request will be performed atomically.
# (In this way, there is no opportunity to have two transactions
# interleaving their cr.execute()..cr.commit() calls and have one
# of them rolled back due to a concurrent access.)
if not openerp.tools.config['test_enable']:
cr.autocommit(True)
cr.autocommit(True)
# check if user exists
res = self.search(cr, SUPERUSER_ID, [('login','=',login)])
if res:
@ -440,7 +439,7 @@ class res_users(osv.osv):
# Successfully logged in as admin!
# Attempt to guess the web base url...
if user_agent_env and user_agent_env.get('base_location'):
cr = self.pool.db.cursor()
cr = self.pool.cursor()
try:
base = user_agent_env['base_location']
ICP = self.pool['ir.config_parameter']
@ -461,7 +460,7 @@ class res_users(osv.osv):
raise openerp.exceptions.AccessDenied()
if self._uid_cache.get(db, {}).get(uid) == passwd:
return
cr = self.pool.db.cursor()
cr = self.pool.cursor()
try:
self.check_credentials(cr, uid, passwd)
if self._uid_cache.has_key(db):

View File

@ -63,8 +63,8 @@ openerp.base = function(instance) {
if (instance.base.apps_client) {
return check_client_available(instance.base.apps_client);
} else {
var ICP = new instance.web.Model('ir.config_parameter');
return ICP.call('get_param', ['apps.server', 'https://apps.openerp.com/apps']).then(function(u) {
var Mod = new instance.web.Model('ir.module.module');
return Mod.call('get_apps_server').then(function(u) {
var link = $(_.str.sprintf('<a href="%s"></a>', u))[0];
var host = _.str.sprintf('%s//%s', link.protocol, link.host);
var dbname = link.pathname;

View File

@ -21,7 +21,7 @@ class test_cr_execute(unittest2.TestCase):
"""
Try to use iterable but non-list or int params in query parameters.
"""
with registry().cursor(auto_commit=False) as cr:
with registry().cursor() as cr:
with self.assertRaises(ValueError):
cr.execute("SELECT id FROM res_users WHERE login=%s", 'admin')
with self.assertRaises(ValueError):

View File

@ -183,7 +183,7 @@ class test_expression(common.TransactionCase):
self.assertIn('res_partner_bank', sql_query[0],
"_auto_join off: ('bank_ids.name', 'like', '..') first query incorrect main table")
expected = "%s like %s" % (unaccent('"res_partner_bank"."name"'), unaccent('%s'))
expected = "%s::text like %s" % (unaccent('"res_partner_bank"."name"'), unaccent('%s'))
self.assertIn(expected, sql_query[1],
"_auto_join off: ('bank_ids.name', 'like', '..') first query incorrect where condition")
@ -223,7 +223,7 @@ class test_expression(common.TransactionCase):
self.assertIn('"res_partner_bank" as "res_partner__bank_ids"', sql_query[0],
"_auto_join on: ('bank_ids.name', 'like', '..') query incorrect join")
expected = "%s like %s" % (unaccent('"res_partner__bank_ids"."name"'), unaccent('%s'))
expected = "%s::text like %s" % (unaccent('"res_partner__bank_ids"."name"'), unaccent('%s'))
self.assertIn(expected, sql_query[1],
"_auto_join on: ('bank_ids.name', 'like', '..') query incorrect where condition")
@ -305,7 +305,7 @@ class test_expression(common.TransactionCase):
self.assertIn('"res_country"', sql_query[0],
"_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect main table")
expected = "%s like %s" % (unaccent('"res_country"."code"'), unaccent('%s'))
expected = "%s::text like %s" % (unaccent('"res_country"."code"'), unaccent('%s'))
self.assertIn(expected, sql_query[1],
"_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect where condition")
@ -339,7 +339,7 @@ class test_expression(common.TransactionCase):
self.assertIn('"res_country" as "res_country_state__country_id"', sql_query[0],
"_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect join")
expected = "%s like %s" % (unaccent('"res_country_state__country_id"."code"'), unaccent('%s'))
expected = "%s::text like %s" % (unaccent('"res_country_state__country_id"."code"'), unaccent('%s'))
self.assertIn(expected, sql_query[1],
"_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect where condition")
@ -373,7 +373,7 @@ class test_expression(common.TransactionCase):
self.assertIn('"res_country" as "res_partner__state_id__country_id"', sql_query[0],
"_auto_join on: ('state_id.country_id.code', 'like', '..') query incorrect join")
expected = "%s like %s" % (unaccent('"res_partner__state_id__country_id"."code"'), unaccent('%s'))
expected = "%s::text like %s" % (unaccent('"res_partner__state_id__country_id"."code"'), unaccent('%s'))
self.assertIn(expected, sql_query[1],
"_auto_join on: ('state_id.country_id.code', 'like', '..') query incorrect where condition")
@ -403,7 +403,7 @@ class test_expression(common.TransactionCase):
# Test produced queries that domains effectively present
sql_query = self.query_list[0].get_sql()
expected = "%s like %s" % (unaccent('"res_partner__child_ids__bank_ids"."acc_number"'), unaccent('%s'))
expected = "%s::text like %s" % (unaccent('"res_partner__child_ids__bank_ids"."acc_number"'), unaccent('%s'))
self.assertIn(expected, sql_query[1],
"_auto_join on one2many with domains incorrect result")
# TDE TODO: check first domain has a correct table name

View File

@ -21,7 +21,7 @@ def registry(model):
return openerp.modules.registry.RegistryManager.get(DB)[model]
def cursor():
return openerp.modules.registry.RegistryManager.get(DB).db.cursor()
return openerp.modules.registry.RegistryManager.get(DB).cursor()
def drop_sequence(code):

View File

@ -13,7 +13,7 @@ def registry(model):
return openerp.modules.registry.RegistryManager.get(DB)[model]
def cursor():
return openerp.modules.registry.RegistryManager.get(DB).db.cursor()
return openerp.modules.registry.RegistryManager.get(DB).cursor()
def get_module(module_name):
registry = openerp.modules.registry.RegistryManager.get(DB)

View File

@ -28,7 +28,7 @@ class ViewCase(common.TransactionCase):
self.assertTreesEqual(c1, c2, msg)
class TestNodeLocator(common.BaseCase):
class TestNodeLocator(common.TransactionCase):
"""
The node locator returns None when it can not find a node, and the first
match when it finds something (no jquery-style node sets)

View File

@ -111,7 +111,7 @@ def export_translation():
fileformat = os.path.splitext(config["translate_out"])[-1][1:].lower()
buf = file(config["translate_out"], "w")
registry = openerp.modules.registry.RegistryManager.new(dbname)
cr = registry.db.cursor()
cr = registry.cursor()
openerp.tools.trans_export(config["language"],
config["translate_modules"] or ["all"], buf, fileformat, cr)
cr.close()
@ -125,7 +125,7 @@ def import_translation():
dbname = config['db_name']
registry = openerp.modules.registry.RegistryManager.new(dbname)
cr = registry.db.cursor()
cr = registry.cursor()
openerp.tools.trans_load( cr, config["translate_in"], config["language"],
context=context)
cr.commit()

View File

@ -235,10 +235,7 @@ class WebRequest(object):
"""
# some magic to lazy create the cr
if not self._cr:
# Test cursors
self._cr = openerp.tests.common.acquire_test_cursor(self.session_id)
if not self._cr:
self._cr = self.registry.db.cursor()
self._cr = self.registry.cursor()
return self._cr
def __enter__(self):
@ -249,14 +246,9 @@ class WebRequest(object):
_request_stack.pop()
if self._cr:
# Dont close test cursors
if not openerp.tests.common.release_test_cursor(self._cr):
if exc_type is None and not self._failed:
self._cr.commit()
else:
# just to be explicit - happens at close() anyway
self._cr.rollback()
self._cr.close()
if exc_type is None and not self._failed:
self._cr.commit()
self._cr.close()
# just to be sure no one tries to re-use the request
self.disable_db = True
self.uid = None
@ -294,7 +286,7 @@ class WebRequest(object):
def checked_call(___dbname, *a, **kw):
# The decorator can call us more than once if there is an database error. In this
# case, the request cursor is unusable. Rollback transaction to create a new one.
if self._cr and not openerp.tools.config['test_enable']:
if self._cr:
self._cr.rollback()
return self.endpoint(*a, **kw)

View File

@ -58,7 +58,10 @@ class Registry(Mapping):
self._init_modules = set()
self.db_name = db_name
self.db = openerp.sql_db.db_connect(db_name)
self._db = openerp.sql_db.db_connect(db_name)
# special cursor for test mode; None means "normal" mode
self.test_cr = None
# Indicates that the registry is
self.ready = False
@ -75,7 +78,7 @@ class Registry(Mapping):
# Useful only in a multi-process context.
self._any_cache_cleared = False
cr = self.db.cursor()
cr = self.cursor()
has_unaccent = openerp.modules.db.has_unaccent(cr)
if openerp.tools.config['unaccent'] and not has_unaccent:
_logger.warning("The option --unaccent was given but no unaccent() function was found in database.")
@ -102,6 +105,10 @@ class Registry(Mapping):
""" Return the model with the given name or raise KeyError if it doesn't exist."""
return self.models[model_name]
def __call__(self, model_name):
""" Same as ``self[model_name]``. """
return self.models[model_name]
def do_parent_store(self, cr):
for o in self._init_parent:
self.get(o)._parent_store_compute(cr)
@ -183,27 +190,38 @@ class Registry(Mapping):
r, c)
return r, c
@contextmanager
def cursor(self, auto_commit=True):
cr = self.db.cursor()
try:
yield cr
if auto_commit:
cr.commit()
finally:
cr.close()
def enter_test_mode(self):
""" Enter the 'test' mode, where one cursor serves several requests. """
assert self.test_cr is None
self.test_cr = self._db.test_cursor()
RegistryManager.enter_test_mode()
class TestRLock(object):
def __init__(self):
self._lock = threading.RLock()
def leave_test_mode(self):
""" Leave the test mode. """
assert self.test_cr is not None
self.test_cr.close(force=True) # close the cursor for real
self.test_cr = None
RegistryManager.leave_test_mode()
def cursor(self):
""" Return a new cursor for the database. The cursor itself may be used
as a context manager to commit/rollback and close automatically.
"""
if self.test_cr is not None:
# While in test mode, we use one special cursor across requests. The
# test cursor uses a reentrant lock to serialize accesses. The lock
# is granted here by cursor(), and automatically released by the
# cursor itself in its method close().
self.test_cr.acquire()
return self.test_cr
return self._db.cursor()
class DummyRLock(object):
""" Dummy reentrant lock, to be used while running rpc and js tests """
def acquire(self):
if openerp.tools.config['test_enable']:
return
return self._lock.acquire()
pass
def release(self):
if openerp.tools.config['test_enable']:
return
return self._lock.release()
pass
def __enter__(self):
self.acquire()
def __exit__(self, type, value, traceback):
@ -219,12 +237,30 @@ class RegistryManager(object):
# Mapping between db name and model registry.
# Accessed through the methods below.
registries = {}
registries_lock = TestRLock()
_lock = threading.RLock()
_saved_lock = None
@classmethod
def lock(cls):
""" Return the current registry lock. """
return cls._lock
@classmethod
def enter_test_mode(cls):
""" Enter the 'test' mode, where the registry is no longer locked. """
assert cls._saved_lock is None
cls._lock, cls._saved_lock = DummyRLock(), cls._lock
@classmethod
def leave_test_mode(cls):
""" Leave the 'test' mode. """
assert cls._saved_lock is not None
cls._lock, cls._saved_lock = cls._saved_lock, None
@classmethod
def get(cls, db_name, force_demo=False, status=None, update_module=False):
""" Return a registry for a given database name."""
with cls.registries_lock:
with cls.lock():
try:
return cls.registries[db_name]
except KeyError:
@ -244,7 +280,7 @@ class RegistryManager(object):
"""
import openerp.modules
with cls.registries_lock:
with cls.lock():
registry = Registry(db_name)
# Initializing a registry will call general code which will in turn
@ -259,7 +295,7 @@ class RegistryManager(object):
registry.base_registry_signaling_sequence = seq_registry
registry.base_cache_signaling_sequence = seq_cache
# This should be a method on Registry
openerp.modules.load_modules(registry.db, force_demo, status, update_module)
openerp.modules.load_modules(registry._db, force_demo, status, update_module)
except Exception:
del cls.registries[db_name]
raise
@ -269,7 +305,7 @@ class RegistryManager(object):
# Yeah, crazy.
registry = cls.registries[db_name]
cr = registry.db.cursor()
cr = registry.cursor()
try:
registry.do_parent_store(cr)
cr.commit()
@ -286,7 +322,7 @@ class RegistryManager(object):
@classmethod
def delete(cls, db_name):
"""Delete the registry linked to a given database. """
with cls.registries_lock:
with cls.lock():
if db_name in cls.registries:
cls.registries[db_name].clear_caches()
del cls.registries[db_name]
@ -294,7 +330,7 @@ class RegistryManager(object):
@classmethod
def delete_all(cls):
"""Delete all the registries. """
with cls.registries_lock:
with cls.lock():
for db_name in cls.registries.keys():
cls.delete(db_name)
@ -309,7 +345,7 @@ class RegistryManager(object):
This method is given to spare you a ``RegistryManager.get(db_name)``
that would loads the given database if it was not already loaded.
"""
with cls.registries_lock:
with cls.lock():
if db_name in cls.registries:
cls.registries[db_name].clear_caches()
@ -325,7 +361,7 @@ class RegistryManager(object):
changed = False
if openerp.multi_process and db_name in cls.registries:
registry = cls.get(db_name)
cr = registry.db.cursor()
cr = registry.cursor()
try:
cr.execute("""
SELECT base_registry_signaling.last_value,
@ -371,7 +407,7 @@ class RegistryManager(object):
registry = cls.get(db_name)
if registry.any_cache_cleared():
_logger.info("At least one model cache has been cleared, signaling through the database.")
cr = registry.db.cursor()
cr = registry.cursor()
r = 1
try:
cr.execute("select nextval('base_cache_signaling')")
@ -386,7 +422,7 @@ class RegistryManager(object):
if openerp.multi_process and db_name in cls.registries:
_logger.info("Registry changed, signaling through the database")
registry = cls.get(db_name)
cr = registry.db.cursor()
cr = registry.cursor()
r = 1
try:
cr.execute("select nextval('base_registry_signaling')")

View File

@ -1182,14 +1182,15 @@ class expression(object):
else:
need_wildcard = operator in ('like', 'ilike', 'not like', 'not ilike')
sql_operator = {'=like': 'like', '=ilike': 'ilike'}.get(operator, operator)
cast = '::text' if sql_operator.endswith('like') else ''
if left in model._columns:
format = need_wildcard and '%s' or model._columns[left]._symbol_set[0]
unaccent = self._unaccent if sql_operator.endswith('like') else lambda x: x
column = '%s.%s' % (table_alias, _quote(left))
query = '(%s %s %s)' % (unaccent(column), sql_operator, unaccent(format))
query = '(%s%s %s %s)' % (unaccent(column), cast, sql_operator, unaccent(format))
elif left in MAGIC_COLUMNS:
query = "(%s.\"%s\" %s %%s)" % (table_alias, left, sql_operator)
query = "(%s.\"%s\"%s %s %%s)" % (table_alias, left, cast, sql_operator)
params = right
else: # Must not happen
raise ValueError("Invalid field %r in domain term %r" % (left, leaf))

View File

@ -36,7 +36,7 @@ def get_db_and_pool(db_name, force_demo=False, status=None, update_module=False)
assert openerp.conf.deprecation.openerp_pooler
_logger.warning('openerp.pooler.get_db_and_pool() is deprecated.')
registry = RegistryManager.get(db_name, force_demo, status, update_module)
return registry.db, registry
return registry._db, registry
def restart_pool(db_name, force_demo=False, status=None, update_module=False):
@ -44,7 +44,7 @@ def restart_pool(db_name, force_demo=False, status=None, update_module=False):
_logger.warning('openerp.pooler.restart_pool() is deprecated.')
assert openerp.conf.deprecation.openerp_pooler
registry = RegistryManager.new(db_name, force_demo, status, update_module)
return registry.db, registry
return registry._db, registry
def get_db(db_name):
"""Return a database connection. The corresponding registry is initialized."""

View File

@ -161,21 +161,10 @@ def execute_cr(cr, uid, obj, method, *args, **kw):
def execute_kw(db, uid, obj, method, args, kw=None):
return execute(db, uid, obj, method, *args, **kw or {})
@contextmanager
def closing_cr_and_commit(cr):
try:
yield cr
cr.commit()
except Exception:
cr.rollback()
raise
finally:
cr.close()
@check
def execute(db, uid, obj, method, *args, **kw):
threading.currentThread().dbname = db
with closing_cr_and_commit(openerp.registry(db).db.cursor()) as cr:
with openerp.registry(db).cursor() as cr:
if method.startswith('_'):
raise except_orm('Access Denied', 'Private methods (such as %s) cannot be called remotely.' % (method,))
res = execute_cr(cr, uid, obj, method, *args, **kw)
@ -190,7 +179,7 @@ def exec_workflow_cr(cr, uid, obj, signal, *args):
@check
def exec_workflow(db, uid, obj, signal, *args):
with closing_cr_and_commit(openerp.registry(db).db.cursor()) as cr:
with openerp.registry(db).cursor() as cr:
return exec_workflow_cr(cr, uid, obj, signal, *args)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -49,7 +49,7 @@ def exp_render_report(db, uid, object, ids, datas=None, context=None):
self_reports[id] = {'uid': uid, 'result': False, 'state': False, 'exception': None}
cr = openerp.registry(db).db.cursor()
cr = openerp.registry(db).cursor()
try:
result, format = openerp.report.render_report(cr, uid, ids, object, datas, context)
if not result:
@ -87,7 +87,7 @@ def exp_report(db, uid, object, ids, datas=None, context=None):
self_reports[id] = {'uid': uid, 'result': False, 'state': False, 'exception': None}
def go(id, uid, ids, datas, context):
cr = openerp.registry(db).db.cursor()
cr = openerp.registry(db).cursor()
try:
result, format = openerp.report.render_report(cr, uid, ids, object, datas, context)
if not result:

View File

@ -167,7 +167,7 @@ class Cursor(object):
self.sql_log_count = 0
self._closed = True # avoid the call of close() (by __del__) if an exception
# is raised by any of the following initialisations
self._pool = pool
self.__pool = pool
self.dbname = dbname
# Whether to enable snapshot isolation level for this cursor.
@ -313,7 +313,7 @@ class Cursor(object):
chosen_template = tools.config['db_template']
templates_list = tuple(set(['template0', 'template1', 'postgres', chosen_template]))
keep_in_pool = self.dbname not in templates_list
self._pool.give_back(self._cnx, keep_in_pool=keep_in_pool)
self.__pool.give_back(self._cnx, keep_in_pool=keep_in_pool)
@check
def autocommit(self, on):
@ -347,6 +347,23 @@ class Cursor(object):
"""
return self._cnx.rollback()
def __enter__(self):
""" Using the cursor as a contextmanager automatically commits and
closes it::
with cr:
cr.execute(...)
# cr is committed if no failure occurred
# cr is closed in any case
"""
return self
def __exit__(self, exc_type, exc_value, traceback):
if exc_type is None:
self.commit()
self.close()
@contextmanager
@check
def savepoint(self):
@ -364,6 +381,42 @@ class Cursor(object):
def __getattr__(self, name):
return getattr(self._obj, name)
class TestCursor(Cursor):
""" A cursor to be used for tests. It keeps the transaction open across
several requests, and simulates committing, rolling back, and closing.
"""
def __init__(self, *args, **kwargs):
super(TestCursor, self).__init__(*args, **kwargs)
# in order to simulate commit and rollback, the cursor maintains a
# savepoint at its last commit
self.execute("SAVEPOINT test_cursor")
# we use a lock to serialize concurrent requests
self._lock = threading.RLock()
def acquire(self):
self._lock.acquire()
def release(self):
self._lock.release()
def close(self, force=False):
if force:
super(TestCursor, self).close()
elif not self._closed:
self.rollback() # for stuff that has not been committed
self.release()
def autocommit(self, on):
_logger.debug("TestCursor.autocommit(%r) does nothing", on)
def commit(self):
self.execute("RELEASE SAVEPOINT test_cursor")
self.execute("SAVEPOINT test_cursor")
def rollback(self):
self.execute("ROLLBACK TO SAVEPOINT test_cursor")
self.execute("SAVEPOINT test_cursor")
class PsycoConnection(psycopg2.extensions.connection):
pass
@ -484,12 +537,17 @@ class Connection(object):
def __init__(self, pool, dbname):
self.dbname = dbname
self._pool = pool
self.__pool = pool
def cursor(self, serialized=True):
cursor_type = serialized and 'serialized ' or ''
_logger.debug('create %scursor to %r', cursor_type, self.dbname)
return Cursor(self._pool, self.dbname, serialized=serialized)
return Cursor(self.__pool, self.dbname, serialized=serialized)
def test_cursor(self, serialized=True):
cursor_type = serialized and 'serialized ' or ''
_logger.debug('create test %scursor to %r', cursor_type, self.dbname)
return TestCursor(self.__pool, self.dbname, serialized=serialized)
# serialized_cursor is deprecated - cursors are serialized by default
serialized_cursor = cursor

View File

@ -20,6 +20,7 @@ from datetime import datetime, timedelta
import werkzeug
import openerp
from openerp.modules.registry import RegistryManager
_logger = logging.getLogger(__name__)
@ -37,25 +38,6 @@ if not DB and hasattr(threading.current_thread(), 'dbname'):
# Useless constant, tests are aware of the content of demo data
ADMIN_USER_ID = openerp.SUPERUSER_ID
# Magic session_id, unfortunately we have to serialize access to the cursors to
# serialize requests. We first tried to duplicate the database for each tests
# but this proved too slow. Any idea to improve this is welcome.
HTTP_SESSION = {}
def acquire_test_cursor(session_id):
if openerp.tools.config['test_enable']:
cr = HTTP_SESSION.get(session_id)
if cr:
cr._test_lock.acquire()
return cr
def release_test_cursor(cr):
if openerp.tools.config['test_enable']:
if hasattr(cr, '_test_lock'):
cr._test_lock.release()
return True
return False
def at_install(flag):
""" Sets the at-install state of a test, the flag is a boolean specifying
whether the test should (``True``) or should not (``False``) run during
@ -67,6 +49,7 @@ def at_install(flag):
obj.at_install = flag
return obj
return decorator
def post_install(flag):
""" Sets the post-install state of a test. The flag is a boolean
specifying whether the test should or should not run after a set of
@ -83,18 +66,13 @@ class BaseCase(unittest2.TestCase):
"""
Subclass of TestCase for common OpenERP-specific code.
This class is abstract and expects self.cr and self.uid to be initialized by subclasses.
This class is abstract and expects self.registry, self.cr and self.uid to be
initialized by subclasses.
"""
@classmethod
def cursor(self):
return openerp.modules.registry.RegistryManager.get(DB).db.cursor()
return self.registry.cursor()
@classmethod
def registry(self, model):
return openerp.modules.registry.RegistryManager.get(DB)[model]
@classmethod
def ref(self, xid):
""" Returns database ID corresponding to a given identifier.
@ -106,7 +84,6 @@ class BaseCase(unittest2.TestCase):
_, id = self.registry('ir.model.data').get_object_reference(self.cr, self.uid, module, xid)
return id
@classmethod
def browse_ref(self, xid):
""" Returns a browsable record for the given identifier.
@ -125,10 +102,9 @@ class TransactionCase(BaseCase):
"""
def setUp(self):
# Store cr and uid in class variables, to allow ref() and browse_ref to be BaseCase @classmethods
# and still access them
TransactionCase.cr = self.cursor()
TransactionCase.uid = openerp.SUPERUSER_ID
self.registry = RegistryManager.get(DB)
self.cr = self.cursor()
self.uid = openerp.SUPERUSER_ID
def tearDown(self):
self.cr.rollback()
@ -143,7 +119,8 @@ class SingleTransactionCase(BaseCase):
@classmethod
def setUpClass(cls):
cls.cr = cls.cursor()
cls.registry = RegistryManager.get(DB)
cls.cr = cls.registry.cursor()
cls.uid = openerp.SUPERUSER_ID
@classmethod
@ -166,16 +143,15 @@ class HttpCase(TransactionCase):
def setUp(self):
super(HttpCase, self).setUp()
self.registry.enter_test_mode()
# setup a magic session_id that will be rollbacked
self.session = openerp.http.root.session_store.new()
self.session_id = self.session.sid
self.session.db = DB
openerp.http.root.session_store.save(self.session)
self.cr._test_lock = threading.RLock()
HTTP_SESSION[self.session_id] = self.cr
def tearDown(self):
del HTTP_SESSION[self.session_id]
self.registry.leave_test_mode()
super(HttpCase, self).tearDown()
def url_open(self, url, data=None, timeout=10):

View File

@ -625,7 +625,7 @@ def email_send(email_from, email_to, subject, body, email_cc=None, email_bcc=Non
if not cr:
db_name = getattr(threading.currentThread(), 'dbname', None)
if db_name:
local_cr = cr = openerp.registry(db_name).db.cursor()
local_cr = cr = openerp.registry(db_name).cursor()
else:
raise Exception("No database cursor found, please pass one explicitly")

View File

@ -71,7 +71,8 @@ _SAFE_OPCODES = _EXPR_OPCODES.union(set(opmap[x] for x in [
'CONTINUE_LOOP', 'RAISE_VARARGS',
# New in Python 2.7 - http://bugs.python.org/issue4715 :
'JUMP_IF_FALSE_OR_POP', 'JUMP_IF_TRUE_OR_POP', 'POP_JUMP_IF_FALSE',
'POP_JUMP_IF_TRUE', 'SETUP_EXCEPT', 'END_FINALLY'
'POP_JUMP_IF_TRUE', 'SETUP_EXCEPT', 'END_FINALLY', 'LOAD_FAST',
'LOAD_GLOBAL', # Only allows access to restricted globals
] if x in opmap))
_logger = logging.getLogger(__name__)
@ -86,16 +87,65 @@ def _get_opcodes(codeobj):
[100, 100, 23, 100, 100, 102, 103, 83]
"""
i = 0
opcodes = []
byte_codes = codeobj.co_code
while i < len(byte_codes):
code = ord(byte_codes[i])
opcodes.append(code)
yield code
if code >= HAVE_ARGUMENT:
i += 3
else:
i += 1
return opcodes
def assert_no_dunder_name(code_obj, expr):
""" assert_no_dunder_name(code_obj, expr) -> None
Asserts that the code object does not refer to any "dunder name"
(__$name__), so that safe_eval prevents access to any internal-ish Python
attribute or method (both are loaded via LOAD_ATTR which uses a name, not a
const or a var).
Checks that no such name exists in the provided code object (co_names).
:param code_obj: code object to name-validate
:type code_obj: CodeType
:param str expr: expression corresponding to the code object, for debugging
purposes
:raises NameError: in case a forbidden name (containing two underscores)
is found in ``code_obj``
.. note:: actually forbids every name containing 2 underscores
"""
for name in code_obj.co_names:
if "__" in name:
raise NameError('Access to forbidden name %r (%r)' % (name, expr))
def assert_valid_codeobj(allowed_codes, code_obj, expr):
""" Asserts that the provided code object validates against the bytecode
and name constraints.
Recursively validates the code objects stored in its co_consts in case
lambdas are being created/used (lambdas generate their own separated code
objects and don't live in the root one)
:param allowed_codes: list of permissible bytecode instructions
:type allowed_codes: set(int)
:param code_obj: code object to name-validate
:type code_obj: CodeType
:param str expr: expression corresponding to the code object, for debugging
purposes
:raises ValueError: in case of forbidden bytecode in ``code_obj``
:raises NameError: in case a forbidden name (containing two underscores)
is found in ``code_obj``
"""
assert_no_dunder_name(code_obj, expr)
for opcode in _get_opcodes(code_obj):
if opcode not in allowed_codes:
raise ValueError(
"opcode %s not allowed (%r)" % (opname[opcode], expr))
for const in code_obj.co_consts:
if isinstance(const, CodeType):
assert_valid_codeobj(allowed_codes, const, 'lambda')
def test_expr(expr, allowed_codes, mode="eval"):
"""test_expr(expression, allowed_codes[, mode]) -> code_object
@ -110,15 +160,13 @@ def test_expr(expr, allowed_codes, mode="eval"):
# eval() does not like leading/trailing whitespace
expr = expr.strip()
code_obj = compile(expr, "", mode)
except (SyntaxError, TypeError):
except (SyntaxError, TypeError, ValueError):
raise
except Exception, e:
import sys
exc_info = sys.exc_info()
raise ValueError, '"%s" while compiling\n%r' % (ustr(e), expr), exc_info[2]
for code in _get_opcodes(code_obj):
if code not in allowed_codes:
raise ValueError("opcode %s not allowed (%r)" % (opname[code], expr))
assert_valid_codeobj(allowed_codes, code_obj, expr)
return code_obj
@ -187,19 +235,13 @@ def safe_eval(expr, globals_dict=None, locals_dict=None, mode="eval", nocopy=Fal
This can be used to e.g. evaluate
an OpenERP domain expression from an untrusted source.
Throws TypeError, SyntaxError or ValueError (not allowed) accordingly.
>>> safe_eval("__import__('sys').modules")
Traceback (most recent call last):
...
ValueError: opcode LOAD_NAME not allowed
:throws TypeError: If the expression provided is a code object
:throws SyntaxError: If the expression provided is not valid Python
:throws NameError: If the expression provided accesses forbidden names
:throws ValueError: If the expression provided uses forbidden bytecode
"""
if isinstance(expr, CodeType):
raise ValueError("safe_eval does not allow direct evaluation of code objects.")
if '__subclasses__' in expr:
raise ValueError('expression not allowed (__subclasses__)')
raise TypeError("safe_eval does not allow direct evaluation of code objects.")
if globals_dict is None:
globals_dict = {}

View File

@ -38,7 +38,7 @@ _logger = logging.getLogger(__name__)
_test_logger = logging.getLogger('openerp.tests')
def try_report(cr, uid, rname, ids, data=None, context=None, our_module=None):
def try_report(cr, uid, rname, ids, data=None, context=None, our_module=None, report_type=None):
""" Try to render a report <rname> with contents of ids
This function should also check for common pitfalls of reports.
@ -114,7 +114,6 @@ def try_report_action(cr, uid, action_id, active_model=None, active_ids=None,
Eg. 'OK' or 'gtk-print'
:param our_module: the name of the calling module (string), like 'account'
"""
if not our_module and isinstance(action_id, basestring):
if '.' in action_id:
our_module = action_id.split('.', 1)[0]
@ -161,7 +160,10 @@ def try_report_action(cr, uid, action_id, active_model=None, active_ids=None,
# Updating the context : Adding the context of action in order to use it on Views called from buttons
if datas.get('id',False):
context.update( {'active_id': datas.get('id',False), 'active_ids': datas.get('ids',[]), 'active_model': datas.get('model',False)})
context.update(safe_eval(action.get('context','{}'), context.copy()))
context1 = action.get('context', {})
if isinstance(context1, basestring):
context1 = safe_eval(context1, context.copy())
context.update(context1)
if action['type'] in ['ir.actions.act_window', 'ir.actions.submenu']:
for key in ('res_id', 'res_model', 'view_type', 'view_mode',
'limit', 'auto_refresh', 'search_view', 'auto_search', 'search_view_id'):
@ -272,7 +274,9 @@ def try_report_action(cr, uid, action_id, active_model=None, active_ids=None,
if 'window' in datas:
del datas['window']
if not datas:
datas = action.get('datas',{})
datas = action.get('datas')
if not datas:
datas = action.get('data')
datas = datas.copy()
ids = datas.get('ids')
if 'ids' in datas:
@ -303,6 +307,4 @@ def try_report_action(cr, uid, action_id, active_model=None, active_ids=None,
return True
#eof
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -33,12 +33,9 @@ def run(args):
xs = []
ir_module_module = registry.get('ir.module.module')
cr = registry.db.cursor() # TODO context manager
try:
with registry.cursor() as cr:
ids = ir_module_module.search(cr, openerp.SUPERUSER_ID, [], {})
xs = ir_module_module.read(cr, openerp.SUPERUSER_ID, ids, [], {})
finally:
cr.close()
if xs:
print "Modules (database `%s`):" % (args.database,)

View File

@ -20,15 +20,12 @@ def run(args):
registry = openerp.modules.registry.RegistryManager.get(
args.database, update_module=False)
model = registry[args.model]
cr = registry.db.cursor() # TODO context manager
field_names = [args.field] if args.field else []
if args.short:
# ignore --field
field_names = ['name']
try:
with registry.cursor() as cr:
xs = model.read(cr, 1, args.id, field_names, {})
finally:
cr.close()
if xs:
print "Records (model `%s`, database `%s`):" % (args.model, args.database)

View File

@ -43,15 +43,12 @@ def run(args):
args.database, update_module=False)
ir_module_module = registry.get('ir.module.module')
cr = registry.db.cursor() # TODO context manager
try:
with registry.cursor() as cr:
ids = ir_module_module.search(cr, openerp.SUPERUSER_ID, [('name', 'in', args.module), ('state', '=', 'installed')], {})
if len(ids) == len(args.module):
ir_module_module.button_immediate_uninstall(cr, openerp.SUPERUSER_ID, ids, {})
else:
print "At least one module not found (database `%s`)." % (args.database,)
finally:
cr.close()
def add_parser(subparsers):
parser = subparsers.add_parser('uninstall',

View File

@ -150,7 +150,7 @@ setuptools.setup(
#include_package_data = True,
install_requires = [
'pychart', # not on pypi, use: pip install http://download.gna.org/pychart/PyChart-1.39.tar.gz
'babel',
'babel >= 1.0',
'docutils',
'feedparser',
'gdata',
@ -171,7 +171,7 @@ setuptools.setup(
'python-openid',
'pytz',
'pyusb >= 1.0.0b1',
'pywebdav',
'pywebdav <= 0.9.4',
'pyyaml',
'qrcode',
'reportlab', # windows binary pypi.python.org/pypi/reportlab