updating documentation

This commit is contained in:
2020-03-08 01:22:06 +00:00
parent a431ce60b7
commit 383aa2b77b
12 changed files with 15164 additions and 155 deletions

View File

@@ -0,0 +1,13 @@
musicbrainzapi
===============
.. 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/github/v/tag/dtomlinson91/musicbrainzapi-cv-airelogic?style=for-the-badge :alt: GitHub tag (latest by date)
.. image:: https://img.shields.io/github/commit-activity/m/dtomlinson91/musicbrainzapi-cv-airelogic?style=for-the-badge :alt: GitHub commit activity
.. image:: https://img.shields.io/github/issues/dtomlinson91/musicbrainzapi-cv-airelogic?style=for-the-badge :alt: GitHub issues
.. image:: https://img.shields.io/github/license/dtomlinson91/musicbrainzapi-cv-airelogic?style=for-the-badge :alt: GitHubtbc

View File

@@ -60,7 +60,7 @@ autodoc_member_order = 'bysource'
templates_path = ['_templates']
# The master toctree document.
master_doc = 'index'
master_doc = 'introduction'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.

View File

@@ -1,13 +1 @@
musicbrainzapi
===============
.. 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/github/v/tag/dtomlinson91/musicbrainzapi-cv-airelogic?style=for-the-badge :alt: GitHub tag (latest by date)
.. image:: https://img.shields.io/github/commit-activity/m/dtomlinson91/musicbrainzapi-cv-airelogic?style=for-the-badge :alt: GitHub commit activity
.. image:: https://img.shields.io/github/issues/dtomlinson91/musicbrainzapi-cv-airelogic?style=for-the-badge :alt: GitHub issues
.. image:: https://img.shields.io/github/license/dtomlinson91/musicbrainzapi-cv-airelogic?style=for-the-badge :alt: GitHubtbc
.. include:: ../../toc.rst

15024
lyrics_count.json Normal file

File diff suppressed because it is too large Load Diff

4
poetry.lock generated
View File

@@ -112,7 +112,7 @@ python-versions = "*"
version = "3.0.4"
[[package]]
category = "dev"
category = "main"
description = "Composable command line interface toolkit"
name = "click"
optional = false
@@ -784,7 +784,7 @@ docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"]
testing = ["jaraco.itertools", "func-timeout"]
[metadata]
content-hash = "1c24bb1bd4e00a1d1278ef7adde7fa1629ac0e02ed5ecc4e79a1f753365372fc"
content-hash = "c39a5b0162f2941acee38685feb99d3b417a277744f8b74339775ee621d81872"
python-versions = "^3.7"
[metadata.files]

View File

@@ -18,6 +18,7 @@ numpy = "^1.18.1"
beautifultable = "^0.8.0"
wordcloud = "^1.6.0"
multidict = "^4.7.5"
click = "^7.0"
[tool.poetry.dev-dependencies]
pytest = "^5.2"

View File

@@ -19,6 +19,7 @@ package_data = \
install_requires = \
['addict>=2.2.1,<3.0.0',
'beautifultable>=0.8.0,<0.9.0',
'click>=7.0,<8.0',
'multidict>=4.7.5,<5.0.0',
'musicbrainzngs>=0.7.1,<0.8.0',
'numpy>=1.18.1,<2.0.0',

View File

@@ -3,7 +3,6 @@ from collections import Counter
import html
import json
import math
import os
import string
from typing import Union, Dict
@@ -88,8 +87,110 @@ class LyricsBuilder(LyricsConcreteBuilder):
@staticmethod
def set_useragent() -> None:
"""Sets the useragent for the Musicbrainz api.
"""
authenticate.set_useragent()
@staticmethod
def construct_lyrics_url(artist: str, song: str) -> str:
"""Builds the URL for the lyrics api.
Parameters
----------
artist : str
Artist
song : str
Track title
Returns
-------
str
URL for lyrics from the lyrics api.
"""
lyrics_api_base = 'https://api.lyrics.ovh/v1'
lyrics_api_url = html.escape(f'{lyrics_api_base}/{artist}/{song}')
return lyrics_api_url
@staticmethod
def request_lyrics_from_url(url: str) -> str:
"""Gets lyrics from the lyrics api.
Parameters
----------
url : str
URL of the track for the lyrics api.
Returns
-------
str
Lyrics of the trakc
"""
resp = requests.get(url)
# No lyrics for a song will return a key of 'error', we pass on this.
try:
lyrics = LyricsBuilder.strip_punctuation(resp.json()['lyrics'])
return lyrics
except (KeyError, json.decoder.JSONDecodeError):
return
@staticmethod
def strip_punctuation(word: str) -> str:
"""Removes punctuation from lyrics.
Parameters
----------
word : str
Word to remove punctuation from.
Returns
-------
str
Same word without any punctuation.
"""
_strip = word.translate(str.maketrans('', '', string.punctuation))
return _strip
@staticmethod
def get_descriptive_statistics(nums: list) -> Dict[str, int]:
"""Calculates descriptive statistics.
Parameters
----------
nums : list
A list containing total number of words from a track.
Returns
-------
Dict[str, int]
Dictionary of statistic and value.
"""
if len(nums) == 0:
return
avg = math.ceil(np.mean(nums))
median = math.ceil(np.median(nums))
std = math.ceil(np.std(nums))
max = math.ceil(np.max(nums))
min = math.ceil(np.min(nums))
p_10 = math.ceil(np.percentile(nums, 10))
p_25 = math.ceil(np.percentile(nums, 25))
p_75 = math.ceil(np.percentile(nums, 75))
p_90 = math.ceil(np.percentile(nums, 90))
count = len(nums)
_d = addict.Dict(
('avg', avg),
('median', median),
('std', std),
('max', max),
('min', min),
('p_10', p_10),
('p_25', p_25),
('p_75', p_75),
('p_90', p_90),
('count', count),
)
return _d
def __init__(self) -> None:
self.reset()
@@ -303,9 +404,6 @@ class LyricsBuilder(LyricsConcreteBuilder):
)
self.all_albums_lyrics.append(lyrics)
bar.update(update)
with open(f'{os.getcwd()}/all_albums_lyrics.json', 'w') as f:
json.dump(self.all_albums_lyrics, f, indent=2)
return self
def count_words_in_lyrics(self) -> None:
@@ -420,104 +518,3 @@ class LyricsBuilder(LyricsConcreteBuilder):
self.year_statistics = addict.Dict(
**self.year_statistics, **addict.Dict((year, _d))
)
# pprint(self.year_statistics)
@staticmethod
def construct_lyrics_url(artist: str, song: str) -> str:
"""Builds the URL for the lyrics api.
Parameters
----------
artist : str
Artist
song : str
Track title
Returns
-------
str
URL for lyrics from the lyrics api.
"""
lyrics_api_base = 'https://api.lyrics.ovh/v1'
lyrics_api_url = html.escape(f'{lyrics_api_base}/{artist}/{song}')
return lyrics_api_url
@staticmethod
def request_lyrics_from_url(url: str) -> str:
"""Gets lyrics from the lyrics api.
Parameters
----------
url : str
URL of the track for the lyrics api.
Returns
-------
str
Lyrics of the trakc
"""
resp = requests.get(url)
# No lyrics for a song will return a key of 'error', we pass on this.
try:
lyrics = LyricsBuilder.strip_punctuation(resp.json()['lyrics'])
return lyrics
except (KeyError, json.decoder.JSONDecodeError):
return
@staticmethod
def strip_punctuation(word: str) -> str:
"""Removes punctuation from lyrics.
Parameters
----------
word : str
Word to remove punctuation from.
Returns
-------
str
Same word without any punctuation.
"""
_strip = word.translate(str.maketrans('', '', string.punctuation))
return _strip
@staticmethod
def get_descriptive_statistics(nums: list) -> Dict[str, int]:
"""Calculates descriptive statistics.
Parameters
----------
nums : list
A list containing total number of words from a track.
Returns
-------
Dict[str, int]
Dictionary of statistic and value.
"""
if len(nums) == 0:
return
avg = math.ceil(np.mean(nums))
median = math.ceil(np.median(nums))
std = math.ceil(np.std(nums))
max = math.ceil(np.max(nums))
min = math.ceil(np.min(nums))
p_10 = math.ceil(np.percentile(nums, 10))
p_25 = math.ceil(np.percentile(nums, 25))
p_75 = math.ceil(np.percentile(nums, 75))
p_90 = math.ceil(np.percentile(nums, 90))
count = len(nums)
_d = addict.Dict(
('avg', avg),
('median', median),
('std', std),
('max', max),
('min', min),
('p_10', p_10),
('p_25', p_25),
('p_75', p_75),
('p_90', p_90),
('count', count),
)
return _d

View File

@@ -114,13 +114,13 @@ class LyricsClickDirector:
self.builder.all_albums_lyrics
)
self.builder.count_words_in_lyrics()
with open(f'{os.getcwd()}/lyrics_count.json', 'w+') as file:
json.dump(
self.builder.all_albums_lyrics_count,
file,
indent=2,
sort_keys=True,
)
# with open(f'{os.getcwd()}/lyrics_count.json', 'w+') as file:
# json.dump(
# self.builder.all_albums_lyrics_count,
# file,
# indent=2,
# sort_keys=True,
# )
self.builder._product.all_albums_lyrics_count = (
self.builder.all_albums_lyrics_count
)

View File

@@ -70,12 +70,20 @@ class LyricsWordcloud:
return cls(mic_img, all_albums_lyrics_count)
@staticmethod
def generate_grey_colours(
# word: str,
# font_size: str,
# random_state: typing.Union[None, bool] = None,
*args,
**kwargs,
) -> str:
"""Static method to generate a random grey colour"""
colour = f'hsl(0, 0%, {random.randint(60, 100)}%)'
return colour
def _get_lyrics_list(self) -> None:
"""Gets all words from lyrics in a single list + cleans them.
Returns
-------
None
"""
self.lyrics_list = list()
for i in self.all_albums_lyrics_count:
@@ -109,23 +117,8 @@ class LyricsWordcloud:
"""
self.char_mask = np.array(self.pillow_img)
@staticmethod
def generate_grey_colours(
word: str,
font_size: str,
random_state: typing.Union[None, bool] = None,
*args,
**kwargs,
) -> str:
colour = f'hsl(0, 0%, {random.randint(60, 100)}%)'
return colour
def _generate_word_cloud(self) -> None:
"""Generates a word cloud
Returns
-------
None
"""
self.wc = WordCloud(
max_words=150,
@@ -138,10 +131,6 @@ class LyricsWordcloud:
def _generate_plot(self) -> None:
"""Plots the wordcloud and sets matplotlib options.
Returns
-------
None
"""
plt.imshow(
self.wc.recolor(
@@ -159,10 +148,6 @@ class LyricsWordcloud:
def create_word_cloud(self) -> None:
"""Creates a word cloud
Returns
-------
None
"""
self._get_lyrics_list()
self._get_frequencies()

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 KiB

After

Width:  |  Height:  |  Size: 186 KiB