Beets: web: Use Unicode paths to send files on Windows under Python 2

Created on 14 Jun 2017  路  3Comments  路  Source: beetbox/beets

Hi,

beets version 1.4.3
Python version 2.7.11
plugins: web

Python 2.7.11 (v2.7.11:6d1b6a68f775, Dec 5 2015, 20:32:19) [MSC v.1500 32 bit (Intel)] on win32

Following flask error was encountered when calling item/file method for non-ascii items:

[2017-06-14 21:36:27,233] ERROR in app: Exception on /item/52117/file [GET]
Traceback (most recent call last):
  File "c:\python\lib\site-packages\flask\app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "c:\python\lib\site-packages\flask\app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "c:\python\lib\site-packages\flask_cors\extension.py", line 161, in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
  File "c:\python\lib\site-packages\flask\app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "c:\python\lib\site-packages\flask\app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "c:\python\lib\site-packages\flask\app.py", line 1598, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "c:\python\lib\site-packages\beetsplug\web\__init__.py", line 209, in item_file
    attachment_filename=os.path.basename(util.py3_path(item.path)),
  File "c:\python\lib\site-packages\flask\helpers.py", line 549, in send_file
    file = open(filename, 'rb')
IOError: [Errno 2] No such file or directory: 'PATH_REDACTED\\01 Marta Kubis\xcc\x8cova\xcc\x81 - Tak Dej Se K Na\xcc\x81m A Projdem Svet.flac'
127.0.0.1 - - [14/Jun/2017 21:36:27] "GET /item/52117/file HTTP/1.1" 500 -

https://github.com/beetbox/beets/blob/master/beetsplug/web/__init__.py

Unicode path fixes it for me:

def item_file(item_id):
    item = g.lib.get_item(item_id)
    response = flask.send_file(
        unicode(item.path, "utf-8", errors="ignore"),
        as_attachment=True,
        attachment_filename=os.path.basename(item.path),
    )
    response.headers['Content-Length'] = os.path.getsize(unicode(item.path, "utf-8", errors="ignore"))
    return response
bitesize bug

All 3 comments

Hi! Thanks for reporting this, and for investigating the problem.

Since you're on Windows, it does makes sense that Flask might want Unicode paths. Here's one other thing to try: can you try changing that argument to use util.syspath instead of util.py3_path? That is, the line would be:

        util.syspath(item.path),

Another alternative would be to try running beets under Python 3.6 instead of 2.7鈥擨 think this might "just work" in that setting.

Hi sampsyo,

thank you for quick reply and solution!

beets version 1.4.4

I can confirm following works:

def item_file(item_id):
    item = g.lib.get_item(item_id)
    response = flask.send_file(
        util.syspath(item.path),
        as_attachment=True,
        attachment_filename=os.path.basename(util.py3_path(item.path)),
    )
    response.headers['Content-Length'] = os.path.getsize(util.syspath(item.path))
    return response

Upgrading python definitely is something to consider .. eventually maybe ;)
Ciao

Thanks! That's helpful to know.

I think the solution is to use syspath on Windows and py3_path on other platforms. This should be a straightforward fix鈥攁 pull request would be very helpful if you have a chance!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Freso picture Freso  路  4Comments

nopoz picture nopoz  路  4Comments

vredesbyyrd picture vredesbyyrd  路  4Comments

lhupitr picture lhupitr  路  5Comments

udiboy1209 picture udiboy1209  路  3Comments