Merge branch 'develop'

This commit is contained in:
2020-03-09 01:31:16 +00:00
30 changed files with 337 additions and 15351 deletions

View File

@@ -1,10 +0,0 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.0.0] - 2020-03-07
### Added
- Initial version

21
CHANGELOG.rst Normal file
View File

@@ -0,0 +1,21 @@
Changelog
==========
All notable changes to this project will be documented in this file.
This format is based on `Keep a Changelog`_
.. _Keep a Changelog: https://keepachangelog.com/en/1.0.0/
and this project adheres to `Semantic Versioning`_
.. _Semantic Versioning: https://semver.org/spec/v2.0.0.html
[1.0.0] - 2020-03-07
------------------------
Added
######
- Initial version

View File

@@ -5,4 +5,4 @@ RUN mkdir /outputs && mkdir /inputs
COPY ./setup.py /inputs/setup.py
COPY ./src /inputs/src
RUN cd /inputs && python ./setup.py install && cd /outputs
RUN cd /inputs && python ./setup.py install

View File

@@ -1,19 +1,128 @@
musicbrainzapi
===============
=============
Introduction
=============
.. image:: https://img.shields.io/readthedocs/panaetius?style=for-the-badge :target: https://panaetius.readthedocs.io/en/latest/?badge=latest
:alt: Documentation Status
.. image:: https://img.shields.io/readthedocs/panaetius?style=for-the-badge
.. image:: https://img.shields.io/github/v/tag/dtomlinson91/musicbrainzapi-cv-airelogic?style=for-the-badge
.. image:: https://img.shields.io/github/commit-activity/m/dtomlinson91/musicbrainzapi-cv-airelogic?style=for-the-badge
.. image:: https://img.shields.io/github/issues/dtomlinson91/musicbrainzapi-cv-airelogic?style=for-the-badge
.. image:: https://img.shields.io/github/license/dtomlinson91/musicbrainzapi-cv-airelogic?style=for-the-badge
.. image:: https://img.shields.io/github/languages/code-size/dtomlinson91/musicbrainzapi-cv-airelogic?style=for-the-badge
.. image:: https://img.shields.io/github/languages/top/dtomlinson91/musicbrainzapi-cv-airelogic?style=for-the-badge
.. image:: https://img.shields.io/requires/github/dtomlinson91/musicbrainzapi-cv-airelogic?style=for-the-badge
.. image:: https://img.shields.io/github/v/tag/dtomlinson91/musicbrainzapi-cv-airelogic?style=for-the-badge :alt: GitHub tag (latest by date)
Summary
========
.. image:: https://img.shields.io/github/commit-activity/m/dtomlinson91/musicbrainzapi-cv-airelogic?style=for-the-badge :alt: GitHub commit activity
Musicbrainzapi is a Python module with a CLI that allows you to search for an artist and receive summary statistics on lyrics across all albums + tracks.
.. image:: https://img.shields.io/github/issues/dtomlinson91/musicbrainzapi-cv-airelogic?style=for-the-badge :alt: GitHub issues
In addition to basic statistics the module further allows you to save details of an artist. You can save album information, the lyrics themselves and track lists.
.. image:: https://img.shields.io/github/license/dtomlinson91/musicbrainzapi-cv-airelogic?style=for-the-badge :alt: GitHubtbc
The module (currently) provides a simple CLI with some underlying assumptions:
.. image:: https://img.shields.io/github/languages/code-size/dtomlinson91/musicbrainzapi-cv-airelogic?style=for-the-badge :alt: GitHub code size in bytes
- We are interested in albums only - no singles.
- We are interested in any album where the artist is listed as a primary artist on a release. This could include compilations or joint albums with other artists.
- Where an album has been released multiple times, in different regions, we take the album with the longest track list.
.. image:: https://img.shields.io/github/languages/top/dtomlinson91/musicbrainzapi-cv-airelogic?style=for-the-badge :alt: GitHub top language
These assumptions are not configurable in the current version - but this functionality could be added to the module if needed.
.. image:: https://img.shields.io/requires/github/dtomlinson91/musicbrainzapi-cv-airelogic?style=for-the-badge :alt: Requires.io
Further information, and a brief summary of decisions taken and current caveats can be found in the documentation which is linked below.
Documentation
=============
The documentation for the module can be found at https://musicbrainzapi-cv-airelogic.readthedocs.io/en/latest/
Installation
============
You will need ``python>=3.7``. Installation to a python virtual environment is recommended.
PIP
---
Download the latest release ``.whl`` file from the `releases`_ page
.. _releases: https://github.com/dtomlinson91/musicbrainzapi-cv-airelogic/releases
In a virtual environment run:
.. code-block:: bash
pip install -U musicbrainzapi.whl
Replacing ``musicbrainzapi.whl`` with the filename you downloaded.
setup.py
--------
Clone the repo:
.. code-block:: bash
git clone https://github.com/dtomlinson91/musicbrainzapi-cv-airelogic.git
In the root of the repo in a virtual environment run:
.. code-block:: bash
python ./setup.py install
Docker
------
.. note:: Using Docker will mean you cannot view a wordcloud, as the default behaviour is to show the plot interactively which the container cannot do.
If you don't have ``python>=3.7`` installed, or would rather use Docker, you can build a Docker image and run the module using Docker.
Clone the repo:
.. code-block:: bash
git clone https://github.com/dtomlinson91/musicbrainzapi-cv-airelogic.git
In the root of the repo build the Docker image:
.. code-block:: bash
docker build . -t musicbrainzapi
No entrypoint is provided in the ``Dockerfile`` - you will have to specify the command at runtime and run the container in interactive mode:
Using Docker run
^^^^^^^^^^^^^^^^
.. code-block:: bash
docker run --rm -it --volume=$(pwd):/outputs \
musicbrainzapi:latest musicbrainzapi --path /outputs \
lyrics -a "Savage Garden" -c gb --show-summary all --save-output
Usage
=====
Once installed you can access the command running:
.. code-block:: bash
musicbrainzapi
To see all options available you can run:
.. code-block:: bash
musicbrainzapi --help
In the current release there is one command available ``lyrics``:
.. code-block:: bash
musicbrainzapi lyrics --help
License information
===================
Released under the `MIT License`_
.. _MIT License: https://github.com/dtomlinson91/musicbrainzapi-cv-airelogic/blob/master/LICENSE

48
docs/source/CLI.rst Normal file
View File

@@ -0,0 +1,48 @@
***
CLI
***
As the CLI is provided by `Click`_ , you can pass the ``--help`` option to the base command, or any subcommands, to see information on usage and all available options.
.. _Click: https://click.palletsprojects.com/en/7.x/
Full options of the CLI are provided on this page.
.. important:: The ``--path`` option should be provided to the base command. This is so the path provided can be used in all subcommands.
Quickstart
==========
If you want to see everything the module offers run the following:
.. code-block:: bash
musicbrainzapi --path . lyrics -a "savage garden" -c gb --show-summary all --wordcloud --save-output
This will search for all tracks across all albums for the artist Savage Garden.
``--show-summary all`` will show descriptive statistics for both albums and years for this artist.
``--wordcloud`` will generate a wordcloud showing the most popular words across all lyrics.
``--save-output`` will save the module's output to disk as ``.json`` files.
Outputs
=======
The following files will be saved to disk
- all_albums_lyrics_sum.json - Total number of words in a track for each album.
- year_statistics.json - Descriptive statistics by year.
- album_statistics.json - Descriptive statistics by album
- all_albums_with_tracks.json - Track titles for each album.
- all_albums_with_lyrics.json - Lyrics for each track for each album.
- all_albums_lyrics_count.json - Shows a frequency count of each word in every track.
CLI Documentation
=================
.. click:: musicbrainzapi.cli.cli:cli
:prog: musicbrainzapi
:show-nested:

View File

@@ -1,87 +1,5 @@
@import url("css/theme.css");
.modname {
font-size: 0.8em;
opacity: 0.4;
}
.modname::before {
content: '- ';
}
.title {
font-weight: bold;
font-size: 1.2em;
background-color: #eee;
display: block;
padding: 1px 5px;
border-left: 2px solid #ddd;
}
/*colour of the text in the toc*/
.wy-menu-vertical header, .wy-menu-vertical p.caption{
color: #b26d46;;
}
/*colour of the top left header*/
.wy-side-nav-search{
background-color: #31465a;
}
/*colours of the class definitions*/
.rst-content dl:not(.docutils) dt{
background: #e2d7d1;
color: #0b2852;
border-top: solid 3px #31465a;
}
/*colour of the link in the class defintions*/
.rst-content .viewcode-link, .rst-content .viewcode-back{
color: #4b674a;
}
/*colour of the function definitions*/
.rst-content dl:not(.docutils) dl dt{
border-left: solid 3px #31465a;
background: #e2d7d1;
color: #0b2852;
}
/*colour of the link in the function definitions*/
.rst-content .viewcode-link, .rst-content .viewcode-back{
color: #4b674a;
}
/*edit the width of the body*/
.wy-nav-content{
max-width: 1200px;
}
/*code example blocks*/
.rst-content pre.literal-block, .rst-content div[class^="highlight"] pre, .rst-content .linenodiv pre{
background: #b4bec8;
color: black;
/*border-style: solid;*/
/*border-width: thin;*/
}
/*colour of inline code blocks using ``*/
.rst-content tt.literal, .rst-content tt.literal, .rst-content code.literal{
color: #b26d46;
}
/* Change code blocks font and bump up font size slightly (normally 12px)*/
.rst-content pre.literal-block, .rst-content div[class^="highlight"] pre, .rst-content .linenodiv pre {
font-family: 'Inconsolata', monospace !important;
font-size: 14px !important;
white-space: pre-wrap;
}
/* Change code descriptions and literal blocks (inline code via ``) to match the normal font size being used in the sphinx_RTD_theme text (normally 14px)*/
.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) tt.descclassname,.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) code.descname,.rst-content dl:not(.docutils) tt.descclassname,.rst-content dl:not(.docutils) code.descclassname, code.docutils {
font-family: 'Inconsolata', monospace !important;
font-size: 14px !important;
}
/*variables text*/
dl.class > dd > table.docutils.field-list tbody tr.field-odd.field th.field-name::before{
content: '(Class Attributes) ';
.highlight {
background: white !important
}

View File

@@ -1,20 +1 @@
Changelog
==========
All notable changes to this project will be documented in this file.
The format is based on `Keep a Changelog`_
.. _https://keepachangelog.com/en/1.0.0/
and this project adheres to `Semantic Versioning`_
.. _https://semver.org/spec/v2.0.0.html
[1.0.0] - 2020-03-07
------------------------
Added
######
- Initial version
.. include:: ../../CHANGELOG.rst

View File

@@ -39,6 +39,8 @@ extensions = [
'sphinx.ext.napoleon',
'sphinx.ext.todo',
'sphinx_click.ext',
'sphinx.ext.intersphinx',
'sphinx.ext.autosectionlabel'
]
# -- Napoleon Settings -----------------------------------------------------
@@ -60,7 +62,7 @@ autodoc_member_order = 'bysource'
templates_path = ['_templates']
# The master toctree document.
master_doc = 'introduction'
master_doc = 'index'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
@@ -82,11 +84,12 @@ html_theme = "sphinx_rtd_theme"
html_theme = "sphinx_rtd_theme"
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
html_static_path = ['_static']
# html_context = {'css_files': ['_static/custom.css']}
html_context = {'css_files': ['_static/custom.css']}
html_theme_options = {
'collapse_navigation': True,
'display_version': True,
'prev_next_buttons_location': 'both',
'navigation_depth': -1,
#'navigation_depth': 3,
}

View File

@@ -1,3 +1,29 @@
*****************
Table of Contents
=================
.. include:: toc.rst
*****************
.. toctree::
:maxdepth: 2
:caption: Contents
introduction
CLI
changelog
.. toctree::
:caption: API
:maxdepth: 2
modules/modules
.. toctree::
:caption: Table of Contents
self
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View File

@@ -1 +1 @@
.. include:: ../../toc.rst
.. include:: ../../README.rst

View File

@@ -0,0 +1,7 @@
musicbrainzapi
--------------
.. toctree::
:maxdepth: 3
musicbrainzapi

View File

@@ -1,10 +0,0 @@
.. include:: ../global.rst
musicbrainzapi.api.authenticate :modname:`musicbrainzapi.api.authenticate module`
------------------------------------------------------------------------------------------
.. automodule:: musicbrainzapi.api.authenticate
:members:
:undoc-members:
:show-inheritance:
:private-members:

View File

@@ -1,10 +0,0 @@
.. include:: ../global.rst
musicbrainzapi.api.lyrics.builder :modname:`musicbrainzapi.api.lyrics.builder`
-------------------------------------------------------------------------------
.. automodule:: musicbrainzapi.api.lyrics.builder
:members:
:undoc-members:
:show-inheritance:
:private-members:

View File

@@ -1,10 +0,0 @@
.. include:: ../global.rst
musicbrainzapi.api.lyrics.concrete_builder :modname:`musicbrainzapi.api.lyrics.concrete_builder`
-------------------------------------------------------------------------------------------------
.. automodule:: musicbrainzapi.api.lyrics.concrete_builder
:members:
:undoc-members:
:show-inheritance:
:private-members:

View File

@@ -1,10 +0,0 @@
.. include:: ../global.rst
musicbrainzapi.api.lyrics.director :modname:`musicbrainzapi.api.lyrics.director`
----------------------------------------------------------------------------------
.. automodule:: musicbrainzapi.api.lyrics.director
:members:
:undoc-members:
:show-inheritance:
:private-members:

View File

@@ -1,7 +1,5 @@
.. include:: ../global.rst
musicbrainzapi.api.lyrics :modname:`musicbrainzapi.api.lyrics`
--------------------------------------------------------------------------
musicbrainzapi.api.lyrics package
=================================
.. automodule:: musicbrainzapi.api.lyrics
:members:
@@ -9,8 +7,32 @@ musicbrainzapi.api.lyrics :modname:`musicbrainzapi.api.lyrics`
:show-inheritance:
:private-members:
.. toctree::
Submodules
----------
musicbrainzapi.api.lyrics.builder
musicbrainzapi.api.lyrics.concrete_builder
musicbrainzapi.api.lyrics.director
musicbrainzapi.api.lyrics.builder module
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. automodule:: musicbrainzapi.api.lyrics.builder
:members:
:undoc-members:
:show-inheritance:
:private-members:
musicbrainzapi.api.lyrics.concrete_builder module
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. automodule:: musicbrainzapi.api.lyrics.concrete_builder
:members:
:undoc-members:
:show-inheritance:
:private-members:
musicbrainzapi.api.lyrics.director module
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. automodule:: musicbrainzapi.api.lyrics.director
:members:
:undoc-members:
:show-inheritance:
:private-members:

View File

@@ -1,7 +1,5 @@
.. include:: ../global.rst
musicbrainzapi.api :modname:`musicbrainzapi.api`
--------------------------------------------------------------------------
musicbrainzapi.api package
===========================
.. automodule:: musicbrainzapi.api
:members:
@@ -9,11 +7,22 @@ musicbrainzapi.api :modname:`musicbrainzapi.api`
:show-inheritance:
:private-members:
Subpackages
-----------
.. toctree::
:maxdepth: 1
musicbrainzapi.api.lyrics
.. toctree::
Submodules
----------
musicbrainzapi.api.authenticate
musicbrainzapi.api.authenticate module
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. automodule:: musicbrainzapi.api.authenticate
:members:
:undoc-members:
:show-inheritance:
:private-members:

View File

@@ -1,10 +0,0 @@
.. include:: ../global.rst
musicbrainzapi.cli.cli :modname:`musicbrainzapi.cli.cli`
--------------------------------------------------------------------------
.. automodule:: musicbrainzapi.cli.cli
:members:
:undoc-members:
:show-inheritance:
:private-members:

View File

@@ -1,16 +0,0 @@
.. include:: ../global.rst
musicbrainzapi.cli.commands.cmd_lyrics :modname:`musicbrainzapi.cli.commands.cmd_lyrics`
------------------------------------------------------------------------------------------
.. automodule:: musicbrainzapi.cli.commands.cmd_lyrics
:members:
:undoc-members:
:show-inheritance:
:private-members:
lyrics subcommand. Use with...
.. click:: musicbrainzapi.cli.cli:cli
:prog: musicbrainzapi
:show-nested:

View File

@@ -1,14 +0,0 @@
.. include:: ../global.rst
musicbrainzapi.cli.commands :modname:`musicbrainzapi.cli.commands`
--------------------------------------------------------------------------
.. automodule:: musicbrainzapi.cli.commands
:members:
:undoc-members:
:show-inheritance:
:private-members:
.. toctree::
musicbrainzapi.cli.commands.cmd_lyrics

View File

@@ -1,18 +0,0 @@
.. include:: ../global.rst
musicbrainzapi.cli :modname:`musicbrainzapi.cli`
--------------------------------------------------------------------------
.. automodule:: musicbrainzapi.cli
:members:
:undoc-members:
:show-inheritance:
:private-members:
.. toctree::
musicbrainzapi.cli.commands
.. toctree::
musicbrainzapi.cli.cli

View File

@@ -1,7 +1,5 @@
.. include:: ../global.rst
musicbrainzapi :modname:`musicbrainzapi`
-----------------------------------------
musicbrainzapi
===============
.. automodule:: musicbrainzapi
:members:
@@ -9,4 +7,13 @@ musicbrainzapi :modname:`musicbrainzapi`
:show-inheritance:
:private-members:
Main module text
Subpackages
-----------
.. toctree::
:maxdepth: 1
musicbrainzapi.api
musicbrainzapi.wordcloud

View File

@@ -1,10 +0,0 @@
.. include:: ../global.rst
musicbrainzapi.wordcloud.resources :modname:`musicbrainzapi.wordcloud.resources`
---------------------------------------------------------------------------------
.. automodule:: musicbrainzapi.wordcloud.resources
:members:
:undoc-members:
:show-inheritance:
:private-members:

View File

@@ -1,14 +1,9 @@
.. include:: ../global.rst
musicbrainzapi.wordcloud :modname:`musicbrainzapi.wordcloud`
--------------------------------------------------------------------------
********************************
musicbrainzapi.wordcloud package
********************************
.. automodule:: musicbrainzapi.wordcloud
:members:
:undoc-members:
:show-inheritance:
:private-members:
.. toctree::
musicbrainzapi.wordcloud.resources

View File

@@ -1,23 +0,0 @@
.. toctree::
:maxdepth: 1
:caption: Overview
:titlesonly:
introduction
changelog
.. toctree::
:maxdepth: 4
:caption: Modules
:titlesonly:
modules/musicbrainzapi.rst
.. toctree::
:maxdepth: 4
:caption: Submodules
:titlesonly:
modules/musicbrainzapi.api.rst
modules/musicbrainzapi.cli.rst
modules/musicbrainzapi.wordcloud.rst

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
"""
musicbrainzapi: A CLI lyrics searcher
=====================================
This module was written by dtomlinson <dtomlinson@panaetius.co.uk> for Aire Logic
"""

View File

@@ -9,12 +9,27 @@ from musicbrainzapi.api.lyrics import Lyrics
class LyricsClickDirector:
"""Director for Lyrics builder.
"""
"""Director for Lyrics builder."""
def __init__(self) -> None:
self._builder = None
@staticmethod
def _get_product(builder_inst: LyricsBuilder) -> Lyrics:
"""Returns the constructed Lyrics object
Parameters
----------
builder_inst : LyricsBuilder
Builder class for Lyrics object
Returns
-------
Lyrics
Lyrics object
"""
return builder_inst._product
@property
def builder(self) -> LyricsBuilder:
return self._builder
@@ -156,19 +171,3 @@ class LyricsClickDirector:
self.builder._product.show_summary()
self.builder._product.show_summary_statistics(group_by='year')
return self
@staticmethod
def _get_product(builder_inst: LyricsBuilder) -> Lyrics:
"""Returns the constructed Lyrics object
Parameters
----------
builder_inst : LyricsBuilder
Builder class for Lyrics object
Returns
-------
Lyrics
Lyrics object
"""
return builder_inst._product

View File

@@ -42,7 +42,7 @@ class ComplexCLI(click.MultiCommand):
type=click.Path(
exists=True, file_okay=False, resolve_path=True, writable=True
),
help='Path to save results.',
help='Local path to save any output files.',
default=os.getcwd()
)
# @click.option('-v', '--verbose', is_flag=True, help='Enables verbose mode.')
@@ -53,7 +53,7 @@ class ComplexCLI(click.MultiCommand):
)
@pass_environment
def cli(ctx, path):
"""A complex command line interface."""
"""Base command for the musicbrainzapi program."""
# ctx.verbose = verbose
if path is not None:
click.echo(f'Path set to {os.path.expanduser(path)}')

View File

@@ -24,7 +24,7 @@ from musicbrainzapi.api.lyrics.director import LyricsClickDirector
@click.option(
'--wordcloud',
required=False,
help='Generate a wordcloud from lyrics.',
help='Generates a wordcloud from lyrics.',
is_flag=True,
default=False,
)
@@ -41,7 +41,7 @@ from musicbrainzapi.api.lyrics.director import LyricsClickDirector
required=False,
multiple=False,
type=str,
help='ISO A-2 Country code (https://en.wikipedia.org/wiki/ISO_3166-1_alpha'
help='Filter artist by country. This is optional but can narrow down a search if many artists share the same or similar names. Country must be a ISO A-2 Country code (https://en.wikipedia.org/wiki/ISO_3166-1_alpha'
'-2) Example: GB',
)
@click.option(
@@ -63,7 +63,7 @@ def lyrics(
wordcloud: bool,
save_output: bool,
) -> None:
"""Search for lyrics statistics of an Artist/Group.
"""Search for lyrics statistics of an Artist/Group. Optionally save the results to disk, and show a wordcloud. Descriptive statistics can be shown in addition to the final average.
"""
director = LyricsClickDirector()
builder = LyricsBuilder()
@@ -78,7 +78,6 @@ def lyrics(
director._query_for_data()
director._get_lyrics()
director._calculate_basic_statistics()
if show_summary is not None:
director._calculate_descriptive_statistics()
# Get the Lyrics object