adding latest working version
This commit is contained in:
BIN
src/.DS_Store
vendored
Normal file
BIN
src/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
src/musicbrainzapi/.DS_Store
vendored
Normal file
BIN
src/musicbrainzapi/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
src/musicbrainzapi/api/.DS_Store
vendored
Normal file
BIN
src/musicbrainzapi/api/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
src/musicbrainzapi/api/command_builders/.DS_Store
vendored
Normal file
BIN
src/musicbrainzapi/api/command_builders/.DS_Store
vendored
Normal file
Binary file not shown.
@@ -383,9 +383,9 @@ class LyricsBuilder(LyricsConcreteBuilder):
|
||||
# rename this
|
||||
def calculate_average_all_albums(self) -> None:
|
||||
self.all_albums_lyrics_sum = list()
|
||||
album_lyrics = self.all_albums_lyrics_count
|
||||
# with open(f'{os.getcwd()}/lyrics_count.json', 'r') as f:
|
||||
# album_lyrics = json.load(f)
|
||||
# album_lyrics = self.all_albums_lyrics_count
|
||||
with open(f'{os.getcwd()}/lyrics_count.json', 'r') as f:
|
||||
album_lyrics = json.load(f)
|
||||
count = 0
|
||||
for i in album_lyrics:
|
||||
count += len(i)
|
||||
@@ -438,9 +438,9 @@ class LyricsBuilder(LyricsConcreteBuilder):
|
||||
def calculate_final_average_by_year(self) -> None:
|
||||
group_by_years = addict.Dict()
|
||||
self.year_statistics = addict.Dict()
|
||||
album_lyrics = self.all_albums_lyrics_sum
|
||||
# with open(f'{os.getcwd()}/lyrics_sum_all_album.json', 'r') as f:
|
||||
# album_lyrics = json.load(f)
|
||||
# album_lyrics = self.all_albums_lyrics_sum
|
||||
with open(f'{os.getcwd()}/lyrics_sum_all_album.json', 'r') as f:
|
||||
album_lyrics = json.load(f)
|
||||
|
||||
# Merge years together
|
||||
for i in album_lyrics:
|
||||
@@ -735,21 +735,24 @@ class Lyrics:
|
||||
stats[9],
|
||||
]
|
||||
for group, s in stats_obj.items():
|
||||
output_1.append_row(
|
||||
[
|
||||
group,
|
||||
s.get(stats[0]),
|
||||
s.get(stats[1]),
|
||||
s.get(stats[2]),
|
||||
s.get(stats[3]),
|
||||
s.get(stats[4]),
|
||||
s.get(stats[5]),
|
||||
s.get(stats[6]),
|
||||
s.get(stats[7]),
|
||||
s.get(stats[8]),
|
||||
s.get(stats[9]),
|
||||
]
|
||||
)
|
||||
try:
|
||||
output_1.append_row(
|
||||
[
|
||||
group,
|
||||
s.get(stats[0]),
|
||||
s.get(stats[1]),
|
||||
s.get(stats[2]),
|
||||
s.get(stats[3]),
|
||||
s.get(stats[4]),
|
||||
s.get(stats[5]),
|
||||
s.get(stats[6]),
|
||||
s.get(stats[7]),
|
||||
s.get(stats[8]),
|
||||
s.get(stats[9]),
|
||||
]
|
||||
)
|
||||
except AttributeError:
|
||||
continue
|
||||
output_0.append_row([output_1])
|
||||
click.echo(output_0)
|
||||
return self
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
0
src/musicbrainzapi/api/lyrics/__init__.py
Normal file
0
src/musicbrainzapi/api/lyrics/__init__.py
Normal file
0
src/musicbrainzapi/api/lyrics/builder.py
Normal file
0
src/musicbrainzapi/api/lyrics/builder.py
Normal file
0
src/musicbrainzapi/api/lyrics/concrete_builder.py
Normal file
0
src/musicbrainzapi/api/lyrics/concrete_builder.py
Normal file
0
src/musicbrainzapi/api/lyrics/director.py
Normal file
0
src/musicbrainzapi/api/lyrics/director.py
Normal file
@@ -33,12 +33,7 @@ class ComplexCLI(click.MultiCommand):
|
||||
|
||||
def get_command(self, ctx, name):
|
||||
try:
|
||||
if sys.version_info[0] == 2:
|
||||
name = name.encode('ascii', 'replace')
|
||||
mod = import_module(f'musicbrainzapi.cli.commands.cmd_{name}')
|
||||
# mod = __import__(
|
||||
# 'complex.commands.cmd_' + name, None, None, ['cli']
|
||||
# )
|
||||
except ImportError as e:
|
||||
print(e)
|
||||
return
|
||||
@@ -50,23 +45,23 @@ class ComplexCLI(click.MultiCommand):
|
||||
'-p',
|
||||
'--path',
|
||||
type=click.Path(
|
||||
exists=False, file_okay=False, resolve_path=True, writable=True
|
||||
exists=True, file_okay=False, resolve_path=True, writable=True
|
||||
),
|
||||
help='Path to save results.',
|
||||
default=os.path.expanduser('~/.musicbrainzapi')
|
||||
default=os.getcwd()
|
||||
)
|
||||
@click.option('-v', '--verbose', is_flag=True, help='Enables verbose mode.')
|
||||
# @click.option('-v', '--verbose', is_flag=True, help='Enables verbose mode.')
|
||||
@click.version_option(
|
||||
version=__version__,
|
||||
prog_name=__header__,
|
||||
message=f'{__header__} version {__version__} 🎤',
|
||||
)
|
||||
@pass_environment
|
||||
def cli(ctx, verbose, path):
|
||||
def cli(ctx, path):
|
||||
"""A complex command line interface."""
|
||||
ctx.verbose = verbose
|
||||
# ctx.verbose = verbose
|
||||
if path is not None:
|
||||
click.echo(f'Path set to {os.path.expanduser(path)}')
|
||||
# click.echo(f'Path set to {os.path.expanduser(path)}')
|
||||
ctx.path = os.path.expanduser(path)
|
||||
|
||||
|
||||
|
||||
@@ -2,8 +2,11 @@ from typing import Union
|
||||
|
||||
import click
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
from musicbrainzapi.cli.cli import pass_environment
|
||||
from musicbrainzapi.api.command_builders import lyrics
|
||||
import musicbrainzapi.wordcloud
|
||||
|
||||
|
||||
# @click.argument('path', required=False, type=click.Path(resolve_path=True))
|
||||
@@ -17,7 +20,14 @@ from musicbrainzapi.api.command_builders import lyrics
|
||||
help='Save the output to json files locally. Will use the path parameter if'
|
||||
' provided else defaults to current working directory.',
|
||||
is_flag=True,
|
||||
default=False
|
||||
default=False,
|
||||
)
|
||||
@click.option(
|
||||
'--wordcloud',
|
||||
required=False,
|
||||
help='Generate a wordcloud from lyrics.',
|
||||
is_flag=True,
|
||||
default=False,
|
||||
)
|
||||
@click.option(
|
||||
'--show-summary',
|
||||
@@ -51,9 +61,12 @@ def cli(
|
||||
country: Union[str, None],
|
||||
dev: bool,
|
||||
show_summary: str,
|
||||
save_output: bool
|
||||
wordcloud: bool,
|
||||
save_output: bool,
|
||||
) -> None:
|
||||
"""Search for lyrics statistics of an Artist/Group."""
|
||||
path = ctx.path
|
||||
print(f'home={ctx.home}')
|
||||
# lyrics_obj = list()
|
||||
director = lyrics.LyricsClickDirector()
|
||||
builder = lyrics.LyricsBuilder()
|
||||
@@ -70,16 +83,34 @@ def cli(
|
||||
director._calculate_basic_statistics()
|
||||
if show_summary is not None:
|
||||
director._calculate_descriptive_statistics()
|
||||
|
||||
|
||||
# Get the Lyrics object
|
||||
lyrics_0 = director.builder.product
|
||||
# lyrics_obj.append(lyrics_0)
|
||||
|
||||
# Show basic count
|
||||
lyrics_0.show_summary()
|
||||
|
||||
# Show summary statistics
|
||||
if show_summary == 'all':
|
||||
lyrics_0.show_summary_statistics(group_by='album')
|
||||
lyrics_0.show_summary_statistics(group_by='year')
|
||||
elif show_summary in ['album', 'year']:
|
||||
lyrics_0.show_summary_statistics(group_by=show_summary)
|
||||
|
||||
# Show wordcloud
|
||||
if wordcloud:
|
||||
click.echo('Generating wordcloud')
|
||||
cloud = musicbrainzapi.wordcloud.LyricsWordcloud.use_microphone(
|
||||
lyrics_0.all_albums_lyrics_count
|
||||
)
|
||||
cloud.create_word_cloud()
|
||||
click.confirm('Wordcloud ready - press enter to show.', default=True)
|
||||
plt.imshow(
|
||||
cloud.wc.recolor(
|
||||
color_func=cloud.generate_grey_colours, random_state=3
|
||||
),
|
||||
interpolation='bilinear',
|
||||
)
|
||||
plt.axis('off')
|
||||
plt.show()
|
||||
|
||||
115
src/musicbrainzapi/wordcloud/__init__.py
Normal file
115
src/musicbrainzapi/wordcloud/__init__.py
Normal file
@@ -0,0 +1,115 @@
|
||||
from __future__ import annotations
|
||||
import collections
|
||||
from importlib import resources
|
||||
import random
|
||||
import re
|
||||
import typing
|
||||
|
||||
from matplotlib import pyplot as plt
|
||||
from PIL import Image
|
||||
from wordcloud import STOPWORDS, WordCloud
|
||||
import numpy as np
|
||||
|
||||
from musicbrainzapi.api.command_builders.lyrics import Lyrics
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
import PIL.PngImagePlugin.PngImageFile
|
||||
|
||||
|
||||
class LyricsWordcloud:
|
||||
|
||||
"""docstring for LyricsWordcloud"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
pillow_img: 'PIL.PngImagePlugin.PngImageFile',
|
||||
all_albums_lyrics_count: 'Lyrics.all_albums_lyrics_count',
|
||||
):
|
||||
self.pillow_img = pillow_img
|
||||
self.all_albums_lyrics_count = all_albums_lyrics_count
|
||||
|
||||
@classmethod
|
||||
def use_microphone(
|
||||
cls, all_albums_lyrics_count: 'Lyrics.all_albums_lyrics_count',
|
||||
) -> LyricsWordcloud:
|
||||
mic_resource = resources.path(
|
||||
'musicbrainzapi.wordcloud.resources', 'mic.png'
|
||||
)
|
||||
with mic_resource as m:
|
||||
mic_img = Image.open(m)
|
||||
|
||||
return cls(mic_img, all_albums_lyrics_count)
|
||||
|
||||
def _get_lyrics_list(self) -> None:
|
||||
self.lyrics_list = list()
|
||||
for i in self.all_albums_lyrics_count:
|
||||
for album, lyric in i.items():
|
||||
for track in lyric:
|
||||
try:
|
||||
for word in track:
|
||||
for _ in range(1, word[1]):
|
||||
cleaned = word[0]
|
||||
cleaned = re.sub(
|
||||
r'[\(\[].*?[\)\]]', ' ', cleaned
|
||||
)
|
||||
cleaned = re.sub(
|
||||
r'[^a-zA-Z0-9\s]', '', cleaned
|
||||
)
|
||||
cleaned = cleaned.lower()
|
||||
if cleaned in STOPWORDS:
|
||||
continue
|
||||
self.lyrics_list.append(cleaned)
|
||||
except IndexError:
|
||||
pass
|
||||
return self
|
||||
|
||||
def _get_frequencies(self) -> None:
|
||||
self.freq = collections.Counter(self.lyrics_list)
|
||||
|
||||
def _get_char_mask(self) -> None:
|
||||
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:
|
||||
self.wc = WordCloud(
|
||||
max_words=50,
|
||||
width=500,
|
||||
height=500,
|
||||
mask=self.char_mask,
|
||||
random_state=1,
|
||||
).generate_from_frequencies(self.freq)
|
||||
return self
|
||||
|
||||
def _generate_plot(self) -> None:
|
||||
plt.imshow(
|
||||
self.wc.recolor(
|
||||
color_func=self.generate_grey_colours, random_state=3
|
||||
),
|
||||
interpolation='bilinear',
|
||||
)
|
||||
plt.axis('off')
|
||||
return self
|
||||
|
||||
def save_to_disk(self, path: str):
|
||||
pass
|
||||
|
||||
def show_word_cloud(self):
|
||||
plt.show()
|
||||
|
||||
def create_word_cloud(self) -> None:
|
||||
self._get_lyrics_list()
|
||||
self._get_frequencies()
|
||||
self._get_char_mask()
|
||||
self._generate_word_cloud()
|
||||
self._generate_plot()
|
||||
return self
|
||||
0
src/musicbrainzapi/wordcloud/resources/__init__.py
Normal file
0
src/musicbrainzapi/wordcloud/resources/__init__.py
Normal file
BIN
src/musicbrainzapi/wordcloud/resources/mic.png
Normal file
BIN
src/musicbrainzapi/wordcloud/resources/mic.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 186 KiB |
Reference in New Issue
Block a user