-
Notifications
You must be signed in to change notification settings - Fork 28
/
Copy pathsing.py
126 lines (92 loc) · 3.01 KB
/
sing.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#sing.py
from modules.__common__ import shorten_url
from urllib.parse import urlencode, unquote
import re, random, sys
import tornado.gen
import tornado.httpclient
from lxml import etree, html
#Metadata
NAME = 'sing'
ENABLE = True
TYPE = 'command'
PATTERN = '^!sing (?P<query>.*$)'
USAGE = '''Usage: !sing <song> [- <artist>]
Given a song title and an optional artist, this module responds with a few lines from
the song.
Example:
> !sing Truth Hurts
Why're men great 'til they gotta be great?
'''
LYRICS_URL = 'http://search.azlyrics.com/'
def parse_query(query):
if " - " in query:
query = query.split("-")
title = query[0].strip()
artist = query[1].strip()
else:
title = query.strip()
artist = None
return (title, artist)
def find_match(artist, title, results):
for song in results:
url = song[0][0].attrib['href']
a_match = "".join(song[0][1].text[:])
t_match = "".join(song[0][0][0].text[:])
if artist.strip().lower() in a_match.strip().lower():
if title.strip().lower() in t_match.strip().lower():
return url
return ""
def get_song_url(tree, title, artist):
try:
results = tree[1][3][0][0][-2][1][:]
except:
return "Song not found"
if artist:
try:
song_url = find_match(artist, title, results)
except:
song_url = find_match(artist, title, results[1:-1])
else:
try:
song_url = results[0][0][0].attrib['href']
except:
song_url = results[1][0][0].attrib['href']
if song_url == "":
return "Song not found"
else:
return song_url
def get_lyrics(tree):
results = tree[1][6][0][2][:]
for i, r in enumerate(results):
string = ""
for each in r[1:]:
string += etree.tostring(each, method="text", encoding="utf-8").decode("utf-8")
lyrics = string.splitlines()
lyrics = [x for x in lyrics if x != '']
lyrics = [x for x in lyrics if not x.startswith("[")]
if len(lyrics) > 1:
i = random.randint(0, len(lyrics))
return lyrics[i] + " \\\\ " + lyrics[i+1]
return "Lyrics not found"
# Command
@tornado.gen.coroutine
def command(bot, nick, message, channel, query=None):
title, artist = parse_query(query)
params = {'q': query}
url = LYRICS_URL + '?' + urlencode(params)
client = tornado.httpclient.AsyncHTTPClient()
result = yield tornado.gen.Task(client.fetch, url)
tree = etree.HTML(result.body)
response = get_song_url(tree, title, artist)
if response != "Song not found":
song_url = response
client = tornado.httpclient.AsyncHTTPClient()
result = yield tornado.gen.Task(client.fetch, song_url)
tree = etree.HTML(result.body)
response = get_lyrics(tree)
bot.send_response(response, nick, channel)
# Register
def register(bot):
return (
(PATTERN, command),
)