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/apps/packages/, gpackages/libs/, ...
Date: Wed, 06 Jun 2012 22:49:12
Message-Id: 1339015177.57baa89e8bd8da906c8a001c92c7354635715b93.bacher09@gentoo
1 commit: 57baa89e8bd8da906c8a001c92c7354635715b93
2 Author: Slava Bacherikov <slava <AT> bacher09 <DOT> org>
3 AuthorDate: Wed Jun 6 20:39:37 2012 +0000
4 Commit: Slava Bacherikov <slava <AT> bacherikov <DOT> org <DOT> ua>
5 CommitDate: Wed Jun 6 20:39:37 2012 +0000
6 URL: http://git.overlays.gentoo.org/gitweb/?p=proj/gentoo-packages.git;a=commit;h=57baa89e
7
8 Add support multiple repo
9
10 ---
11 .../packages/management/commands/scanpackages.py | 3 +-
12 gpackages/apps/packages/models.py | 14 +++--
13 gpackages/apps/packages/scan.py | 35 +++++++----
14 gpackages/libs/generic.py | 28 +++++++-
15 gpackages/libs/porttree.py | 69 ++++++++++++++++---
16 5 files changed, 117 insertions(+), 32 deletions(-)
17
18 diff --git a/gpackages/apps/packages/management/commands/scanpackages.py b/gpackages/apps/packages/management/commands/scanpackages.py
19 index 27cc782..35a117b 100644
20 --- a/gpackages/apps/packages/management/commands/scanpackages.py
21 +++ b/gpackages/apps/packages/management/commands/scanpackages.py
22 @@ -12,5 +12,6 @@ class Command(BaseCommand):
23 help = 'Will scan package tree and update info about it in database'
24 def handle(self, *args, **options):
25 st = datetime.datetime.now()
26 - scan.scanpackages()
27 + #scan.scanpackages()
28 + scan.scan_all_repos()
29 print (datetime.datetime.now() - st).total_seconds()
30
31 diff --git a/gpackages/apps/packages/models.py b/gpackages/apps/packages/models.py
32 index 90665bd..80e4103 100644
33 --- a/gpackages/apps/packages/models.py
34 +++ b/gpackages/apps/packages/models.py
35 @@ -23,10 +23,13 @@ class ArchesModel(models.Model):
36 return self.name
37
38 class RepositoryModel(models.Model):
39 - name = models.CharField(max_length = 60)
40 + name = models.CharField(unique = True, max_length = 60)
41 description = models.TextField(blank = True, null = True)
42 # And other fields
43
44 + def __unicode__(self):
45 + return self.name
46 +
47 class CategoryModel(models.Model):
48 def __init__(self, *args, **kwargs):
49 category_object = None
50 @@ -125,9 +128,10 @@ class PackageModel(AbstractDateTimeModel):
51
52 if 'package' in kwargs:
53 package_object = kwargs['package']
54 + del kwargs['package']
55
56 if isinstance(package_object, Package):
57 - super(PackageModel, self).__init__()
58 + super(PackageModel, self).__init__(*args, **kwargs)
59 self.init_by_package(package_object, category = kwargs.get('category'))
60 else:
61 super(PackageModel, self).__init__(*args, **kwargs)
62 @@ -136,7 +140,7 @@ class PackageModel(AbstractDateTimeModel):
63
64 name = models.CharField(max_length = 254)
65 category = models.ForeignKey(CategoryModel)
66 - changelog = models.TextField(blank = True)
67 + changelog = models.TextField(blank = True, null = True)
68 changelog_hash = models.CharField(max_length = 128)
69 manifest_hash = models.CharField(max_length = 128)
70 metadata_hash = models.CharField(max_length = 128)
71 @@ -148,6 +152,7 @@ class PackageModel(AbstractDateTimeModel):
72 maintainers = models.ManyToManyField(MaintainerModel, blank = True)
73
74 description = models.TextField(blank = True, null = True)
75 + repository = models.ForeignKey(RepositoryModel)
76 # Different versions can have different licenses, or homepages.
77
78 objects = managers.PackageManager()
79 @@ -188,7 +193,7 @@ class PackageModel(AbstractDateTimeModel):
80 self.description = package.description
81
82 class Meta:
83 - unique_together = ('name', 'category')
84 + unique_together = ('name', 'category', 'repository')
85
86 class UseFlagModel(models.Model):
87 name = models.CharField(unique = True, max_length = 60)
88 @@ -221,7 +226,6 @@ class LicensModel(models.Model):
89
90 class EbuildModel(AbstractDateTimeModel):
91 package = models.ForeignKey(PackageModel)
92 - #repository = models.ForeignKey(RepositoryModel)
93 version = models.CharField(max_length = 26)
94 revision = models.CharField(max_length = 12)
95 use_flags = models.ManyToManyField(UseFlagModel)
96
97 diff --git a/gpackages/apps/packages/scan.py b/gpackages/apps/packages/scan.py
98 index f739c69..add62f1 100644
99 --- a/gpackages/apps/packages/scan.py
100 +++ b/gpackages/apps/packages/scan.py
101 @@ -1,16 +1,19 @@
102 from packages import models
103 +from django.db import IntegrityError
104 from collections import defaultdict
105 +from generic import StrThatIgnoreCase
106 import porttree
107 import herds
108 import use_info
109
110 -porttree = porttree.PortTree()
111 +portage = porttree.Portage()
112
113 def _get_from_cache(cache, what):
114 save_to = []
115 geted_items = set()
116 for item in what:
117 - if item in cache:
118 + if item.lower() in cache:
119 + item = StrThatIgnoreCase(item)
120 geted_items.add(item)
121 save_to.append(cache[item])
122 return save_to, geted_items
123 @@ -26,8 +29,9 @@ def _update_cache_by_queryset(cache, queryset, field_name):
124 if queryset is None:
125 return None
126 for item in queryset:
127 - cache[getattr(item, field_name)] = item
128 - geted_items.add(getattr(item, field_name))
129 + val = StrThatIgnoreCase(getattr(item, field_name))
130 + cache[val] = item
131 + geted_items.add(val)
132 return geted_items
133
134 def _get_from_database_and_update_cache(Model, field_name, request_items, cache):
135 @@ -159,6 +163,7 @@ def update_globals_uses_descriptions():
136
137
138 def scan_uses_description():
139 + # need changes for support many repos !!!
140 uses_local = use_info.get_local_uses_info()
141 existend_use_objects = models.UseFlagModel.objects.filter(name__in = uses_local.keys())
142 existend_use_local_descr = models.UseFlagDescriptionModel.objects.all()
143 @@ -196,18 +201,21 @@ def scan_uses_description():
144 use_desc_obj.save(force_update = True)
145 models.UseFlagDescriptionModel.objects.bulk_create(to_create)
146
147 -def scanpackages(delete = True, force_update = False):
148 - licenses_cache = {}
149 +licenses_cache = {}
150 +uses_cache = {}
151 +arches_cache = {}
152 +homepages_cache = {}
153 +herds_cache = {}
154 +maintainers_cache = {}
155 +def scanpackages(porttree, porttree_obj, delete = True, force_update = False):
156 def get_licenses_objects(ebuild):
157 licenses = ebuild.licenses
158 return _get_items(licenses, models.LicensModel, 'name', licenses_cache)
159
160 - uses_cache = {}
161 def get_uses_objects(ebuild):
162 uses = [ use.name for use in ebuild.iter_uses() ]
163 return _get_items(uses, models.UseFlagModel, 'name', uses_cache)
164
165 - arches_cache = {}
166 def get_keywords_objects(ebuild, ebuild_object):
167 keywords_list = []
168 for keyword in ebuild.get_keywords():
169 @@ -226,13 +234,11 @@ def scanpackages(delete = True, force_update = False):
170 models.Keyword.objects.bulk_create(keywords_list)
171
172
173 - homepages_cache = {}
174 def get_homepages_objects(ebuild):
175 homepages = ebuild.homepages
176 return _get_items(homepages, models.HomepageModel, 'url', homepages_cache)
177
178
179 - herds_cache, maintainers_cache = scan_herds()
180 def get_maintainers_objects(package):
181 maintainers = package.metadata.maintainers()
182 objects = []
183 @@ -319,8 +325,8 @@ def scanpackages(delete = True, force_update = False):
184 category_object, category_created = models.CategoryModel.objects.get_or_create(category = category)
185 existend_categorys.append(category_object.pk)
186 for package in category.iter_packages():
187 - print package
188 - package_object, package_created = models.PackageModel.objects.get_or_create(package = package, category = category_object)
189 + print('%s [%s]' % (package, porttree))
190 + package_object, package_created = models.PackageModel.objects.get_or_create(package = package, category = category_object, repository = porttree_obj)
191 existend_packages.append(package_object.pk)
192 if not package_created:
193 if package_object.check_or_need_update(package) or force_update:
194 @@ -341,3 +347,8 @@ def scanpackages(delete = True, force_update = False):
195 #models.CategoryModel.objects.exclude(pk__in = existend_categorys).delete()
196
197
198 +def scan_all_repos():
199 + herds_cache, maintainers_cache = scan_herds()
200 + for repo in portage.iter_trees():
201 + repo_obj, repo_created = models.RepositoryModel.objects.get_or_create(name = repo.name)
202 + scanpackages(repo, repo_obj)
203
204 diff --git a/gpackages/libs/generic.py b/gpackages/libs/generic.py
205 index ed08d93..c3d8d2b 100644
206 --- a/gpackages/libs/generic.py
207 +++ b/gpackages/libs/generic.py
208 @@ -2,6 +2,21 @@ import os.path
209 import hashlib
210 from datetime import datetime
211
212 +class StrThatIgnoreCase(unicode):
213 +
214 + def __init__(self, value):
215 + super(StrThatIgnoreCase, self).__init__(value)
216 + self._forcmp = value.lower()
217 +
218 + def __hash__(self):
219 + return hash(self._forcmp)
220 +
221 + def __eq__(self, other):
222 + return self._forcmp == unicode(other).lower()
223 +
224 + def __ne__(self, other):
225 + return self._forcmp != unicode(other).lower()
226 +
227 class ToStrMixin(object):
228 """Abstract class for inheritence, allow add simple `__str__` and `__repr__`
229 methods
230 @@ -13,12 +28,19 @@ class ToStrMixin(object):
231 return '<%s %s>' % (type(self).__name__, self.__str__())
232
233
234 +def file_get_content(file_path):
235 + if os.path.exists(file_path):
236 + with open(file_path, 'r') as f:
237 + content = f.read()
238 + return content
239 + else:
240 + return None
241 +
242 def file_sha1(file_path):
243 sha1 = 'NULL'
244 if os.path.exists(file_path):
245 - f = open(file_path, 'r')
246 - sha1 = hashlib.sha1(f.read()).hexdigest()
247 - f.close()
248 + with open(file_path, 'r') as f:
249 + sha1 = hashlib.sha1(f.read()).hexdigest()
250 return sha1
251
252 def file_mtime(file_path):
253
254 diff --git a/gpackages/libs/porttree.py b/gpackages/libs/porttree.py
255 index 5a4da3a..5b1dba8 100644
256 --- a/gpackages/libs/porttree.py
257 +++ b/gpackages/libs/porttree.py
258 @@ -6,7 +6,8 @@ from portage.exception import PortageException, FileNotFound, InvalidAtom, \
259
260 from gentoolkit.package import Package as PackageInfo
261 from gentoolkit.metadata import MetaData
262 -from generic import ToStrMixin, file_sha1, file_mtime, cached_property
263 +from generic import ToStrMixin, file_sha1, file_mtime, cached_property, \
264 + file_get_content, StrThatIgnoreCase
265 from use_info import get_uses_info, get_local_uses_info
266 import os
267
268 @@ -41,6 +42,21 @@ def _get_info_by_func(func, path1, path2):
269 except IOError:
270 return None
271
272 +class FakeMetaData(ToStrMixin):
273 +
274 + def herds(self):
275 + return []
276 +
277 + def maintainers(self):
278 + return []
279 +
280 + def descriptions(self):
281 + return []
282 +
283 + def __unicode__(self):
284 + return 'fake'
285 +
286 +
287 class Use(ToStrMixin):
288 "Represend Use flag as object"
289 __slots__ = ('name',)
290 @@ -51,7 +67,7 @@ class Use(ToStrMixin):
291 """
292 if name.startswith('+') or name.startswith('-'):
293 name = name[1:]
294 - self.name = name
295 + self.name = StrThatIgnoreCase(name)
296
297 def __unicode__(self):
298 return self.name
299 @@ -106,18 +122,28 @@ def _gen_all_use(func, iterator):
300 return use_all_dict
301
302 class Portage(object):
303 +
304 + def __init__(self):
305 + self.treemap = PORTDB.repositories.treemap
306 + self.tree_order = PORTDB.repositories.prepos_order
307 +
308 + def get_tree_by_name(self, tree_name):
309 + if tree_name in self.treemap:
310 + return PortTree(self.treemap[tree_name], tree_name)
311 + else:
312 + raise AttributeError
313
314 def iter_trees(self):
315 - tree_dict = PORTDB.repositories.treemap
316 - for tree_name in PORTDB.repositories.prepos_order:
317 + tree_dict = self.treemap
318 + for tree_name in self.tree_order:
319 yield PortTree(tree_dict[tree_name], tree_name)
320
321 - def iter_packages():
322 + def iter_packages(self):
323 for tree in self.iter_trees():
324 for package in tree.iter_package():
325 yield package
326
327 - def iter_ebuilds():
328 + def iter_ebuilds(self):
329 for tree in self.iter_trees():
330 for ebuild in tree.iter_ebuilds():
331 yield ebuild
332 @@ -147,6 +173,7 @@ class PortTree(ToStrMixin):
333 def __init__(self, tree_path = '/usr/portage', name = 'main'):
334 """Args:
335 tree_path -- full path to portage tree as str
336 + name -- repo name as str
337 """
338 self.porttree = tree_path
339 self.name = name
340 @@ -220,6 +247,10 @@ class Category(ToStrMixin):
341 "Full path to category"
342 return os.path.join(self.porttree.porttree_path, self.category)
343
344 + @property
345 + def porttree_path(self):
346 + return self.porttree.porttree
347 +
348
349 class Package(ToStrMixin):
350 "Represent package as object"
351 @@ -235,7 +266,12 @@ class Package(ToStrMixin):
352 ebuilds = PORTDB.cp_list(self.package,
353 mytree = self.category.porttree.porttree)
354 for ebuild in ebuilds:
355 - yield Ebuild(self ,ebuild)
356 + try:
357 + PORTDB.aux_get(ebuild, [], mytree = self.category.porttree_path)
358 + except KeyError:
359 + pass
360 + else:
361 + yield Ebuild(self ,ebuild)
362
363 def __unicode__(self):
364 return '%s' % self.package
365 @@ -246,7 +282,10 @@ class Package(ToStrMixin):
366
367 @cached_property
368 def metadata(self):
369 - return MetaData( self.metadata_path)
370 + try:
371 + return MetaData( self.metadata_path)
372 + except IOError:
373 + return FakeMetaData()
374
375 @property
376 def cp(self):
377 @@ -287,7 +326,7 @@ class Package(ToStrMixin):
378
379 @cached_property
380 def changelog(self):
381 - return open(self.changelog_path,'r').read()
382 + return file_get_content(self.changelog_path)
383
384
385 class Ebuild(ToStrMixin):
386 @@ -371,7 +410,11 @@ class Ebuild(ToStrMixin):
387 @cached_property
388 def homepages(self):
389 "List of homepages"
390 - return self.homepage_val.split()
391 + ho_list = self.homepage_val.split()
392 + ret_list = []
393 + for ho in ho_list:
394 + ret_list.append(StrThatIgnoreCase(ho))
395 + return ret_list
396
397 @cached_property
398 def homepage(self):
399 @@ -382,7 +425,11 @@ class Ebuild(ToStrMixin):
400 @cached_property
401 def licenses(self):
402 "List of licenses used in ebuild"
403 - return filter(_license_filter, self.license.split())
404 + license_list = filter(_license_filter, self.license.split())
405 + ret_list = []
406 + for lic in license_list:
407 + ret_list.append(StrThatIgnoreCase(lic))
408 + return ret_list
409
410 sha1 = cached_property(_file_hash("ebuild_path"), name = 'sha1')
411 mtime = cached_property(_file_mtime("ebuild_path"), name = 'mtime')