Skip to content

Commit

Permalink
Merge pull request #36 from pganssle/update_docs
Browse files Browse the repository at this point in the history
Redo the README.rst
  • Loading branch information
pganssle authored Nov 27, 2022
2 parents c2ba9a2 + c759018 commit 0741388
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 27 deletions.
6 changes: 6 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
include LICENSE *.rst *.toml *.yml *.yaml *.ini
global-exclude *.pyc
global-exclude *.pyo
global-exclude *.pyd
recursive-include licenses *
graft .github

Expand All @@ -9,9 +12,12 @@ recursive-include src *.pyi
# Tests
include tox.ini
recursive-include tests *.py
recursive-include tests/data *.*

# Documentation
recursive-include docs *.png
recursive-include docs *.jpg
recursive-include docs *.jpeg
recursive-include docs *.svg
recursive-include docs *.py
recursive-include docs *.rst
Expand Down
84 changes: 58 additions & 26 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,39 +1,71 @@
``audio-feeder`` is a Flask-based web-app that hosts your audiobooks (or other audio content) as RSS feeds compatible with podcatchers.

Installation
============
Currently, there is no installer that will install things "correctly", so you should look into the proper way to deploy this web app. In 'development mode', you can install it using these steps:
Features
========

.. image:: docs/images/screenshots/list_entry_p0.jpg
:width: 800px
:alt: The main list interface

The main interface lists all your audiobooks once the database is updated (either by using ``audio-feeder update`` or by visiting the ``/update`` url. The default interface should also work well on mobile:

.. image:: docs/images/screenshots/list_mobile.jpg
:width: 400px
:alt: The mobile list interface

Rendered feeds
**************
For each entry, ``audio-feeder`` can also generate "rendered" feeds, depending on what metadata is available:

- Single file: This feed consists of a single file; if the original directory contains multiple files, they will be merged together using ``ffmpeg``. If chapter information is not available in the original files, each file will be considered a separate "chapter".

- Chapters: This feed has one file per chapter; it is only available if explicit chapter metadata is available in the file (e.g. in an ``m4b`` file, or using Overdrive MediaMarkers).

- Segmented: This is a feed that splits up and recombines files in such a way as to create files that are ~1 hour long (preferring longer files to shorter files). Files will only be split up along chapter boundaries, but they can be combined from files without chapter information. This mode is available if the original entry has more than one file, or if it has chapter information (or both).

QR Codes
********

Each feed has an associated QR code, so that you can easily browse the list from a computer, but scan the individual feeds from your phone. In the default front-end, QR codes are displayed via modal pop-ups:


.. image:: docs/images/screenshots/list_p0_qr.jpg
:width: 800px
:alt: Demonstration of the QR code mobile.

- Download the source code, ``cd`` into the extracted directory.
- In your virtualenv, run ``pip install .``
- Run ``audio-feeder install`` - this should create a basic ``{{CONFIG}}`` directory in ``/etc/audio_feeder`` or ``~/.config/audio_feeder``
- Modify the configuration files in ``{{CONFIG}}/config.yml`` as desired.
- Modify the templates and CSS files as desired.
- Create a symbolic link to your audiobooks directory under ``{{CONFIG}}/static/media/`` (e.g. ``~/.config/audio_feeder/static/media/audiobooks``) - we'll call this ``{{AUDIOBOOKS}}``.
- Run ``audio-feeder update {{AUDIOBOOKS}}`` to pull metadata from Google Books (for a large number of audiobooks, you may need to get a `Google API key <https://developers.google.com/maps/documentation/javascript/get-api-key>`_, which should be entered in your ``config.yml`` page under ``google_api_key``).
- Run the server with ``audio-feeder run``
- Visit your page at ``localhost:9090`` (default value). *Note:* You should specify your computer's specific IP address if you are planning on serving your audiobooks directly to a phone or device over wifi.

If you add more audiobooks to your audiobook path, run ``audio-feeder update {{AUDIOBOOKS}}`` again and restart the application.
Display options
***************

The user can customize things like the sort order and the number of entries per page:

.. image:: docs/images/screenshots/settings_pulldown.jpg
:width: 800px
:alt: Demonstration of the settings pulldown


Installation and use
====================

Probably the easiest way to deploy this is via docker. For your convenience, I have created `a repository with a docker-compose configuration <https://github.com/pganssle/audio_feeder_docker>`_. It uses ``nginx`` to serve static media files, and ``gunicorn`` to deploy the application.

If you want to test it out locally, you can use ``tox -e start_server`` to run a test server. This will create a temporary server directory at ``/tmp/audio_feeder_server``, and you can play around with, and you can mount your audiobook directory at ``/tmp/audio_feeder_server/static/media`` to have it work on your own audiobooks (bind mount, symlink or hard link should work just fine).

In a ``virtualenv`` with ``audio-feeder`` installed, you can run ``audio-feeder --help`` to see the various command line tools bundled with the application.


Note
=====
Version 0.1.0 is a very rough initial cut, and if you're looking for something easy to use out of the box, you may have to wait a bit longer. The odd choice of using YAML files as a pseudo-database is *not* intended to be permanent, and these will be replaced with a proper database soon.

While the state of this is getting much closer to something production-ready, I am emphatically *not* a front-end developer, and I don't have extremely high confidence in the security of this project. Use at your own risk (and if you do come up with some security and/or usability improvements, please do send a PR).

This is only tested on Linux, but it may also work on other platforms.

Dependencies
============
The following dependencies are required for installation, and will be installed if missing when installed through `pip`:

- ``Flask``
- ``ruamel.yaml``
- ``qrcode``
- ``Pillow``
- ``requests``
- ``jinja2``
- ``click``
- ``progressbar2``

To run the test suite, ``pytest`` is also required.

In addition to the python dependencies specified in ``pyproject.toml``, this project also requires installing ``ffmpeg`` with at least the ``aac`` codec, and the tests also require the ``libmp3lame`` codec.


License
=======
Expand Down
Binary file added docs/images/screenshots/list_entry_p0.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/screenshots/list_mobile.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/screenshots/list_p0_qr.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/screenshots/settings_pulldown.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ authors = [{name = "Paul Ganssle"}]
description = """
audio-feeder provides a server that serves your audiobooks and other audio
content as RSS feeds, with rich metadata, and provides a web frontent for navigation."""
readme = "README.rst"
license = {file = "LICENSE"}
requires-python = ">= 3.9"
dependencies = [
Expand Down Expand Up @@ -39,6 +38,7 @@ classifiers = [
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
]
dynamic = ["version"]

Expand Down
47 changes: 47 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import itertools
import pathlib
import re
import typing

from setuptools import setup

ROOT: typing.Final[pathlib.Path] = pathlib.Path(__file__).parent


def strip_images(rst_file: pathlib.Path) -> str:
pattern = re.compile(r"(?P<whitespace>\s*).. image:: (?P<path>.*)$")
text = rst_file.read_text()
lines = text.split("\n")
lines_out = []
in_block = False
indent = None
for line in lines:
if pattern.match(line):
in_block = True
continue
else:
if in_block:
prefix_m = re.match("\s+", line)
if not prefix_m or (
(indent is not None) and indent != line[slice(*prefix_m.span())]
):
in_block = False
indent = None
else:
if indent is None:
indent = line[slice(*prefix_m.span())]
continue

lines_out.append(line)

lines_with_newlines = itertools.groupby(lines_out, key=bool)
lines_with_collapsed_newlines = (
grp if has_contents else ("",) for has_contents, grp in lines_with_newlines
)
return "\n".join(itertools.chain.from_iterable(lines_with_collapsed_newlines))


setup(
long_description=strip_images(ROOT / "README.rst"),
long_description_content_type="text/x-rst",
)

0 comments on commit 0741388

Please sign in to comment.