~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/win32utils.py

MergeĀ lp:~gz/bzr/path_from_environ_832028

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
"""
21
21
 
22
22
import glob
 
23
import operator
23
24
import os
24
25
import struct
25
26
import sys
26
27
 
27
 
from bzrlib import cmdline
 
28
from bzrlib import (
 
29
    cmdline,
 
30
    symbol_versioning,
 
31
    )
28
32
from bzrlib.i18n import gettext
29
33
 
30
34
# Windows version
63
67
else:
64
68
    if winver == 'Windows 98':
65
69
        create_buffer = ctypes.create_string_buffer
 
70
        def extract_buffer(buf):
 
71
            return buf.val.decode("mbcs")
66
72
        suffix = 'A'
67
73
    else:
68
74
        create_buffer = ctypes.create_unicode_buffer
 
75
        extract_buffer = operator.attrgetter("value")
69
76
        suffix = 'W'
70
77
try:
71
78
    import pywintypes
248
255
    one that moves with the user as they logon to different machines, and
249
256
    a 'local' one that stays local to the machine.  This returns the 'roaming'
250
257
    directory, and thus is suitable for storing user-preferences, etc.
251
 
 
252
 
    Returned value can be unicode or plain string.
253
 
    To convert plain string to unicode use
254
 
    s.decode(osutils.get_user_encoding())
255
 
    (XXX - but see bug 262874, which asserts the correct encoding is 'mbcs')
256
258
    """
257
259
    appdata = _get_sh_special_folder_path(CSIDL_APPDATA)
258
260
    if appdata:
259
261
        return appdata
260
 
    # from env variable
261
 
    appdata = os.environ.get('APPDATA')
262
 
    if appdata:
263
 
        return appdata
264
 
    # if we fall to this point we on win98
265
 
    # at least try C:/WINDOWS/Application Data
266
 
    windir = os.environ.get('windir')
267
 
    if windir:
268
 
        appdata = os.path.join(windir, 'Application Data')
269
 
        if os.path.isdir(appdata):
270
 
            return appdata
271
 
    # did not find anything
272
 
    return None
 
262
    # Use APPDATA if defined, will return None if not
 
263
    return get_environ_unicode('APPDATA')
273
264
 
274
265
 
275
266
def get_local_appdata_location():
281
272
    a 'local' one that stays local to the machine.  This returns the 'local'
282
273
    directory, and thus is suitable for caches, temp files and other things
283
274
    which don't need to move with the user.
284
 
 
285
 
    Returned value can be unicode or plain string.
286
 
    To convert plain string to unicode use
287
 
    s.decode(osutils.get_user_encoding())
288
 
    (XXX - but see bug 262874, which asserts the correct encoding is 'mbcs')
289
275
    """
290
276
    local = _get_sh_special_folder_path(CSIDL_LOCAL_APPDATA)
291
277
    if local:
292
278
        return local
293
279
    # Vista supplies LOCALAPPDATA, but XP and earlier do not.
294
 
    local = os.environ.get('LOCALAPPDATA')
 
280
    local = get_environ_unicode('LOCALAPPDATA')
295
281
    if local:
296
282
        return local
297
283
    return get_appdata_location()
302
288
    Assume on win32 it's the <My Documents> folder.
303
289
    If location cannot be obtained return system drive root,
304
290
    i.e. C:\
305
 
 
306
 
    Returned value can be unicode or plain string.
307
 
    To convert plain string to unicode use
308
 
    s.decode(osutils.get_user_encoding())
309
291
    """
310
292
    home = _get_sh_special_folder_path(CSIDL_PERSONAL)
311
293
    if home:
312
294
        return home
313
 
    # try for HOME env variable
314
 
    home = os.path.expanduser('~')
315
 
    if home != '~':
 
295
    home = get_environ_unicode('HOME')
 
296
    if home is not None:
316
297
        return home
 
298
    homepath = get_environ_unicode('HOMEPATH')
 
299
    if homepath is not None:
 
300
        return os.path.join(get_environ_unicode('HOMEDIR', ''), home)
317
301
    # at least return windows root directory
318
 
    windir = os.environ.get('windir')
 
302
    windir = get_environ_unicode('WINDIR')
319
303
    if windir:
320
304
        return os.path.splitdrive(windir)[0] + '/'
321
305
    # otherwise C:\ is good enough for 98% users
322
 
    return 'C:/'
 
306
    return unicode('C:/')
323
307
 
324
308
 
325
309
def get_user_name():
326
310
    """Return user name as login name.
327
311
    If name cannot be obtained return None.
328
 
 
329
 
    Returned value can be unicode or plain string.
330
 
    To convert plain string to unicode use
331
 
    s.decode(osutils.get_user_encoding())
332
312
    """
333
313
    if has_ctypes:
334
314
        try:
340
320
            buf = create_buffer(UNLEN+1)
341
321
            n = ctypes.c_int(UNLEN+1)
342
322
            if GetUserName(buf, ctypes.byref(n)):
343
 
                return buf.value
 
323
                return extract_buffer(buf)
344
324
    # otherwise try env variables
345
 
    return os.environ.get('USERNAME', None)
 
325
    return get_environ_unicode('USERNAME')
346
326
 
347
327
 
348
328
# 1 == ComputerNameDnsHostname, which returns "The DNS host name of the local
353
333
    """Return host machine name.
354
334
    If name cannot be obtained return None.
355
335
 
356
 
    :return: A unicode string representing the host name. On win98, this may be
357
 
        a plain string as win32 api doesn't support unicode.
 
336
    :return: A unicode string representing the host name.
358
337
    """
359
338
    if has_win32api:
360
339
        try:
377
356
            if (GetComputerNameEx is not None
378
357
                and GetComputerNameEx(_WIN32_ComputerNameDnsHostname,
379
358
                                      buf, ctypes.byref(n))):
380
 
                return buf.value
 
359
                return extract_buffer(buf)
381
360
 
382
361
            # Try GetComputerName in case GetComputerNameEx wasn't found
383
362
            # It returns the NETBIOS name, which isn't as good, but still ok.
387
366
                                      None)
388
367
            if (GetComputerName is not None
389
368
                and GetComputerName(buf, ctypes.byref(n))):
390
 
                return buf.value
391
 
    # otherwise try env variables, which will be 'mbcs' encoded
392
 
    # on Windows (Python doesn't expose the native win32 unicode environment)
393
 
    # According to this:
394
 
    # http://msdn.microsoft.com/en-us/library/aa246807.aspx
395
 
    # environment variables should always be encoded in 'mbcs'.
396
 
    try:
397
 
        return os.environ['COMPUTERNAME'].decode("mbcs")
398
 
    except KeyError:
399
 
        return None
400
 
 
401
 
 
 
369
                return extract_buffer(buf)
 
370
    return get_environ_unicode('COMPUTERNAME')
 
371
 
 
372
 
 
373
@symbol_versioning.deprecated_method(
 
374
    symbol_versioning.deprecated_in((2, 5, 0)))
402
375
def _ensure_unicode(s):
403
376
    if s and type(s) != unicode:
404
377
        from bzrlib import osutils
406
379
    return s
407
380
 
408
381
 
409
 
def get_appdata_location_unicode():
410
 
    return _ensure_unicode(get_appdata_location())
411
 
 
412
 
def get_home_location_unicode():
413
 
    return _ensure_unicode(get_home_location())
414
 
 
415
 
def get_user_name_unicode():
416
 
    return _ensure_unicode(get_user_name())
417
 
 
418
 
def get_host_name_unicode():
419
 
    return _ensure_unicode(get_host_name())
 
382
get_appdata_location_unicode = symbol_versioning.deprecated_method(
 
383
    symbol_versioning.deprecated_in((2, 5, 0)))(get_appdata_location)
 
384
 
 
385
get_home_location_unicode = symbol_versioning.deprecated_method(
 
386
    symbol_versioning.deprecated_in((2, 5, 0)))(get_home_location)
 
387
 
 
388
get_user_name_unicode = symbol_versioning.deprecated_method(
 
389
    symbol_versioning.deprecated_in((2, 5, 0)))(get_user_name)
 
390
 
 
391
get_host_name_unicode = symbol_versioning.deprecated_method(
 
392
    symbol_versioning.deprecated_in((2, 5, 0)))(get_host_name)
420
393
 
421
394
 
422
395
def _ensure_with_dir(path):
433
406
        return path
434
407
 
435
408
 
436
 
 
437
409
def glob_one(possible_glob):
438
410
    """Same as glob.glob().
439
411
 
609
581
                return buffer[:length]
610
582
            buffer_size = length
611
583
else:
612
 
    get_unicode_argv = get_environ_unicode = None
 
584
    get_unicode_argv = None
 
585
    def get_environ_unicode(key, default=None):
 
586
        """Get `key` from environment as unicode or `default` if unset
 
587
 
 
588
        Fallback version that should basically never be needed.
 
589
        """
 
590
        try:
 
591
            return os.environ[key].decode("mbcs")
 
592
        except KeyError:
 
593
            return default
613
594
 
614
595
 
615
596
if has_win32api: