summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md23
-rw-r--r--devel/utils.py8
-rw-r--r--main/utils.py15
-rw-r--r--news/models.py7
-rw-r--r--news/views.py6
-rw-r--r--packages/views/search.py17
-rw-r--r--releng/models.py6
-rw-r--r--requirements.txt4
-rw-r--r--requirements_prod.txt4
-rw-r--r--sitestatic/archweb.js4
-rw-r--r--templates/devel/index.html15
11 files changed, 68 insertions, 41 deletions
diff --git a/README.md b/README.md
index 3e48ca8c..7f94626f 100644
--- a/README.md
+++ b/README.md
@@ -32,15 +32,15 @@ packages, you will probably want the following:
1. Run `virtualenv2`.
- $ cd /path/to/archweb && virtualenv2 ./env/
+ cd /path/to/archweb && virtualenv2 ./env/
2. Activate the virtualenv.
- $ source ./env/bin/activate
+ source ./env/bin/activate
2. Install dependencies through `pip`.
- (archweb-env) $ pip install -r requirements.txt
+ pip install -r requirements.txt
3. Copy `local_settings.py.example` to `local_settings.py` and modify.
Make sure to uncomment the appropriate database section (either sqlite or
@@ -48,26 +48,29 @@ packages, you will probably want the following:
4. Sync the database to create it.
- (archweb-env) $ ./manage.py syncdb
+ ./manage.py syncdb
5. Migrate changes.
- (archweb-env) $ ./manage.py migrate
+ ./manage.py migrate
6. Load the fixtures to prepopulate some data. If you don't want some of the
provided data, adjust the file glob accordingly.
- (archweb-env) $ ./manage.py loaddata */fixtures/*.json
+ ./manage.py loaddata main/fixtures/*.json
+ ./manage.py loaddata devel/fixtures/*.json
+ ./manage.py loaddata mirrors/fixtures/*.json
+ ./manage.py loaddata releng/fixtures/*.json
7. Use the following commands to start a service instance
- (archweb-env) $ ./manage.py runserver
+ ./manage.py runserver
8. To optionally populate the database with real data:
- (archweb-env) $ wget ftp://ftp.archlinux.org/core/os/i686/core.db.tar.gz
- (archweb-env) $ ./manage.py reporead i686 core.db.tar.gz
- (archweb-env) $ ./manage.py syncisos
+ wget http://mirrors.kernel.org/archlinux/core/os/i686/core.db.tar.gz
+ ./manage.py reporead i686 core.db.tar.gz
+ ./manage.py syncisos
Alter architecture and repo to get x86\_64 and packages from other repos if
needed.
diff --git a/devel/utils.py b/devel/utils.py
index eaa7d07e..3326987a 100644
--- a/devel/utils.py
+++ b/devel/utils.py
@@ -6,13 +6,16 @@ from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
from django.db import connection
from django.db.models import Count, Q
+from devel.models import UserProfile
from main.utils import cache_function
from main.models import Package
from packages.models import PackageRelation
@cache_function(283)
def get_annotated_maintainers():
- maintainers = User.objects.filter(is_active=True).order_by(
+ profile_ids = UserProfile.allowed_repos.through.objects.values('userprofile_id')
+ maintainers = User.objects.filter(
+ is_active=True, userprofile__id__in=profile_ids).order_by(
'first_name', 'last_name')
# annotate the maintainers with # of maintained and flagged packages
@@ -43,7 +46,8 @@ SELECT pr.user_id, COUNT(*), COUNT(p.flag_date)
m.flagged_count = flag_count.get(m.id, 0)
m.updated_count = update_count.get(m.id, 0)
- return maintainers
+ # force non-QS context, otherwise pickling doesn't work
+ return list(maintainers)
def ignore_does_not_exist(func):
diff --git a/main/utils.py b/main/utils.py
index cf156566..f94f314d 100644
--- a/main/utils.py
+++ b/main/utils.py
@@ -4,6 +4,8 @@ except ImportError:
import pickle
import hashlib
+import markdown
+from markdown.extensions import Extension
from django.core.cache import cache
from django.db import connections, router
@@ -109,6 +111,19 @@ def database_vendor(model, mode='read'):
return connections[database].vendor
+class EscapeHtml(Extension):
+ def extendMarkdown(self, md, md_globals):
+ del md.preprocessors['html_block']
+ del md.inlinePatterns['html']
+
+
+def parse_markdown(text, allow_html=False):
+ if allow_html:
+ return markdown.markdown(text, enable_attributes=False)
+ ext = [EscapeHtml()]
+ return markdown.markdown(text, extensions=ext, enable_attributes=False)
+
+
def groupby_preserve_order(iterable, keyfunc):
'''Take an iterable and regroup using keyfunc to determine whether items
belong to the same group. The order of the iterable is preserved and
diff --git a/news/models.py b/news/models.py
index 985c1088..a66da8d4 100644
--- a/news/models.py
+++ b/news/models.py
@@ -1,11 +1,11 @@
-import markdown
-
from django.db import models
from django.contrib.auth.models import User
from django.contrib.sites.models import Site
from django.utils.safestring import mark_safe
from django.utils.timezone import now
+from main.utils import parse_markdown
+
class News(models.Model):
slug = models.SlugField(max_length=255, unique=True)
@@ -22,8 +22,7 @@ class News(models.Model):
return '/news/%s/' % self.slug
def html(self):
- return mark_safe(markdown.markdown(
- self.content, safe_mode=self.safe_mode, enable_attributes=False))
+ return mark_safe(parse_markdown(self.content, not self.safe_mode))
def __unicode__(self):
return self.title
diff --git a/news/views.py b/news/views.py
index ca4fdf97..274ba75d 100644
--- a/news/views.py
+++ b/news/views.py
@@ -1,5 +1,3 @@
-import markdown
-
from django import forms
from django.http import HttpResponse
from django.shortcuts import get_object_or_404, redirect
@@ -8,7 +6,7 @@ from django.views.generic import (DetailView, ListView,
CreateView, UpdateView, DeleteView)
from .models import News
-from main.utils import find_unique_slug
+from main.utils import find_unique_slug, parse_markdown
class NewsForm(forms.ModelForm):
@@ -62,7 +60,7 @@ def view_redirect(request, object_id):
@require_POST
def preview(request):
data = request.POST.get('data', '')
- markup = markdown.markdown(data, safe_mode=True, enable_attributes=False)
+ markup = parse_markdown(data)
return HttpResponse(markup)
# vim: set ts=4 sw=4 et:
diff --git a/packages/views/search.py b/packages/views/search.py
index 0b776d79..e4cd0423 100644
--- a/packages/views/search.py
+++ b/packages/views/search.py
@@ -6,6 +6,7 @@ from django.db.models import Q
from django.http import HttpResponse
from django.views.generic import ListView
+from devel.models import UserProfile
from main.models import Package, Arch, Repo
from main.utils import empty_response, make_choice
from ..models import PackageRelation
@@ -36,14 +37,16 @@ class PackageSearchForm(forms.Form):
self.fields['arch'].choices = make_choice(
[arch.name for arch in Arch.objects.all()])
self.fields['q'].widget.attrs.update({"size": "30"})
- maints = User.objects.filter(is_active=True).order_by(
+
+ profile_ids = UserProfile.allowed_repos.through.objects.values('userprofile_id')
+ people = User.objects.filter(
+ is_active=True, userprofile__id__in=profile_ids).order_by(
'first_name', 'last_name')
- self.fields['maintainer'].choices = \
- [('', 'All'), ('orphan', 'Orphan')] + \
- [(m.username, m.get_full_name()) for m in maints]
- self.fields['packager'].choices = \
- [('', 'All'), ('unknown', 'Unknown')] + \
- [(m.username, m.get_full_name()) for m in maints]
+ people = [('', 'All'), ('orphan', 'Orphan')] + \
+ [(p.username, p.get_full_name()) for p in people]
+
+ self.fields['maintainer'].choices = people
+ self.fields['packager'].choices = people
def exact_matches(self):
# only do exact match search if 'q' is sole parameter
diff --git a/releng/models.py b/releng/models.py
index 2f9216bd..a4af81ab 100644
--- a/releng/models.py
+++ b/releng/models.py
@@ -2,7 +2,6 @@ from base64 import b64decode
from bencode import bdecode, bencode
from datetime import datetime
import hashlib
-import markdown
from pytz import utc
from django.conf import settings
@@ -12,7 +11,7 @@ from django.db.models.signals import pre_save
from django.utils.safestring import mark_safe
from main.fields import PositiveBigIntegerField
-from main.utils import set_created_field
+from main.utils import set_created_field, parse_markdown
class IsoOption(models.Model):
@@ -154,8 +153,7 @@ class Release(models.Model):
return "magnet:?%s" % '&'.join(['%s=%s' % (k, v) for k, v in query])
def info_html(self):
- return mark_safe(markdown.markdown(
- self.info, safe_mode=True, enable_attributes=False))
+ return mark_safe(parse_markdown(self.info))
def torrent(self):
try:
diff --git a/requirements.txt b/requirements.txt
index e1acd2e9..2a5dba96 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -2,9 +2,9 @@
Django==1.7.1
IPy==0.81
Jinja2==2.7.3
-Markdown==2.4.1
+Markdown==2.5.2
bencode==1.0
-django-jinja==1.0.4
+django-jinja==1.0.5
django_countries==3.0.1
jsmin==2.0.11
pgpdump==1.5
diff --git a/requirements_prod.txt b/requirements_prod.txt
index ef535eb8..6edfa17f 100644
--- a/requirements_prod.txt
+++ b/requirements_prod.txt
@@ -2,9 +2,9 @@
Django==1.7.1
IPy==0.81
Jinja2==2.7.3
-Markdown==2.4.1
+Markdown==2.5.2
bencode==1.0
-django-jinja==1.0.4
+django-jinja==1.0.5
django_countries==3.0.1
jsmin==2.0.11
pgpdump==1.5
diff --git a/sitestatic/archweb.js b/sitestatic/archweb.js
index 43816c5b..dce9cd0c 100644
--- a/sitestatic/archweb.js
+++ b/sitestatic/archweb.js
@@ -303,12 +303,12 @@ function filter_packages() {
var cells = $(this).children('td');
/* all this just to get the split version out of the table cell */
- var ver_a = cells.eq(2).find('span').text().match(pat);
+ var ver_a = cells.eq(2).text().match(pat);
if (!ver_a) {
return true;
}
- var ver_b = cells.eq(3).find('span').text().match(pat);
+ var ver_b = cells.eq(3).text().match(pat);
if (!ver_b) {
return true;
}
diff --git a/templates/devel/index.html b/templates/devel/index.html
index 8ed9f9ac..0de285d5 100644
--- a/templates/devel/index.html
+++ b/templates/devel/index.html
@@ -157,8 +157,11 @@
</ul>
</div>{# #dev-dashboard #}
-<div id='stats-area'>
- <p>Enable Javascript to get more useful info here.</p>
+<div id="stats-area">
+ <div class="box">
+ <h2>Developer Stats</h2>
+ <p id="stats-message">Enable JavaScript to get more useful info here.</p>
+ </div>
</div>
{% endblock %}
@@ -167,8 +170,12 @@
<script type="text/javascript" src="{% static "archweb.js" %}"></script>
<script type="text/javascript">
$(document).ready(function() {
- $("#stats-area").html('<p>Loading stats…</p>');
- $("#stats-area").load('stats/', function() {
+ $("#stats-message").html('Loading developer stats…');
+ $("#stats-area").load('stats/', function(response, status, xhr) {
+ if (status === 'error' || status === 'timeout') {
+ $("#stats-message").html('Developer stats loading encountered an error. Sorry.');
+ return;
+ }
var settings = {
widgets: ['zebra'],
sortList: [[0,0]],