Browse Source
Merge pull request #46 from acsone/8.0help_online_export
Merge pull request #46 from acsone/8.0help_online_export
[8.0] Help online: new featurespull/52/head
Yannick Vaucher
10 years ago
21 changed files with 1114 additions and 3 deletions
-
1.travis.yml
-
9help_online/__openerp__.py
-
9help_online/data/help_auto_backup.xml
-
25help_online/data/ir_config_parameter_data.xml
-
222help_online/i18n/fr.po
-
3help_online/models/__init__.py
-
275help_online/models/export_help_wizard.py
-
11help_online/models/help_online.py
-
49help_online/models/import_help_wizard.py
-
73help_online/models/ir_model.py
-
32help_online/security/help_online_rules.xml
-
BINhelp_online/static/description/icon.png
-
1help_online/static/description/index.html
-
BINhelp_online/static/src/img/snippet/snippet_thumbs.png
-
27help_online/tests/__init__.py
-
78help_online/tests/data/help_test_data.xml
-
161help_online/tests/test_export_help_wizard.py
-
52help_online/views/export_help_wizard_view.xml
-
15help_online/views/help_online_view.xml
-
46help_online/views/import_help_wizard_view.xml
-
28help_online/views/ir_ui_view_view.xml
@ -0,0 +1,9 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<openerp> |
||||
|
<data noupdate="0"> |
||||
|
<record id="wz_auto_backup" model="export.help.wizard"> |
||||
|
</record> |
||||
|
|
||||
|
<function model="export.help.wizard" name="auto_backup"/> |
||||
|
</data> |
||||
|
</openerp> |
@ -0,0 +1,25 @@ |
|||||
|
<?xml version='1.0' encoding='UTF-8' ?> |
||||
|
<openerp> |
||||
|
|
||||
|
<data noupdate="1"> |
||||
|
<record id="help_online_autobackup_path" model="ir.config_parameter"> |
||||
|
<field name="key">help_online_autobackup_path</field> |
||||
|
<field name="value">False</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
|
||||
|
<data noupdate="1"> |
||||
|
<record id="help_online_page_prefix" model="ir.config_parameter"> |
||||
|
<field name="key">help_online_page_prefix</field> |
||||
|
<field name="value">help</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
|
||||
|
<data noupdate="1"> |
||||
|
<record id="help_online_template_prefix" model="ir.config_parameter"> |
||||
|
<field name="key">help_online_template_prefix</field> |
||||
|
<field name="value">help-template</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
|
||||
|
</openerp> |
@ -0,0 +1,222 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * help_online |
||||
|
# |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 8.0\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2014-10-14 09:06+0000\n" |
||||
|
"PO-Revision-Date: 2014-10-14 09:06+0000\n" |
||||
|
"Last-Translator: <>\n" |
||||
|
"Language-Team: \n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Plural-Forms: \n" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#. openerp-web |
||||
|
#: code:addons/help_online/static/src/js/help_online.js:83 |
||||
|
#, python-format |
||||
|
msgid "Cancel" |
||||
|
msgstr "Annuler" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#: view:export.help.wizard:help_online.export_help_wizard_view |
||||
|
#: view:import.help.wizard:help_online.import_help_wizard_view |
||||
|
msgid "Close" |
||||
|
msgstr "Fermer" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#. openerp-web |
||||
|
#: code:addons/help_online/static/src/js/help_online.js:81 |
||||
|
#, python-format |
||||
|
msgid "Confirm" |
||||
|
msgstr "Confirmer" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#: code:addons/help_online/models/help_online.py:60 |
||||
|
#, python-format |
||||
|
msgid "Create Help page for %s" |
||||
|
msgstr "Créer la page d'aide pour %s" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#: field:export.help.wizard,create_uid:0 |
||||
|
#: field:help.online,create_uid:0 |
||||
|
#: field:import.help.wizard,create_uid:0 |
||||
|
msgid "Created by" |
||||
|
msgstr "Créé par" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#: field:export.help.wizard,create_date:0 |
||||
|
#: field:help.online,create_date:0 |
||||
|
#: field:import.help.wizard,create_date:0 |
||||
|
msgid "Created on" |
||||
|
msgstr "Créé le" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#: view:export.help.wizard:help_online.export_help_wizard_view |
||||
|
msgid "Export" |
||||
|
msgstr "Export" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#: model:ir.actions.act_window,name:help_online.action_export_help_wizard |
||||
|
msgid "Export Help" |
||||
|
msgstr "Export des pages d'aide" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#: view:export.help.wizard:help_online.export_help_wizard_view |
||||
|
msgid "Export Help Data" |
||||
|
msgstr "Export des pages d'aide" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#: model:ir.model,name:help_online.model_export_help_wizard |
||||
|
#: model:ir.ui.menu,name:help_online.menu_help_export |
||||
|
msgid "Export Help Online" |
||||
|
msgstr "Export des pages d'aide" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#: field:export.help.wizard,export_filename:0 |
||||
|
msgid "Export XML Filename" |
||||
|
msgstr "Fichier XML" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#: model:ir.ui.menu,name:help_online.menu_help |
||||
|
#: model:ir.ui.menu,name:help_online.menu_help_main |
||||
|
msgid "Help Online" |
||||
|
msgstr "Aide en ligne" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#: code:addons/help_online/models/help_online.py:55 |
||||
|
#, python-format |
||||
|
msgid "Help on %s" |
||||
|
msgstr "Aide sur %s" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#: model:res.groups,name:help_online.help_online_group_reader |
||||
|
msgid "Help reader" |
||||
|
msgstr "Aide: lecteur" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#: model:res.groups,name:help_online.help_online_group_writer |
||||
|
msgid "Help writer" |
||||
|
msgstr "Aide: rédacteur" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#: field:export.help.wizard,id:0 |
||||
|
#: field:help.online,id:0 |
||||
|
#: field:import.help.wizard,id:0 |
||||
|
msgid "ID" |
||||
|
msgstr "ID" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#: view:import.help.wizard:help_online.import_help_wizard_view |
||||
|
msgid "Import" |
||||
|
msgstr "Import" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#: model:ir.actions.act_window,name:help_online.action_import_help_wizard |
||||
|
msgid "Import Help" |
||||
|
msgstr "Import des pages d'aide" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#: view:import.help.wizard:help_online.import_help_wizard_view |
||||
|
msgid "Import Help Data" |
||||
|
msgstr "Import des pages d'aide" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#: model:ir.ui.menu,name:help_online.menu_help_import |
||||
|
msgid "Import Help Online" |
||||
|
msgstr "Import des pages d'aide" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#: field:export.help.wizard,write_uid:0 |
||||
|
#: field:help.online,write_uid:0 |
||||
|
#: field:import.help.wizard,write_uid:0 |
||||
|
msgid "Last Updated by" |
||||
|
msgstr "Mis à jour par" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#: field:export.help.wizard,write_date:0 |
||||
|
#: field:help.online,write_date:0 |
||||
|
#: field:import.help.wizard,write_date:0 |
||||
|
msgid "Last Updated on" |
||||
|
msgstr "Mis à jour le" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#: code:addons/help_online/models/export_help_wizard.py:238 |
||||
|
#, python-format |
||||
|
msgid "No data to export !" |
||||
|
msgstr "Aucune page à exporter !" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#: code:addons/help_online/models/help_online.py:33 |
||||
|
#, python-format |
||||
|
msgid "No page prefix parameter specified !" |
||||
|
msgstr "Le paramètre spécifiant le préfixe des pages n'est pas configuré !" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#. openerp-web |
||||
|
#: code:addons/help_online/static/src/js/help_online.js:88 |
||||
|
#, python-format |
||||
|
msgid "Ok" |
||||
|
msgstr "Ok" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#. openerp-web |
||||
|
#: code:addons/help_online/static/src/js/help_online.js:107 |
||||
|
#, python-format |
||||
|
msgid "Page does not exist. Do you want to create?" |
||||
|
msgstr "La page n'existe pas. Voulez-vous la créer?" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#: field:import.help.wizard,source_file:0 |
||||
|
msgid "Source File" |
||||
|
msgstr "Fichier de données" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#: view:export.help.wizard:help_online.export_help_wizard_view |
||||
|
msgid "This wizard allow you to export all QWeb views\n" |
||||
|
" related to help online. The result will be an Odoo\n" |
||||
|
" data xml file." |
||||
|
msgstr "Cet assistant vous permet d'exporter toutes les vues QWeb \n" |
||||
|
" concernant l'aide. Le résultat sera un\n" |
||||
|
" fichier de données Odoo." |
||||
|
|
||||
|
#. module: help_online |
||||
|
#: view:import.help.wizard:help_online.import_help_wizard_view |
||||
|
msgid "This wizard allow you to import QWeb views\n" |
||||
|
" related to help online. The required file format is an Odoo\n" |
||||
|
" data xml file." |
||||
|
msgstr "Cet assistant vous permet d'importer toutes les vues QWeb\n" |
||||
|
" concernant l'aide. Le format de fichier requis est un\n" |
||||
|
" fichier de données Odoo." |
||||
|
|
||||
|
#. module: help_online |
||||
|
#: code:addons/help_online/models/export_help_wizard.py:275 |
||||
|
#, python-format |
||||
|
msgid "Unable to write autobackup file in given directory: %s" |
||||
|
msgstr "Impossible d'écrire le fichier de sauvegarde dans le répertoire spécifié: %s" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#: view:ir.ui.view:help_online.view_view_search |
||||
|
msgid "Website Page" |
||||
|
msgstr "Page du site" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#: view:ir.ui.view:help_online.view_view_form |
||||
|
msgid "Website Page?" |
||||
|
msgstr "Page du site?" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#: model:ir.actions.act_window,name:help_online.action_website_pages |
||||
|
#: model:ir.ui.menu,name:help_online.menu_help_pages |
||||
|
msgid "Website Pages" |
||||
|
msgstr "Pages du site" |
||||
|
|
||||
|
#. module: help_online |
||||
|
#: field:export.help.wizard,data:0 |
||||
|
msgid "XML" |
||||
|
msgstr "XML" |
||||
|
|
@ -0,0 +1,275 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Authors: Cédric Pigeon |
||||
|
# Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu) |
||||
|
# |
||||
|
# This program is free software: you can redistribute it and/or modify |
||||
|
# it under the terms of the GNU Affero General Public License as published |
||||
|
# by the Free Software Foundation, either version 3 of the License, or |
||||
|
# (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU Affero General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
import logging |
||||
|
import base64 |
||||
|
import time |
||||
|
import copy |
||||
|
|
||||
|
from lxml import etree as ET |
||||
|
from openerp import models, fields, api, exceptions |
||||
|
from openerp.tools.translate import _ |
||||
|
|
||||
|
_logger = logging.getLogger(__name__) |
||||
|
|
||||
|
PAGE_PREFIX_PARAMETER = 'help_online_page_prefix' |
||||
|
TEMPLATE_PREFIX_PARAMETER = 'help_online_template_prefix' |
||||
|
AUTOBACKUP_PARAMETER = 'help_online_autobackup_path' |
||||
|
HELP_ONLINE_SNIPPET_IMAGE_PATH = '/help_online/static/src/'\ |
||||
|
'img/snippet/snippet_thumbs.png' |
||||
|
|
||||
|
|
||||
|
class ExportHelpWizard(models.TransientModel): |
||||
|
_name = "export.help.wizard" |
||||
|
_description = 'Export Help Online' |
||||
|
|
||||
|
data = fields.Binary('XML', readonly=True) |
||||
|
export_filename = fields.Char('Export XML Filename', size=128) |
||||
|
|
||||
|
def _manage_images_on_page(self, page_node, data_node): |
||||
|
""" |
||||
|
- Extract images from page and generate a xml node |
||||
|
- Replace db id in url with xml id |
||||
|
""" |
||||
|
|
||||
|
def substitute_id_by_xml_id(img_elem): |
||||
|
new_src = False |
||||
|
attach_id = False |
||||
|
img_src = img_elem.get('src') |
||||
|
if 'id=' in img_src: |
||||
|
id_pos = img_src.index('id=') + 3 |
||||
|
attach_id = img_elem.get('src')[id_pos:] |
||||
|
new_src = img_src.replace(attach_id, xml_id) |
||||
|
else: |
||||
|
fragments = img_src.split('ir.attachment/') |
||||
|
attach_id, trail = fragments[1].split('_', 1) |
||||
|
new_src = "/website/image/ir.attachment/%s|%s" % \ |
||||
|
(xml_id, trail) |
||||
|
return new_src, attach_id |
||||
|
|
||||
|
i_img = 0 |
||||
|
img_model = 'ir.attachment' |
||||
|
for img_elem in page_node.iter('img'): |
||||
|
if img_model in img_elem.get('src'): |
||||
|
i_img += 1 |
||||
|
xml_id = "%s_img_%s" % \ |
||||
|
(page_node.attrib['name'], str(i_img).rjust(2, '0')) |
||||
|
|
||||
|
new_src, attach_id = substitute_id_by_xml_id(img_elem) |
||||
|
|
||||
|
if not attach_id: |
||||
|
continue |
||||
|
|
||||
|
image = self.env[img_model].browse(int(attach_id)) |
||||
|
if not image: |
||||
|
continue |
||||
|
|
||||
|
img_elem.attrib['src'] = new_src |
||||
|
img_node = ET.SubElement(data_node, |
||||
|
'record', |
||||
|
attrib={'id': xml_id, |
||||
|
'model': img_model}) |
||||
|
field_node = ET.SubElement(img_node, |
||||
|
'field', |
||||
|
attrib={'name': 'datas'}) |
||||
|
field_node.text = str(image.datas) |
||||
|
field_node = ET.SubElement(img_node, |
||||
|
'field', |
||||
|
attrib={'name': 'datas_fname'}) |
||||
|
field_node.text = image.datas_fname |
||||
|
field_node = ET.SubElement(img_node, |
||||
|
'field', |
||||
|
attrib={'name': 'name'}) |
||||
|
field_node.text = image.name |
||||
|
field_node = ET.SubElement(img_node, |
||||
|
'field', |
||||
|
attrib={'name': 'res_model'}) |
||||
|
field_node.text = image.res_model |
||||
|
field_node = ET.SubElement(img_node, |
||||
|
'field', |
||||
|
attrib={'name': 'mimetype'}) |
||||
|
field_node.text = image.mimetype |
||||
|
data_node.append(img_node) |
||||
|
|
||||
|
def _clean_href_urls(self, page_node, page_prefix, template_prefix): |
||||
|
""" |
||||
|
Remove host address for href urls |
||||
|
""" |
||||
|
for a_elem in page_node.iter('a'): |
||||
|
if not a_elem.get('href'): |
||||
|
continue |
||||
|
href = a_elem.get('href') |
||||
|
if not href.startswith('http'): |
||||
|
continue |
||||
|
page_url = '/page/%s' % page_prefix |
||||
|
template_url = '/page/%s' % template_prefix |
||||
|
if page_url not in href and template_url not in href: |
||||
|
continue |
||||
|
elif page_url in href and template_url not in href: |
||||
|
pass |
||||
|
elif page_url not in href and template_url in href: |
||||
|
page_url = template_url |
||||
|
else: |
||||
|
if page_prefix in template_prefix: |
||||
|
page_url = template_url |
||||
|
else: |
||||
|
pass |
||||
|
|
||||
|
if page_url: |
||||
|
trail = href.split(page_url, 1)[1] |
||||
|
a_elem.attrib['href'] = page_url + trail |
||||
|
|
||||
|
def _generate_snippet_from_template(self, page_node, |
||||
|
template_id, template_prefix): |
||||
|
""" |
||||
|
Generate a website snippet from a template |
||||
|
""" |
||||
|
page = copy.deepcopy(page_node) |
||||
|
snippet = ET.Element('template') |
||||
|
snippet.attrib['id'] = template_id + '_snippet' |
||||
|
snippet.attrib['inherit_id'] = 'website.snippets' |
||||
|
snippet.attrib['name'] = page_node.attrib['name'] |
||||
|
|
||||
|
xpath = ET.SubElement(snippet, |
||||
|
'xpath', |
||||
|
attrib={'expr': "//div[@id='snippet_structure']", |
||||
|
'position': 'inside'}) |
||||
|
main_div = ET.SubElement(xpath, |
||||
|
'div') |
||||
|
thumbnail = ET.SubElement(main_div, |
||||
|
'div', |
||||
|
attrib={'class': 'oe_snippet_thumbnail'}) |
||||
|
ET.SubElement(thumbnail, |
||||
|
'img', |
||||
|
attrib={'class': 'oe_snippet_thumbnail_img', |
||||
|
'src': HELP_ONLINE_SNIPPET_IMAGE_PATH}) |
||||
|
span = ET.SubElement(thumbnail, |
||||
|
'span', |
||||
|
attrib={'class': 'oe_snippet_thumbnail_title'}) |
||||
|
span.text = page_node.attrib['name'].replace(template_prefix, '') |
||||
|
body = ET.SubElement(main_div, |
||||
|
'section', |
||||
|
attrib={'class': 'oe_snippet_body ' |
||||
|
'mt_simple_snippet'}) |
||||
|
|
||||
|
template = page.find(".//div[@id='wrap']") |
||||
|
|
||||
|
for node in template.getchildren(): |
||||
|
body.append(node) |
||||
|
|
||||
|
return snippet |
||||
|
|
||||
|
def _get_qweb_views_data(self): |
||||
|
parameter_model = self.env['ir.config_parameter'] |
||||
|
page_prefix = parameter_model.get_param(PAGE_PREFIX_PARAMETER, |
||||
|
False) |
||||
|
template_prefix = parameter_model.get_param(TEMPLATE_PREFIX_PARAMETER, |
||||
|
False) |
||||
|
|
||||
|
if not page_prefix or not template_prefix: |
||||
|
return False |
||||
|
|
||||
|
domain = [('type', '=', 'qweb'), |
||||
|
('page', '=', True), |
||||
|
'|', |
||||
|
('name', 'like', '%s%%' % page_prefix), |
||||
|
('name', 'like', '%s%%' % template_prefix)] |
||||
|
|
||||
|
view_data_list = self.env['ir.ui.view'].search_read(domain, |
||||
|
['arch', 'name'], |
||||
|
order='name') |
||||
|
xml_to_export = ET.Element('openerp') |
||||
|
data_node = ET.SubElement(xml_to_export, 'data') |
||||
|
|
||||
|
for view_data in view_data_list: |
||||
|
parser = ET.XMLParser(remove_blank_text=True) |
||||
|
root = ET.XML(view_data['arch'], parser=parser) |
||||
|
|
||||
|
root.tag = 'template' |
||||
|
template_id = root.attrib.pop('t-name') |
||||
|
root.attrib['name'] = view_data['name'].replace('website.', '') |
||||
|
root.attrib['id'] = template_id |
||||
|
root.attrib['page'] = 'True' |
||||
|
|
||||
|
self._manage_images_on_page(root, data_node) |
||||
|
self._clean_href_urls(root, page_prefix, template_prefix) |
||||
|
data_node.append(root) |
||||
|
|
||||
|
if root.attrib['name'].startswith(template_prefix): |
||||
|
snippet = self._generate_snippet_from_template(root, |
||||
|
template_id, |
||||
|
template_prefix) |
||||
|
data_node.append(snippet) |
||||
|
|
||||
|
if len(view_data_list) > 0: |
||||
|
return ET.tostring(xml_to_export, encoding='utf-8', |
||||
|
xml_declaration=True, |
||||
|
pretty_print=True) |
||||
|
else: |
||||
|
return False |
||||
|
|
||||
|
@api.multi |
||||
|
def export_help(self): |
||||
|
""" |
||||
|
Export all Qweb views related to help online in a Odoo |
||||
|
data XML file |
||||
|
""" |
||||
|
xml_data = self._get_qweb_views_data() |
||||
|
if not xml_data: |
||||
|
raise exceptions.Warning(_('No data to export !')) |
||||
|
out = base64.encodestring(xml_data) |
||||
|
|
||||
|
self.write({'data': out, |
||||
|
'export_filename': 'help_online_data.xml'}) |
||||
|
|
||||
|
return { |
||||
|
'name': _('Export Help'), |
||||
|
'type': 'ir.actions.act_window', |
||||
|
'res_model': self._name, |
||||
|
'view_mode': 'form', |
||||
|
'view_type': 'form', |
||||
|
'res_id': self.id, |
||||
|
'views': [(False, 'form')], |
||||
|
'target': 'new', |
||||
|
} |
||||
|
|
||||
|
@api.model |
||||
|
def auto_backup(self): |
||||
|
""" |
||||
|
Export data to a file on home directory of user |
||||
|
""" |
||||
|
parameter_model = self.env['ir.config_parameter'] |
||||
|
autobackup_path = parameter_model.get_param(AUTOBACKUP_PARAMETER, |
||||
|
False) |
||||
|
|
||||
|
if autobackup_path: |
||||
|
xml_data = self._get_qweb_views_data() |
||||
|
try: |
||||
|
timestr = time.strftime("%Y%m%d-%H%M%S") |
||||
|
filename = '%s/help_online_backup-%s.xml' % (autobackup_path, |
||||
|
timestr) |
||||
|
backup_file = open(filename, |
||||
|
'w') |
||||
|
backup_file.write(xml_data) |
||||
|
backup_file.close |
||||
|
except: |
||||
|
_logger.warning(_('Unable to write autobackup file ' |
||||
|
'in given directory: %s' |
||||
|
% autobackup_path)) |
@ -0,0 +1,49 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu) |
||||
|
# All Rights Reserved |
||||
|
# |
||||
|
# WARNING: This program as such is intended to be used by professional |
||||
|
# programmers who take the whole responsibility of assessing all potential |
||||
|
# consequences resulting from its eventual inadequacies and bugs. |
||||
|
# End users who are looking for a ready-to-use solution with commercial |
||||
|
# guarantees and support are strongly advised to contact a Free Software |
||||
|
# Service Company. |
||||
|
# |
||||
|
# This program is free software: you can redistribute it and/or modify |
||||
|
# it under the terms of the GNU Affero General Public License as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU Affero General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
from openerp import models, fields, api |
||||
|
from openerp.tools import convert |
||||
|
|
||||
|
import base64 |
||||
|
from cStringIO import StringIO |
||||
|
|
||||
|
|
||||
|
class ImportHelpWizard(models.TransientModel): |
||||
|
_name = "import.help.wizard" |
||||
|
|
||||
|
source_file = fields.Binary('Source File') |
||||
|
|
||||
|
@api.one |
||||
|
def import_help(self): |
||||
|
source_file = base64.decodestring(self.source_file) |
||||
|
convert.convert_xml_import(self.env.cr, |
||||
|
self._module, |
||||
|
StringIO(source_file), |
||||
|
idref=None, |
||||
|
mode='init', |
||||
|
noupdate=False, |
||||
|
report=None) |
@ -0,0 +1,73 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Authors: Cédric Pigeon |
||||
|
# Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu) |
||||
|
# |
||||
|
# This program is free software: you can redistribute it and/or modify |
||||
|
# it under the terms of the GNU Affero General Public License as published |
||||
|
# by the Free Software Foundation, either version 3 of the License, or |
||||
|
# (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU Affero General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
from openerp import models, api |
||||
|
|
||||
|
from lxml import etree as ET |
||||
|
|
||||
|
|
||||
|
class ir_model_data(models.Model): |
||||
|
_inherit = 'ir.model.data' |
||||
|
|
||||
|
@api.model |
||||
|
def _update(self, model, module, values, xml_id=False, store=True, |
||||
|
noupdate=False, mode='init', res_id=False): |
||||
|
|
||||
|
if model == 'ir.ui.view': |
||||
|
parameter_model = self.env['ir.config_parameter'] |
||||
|
page_prefix = parameter_model.get_param('help_online_page_prefix', |
||||
|
False) |
||||
|
if page_prefix and xml_id.startswith('website.%s' % page_prefix): |
||||
|
xml_str = self.manageImageReferences(values['arch'], module) |
||||
|
values['arch'] = xml_str |
||||
|
|
||||
|
return super(ir_model_data, self)._update(model, |
||||
|
module, |
||||
|
values, |
||||
|
xml_id=xml_id, |
||||
|
store=store, |
||||
|
noupdate=noupdate, |
||||
|
mode=mode, |
||||
|
res_id=res_id) |
||||
|
|
||||
|
def manageImageReferences(self, xml_str, module): |
||||
|
parser = ET.XMLParser(remove_blank_text=True) |
||||
|
root = ET.XML(xml_str, parser=parser) |
||||
|
img_model = 'ir.attachment' |
||||
|
for img_elem in root.iter('img'): |
||||
|
if img_model in img_elem.get('src'): |
||||
|
img_src = img_elem.get('src') |
||||
|
try: |
||||
|
if '/ir.attachment/' in img_src: |
||||
|
fragments = img_src.split('/ir.attachment/') |
||||
|
xml_id = fragments[1].split('|')[0] |
||||
|
img_src = img_src.replace("|", "_") |
||||
|
else: |
||||
|
id_pos = img_src.index('id=') + 3 |
||||
|
xml_id = img_elem.get('src')[id_pos:] |
||||
|
|
||||
|
img_id = self.get_object_reference(module, |
||||
|
xml_id) |
||||
|
|
||||
|
img_elem.attrib['src'] = img_src.replace(xml_id, |
||||
|
str(img_id[1])) |
||||
|
except: |
||||
|
continue |
||||
|
return ET.tostring(root, encoding='utf-8', xml_declaration=False) |
@ -0,0 +1,32 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<openerp> |
||||
|
<data noupdate="1"> |
||||
|
<record id="online_help_confidential_rule" model="ir.rule"> |
||||
|
<field name="name">Online Help Hidden by Default</field> |
||||
|
<field name="model_id" ref="base.model_ir_ui_view"/> |
||||
|
<field name="domain_force">[ |
||||
|
'|', |
||||
|
('type', '!=', 'qweb'), |
||||
|
('name','not like','help-%'), |
||||
|
]</field> |
||||
|
<field name="groups" eval="[(6, 0, [ |
||||
|
ref('base.group_portal'), |
||||
|
ref('base.group_public'), |
||||
|
ref('base.group_user'), |
||||
|
])]"/> |
||||
|
<field name="perm_read" eval="1"/><field name="perm_write" eval="0"/> |
||||
|
<field name="perm_create" eval="0"/><field name="perm_unlink" eval="0"/> |
||||
|
</record> |
||||
|
|
||||
|
<record id="online_help_reader_rule" model="ir.rule"> |
||||
|
<field name="name">Online Help for Help Reader</field> |
||||
|
<field name="model_id" ref="base.model_ir_ui_view"/> |
||||
|
<field name="domain_force">[(1, '=', 1)]</field> |
||||
|
<field name="groups" eval="[(6, 0, [ |
||||
|
ref('help_online.help_online_group_reader'), |
||||
|
])]"/> |
||||
|
<field name="perm_read" eval="1"/><field name="perm_write" eval="0"/> |
||||
|
<field name="perm_create" eval="0"/><field name="perm_unlink" eval="0"/> |
||||
|
</record> |
||||
|
</data> |
||||
|
</openerp> |
After Width: 225 | Height: 218 | Size: 79 KiB |
After Width: 169 | Height: 180 | Size: 42 KiB |
@ -0,0 +1,27 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu) |
||||
|
# |
||||
|
# This program is free software: you can redistribute it and/or modify |
||||
|
# it under the terms of the GNU Affero General Public License as published |
||||
|
# by the Free Software Foundation, either version 3 of the License, or |
||||
|
# (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU Affero General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
from . import test_export_help_wizard |
||||
|
|
||||
|
fast_suite = [ |
||||
|
] |
||||
|
|
||||
|
checks = [ |
||||
|
test_export_help_wizard, |
||||
|
] |
@ -0,0 +1,78 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<openerp> |
||||
|
<data> |
||||
|
<record id="test_img_1" model="ir.attachment"> |
||||
|
<field name="datas">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 |
||||
|
</field> |
||||
|
<field name="index_content">image</field> |
||||
|
<field name="datas_fname">test.png</field> |
||||
|
<field name="name">test.png</field> |
||||
|
<field name="res_model">ir.ui.view</field> |
||||
|
<field name="mimetype">image/png</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
</openerp> |
@ -0,0 +1,161 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Authors: Cédric Pigeon |
||||
|
# Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu) |
||||
|
# |
||||
|
# This program is free software: you can redistribute it and/or modify |
||||
|
# it under the terms of the GNU Affero General Public License as published |
||||
|
# by the Free Software Foundation, either version 3 of the License, or |
||||
|
# (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU Affero General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
import logging |
||||
|
import base64 |
||||
|
from lxml import etree as ET |
||||
|
|
||||
|
from anybox.testing.openerp import SharedSetupTransactionCase |
||||
|
|
||||
|
_logger = logging.getLogger(__name__) |
||||
|
|
||||
|
|
||||
|
class test_export_help_wizard(object): |
||||
|
_data_files = ('data/help_test_data.xml',) |
||||
|
|
||||
|
_module_ns = 'help_online' |
||||
|
|
||||
|
def createPage(self, pageName, imgXmlId=False): |
||||
|
imgId = False |
||||
|
if imgXmlId: |
||||
|
imgId = self.ref('%s.%s' % (self._module_ns, imgXmlId)) |
||||
|
|
||||
|
rootNode = ET.Element('t') |
||||
|
rootNode.attrib['name'] = pageName |
||||
|
rootNode.attrib['t-name'] = "website.%s" % pageName |
||||
|
tNode = ET.SubElement(rootNode, |
||||
|
't', |
||||
|
attrib={'t-call': 'website.layout'}) |
||||
|
structDivNode = ET.SubElement(tNode, |
||||
|
'div', |
||||
|
attrib={'class': 'oe_structure oe_empty', |
||||
|
'id': 'wrap'}) |
||||
|
sectionNode = ET.SubElement(structDivNode, |
||||
|
'section', |
||||
|
attrib={'class': 'mt16 mb16'}) |
||||
|
containerNode = ET.SubElement(sectionNode, |
||||
|
'div', |
||||
|
attrib={'class': 'container'}) |
||||
|
rowNode = ET.SubElement(containerNode, |
||||
|
'div', |
||||
|
attrib={'class': 'row'}) |
||||
|
bodyDivNode = ET.SubElement(rowNode, |
||||
|
'div', |
||||
|
attrib={'class': 'col-md-12 ' |
||||
|
'text-center mt16 mb32'}) |
||||
|
style = "font-family: 'Helvetica Neue', Helvetica,"\ |
||||
|
" Arial, sans-serif; color: rgb(51, 51, 51);"\ |
||||
|
" text-align: left;" |
||||
|
h2Node = ET.SubElement(bodyDivNode, |
||||
|
'h2', |
||||
|
attrib={'style': style}) |
||||
|
h2Node.text = "Test Sample Title" |
||||
|
if imgId: |
||||
|
imgDivNode = ET.SubElement(bodyDivNode, |
||||
|
'div', |
||||
|
attrib={'style': 'text-align: left;'}) |
||||
|
src = "/website/image?field=datas&"\ |
||||
|
"model=ir.attachment&id=%s" % str(imgId) |
||||
|
ET.SubElement(imgDivNode, |
||||
|
'img', |
||||
|
attrib={'class': 'img-thumbnail', |
||||
|
'src': src}) |
||||
|
imgDivNode = ET.SubElement(bodyDivNode, |
||||
|
'div', |
||||
|
attrib={'style': 'text-align: left;'}) |
||||
|
src = "/website/image/ir.attachment/%s_ccc838d/datas" % str(imgId) |
||||
|
ET.SubElement(imgDivNode, |
||||
|
'img', |
||||
|
attrib={'class': 'img-thumbnail', |
||||
|
'src': src}) |
||||
|
arch = ET.tostring(rootNode, encoding='utf-8', xml_declaration=False) |
||||
|
vals = { |
||||
|
'name': pageName, |
||||
|
'type': 'qweb', |
||||
|
'arch': arch, |
||||
|
'page': True, |
||||
|
} |
||||
|
view_id = self.env['ir.ui.view'].create(vals) |
||||
|
return view_id.id |
||||
|
|
||||
|
def setUp(self): |
||||
|
super(test_export_help_wizard, self).setUp() |
||||
|
self.pageName = False |
||||
|
self.imgXmlId = False |
||||
|
self.pageTemplate = False |
||||
|
|
||||
|
def test_export_help(self): |
||||
|
""" |
||||
|
Export help data |
||||
|
""" |
||||
|
self.createPage(pageName=self.pageName, imgXmlId=self.imgXmlId) |
||||
|
|
||||
|
wizardPool = self.env['export.help.wizard'] |
||||
|
wizard = wizardPool.create({}) |
||||
|
wizard.export_help() |
||||
|
xmlData = base64.decodestring(wizard.data) |
||||
|
|
||||
|
parser = ET.XMLParser(remove_blank_text=True) |
||||
|
rootXml = ET.XML(xmlData, parser=parser) |
||||
|
|
||||
|
xPath = ".//template[@id='website.%s']" % self.pageName |
||||
|
templateNodeList = rootXml.findall(xPath) |
||||
|
self.assertEqual(len(templateNodeList), 1) |
||||
|
self.assertNotIn("website.", templateNodeList[0].attrib['name']) |
||||
|
|
||||
|
if self.imgXmlId: |
||||
|
xPath = ".//record[@id='%s_img_01']" % self.pageName |
||||
|
imgNodeList = rootXml.findall(xPath) |
||||
|
self.assertEqual(len(imgNodeList), 1) |
||||
|
|
||||
|
for imgElem in templateNodeList[0].iter('img'): |
||||
|
imgSrc = imgElem.get('src') |
||||
|
if '/ir.attachment/' in imgSrc: |
||||
|
self.assertIn("/ir.attachment/%s_img_02|" |
||||
|
% self.pageName, imgSrc) |
||||
|
else: |
||||
|
self.assertIn("id=%s_img_01" % self.pageName, imgSrc) |
||||
|
|
||||
|
if self.pageTemplate: |
||||
|
xPath = ".//template[@id='website.%s_snippet']" % self.pageName |
||||
|
templateNodeList = rootXml.findall(xPath) |
||||
|
self.assertEqual(len(templateNodeList), 1) |
||||
|
self.assertNotIn("website.", templateNodeList[0].attrib['name']) |
||||
|
|
||||
|
|
||||
|
class test_export_help_with_image(test_export_help_wizard, |
||||
|
SharedSetupTransactionCase): |
||||
|
def setUp(self): |
||||
|
super(test_export_help_with_image, self).setUp() |
||||
|
parameter_model = self.env['ir.config_parameter'] |
||||
|
page_prefix = parameter_model.get_param('help_online_page_prefix') |
||||
|
self.pageName = '%stest-page' % page_prefix |
||||
|
self.imgXmlId = 'test_img_1' |
||||
|
|
||||
|
|
||||
|
class test_export_help_template(test_export_help_wizard, |
||||
|
SharedSetupTransactionCase): |
||||
|
def setUp(self): |
||||
|
super(test_export_help_template, self).setUp() |
||||
|
parameter_model = self.env['ir.config_parameter'] |
||||
|
param = 'help_online_template_prefix' |
||||
|
template_prefix = parameter_model.get_param(param) |
||||
|
self.pageName = '%stest-template' % template_prefix |
||||
|
self.pageTemplate = True |
@ -0,0 +1,52 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<openerp> |
||||
|
<data> |
||||
|
<record model="ir.ui.view" id="export_help_wizard_view"> |
||||
|
<field name="name">export.help.wizard.view</field> |
||||
|
<field name="model">export.help.wizard</field> |
||||
|
<field name="type">form</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="Export Help Data"> |
||||
|
<group colspan="2"> |
||||
|
<field name="export_filename" |
||||
|
invisible="1"/> |
||||
|
</group> |
||||
|
<group> |
||||
|
<p> |
||||
|
This wizard allow you to export all QWeb views |
||||
|
related to help online. The result will be an Odoo |
||||
|
data xml file. |
||||
|
</p> |
||||
|
</group> |
||||
|
<group> |
||||
|
<field name="data" |
||||
|
nolabel="1" |
||||
|
readonly="1" |
||||
|
filename="export_filename" /> |
||||
|
</group> |
||||
|
<footer> |
||||
|
<span name="go-wizard" attrs="{'invisible': [('export_filename', '!=', False)]}"> |
||||
|
<button name="export_help" |
||||
|
string="Export" |
||||
|
type="object" |
||||
|
icon="gtk-execute" |
||||
|
class="oe_highlight" /> |
||||
|
or |
||||
|
</span> |
||||
|
<button string="Close" class="oe_link" special="cancel" /> |
||||
|
</footer> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record model="ir.actions.act_window" id="action_export_help_wizard"> |
||||
|
<field name="name">Export Help</field> |
||||
|
<field name="res_model">export.help.wizard</field> |
||||
|
<field name="view_id" ref="export_help_wizard_view"/> |
||||
|
<field name="view_type">form</field> |
||||
|
<field name="view_mode">form</field> |
||||
|
<field name="target">new</field> |
||||
|
<field name="type">ir.actions.act_window</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
</openerp> |
@ -0,0 +1,46 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<openerp> |
||||
|
<data> |
||||
|
<record model="ir.ui.view" id="import_help_wizard_view"> |
||||
|
<field name="name">import.help.wizard.view</field> |
||||
|
<field name="model">import.help.wizard</field> |
||||
|
<field name="type">form</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="Import Help Data"> |
||||
|
<group> |
||||
|
<p> |
||||
|
This wizard allow you to import QWeb views |
||||
|
related to help online. The required file format is an Odoo |
||||
|
data xml file. |
||||
|
</p> |
||||
|
</group> |
||||
|
<group> |
||||
|
<field name="source_file"/> |
||||
|
</group> |
||||
|
<footer> |
||||
|
<span name="go-wizard" attrs="{'invisible': [('source_file', '=', False)]}"> |
||||
|
<button name="import_help" |
||||
|
string="Import" |
||||
|
type="object" |
||||
|
icon="gtk-execute" |
||||
|
class="oe_highlight" /> |
||||
|
or |
||||
|
</span> |
||||
|
<button string="Close" class="oe_link" special="cancel" /> |
||||
|
</footer> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record model="ir.actions.act_window" id="action_import_help_wizard"> |
||||
|
<field name="name">Import Help</field> |
||||
|
<field name="res_model">import.help.wizard</field> |
||||
|
<field name="view_id" ref="import_help_wizard_view"/> |
||||
|
<field name="view_type">form</field> |
||||
|
<field name="view_mode">form</field> |
||||
|
<field name="target">new</field> |
||||
|
<field name="type">ir.actions.act_window</field> |
||||
|
</record> |
||||
|
|
||||
|
</data> |
||||
|
</openerp> |
@ -0,0 +1,28 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<openerp> |
||||
|
<data noupdate="0"> |
||||
|
|
||||
|
<record id="view_view_search" model="ir.ui.view"> |
||||
|
<field name="name">ir.ui.view search (help_online)</field> |
||||
|
<field name="inherit_id" ref="base.view_view_search"/> |
||||
|
<field name="model">ir.ui.view</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<xpath expr="//filter[@string='QWeb']" position="after"> |
||||
|
<filter name="website" string="Website Page" domain="[('type', '=', 'qweb'),('page', '=', True)]"/> |
||||
|
</xpath> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="view_view_form" model="ir.ui.view"> |
||||
|
<field name="name">ir.ui.view form (help_online)</field> |
||||
|
<field name="inherit_id" ref="base.view_view_form"/> |
||||
|
<field name="model">ir.ui.view</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<xpath expr="//field[@name='type']" position="after"> |
||||
|
<field name="page" string="Website Page?" readonly="1" attrs="{'invisible': [('type', '!=', 'qweb')]}"/> |
||||
|
</xpath> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
</data> |
||||
|
</openerp> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue