16
16
# along with this program; if not, write to the Free Software
17
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
import os, types, re, time, types
19
import os, types, re, time, errno
20
20
from stat import S_ISREG, S_ISDIR, S_ISLNK, ST_MODE, ST_SIZE
22
from errors import bailout
22
from errors import bailout, BzrError
23
from trace import mutter
24
26
def make_readonly(filename):
25
27
"""Make a filename read-only."""
86
88
## XXX: Could alternatively read /proc/sys/kernel/random/uuid on
87
89
## Linux, but we need something portable for other systems;
88
90
## preferably an implementation in Python.
89
bailout('uuids not allowed!')
90
return chomp(os.popen('uuidgen').readline())
92
return chomp(file('/proc/sys/kernel/random/uuid').readline())
94
return chomp(os.popen('uuidgen').readline())
93
98
if s and (s[-1] == '\n'):
118
"""Return email-style username.
120
Something similar to 'Martin Pool <mbp@sourcefrog.net>'
122
:todo: Check it's reasonably well-formed.
124
:todo: Allow taking it from a dotfile to help people on windows
125
who can't easily set variables.
127
:todo: Cope without pwd module, which is only on unix.
129
e = os.environ.get('BZREMAIL') or os.environ.get('EMAIL')
122
def fingerprint_file(f):
128
return {'size': size,
129
'sha1': s.hexdigest()}
133
"""Return per-user configuration directory.
135
By default this is ~/.bzr.conf/
137
TODO: Global option --config-dir to override this.
139
return os.path.expanduser("~/.bzr.conf")
143
"""Calculate automatic user identification.
145
Returns (realname, email).
147
Only used when none is set in the environment or the id file.
149
This previously used the FQDN as the default domain, but that can
150
be very slow on machines where DNS is broken. So now we simply
155
# XXX: Any good way to get real user name on win32?
136
159
uid = os.getuid()
137
160
w = pwd.getpwuid(uid)
161
gecos = w.pw_gecos.decode(bzrlib.user_encoding)
162
username = w.pw_name.decode(bzrlib.user_encoding)
139
163
comma = gecos.find(',')
143
167
realname = gecos[:comma]
144
return '%s <%s@%s>' % (realname, w.pw_name, socket.getfqdn())
145
171
except ImportError:
148
import getpass, socket
149
return '<%s@%s>' % (getpass.getuser(), socket.getfqdn())
173
realname = username = getpass.getuser().decode(bzrlib.user_encoding)
175
return realname, (username + '@' + socket.gethostname())
179
"""Return the full user id from a file or environment variable.
181
TODO: Allow taking this from a file in the branch directory too
182
for per-branch ids."""
183
v = os.environ.get('BZREMAIL')
185
return v.decode(bzrlib.user_encoding)
188
return (open(os.path.join(config_dir(), "email"))
190
.decode(bzrlib.user_encoding)
193
if e.errno != errno.ENOENT:
196
v = os.environ.get('EMAIL')
198
return v.decode(bzrlib.user_encoding)
204
"""Return email-style username.
206
Something similar to 'Martin Pool <mbp@sourcefrog.net>'
208
TODO: Check it's reasonably well-formed.
214
name, email = _auto_user_id()
216
return '%s <%s>' % (name, email)
221
_EMAIL_RE = re.compile(r'[\w+.-]+@[\w+.-]+')
152
222
def user_email():
153
223
"""Return just the email component of a username."""
154
e = os.environ.get('BZREMAIL') or os.environ.get('EMAIL')
157
m = re.search(r'[\w+.-]+@[\w+.-]+', e)
226
m = _EMAIL_RE.search(e)
159
bailout('%r is not a reasonable email address' % e)
228
bailout("%r doesn't seem to contain a reasonable email address" % e)
160
229
return m.group(0)
163
import getpass, socket
164
return '%s@%s' % (getpass.getuser(), socket.getfqdn())
231
return _auto_user_id()[1]
169
235
def compare_files(a, b):
170
236
"""Returns true if equal in contents"""
171
237
# TODO: don't read the whole thing in one go.
172
result = a.read() == b.read()
177
def local_time_offset():
249
def local_time_offset(t=None):
250
"""Return offset of local zone from GMT, either at present or at time t."""
251
# python2.3 localtime() can't take None
255
if time.localtime(t).tm_isdst and time.daylight:
179
256
return -time.altzone
181
258
return -time.timezone