Giter Club home page Giter Club logo

tswift's Introduction

GOODBYE CRUEL WORLD

I'm sorry to report that, as of June 29, 2021, Metrolyrics has mysteriously gone offline. As a result, this package is functionally dead and useless. If you use it, you'll probably get an exception like the following:

$ tswift -l 'so casually cruel in the name of being honest'
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 169, in _new_conn
    conn = connection.create_connection(
  File "/usr/lib/python3/dist-packages/urllib3/util/connection.py", line 73, in create_connection
    for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):
  File "/usr/lib/python3.9/socket.py", line 953, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -5] No address associated with hostname

During handling of the above exception, another exception occurred:
.... many more tracebacks ....

Maybe someday I'll select a new lyric website and try to implement a similar API from it. But it's unlikely it would be compatible (depends on the URL structure) and the content list (and formatting) would likely be different as well.

Rest in peace, Metrolyrics.

tswift

This repo is actually not directly related to Taylor Swift. It's just a simple Python API for getting lyrics from MetroLyrics. Here is how easy it is:

from tswift import Artist
import random

tswift = Artist('Taylor Swift')
song = random.choice(tswift.songs)
print(song.format())

Setup

This package depends on lxml, requests, and google. These should be installed when you install this package from pip:

pip install tswift

After installing, you can also print a random Taylor Swift song lyric with the command:

tswift

CLI

The module comes with a simple command line interface. By default, it will display a random song by Taylor Swift. You can specify an artist like this:

tswift 'Lynyrd Skynyrd'

You can choose a particular song:

tswift 'Lynyrd Skynyrd' -s Freebird

There is also a "lyric search mode", which allows you to search for a song by lyrics, e.g.:

tswift -l 'I would walk 500 miles'

Im Gonna Be 500 Miles
Proclaimers
---------------------

When I wake up, well I know I'm gonna be,
I'm gonna be the man who wakes up next you
...

API

Artist class

The constructor takes a single argument, the artist name. This name will be "slugified" in order to use it within URLs. This process involves replacing spaces with hyphens, and making everything lowercase. If this is not sufficient for your particular artist, you'll need to provide a pre-slugified version of their name.

  • songs - a list of Song instances by this artist. This will call load() if it hasn't been called yet
  • name - the artist's slugified name
  • load() - populates the songs list

Song class

The constructor can be called in two ways. In the first, you provide a Metrolyrics URL, and the class will infer the artist and song title:

s = Song(url='url here')

In the second way, you provide a title and artist, which will be slugified.

s = Song('Taylor Swift', 'Love Story')

The attributes are:

  • lyrics - a string. Accessing this will call load() if not yet loaded
  • title - de-slugified title of song
  • artist - de-slugified artist name
  • load() - loads the lyrics
  • format() - returns the lyrics, with a header that includes the title and artist.

The static method Song.find_song(lyrics) takes a string with a search term, and performs a Google search. It returns a Song instance corresponding to the first Metrolyrics link it finds, stopping after 20 results. If nothing is found, returns None.

tswift's People

Contributors

a-johnston avatar brenns10 avatar briana-mcn avatar dacukimonsta avatar esotericalgorithm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

tswift's Issues

AttributeError in tswift.py

Using this code:

from tswift import Artist
import random

tswift = Artist('Taylor Swift')
song = random.choice(tswift.songs)
print(song.format())

I get the following traceback:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-12-2341cd82ac4a> in <module>()
      3 
      4 tswift = Artist('Taylor Swift')
----> 5 song = random.choice(tswift.songs)
      6 print(song.format())

~/anaconda3/envs/python3/lib/python3.6/site-packages/tswift.py in songs(self)
    148     def songs(self):
    149         if self._songs is None:
--> 150             self.load()
    151         return self._songs
    152 

~/anaconda3/envs/python3/lib/python3.6/site-packages/tswift.py in load(self, verbose)
    139                 song_link = row.xpath(r'./td/a[contains(@class,"title")]')
    140                 assert len(song_link) == 1
--> 141                 self._songs.append(Song(url=song_link[0].attrib['href']))
    142 
    143             total_pages = len(tree.xpath(songlist_pagination_xp))

~/anaconda3/envs/python3/lib/python3.6/site-packages/tswift.py in __init__(self, title, artist, url)
     45         if url is not None:
     46             self._url = url
---> 47             self.title, self.artist = re.match(SONG_RE, url).groups()
     48         elif title is not None and artist is not None:
     49             self.title = title

AttributeError: 'NoneType' object has no attribute 'groups'

I don't know the cause of the error, but I suspect the MetroLyrics API changed? I've been using your your package for almost a year (thank you its awesome!) and I've never had any issues with it in the past.

Async version?

First, really enjoying using this package. Works great!

I was hoping to use this with my discord bot, but the bot uses async and requests is blocking. If I wanted to write an async version (looking at using aiohttp) what would need to be changed?

Thanks!

Calling Song.lyrics results in KeyError: 'lyrics-body-text'

Hi! Awesome repo:)

Accessing lyrics as in the examples works fine. However, when I try to programmatically create instances of Song, then print their lyrics. I run into the following error:

Traceback (most recent call last):
  File "/anaconda/lib/python3.6/site-packages/lxml/html/__init__.py", line 409, in get_element_by_id
    return _id_xpath(self, id=id)[0]
IndexError: list index out of range

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "billboard.py", line 50, in <module>
    print(s.lyrics)
  File "/anaconda/lib/python3.6/site-packages/tswift.py", line 76, in lyrics
    self.load()
  File "/anaconda/lib/python3.6/site-packages/tswift.py", line 68, in load
    lyric_div = tree.get_element_by_id('lyrics-body-text')
  File "/anaconda/lib/python3.6/site-packages/lxml/html/__init__.py", line 414, in get_element_by_id
    raise KeyError(id)
KeyError: 'lyrics-body-text'

This occurs when I do:

import tswift as tw
for index, row in cleaned.iterrows():
    s=tw.Song(row['song'],row['artist'])
    print(s.lyrics) 

Don't get an issue when I try print(s), which results in

Song(title='Rockstar', artist='Post Malone Featuring 21 Savage')
Song(title='Too Good At Goodbyes', artist='Sam Smith')
Song(title='I Fall Apart', artist='Post Malone')
Song(title='Gucci Gang', artist='Lil Pump')

Thanks for any assistance, perhaps you know what's going on:)

Error while retrieving lyrics - ValueError: Input object is not an XML element: HtmlComment

Traceback (most recent call last):
  File "./tswift.py", line 202, in <module>
    main()
  File "./tswift.py", line 198, in main
    print(song.format())
  File "./tswift.py", line 84, in format
    self.lyrics,
  File "./tswift.py", line 76, in lyrics
    self.load()
  File "./tswift.py", line 69, in load
    verses = [c.text_content() for c in lyric_div]
  File "./tswift.py", line 69, in <listcomp>
    verses = [c.text_content() for c in lyric_div]
  File "/usr/local/lib/python3.5/dist-packages/lxml/html/__init__.py", line 420, in text_content
    return _collect_string_content(self)
  File "src/lxml/xpath.pxi", line 433, in lxml.etree.XPath.__call__ (src/lxml/lxml.etree.c:174192)
  File "src/lxml/apihelpers.pxi", line 67, in lxml.etree._rootNodeOrRaise (src/lxml/lxml.etree.c:17443)
ValueError: Input object is not an XML element: HtmlComment

I think this is because in lyric_di contains not only objects like HtmlComment. It is expected that all elements of lyric_div contain the method text_content, but HtmlComment does not have this method.

Version bump

need to put the cli code into main(), and make it console_script in setup.py. then do a bump and push to pypi. but not right now.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.