kitconcept.contentcreator


Namekitconcept.contentcreator JSON
Version 1.2.0 PyPI version JSON
download
home_pagehttps://github.com/kitconcept/kitconcept.contentcreator
SummaryCreate Plone content via JSON
upload_time2021-04-08 11:43:02
maintainer
docs_urlNone
authorkitconcept GmbH
requires_python
licenseGPL version 2
keywords python plone
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            .. This README is meant for consumption by humans and pypi. Pypi can render rst files so please do not use Sphinx features.
   If you want to learn more about writing documentation, please check out: http://docs.plone.org/about/documentation_styleguide.html
   This text does not appear on pypi or github. It is a comment.

==============================================================================
kitconcept.contentcreator
==============================================================================

.. image:: https://kitconcept.com/logo.svg
   :alt: kitconcept
   :target: https://kitconcept.com/


.. image:: https://github.com/kitconcept/kitconcept.contentcreator/workflows/kitconcept.contentcreator%20CI/badge.svg
    :target: https://github.com/kitconcept/kitconcept.contentcreator/actions?query=workflow%3A%22kitconcept.contentcreator+CI%22

This package is the responsible for automated content creation via
plone.restapi serializers/creators.

Initially based on ``collective.contentcreator`` written by Johannes Raggam (@thet) and evolved and improved from it.

Usage
=====

Basic
-----

It allows to have a structure in your policy package like::

  |-content_creator
      |- content.json
      |- siteroot.json
      |- de.mysection.json
      |- ...
      |- images
  |-content_images

using these names (for both files and folders) as sensible defaults. This is the
recommended way, although you can specify runners for custom JSON files (see below).

and creates the content in a tree like from `content.json` using the runner, and
object by object using the standalone json files.

The ``images`` folder is blacklisted to support the images folder to be inside the creator folder.

In your setuphandlers.py you need to::

  from kitconcept.contentcreator.creator import content_creator_from_folder
  ...

  content_creator_from_folder()

the method ``content_creator_from_folder`` has the following signature::

  def content_creator_from_folder(
    folder_name=os.path.join(os.path.dirname(__file__), "content_creator"),
    base_image_path=os.path.join(os.path.dirname(__file__), "content_images"),
    default_lang=None,
    default_wf_state=None,
    ignore_wf_types=["Image", "File"],
    logger=logger,
    temp_enable_content_types=[],
    custom_order=[],
  ):

Creator runner given a single file
----------------------------------

Given a JSON file containing an array of objects to be created, this runner takes this
array content (should have plone.restapi syntax compliant structure) and creates content
out of it. You can load it using the method: ``load_json``::

  from kitconcept.contentcreator.creator import load_json

  content_structure = load_json('testcontent/content.json', __file__)

Then you can call the runner with the method ``create_item_runner``::

  from kitconcept.contentcreator.creator import create_item_runner

  create_item_runner(
      api.portal.get(),
      content_structure,
      default_lang='en',
      default_wf_state='published'
  )

Creator runner given a folder with multiple files
-------------------------------------------------

Each file should contain a single p.restapi JSON compliant object (non arrayed, can't
contain other objects). It takes the placement in the tree hierarchy and the object id
from the filename name (eg. de.beispiele.bildergroessen.json)

Setup runners from external modules/packages
--------------------------------------------

Alternativelly, you can create custom content creators in other packages and
call them all at the same time, via a custom adapter::

  from kitconcept.contentcreator.interfaces import ICreateTestContent

  for name, provider in getAdapters((api.portal.get(), ), ICreateTestContent):
    provider()

this should be the declaration in the other package::

  @implementer(ICreateTestContent)
  @adapter(IPloneSiteRoot)
  class CreatePFGContent(object):
      """Adapter to create PFG initial content."""

      def __init__(self, context):
          self.context = context

      def __call__(self):
          content_structure = load_json('testcontent/content.json', __file__)

          create_item_runner(
              api.portal.get(),
              content_structure,
              default_lang='en',
              default_wf_state='published',
              ignore_wf_types=[
                  'FormBooleanField',
                  'FormDateField',
                  'FormFileField',
                  'FormFixedPointField',
                  'FormIntegerField',
                  'FormLabelField',
                  'FormLinesField',
                  'FormPasswordField',
              ],
          )

other common use is calling from a folder::

  from kitconcept.contentcreator.creator import content_creator_from_folder

  content_creator_from_folder(
      folder_name=os.path.join(os.path.dirname(__file__), "content_creator"),
      base_image_path=os.path.join(os.path.dirname(__file__), "images"),
      default_lang='en',
      default_wf_state='published',
      ignore_wf_types=[
          'FormBooleanField',
          'FormDateField',
          'FormFileField',
          'FormFixedPointField',
          'FormIntegerField',
          'FormLabelField',
          'FormLinesField',
          'FormPasswordField',
      ],
      logger=logger,
      temp_enable_content_types=[],
      custom_order=[
        'object-id-2.json',
        'object-id-3.json',
        'object-id-1.json',
      ],
  )

Images and Files
----------------

For the creation of images, you can use the plone.restapi approach using the
following serialization mapping containg the file data and some additional
metadata:

- ``data`` - the base64 encoded contents of the file
- ``encoding`` - the encoding you used to encode the data, so usually `base64`
- ``content-type`` - the MIME type of the file
- ``filename`` - the name of the file, including extension

.. code-block:: json

      {
        "...": "",
        "@type": "File",
        "title": "My file",
        "file": {
            "data": "TG9yZW0gSXBzdW0uCg==",
            "encoding": "base64",
            "filename": "lorem.txt",
            "content-type": "text/plain"}
      }

Alternativelly, you can provide the image an extra property ``set_dummy_image``
with an array of (image) field names that will create a dummy image placeholder
in the specified fields in the to be created content type::

      {
        "id": "an-image",
        "@type": "Image",
        "title": "Test Image",
        "set_dummy_image": ["image"]
      }

A deprecated syntax form is also supported (it will create the image in the
``image`` field)::

      {
        "id": "an-image",
        "@type": "Image",
        "title": "Test Image",
        "set_dummy_image": true
      }

You can specify a real image too, using a dict in the ``set_local_image`` JSON
attribute with the field name and the filename of the real image::

      {
        "id": "another-image",
        "@type": "Image",
        "title": "Another Test Image",
        "set_local_image": {"image": "image.png"}
      }

Again, a deprecated form is also supported (it will create the image in the
``image`` field)::

      {
        "id": "another-image",
        "@type": "Image",
        "title": "Another Test Image",
        "set_local_image": "image.png"
      }

the same syntax is valid for files::

      {
        "id": "an-file",
        "@type": "File",
        "title": "Test File",
        "set_dummy_file": ["file"]
      }

the deprecated form is also supported (it will create the file in the
``file`` field)::

      {
        "id": "an-file",
        "@type": "File",
        "title": "Test File",
        "set_dummy_file": true
      }

You can specify a real file too, using a dict in the ``set_local_file`` JSON
attribute with the field name and the filename of the real file::

      {
        "id": "another-file",
        "@type": "File",
        "title": "Another Test File",
        "set_local_file": {"file": "file.png"}
      }

the deprecated form is also supported (it will create the file in the
``file`` field)::

      {
        "id": "another-file",
        "@type": "File",
        "title": "Another Test File",
        "set_local_file": "file.png"
      }

For all local images and files specified, you can specify the ``base_path`` for the image in the ``create_item_runner``::

  create_item_runner(
      api.portal.get(),
      content_structure,
      default_lang='en',
      default_wf_state='published',
      base_image_path=__file__
  )


Development
-----------

Requirements:

- Python 3
- venv

Setup::

  make

Run Static Code Analysis::

  make code-Analysis

Run Unit / Integration Tests::

  make test

Run Robot Framework based acceptance tests::

  make test-acceptance


Contributors
============

- kitconcept GmbH, info@kitconcept.com


Changelog
=========

1.2.0 (2021-04-08)
------------------

- Black list ``images`` foder inside the create content folders
  [sneridagh]
- Improve error detection and report
  [sneridagh]

1.1.0 (2021-01-26)
------------------

- Improve content language detection if the field is not present
  [sneridagh]
- Fix and improve language inferring in the editing of an existing content
  [sneridagh]

1.0.6 (2020-05-08)
------------------

- Publish package on pypi.
  [timo]

- Added the from a folder content creation.
  [sneridagh]


1.0.5 (2019-11-22)
------------------

- Improve error reporting in create_item_runner.
  [timo]


1.0.4 (2019-11-21)
------------------

- Re-release.
  [timo]


1.0.3 (2019-05-06)
------------------

- Re-release.
  [sneridagh]


1.0.2 (2019-05-06)
------------------

- Nothing changed yet.


1.0.1 (unreleased)
------------------

- Port to Python 3.
  [sneridagh]

- Documentation.
  [sneridagh]


1.0.0 (2019-03-26)
------------------

- Initial release.
  [kitconcept]
            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/kitconcept/kitconcept.contentcreator",
    "name": "kitconcept.contentcreator",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "",
    "keywords": "Python Plone",
    "author": "kitconcept GmbH",
    "author_email": "info@kitconcept.com",
    "download_url": "https://files.pythonhosted.org/packages/68/cd/c0ce9a93e370f15b5c79c2e588f069165689e4b29a0ea4d5996a8a253b41/kitconcept.contentcreator-1.2.0.tar.gz",
    "platform": "",
    "description": ".. This README is meant for consumption by humans and pypi. Pypi can render rst files so please do not use Sphinx features.\n   If you want to learn more about writing documentation, please check out: http://docs.plone.org/about/documentation_styleguide.html\n   This text does not appear on pypi or github. It is a comment.\n\n==============================================================================\nkitconcept.contentcreator\n==============================================================================\n\n.. image:: https://kitconcept.com/logo.svg\n   :alt: kitconcept\n   :target: https://kitconcept.com/\n\n\n.. image:: https://github.com/kitconcept/kitconcept.contentcreator/workflows/kitconcept.contentcreator%20CI/badge.svg\n    :target: https://github.com/kitconcept/kitconcept.contentcreator/actions?query=workflow%3A%22kitconcept.contentcreator+CI%22\n\nThis package is the responsible for automated content creation via\nplone.restapi serializers/creators.\n\nInitially based on ``collective.contentcreator`` written by Johannes Raggam (@thet) and evolved and improved from it.\n\nUsage\n=====\n\nBasic\n-----\n\nIt allows to have a structure in your policy package like::\n\n  |-content_creator\n      |- content.json\n      |- siteroot.json\n      |- de.mysection.json\n      |- ...\n      |- images\n  |-content_images\n\nusing these names (for both files and folders) as sensible defaults. This is the\nrecommended way, although you can specify runners for custom JSON files (see below).\n\nand creates the content in a tree like from `content.json` using the runner, and\nobject by object using the standalone json files.\n\nThe ``images`` folder is blacklisted to support the images folder to be inside the creator folder.\n\nIn your setuphandlers.py you need to::\n\n  from kitconcept.contentcreator.creator import content_creator_from_folder\n  ...\n\n  content_creator_from_folder()\n\nthe method ``content_creator_from_folder`` has the following signature::\n\n  def content_creator_from_folder(\n    folder_name=os.path.join(os.path.dirname(__file__), \"content_creator\"),\n    base_image_path=os.path.join(os.path.dirname(__file__), \"content_images\"),\n    default_lang=None,\n    default_wf_state=None,\n    ignore_wf_types=[\"Image\", \"File\"],\n    logger=logger,\n    temp_enable_content_types=[],\n    custom_order=[],\n  ):\n\nCreator runner given a single file\n----------------------------------\n\nGiven a JSON file containing an array of objects to be created, this runner takes this\narray content (should have plone.restapi syntax compliant structure) and creates content\nout of it. You can load it using the method: ``load_json``::\n\n  from kitconcept.contentcreator.creator import load_json\n\n  content_structure = load_json('testcontent/content.json', __file__)\n\nThen you can call the runner with the method ``create_item_runner``::\n\n  from kitconcept.contentcreator.creator import create_item_runner\n\n  create_item_runner(\n      api.portal.get(),\n      content_structure,\n      default_lang='en',\n      default_wf_state='published'\n  )\n\nCreator runner given a folder with multiple files\n-------------------------------------------------\n\nEach file should contain a single p.restapi JSON compliant object (non arrayed, can't\ncontain other objects). It takes the placement in the tree hierarchy and the object id\nfrom the filename name (eg. de.beispiele.bildergroessen.json)\n\nSetup runners from external modules/packages\n--------------------------------------------\n\nAlternativelly, you can create custom content creators in other packages and\ncall them all at the same time, via a custom adapter::\n\n  from kitconcept.contentcreator.interfaces import ICreateTestContent\n\n  for name, provider in getAdapters((api.portal.get(), ), ICreateTestContent):\n    provider()\n\nthis should be the declaration in the other package::\n\n  @implementer(ICreateTestContent)\n  @adapter(IPloneSiteRoot)\n  class CreatePFGContent(object):\n      \"\"\"Adapter to create PFG initial content.\"\"\"\n\n      def __init__(self, context):\n          self.context = context\n\n      def __call__(self):\n          content_structure = load_json('testcontent/content.json', __file__)\n\n          create_item_runner(\n              api.portal.get(),\n              content_structure,\n              default_lang='en',\n              default_wf_state='published',\n              ignore_wf_types=[\n                  'FormBooleanField',\n                  'FormDateField',\n                  'FormFileField',\n                  'FormFixedPointField',\n                  'FormIntegerField',\n                  'FormLabelField',\n                  'FormLinesField',\n                  'FormPasswordField',\n              ],\n          )\n\nother common use is calling from a folder::\n\n  from kitconcept.contentcreator.creator import content_creator_from_folder\n\n  content_creator_from_folder(\n      folder_name=os.path.join(os.path.dirname(__file__), \"content_creator\"),\n      base_image_path=os.path.join(os.path.dirname(__file__), \"images\"),\n      default_lang='en',\n      default_wf_state='published',\n      ignore_wf_types=[\n          'FormBooleanField',\n          'FormDateField',\n          'FormFileField',\n          'FormFixedPointField',\n          'FormIntegerField',\n          'FormLabelField',\n          'FormLinesField',\n          'FormPasswordField',\n      ],\n      logger=logger,\n      temp_enable_content_types=[],\n      custom_order=[\n        'object-id-2.json',\n        'object-id-3.json',\n        'object-id-1.json',\n      ],\n  )\n\nImages and Files\n----------------\n\nFor the creation of images, you can use the plone.restapi approach using the\nfollowing serialization mapping containg the file data and some additional\nmetadata:\n\n- ``data`` - the base64 encoded contents of the file\n- ``encoding`` - the encoding you used to encode the data, so usually `base64`\n- ``content-type`` - the MIME type of the file\n- ``filename`` - the name of the file, including extension\n\n.. code-block:: json\n\n      {\n        \"...\": \"\",\n        \"@type\": \"File\",\n        \"title\": \"My file\",\n        \"file\": {\n            \"data\": \"TG9yZW0gSXBzdW0uCg==\",\n            \"encoding\": \"base64\",\n            \"filename\": \"lorem.txt\",\n            \"content-type\": \"text/plain\"}\n      }\n\nAlternativelly, you can provide the image an extra property ``set_dummy_image``\nwith an array of (image) field names that will create a dummy image placeholder\nin the specified fields in the to be created content type::\n\n      {\n        \"id\": \"an-image\",\n        \"@type\": \"Image\",\n        \"title\": \"Test Image\",\n        \"set_dummy_image\": [\"image\"]\n      }\n\nA deprecated syntax form is also supported (it will create the image in the\n``image`` field)::\n\n      {\n        \"id\": \"an-image\",\n        \"@type\": \"Image\",\n        \"title\": \"Test Image\",\n        \"set_dummy_image\": true\n      }\n\nYou can specify a real image too, using a dict in the ``set_local_image`` JSON\nattribute with the field name and the filename of the real image::\n\n      {\n        \"id\": \"another-image\",\n        \"@type\": \"Image\",\n        \"title\": \"Another Test Image\",\n        \"set_local_image\": {\"image\": \"image.png\"}\n      }\n\nAgain, a deprecated form is also supported (it will create the image in the\n``image`` field)::\n\n      {\n        \"id\": \"another-image\",\n        \"@type\": \"Image\",\n        \"title\": \"Another Test Image\",\n        \"set_local_image\": \"image.png\"\n      }\n\nthe same syntax is valid for files::\n\n      {\n        \"id\": \"an-file\",\n        \"@type\": \"File\",\n        \"title\": \"Test File\",\n        \"set_dummy_file\": [\"file\"]\n      }\n\nthe deprecated form is also supported (it will create the file in the\n``file`` field)::\n\n      {\n        \"id\": \"an-file\",\n        \"@type\": \"File\",\n        \"title\": \"Test File\",\n        \"set_dummy_file\": true\n      }\n\nYou can specify a real file too, using a dict in the ``set_local_file`` JSON\nattribute with the field name and the filename of the real file::\n\n      {\n        \"id\": \"another-file\",\n        \"@type\": \"File\",\n        \"title\": \"Another Test File\",\n        \"set_local_file\": {\"file\": \"file.png\"}\n      }\n\nthe deprecated form is also supported (it will create the file in the\n``file`` field)::\n\n      {\n        \"id\": \"another-file\",\n        \"@type\": \"File\",\n        \"title\": \"Another Test File\",\n        \"set_local_file\": \"file.png\"\n      }\n\nFor all local images and files specified, you can specify the ``base_path`` for the image in the ``create_item_runner``::\n\n  create_item_runner(\n      api.portal.get(),\n      content_structure,\n      default_lang='en',\n      default_wf_state='published',\n      base_image_path=__file__\n  )\n\n\nDevelopment\n-----------\n\nRequirements:\n\n- Python 3\n- venv\n\nSetup::\n\n  make\n\nRun Static Code Analysis::\n\n  make code-Analysis\n\nRun Unit / Integration Tests::\n\n  make test\n\nRun Robot Framework based acceptance tests::\n\n  make test-acceptance\n\n\nContributors\n============\n\n- kitconcept GmbH, info@kitconcept.com\n\n\nChangelog\n=========\n\n1.2.0 (2021-04-08)\n------------------\n\n- Black list ``images`` foder inside the create content folders\n  [sneridagh]\n- Improve error detection and report\n  [sneridagh]\n\n1.1.0 (2021-01-26)\n------------------\n\n- Improve content language detection if the field is not present\n  [sneridagh]\n- Fix and improve language inferring in the editing of an existing content\n  [sneridagh]\n\n1.0.6 (2020-05-08)\n------------------\n\n- Publish package on pypi.\n  [timo]\n\n- Added the from a folder content creation.\n  [sneridagh]\n\n\n1.0.5 (2019-11-22)\n------------------\n\n- Improve error reporting in create_item_runner.\n  [timo]\n\n\n1.0.4 (2019-11-21)\n------------------\n\n- Re-release.\n  [timo]\n\n\n1.0.3 (2019-05-06)\n------------------\n\n- Re-release.\n  [sneridagh]\n\n\n1.0.2 (2019-05-06)\n------------------\n\n- Nothing changed yet.\n\n\n1.0.1 (unreleased)\n------------------\n\n- Port to Python 3.\n  [sneridagh]\n\n- Documentation.\n  [sneridagh]\n\n\n1.0.0 (2019-03-26)\n------------------\n\n- Initial release.\n  [kitconcept]",
    "bugtrack_url": null,
    "license": "GPL version 2",
    "summary": "Create Plone content via JSON",
    "version": "1.2.0",
    "split_keywords": [
        "python",
        "plone"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "md5": "260d4f5c0cd3c104710ff5f820ab593d",
                "sha256": "643a342cb221e29c819b32d61963d0e60780b4583d2827fdaf2b2f3dc1ac71a9"
            },
            "downloads": -1,
            "filename": "kitconcept.contentcreator-1.2.0.tar.gz",
            "has_sig": false,
            "md5_digest": "260d4f5c0cd3c104710ff5f820ab593d",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 254478,
            "upload_time": "2021-04-08T11:43:02",
            "upload_time_iso_8601": "2021-04-08T11:43:02.589499Z",
            "url": "https://files.pythonhosted.org/packages/68/cd/c0ce9a93e370f15b5c79c2e588f069165689e4b29a0ea4d5996a8a253b41/kitconcept.contentcreator-1.2.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2021-04-08 11:43:02",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "github_user": null,
    "github_project": "kitconcept",
    "error": "Could not fetch GitHub repository",
    "lcname": "kitconcept.contentcreator"
}
        
Elapsed time: 0.23934s