Browse Source

update to python3

MFTECH 1 year ago
parent
commit
065640ef4b
1 changed files with 37 additions and 36 deletions
  1. 37
    36
      gitstats

+ 37
- 36
gitstats View File

1
-#!/usr/bin/env python2
1
+#!/usr/bin/env python3
2
 # Copyright (c) 2007-2014 Heikki Hokkanen <hoxu@users.sf.net> & others (see doc/AUTHOR)
2
 # Copyright (c) 2007-2014 Heikki Hokkanen <hoxu@users.sf.net> & others (see doc/AUTHOR)
3
 # GPLv2 / GPLv3
3
 # GPLv2 / GPLv3
4
 import datetime
4
 import datetime
54
 	global exectime_external
54
 	global exectime_external
55
 	start = time.time()
55
 	start = time.time()
56
 	if not quiet and ON_LINUX and os.isatty(1):
56
 	if not quiet and ON_LINUX and os.isatty(1):
57
-		print '>> ' + ' | '.join(cmds),
57
+		print('>> ' + ' | '.join(cmds))
58
 		sys.stdout.flush()
58
 		sys.stdout.flush()
59
 	p = subprocess.Popen(cmds[0], stdout = subprocess.PIPE, shell = True)
59
 	p = subprocess.Popen(cmds[0], stdout = subprocess.PIPE, shell = True)
60
 	processes=[p]
60
 	processes=[p]
61
 	for x in cmds[1:]:
61
 	for x in cmds[1:]:
62
 		p = subprocess.Popen(x, stdin = p.stdout, stdout = subprocess.PIPE, shell = True)
62
 		p = subprocess.Popen(x, stdin = p.stdout, stdout = subprocess.PIPE, shell = True)
63
 		processes.append(p)
63
 		processes.append(p)
64
-	output = p.communicate()[0]
64
+	output = (p.communicate()[0]).decode("utf-8")
65
 	for p in processes:
65
 	for p in processes:
66
 		p.wait()
66
 		p.wait()
67
 	end = time.time()
67
 	end = time.time()
68
 	if not quiet:
68
 	if not quiet:
69
 		if ON_LINUX and os.isatty(1):
69
 		if ON_LINUX and os.isatty(1):
70
-			print '\r',
71
-		print '[%.5f] >> %s' % (end - start, ' | '.join(cmds))
70
+			print('\r')
71
+		print('[%.5f] >> %s' % (end - start, ' | '.join(cmds)))
72
 	exectime_external += (end - start)
72
 	exectime_external += (end - start)
73
 	return output.rstrip('\n')
73
 	return output.rstrip('\n')
74
 
74
 
86
 	return defaultrange
86
 	return defaultrange
87
 
87
 
88
 def getkeyssortedbyvalues(dict):
88
 def getkeyssortedbyvalues(dict):
89
-	return map(lambda el : el[1], sorted(map(lambda el : (el[1], el[0]), dict.items())))
89
+	return list(map(lambda el : el[1], sorted(map(lambda el : (el[1], el[0]), dict.items()))))
90
 
90
 
91
 # dict['author'] = { 'commits': 512 } - ...key(dict, 'commits')
91
 # dict['author'] = { 'commits': 512 } - ...key(dict, 'commits')
92
 def getkeyssortedbyvaluekey(d, key):
92
 def getkeyssortedbyvaluekey(d, key):
93
-	return map(lambda el : el[1], sorted(map(lambda el : (d[el][key], el), d.keys())))
93
+	return list(map(lambda el : el[1], sorted(map(lambda el : (d[el][key], el), d.keys()))))
94
 
94
 
95
 def getstatsummarycounts(line):
95
 def getstatsummarycounts(line):
96
 	numbers = re.findall('\d+', line)
96
 	numbers = re.findall('\d+', line)
207
 	def loadCache(self, cachefile):
207
 	def loadCache(self, cachefile):
208
 		if not os.path.exists(cachefile):
208
 		if not os.path.exists(cachefile):
209
 			return
209
 			return
210
-		print 'Loading cache...'
210
+		print( 'Loading cache...')
211
 		f = open(cachefile, 'rb')
211
 		f = open(cachefile, 'rb')
212
 		try:
212
 		try:
213
 			self.cache = pickle.loads(zlib.decompress(f.read()))
213
 			self.cache = pickle.loads(zlib.decompress(f.read()))
269
 	##
269
 	##
270
 	# Save cacheable data
270
 	# Save cacheable data
271
 	def saveCache(self, cachefile):
271
 	def saveCache(self, cachefile):
272
-		print 'Saving cache...'
272
+		print( 'Saving cache...')
273
 		tempfile = cachefile + '.tmp'
273
 		tempfile = cachefile + '.tmp'
274
 		f = open(tempfile, 'wb')
274
 		f = open(tempfile, 'wb')
275
 		#pickle.dump(self.cache, f)
275
 		#pickle.dump(self.cache, f)
308
 				self.tags[tag] = { 'stamp': stamp, 'hash' : hash, 'date' : datetime.datetime.fromtimestamp(stamp).strftime('%Y-%m-%d'), 'commits': 0, 'authors': {} }
308
 				self.tags[tag] = { 'stamp': stamp, 'hash' : hash, 'date' : datetime.datetime.fromtimestamp(stamp).strftime('%Y-%m-%d'), 'commits': 0, 'authors': {} }
309
 
309
 
310
 		# collect info on tags, starting from latest
310
 		# collect info on tags, starting from latest
311
-		tags_sorted_by_date_desc = map(lambda el : el[1], reversed(sorted(map(lambda el : (el[1]['date'], el[0]), self.tags.items()))))
311
+		tags_sorted_by_date_desc = list(map(lambda el : el[1], reversed(sorted(map(lambda el : (el[1]['date'], el[0]), self.tags.items())))))
312
 		prev = None
312
 		prev = None
313
 		for tag in reversed(tags_sorted_by_date_desc):
313
 		for tag in reversed(tags_sorted_by_date_desc):
314
 			cmd = 'git shortlog -s "%s"' % tag
314
 			cmd = 'git shortlog -s "%s"' % tag
474
 			try:
474
 			try:
475
 				self.files_by_stamp[int(stamp)] = int(files)
475
 				self.files_by_stamp[int(stamp)] = int(files)
476
 			except ValueError:
476
 			except ValueError:
477
-				print 'Warning: failed to parse line "%s"' % line
477
+				print('Warning: failed to parse line "%s"' % line)
478
 
478
 
479
 		# extensions and size of files
479
 		# extensions and size of files
480
 		lines = getpipeoutput(['git ls-tree -r -l -z %s' % getcommitrange('HEAD', end_only = True)]).split('\000')
480
 		lines = getpipeoutput(['git ls-tree -r -l -z %s' % getcommitrange('HEAD', end_only = True)]).split('\000')
563
 
563
 
564
 						files, inserted, deleted = 0, 0, 0
564
 						files, inserted, deleted = 0, 0, 0
565
 					except ValueError:
565
 					except ValueError:
566
-						print 'Warning: unexpected line "%s"' % line
566
+						print('Warning: unexpected line "%s"' % line)
567
 				else:
567
 				else:
568
-					print 'Warning: unexpected line "%s"' % line
568
+					print('Warning: unexpected line "%s"' % line)
569
 			else:
569
 			else:
570
 				numbers = getstatsummarycounts(line)
570
 				numbers = getstatsummarycounts(line)
571
 
571
 
572
 				if len(numbers) == 3:
572
 				if len(numbers) == 3:
573
-					(files, inserted, deleted) = map(lambda el : int(el), numbers)
573
+					(files, inserted, deleted) = list(map(lambda el : int(el), numbers))
574
 					total_lines += inserted
574
 					total_lines += inserted
575
 					total_lines -= deleted
575
 					total_lines -= deleted
576
 					self.total_lines_added += inserted
576
 					self.total_lines_added += inserted
577
 					self.total_lines_removed += deleted
577
 					self.total_lines_removed += deleted
578
 
578
 
579
 				else:
579
 				else:
580
-					print 'Warning: failed to handle line "%s"' % line
580
+					print( 'Warning: failed to handle line "%s"' % line)
581
 					(files, inserted, deleted) = (0, 0, 0)
581
 					(files, inserted, deleted) = (0, 0, 0)
582
 				#self.changes_by_date[stamp] = { 'files': files, 'ins': inserted, 'del': deleted }
582
 				#self.changes_by_date[stamp] = { 'files': files, 'ins': inserted, 'del': deleted }
583
 		self.total_lines += total_lines
583
 		self.total_lines += total_lines
622
 						self.changes_by_date_by_author[stamp][author]['commits'] = self.authors[author]['commits']
622
 						self.changes_by_date_by_author[stamp][author]['commits'] = self.authors[author]['commits']
623
 						files, inserted, deleted = 0, 0, 0
623
 						files, inserted, deleted = 0, 0, 0
624
 					except ValueError:
624
 					except ValueError:
625
-						print 'Warning: unexpected line "%s"' % line
625
+						print( 'Warning: unexpected line "%s"' % line)
626
 				else:
626
 				else:
627
-					print 'Warning: unexpected line "%s"' % line
627
+					print( 'Warning: unexpected line "%s"' % line)
628
 			else:
628
 			else:
629
 				numbers = getstatsummarycounts(line);
629
 				numbers = getstatsummarycounts(line);
630
 
630
 
631
 				if len(numbers) == 3:
631
 				if len(numbers) == 3:
632
-					(files, inserted, deleted) = map(lambda el : int(el), numbers)
632
+					(files, inserted, deleted) = list(map(lambda el : int(el), numbers))
633
 				else:
633
 				else:
634
-					print 'Warning: failed to handle line "%s"' % line
634
+					print( 'Warning: failed to handle line "%s"' % line)
635
 					(files, inserted, deleted) = (0, 0, 0)
635
 					(files, inserted, deleted) = (0, 0, 0)
636
 	
636
 	
637
 	def refine(self):
637
 	def refine(self):
744
 					shutil.copyfile(src, path + '/' + file)
744
 					shutil.copyfile(src, path + '/' + file)
745
 					break
745
 					break
746
 			else:
746
 			else:
747
-				print 'Warning: "%s" not found, so not copied (searched: %s)' % (file, basedirs)
747
+				print( 'Warning: "%s" not found, so not copied (searched: %s)' % (file, basedirs))
748
 
748
 
749
 		f = open(path + "/index.html", 'w')
749
 		f = open(path + "/index.html", 'w')
750
 		format = '%Y-%m-%d %H:%M:%S'
750
 		format = '%Y-%m-%d %H:%M:%S'
1153
 		f.write('<table class="tags">')
1153
 		f.write('<table class="tags">')
1154
 		f.write('<tr><th>Name</th><th>Date</th><th>Commits</th><th>Authors</th></tr>')
1154
 		f.write('<tr><th>Name</th><th>Date</th><th>Commits</th><th>Authors</th></tr>')
1155
 		# sort the tags by date desc
1155
 		# sort the tags by date desc
1156
-		tags_sorted_by_date_desc = map(lambda el : el[1], reversed(sorted(map(lambda el : (el[1]['date'], el[0]), data.tags.items()))))
1156
+		tags_sorted_by_date_desc = list(map(lambda el : el[1], reversed(sorted(map(lambda el : (el[1]['date'], el[0]), data.tags.items())))))
1157
 		for tag in tags_sorted_by_date_desc:
1157
 		for tag in tags_sorted_by_date_desc:
1158
 			authorinfo = []
1158
 			authorinfo = []
1159
 			self.authors_by_commits = getkeyssortedbyvalues(data.tags[tag]['authors'])
1159
 			self.authors_by_commits = getkeyssortedbyvalues(data.tags[tag]['authors'])
1168
 		self.createGraphs(path)
1168
 		self.createGraphs(path)
1169
 	
1169
 	
1170
 	def createGraphs(self, path):
1170
 	def createGraphs(self, path):
1171
-		print 'Generating graphs...'
1171
+		print( 'Generating graphs...')
1172
 
1172
 
1173
 		# hour of day
1173
 		# hour of day
1174
 		f = open(path + '/hour_of_day.plot', 'w')
1174
 		f = open(path + '/hour_of_day.plot', 'w')
1370
 		for f in files:
1370
 		for f in files:
1371
 			out = getpipeoutput([gnuplot_cmd + ' "%s"' % f])
1371
 			out = getpipeoutput([gnuplot_cmd + ' "%s"' % f])
1372
 			if len(out) > 0:
1372
 			if len(out) > 0:
1373
-				print out
1373
+				print( out)
1374
 
1374
 
1375
 	def printHeader(self, f, title = ''):
1375
 	def printHeader(self, f, title = ''):
1376
 		f.write(
1376
 		f.write(
1401
 """)
1401
 """)
1402
 		
1402
 		
1403
 def usage():
1403
 def usage():
1404
-	print """
1404
+	text = """
1405
 Usage: gitstats [options] <gitpath..> <outputpath>
1405
 Usage: gitstats [options] <gitpath..> <outputpath>
1406
 
1406
 
1407
 Options:
1407
 Options:
1412
 
1412
 
1413
 Please see the manual page for more details.
1413
 Please see the manual page for more details.
1414
 """ % conf
1414
 """ % conf
1415
+	print(text)
1415
 
1416
 
1416
 
1417
 
1417
 class GitStats:
1418
 class GitStats:
1442
 		except OSError:
1443
 		except OSError:
1443
 			pass
1444
 			pass
1444
 		if not os.path.isdir(outputpath):
1445
 		if not os.path.isdir(outputpath):
1445
-			print 'FATAL: Output path is not a directory or does not exist'
1446
+			print( 'FATAL: Output path is not a directory or does not exist')
1446
 			sys.exit(1)
1447
 			sys.exit(1)
1447
 
1448
 
1448
 		if not getgnuplotversion():
1449
 		if not getgnuplotversion():
1449
-			print 'gnuplot not found'
1450
+			print( 'gnuplot not found')
1450
 			sys.exit(1)
1451
 			sys.exit(1)
1451
 
1452
 
1452
-		print 'Output path: %s' % outputpath
1453
+		print( 'Output path: %s' % outputpath)
1453
 		cachefile = os.path.join(outputpath, 'gitstats.cache')
1454
 		cachefile = os.path.join(outputpath, 'gitstats.cache')
1454
 
1455
 
1455
 		data = GitDataCollector()
1456
 		data = GitDataCollector()
1456
 		data.loadCache(cachefile)
1457
 		data.loadCache(cachefile)
1457
 
1458
 
1458
 		for gitpath in args[0:-1]:
1459
 		for gitpath in args[0:-1]:
1459
-			print 'Git path: %s' % gitpath
1460
+			print( 'Git path: %s' % gitpath)
1460
 
1461
 
1461
 			prevdir = os.getcwd()
1462
 			prevdir = os.getcwd()
1462
 			os.chdir(gitpath)
1463
 			os.chdir(gitpath)
1463
 
1464
 
1464
-			print 'Collecting data...'
1465
+			print( 'Collecting data...')
1465
 			data.collect(gitpath)
1466
 			data.collect(gitpath)
1466
 
1467
 
1467
 			os.chdir(prevdir)
1468
 			os.chdir(prevdir)
1468
 
1469
 
1469
-		print 'Refining data...'
1470
+		print( 'Refining data...')
1470
 		data.saveCache(cachefile)
1471
 		data.saveCache(cachefile)
1471
 		data.refine()
1472
 		data.refine()
1472
 
1473
 
1473
 		os.chdir(rundir)
1474
 		os.chdir(rundir)
1474
 
1475
 
1475
-		print 'Generating report...'
1476
+		print( 'Generating report...')
1476
 		report = HTMLReportCreator()
1477
 		report = HTMLReportCreator()
1477
 		report.create(data, outputpath)
1478
 		report.create(data, outputpath)
1478
 
1479
 
1479
 		time_end = time.time()
1480
 		time_end = time.time()
1480
 		exectime_internal = time_end - time_start
1481
 		exectime_internal = time_end - time_start
1481
-		print 'Execution time %.5f secs, %.5f secs (%.2f %%) in external commands)' % (exectime_internal, exectime_external, (100.0 * exectime_external) / exectime_internal)
1482
+		print( 'Execution time %.5f secs, %.5f secs (%.2f %%) in external commands)' % (exectime_internal, exectime_external, (100.0 * exectime_external) / exectime_internal))
1482
 		if sys.stdin.isatty():
1483
 		if sys.stdin.isatty():
1483
-			print 'You may now run:'
1484
-			print
1485
-			print '   sensible-browser \'%s\'' % os.path.join(outputpath, 'index.html').replace("'", "'\\''")
1486
-			print
1484
+			print( 'You may now run:')
1485
+			print()
1486
+			print( '   sensible-browser \'%s\'' % os.path.join(outputpath, 'index.html').replace("'", "'\\''"))
1487
+			print()
1487
 
1488
 
1488
 if __name__=='__main__':
1489
 if __name__=='__main__':
1489
 	g = GitStats()
1490
 	g = GitStats()