diff --git a/docs/usersguide/accessing.rst b/docs/usersguide/accessing.rst index 65e16febd..343c18886 100644 --- a/docs/usersguide/accessing.rst +++ b/docs/usersguide/accessing.rst @@ -1,2 +1,187 @@ +.. _accessing_content: + Accessing content ================= + +JSON representation +------------------- + +Records are internally stored in JSON following a certain JSON Schema. +They can be obtained using REST API to records. + +Using CLI: + +.. code-block:: console + + $ curl http://192.168.50.10/api/records/117 + { + + "created": "2017-03-21T00:01:27.933711+00:00", + "id": 117, + "links": { + "self": "http://192.168.50.10/api/records/117" + }, + "metadata": { + "__order__": [ + "title_statement", + "main_entry_personal_name" + ], + "_oai": { + "id": "oai:invenio:recid/118", + "updated": "2017-03-21T00:01:27Z" + }, + "control_number": "118", + "main_entry_personal_name": { + "__order__": [ + "personal_name" + ], + "personal_name": "Doe, John" + }, + "title_statement": { + "__order__": [ + "title" + ], + "title": "This is title" + } + }, + "updated": "2017-03-21T00:01:27.933721+00:00" + + } + +Using Python: + +.. code-block:: console + + $ ipython + In [1]: import requests + In [2]: r = requests.get('http://192.168.50.10/api/records/117') + In [3]: r.status_code + Out[3]: 200 + In [4]: r.json() + Out[4]: + {'created': '2017-03-21T00:01:27.933711+00:00', + 'id': 117, + 'links': {'self': 'http://192.168.50.10/api/records/117'}, + 'metadata': {'__order__': ['title_statement', 'main_entry_personal_name'], + '_oai': {'id': 'oai:invenio:recid/118', 'updated': '2017-03-21T00:01:27Z'}, + 'control_number': '118', + 'main_entry_personal_name': {'__order__': ['personal_name'], + 'personal_name': 'Doe, John'}, + 'title_statement': {'__order__': ['title'], 'title': 'This is title'}}, + 'updated': '2017-03-21T00:01:27.933721+00:00'} + +Multiple output formats +----------------------- + +You can obtain information in other formats by setting an appropriate Accept +header. Invenio REST API endpoint will read this information and invoke +appropriate record serialisation. For example, to obtain a BibTeX representation +of a record: + +.. code-block:: console + + $ curl -H 'Accept: application/x-bibtex' https://zenodo.org/api/records/46643 + @misc{himpe_2016_46643, + author = {Himpe, Christian and + Ohlberger, Mario}, + title = {{Accelerating the Computation of Empirical Gramians + and Related Methods}}, + month = feb, + year = 2016, + note = {Extended Abstract}, + doi = {10.5281/zenodo.46643}, + url = {https://doi.org/10.5281/zenodo.46643} + +Getting record fields +--------------------- + +Getting title +~~~~~~~~~~~~~ + +If we would like to obtain only some part of information, for example record +title, we can simply filter the output fields. + +Using CLI: + +.. code-block:: console + + $ curl -s http://192.168.50.10/api/records/117 | \ + jq -r '.metadata.title_statement.title' + This is title + +Using Python: + +.. code-block:: console + + $ ipython + In [1]: import requests + In [2]: r = requests.get('http://192.168.50.10/api/records/117') + In [3]: r.json()['metadata'].get('title_statement',{}).get('title','') + Out[3]: 'This is title' + +Getting co-authors +~~~~~~~~~~~~~~~~~~ + +If we would like to print all co-author names, we can iterate over respective +JSON field as follows: + +Using CLI: + +.. code-block:: console + + $ curl -s http://192.168.50.10/api/records/97 | \ + jq -r '.metadata.added_entry_personal_name[].personal_name' + Lokajczyk, T + Xu, W + Jastrow, U + Hahn, U + Bittner, L + Feldhaus, J + +Using Python: + +.. code-block:: console + + $ ipython + In [1]: import requests + In [2]: r = requests.get('http://192.168.50.10/api/records/97') + In [2]: for coauthor in r.json()['metadata']['added_entry_personal_name']: + ......: print(coauthor['personal_name']) + Lokajczyk, T + Xu, W + Jastrow, U + Hahn, U + Bittner, L + Feldhaus, J + +Searching records +----------------- + +Invenio instance can be searched programmatically via the REST API endpoint: + +.. code-block:: console + + $ curl http://192.168.50.10/api/records?q=model + +Note the pagination of the output done by the "links" output field. + +How many records are there that contain the word "model"? We need to iterate +over results: + +.. code-block:: Python + + nb_hits = 0 + + def get_nb_hits(json_response): + return len(json_response['hits']['hits']) + + def get_next_link(json_response): + return json_response['links'].get('next', None) + + response = requests.get('http://192.168.50.10/api/records?q=model').json() + nb_hits += get_nb_hits(response) + while get_next_link(response): + response = requests.get(get_next_link(response)).json() + nb_hits += get_nb_hits(response) + + print(nb_hits) diff --git a/docs/usersguide/loading.rst b/docs/usersguide/loading.rst index 2d47f0f79..b2f64352f 100644 --- a/docs/usersguide/loading.rst +++ b/docs/usersguide/loading.rst @@ -1,2 +1,121 @@ +.. _loading_content: + Loading content =============== + +Loading records +--------------- + +In the Invenio demo site example using ILS flavour, we have seen the ``invenio +marc21`` command that can load records directly from a MARCXML file. + +You can use ``dojson`` to convert MARCXML format to its JSON representation: + +.. code-block:: console + + $ dojson -i book.xml -l marcxml do marc21 \ + schema "http://192.168.50.10/schema/marc21/bibliographic/bd-v1.0.0.json" \ + > book.json + $ cat book.json | jq . + [ + { + "title_statement": { + "title": "This is title", + "__order__": [ + "title" + ] + }, + "main_entry_personal_name": { + "personal_name": "Doe, John", + "__order__": [ + "personal_name" + ] + }, + "__order__": [ + "title_statement", + "main_entry_personal_name" + ], + "$schema": "http://192.168.50.10/schema/marc21/bibliographic/bd-v1.0.0.json" + } + ] + +You can load JSON records using the ``invenio records`` command: + +.. code-block:: console + + $ cat book.json | invenio records create --pid-minter recid --pid-minter oaiid + efac2fc2-29af-40bb-a85e-77af0349c0fe + +The new record that we have just uploaded got the UUID +efac2fc2-29af-40bb-a85e-77af0349c0fe that uniquely identifies it inside the +Invenio record database. It was also minted persistent identifiers ``recid`` +representing record ID and ``oaiid`` representing OAI ID. + +UUIDs and PIDs +-------------- + +Objects managed by Invenio use "internal" UUID identifiers and "external" +persistent identifiers (PIDs). + +Starting from a persistent identifier, you can see which UUID a persistent +identifier points to by using the ``invenio pid`` command: + +.. code-block:: console + + $ invenio pid get recid 117 + rec a11dad76-5bd9-471c-975a-0b2b01d74831 R + +Starting from the UUID of a record, you can see which PIDs the record was +assigned by doing: + +.. code-block:: console + + $ invenio pid dereference rec a11dad76-5bd9-471c-975a-0b2b01d74831 + recid 117 None + oai oai:invenio:recid/117 oai + +You can unassign persistent identifiers: + +.. code-block:: console + + $ invenio pid unassign recid 117 + R + $ invenio pid unassign oai oai:invenio:recid/117 + R + +What happens when you try to access the given record ID? + +.. code-block:: console + + $ firefox http://192.168.50.10/api/records/117 + +You can assign another record the same PID: + +.. code-block:: console + + $ invenio pid assign -s REGISTERED -t rec -i 29351009-5e6f-4754-95cb-508f89f4de39 recid 117 + +What happens when you try to access the given record ID now? + +.. code-block:: console + + $ firefox http://192.168.50.10/api/records/117 + +Deleting records +---------------- + +If you want to delete a certain record, you can use: + +.. code-block:: console + + $ invenio records delete -i efac2fc2-29af-40bb-a85e-77af0349c0fe + +Beware of any registered persistent identifiers, though. + +Loading files +------------- + +Loading full-text files, such as PDF papers or CSV data files together with the +records, will be addressed later. + +.. todo:: Describe records, files, buckets. diff --git a/docs/usersguide/quickstart.rst b/docs/usersguide/quickstart.rst index aff38b85b..528892cab 100644 --- a/docs/usersguide/quickstart.rst +++ b/docs/usersguide/quickstart.rst @@ -1,61 +1,63 @@ .. This file is part of Invenio Copyright (C) 2014, 2015, 2016, 2017 CERN. Invenio is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Invenio 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 General Public License for more details. You should have received a copy of the GNU General Public License along with Invenio; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. +.. _quickstart: + Quickstart ========== Using Docker ------------ You can get Invenio v3.0 demo site up and running using Docker:: docker-compose build docker-compose up -d docker-compose run --rm web ./scripts/populate-instance.sh firefox http://127.0.0.1/records/1 Using Vagrant ------------- You can get Invenio v3.0 demo site up and running using Vagrant:: vagrant up vagrant ssh web -c 'source .inveniorc && /vagrant/scripts/create-instance.sh' vagrant ssh web -c 'source .inveniorc && /vagrant/scripts/populate-instance.sh' vagrant ssh web -c 'source .inveniorc && nohup /vagrant/scripts/start-instance.sh' firefox http://192.168.50.10/records/1 Using kickstart scripts ----------------------- You can set some environment variables and run kickstart provisioning and installation scripts manually:: vim .inveniorc source .inveniorc scripts/provision-web.sh scripts/provision-postgresql.sh scripts/provision-elasticsearch.sh scripts/provision-redis.sh scripts/provision-rabbitmq.sh scripts/provision-worker.sh scripts/create-instance.sh scripts/populate-instance.sh scripts/start-instance.sh firefox http://192.168.50.10/records/1 -See :ref:`installation_detailed` for more information. +See :ref:`install_prerequisites` for more information. diff --git a/docs/usersguide/running.rst b/docs/usersguide/running.rst index b0224bfe2..2fa4c3af6 100644 --- a/docs/usersguide/running.rst +++ b/docs/usersguide/running.rst @@ -1,11 +1,162 @@ Running Invenio =============== +Understanding Invenio components +-------------------------------- + +Invenio dems site consists of many components. To see which ones the Invenio +demo site uses, you can do: + +.. code-block:: console + + $ pip freeze | grep invenio + invenio-access==1.0.0a11 + invenio-accounts==1.0.0b3 + invenio-admin==1.0.0b1 + invenio-app==1.0.0a1 + invenio-app-ils==1.0.0a2 + invenio-assets==1.0.0b6 + invenio-base==1.0.0a14 + invenio-celery==1.0.0b2 + invenio-config==1.0.0b3 + invenio-db==1.0.0b3 + invenio-formatter==1.0.0b1 + invenio-i18n==1.0.0b3 + invenio-indexer==1.0.0a9 + invenio-jsonschemas==1.0.0a3 + invenio-logging==1.0.0b1 + invenio-mail==1.0.0b1 + invenio-marc21==1.0.0a5 + invenio-oaiserver==1.0.0a12 + invenio-oauth2server==1.0.0a15 + invenio-oauthclient==1.0.0a12 + invenio-pidstore==1.0.0b1 + invenio-query-parser==0.6.0 + invenio-records==1.0.0b1 + invenio-records-rest==1.0.0a18 + invenio-records-ui==1.0.0a9 + invenio-rest==1.0.0a10 + invenio-search==1.0.0a9 + invenio-search-ui==1.0.0a6 + invenio-theme==1.0.0b2 + invenio-userprofiles==1.0.0a9 + Starting the webserver ---------------------- -Starting job queue ------------------- +The Invenio application server can be started using: + +.. code-block:: bash + + invenio run -h 0.0.0.0 + +For debugging purposes, you can use: + +.. code-block:: bash + + pip install Flask-DebugToolbar + FLASK_DEBUG=1 invenio run --debugger -h 0.0.0.0 + +Starting the job queue +---------------------- + +Invenio uses Celery for task execution. The task queue should be started as +follows: + +.. code-block:: bash + + celery worker -A invenio_app.celery + +For debugging purposes, you can increse logging level: + +.. code-block:: bash + + celery worker -A invenio_app.celery -l DEBUG Using the CLI ------------- + +Invenio comes with centralised command line. Use ``--help`` to see available commands: + +.. code-block:: console + + $ invenio --help + Usage: invenio [OPTIONS] COMMAND [ARGS]... + + Command Line Interface for Invenio. + + Options: + --version Show the flask version + --help Show this message and exit. + + Commands: + access Account commands. + alembic Perform database migrations. + assets Web assets commands. + collect Collect static files. + db Database commands. + demo Demo-site commands. + index Management command for search indicies. + instance Instance commands. + marc21 MARC21 related commands. + npm Generate a package.json file. + pid PID-Store management commands. + records Record management commands. + roles Role commands. + run Runs a development server. + shell Runs a shell in the app context. + users User commands. + +You can use ``--help`` for each individual command, for example: + +.. code-block:: console + + $ invenio marc21 import --help + Usage: invenio marc21 import [OPTIONS] INPUT + + Import MARCXML records. + + Options: + --bibliographic + --authority + --help Show this message and exit. + +Using Python shell +------------------ + +You can start interactive Python shell which will load the Invenio application +context so that you can work with the instance: + +.. code-block:: console + + $ invenio shell + Python 2.7.6 (default, Oct 26 2016, 20:30:19) + [GCC 4.8.4] on linux2 + App: invenio + Instance: /home/vagrant/.virtualenvs/invenio/var/instance + >>> app.config['BABEL_DEFAULT_LANGUAGE'] + 'en' + >>> app.config['BROKER_URL'] + 'amqp://guest:guest@192.168.50.10:5672//' + +Using administrative interface +------------------------------ + +You can access administrative interface: + +.. code-block:: console + + $ firefox http://192.168.50.10/admin + +For example, let us look at the record ID 117 that we have uploaded in +:ref:`create_and_search_your_first_record`. Looking at the administrative +interface, we can see that this record has been attributed an internal UUID: + + ======== ===================== ========== =========== ==================================== + PID_Type PID Status Object Type Object UUID + ======== ===================== ========== =========== ==================================== + oai oai:invenio:recid/117 REGISTERED rec a11dad76-5bd9-471c-975a-0b2b01d74831 + recid 117 REGISTERED rec a11dad76-5bd9-471c-975a-0b2b01d74831 + ======== ===================== ========== =========== ==================================== + +See :ref:`loading_content` for more information about object UUIDs and PIDs. diff --git a/docs/usersguide/tutorial/configure.rst b/docs/usersguide/tutorial/configure.rst new file mode 100644 index 000000000..acc26478f --- /dev/null +++ b/docs/usersguide/tutorial/configure.rst @@ -0,0 +1,53 @@ +.. _configure_invenio: + +Configure Invenio +================= + +After having installed Invenio demo site in :ref:`install_invenio`, let us see +briefly the instance configuration. + +Configure instance +------------------ + +Invenio instance can be configured by editing ``invenio.cfg`` configuration +file. Here is an example: + +.. code-block:: console + + $ cdvirtualenv var/instance/ + $ cat invenio.cfg + # Database + SQLALCHEMY_DATABASE_URI='postgresql+psycopg2://invenio:dbpass123@192.168.50.10:5432/invenio' + + # Statis files + COLLECT_STORAGE='flask_collect.storage.file' + + # Redis + CACHE_TYPE='redis' + CACHE_REDIS_HOST='192.168.50.10' + CACHE_REDIS_URL='redis://192.168.50.10:6379/0' + ACCOUNTS_SESSION_REDIS_URL='redis://192.168.50.10:6379/1' + + # Celery + BROKER_URL='amqp://guest:guest@192.168.50.10:5672//' + CELERY_RESULT_BACKEND='redis://192.168.50.10:6379/2' + + # Elasticsearch + SEARCH_ELASTIC_HOSTS='192.168.50.10' + + # JSON Schema + JSONSCHEMAS_ENDPOINT='/schema' + JSONSCHEMAS_HOST='192.168.50.10' + + # OAI server + OAISERVER_RECORD_INDEX='marc21' + OAISERVER_ID_PREFIX='oai:invenio:recid/' + +Configuration options +--------------------- + +Since Invenio demo site uses ILS flavour of Invenio, you can learn more about +the configuration options in `Invenio-App-ILS configuration documentation +<http://invenio-app-ils.readthedocs.io/en/latest/configuration.html>`_. + +We shall see how to customise instance more deeply in :ref:`customise_invenio`. diff --git a/docs/usersguide/tutorial/customize.rst b/docs/usersguide/tutorial/customize.rst index da8428938..3e08718ac 100644 --- a/docs/usersguide/tutorial/customize.rst +++ b/docs/usersguide/tutorial/customize.rst @@ -1,332 +1,336 @@ .. This file is part of Invenio. Copyright (C) 2017 CERN. Invenio is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Invenio 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 General Public License for more details. You should have received a copy of the GNU General Public License along with Invenio; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. In applying this license, CERN does not waive the privileges and immunities granted to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. -Customization -============= +.. _customise_invenio: -The goal of this tutorial is to customize Invenio v3. +Customise Invenio +================= -Install -------- +The goal of this tutorial is to demonstrate basic Invenio customisation. We +shall modify the size logo, the page templates, the search facets, the sort +options, and more. + +Install "beauty" module +----------------------- First go in the virtual machine: .. code-block:: console laptop> vagrant ssh web vagrant> workon invenio Install the module ``invenio-beauty``: .. code-block:: console vagrant> cd /vagrant/2-customization/invenio-beauty vagrant> pip install . vagrant> invenio collect vagrant> invenio run -h 0.0.0.0 -Customize ---------- +Customize logo and templates +---------------------------- If you go to ``http://192.168.50.10/``, you will see the default Invenio, but how we can customize it? Let's first stop invenio server. Open with your favorite editor the ``~/.virtualenvs/invenio/var/instance/invenio.cfg`` 1. Modify the logo ^^^^^^^^^^^^^^^^^^ Let's make our theme beautiful by replacing the logo in the ``~/.virtualenvs/invenio/var/instance/invenio.cfg`` add the following: .. code-block:: python THEME_LOGO = 'images/unicorn.png' THEME_FRONTPAGE_TITLE = 'Unicorn Institute' Now if you run .. code-block:: console vagrant> invenio run -h 0.0.0.0 and navigate to ``http://192.168.50.10`` you will see the new logo and front page title. 2. Add facets ^^^^^^^^^^^^^ Let's replace the facets with the ``Authors`` adding the field ``main_entry_personal_name.personal_name`` in the ``~/.virtualenvs/invenio/var/instance/invenio.cfg`` add the following: .. code-block:: python from invenio_records_rest.facets import terms_filter RECORDS_REST_FACETS = { 'marc21': { 'aggs': { 'author': { 'terms': { 'field': 'main_entry_personal_name.personal_name' } } }, 'post_filters': { 'author': terms_filter('main_entry_personal_name.personal_name') } } } Now if you run .. code-block:: console vagrant> invenio run -h 0.0.0.0 and navigate to ``http://192.168.50.10/search`` you will see that the facets have been replaced with the ``Authors``. 3. Add sort options ^^^^^^^^^^^^^^^^^^^ in the ``~/.virtualenvs/invenio/var/instance/invenio.cfg`` add the following: .. code-block:: python RECORDS_REST_SORT_OPTIONS = { 'records': { 'title': { 'fields': ['title_statement.title'], 'title': 'Record title', 'order': 1, } } } Now if you run .. code-block:: console vagrant> invenio run -h 0.0.0.0 and navigate to ``http://192.168.50.10/search`` you will see that the sort list have been replaced with the ``Record title``. 4. Change a detail view ^^^^^^^^^^^^^^^^^^^^^^^ We will now replace the template for the detail view of the record, this is possible by changing ``RECORDS_UI_ENDPOINTS`` with the desired template. In our case we have created the following: in the ``/vagrant/2-customization/invenio-beauty/invenio_beauty/templates/detail.html`` .. code-block:: python {%- extends config.RECORDS_UI_BASE_TEMPLATE %} {%- macro record_content(data) %} {% for key, value in data.items() recursive %} <li class="list-group-item"> {% if value is mapping %} <strong>{{ key }}:</strong> <ul class="list-group">{{ loop(value.items()) }}</ul> {% elif value is iterable and value is not string %} <strong>{{ key }}:</strong> <ol> {% for item in value %} <li> {% if item is mapping %} <ul class="list-group"> {{ record_content(item) }} </ul> {% else %} {{ item }} {% endif %} </li> {% endfor %} </ol> {% else %} <strong>{{ key }}:</strong> {{ value }} {% endif %} </li> {% endfor %} {%- endmacro %} {%- block page_body %} <div class="container"> <div class="row"> <div class="col-md-12"> <h2> {{ record.title_statement.title }}</h2> <hr /> <p class="lead">{{ record.summary[0].summary }}</p> <hr /> <h3> {{ _('Metadata') }}</h3> <div calss="well"> {{ record_content(record) }} </div> </div> </div> </div> {%- endblock %} in the ``~/.virtualenvs/invenio/var/instance/invenio.cfg`` add the following: .. code-block:: python RECORDS_UI_ENDPOINTS = { "recid": { "pid_type": "recid", "route": "/records/<pid_value>", "template": "invenio_beauty/detail.html" }, } Now if you run .. code-block:: console vagrant> invenio run -h 0.0.0.0 and navigate to ``http://192.168.50.10/records/1`` you will see the new template. 5. Modify search results template ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ We will now replace the search results template, in the search result we are using angular templates and they can easily configured from the following vars: - SEARCH_UI_JSTEMPLATE_COUNT - SEARCH_UI_JSTEMPLATE_ERROR - SEARCH_UI_JSTEMPLATE_FACETS - SEARCH_UI_JSTEMPLATE_RANGE - SEARCH_UI_JSTEMPLATE_LOADING - SEARCH_UI_JSTEMPLATE_PAGINATION - SEARCH_UI_JSTEMPLATE_RESULTS - SEARCH_UI_JSTEMPLATE_SELECT_BOX - SEARCH_UI_JSTEMPLATE_SORT_ORDER For our example we will change only ``SEARCH_UI_JSTEMPLATE_RESULTS``, the location of the angular templates are ``static/templates/<name of your module>`` in ``/vagrant/2-customization/invenio-beauty/invenio_beauty/static/templates/invenio_beauty/results.html`` .. code-block:: html <ol> <li ng-repeat="record in vm.invenioSearchResults.hits.hits track by $index"> <span class="label label-success">{{ record.metadata.language_code[0].language_code_of_text_sound_track_or_separate_title[0] }}</span> <h4><a target="_self" ng-href="/records/{{ record.id }}">{{ record.metadata.title_statement.title }}</a></h4> <p>{{ record.metadata.summary[0].summary }}</p> </li> </ol> On the angular templates, you have access to the record metadata object, so in you templates you can use ``{{ record.metadata.foo }}``. Now in the search results template, we will display the language tag on top of each record ``language_code``. in the ``~/.virtualenvs/invenio/var/instance/invenio.cfg`` add the following: .. code-block:: python SEARCH_UI_JSTEMPLATE_RESULTS = 'templates/invenio_beauty/results.html' Now if you run .. code-block:: console vagrant> invenio collect -v vagrant> invenio run -h 0.0.0.0 and navigate to ``http://192.168.50.10/search`` you will see the new template. 6. Change the homepage template ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ We will now replace the demo's homepage. You can change the whole homepage just by replacing ``THEME_FRONTPAGE_TEMPLATE`` with your own template, for this example we have created the following: in ``/vagrant/2-customization/invenio-beauty/invenio_beauty/templates/invenio_beauty/home.html`` .. code-block:: python {%- extends "invenio_theme/page.html" %} {%- block navbar_search %}{% endblock %} {%- block page_body %} <div class="container"> <div class="row"> <div class="col-lg-12"> <h1 class="text-center"> {{_(config.THEME_FRONTPAGE_TITLE)}} Search </h1> <form action="/search"> <div class="form-group"> <input type="text" name="q" class="form-control" placeholder="Type and press enter to search"> </div> </form> </div> </div> </div> {%- endblock %} If you have a closer look, you will see that we have access to different config variables on the template, by using the ``config``. For example if we want to display the ``THEME_FRONTPAGE_TITLE`` we can you ``config.THEME_FRONTPAGE_TITLE`` So the only thing we should do is to edit the ``config.py`` in the ``~/.virtualenvs/invenio/var/instance/invenio.cfg`` add the following: .. code-block:: python THEME_FRONTPAGE_TEMPLATE = 'invenio_beauty/home.html' Now if you run .. code-block:: console vagrant> invenio run -h 0.0.0.0 and navigate to ``http://192.168.50.10`` you will see the new template. Everything together ------------------- You want to see the results? Just run the following command. .. code-block:: console vagrant> cd /vagrant/iugw2017/2-customization vagrant> cat final.cfg >> ~/.virtualenvs/invenio/var/instance/invenio.cfg diff --git a/docs/usersguide/tutorial/index.rst b/docs/usersguide/tutorial/index.rst index c479d187f..4567bedfb 100644 --- a/docs/usersguide/tutorial/index.rst +++ b/docs/usersguide/tutorial/index.rst @@ -1,28 +1,29 @@ .. This file is part of Invenio - Copyright (C) 2015 CERN. + Copyright (C) 2015, 2017 CERN. Invenio is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Invenio 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 General Public License for more details. You should have received a copy of the GNU General Public License along with Invenio; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. First steps =========== .. toctree:: :maxdepth: 2 prerequisites install + configure records customize diff --git a/docs/usersguide/tutorial/install.rst b/docs/usersguide/tutorial/install.rst index 3ae67cb27..f49a3abd3 100644 --- a/docs/usersguide/tutorial/install.rst +++ b/docs/usersguide/tutorial/install.rst @@ -1,2 +1,141 @@ -Part 1: Install and configuring Invenio -======================================= +.. _install_invenio: + +Install Invenio +=============== + +Now that all the prerequisites have been set up in :ref:`install_prerequisites`, +we can proceed with the installation of the Invenio itself. The installation is +happening on the web node (192.168.50.10). + +We start by creating and configuring a new Invenio instance, continue by +populating it with some example records, and finally we start the web +application. This can be done in an automated unattended way by running the +following scripts: + +.. code-block:: shell + + source .inveniorc + ./scripts/create-instance.sh + ./scripts/populate-instance.sh + ./scripts/start-instance.sh + +.. note:: + + If you want to install the very-bleeding-edge Invenio packages from GitHub, + you can run the ``create-instance.sh`` script with the ``--devel`` argument:: + + ./scripts/create-instance.sh --devel + +Let’s see in detail about every Invenio installation step. + +Create instance +~~~~~~~~~~~~~~~ + +We start by creating a fresh new Python virtual environment that will hold our +brand new Invenio v3.0 instance: + +.. include:: ../../../scripts/create-instance.sh + :start-after: # sphinxdoc-create-virtual-environment-begin + :end-before: # sphinxdoc-create-virtual-environment-end + :literal: + +We continue by installing Invenio v3.0 Integrated Library System flavour demo +site from PyPI: + +.. include:: ../../../scripts/create-instance.sh + :start-after: # sphinxdoc-install-invenio-full-begin + :end-before: # sphinxdoc-install-invenio-full-end + :literal: + +Let's briefly customise our instance with respect to the location of the +database server, the Redis server, the Elasticsearch server, and all the other +dependent services in our multi-server environment: + +.. include:: ../../../scripts/create-instance.sh + :start-after: # sphinxdoc-customise-instance-begin + :end-before: # sphinxdoc-customise-instance-end + :literal: + +In the instance folder, we run Npm to install any JavaScript libraries that +Invenio needs: + +.. include:: ../../../scripts/create-instance.sh + :start-after: # sphinxdoc-run-npm-begin + :end-before: # sphinxdoc-run-npm-end + :literal: + +We can now collect and build CSS/JS assets of our Invenio instance: + +.. include:: ../../../scripts/create-instance.sh + :start-after: # sphinxdoc-collect-and-build-assets-begin + :end-before: # sphinxdoc-collect-and-build-assets-end + :literal: + +Our first new Invenio instance is created and ready for loading some example +records. + +Populate instance +~~~~~~~~~~~~~~~~~ + +We proceed by creating a dedicated database that will hold persistent data of +our installation, such as bibliographic records or user accounts. The database +tables can be created as follows: + +.. include:: ../../../scripts/populate-instance.sh + :start-after: # sphinxdoc-create-database-begin + :end-before: # sphinxdoc-create-database-end + :literal: + +We continue by creating a user account: + +.. include:: ../../../scripts/populate-instance.sh + :start-after: # sphinxdoc-create-user-account-begin + :end-before: # sphinxdoc-create-user-account-end + :literal: + +We can now create the Elasticsearch indexes and initialise the indexing queue: + +.. include:: ../../../scripts/populate-instance.sh + :start-after: # sphinxdoc-index-initialisation-begin + :end-before: # sphinxdoc-index-initialisation-end + :literal: + +We proceed by populating our Invenio demo instance with some example demo +MARCXML records: + +.. include:: ../../../scripts/populate-instance.sh + :start-after: # sphinxdoc-populate-with-demo-records-begin + :end-before: # sphinxdoc-populate-with-demo-records-end + :literal: + +Start instance +~~~~~~~~~~~~~~ + +Let's now start the web application: + +.. include:: ../../../scripts/start-instance.sh + :start-after: # sphinxdoc-start-application-begin + :end-before: # sphinxdoc-start-application-end + :literal: + +and the web server: + +.. include:: ../../../scripts/start-instance.sh + :start-after: # sphinxdoc-start-nginx-begin + :end-before: # sphinxdoc-start-nginx-end + :literal: + +We should now see our demo records on the web: + +.. code-block:: shell + + firefox http://${INVENIO_WEB_HOST}/records/1 + +and we can access them via REST API: + +.. code-block:: shell + + curl -i -H "Accept: application/json" \ + http://${INVENIO_WEB_HOST}/api/records/1 + +We are done! Our first Invenio v3.0 demo instance is fully up and running. diff --git a/docs/usersguide/tutorial/prerequisites.rst b/docs/usersguide/tutorial/prerequisites.rst index 5a14fd0ba..35e4529f3 100644 --- a/docs/usersguide/tutorial/prerequisites.rst +++ b/docs/usersguide/tutorial/prerequisites.rst @@ -1,2 +1,510 @@ +.. _install_prerequisites: + Install prerequisites ===================== + +Overview +-------- + +Invenio uses several services such as `PostgreSQL <http://www.postgresql.org/>`_ +database server, `Redis <http://redis.io/>`_ for caching, `Elasticsearch +<https://www.elastic.co/products/elasticsearch>`_ for indexing and information +retrieval, `RabbitMQ <http://www.rabbitmq.com/>`_ for messaging, `Celery +<http://www.celeryproject.org/>`_ for task execution. + +You can install them manually or you can use provided kickstart scripts as +mentioned in :ref:`quickstart`: + +.. code-block:: bash + + vim .inveniorc + source .inveniorc + scripts/provision-web.sh + scripts/provision-postgresql.sh + scripts/provision-elasticsearch.sh + scripts/provision-redis.sh + scripts/provision-rabbitmq.sh + scripts/provision-worker.sh + +The next section gives a detailed walk-through of what the scripts do. + +Concrete example +---------------- + +In this installation example, we'll create an Invenio digital library instance +using a multi-machine setup where separate services (such as the database server +and the web server) run on separate dedicated machines. Such a multi-machine +setup emulates to what one would typically use in production. (However, it is +very well possible to follow this guide and install all the services onto the +same "localhost", if one wants to.) + +We'll use six dedicated machines running the following services: + +============= ============= ==================== +node IP runs +============= ============= ==================== +web 192.168.50.10 Invenio web application +postgresql 192.168.50.11 `PostgreSQL <http://www.postgresql.org/>`_ database server +redis 192.168.50.12 `Redis <http://redis.io/>`_ caching service +elasticsearch 192.168.50.13 `Elasticsearch <https://www.elastic.co/products/elasticsearch>`_ information retrieval service +rabbitmq 192.168.50.14 `RabbitMQ <http://www.rabbitmq.com/>`_ messaging service +worker 192.168.50.15 `Celery <http://www.celeryproject.org/>`_ worker node +============= ============= ==================== + +The instructions below are tested on Ubuntu 14.04 LTS (Trusty Tahr) and CentOS 7 +operating systems. For other operating systems such as Mac OS X, you may want to +check out the "kickstart" set of scripts coming with the Invenio source code +that perform the below-quoted installation steps in an unattended automated way. + +Environment variables +~~~~~~~~~~~~~~~~~~~~~ + +Let's define some useful environment variables that will describe our Invenio +instance setup: + +.. glossary:: + + INVENIO_WEB_HOST + The IP address of the Web server node. + + INVENIO_WEB_INSTANCE + The name of your Invenio instance that will be created. Usually equal to + the name of the Python virtual environment. + + INVENIO_WEB_VENV + The name of the Python virtual environment where Invenio will be installed. + Usually equal to the name of the Invenio instance. + + INVENIO_USER_EMAIL + The email address of a user account that will be created on the Invenio + instance. + + INVENIO_USER_PASS + The password of this Invenio user. + + INVENIO_POSTGRESQL_HOST + The IP address of the PostgreSQL database server. + + INVENIO_POSTGRESQL_DBNAME + The database name that will hold persistent data of our Invenio instance. + + INVENIO_POSTGRESQL_DBUSER + The database user name used to connect to the database server. + + INVENIO_POSTGRESQL_DBPASS + The password of this database user. + + INVENIO_REDIS_HOST + The IP address af the Redis server. + + INVENIO_ELASTICSEARCH_HOST + The IP address of the Elasticsearch information retrieval server. + + INVENIO_RABBITMQ_HOST + The IP address of the RabbitMQ messaging server. + + INVENIO_WORKER_HOST + The IP address of the Celery worker node. + +In our example setup, we shall use: + +.. include:: ../../../.inveniorc + :start-after: # sphinxdoc-kickstart-configuration-variables-begin + :end-before: # sphinxdoc-kickstart-configuration-variables-end + :literal: + +Let us save this configuration in a file called ``.inveniorc`` for future use. + +Web +~~~ + +The web application node (192.168.50.10) is where the main Invenio application +will be running. We need to provision it with some system dependencies in order +to be able to install various underlying Python and JavaScript libraries. + +The web application node can be set up in an automated unattended way by running +the following script: + +.. code-block:: shell + + source .inveniorc + ./scripts/provision-web.sh + +Let's see in detail what the web provisioning script does. + +First, let's see if using ``sudo`` will be required: + +.. include:: ../../../scripts/provision-web.sh + :start-after: # sphinxdoc-install-detect-sudo-begin + :end-before: # sphinxdoc-install-detect-sudo-end + :literal: + +Second, some useful system tools are installed: + +* on Ubuntu 14.04 LTS (Trusty Tahr): + +.. include:: ../../../scripts/provision-web.sh + :start-after: # sphinxdoc-install-useful-system-tools-ubuntu14-begin + :end-before: # sphinxdoc-install-useful-system-tools-ubuntu14-end + :literal: + +* on CentOS 7: + +.. include:: ../../../scripts/provision-web.sh + :start-after: # sphinxdoc-install-useful-system-tools-centos7-begin + :end-before: # sphinxdoc-install-useful-system-tools-centos7-end + :literal: + +Third, an external Node.js package repository is enabled. We'll be needing to +install and run Npm on the web node later. The Node.js repository is enabled as +follows: + +* on Ubuntu 14.04 LTS (Trusty Tahr): + +.. include:: ../../../scripts/provision-web.sh + :start-after: # sphinxdoc-add-nodejs-external-repository-ubuntu14-begin + :end-before: # sphinxdoc-add-nodejs-external-repository-ubuntu14-end + :literal: + +* on CentOS 7: + +.. include:: ../../../scripts/provision-web.sh + :start-after: # sphinxdoc-add-nodejs-external-repository-centos7-begin + :end-before: # sphinxdoc-add-nodejs-external-repository-centos7-end + :literal: + +Fourth, all the common prerequisite software libraries and packages that Invenio +needs are installed: + +* on Ubuntu 14.04 LTS (Trusty Tahr): + +.. include:: ../../../scripts/provision-web.sh + :start-after: # sphinxdoc-install-web-common-ubuntu14-begin + :end-before: # sphinxdoc-install-web-common-ubuntu14-end + :literal: + +* on CentOS7: + +.. include:: ../../../scripts/provision-web.sh + :start-after: # sphinxdoc-install-web-common-centos7-begin + :end-before: # sphinxdoc-install-web-common-centos7-end + :literal: + +We want to use PostgreSQL database in this installation example, so we need to +install corresponding libraries too: + +* on Ubuntu 14.04 LTS (Trusty Tahr): + +.. include:: ../../../scripts/provision-web.sh + :start-after: # sphinxdoc-install-web-libpostgresql-ubuntu14-begin + :end-before: # sphinxdoc-install-web-libpostgresql-ubuntu14-end + :literal: + +* on CentOS7: + +.. include:: ../../../scripts/provision-web.sh + :start-after: # sphinxdoc-install-web-libpostgresql-centos7-begin + :end-before: # sphinxdoc-install-web-libpostgresql-centos7-end + :literal: + +Fifth, now that Node.js is installed, we can proceed with installing Npm and +associated CSS/JS filter tools. Let's do it globally: + +* on either of the operating systems: + +.. include:: ../../../scripts/provision-web.sh + :start-after: # sphinxdoc-install-npm-and-css-js-filters-begin + :end-before: # sphinxdoc-install-npm-and-css-js-filters-end + :literal: + +Sixth, we'll install Python virtual environment wrapper tools and activate them +in the current user shell process: + +* on either of the operating systems: + +.. include:: ../../../scripts/provision-web.sh + :start-after: # sphinxdoc-install-virtualenvwrapper-begin + :end-before: # sphinxdoc-install-virtualenvwrapper-end + :literal: + +Seventh, we install Nginx web server and configure appropriate virtual host: + +* on Ubuntu 14.04 LTS (Trusty Tahr): + +.. include:: ../../../scripts/provision-web.sh + :start-after: # sphinxdoc-install-web-nginx-ubuntu14-begin + :end-before: # sphinxdoc-install-web-nginx-ubuntu14-end + :literal: + +* on CentOS7: + +.. include:: ../../../scripts/provision-web.sh + :start-after: # sphinxdoc-install-web-nginx-centos7-begin + :end-before: # sphinxdoc-install-web-nginx-centos7-end + :literal: + +Finally, let's clean after ourselves: + +* on Ubuntu 14.04 LTS (Trusty Tahr): + +.. include:: ../../../scripts/provision-web.sh + :start-after: # sphinxdoc-install-web-cleanup-ubuntu14-begin + :end-before: # sphinxdoc-install-web-cleanup-ubuntu14-end + :literal: + +* on CentOS7: + +.. include:: ../../../scripts/provision-web.sh + :start-after: # sphinxdoc-install-web-cleanup-centos7-begin + :end-before: # sphinxdoc-install-web-cleanup-centos7-end + :literal: + +Database +~~~~~~~~ + +The database server (192.168.50.11) will hold persistent data of our Invenio +installation, such as bibliographic records or user accounts. Invenio supports +MySQL, PostgreSQL, and SQLite databases. In this tutorial, we shall use +PostgreSQL that is the recommended database platform for Invenio. + +The database server node can be set up in an automated unattended way by running +the following script: + +.. code-block:: shell + + source .inveniorc + ./scripts/provision-postgresql.sh + +Let's see in detail what the database provisioning script does. + +First, we install and configure the database software: + +* on Ubuntu 14.04 LTS (Trusty Tahr): + +.. include:: ../../../scripts/provision-postgresql.sh + :start-after: # sphinxdoc-install-postgresql-ubuntu14-begin + :end-before: # sphinxdoc-install-postgresql-ubuntu14-end + :literal: + +* on CentOS 7: + +.. include:: ../../../scripts/provision-postgresql.sh + :start-after: # sphinxdoc-install-postgresql-centos7-begin + :end-before: # sphinxdoc-install-postgresql-centos7-end + :literal: + +We can now create a new database user with the necessary access permissions on +the new database: + +* on either of the operating systems: + +.. include:: ../../../scripts/provision-postgresql.sh + :start-after: # sphinxdoc-setup-postgresql-access-begin + :end-before: # sphinxdoc-setup-postgresql-access-end + :literal: + +Finally, let's clean after ourselves: + +* on Ubuntu 14.04 LTS (Trusty Tahr): + +.. include:: ../../../scripts/provision-postgresql.sh + :start-after: # sphinxdoc-install-postgresql-cleanup-ubuntu14-begin + :end-before: # sphinxdoc-install-postgresql-cleanup-ubuntu14-end + :literal: + +* on CentOS7: + +.. include:: ../../../scripts/provision-postgresql.sh + :start-after: # sphinxdoc-install-postgresql-cleanup-centos7-begin + :end-before: # sphinxdoc-install-postgresql-cleanup-centos7-end + :literal: + +Redis +~~~~~ + +The Redis server (192.168.50.12) is used for various caching needs. + +The Redis server can be set up in an automated unattended way by running the +following script: + +.. code-block:: shell + + source .inveniorc + ./scripts/provision-redis.sh + +Let's see in detail what the Redis provisioning script does. + +* on Ubuntu 14.04 LTS (Trusty Tahr): + +.. include:: ../../../scripts/provision-redis.sh + :start-after: # sphinxdoc-install-redis-ubuntu14-begin + :end-before: # sphinxdoc-install-redis-ubuntu14-end + :literal: + +* on CentOS 7: + +.. include:: ../../../scripts/provision-redis.sh + :start-after: # sphinxdoc-install-redis-centos7-begin + :end-before: # sphinxdoc-install-redis-centos7-end + :literal: + +Finally, let's clean after ourselves: + +* on Ubuntu 14.04 LTS (Trusty Tahr): + +.. include:: ../../../scripts/provision-redis.sh + :start-after: # sphinxdoc-install-redis-cleanup-ubuntu14-begin + :end-before: # sphinxdoc-install-redis-cleanup-ubuntu14-end + :literal: + +* on CentOS7: + +.. include:: ../../../scripts/provision-redis.sh + :start-after: # sphinxdoc-install-redis-cleanup-centos7-begin + :end-before: # sphinxdoc-install-redis-cleanup-centos7-end + :literal: + +Elasticsearch +~~~~~~~~~~~~~ + +The Elasticsearch server (192.168.50.13) is used to index and search +bibliographic records, fulltext documents, and other various interesting +information managed by our Invenio digital library instance. + +The Elasticsearch server can be set up in an automated unattended way by running +the following script: + +.. code-block:: shell + + source .inveniorc + ./scripts/provision-elasticsearch.sh + +Let's see in detail what the Elasticsearch provisioning script does. + +* on Ubuntu 14.04 LTS (Trusty Tahr): + +.. include:: ../../../scripts/provision-elasticsearch.sh + :start-after: # sphinxdoc-install-elasticsearch-ubuntu14-begin + :end-before: # sphinxdoc-install-elasticsearch-ubuntu14-end + :literal: + +* on CentOS 7: + +.. include:: ../../../scripts/provision-elasticsearch.sh + :start-after: # sphinxdoc-install-elasticsearch-centos7-begin + :end-before: # sphinxdoc-install-elasticsearch-centos7-end + :literal: + +Some packages require extra plugins to be installed. + +.. include:: ../../../scripts/provision-elasticsearch.sh + :start-after: # sphinxdoc-install-elasticsearch-plugins-begin + :end-before: # sphinxdoc-install-elasticsearch-plugins-end + :literal: + +Finally, let's clean after ourselves: + +* on Ubuntu 14.04 LTS (Trusty Tahr): + +.. include:: ../../../scripts/provision-elasticsearch.sh + :start-after: # sphinxdoc-install-elasticsearch-cleanup-ubuntu14-begin + :end-before: # sphinxdoc-install-elasticsearch-cleanup-ubuntu14-end + :literal: + +* on CentOS7: + +.. include:: ../../../scripts/provision-elasticsearch.sh + :start-after: # sphinxdoc-install-elasticsearch-cleanup-centos7-begin + :end-before: # sphinxdoc-install-elasticsearch-cleanup-centos7-end + :literal: + +RabbitMQ +~~~~~~~~ + +The RabbitMQ server (192.168.50.14) is used as a messaging middleware broker. + +The RabbitMQ server can be set up in an automated unattended way by running the +following script: + +.. code-block:: shell + + source .inveniorc + ./scripts/provision-rabbitmq.sh + +Let's see in detail what the RabbitMQ provisioning script does. + +* on Ubuntu 14.04 LTS (Trusty Tahr): + +.. include:: ../../../scripts/provision-rabbitmq.sh + :start-after: # sphinxdoc-install-rabbitmq-ubuntu14-begin + :end-before: # sphinxdoc-install-rabbitmq-ubuntu14-end + :literal: + +* on CentOS 7: + +.. include:: ../../../scripts/provision-rabbitmq.sh + :start-after: # sphinxdoc-install-rabbitmq-centos7-begin + :end-before: # sphinxdoc-install-rabbitmq-centos7-end + :literal: + +Finally, let's clean after ourselves: + +* on Ubuntu 14.04 LTS (Trusty Tahr): + +.. include:: ../../../scripts/provision-rabbitmq.sh + :start-after: # sphinxdoc-install-rabbitmq-cleanup-ubuntu14-begin + :end-before: # sphinxdoc-install-rabbitmq-cleanup-ubuntu14-end + :literal: + +* on CentOS7: + +.. include:: ../../../scripts/provision-rabbitmq.sh + :start-after: # sphinxdoc-install-rabbitmq-cleanup-centos7-begin + :end-before: # sphinxdoc-install-rabbitmq-cleanup-centos7-end + :literal: + +Worker +~~~~~~ + +The Celery worker node (192.168.50.15) is used to execute potentially long tasks +in asynchronous manner. + +The worker node can be set up in an automated unattended way by running the +following script: + +.. code-block:: shell + + source .inveniorc + ./scripts/provision-worker.sh + +Let's see in detail what the worker provisioning script does. + +* on Ubuntu 14.04 LTS (Trusty Tahr): + +.. include:: ../../../scripts/provision-worker.sh + :start-after: # sphinxdoc-install-worker-ubuntu14-begin + :end-before: # sphinxdoc-install-worker-ubuntu14-end + :literal: + +* on CentOS 7: + +.. include:: ../../../scripts/provision-worker.sh + :start-after: # sphinxdoc-install-worker-centos7-begin + :end-before: # sphinxdoc-install-worker-centos7-end + :literal: + +Finally, let's clean after ourselves: + +* on Ubuntu 14.04 LTS (Trusty Tahr): + +.. include:: ../../../scripts/provision-worker.sh + :start-after: # sphinxdoc-install-worker-cleanup-ubuntu14-begin + :end-before: # sphinxdoc-install-worker-cleanup-ubuntu14-end + :literal: + +* on CentOS7: + +.. include:: ../../../scripts/provision-worker.sh + :start-after: # sphinxdoc-install-worker-cleanup-centos7-begin + :end-before: # sphinxdoc-install-worker-cleanup-centos7-end + :literal: diff --git a/docs/usersguide/tutorial/records.rst b/docs/usersguide/tutorial/records.rst index c1a13fcda..ac80a3cb5 100644 --- a/docs/usersguide/tutorial/records.rst +++ b/docs/usersguide/tutorial/records.rst @@ -1,2 +1,58 @@ -Part 2: Create and search your first record -=========================================== +.. _create_and_search_your_first_record: + +Create and search your first record +=================================== + +Now that Invenio demo site has been installed in :ref:`install_invenio`, let us +see how we can load some records. + +Upload a new record +------------------- + +For the ILS flavour let us create a small example record in MARCXML format: + +.. code-block:: console + + $ vim book.xml + $ cat book.xml + <?xml version="1.0" encoding="UTF-8"?> + <collection xmlns="http://www.loc.gov/MARC21/slim"> + <record> + <datafield tag="245" ind1=" " ind2=" "> + <subfield code="a">This is title</subfield> + </datafield> + <datafield tag="100" ind1=" " ind2=" "> + <subfield code="a">Doe, John</subfield> + </datafield> + </record> + </collection> + +We can upload it by using ``invenio marc21 import`` command: + +.. code-block:: console + + $ invenio marc21 import --bibliographic book.xml + Importing records + Created record 117 + Indexing records + +Search for the record +--------------------- + +Let us verify that it was well uploaded: + +.. code-block:: console + + $ firefox http://192.168.50.10/records/117 + +and that it is well searchable: + +.. code-block:: console + + $ firefox http://192.168.50.10/search?q=doe + +Uploading content +----------------- + +For more information on how to upload content to an Invenio instance, see the +documentation chapter on :ref:`loading_content`.