Mic92 / python-mpd2

Python library which provides a client interface for the Music Player Daemon.
GNU Lesser General Public License v3.0
352 stars 119 forks source link

playlist rename method can not process chinese characters on Win7? #6

Closed handsomegui closed 12 years ago

handsomegui commented 12 years ago

Hi Mic92,

I got a problem using python-mpd2 version 0.4.2.

I'm running: Python 2.7.3, PyQt4.9.1, mpd 0.16.8, Windows 7 professional SP1 ( English Edition)

The problem i got is the playlist rename method. My english is bad, but the following fuzzy code may give you some clues to understand what i mean:

import sys, mpd

sys.getfilesystemencoding() 'mbcs'

m = mpd.MPDClient() m.connect('localhost', 6600)

old_playlist_name = "大" # Name in Chinese which means 'Big' in English, and it is already existed in m.listplaylists() new_playlist_name = "New Name"

m.rename(old_playlist_name, new_playlist_name)

Error below (The same logic with the above code):

Traceback (most recent call last): File "xplayer.py", line 2171, in OKPressed handler.rename(self.selectedItem, givenName) File "c:\Python27\lib\site-packages\mpd.py", line 491, in decorator return wrapper(self, name, args, bound_decorator(self, returnValue)) File "c:\Python27\lib\site-packages\mpd.py", line 213, in _execute return retval() File "c:\Python27\lib\site-packages\mpd.py", line 486, in decorator return function(self, _args, *_kwargs) File "c:\Python27\lib\site-packages\mpd.py", line 314, in _fetch_nothing line = self._read_line() File "c:\Python27\lib\site-packages\mpd.py", line 235, in _read_line raise CommandError(error) mpd.CommandError: [50@0] {rename} No such playlist

The most strange thing is:

new_name = unicode(Chinese_Characters) m.save(new_name)

Works fine. So i really don't know why.

Please help, thanks a lot.

Mic92 commented 12 years ago

What happens if you use this code:

client = MPDClient(use_unicode=True)
old_playlist_name = u"大" 
new_playlist_name = "New Name"
m.rename(old_playlist_name, new_playlist_name)

or this:

client = MPDClient()
old_playlist_name = ("大").encode("utf-8")
new_playlist_name = "New Name"
m.rename(old_playlist_name, new_playlist_name)
handsomegui commented 12 years ago

Mic92, sorry to tell you that it doesn't work. Actually i tried every way i could think of.

Save a new Chinese named playlist is OK, but rename a existed Chinese named playlist is not work.

Please check below:


Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)]
Type "copyright", "credits" or "license" for more information.

IPython 0.12 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: import mpd, sys

In [2]: sys.getfilesystemencoding()
Out[2]: 'mbcs'

In [3]: old_playlist_name = u"大".encode("UTF-8")

In [4]: old_playlist_name
Out[4]: '\xe5\xa4\xa7'

In [5]: client = mpd.MPDClient()

In [6]: client.connect('localhost', 6600)

In [7]: client.listplaylists()
Out[7]: []

In [8]: client.save(old_playlist_name)

In [9]: client.listplaylists()
Out[9]: [{'last-modified': '2012-05-26T08:56:00Z', 'playlist': '\xe5\xa4\xa7'}]

In [10]: client.rename(old_playlist_name, "new_name")
---------------------------------------------------------------------------
CommandError                              Traceback (most recent call last)
C:\Documents and Settings\Administrator\<ipython-input-10-6dded4d6055c> in <modu
le>()
----> 1 client.rename(old_playlist_name, "new_name")

C:\Python27\lib\site-packages\mpd.pyc in decorator(self, *args)
    489 def newFunction(wrapper, name, returnValue):
    490     def decorator(self, *args):
--> 491         return wrapper(self, name, args, bound_decorator(self, returnVal
ue))
    492     return decorator
    493

C:\Python27\lib\site-packages\mpd.pyc in _execute(self, command, args, retval)
    211             self._write_command(command, args)
    212             if isinstance(retval, Callable):
--> 213                 return retval()
    214             return retval
    215

C:\Python27\lib\site-packages\mpd.pyc in decorator(*args, **kwargs)
    484     """ bind decorator to self """
    485     def decorator(*args, **kwargs):
--> 486         return function(self, *args, **kwargs)
    487     return decorator
    488

C:\Python27\lib\site-packages\mpd.pyc in _fetch_nothing(self)
    312
    313     def _fetch_nothing(self):
--> 314         line = self._read_line()
    315         if line is not None:
    316             raise ProtocolError("Got unexpected return value: '%s'" % li
ne)

C:\Python27\lib\site-packages\mpd.pyc in _read_line(self)
    233         if line.startswith(ERROR_PREFIX):
    234             error = line[len(ERROR_PREFIX):].strip()
--> 235             raise CommandError(error)
    236         if self._command_list is not None:
    237             if line == NEXT:

CommandError: [50@0] {rename} No such playlist

In [11]:
handsomegui commented 12 years ago

Mic92, for the other method you post, i tried, it failed too.

Like below:


Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)]
Type "copyright", "credits" or "license" for more information.

IPython 0.12 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: import mpd, sys

In [2]: sys.getfilesystemencoding()
Out[2]: 'mbcs'

In [3]: old_playlist_name = u"大"

In [4]: old_playlist_name
Out[4]: u'\u5927'

In [5]: client = mpd.MPDClient(use_unicode=True)

In [6]: client.connect('localhost', 6600)

In [7]: client.listplaylists()
Out[7]: []

In [8]: client.save(old_playlist_name)

In [9]: client.listplaylists()
Out[9]: [{u'last-modified': u'2012-05-26T09:11:01Z', u'playlist': u'\u5927'}]

In [10]: client.rename(old_playlist_name, "New_Name")
---------------------------------------------------------------------------
CommandError                              Traceback (most recent call last)
C:\Documents and Settings\Administrator\<ipython-input-10-fcec17c403c0> in <modu
le>()
----> 1 client.rename(old_playlist_name, "New_Name")

C:\Python27\lib\site-packages\mpd.pyc in decorator(self, *args)
    489 def newFunction(wrapper, name, returnValue):
    490     def decorator(self, *args):
--> 491         return wrapper(self, name, args, bound_decorator(self, returnVal
ue))
    492     return decorator
    493

C:\Python27\lib\site-packages\mpd.pyc in _execute(self, command, args, retval)
    211             self._write_command(command, args)
    212             if isinstance(retval, Callable):
--> 213                 return retval()
    214             return retval
    215

C:\Python27\lib\site-packages\mpd.pyc in decorator(*args, **kwargs)
    484     """ bind decorator to self """
    485     def decorator(*args, **kwargs):
--> 486         return function(self, *args, **kwargs)
    487     return decorator
    488

C:\Python27\lib\site-packages\mpd.pyc in _fetch_nothing(self)
    312
    313     def _fetch_nothing(self):
--> 314         line = self._read_line()
    315         if line is not None:
    316             raise ProtocolError("Got unexpected return value: '%s'" % li
ne)

C:\Python27\lib\site-packages\mpd.pyc in _read_line(self)
    233         if line.startswith(ERROR_PREFIX):
    234             error = line[len(ERROR_PREFIX):].strip()
--> 235             raise CommandError(error)
    236         if self._command_list is not None:
    237             if line == NEXT:

CommandError: [50@0] {rename} No such playlist

In [11]:
Mic92 commented 12 years ago

Actually this lines works for me on linux:

In [4]: client.connect('localhost', 6600)                                                                                                             

In [5]: client.listplaylists()                                                                                                                        
Out[5]: 
[{u'last-modified': u'2012-03-01T10:21:34Z', u'playlist': u'Favorites'},
 {u'last-modified': u'2012-05-26T11:16:23Z', u'playlist': u'New_Name'}]

In [6]: x = u"大"

In [7]: client.rename("New_Name",x)

In [8]: client.rename(x,"New_name")                                                                                                                   

In [9]: client.listplaylists()                                                                                                                        
Out[9]: 
[{u'last-modified': u'2012-05-26T11:16:23Z', u'playlist': u'New_name'},
 {u'last-modified': u'2012-03-01T10:21:34Z', u'playlist': u'Favorites'}]

In [10]: client.rename("New_name",x)                                                                                                                  

In [11]: client.listplaylists()                                                                                                                       
Out[11]: 
[{u'last-modified': u'2012-03-01T10:21:34Z', u'playlist': u'Favorites'},
 {u'last-modified': u'2012-05-26T11:16:23Z', u'playlist': u'\u5927'}]

If I look in my playlist directory, both are created properly:

$ ls /home/joerg/.mpd/playlists
Favorites.m3u  大.m3u

Is it possible that Windows don't support this character as a filename? Or maybe it's a combination of how mpd save filenames and Windows expects it.

Mic92 commented 12 years ago

Prove me wrong, but it seems that this error is outside of python-mpd scope. CommandError is raised, if mpd doesn't accept the command. You could test it, with netcat and a utf-8 capable terminal by hand:

$ nc -vv localhost 6600
OK MPD 0.16.0
rename "New_Name" "大"
OK
handsomegui commented 12 years ago

Thank you very much for your work, Mic92.

Before i do some testing you mentioned just now, i think the main difference between you operations and mine is:

I run MPD & python-mpd2 on Windows NOT Linux(or Mac OS X).

The above code we post also works fine on my linux box & Mac OS X, but not fine on Windows.

Since i was planning to write a cross-platform GUI for MPD by using PyQt4. So i need it can be run on Win/Mac/Linux.

For the question i ask, the question now is more about Windows-specific. So i post my OS information since the first post:

Windows 7 Professional Service Pack 1 (English Edition)

And the filesystem encoding of Windows system is got by python:

sys.getfilesystemencoding() 'mbcs'

Now i was stuck on this problem, is it even a bug of MPD? I'm not sure, i am a newbie.

Thanks again for you patient support.

Mic92 commented 12 years ago

You could alternate the filesystem_charset option to "UTF-16" in mpd.conf (Don't whether this helps). If you think it is a bug, you could visit the irc channel of mpd at freenode.net or open a bug in the mpd bugtracker.

As far as I understand 'mbcs' stands for multi-byte character sets. There are several MBCS encodings out there like Shift-JIS and EUC-JP, but filenames on Windows ntfs should be UTF-16.

handsomegui commented 12 years ago

After asked in the mailing list of MPD, I confirmed this is a bug of MPD. Please close this bug report of python-mpd2.

Thank you very much for your help, Mic92.