diff --git a/docs/api.rst b/docs/api.rst new file mode 100644 index 0000000..6224aeb --- /dev/null +++ b/docs/api.rst @@ -0,0 +1,16 @@ +API +=== + +.. module:: youtube_bz + +YouTube API +----------- + +.. autoclass:: youtube_bz.api.youtube.Client + :members: + +MusicBrainz API +--------------- + +.. autoclass:: youtube_bz.api.musicbrainz.Client + :members: \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py index 64dd18b..0a994b8 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -10,9 +10,10 @@ # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # -# import os -# import sys -# sys.path.insert(0, os.path.abspath('.')) +import os +import sys + +sys.path.insert(0, os.path.abspath("..")) # -- Project information ----------------------------------------------------- @@ -30,7 +31,7 @@ # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = [] +extensions = ["sphinx.ext.autodoc"] # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] @@ -46,10 +47,9 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = "alabaster" -html_theme_options = {"nosidebar": True} +html_theme = "sphinx_rtd_theme" # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ["_static"] +html_static_path = [] diff --git a/docs/index.rst b/docs/index.rst index 231c7ab..16dbb0e 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -4,78 +4,27 @@ YouTubeBrainz YoutubeBrainz allows you to find and download Youtube videos associated to an album on MusicBrainz. -Installation -============ -Requirements ------------- +The User Guide +-------------- -Before you use YouTubeBrainz you need to get yourself ``ffmpeg`` installed. -In Debian-like systems you can get it like this: +.. toctree:: + :maxdepth: 2 -.. code-block:: console - - $ sudo apt install ffmpeg + user/install + user/quickstart +API Documentation +----------------- -From PyPi ---------- +.. toctree:: + :maxdepth: 2 -Then you can get YoutubeBrainz from PyPi repository directly: + api -.. code-block:: console +Indices and tables +================== - $ pip install youtube-bz - -From source ------------ - -You can also install YouTubeBrainz from sources. - -First, get a copy of the repository: - -.. code-block:: console - - $ https://github.com/Flowrey/youtube-bz.git - -And then, you can install it with pip: - -.. code-block:: console - - $ cd youtube-bz - $ pip install -e . - - -Getting started -=============== - -To get you started we will fetch an album from a MusicBrainzID. - -Find a MBID ------------ - -In this exemple we will get the album "Hybrid Theory" from "Linkin Park". - -YouTubeBrainz need to use the MIBD of a release to download it. - -For instance in the following URL: - -.. code-block:: text - - https://musicbrainz.org/release/5fc6445c-05ce-34e7-ab31-63bf7d3a9f24 - -the MBID is ``5fc6445c-05ce-34e7-ab31-63bf7d3a9f24``. - -Now that we have the MBID we can download the release thanks to YouTubeBrainz. - -Download the Release --------------------- - -Downloading the release is really straight forward: - -.. code-block:: console - - $ youtube-bz download 5fc6445c-05ce-34e7-ab31-63bf7d3a9f24 - -Your download should start now and you will get the YouTube videos -associated to the MBID album. +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` \ No newline at end of file diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..07084c4 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,2 @@ +sphinx +sphinx-rtd-theme \ No newline at end of file diff --git a/docs/user/install.rst b/docs/user/install.rst new file mode 100644 index 0000000..666d000 --- /dev/null +++ b/docs/user/install.rst @@ -0,0 +1,11 @@ +Installation +============ + +From PyPi +--------- + +You can get YoutubeBrainz from PyPi repository directly: + +.. code-block:: console + + $ pip install youtube-bz diff --git a/docs/user/quickstart.rst b/docs/user/quickstart.rst new file mode 100644 index 0000000..a76c2c8 --- /dev/null +++ b/docs/user/quickstart.rst @@ -0,0 +1,33 @@ +Getting started +=============== + +To get you started we will fetch an album from a MusicBrainzID. + +Find a MBID +----------- + +In this exemple we will get the album "Hybrid Theory" from "Linkin Park". + +YouTubeBrainz need to use the MIBD of a release to download it. + +For instance in the following URL: + +.. code-block:: text + + https://musicbrainz.org/release/5fc6445c-05ce-34e7-ab31-63bf7d3a9f24 + +the MBID is ``5fc6445c-05ce-34e7-ab31-63bf7d3a9f24``. + +Now that we have the MBID we can download the release thanks to YouTubeBrainz. + +Download the Release +-------------------- + +Downloading the release is really straight forward: + +.. code-block:: console + + $ youtube-bz download 5fc6445c-05ce-34e7-ab31-63bf7d3a9f24 + +Your download should start now and you will get the YouTube videos +associated to the MBID album. \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index 4506f24..9a4596c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -408,13 +408,13 @@ toml = ["tomli"] [[package]] name = "docutils" -version = "0.20.1" +version = "0.18.1" description = "Docutils -- Python Documentation Utilities" optional = false -python-versions = ">=3.7" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ - {file = "docutils-0.20.1-py3-none-any.whl", hash = "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6"}, - {file = "docutils-0.20.1.tar.gz", hash = "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b"}, + {file = "docutils-0.18.1-py2.py3-none-any.whl", hash = "sha256:23010f129180089fbcd3bc08cfefccb3b890b0050e1ca00c867036e9d161b98c"}, + {file = "docutils-0.18.1.tar.gz", hash = "sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06"}, ] [[package]] @@ -942,6 +942,25 @@ docs = ["sphinxcontrib-websupport"] lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-simplify", "isort", "mypy (>=0.990)", "ruff", "sphinx-lint", "types-requests"] test = ["cython (>=3.0)", "filelock", "html5lib", "pytest (>=4.6)", "setuptools (>=67.0)"] +[[package]] +name = "sphinx-rtd-theme" +version = "1.3.0" +description = "Read the Docs theme for Sphinx" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "sphinx_rtd_theme-1.3.0-py2.py3-none-any.whl", hash = "sha256:46ddef89cc2416a81ecfbeaceab1881948c014b1b6e4450b815311a89fb977b0"}, + {file = "sphinx_rtd_theme-1.3.0.tar.gz", hash = "sha256:590b030c7abb9cf038ec053b95e5380b5c70d61591eb0b552063fbe7c41f0931"}, +] + +[package.dependencies] +docutils = "<0.19" +sphinx = ">=1.6,<8" +sphinxcontrib-jquery = ">=4,<5" + +[package.extras] +dev = ["bump2version", "sphinxcontrib-httpdomain", "transifex-client", "wheel"] + [[package]] name = "sphinxcontrib-applehelp" version = "1.0.7" @@ -996,6 +1015,20 @@ Sphinx = ">=5" lint = ["docutils-stubs", "flake8", "mypy"] test = ["html5lib", "pytest"] +[[package]] +name = "sphinxcontrib-jquery" +version = "4.1" +description = "Extension to include jQuery on newer Sphinx releases" +optional = false +python-versions = ">=2.7" +files = [ + {file = "sphinxcontrib-jquery-4.1.tar.gz", hash = "sha256:1620739f04e36a2c779f1a131a2dfd49b2fd07351bf1968ced074365933abc7a"}, + {file = "sphinxcontrib_jquery-4.1-py2.py3-none-any.whl", hash = "sha256:f936030d7d0147dd026a4f2b5a57343d233f1fc7b363f68b3d4f1cb0993878ae"}, +] + +[package.dependencies] +Sphinx = ">=1.8" + [[package]] name = "sphinxcontrib-jsmath" version = "1.0.1" @@ -1190,4 +1223,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "81affe04cf8b1243bd052c0c579e75c9d58d3414419937b1281be6e978382af9" +content-hash = "e158d6418d6e42de697545d473340e382fcf826bbf3d6e06e71dac9e36847663" diff --git a/pyproject.toml b/pyproject.toml index 792875a..c8344e3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,13 @@ isort = "^5.12.0" pytest = "^7.4.0" pytest-asyncio = "^0.21.1" pytest-cov = "^4.1.0" + +[tool.poetry.group.docs] +optional = true + +[tool.poetry.group.docs.dependencies] sphinx = "^7.0.1" +sphinx-rtd-theme = "^1.3.0" [build-system] requires = ["poetry-core"] diff --git a/youtube_bz/api/musicbrainz/api.py b/youtube_bz/api/musicbrainz/api.py index 632761a..75398a2 100644 --- a/youtube_bz/api/musicbrainz/api.py +++ b/youtube_bz/api/musicbrainz/api.py @@ -4,15 +4,21 @@ class ArtistCredit(TypedDict): + """A MusicBrainz ArtistCredit.""" + name: str class Track(TypedDict): + """A MusicBrainz Track.""" + title: str position: int class Media(TypedDict): + """A MusicBrainz Media.""" + tracks: list[Track] @@ -22,11 +28,13 @@ class Media(TypedDict): class Client: - _host: str + """MusicBrainz API client.""" + _session: ClientSession @classmethod async def new(cls, host: str = "https://musicbrainz.org"): + """Create a new MusicBrainz client.""" self = cls() self._session = ClientSession( base_url=host, @@ -44,7 +52,9 @@ async def _lookup(self, entity_type: str, mbid: str) -> dict[str, Any]: return await response.json() async def lookup_release(self, mbid: str) -> Release: + """Lookup for a release with it's MBID.""" return cast(Release, await self._lookup("release", mbid)) async def close(self) -> None: + """Close client session.""" await self._session.close() diff --git a/youtube_bz/api/youtube/api.py b/youtube_bz/api/youtube/api.py index 957c5a8..742e3d7 100644 --- a/youtube_bz/api/youtube/api.py +++ b/youtube_bz/api/youtube/api.py @@ -8,11 +8,13 @@ class Client: - _host: str + """YouTube API client.""" + _session: ClientSession @classmethod async def new(cls, host: str = "https://www.youtube.com"): + """Create a new YouTube client.""" self = cls() self._session = ClientSession(base_url=host, raise_for_status=True) @@ -26,6 +28,7 @@ async def get_search_results(self, search_query: str) -> str: return await response.text() async def close(self) -> None: + """Close client session.""" await self._session.close()