Ticket #13545: music_scripts_python_2_3.patch

File music_scripts_python_2_3.patch, 38.5 KB (added by rcrdnalor, 7 years ago)

Add compatibility to python3 for music grabber scripts

  • mythtv/programs/scripts/metadata/Music/lyrics/common/__init__.py

    diff --git a/mythtv/programs/scripts/metadata/Music/lyrics/common/__init__.py b/mythtv/programs/scripts/metadata/Music/lyrics/common/__init__.py
    index b1b9bddeaf..391fdc6bbe 100644
    a b  
    11__version__ = "1.0.0"
    22
    3 import utilities, audiofile
     3from . import utilities, audiofile
     4
  • mythtv/programs/scripts/metadata/Music/lyrics/common/utilities.py

    diff --git a/mythtv/programs/scripts/metadata/Music/lyrics/common/utilities.py b/mythtv/programs/scripts/metadata/Music/lyrics/common/utilities.py
    index 4ad657d21b..dfca3b2cd6 100644
    a b import sys  
    22import os
    33import unicodedata
    44
     5IS_PY2 = sys.version_info[0] == 2
     6
    57def log(debug, txt):
    68    if debug:
    7         print txt
     9        print(txt)
    810
    911class Lyrics:
    1012    def __init__(self):
    class Lyrics:  
    1921
    2022def deAccent(str):
    2123    return unicodedata.normalize('NFKD', unicode(str, 'utf-8'))
     24   
     25def convert_etree(etostr):
     26    """lxml.etree.tostring is a bytes object in python3, and a str in python2.
     27    """
     28    if IS_PY2:
     29        return(etostr)
     30    else:
     31        return(etostr.decode())
     32
  • mythtv/programs/scripts/metadata/Music/lyrics/darklyrics.py

    diff --git a/mythtv/programs/scripts/metadata/Music/lyrics/darklyrics.py b/mythtv/programs/scripts/metadata/Music/lyrics/darklyrics.py
    index 8c3363d459..9b0a9250a8 100644
    a b scraper by smory  
    66"""
    77
    88import hashlib
    9 import urllib2
     9try:
     10    from urllib2 import quote, urlopen
     11except ImportError:
     12    from urllib.request import urlopen
     13    from urllib.parse import quote
    1014import re
    1115import chardet
    1216import sys
    from common import utilities  
    1620__author__      = "Paul Harrison and smory'"
    1721__title__       = "DarkLyrics"
    1822__description__ = "Search http://www.darklyrics.com/ - the largest metal lyrics archive on the Web"
    19 __priority__    = "180";
     23__priority__    = "180"
    2024__version__     = "0.1"
    21 __syncronized__ = False;
     25__syncronized__ = False
    2226
    2327debug = False
    2428
    class LyricsFetcher:  
    2933        self.searchUrl = "http://www.darklyrics.com/search?q=%term%"
    3034
    3135    def search(self, artist, title):
    32         term = urllib2.quote((artist if artist else "") + " " + (title if title else ""));
     36        term = quote((artist if artist else "") + " " + (title if title else ""))
    3337
    3438        try:
    35             request = urllib2.urlopen(self.searchUrl.replace("%term%", term))
    36             searchResponse = request.read();
     39            request = urlopen(self.searchUrl.replace("%term%", term))
     40            searchResponse = request.read()
    3741        except:
    3842            return None
    3943
    40         searchResult = re.findall("<h2><a\shref=\"(.*?#([0-9]+))\".*?>(.*?)</a></h2>", searchResponse);
     44        searchResult = re.findall(b"<h2><a\shref=\"(.*?#([0-9]+))\".*?>(.*?)</a></h2>", searchResponse)
    4145
    4246        if len(searchResult) == 0:
    43             return None;
     47            return None
    4448
    45         links = [];
     49        links = []
    4650
    47         i = 0;
     51        i = 0
    4852        for result in searchResult:
    49             a = [];
    50             a.append(result[2] + ( " " + self.getAlbumName(self.base_url + result[0]) if i < 6 else "")); # title from server + album nane
    51             a.append(self.base_url + result[0]);  # url with lyrics
    52             a.append(artist);
    53             a.append(title);
    54             a.append(result[1]); # id of the side part containing this song lyrics
    55             links.append(a);
    56             i += 1;
     53            a = []
     54            a.append(result[2] + ( b" " + self.getAlbumName(self.base_url + result[0].decode('utf-8') )if i < 6 else b"")) # title from server + album nane
     55            a.append(self.base_url + result[0].decode('utf-8'))  # url with lyrics
     56            a.append(artist)
     57            a.append(title)
     58            a.append(result[1]) # id of the side part containing this song lyrics
     59            links.append(a)
     60            i += 1
    5761
    58         return links;
     62        return links
    5963
    6064    def findLyrics(self, url, index):
    6165        try:
    62             request = urllib2.urlopen(url);
    63             res = request.read();
     66            request = urlopen(url)
     67            res = request.read()
    6468        except:
    6569            return None
    6670
    67         pattern = "<a\sname=\"%index%\">(.*?)(?:<h3>|<div)";  # require multi line and dot all mode
    68         pattern = pattern.replace("%index%", index);
     71        pattern = b"<a\sname=\"%index%\">(.*?)(?:<h3>|<div)"  # require multi line and dot all mode
     72        pattern = pattern.replace(b"%index%", index)
    6973
    70         match = re.search(pattern, res, re.MULTILINE | re.DOTALL);
     74        match = re.search(pattern, res, re.MULTILINE | re.DOTALL)
    7175        if match: 
    72             s = match.group(1);
    73             s = s.replace("<br />", "");
    74             s = s.replace("<i>", "");
    75             s = s.replace("</i>", "");
    76             s = s.replace("</a>", "");
    77             s = s.replace("</h3>", "");
    78             return s;
     76            s = match.group(1)
     77            s = s.replace(b"<br />", b"")
     78            s = s.replace(b"<i>", b"")
     79            s = s.replace(b"</i>", b"")
     80            s = s.replace(b"</a>", b"")
     81            s = s.replace(b"</h3>", b"")
     82            return s
    7983        else:
    80             return None;
     84            return None
    8185
    8286    def getAlbumName(self, url):
    8387        try:
    84             request = urllib2.urlopen(url);
    85             res = request.read();
     88            request = urlopen(url)
     89            res = request.read()
    8690        except:
    87             return "";
     91            return b""
    8892
    89         match = re.search("<h2>(?:album|single|ep|live):?\s?(.*?)</h2>", res, re.IGNORECASE);
     93        match = re.search(b"<h2>(?:album|single|ep|live):?\s?(.*?)</h2>", res, re.IGNORECASE)
    9094
    9195        if match:
    92             return ("(" + match.group(1) + ")").replace("\"", "");
     96            ret = (b"(" + match.group(1) + b")").replace(b"\"", b"")
    9397        else:
    94             return "";
     98            ret = b""
     99        return(ret)
     100           
     101           
    95102
    96103    def get_lyrics(self, lyrics):
    97104        utilities.log(debug, "%s: searching lyrics for %s - %s - %s" % (__title__, lyrics.artist, lyrics.album, lyrics.title))
    98         links = self.search(lyrics.artist, lyrics.title);
     105        links = self.search(lyrics.artist, lyrics.title)
    99106
    100107        if(links == None or len(links) == 0):
    101             return False;
     108            return False
    102109        elif len(links) > 1:
    103110            lyrics.list = links
    104111
    class LyricsFetcher:  
    109116        enc = chardet.detect(lyr)
    110117        lyr = lyr.decode(enc['encoding'], 'ignore')
    111118        lyrics.lyrics = lyr
    112         return True;
     119        return True
    113120
    114121    def get_lyrics_from_list(self, link):
    115         title, url, artist, song, index = link;
    116         return self.findLyrics(url, index);
     122        title, url, artist, song, index = link
     123        return self.findLyrics(url, index)
    117124
    118125def performSelfTest():
    119126    found = False
    def performSelfTest():  
    129136
    130137    if found:
    131138        utilities.log(True, "Everything appears in order.")
     139        buildLyrics(lyrics)
    132140        sys.exit(0)
    133141
    134142    utilities.log(True, "The lyrics for the test search failed!")
    def buildLyrics(lyrics):  
    148156        line2 = re.sub(u'[^\u0020-\uD7FF\u0009\u000A\u000D\uE000-\uFFFD\u10000-\u10FFFF]+', '', line)
    149157        etree.SubElement(xml, "lyric").text = line2
    150158
    151     utilities.log(True, etree.tostring(xml, encoding='UTF-8', pretty_print=True,
    152                                     xml_declaration=True))
     159    utilities.log(True, utilities.convert_etree(etree.tostring(xml, encoding='UTF-8',
     160                                      pretty_print=True, xml_declaration=True)))
    153161    sys.exit(0)
    154162
    155163def buildVersion():
    def buildVersion():  
    164172    etree.SubElement(version, "priority").text = __priority__
    165173    etree.SubElement(version, "syncronized").text = 'True' if __syncronized__ else 'False'
    166174
    167     utilities.log(True, etree.tostring(version, encoding='UTF-8', pretty_print=True,
    168                                     xml_declaration=True))
     175    utilities.log(True, utilities.convert_etree(etree.tostring(version, encoding='UTF-8',
     176                                      pretty_print=True, xml_declaration=True)))
    169177    sys.exit(0)
    170178
    171179def main():
  • mythtv/programs/scripts/metadata/Music/lyrics/embedlrc.py

    diff --git a/mythtv/programs/scripts/metadata/Music/lyrics/embedlrc.py b/mythtv/programs/scripts/metadata/Music/lyrics/embedlrc.py
    index f3d36484f6..3f5815c243 100644
    a b class LyricsFetcher:  
    124124    def get_lyrics(self, lyrics):
    125125        utilities.log(debug, "%s: searching lyrics for %s - %s - %s" % (__title__, lyrics.artist, lyrics.album, lyrics.title))
    126126
    127         filename = lyrics.filename.decode("utf-8")
     127        if utilities.IS_PY2:
     128            filename = lyrics.filename.decode("utf-8")
     129        else:
     130            filename = lyrics.filename
     131
    128132        ext = os.path.splitext(filename)[1].lower()
    129133        lry = None
    130134
    def performSelfTest():  
    173177
    174178    if found:
    175179        utilities.log(True, "Everything appears in order.")
     180        buildLyrics(lyrics)
    176181        sys.exit(0)
    177182
    178183    utilities.log(True, "The lyrics for the test search failed!")
    def buildLyrics(lyrics):  
    191196    for line in lines:
    192197        etree.SubElement(xml, "lyric").text = line
    193198
    194     utilities.log(True, etree.tostring(xml, encoding='UTF-8', pretty_print=True,
    195                                     xml_declaration=True))
     199    utilities.log(True,  utilities.convert_etree(etree.tostring(xml, encoding='UTF-8',
     200                                                 pretty_print=True, xml_declaration=True)))
    196201    sys.exit(0)
    197202
    198203def buildVersion():
    def buildVersion():  
    207212    etree.SubElement(version, "priority").text = __priority__
    208213    etree.SubElement(version, "syncronized").text = 'True' if __syncronized__ else 'False'
    209214
    210     utilities.log(True, etree.tostring(version, encoding='UTF-8', pretty_print=True,
    211                                     xml_declaration=True))
     215    utilities.log(True,  utilities.convert_etree(etree.tostring(version, encoding='UTF-8',
     216                                                 pretty_print=True, xml_declaration=True)))
    212217    sys.exit(0)
    213218
    214219def main():
  • mythtv/programs/scripts/metadata/Music/lyrics/filelyrics.py

    diff --git a/mythtv/programs/scripts/metadata/Music/lyrics/filelyrics.py b/mythtv/programs/scripts/metadata/Music/lyrics/filelyrics.py
    index bf34f2e29d..7aadb9dd52 100644
    a b class LyricsFetcher:  
    2626    def get_lyrics(self, lyrics):
    2727        utilities.log(debug, "%s: searching lyrics for %s - %s - %s" % (__title__, lyrics.artist, lyrics.album, lyrics.title))
    2828
    29         filename = lyrics.filename.decode("utf-8")
     29        if utilities.IS_PY2:
     30            filename = lyrics.filename.decode("utf-8")
     31        else:
     32            filename = lyrics.filename
    3033        filename = os.path.splitext(filename)[0]
    3134
    3235        # look for a file ending in .lrc with the same filename as the track minus the extension
    def buildLyrics(lyrics):  
    8386    for line in lines:
    8487        etree.SubElement(xml, "lyric").text = line
    8588
    86     utilities.log(True, etree.tostring(xml, encoding='UTF-8', pretty_print=True,
    87                                     xml_declaration=True))
     89    utilities.log(True, utilities.convert_etree(etree.tostring(xml, encoding='UTF-8',
     90                                      pretty_print=True, xml_declaration=True)))
    8891
    8992def buildVersion():
    9093    from lxml import etree
    def buildVersion():  
    98101    etree.SubElement(version, "priority").text = __priority__
    99102    etree.SubElement(version, "syncronized").text = 'True' if __syncronized__ else 'False'
    100103
    101     utilities.log(True, etree.tostring(version, encoding='UTF-8', pretty_print=True,
    102                                     xml_declaration=True))
     104    utilities.log(True, utilities.convert_etree(etree.tostring(version, encoding='UTF-8',
     105                                      pretty_print=True, xml_declaration=True)))
    103106    sys.exit(0)
    104107
    105108def main():
  • mythtv/programs/scripts/metadata/Music/lyrics/genius.py

    diff --git a/mythtv/programs/scripts/metadata/Music/lyrics/genius.py b/mythtv/programs/scripts/metadata/Music/lyrics/genius.py
    index a07d1ff489..3b163b781e 100644
    a b Scraper for http://www.genius.com  
    55taxigps
    66"""
    77import sys
    8 import urllib
    9 import urllib2
     8try:
     9    from urllib2 import quote, urlopen, Request
     10except ImportError:     
     11    from urllib.request import urlopen, Request
     12    from urllib.parse import quote
     13try:
     14    import HTMLParser as html_parser
     15except ImportError:             
     16        from html import parser as html_parser 
    1017import socket
    1118import re
    12 import chardet
    13 import HTMLParser
    1419from hashlib import md5
    15 import chardet
    1620import difflib
    1721from optparse import OptionParser
    1822from common import utilities
    class LyricsFetcher:  
    4246        utilities.log(debug, "%s: searching lyrics for %s - %s - %s" % (__title__, lyrics.artist, lyrics.album, lyrics.title))
    4347
    4448        try:
    45             request = urllib2.Request(self.url % (urllib2.quote(lyrics.artist), '%20', urllib2.quote(lyrics.title)))
     49            request = Request(self.url % (quote(lyrics.artist), '%20', quote(lyrics.title)))
    4650            request.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.1; rv:25.0) Gecko/20100101 Firefox/25.0')
    47             req = urllib2.urlopen(request)
    48             response = req.read()
     51            req = urlopen(request)
     52            response = req.read().decode('utf-8')
    4953        except:
    5054            return False
    5155
    class LyricsFetcher:  
    6064        utilities.log(debug, "%s: search url: %s" % (__title__, self.page))
    6165
    6266        try:
    63             request = urllib2.Request(self.page)
     67            request = Request(self.page)
    6468            request.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.1; rv:25.0) Gecko/20100101 Firefox/25.0')
    65             req = urllib2.urlopen(request)
    66             response = req.read()
     69            req = urlopen(request)
     70            response = req.read().decode('utf-8')
    6771        except:
    6872            return False
    6973
    7074        req.close()
    71         matchcode = re.search('<div class="lyrics">(.*?)</div>', response, flags=re.DOTALL)
     75        matchcode = re.search(u'<div class="lyrics">(.*?)</div>', response, flags=re.DOTALL)
    7276
    7377        try:
    7478            lyricscode = (matchcode.group(1))
    75             htmlparser = HTMLParser.HTMLParser()
    76             lyricstext = htmlparser.unescape(lyricscode).replace('<br />', '\n')
    77             templyr = re.sub('<[^<]+?>', '', lyricstext)
    78             lyr = re.sub('\[(.*?)\]', '', templyr)
    79             lyrics.lyrics = lyr.strip().replace('\n\n\n', '\n\n')
     79            htmlparser = html_parser.HTMLParser()
     80            lyricstext = htmlparser.unescape(lyricscode).replace(u'<br />', u'\n')
     81            templyr = re.sub(u'<[^<]+?>', '', lyricstext)
     82            lyr = re.sub(u'\[(.*?)\]', '', templyr)
     83            lyrics.lyrics = lyr.strip().replace(u'\n\n\n', u'\n\n')
    8084            return True
    8185        except:
    8286            return False
    def performSelfTest():  
    96100
    97101    if found:
    98102        utilities.log(True, "Everything appears in order.")
     103        buildLyrics(lyrics)
    99104        sys.exit(0)
    100105
    101106    utilities.log(True, "The lyrics for the test search failed!")
    def buildLyrics(lyrics):  
    114119    for line in lines:
    115120        etree.SubElement(xml, "lyric").text = line
    116121
    117     utilities.log(True, etree.tostring(xml, encoding='UTF-8', pretty_print=True,
    118                                        xml_declaration=True))
     122    utilities.log(True,  utilities.convert_etree(etree.tostring(xml, encoding='UTF-8',
     123                                                 pretty_print=True, xml_declaration=True)))
    119124    sys.exit(0)
    120125
    121126def buildVersion():
    def buildVersion():  
    130135    etree.SubElement(version, "priority").text = __priority__
    131136    etree.SubElement(version, "syncronized").text = 'True' if __syncronized__ else 'False'
    132137
    133     utilities.log(True, etree.tostring(version, encoding='UTF-8', pretty_print=True,
    134                                        xml_declaration=True))
     138    utilities.log(True, utilities.convert_etree(etree.tostring(version, encoding='UTF-8',
     139                                                pretty_print=True, xml_declaration=True)))
    135140    sys.exit(0)
    136141
    137142def main():
  • mythtv/programs/scripts/metadata/Music/lyrics/lyricscom.py

    diff --git a/mythtv/programs/scripts/metadata/Music/lyrics/lyricscom.py b/mythtv/programs/scripts/metadata/Music/lyrics/lyricscom.py
    index 14993c8fb4..9ce9e1a185 100644
    a b ronie  
    77
    88import sys
    99import re
    10 import urllib
    11 import urllib2
     10try:
     11    from urllib import quote_plus
     12    from urllib2 import urlopen
     13except ImportError:     
     14    from urllib.parse import quote_plus
     15    from urllib.request import urlopen
     16
    1217import socket
    1318import difflib
    1419from optparse import OptionParser
    class LyricsFetcher:  
    3944            return False
    4045
    4146        try:
    42             request = urllib2.urlopen(self.url % urllib.quote_plus(lyrics.artist))
     47            request = urlopen(self.url % quote_plus(lyrics.artist))
    4348            response = request.read()
    4449        except:
    4550            return False
    class LyricsFetcher:  
    5459        if url:
    5560            utilities.log(debug, "%s: Artist url is %s"  % (__title__, url))
    5661            try:
    57                 req = urllib2.urlopen(url)
    58                 resp = req.read()
     62                req = urlopen(url)
     63                resp = req.read().decode('utf-8')
    5964            except:
    6065                return False
    6166            req.close()
    class LyricsFetcher:  
    7075                utilities.log(debug, "%s: Song url is %s"  % (__title__, url))
    7176
    7277                try:
    73                     req2 = urllib2.urlopen(url)
    74                     resp2 = req2.read()
     78                    req2 = urlopen(url)
     79                    resp2 = req2.read().decode('utf-8')
    7580                except:
    7681                    return False
    7782                req2.close()
    7883
    79                 matchcode = re.search('<pre.*?>(.*?)</pre>', resp2, flags=re.DOTALL)
     84                matchcode = re.search(u'<pre.*?>(.*?)</pre>', resp2, flags=re.DOTALL)
    8085                if matchcode:
    8186                    lyricscode = (matchcode.group(1))
    82                     lyr = re.sub('<[^<]+?>', '', lyricscode)
     87                    lyr = re.sub(u'<[^<]+?>', '', lyricscode)
    8388                    lyrics.lyrics = lyr.replace('\\n','\n')
    8489                    return True
    8590
    def performSelfTest():  
    105110
    106111    if found:
    107112        utilities.log(True, "Everything appears in order.")
     113        buildLyrics(lyrics)
    108114        sys.exit(0)
    109115
    110116    utilities.log(True, "The lyrics for the test search failed!")
    def buildLyrics(lyrics):  
    123129    for line in lines:
    124130        etree.SubElement(xml, "lyric").text = line
    125131
    126     utilities.log(True, etree.tostring(xml, encoding='UTF-8', pretty_print=True,
    127                                     xml_declaration=True))
     132    utilities.log(True, utilities.convert_etree(etree.tostring(xml, encoding='UTF-8',
     133                                                pretty_print=True, xml_declaration=True)))
    128134    sys.exit(0)
    129135
    130136def buildVersion():
    def buildVersion():  
    139145    etree.SubElement(version, "priority").text = __priority__
    140146    etree.SubElement(version, "syncronized").text = 'True' if __syncronized__ else 'False'
    141147
    142     utilities.log(True, etree.tostring(version, encoding='UTF-8', pretty_print=True,
    143                                     xml_declaration=True))
     148    utilities.log(True, utilities.convert_etree(etree.tostring(version, encoding='UTF-8',
     149                                                pretty_print=True, xml_declaration=True)))
    144150    sys.exit(0)
    145151
    146152def main():
  • mythtv/programs/scripts/metadata/Music/lyrics/lyricsmode.py

    diff --git a/mythtv/programs/scripts/metadata/Music/lyrics/lyricsmode.py b/mythtv/programs/scripts/metadata/Music/lyrics/lyricsmode.py
    index b89c085416..e194c4171f 100644
    a b  
    11#-*- coding: UTF-8 -*-
    22import sys
    3 import urllib
     3
     4try:
     5    from urllib import urlopen, quote_plus
     6except ImportError:     
     7    from urllib.request import urlopen
     8    from urllib.parse import quote_plus
     9
    410import re
    511from optparse import OptionParser
    612from common import utilities
    class LyricsFetcher:  
    3238            lyrics_found = False
    3339            while True:
    3440                utilities.log(debug, "%s: search url: %s" % (__title__, url))
    35                 song_search = urllib.urlopen(url).read()
     41                song_search = urlopen(url).read()
    3642                if song_search.find("<p id=\"lyrics_text\" class=\"ui-annotatable\">") >= 0:
    3743                    break
    3844
    class LyricsFetcher:  
    4349
    4450                # Let's try to use the research box if we didn't yet
    4551                if not 'search' in url:
    46                     url = "http://www.lyricsmode.com/search.php?what=songs&s=" + urllib.quote_plus(title.lower())
     52                    url = "http://www.lyricsmode.com/search.php?what=songs&s=" + quote_plus(title.lower())
    4753                else:
    4854                    # the search gave more than on result, let's try to find our song
    4955                    url = ""
    def performSelfTest():  
    102108
    103109    if found:
    104110        utilities.log(True, "Everything appears in order.")
     111        buildLyrics(lyrics)
    105112        sys.exit(0)
    106113
    107114    utilities.log(True, "The lyrics for the test search failed!")
    def buildLyrics(lyrics):  
    120127    for line in lines:
    121128        etree.SubElement(xml, "lyric").text = line
    122129
    123     utilities.log(True, etree.tostring(xml, encoding='UTF-8', pretty_print=True,
    124                                        xml_declaration=True))
     130    utilities.log(True,  utilities.convert_etree(etree.tostring(xml, encoding='UTF-8',
     131                                                 pretty_print=True, xml_declaration=True)))
    125132    sys.exit(0)
    126133
    127134def buildVersion():
    def buildVersion():  
    136143    etree.SubElement(version, "priority").text = __priority__
    137144    etree.SubElement(version, "syncronized").text = 'True' if __syncronized__ else 'False'
    138145
    139     utilities.log(True, etree.tostring(version, encoding='UTF-8', pretty_print=True,
    140                                        xml_declaration=True))
     146    utilities.log(True,  utilities.convert_etree(etree.tostring(version, encoding='UTF-8',
     147                                                 pretty_print=True, xml_declaration=True)))
    141148    sys.exit(0)
    142149
    143150def main():
  • mythtv/programs/scripts/metadata/Music/lyrics/lyricswiki.py

    diff --git a/mythtv/programs/scripts/metadata/Music/lyrics/lyricswiki.py b/mythtv/programs/scripts/metadata/Music/lyrics/lyricswiki.py
    index bcda8959f7..34179c180c 100644
    a b  
    11#-*- coding: UTF-8 -*-
    2 import sys, re, urllib2, socket, HTMLParser
     2
     3import sys, re, socket
     4
     5try:
     6    from urllib2 import quote, urlopen, HTTPError
     7except ImportError:     
     8    from urllib.request import urlopen, HTTPError
     9    from urllib.parse import quote     
     10       
     11try:
     12    import HTMLParser as html_parser
     13except ImportError:             
     14        from html import parser as html_parser
     15
    316from optparse import OptionParser
    417
    518if sys.version_info < (2, 7):
    class LyricsFetcher:  
    3144        utilities.log(debug,  "%s: searching lyrics for %s - %s - %s" % (__title__, lyrics.artist, lyrics.album, lyrics.title))
    3245
    3346        try:
    34             req = urllib2.urlopen(self.url % (urllib2.quote(lyrics.artist), urllib2.quote(lyrics.title)))
    35             response = req.read()
     47            req = urlopen(self.url % (quote(lyrics.artist), quote(lyrics.title)))
     48            response = req.read().decode('utf-8')
    3649        except:
    3750            return False
    3851        req.close()
    class LyricsFetcher:  
    4457        if not self.page.endswith('action=edit'):
    4558            utilities.log(debug, "%s: search url: %s" % (__title__, self.page))
    4659            try:
    47                 req = urllib2.urlopen(self.page)
    48                 response = req.read()
    49             except urllib2.HTTPError, error: # strange... sometimes lyrics are returned with a 404 error
     60                req = urlopen(self.page)
     61                response = req.read().decode('utf-8')
     62            except HTTPError as error: # strange... sometimes lyrics are returned with a 404 error
    5063                if error.code == 404:
    51                     response = error.read()
     64                    response = error.read().decode('utf-8')
    5265                else:
    5366                    return False
    5467            req.close()
    5568            matchcode = re.search("lyricbox'>.*?(&#.*?)<div", response)
    5669            try:
    5770                lyricscode = (matchcode.group(1))
    58                 htmlparser = HTMLParser.HTMLParser()
     71                htmlparser = html_parser.HTMLParser()
    5972                lyricstext = htmlparser.unescape(lyricscode).replace('<br />', '\n')
    6073                lyr = re.sub('<[^<]+?>', '', lyricstext)
    6174                if LIC_TXT in lyr:
    def performSelfTest():  
    8194
    8295    if found:
    8396        utilities.log(True, "Everything appears in order.")
     97        buildLyrics(lyrics)
    8498        sys.exit(0)
    8599
    86100    utilities.log(True, "The lyrics for the test search failed!")
    def buildLyrics(lyrics):  
    99113    for line in lines:
    100114        etree.SubElement(xml, "lyric").text = line
    101115
    102     utilities.log(True, etree.tostring(xml, encoding='UTF-8', pretty_print=True,
    103                                        xml_declaration=True))
     116    utilities.log(True, utilities.convert_etree(etree.tostring(xml, encoding='UTF-8',
     117                                                pretty_print=True, xml_declaration=True)))
    104118    sys.exit(0)
    105119
    106120def buildVersion():
    def buildVersion():  
    115129    etree.SubElement(version, "priority").text = __priority__
    116130    etree.SubElement(version, "syncronized").text = 'True' if __syncronized__ else 'False'
    117131
    118     utilities.log(True, etree.tostring(version, encoding='UTF-8', pretty_print=True,
    119                                        xml_declaration=True))
     132    utilities.log(True, utilities.convert_etree(etree.tostring(version, encoding='UTF-8',
     133                                                pretty_print=True, xml_declaration=True)))
    120134    sys.exit(0)
    121135
    122136def main():
  • mythtv/programs/scripts/metadata/Music/lyrics/ttplayer.py

    diff --git a/mythtv/programs/scripts/metadata/Music/lyrics/ttplayer.py b/mythtv/programs/scripts/metadata/Music/lyrics/ttplayer.py
    index a573bce1c9..48a3898615 100644
    a b taxigps  
    88import os
    99import sys
    1010import socket
    11 import urllib
     11
     12try:
     13    from urllib import urlopen
     14except ImportError:
     15    from urllib.request import urlopen
     16
    1217import re
    1318import chardet
    1419import random
    class ttpClient(object):  
    108113        return tmp1
    109114
    110115    @staticmethod
    111     def EncodeArtTit(str):
     116    def EncodeArtTit(mystr):
    112117        rtn = ''
    113         uni = unicode(str, 'UTF-8')
    114         str = uni.encode('UTF-16')[2:]
    115         for i in range(len(str)):
    116             rtn += '%02x' % ord(str[i])
    117 
     118        if utilities.IS_PY2:
     119            uni = unicode(mystr, 'UTF-8')
     120            mystr = uni.encode('UTF-16')[2:]
     121            for i in range(len(mystr)):
     122                rtn += '%02x' % ord(mystr[i])
     123        else:
     124            uni = str(mystr)
     125            mystr = uni.encode('UTF-16')[2:]
     126            for i in range(len(mystr)):
     127                rtn += '%02x' % (mystr[i])
    118128        return rtn
    119129
    120130
    class LyricsFetcher:  
    145155
    146156        try:
    147157            url = self.LIST_URL %(ttpClient.EncodeArtTit(artist.replace(' ','').lower()), ttpClient.EncodeArtTit(title.replace(' ','').lower()))
    148             f = urllib.urlopen(url)
    149             Page = f.read()
     158            f = urlopen(url)
     159            Page = f.read().decode('utf-8')
    150160        except:
    151161            utilities.log(True, "%s: %s::%s (%d) [%s]" % (
    152162                   __title__, self.__class__.__name__,
    class LyricsFetcher:  
    168178            lyrics.list = links
    169179        for link in links:
    170180            lyr = self.get_lyrics_from_list(link)
    171             if lyr and lyr.startswith('['):
     181            if lyr and lyr.startswith(b'['):
    172182                enc = chardet.detect(lyr)
    173183                lyr = lyr.decode(enc['encoding'], 'ignore')
    174184                lyrics.lyrics = lyr
    class LyricsFetcher:  
    180190        utilities.log(debug, '%s %s %s' %(Id, artist, song))
    181191        try:
    182192            url = self.LYRIC_URL %(int(Id),ttpClient.CodeFunc(int(Id), artist + song), random.randint(0,0xFFFFFFFFFFFF))
    183             f = urllib.urlopen(url)
     193            f = urlopen(url)
    184194            Page = f.read()
    185195        except:
    186196            utilities.log(True, "%s: %s::%s (%d) [%s]" % (
    class LyricsFetcher:  
    190200                   sys.exc_info()[ 1 ]
    191201                   ))
    192202            return None
    193         if Page.startswith('['):
     203        if Page.startswith(b'['):
    194204            return Page
    195205        return ''
    196206
    def performSelfTest():  
    208218
    209219    if found:
    210220        utilities.log(True, "Everything appears in order.")
     221        buildLyrics(lyrics)
    211222        sys.exit(0)
    212223
    213224    utilities.log(True, "The lyrics for the test search failed!")
    def buildLyrics(lyrics):  
    226237    for line in lines:
    227238        etree.SubElement(xml, "lyric").text = line
    228239
    229     utilities.log(True, etree.tostring(xml, encoding='UTF-8', pretty_print=True,
    230                                        xml_declaration=True))
     240    utilities.log(True, utilities.convert_etree(etree.tostring(xml, encoding='UTF-8',
     241                                                pretty_print=True, xml_declaration=True)))
    231242    sys.exit(0)
    232243
    233244def buildVersion():
    def buildVersion():  
    242253    etree.SubElement(version, "priority").text = __priority__
    243254    etree.SubElement(version, "syncronized").text = 'True' if __syncronized__ else 'False'
    244255
    245     utilities.log(True, etree.tostring(version, encoding='UTF-8', pretty_print=True,
    246                                        xml_declaration=True))
     256    utilities.log(True, utilities.convert_etree(etree.tostring(version, encoding='UTF-8',
     257                                                pretty_print=True, xml_declaration=True)))
    247258    sys.exit(0)
    248259
    249260def main():
  • mythtv/programs/scripts/metadata/Music/mbutils.py

    diff --git a/mythtv/programs/scripts/metadata/Music/mbutils.py b/mythtv/programs/scripts/metadata/Music/mbutils.py
    index 2e63371f38..fa4fe6965a 100755
    a b from __future__ import print_function  
    1919from __future__ import unicode_literals
    2020from optparse import OptionParser
    2121import musicbrainzngs
     22from musicbrainzngs.compat import is_py2
    2223import sys
    2324import pprint
    2425
    musicbrainzngs.set_hostname("musicbrainz-mirror.eu:5000")  
    4243def log(debug, txt):
    4344    if debug:
    4445        print(txt)
     46       
     47def convert_etree(etostr):
     48    """lxml.etree.tostring is a bytes object in python3, and a str in python2.
     49    """
     50    if is_py2:
     51        return(etostr)
     52    else:
     53        return(etostr.decode())
    4554
    4655def search_releases(artist, album, limit):
    4756    from lxml import etree
    def search_releases(artist, album, limit):  
    5261
    5362    if not result['release-list']:
    5463        etree.SubElement(root, "error").text = "No Releases found"
    55         log(True, etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True))
     64        log(True, convert_etree(etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True)))
    5665        sys.exit(1)
    5766
    5867    for (idx, release) in enumerate(result['release-list']):
    def search_releases(artist, album, limit):  
    7281        if 'release-group' in release:
    7382            etree.SubElement(relNode, "releasegroup").text = release["release-group"]["id"]
    7483
    75     log(True, etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True))
     84    log(True, convert_etree(etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True)))
    7685
    7786    sys.exit(0)
    7887
    def search_artists(artist, limit):  
    93102            etree.SubElement(artistNode, "sort-name").text = artist['sort-name']
    94103    else:
    95104        etree.SubElement(root, "error").text = "No Artists found"
    96         log(True, etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True))
     105        log(True, convert_etree(etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True)))
    97106        sys.exit(1)
    98107
    99     log(True, etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True))
     108    log(True, convert_etree(etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True)))
    100109
    101110    sys.exit(0)
    102111
    def get_artist(artistid):  
    125134                    node.set("type", url['type'])
    126135    else:
    127136        etree.SubElement(root, "error").text = "MusicBrainz ID was not found"
    128         log(True, etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True))
     137        log(True, convert_etree(etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True)))
    129138        sys.exit(1)
    130139
    131     log(True, etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True))
     140    log(True, convert_etree(etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True)))
    132141    sys.exit(0)
    133142
    134143def find_coverart(release):
    def find_coverart(release):  
    141150    except musicbrainzngs.ResponseError as err:
    142151        if err.cause.code == 404:
    143152            etree.SubElement(root, "error").text = "Release ID not found"
    144             log(True, etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True))
     153            log(True, convert_etree(etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True)))
    145154            sys.exit(1)
    146155        else:
    147156            etree.SubElement(root, "error").text = "Received bad response from the MB server"
    148             log(True, etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True))
     157            log(True, convert_etree(etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True)))
    149158            sys.exit(1)
    150159
    151160    if debug:
    def find_coverart(release):  
    161170        etree.SubElement(imageNode, "thumb-small").text = image["thumbnails"]["small"]
    162171        etree.SubElement(imageNode, "thumb-large").text = image["thumbnails"]["large"]
    163172
    164     log(True, etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True))
     173    log(True, convert_etree(etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True)))
    165174    sys.exit(0)
    166175
    167176def find_coverart_releasegroup(releaseGroup):
    def find_coverart_releasegroup(releaseGroup):  
    174183    except musicbrainzngs.ResponseError as err:
    175184        if err.cause.code == 404:
    176185            etree.SubElement(root, "error").text = "Release ID not found"
    177             log(True, etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True))
     186            log(True, convert_etree(etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True)))
    178187            sys.exit(1)
    179188        else:
    180189            etree.SubElement(root, "error").text = "Received bad response from the MB server"
    181             log(True, etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True))
     190            log(True, convert_etree(etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True)))
    182191            sys.exit(1)
    183192
    184193    if debug:
    def find_coverart_releasegroup(releaseGroup):  
    194203        etree.SubElement(imageNode, "thumb-small").text = image["thumbnails"]["small"]
    195204        etree.SubElement(imageNode, "thumb-large").text = image["thumbnails"]["large"]
    196205
    197     log(True, etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True))
     206    log(True, convert_etree(etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True)))
    198207    sys.exit(0)
    199208
    200209def find_disc(cddrive):
    def find_disc(cddrive):  
    209218        toc = disc.toc_string
    210219    except discid.DiscError as err:
    211220        etree.SubElement(root, "error").text = "Failed to get discid ({})".format(str(err))
    212         log(True, etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True))
     221        log(True, convert_etree(etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True)))
    213222        sys.exit(1)
    214223
    215224    etree.SubElement(root, "discid").text = id
    def find_disc(cddrive):  
    221230    except musicbrainzngs.ResponseError as err:
    222231        if err.cause.code == 404:
    223232            etree.SubElement(root, "error").text = "Disc not found"
    224             log(True, etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True))
     233            log(True, convert_etree(etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True)))
    225234            sys.exit(1)
    226235        else:
    227236            etree.SubElement(root, "error").text = "Received bad response from the MB server"
    228             log(True, etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True))
     237            log(True, convert_etree(etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True)))
    229238            sys.exit(1)
    230239
    231240    # The result can either be a "disc" or a "cdstub"
    def find_disc(cddrive):  
    266275            etree.SubElement(stubnode, "barcode").text = result['cdstub']['barcode']
    267276    else:
    268277        etree.SubElement(root, "error").text = "No valid results"
    269         log(True, etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True))
     278        log(True, convert_etree(etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True)))
    270279        sys.exit(1)
    271280
    272     log(True, etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True))
     281    log(True, convert_etree(etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True)))
    273282    sys.exit(0)
    274283
    275284def buildVersion():
    def buildVersion():  
    281290    etree.SubElement(version, "description").text = __description__
    282291    etree.SubElement(version, "version").text = __version__
    283292
    284     log(True, etree.tostring(version, encoding='UTF-8', pretty_print=True,
    285                              xml_declaration=True))
     293    log(True, convert_etree(etree.tostring(version, encoding='UTF-8', pretty_print=True,
     294                             xml_declaration=True)))
    286295    sys.exit(0)
    287296
    288297def performSelfTest():