Gentoo Archives: gentoo-commits

From: Slava Bacherikov <slava@××××××××××××××.ua>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/gentoo-packages:master commit in: gpackages/libs/package_info/, gpackages/libs/package_info/generic_metadata/
Date: Fri, 06 Jul 2012 23:10:00
Message-Id: 1341583307.f9a040809c1ed0bf5fffea0602be20b55f5738d2.bacher09@gentoo
1 commit: f9a040809c1ed0bf5fffea0602be20b55f5738d2
2 Author: Slava Bacherikov <slava <AT> bacher09 <DOT> org>
3 AuthorDate: Fri Jul 6 13:36:29 2012 +0000
4 Commit: Slava Bacherikov <slava <AT> bacherikov <DOT> org <DOT> ua>
5 CommitDate: Fri Jul 6 14:01:47 2012 +0000
6 URL: http://git.overlays.gentoo.org/gitweb/?p=proj/gentoo-packages.git;a=commit;h=f9a04080
7
8 Add license text object
9
10 ---
11 .../package_info/generic_metadata/license_text.py | 175 ++++++++++++++++++++
12 gpackages/libs/package_info/mixins.py | 14 ++-
13 2 files changed, 188 insertions(+), 1 deletions(-)
14
15 diff --git a/gpackages/libs/package_info/generic_metadata/license_text.py b/gpackages/libs/package_info/generic_metadata/license_text.py
16 new file mode 100644
17 index 0000000..36e8336
18 --- /dev/null
19 +++ b/gpackages/libs/package_info/generic_metadata/license_text.py
20 @@ -0,0 +1,175 @@
21 +from ..generic import ToStrMixin, file_get_content
22 +from itertools import ifilter, izip
23 +from functools import wraps
24 +import collections
25 +import os
26 +import os.path
27 +
28 +def reverse_enumerate(lst):
29 + return izip(xrange(len(lst)-1, -1, -1), reversed(lst))
30 +
31 +def filter_predicate(file_name, file_path):
32 + full_file = os.path.join(file_path, file_name)
33 + return not file_name.startswith('.') and os.path.isfile(full_file)
34 +
35 +class LicenseMixin(ToStrMixin):
36 +
37 + def get_license(self, license):
38 + try:
39 + return self[license]
40 + except (TypeError, KeyError):
41 + return None
42 +
43 +class Licenses(LicenseMixin):
44 + __slots__ = ('is_valid', 'licenses_dict', 'licenses_path', 'tree_path')
45 +
46 + def __init__(self, tree_path):
47 + self.licenses_dict = {}
48 + self.is_valid = False
49 + self.tree_path = tree_path
50 + self.licenses_path = os.path.join(tree_path, 'licenses')
51 + if os.path.isdir(self.licenses_path):
52 + self.is_valid = True
53 + self._fetch_licenses_list()
54 +
55 + def _fetch_licenses_list(self):
56 + dir_list = os.listdir(self.licenses_path)
57 + f = lambda x: filter_predicate(x, self.licenses_path)
58 + licenses_list = ((s.lower(), s) for s in ifilter(f, dir_list))
59 + self.licenses_dict = dict(licenses_list)
60 +
61 + def __len__(self):
62 + return len(self.licenses_dict)
63 +
64 + def __contains__(self, item):
65 + item = unicode(item)
66 + return item.lower() in self.licenses_dict
67 +
68 + def __iter__(self):
69 + return self.licenses_dict.itervalues()
70 +
71 + def __eq__(self, other):
72 + if isinstance(other, Licenses):
73 + return other.tree_path == self.tree_path
74 +
75 + def __ne__(self, other):
76 + return not self.__eq__(other)
77 +
78 + def __or__(self, other):
79 + return LicensesSet([self, other])
80 +
81 + def hash(self):
82 + return hash(self.tree_path)
83 +
84 + def get_license_path(self, license):
85 + try:
86 + key = unicode(license).lower()
87 + except:
88 + raise TypeError
89 + return os.path.join(self.licenses_path, self.licenses_dict[key])
90 +
91 + def __getitem__(self, key):
92 + return file_get_content(self.get_license_path(key))
93 +
94 + def __unicode__(self):
95 + return unicode(self.tree_path)
96 +
97 +def preinit_cache(func):
98 + @wraps(func)
99 + def wrapper(self, *args, **kwargs):
100 + if not self._cache_is_init:
101 + self._precache_objects()
102 + return func(self, *args, **kwargs)
103 +
104 + return wrapper
105 +
106 +class LicensesSet(LicenseMixin):
107 +
108 + __slots__ = ('licenses_list', 'licenses_set', '_cache', '_cache_is_init')
109 +
110 + def __init__(self, val):
111 + self.licenses_list = []
112 + self.licenses_set = set()
113 + self._cache = {}
114 + self._cache_is_init = False
115 + if isinstance(val, LicensesSet):
116 + obj = val.copy()
117 + self.licenses_list = obj.licenses_list
118 + self.licenses_set = obj.licenses_set
119 + self._cache = obj._cache
120 + self._cache_is_init = obj._cache_is_init
121 + else:
122 + if not isinstance(val, collections.Iterable):
123 + raise TypeError
124 +
125 + for item in val:
126 + if not isinstance(item, Licenses):
127 + raise TypeError
128 + self.add_licenses(item)
129 +
130 + def _precache_objects(self):
131 + cache = {}
132 + for num, licenses in reverse_enumerate(self.licenses_list):
133 + for key in licenses.licenses_dict.iterkeys():
134 + cache[key] = num
135 + self._cache = cache
136 + self._cache_is_init = True
137 +
138 + def copy(self):
139 + return LicensesSet(self.licenses_list)
140 +
141 + def add_licenses(self, licenses):
142 + if not isinstance(licenses, Licenses):
143 + return None
144 +
145 + if (not licenses in self.licenses_set) and licenses.is_valid:
146 + self.licenses_list.append(licenses)
147 + self.licenses_set.add(licenses)
148 + self._cache_is_init = False
149 +
150 + def merge(self, licenses):
151 + if isinstance(licenses, Licenses):
152 + self.add_licenses(licenses)
153 + elif isinstance(licenses, LicensesSet):
154 + for licenses in licenses.licenses_list:
155 + self.add_licenses(licenses)
156 + else:
157 + raise TypeError
158 +
159 + def __or__(self, other):
160 + try:
161 + obj = self.copy()
162 + obj.merge(other)
163 + return obj
164 + except TypeError:
165 + return NotImplemented
166 +
167 + def __ior__(self, other):
168 + return self.merge(other)
169 +
170 + @preinit_cache
171 + def __contains__(self, item):
172 + item = unicode(item)
173 + return item.lower() in self._cache
174 +
175 + @preinit_cache
176 + def __len__(self):
177 + return len(self._cache)
178 +
179 + @preinit_cache
180 + def __getitem__(self, key):
181 + try:
182 + key = unicode(key).lower()
183 + except:
184 + raise TypeError
185 + return self.licenses_list[self._cache[key.lower()]][key]
186 +
187 + def __unicode__(self):
188 + res = ""
189 + for num ,licenses in enumerate(self.licenses_list):
190 + if num == 0:
191 + res += repr(licenses)
192 + else:
193 + res += ', %s' % repr(licenses)
194 + return '[%s]' % res
195 +
196
197 diff --git a/gpackages/libs/package_info/mixins.py b/gpackages/libs/package_info/mixins.py
198 index c18607e..a5cf9d1 100644
199 --- a/gpackages/libs/package_info/mixins.py
200 +++ b/gpackages/libs/package_info/mixins.py
201 @@ -13,6 +13,8 @@ from .generic_metadata.category_metadata import CategoryMetadata
202 from .generic_metadata.package_metadata import PackageMetaData
203 #License group metadata
204 from .generic_metadata.license_groups import LicenseGroups
205 +# License text
206 +from .generic_metadata.license_text import Licenses, LicensesSet
207 # News
208 from .generic_metadata.news import News
209 # Validators
210 @@ -100,6 +102,10 @@ class PortageHerdsMixin(object):
211 "Return new `LicenseGroups` object"
212 return LicenseGroups()
213
214 + @cached_property
215 + def licenses(self):
216 + return LicensesSet([tree.licenses for tree in self.iter_trees()])
217 +
218 def _get_info_by_func(func, path1, path2):
219 path = os.path.join(path1, path2)
220 try:
221 @@ -140,6 +146,12 @@ class PortTreeNewsMixin(object):
222 class PortTreeIteratorMixin(AutoGeneratorMixin):
223 main_iterator = 'iter_categories'
224 generator_names = ('iter_packages', 'iter_ebuilds')
225 +
226 +class PortTreeLicenseMixin(object):
227 +
228 + @cached_property
229 + def licenses(self):
230 + return Licenses(self.porttree_path)
231
232 class CategoryBaseMixin(ToStrMixin):
233
234 @@ -362,7 +374,7 @@ class PortageMixin(PortageGenericMixin, PortageIteratorMixin, AbstractPortage):
235 pass
236
237 class PortTreeMixin(PortTreeBaseMixin, PortTreeIteratorMixin, \
238 - PortTreeNewsMixin, AbstractPortTree):
239 + PortTreeNewsMixin, PortTreeLicenseMixin, AbstractPortTree):
240 pass
241
242 class CategoryMixin(CategoryBaseMixin, CategoryIteratorMixin, AbstractCategory):