3

I am relatively new to programming, and I have a small problem writing a python equivalent of Snip for spotify for ubuntu(linux) Somehow i can encode the title correctly, but am unable to encode the artist the same way

when i try to encode the artist in the same fashion i get this:

File "./songfinder.py", line 11, in currentplaying
    artiststr = str((metadata['xesam:artist']).encode('utf-8'))
AttributeError: 'dbus.Array' object has no attribute 'encode'

however the title is done exactly the same and that is working.

Code so far IS working but has for example \xd8 instead of Ø, and similar:

import dbus
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")

def currentplaying():
    metadata = spotify_properties.Get("org.mpris.MediaPlayer2.Player", "Metadata")
    title =  str((metadata['xesam:title']).encode('utf-8'))
    artiststr = str((metadata['xesam:artist']))
    if ("dbus.string" in artiststr.lower()):
        artists = artiststr.split("(u")
        artist = artists[1]
        artists = artist.split(")],")
        artist = artists[0]
        artist = artist.replace("(u", "")
    else:
        artist = "'unknown'"

    artist = (artist.replace("'",""))

    playing = (artist + " - " + title + "             ")
    return playing

#save playing to file.txt

relevant qna's: Replace non-ascii chars from a unicode string in Python

Why it does not resolve my problem: I would like to print/save the actual character, not replace it with similar ones

Community
  • 1
  • 1
Bjornolil
  • 33
  • 4

3 Answers3

0

The error you getting is not about unicode, it is about wrong type. Python complains that you trying to call string method encode from the array object. Which does not have this method.

The first this I would try is to remove redundant brackets here it getting artiststr like this: artiststr = str(metadata['xesam:artist']).

But I'm not sure this would work. If it doesn't work, you need to find out what type has metadata['xesam:artist']. Looks like it is not string, but array. So you need to fix the code which fills metadata['xesam:artist'] with data. You can try to use debugger or just print() function to find out the content of metadata['xesam:artist']. Or provide the relevant code in you question too.

Paul
  • 6,641
  • 8
  • 41
  • 56
  • Thanks for the help, with your information I was able to do a simple recoding to get it working. Thank you so much. the final solution: artiststr = str((metadata['xesam:artist'])[0].encode('utf-8')) – Bjornolil Sep 11 '16 at 09:01
  • No problem. :) Yes, it works, but you should be sure that there will not be more that one item it that dataset. – Paul Sep 11 '16 at 09:42
0

Final program, feel free to use if you like:

import time
import dbus
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")


def currentplaying():
    metadata = spotify_properties.Get("org.mpris.MediaPlayer2.Player", "Metadata")
    title =  str((metadata['xesam:title']).encode('utf-8'))
    artiststr = str((metadata['xesam:artist'])[0].encode('utf-8'))

    artist = artiststr



    playing = (artist + " - " + title + "             ")
    return playing

while True:

    filetxt = open("/home/USER/Desktop/currentsongspotify.txt", "r")
    oldtitle = filetxt.read()
    filetxt.close()

    newtitle = str(currentplaying())


    if(newtitle == oldtitle):
        time.sleep(1)
    else:
        filetxt = open("/home/USER/Desktop/currentsongspotify.txt", "w")    #save newtitle to file, overwriting existing data
        filetxt.write(str(newtitle))
        print("new file saved:  " + newtitle)
Bjornolil
  • 33
  • 4
0

Looking at your question metadata contains at least something like this with Unicode strings. The artist field seems to be some sort of iterable the begins with the artist. Something like this (feel free to post actual metadata content):

metadata = {'xesam:title':u'title','xesam:artist':[u'artist']}

In the title assignment line, str is unnecessary since encoding a Unicode string returns a str anyway, but no need to encode it either. Unicode strings represent text, so leave it that way:

title =  metadata['xesam:title']

Similar for artist assignment, but get the first element of the iterable:

artist = metadata['xesam:artist'][0]

Next, in your song-updating logic, use io.open to open the files with a UTF-8 encoding. This lets Unicode strings (text) be written directly and the file will handle the encoding. Also use a with statement to automatically close the file when the with ends.

Program with recommended changes:

import time
import dbus
import io
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")

def currentplaying():
    metadata = spotify_properties.Get("org.mpris.MediaPlayer2.Player", "Metadata")
    title =  metadata['xesam:title']
    artist = metadata['xesam:artist'][0]
    playing = artist + " - " + title + "             "
    return playing

while True:
    with io.open('currentsongspotify.txt', encoding='utf8') as filetxt:
        oldtitle = filetxt.read()
    newtitle = currentplaying()
    if newtitle == oldtitle:
        time.sleep(1)
    else:
        with io.open('currentsongspotify.txt','w',encoding='utf8') as filetxt: # save newtitle to file, overwriting existing data
            filetxt.write(newtitle)
        print 'new file saved:',newtitle
Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251