diff --git a/roles/calibre-web/README.rst b/roles/calibre-web/README.rst new file mode 100644 index 000000000..e7c735158 --- /dev/null +++ b/roles/calibre-web/README.rst @@ -0,0 +1,69 @@ +==================== +Calibre-web README +==================== + +This Ansible role installs Calibre-web in Internet-in-a-Box. Calibre-web server +provides a clean interface for browsing, reading and downloading eBooks +using an existing Calibre database. + +Access +------ + +After installation you can access Calibre-web at `http://box/calibre-web` using the +following IIAB calibre-web administration account. + + Username: Admin + + Password: changme + +If the default configuration is not found calibre-web server creates a new settings file +with calibre-web default administration account. + + Username: admin + + Password: admin123 + +Backend +-------- +You can manage the backend Calibre-web server manually with the following commands: + + systemctl enable calibre-web + + systemctl start calibre-web + + systemctl status calibre-web + + systemctl stop calibre-web + +Configuration +------------- +To configure calibre-web, first login as 'Admin'. Then select 'Configuration' +under the admin panel. + + +The default calibre-web settings are stored under '/library/calibre-web/config/app.db' +database file. The calibre-web stores its eBook information in calibre database + '/library/calibre-web/metadata.db' file. + +Upgrading +--------- +Reinstalling Calibre-web automatically upgrades to the latest version. Please backup your configuration +before reinstalling. To retain your configuration set `calibreweb_provision` variable to False. + +You can manually upgrade using 'git' command: + +$ cd /opt/calibre-web + +$ sudo git pull + +Backuping Content +-------------- +Calibre-web stores eBooks and various configuration settings under /library/calibre-web. +Please backup this folder before upgrading. Also set `calibreweb_provision` variable to +False before upgrading to prevent the Provision script from over-writting your settings. + +Known Issues +------------ +Trying to access a empty public bookshelf causes a system error. + +Current implementation of the calibre-web in Internet in a box doesn't include ebook converter program. diff --git a/roles/calibre-web/defaults/main.yml b/roles/calibre-web/defaults/main.yml new file mode 100644 index 000000000..348464f75 --- /dev/null +++ b/roles/calibre-web/defaults/main.yml @@ -0,0 +1,29 @@ +# The values here are defaults. +# To override them edit /etc/iiab/local_vars.yml + +# Installation Variables +calibreweb_install: False +calibreweb_enabled: False + +calibreweb_port: 8083 +calibreweb_url: /calibre-web +calibreweb_path: "{{ iiab_base }}/calibre-web" +calibreweb_exec_path: "{{ calibreweb_path }}/cps.py" + +# calibre-web folder to store its data files. +calibreweb_home: "{{ content_base }}/calibre-web" +# calibre-web folder to store configuration files. +calibreweb_config: "{{ calibreweb_home }}/config" + +# Calibre-web setup will be provisioned with default administration account, metadata.db and +# language. You could turn this to 'False' while reinstalling/upgrading calibre-web. +calibreweb_provision: True +calibreweb_settings_database: app.db +calibreweb_database: metadata.db + +#calibre-web system user +calibreweb_user: root + +# calibreweb admin account +# calibreweb_admin_user: Admin +# calibreweb_admin_password: changeme diff --git a/roles/calibre-web/files/app.db b/roles/calibre-web/files/app.db new file mode 100644 index 000000000..719553a34 Binary files /dev/null and b/roles/calibre-web/files/app.db differ diff --git a/roles/calibre-web/files/metadata.db b/roles/calibre-web/files/metadata.db new file mode 100644 index 000000000..828afa0ca Binary files /dev/null and b/roles/calibre-web/files/metadata.db differ diff --git a/roles/calibre-web/files/metadata_db_prefs_backup.json b/roles/calibre-web/files/metadata_db_prefs_backup.json new file mode 100644 index 000000000..a6b74b252 --- /dev/null +++ b/roles/calibre-web/files/metadata_db_prefs_backup.json @@ -0,0 +1,566 @@ +{ + "tag_browser_hidden_categories": [], + "library_view books view state": { + "column_positions": { + "languages": 11, + "publisher": 8, + "pubdate": 9, + "rating": 5, + "title": 1, + "tags": 6, + "series": 7, + "timestamp": 3, + "authors": 2, + "ondevice": 0, + "size": 4, + "last_modified": 10 + }, + "last_modified_injected": true, + "column_sizes": { + "languages": 0, + "publisher": 62, + "pubdate": 105, + "rating": 86, + "title": 51, + "tags": 100, + "series": 52, + "timestamp": 76, + "authors": 78, + "last_modified": 0, + "size": 88 + }, + "sort_history": [ + [ + "timestamp", + false + ] + ], + "languages_injected": true, + "column_alignment": { + "size": "center", + "pubdate": "center", + "timestamp": "center" + }, + "hidden_columns": [ + "last_modified", + "languages" + ] + }, + "user_categories": {}, + "saved_searches": {}, + "field_metadata": { + "pubdate": { + "table": null, + "is_multiple": {}, + "search_terms": [ + "pubdate" + ], + "is_editable": true, + "is_custom": false, + "rec_index": 15, + "is_csp": false, + "datatype": "datetime", + "name": "Ver\u00f6ffentlicht", + "label": "pubdate", + "is_category": false, + "display": { + "date_format": "MMM yyyy" + }, + "kind": "field", + "column": null + }, + "author_sort": { + "table": null, + "is_multiple": {}, + "search_terms": [ + "author_sort" + ], + "is_editable": true, + "is_custom": false, + "rec_index": 12, + "is_csp": false, + "datatype": "text", + "name": "Autorensortierung", + "label": "author_sort", + "is_category": false, + "display": {}, + "kind": "field", + "column": null + }, + "tags": { + "table": "tags", + "is_multiple": { + "cache_to_list": ",", + "ui_to_list": ",", + "list_to_ui": ", " + }, + "search_terms": [ + "tags", + "tag" + ], + "is_editable": true, + "is_custom": false, + "category_sort": "name", + "is_csp": false, + "datatype": "text", + "name": "Schlagw\u00f6rter", + "link_column": "tag", + "label": "tags", + "is_category": true, + "display": {}, + "kind": "field", + "rec_index": 6, + "column": "name" + }, + "id": { + "table": null, + "is_multiple": {}, + "search_terms": [ + "id" + ], + "is_editable": true, + "is_custom": false, + "rec_index": 0, + "is_csp": false, + "datatype": "int", + "name": null, + "label": "id", + "is_category": false, + "display": {}, + "kind": "field", + "column": null + }, + "news": { + "table": "news", + "is_multiple": {}, + "search_terms": [], + "is_editable": true, + "is_custom": false, + "category_sort": "name", + "is_csp": false, + "datatype": null, + "name": "Nachrichten", + "label": "news", + "is_category": true, + "display": {}, + "kind": "category", + "column": "name" + }, + "cover": { + "table": null, + "is_multiple": {}, + "search_terms": [ + "cover" + ], + "is_editable": true, + "is_custom": false, + "rec_index": 17, + "is_csp": false, + "datatype": "int", + "name": "Titelbild", + "label": "cover", + "is_category": false, + "display": {}, + "kind": "field", + "column": null + }, + "marked": { + "table": null, + "is_multiple": {}, + "search_terms": [ + "marked" + ], + "is_editable": true, + "is_custom": false, + "rec_index": 23, + "is_csp": false, + "datatype": "text", + "name": null, + "label": "marked", + "is_category": false, + "display": {}, + "kind": "field", + "column": null + }, + "series_sort": { + "table": null, + "is_multiple": {}, + "search_terms": [ + "series_sort" + ], + "is_editable": true, + "is_custom": false, + "rec_index": 24, + "is_csp": false, + "datatype": "text", + "name": "Seriensortierung", + "label": "series_sort", + "is_category": false, + "display": {}, + "kind": "field", + "column": null + }, + "comments": { + "table": null, + "is_multiple": {}, + "search_terms": [ + "comments", + "comment" + ], + "is_editable": true, + "is_custom": false, + "rec_index": 7, + "is_csp": false, + "datatype": "text", + "name": "Kommentare", + "label": "comments", + "is_category": false, + "display": {}, + "kind": "field", + "column": null + }, + "ondevice": { + "table": null, + "is_multiple": {}, + "search_terms": [ + "ondevice" + ], + "is_editable": true, + "is_custom": false, + "rec_index": 22, + "is_csp": false, + "datatype": "text", + "name": "Auf Ger\u00e4t", + "label": "ondevice", + "is_category": false, + "display": {}, + "kind": "field", + "column": null + }, + "size": { + "table": null, + "is_multiple": {}, + "search_terms": [ + "size" + ], + "is_editable": true, + "is_custom": false, + "rec_index": 4, + "is_csp": false, + "datatype": "float", + "name": "Gr\u00f6\u00dfe", + "label": "size", + "is_category": false, + "display": {}, + "kind": "field", + "column": null + }, + "title": { + "table": null, + "is_multiple": {}, + "search_terms": [ + "title" + ], + "is_editable": true, + "is_custom": false, + "rec_index": 1, + "is_csp": false, + "datatype": "text", + "name": "Titel", + "label": "title", + "is_category": false, + "display": {}, + "kind": "field", + "column": null + }, + "languages": { + "table": "languages", + "is_multiple": { + "cache_to_list": ",", + "ui_to_list": ",", + "list_to_ui": ", " + }, + "search_terms": [ + "languages", + "language" + ], + "is_editable": true, + "is_custom": false, + "category_sort": "lang_code", + "is_csp": false, + "datatype": "text", + "name": "Sprachen", + "link_column": "lang_code", + "label": "languages", + "is_category": true, + "display": {}, + "kind": "field", + "rec_index": 21, + "column": "lang_code" + }, + "series_index": { + "table": null, + "is_multiple": {}, + "search_terms": [ + "series_index" + ], + "is_editable": true, + "is_custom": false, + "rec_index": 10, + "is_csp": false, + "datatype": "float", + "name": null, + "label": "series_index", + "is_category": false, + "display": {}, + "kind": "field", + "column": null + }, + "path": { + "table": null, + "is_multiple": {}, + "search_terms": [], + "is_editable": true, + "is_custom": false, + "rec_index": 14, + "is_csp": false, + "datatype": "text", + "name": "Pfad", + "label": "path", + "is_category": false, + "display": {}, + "kind": "field", + "column": null + }, + "last_modified": { + "table": null, + "is_multiple": {}, + "search_terms": [ + "last_modified" + ], + "is_editable": true, + "is_custom": false, + "rec_index": 19, + "is_csp": false, + "datatype": "datetime", + "name": "Ge\u00e4ndert", + "label": "last_modified", + "is_category": false, + "display": { + "date_format": "dd MMM yyyy" + }, + "kind": "field", + "column": null + }, + "uuid": { + "table": null, + "is_multiple": {}, + "search_terms": [ + "uuid" + ], + "is_editable": true, + "is_custom": false, + "rec_index": 16, + "is_csp": false, + "datatype": "text", + "name": null, + "label": "uuid", + "is_category": false, + "display": {}, + "kind": "field", + "column": null + }, + "identifiers": { + "table": null, + "is_multiple": { + "cache_to_list": ",", + "ui_to_list": ",", + "list_to_ui": ", " + }, + "search_terms": [ + "identifiers", + "identifier", + "isbn" + ], + "is_editable": true, + "is_custom": false, + "rec_index": 20, + "is_csp": true, + "datatype": "text", + "name": "Kennungen", + "label": "identifiers", + "is_category": true, + "display": {}, + "kind": "field", + "column": null + }, + "formats": { + "table": null, + "is_multiple": { + "cache_to_list": ",", + "ui_to_list": ",", + "list_to_ui": ", " + }, + "search_terms": [ + "formats", + "format" + ], + "is_editable": true, + "is_custom": false, + "rec_index": 13, + "is_csp": false, + "datatype": "text", + "name": "Formate", + "label": "formats", + "is_category": true, + "display": {}, + "kind": "field", + "column": null + }, + "au_map": { + "table": null, + "is_multiple": { + "cache_to_list": ",", + "ui_to_list": null, + "list_to_ui": null + }, + "search_terms": [], + "is_editable": true, + "is_custom": false, + "rec_index": 18, + "is_csp": false, + "datatype": "text", + "name": null, + "label": "au_map", + "is_category": false, + "display": {}, + "kind": "field", + "column": null + }, + "rating": { + "table": "ratings", + "is_multiple": {}, + "search_terms": [ + "rating" + ], + "is_editable": true, + "is_custom": false, + "category_sort": "rating", + "is_csp": false, + "datatype": "rating", + "name": "Bewertung", + "link_column": "rating", + "label": "rating", + "is_category": true, + "display": {}, + "kind": "field", + "rec_index": 5, + "column": "rating" + }, + "publisher": { + "table": "publishers", + "is_multiple": {}, + "search_terms": [ + "publisher" + ], + "is_editable": true, + "is_custom": false, + "category_sort": "name", + "is_csp": false, + "datatype": "text", + "name": "Verlag", + "link_column": "publisher", + "label": "publisher", + "is_category": true, + "display": {}, + "kind": "field", + "rec_index": 9, + "column": "name" + }, + "series": { + "table": "series", + "is_multiple": {}, + "search_terms": [ + "series" + ], + "is_editable": true, + "is_custom": false, + "category_sort": "(title_sort(name))", + "is_csp": false, + "datatype": "series", + "name": "Serie", + "link_column": "series", + "label": "series", + "is_category": true, + "display": {}, + "kind": "field", + "rec_index": 8, + "column": "name" + }, + "timestamp": { + "table": null, + "is_multiple": {}, + "search_terms": [ + "date" + ], + "is_editable": true, + "is_custom": false, + "rec_index": 3, + "is_csp": false, + "datatype": "datetime", + "name": "Datum", + "label": "timestamp", + "is_category": false, + "display": { + "date_format": "dd MMM yyyy" + }, + "kind": "field", + "column": null + }, + "authors": { + "table": "authors", + "is_multiple": { + "cache_to_list": ",", + "ui_to_list": "&", + "list_to_ui": " & " + }, + "search_terms": [ + "authors", + "author" + ], + "is_editable": true, + "is_custom": false, + "category_sort": "sort", + "is_csp": false, + "datatype": "text", + "name": "Autoren", + "link_column": "author", + "label": "authors", + "is_category": true, + "display": {}, + "kind": "field", + "rec_index": 2, + "column": "name" + }, + "sort": { + "table": null, + "is_multiple": {}, + "search_terms": [ + "title_sort" + ], + "is_editable": true, + "is_custom": false, + "rec_index": 11, + "is_csp": false, + "datatype": "text", + "name": "Titelsortierung", + "label": "sort", + "is_category": false, + "display": {}, + "kind": "field", + "column": null + } + }, + "bools_are_tristate": true, + "grouped_search_terms": {} +} \ No newline at end of file diff --git a/roles/calibre-web/tasks/main.yml b/roles/calibre-web/tasks/main.yml new file mode 100644 index 000000000..b937a8e9e --- /dev/null +++ b/roles/calibre-web/tasks/main.yml @@ -0,0 +1,129 @@ +- name: Create calibre-web folders to store data and configuration files. + file: + path: "{{ item }}" + owner: "{{ calibreweb_user }}" + group: "{{ apache_user }}" + mode: 0755 + state: directory + with_items: + - "{{ calibreweb_home }}" + - "{{ calibreweb_path }}" + - "{{ calibreweb_config }}" + +## TODO: Calibre-web future release might get into pypi https://github.com/janeczku/calibre-web/issues/456 +- name: Download calibre-web github repository. + git: + repo: https://github.com/janeczku/calibre-web.git + dest: "{{ calibreweb_path }}" + update: yes + depth: 1 + version: master + when: internet_available + +## Ansible Pip Bug: Cannot use 'chdir' with 'env' https://github.com/ansible/ansible/issues/37912 (Patch landed) +#- name: Download calibre-web dependencies into vendor subdirectory. +# pip: +# requirements: "{{ calibreweb_path }}/requirements.txt" +# chdir: "{{ calibreweb_path }}" +# extra_args: '--target vendor' +# ignore_errors: True +## +# Implmenting this with Ansible command module for now. +- name: Download calibre-web dependencies into vendor subdirectory. + command: pip install --target vendor -r ./requirements.txt + args: + chdir: "{{ calibreweb_path }}" + ignore_errors: True + when: internet_available + +- name: Create calibre-web systemd service unit and httpd2 configuration. + template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + mode: "{{ item.mode }}" + owner: "{{ calibreweb_user }}" + group: "{{ apache_user }}" + with_items: + - { src: 'calibre-web.service.j2', dest: '/etc/systemd/system/calibre-web.service', mode: '0644' } + - { src: 'calibre-web.conf.j2', dest: '/etc/apache2/sites-available/calibre-web.conf', mode: '0644' } + +- name: Provision calibre-web default metadata. + copy: + src: "{{ item }}" + dest: "{{ calibreweb_home }}" + owner: "{{ calibreweb_user }}" + group: "{{ apache_user }}" + mode: 0644 + backup: yes + with_items: + - roles/calibre-web/files/metadata.db + - roles/calibre-web/files/metadata_db_prefs_backup.json + when: calibreweb_provision + +- name: Provision calibre-web with default administration settings. + copy: + src: roles/calibre-web/files/app.db + dest: "{{ calibreweb_config }}" + owner: "{{ calibreweb_user }}" + group: "{{ apache_user }}" + mode: 0644 + backup: yes + when: calibreweb_provision + +- name: Enable and reload calibre-web service. + systemd: + name: calibre-web + daemon_reload: yes + enabled: yes + state: restarted + when: calibreweb_enabled + +- name: Enable calibre-web httpd2 site + command: a2ensite calibre-web.conf + when: calibreweb_enabled + +- name: Restart Apache after enabling calibre-web httpd2 site. + command: apachectl -k graceful + when: calibreweb_enabled + +- name: Disable calibre-web service. + systemd: + name: calibre-web + daemon_reload: yes + enabled: no + state: stopped + when: not calibreweb_enabled + +- name: Disable calibre-web httpd2 site. + command: a2dissite calibre-web.conf + when: not calibreweb_enabled + +- name: Restart Apache after disabling calibre-web httpd2 site. + command: apachectl -k graceful + when: not calibreweb_enabled + +- name: Add 'calibre-web' to list of services at /etc/iiab/iiab.ini + ini_file: + dest: "{{ service_filelist }}" + section: calibre-web + option: "{{ item.option }}" + value: "{{ item.value }}" + with_items: + - option: name + value: calibre-web + - option: description + value: '"calibre-web is a web app providing a clean interface for browsing, reading and downloading eBooks."' + - option: calibreweb_url + value: "{{ calibreweb_url }}" + - option: calibreweb_path + value: "{{ calibreweb_path }}" + - option: calibreweb_home + value: "{{ calibreweb_home }}" + - option: calibreweb_port + value: "{{ calibreweb_port }}" + - option: calibreweb_database + value: "{{ calibreweb_database }}" + - option: calibreweb_enabled + value: "{{ calibreweb_enabled }}" + - option: calibreweb_provision + value: "{{ calibreweb_provision }}" diff --git a/roles/calibre-web/templates/calibre-web.conf.j2 b/roles/calibre-web/templates/calibre-web.conf.j2 new file mode 100644 index 000000000..33a95a950 --- /dev/null +++ b/roles/calibre-web/templates/calibre-web.conf.j2 @@ -0,0 +1,8 @@ + + + RequestHeader set X-SCRIPT-NAME {{ calibreweb_url }} + RequestHeader set X-SCHEME http + ProxyPass http://localhost:{{ calibreweb_port }}/ + ProxyPassReverse http://localhost:{{ calibreweb_port }}/ + + diff --git a/roles/calibre-web/templates/calibre-web.service.j2 b/roles/calibre-web/templates/calibre-web.service.j2 new file mode 100644 index 000000000..8a8c140dc --- /dev/null +++ b/roles/calibre-web/templates/calibre-web.service.j2 @@ -0,0 +1,9 @@ +Description=Calibre-Web + +[Service] +Type=simple +User={{ calibreweb_user }} +ExecStart=/usr/bin/python {{ calibreweb_exec_path }} -p {{ calibreweb_config }}/{{ calibreweb_settings_database }} + +[Install] +WantedBy=multi-user.target