[ create a new paste ] login | about

Link: http://codepad.org/1qi8IATv    [ raw code | fork ]

Python, pasted on Apr 16:
import os, sys, re, argparse, shutil

ARCHIVE_README = '''These image files for the client should be located in
$prefix/share/crossfire-client.  $prefix is the location given in the -prefix
option when configure is run to build the client.  The default is /usr/local.
In that case these files should be put in /usr/local/share/crossfire-client
The client will print a messgae if it is unable to find the image information
with the location is looked for them.
'''

class ImageParser(object):
	def __init__(self, arch_path, data_path, archive):
		self.bmaps_paths_path = os.path.join(data_path, 'bmaps.paths')
		self.image_info_path = os.path.join(data_path, 'image_info')
		self.arch_path = arch_path

		self.archive = archive

		if not os.path.isdir(os.path.join(arch_path, 'arch')) or not \
			os.path.exists(self.bmaps_paths_path) or not \
			os.path.exists(self.image_info_path):
			print 'Error while checking for arch path and data files.'
			print 'Please make sure you are on the right directory, or that your arguments point to the correct directories'
			sys.exit(1)

		self.set_name_prefix = 'crossfire.'
		self.archive_path_name = 'crossfire-images'
		self.archive_format = '''{0}.{1} {2} crossfire.{3}@{4}:{5}\n'''

		if self.archive:
			print 'Will generate appropriate files for image archive'
			if os.path.exists(self.archive_path_name):
				print '%s already exists - remove if you really want to remake the images' % self.archive_path_name
				sys.exit(1)

			try:
				os.mkdir(self.archive_path_name, 0755)
			except OSError, e:
				print 'unable to mkdir %s:\n' % self.archive_path_name, e
				sys.exit(1)

		self.sets = {}
		self.setfiles = {}
		self.archive_sets = []

	def parseImageInfo(self):
		''' This method reads image_info in order to get the information on the image sets available'''

		try:
			image_info = open(self.image_info_path)
		except IOError, e:
			print "Can't open image_info file:\n", e
			sys.exit(1)
	
		for line in image_info:
			if not line.strip() or line.strip()[0] == '#':
				continue

			infos = line.split(':')
			setno = infos[0]
			setname = infos[1]

			# Check if all the fields are actually returned
			if len(infos) != 7:
				print 'image_info: line is corrupt:\n%s' % line

			# The duplicate will replace previous assignments
			if setno in self.sets:
				print 'Warning: set %s is duplicated in image_info file' % setno

			self.sets[setno] = setname

		image_info.close()

	def generateSets(self):
		self.parseImageInfo()

		# Assign the file handlers related to the sets
		for num in self.sets:
			try:
				self.setfiles[num] = open(self.set_name_prefix + num, 'wb')
			except IOError, e:
				print "Can't open %s for write:\n" % (self.set_name_prefix + num), e
				sys.exit(1)

		try:
			bmaps_paths = open(self.bmaps_paths_path)
		except IOError, e:
			print "Can't open bmaps.paths:\n", e
			sys.exit(1)

		for line in bmaps_paths:
			# Parse and consequently filter only valid lines
			parsed_line = re.findall('(\d{5})\s+(\S+).(\w\w\w)', line)
			if not parsed_line:
				continue

			findex, fname, fnumber = parsed_line[0]

			# Display some progress information
			if int(findex) % 500 == 0:
				print findex, fname

			for num in self.sets.iterkeys():
				filename = '{0}.{1}.{2}.png'.format(fname, self.sets[num], fnumber)
				filename = os.path.join(self.arch_path, filename)

				# Set 0 should always contain all images since it's the base set
				if not os.path.exists(filename):
					if num == '0':
						print 'Error: Image %s not found for set 0!' % filename

					continue

				try:
					ifile = open(filename, 'rb')
				except IOError, e:
					print 'Error reading file %s\n' % filename, e
					sys.exit(1)

				ifile.seek(0, 2)
				eof = ifile.tell()
				ifile.seek(0, 0)

				buffer = ifile.read(eof)

				ifile.close()

				# Write 'header' information
				self.setfiles[num].write('IMAGE {0} {1}.{2}\n'.format(eof, fname, fnumber))

				# If we're archiving this, we need to calculate the checksums
				if self.archive:
					position = self.setfiles[num].tell()

					sum = 0
					for i in xrange(eof):
						if sum & 01:
							sum = (sum >> 1) | 0x80000000
						else:
							sum >>= 1

						sum += ord(buffer[i])
						sum &= 0xffffffff

					self.archive_sets.append(self.archive_format.format(fname.split('/')[-1], fnumber, sum, self.sets[num], position, eof))

				# Write the actual image binary data
				self.setfiles[num].write(buffer)

		bmaps_paths.close()

		for setfile in self.setfiles.itervalues():
			setfile.close()

		# Write required archiving files and perform file-copying / compressing operations
		if self.archive:
			try:
				bmaps_client = open(os.path.join(self.archive_path_name, 'bmaps.client'), 'wb')
				bmaps_client.writelines(sorted(self.archive_sets))
				bmaps_client.close()
			except IOError, e:
				print "Can not open %s/bmaps.client:\n" % self.archive_path_name, e
				sys.exit(1)

			try:
				readme = open(os.path.join(self.archive_path_name, 'README'), 'wb')
				readme.write(ARCHIVE_README)
				readme.close()
			except IOError, e:
				print "Can not open %s/README:\n" % self.archive_path_name, e
				sys.exit(1)

			for count in self.sets.iterkeys():
				name = self.set_name_prefix + count
				shutil.copyfile(name, os.path.join(self.archive_path_name, name))
				shutil.copystat(name, os.path.join(self.archive_path_name, name))

			# We do not have a win32 replacement for tar in place yet, so just avoid trying
			if sys.platform == 'win32':
				print 'Archive folder created, to use it you must compact the folder,',
				print 'refer to the README inside the folder for more information'
			else:
				os.chdir(self.archive_path_name)
				os.system('tar cf ../%s.tar .' % self.archive_path_name)
				os.chdir('..')
				os.system('rm -rf %s' % self.archive_path_name)

def main():
	parser = argparse.ArgumentParser(description='This script collects image data into crossfire image set files')
	parser.add_argument('-archive', action="store_true", help='Archives the images into a tar file')
	parser.add_argument('-src', metavar='ARCH_DIR', default='.', help='Specify a source arch directory (default: ".")')
	parser.add_argument('-data', metavar='DATA_DIR', default='.', help='Specify a source data directory (default: ".")')

	args = parser.parse_args()

	im = ImageParser(args.src, args.data, args.archive)
	im.generateSets()

if __name__ == '__main__':
	main()


Create a new paste based on this one


Comments: