1395
1430
return self._get_best_value('_acceptable_keys')
1433
def ensure_config_dir_exists(path=None):
1434
"""Make sure a configuration directory exists.
1435
This makes sure that the directory exists.
1436
On windows, since configuration directories are 2 levels deep,
1437
it makes sure both the directory and the parent directory exists.
1441
if not os.path.isdir(path):
1442
if sys.platform == 'win32':
1443
parent_dir = os.path.dirname(path)
1444
if not os.path.isdir(parent_dir):
1446
'creating config parent directory: %r', parent_dir)
1447
os.mkdir(parent_dir)
1448
trace.mutter('creating config directory: %r', path)
1450
osutils.copy_ownership_from_path(path)
1453
def bazaar_config_dir():
1454
"""Return per-user configuration directory as unicode string
1456
By default this is %APPDATA%/bazaar/2.0 on Windows, ~/.bazaar on Mac OS X
1457
and Linux. On Mac OS X and Linux, if there is a $XDG_CONFIG_HOME/bazaar
1458
directory, that will be used instead
1460
TODO: Global option --config-dir to override this.
1462
base = osutils.path_from_environ('BZR_HOME')
1463
if sys.platform == 'win32':
1465
base = win32utils.get_appdata_location()
1467
base = win32utils.get_home_location()
1468
return osutils.pathjoin(base, 'bazaar', '2.0')
1470
xdg_dir = osutils.path_from_environ('XDG_CONFIG_HOME')
1472
xdg_dir = osutils.pathjoin(osutils._get_home_dir(), ".config")
1473
xdg_dir = osutils.pathjoin(xdg_dir, 'bazaar')
1474
if osutils.isdir(xdg_dir):
1476
"Using configuration in XDG directory %s." % xdg_dir)
1478
base = osutils._get_home_dir()
1479
return osutils.pathjoin(base, ".bazaar")
1483
"""Return per-user configuration directory as unicode string
1485
By default this is %APPDATA%/breezy on Windows, $XDG_CONFIG_HOME/breezy on
1486
Mac OS X and Linux. If the breezy config directory doesn't exist but
1487
the bazaar one (see bazaar_config_dir()) does, use that instead.
1489
# TODO: Global option --config-dir to override this.
1490
base = osutils.path_from_environ('BRZ_HOME')
1491
if sys.platform == 'win32':
1493
base = win32utils.get_appdata_location()
1495
base = win32utils.get_home_location()
1497
base = osutils.path_from_environ('XDG_CONFIG_HOME')
1499
base = osutils.pathjoin(osutils._get_home_dir(), ".config")
1500
breezy_dir = osutils.pathjoin(base, 'breezy')
1501
if osutils.isdir(breezy_dir):
1502
return (breezy_dir, 'breezy')
1503
# If the breezy directory doesn't exist, but the bazaar one does, use that:
1504
bazaar_dir = bazaar_config_dir()
1505
if osutils.isdir(bazaar_dir):
1507
"Using Bazaar configuration directory (%s)", bazaar_dir)
1508
return (bazaar_dir, 'bazaar')
1509
return (breezy_dir, 'breezy')
1513
"""Return per-user configuration directory as unicode string
1515
By default this is %APPDATA%/breezy on Windows, $XDG_CONFIG_HOME/breezy on
1516
Mac OS X and Linux. If the breezy config directory doesn't exist but
1517
the bazaar one (see bazaar_config_dir()) does, use that instead.
1519
return _config_dir()[0]
1522
def config_filename():
1523
"""Return per-user configuration ini file filename."""
1524
path, kind = _config_dir()
1525
if kind == 'bazaar':
1526
return osutils.pathjoin(path, 'bazaar.conf')
1528
return osutils.pathjoin(path, 'breezy.conf')
1531
def locations_config_filename():
1532
"""Return per-user configuration ini file filename."""
1533
return osutils.pathjoin(config_dir(), 'locations.conf')
1536
def authentication_config_filename():
1537
"""Return per-user authentication ini file filename."""
1538
return osutils.pathjoin(config_dir(), 'authentication.conf')
1541
def user_ignore_config_filename():
1542
"""Return the user default ignore filename"""
1543
return osutils.pathjoin(config_dir(), 'ignore')
1547
"""Return the directory name to store crash files.
1549
This doesn't implicitly create it.
1551
On Windows it's in the config directory; elsewhere it's /var/crash
1552
which may be monitored by apport. It can be overridden by
1555
if sys.platform == 'win32':
1556
return osutils.pathjoin(config_dir(), 'Crash')
1558
# XXX: hardcoded in apport_python_hook.py; therefore here too -- mbp
1560
return os.environ.get('APPORT_CRASH_DIR', '/var/crash')
1563
def xdg_cache_dir():
1564
# See http://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
1565
# Possibly this should be different on Windows?
1566
e = os.environ.get('XDG_CACHE_HOME', None)
1570
return os.path.expanduser('~/.cache')
1573
def _get_default_mail_domain(mailname_file='/etc/mailname'):
1574
"""If possible, return the assumed default email domain.
1576
:returns: string mail domain, or None.
1578
if sys.platform == 'win32':
1579
# No implementation yet; patches welcome
1582
f = open(mailname_file)
1583
except (IOError, OSError):
1586
domain = f.readline().strip()
1592
def default_email():
1593
v = os.environ.get('BRZ_EMAIL')
1596
v = v.decode(osutils.get_user_encoding())
1598
v = os.environ.get('EMAIL')
1601
v = v.decode(osutils.get_user_encoding())
1603
name, email = _auto_user_id()
1605
return u'%s <%s>' % (name, email)
1611
def _auto_user_id():
1612
"""Calculate automatic user identification.
1614
:returns: (realname, email), either of which may be None if they can't be
1617
Only used when none is set in the environment or the id file.
1619
This only returns an email address if we can be fairly sure the
1620
address is reasonable, ie if /etc/mailname is set on unix.
1622
This doesn't use the FQDN as the default domain because that may be
1623
slow, and it doesn't use the hostname alone because that's not normally
1624
a reasonable address.
1626
if sys.platform == 'win32':
1627
# No implementation to reliably determine Windows default mail
1628
# address; please add one.
1631
default_mail_domain = _get_default_mail_domain()
1632
if not default_mail_domain:
1638
w = pwd.getpwuid(uid)
1640
trace.mutter('no passwd entry for uid %d?' % uid)
1643
# we try utf-8 first, because on many variants (like Linux),
1644
# /etc/passwd "should" be in utf-8, and because it's unlikely to give
1645
# false positives. (many users will have their user encoding set to
1646
# latin-1, which cannot raise UnicodeError.)
1648
if isinstance(gecos, bytes):
1650
gecos = gecos.decode('utf-8')
1652
except UnicodeError:
1654
encoding = osutils.get_user_encoding()
1655
gecos = gecos.decode(encoding)
1656
except UnicodeError:
1657
trace.mutter("cannot decode passwd entry %s" % w)
1660
username = w.pw_name
1661
if isinstance(username, bytes):
1663
username = username.decode(encoding)
1664
except UnicodeError:
1665
trace.mutter("cannot decode passwd entry %s" % w)
1668
comma = gecos.find(',')
1672
realname = gecos[:comma]
1674
return realname, (username + '@' + default_mail_domain)
1398
1677
def parse_username(username):
1399
1678
"""Parse e-mail username and return a (name, address) tuple."""
1400
1679
match = re.match(r'(.*?)\s*<?([\w+.-]+@[\w+.-]+)>?', username)
1401
1680
if match is None:
1402
1681
return (username, '')
1403
return (match.group(1), match.group(2))
1683
return (match.group(1), match.group(2))
1406
1686
def extract_email_address(e):