File: macostools.py

package info (click to toggle)
python2.2 2.2.3dfsg-2sarge1
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 36,920 kB
  • ctags: 69,127
  • sloc: ansic: 219,839; python: 203,969; sh: 9,690; makefile: 3,468; perl: 3,454; lisp: 3,248; xml: 2,262; cpp: 106; sed: 2
file content (131 lines) | stat: -rw-r--r-- 3,284 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
"""macostools - Various utility functions for MacOS.

mkalias(src, dst) - Create a finder alias 'dst' pointing to 'src'
copy(src, dst) - Full copy of 'src' to 'dst'
"""

import macfs
from Carbon import Res
import os
from MACFS import *
import MacOS
import time
try:
	openrf = MacOS.openrf
except AttributeError:
	# Backward compatability
	openrf = open

Error = 'macostools.Error'

BUFSIZ=0x80000		# Copy in 0.5Mb chunks

#
# Not guaranteed to be correct or stay correct (Apple doesn't tell you
# how to do this), but it seems to work.
#
def mkalias(src, dst, relative=None):
	"""Create a finder alias"""
	srcfss = macfs.FSSpec(src)
	dstfss = macfs.FSSpec(dst)
	if relative:
		relativefss = macfs.FSSpec(relative)
		# ik mag er geen None in stoppen :-(
		alias = srcfss.NewAlias(relativefss)
	else:
		alias = srcfss.NewAlias()
	
	if os.path.isdir(src):
		cr, tp = 'MACS', 'fdrp'
	else:
		cr, tp = srcfss.GetCreatorType()
	
	Res.FSpCreateResFile(dstfss, cr, tp, -1)
	h = Res.FSpOpenResFile(dstfss, 3)
	resource = Res.Resource(alias.data)
	resource.AddResource('alis', 0, '')
	Res.CloseResFile(h)
	
	dstfinfo = dstfss.GetFInfo()
	dstfinfo.Flags = dstfinfo.Flags|0x8000    # Alias flag
	dstfss.SetFInfo(dstfinfo)
	
def mkdirs(dst):
	"""Make directories leading to 'dst' if they don't exist yet"""
	if dst == '' or os.path.exists(dst):
		return
	head, tail = os.path.split(dst)
	if not ':' in head:
		head = head + ':'
	mkdirs(head)
	os.mkdir(dst, 0777)
	
def touched(dst):
	"""Tell the finder a file has changed"""
	file_fss = macfs.FSSpec(dst)
	vRefNum, dirID, name = file_fss.as_tuple()
	dir_fss = macfs.FSSpec((vRefNum, dirID, ''))
	crdate, moddate, bkdate = dir_fss.GetDates()
	now = time.time()
	if now == moddate:
		now = now + 1
	try:
		dir_fss.SetDates(crdate, now, bkdate)
	except macfs.error:
		pass
	
def touched_ae(dst):
	"""Tell the finder a file has changed"""
	import Finder
	f = Finder.Finder()
	file_fss = macfs.FSSpec(dst)
	vRefNum, dirID, name = file_fss.as_tuple()
	dir_fss = macfs.FSSpec((vRefNum, dirID, ''))
	f.update(dir_fss)
	
def copy(src, dst, createpath=0, copydates=1, forcetype=None):
	"""Copy a file, including finder info, resource fork, etc"""
	if createpath:
		mkdirs(os.path.split(dst)[0])
	srcfss = macfs.FSSpec(src)
	dstfss = macfs.FSSpec(dst)
	
	ifp = open(srcfss.as_pathname(), 'rb')
	ofp = open(dstfss.as_pathname(), 'wb')
	d = ifp.read(BUFSIZ)
	while d:
		ofp.write(d)
		d = ifp.read(BUFSIZ)
	ifp.close()
	ofp.close()
	
	ifp = openrf(srcfss.as_pathname(), '*rb')
	ofp = openrf(dstfss.as_pathname(), '*wb')
	d = ifp.read(BUFSIZ)
	while d:
		ofp.write(d)
		d = ifp.read(BUFSIZ)
	ifp.close()
	ofp.close()
	
	sf = srcfss.GetFInfo()
	df = dstfss.GetFInfo()
	df.Creator, df.Type = sf.Creator, sf.Type
	if forcetype != None:
		df.Type = forcetype
	df.Flags = (sf.Flags & (kIsStationary|kNameLocked|kHasBundle|kIsInvisible|kIsAlias))
	dstfss.SetFInfo(df)
	if copydates:
		crdate, mddate, bkdate = srcfss.GetDates()
		dstfss.SetDates(crdate, mddate, bkdate)
	touched(dstfss)
	
def copytree(src, dst, copydates=1):
	"""Copy a complete file tree to a new destination"""
	if os.path.isdir(src):
		mkdirs(dst)
		files = os.listdir(src)
		for f in files:
			copytree(os.path.join(src, f), os.path.join(dst, f), copydates)
	else:
		copy(src, dst, 1, copydates)