Skip to content

Commit a820a55

Browse files
committed
try and fix unicode filenames
1 parent 3655a10 commit a820a55

File tree

2 files changed

+70
-8
lines changed

2 files changed

+70
-8
lines changed

BigStash/upload.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626

2727
from __future__ import print_function
2828
import boto3
29+
import six
30+
import sys
2931
import os
3032
import errno
3133
import sys
@@ -44,9 +46,15 @@
4446
log = logging.getLogger('bigstash.upload')
4547

4648

49+
def smart_str(s):
50+
if isinstance(s, six.text_type):
51+
return s
52+
return s.decode('utf-8')
53+
54+
4755
class ProgressPercentage(object):
4856
def __init__(self, filename):
49-
self._filename = filename
57+
self._filename = smart_str(filename)
5058
self._size = os.path.getsize(filename)
5159
self._seen_so_far = 0
5260
self._lock = threading.Lock()
@@ -55,7 +63,7 @@ def _write_progress(self, wrote, total):
5563
percentage = 100
5664
if total > 0:
5765
percentage = (wrote / float(total)) * 100
58-
sys.stdout.write("\r{} {} / {} ({:.2f}%)".format(
66+
sys.stdout.write(u"\r{} {} / {} ({:.2f}%)".format(
5967
self._filename, wrote, total, percentage))
6068
sys.stdout.flush()
6169

@@ -72,7 +80,12 @@ def __call__(self, bytes_amount):
7280

7381

7482
def main():
75-
args = docopt(__doc__, version=__version__)
83+
argv = sys.argv
84+
if not six.PY3 and os.name == 'nt':
85+
from BigStash.winargvfix import fix_argv_on_windows, fix_env_on_windows
86+
argv = fix_argv_on_windows()
87+
fix_env_on_windows()
88+
args = docopt(__doc__, argv=argv[1:], version=__version__)
7689

7790
settings = BigStashAPISettings.load_settings()
7891
BigStashAPI.setup_logging(settings)
@@ -145,15 +158,12 @@ def bgst_settings(args, settings):
145158

146159
def bgst_put(args, settings):
147160
try:
148-
149161
title = args['--title'] if args['--title'] else None
150162
opt_silent = False if not args['--silent'] else True
151163
opt_dont_wait = False if not args['--dont-wait'] else True
152164
upload = None
153-
manifest, errors = Manifest.from_paths(
154-
paths=[f.decode('utf-8') for f in args['FILES']],
155-
title=title
156-
)
165+
filepaths = map(smart_str, args['FILES'])
166+
manifest, errors = Manifest.from_paths(paths=filepaths, title=title)
157167
if errors:
158168
errtext = [": ".join(e) for e in errors]
159169
print("\n".join(["There were errors:"] + errtext))

BigStash/winargvfix.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import os
2+
import sys
3+
from ctypes import (WINFUNCTYPE, windll, POINTER, byref, c_int,
4+
create_unicode_buffer, c_wchar_p)
5+
from ctypes.wintypes import LPWSTR, LPCWSTR
6+
7+
8+
def fix_env_on_windows():
9+
def getEnvironmentVariable(name):
10+
name= unicode(name) # make sure string argument is unicode
11+
n= windll.kernel32.GetEnvironmentVariableW(name, None, 0)
12+
if n==0:
13+
return None
14+
buf= create_unicode_buffer(u'\0'*n)
15+
windll.kernel32.GetEnvironmentVariableW(name, buf, n)
16+
return buf.value
17+
for k in os.environ.keys():
18+
os.environ[k] = getEnvironmentVariable(k).encode('utf-8')
19+
20+
21+
def fix_argv_on_windows():
22+
# This works around <http://bugs.python.org/issue2128>.
23+
GetCommandLineW = windll.kernel32.GetCommandLineW
24+
GetCommandLineW.restype = c_wchar_p
25+
CommandLineToArgvW = windll.shell32.CommandLineToArgvW
26+
CommandLineToArgvW.restype = POINTER(c_wchar_p)
27+
28+
argc = c_int(0)
29+
argv_unicode = CommandLineToArgvW(GetCommandLineW(), byref(argc))
30+
31+
argv = [argv_unicode[i].encode('utf-8') for i in range(0, argc.value)]
32+
33+
if not hasattr(sys, 'frozen'):
34+
# If this is an executable produced by py2exe or bbfreeze, then it will
35+
# have been invoked directly. Otherwise, unicode_argv[0] is the Python
36+
# interpreter, so skip that.
37+
argv = argv[1:]
38+
39+
# Also skip option arguments to the Python interpreter.
40+
while len(argv) > 0:
41+
arg = argv[0]
42+
if not arg.startswith("-") or arg == "-":
43+
break
44+
argv = argv[1:]
45+
if arg == '-m':
46+
# sys.argv[0] should really be the absolute path of the module source,
47+
# but never mind
48+
break
49+
if arg == '-c':
50+
argv[0] = '-c'
51+
break
52+
return argv

0 commit comments

Comments
 (0)