summaryrefslogtreecommitdiff
path: root/portato/helper.py
blob: cc797b94c71d83a5bee8b52997e8a18fdfdc6f61 (plain)
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# -*- coding: utf-8 -*-
#
# File: portato/helper.py
# This file is part of the Portato-Project, a graphical portage-frontend.
#
# Copyright (C) 2006-2007 René 'Necoro' Neumann
# This is free software.  You may redistribute copies of it under the terms of
# the GNU General Public License version 2.
# There is NO WARRANTY, to the extent permitted by law.
#
# Written by René 'Necoro' Neumann <necoro@necoro.net> et.al.

"""
Some nice functions used in the program.

@var DEBUG: Boolean controlling whether to printout debug messages.
@type DEBUG: boolean
"""

import traceback, os.path, sys, types
import os, signal

DEBUG = True

def set_debug (d):
	"""Sets the global DEBUG variable. Do not set it by your own - always use this function.

	@param d: True to enable debugging; False otherwise
	@type d: boolean"""

	global DEBUG
	DEBUG = d

def debug(*args, **kwargs):
	"""Prints a debug message including filename and lineno.
	A variable number of positional arguments are allowed.

	If debug(obj0, obj1, obj2) is called, the text part of the output 
	looks like the output from print obj0, obj1, obj2.
	
	@keyword name: Use the given name instead the correct function name.
	@keyword file: Output file to use.
	@keyword minus: The value given is the amount of frames to ignore in the stack to return the correct function call.
	This should be used if you are wrapping the debug call.
	@keyword warn: Prints the message as a warning. Value of DEBUG is ignored.
	@keyword error: Prints the message as an error. Value of DEBUG is ignored."""

	if not DEBUG and not ("warn" in kwargs or "error" in kwargs): return
	
	stack = traceback.extract_stack()
	minus = -2
	if "minus" in kwargs:
		minus = minus - kwargs["minus"]
	a, b, c, d = stack[minus]
	a = os.path.basename(a)
	out = []
	for obj in args:
		out.append(str(obj))
	text = ' '.join(out)
	if "name" in kwargs:
		text = 'In %s (%s:%s): %s' % (kwargs["name"], a, b, text)
	else:
		text = 'In %s (%s:%s): %s' % (c, a, b, text)
	
	outfile = sys.stdout
	surround = "DEBUG"

	if "warn" in kwargs:
		outfile = sys.stderr
		surround = "WARNING"
	elif "error" in kwargs:
		outfile = sys.stderr
		surround = "ERROR"

	text = ("***%s*** %s ***%s***" % (surround, text, surround))
	
	if "file" in kwargs:
		f = open(kwargs["file"], "a+")
		f.write(text+"\n")
		f.close()
	else:
		print >> outfile, text

def send_signal_to_group (sig):
	"""Sends a signal to all processes of our process group (w/o ourselves).
	
	@param sig: signal number to send
	@type sig: int"""

	def handler (sig, stack):
		"""Ignores the signal exactly one time and then restores the default."""
		signal.signal(sig, signal.SIG_DFL)
	
	signal.signal(sig, handler)
	
	pgid = os.getpgrp()
	os.killpg(pgid, sig)

def am_i_root ():
	"""Returns True if the current user is root, False otherwise.
	@rtype: boolean"""

	from plugin import hook

	@hook("am_i_root")
	def __am_i_root():
		if os.getuid() == 0:
			return True
		else:
			return False
	
	return __am_i_root()

def flatten (listOfLists):
	"""Flattens the given list of lists.

	@param listOfLists: the list of lists to flatten
	@type listOfLists: list of lists
	@returns: flattend list
	@rtype: list"""

	if type(listOfLists) != types.ListType:
		return [listOfLists]

	ret = []
	for r in listOfLists:
		ret.extend(flatten(r))

	return ret

def unique_array(s):
	"""Stolen from portage_utils:
	lifted from python cookbook, credit: Tim Peters
	Return a list of the elements in s in arbitrary order, sans duplicates"""
	n = len(s)
	# assume all elements are hashable, if so, it's linear
	try:
		return list(set(s))
	except TypeError:
		pass

	# so much for linear.  abuse sort.
	try:
		t = list(s)
		t.sort()
	except TypeError:
		pass
	else:
		assert n > 0
		last = t[0]
		lasti = i = 1
		while i < n:
			if t[i] != last:
				t[lasti] = last = t[i]
				lasti += 1
			i += 1
		return t[:lasti]

	# blah.	 back to original portage.unique_array
	u = []
	for x in s:
		if x not in u:
			u.append(x)
	return u