#!/usr/bin/python

import requests
from bs4 import BeautifulSoup
import os
import dbus
from subprocess import Popen, PIPE
import errno
import ueberzug.lib.v0 as ueberzug
import textwrap
import time

from urllib.request import urlretrieve
try:
    from urllib.parse import quote_plus
except ImportError:
    from urllib import quote_plus

from pathlib import Path

# https://github.com/bhrigu123/Instant-Lyrics/blob/29e2a817fee3853a6a0f0bdc825145fd4004d1e1/src/lyrics.py#L11
def get_lyrics(song_name):

    song_name += ' metrolyrics'
    name = quote_plus(song_name)
    hdr = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11'
           '(KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11',
           'Accept-Language': 'en-US,en;q=0.8',
           'Connection': 'keep-alive'}

    url = 'http://www.google.com/search?q={}'.format(name)

    result = requests.get(url, headers=hdr).text
    link_start = result.find('http://www.metrolyrics.com')

    if(link_start == -1):
        return("Lyrics not found on Metrolyrics")

    link_end = result.find('html', link_start + 1)
    link = result[link_start:link_end + 4]


    r = requests.get(link, headers={ 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel'
        'Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, '
        'like Gecko) Chrome/55.0.2883.95 Safari/537.36' })
    lyrics_html = r.content

    soup = BeautifulSoup(lyrics_html, "lxml", from_encoding='UTF-8')
    raw_lyrics = (soup.findAll('p', attrs={'class': 'verse'}))

    paras = []
    try:
        final_lyrics = unicode.join(u'\n', map(unicode, raw_lyrics))
    except NameError:
        final_lyrics = str.join(u'\n', map(str, raw_lyrics))

    final_lyrics = (final_lyrics.replace('<p class="verse">', '\n'))
    final_lyrics = (final_lyrics.replace('<br/>', ' '))
    final_lyrics = final_lyrics.replace('</p>', ' ')
    return (final_lyrics)

def get_spotify_song_data():
    session_bus = dbus.SessionBus()

    spotify_bus = session_bus.get_object(
        "org.mpris.MediaPlayer2.spotify", "/org/mpris/MediaPlayer2")
    spotify_properties = dbus.Interface(
        spotify_bus, "org.freedesktop.DBus.Properties")
    metadata = spotify_properties.Get(
        "org.mpris.MediaPlayer2.Player", "Metadata")
    title = metadata['xesam:title'].encode(
        'utf-8').decode('utf-8').replace("&", "&amp;")
    artist = metadata['xesam:artist'][0].encode(
        'utf-8').decode('utf-8').replace("&", "&amp;")
    album = metadata['xesam:album'].encode(
        'utf-8').decode('utf-8').replace("&", "&amp;")
    art_url = metadata['mpris:artUrl'].encode(
        'utf-8').decode('utf-8').replace("&", "&amp;")
    return title, artist, album, art_url

@ueberzug.Canvas()
def main(canvas):
    rows, columns = map(int, os.popen('stty size', 'r').read().split())
    try:
        song, artist, album, art_url = get_spotify_song_data()
    except:
        raise ValueError("Can't reach to the Spotify DBus")
    home = str(Path.home())
    lyrics_directory = os.path.join(home, 'lyrics')
    artist_directory = os.path.join(lyrics_directory, artist.replace('/', ''))
    image_directory = os.path.join(artist_directory, 'album_arts')
    lyrics_file = os.path.join(artist_directory, song.replace('/', ''))
    image_file = '{}.png'.format(os.path.join(image_directory, album))

    if not os.path.isdir(lyrics_directory): os.mkdir(lyrics_directory)
    if not os.path.isdir(artist_directory): os.mkdir(artist_directory)
    if not os.path.isdir(image_directory): os.mkdir(image_directory)

    if not os.path.exists(lyrics_file):
        lyrics = get_lyrics(song)
        with open(lyrics_file, 'w') as f:
            f.write(lyrics)
    else:
        with open(lyrics_file, 'r') as f:
            lyrics = ''.join(f.readlines())

    if not os.path.exists(image_file):
        urlretrieve(art_url, image_file)

    album_cover = canvas.create_placement('album_cover',
            x=columns//2, y=4,
            scaler=ueberzug.ScalerOption.COVER.value)
    album_cover.path = image_file
    album_cover.visibility = ueberzug.Visibility.VISIBLE

    p = Popen('less', stdin=PIPE)
    p.stdin.write('Artist: {}\n'.format(artist).encode(encoding='UTF-8'))
    p.stdin.write('Album: {}\n'.format(album).encode(encoding='UTF-8'))
    p.stdin.write('Song: {}\n'.format(song).encode(encoding='UTF-8'))
    for line in lyrics.split('\n'):
        p.stdin.write(
            '{}\n'.format(textwrap.fill(line, columns//2-2)).encode(encoding='UTF-8'))
    p.stdin.close()
    p.wait()


if __name__ == '__main__':
    main()
