├── .gitignore ├── README.rst ├── bin └── pygalume ├── changelog ├── pygalume ├── __init__.py ├── controller │ ├── __init__.py │ ├── api.py │ ├── database.py │ ├── factory.py │ └── utils.py ├── models │ ├── __init__.py │ └── lyrics.py ├── myexceptions.py ├── pygalume.py ├── run_tests.sh └── settings.py ├── requirements.txt ├── setup.cfg ├── setup.py └── tests ├── __init__.py ├── test_api.py ├── test_database.py ├── test_factory.py ├── test_models.py └── test_utils.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io 2 | 3 | ### Python ### 4 | # Byte-compiled / optimized / DLL files 5 | __pycache__/ 6 | *.py[cod] 7 | 8 | # C extensions 9 | *.so 10 | 11 | # Distribution / packaging 12 | .Python 13 | env/ 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | downloads/ 18 | eggs/ 19 | .eggs/ 20 | lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .coverage 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | 47 | # Translations 48 | *.mo 49 | *.pot 50 | 51 | # Django stuff: 52 | *.log 53 | 54 | # Sphinx documentation 55 | docs/_build/ 56 | 57 | # PyBuilder 58 | target/ 59 | 60 | # Database 61 | *.db 62 | 63 | # PyCharm directory 64 | .idea 65 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | .. image:: https://badge.waffle.io/indacode/pygalume.svg?label=ready&title=Ready 2 | :height: 18px 3 | :width: 70px 4 | :alt: Stories in Ready 5 | :align: left 6 | 7 | ======== 8 | pygalume 9 | ======== 10 | 11 | A simple python command line utility using the Vagalume API to search and show songs lyrics. 12 | 13 | .. image:: http://i.imgur.com/MpmZu1j.png 14 | :height: 524px 15 | :width: 582px 16 | :alt: Usage 17 | :align: center 18 | 19 | 20 | Installing 21 | ---------- 22 | 23 | Via pip 24 | 25 | .. code-block:: bash 26 | 27 | $ pip install pygalume 28 | 29 | 30 | Clone this project and install via setup.py 31 | 32 | .. code-block:: bash 33 | 34 | $ git clone git@github.com:dunderlabs/pygalume.git 35 | $ cd pygalume/ 36 | $ python setup.py install 37 | 38 | 39 | Usage example 40 | ------------- 41 | 42 | Here you can see pygalume in action. How to get a lyric from your favorite artist? 43 | 44 | Pygalume works offline for those lyrics you had already searched for. 45 | 46 | Note: if the artist's name or music have more than one word, wrap it with double quotes. 47 | 48 | .. code-block:: bash 49 | 50 | $ pygalume -a Sia -m "Bird set free" 51 | 52 | 53 | How to print lyrics side by side? 54 | 55 | .. code-block:: bash 56 | 57 | $ pygalume -a Sia -m "Bird set free" -p 58 | 59 | 60 | How to get the discography? 61 | 62 | .. code-block:: bash 63 | 64 | $ pygalume -a Sia -d 65 | 66 | 67 | How to get songs name from an album? 68 | 69 | .. code-block:: bash 70 | 71 | $ pygalume -a Sia --al "This Is Acting" 72 | 73 | 74 | How to list all songs in cache? 75 | 76 | .. code-block:: bash 77 | 78 | $ pygalume --lc # or 79 | $ pygalume --list-cache 80 | 81 | 82 | How to clear all songs in cache? 83 | 84 | .. code-block:: bash 85 | 86 | $ pygalume --cc # or 87 | $ pygalume --clear-cache 88 | 89 | 90 | Development 91 | ------------- 92 | 93 | Running unit tests: 94 | 95 | .. code-block:: bash 96 | 97 | $ python setup.py test 98 | -------------------------------------------------------------------------------- /bin/pygalume: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ python 2 | 3 | from pygalume import pygalume 4 | 5 | if __name__ == '__main__': 6 | pygalume.main() 7 | -------------------------------------------------------------------------------- /changelog: -------------------------------------------------------------------------------- 1 | - 0.2.6 2 | - Display lyrics side by side with pretty print option. 3 | - 0.2.5 4 | - Change class responsibility. Lyrics should update itself not Database class. 5 | - 0.2.4 6 | - New template to print out lyrics information including url to vagalume's page. 7 | - 0.2.3 8 | - When a album name that did not exists is given, raise an error 9 | - Order musics from the cache by artist name 10 | -------------------------------------------------------------------------------- /pygalume/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dunderlabs/pygalume/a891265fd6a69149068068b6c9842bfcf120a03a/pygalume/__init__.py -------------------------------------------------------------------------------- /pygalume/controller/__init__.py: -------------------------------------------------------------------------------- 1 | from .api import * 2 | from .database import * 3 | from .factory import * 4 | -------------------------------------------------------------------------------- /pygalume/controller/api.py: -------------------------------------------------------------------------------- 1 | import requests as r 2 | from ..settings import API_URL 3 | from ..models import Lyrics 4 | from ..myexceptions import MusicNotFound, ArtistNotFound, DiscographyNotFound 5 | 6 | from .utils import formating_string_name 7 | 8 | 9 | SONG_NOT_FOUND = 'song_notfound' 10 | NOT_FOUND = 'notfound' 11 | 12 | 13 | class API(): 14 | 15 | def getLyrics(self, artist, music): 16 | artist = formating_string_name(artist) 17 | music = formating_string_name(music) 18 | 19 | response = r.get('{0}art={1}&mus={2}'.format(API_URL, artist, music)) 20 | response = response.json() 21 | 22 | if response['type'] == SONG_NOT_FOUND: 23 | raise MusicNotFound 24 | 25 | elif response['type'] == NOT_FOUND: 26 | raise ArtistNotFound 27 | 28 | else: 29 | # If the song is in portuguese, for example 30 | # there is no translation. 31 | try: 32 | translate = response['mus'][0]['translate'] 33 | translate = translate[0]['text'] 34 | except KeyError: 35 | translate = '' 36 | 37 | artist_name = response['art']['name'] 38 | music_name = response['mus'][0]['name'] 39 | 40 | data = { 41 | 'artist': artist_name, 42 | 'artist_url': response['art']['url'], 43 | 'music': music_name, 44 | 'music_url': response['mus'][0]['url'], 45 | 'text': response['mus'][0]['text'], 46 | 'translate': translate, 47 | } 48 | return Lyrics(**data) 49 | 50 | def getDiscography(self, artist): 51 | artist = formating_string_name(artist) 52 | response = r.get( 53 | 'http://www.vagalume.com.br/{}/discografia/index.js'.format(artist) 54 | ) 55 | 56 | try: 57 | response = response.json() 58 | 59 | except ValueError: 60 | raise ArtistNotFound 61 | 62 | albums_name = [ 63 | disc['desc'] for disc in response['discography']['item'] 64 | ] 65 | 66 | data = { 67 | 'artist': response['discography']['artist']['desc'], 68 | 'albums': albums_name, 69 | } 70 | return data 71 | 72 | def getSongs(self, artist, album): 73 | songs = [] 74 | artist = formating_string_name(artist) 75 | 76 | response = r.get( 77 | 'http://www.vagalume.com.br/{}/discografia/index.js'.format(artist) 78 | ) 79 | 80 | try: 81 | response = response.json() 82 | except ValueError: 83 | raise ArtistNotFound 84 | 85 | for discography in response['discography']['item']: 86 | if (discography['desc'] == album): 87 | songs = [ 88 | songs['desc'] for songs in discography['discs'][0] 89 | ] 90 | break 91 | 92 | if not songs: 93 | raise DiscographyNotFound 94 | # List songs from the album which the user chosen 95 | return songs 96 | -------------------------------------------------------------------------------- /pygalume/controller/database.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | 3 | from ..models import Lyrics 4 | from .utils import formating_string_name 5 | 6 | 7 | class DataBase(): 8 | """ 9 | This class will work as a cache. 10 | """ 11 | 12 | def getLyrics(self, artist, music): 13 | artist_tag = formating_string_name(artist) 14 | music_tag = formating_string_name(music) 15 | 16 | lyrics = Lyrics.select().where( 17 | Lyrics.artist_tag == artist_tag, 18 | Lyrics.music_tag == music_tag 19 | ).first() 20 | 21 | return lyrics 22 | 23 | def exists(self, artist, music): 24 | lyrics = self.getLyrics(artist, music) 25 | 26 | if lyrics: 27 | return True 28 | else: 29 | return False 30 | 31 | def getCachedSongs(self): 32 | lyrics = Lyrics.select().order_by(Lyrics.artist) 33 | 34 | return lyrics 35 | -------------------------------------------------------------------------------- /pygalume/controller/factory.py: -------------------------------------------------------------------------------- 1 | from .database import DataBase 2 | from .api import API 3 | 4 | 5 | class Factory(): 6 | 7 | def __init__(self): 8 | self._db = DataBase() 9 | self._api = API() 10 | 11 | def getLyrics(self, artist, music): 12 | 13 | try: 14 | if self._db.exists(artist, music): 15 | lyrics = self._db.getLyrics(artist, music) 16 | 17 | if lyrics.expired(): 18 | new_lyrics = self._api.getLyrics(artist, music) 19 | lyrics.updateTo(new_lyrics) 20 | 21 | else: 22 | lyrics = self._api.getLyrics(artist, music) 23 | lyrics.save() 24 | except: 25 | raise 26 | 27 | return lyrics 28 | 29 | def getDiscography(self, artist): 30 | 31 | try: 32 | return self._api.getDiscography(artist) 33 | 34 | except: 35 | raise 36 | 37 | def getSongs(self, artist, album): 38 | 39 | try: 40 | return self._api.getSongs(artist, album) 41 | 42 | except: 43 | raise 44 | 45 | def getCachedSongs(self): 46 | 47 | try: 48 | return self._db.getCachedSongs() 49 | except: 50 | raise 51 | -------------------------------------------------------------------------------- /pygalume/controller/utils.py: -------------------------------------------------------------------------------- 1 | 2 | def formating_string_name(string): 3 | return string.strip().replace(' ', '-').lower() 4 | -------------------------------------------------------------------------------- /pygalume/models/__init__.py: -------------------------------------------------------------------------------- 1 | from .lyrics import Lyrics, db 2 | 3 | 4 | if 'lyrics' not in db.get_tables(): 5 | db.create_table(Lyrics) 6 | -------------------------------------------------------------------------------- /pygalume/models/lyrics.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime, timedelta 2 | 3 | from peewee import * 4 | from playhouse.sqlite_ext import SqliteExtDatabase 5 | 6 | from ..settings import DATABASE_URL 7 | from ..controller.utils import formating_string_name 8 | 9 | db = SqliteExtDatabase(DATABASE_URL) 10 | 11 | 12 | class Lyrics(Model): 13 | ''' 14 | music_tag & artist_tag save the string like this: 15 | last-kiss & pearl-jam, to improve the search. 16 | ''' 17 | 18 | created_date = DateField(default=datetime.now().date) 19 | 20 | music = CharField(null=False) 21 | music_tag = CharField(null=False) 22 | music_url = CharField(null=False) 23 | 24 | text = TextField(null=False) 25 | translate = TextField() 26 | 27 | artist = CharField(null=False) 28 | artist_tag = CharField(null=False) 29 | artist_url = CharField(null=False) 30 | 31 | def save(self, *args, **kwargs): 32 | self.music_tag = formating_string_name(self.music) 33 | self.artist_tag = formating_string_name(self.artist) 34 | 35 | return super(Lyrics, self).save(*args, **kwargs) 36 | 37 | class Meta: 38 | database = db 39 | indexes = (('music', 'artist'), True) 40 | 41 | def __repr__(self): 42 | return '{0} - {1}'.format(self.artist, self.music) 43 | 44 | def expired(self): 45 | lyrics_date = self.created_date 46 | now = datetime.now().date() 47 | 48 | date_to_expires = lyrics_date + timedelta(days=30) 49 | 50 | return date_to_expires < now 51 | 52 | def updateTo(self, new_lyrics): 53 | 54 | self.text = new_lyrics.text 55 | self.translate = new_lyrics.translate 56 | self.created_date = datetime.now().date() 57 | 58 | self.save() 59 | -------------------------------------------------------------------------------- /pygalume/myexceptions.py: -------------------------------------------------------------------------------- 1 | class MusicNotFound(Exception): 2 | pass 3 | 4 | 5 | class ArtistNotFound(Exception): 6 | pass 7 | 8 | 9 | class DiscographyNotFound(Exception): 10 | pass 11 | -------------------------------------------------------------------------------- /pygalume/pygalume.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import os 3 | from .controller.factory import Factory 4 | from .myexceptions import MusicNotFound, ArtistNotFound, DiscographyNotFound 5 | 6 | 7 | factory = Factory() 8 | 9 | 10 | def main(): 11 | parser = argparse.ArgumentParser( 12 | prog='Pygalume', 13 | description="""A simple python command line utility using the Vagalume 14 | API to search and show songs lyrics.""", 15 | usage=""" 16 | Pygalume - Lyrics Finder 17 | 18 | Usage: pygalume.py [-a/--artist ] 19 | [-m/--music ] 20 | [--al/--album ] 21 | [-d/--discography] 22 | [--lc/--list-cache] 23 | [--cc/--clear-cache] 24 | [-p/--pretty] 25 | \n Get basic options and Help, use: -h\--help 26 | 27 | Examples: 28 | - Get Lyrics: 29 | pygalume.py -a "Pearl Jam" -m Black 30 | 31 | - Get Lyrics (Versions side by side): 32 | pygalume.py -a "Pearl Jam" -m Black -p 33 | 34 | - Get Discography: 35 | pygalume.py -a "Pearl Jam" -d 36 | 37 | - Get Songs name from an album: 38 | pygalume.py -a "Pearl Jam" --al "Ten" 39 | """ 40 | ) 41 | 42 | parser.add_argument( 43 | "-a", 44 | "--artist", 45 | dest="artist", 46 | type=str, 47 | help="Set artist name", 48 | ) 49 | 50 | parser.add_argument( 51 | "-m", 52 | "--music", 53 | dest="music", 54 | type=str, 55 | help="Set music name", 56 | ) 57 | 58 | parser.add_argument( 59 | "-p", 60 | "--pretty", 61 | action="store_true", 62 | help="Display song versions side by side", 63 | ) 64 | 65 | parser.add_argument( 66 | "--al", 67 | "--album", 68 | dest="album", 69 | type=str, 70 | help="Set album name", 71 | ) 72 | 73 | parser.add_argument( 74 | "-d", 75 | action="store_true", 76 | dest="discography", 77 | help="List all albums", 78 | ) 79 | 80 | parser.add_argument( 81 | "--lc", 82 | action="store_true", 83 | dest="listCache", 84 | help="List all songs in cache", 85 | ) 86 | 87 | parser.add_argument( 88 | "--cc", 89 | action="store_true", 90 | dest="cache", 91 | help="Clear the database cache", 92 | ) 93 | 94 | options = parser.parse_args() 95 | 96 | artist = options.artist 97 | music = options.music 98 | album = options.album 99 | discography = options.discography 100 | listCache = options.listCache 101 | cache = options.cache 102 | pretty = options.pretty 103 | 104 | if cache: 105 | clearCache() 106 | return 107 | 108 | if listCache: 109 | getCachedMusics() 110 | return 111 | 112 | if artist and music: 113 | getLyrics(artist, music, pretty) 114 | return 115 | 116 | if artist and discography: 117 | getDiscography(artist) 118 | 119 | if artist and album: 120 | getSongs(artist, album) 121 | 122 | else: 123 | printHelpMessage() 124 | return 125 | 126 | 127 | def printHelpMessage(): 128 | print(""" 129 | Options: 130 | -h, --help show this help message and exit 131 | 132 | -a, --artist set artist name 133 | -m, --music set music name 134 | --al, --album set album name 135 | -d, --discography search for artist name 136 | 137 | --lc, --list-cache list all songs in cache 138 | --cc, --clear-cache clear cache from database 139 | 140 | -p, --pretty display song versions side by side 141 | """) 142 | 143 | 144 | def clearCache(): 145 | os.remove('banco.db') 146 | print("Cache cleaned!") 147 | 148 | 149 | def getCachedMusics(): 150 | songs = factory.getCachedSongs() 151 | 152 | print('\n\n Artist - Song') 153 | print('-------------------') 154 | for song in songs: 155 | print(song) 156 | print('\n\n') 157 | 158 | 159 | def getLyrics(artist, music, pretty): 160 | try: 161 | data = factory.getLyrics(artist, music) 162 | 163 | if pretty and data.translate: 164 | print_pretty_lyrics(data) 165 | else: 166 | print_lyrics(data) 167 | 168 | except MusicNotFound: 169 | print('Music not found!') 170 | 171 | except ArtistNotFound: 172 | print('Artist not found!') 173 | 174 | 175 | def getDiscography(artist): 176 | try: 177 | data = factory.getDiscography(artist) 178 | for disc in data['albums']: 179 | print(disc) 180 | 181 | except ArtistNotFound: 182 | print('Artist not found!') 183 | 184 | 185 | def getSongs(artist, album): 186 | try: 187 | data = factory.getSongs(artist, album) 188 | for music in data: 189 | print(music) 190 | except DiscographyNotFound: 191 | print('Discography not found!') 192 | 193 | 194 | def print_lyrics(data): 195 | print('\n-------------------------\n') 196 | print('Artist: {}'.format(data.artist)) 197 | print('Song: {}'.format(data.music)) 198 | print('URL: {}'.format(data.music_url)) 199 | print('\n-------------------------\n') 200 | print(data.text) 201 | print('\n-------------------------\n') 202 | 203 | if data.translate: 204 | print(data.translate) 205 | print('\n-------------------------\n') 206 | 207 | 208 | def print_pretty_lyrics(data): 209 | original_song = [x.strip() for x in data.text.split('\n')] 210 | translated_song = [x.strip() for x in data.translate.split('\n')] 211 | 212 | original_title = '[{0}]'.format(data.music) 213 | translated_title = translated_song.pop(0) 214 | 215 | while(translated_song and translated_song[0].strip() == ''): 216 | translated_song.pop(0) 217 | 218 | max_length = max([len(x) for x in original_song]) 219 | 220 | text = prettify_title(data, original_title, translated_title, max_length) 221 | for i in range(len(original_song)): 222 | text += prettify_line(original_song[i], translated_song[i], max_length) 223 | 224 | text += '\n-------------------------\n' 225 | print(text) 226 | 227 | 228 | def prettify_title(data, original, translated, max_length): 229 | text = '\n-------------------------\n\n' 230 | text += 'Artist: {}'.format(data.artist) 231 | text += '\n' 232 | text += 'URL: {}'.format(data.music_url) 233 | text += '\n\n-------------------------\n\n' 234 | text += prettify_line(original, translated, max_length) 235 | text += prettify_line('', '', max_length) 236 | return text 237 | 238 | 239 | def prettify_line(original, translated, max_length): 240 | text = original + ' ' * (max_length - len(original)) 241 | text += '{0}|{0}'.format(' ' * 10) 242 | text += translated 243 | text += '\n' 244 | return text 245 | 246 | 247 | if __name__ == "__main__": 248 | main() 249 | -------------------------------------------------------------------------------- /pygalume/run_tests.sh: -------------------------------------------------------------------------------- 1 | python -m unittest discover tests -------------------------------------------------------------------------------- /pygalume/settings.py: -------------------------------------------------------------------------------- 1 | import os 2 | from os.path import join, expanduser 3 | # If on Linux get, /home/$USER 4 | # If on Windows get, c:\\Users\\MyUser 5 | HOME = expanduser("~") 6 | 7 | PATH = join(HOME, '.pygalume') 8 | 9 | if not os.path.isdir(PATH): 10 | os.makedirs(PATH) 11 | 12 | DATABASE_URL = join(PATH, 'banco.db') 13 | 14 | API_URL = 'http://api.vagalume.com.br/search.php?' 15 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | peewee==2.8.0 2 | requests==2.9.1 3 | wheel==0.29.0 4 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [bdist_wheel] 2 | # This flag says that the code is written to work on both Python 2 and Python 3 | # 3. If at all possible, it is good practice to do this. If you cannot, you 4 | # will need to generate wheels for each Python version that you support. 5 | universal=1 6 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | 4 | long_description = """ 5 | Pygalume is a simple python command line utility using the 6 | Vagalume API to search and show songs lyrics. 7 | """ 8 | 9 | setup( 10 | name='Pygalume', 11 | version='0.2.6', 12 | description='Pygalume is a simple Python CLI to get lyrics', 13 | long_description=long_description, 14 | url='https://github.com/dunderlabs/pygalume', 15 | author='Dunderlabs Team', 16 | author_email='dunderlabs@gmail.com', 17 | maintainer='Dunderlabs Team', 18 | maintainer_email='dunderlabs@gmail.com', 19 | license='MIT', 20 | classifiers=[ 21 | 'Development Status :: 4 - Beta', 22 | 'Intended Audience :: Developers', 23 | 'Topic :: System :: Shells', 24 | 'Programming Language :: Python :: 2.7', 25 | 'Programming Language :: Python :: 3.3', 26 | 'Programming Language :: Python :: 3.4', 27 | 'Programming Language :: Python :: 3.5', 28 | ], 29 | keywords='pygalume cli lyrics shell vagalume music song', 30 | download_url='https://github.com/dunderlabs/pygalume/archive/master.zip', 31 | packages=find_packages(exclude=['tests*']), 32 | install_requires=['requests>=2.7.0', 'peewee>=2.8.0'], 33 | scripts=['bin/pygalume'], 34 | platforms='windows linux', 35 | ) 36 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from unittest import TestCase 3 | 4 | from pygalume.models import Lyrics 5 | from pygalume.controller import DataBase 6 | 7 | 8 | class TestBaseDb(TestCase): 9 | 10 | def setUp(self): 11 | self.__clear_table() 12 | self.db = DataBase() 13 | 14 | def tearDown(self): 15 | self.__clear_table() 16 | 17 | def __clear_table(self): 18 | Lyrics.delete().execute() 19 | 20 | def _create(self, commit=True, **kwargs): 21 | data = { 22 | 'artist': 'Testudo', 23 | 'artist_url': 'http', 24 | 'music': 'Test', 25 | 'music_url': 'http://', 26 | 'text': 'Testing', 27 | 'translate': 'Testando', 28 | 'artist_tag': 'testudo', 29 | 'music_tag': 'test', 30 | 'created_date': datetime.now().date(), 31 | } 32 | data.update(kwargs) 33 | 34 | lyrics = Lyrics(**data) 35 | 36 | if commit: 37 | lyrics.save() 38 | 39 | return lyrics 40 | -------------------------------------------------------------------------------- /tests/test_api.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | from pygalume.models import Lyrics 4 | from pygalume.controller import API 5 | from pygalume.myexceptions import ( 6 | MusicNotFound, ArtistNotFound, DiscographyNotFound 7 | ) 8 | 9 | 10 | class GetLyricsTest(unittest.TestCase): 11 | def setUp(self): 12 | self.api = API() 13 | 14 | def test_artist_not_found(self): 15 | with self.assertRaises(ArtistNotFound): 16 | self.api.getLyrics('a', 'Last Kiss') 17 | 18 | def test_music_not_found(self): 19 | with self.assertRaises(MusicNotFound): 20 | self.api.getLyrics('Pearl Jam', 'LastKiss') 21 | self.api.getLyrics('Pearl Jam', 'Last--Kiss') 22 | 23 | def test_music_found(self): 24 | self._test_music('Pearl Jam', 'Last Kiss') 25 | 26 | self._test_music('PearlJam', 'Last Kiss') 27 | 28 | self._test_music('Pearl-Jam', 'Last Kiss') 29 | 30 | self._test_music('Pearl Jam', 'Last-Kiss') 31 | 32 | self._test_music('Pearl Jam', 'Last Kiss ') 33 | 34 | self._test_music('Pearl Jam', ' Last Kiss') 35 | 36 | def _test_music(self, artist, music): 37 | lyrics = self.api.getLyrics(artist, music) 38 | 39 | self.assertIsInstance(lyrics, Lyrics) 40 | 41 | self.assertEqual(lyrics.music, 'Last Kiss') 42 | self.assertEqual(lyrics.artist, 'Pearl Jam') 43 | 44 | 45 | class GetDiscographyTest(unittest.TestCase): 46 | def setUp(self): 47 | self.api = API() 48 | 49 | def test_artist_not_found(self): 50 | with self.assertRaises(ArtistNotFound): 51 | self.api.getDiscography('a') 52 | self.api.getDiscography('PearlJam') 53 | self.api.getDiscography('Pearl Ja') 54 | 55 | def test_artist_found(self): 56 | self._test_artist('Pearl Jam') 57 | 58 | self._test_artist('Pearl Jam ') 59 | 60 | self._test_artist(' Pearl Jam') 61 | 62 | self._test_artist('Pearl-Jam') 63 | 64 | def _test_artist(self, artist): 65 | data = self.api.getDiscography(artist) 66 | 67 | self.assertIsInstance(data, dict) 68 | self.assertIsNotNone(data) 69 | self.assertIn('albums', data.keys()) 70 | 71 | 72 | class GetSongsTest(unittest.TestCase): 73 | 74 | def setUp(self): 75 | self.api = API() 76 | 77 | def test_artist_not_found(self): 78 | with self.assertRaises(ArtistNotFound): 79 | self.api.getSongs('Pearl Ja', 'Ten') 80 | 81 | def test_discography_not_found(self): 82 | with self.assertRaises(DiscographyNotFound): 83 | self.api.getSongs('Pearl Jam', 'Aasd') 84 | self.api.getSongs('PearlJam', 'Kiss') 85 | self.api.getSongs('Pearl-Jam', 'Last') 86 | 87 | def test_song_found(self): 88 | result = self.api.getSongs('Pearl Jam', 'No Code') 89 | self.assertIsInstance(result, list) 90 | self.assertNotEqual(result[0], None) 91 | 92 | result = self.api.getSongs('Pearl-Jam', 'No Code') 93 | self.assertIsInstance(result, list) 94 | self.assertNotEqual(result[0], None) 95 | -------------------------------------------------------------------------------- /tests/test_database.py: -------------------------------------------------------------------------------- 1 | from pygalume.models import Lyrics 2 | from . import TestBaseDb 3 | 4 | 5 | class TestDataBase(TestBaseDb): 6 | 7 | def test_get_lyrics(self): 8 | self._create() 9 | 10 | lyrics = self.db.getLyrics(artist='Testudo', music='Test') 11 | 12 | self.assertIsInstance(lyrics, Lyrics) 13 | 14 | def test_if_exist_lyrics(self): 15 | self._create() 16 | 17 | answer = self.db.exists(artist='Testudo', music='Test') 18 | 19 | self.assertTrue(answer) 20 | 21 | def test_cached_songs(self): 22 | self._create() 23 | self._create(artist="test2", music="music2") 24 | 25 | db_lyrics = self.db.getCachedSongs() 26 | 27 | self.assertEqual(len(db_lyrics), 2) 28 | -------------------------------------------------------------------------------- /tests/test_factory.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | 3 | from pygalume.models import Lyrics 4 | from pygalume.controller import Factory 5 | from pygalume.myexceptions import ArtistNotFound 6 | from . import TestBaseDb 7 | 8 | 9 | class TestFactory(TestBaseDb): 10 | 11 | def test_get_lyrics_with_db(self): 12 | ''' When lyrics exists in DB''' 13 | self._create() 14 | 15 | fac = Factory() 16 | 17 | db_lyrics = fac.getLyrics(artist='Testudo', music='Test') 18 | 19 | self.assertIsInstance(db_lyrics, Lyrics) 20 | self.assertEqual(str(db_lyrics), 'Testudo - Test') 21 | 22 | def test_get_lyrics_without_db(self): 23 | ''' When lyrics does not exist in DB ''' 24 | fac = Factory() 25 | 26 | db_lyrics = fac.getLyrics(artist='Pearl Jam', music='Last Kiss') 27 | 28 | self.assertIsInstance(db_lyrics, Lyrics) 29 | self.assertEqual(str(db_lyrics), 'Pearl Jam - Last Kiss') 30 | 31 | def test_get_expired_lyrics(self): 32 | ''' When lyrics exists and is expired ''' 33 | fac = Factory() 34 | old_lyrics = fac.getLyrics(artist='Pearl Jam', music='Last Kiss') 35 | 36 | new_date = datetime.strptime('2014-04-04', '%Y-%m-%d') 37 | old_lyrics.created_date = new_date 38 | 39 | old_lyrics.save() 40 | 41 | new_lyrics = fac.getLyrics(artist='Pearl Jam', music='Last Kiss') 42 | 43 | expected = datetime.now().date() 44 | self.assertEqual(new_lyrics.created_date, expected) 45 | 46 | def test_get_lyrics_raises(self): 47 | fac = Factory() 48 | 49 | with self.assertRaises(ArtistNotFound): 50 | fac.getLyrics(artist='Pear', music='Last Kiss') 51 | 52 | with self.assertRaises(ArtistNotFound): 53 | fac.getLyrics(artist='Pear Jam', music='Last') 54 | 55 | def test_get_cached_songs(self): 56 | ''' When lyrics exists in DB''' 57 | self._create() 58 | fac = Factory() 59 | 60 | db_lyrics = fac.getCachedSongs() 61 | 62 | self.assertEqual(len(db_lyrics), 1) 63 | -------------------------------------------------------------------------------- /tests/test_models.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | 3 | from pygalume.models import Lyrics 4 | 5 | from . import TestBaseDb 6 | 7 | 8 | class TestLyricsModel(TestBaseDb): 9 | 10 | def test_if_created(self): 11 | lyrics = self._create() 12 | 13 | expected = [lyrics] 14 | result = Lyrics.select() 15 | 16 | self.assertEqual(result, expected) 17 | 18 | def test_if_was_saved_with_tag_formating(self): 19 | lyrics = self._create(artist='Artist Test', music='Music Test') 20 | 21 | self.assertEqual(lyrics.artist_tag, 'artist-test') 22 | self.assertEqual(lyrics.music_tag, 'music-test') 23 | 24 | def test_update(self): 25 | lyrics = self._create() 26 | 27 | another_lyrics = self._create(commit=False, text='Bar') 28 | 29 | lyrics.updateTo(another_lyrics) 30 | 31 | db_lyrics = self.db.getLyrics(artist='Testudo', music='Test') 32 | 33 | self.assertEqual(db_lyrics.text, 'Bar') 34 | 35 | def test_expired(self): 36 | new_date = datetime.strptime('2014-04-04', '%Y-%m-%d').date() 37 | lyrics = self._create(created_date=new_date) 38 | 39 | answer = lyrics.expired() 40 | 41 | self.assertTrue(answer) 42 | 43 | def test_not_expired(self): 44 | lyrics = self._create() 45 | 46 | answer = lyrics.expired() 47 | 48 | self.assertFalse(answer) 49 | -------------------------------------------------------------------------------- /tests/test_utils.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | from pygalume.controller.utils import formating_string_name 4 | 5 | 6 | class FormatingStringTest(unittest.TestCase): 7 | 8 | def setUp(self): 9 | self.string1 = 'Pearl Jam' 10 | self.string2 = 'PearlJam' 11 | self.string3 = 'Pearl Jam ' 12 | self.string4 = ' Pearl Jam' 13 | 14 | def test_if_was_formated(self): 15 | expected = 'pearl-jam' 16 | result = formating_string_name(self.string1) 17 | self.assertEqual(expected, result) 18 | 19 | expected = 'pearljam' 20 | result = formating_string_name(self.string2) 21 | self.assertEqual(expected, result) 22 | 23 | expected = 'pearl-jam' 24 | result = formating_string_name(self.string3) 25 | self.assertEqual(expected, result) 26 | 27 | result = formating_string_name(self.string4) 28 | self.assertEqual(expected, result) 29 | --------------------------------------------------------------------------------