diff --git a/.gitignore b/.gitignore index c46f9328b0..023db3d172 100644 --- a/.gitignore +++ b/.gitignore @@ -2,9 +2,8 @@ .* *.mo -# sphinx build directories +# Sphinx build files _build/ -# venv -bin/ -include/ -lib/ + +# Dependencies +odoo diff --git a/.tx/config b/.tx/config index 404fc576a7..f48963cf5d 100644 --- a/.tx/config +++ b/.tx/config @@ -2,39 +2,14 @@ host = https://www.transifex.com type = PO -[odoo-12-doc.accounting] -file_filter = locale//LC_MESSAGES/accounting.po -source_file = locale/sources/accounting.pot -source_lang = en - [odoo-12-doc.applications] file_filter = locale//LC_MESSAGES/applications.po source_file = locale/sources/applications.pot source_lang = en -[odoo-12-doc.crm] -file_filter = locale//LC_MESSAGES/crm.po -source_file = locale/sources/crm.pot -source_lang = en - -[odoo-12-doc.db_management] -file_filter = locale//LC_MESSAGES/db_management.po -source_file = locale/sources/db_management.pot -source_lang = en - -[odoo-12-doc.discuss] -file_filter = locale//LC_MESSAGES/discuss.po -source_file = locale/sources/discuss.pot -source_lang = en - -[odoo-12-doc.ecommerce] -file_filter = locale//LC_MESSAGES/ecommerce.po -source_file = locale/sources/ecommerce.pot -source_lang = en - -[odoo-12-doc.expenses] -file_filter = locale//LC_MESSAGES/expenses.po -source_file = locale/sources/expenses.pot +[odoo-12-doc.finance] +file_filter = locale//LC_MESSAGES/finance.po +source_file = locale/sources/finance.pot source_lang = en [odoo-12-doc.general] @@ -42,82 +17,42 @@ file_filter = locale//LC_MESSAGES/general.po source_file = locale/sources/general.pot source_lang = en -[odoo-12-doc.getting_started] -file_filter = locale//LC_MESSAGES/getting_started.po -source_file = locale/sources/getting_started.pot -source_lang = en - -[odoo-12-doc.helpdesk] -file_filter = locale//LC_MESSAGES/helpdesk.po -source_file = locale/sources/helpdesk.pot -source_lang = en - [odoo-12-doc.index] file_filter = locale//LC_MESSAGES/index.po source_file = locale/sources/index.pot source_lang = en -[odoo-12-doc.inventory] -file_filter = locale//LC_MESSAGES/inventory.po -source_file = locale/sources/inventory.pot -source_lang = en - -[odoo-12-doc.iot] -file_filter = locale//LC_MESSAGES/iot.po -source_file = locale/sources/iot.pot +[odoo-12-doc.inventory_and_mrp] +file_filter = locale//LC_MESSAGES/inventory_and_mrp.po +source_file = locale/sources/inventory_and_mrp.pot source_lang = en -[odoo-12-doc.livechat] -file_filter = locale//LC_MESSAGES/livechat.po -source_file = locale/sources/livechat.pot +[odoo-12-doc.productivity] +file_filter = locale//LC_MESSAGES/productivity.po +source_file = locale/sources/productivity.pot source_lang = en -[odoo-12-doc.mobile] -file_filter = locale//LC_MESSAGES/mobile.po -source_file = locale/sources/mobile.pot -source_lang = en - -[odoo-12-doc.manufacturing] -file_filter = locale//LC_MESSAGES/manufacturing.po -source_file = locale/sources/manufacturing.pot -source_lang = en - -[odoo-12-doc.point_of_sale] -file_filter = locale//LC_MESSAGES/point_of_sale.po -source_file = locale/sources/point_of_sale.pot -source_lang = en - -[odoo-12-doc.portal] -file_filter = locale//LC_MESSAGES/portal.po -source_file = locale/sources/portal.pot -source_lang = en - -[odoo-12-doc.practical] -file_filter = locale//LC_MESSAGES/practical.po -source_file = locale/sources/practical.pot -source_lang = en - -[odoo-12-doc.project] -file_filter = locale//LC_MESSAGES/project.po -source_file = locale/sources/project.pot +[odoo-12-doc.sales] +file_filter = locale//LC_MESSAGES/sales.po +source_file = locale/sources/sales.pot source_lang = en -[odoo-12-doc.purchase] -file_filter = locale//LC_MESSAGES/purchase.po -source_file = locale/sources/purchase.pot +[odoo-12-doc.services] +file_filter = locale//LC_MESSAGES/services.po +source_file = locale/sources/services.pot source_lang = en -[odoo-12-doc.recruitment] -file_filter = locale//LC_MESSAGES/recruitment.po -source_file = locale/sources/recruitment.pot +[odoo-12-doc.theme] +file_filter = locale//LC_MESSAGES/sphinx.po +source_file = locale/sources/sphinx.pot source_lang = en -[odoo-12-doc.sales] -file_filter = locale//LC_MESSAGES/sales.po -source_file = locale/sources/sales.pot +[odoo-12-doc.user_settings] +file_filter = locale//LC_MESSAGES/settings.po +source_file = locale/sources/settings.pot source_lang = en -[odoo-12-doc.website] -file_filter = locale//LC_MESSAGES/website.po -source_file = locale/sources/website.pot +[odoo-12-doc.websites] +file_filter = locale//LC_MESSAGES/websites.po +source_file = locale/sources/websites.pot source_lang = en diff --git a/Makefile b/Makefile index 236e759327..8361faba2d 100644 --- a/Makefile +++ b/Makefile @@ -1,190 +1,82 @@ # Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = _build -LESSOPTS = - -# User-friendly check for sphinx-build -ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) -$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) + +# Pass WORKERS=1 for single-worker build +ifndef WORKERS + WORKERS = auto +endif + +ifndef BUILD_DIR + BUILD_DIR = _build endif -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . -ALLI18NSPHINXOPTS = -d $(BUILDDIR)/doctrees/$(LANG) $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) -D language=$(LANG) . -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +ifndef CURRENT_LANG + CURRENT_LANG = en +endif + +SPHINX_BUILD = sphinx-build +CONFIG_DIR = . +SPHINXOPTS = -D project_root=$(ROOT) -D canonical_version=$(CANONICAL_VERSION) \ + -D versions=$(VERSIONS) -D languages=$(LANGUAGES) -D language=$(CURRENT_LANG) \ + -D is_remote_build=$(IS_REMOTE_BUILD) \ + -A google_analytics_key=$(GOOGLE_ANALYTICS_KEY) \ + -j $(WORKERS) +SOURCE_DIR = content + +HTML_BUILD_DIR = $(BUILD_DIR)/html +ifdef VERSIONS + HTML_BUILD_DIR := $(HTML_BUILD_DIR)/12.0 +endif +ifneq ($(CURRENT_LANG),en) + HTML_BUILD_DIR := $(HTML_BUILD_DIR)/$(CURRENT_LANG) +endif -lessfiles = _extensions/odoo/static/*.less -_extensions/odoo/static/style.css: $(lessfiles) - lessc $(LESSOPTS) $(subst .css,.less,$@) $@ +#=== Standard rules ===# -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext +# In first position to build the documentation from scratch by default +all: html help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " i18nhtml to make standalone translated HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " xml to make Docutils-native XML files" - @echo " pseudoxml to make pseudoxml-XML files for display purposes" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" + @echo "Please use 'make ' where is one of" + @echo " html to build the documentation to HTML" + @echo " fast to build the documentation to HTML with shallow menu (faster)" + @echo " clean to delete the build files" clean: - rm -rf $(BUILDDIR)/* - -html: _extensions/odoo/static/style.css - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -i18nhtml: _extensions/odoo/static/style.css - $(SPHINXBUILD) -b html $(ALLI18NSPHINXOPTS) $(BUILDDIR)/html/$(LANG) - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html/$(LANG)." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/UnderstandingAccountingForEntrepreneurs.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/UnderstandingAccountingForEntrepreneurs.qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo + @echo "Cleaning build files..." + rm -rf $(BUILD_DIR)/* + @echo "Cleaning finished." + +html: $(HTML_BUILD_DIR)/_static/style.css + @echo "Starting build..." + $(SPHINX_BUILD) -c $(CONFIG_DIR) -b html $(SPHINXOPTS) $(SOURCE_DIR) $(HTML_BUILD_DIR) @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/UnderstandingAccountingForEntrepreneurs" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/UnderstandingAccountingForEntrepreneurs" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." +# To call *after* `make html` +# Binary dependencies (Debian): texlive-fonts-recommended texlive-latex-extra +# texlive-generic-recommended texlive-fonts-extra latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - cp $(BUILDDIR)/latex/*.pdf $(BUILDDIR)/html/ - -latexpdfja: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through platex and dvipdfmx..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + @echo "Starting build..." + $(SPHINX_BUILD) -c $(CONFIG_DIR) -b latex $(SPHINXOPTS) $(SOURCE_DIR) $(BUILD_DIR)/latex + $(MAKE) -C $(BUILD_DIR)/latex + cp $(BUILD_DIR)/latex/*.pdf $(BUILD_DIR)/html/ + @echo "Build finished." gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) locale/sources - @echo - @echo "Build finished. The message catalogs are in locale/sources." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - -xml: - $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml - @echo - @echo "Build finished. The XML files are in $(BUILDDIR)/xml." - -pseudoxml: - $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml - @echo - @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." + @echo "Generating translatable files..." + $(SPHINX_BUILD) -c $(CONFIG_DIR) -b gettext $(SOURCE_DIR) locale/sources + @echo "Generation finished." + +$(HTML_BUILD_DIR)/_static/style.css: extensions/odoo_theme/static/style.scss extensions/odoo_theme/static/scss/*.scss + @echo "Compiling stylesheets..." + mkdir -p $(HTML_BUILD_DIR)/_static + pysassc extensions/odoo_theme/static/style.scss $(HTML_BUILD_DIR)/_static/style.css + @echo "Compilation finished." + +#=== Development and debugging rules ===# + +fast: SPHINXOPTS += -A collapse_menu=True +fast: html + +static: $(HTML_BUILD_DIR)/static/style.css + cp -r extensions/odoo_theme/static/* $(HTML_BUILD_DIR)/_static/ + cp -r static/* $(HTML_BUILD_DIR)/_static/ diff --git a/README.md b/README.md new file mode 100644 index 0000000000..333b0d42ac --- /dev/null +++ b/README.md @@ -0,0 +1,43 @@ +# Odoo documentation + +## Build the documentation locally + +### Requirements + +- [Git](https://www.odoo.com/documentation/12.0/contributing/documentation.html#install-git) +- [Python 3.6, 3.7, or 3.8](https://www.odoo.com/documentation/12.0/contributing/documentation.html#python) +- Python dependencies listed in the file [`requirements.txt`](https://github.com/odoo/documentation/tree/12.0/requirements.txt). +- [Make](https://www.odoo.com/documentation/12.0/contributing/documentation.html#make) +- A local copy of the [odoo/odoo repository in 12.0](https://github.com/odoo/odoo/tree/12.0) (Optional) + +### Instructions + +1. In a terminal, navigate to the root directory and compile the documentation to HTML with the + following command: + + ```sh + make + ``` + + Additional commands are available with `make help`. + +2. Open the file `documentation/_build/html/index.html` in your web browser to display the render. + +3. See [this guide](https://www.odoo.com/documentation/12.0/contributing/documentation.html#preview-your-changes) + for more detailed instructions. + +Optional: to fully build the developer documentation with inline docstrings for documented Python +functions, place your local copy of the `odoo/odoo` repository in the root directory. Alternatively, +create a symbolic link with `odoo` as link name. If the Odoo sources are not found, a warning will +be shown. + +## Contribute to the documentation + +For contributions to the content of the documentation, please refer to the +[Introduction Guide](https://www.odoo.com/documentation/12.0/contributing/documentation.html). + +To **report a content issue**, **request new content** or **ask a question**, use the +[repository's issue tracker](https://github.com/odoo/documentation-user/issues) as usual. + +If you have a pull request that is ready for review, request one from the +[odoo/doc-review](https://github.com/orgs/odoo/teams/doc-review) team. \ No newline at end of file diff --git a/README.rst b/README.rst deleted file mode 100644 index f8a96dcc73..0000000000 --- a/README.rst +++ /dev/null @@ -1,127 +0,0 @@ -=========================== -End-user Odoo documentation -=========================== - -Building requirements: - -* Python 2.7 -* recent `Sphinx `_ (at least Sphinx 1.2) - - you can check if Sphinx is installed by trying to launch - - .. code-block:: console - - $ sphinx-build --version - - See `the sphinx documentation `_ - for local installation instructions. -* `git `_ -* clone this repository using git, then at the root of the repository, - in a console, - - .. code-block:: console - - $ make html - - this should compile the documentation to HTML, and put the generated - HTML in ``_build/html/index.html``. - -Contributions -============= - -For simple edition (typo, just add paragraphs of text without markup), -the Github web interface can be used directly. - -For more complex edition, to add images or advanced directives, edit -locally. **Do not commit if there are warnings or errors when building -the documentation** fix them first. rST is fairly sensitive to -whitespace and newlines (especially the lack of newlines). It's a bit -annoying but it's not hard to learn. - -Issues can be reported on the repository's bug tracker as usual. - -Custom features -=============== - -Extensions ----------- - -Two custom directives are provided for integration with Odoo's demo -system: - -* ``demo:fields:: {external_id}`` lists all the fields with a - tooltip (``help``) of the action whose ``external_id`` is provided. - - - Uses the ``form`` view by default, can be customized by specifying - ``:view:``. - - The list of fields displayed can be filtered with ``:only:`` which - should be a list of space-separated fields to display. Note that - this will further reduce the number of fields displayed, it will - not force fields to be listed when they don't have a ``help``. - - .. code-block:: restructuredtext - - .. demo:fields:: account_asset.action_account_asset_asset_list_normal_sale - :only: name - - will display a table of just the ``name`` field and its ``help`` (or - nothing if the ``name`` field does not have a ``help``) - -* ``demo:action:: {external_id}`` will create a link button to the - action (specified by external id) on the demo site. The text of the - button should be provided as the directive's content: - - .. code-block:: restructuredtext - - .. demo:action:: account_asset.action_account_asset_asset_list_normal_sale - - View *Asset Types* - -Theme Customisations --------------------- - -* The Odoo theme supports *Banner Images* at the top of - documents. These banners are configured by setting a ``:banner:`` - field at the top of the document (before the page title), the banner - images will be looked up in the ``_static`` folder at the root of - the project - - .. code-block:: restructuredtext - - :banner: banners/accounting.png - - ========== - Accounting - ========== - - [...] - - .. warning:: - - because banners are wide images and each page may have one, it is - strongly recommended to compress them well. For PNG, use - `pngquant `_ (or a UI to it) to reduce the - number of colors in the image followed by regular PNG - recompression tools like `pngcrush - `_ and `pngout - `_. - - - -Importing existing documents -============================ - -For documents which already exist in an other format or in Google -docs, it's possible to get a head-start by converting the existing -document using `Pandoc `_. The main issue is that -anything but trivial original documents will need fixing up (possibly -lots of it) to get *good* rST (or possibly working rST at all). - -Example:: - - pandoc -f docx -t rst path/to/document.docx -o new_doc.rst --extract-media=. - -will convert ``path/to/document.docx`` to ``new_doc.rst`` and export -all images to ``./media`` (and link them from the document). While -there are issues with the exported document, it's much more convenient -than manually re-typing the original. diff --git a/_extensions/demo_link.py b/_extensions/demo_link.py deleted file mode 100644 index 9038d8040e..0000000000 --- a/_extensions/demo_link.py +++ /dev/null @@ -1,207 +0,0 @@ -import collections -import threading -import werkzeug - -try: - import xmlrpclib -except ImportError: - # P3 - import xmlrpc.client as xmlrpclib - -try: - import Queue -except ImportError: - # P3 - import queue as Queue - -from xml.etree import ElementTree as ET - -from docutils import nodes, utils -from docutils.parsers.rst import Directive, directives -from sphinx.domains import Domain - -def setup(app): - app.add_domain(OdooDemoDomain) - -class Fields(Directive): - """Fetches and lists the fields linked to a specific action. - - Required argument: external ID of the action - - Options: - - view - defaults to "form" - fields - comma-separated whitelist of fields. By default, lists all - fields returned by fields_view_get - """ - required_arguments = 1 - option_spec = { - 'view': directives.unchanged, - 'only': directives.unchanged, - } - def __init__(self, name, arguments, options, content, lineno, - content_offset, block_text, state, state_machine): - super(Fields, self).__init__( - name, arguments, options, content, lineno, - content_offset, block_text, state, state_machine) - xid = arguments[0] - self.future_fields = self._get_fields(xid, options.get('view') or 'form') - - def run(self): - try: - fields = self.future_fields.get(timeout=30) - except Queue.Empty: - return [self.state_machine.reporter.error( - "Timed out while fetching fields related to action [%s]" % self.arguments[0] - )] - if fields is None: - return [self.state_machine.reporter.warning( - "Could not find any field related to the action [%s]" % self.arguments[0] - )] - if isinstance(fields, str): - return [self.state_machine.reporter.warning( - "Error while fetching fields related to the action [%s]: %s" % ( - self.arguments[0], fields))] - - whitelist = set(self.options.get('only', '').split()) - return [nodes.field_list('', *( - nodes.field('', - nodes.field_name(text=v['string'] or k), - nodes.field_body('', - # keep help formatting around (e.g. newlines for lists) - nodes.line_block('', *( - nodes.line(text=line) - for line in v['help'].split('\n') - )) - ) - ) - for k, v in fields.items() - # if there's a whitelist, only display whitelisted fields - if not whitelist or k in whitelist - # only display if there's a help text - if v.get('help') - ))] - - def _get_fields(self, xid, view='form'): - q = Queue.Queue(1) - _submit(q, xid, view) - return q - -class Action(Directive): - required_arguments = 1 - final_argument_whitespace = True - has_content = True - - def run(self): - self.assert_has_content() - external_id = self.arguments[0] - text = "action button" - node = nodes.reference( - refuri='https://demo.odoo.com?{}'.format(werkzeug.urls.url_encode({ - 'module': external_id - })), - classes=['btn', 'btn-primary', 'btn-lg', 'btn-block', 'center-block'] - ) - self.state.nested_parse(self.content, self.content_offset, node) - return [node] - -class OdooDemoDomain(Domain): - name = 'demo' - label = 'Odoo Demo' - directives = { - 'fields': Fields, - 'action': Action, - } - -FETCH_THREADS = 4 -launcher_lock = threading.Lock() -launcher = None -work_queue = Queue.Queue() -Task = collections.namedtuple('Task', 'result xid view') -def _submit(result_queue, xid, view='form'): - global launcher - # enqueue task before checking launcher, that way if the launcher - # is already started (likely) a worker can immediately get to work - work_queue.put(Task(result_queue, xid, view)) - - with launcher_lock: - if launcher is None: - launcher = threading.Thread(target=_launcher, name="Fetch threads launcher") - launcher.daemon = True - launcher.start() - -def _launcher(): - try: - info = xmlrpclib.ServerProxy('https://demo.odoo.com/start').start() - except xmlrpclib.Fault as e: - threading.Thread( - target=_fault_requests, - args=["Demo start() failed: %s" % e.faultString], - name="fields_get login failed").start() - return - url, db, username, password = \ - info['host'], info['database'], info['user'], info['password'] - - uid = xmlrpclib.ServerProxy('{}/xmlrpc/2/common'.format(url))\ - .authenticate(db, username, password, {}) - - for i in range(FETCH_THREADS): - # daemon because Launcher is daemon - threading.Thread(target=_fetch_fields, kwargs={ - 'db': db, - 'uid': uid, - 'password': password, - 'url': '{}/xmlrpc/2/object'.format(url) - }, name="fields_get fetcher thread %d/%d" % (i, FETCH_THREADS)).start() - -def _fault_requests(error): - while True: - task = work_queue.get() - task.result.put(error) - work_queue.task_done() - -def _fetch_fields(url, db, uid, password): - server = xmlrpclib.ServerProxy(url) - while True: - task = work_queue.get() - - # resolve xid - model, id_ = server.execute_kw( - db, uid, password, - 'ir.model.data', 'xmlid_to_res_model_res_id', [task.xid]) - if not id_: # didn't find xid - result = None - elif model != 'ir.actions.act_window': # we only handle action windows, rest is unknown - result = None - else: - action = server.execute_kw(db, uid, password, model, 'read', [id_, ['res_model', 'views']]) - view_id = next((id_ for type, id_ in action[0]['views'] if type == task.view), False) - fvg = server.execute_kw( - db, uid, password, - action[0]['res_model'], 'fields_view_get', [], { - 'view_id': view_id, - 'view_type': task.view - }) - result = collections.OrderedDict() - # reorder fields to be in view order, and add @help from view if any - arch = ET.fromstring(fvg['arch']) - for node in arch.iter(tag='field'): - field = node.get('name') - - result[field] = fvg['fields'][field] - # bit trashy but should work well enough to update - # @string and @help - result[field].update(node.attrib) - if node.get('nolabel'): - # native @string suppressed, look for