dmg-builder 26.0.17 → 26.0.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,39 +1,29 @@
1
- # -*- coding: utf-8 -*-
2
- from __future__ import unicode_literals
3
- from __future__ import division
4
-
5
- import struct
6
1
  import datetime
7
2
  import io
8
- import re
9
3
  import os
10
4
  import os.path
11
- import stat
5
+ import struct
12
6
  import sys
7
+ from unicodedata import normalize
13
8
 
14
- if sys.platform == 'darwin':
9
+ if sys.platform == "darwin":
15
10
  from . import osx
16
11
 
17
- try:
18
- long
19
- except NameError:
20
- long = int
21
-
22
- from .utils import *
12
+ from .utils import mac_epoch
23
13
 
24
14
  ALIAS_KIND_FILE = 0
25
15
  ALIAS_KIND_FOLDER = 1
26
16
 
27
- ALIAS_HFS_VOLUME_SIGNATURE = b'H+'
17
+ ALIAS_HFS_VOLUME_SIGNATURE = b"H+"
28
18
 
29
- ALIAS_FILESYSTEM_UDF = 'UDF (CD/DVD)'
30
- ALIAS_FILESYSTEM_FAT32 = 'FAT32'
31
- ALIAS_FILESYSTEM_EXFAT = 'exFAT'
32
- ALIAS_FILESYSTEM_HFSX = 'HFSX'
33
- ALIAS_FILESYSTEM_HFSPLUS = 'HFS+'
34
- ALIAS_FILESYSTEM_FTP = 'FTP'
35
- ALIAS_FILESYSTEM_NTFS = 'NTFS'
36
- ALIAS_FILESYSTEM_UNKNOWN = 'unknown'
19
+ ALIAS_FILESYSTEM_UDF = "UDF (CD/DVD)"
20
+ ALIAS_FILESYSTEM_FAT32 = "FAT32"
21
+ ALIAS_FILESYSTEM_EXFAT = "exFAT"
22
+ ALIAS_FILESYSTEM_HFSX = "HFSX"
23
+ ALIAS_FILESYSTEM_HFSPLUS = "HFS+"
24
+ ALIAS_FILESYSTEM_FTP = "FTP"
25
+ ALIAS_FILESYSTEM_NTFS = "NTFS"
26
+ ALIAS_FILESYSTEM_UNKNOWN = "unknown"
37
27
 
38
28
  ALIAS_FIXED_DISK = 0
39
29
  ALIAS_NETWORK_DISK = 1
@@ -42,34 +32,36 @@ ALIAS_800KB_FLOPPY_DISK = 3
42
32
  ALIAS_1_44MB_FLOPPY_DISK = 4
43
33
  ALIAS_EJECTABLE_DISK = 5
44
34
 
45
- ALIAS_NO_CNID = 0xffffffff
35
+ ALIAS_NO_CNID = 0xFFFFFFFF
46
36
 
47
37
  ALIAS_FSTYPE_MAP = {
48
38
  # Version 2 aliases
49
- b'HX': ALIAS_FILESYSTEM_HFSX,
50
- b'H+': ALIAS_FILESYSTEM_HFSPLUS,
51
-
39
+ b"HX": ALIAS_FILESYSTEM_HFSX,
40
+ b"H+": ALIAS_FILESYSTEM_HFSPLUS,
52
41
  # Version 3 aliases
53
- b'BDcu': ALIAS_FILESYSTEM_UDF,
54
- b'BDIS': ALIAS_FILESYSTEM_FAT32,
55
- b'BDxF': ALIAS_FILESYSTEM_EXFAT,
56
- b'HX\0\0': ALIAS_FILESYSTEM_HFSX,
57
- b'H+\0\0': ALIAS_FILESYSTEM_HFSPLUS,
58
- b'KG\0\0': ALIAS_FILESYSTEM_FTP,
59
- b'NTcu': ALIAS_FILESYSTEM_NTFS,
42
+ b"BDcu": ALIAS_FILESYSTEM_UDF,
43
+ b"BDIS": ALIAS_FILESYSTEM_FAT32,
44
+ b"BDxF": ALIAS_FILESYSTEM_EXFAT,
45
+ b"HX\0\0": ALIAS_FILESYSTEM_HFSX,
46
+ b"H+\0\0": ALIAS_FILESYSTEM_HFSPLUS,
47
+ b"KG\0\0": ALIAS_FILESYSTEM_FTP,
48
+ b"NTcu": ALIAS_FILESYSTEM_NTFS,
60
49
  }
61
50
 
51
+
62
52
  def encode_utf8(s):
63
53
  if isinstance(s, bytes):
64
54
  return s
65
- return s.encode('utf-8')
55
+ return s.encode("utf-8")
56
+
66
57
 
67
58
  def decode_utf8(s):
68
59
  if isinstance(s, bytes):
69
- return s.decode('utf-8')
60
+ return s.decode("utf-8")
70
61
  return s
71
62
 
72
- class AppleShareInfo (object):
63
+
64
+ class AppleShareInfo:
73
65
  def __init__(self, zone=None, server=None, user=None):
74
66
  #: The AppleShare zone
75
67
  self.zone = zone
@@ -79,13 +71,27 @@ class AppleShareInfo (object):
79
71
  self.user = user
80
72
 
81
73
  def __repr__(self):
82
- return 'AppleShareInfo(%r,%r,%r)' % (self.zone, self.server, self.user)
83
-
84
- class VolumeInfo (object):
85
- def __init__(self, name, creation_date, fs_type, disk_type,
86
- attribute_flags, fs_id, appleshare_info=None,
87
- driver_name=None, posix_path=None, disk_image_alias=None,
88
- dialup_info=None, network_mount_info=None):
74
+ return "AppleShareInfo({!r},{!r},{!r})".format(
75
+ self.zone, self.server, self.user
76
+ )
77
+
78
+
79
+ class VolumeInfo:
80
+ def __init__(
81
+ self,
82
+ name,
83
+ creation_date,
84
+ fs_type,
85
+ disk_type,
86
+ attribute_flags,
87
+ fs_id,
88
+ appleshare_info=None,
89
+ driver_name=None,
90
+ posix_path=None,
91
+ disk_image_alias=None,
92
+ dialup_info=None,
93
+ network_mount_info=None,
94
+ ):
89
95
  #: The name of the volume on which the target resides
90
96
  self.name = name
91
97
 
@@ -140,26 +146,52 @@ class VolumeInfo (object):
140
146
  return ALIAS_FSTYPE_MAP.get(self.fs_type, ALIAS_FILESYSTEM_UNKNOWN)
141
147
 
142
148
  def __repr__(self):
143
- args = ['name', 'creation_date', 'fs_type', 'disk_type',
144
- 'attribute_flags', 'fs_id']
149
+ args = [
150
+ "name",
151
+ "creation_date",
152
+ "fs_type",
153
+ "disk_type",
154
+ "attribute_flags",
155
+ "fs_id",
156
+ ]
145
157
  values = []
146
158
  for a in args:
147
159
  v = getattr(self, a)
148
160
  values.append(repr(v))
149
161
 
150
- kwargs = ['appleshare_info', 'driver_name', 'posix_path',
151
- 'disk_image_alias', 'dialup_info', 'network_mount_info']
162
+ kwargs = [
163
+ "appleshare_info",
164
+ "driver_name",
165
+ "posix_path",
166
+ "disk_image_alias",
167
+ "dialup_info",
168
+ "network_mount_info",
169
+ ]
152
170
  for a in kwargs:
153
171
  v = getattr(self, a)
154
172
  if v is not None:
155
- values.append('%s=%r' % (a, v))
156
- return 'VolumeInfo(%s)' % ','.join(values)
157
-
158
- class TargetInfo (object):
159
- def __init__(self, kind, filename, folder_cnid, cnid, creation_date,
160
- creator_code, type_code, levels_from=-1, levels_to=-1,
161
- folder_name=None, cnid_path=None, carbon_path=None,
162
- posix_path=None, user_home_prefix_len=None):
173
+ values.append(f"{a}={v!r}")
174
+ return "VolumeInfo(%s)" % ",".join(values)
175
+
176
+
177
+ class TargetInfo:
178
+ def __init__(
179
+ self,
180
+ kind,
181
+ filename,
182
+ folder_cnid,
183
+ cnid,
184
+ creation_date,
185
+ creator_code,
186
+ type_code,
187
+ levels_from=-1,
188
+ levels_to=-1,
189
+ folder_name=None,
190
+ cnid_path=None,
191
+ carbon_path=None,
192
+ posix_path=None,
193
+ user_home_prefix_len=None,
194
+ ):
163
195
  #: Either ALIAS_KIND_FILE or ALIAS_KIND_FOLDER
164
196
  self.kind = kind
165
197
 
@@ -208,25 +240,38 @@ class TargetInfo (object):
208
240
  self.user_home_prefix_len = user_home_prefix_len
209
241
 
210
242
  def __repr__(self):
211
- args = ['kind', 'filename', 'folder_cnid', 'cnid', 'creation_date',
212
- 'creator_code', 'type_code']
243
+ args = [
244
+ "kind",
245
+ "filename",
246
+ "folder_cnid",
247
+ "cnid",
248
+ "creation_date",
249
+ "creator_code",
250
+ "type_code",
251
+ ]
213
252
  values = []
214
253
  for a in args:
215
254
  v = getattr(self, a)
216
255
  values.append(repr(v))
217
256
 
218
257
  if self.levels_from != -1:
219
- values.append('levels_from=%r' % self.levels_from)
258
+ values.append("levels_from=%r" % self.levels_from)
220
259
  if self.levels_to != -1:
221
- values.append('levels_to=%r' % self.levels_to)
222
-
223
- kwargs = ['folder_name', 'cnid_path', 'carbon_path',
224
- 'posix_path', 'user_home_prefix_len']
260
+ values.append("levels_to=%r" % self.levels_to)
261
+
262
+ kwargs = [
263
+ "folder_name",
264
+ "cnid_path",
265
+ "carbon_path",
266
+ "posix_path",
267
+ "user_home_prefix_len",
268
+ ]
225
269
  for a in kwargs:
226
270
  v = getattr(self, a)
227
- values.append('%s=%r' % (a, v))
271
+ values.append(f"{a}={v!r}")
272
+
273
+ return "TargetInfo(%s)" % ",".join(values)
228
274
 
229
- return 'TargetInfo(%s)' % ','.join(values)
230
275
 
231
276
  TAG_CARBON_FOLDER_NAME = 0
232
277
  TAG_CNID_PATH = 1
@@ -246,9 +291,16 @@ TAG_POSIX_PATH_TO_MOUNTPOINT = 19
246
291
  TAG_RECURSIVE_ALIAS_OF_DISK_IMAGE = 20
247
292
  TAG_USER_HOME_LENGTH_PREFIX = 21
248
293
 
249
- class Alias (object):
250
- def __init__(self, appinfo=b'\0\0\0\0', version=2, volume=None,
251
- target=None, extra=[]):
294
+
295
+ class Alias:
296
+ def __init__(
297
+ self,
298
+ appinfo=b"\0\0\0\0",
299
+ version=2,
300
+ volume=None,
301
+ target=None,
302
+ extra=[],
303
+ ):
252
304
  """Construct a new :class:`Alias` object with the specified
253
305
  contents."""
254
306
 
@@ -269,26 +321,48 @@ class Alias (object):
269
321
 
270
322
  @classmethod
271
323
  def _from_fd(cls, b):
272
- appinfo, recsize, version = struct.unpack(b'>4shh', b.read(8))
324
+ appinfo, recsize, version = struct.unpack(b">4shh", b.read(8))
273
325
 
274
326
  if recsize < 150:
275
- raise ValueError('Incorrect alias length')
327
+ raise ValueError("Incorrect alias length")
276
328
 
277
329
  if version not in (2, 3):
278
- raise ValueError('Unsupported alias version %u' % version)
330
+ raise ValueError("Unsupported alias version %u" % version)
279
331
 
280
332
  if version == 2:
281
- kind, volname, voldate, fstype, disktype, \
282
- folder_cnid, filename, cnid, crdate, creator_code, type_code, \
283
- levels_from, levels_to, volattrs, volfsid, reserved = \
284
- struct.unpack(b'>h28pI2shI64pII4s4shhI2s10s', b.read(142))
333
+ (
334
+ kind, # h
335
+ volname, # 28p
336
+ voldate, # I
337
+ fstype, # 2s
338
+ disktype, # h
339
+ folder_cnid, # I
340
+ filename, # 64p
341
+ cnid, # I
342
+ crdate, # I
343
+ creator_code, # 4s
344
+ type_code, # 4s
345
+ levels_from, # h
346
+ levels_to, # h
347
+ volattrs, # I
348
+ volfsid, # 2s
349
+ reserved, # 10s
350
+ ) = struct.unpack(b">h28pI2shI64pII4s4shhI2s10s", b.read(142))
285
351
  else:
286
- kind, voldate_hr, fstype, disktype, folder_cnid, cnid, crdate_hr, \
287
- volattrs, reserved = \
288
- struct.unpack(b'>hQ4shIIQI14s', b.read(46))
289
-
290
- volname = b''
291
- filename = b''
352
+ (
353
+ kind, # h
354
+ voldate_hr, # Q
355
+ fstype, # 4s
356
+ disktype, # h
357
+ folder_cnid, # I
358
+ cnid, # I
359
+ crdate_hr, # Q
360
+ volattrs, # I
361
+ reserved, # 14s
362
+ ) = struct.unpack(b">hQ4shIIQI14s", b.read(46))
363
+
364
+ volname = b""
365
+ filename = b""
292
366
  creator_code = None
293
367
  type_code = None
294
368
  voldate = voldate_hr / 65536.0
@@ -300,28 +374,38 @@ class Alias (object):
300
374
  alias = Alias()
301
375
  alias.appinfo = appinfo
302
376
 
303
- alias.volume = VolumeInfo (volname.decode().replace('/',':'),
304
- voldate, fstype, disktype,
305
- volattrs, volfsid)
306
- alias.target = TargetInfo (kind, filename.decode().replace('/',':'),
307
- folder_cnid, cnid,
308
- crdate, creator_code, type_code)
377
+ alias.volume = VolumeInfo(
378
+ volname.decode().replace("/", ":"),
379
+ voldate,
380
+ fstype,
381
+ disktype,
382
+ volattrs,
383
+ volfsid,
384
+ )
385
+ alias.target = TargetInfo(
386
+ kind,
387
+ filename.decode().replace("/", ":"),
388
+ folder_cnid,
389
+ cnid,
390
+ crdate,
391
+ creator_code,
392
+ type_code,
393
+ )
309
394
  alias.target.levels_from = levels_from
310
395
  alias.target.levels_to = levels_to
311
396
 
312
- tag = struct.unpack(b'>h', b.read(2))[0]
397
+ tag = struct.unpack(b">h", b.read(2))[0]
313
398
 
314
399
  while tag != -1:
315
- length = struct.unpack(b'>h', b.read(2))[0]
400
+ length = struct.unpack(b">h", b.read(2))[0]
316
401
  value = b.read(length)
317
402
  if length & 1:
318
403
  b.read(1)
319
404
 
320
405
  if tag == TAG_CARBON_FOLDER_NAME:
321
- alias.target.folder_name = value.decode().replace('/',':')
406
+ alias.target.folder_name = value.decode().replace("/", ":")
322
407
  elif tag == TAG_CNID_PATH:
323
- alias.target.cnid_path = struct.unpack('>%uI' % (length // 4),
324
- value)
408
+ alias.target.cnid_path = struct.unpack(">%uI" % (length // 4), value)
325
409
  elif tag == TAG_CARBON_PATH:
326
410
  alias.target.carbon_path = value
327
411
  elif tag == TAG_APPLESHARE_ZONE:
@@ -343,17 +427,19 @@ class Alias (object):
343
427
  elif tag == TAG_DIALUP_INFO:
344
428
  alias.volume.dialup_info = value
345
429
  elif tag == TAG_UNICODE_FILENAME:
346
- alias.target.filename = value[2:].decode('utf-16be')
430
+ alias.target.filename = value[2:].decode("utf-16be")
347
431
  elif tag == TAG_UNICODE_VOLUME_NAME:
348
- alias.volume.name = value[2:].decode('utf-16be')
432
+ alias.volume.name = value[2:].decode("utf-16be")
349
433
  elif tag == TAG_HIGH_RES_VOLUME_CREATION_DATE:
350
- seconds = struct.unpack(b'>Q', value)[0] / 65536.0
351
- alias.volume.creation_date \
352
- = mac_epoch + datetime.timedelta(seconds=seconds)
434
+ seconds = struct.unpack(b">Q", value)[0] / 65536.0
435
+ alias.volume.creation_date = mac_epoch + datetime.timedelta(
436
+ seconds=seconds
437
+ )
353
438
  elif tag == TAG_HIGH_RES_CREATION_DATE:
354
- seconds = struct.unpack(b'>Q', value)[0] / 65536.0
355
- alias.target.creation_date \
356
- = mac_epoch + datetime.timedelta(seconds=seconds)
439
+ seconds = struct.unpack(b">Q", value)[0] / 65536.0
440
+ alias.target.creation_date = mac_epoch + datetime.timedelta(
441
+ seconds=seconds
442
+ )
357
443
  elif tag == TAG_POSIX_PATH:
358
444
  alias.target.posix_path = value.decode()
359
445
  elif tag == TAG_POSIX_PATH_TO_MOUNTPOINT:
@@ -361,11 +447,11 @@ class Alias (object):
361
447
  elif tag == TAG_RECURSIVE_ALIAS_OF_DISK_IMAGE:
362
448
  alias.volume.disk_image_alias = Alias.from_bytes(value)
363
449
  elif tag == TAG_USER_HOME_LENGTH_PREFIX:
364
- alias.target.user_home_prefix_len = struct.unpack(b'>h', value)[0]
450
+ alias.target.user_home_prefix_len = struct.unpack(b">h", value)[0]
365
451
  else:
366
452
  alias.extra.append((tag, value))
367
453
 
368
- tag = struct.unpack(b'>h', b.read(2))[0]
454
+ tag = struct.unpack(b">h", b.read(2))[0]
369
455
 
370
456
  return alias
371
457
 
@@ -378,8 +464,8 @@ class Alias (object):
378
464
  @classmethod
379
465
  def for_file(cls, path):
380
466
  """Create an :class:`Alias` that points at the specified file."""
381
- if sys.platform != 'darwin':
382
- raise Exception('Not implemented (requires special support)')
467
+ if sys.platform != "darwin":
468
+ raise Exception("Not implemented (requires special support)")
383
469
 
384
470
  path = encode_utf8(path)
385
471
 
@@ -389,21 +475,29 @@ class Alias (object):
389
475
  st = osx.statfs(path)
390
476
  vol_path = st.f_mntonname
391
477
 
478
+ # File and folder names in HFS+ are normalized to a form similar to NFD.
479
+ # Must be normalized (NFD->NFC) before use to avoid unicode string comparison issues.
480
+ vol_path = normalize("NFC", vol_path.decode("utf-8")).encode("utf-8")
481
+
392
482
  # Grab its attributes
393
- attrs = [osx.ATTR_CMN_CRTIME,
394
- osx.ATTR_VOL_NAME,
395
- 0, 0, 0]
483
+ attrs = [osx.ATTR_CMN_CRTIME, osx.ATTR_VOL_NAME, 0, 0, 0]
396
484
  volinfo = osx.getattrlist(vol_path, attrs, 0)
397
485
 
398
486
  vol_crtime = volinfo[0]
399
487
  vol_name = encode_utf8(volinfo[1])
400
488
 
401
489
  # Also grab various attributes of the file
402
- attrs = [(osx.ATTR_CMN_OBJTYPE
403
- | osx.ATTR_CMN_CRTIME
404
- | osx.ATTR_CMN_FNDRINFO
405
- | osx.ATTR_CMN_FILEID
406
- | osx.ATTR_CMN_PARENTID), 0, 0, 0, 0]
490
+ attrs = [
491
+ osx.ATTR_CMN_OBJTYPE
492
+ | osx.ATTR_CMN_CRTIME
493
+ | osx.ATTR_CMN_FNDRINFO
494
+ | osx.ATTR_CMN_FILEID
495
+ | osx.ATTR_CMN_PARENTID,
496
+ 0,
497
+ 0,
498
+ 0,
499
+ 0,
500
+ ]
407
501
  info = osx.getattrlist(path, attrs, osx.FSOPT_NOFOLLOW)
408
502
 
409
503
  if info[0] == osx.VDIR:
@@ -416,7 +510,7 @@ class Alias (object):
416
510
 
417
511
  dirname, filename = os.path.split(path)
418
512
 
419
- if dirname == b'' or dirname == b'.':
513
+ if dirname == b"" or dirname == b".":
420
514
  dirname = os.getcwd()
421
515
 
422
516
  foldername = os.path.basename(dirname)
@@ -424,16 +518,16 @@ class Alias (object):
424
518
  creation_date = info[1]
425
519
 
426
520
  if kind == ALIAS_KIND_FILE:
427
- creator_code = struct.pack(b'I', info[2].fileInfo.fileCreator)
428
- type_code = struct.pack(b'I', info[2].fileInfo.fileType)
521
+ creator_code = struct.pack(b"I", info[2].fileInfo.fileCreator)
522
+ type_code = struct.pack(b"I", info[2].fileInfo.fileType)
429
523
  else:
430
- creator_code = b'\0\0\0\0'
431
- type_code = b'\0\0\0\0'
524
+ creator_code = b"\0\0\0\0"
525
+ type_code = b"\0\0\0\0"
432
526
 
433
- a.target = TargetInfo(kind, filename, folder_cnid, cnid, creation_date,
434
- creator_code, type_code)
435
- a.volume = VolumeInfo(vol_name, vol_crtime, b'H+',
436
- ALIAS_FIXED_DISK, 0, b'\0\0')
527
+ a.target = TargetInfo(
528
+ kind, filename, folder_cnid, cnid, creation_date, creator_code, type_code
529
+ )
530
+ a.volume = VolumeInfo(vol_name, vol_crtime, b"H+", ALIAS_FIXED_DISK, 0, b"\0\0")
437
531
 
438
532
  a.target.folder_name = foldername
439
533
  a.volume.posix_path = vol_path
@@ -441,10 +535,10 @@ class Alias (object):
441
535
  rel_path = os.path.relpath(path, vol_path)
442
536
 
443
537
  # Leave off the initial '/' if vol_path is '/' (no idea why)
444
- if vol_path == b'/':
538
+ if vol_path == b"/":
445
539
  a.target.posix_path = rel_path
446
540
  else:
447
- a.target.posix_path = b'/' + rel_path
541
+ a.target.posix_path = b"/" + rel_path
448
542
 
449
543
  # Construct the Carbon and CNID paths
450
544
  carbon_path = []
@@ -457,11 +551,11 @@ class Alias (object):
457
551
  attrs = [osx.ATTR_CMN_FILEID, 0, 0, 0, 0]
458
552
  info = osx.getattrlist(os.path.join(vol_path, head), attrs, 0)
459
553
  cnid_path.append(info[0])
460
- carbon_tail = tail.replace(b':',b'/')
554
+ carbon_tail = tail.replace(b":", b"/")
461
555
  carbon_path.insert(0, carbon_tail)
462
556
  head, tail = os.path.split(head)
463
557
 
464
- carbon_path = vol_name + b':' + b':\0'.join(carbon_path)
558
+ carbon_path = vol_name + b":" + b":\0".join(carbon_path)
465
559
 
466
560
  a.target.carbon_path = carbon_path
467
561
  a.target.cnid_path = cnid_path
@@ -471,172 +565,188 @@ class Alias (object):
471
565
  def _to_fd(self, b):
472
566
  # We'll come back and fix the length when we're done
473
567
  pos = b.tell()
474
- b.write(struct.pack(b'>4shh', self.appinfo, 0, self.version))
568
+ b.write(struct.pack(b">4shh", self.appinfo, 0, self.version))
475
569
 
476
- carbon_volname = encode_utf8(self.volume.name).replace(b':',b'/')
477
- carbon_filename = encode_utf8(self.target.filename).replace(b':',b'/')
570
+ carbon_volname = encode_utf8(self.volume.name).replace(b":", b"/")
571
+ carbon_filename = encode_utf8(self.target.filename).replace(b":", b"/")
478
572
  voldate = (self.volume.creation_date - mac_epoch).total_seconds()
479
573
  crdate = (self.target.creation_date - mac_epoch).total_seconds()
480
574
 
481
575
  if self.version == 2:
482
576
  # NOTE: crdate should be in local time, but that's system dependent
483
577
  # (so doing so is ridiculous, and nothing could rely on it).
484
- b.write(struct.pack(b'>h28pI2shI64pII4s4shhI2s10s',
485
- self.target.kind,
486
- carbon_volname, int(voldate),
487
- self.volume.fs_type,
488
- self.volume.disk_type,
489
- self.target.folder_cnid,
490
- carbon_filename,
491
- self.target.cnid,
492
- int(crdate),
493
- self.target.creator_code,
494
- self.target.type_code,
495
- self.target.levels_from,
496
- self.target.levels_to,
497
- self.volume.attribute_flags,
498
- self.volume.fs_id,
499
- b'\0'*10))
578
+ b.write(
579
+ struct.pack(
580
+ b">h28pI2shI64pII4s4shhI2s10s",
581
+ self.target.kind, # h
582
+ carbon_volname, # 28p
583
+ int(voldate), # I
584
+ self.volume.fs_type, # 2s
585
+ self.volume.disk_type, # h
586
+ self.target.folder_cnid, # I
587
+ carbon_filename, # 64p
588
+ self.target.cnid, # I
589
+ int(crdate), # I
590
+ self.target.creator_code, # 4s
591
+ self.target.type_code, # 4s
592
+ self.target.levels_from, # h
593
+ self.target.levels_to, # h
594
+ self.volume.attribute_flags, # I
595
+ self.volume.fs_id, # 2s
596
+ b"\0" * 10, # 10s
597
+ )
598
+ )
500
599
  else:
501
- b.write(struct.pack(b'>hQ4shIIQI14s',
502
- self.target.kind,
503
- int(voldate * 65536),
504
- self.volume.fs_type,
505
- self.volume.disk_type,
506
- self.target.folder_cnid,
507
- self.target.cnid,
508
- int(crdate * 65536),
509
- self.volume.attribute_flags,
510
- self.volume.fs_id,
511
- b'\0'*14))
600
+ b.write(
601
+ struct.pack(
602
+ b">hQ4shIIQI14s",
603
+ self.target.kind, # h
604
+ int(voldate * 65536), # Q
605
+ self.volume.fs_type, # 4s
606
+ self.volume.disk_type, # h
607
+ self.target.folder_cnid, # I
608
+ self.target.cnid, # I
609
+ int(crdate * 65536), # Q
610
+ self.volume.attribute_flags, # I
611
+ b"\0" * 14, # 14s
612
+ )
613
+ )
512
614
 
513
615
  # Excuse the odd order; we're copying Finder
514
616
  if self.target.folder_name:
515
- carbon_foldername = encode_utf8(self.target.folder_name)\
516
- .replace(b':',b'/')
517
- b.write(struct.pack(b'>hh', TAG_CARBON_FOLDER_NAME,
518
- len(carbon_foldername)))
617
+ carbon_foldername = encode_utf8(self.target.folder_name).replace(b":", b"/")
618
+ b.write(struct.pack(b">hh", TAG_CARBON_FOLDER_NAME, len(carbon_foldername)))
519
619
  b.write(carbon_foldername)
520
620
  if len(carbon_foldername) & 1:
521
- b.write(b'\0')
621
+ b.write(b"\0")
522
622
 
523
- b.write(struct.pack(b'>hhQhhQ',
623
+ b.write(
624
+ struct.pack(
625
+ b">hhQhhQ",
524
626
  TAG_HIGH_RES_VOLUME_CREATION_DATE,
525
- 8, int(voldate * 65536),
627
+ 8,
628
+ int(voldate * 65536),
526
629
  TAG_HIGH_RES_CREATION_DATE,
527
- 8, int(crdate * 65536)))
630
+ 8,
631
+ int(crdate * 65536),
632
+ )
633
+ )
528
634
 
529
635
  if self.target.cnid_path:
530
- cnid_path = struct.pack('>%uI' % len(self.target.cnid_path),
531
- *self.target.cnid_path)
532
- b.write(struct.pack(b'>hh', TAG_CNID_PATH,
533
- len(cnid_path)))
636
+ cnid_path = struct.pack(
637
+ ">%uI" % len(self.target.cnid_path), *self.target.cnid_path
638
+ )
639
+ b.write(struct.pack(b">hh", TAG_CNID_PATH, len(cnid_path)))
534
640
  b.write(cnid_path)
535
641
 
536
642
  if self.target.carbon_path:
537
- carbon_path=encode_utf8(self.target.carbon_path)
538
- b.write(struct.pack(b'>hh', TAG_CARBON_PATH,
539
- len(carbon_path)))
643
+ carbon_path = encode_utf8(self.target.carbon_path)
644
+ b.write(struct.pack(b">hh", TAG_CARBON_PATH, len(carbon_path)))
540
645
  b.write(carbon_path)
541
646
  if len(carbon_path) & 1:
542
- b.write(b'\0')
647
+ b.write(b"\0")
543
648
 
544
649
  if self.volume.appleshare_info:
545
650
  ai = self.volume.appleshare_info
546
651
  if ai.zone:
547
- b.write(struct.pack(b'>hh', TAG_APPLESHARE_ZONE,
548
- len(ai.zone)))
652
+ b.write(struct.pack(b">hh", TAG_APPLESHARE_ZONE, len(ai.zone)))
549
653
  b.write(ai.zone)
550
654
  if len(ai.zone) & 1:
551
- b.write(b'\0')
655
+ b.write(b"\0")
552
656
  if ai.server:
553
- b.write(struct.pack(b'>hh', TAG_APPLESHARE_SERVER_NAME,
554
- len(ai.server)))
657
+ b.write(struct.pack(b">hh", TAG_APPLESHARE_SERVER_NAME, len(ai.server)))
555
658
  b.write(ai.server)
556
659
  if len(ai.server) & 1:
557
- b.write(b'\0')
660
+ b.write(b"\0")
558
661
  if ai.username:
559
- b.write(struct.pack(b'>hh', TAG_APPLESHARE_USERNAME,
560
- len(ai.username)))
662
+ b.write(struct.pack(b">hh", TAG_APPLESHARE_USERNAME, len(ai.username)))
561
663
  b.write(ai.username)
562
664
  if len(ai.username) & 1:
563
- b.write(b'\0')
665
+ b.write(b"\0")
564
666
 
565
667
  if self.volume.driver_name:
566
668
  driver_name = encode_utf8(self.volume.driver_name)
567
- b.write(struct.pack(b'>hh', TAG_DRIVER_NAME,
568
- len(driver_name)))
669
+ b.write(struct.pack(b">hh", TAG_DRIVER_NAME, len(driver_name)))
569
670
  b.write(driver_name)
570
671
  if len(driver_name) & 1:
571
- b.write(b'\0')
672
+ b.write(b"\0")
572
673
 
573
674
  if self.volume.network_mount_info:
574
- b.write(struct.pack(b'>hh', TAG_NETWORK_MOUNT_INFO,
575
- len(self.volume.network_mount_info)))
675
+ b.write(
676
+ struct.pack(
677
+ b">hh", TAG_NETWORK_MOUNT_INFO, len(self.volume.network_mount_info)
678
+ )
679
+ )
576
680
  b.write(self.volume.network_mount_info)
577
681
  if len(self.volume.network_mount_info) & 1:
578
- b.write(b'\0')
682
+ b.write(b"\0")
579
683
 
580
684
  if self.volume.dialup_info:
581
- b.write(struct.pack(b'>hh', TAG_DIALUP_INFO,
582
- len(self.volume.network_mount_info)))
685
+ b.write(
686
+ struct.pack(
687
+ b">hh", TAG_DIALUP_INFO, len(self.volume.network_mount_info)
688
+ )
689
+ )
583
690
  b.write(self.volume.network_mount_info)
584
691
  if len(self.volume.network_mount_info) & 1:
585
- b.write(b'\0')
692
+ b.write(b"\0")
586
693
 
587
- utf16 = decode_utf8(self.target.filename)\
588
- .replace(':','/').encode('utf-16-be')
589
- b.write(struct.pack(b'>hhh', TAG_UNICODE_FILENAME,
590
- len(utf16) + 2,
591
- len(utf16) // 2))
694
+ utf16 = decode_utf8(self.target.filename).replace(":", "/").encode("utf-16-be")
695
+ b.write(
696
+ struct.pack(b">hhh", TAG_UNICODE_FILENAME, len(utf16) + 2, len(utf16) // 2)
697
+ )
592
698
  b.write(utf16)
593
699
 
594
- utf16 = decode_utf8(self.volume.name)\
595
- .replace(':','/').encode('utf-16-be')
596
- b.write(struct.pack(b'>hhh', TAG_UNICODE_VOLUME_NAME,
597
- len(utf16) + 2,
598
- len(utf16) // 2))
700
+ utf16 = decode_utf8(self.volume.name).replace(":", "/").encode("utf-16-be")
701
+ b.write(
702
+ struct.pack(
703
+ b">hhh", TAG_UNICODE_VOLUME_NAME, len(utf16) + 2, len(utf16) // 2
704
+ )
705
+ )
599
706
  b.write(utf16)
600
707
 
601
708
  if self.target.posix_path:
602
709
  posix_path = encode_utf8(self.target.posix_path)
603
- b.write(struct.pack(b'>hh', TAG_POSIX_PATH,
604
- len(posix_path)))
710
+ b.write(struct.pack(b">hh", TAG_POSIX_PATH, len(posix_path)))
605
711
  b.write(posix_path)
606
712
  if len(posix_path) & 1:
607
- b.write(b'\0')
713
+ b.write(b"\0")
608
714
 
609
715
  if self.volume.posix_path:
610
716
  posix_path = encode_utf8(self.volume.posix_path)
611
- b.write(struct.pack(b'>hh', TAG_POSIX_PATH_TO_MOUNTPOINT,
612
- len(posix_path)))
717
+ b.write(struct.pack(b">hh", TAG_POSIX_PATH_TO_MOUNTPOINT, len(posix_path)))
613
718
  b.write(posix_path)
614
719
  if len(posix_path) & 1:
615
- b.write(b'\0')
720
+ b.write(b"\0")
616
721
 
617
722
  if self.volume.disk_image_alias:
618
723
  d = self.volume.disk_image_alias.to_bytes()
619
- b.write(struct.pack(b'>hh', TAG_RECURSIVE_ALIAS_OF_DISK_IMAGE,
620
- len(d)))
724
+ b.write(struct.pack(b">hh", TAG_RECURSIVE_ALIAS_OF_DISK_IMAGE, len(d)))
621
725
  b.write(d)
622
726
  if len(d) & 1:
623
- b.write(b'\0')
727
+ b.write(b"\0")
624
728
 
625
729
  if self.target.user_home_prefix_len is not None:
626
- b.write(struct.pack(b'>hhh', TAG_USER_HOME_LENGTH_PREFIX,
627
- 2, self.target.user_home_prefix_len))
628
-
629
- for t,v in self.extra:
630
- b.write(struct.pack(b'>hh', t, len(v)))
730
+ b.write(
731
+ struct.pack(
732
+ b">hhh",
733
+ TAG_USER_HOME_LENGTH_PREFIX,
734
+ 2,
735
+ self.target.user_home_prefix_len,
736
+ )
737
+ )
738
+
739
+ for t, v in self.extra:
740
+ b.write(struct.pack(b">hh", t, len(v)))
631
741
  b.write(v)
632
742
  if len(v) & 1:
633
- b.write(b'\0')
743
+ b.write(b"\0")
634
744
 
635
- b.write(struct.pack(b'>hh', -1, 0))
745
+ b.write(struct.pack(b">hh", -1, 0))
636
746
 
637
747
  blen = b.tell() - pos
638
748
  b.seek(pos + 4, os.SEEK_SET)
639
- b.write(struct.pack(b'>h', blen))
749
+ b.write(struct.pack(b">h", blen))
640
750
 
641
751
  def to_bytes(self):
642
752
  """Returns the binary representation for this :class:`Alias`."""
@@ -645,18 +755,18 @@ class Alias (object):
645
755
  return b.getvalue()
646
756
 
647
757
  def __str__(self):
648
- return '<Alias target=%s>' % self.target.filename
758
+ return "<Alias target=%s>" % self.target.filename
649
759
 
650
760
  def __repr__(self):
651
761
  values = []
652
- if self.appinfo != b'\0\0\0\0':
653
- values.append('appinfo=%r' % self.appinfo)
762
+ if self.appinfo != b"\0\0\0\0":
763
+ values.append("appinfo=%r" % self.appinfo)
654
764
  if self.version != 2:
655
- values.append('version=%r' % self.version)
765
+ values.append("version=%r" % self.version)
656
766
  if self.volume is not None:
657
- values.append('volume=%r' % self.volume)
767
+ values.append("volume=%r" % self.volume)
658
768
  if self.target is not None:
659
- values.append('target=%r' % self.target)
769
+ values.append("target=%r" % self.target)
660
770
  if self.extra:
661
- values.append('extra=%r' % self.extra)
662
- return 'Alias(%s)' % ','.join(values)
771
+ values.append("extra=%r" % self.extra)
772
+ return "Alias(%s)" % ",".join(values)