diff options
Diffstat (limited to 'devel')
-rw-r--r-- | devel/management/commands/reporead.py | 84 | ||||
-rw-r--r-- | devel/tests.py | 7 | ||||
-rw-r--r-- | devel/urls.py | 1 | ||||
-rw-r--r-- | devel/views.py | 39 |
4 files changed, 76 insertions, 55 deletions
diff --git a/devel/management/commands/reporead.py b/devel/management/commands/reporead.py index e31478c5..09e48559 100644 --- a/devel/management/commands/reporead.py +++ b/devel/management/commands/reporead.py @@ -27,9 +27,17 @@ import logging from datetime import datetime from optparse import make_option +# New in 2.6, but fast (C implementation) in 2.7. We will use it over codecs if +# available. Eventually remove the codecs import completely. +io = None +try: + import io +except ImportError: + pass + from logging import ERROR, WARNING, INFO, DEBUG -from main.models import Arch, Package, Repo +from main.models import Arch, Package, PackageDepend, PackageFile, Repo logging.basicConfig( level=WARNING, @@ -79,14 +87,13 @@ class Pkg(object): """An interim 'container' object for holding Arch package data.""" bare = ( 'name', 'base', 'arch', 'desc', 'filename', 'md5sum', 'url', 'builddate', 'packager' ) - squash = ( 'license', ) number = ( 'csize', 'isize' ) def __init__(self, repo): self.repo = repo self.ver = None self.rel = None - for k in self.bare + self.squash + self.number: + for k in self.bare + self.number: setattr(self, k, None) def populate(self, values): @@ -94,8 +101,6 @@ class Pkg(object): # ensure we stay under our DB character limit if k in self.bare: setattr(self, k, v[0][:254]) - elif k in self.squash: - setattr(self, k, u', '.join(v)[:254]) elif k in self.number: setattr(self, k, long(v[0])) elif k == 'force': @@ -158,6 +163,20 @@ def find_user(userstring): # lookup more than strictly necessary. find_user.cache = {} +def create_depend(package, dep_str, optional=False): + depend = PackageDepend(pkg=package, optional=optional) + # lop off any description first + parts = dep_str.split(':', 1) + if len(parts) > 1: + depend.description = parts[1].strip() + match = re.match(r"^(.+?)((>=|<=|=|>|<)(.*))?$", parts[0].strip()) + if match: + depend.depname = match.group(1) + if match.group(2): + depend.depvcmp = match.group(2) + depend.save(force_insert=True) + return depend + def populate_pkg(dbpkg, repopkg, force=False, timestamp=None): if repopkg.base: dbpkg.pkgbase = repopkg.base @@ -166,7 +185,6 @@ def populate_pkg(dbpkg, repopkg, force=False, timestamp=None): dbpkg.pkgver = repopkg.ver dbpkg.pkgrel = repopkg.rel dbpkg.pkgdesc = repopkg.desc - dbpkg.license = repopkg.license dbpkg.url = repopkg.url dbpkg.filename = repopkg.filename dbpkg.compressed_size = repopkg.csize @@ -192,21 +210,22 @@ def populate_pkg(dbpkg, repopkg, force=False, timestamp=None): populate_files(dbpkg, repopkg, force=force) dbpkg.packagedepend_set.all().delete() - if 'depends' in repopkg.__dict__: + if hasattr(repopkg, 'depends'): for y in repopkg.depends: - # make sure we aren't adding self depends.. - # yes *sigh* i have seen them in pkgbuilds - dpname, dpvcmp = re.match(r"([a-z0-9._+-]+)(.*)", y).groups() - if dpname == repopkg.name: - logger.warning('Package %s has a depend on itself', repopkg.name) - continue - dbpkg.packagedepend_set.create(depname=dpname, depvcmp=dpvcmp) - logger.debug('Added %s as dep for pkg %s', dpname, repopkg.name) + dep = create_depend(dbpkg, y) + if hasattr(repopkg, 'optdepends'): + for y in repopkg.optdepends: + dep = create_depend(dbpkg, y, True) - dbpkg.packagegroup_set.all().delete() - if 'groups' in repopkg.__dict__: + dbpkg.groups.all().delete() + if hasattr(repopkg, 'groups'): for y in repopkg.groups: - dbpkg.packagegroup_set.create(name=y) + dbpkg.groups.create(name=y) + + dbpkg.licenses.all().delete() + if hasattr(repopkg, 'license'): + for y in repopkg.license: + dbpkg.licenses.create(name=y) def populate_files(dbpkg, repopkg, force=False): @@ -222,12 +241,21 @@ def populate_files(dbpkg, repopkg, force=False): elif dbpkg.files_last_update > dbpkg.last_update: return # only delete files if we are reading a DB that contains them - if 'files' in repopkg.__dict__: + if hasattr(repopkg, 'files'): dbpkg.packagefile_set.all().delete() logger.info("adding %d files for package %s", len(repopkg.files), dbpkg.pkgname) - for x in repopkg.files: - dbpkg.packagefile_set.create(path=x) + for f in repopkg.files: + dirname, filename = f.rsplit('/', 1) + if filename == '': + filename = None + # this is basically like calling dbpkg.packagefile_set.create(), + # but much faster as we can skip a lot of the repeated code paths + pkgfile = PackageFile(pkg=dbpkg, + is_directory=(filename is None), + directory=dirname + '/', + filename=filename) + pkgfile.save() dbpkg.files_last_update = datetime.now() dbpkg.save() @@ -363,21 +391,21 @@ def parse_repo(repopath): logger.error("File does not have the proper extension") raise Exception("File does not have the proper extension") - repodb = tarfile.open(repopath,"r") - ## assuming well formed tar, with dir first then files after - ## repo-add enforces this + repodb = tarfile.open(repopath, "r") logger.debug("Starting package parsing") dbfiles = ('desc', 'depends', 'files') pkgs = {} for tarinfo in repodb.getmembers(): - if tarinfo.isdir(): - continue - elif tarinfo.isreg(): + if tarinfo.isreg(): pkgid, fname = os.path.split(tarinfo.name) if fname not in dbfiles: continue data_file = repodb.extractfile(tarinfo) - data_file = codecs.EncodedFile(data_file, 'utf-8') + if io is None: + data_file = codecs.EncodedFile(data_file, 'utf-8') + else: + data_file = io.TextIOWrapper(io.BytesIO(data_file.read()), + encoding='utf=8') try: data = parse_info(data_file) p = pkgs.setdefault(pkgid, Pkg(reponame)) diff --git a/devel/tests.py b/devel/tests.py index 682f3d92..da5459d6 100644 --- a/devel/tests.py +++ b/devel/tests.py @@ -10,13 +10,6 @@ class DevelTest(TestCase): self.assertEqual(response['location'], 'http://testserver/login/?next=/devel/') - def test_notify(self): - response = self.client.get('/devel/notify/') - self.assertEqual(response.status_code, 302) - self.assertEqual(response.has_header('Location'), True) - self.assertEqual(response['location'], - 'http://testserver/login/?next=/devel/notify/') - def test_profile(self): response = self.client.get('/devel/profile/') self.assertEqual(response.status_code, 302) diff --git a/devel/urls.py b/devel/urls.py index 0a050a92..bcf9c071 100644 --- a/devel/urls.py +++ b/devel/urls.py @@ -3,7 +3,6 @@ from django.conf.urls.defaults import patterns urlpatterns = patterns('devel.views', (r'^$', 'index'), (r'^clock/$', 'clock'), - (r'^notify/$', 'change_notify'), (r'^profile/$', 'change_profile'), (r'^newuser/$', 'new_user_form'), ) diff --git a/devel/views.py b/devel/views.py index b26c7af0..311922ca 100644 --- a/devel/views.py +++ b/devel/views.py @@ -4,6 +4,7 @@ from django.contrib.auth.decorators import login_required, permission_required from django.contrib.auth.models import User from django.contrib.sites.models import Site from django.core.mail import send_mail +from django.template import loader, Context from django.views.decorators.cache import never_cache from django.views.generic.simple import direct_to_template @@ -23,8 +24,8 @@ from string import ascii_letters, digits def index(request): '''the Developer dashboard''' inner_q = PackageRelation.objects.filter(user=request.user).values('pkgbase') - flagged = Package.objects.select_related('arch', 'repo').filter(flag_date__isnull=False) - flagged = flagged.filter(pkgbase__in=inner_q).order_by('pkgname') + flagged = Package.objects.select_related('arch', 'repo').filter( + flag_date__isnull=False, pkgbase__in=inner_q).order_by('pkgname') todopkgs = TodolistPkg.objects.select_related( 'pkg', 'pkg__arch', 'pkg__repo').filter(complete=False) @@ -65,15 +66,6 @@ def clock(request): return direct_to_template(request, 'devel/clock.html', page_dict) -@login_required -def change_notify(request): - maint = User.objects.get(username=request.user.username) - notify = request.POST.get('notify', 'no') - prof = maint.get_profile() - prof.notify = (notify == 'yes') - prof.save() - return HttpResponseRedirect('/devel/') - class ProfileForm(forms.Form): email = forms.EmailField(label='Private email (not shown publicly):', help_text="Used for out-of-date notifications, etc.") @@ -120,25 +112,34 @@ class NewUserForm(forms.ModelForm): first_name = forms.CharField(required=False) last_name = forms.CharField(required=False) + def clean_username(self): + username = self.cleaned_data['username'] + if User.objects.filter(username=username).exists(): + raise forms.ValidationError( + "A user with that username already exists.") + return username + def save(self): profile = forms.ModelForm.save(self, False) pwletters = ascii_letters + digits - pw = ''.join([random.choice(pwletters) for i in xrange(8)]) + password = ''.join([random.choice(pwletters) for i in xrange(8)]) user = User.objects.create_user(username=self.cleaned_data['username'], - email=self.cleaned_data['email'], password=pw) + email=self.cleaned_data['email'], password=password) user.first_name = self.cleaned_data['first_name'] user.last_name = self.cleaned_data['last_name'] user.save() profile.user = user profile.save() - domain = Site.objects.get_current().domain + + t = loader.get_template('devel/new_account.txt') + c = Context({ + 'site': Site.objects.get_current(), + 'user': user, + 'password': password, + }) send_mail("Your new archweb account", - """You can now log into: -https://%s/login/ -with these login details: -Username: %s -Password: %s""" % (domain, user.username, pw), + t.render(c), 'Arch Website Notification <nobody@archlinux.org>', [user.email], fail_silently=False) |