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
|
# -*- coding: utf-8 -*-
#
# File: portato/db/hash.py
# This file is part of the Portato-Project, a graphical portage-frontend.
#
# Copyright (C) 2006-2010 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>
from __future__ import absolute_import, with_statement
import re
from collections import defaultdict
from ..helper import info
from ..backend import system
from .database import Database, PkgData
class HashDatabase (Database):
"""An internal database which holds a simple dictionary cat -> [package_list]."""
lock = Database.lock
def __init__ (self, session):
"""Constructor."""
Database.__init__(self)
self.session = session
self.__initialize()
self.populate()
def search_types(self):
return Database.SEARCH_NAME
def __initialize (self):
self._db = defaultdict(list)
self.inst_cats = set([self.ALL])
self._restrict = None
def __sort_key (self, x):
return x.pkg.lower()
@lock
def populate (self, category = None):
# get the lists
packages = system.find_packages(category, with_version = False)
installed = system.find_packages(category, system.SET_INSTALLED, with_version = False)
# cycle through packages
for p in packages:
cat, pkg = p.split("/")
inst = p in installed
t = PkgData(cat, pkg, inst, False)
self._db[cat].append(t)
self._db[self.ALL].append(t)
if inst:
self.inst_cats.add(cat)
for key in self._db: # sort alphabetically
self._db[key].sort(key = self.__sort_key)
@lock
def get_cat (self, cat = None, byName = True, showDisabled = False):
if not cat:
cat = self.ALL
def get_pkgs():
if byName:
for pkg in self._db[cat]:
if showDisabled or not pkg.disabled:
yield pkg
else:
ninst = []
for pkg in self._db[cat]:
if not showDisabled and pkg.disabled: continue
if pkg.inst:
yield pkg
else:
ninst.append(pkg)
for pkg in ninst:
yield pkg
try:
if self.restrict:
return (pkg for pkg in get_pkgs() if self.restrict.search(pkg.cat+"/"+pkg.pkg))
else:
return get_pkgs()
except KeyError: # cat is in category list - but not in portage
info(_("Catched KeyError => %s seems not to be an available category. Have you played with rsync-excludes?"), cat)
@lock
def get_categories (self, installed = False):
if not self.restrict:
if installed:
cats = self.inst_cats
else:
cats = self._db.iterkeys()
else:
if installed:
cats = set((pkg.cat for pkg in self.get_cat(self.ALL) if pkg.inst))
else:
cats = set((pkg.cat for pkg in self.get_cat(self.ALL)))
if len(cats)>1:
cats.add(self.ALL)
return (cat for cat in cats)
@lock
def reload (self, cat = None):
if cat:
del self._db[cat]
try:
self.inst_cats.remove(cat)
except KeyError: # not in inst_cats - can be ignored
pass
self._db[self.ALL] = filter(lambda x: x.cat != cat, self._db[self.ALL])
self.populate(cat+"/*")
else:
self.__initialize()
self.populate()
@lock
def disable (self, cpv):
cat, pkg = cpv.split("/")
c = self._db[cat]
p = c[c.index(PkgData(cat, pkg))]
p.disabled = True
def get_restrict (self):
return self._restrict
@lock
def set_restrict (self, restrict):
if not restrict:
self._restrict = None
else:
try:
regex = re.compile(restrict, re.I)
except re.error, e:
info(_("Error while compiling search expression: '%s'."), str(e))
else: # only set self._restrict if no error occurred
self._restrict = regex
restrict = property(get_restrict, set_restrict)
|