summaryrefslogtreecommitdiff
path: root/portato/helper.py
blob: d3fc70b2ebd63d0fd6499a833bcd6026a95c8a76 (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
# -*- coding: utf-8 -*-
#
# File: portato/helper.py
# This file is part of the Portato-Project, a graphical portage-frontend.
#
# Copyright (C) 2006-2009 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.
"""
from __future__ import absolute_import, with_statement

import os, signal, logging, grp

from .log import set_log_level

debug         = logging.getLogger("portatoLogger").debug
info         = logging.getLogger("portatoLogger").info
warning     = logging.getLogger("portatoLogger").warning
error         = logging.getLogger("portatoLogger").error
critical     = logging.getLogger("portatoLogger").critical

def N_ (s):
    return s

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 get_runsystem ():
     # check for sabayon first, as sabayon also has the gentoo release
    for sp in ("/etc/sabayon-release", "/etc/sabayon-edition"):
        if os.path.exists(sp):
            with open(sp) as r:
                return ("Sabayon", r.readline().strip())
    
    if os.path.exists("/etc/gentoo-release"):
            return ("Gentoo", "")

    else: return ("Unknown", "")

def paren_reduce(mystr):
    """
    Take a string and convert all paren enclosed entities into sublists, optionally
    futher splitting the list elements by spaces.
    
    This function is copied from portage.

    Example usage:
        >>> paren_reduce('foobar foo ( bar baz )')
        ['foobar', 'foo', ['bar', 'baz']]

    @param mystr: The string to reduce
    @type mystr: String
    @rtype: Array
    @return: The reduced string in an array
    """
    mylist = []
    while mystr:
        left_paren = mystr.find("(")
        has_left_paren = left_paren != -1
        right_paren = mystr.find(")")
        has_right_paren = right_paren != -1
        if not has_left_paren and not has_right_paren:
            freesec = mystr
            subsec = None
            tail = ""
        elif mystr[0] == ")":
            return [mylist,mystr[1:]]
        elif has_left_paren and not has_right_paren:
            error(_("Invalid dependency string"))
            return []
        elif has_left_paren and left_paren < right_paren:
            freesec,subsec = mystr.split("(",1)
            subsec,tail = paren_reduce(subsec)
        else:
            subsec,tail = mystr.split(")",1)
            subsec = filter(None, subsec.split(" "))
            return [mylist+subsec,tail]
        mystr = tail
        if freesec:
            mylist = mylist + filter(None, freesec.split(" "))
        if subsec is not None:
            mylist = mylist + [subsec]
    return mylist

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 not isinstance(listOfLists, list):
        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"""
    # 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:
        n = len(s)
        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